diff --git a/.cargo/config.toml b/.cargo/config.toml index 24fe1acfba8..b9064b6c064 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,34 +8,40 @@ xclippy = [ "-Wunexpected_cfgs", "-Dwarnings", "-Wclippy::all", # TODO: at some point we need to clean up all the exceptions listed below - "-Aclippy::upper_case_acronyms", - "-Aclippy::enum-variant-names", - "-Aclippy::result-large-err", - "-Aclippy::mutable-key-type", - "-Aclippy::map_identity", # We temporarily ignore this due to: https://github.com/rust-lang/rust-clippy/issues/11764 - "-Aclippy::doc_lazy_continuation", + "-Aclippy::collapsible_if", "-Aclippy::collapsible_match", - "-Aclippy::needless_borrows_for_generic_args", - "-Anon_local_definitions", - "-Aclippy::needless_lifetimes", - "-Aclippy::empty_line_after_doc_comments", - "-Aclippy::manual-ok-err", + "-Aclippy::doc_lazy_continuation", "-Aclippy::doc-overindented-list-items", - "-Aclippy::unneeded_struct_pattern", - "-Aclippy::manual_div_ceil", - "-Aclippy::manual-repeat-n", + "-Aclippy::empty_line_after_doc_comments", + "-Aclippy::enum-variant-names", + "-Aclippy::large-enum-variant", + "-Aclippy::mutable-key-type", + "-Aclippy::result-large-err", "-Aclippy::sliced-string-as-bytes", - "-Aclippy::obfuscated-if-else", - "-Aclippy::unnecessary-map-or", + "-Aclippy::upper_case_acronyms", ] x = "run --package aptos-cargo-cli --bin aptos-cargo-cli --" [build] rustflags = ["--cfg", "tokio_unstable", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes"] -# TODO(grao): Figure out whether we should enable othaer cpu features, and whether we should use a different way to configure them rather than list every single one here. [target.x86_64-unknown-linux-gnu] -rustflags = ["--cfg", "tokio_unstable", "-C", "link-arg=-fuse-ld=lld", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] +rustflags = [ + "--cfg", + "tokio_unstable", + "-C", + "link-arg=-fuse-ld=lld", + "-C", + "force-frame-pointers=yes", + "-C", + "force-unwind-tables=yes", + "-C", + "target-cpu=x86-64-v3", +] + +# Need this for RocksDB to build until its build script is fixed. +[env] +CXXFLAGS_x86_64_unknown_linux_gnu = "-mpclmul" # 64 bit MSVC [target.x86_64-pc-windows-msvc] diff --git a/.dockerignore b/.dockerignore index a68f3718bca..6c41e3ac776 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,6 +19,7 @@ !**/*.mv !**/*.rs !**/*.mrb +!**/*.mpb !**/*.errmap !config/src/config/test_data !aptos-move/aptos-gas-profiling/templates/ diff --git a/.github/actions.bak/fullnode-sync/fullnode_sync.py b/.github/actions.bak/fullnode-sync/fullnode_sync.py index d081227b4a3..6f2af74ad6b 100644 --- a/.github/actions.bak/fullnode-sync/fullnode_sync.py +++ b/.github/actions.bak/fullnode-sync/fullnode_sync.py @@ -9,21 +9,88 @@ # This script runs the fullnode-sync from the root of aptos-core. -# Useful file constants +# Network name constants +TESTNET_STRING = "testnet" +MAINNET_STRING = "mainnet" + +# Config file constants FAST_SYNC_BOOTSTRAPPING_MODE = "DownloadLatestStates" # The bootstrapping string for fast sync FULLNODE_CONFIG_NAME = "public_full_node.yaml" # Relative to the aptos-core repo FULLNODE_CONFIG_TEMPLATE_PATH = "config/src/config/test_data/public_full_node.yaml" # Relative to the aptos-core repo GENESIS_BLOB_PATH = "https://raw.githubusercontent.com/aptos-labs/aptos-networks/main/{network}/genesis.blob" # Location inside the aptos-networks repo +WAYPOINT_FILE_PATH = "https://raw.githubusercontent.com/aptos-labs/aptos-networks/main/{network}/waypoint.txt" # Location inside the aptos-networks repo + +# Service endpoint constants LOCAL_METRICS_ENDPOINT = "http://127.0.0.1:9101/json_metrics" # The json metrics endpoint running on the local host LOCAL_METRICS_ENDPOINT_TEXT = "http://127.0.0.1:9101/metrics" # The text metrics endpoint running on the local host LOCAL_REST_ENDPOINT = "http://127.0.0.1:8080/v1" # The rest endpoint running on the local host +REMOTE_REST_ENDPOINTS = "https://api.{network}.aptoslabs.com/v1" # The remote rest endpoint + +# API and metric constants LEDGER_VERSION_API_STRING = "ledger_version" # The string to fetch the ledger version from the REST API LEDGER_VERSION_METRICS_STRING = "aptos_state_sync_version.synced" # The string to fetch the ledger version from the metrics API +SYNCED_STATES_METRICS_STRING = "aptos_state_sync_version.synced_states" # The string to fetch the synced states from the metrics API + +# Generic constants MAX_TIME_BETWEEN_SYNC_INCREASES_SECS = 1800 # The number of seconds after which to fail if the node isn't syncing -REMOTE_REST_ENDPOINTS = "https://fullnode.{network}.aptoslabs.com/v1" # The remote rest endpoint +NUMBER_OF_HISTORICAL_TRANSACTIONS_TO_SYNC = 2000000 # The number of historical transactions to sync (when syncing from genesis) SYNCING_DELTA_VERSIONS = 20000 # The number of versions to sync beyond the highest known at the job start -SYNCED_STATES_METRICS_STRING = "aptos_state_sync_version.synced_states" # The string to fetch the synced states from the metrics API -WAYPOINT_FILE_PATH = "https://raw.githubusercontent.com/aptos-labs/aptos-networks/main/{network}/waypoint.txt" # Location inside the aptos-networks repo + +# Testnet seed peer constants +TESTNET_SEED_PEERS = { + "2DA03E9D24E501741234047953A63ABC6D84193BE495C507C72F68269FB8B76A": { + "addresses": [ + "/dns4/pfn1.usce1.fullnode.testnet.aptoslabs.com/tcp/6182/noise-ik/2DA03E9D24E501741234047953A63ABC6D84193BE495C507C72F68269FB8B76A/handshake/0" + ], + "role": "Upstream", + }, + "8B68819D267E19D44716B821CE499B79D258C86BB65E7A60884EC31FF987ED14": { + "addresses": [ + "/dns4/pfn2.usce2.fullnode.testnet.aptoslabs.com/tcp/6182/noise-ik/8B68819D267E19D44716B821CE499B79D258C86BB65E7A60884EC31FF987ED14/handshake/0" + ], + "role": "Upstream", + }, + "76902CCCDBDC116894EBA1EDE36D1D2C3BE9155F21D731F6B4EBE17FC611DD00": { + "addresses": [ + "/dns4/pfn1.euwe4.fullnode.testnet.aptoslabs.com/tcp/6182/noise-ik/76902CCCDBDC116894EBA1EDE36D1D2C3BE9155F21D731F6B4EBE17FC611DD00/handshake/0" + ], + "role": "Upstream", + }, + "2A8153A065E60FFE63E8B4285044972376FD06092FB8E877EBF72BE91198BB65": { + "addresses": [ + "/dns4/pfn1.apne1.fullnode.testnet.aptoslabs.com/tcp/6182/noise-ik/2A8153A065E60FFE63E8B4285044972376FD06092FB8E877EBF72BE91198BB65/handshake/0" + ], + "role": "Upstream", + }, +} + +# Mainnet seed peer constants +MAINNET_SEED_PEERS = { + "A118B9BBBB8670D026C59C494317F7B6AA449A8E1B6AE0F9A6D434478AD1CC35": { + "addresses": [ + "/dns4/pfn1.usce1.fullnode.mainnet.aptoslabs.com/tcp/6182/noise-ik/A118B9BBBB8670D026C59C494317F7B6AA449A8E1B6AE0F9A6D434478AD1CC35/handshake/0" + ], + "role": "Upstream", + }, + "058D7AF7A9074D8E48255EC08EDD8AEE4D2120CA7FAC18E2A6DE9EC603FF7A66": { + "addresses": [ + "/dns4/pfn2.usce1.fullnode.mainnet.aptoslabs.com/tcp/6182/noise-ik/058D7AF7A9074D8E48255EC08EDD8AEE4D2120CA7FAC18E2A6DE9EC603FF7A66/handshake/0" + ], + "role": "Upstream", + }, + "C0171305FEF577904C874D44C0A3821F830E9419D3AA3A40C29CA7DEA24F466F": { + "addresses": [ + "/dns4/pfn3.usce1.fullnode.mainnet.aptoslabs.com/tcp/6182/noise-ik/C0171305FEF577904C874D44C0A3821F830E9419D3AA3A40C29CA7DEA24F466F/handshake/0" + ], + "role": "Upstream", + }, + "99A2C88D211A6FDF56B934BE039330B4E76EC5FEEE4989ACE4C7CD63B2F94C34": { + "addresses": [ + "/dns4/pfn4.usce1.fullnode.mainnet.aptoslabs.com/tcp/6182/noise-ik/99A2C88D211A6FDF56B934BE039330B4E76EC5FEEE4989ACE4C7CD63B2F94C34/handshake/0" + ], + "role": "Upstream", + }, +} def print_error_and_exit(error): """Prints the given error and exits the process""" @@ -172,7 +239,7 @@ def monitor_fullnode_syncing(fullnode_process_handle, bootstrapping_mode, node_l print(errors) # Sleep for a few seconds while the fullnode synchronizes - time.sleep(10) + time.sleep(5) def wait_for_fullnode_to_start(fullnode_process_handle): @@ -191,8 +258,15 @@ def wait_for_fullnode_to_start(fullnode_process_handle): api_index_response = ping_rest_api_index_page(LOCAL_REST_ENDPOINT, False) -def get_public_and_target_version(network): +def get_public_and_target_version(network, syncing_historical_data): """Calculates the syncing target version of the fullnode""" + # If we're syncing historical data, it will take too long to catch up + # to the head of the chain, so we only sync to a fixed target version. + if syncing_historical_data: + target_version = NUMBER_OF_HISTORICAL_TRANSACTIONS_TO_SYNC + print("Syncing historical data. Setting public and target version to: {target_version}".format(target_version=target_version)) + return (target_version, target_version) + # Fetch the latest version from the public fullnode endpoint public_fullnode_endpoint = REMOTE_REST_ENDPOINTS.format(network=network) api_index_response = ping_rest_api_index_page(public_fullnode_endpoint, True) @@ -231,7 +305,24 @@ def spawn_fullnode(git_ref, network, bootstrapping_mode, continuous_syncing_mode return process_handle -def setup_fullnode_config(bootstrapping_mode, continuous_syncing_mode, data_dir_file_path): +def add_seed_peers(fullnode_config: dict, seed_peers: dict) -> None: + """Adds the given seed peers to the public fullnode network of the given config""" + # Get the public fullnode network + public_network = None + for network in fullnode_config["full_node_networks"]: + if network.get("network_id") == "public": # The "public" fullnode network is the only network for PFNs + public_network = network + break + + # Ensure we have the public fullnode network + if public_network is None: + print_error_and_exit("Exiting! Unable to find the public fullnode network in the config!") + + # Add the seed peers to the public fullnode network + public_network["seeds"] = seed_peers + + +def setup_fullnode_config(network, bootstrapping_mode, continuous_syncing_mode, syncing_historical_data, data_dir_file_path): """Initializes and configures the fullnode config file""" # Copy the node config template to the working directory if not os.path.exists(FULLNODE_CONFIG_TEMPLATE_PATH): @@ -253,6 +344,16 @@ def setup_fullnode_config(bootstrapping_mode, continuous_syncing_mode, data_dir_ # Avoid having to set ulimit configurations fullnode_config['storage'] = {"ensure_rlimit_nofile": 0} + # Enable storage sharding (AIP-97) + fullnode_config['storage']['rocksdb_configs'] = {"enable_storage_sharding": True} + + # If we're syncing historical data, we need to add seed peers + if syncing_historical_data: + if network == MAINNET_STRING: + add_seed_peers(fullnode_config, MAINNET_SEED_PEERS) + elif network == TESTNET_STRING: + add_seed_peers(fullnode_config, TESTNET_SEED_PEERS) + # Write the config file back to disk with open(FULLNODE_CONFIG_NAME, "w") as file: yaml.dump(fullnode_config, file) @@ -266,6 +367,23 @@ def get_genesis_and_waypoint(network): subprocess.run(["curl", "-s", "-O", waypoint_file_path]) +def check_if_syncing_historical_data(network, bootstrapping_mode): + """Determines if we're syncing historical data based on the network and bootstrapping mode""" + # If we're fast syncing, we're not syncing historical data + if bootstrapping_mode == FAST_SYNC_BOOTSTRAPPING_MODE: + print("The bootstrapping mode is fast sync! We're not syncing historical data.") + return False + + # If we're on mainnet or testnet, we're syncing historical data + if network == TESTNET_STRING or network == MAINNET_STRING: + print("Syncing historical data on network: {network}. Bootstrapping mode: {bootstrapping_mode}".format(network=network, bootstrapping_mode=bootstrapping_mode)) + return True + + # Otherwise, default to not syncing historical data + print("Not syncing historical data by default. Network: {network}, Bootstrapping mode: {bootstrapping_mode}".format(network=network, bootstrapping_mode=bootstrapping_mode)) + return False + + def checkout_git_ref(git_ref): """Checkout the specified git ref. This assumes the working directory is aptos-core""" subprocess.run(["git", "fetch"]) @@ -296,6 +414,9 @@ def main(): NODE_LOG_FILE_PATH = os.environ["NODE_LOG_FILE_PATH"] METRICS_DUMP_FILE_PATH = os.environ["METRICS_DUMP_FILE_PATH"] + # Determine if we're syncing historical data + syncing_historical_data = check_if_syncing_historical_data(NETWORK, BOOTSTRAPPING_MODE) + # Check out the correct git ref (branch or commit hash) checkout_git_ref(GIT_REF) @@ -303,10 +424,10 @@ def main(): get_genesis_and_waypoint(NETWORK) # Setup the fullnode config - setup_fullnode_config(BOOTSTRAPPING_MODE, CONTINUOUS_SYNCING_MODE, DATA_DIR_FILE_PATH) + setup_fullnode_config(NETWORK, BOOTSTRAPPING_MODE, CONTINUOUS_SYNCING_MODE, syncing_historical_data, DATA_DIR_FILE_PATH) # Get the public synced version and calculate the fullnode syncing target version - (public_version, target_version) = get_public_and_target_version(NETWORK) + (public_version, target_version) = get_public_and_target_version(NETWORK, syncing_historical_data) # Spawn the fullnode fullnode_process_handle = spawn_fullnode(GIT_REF, NETWORK, BOOTSTRAPPING_MODE, CONTINUOUS_SYNCING_MODE, NODE_LOG_FILE_PATH) diff --git a/.github/actions.bak/get-latest-docker-image-tag/action.yml b/.github/actions.bak/get-latest-docker-image-tag/action.yml index f42a7062f50..4e91180556d 100644 --- a/.github/actions.bak/get-latest-docker-image-tag/action.yml +++ b/.github/actions.bak/get-latest-docker-image-tag/action.yml @@ -23,18 +23,22 @@ runs: ref: ${{ inputs.branch }} path: checkout_branch fetch-depth: 0 + - uses: ./checkout_branch/.github/actions/python-setup # use python-setup from that branch with: pyproject_directory: checkout_branch/testsuite + - name: Determine image tag id: determine-test-image-tag - # Forge relies on the default and failpoints variants - run: | - variants=(${{ inputs.variants }}) # split the variants string into an array - variants_args=() - for variant in "${variants[@]}"; do - variants_args+=("--variant" "$variant") - done - ./testrun find_latest_image.py "${variants_args[@]}" - shell: bash - working-directory: checkout_branch/testsuite # the checkout_branch is a subdirectory + uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 + with: + max_attempts: 5 + timeout_minutes: 20 + command: | + cd checkout_branch/testsuite + variants=(${{ inputs.variants }}) # split the variants string into an array + variants_args=() + for variant in "${variants[@]}"; do + variants_args+=("--variant" "$variant") + done + ./testrun find_latest_image.py "${variants_args[@]}" diff --git a/.github/actions.bak/python-setup/action.yaml b/.github/actions.bak/python-setup/action.yaml index 2b0dd50b641..3b072903504 100644 --- a/.github/actions.bak/python-setup/action.yaml +++ b/.github/actions.bak/python-setup/action.yaml @@ -11,7 +11,7 @@ inputs: poetry_version: description: "Poetry package manager version" required: false - default: 1.2.2 + default: 2.2.1 runs: using: composite diff --git a/.github/actions.bak/wait-images-ci/action.yaml b/.github/actions.bak/wait-images-ci/action.yaml index e9a595d23ee..3081e56d6d2 100644 --- a/.github/actions.bak/wait-images-ci/action.yaml +++ b/.github/actions.bak/wait-images-ci/action.yaml @@ -11,11 +11,23 @@ inputs: description: "The number of seconds to wait for the images to be available" required: false default: "1800" # a sane default based on the longest observed build time on the main branch + PROFILE_RELEASE: + description: "If true, wait for the release default images to be available." + required: false + default: false + PROFILE_PERF: + description: "If true, wait for the performance images to be available." + required: false + default: false + FEATURE_FAILPOINTS: + description: "If true, wait for the failpoints images to be available." + required: false + default: false runs: using: composite steps: # Deps setup - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - uses: pnpm/action-setup@v4 @@ -23,5 +35,5 @@ runs: # The source code must be checkout out by the workflow that invokes this action. - name: Run wait-images-ci run: | - GCP_DOCKER_ARTIFACT_REPO=${{ inputs.GCP_DOCKER_ARTIFACT_REPO }} GIT_SHA=${{ inputs.GIT_SHA }} ./docker/wait-images-ci.mjs --wait-for-image-seconds=${{ inputs.WAIT_FOR_IMAGE_SECONDS }} + GCP_DOCKER_ARTIFACT_REPO=${{ inputs.GCP_DOCKER_ARTIFACT_REPO }} GIT_SHA=${{ inputs.GIT_SHA }} PROFILE_RELEASE=${{ inputs.PROFILE_RELEASE }} PROFILE_PERF=${{ inputs.PROFILE_PERF }} FEATURE_FAILPOINTS=${{ inputs.FEATURE_FAILPOINTS }} ./docker/wait-images-ci.mjs --wait-for-image-seconds=${{ inputs.WAIT_FOR_IMAGE_SECONDS }} shell: bash diff --git a/.github/linters/semgrep/disallow-schedule-trigger.yaml b/.github/linters/semgrep/disallow-schedule-trigger.yaml new file mode 100644 index 00000000000..928865791ea --- /dev/null +++ b/.github/linters/semgrep/disallow-schedule-trigger.yaml @@ -0,0 +1,15 @@ +rules: + - id: disallow-schedule-in-github-workflow + languages: + - yaml + severity: ERROR + message: "schedule trigger is disallowed! Use `workflow_dispatch` instead. The workflow can instead be workflow_dispatched via PIES on a schedule" + patterns: + - pattern-inside: | + on: + ... + - pattern: schedule + paths: + include: + - "/.github/workflows/*.yaml" + - "/.github/workflows/*.yml" diff --git a/.github/workflows.bak/backport-to-release-branches.yaml b/.github/workflows.bak/backport-to-release-branches.yaml index 2003cb55d04..ce34265f5bc 100644 --- a/.github/workflows.bak/backport-to-release-branches.yaml +++ b/.github/workflows.bak/backport-to-release-branches.yaml @@ -27,7 +27,7 @@ jobs: - name: Backport Action uses: sorenlouv/backport-github-action@ad888e978060bc1b2798690dd9d03c4036560947 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + github_token: ${{ secrets.APTOS_BOT_PAT }} add_original_reviewers: true - name: Info log diff --git a/.github/workflows.bak/bump-release-version.yaml b/.github/workflows.bak/bump-release-version.yaml index 11e09273dd0..884d93be43d 100644 --- a/.github/workflows.bak/bump-release-version.yaml +++ b/.github/workflows.bak/bump-release-version.yaml @@ -85,17 +85,24 @@ jobs: core.setOutput("newVersion", newVersion); core.setOutput("releaseBranch", branch); core.setOutput("currentVersion", currentVersion); + + - uses: dtolnay/rust-toolchain@stable + + - name: Update Cargo.lock + run: | + cargo update -p aptos-node + - name: Create Pull Request id: create-pr uses: peter-evans/create-pull-request@v7 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.APTOS_BOT_PAT }} branch: update-version-${{ github.run_id }} base: ${{ github.event.inputs.branch }} title: "[${{ steps.determine-version.outputs.releaseBranch }}] Bump version to ${{ steps.determine-version.outputs.newVersion }}" body: "This PR bumps the aptos-node version to ${{ steps.determine-version.outputs.newVersion }} in ${{ steps.determine-version.outputs.releaseBranch }}." commit-message: "[${{ steps.determine-version.outputs.releaseBranch }}] Bump version to ${{ steps.determine-version.outputs.newVersion }}" - add-paths: "aptos-node/Cargo.toml" + add-paths: "aptos-node/Cargo.toml, Cargo.lock" - name: Log PR URL if: ${{ steps.create-pr.outputs.pull-request-number }} run: | diff --git a/.github/workflows.bak/cli-e2e-tests.yaml b/.github/workflows.bak/cli-e2e-tests.yaml index 5217a47c283..467631073bc 100644 --- a/.github/workflows.bak/cli-e2e-tests.yaml +++ b/.github/workflows.bak/cli-e2e-tests.yaml @@ -52,7 +52,7 @@ jobs: poetry_version: 2.1.2 # Run CLI tests against local testnet built from devnet branch. - - uses: nick-fields/retry@7f8f3d9f0f62fe5925341be21c2e8314fd4f7c7c # pin@v2 + - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 if: ${{ !inputs.SKIP_JOB }} name: devnet-tests with: @@ -61,7 +61,7 @@ jobs: command: cd ./crates/aptos/e2e && poetry run python main.py -d --base-network devnet --image-repo-with-project ${{ vars.GCP_DOCKER_ARTIFACT_REPO }} --test-cli-tag ${{ inputs.GIT_SHA }} --working-directory ${{ runner.temp }}/aptos-e2e-tests-devnet # Run CLI tests against local testnet built from testnet branch. - - uses: nick-fields/retry@7f8f3d9f0f62fe5925341be21c2e8314fd4f7c7c # pin@v2 + - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 if: ${{ !inputs.SKIP_JOB }} name: testnet-tests with: @@ -70,7 +70,7 @@ jobs: command: cd ./crates/aptos/e2e && poetry run python main.py -d --base-network testnet --image-repo-with-project ${{ vars.GCP_DOCKER_ARTIFACT_REPO }} --test-cli-tag ${{ inputs.GIT_SHA }} --working-directory ${{ runner.temp }}/aptos-e2e-tests-testnet # Run CLI tests against local testnet built from mainnet branch. - - uses: nick-fields/retry@7f8f3d9f0f62fe5925341be21c2e8314fd4f7c7c # pin@v2 + - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 if: ${{ !inputs.SKIP_JOB }} name: mainnet-tests with: diff --git a/.github/workflows.bak/close-stale-issues.yaml b/.github/workflows.bak/close-stale-issues.yaml index 28ace31ba5d..07b506fed34 100644 --- a/.github/workflows.bak/close-stale-issues.yaml +++ b/.github/workflows.bak/close-stale-issues.yaml @@ -1,7 +1,6 @@ name: "Close stale issues and PRs" on: - schedule: - - cron: "30 1 * * *" + # schedule: # NOTE: the schedule is dictated by PIES workflow_dispatch: permissions: diff --git a/.github/workflows.bak/copy-images-to-dockerhub-nightly.yaml b/.github/workflows.bak/copy-images-to-dockerhub-nightly.yaml index c9596eda0e1..c2bcc4f76d8 100644 --- a/.github/workflows.bak/copy-images-to-dockerhub-nightly.yaml +++ b/.github/workflows.bak/copy-images-to-dockerhub-nightly.yaml @@ -1,25 +1,15 @@ name: Copy images to dockerhub nightly on: - schedule: - # 9am PST (16:00 UTC). - - cron: "0 16 * * *" + # schedule: # NOTE: the schedule is dictated by PIES + workflow_dispatch: permissions: contents: read id-token: write #required for GCP Workload Identity federation - actions: write #required for workflow cancellation via check-aptos-core jobs: - check-repo: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: aptos-labs/aptos-core/.github/actions/check-aptos-core@main - with: - cancel-workflow: ${{ github.event_name == 'schedule' }} # Cancel the workflow if it is scheduled on a fork copy-images-to-dockerhub: - needs: check-repo if: github.repository == 'aptos-labs/aptos-core' uses: ./.github/workflows/copy-images-to-dockerhub.yaml with: diff --git a/.github/workflows.bak/copy-images-to-dockerhub.yaml b/.github/workflows.bak/copy-images-to-dockerhub.yaml index b02b60cb0ec..cf9ab58a3d2 100644 --- a/.github/workflows.bak/copy-images-to-dockerhub.yaml +++ b/.github/workflows.bak/copy-images-to-dockerhub.yaml @@ -58,7 +58,7 @@ jobs: username: ${{ secrets.ENV_DOCKERHUB_USERNAME }} password: ${{ secrets.ENV_DOCKERHUB_PASSWORD }} - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: .node-version diff --git a/.github/workflows.bak/coverage.yaml b/.github/workflows.bak/coverage.yaml index d4dd559c20a..0a719a6e8f7 100644 --- a/.github/workflows.bak/coverage.yaml +++ b/.github/workflows.bak/coverage.yaml @@ -1,10 +1,9 @@ name: "Test_Coverage" on: # Trigger if any of the conditions - # 1. Daily at 12am UTC from the main branch, or + # 1. Daily via PIES scheduled workflow, or # 2. PR with a specific label (see below) - schedule: - - cron: "0 0 * * *" + # schedule: # NOTE: the schedule is dictated by PIES pull_request: types: [labeled] workflow_dispatch: @@ -24,7 +23,7 @@ jobs: rust-unit-coverage: if: | contains(github.event.pull_request.labels.*.name, 'CICD:run-coverage') || - (github.event_name == 'schedule' && github.ref_name == 'main') + (github.event_name == 'workflow_dispatch' && github.ref_name == 'main') # Note the tests run slowly due to instrutmentation. It takes CI 10 hrs timeout-minutes: 720 runs-on: runs-on,cpu=64,family=c7,disk=large,image=aptos-ubuntu-x64,run-id=${{ github.run_id }} @@ -55,7 +54,7 @@ jobs: rust-smoke-coverage: if: | contains(github.event.pull_request.labels.*.name, 'CICD:run-coverage') || - (github.event_name == 'schedule' && github.ref_name == 'main') + (github.event_name == 'workflow_dispatch' && github.ref_name == 'main') timeout-minutes: 720 # incremented from 240 due to execution time limit hit in cron runs-on: runs-on,cpu=64,family=c7,disk=large,image=aptos-ubuntu-x64,run-id=${{ github.run_id }} steps: @@ -85,7 +84,7 @@ jobs: upload-to-codecov: if: | contains(github.event.pull_request.labels.*.name, 'CICD:run-coverage') || - (github.event_name == 'schedule' && github.ref_name == 'main') + (github.event_name == 'workflow_dispatch' && github.ref_name == 'main') && !cancelled() needs: [ rust-unit-coverage, rust-smoke-coverage ] runs-on: ubuntu-latest diff --git a/.github/workflows.bak/docker-update-images.yaml b/.github/workflows.bak/docker-update-images.yaml index 1e93f2cf4c0..ad50e9dff48 100644 --- a/.github/workflows.bak/docker-update-images.yaml +++ b/.github/workflows.bak/docker-update-images.yaml @@ -7,9 +7,7 @@ permissions: on: workflow_dispatch: - schedule: - - cron: "0 9 * * 1" # once a week - + # schedule: # NOTE: the schedule is dictated by PIES pull_request: paths: - scripts/update_docker_images.py diff --git a/.github/workflows.bak/execution-performance.yaml b/.github/workflows.bak/execution-performance.yaml index 1597d9ecbc8..5ab0bd4e176 100644 --- a/.github/workflows.bak/execution-performance.yaml +++ b/.github/workflows.bak/execution-performance.yaml @@ -3,15 +3,12 @@ on: workflow_dispatch: pull_request: types: [labeled, opened, synchronize, reopened, auto_merge_enabled] - schedule: - - cron: "0 */4 * * *" # This runs every four hours - + # schedule: # NOTE: the schedule is dictated by PIES jobs: execution-performance: if: | # Only run on each PR once an appropriate event occurs ( github.event_name == 'workflow_dispatch' || - github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'CICD:run-e2e-tests') || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-test') || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-full-test') || @@ -21,8 +18,8 @@ jobs: secrets: inherit with: GIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - RUNNER_NAME: executor-benchmark-runner - # Run all tests only on the scheduled cadence, or explicitly requested - FLOW: ${{ (github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-full-test')) && 'CONTINUOUS' || 'LAND_BLOCKING' }} + RUNNER_NAME: benchmark-c3d-60 + # Run all tests only on the scheduled cadence, or explicitly requested + FLOW: ${{ (github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-full-test')) && 'CONTINUOUS' || 'LAND_BLOCKING' }} # Ignore target determination if on the scheduled cadence, or explicitly requested - IGNORE_TARGET_DETERMINATION: ${{ github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-test') || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-full-test') }} + IGNORE_TARGET_DETERMINATION: ${{ github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-test') || contains(github.event.pull_request.labels.*.name, 'CICD:run-execution-performance-full-test') }} diff --git a/.github/workflows.bak/forge-continuous-land-blocking-test.yaml b/.github/workflows.bak/forge-continuous-land-blocking-test.yaml index 54371b5fd6a..19c455e26f2 100644 --- a/.github/workflows.bak/forge-continuous-land-blocking-test.yaml +++ b/.github/workflows.bak/forge-continuous-land-blocking-test.yaml @@ -7,11 +7,15 @@ permissions: pull-requests: write contents: read id-token: write - actions: write #required for workflow cancellation via check-aptos-core on: # Allow triggering manually workflow_dispatch: + inputs: + FORGE_CLUSTER_NAME: + required: false + type: string + description: The Forge k8s cluster to be used for test push: branches: # Use this branch for canary @@ -85,6 +89,7 @@ jobs: FORGE_TEST_SUITE: realistic_env_max_load IMAGE_TAG: ${{ needs.determine-docker-build-metadata.outputs.gitSha }} FORGE_RUNNER_DURATION_SECS: 480 + FORGE_CLUSTER_NAME: ${{ inputs.FORGE_CLUSTER_NAME }} FORGE_NAMESPACE: forge-e2e-${{ needs.determine-docker-build-metadata.outputs.FORGE_NAMESPACE_SUFFIX }} SEND_RESULTS_TO_TRUNK: true @@ -144,6 +149,7 @@ jobs: FORGE_TEST_SUITE: compat IMAGE_TAG: ${{ needs.fetch-last-released-docker-image-tag.outputs.IMAGE_TAG }} FORGE_RUNNER_DURATION_SECS: 300 + FORGE_CLUSTER_NAME: ${{ inputs.FORGE_CLUSTER_NAME }} FORGE_NAMESPACE: forge-compat-${{ needs.determine-docker-build-metadata.outputs.FORGE_NAMESPACE_SUFFIX }} SEND_RESULTS_TO_TRUNK: true @@ -161,5 +167,6 @@ jobs: FORGE_TEST_SUITE: framework_upgrade IMAGE_TAG: ${{ needs.fetch-last-released-docker-image-tag.outputs.IMAGE_TAG }} FORGE_RUNNER_DURATION_SECS: 300 + FORGE_CLUSTER_NAME: ${{ inputs.FORGE_CLUSTER_NAME }} FORGE_NAMESPACE: forge-framework-upgrade-${{ needs.determine-docker-build-metadata.outputs.FORGE_NAMESPACE_SUFFIX }} SEND_RESULTS_TO_TRUNK: true diff --git a/.github/workflows.bak/forge-stable.yaml b/.github/workflows.bak/forge-stable.yaml index 6dc2509d856..83beaa4ffbb 100644 --- a/.github/workflows.bak/forge-stable.yaml +++ b/.github/workflows.bak/forge-stable.yaml @@ -3,6 +3,7 @@ name: Continuous Forge Tests - Stable # We have various Forge Stable tests here, that test out different situations and workloads. # +# # Dashboard showing historical results: https://grafana.aptoslabs.com/d/bdnt45ggsg000f/forge-stable-performance?orgId=1 # Tests are named based on how they are set up, some of the common flavors are: @@ -10,23 +11,23 @@ name: Continuous Forge Tests - Stable # be more realisistic. They use "wrap_with_realistic_env", which sets: # * MultiRegionNetworkEmulationTest which splits nodes into 4 "regions", which have different # x-region and in-region latencies and reliability rates -# * CpuChaosTest which tries to make nodes have heterogenous hardware, by loading a few cores fully -# on a few nodes. But this is not too helpful, as block execution time variance is minimal +# * CpuChaosTest which tries to make nodes have heterogenous hardware, by loading a few cores fully +# on a few nodes. But this is not too helpful, as block execution time variance is minimal # (as we generally have a few idle cores, and real variance mostly comes from variance in cpu speed instead) -# * sweep - means running a multiple tests within a single test, by having everything the same, except for one +# * sweep - means running a multiple tests within a single test, by having everything the same, except for one # thing - i.e. the thing we sweep over. There are two main dimensions we "sweep" over: -# * load sweep - this generally uses const tps workload, and varies the load across the tests (i.e. 10 vs 100 vs 1000 TPS) +# * load sweep - this generally uses const tps workload, and varies the load across the tests (i.e. 10 vs 100 vs 1000 TPS) # * workload sweep - this varies the transaction type being submitted, trying to test out how the system behaves # when different part of the system are stressed (i.e. low vs high output sizes, good vs bad gas calibration, parallel vs sequential, etc) # * graceful - tests where we are overloading the system - i.e. submitting more transactions than we expect system to handle, # and seeing how it behaves. overall e2e latency is then high, but we can test that only validator -> block proposal has increased. # additionally, we generally add a small TPS high-fee traffic in these tests, to confirm it is unaffected by the high load. # * changing-working-quorum - tests where we intentionally make nodes unreachable (cut their network), and bring them back, -# and go to cut network on next set of nodes - requiring state-sync to catch up, consensus to work with different set of +# and go to cut network on next set of nodes - requiring state-sync to catch up, consensus to work with different set of # nodes being required to form consensus. During each iteration, we test that enough progress was made. # # Main success criteria used across the tests are: -# * throughput and expiration/rejection rate +# * throughput and expiration/rejection rate # * latency (avg / p50 / p90 / p99 ) # * latency breakdown across the components - currently within a validator alone: # batch->pos->proposal->ordered->committed @@ -44,7 +45,6 @@ permissions: pull-requests: write contents: read id-token: write - actions: write #required for workflow cancellation via check-aptos-core on: # Allow triggering manually @@ -62,31 +62,33 @@ on: required: true type: choice description: The specific stable test to run. If 'all', all stable tests will be run - default: 'all' + default: "all" options: - all - framework-upgrade-test - # Test varies the load, i.e. sending 10, 100, 1000, 5000, etc TPS, and then measuring + # Test varies the load, i.e. sending 10, 100, 1000, 5000, etc TPS, and then measuring # onchain TPS, expired rate, as well as p50/p90/p99 latency, among other things, - # testing that we don't degrade performance both for low, mid and high loads. + # testing that we don't degrade performance both for low, mid and high loads. - realistic-env-load-sweep - # Test varies the workload, across some basic workloads (i.e. some cheap, some expensive), + # Test varies the workload, across some basic workloads (i.e. some cheap, some expensive), # and checks that throughput and performance across different stages - realistic-env-workload-sweep + # Test runs different variants of the orderbook workload + - realistic-env-orderbook-workload-sweep # Test sends ConstTps workload above what the system can handle, while additionally sending # non-small high-fee traffic (1000 TPS), and measures overall system performance. - realistic-env-graceful-overload - # Test varies the workload (opposite ends of gas calibration, high and low output sizes, - # sequential / parallel, etc), and sends ConstTPS for each above what the system can handle, - # while sending low TPS of high fee transactions. And primarily confirms that high-fee traffic + # Test varies the workload (opposite ends of gas calibration, high and low output sizes, + # sequential / parallel, etc), and sends ConstTPS for each above what the system can handle, + # while sending low TPS of high fee transactions. And primarily confirms that high-fee traffic # has predictably low latency, and execution pipeline doesn't get backed up. - realistic-env-graceful-workload-sweep - # Test varies workload, which is user-contracts, such that max throughput varies from high to mid to low, + # Test varies workload, which is user-contracts, such that max throughput varies from high to mid to low, # while testing that unrelated transactions paying the same gas price, are able to go through. - realistic-env-fairness-workload-sweep # Test which tunes all configurations for largest throughput possible (potentially sacrificing latency a bit) - realistic-network-tuned-for-throughput - # Run small-ish load, but checks that at all times all nodes are making progress, + # Run small-ish load, but checks that at all times all nodes are making progress, # catching any unexpected unreliabilities/delays in consensus - consensus-stress-test # Send a mix of different workloads, to catch issues with different interactions of workloads. @@ -96,7 +98,7 @@ on: - fullnode-reboot-stress-test - compat # Send low TPS (100 TPS) - # Cut network on enough nodes, such that all others are needed for consensus. Then bring a few back, and cut + # Cut network on enough nodes, such that all others are needed for consensus. Then bring a few back, and cut # same amount of new ones - requiring all that were brought back to state-sync and continue executing. # Check that in each iteration - we were able to make meaningful progress. - changing-working-quorum-test @@ -105,23 +107,23 @@ on: - changing-working-quorum-test-high-load - pfn-const-tps-realistic-env # Run a production config (same as land blocking run) max load (via mempool backlog), but run it for 2 hours, - # to check reliability and consistency of the newtork. + # to check reliability and consistency of the newtork. - realistic-env-max-load-long + - etna JOB_PARALLELISM: required: false type: number description: The number of test jobs to run in parallel. If not specified, defaults to 1 default: 1 - schedule: - - cron: "0 22 * * 1-5" # The main branch cadence. This runs every Mon-Fri + # schedule: # NOTE: the schedule is dictated by PIES pull_request: paths: - ".github/workflows/forge-stable.yaml" - "testsuite/find_latest_image.py" concurrency: - group: forge-stable-${{ format('{0}-{1}-{2}-{3}', github.ref_name, inputs.GIT_SHA, inputs.IMAGE_TAG, inputs.TEST_NAME) }} + group: forge-stable-${{ format('{0}-{1}-{2}-{3}', github.ref_name, inputs.GIT_SHA || github.sha || github.head_ref || github.ref, inputs.IMAGE_TAG, inputs.TEST_NAME) }} cancel-in-progress: true env: @@ -152,6 +154,7 @@ jobs: { TEST_NAME: 'framework-upgrade-test', FORGE_RUNNER_DURATION_SECS: 7200, FORGE_TEST_SUITE: 'framework_upgrade' }, { TEST_NAME: 'realistic-env-load-sweep', FORGE_RUNNER_DURATION_SECS: 1800, FORGE_TEST_SUITE: 'realistic_env_load_sweep' }, { TEST_NAME: 'realistic-env-workload-sweep', FORGE_RUNNER_DURATION_SECS: 2000, FORGE_TEST_SUITE: 'realistic_env_workload_sweep' }, + { TEST_NAME: 'realistic-env-orderbook-workload-sweep', FORGE_RUNNER_DURATION_SECS: 2000, FORGE_TEST_SUITE: 'realistic_env_orderbook_workload_sweep' }, { TEST_NAME: 'realistic-env-graceful-overload', FORGE_RUNNER_DURATION_SECS: 1200, FORGE_TEST_SUITE: 'realistic_env_graceful_overload' }, { TEST_NAME: 'realistic-env-graceful-workload-sweep', FORGE_RUNNER_DURATION_SECS: 2100, FORGE_TEST_SUITE: 'realistic_env_graceful_workload_sweep' }, { TEST_NAME: 'realistic-env-fairness-workload-sweep', FORGE_RUNNER_DURATION_SECS: 900, FORGE_TEST_SUITE: 'realistic_env_fairness_workload_sweep' }, @@ -164,7 +167,8 @@ jobs: { TEST_NAME: 'changing-working-quorum-test', FORGE_RUNNER_DURATION_SECS: 1200, FORGE_TEST_SUITE: 'changing_working_quorum_test', FORGE_ENABLE_FAILPOINTS: true }, { TEST_NAME: 'changing-working-quorum-test-high-load', FORGE_RUNNER_DURATION_SECS: 900, FORGE_TEST_SUITE: 'changing_working_quorum_test_high_load', FORGE_ENABLE_FAILPOINTS: true }, { TEST_NAME: 'pfn-const-tps-realistic-env', FORGE_RUNNER_DURATION_SECS: 900, FORGE_TEST_SUITE: 'pfn_const_tps_with_realistic_env' }, - { TEST_NAME: 'realistic-env-max-load-long', FORGE_RUNNER_DURATION_SECS: 7200, FORGE_TEST_SUITE: 'realistic_env_max_load_large' } + { TEST_NAME: 'realistic-env-max-load-long', FORGE_RUNNER_DURATION_SECS: 7200, FORGE_TEST_SUITE: 'realistic_env_max_load_large' }, + { TEST_NAME: 'etna', FORGE_RUNNER_DURATION_SECS: 7200, FORGE_TEST_SUITE: 'etna', FORGE_IMAGE_NAME: 'etna-rust' } ]; const matrix = testName != "all" ? tests.filter(test => test.TEST_NAME === testName) : tests; @@ -207,19 +211,16 @@ jobs: - name: Determine branch based on cadence id: determine-test-branch - # NOTE: the schedule cron MUST match the one in the 'on.schedule.cron' section above run: | BRANCH="" - if [[ "${{ github.event_name }}" == "schedule" ]]; then - echo "BRANCH=main" >> $GITHUB_OUTPUT - elif [[ "${{ github.event_name }}" == "push" ]]; then + if [[ "${{ github.event_name }}" == "push" ]]; then echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_OUTPUT # on workflow_dispatch, this will simply use the inputs.GIT_SHA given (or the default) elif [[ -n "${{ inputs.GIT_SHA }}" ]]; then echo "BRANCH=${{ inputs.GIT_SHA }}" >> $GITHUB_OUTPUT # if GIT_SHA not provided, use the branch where workflow runs on else - echo "BRANCH=${{ github.head_ref }}" >> $GITHUB_OUTPUT + echo "BRANCH=${{ github.head_ref || github.ref_name }}" >> $GITHUB_OUTPUT fi echo "Branch: $(grep BRANCH= $GITHUB_OUTPUT)" # Use the branch hash instead of the full branch name to stay under kubernetes namespace length limit @@ -229,10 +230,6 @@ jobs: # Hashing the branch name echo "BRANCH_HASH=$(echo -n "${{ steps.determine-test-branch.outputs.BRANCH }}" | sha256sum | cut -c1-10)" >> $GITHUB_OUTPUT - - uses: aptos-labs/aptos-core/.github/actions/check-aptos-core@main - with: - cancel-workflow: ${{ github.event_name == 'schedule' }} # Cancel the workflow if it is scheduled on a fork - # actions/get-latest-docker-image-tag requires docker utilities and having authenticated to internal docker image registries - uses: aptos-labs/aptos-core/.github/actions/docker-setup@main id: docker-setup @@ -286,5 +283,7 @@ jobs: FORGE_RUNNER_DURATION_SECS: ${{ matrix.FORGE_RUNNER_DURATION_SECS }} FORGE_ENABLE_PERFORMANCE: ${{ matrix.FORGE_ENABLE_PERFORMANCE || false }} FORGE_ENABLE_FAILPOINTS: ${{ matrix.FORGE_ENABLE_FAILPOINTS || false }} + FORGE_IMAGE_NAME: ${{ matrix.FORGE_IMAGE_NAME }} POST_TO_SLACK: true - SEND_RESULTS_TO_TRUNK: true \ No newline at end of file + SEND_RESULTS_TO_TRUNK: true + FORGE_CONTINUOUS_TEST_MODE: true diff --git a/.github/workflows.bak/fuzzer-data-update.yml b/.github/workflows.bak/fuzzer-data-update.yml index 02e83ee841a..13172e841d1 100644 --- a/.github/workflows.bak/fuzzer-data-update.yml +++ b/.github/workflows.bak/fuzzer-data-update.yml @@ -6,11 +6,13 @@ on: - 'main' paths: - 'testsuite/fuzzer/data/**' + - '.github/workflows/fuzzer-data-update.yml' workflow_dispatch: permissions: contents: read id-token: write # Required for GCP Workload Identity federation + actions: write jobs: update-fuzzer-data: @@ -19,9 +21,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Rust - uses: aptos-labs/aptos-core/.github/actions/rust-setup@main - - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: @@ -39,17 +38,42 @@ jobs: # - move_bytecode_verifier_compiled_modules_seed_corpus # All of them reuse the same seed corpus, so we only need to download/upload one of them. - name: Download existing corpus + working-directory: testsuite/fuzzer/ run: | gcloud storage cp gs://aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip move_aptosvm_publish_and_run_seed_corpus.zip + gcloud storage cp gs://aptos-core-corpora/move_aptosvm_publish_and_run_transactional_seed_corpus.zip move_aptosvm_publish_and_run_transactional_seed_corpus.zip unzip -q move_aptosvm_publish_and_run_seed_corpus.zip -d move_aptosvm_publish_and_run_seed_corpus + unzip -q move_aptosvm_publish_and_run_transactional_seed_corpus.zip -d move_aptosvm_publish_and_run_transactional_seed_corpus - - name: Generate runnable states + - name: Generate runnable states from data + working-directory: testsuite/fuzzer/ run: | chmod +x ./fuzz.sh - ./fuzz.sh block-builder generate_runnable_states_recursive testsuite/fuzzer/data/0x1/ move_aptosvm_publish_and_run_seed_corpus + ./fuzz.sh block-builder generate_runnable_states_recursive data/0x1/ move_aptosvm_publish_and_run_seed_corpus + + - name: Generate transactional runnable states from data + working-directory: testsuite/fuzzer/ + run: | + ./fuzz.sh block-builder generate_transactional_runnable_states_recursive data/transactional/ move_aptosvm_publish_and_run_transactional_seed_corpus + + # TODO: split task based on directory changes + - name: Generate runnable states from e2e tests + working-directory: testsuite/fuzzer/ + run: | + ./fuzz.sh block-builder generate_runnable_states_recursive /aptos-move/e2e-move-tests move_aptosvm_publish_and_run_seed_corpus + + - name: Generate runnable states transactional from transactional tests + working-directory: testsuite/fuzzer/ + run: | + ./fuzz.sh block-builder generate_runnable_states_from_all_tests move_aptosvm_publish_and_run_transactional_seed_corpus + # TODO: run distillation before pushing(?) - name: Create and upload new corpus + working-directory: testsuite/fuzzer/ run: | zip -r move_aptosvm_publish_and_run_seed_corpus.zip move_aptosvm_publish_and_run_seed_corpus gcloud storage cp move_aptosvm_publish_and_run_seed_corpus.zip gs://aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip - gcloud storage objects update gs://aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip --add-acl=publicRead + gcloud storage objects update gs://aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip --canned-acl=publicRead + zip -r move_aptosvm_publish_and_run_transactional_seed_corpus.zip move_aptosvm_publish_and_run_transactional_seed_corpus + gcloud storage cp move_aptosvm_publish_and_run_transactional_seed_corpus.zip gs://aptos-core-corpora/move_aptosvm_publish_and_run_transactional_seed_corpus.zip + gcloud storage objects update gs://aptos-core-corpora/move_aptosvm_publish_and_run_transactional_seed_corpus.zip --canned-acl=publicRead diff --git a/.github/workflows.bak/node-api-compatibility-tests.yaml b/.github/workflows.bak/node-api-compatibility-tests.yaml index 2bc6c6bf0df..15e36c81a5c 100644 --- a/.github/workflows.bak/node-api-compatibility-tests.yaml +++ b/.github/workflows.bak/node-api-compatibility-tests.yaml @@ -63,7 +63,7 @@ jobs: AWS_DOCKER_ARTIFACT_REPO: ${{ secrets.AWS_DOCKER_ARTIFACT_REPO }} GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 if: ${{ !inputs.SKIP_JOB }} with: node-version-file: .node-version @@ -83,7 +83,7 @@ jobs: if: ${{ !inputs.SKIP_JOB }} # Build the API specs. - - uses: nick-fields/retry@7f8f3d9f0f62fe5925341be21c2e8314fd4f7c7c # pin@v2 + - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 if: ${{ !inputs.SKIP_JOB }} name: generate-yaml-spec with: @@ -91,7 +91,7 @@ jobs: timeout_minutes: 20 command: docker run --rm --mount=type=bind,source=${{ runner.temp }}/specs,target=/specs ${{ vars.GCP_DOCKER_ARTIFACT_REPO }}/tools:${IMAGE_TAG} aptos-openapi-spec-generator -f yaml -o /specs/spec.yaml - - uses: nick-fields/retry@7f8f3d9f0f62fe5925341be21c2e8314fd4f7c7c # pin@v2 + - uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # pin@v3.0.2 if: ${{ !inputs.SKIP_JOB }} name: generate-json-spec with: diff --git a/.github/workflows.bak/prover-daily-test.yaml b/.github/workflows.bak/prover-daily-test.yaml index c222e58815e..f2740189228 100644 --- a/.github/workflows.bak/prover-daily-test.yaml +++ b/.github/workflows.bak/prover-daily-test.yaml @@ -2,9 +2,7 @@ name: "Prover Daily Test" on: # Allow us to manually run this specific workflow without a PR workflow_dispatch: - # Until enabled on all PRs, run twice a week - schedule: - - cron: "14 14 */3 * *" + # schedule: # NOTE: when ready to re-enable, the schedule should be dictated by PIES pull_request: paths: - ".github/workflows/prover-daily-test.yaml" diff --git a/.github/workflows.bak/provision-replay-verify-archive-disks.yaml b/.github/workflows.bak/provision-replay-verify-archive-disks.yaml index 0cf64b7790c..6ed2d6963ac 100644 --- a/.github/workflows.bak/provision-replay-verify-archive-disks.yaml +++ b/.github/workflows.bak/provision-replay-verify-archive-disks.yaml @@ -13,8 +13,7 @@ on: paths: - ".github/workflows/provision-replay-verify-archive-disks.yaml" - ".github/workflows/workflow-run-replay-verify-archive-storage-provision.yaml" - schedule: - - cron: "0 8 * * 1,3,5" # This runs every Mon,Wed,Fri UTC 08:00 + # schedule: # NOTE: the schedule is dictated by PIES permissions: contents: read @@ -32,12 +31,6 @@ jobs: determine-test-metadata: runs-on: ubuntu-latest steps: - # checkout the repo first, so check-aptos-core can use it and cancel the workflow if necessary - - uses: actions/checkout@v4 - - uses: ./.github/actions/check-aptos-core - with: - cancel-workflow: ${{ github.event_name == 'schedule' }} # Cancel the workflow if it is scheduled on a fork - - name: Debug run: | echo "Event name: ${{ github.event_name }}" @@ -45,17 +38,15 @@ jobs: provision-testnet: if: | - github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' && (inputs.NETWORK == 'testnet' || inputs.NETWORK == 'all') needs: determine-test-metadata uses: ./.github/workflows/workflow-run-replay-verify-archive-storage-provision.yaml secrets: inherit with: NETWORK: testnet - + provision-mainnet: if: | - github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' && (inputs.NETWORK == 'mainnet' || inputs.NETWORK == 'all') needs: determine-test-metadata uses: ./.github/workflows/workflow-run-replay-verify-archive-storage-provision.yaml diff --git a/.github/workflows.bak/prune-old-workflow-runs.yaml b/.github/workflows.bak/prune-old-workflow-runs.yaml index e7e736f195c..3a63e7b5f5d 100644 --- a/.github/workflows.bak/prune-old-workflow-runs.yaml +++ b/.github/workflows.bak/prune-old-workflow-runs.yaml @@ -4,9 +4,7 @@ name: Prune old workflow runs on: workflow_dispatch: - schedule: - # every day at 3am PST - - cron: "0 10 * * *" + # schedule: # NOTE: the schedule is dictated by PIES permissions: actions: write @@ -17,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - uses: pnpm/action-setup@v4 diff --git a/.github/workflows.bak/run-fullnode-sync.yaml b/.github/workflows.bak/run-fullnode-sync.yaml index ff22ae6ab08..16606ead32b 100644 --- a/.github/workflows.bak/run-fullnode-sync.yaml +++ b/.github/workflows.bak/run-fullnode-sync.yaml @@ -1,5 +1,5 @@ # This workflow is a simple wrapper around the fullnode-sync github -# action. It invokes the action with all the neccessary configurations +# action. It invokes the action with all the necessary configurations # required by the specific fullnode sync test instance. name: "Run Fullnode Sync" @@ -8,50 +8,50 @@ on: workflow_call: inputs: TEST_NAME: - description: "The unique name of the fullnode test." + description: "The name of the test run (only used for logs, e.g., slack failures)." type: string required: true GIT_REF: - description: "The aptos-core git ref (GIT_REF or commit hash) to switch to before running the fullnode." + description: "The aptos-core reference (GIT_REF or commit hash) to compile the fullnode." type: string required: true NETWORK: - description: "The network to connect the fullnode to: devnet, testnet, or mainnet." + description: "The network to connect the fullnode to (e.g., devnet, testnet, mainnet)." type: string required: true BOOTSTRAPPING_MODE: - description: "The state sync bootstrapping mode for the fullnode." + description: "The fullnode bootstrapping mode (e.g., DownloadLatestStates)." type: string required: true CONTINUOUS_SYNCING_MODE: - description: "The state sync continuous syncing mode for the fullnode." + description: "The fullnode continuous syncing mode (e.g., ApplyTransactionOutputs)." type: string required: true TIMEOUT_MINUTES: - description: "The number of minutes to wait for fullnode sync to finish." + description: "The number of minutes to wait for fullnode to sync." type: number required: false default: 300 # Run for at most 5 hours workflow_dispatch: inputs: TEST_NAME: - description: "The unique name of the fullnode test." + description: "The name of the test run (only used for logs, e.g., slack failures)." type: string required: true GIT_REF: - description: "The aptos-core GIT_REF (or ref) to switch to before running the fullnode." + description: "The aptos-core reference (GIT_REF or commit hash) to compile the fullnode." type: string required: true NETWORK: - description: "The network to connect the fullnode to: devnet, testnet, or mainnet." + description: "The network to connect the fullnode to (e.g., devnet, testnet, mainnet)." type: string required: true BOOTSTRAPPING_MODE: - description: "The state sync bootstrapping mode for the fullnode." + description: "The fullnode bootstrapping mode (e.g., DownloadLatestStates)." type: string required: true CONTINUOUS_SYNCING_MODE: - description: "The state sync continuous syncing mode for the fullnode." + description: "The fullnode continuous syncing mode (e.g., ApplyTransactionOutputs)." type: string required: true @@ -62,6 +62,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Dump all inputs to GITHUB_STEP_SUMMARY + run: | + echo "GIT_REF: ${{ inputs.GIT_REF }}" >> $GITHUB_STEP_SUMMARY + echo "NETWORK: ${{ inputs.NETWORK }}" >> $GITHUB_STEP_SUMMARY + echo "BOOTSTRAPPING_MODE: ${{ inputs.BOOTSTRAPPING_MODE }}" >> $GITHUB_STEP_SUMMARY + echo "CONTINUOUS_SYNCING_MODE: ${{ inputs.CONTINUOUS_SYNCING_MODE }}" >> $GITHUB_STEP_SUMMARY + echo "DATA_DIR_FILE_PATH: ${{ runner.temp }}/" >> $GITHUB_STEP_SUMMARY + echo "NODE_LOG_FILE_PATH: ${{ runner.temp }}/node_log" >> $GITHUB_STEP_SUMMARY + echo "METRICS_DUMP_FILE_PATH: ${{ runner.temp }}/metrics" >> $GITHUB_STEP_SUMMARY + - uses: ./.github/actions/fullnode-sync with: GIT_REF: ${{ inputs.GIT_REF }} diff --git a/.github/workflows.bak/semgrep.yaml b/.github/workflows.bak/semgrep.yaml index d05dbe27073..dccc6df12c7 100644 --- a/.github/workflows.bak/semgrep.yaml +++ b/.github/workflows.bak/semgrep.yaml @@ -4,8 +4,7 @@ on: workflow_dispatch: pull_request: types: [labeled, opened, synchronize, reopened, auto_merge_enabled] - schedule: - - cron: '0 * * * *' + # schedule: # NOTE: the schedule is dictated by PIES jobs: semgrep: @@ -25,3 +24,4 @@ jobs: env: SEMGREP_RULES: >- ./.github/linters/semgrep/pull-request-target-code-checkout.yaml + ./.github/linters/semgrep/disallow-schedule-trigger.yaml diff --git a/.github/workflows.bak/test-copy-images-to-dockerhub.yaml b/.github/workflows.bak/test-copy-images-to-dockerhub.yaml index 25c9e8387fa..f7daa1d7621 100644 --- a/.github/workflows.bak/test-copy-images-to-dockerhub.yaml +++ b/.github/workflows.bak/test-copy-images-to-dockerhub.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - uses: pnpm/action-setup@v4 diff --git a/.github/workflows.bak/windows-build.yaml b/.github/workflows.bak/windows-build.yaml index 124cc3e3341..aaab12d0952 100644 --- a/.github/workflows.bak/windows-build.yaml +++ b/.github/workflows.bak/windows-build.yaml @@ -4,16 +4,12 @@ name: "Windows CLI Build" on: workflow_dispatch: pull_request: - types: [ labeled, opened, synchronize, reopened, auto_merge_enabled ] - schedule: - # Run twice a day at 12PM PT and 8PM PT Monday through Friday - - cron: "0 19,3 * * 1-5" - # Run once a day at 12PM PT on Saturday and Sunday - - cron: "0 19 * * 6,0" + types: [labeled, opened, synchronize, reopened, auto_merge_enabled] + # schedule: # NOTE: the schedule is dictated by PIES jobs: windows-build: - runs-on: windows-latest + runs-on: windows-2025 if: | # Only run on each PR once an appropriate event occurs ( github.event_name == 'workflow_dispatch' || diff --git a/.github/workflows.bak/workflow-run-docker-rust-build.yaml b/.github/workflows.bak/workflow-run-docker-rust-build.yaml index ba98ebef651..58b5cd87bde 100644 --- a/.github/workflows.bak/workflow-run-docker-rust-build.yaml +++ b/.github/workflows.bak/workflow-run-docker-rust-build.yaml @@ -30,6 +30,11 @@ on: required: false type: string description: The target docker registry to push to + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not build and push images. + default: false workflow_dispatch: inputs: @@ -56,6 +61,11 @@ on: required: false type: string description: The target docker registry to push to + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not build and push images. + default: false env: GIT_SHA: ${{ inputs.GIT_SHA }} @@ -66,6 +76,10 @@ env: AWS_ECR_ACCOUNT_NUM: ${{ secrets.ENV_ECR_AWS_ACCOUNT_NUM }} GCP_DOCKER_ARTIFACT_REPO: ${{ vars.GCP_DOCKER_ARTIFACT_REPO }} TARGET_REGISTRY: ${{ inputs.TARGET_REGISTRY }} + GCP_DOCKER_BUILD_LOCK_BUCKET: "aptos-docker-build-lock-bucket" + PROFILE_RELEASE: ${{ inputs.PROFILE == 'release' && inputs.FEATURES == '' }} + PROFILE_PERF: ${{ inputs.PROFILE == 'performance' }} + FEATURE_FAILPOINTS: ${{ inputs.FEATURES == 'failpoints' }} permissions: contents: read @@ -103,7 +117,62 @@ jobs: AWS_DOCKER_ARTIFACT_REPO: ${{ secrets.AWS_DOCKER_ARTIFACT_REPO }} GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + - name: Check if docker images already exist + id: check-images + uses: aptos-labs/aptos-core/.github/actions/wait-images-ci@main + continue-on-error: true + with: + GIT_SHA: ${{ env.GIT_SHA }} + GCP_DOCKER_ARTIFACT_REPO: ${{ env.GCP_DOCKER_ARTIFACT_REPO }} + WAIT_FOR_IMAGE_SECONDS: 1 + PROFILE_RELEASE : ${{ env.PROFILE_RELEASE }} + PROFILE_PERF: ${{ env.PROFILE_PERF }} + FEATURE_FAILPOINTS: ${{ env.FEATURE_FAILPOINTS }} + + - name: Authenticate to Google Cloud + id: auth + uses: "google-github-actions/auth@v2" + with: + workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} + + - name: Lock Check and Creation + id: lock + if: ${{ steps.check-images.outcome == 'failure' && inputs.DRY_RUN == false }} + run: | + set +e + output=$(gcloud storage cat gs://${{ env.GCP_DOCKER_BUILD_LOCK_BUCKET }}/${{ env.GIT_SHA }}.txt) + result=$? + set -e + if [[ $result -eq 0 ]]; then + if [[ "$output" == *"${{ github.run_id }}"* ]]; then + echo "Lock file for current workflow exists. Continuing ..." + else + echo "Lock file exists: Current workflow building: " | tee -a $GITHUB_STEP_SUMMARY + echo "$output" | tee -a $GITHUB_STEP_SUMMARY + echo "Attempting to wait for build to finish ..." | tee -a $GITHUB_STEP_SUMMARY + echo "wait_images=true" >> $GITHUB_OUTPUT + fi + else + echo "Lock file does not exist" + echo "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" > ${{ env.GIT_SHA }}.txt + gcloud storage cp ${{ env.GIT_SHA }}.txt gs://${{ env.GCP_DOCKER_BUILD_LOCK_BUCKET }}/${{ env.GIT_SHA }}.txt + echo "Docker Build locked" + fi + + - name: Wait for docker images to build + uses: aptos-labs/aptos-core/.github/actions/wait-images-ci@main + if: ${{ steps.lock.outputs.wait_images == 'true' }} + with: + GIT_SHA: ${{ env.GIT_SHA }} + GCP_DOCKER_ARTIFACT_REPO: ${{ env.GCP_DOCKER_ARTIFACT_REPO }} + WAIT_FOR_IMAGE_SECONDS: 1200 # 20 minutes + PROFILE_RELEASE : ${{ env.PROFILE_RELEASE }} + PROFILE_PERF: ${{ env.PROFILE_PERF }} + FEATURE_FAILPOINTS: ${{ env.FEATURE_FAILPOINTS }} + - name: Build and Push Rust images + if: ${{ steps.check-images.outcome == 'failure' && steps.lock.outputs.wait_images != 'true' && inputs.DRY_RUN == false }} run: docker/builder/docker-bake-rust-all.sh env: PROFILE: ${{ env.PROFILE }} @@ -118,4 +187,9 @@ jobs: sudo systemctl stop docker sudo tar --posix -cf /home/runner/docker-cache.tzst -P -C /var/lib/docker --use-compress-program zstdmt . fi - + + - name: Post-run Lock Cleanup + if: ${{ always() && steps.lock.outcome == 'success' }} + run: | + gcloud storage rm gs://${{ env.GCP_DOCKER_BUILD_LOCK_BUCKET }}/${GIT_SHA}.txt || true + echo "Docker Build unlocked" diff --git a/.github/workflows.bak/workflow-run-execution-performance.yaml b/.github/workflows.bak/workflow-run-execution-performance.yaml index 5fadd575719..d5155b9d41f 100644 --- a/.github/workflows.bak/workflow-run-execution-performance.yaml +++ b/.github/workflows.bak/workflow-run-execution-performance.yaml @@ -80,6 +80,7 @@ on: - MAINNET - MAINNET_LARGE_DB - EXECUTORS + - ORDER_BOOK type: choice description: Which set of tests to run. MAINNET/MAINNET_LARGE_DB are for performance validation of mainnet nodes. SKIP_MOVE_E2E: diff --git a/.github/workflows.bak/workflow-run-forge.yaml b/.github/workflows.bak/workflow-run-forge.yaml index 17eefd7350e..6aa4630c166 100644 --- a/.github/workflows.bak/workflow-run-forge.yaml +++ b/.github/workflows.bak/workflow-run-forge.yaml @@ -16,6 +16,11 @@ on: required: false type: string description: The docker image tag to use for forge runner. If not specified, falls back on GIT_SHA, and then to the latest commits on the current branch + + FORGE_IMAGE_NAME: + required: false + type: string + description: The docker image name to use for forge runner. Defaults to `forge`. FORGE_NAMESPACE: required: false type: string @@ -92,6 +97,12 @@ on: type: boolean description: Send forge results to trunk.io + FORGE_CONTINUOUS_TEST_MODE: + required: false + type: boolean + default: false + description: Indicates that this is a continuous test, not a land blocking test. + env: AWS_ACCOUNT_NUM: ${{ secrets.ENV_ECR_AWS_ACCOUNT_NUM }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -101,6 +112,7 @@ env: AWS_REGION: us-west-2 IMAGE_TAG: ${{ inputs.IMAGE_TAG }} FORGE_IMAGE_TAG: ${{ inputs.FORGE_IMAGE_TAG }} + FORGE_IMAGE_NAME: ${{ inputs.FORGE_IMAGE_NAME }} FORGE_BLOCKING: ${{ secrets.FORGE_BLOCKING }} FORGE_CLUSTER_NAME: ${{ inputs.FORGE_CLUSTER_NAME }} FORGE_OUTPUT: forge_output.txt @@ -118,6 +130,7 @@ env: FORGE_ENABLE_FAILPOINTS: ${{ inputs.FORGE_ENABLE_FAILPOINTS }} FORGE_ENABLE_PERFORMANCE: ${{ inputs.FORGE_ENABLE_PERFORMANCE }} FORGE_RETAIN_DEBUG_LOGS: ${{ inputs.FORGE_RETAIN_DEBUG_LOGS }} + FORGE_CONTINUOUS_TEST_MODE: ${{ inputs.FORGE_CONTINUOUS_TEST_MODE }} COMMENT_HEADER: ${{ inputs.COMMENT_HEADER }} VERBOSE: true FORGE_NUM_VALIDATORS: ${{ inputs.FORGE_NUM_VALIDATORS }} diff --git a/.github/workflows.bak/workflow-run-replay-verify-on-archive.yaml b/.github/workflows.bak/workflow-run-replay-verify-on-archive.yaml index f1fce9a8006..66da30f3421 100644 --- a/.github/workflows.bak/workflow-run-replay-verify-on-archive.yaml +++ b/.github/workflows.bak/workflow-run-replay-verify-on-archive.yaml @@ -20,7 +20,12 @@ on: required: false type: string description: Optional version to end replaying. If not specified, replay-verify will determines end version itself. - + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not run replay verify. + default: false + workflow_dispatch: inputs: NETWORK: @@ -39,9 +44,25 @@ on: required: false type: string description: The end version to use for the backup. If not specified, it will use the latest version. + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not run replay verify. + default: false jobs: + build-images: + secrets: inherit + uses: aptos-labs/aptos-core/.github/workflows/workflow-run-docker-rust-build.yaml@main + with: + GIT_SHA: ${{ inputs.IMAGE_TAG || github.event.pull_request.head.sha || github.sha }} + TARGET_CACHE_ID: ${{ github.event.number && format('pr-{0}', github.event.number) || github.ref_name }} + PROFILE: performance + DRY_RUN: ${{ inputs.DRY_RUN }} + run-replay-verify: runs-on: ubuntu-latest-32-core # consider moving this to a smaller machien since the compute runs on GKE + timeout-minutes: 420 # 7 hours + needs: build-images steps: - name: Checkout code uses: actions/checkout@v4 @@ -58,7 +79,7 @@ jobs: GCP_SERVICE_ACCOUNT_EMAIL: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} EXPORT_GCP_PROJECT_VARIABLES: "false" GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} - GCP_AUTH_DURATION: "10800" + GCP_AUTH_DURATION: "25200" # 7 hours # Authenticate to Google Cloud the project is aptos-ci with credentails files generated - name: Authenticate to Google Cloud @@ -86,12 +107,13 @@ jobs: - name: "Setup GCloud project" shell: bash run: gcloud config set project aptos-devinfra-0 - + - uses: ./.github/actions/python-setup with: pyproject_directory: testsuite/replay-verify - name: Schedule replay verify + if: ${{ inputs.DRY_RUN == false }} env: GOOGLE_CLOUD_PROJECT: aptos-devinfra-0 run: | @@ -107,14 +129,15 @@ jobs: if [ -n "${{ inputs.IMAGE_TAG }}" ]; then CMD="$CMD --image_tag ${{ inputs.IMAGE_TAG }}" fi + CMD="$CMD --image_profile performance" eval $CMD - timeout-minutes: 300 + timeout-minutes: 420 # 7 hours # This is in case user manually cancel the step above, we still want to cleanup the resources - name: Post-run cleanup env: GOOGLE_CLOUD_PROJECT: aptos-devinfra-0 - if: ${{ always() }} + if: ${{ always() && inputs.DRY_RUN == false }} run: | cd testsuite/replay-verify CMD="poetry run python main.py --network ${{ inputs.NETWORK }} --cleanup" diff --git a/.github/workflows/build-versions.yaml b/.github/workflows/build-versions.yaml index 3fa9903f88f..887a614d6e1 100644 --- a/.github/workflows/build-versions.yaml +++ b/.github/workflows/build-versions.yaml @@ -5,12 +5,12 @@ on: workflow_dispatch: inputs: ref: - description: 'The git ref to build (branch, tag, sha).' + description: "The git ref to build (branch, tag, sha)." required: true - default: 'main' + default: "main" build_profile: - description: 'The cargo build profile to use.' - default: 'release' + description: "The cargo build profile to use." + default: "release" jobs: setup: @@ -72,7 +72,7 @@ jobs: echo "build_profile=${{ inputs.build_profile || 'release' }}" >> $GITHUB_OUTPUT binaries-aptos-node: - needs: + needs: - setup runs-on: blacksmith-16vcpu-ubuntu-2204 name: "Build ${{ matrix.binary.package }} with Nix" @@ -90,14 +90,14 @@ jobs: with: ref: ${{ inputs.ref || github.sha}} - name: Build binary ${{ matrix.binary.package }} - uses: movementlabsxyz/aptos-core/.github/actions/build-binary@m1 + uses: movement-network/aptos-core/.github/actions/build-binary@m1 with: binary_package: ${{ matrix.binary.package }} profile: ${{ needs.setup.outputs.build_profile }} github_token: ${{ secrets.GITHUB_TOKEN }} git_sha: ${{ needs.setup.outputs.git_sha }} container-aptos-node: - needs: + needs: - setup - binaries-aptos-node runs-on: blacksmith-16vcpu-ubuntu-2204 @@ -130,11 +130,11 @@ jobs: path: ${{ env.TARGET_FOLDER }} - name: List binaries run: ls -la ${{ env.TARGET_FOLDER }} - + - name: Build Container - uses: movementlabsxyz/aptos-core/.github/actions/build-container@m1 + uses: movement-network/aptos-core/.github/actions/build-container@m1 with: - image_name: ghcr.io/movementlabsxyz/aptos-node + image_name: ghcr.io/movement-network/aptos-node dockerfile_subdir: aptos-node build_args: | BINARY_PATH=${{ env.TARGET_FOLDER }} @@ -170,9 +170,9 @@ jobs: - name: List binaries run: ls -la ${{ env.TARGET_FOLDER }} - name: Build Container - uses: movementlabsxyz/aptos-core/.github/actions/build-container@m1 + uses: movement-network/aptos-core/.github/actions/build-container@m1 with: - image_name: ghcr.io/movementlabsxyz/aptos-debugger + image_name: ghcr.io/movement-network/aptos-debugger dockerfile_subdir: aptos-debugger build_args: | BINARY_PATH=${{ env.TARGET_FOLDER }} @@ -185,7 +185,7 @@ jobs: git_sha: ${{ needs.setup.outputs.git_sha }} binaries-aptos-faucet-service: - needs: + needs: - setup runs-on: blacksmith-16vcpu-ubuntu-2204 name: "Build ${{ matrix.binary.package }} with Nix" @@ -200,14 +200,14 @@ jobs: with: ref: ${{ inputs.ref || github.sha}} - name: Build binary ${{ matrix.binary.package }} - uses: movementlabsxyz/aptos-core/.github/actions/build-binary@m1 + uses: movement-network/aptos-core/.github/actions/build-binary@m1 with: binary_package: ${{ matrix.binary.package }} profile: ${{ needs.setup.outputs.build_profile }} github_token: ${{ secrets.GITHUB_TOKEN }} git_sha: ${{ needs.setup.outputs.git_sha }} container-aptos-faucet-service: - needs: + needs: - setup - binaries-aptos-faucet-service runs-on: blacksmith-16vcpu-ubuntu-2204 @@ -230,11 +230,11 @@ jobs: path: ${{ env.TARGET_FOLDER }} - name: List binaries run: ls -la ${{ env.TARGET_FOLDER }} - + - name: Build Container - uses: movementlabsxyz/aptos-core/.github/actions/build-container@m1 + uses: movement-network/aptos-core/.github/actions/build-container@m1 with: - image_name: ghcr.io/movementlabsxyz/aptos-faucet-service + image_name: ghcr.io/movement-network/aptos-faucet-service dockerfile_subdir: aptos-faucet-service build_args: | BINARY_PATH=${{ env.TARGET_FOLDER }} @@ -247,7 +247,7 @@ jobs: git_sha: ${{ needs.setup.outputs.git_sha }} binaries-aptos-tools: - needs: + needs: - setup runs-on: blacksmith-16vcpu-ubuntu-2204 name: "Build ${{ matrix.binary.package }} with Nix" @@ -262,9 +262,9 @@ jobs: with: ref: ${{ inputs.ref || github.sha}} - name: Build binary ${{ matrix.binary.package }} - uses: movementlabsxyz/aptos-core/.github/actions/build-binary@m1 + uses: movement-network/aptos-core/.github/actions/build-binary@m1 with: binary_package: ${{ matrix.binary.package }} profile: ${{ needs.setup.outputs.build_profile }} github_token: ${{ secrets.GITHUB_TOKEN }} - git_sha: ${{ needs.setup.outputs.git_sha }} \ No newline at end of file + git_sha: ${{ needs.setup.outputs.git_sha }} diff --git a/.github/workflows/claude-audit-pr.yml b/.github/workflows/claude-audit-pr.yml index ee15ab07902..ba66d607551 100644 --- a/.github/workflows/claude-audit-pr.yml +++ b/.github/workflows/claude-audit-pr.yml @@ -13,7 +13,7 @@ name: Claude Audit PR # because that would expose repository secrets to untrusted code. # # Audit *content* (subagent definition, analyzers, prompt, settings) lives in -# movementlabsxyz/claude-pr-reviewer and is checked out + staged at runtime. +# movement-network/claude-pr-reviewer and is checked out + staged at runtime. # Bump REVIEWER_REF below to upgrade. See that repo's README for the consumer # contract. @@ -43,7 +43,7 @@ concurrency: env: # Pin to a tag (e.g. v1, v0.1.0) or an immutable SHA. Rolling tags pick up # patches automatically; SHAs require a bump PR but are tamper-evident. - REVIEWER_REPO: movementlabsxyz/claude-pr-reviewer + REVIEWER_REPO: movement-network/claude-pr-reviewer REVIEWER_REF: v1 jobs: diff --git a/.github/workflows/publish-builder-images.yaml b/.github/workflows/publish-builder-images.yaml index 2f3987372b6..5fc8a10339c 100644 --- a/.github/workflows/publish-builder-images.yaml +++ b/.github/workflows/publish-builder-images.yaml @@ -30,7 +30,7 @@ permissions: env: REGISTRY: ghcr.io - IMAGE_NAMESPACE: ghcr.io/movementlabsxyz + IMAGE_NAMESPACE: ghcr.io/movement-network DEBIAN_CONTEXT: docker-image://debian:bullseye@sha256:cf48c31af360e1c0a0aedd33aae4d928b68c2cdf093f1612650eb1ff434d1c34 PROFILE: release FEATURES: "" diff --git a/.github/workflows/replay-verify-mainnet.yaml b/.github/workflows/replay-verify-mainnet.yaml new file mode 100644 index 00000000000..70fe7bbc5e2 --- /dev/null +++ b/.github/workflows/replay-verify-mainnet.yaml @@ -0,0 +1,56 @@ +# This defines a workflow to replay transactions on the given chain with the latest aptos node software. +# In order to trigger it go to the Actions Tab of the Repo, click "replay-verify" and then "Run Workflow". +# +# On PR, a single test case will run. On workflow_dispatch, you may specify the CHAIN_NAME to verify. + +name: "Replay-verify on archive: Mainnet" +on: + # Allow triggering manually + workflow_dispatch: + inputs: + IMAGE_TAG: + required: false + type: string + description: The image tag of the feature branch to test, if not specified, it will use the latest commit on current branch. + START_VERSION: + required: false + type: string + description: Optional version to start replaying. If not specified, replay-verify will determine start version itself. + END_VERSION: + required: false + type: string + description: Optional version to end replaying. If not specified, replay-verify will determine end version itself. + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not run replay verify nor build images. + default: false + pull_request: + paths: + - ".github/workflows/replay-verify-mainnet.yaml" + - ".github/workflows/workflow-run-replay-verify-on-archive.yaml" + # schedule: # NOTE: the schedule is dictated by PIES + +permissions: + contents: read + id-token: write #required for GCP Workload Identity federation which we use to login into Google Artifact Registry + issues: read + pull-requests: read + +# cancel redundant builds +concurrency: + # cancel redundant builds on PRs (only on PR, not on branches) + group: ${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.ref) || github.sha }}-${{ inputs.IMAGE_TAG || 'latest' }} + cancel-in-progress: true + +jobs: + replay: + if: github.event_name == 'workflow_dispatch' + uses: ./.github/workflows/workflow-run-replay-verify-on-archive.yaml + secrets: inherit + with: + NETWORK: "mainnet" + IMAGE_TAG: ${{ inputs.IMAGE_TAG }} + START_VERSION: ${{ inputs.START_VERSION }} + END_VERSION: ${{ inputs.END_VERSION }} + DRY_RUN: ${{ inputs.DRY_RUN || false }} diff --git a/.github/workflows/replay-verify-testnet.yaml b/.github/workflows/replay-verify-testnet.yaml new file mode 100644 index 00000000000..4616c942e72 --- /dev/null +++ b/.github/workflows/replay-verify-testnet.yaml @@ -0,0 +1,56 @@ +# This defines a workflow to replay transactions on the given chain with the latest aptos node software. +# In order to trigger it go to the Actions Tab of the Repo, click "replay-verify" and then "Run Workflow". +# +# On PR, a single test case will run. On workflow_dispatch, you may specify the CHAIN_NAME to verify. + +name: "Replay-verify on archive: Testnet" +on: + # Allow triggering manually + workflow_dispatch: + inputs: + IMAGE_TAG: + required: false + type: string + description: The image tag of the feature branch to test, if not specified, it will use the latest commit on current branch. + START_VERSION: + required: false + type: string + description: Optional version to start replaying. If not specified, replay-verify will determine start version itself. + END_VERSION: + required: false + type: string + description: Optional version to end replaying. If not specified, replay-verify will determine end version itself. + DRY_RUN: + required: false + type: boolean + description: If true, the workflow will not run replay verify nor build images. + default: false + pull_request: + paths: + - ".github/workflows/replay-verify-testnet.yaml" + - ".github/workflows/workflow-run-replay-verify-on-archive.yaml" + # schedule: # NOTE: the schedule is dictated by PIES + +permissions: + contents: read + id-token: write #required for GCP Workload Identity federation which we use to login into Google Artifact Registry + issues: read + pull-requests: read + +# cancel redundant builds +concurrency: + # cancel redundant builds on PRs (only on PR, not on branches) + group: ${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.ref) || github.sha }}-${{ inputs.IMAGE_TAG || 'latest' }} + cancel-in-progress: true + +jobs: + replay: + if: github.event_name == 'workflow_dispatch' + uses: ./.github/workflows/workflow-run-replay-verify-on-archive.yaml + secrets: inherit + with: + NETWORK: "testnet" + IMAGE_TAG: ${{ inputs.IMAGE_TAG }} + START_VERSION: ${{ inputs.START_VERSION }} + END_VERSION: ${{ inputs.END_VERSION }} + DRY_RUN: ${{ inputs.DRY_RUN || false }} diff --git a/.gitignore b/.gitignore index 383d9e8dbd7..ca4a3791589 100644 --- a/.gitignore +++ b/.gitignore @@ -148,3 +148,9 @@ genesis_antithesis_*/ # Ignore generated credentials from google-github-actions/auth gha-creds-*.json + +# Ignore cache for move-package-resolver tests +third_party/move/tools/move-package-resolver/cache + +# Ignore cache for docs +.docs-cache \ No newline at end of file diff --git a/.watchmanconfig b/.watchmanconfig new file mode 100644 index 00000000000..1b606a64cee --- /dev/null +++ b/.watchmanconfig @@ -0,0 +1,3 @@ +{ + "ignore_dirs": ["target"] +} diff --git a/Cargo.lock b/Cargo.lock index aa5da02afb8..2d1aa7a7786 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -117,7 +117,7 @@ dependencies = [ "once_cell", "serde", "version_check", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -345,6 +345,8 @@ dependencies = [ "http 0.2.11", "hyper 0.14.28", "sha256", + "tikv-jemalloc-ctl", + "tikv-jemalloc-sys", "tokio", "url", ] @@ -361,6 +363,7 @@ dependencies = [ "move-vm-types", "once_cell", "test-case", + "triomphe", ] [[package]] @@ -387,6 +390,7 @@ dependencies = [ "aptos-runtimes", "aptos-sdk", "aptos-storage-interface", + "aptos-transaction-filters", "aptos-types", "aptos-vm", "bcs 0.1.4", @@ -410,6 +414,7 @@ dependencies = [ "rand 0.7.3", "regex", "reqwest 0.11.23", + "rstest", "serde", "serde_json", "tokio", @@ -609,6 +614,7 @@ dependencies = [ "aptos-aggregator", "aptos-crypto", "aptos-drop-helper", + "aptos-gas-schedule", "aptos-infallible", "aptos-logger", "aptos-metrics-core", @@ -626,6 +632,7 @@ dependencies = [ "concurrent-queue", "criterion", "crossbeam", + "dashmap 7.0.0-rc2", "derivative", "fail", "hashbrown 0.14.3", @@ -642,6 +649,7 @@ dependencies = [ "rand 0.7.3", "rayon", "test-case", + "triomphe", ] [[package]] @@ -655,14 +663,14 @@ dependencies = [ "bcs 0.1.4", "clap 4.5.21", "criterion", - "dashmap", + "dashmap 7.0.0-rc2", "itertools 0.13.0", - "jemallocator", "move-core-types", "once_cell", "rand 0.7.3", "rayon", "serde", + "tikv-jemallocator", ] [[package]] @@ -794,6 +802,7 @@ dependencies = [ "aptos-secure-storage", "aptos-short-hex-str", "aptos-temppath", + "aptos-transaction-filters", "aptos-types", "arr_macro", "bcs 0.1.4", @@ -847,6 +856,7 @@ dependencies = [ "aptos-network", "aptos-peer-monitoring-service-types", "aptos-reliable-broadcast", + "aptos-resource-viewer", "aptos-runtimes", "aptos-safety-rules", "aptos-schemadb", @@ -855,10 +865,10 @@ dependencies = [ "aptos-storage-interface", "aptos-temppath", "aptos-time-service", + "aptos-transaction-filters", "aptos-types", "aptos-validator-transaction-pool", "aptos-vm", - "aptos-vm-validator", "async-trait", "bcs 0.1.4", "byteorder", @@ -866,19 +876,20 @@ dependencies = [ "chrono", "claims", "clap 4.5.21", - "dashmap", + "dashmap 7.0.0-rc2", "enum_dispatch", "fail", "futures", "futures-channel", "hex", "itertools 0.13.0", - "lru 0.7.8", + "lru", "maplit", "mini-moka", "mirai-annotations", "mockall 0.11.4", "move-core-types", + "move-vm-runtime", "num-derive", "num-traits", "once_cell", @@ -891,7 +902,6 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "serde_yaml 0.8.26", "sha3 0.9.1", "strum 0.27.1", "strum_macros 0.27.1", @@ -966,19 +976,28 @@ dependencies = [ "anyhow", "aptos-crypto-derive", "arbitrary", - "ark-bls12-381", + "ark-bls12-381 0.4.0", + "ark-bls12-381 0.5.0", "ark-bn254", - "ark-ec", - "ark-ff", + "ark-ec 0.4.2", + "ark-ec 0.5.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", "ark-groth16", - "ark-serialize", - "ark-std", + "ark-poly 0.5.0", + "ark-relations", + "ark-serialize 0.4.2", + "ark-serialize 0.5.0", + "ark-snark", + "ark-std 0.5.0", "base64 0.13.1", "bcs 0.1.4", - "bitvec 1.0.1", + "bitvec", "blake2", "blake2-rfc", + "bls12_381", "blst", + "blstrs", "bulletproofs", "byteorder", "bytes", @@ -986,19 +1005,23 @@ dependencies = [ "curve25519-dalek 3.2.0", "curve25519-dalek-ng", "digest 0.9.0", + "dudect-bencher", "ed25519-dalek 1.0.1", "ff", + "group", "hex", "hkdf 0.10.0", + "itertools 0.13.0", "libsecp256k1", "merlin", "more-asserts", "neptune", "num-bigint 0.3.3", "num-integer", + "num-traits", "once_cell", "p256", - "poseidon-ark", + "pairing", "proptest", "proptest-derive", "rand 0.7.3", @@ -1055,7 +1078,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "claims", - "dashmap", + "dashmap 7.0.0-rc2", "futures", "itertools 0.13.0", "maplit", @@ -1127,12 +1150,12 @@ dependencies = [ "claims", "clap 4.5.21", "crossbeam-channel", - "dashmap", + "dashmap 7.0.0-rc2", "either", "hex", "indicatif 0.15.0", "itertools 0.13.0", - "lru 0.7.8", + "lru", "move-core-types", "once_cell", "ouroboros", @@ -1164,7 +1187,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "dashmap", + "dashmap 7.0.0-rc2", "move-core-types", "once_cell", "rand 0.7.3", @@ -1208,6 +1231,7 @@ dependencies = [ "aptos-temppath", "aptos-types", "aptos-vm", + "aptos-vm-environment", "bcs 0.1.4", "clap 4.5.21", "itertools 0.13.0", @@ -1228,22 +1252,30 @@ dependencies = [ "aptos-move-debugger", "aptos-push-metrics", "clap 4.5.21", - "jemallocator", + "tikv-jemallocator", "tokio", ] [[package]] name = "aptos-dkg" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "aptos-crypto", "aptos-crypto-derive", "aptos-runtimes", + "ark-bls12-381 0.5.0", + "ark-bn254", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "bcs 0.1.4", "blst", "blstrs", "criterion", + "derive_more 0.99.17", "ff", "group", "hex", @@ -1253,7 +1285,6 @@ dependencies = [ "num-integer", "num-traits", "num_cpus", - "once_cell", "pairing", "rand 0.7.3", "rand_core 0.5.1", @@ -1396,17 +1427,21 @@ version = "0.1.0" dependencies = [ "anyhow", "aptos-aggregator", + "aptos-api", "aptos-block-executor", "aptos-block-partitioner", "aptos-config", "aptos-crypto", "aptos-db", + "aptos-db-indexer", "aptos-executor", "aptos-executor-service", "aptos-executor-types", "aptos-experimental-ptx-executor", "aptos-experimental-runtimes", "aptos-genesis", + "aptos-indexer-grpc-fullnode", + "aptos-indexer-grpc-table-info", "aptos-infallible", "aptos-jellyfish-merkle", "aptos-logger", @@ -1414,6 +1449,7 @@ dependencies = [ "aptos-mvhashmap", "aptos-node-resource-metrics", "aptos-profiler 0.1.0", + "aptos-protos 1.3.1", "aptos-push-metrics", "aptos-sdk", "aptos-storage-interface", @@ -1430,11 +1466,11 @@ dependencies = [ "bytes", "chrono", "clap 4.5.21", - "dashmap", + "dashmap 7.0.0-rc2", "derivative", + "futures", "indicatif 0.15.0", "itertools 0.13.0", - "jemallocator", "move-core-types", "move-vm-types", "num_cpus", @@ -1442,9 +1478,12 @@ dependencies = [ "rand 0.7.3", "rayon", "serde", + "serde_json", "thread_local", + "tikv-jemallocator", "tokio", "toml 0.7.8", + "tonic 0.12.3", ] [[package]] @@ -1470,7 +1509,7 @@ dependencies = [ "clap 4.5.21", "crossbeam-channel", "ctrlc", - "dashmap", + "dashmap 7.0.0-rc2", "itertools 0.13.0", "num_cpus", "once_cell", @@ -1557,10 +1596,10 @@ dependencies = [ "aptos-metrics-core", "criterion", "itertools 0.13.0", - "jemallocator", "once_cell", "proptest", "rand 0.7.3", + "tikv-jemallocator", ] [[package]] @@ -1575,14 +1614,14 @@ dependencies = [ "aptos-metrics-core", "aptos-schemadb", "aptos-temppath", - "bitvec 1.0.1", + "bitvec", "criterion", "itertools 0.13.0", - "jemallocator", "once_cell", "proptest", "rand 0.7.3", "rocksdb", + "tikv-jemallocator", ] [[package]] @@ -1656,7 +1695,7 @@ dependencies = [ "hex", "ipnet", "iprange", - "lru 0.9.0", + "lru", "once_cell", "poem", "poem-openapi", @@ -1787,7 +1826,6 @@ dependencies = [ "clap 4.5.21", "env_logger", "futures", - "jemallocator", "once_cell", "rand 0.7.3", "random_word", @@ -1795,6 +1833,7 @@ dependencies = [ "serde_json", "serde_yaml 0.8.26", "sugars", + "tikv-jemallocator", "tokio", "url", ] @@ -1815,12 +1854,12 @@ dependencies = [ "aptos-types", "aptos-vm", "aptos-vm-types", - "ark-bls12-381", + "ark-bls12-381 0.5.0", "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "bcs 0.1.4", "better_any", "blake2-rfc", @@ -1869,6 +1908,7 @@ dependencies = [ "tempfile", "tiny-keccak", "toml 0.7.8", + "triomphe", ] [[package]] @@ -2007,6 +2047,15 @@ version = "0.1.0" name = "aptos-id-generator" version = "0.1.0" +[[package]] +name = "aptos-in-memory-cache" +version = "0.1.0" +dependencies = [ + "get-size", + "parking_lot 0.12.1", + "tokio", +] + [[package]] name = "aptos-indexer" version = "0.0.1" @@ -2054,13 +2103,13 @@ dependencies = [ "clap 4.5.21", "futures", "futures-core", - "jemallocator", "once_cell", "prost 0.13.4", "redis", "reqwest 0.11.23", "serde", "tempfile", + "tikv-jemallocator", "tokio", "tonic 0.12.3", "tracing", @@ -2081,13 +2130,13 @@ dependencies = [ "async-trait", "clap 4.5.21", "futures", - "jemallocator", "once_cell", "prost 0.13.4", "redis", "rstest", "serde", "serde_json", + "tikv-jemallocator", "tokio", "tokio-stream", "tonic 0.12.3", @@ -2109,13 +2158,13 @@ dependencies = [ "async-trait", "build_html", "clap 4.5.21", - "dashmap", + "dashmap 7.0.0-rc2", "futures", - "jemallocator", "once_cell", "prost 0.13.4", "rand 0.7.3", "serde", + "tikv-jemallocator", "tokio", "tokio-scoped", "tokio-stream", @@ -2137,10 +2186,10 @@ dependencies = [ "async-trait", "clap 4.5.21", "cloud-storage", - "jemallocator", "once_cell", "serde", "serde_json", + "tikv-jemallocator", "tokio", "tracing", ] @@ -2157,10 +2206,10 @@ dependencies = [ "async-trait", "clap 4.5.21", "futures", - "jemallocator", "once_cell", "redis", "serde", + "tikv-jemallocator", "tokio", "tracing", ] @@ -2176,9 +2225,9 @@ dependencies = [ "async-trait", "clap 4.5.21", "futures", - "jemallocator", "serde", "serde_json", + "tikv-jemallocator", "tokio", "tonic 0.12.3", "tracing", @@ -2238,6 +2287,27 @@ dependencies = [ "tonic-reflection", ] +[[package]] +name = "aptos-indexer-grpc-gateway" +version = "1.0.0" +dependencies = [ + "anyhow", + "aptos-indexer-grpc-server-framework", + "aptos-protos 1.3.1", + "async-trait", + "axum 0.7.5", + "clap 4.5.21", + "futures", + "http-body-util", + "hyper-util", + "jemallocator", + "serde", + "tokio", + "tonic 0.12.3", + "tracing", + "url", +] + [[package]] name = "aptos-indexer-grpc-in-memory-cache-benchmark" version = "0.1.0" @@ -2246,11 +2316,11 @@ dependencies = [ "aptos-indexer-grpc-utils", "aptos-protos 1.3.1", "futures", - "jemallocator", "lazy_static", "once_cell", "redis", "redis-test", + "tikv-jemallocator", "tokio", ] @@ -2267,14 +2337,14 @@ dependencies = [ "async-trait", "build_html", "clap 4.5.21", - "dashmap", + "dashmap 7.0.0-rc2", "futures", - "jemallocator", "once_cell", "prost 0.13.4", "rand 0.7.3", "serde", "serde_json", + "tikv-jemallocator", "tokio", "tokio-scoped", "tonic 0.12.3", @@ -2351,7 +2421,7 @@ dependencies = [ "bytesize", "chrono", "cloud-storage", - "dashmap", + "dashmap 7.0.0-rc2", "futures", "itertools 0.13.0", "lz4", @@ -2382,9 +2452,9 @@ dependencies = [ "async-trait", "clap 4.5.21", "futures", - "jemallocator", "serde", "serde_json", + "tikv-jemallocator", "tokio", "tokio-scoped", "tonic 0.12.3", @@ -2395,7 +2465,7 @@ dependencies = [ [[package]] name = "aptos-indexer-processor-sdk" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157#c63f6ee891e42cc50f92480c21d4afa86012b157" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" dependencies = [ "ahash 0.8.11", "anyhow", @@ -2480,10 +2550,10 @@ dependencies = [ [[package]] name = "aptos-indexer-transaction-stream" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157#c63f6ee891e42cc50f92480c21d4afa86012b157" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" dependencies = [ "anyhow", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157)", + "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2)", "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", "aptos-transaction-filter 0.1.0 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", "chrono", @@ -2625,17 +2695,12 @@ dependencies = [ "anyhow", "aptos-crypto", "aptos-crypto-derive", - "aptos-dkg", "aptos-types", - "ark-bls12-381", - "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", "bcs 0.1.4", "blstrs", "derivation-path", "ed25519-dalek 1.0.1", + "group", "hex", "hmac 0.12.1", "jsonwebtoken 8.3.0", @@ -2655,12 +2720,14 @@ dependencies = [ "aptos-infallible", "aptos-keyless-pepper-common", "aptos-types", - "ark-bls12-381", - "ark-serialize", "bcs 0.1.4", + "blstrs", + "clap 4.5.21", "firestore", "hex", + "rand 0.7.3", "reqwest 0.11.23", + "serde", "serde_json", "tokio", ] @@ -2669,28 +2736,31 @@ dependencies = [ name = "aptos-keyless-pepper-service" version = "0.1.0" dependencies = [ - "aes-gcm", "anyhow", + "aptos-build-info", "aptos-crypto", "aptos-infallible", "aptos-inspection-service", "aptos-keyless-pepper-common", "aptos-logger", "aptos-metrics-core", + "aptos-time-service", "aptos-types", - "ark-bls12-381", "ark-bn254", - "ark-ec", - "ark-ff", "ark-groth16", - "ark-serialize", + "ark-serialize 0.5.0", + "async-trait", "bcs 0.1.4", - "dashmap", + "blstrs", + "clap 4.5.21", + "dudect-bencher", "firestore", "hex", "hyper 0.14.28", "jsonwebtoken 8.3.0", "jwt", + "more-asserts", + "num-traits", "once_cell", "rand 0.7.3", "regex", @@ -2698,8 +2768,9 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", + "tempfile", + "thiserror 1.0.69", "tokio", - "uuid 1.11.0", ] [[package]] @@ -2731,7 +2802,6 @@ dependencies = [ "aptos-vm-types", "bcs 0.1.4", "bytes", - "claims", "goldenfile", "move-binary-format", "move-command-line-common", @@ -2855,6 +2925,7 @@ dependencies = [ "aptos-short-hex-str", "aptos-storage-interface", "aptos-time-service", + "aptos-transaction-filters", "aptos-types", "aptos-vm-validator", "bcs 0.1.4", @@ -2904,6 +2975,8 @@ version = "0.1.0" dependencies = [ "anyhow", "claims", + "once_cell", + "paste", "prometheus", ] @@ -2937,14 +3010,24 @@ dependencies = [ name = "aptos-move-e2e-benchmark" version = "0.1.0" dependencies = [ + "anyhow", + "aptos-cached-packages", + "aptos-crypto", + "aptos-gas-algebra", + "aptos-gas-profiling", "aptos-language-e2e-tests", "aptos-logger", + "aptos-sdk", "aptos-transaction-generator-lib", "aptos-transaction-workloads-lib", "aptos-types", + "aptos-vm-environment", + "async-trait", "clap 4.5.21", + "e2e-move-tests", "rand 0.7.3", "serde_json", + "tokio", ] [[package]] @@ -2990,7 +3073,7 @@ dependencies = [ [[package]] name = "aptos-moving-average" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=62beedc881d1b76632318ceb186ee9065236468e#62beedc881d1b76632318ceb186ee9065236468e" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" dependencies = [ "chrono", ] @@ -2998,7 +3081,7 @@ dependencies = [ [[package]] name = "aptos-moving-average" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157#c63f6ee891e42cc50f92480c21d4afa86012b157" +source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=62beedc881d1b76632318ceb186ee9065236468e#62beedc881d1b76632318ceb186ee9065236468e" dependencies = [ "chrono", ] @@ -3009,21 +3092,27 @@ version = "0.1.0" dependencies = [ "anyhow", "aptos-aggregator", + "aptos-infallible", "aptos-types", "aptos-vm-types", "bytes", "claims", + "concurrent-queue", "crossbeam", - "dashmap", + "dashmap 7.0.0-rc2", + "equivalent", + "fail", "move-binary-format", "move-core-types", "move-vm-runtime", "move-vm-types", + "num_cpus", "proptest", "proptest-derive", "rayon", "serde", "test-case", + "triomphe", ] [[package]] @@ -3283,7 +3372,8 @@ dependencies = [ "fail", "futures", "hex", - "jemallocator", + "move-vm-runtime", + "move-vm-types", "num_cpus", "rand 0.7.3", "rayon", @@ -3292,6 +3382,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", + "tikv-jemallocator", "tokio", "ureq", "url", @@ -3474,11 +3565,9 @@ name = "aptos-profiler" version = "0.1.0" dependencies = [ "anyhow", - "backtrace", - "jemalloc-sys", - "jemallocator", "pprof", "regex", + "tikv-jemalloc-sys", ] [[package]] @@ -3659,13 +3748,17 @@ name = "aptos-resource-viewer" version = "0.1.0" dependencies = [ "anyhow", + "aptos-logger", "aptos-types", "aptos-vm", "aptos-vm-environment", + "aptos-vm-logging", "move-binary-format", "move-bytecode-utils", "move-core-types", "move-resource-viewer", + "move-vm-runtime", + "move-vm-types", ] [[package]] @@ -3756,7 +3849,6 @@ dependencies = [ "aptos-temppath", "byteorder", "dunce", - "once_cell", "proptest", "rand 0.7.3", "rocksdb", @@ -3772,16 +3864,16 @@ dependencies = [ "aptos-metrics-core", "aptos-types", "aptos-vm", - "bitvec 1.0.1", + "bitvec", "criterion", - "dashmap", + "dashmap 7.0.0-rc2", "itertools 0.13.0", - "jemallocator", "once_cell", "proptest", "rand 0.7.3", "rayon", "thiserror 1.0.69", + "tikv-jemallocator", ] [[package]] @@ -3953,15 +4045,18 @@ dependencies = [ "anyhow", "aptos-crypto", "aptos-experimental-layered-map", + "aptos-logger", "aptos-metrics-core", "aptos-scratchpad", "aptos-secure-net", "aptos-types", "arr_macro", "bcs 0.1.4", - "dashmap", + "bytes", + "dashmap 7.0.0-rc2", "derive_more 0.99.17", "itertools 0.13.0", + "lru", "once_cell", "parking_lot 0.12.1", "proptest", @@ -4019,8 +4114,9 @@ dependencies = [ "bcs 0.1.4", "bytes", "claims", - "dashmap", + "dashmap 7.0.0-rc2", "futures", + "itertools 0.13.0", "maplit", "mini-moka", "mockall 0.11.4", @@ -4104,6 +4200,7 @@ dependencies = [ "move-vm-types", "sha3 0.9.1", "smallvec", + "triomphe", ] [[package]] @@ -4136,7 +4233,6 @@ dependencies = [ "reqwest 0.11.23", "reqwest-middleware", "reqwest-retry", - "serde", "serde_json", "sysinfo", "tokio", @@ -4345,6 +4441,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "aptos-transaction-filters" +version = "0.1.0" +dependencies = [ + "aptos-crypto", + "aptos-types", + "move-core-types", + "rand 0.7.3", + "serde", + "serde_yaml 0.8.26", +] + [[package]] name = "aptos-transaction-generator-lib" version = "0.0.0" @@ -4358,6 +4466,7 @@ dependencies = [ "clap 4.5.21", "log", "move-binary-format", + "move-core-types", "move-package", "once_cell", "rand 0.7.3", @@ -4383,6 +4492,31 @@ dependencies = [ "serde", ] +[[package]] +name = "aptos-transaction-simulation-session" +version = "0.0.1" +dependencies = [ + "anyhow", + "aptos-api-types", + "aptos-resource-viewer", + "aptos-rest-client", + "aptos-transaction-simulation", + "aptos-types", + "aptos-validator-interface", + "aptos-vm", + "aptos-vm-environment", + "aptos-vm-logging", + "aptos-vm-types", + "bcs 0.1.4", + "hex", + "move-core-types", + "serde", + "serde_json", + "tempfile", + "tokio", + "url", +] + [[package]] name = "aptos-transaction-workloads-lib" version = "0.0.0" @@ -4452,12 +4586,12 @@ dependencies = [ "aptos-proptest-helpers", "arbitrary", "ark-bn254", - "ark-ec", - "ark-ff", + "ark-ec 0.5.0", + "ark-ff 0.5.0", "ark-groth16", "ark-relations", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "async-trait", "base64 0.13.1", "bcs 0.1.4", @@ -4468,16 +4602,15 @@ dependencies = [ "claims", "coset", "criterion", - "dashmap", + "dashmap 7.0.0-rc2", "derivative", - "derive_more 0.99.17", "fixed", "fxhash", "hashbrown 0.14.3", "hex", "itertools 0.13.0", "jsonwebtoken 8.3.0", - "lru 0.7.8", + "lru", "move-binary-format", "move-core-types", "move-model", @@ -4497,6 +4630,7 @@ dependencies = [ "proptest-derive", "quick_cache", "rand 0.7.3", + "rapidhash", "rayon", "ref-cast", "reqwest 0.11.23", @@ -4531,7 +4665,7 @@ dependencies = [ "async-recursion", "async-trait", "bcs 0.1.4", - "lru 0.7.8", + "lru", "move-core-types", "tokio", ] @@ -4581,7 +4715,6 @@ dependencies = [ "aptos-gas-algebra", "aptos-gas-meter", "aptos-gas-schedule", - "aptos-infallible", "aptos-keygen", "aptos-language-e2e-tests", "aptos-logger", @@ -4621,6 +4754,7 @@ dependencies = [ "rayon", "serde", "test-case", + "triomphe", ] [[package]] @@ -4658,6 +4792,7 @@ dependencies = [ "once_cell", "serde", "sha3 0.9.1", + "triomphe", ] [[package]] @@ -4714,7 +4849,6 @@ dependencies = [ "aptos-transaction-simulation", "aptos-types", "aptos-vm", - "bcs 0.1.4", "clap 4.5.21", "glob", "move-binary-format", @@ -4742,6 +4876,7 @@ dependencies = [ "bcs 0.1.4", "bytes", "claims", + "derivative", "either", "move-binary-format", "move-core-types", @@ -4750,6 +4885,7 @@ dependencies = [ "rand 0.7.3", "serde", "test-case", + "triomphe", ] [[package]] @@ -4763,15 +4899,13 @@ dependencies = [ "aptos-executor-test-helpers", "aptos-gas-schedule", "aptos-logger", + "aptos-resource-viewer", "aptos-storage-interface", "aptos-temppath", "aptos-types", "aptos-vm", - "aptos-vm-environment", "aptos-vm-genesis", - "aptos-vm-logging", "fail", - "move-binary-format", "move-core-types", "move-vm-runtime", "move-vm-types", @@ -4841,56 +4975,104 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ - "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-bls12-381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", ] [[package]] name = "ark-bn254" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] name = "ark-crypto-primitives" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" +checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" dependencies = [ - "ark-ec", - "ark-ff", + "ahash 0.8.11", + "ark-crypto-primitives-macros", + "ark-ec 0.5.0", + "ark-ff 0.5.0", "ark-relations", - "ark-serialize", + "ark-serialize 0.5.0", "ark-snark", - "ark-std", + "ark-std 0.5.0", "blake2", "derivative", "digest 0.10.7", + "fnv", + "merlin", "rayon", "sha2 0.10.8", ] +[[package]] +name = "ark-crypto-primitives-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ark-ec" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", "itertools 0.10.5", "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash 0.8.11", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.3", + "itertools 0.13.0", + "num-bigint 0.4.4", + "num-integer", + "num-traits", "rayon", "zeroize", ] @@ -4901,21 +5083,41 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "digest 0.10.7", "itertools 0.10.5", "num-bigint 0.4.4", "num-traits", "paste", - "rayon", "rustc_version", "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec 0.7.4", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.4", + "num-traits", + "paste", + "rayon", + "zeroize", +] + [[package]] name = "ark-ff-asm" version = "0.4.2" @@ -4926,6 +5128,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.87", +] + [[package]] name = "ark-ff-macros" version = "0.4.2" @@ -4939,19 +5151,32 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ark-groth16" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" +checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" dependencies = [ "ark-crypto-primitives", - "ark-ec", - "ark-ff", - "ark-poly", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", "ark-relations", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "rayon", ] @@ -4961,22 +5186,37 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash 0.8.11", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.3", "rayon", ] [[package]] name = "ark-relations" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" +checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" dependencies = [ - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", "tracing", "tracing-subscriber 0.2.25", ] @@ -4987,12 +5227,26 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "ark-serialize-derive", - "ark-std", + "ark-serialize-derive 0.4.2", + "ark-std 0.4.0", "digest 0.10.7", "num-bigint 0.4.4", ] +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive 0.5.0", + "ark-std 0.5.0", + "arrayvec 0.7.4", + "digest 0.10.7", + "num-bigint 0.4.4", + "rayon", +] + [[package]] name = "ark-serialize-derive" version = "0.4.2" @@ -5004,16 +5258,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ark-snark" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" +checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" dependencies = [ - "ark-ff", + "ark-ff 0.5.0", "ark-relations", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -5021,6 +5286,16 @@ name = "ark-std" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", @@ -5148,7 +5423,7 @@ dependencies = [ "async-lock 3.2.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-lite 2.2.0", "slab", ] @@ -5383,6 +5658,34 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "attribute-derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c124f12ade4e670107b132722d0ad1a5c9790bcbc1b265336369ea05626b4498" +dependencies = [ + "attribute-derive-macro", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "attribute-derive-macro" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b217a07446e0fb086f83401a98297e2d81492122f5874db5391bd270a185f88" +dependencies = [ + "collection_literals", + "interpolator", + "proc-macro-error", + "proc-macro-utils", + "proc-macro2", + "quote", + "quote-use", + "syn 2.0.87", +] + [[package]] name = "atty" version = "0.2.14" @@ -5742,20 +6045,18 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.4" +version = "0.72.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cexpr", "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", + "itertools 0.13.0", "proc-macro2", "quote", "regex", - "rustc-hash 1.1.0", + "rustc-hash 2.1.1", "shlex", "syn 2.0.87", ] @@ -5766,7 +6067,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -5775,6 +6085,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" version = "0.10.2" @@ -5789,9 +6105,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bitmaps" @@ -5802,28 +6118,16 @@ dependencies = [ "typenum", ] -[[package]] -name = "bitvec" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" -dependencies = [ - "funty 1.1.0", - "radium 0.6.2", - "tap", - "wyz 0.2.0", -] - [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty 2.0.0", - "radium 0.7.0", + "funty", + "radium", "tap", - "wyz 0.5.1", + "wyz", ] [[package]] @@ -5853,7 +6157,7 @@ checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq 0.3.0", + "constant_time_eq 0.3.1", ] [[package]] @@ -5864,7 +6168,7 @@ checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq 0.3.0", + "constant_time_eq 0.3.1", ] [[package]] @@ -5901,18 +6205,31 @@ dependencies = [ "async-channel 2.1.1", "async-lock 3.2.0", "async-task", - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-io", "futures-lite 2.2.0", "piper", "tracing", ] +[[package]] +name = "bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" +dependencies = [ + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "blst" -version = "0.3.11" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" dependencies = [ "cc", "glob", @@ -6096,7 +6413,10 @@ name = "bytecode-verifier-transactional-tests" version = "0.1.0" dependencies = [ "datatest-stable", + "libtest-mimic", "move-transactional-test-runner", + "once_cell", + "walkdir", ] [[package]] @@ -6621,7 +6941,7 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" dependencies = [ - "bitvec 1.0.1", + "bitvec", "coins-bip32", "hmac 0.12.1", "once_cell", @@ -6651,6 +6971,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "collection_literals" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" + [[package]] name = "color_quant" version = "1.1.0" @@ -6839,9 +7165,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "convert_case" @@ -7386,7 +7712,21 @@ dependencies = [ "hashbrown 0.14.3", "lock_api", "once_cell", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "dashmap" +version = "7.0.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a1e35a65fe0538a60167f0ada6e195ad5d477f6ddae273943596d4a1a5730b" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "equivalent", + "hashbrown 0.15.3", + "lock_api", + "parking_lot_core 0.9.10", ] [[package]] @@ -7525,6 +7865,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "derive_arbitrary" version = "1.4.1" @@ -7642,7 +7993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" dependencies = [ "bigdecimal", - "bitflags 2.6.0", + "bitflags 2.9.1", "byteorder", "chrono", "diesel_derives", @@ -7828,6 +8179,20 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dof" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed9b77e3c2a83995eedff2fbf992eef44c9f319b8016254f68108e27a4d06e7" +dependencies = [ + "goblin", + "pretty-hex", + "serde", + "serde_json", + "thiserror 2.0.17", + "zerocopy 0.8.27", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -7860,6 +8225,28 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" +[[package]] +name = "dtrace-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc09b90bda5770641457f1c0a42c8203c48f5a3d9799dcf1bafbd84e30ccf080" +dependencies = [ + "pest", + "pest_derive", + "thiserror 2.0.17", +] + +[[package]] +name = "dudect-bencher" +version = "0.6.0" +source = "git+https://github.com/aptos-labs/dudect-bencher?rev=9515677c83c58884c1a8c764251753269d46fc0e#9515677c83c58884c1a8c764251753269d46fc0e" +dependencies = [ + "clap 2.34.0", + "ctrlc", + "rand 0.8.5", + "rand_chacha 0.3.1", +] + [[package]] name = "dunce" version = "1.0.4" @@ -7925,9 +8312,8 @@ dependencies = [ "aptos-language-e2e-tests", "aptos-package-builder", "aptos-rest-client", - "aptos-transaction-generator-lib", + "aptos-sdk", "aptos-transaction-simulation", - "aptos-transaction-workloads-lib", "aptos-types", "aptos-vm", "aptos-vm-environment", @@ -7943,7 +8329,6 @@ dependencies = [ "once_cell", "project-root", "proptest", - "rand 0.7.3", "rstest", "serde", "sha3 0.9.1", @@ -8021,10 +8406,22 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" dependencies = [ - "derivation-path", - "ed25519-dalek 1.0.1", - "hmac 0.12.1", - "sha2 0.10.8", + "derivation-path", + "ed25519-dalek 1.0.1", + "hmac 0.12.1", + "sha2 0.10.8", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -8104,6 +8501,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "enum_dispatch" version = "0.3.12" @@ -8209,10 +8626,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", - "fixed-hash 0.8.0", - "impl-codec 0.6.0", + "fixed-hash", + "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "scale-info", "tiny-keccak", ] @@ -8224,11 +8641,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ "ethbloom", - "fixed-hash 0.8.0", - "impl-codec 0.6.0", + "fixed-hash", + "impl-codec", "impl-rlp", - "impl-serde 0.4.0", - "primitive-types 0.12.2", + "impl-serde", + "primitive-types", "scale-info", "uint", ] @@ -8483,9 +8900,12 @@ dependencies = [ [[package]] name = "ethnum" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" +dependencies = [ + "serde", +] [[package]] name = "event-listener" @@ -8588,9 +9008,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" @@ -8607,7 +9027,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec 1.0.1", + "bitvec", "byteorder", "ff_derive", "rand_core 0.6.4", @@ -8752,18 +9172,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixed-hash" version = "0.8.0" @@ -8838,6 +9246,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -8911,12 +9325,6 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "funty" version = "2.0.0" @@ -8987,7 +9395,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -9056,6 +9464,7 @@ name = "fuzzer" version = "0.1.0" dependencies = [ "aptos-framework", + "aptos-language-e2e-tests", "aptos-types", "arbitrary", "base64 0.21.7", @@ -9066,6 +9475,8 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", + "move-model", + "move-transactional-test-runner", "rayon", "sha2 0.9.9", "walkdir", @@ -9075,6 +9486,7 @@ dependencies = [ name = "fuzzer-fuzz" version = "0.0.0" dependencies = [ + "aptos-block-executor", "aptos-cached-packages", "aptos-consensus", "aptos-crypto", @@ -9087,10 +9499,13 @@ dependencies = [ "arbitrary", "base64 0.13.1", "bcs 0.1.4", + "fuzzer", "libfuzzer-sys", "move-binary-format", "move-bytecode-verifier", "move-core-types", + "move-transactional-test-runner", + "move-vm-runtime", "move-vm-types", "once_cell", "rayon", @@ -9197,6 +9612,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "get-size" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b61e2dab7eedce93a83ab3468b919873ff16bac5a3e704011ff836d22b2120" +dependencies = [ + "get-size-derive", +] + +[[package]] +name = "get-size-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a1bcfb855c1f340d5913ab542e36f25a1c56f57de79022928297632435dec2" +dependencies = [ + "attribute-derive", + "quote", + "syn 2.0.87", +] + [[package]] name = "get_if_addrs" version = "0.5.3" @@ -9247,16 +9682,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi", - "wasip2", - "wasm-bindgen", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -9355,6 +9788,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "goblin" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51876e3748c4a347fe65b906f2b1ae46a1e55a497b22c94c1f4f2c469ff7673a" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "goldenfile" version = "1.6.0" @@ -9494,7 +9938,7 @@ dependencies = [ "ff", "rand 0.8.5", "rand_core 0.6.4", - "rand_xorshift", + "rand_xorshift 0.3.0", "subtle", ] @@ -9647,9 +10091,14 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "hashers" @@ -10056,7 +10505,7 @@ dependencies = [ "http 0.2.11", "hyper 0.14.28", "log", - "rustls 0.21.12", + "rustls 0.21.10", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -10260,22 +10709,13 @@ dependencies = [ "tiff", ] -[[package]] -name = "impl-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" -dependencies = [ - "parity-scale-codec 2.3.1", -] - [[package]] name = "impl-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.12", + "parity-scale-codec", ] [[package]] @@ -10287,15 +10727,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - [[package]] name = "impl-serde" version = "0.4.0" @@ -10364,7 +10795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.3", "serde", ] @@ -10409,7 +10840,7 @@ dependencies = [ "clap 4.5.21", "crossbeam-channel", "crossbeam-utils", - "dashmap", + "dashmap 5.5.3", "env_logger", "indexmap 2.7.0", "is-terminal", @@ -10452,7 +10883,7 @@ dependencies = [ [[package]] name = "instrumented-channel" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157#c63f6ee891e42cc50f92480c21d4afa86012b157" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" dependencies = [ "delegate", "derive_builder", @@ -10475,12 +10906,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" dependencies = [ "ahash 0.7.8", - "dashmap", + "dashmap 5.5.3", "hashbrown 0.12.3", "once_cell", "parking_lot 0.12.1", ] +[[package]] +name = "interpolator" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -10621,11 +11058,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jemalloc-sys" version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +source = "git+https://github.com/aptos-labs/jemalloc-sys-shim?rev=e0920246dd74303fab9a14b990768c6ac990a59b#e0920246dd74303fab9a14b990768c6ac990a59b" dependencies = [ - "cc", - "libc", + "tikv-jemalloc-sys", ] [[package]] @@ -10902,7 +11337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "diff", "ena", "is-terminal", @@ -10924,7 +11359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "ena", "itertools 0.11.0", "lalrpop-util 0.20.2", @@ -10977,6 +11412,7 @@ dependencies = [ "move-core-types", "move-ir-compiler", "proptest", + "test-case", ] [[package]] @@ -10988,12 +11424,6 @@ dependencies = [ "spin 0.5.2", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "lebe" version = "0.5.2" @@ -11127,21 +11557,20 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "libc", "redox_syscall 0.4.1", ] [[package]] name = "librocksdb-sys" -version = "0.16.0+8.10.0" +version = "0.17.3+10.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3d60bc059831dc1c83903fb45c103f75db65c5a7bf22272764d9cc683e348c" +checksum = "cef2a00ee60fe526157c9023edab23943fae1ce2ab6f4abb2a807c1746835de9" dependencies = [ "bindgen", "bzip2-sys", "cc", - "glob", "libc", "libz-sys", "lz4-sys", @@ -11279,9 +11708,9 @@ checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[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", @@ -11312,28 +11741,13 @@ dependencies = [ [[package]] name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - -[[package]] -name = "lru" -version = "0.9.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e7d46de488603ffdd5f30afbc64fbba2378214a2c3a2fb83abf3d33126df17" +checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.15.3", ] -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "lz4" version = "1.28.1" @@ -11450,6 +11864,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memmap2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +dependencies = [ + "libc", +] + [[package]] name = "memory-stats" version = "1.1.0" @@ -11567,7 +11990,7 @@ checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" dependencies = [ "crossbeam-channel", "crossbeam-utils", - "dashmap", + "dashmap 5.5.3", "skeptic", "smallvec", "tagptr", @@ -11674,15 +12097,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "module-publish" -version = "0.1.0" -dependencies = [ - "anyhow", - "aptos-transaction-generator-lib", - "clap 4.5.21", -] - [[package]] name = "more-asserts" version = "0.3.1" @@ -11711,6 +12125,23 @@ dependencies = [ "tempfile", ] +[[package]] +name = "move-asm" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.5.21", + "codespan", + "codespan-reporting", + "either", + "itertools 0.13.0", + "libtest-mimic", + "move-binary-format", + "move-core-types", + "move-transactional-test-runner", + "walkdir", +] + [[package]] name = "move-ast-generator-tests" version = "0.1.0" @@ -11735,6 +12166,7 @@ dependencies = [ "indexmap 2.7.0", "move-bytecode-spec", "move-core-types", + "once_cell", "proptest", "proptest-derive", "ref-cast", @@ -11778,7 +12210,6 @@ dependencies = [ "move-binary-format", "move-core-types", "petgraph 0.6.5", - "serde-reflection", ] [[package]] @@ -11876,6 +12307,7 @@ dependencies = [ "clap 4.5.21", "codespan", "codespan-reporting", + "colored", "ethnum", "flexi_logger", "im", @@ -11883,13 +12315,13 @@ dependencies = [ "legacy-move-compiler", "libtest-mimic", "log", + "move-asm", "move-binary-format", "move-borrow-graph", "move-bytecode-source-map", "move-bytecode-verifier", "move-command-line-common", "move-core-types", - "move-disassembler", "move-ir-types", "move-model", "move-prover-test-utils", @@ -11930,7 +12362,6 @@ dependencies = [ "hex", "num 0.4.1", "once_cell", - "primitive-types 0.10.1", "proptest", "proptest-derive", "rand 0.8.5", @@ -11940,7 +12371,6 @@ dependencies = [ "serde_bytes", "serde_json", "thiserror 1.0.69", - "uint", ] [[package]] @@ -11971,6 +12401,7 @@ dependencies = [ "codespan", "codespan-reporting", "datatest-stable", + "libtest-mimic", "move-binary-format", "move-bytecode-source-map", "move-bytecode-verifier", @@ -11979,6 +12410,9 @@ dependencies = [ "move-model", "move-prover-test-utils", "move-stackless-bytecode", + "once_cell", + "tempfile", + "walkdir", ] [[package]] @@ -12133,11 +12567,11 @@ dependencies = [ "itertools 0.13.0", "legacy-move-compiler", "log", + "move-asm", "move-binary-format", "move-bytecode-source-map", "move-command-line-common", "move-core-types", - "move-disassembler", "move-ir-types", "move-prover-test-utils", "move-symbol-pool", @@ -12183,6 +12617,24 @@ dependencies = [ "whoami", ] +[[package]] +name = "move-package-cache" +version = "0.1.0" +dependencies = [ + "anyhow", + "aptos-framework", + "aptos-rest-client", + "fs2", + "futures", + "git2 0.16.1", + "hex", + "move-core-types", + "percent-encoding", + "tempfile", + "tokio", + "url", +] + [[package]] name = "move-package-manifest" version = "0.1.0" @@ -12198,6 +12650,26 @@ dependencies = [ "url", ] +[[package]] +name = "move-package-resolver" +version = "0.1.0" +dependencies = [ + "anyhow", + "aptos-rest-client", + "datatest-stable", + "either", + "git2 0.16.1", + "move-core-types", + "move-package-cache", + "move-package-manifest", + "move-prover-test-utils", + "petgraph 0.6.5", + "serde", + "tokio", + "toml 0.7.8", + "url", +] + [[package]] name = "move-prover" version = "0.1.0" @@ -12223,7 +12695,6 @@ dependencies = [ "once_cell", "serde", "shell-words", - "simplelog", "tempfile", "toml 0.7.8", "walkdir", @@ -12261,7 +12732,6 @@ dependencies = [ name = "move-prover-bytecode-pipeline" version = "0.1.0" dependencies = [ - "abstract-domain-derive", "anyhow", "codespan-reporting", "datatest-stable", @@ -12408,6 +12878,7 @@ dependencies = [ "sha3 0.9.1", "smallvec", "tempfile", + "triomphe", ] [[package]] @@ -12415,16 +12886,23 @@ name = "move-transactional-test-runner" version = "0.1.0" dependencies = [ "anyhow", + "aptos-framework", + "arbitrary", + "bcs 0.1.4", "clap 4.5.21", "datatest-stable", + "dearbitrary", "difference", + "either", "legacy-move-compiler", + "move-asm", "move-binary-format", "move-bytecode-source-map", "move-bytecode-verifier", "move-command-line-common", "move-compiler-v2", "move-core-types", + "move-decompiler", "move-disassembler", "move-ir-compiler", "move-ir-types", @@ -12438,6 +12916,7 @@ dependencies = [ "once_cell", "regex", "tempfile", + "tera", "termcolor", ] @@ -12474,6 +12953,7 @@ dependencies = [ "rayon", "regex", "tempfile", + "thiserror 1.0.69", ] [[package]] @@ -12497,6 +12977,7 @@ dependencies = [ "move-vm-types", "smallvec", "tempfile", + "test-case", ] [[package]] @@ -12507,6 +12988,15 @@ dependencies = [ "prometheus", ] +[[package]] +name = "move-vm-profiler" +version = "0.1.0" +dependencies = [ + "move-vm-types", + "once_cell", + "usdt", +] + [[package]] name = "move-vm-runtime" version = "0.1.0" @@ -12515,19 +13005,24 @@ dependencies = [ "anyhow", "bcs 0.1.4", "better_any", + "bitvec", "bytes", + "cfg-if", "claims", "fail", + "fxhash", "hashbrown 0.14.3", "hex", + "itertools 0.13.0", "lazy_static", "legacy-move-compiler", - "lru 0.7.8", + "lru", "move-binary-format", "move-bytecode-verifier", "move-core-types", "move-ir-compiler", "move-vm-metrics", + "move-vm-profiler", "move-vm-test-utils", "move-vm-types", "once_cell", @@ -12536,6 +13031,7 @@ dependencies = [ "serde", "sha3 0.9.1", "smallbitvec", + "test-case", "triomphe", "typed-arena", ] @@ -12581,13 +13077,14 @@ dependencies = [ "bytes", "claims", "crossbeam", - "dashmap", + "dashmap 7.0.0-rc2", "derivative", "hashbrown 0.14.3", "itertools 0.13.0", "mockall 0.11.4", "move-binary-format", "move-core-types", + "once_cell", "parking_lot 0.12.1", "proptest", "rand 0.7.3", @@ -12632,6 +13129,8 @@ dependencies = [ "aptos-storage-interface", "aptos-telemetry", "aptos-temppath", + "aptos-transaction-simulation", + "aptos-transaction-simulation-session", "aptos-types", "aptos-vm", "aptos-vm-environment", @@ -12648,7 +13147,7 @@ dependencies = [ "clap 4.5.21", "clap_complete", "colored", - "dashmap", + "dashmap 7.0.0-rc2", "diesel", "diesel-async", "dirs 5.0.1", @@ -12656,9 +13155,9 @@ dependencies = [ "hex", "indoc", "itertools 0.13.0", - "jemallocator", "legacy-move-compiler", "maplit", + "move-asm", "move-binary-format", "move-bytecode-source-map", "move-cli", @@ -12666,6 +13165,7 @@ dependencies = [ "move-compiler-v2", "move-core-types", "move-coverage", + "move-decompiler", "move-disassembler", "move-ir-types", "move-linter", @@ -12690,6 +13190,7 @@ dependencies = [ "shadow-rs", "tempfile", "thiserror 1.0.69", + "tikv-jemallocator", "tokio", "toml 0.7.8", "tracing", @@ -12849,7 +13350,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "libc", ] @@ -12860,7 +13361,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "cfg_aliases 0.2.1", "libc", @@ -12930,7 +13431,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc7c92f190c97f79b4a332f5e81dcf68c8420af2045c936c9be0bc9de6f63b5" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -13159,7 +13660,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.87", @@ -13255,7 +13756,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "foreign-types 0.3.2", "libc", @@ -13425,6 +13926,15 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "package-generator" +version = "0.1.0" +dependencies = [ + "anyhow", + "aptos-transaction-generator-lib", + "clap 4.5.21", +] + [[package]] name = "pad" version = "0.1.6" @@ -13443,20 +13953,6 @@ dependencies = [ "group", ] -[[package]] -name = "parity-scale-codec" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" -dependencies = [ - "arrayvec 0.7.4", - "bitvec 0.20.4", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive 2.3.1", - "serde", -] - [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -13464,32 +13960,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.4", - "bitvec 1.0.1", + "bitvec", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.12", + "parity-scale-codec-derive", "serde", ] -[[package]] -name = "parity-scale-codec-derive" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "parity-scale-codec-derive" version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -13519,7 +14003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -13538,15 +14022,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.11", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -13631,7 +14115,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "ciborium", "coset", "data-encoding", @@ -13823,20 +14307,19 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 1.0.69", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -13844,9 +14327,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", @@ -13857,11 +14340,10 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ - "once_cell", "pest", "sha2 0.10.8", ] @@ -14016,7 +14498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-io", ] @@ -14069,6 +14551,12 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "platforms" version = "3.3.0" @@ -14167,7 +14655,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdfed15c1102d2a9a51b9f1aba945628c72ccb52fc5d3e4ad4ffbbd222e11821" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.87", @@ -14209,7 +14697,7 @@ dependencies = [ "http 1.1.0", "indexmap 2.7.0", "mime", - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "regex", @@ -14285,16 +14773,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" -[[package]] -name = "poseidon-ark" -version = "0.0.1" -source = "git+https://github.com/arnaucube/poseidon-ark.git?rev=6d2487aa1308d9d3860a2b724c485d73095c1c68#6d2487aa1308d9d3860a2b724c485d73095c1c68" -dependencies = [ - "ark-bn254", - "ark-ff", - "ark-std", -] - [[package]] name = "postgres-native-tls" version = "0.5.0" @@ -14437,6 +14915,12 @@ dependencies = [ "typed-arena", ] +[[package]] +name = "pretty-hex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc83ee4a840062f368f9096d80077a9841ec117e17e7f700df81958f1451254" + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -14492,42 +14976,20 @@ dependencies = [ "elliptic-curve", ] -[[package]] -name = "primitive-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" -dependencies = [ - "fixed-hash 0.7.0", - "impl-codec 0.5.1", - "impl-serde 0.3.2", - "uint", -] - [[package]] name = "primitive-types" version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ - "fixed-hash 0.8.0", - "impl-codec 0.6.0", + "fixed-hash", + "impl-codec", "impl-rlp", - "impl-serde 0.4.0", + "impl-serde", "scale-info", "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -14573,11 +15035,22 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" +[[package]] +name = "proc-macro-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8" +dependencies = [ + "proc-macro2", + "quote", + "smallvec", +] + [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -14598,7 +15071,7 @@ dependencies = [ [[package]] name = "processor" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors-v2.git?rev=8628f1534efa28ada547bbcd34afec1af55697d4#8628f1534efa28ada547bbcd34afec1af55697d4" +source = "git+https://github.com/aptos-labs/aptos-indexer-processors-v2.git?tag=aptos-indexer-processors-v2.1.5#a1a0cfeff7febc81dbe5a238ed5318f319aaef6c" dependencies = [ "ahash 0.8.11", "allocative", @@ -14608,7 +15081,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "bigdecimal", - "bitflags 2.6.0", + "bitflags 2.9.1", "canonical_json", "chrono", "clap 4.5.21", @@ -14739,18 +15212,18 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.6.0", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.9.1", "lazy_static", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", + "rand 0.9.1", + "rand_chacha 0.9.0", + "rand_xorshift 0.4.0", "regex-syntax 0.8.2", "rusty-fork", "tempfile", @@ -15036,23 +15509,19 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" dependencies = [ "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.4", + "rand 0.8.5", "ring 0.17.7", - "rustc-hash 2.1.2", + "rustc-hash 1.1.0", "rustls 0.23.7", - "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 1.0.69", "tinyvec", "tracing", - "web-time", ] [[package]] @@ -15076,11 +15545,34 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quote-use" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7b5abe3fe82fdeeb93f44d66a7b444dedf2e4827defb0a8e69c437b2de2ef94" +dependencies = [ + "quote", + "quote-use-macros", + "syn 2.0.87", +] + +[[package]] +name = "quote-use-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ea44c7e20f16017a76a245bb42188517e13d16dcb1aa18044bc406cdc3f4af" +dependencies = [ + "derive-where", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "r-efi" -version = "5.3.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "r2d2" @@ -15093,12 +15585,6 @@ dependencies = [ "scheduled-thread-pool", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "radium" version = "0.7.0" @@ -15132,12 +15618,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -15167,7 +15653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -15190,11 +15676,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.3.3", ] [[package]] @@ -15224,6 +15710,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -15243,6 +15738,12 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "rapidhash" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9813f789f95ee4fe6b4d01834404d7cccacbc3f6c029343af910b3c2835eb9f1" + [[package]] name = "raw-cpuid" version = "10.7.0" @@ -15328,6 +15829,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags 2.9.1", +] + [[package]] name = "redox_users" version = "0.4.4" @@ -15431,7 +15941,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.12", + "rustls 0.21.10", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -15651,9 +16161,9 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.22.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd13e55d6d7b8cd0ea569161127567cd587676c99f4472f779a0279aa60a7a7" +checksum = "ddb7af00d2b17dbd07d82c0063e25411959748ff03e8d4f96134c2ff41fce34f" dependencies = [ "libc", "librocksdb-sys", @@ -15777,9 +16287,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-hex" @@ -15830,7 +16340,7 @@ version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.4.12", @@ -15851,9 +16361,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.12" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring 0.17.7", @@ -15961,9 +16471,6 @@ name = "rustls-pki-types" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" -dependencies = [ - "web-time", -] [[package]] name = "rustls-webpki" @@ -16070,7 +16577,7 @@ dependencies = [ [[package]] name = "sample" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=c63f6ee891e42cc50f92480c21d4afa86012b157#c63f6ee891e42cc50f92480c21d4afa86012b157" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" dependencies = [ "tracing", ] @@ -16083,7 +16590,7 @@ checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", "derive_more 1.0.0", - "parity-scale-codec 3.6.12", + "parity-scale-codec", "scale-info-derive", ] @@ -16093,21 +16600,12 @@ version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.87", ] -[[package]] -name = "scc" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" -dependencies = [ - "sdd", -] - [[package]] name = "schannel" version = "0.1.23" @@ -16148,6 +16646,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed76efe62313ab6610570951494bdaa81568026e0318eaa55f167de70eeea67d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "scrypt" version = "0.10.0" @@ -16170,12 +16688,6 @@ dependencies = [ "untrusted 0.9.0", ] -[[package]] -name = "sdd" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" - [[package]] name = "seahash" version = "4.1.0" @@ -16450,6 +16962,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_tokenstream" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64060d864397305347a78851c51588fd283767e7e7589829e8121d65512340f1" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.87", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -16528,24 +17052,23 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f" +checksum = "699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d" dependencies = [ "futures-executor", "futures-util", "log", "once_cell", "parking_lot 0.12.1", - "scc", "serial_test_derive", ] [[package]] name = "serial_test_derive" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9" +checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c" dependencies = [ "proc-macro2", "quote", @@ -16560,6 +17083,7 @@ dependencies = [ "move-core-types", "proptest", "proptest-derive", + "similar-asserts", ] [[package]] @@ -16758,9 +17282,9 @@ dependencies = [ [[package]] name = "similar-asserts" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e041bb827d1bfca18f213411d51b665309f1afb37a04a5d1464530e13779fc0f" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" dependencies = [ "console", "similar", @@ -16789,17 +17313,6 @@ dependencies = [ "time", ] -[[package]] -name = "simplelog" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc0ffd69814a9b251d43afcabf96dad1b29f5028378056257be9e3fecc9f720" -dependencies = [ - "chrono", - "log", - "termcolor", -] - [[package]] name = "siphasher" version = "0.3.11" @@ -16890,6 +17403,7 @@ name = "smoke-test" version = "0.1.0" dependencies = [ "anyhow", + "aptos-api-types", "aptos-backup-cli", "aptos-bitvec", "aptos-cached-packages", @@ -16922,11 +17436,13 @@ dependencies = [ "aptos-storage-interface", "aptos-temppath", "aptos-time-service", + "aptos-transaction-filters", "aptos-types", "aptos-vault-client", "aptos-vm", "base64 0.13.1", "bcs 0.1.4", + "blake2-rfc", "diesel", "digest 0.9.0", "ethers", @@ -17307,7 +17823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b55cdc318ede251d0957f07afe5fed912119b8c1bc5a7804151826db999e737" dependencies = [ "debugid", - "memmap2", + "memmap2 0.5.10", "stable_deref_trait", "uuid 1.11.0", ] @@ -17454,7 +17970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", - "fastrand 2.0.1", + "fastrand 2.3.0", "redox_syscall 0.4.1", "rustix 0.38.28", "windows-sys 0.52.0", @@ -17598,11 +18114,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.17", ] [[package]] @@ -17618,15 +18134,25 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", "syn 2.0.87", ] +[[package]] +name = "thread-id" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99043e46c5a15af379c06add30d9c93a6c0e8849de00d244c4a2c417da128d80" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -17668,6 +18194,37 @@ dependencies = [ "weezl", ] +[[package]] +name = "tikv-jemalloc-ctl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f21f216790c8df74ce3ab25b534e0718da5a1916719771d3fec23315c99e468b" +dependencies = [ + "libc", + "paste", + "tikv-jemalloc-sys", +] + +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "time" version = "0.3.41" @@ -17858,7 +18415,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.12", + "rustls 0.21.10", "tokio", ] @@ -17926,7 +18483,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.12", + "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", "tungstenite", @@ -18336,9 +18893,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" dependencies = [ "serde", "stable_deref_trait", @@ -18411,7 +18968,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.12", + "rustls 0.21.10", "sha1", "thiserror 1.0.69", "url", @@ -18704,6 +19261,68 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "usdt" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1953f8d8a98ac7883c230963291acb65c7ed6ae3e2e4c99d5c65f4e65cc9db38" +dependencies = [ + "dof", + "goblin", + "memmap2 0.9.9", + "serde", + "usdt-attr-macro", + "usdt-impl", + "usdt-macro", +] + +[[package]] +name = "usdt-attr-macro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55d0d673848744c556fcfe8479f87b6974459106e4c41f38375f6d559bb0ee28" +dependencies = [ + "dtrace-parser", + "proc-macro2", + "quote", + "serde_tokenstream", + "syn 2.0.87", + "usdt-impl", +] + +[[package]] +name = "usdt-impl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf0085a93af1ca095d8b1dc8672cc4620fcd1db5dff8d165486067badce05555" +dependencies = [ + "byteorder", + "dof", + "dtrace-parser", + "libc", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 2.0.87", + "thiserror 2.0.17", + "thread-id", +] + +[[package]] +name = "usdt-macro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9bf594f86b676f7e2fd3d523d50f9d0cffecff6c19729ff5dbebe86c4cb8cb2" +dependencies = [ + "dtrace-parser", + "proc-macro2", + "quote", + "serde_tokenstream", + "syn 2.0.87", + "usdt-impl", +] + [[package]] name = "utcnow" version = "0.2.4" @@ -18937,12 +19556,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasip2" -version = "1.0.3+wasi-0.2.9" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "wit-bindgen", + "wit-bindgen-rt", ] [[package]] @@ -19073,16 +19692,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webpki" version = "0.22.4" @@ -19458,10 +20067,13 @@ dependencies = [ ] [[package]] -name = "wit-bindgen" -version = "0.57.1" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] [[package]] name = "ws_stream_wasm" @@ -19482,12 +20094,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - [[package]] name = "wyz" version = "0.5.1" @@ -19592,7 +20198,16 @@ version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.32", +] + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive 0.8.27", ] [[package]] @@ -19606,6 +20221,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index e6c48077715..5954cb9e5e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "aptos-move/aptos-sdk-builder", "aptos-move/aptos-transaction-benchmarks", "aptos-move/aptos-transaction-simulation", + "aptos-move/aptos-transaction-simulation-session", "aptos-move/aptos-transactional-test-harness", "aptos-move/aptos-validator-interface", "aptos-move/aptos-vm", @@ -73,6 +74,7 @@ members = [ "crates/aptos-genesis", "crates/aptos-github-client", "crates/aptos-id-generator", + "crates/aptos-in-memory-cache", "crates/aptos-infallible", "crates/aptos-inspection-service", "crates/aptos-jwk-consensus", @@ -98,6 +100,7 @@ members = [ "crates/aptos-telemetry-service", "crates/aptos-temppath", "crates/aptos-time-service", + "crates/aptos-transaction-filters", "crates/aptos-warp-webserver", "crates/bounded-executor", "crates/channel", @@ -124,6 +127,7 @@ members = [ "ecosystem/indexer-grpc/indexer-grpc-file-store", "ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller", "ecosystem/indexer-grpc/indexer-grpc-fullnode", + "ecosystem/indexer-grpc/indexer-grpc-gateway", "ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark", "ecosystem/indexer-grpc/indexer-grpc-manager", "ecosystem/indexer-grpc/indexer-grpc-server-framework", @@ -188,12 +192,12 @@ members = [ "storage/schemadb", "storage/scratchpad", "storage/storage-interface", + "testsuite/benchmark-workloads/package-generator", "testsuite/forge", "testsuite/forge-cli", "testsuite/fuzzer", "testsuite/fuzzer/fuzz", "testsuite/generate-format", - "testsuite/module-publish", "testsuite/smoke-test", "testsuite/testcases", "third_party/move/extensions/move-table-extension", @@ -233,11 +237,13 @@ members = [ "third_party/move/move-symbol-pool", "third_party/move/move-vm/integration-tests", "third_party/move/move-vm/metrics", + "third_party/move/move-vm/profiler", "third_party/move/move-vm/runtime", "third_party/move/move-vm/test-utils", "third_party/move/move-vm/transactional-tests", "third_party/move/move-vm/types", "third_party/move/testing-infra/transactional-test-runner", + "third_party/move/tools/move-asm", "third_party/move/tools/move-bytecode-utils", "third_party/move/tools/move-bytecode-viewer", "third_party/move/tools/move-cli", @@ -246,7 +252,9 @@ members = [ "third_party/move/tools/move-disassembler", "third_party/move/tools/move-linter", "third_party/move/tools/move-package", + "third_party/move/tools/move-package-cache", "third_party/move/tools/move-package-manifest", + "third_party/move/tools/move-package-resolver", "third_party/move/tools/move-resource-viewer", "third_party/move/tools/move-unit-test", "tools/calc-dep-sizes", @@ -279,12 +287,12 @@ default-members = [ # for package declarations. [workspace.package] authors = ["Aptos Labs "] -edition = "2021" +edition = "2024" homepage = "https://aptoslabs.com" license = "Apache-2.0" publish = false repository = "https://github.com/aptos-labs/aptos-core" -rust-version = "1.80.1" +rust-version = "1.85" [workspace.dependencies] # Internal crate dependencies. @@ -356,6 +364,7 @@ aptos-genesis = { path = "crates/aptos-genesis" } aptos-github-client = { path = "crates/aptos-github-client" } aptos-global-constants = { path = "config/global-constants" } aptos-id-generator = { path = "crates/aptos-id-generator" } +aptos-in-memory-cache = { path = "crates/aptos-in-memory-cache" } aptos-indexer = { path = "crates/indexer" } aptos-indexer-grpc-cache-worker = { path = "ecosystem/indexer-grpc/indexer-grpc-cache-worker" } aptos-indexer-grpc-data-service = { path = "ecosystem/indexer-grpc/indexer-grpc-data-service" } @@ -364,6 +373,7 @@ aptos-indexer-grpc-file-store = { path = "ecosystem/indexer-grpc/indexer-grpc-fi aptos-indexer-grpc-file-checker = { path = "ecosystem/indexer-grpc/indexer-grpc-file-checker" } aptos-indexer-grpc-file-store-backfiller = { path = "ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller" } aptos-indexer-grpc-fullnode = { path = "ecosystem/indexer-grpc/indexer-grpc-fullnode" } +aptos-indexer-grpc-gateway = { path = "ecosystem/indexer-grpc/indexer-grpc-gateway" } aptos-indexer-grpc-in-memory-cache-benchmark = { path = "ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark" } aptos-indexer-grpc-manager = { path = "ecosystem/indexer-grpc/indexer-grpc-manager" } aptos-indexer-grpc-table-info = { path = "ecosystem/indexer-grpc/indexer-grpc-table-info" } @@ -445,6 +455,7 @@ aptos-storage-service-types = { path = "state-sync/storage-service/types" } aptos-storage-service-server = { path = "state-sync/storage-service/server" } aptos-system-utils = { path = "crates/aptos-system-utils" } aptos-transaction-filter = { path = "ecosystem/indexer-grpc/transaction-filter" } +aptos-transaction-filters = { path = "crates/aptos-transaction-filters" } aptos-telemetry = { path = "crates/aptos-telemetry" } aptos-telemetry-service = { path = "crates/aptos-telemetry-service" } aptos-temppath = { path = "crates/aptos-temppath" } @@ -456,6 +467,7 @@ aptos-transaction-emitter-lib = { path = "crates/transaction-emitter-lib" } aptos-transaction-generator-lib = { path = "crates/transaction-generator-lib" } aptos-transaction-workloads-lib = { path = "crates/transaction-workloads-lib" } aptos-transaction-simulation = { path = "aptos-move/aptos-transaction-simulation" } +aptos-transaction-simulation-session = { path = "aptos-move/aptos-transaction-simulation-session" } aptos-transactional-test-harness = { path = "aptos-move/aptos-transactional-test-harness" } aptos-types = { path = "types" } aptos-validator-interface = { path = "aptos-move/aptos-validator-interface" } @@ -486,15 +498,17 @@ anstyle = "1.0.1" arbitrary = { version = "1.4.1", features = ["derive"] } arc-swap = "1.6.0" arr_macro = "0.2.1" -ark-bls12-381 = "0.4.0" -ark-bn254 = "0.4.0" -ark-ec = "0.4.0" -ark-ff = "0.4.0" -ark-groth16 = "0.4.0" -ark-relations = "0.4.0" -ark-serialize = "0.4.0" -ark-std = { version = "0.4.0", features = ["getrandom"] } -aptos-indexer-processor-sdk = { git = "https://github.com/aptos-labs/aptos-indexer-processor-sdk.git", rev = "c63f6ee891e42cc50f92480c21d4afa86012b157", features = [ +ark-bls12-381 = "0.5.0" +ark-bn254 = "0.5.0" +ark-ec = "0.5.0" +ark-ff = "0.5.0" +ark-groth16 = "0.5.0" +ark-poly = "0.5.0" +ark-relations = "0.5.0" +ark-serialize = { version = "0.5.0", features = ["derive"] } +ark-snark = { version = "0.5.0" } +ark-std = { version = "0.5.0", features = ["getrandom"] } +aptos-indexer-processor-sdk = { git = "https://github.com/aptos-labs/aptos-indexer-processor-sdk.git", tag = "aptos-indexer-processor-sdk-v2.1.2", features = [ "postgres_partial", ] } aptos-moving-average = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "62beedc881d1b76632318ceb186ee9065236468e" } @@ -514,7 +528,8 @@ version-compare = "0.1.1" bitvec = "1.0.1" blake2 = "0.10.4" blake2-rfc = "0.2.18" -blst = "0.3.11" +bls12_381 = "0.8.0" +blst = "0.3.15" # The __private_bench feature exposes the Fp12 type which we need to implement a multi-threaded multi-pairing. blstrs = { version = "0.7.1", features = ["serde", "__private_bench"] } bollard = "0.15" @@ -556,7 +571,7 @@ crossterm = "0.26.1" csv = "1.2.1" curve25519-dalek = "3" curve25519-dalek-ng = "4" -dashmap = { version = "5.5.3", features = ["inline"] } +dashmap = { version = "7.0.0-rc2", features = ["inline-more"] } datatest-stable = "0.1.1" debug-ignore = { version = "1.0.3", features = ["serde"] } derivative = "2.2.0" @@ -579,14 +594,16 @@ digest = "0.9.0" dir-diff = "0.3.2" dirs = "5.0.1" dirs-next = "2.0.0" +dudect-bencher = "0.6" dunce = "1.0.4" ed25519-dalek = { version = "1.0.1", features = ["std", "serde"] } ed25519-dalek-bip32 = "0.2.0" either = "1.6.1" enum_dispatch = "0.3.12" env_logger = "0.10.0" +equivalent = "1.0" erased-serde = "0.3.13" -ethnum = "1.5.0" +ethnum = "1.5.2" ethers = { version = "2" } dearbitrary = { version = "1.0.4", features = ["derive"] } fail = "0.5.0" @@ -604,9 +621,11 @@ futures-channel = "0.3.29" futures-core = "0.3.29" futures-util = "0.3.29" fxhash = "0.2.1" +fs2 = "0.4.3" getrandom = "0.2.2" gcp-bigquery-client = "0.16.8" get_if_addrs = "0.5.3" +get-size = { version = "0.1.4", features = ["derive"] } git2 = "0.16.1" glob = "0.3.0" goldenfile = "1.5.2" @@ -622,8 +641,10 @@ hkdf = "0.10.0" hmac = "0.12.0" hostname = "0.3.1" http = "0.2.9" +http-body-util = "0.1.1" httpmock = "0.6.8" hyper = { version = "0.14.18", features = ["full"] } +hyper-util = { version = "0.1.3", features = ["client-legacy"] } im = "15.0.0" image = "0.24.5" indexmap = "2.7.0" @@ -633,6 +654,13 @@ inferno = "0.11.14" internment = { version = "0.5.0", features = ["arc"] } ipnet = "2.5.0" itertools = "0.13" +jemallocator = { package = "tikv-jemallocator", version = "0.6.0", features = [ + "profiling", + "stats", + "unprefixed_malloc_on_supported_platforms", +] } +jemalloc-ctl = { package = "tikv-jemalloc-ctl", version = "0.6.0" } +jemalloc-sys = { package = "tikv-jemalloc-sys", version = "0.6.0" } json-patch = "0.2.6" jsonwebtoken = "8.1" jwt = "0.16.0" @@ -642,7 +670,7 @@ libfuzzer-sys = "0.4.6" libsecp256k1 = "0.7.0" libtest-mimic = "0.5.2" log = "0.4.17" -lru = "0.7.5" +lru = "0.16.1" lz4 = "1.28.0" maplit = "1.0.2" merlin = "3" @@ -693,7 +721,7 @@ pretty = "0.10.0" pretty_assertions = "1.2.1" # We set default-features to false so we don't onboard the libpq dep. See more here: # https://github.com/aptos-labs/aptos-core/pull/12568 -processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors-v2.git", rev = "8628f1534efa28ada547bbcd34afec1af55697d4", default-features = false } +processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors-v2.git", tag = "aptos-indexer-processors-v2.1.5", default-features = false } procfs = "0.14.1" proc-macro2 = "1.0.38" project-root = "0.2.2" @@ -711,6 +739,7 @@ quote = "1.0.18" rand = "0.7.3" rand_core = "0.5.1" random_word = "0.3.0" +rapidhash = "1.4.0" rayon = "1.5.2" redis = { version = "0.22.3", features = [ "tokio-comp", @@ -732,7 +761,7 @@ reqwest-retry = "0.2.1" ring = { version = "0.16.20", features = ["std"] } ripemd = "0.1.1" rlimit = "0.10.2" -rocksdb = { version = "0.22.0", features = ["lz4"] } +rocksdb = { version = "0.24.0", features = ["lz4"] } rsa = { version = "0.9.6" } rstack-self = { version = "0.3.0", features = ["dw"], default-features = false } rstest = "0.15.0" @@ -762,7 +791,6 @@ serde_yaml = "0.8.24" serial_test = "3.1.1" set_env = "1.3.4" shadow-rs = "0.16.2" -simplelog = "0.9.0" smallbitvec = "2.5.1" smallvec = "1.8.0" static_assertions = "1.1.0" @@ -785,6 +813,7 @@ tiny-bip39 = "0.8.2" tiny-keccak = { version = "2.0.2", features = ["keccak", "sha3"] } tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["json", "env-filter"] } +triomphe = "0.1.14" trybuild = "1.0.80" try_match = "0.4.2" tokio = { version = "1.35.1", features = ["full"] } @@ -805,7 +834,6 @@ tonic = { version = "0.12.3", features = [ ] } tonic-reflection = "0.12.3" topological-sort = "0.2.2" -triomphe = "0.1.9" tui = "0.19.0" typed-arena = "2.0.2" typenum = "1.17.0" @@ -815,6 +843,7 @@ ureq = { version = "1.5.4", features = [ "native-tls", ], default-features = false } url = { version = "2.4.0", features = ["serde"] } +usdt = "0.6.0" uuid = { version = "1.0.0", features = ["v4", "serde"] } variant_count = "1.1.0" walkdir = "2.3.3" @@ -831,6 +860,7 @@ z3tracer = "0.8.0" # MOVE DEPENDENCIES move-abigen = { path = "third_party/move/move-prover/move-abigen" } +move-asm = { path = "third_party/move/tools/move-asm" } move-binary-format = { path = "third_party/move/move-binary-format" } move-borrow-graph = { path = "third_party/move/move-borrow-graph" } move-bytecode-source-map = { path = "third_party/move/move-ir-compiler/move-bytecode-source-map" } @@ -855,6 +885,7 @@ move-ir-to-bytecode = { path = "third_party/move/move-ir-compiler/move-ir-to-byt move-linter = { path = "third_party/move/tools/move-linter" } move-model = { path = "third_party/move/move-model" } move-package = { path = "third_party/move/tools/move-package" } +move-package-cache = { path = "third_party/move/tools/move-package-cache" } move-package-manifest = { path = "third_party/move/tools/move-package-manifest" } move-prover = { path = "third_party/move/move-prover" } move-prover-boogie-backend = { path = "third_party/move/move-prover/boogie-backend" } @@ -873,6 +904,7 @@ move-unit-test = { path = "third_party/move/tools/move-unit-test", features = [ "table-extension", ] } move-vm-metrics = { path = "third_party/move/move-vm/metrics" } +move-vm-profiler = { path = "third_party/move/move-vm/profiler" } move-vm-runtime = { path = "third_party/move/move-vm/runtime" } move-vm-test-utils = { path = "third_party/move/move-vm/test-utils", features = [ "table-extension", @@ -883,6 +915,15 @@ move-vm-types = { path = "third_party/move/move-vm/types" } debug = true overflow-checks = true +# For [build-dependencies], cargo sets `opt-level=0` independent of the actual profile used. +# In `aptos-cached-packages` crate, we have `aptos-framework` as a build dependency. Which in a `--release` mode, +# results in additional crates being compiled (335 for `opt-level=3`, 335 more for `opt-level=0`). +# In addition to that, the same `aptos-cached-packages` build has a very compute intensive step to compile +# the whole Aptos Framework with the Move Compiler - which with the `opt-level=0` slows down compilation a lot. +# For the explanation, see https://github.com/rust-lang/cargo/pull/8500 +[profile.release.build-override] +opt-level = 3 + # The performance build is not currently recommended # for production deployments. It has not been widely tested. [profile.performance] @@ -911,6 +952,8 @@ debug-assertions = true debug = true [patch.crates-io] +# version 0.6 at commit 444eb13579c733089453806743b19f1ea2dce1c0 did not expose 'run_bench_with_bencher' as a public function, which we need +dudect-bencher = { git = "https://github.com/aptos-labs/dudect-bencher", rev = "9515677c83c58884c1a8c764251753269d46fc0e" } serde-reflection = { git = "https://github.com/aptos-labs/serde-reflection", rev = "73b6bbf748334b71ff6d7d09d06a29e3062ca075" } merlin = { git = "https://github.com/aptos-labs/merlin" } futures = { git = "https://github.com/aptos-labs/futures-rs", branch = "backport" } @@ -922,3 +965,8 @@ futures-sink = { git = "https://github.com/aptos-labs/futures-rs", branch = "bac futures-io = { git = "https://github.com/aptos-labs/futures-rs", branch = "backport" } futures-task = { git = "https://github.com/aptos-labs/futures-rs", branch = "backport" } futures-macro = { git = "https://github.com/aptos-labs/futures-rs", branch = "backport" } + +# There is a circular dependency between aptos-core, aptos-indexer-processor-sdk, and aptos-indexer-processors-v2, +# so we cannot simply change the version and package for `jemalloc-sys` in one repo without running into conflicts. +# We have to keep this shim until everything uses the same jemalloc dependency. +jemalloc-sys = { git = "https://github.com/aptos-labs/jemalloc-sys-shim", rev = "e0920246dd74303fab9a14b990768c6ac990a59b" } diff --git a/Justfile b/Justfile index 60cc94540b9..0cd6889bb9d 100644 --- a/Justfile +++ b/Justfile @@ -110,14 +110,14 @@ container-build container="aptos-node" tag="latest" profile="release": docker build \ --build-arg BINARY_PATH="$BINARY_PATH" \ -f docker/{{container}}/Dockerfile \ - -t ghcr.io/movementlabsxyz/{{container}}:{{tag}} . + -t ghcr.io/movement-network/{{container}}:{{tag}} . # Clean up the copied binary rm -f aptos-test # Push a container image to GHCR container-push container="aptos-node" tag="latest": - docker push ghcr.io/movementlabsxyz/{{container}}:{{tag}} + docker push ghcr.io/movement-network/{{container}}:{{tag}} # Build and push a container image container-release container="aptos-node" tag="latest" profile="release": diff --git a/api/Cargo.toml b/api/Cargo.toml index 4bda07ed552..3be5a7dd2ad 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -44,6 +44,7 @@ paste = { workspace = true } poem = { workspace = true } poem-openapi = { workspace = true } regex = { workspace = true } +rstest = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } @@ -56,6 +57,7 @@ aptos-gas-meter = { workspace = true } aptos-gas-schedule = { workspace = true, features = ["testing"] } aptos-move-stdlib = { workspace = true } aptos-proptest-helpers = { workspace = true } +aptos-transaction-filters = { workspace = true, features = ["fuzzing"] } move-package = { workspace = true } passkey-types = { workspace = true } percent-encoding = { workspace = true } diff --git a/api/doc/spec.html b/api/doc/spec.html index 6a07046200d..5a28dba0b73 100644 --- a/api/doc/spec.html +++ b/api/doc/spec.html @@ -11,7 +11,7 @@ ) data is represented as hex-encoded string prefixed with `0x` and fulfilled with\ntwo hex digits per byte.\n\nUnlike the `Address` type, HexEncodedBytes will not trim any zeros.\n", "example": "0x88fbd33f54e1126269769780feb24480428179f552e2313fbe571b72e62a1ca1" }, + "I128": { + "type": "string", + "format": "int128", + "description": "A string containing a 128-bit signed integer.\n\nWe represent i128 values as a string to ensure compatibility with languages such\nas JavaScript that do not parse i128s in JSON natively.\n", + "example": "-32425224034" + }, + "I256": { + "type": "string", + "format": "int256", + "description": "A string containing a 256-bit signed integer.\n\nWe represent i256 values as a string to ensure compatibility with languages such\nas JavaScript that do not parse i256s in JSON natively.\n", + "example": "-32425224034" + }, + "I64": { + "type": "string", + "format": "int64", + "description": "A string containing a 64-bit signed integer.\n\nWe represent i64 values as a string to ensure compatibility with languages such\nas JavaScript that do not parse i64s in JSON natively.\n", + "example": "-32425224034" + }, "IdentifierWrapper": { "type": "string" }, @@ -16695,6 +17309,7 @@ "name", "is_native", "is_event", + "is_enum", "abilities", "generic_type_params", "fields" @@ -16711,6 +17326,10 @@ "type": "boolean", "description": "Whether the struct is marked with the #[event] annotation" }, + "is_enum": { + "type": "boolean", + "description": "Whether the struct is an enum (i.e. enum MyEnum vs struct MyStruct)." + }, "abilities": { "type": "array", "description": "Abilities associated with the struct", @@ -16774,7 +17393,7 @@ }, "MoveStructValue": { "type": "object", - "description": "This is a JSON representation of some data within an account resource. More specifically,\nit is a map of strings to arbitrary JSON values / objects, where the keys are top level\nfields within the given resource.\n\nTo clarify, you might query for 0x1::account::Account and see the example data.\n\nMove `bool` type value is serialized into `boolean`.\n\nMove `u8`, `u16` and `u32` type value is serialized into `integer`.\n\nMove `u64`, `u128` and `u256` type value is serialized into `string`.\n\nMove `address` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string.\nFor example:\n - `0x1`\n - `0x1668f6be25668c1a17cd8caf6b8d2f25`\n\nMove `vector` type value is serialized into `array`, except `vector` which is serialized into a\nHexEncodedBytes string with `0x` prefix.\nFor example:\n - `vector{255, 255}` => `[\"255\", \"255\"]`\n - `vector{255, 255}` => `0xffff`\n\nMove `struct` type value is serialized into `object` that looks like this (except some Move stdlib types, see the following section):\n ```json\n {\n field1_name: field1_value,\n field2_name: field2_value,\n ......\n }\n ```\n\nFor example:\n `{ \"created\": \"0xa550c18\", \"role_id\": \"0\" }`\n\n**Special serialization for Move stdlib types**:\n - [0x1::string::String](https://github.com/aptos-labs/aptos-core/blob/main/third_party/move/move-stdlib/docs/ascii.md)\n is serialized into `string`. For example, struct value `0x1::string::String{bytes: b\"Hello World!\"}`\n is serialized as `\"Hello World!\"` in JSON.\n", + "description": "This is a JSON representation of some data within an account resource. More specifically,\nit is a map of strings to arbitrary JSON values / objects, where the keys are top level\nfields within the given resource.\n\nTo clarify, you might query for 0x1::account::Account and see the example data.\n\nMove `bool` type value is serialized into `boolean`.\n\nMove `u8`, `u16`, `u32`, `i8`, `i16`, and `i32` type value is serialized into `integer`.\n\nMove `u64`, `u128`, `u256`, `i64`, `i128`, and `i256` type value is serialized into `string`.\n\nMove `address` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string.\nFor example:\n - `0x1`\n - `0x1668f6be25668c1a17cd8caf6b8d2f25`\n\nMove `vector` type value is serialized into `array`, except `vector` which is serialized into a\nHexEncodedBytes string with `0x` prefix.\nFor example:\n - `vector{255, 255}` => `[\"255\", \"255\"]`\n - `vector{255, 255}` => `0xffff`\n\nMove `struct` type value is serialized into `object` that looks like this (except some Move stdlib types, see the following section):\n ```json\n {\n field1_name: field1_value,\n field2_name: field2_value,\n ......\n }\n ```\n\nFor example:\n `{ \"created\": \"0xa550c18\", \"role_id\": \"0\" }`\n\n**Special serialization for Move stdlib types**:\n - [0x1::string::String](https://github.com/aptos-labs/aptos-core/blob/main/third_party/move/move-stdlib/docs/ascii.md)\n is serialized into `string`. For example, struct value `0x1::string::String{bytes: b\"Hello World!\"}`\n is serialized as `\"Hello World!\"` in JSON.\n", "example": { "authentication_key": "0x0000000000000000000000000000000000000000000000000000000000000001", "coin_register_events": { @@ -16792,8 +17411,8 @@ }, "MoveType": { "type": "string", - "description": "String representation of an on-chain Move type tag that is exposed in transaction payload.\n Values:\n - bool\n - u8\n - u16\n - u32\n - u64\n - u128\n - u256\n - address\n - signer\n - vector: `vector<{non-reference MoveTypeId}>`\n - struct: `{address}::{module_name}::{struct_name}::<{generic types}>`\n\n Vector type value examples:\n - `vector`\n - `vector>`\n - `vector<0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>>`\n\n Struct type value examples:\n - `0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>\n - `0x1::account::Account`\n\n Note:\n 1. Empty chars should be ignored when comparing 2 struct tag ids.\n 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding).\n", - "pattern": "^(bool|u8|u64|u128|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$" + "description": "String representation of an on-chain Move type tag that is exposed in transaction payload.\n Values:\n - bool\n - u8\n - u16\n - u32\n - u64\n - u128\n - u256\n - i8\n - i16\n - i32\n - i64\n - i128\n - i256\n - address\n - signer\n - vector: `vector<{non-reference MoveTypeId}>`\n - struct: `{address}::{module_name}::{struct_name}::<{generic types}>`\n\n Vector type value examples:\n - `vector`\n - `vector>`\n - `vector<0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>>`\n\n Struct type value examples:\n - `0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>\n - `0x1::account::Account`\n\n Note:\n 1. Empty chars should be ignored when comparing 2 struct tag ids.\n 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding).\n", + "pattern": "^(bool|u8|u16|u32|u64|u128|u256|i8|i16|i32|i64|i128|i256|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$" }, "MoveValue": { "type": "object", @@ -16820,6 +17439,27 @@ { "$ref": "#/components/schemas/U256" }, + { + "type": "integer", + "format": "int8" + }, + { + "type": "integer", + "format": "int16" + }, + { + "type": "integer", + "format": "int32" + }, + { + "$ref": "#/components/schemas/I64" + }, + { + "$ref": "#/components/schemas/I128" + }, + { + "$ref": "#/components/schemas/I256" + }, { "type": "boolean" }, @@ -17029,6 +17669,17 @@ } } }, + "PersistedAuxiliaryInfo": { + "type": "object", + "description": "API representation of persisted auxiliary transaction information", + "properties": { + "transaction_index": { + "type": "integer", + "format": "uint32", + "description": "Optional transaction index in the block (None indicates no auxiliary info available)" + } + } + }, "PublicKey": { "type": "object", "oneOf": [ diff --git a/api/doc/spec.yaml b/api/doc/spec.yaml index 4698a0f0458..f8fb3385a2e 100644 --- a/api/doc/spec.yaml +++ b/api/doc/spec.yaml @@ -8241,6 +8241,447 @@ paths: type: integer format: uint64 operationId: get_transaction_by_version + /transactions/auxiliary_info: + get: + tags: + - Transactions + summary: Get transactions auxiliary info + description: |- + Retrieves persisted auxiliary information (such as transaction indices within blocks) for + transactions in a given version range. + + If the version range has been pruned, a 410 will be returned. + parameters: + - name: start_version + schema: + $ref: '#/components/schemas/U64' + in: query + description: Starting ledger version to retrieve auxiliary info for + required: true + deprecated: false + explode: true + - name: limit + schema: + type: integer + format: uint16 + in: query + description: |- + Max number of transactions to retrieve auxiliary info for. + + If not provided, defaults to default page size + required: false + deprecated: false + explode: true + responses: + '200': + description: '' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PersistedAuxiliaryInfo' + application/x-bcs: + schema: + type: array + items: + type: integer + format: uint8 + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + required: true + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-CURSOR: + description: |- + Cursor to be used for endpoints that support cursor-based + pagination. Pass this to the `start` field of the endpoint + on the next call to get the next page of results. + deprecated: false + schema: + type: string + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '410': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '503': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + operationId: get_transactions_auxiliary_info /accounts/{address}/transactions: get: tags: @@ -11361,7 +11802,7 @@ paths: operationId: view components: schemas: - AbstractionSignature: + AbstractSignature: type: object required: - function_info @@ -11401,7 +11842,7 @@ components: - $ref: '#/components/schemas/AccountSignature_SingleKeySignature' - $ref: '#/components/schemas/AccountSignature_MultiKeySignature' - $ref: '#/components/schemas/AccountSignature_NoAccountSignature' - - $ref: '#/components/schemas/AccountSignature_AbstractionSignature' + - $ref: '#/components/schemas/AccountSignature_AbstractSignature' discriminator: propertyName: type mapping: @@ -11410,8 +11851,8 @@ components: single_key_signature: '#/components/schemas/AccountSignature_SingleKeySignature' multi_key_signature: '#/components/schemas/AccountSignature_MultiKeySignature' no_account_signature: '#/components/schemas/AccountSignature_NoAccountSignature' - abstraction_signature: '#/components/schemas/AccountSignature_AbstractionSignature' - AccountSignature_AbstractionSignature: + abstract_signature: '#/components/schemas/AccountSignature_AbstractSignature' + AccountSignature_AbstractSignature: allOf: - type: object required: @@ -11420,9 +11861,9 @@ components: type: type: string enum: - - abstraction_signature - example: abstraction_signature - - $ref: '#/components/schemas/AbstractionSignature' + - abstract_signature + example: abstract_signature + - $ref: '#/components/schemas/AbstractSignature' AccountSignature_Ed25519Signature: allOf: - type: object @@ -11533,6 +11974,7 @@ components: - invalid_transaction_update - sequence_number_too_old - vm_error + - rejected_by_filter - health_check_failed - mempool_is_full - internal_error @@ -12219,6 +12661,33 @@ components: Unlike the `Address` type, HexEncodedBytes will not trim any zeros. example: 0x88fbd33f54e1126269769780feb24480428179f552e2313fbe571b72e62a1ca1 + I128: + type: string + format: int128 + description: | + A string containing a 128-bit signed integer. + + We represent i128 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i128s in JSON natively. + example: '-32425224034' + I256: + type: string + format: int256 + description: | + A string containing a 256-bit signed integer. + + We represent i256 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i256s in JSON natively. + example: '-32425224034' + I64: + type: string + format: int64 + description: | + A string containing a 64-bit signed integer. + + We represent i64 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i64s in JSON natively. + example: '-32425224034' IdentifierWrapper: type: string IndexResponse: @@ -12467,6 +12936,7 @@ components: - name - is_native - is_event + - is_enum - abilities - generic_type_params - fields @@ -12479,6 +12949,9 @@ components: is_event: type: boolean description: 'Whether the struct is marked with the #[event] annotation' + is_enum: + type: boolean + description: Whether the struct is an enum (i.e. enum MyEnum vs struct MyStruct). abilities: type: array description: Abilities associated with the struct @@ -12548,9 +13021,9 @@ components: Move `bool` type value is serialized into `boolean`. - Move `u8`, `u16` and `u32` type value is serialized into `integer`. + Move `u8`, `u16`, `u32`, `i8`, `i16`, and `i32` type value is serialized into `integer`. - Move `u64`, `u128` and `u256` type value is serialized into `string`. + Move `u64`, `u128`, `u256`, `i64`, `i128`, and `i256` type value is serialized into `string`. Move `address` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string. For example: @@ -12601,6 +13074,12 @@ components: - u64 - u128 - u256 + - i8 + - i16 + - i32 + - i64 + - i128 + - i256 - address - signer - vector: `vector<{non-reference MoveTypeId}>` @@ -12618,7 +13097,7 @@ components: Note: 1. Empty chars should be ignored when comparing 2 struct tag ids. 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding). - pattern: ^(bool|u8|u64|u128|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$ + pattern: ^(bool|u8|u16|u32|u64|u128|u256|i8|i16|i32|i64|i128|i256|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$ MoveValue: type: object description: An enum of the possible Move value types @@ -12632,6 +13111,15 @@ components: - $ref: '#/components/schemas/U64' - $ref: '#/components/schemas/U128' - $ref: '#/components/schemas/U256' + - type: integer + format: int8 + - type: integer + format: int16 + - type: integer + format: int32 + - $ref: '#/components/schemas/I64' + - $ref: '#/components/schemas/I128' + - $ref: '#/components/schemas/I256' - type: boolean - $ref: '#/components/schemas/Address' - type: array @@ -12775,6 +13263,14 @@ components: $ref: '#/components/schemas/TransactionSignature' replay_protection_nonce: $ref: '#/components/schemas/U64' + PersistedAuxiliaryInfo: + type: object + description: API representation of persisted auxiliary transaction information + properties: + transaction_index: + type: integer + format: uint32 + description: Optional transaction index in the block (None indicates no auxiliary info available) PublicKey: type: object oneOf: diff --git a/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_replay_protection_nonce.json b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_replay_protection_nonce.json new file mode 100644 index 00000000000..a14b4c0c54e --- /dev/null +++ b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_replay_protection_nonce.json @@ -0,0 +1,5 @@ +{ + "message": "parse request payload error: failed to parse \"string(U64)\": Parsing u64 string \"invalid\" failed, caused by error: invalid digit found in string (occurred while parsing \"optional\") (occurred while parsing \"UserTransactionRequestInner\") (occurred while parsing \"EncodeSubmissionRequest\")", + "error_code": "web_framework_error", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sender_address.json b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sender_address.json new file mode 100644 index 00000000000..2b4215dd812 --- /dev/null +++ b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sender_address.json @@ -0,0 +1,5 @@ +{ + "message": "parse request payload error: failed to parse \"string(Address)\": Invalid account address: Hex characters are invalid: Invalid character 'i' at position 57 (occurred while parsing \"UserTransactionRequestInner\") (occurred while parsing \"EncodeSubmissionRequest\")", + "error_code": "web_framework_error", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sequence_number.json b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sequence_number.json new file mode 100644 index 00000000000..ce0d0db8fe7 --- /dev/null +++ b/api/goldens/aptos_api__tests__invalid_post_request_test__test_invalid_sequence_number.json @@ -0,0 +1,5 @@ +{ + "message": "parse request payload error: failed to parse \"string(U64)\": Parsing u64 string \"invalid\" failed, caused by error: invalid digit found in string (occurred while parsing \"UserTransactionRequestInner\") (occurred while parsing \"EncodeSubmissionRequest\")", + "error_code": "web_framework_error", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__option_test__run_option.json b/api/goldens/aptos_api__tests__option_test__run_option.json new file mode 100644 index 00000000000..2aab72ee8da --- /dev/null +++ b/api/goldens/aptos_api__tests__option_test__run_option.json @@ -0,0 +1 @@ +[{"vec":["1"]}] \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa.json index bac77b4abe7..5a896ef61b4 100644 --- a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa.json +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa.json @@ -1,19 +1,5 @@ { - "public_keys": [ - { - "value": "0x049b8327d929a0e45285c04d19c9fffbee065c266b701972922d807228120e43f34ad68ac77f6ec0205fe39f7c5b6055dad973a03464a3a743302de0feaf6ec6d9", - "type": "secp256k1_ecdsa" - } - ], - "signatures": [ - { - "index": 0, - "signature": { - "value": "0xd1c84463d33b27977431b60664b36c6c1717569b1fbe2f9808c1e78f36958ae71a2b59a7c062e9491c12e69e25e3d3f82253a4efd1c1857b3695ff1b9050c5e4", - "type": "secp256k1_ecdsa" - } - } - ], - "signatures_required": 1, - "type": "single_sender" + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x56e2eb368dc65d486aeeb59ced618b1866a79e5abf6cc5e58b77690a3de4ec7a4cf953c7ca73c2a1ee9576847efcec9798c69dc081651a58db649dc3595e2c05", + "type": "ed25519_signature" } diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_orderless.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_orderless.json new file mode 100644 index 00000000000..9f9ea692f72 --- /dev/null +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_orderless.json @@ -0,0 +1,5 @@ +{ + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xefaf3aedae6b756deffb2c11cf166afa1bcbb39275d5e942a785505152db9c5725b55c7d8772bc8d5b6c99d5437cadcbe2943a7eaed1f730ecb46c8cc1f7710e", + "type": "ed25519_signature" +} diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_payload_v2.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_payload_v2.json new file mode 100644 index 00000000000..fbdb7f4c952 --- /dev/null +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_multi_secp256k1_ecdsa_payload_v2.json @@ -0,0 +1,5 @@ +{ + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xc992ceaebe5d65f34f3e8dcbdae3f303e98b25d922f076fdddd3942b1b5972eccb1714c38a5c124ac055dfd656a3d6056885cd82d5454514eb136271fcc26b04", + "type": "ed25519_signature" +} diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa.json index 958ae212277..5a896ef61b4 100644 --- a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa.json +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa.json @@ -1,11 +1,5 @@ { - "public_key": { - "value": "0x049b8327d929a0e45285c04d19c9fffbee065c266b701972922d807228120e43f34ad68ac77f6ec0205fe39f7c5b6055dad973a03464a3a743302de0feaf6ec6d9", - "type": "secp256k1_ecdsa" - }, - "signature": { - "value": "0x357a77abdb3ef4a01aea1e8d0cb932606655bcf66e6726d2cefbfd904d57703b0bf38eb19bc3da1e3e9f6929db0d4806f83fa5370f6981d704efa42cdba56fb9", - "type": "secp256k1_ecdsa" - }, - "type": "single_sender" + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x56e2eb368dc65d486aeeb59ced618b1866a79e5abf6cc5e58b77690a3de4ec7a4cf953c7ca73c2a1ee9576847efcec9798c69dc081651a58db649dc3595e2c05", + "type": "ed25519_signature" } diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_orderless.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_orderless.json new file mode 100644 index 00000000000..9f9ea692f72 --- /dev/null +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_orderless.json @@ -0,0 +1,5 @@ +{ + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xefaf3aedae6b756deffb2c11cf166afa1bcbb39275d5e942a785505152db9c5725b55c7d8772bc8d5b6c99d5437cadcbe2943a7eaed1f730ecb46c8cc1f7710e", + "type": "ed25519_signature" +} diff --git a/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_payload_v2.json b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_payload_v2.json new file mode 100644 index 00000000000..fbdb7f4c952 --- /dev/null +++ b/api/goldens/aptos_api__tests__secp256k1_ecdsa__test_secp256k1_ecdsa_payload_v2.json @@ -0,0 +1,5 @@ +{ + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xc992ceaebe5d65f34f3e8dcbdae3f303e98b25d922f076fdddd3942b1b5972eccb1714c38a5c124ac055dfd656a3d6056885cd82d5454514eb136271fcc26b04", + "type": "ed25519_signature" +} diff --git a/api/goldens/aptos_api__tests__simulation_test__test_simulate_transaction_with_valid_signature_bcs.json b/api/goldens/aptos_api__tests__simulation_test__test_simulate_transaction_with_valid_signature_bcs.json new file mode 100644 index 00000000000..af1db2c44e3 --- /dev/null +++ b/api/goldens/aptos_api__tests__simulation_test__test_simulate_transaction_with_valid_signature_bcs.json @@ -0,0 +1,5 @@ +{ + "message": "Simulated transactions must not have a valid signature", + "error_code": "invalid_input", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__state_test__test_get_account_module.json b/api/goldens/aptos_api__tests__state_test__test_get_account_module.json index 8840a0ca300..5159d0a6653 100644 --- a/api/goldens/aptos_api__tests__state_test__test_get_account_module.json +++ b/api/goldens/aptos_api__tests__state_test__test_get_account_module.json @@ -1,5 +1,5 @@ { - "bytecode": "0xa11ceb0b0700000a0b010002020208030a30053a23075d7b08d8012010f801b9010ab1030d0cbe037e0dbc04060fc2040400000001060000030700000600010001000703040001000406020001000806070001000908090001000206040001000a0a020001000b0a0700010205070301080001030205030108010001060800010502060800060801010101060801046775696404475549440269640249440c6372656174696f6e5f6e756d046164647206637265617465096372656174655f69640f63726561746f725f616464726573730565715f69640f69645f6372656174696f6e5f6e756d1269645f63726561746f725f61646472657373076163636f756e74066f626a656374000000000000000000000000000000000000000000000000000000000000000114636f6d70696c6174696f6e5f6d65746164617461090003322e3003322e31126170746f733a3a6d657461646174615f763185010100000000000000001d45475549445f47454e455241544f525f4e4f545f5055424c49534845445b475549442067656e657261746f72206d757374206265207075626c6973686564206168656164206f66206669727374207573616765206f6620606372656174655f776974685f6361706162696c697479602066756e6374696f6e2e00000002010208010102020403050500030000020d0a01140c020a02060100000000000000160b01150b020b0012011200020101000005040b010b001201020201000005050b001000100114020301000005050b001000100214020401000005050b0010000b0121020501000005040b00100014020601000005040b00100114020701000005040b0010021402000001000101000c000d00", + "bytecode": "0xa11ceb0b0800000a0b010002020208030a3f054923076c7b08e70120108702b9010ac0030d0ccd037e0dcb04060fd10404000000010600000307000006000100010000070304000101010004060200010101000806070001010100090809000101010002060400010101000a0a0200010101000b0a07000101010205070301080001030205030108010001060800010502060800060801010101060801046775696404475549440269640249440c6372656174696f6e5f6e756d046164647206637265617465096372656174655f69640f63726561746f725f616464726573730565715f69640f69645f6372656174696f6e5f6e756d1269645f63726561746f725f61646472657373076163636f756e74066f626a656374000000000000000000000000000000000000000000000000000000000000000114636f6d70696c6174696f6e5f6d65746164617461090003322e3003322e32126170746f733a3a6d657461646174615f763185010100000000000000001d45475549445f47454e455241544f525f4e4f545f5055424c49534845445b475549442067656e657261746f72206d757374206265207075626c6973686564206168656164206f66206669727374207573616765206f6620606372656174655f776974685f6361706162696c697479602066756e6374696f6e2e00000002010208010102020403050500030000020d0a01140c020a02060100000000000000160b01150b020b0012011200020101000005040b010b001201020201000005050b001000100114020301000005050b001000100214020401000005050b0010000b0121020501000005040b00100014020601000005040b00100114020701000005040b0010021402000001000101000c000d00", "abi": { "address": "0x1", "name": "guid", @@ -121,6 +121,7 @@ "name": "GUID", "is_native": false, "is_event": false, + "is_enum": false, "abilities": [ "drop", "store" @@ -137,6 +138,7 @@ "name": "ID", "is_native": false, "is_event": false, + "is_enum": false, "abilities": [ "copy", "drop", diff --git a/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json b/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json index 7e340984449..0a113023990 100644 --- a/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json +++ b/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json @@ -1,211 +1,324 @@ [ { "raw_txn": { - "sender": "3364faedb070fcddabba6af05ac3b1d3e4cf59517df4d296872fe3cc41763c07", - "sequence_number": "18129649627527924708", + "sender": "f781d9248b3965741e9d4d11c0acc44743e773c469796bb070c3914aed7136b3", + "sequence_number": "10142476032578219882", "payload": { "EntryFunction": { "module": { "address": "0496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c", - "name": "xEWRAnYkugjvJrVhoZLPfQYVMwjXPoR1_Coin" + "name": "lTFMwskIkF_Coin" }, - "function": "bqIEyRbFAc7", + "function": "BJCusjEgchjGrHJHfKmL3", "ty_args": [ { "vector": { - "vector": "u8" - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "4866220c00bb849c354aebf118b7e7675ad8e5592dd144edb23b520b53d4c874", - "module": "awOEaxZmLztVXoKOOcBmjLVTY", - "name": "PwJ", - "type_args": [] - } - } + "vector": "signer" } }, { - "vector": "address" + "vector": "signer" }, { "struct": { - "address": "2bf1cb23b029f9771b9ab78de45b21fabe79496e392fc4129b157f881e646bba", - "module": "xhdHJvZKTGkwoT", - "name": "GWGwAcDTUKLbVapovyiYPFXylxO", + "address": "b7e7675ad8e5592dd144edb23b520b53d4c874d5bb61d8f0bfc357bff99bdbf4", + "module": "FFtlLLaTWpvvErMMQKulDxAeAiGO", + "name": "NDqdiWY", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "f74c7fef8a72033b03a145edb4cb8fdedf59994753e563394cb1e5fd22b126f4", - "module": "MjrpLAGaTUmrfPelcgAdIjvvzArjNdP", - "name": "SKZdMYrqYdLqHLZdzknLvav", - "type_args": [] - } + "vector": "signer" + } + }, + { + "vector": { + "struct": { + "address": "da1f1740b3274a727934637d853b8642c789c38750f9c221a082a27ae257402f", + "module": "x6", + "name": "eWwgpakKdBqwrLPavM", + "type_args": [] } } }, { "struct": { - "address": "bc788e57184e12a7c21570762a1a0ccf1756448be98bd597c5ed528d3d6da03c", - "module": "xboPoeiE", - "name": "ylHMDIorVYPTwGtdBRuL8", + "address": "da1ab2bf902e45e73c5a590b9e2ae7d8b2c5f3cf10763868052460d19b726f69", + "module": "XBHmJC5", + "name": "nfsdfNnwRIQZZIPFp", "type_args": [] } } ], "args": [ - "1693730cdd1903ac", "01", - "72", - "97e8487e2c8ae82bd8431fde4053c4fc772146b39f97b269e960c3125f062925" + "66708be7833cefb7994ed0a5e277767a034b546a880e71dc189254009abac792", + "9a", + "20", + "00", + "9987f15a96b78be319170febeee4f65618ca29f9f9ed5ef623577d10cbbd8330", + "e954018b387611a72eda24ec9429b14d3c114db76e54b933cf1f8bd039a70fdc" ] } }, - "max_gas_amount": "8512786420152370650", - "gas_unit_price": "14991845072478366484", - "expiration_timestamp_secs": "2619726678109771971", - "chain_id": 67 + "max_gas_amount": "11416506364619761024", + "gas_unit_price": "2407153818005157530", + "expiration_timestamp_secs": "15488783003977911101", + "chain_id": 195 }, - "signed_txn_bcs": "3364faedb070fcddabba6af05ac3b1d3e4cf59517df4d296872fe3cc41763c07e44b18ff477499fb020496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c2578455752416e596b75676a764a7256686f5a4c50665159564d776a58506f52315f436f696e0b6271494579526246416337060606010606074866220c00bb849c354aebf118b7e7675ad8e5592dd144edb23b520b53d4c8741961774f4561785a6d4c7a7456586f4b4f4f63426d6a4c5654590350774a000604072bf1cb23b029f9771b9ab78de45b21fabe79496e392fc4129b157f881e646bba0e786864484a765a4b54476b776f541b4757477741634454554b4c625661706f76796959504658796c784f00060607f74c7fef8a72033b03a145edb4cb8fdedf59994753e563394cb1e5fd22b126f41f4d6a72704c41476154556d726650656c63674164496a76767a41726a4e645017534b5a644d59727159644c71484c5a647a6b6e4c7661760007bc788e57184e12a7c21570762a1a0ccf1756448be98bd597c5ed528d3d6da03c0878626f506f65694515796c484d44496f7256595054774774644252754c380004081693730cdd1903ac010101722097e8487e2c8ae82bd8431fde4053c4fc772146b39f97b269e960c3125f062925da85f37d257e2376146bc3c8a9bb0dd0c3d858a988235b2443002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019f9c012c90154ed387cb69f28fcbc683e2bba26924ef8351b6d83baf327dffbfd354b06d4f6ffdad0e551dc80a603398bffbcee2cfb127e496f4c2a4bd13e07", + "signed_txn_bcs": "f781d9248b3965741e9d4d11c0acc44743e773c469796bb070c3914aed7136b36aefbce83650c18c020496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c0f6c54464d77736b496b465f436f696e15424a4375736a456763686a4772484a48664b6d4c3306060605060507b7e7675ad8e5592dd144edb23b520b53d4c874d5bb61d8f0bfc357bff99bdbf41c4646746c4c4c61545770767645724d4d514b756c447841654169474f074e447164695759000606050607da1f1740b3274a727934637d853b8642c789c38750f9c221a082a27ae257402f027836126557776770616b4b64427177724c5061764d0007da1ab2bf902e45e73c5a590b9e2ae7d8b2c5f3cf10763868052460d19b726f69075842486d4a4335116e667364664e6e775249515a5a49504670000701012066708be7833cefb7994ed0a5e277767a034b546a880e71dc189254009abac792019a01200100209987f15a96b78be319170febeee4f65618ca29f9f9ed5ef623577d10cbbd833020e954018b387611a72eda24ec9429b14d3c114db76e54b933cf1f8bd039a70fdc80a525270d946f9e9a36ecd1a4ed67213d0b363b1436f3d6c3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f9740dec82d0bfe6dfd5b6aa874516c2766d1b9dd38ff07d34e694426b1db0c5c181263961e5d15adf58d2a8c12a6a2f04d2276e4a744a3af8d20f95a16bf0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c04702271194143d2ec17a83f50213effde95200110c77fe4c2128e09fddec03", - "sequence_number": "11779767485194459705", + "sender": "46bf9ca6cc12d114280cbff0697317c79ca78a2d85015b90f4497fbed3b86ab2", + "sequence_number": "16693192227961553902", "payload": { "EntryFunction": { "module": { - "address": "ae97a3f28d001e3e009cfa88bb5df4ef8b0e489156348f02bfa5972dcbf64198", - "name": "KtazJwvtQGVixUtdmpdTxPgIzRP3_Coin" + "address": "638dca5cf3940cdbe43f91d657f3cf9f058d2b75f4df7763dbd12fc5a2a012ef", + "name": "uCnfPWzPrUL6_Coin" }, - "function": "JnZVFRTxAXwABaXbfFduosWxgRBuEAo3", + "function": "HvdSlCUSpzuzRRRdEzGDrF4", "ty_args": [ { "vector": { - "struct": { - "address": "bb1b18f7e217081e4b924cbf2f7127e4b875e606c3b2785c46f14e4983c16f1b", - "module": "aBdTPBGhsXWBqxgdP", - "name": "jgvLXdLMdqGgEVAXhVtmyEsXaOF", - "type_args": [] - } + "vector": "u64" } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "27533da6db6fd9029cb6b1f6ef776782fd090908c30bfe5d179bfe733d77b4ce", + "module": "WQ", + "name": "jo", + "type_args": [] } - }, + } + ], + "args": [ + "71490b008988c9b516c76697e8487e2c8ae82bd8431fde4053c4fc772146b39f", + "962b5ab587966238", + "f25439c1048494cb6a726903a7027ad5", + "08580580106e1d559623a2647985a2ef", + "a0b6348a6c806f39103cf15787ba8173747a54d40d3355dca58618bc97b6c128", + "7bdfbeace6a575255ce9cbb81b53c3b1" + ] + } + }, + "max_gas_amount": "12103938025441788085", + "gas_unit_price": "11586076299572095280", + "expiration_timestamp_secs": "14104416069887580933", + "chain_id": 167 + }, + "signed_txn_bcs": "46bf9ca6cc12d114280cbff0697317c79ca78a2d85015b90f4497fbed3b86ab2eec3f512e321aae702638dca5cf3940cdbe43f91d657f3cf9f058d2b75f4df7763dbd12fc5a2a012ef1175436e6650577a5072554c365f436f696e17487664536c435553707a757a52525264457a4744724634020606020727533da6db6fd9029cb6b1f6ef776782fd090908c30bfe5d179bfe733d77b4ce025751026a6f00062071490b008988c9b516c76697e8487e2c8ae82bd8431fde4053c4fc772146b39f08962b5ab58796623810f25439c1048494cb6a726903a7027ad51008580580106e1d559623a2647985a2ef20a0b6348a6c806f39103cf15787ba8173747a54d40d3355dca58618bc97b6c128107bdfbeace6a575255ce9cbb81b53c3b1b500cd3581d3f9a7302991400203caa005dbf5e9aff3bcc3a7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440be73eb79d4a4644b634f913caadc800d3cc683e9ff85df7be60b2d3eb42a3fe57c9d1d8a4c899654f310b9f0007ee0f7a13ba4eb84797d4bae2f3cc508a3bd06", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a52aa97eaa15eb9cfb37f68332228a5997d2f97490615c1cde6c9523db431797", + "sequence_number": "14766778299961515281", + "payload": { + "EntryFunction": { + "module": { + "address": "2d74b2717e76a37467779bcb5048b6af3e9138f7adc51f496916fed0953525a3", + "name": "aYZO7_Coin" + }, + "function": "jgBFNsDsQsATjJi", + "ty_args": [ { "vector": { "struct": { - "address": "bae650dbb57e7dd0c1c0327c877d1cc683548dbfd1d95dab28d289429eff8ca4", - "module": "FJpsseqAKLIlYRwAxHNWznqY", - "name": "DBQBIX", + "address": "4af73603539a5bf5e9f1e5da8582c1a434fe94a9a61082b57b4f10fbfc6f6d82", + "module": "UhFNxnGwVNrVzO", + "name": "ArKOTvpmcU", "type_args": [] } } + } + ], + "args": [ + "01", + "aeaee3cc10f4911c9c7c735562564b15", + "3a87246a6888a65e", + "683feee7fbb5135a754e9cffb0e76df6bc1d1d4194c06336573360eabd7544c6", + "735292de992099c4fd2674654f8d9ea0", + "01", + "d0d15068c122438dc03f34b53276aa13", + "894f01daa26a267285dacffd35978539f36dad2bc374d82207ef250773db9e70", + "fe11fb6f9a41e371a936639639373cebe660daf1497ae20ff6cc7bc7dfcf3459", + "52a3c4e0d86d5493725544d0647b9fb2" + ] + } + }, + "max_gas_amount": "12426891022180114397", + "gas_unit_price": "13136716047207170025", + "expiration_timestamp_secs": "7735136167759826674", + "chain_id": 213 + }, + "signed_txn_bcs": "a52aa97eaa15eb9cfb37f68332228a5997d2f97490615c1cde6c9523db431797111d2746a022eecc022d74b2717e76a37467779bcb5048b6af3e9138f7adc51f496916fed0953525a30a61595a4f375f436f696e0f6a6742464e734473517341546a4a690106074af73603539a5bf5e9f1e5da8582c1a434fe94a9a61082b57b4f10fbfc6f6d820e5568464e786e4777564e72567a4f0a41724b4f5476706d6355000a010110aeaee3cc10f4911c9c7c735562564b15083a87246a6888a65e20683feee7fbb5135a754e9cffb0e76df6bc1d1d4194c06336573360eabd7544c610735292de992099c4fd2674654f8d9ea0010110d0d15068c122438dc03f34b53276aa1320894f01daa26a267285dacffd35978539f36dad2bc374d82207ef250773db9e7020fe11fb6f9a41e371a936639639373cebe660daf1497ae20ff6cc7bc7dfcf34591052a3c4e0d86d5493725544d0647b9fb2dd5f894f8b2f75ace9fff4c4a4fd4eb6f2ce99b05cb9586bd5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a208a4f0faeb180684c9fbc082f4fdbb6700748e10e291a80682103fbeed5f8fed336c1ca2a157719e9e842e92689e77815ccfd073998720d04d95380e33120c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a4530486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b00", + "sequence_number": "5941087757108226865", + "payload": { + "EntryFunction": { + "module": { + "address": "cf4e9741567aa421be0114aca3a1a542d3a1fae0ccbd98e11d29e020e5ab1df7", + "name": "qQlFudASTiosQq_Coin" + }, + "function": "ZXFxXytjcuZJqXOzpEiPm2", + "ty_args": [ + { + "vector": { + "vector": { + "struct": { + "address": "b7b9efbcdebbbd4f536e2b525eb6243fc8c04d5e87c6dd52142fe0147839e236", + "module": "VkafuWVJVqmdCzuy", + "name": "oY", + "type_args": [] + } + } + } }, { "vector": { "struct": { - "address": "8332228a5997d2f97490615c1cde6c9523db43179711a0f25cdd8be9a4d5cf4e", - "module": "vaxllIZcpOv6", - "name": "bZcWhxZqsODC5", + "address": "198bdcb25193c74fccc8e57724586f1618e4b35c3a4282057599350497aa5579", + "module": "LbXzGlRKLjz0", + "name": "yfevEAYBBGJM", "type_args": [] } } } ], - "args": [] + "args": [ + "427d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318", + "01", + "05a86fe39d45fad4de532f81ead27c83bd2b5186e3d7aed06a2dbfc2a5cb9ed9", + "a6b8f9b12e3a402dcf463164eff5ee26cd60f03b5bd97076a0b54bc61ec2c596", + "6c", + "6417dd58fa94b1cff6b7ee6e935790904cdb53446c4c01a71f3b83f395142fdd", + "01", + "52beb142c7af701e", + "00" + ] } }, - "max_gas_amount": "6557116728673777100", - "gas_unit_price": "460112503178869952", - "expiration_timestamp_secs": "4391489686854670868", - "chain_id": 82 + "max_gas_amount": "4591469829133248893", + "gas_unit_price": "1083417168633788325", + "expiration_timestamp_secs": "665348431662327138", + "chain_id": 39 }, - "signed_txn_bcs": "c04702271194143d2ec17a83f50213effde95200110c77fe4c2128e09fddec03395ab6ab1d247aa302ae97a3f28d001e3e009cfa88bb5df4ef8b0e489156348f02bfa5972dcbf64198214b74617a4a77767451475669785574646d706454785067497a5250335f436f696e204a6e5a56465254784158774142615862664664756f7357786752427545416f33040607bb1b18f7e217081e4b924cbf2f7127e4b875e606c3b2785c46f14e4983c16f1b1161426454504247687358574271786764501b6a67764c58644c4d64714767455641586856746d79457358614f46000606020607bae650dbb57e7dd0c1c0327c877d1cc683548dbfd1d95dab28d289429eff8ca418464a7073736571414b4c496c5952774178484e577a6e7159064442514249580006078332228a5997d2f97490615c1cde6c9523db43179711a0f25cdd8be9a4d5cf4e0c7661786c6c495a63704f76360d625a635768785a71734f4443350000cc355f73ec8eff5ac03cb144e2a56206149ac3639ab4f13c52002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c076a381282d1aee8ef476c0edab5a49e6e4f880c4b00d7db55a26aba7b8470353fc73b1571d0224ca94086cb0fd840ff7d347a7d70d6b51f8aedc881597301", + "signed_txn_bcs": "a4530486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031abdb7dd6fb725202cf4e9741567aa421be0114aca3a1a542d3a1fae0ccbd98e11d29e020e5ab1df71371516c467564415354696f7351715f436f696e165a5846785879746a63755a4a71584f7a704569506d3202060607b7b9efbcdebbbd4f536e2b525eb6243fc8c04d5e87c6dd52142fe0147839e23610566b61667557564a56716d64437a7579026f59000607198bdcb25193c74fccc8e57724586f1618e4b35c3a4282057599350497aa55790c4c62587a476c524b4c6a7a300c796665764541594242474a4d000920427d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b7931801012005a86fe39d45fad4de532f81ead27c83bd2b5186e3d7aed06a2dbfc2a5cb9ed920a6b8f9b12e3a402dcf463164eff5ee26cd60f03b5bd97076a0b54bc61ec2c596016c206417dd58fa94b1cff6b7ee6e935790904cdb53446c4c01a71f3b83f395142fdd01010852beb142c7af701e01007d2969a27b2db83fa5f7f9b72c12090f62a51899dfca3b0927002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444062155d3d05b0eae448b5814cb4c4d33b4b66bb94ebffc1dba7b1003650fdc4aea2b6e2abf4e5bf041d6ff0b52ca2ebbe663480236e149bd5e21511e715134c04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "28505d751c53f896b5b381d2b8b7bd85011e93af9697ce5b5f97caff92a4ff9d", - "sequence_number": "2592604223019102058", + "sender": "8fb6127415d329d85b4114f186b4fbfd3482f5641b32ba64d161358b0f450e5f", + "sequence_number": "10319453198047505295", "payload": { "EntryFunction": { "module": { - "address": "f066aabe3b0aa6d823edc0ca5d69d68f2f5055d98d0c054792a933f6a93b5c00", - "name": "VxPKiXi_Coin" + "address": "fdc1dd356292312fe49b46fb69a61458b8ce40212f91e37023b0034ac7849e6e", + "name": "BPFVXLvHgOJocTPnkZ_Coin" }, - "function": "QvRDkmoVyQTaZHVhXSxcCGuz4", + "function": "fZFvyBucUOHmMtEaNIiuurGqTBwsKR", "ty_args": [ { "vector": { "struct": { - "address": "fa7edab19264823887df4f1a656b3485c2c63922f0a73bb403ac86e4e8dcd857", - "module": "Yyxn", - "name": "xlj5", + "address": "7e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f32e332ab3", + "module": "yLsxbSVOwWSVlkxypvn", + "name": "MYutLHVigDmjlxBBoMKLASXQ2", "type_args": [] } } }, { "struct": { - "address": "7d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318f2", - "module": "ruQzLNgptFtOIqhbffssFzjHFyeVfb", - "name": "HMIyiYeRORPpNCTkhKzIRXbkzZPmk3", + "address": "70a5bf00e21040b01aad375a6743507253d6cb0bef9bd17b679515ea685ca2e8", + "module": "EIvkDcixVObQxqpNig0", + "name": "BURxeomKcfuVIkkkwChm7", "type_args": [] } }, { "struct": { - "address": "cc91d0aed6f67a840f2fc5cf9c181ca6528f62448c556d79eb193e27633bf317", - "module": "FJHolrUreqxAEZuinoxsYQTuT5", - "name": "COpmCCfVnyTZ", + "address": "1b2e7f03ba4f6e6d627ce14243c60b0cd5992c1d031e6c2d32c516601fac87b7", + "module": "Anvcztgt", + "name": "umiWTSOUWfbQSLYgGIlQARFPNbhsU1", "type_args": [] } }, { - "struct": { - "address": "a6a62405695c22f36587273aa80f1cd68c27c2f4bbf2c79a2f08fd7789dd15b1", - "module": "tcxcMDvjYyQqbcByiyCCl4", - "name": "P", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "5956bb82de8d9a89d59ead68150a87dea4460a5c3760070a38003f78f7ebb012", + "module": "KBUUiHiiDBssmDLQL3", + "name": "AqBozFjNvFKoyhWyV", + "type_args": [] + } + } } }, { "struct": { - "address": "5456d5d711a688d8650ec5d6515e745d35145d2a361541ceb2a298639f3165ca", - "module": "adlfrRILbqMaLRMeWPq", - "name": "aZxtLslCurkLiPrzNeouq4", + "address": "ddc4dcf50f49b80da174e040c27da5ba1b59252879c573c4dffdf752876efd34", + "module": "NKq", + "name": "RYfNTt", "type_args": [] } - }, + } + ], + "args": [ + "392ac5a611f11502fb3d559560b18d75", + "fe34e74525a694e9", + "abe3d63b31866595327aee2bf8ed94bdc32d4ee7bc0a4e369d6e89bcc222c2a9", + "bfaf5abaeb2dc42337953093a37baf58", + "98" + ] + } + }, + "max_gas_amount": "3685048587990418110", + "gas_unit_price": "18224268506418640625", + "expiration_timestamp_secs": "13605692111218686210", + "chain_id": 29 + }, + "signed_txn_bcs": "8fb6127415d329d85b4114f186b4fbfd3482f5641b32ba64d161358b0f450e5f8febe3410210368f02fdc1dd356292312fe49b46fb69a61458b8ce40212f91e37023b0034ac7849e6e1742504656584c7648674f4a6f6354506e6b5a5f436f696e1e665a467679427563554f486d4d7445614e49697575724771544277734b520506077e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f32e332ab313794c73786253564f775753566c6b787970766e194d5975744c48566967446d6a6c7842426f4d4b4c4153585132000770a5bf00e21040b01aad375a6743507253d6cb0bef9bd17b679515ea685ca2e8134549766b44636978564f62517871704e6967301542555278656f6d4b63667556496b6b6b7743686d3700071b2e7f03ba4f6e6d627ce14243c60b0cd5992c1d031e6c2d32c516601fac87b708416e76637a7467741e756d695754534f5557666251534c596747496c51415246504e6268735531000606075956bb82de8d9a89d59ead68150a87dea4460a5c3760070a38003f78f7ebb012124b42555569486969444273736d444c514c33114171426f7a466a4e76464b6f79685779560007ddc4dcf50f49b80da174e040c27da5ba1b59252879c573c4dffdf752876efd34034e4b71065259664e5474000510392ac5a611f11502fb3d559560b18d7508fe34e74525a694e920abe3d63b31866595327aee2bf8ed94bdc32d4ee7bc0a4e369d6e89bcc222c2a910bfaf5abaeb2dc42337953093a37baf580198be4239a32aec2333f1f66b78a69be9fc0239869ce320d1bc1d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403d28a10cdf4f0c549cefa43ec230792fc2658e04f0bd0945ea0e31cd6be3b10a1a28be0e200fcd52d4d70183716ffe111ceca2d336ab7a5e9796d75ab696c305", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "642f28579c0649a3ed597aa502ed2454c3755d153630812625b591cced960fb2", + "sequence_number": "2970420445790869281", + "payload": { + "EntryFunction": { + "module": { + "address": "6f3432c2ad9899f87d7944d89790e263e918c29c5117b0fe3fea83078656fb53", + "name": "taHvsbKyEEtJjHQbbVuOeTKhgTDbJc7_Coin" + }, + "function": "PZxHmTyEhWsrtEKaSfGZvUYIbdnHoVCt", + "ty_args": [ { - "struct": { - "address": "b74ccdc00071baf2c19d210ed4df374485895855605f521f980e65e5c3cdd554", - "module": "HeHALNyVBmnmaBIQPPlsYvQeQbQwjzDF7", - "name": "BPyQTBl7", - "type_args": [] + "vector": { + "struct": { + "address": "8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad684a04", + "module": "Z7", + "name": "EIjiPRawKeJyKqbJ", + "type_args": [] + } } }, - { - "vector": "u64" - }, { "vector": { "struct": { - "address": "62815895e577a53f9d620891d92b7b295c2239ae3545d2e0368f2a08b2c381f1", - "module": "CKFsMhcNOgZfawHuVAfGngACasda", - "name": "zJUMNNDUOmNIiLSJOInQWN", + "address": "b0d38910a88c19d80463a7cb589605ecfc3048baf2edccacddbfe85b751f5582", + "module": "gLJgzALdZADkbuZn", + "name": "sEflokOb9", "type_args": [] } } @@ -213,898 +326,1300 @@ { "vector": { "struct": { - "address": "73055b8d809efda16239c0fe9a0ebb631e2383c361ba43d4cb8f7ba4b4100047", - "module": "DTDEgUWCYkkotrgG3", - "name": "jslFRVmpyvDtoYZhNFNWqZTcSP", + "address": "4d8368d70bfa74bcfaca9d4f1bf772ea9dbfe24ae6d2897e589292fd77bd360f", + "module": "Rp9", + "name": "JWZfFATAr", "type_args": [] } } }, { - "vector": { - "vector": "bool" + "struct": { + "address": "5397093bbc857502123f53ec878f4a16654783b27af4fd15f3026efeb92e3ead", + "module": "AyHvkIOPm4", + "name": "lytXkw8", + "type_args": [] + } + }, + { + "struct": { + "address": "9e923412ce21c119267695ffb89190d246e4cacacbbd052bfc0760e48a8326f7", + "module": "irrFvwLKiMhbOnhSNUf", + "name": "DgZIFspIOEWHHxLCHdwCViUfsn", + "type_args": [] } } ], "args": [ - "63", - "00", - "4c1644b01c901770", - "d89c665cf8f4fa9167ff536292fe4805280408933be8b5af5ab6e795bdbcc684", - "3554b37b01c5ec47e54b1e2fcbc0e3af", - "ce", - "6e52f30c677f3e9d" + "ef", + "580431c60c33522e7170b1d04fb2a270" ] } }, - "max_gas_amount": "12280717757782111148", - "gas_unit_price": "2816398204727124829", - "expiration_timestamp_secs": "3290632587629072169", - "chain_id": 37 + "max_gas_amount": "4295949611041354107", + "gas_unit_price": "9505809599834404731", + "expiration_timestamp_secs": "8639185162411237087", + "chain_id": 99 }, - "signed_txn_bcs": "28505d751c53f896b5b381d2b8b7bd85011e93af9697ce5b5f97caff92a4ff9d6a2f3bfccdc7fa2302f066aabe3b0aa6d823edc0ca5d69d68f2f5055d98d0c054792a933f6a93b5c000c5678504b6958695f436f696e19517652446b6d6f56795154615a485668585378634347757a340a0607fa7edab19264823887df4f1a656b3485c2c63922f0a73bb403ac86e4e8dcd857045979786e04786c6a3500077d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318f21e7275517a4c4e67707446744f4971686266667373467a6a484679655666621e484d4979695965524f5250704e43546b684b7a495258626b7a5a506d6b330007cc91d0aed6f67a840f2fc5cf9c181ca6528f62448c556d79eb193e27633bf3171a464a486f6c72557265717841455a75696e6f78735951547554350c434f706d434366566e79545a0007a6a62405695c22f36587273aa80f1cd68c27c2f4bbf2c79a2f08fd7789dd15b116746378634d44766a5979517162634279697943436c34015000075456d5d711a688d8650ec5d6515e745d35145d2a361541ceb2a298639f3165ca1361646c667252494c62714d614c524d6557507116615a78744c736c4375726b4c6950727a4e656f7571340007b74ccdc00071baf2c19d210ed4df374485895855605f521f980e65e5c3cdd55421486548414c4e7956426d6e6d6142495150506c7359765165516251776a7a444637084250795154426c37000602060762815895e577a53f9d620891d92b7b295c2239ae3545d2e0368f2a08b2c381f11c434b46734d68634e4f675a6661774875564166476e67414361736461167a4a554d4e4e44554f6d4e49694c534a4f496e51574e00060773055b8d809efda16239c0fe9a0ebb631e2383c361ba43d4cb8f7ba4b4100047114454444567555743596b6b6f74726747331a6a736c4652566d70797644746f595a684e464e57715a54635350000606000701630100084c1644b01c90177020d89c665cf8f4fa9167ff536292fe4805280408933be8b5af5ab6e795bdbcc684103554b37b01c5ec47e54b1e2fcbc0e3af01ce086e52f30c677f3e9dac336f13bcdf6daa5de3ceca3edb1527298ff467e7acaa2d25002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440481a1966e7da968b18f85fb44b787b45d29bd85b0a87c105dba0cdac32d9b80671f2cf4a9fca3647e43814ed23be55990c1f44d518a342447f3f36e3041b9302", + "signed_txn_bcs": "642f28579c0649a3ed597aa502ed2454c3755d153630812625b591cced960fb22117ec50a80d3929026f3432c2ad9899f87d7944d89790e263e918c29c5117b0fe3fea83078656fb53247461487673624b794545744a6a4851626256754f65544b68675444624a63375f436f696e20505a78486d5479456857737274454b615366475a7655594962646e486f5643740506078524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad684a04025a371045496a69505261774b654a794b71624a000607b0d38910a88c19d80463a7cb589605ecfc3048baf2edccacddbfe85b751f558210674c4a677a414c645a41446b62755a6e097345666c6f6b4f62390006074d8368d70bfa74bcfaca9d4f1bf772ea9dbfe24ae6d2897e589292fd77bd360f03527039094a575a66464154417200075397093bbc857502123f53ec878f4a16654783b27af4fd15f3026efeb92e3ead0a417948766b494f506d34076c7974586b773800079e923412ce21c119267695ffb89190d246e4cacacbbd052bfc0760e48a8326f7136972724676774c4b694d68624f6e68534e55661a44675a49467370494f45574848784c434864774356695566736e000201ef10580431c60c33522e7170b1d04fb2a2707bf1180b69479e3b7bb7a094776beb83dfde5802228de47763002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406fc084fd834622c26a3d443ae3e7ab419c027d5806daef62f2e4258bf8020335f2272dfd2fdc04ced2f9628676346da41f821c2ec69a209e0728f986ad8ab405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "704f51770a300c83fe50b15ccd55c033e3a586cceab9cc10fa1d666c7f32db1b", - "sequence_number": "4434821165149788175", + "sender": "d6abf9249bde4e56b4cec4d00f568aa20795a8149a0ba73db571bfb0cd1e6075", + "sequence_number": "13222762460728728129", "payload": { "EntryFunction": { "module": { - "address": "bde8beb96188d747ecb0af757b2577c913940e16e53c26c13c601721b758a65d", - "name": "ZKaRPFOjxMivEpQbtxVRfxW2_Coin" + "address": "2c630a955cba95a21eb61038b56106b8df47c2196b5c4e502299241e2d65c8be", + "name": "LxTTExbO7_Coin" }, - "function": "JY5", + "function": "NcxVvufsoPehPSva2", "ty_args": [ { - "struct": { - "address": "57a14f62ee36bc620168d62da4eb73024a45c42dbd087a0be10535ede468b307", - "module": "SrZWYwEFwVWiTwAAwROlmPTYwDObVs7", - "name": "lwMlDaEdfRgtSmrtkmJvdVpewARsuVkV5", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "00c3a4c06c54f0a31617f12d32baec31dec3d03c66b949dd8e37d8cdd9d1ebcd", + "module": "fuJyeiWMhuesjtdiV2", + "name": "TApgwnnSxXQZxiQRCeWlAROBelSEgo", + "type_args": [] + } + } } }, { "struct": { - "address": "d9d1ebcd76d8e5b13e11a7eaaa3df42e3ea81b61d6b55c245f56b1e0344e5f06", - "module": "MinJJnnfHqvQUnexmWTtMfMxBYRgTa5", - "name": "Daf7", + "address": "4f8641bc3f8e01a399e35f2a9b4151c845f0ca0220a3124fd5c9409e5fd961bb", + "module": "glgx", + "name": "tUwhrSAUntgaWp", "type_args": [] } }, { "vector": { "struct": { - "address": "de2fac53cd494b87683944d14cf0994a93163142d24e60d61d85e76c98db2b7b", - "module": "xzH7", - "name": "yJLKbKYiTHPUNWDfheQHONmhtKbcle", + "address": "4ca95b62c0fc80f43412f7e082c40cd2aa7c408f926d1e7ef8dc4ce199fa5694", + "module": "ukJNMzpHalbPBCsBwbSpaEkFi", + "name": "ngtUCxUeCgcjcNOO9", "type_args": [] } } }, { "struct": { - "address": "913b2a61dcf07f2e9f382ae0abfe0349f368f56421678c2169ec153159dc9150", - "module": "GyAGzKPPvymNiOyPsePMGSdzoXnIc7", - "name": "zWlugnLdyrqnbsEKszBDzbxSdvLUQyZK", + "address": "fe0349f368f56421678c2169ec153159dc9150cb25cbe8447f356053d3ce299e", + "module": "xDJfCWn5", + "name": "kDranhwTsrWcNvqiGKO3", "type_args": [] } }, - { - "vector": { - "vector": { - "struct": { - "address": "b1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6c70cb2bd1b7c6e", - "module": "wshhbiieZcZNf", - "name": "XRFcPMRJTEWiET", - "type_args": [] - } - } - } - }, { "struct": { - "address": "74558aa16f49aeb9b8cc113c018b31479490672bc91a9723623bdec5776b5ae2", - "module": "RLhRpqAghBDVLeDPjm4", - "name": "YfDCifzaoCdBmXPjJHEP1", + "address": "bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e4", + "module": "NLZHfRRePhLtpH8", + "name": "InKOUtWKttONPLxDpORUygBjUfAZUzv", "type_args": [] } } ], "args": [ - "75692ee9fefe7a9f77058da16c81e6c16307d59c506402ea361fb4307c39d20a", - "835ace4377243888ca8798edddbdc0dd675432973c495ee30a08eb4e1f3d0f8b" + "652280867781bdb1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6", + "b2", + "dac7c103c53063b5", + "41dc98024cea4802", + "e94edfe097af53bb075f8c06a2859b62", + "a813eadeec031b091c6029872550a277", + "b2af9c477adcae21" ] } }, - "max_gas_amount": "16215824449604551441", - "gas_unit_price": "16193022985363382274", - "expiration_timestamp_secs": "2852043486238873068", - "chain_id": 170 + "max_gas_amount": "7339992893755117158", + "gas_unit_price": "17475894077085177983", + "expiration_timestamp_secs": "8199206587883525069", + "chain_id": 82 }, - "signed_txn_bcs": "704f51770a300c83fe50b15ccd55c033e3a586cceab9cc10fa1d666c7f32db1b0f18235f5aa68b3d02bde8beb96188d747ecb0af757b2577c913940e16e53c26c13c601721b758a65d1d5a4b615250464f6a784d69764570516274785652667857325f436f696e034a5935060757a14f62ee36bc620168d62da4eb73024a45c42dbd087a0be10535ede468b3071f53725a5759774546775657695477414177524f6c6d50545977444f62567337216c774d6c4461456466526774536d72746b6d4a76645670657741527375566b56350007d9d1ebcd76d8e5b13e11a7eaaa3df42e3ea81b61d6b55c245f56b1e0344e5f061f4d696e4a4a6e6e6648717651556e65786d5754744d664d78425952675461350444616637000607de2fac53cd494b87683944d14cf0994a93163142d24e60d61d85e76c98db2b7b04787a48371e794a4c4b624b5969544850554e574466686551484f4e6d68744b62636c650007913b2a61dcf07f2e9f382ae0abfe0349f368f56421678c2169ec153159dc91501e477941477a4b505076796d4e694f79507365504d4753647a6f586e496337207a576c75676e4c647972716e6273454b737a42447a62785364764c5551795a4b00060607b1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6c70cb2bd1b7c6e0d77736868626969655a635a4e660e58524663504d524a544557694554000774558aa16f49aeb9b8cc113c018b31479490672bc91a9723623bdec5776b5ae213524c685270714167684244564c6544506a6d34155966444369667a616f4364426d58506a4a4845503100022075692ee9fefe7a9f77058da16c81e6c16307d59c506402ea361fb4307c39d20a20835ace4377243888ca8798edddbdc0dd675432973c495ee30a08eb4e1f3d0f8b1103c6fa6b2e0ae102e051629c2cb9e0ec153ca1707e9427aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444045c90dcd4614d30a285f323327fcd9a18cfb96e8d4b51baf408cb88869c161ee5c27bff1ab8e6f3d02ab83a89b805ecd6354913864f63eccea84193b019e6506", + "signed_txn_bcs": "d6abf9249bde4e56b4cec4d00f568aa20795a8149a0ba73db571bfb0cd1e6075411a1b9d66b080b7022c630a955cba95a21eb61038b56106b8df47c2196b5c4e502299241e2d65c8be0e4c7854544578624f375f436f696e114e637856767566736f50656850537661320506060700c3a4c06c54f0a31617f12d32baec31dec3d03c66b949dd8e37d8cdd9d1ebcd1266754a796569574d687565736a74646956321e54417067776e6e537858515a786951524365576c41524f42656c5345676f00074f8641bc3f8e01a399e35f2a9b4151c845f0ca0220a3124fd5c9409e5fd961bb04676c67780e74557768725341556e74676157700006074ca95b62c0fc80f43412f7e082c40cd2aa7c408f926d1e7ef8dc4ce199fa569419756b4a4e4d7a7048616c6250424373427762537061456b4669116e677455437855654367636a634e4f4f390007fe0349f368f56421678c2169ec153159dc9150cb25cbe8447f356053d3ce299e0878444a6643576e35146b4472616e687754737257634e767169474b4f330007bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e40f4e4c5a486652526550684c747048381f496e4b4f5574574b74744f4e504c7844704f52557967426a5566415a557a76000720652280867781bdb1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab601b208dac7c103c53063b50841dc98024cea480210e94edfe097af53bb075f8c06a2859b6210a813eadeec031b091c6029872550a27708b2af9c477adcae21664e2adea5e4dc657fd8036512d986f2cd13d74ef36ec97152002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402cd91424e3bd8bed85d9b48a3d89d25357bfeaa626a907e41ed1c30b81a53d94191d06c521cb5177c564fe167869a4b02cfc5b09aaea6cccd102e1423a677901", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e0300fb2af98c1dbb89453f572246c816d9926c0c170672f88ecf7f31ba0e902", - "sequence_number": "2800249294766190279", + "sender": "5e79d29c30b86f11de5beb4f3bb607714c2a21e0cc4b02346843af75a4863362", + "sequence_number": "15143935663759118013", "payload": { "EntryFunction": { "module": { - "address": "f906305b488331f285d09953fd6ef35cc4d9683003f506b403bbe344eb5519a8", - "name": "AmBdyexJfwAuOKmRm_Coin" + "address": "3de48f82cce202873abe314abc5543556974558aa16f49aeb9b8cc113c018b31", + "name": "kySktHTTpomZIdNCTMhuBDhVGmmDc1_Coin" }, - "function": "rAZTBSYwhW", + "function": "DufPMUmAjkLDgsQQTUAM", "ty_args": [ + { + "vector": { + "vector": "address" + } + }, + { + "vector": { + "vector": "u64" + } + }, { "vector": { "struct": { - "address": "5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418ae1ca", - "module": "kFEKnJFyHGWqQZyNGBRPQvgnQ", - "name": "XKcSYVvIMHVQ", + "address": "db1b0f5aec70116b029caaf906305b488331f285d09953fd6ef35cc4d9683003", + "module": "TlqHpdRBxKwNyp2", + "name": "qswlZASFrnGLW", "type_args": [] } } }, { - "struct": { - "address": "1772f0c9bb1b59bfda6b1b5c405ef1cd6a3e4454035f57e6296d6092272454fe", - "module": "awrgqyMbDRXub", - "name": "PQpkcTBppS0", - "type_args": [] + "vector": { + "vector": "u128" } }, { - "struct": { - "address": "0b0933907b4ea015643fa122cfac9af2f0584c678da4d25a5ee0158accc51997", - "module": "BNDhjidqQiiWbAjFlvsQW", - "name": "hvQHHfSExiZxe3", - "type_args": [] + "vector": { + "struct": { + "address": "126f2a252d7872294e78ffc2760592e4fa9a35951df075e4d4735b078eb6c63d", + "module": "RHHlkQEwokfGi1", + "name": "GPFZkZQoAtKgd0", + "type_args": [] + } } }, { - "struct": { - "address": "d9d02cbf25f43f1ff402c455ab14e383153bfe88eee765114ffbedc850b7719e", - "module": "peQQbZyd", - "name": "wc", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "e2232ae0791a71cf38efea7bc3705a4d8db86d88bc066331c43d99a26ba93de1", + "module": "WFmFlvJTOIalqUrtmnQjMpX", + "name": "WINuEkKhwftjGRrttBfnHKnJviJXNCFD", + "type_args": [] + } + } } }, { "struct": { - "address": "5b283e633761df652f3ed47396b9f9d94d0d29423b248cb224522d0075d49671", - "module": "TkOJHvpvfBzSsioaMuR", - "name": "aQav5", + "address": "158accc51997b45901533466f6db3ea35a538f87fd286906db6ac1a02d88445d", + "module": "MgBZTfhbMSpiWqpLR0", + "name": "KxSFmIwijQFjkhLWIBWDhayQmgKBoG", "type_args": [] } } ], "args": [ - "49cd22ca28a067a96dab0e11efd4648433b61a7b2121256ab3ee708081f028da", - "0d" + "71e424cbef1f2ac9", + "01", + "01" ] } }, - "max_gas_amount": "18412968427985577241", - "gas_unit_price": "7802961839568221912", - "expiration_timestamp_secs": "15214679683176441959", - "chain_id": 176 + "max_gas_amount": "15795417235777155219", + "gas_unit_price": "9932769222204044383", + "expiration_timestamp_secs": "11099530764670004767", + "chain_id": 162 }, - "signed_txn_bcs": "e0300fb2af98c1dbb89453f572246c816d9926c0c170672f88ecf7f31ba0e902c7ae13b1e57bdc2602f906305b488331f285d09953fd6ef35cc4d9683003f506b403bbe344eb5519a816416d42647965784a667741754f4b6d526d5f436f696e0a72415a544253597768570506075dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418ae1ca196b46454b6e4a467948475771515a794e474252505176676e510c584b6353595676494d48565100071772f0c9bb1b59bfda6b1b5c405ef1cd6a3e4454035f57e6296d6092272454fe0d6177726771794d6244525875620b5051706b6354427070533000070b0933907b4ea015643fa122cfac9af2f0584c678da4d25a5ee0158accc5199715424e44686a6964715169695762416a466c767351570e687651484866534578695a7865330007d9d02cbf25f43f1ff402c455ab14e383153bfe88eee765114ffbedc850b7719e0870655151625a796402776300075b283e633761df652f3ed47396b9f9d94d0d29423b248cb224522d0075d4967113546b4f4a4876707666427a5373696f614d755205615161763500022049cd22ca28a067a96dab0e11efd4648433b61a7b2121256ab3ee708081f028da010d192590aa3a0188ffd876648373b0496c67a8159f8f6625d3b0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f1e77c1f811d31555b82ed431c20bbbcdd361c9d92902b85f9eded96a4491511d09839f5862436018c3ac2fd0497e715851356ef0eeb8721e3e0bef386fbb701", + "signed_txn_bcs": "5e79d29c30b86f11de5beb4f3bb607714c2a21e0cc4b02346843af75a4863362bd4ebb0b40112ad2023de48f82cce202873abe314abc5543556974558aa16f49aeb9b8cc113c018b31236b79536b74485454706f6d5a49644e43544d687542446856476d6d4463315f436f696e14447566504d556d416a6b4c44677351515455414d070606040606020607db1b0f5aec70116b029caaf906305b488331f285d09953fd6ef35cc4d96830030f546c714870645242784b774e7970320d7173776c5a415346726e474c57000606030607126f2a252d7872294e78ffc2760592e4fa9a35951df075e4d4735b078eb6c63d0e5248486c6b5145776f6b664769310e4750465a6b5a516f41744b67643000060607e2232ae0791a71cf38efea7bc3705a4d8db86d88bc066331c43d99a26ba93de11757466d466c764a544f49616c715572746d6e516a4d70582057494e75456b4b687766746a475272747442666e484b6e4a76694a584e4346440007158accc51997b45901533466f6db3ea35a538f87fd286906db6ac1a02d88445d124d67425a546668624d5370695771704c52301e4b7853466d4977696a51466a6b684c5749425744686179516d674b426f4700030871e424cbef1f2ac901010101937094c9499834db5fb46745fb48d8891feeac316c74099aa2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444068b6dda6e327631130de78cd5c8f7418a200d1e1c17369d78fdfaa1f2d8e584015b6b174bf940ec582be0dd75f57422ca61858ba2762ae1acb8cea21beab000d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "869602f21b32d569f970326578744fbbf91d0ae97405c80e0b4d4e086dccd2ac", - "sequence_number": "8350752623996713121", + "sender": "fe634b80b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13", + "sequence_number": "27535578183918161", "payload": { "EntryFunction": { "module": { - "address": "00a3546eaf81a8f71935070e2c793ca6b787c7feea37696085fe634b80b5a38c", - "name": "HUpTFwMnzORtQRUQTkd_Coin" + "address": "d839b79d2b2ec04bef47c0c3eb146c0d9e2abe5b283e633761df652f3ed47396", + "name": "TKUlPeqjlhAQQOwRKFSQBSrSGkoHrt_Coin" }, - "function": "ZPPFbPSoOQuHEpMi", - "ty_args": [ - { - "vector": "bool" - } - ], + "function": "AtyznraCAsVQBcNxKANz8", + "ty_args": [], "args": [ - "01", - "ab9533566138687cd2ec256d2ae4c8d26b638181c61e938ab4da5b889d476fd7", - "b1", - "71a0238457393917", - "00", - "66c8b519ebfad31f91663851eac37ac4", - "73d66f19a98c3792f8367fdaf79df359f3653cee651aa78d62ea7ad9d1869028", - "df75e81533e5de25bab636d1afa18a9317c782a435b32c7a37db4e321d377329" + "eb87f1f938d141a4", + "678f193ad873b000a3546eaf81a8f71935070e2c793ca6b787c7feea37696085" ] } }, - "max_gas_amount": "9062239492371603291", - "gas_unit_price": "13296775297672042174", - "expiration_timestamp_secs": "14626097145987141461", - "chain_id": 232 + "max_gas_amount": "11764068562823368243", + "gas_unit_price": "5707241498503189844", + "expiration_timestamp_secs": "15668928689916847975", + "chain_id": 182 }, - "signed_txn_bcs": "869602f21b32d569f970326578744fbbf91d0ae97405c80e0b4d4e086dccd2aca1387c7044d5e3730200a3546eaf81a8f71935070e2c793ca6b787c7feea37696085fe634b80b5a38c184855705446774d6e7a4f527451525551546b645f436f696e105a5050466250536f4f51754845704d6901060008010120ab9533566138687cd2ec256d2ae4c8d26b638181c61e938ab4da5b889d476fd701b10871a023845739391701001066c8b519ebfad31f91663851eac37ac42073d66f19a98c3792f8367fdaf79df359f3653cee651aa78d62ea7ad9d186902820df75e81533e5de25bab636d1afa18a9317c782a435b32c7a37db4e321d3773295b5f53f4cd8ac37dbe56ee13afa287b8550feba4dc55facae8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444078a8599f483d6c6c7558e8789fb25c8ccb94720b6b59cede9b98045b429b53611a68de7f8776d44ceee5e0dedb35719a03c2935ed28f3f432778aceae6c7d00d", + "signed_txn_bcs": "fe634b80b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb135162566476d3610002d839b79d2b2ec04bef47c0c3eb146c0d9e2abe5b283e633761df652f3ed4739623544b556c5065716a6c684151514f77524b46535142537253476b6f4872745f436f696e154174797a6e7261434173565142634e784b414e7a38000208eb87f1f938d141a420678f193ad873b000a3546eaf81a8f71935070e2c793ca6b787c7feea37696085334e6d78075e42a35495a695e731344f67a76b3da03773d9b6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406d1e38827468500143680a42a66bb990a266aab9cc068a38bc364caaac7c0a14f38a114fbce3cbc1eb7ce8e2ea3c738b550a3a15121b97582cf427aaf4d75f05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f4b516580e09ea7a7533ec76f633cb0fc67095461c81c4afee376affb68b39d1", - "sequence_number": "3101801249685340521", + "sender": "b9df74919d57cb7274d4b7011b69f0b6ba9d6c8a63a321ce1a269a4c190b31f6", + "sequence_number": "9616022168444437854", "payload": { "EntryFunction": { "module": { - "address": "913b28cd8ea64e1bbc713e03234ed8745cdf039e53c4b83c81fef0683dae4335", - "name": "hJghrBITptkgZgSeNDhJXnikQNweC_Coin" + "address": "4300619d934cd884e787074355e028ca8f56a0cd85309acb6db3f7b35db5d3d3", + "name": "LecmGTyHbJWi_Coin" }, - "function": "pVrwwnvVSzShlZHOeHNtdcNKMfAmv", + "function": "pjDk7", "ty_args": [ - { - "struct": { - "address": "8dfa75730167c36a39f323f737f8ec2d5e3b7b92c22ba775cd0ed282425a4114", - "module": "aaoiMOzhTnXZu", - "name": "UdBwkog", - "type_args": [] - } - }, - { - "struct": { - "address": "7a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab6c77ac13b478", - "module": "XKAzVbammgZWESzMxvO", - "name": "zoQSGjCbWIaSMpODr", - "type_args": [] - } - }, { "vector": { - "vector": "u8" + "struct": { + "address": "e8bff30aff52d07a52e23b1f04281f78eafacfd5371908a8b297555c03e3e444", + "module": "VUQFjJGRwWVKMAKiia4", + "name": "GsSXHHWeWFRDTnsCrbLzGPUGKM", + "type_args": [] + } } }, { - "struct": { - "address": "d89ee75cb1113d12b0f10abefe68c669fe561f3e610e0b0bf3ab120bbc793fe4", - "module": "O7", - "name": "nmLhEAddkPMYftzVwZOoFZhcGZhsZWut1", - "type_args": [] + "vector": { + "vector": "bool" } }, { "struct": { - "address": "771475ef01439c5dc2346154796f08328ac34bfa0b2b25f14a76c094729d60e7", - "module": "BWDIdZVJLhOjgknllbqkA1", - "name": "KxjmoKRjVnjxQcZOBZDhKjL6", + "address": "200ff188fc76f05eed82f4d6215934c94871573df05b744f3c8129e219e68e40", + "module": "ltdN", + "name": "ImuPuVYLzQyVLOGi1", "type_args": [] } }, { "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "u128" + "struct": { + "address": "82614bede62d772a15ad3276e1e6330af7471bd683b53b11b156f597a997b9f1", + "module": "jVuxYTorwNFAJkTdrDIeSFJw6", + "name": "KnPPVcGBxXCDFhBBXrJ", + "type_args": [] + } } } ], "args": [ - "cbb8890c6ce701f0", - "ce476d520350064dbf8019737d70589329bfe130eae8e7d350e848da297a063b", - "fcf6c9fd6adfc9fff84055c2d42a86d4856652e338711bfb9d04db013c74ee9e", - "01", - "6d9d404a4555ce7244ff5cc70e483838af6f43d6e0f4518c42ce14e8872f3787", - "c9020388386b41ca", - "00" + "ae4056b643fce7f73556d67c10933f28", + "21", + "aa083b1e189ed680472641a6723f8b75", + "a3f8f3ba9107e79c", + "b3df80b7bfcac661", + "678b40c8f70ec02b722fcb236a90d3a6", + "c7bf8e6029c234f7ac4a36fcb988247dcfec2f200105fd8720fd3c009e865a99" ] } }, - "max_gas_amount": "1867025542719666117", - "gas_unit_price": "14061964006813278264", - "expiration_timestamp_secs": "12115124549471106767", - "chain_id": 209 + "max_gas_amount": "13653972913826495318", + "gas_unit_price": "11631731741450810283", + "expiration_timestamp_secs": "1420956246263986001", + "chain_id": 136 }, - "signed_txn_bcs": "f4b516580e09ea7a7533ec76f633cb0fc67095461c81c4afee376affb68b39d169815b73cdcf0b2b02913b28cd8ea64e1bbc713e03234ed8745cdf039e53c4b83c81fef0683dae433522684a67687242495470746b675a6753654e44684a586e696b514e7765435f436f696e1d70567277776e7656537a53686c5a484f65484e7464634e4b4d66416d7607078dfa75730167c36a39f323f737f8ec2d5e3b7b92c22ba775cd0ed282425a41140d61616f694d4f7a68546e585a7507556442776b6f6700077a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab6c77ac13b47813584b417a5662616d6d675a5745537a4d78764f117a6f5153476a4362574961534d704f44720006060107d89ee75cb1113d12b0f10abefe68c669fe561f3e610e0b0bf3ab120bbc793fe4024f37216e6d4c68454164646b504d5966747a56775a4f6f465a6863475a68735a577574310007771475ef01439c5dc2346154796f08328ac34bfa0b2b25f14a76c094729d60e71642574449645a564a4c684f6a676b6e6c6c62716b4131184b786a6d6f4b526a566e6a7851635a4f425a44684b6a4c36000606050606030708cbb8890c6ce701f020ce476d520350064dbf8019737d70589329bfe130eae8e7d350e848da297a063b20fcf6c9fd6adfc9fff84055c2d42a86d4856652e338711bfb9d04db013c74ee9e0101206d9d404a4555ce7244ff5cc70e483838af6f43d6e0f4518c42ce14e8872f378708c9020388386b41ca0100c5f762d4d601e91938206fbec22126c3cff6d6cc969121a8d1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444052ad9888ba9ece92dedb09df12681630e6fcbea135b4d50f08c0e962f414e69d725cf6b0b8e8b1a53039b829fd1f46f69aa4a8ccef4fda0646421eb5b1bd1907", + "signed_txn_bcs": "b9df74919d57cb7274d4b7011b69f0b6ba9d6c8a63a321ce1a269a4c190b31f65e8569de36f97285024300619d934cd884e787074355e028ca8f56a0cd85309acb6db3f7b35db5d3d3114c65636d47547948624a57695f436f696e05706a446b37040607e8bff30aff52d07a52e23b1f04281f78eafacfd5371908a8b297555c03e3e44413565551466a4a47527757564b4d414b696961341a477353584848576557465244546e734372624c7a475055474b4d0006060007200ff188fc76f05eed82f4d6215934c94871573df05b744f3c8129e219e68e40046c74644e11496d75507556594c7a5179564c4f47693100060782614bede62d772a15ad3276e1e6330af7471bd683b53b11b156f597a997b9f1196a56757859546f72774e46414a6b54647244496553464a7736134b6e505056634742785843444668424258724a000710ae4056b643fce7f73556d67c10933f28012110aa083b1e189ed680472641a6723f8b7508a3f8f3ba9107e79c08b3df80b7bfcac66110678b40c8f70ec02b722fcb236a90d3a620c7bf8e6029c234f7ac4a36fcb988247dcfec2f200105fd8720fd3c009e865a9956fb6ef505a87cbdabb3cf2b64366ca151f7ef6b2d40b81388002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444062eda0fc0c0081f975945675eb553ab5e20f06a4d555255f6e5c4c3d0d8c4565913e7adaaa79056bcb3d8f7825b83960520f8d17c6aff56109c36c40b96aee01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "60039e095c21c6280afc95d28b441cd480945a7307363a4cfef06efba7774cfa", - "sequence_number": "12440803281185121067", + "sender": "4a995849ef5ef9d1a80c2e9c22816f97cc667f74ad4031f2a81391a1c66bd1d4", + "sequence_number": "15718082279670922044", "payload": { "EntryFunction": { "module": { - "address": "81f7fb5abab5c7567fc9d994cd9e21ba7bf8881025d68fd028648c76196f4142", - "name": "YDcedzcSYyKigPyLLbPAhDZMWlrgC8_Coin" + "address": "b80d093eded486b86cc1e7875f023b19d67332c261296604a38a2f720110aeab", + "name": "RWWlkgaSEOnKhgStfdmVq_Coin" }, - "function": "pjinIUtfwvwEZhrbPZjpHlThRXGlxM", + "function": "TsLmCYabR3", "ty_args": [ { - "struct": { - "address": "adef5785329d5000b459bb4f9f289e1698e24ce1d81977af63a7ba1f38d758b3", - "module": "IiPGdvtAReXjMVJcyQK", - "name": "aXQwpg", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } + } + }, + { + "vector": { + "vector": "u64" } }, { "struct": { - "address": "89977a05a56e353f5c49bebd0767eecf42094a2332e57b3ae000fd93046eb930", - "module": "OzGcx2", - "name": "abuUPvEcp", + "address": "4decb8fbefcb92d45325dc39c48042b94abe3b4fe6e945dfc15364f91c34b224", + "module": "uOIOe0", + "name": "bEeedDrIlKjgamT3", "type_args": [] } }, { "struct": { - "address": "4a923956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb6237", - "module": "BcrKctQmOuuHPSYvhFoUBQS2", - "name": "zJRQEbVPqn", + "address": "322cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375", + "module": "ffAwanSurjHHeqTzcPYNQrrOGRJuWEFE", + "name": "dff4", "type_args": [] } }, { "vector": { "vector": { - "vector": "u128" + "struct": { + "address": "b58df2df1704d6f6ab4524eb676406204c1839bfaaf5d0d6819f2ec0e9c731f4", + "module": "ZjXlEltbvwWmFiGssdOy9", + "name": "ubpuihlNulpADSwxUjoVbD7", + "type_args": [] + } } } - } - ], - "args": [ - "56040f81dc0e9932e67bee8d093ff7dc", - "f491c95dc30e94c0" - ] - } - }, - "max_gas_amount": "6410391226991906913", - "gas_unit_price": "14708646698958368515", - "expiration_timestamp_secs": "12012681263968585384", - "chain_id": 121 - }, - "signed_txn_bcs": "60039e095c21c6280afc95d28b441cd480945a7307363a4cfef06efba7774cfa2ba38d87ab9ca6ac0281f7fb5abab5c7567fc9d994cd9e21ba7bf8881025d68fd028648c76196f41422359446365647a635359794b696750794c4c62504168445a4d576c726743385f436f696e1e706a696e49557466777677455a687262505a6a70486c54685258476c784d0407adef5785329d5000b459bb4f9f289e1698e24ce1d81977af63a7ba1f38d758b31349695047647674415265586a4d564a6379514b06615851777067000789977a05a56e353f5c49bebd0767eecf42094a2332e57b3ae000fd93046eb930064f7a476378320961627555507645637000074a923956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb6237184263724b6374516d4f7575485053597668466f55425153320a7a4a525145625650716e0006060603021056040f81dc0e9932e67bee8d093ff7dc08f491c95dc30e94c061102274db48f65803af22323e9c1fcca886d6b2f69db5a679002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402a31220115b1dd5456964c19fa097659f84ce1e8cf7d04e79bb7a063f30b68691a3e4c2202957a61d89fdba3f9fdfd8e8e6f2d28c51a73bf714f3deb81a9350e", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "2840b829b1a82bf4a695cc253e384d14048acfe2855afc520f2b57678e25e48e", - "sequence_number": "5518872340837970104", - "payload": { - "EntryFunction": { - "module": { - "address": "ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b3885e58e3", - "name": "XnLdNotwOwWDqrgNlqOwEezpE_Coin" - }, - "function": "NUJIkVqRpFXDWlHxPbubCEtDp", - "ty_args": [ + }, { "struct": { - "address": "5d5b79470e757f5224f9c2ff40f91caa1009f930d6736514c58d53153bbc973b", - "module": "RQpSnDenchvDCyZtsKcxZssGNISZbX", - "name": "OlEwdUQysf4", + "address": "6735aa9261726c014632c1efde48963fd944940c234b265572e17940b1657978", + "module": "vOSjEtxJzWtHzBFevVQeZNmG", + "name": "QsouQERjVhLXBvCMchEDdfEIzpM", "type_args": [] } }, { "vector": { - "vector": "u128" - } - }, + "struct": { + "address": "6fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f", + "module": "RxONPUYsUR9", + "name": "frRfxRlVctBbMmUZEmjzAeaMCIlpErAJ1", + "type_args": [] + } + } + }, + { + "struct": { + "address": "2bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db", + "module": "eFHXEusORmvUSIclJW", + "name": "woItodFBReSjBgTuVwDxpVCo7", + "type_args": [] + } + }, + { + "struct": { + "address": "856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a", + "module": "j5", + "name": "MQaSdweM", + "type_args": [] + } + }, { "struct": { - "address": "d8c1617de732983c3d9479394b5b84d9ce9da78a9d400baa332193566ba76dbc", - "module": "SYDhBwdHCtxdPhITtkKOlz8", - "name": "iQMG3", + "address": "400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef", + "module": "lJuuIKvao", + "name": "qGglBigfJIEqljouDsqIQElwey4", "type_args": [] } } ], "args": [ - "01", - "01", - "c3fef31a3ca1e14970535ada4446d54f" + "1674a6fad1b08e55450decb9019b656fe3d9878ab27eb6511ee0c3d39d72849d", + "de5212c84e586b50934f62135a912066", + "99", + "2febe15981188fd6ca1d04f8305bdb99" ] } }, - "max_gas_amount": "1219951378163840144", - "gas_unit_price": "3798051916844728159", - "expiration_timestamp_secs": "15549149336408166729", - "chain_id": 165 + "max_gas_amount": "10100996247913873977", + "gas_unit_price": "11303796198471544444", + "expiration_timestamp_secs": "10519654434661632759", + "chain_id": 45 }, - "signed_txn_bcs": "2840b829b1a82bf4a695cc253e384d14048acfe2855afc520f2b57678e25e48eb830605c27f9964c02ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b3885e58e31e586e4c644e6f74774f7757447172674e6c714f7745657a70455f436f696e194e554a496b56715270465844576c487850627562434574447003075d5b79470e757f5224f9c2ff40f91caa1009f930d6736514c58d53153bbc973b1e525170536e44656e6368764443795a74734b63785a7373474e49535a62580b4f6c4577645551797366340006060307d8c1617de732983c3d9479394b5b84d9ce9da78a9d400baa332193566ba76dbc1753594468427764484374786450684954746b4b4f6c7a380569514d473300030101010110c3fef31a3ca1e14970535ada4446d54f9034b49a5023ee105f7f056e1864b53449111c44f0acc9d7a5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3c115ea61385c9e63fd6967f8c7c9b4111b479b45ca6ea39911d26f1fad22d2c68d4b51d4409bf900635ab5df3d8046569b22c93a9228c480e66640fec35009", + "signed_txn_bcs": "4a995849ef5ef9d1a80c2e9c22816f97cc667f74ad4031f2a81391a1c66bd1d43cbb252e8ed821da02b80d093eded486b86cc1e7875f023b19d67332c261296604a38a2f720110aeab1a5257576c6b676153454f6e4b6867537466646d56715f436f696e0a54734c6d4359616252330a06060605060602074decb8fbefcb92d45325dc39c48042b94abe3b4fe6e945dfc15364f91c34b22406754f494f65301062456565644472496c4b6a67616d54330007322cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe09943752066664177616e5375726a48486571547a6350594e5172724f47524a7557454645046466663400060607b58df2df1704d6f6ab4524eb676406204c1839bfaaf5d0d6819f2ec0e9c731f4155a6a586c456c74627677576d4669477373644f7939177562707569686c4e756c704144537778556a6f5662443700076735aa9261726c014632c1efde48963fd944940c234b265572e17940b165797818764f536a4574784a7a5774487a424665765651655a4e6d471b51736f755145526a56684c584276434d63684544646645497a704d0006076fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f0b52784f4e50555973555239216672526678526c56637442624d6d555a456d6a7a4165614d43496c704572414a3100072bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db12654648584575734f526d76555349636c4a5719776f49746f6446425265536a42675475567744787056436f370007856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a026a35084d5161536477654d0007400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef096c4a7575494b76616f1b7147676c426967664a4945716c6a6f754473714951456c776579340004201674a6fad1b08e55450decb9019b656fe3d9878ab27eb6511ee0c3d39d72849d10de5212c84e586b50934f62135a9120660199102febe15981188fd6ca1d04f8305bdb9939c275f291f22d8c7cae4e9fc026df9cf78ade09f951fd912d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e859e35d5c29a853611492f919bd0b80d54127ca7d882614d74960b5cf3c84f0e7ddd8ced0e512bcf09ba34541370f001eb49b54b9e259d6bf093725953d650f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "37add42d66e8b62e0b77cad2f9127da9886c6d9a28f21a73f132251fc53c11a5", - "sequence_number": "16403975168816619338", + "sender": "5d5d82a19a55bc6c805e2264584b01a36d42be537d15d1b3ca6cbefc6ac953d6", + "sequence_number": "9177619198438643909", "payload": { "EntryFunction": { "module": { - "address": "d184c931a465098e3666deb2a80104a2e1097b98f9c85c7800d53093cb5f5eaa", - "name": "EDzoghCKNj_Coin" + "address": "345b9925c0f1f779ae7cf564bb4dfca6afdfe7b9f4905117f0b0b154fd03336c", + "name": "exyqp_Coin" }, - "function": "LQgqLzCSetg", + "function": "XXSimzqLTEUkmonKS5", "ty_args": [ + { + "vector": "u128" + }, + { + "vector": { + "vector": { + "struct": { + "address": "38d758b39c63f8e4b79d10b3c41862018b1739867390c1f277db7adf7dda8bf7", + "module": "ZwdjOWFwCZlqwXaStMZD", + "name": "MHZkyJRjHssrEQRwYInXINRsVDRDBod7", + "type_args": [] + } + } + } + }, + { + "struct": { + "address": "fc83510f8489c6ed603e3b28722b6718f14a988456f2484794d29f4e48229f4b", + "module": "du", + "name": "YrYaGdDabPjAZfnQUFbNccpE", + "type_args": [] + } + }, { "struct": { - "address": "b9fb1632081c3996cc6289cfbeaef045f9cb575a49f63c16b35aed2e445d388d", - "module": "iWYUvDjwpOrxsQF", - "name": "rkUyDxChRFfNAXV0", + "address": "3956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb623760eb", + "module": "IMZtZrfDTzR", + "name": "wyCuCouHTwNwwzpSwhWZ0", + "type_args": [] + } + }, + { + "struct": { + "address": "c36e662e3004ebf52b8f38afc1e756f4f0b067be87c789681ade14dfc1c4c60b", + "module": "cKhlFCvn", + "name": "AsiZfBehGDsuNy6", + "type_args": [] + } + }, + { + "struct": { + "address": "a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df536944", + "module": "EBPb", + "name": "dOuHUjejEpWS", "type_args": [] } } ], "args": [ - "0a9ba1be69471b779dc158aef22778feee6d44acba431b06530c9a23265948f7", - "84f3d49579cd2a55d2de4b4dfb7eda93", - "0744c63a848f4b9c427942efda887555", - "332bd7399041fb9f4a0e1dadbc5b5852", - "14", - "01", - "01", - "01", + "033e79ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b388", + "e3", "00", - "8e" + "15", + "00" ] } }, - "max_gas_amount": "3836006231316372569", - "gas_unit_price": "16613171545488070686", - "expiration_timestamp_secs": "1863092544196614113", - "chain_id": 235 + "max_gas_amount": "7282141613084938976", + "gas_unit_price": "16718807614804579272", + "expiration_timestamp_secs": "9403326547462170850", + "chain_id": 129 }, - "signed_txn_bcs": "37add42d66e8b62e0b77cad2f9127da9886c6d9a28f21a73f132251fc53c11a54a9fa40981a0a6e302d184c931a465098e3666deb2a80104a2e1097b98f9c85c7800d53093cb5f5eaa0f45447a6f6768434b4e6a5f436f696e0b4c5167714c7a43536574670107b9fb1632081c3996cc6289cfbeaef045f9cb575a49f63c16b35aed2e445d388d0f6957595576446a77704f727873514610726b5579447843685246664e41585630000a200a9ba1be69471b779dc158aef22778feee6d44acba431b06530c9a23265948f71084f3d49579cd2a55d2de4b4dfb7eda93100744c63a848f4b9c427942efda88755510332bd7399041fb9f4a0e1dadbc5b585201140101010101010100018e591ccce5573b3c351e98711180d78de6e1978440cc08db19eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408ac8cddabedd81aea61bcca7fe1cbd045e4f6ab7aa02c980aab7668eaa618fc473bf2093514c2e46343f0fb600145a22d1375c040edde999545eb1ea2091ba01", + "signed_txn_bcs": "5d5d82a19a55bc6c805e2264584b01a36d42be537d15d1b3ca6cbefc6ac953d6c598bd2e09745d7f02345b9925c0f1f779ae7cf564bb4dfca6afdfe7b9f4905117f0b0b154fd03336c0a65787971705f436f696e12585853696d7a714c5445556b6d6f6e4b533506060306060738d758b39c63f8e4b79d10b3c41862018b1739867390c1f277db7adf7dda8bf7145a77646a4f574677435a6c7177586153744d5a44204d485a6b794a526a487373724551527759496e58494e527356445244426f64370007fc83510f8489c6ed603e3b28722b6718f14a988456f2484794d29f4e48229f4b02647518597259614764446162506a415a666e515546624e6363704500073956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb623760eb0b494d5a745a726644547a521577794375436f754854774e77777a70537768575a300007c36e662e3004ebf52b8f38afc1e756f4f0b067be87c789681ade14dfc1c4c60b08634b686c4643766e0f4173695a66426568474473754e79360007a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df53694404454250620c644f7548556a656a45705753000520033e79ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b38801e3010001150100e09204f4365d0f65c8d38514f22205e8e2a87b88ac537f8281002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059b81ca3d2cb40eba39363107e5d9ad1fec185d5f41952ca08a3e284657d433b034bb8e43f146d07c02e888b913033c8f10052d984a634e1a32ac646164f1706", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4e042f633cec6fa02a922b0606809cb8fc089dcc7357f8d96be5f3eed2ef1e9d", - "sequence_number": "13888642121806453276", + "sender": "7d374122ab3c356625126028df8bb1045a4d2170eb35a6d8c1617de732983c3d", + "sequence_number": "9665366335728380308", "payload": { "EntryFunction": { "module": { - "address": "b959010ed51103ab3e3af6b948c01504f6059db5807a8f230a21d419b852ad67", - "name": "HIATvkOl_Coin" + "address": "9474b931316737487845f5a0981172e44d19dc727f79c366219727fd64c5437c", + "name": "QlrnmliBiPjLojmJsTD1_Coin" }, - "function": "ZAbJLZzMd3", + "function": "gDWtGJVESwDIz", + "ty_args": [], + "args": [ + "01", + "b8399fd8c943fcacf93400278999e1b98731e913ccf7e284dd5f81266749e7b9", + "586be7fc9f4a5dea", + "0b332f0f3c31c7272d0be9687ca77173d5107e397c36813dd317e424ea642b2a", + "cb3e4fca3e2603dc", + "2f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a60a4093", + "f5", + "01" + ] + } + }, + "max_gas_amount": "13656846481406653787", + "gas_unit_price": "15188488487885098201", + "expiration_timestamp_secs": "8776315331632196665", + "chain_id": 157 + }, + "signed_txn_bcs": "7d374122ab3c356625126028df8bb1045a4d2170eb35a6d8c1617de732983c3d94e91b1979472286029474b931316737487845f5a0981172e44d19dc727f79c366219727fd64c5437c19516c726e6d6c694269506a4c6f6a6d4a735444315f436f696e0d67445774474a5645537744497a0008010120b8399fd8c943fcacf93400278999e1b98731e913ccf7e284dd5f81266749e7b908586be7fc9f4a5dea200b332f0f3c31c7272d0be9687ca77173d5107e397c36813dd317e424ea642b2a08cb3e4fca3e2603dc202f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a60a409301f501015b75498c84dd86bdd94c80c3ce59c8d2396cc0924bbccb799d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444091eb7f048cd20315353670b168b6648939e5acf5bcd46a58ad4d565b7bf6aae52004e53a51d7f26df0ac4210eaffc6db59f311ceb9b6d86a1339f0ffa6f3990c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "df595622dd8d67b873861c9498e65de471532a93c1427547a01aa93fd22c1c27", + "sequence_number": "15846156409455883481", + "payload": { + "EntryFunction": { + "module": { + "address": "a78a9d400baa332193566ba76dbc98dbc785c0a954ea1d28ae984848e10fa396", + "name": "OHRsHGxfRBFEtZB8_Coin" + }, + "function": "HVNFowSPViKSglyXtxVVeIyAGNqdBhF", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "f3a48b884c70a3617f971e6ee5a62933d2d126827ae05d4a2c9f42247c299fc6", - "module": "cUXKTnQMzasUJpeL7", - "name": "ZSQVCefFAoidhIBuwu", - "type_args": [] - } - } + "struct": { + "address": "3a561de2660667163e04f038775fc85d6a1274fdc0c229113b335c3b4acf8b27", + "module": "jVdZYJWOTfkamKghOK0", + "name": "TvNBXJnSonWtpYbxBBpLtMqqvsSKUG8", + "type_args": [] + } + }, + { + "struct": { + "address": "d1ecf71b987fafc930c171342467fcac30f6f8a0029983f8953b9ba84b334bba", + "module": "pvwyBVc", + "name": "xWJfzDakIxNWknoroUaJDQWL6", + "type_args": [] } }, { "struct": { - "address": "356213c0b09a655f85baae5533eeda9fa95355a395e688f4254d4bbb632949d7", - "module": "ZOsBnuoqrNHcyNbefUVLDlQDFqXMn2", - "name": "RXxZNhEbPie1", + "address": "86416947d913f696336de7d5348f47f478831fe111f845e69e212175ba4a873c", + "module": "RwDHVbCZ", + "name": "zKViyFyt3", + "type_args": [] + } + }, + { + "struct": { + "address": "a2025bf9ef7e001ce88ff652eedc5425b5a0032b62cd0fed195a0fac3bd1c814", + "module": "b", + "name": "Vdhv", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, { "vector": { "vector": { - "vector": "u64" + "struct": { + "address": "e52827d6c91d12c05ac75ef744f9c433a5aee1ae0477c9871e7d172df1f852f5", + "module": "Iif", + "name": "ABaFaqr5", + "type_args": [] + } } } }, { - "struct": { - "address": "713148b29ac930d83904e8ca9d5ed470578f4c1657e05a276515be46e6407959", - "module": "WYMlRyqOk2", - "name": "ysouotCjNYtCL", - "type_args": [] + "vector": { + "vector": "u128" } }, { "vector": { "struct": { - "address": "a914a1193d054f3c4d9cebf60f9d5107e954f4efe12bff09a50668369dd8e262", - "module": "uNxlvJKLxZUnw", - "name": "ezblbJXDbtvHVWUydqUamAVzpHIpCa2", + "address": "028b692f6d3819887e2e5ed14a597fd66222b8de65ebb416494c177c088a751c", + "module": "lcWdYRziqAbhXgwj6", + "name": "TSlCqBRZrSywovkOiKGmy0", "type_args": [] } } }, + { + "struct": { + "address": "91c005c79ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb", + "module": "VCtGROxPxJISxxWba", + "name": "iLdLxEueMFJ7", + "type_args": [] + } + }, { "vector": { "vector": { "struct": { - "address": "f7da95a6e1f113e5cf8d3734762969dbc4c869ff304d6b318cfa1d7b5e608d14", - "module": "mHOhNnhOGlZZoDwTO4", - "name": "eX", + "address": "99411c621754db098e1885aa7351916fc8e9ed69a523e84e354f020caab34f0b", + "module": "SWsZkbZYO", + "name": "AT4", "type_args": [] } } } } ], - "args": [] + "args": [ + "2b07aa83d3d7aa5c4a14a225ec7ff3eaa23382882d356213c0b09a655f85baae", + "ee", + "a9", + "01", + "a1aedd2078cddabd282e96226f4eeff4d22d3dc0e288a627fca776ba1b3b0962", + "01" + ] } }, - "max_gas_amount": "11292402725231183603", - "gas_unit_price": "16212609470190026335", - "expiration_timestamp_secs": "11819332509964959198", - "chain_id": 38 + "max_gas_amount": "6168383091833147914", + "gas_unit_price": "13429683339798672774", + "expiration_timestamp_secs": "4201528277634298732", + "chain_id": 241 }, - "signed_txn_bcs": "4e042f633cec6fa02a922b0606809cb8fc089dcc7357f8d96be5f3eed2ef1e9d1c1acdb26c5ebec002b959010ed51103ab3e3af6b948c01504f6059db5807a8f230a21d419b852ad670d48494154766b4f6c5f436f696e0a5a41624a4c5a7a4d643306060607f3a48b884c70a3617f971e6ee5a62933d2d126827ae05d4a2c9f42247c299fc6116355584b546e514d7a6173554a70654c37125a53515643656646416f69646849427577750007356213c0b09a655f85baae5533eeda9fa95355a395e688f4254d4bbb632949d71e5a4f73426e756f71724e4863794e62656655564c446c51444671584d6e320c5258785a4e68456250696531000606060207713148b29ac930d83904e8ca9d5ed470578f4c1657e05a276515be46e64079590a57594d6c5279714f6b320d79736f756f74436a4e5974434c000607a914a1193d054f3c4d9cebf60f9d5107e954f4efe12bff09a50668369dd8e2620d754e786c764a4b4c785a556e771f657a626c624a58446274764856575579647155616d41567a7048497043613200060607f7da95a6e1f113e5cf8d3734762969dbc4c869ff304d6b318cfa1d7b5e608d14126d484f684e6e684f476c5a5a6f4477544f340265580000f3c60eea72acb69c5f7ecf406ac2fee0defdafda4bb406a426002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444067e5d8b8d1b11febd84172aba1ae9d29cc86a1abe91031b89c01d3997eeaf68e7ca47db8e58d22fa3922af2cacb3febd6e25f3a0e9b4678e866b64f15e998a06", + "signed_txn_bcs": "df595622dd8d67b873861c9498e65de471532a93c1427547a01aa93fd22c1c27d9b4e5404cdbe8db02a78a9d400baa332193566ba76dbc98dbc785c0a954ea1d28ae984848e10fa396154f4852734847786652424645745a42385f436f696e1f48564e466f77535056694b53676c79587478565665497941474e71644268460a073a561de2660667163e04f038775fc85d6a1274fdc0c229113b335c3b4acf8b27136a56645a594a574f54666b616d4b67684f4b301f54764e42584a6e536f6e5774705962784242704c744d71717673534b5547380007d1ecf71b987fafc930c171342467fcac30f6f8a0029983f8953b9ba84b334bba07707677794256631978574a667a44616b49784e576b6e6f726f55614a4451574c36000786416947d913f696336de7d5348f47f478831fe111f845e69e212175ba4a873c08527744485662435a097a4b566979467974330007a2025bf9ef7e001ce88ff652eedc5425b5a0032b62cd0fed195a0fac3bd1c8140162045664687600060602060607e52827d6c91d12c05ac75ef744f9c433a5aee1ae0477c9871e7d172df1f852f503496966084142614661717235000606030607028b692f6d3819887e2e5ed14a597fd66222b8de65ebb416494c177c088a751c116c63576459527a69714162685867776a361654536c437142525a725379776f766b4f694b476d7930000791c005c79ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb1156437447524f7850784a495378785762610c694c644c784575654d464a370006060799411c621754db098e1885aa7351916fc8e9ed69a523e84e354f020caab34f0b095357735a6b625a594f034154340006202b07aa83d3d7aa5c4a14a225ec7ff3eaa23382882d356213c0b09a655f85baae01ee01a9010120a1aedd2078cddabd282e96226f4eeff4d22d3dc0e288a627fca776ba1b3b096201010a923d93bd7f9a558675ae12d8d15fba6cb32636b5d34e3af1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440786fc819f99727aeb242659344c088af30239750c70a71ef31a9fcc568b0e07991ea59a5c2ce32468e1cc607eb87d697e73bb3b150bbc4c76f2e97239664ac03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "da52d5ef29dcca1e8c29d754309118e9ef12f45c936abb97977b9e657372825e", - "sequence_number": "11124694569744965819", + "sender": "5d9717fdbfc27de79db2fad16ab2f3761aecfc8144bd64ad62983269ee87a696", + "sequence_number": "2218608088557949180", "payload": { "EntryFunction": { "module": { - "address": "5c4abdf5c0e0656437bca27808d69f83e56453506a29d8984ced66fb71b69d28", - "name": "SFrkc0_Coin" + "address": "f0bd53c8c3afa9aa842138ded8a060956e846d88a0030a61f91483ceb26635a7", + "name": "i7_Coin" }, - "function": "zsZChjIFj", + "function": "QASEbRGdwsPvoCp8", "ty_args": [ { "vector": { "struct": { - "address": "e69a12e79bb0f49f7e4809c262dc3300473143dfea3599347772b85acc5c8e36", - "module": "RrCskeBWWUapT7", - "name": "ymDoaXIIcSSUJpyeibZmBemcdGPR0", + "address": "fd2f959279f5d5dafa186c4021c9876b93bf1ca98dd50f80ea233ffb6038bf6b", + "module": "tsTOpsCCGZLlrsbZiur", + "name": "mKwnDaUHCfymCanaThfUyJCNnzlSnF7", "type_args": [] } } }, { - "struct": { - "address": "6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc05", - "module": "WZGhPzADKBHhzRAgyh1", - "name": "VhbVeKVOH", - "type_args": [] + "vector": { + "vector": "bool" } }, { - "vector": "address" + "vector": { + "vector": "signer" + } + }, + { + "struct": { + "address": "7d3a9af931d93a4931bcd0f5e2c594bca07d7159e0add80f09c6caff0a3aac7b", + "module": "mmd7", + "name": "ovGjOWRjhyoqiXHYJmhIGsEg6", + "type_args": [] + } }, { "struct": { - "address": "fbe869392bbc47ccc39856cb4eb89a389d108405d1f020719f118a0f643c214e", - "module": "KBKQPneDvJIYMNiiAnztyFGdShY5", - "name": "Gfi2", + "address": "dc750532f3b61399b2121858a54e26a2887082647f6247303afb3e104b4e6656", + "module": "zUjQDYQXMHaPDhvmWH3", + "name": "TFRdHzlVSZwqqHDMQmxvJaVfvlKCZgZ", "type_args": [] } }, + { + "vector": { + "vector": { + "struct": { + "address": "08d69f83e56453506a29d8984ced66fb71b69d2854033d19ebe0ec9d927ac00f", + "module": "WPIemSTiNWsfwzc", + "name": "V6", + "type_args": [] + } + } + } + }, { "vector": { "struct": { - "address": "11cf7430d23d4cd73d43f4200b125e0ebfb4dfb275f4729e032ed9c20eb52a47", - "module": "bK8", - "name": "URVIBnreILgUQjlFEYM8", + "address": "659899a40213ad955dc377e5b453760169934f37168a705582f68345f1701545", + "module": "O", + "name": "LYwfxDOsRmDJHsZXh", "type_args": [] } } + }, + { + "struct": { + "address": "f05be73565984d7f31158764fc3e6f176ea654c2cc773e49b4a1d0bb514d01aa", + "module": "SYXuoRRtfnIlKuFfGTpDeaWzorqZn9", + "name": "izePLRZTtZREHqkrxTCJmkYu9", + "type_args": [] + } + }, + { + "struct": { + "address": "62875f98b53f70b637470cabe3fc15026422d7e216f504f03a08cdf8d8d238a1", + "module": "otpdzPdCmgMJySyTZHQNSuZXmfqTYw2", + "name": "GIpbumwyKFmUAH", + "type_args": [] + } + }, + { + "vector": "address" } ], "args": [ - "f628b98cb2a52017", - "f93d7c51ab39f174" + "01", + "4e", + "74680f966e138c58804e0dd9758ec250646ac6dadd4540f7a78481b1cf2e0441", + "1215309177624810137c844a1baba3ae2df40fb0a0c56e02baf0b9b13792ea72", + "9480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64" ] } }, - "max_gas_amount": "14346483141261471112", - "gas_unit_price": "16772306631261316586", - "expiration_timestamp_secs": "744287654133592165", - "chain_id": 244 + "max_gas_amount": "12306627183377365997", + "gas_unit_price": "13239226504445224793", + "expiration_timestamp_secs": "749228628132620752", + "chain_id": 226 }, - "signed_txn_bcs": "da52d5ef29dcca1e8c29d754309118e9ef12f45c936abb97977b9e657372825ebba05d20c5da629a025c4abdf5c0e0656437bca27808d69f83e56453506a29d8984ced66fb71b69d280b5346726b63305f436f696e097a735a43686a49466a050607e69a12e79bb0f49f7e4809c262dc3300473143dfea3599347772b85acc5c8e360e527243736b6542575755617054371d796d446f61584949635353554a70796569625a6d42656d63644750523000076c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc0513575a4768507a41444b4248687a5241677968310956686256654b564f4800060407fbe869392bbc47ccc39856cb4eb89a389d108405d1f020719f118a0f643c214e1c4b424b51506e6544764a49594d4e6969416e7a747946476453685935044766693200060711cf7430d23d4cd73d43f4200b125e0ebfb4dfb275f4729e032ed9c20eb52a4703624b381455525649426e7265494c6755516a6c4645594d38000208f628b98cb2a5201708f93d7c51ab39f174882d05f367f218c7ea6542840434c3e865705793ad3d540af4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cdb956fe7a658a1054354bc882caded3d3c2f1be881e44a11d2b4a4b3ab2199642500e4ac997380b6258737d47837425c85fdf81c523f94677aa76fea140108", + "signed_txn_bcs": "5d9717fdbfc27de79db2fad16ab2f3761aecfc8144bd64ad62983269ee87a696fc104e464d14ca1e02f0bd53c8c3afa9aa842138ded8a060956e846d88a0030a61f91483ceb26635a70769375f436f696e105141534562524764777350766f4370380a0607fd2f959279f5d5dafa186c4021c9876b93bf1ca98dd50f80ea233ffb6038bf6b137473544f70734343475a4c6c7273625a6975721f6d4b776e446155484366796d43616e6154686655794a434e6e7a6c536e463700060600060605077d3a9af931d93a4931bcd0f5e2c594bca07d7159e0add80f09c6caff0a3aac7b046d6d6437196f76476a4f57526a68796f71695848594a6d684947734567360007dc750532f3b61399b2121858a54e26a2887082647f6247303afb3e104b4e6656137a556a51445951584d4861504468766d5748331f54465264487a6c56535a77717148444d516d78764a615666766c4b435a675a0006060708d69f83e56453506a29d8984ced66fb71b69d2854033d19ebe0ec9d927ac00f0f575049656d5354694e577366777a63025636000607659899a40213ad955dc377e5b453760169934f37168a705582f68345f1701545014f114c59776678444f73526d444a48735a58680007f05be73565984d7f31158764fc3e6f176ea654c2cc773e49b4a1d0bb514d01aa1e535958756f525274666e496c4b754666475470446561577a6f72715a6e3919697a65504c525a54745a524548716b727854434a6d6b597539000762875f98b53f70b637470cabe3fc15026422d7e216f504f03a08cdf8d8d238a11f6f7470647a5064436d674d4a795379545a48514e53755a586d6671545977320e47497062756d77794b466d554148000604050101014e2074680f966e138c58804e0dd9758ec250646ac6dadd4540f7a78481b1cf2e0441201215309177624810137c844a1baba3ae2df40fb0a0c56e02baf0b9b13792ea72209480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64edbb5f5038ecc9aa59e764825c2ebbb7d0e965bb77cb650ae2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cd3ff1233df4016bc45e61622cc0625f40c887ef8e013fed407efa3e0702ec3681195d3b15eba4bf575b837396135b982bdf1610b9b849ddebe6edd6db08190e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ae735f802186bc4bdb6a2152ab03f84c113a040c8fa43b1681caa3d012bbf624", - "sequence_number": "10357555565551221430", + "sender": "b91a2a1ea12e0f4265fa3e99cdba576848fa3a539d1d958c2f357472c3403beb", + "sequence_number": "7101046367776588778", "payload": { "EntryFunction": { "module": { - "address": "b469114139a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23e", - "name": "qmbcTtzayHmxluNRUMW_Coin" + "address": "7c872dca6aa04b42c91402b56d9543fbef99bda622a59e28661fbcdce25c5b30", + "name": "hR1_Coin" }, - "function": "JccbHQfmvLwxICZRPhjBi", + "function": "pWZjDnSHoHqqGoHdZgjnaYCwl", "ty_args": [ { "struct": { - "address": "8818f3ce6416a2a75725199c3e6260836a0bedff92a850734e97e851395f98e0", - "module": "ErEEQKEQvCYQAoifLBCXs1", - "name": "YhCwunVVGdpXnxXQXzUQBBenhQm6", + "address": "39a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23ef1796d30", + "module": "dPNOsXIFVqazzuljRJyLKYEh", + "name": "lvowRCftUbYmehZWLAwRCM4", "type_args": [] } + }, + { + "vector": { + "vector": "u128" + } + }, + { + "vector": { + "struct": { + "address": "82a1142edfb1002830b0f54245ea06f2376880b076e2a8939378a37d6db8e0f8", + "module": "uCCpkDEoigwdhzBUFlcsSiArv7", + "name": "BVZpCwEKwQ", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "329a3c36e3dadb0eb2c2a3dd6a230016df4fc18265c37fda909fafa19b627807", + "module": "fqfOycTNIvuZ4", + "name": "TOrgHQVXHHOXhcEj", + "type_args": [] + } + } } ], "args": [ - "dd", - "1f066d1487c2bdda" + "69be79cd01c4b5c4ac46e9b2d20b4752" ] } }, - "max_gas_amount": "11045730974253775244", - "gas_unit_price": "15767577093260820063", - "expiration_timestamp_secs": "1023574694421096523", - "chain_id": 129 + "max_gas_amount": "10548839001685872019", + "gas_unit_price": "2910013646378867616", + "expiration_timestamp_secs": "7052182352659501442", + "chain_id": 142 }, - "signed_txn_bcs": "ae735f802186bc4bdb6a2152ab03f84c113a040c8fa43b1681caa3d012bbf624b6fa0c02e96dbd8f02b469114139a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23e18716d626354747a6179486d786c754e52554d575f436f696e154a6363624851666d764c777849435a5250686a426901078818f3ce6416a2a75725199c3e6260836a0bedff92a850734e97e851395f98e01645724545514b455176435951416f69664c42435873311c59684377756e5656476470586e785851587a55514242656e68516d36000201dd081f066d1487c2bdda8cf9ec5ccc514a995fbe657cd3afd1da4b680ceec277340e81002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3b245ebab878a6b2590d8af49dc4516a186edff3e7fcf2f4d9955839c1f65d830ce47e8c7852b356d5db36f29c13b992a771443d015688e1990c2c978b0ec07", + "signed_txn_bcs": "b91a2a1ea12e0f4265fa3e99cdba576848fa3a539d1d958c2f357472c3403bebeac3e66c0cfc8b62027c872dca6aa04b42c91402b56d9543fbef99bda622a59e28661fbcdce25c5b30086852315f436f696e1970575a6a446e53486f487171476f48645a676a6e615943776c040739a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23ef1796d301864504e4f735849465671617a7a756c6a524a794c4b594568176c766f77524366745562596d65685a574c417752434d3400060603060782a1142edfb1002830b0f54245ea06f2376880b076e2a8939378a37d6db8e0f81a754343706b44456f69677764687a4255466c63735369417276370a42565a704377454b7751000607329a3c36e3dadb0eb2c2a3dd6a230016df4fc18265c37fda909fafa19b6278070d6671664f7963544e4976755a3410544f72674851565848484f586863456a00011069be79cd01c4b5c4ac46e9b2d20b475293cd45902e016592a09bf353fe71622882518c557c62de618e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408c6220c4bd8baee97ae9e4e1d4c2e900c56d7abda07ab5986dfccd558cc5a89e417c4db3dabd76b15dce0d2c038657964c9c5829c1160fafec45656b70b2ea0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "449dcf23a3a88c081dee408676039e001179d4df57db37c1cc592ae7c1e2e49e", - "sequence_number": "11505292297128598057", + "sender": "5eab6dd048d24b07066005e274a13f630e77305eb120c6257ed9fd7512ec11e3", + "sequence_number": "13526641379719566225", "payload": { "EntryFunction": { "module": { - "address": "d8c35420c5943434ff6a8296473d2603438c4fea603a80be93bc290c0243bd8f", - "name": "qWyHiahMLgkqpdVwQooWGjRIVOuzZ8_Coin" + "address": "056c40a62b04dd01086d31e11cb68be029414710b533264aa95f0a009035e5c4", + "name": "zafQazlFxlaJVkwc_Coin" }, - "function": "NXNjfPcYrhtrj8", + "function": "HOafeuL", "ty_args": [ { "struct": { - "address": "112d5944bd109c210f029edeb8b846d740342668d593dee6ee0bf1bc6de6988a", - "module": "KsVTNDfMJDrVrDUg", - "name": "hfRptevFcnGuVbCjrhy", + "address": "8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f1cf9b819094a71d94f63", + "module": "zQFnY8", + "name": "gbyKLQZWOPiOGzdq0", "type_args": [] } }, { - "vector": { - "struct": { - "address": "9157ee23a4f0d6136d63639d5a787f28ec23c1d7141982b1b229e23a513922dc", - "module": "biZhdW3", - "name": "swQta4", - "type_args": [] - } + "struct": { + "address": "aaf19149132b339d45624e164cf2a3b7216ffb44dc22ba112d5944bd109c210f", + "module": "xviiBSmLx6", + "name": "KWgmHxCgi", + "type_args": [] + } + }, + { + "struct": { + "address": "ef7cb7904c1f5fcb23487e81caeb0262714f222f364719bf86ecc28e2d9d82ae", + "module": "OfnPxYYBIZGnUdVgy", + "name": "SffnwCWOrhfMeffuPtMsH6", + "type_args": [] } }, { "struct": { - "address": "be99e94d5a5eda54b8ece68db6c629f4cd63db19ff641929539b3a7f69cafb65", - "module": "tnojhCssrMwdvvVL1", - "name": "dtkF", + "address": "28ec23c1d7141982b1b229e23a513922dce3547aa90107a22a6199e11c27a0d2", + "module": "GZzjKPgfcebOzDhztqIXsjxMqBjb9", + "name": "nTvRgLnsQdgDcwnbmfATuwIUTJlxS7", "type_args": [] } }, { "vector": { - "vector": "u128" + "vector": { + "struct": { + "address": "fa9ea71ed1abb77033d69fedcd49118ef9f6c2f29aa1a709f1b04c2e3527d329", + "module": "FjnGbABbsOM", + "name": "cuJgIQXVybiVqf", + "type_args": [] + } + } } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "34c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83", + "module": "JaTfYxmVyMhNizGwp9", + "name": "vHsSYzynEo", + "type_args": [] + } + } } }, { "struct": { - "address": "7876e52e16f77d32ed355c7332b29bd9ec08be42d92b715ecf0568cfa3815ddd", - "module": "MxVbAvxhInqGZvzKxcYUNuda8", - "name": "ZLGoXdtZVQPhg", + "address": "9211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f28", + "module": "LPmmTRtRrvxpy", + "name": "dDhIJxsMVzqzfZoXX", "type_args": [] } }, { "struct": { - "address": "2463613ba905097bdcce7c32df8ccc73ac2077861d3ce8b02b065facdcedd037", - "module": "JmsHecoY3", - "name": "etLqCOT", + "address": "6988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe", + "module": "VlgTxRgLzgNjRgHJumm", + "name": "RMSHTuRdCBXgt", "type_args": [] } + }, + { + "vector": "bool" } ], "args": [ - "524d1baa6a91f5711f37a0f419cba6f7eadd0ba0d2f5e3e174e8bc8e318f6ad2", - "ed", - "8b52e908844e2cdd", - "4c", - "fb78cbbaac37ab33fe18b8ac64f2a32d", - "82ea7808b7b187e2eac8c3de8270dca1", - "00", - "cb0fa9c16181d087" + "a069f29d27d4e37088a25e6e13a1fdff", + "4297fe91ea65c861", + "570d34a2059698d1cadf5e5ce8a5e78a11143641848660fffa1ff8f7fab7fe9c", + "a2", + "e01a6a477ebb3f08", + "7a", + "60", + "6cc8131a5dd3e1bd7419f11442efdaff", + "db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee292a0f3c0ef6c5" ] } }, - "max_gas_amount": "5806192569497141911", - "gas_unit_price": "3168304758433508900", - "expiration_timestamp_secs": "18379822374843973765", - "chain_id": 107 + "max_gas_amount": "13943765375296266576", + "gas_unit_price": "4260045256900789382", + "expiration_timestamp_secs": "8994813284850017941", + "chain_id": 194 }, - "signed_txn_bcs": "449dcf23a3a88c081dee408676039e001179d4df57db37c1cc592ae7c1e2e49e295a63f76202ab9f02d8c35420c5943434ff6a8296473d2603438c4fea603a80be93bc290c0243bd8f23715779486961684d4c676b7170645677516f6f57476a5249564f757a5a385f436f696e0e4e584e6a66506359726874726a380707112d5944bd109c210f029edeb8b846d740342668d593dee6ee0bf1bc6de6988a104b7356544e44664d4a44725672445567136866527074657646636e47755662436a7268790006079157ee23a4f0d6136d63639d5a787f28ec23c1d7141982b1b229e23a513922dc0762695a68645733067377517461340007be99e94d5a5eda54b8ece68db6c629f4cd63db19ff641929539b3a7f69cafb6511746e6f6a68437373724d77647676564c310464746b4600060603060602077876e52e16f77d32ed355c7332b29bd9ec08be42d92b715ecf0568cfa3815ddd194d78566241767868496e71475a767a4b786359554e756461380d5a4c476f5864745a565150686700072463613ba905097bdcce7c32df8ccc73ac2077861d3ce8b02b065facdcedd037094a6d734865636f59330765744c71434f54000820524d1baa6a91f5711f37a0f419cba6f7eadd0ba0d2f5e3e174e8bc8e318f6ad201ed088b52e908844e2cdd014c10fb78cbbaac37ab33fe18b8ac64f2a32d1082ea7808b7b187e2eac8c3de8270dca1010008cb0fa9c16181d08797c2632261bd935024ee9b326414f82b85005ac7113f12ff6b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c5366ce74e88c5d10daecc446a935c085eba437d80064bbfa6dc952a2661180ddd3dd674963a885002248a3c2011c33f5bce2ef59f80e34361a38eefa64efd06", + "signed_txn_bcs": "5eab6dd048d24b07066005e274a13f630e77305eb120c6257ed9fd7512ec11e391d348eaaa48b8bb02056c40a62b04dd01086d31e11cb68be029414710b533264aa95f0a009035e5c4157a616651617a6c46786c614a566b77635f436f696e07484f616665754c09078396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f1cf9b819094a71d94f63067a51466e5938116762794b4c515a574f50694f477a6471300007aaf19149132b339d45624e164cf2a3b7216ffb44dc22ba112d5944bd109c210f0a7876696942536d4c7836094b57676d48784367690007ef7cb7904c1f5fcb23487e81caeb0262714f222f364719bf86ecc28e2d9d82ae114f666e5078595942495a476e5564566779165366666e7743574f7268664d6566667550744d734836000728ec23c1d7141982b1b229e23a513922dce3547aa90107a22a6199e11c27a0d21d475a7a6a4b5067666365624f7a44687a74714958736a784d71426a62391e6e547652674c6e735164674463776e626d66415475774955544a6c78533700060607fa9ea71ed1abb77033d69fedcd49118ef9f6c2f29aa1a709f1b04c2e3527d3290b466a6e4762414262734f4d0e63754a67495158567962695671660006060734c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83124a61546659786d56794d684e697a477770390a76487353597a796e456f00079211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f280d4c506d6d54527452727678707911644468494a78734d567a717a665a6f585800076988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe13566c67547852674c7a674e6a5267484a756d6d0d524d53485475526443425867740006000910a069f29d27d4e37088a25e6e13a1fdff084297fe91ea65c86120570d34a2059698d1cadf5e5ce8a5e78a11143641848660fffa1ff8f7fab7fe9c01a208e01a6a477ebb3f08017a0160106cc8131a5dd3e1bd7419f11442efdaff20db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee292a0f3c0ef6c550e1ec49bb3482c186c4a82897b81e3b952673a806ffd37cc2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406ac1d72d60b3f2fda3320ed03008d418a0bca9146335ab2cd46f7e07583e106c83f68781a2d4be0569b70c692dcd3b78a1ab138b7c800b98a01b3311e0643a05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "880cdd61301a9936f83efb9e66b4e5742cef37ef6710ed8cfb2b1ff9501c2795", - "sequence_number": "1381338177129607191", + "sender": "93ceb5453a39c221ef6a5afa8815e522038c1aec1ca61b5056f42db035f42079", + "sequence_number": "15579649052219066323", "payload": { "EntryFunction": { "module": { - "address": "0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005e274a13f630e77305e", - "name": "CzRBhknwhUT_Coin" + "address": "055b04fc3d74bd35bc3bce2b2a1d8d69f23d9ea8a15fe86c21e062bc23683948", + "name": "OREdnXCgmLAZ2_Coin" }, - "function": "gaNbHAyp6", + "function": "MCzlrszXqPuIleAql7", "ty_args": [ + { + "struct": { + "address": "e31cfdeb35a1d4e4c9654384abbb81a2d3a322b336aa4061a8fd4dfbe3b5130f", + "module": "GxqHexHGkdUjx", + "name": "PXcAslEqhPEWdTyIO", + "type_args": [] + } + }, { "vector": { - "vector": { - "vector": "bool" - } + "vector": "u128" } }, { "vector": { "struct": { - "address": "985425bbbefea6b1bef17371474e9800ae2956d18f4745809f623d97d6aa1d00", - "module": "CLVgCaEeiGDFlrfVlZYTKYSOfJxLwkvm", - "name": "bopmuIeoLyKkcy", + "address": "09369e71b0586793f98ca19f748578c3f4f4530cf6cc6cd340a4dd6948a42fda", + "module": "VZVhMubYejRySNyONUkuxgGYWlO9", + "name": "sMIPyFWEbaBa4", "type_args": [] } } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "82fd8da12bd8c5e3eb281236266eedea4156a4538283caa5307e18998c382cd7", - "module": "AFomyTGWUJkvScaznvYZYhMa", - "name": "ITCLhAYZAKywmnI4", + "address": "4afdfe5fcafb92a3938655ad4af060e09c58d5a58ca2ab15ec7482aaef47b8b2", + "module": "LznaikVZwCAK", + "name": "nNTXwWDEwAVtDQfcgtEjXL", "type_args": [] } }, { "vector": { "struct": { - "address": "d8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f136472e38994d66e37e309", - "module": "WPVh", - "name": "gKzDkGV", + "address": "a25ecb9d2ced8e3e99a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52", + "module": "SyEJ4", + "name": "NwwZQNG", "type_args": [] } } }, + { + "struct": { + "address": "92279124e797f1599258e99c38d02cf8b5bc99e133fea353fd14070621eefead", + "module": "mqkQzmwvzqxkSnDCyrkTHPFmH", + "name": "YTce2", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "0b8c33e2b754278857c606fbce3542bd8fdb55dea9c5fe0bbf43027458e11261", - "module": "pxOaCwOapCuBId6", - "name": "KSoPzgZfqgwxnqNgDIIoTiYjJP", - "type_args": [] + "vector": { + "vector": "u8" } } }, + { + "struct": { + "address": "9392b09cc82a3d6503682c179c9bdd09baa0f1f3a1002a1ca9bad45ea54161c6", + "module": "RqTZPrQyDYmSETGzRlfwKxwn", + "name": "EgiYiGOLJcBfcJBoFQtc", + "type_args": [] + } + } + ], + "args": [ + "00", + "02", + "636b7a72c6c12600" + ] + } + }, + "max_gas_amount": "10347459430950769268", + "gas_unit_price": "5821428440788011840", + "expiration_timestamp_secs": "11676970727382150744", + "chain_id": 139 + }, + "signed_txn_bcs": "93ceb5453a39c221ef6a5afa8815e522038c1aec1ca61b5056f42db035f42079d3c7c4ba440836d802055b04fc3d74bd35bc3bce2b2a1d8d69f23d9ea8a15fe86c21e062bc23683948124f5245646e5843676d4c415a325f436f696e124d437a6c72737a58715075496c6541716c370907e31cfdeb35a1d4e4c9654384abbb81a2d3a322b336aa4061a8fd4dfbe3b5130f0d47787148657848476b64556a781150586341736c457168504557645479494f00060603060709369e71b0586793f98ca19f748578c3f4f4530cf6cc6cd340a4dd6948a42fda1c565a56684d756259656a5279534e794f4e556b7578674759576c4f390d734d495079465745626142613400060603074afdfe5fcafb92a3938655ad4af060e09c58d5a58ca2ab15ec7482aaef47b8b20c4c7a6e61696b565a7743414b166e4e54587757444577415674445166636774456a584c000607a25ecb9d2ced8e3e99a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52055379454a34074e77775a514e47000792279124e797f1599258e99c38d02cf8b5bc99e133fea353fd14070621eefead196d716b517a6d77767a71786b536e444379726b544850466d480559546365320006060601079392b09cc82a3d6503682c179c9bdd09baa0f1f3a1002a1ca9bad45ea54161c6185271545a5072517944596d534554477a526c66774b78776e144567695969474f4c4a634266634a426f4651746300030100010208636b7a72c6c126007412967d878f998f408b86da52dec950586e3f6202ef0ca28b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400625f4181a4dae1bac0fe40981e46039e91544a02260dcd428b63b852f5a434d34828d562c1a6aeb8dfc2a5a0db4522d83a5349567dd4e05bd23e7669d22d404", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "046fe90fd575a0b7f069479fa11c47029b89cd14f89fd4512c9b9aa190f120e3", + "sequence_number": "12166345473849194768", + "payload": { + "EntryFunction": { + "module": { + "address": "0f0e82c4b35d3db8994cdaf46085f6dd9c3e0b3fe3f0c68b8f11088d5d0b700a", + "name": "pupgeOiJpLbr_Coin" + }, + "function": "kASWwvEOkKVdUKJdpHCrMXrNmnZJEDdL", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "6229610779039224186", + "gas_unit_price": "15048478706417742305", + "expiration_timestamp_secs": "6763500135402354831", + "chain_id": 111 + }, + "signed_txn_bcs": "046fe90fd575a0b7f069479fa11c47029b89cd14f89fd4512c9b9aa190f120e310797697bf8ad7a8020f0e82c4b35d3db8994cdaf46085f6dd9c3e0b3fe3f0c68b8f11088d5d0b700a1170757067654f694a704c62725f436f696e206b4153577776454f6b4b5664554b4a64704843724d58724e6d6e5a4a4544644c00007ad19365ff057456e1310f3aa7efd6d08fb8f6e089c7dc5d6f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440eb7a466d55a1a837d16669d4727af30a7507a20e6d1ab07a66749e2e6cea12283dac63ec2f84978b52dc1d133c7c449aacf190e49f1c8e9b4700fbca3c41fd03", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "cf38db305e36d752adbffa775e0c0d22728aff181ef71f296505b32a566ebfb0", + "sequence_number": "6886332014812307704", + "payload": { + "EntryFunction": { + "module": { + "address": "e7d000b8cffbf433727cbb9af90b854535a90a9e686f27313f2d5b75a85dbc79", + "name": "JBbqWYCRsLawKAWDTi_Coin" + }, + "function": "jeXGkOTTOUwPCUAPkIBJEhBrUooH", + "ty_args": [], + "args": [ + "1349120545449abb862890778ee78cf3", + "4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab629ccdb621bc2c" + ] + } + }, + "max_gas_amount": "16112721288988679135", + "gas_unit_price": "14147689124333243195", + "expiration_timestamp_secs": "8557782823263658189", + "chain_id": 116 + }, + "signed_txn_bcs": "cf38db305e36d752adbffa775e0c0d22728aff181ef71f296505b32a566ebfb0f8a0496c7b2a915f02e7d000b8cffbf433727cbb9af90b854535a90a9e686f27313f2d5b75a85dbc79174a42627157594352734c61774b41574454695f436f696e1c6a6558476b4f54544f557750435541506b49424a45684272556f6f480002101349120545449abb862890778ee78cf3204e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab629ccdb621bc2cdf5b0bbba4e29bdf3b4b8a084db056c4cde091fd225ac37674002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440516d0e07c842647dd4d2374e66f2cd23bae93889ea092bc2f4e175b5548365d9366b8adcd9e2d6a8b2195b93b5f1cfbb22641c3ca28f26cd8c0651d040c30807", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "89f4844338fee31ec24997c4d09688f1f4525f865c2d1655a844aad8982c50f5", + "sequence_number": "6460905479205342360", + "payload": { + "EntryFunction": { + "module": { + "address": "25e33821ae7072467f96977906b51f2a66bd99386dc32afa0f8b1d19cd5707ef", + "name": "bkYgKqkQQjXEBAmIhKIduDqZahyisjM_Coin" + }, + "function": "dsZbTfMxShxHdprnRD", + "ty_args": [ + { + "struct": { + "address": "f542d67e6355ee49c702cef2490766afca33a7c5dd6b2ad3904e8d2c8eb05960", + "module": "jkoifyRcgU6", + "name": "xYL9", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "15a3b6f442bccb980e3406c8f2a511dc422f209c83ca6d2d1f89588c66c30dc1", - "module": "GhQBvJc", - "name": "fnDXHGyjjpFQvnPgyuXpqoxMZppl3", + "address": "900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e10ac62ec", + "module": "cgzhvouadziQwQsVeReJHJtu", + "name": "sXSYE", "type_args": [] } } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "d08a3151ba345f85c9bd68750699abd24a793d30ec8dba963c76103d3efc0fd7", - "module": "aQXCTlOkdCgGVEAkeooPQ", - "name": "YAavhLxVbGGroOjAJg3", + "address": "f7aa485b5bb10a185e6ed0ea7ec274b80c2284abb9b3830d29bc90f8690a8d44", + "module": "ZdEkdPQxSzID", + "name": "TOyzonhOTNuBUFPQrhYKgJSGmRYd", "type_args": [] } }, { - "vector": { - "vector": "u128" + "struct": { + "address": "bfb6bcffeb750b6b65d5c28bd04d63f6c8beabfc7cc91b28192b4259a1207174", + "module": "VbvLYvHBViWGslLSjYA7", + "name": "PE7", + "type_args": [] + } + }, + { + "struct": { + "address": "d9cecc75d2c1cf7d08cdf21d8ec932d078d80f0ede022371f6ad1973a2b57474", + "module": "nlnrVBnGnObmQxpXHOEWFTdAUFgRJ1", + "name": "JVwpSQBxhlTJKjOGsHsMErqwgP9", + "type_args": [] } }, { "struct": { - "address": "05e58e9b159d4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab62", - "module": "Ds", - "name": "PvgFiXBnEaQlQitglmDgYznI", + "address": "b3c9602101ba78d04c9f16b5428d671bf9f268b549fc9249a596cc974b0edc70", + "module": "ujRcytrHWQXRHHCvVBvuQeEceWSd5", + "name": "OKZMWwOkrSVtiJYXpje9", "type_args": [] } } ], "args": [ "00", - "00", - "01" + "33d0a30b42903b5f5beab55afd7b4947", + "36f8384afcbb04685a1698f2aeb8f8c6", + "87798bd70a704217b910c0f01e7489bb", + "01", + "afba364e217c47a189c3e31b7d1d14cc" ] } }, - "max_gas_amount": "14234658448162911346", - "gas_unit_price": "5618757543891850476", - "expiration_timestamp_secs": "2259191920989873696", - "chain_id": 93 + "max_gas_amount": "9071601584770487647", + "gas_unit_price": "17936966246252769706", + "expiration_timestamp_secs": "10826884554604528622", + "chain_id": 169 }, - "signed_txn_bcs": "880cdd61301a9936f83efb9e66b4e5742cef37ef6710ed8cfb2b1ff9501c279517f07ee2c07f2b13020731f44eee292a0f3c0ef6c55eab6dd048d24b07066005e274a13f630e77305e10437a5242686b6e776855545f436f696e0967614e62484179703609060606000607985425bbbefea6b1bef17371474e9800ae2956d18f4745809f623d97d6aa1d0020434c566743614565694744466c7266566c5a59544b59534f664a784c776b766d0e626f706d7549656f4c794b6b6379000782fd8da12bd8c5e3eb281236266eedea4156a4538283caa5307e18998c382cd71841466f6d79544757554a6b765363617a6e76595a59684d61104954434c6841595a414b79776d6e4934000607d8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f136472e38994d66e37e309045750566807674b7a446b47560006070b8c33e2b754278857c606fbce3542bd8fdb55dea9c5fe0bbf43027458e112610f70784f6143774f61704375424964361a4b536f507a675a66716777786e714e674449496f5469596a4a5000060715a3b6f442bccb980e3406c8f2a511dc422f209c83ca6d2d1f89588c66c30dc10747685142764a631d666e44584847796a6a704651766e506779755870716f784d5a70706c330007d08a3151ba345f85c9bd68750699abd24a793d30ec8dba963c76103d3efc0fd71561515843546c4f6b644367475645416b656f6f50511359416176684c7856624747726f4f6a414a6733000606030705e58e9b159d4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab6202447318507667466958426e4561516c516974676c6d4467597a6e4900030100010001017274c3ad70aa8bc5ec54b87a37d6f94d20a6081a15435a1f5d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0e262d002e853d0c81378f6d510d6fbc6c4426c744b303d392b8a15a572646ece0a0612998425b33ddb8edb42e100f4272dae2e09a5a896ecb305b226665e08", + "signed_txn_bcs": "89f4844338fee31ec24997c4d09688f1f4525f865c2d1655a844aad8982c50f598cc684f4dbfa9590225e33821ae7072467f96977906b51f2a66bd99386dc32afa0f8b1d19cd5707ef24626b59674b716b51516a584542416d49684b49647544715a61687969736a4d5f436f696e1264735a6254664d78536878486470726e52440707f542d67e6355ee49c702cef2490766afca33a7c5dd6b2ad3904e8d2c8eb059600b6a6b6f69667952636755360478594c39000607900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e10ac62ec1863677a68766f7561647a6951775173566552654a484a74750573585359450006060307f7aa485b5bb10a185e6ed0ea7ec274b80c2284abb9b3830d29bc90f8690a8d440c5a64456b64505178537a49441c544f797a6f6e684f544e7542554650517268594b674a53476d5259640007bfb6bcffeb750b6b65d5c28bd04d63f6c8beabfc7cc91b28192b4259a1207174145662764c5976484256695747736c4c536a594137035045370007d9cecc75d2c1cf7d08cdf21d8ec932d078d80f0ede022371f6ad1973a2b574741e6e6c6e7256426e476e4f626d51787058484f455746546441554667524a311b4a56777053514278686c544a4b6a4f477348734d457271776750390007b3c9602101ba78d04c9f16b5428d671bf9f268b549fc9249a596cc974b0edc701d756a526379747248575158524848437656427675516545636557536435144f4b5a4d57774f6b72535674694a5958706a6539000601001033d0a30b42903b5f5beab55afd7b49471036f8384afcbb04685a1698f2aeb8f8c61087798bd70a704217b910c0f01e7489bb010110afba364e217c47a189c3e31b7d1d14cc5f951df493cde47daa711150c4e7ecf8eec35d9d23d24096a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b74ef839176390d37ab2b84cf7898af0e3bef671218afcae2c56382fdba7b489f5e873dddd748f4e8f35e45e75622dd561646c9f5095af7cc97f342d86b29a00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "54d5baf582f9994a667d148324ce2691fcf9b0826fdf26ef35ceb5ddd7269d88", - "sequence_number": "3717353077664826892", + "sender": "134d732e9db31a2ab21326068f1c565beab5c67c5b9882b4a097594cf605527d", + "sequence_number": "2570068892391005937", "payload": { "EntryFunction": { "module": { - "address": "83087427899de51fedbd2125795abb17c06116ebf688e7de92721495825a2fc6", - "name": "e_Coin" + "address": "0081ee5519879b7b6adf3565d5fa922747ea5574df7178f175a23ff20907848b", + "name": "UudEaMn_Coin" }, - "function": "fYxUKZQyHfE", + "function": "ZxsXIuGaThkZ", "ty_args": [ { "struct": { - "address": "c5cde625a0a3c678b770d09b95cbeef50a420bd3699ed62a6a23b7c724b88f02", - "module": "shQVyUqjZpTXASdbLtTErv3", - "name": "RKxUYHHOCse3", + "address": "253ab14b324243f82f93c1ac8e92227c9c75b85cbd18f10b20d915b4f1411bb9", + "module": "UFfZf", + "name": "Vp1", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "e210099838049ce8727613c6cb2834ee620c606f3ff75559fbba622cb087b0f7", + "module": "UjOV", + "name": "wPfxVZQgWigsuwggPnwijwYFTjHDruii", + "type_args": [] + } + } + }, { "vector": { "vector": { - "vector": "u64" + "struct": { + "address": "b90cb79a6aeea497cd32dbddfdfaf3f6442b0a5fd30230b935329beecac88e6b", + "module": "NMBfQRDaQTQNCsjbM8", + "name": "abznvPLKI", + "type_args": [] + } } } }, { "struct": { - "address": "cf0dbd1c73cd107278da141c099f9af01510b6978515babaa55a2325010a27fe", - "module": "GgjLEsnzSdyvyhahyfArBGaW1", - "name": "xTKKapZphRgNptVknSiQ", + "address": "770bfa0e8b2eb302ceb436d67840d791478412af7a6fe0c37a093c6bac0ad901", + "module": "nbxNRKtrymYduJynEsRbCSb", + "name": "TpmpRHhiVholsTFPFjniGFRpaYSu", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "4c908e1026bf4a76833244e8f0303ca805332436b25ba0831139db704e15e769", + "module": "YxEaSNvIomkEIYyRNAzJluXmKGFY", + "name": "xHMQBL", + "type_args": [] + } + } + }, { "struct": { - "address": "8a1e5530eae60819bec6b7e74a23b370a2f7d46774757d28d299016aefe01060", - "module": "UAxHputqpmDrUrxQTBzHundp5", - "name": "txJaCfVcJfTU", + "address": "2ed2febc7594a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd10", + "module": "yggrQUPHxNbVOuqBtjrDlodm", + "name": "sEkwQrwjTxwwppoYQVHfCPvBlIFnml9", "type_args": [] } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "74c3220aaccdc846d8294625181e8ae1ef0c0cff68e5775a0dd5ebbb8f17a4cc", - "module": "JeVLCxAvUzlawpnhTCM6", - "name": "rJjTugMkyCcoikdUOdbaxj6", + "address": "e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f27", + "module": "MhbkpfVqZMNsT", + "name": "BqIxxIbxQMAqAO", + "type_args": [] + } + }, + { + "struct": { + "address": "0657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f11", + "module": "szyxIi0", + "name": "ZeJrHJgrdDTMzgS", + "type_args": [] + } + }, + { + "struct": { + "address": "66e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c", + "module": "Kw2", + "name": "Mq", + "type_args": [] + } + } + ], + "args": [] + } + }, + "max_gas_amount": "16363801318092544663", + "gas_unit_price": "16369882238411763458", + "expiration_timestamp_secs": "10800036792930028983", + "chain_id": 30 + }, + "signed_txn_bcs": "134d732e9db31a2ab21326068f1c565beab5c67c5b9882b4a097594cf605527df15e3f730ab8aa23020081ee5519879b7b6adf3565d5fa922747ea5574df7178f175a23ff20907848b0c55756445614d6e5f436f696e0c5a7873584975476154686b5a0a07253ab14b324243f82f93c1ac8e92227c9c75b85cbd18f10b20d915b4f1411bb9055546665a6603567031000607e210099838049ce8727613c6cb2834ee620c606f3ff75559fbba622cb087b0f704556a4f562077506678565a51675769677375776767506e77696a775946546a48447275696900060607b90cb79a6aeea497cd32dbddfdfaf3f6442b0a5fd30230b935329beecac88e6b124e4d4266515244615154514e43736a624d380961627a6e76504c4b490007770bfa0e8b2eb302ceb436d67840d791478412af7a6fe0c37a093c6bac0ad901176e62784e524b7472796d5964754a796e457352624353621c54706d705248686956686f6c73544650466a6e6947465270615953750006074c908e1026bf4a76833244e8f0303ca805332436b25ba0831139db704e15e7691c59784561534e76496f6d6b45495979524e417a4a6c75586d4b4746590678484d51424c00072ed2febc7594a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd10187967677251555048784e62564f757142746a72446c6f646d1f73456b775172776a5478777770706f5951564866435076426c49466e6d6c390006060307e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f270d4d68626b706656715a4d4e73540e4271497878496278514d4171414f00070657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f1107737a79784969300f5a654a72484a67726444544d7a6753000766e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c034b7732024d710000979af98399e617e3026f821b2a812de3b74dbefb3d70e1951e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d81156136cd319a30df481932d79404f51cf3abf88cbb27f294d05d85cd3df50a7f92baf96cd93cf045c96504661abb8b06483700967b84166735bb8106a9001", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "e34c228cb0db32dc07105d569c400e706d7e9d44357e3e54ca8fc6e6a3a67855", + "sequence_number": "888570191171883374", + "payload": { + "EntryFunction": { + "module": { + "address": "244760371f7677296d3ef09b116fce093dea6f10cc4558d5810b6a57f42cfe02", + "name": "PaeYJMCBWximKgPRAxfc7_Coin" + }, + "function": "hiOrLWaLZrCLQJNaUvJNzCYgJ3", + "ty_args": [ + { + "struct": { + "address": "3cc9105c38812512626f90e3ec0c810ab5f197ecb0a8d8712ba2e8d91deaf86e", + "module": "TN", + "name": "acjTOuQF2", "type_args": [] } }, { "vector": { "struct": { - "address": "24faaf65e7cefe05f740b732e5fdf3aa467a2418bea584952347b1ef46d3eedf", - "module": "kkNCRVOSBPwKCfyqDuQxvjKNCVtujP6", - "name": "wEjzhGdLBdYaEDhPSkdKUIBQMT2", + "address": "3f3093b6c3bc411ff7477f73d8f49f5c0449af13cd476b3485c96ae5cb5b59a0", + "module": "TilObrKeXE", + "name": "sPxgFQdM7", "type_args": [] } } }, { "struct": { - "address": "2a128efa8dc655606530bd39b474f868244df262fed29e42f3d652b1dabdcf8b", - "module": "HqYDRhUJ6", - "name": "bowFKgoxlbvqGJgyRgwwWwJe3", + "address": "84c3c8114b4cda43a352b7efd2cffdf58010d3e4abc0245de9e09c8feee4904a", + "module": "ldupuolksWYwEFoodFf", + "name": "TWTgNZERkSwjImJfAwfTMbhaEDrDrUed", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff4ad26877cd27dcc5", + "module": "PmwlvpdhJFbyLGQMa1", + "name": "BjKeImcNaFmUMdWIAW6", + "type_args": [] + } + } + }, { "struct": { - "address": "1994a1bdf29555ce80c36f63f05e216aa1b35d14829eedc4039230f8e700d576", - "module": "lzV4", - "name": "mRXWzELcuVWTYp", + "address": "89a200128cc1f57108b093f6c6ac3ab49b3f7e825439eeab9d2d2986e486fc6b", + "module": "GHrJwPvRDxtbeHlJfDsMtS", + "name": "iYRrXB", "type_args": [] } }, @@ -1112,9 +1627,9 @@ "vector": { "vector": { "struct": { - "address": "e34a464bd706ed3bd619596d791e2ed2febc7594a4173faea83d4df1ffbbb90e", - "module": "JWMroNMVcGcBvVRk", - "name": "QRIMpjbeTKfTFmtyCHvm", + "address": "e84a980c5bf6f1dfcbf2554344b84a42a96b3f38018170b8a141d72aa7f8a3fb", + "module": "NNrWslc6", + "name": "ztdkjUrgIXeMPMU2", "type_args": [] } } @@ -1122,1021 +1637,1085 @@ } ], "args": [ - "12", - "0fcc7132f551402a", - "9e93813082773ed762d7bbcbb7ce1ccc", - "883c87ff252dcdad49c9c12a2bb9a75de53e3ba95d72a89691ebca25874a5987" + "d27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be5003", + "5ca2c3f79f855a38ec3b1e13d7d20910", + "01", + "5033aa4e303a3e593dab78acc7909c65b47b89c2a8a9905602d80a47cea4b13d", + "4c11b3c4e857a778", + "57f996bfc6c0365226365ee5fdb57f1a70a89c7bd49732e2ff2d5a9339e45436" ] } }, - "max_gas_amount": "6744637128398603363", - "gas_unit_price": "734413557413829576", - "expiration_timestamp_secs": "11536696249601430455", - "chain_id": 174 + "max_gas_amount": "3666232234570733649", + "gas_unit_price": "30194248730412988", + "expiration_timestamp_secs": "4187513366266677308", + "chain_id": 225 }, - "signed_txn_bcs": "54d5baf582f9994a667d148324ce2691fcf9b0826fdf26ef35ceb5ddd7269d880cc6eac2edb096330283087427899de51fedbd2125795abb17c06116ebf688e7de92721495825a2fc606655f436f696e0b665978554b5a51794866450907c5cde625a0a3c678b770d09b95cbeef50a420bd3699ed62a6a23b7c724b88f0217736851567955716a5a705458415364624c7454457276330c524b78555948484f43736533000606060207cf0dbd1c73cd107278da141c099f9af01510b6978515babaa55a2325010a27fe1947676a4c45736e7a53647976796861687966417242476157311478544b4b61705a706852674e7074566b6e53695100078a1e5530eae60819bec6b7e74a23b370a2f7d46774757d28d299016aefe01060195541784870757471706d44725572785154427a48756e6470350c74784a61436656634a665455000774c3220aaccdc846d8294625181e8ae1ef0c0cff68e5775a0dd5ebbb8f17a4cc144a65564c43784176557a6c6177706e6854434d3617724a6a5475674d6b7943636f696b64554f646261786a3600060724faaf65e7cefe05f740b732e5fdf3aa467a2418bea584952347b1ef46d3eedf1f6b6b4e4352564f534250774b4366797144755178766a4b4e435674756a50361b77456a7a6847644c4264596145446850536b644b554942514d543200072a128efa8dc655606530bd39b474f868244df262fed29e42f3d652b1dabdcf8b09487159445268554a3619626f77464b676f786c627671474a67795267777757774a653300071994a1bdf29555ce80c36f63f05e216aa1b35d14829eedc4039230f8e700d576046c7a56340e6d5258577a454c6375565754597000060607e34a464bd706ed3bd619596d791e2ed2febc7594a4173faea83d4df1ffbbb90e104a574d726f4e4d56634763427656526b145152494d706a6265544b6654466d74794348766d00040112080fcc7132f551402a109e93813082773ed762d7bbcbb7ce1ccc20883c87ff252dcdad49c9c12a2bb9a75de53e3ba95d72a89691ebca25874a598763041cd1bbc3995dc8dbe1473d29310ab713136f1d941aa0ae002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d7ffd92ecb3fb714cb14babb35011457eb73f5c27bcefe028393c780dc35d811d9cdbbe741c93a4b486b8754b57fa89dedaf9f9dc533e556c88fb32e2a03450b", + "signed_txn_bcs": "e34c228cb0db32dc07105d569c400e706d7e9d44357e3e54ca8fc6e6a3a678556e11cd8ae1d5540c02244760371f7677296d3ef09b116fce093dea6f10cc4558d5810b6a57f42cfe021a506165594a4d43425778696d4b67505241786663375f436f696e1a68694f724c57614c5a72434c514a4e6155764a4e7a4359674a3306073cc9105c38812512626f90e3ec0c810ab5f197ecb0a8d8712ba2e8d91deaf86e02544e0961636a544f755146320006073f3093b6c3bc411ff7477f73d8f49f5c0449af13cd476b3485c96ae5cb5b59a00a54696c4f62724b65584509735078674651644d37000784c3c8114b4cda43a352b7efd2cffdf58010d3e4abc0245de9e09c8feee4904a136c647570756f6c6b7357597745466f6f64466620545754674e5a45526b53776a496d4a66417766544d62686145447244725565640006070bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff4ad26877cd27dcc512506d776c767064684a4662794c47514d613113426a4b65496d634e61466d554d645749415736000789a200128cc1f57108b093f6c6ac3ab49b3f7e825439eeab9d2d2986e486fc6b164748724a775076524478746265486c4a6644734d74530669595272584200060607e84a980c5bf6f1dfcbf2554344b84a42a96b3f38018170b8a141d72aa7f8a3fb084e4e7257736c6336107a74646b6a5572674958654d504d5532000620d27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be5003105ca2c3f79f855a38ec3b1e13d7d209100101205033aa4e303a3e593dab78acc7909c65b47b89c2a8a9905602d80a47cea4b13d084c11b3c4e857a7782057f996bfc6c0365226365ee5fdb57f1a70a89c7bd49732e2ff2d5a9339e4543651d8acf5ca12e132bc07d65d82456b003c88866038091d3ae1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409db7b1e8a85bfa87bf1f6e09843c9a0e73c7717e6d3af86b55cf335d4fab91c8cb167ed424017e5dfa3f5c67f6800efc63fc91567e27177dbe91fe370156ed01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24c02074401299864e34d765e7cdc212a9bab6b53d812f05526e048aa7fff7e3", - "sequence_number": "18086002593060308461", + "sender": "7c5677dc6662cf3227da3e6ab18bf03d07c7ab987364c6e2057843c04cf6b1c7", + "sequence_number": "6905325641423493828", "payload": { "EntryFunction": { "module": { - "address": "26903d925bc0127b98e641d6f8c8ee92bf76b148a4c8859334d8b3da032e24c8", - "name": "DOwslDvcwWRCTsRYhyIPwCyOVZGiC7_Coin" + "address": "e6cbfc63ba5d801d1605672602731080adbe4b8e4963328222a7f7081bcb17a1", + "name": "nVfZwVBXSHjw1_Coin" }, - "function": "bicVvAkYbwrpRE", + "function": "UrVhCRMLXNIeUplO", "ty_args": [], "args": [ - "fefeaa587042407ad2dd90db5ba259264ce600a46cd6df9c715dd0975ca2670f", - "7ca7b496313b629f06df291ef6fbfbf9c8295c656d2c6157fbba785d6d43ce57", - "01" + "01", + "01", + "8f481ec5966cf9ee8d10423503ddf299", + "4cf4567222684fe41a556c8f7639d88d", + "00", + "c5" ] } }, - "max_gas_amount": "7716011856904148623", - "gas_unit_price": "1435933835037602044", - "expiration_timestamp_secs": "8271686736635672138", - "chain_id": 162 + "max_gas_amount": "18040656634559581542", + "gas_unit_price": "15754263679587659502", + "expiration_timestamp_secs": "2493882573905329835", + "chain_id": 202 }, - "signed_txn_bcs": "24c02074401299864e34d765e7cdc212a9bab6b53d812f05526e048aa7fff7e3ed4527de8863fefa0226903d925bc0127b98e641d6f8c8ee92bf76b148a4c8859334d8b3da032e24c823444f77736c4476637757524354735259687949507743794f565a476943375f436f696e0e6269635676416b59627772705245000320fefeaa587042407ad2dd90db5ba259264ce600a46cd6df9c715dd0975ca2670f207ca7b496313b629f06df291ef6fbfbf9c8295c656d2c6157fbba785d6d43ce5701018f567915e7c7146bfc70610e3776ed134ab67afe42efca72a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403b23375b7256fe02abeec9d286a9b35095bcd82edd768176de864b00b7c4bcaadc1b5fe840d2e3a64cb52be173c6efc877c55ccedf2dc509145125b714dc320e", + "signed_txn_bcs": "7c5677dc6662cf3227da3e6ab18bf03d07c7ab987364c6e2057843c04cf6b1c7c49a71bb15a5d45f02e6cbfc63ba5d801d1605672602731080adbe4b8e4963328222a7f7081bcb17a1126e56665a7756425853486a77315f436f696e105572566843524d4c584e496555706c4f000601010101108f481ec5966cf9ee8d10423503ddf299104cf4567222684fe41a556c8f7639d88d010001c566cdb729a0495dfaee2ea9cf5863a2daabfe29e1fc0c9c22ca002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405ddcb990b73a5d491c6a74c5a6e67c18fbe27602825ed8ebcfdd9bfefaca28b11a87d2bd7d625b1694ffce62878dd69df5fe9c37c32c5e4d171d9dd832cf9006", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c7196048ae1b6b6badb5051fe55702ddcbcea417cfbb25686481a135adc1f2c2", - "sequence_number": "2609204882976820818", + "sender": "d582d64eb84ea6497edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15", + "sequence_number": "9117124696319766204", "payload": { "EntryFunction": { "module": { - "address": "b68426c0b04d890f08ef417086c02634ef08c7758c7158ae1c2f0c33c5a1af43", - "name": "SEFfJoUwaoMHFxCzm_Coin" + "address": "3f8ffd1339aec7961c6552ea354e1b8224dc101155d545211655e7905639dcb3", + "name": "uxTQ_Coin" }, - "function": "pUsPuolfbhfOlpjvESLoQSZTVZCxurR4", + "function": "OilsgLnWUpYBb", "ty_args": [ + { + "struct": { + "address": "b707063fbae528597d01de68ee4ed5d02e2da2a03f8e2c8e6297a4a98833cd45", + "module": "gAtlJEWKciHRuUfijQNuDXUDjpQnWGP", + "name": "asBmWVCKeDHMhWdHZUdfidHmJksQHxM", + "type_args": [] + } + }, { "vector": { "vector": { - "vector": "bool" + "vector": "address" } } }, { - "struct": { - "address": "ae410379d36252a6d8b8ff4ad26877cd27dcc582f47a700b80bb135b9992c32e", - "module": "vphTmGmxdjIXtlhTLLTay", - "name": "AtGOeSQrwuOrmuPhxcMHyUjUKTLJhC", - "type_args": [] + "vector": { + "vector": "address" } }, { "vector": { "struct": { - "address": "cc5a38151852cc97fd7bf9ff603970120a7f77dbe84a980c5bf6f1dfcbf25543", - "module": "oqFQwcN", - "name": "FdWMoDkLfozpEyJYklJJiCqWhYcAVT6", + "address": "c13875b7536c22ed5b4707d1d7dbd73e9280265b91aa713bcf2df7d708588614", + "module": "yeACZwrsxtZpOOAoPhsjtfsHw", + "name": "GfQLKUdTpblUKCfMlyOoVSiyyLJp3", "type_args": [] } } }, { - "vector": { - "struct": { - "address": "b0fc45bef6184a8100a982dfed41d86d7a2c34a4c05a8e70cb5decffb08af6ca", - "module": "uoxUGXeb1", - "name": "mJciLGtTNXAGKPjLoWF4", - "type_args": [] - } + "struct": { + "address": "72b8a8f7acf89b1ffa6043823639964c2c4fb29dde3dcd31978d683c80bd7880", + "module": "ctlMOZMyiW", + "name": "R", + "type_args": [] } }, { "vector": { - "vector": { - "vector": "u128" + "struct": { + "address": "b55a0e54cf8dcee8e9e27437e8f2929c37b94dc20fd72990e37a85821c8a16de", + "module": "alPuBZmtrO1", + "name": "PaSO6", + "type_args": [] } } }, + "u128", { "struct": { - "address": "2bd44b1874a5ad1b79869d76a93e5a0227fb879c042f3c38beb47dc222e9d698", - "module": "pPUsqGagULyIhi3", - "name": "doJUWBmiREclbOsKngzgRudpVmVbJx", + "address": "ada65994413d125ec33dc34f2a62f2f2986ccb62d5e160f2fb25e94d9cd9749c", + "module": "dywNzislXPKZDVNRwVFvVxNtAEakpZCA9", + "name": "ejpKlYOeSaMXxpqZPpllqogpdAJuxGDi7", "type_args": [] } + }, + { + "vector": { + "vector": "u8" + } } ], - "args": [] + "args": [ + "2668a664c7fad55058031e203958245f64db890d4f1513073cb47e0226f52010", + "00", + "20cd5eee30144faa", + "9213c4403e92b659", + "01", + "791cbe62acfb65f2394f99eb97e33417" + ] } }, - "max_gas_amount": "8316483292381286413", - "gas_unit_price": "4755289998184685823", - "expiration_timestamp_secs": "14157415986381130450", - "chain_id": 205 + "max_gas_amount": "6149953208834578549", + "gas_unit_price": "5751162415133397679", + "expiration_timestamp_secs": "16653012668262455914", + "chain_id": 41 }, - "signed_txn_bcs": "c7196048ae1b6b6badb5051fe55702ddcbcea417cfbb25686481a135adc1f2c2524e0c5404c2352402b68426c0b04d890f08ef417086c02634ef08c7758c7158ae1c2f0c33c5a1af4316534546664a6f5577616f4d484678437a6d5f436f696e2070557350756f6c666268664f6c706a7645534c6f51535a54565a437875725234060606060007ae410379d36252a6d8b8ff4ad26877cd27dcc582f47a700b80bb135b9992c32e15767068546d476d78646a4958746c68544c4c5461791e4174474f6553517277754f726d75506878634d4879556a554b544c4a6843000607cc5a38151852cc97fd7bf9ff603970120a7f77dbe84a980c5bf6f1dfcbf25543076f71465177634e1f4664574d6f446b4c666f7a7045794a596b6c4a4a6943715768596341565436000607b0fc45bef6184a8100a982dfed41d86d7a2c34a4c05a8e70cb5decffb08af6ca09756f78554758656231146d4a63694c4774544e5841474b506a4c6f5746340006060603072bd44b1874a5ad1b79869d76a93e5a0227fb879c042f3c38beb47dc222e9d6980f7050557371476167554c79496869331e646f4a5557426d695245636c624f734b6e677a6752756470566d56624a7800000d90dbe67d156a73ff20c4090f2ffe41d20aaf95d43e79c4cd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3da784f93d783ed3969ab7fdbac707639308e126b76862dc8d9f634c0467929f9a656a528de578db678c380234c44319bca6049cd4896ddf82d4313d057cc04", + "signed_txn_bcs": "d582d64eb84ea6497edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bcae14519b88867e023f8ffd1339aec7961c6552ea354e1b8224dc101155d545211655e7905639dcb309757854515f436f696e0d4f696c73674c6e5755705942620907b707063fbae528597d01de68ee4ed5d02e2da2a03f8e2c8e6297a4a98833cd451f6741746c4a45574b63694852755566696a514e75445855446a70516e5747501f6173426d5756434b6544484d685764485a5564666964486d4a6b735148784d00060606040606040607c13875b7536c22ed5b4707d1d7dbd73e9280265b91aa713bcf2df7d70858861419796541435a77727378745a704f4f416f5068736a74667348771d4766514c4b55645470626c554b43664d6c794f6f56536979794c4a7033000772b8a8f7acf89b1ffa6043823639964c2c4fb29dde3dcd31978d683c80bd78800a63746c4d4f5a4d7969570152000607b55a0e54cf8dcee8e9e27437e8f2929c37b94dc20fd72990e37a85821c8a16de0b616c5075425a6d74724f31055061534f36000307ada65994413d125ec33dc34f2a62f2f2986ccb62d5e160f2fb25e94d9cd9749c216479774e7a69736c58504b5a44564e527756467656784e744145616b705a43413921656a704b6c594f6553614d587870715a50706c6c716f677064414a7578474469370006060106202668a664c7fad55058031e203958245f64db890d4f1513073cb47e0226f5201001000820cd5eee30144faa089213c4403e92b659010110791cbe62acfb65f2394f99eb97e3341775d8db0ddc055955af929adfbe3bd04f6a1add53ca621be729002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444029dce6d6ca09eddb82934807195e6bf2862a590f649f07b289245c1ce8b6de52ad6225c3a8e86d11b83d3886c0efc936f21bf357ca8b3a2243d8ae62ea4b5909", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4fa1eaf15b0f81e467b4cbe49cf2c8780d01b499c6da1faa3b6d309fc9a76293", - "sequence_number": "3325178443860027294", + "sender": "354dd7953f0fc33c7ef8204fc900510ed78b156b0a55e88332e92d3f3d95a2f3", + "sequence_number": "2864957607836685553", "payload": { "EntryFunction": { "module": { - "address": "c00471a90ad2ce3021246a88795657b0da59c4b3e623d8c57c5677dc6662cf32", - "name": "qlgdIJEugBiyhKRQ_Coin" + "address": "312a14bf8383fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c35", + "name": "IznGG_Coin" }, - "function": "MD", + "function": "RiAQTAkPYIqHIxVG", "ty_args": [ { - "struct": { - "address": "2e2da2a03f8e2c8e6297a4a98833cd4564410accf28d893c63f800b67f3d337e", - "module": "JMTyBajvpQQHbARI7", - "name": "kvUjzWs", - "type_args": [] + "vector": { + "struct": { + "address": "94b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4e03c", + "module": "XPxSjBQh5", + "name": "RuBoJhQTIlZmXbWbaWlbK", + "type_args": [] + } } } ], "args": [ - "60ccb306bf7c1d9e126032fc76ddb8e097e3a67e0bb9a8b453f269792c9bdca3" + "aca8e198557f904c28232a424c3d439c4eec3ea3011bd28bb915afebbf49920b", + "01", + "ed0d14a2e5d2cd7f9bcfbf483f8b3860e5db9e3f2f281ed86fad3e3d1905d6ce", + "b0a99207e9583e6be46e07ca411ecab3f8ddf6c09a6487e691fbbd6038ec3fea", + "9b1891fd8c6a1a43", + "9c" ] } }, - "max_gas_amount": "10423124090295223446", - "gas_unit_price": "14332818859078417237", - "expiration_timestamp_secs": "12447827346449393986", - "chain_id": 150 + "max_gas_amount": "448815171824525478", + "gas_unit_price": "6840996711809809708", + "expiration_timestamp_secs": "10116137999700805261", + "chain_id": 179 }, - "signed_txn_bcs": "4fa1eaf15b0f81e467b4cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2710592d68252e02c00471a90ad2ce3021246a88795657b0da59c4b3e623d8c57c5677dc6662cf3215716c6764494a457567426979684b52515f436f696e024d4401072e2da2a03f8e2c8e6297a4a98833cd4564410accf28d893c63f800b67f3d337e114a4d547942616a76705151486241524937076b76556a7a577300012060ccb306bf7c1d9e126032fc76ddb8e097e3a67e0bb9a8b453f269792c9bdca39604ddd32260a690557b6355d066e8c64269822a0591bfac96002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407c2cde35d5c24b5af2630ddde85ce53116def16d99a12e81d119960f2bab0c293b7ab13ec692858eb7df6c3e8badff421701fc797f3ba6ed9de971fd04a4320b", + "signed_txn_bcs": "354dd7953f0fc33c7ef8204fc900510ed78b156b0a55e88332e92d3f3d95a2f3f194a8dfc35fc22702312a14bf8383fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c350a497a6e47475f436f696e105269415154416b50594971484978564701060794b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4e03c09585078536a42516835155275426f4a685154496c5a6d5862576261576c624b000620aca8e198557f904c28232a424c3d439c4eec3ea3011bd28bb915afebbf49920b010120ed0d14a2e5d2cd7f9bcfbf483f8b3860e5db9e3f2f281ed86fad3e3d1905d6ce20b0a99207e9583e6be46e07ca411ecab3f8ddf6c09a6487e691fbbd6038ec3fea089b1891fd8c6a1a43019ca620685605833a062cfd09a5431af05e8d46ffc2e9bd638cb3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444034137d48f8d42c3ec742c720ad099c99ef05e04c6018c2bca46f0c428769fdd755b9eabc715fcec96846316cff06f63190ea0452f182226b7538fa3730bd9a0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d319349dcf971010e7113bda5c031175578b3bbe2eda398c0e18862f020f1fb6", - "sequence_number": "16355829892650573629", + "sender": "60d43edaec47a76c61563172716510ff00712d18fad0fbdbe2e8582ff35305ca", + "sequence_number": "6489623314579479024", "payload": { "EntryFunction": { "module": { - "address": "a718056473adfb04ec9139895bf4f55dad151685acf6174c740ad7f68d7ee85c", - "name": "fyh_Coin" + "address": "0809d65751bd28f265563f72871e06ce1a888171a043a5f8328ecbb460a5d092", + "name": "TtQwbhhfvYfWK_Coin" }, - "function": "lnWZptEMukyevSdrxJy", + "function": "JgnNCt", "ty_args": [ - { - "vector": "signer" - }, { "struct": { - "address": "c1a8e819a8e4aa0dda41456cc7e4d2f4f6545b2e49eb4a3ed0c704d7013202d6", - "module": "TTd0", - "name": "GdqnNNmNjK", + "address": "bf93e0f58fb532efa1e07b525df228136a15933fa00872c1b1619d431d4b3be4", + "module": "Pa2", + "name": "dzDZcOG9", "type_args": [] } }, { "vector": { - "vector": "u128" + "struct": { + "address": "63bb31fa316c4556eadbacef93d38887184e46dbfe9d696030bfe61e87e035d4", + "module": "WuxVyqGjGCCsDqxbuWnEF5", + "name": "sGFnoJI", + "type_args": [] + } } } ], "args": [ - "c1efc268c0a0757d", + "9ce2f43e3a6c246e", + "8364c91fc7fed6c6167e463ea03a1964", + "d0", + "adfc2cdf74966aac", + "6d7885c7382f1d49179f9c14d8e7e192", "01", - "742834f586d97ec4417492bea1c27453", - "9c", - "4f", - "8e", - "40ad278eb9c296b9" + "5a235e716b20f369e49fa939ce1565af", + "1b" ] } }, - "max_gas_amount": "12255823520549005536", - "gas_unit_price": "8935819560039374055", - "expiration_timestamp_secs": "13068481333707491606", - "chain_id": 235 + "max_gas_amount": "1391072344350889424", + "gas_unit_price": "17452982293095219306", + "expiration_timestamp_secs": "12165991714004765251", + "chain_id": 208 }, - "signed_txn_bcs": "d319349dcf971010e7113bda5c031175578b3bbe2eda398c0e18862f020f1fb63d1f2766a194fbe202a718056473adfb04ec9139895bf4f55dad151685acf6174c740ad7f68d7ee85c086679685f436f696e136c6e575a7074454d756b796576536472784a7903060507c1a8e819a8e4aa0dda41456cc7e4d2f4f6545b2e49eb4a3ed0c704d7013202d604545464300a4764716e4e4e6d4e6a4b000606030708c1efc268c0a0757d010110742834f586d97ec4417492bea1c27453019c014f018e0840ad278eb9c296b9e06833cc8e6e15aae75c22bd8b68027c1649758188925cb5eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400c7ca504f28cc13f65585043f881daed1109c51c76bd85290a353279da27d30da3885d550e776f1b330126f97aa54758ad83485c2102539d8a27b4dba77fca05", + "signed_txn_bcs": "60d43edaec47a76c61563172716510ff00712d18fad0fbdbe2e8582ff35305caf0599a6705c60f5a020809d65751bd28f265563f72871e06ce1a888171a043a5f8328ecbb460a5d092125474517762686866765966574b5f436f696e064a676e4e43740207bf93e0f58fb532efa1e07b525df228136a15933fa00872c1b1619d431d4b3be40350613208647a445a634f473900060763bb31fa316c4556eadbacef93d38887184e46dbfe9d696030bfe61e87e035d416577578567971476a474343734471786275576e454635077347466e6f4a490008089ce2f43e3a6c246e108364c91fc7fed6c6167e463ea03a196401d008adfc2cdf74966aac106d7885c7382f1d49179f9c14d8e7e1920101105a235e716b20f369e49fa939ce1565af011bd095e74ded144e136a801ffbec7235f2438a99750149d6a8d0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dda7f1fb6c7c9bd6177dcbb30c26a892e9e3174d098a469c76cc9d25ab51556344d69efd4e77ee6f3b8f4365ddd9525baf34e9f01b306d529757fdc8dfdb0707", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "14d1709d0a4fdec719078a3f6fa4eb632378999f8d87165de109d2fc8e77910c", - "sequence_number": "11542562776416229157", + "sender": "492567b13ed379b192567070f7c5adbb2957241a917f32abe7142d12aa75d23c", + "sequence_number": "14636393335272218835", "payload": { "EntryFunction": { "module": { - "address": "b5c612ed124cecb353449912b21dc34c2d922dfecc9062319cd6ae301e4985a0", - "name": "mISNsySdaVlNfrolHRMHkZ_Coin" + "address": "6c7f2df2c745ff6f47dde5d68d5dc89970ea4f337b52813b0d42763ab190b9a4", + "name": "ej_Coin" }, - "function": "sRZTCcuoUHpNmpHvaz", + "function": "wsys3", "ty_args": [ { "struct": { - "address": "49a20934f5f6a3f2e77fa30cb7552aa055002455ac7887cd01ee9682367b89ba", - "module": "iegkYKJurYIbuTNCokjqVihVyamUs7", - "name": "wUmrnrMDSqmpetuz", + "address": "3fe267f463455d2e22feee79d2a1a0f76b400e774dce70f577a7dbe12b50e440", + "module": "qnGtoWTmMmrWitlJwHzobdBwLJttlV", + "name": "nDAdBeTZrsIZWVzTzRLMXwPhLFMSxl8", "type_args": [] } - } - ], - "args": [ - "775f24314cd492fa818f5c0ad0dfcf0cc90739acd9f8c83079ac3997d582d64e", - "af929adfbe3bd04f", - "2a", - "0bda45c718f002ab14fd1e73ecf5afba", - "10", - "2dbe444f4bdddbfe", - "63", - "619494b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4", - "4aab1dc471b6d5028a471eba3270728a1022a1e87da7337d3457dc9188e27385" - ] - } - }, - "max_gas_amount": "5154745630719927855", - "gas_unit_price": "17208755434787040077", - "expiration_timestamp_secs": "10124569666660383901", - "chain_id": 48 - }, - "signed_txn_bcs": "14d1709d0a4fdec719078a3f6fa4eb632378999f8d87165de109d2fc8e77910c2597efa5b06b2fa002b5c612ed124cecb353449912b21dc34c2d922dfecc9062319cd6ae301e4985a01b6d49534e7379536461566c4e66726f6c48524d486b5a5f436f696e1273525a544363756f5548704e6d704876617a010749a20934f5f6a3f2e77fa30cb7552aa055002455ac7887cd01ee9682367b89ba1e6965676b594b4a757259496275544e436f6b6a715669685679616d5573371077556d726e724d4453716d706574757a000920775f24314cd492fa818f5c0ad0dfcf0cc90739acd9f8c83079ac3997d582d64e08af929adfbe3bd04f012a100bda45c718f002ab14fd1e73ecf5afba0110082dbe444f4bdddbfe016320619494b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4204aab1dc471b6d5028a471eba3270728a1022a1e87da7337d3457dc9188e273852fe68e12d75589474deb0d5de4c7d1ee9dbcfc3478b2818c30002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406d589dfb72349139fbd8b7d11ce7b801d91251afc7591698e88827a3e9a2cc65b916595e3fa920fa6a6d03672f0f4168e9bca926ffdec4bdbae2f45a90666209", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "bfe0032d7fc34b8baf3acb7b4eea1f1565e5e302d5e8c5ce8512fee729815ca6", - "sequence_number": "3684526055655899207", - "payload": { - "EntryFunction": { - "module": { - "address": "dd8efb47376dbe66089602d544872340e34d46c13f7ed03bc7df3513c96a5c50", - "name": "TLFd6_Coin" - }, - "function": "UOePmmGAIHRQGQJqFap", - "ty_args": [ + }, { "struct": { - "address": "e5db9e3f2f281ed86fad3e3d1905d6ce996b7cbb84f33ff4899ff91f69adac42", - "module": "B", - "name": "kXDeRdRbKIADaUgCtpNTAJGapi3", + "address": "1117a28be7ed602d0daf4a1158d458f999eee81d99b632e0679b7092e5488b27", + "module": "VcHQXDuysQgsq5", + "name": "Jpu", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "9038d084aa172347d445783d1de45fa58122a89624730e8a5287798f57896db8", + "module": "GoUQLEsADgwbXwMQAALWePD0", + "name": "wyHwLvIkrpEmxwToVeWH8", + "type_args": [] + } + } + }, { "struct": { - "address": "75a3024e99693a53a050cb08d16bc51bed64f2707c1a9a323097d017f45b5bc2", - "module": "gCifNWMXtfHcfaFdDZjDQosPx8", - "name": "PzvzhxBEPhYTGJ", + "address": "5d12df7dfdf9d8a552a1d1650ccfa429a0722f4f4df371439053bc9c80fb9017", + "module": "UIaQEjLkNqSlhrnerWmjOy", + "name": "cravXgxrTlSQNaRIhcppBY2", "type_args": [] } }, + { + "vector": { + "vector": "signer" + } + }, { "struct": { - "address": "6c3beb3be280e492256bab9767bd1edf64cc9b01b2e256c4f203c4e763bf2b78", - "module": "WxTwlvSBQUbAjtWQzsMppKa0", - "name": "TPbzAtqYFzcwoRmmKCdkyRA", + "address": "421d3d059d947c2cbe789fdeeb4d71acac26107eb686b8b2c791f746b84254d5", + "module": "ObWPfj", + "name": "xVqksRecTlGsCQPtfTGPBr", "type_args": [] } }, { "struct": { - "address": "2f97e4f66013d60144d835e8be906b57a42dd881c1967c7677f72c4ff61e24b1", - "module": "dn1", - "name": "kbsPrTMMAUgJQZyme", + "address": "e19be0aea40f644987357b0ec30c015d20f31cda3d8e162e2346ab4ca121b5f0", + "module": "JUdhlnBTjjiNhYMaYpZM", + "name": "KRXQ7", "type_args": [] } } ], "args": [ - "01", - "6ea0b2bac0c163305ab801bb22084cca", - "c51ce27535f007e05e6fe75df344de4c7a1a32e3ff229d491e46e5fcdfdb7645", - "6814468c56caf5531382bf6e9212d6d5", - "618ed1ea36ab3163", - "00", - "c931e1d04152128975fdd2558957eeeb0c0b0d93cf687a2a80c5e741a9868a0d" + "528bccfa87b00e933770391a8bcc6ac1", + "d369bf1deb4502d9315a1b59c635e2c66fd86490622f1c3fac64b4c3c6aa2c0b", + "c35780147370001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999", + "8924290c2bd07b38562b13c2c956e8f4725d55c47949e24542b29757537c4639", + "691742bc128ece0784313e9831e14aa2", + "9b22f9e25de41a99bde0e2c13cffab90", + "55c3e3b69632f652", + "9ddf9d56cec575aeb2ecf11ee80033a1", + "80c97183b15bb9df", + "9dd777f326759cce" ] } }, - "max_gas_amount": "15810533055880728804", - "gas_unit_price": "8160813382947086470", - "expiration_timestamp_secs": "3922053241510363826", - "chain_id": 34 + "max_gas_amount": "6912783674791583668", + "gas_unit_price": "5859368504772063319", + "expiration_timestamp_secs": "6933156099596175073", + "chain_id": 206 }, - "signed_txn_bcs": "bfe0032d7fc34b8baf3acb7b4eea1f1565e5e302d5e8c5ce8512fee729815ca647800a19ed10223302dd8efb47376dbe66089602d544872340e34d46c13f7ed03bc7df3513c96a5c500a544c4664365f436f696e13554f65506d6d47414948525147514a714661700407e5db9e3f2f281ed86fad3e3d1905d6ce996b7cbb84f33ff4899ff91f69adac4201421b6b584465526452624b4941446155674374704e54414a4761706933000775a3024e99693a53a050cb08d16bc51bed64f2707c1a9a323097d017f45b5bc21a674369664e574d587466486366614664445a6a44516f735078380e507a767a6878424550685954474a00076c3beb3be280e492256bab9767bd1edf64cc9b01b2e256c4f203c4e763bf2b7818577854776c765342515562416a7457517a734d70704b6130175450627a41747159467a63776f526d6d4b43646b79524100072f97e4f66013d60144d835e8be906b57a42dd881c1967c7677f72c4ff61e24b103646e31116b62735072544d4d4155674a515a796d6500070101106ea0b2bac0c163305ab801bb22084cca20c51ce27535f007e05e6fe75df344de4c7a1a32e3ff229d491e46e5fcdfdb7645106814468c56caf5531382bf6e9212d6d508618ed1ea36ab3163010020c931e1d04152128975fdd2558957eeeb0c0b0d93cf687a2a80c5e741a9868a0de49057e90b4c6adb86a0d0b088084171b20265aaa4ee6d3622002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444053d263dedb7fffb975d3dd64d32c4288e929bcaa05910b6ed40822e896209cb2b6ab73cc630b329eaf213f0ac4e62e8a5f3e93918633f75025c3f9eabc0f9f0b", + "signed_txn_bcs": "492567b13ed379b192567070f7c5adbb2957241a917f32abe7142d12aa75d23cd3a0cb0531ea1ecb026c7f2df2c745ff6f47dde5d68d5dc89970ea4f337b52813b0d42763ab190b9a407656a5f436f696e05777379733307073fe267f463455d2e22feee79d2a1a0f76b400e774dce70f577a7dbe12b50e4401e716e47746f57546d4d6d725769746c4a77487a6f626442774c4a74746c561f6e4441644265545a7273495a57567a547a524c4d587750684c464d53786c3800071117a28be7ed602d0daf4a1158d458f999eee81d99b632e0679b7092e5488b270e5663485158447579735167737135034a70750006079038d084aa172347d445783d1de45fa58122a89624730e8a5287798f57896db818476f55514c4573414467776258774d5141414c576550443015777948774c76496b7270456d7877546f566557483800075d12df7dfdf9d8a552a1d1650ccfa429a0722f4f4df371439053bc9c80fb90171655496151456a4c6b4e71536c68726e6572576d6a4f79176372617658677872546c53514e615249686370704259320006060507421d3d059d947c2cbe789fdeeb4d71acac26107eb686b8b2c791f746b84254d5064f625750666a167856716b73526563546c4773435150746654475042720007e19be0aea40f644987357b0ec30c015d20f31cda3d8e162e2346ab4ca121b5f0144a5564686c6e42546a6a694e68594d6159705a4d054b52585137000a10528bccfa87b00e933770391a8bcc6ac120d369bf1deb4502d9315a1b59c635e2c66fd86490622f1c3fac64b4c3c6aa2c0b20c35780147370001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999208924290c2bd07b38562b13c2c956e8f4725d55c47949e24542b29757537c463910691742bc128ece0784313e9831e14aa2109b22f9e25de41a99bde0e2c13cffab900855c3e3b69632f652109ddf9d56cec575aeb2ecf11ee80033a10880c97183b15bb9df089dd777f326759cceb45f12712024ef5f57f00c5f9ca85051e146c338bd843760ce002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407da102626f65c2e6a73b7a35c4e39c071b402a1c63c8e9cdd07a0d3f0ec9831d6c446f05d329182bb736d31c88cb8d3f9e0ea1f7423461b5df6322b68ed4a204", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "2fbe7ae7760b38b0a4ccd59f2b07ab56d6138a21ea8de2856bb1becd82d5b321", - "sequence_number": "9471573047067652990", + "sender": "30a66c870e97f22763f0c837598a470d21566b0eff14be6570929b5381631cd9", + "sequence_number": "4817647060128806984", "payload": { "EntryFunction": { "module": { - "address": "7e7bacf6750ee1e3e6dd6a9084153ad37bb65e296503be693439155d12df7dfd", - "name": "WxvQYSdcHrNrVsNrCsfhQakHLomQ9_Coin" + "address": "c2612a1f7a9413f5638132c912abfb41924a9109646168993d46b1d3025d0c0d", + "name": "TavNIFyhawqprRZUTGZNcNr_Coin" }, - "function": "uHxYd2", + "function": "FzNaOeJWTMThcpVBuHSkFDlclTGHlCuy6", "ty_args": [ + { + "vector": { + "vector": "signer" + } + }, + { + "struct": { + "address": "a7c25eefc894af8a6d08aa0414c6ec1ffb0067dbce3042ddde3de8e7f446ef0b", + "module": "vCxqhfDYsNNkaePQxUyxYKnvcSkniIw9", + "name": "HhnMucFftZFCgasJItBRynwiOpNffP3", + "type_args": [] + } + }, + { + "struct": { + "address": "9aeb11623d06469bfa9d4105adb6d5a77f41ea276a0f3718d7e1a49e1cc85eb6", + "module": "duXGEGGcE8", + "name": "NKsxjitSJGAzgc6", + "type_args": [] + } + }, + { + "struct": { + "address": "b2b656d832c731d3fbbf776898a9b533b90bc1d7f8e40d0d302a8199f1636f75", + "module": "SU4", + "name": "nTrRqOfARJyyKruXqEg8", + "type_args": [] + } + }, + { + "struct": { + "address": "1d3b523f593d92fc1ea05c250f866b0d02b054c4c5d35dde5b04e146af6204b4", + "module": "icBSXHIjStq3", + "name": "fjUTTFiPXqHZXGJxDYReIEthNFv1", + "type_args": [] + } + }, { "struct": { - "address": "cafd9ba4993d61b5b2536f750432561fa6dfbb6f09243917aab3313f84af664f", - "module": "ZRpt", - "name": "xAtOWbTKB6", + "address": "b405d488629dc647194ebcf8f06ca89ed4f83c97e4637ebee04ab5591d66bfe8", + "module": "envARKRxGvHylk", + "name": "wbPZlfdtELatVySeJthAK", "type_args": [] } }, { - "vector": { - "struct": { - "address": "6fc27b6af2cc8959cbad7a02df83b8a1d5107714ce8789806c232f3078efc51e", - "module": "XXxdomxpNcXZzOzqUFnLBKhbOKex", - "name": "oFudvyNbzdLRpYblLbZdjKpqQ1", - "type_args": [] - } + "struct": { + "address": "fb0bfeed94b942ed153a736d16ad284fabb0d85ee448a5e2fd3284f656cf85fd", + "module": "CZXltTquuEjgDyYarjjmrgk7", + "name": "JTLywcx9", + "type_args": [] } } ], "args": [ - "001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999605b9ea506bd", - "0aaa91074ed2ee54", - "8efc2b679f7322aa7e3e35e868b61f6a", - "00bc42870524aae445d2d35e27ee5cdd02a35a69825dce3122b679f8bac44f82", - "b5eee2ac8b424b18", - "01" + "a1764262e6ce89af", + "00", + "5ce7a217b8389cfd2044f39eba055ee0328567d3a45dccffbc9b7ff8d7fa74e3", + "01c8a787912ac553", + "a45d8408e13e1a521920610294357583157d56b9a237ea1f90dbd7f06c21c2de", + "95c928d7c9b016bd43eac70439d2b15b", + "7922cb9f56f80860", + "a7db9f0d3c934240a9d8cfcc18966e6121a2dd8837adb0e9464ddb015029b627", + "00", + "99378115017b46d22ebb103ebf6ecb441e4f183f7d7a976c817fd32fb6756576" ] } }, - "max_gas_amount": "198408076994411574", - "gas_unit_price": "3960752392244391960", - "expiration_timestamp_secs": "16631222935716715441", - "chain_id": 195 + "max_gas_amount": "13115879407401372479", + "gas_unit_price": "15731584257188240775", + "expiration_timestamp_secs": "12959156708318052505", + "chain_id": 108 }, - "signed_txn_bcs": "2fbe7ae7760b38b0a4ccd59f2b07ab56d6138a21ea8de2856bb1becd82d5b3217eb3a1f680c97183027e7bacf6750ee1e3e6dd6a9084153ad37bb65e296503be693439155d12df7dfd22577876515953646348724e7256734e724373666851616b484c6f6d51395f436f696e067548785964320207cafd9ba4993d61b5b2536f750432561fa6dfbb6f09243917aab3313f84af664f045a5270740a7841744f5762544b42360006076fc27b6af2cc8959cbad7a02df83b8a1d5107714ce8789806c232f3078efc51e1c585878646f6d78704e63585a7a4f7a7155466e4c424b68624f4b65781a6f46756476794e627a644c527059626c4c625a646a4b70715131000620001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999605b9ea506bd080aaa91074ed2ee54108efc2b679f7322aa7e3e35e868b61f6a2000bc42870524aae445d2d35e27ee5cdd02a35a69825dce3122b679f8bac44f8208b5eee2ac8b424b18010136fcd14518e3c002187001d7506bf736b15bb9df24f9cde6c3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406bc88fa984140a2cbe17bf8e81862e6df702c5874614dd941e9865a570fcdb0bead3bb46bf6165bf6ea2434bbef28d1c65cf7258a19706d80e6191f34c82ea0a", + "signed_txn_bcs": "30a66c870e97f22763f0c837598a470d21566b0eff14be6570929b5381631cd948b82ee879b8db4202c2612a1f7a9413f5638132c912abfb41924a9109646168993d46b1d3025d0c0d1c5461764e494679686177717072525a5554475a4e634e725f436f696e21467a4e614f654a57544d5468637056427548536b46446c636c5447486c437579360706060507a7c25eefc894af8a6d08aa0414c6ec1ffb0067dbce3042ddde3de8e7f446ef0b207643787168664459734e4e6b6165505178557978594b6e7663536b6e694977391f48686e4d75634666745a46436761734a49744252796e77694f704e6666503300079aeb11623d06469bfa9d4105adb6d5a77f41ea276a0f3718d7e1a49e1cc85eb60a647558474547476345380f4e4b73786a6974534a47417a6763360007b2b656d832c731d3fbbf776898a9b533b90bc1d7f8e40d0d302a8199f1636f7503535534146e547252714f6641524a79794b7275587145673800071d3b523f593d92fc1ea05c250f866b0d02b054c4c5d35dde5b04e146af6204b40c696342535848496a537471331c666a5554544669505871485a58474a7844595265494574684e4676310007b405d488629dc647194ebcf8f06ca89ed4f83c97e4637ebee04ab5591d66bfe80e656e7641524b5278477648796c6b157762505a6c666474454c6174567953654a7468414b0007fb0bfeed94b942ed153a736d16ad284fabb0d85ee448a5e2fd3284f656cf85fd18435a586c7454717575456a6744795961726a6a6d72676b37084a544c7977637839000a08a1764262e6ce89af0100205ce7a217b8389cfd2044f39eba055ee0328567d3a45dccffbc9b7ff8d7fa74e30801c8a787912ac55320a45d8408e13e1a521920610294357583157d56b9a237ea1f90dbd7f06c21c2de1095c928d7c9b016bd43eac70439d2b15b087922cb9f56f8086020a7db9f0d3c934240a9d8cfcc18966e6121a2dd8837adb0e9464ddb015029b62701002099378115017b46d22ebb103ebf6ecb441e4f183f7d7a976c817fd32fb67565763f0b0583d4f604b6871dd54b88d051da9900eb9b5d2cd8b36c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444088daaf4c40016b31dd0d7180abb5351e809c37883569291a0a2b873823b73969c78793fa20344e79d51ea3a5aa2bf8bfb4880d7ef24054f7b5dd7a772e352e06", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998c2", - "sequence_number": "7951721077400340342", + "sender": "0a2262bb2f4e032573f2d9ab6de5df370cc48123983feb870212094955c8b5c1", + "sequence_number": "4243155741195374353", "payload": { "EntryFunction": { "module": { - "address": "5cbd1aa3eeba7a5e428a714043a4b13ca82265914e147818030ce0e49d264925", - "name": "XDkgnRjAJCzPqQFH1_Coin" + "address": "34ac0434f14c56a1a0cee12af501b57c72df3440e8a19a194d7bff0b62cf7ee3", + "name": "XrEQiVNhRaOcsUoTqFeDyQV_Coin" }, - "function": "ZPwNcAjWPEADYWJYc", + "function": "XCHUHvfKbmuQXWphJjpplR", "ty_args": [ { - "struct": { - "address": "2b90214d86e51df6cf0a639a709ebe86b0cb9bc15c68add36f2d67becb3caf07", - "module": "qALDMGXIYDVAkWkTbeA", - "name": "FOPUgbAgNZmIkTPvkCTHskKQdpsBgzIn2", - "type_args": [] + "vector": { + "struct": { + "address": "4681de2a3f39b54f3e610f143d7c741fd6f36eb6f1d4fe8d9a69df2c50ec4b8d", + "module": "ACEHnbUHMFXeif", + "name": "EecXlTcyY", + "type_args": [] + } } }, { "struct": { - "address": "3691b97ab24f3fe6a34204155f1d9d4836e4d88e6b9238f0c67b26f8f0283ac5", - "module": "oIqnybC7", - "name": "abYsvnDujPcdXx", + "address": "bfb1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998", + "module": "kgcivZwUhImVFmzoWHsvJa", + "name": "XpfsRRkEiHRpAIayFLyt5", "type_args": [] } }, { "vector": { "struct": { - "address": "cf6bf4769f1b6fb0d6e79aa700fa708dc44ec4d8f828b3f8b0a9a6d5eb330495", - "module": "DKSnx5", - "name": "ckfzGcRFcIuuUZgtAZ9", + "address": "9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d43dd3f5e36efe4f", + "module": "DpvqYqvvTh", + "name": "ghAhOongPMYY", "type_args": [] } } }, { "struct": { - "address": "d35dde5b04e146af6204b46fea5cf36501aae42ce3e5d809499513236e3bdfe9", - "module": "NRpwKPFwpzS3", - "name": "xKBGeXMNXiYpgnOruFDGpFnIsKsTQW", + "address": "74b2a474485adcc985746579ebbe7e40d49d19f9b7863705bb973fc9b5966400", + "module": "AcDIVHdwdAVPmqYYvAgdhUDty2", + "name": "RxQHHSYmyi", "type_args": [] } }, { - "struct": { - "address": "dd69e6a90ec6bc8e27395ebd7a0110acd93d862347fd90fcc59799616ec8fb41", - "module": "f", - "name": "jyiDTAqeNlwdCJgTGKjeJUwLDgSmu", - "type_args": [] + "vector": { + "struct": { + "address": "d09e9d2e6928acc9e3ce3c48c553b45e21ac70d241900e14734cff89f4a6d19d", + "module": "CSIgifIuXKYhc", + "name": "uhMZIHZnvYLmjfnUNHoxvKYKwXypZmG", + "type_args": [] + } } }, { "vector": { - "struct": { - "address": "5933607ca9b10061e97625fa20257723d0a57b5a3597e350cd3c9b3af6ab21d7", - "module": "vzvLvz2", - "name": "SIDHFKrgyYErC3", - "type_args": [] + "vector": { + "vector": "u8" } } }, { "struct": { - "address": "38c53f54d822e4addbf8b0484444705300fe931b506c5b09d7a50e082d9ce72c", - "module": "QqekmctjfRLLhIdlNQfFqHvMxIU", - "name": "rouyNvoWRKxzjjAu", + "address": "95bd76b70ec10ddb28bcf91af17a6f0ab254970b0f793853e6ccba12f17998ae", + "module": "gwhces8", + "name": "fxCboAZmKvIiSmbVdxTDhmuCBAZZKvu4", "type_args": [] } } ], "args": [ - "3a9baca809c3536d", - "21f4c637e59c71071ab2959eba760800", - "21da719ddf7d658c3de5d2046030ec23e91983a8bbbcf21062e2f4c6e760f864", - "01", - "053883cb99440a99", - "00", - "06", - "01", - "2d126b07b4ab8b3f896efebf190f8e19a7e52277cddc669599be119cd3026ebf" + "3f935df258c0a050", + "01" ] } }, - "max_gas_amount": "12941676234029091198", - "gas_unit_price": "5878499895629654640", - "expiration_timestamp_secs": "17723079372365953068", - "chain_id": 196 + "max_gas_amount": "13394626205725655419", + "gas_unit_price": "10907988120019705214", + "expiration_timestamp_secs": "10076503061810064238", + "chain_id": 191 }, - "signed_txn_bcs": "b1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998c276076f9b30305a6e025cbd1aa3eeba7a5e428a714043a4b13ca82265914e147818030ce0e49d2649251658446b676e526a414a437a5071514648315f436f696e115a50774e63416a575045414459574a596307072b90214d86e51df6cf0a639a709ebe86b0cb9bc15c68add36f2d67becb3caf071371414c444d475849594456416b576b5462654121464f5055676241674e5a6d496b5450766b435448736b4b5164707342677a496e3200073691b97ab24f3fe6a34204155f1d9d4836e4d88e6b9238f0c67b26f8f0283ac5086f49716e796243370e61625973766e44756a5063645878000607cf6bf4769f1b6fb0d6e79aa700fa708dc44ec4d8f828b3f8b0a9a6d5eb33049506444b536e783513636b667a4763524663497575555a6774415a390007d35dde5b04e146af6204b46fea5cf36501aae42ce3e5d809499513236e3bdfe90c4e5270774b504677707a53331e784b424765584d4e58695970676e4f727546444770466e49734b735451570007dd69e6a90ec6bc8e27395ebd7a0110acd93d862347fd90fcc59799616ec8fb4101661d6a796944544171654e6c7764434a6754474b6a654a55774c4467536d750006075933607ca9b10061e97625fa20257723d0a57b5a3597e350cd3c9b3af6ab21d707767a764c767a320e53494448464b7267795945724333000738c53f54d822e4addbf8b0484444705300fe931b506c5b09d7a50e082d9ce72c1b5171656b6d63746a66524c4c6849646c4e5166467148764d78495510726f75794e766f57524b787a6a6a41750009083a9baca809c3536d1021f4c637e59c71071ab2959eba7608002021da719ddf7d658c3de5d2046030ec23e91983a8bbbcf21062e2f4c6e760f864010108053883cb99440a99010001060101202d126b07b4ab8b3f896efebf190f8e19a7e52277cddc669599be119cd3026ebf7e496b87f7119ab3702a2d6b82a094512cf8eccbc906f5f5c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440721c5a5da9c6b68d302251f06c76f880c275fb4eb31f958a43a28e8d6b38bcf25dfb25355f73236aa6acbd132980594e44cb2154b8c99f20290a59597d9c6908", + "signed_txn_bcs": "0a2262bb2f4e032573f2d9ab6de5df370cc48123983feb870212094955c8b5c1110f9c58aab7e23a0234ac0434f14c56a1a0cee12af501b57c72df3440e8a19a194d7bff0b62cf7ee31c5872455169564e6852614f6373556f54714665447951565f436f696e16584348554876664b626d7551585770684a6a70706c520706074681de2a3f39b54f3e610f143d7c741fd6f36eb6f1d4fe8d9a69df2c50ec4b8d0e414345486e6255484d465865696609456563586c546379590007bfb1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998166b676369765a775568496d56466d7a6f574873764a61155870667352526b456948527041496179464c7974350006079ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d43dd3f5e36efe4f0a447076715971767654680c676841684f6f6e67504d5959000774b2a474485adcc985746579ebbe7e40d49d19f9b7863705bb973fc9b59664001a4163444956486477644156506d715959764167646855447479320a527851484853596d7969000607d09e9d2e6928acc9e3ce3c48c553b45e21ac70d241900e14734cff89f4a6d19d0d4353496769664975584b5968631f75684d5a49485a6e76594c6d6a666e554e486f78764b594b775879705a6d4700060606010795bd76b70ec10ddb28bcf91af17a6f0ab254970b0f793853e6ccba12f17998ae076777686365733820667843626f415a6d4b764969536d625664785444686d754342415a5a4b7675340002083f935df258c0a05001017b816afb9045e3b97e9df4f366f560976e2b53a925eed68bbf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3a7068e68bb52765fdf284804f38d324df3af047e9079ea65e1e4d1b68f00eb257bc44b3171900524384c871b21503ec192068355ad72c4671441a0dbba440a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ce52a21f0196c241499e4666394dc8c488300dafa1bca1e189224d248a910f2b", - "sequence_number": "3610790754903159157", + "sender": "cab0ddff7149501cbdaf45dd941ef01d1c27ccc10575ff8818c24e40fac619e4", + "sequence_number": "4867804281556525266", "payload": { "EntryFunction": { "module": { - "address": "ba73e56fb545809fcc90bb8251eb6c593a0dd6e3ee3c578e4f6b99c7a23a6a3d", - "name": "awmoalaKxS_Coin" + "address": "b00315f1122ae8888d442d657343a629a42ce4a82bf902123295eb46da7b1c5f", + "name": "YNsGhawhzbP_Coin" }, - "function": "JbRmqzmJCfhzBsldQAGGeGbK", + "function": "MZcGtQQbegscGijtRV", "ty_args": [ + { + "vector": "bool" + }, + { + "struct": { + "address": "e4414ae7f90379c21800e6302ff6ed0450adb5b2703afb1fb09ca217960bc092", + "module": "sVRKPGOZqCuBDZOPv2", + "name": "tXglVgbybAAoWQOIbpoJ1", + "type_args": [] + } + }, { "struct": { - "address": "5d7a6f55e1ac23d8ac71647c3e0332b14184efad7fb7581e137b30e52574844e", - "module": "vNlciOEczkoOMvtDqHnBtirPOoguq9", - "name": "SmGfvoXkKclaxHG", + "address": "71ca3d62766f01d128c5c221ca5b839beb5e40e2215e17f8bbd97a24cd1f2974", + "module": "iATszaDeU", + "name": "ODYeHGLNx2", "type_args": [] } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "ffd58e54489ab984756871967307bca9d8ec14ffe7771814b7617631470e5889", - "module": "nYEjwcHxWdYusHtRuDkUMvvIsZ5", - "name": "whSWt", + "address": "665df07edd482ce5585a013e01950a843aa0b3fc086014c479135711be86bdca", + "module": "XxyBVXyoLGcBaXJpBFu1", + "name": "NvzYHbaTudPtMNqETyHM1", "type_args": [] } } ], - "args": [] + "args": [ + "dabcec5834f1262f0505a13900382dc6", + "f6" + ] } }, - "max_gas_amount": "18194581930582188789", - "gas_unit_price": "15052774334202349260", - "expiration_timestamp_secs": "4118627564632064333", - "chain_id": 135 + "max_gas_amount": "14179493893931586993", + "gas_unit_price": "17329011313062081753", + "expiration_timestamp_secs": "9271361166066967534", + "chain_id": 175 }, - "signed_txn_bcs": "ce52a21f0196c241499e4666394dc8c488300dafa1bca1e189224d248a910f2b757144900f1b1c3202ba73e56fb545809fcc90bb8251eb6c593a0dd6e3ee3c578e4f6b99c7a23a6a3d0f61776d6f616c614b78535f436f696e184a62526d717a6d4a4366687a42736c64514147476547624b02075d7a6f55e1ac23d8ac71647c3e0332b14184efad7fb7581e137b30e52574844e1e764e6c63694f45637a6b6f4f4d76744471486e42746972504f6f677571390f536d4766766f586b4b636c617848470007ffd58e54489ab984756871967307bca9d8ec14ffe7771814b7617631470e58891b6e59456a77634878576459757348745275446b554d767649735a350577685357740000f5a217e9dd2380fccc863f028132e6d04dc106d8f24d283987002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444076dfc33f53146440679dac22e2dabfe84e92845c01359b33bcfc851ed28b485bcf901bc1ba57a35108de47421bd1dac5f1c0cf5b749338837973e253cd532d0d", + "signed_txn_bcs": "cab0ddff7149501cbdaf45dd941ef01d1c27ccc10575ff8818c24e40fac619e4d2604d0e34ea8d4302b00315f1122ae8888d442d657343a629a42ce4a82bf902123295eb46da7b1c5f10594e7347686177687a62505f436f696e124d5a6347745151626567736347696a74525605060007e4414ae7f90379c21800e6302ff6ed0450adb5b2703afb1fb09ca217960bc092127356524b50474f5a71437542445a4f507632157458676c566762796241416f57514f4962706f4a31000771ca3d62766f01d128c5c221ca5b839beb5e40e2215e17f8bbd97a24cd1f297409694154737a614465550a4f44596548474c4e78320006060307665df07edd482ce5585a013e01950a843aa0b3fc086014c479135711be86bdca14587879425658796f4c47634261584a7042467531154e767a5948626154756450744d4e71455479484d31000210dabcec5834f1262f0505a13900382dc601f6b1d59c0292aec7c4d974cae7f9037df0eee3c5d7db7daa80af002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403e2d3d3fd8f65dfdaaeb215e025307afa91956557164571b8a6e25f28e5f355bd2a2602ca0281d4f3b8e03dffe11715bfcc45eaa29b798019aad2d466b732202", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0e8c46f21816b047fc8966bace7f541eef16a7a6bee6a0fd4a6e829cf0a321e6", - "sequence_number": "4659206246992072591", + "sender": "f74cc696f563eb567d57661870ceca4057ebfe0ff4ab5ccbd5b587bef850464b", + "sequence_number": "12939778027499514379", "payload": { "EntryFunction": { "module": { - "address": "0b24ff24b7d56f4f3e03fc4bca557cbfcc34c4db32463b14e57bd3b5fdb8fbef", - "name": "pDIL7_Coin" + "address": "2697ed4e7559b704bcea855595baefc98a860b8ecd03d0f279f7a04533aa7ff9", + "name": "AIfgtJXvSeXQNw3_Coin" }, - "function": "GwwcpiUSdRI", + "function": "VybeqOJMZMvwCbIWvLpSMjT6", "ty_args": [ - { - "vector": "address" - }, { "struct": { - "address": "a42ce4a82bf902123295eb46da7b1c5fe284e676dbc19864fb6861367625dc5b", - "module": "VaqFOGPiZMbOtpcJWxSfNPR5", - "name": "ollrNoqvRVis", + "address": "634a88493e07d254a007a9d9f82bbe21123b924a1518588841ce72133445f46a", + "module": "zDXHtjXZDoNbmQLBRcQvBgKzaeeVqw", + "name": "ObLtXGSuwLG7", "type_args": [] } }, + { + "vector": "u64" + }, { "struct": { - "address": "64dc905edc981194f03a87d27b9db31d0432ce426f5b50c33603b3bc01a10343", - "module": "KO", - "name": "WeoumtPoVZciPc", + "address": "546d1a4a380bb4bd852df88a79275aa094cef2cfff26679aa148575bd75356c7", + "module": "BiVaYcG", + "name": "PMNoOUUsldPXgN2", "type_args": [] } }, { - "vector": { - "struct": { - "address": "fc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b386b873", - "module": "AMxqxdoPdjWgFcEbIvR", - "name": "mOhnTQOC", - "type_args": [] - } + "struct": { + "address": "6b4b12c36980549b8b46e3b0f34cd61e439cded59c20d933d00a0a655dbc85e3", + "module": "dMMpDZUILRXxwuqnlUK", + "name": "alseWDgdWooHzbZgJLHPwlnAMeILC", + "type_args": [] } }, { "struct": { - "address": "9fd18aa729dd01080d1c8b6b134b3d8e01391334d348aac8b125cc37cae95df6", - "module": "vhktgw", - "name": "MqHcFslclpfBUkRpKxUA7", + "address": "844341c568eafd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1", + "module": "uAHwRiB", + "name": "OiqyNBqpZipwBVFTfmIdwLuh0", "type_args": [] } - } - ], - "args": [ - "00", - "c6", - "fc83e0e343c66479f9c4aa88a835d6d032554b375b7c634a88493e07d254a007", - "b8d16bbdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b8" - ] - } - }, - "max_gas_amount": "7118661719599132610", - "gas_unit_price": "16960348661650773191", - "expiration_timestamp_secs": "13928332283136587354", - "chain_id": 104 - }, - "signed_txn_bcs": "0e8c46f21816b047fc8966bace7f541eef16a7a6bee6a0fd4a6e829cf0a321e68f4f3e6765d3a840020b24ff24b7d56f4f3e03fc4bca557cbfcc34c4db32463b14e57bd3b5fdb8fbef0a7044494c375f436f696e0b477777637069555364524905060407a42ce4a82bf902123295eb46da7b1c5fe284e676dbc19864fb6861367625dc5b18566171464f4750695a4d624f7470634a577853664e5052350c6f6c6c724e6f717652566973000764dc905edc981194f03a87d27b9db31d0432ce426f5b50c33603b3bc01a10343024b4f0e57656f756d74506f565a63695063000607fc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b386b87313414d787178646f50646a576746634562497652086d4f686e54514f4300079fd18aa729dd01080d1c8b6b134b3d8e01391334d348aac8b125cc37cae95df60676686b746777154d71486346736c636c706642556b52704b785541370004010001c620fc83e0e343c66479f9c4aa88a835d6d032554b375b7c634a88493e07d254a00720b8d16bbdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b8c2afe0201e91ca62c754777c3f435feb5a36f6816a604bc168002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440db6178975753b41f5b4dc279c84ab2da3f1105ce8dc8d4d04e480bb0405c85f4e728ed9ab1058ed046575ebefaea73dfb535c8025ae41975aa9f3791ee1b2809", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "fa1ce6f43517981fbd8ce9c94b4f2849b49e93cce01b1fa1c03ebce4708d25fd", - "sequence_number": "4866385425938600464", - "payload": { - "EntryFunction": { - "module": { - "address": "74f1b7cf04ddf45d2bd766981d4c318cd619259627801689ea55719f3b18d883", - "name": "aMFuHUPfAlNbdXOmBBaAoyq8_Coin" - }, - "function": "OhLzBZPpLpqo", - "ty_args": [ + }, { - "vector": { - "struct": { - "address": "df319d7fd6bc20202807cea26b4b12c36980549b8b46e3b0f34cd61e439cded5", - "module": "XkMpomRuBguJiWTpeQXccHge1", - "name": "ORKFDCP3", - "type_args": [] - } + "struct": { + "address": "effd65750ded7861b099f9417bb54921f93bc1688116515269361d8f41eaf246", + "module": "ARhEnTzFOYGVhJNlLvCTFndWbSNcFsp", + "name": "zVkUoniuGWoQjQIPUlRuXazivhqbhl0", + "type_args": [] } }, { "struct": { - "address": "8d213ab978276b6bb46ddc1790add8ba7c625bed6c6732614c246d737814eae8", - "module": "epvBQDHzZXzqhtFQhHJbbnzzCbQHIfZ", - "name": "gdSyqNWeuwLMakZlwfumB1", + "address": "56266aaa086556a9c9163c0e3a88153e94d606033cda298c113c8b275a493df5", + "module": "Gu", + "name": "cqJcMWWlBlytdOdVcJLKgqesI2", "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": { + "struct": { + "address": "8340f78c68620cce098780878ae5d7129c937c0d79946646e4f44d9c91a23bda", + "module": "CqHZGiAEMegPJqDzvupMGPPt1", + "name": "HKDyRGOBqkGlSfGZ", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "182116172a257903006b40325b662364e54857d58a3589807d08ed3e5a43fdb7", - "module": "NhAT8", - "name": "DWOsAElC0", + "address": "4874c01bffac1996c0112fb99371b39e8d624fdf767368547f86be4b8b4f9584", + "module": "HAITlHiF5", + "name": "LYqeaYhREWShwRJWRe4", "type_args": [] } } - }, - { - "vector": "u64" - }, - { - "vector": "address" } ], "args": [ - "8cadb4d640137ae1", - "48", - "7c624463c3815b2285d6cc549e1541259ee3b8c62013c48f20d2b19de28e47a3" + "406fcc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b10", + "01", + "41", + "e0cafc4533a6c19ee9ec1d16898d61dd", + "bca988f3dd4689ab4a4d2ed11e676d1a340404dc24157327a6718c5386958dae", + "922e9354c23a7a4211a2565eeeb8353b", + "8d", + "8a4a6a3f8b937a63", + "ea" ] } }, - "max_gas_amount": "10256266921941942060", - "gas_unit_price": "5359926310300319652", - "expiration_timestamp_secs": "1687112809681852145", - "chain_id": 15 + "max_gas_amount": "1625582528020249607", + "gas_unit_price": "1971200951394293533", + "expiration_timestamp_secs": "2444651526185555232", + "chain_id": 22 }, - "signed_txn_bcs": "fa1ce6f43517981fbd8ce9c94b4f2849b49e93cce01b1fa1c03ebce4708d25fd105235fdc2df88430274f1b7cf04ddf45d2bd766981d4c318cd619259627801689ea55719f3b18d8831d614d467548555066416c4e6264584f6d424261416f7971385f436f696e0c4f684c7a425a50704c70716f060607df319d7fd6bc20202807cea26b4b12c36980549b8b46e3b0f34cd61e439cded519586b4d706f6d52754267754a69575470655158636348676531084f524b464443503300078d213ab978276b6bb46ddc1790add8ba7c625bed6c6732614c246d737814eae81f657076425144487a5a587a716874465168484a62626e7a7a4362514849665a1667645379714e576575774c4d616b5a6c7766756d4231000606010607182116172a257903006b40325b662364e54857d58a3589807d08ed3e5a43fdb7054e684154380944574f7341456c4330000602060403088cadb4d640137ae10148207c624463c3815b2285d6cc549e1541259ee3b8c62013c48f20d2b19de28e47a32c3ff0eb6c94558ea47fb8c39448624af116196529d469170f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444006ba78228b4d5a152834fbfdc5094acd59b7ae431486d49c263c4be4dae95654ee727d6a82ad63097e601af93bdf40df77fd99bd63bcb30288aa00b23a7d640f", + "signed_txn_bcs": "f74cc696f563eb567d57661870ceca4057ebfe0ff4ab5ccbd5b587bef850464b0b6a83e18e5393b3022697ed4e7559b704bcea855595baefc98a860b8ecd03d0f279f7a04533aa7ff91441496667744a5876536558514e77335f436f696e1856796265714f4a4d5a4d767743624957764c70534d6a54360907634a88493e07d254a007a9d9f82bbe21123b924a1518588841ce72133445f46a1e7a445848746a585a446f4e626d514c425263517642674b7a6165655671770c4f624c7458475375774c473700060207546d1a4a380bb4bd852df88a79275aa094cef2cfff26679aa148575bd75356c707426956615963470f504d4e6f4f5555736c645058674e3200076b4b12c36980549b8b46e3b0f34cd61e439cded59c20d933d00a0a655dbc85e313644d4d70445a55494c5258787775716e6c554b1d616c736557446764576f6f487a625a674a4c4850776c6e414d65494c430007844341c568eafd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc10775414877526942194f6971794e4271705a69707742564654666d4964774c7568300007effd65750ded7861b099f9417bb54921f93bc1688116515269361d8f41eaf2461f415268456e547a464f594756684a4e6c4c764354466e645762534e634673701f7a566b556f6e697547576f516a514950556c527558617a6976687162686c30000756266aaa086556a9c9163c0e3a88153e94d606033cda298c113c8b275a493df50247751a63714a634d57576c426c7974644f6456634a4c4b677165734932000606078340f78c68620cce098780878ae5d7129c937c0d79946646e4f44d9c91a23bda194371485a476941454d6567504a71447a7675704d475050743110484b447952474f42716b476c5366475a0006074874c01bffac1996c0112fb99371b39e8d624fdf767368547f86be4b8b4f958409484149546c48694635134c597165615968524557536877524a57526534000920406fcc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b100101014110e0cafc4533a6c19ee9ec1d16898d61dd20bca988f3dd4689ab4a4d2ed11e676d1a340404dc24157327a6718c5386958dae10922e9354c23a7a4211a2565eeeb8353b018d088a4a6a3f8b937a6301ea077cba4fb23a8f161dd7c448d21c5b1b2015e8599c25ed2116002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440038213996f6ac6d9b8df80a8df590c054cf4498ce843bb3cf61a21c31ba4fa90a079dc2bfe9d2e021373a68ffc5ca4558bcf63d2c629c42f982d14fdbdb3530c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "82f68beed585f3951ed855c81c73a11452a1a5792ffabdfc0455f72e2292b91e", - "sequence_number": "3699824623779724405", + "sender": "71a17a1e5cfadfc3a89d87403d44af89a08304a7c53374b7ade00c31ad66cb31", + "sequence_number": "7875611597046967813", "payload": { "EntryFunction": { "module": { - "address": "43839e347b12334f9daadd9277a59eb1d993e013d64949cfa6130768ec9fb1e5", - "name": "xMRoCnSdGtiqwuAOpA6_Coin" + "address": "09b20c3be19714c3b2f0248aa551ae5b3ce70d9a1d1e34c0e27edbb919a0fadb", + "name": "sofWaXYWFHWoOxI8_Coin" }, - "function": "M1", + "function": "TQErrZJaLEJ", "ty_args": [ { "struct": { - "address": "b4bfae6ee033e9890abef9165941ee5eedfff8dff86c67f2797d022844a34970", - "module": "Fe", - "name": "WOWxMCWADjYQavJtJpAuwYTLfIIKCC", + "address": "58b64596a3800d58c66d9847a240666e7286feba5107e73bd1b89ae68f51aab0", + "module": "FOTQHsnNOBnVwONgAGxaFXDV", + "name": "PyglmsiCHCWiDEK2", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": "u8" } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "4e265a636b07bdf8a9ba99dde48a8de36ae6b8718b3719dd10e44b77c7d04c33", + "module": "fVyncLOuGBSAQcGkRHdQgTt", + "name": "scjszwLIlsCxPWYGEM", + "type_args": [] + } + }, + { + "struct": { + "address": "c80c8f0130ae87f45404228ba8991d5c376417e21e0e8a59aff5d15a21134008", + "module": "oWWMZsjoFSJCBJgruEuoofalmLVicWix2", + "name": "mmiBbJaTTBqPcOkCf", + "type_args": [] } }, { "struct": { - "address": "789faa8795f6a412399941a62a50108d994f4ab0e91f6e2e39fdc4067c85f628", - "module": "RL", - "name": "AnfJkabAdyDoGoUGlUoeDmnEvN", + "address": "679be46377eabe7953210a122cd5ea4efe7ae87ed30908d872705191629a4a46", + "module": "p8", + "name": "cgPAteXloXjENywDY", "type_args": [] } }, { "vector": { "struct": { - "address": "8ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad65999a0dcfe064ab99e57", - "module": "nIwTPAZjAqsjtdHSSFoKoeJpnTM6", - "name": "USSUYOWRbONvbDhqTqmLmDshMAH1", + "address": "74062fc5d7a8cc14858d26574079750f5982c234665439d0d5a7a18b5d88fb3c", + "module": "WmgQxbThhJlfEwCx8", + "name": "ExU", "type_args": [] } } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "f956e94f8c8046facd52563dec88a1bcd5d912dba915e7f872a3dead61b1f7d2", + "module": "ZsduSSeXnZPoLeR", + "name": "LKP", + "type_args": [] } }, { "vector": { - "vector": { - "vector": "u128" - } + "vector": "address" } - }, - { - "vector": "u64" } ], "args": [ - "bd57e52673b0595a" + "01", + "01", + "1511671db1768e5eafff115bcb72ecdbcc90cb61682cd771035b8e43c88fcca8", + "69e45e0f0aa236b0642a91745c1f21ea", + "e2", + "ac" ] } }, - "max_gas_amount": "14496145507148609802", - "gas_unit_price": "17594285429741085772", - "expiration_timestamp_secs": "1644132714284548029", - "chain_id": 148 + "max_gas_amount": "14656695364758413523", + "gas_unit_price": "6834853282014549520", + "expiration_timestamp_secs": "11294346160195837226", + "chain_id": 126 }, - "signed_txn_bcs": "82f68beed585f3951ed855c81c73a11452a1a5792ffabdfc0455f72e2292b91e753ca28fe46a58330243839e347b12334f9daadd9277a59eb1d993e013d64949cfa6130768ec9fb1e518784d526f436e5364477469717775414f7041365f436f696e024d310807b4bfae6ee033e9890abef9165941ee5eedfff8dff86c67f2797d022844a349700246651e574f57784d435741446a595161764a744a7041757759544c6649494b43430006060006060507789faa8795f6a412399941a62a50108d994f4ab0e91f6e2e39fdc4067c85f62802524c1a416e664a6b6162416479446f476f55476c556f65446d6e45764e0006078ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad65999a0dcfe064ab99e571c6e49775450415a6a4171736a7464485353466f4b6f654a706e544d361c55535355594f5752624f4e766244687154716d4c6d4473684d414831000606050606060306020108bd57e52673b0595a0ab9f7ed88a72cc94c648c3c61752bf4bd7f871efe21d11694002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e0a4e39c294f8472afec510aa24006fe7a0fcc7ebb026907c009f0f5a3eb7887b71b8be7a7af4a2915c43d76b10598565f925b5772a756f49d48ea0a5d7a140d", + "signed_txn_bcs": "71a17a1e5cfadfc3a89d87403d44af89a08304a7c53374b7ade00c31ad66cb31056eee4e05cb4b6d0209b20c3be19714c3b2f0248aa551ae5b3ce70d9a1d1e34c0e27edbb919a0fadb15736f6657615859574648576f4f7849385f436f696e0b54514572725a4a614c454a080758b64596a3800d58c66d9847a240666e7286feba5107e73bd1b89ae68f51aab018464f545148736e4e4f426e56774f4e674147786146584456105079676c6d7369434843576944454b3200060601074e265a636b07bdf8a9ba99dde48a8de36ae6b8718b3719dd10e44b77c7d04c33176656796e634c4f75474253415163476b524864516754741273636a737a774c496c73437850575947454d0007c80c8f0130ae87f45404228ba8991d5c376417e21e0e8a59aff5d15a21134008216f57574d5a736a6f46534a43424a67727545756f6f66616c6d4c56696357697832116d6d6942624a615454427150634f6b43660007679be46377eabe7953210a122cd5ea4efe7ae87ed30908d872705191629a4a4602703811636750417465586c6f586a454e7977445900060774062fc5d7a8cc14858d26574079750f5982c234665439d0d5a7a18b5d88fb3c11576d675178625468684a6c664577437838034578550007f956e94f8c8046facd52563dec88a1bcd5d912dba915e7f872a3dead61b1f7d20f5a736475535365586e5a506f4c6552034c4b50000606040601010101201511671db1768e5eafff115bcb72ecdbcc90cb61682cd771035b8e43c88fcca81069e45e0f0aa236b0642a91745c1f21ea01e201acd3208a9dc70a67cb10d663eed846da5e2a1dc520fe93bd9c7e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404c8f93f0a2dc5515a8c2c723229b552bcfeec1c38f103e96b5dc1d30edc010971dccd34d679d265f788967d2f01766901ca79a0af7a4127dd5b6499680915e0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8aec5a01c06bfc2dea3c13a721b245ffe93ecd26683ee4ffa8d05f8555290398", - "sequence_number": "4394393999545566916", + "sender": "5dbe8a37c17ccc12f43ca8cf3bf0551253a2ddbba77a3560a954ab1eefe725e3", + "sequence_number": "2161835325662260676", "payload": { "EntryFunction": { "module": { - "address": "ece5054e435226d5ba459aef72b6eced040b4bd89acdadb03fed46c082c0e421", - "name": "nYrkQDvmZzZLBCYzJyqjnClcb_Coin" + "address": "6256bbdf7fa5e98e6f23453268da47335938d04789e68293b54cad5ec9de5a8f", + "name": "OLVGfncDAnkhf_Coin" }, - "function": "BcCVeTfLyDwBNaMgi6", + "function": "AhuIZAfRISvsUDOOThimucKISkfj2", "ty_args": [ { "struct": { - "address": "bd20690a645c2697e25616ac71a17a1e5cfadfc3a89d87403d44af89a08304a7", - "module": "I", - "name": "rDjINOGCAQWWZafskuzs", + "address": "152e229a5ae16c7207a4443cf0feefddb6ab3c2977254da443e1fefffc06985c", + "module": "VEhrgGoSb9", + "name": "bhWZEsRTqBSdmuCvmQFGcZzNZI6", "type_args": [] } }, { - "struct": { - "address": "c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e69", - "module": "qSSUGPXd", - "name": "KHSaaImrYsotjdXoYZgudam", - "type_args": [] + "vector": { + "struct": { + "address": "91f4573de57880f8208829f278e24e54e49b156ca43a0b76b9da096cfb718808", + "module": "CNDtsgeWZQbHOOXPATkAMATYnO1", + "name": "UQE", + "type_args": [] + } } }, { "struct": { - "address": "1b938a8b177921148cce0be13e9463920c4168c08509db177b42c20664ba0370", - "module": "LCZOgQYHgAw", - "name": "cOsLlKAywsUKCTohnxk0", + "address": "88a7f9c0ae37118116cf48df5196335480988d155c080721df8bd54b2f19ffb0", + "module": "xKerUNXS", + "name": "RJSnFNClPASxGGfLFW6", "type_args": [] } }, { "vector": { "struct": { - "address": "16263889887c6f2f15fe34fdfa843221458380232428641307bc80e284435edd", - "module": "fWhjNogsC", - "name": "tRgWZIlmO1", + "address": "3ff051e25a75624af99c6fcfdeaaa1e24188d99eb703c0f206d6d30088d8f2f5", + "module": "cDfHj3", + "name": "F", "type_args": [] } } - } - ], - "args": [ - "00", - "e4b1bf90cb4398c77ca669cff392ca4eacff0224e27f7b0b7397abcdc8ec548c", - "d907d1d2acd14592458d742525e7cf807d3cf9613a95116bf374e4a93417c5ae" - ] - } - }, - "max_gas_amount": "15381588969336334073", - "gas_unit_price": "2170233801944397936", - "expiration_timestamp_secs": "9952888537206348761", - "chain_id": 96 - }, - "signed_txn_bcs": "8aec5a01c06bfc2dea3c13a721b245ffe93ecd26683ee4ffa8d05f8555290398c48605620f06fc3c02ece5054e435226d5ba459aef72b6eced040b4bd89acdadb03fed46c082c0e4211e6e59726b5144766d5a7a5a4c4243597a4a79716a6e436c63625f436f696e12426343566554664c794477424e614d6769360407bd20690a645c2697e25616ac71a17a1e5cfadfc3a89d87403d44af89a08304a701491472446a494e4f4743415157575a6166736b757a730007c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e69087153535547505864174b48536161496d7259736f746a64586f595a677564616d00071b938a8b177921148cce0be13e9463920c4168c08509db177b42c20664ba03700b4c435a4f6751594867417714634f734c6c4b41797773554b43546f686e786b3000060716263889887c6f2f15fe34fdfa843221458380232428641307bc80e284435edd096657686a4e6f6773430a745267575a496c6d4f310003010020e4b1bf90cb4398c77ca669cff392ca4eacff0224e27f7b0b7397abcdc8ec548c20d907d1d2acd14592458d742525e7cf807d3cf9613a95116bf374e4a93417c5aef9e65b26ac6176d570f870fc24381e1ed9db3d5564c31f8a60002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405ce30beea39582eb14457ec8543bf93761249fe1af42f888bf7e34df1a1b1be27ccb6c955b5c6e48e0a957cf2ab3ea72c07488645280bf4e48997d8e59c79909", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "64da90f6c8598dadb27e34e076ccdfe8b2d71f75f3aa347b92b72e7647d50da3", - "sequence_number": "5652109983803950991", - "payload": { - "EntryFunction": { - "module": { - "address": "d4b8f164c25219d4c330ccd9bd151dae451e43182223b2bf150dd9d8b220f611", - "name": "mHqisOEzXnroyYn_Coin" - }, - "function": "PoO", - "ty_args": [ + }, + { + "struct": { + "address": "02d2e5d321f64908cf85dd81ca97642eb87aeb98a0f6a945af56cf3892a3c8f6", + "module": "fdsCJAeVonImP7", + "name": "vOBpvjWdjquEJHErIJMByHyXdS", + "type_args": [] + } + }, + { + "struct": { + "address": "613a95116bf374e4a93417c5ae8aec5a01c06bfc2dea3c13a721b245ffe93ecd", + "module": "TXIVTGDiC3", + "name": "sLXayWTLmkNpLxxYYJ4", + "type_args": [] + } + }, { "struct": { - "address": "b63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e421988876fd3", - "module": "fHRQOOanOSaqGToGFHdiU8", - "name": "raQdxzyXufAeYOxwUO3", + "address": "bf8d16934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4", + "module": "bDKhgfXyy", + "name": "CvIgPeVlfmWikXoVOi4", "type_args": [] } }, { "struct": { - "address": "c37f648cde3ca9c0c63e60cf217436c4c87e31168baeff89669aadcaf46c2352", - "module": "VvVJQdyGBWQVsaEycenBBOjH1", - "name": "IcceBWMVSttbMQdeUXKYcoVcfyTPuC3", + "address": "831b45445ebee9446778e3b6d6afd89e3af4b4e5f4dd52b65416b41683241d2e", + "module": "BqchvuxOfiyparRfflL", + "name": "uRbkVjGeMgUXMSkbBXCKCWd", "type_args": [] } }, { "vector": { - "struct": { - "address": "6fb5721acbb475a4be0bd807be5d4f53c5a71e6403c714e8c7d502fb7c8a6cdd", - "module": "zieFoaoAFPbffeKeFvltgmlWMum", - "name": "hdlvxlSBmMicBzVDvmLfGyGaprmiewm", - "type_args": [] + "vector": { + "vector": "bool" } } } ], "args": [ - "5f4c02ab3c37be6a4112467350995026900bf36ffb87a8c723895102f6123b25", - "54f0c269c845adb3", - "0c1aadfd46f94aab0ae79d2dcf543ab4" + "01" ] } }, - "max_gas_amount": "5189893107018236590", - "gas_unit_price": "6000570407352201126", - "expiration_timestamp_secs": "480398375468096016", - "chain_id": 119 + "max_gas_amount": "11192853545400697713", + "gas_unit_price": "6518750766354711059", + "expiration_timestamp_secs": "4505624551975296546", + "chain_id": 79 }, - "signed_txn_bcs": "64da90f6c8598dadb27e34e076ccdfe8b2d71f75f3aa347b92b72e7647d50da38fc712881554704e02d4b8f164c25219d4c330ccd9bd151dae451e43182223b2bf150dd9d8b220f611146d487169734f457a586e726f79596e5f436f696e03506f4f0307b63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e421988876fd316664852514f4f616e4f53617147546f474648646955381372615164787a795875664165594f7877554f330007c37f648cde3ca9c0c63e60cf217436c4c87e31168baeff89669aadcaf46c2352195676564a51647947425751567361457963656e42424f6a48311f4963636542574d56537474624d51646555584b59636f5663667954507543330006076fb5721acbb475a4be0bd807be5d4f53c5a71e6403c714e8c7d502fb7c8a6cdd1b7a6965466f616f414650626666654b6546766c74676d6c574d756d1f68646c76786c53426d4d6963427a5644766d4c664779476170726d6965776d0003205f4c02ab3c37be6a4112467350995026900bf36ffb87a8c723895102f6123b250854f0c269c845adb3100c1aadfd46f94aab0ae79d2dcf543ab4ae02129a48340648a6eff23bfe4e4653105a73f8c6b7aa0677002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444045747c032b586818a7e6bd104770ac63b00d052fce9876b674b18677ae07ba896ccc4b7df20596cd2e3d0062fb718eded96bf46253102ab9e455ba2ee7448402", + "signed_txn_bcs": "5dbe8a37c17ccc12f43ca8cf3bf0551253a2ddbba77a3560a954ab1eefe725e3c46dfd58c661001e026256bbdf7fa5e98e6f23453268da47335938d04789e68293b54cad5ec9de5a8f124f4c5647666e6344416e6b68665f436f696e1d416875495a4166524953767355444f4f5468696d75634b49536b666a320907152e229a5ae16c7207a4443cf0feefddb6ab3c2977254da443e1fefffc06985c0a5645687267476f5362391b6268575a45735254714253646d7543766d514647635a7a4e5a493600060791f4573de57880f8208829f278e24e54e49b156ca43a0b76b9da096cfb7188081b434e4474736765575a5162484f4f585041546b414d4154596e4f3103555145000788a7f9c0ae37118116cf48df5196335480988d155c080721df8bd54b2f19ffb008784b6572554e585313524a536e464e436c504153784747664c4657360006073ff051e25a75624af99c6fcfdeaaa1e24188d99eb703c0f206d6d30088d8f2f506634466486a330146000702d2e5d321f64908cf85dd81ca97642eb87aeb98a0f6a945af56cf3892a3c8f60e666473434a4165566f6e496d50371a764f4270766a57646a7175454a484572494a4d427948795864530007613a95116bf374e4a93417c5ae8aec5a01c06bfc2dea3c13a721b245ffe93ecd0a5458495654474469433313734c58617957544c6d6b4e704c787859594a340007bf8d16934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f40962444b68676658797913437649675065566c666d57696b586f564f69340007831b45445ebee9446778e3b6d6afd89e3af4b4e5f4dd52b65416b41683241d2e13427163687675784f6669797061725266666c4c177552626b566a47654d6755584d536b624258434b43576400060606000101017183944cff00559b13c2e0bf4841775a221ec47fa831873e4f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cc729329281c643b5cbef719335e66e0fd620b07add27ad418a94105e839557ae1765a95c58981587d4cdcb0aaa703181a058d0bc6d9a4b7520728c075300e05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e036903087d53c8", - "sequence_number": "17995524261789320622", + "sender": "dc44f42ff37dfbc017d673a65110c206933e31c7f7ca8e1832275ae24ebc9d69", + "sequence_number": "1568570467573419337", "payload": { "EntryFunction": { "module": { - "address": "813babcf3cb7e5e8be96f3fb7a9006df4d309176fdc49440c1287396ff06f45b", - "name": "hsdxPAtVUctkMWKhaUHaEdxJEf_Coin" + "address": "9a8cc18eb3c6e8b0b571178dcc2387cd5913c6413cc010c4e5d22965f19d9845", + "name": "IvTceBoWMdzDSWXk_Coin" }, - "function": "GyxIUcfIDyKwpPb", + "function": "bYFMobdberuKDHycYAlc", "ty_args": [ { "vector": { - "vector": "u128" + "vector": { + "struct": { + "address": "fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc610f806", + "module": "EYjAdsNnVSiQxOWlaZ2", + "name": "lCodJaBnofJQPfmKBBvZFgxmtIN9", + "type_args": [] + } + } } }, { "struct": { - "address": "8485de37fe833437cb402099f38fac789155918f0819fd4a685b19a0a0be018b", - "module": "fDi7", - "name": "AfYQUrmYkWLZuFlOAZFSldHQcGmhbwr6", + "address": "2cdf5572e6b1fc494581f79b8267ac8cdfeee3bf7140d577d03e515f900a62bd", + "module": "GXy7", + "name": "wOovJFavsQeLchTDxfVHpHhpj8", "type_args": [] } }, { "vector": { "struct": { - "address": "9f0f514bb2ae3f29833f2398c2d82bfe4c13f5f2ff554ca2a6944539192670e7", - "module": "NN", - "name": "pp4", + "address": "2461bfd3b9250539f5a4aed624919a804dc7c84a389b798659237d436914b698", + "module": "AAOFTJoNefcPJPkMNloF6", + "name": "FkTFareNkjigANYQsTUSOITDeHNPr", "type_args": [] } } }, { "struct": { - "address": "94f7f3198ebd3847f9669158e3f785f9b2f341a12ad486edf94c7e22b13c7697", - "module": "RbyAHfmFJWFPjrFxjCqa4", - "name": "yYBuSTAZRpERwahslPuCi", + "address": "b0450561dfbc2444c4247ea7eafce61705a2fb1b7c12e342e929e4ac6bae35ae", + "module": "FXUyxxyAXGkdwCFEvHmUeMozKjYYhOXR3", + "name": "wCOLxkWIDWYMmm", "type_args": [] } - } - ], - "args": [ - "09ef47e57c9f71030ec4cdf24b169384b54191d82070318da0c085de876ebb39", - "edaabf13bfa35ab3e17c30f22f05ee15", - "00", - "856894ebb2d6cc44e2141d268a7c651b" - ] - } - }, - "max_gas_amount": "10050040562277102782", - "gas_unit_price": "13321142185640067551", - "expiration_timestamp_secs": "8684857236114279010", - "chain_id": 61 - }, - "signed_txn_bcs": "e850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e036903087d53c8ae45e0c2f8f1bcf902813babcf3cb7e5e8be96f3fb7a9006df4d309176fdc49440c1287396ff06f45b1f68736478504174565563746b4d574b68615548614564784a45665f436f696e0f477978495563664944794b7770506204060603078485de37fe833437cb402099f38fac789155918f0819fd4a685b19a0a0be018b0466446937204166595155726d596b574c5a75466c4f415a46536c64485163476d68627772360006079f0f514bb2ae3f29833f2398c2d82bfe4c13f5f2ff554ca2a6944539192670e7024e4e03707034000794f7f3198ebd3847f9669158e3f785f9b2f341a12ad486edf94c7e22b13c7697155262794148666d464a5746506a7246786a4371613415795942755354415a52704552776168736c5075436900042009ef47e57c9f71030ec4cdf24b169384b54191d82070318da0c085de876ebb3910edaabf13bfa35ab3e17c30f22f05ee15010010856894ebb2d6cc44e2141d268a7c651bbe34cbdca4ea788bdf018c493d34deb8628a9253a4cf86783d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407e5ae9dbe24991ff6b9be7a55336400a75326fcb29774480fa876ab5ce4788799f3bfd02ed1d805e767d1673546969af42c0537c8267cd3fa8e5f395065edf0a", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "42af3ae1d0f0c5a572dbd55d4f8da36f623aad23306d1ae0ee44d7cc254212f7", - "sequence_number": "2455683739375654353", - "payload": { - "EntryFunction": { - "module": { - "address": "08248baf8e4872c8a32d96c6af4eb6bd5859ab2f152de3afc081cc18ee203d67", - "name": "LmtBuqJj8_Coin" - }, - "function": "OAIxQOhHqfCMcBCIvhClODVKSMuxQ", - "ty_args": [ + }, + { + "struct": { + "address": "a759ff6f19e41aeaa5f8923a4cb89003faca836f2b452ff0521edbf63a2c034b", + "module": "HDOSzNDhbjRwY9", + "name": "eZRgtnzVbMajutyB6", + "type_args": [] + } + }, + { + "struct": { + "address": "34d2ade043b09c8f18639f3570740938962b6e85530c8c9f0d7a75eafa1f91ec", + "module": "wwXcfyFoKGJisZzbPejABRdpb6", + "name": "pXwmVQztiPgtXN", + "type_args": [] + } + }, { "struct": { - "address": "bc946e2d27fa14fdc2a422e075027885b9be806599b0bef97dedc23022df5007", - "module": "QdEWV", - "name": "CekXCkZGOsPZo", + "address": "dd286edab4957f3cbf2d1c6bce48d25bafd03c8ca0d4b83c9a9182607ce089e0", + "module": "UdpLvMonqdASLStwymxMasQeALMwdtyZ9", + "name": "XmmjwATcqVcsDlYfbOfXyHiIGfWF", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + }, { "struct": { - "address": "d41e960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a", - "module": "UmanGyW", - "name": "XGTAZiwPFCweKpX", + "address": "cb06141c3566a09f5130a915c441516f2414d8013814bc781c5b969cce8fa391", + "module": "pevKUyRkLCtvbrXNtp7", + "name": "sDwqkIZfnDGKzd5", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "84b54191d82070318da0c085de876ebb397d39fe33ac3ddd6c3aa64b61a589f9", + "module": "YUQ8", + "name": "dJyDmydYHqiSVIrMVgZNHr", + "type_args": [] + } + } } ], - "args": [ - "67", - "16152096c4c69876", - "08f8b519c1e5922a768b1f14f0e77e65ab55da07fa245dc2ba71a5f78a02e3fa", - "62902f67ce645fb2458b1f45d5ad2391400659b1b42348b26a24bc2777c3c994", - "00", - "ee", - "0e", - "1e", - "df427704e350b4c555e03e2648bfe96a", - "01" - ] + "args": [] } }, - "max_gas_amount": "6025768940618406886", - "gas_unit_price": "11232156725308974974", - "expiration_timestamp_secs": "3118786794130706781", - "chain_id": 77 + "max_gas_amount": "12680044471583224156", + "gas_unit_price": "6330145959402166020", + "expiration_timestamp_secs": "5966256172242054543", + "chain_id": 64 }, - "signed_txn_bcs": "42af3ae1d0f0c5a572dbd55d4f8da36f623aad23306d1ae0ee44d7cc254212f7d15530a6595714220208248baf8e4872c8a32d96c6af4eb6bd5859ab2f152de3afc081cc18ee203d670e4c6d744275714a6a385f436f696e1d4f414978514f68487166434d634243497668436c4f44564b534d7578510207bc946e2d27fa14fdc2a422e075027885b9be806599b0bef97dedc23022df50070551644557560d43656b58436b5a474f73505a6f0007d41e960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a07556d616e4779570f584754415a697750464377654b7058000a01670816152096c4c698762008f8b519c1e5922a768b1f14f0e77e65ab55da07fa245dc2ba71a5f78a02e3fa2062902f67ce645fb2458b1f45d5ad2391400659b1b42348b26a24bc2777c3c994010001ee010e011e10df427704e350b4c555e03e2648bfe96a0101e65b24f4ecd49f537e678ef907a3e09b5d1157b21028482b4d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bbe8b40ba2bb4b1b785105776c9ec49278552da8c85a84db7b20f02e7350f3145d069912f6ffbb4acb1dd8bccd33dbd5803f4e3c93276dd7dfe4cdb1a7dc3b0e", + "signed_txn_bcs": "dc44f42ff37dfbc017d673a65110c206933e31c7f7ca8e1832275ae24ebc9d6949cde19487aec415029a8cc18eb3c6e8b0b571178dcc2387cd5913c6413cc010c4e5d22965f19d9845154976546365426f574d647a445357586b5f436f696e146259464d6f6264626572754b4448796359416c630a060607fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc610f8061345596a4164734e6e56536951784f576c615a321c6c436f644a61426e6f664a5150666d4b4242765a4667786d74494e3900072cdf5572e6b1fc494581f79b8267ac8cdfeee3bf7140d577d03e515f900a62bd04475879371a774f6f764a4661767351654c6368544478665648704868706a380006072461bfd3b9250539f5a4aed624919a804dc7c84a389b798659237d436914b6981541414f46544a6f4e656663504a506b4d4e6c6f46361d466b54466172654e6b6a6967414e5951735455534f49544465484e50720007b0450561dfbc2444c4247ea7eafce61705a2fb1b7c12e342e929e4ac6bae35ae21465855797878794158476b647743464576486d55654d6f7a4b6a5959684f5852330e77434f4c786b57494457594d6d6d0007a759ff6f19e41aeaa5f8923a4cb89003faca836f2b452ff0521edbf63a2c034b0e48444f537a4e4468626a5277593911655a5267746e7a56624d616a7574794236000734d2ade043b09c8f18639f3570740938962b6e85530c8c9f0d7a75eafa1f91ec1a777758636679466f4b474a69735a7a6250656a414252647062360e7058776d56517a7469506774584e0007dd286edab4957f3cbf2d1c6bce48d25bafd03c8ca0d4b83c9a9182607ce089e0215564704c764d6f6e716441534c537477796d784d61735165414c4d776474795a391c586d6d6a7741546371566373446c5966624f665879486949476657460006060007cb06141c3566a09f5130a915c441516f2414d8013814bc781c5b969cce8fa391137065764b5579526b4c4374766272584e7470370f734477716b495a666e44474b7a643500060784b54191d82070318da0c085de876ebb397d39fe33ac3ddd6c3aa64b61a589f9045955513816644a79446d796459487169535649724d56675a4e487200005cb1dfe04391f8af04578a263632d9578f2d78c96066cc5240002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d94cc6d550f2001a4bdba34903589304cb935145af4fef8ec5cde096c3f5974f308a5c09e693f117f988cf6bb52d7647bd3a0f24cddeea6076c090ebeb7ef70b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fd71525306985c0c5d8496c874d5a725c58d8931e051124b4d0ad9dcd6c8d490", - "sequence_number": "7354507105233684228", + "sender": "b1abeb725fedba093a9e93e27359b4f261ed80425119b89779832de91be9c4c8", + "sequence_number": "8844391917843465996", "payload": { "EntryFunction": { "module": { - "address": "a69b372f465df051ef898beffcf15052127122960ab3eb7c22046af41ac116aa", - "name": "o_Coin" + "address": "c629ff44b5780e3414a2094e545ed162523c42376004f70d0c3266978c30eea8", + "name": "UgCykPx_Coin" }, - "function": "fdVNfpspjmtsecymyoCEkrdUGcXW", + "function": "TzoxSueBAGO", "ty_args": [ { "struct": { - "address": "67b8ba5bc4f9adc50ba4e90fa1cd769043eb84cce297e4cceb9ebb9d523a6aff", - "module": "jy2", - "name": "uLmiDfntnPLyYhGzqWgAMCpW", + "address": "ed57a7e86d17d37f44962fdfb25047e8da7e04f5cc1d7e30ae9d3317c7ac8cd8", + "module": "f", + "name": "GPgkHRfACefWcIbnaPJI4", + "type_args": [] + } + }, + { + "struct": { + "address": "5b9209eb432da7563934bfa4400a24b876230302c169487fa9e864905af8f9a2", + "module": "WqFPz4", + "name": "RUnEGa7", "type_args": [] } }, { "vector": { - "struct": { - "address": "a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d52bd15a3090a0080d30e", - "module": "MbbySfJcukGfVFJxqVdS", - "name": "exxigysiUrlIlsrwUdQYZdkFiZyHjze", - "type_args": [] + "vector": "u8" + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a24f9", + "module": "jCOfkisDFYGls3", + "name": "RNgDcngIJlYQOL", + "type_args": [] + } } } }, { - "struct": { - "address": "6454333b5ffca7416312e8701aeca7a7c434475e87effa7803de00fec92afd98", - "module": "PdPSwiEKUbjjvdHsxTHbfJm6", - "name": "IULgOEnWvoYyHWLHtvOZkAVwkKHbuBYC", - "type_args": [] + "vector": { + "struct": { + "address": "61b6f097e18f0a62b37f75c1c9b96dc7709f5e5ec3feabc1ee1de1029e03b4ea", + "module": "JQREpcWFleOBGBQYYktDczwTswaFnQ3", + "name": "tEMEGzcmCGREmAELIWbYDdrkgHYI", + "type_args": [] + } } }, { - "struct": { - "address": "7268c644159ed1ba9fd20a53228405d4ee7d28cf9698ebd7e0360d2108362361", - "module": "kiMaFXUxPX1", - "name": "dpBnFAcfyZbWhTbzrt", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "fb2f927ea536d51be87cdfe35548612ae2e52b8e606750eff79ddaa364607917", + "module": "qHnuuGXoJ8", + "name": "ZCHct7", + "type_args": [] + } + } } }, { "vector": { - "vector": "signer" + "struct": { + "address": "8f74cb73a43a927e0d020c5deef599b95c99809bd4c950b42c5b817dd07cf0ad", + "module": "YGFixkKLEgFJwchyffmWYZW", + "name": "iFMdFSwrYrfD", + "type_args": [] + } } } ], "args": [ + "00", + "43cb9adb55c5637472c542a4b6293df6", + "9c6cb733acf034d1", + "a2a34dfc9e1372bb9fd14d87543da8d0", + "7c", "01", - "301c38c9bfafa36d09aece7a498d406b", - "4b6fa5b50b8b8d4db0813b0bc72e8fc1604810ccb12493e3e6bb74b84c86c884", - "7d3363649a7f186a233b21df5acce645e53b1ecb706de84c6b4cf3b2f826a3fd", - "9083a6d838e234ac", - "7f2c22bf836a41552c4dfdff9f0bc7a7b3e55ae4162025192e5e29b75bac4611", - "28", - "222d126313f5bc5e", - "5fdb8ac25668f992b4df0d46b9e7839aea4cf3551bc51e83c38d2ae1179c3473", - "73a9113ec7f58cbb876fef394b5a78ae38b1a7b5f9f9a302c4426bca1b22cb02" + "01" ] } }, - "max_gas_amount": "9191068898117423521", - "gas_unit_price": "10472524769623398718", - "expiration_timestamp_secs": "18240895821559382570", - "chain_id": 138 + "max_gas_amount": "12377412770658682390", + "gas_unit_price": "13855668859741411736", + "expiration_timestamp_secs": "7115958003360343245", + "chain_id": 135 }, - "signed_txn_bcs": "fd71525306985c0c5d8496c874d5a725c58d8931e051124b4d0ad9dcd6c8d49004478a113f75106602a69b372f465df051ef898beffcf15052127122960ab3eb7c22046af41ac116aa066f5f436f696e1c6664564e667073706a6d74736563796d796f43456b72645547635857050767b8ba5bc4f9adc50ba4e90fa1cd769043eb84cce297e4cceb9ebb9d523a6aff036a793218754c6d6944666e746e504c795968477a715767414d437057000607a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d52bd15a3090a0080d30e144d62627953664a63756b476656464a78715664531f657878696779736955726c496c737277556451595a646b46695a79486a7a6500076454333b5ffca7416312e8701aeca7a7c434475e87effa7803de00fec92afd9818506450537769454b55626a6a7664487378544862664a6d362049554c674f456e57766f597948574c4874764f5a6b4156776b4b48627542594300077268c644159ed1ba9fd20a53228405d4ee7d28cf9698ebd7e0360d21083623610b6b694d6146585578505831126470426e46416366795a62576854627a7274000606050a010110301c38c9bfafa36d09aece7a498d406b204b6fa5b50b8b8d4db0813b0bc72e8fc1604810ccb12493e3e6bb74b84c86c884207d3363649a7f186a233b21df5acce645e53b1ecb706de84c6b4cf3b2f826a3fd089083a6d838e234ac207f2c22bf836a41552c4dfdff9f0bc7a7b3e55ae4162025192e5e29b75bac4611012808222d126313f5bc5e205fdb8ac25668f992b4df0d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732073a9113ec7f58cbb876fef394b5a78ae38b1a7b5f9f9a302c4426bca1b22cb02a1116e6a773c8d7f3ed9e1cacae155912a42f4f41aae24fd8a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440144f6e1e114e7bad87a2f52f09a5d1d8ea1e7e707eef843810f7028f112f1517338fd79595541469b0a73db94d01e208f2caff7b45689ec9ca2e74c329400708", + "signed_txn_bcs": "b1abeb725fedba093a9e93e27359b4f261ed80425119b89779832de91be9c4c80c4765f59697bd7a02c629ff44b5780e3414a2094e545ed162523c42376004f70d0c3266978c30eea80c556743796b50785f436f696e0b547a6f785375654241474f0707ed57a7e86d17d37f44962fdfb25047e8da7e04f5cc1d7e30ae9d3317c7ac8cd80166154750676b48526641436566576349626e61504a493400075b9209eb432da7563934bfa4400a24b876230302c169487fa9e864905af8f9a206577146507a340752556e4547613700060601060607960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a24f90e6a434f666b6973444659476c73330e524e6744636e67494a6c59514f4c00060761b6f097e18f0a62b37f75c1c9b96dc7709f5e5ec3feabc1ee1de1029e03b4ea1f4a515245706357466c654f4247425159596b7444637a7754737761466e51331c74454d45477a636d434752456d41454c495762594464726b6748594900060607fb2f927ea536d51be87cdfe35548612ae2e52b8e606750eff79ddaa3646079170a71486e757547586f4a38065a43486374370006078f74cb73a43a927e0d020c5deef599b95c99809bd4c950b42c5b817dd07cf0ad1759474669786b4b4c4567464a7763687966666d57595a570c69464d644653777259726644000701001043cb9adb55c5637472c542a4b6293df6089c6cb733acf034d110a2a34dfc9e1372bb9fd14d87543da8d0017c0101010116867e295667c5ab981954de6a3949c0cd24e4221af6c06287002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440180c8421f7bb7f4e86404feef8461f60c2c318e45ed25875689cb48e28a56249319b57e192b287dc29a82fa70e40df227f388c0ee5a056a3c102751b62b13405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7f37cdf924047a7d833f04cc52b5ee0981c16fb49031121133c96730b6830b6d", - "sequence_number": "18029546327269471879", + "sender": "9135eb9b0290386e71bb37f25e188e99ac39f422f2e57baef5a5c4079dc5b103", + "sequence_number": "5025910601440530849", "payload": { "EntryFunction": { "module": { - "address": "aaca7e3c0d796b41b2d0adbe0a2a3345f3d04518b1537b19c66325c7d13edcbc", - "name": "kLhgrDgcfvDjGwYEujBpgLXesRO6_Coin" + "address": "b80e41b764b193bd4646a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d", + "name": "xplv_Coin" }, - "function": "FnZxUivYyLTckvWSFkReOgbUtcTWjkN", + "function": "UlCrSOy", "ty_args": [ { "struct": { - "address": "22a90a126d58504682bc5c95880a530853d24213f29dbf3fcb2bd597123262ed", - "module": "ABabled", - "name": "SDaKIskFTGrsZleVv1", + "address": "4510c51dbb4b340705b24b170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6", + "module": "QAYoCccSTjHkqIsqkVtaJYbr2", + "name": "gmEiwUJUSKQadMhe3", "type_args": [] } }, @@ -2148,669 +2727,643 @@ } }, { - "struct": { - "address": "1e742aa26e4fc8f10fd9c011c5091991d753ce64f433b61773ff6bd08bb96930", - "module": "AJBvqCPLzgvmvcrRZMOCbvcFqxURxYh", - "name": "oIuwAn9", - "type_args": [] + "vector": { + "vector": "bool" } }, { "vector": { - "vector": "address" + "struct": { + "address": "a458eaa84cc66c179d4023b0fafd28d2be494985d1f694a818c257269086e72e", + "module": "AVVzvZHT", + "name": "YqyszyizbuUSTUBEJFiu", + "type_args": [] + } } }, { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "6c6209b1fd1ed4c0c0ba5ca6ab8acf84ec8d3f62ad4bbeabd6546d9010f97623", + "module": "CHGzalxcTHSDmoUwIhBDKb", + "name": "orHNwUezGMqzQxvxqmxzXZJssKBVgBFH", + "type_args": [] } } }, + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "vector": "u8" + } + }, { "struct": { - "address": "3ee5e172ea0b54f333780d1f96cdca7bb9649a79b5115c24fa00fbfab4246f71", - "module": "HocOtMVjuId", - "name": "e", + "address": "2259e756daf15551e69c5fe80f9cf37c55747bb1c792cb59087b232e191e4057", + "module": "sZqctKbufgZgHtRZlLxMtdGjDmoIibw0", + "name": "MgX", "type_args": [] } } ], - "args": [] + "args": [ + "fc", + "01", + "48f61da910a30dc1", + "24", + "e6", + "00", + "00" + ] } }, - "max_gas_amount": "2807864525545556098", - "gas_unit_price": "8074205226668089558", - "expiration_timestamp_secs": "6474922013705849302", - "chain_id": 203 + "max_gas_amount": "197618437163433449", + "gas_unit_price": "2919865573578330141", + "expiration_timestamp_secs": "10285813321112450341", + "chain_id": 77 }, - "signed_txn_bcs": "7f37cdf924047a7d833f04cc52b5ee0981c16fb49031121133c96730b6830b6d8776582adcd035fa02aaca7e3c0d796b41b2d0adbe0a2a3345f3d04518b1537b19c66325c7d13edcbc216b4c6867724467636676446a47775945756a4270674c586573524f365f436f696e1f466e5a7855697659794c54636b765753466b52654f676255746354576a6b4e060722a90a126d58504682bc5c95880a530853d24213f29dbf3fcb2bd597123262ed07414261626c6564125344614b49736b46544772735a6c655676310006060603071e742aa26e4fc8f10fd9c011c5091991d753ce64f433b61773ff6bd08bb969301f414a42767143504c7a67766d766372525a4d4f436276634671785552785968076f497577416e390006060406060604073ee5e172ea0b54f333780d1f96cdca7bb9649a79b5115c24fa00fbfab4246f710b486f634f744d566a75496401650000824890c6e889f726d66027ebdf560d70d6494b0f448bdb59cb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cca6cef1b8bc521eb1741308f37503e143ffbfaca070be9c9f5cdef1c5a369240417c3ffb52063d72e2c1cd053924037850017dbb491299cfe95b19a0539b900", + "signed_txn_bcs": "9135eb9b0290386e71bb37f25e188e99ac39f422f2e57baef5a5c4079dc5b103a191bb47109fbf4502b80e41b764b193bd4646a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d0978706c765f436f696e07556c4372534f7908074510c51dbb4b340705b24b170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6195141596f43636353546a486b714973716b5674614a5962723211676d456977554a55534b5161644d68653300060606030606000607a458eaa84cc66c179d4023b0fafd28d2be494985d1f694a818c257269086e72e084156567a765a485414597179737a79697a62755553545542454a4669750006076c6209b1fd1ed4c0c0ba5ca6ab8acf84ec8d3f62ad4bbeabd6546d9010f97623164348477a616c7863544853446d6f5577496842444b62206f72484e7755657a474d717a51787678716d787a585a4a73734b42566742464800060602060601072259e756daf15551e69c5fe80f9cf37c55747bb1c792cb59087b232e191e405720735a7163744b627566675a674874525a6c4c784d7464476a446d6f4969627730034d6758000701fc01010848f61da910a30dc1012401e601000100e9bd31eceb14be021d5007e1447285282575e30eb88cbe8e4d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d7c777a5b03789af313b56232829160ed7cf1f0afe4a86cdf79b8c653c13e6ed7c5f47c5b4f1ec1a1a064b100a8a310a16c96227059c8244242f95d5e969c80d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e317", - "sequence_number": "18060385885481239920", + "sender": "34d2b7f24ed8ba6d2a28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409", + "sequence_number": "452007691087670478", "payload": { "EntryFunction": { "module": { - "address": "e6e578e1ee5b39d65a00c660a5cb3cb56ae5c8308297d1fb8da4872f45d4cad5", - "name": "RLDmy4_Coin" + "address": "0361d71267ba41799be42dbc53922711e9c1bdc3e7ed631ccf8bde2c1cc9f01d", + "name": "fjiAZqOCdfwqBZSOGmjdK8_Coin" }, - "function": "XY5", + "function": "kVxRASONwzKdagKCwgdSCOCOnCyaRJ", "ty_args": [ { "struct": { - "address": "773460e5ae3e4237a0f6416665a24a83d515db2d4b5f314dbd43fcdd6c0cc17f", - "module": "JYkMSJBeJaEndfYEyhVkHYyQCKdE9", - "name": "pQCZVtLQPTCjayexHu5", + "address": "8ea8d93569747f1cc7536765e455bb2593568200b7bfc7a67dc84025953225a6", + "module": "zMuAfJbvz2", + "name": "JRQzuagpgZieXBU5", + "type_args": [] + } + }, + { + "struct": { + "address": "7c9f04422184fc2328b04ae974231a183da31986e5a33de97bfcb47a20acf281", + "module": "PivxYXCQwqBDgKpqmBlvR8", + "name": "YWqdcQGOPRCjFzWiBZEDRF", + "type_args": [] + } + }, + { + "struct": { + "address": "64e5b04f59aafd10322c1ee79b3b0ffd9634aaa49fa286b7f5775e918c799890", + "module": "QQMNYPIT", + "name": "dr3", "type_args": [] } } ], "args": [ - "97da81147edba5e9", - "01", - "11", - "2c641e1110d1a78d" + "be154fec13fbcf84", + "aceda067a6873aef", + "7d", + "5fb5a4bd062a83aa", + "0b54cbd3cb89e67a", + "2a7f910af5e4cc315238ada049849000", + "00", + "96", + "fe04afd2e7dc8738f4503202d7bfae3ce1873c6054255144530670b39db104fa", + "01" ] } }, - "max_gas_amount": "6691848954133267560", - "gas_unit_price": "396785085347461217", - "expiration_timestamp_secs": "5217000071570202020", - "chain_id": 218 + "max_gas_amount": "6323064361001264397", + "gas_unit_price": "17526482840008418649", + "expiration_timestamp_secs": "14506135780477091069", + "chain_id": 186 }, - "signed_txn_bcs": "a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e3177085965a4661a3fa02e6e578e1ee5b39d65a00c660a5cb3cb56ae5c8308297d1fb8da4872f45d4cad50b524c446d79345f436f696e035859350107773460e5ae3e4237a0f6416665a24a83d515db2d4b5f314dbd43fcdd6c0cc17f1d4a596b4d534a42654a61456e646659457968566b48597951434b644539137051435a56744c515054436a6179657848753500040897da81147edba5e901010111082c641e1110d1a78d68c4ae392b39de5c61f84ed0eea98105a41d219bec816648da002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440775a1ac1a1aa739bfbbf44ac7a27d643793d7284b7a6bd64282b7ea2bf54f941efd444b7d55f8b872440e7fa14d36040f8ef1cbcf92401b684e300327879f203", + "signed_txn_bcs": "34d2b7f24ed8ba6d2a28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce6c06a799da4506020361d71267ba41799be42dbc53922711e9c1bdc3e7ed631ccf8bde2c1cc9f01d1b666a69415a714f4364667771425a534f476d6a644b385f436f696e1e6b56785241534f4e777a4b6461674b4377676453434f434f6e437961524a03078ea8d93569747f1cc7536765e455bb2593568200b7bfc7a67dc84025953225a60a7a4d7541664a62767a32104a52517a75616770675a69655842553500077c9f04422184fc2328b04ae974231a183da31986e5a33de97bfcb47a20acf28116506976785958435177714244674b70716d426c76523816595771646351474f5052436a467a5769425a45445246000764e5b04f59aafd10322c1ee79b3b0ffd9634aaa49fa286b7f5775e918c7998900851514d4e5950495403647233000a08be154fec13fbcf8408aceda067a6873aef017d085fb5a4bd062a83aa080b54cbd3cb89e67a102a7f910af5e4cc315238ada0498490000100019620fe04afd2e7dc8738f4503202d7bfae3ce1873c6054255144530670b39db104fa01010da569098909c0575965aea048933af3fdbcebb2a22550c9ba002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444068bb8b7bc6d611754d0055e5f378cb231d27929ce3348307e4193f44b508fb6847e6ee2a699e4648e8264048104baada67f76b8e28b9aeee8ec49f8f7c8c7705", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b4fdb4f06ca2de91dc7998ef7d478b65c2cda346d7b336a5ad1ad9d44c953407", - "sequence_number": "13845369706455041372", + "sender": "db784de31c6d46d5a0a8000bd4eb5acd4649fd78f9ca79313175b715f81bd43f", + "sequence_number": "10787838317076000469", "payload": { "EntryFunction": { "module": { - "address": "aff1e81c618372adef86f6daebfd7e581b666b8dc0dcba7b31417f96e1e0a4de", - "name": "wHkqJFCHHwbwfaboIPh6_Coin" + "address": "f64ce531c4aea1c5c88813e338423594083097dae790b8298ff79ebe210c01bd", + "name": "GGezhgZiPSVWRkYzZg2_Coin" }, - "function": "VhohlZdOmTtwu0", + "function": "fbJVEjzgwaZWTrLNsglXVfhxPyaVIK1", "ty_args": [ { - "struct": { - "address": "fda28d5c11349d7cf81d1798869b768a79636751341c5fc07470a6beec92a9cd", - "module": "yHBgGFZKRGJNYyRmQNvaYMlqCVDx4", - "name": "gGMjYSnzdVAhAFEJ", - "type_args": [] + "vector": { + "struct": { + "address": "b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec1c56c00e59", + "module": "ngTip3", + "name": "p", + "type_args": [] + } } }, { "struct": { - "address": "71feb2bcf6c67a3d53848f80ab39255b51d7fe5a8789333eb8a04bcea4cf2d8d", - "module": "UUabxlk3", - "name": "PhrCyQOMxfWwPceVcRhwgEG0", + "address": "a6cf3edfb97b4b579502fc75232fc92bb41e402ebca9aa27aa1b62c7988550e0", + "module": "ZRteQeY", + "name": "K", "type_args": [] } }, { "vector": { - "vector": { - "vector": { - "vector": "bool" - } + "struct": { + "address": "1b7c570c8eeb64fc94cbf820c83e0ce34d6fb03bb53695e380a72ceb88071cdd", + "module": "Vjapw4", + "name": "sTLXB1", + "type_args": [] } } }, - { - "vector": { - "vector": "signer" - } - }, { "vector": { "vector": { "struct": { - "address": "588cacd4b2fd7610684d3eab881fab1566c624463aaae9ef3356f4b8531235ce", - "module": "hVEKlDWjnEusLoLmCSBEIK7", - "name": "XuYOLNbHiYEDsLzPHSOKNgkn", + "address": "0f5e3e84663ef2eb7b858dfc49405122057e487695be332fc6156618400b9dcc", + "module": "PxevRDzhEDoQxjUPyApvlkTpfdR6", + "name": "oNNKX4", "type_args": [] } } } - }, - { - "vector": { - "vector": { - "vector": "signer" - } - } - }, - { - "vector": { - "vector": "u8" - } - }, - { - "vector": "signer" - }, - { - "vector": { - "struct": { - "address": "f3ca942495cae1376c7316e5aa2097042d60152e31360a19b5485c4aaa03c1f1", - "module": "nwWrAnDJsHyK", - "name": "QfvRfpIQgSo7", - "type_args": [] - } - } } ], "args": [ - "01" + "01", + "00", + "e3", + "b386c401f8f369169c9a6e94f2c90e8eeb6c080fb58ea57ad2e953521820d122", + "bb", + "ef2f9e055146502c", + "3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b6a5c643d25d97584a886a7" ] } }, - "max_gas_amount": "2946195462293242263", - "gas_unit_price": "14033485629172010867", - "expiration_timestamp_secs": "11693715517818192020", - "chain_id": 48 + "max_gas_amount": "870947171588840137", + "gas_unit_price": "684142261780142419", + "expiration_timestamp_secs": "11171755157904492154", + "chain_id": 84 }, - "signed_txn_bcs": "b4fdb4f06ca2de91dc7998ef7d478b65c2cda346d7b336a5ad1ad9d44c9534075c05356164a224c002aff1e81c618372adef86f6daebfd7e581b666b8dc0dcba7b31417f96e1e0a4de1977486b714a464348487762776661626f495068365f436f696e0e56686f686c5a644f6d54747775300907fda28d5c11349d7cf81d1798869b768a79636751341c5fc07470a6beec92a9cd1d7948426747465a4b52474a4e5979526d514e7661594d6c7143564478341067474d6a59536e7a645641684146454a000771feb2bcf6c67a3d53848f80ab39255b51d7fe5a8789333eb8a04bcea4cf2d8d0855556162786c6b33185068724379514f4d78665777506365566352687767454730000606060600060605060607588cacd4b2fd7610684d3eab881fab1566c624463aaae9ef3356f4b8531235ce176856454b6c44576a6e4575734c6f4c6d43534245494b37185875594f4c4e624869594544734c7a5048534f4b4e676b6e000606060506060106050607f3ca942495cae1376c7316e5aa2097042d60152e31360a19b5485c4aaa03c1f10c6e775772416e444a7348794b0c516676526670495167536f37000101019741dbd029fde22873cf58bfd3f4c0c294c006b84e6c48a230002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c9df879c7601b71658baf02b2e4e3c5de41097b3324eee9d70215b7721f07935c37a2414d554ce0620c48d22e0d4e7e2b43bf57228bb7fe9fdfe0ac6e984fd00", + "signed_txn_bcs": "db784de31c6d46d5a0a8000bd4eb5acd4649fd78f9ca79313175b715f81bd43fd5aea9ffca19b69502f64ce531c4aea1c5c88813e338423594083097dae790b8298ff79ebe210c01bd184747657a68675a6950535657526b597a5a67325f436f696e1f66624a56456a7a6777615a5754724c4e73676c585666687850796156494b31040607b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec1c56c00e59066e675469703301700007a6cf3edfb97b4b579502fc75232fc92bb41e402ebca9aa27aa1b62c7988550e0075a527465516559014b0006071b7c570c8eeb64fc94cbf820c83e0ce34d6fb03bb53695e380a72ceb88071cdd06566a617077340673544c584231000606070f5e3e84663ef2eb7b858dfc49405122057e487695be332fc6156618400b9dcc1c5078657652447a6845446f51786a5550794170766c6b547066645236066f4e4e4b583400070101010001e320b386c401f8f369169c9a6e94f2c90e8eeb6c080fb58ea57ad2e953521820d12201bb08ef2f9e055146502c203d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b6a5c643d25d97584a886a7c91aaf8cd639160c53d93c29c38f7e097a068928200c0a9b54002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404927d288358b89865b74c67c7e4ec5f4d0d901cff6d15db2e9f45e9553bd42b1df43bd55c6af4272486476729ba8d318eca53a68be4259c053dd9ef0b701e200", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5677cf319447c640e437f0f54d09d0052c71230ce042bd9702e0b661f241af4", - "sequence_number": "1878380097931517789", + "sender": "53e191cb1e4dc400716c7edc150a7b5de466cbbf925931a511eb15c66fc6538b", + "sequence_number": "12721589224998138041", "payload": { "EntryFunction": { "module": { - "address": "fdfa1ed33806bdf46693e66456d22062b8f146909d30cffea95047889e382ea5", - "name": "UKXqnFpkGaJETdhuCBcrIAbORX2_Coin" + "address": "6f7182a21fdd86ff4825b2e9a36435379380be9301b25c4ca1e1f4c89fef9106", + "name": "WTSPvtAhVXjyJNMOHCQwIFVexI4_Coin" }, - "function": "YUPGrOeRoxNjwZonFJnIGdQXDcJtcC4", + "function": "KZUZMGMrUyXxNDtMvhlO", "ty_args": [ { - "vector": { - "struct": { - "address": "9e804a293d5e42fada17932cf260c1a1a96dc2be3f4378aff31f706b3aa0d27f", - "module": "OAQOHdJNFYhgBimPFzOPxrAKGWeMmNt", - "name": "RkxHNKaeHUXDcVwttLVsXtyZ8", - "type_args": [] - } - } + "vector": "u128" }, { - "struct": { - "address": "c4ffef8e91871f0d6c0944250b19d4e68a7766f974dc2a2ebd21142479d7fe61", - "module": "lTbKVgILHSSMedNwjubCZkb", - "name": "hukrNkFZgDZuIOSEXp0", - "type_args": [] - } + "vector": "u128" } ], "args": [ - "af86bc1e58cc378ae375ee82ed7a1ce1", - "01", - "92" + "033631b8baa23ffe", + "daffac01929af03a463e08b768a9c509ada402c5e2471e498bfda28d5c11349d", + "1d", + "86", + "00", + "eaecaf79d8bc11b65cf49b0112dd1d83dabfcdee794f96fab4f02118d6210866", + "e4" ] } }, - "max_gas_amount": "9925555158849264896", - "gas_unit_price": "5256543240638435974", - "expiration_timestamp_secs": "6046679605804467685", - "chain_id": 232 + "max_gas_amount": "10085432895586854506", + "gas_unit_price": "11669446904000351920", + "expiration_timestamp_secs": "4620749631408738878", + "chain_id": 40 }, - "signed_txn_bcs": "d5677cf319447c640e437f0f54d09d0052c71230ce042bd9702e0b661f241af45d1f5f3abf58111a02fdfa1ed33806bdf46693e66456d22062b8f146909d30cffea95047889e382ea520554b58716e46706b47614a4554646875434263724941624f5258325f436f696e1f59555047724f65526f784e6a775a6f6e464a6e494764515844634a746343340206079e804a293d5e42fada17932cf260c1a1a96dc2be3f4378aff31f706b3aa0d27f1f4f41514f48644a4e4659686742696d50467a4f507872414b4757654d6d4e7419526b78484e4b61654855584463567774744c56735874795a380007c4ffef8e91871f0d6c0944250b19d4e68a7766f974dc2a2ebd21142479d7fe61176c54624b5667494c4853534d65644e776a7562435a6b621368756b724e6b465a67445a75494f5345587030000310af86bc1e58cc378ae375ee82ed7a1ce101010192009dc141d4a7be898612bc1c3afef248e5059396101fea53e8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba61083d243418caac6ebcb742dd98f18ceb285a66bbb61b4e7b7dd52300e1716ad48b2fbb835dcbacc4754ec0ef9992d4e83b2184709857b52b1e95d5fe730d", + "signed_txn_bcs": "53e191cb1e4dc400716c7edc150a7b5de466cbbf925931a511eb15c66fc6538bb970738eff298cb0026f7182a21fdd86ff4825b2e9a36435379380be9301b25c4ca1e1f4c89fef910620575453507674416856586a794a4e4d4f48435177494656657849345f436f696e144b5a555a4d474d72557958784e44744d76686c4f02060306030708033631b8baa23ffe20daffac01929af03a463e08b768a9c509ada402c5e2471e498bfda28d5c11349d011d0186010020eaecaf79d8bc11b65cf49b0112dd1d83dabfcdee794f96fab4f02118d621086601e46a667e9bc8a7f68bb00e39be2134f2a13e9222d84e33204028002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e3c1cc43ffd9f8ea752977b78ec66c23639957d207716d8d2b0fdce906b809d5d589654ce68f9960fc55edeb6c2cf7b8cdae59e12d160a0818c296643cc9140e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9fb9a26728c82e7080454327b831fde9858e3aecc00ea250fe30fd830fe798ba", - "sequence_number": "8045682877290477653", + "sender": "1a07699f4ea7d7af86cdab18897206016666af834f438219a2621ff340f056c1", + "sequence_number": "6393138401489061514", "payload": { "EntryFunction": { "module": { - "address": "1e54c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892ca", - "name": "OdJIkDLSvckclMYf5_Coin" + "address": "aadfea71cc1b4063703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a", + "name": "qbQjxRwJbmKsAkzFP_Coin" }, - "function": "sXibMsGJrjSoaUtsqEhZx8", + "function": "cMmZkO", "ty_args": [ - { - "vector": { - "struct": { - "address": "7ad1724e91e802867f203ef815dcf559da22fefc2f14eb1132b238a4da0f145e", - "module": "IWZsPO0", - "name": "MCugsUYS", - "type_args": [] - } - } - }, - { - "vector": { - "vector": { - "vector": "u128" - } - } - }, { "struct": { - "address": "c6e8953f0ce603131a481c6ffcbdf28cf2d9aa840e09c4714bc9cbcde9044689", - "module": "IBwdFVrcElyDZsBhYxFDUjRXrhJh9", - "name": "jxGKyFNzqSkRSFwpXExFZIkyAEfhwJ", + "address": "3eb8a04bcea4cf2d8d72b21b2065418f6eee9ec1e948f563faf2c49ef0f5a2bd", + "module": "bGRpmIrgAZiXioMvJyJeoHBzi1", + "name": "FFEeWDrVwphaRpDqZKKnpq2", "type_args": [] } }, - { - "vector": "address" - }, { "struct": { - "address": "8cdfe9abb4e512e3648dfb0f655df12aee185dc9c20baa0d5f4614ed8f0d380e", - "module": "zLlGhIvRDiXFQhStQtXgGZTiLQZqUrh", - "name": "fkyvdhbvzmViya", + "address": "cb3d4f285f5fa8c90b68ae6f9939eb87f9462d44a548bb0c221df8574d7d257f", + "module": "ExtdSlpTyAFadJFXEyUPLnLMo8", + "name": "cuxZyVjV2", "type_args": [] } }, { "struct": { - "address": "b6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395ad4d2cd", - "module": "EmhFBbpDLUAVYP", - "name": "CdeiBVLwoPGOHyiZgLd6", + "address": "7b68664941e0c3c1fdf9cef8dea90af892b163f24898a29cea25f27ac33efa65", + "module": "bGRjeUWpGjwANqCt1", + "name": "RiwbtFDSnTSLdhtQegRVREmWRsdHRmWi", "type_args": [] } }, { - "vector": { - "vector": "u128" - } - }, - { - "vector": { - "struct": { - "address": "03fe0a4626d5dae3f59b4ee365f33ae99910e2df86c188d06128b79fafd44ff4", - "module": "lxXhYPOTswiFyOpaXnOXRSmnaXH7", - "name": "CqZBTtlTFrIfOTjvWclXNsTUPFkP7", - "type_args": [] - } + "struct": { + "address": "1fd1a8678a67c15992037118a7c3ad9fc978d79b74a8881964fe10011f85202b", + "module": "xiMYEMHVboBDYzSyODtLakoHcQDptV", + "name": "mbnbqyJsPgElBQWzkkdGIQBn", + "type_args": [] } }, { "vector": { "struct": { - "address": "b57f7a31472000ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9e", - "module": "yLSYHrDjrLh3", - "name": "bMBKLNdcmYmmpOOwbJ", + "address": "565b89ff84add8b5519799a73d27813479588b664f6d212db2e241f2a973330f", + "module": "tvylczukQQKCaBlvXNGSiDzMWSavRN", + "name": "pgkJHXVmoTmChKd8", "type_args": [] } } } ], - "args": [ - "00", - "f2", - "01", - "01", - "c59f60b8d0ecfaadc6c2ac46e430b6d27ecbcd45da5b90f303877872747152b3", - "01", - "00" - ] + "args": [] } }, - "max_gas_amount": "873638699538835602", - "gas_unit_price": "5168442970645378220", - "expiration_timestamp_secs": "8649648247714166998", - "chain_id": 49 + "max_gas_amount": "4635852432370655208", + "gas_unit_price": "12592904291567948249", + "expiration_timestamp_secs": "1601151355790774827", + "chain_id": 200 }, - "signed_txn_bcs": "9fb9a26728c82e7080454327b831fde9858e3aecc00ea250fe30fd830fe798ba557857f4f201a86f021e54c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892ca164f644a496b444c5376636b636c4d5966355f436f696e16735869624d73474a726a536f615574737145685a78380906077ad1724e91e802867f203ef815dcf559da22fefc2f14eb1132b238a4da0f145e0749575a73504f30084d43756773555953000606060307c6e8953f0ce603131a481c6ffcbdf28cf2d9aa840e09c4714bc9cbcde90446891d4942776446567263456c79445a73426859784644556a525872684a68391e6a78474b79464e7a71536b5253467770584578465a496b7941456668774a000604078cdfe9abb4e512e3648dfb0f655df12aee185dc9c20baa0d5f4614ed8f0d380e1f7a4c6c4768497652446958465168537451745867475a54694c515a715572680e666b7976646862767a6d566979610007b6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395ad4d2cd0e456d6846426270444c5541565950144364656942564c776f50474f4879695a674c643600060603060703fe0a4626d5dae3f59b4ee365f33ae99910e2df86c188d06128b79fafd44ff41c6c78586859504f5473776946794f7061586e4f5852536d6e615848371d43715a4254746c54467249664f546a7657636c584e73545550466b5037000607b57f7a31472000ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9e0c794c53594872446a724c683312624d424b4c4e64636d596d6d704f4f77624a0007010001f20101010120c59f60b8d0ecfaadc6c2ac46e430b6d27ecbcd45da5b90f303877872747152b30101010092e80bbcc4c91f0cacb42e8b7fffb947d63815e540b9097831002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023de5862b3e1cd2ddcf2d417900d175c07da2e35ce26487eea3c546940d553fcaf7274159573c72ae6761fab0d44025500b6769da501e6db95a775100b1a3a0a", + "signed_txn_bcs": "1a07699f4ea7d7af86cdab18897206016666af834f438219a2621ff340f056c18a06aafc80fdb85802aadfea71cc1b4063703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a167162516a7852774a626d4b73416b7a46505f436f696e06634d6d5a6b4f05073eb8a04bcea4cf2d8d72b21b2065418f6eee9ec1e948f563faf2c49ef0f5a2bd1a624752706d497267415a6958696f4d764a794a656f48427a693117464645655744725677706861527044715a4b4b6e7071320007cb3d4f285f5fa8c90b68ae6f9939eb87f9462d44a548bb0c221df8574d7d257f1a45787464536c705479414661644a4658457955504c6e4c4d6f38096375785a79566a563200077b68664941e0c3c1fdf9cef8dea90af892b163f24898a29cea25f27ac33efa65116247526a65555770476a77414e714374312052697762744644536e54534c646874516567525652456d5752736448526d576900071fd1a8678a67c15992037118a7c3ad9fc978d79b74a8881964fe10011f85202b1e78694d59454d4856626f4244597a53794f44744c616b6f48635144707456186d626e6271794a735067456c4251577a6b6b64474951426e000607565b89ff84add8b5519799a73d27813479588b664f6d212db2e241f2a973330f1e7476796c637a756b51514b4361426c76584e475369447a4d57536176524e1070676b4a4858566d6f546d43684b64380000e85f95b639db5540d95166adbbfbc2ae2b528bc1ac6e3816c8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fdde5bf26ff5c498d4fcfd5ae1d5bcf5e5731f537dc7041336454bc1374787ec3b7ffc8110442577723e9fb6aadb796e91970b99fe67b505668135699c4f7b04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "222cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d4938", - "sequence_number": "2421426922280710295", + "sender": "f1ed7a8dbc812d61ba115d220ad5acaf2df58ac113879ffa3f8318c0df401213", + "sequence_number": "11055023505453793912", "payload": { "EntryFunction": { "module": { - "address": "28cacab96ef2658950e4e5dbc0205f65aa14b1103b6120eb72bac66ca3ee40f6", - "name": "qErYhkLnTKLjEWni_Coin" + "address": "b45bed166e357b68de8eec6f51721a04f29037411f3d2657500d2f12a986c08a", + "name": "XSYgndDLIFNxVdWXJkxxk_Coin" }, - "function": "MINTwKlJJYlEqdAaOaG", + "function": "obVJhccwsDzpLiCKZxMETLupZRVgifV", "ty_args": [ { - "struct": { - "address": "b9b99b9e2e42a907e1d574c156a3be3a1460fa5690416835c7c2ed71ff96a4e2", - "module": "aAKaN", - "name": "OMyLadmqHHDLDnQaggwdDEoSWvQdL3", - "type_args": [] + "vector": { + "struct": { + "address": "c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f536c2", + "module": "wHOrERUJKq5", + "name": "EvpeRpG1", + "type_args": [] + } } - } - ], - "args": [ - "aeaf001dc9491105", - "c29a89ee6b7b78ce", - "98e89bda07a8aae83b87ecc03aef3192f8d4f51fde10a429151be9e071ff09e9", - "01", - "7c" - ] - } - }, - "max_gas_amount": "11657047152064288007", - "gas_unit_price": "10327563732900448828", - "expiration_timestamp_secs": "2449168127409132211", - "chain_id": 18 - }, - "signed_txn_bcs": "222cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d493897f01be0f4a29a210228cacab96ef2658950e4e5dbc0205f65aa14b1103b6120eb72bac66ca3ee40f61571457259686b4c6e544b4c6a45576e695f436f696e134d494e54774b6c4a4a596c45716441614f61470107b9b99b9e2e42a907e1d574c156a3be3a1460fa5690416835c7c2ed71ff96a4e20561414b614e1e4f4d794c61646d714848444c446e51616767776444456f53577651644c33000508aeaf001dc949110508c29a89ee6b7b78ce2098e89bda07a8aae83b87ecc03aef3192f8d4f51fde10a429151be9e071ff09e90101017c0755c5849f26c6a13c0abd4e7fe0528fb3126e856f31fd2112002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405c5d20568e97960724303220a0e16f4314d81ea77c32f8ec42158920b8c81e22430b7c581a328ff5f18ff5352d55204b8efacfe7cc11fc631cd01cf88870e40e", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cd024813caccae2287438ebcbcf54ec918a76cfd87928c20ea3f3eb92942b456", - "sequence_number": "10191793175056855089", - "payload": { - "EntryFunction": { - "module": { - "address": "9c86e21299a794ee4dfcc53361de26450819f9ba7c7fb556c34103dd29f63679", - "name": "I0_Coin" - }, - "function": "EERtWBRGMkhVQUBvnaj", - "ty_args": [ + }, { "vector": { "struct": { - "address": "13612872dd98003a98fda8f975ee111c975ffced1e7dd63f89bbe53def9834e6", - "module": "WBLt2", - "name": "kugkSzFdpZRPqubxBJxqV4", + "address": "53aef66fb374ba6975a2648c87963991919a9886e7d6c2410ee5015c55266ab0", + "module": "VzGbptcNRsthDJBdkGGeUtOfq3", + "name": "nQSPLMCQIefjyciuDCQTrqUGNCZ4", "type_args": [] } } }, { "struct": { - "address": "5a288b7d1d0fff57580ec960a94e5ebec1bdaf00c722ffa7bcd7077e4c38ff09", - "module": "SrqMzJjGxxeEtRpw8", - "name": "xCVGvweqcDesqSnFIC", + "address": "70fadd37a9973ad9d5cd5207a212f8bf67545c4d2831beed6edbdd99d616e28b", + "module": "swnaiRhEf7", + "name": "wxxFfRiPIHWtzYhnTiCPtShN1", "type_args": [] } }, { "vector": { "struct": { - "address": "96db37481beb44b255a60351155d914f98806fd3c8ca1a9b0318d505448519f2", - "module": "jSZbvdGFp", - "name": "srsXvqCgCGg7", + "address": "32aac68ed3b2afc8542ceb8ef7cb974ab9defa9e804a293d5e42fada17932cf2", + "module": "ZFAMLHTawcoGQnn", + "name": "BIIQkTGyk", "type_args": [] } } }, { "struct": { - "address": "b07d010654bb8f2720c4da6327d05ea3cdd6579889e5659e58ac23bed6af8448", - "module": "RDRHEHhcOQirKYHORNRAsDyVrXuyE0", - "name": "jPtSTJwtIUkIPPnZlmfspfBai1", + "address": "2afa221144806096fbebd407be51454879119b0bb50d0b743d905e08f385d81b", + "module": "EOdIxAljFrYoJNTShH", + "name": "aGnMsfpFXdKoxfzfH8", "type_args": [] } }, { "vector": { "struct": { - "address": "c34fa23c046e05df2fdcf64b251ee2d3d43004b3205b7b11888e607acdd9aecd", - "module": "Y8", - "name": "hpMrlk", + "address": "a46efe2a843dce11afb2e441798c5f015362923c0ff8bd4141b595bc65201222", + "module": "qQtLtCqQg5", + "name": "EzeqEJsgtCpSCpqxULm2", "type_args": [] } } - }, - { - "struct": { - "address": "8d6610644f6b1e4bec9278f5a651cffde44ea863d73c15a1d343b17190c7f905", - "module": "nnyTO7", - "name": "eFydRU3", - "type_args": [] - } } ], "args": [ - "9fcffe4504ce4a33738eddf122897d32" + "01", + "a4", + "d7", + "5b800c550a0c0075", + "8c095edaa1374b44f15d56e4db4ccdbd", + "2be9f664caae2735fa712271d482ece0" ] } }, - "max_gas_amount": "14870805680598235862", - "gas_unit_price": "1406228066669832324", - "expiration_timestamp_secs": "14548874060634569088", - "chain_id": 27 + "max_gas_amount": "40061172565702091", + "gas_unit_price": "12806960680012040838", + "expiration_timestamp_secs": "12949656614228081273", + "chain_id": 70 }, - "signed_txn_bcs": "cd024813caccae2287438ebcbcf54ec918a76cfd87928c20ea3f3eb92942b45631b083efe485708d029c86e21299a794ee4dfcc53361de26450819f9ba7c7fb556c34103dd29f636790749305f436f696e1345455274574252474d6b6856515542766e616a06060713612872dd98003a98fda8f975ee111c975ffced1e7dd63f89bbe53def9834e60557424c7432166b75676b537a4664705a525071756278424a7871563400075a288b7d1d0fff57580ec960a94e5ebec1bdaf00c722ffa7bcd7077e4c38ff09115372714d7a4a6a477878654574527077381278435647767765716344657371536e46494300060796db37481beb44b255a60351155d914f98806fd3c8ca1a9b0318d505448519f2096a535a6276644746700c7372735876714367434767370007b07d010654bb8f2720c4da6327d05ea3cdd6579889e5659e58ac23bed6af84481e52445248454868634f5169724b59484f524e5241734479567258757945301a6a507453544a777449556b4950506e5a6c6d6673706642616931000607c34fa23c046e05df2fdcf64b251ee2d3d43004b3205b7b11888e607acdd9aecd0259380668704d726c6b00078d6610644f6b1e4bec9278f5a651cffde44ea863d73c15a1d343b17190c7f905066e6e79544f3707654679645255330001109fcffe4504ce4a33738eddf122897d32d63aeb43fab65fce84280ae3f9ec831380b904fadffbe7c91b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440add9f80745a5512865611ec445f737ce96369380e3c886809f6c8ee108fc71b6c3227d5439eb00669cf8ddde74cc2ea64452cfbfecf5a6c77a0496d7b3d79b05", + "signed_txn_bcs": "f1ed7a8dbc812d61ba115d220ad5acaf2df58ac113879ffa3f8318c0df40121378c22a624e556b9902b45bed166e357b68de8eec6f51721a04f29037411f3d2657500d2f12a986c08a1a585359676e64444c49464e78566457584a6b78786b5f436f696e1f6f62564a6863637773447a704c69434b5a784d45544c75705a525667696656060607c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f536c20b77484f724552554a4b713508457670655270473100060753aef66fb374ba6975a2648c87963991919a9886e7d6c2410ee5015c55266ab01a567a47627074634e52737468444a42646b47476555744f6671331c6e5153504c4d43514965666a7963697544435154727155474e435a34000770fadd37a9973ad9d5cd5207a212f8bf67545c4d2831beed6edbdd99d616e28b0a73776e61695268456637197778784666526950494857747a59686e546943507453684e3100060732aac68ed3b2afc8542ceb8ef7cb974ab9defa9e804a293d5e42fada17932cf20f5a46414d4c48546177636f47516e6e09424949516b5447796b00072afa221144806096fbebd407be51454879119b0bb50d0b743d905e08f385d81b12454f644978416c6a4672596f4a4e545368481261476e4d7366704658644b6f78667a664838000607a46efe2a843dce11afb2e441798c5f015362923c0ff8bd4141b595bc652012220a7151744c74437151673514457a6571454a73677443705343707178554c6d320006010101a401d7085b800c550a0c0075108c095edaa1374b44f15d56e4db4ccdbd102be9f664caae2735fa712271d482ece0cb7510986c538e00864a8360e276bbb1793a5a96146cb6b346002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d448ec2ef87e9c087022b0d5769dc07cb22e0eb4455690a8b0eb4c47ed076d73a7f68e6a83faa07a8d05e687237f89989c759f2c5171f62d3c769bf6165de603", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6ecc516d0bd5bd1871bcf74ef6bdcf9db0d21ee625a8732c6ff04d47ba02e852", - "sequence_number": "4229499932157335504", + "sender": "8097c870da2894624f8560bc2691a083eb8e22a4e75179f37bebb076cf9fcd7f", + "sequence_number": "4668949557064069391", "payload": { "EntryFunction": { "module": { - "address": "bbf5fc7f48ba522a374b42f200f359c29aaa50dcfc64d29d3459b067f75ba0aa", - "name": "uSH3_Coin" + "address": "281b875357192ffc6cde7f10c65e051d6f20687792bbdd32bbc79946118e4b4b", + "name": "NDdiBabPDZqHDaduKLVTXnMbOkG2_Coin" }, - "function": "ulHLTgDcfotYMGrLNZTqfHKChEmGchH4", + "function": "MCARjOk3", "ty_args": [ { "struct": { - "address": "b80d183c84c7331d362bae436292fd19fa4e91c9b5bd3e5981a93f4ef087d08e", - "module": "GZWJuLssawyjywqaaty", - "name": "gbYuTvedHuCtEMn", + "address": "17a2b2303887eb88e2fce4c16af0e3fba550c6defbbcafb3b1928a1dcbd01b28", + "module": "UmsVPpfajsSKjgAfjh", + "name": "SdBLSnhcvxgDHnBhpypaktksIP", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "fd2f54f85938e2c116197c1686d17eea76f21a5657fe9e4d582b12259eb3b3ce", + "module": "wuXBybToiddrzTswMFHgOWxeCgvWzUCM", + "name": "bmhtscePASPqvEHny", + "type_args": [] + } } } ], "args": [ - "beefd7c42645fab1", - "c6cc77a7ff214cd7", - "c1d1c4fdea09d029ad38c71daea6b76e" + "25" ] } }, - "max_gas_amount": "5449064544583208634", - "gas_unit_price": "6343790711398206942", - "expiration_timestamp_secs": "6489472502238722924", - "chain_id": 103 + "max_gas_amount": "7232575745544214858", + "gas_unit_price": "11508038239771854729", + "expiration_timestamp_secs": "16404010806166839774", + "chain_id": 198 }, - "signed_txn_bcs": "6ecc516d0bd5bd1871bcf74ef6bdcf9db0d21ee625a8732c6ff04d47ba02e852d0d7c689c733b23a02bbf5fc7f48ba522a374b42f200f359c29aaa50dcfc64d29d3459b067f75ba0aa09755348335f436f696e20756c484c54674463666f74594d47724c4e5a547166484b4368456d47636848340207b80d183c84c7331d362bae436292fd19fa4e91c9b5bd3e5981a93f4ef087d08e13475a574a754c73736177796a797771616174790f676259755476656448754374454d6e000606040308beefd7c42645fab108c6cc77a7ff214cd710c1d1c4fdea09d029ad38c71daea6b76ebace0e3a55f79e4bde0d508a0aac09586cbb9aabdb3c0f5a67002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404cc9dec8cf4253702d7efe01f1f54672ff5605827c091a8c76db65310a9023a699113d6e2eaa20f0ac63e7d38bb13061a02cf878c2d9735cd21d33de3c72330c", + "signed_txn_bcs": "8097c870da2894624f8560bc2691a083eb8e22a4e75179f37bebb076cf9fcd7f0f71058fe270cb4002281b875357192ffc6cde7f10c65e051d6f20687792bbdd32bbc79946118e4b4b214e44646942616250445a7148446164754b4c5654586e4d624f6b47325f436f696e084d4341526a4f6b33020717a2b2303887eb88e2fce4c16af0e3fba550c6defbbcafb3b1928a1dcbd01b2812556d7356507066616a73534b6a6741666a681a5364424c536e686376786744486e4268707970616b746b734950000607fd2f54f85938e2c116197c1686d17eea76f21a5657fe9e4d582b12259eb3b3ce20777558427962546f696464727a5473774d4648674f577865436776577a55434d11626d687473636550415350717645486e79000101254ad9441c52455f648987368fcec3b49fde613e81eac0a6e3c6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bca159617075e88ad5fb7bead896fb12c489a50c6f00ebc5fd2e900a85f68de28e785a60e899c16119764c27ac010b9705e942c40090786c73c41cfc0d9b8f08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8aaeb25091303219507ad3951038a391a0d637ea7a366433e13e8e0f76e08e8a", - "sequence_number": "3650245720722201929", + "sender": "ae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ffcf5fe3baa3d2", + "sequence_number": "3232771898260856413", "payload": { "EntryFunction": { "module": { - "address": "b760fcb18efb1a1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc", - "name": "agCTHqS_Coin" + "address": "73786bc8508aebd92ad8bca5a8eea17fd86d9d10ad4fb4d9e74cdf6b55a646c9", + "name": "jVoUPKhQ_Coin" }, - "function": "twXCumwvRKkyHkLFNlcrjKdubKzmQ", + "function": "PiPU", "ty_args": [ { - "vector": "u8" - }, - { - "struct": { - "address": "84f60c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e", - "module": "jxHDjoD1", - "name": "uwlsZwYQqHXYvcc", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "46895e850147098c1fb148be67e13448ac08ddcfbd81539e992fb02ada5301bd", + "module": "HLHRVRNamWoacpyL9", + "name": "ZWDKMwPeFpuvWPZldsOEiYgK", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "4b0fae6efd27837e0911fc411d670201c0d351450191a259c2456696d850d2b5", - "module": "KTtJRhP1", - "name": "J", + "address": "1b829bb1297140a1b4f8acc0f5c04223a057915f03dadee3a8c4d86272701f22", + "module": "hJE9", + "name": "XDuewAgdedrqgoA", "type_args": [] } } }, { "vector": { - "struct": { - "address": "35963ddb8630e82e269215daa84595e17fc20f278b2005db88eae012fb19bb16", - "module": "gtDohRkIdLaXQPgwUgUt2", - "name": "ZqCWUoDxryp7", - "type_args": [] - } + "vector": "u64" } }, { "vector": { - "struct": { - "address": "407c122e80ea037e8db87f3d7797caefee068aa5241d168d5f921acd8198895b", - "module": "EPmsLEyncIsEajqPsZTKjajLyMMLB4", - "name": "VsbWUfYnYJ9", - "type_args": [] + "vector": { + "struct": { + "address": "26aa6b8e7fb4504d68f53f9ec39ce166e8ea3d8cdfe9abb4e512e3648dfb0f65", + "module": "RootYezUhUkI", + "name": "uwRwfrbbIQu", + "type_args": [] + } } } }, { "struct": { - "address": "e8a27f639c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31", - "module": "hfFszWkzZwMtJymBphlmPptmJfFjA", - "name": "HXxdnXNOoZtLSJwVcs", + "address": "f67d62313b4007e58ebd60c8ca62404c53558d1e3ad0303bba00b16019859bb2", + "module": "MDZezTUffhlmnqHshVpjYrUM7", + "name": "CgLVHVkz", + "type_args": [] + } + }, + { + "struct": { + "address": "0d512eb6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395a", + "module": "QgndOt", + "name": "usKARDxYdDDITqrXZIlbYjlCu", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "fafdcc2dc3eef830849524b0501a691e3257e8ba6b0691fc33b3d9ae834d615e", + "module": "SoGZtBPAtgUHiQBrohjf", + "name": "VFcjwqbNJROEcQZAfqJ5", + "type_args": [] + } + } } }, { "struct": { - "address": "edcdf1e1f14d239968c5ce2398b83ad8ed5a38986dd98ce3ed86ea05c192b84c", - "module": "CTvQEXSZyPtmYTMFxsegWnbNgQhKApwF9", - "name": "vkgLzdoBWrNvzF", + "address": "86c188d06128b79fafd44ff4e6f5e8b723061153365615ff82318bfb73ba9589", + "module": "qnrhHywhEkTceeHMGfnWOEYiicEhnp", + "name": "rOvAfEMEdPs", "type_args": [] } } ], - "args": [ - "46eef7c7e0a4aa3c818cc6e7db82ac8e", - "169ebac73b5d1e39", - "20", - "25" - ] + "args": [] } }, - "max_gas_amount": "5884333008804670626", - "gas_unit_price": "4248460506912669358", - "expiration_timestamp_secs": "11382274384853212882", - "chain_id": 216 + "max_gas_amount": "7115867385316374095", + "gas_unit_price": "2498960324979615472", + "expiration_timestamp_secs": "7488013861149748261", + "chain_id": 144 }, - "signed_txn_bcs": "8aaeb25091303219507ad3951038a391a0d637ea7a366433e13e8e0f76e08e8a495d89a62447a83202b760fcb18efb1a1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc0c616743544871535f436f696e1d74775843756d7776524b6b79486b4c464e6c63726a4b6475624b7a6d510806010784f60c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e086a7848446a6f44310f75776c735a775951714858597663630006074b0fae6efd27837e0911fc411d670201c0d351450191a259c2456696d850d2b5084b54744a52685031014a00060735963ddb8630e82e269215daa84595e17fc20f278b2005db88eae012fb19bb16156774446f68526b49644c61585150677755675574320c5a714357556f447872797037000607407c122e80ea037e8db87f3d7797caefee068aa5241d168d5f921acd8198895b1e45506d734c45796e63497345616a7150735a544b6a616a4c794d4d4c42340b567362575566596e594a390007e8a27f639c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede311d686646737a576b7a5a774d744a796d4270686c6d5070746d4a66466a4112485878646e584e4f6f5a744c534a775663730006060207edcdf1e1f14d239968c5ce2398b83ad8ed5a38986dd98ce3ed86ea05c192b84c21435476514558535a7950746d59544d4678736567576e624e6751684b41707746390e766b674c7a646f4257724e767a4600041046eef7c7e0a4aa3c818cc6e7db82ac8e08169ebac73b5d1e3901200125a26ce8e9b159a951ae3ece5c5290f53ad21e34453ff6f59dd8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bf9e2816707d750833ad7cdafb9575e1ae28fe9ec7d05f540eed23e1a2bd8533ad861fedc872214c4ed0af5375de72615923623a6f6e795a2168da2045a4a904", + "signed_txn_bcs": "ae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ffcf5fe3baa3d25d1eb4dbe91cdd2c0273786bc8508aebd92ad8bca5a8eea17fd86d9d10ad4fb4d9e74cdf6b55a646c90d6a566f55504b68515f436f696e04506950550806060746895e850147098c1fb148be67e13448ac08ddcfbd81539e992fb02ada5301bd11484c485256524e616d576f616370794c39185a57444b4d7750654670757657505a6c64734f456959674b0006071b829bb1297140a1b4f8acc0f5c04223a057915f03dadee3a8c4d86272701f2204684a45390f584475657741676465647271676f410006060206060726aa6b8e7fb4504d68f53f9ec39ce166e8ea3d8cdfe9abb4e512e3648dfb0f650c526f6f7459657a5568556b490b75775277667262624951750007f67d62313b4007e58ebd60c8ca62404c53558d1e3ad0303bba00b16019859bb2194d445a657a54556666686c6d6e7148736856706a5972554d370843674c5648566b7a00070d512eb6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395a0651676e644f741975734b415244785964444449547172585a496c62596a6c437500060607fafdcc2dc3eef830849524b0501a691e3257e8ba6b0691fc33b3d9ae834d615e14536f475a7442504174675548695142726f686a66145646636a7771624e4a524f4563515a4166714a35000786c188d06128b79fafd44ff4e6f5e8b723061153365615ff82318bfb73ba95891e716e726848797768456b54636565484d47666e574f455969696345686e700b724f764166454d4564507300004ff6917aafa3c062f06634ee2c17ae22252c08fbeec4ea6790002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099c4f579e65e9105e449c52c87517a8afe6e42dc0930127c0d5dcef3ee89bc4dc6d9862134c94b9ea2a8d37c89d4034070d29a952dec0371e67a3ec358ab8c07", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6e68e0ad33e9f661b98c5b96845453e9f99228db8f07a738992cb0304c1e7af8", - "sequence_number": "1181733586840230246", + "sender": "73e80cbe2a7518d6909c900f7b8aa28e1a5f7c92b2fe2b5b6361910b1ee8b347", + "sequence_number": "15423139578077517809", "payload": { "EntryFunction": { "module": { - "address": "e578695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e", - "name": "Paa6_Coin" + "address": "550f12209576637decf60eef4724cd4aad06d5c3eb5e0b4fecdfc04ac8bec02a", + "name": "rWTEUsZIQSWOoIrglrcns_Coin" }, - "function": "KfoiqU5", + "function": "vRgskcbuPRVnUSVqsmefNoMQE", "ty_args": [ { "struct": { - "address": "c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1f677737", - "module": "JuLzUFZDlaeEAUXXcktsmKxlBbLkbi", - "name": "h", + "address": "ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9ea2537f7d883265", + "module": "QzKaAxyCoolrKfuo5", + "name": "crHuBiIbMXJDdKSKinmFWqxy", "type_args": [] } }, { - "struct": { - "address": "3bc73f2bbebc764dc695ee79269016358487ada21e8df73f0060784e93ed4d57", - "module": "ArLgWuMyyfBobXSqtBkBIFsV", - "name": "kr1", - "type_args": [] + "vector": { + "vector": { + "vector": "address" + } } }, { - "vector": "bool" - }, - "bool", - { - "struct": { - "address": "b237f4af9061e1c882774c1bb050ed57d2eeff4a728782312d246b24c8ec98e0", - "module": "QYNbEBaWjqeoXDLYiQPWcYdFHrqxt", - "name": "ovVFJv", - "type_args": [] - } - }, + "vector": "u8" + } + ], + "args": [] + } + }, + "max_gas_amount": "5665905787442427844", + "gas_unit_price": "2003020702888368619", + "expiration_timestamp_secs": "1755321824711168510", + "chain_id": 94 + }, + "signed_txn_bcs": "73e80cbe2a7518d6909c900f7b8aa28e1a5f7c92b2fe2b5b6361910b1ee8b347f1179420bbff09d602550f12209576637decf60eef4724cd4aad06d5c3eb5e0b4fecdfc04ac8bec02a1a7257544555735a495153574f6f4972676c72636e735f436f696e19765267736b6362755052566e55535671736d65664e6f4d51450307ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9ea2537f7d88326511517a4b61417879436f6f6c724b66756f351863724875426949624d584a44644b534b696e6d46577178790006060604060100c4f7555f4b57a14eeb196a81b728cc1bfe516644e6275c185e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408e8d5a929965598c1c0a03936195a06f2dcfc6589ce7689ed24be315e47f4d6f531320998f20bf1099aa71cc5d235c6b854e57e0c352a3f0e90092889851770d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "e8e8d6d9bec0f7e38f646fb48bffaa8cffaec917695855b70e76e575b0b6846e", + "sequence_number": "4947151182958275233", + "payload": { + "EntryFunction": { + "module": { + "address": "dafe9577c79423fcf91bb0ea8c0ab2001b1f7687d7a91b183becc248400061e9", + "name": "cdnjaXeohdyH_Coin" + }, + "function": "sgVOHUVurbHbUkmraNYYOhT", + "ty_args": [ { - "struct": { - "address": "5be8c524a4be5a8dd5fbcd9ab4976161591109d7390658bd0bb2670f01f377a8", - "module": "idvTEzFyQWfqeUEInUJ", - "name": "RyQcMvCLtYkzYdNeQIdSiDFzUwPkun9", - "type_args": [] - } + "vector": "u8" }, { - "struct": { - "address": "96125ef1cc0232eae11f227a6a451644705947fb42465af5aac885cc6fde9712", - "module": "q0", - "name": "gwGzAI1", - "type_args": [] + "vector": { + "vector": "bool" } }, { "struct": { - "address": "22f6247faf0b55e979ef3b055d0acadc8d334add4e6cba205642d27c92d23e91", - "module": "MQrgNAOtlavkInbDZOzXylRDH", - "name": "fxyfPeLOSUZAZqy", + "address": "afb5954807f598aabb0a0aceb9e400368717115e8571e223d7c137b148850123", + "module": "YfksWinaKGxGjHpMKW1", + "name": "XTpcoFnh", "type_args": [] } } ], "args": [ - "1aee8e8be8ea6a12ff47aecebdbb9908413c789e54f90230798a4dabd0ad9b50", - "01" + "5c", + "9f04aa7cace870708c215ca397aa21bb", + "00", + "41016c23687433de", + "31f51bf513eb3a88", + "00", + "ce283dc2d678c910e40215ab91e95e13601bed4cd25247d59a14f2215f011143", + "39fc570a86f18f3d", + "d7c6cbdf962ccc95" ] } }, - "max_gas_amount": "12299265788543233336", - "gas_unit_price": "2447077526551110119", - "expiration_timestamp_secs": "12689068831543315256", - "chain_id": 127 + "max_gas_amount": "7574570237970311197", + "gas_unit_price": "75889477014785962", + "expiration_timestamp_secs": "5097396785493781993", + "chain_id": 181 }, - "signed_txn_bcs": "6e68e0ad33e9f661b98c5b96845453e9f99228db8f07a738992cb0304c1e7af86699c2a66f5c661002e578695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e09506161365f436f696e074b666f697155350807c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1f6777371e4a754c7a55465a446c61654541555858636b74736d4b786c42624c6b6269016800073bc73f2bbebc764dc695ee79269016358487ada21e8df73f0060784e93ed4d571841724c6757754d797966426f6258537174426b4249467356036b72310006000007b237f4af9061e1c882774c1bb050ed57d2eeff4a728782312d246b24c8ec98e01d51594e62454261576a71656f58444c5969515057635964464872717874066f7656464a7600075be8c524a4be5a8dd5fbcd9ab4976161591109d7390658bd0bb2670f01f377a81369647654457a467951576671655545496e554a1f527951634d76434c74596b7a59644e65514964536944467a5577506b756e39000796125ef1cc0232eae11f227a6a451644705947fb42465af5aac885cc6fde9712027130076777477a414931000722f6247faf0b55e979ef3b055d0acadc8d334add4e6cba205642d27c92d23e91194d5172674e414f746c61766b496e62445a4f7a58796c5244480f6678796650654c4f53555a415a71790002201aee8e8be8ea6a12ff47aecebdbb9908413c789e54f90230798a4dabd0ad9b50010138ed3b0412c5afaae7a1eb930bc4f52138cb9e6adfa018b07f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444067352af2794582fc7998a7819d3fcd14db0838015c0cb79230ddabcef1bc22d0c3a47340b692ca6b73765c96acee4c8de811acfb4d483ef883f1b21fd9298901", + "signed_txn_bcs": "e8e8d6d9bec0f7e38f646fb48bffaa8cffaec917695855b70e76e575b0b6846ea1aa612ecacfa74402dafe9577c79423fcf91bb0ea8c0ab2001b1f7687d7a91b183becc248400061e91163646e6a6158656f686479485f436f696e177367564f4855567572624862556b6d72614e59594f685403060106060007afb5954807f598aabb0a0aceb9e400368717115e8571e223d7c137b1488501231359666b7357696e614b4778476a48704d4b573108585470636f466e680009015c109f04aa7cace870708c215ca397aa21bb01000841016c23687433de0831f51bf513eb3a88010020ce283dc2d678c910e40215ab91e95e13601bed4cd25247d59a14f2215f0111430839fc570a86f18f3d08d7c6cbdf962ccc951d6877e87f471e69aa0fa8c7139d0d01e92d93865e97bd46b5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bfd19cdd774f90dc96cca3f9a54372c908f4567da0abb27ec8a160bb1abd79ed881517d7f8a15db7608588227872a47c3df8b0eb7da672204ced5956cd9e9907", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c5060b74d8c2b77634d479babf1116ec5e19873da563694e5370446e8d184014", - "sequence_number": "2661518262186350512", + "sender": "257527d9b8f0e72f0dda5c1b8a310b223b79d7db732047478ee6f11222f91731", + "sequence_number": "12893816990267342013", "payload": { "EntryFunction": { "module": { - "address": "4d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd0", - "name": "E_Coin" + "address": "6ae8e083bd57f456c2c58450c26b97edf60b8ab6badb48aacded72a841dd5b52", + "name": "VwRYoFmHKXJxSA7_Coin" }, - "function": "aDLohvvIvQKtcyACxQmaX9", + "function": "GRVInjXGYtR4", "ty_args": [ { "vector": { "struct": { - "address": "90d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243dc8c", - "module": "KvQtgzJAWNRrRDS7", - "name": "GcYUHfqbwVhdAPlFtsuhyfn", + "address": "2cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d493897", + "module": "pkSEw", + "name": "dEiWd", "type_args": [] } } @@ -2818,2172 +3371,2058 @@ { "vector": { "struct": { - "address": "ea5dee94e3230121db18557fe26185a802d7e6a05211865b69df4006a130327f", - "module": "MHG2", - "name": "VycyNfpy", + "address": "de01266242e66fd40bfe5a784f5909bd3e1bf76670789295207afe2a063e3ed8", + "module": "zbPNRneLC", + "name": "nCxQqwGECxcXnjTxrqKVHzjpZwJBK", "type_args": [] } } }, - { - "struct": { - "address": "f3ce42c13d3881af5aac0dae2119d6dff76f745ecc3c78bd29f501d64789b6f3", - "module": "gWVWeNVMWETXsuijxERtfeC5", - "name": "oAfHUUoYORtVvROilnUEfhvuqh4", - "type_args": [] - } - }, - { - "vector": { - "vector": "u64" - } - }, { "vector": { - "vector": { - "struct": { - "address": "bcb067e6b1499c3e6204ea45da1ce0b210b77991d7edbeb1fe9298b472df0df8", - "module": "ywTYIBLkosJCVfv", - "name": "KrDwpqv6", - "type_args": [] - } + "struct": { + "address": "85779fc9877a0dcb4f7a1d0291e46f612354927bb537c37e66b1b85b20a85455", + "module": "YKWjbun3", + "name": "CCzbZvhfcbBXKbbsl2", + "type_args": [] } } }, { - "struct": { - "address": "f11988aab4ee79dfc570b7437e0c0bd4def6cb891a7347ae094e4b3c258cd516", - "module": "yytLeOaasOOrvqxDsvvYUlqoGhvjga8", - "name": "xEaHOQWHipXMV", - "type_args": [] - } - }, - { - "struct": { - "address": "0333cd96931f1bad3d82db0262ea607436d542029de57e8e3c5121dedae396c5", - "module": "oKVncYwEFIaBLSqgoHfKUaSsNQpYtlT9", - "name": "ycWBzuriCQnGXowcgaHkXIpUoGSNQA3", - "type_args": [] - } + "vector": "u128" }, { "vector": { "struct": { - "address": "372d7507a38d095e855bb72e331c47441797854e3aa0a265525ca001682ad302", - "module": "DQqqBhm", - "name": "ibjNBXuDkjpSjEk", + "address": "688f07e88dfa2f7d890e34ea9e63cba557678f69ec1653a27a14157184fe4c06", + "module": "FefTzMxCWpSZ", + "name": "rnmSHCOcwfoQtN1", "type_args": [] } } }, { "struct": { - "address": "47f21e96adfe45ba131ef7a125501ccae1261fc78089ba5308ae84a356f2bb51", - "module": "LwpWvqKug", - "name": "NRKYXugJOpy2", - "type_args": [] - } - }, - { - "struct": { - "address": "4edba3a64aabefd88bb8d4277524a8d8ce1d54b6b731147a310ea667265fe6b1", - "module": "RdhfMBNnukrjIqhVVkCEzszGhwolWx", - "name": "wcBQHYeXXnTQo", + "address": "55a60351155d914f98806fd3c8ca1a9b0318d505448519f2b13fd16038c18acb", + "module": "qouZKJaxddeI", + "name": "FZWWqWBvPhXMQIqNHBgCgvp", "type_args": [] } } ], "args": [ + "23bed6af8448e4428a2d6af7eb957bdae932d161de1efd530a65c68044300b4a", "01", - "965cc75f7e165519", - "88d5d9f1f9d09da3", - "a5b44163a83bcd8f", - "00", - "b86cd934672cabddb3938959beb85848", - "4435e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8", - "3d", - "ea4df748ffe7484c5ddb343806f0d27353aca094eb30a37bf5e1d59babda026f", - "01aa605e59aceebc380d4a5b19f1ab1504f50f340a07c3555500e2004f77c6dc" + "39b06f23c05a0cf1", + "829db1554e59fb0b", + "26", + "ce", + "9433c1c7bd507716b06cb72368f51153", + "f495573280c9bacb6d036a34a12342cd", + "146deaa34d074241" ] } }, - "max_gas_amount": "5728441886086910062", - "gas_unit_price": "1056590787584835226", - "expiration_timestamp_secs": "7238184894938488041", - "chain_id": 60 + "max_gas_amount": "1019463178458680298", + "gas_unit_price": "10482196570888853610", + "expiration_timestamp_secs": "14142035163590226473", + "chain_id": 99 }, - "signed_txn_bcs": "c5060b74d8c2b77634d479babf1116ec5e19873da563694e5370446e8d184014b017d514c29cef24024d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd006455f436f696e1661444c6f6876764976514b746379414378516d6158390a060790d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243dc8c104b765174677a4a41574e5272524453371747635955486671627756686441506c467473756879666e000607ea5dee94e3230121db18557fe26185a802d7e6a05211865b69df4006a130327f044d48473208567963794e6670790007f3ce42c13d3881af5aac0dae2119d6dff76f745ecc3c78bd29f501d64789b6f31867575657654e564d574554587375696a78455274666543351b6f41664855556f594f52745676524f696c6e55456668767571683400060602060607bcb067e6b1499c3e6204ea45da1ce0b210b77991d7edbeb1fe9298b472df0df80f7977545949424c6b6f734a43566676084b724477707176360007f11988aab4ee79dfc570b7437e0c0bd4def6cb891a7347ae094e4b3c258cd5161f7979744c654f6161734f4f727671784473767659556c716f4768766a6761380d784561484f5157486970584d5600070333cd96931f1bad3d82db0262ea607436d542029de57e8e3c5121dedae396c5206f4b566e63597745464961424c5371676f48664b556153734e517059746c54391f796357427a75726943516e47586f77636761486b584970556f47534e514133000607372d7507a38d095e855bb72e331c47441797854e3aa0a265525ca001682ad302074451717142686d0f69626a4e425875446b6a70536a456b000747f21e96adfe45ba131ef7a125501ccae1261fc78089ba5308ae84a356f2bb51094c77705776714b75670c4e524b595875674a4f70793200074edba3a64aabefd88bb8d4277524a8d8ce1d54b6b731147a310ea667265fe6b11e526468664d424e6e756b726a49716856566b43457a737a4768776f6c57780d7763425148596558586e54516f000a010108965cc75f7e1655190888d5d9f1f9d09da308a5b44163a83bcd8f010010b86cd934672cabddb3938959beb85848204435e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8013d20ea4df748ffe7484c5ddb343806f0d27353aca094eb30a37bf5e1d59babda026f2001aa605e59aceebc380d4a5b19f1ab1504f50f340a07c3555500e2004f77c6dc6ed0ad788b837f4f9abef126b9c3a90ee91c68f9cf3273643c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ccbd41f5b7ee3024137768cb15898712ce2c7d5e988113c979777b67f9578919a479050c398953e55c7c96ecf78bd019f822e044d6250e3e4bca79c40f3fb709", + "signed_txn_bcs": "257527d9b8f0e72f0dda5c1b8a310b223b79d7db732047478ee6f11222f91731bdfcc7ff3c0af0b2026ae8e083bd57f456c2c58450c26b97edf60b8ab6badb48aacded72a841dd5b5214567752596f466d484b584a785341375f436f696e0c475256496e6a5847597452340606072cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d49389705706b534577056445695764000607de01266242e66fd40bfe5a784f5909bd3e1bf76670789295207afe2a063e3ed8097a62504e526e654c431d6e43785171774745437863586e6a547872714b56487a6a705a774a424b00060785779fc9877a0dcb4f7a1d0291e46f612354927bb537c37e66b1b85b20a8545508594b576a62756e331243437a625a766866636242584b6262736c320006030607688f07e88dfa2f7d890e34ea9e63cba557678f69ec1653a27a14157184fe4c060c466566547a4d78435770535a0f726e6d5348434f6377666f51744e31000755a60351155d914f98806fd3c8ca1a9b0318d505448519f2b13fd16038c18acb0c716f755a4b4a61786464654917465a5757715742765068584d5149714e4842674367767000092023bed6af8448e4428a2d6af7eb957bdae932d161de1efd530a65c68044300b4a01010839b06f23c05a0cf108829db1554e59fb0b012601ce109433c1c7bd507716b06cb72368f5115310f495573280c9bacb6d036a34a12342cd08146deaa34d074241eacb9e055cdc250e6ad8a5813e3e789129f2e0b60d9a42c463002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b19904e5c0c372eebad399a9861ef92d01d725d42fb4342f0e6d404cc36e127b9683dd838d09d83a7e0a2cf1e3f78bff811d3e7edf6ce0f755d0fc7aa068dd01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7254d81e6cd63469d0aeed8fbb476479b948af8eeffeb15f34be6842fbf0bac6", - "sequence_number": "18425695080377418547", + "sender": "296a4cee8bb28c535f0ea3679d099e007e89b193a1e1af9e79ef63b5d8c95972", + "sequence_number": "16948937482465331656", "payload": { "EntryFunction": { "module": { - "address": "9f822008cc50b496e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b9", - "name": "ksNwXIpN_Coin" + "address": "2cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a4a27a60a14", + "name": "uyrzFEEzOYvZZrQepa_Coin" }, - "function": "eKDZhMPLwuQJfLMbrch6", + "function": "hkGOVee", "ty_args": [ { "struct": { - "address": "532465ba437df458f0cbda3a6ac9b2d6cd8e5ba486d85c0b4dbee8fdee4888e5", - "module": "HalCmreIzHWOKDpvQ", - "name": "q", + "address": "5e44c552952ad191a75f2d853cd0f99b7c62d641e7b82c8343ba8e40711aed2f", + "module": "xuTtkrHaTINNqpyQsHkEkCUiDupa5", + "name": "bnOnHIgAPtUvAOukYvYRw", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "6cfd87928c20ea3f3eb92942b45631e480dfd6fa84f91bbbf5fc7f48ba522a37", + "module": "VyoVVKJSsWKyWDm2", + "name": "fCmDqktVEohvhartHPcxrmgQ7", + "type_args": [] + } + } + }, { "struct": { - "address": "831b1513110f2916e1bf4949f3b62752be3f2ecbc4cc27a057bcfb06cab444c0", - "module": "VjrOY5", - "name": "CiqYXOVFdTvTnLi4", + "address": "4f7ada52a7b0ec0af67885272fea779a93ae4ace8074e87180fb9f72590bccfe", + "module": "EgGyel9", + "name": "WbWjwCMsFpiajz5", "type_args": [] } }, { "struct": { - "address": "f2d60796d768bbcc9533f401ac3312411bbbdea3dfb6cd40ae4155ee0e993239", - "module": "YyNGJBwVlcUiSFrTdnVdczfOUarN9", - "name": "LOmUQtaOGNXykCYvbPrbLBX1", + "address": "c6315465f3b9e3e6d6b7a5b0274486d4b7ebbc1710eb70fc35b24647850515ab", + "module": "LisCD", + "name": "AO2", "type_args": [] } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "33cae74acbdf24b28438727a1dae624275f72b362c670af08b0e298f78760fb6", + "module": "CTBnonPFtjavGlAjqpRFsAxgrcjcF8", + "name": "wHdhTehrftcWRszZIpnZF", + "type_args": [] } }, { "struct": { - "address": "b00f8e4b6864958e29cb8e72b8af508a8a452f8f5bff57d1238f1d98d53e83b1", - "module": "cgCrNjRVEWSmvvZNSs", - "name": "sPXzCwMydK", + "address": "a847955df25f5a8252001d36886356be2617b44125825e635ce66861c87aa081", + "module": "SoWoQgDAUzuHgNOwQoLHGrEu", + "name": "OAPWesKZZlycdEjPJL3", "type_args": [] } }, { "vector": { "struct": { - "address": "c78ebe83eb4973283459cb133f10db368fa77296571a37f819d92c0886536fc5", - "module": "XeAomAYZkgpVWTJUdjmRTExa", - "name": "SEClvMeXzuSYUhFJwdMth5", + "address": "14c58ccf9bfa629f45fe36c4491f175f7ee16df237bd450d348c216ec06ccf63", + "module": "HbLcefVu4", + "name": "SCsrRGEyfQ", "type_args": [] } } - }, - { - "vector": "u64" } ], "args": [ - "10258ac91238ec19", - "15", - "718a1ff0133c0ff998d730d55fc8921a", - "8a" + "6933cfd988544e4d1116a53cbd50bb8c98b91aed5b59723b6584f60c65ede80f", + "b4456c26a607b4b952d03f781b28c311f0056c231b355cf92e1730ab083ebb00" ] } }, - "max_gas_amount": "9642444206990112737", - "gas_unit_price": "8269609754187846819", - "expiration_timestamp_secs": "7138260881688368457", - "chain_id": 74 + "max_gas_amount": "18433573115159890309", + "gas_unit_price": "2706418751625183888", + "expiration_timestamp_secs": "9888836989083813752", + "chain_id": 150 }, - "signed_txn_bcs": "7254d81e6cd63469d0aeed8fbb476479b948af8eeffeb15f34be6842fbf0bac633038f550d38b5ff029f822008cc50b496e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b90d6b734e775849704e5f436f696e14654b445a684d504c7775514a664c4d62726368360707532465ba437df458f0cbda3a6ac9b2d6cd8e5ba486d85c0b4dbee8fdee4888e51148616c436d7265497a48574f4b4470765101710007831b1513110f2916e1bf4949f3b62752be3f2ecbc4cc27a057bcfb06cab444c006566a724f59351043697159584f5646645476546e4c69340007f2d60796d768bbcc9533f401ac3312411bbbdea3dfb6cd40ae4155ee0e9932391d59794e474a4277566c63556953467254646e5664637a664f5561724e39184c4f6d555174614f474e58796b435976625072624c4258310006060207b00f8e4b6864958e29cb8e72b8af508a8a452f8f5bff57d1238f1d98d53e83b112636743724e6a52564557536d76765a4e53730a7350587a43774d79644b000607c78ebe83eb4973283459cb133f10db368fa77296571a37f819d92c0886536fc5185865416f6d41595a6b67705657544a55646a6d5254457861165345436c764d65587a7553595568464a77644d746835000602040810258ac91238ec19011510718a1ff0133c0ff998d730d55fc8921a018ae1372b1cebd7d085a3d478d5418ec37249151aa7733210634a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401ff24fde13a4f79dbfb36c0f68a36f18dd2823dfb3082014575b091558faf697e195a3cd1c242c71db30d2ad976830c9233d8b50d5079f29730b1dbf6b78e304", + "signed_txn_bcs": "296a4cee8bb28c535f0ea3679d099e007e89b193a1e1af9e79ef63b5d8c95972c849a64ad7b836eb022cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a4a27a60a14177579727a4645457a4f59765a5a72516570615f436f696e07686b474f56656507075e44c552952ad191a75f2d853cd0f99b7c62d641e7b82c8343ba8e40711aed2f1d787554746b72486154494e4e7170795173486b456b435569447570613515626e4f6e4849674150745576414f756b59765952770006076cfd87928c20ea3f3eb92942b45631e480dfd6fa84f91bbbf5fc7f48ba522a371056796f56564b4a5373574b7957446d321966436d44716b7456456f68766861727448506378726d67513700074f7ada52a7b0ec0af67885272fea779a93ae4ace8074e87180fb9f72590bccfe0745674779656c390f5762576a77434d73467069616a7a350007c6315465f3b9e3e6d6b7a5b0274486d4b7ebbc1710eb70fc35b24647850515ab054c6973434403414f32000733cae74acbdf24b28438727a1dae624275f72b362c670af08b0e298f78760fb61e4354426e6f6e5046746a6176476c416a717052467341786772636a6346381577486468546568726674635752737a5a49706e5a460007a847955df25f5a8252001d36886356be2617b44125825e635ce66861c87aa08118536f576f51674441557a7548674e4f77516f4c4847724575134f41505765734b5a5a6c796364456a504a4c3300060714c58ccf9bfa629f45fe36c4491f175f7ee16df237bd450d348c216ec06ccf630948624c6365665675340a534373725247457966510002206933cfd988544e4d1116a53cbd50bb8c98b91aed5b59723b6584f60c65ede80f20b4456c26a607b4b952d03f781b28c311f0056c231b355cf92e1730ab083ebb0085c94b3e1535d1ff904213f083218f2578871528d9343c8996002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f85854c6c6ebbc2208a99ad9682ed99fec7f22fb7873166077cd7a566f061560ab9a9d81cf7bc0e72e42ffeecef6d70bd1e96a00edcb1067cde2cde396691207", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9fa37e9249deb0745364a55ab954875a52f3e4fc267d468295017ee89ef2eda4", - "sequence_number": "5440367760114619002", + "sender": "07011ab22a2d46a7a5bace8bbe0fecd63e8a43c99a0161d7c605a5bd7796391d", + "sequence_number": "14383908686984374315", "payload": { "EntryFunction": { "module": { - "address": "e3213dcf59716f356786e68ed618ac575632846940c9351bc855deb6f95aae61", - "name": "XgIGrNQCfFHTrranyEgidjAuRG6_Coin" + "address": "0221c4ab6cc3cdec859c22fc2efc42149cfedae37180ce2f8a1a13a55dc18f27", + "name": "LZIkICdTZnEeURuTVpTgvAxuXitK7_Coin" }, - "function": "SKwNWePYJyTHAeRpZKvwevtH6", + "function": "AeLqou4", "ty_args": [ { "struct": { - "address": "8d6a4364b105765c8be7684c5b00afe6117a71569c40694bc075f4f910ca97e5", - "module": "MusMwIshTNPkUvCn", - "name": "JXLluQSKqqlU6", + "address": "1f64d13cf3fa7bf0312b7f80a4b586a9515970e72f40b8b3fd3aa43fcc7a48ce", + "module": "nTxWKsxkZhbHyaNSUJIUQi", + "name": "kiPddEDtfZavbNbryVVbTAuATStogaky0", "type_args": [] } }, { "struct": { - "address": "1fc5245eefc2e42b7a8f5355ae03990c3c92ce07a096d21168873bb3adbbc79a", - "module": "AjtfUWbNmQvCcyrOFBSKz", - "name": "beTkiyfsqioWvqAl6", + "address": "adc085e5049cd811f6779e0d679725301d92c976bbeaee4e53c1235ce91e54bd", + "module": "XcvjgMfsasHczWYNZHJiGoeeYAmt", + "name": "lzAaaBQqfQnlkhYNovCASjehLSotSUq", "type_args": [] } }, + { + "vector": { + "vector": "address" + } + }, { "struct": { - "address": "80e5a4d6d14747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f2", - "module": "whACmG5", - "name": "QECjYfzRnOewSnZwugrbMKNupSaIWZa2", + "address": "9c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31e93b09bb", + "module": "KRXioruWBjTzbrWzzLcwscGvA0", + "name": "vcGdQLsfL4", "type_args": [] } + }, + { + "vector": { + "vector": "bool" + } + }, + { + "vector": { + "struct": { + "address": "178780bad8ea54ffa6652d9f23fd71c3ab59fcb4f1dfde7f20231b953616ec30", + "module": "zcushBPHoFHpMGpaGSvZ8", + "name": "IOzPYJqfCFuzeaNxbsblOTEHcmfUHQ", + "type_args": [] + } + } } ], "args": [ - "7f", + "92", + "63", + "074f5f2b5112e5ce2f0b70201d3191ed5c7caa9462cf866cd9840e397905f0fe", + "dcfbe536fc66b72ecdb77743cd9427fe", "00" ] } }, - "max_gas_amount": "11639940403674919501", - "gas_unit_price": "6877393875617437492", - "expiration_timestamp_secs": "9119006124175631920", - "chain_id": 49 + "max_gas_amount": "14770297084228111933", + "gas_unit_price": "17612041824152283443", + "expiration_timestamp_secs": "13591195005148563315", + "chain_id": 184 }, - "signed_txn_bcs": "9fa37e9249deb0745364a55ab954875a52f3e4fc267d468295017ee89ef2eda47a921e4da711804b02e3213dcf59716f356786e68ed618ac575632846940c9351bc855deb6f95aae612058674947724e5143664648547272616e79456769646a41755247365f436f696e19534b774e576550594a795448416552705a4b7677657674483603078d6a4364b105765c8be7684c5b00afe6117a71569c40694bc075f4f910ca97e5104d75734d77497368544e506b5576436e0d4a584c6c7551534b71716c553600071fc5245eefc2e42b7a8f5355ae03990c3c92ce07a096d21168873bb3adbbc79a15416a74665557624e6d5176436379724f4642534b7a116265546b6979667371696f577671416c36000780e5a4d6d14747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f207776841436d4735205145436a59667a526e4f6577536e5a77756772624d4b4e7570536149575a61320002017f01004db2c247206089a134d79fb84a69715f30a61960c1378d7e31002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444044838a0133a927c315eb420d6a7fc4cb06373f549025c80c44d8ec0bb51aaa0e2f43c65ef338cd7c4f0aff26226b3e99ff4eeeeec19224fe274fa6615fdac70c", + "signed_txn_bcs": "07011ab22a2d46a7a5bace8bbe0fecd63e8a43c99a0161d7c605a5bd7796391d2be85bd9bde89dc7020221c4ab6cc3cdec859c22fc2efc42149cfedae37180ce2f8a1a13a55dc18f27224c5a496b494364545a6e45655552755456705467764178755869744b375f436f696e0741654c716f753406071f64d13cf3fa7bf0312b7f80a4b586a9515970e72f40b8b3fd3aa43fcc7a48ce166e5478574b73786b5a68624879614e53554a49555169216b69506464454474665a6176624e627279565662544175415453746f67616b79300007adc085e5049cd811f6779e0d679725301d92c976bbeaee4e53c1235ce91e54bd1c5863766a674d6673617348637a57594e5a484a69476f656559416d741f6c7a41616142517166516e6c6b68594e6f764341536a65684c536f7453557100060604079c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31e93b09bb1a4b5258696f727557426a547a6272577a7a4c63777363477641300a76634764514c73664c34000606000607178780bad8ea54ffa6652d9f23fd71c3ab59fcb4f1dfde7f20231b953616ec30157a637573684250486f4648704d4770614753765a381e494f7a50594a71664346757a65614e786273626c4f544548636d6655485100050192016320074f5f2b5112e5ce2f0b70201d3191ed5c7caa9462cf866cd9840e397905f0fe10dcfbe536fc66b72ecdb77743cd9427fe01003d8e6714f1a2facc3369ebf9b98a6af47387f112d99f9dbcb8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440918e9cfc1402a9f003a716ba53c29b20eef9a487673f0384130dce6f5172b773046f8eba37d15c52640a8cd8267045b0d9386812f28030a7ed1b5a14788a6804", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "211b76aa0eb38de432a867e89b7653078289fb149c2c7f27f4bccd1de358fedb", - "sequence_number": "16672653382472951230", + "sender": "5db903504d1e56d51ed9c486dc34233eec2bd24ba8e4299eda7689f94715b973", + "sequence_number": "9237185929491568159", "payload": { "EntryFunction": { "module": { - "address": "aaae3c1c17e7b00c1638166e720c137b161d8d34d6c89ad36285cadbb66948c5", - "name": "pKbyGHIVTrpp3_Coin" + "address": "a4601d808a04bb26814df344840a3531e8406b3d8dbc1a25b4782644e7c98e12", + "name": "bqrUzbFADSRPYUKOpuClpNgxbiHhPm_Coin" }, - "function": "FecKCcpIOCuUkNkWkLHXrmoEqJpJg", - "ty_args": [ - { - "struct": { - "address": "56fe145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165", - "module": "eiZfrhMZjgk6", - "name": "GyNuKiaTJgOkgVxgFYYeJBeS", - "type_args": [] - } - } - ], - "args": [ - "2a447964c7a6e460141710c7d872103d", - "65f23d7d081ee4f6", - "b4c16d8fab7bd558" - ] + "function": "qhxNYjEuRpbaHIGOt", + "ty_args": [], + "args": [] } }, - "max_gas_amount": "9274521249931839578", - "gas_unit_price": "4427760382647208866", - "expiration_timestamp_secs": "10084278143191037357", - "chain_id": 173 + "max_gas_amount": "10607121249944982121", + "gas_unit_price": "5968632341615920307", + "expiration_timestamp_secs": "15415890371698324302", + "chain_id": 234 }, - "signed_txn_bcs": "211b76aa0eb38de432a867e89b7653078289fb149c2c7f27f4bccd1de358fedbbee58375ea2961e702aaae3c1c17e7b00c1638166e720c137b161d8d34d6c89ad36285cadbb66948c512704b62794748495654727070335f436f696e1d4665634b436370494f4375556b4e6b576b4c4858726d6f45714a704a67010756fe145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc1650c65695a6672684d5a6a676b361847794e754b6961544a674f6b67567867465959654a4265530003102a447964c7a6e460141710c7d872103d0865f23d7d081ee4f608b4c16d8fab7bd5585ac8ff33f0b7b580a20b3cd69b90723dad3523dd8a8df28bad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f286b2088dc127928a1ba9c6bad0eb18e7b2561ccf58916f64f442fc73aacabf88b7be6d086244ce01fa9274f1d6fe96ca1fd31cee578a11d01c7e8f184dd90f", + "signed_txn_bcs": "5db903504d1e56d51ed9c486dc34233eec2bd24ba8e4299eda7689f94715b9731fd69483a913318002a4601d808a04bb26814df344840a3531e8406b3d8dbc1a25b4782644e7c98e1223627172557a6246414453525059554b4f7075436c704e677862694868506d5f436f696e117168784e596a4575527062614849474f74000069d277f093103493b3c4ecd47dd7d4524e7371bd9d3ef0d5ea002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409096f12867efdb7ec0da7c0e68ceee58ea52eed2d50f24d45ac7e006775caa14a6b02e3c222bb17c3bb289f76286e44f06b291c4b341d0329a59310d17d77009", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d8bb3d6f84e4207faf1b0050be34fbf697514d5fb5cce2b1adb116be4ab544c4", - "sequence_number": "9030378947015319143", + "sender": "a7a6ad8a57493204fc0ec8202b5abb3d80352876bbd3bc7c96a55a6d3ad00941", + "sequence_number": "4426527547749008489", "payload": { "EntryFunction": { "module": { - "address": "53d9c1c3bd39399c2880c9c4db594ef9a2929a960c42172a3882abd441300635", - "name": "YtKWLdtzeteFnGz_Coin" + "address": "2206a247c832960eca621d9397e5c7885e470eaa0fcecab886c2abd359fb9e56", + "name": "AnOF_Coin" }, - "function": "FcvPsiSiGvVdi2", + "function": "KcYxjMmZecfbEXtChdWIFFjn", "ty_args": [ - { - "struct": { - "address": "b309acfd6f30dd9e90ee56bd6027e8ce820e6c3c486bc3438ccb73ee72bdde7c", - "module": "zdlSGksImmemhqC1", - "name": "eVKEQI", - "type_args": [] - } - }, - { - "struct": { - "address": "6a4d9253e80a240fd8bb181bd8002f7a60a02ccc6a7264c3eee7fb23e5bb46d4", - "module": "zZelUVPXLgFvDqvbywGfRkW", - "name": "QESHCZYYOiWOL5", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "1cefe1495ae10e87c22a854ca0ec5cff098354ab139b9e78916118acf25aef93", - "module": "JtBSwNNpw2", - "name": "CeSFYF7", + "address": "abc8bb008c7b88c195b10ba4632a29247660ef666366c76f1eda2338a69c6777", + "module": "v4", + "name": "bvrYRZJfLHhbBzpsBxT6", "type_args": [] } } }, { "vector": { - "vector": "address" + "struct": { + "address": "d3b094ee726c415f5099ba66e3e66f1d308c1d5a70ecbdff5c875b592fc4f571", + "module": "ezrWjbCrWqDmSSsrGMLHrM", + "name": "NAsijOnBsMEQ", + "type_args": [] + } } }, { - "struct": { - "address": "285c936601557a454a251cabd8d89c22e56d56b814d8667fdb6e5568d7f58503", - "module": "GpACBGy", - "name": "HaKtYZGVlQRmnnvIZQyoZqFucKXsYsHI9", - "type_args": [] - } - } - ], - "args": [] - } - }, - "max_gas_amount": "11474648439998629906", - "gas_unit_price": "4680695588779612505", - "expiration_timestamp_secs": "4211073660057338776", - "chain_id": 122 - }, - "signed_txn_bcs": "d8bb3d6f84e4207faf1b0050be34fbf697514d5fb5cce2b1adb116be4ab544c4679e03acce59527d0253d9c1c3bd39399c2880c9c4db594ef9a2929a960c42172a3882abd4413006351459744b574c64747a657465466e477a5f436f696e0e46637650736953694776566469320507b309acfd6f30dd9e90ee56bd6027e8ce820e6c3c486bc3438ccb73ee72bdde7c107a646c53476b73496d6d656d687143310665564b45514900076a4d9253e80a240fd8bb181bd8002f7a60a02ccc6a7264c3eee7fb23e5bb46d4177a5a656c555650584c6746764471766279774766526b570e51455348435a59594f69574f4c350006071cefe1495ae10e87c22a854ca0ec5cff098354ab139b9e78916118acf25aef930a4a744253774e4e70773207436553465946370006060407285c936601557a454a251cabd8d89c22e56d56b814d8667fdb6e5568d7f5850307477041434247792148614b74595a47566c51526d6e6e76495a51796f5a714675634b58735973484939000012c89bfcf5233e9f5959f2aed62bf54098c3b8be2ebd703a7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440552b282d9e112043faab32bb0117e2fabc79276e622a4a92a909c72ac4ecdfdca10c243ac39213c5e54611b5f4abf908e54d970ea658caacbc9054346e64d003", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "ae5a6ea9573592de5a687ae72f045956eae0f8d1674bd96205ea57798ab67afe", - "sequence_number": "3723571107033368582", - "payload": { - "EntryFunction": { - "module": { - "address": "778c04d799ac2e3f2c516342eaa2cc263cea5f42852a913eb2d8d219fe8f0231", - "name": "acYiCEtRXfySFczuf_Coin" - }, - "function": "CaMqrMdiABKkEHwBJYX8", - "ty_args": [ - { - "struct": { - "address": "b6279c32bfaf0e363bed44be780f8e50ece07c0cefcbe2e71abed3dbca645ef3", - "module": "cOhCV", - "name": "HYNZVQtBEDYZcSFvLGKO", - "type_args": [] - } + "vector": "u64" }, { - "struct": { - "address": "88f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384aef7617e06dc", - "module": "CnczVFITRrrougDOB0", - "name": "WJyGLcjneHqAijNVCSTGxMvmHCPn9", - "type_args": [] - } + "vector": "signer" }, { "vector": { "vector": { "struct": { - "address": "580e2d9bbd479b135588f20586f7bfa606b7c146b2ae92ea1e71301454f14c9f", - "module": "IxyhST8", - "name": "G", + "address": "9afbb4afea3a7cc811ab9bdcecfbaa72d6517a19139443b6162d4d9a52f6ba5c", + "module": "mxQZxltDpFwlWIDzRTxLnkCQ9", + "name": "CyUOjWAOHxlIgSBfUKENW", "type_args": [] } } } }, { - "struct": { - "address": "25e82505ca23e1687b8afae8c6b55beac01bd51dec15f284e56c0688e302254b", - "module": "wcfsJzgRAuzZKsTYAoUvc", - "name": "KEaXMnOaimkQwDiLTzBcsvKOWV3", - "type_args": [] - } - } - ], - "args": [ - "1d", - "0d6ecf8e024b5025", - "bcbf840e268c3f4b", - "d7", - "d34045cecdf93b4931eff5a81969d450", - "ad", - "6dd066ea13c357f8f70e1bac1cc45420", - "0af75f1f5b10ddc8", - "05cd278e74bdc88c34623ef352e9696f" - ] - } - }, - "max_gas_amount": "5555942518196952427", - "gas_unit_price": "6134359657424957727", - "expiration_timestamp_secs": "8244092837585326127", - "chain_id": 4 - }, - "signed_txn_bcs": "ae5a6ea9573592de5a687ae72f045956eae0f8d1674bd96205ea57798ab67afe06c8a18a31c8ac3302778c04d799ac2e3f2c516342eaa2cc263cea5f42852a913eb2d8d219fe8f02311661635969434574525866795346637a75665f436f696e1443614d71724d646941424b6b454877424a5958380407b6279c32bfaf0e363bed44be780f8e50ece07c0cefcbe2e71abed3dbca645ef305634f6843561448594e5a565174424544595a635346764c474b4f000788f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384aef7617e06dc12436e637a564649545272726f7567444f42301d574a79474c636a6e65487141696a4e5643535447784d766d4843506e3900060607580e2d9bbd479b135588f20586f7bfa606b7c146b2ae92ea1e71301454f14c9f07497879685354380147000725e82505ca23e1687b8afae8c6b55beac01bd51dec15f284e56c0688e302254b15776366734a7a675241757a5a4b735459416f5576631b4b4561584d6e4f61696d6b517744694c547a426373764b4f5756330009011d080d6ecf8e024b502508bcbf840e268c3f4b01d710d34045cecdf93b4931eff5a81969d45001ad106dd066ea13c357f8f70e1bac1cc45420080af75f1f5b10ddc81005cd278e74bdc88c34623ef352e9696f6b5d9e9d48ac1a4d1f314d719b9f21552f909db7c1e6687204002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f52addf527f68b66f70ea85b69d1c85626d8552f1de9a719c1d3bb7cf9c66e7252c88277327da30bace4f415309553bc96fd1eac3722ff603384842333de5c09", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "d32f8616dc870f85b92f0feccc75869549166ecd4856f553a71a4dcb7e65dea8", - "sequence_number": "8115358981140172803", - "payload": { - "EntryFunction": { - "module": { - "address": "468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19ad6a90090", - "name": "cEma_Coin" - }, - "function": "aDCXeVQFzjEfvptgVv3", - "ty_args": [], - "args": [ - "aa8ff2be0632eddf55289cb5fe0a74f58e5316c38b7de87760d60045ba107d3b", - "00", - "01" - ] - } - }, - "max_gas_amount": "9075634731442254814", - "gas_unit_price": "4439356434626085384", - "expiration_timestamp_secs": "15935088546365993895", - "chain_id": 175 - }, - "signed_txn_bcs": "d32f8616dc870f85b92f0feccc75869549166ecd4856f553a71a4dcb7e65dea803d0a20fff8b9f7002468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19ad6a900900963456d615f436f696e1361444358655651467a6a456676707467567633000320aa8ff2be0632eddf55289cb5fe0a74f58e5316c38b7de87760d60045ba107d3b01000101de33d016b421f37d08823b1528c39b3da7738aee9ace24ddaf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444033dbc7ebc6061c52d872762524c397b529a0008d5383f7a9a0eab6638badad218b004fa5e2f6fd76f7dc5071c13a437a273b6d257c546c7cb1c0f5fd0726c200", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "70a73ea0d9e144d1f237abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c", - "sequence_number": "13602672635404385948", - "payload": { - "EntryFunction": { - "module": { - "address": "2ea69f001cb160a518f7d709a4ec8a3d83c66d7de1308ab2f14cb7d3e5619d13", - "name": "JwrKuEXMG_Coin" - }, - "function": "HLaLWUBGXZyaHzokKvzMiuSoEVSJXn3", - "ty_args": [ - { - "struct": { - "address": "2b0df83edb2dd02e23796438b5eeb5175dc27d61bc74924bb6b2c2af58dc8625", - "module": "dtFZED3", - "name": "vZDPytSMirIKMYHwB", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "d81266cda990d02b55b83ecc2deecdb360763675c35500ba7d0dc0b3e256a69b", + "module": "klQPKmWlHpoEWvgp8", + "name": "X", + "type_args": [] + } + } } }, { "struct": { - "address": "c3eaa3e33815d8355f591f8520f012cc5f55ff4563974bc8a9337671755e1481", - "module": "MZjppCXMDwmt", - "name": "VbY3", + "address": "4e5b399096c08f4dca96125ef1cc0232eae11f227a6a451644705947fb42465a", + "module": "lMaLjeCKItSmhSSAFCQFqi", + "name": "hplWJMcfnjJmoFQeREkgkePIAaJjlTRb", "type_args": [] } }, { "struct": { - "address": "3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b61212af98508b44dc283cac0c", - "module": "ntaUfLhckil3", - "name": "nHtbTydXWOERHtVdJNKbgTlAkHbe5", + "address": "99869884b45e171032cfff1d5d628df869e817fb67bdf0b8998920ded60c7a69", + "module": "EhHIiaNxUuUGnVnTlIzJYm2", + "name": "mURgeNRixq", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "7b65df9a3b1ce6464bd16abb69187d9bb808fd37acb7cfcabf6437414c425e65", - "module": "tNkvpMYUfIurrM", - "name": "IHOJnnghJaeGvmSqbudCc4", - "type_args": [] - } - } - }, { "struct": { - "address": "b66ec15047a8a2d14ed31537d3ed415e1e3239de9c9678b602baaed3533bb588", - "module": "HCjE2", - "name": "yjdeSZtxlK", + "address": "884f52f96c3e0286e5b75a4bfca39e9d466831ed1eeccf75c5c2845320bd4081", + "module": "bLYyVKMhbBVdAdMqmcd", + "name": "pbsPKCVplFSpryLaysO", "type_args": [] } }, { "struct": { - "address": "1cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e6b", - "module": "Nsw", - "name": "jEkEXUzu8", + "address": "7c45d8aab3d95b44dafde63a9dbdc54d9dd74bc10a37edca459140baa2a1d99b", + "module": "XTjHmvPHa", + "name": "QzBgKThLlmEca", "type_args": [] } } ], "args": [ - "e8941ec5b325b829bdb9db0e022cf89d2bd0c6dade5ffea765fe0bf0579196f3", - "7b7ab9299216c42b719a72fc6f77fe76" + "01", + "00", + "2bf13a5a72b8f627b99e922faea172ba" ] } }, - "max_gas_amount": "4297974395487375707", - "gas_unit_price": "5195197727577819216", - "expiration_timestamp_secs": "7310655633586021697", - "chain_id": 7 + "max_gas_amount": "2552599493318923495", + "gas_unit_price": "2517986953649707132", + "expiration_timestamp_secs": "5538611344957471463", + "chain_id": 240 }, - "signed_txn_bcs": "70a73ea0d9e144d1f237abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9c7e341db166c6bc022ea69f001cb160a518f7d709a4ec8a3d83c66d7de1308ab2f14cb7d3e5619d130e4a77724b7545584d475f436f696e1f484c614c57554247585a7961487a6f6b4b767a4d6975536f4556534a586e3306072b0df83edb2dd02e23796438b5eeb5175dc27d61bc74924bb6b2c2af58dc8625076474465a45443311765a44507974534d6972494b4d594877420007c3eaa3e33815d8355f591f8520f012cc5f55ff4563974bc8a9337671755e14810c4d5a6a707043584d44776d74045662593300073bd3b01df1f25c4bc2feeadde76db0d07e5cf3b61212af98508b44dc283cac0c0c6e746155664c68636b696c331d6e48746254796458574f4552487456644a4e4b6267546c416b486265350006077b65df9a3b1ce6464bd16abb69187d9bb808fd37acb7cfcabf6437414c425e650e744e6b76704d595566497572724d1649484f4a6e6e67684a616547766d53716275644363340007b66ec15047a8a2d14ed31537d3ed415e1e3239de9c9678b602baaed3533bb5880548436a45320a796a6465535a74786c4b00071cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e6b034e7377096a456b4558557a7538000220e8941ec5b325b829bdb9db0e022cf89d2bd0c6dade5ffea765fe0bf0579196f3107b7ab9299216c42b719a72fc6f77fe765bd1bfe8f078a53b504831d2ce0c194841651ab390aa746507002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444074ae208bf0a9697cccd0e383d1b0ed58e93b407eaa03083243c34cb836bc1f4da542e9661d97dcd80c6abd1976e5485c242b99a0eaff7cb368d235d8b817a708", + "signed_txn_bcs": "a7a6ad8a57493204fc0ec8202b5abb3d80352876bbd3bc7c96a55a6d3ad0094169840f185a2f6e3d022206a247c832960eca621d9397e5c7885e470eaa0fcecab886c2abd359fb9e5609416e4f465f436f696e184b6359786a4d6d5a65636662455874436864574946466a6e0a0607abc8bb008c7b88c195b10ba4632a29247660ef666366c76f1eda2338a69c67770276341462767259525a4a664c486862427a707342785436000607d3b094ee726c415f5099ba66e3e66f1d308c1d5a70ecbdff5c875b592fc4f57116657a72576a6243725771446d53537372474d4c48724d0c4e4173696a4f6e42734d455100060206050606079afbb4afea3a7cc811ab9bdcecfbaa72d6517a19139443b6162d4d9a52f6ba5c196d78515a786c74447046776c5749447a5254784c6e6b435139154379554f6a57414f48786c4967534266554b454e5700060607d81266cda990d02b55b83ecc2deecdb360763675c35500ba7d0dc0b3e256a69b116b6c51504b6d576c48706f455776677038015800074e5b399096c08f4dca96125ef1cc0232eae11f227a6a451644705947fb42465a166c4d614c6a65434b4974536d685353414643514671692068706c574a4d63666e6a4a6d6f46516552456b676b65504941614a6a6c545262000799869884b45e171032cfff1d5d628df869e817fb67bdf0b8998920ded60c7a69174568484969614e78557555476e566e546c497a4a596d320a6d555267654e526978710007884f52f96c3e0286e5b75a4bfca39e9d466831ed1eeccf75c5c2845320bd408113624c5979564b4d686242566441644d716d636413706273504b4356706c46537072794c6179734f00077c45d8aab3d95b44dafde63a9dbdc54d9dd74bc10a37edca459140baa2a1d99b0958546a486d765048610d517a42674b54684c6c6d456361000301010100102bf13a5a72b8f627b99e922faea172bae7d41d05b7a76c237cd85b21cbaff122e77a2365ac19dd4cf0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409d3f687dc57d4f7887d474b488c9cf13570329bc18689919c507cac1f7758a754ec298f2dd629f4aec8077079144178691f9670558f5bd473970c49d6ae1590b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "efaf905d9cbd28d3429c0568d9d50c6ad2e8ce866d924a7a0056ffdc52667522", - "sequence_number": "5410169994901629604", + "sender": "6bb033020106518e8791fadaf2f07f2896fa3ae619882c589f231cd7c966214c", + "sequence_number": "1758092874778925521", "payload": { "EntryFunction": { "module": { - "address": "2ed7ab95be2d704a725e79559bb1398cccc1749c36e5c9f7e0a8a859c2df5ee5", - "name": "JnAjeHRSAUYHApNZRC3_Coin" + "address": "02ba90a6526a64186c5db32b54d6b959850e6ca1c571e572549a3143c2cea975", + "name": "xHYCLBHVNyedIS_Coin" }, - "function": "SuvcBNZaqLzJcEpOJcldGQCHSHQviNvk0", + "function": "r9", "ty_args": [ { - "struct": { - "address": "cad8421bc2831956e2a689183fb7887743662bea748f03ba3f2b0a7f5802f260", - "module": "VsRqXcHzmgRqxEOeCRMRFgUbvLuHwr", - "name": "EGoNDcmZYW0", - "type_args": [] + "vector": { + "struct": { + "address": "f8ed1eb9dcfb4514423b4cb19e3589ca6689ce4d19f080a255c3ccbdea81d352", + "module": "tXdMUDlxwNJBSrhy", + "name": "xzQHlQuQKRsqMFaTWturr9", + "type_args": [] + } } }, { - "struct": { - "address": "a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe", - "module": "sEpQncZWVLBuOHUgFBsaZcrqdB8", - "name": "MbfUqumYoMKuKrPKIGtsWrkcvKwLk2", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "0c24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d3092", + "module": "vZmwrpkOMJtYQRCNF", + "name": "jLijxBWFqwrJTpKewPcS", + "type_args": [] + } + } } }, { "struct": { - "address": "d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7", - "module": "KLSHfHnHsvFRSaknh", - "name": "YhIbxVeETPuEVhdY", + "address": "3ff8f9dbd319d8364aa10b55cf07844c8dc3eb9b4bdc415f637ee0f6d14d6ee0", + "module": "afSDIUgAPiOHPPrrpfBltiLGWF", + "name": "SVPglAqctajtACZhyokXLYEo", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "ca7c99725f58cbc5b05c9f0e21c4ad90806c219464610e552c1ddcc266e2e61a", - "module": "xwdQESCtvfPgOg", - "name": "NsLIqwIjji", - "type_args": [] - } - } - }, { "struct": { - "address": "dc60cb3b28f0309f5aba62d3eaf82a3a2b8f39810f0afad8c9827471bed1d431", - "module": "cgU9", - "name": "AdCVYgYORXI4", + "address": "c2a9ccfedc3625dda71a3d7ade7665a7c7348ed3a2793d629a4a29aaf9717bf8", + "module": "lBKOlgeqGcVlQOY7", + "name": "xAm", "type_args": [] } } ], "args": [ - "c417741308b8aede", - "2c69d4b906524a23b725dc02c1d8c9cc", - "ec34ed88f290127adbab049e174656864db9a403dece49af62c06496ec9d4de0", - "00", - "0f", - "57", - "fc2d028aae80096b738a7ef927eeb1cb", - "cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc55bab7", - "ce83c4f04c67d73501fd07d862bdf9feb74dd7e2e1dcfb3cc301e45d8202f801", - "01fa876405a4639dc855ad7183be588d7cdb226b7d7096b2a7119bce0db0838e" + "01", + "2941dc907428c7c0", + "bdb1654b742755fc", + "32" ] } }, - "max_gas_amount": "11368655333997618484", - "gas_unit_price": "14055158318522351311", - "expiration_timestamp_secs": "296318824705683393", - "chain_id": 221 + "max_gas_amount": "3159814478235305041", + "gas_unit_price": "15465352455365793319", + "expiration_timestamp_secs": "5849613825024107381", + "chain_id": 21 }, - "signed_txn_bcs": "efaf905d9cbd28d3429c0568d9d50c6ad2e8ce866d924a7a0056ffdc52667522a4aa9630f2c8144b022ed7ab95be2d704a725e79559bb1398cccc1749c36e5c9f7e0a8a859c2df5ee5184a6e416a654852534155594841704e5a5243335f436f696e2153757663424e5a61714c7a4a6345704f4a636c644751434853485176694e766b300507cad8421bc2831956e2a689183fb7887743662bea748f03ba3f2b0a7f5802f2601e567352715863487a6d67527178454f6543524d5246675562764c754877720b45476f4e44636d5a5957300007a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe1b734570516e635a57564c42754f485567464273615a6372716442381e4d62665571756d596f4d4b754b72504b4947747357726b63764b774c6b320007d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7114b4c534866486e487376465253616b6e681059684962785665455450754556686459000607ca7c99725f58cbc5b05c9f0e21c4ad90806c219464610e552c1ddcc266e2e61a0e7877645145534374766650674f670a4e734c497177496a6a690007dc60cb3b28f0309f5aba62d3eaf82a3a2b8f39810f0afad8c9827471bed1d43104636755390c416443565967594f52584934000a08c417741308b8aede102c69d4b906524a23b725dc02c1d8c9cc20ec34ed88f290127adbab049e174656864db9a403dece49af62c06496ec9d4de00100010f015710fc2d028aae80096b738a7ef927eeb1cb20cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc55bab720ce83c4f04c67d73501fd07d862bdf9feb74dd7e2e1dcfb3cc301e45d8202f8012001fa876405a4639dc855ad7183be588d7cdb226b7d7096b2a7119bce0db0838e3425c7e4ca93c59dcfbe66f505f40dc3c1efd7ae66bc1c04dd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b21e49a64155bd8fcf71b194fe4f5e33b04dc7b040fe5a51acef87c29f33d5390adee86202f6d302cf9db0060ccd4573955966846e0f0476cdd6edd732d4590e", + "signed_txn_bcs": "6bb033020106518e8791fadaf2f07f2896fa3ae619882c589f231cd7c966214cd1d957a3270066180202ba90a6526a64186c5db32b54d6b959850e6ca1c571e572549a3143c2cea97513784859434c4248564e79656449535f436f696e027239040607f8ed1eb9dcfb4514423b4cb19e3589ca6689ce4d19f080a255c3ccbdea81d352107458644d55446c78774e4a425372687916787a51486c5175514b5273714d466154577475727239000606070c24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d309211765a6d7772706b4f4d4a74595152434e46146a4c696a784257467177724a54704b657750635300073ff8f9dbd319d8364aa10b55cf07844c8dc3eb9b4bdc415f637ee0f6d14d6ee01a616653444955674150694f48505072727066426c74694c47574618535650676c41716374616a7441435a68796f6b584c59456f0007c2a9ccfedc3625dda71a3d7ade7665a7c7348ed3a2793d629a4a29aaf9717bf8106c424b4f6c6765714763566c514f59370378416d00040101082941dc907428c7c008bdb1654b742755fc013251045acb86ead92b27164b841ef89fd675a3c601c8002e5115002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e57190b3dc8566d1cc99b64e2b7a6d8a874ce97fa45edc594626d10aee79f929014a6d7fd67cc4e30cbe7d5f434021cb60fdd7978197ac4f62f47c93a803da0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c97c6ad1f365bcee0233c9ffcd8faa4a241661925660ab55f440412278288d52", - "sequence_number": "12123035773214832494", + "sender": "bafd4e0c2bbaec46393c66af927e328bf45d5bb11231cc079679423bc49322a2", + "sequence_number": "17544160367041894174", "payload": { "EntryFunction": { "module": { - "address": "820b0a2353f9702a42fc9bfd1f13587369a56c4aab2e4d67e33e3053ddebbf08", - "name": "WujXdeIIjVjmRsKxkleYY0_Coin" + "address": "0dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77539fbd397ba9", + "name": "CQdgZ2_Coin" }, - "function": "YIisHeQn5", + "function": "fYjCcFUjBloyKeDQbUiXEBIoNR6", "ty_args": [ - { - "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "ff2b8a261483eff3c6bac6a51a4b837704807f4ac74edb431cab2ecdf24bed2c", - "module": "vsyzrrg", - "name": "ncFsHSoLYCBEsGvZGklcLf9", - "type_args": [] - } - }, { "struct": { - "address": "a50408a8c8b9cefdba2c428f5ea87c50618da0ce06282deba37c5040b1ebaa26", - "module": "JPjxjZQOWferqAfmMCG", - "name": "yqsVCxrRvuXG", + "address": "628f95e338200e1ca3287e010c175892733f73ec51d4c24d597de448a2f786c6", + "module": "FNXbDIcYwCEzpEWbenGHfHQUwQUE1", + "name": "GjTfLIlYWcELGPwsLhoWD", "type_args": [] } }, { "struct": { - "address": "a01040059c7a80c08957e1ed3d57d283ab1980ff8bd77438af3328043fa96fef", - "module": "CfEJuZMIOIyCy", - "name": "gpMMBTwAwfXdy", + "address": "1d4874b1eb6e48635261e70f3f23c8a359b47dc8bff14efe2f9969d6db261488", + "module": "tecKfKSaIPoxaS", + "name": "BwkydKDoSfPobNjAgbRWLrsQQzzykOUq4", "type_args": [] } }, { "vector": { "struct": { - "address": "916f0897855fae032d0738d67eb38711c77b827e62528cd356e7f686deffd41d", - "module": "oQKLXUkfYISlzUGE1", - "name": "RXGmRakSQZvbtFxPaFhGrQ3", + "address": "bd8b5eeddab04cde77003afd557bb4352e594166c631177c5a7d9be82f1b6e3e", + "module": "mqtLdSvZUXanQKCbLpTeRvOWVkNj2", + "name": "qJAFwJLMMXqTjMHhsCS", "type_args": [] } } }, { "struct": { - "address": "57f3ec98be03abbfbfa0905e8281f6b0274c0c64702dfd53bb75eab8ba74607c", - "module": "FToLsdNJXAQqWKm9", - "name": "PNJSoEXVIFzQ9", + "address": "571e64acf55c43cae2e6b7de0a529c6c9d1431d364fec8b9535b96cbf3537e5b", + "module": "UcMPIMLAtyXKVrtlQKlJpW", + "name": "Sp", "type_args": [] } }, { "struct": { - "address": "87d18f490eeee1727d3b7f6c1d1e75f036000a89ab7450f3d6f3941e708f8698", - "module": "HmreSwBZdmUJztlpNLToECbeVOB8", - "name": "H9", + "address": "288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f21e96", + "module": "RVDPVmupnJCiXWtTdYgnYOg5", + "name": "IsaCvmrREHdeUmqUxFDjrVWSp0", "type_args": [] } }, { "vector": { - "struct": { - "address": "3f0da91e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c954", - "module": "YpvZxFCYVqGHoFKbvtlfjSWVygvt4", - "name": "KiVReT", - "type_args": [] + "vector": { + "struct": { + "address": "12f0fa7d6c8a6657f7993b3d1c58d99613689810fc08d6bd76e4f123de97cf7d", + "module": "qJFvTuugvGSIuGjFGg", + "name": "FhYH8", + "type_args": [] + } } } }, { - "struct": { - "address": "b4b3339aac701607ea2d7937d6ae55e568ef581674a4a76e39985fdfbf998242", - "module": "AJYJYGIzGrRUgulKoPRzctvZOKznex0", - "name": "IlrSBHXOXJmTaSyFbVxfI2", - "type_args": [] + "vector": { + "struct": { + "address": "a7a4f7a5d5e8a29060762230f10f26a0433b0f4401b9acf76a87e7e2724da949", + "module": "oUXHaIoqexLOksCIPsbNPmABgZbWR", + "name": "EjNlfHyGtjYibRWUvIhsDahTO", + "type_args": [] + } } }, { - "struct": { - "address": "f7d0b635843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d", - "module": "hbWax", - "name": "GaCEIONXYfcNzsXBdOrTaPQPA8", - "type_args": [] - } - } - ], - "args": [ - "b69d8849dfa1d6c6", - "00", - "b1" - ] - } - }, - "max_gas_amount": "12490997299298066625", - "gas_unit_price": "6903517920949035232", - "expiration_timestamp_secs": "4313428367871423487", - "chain_id": 101 - }, - "signed_txn_bcs": "c97c6ad1f365bcee0233c9ffcd8faa4a241661925660ab55f440412278288d526eb7d21dceac3da802820b0a2353f9702a42fc9bfd1f13587369a56c4aab2e4d67e33e3053ddebbf081b57756a58646549496a566a6d52734b786b6c655959305f436f696e09594969734865516e350a06060107ff2b8a261483eff3c6bac6a51a4b837704807f4ac74edb431cab2ecdf24bed2c077673797a727267176e63467348536f4c594342457347765a476b6c634c66390007a50408a8c8b9cefdba2c428f5ea87c50618da0ce06282deba37c5040b1ebaa26134a506a786a5a514f576665727141666d4d43470c7971735643787252767558470007a01040059c7a80c08957e1ed3d57d283ab1980ff8bd77438af3328043fa96fef0d4366454a755a4d494f497943790d67704d4d425477417766586479000607916f0897855fae032d0738d67eb38711c77b827e62528cd356e7f686deffd41d116f514b4c58556b665949536c7a55474531175258476d52616b53515a76627446785061466847725133000757f3ec98be03abbfbfa0905e8281f6b0274c0c64702dfd53bb75eab8ba74607c1046546f4c73644e4a58415171574b6d390d504e4a536f45585649467a5139000787d18f490eeee1727d3b7f6c1d1e75f036000a89ab7450f3d6f3941e708f86981c486d72655377425a646d554a7a746c704e4c546f45436265564f42380248390006073f0da91e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9541d5970765a78464359567147486f464b6276746c666a5357567967767434064b69565265540007b4b3339aac701607ea2d7937d6ae55e568ef581674a4a76e39985fdfbf9982421f414a594a5947497a4772525567756c4b6f50527a6374765a4f4b7a6e65783016496c72534248584f584a6d54615379466256786649320007f7d0b635843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d0568625761781a47614345494f4e585966634e7a735842644f7254615051504138000308b69d8849dfa1d6c6010001b1c1600613ddef58ade0e0b502f938ce5fffb3113f3f60dc3b65002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099395f75e09a2a983e6ff71dc38c70e688b695e7868a130e92d77e6ce26e677a118278ccc50c05786762d25eb91e8b0f9b07141b8d7de8325f532ef0d92ec307", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "d2e697d81794f91bc99d4bfc8a6b9988fae75c175907b42a927336bee67398ff", - "sequence_number": "2137401416069863360", - "payload": { - "EntryFunction": { - "module": { - "address": "0495923c6adaaa80fc24bf8d54e116d2f8cbf1a98c3cca117d9f54a7cf56f5fc", - "name": "mTGrqQAJtcgMwsKXPOscMr_Coin" - }, - "function": "EVMLkgiqlzdbydoiruEGS7", - "ty_args": [ - { - "struct": { - "address": "3b4c8a715a3966538624869b527d928282d0a13e4b3e28f34acfc6f2c5092f43", - "module": "auqj", - "name": "auljdUCBvZIWpajsdJCEFjguem7", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "4d5167b867b3be746092265da8baaa0e8825455cab1952f59a6edf241657ff09", + "module": "wTZ8", + "name": "B2", + "type_args": [] + } + } } }, { "struct": { - "address": "5c95967af8a288f4ba4c5aa1a608fbf26ee4e36b58edafac7d0b48af72d867b9", - "module": "meSQZQjkPVTiXKegADGZTSeLBHmc", - "name": "loECdVuqGryQWAArhiCdGRdLtEHBe", + "address": "35e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8a7", + "module": "Q0", + "name": "LIgIFFCNxTuPyQmoRLU", "type_args": [] } } ], "args": [ - "939836c2e640ecb454a479410a7ed965" + "3870312306af8153", + "00", + "96e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b956184f35e218d2", + "efcbfa5d63650daa", + "99fb66844ba677fdafcb8e0a3c8ed15f777761f98f914ec630038130f9eb81f8", + "cb0aa68c518c288f958d68e7f21bc1da13f0db0a65897d4ed2791dcc532465ba", + "00", + "d2036309d39f8bfc5d1e001946e76eaa02d6d560e067f5c3e9f7eccf178968ac", + "217c00087b59c8f102ea1e22dd0361dbca75cfbbff7b6c6ba17d717e2964ab69", + "00" ] } }, - "max_gas_amount": "533426335464637558", - "gas_unit_price": "17324896568071707149", - "expiration_timestamp_secs": "11640582366230838350", - "chain_id": 127 + "max_gas_amount": "6474672790465785428", + "gas_unit_price": "18269917365123453405", + "expiration_timestamp_secs": "4411469518669170188", + "chain_id": 123 }, - "signed_txn_bcs": "d2e697d81794f91bc99d4bfc8a6b9988fae75c175907b42a927336bee67398ffc0d742734393a91d020495923c6adaaa80fc24bf8d54e116d2f8cbf1a98c3cca117d9f54a7cf56f5fc1b6d5447727151414a7463674d77734b58504f73634d725f436f696e1645564d4c6b6769716c7a646279646f6972754547533702073b4c8a715a3966538624869b527d928282d0a13e4b3e28f34acfc6f2c5092f43046175716a1b61756c6a64554342765a495770616a73644a4345466a6775656d3700075c95967af8a288f4ba4c5aa1a608fbf26ee4e36b58edafac7d0b48af72d867b91c6d6553515a516a6b50565469584b65674144475a5453654c42486d631d6c6f4543645675714772795157414172686943644752644c7445484265000110939836c2e640ecb454a479410a7ed965764435076d1c67070d5a4c2ea3656ef04e7cddd5fca78ba17f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3f3e7634861b1625c1d5b81265a7693ed672268227d050d54fa670e34ac04c16a2ab0460170a570411635549dd469793d39232989bd79db3db13a4ca82de801", + "signed_txn_bcs": "bafd4e0c2bbaec46393c66af927e328bf45d5bb11231cc079679423bc49322a21ed704a0e66079f3020dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77539fbd397ba90b435164675a325f436f696e1b66596a436346556a426c6f794b654451625569584542496f4e52360907628f95e338200e1ca3287e010c175892733f73ec51d4c24d597de448a2f786c61d464e5862444963597743457a70455762656e474866485155775155453115476a54664c496c595763454c475077734c686f574400071d4874b1eb6e48635261e70f3f23c8a359b47dc8bff14efe2f9969d6db2614880e7465634b664b536149506f7861532142776b79644b446f5366506f624e6a41676252574c727351517a7a796b4f557134000607bd8b5eeddab04cde77003afd557bb4352e594166c631177c5a7d9be82f1b6e3e1d6d71744c6453765a5558616e514b43624c70546552764f57566b4e6a3213714a4146774a4c4d4d5871546a4d48687343530007571e64acf55c43cae2e6b7de0a529c6c9d1431d364fec8b9535b96cbf3537e5b1655634d50494d4c417479584b5672746c514b6c4a70570253700007288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f21e961852564450566d75706e4a4369585774546459676e594f67351a49736143766d725245486465556d71557846446a7256575370300006060712f0fa7d6c8a6657f7993b3d1c58d99613689810fc08d6bd76e4f123de97cf7d12714a4676547575677647534975476a464767054668594838000607a7a4f7a5d5e8a29060762230f10f26a0433b0f4401b9acf76a87e7e2724da9491d6f55584861496f7165784c4f6b7343495073624e506d4142675a62575219456a4e6c66487947746a59696252575576496873446168544f000606074d5167b867b3be746092265da8baaa0e8825455cab1952f59a6edf241657ff090477545a38024232000735e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8a7025130134c4967494646434e7854755079516d6f524c55000a083870312306af815301002096e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b956184f35e218d208efcbfa5d63650daa2099fb66844ba677fdafcb8e0a3c8ed15f777761f98f914ec630038130f9eb81f820cb0aa68c518c288f958d68e7f21bc1da13f0db0a65897d4ed2791dcc532465ba010020d2036309d39f8bfc5d1e001946e76eaa02d6d560e067f5c3e9f7eccf178968ac20217c00087b59c8f102ea1e22dd0361dbca75cfbbff7b6c6ba17d717e2964ab69010054ae994099a8da59dd91ec9f0bc98bfd0c46bd7d27b0383d7b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444040994bab3db59ac76ea6052c6c61ac18314200f09ff1bd58736c9bf99a723f1a42dee94a5ddaa2bf88a5c790d2ad50692d3da8f03abe238b5b36522bac7f3504", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5894d59791ce104ccc08e862a40f9abe6762819079d607d11f6088ddd4a9b339", - "sequence_number": "18170734757694866675", + "sender": "c7595666f07a0907e14efbd2214993d971ec5d5a7867bdb4f8f2b6cc316a409e", + "sequence_number": "5947902502497048432", "payload": { "EntryFunction": { "module": { - "address": "0e2d8ba2b1f96b1bfef5acf29d94981beda302dad649c7e40732a1c8b857c11c", - "name": "XSzZvXhGikuxnSZhEWwRPSz_Coin" + "address": "c50e47674680a109402988bbf0afdbdb34f87acbad31bdd1f0e07c60eb4c0537", + "name": "GBMFhqCTtOJrvpLmeRbuOKCUXtO_Coin" }, - "function": "DnOCbGlZxPsmRIGvfFA", + "function": "KXwdWNV", "ty_args": [ { "vector": { "struct": { - "address": "fda4e425fad55dd73e53b04390a3543f4655c043d2231ab893ad05bea5acbc10", - "module": "HbZSHxlqkKHbmLpsOovfrTFelokuTRPD8", - "name": "lNVAqXtpVBTsYElif8", + "address": "7c55145424fafd135562b02f53db1867954c79336b0b423ac16b1daf5d8fe43a", + "module": "ycFlhvHLvQVkxfExuyISCf", + "name": "cpAORkNgvMNWiEwdMQrX", "type_args": [] } } }, { - "struct": { - "address": "6fbc0a16bd40c7fa5c0fcdc6b952d20e90ad7ff537b0c2b1ae3bac5b7e13ddfa", - "module": "JTltrUqQQFaElGIDQOQhIAXWoz6", - "name": "yQ", - "type_args": [] + "vector": { + "vector": "address" } }, { "struct": { - "address": "af035dad551d3d80abf570b59610e85038aa431d7d7d83b32310a30188c90808", - "module": "CdArWHnslKnL1", - "name": "UlEl5", + "address": "c00ca5f249c12bfd4f9f294428c11a06c04aed44f93249f1ad0ad603b8a0e0dd", + "module": "DWZSZCW", + "name": "tPmIwvPyaNEaSDbvdm", "type_args": [] } }, { "struct": { - "address": "0a6399a598724c89dc6648495e4a19a77b0c80d573e8aaf1dc342efdd86d4cd4", - "module": "AzcoSwLxeBjRiHPDkJXr8", - "name": "PKleUxhEnZMYLdklagD8", + "address": "386802ce917a6ef7a29b0e9e215c91b22748082311b7ce060bb573bc67881733", + "module": "SXfQABHzCNMp", + "name": "bLSLCwBOHuavKWfXeGaJj", "type_args": [] } }, { "struct": { - "address": "b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7cddf0980f02babfe", - "module": "aPIR1", - "name": "UnyAtlhLEyQWspthropxxYXeaVqxHn", + "address": "3532a8dd9d9b0a7c7f4995ea225cb1c904284cbab4d02f4f876c28b283d13b62", + "module": "YRZCnsIaQxkyKQSJgEBOiZUixng", + "name": "EzJmcRyfoCiqiYmyMtch", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "8a945242b918865557d991bf889ac19b4ec492db48c2a88b4beb5b780a1a7b61", + "module": "uEHlROVZPCExXAuhccmzQkBJNuRWD", + "name": "LwlFXSaxKuPMTIjhE5", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "c466a0c6283d90ed207b5fd8f85fd6b05ebfd870eea2d57f10eed7ac766df01a", + "module": "mFisEgIqnfKUCwDItDBc0", + "name": "CGoMlsUJUGmlWrvOkMBgerefnwnpJJj", + "type_args": [] + } + } } ], - "args": [ - "b5e11d0fab07b93bca0b431076b1b962" - ] + "args": [] } }, - "max_gas_amount": "15690994166080608262", - "gas_unit_price": "1019922765953207371", - "expiration_timestamp_secs": "12322986801690557708", - "chain_id": 196 + "max_gas_amount": "18132661458080473926", + "gas_unit_price": "15286620286439603657", + "expiration_timestamp_secs": "11740717763513176354", + "chain_id": 51 }, - "signed_txn_bcs": "5894d59791ce104ccc08e862a40f9abe6762819079d607d11f6088ddd4a9b339f3043f4cfd6a2bfc020e2d8ba2b1f96b1bfef5acf29d94981beda302dad649c7e40732a1c8b857c11c1c58537a5a76586847696b75786e535a684557775250537a5f436f696e13446e4f4362476c5a7850736d52494776664641050607fda4e425fad55dd73e53b04390a3543f4655c043d2231ab893ad05bea5acbc102148625a5348786c716b4b48626d4c70734f6f7666725446656c6f6b755452504438126c4e5641715874705642547359456c69663800076fbc0a16bd40c7fa5c0fcdc6b952d20e90ad7ff537b0c2b1ae3bac5b7e13ddfa1b4a546c7472557151514661456c474944514f5168494158576f7a360279510007af035dad551d3d80abf570b59610e85038aa431d7d7d83b32310a30188c908080d4364417257486e736c4b6e4c3105556c456c3500070a6399a598724c89dc6648495e4a19a77b0c80d573e8aaf1dc342efdd86d4cd415417a636f53774c7865426a52694850446b4a58723814504b6c65557868456e5a4d594c646b6c616744380007b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7cddf0980f02babfe0561504952311e556e7941746c684c4579515773707468726f70787859586561567178486e000110b5e11d0fab07b93bca0b431076b1b9620618f6410f9cc1d94b8cf9125a7e270e0cbd97c6340b04abc4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440146c88586af1a18a4d4fb43d6013984e5d117a7a94b3a17a83bbf26edd7f546a9182b3a977c14518686db2a750abe8812bfd26ee0aec5de1f5ebb755af1bc40d", + "signed_txn_bcs": "c7595666f07a0907e14efbd2214993d971ec5d5a7867bdb4f8f2b6cc316a409e7057fe0bd0318b5202c50e47674680a109402988bbf0afdbdb34f87acbad31bdd1f0e07c60eb4c05372047424d4668714354744f4a7276704c6d655262754f4b435558744f5f436f696e074b587764574e560706077c55145424fafd135562b02f53db1867954c79336b0b423ac16b1daf5d8fe43a167963466c6876484c7651566b78664578757949534366146370414f526b4e67764d4e57694577644d5172580006060407c00ca5f249c12bfd4f9f294428c11a06c04aed44f93249f1ad0ad603b8a0e0dd0744575a535a43571274506d4977765079614e456153446276646d0007386802ce917a6ef7a29b0e9e215c91b22748082311b7ce060bb573bc678817330c535866514142487a434e4d7015624c534c4377424f487561764b5766586547614a6a00073532a8dd9d9b0a7c7f4995ea225cb1c904284cbab4d02f4f876c28b283d13b621b59525a436e73496151786b794b51534a6745424f695a5569786e6714457a4a6d635279666f43697169596d794d7463680006078a945242b918865557d991bf889ac19b4ec492db48c2a88b4beb5b780a1a7b611d7545486c524f565a504345785841756863636d7a516b424a4e75525744124c776c46585361784b75504d54496a684535000607c466a0c6283d90ed207b5fd8f85fd6b05ebfd870eea2d57f10eed7ac766df01a156d466973456749716e664b554377444974444263301f43476f4d6c73554a55476d6c5772764f6b4d4267657265666e776e704a4a6a000046a34d718627a4fbc93d839528fc24d4225152d69968efa233002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440088ea14d2822add45bbfc4a42f0559307e61fcce418fd2e973ba639e23de573ec8ce57f56421e76b8a17517abfe3b3a8f4a69a474f4c0ee596a2fc91a88e640c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8c7ef4d27c16f347b878e61339ec075933e756ae50f2ed30b48d29c06913c6ec", - "sequence_number": "934095557084397604", + "sender": "8340971c80b76164b38f4e13748211d13a97ec3eaebb9da342954d365bb4d95c", + "sequence_number": "1093245616517658282", "payload": { "EntryFunction": { "module": { - "address": "3e454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73b", - "name": "SIBJISTztyKbanATqymrFWLmoIHU3_Coin" + "address": "7b018235a34a982334dfc1abbc223f027f01c56b1a76d5f31561cf178d6a4364", + "name": "wI2_Coin" }, - "function": "EwLZGAojawYq8", + "function": "DoatyUOyTFGscluKnNXnhktuhYnPU2", "ty_args": [ - { - "struct": { - "address": "6c1ac7b61a4b272c9aca8a48bbae63148204cb058015db82a869c1ff7ca47f3e", - "module": "ryAbyAZEAcaxyi", - "name": "DaiGGDAoGzcdGOmiLJuGulektKiS6", - "type_args": [] - } - }, { "vector": { "vector": { "struct": { - "address": "5860fd94a3e7b173098e592544dda997336ce801074e187b41a1cfeb2692e0c8", - "module": "PPzPuGEICJcHuMGiEOSJAsq", - "name": "C", + "address": "04516d2e134d40a0dd3fb2a2e079f548bd33d67bfda7e462fe3cd167bbfe394b", + "module": "KoyrpCCjckYqANPrwaVPnn9", + "name": "eMQFVIzZFirbxdDJCtXbGqpCaDvX7", "type_args": [] } } } }, { - "struct": { - "address": "af09eeeda0efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed", - "module": "QXrl2", - "name": "ucPmcNOpAAfdKUvwqaIDC1", - "type_args": [] - } - }, - { - "vector": "u64" - }, - { - "struct": { - "address": "d17554224e80a6c3f7cad84f2cce8709e3d2df0592e526243aca41876befd6e5", - "module": "KfXwhHbpOvZCCuMMVlJNyRHe8", - "name": "EcHbrQPJepFhiWzFPuDPg", - "type_args": [] - } - }, - { - "struct": { - "address": "66379cf2947b9050bbfde5e3f06210fc09634740497a7f6755df330e9822abb0", - "module": "O8", - "name": "oTXyArcNRIX3", - "type_args": [] + "vector": { + "struct": { + "address": "f01f096d047608f1ce4d1febba891aae32f2540d0738f9e615293f9937e31c51", + "module": "NFZhthIdUqxFqyCJNEmSmnAmiOobb", + "name": "vnnWykBUC", + "type_args": [] + } } }, { - "struct": { - "address": "24ecf01fb221bc367980b8e5c81541d657cf66d2737b2e41a48a3cf0544f96af", - "module": "banF4", - "name": "bRHGTfxBMKEeH", - "type_args": [] + "vector": { + "vector": "signer" } }, { "vector": { "vector": { "struct": { - "address": "27d56b0676caa1050bb1821e28263ee656c2881dc3dc7903a4b74821ff5a488a", - "module": "aYOpgirdvMLJErXZUgiVnYXfeMUyIpq", - "name": "niZDPjVUSlZQIvPgAqWNlrOHgtB8", + "address": "54875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31aaae3c1c", + "module": "xUYAjDbqTvkhVn9", + "name": "bcVpZZqAtOSxlwhEdFW2", "type_args": [] } } } + }, + { + "vector": { + "struct": { + "address": "39375bd649c98f788e9505439bd12821b63cbf360fb3a6ec72a34a1134cd1306", + "module": "qQICZTNWEwqfwSglXPDGfkXHjD", + "name": "aLvAcNetIaUWqNSxnfqfqS", + "type_args": [] + } + } } ], "args": [ - "2fae7f946c2a4c76980f536bd4187bed", - "00", - "02d37a1024d03794d8d28017097a5c809321908b73a8a7e01827210ea33744d8", - "8267b4c8d469c5520249870517aec7dd", - "b2e75aa6a53f28c2393e2f1243717cce7bac40375c6f2ce46f6c3e5c74625343", - "00", - "44ab4c34ec26105469b0e6b3b0dcfde1", - "f5", - "00" + "305b4bcc64703bc374d9cce7d61dfc2a", + "86bf81f3b00e64bd" ] } }, - "max_gas_amount": "12858810095607501848", - "gas_unit_price": "2164941838794790151", - "expiration_timestamp_secs": "6323315818208380198", - "chain_id": 65 + "max_gas_amount": "14419184308878584498", + "gas_unit_price": "12641339608471202686", + "expiration_timestamp_secs": "8339370291029987680", + "chain_id": 170 }, - "signed_txn_bcs": "8c7ef4d27c16f347b878e61339ec075933e756ae50f2ed30b48d29c06913c6ec244049caf592f60c023e454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73b225349424a4953547a74794b62616e415471796d7246574c6d6f494855335f436f696e0d45774c5a47416f6a617759713808076c1ac7b61a4b272c9aca8a48bbae63148204cb058015db82a869c1ff7ca47f3e0e7279416279415a454163617879691d446169474744416f477a6364474f6d694c4a7547756c656b744b695336000606075860fd94a3e7b173098e592544dda997336ce801074e187b41a1cfeb2692e0c81750507a5075474549434a6348754d4769454f534a41737101430007af09eeeda0efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed055158726c32167563506d634e4f70414166644b55767771614944433100060207d17554224e80a6c3f7cad84f2cce8709e3d2df0592e526243aca41876befd6e5194b665877684862704f765a4343754d4d566c4a4e795248653815456348627251504a6570466869577a465075445067000766379cf2947b9050bbfde5e3f06210fc09634740497a7f6755df330e9822abb0024f380c6f5458794172634e52495833000724ecf01fb221bc367980b8e5c81541d657cf66d2737b2e41a48a3cf0544f96af0562616e46340d62524847546678424d4b4565480006060727d56b0676caa1050bb1821e28263ee656c2881dc3dc7903a4b74821ff5a488a1f61594f7067697264764d4c4a4572585a556769566e595866654d55794970711c6e695a44506a5655536c5a51497650674171574e6c724f48677442380009102fae7f946c2a4c76980f536bd4187bed01002002d37a1024d03794d8d28017097a5c809321908b73a8a7e01827210ea33744d8108267b4c8d469c5520249870517aec7dd20b2e75aa6a53f28c2393e2f1243717cce7bac40375c6f2ce46f6c3e5c7462534301001044ab4c34ec26105469b0e6b3b0dcfde101f501001854e42ea7ab73b20795becc216b0b1e2645ebfa3beec05741002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fac786081029253460169c02c8531260a3e60f0f79037318a646734a2cc46120e949f4b3f7fa333de7d6e1d7ca089d97def0044ec8c127299b4fc8a9f8510608", + "signed_txn_bcs": "8340971c80b76164b38f4e13748211d13a97ec3eaebb9da342954d365bb4d95caab6c99018fd2b0f027b018235a34a982334dfc1abbc223f027f01c56b1a76d5f31561cf178d6a4364087749325f436f696e1e446f617479554f7954464773636c754b6e4e586e686b747568596e5055320506060704516d2e134d40a0dd3fb2a2e079f548bd33d67bfda7e462fe3cd167bbfe394b174b6f79727043436a636b5971414e5072776156506e6e391d654d514656497a5a466972627864444a43745862477170436144765837000607f01f096d047608f1ce4d1febba891aae32f2540d0738f9e615293f9937e31c511d4e465a6874684964557178467179434a4e456d536d6e416d694f6f626209766e6e57796b4255430006060506060754875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31aaae3c1c0f785559416a44627154766b68566e3914626356705a5a7141744f53786c7768456446573200060739375bd649c98f788e9505439bd12821b63cbf360fb3a6ec72a34a1134cd13061a715149435a544e57457771667753676c58504447666b58486a4416614c7641634e657449615557714e53786e6671667153000210305b4bcc64703bc374d9cce7d61dfc2a0886bf81f3b00e64bdb22a9899bb3b1bc87e6b00b0650f6faf60d149871865bb73aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402da05bcaddf533c9b5278cc04233ad266887d635b7d28f5191e53df1e03166522d9e72d92e67ee391b53f65b1677bbde0b9f66720516b6682df1c1a6dc9c6002", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fce38649ab69c65bf3efc88305087a2ad64381dd6b013ff073435dab2b95fdef", - "sequence_number": "9210329543072062798", + "sender": "6ce4807617a2bdd7521237eaf7648064623f967dba38800d59148bae631dc59f", + "sequence_number": "10024027587874959934", "payload": { "EntryFunction": { "module": { - "address": "325a3f73a6737af32ebb80b2e2602b991bab54b6ab80ff200f781908fed603ba", - "name": "WAkZGLEEaa0_Coin" + "address": "cefcac9eb3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c", + "name": "RWtqQVgSP3_Coin" }, - "function": "XdB5", - "ty_args": [], + "function": "YgiINjEGmCxKsiSheUKEagywjiIUgj", + "ty_args": [ + { + "vector": "u8" + }, + { + "struct": { + "address": "e33ef8f86169d3503809dd5d37570042eb8c5d129607937bc473e70c4be1eba3", + "module": "iJJnirYztpqtVfsPqIvzJAsAxu2", + "name": "wmzZBTiLKZHRcMbGmkwbXWSaI3", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "73ee72bdde7c78269b5c64b7c7ede605da94bd1a67c228bebc312eb6f89dad1c", + "module": "dbzVkkTiqTOmswfCHPmJt", + "name": "HXl", + "type_args": [] + } + } + }, + { + "struct": { + "address": "0401657da28fc559fbf997e6901ac7c7ae35ce1621dda8e26e88e6833d0eeb3b", + "module": "DCpbNHfaasbmhIEIGBekVpuIHQ", + "name": "bljQknyTyVWutFGzdUtqyBNRKxDGd4", + "type_args": [] + } + }, + { + "struct": { + "address": "d190e257610dca30a4a911ece34ab51c54ef34c4bb204acc478021c98778b259", + "module": "EQMGdWzsX1", + "name": "YqjHjheHvV4", + "type_args": [] + } + }, + { + "struct": { + "address": "92f6830eda0fe407881b63699a963e5b19b4de87fc10fb1eab4b30a00c96f968", + "module": "vdGTCEkgwRglvA", + "name": "pjmzREx0", + "type_args": [] + } + } + ], "args": [ - "86", - "aba525b40b6181a6ca9e94349302ece56fa7b35dfde391740190882fa19034eb" + "5d911df6dfdbe0c3ecaeb32280fa08e1" ] } }, - "max_gas_amount": "3308815829877714599", - "gas_unit_price": "14112012253935530488", - "expiration_timestamp_secs": "5948639000346966189", - "chain_id": 196 + "max_gas_amount": "3872677047018042768", + "gas_unit_price": "10861652966118473630", + "expiration_timestamp_secs": "7528687943350007434", + "chain_id": 39 }, - "signed_txn_bcs": "fce38649ab69c65bf3efc88305087a2ad64381dd6b013ff073435dab2b95fdef4e9d18c7eba9d17f02325a3f73a6737af32ebb80b2e2602b991bab54b6ab80ff200f781908fed603ba1057416b5a474c45456161305f436f696e04586442350002018620aba525b40b6181a6ca9e94349302ece56fa7b35dfde391740190882fa19034eba7ee0c677746eb2df871c95560f0d7c3ad38b750a7cf8d52c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401fd6e2910bf6e22d80eb0810036cedb2afd497a21a9b418dbffdb5ddbc5d71a49bda199133458bb2978bcb0fee0a7893278b292f6459cc4558a9ce3877cb2600", + "signed_txn_bcs": "6ce4807617a2bdd7521237eaf7648064623f967dba38800d59148bae631dc59f3eb2004afb7f1c8b02cefcac9eb3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c0f525774715156675350335f436f696e1e596769494e6a45476d43784b7369536865554b45616779776a694955676a06060107e33ef8f86169d3503809dd5d37570042eb8c5d129607937bc473e70c4be1eba31b694a4a6e6972597a74707174566673507149767a4a4173417875321a776d7a5a4254694c4b5a4852634d62476d6b776258575361493300060773ee72bdde7c78269b5c64b7c7ede605da94bd1a67c228bebc312eb6f89dad1c1564627a566b6b546971544f6d7377664348506d4a740348586c00070401657da28fc559fbf997e6901ac7c7ae35ce1621dda8e26e88e6833d0eeb3b1a444370624e4866616173626d684945494742656b5670754948511e626c6a516b6e7954795657757446477a6455747179424e524b78444764340007d190e257610dca30a4a911ece34ab51c54ef34c4bb204acc478021c98778b2590a45514d4764577a7358310b59716a486a686548765634000792f6830eda0fe407881b63699a963e5b19b4de87fc10fb1eab4b30a00c96f9680e7664475443456b677752676c764108706a6d7a524578300001105d911df6dfdbe0c3ecaeb32280fa08e190b551854183be359e3f0f3fd357bc968ab624b8cb457b6827002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444052dcb21f82ceddae1d610cd40d266dc3d855fc028d619f7e50713d772e0707c54c9c38b54c8973bdf122a59775671f535d2995123111ee59010de8df4cea0d08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8867be519974482d85749ec7e447e30d32e7ed9887c72537d540788c5062cf29", - "sequence_number": "14028212931138068049", + "sender": "a6caa7b50cff5188f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd3", + "sequence_number": "10497445081074617988", "payload": { "EntryFunction": { "module": { - "address": "322b2866b67ed7e4805ce02cf4789c936dd80d6b7067744987cc07d7539d3b09", - "name": "FEWPYalbTOdKuqlTfrHt9_Coin" + "address": "394062af170c721804ab2a1db0451c53e34e9e1ea62af30ef16609bdd1d0aaba", + "name": "TLAFRnUgSKfDLCeEFvLrwmbnztOizP_Coin" }, - "function": "ZRYSddigNRsqpuwiCEQzfn", + "function": "qsfXSG9", "ty_args": [ { "vector": { - "vector": "bool" + "vector": { + "struct": { + "address": "786d76a6ddd39a30dfacb874256c2d2f28c337f75d90e783e30a82d7843f578a", + "module": "CydYJCLjGXFxHWtK9", + "name": "TIeqVRfI1", + "type_args": [] + } + } } }, + "bool", { - "vector": { - "vector": "u64" + "struct": { + "address": "50be34fbf697514d5fb5cce2b1adb116be4ab544c467ce982e12f559d67a778c", + "module": "ApIkZcQpuSYooJTJBJnjfgqApLntVx", + "name": "rSPuZVCWjHMqrkSdZAwLaZxFHzEBDUXZ1", + "type_args": [] + } + }, + { + "struct": { + "address": "b7e5efd1d521e0770b3160266053074ce7b0693f395a0a2c8cf1256fc7d2ab40", + "module": "SNEDejlObHjOrslLAKbiaxgkZhl9", + "name": "CYUq0", + "type_args": [] } } ], "args": [ - "9fefab3896102103" + "80606055b93c6fa9d125a534c1a00139a515606519688084cc9216decb27dfea" ] } }, - "max_gas_amount": "14351007517483828191", - "gas_unit_price": "16513633505218907534", - "expiration_timestamp_secs": "4509086126613255848", - "chain_id": 126 + "max_gas_amount": "13709806115342765438", + "gas_unit_price": "13497204900084317404", + "expiration_timestamp_secs": "150081558987513591", + "chain_id": 170 }, - "signed_txn_bcs": "8867be519974482d85749ec7e447e30d32e7ed9887c72537d540788c5062cf29519e06125639aec202322b2866b67ed7e4805ce02cf4789c936dd80d6b7067744987cc07d7539d3b091a4645575059616c62544f644b75716c5466724874395f436f696e165a525953646469674e527371707577694345517a666e0206060006060201089fefab3896102103df8395604d0529c78ecd8f152e362ce5a8d66c26f17d933e7e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403e1d492edb3f45f704a2eba22135561e5951b4125eab641a11294546f1280a2537ccb51602ffdec07d3eda67408a46c789adf105edbcabc9492c46ef8bc6f305", + "signed_txn_bcs": "a6caa7b50cff5188f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384ce9ff2ae6aae9102394062af170c721804ab2a1db0451c53e34e9e1ea62af30ef16609bdd1d0aaba23544c4146526e5567534b66444c43654546764c72776d626e7a744f697a505f436f696e077173665853473904060607786d76a6ddd39a30dfacb874256c2d2f28c337f75d90e783e30a82d7843f578a11437964594a434c6a475846784857744b390954496571565266493100000750be34fbf697514d5fb5cce2b1adb116be4ab544c467ce982e12f559d67a778c1e4170496b5a6351707553596f6f4a544a424a6e6a66677141704c6e74567821725350755a5643576a484d71726b53645a41774c615a7846487a45424455585a310007b7e5efd1d521e0770b3160266053074ce7b0693f395a0a2c8cf1256fc7d2ab401c534e4544656a6c4f62486a4f72736c4c414b62696178676b5a686c3905435955713000012080606055b93c6fa9d125a534c1a00139a515606519688084cc9216decb27dfea7ecd7b34060443bedcfc2f6a58b44fbbf79ec9fa61321502aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440613f446ddd36105c86ce4bd9e69acfa667c714280d3f6d959f970a521015abe2fe92562bd51959423e04f85d5b5ff08a6b3904e8902b66c6276b7d88e68f2e0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1e69a8d43901bd3e6937ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d", - "sequence_number": "16293253121409703180", + "sender": "575811eaabab700fa0447ba9673b362a7561130af49da337f301d32f8616dc87", + "sequence_number": "1997651572116658959", "payload": { "EntryFunction": { "module": { - "address": "2b86b5fbfebc4d6b438debaf176b48447e9c95f3cc850e28394b5f7fd6ca1975", - "name": "khZMGRFKszBVgXvecpZv_Coin" + "address": "f68d5d1021b79beef496e3bc86cd7377b3670895bedf052db39128457932c828", + "name": "mjbJkgpP4_Coin" }, - "function": "kEZAp", + "function": "rXnDociJqPcrUawA0", "ty_args": [ - { - "struct": { - "address": "6e5b72ea2206a14646b7e5f71aebac78ed203d7cb2c265ed80fb86547b7e3cde", - "module": "ZHy4", - "name": "ycBuWrtJLFtFCkVDsNTWfVNKxEUZM", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "3061470749f650bc5649906b2b38dae2458a4ebb10ec26fce1f37e2ead0ac9cb", - "module": "mWqDJUdbVULuRQtlz5", - "name": "riUBDEKAwqyjOLtDLMfGOSLngD", + "address": "b7168337dd0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df22", + "module": "YlskG", + "name": "TKuKIu0", "type_args": [] } } }, { "struct": { - "address": "ba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877bba1af7ff1", - "module": "VTVpxiEouCIAgMkmDca", - "name": "lhQNUKfZjXVDTtMnATBkM", + "address": "98409d26594da9a75287f72417d3267adc9d41438ce6d7b5f2514bfe062159ef", + "module": "XBfWUU", + "name": "HxzQtLecEyc", "type_args": [] } }, { "struct": { - "address": "026383b44979155157731849d88b9e86babf112a5534dba204dec17bbcf1fe66", - "module": "YAiRCKwlZZbdbqysVpGuTHCfz", - "name": "sNNmskcF6", + "address": "45708425d1d31e64482023751a813cc091659f550da3d8e5fca1bf2f7600828e", + "module": "lVNGtkpyu8", + "name": "GckVDAFrhTtdDQzycsanzVcaRI5", "type_args": [] } }, { "struct": { - "address": "9ef7fb0988ed299836783964b6d37576402efab170e239c43d04b90a260a16ed", - "module": "LFfRdrJFhGpeS", - "name": "WUDwObKbweeOdPxFSPesDZdTpB", + "address": "982374303505fd8bf6bbd8c9ee78eef7156f5c14281593be44fa7545199eaff3", + "module": "jvBiKEWTuhFSnAkxrHTpeLDiCCR", + "name": "bRdEdXqh5", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "974418edfc477bd97ec12cef59f54dfbc860a552bd15db3783dd15106c10a018", - "module": "BqDVNrhBFpAdxjoaRpbweFlW", - "name": "coQS8", - "type_args": [] - } + "struct": { + "address": "07fb7cdeb37f4f81fb573f5bee8b0d0200ab3265d274356df7feb702f0e945d3", + "module": "vWaGMIJK5", + "name": "IGmaVKLFubPIImoSjxFZaUpC", + "type_args": [] } } }, - { - "struct": { - "address": "5db98d0627ee32093b77491ff85b9d054da6f96a8ea877ddab008e9ff1584999", - "module": "m", - "name": "yySZGfZCu", - "type_args": [] - } - }, { "vector": { - "vector": "address" + "vector": { + "struct": { + "address": "481f9b04468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19a", + "module": "VRJ", + "name": "nkLxC9", + "type_args": [] + } + } } } ], "args": [ - "50dca3ae56446b5ef52204daeaaa449b", - "08", - "9e9f7fe547e6971e", + "f6", + "d3329b14c3d94a25f2e528e412193c246793ad26f356960d120b1bc08659a52e", + "bf9e50828e9b924da2e9b65864a6f070", + "b6", "01", - "47", - "01", - "4b" + "01" ] } }, - "max_gas_amount": "1867269909061192501", - "gas_unit_price": "12996127631785832905", - "expiration_timestamp_secs": "8049646627435807187", - "chain_id": 198 + "max_gas_amount": "9112191536816973839", + "gas_unit_price": "689809912111241676", + "expiration_timestamp_secs": "16724924462822336185", + "chain_id": 134 }, - "signed_txn_bcs": "1e69a8d43901bd3e6937ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c5d267963431de2022b86b5fbfebc4d6b438debaf176b48447e9c95f3cc850e28394b5f7fd6ca1975196b685a4d4752464b737a42566758766563705a765f436f696e056b455a417008076e5b72ea2206a14646b7e5f71aebac78ed203d7cb2c265ed80fb86547b7e3cde045a4879341d796342755772744a4c467446436b5644734e545766564e4b7845555a4d0006073061470749f650bc5649906b2b38dae2458a4ebb10ec26fce1f37e2ead0ac9cb126d5771444a55646256554c755251746c7a351a7269554244454b417771796a4f4c74444c4d66474f534c6e67440007ba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877bba1af7ff113565456707869456f75434941674d6b6d446361156c68514e554b665a6a58564454744d6e4154426b4d0007026383b44979155157731849d88b9e86babf112a5534dba204dec17bbcf1fe661959416952434b776c5a5a62646271797356704775544843667a09734e4e6d736b63463600079ef7fb0988ed299836783964b6d37576402efab170e239c43d04b90a260a16ed0d4c46665264724a4668477065531a575544774f624b627765654f6450784653506573445a6454704200060607974418edfc477bd97ec12cef59f54dfbc860a552bd15db3783dd15106c10a01818427144564e72684246704164786a6f615270627765466c5705636f51533800075db98d0627ee32093b77491ff85b9d054da6f96a8ea877ddab008e9ff1584999016d097979535a47665a437500060604071050dca3ae56446b5ef52204daeaaa449b0108089e9f7fe547e6971e010101470101014b354b5ecd16e0e919c9b13b8439855bb4d381bb73f516b66fc6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444020052c05b93b082576e2061cd79f51fbf9491d559848e14eadff6361c1c6c2d60726f6684e7e978efee8b5c7df5e4c0609d77472ea69ad15cb9ad45f7a290b0d", + "signed_txn_bcs": "575811eaabab700fa0447ba9673b362a7561130af49da337f301d32f8616dc870f9b03558515b91b02f68d5d1021b79beef496e3bc86cd7377b3670895bedf052db39128457932c8280e6d6a624a6b677050345f436f696e1172586e446f63694a715063725561774130060607b7168337dd0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2205596c736b4707544b754b497530000798409d26594da9a75287f72417d3267adc9d41438ce6d7b5f2514bfe062159ef065842665755550b48787a51744c6563457963000745708425d1d31e64482023751a813cc091659f550da3d8e5fca1bf2f7600828e0a6c564e47746b707975381b47636b56444146726854746444517a796373616e7a5663615249350007982374303505fd8bf6bbd8c9ee78eef7156f5c14281593be44fa7545199eaff31b6a7642694b455754756846536e416b7872485470654c44694343520962526445645871683500060707fb7cdeb37f4f81fb573f5bee8b0d0200ab3265d274356df7feb702f0e945d309765761474d494a4b351849476d61564b4c4675625049496d6f536a78465a6155704300060607481f9b04468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19a0356524a066e6b4c784339000601f620d3329b14c3d94a25f2e528e412193c246793ad26f356960d120b1bc08659a52e10bf9e50828e9b924da2e9b65864a6f07001b6010101010fe84b9dec01757ecc19efd575b29209b926c4bd2fde1ae886002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401f67e7678ac237d7a5781236581cc05e5ae495c40ae2a082bc79cac4bdb3bad82a24023f88ea77817d9cf3c53e2f36348462a31f0e75cb9970aee9f22deac804", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "02886dccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6", - "sequence_number": "14115098276434168496", + "sender": "db21e20f06cac0a7c5cac21311c387deff22296df93e7602d255b41cfbe7b724", + "sequence_number": "6142073736242761049", "payload": { "EntryFunction": { "module": { - "address": "2e17158708fc259583be086d060e2307863c1b6fd17a229327ece03b4189ba9d", - "name": "BvIVuGDLOaOQDWeIWzeECWV_Coin" + "address": "9549166ecd4856f553a71a4dcb7e65dea803ffa79adeb40828af2ea69f001cb1", + "name": "Gr_Coin" }, - "function": "jBRrOHxkBeRPlBPZf", + "function": "KAclDIFEEQVkFLBtUjVS", "ty_args": [ { "vector": { - "vector": "u64" + "struct": { + "address": "294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6e1564e8eb4c6", + "module": "licVGZVxtYsuQeLwIFyP6", + "name": "qnepjyTOzwAtUiMnYRRBomQ3", + "type_args": [] + } } - } - ], - "args": [ - "df7c30f0df076cf4f01a77469534bb4e", - "01", - "60", - "dd3e1e3607a73e9a82108ea8d183b909", - "4d", - "c9", - "39f676f277ab210a1a7ef67651e09306cb6efafc41eac87ef5247c1bacb7c74f", - "1802f968def58330", - "ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e78", - "78b21b3a04bf65321aa776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f8" - ] - } - }, - "max_gas_amount": "1372575531059564028", - "gas_unit_price": "8145372623935955716", - "expiration_timestamp_secs": "12059370263054168483", - "chain_id": 51 - }, - "signed_txn_bcs": "02886dccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b04a96f018e7e2c3022e17158708fc259583be086d060e2307863c1b6fd17a229327ece03b4189ba9d1c427649567547444c4f614f5144576549577a65454357565f436f696e116a4252724f48786b426552506c42505a66010606020a10df7c30f0df076cf4f01a77469534bb4e0101016010dd3e1e3607a73e9a82108ea8d183b909014d01c92039f676f277ab210a1a7ef67651e09306cb6efafc41eac87ef5247c1bacb7c74f081802f968def5833020ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e782078b21b3a04bf65321aa776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f8fccd325c2c5e0c1304e3e4d43e2d0a71a3b140685c7d5ba733002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c0d633725c4b5d18f0b9a6143803f9101b81420e9177500bfe65534a43256b05564908fcc038b2cd94bf4f538090ce3bf95bbb4f997ae49c520d63894320b0b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "f508aee9e8be65a1ff3f88210946013475d8c883c5789296126b22d781248811", - "sequence_number": "7411065962129702027", - "payload": { - "EntryFunction": { - "module": { - "address": "91d47d3a4e99dbe306e8e35101ac56b6b1377168b06a9303a552c29a3684c1e7", - "name": "rYcXGngSehrhNLM6_Coin" - }, - "function": "XmUGfvQPQYLjovIFb1", - "ty_args": [ + }, { "vector": { - "vector": { - "vector": "u8" - } + "vector": "u8" } }, { "struct": { - "address": "7126b68c7e144a5556b281a4bfeb4893e755a1c4aedf3562eaa3c4b23d051d4c", - "module": "aNhIFhmkpQndZzwdGVDOjpNSNKos0", - "name": "FpCcUgpzIEkFmZgHXESTeyjwaPtyUD0", + "address": "f867803cc5828dddc90181dbec6a1a82f7a81f7403185d88c0b7e6278a262f32", + "module": "cmlELvGSrXV2", + "name": "xYFUESIVyjskjzzMpmrXWgfyjsDkqVVt0", "type_args": [] } }, { "vector": { - "vector": "u128" - } - }, - { - "struct": { - "address": "0f3767e8f3418727b349469f6caa379975e738ba0565d806dc5fe630ac9beeee", - "module": "oXTgYBycWWv9", - "name": "NYeqyobnKIjhR4", - "type_args": [] + "struct": { + "address": "588085a949dc743119e7ce3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b612", + "module": "FYmRkXkaCzMfptMiMP", + "name": "CmF", + "type_args": [] + } } }, { - "struct": { - "address": "e352dc78be93047b539cd60678c99ff025da2ab58d82300b8513a1fd4b3ef82d", - "module": "GNZshkDfoyimPEHayJad", - "name": "GWHovCZpq", - "type_args": [] + "vector": { + "vector": "signer" } }, { "struct": { - "address": "189f78f12ec09d40dfcab3ff56b174ae89d0306cafea87d1b57da68e500009c5", - "module": "UsC0", - "name": "MXofsFBbOmOLFsEkhqKyFRiVZoWTygq3", + "address": "a05f9b1fb59f6f508084622f923124a5c5af0979ab9dc1fc26185529d0b5325b", + "module": "MiaTZmWiwxcpWVvujJVV6", + "name": "iGPJkLBnPGBEFKpAJaSjIUAO", "type_args": [] } }, { "vector": { "struct": { - "address": "72913d4c8c65161b174d33f965f0f580a61b1ec2e12a6a476e29794cd765fdae", - "module": "EbIzWaRLFoXkBxZn5", - "name": "KdVifueRYagVYwakirM", + "address": "ef65043b74a0aea0ac3ae913b345f77dbf5b2733b2d076e41e708e9c9dad387a", + "module": "dUSVEneGjYJgBmODPErJagHWJM1", + "name": "KCxXflQCEOknXUBml1", "type_args": [] } } } ], "args": [ - "00", - "bf9723de9ca9bf5f706a72460ee037ac", - "59ac0e2cf75f823cf7fdaccd052593ca", - "30", - "714674d1f28e74b8060194c43de7e608", - "534b326cacf75f4c8c80aec1d5f8d883", - "b833ff9e1d300a25e634e4c71dcc7755", - "7b905bd8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e026303", - "b6ce0c225e3dd003cbad4d0ee9731876713be06ac396798292a0ed118b86ba54" + "4dc9722bd67b687a", + "b55bea562d9db3a5" ] } }, - "max_gas_amount": "13956917626014664570", - "gas_unit_price": "12414917268344739473", - "expiration_timestamp_secs": "9222137133471424349", - "chain_id": 134 + "max_gas_amount": "7087822654672157468", + "gas_unit_price": "5386696312750303881", + "expiration_timestamp_secs": "16097047032009723918", + "chain_id": 101 }, - "signed_txn_bcs": "f508aee9e8be65a1ff3f88210946013475d8c883c5789296126b22d7812488118bbcba1f3a65d9660291d47d3a4e99dbe306e8e35101ac56b6b1377168b06a9303a552c29a3684c1e71572596358476e6753656872684e4c4d365f436f696e12586d55476676515051594c6a6f76494662310706060601077126b68c7e144a5556b281a4bfeb4893e755a1c4aedf3562eaa3c4b23d051d4c1d614e684946686d6b70516e645a7a77644756444f6a704e534e4b6f73301f467043635567707a49456b466d5a67485845535465796a776150747955443000060603070f3767e8f3418727b349469f6caa379975e738ba0565d806dc5fe630ac9beeee0c6f58546759427963575776390e4e596571796f626e4b496a6852340007e352dc78be93047b539cd60678c99ff025da2ab58d82300b8513a1fd4b3ef82d14474e5a73686b44666f79696d50454861794a6164094757486f76435a70710007189f78f12ec09d40dfcab3ff56b174ae89d0306cafea87d1b57da68e500009c50455734330204d586f66734642624f6d4f4c4673456b68714b79465269565a6f57547967713300060772913d4c8c65161b174d33f965f0f580a61b1ec2e12a6a476e29794cd765fdae114562497a5761524c466f586b42785a6e35134b64566966756552596167565977616b69724d0009010010bf9723de9ca9bf5f706a72460ee037ac1059ac0e2cf75f823cf7fdaccd052593ca013010714674d1f28e74b8060194c43de7e60810534b326cacf75f4c8c80aec1d5f8d88310b833ff9e1d300a25e634e4c71dcc7755207b905bd8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630320b6ce0c225e3dd003cbad4d0ee9731876713be06ac396798292a0ed118b86ba547a07fe49a2eeb0c191168d7f7aa54aac5ddf80a6dc9cfb7f86002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a115c7bd22d4d1d00339c41e087c5284554cdafed1c7ea53dd6768da638ae7d320bcb2382a17c982bb7d5c3026b2ce651646bf15523dd539ea069fa79a764404", + "signed_txn_bcs": "db21e20f06cac0a7c5cac21311c387deff22296df93e7602d255b41cfbe7b724598d016185073d55029549166ecd4856f553a71a4dcb7e65dea803ffa79adeb40828af2ea69f001cb10747725f436f696e144b41636c444946454551566b464c4274556a5653070607294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6e1564e8eb4c6156c696356475a56787459737551654c77494679503618716e65706a79544f7a77417455694d6e595252426f6d51330006060107f867803cc5828dddc90181dbec6a1a82f7a81f7403185d88c0b7e6278a262f320c636d6c454c76475372585632217859465545534956796a736b6a7a7a4d706d7258576766796a73446b7156567430000607588085a949dc743119e7ce3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b6121246596d526b586b61437a4d6670744d694d5003436d460006060507a05f9b1fb59f6f508084622f923124a5c5af0979ab9dc1fc26185529d0b5325b154d6961545a6d576977786370575676756a4a565636186947504a6b4c426e50474245464b70414a61536a4955414f000607ef65043b74a0aea0ac3ae913b345f77dbf5b2733b2d076e41e708e9c9dad387a1b64555356456e65476a594a67426d4f445045724a616748574a4d31124b437858666c5143454f6b6e5855426d6c310002084dc9722bd67b687a08b55bea562d9db3a51c3bb3ca26015d62896a63aac163c14a0e10b263fd3264df65002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440540577ce6acbe7934e97c5f9075b7348686af56b0e2249d35e7fc3ecee264680a4aaac0f0ce4c17581791bb7ee92c619374d8144ada75a7b994e20b12133b80d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1a5b4722ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a", - "sequence_number": "9909356483017387857", + "sender": "ef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce95a40ffcf87c11", + "sequence_number": "3568203870469089742", "payload": { "EntryFunction": { "module": { - "address": "f78eaaf80e695ad24d1df6d6d73cf1cac39b8044fa202a3ec5fbd70354235a88", - "name": "FZnpisFL0_Coin" + "address": "f61cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e", + "name": "icwgSfIjcSOPjqjtjURHjGZ4_Coin" }, - "function": "YvLBXOSOuzozUbOUbk", + "function": "ZoRRoSBDENFMdWKzzZnyiwhaWjWVKam8", "ty_args": [ + { + "struct": { + "address": "abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9cb141905bf050ce072e", + "module": "pKJJGTShQcWXNAJ7", + "name": "AjkwQuUFSfVOZGpZuwYfjZooME9", + "type_args": [] + } + }, + { + "struct": { + "address": "e098e6a947216c0abbf21a765e280633e754710707eb1ee41fa64c0d023e930e", + "module": "BKLnOoCmOnUPnnIHFxrWDoYyGjAuMvi", + "name": "VWNMrnhmVmVUGZFHqc", + "type_args": [] + } + }, + { + "struct": { + "address": "19d4d59dd306f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4ca", + "module": "agQFsDMnZryBotEvoLTQxEUQegR1", + "name": "IEAx", + "type_args": [] + } + }, { "vector": { - "vector": "u8" + "vector": "u64" + } + }, + { + "vector": { + "vector": { + "vector": "u64" + } } }, { "vector": { "struct": { - "address": "b5ea179dace4702cfbfcc9e950a54cb6037a0a443b0ed99f1580528e351fe5f4", - "module": "MiymArhMA1", - "name": "cMbSLYPHhBTu", + "address": "89d9338477d513f9b2f313c5d9a93c115b5b2d2b85310963c031b9f65b6df4ff", + "module": "nhbuNHdObMaPXBtAjdiXVw", + "name": "YkAXAKpD", "type_args": [] } } }, { "struct": { - "address": "aa88ae6b4ab92ea1eb8c3d27b29f68f25279614c47b6478f4ad2cbb35bcb6bfb", - "module": "WHhTPyTC7", - "name": "xyqdIYdzNQDKqBzsCIv6", + "address": "9cd67396e922e6b449ebaf30d1a0b3c5bf0c6f26e8e90efbdb5cdb49fda9e652", + "module": "twBe8", + "name": "FLykkphBxCXhWkv", "type_args": [] } }, { - "struct": { - "address": "8a31b3fe89546607c6c71ce54a3fd88273db518854b62b2642b40fe36fa906e5", - "module": "JjgpQzUMMdIMf6", - "name": "DxUMSfKDMLkSWXUwXkgJHPY3", - "type_args": [] + "vector": { + "struct": { + "address": "ae15ca5aba5b60cc6e0041bca651792c41088c48d7e92dc0cfd3b33be459be7a", + "module": "lPuhBMJYnhFovDwawm", + "name": "PbgmQxLpChftyOLwEFGJuXkFhV", + "type_args": [] + } } } ], "args": [ - "2e6e16fd001e1cca65e04274689782949bf1c25b196a5d7ff1ba7e8796b61770" + "0035f384be186f26", + "e61accf7c33617585ab220a264535f3fd1c0d6fa2299d7e4a9e9966cb2addd80", + "dab449b40c45f534" + ] + } + }, + "max_gas_amount": "5978384933565601556", + "gas_unit_price": "12697481204468443067", + "expiration_timestamp_secs": "4085833426773117905", + "chain_id": 196 + }, + "signed_txn_bcs": "ef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce95a40ffcf87c11cee97bd983ce843102f61cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e1d696377675366496a63534f506a716a746a5552486a475a345f436f696e205a6f52526f534244454e464d64574b7a7a5a6e7969776861576a57564b616d380807abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9cb141905bf050ce072e10704b4a4a47545368516357584e414a371b416a6b77517555465366564f5a47705a757759666a5a6f6f4d45390007e098e6a947216c0abbf21a765e280633e754710707eb1ee41fa64c0d023e930e1f424b4c6e4f6f436d4f6e55506e6e494846787257446f5979476a41754d76691256574e4d726e686d566d5655475a46487163000719d4d59dd306f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4ca1c6167514673444d6e5a7279426f7445766f4c5451784555516567523104494541780006060206060602060789d9338477d513f9b2f313c5d9a93c115b5b2d2b85310963c031b9f65b6df4ff166e6862754e48644f624d6150584274416a646958567708596b4158414b704400079cd67396e922e6b449ebaf30d1a0b3c5bf0c6f26e8e90efbdb5cdb49fda9e6520574774265380f464c796b6b70684278435868576b76000607ae15ca5aba5b60cc6e0041bca651792c41088c48d7e92dc0cfd3b33be459be7a126c507568424d4a596e68466f76447761776d1a5062676d51784c7043686674794f4c774546474a75586b4668560003080035f384be186f2620e61accf7c33617585ab220a264535f3fd1c0d6fa2299d7e4a9e9966cb2addd8008dab449b40c45f5341497b9176c7df752bb678a9ee18336b0d18b3a9edacbb338c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440db2bc9ad0a6aba3a6e157b4407c87a076657d16391cd0d5ca19500aa58ba4340210ca948eb959f15b8258ded50fb5eeef88181c85adaafa72894c272bec78500", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "19ffbaadb1307587f637b9ee84cf6590f8398bfb1ddf90d55637ee36a4dde8da", + "sequence_number": "10760634243356899393", + "payload": { + "EntryFunction": { + "module": { + "address": "786103b9609086e6a1873e1f5ff5bc03bc12cc378d8459a51f76edeb17c91115", + "name": "j_Coin" + }, + "function": "dRFQVjTjsJsiwuYSxuOGaMebGVhLBViH2", + "ty_args": [], + "args": [ + "cbcdcf695bccfd32efb5141ca30dd4a04abd1aec5804ac0e9cba84967efc76d2", + "7d3a8cc9495b5d2de87f0006c47f7c67", + "67d1e8023cbc871abf79ec37929b7eaa7f9ed39adfbe96e57ac34d72739dbce4", + "d0", + "754f7cca9b0faeb75731fd6778e5475fbd9127c6c9d3606cc2afa04b4d1d1bb9", + "00", + "90" ] } }, - "max_gas_amount": "12141343625491720070", - "gas_unit_price": "5233756779710902830", - "expiration_timestamp_secs": "9649027066944241969", - "chain_id": 61 + "max_gas_amount": "17198227190739173324", + "gas_unit_price": "9584021427452052761", + "expiration_timestamp_secs": "14195817529465238459", + "chain_id": 31 }, - "signed_txn_bcs": "1a5b4722ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a512ff722381b858902f78eaaf80e695ad24d1df6d6d73cf1cac39b8044fa202a3ec5fbd70354235a880e465a6e706973464c305f436f696e1259764c42584f534f757a6f7a55624f55626b040606010607b5ea179dace4702cfbfcc9e950a54cb6037a0a443b0ed99f1580528e351fe5f40a4d69796d4172684d41310c634d62534c595048684254750007aa88ae6b4ab92ea1eb8c3d27b29f68f25279614c47b6478f4ad2cbb35bcb6bfb0957486854507954433714787971644959647a4e51444b71427a734349763600078a31b3fe89546607c6c71ce54a3fd88273db518854b62b2642b40fe36fa906e50e4a6a6770517a554d4d64494d6636184478554d53664b444d4c6b5357585577586b674a485059330001202e6e16fd001e1cca65e04274689782949bf1c25b196a5d7ff1ba7e8796b6177086276325b3b77ea82ef275bf0f0aa248314157a1fe3ae8853d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440928106fd159c95a655e578cca3628d4591e7590421c9511eebd155c794bd912f019c7f5c658138dcefe15e6e163d2647815a7a9713eab031078cea61d016d80d", + "signed_txn_bcs": "19ffbaadb1307587f637b9ee84cf6590f8398bfb1ddf90d55637ee36a4dde8da41383101d573559502786103b9609086e6a1873e1f5ff5bc03bc12cc378d8459a51f76edeb17c91115066a5f436f696e2164524651566a546a734a73697775595378754f47614d65624756684c4256694832000720cbcdcf695bccfd32efb5141ca30dd4a04abd1aec5804ac0e9cba84967efc76d2107d3a8cc9495b5d2de87f0006c47f7c672067d1e8023cbc871abf79ec37929b7eaa7f9ed39adfbe96e57ac34d72739dbce401d020754f7cca9b0faeb75731fd6778e5475fbd9127c6c9d3606cc2afa04b4d1d1bb901000190ccff78868260acee190503bfb5480185bbf30994d4ac01c51f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba85c68b9a25526e840d0a53ddf423f084274fbe628c0d0152dd8e163546ae188eca3e917f70301197b6dc562b05c56a81a5537c365ceaafe69fc7d54ba2760a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0e5f3a9a117cee5cba2c122690ba630c6bcfa60b0e3627cb66497a80ab434c6f", - "sequence_number": "14731477467461079559", + "sender": "3c68ec584027dc36ca3f6f63d2f233b63c59b3c151fe026b76333d0f5b9bfb60", + "sequence_number": "17390244856979794740", "payload": { "EntryFunction": { "module": { - "address": "efb4268809c1b90b4c6739dd67711a24ae26bf45c046fcc3081ecaeeb62953c4", - "name": "jhpD_Coin" + "address": "4ddea3eec776f30f4847204d540158b849e207beebef55ecc7f7a835e71a56e8", + "name": "LDqfapClUMsQwmonNiF3_Coin" }, - "function": "RZaOerKznxYsGoGgGHBxT", + "function": "zOnmGAQqPoXhEpRhctDxYg5", "ty_args": [ { "struct": { - "address": "c9c48aeca6fdaf4fd50ef4c54a3e057334108412c9b2dcee22dbd26b4e2c700d", - "module": "yTcZcGyFrTRsSYyJrBVGRgXtD", - "name": "mEAmolnkomZxs", + "address": "701350223e3cdab45446e5108013d95bbb074b7b7d5023ccfda3e5ae212b173a", + "module": "kjCpRYHoUcCOdtfIlhj6", + "name": "zCOagnmXTELFDOLzYTXv", "type_args": [] } }, { "vector": { - "vector": "u64" + "struct": { + "address": "e658419e417115d1c60b01163f1012fad905cd42f2108c68d3cf3010fdc13b70", + "module": "IcLSmgnLHKplZNsUvibbtaJ", + "name": "Soy", + "type_args": [] + } + } + }, + { + "struct": { + "address": "2edf45ce26ed750f48ac6572bf6b4fa931927c09aaedbbb07c9eb9bb65de21df", + "module": "aUXzCyjkJar8", + "name": "vRWrYNLyMUfmopPjfHdICeMzcAmELxP6", + "type_args": [] } }, { "vector": { "vector": { - "vector": "u8" + "struct": { + "address": "e1d6b084c1f753b1d0304bc83ab20d5fc44aa8a50408a8c8b9cefdba2c428f5e", + "module": "VxFsDPVOrxplZLY", + "name": "dWWrQui", + "type_args": [] + } } } }, { "struct": { - "address": "60d5d253f4c8d5cf74549332ddf0addee4e8e63094c3e8b2691248fc4abd4e6b", - "module": "LB2", - "name": "D8", + "address": "c30d2d828fb656cffd85d38bf06d8e06d93fae8441a9b9adfde74c3ae1692990", + "module": "vZD1", + "name": "tbREAMmIQhlhgeF8", + "type_args": [] + } + }, + { + "struct": { + "address": "2f7f0ec5ac3242a8cfa8bf75fcdd3c30bdcb7cf9e6efbe6baee92133cad1d719", + "module": "ETihgVFQeJytPCFc", + "name": "ebd2", "type_args": [] } } ], "args": [ - "794212eaeaf922fb", - "04584748faac8e37", - "88b372ff2aa3fd15" + "01", + "bc28daeefa1d0c87", + "1d1c6fe79f590043549431784146a402", + "01", + "00", + "00", + "2ff2d2197ccfcb4b656de0bc6f41a4f1" ] } }, - "max_gas_amount": "2906846268964641390", - "gas_unit_price": "18273790671293480295", - "expiration_timestamp_secs": "1892230298483870303", - "chain_id": 182 + "max_gas_amount": "2153991594174387025", + "gas_unit_price": "2953682040473812213", + "expiration_timestamp_secs": "8717308078034732449", + "chain_id": 17 }, - "signed_txn_bcs": "0e5f3a9a117cee5cba2c122690ba630c6bcfa60b0e3627cb66497a80ab434c6f0752b0b8b4b870cc02efb4268809c1b90b4c6739dd67711a24ae26bf45c046fcc3081ecaeeb62953c4096a6870445f436f696e15525a614f65724b7a6e785973476f476747484278540407c9c48aeca6fdaf4fd50ef4c54a3e057334108412c9b2dcee22dbd26b4e2c700d197954635a63477946725452735359794a7242564752675874440d6d45416d6f6c6e6b6f6d5a787300060602060606010760d5d253f4c8d5cf74549332ddf0addee4e8e63094c3e8b2691248fc4abd4e6b034c4232024438000308794212eaeaf922fb0804584748faac8e370888b372ff2aa3fd156e9a4ece47315728677d4bfecb8b99fd5fca5c566e8d421ab6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cb973207e191ae2c4a0e467ea114e7c684ebe42d7b1953c3f91036a2c78963da599d371621831e1cf6c943070bb8fb086948c3641533982aac15b06369d5820c", + "signed_txn_bcs": "3c68ec584027dc36ca3f6f63d2f233b63c59b3c151fe026b76333d0f5b9bfb60342b58598f8f56f1024ddea3eec776f30f4847204d540158b849e207beebef55ecc7f7a835e71a56e8194c4471666170436c554d7351776d6f6e4e6946335f436f696e177a4f6e6d47415171506f586845705268637444785967350607701350223e3cdab45446e5108013d95bbb074b7b7d5023ccfda3e5ae212b173a146b6a43705259486f5563434f647466496c686a36147a434f61676e6d5854454c46444f4c7a59545876000607e658419e417115d1c60b01163f1012fad905cd42f2108c68d3cf3010fdc13b701749634c536d676e4c484b706c5a4e73557669626274614a03536f7900072edf45ce26ed750f48ac6572bf6b4fa931927c09aaedbbb07c9eb9bb65de21df0c6155587a43796a6b4a6172382076525772594e4c794d55666d6f70506a6648644943654d7a63416d454c78503600060607e1d6b084c1f753b1d0304bc83ab20d5fc44aa8a50408a8c8b9cefdba2c428f5e0f567846734450564f7278706c5a4c5907645757725175690007c30d2d828fb656cffd85d38bf06d8e06d93fae8441a9b9adfde74c3ae169299004765a44311074625245414d6d4951686c686765463800072f7f0ec5ac3242a8cfa8bf75fcdd3c30bdcb7cf9e6efbe6baee92133cad1d719104554696867564651654a79745043466304656264320007010108bc28daeefa1d0c87101d1c6fe79f590043549431784146a402010101000100102ff2d2197ccfcb4b656de0bc6f41a4f15113f14bf183e41df57ce4a12a96fd28a145e7bc8219fa7811002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f19228b6eb7129addc430ff23c7f00af9e07c6fb9b4b9b0dca8e4174fbdb5990ebd55bf8a9d0c0f778b448ebd65d1767d0174b556449cc46fc92ab5fc82d3a0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a385c204a88000efcb5cdd922adc043ab5a3332d5c15302548036ace686ad9da", - "sequence_number": "13704468344051268201", + "sender": "2e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f90741cd5116ce2c", + "sequence_number": "13292118493125151970", "payload": { "EntryFunction": { "module": { - "address": "d528e4c4d77ad4096fbc1822320f9d049768996e8362eac97be042f0fb46b480", - "name": "VrPjDswDgxEfRUACgw6_Coin" + "address": "3bf9191e78251d273a4ee049a35d1b898bbca0c2929727d437773e3d4dd578b2", + "name": "IwprzCDLkcuLMCTgG0_Coin" }, - "function": "IwOvKLAavjblSoPumHYOKVcWOYoVh4", + "function": "IXiYFIWxyMXEOMzwavLt", "ty_args": [ { "struct": { - "address": "2993dfef5ec0db4af60cc49cafe4e44dc6da010e5c8eee92f79b17d92c9e788b", - "module": "GSiLplAdjYfyRYzFVVwonSZdNG", - "name": "FkThBfdLNXiUKwlEVJtugYcv8", + "address": "d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae52ebc63bef3a", + "module": "MMedQDmbxNuBSCGLnUMlfXhDX4", + "name": "GxmPrUh6", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "c07fbde8d27ec9b72033b8a87327342a13712c729b8a8f418c458c00d48108bc", + "module": "mECBjERfYUmkSUBlbPeBen", + "name": "wUkDtUmzs", + "type_args": [] + } + } + }, + { + "struct": { + "address": "1e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9548307a8", + "module": "bCNxiIhtFUYjADitqhBqkyCso", + "name": "KqvEVeOHgpvtKsepKeohaGnTtoM", + "type_args": [] } }, { "vector": { - "struct": { - "address": "ee9771fa6d7d2f28eee2496fdf188ed03805b7d063201c3ef910880a48571197", - "module": "r5", - "name": "ROqhyzBBVwEZEaNYZRZZc", - "type_args": [] - } + "vector": "u8" } }, { "vector": { "struct": { - "address": "aade919e95a1ce2ce75142d67f3eb0dd609c51fd1e1ac8407c41a2f0e04048c7", - "module": "ypnBOodtpw4", - "name": "gSECCCEEVrdccGTonWm6", + "address": "920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9831b6b", + "module": "xmgyqKrKaVeRfk", + "name": "ZRVyD", "type_args": [] } } }, { "vector": { - "vector": { - "struct": { - "address": "1e7165c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c2955", - "module": "oQIlpRfGXMcnQNFKKCSJCDGYoSlSbevM", - "name": "FhKsnhrcVWiVViQU1", - "type_args": [] - } + "struct": { + "address": "4f11a194ff87b5c60978cea042e77c6693b6bd2f49301c4be3037364f3151418", + "module": "UMcnfeMJJsdYsRaASkFghSDuSc", + "name": "EUbSRCDtlNF0", + "type_args": [] } } }, { "struct": { - "address": "386210bdeaa52f74c499e9c087222aae35ee37821d62d664ec223f2f5aa57af0", - "module": "mjAUijmoS0", - "name": "VLeckVxCSLMdHiuavNfQhRfmOllFOVBm6", - "type_args": [] - } - }, - { - "struct": { - "address": "fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd86e4541d90b", - "module": "qbaRY", - "name": "GxsP3", + "address": "a0db485ce70b7a86ad3c7f0fbe157498533d9779e084cda141195d6357447778", + "module": "TaeQeYOfCxoJoGfVYcU", + "name": "suGbejDqIjpZrwfKjP9", "type_args": [] } }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "d7fcb3662122cba4982d03793481d0bddce4320ab977b083281cf2027e775683", - "module": "FtfmbEcsIf8", - "name": "kEqCUKXzn", + "address": "dec1bd013459b6dfd50447217498858823e8e94425b6857979424a4103a09f59", + "module": "xqkzc", + "name": "lEcTTiev", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "vector": { + "vector": "u128" + } + } } } ], - "args": [] + "args": [ + "f2c6d4904ab08c86afa601e5659cea8e97bcce58bb4e6accece1844e784cf521", + "ce", + "00", + "3777e4aa82b3177c", + "1f", + "01" + ] } }, - "max_gas_amount": "787700363516691461", - "gas_unit_price": "2253623552836068268", - "expiration_timestamp_secs": "12924879428485727890", - "chain_id": 253 + "max_gas_amount": "12812229658802979376", + "gas_unit_price": "10387984302647450081", + "expiration_timestamp_secs": "16871334350373130331", + "chain_id": 183 }, - "signed_txn_bcs": "a385c204a88000efcb5cdd922adc043ab5a3332d5c15302548036ace686ad9da69fac27a590d30be02d528e4c4d77ad4096fbc1822320f9d049768996e8362eac97be042f0fb46b480185672506a4473774467784566525541436777365f436f696e1e49774f764b4c4161766a626c536f50756d48594f4b5663574f596f5668340a072993dfef5ec0db4af60cc49cafe4e44dc6da010e5c8eee92f79b17d92c9e788b1a4753694c706c41646a59667952597a465656776f6e535a644e4719466b54684266644c4e5869554b776c45564a74756759637638000606040607ee9771fa6d7d2f28eee2496fdf188ed03805b7d063201c3ef910880a4857119702723515524f7168797a42425677455a45614e595a525a5a63000607aade919e95a1ce2ce75142d67f3eb0dd609c51fd1e1ac8407c41a2f0e04048c70b79706e424f6f6474707734146753454343434545567264636347546f6e576d36000606071e7165c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c2955206f51496c70526647584d636e514e464b4b43534a434447596f536c536265764d1146684b736e6872635657695656695155310007386210bdeaa52f74c499e9c087222aae35ee37821d62d664ec223f2f5aa57af00a6d6a4155696a6d6f533021564c65636b567843534c4d6448697561764e66516852666d4f6c6c464f56426d360007fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd86e4541d90b0571626152590547787350330006060007d7fcb3662122cba4982d03793481d0bddce4320ab977b083281cf2027e7756830b4674666d62456373496638096b457143554b587a6e000606000005c4dba44e79ee0aac633f5cae7a461f9246a57b5c655eb3fd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409bac87e879f6815dc4aa01e3618d5bd1df6418a68536bab89d090b0310172cefbdf079f501a1801531e36cf731e5d15c23ac8928795c4896aaf4a0ff40d5440a", + "signed_txn_bcs": "2e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f90741cd5116ce2ce20c2047581777b8023bf9191e78251d273a4ee049a35d1b898bbca0c2929727d437773e3d4dd578b217497770727a43444c6b63754c4d43546747305f436f696e144958695946495778794d58454f4d7a7761764c740907d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae52ebc63bef3a1a4d4d656451446d62784e75425343474c6e554d6c6658684458340847786d5072556836000607c07fbde8d27ec9b72033b8a87327342a13712c729b8a8f418c458c00d48108bc166d4543426a45526659556d6b5355426c62506542656e0977556b4474556d7a7300071e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9548307a81962434e78694968744655596a41446974716842716b7943736f1b4b71764556654f48677076744b7365704b656f6861476e54746f4d000606010607920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9831b6b0e786d6779714b724b61566552666b055a525679440006074f11a194ff87b5c60978cea042e77c6693b6bd2f49301c4be3037364f31514181a554d636e66654d4a4a73645973526141536b46676853447553630c45556253524344746c4e46300007a0db485ce70b7a86ad3c7f0fbe157498533d9779e084cda141195d6357447778135461655165594f6643786f4a6f4766565963551373754762656a4471496a705a7277664b6a50390007dec1bd013459b6dfd50447217498858823e8e94425b6857979424a4103a09f590578716b7a63086c456354546965760006060606030620f2c6d4904ab08c86afa601e5659cea8e97bcce58bb4e6accece1844e784cf52101ce0100083777e4aa82b3177c011f01013002ad19fe2eceb1e199a273af8829905b10d618340523eab7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400928d9e0cb72569fe718fbdcd5bc786cef60922ee4d2fdd4839ee8b4676250122ce5a12499070d698541d5aef03eea23d50fd3c452ba7f0d4eb3d8074ab8060d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "41e4f51efd906a78b101ec45005dc1b1e7e3bdb5106067d04aee032f9e950bd7", - "sequence_number": "18052590803928200838", + "sender": "f56da85068d328ca9f4f000f7f158bac3791d2f4e77fcc9942edba3d288e8661", + "sequence_number": "2381091883749179909", "payload": { "EntryFunction": { "module": { - "address": "b00b3bc4630f54aa5eba8e03e250c329900ce4e13797cf4d66deba8082273031", - "name": "sitibnobnSpx4_Coin" + "address": "49ce1e2ebf1166b97ec7d8ae199548a7ac968d45b584e00d948f4895147595c1", + "name": "TCkM_Coin" }, - "function": "BejSHvtcNAZXEzbPYbwFRy", + "function": "WqvmNFxwIJUWEvCgNbeMKJOQEnVMD3", "ty_args": [ { - "struct": { - "address": "6cb86465135097d01663f9934cc9e06a94e3c2f7f50e5c1093c324c63ef7419d", - "module": "bJQB8", - "name": "nlZYOjIWeQNiVoUw1", - "type_args": [] - } - }, - { - "struct": { - "address": "6d049dc804ad0be6b456670ffe578ec64b1430ce1a79340018dd973309d6f37a", - "module": "kfjhLPRvbuJZxYFzzohBqeROhAhM", - "name": "dSlTIAyoPtInGFMQwHZNWrgEt", - "type_args": [] + "vector": { + "struct": { + "address": "89e5575c81bf859caef143b0adfdb331e2b9267209b41073f9c24eb4386e3ec1", + "module": "KknxyVOPBXCQSNUAk3", + "name": "QpxrMdokDLxUiFGFszSXoglsv", + "type_args": [] + } } } ], "args": [ - "e0862d486cfbc3ce", - "89", - "f9a300544be778ae9f8364130827f6d8a48df09a21d63deb71daf90590f69ca5", - "00" + "f73d46165c8fc9567ad697b9f7c27863", + "cf2964467eef594f", + "01", + "01", + "987ca20f1b0bd902edc891a6a3093a3d", + "c3ea89772df7ce25aba1b9c236575da2e234bf66c2ae244c3b67cbb3ad6407fb", + "1be094ef12ebba7ac96777ffcdff8394" + ] + } + }, + "max_gas_amount": "6873527945612096672", + "gas_unit_price": "13091222159671541088", + "expiration_timestamp_secs": "3260526299180740587", + "chain_id": 216 + }, + "signed_txn_bcs": "f56da85068d328ca9f4f000f7f158bac3791d2f4e77fcc9942edba3d288e866105826fe473560b210249ce1e2ebf1166b97ec7d8ae199548a7ac968d45b584e00d948f4895147595c10954436b4d5f436f696e1e5771766d4e467877494a5557457643674e62654d4b4a4f51456e564d443301060789e5575c81bf859caef143b0adfdb331e2b9267209b41073f9c24eb4386e3ec1124b6b6e7879564f5042584351534e55416b3319517078724d646f6b444c785569464746737a53586f676c7376000710f73d46165c8fc9567ad697b9f7c2786308cf2964467eef594f0101010110987ca20f1b0bd902edc891a6a3093a3d20c3ea89772df7ce25aba1b9c236575da2e234bf66c2ae244c3b67cbb3ad6407fb101be094ef12ebba7ac96777ffcdff8394a0f4edbf3fad635f60bdf1a6315dadb5ebaf7ce364b73f2dd8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440adce82e43ae44894afd9532e24a361edb41690779e604f630f7e2d54c932212ebc94a7d4deddd05da776a9ebfb427059bcaa62bdf43b3b39252e36a97efcaa0c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "89096e1bbacac0bf73e8f01a5ad8859444e743e7c09357d7f520ed420c0f618f", + "sequence_number": "16646303590430540292", + "payload": { + "EntryFunction": { + "module": { + "address": "38cda35d66d698be8342b209283e25540fb019e071b10bddb44857b73c08af49", + "name": "aIqWIcx_Coin" + }, + "function": "fucjiQdpkxGHDvvSCzeIE", + "ty_args": [], + "args": [ + "32080be3deec3678", + "2cb863c3a69c3d11e0cd07469d96bb6e", + "c1d426523e43dc23913b883df9ed1e20", + "2943fe529dbf949a2b9fae4f06ccf864" ] } }, - "max_gas_amount": "17484836495617486891", - "gas_unit_price": "14301740504977152099", - "expiration_timestamp_secs": "2474958349761980257", - "chain_id": 245 + "max_gas_amount": "13720985037169515524", + "gas_unit_price": "1549985750013368675", + "expiration_timestamp_secs": "8310368323352221542", + "chain_id": 196 }, - "signed_txn_bcs": "41e4f51efd906a78b101ec45005dc1b1e7e3bdb5106067d04aee032f9e950bd786b69f7fb0af87fa02b00b3bc4630f54aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311273697469626e6f626e537078345f436f696e1642656a53487674634e415a58457a625059627746527902076cb86465135097d01663f9934cc9e06a94e3c2f7f50e5c1093c324c63ef7419d05624a514238116e6c5a594f6a495765514e69566f55773100076d049dc804ad0be6b456670ffe578ec64b1430ce1a79340018dd973309d6f37a1c6b666a684c50527662754a5a7859467a7a6f68427165524f6841684d1964536c544941796f5074496e47464d5177485a4e5772674574000408e0862d486cfbc3ce018920f9a300544be778ae9f8364130827f6d8a48df09a21d63deb71daf90590f69ca501002bf01075279ea6f26398fa2437fd79c66127739781d15822f5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400d2e55900a2dfd226b61d2404243e22619e6db6052e0ace1cdc67af00185aaeadb0426efe76396f051c0726487c070c3e5610a1800c43e2ab52c79d3ad86e30f", + "signed_txn_bcs": "89096e1bbacac0bf73e8f01a5ad8859444e743e7c09357d7f520ed420c0f618f0402ec6aeb8c03e70238cda35d66d698be8342b209283e25540fb019e071b10bddb44857b73c08af490c614971574963785f436f696e156675636a695164706b78474844767653437a65494500040832080be3deec3678102cb863c3a69c3d11e0cd07469d96bb6e10c1d426523e43dc23913b883df9ed1e20102943fe529dbf949a2b9fae4f06ccf864045cf0c431bb6abe63d976d4d3a78215665711baf55b5473c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405277a23229093ff77dec95ea68b34af6d799f52c002ededd18964bee1acf63000aba560dbb061a832bf59b8f44c1237a57c0c9c8e5c9646bbb9bad03b5679a05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "860786a2e72ff6bfb4269ab8925f514e02849da1d55da5c5686731b641ad7bd4", - "sequence_number": "4238815789794674729", + "sender": "f147491bfcad57b97d5c2d174711e0693e22976fa790f081b0aae4b4d27593c9", + "sequence_number": "2295976120420002857", "payload": { "EntryFunction": { "module": { - "address": "3c22488bafcb15495a5d163c7c108f356e187e9db9b6f7b563c2fd0dbca7141b", - "name": "BrZhiRCBkj9_Coin" + "address": "60165d39eeea8c26a1e8f558a3a353770364495fefe980593bf213ad4ff43436", + "name": "WiOMlEo8_Coin" }, - "function": "EYYdTuVugsTbfykfvoGmDQ9", + "function": "huXGQCTdzXFxlojzvVaRAvoFve4", "ty_args": [ { "vector": { "struct": { - "address": "0f6c49258197632e2e7607039ef09e5014701644697e82d57e74980dda7fd350", - "module": "cgcHEASgyNWFstPRtgDFoEjPdTEVSYKK", - "name": "C4", + "address": "34d6045ed94c34b6692020ac9be1d65e0f682ca28a6ed5d0b5362cfcd1d59aac", + "module": "fMoREh", + "name": "WNDmulBOlTpntiM", "type_args": [] } } }, { "struct": { - "address": "d17adc7b66ca5c45cd9d7d40b45c6398ef416bddb84a3909d17c33b61b60dac0", - "module": "J", - "name": "scVDUiVzlbjojltjtPWcGyYBOfWY2", + "address": "df7b06a43804e9849cda19520de4fe6b2423470f765354df246c714d34a6bcb5", + "module": "bpJxrHIOZtkEqwAJciSIoienZqs", + "name": "lQDxxqxabCzJwICprxmfVACXrgMsWkM9", "type_args": [] } }, { "struct": { - "address": "9a169316ddbdb6b5bac240aacf75bcc7345a010b11d84296fd19650faedb72a8", - "module": "BoYsHeJkePGMrCuNcJjBHgAHkdXew1", - "name": "hrQztUKbtAQPmNwj", - "type_args": [] - } - }, - { - "struct": { - "address": "975efb5db65d1004bf46294f302442a7aa2c01fd1527a93cc3d5f8fde315079b", - "module": "ebLZCPtViTQ", - "name": "AXqxrY", + "address": "816da3c80107b83f5358b779f363a2d91204a2444b37da9591adde2d000b7de6", + "module": "LFoOytcjGY0", + "name": "cNZoAjYflPhgOxYWcDzUYoFSNK9", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "ab4e989cad803d8125ab3879879d65127551510a7821030b99b5e35e7327d316", - "module": "DdKOQNtWBXAHtHqnNmPvMrHIAbYlUyNZ", - "name": "hcbRkETOzdHUOTqaKpJpfcvgXD", - "type_args": [] - } + "struct": { + "address": "552324dba74b8af97fdf022428888a887bc8ef8569bf1ad65c40941d273d6856", + "module": "agdVMJhH8", + "name": "gnRFQYHYHJmV5", + "type_args": [] } } }, { - "vector": "u128" - }, - { - "struct": { - "address": "ed3895aa0898bbd5c47991ec3b128156b7db80678b65591edd9e2fa161c0fba8", - "module": "qVnKKxBJJYXmuUnQxJLuKF", - "name": "hTCM", - "type_args": [] + "vector": { + "struct": { + "address": "9d94389021547140b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7", + "module": "xQHMaISKmJyiBLBZoIkVKAej", + "name": "spcypVzZxOoyBrhN6", + "type_args": [] + } } } ], - "args": [] + "args": [ + "ad77195f31bc8614a27c706c6e89c86a02016401780261df8a98ce8d9e0cd026", + "86", + "c6", + "01", + "d8b5ab8c3fb04f44da60b3af065400dafda15f3274e2493a7a993059a9d1d8a7", + "ca0afe31a8fcdcfa1a480da29d83584f" + ] } }, - "max_gas_amount": "16567008626372739107", - "gas_unit_price": "3683144946775359419", - "expiration_timestamp_secs": "4904256669355706873", - "chain_id": 122 + "max_gas_amount": "11272266645211468354", + "gas_unit_price": "7103600372080276284", + "expiration_timestamp_secs": "17538683650486161090", + "chain_id": 85 }, - "signed_txn_bcs": "860786a2e72ff6bfb4269ab8925f514e02849da1d55da5c5686731b641ad7bd4294807ab804cd33a023c22488bafcb15495a5d163c7c108f356e187e9db9b6f7b563c2fd0dbca7141b1042725a68695243426b6a395f436f696e1745595964547556756773546266796b66766f476d4451390706070f6c49258197632e2e7607039ef09e5014701644697e82d57e74980dda7fd350206367634845415367794e574673745052746744466f456a506454455653594b4b0243340007d17adc7b66ca5c45cd9d7d40b45c6398ef416bddb84a3909d17c33b61b60dac0014a1d736356445569567a6c626a6f6a6c746a74505763477959424f6657593200079a169316ddbdb6b5bac240aacf75bcc7345a010b11d84296fd19650faedb72a81e426f597348654a6b6550474d7243754e634a6a42486741486b6458657731106872517a74554b62744151506d4e776a0007975efb5db65d1004bf46294f302442a7aa2c01fd1527a93cc3d5f8fde315079b0b65624c5a435074566954510641587178725900060607ab4e989cad803d8125ab3879879d65127551510a7821030b99b5e35e7327d3162044644b4f514e7457425841487448716e4e6d50764d7248494162596c55794e5a1a686362526b45544f7a6448554f5471614b704a7066637667584400060307ed3895aa0898bbd5c47991ec3b128156b7db80678b65591edd9e2fa161c0fba81671566e4b4b78424a4a59586d75556e51784a4c754b46046854434d00002380c7e591d6e9e5bbffd1a0d0281d33f98949f8746b0f447a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403119557d7e3d18a28b0df24b5efa8f3e3474b290bfe05aeda457bfb409843738a5ec0e0c612b7d0cd40a4898e544faae37d2fa77d97ff44d4f833f1347363505", + "signed_txn_bcs": "f147491bfcad57b97d5c2d174711e0693e22976fa790f081b0aae4b4d27593c929ec69ee1df2dc1f0260165d39eeea8c26a1e8f558a3a353770364495fefe980593bf213ad4ff434360d57694f4d6c456f385f436f696e1b68755847514354647a5846786c6f6a7a7656615241766f4676653405060734d6045ed94c34b6692020ac9be1d65e0f682ca28a6ed5d0b5362cfcd1d59aac06664d6f5245680f574e446d756c424f6c54706e74694d0007df7b06a43804e9849cda19520de4fe6b2423470f765354df246c714d34a6bcb51b62704a787248494f5a746b457177414a636953496f69656e5a7173206c5144787871786162437a4a7749437072786d665641435872674d73576b4d390007816da3c80107b83f5358b779f363a2d91204a2444b37da9591adde2d000b7de60b4c466f4f7974636a4759301b634e5a6f416a59666c5068674f78595763447a55596f46534e4b39000607552324dba74b8af97fdf022428888a887bc8ef8569bf1ad65c40941d273d685609616764564d4a6848380d676e524651594859484a6d56350006079d94389021547140b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7187851484d6149534b6d4a7969424c425a6f496b564b41656a117370637970567a5a784f6f794272684e36000620ad77195f31bc8614a27c706c6e89c86a02016401780261df8a98ce8d9e0cd026018601c6010120d8b5ab8c3fb04f44da60b3af065400dafda15f3274e2493a7a993059a9d1d8a710ca0afe31a8fcdcfa1a480da29d83584f42525071ca226f9c3c732de4e60e9562c2ce2d2fdbeb65f355002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408605ff4d2706892a22914e3a6414de317c0d0a92acdacd2a2abd2f3032097d05813571f213f3e3e518cc1d7a0964b9d8a3cb0b7fc523bef882e537f576294201", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4a2965ea422d11818be607577cedbe8f41849cd0957dfcc290fb07322e803c12", - "sequence_number": "14472827820061072350", + "sender": "b070c8fa03321ace0f289c3a9da57a48c598422994f9333d730bd8c0ef769ad7", + "sequence_number": "6177125906860738368", "payload": { "EntryFunction": { "module": { - "address": "b3f18de0af2ab3f4af1afaabfa0b6c9d5737979d1430e5bba461f82b83d733f2", - "name": "B4_Coin" + "address": "9edb2d8553a262b1020039f593f28bd713469a8d57b28e62d6943c281096ccbf", + "name": "hZkoT6_Coin" }, - "function": "EBwwXnTxEeW6", + "function": "WjAozPRLmAXgBQkbhTROvRfU8", "ty_args": [ { - "struct": { - "address": "605e4624f631ea88c07742715dfb8f450d0877c81c0fd68df92024604521c1ce", - "module": "ipHksqmtEIwoEjF9", - "name": "jlBKO7", - "type_args": [] - } - }, - { - "struct": { - "address": "1a131db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce507", - "module": "MxOIolAFQODFSekDZF6", - "name": "XNCcsygyKicPcQQbPunaQKhJMEz5", - "type_args": [] + "vector": { + "struct": { + "address": "7810c3d438a37068359ebdcb9e0e1e0e7330122b078211c4a5dee4d8c86e73bf", + "module": "jqfDtSEUsobUtAayQDQpKhlZDggKCKi", + "name": "IGBzfGWXNlSO2", + "type_args": [] + } } }, { "vector": { "vector": { - "struct": { - "address": "b4307919ddfa7e916aa5d0b6282c7531478a90001de4d6057ee6a3c787412a60", - "module": "cywFVWalxsfynoMtbaIQJQ8", - "name": "h9", - "type_args": [] - } + "vector": "u8" } } - } - ], - "args": [ - "80", - "00", - "f8cc9b1b7791758f", - "00", - "13", - "df8ecc3c5f0374e9e2f6be3af3e46c0ed1ec0f614d3903b0ce42b03dbc1eec6f", - "8b03c8202ae75de7", - "ebe58764f802bdcb622bee5fb91d1bf2" - ] - } - }, - "max_gas_amount": "7612315422534578784", - "gas_unit_price": "7126107356915110626", - "expiration_timestamp_secs": "3765643732774742854", - "chain_id": 144 - }, - "signed_txn_bcs": "4a2965ea422d11818be607577cedbe8f41849cd0957dfcc290fb07322e803c12de9b21d638d0d9c802b3f18de0af2ab3f4af1afaabfa0b6c9d5737979d1430e5bba461f82b83d733f20742345f436f696e0c45427777586e5478456557360307605e4624f631ea88c07742715dfb8f450d0877c81c0fd68df92024604521c1ce106970486b73716d744549776f456a4639066a6c424b4f3700071a131db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce507134d784f496f6c4146514f444653656b445a46361c584e4363737967794b6963506351516250756e61514b684a4d457a3500060607b4307919ddfa7e916aa5d0b6282c7531478a90001de4d6057ee6a3c787412a6017637977465657616c787366796e6f4d74626149514a513802683900080180010008f8cc9b1b7791758f0100011320df8ecc3c5f0374e9e2f6be3af3e46c0ed1ec0f614d3903b0ce42b03dbc1eec6f088b03c8202ae75de710ebe58764f802bdcb622bee5fb91d1bf260b266868b60a469e21239a8e204e56246ebb6120641423490002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405044c02d7ff12713b61ec66ba82c1fd33a3552c5bbc591e779aab95c443fa45d444bea31f262eed464a0dc91b27a7bc8e360ab26e8fa55b6e931ad09d3ecea03", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "8506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d758d76b", - "sequence_number": "16877266771338628753", - "payload": { - "EntryFunction": { - "module": { - "address": "0a3a6beb54c9ab707b21dc407a3da42954a3f9e82c9f40f6e4bb868beb92438b", - "name": "NVfSb1_Coin" - }, - "function": "GwCzqwFNmNmhunYMIm", - "ty_args": [ + }, { "struct": { - "address": "0cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d619", - "module": "GM", - "name": "yKNbTAtXrLbaLeDryqFNsGNFQTJTrbgy2", + "address": "bd90884985a0f75c3ac76eab9debcf33b3ab3bd6f8f10937f7b1704340a53911", + "module": "PfCFEwt2", + "name": "uHmS1", "type_args": [] } } ], "args": [ - "501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0332e9e95fa8", - "d6422734f9842be9", - "f8742a4cb2d4ae0b4ff2af62fc66a612053653909ae67f34c0f3220b2cf3261d", - "2df19b9d1d6f168d38553ab95059e82a", - "8c3fcf4f75140f69f019e29c5e256df847505437915834afc3fc037f5e65f02f", - "48507c47db215d7fd066ff188a74b993f4bd5bf250bc448c99333e57e1cc71c7" + "9e333853075c6771a21ca87cc088433e" ] } }, - "max_gas_amount": "11438595287817743361", - "gas_unit_price": "16967601714845867504", - "expiration_timestamp_secs": "12991137736850721006", - "chain_id": 173 + "max_gas_amount": "16505778574009280432", + "gas_unit_price": "17406207243672207826", + "expiration_timestamp_secs": "1113148162930406650", + "chain_id": 250 }, - "signed_txn_bcs": "8506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d758d76b918e247db51838ea020a3a6beb54c9ab707b21dc407a3da42954a3f9e82c9f40f6e4bb868beb92438b0b4e56665362315f436f696e124777437a7177464e6d4e6d68756e594d496d01070cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d61902474d21794b4e6254417458724c62614c6544727971464e73474e4651544a547262677932000620501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0332e9e95fa808d6422734f9842be920f8742a4cb2d4ae0b4ff2af62fc66a612053653909ae67f34c0f3220b2cf3261d102df19b9d1d6f168d38553ab95059e82a208c3fcf4f75140f69f019e29c5e256df847505437915834afc3fc037f5e65f02f2048507c47db215d7fd066ff188a74b993f4bd5bf250bc448c99333e57e1cc71c7016cd55bcf0dbe9ef05db287dc0779ebeec82811f1ca49b4ad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099ca6939ff52a83aaf81ab2917ac2afc4623ad9ac8644dc44ed75d08d1d7913e2c9184d767b23a140a5247f30e7bebf0b48b7f0edf6cd3b02ce2da3f381eef01", + "signed_txn_bcs": "b070c8fa03321ace0f289c3a9da57a48c598422994f9333d730bd8c0ef769ad740074cd3488fb955029edb2d8553a262b1020039f593f28bd713469a8d57b28e62d6943c281096ccbf0b685a6b6f54365f436f696e19576a416f7a50524c6d41586742516b626854524f76526655380306077810c3d438a37068359ebdcb9e0e1e0e7330122b078211c4a5dee4d8c86e73bf1f6a71664474534555736f625574416179514451704b686c5a4467674b434b690d4947427a664757584e6c534f32000606060107bd90884985a0f75c3ac76eab9debcf33b3ab3bd6f8f10937f7b1704340a539110850664346457774320575486d53310001109e333853075c6771a21ca87cc088433eb0a71365294e10e5d2c1e91d44458ff1fa74d8415bb2720ffa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d029aa60189666152f8263e0756a89b305b6d78e0992da765438969e2a42daeeb10eb0f6e458c886babcf404a2744804c33707a60c694ecf326020c792dd7b0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6c4fbc1b3da1dcc6fecf0762d1b4d5c92e0f4aa35a7137aa18b5bd0cdafbeb88", - "sequence_number": "2102221068478695521", + "sender": "e9482f794ee5a19e8dabbe1835c8fdd0b63b7569ff446e7f9cee01309567c04b", + "sequence_number": "16538324045974198284", "payload": { "EntryFunction": { "module": { - "address": "834ec1e45eea6ff41eed5665fd11f309f0ce9f8c238804f2c85cfee8822937ff", - "name": "ZlKDxOQ1_Coin" + "address": "4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1676f478200", + "name": "n8_Coin" }, - "function": "cbIsL6", + "function": "xrdNNgAxMOxHNJSSEGomiG", "ty_args": [ { "struct": { - "address": "a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1df", - "module": "jJtxkPaWmngdifTrA", - "name": "qsXCConWUoHRCqsWFQMurLhjggbe8", + "address": "2d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b756544ca80644f26fcf50ee", + "module": "ioLpxRgluJNVsfCiUFbaTRkyg", + "name": "bahcEKQFdAS4", + "type_args": [] + } + }, + { + "struct": { + "address": "243aca41876befd6e5bd163e5f4ecfa7c32003f8a25d5be63a3119056de66f05", + "module": "QHcQLTatpeGnUctL", + "name": "onNDjD", "type_args": [] } }, { "vector": { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "c5032f880e9e9906dbd9e476f7c9e994190e69d225149cfef23a408ec549392d", + "module": "Xra", + "name": "OpRTKAwFGvWSjjWS", + "type_args": [] } } } }, { "struct": { - "address": "12b76fef2bc2510ac6f2392243a581ad1f777511b44224e5c759090d9fdb4159", - "module": "fOjTySPBIFzHOFFaPagNTDuZaM", - "name": "HOwaW", - "type_args": [] - } - }, - { - "struct": { - "address": "66f4f2943450fdbda3086482fdd32ed151d994e5c9166424e69ff945aa011afb", - "module": "sButNDrdOtUtKMQOdYZJFTxtLxtMll", - "name": "MKWHNV", + "address": "c6ba3969486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014c", + "module": "LaWEdIFFlGTmdy3", + "name": "ySXBJyBJWrtkNzRf", "type_args": [] } } ], "args": [ - "b3a74ab81ec292c5", - "50", - "c8743e72da832594", - "f3" + "00", + "23f2b221a414203e6559274f9e542a889bb5fde471da04e8b0334f87b78c7aa0", + "a6" ] } }, - "max_gas_amount": "2162485022171231861", - "gas_unit_price": "3033277309195572849", - "expiration_timestamp_secs": "7167970984150080068", - "chain_id": 226 + "max_gas_amount": "4470031051066226875", + "gas_unit_price": "13286768312151856452", + "expiration_timestamp_secs": "16078901869778707216", + "chain_id": 134 }, - "signed_txn_bcs": "6c4fbc1b3da1dcc6fecf0762d1b4d5c92e0f4aa35a7137aa18b5bd0cdafbeb8861c8037aec962c1d02834ec1e45eea6ff41eed5665fd11f309f0ce9f8c238804f2c85cfee8822937ff0d5a6c4b44784f51315f436f696e06636249734c360407a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1df116a4a74786b5061576d6e676469665472411d71735843436f6e57556f48524371735746514d75724c686a67676265380006060606040712b76fef2bc2510ac6f2392243a581ad1f777511b44224e5c759090d9fdb41591a664f6a547953504249467a484f4646615061674e5444755a614d05484f776157000766f4f2943450fdbda3086482fdd32ed151d994e5c9166424e69ff945aa011afb1e734275744e4472644f7455744b4d514f64595a4a465478744c78744d6c6c064d4b57484e56000408b3a74ab81ec292c5015008c8743e72da83259401f375769e9aabb0021e71d6da47a45d182a449a92eea1bf7963e2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bbfa845aefb2e69d1a481c62a6a89fcba8b0adf7d8999bcd45ae2fe375c44247fa1e4718b4b0c388c07a63eb5b5a7e6c77e2e563645a05d533ef53305d128e02", + "signed_txn_bcs": "e9482f794ee5a19e8dabbe1835c8fdd0b63b7569ff446e7f9cee01309567c04b0cd8979418ee83e5024c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1676f478200076e385f436f696e167872644e4e6741784d4f78484e4a535345476f6d694704072d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b756544ca80644f26fcf50ee19696f4c707852676c754a4e56736643695546626154526b79670c62616863454b5146644153340007243aca41876befd6e5bd163e5f4ecfa7c32003f8a25d5be63a3119056de66f0510514863514c5461747065476e5563744c066f6e4e446a4400060607c5032f880e9e9906dbd9e476f7c9e994190e69d225149cfef23a408ec549392d03587261104f7052544b417746477657536a6a57530007c6ba3969486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014c0f4c615745644946466c47546d64793310795358424a79424a5772746b4e7a5266000301002023f2b221a414203e6559274f9e542a889bb5fde471da04e8b0334f87b78c7aa001a6bbb8c4c58ebd083e4455ba32621564b8102386960fbc23df86002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c60b890f9cbd5dc35042092e546028bbd55ec07bbee814d0a552121f8a08a69ccb8b469a1a2c69b4d08cc909d9cab085441afd12a25a64b6fb055b17a127e600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c173dd48e9f2ae09bd68bb4b0d46022d610e13d2ad8d703adb6c96d404865934", - "sequence_number": "13985455694557908219", + "sender": "b85711e1213ac8fe40b9427fb2af6b085da8fcb70a74714f1d63e47298b01b86", + "sequence_number": "4956597925115649980", "payload": { "EntryFunction": { "module": { - "address": "e5f26a79de77b33b3c8ecf733383dcfa56f6d27000c3cc33a79ec804fd847170", - "name": "CHKLPVOmZqgW_Coin" + "address": "ee2cba765b7702bdeef83f4a6afdcd4c6d7674987a201d144d0e2fa3eb2853ba", + "name": "pOFwzUyiAalXbxsSMFOFMU_Coin" }, - "function": "eW4", + "function": "dOcPYCTfgLY", "ty_args": [ { "vector": { - "struct": { - "address": "a663385db20dd34fe57b6c1eb841ec2c6b10435b7bd986ce8f36cec6759aee49", - "module": "oiXhHPVkvIjiMPWMgq", - "name": "U", - "type_args": [] + "vector": "u128" + } + }, + { + "struct": { + "address": "8c5f1682743700b660426b943490d132eb11d3c492c27c710a4d4a1b0db5127d", + "module": "IkFinBjunFrzVIBUc9", + "name": "FjZBGaL3", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "d39cca3d33506b8cc1221bbf54b3edd7443c1bcc5abbe5511506179ff006038f", + "module": "YvGhRicYgvGXbucsrSODZf", + "name": "KmkPJdQmXSxZU0", + "type_args": [] + } } } }, { "struct": { - "address": "1eb940db2f3cd6b1424666fea07f1d3dae707982e5679a7e54168b3375dac71c", - "module": "WpePAi6", - "name": "VlOnkettbXAath", + "address": "e01827210ea33744d8de768fc9a717520763b272711112eaae09abf56595e363", + "module": "SygwyhrIiydwGZqUKLsmqDKhJT2", + "name": "CfCnzBGDIk", "type_args": [] } }, { "struct": { - "address": "4b4935517f18690a5794280e78652a20b8a4b60f87656e6a685e048942eb8cba", - "module": "VfsQLrFRrymXxCRqSeRmAEVuF7", - "name": "mJPVRBKblkxlk", + "address": "1bc8e3935aa010725a41f4fa105379f6045df944ad1149167917251287626c84", + "module": "lyuwVjLEhQyFVJVLZ", + "name": "xwetNgogPPlpnsjOjKqActTZIgfEOC", "type_args": [] } + }, + { + "vector": { + "vector": { + "vector": { + "vector": "address" + } + } + } + }, + { + "vector": { + "vector": "bool" + } } ], "args": [ - "7180113a716403c7", - "4baf11cf52927097", - "e8" + "a795eb563695723446af4f3bb75df514", + "00", + "d4c80dbb9d6a756a269aea819864c89241db96b0de8a7f7a9973b0c434d401f7", + "9f7646c98c5295d5e7c36f4699e30360", + "85", + "62a0a7a293bc3d2f97c8d51d4b5259e2ac853931e17f5006fcf6cb26c7375e26", + "3c424b72d1a01047bef0c8c74dacccd0ca2817dd17e1be19cedffb5b949f9688", + "51", + "3a24213abe8695979eb3c628be7dbb7b2ced8a6727b9677b0b163b797a7aac78" ] } }, - "max_gas_amount": "9656599366441229911", - "gas_unit_price": "3246663498399746146", - "expiration_timestamp_secs": "6365248133953928743", - "chain_id": 81 + "max_gas_amount": "16404006694186810573", + "gas_unit_price": "13172268199097888748", + "expiration_timestamp_secs": "8841549655154613548", + "chain_id": 92 }, - "signed_txn_bcs": "c173dd48e9f2ae09bd68bb4b0d46022d610e13d2ad8d703adb6c96d404865934fb8c1628db5116c202e5f26a79de77b33b3c8ecf733383dcfa56f6d27000c3cc33a79ec804fd8471701143484b4c50564f6d5a7167575f436f696e03655734030607a663385db20dd34fe57b6c1eb841ec2c6b10435b7bd986ce8f36cec6759aee49126f6958684850566b76496a694d50574d6771015500071eb940db2f3cd6b1424666fea07f1d3dae707982e5679a7e54168b3375dac71c07577065504169360e566c4f6e6b65747462584161746800074b4935517f18690a5794280e78652a20b8a4b60f87656e6a685e048942eb8cba1a566673514c72465272796d58784352715365526d4145567546370d6d4a505652424b626c6b786c6b0003087180113a716403c7084baf11cf5292709701e857defdfef52103866208580f40770e2d27be8a0b74e7555851002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f91c7f155886ebbcb761238a666aba6a7ea7cb76856abd8f35fa5c04ab47299648e50ea9fcb8f373e3c960d61b71514b632765687ed24e314b6817e69c10a80f", + "signed_txn_bcs": "b85711e1213ac8fe40b9427fb2af6b085da8fcb70a74714f1d63e47298b01b86bcdff43c8d5fc94402ee2cba765b7702bdeef83f4a6afdcd4c6d7674987a201d144d0e2fa3eb2853ba1b704f46777a55796941616c58627873534d464f464d555f436f696e0b644f635059435466674c5907060603078c5f1682743700b660426b943490d132eb11d3c492c27c710a4d4a1b0db5127d12496b46696e426a756e46727a56494255633908466a5a4247614c3300060607d39cca3d33506b8cc1221bbf54b3edd7443c1bcc5abbe5511506179ff006038f165976476852696359677647586275637372534f445a660e4b6d6b504a64516d5853785a55300007e01827210ea33744d8de768fc9a717520763b272711112eaae09abf56595e3631b537967777968724969796477475a71554b4c736d71444b684a54320a4366436e7a424744496b00071bc8e3935aa010725a41f4fa105379f6045df944ad1149167917251287626c84116c797577566a4c4568517946564a564c5a1e787765744e676f6750506c706e736a4f6a4b71416374545a496766454f430006060606040606000910a795eb563695723446af4f3bb75df514010020d4c80dbb9d6a756a269aea819864c89241db96b0de8a7f7a9973b0c434d401f7109f7646c98c5295d5e7c36f4699e3036001852062a0a7a293bc3d2f97c8d51d4b5259e2ac853931e17f5006fcf6cb26c7375e26203c424b72d1a01047bef0c8c74dacccd0ca2817dd17e1be19cedffb5b949f96880151203a24213abe8695979eb3c628be7dbb7b2ced8a6727b9677b0b163b797a7aac78cd7c221c2dbda6e3ec6f672d234ccdb62cdd771b917eb37a5c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b2f6208ea7db2b172f8cb58f96699a07bb8bed200e50c2cf0b543bcb4786d56a9f45a81bd7a3609f970077ebce8940fcf2c05f3ae1f705cc8301219b63e89509", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7aa115aa69dcb6277ad3cf843e50dea69f536ebe4de13e206e141ae390ff869f", - "sequence_number": "9067414561635691199", + "sender": "ccf524d78d3bba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf8", + "sequence_number": "11799231719437850743", "payload": { "EntryFunction": { "module": { - "address": "9ca2ee85e9bb9bb000ced8b239f53b90594c88f9e807dd4e1f81da7bd68324e1", - "name": "kxKctZAuEML3_Coin" + "address": "b18ee30a1ba60617d5c49b646a14f3646a694aa87a087803df1b761d125356fc", + "name": "OUpdOpZmKvZ_Coin" }, - "function": "BpwHgjTDHneUCG3", + "function": "AqzEReSpdxakrGdruwrh5", "ty_args": [ { - "vector": { - "vector": "u64" + "struct": { + "address": "32b45d3839c25c64ce0285b71c579cd24a624b8354dbe9b850a2a424029fad2c", + "module": "iOZh4", + "name": "XDtLKCJVZjswnIyvcdkBfO8", + "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": "signer" } }, { "vector": { - "vector": "u64" - } - }, - { - "struct": { - "address": "6bacda7b4018500e44f72c7535b43adfe4d18b65f9e82e66e65262b20e0edcce", - "module": "WEeYkmQXzfdLeEbLOGSRNnVBThRV4", - "name": "UkgYeEJb8", - "type_args": [] + "struct": { + "address": "022199ea4571ff4db56b0c46b14521c1c43083051456a5c2713baf0ec3d2be55", + "module": "vHt", + "name": "etbjGBTE", + "type_args": [] + } } } ], "args": [ - "b4", - "00", - "d1", - "99", - "f0", - "0b50a699cb67466ad825a55216ba50ba5f41b71de797f893930d2b7b871295dc", - "01", - "97f70e43540259d75858ad063b0bf155" + "87555392c0343597446aa172ffd0850d", + "3d9a302ce75670d8eaa475ebb56cd2a189596b47e12386e42b45a4c8d99ca696" ] } }, - "max_gas_amount": "16583592488852503128", - "gas_unit_price": "12778924948966926060", - "expiration_timestamp_secs": "12171629856011959008", - "chain_id": 162 + "max_gas_amount": "1143267728454726271", + "gas_unit_price": "10396682778159846291", + "expiration_timestamp_secs": "8016354214383991969", + "chain_id": 108 }, - "signed_txn_bcs": "7aa115aa69dcb6277ad3cf843e50dea69f536ebe4de13e206e141ae390ff869fbfea7fa980edd57d029ca2ee85e9bb9bb000ced8b239f53b90594c88f9e807dd4e1f81da7bd68324e1116b784b63745a4175454d4c335f436f696e0f42707748676a5444486e655543473304060602060601060602076bacda7b4018500e44f72c7535b43adfe4d18b65f9e82e66e65262b20e0edcce1d574565596b6d51587a66644c6545624c4f4753524e6e5642546852563409556b675965454a6238000801b4010001d1019901f0200b50a699cb67466ad825a55216ba50ba5f41b71de797f893930d2b7b871295dc01011097f70e43540259d75858ad063b0bf15558bae34581c124e6ece68c1289dc57b1e0ba21b1dd50eaa8a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440235b541a406ea18a3e6850d08624d448f1e57da90825c4770b4671db1a614139530723a26a2fb195996dd13253af57f50bf64beccd8f641442ac1af408686603", + "signed_txn_bcs": "ccf524d78d3bba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877589ddbbb4abfa302b18ee30a1ba60617d5c49b646a14f3646a694aa87a087803df1b761d125356fc104f5570644f705a6d4b765a5f436f696e1541717a45526553706478616b724764727577726835030732b45d3839c25c64ce0285b71c579cd24a624b8354dbe9b850a2a424029fad2c05694f5a6834175844744c4b434a565a6a73776e49797663646b42664f38000606050607022199ea4571ff4db56b0c46b14521c1c43083051456a5c2713baf0ec3d2be5503764874086574626a4742544500021087555392c0343597446aa172ffd0850d203d9a302ce75670d8eaa475ebb56cd2a189596b47e12386e42b45a4c8d99ca6967f32b615f1b3dd0f9393a31ae76f4890a13c107eafcf3f6f6c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401c0d7f4085aeaf3c23a23221eb9977672c69cb30b73125b884215f10f1de9a08cfc0f71b3b11e2dfd9efebb4601c68121f8ab046efe69c1618ae7f3e52cad109", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "263abebe0754ea910db90c2e648a641dac56dc04da79911b6ca6134befa202f4", - "sequence_number": "7017105405210085067", + "sender": "94ea8b1a03dd9934414a6151d97802e4fb0f48dd9d03555df1d57d3fce35ba80", + "sequence_number": "5724768557541440751", "payload": { "EntryFunction": { "module": { - "address": "d1da4cc74a36ca0bff67e7ead53b962035103df55b886fcc61e4e2391824e42c", - "name": "FTdPWFwpUYApolhymdhmYrmUGQ1_Coin" + "address": "02e733b1df658a21fe60272acd6d52d54b5ef050f8d67113895a895cf24ff957", + "name": "XxFLDT_Coin" }, - "function": "gaHrPAubtNasp8", + "function": "p6", "ty_args": [ + { + "struct": { + "address": "74f3c427591f6dd5a4ae6aa6ada5dbb5091ef2332c4206a83062408e08a6c770", + "module": "hTlaDxMWfaMbbZklpUmTWlJw4", + "name": "gUg7", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "2f3569966f98a1ab8ca218e62d464714e41c7ed7bfae541cce3ee838e35439b4", - "module": "XUdHVdOtpZmZ8", - "name": "WlWF0", - "type_args": [] + "vector": { + "vector": "u128" } } }, { "struct": { - "address": "3016eca4e0b80ae5832b79a25541f5a550919723b880b6d5dd667193a73a9082", - "module": "WJzSXQSqELWa6", - "name": "gniSkpquyJWAzZYuEpoG", + "address": "4564b311f2e3c0efc3791b5b1387cff1bdd9ec686ed8d9cdaa500b7de5dcee94", + "module": "icjmhTKUwmRBJkxVrTrKepUjuflNe", + "name": "bWqwlwgrCKcgLhFvZmYzSSZEYThwCp", "type_args": [] } } ], "args": [ + "40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb348adc2c", + "1393e67584cc468b98cd9933555e63a1edeba3b11e8d5640815c35a63da15676", "00", - "52ba97f21f079ef7", "00", - "b4044794a4e44a4e", - "00" + "f1392af899faf0705459388c6584750ae8d1a891b721a8d98a300fbb694ad6fc", + "00", + "8e", + "01" ] } }, - "max_gas_amount": "2470189135079308135", - "gas_unit_price": "14676404892966061827", - "expiration_timestamp_secs": "7946542680997397790", - "chain_id": 230 + "max_gas_amount": "7942297055904599991", + "gas_unit_price": "15221829944515414785", + "expiration_timestamp_secs": "7048737163643094817", + "chain_id": 238 }, - "signed_txn_bcs": "263abebe0754ea910db90c2e648a641dac56dc04da79911b6ca6134befa202f4cb46051530c4616102d1da4cc74a36ca0bff67e7ead53b962035103df55b886fcc61e4e2391824e42c204654645057467770555941706f6c68796d64686d59726d554751315f436f696e0e6761487250417562744e617370380206072f3569966f98a1ab8ca218e62d464714e41c7ed7bfae541cce3ee838e35439b40d5855644856644f74705a6d5a3805576c57463000073016eca4e0b80ae5832b79a25541f5a550919723b880b6d5dd667193a73a90820d574a7a5358515371454c57613614676e69536b707175794a57417a5a597545706f47000501000852ba97f21f079ef7010008b4044794a4e44a4e0100677b6e44eedf472203070cc17d10adcb1e85543d77ca476ee6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444058c291b5f10623e98d3cdd97138226529ef80646766a4061c5cd6d7d7e7b7f2c456a5682c7b529296e7fb9d7d7348cbdf52dd60dcd9c9ca4c81f89884dfe4807", + "signed_txn_bcs": "94ea8b1a03dd9934414a6151d97802e4fb0f48dd9d03555df1d57d3fce35ba80ef3c9505ac76724f0202e733b1df658a21fe60272acd6d52d54b5ef050f8d67113895a895cf24ff9570b5878464c44545f436f696e027036030774f3c427591f6dd5a4ae6aa6ada5dbb5091ef2332c4206a83062408e08a6c7701968546c6144784d5766614d62625a6b6c70556d54576c4a773404675567370006060603074564b311f2e3c0efc3791b5b1387cff1bdd9ec686ed8d9cdaa500b7de5dcee941d69636a6d68544b55776d52424a6b78567254724b6570556a75666c4e651e625771776c776772434b63674c6846765a6d597a53535a4559546877437000082040ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb348adc2c201393e67584cc468b98cd9933555e63a1edeba3b11e8d5640815c35a63da156760100010020f1392af899faf0705459388c6584750ae8d1a891b721a8d98a300fbb694ad6fc0100018e0101b70fd39d17b5386e01cb3e92afcd3ed321870ac21a25d261ee002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440af84219e85b772223c6c6c485108994b40e3db4e45e33dab66806e626d4f9a9036df32e61d47c23301588d1158dc481c4b7592dd2ef8aa6ef54f759c6229d803", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4340105451eb392d3cc037dc812416941c1dc10b913665144b1d6b9d90043379", - "sequence_number": "14768792697688847021", + "sender": "f32477ffca61486c2c8ae41b00c4b4791577bb28508f131860045cc1904af61b", + "sequence_number": "10369884036316857967", "payload": { "EntryFunction": { "module": { - "address": "ee1ad60948498ddbe6a6ebd91d38db29b610fd72d271803a8fdb019fdb35aff4", - "name": "gFleWbQuBMsXQbKVNrKauVck2_Coin" + "address": "880fdc0115def3c6785b55cf5e39c6da4e70beab2abe6dfe94bace886855ed0a", + "name": "utZ9_Coin" }, - "function": "xUdYxDEXf6", + "function": "tsDtdS", "ty_args": [ { "vector": { - "struct": { - "address": "eb6441ab97fe6403d6ca6c7855b9eceeb5a0ac8753a69b35e9c0d0e94ef1eedb", - "module": "KVjskjiVbBURtdZYBaC", - "name": "AXnnAwGtBcO9", - "type_args": [] + "vector": { + "vector": "u8" } } }, { - "struct": { - "address": "711b00ca198eafd77767390bd4aacc6fe37795c2a43b6631279cc8acd7698eff", - "module": "FSzFbQlCwopeDadro", - "name": "UjEumVPTZPH", - "type_args": [] - } - }, - { - "struct": { - "address": "547216f5ee079c833f055708215caffaca3ebb94bfc9389d84cdac060c5ca199", - "module": "DPjhIDeroUavOW7", - "name": "NLRUAduxVgCQWDyrIDY", - "type_args": [] - } - }, - { - "struct": { - "address": "7e4163ae4a75cafe476002169655ccb2b6a995acabc256bf47381b276545cee5", - "module": "CyHwBpFwYlUXLWyScng5", - "name": "NUbyivi6", - "type_args": [] - } - }, - { - "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "address" - } + "vector": "bool" } ], "args": [ - "84876fd4b8c346d95e94449ba66b52672f963b3b2a286580d451afef11d5f56e" + "01", + "00", + "1bcfc3f7458eae4821db1ac1f8b3965f320ac0785dcb78f88956192aacb45110", + "9d", + "8ba70d3a8204c80f", + "30089ce4a20d4649b75af20256369145" ] } }, - "max_gas_amount": "5014881067796366166", - "gas_unit_price": "10284107719020051992", - "expiration_timestamp_secs": "16343549532649488808", - "chain_id": 162 + "max_gas_amount": "5243357817996892892", + "gas_unit_price": "9444438872369638487", + "expiration_timestamp_secs": "10545651318676919993", + "chain_id": 177 }, - "signed_txn_bcs": "4340105451eb392d3cc037dc812416941c1dc10b913665144b1d6b9d90043379ad7220cbb54af5cc02ee1ad60948498ddbe6a6ebd91d38db29b610fd72d271803a8fdb019fdb35aff41e67466c6557625175424d735851624b564e724b617556636b325f436f696e0a78556459784445586636060607eb6441ab97fe6403d6ca6c7855b9eceeb5a0ac8753a69b35e9c0d0e94ef1eedb134b566a736b6a69566242555274645a594261430c41586e6e4177477442634f390007711b00ca198eafd77767390bd4aacc6fe37795c2a43b6631279cc8acd7698eff1146537a4662516c43776f7065446164726f0b556a45756d5650545a50480007547216f5ee079c833f055708215caffaca3ebb94bfc9389d84cdac060c5ca1990f44506a68494465726f5561764f5737134e4c525541647578566743515744797249445900077e4163ae4a75cafe476002169655ccb2b6a995acabc256bf47381b276545cee5144379487742704677596c55584c577953636e6735084e5562796976693600060605060604012084876fd4b8c346d95e94449ba66b52672f963b3b2a286580d451afef11d5f56e5683d5dcc26f984518fe0aa07b7db88ea8019346b5f3cfe2a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408b81403e240a10c7a9af9716c43ae7264dd723d366c5ed2d076c25be20fe86307f2db7eac3e1a54eb97acd027948738384c4bd55f5eb9bfb24b383fbe5000c01", + "signed_txn_bcs": "f32477ffca61486c2c8ae41b00c4b4791577bb28508f131860045cc1904af61b6f06a9ca963ae98f02880fdc0115def3c6785b55cf5e39c6da4e70beab2abe6dfe94bace886855ed0a0975745a395f436f696e06747344746453020606060106000601010100201bcfc3f7458eae4821db1ac1f8b3965f320ac0785dcb78f88956192aacb45110019d088ba70d3a8204c80f1030089ce4a20d4649b75af20256369145dcdaf8ab2726c44857ac7b9a1d631183b916de4600ae5992b1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a8e5a8b44d347b35a63e17598a5c468ea17647b726ff322efaa63a101588e7825b095ee5ec6c48f511e7b402ce70104609d499ae39ef7db7a8f766da2ed38f05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ae3c899d46331f2f945c62e521a934ced10d2e695c132bd648bdf672ffe66387", - "sequence_number": "9710929933222611683", + "sender": "de431e12633493917b2f39b6911d9dd19a9f8d6f9ada58a13f3613366b06c133", + "sequence_number": "15601851185367795655", "payload": { "EntryFunction": { "module": { - "address": "bc11cfe1bc7c2ce85c3356e392c517e526b36a12c247390bac6df8286b09f865", - "name": "Wrfn8_Coin" + "address": "0b8dadb06febf55b7e7d2ca48c0b8db5eb02538059daf541fd5737d47c950040", + "name": "bAsHTWWsEhPweqGW_Coin" }, - "function": "o1", + "function": "jY6", "ty_args": [ { - "vector": "u64" + "struct": { + "address": "0fda0e682eb4b9e09474614c5548ca79cb57dbcbc50f1fa6bb96094299de677b", + "module": "SGuMFhbudpFsNkbRBB", + "name": "tZz", + "type_args": [] + } }, { "struct": { - "address": "a46a09f87ed9a67ccbd7bb65e3f7860893a411c712feaac50b0d13be8f4b749f", - "module": "jFixKtTUYhAqzzMJUiu3", - "name": "LlwLALHLPoTNfdRuIPqPVreJGv1", + "address": "7228fad5d1a95d36f10dadf82fe38e6fb7a458a2f9741509f7ee579f0196aee9", + "module": "rIrFTrHvBYEZf1", + "name": "rLCrBz3", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": "u8" } } ], "args": [ - "ffc4ab76d50b8322", - "1f7fb8a4deb6ec3a41d3701e455581f4752f77cbe78b98ba07e114a6506e1ec7", - "01", - "01", - "00", - "9af65988d58af4bfd53386d9dc6f29de", - "ed44525fc5125f6470190016e287b1b3", - "02", - "01" + "63036ae1f1800c1e4684b4a41802f968" ] } }, - "max_gas_amount": "10206929233670852440", - "gas_unit_price": "2604431443004056849", - "expiration_timestamp_secs": "16774726504011982482", - "chain_id": 210 + "max_gas_amount": "3335893672433147462", + "gas_unit_price": "4999270595337222181", + "expiration_timestamp_secs": "12225224986382944946", + "chain_id": 233 }, - "signed_txn_bcs": "ae3c899d46331f2f945c62e521a934ced10d2e695c132bd648bdf672ffe66387e30a71d45227c48602bc11cfe1bc7c2ce85c3356e392c517e526b36a12c247390bac6df8286b09f8650a5772666e385f436f696e026f3103060207a46a09f87ed9a67ccbd7bb65e3f7860893a411c712feaac50b0d13be8f4b749f146a4669784b745455596841717a7a4d4a556975331b4c6c774c414c484c506f544e66645275495071505672654a477631000606050908ffc4ab76d50b8322201f7fb8a4deb6ec3a41d3701e455581f4752f77cbe78b98ba07e114a6506e1ec7010101010100109af65988d58af4bfd53386d9dc6f29de10ed44525fc5125f6470190016e287b1b301020101584f80340f4ca68d11651d3a99cc242492e6f60be1cccbe8d2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bb3ada5f9f177b835075fca485b8b01bac3ebae02ee38c10a9084f16b511f13b4ce7e0db3aaeb52a56a5412977bbd203d645705f6f15572f22f16cba9af7340f", + "signed_txn_bcs": "de431e12633493917b2f39b6911d9dd19a9f8d6f9ada58a13f3613366b06c133c7c75aaefde884d8020b8dadb06febf55b7e7d2ca48c0b8db5eb02538059daf541fd5737d47c95004015624173485457577345685077657147575f436f696e036a593603070fda0e682eb4b9e09474614c5548ca79cb57dbcbc50f1fa6bb96094299de677b125347754d46686275647046734e6b6252424203745a7a00077228fad5d1a95d36f10dadf82fe38e6fb7a458a2f9741509f7ee579f0196aee90e72497246547248764259455a663107724c4372427a3300060601011063036ae1f1800c1e4684b4a41802f96846ded9e99e794b2e257821831efa6045b2ca95645ab9a8a9e9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d44e09c5411281e7051beba0f3c7dd78b0a9a19182ccd5160de3834218f7944a6e3cd178c4a48807435d28e9fb1c16e15a5c6d2fdd84cc80911f0f97dda76308", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6024b1bbf11a1aa03b522c3232296af3de35cf4ed6b2922f80081e1c0f86b7de", - "sequence_number": "14934495808590520968", + "sender": "3d95d1c9457ec5dd49d918eefb2b81f7ced6350934f9d492639e4f5ffa4ae1c1", + "sequence_number": "6503306600740168691", "payload": { "EntryFunction": { "module": { - "address": "fd45db7eb37db82a5b48a8411c768ece9346fe0278bd9c6b7403dad7e302aec3", - "name": "xFhyyyaztxczgZGX3_Coin" + "address": "307e1217113f316d147c938f383f3f1073e42fefc7868e33e7d4186ee97574b2", + "name": "PWdkwmpfyeLOIX_Coin" }, - "function": "GzqlWkUKayCzAiwrqSLKz", + "function": "JvJMOXzC7", "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "0a57ab396cc0de20d68c9f913706e04fbe787681e725b7d9b231171f39cf7126", - "module": "fNMd5", - "name": "zn2", - "type_args": [] - } + "struct": { + "address": "a776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f802886dccdadff8e15d", + "module": "UTqQtlITP2", + "name": "TINGysgSGOnSSlk", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "94ebccc34202e857027ce8240ed8a69d3264ec0c2a50cf25cbe7ae74fd07174a", + "module": "hufBYCynMMaHGnXA", + "name": "xQLnWFrSreFBpbjFVBrQpWuWvn", + "type_args": [] } } + }, + { + "struct": { + "address": "35cd526d45d904c862dd607ad8932ef6d0a41def94c9df7f9b4512080d35d056", + "module": "WwkjcZLlEqwRPswaLFtymstIkebiV", + "name": "QUhTOkofhCgPADwjUumOTGlND", + "type_args": [] + } } ], "args": [ - "034224b2e471b0c95d2becaba7dd6ea351e89708e32f0a7832cd0a20270a7c10", - "a7668d0e759010762243bd98a9ff46b1", - "6aaa7289962fe321", - "0853ac94b5fb81387554455e9fc7aae0d9ec923e6f86961c6b3c59f5d13aed6b", - "7b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f164facb8e9d04a", - "646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313898d5b", - "06" + "01", + "baaed5bc2a0606d7a10ec329a4ac82ee", + "4c893f5493828b38a248f1e13ce8c058", + "bf9844ef6244f5ab7dd4877d2b406857", + "0f10dab615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6d", + "41", + "0d7bd2b7c44053ba" ] } }, - "max_gas_amount": "16466216651595651702", - "gas_unit_price": "9183487826657206494", - "expiration_timestamp_secs": "7924879799203201130", - "chain_id": 84 + "max_gas_amount": "16160087449451456012", + "gas_unit_price": "1997283851603316910", + "expiration_timestamp_secs": "1355921652732278076", + "chain_id": 119 }, - "signed_txn_bcs": "6024b1bbf11a1aa03b522c3232296af3de35cf4ed6b2922f80081e1c0f86b7de882299c2cffc41cf02fd45db7eb37db82a5b48a8411c768ece9346fe0278bd9c6b7403dad7e302aec316784668797979617a7478637a675a4758335f436f696e15477a716c576b554b6179437a4169777271534c4b7a010606070a57ab396cc0de20d68c9f913706e04fbe787681e725b7d9b231171f39cf712605664e4d6435037a6e32000720034224b2e471b0c95d2becaba7dd6ea351e89708e32f0a7832cd0a20270a7c1010a7668d0e759010762243bd98a9ff46b1086aaa7289962fe321200853ac94b5fb81387554455e9fc7aae0d9ec923e6f86961c6b3c59f5d13aed6b207b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f164facb8e9d04a20646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313898d5b0106761afb88cdc083e4dee006ab854d727f6a002d8730d4fa6d54002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407b7a5d2173d7f6daec50ec9212fbbf19d2aeb8c7f6c81fbf4a3a29a3f66874df98711d9e3e16f7400b90c7d3539b2de2a2c9c6801840aed3ad691d45fa29200a", + "signed_txn_bcs": "3d95d1c9457ec5dd49d918eefb2b81f7ced6350934f9d492639e4f5ffa4ae1c1f32392bae562405a02307e1217113f316d147c938f383f3f1073e42fefc7868e33e7d4186ee97574b2135057646b776d706679654c4f49585f436f696e094a764a4d4f587a4337030607a776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f802886dccdadff8e15d0a55547151746c495450320f54494e4779736753474f6e53536c6b00060794ebccc34202e857027ce8240ed8a69d3264ec0c2a50cf25cbe7ae74fd07174a10687566425943796e4d4d6148476e58411a78514c6e574672537265464270626a465642725170577557766e000735cd526d45d904c862dd607ad8932ef6d0a41def94c9df7f9b4512080d35d0561d57776b6a635a4c6c45717752507377614c4674796d7374496b6562695619515568544f6b6f66684367504144776a55756d4f54476c4e440007010110baaed5bc2a0606d7a10ec329a4ac82ee104c893f5493828b38a248f1e13ce8c05810bf9844ef6244f5ab7dd4877d2b406857200f10dab615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6d0141080d7bd2b7c44053ba0c66cd5bea2944e0ae9070ba14c7b71b3c355e268f33d11277002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400a9fc69f56b40cc2379f58f198c798614cceac9cb552bd114baa8a7dc0b59f257e0a2ad19a79f58f2a6cca1f88bab0a4eb0ca8e924dbd778a69ec0a6ceb27606", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24743c19992aca92785d0ff92a29bee359fcdc6681238d17788656cbe2525e80", - "sequence_number": "9360365806149000792", + "sender": "cef634d8bd1e06c2aca36e50b05052d97f9a3be27991b231a83040fe4d257c67", + "sequence_number": "14499498641130194886", "payload": { "EntryFunction": { "module": { - "address": "44cfa04f8dac2eb538dc22684ec91f93a89feeeede8e975b8997c5a1acc71a28", - "name": "wPLW_Coin" + "address": "8cdbf1de27df1b9c9eeb80bc3ae40b0478f6686fe1f19d86f52e3965e7e8c3da", + "name": "Bso6_Coin" }, - "function": "txuiIBGAoddfaeavAnuZnkNHUhBp", + "function": "DFqKFqiMaQhcB", "ty_args": [ - { - "vector": { - "vector": { - "vector": "signer" - } - } - }, { "vector": { "struct": { - "address": "5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73a9", - "module": "drwNdFEGxwvNoFtPSvnYbOToKN", - "name": "QrJMmswgUqQRSDdeIUEPsQZ1", + "address": "e5473d49de5ec077531f7a1baa6987e00d776f435008b30ba541f3a763235694", + "module": "lpWYFnMZWKBFeKBpC", + "name": "urjuGkZiGEJXrnqNbvlZSoL", "type_args": [] } } }, - { - "struct": { - "address": "645402a096ae0ea0e67d62f26373cc95a844ecd26a73cd57650d5482460b47bf", - "module": "RKvBCkkcQZofbNpmNVHYseTVITieYEpk5", - "name": "PnffaXRsrmDjmApWf3", - "type_args": [] - } - }, - { - "struct": { - "address": "2df40ad7bedc8c3ea427b8a590e7ec09a773517d0c57d3ebf885d4d11ad803b7", - "module": "Zjv", - "name": "uODsVk7", - "type_args": [] - } - }, { "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "2e3fdcd9164f4dc3da50077107930ebbce55ec691db8d9ac7c8ba1a215ee5be6", - "module": "kyXPsybswKFvutvEcHjEoAhJFk8", - "name": "aOJJTmYDMHyHodowoYtFIdYeIw4", - "type_args": [] + "vector": { + "struct": { + "address": "8620965f6b3f186879a8c041bfaa097cc9f4dfacfdf9942490193f85f5f9f1e2", + "module": "KMnGsDzeDkbmEawefHIOoOFmJJQXb2", + "name": "btUTmWnPQhMJtZgigHVGDTWRmZmpC", + "type_args": [] + } + } } }, { "struct": { - "address": "dcb4823adc5740a858266b2134d8254bc405ccaa6ca9cfdea59a0331985b4c51", - "module": "LSoYhJKgrqGJHscAhBdnsjzcbs", - "name": "PqemYDcPerSycmAynPrMZ9", + "address": "8d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154bdd5e1a1d2a5ad6c", + "module": "RoYytyEy", + "name": "gknVbpT3", "type_args": [] } }, - { - "vector": { - "vector": "u8" - } - }, { "vector": { "struct": { - "address": "c07e6d846e9b6e79b74af6f0d56077f28df2b1dbb237d78be7ee19b92c4e1972", - "module": "txhZgmRHhYQTZC3", - "name": "ePUZCnCT", + "address": "80a61b1ec2e12a6a476e29794cd765fdae2a2f0ca7d0e9fd9bb09dd054ab7c3e", + "module": "YoNiux", + "name": "HfxSLaBbmtddXIDDCvxyq", "type_args": [] } } }, { "struct": { - "address": "327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c", - "module": "KZWDPAiPWDdGl", - "name": "YdOPoyTNckqUKowpeAX7", + "address": "54f53e444cab1a11b09b67d1060abdf0367dbef422c4be37980e5e992dc1acdf", + "module": "HdSG", + "name": "XvVqKRPjnohJfjQyYRXoKqftrRBxNqF", "type_args": [] } } ], "args": [ - "01", - "7dff31bc1e6e8ccb96a2ca92fb6b9d5d02596e7cfd57daf5645bcd100502f2f8", - "b6584c3350f088cc", - "66e3b4ae1160618b", - "2823d7947633bb76c3707cbddf55b25abbfd891a9da2781c7e6f0d1ecaa0344d", "00", - "64", - "29" + "57d3eeaf5649bac478fc990c6c12134e", + "ebe2b76c356c88fe", + "6734a0855b4b0c7d", + "efa79b34a21ad17ecc3fc14228f3aa3e", + "00", + "d66dc7a28f25db0e", + "bb" ] } }, - "max_gas_amount": "10812350595248184786", - "gas_unit_price": "206499380024714730", - "expiration_timestamp_secs": "13130731864468102950", - "chain_id": 178 + "max_gas_amount": "11050409494143445722", + "gas_unit_price": "1934110844654878075", + "expiration_timestamp_secs": "14344789952289861980", + "chain_id": 91 }, - "signed_txn_bcs": "24743c19992aca92785d0ff92a29bee359fcdc6681238d17788656cbe2525e80585e397b1bb3e6810244cfa04f8dac2eb538dc22684ec91f93a89feeeede8e975b8997c5a1acc71a280977504c575f436f696e1c74787569494247416f64646661656176416e755a6e6b4e48556842700a0606060506075686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73a91a6472774e644645477877764e6f46745053766e59624f546f4b4e1851724a4d6d73776755715152534464654955455073515a310007645402a096ae0ea0e67d62f26373cc95a844ecd26a73cd57650d5482460b47bf21524b7642436b6b63515a6f66624e706d4e56485973655456495469655945706b3512506e666661585273726d446a6d417057663300072df40ad7bedc8c3ea427b8a590e7ec09a773517d0c57d3ebf885d4d11ad803b7035a6a7607754f4473566b3700060601072e3fdcd9164f4dc3da50077107930ebbce55ec691db8d9ac7c8ba1a215ee5be61b6b79585073796273774b46767574764563486a456f41684a466b381b614f4a4a546d59444d4879486f646f776f597446496459654977340007dcb4823adc5740a858266b2134d8254bc405ccaa6ca9cfdea59a0331985b4c511a4c536f59684a4b677271474a487363416842646e736a7a636273165071656d5944635065725379636d41796e50724d5a39000606010607c07e6d846e9b6e79b74af6f0d56077f28df2b1dbb237d78be7ee19b92c4e19720f7478685a676d5248685951545a4333086550555a436e43540007327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c0d4b5a574450416950574464476c1459644f506f79544e636b71554b6f77706541583700080101207dff31bc1e6e8ccb96a2ca92fb6b9d5d02596e7cfd57daf5645bcd100502f2f808b6584c3350f088cc0866e3b4ae1160618b202823d7947633bb76c3707cbddf55b25abbfd891a9da2781c7e6f0d1ecaa0344d010001640129d25dc080942f0d96ea25b69017a2dd02261f86a60fbb39b6b2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440afb0da13fc35b1d0b359d10f4caa95c7a823363e0347099a8e258972c54018536da7d9efc03388e60426feb07edc257caba7b4563d30eae1042fdf3c4ae59409", + "signed_txn_bcs": "cef634d8bd1e06c2aca36e50b05052d97f9a3be27991b231a83040fe4d257c67c607d345319138c9028cdbf1de27df1b9c9eeb80bc3ae40b0478f6686fe1f19d86f52e3965e7e8c3da0942736f365f436f696e0d4446714b4671694d6151686342050607e5473d49de5ec077531f7a1baa6987e00d776f435008b30ba541f3a763235694116c705759466e4d5a574b4246654b4270431775726a75476b5a6947454a58726e714e62766c5a536f4c000606078620965f6b3f186879a8c041bfaa097cc9f4dfacfdf9942490193f85f5f9f1e21e4b4d6e4773447a65446b626d456177656648494f6f4f466d4a4a515862321d627455546d576e5051684d4a745a676967485647445457526d5a6d704300078d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154bdd5e1a1d2a5ad6c08526f59797479457908676b6e566270543300060780a61b1ec2e12a6a476e29794cd765fdae2a2f0ca7d0e9fd9bb09dd054ab7c3e06596f4e69757815486678534c6142626d746464584944444376787971000754f53e444cab1a11b09b67d1060abdf0367dbef422c4be37980e5e992dc1acdf04486453471f587656714b52506a6e6f684a666a51795952586f4b716674725242784e7146000801001057d3eeaf5649bac478fc990c6c12134e08ebe2b76c356c88fe086734a0855b4b0c7d10efa79b34a21ad17ecc3fc14228f3aa3e010008d66dc7a28f25db0e01bbda2a0629e3f05a997b7de2db9057d71a5c71d4ab75ee12c75b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf91ddc872090437c48eba52402cbd8e0c265d9fb5193abbf1a81915ae3213ee195ed2aba525b111a6714c905be3778ab5ea10ea981e4ae3acabdb5c319d90b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b", - "sequence_number": "5990529320530598198", + "sender": "3b0707ca80892ecb201a6ec391eb1c567f235fea982fc67d9381c8419717a212", + "sequence_number": "12584222423719844830", "payload": { "EntryFunction": { "module": { - "address": "71d3b2e5fb84df92f2864e0fe41235808d92102bd29d69fbd7b84364e8b37ef9", - "name": "QiayZGoDmVyBAfsQXlsJlGnBlpcCuX7_Coin" + "address": "d8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630348002e", + "name": "jGpIQCYIholgELmXIDxTkmUOk9_Coin" }, - "function": "dyPncMAZUOWgwSSaqtr4", + "function": "EPFOMTkEUmdmLTWDCavDLRWxXvf0", "ty_args": [ + { + "struct": { + "address": "ed842ad4239ddf6a327985076574c398462d47dc5bf0418d1d81db7ad015299e", + "module": "Tz", + "name": "bQ9", + "type_args": [] + } + }, { "vector": { - "vector": { - "struct": { - "address": "ca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e37ac81", - "module": "tmIcXsQ3", - "name": "XloOTg", - "type_args": [] - } + "struct": { + "address": "4ed3dda2b6d709be6c3724087aa17dbd791616ac8d5f6736f47082efcf87d1fe", + "module": "KufuBm2", + "name": "OfkzFvCyxEuDYaUebmmVCzws", + "type_args": [] } } }, { "vector": { "vector": { - "vector": "u128" + "struct": { + "address": "8b71b0c22ef7b0ad0bdd4fe1ab6703821868d7977353916f47983fe1a8e24dd8", + "module": "zcYcctLSkwuNELUC", + "name": "wvsZAzldOSzYWxFzBVjzQA8", + "type_args": [] + } } } }, { "struct": { - "address": "fb2f37d44afd9f37fd5db9dbf9c88e460d3587a30102e6486ebc48a96c067278", - "module": "PvIrPMT", - "name": "TlVnsUGbfNtxq1", + "address": "5c45fd57b0f7d2f709525feef4e0e68b8c5403bf2ff805135bbad93169044809", + "module": "JYLYZLdwFuJpFKklVTMXfmU9", + "name": "QykXZcNOjWyjdk0", "type_args": [] } }, { "struct": { - "address": "a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d2755", - "module": "apNSsfnEbjL", - "name": "wzNgbHKIoYEBWiTWwoQTXAjYuwOkf2", + "address": "82fb517f5914a9841a0ab1f71a5511293263d4a292dfd005cbb716107ac31b95", + "module": "mDdlfLTFCQiQleP", + "name": "hDbJLNkN", "type_args": [] } } @@ -4991,155 +5430,245 @@ "args": [] } }, - "max_gas_amount": "12149949148592631079", - "gas_unit_price": "5755966100836256336", - "expiration_timestamp_secs": "489257404244072347", - "chain_id": 62 + "max_gas_amount": "18120236537945030104", + "gas_unit_price": "8924417157808123988", + "expiration_timestamp_secs": "8391785183681096261", + "chain_id": 143 }, - "signed_txn_bcs": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b36d9c986ada222530271d3b2e5fb84df92f2864e0fe41235808d92102bd29d69fbd7b84364e8b37ef924516961795a476f446d56794241667351586c734a6c476e426c7063437558375f436f696e146479506e634d415a554f5767775353617174723404060607ca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e37ac8108746d49635873513306586c6f4f5467000606060307fb2f37d44afd9f37fd5db9dbf9c88e460d3587a30102e6486ebc48a96c0672780750764972504d540e546c566e73554762664e747871310007a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d27550b61704e5373666e45626a4c1e777a4e6762484b496f59454257695457776f515458416a5975774f6b66320000276deca0604a9da8500a891bac4ce14f9b97b2570431ca063e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401836988b035c5a0f5e0d553257c96d91bfbf3f8e8279e80619b79ff2a254bda51f51b630f91f9f929ed24f836900661542eed10da07416c154dc14ae91dc400a", + "signed_txn_bcs": "3b0707ca80892ecb201a6ec391eb1c567f235fea982fc67d9381c8419717a212de9b53cc9e23a4ae02d8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630348002e1f6a47704951435949686f6c67454c6d58494478546b6d554f6b395f436f696e1c4550464f4d546b45556d646d4c545744436176444c525778587666300507ed842ad4239ddf6a327985076574c398462d47dc5bf0418d1d81db7ad015299e02547a036251390006074ed3dda2b6d709be6c3724087aa17dbd791616ac8d5f6736f47082efcf87d1fe074b756675426d32184f666b7a467643797845754459615565626d6d56437a7773000606078b71b0c22ef7b0ad0bdd4fe1ab6703821868d7977353916f47983fe1a8e24dd8107a63596363744c536b77754e454c5543177776735a417a6c644f537a595778467a42566a7a51413800075c45fd57b0f7d2f709525feef4e0e68b8c5403bf2ff805135bbad93169044809184a594c595a4c647746754a70464b6b6c56544d58666d55390f51796b585a634e4f6a57796a646b30000782fb517f5914a9841a0ab1f71a5511293263d4a292dfd005cbb716107ac31b950f6d44646c664c5446435169516c6550086844624a4c4e6b4e0000d87d444a200378fb54f08d161fe6d97b45aab2b8299c75748f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea13391e30fb64fcf698552550e9987f2084ff492f10db42a6b9780fc15fa58c7dbfebcc4cd42fbc4624ae0bb4fe2da8e39a0ba32108a626e2a4a915094d7701", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6ef0b35a4bdfd6843e769dd46227a1b7525ad29ef25fafb791c9353ecc7afc3c", - "sequence_number": "5144150898799306293", + "sender": "f9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea731f7db22db43", + "sequence_number": "3935367627153526151", "payload": { "EntryFunction": { "module": { - "address": "967286f392e6fceaefc0e5eca020da2208b9f962f60c60fd3d3a42b1b2da699c", - "name": "LTJRLSuXzvseOa_Coin" + "address": "7e124120250c327fed390fe57dc099302e20f167ece61dc55e20570aaf91ae56", + "name": "wEeNVBnGEeVSefxrUqjG0_Coin" }, - "function": "pYirLsUNfLPHVZJILBPBFNtpYvB", + "function": "uFfmokhkdAp3", "ty_args": [ { "struct": { - "address": "2bf8302396a5e774266888be954168eb3e8b7dcd8a99308e303a004097ebb3f4", - "module": "wDCfnzBNjQtQRZCJStNjti9", - "name": "DehRZLIukWTNK2", + "address": "ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a513831fe", + "module": "eIwpP", + "name": "sdQBsprLlIDimrtaWTphO", "type_args": [] } }, { "struct": { - "address": "52bf6e8aad73229c54c5a713878078fc08245339e1b821d85f96c1f8de051967", - "module": "PxYUPOLmVkwd1", - "name": "c", + "address": "c857cfdcbe402808c8bc8a452f380995a16e06fc6d61aae212855065de8740a1", + "module": "PVJxpA7", + "name": "xk", + "type_args": [] + } + }, + { + "struct": { + "address": "7334108412c9b2dcee22dbd26b4e2c700d04f45828fc600ee6dbb41a954ccb03", + "module": "TxY", + "name": "OfGuxCKNKAWjdIsYivzyXVJxjPgKHA", "type_args": [] } }, { "vector": { "struct": { - "address": "6196ad6c46a0bcb427c9748d6ac8fd097d39ec98ae4f0251c9cd6281310917ae", - "module": "bccohAy", - "name": "iNxeXSsjJhexdElxrhdRFdajgl", + "address": "6ed1188441ba150d67b88aca185ccdbdd07dc90556ea7abde1c251b0452939d4", + "module": "QCSHrcRIFVXsb7", + "name": "mJhukJwThvDC", "type_args": [] } } }, { "struct": { - "address": "5591e026da98df7662a1fe2c23efebfaadea9ced59e6b19afb097c22bc63bea5", - "module": "zGSyAvkYBgfWjcBuOvDuLPJs", - "name": "sovELQLMXrqqjFsnbzISALalMtTJc", + "address": "8def064d6b4f036357028625bd4339d4dc5c960d27487fcfa166bc09223764e5", + "module": "XhFkuPVSTDEaFcYSysmDCDwGhaZRKr8", + "name": "HTBKctkabKxrqhYfMZDhJGln7", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + } + ], + "args": [ + "d32f70786e7312f81094731ecd0e10077954afcec2c62866e6a80b79bbded1af", + "5dccae51abb6b799bcd0f53cf43161e1", + "01", + "f8d347f9b7793342", + "9bd7cc3eaa3e9e596be5a4d39bb01f6c5d3960646ed1515d4f3cffabb7b536c3", + "29ae391a93a97d7ddf9e3c0eef40a740", + "6b08330994f2701bce4a7d8b5a65b8ccc98fd71b05d264191e376d29a83d3e34", + "2c25b34c392dc2426c79960364f5b3d499a1e7fc2259e7044f85edf521f817e5", + "7e" + ] + } + }, + "max_gas_amount": "8637265394567282464", + "gas_unit_price": "16343533545087809091", + "expiration_timestamp_secs": "9587767908266062746", + "chain_id": 137 + }, + "signed_txn_bcs": "f9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea731f7db22db4387cd0ea5013c9d36027e124120250c327fed390fe57dc099302e20f167ece61dc55e20570aaf91ae561a7745654e56426e47456556536566787255716a47305f436f696e0c7546666d6f6b686b644170330607ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a513831fe05654977705015736451427370724c6c4944696d727461575470684f0007c857cfdcbe402808c8bc8a452f380995a16e06fc6d61aae212855065de8740a10750564a7870413702786b00077334108412c9b2dcee22dbd26b4e2c700d04f45828fc600ee6dbb41a954ccb03035478591e4f66477578434b4e4b41576a6449735969767a7958564a786a50674b48410006076ed1188441ba150d67b88aca185ccdbdd07dc90556ea7abde1c251b0452939d40e51435348726352494656587362370c6d4a68756b4a77546876444300078def064d6b4f036357028625bd4339d4dc5c960d27487fcfa166bc09223764e51f5868466b75505653544445614663595379736d444344774768615a524b7238194854424b63746b61624b7872716859664d5a44684a476c6e37000606000920d32f70786e7312f81094731ecd0e10077954afcec2c62866e6a80b79bbded1af105dccae51abb6b799bcd0f53cf43161e1010108f8d347f9b7793342209bd7cc3eaa3e9e596be5a4d39bb01f6c5d3960646ed1515d4f3cffabb7b536c31029ae391a93a97d7ddf9e3c0eef40a740206b08330994f2701bce4a7d8b5a65b8ccc98fd71b05d264191e376d29a83d3e34202c25b34c392dc2426c79960364f5b3d499a1e7fc2259e7044f85edf521f817e5017e20fff4391dbbdd7743b6a3e12ae5cfe29ab316491d980e8589002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f86cdb111b01ca37b8da66bd29f76d9a97cb0e14d38ace83b645971fcf21f28b207dec127c6a11340eb8e01e9aa4a4230b194ae92afc12b2110dd638faa7104", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "190edabe73df3005278ea9d2afb38ea6f8f480ab441ee7b1146c07e6c90010b3", + "sequence_number": "4394165734779209286", + "payload": { + "EntryFunction": { + "module": { + "address": "7e9d3c319876a7a4165c8e9ec3dadaa07c0df5be44021a3d72c8ca83e15a4056", + "name": "ByUtvtRIhFMrf9_Coin" + }, + "function": "zfgWDGYtoxrOCDHd", + "ty_args": [ { "vector": { "struct": { - "address": "67e66bacd1bd6498a3640c66d591d099fb550be4a7694239c006c1f57e1b7956", - "module": "yBJHVC", - "name": "OXmVBQxs", + "address": "d41fbaa554fc07ebf675e1bf8e1a56933e70dfcc7107b47b9d1a2046dffe6c4b", + "module": "FkfDxyedQ5", + "name": "Ry1", "type_args": [] } } }, { - "struct": { - "address": "560e5a1a747c100e30f3da7d8260be526096245fa6a3c08f5a2a32198cadff27", - "module": "qThrKuSIcfiIUtYjlET3", - "name": "geQZscETkgc", - "type_args": [] + "vector": { + "vector": "u8" } - }, + } + ], + "args": [ + "7914dd70f88fd869", + "43", + "bd347dccd29caed01d1e6a78f72d0228f5a4efa16c9aa70a5de59b34dd355025", + "cc80110b79c06206891105e83c2b5ca0a3ffe2b1a38b892174b279f6f4ea8715", + "b8b98e038ff73f0f41f7941606eaa869" + ] + } + }, + "max_gas_amount": "8885486341595182023", + "gas_unit_price": "17317823854610856875", + "expiration_timestamp_secs": "15866080410689049502", + "chain_id": 102 + }, + "signed_txn_bcs": "190edabe73df3005278ea9d2afb38ea6f8f480ab441ee7b1146c07e6c90010b34646b5597436fb3c027e9d3c319876a7a4165c8e9ec3dadaa07c0df5be44021a3d72c8ca83e15a405613427955747674524968464d7266395f436f696e107a666757444759746f78724f43444864020607d41fbaa554fc07ebf675e1bf8e1a56933e70dfcc7107b47b9d1a2046dffe6c4b0a466b6644787965645135035279310006060105087914dd70f88fd869014320bd347dccd29caed01d1e6a78f72d0228f5a4efa16c9aa70a5de59b34dd35502520cc80110b79c06206891105e83c2b5ca0a3ffe2b1a38b892174b279f6f4ea871510b8b98e038ff73f0f41f7941606eaa869c7b35d17c0964f7babbbddc00a4555f09e93e74812a42fdc66002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb60e53c46d4fdef69eaa39ad4730ebb4792a2f60caa1e6e207b7e8401e7bddc4e22605258055c46466690fb53a97903d45cf9eb8d5a15c53e7c6b9511142900", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "99fd3eb88be8fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14c", + "sequence_number": "14521371487918958808", + "payload": { + "EntryFunction": { + "module": { + "address": "d3f612afca6b25f7a214c4f1c25754d3d33c70d1266efbdd0b1fb9f2a0af6d56", + "name": "qLRHHyJ_Coin" + }, + "function": "rQwdsiitpswxOXdxNrTKLuYhNOPxbjZU", + "ty_args": [ { "struct": { - "address": "a1c8bf180cfd5eda9d45806efb7c108ed0f2a9ce7d78c1445f3ae45c6b5d995f", - "module": "fnpdoUltgONF0", - "name": "yluFjYemtXLNRtJQXspzQHYsGiqC6", + "address": "c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c295582964c", + "module": "onUqtAo8", + "name": "aRPRGDqagTlcuhQsP", "type_args": [] } }, { "struct": { - "address": "dfdd1f365f49185f446f017679842e14e38f70be2694f9666671533fb24162dd", - "module": "ZcWEgwOHQCuBlTCMxFkEeo0", - "name": "zg", + "address": "7e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e545", + "module": "bRXhTvyCjyvt", + "name": "LlusnjFjr0", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "59925cc9bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a9", - "module": "EWDTjmugQGpZtVNMHQrofYJV1", - "name": "YDyVexWNYBF", - "type_args": [] - } - } - } + "u128" ], "args": [ - "58105313d008f0bb", - "01", - "25", - "01", - "4c60eb34df833da4", - "10d48b9d2339a629fbc52ae094a1ff96" + "00", + "8275e5b86d2fa243362f92bb0250eedd", + "3cf4012c73964da5706ecb42ac8a02bd4b94e0a4fb4eaace9c8ef4452767326f", + "4f", + "7b3855b49100e57b", + "99", + "e52fad792b449d873af69db58ba86f7e", + "02a2095f56f0f16463569b50161b1010" + ] + } + }, + "max_gas_amount": "17879258683857870553", + "gas_unit_price": "2605423656524117849", + "expiration_timestamp_secs": "8802723359040033093", + "chain_id": 213 + }, + "signed_txn_bcs": "99fd3eb88be8fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd828e5446e4686c902d3f612afca6b25f7a214c4f1c25754d3d33c70d1266efbdd0b1fb9f2a0af6d560c714c524848794a5f436f696e207251776473696974707377784f5864784e72544b4c7559684e4f5078626a5a550307c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c295582964c086f6e557174416f3811615250524744716167546c63756851735000077e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e5450c62525868547679436a7976740a4c6c75736e6a466a72300003080100108275e5b86d2fa243362f92bb0250eedd203cf4012c73964da5706ecb42ac8a02bd4b94e0a4fb4eaace9c8ef4452767326f014f087b3855b49100e57b019910e52fad792b449d873af69db58ba86f7e1002a2095f56f0f16463569b50161b1010d99eaa6a0be31ff859f784f00253282445519d97418e297ad5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408e21be47d80617f1b917c4e052971934923ca06c6c8822d38d580f3c3ba800a9017083360de9c90beb96d20235924fe5e2254b5a38ac212c0db5866fe2afea09", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "68d337a0f6277f5d0349d789790d016e79de516c8e4ae6ff9c4cd36950e70a0f", + "sequence_number": "2157332272851327941", + "payload": { + "EntryFunction": { + "module": { + "address": "864a21ae60811a18560aca58de0e829a9ad8fe71be9d2abd8d0330e21c5e5142", + "name": "wMduaLNplNzhrVP2_Coin" + }, + "function": "eWGbDqGiTvfbCoUKHrulmfYJdgZGUyB9", + "ty_args": [], + "args": [ + "00", + "2fda54c850a6a8e4" ] } }, - "max_gas_amount": "7906394760520268964", - "gas_unit_price": "8327544633798890850", - "expiration_timestamp_secs": "2479669273317751503", - "chain_id": 220 + "max_gas_amount": "10380498159669693669", + "gas_unit_price": "8746182619075811418", + "expiration_timestamp_secs": "7313961327173535914", + "chain_id": 22 }, - "signed_txn_bcs": "6ef0b35a4bdfd6843e769dd46227a1b7525ad29ef25fafb791c9353ecc7afc3c3566f0d1fcb1634702967286f392e6fceaefc0e5eca020da2208b9f962f60c60fd3d3a42b1b2da699c134c544a524c5375587a7673654f615f436f696e1b705969724c73554e664c5048565a4a494c425042464e747059764209072bf8302396a5e774266888be954168eb3e8b7dcd8a99308e303a004097ebb3f417774443666e7a424e6a517451525a434a53744e6a7469390e446568525a4c49756b57544e4b32000752bf6e8aad73229c54c5a713878078fc08245339e1b821d85f96c1f8de0519670d50785955504f4c6d566b77643101630006076196ad6c46a0bcb427c9748d6ac8fd097d39ec98ae4f0251c9cd6281310917ae076263636f6841791a694e78655853736a4a68657864456c78726864524664616a676c00075591e026da98df7662a1fe2c23efebfaadea9ced59e6b19afb097c22bc63bea5187a47537941766b59426766576a6342754f7644754c504a731d736f76454c514c4d587271716a46736e627a4953414c616c4d74544a6300060767e66bacd1bd6498a3640c66d591d099fb550be4a7694239c006c1f57e1b79560679424a485643084f586d56425178730007560e5a1a747c100e30f3da7d8260be526096245fa6a3c08f5a2a32198cadff2714715468724b755349636669495574596a6c4554330b6765515a736345546b67630007a1c8bf180cfd5eda9d45806efb7c108ed0f2a9ce7d78c1445f3ae45c6b5d995f0d666e70646f556c74674f4e46301d796c75466a59656d74584c4e52744a515873707a5148597347697143360007dfdd1f365f49185f446f017679842e14e38f70be2694f9666671533fb24162dd175a63574567774f48514375426c54434d78466b45656f30027a6700060759925cc9bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a919455744546a6d75675147705a74564e4d4851726f66594a56310b594479566578574e59424600060858105313d008f0bb010101250101084c60eb34df833da41010d48b9d2339a629fbc52ae094a1ff96a4fcd1122528b96d6215cb24b9619173cf3a8ef4108e6922dc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444025cf42ad15ed3ea6ac061ffbd383bed69b1372958f40627d269b9910eb99c0acf84d8adb9e8cd9a0aed6c527da3e176c74150fc103024488668fc580df7ac30c", + "signed_txn_bcs": "68d337a0f6277f5d0349d789790d016e79de516c8e4ae6ff9c4cd36950e70a0fc51bcaa94562f01d02864a21ae60811a18560aca58de0e829a9ad8fe71be9d2abd8d0330e21c5e514215774d6475614c4e706c4e7a68725650325f436f696e20655747624471476954766662436f554b4872756c6d66594a64675a475579423900020100082fda54c850a6a8e4e54cb5f613f00e905a98b5b6c0ae6079aa881f771369806516002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405eba09c2006fef19fe8237783bb554a632103205ba6b61e7eafaf06da76e83b7ab42dadfa3c4755d8571c6894a5a0aa12709179dd826d160248b8f644ec0350b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "cdae5d36e8b3894d69347f9fb627730171a09ef20fd14bb95d6929e6ebe3558e", - "sequence_number": "4103580044930880649", + "sender": "523f859b49472b872257e9d8692ceb1c361d580936c31632160d2f66ede09bfb", + "sequence_number": "12453521025643580607", "payload": { "EntryFunction": { "module": { - "address": "1a24efa5b9f435261b31a7a0a3f99762d77c77cf1d4361320aec1c86294532f1", - "name": "QiyTVBnAZyPNy9_Coin" + "address": "639707b7e9ca960d81877d36176b04645685d35722e63fec67e772557883a044", + "name": "JppbPUyNONIZSpMDInFHBjp_Coin" }, - "function": "CqEN", + "function": "QsGTuUqCIOZVR", "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "vector": "address" - }, - { - "struct": { - "address": "d15c26076dc690c0973cb96048d23946eac7a6891005d0582efb6d94a3c0f0e4", - "module": "W3", - "name": "CxlqrcBBzGtObmnsFZPYtkD2", - "type_args": [] + "struct": { + "address": "eda0461881555e0ee747b7fc4cb1dedbef42d037b85e8cdc39371f03dd296e3a", + "module": "XTVsFxmIbksDBj", + "name": "gofjIqlnbDn2", + "type_args": [] + } } }, { "vector": { - "vector": { - "vector": "signer" + "struct": { + "address": "70c9a1458c9e888d88b98f4ccc613296fbfd71f452ed36dcf08dae37da8616f4", + "module": "NcbV", + "name": "wgnfvkxvwNvikwtSVeFuQeYcIY", + "type_args": [] } } }, @@ -5147,957 +5676,910 @@ "vector": { "vector": { "struct": { - "address": "382874ffd0e010e11be2b5107d5c0ecaf17817cf5c64a804482ecd2b23945346", - "module": "Ffe2", - "name": "vybGeTPfG", + "address": "2b11e1dd1060724f7c51a22d4a828ae42f101d7cfb769516324357a8a1a6fd91", + "module": "WZcGNKaorwrwJSWW8", + "name": "JNORCelHPWTi6", "type_args": [] } } } }, { - "struct": { - "address": "c52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdda3c93d91ed2b64", - "module": "yofMT", - "name": "pNjcxnwcUiALPZecswUULcK3", - "type_args": [] - } - }, - { - "struct": { - "address": "39e3db494d86811a4a2f5bc3492a993dbe3482ce749f5fd651ac030c65e739b5", - "module": "df", - "name": "kIziLA0", - "type_args": [] - } + "vector": "u64" }, { "vector": { "struct": { - "address": "7d7b59b2ab1604b73d4872432010a7d91e2b62e96328ad825995225ea0ed988e", - "module": "xAGsMso", - "name": "hjxISgSIFlWLGglEZhGKPaFRQ", + "address": "b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff7451", + "module": "abpaSVxoEbYyYGEmEaSiveidFfLcPuW4", + "name": "xHiVgmvfEXqplIXjHxIYsmZHBCy1", "type_args": [] } } - }, - "u64" + } ], + "args": [] + } + }, + "max_gas_amount": "2121712084599913483", + "gas_unit_price": "4205030645980683583", + "expiration_timestamp_secs": "2915328730634002746", + "chain_id": 146 + }, + "signed_txn_bcs": "523f859b49472b872257e9d8692ceb1c361d580936c31632160d2f66ede09bfbbf0c582864cbd3ac02639707b7e9ca960d81877d36176b04645685d35722e63fec67e772557883a0441c4a7070625055794e4f4e495a53704d44496e4648426a705f436f696e0d5173475475557143494f5a5652050607eda0461881555e0ee747b7fc4cb1dedbef42d037b85e8cdc39371f03dd296e3a0e5854567346786d49626b7344426a0c676f666a49716c6e62446e3200060770c9a1458c9e888d88b98f4ccc613296fbfd71f452ed36dcf08dae37da8616f4044e6362561a77676e66766b7876774e76696b77745356654675516559634959000606072b11e1dd1060724f7c51a22d4a828ae42f101d7cfb769516324357a8a1a6fd9111575a63474e4b616f727772774a535757380d4a4e4f5243656c4850575469360006020607b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff745120616270615356786f456259795947456d456153697665696446664c63507557341c78486956676d7666455871706c49586a48784959736d5a484243793100000b3c3b4ee6d5711d3f5d4fe317455b3a3a21eed00854752892002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ee0ef6d18b3faf513e10327f38a4fc377b6486772cd713771179d81171708c6ba76519ca7e6d9515dcd5a0c53a3e1763ed52402aad800ed081a350ce93b6d206", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "ccd1576d8e206739f9e65c823e0f6c49258197632e2e7607039ef09e50147016", + "sequence_number": "10249967804133273924", + "payload": { + "EntryFunction": { + "module": { + "address": "b42e07d4c6750f4296cad0b23f77cd8299b90b1f8c486b3a9c80ace1fa5f902b", + "name": "bBTrPib_Coin" + }, + "function": "CDqOuaaQOEHDAExBukPIvon5", + "ty_args": [], "args": [ - "a1a5437fc6432ffcf074db13006241a2b397f9a25818305cdb53047d7634d1de" + "ba226df75bef7e1eb76461f5f52e730a", + "0691a777c14996a8a2482de376a2b072" ] } }, - "max_gas_amount": "17830332572551937389", - "gas_unit_price": "6240710093775976093", - "expiration_timestamp_secs": "9935782003335331201", - "chain_id": 201 + "max_gas_amount": "8019537092035902677", + "gas_unit_price": "8538650725598733428", + "expiration_timestamp_secs": "13284623303320135806", + "chain_id": 13 }, - "signed_txn_bcs": "cdae5d36e8b3894d69347f9fb627730171a09ef20fd14bb95d6929e6ebe3558e89947c254fd8f238021a24efa5b9f435261b31a7a0a3f99762d77c77cf1d4361320aec1c86294532f1135169795456426e415a79504e79395f436f696e044371454e09060604060407d15c26076dc690c0973cb96048d23946eac7a6891005d0582efb6d94a3c0f0e40257331843786c71726342427a47744f626d6e73465a5059746b44320006060605060607382874ffd0e010e11be2b5107d5c0ecaf17817cf5c64a804482ecd2b239453460446666532097679624765545066470007c52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdda3c93d91ed2b6405796f664d5418704e6a63786e77635569414c505a6563737755554c634b33000739e3db494d86811a4a2f5bc3492a993dbe3482ce749f5fd651ac030c65e739b5026466076b497a694c41300006077d7b59b2ab1604b73d4872432010a7d91e2b62e96328ad825995225ea0ed988e07784147734d736f19686a784953675349466c574c47676c455a68474b506146525100020120a1a5437fc6432ffcf074db13006241a2b397f9a25818305cdb53047d7634d1de6dfd086e011172f79d36b6fdc3749b56817d850a17fde289c9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409bf27d31d188ae544c8b5291b760befe79320e4544f1f91017a8714684c128b8f075bb2384b57831aff2f40a464abb5373d5cbf4ddbe8fd5ca5dd79c856a670f", + "signed_txn_bcs": "ccd1576d8e206739f9e65c823e0f6c49258197632e2e7607039ef09e5014701644f18d4469333f8e02b42e07d4c6750f4296cad0b23f77cd8299b90b1f8c486b3a9c80ace1fa5f902b0c624254725069625f436f696e184344714f756161514f45484441457842756b5049766f6e35000210ba226df75bef7e1eb76461f5f52e730a100691a777c14996a8a2482de376a2b072d57cdef17e1e4b6f74a4716098617f767ee8456982765cb80d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c5ee4e4056ad2fe552cc7da0daf4fb8beac344ba70e5ec07a0c2003f044d20402a82ac6e7045c2e28a5dfc0b5087693803d4903dc635d0996d7dbbfa88993502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b122f0a74", - "sequence_number": "9663237585012466233", + "sender": "1db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce50791e7", + "sequence_number": "5274975001615907895", "payload": { "EntryFunction": { "module": { - "address": "5aa8e1999aa92f0daafbafe7b760749df76265152de201e7863205b1058573a4", - "name": "OCXVISMHODJGaurrHlaEYqK_Coin" + "address": "da7fd350e5d1c6b8640c3713d88c0813fbf84fe750f9b4296b6bdcfbce554a40", + "name": "R0_Coin" }, - "function": "UAPQocoVQxMqWvAa4", + "function": "uvSMN", "ty_args": [ { "struct": { - "address": "68e85884c392b1985372b02b975ec9f68e266c8c4ce0339e085c64247ddad54f", - "module": "wnausFhpytSqD5", - "name": "XeYQTqdrZMXWgHDixhNVsuGUL", + "address": "966ab4d4086ea16f0d19f33e0629741e4095a06103ab799ec7a9074dd3e48c42", + "module": "tCPZgjUUCVvHdIzTxBEgCdkG9", + "name": "gNEudbDqfrI4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "3c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec", - "module": "mfXGN", - "name": "LFktQYHMnOxZTNeitJdla2", - "type_args": [] - } + "struct": { + "address": "e568407cd551802b3069a1424bae127ad752125a5e9e950b365c812c7815aef0", + "module": "tJZwRIYD0", + "name": "HexMkytjYWP", + "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": { + "vector": "signer" + } } }, { "struct": { - "address": "0aae102420453e9d84b40b523b8349ac5df8875f9df918b7d3d6fa60857809bb", - "module": "QGtSoXwdVZsfsVvzy4", - "name": "LgKbSBtCAquMOGyVpmlkMC", + "address": "589cf2731da9ad868d676432a540730a4497afeb17089cf8eb3fcdff92a00de9", + "module": "HLieJDdcrzhDXYmg9", + "name": "PxhbVcQvkwfUowKKSnjv0", "type_args": [] } }, { "struct": { - "address": "769039133e7a971456e0cf7fe30a19164a227fc288043f794feb10b5bb814235", - "module": "aaGWZcPYzBZwVaGC", - "name": "NvmnspnzvrYXBPsRimTHdSAlg", + "address": "371a3930753b26845e87f35acf14539875ef36a40cd9442f827fbbb404cb76ca", + "module": "CLyhVERWalfymVP", + "name": "GfKETzLLuzXcSu2", "type_args": [] } }, { - "struct": { - "address": "130ded7057c932665326f4846bb01477df2a77e1f7ab44ccd684ec1c536f2012", - "module": "bEDjYwhmBdUmLoMXbQER", - "name": "WIHEAbVzehZNqGuwsNLHWDZ", - "type_args": [] + "vector": { + "struct": { + "address": "063c705df504166eb6abe266adba197a436e53fed056a31882ef45a10a3c999b", + "module": "nfHhxMoSqwf5", + "name": "ZurphlzORmvtxYMqKbwmlyJhcdhsSNCx6", + "type_args": [] + } } }, { - "struct": { - "address": "734184284a19ca6af3385961fb8db21142cf5c1e60f4dc67bbe62ba2dfaf56ce", - "module": "BbWcCIVynjK", - "name": "cgDwS", - "type_args": [] + "vector": { + "struct": { + "address": "06c9eff13c2c32fed87bcc60c96d5bd2abff49be533f79b7a7d1dd123131ced1", + "module": "bKUOmRPPiijLjybgEzulhiKtF", + "name": "rqwWFesjS7", + "type_args": [] + } } }, - { - "vector": "u64" - }, { "struct": { - "address": "01fd4e12ec18f511528f7ea2cf6c350e881c0b813587d908c0bdb0d425b2cca0", - "module": "rLCckGCKwCthAAgQhiNjNSHedS", - "name": "NjXqEzwmuxFJdkQesRA", + "address": "ab2f10d4d977010445578648d2e7e30c7e9f7cc58a7be1a1ddd849cd3e1a7aed", + "module": "JlVSdcjzlPNHzaCtpL", + "name": "bYtWNHaN3", "type_args": [] } }, { - "vector": "u8" + "vector": { + "vector": { + "struct": { + "address": "62f72cab10b9e58626ee5228ed3895aa0898bbd5c47991ec3b128156b7db8067", + "module": "OxyOVgbnKPLEaKBJerHqn", + "name": "MTgcaXalnzrCrRXaRzEO", + "type_args": [] + } + } + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "f7c19a15f67a9f70d70795464355a0300ab5989db4ff7995e529a74e24cc3308", + "module": "tZDoyjBbjDeNFzYpeAg2", + "name": "ffNfp", + "type_args": [] + } + } + } } ], "args": [ - "00", - "ad07d50f6c5fab0b70b22c6875a20a97febff6a58faeaad71c5117479e7d2870", - "a5", - "db33adbae3d160ba13681f37667dad0f" + "15", + "c05047be77dc5113", + "9f320a5481395fc1", + "b2bc27176085da2abe23db5129ad8d5a", + "c417a510363a2614", + "e3cfd3817ae33db03bf0593acaa201ea20cf37a81950dbb3c6e4365a2b7a1a13" ] } }, - "max_gas_amount": "16972055748975707876", - "gas_unit_price": "1412612105432416277", - "expiration_timestamp_secs": "9001456888302104920", - "chain_id": 122 + "max_gas_amount": "2426038067790815985", + "gas_unit_price": "261788517794558074", + "expiration_timestamp_secs": "1129844286756052873", + "chain_id": 231 }, - "signed_txn_bcs": "f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b122f0a743922dfb262b71a86025aa8e1999aa92f0daafbafe7b760749df76265152de201e7863205b1058573a41c4f43585649534d484f444a4761757272486c614559714b5f436f696e11554150516f636f5651784d7157764161340a0768e85884c392b1985372b02b975ec9f68e266c8c4ce0339e085c64247ddad54f0e776e6175734668707974537144351958655951547164725a4d58576748446978684e56737547554c0006073c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec056d6658474e164c466b745159484d6e4f785a544e6569744a646c613200060602070aae102420453e9d84b40b523b8349ac5df8875f9df918b7d3d6fa60857809bb12514774536f587764565a73667356767a7934164c674b62534274434171754d4f477956706d6c6b4d430007769039133e7a971456e0cf7fe30a19164a227fc288043f794feb10b5bb81423510616147575a6350597a425a7756614743194e766d6e73706e7a7672595842507352696d54486453416c670007130ded7057c932665326f4846bb01477df2a77e1f7ab44ccd684ec1c536f2012146245446a5977686d4264556d4c6f4d586251455217574948454162567a65685a4e71477577734e4c4857445a0007734184284a19ca6af3385961fb8db21142cf5c1e60f4dc67bbe62ba2dfaf56ce0b42625763434956796e6a4b0563674477530006020701fd4e12ec18f511528f7ea2cf6c350e881c0b813587d908c0bdb0d425b2cca01a724c43636b47434b774374684141675168694e6a4e5348656453134e6a5871457a776d7578464a646b516573524100060104010020ad07d50f6c5fab0b70b22c6875a20a97febff6a58faeaad71c5117479e7d287001a510db33adbae3d160ba13681f37667dad0fe4c6d229c8da88eb1540b7bd399b9a1358713d205999eb7c7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bb28ce9b104c5027f66b3a21dd94a001aa05c5abdc798c7bb036ad5a3acc5028e8da70fe55c176ab45fed1e9cccf3fccec4d610abb27408fdf0b7e99055e2b02", + "signed_txn_bcs": "1db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce50791e737bc61e2d079344902da7fd350e5d1c6b8640c3713d88c0813fbf84fe750f9b4296b6bdcfbce554a400752305f436f696e057576534d4e0a07966ab4d4086ea16f0d19f33e0629741e4095a06103ab799ec7a9074dd3e48c42197443505a676a55554356764864497a547842456743646b47390c674e457564624471667249340007e568407cd551802b3069a1424bae127ad752125a5e9e950b365c812c7815aef009744a5a7752495944300b4865784d6b79746a595750000606060507589cf2731da9ad868d676432a540730a4497afeb17089cf8eb3fcdff92a00de911484c69654a446463727a684458596d67391550786862566351766b7766556f774b4b536e6a76300007371a3930753b26845e87f35acf14539875ef36a40cd9442f827fbbb404cb76ca0f434c796856455257616c66796d56500f47664b45547a4c4c757a5863537532000607063c705df504166eb6abe266adba197a436e53fed056a31882ef45a10a3c999b0c6e664868784d6f5371776635215a757270686c7a4f526d767478594d714b62776d6c794a6863646873534e43783600060706c9eff13c2c32fed87bcc60c96d5bd2abff49be533f79b7a7d1dd123131ced119624b554f6d52505069696a4c6a796267457a756c68694b74460a727177574665736a53370007ab2f10d4d977010445578648d2e7e30c7e9f7cc58a7be1a1ddd849cd3e1a7aed124a6c565364636a7a6c504e487a614374704c09625974574e48614e330006060762f72cab10b9e58626ee5228ed3895aa0898bbd5c47991ec3b128156b7db8067154f78794f5667626e4b504c45614b424a657248716e144d5467636158616c6e7a724372525861527a454f00060607f7c19a15f67a9f70d70795464355a0300ab5989db4ff7995e529a74e24cc330814745a446f796a42626a44654e467a5970654167320566664e66700006011508c05047be77dc5113089f320a5481395fc110b2bc27176085da2abe23db5129ad8d5a08c417a510363a261420e3cfd3817ae33db03bf0593acaa201ea20cf37a81950dbb3c6e4365a2b7a1a13f1223fdac404ab217ab06b19450fa203895f99836403ae0fe7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444008ed8ea53aa1c62d1dfebe61ff5a3d5325968dc267eb3f33c503286a1b83cce6d4900672cfda63d099a4107f001a83daf9ffae010d521e706390225232176803", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "519f286dc93603c580cfe6b065886fc2e3a299b0caef2e3fce04c9456d291b83", - "sequence_number": "13732536632205293064", + "sender": "2262a0894340b635fbd202d48474bffa8fec61e805115640ff5652bda5048392", + "sequence_number": "14174148195835009751", "payload": { "EntryFunction": { "module": { - "address": "ec0f4c6a05a495f803ba31015d46fc6691fc03025c0c87e44c073b300a7833cd", - "name": "EZgUWKPEGoDMHYkzcFpqBuqoMZgzU_Coin" + "address": "f4c550dabc219964c4090d65a0dac9475fb265082bbf007504c4dea4ff1ec8e6", + "name": "XirtbNWnSNWrCEDdHelzzd_Coin" }, - "function": "fVjaxadhHWImGvjTUUpndIkSZEMz", + "function": "iZaFj9", "ty_args": [ { "vector": { - "struct": { - "address": "d62d804f7dd2851925d1b83e05651506b9500df7c0837d4bc694bdf86955da7b", - "module": "HhSAHzDztDSno7", - "name": "jJNUSDSYLPSNvvDnUNdyDHyiGjNz", - "type_args": [] - } - } - }, - { - "struct": { - "address": "a53c2132dab3df013b11b6300d3d17eb7b18555a7871db21a99322bb78de2e6e", - "module": "vkKYZVmFYNTQvMbDhMLLa3", - "name": "HgZgaEaKwTySSCwMiztGhXSkPvopZ3", - "type_args": [] - } - }, - { - "struct": { - "address": "a791cc0423b493ae9b175532fd8a4d87bd178fdafa52c3a49e98ec67ac051c25", - "module": "riEglWV3", - "name": "eqpd", - "type_args": [] - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "2e0fbf7a20fbf7701a7632973da39bd900c3be72c92cf1d5b9a1d00e9ad15bbc", - "module": "tLeOHkxYrr", - "name": "UUNUNUfhfhLdQUVUtnhb", - "type_args": [] - } - } - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "5a68269ba685df6563e15f06cb1875f733bf4008f1a09c6081248ea9886a27fc", - "module": "doeXYSPdEpWkXanDJk9", - "name": "NyTRXl1", - "type_args": [] - } + "struct": { + "address": "47b25f6e6460f7e1aab0a624677ca1fb9676439295395ca823274a90d2725eaf", + "module": "cRyalecyPo", + "name": "ekknxOKVVlQxePzEnfMrEOoFlljJ", + "type_args": [] } } }, { "struct": { - "address": "6246020d735c6ba2eb319a7019daf9b2e48b96e34f33aa796895f39fded5eaba", - "module": "GevtFrTbRgIUEFKILinHmBpGLMoYer3", - "name": "JnTZdjeOnUzhEUbhhTavuVgt", + "address": "38262cb1e4a3bd0005bbf76adc702b6cb9bd9f015bb4307919ddfa7e916aa5d0", + "module": "g4", + "name": "jNr", "type_args": [] } }, { - "vector": { - "struct": { - "address": "fdf4630955c58b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b", - "module": "IpvjRXlCxW", - "name": "LBOSJsiVYu8", - "type_args": [] - } + "struct": { + "address": "1e1cf8d985f461444ac39c6d522649c4dcbca8928665990ddc1b3d3e852e5efa", + "module": "NkjNMINEbaHPPCyaWZiLqvrRuZnYjk6", + "name": "EpwDMcVwSoSuDtIRorxNgfpjcZDXfk", + "type_args": [] } }, { - "struct": { - "address": "b92014919382d8b2676ad41bd7ff43f6ef1af3b5534920a6d35314b0adbc2930", - "module": "rGxcW", - "name": "zfCEoKsVCugKqbJoXhLlWunQmmLiAu1", - "type_args": [] + "vector": { + "vector": "address" } }, { "vector": { "struct": { - "address": "20ddb1daa827ae01f7f7eaf973e98b3c10e6ab3ff28f5a1f8059f96da8e6f489", - "module": "mJEozCRMHAjHjcbfnAaOSMV", - "name": "NRl4", + "address": "029159e7ebf862b94a2965ea422d11818be607577cedbe8f41849cd0957dfcc2", + "module": "sokH", + "name": "dCHbyUfHnsbbAPGzEYGinQKT5", "type_args": [] } } + }, + { + "struct": { + "address": "dc5c6ecbbe5798959c7ccbb327500fa10500a1e7801a62663b6376004c4838dc", + "module": "XcsECDmxndHVrGFkHkKBeATMzcI6", + "name": "yINMBzYSOMVQKlE", + "type_args": [] + } } ], "args": [ - "d8e534c43c1f5acb", - "15", - "00", - "17", - "289047bb0072d88ddde4674eaf7342ec", - "808170f0208f7175", - "82dcf6677f44c368e9563aa63f1d5ff883e7acdbd83dad196ec9b678613830ba", - "67704465b910d0c0125588a27afb58f86ed8e88ec2ec9c3d618fe8e6642ba4df", - "9df68b441485ba3f", - "f267340695a22919" + "18", + "8e17569f378fb87c1305a1f012857023be686b274de2c410ad12be50b5121dca", + "01", + "4d", + "110723d978bb25b4" ] } }, - "max_gas_amount": "4667834604792196443", - "gas_unit_price": "1859594188800543022", - "expiration_timestamp_secs": "12609327417526666413", - "chain_id": 164 + "max_gas_amount": "11654879041958255661", + "gas_unit_price": "10906307489344411750", + "expiration_timestamp_secs": "6526634952143335589", + "chain_id": 243 }, - "signed_txn_bcs": "519f286dc93603c580cfe6b065886fc2e3a299b0caef2e3fce04c9456d291b8308b6a2134fc593be02ec0f4c6a05a495f803ba31015d46fc6691fc03025c0c87e44c073b300a7833cd22455a6755574b5045476f444d48596b7a634670714275716f4d5a677a555f436f696e1c66566a61786164684857496d47766a545555706e64496b535a454d7a090607d62d804f7dd2851925d1b83e05651506b9500df7c0837d4bc694bdf86955da7b0e48685341487a447a7444536e6f371c6a4a4e55534453594c50534e7676446e554e647944487969476a4e7a0007a53c2132dab3df013b11b6300d3d17eb7b18555a7871db21a99322bb78de2e6e16766b4b595a566d46594e5451764d6244684d4c4c61331e48675a676145614b775479535343774d697a74476858536b50766f705a330007a791cc0423b493ae9b175532fd8a4d87bd178fdafa52c3a49e98ec67ac051c2508726945676c5756330465717064000606072e0fbf7a20fbf7701a7632973da39bd900c3be72c92cf1d5b9a1d00e9ad15bbc0a744c654f486b785972721455554e554e55666866684c6451555655746e6862000606075a68269ba685df6563e15f06cb1875f733bf4008f1a09c6081248ea9886a27fc13646f6558595350644570576b58616e444a6b39074e795452586c3100076246020d735c6ba2eb319a7019daf9b2e48b96e34f33aa796895f39fded5eaba1f47657674467254625267495545464b494c696e486d4270474c4d6f59657233184a6e545a646a654f6e557a68455562686854617675566774000607fdf4630955c58b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b0a4970766a52586c4378570b4c424f534a7369565975380007b92014919382d8b2676ad41bd7ff43f6ef1af3b5534920a6d35314b0adbc29300572477863571f7a6643456f4b73564375674b71624a6f58684c6c57756e516d6d4c6941753100060720ddb1daa827ae01f7f7eaf973e98b3c10e6ab3ff28f5a1f8059f96da8e6f489176d4a456f7a43524d48416a486a6362666e41614f534d56044e526c34000a08d8e534c43c1f5acb01150100011710289047bb0072d88ddde4674eaf7342ec08808170f0208f71752082dcf6677f44c368e9563aa63f1d5ff883e7acdbd83dad196ec9b678613830ba2067704465b910d0c0125588a27afb58f86ed8e88ec2ec9c3d618fe8e6642ba4df089df68b441485ba3f08f267340695a229195b2dea80d77ac7402e49d6e90f9bce19ad4445aa7a54fdaea4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ee2f66f9660f6efef622b211dc518149bc2a1efc684f9f81ae896124563b6f29f28096255b7ebdc86be14334e8314c662426b14552ebb05616d698ce33790e0c", + "signed_txn_bcs": "2262a0894340b635fbd202d48474bffa8fec61e805115640ff5652bda5048392d75a7daeafb0b4c402f4c550dabc219964c4090d65a0dac9475fb265082bbf007504c4dea4ff1ec8e61b58697274624e576e534e57724345446448656c7a7a645f436f696e06695a61466a3906060747b25f6e6460f7e1aab0a624677ca1fb9676439295395ca823274a90d2725eaf0a635279616c656379506f1c656b6b6e784f4b56566c517865507a456e664d72454f6f466c6c6a4a000738262cb1e4a3bd0005bbf76adc702b6cb9bd9f015bb4307919ddfa7e916aa5d0026734036a4e7200071e1cf8d985f461444ac39c6d522649c4dcbca8928665990ddc1b3d3e852e5efa1f4e6b6a4e4d494e456261485050437961575a694c71767252755a6e596a6b361e457077444d635677536f5375447449526f72784e6766706a635a4458666b000606040607029159e7ebf862b94a2965ea422d11818be607577cedbe8f41849cd0957dfcc204736f6b481964434862795566486e7362624150477a455947696e514b54350007dc5c6ecbbe5798959c7ccbb327500fa10500a1e7801a62663b6376004c4838dc1c5863734543446d786e6448567247466b486b4b426541544d7a6349360f79494e4d427a59534f4d56514b6c4500050118208e17569f378fb87c1305a1f012857023be686b274de2c410ad12be50b5121dca0101014d08110723d978bb25b42d1c110cbd72bea166588ea1e0fc5a97a5f026cde843935af3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f122d0a4fcd3f72e331d693e8ae913f46f8db682add4bcbaa2ac474f37b72f0b810a39c2866f0e97c77b50bb70d693b1ca63796effa3d81bc83859b7ec78f04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5a49d30d9133f3e16b724f055f042096c569e1d6d30e16d8c5e677ee68f3fa2", - "sequence_number": "15438830636111827449", + "sender": "c9166424e69ff945aa011afbaf8712db99a0e54ec2717afcfe69fb2933e97035", + "sequence_number": "17269409797658351941", "payload": { "EntryFunction": { "module": { - "address": "4e8a0bfc982e4a54a3d64d3757f2d58cca12129ec4b4cb359e860abceac1b013", - "name": "rCbIbtxdlAJZfSUuUNkNC_Coin" + "address": "85b6a3fcf3501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b03", + "name": "coMsCjZRvHHuFLHSbNBmqQmRivSJpIVA3_Coin" }, - "function": "NGaVDk5", + "function": "WJiZuFIjlrJdwDulop4", "ty_args": [ { "struct": { - "address": "bcf6b3d454b77337cff4db962c20a23f3691a28a7e45888d44b254ed63bc28b8", - "module": "HCUIN4", - "name": "GcKp", + "address": "23d56d1b65fd2f9a61b254e03e116ea56ab97e2ae4779d35a7a416c9296bc162", + "module": "oUTpHIXmaBTvBrjZZjEMePnwNzHmy", + "name": "QM6", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "0cfa637d3c772a93a2df9d3557dbbb85bb26c8efe2d15b13b6ba85e1f22f41e2", - "module": "OAgPPRXuwNaVWMrnQp7", - "name": "xISNyKvTaWbbLsmiKdhIahNcHyC2", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "e0df5fb8210ef562af7b0438329efab0b8ef1bd5c39014f0f7d1698584901fbd", - "module": "S", - "name": "XYdoIrEzKruCYzHeIApmsRiR", + "address": "cc71c78506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d7", + "module": "bwyDigskjtAiJfkHW7", + "name": "hFOxFMMgKvXdYivpenOS", "type_args": [] } }, { "struct": { - "address": "42ae20cfdc98ebf5291e30c25b1ca4d87c2e9c8b19583bd80e0e68b57f169962", - "module": "WmXMUyCVhnjgsQypwPjdipPpbGXQlWNa8", - "name": "KKwFhIheFyaZuFwGuoInvydyBep", + "address": "30993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1dfd3dcfa8e", + "module": "IgAAMxlUAZMGKO", + "name": "ypPnDkonZdXLsMjtpeNS2", "type_args": [] } }, { - "struct": { - "address": "2730376d1b27bad9dee8fb8932fd82ead9ed293e7714f464e1f763268105b367", - "module": "XkEkZlQNrKeWG", - "name": "vFKdZbPYzDovaylercjnCiE", - "type_args": [] + "vector": { + "struct": { + "address": "f9b0441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df0101164", + "module": "ezLYgMFXapmOMraM", + "name": "eqI2", + "type_args": [] + } } } ], "args": [ - "cfdc9ada7e53a1891ffdb8f9bda58260", - "906c0539783bd1d300a0d7cc88331488", - "3c8c1dca210cebcc04ba2b53eb08aca793238119a69959201803541061d90ae9", + "d0c60d8c1aa3097d936f40350f5a027010bb387992b0f3db859899f0fa3800af", + "01", + "57a3cd584cc4d551", + "15b80faaa193e1e33c17d7ffe94b64ea", + "9f6a4699db01c1e341077cf659af341d", + "5ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a16e3b66", + "01", "01" ] } }, - "max_gas_amount": "9206564620883451925", - "gas_unit_price": "3700298311803824370", - "expiration_timestamp_secs": "7911132546571793726", - "chain_id": 1 + "max_gas_amount": "12163981542360528951", + "gas_unit_price": "14765093712408029964", + "expiration_timestamp_secs": "11114357721146404348", + "chain_id": 157 + }, + "signed_txn_bcs": "c9166424e69ff945aa011afbaf8712db99a0e54ec2717afcfe69fb2933e97035459913b6b644a9ef0285b6a3fcf3501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0326636f4d73436a5a5276484875464c4853624e426d71516d526976534a70495641335f436f696e13574a695a7546496a6c724a647744756c6f7034040723d56d1b65fd2f9a61b254e03e116ea56ab97e2ae4779d35a7a416c9296bc1621d6f5554704849586d6142547642726a5a5a6a454d65506e774e7a486d7903514d360007cc71c78506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d712627779446967736b6a7441694a666b4857371468464f78464d4d674b76586459697670656e4f53000730993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1dfd3dcfa8e0e496741414d786c55415a4d474b4f157970506e446b6f6e5a64584c734d6a7470654e5332000607f9b0441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df010116410657a4c59674d465861706d4f4d72614d0465714932000820d0c60d8c1aa3097d936f40350f5a027010bb387992b0f3db859899f0fa3800af01010857a3cd584cc4d5511015b80faaa193e1e33c17d7ffe94b64ea109f6a4699db01c1e341077cf659af341d205ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a16e3b660101010137b8cee6c324cfa80c2b6fab8026e8ccfc2d8d0376213e9a9d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444027785b74f5ccba50ebf891f365c2f1335d50bd5db158c72ea097751c07aa6fe3f94692383b70ed5d32ee8b853df6300a2d55c036a757659a184afb85c998b207", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "bb4c0f670be7aa9717e8547036b31e489950632ff2043a7696b92aea3fe5610c", + "sequence_number": "6453282049904902343", + "payload": { + "EntryFunction": { + "module": { + "address": "72850c2d70ec6454e91948351689ca952f0c46fc6739f6adf6cea918b938d5cb", + "name": "obngthmKtrYvT2_Coin" + }, + "function": "hFwbgQpvkYCqC6", + "ty_args": [], + "args": [ + "01", + "01", + "82" + ] + } + }, + "max_gas_amount": "10181911510354079584", + "gas_unit_price": "833200967485478358", + "expiration_timestamp_secs": "10175748302787041689", + "chain_id": 111 }, - "signed_txn_bcs": "d5a49d30d9133f3e16b724f055f042096c569e1d6d30e16d8c5e677ee68f3fa2f911dd44aabe41d6024e8a0bfc982e4a54a3d64d3757f2d58cca12129ec4b4cb359e860abceac1b0131a72436249627478646c414a5a66535575554e6b4e435f436f696e074e476156446b350607bcf6b3d454b77337cff4db962c20a23f3691a28a7e45888d44b254ed63bc28b806484355494e340447634b700006070cfa637d3c772a93a2df9d3557dbbb85bb26c8efe2d15b13b6ba85e1f22f41e2134f41675050525875774e6156574d726e5170371c7849534e794b7654615762624c736d694b64684961684e63487943320006060007e0df5fb8210ef562af7b0438329efab0b8ef1bd5c39014f0f7d1698584901fbd0153185859646f4972457a4b727543597a48654941706d73526952000742ae20cfdc98ebf5291e30c25b1ca4d87c2e9c8b19583bd80e0e68b57f16996221576d584d55794356686e6a677351797077506a6469705070624758516c574e61381b4b4b7746684968654679615a75467747756f496e7679647942657000072730376d1b27bad9dee8fb8932fd82ead9ed293e7714f464e1f763268105b3670d586b456b5a6c514e724b6557471776464b645a6250597a446f7661796c6572636a6e436945000410cfdc9ada7e53a1891ffdb8f9bda5826010906c0539783bd1d300a0d7cc88331488203c8c1dca210cebcc04ba2b53eb08aca793238119a69959201803541061d90ae9010115e06f85be49c47ff2680ba6b5195a333e7571d922fdc96d01002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400c4088eb433e4e0ad75126a9161f6878c51c9e367c9fcb64543c10d227318e1aba5e338a66d6ef4c123476d014a9caca1bd3a9527267e1021440717f769b2802", + "signed_txn_bcs": "bb4c0f670be7aa9717e8547036b31e489950632ff2043a7696b92aea3fe5610cc780fc5bd5a98e590272850c2d70ec6454e91948351689ca952f0c46fc6739f6adf6cea918b938d5cb136f626e6774686d4b7472597654325f436f696e0e68467762675170766b5943714336000301010101018260af1d95926a4d8dd6d57b8ddd1f900b99d967ff2a85378d6f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c26261e0146341b5b7ba198cee21d3ea928f28ab5f83b06d59090ea0e506b679465e2155fd99ef5753181b21693d562368042bcd3e86021e6aaa5e56d1a0e601", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bd4c462ed728b02c397d164233843798c5642043aa172a22e767b5be9e6653fd", - "sequence_number": "11845293532130120585", + "sender": "118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932ef", + "sequence_number": "11566724955845481078", "payload": { "EntryFunction": { "module": { - "address": "6176ed9dcfb921a3216cf549ac74529efdbd7c1b8099c1fd115772b85d0beed4", - "name": "JFImCdAwzEuiw8_Coin" + "address": "8cefec8c2965bf886c57b4c8da4940f36c4fbc1b3da1dcc6fecf0762d1b4d5c9", + "name": "vgSkXRCfmzihhjpiaHmgyspYwObo2_Coin" }, - "function": "VBVjevXdaELQaSSU", + "function": "KrUdcAPssHEWqRTBja2", "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "4cf37dd5915368719924f2fee04f0539db16fd30992e6b200dde8be52621e382", - "module": "SUqpXvVKyvkKTt2", - "name": "MOAKQjzPvhWsgWG", - "type_args": [] + "struct": { + "address": "a3b25c3d1173d9e338537d2fcffb131ac9c7d01eadb657cd4fc84f489248d879", + "module": "UrgLXAsRxjhBZDnfhmYabMJt3", + "name": "Ujj", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "5ba469c77457646b0646105582c80c1ca908afd8bf45597300fd2975ca17aa80", - "module": "ZInMTnhpVJQclqYqtkte5", - "name": "agMfiaqrcYrFNa", + "address": "01fa5e8bda469e1e1b5459bcd7af60c03aedac73929857cdd2e843f10245a619", + "module": "NnrbHbVXMt", + "name": "JgPNnVW6", "type_args": [] } } }, { "struct": { - "address": "2b3914d54f345bec8bb0ba0f841778d46d46bad3c7dfa5e4788ff8b19aac3e43", - "module": "bcXDbitZAsEpIgxzCRzuGV", - "name": "rVsQtBdUEDeXHYWVsKfIvPknQBmY4", - "type_args": [] - } - }, - { - "struct": { - "address": "f7965365269b4fad14d50d707e74a101dde1ec7310ec2e6d96ca4ede2b87e19d", - "module": "olZJI0", - "name": "cSkMdVpyohjR0", + "address": "eab93ef6a3f3ef9113c746506966f342e97b3b4eda6e8eefbdfa3ee1c11073c7", + "module": "nrwfnRftigR5", + "name": "AFsAEbCuODmNbQScczArET", "type_args": [] } } ], "args": [ - "64d13c8d2327ae6d8cce0f34a3778bf665a9627f3a3c6a753960e3b5e870fd52", - "7acfe5726e00dd78", - "6c", - "00", - "fb97ed3d15b3168a38db3119dcf2562b", - "b5ce551b4a3d09f629aa1b76fb0cfc4cc3126d18cf91b201e9fd45825d7b3801", - "0f18bb333f2864e5c2fb98ba0c52dfb7", - "9dc7a5291da914adf78a6f24596a6278", - "36c0815c0db1db6d0677bfcff2a430a2", - "e47eb96fb16954100ab67094988214eb" + "6d8fa83b826231b2a44173b7cdf0c57f", + "00" ] } }, - "max_gas_amount": "4985178632606946101", - "gas_unit_price": "13246191027765076139", - "expiration_timestamp_secs": "7949440090373165906", - "chain_id": 76 + "max_gas_amount": "7303608381061446115", + "gas_unit_price": "13274416015632612760", + "expiration_timestamp_secs": "12986023075089194371", + "chain_id": 204 }, - "signed_txn_bcs": "bd4c462ed728b02c397d164233843798c5642043aa172a22e767b5be9e6653fd8913d95ab5ef62a4026176ed9dcfb921a3216cf549ac74529efdbd7c1b8099c1fd115772b85d0beed4134a46496d436441777a45756977385f436f696e105642566a6576586461454c516153535506060604060601074cf37dd5915368719924f2fee04f0539db16fd30992e6b200dde8be52621e3820f535571705876564b79766b4b5474320f4d4f414b516a7a50766857736757470006075ba469c77457646b0646105582c80c1ca908afd8bf45597300fd2975ca17aa80155a496e4d546e6870564a51636c715971746b7465350e61674d6669617172635972464e6100072b3914d54f345bec8bb0ba0f841778d46d46bad3c7dfa5e4788ff8b19aac3e4316626358446269745a417345704967787a43527a7547561d72567351744264554544655848595756734b664976506b6e51426d59340007f7965365269b4fad14d50d707e74a101dde1ec7310ec2e6d96ca4ede2b87e19d066f6c5a4a49300d63536b4d645670796f686a5230000a2064d13c8d2327ae6d8cce0f34a3778bf665a9627f3a3c6a753960e3b5e870fd52087acfe5726e00dd78016c010010fb97ed3d15b3168a38db3119dcf2562b20b5ce551b4a3d09f629aa1b76fb0cfc4cc3126d18cf91b201e9fd45825d7b3801100f18bb333f2864e5c2fb98ba0c52dfb7109dc7a5291da914adf78a6f24596a62781036c0815c0db1db6d0677bfcff2a430a210e47eb96fb16954100ab67094988214eb359367c28de92e45ab60e7f48eecd3b75213f1eda415526e4c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409dc65aff0ed00d8a868f8662ca4f63edbafc359c1586d5b4341db2de96ff181939d96fabb1ec46d21f0abcbd4aff7bc25ebc3d49ab6c185643d6c80f06e0cc02", + "signed_txn_bcs": "118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932ef76d2d06f104385a0028cefec8c2965bf886c57b4c8da4940f36c4fbc1b3da1dcc6fecf0762d1b4d5c9227667536b585243666d7a6968686a706961486d6779737059774f626f325f436f696e134b7255646341507373484557715254426a6132030607a3b25c3d1173d9e338537d2fcffb131ac9c7d01eadb657cd4fc84f489248d879195572674c58417352786a68425a446e66686d5961624d4a743303556a6a00060701fa5e8bda469e1e1b5459bcd7af60c03aedac73929857cdd2e843f10245a6190a4e6e7262486256584d74084a67504e6e5657360007eab93ef6a3f3ef9113c746506966f342e97b3b4eda6e8eefbdfa3ee1c11073c70c6e7277666e526674696752351641467341456243754f446d4e62515363637a417245540002106d8fa83b826231b2a44173b7cdf0c57f0100e3b9bb5b20a15b6598bd890c093338b8839db7132f9f37b4cc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404a3718994880432cb46bdaba6310d5f7d866da4757c7920d746bc3a92c4909817be06f4d92594034cbd8b2d4ea24f21cfe4dcec7a0d5a67c1deac1fefd1b5d0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24555927c73a0a938a8f4cec3996dceaf37924383bb237e7184a05386b07d352", - "sequence_number": "1376807367105215343", + "sender": "08cca3e6831835945878db45288c595dc9a6b6f3be8ffd071e51bb85a47c6a68", + "sequence_number": "9127392870752029956", "payload": { "EntryFunction": { "module": { - "address": "b41b6572b3350c3b8a007d657090ea490d82026ff2203fb44a373fc11f6d13e6", - "name": "j_Coin" + "address": "d9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62e96f5761", + "name": "WZy2_Coin" }, - "function": "yo", + "function": "QzHWIyoJkf6", "ty_args": [ { "vector": { - "struct": { - "address": "cfebdf04927aecd6ecd33041d251a5f132dbc37be6877dff1e9c23df19ad314f", - "module": "AhyhZiERYDyuTXLrKEHnyoBSdAMLfb9", - "name": "KzNUmtiPgsCm", - "type_args": [] + "vector": { + "vector": "u64" } } }, { "struct": { - "address": "432b868bac0617b6687558fe781309beb91e47fe9e8ef7ab455451744d5919d5", - "module": "FWqENxaVECJkHyMaSgdeMkvZhTVDZ9", - "name": "dewqdKBElMfygZsLmMlyM", + "address": "05508a1b2b055007b8046d9c26ab1622d6c2262a75a90d2573a9f43bda3673b5", + "module": "oUgDQmERiuYejDQsaW", + "name": "xS6", "type_args": [] } }, { "struct": { - "address": "f4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9eb590bd6cbb3e9b", - "module": "FSjOBmHJTLmiJynMPKMIE8", - "name": "NuIZ", + "address": "24930ae8450ca8947271623ba78ae9a1c6a5172e91763c8f8b498c9db9d0c6d4", + "module": "rIYjlbcBdAdzV", + "name": "CwCHeCHLhaCGdVctjqXtNdG6", "type_args": [] } }, { "struct": { - "address": "f1f90c0a41d4291c897f3deb0e033ec5e0e1b51a5f1cf7ac53cd96a88182f71b", - "module": "KMfjNsHrNQFRUdBzPuYQciByQ", - "name": "WYFdAJRmkfRcxnCieudysCVXPYr", + "address": "089756c2fce6c14214bd45a1baabf27a37371b581b9d9ddce2f507a18d763823", + "module": "FkEgkuuPOmqvyfdtBKOABsM8", + "name": "SqtTWYZxkA2", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "608a4f1c81926883c2d7dd63ef54523c6ef8f491199180306283bee9138b15bf", - "module": "EXhY", - "name": "ApAnxKdDrmRWnyoHB8", - "type_args": [] - } - } - }, { "struct": { - "address": "8dec53d3fee8411cb86e4a0b348237fad194cae841b78fcba8e607bfe6302641", - "module": "GNydsmDLb", - "name": "yBJIGqgfYqIvmEKBbA4", + "address": "b0c1f657727e59851c46de3479d91297f0da683bb92dc04103a8b83618ac5fd7", + "module": "NdgBVfiRbuvXgqZSaqilhGGKGbkQVDa", + "name": "I", "type_args": [] } }, { "struct": { - "address": "8123b47f7ab0af9d7dac568c3795b89a8bd567893e348bb79e46e89e8edad85c", - "module": "WbqKDdsBalNeRIGGYYYOsBMARZMNNR", - "name": "eT", + "address": "ec9ce14166e2417c771c2911a39ef6e47be80590a4fcdab20635abfb1aff87eb", + "module": "PVritKDrnrrmrVuygh9", + "name": "ytwNfh5", "type_args": [] } }, { "struct": { - "address": "7a62255139eb85adf10f17099ed3d490a69afd188f8b28acfd50c60e67621fde", - "module": "WNynIJlQicFxIgTvJrrsi3", - "name": "XTRArdOhwYSnHDQhQjdnSFEjxS", + "address": "05c1a925c96b8713b4dbe84fac37c2c2b4b6370c8ee701a7f78a505b342c272f", + "module": "OesyQmFPSJTXETJLQpmIHZQg4", + "name": "nonfafRDa2", "type_args": [] } }, { "vector": { - "struct": { - "address": "dd6601a51a6b4e8fbe283d28947d2614031b4ca46494fc7f7992dfbae28141d5", - "module": "egUPEuIRGIMVTKRHLwOFiss1", - "name": "JDWwPpIyFdSonZ", - "type_args": [] + "vector": { + "struct": { + "address": "74a7c8c96a1fe405fbffd17cbaef897889b1d8b1fffffbe7cc001c3f3963ca8a", + "module": "JeSFmhGRudQNvXxdXuKnRmZsa", + "name": "oBQ6", + "type_args": [] + } } } }, { "vector": { - "vector": "u128" + "struct": { + "address": "e2b4fe5eff9cb2ddcd11a49e71d4f43b769bad87e095d855fb8f5911bd3786c7", + "module": "musMSLeICJVjEWEMNiYTeascZZm", + "name": "BsXSYdxDtShyVxOwp7", + "type_args": [] + } } } ], "args": [ - "b4b3b2c77e005ea95e85b0e7556aa132947b1cca6fee05596ee19f218b00cb32", - "89", - "a7f9495a34070bd3d48cb3047d45a357", "00", - "28e7baf5519e67472880af3d61ef8bf05dc568ae47eacd72198aa744555e3d1b", - "f9490db31b8e6f8d3590d8e97fad1466e798b1286e2ce3d0833def2c920a4c61", - "474c050ecf230611deec92b5a5201574", - "7e", - "01" + "f8d9cf68fa0f4875" ] } }, - "max_gas_amount": "1343955921040667317", - "gas_unit_price": "1554507090856542603", - "expiration_timestamp_secs": "1938967014672769545", - "chain_id": 65 + "max_gas_amount": "1496721602515314109", + "gas_unit_price": "5861327224961934685", + "expiration_timestamp_secs": "8536129913379145190", + "chain_id": 198 }, - "signed_txn_bcs": "24555927c73a0a938a8f4cec3996dceaf37924383bb237e7184a05386b07d3526f7b727801671b1302b41b6572b3350c3b8a007d657090ea490d82026ff2203fb44a373fc11f6d13e6066a5f436f696e02796f0a0607cfebdf04927aecd6ecd33041d251a5f132dbc37be6877dff1e9c23df19ad314f1f416879685a6945525944797554584c724b45486e796f425364414d4c6662390c4b7a4e556d7469506773436d0007432b868bac0617b6687558fe781309beb91e47fe9e8ef7ab455451744d5919d51e465771454e78615645434a6b48794d61536764654d6b765a685456445a391564657771644b42456c4d6679675a734c6d4d6c794d0007f4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9eb590bd6cbb3e9b1646536a4f426d484a544c6d694a796e4d504b4d494538044e75495a0007f1f90c0a41d4291c897f3deb0e033ec5e0e1b51a5f1cf7ac53cd96a88182f71b194b4d666a4e7348724e5146525564427a5075595163694279511b57594664414a526d6b665263786e43696575647973435658505972000607608a4f1c81926883c2d7dd63ef54523c6ef8f491199180306283bee9138b15bf0445586859124170416e784b6444726d52576e796f48423800078dec53d3fee8411cb86e4a0b348237fad194cae841b78fcba8e607bfe630264109474e7964736d444c621379424a4947716766597149766d454b4262413400078123b47f7ab0af9d7dac568c3795b89a8bd567893e348bb79e46e89e8edad85c1e5762714b44647342616c4e65524947475959594f73424d41525a4d4e4e5202655400077a62255139eb85adf10f17099ed3d490a69afd188f8b28acfd50c60e67621fde16574e796e494a6c5169634678496754764a72727369331a5854524172644f687759536e48445168516a646e5346456a7853000607dd6601a51a6b4e8fbe283d28947d2614031b4ca46494fc7f7992dfbae28141d518656755504575495247494d56544b52484c774f46697373310e4a445777507049794664536f6e5a000606030920b4b3b2c77e005ea95e85b0e7556aa132947b1cca6fee05596ee19f218b00cb32018910a7f9495a34070bd3d48cb3047d45a35701002028e7baf5519e67472880af3d61ef8bf05dc568ae47eacd72198aa744555e3d1b20f9490db31b8e6f8d3590d8e97fad1466e798b1286e2ce3d0833def2c920a4c6110474c050ecf230611deec92b5a5201574017e0101b5726923cab0a6128b815487f6b792150922c50c3a98e81a41002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404f86d71f451392ef54e1f9e316394695d16fb75c855ff6d77047fcee070fe95b723900bfab8b3494a9d609e917afdd4efa01f2a769a10bee834ce25eaad1c308", + "signed_txn_bcs": "08cca3e6831835945878db45288c595dc9a6b6f3be8ffd071e51bb85a47c6a68048d9bfa7403ab7e02d9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62e96f576109575a79325f436f696e0b517a485749796f4a6b663609060606020705508a1b2b055007b8046d9c26ab1622d6c2262a75a90d2573a9f43bda3673b5126f556744516d4552697559656a445173615703785336000724930ae8450ca8947271623ba78ae9a1c6a5172e91763c8f8b498c9db9d0c6d40d7249596a6c6263426441647a5618437743486543484c68614347645663746a7158744e6447360007089756c2fce6c14214bd45a1baabf27a37371b581b9d9ddce2f507a18d76382318466b45676b7575504f6d717679666474424b4f4142734d380b5371745457595a786b41320007b0c1f657727e59851c46de3479d91297f0da683bb92dc04103a8b83618ac5fd71f4e646742566669526275765867715a536171696c6847474b47626b5156446101490007ec9ce14166e2417c771c2911a39ef6e47be80590a4fcdab20635abfb1aff87eb1350567269744b44726e72726d72567579676839077974774e666835000705c1a925c96b8713b4dbe84fac37c2c2b4b6370c8ee701a7f78a505b342c272f194f657379516d4650534a545845544a4c51706d49485a5167340a6e6f6e666166524461320006060774a7c8c96a1fe405fbffd17cbaef897889b1d8b1fffffbe7cc001c3f3963ca8a194a6553466d6847527564514e7658786458754b6e526d5a7361046f425136000607e2b4fe5eff9cb2ddcd11a49e71d4f43b769bad87e095d855fb8f5911bd3786c71b6d75734d534c6549434a566a4557454d4e695954656173635a5a6d1242735853596478447453687956784f7770370002010008f8d9cf68fa0f4875bd2594155e6cc5145da52e740e9e5751e6c58c0bee6c7676c6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a301a5fb7ec09136dd3479ad039cbacfa810c59c8582dda28bd3d2464d9ffaf9dde2b5226d5b15f2e17b2990de8f291bdecbf0c07d56db6497459c2afe86020b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "42ed563cf7d8de375ab586013640e5ec0c556d2d901a703ad2dc84f6ef4306a9", - "sequence_number": "13308712221981273264", + "sender": "40d15ef04d926a127deb574aef4fa645c3a72f6f3b81c1fc987b1b70f90fa656", + "sequence_number": "17577631904513889653", "payload": { "EntryFunction": { "module": { - "address": "f548740496df955a20f1d7e1a216a858db24737175b0f1b966a6b23840e97044", - "name": "DAqaGyIZkLwONvVhcdWUodLYAmLRKGZf5_Coin" + "address": "7d1e1a28e905fe4c3f616c013016eca4e0b80ae5832b79a25541f5a550919723", + "name": "MLCuaCwZLQqi_Coin" }, - "function": "unAjqbqse", + "function": "DLbAKcFApENdmqBvfxzdYpsvznl5", "ty_args": [ { "vector": { - "vector": "u128" + "vector": "address" + } + }, + { + "struct": { + "address": "882dadcf627059770fe01bad69a122506a3c77de79dc8480b7c4d4d5711d4730", + "module": "FIrBucmzVUJrosyyTmc", + "name": "CCNRndPJwwKiPJnStENMjMtPLuHf", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "0b810face7fd3b08bcf9128fe96dbd30486ccc2090d7c60ce089c7ce712ef91a", + "module": "WxxzPKQrBqtqKJ2", + "name": "EQlyLdxtm", + "type_args": [] + } + } + } + }, + { + "struct": { + "address": "538036f6e2871d6cb2619c25994129a0506cd6ca11b28753879c0835f6000458", + "module": "tXbybiJRaMcugptutiGFlc", + "name": "tCgblAn3", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "80dfb5ae095d2c2801cc39b0a3b6ad344b3307aa227be2756076d698e9264ee5", + "module": "akrpvghtwbvNchgTjblwaROBT4", + "name": "eRiaUSNBwPRCYZ3", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "4f848a5c37546b64a16d2b31e2ea80c206c941aeea0d35275c91bbc8e65933b4", - "module": "iTejDUHpj3", - "name": "nFyszxxawlGFJSBjGHrtjnXwvxqmHg0", + "address": "654dbd4d23f6e407159b3a6d9115d32f95215621c51ee2528ee9293624743db1", + "module": "jJ", + "name": "vsEHXeYqAQUolBOEkdVYngOomETyNji", "type_args": [] } } } ], "args": [ - "26cfa2bc3482e92dffbe03fb0ea18f03", - "0fc86437a60e433358b084c97fedaf8a", - "00" + "01", + "3062ec6e489bbbc2054964af945497ac" ] } }, - "max_gas_amount": "12695207949733120140", - "gas_unit_price": "15749846802159546298", - "expiration_timestamp_secs": "8716299144477001698", - "chain_id": 70 + "max_gas_amount": "5897866893466189851", + "gas_unit_price": "10500791076102577215", + "expiration_timestamp_secs": "11816105298633330157", + "chain_id": 8 }, - "signed_txn_bcs": "42ed563cf7d8de375ab586013640e5ec0c556d2d901a703ad2dc84f6ef4306a9b0ec17d9400bb2b802f548740496df955a20f1d7e1a216a858db24737175b0f1b966a6b23840e9704426444171614779495a6b4c774f4e765668636457556f644c59416d4c524b475a66355f436f696e09756e416a71627173650206060306074f848a5c37546b64a16d2b31e2ea80c206c941aeea0d35275c91bbc8e65933b40a6954656a445548706a331f6e4679737a787861776c47464a53426a474872746a6e58777678716d48673000031026cfa2bc3482e92dffbe03fb0ea18f03100fc86437a60e433358b084c97fedaf8a01008cc88e415e702eb0baaf8a6538b292dae2c79716e483f67846002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f5fef41fabcdbd9e0d91eba828f3730a43fb3d44e037d24c24d23fdac49472247ddadd2e6c74550adf19f81cc3853d587cd702f70352ac0ca47387e37314880b", + "signed_txn_bcs": "40d15ef04d926a127deb574aef4fa645c3a72f6f3b81c1fc987b1b70f90fa65675951f3d164bf0f3027d1e1a28e905fe4c3f616c013016eca4e0b80ae5832b79a25541f5a550919723114d4c43756143775a4c5171695f436f696e1c444c62414b63464170454e646d71427666787a64597073767a6e6c350606060407882dadcf627059770fe01bad69a122506a3c77de79dc8480b7c4d4d5711d4730134649724275636d7a56554a726f737979546d631c43434e526e64504a77774b69504a6e5374454e4d6a4d74504c754866000606070b810face7fd3b08bcf9128fe96dbd30486ccc2090d7c60ce089c7ce712ef91a0f5778787a504b5172427174714b4a320945516c794c6478746d0007538036f6e2871d6cb2619c25994129a0506cd6ca11b28753879c0835f6000458167458627962694a52614d637567707475746947466c6308744367626c416e330006060780dfb5ae095d2c2801cc39b0a3b6ad344b3307aa227be2756076d698e9264ee51a616b7270766768747762764e636867546a626c7761524f4254340f6552696155534e4277505243595a33000607654dbd4d23f6e407159b3a6d9115d32f95215621c51ee2528ee9293624743db1026a4a1f76734548586559714151556f6c424f456b6456596e674f6f6d4554794e6a6900020101103062ec6e489bbbc2054964af945497ac1bc096fdb06ed9513f9caf1fd94dba91ed8da6292a3dfba308002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440385c5e212c8ad6c9bd3d1e4311b8d31222904e95d133e6e7f7fd68d12c0fdc991e31b83f085ae82b73a5776ea717894424a21b31da329f4018c947f6cab6e406", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d2bc24b0f019b2b82ebb1f9fb92617526626952d1ac2472ba1aaa4491b323cb3", - "sequence_number": "4211736428245228250", + "sender": "b13d2e3db8e0541f8b85e84d797ae2c18d09a04af48835393ac2bd78c12290c2", + "sequence_number": "10873594142851988359", "payload": { "EntryFunction": { "module": { - "address": "2b3e987c6c6a4c9674d36208082c1cd1c0b056a2a2a6b9ee9c2737895cd3a895", - "name": "MNmbLHAVwlbneu3_Coin" + "address": "ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedbb24a7d46240705d2b9", + "name": "pAfneD3_Coin" }, - "function": "LZZhGMzzFoSrxftt8", - "ty_args": [ - { - "vector": { - "struct": { - "address": "9eb96b3824bcce2dab78f474c257cf886f128025433a702d6950f21325483c82", - "module": "XpADI", - "name": "gOlzjUtqJc", - "type_args": [] - } - } - } - ], + "function": "BkKTlZIHsXlwcpfuFQ", + "ty_args": [], "args": [ - "27df94f48ef84a958734d707dac0b875", - "e2690de2bb8285a5", - "55", - "00", - "c3a9edea62dedd56e1e9b2aa7fc3b25bc96e4b7e3af938e19ae9740aa4366705", - "00", - "01", - "30" + "0a", + "d01bc3d91d958a0b130fd14d32ff300e95d8bf535000de174f1dcc6dc183f781", + "89be9a9d1d81d486", + "e0c3ab969e0d6306d26edbe527a704f4ef29f2dbb0300dd805f5d2bbb1705f6a", + "6e12d5d340f2c7c20fa14df2c8fc04f4", + "09" ] } }, - "max_gas_amount": "15188451962748323527", - "gas_unit_price": "1643726718602092844", - "expiration_timestamp_secs": "331084826812339556", - "chain_id": 94 + "max_gas_amount": "14741512601017041932", + "gas_unit_price": "16679536404755377091", + "expiration_timestamp_secs": "7373462436341996817", + "chain_id": 67 }, - "signed_txn_bcs": "d2bc24b0f019b2b82ebb1f9fb92617526626952d1ac2472ba1aaa4491b323cb3da1a217df717733a022b3e987c6c6a4c9674d36208082c1cd1c0b056a2a2a6b9ee9c2737895cd3a895144d4e6d624c484156776c626e6575335f436f696e114c5a5a68474d7a7a466f537278667474380106079eb96b3824bcce2dab78f474c257cf886f128025433a702d6950f21325483c820558704144490a674f6c7a6a5574714a6300081027df94f48ef84a958734d707dac0b87508e2690de2bb8285a50155010020c3a9edea62dedd56e1e9b2aa7fc3b25bc96e4b7e3af938e19ae9740aa4366705010001010130c7c6b2979638c8d22ca118e2bdb0cf1664d5ab54e53f98045e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444091e51e51711745361a083c22d6c3b4e23ada0481cf711b9a4471a14ed70af742d7a0478a05a14078118a9a137b2e72d18f817f7ad476c164880b5f970e226506", + "signed_txn_bcs": "b13d2e3db8e0541f8b85e84d797ae2c18d09a04af48835393ac2bd78c12290c287fb751c43c4e69602ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedbb24a7d46240705d2b90c7041666e6544335f436f696e12426b4b546c5a494873586c776370667546510006010a20d01bc3d91d958a0b130fd14d32ff300e95d8bf535000de174f1dcc6dc183f7810889be9a9d1d81d48620e0c3ab969e0d6306d26edbe527a704f4ef29f2dbb0300dd805f5d2bbb1705f6a106e12d5d340f2c7c20fa14df2c8fc04f401090cc490539b5f94ccc3eba3f7fc9d79e711ddd90205cd536643002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444093368d2f3217473f6261ffa7cd6d61d9b1d7529429d6034e6a88e625f0bea4832f1ee4bacc947f51126b3de090dc0cfef0ee01f15d177e14683ee6b90e33a806", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f529681e812425ef7ff1181614127bfd0d44cbc2c9de3c97379ba3cab58e69c6", - "sequence_number": "6188140359364258365", + "sender": "d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c637c2a61e6cbb8ca96", + "sequence_number": "2046370809621826751", "payload": { "EntryFunction": { "module": { - "address": "6f0c3212072e8b9101f423b113c9a5fec394316b9b9e38c85b9520da8d5982b9", - "name": "oS_Coin" + "address": "286df04220939f8a5433a337fd38912f5024022ed1e8f2bc1862f4dad2ba0fd3", + "name": "FaM7_Coin" }, - "function": "UIyiNLs", + "function": "nUVrtSuXitzoCjgduuKR9", "ty_args": [ { - "vector": "bool" + "struct": { + "address": "71dcccd79e40cdf048e8e19181e4209f836a4b9b104ccc9e01aef2c568bcde26", + "module": "MvCrodIJmaKenjTqDtkvzrXQDefZYcd", + "name": "ceJwqQyKGiJFYwpZQytbpjhHLfX1", + "type_args": [] + } }, { "struct": { - "address": "faa6772651e726fd538aa2ec247b1abe00eabe5bd2204e4306fe55c60ffe365e", - "module": "JESk", - "name": "CYiMhFlLuryMezloEGbYIJYuLkmkbHUO7", + "address": "f810435df41b418fda3ea6d4dd5aa1a3326be052568379696abcde21b3e72d29", + "module": "suCyyzQbtzKDXWmsqhhq8", + "name": "BzGlwFtX6", "type_args": [] } }, { "struct": { - "address": "2ecb72480ba3bdc2eccd3d7995e4fd9c72aa5e6aa0fed2ce251a2c4efe91dfb0", - "module": "TumAyURkVdU", - "name": "PrWvwxiFgOVxniIqDGvaMgIQKYmp", + "address": "079615fbb04d03bb19b47c19ff6cc868fdea83d3682acbb8ed399180a6ce0188", + "module": "xILabrjsvvaU", + "name": "eznGxSCLzHQJDxlpgSwMbYWfViTa5", "type_args": [] } }, { "struct": { - "address": "73581947cd9aae0edf44a748124136c5a4ba496fae367516508014c599c6187e", - "module": "upKIsrqPOGNgMBqgvFjTaXUxaYTRZzd", - "name": "UddbjIiyxzrkCoGfcFMrDzWPWb", + "address": "7807297e8d7d93dcb5edfe984276d32daf79dc5df11e56b9a309f1478aa5f656", + "module": "KKSHxBNrDvUZwqxic9", + "name": "sxafwjwZJFbNjYTgAtiIVqoMTpCCFi9", "type_args": [] } }, { "struct": { - "address": "8eb6b83d5e43cf46b004d04bb6f0e6f58bbcd236644b6e3abe642d5dc7ce1352", - "module": "wjbGDsSnvCNbKqr6", - "name": "qRH", + "address": "680d6b94d6e4db59c4429af17d2b26cdf3ef6ded4ff2c84e2bb6bb318dc9e957", + "module": "kxFiOvTSfNXTfvjI", + "name": "DnwDogNepHkazEMxjJSxvYIQi", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "bee3bb090a1f09f43aa41f6e7084eca4559f540fcb5ef4ee01994f79739a8303", + "module": "P2", + "name": "vFzYNbRNJX", + "type_args": [] + } + } + }, + { + "vector": { + "vector": { + "vector": "u8" + } + } + }, + { + "vector": { + "vector": "u128" + } } ], "args": [ - "d49b480b39c513752ed949578a45cb04be4ce3a2f32e741e5dce2f74413b26b9", - "c65e6a7b03bcd4559c9fa58be4884d9417004126cb47b7b7e4c05e7977b45b29", - "c04022a5d3dc9f6d", - "01", - "601718e49ea508216e847725786b115d37ae941924e7148e943d2c83b0c0d395" + "88", + "b472e11751d58735cb5d87fa65283eb03a6b9780286fe47730cdf24381f83183", + "61cdac66654a209fe3de09768fd0d64e", + "9ecd0ea060dc1456", + "170fdd29538d50f53e1653948e746d8060e246a7ad68411364d3141f2a8206d0", + "4a1ae182ace4bff95b201f7d2de27b03c06fb5f32e370a10ccd29ebf459cd7c8", + "16ef156773b75c4f" ] } }, - "max_gas_amount": "7323667094198240433", - "gas_unit_price": "9466671185694131136", - "expiration_timestamp_secs": "13224356982163801046", - "chain_id": 70 + "max_gas_amount": "17653232582407812613", + "gas_unit_price": "16759295553845889652", + "expiration_timestamp_secs": "6075588763469599562", + "chain_id": 7 }, - "signed_txn_bcs": "f529681e812425ef7ff1181614127bfd0d44cbc2c9de3c97379ba3cab58e69c63d2a2ae4deb0e055026f0c3212072e8b9101f423b113c9a5fec394316b9b9e38c85b9520da8d5982b9076f535f436f696e07554979694e4c7305060007faa6772651e726fd538aa2ec247b1abe00eabe5bd2204e4306fe55c60ffe365e044a45536b214359694d68466c4c7572794d657a6c6f45476259494a59754c6b6d6b6248554f3700072ecb72480ba3bdc2eccd3d7995e4fd9c72aa5e6aa0fed2ce251a2c4efe91dfb00b54756d417955526b5664551c5072577677786946674f56786e694971444776614d6749514b596d70000773581947cd9aae0edf44a748124136c5a4ba496fae367516508014c599c6187e1f75704b49737271504f474e674d42716776466a5461585578615954525a7a641a556464626a496979787a726b436f476663464d72447a5750576200078eb6b83d5e43cf46b004d04bb6f0e6f58bbcd236644b6e3abe642d5dc7ce135210776a62474473536e76434e624b71723603715248000520d49b480b39c513752ed949578a45cb04be4ce3a2f32e741e5dce2f74413b26b920c65e6a7b03bcd4559c9fa58be4884d9417004126cb47b7b7e4c05e7977b45b2908c04022a5d3dc9f6d010120601718e49ea508216e847725786b115d37ae941924e7148e943d2c83b0c0d395b144e7726be4a265c083b96c495f6083d683d4109c5a86b746002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440adacf592d3eead46a54c131908c1d3a63827e0428930054025377de4517c72ddc6ea6b7111ffa314dbb9e90fa075aee49595ee0a5eae3434ee61fe90c56ec20b", + "signed_txn_bcs": "d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c637c2a61e6cbb8ca96bfcc3cc2682b661c02286df04220939f8a5433a337fd38912f5024022ed1e8f2bc1862f4dad2ba0fd30946614d375f436f696e156e5556727453755869747a6f436a676475754b5239080771dcccd79e40cdf048e8e19181e4209f836a4b9b104ccc9e01aef2c568bcde261f4d7643726f64494a6d614b656e6a547144746b767a7258514465665a5963641c63654a777151794b47694a465977705a51797462706a68484c6658310007f810435df41b418fda3ea6d4dd5aa1a3326be052568379696abcde21b3e72d291573754379797a5162747a4b4458576d73716868713809427a476c77467458360007079615fbb04d03bb19b47c19ff6cc868fdea83d3682acbb8ed399180a6ce01880c78494c6162726a73767661551d657a6e477853434c7a48514a44786c706753774d62595766566954613500077807297e8d7d93dcb5edfe984276d32daf79dc5df11e56b9a309f1478aa5f656124b4b534878424e724476555a7771786963391f73786166776a775a4a46624e6a5954674174694956716f4d547043434669390007680d6b94d6e4db59c4429af17d2b26cdf3ef6ded4ff2c84e2bb6bb318dc9e957106b7846694f765453664e585466766a4919446e77446f674e6570486b617a454d786a4a53787659495169000607bee3bb090a1f09f43aa41f6e7084eca4559f540fcb5ef4ee01994f79739a83030250320a76467a594e62524e4a58000606060106060307018820b472e11751d58735cb5d87fa65283eb03a6b9780286fe47730cdf24381f831831061cdac66654a209fe3de09768fd0d64e089ecd0ea060dc145620170fdd29538d50f53e1653948e746d8060e246a7ad68411364d3141f2a8206d0204a1ae182ace4bff95b201f7d2de27b03c06fb5f32e370a10ccd29ebf459cd7c80816ef156773b75c4f05f6c4bb80e1fcf4748ac4fc82fa94e84ad3f55fcad3505407002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406142e3e09dbc0cb612cb50a0356766dad6d8ccd0ce6135aecea873398064df335a29acd84c7ca90e46dfd6499b228b1a9fb6060c54cab21354afb3a90ebd760a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "96c11e9d896f174f0315513049d4822767df0f1616142d7eca104b1d78ceceff", - "sequence_number": "11559191383198427281", + "sender": "81133450ae78d10f2a992fde2c7f36ef4dec9add7a3b1fc7bb89f7ce9cdb9220", + "sequence_number": "15029474211003710184", "payload": { "EntryFunction": { "module": { - "address": "53469100bcfc213d42f24288e08b6a5143e43d1f228566ce671e90e1a4df17b0", - "name": "Lbb_Coin" + "address": "cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee73bdd27", + "name": "TflmkLMbgiLqKaLDWqHLVb8_Coin" }, - "function": "gGgayA", + "function": "VHVl6", "ty_args": [ { "struct": { - "address": "e274060106cd8f4c8f6b9437861f8b9c8a646bd6692cad99806ce67a24afda5c", - "module": "LXl", - "name": "wuzxvWYAKcvQMGgXTQfilGXhcDtJwtWN", + "address": "8d5251fdfe6f20707fcadd12cd4ad7f999a682bb019f4af86cbb6fb871dc4d2c", + "module": "fPAgZdUzyFEATRuELCeIjXlUrls5", + "name": "UmSavkxxSaoDedKdIGaYQqIqgcshb", "type_args": [] } }, { - "vector": { - "struct": { - "address": "4b9c754aa38ba008606b7c2e8691de46093190cb4dfea7043db3ac8d831262cd", - "module": "awZkBLMlL3", - "name": "jFoEIAjizmlMgTPfusXNkqeA8", - "type_args": [] - } + "struct": { + "address": "b68e4fc5c2268337918aefa57c60e14a09156444aca0ca0b441ae1ca8447ed76", + "module": "KsTnWq", + "name": "PmQvd", + "type_args": [] } }, { - "struct": { - "address": "d40f8cd435359da4b6356d530fe7121f7e6fea952f62ce697cc879c04b6ec1ad", - "module": "iElxmcNxvMokvHOXLWrbEULmE", - "name": "tRzASqosndJldXnQThJr", - "type_args": [] + "vector": { + "vector": "signer" } }, { "vector": { "vector": { "struct": { - "address": "cdaa73f986e43d409b5e25cb9ad570d0895cc91ca72a83a474f526cff4aca2f1", - "module": "cpsXwMkWpdaVIaZWDzaTDUiTwcToI4", - "name": "SpCJfgswkSgpdXkfDGysE7", + "address": "bed2635e0cb1f7e72bf40a722b9d992ffb892c943d466fef820eb029849cbdd9", + "module": "oegjW", + "name": "vSMcnTpgDDmUvUuDIPCtYrEczeV7", "type_args": [] } } } }, - { - "struct": { - "address": "b36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8e21b", - "module": "bmrEipOOvzVAcsWTWVUEOfflUUqaFtU", - "name": "wSoRmAwMbjmG5", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "5bb0698e9f5594ddd3be77eebeea8c150d4ab7bf40c663ffaf1e744ab90bd232", - "module": "NQsLVvAXCKNgWx", - "name": "LFOv", + "address": "0a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73", + "module": "FAhOANFOTjpR", + "name": "H", "type_args": [] } } }, { "struct": { - "address": "3a0b88e0b8dc41ebc4d74f1b2349c950a4b091fbae0eb09f62624f22ef8a4e65", - "module": "npwEw3", - "name": "bojLBrdEyFicYdsyMBZB", + "address": "22dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c", + "module": "lHAkawXUQaNWTIovCKxwNrqzrV", + "name": "LZEmkKROvwJaoqSkliLmSDNVJJPHcjP", "type_args": [] } }, - { - "vector": "signer" - }, { "struct": { - "address": "2a0415a7406192d0a4124bcdb027342d758f81173b97b8515ebbb39ffaacf8c8", - "module": "VTauwkxVeCvWQUROeFJCIRmle", - "name": "LwfbHiQqTwqhzNIptlJslmmBfZdzkG5", + "address": "fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f2", + "module": "pVsvVQfbPvx1", + "name": "IJykNT", "type_args": [] } }, { - "vector": { - "struct": { - "address": "9c9bb9958b26b970cb5fdafb149933d724371883b05d302e8a78fc7ac50232eb", - "module": "JjSfrYcEUNNHQzKGLHXD3", - "name": "GKWfza4", - "type_args": [] - } + "struct": { + "address": "93714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de97", + "module": "HLtKraXORTK1", + "name": "GTiSSKaApmlRPlrjTrnuOL7", + "type_args": [] } } ], "args": [ - "982af3edb8e57732", - "9d474766ccd6da84" + "8a404d169212231eba50dab75619d447", + "26756851b2eb6d70", + "ac1359453b5c89b7e227b099103c7e01", + "3458ef907851a500db640fca47db8b963dab06348ddfa4ce5110b55bbc01eb26", + "bd663ff14fd60185467e653e3801741d73daf8698047d969936603b3ff88cd49", + "00" ] } }, - "max_gas_amount": "2024503265829179028", - "gas_unit_price": "13048994257953207127", - "expiration_timestamp_secs": "14340796864842073462", - "chain_id": 108 + "max_gas_amount": "42646023232644863", + "gas_unit_price": "11010247173556066819", + "expiration_timestamp_secs": "5430664830276812460", + "chain_id": 70 }, - "signed_txn_bcs": "96c11e9d896f174f0315513049d4822767df0f1616142d7eca104b1d78ceceff91684cde517f6aa00253469100bcfc213d42f24288e08b6a5143e43d1f228566ce671e90e1a4df17b0084c62625f436f696e066747676179410a07e274060106cd8f4c8f6b9437861f8b9c8a646bd6692cad99806ce67a24afda5c034c586c2077757a78765759414b6376514d476758545166696c4758686344744a7774574e0006074b9c754aa38ba008606b7c2e8691de46093190cb4dfea7043db3ac8d831262cd0a61775a6b424c4d6c4c33196a466f4549416a697a6d6c4d675450667573584e6b716541380007d40f8cd435359da4b6356d530fe7121f7e6fea952f62ce697cc879c04b6ec1ad1969456c786d634e78764d6f6b76484f584c57726245554c6d451474527a4153716f736e644a6c64586e5154684a7200060607cdaa73f986e43d409b5e25cb9ad570d0895cc91ca72a83a474f526cff4aca2f11e63707358774d6b577064615649615a57447a6154445569547763546f4934165370434a666773776b53677064586b664447797345370007b36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8e21b1f626d724569704f4f767a564163735754575655454f66666c555571614674550d77536f526d41774d626a6d47350006075bb0698e9f5594ddd3be77eebeea8c150d4ab7bf40c663ffaf1e744ab90bd2320e4e51734c56764158434b4e675778044c464f7600073a0b88e0b8dc41ebc4d74f1b2349c950a4b091fbae0eb09f62624f22ef8a4e65066e707745773314626f6a4c4272644579466963596473794d425a42000605072a0415a7406192d0a4124bcdb027342d758f81173b97b8515ebbb39ffaacf8c81956546175776b7856654376575155524f65464a4349526d6c651f4c77666248695171547771687a4e4970746c4a736c6d6d42665a647a6b47350006079c9bb9958b26b970cb5fdafb149933d724371883b05d302e8a78fc7ac50232eb154a6a536672596345554e4e48517a4b474c4858443307474b57667a6134000208982af3edb8e57732089d474766ccd6da8494ce5d76fe7a181c57b3691d245717b57685f28cc4be04c76c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3bdfe0a07fb0d252271c80f05c27240ebe0da78d4814b780ff2e9029d8c3b12dc669feb497979bce0bd4bd1feec5315dfcb038dba4544542df513d00c59530c", + "signed_txn_bcs": "81133450ae78d10f2a992fde2c7f36ef4dec9add7a3b1fc7bb89f7ce9cdb9220e83ac5532a6b93d002cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee73bdd271c54666c6d6b4c4d6267694c714b614c445771484c5662385f436f696e055648566c3608078d5251fdfe6f20707fcadd12cd4ad7f999a682bb019f4af86cbb6fb871dc4d2c1c665041675a64557a79464541545275454c4365496a586c55726c73351d556d5361766b787853616f4465644b64494761595171497167637368620007b68e4fc5c2268337918aefa57c60e14a09156444aca0ca0b441ae1ca8447ed76064b73546e577105506d51766400060605060607bed2635e0cb1f7e72bf40a722b9d992ffb892c943d466fef820eb029849cbdd9056f65676a571c76534d636e54706744446d557655754449504374597245637a6556370006070a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc730c4641684f414e464f546a70520148000722dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c1a6c48416b6177585551614e5754496f76434b78774e72717a72561f4c5a456d6b4b524f76774a616f71536b6c694c6d53444e564a4a5048636a500007fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f20c70567376565166625076783106494a796b4e54000793714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de970c484c744b7261584f52544b311747546953534b6141706d6c52506c726a54726e754f4c370006108a404d169212231eba50dab75619d4470826756851b2eb6d7010ac1359453b5c89b7e227b099103c7e01203458ef907851a500db640fca47db8b963dab06348ddfa4ce5110b55bbc01eb2620bd663ff14fd60185467e653e3801741d73daf8698047d969936603b3ff88cd490100ff66dd095582970003da0e357841cc98ac3edbe6e3985d4b46002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444087475046b185276fd453a0d5e3ff21704d676045e12a938404a0b8631d97a8f72096c25a4daae2c2c06b852639e55180ad150279d6dbf193ab390cb4523bd00b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fbc5a206f7fae90fcf70eea1cda0355e4c9efe0fbe4dc8c9ce4af00514b9b0e3", - "sequence_number": "745648003805177336", + "sender": "e0247736e22af10e5c0d51c6315ad0531a58cbc9fae45362122007426aea0da9", + "sequence_number": "10029122952531535429", "payload": { "EntryFunction": { "module": { - "address": "837bad2a269644dd81a55ccefcd1a980033f5e49f7d0bf4bee868827d76114b2", - "name": "tlGsWMMAFr_Coin" + "address": "84ece6d4652d666f0aa272b9f63dd985c8d172791328d799fb0783862c1555e4", + "name": "AmhcGBkABcVhICJTiEvpTUNecA2_Coin" }, - "function": "gQkhxR", + "function": "EFMBgyWKMuMSEOSodWW1", "ty_args": [ - { - "struct": { - "address": "ac6d1c1d76b444ad094755c6c2d1e2751f5db2a40a2b80736a10a5601afd57db", - "module": "FJYiAqRJvBdnByLnCforvRnAtZJ", - "name": "XLflVtRSndErPr", - "type_args": [] - } - }, - { - "vector": { - "struct": { - "address": "e954e1e55c4a5a81416ea56c225f09850a1c53250d9fec509201014961077839", - "module": "hiWrNQihET", - "name": "QFcCkiXkuMEBTOLcbdLRdDEYtXNINUo5", - "type_args": [] - } - } - }, { "vector": { "struct": { - "address": "6e66f3a95bb8fb2eb6d33c6f1c6bb840267ca2e200daafed30ff5cbaee37adfd", - "module": "htnIYGlqfBlQgotrnLpGm", - "name": "cddsdHoRhYLoNNVONPLub3", + "address": "6b2ca45f532d03ce487367fceb74144c5b796a2ce67357f251e593f9d2ab1bb3", + "module": "WeAImICitwSAv8", + "name": "vtQxQrVpGxUv", "type_args": [] } } }, { "struct": { - "address": "f10b1ca3465fceeaa1fbe244939a56ce0490dd28e6e3492a6cf458394aaeff45", - "module": "tmcLFbxwzmPLrtjpBmeB", - "name": "WtIrDKOHQGJwZSspwQZygYRWCMF", + "address": "b01c45ed5248881e3efd7b91f5c2381ab2c52d09667660ed09ee1d81f80e2744", + "module": "AbAE0", + "name": "djwgORARgPhR", "type_args": [] } - }, - { - "vector": { - "vector": { - "struct": { - "address": "48aa03a7c032eb572c7fed2179a35bf6d309c3e604bd3e6511ad882cb689edc3", - "module": "V0", - "name": "rkw", - "type_args": [] - } - } - } - }, - { - "vector": { - "struct": { - "address": "b16a91b9667bf06025ce699c79470fe70a72376316b70c51f7ce9f89dbdf38c8", - "module": "ncwAaJPcwEmIXiaycHLruAVuWMx", - "name": "GukvNyrZwF", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "address" - } } ], "args": [ - "6a555e0c18e81dd3bb582715f1c0d099" - ] - } - }, - "max_gas_amount": "898980706617675217", - "gas_unit_price": "7210551618278762929", - "expiration_timestamp_secs": "5688830681978596580", - "chain_id": 90 - }, - "signed_txn_bcs": "fbc5a206f7fae90fcf70eea1cda0355e4c9efe0fbe4dc8c9ce4af00514b9b0e3f86549aae812590a02837bad2a269644dd81a55ccefcd1a980033f5e49f7d0bf4bee868827d76114b20f746c4773574d4d4146725f436f696e0667516b6878520707ac6d1c1d76b444ad094755c6c2d1e2751f5db2a40a2b80736a10a5601afd57db1b464a59694171524a7642646e42794c6e43666f7276526e41745a4a0e584c666c567452536e6445725072000607e954e1e55c4a5a81416ea56c225f09850a1c53250d9fec5092010149610778390a686957724e516968455420514663436b69586b754d4542544f4c6362644c526444455974584e494e556f350006076e66f3a95bb8fb2eb6d33c6f1c6bb840267ca2e200daafed30ff5cbaee37adfd1568746e4959476c7166426c51676f74726e4c70476d166364647364486f5268594c6f4e4e564f4e504c7562330007f10b1ca3465fceeaa1fbe244939a56ce0490dd28e6e3492a6cf458394aaeff4514746d634c466278777a6d504c72746a70426d65421b57744972444b4f4851474a775a53737077515a7967595257434d460006060748aa03a7c032eb572c7fed2179a35bf6d309c3e604bd3e6511ad882cb689edc302563003726b77000607b16a91b9667bf06025ce699c79470fe70a72376316b70c51f7ce9f89dbdf38c81b6e637741614a506377456d495869617963484c7275415675574d780a47756b764e79725a77460006060401106a555e0c18e81dd3bb582715f1c0d099d14de08d30d2790cb1a91f627e061164e46cad525dc9f24e5a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cb0761e15eba801cc3e1ff3b542e2801b8b8e92bbaa2ac5836cf2af34de88d4a6ce3b16a702ba30e031520a7ce1c90525198d6e0cb56de41edcf5a1e15261401", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "30a1daef4d811cd587cf300147af34da5d0b89b1666dfd2eab2e402b63ac805b", - "sequence_number": "2714727452880618199", - "payload": { - "EntryFunction": { - "module": { - "address": "19f437c3b9441a5661367cf398973528c6e8c4eb4b098a91a18587ad76a447da", - "name": "gOBIYGhMdORWvgnY7_Coin" - }, - "function": "FOKmOgYpEBDuGDYw", - "ty_args": [], - "args": [ - "7e5d89badcbb467da497c49c625304d3", - "c5ec47f373dbaec556205a8a2ca4f27318e917a40e6d486f366636f5e38cd326", - "1cf2b84d921e706a", - "9198f94dccb74835" + "7e012218621dbe5e", + "9b", + "5bc9718fe91157d5ad5f835a338a47c8", + "f4", + "ae44011a553e4d89", + "4ca8b119e464fad51fe9cfef3781d50737e78a82c31b32b62047bfcd6cde7411", + "00", + "5f10c514213e7079bd1873f2f5595e65bb6c81f671d2d94924ea9c43d518753e" ] } }, - "max_gas_amount": "1953091393739247917", - "gas_unit_price": "17223638430308449281", - "expiration_timestamp_secs": "10767712634746963016", - "chain_id": 117 + "max_gas_amount": "9051309887105204035", + "gas_unit_price": "13933671736710381225", + "expiration_timestamp_secs": "5244721609848198792", + "chain_id": 4 }, - "signed_txn_bcs": "30a1daef4d811cd587cf300147af34da5d0b89b1666dfd2eab2e402b63ac805bd742f3323ca6ac250219f437c3b9441a5661367cf398973528c6e8c4eb4b098a91a18587ad76a447da16674f42495947684d644f525776676e59375f436f696e10464f4b6d4f67597045424475474459770004107e5d89badcbb467da497c49c625304d320c5ec47f373dbaec556205a8a2ca4f27318e917a40e6d486f366636f5e38cd326081cf2b84d921e706a089198f94dccb748352d51b35146c61a1b013c4dcae5a706ef4804946d97996e9575002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409ead5895864296bf22c805683a4890813f6b35260e12bc4aa26cb8631c595c990576861cf676cbc02d2adf117630666bb5faa1470583962ec77d0f1759a9030c", + "signed_txn_bcs": "e0247736e22af10e5c0d51c6315ad0531a58cbc9fae45362122007426aea0da945e65b52309a2e8b0284ece6d4652d666f0aa272b9f63dd985c8d172791328d799fb0783862c1555e420416d686347426b414263566849434a546945767054554e656341325f436f696e1445464d426779574b4d754d53454f536f645757310206076b2ca45f532d03ce487367fceb74144c5b796a2ce67357f251e593f9d2ab1bb30e576541496d4943697477534176380c7674517851725670477855760007b01c45ed5248881e3efd7b91f5c2381ab2c52d09667660ed09ee1d81f80e27440541624145300c646a77674f524152675068520008087e012218621dbe5e019b105bc9718fe91157d5ad5f835a338a47c801f408ae44011a553e4d89204ca8b119e464fad51fe9cfef3781d50737e78a82c31b32b62047bfcd6cde74110100205f10c514213e7079bd1873f2f5595e65bb6c81f671d2d94924ea9c43d518753e43ffe2ec62b69c7da9be85eb9e585ec18816d13484fec84804002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440343eccb1956e74a49e1663a37ed66c314a1b97c6504929020fc7e924169b3c63e561da4894d6b85a633222a64551c7bfeb7c9411d8007b284106512787e9850a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e746c64d6b9a393b7ccdbc0008a9fcc468c20cbd46ffb0b21892d4300d6a3395", - "sequence_number": "2060520937195848607", + "sender": "00c0d0991ac6a0eebb9649eb505f2e62ec4b8d0c9e3a734a9075bde1668f0f23", + "sequence_number": "17725476240111942094", "payload": { "EntryFunction": { "module": { - "address": "cd32ff0caf4a263d388bc32234fa832a9c3c0352022d03fddc02cfa8e4f2813f", - "name": "FdqMjNhyssQXKxFJMwy_Coin" + "address": "260ccf1cdb626e4ab219dff04438da2bf025c2ef104c5568cac9fc437760ace5", + "name": "KlDTQvtvp_Coin" }, - "function": "GNrKBKIFWiEhRO6", + "function": "BNarIzEowihuLPQowCjPkD", "ty_args": [ { "struct": { - "address": "c2fc60f46b344fc52f0f5d331b1cd8f78c04e6f41f5a09e456b473bcb50ee5f6", - "module": "HYntURLGRXmhHItBY4", - "name": "xSCHkOmthlWTiaWCzaGIJXEVCIUN4", + "address": "42ef1d27b329b29e9010a1c4674f2a130dfa039b22da6679c61643f9fdb03aa4", + "module": "gnQQRcWgcQfVTTnkSgoVNedJ1", + "name": "BmOaEGtBYdqchFnrfrjFmoX", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "09cb81be1b4706872dd7d8cca0feafa94a4c4d14ff386f69e4b52f2b3da43c3b", + "module": "nlAe", + "name": "SRtfqxNwNFKTFpLHdFYORtNkFrhoOOiS4", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "5240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170e390", - "module": "pxmHxgotFcWY9", - "name": "SnsHdwg", + "address": "9da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e", + "module": "sTcxImSQiLOXChkjwGvNrWZc8", + "name": "YjpAOWYUzqPRPAx", "type_args": [] } } @@ -6105,446 +6587,404 @@ { "vector": { "struct": { - "address": "5988be909a38db33f5d28e2fc432bdd2b48e5f2864e6b30e299e0be22cdaf802", - "module": "RfEfqGNCrBJTbGhNkZL3", - "name": "oZwEDSTAhzxhvOYuJpYzM9", + "address": "37e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e787", + "module": "dGMGHGeUvnWQlWCVtX7", + "name": "sVbznwxXoNAINJOd0", "type_args": [] } } }, - { - "struct": { - "address": "445a538bd20313c97323bfc650b38be10d94ac58cd2e7b35989ba7e3348f67d2", - "module": "imBjyYyMKbgVrxGRi", - "name": "WBASBjRUS7", - "type_args": [] - } - }, { "vector": { "vector": { - "vector": "u8" + "struct": { + "address": "a55cc024484783de4cf6b10edea3d73d24aee1c1f592d5e3f45a2f0df3517c61", + "module": "pnxdQsKqqjwZUuDLVbqCrguuGHePPhlm", + "name": "greNkayEDVH", + "type_args": [] + } } } }, { "vector": { "struct": { - "address": "b0bfd5186d35afc9ff7629caaef8fb1a3db89947786f222f4ade5dfc6e9483d2", - "module": "UGGxGxHRIDkFHduxAufbl", - "name": "EnjrnqRrgUIrGCTjphKbkLjfzaHelrR", + "address": "adc57b5e2b25c5b91ddf9b4a04e9a7ce75a766ddbf691f122617a6a8f63df9b9", + "module": "BnIowWFrNBxsCzWwenrBtXuqX", + "name": "zJ0", "type_args": [] } } }, { - "struct": { - "address": "3b9c72ac28702f1b3db64b8d6105ac251abda21be31b67000cae580a5d7bfaaa", - "module": "OtP9", - "name": "bdYuk6", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "9b905a70f34bf982ff4cd7630fbb0e00d81a78988e0a89baefb7184f70ed6d92", + "module": "EInLkSbNAiTfAEeeqB7", + "name": "qYYhreozURBlUrZZmosY2", + "type_args": [] + } + } } }, { "struct": { - "address": "340fd5395a7aef450e7f25a1ca1ad5cfea7cd80638592b1136007798baa27af0", - "module": "sEBsqci", - "name": "znFlq", + "address": "f1cc55af2ba266a08f5dbb2bc8f3f06b63f2ac01d909212f99160b9e16554875", + "module": "a6", + "name": "HFQRTElPNhmmTiMOjKDIgGT", "type_args": [] } }, { "vector": { - "struct": { - "address": "4bd666c517292a353c780a78da2880740b32162044eb600a2f5edad8dfc5fbb5", - "module": "ezOU3", - "name": "Zs8", - "type_args": [] - } + "vector": "u128" + } + }, + { + "vector": { + "vector": "address" } } ], "args": [ - "f1968abd440f875613be09016f62f445", - "b45a3ae40c1d13f8", - "6e2bd1b0a9e1a917b0d243adc2e519d4", - "be", - "521cdc2e4281babdd5c24c5a19dd359b" + "4fa87f3704166bd0a3e02ca8c6389743", + "0e12493a5b5ba9e2", + "953111b4b5fcf27c", + "b4dbda68dee18302a0f7893e9dbdd5b2", + "01", + "64424066472402bea9c9bcab6c45621e", + "4b71e09d170a748abae5aeb94c984c3fd4faa8fe25509ee4e5407cf77a468790", + "70e8f976aa0b98ced857a5d4562cd2bb" ] } }, - "max_gas_amount": "11416902272062105797", - "gas_unit_price": "4683073065799001555", - "expiration_timestamp_secs": "13509958379741968100", - "chain_id": 133 + "max_gas_amount": "159525429769349151", + "gas_unit_price": "13415899599566842889", + "expiration_timestamp_secs": "15680871419898424020", + "chain_id": 16 }, - "signed_txn_bcs": "e746c64d6b9a393b7ccdbc0008a9fcc468c20cbd46ffb0b21892d4300d6a33959f43d011e070981c02cd32ff0caf4a263d388bc32234fa832a9c3c0352022d03fddc02cfa8e4f2813f184664714d6a4e6879737351584b78464a4d77795f436f696e0f474e724b424b494657694568524f360a07c2fc60f46b344fc52f0f5d331b1cd8f78c04e6f41f5a09e456b473bcb50ee5f61248596e7455524c4752586d684849744259341d785343486b4f6d74686c5754696157437a6147494a5845564349554e340006060406075240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170e3900d70786d4878676f74466357593907536e73486477670006075988be909a38db33f5d28e2fc432bdd2b48e5f2864e6b30e299e0be22cdaf802145266456671474e4372424a546247684e6b5a4c33166f5a774544535441687a7868764f59754a70597a4d390007445a538bd20313c97323bfc650b38be10d94ac58cd2e7b35989ba7e3348f67d211696d426a7959794d4b62675672784752690a57424153426a5255533700060606010607b0bfd5186d35afc9ff7629caaef8fb1a3db89947786f222f4ade5dfc6e9483d215554747784778485249446b4648647578417566626c1f456e6a726e715272675549724743546a70684b626b4c6a667a6148656c725200073b9c72ac28702f1b3db64b8d6105ac251abda21be31b67000cae580a5d7bfaaa044f74503906626459756b360007340fd5395a7aef450e7f25a1ca1ad5cfea7cd80638592b1136007798baa27af00773454273716369057a6e466c710006074bd666c517292a353c780a78da2880740b32162044eb600a2f5edad8dfc5fbb505657a4f5533035a7338000510f1968abd440f875613be09016f62f44508b45a3ae40c1d13f8106e2bd1b0a9e1a917b0d243adc2e519d401be10521cdc2e4281babdd5c24c5a19dd359bc5a89c8920fc709ed3252630249efd40e4f6d44a91037dbb85002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409929430724e53ce4e0215b679f754bef185016c2b0d175d22657d4cb376bee5c372c5f93c89c6a1b6584b18c52d7d31f1da946dd0e08c7a987b2fd262e8bec06", + "signed_txn_bcs": "00c0d0991ac6a0eebb9649eb505f2e62ec4b8d0c9e3a734a9075bde1668f0f23ceb97f0eba8afdf502260ccf1cdb626e4ab219dff04438da2bf025c2ef104c5568cac9fc437760ace50e4b6c445451767476705f436f696e16424e6172497a456f776968754c50516f77436a506b440a0742ef1d27b329b29e9010a1c4674f2a130dfa039b22da6679c61643f9fdb03aa419676e5151526357676351665654546e6b53676f564e65644a3117426d4f61454774425964716368466e7266726a466d6f5800060709cb81be1b4706872dd7d8cca0feafa94a4c4d14ff386f69e4b52f2b3da43c3b046e6c4165215352746671784e774e464b5446704c486446594f52744e6b4672686f4f4f6953340006079da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e1973546378496d5351694c4f5843686b6a7747764e72575a63380f596a70414f5759557a71505250417800060737e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e7871364474d4748476555766e57516c574356745837117356627a6e7778586f4e41494e4a4f643000060607a55cc024484783de4cf6b10edea3d73d24aee1c1f592d5e3f45a2f0df3517c6120706e786451734b71716a775a5575444c56627143726775754748655050686c6d0b6772654e6b617945445648000607adc57b5e2b25c5b91ddf9b4a04e9a7ce75a766ddbf691f122617a6a8f63df9b919426e496f775746724e427873437a5777656e72427458757158037a4a30000606079b905a70f34bf982ff4cd7630fbb0e00d81a78988e0a89baefb7184f70ed6d921345496e4c6b53624e4169546641456565714237157159596872656f7a5552426c55725a5a6d6f7359320007f1cc55af2ba266a08f5dbb2bc8f3f06b63f2ac01d909212f99160b9e16554875026136174846515254456c504e686d6d54694d4f6a4b44496747540006060306060408104fa87f3704166bd0a3e02ca8c6389743080e12493a5b5ba9e208953111b4b5fcf27c10b4dbda68dee18302a0f7893e9dbdd5b201011064424066472402bea9c9bcab6c45621e204b71e09d170a748abae5aeb94c984c3fd4faa8fe25509ee4e5407cf77a4687901070e8f976aa0b98ced857a5d4562cd2bb1f280b7e88bf360209ac7cf69ad92ebad4ea9ebf79a59dd910002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d754f43fab3c4e8fc7501eaa11178df1113dc447709fc167807435ddb9845b6076e56121563f75af41ee6e4aac6d22aa500f675da8198f9a5cca4d9fbb633d0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "522ba9a0c868f2410ce9fba8ecec6e5b3085e67956412f24de3ccfc93b67a400", - "sequence_number": "9708135129554253710", + "sender": "b17ed44f5106ef2206751bc41b34553c3a21dc2414f0ebe34aae3ee3693d5a90", + "sequence_number": "11053536302808657764", "payload": { "EntryFunction": { "module": { - "address": "2c193cbf81e90dbe7d4f5ed11c7951fdbf314fecb4294b223626cce67cb4fa3a", - "name": "VTYQKSg0_Coin" + "address": "db75d0ab4e371025348defd7b76a38e1d623859fff01583bbde1acd0ebfb3770", + "name": "fTVixSeMAdgSEMBozEBPYBy_Coin" }, - "function": "qzpiDhuugNENjqpTQSMJPirfHYEfbVk8", + "function": "lTkvCqPU1", "ty_args": [ + { + "vector": { + "vector": "bool" + } + }, + { + "struct": { + "address": "8ecec98dda4cace103facbbf02db26e27168a96196ad6c46a0bcb427c9748d6a", + "module": "HCdfgbyexhoSgY", + "name": "RIuhGkNPXfXobrtpqoRWsvRxAsbyDw7", + "type_args": [] + } + }, { "struct": { - "address": "193cd22d8bfc41ee65cdd696018fcc21e80e5a813f2959d36219ec1a318230c4", - "module": "jGXWzQ", - "name": "pCKS8", + "address": "ecd3668476cb556c93a02f72437567bc61989620167886f2d637183b3adf1342", + "module": "NCQyIkmUpBWdmi8", + "name": "qSM3", "type_args": [] } }, { "vector": { - "struct": { - "address": "0c7d43a2d74772a19735af32201c253aa8f92b8176648084c6de90488d970ea1", - "module": "AhrYtqrvVQCrpltFkQCZTAlsHdG9", - "name": "ZhkWjDiDprRshBXqLWOEDNCjHLyDtcHH", - "type_args": [] - } + "vector": "bool" + } + }, + { + "struct": { + "address": "2ae1f9a4d0ecd43db83555207c59399b142a74aff83f8d431f93ecb01e48b014", + "module": "qPJhjUdmTYCCmAJOTFuNllrTUWTqcIWF3", + "name": "O5", + "type_args": [] + } + }, + { + "struct": { + "address": "0808357741d50041ab6132d24986c84bda2bb520d3a315307589a2a270b3959e", + "module": "pVcM", + "name": "sVTGidCrUVRauvDeC3", + "type_args": [] } + }, + { + "vector": "u8" } ], "args": [ - "3139765f1a3e9d51", - "00", + "2a3ed44f0ed53e19", + "a6a3c08f5a2a32198cadff2758351ffa8a8dbe2f84eefc5843d3e46fe5502bc2", + "269694b61fd8c70e", + "ceaab856e69c0a6e51c30531be9186f4", + "7a", + "8d", "00", - "a2f1f6c0388f7388" - ] - } - }, - "max_gas_amount": "1364424639455611421", - "gas_unit_price": "13608074874311660985", - "expiration_timestamp_secs": "5558338812362258986", - "chain_id": 91 - }, - "signed_txn_bcs": "522ba9a0c868f2410ce9fba8ecec6e5b3085e67956412f24de3ccfc93b67a4008e7792e47639ba86022c193cbf81e90dbe7d4f5ed11c7951fdbf314fecb4294b223626cce67cb4fa3a0d565459514b5367305f436f696e20717a706944687575674e454e6a71705451534d4a506972664859456662566b380207193cd22d8bfc41ee65cdd696018fcc21e80e5a813f2959d36219ec1a318230c4066a4758577a510570434b53380006070c7d43a2d74772a19735af32201c253aa8f92b8176648084c6de90488d970ea11c416872597471727656514372706c74466b51435a54416c7348644739205a686b576a44694470725273684258714c574f45444e436a484c7944746348480004083139765f1a3e9d510100010008a2f1f6c0388f73881dca8a05fb68ef12b9d543e0ff97d9bc2a7a1e54b32f234d5b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444018d5e087013367f0c3d4d0a140ffc66c56cf19a056ce9f521bc8f85023b81e41040513850c569219817e1a37dd6fc5f70909c0ab8122c1a33a943af08e73890b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "98f4a2068c66b5dcb53f732bbf4142bc1d31dbf6b15fdedd7a1384ff33f6bb94", - "sequence_number": "11266348269592408159", - "payload": { - "EntryFunction": { - "module": { - "address": "ece1b40c8d9fb086da7ba30cfd428b8aa3c737690e5f974fb7e61e5fb862d5ba", - "name": "WT0_Coin" - }, - "function": "EQdTcyB", - "ty_args": [], - "args": [ - "25bb266e0a80c57b", - "afebdf3932c59c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159", - "f6" - ] - } - }, - "max_gas_amount": "13553455173283714370", - "gas_unit_price": "14686835722051792292", - "expiration_timestamp_secs": "17601619364688645269", - "chain_id": 14 - }, - "signed_txn_bcs": "98f4a2068c66b5dcb53f732bbf4142bc1d31dbf6b15fdedd7a1384ff33f6bb945f70e43c0f1c5a9c02ece1b40c8d9fb086da7ba30cfd428b8aa3c737690e5f974fb7e61e5fb862d5ba085754305f436f696e074551645463794200030825bb266e0a80c57b20afebdf3932c59c18ae5d635ab973977b02adbb015c7ef091a156d437c16e015901f64295c1baab8b17bca42d6a67461fd2cb954ce7078e8345f40e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401178e5516aacf67e552828d29f85186d0abf850b4ca7b9b0df03aefde166377d2064de2763d6971ca02c21934031b9e6049b8814d5a74d97088416efdd48be05", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c3cdd2f19bf9e41edaf6827c622b6643657873fe148f2d3a04a5db77eb959964", - "sequence_number": "11625350026605985555", - "payload": { - "EntryFunction": { - "module": { - "address": "8487765f9600a41ad93889a0167178dacabfe2103b67e979a876bf231ddc8664", - "name": "gtQeOQNXROecwHXqnlmDvvxFtbkqxFt3_Coin" - }, - "function": "pdHHUTSPXYzqifqxSrLImwwtahmu", - "ty_args": [], - "args": [ - "6c", - "2a" - ] - } - }, - "max_gas_amount": "8613143236029441603", - "gas_unit_price": "12871874025297730325", - "expiration_timestamp_secs": "5202525924052740702", - "chain_id": 117 - }, - "signed_txn_bcs": "c3cdd2f19bf9e41edaf6827c622b6643657873fe148f2d3a04a5db77eb959964137f6d65418a55a1028487765f9600a41ad93889a0167178dacabfe2103b67e979a876bf231ddc866425677451654f514e58524f6563774858716e6c6d447676784674626b71784674335f436f696e1c706448485554535058597a716966717853724c496d77777461686d750002016c012a43e617872308887715db72573a15a2b25eaaec85c315334875002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401edfc5b6fce1388bab75d963cb1833e146dea2653c2a7ece18921fd8a2f8f3eb511fad19deb1f30a4ed90a2c8b730ba76cfcf64df55a09982530cf554abafc0c", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "52f462e609ddd4f47fa654a0e08ca0b3c58791e7079a8a8b8ed2665813cdb381", - "sequence_number": "402780560270399056", - "payload": { - "EntryFunction": { - "module": { - "address": "47b29ea2377514149ce05bbc213a484544b8f86a106d83b5650558c3662c3d1d", - "name": "Rjy9_Coin" - }, - "function": "IrweXnyEhWcyRR", - "ty_args": [], - "args": [ - "d88931abed1680d2", - "d1e59e5d85ba1dcfe661aef0f8a80b4e", - "4119514cd9614af165aa991ea5b782cc", - "01" + "88fa8d8b122bb23f", + "8f", + "e0" ] } }, - "max_gas_amount": "12491913433583050434", - "gas_unit_price": "1117778264511740331", - "expiration_timestamp_secs": "4676265782475935942", - "chain_id": 227 + "max_gas_amount": "15596187450180252967", + "gas_unit_price": "12669226718746987033", + "expiration_timestamp_secs": "7775379903985497020", + "chain_id": 28 }, - "signed_txn_bcs": "52f462e609ddd4f47fa654a0e08ca0b3c58791e7079a8a8b8ed2665813cdb38150965919c9f696050247b29ea2377514149ce05bbc213a484544b8f86a106d83b5650558c3662c3d1d09526a79395f436f696e0e49727765586e7945685763795252000408d88931abed1680d210d1e59e5d85ba1dcfe661aef0f8a80b4e104119514cd9614af165aa991ea5b782cc0101c2dea53515315cadabf9dfc96825830fc6d0ca07f46ee540e3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401c6f9a3bfa5f6b6150d7b530229b127e94c5628a7036c9c5672374c0d6ce7645f0ee0a3b9be8b853b789f132ee8ce3ce4317f80e8a8c6674b275613b2be1690e", + "signed_txn_bcs": "b17ed44f5106ef2206751bc41b34553c3a21dc2414f0ebe34aae3ee3693d5a90646fcb08b40c669902db75d0ab4e371025348defd7b76a38e1d623859fff01583bbde1acd0ebfb37701c665456697853654d41646753454d426f7a4542505942795f436f696e096c546b76437150553107060600078ecec98dda4cace103facbbf02db26e27168a96196ad6c46a0bcb427c9748d6a0e484364666762796578686f5367591f52497568476b4e505866586f62727470716f525773765278417362794477370007ecd3668476cb556c93a02f72437567bc61989620167886f2d637183b3adf13420f4e435179496b6d55704257646d69380471534d3300060600072ae1f9a4d0ecd43db83555207c59399b142a74aff83f8d431f93ecb01e48b0142171504a686a55646d545943436d414a4f5446754e6c6c7254555754716349574633024f3500070808357741d50041ab6132d24986c84bda2bb520d3a315307589a2a270b3959e047056634d127356544769644372555652617576446543330006010a082a3ed44f0ed53e1920a6a3c08f5a2a32198cadff2758351ffa8a8dbe2f84eefc5843d3e46fe5502bc208269694b61fd8c70e10ceaab856e69c0a6e51c30531be9186f4017a018d01000888fa8d8b122bb23f018f01e027356692dac970d8194acd859322d2afbc33c4b2d3b2e76b1c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401534e7c8d384eac66d310a1e788f1bc17bd3a25b2decace27a2a13fff063bc16eec9d0262c2efa579734697bd52d765b12f2833a7e73ebb97a8f2aaf0122fb01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ecee76b8cf2d77c185945bdb3f8c32f20e2e6e51084ca7d79ddc1b12b9dac418", - "sequence_number": "16506098280255848226", + "sender": "91c9353ecc7afc3c35fccf10a42562b9dc1a24efa5b9f435261b31a7a0a3f997", + "sequence_number": "3570480216679393122", "payload": { "EntryFunction": { "module": { - "address": "80639879a4aa60afe7ebcea5626b84238c6d25c797d8b4218d0f4e63a6cf9f7a", - "name": "KEPPiKOWgjHRJXJ_Coin" + "address": "dd7e4de93632810988d3d9eec4869ce7abcd263404f0d15d515ddfc473e56102", + "name": "PxRojjYUTrHhj7_Coin" }, - "function": "KYFbHRaSvkxkFuhZPKTfAztCDwq3", + "function": "ilohmlnXXJk9", "ty_args": [ { "struct": { - "address": "1fe0bc9eecc1490323030851e866e956b6186c4169a6f84a70103f855919c59c", - "module": "CLlFVsWebuLdNZgHiBUkyGF", - "name": "dFjHn", + "address": "41ed44f7f5c335f9caf860b435ceef171fb32debd6f6b873f6c52b96fd4b08fa", + "module": "RxQbHjJKRoehQQBJjhTcwymCLGDyKn", + "name": "oivYMCnQtNKtbe", "type_args": [] } }, { "struct": { - "address": "d6bd4e12c5238d7f8c7e2bd9113195b5e39481b7190b9bfdf81256cf83fe6758", - "module": "DjQivUCNShhLmHbpQGX7", - "name": "hGeUFZgEIoCCdPua8", + "address": "c6ee3f80e6f1cd0d7c63f7804eda5d6361c4efaa44fc7a52ee7997f5748f5f3d", + "module": "fqGPTqYObWIxDpLijspfiCaKX2", + "name": "FknPFQJjJAeTzqg3", "type_args": [] } }, { "vector": { "struct": { - "address": "c0ae510496151ad2c10c8e500bdf6ff7ed0ece968c09a0784d8d40d746c00f63", - "module": "sqYBZPIkJWZFMnqlU5", - "name": "aTrsRPBVNFkLqUXnsSyppkWXgoUIuBPe", + "address": "bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a993032181", + "module": "queUHHSTdNZPKeFEAwpsXxQxjguN", + "name": "dR9", "type_args": [] } } }, { - "struct": { - "address": "2cc21154adc669e52cc4f69942a058d58d74ecab6e1fb4cf2b15bd5be7709ae6", - "module": "TbbIKZwVsghRJETUEt5", - "name": "ofjfrPdqzhziMyZzGhtYiTACNG5", - "type_args": [] - } - }, - { - "struct": { - "address": "9b423b60dd801b9311ca07e15b6869a234a40a633874d7fee73914f6807352a6", - "module": "IqMffgGGckskecZyJans4", - "name": "vxH8", - "type_args": [] - } - }, - { - "struct": { - "address": "93121002189a050e6a6f4789ebc48c6bab3b74b41e768957adf03e486628c638", - "module": "Psp3", - "name": "ejzVpoXHFfNzTAPxA2", - "type_args": [] + "vector": { + "struct": { + "address": "6a5b43b11ff2cbede42398400daffce4e16a16167bdf8028118f0732a0526ef6", + "module": "XhstxajLKPC7", + "name": "DbyTlbfocp8", + "type_args": [] + } } }, { "struct": { - "address": "4474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e", - "module": "fPROplAQR3", - "name": "BdJcspIEAxrSpNxNHkXSUeqdKvO0", + "address": "83c73337e0dcae1b9f257cb0ee37846525821441734c2d05466dcc7973bb8f50", + "module": "zOaRDJfSg", + "name": "gKTNONeHsilUQyaRzpRSPTapcNfRtXD", "type_args": [] } - }, + } + ], + "args": [] + } + }, + "max_gas_amount": "14858205428171983055", + "gas_unit_price": "18083285532585807171", + "expiration_timestamp_secs": "10609333344275075708", + "chain_id": 50 + }, + "signed_txn_bcs": "91c9353ecc7afc3c35fccf10a42562b9dc1a24efa5b9f435261b31a7a0a3f9976227bc00d7e48c3102dd7e4de93632810988d3d9eec4869ce7abcd263404f0d15d515ddfc473e56102135078526f6a6a5955547248686a375f436f696e0c696c6f686d6c6e58584a6b39050741ed44f7f5c335f9caf860b435ceef171fb32debd6f6b873f6c52b96fd4b08fa1e52785162486a4a4b526f65685151424a6a68546377796d434c4744794b6e0e6f6976594d436e51744e4b7462650007c6ee3f80e6f1cd0d7c63f7804eda5d6361c4efaa44fc7a52ee7997f5748f5f3d1a667147505471594f6257497844704c696a7370666943614b583210466b6e5046514a6a4a4165547a716733000607bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a9930321811c7175655548485354644e5a504b65464541777073587851786a67754e036452390006076a5b43b11ff2cbede42398400daffce4e16a16167bdf8028118f0732a0526ef60c5868737478616a4c4b5043370b446279546c62666f637038000783c73337e0dcae1b9f257cb0ee37846525821441734c2d05466dcc7973bb8f50097a4f6152444a6653671f674b544e4f4e654873696c55517961527a70525350546170634e66527458440000cfc8f8611df332ce43cdbced61bcf4fa7c12394977ec3b9332002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023a819af297f01a5d24e2db211e6560d38c009a3e41f716f7c355f32475f0724d6414143674b622ee6cd3313df1ba44faf5590ac51538a720ddea90314d0750e", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8f885f2e8d64307eb2ebabcdcbb0da33e92bad819945e0fda3e539ba2b406c2a", + "sequence_number": "15482645997933708300", + "payload": { + "EntryFunction": { + "module": { + "address": "0aec1c86294532f1140bc6ad5576554b66034ae2db8e1271e9efac47d975a8ae", + "name": "xuukDAenpMFZoivxJhHhWPnshxXsYYFq_Coin" + }, + "function": "DLVXhCgFcrgLrgRUDyWoLFVeZabHu9", + "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "struct": { - "address": "5a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b", - "module": "epPFGCJFNr", - "name": "JFcjqMaInQD6", - "type_args": [] + "vector": { + "vector": "address" + } } } ], "args": [ - "eb" + "623e4a74acd9afc69ef1040bb4ec7f0e", + "a67b34625a56dfb807512dfd7e54a36691b6028ea2dc93242f2bc0f331e55447", + "12a7700f7736688320934b79dd9e109a", + "b2ed3d11ed8197b6091ef86db76255abbe7b8ade23bfd73a7514ebe799c198d4", + "01", + "82", + "93" ] } }, - "max_gas_amount": "13402343559833689883", - "gas_unit_price": "1667303761792637328", - "expiration_timestamp_secs": "10618678220240828538", - "chain_id": 178 + "max_gas_amount": "5565563150619258041", + "gas_unit_price": "5161692174764465018", + "expiration_timestamp_secs": "15892331458200183756", + "chain_id": 195 }, - "signed_txn_bcs": "ecee76b8cf2d77c185945bdb3f8c32f20e2e6e51084ca7d79ddc1b12b9dac41822ff55ceee7011e50280639879a4aa60afe7ebcea5626b84238c6d25c797d8b4218d0f4e63a6cf9f7a144b455050694b4f57676a48524a584a5f436f696e1c4b59466248526153766b786b4675685a504b5466417a74434477713309071fe0bc9eecc1490323030851e866e956b6186c4169a6f84a70103f855919c59c17434c6c465673576562754c644e5a67486942556b7947460564466a486e0007d6bd4e12c5238d7f8c7e2bd9113195b5e39481b7190b9bfdf81256cf83fe675814446a51697655434e5368684c6d486270514758371168476555465a6745496f43436450756138000607c0ae510496151ad2c10c8e500bdf6ff7ed0ece968c09a0784d8d40d746c00f6312737159425a50496b4a575a464d6e716c55352061547273525042564e466b4c7155586e73537970706b5758676f55497542506500072cc21154adc669e52cc4f69942a058d58d74ecab6e1fb4cf2b15bd5be7709ae613546262494b5a7756736768524a4554554574351b6f666a66725064717a687a694d795a7a47687459695441434e473500079b423b60dd801b9311ca07e15b6869a234a40a633874d7fee73914f6807352a61549714d6666674747636b736b65635a794a616e73340476784838000793121002189a050e6a6f4789ebc48c6bab3b74b41e768957adf03e486628c638045073703312656a7a56706f584846664e7a54415078413200074474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e0a6650524f706c415152331c42644a637370494541787253704e784e486b5853556571644b764f3000060604075a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b0a6570504647434a464e720c4a46636a714d61496e514436000101eb1b9fa18175b0feb990995206f07323177ab8a1c5941f5d93b2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f4d6f3e098a9c7c89f85311bc0a3e01e8587d8d1f58abbfa77cc999fb19675594b5bb7b3453014f1218bd04beae64f21f2f1040f0afbe5369b8693cfc368705", + "signed_txn_bcs": "8f885f2e8d64307eb2ebabcdcbb0da33e92bad819945e0fda3e539ba2b406c2a0c44f6298168ddd6020aec1c86294532f1140bc6ad5576554b66034ae2db8e1271e9efac47d975a8ae257875756b4441656e704d465a6f6976784a68486857506e7368785873595946715f436f696e1e444c5658684367466372674c726752554479576f4c4656655a616248753901060606040710623e4a74acd9afc69ef1040bb4ec7f0e20a67b34625a56dfb807512dfd7e54a36691b6028ea2dc93242f2bc0f331e554471012a7700f7736688320934b79dd9e109a20b2ed3d11ed8197b6091ef86db76255abbe7b8ade23bfd73a7514ebe799c198d4010101820193b92caaa732da3c4d7adbbf64af03a247cca3c99242e78cdcc3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a6617f9650a1b95f7537c50380d4b376b04047cc850383a3accd770fb1fa600b64b29c952d690c2d8da24b530db93dcf2782acbe67cc31cdc03a0db3249b5d0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4cf9da65612636650a5fa18e3d0a7dc5a81632468f15d56bcf1fdbf53f004e14", - "sequence_number": "1175884268994291843", + "sender": "ea975cb1b94b93f25b6735fb6db40f6eee62bd372bf462550a40536f191d5f3a", + "sequence_number": "9507448392380117424", "payload": { "EntryFunction": { "module": { - "address": "2c1df553bbaa84028a3904a9e3ae2791cd12f7aaff8c88aef3577d4ab4abf096", - "name": "MsnpLtaAEkpBh_Coin" + "address": "36b8d7a64c0aecea9634f5d5acf177524f5ff4b5a5e1629ab6b0b201215bfbdd", + "name": "VhzyasqWjMT_Coin" }, - "function": "DTazIxHhpuVRkrDnkrFvGeaKaiC", + "function": "TkNMRmFkaStYTe4", "ty_args": [ { "struct": { - "address": "1cd778bdb941dbd4316b921c14eb5461feaaedd550801f0ff0ff7a5cfb5831fd", - "module": "J", - "name": "zbDxA3", + "address": "1119d5b664aefac81ef6d7d1e1f68417091acf18de18c39d605593fce9a150fb", + "module": "nt", + "name": "ZsesfgqsRkELXAd", "type_args": [] } }, { "vector": { "vector": { - "vector": "signer" + "vector": "u64" } } }, + { + "struct": { + "address": "83778a69666982c4721925306403014d3c8caaeb42d85d0b5d78e261b7c56014", + "module": "hbsLcCUjSLtjtCNKkTBhnIXcyD", + "name": "WpgYBaBzb8", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "df7dca80c2f7474ab751ef3f0bdf5f78aac239dc4a1b8e2691f2fa5f03dafec8", - "module": "ZgHOoODnZiSlelWQzjPmOGdqa", - "name": "OmBEpbfvvNSKVsMejuTcvBpGoAHSif", - "type_args": [] - } + "vector": "bool" } }, + { + "vector": "u128" + }, { "vector": { "vector": { "struct": { - "address": "d1b11c1e5ddb8424ea8106dbacb96388f92d58543b51228d6920cd7468d3bc8e", - "module": "wuvluoOrSPRblIwfdENDFPBBKWqwDx", - "name": "OfgfnadWQXtMtacjViL3", + "address": "3129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5fd131", + "module": "jJ", + "name": "iTylTQJbpNBVJDCPWVB1", "type_args": [] } } } }, + { + "struct": { + "address": "b6ab077aa0027da458cd171b0db51d7002fcd08f1278355b7f26b4f75a609936", + "module": "PJiZeUVwmJzHjzHh", + "name": "kYfBeIN", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "2e46b573e37510ffe1748fb7dc44777b1392467a740980c13e1af83d0b9fcc42", - "module": "IQm8", - "name": "izzhEMfacEYP9", + "address": "c12ce1dff77bdc3fda9e82306f2ba3200e7cd8dadc63fa0247f2c1d736a4a5a9", + "module": "jmnSHNChOxj", + "name": "ER", "type_args": [] } } }, - { - "struct": { - "address": "0d061744da1c099ba010362cb3d7901d1368fccfb04c7ea18924c4e6205c4211", - "module": "zEFFoTCuAqvmm0", - "name": "M", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "99e385c490a595c127c422caa407fe03f6a2beab5998e6819a6e628e90f07793", - "module": "tgyjqslSuILJsGwNyhbIR", - "name": "dgvkqhY", + "address": "733db0e8db073486139e003357792b07ebbf5b216a14a20eae53b70c5ef3bffe", + "module": "corCYwheAClMqKqAWZheEWtmKgLw7", + "name": "MYTdyPBn", "type_args": [] } } }, { "struct": { - "address": "4d42d063185143901d05c3701c8a0d53ec9b56ce5d525f4c1f75c9a46b10e5cc", - "module": "zUUYPvyOrQuqElnOY", - "name": "TPiTEQNJQrGYEadpBaZ", + "address": "df6301c0d7b8cfdaae0a5051ef8aeeb42d74e10964e4772564059b774af57296", + "module": "p9", + "name": "oZajNdnRvNfuqYjZSFlxV", "type_args": [] } } ], "args": [ - "d0", - "7de4c159275a2a4288fcc9f3c2a6c912", - "128670234bdadfe3", - "0c98e4ba31c067ca", - "a235b1a3d42b30cca52639dc7c21c856", - "c7" + "01", + "52", + "00", + "00", + "39531951e0cfce6d3706b6a1edaa28a1", + "258c183b63a905bd3e3451813e3190cc", + "d28cd8c1516c4f17", + "08ec26244edc64e7b3e43347e5b2eee86ba0c35c736eba9e2581773865023bc6" ] } }, - "max_gas_amount": "14641276958299992272", - "gas_unit_price": "11816269869188365754", - "expiration_timestamp_secs": "15779597964659532366", - "chain_id": 144 + "max_gas_amount": "17780926253518102796", + "gas_unit_price": "8481489915609985387", + "expiration_timestamp_secs": "13790857081150253923", + "chain_id": 75 }, - "signed_txn_bcs": "4cf9da65612636650a5fa18e3d0a7dc5a81632468f15d56bcf1fdbf53f004e1483e85f3683945110022c1df553bbaa84028a3904a9e3ae2791cd12f7aaff8c88aef3577d4ab4abf096124d736e704c746141456b7042685f436f696e1b4454617a49784868707556526b72446e6b7246764765614b61694308071cd778bdb941dbd4316b921c14eb5461feaaedd550801f0ff0ff7a5cfb5831fd014a067a624478413300060606050607df7dca80c2f7474ab751ef3f0bdf5f78aac239dc4a1b8e2691f2fa5f03dafec8195a67484f6f4f446e5a69536c656c57517a6a506d4f476471611e4f6d424570626676764e534b56734d656a755463764270476f414853696600060607d1b11c1e5ddb8424ea8106dbacb96388f92d58543b51228d6920cd7468d3bc8e1e7775766c756f4f72535052626c49776664454e44465042424b5771774478144f6667666e6164575158744d7461636a56694c330006072e46b573e37510ffe1748fb7dc44777b1392467a740980c13e1af83d0b9fcc420449516d380d697a7a68454d6661634559503900070d061744da1c099ba010362cb3d7901d1368fccfb04c7ea18924c4e6205c42110e7a4546466f5443754171766d6d30014d00060799e385c490a595c127c422caa407fe03f6a2beab5998e6819a6e628e90f07793157467796a71736c5375494c4a7347774e7968624952076467766b71685900074d42d063185143901d05c3701c8a0d53ec9b56ce5d525f4c1f75c9a46b10e5cc117a5555595076794f72517571456c6e4f59135450695445514e4a517247594561647042615a000601d0107de4c159275a2a4288fcc9f3c2a6c91208128670234bdadfe3080c98e4ba31c067ca10a235b1a3d42b30cca52639dc7c21c85601c7d030951dd24330cbbabd1f3bd7d2fba34e2202b6be64fcda90002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bcab78f1ebc73e950a640b879931bef90f44be07ec4678029838efc81bd7648345f18ca7b14437c7bea6e2de39f1ede9fac6fb66da9cde7355efc20425516c0f", + "signed_txn_bcs": "ea975cb1b94b93f25b6735fb6db40f6eee62bd372bf462550a40536f191d5f3ab0f12cb4f03df1830236b8d7a64c0aecea9634f5d5acf177524f5ff4b5a5e1629ab6b0b201215bfbdd1056687a79617371576a4d545f436f696e0f546b4e4d526d466b615374595465340a071119d5b664aefac81ef6d7d1e1f68417091acf18de18c39d605593fce9a150fb026e740f5a73657366677173526b454c58416400060606020783778a69666982c4721925306403014d3c8caaeb42d85d0b5d78e261b7c560141a6862734c6343556a534c746a74434e4b6b5442686e49586379440a577067594261427a62380006060006030606073129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5fd131026a4a146954796c54514a62704e42564a444350575642310007b6ab077aa0027da458cd171b0db51d7002fcd08f1278355b7f26b4f75a60993610504a695a655556776d4a7a486a7a4868076b59664265494e000607c12ce1dff77bdc3fda9e82306f2ba3200e7cd8dadc63fa0247f2c1d736a4a5a90b6a6d6e53484e43684f786a024552000607733db0e8db073486139e003357792b07ebbf5b216a14a20eae53b70c5ef3bffe1d636f72435977686541436c4d714b7141575a68654557746d4b674c7737084d5954647950426e0007df6301c0d7b8cfdaae0a5051ef8aeeb42d74e10964e4772564059b774af57296027039156f5a616a4e646e52764e667571596a5a53466c7856000801010152010001001039531951e0cfce6d3706b6a1edaa28a110258c183b63a905bd3e3451813e3190cc08d28cd8c1516c4f172008ec26244edc64e7b3e43347e5b2eee86ba0c35c736eba9e2581773865023bc60c215d5e388ac2f66bb1fd31244eb475632b24be72f762bf4b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a4316e282a65cd7b3182a26f55b8115e70457001daffc2bc6f55f86953c80c48237f9f7db7a8649bba58ff875d52e51a8d84ad4a1f4c21c1f7e0331c34456006", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "555157eef5c2a66918739038d7a73237b7e55bfee7a429a82b83fd3a501a7c80", - "sequence_number": "17550559087365898062", + "sender": "ed25163dbc552d6996903246d7a3207b2aa2f824b20ddd28a53c2132dab3df01", + "sequence_number": "13265645245838293307", "payload": { "EntryFunction": { "module": { - "address": "4261a4b87cf1e2b26eb4775d8ed8a713ad6189f0710a855bb3d02c6bb2f2107c", - "name": "vRYfducDeDnSwmdQ_Coin" + "address": "61ad29837b7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b", + "name": "SiNAVCzHsCJmIXeFyTPZbhXFooK3_Coin" }, - "function": "FUBgeyxeAnCAdbJhJWpykdKykSZ2", + "function": "tOdurPVhuw", "ty_args": [ - { - "struct": { - "address": "a05758ed3b49170daedc052780995acd674b95f2b7a800d346a6256dd54f4288", - "module": "sTJQIEZbsSAQaJMHPzHcLWbq", - "name": "KKRQwulvCc6", - "type_args": [] - } - }, - { - "struct": { - "address": "2203fbd6085761f1d25c9b8c0785c77c337d5301cd22301c2cffd03a22688f8c", - "module": "JqcPjWpLdrmJiHr", - "name": "rApyYWhwHhdxChSXFtLI", - "type_args": [] - } - }, { "vector": { "vector": { "struct": { - "address": "8d97cb5cf34b4554880e9c30a6759e947e00a408e61bbcb6a4d9101b13b23e72", - "module": "XivxzomTWtFBu", - "name": "NfiWhMiPrZNEQPjgG6", + "address": "775249248fd67146bd015e9ba8f4e5b85b713a6ed7e06d521e12b7340015236d", + "module": "TMltUiIrJKVTjmhkWrRaGVGM", + "name": "dQMhsxfKHnUWvuRLMWZ", "type_args": [] } } @@ -6552,196 +6992,143 @@ }, { "struct": { - "address": "5d89a6aa63ef6ae338dfafd83332c1598b361b2f9a298a12ef8935f655b35e98", - "module": "m", - "name": "RPUC", - "type_args": [] - } - }, - { - "struct": { - "address": "1a56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56", - "module": "lFzUidMBlIjvdsVlIh", - "name": "zXb", + "address": "add6ee76d7116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a6", + "module": "nCCANAWTCUSNVIk2", + "name": "eJHUrfzEtyZfpPhcPxCDrbDGxdlzPy1", "type_args": [] } }, { "struct": { - "address": "02786e6ae3354703196c1a1e64dda26e67562c6d3faf2d7b42161d4240bcceb1", - "module": "PWjENfDcR0", - "name": "FBpIZcwMspYCfFPqZg", + "address": "b2f14cc33b042cdaa6634447da83cc8e8af0d19c678f7ad9bffab1086d5f99e7", + "module": "WsjmNckoOkEVY5", + "name": "AQUjUhXDA2", "type_args": [] } }, { "struct": { - "address": "6b19b3b8bf936a8b2a278adebf4c3caa4c7e5ff2cc8961b62c3d89a52fc798d3", - "module": "UseRWKEOPXZggAOCgXGeMhRhOfNqPZFs9", - "name": "VwiWBKkPkBPBLUUJOaE9", + "address": "c1f015afdff9e9ef96014fad5557eab5b66b7f3d1e23850459cac859019a70a4", + "module": "mt", + "name": "RqISDRona", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "56709589a2ea4228622ae1a42b7c5d9c95ccf04bf0d13057e2ed3e422595ef35", - "module": "mwPcqDYJIhdiAcikMBwRZlnh", - "name": "YJFBPQpMwmREBraxyxb", - "type_args": [] - } - } - } - ], - "args": [ - "05", - "95", - "be", - "b3", - "7762099c1411efb8", - "ab9f6f1e1754dd0b", - "0b3df99d75741908f3c7a2de4555f75d" - ] - } - }, - "max_gas_amount": "5152191004395986010", - "gas_unit_price": "16501995279232981224", - "expiration_timestamp_secs": "8188060161470793311", - "chain_id": 65 - }, - "signed_txn_bcs": "555157eef5c2a66918739038d7a73237b7e55bfee7a429a82b83fd3a501a7c804ebff2cb801c90f3024261a4b87cf1e2b26eb4775d8ed8a713ad6189f0710a855bb3d02c6bb2f2107c15765259666475634465446e53776d64515f436f696e1c4655426765797865416e434164624a684a5770796b644b796b535a320807a05758ed3b49170daedc052780995acd674b95f2b7a800d346a6256dd54f42881873544a5149455a6273534151614a4d48507a48634c5762710b4b4b525177756c7643633600072203fbd6085761f1d25c9b8c0785c77c337d5301cd22301c2cffd03a22688f8c0f4a7163506a57704c64726d4a694872147241707959576877486864784368535846744c49000606078d97cb5cf34b4554880e9c30a6759e947e00a408e61bbcb6a4d9101b13b23e720d586976787a6f6d545774464275124e666957684d6950725a4e4551506a67473600075d89a6aa63ef6ae338dfafd83332c1598b361b2f9a298a12ef8935f655b35e98016d045250554300071a56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56126c467a5569644d426c496a766473566c4968037a5862000702786e6ae3354703196c1a1e64dda26e67562c6d3faf2d7b42161d4240bcceb10a50576a454e664463523012464270495a63774d73705943664650715a6700076b19b3b8bf936a8b2a278adebf4c3caa4c7e5ff2cc8961b62c3d89a52fc798d32155736552574b454f50585a6767414f43675847654d6852684f664e71505a4673391456776957424b6b506b4250424c55554a4f61453900060756709589a2ea4228622ae1a42b7c5d9c95ccf04bf0d13057e2ed3e422595ef35186d7750637144594a496864694163696b4d4277525a6c6e6813594a46425051704d776d52454272617879786200070105019501be01b3087762099c1411efb808ab9f6f1e1754dd0b100b3df99d75741908f3c7a2de4555f75d5a5cfcc76b428047e8d8da6f46dd02e55f86feab55d5a17141002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444036caf64fe036bdeac5f9826d8b57868dd0ffff2594aa133e3e6108c4b3286f169302909efb7b04cc4d28dc565494c5f00fc07c5eb74f8b97da6e8e4cf4bb1c0f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "6b46acabc7c6ea6665d51a84a0b29fee090f40be5a588be4b740dee7e07341a4", - "sequence_number": "9796473743182989945", - "payload": { - "EntryFunction": { - "module": { - "address": "5f363cf6eefc06531ba344935f74745932e3d7d3f801df7347ca06a0faadbade", - "name": "XrmxWf9_Coin" - }, - "function": "HTncePbwJopzCMbygHV2", - "ty_args": [ { "vector": { "vector": { "struct": { - "address": "009572fcb80cca479f33ac5b36ac79f886487be9ea35cb5321b1f9cc32b0e96c", - "module": "olUQdxqygJGZXazFVcYH9", - "name": "wDLjWQgDJKjCNSTrEvDlccf4", + "address": "7c2104690336e006c862dde29270e3e598247185c4d1fa811a6eb18aba0c1788", + "module": "lAZjWllpJUOuOMOnBTvxRYwVrqLf", + "name": "NPjLGh9", "type_args": [] } } } }, { - "vector": { - "vector": { - "vector": { - "struct": { - "address": "ddb66ca4bc7058c2a06ca055d2d9cbf6025090a86c73b1494a89cc891400e98b", - "module": "MTKuSGIeFqIfHctedJ", - "name": "xlcWTPDMCJRTwBmzCl9", - "type_args": [] - } - } - } + "struct": { + "address": "977d2230a609d14c265d78d8fab839ea5bae5f4a000b639417f7d9e42f4ded86", + "module": "TeHwSyMATOTaTKrNiIYrRRiEd6", + "name": "QpKFkKxEnzr", + "type_args": [] } }, { "struct": { - "address": "787a181a21eacde79fce2af097fddf0616c98c211cc4c4c64f1db53a5412d9e6", - "module": "ZWrkuJhATGyAGneoFANNR", - "name": "hNfjhBOJcUJMJEzc8", + "address": "ec4d1807b5967831e69de5c0f5553dcb1ffef85d2f8bfb8a1f0129546e094f42", + "module": "Nwth1", + "name": "dGWdVGezJezKAgqwLAcL3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "b4309529bdce0037abe4ccaa289dfe917d410c5c2b4ccdd9f4f41d16261c7e37", - "module": "usUjuN", - "name": "bkalkyOYGIfUKhTMrDeMxYSWZWu0", - "type_args": [] - } + "struct": { + "address": "c4e21773084d52cd25e68f1f24b4d3d814a600a52b1290a73a1f75ea161f7b9d", + "module": "WSoOUhKpypLMjIlZjbbIFDq1", + "name": "NODRBTChKIKLQLcURMxc4", + "type_args": [] + } + }, + { + "struct": { + "address": "f5c831952a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa7", + "module": "wnxutxfOpuSgcIzEcxWBKQfWtXiz", + "name": "QBmjhMuLmqXTqChBpyfKWSRfYIEI", + "type_args": [] + } + }, + { + "struct": { + "address": "add5a2dfbde0da7202c4843177bb1700f11e4c5215205c20a7e203e67dbdac1d", + "module": "iKvUdrarqgnSPsMMAicdHRRwFUsMZbJb0", + "name": "KxPTMIGhtrisCqcdgjGWbSPoiv5", + "type_args": [] } } ], "args": [ - "01", - "8670b6c923b144b6", - "97dbaa52a5a74d6d2d2333de62c81a216bddffb54ae0048842725f069a54dd6a", - "d0e9700e061be3d7e54be431e37ed6e7", - "cceb4a5bd3a72f83", - "d5b445bfd2013b5e795118a54cc922f76554c8b4df4f9704476bbc5070ddd3cd", - "6fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cfaeaf7a399671e22d9c97" + "61c590b05ab0bc3b8caa40aa2ddf5bc23bd14cbe0b5dbdac699162e6e039204a", + "dd5e76d8b6ae636786bc5bc9d61a2777c838c72f701a38cb961307c351145ae3", + "cea665f861d76cf9", + "ac", + "e882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3b7d494051c", + "275a97c225b3b237e8798414411602946592b8d545772a9ecabdfb2e258a4d7e", + "551699eb38ad6d33", + "eb197aa234e255ce", + "f135b94b8aa0a209", + "c1" ] } }, - "max_gas_amount": "5809823051666828294", - "gas_unit_price": "1424962271267863624", - "expiration_timestamp_secs": "8336870702502479669", - "chain_id": 74 + "max_gas_amount": "6958953391503829005", + "gas_unit_price": "17028215654876135447", + "expiration_timestamp_secs": "17144117674252706486", + "chain_id": 123 }, - "signed_txn_bcs": "6b46acabc7c6ea6665d51a84a0b29fee090f40be5a588be4b740dee7e07341a4790add29f710f487025f363cf6eefc06531ba344935f74745932e3d7d3f801df7347ca06a0faadbade0c58726d785766395f436f696e1448546e63655062774a6f707a434d62796748563204060607009572fcb80cca479f33ac5b36ac79f886487be9ea35cb5321b1f9cc32b0e96c156f6c555164787179674a475a58617a4656635948391877444c6a575167444a4b6a434e5354724576446c636366340006060607ddb66ca4bc7058c2a06ca055d2d9cbf6025090a86c73b1494a89cc891400e98b124d544b75534749654671496648637465644a13786c63575450444d434a525477426d7a436c390007787a181a21eacde79fce2af097fddf0616c98c211cc4c4c64f1db53a5412d9e6155a57726b754a684154477941476e656f46414e4e5211684e666a68424f4a63554a4d4a457a6338000607b4309529bdce0037abe4ccaa289dfe917d410c5c2b4ccdd9f4f41d16261c7e37067573556a754e1c626b616c6b794f59474966554b68544d7244654d785953575a57753000070101088670b6c923b144b62097dbaa52a5a74d6d2d2333de62c81a216bddffb54ae0048842725f069a54dd6a10d0e9700e061be3d7e54be431e37ed6e708cceb4a5bd3a72f8320d5b445bfd2013b5e795118a54cc922f76554c8b4df4f9704476bbc5070ddd3cd206fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cfaeaf7a399671e22d9c97062c7aa248a3a050483c41cda27bc613358705b9bb83b2734a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059aed456ade6e5680ed5cf6bf24828ec6a46e12e2939997ba81290dd1a2fcd8e0f043c28d4e4b59da4a8f55209308b5836baa93c29b0bd013657b81c197c0b09", + "signed_txn_bcs": "ed25163dbc552d6996903246d7a3207b2aa2f824b20ddd28a53c2132dab3df013b798a12110a19b80261ad29837b7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b2153694e4156437a4873434a6d495865467954505a626858466f6f4b335f436f696e0a744f64757250566875770a060607775249248fd67146bd015e9ba8f4e5b85b713a6ed7e06d521e12b7340015236d18544d6c74556949724a4b56546a6d686b577252614756474d1364514d687378664b486e55577675524c4d575a0007add6ee76d7116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a6106e4343414e4157544355534e56496b321f654a485572667a4574795a6670506863507843447262444778646c7a5079310007b2f14cc33b042cdaa6634447da83cc8e8af0d19c678f7ad9bffab1086d5f99e70e57736a6d4e636b6f4f6b455659350a4151556a5568584441320007c1f015afdff9e9ef96014fad5557eab5b66b7f3d1e23850459cac859019a70a4026d74095271495344526f6e61000606077c2104690336e006c862dde29270e3e598247185c4d1fa811a6eb18aba0c17881c6c415a6a576c6c704a554f754f4d4f6e425476785259775672714c66074e506a4c4768390007977d2230a609d14c265d78d8fab839ea5bae5f4a000b639417f7d9e42f4ded861a5465487753794d41544f5461544b724e694959725252694564360b51704b466b4b78456e7a720007ec4d1807b5967831e69de5c0f5553dcb1ffef85d2f8bfb8a1f0129546e094f42054e7774683115644757645647657a4a657a4b416771774c41634c330007c4e21773084d52cd25e68f1f24b4d3d814a600a52b1290a73a1f75ea161f7b9d1857536f4f55684b7079704c4d6a496c5a6a62624946447131154e4f4452425443684b494b4c514c6355524d7863340007f5c831952a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa71c776e78757478664f7075536763497a45637857424b5166577458697a1c51426d6a684d754c6d715854714368427079664b57535266594945490007add5a2dfbde0da7202c4843177bb1700f11e4c5215205c20a7e203e67dbdac1d21694b76556472617271676e5350734d4d41696364485252774655734d5a624a62301b4b7850544d4947687472697343716364676a47576253506f697635000a2061c590b05ab0bc3b8caa40aa2ddf5bc23bd14cbe0b5dbdac699162e6e039204a20dd5e76d8b6ae636786bc5bc9d61a2777c838c72f701a38cb961307c351145ae308cea665f861d76cf901ac20e882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3b7d494051c20275a97c225b3b237e8798414411602946592b8d545772a9ecabdfb2e258a4d7e08551699eb38ad6d3308eb197aa234e255ce08f135b94b8aa0a20901c10de8154d3d2b93601740a333eb5f50ecb62254f93024eced7b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d1073cd64b85de881312847f0856b9c9c170c2a5f34887fa95c587f7dd42ed1632d048f60072a79cba426b8db12d04f17519490c1b12632fa4a8e34c05e8140a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e50cf2f58c8f60f51778ded644606ec4c51179114d9837196addc43f1d924407", - "sequence_number": "5969652622676644968", + "sender": "a42daed21bdedd449e3c50a9c59393c7c0837a733ca640360d6aa41c19a2bb82", + "sequence_number": "962110457275232569", "payload": { "EntryFunction": { "module": { - "address": "1315b5634efb86a795e4749502a4ff68ae21be5eacafdd0918a62ae30b2cee16", - "name": "QEwKmxRbKqGf_Coin" + "address": "18555a7871db21a99322bb78de2e6ee32a9177e3adc1b3cf4a95daa28d99620e", + "name": "jKxRkeyEwloYVNYHsOU_Coin" }, - "function": "wNJssxWYothgPcCvzFSShzGow4", + "function": "bvbStM8", "ty_args": [ - { - "vector": { - "vector": "u64" - } - }, - { - "struct": { - "address": "b6a9ffe42c37328236ded3541f53c4dfcafc1ed2b98e8ae60d88a924d4358770", - "module": "KJgeafEmPj9", - "name": "VcHIpsG2", - "type_args": [] - } - }, - { - "struct": { - "address": "1dcc7e87dd156b95fcde81923c41229cb6597fe4a02adf40edb8447cdc4a3ca3", - "module": "EjtGgJAiABYrDtiTwU4", - "name": "rBhRXVdUsUDUkMFeBxjaErKaJGZa", - "type_args": [] - } - }, { "struct": { - "address": "63214b2b7d07b27bcf2046f258649a57f340bb0e0ab053cb715bcc17a1315514", - "module": "tFiU2", - "name": "MeAVZYYLSIfQoayzcG", + "address": "949f538bf19fd0d70ec0510b59cb529074f9a2fff15baa89958bec15aa733701", + "module": "ijUWsk9", + "name": "CtPsMrSIcpHNItzJbOOHgnVooHF", "type_args": [] } } ], "args": [ - "9536a1911eda0576", - "5aa2fd34b33a6339" + "00", + "7f75155ae7c9efcaafe38ca5c356d10e", + "a7c4b617e463e05e", + "05c0a1bded20a406484b9a11764c6c06", + "ecfb00e9235da9cd7864b76f6e61fed7", + "4b7688f02fddeddd", + "01", + "33", + "4bf362b461c53493" ] } }, - "max_gas_amount": "1529263278239304793", - "gas_unit_price": "12665888032592171223", - "expiration_timestamp_secs": "16745816932938102590", - "chain_id": 57 + "max_gas_amount": "6693488240307777576", + "gas_unit_price": "14234577073664709025", + "expiration_timestamp_secs": "488493618113310900", + "chain_id": 188 }, - "signed_txn_bcs": "e50cf2f58c8f60f51778ded644606ec4c51179114d9837196addc43f1d92440768d41e876e77d852021315b5634efb86a795e4749502a4ff68ae21be5eacafdd0918a62ae30b2cee16115145774b6d7852624b7147665f436f696e1a774e4a73737857596f746867506343767a465353687a476f77340406060207b6a9ffe42c37328236ded3541f53c4dfcafc1ed2b98e8ae60d88a924d43587700b4b4a67656166456d506a3908566348497073473200071dcc7e87dd156b95fcde81923c41229cb6597fe4a02adf40edb8447cdc4a3ca313456a7447674a416941425972447469547755341c7242685258566455735544556b4d466542786a6145724b614a475a61000763214b2b7d07b27bcf2046f258649a57f340bb0e0ab053cb715bcc17a1315514057446695532124d6541565a59594c534966516f61797a63470002089536a1911eda0576085aa2fd34b33a633959cc8063d9083915d71087130f46c6af3e377f01c71765e839002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ceda275cafb02f650b06e82765eaf41a7c98eb20dc9efb5f376b5a1ce46415d91d8209bf7cad2ff7a1b9650f46a16cc4f0f021013d6e0dcd0ae89424c833fa09", + "signed_txn_bcs": "a42daed21bdedd449e3c50a9c59393c7c0837a733ca640360d6aa41c19a2bb82393194085d1a5a0d0218555a7871db21a99322bb78de2e6ee32a9177e3adc1b3cf4a95daa28d99620e186a4b78526b657945776c6f59564e5948734f555f436f696e0762766253744d380107949f538bf19fd0d70ec0510b59cb529074f9a2fff15baa89958bec15aa73370107696a5557736b391b437450734d7253496370484e49747a4a624f4f48676e566f6f484600090100107f75155ae7c9efcaafe38ca5c356d10e08a7c4b617e463e05e1005c0a1bded20a406484b9a11764c6c0610ecfb00e9235da9cd7864b76f6e61fed7084b7688f02fddeddd01010133084bf362b461c5349328b0cc47170ce45ca151b4336e608bc5b470b0865b7ac706bc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407a9335924968b0732f5a080b358a1c9a23d01e23338a8a0812bfd0891682f40d718e8868e6a703c308398ba948a792f8b0b0e4c862dc324217170bade0fa6207", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" } ] diff --git a/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json b/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json index 12d27c6ad06..e471267bfa6 100644 --- a/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json +++ b/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json @@ -1,346 +1,371 @@ [ { "raw_txn": { - "sender": "3677c13bc493651612ace666edf6df7d5487b8c879190e076e9ad821df7b10c1", - "sequence_number": "7368908614509515972", + "sender": "2729dccd25b898c50a4817ac2e2da58483cc8ce1a5fa27c38e49ad5467c2f62c", + "sequence_number": "5705042828739947510", "payload": { "Script": { - "code": "d14669faf5d7bcc3e0ef6f2b5fbf4e", + "code": "140f8872", "ty_args": [], "args": [ { - "Bool": true - }, + "U128": "261704167350626216139117546641434913030" + } + ] + } + }, + "max_gas_amount": "13830445450937936658", + "gas_unit_price": "12586797386046485072", + "expiration_timestamp_secs": "717113376446464636", + "chain_id": 71 + }, + "signed_txn_bcs": "2729dccd25b898c50a4817ac2e2da58483cc8ce1a5fa27c38e49ad5467c2f62cf62b6fe339622c4f0004140f887200010206a9908b8499aa41290f83b3a563e2c412ab925cdc9cefbf50b21def8849adae7cc2c502d1b2f30947002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019e332a536e7a5319ff7935050262a5782743122074ea1dec72e396f9c332b77cb7e570751e2bf7fc6f151c347c6522c4b3571f587f90ee7f8d8d3d26ab2450c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "2a1a0ccf1756448be98bd597c5ed528d3d6da03cfb63e9a2ea40507a83593ac5", + "sequence_number": "16614609060284234275", + "payload": { + "Script": { + "code": "b3c2b6a493a64a", + "ty_args": [ { - "U8Vector": "1ada43" + "vector": { + "struct": { + "address": "8713ef270a2c14cca1e2887d73a54b32671c2708971cf076d40326aac136fce4", + "module": "S3", + "name": "YvJFrYPdeKTvW", + "type_args": [] + } + } }, { - "Address": "cc8b2b138d80f546f8acf863d0485e58082290a8e418e93c0c79784c0a98ccbc" + "struct": { + "address": "4a2d581f1f10299989d0a73bf6665aa46e3242c19ef02cee8612c5e189318f61", + "module": "RWhyXlQlZOrxTtogqfPa", + "name": "zHyS", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "cb9d5c0e6a5ed6f8860e0e27660a2b712e0254b1b86ee1dc2d20e98ee41c088a", + "module": "WpvvErMMQKulDxAeAi5", + "name": "cMD3", + "type_args": [] + } }, { - "U128": "315385698958223888496209828405063395858" + "struct": { + "address": "ea12520a6c2df57589429329b35154a30cc8a24eaa7fec9fd8dba1fbf6615d4b", + "module": "DBWEotdUgxeFGOmSgXVanZgmmjNIq6", + "name": "UepisP", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "6bba16f836d6fd28be7403e6da1f1740b3274a727934637d853b8642c789c387", + "module": "ZlORXKfXpwkK", + "name": "Bqwr", + "type_args": [] + } }, { - "U8": 62 + "vector": { + "vector": { + "vector": "signer" + } + } }, { - "U8": 160 + "vector": { + "struct": { + "address": "37b4cf18e28c88a631cbee996ed7236addecc4327a1f889caf5480810049fba8", + "module": "YyKMOivPyELeAeLbWOnQEneOXF", + "name": "aUMdXCqRF", + "type_args": [] + } + } }, { - "U8": 216 + "struct": { + "address": "4e36310b49e197b6ba356f28da0af750165c98a4090e831de802db5b9f658be3", + "module": "obpiLuLpynLeiySvAoGdddUZRvIY", + "name": "JgbqmslEqliXE4", + "type_args": [] + } + } + ], + "args": [ + { + "Address": "3bcb2090dc01c4e2f6c6601047e5df19d2395188bc788e57184e12a7c2157076" } ] } }, - "max_gas_amount": "3632834521076475754", - "gas_unit_price": "12742885074082071529", - "expiration_timestamp_secs": "12222167853736003849", - "chain_id": 232 + "max_gas_amount": "7870293755328302448", + "gas_unit_price": "10031130616132128983", + "expiration_timestamp_secs": "1873221992609571222", + "chain_id": 14 }, - "signed_txn_bcs": "3677c13bc493651612ace666edf6df7d5487b8c879190e076e9ad821df7b10c1c4d427be579f4366000fd14669faf5d7bcc3e0ef6f2b5fbf4e0009050104031ada4303cc8b2b138d80f546f8acf863d0485e58082290a8e418e93c0c79784c0a98ccbc050002122a57179bf2e9d4156b48957f1345ed0500003e00a000d86a278ad4bf6b6a32e9034ace75d2d7b00909223be8dc9da9e8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fae8669b12f59ff55096893b9f6a30df5e11f81fb00d3477ef94bfa5aa7d6975e6f719132e4ba950c87c2d84467aa6d37b1b210f910709d37cd0d99c594f5a0d", + "signed_txn_bcs": "2a1a0ccf1756448be98bd597c5ed528d3d6da03cfb63e9a2ea40507a83593ac5237a3a90e9f292e60007b3c2b6a493a64a0806078713ef270a2c14cca1e2887d73a54b32671c2708971cf076d40326aac136fce40253330d59764a4672595064654b54765700074a2d581f1f10299989d0a73bf6665aa46e3242c19ef02cee8612c5e189318f611452576879586c516c5a4f727854746f6771665061047a4879530007cb9d5c0e6a5ed6f8860e0e27660a2b712e0254b1b86ee1dc2d20e98ee41c088a135770767645724d4d514b756c4478416541693504634d44330007ea12520a6c2df57589429329b35154a30cc8a24eaa7fec9fd8dba1fbf6615d4b1e444257456f74645567786546474f6d53675856616e5a676d6d6a4e4971360655657069735000076bba16f836d6fd28be7403e6da1f1740b3274a727934637d853b8642c789c3870c5a6c4f52584b665870776b4b04427177720006060605060737b4cf18e28c88a631cbee996ed7236addecc4327a1f889caf5480810049fba81a59794b4d4f69765079454c6541654c62574f6e51456e654f58460961554d64584371524600074e36310b49e197b6ba356f28da0af750165c98a4090e831de802db5b9f658be31c6f6270694c754c70796e4c6569795376416f47646464555a527649590e4a6762716d736c45716c695845340001033bcb2090dc01c4e2f6c6601047e5df19d2395188bc788e57184e12a7c2157076708d51cc78e6386dd7d019ee25bc358b9661f13e7a05ff190e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444017f34220abb3d7c7af5f2a94316b97ebf086d12d25fbb896361473d957ed5f87481df0568a8f7caf0c5596aa99d51a0ced192d1a568ac18652636c82331bb603", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7ac465126a334a70eee1b07d1a1989771e1518edc598e263e24150e59c4f0f6f", - "sequence_number": "13441949339655375926", + "sender": "a7cca0278bb399cfa9ee82a0eea6c90cfa20a7bcbfd9b60b4c87d65cf28bbb51", + "sequence_number": "5310585696735356372", "payload": { "Script": { - "code": "d873cf24d7ad9a749d9aa5cd29f5e8cb", + "code": "d0", "ty_args": [ { - "vector": { - "vector": "bool" + "struct": { + "address": "9a6f279399cf5d6e585e9a87fde31cdb49362e8835569bcba367f3709feecc2a", + "module": "OXwfUsxKF2", + "name": "vOxvMzbkmUpVGIiSUMNBvXqDDL", + "type_args": [] } - } - ], - "args": [ - { - "Bool": true - }, - { - "U8Vector": "01d042c4" }, { - "U8": 192 + "vector": "bool" }, { - "U64": "617923059089471977" + "vector": { + "struct": { + "address": "dee55c3b1b7a1616f3661ba2d5d8ee931999c75881fa59bc3d06da50a289c9c1", + "module": "nZklZhKAwcx", + "name": "ZaqGZLXqbVIez", + "type_args": [] + } + } }, { - "U64": "1598632091548018378" + "struct": { + "address": "89e8154e9f0ab0f0edd4ca6a08109679c84989d6f0d4dac289826566d76ed712", + "module": "x0", + "name": "tMeP8", + "type_args": [] + } }, { - "U64": "16796681836754028853" + "struct": { + "address": "2a4340fabbdda0b6348a6c806f39103cf15787ba8173747a54d40d3355dca586", + "module": "BaPmNIaQwnaOzxFlw", + "name": "xClSXgXEGfJOFYZOtnjgBFNsDsQsAT1", + "type_args": [] + } }, { - "Address": "5eac1204eded4d878683d24ea4b48d8f606e6e4ac01c5100865ba04dc798226c" + "vector": { + "struct": { + "address": "4f765754fcd331bca469603a4af73603539a5bf5e9f1e5da8582c1a434fe94a9", + "module": "VSKgoNxnGwVNrVzOqAjIU5", + "name": "SdmcUYZrd", + "type_args": [] + } + } }, { - "Address": "bc53656662b19e30a91463bd658e7dad8cd266507a8991812cc5f4530268d3c0" + "vector": { + "struct": { + "address": "c5dd214165b0115f0e0fb21e6e23f29321c5cfc5665b527e9facbe093f5902af", + "module": "AuZMhKSHnVBdEaxjBh4", + "name": "qVKuEsAhMWQSUOImiDvIwPUKkw9", + "type_args": [] + } + } } - ] - } - }, - "max_gas_amount": "2379161332701705344", - "gas_unit_price": "15831352416342365390", - "expiration_timestamp_secs": "12632939087256464513", - "chain_id": 222 - }, - "signed_txn_bcs": "7ac465126a334a70eee1b07d1a1989771e1518edc598e263e24150e59c4f0f6f368cf4b6b4658bba0010d873cf24d7ad9a749d9aa5cd29f5e8cb01060600080501040401d042c400c001e9f98c93bf4d930801ca6642d76a7b2f160135c9fa4c23cd19e9035eac1204eded4d878683d24ea4b48d8f606e6e4ac01c5100865ba04dc798226c03bc53656662b19e30a91463bd658e7dad8cd266507a8991812cc5f4530268d3c080b40773a07a0421ced41b022543b4db81ac11ed2a3751afde002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440818825720e7bd76df57e1ff092bf82f5275b7fdc9c30d0747989b4eb0a52be706c27775bdac614a433b098ca52be51d4fe7f96dc7b78a46ddc32a2eb6fe04004", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c1ba58be8f01dae46304ef12e16f5ef0edcf7e41e745a4e2449a061797a804dc", - "sequence_number": "9388239715593337979", - "payload": { - "Script": { - "code": "4d2a7adaf0540f0f2b85e0acc2cd", - "ty_args": [], + ], "args": [ { - "Address": "30571cb038bae02be546e861058a5c326108632029a7ab397ad2c581df4e8fde" + "U128": "25680354967437262440103972820965337728" }, { - "Bool": true + "U8Vector": "a26bde0ea1eaae47120ad576faa9" }, { - "U128": "315909425913736247369136596642703600253" + "U8": 162 }, { - "U8Vector": "132c7da6" + "U64": "1305168316212991399" }, { - "U128": "2920741250566672498145397932276312518" + "Address": "046214b96f7e55a6ed579b630f38a740bc6f8ec0b7cbaccdd8150c2f0ee72ece" }, { "Bool": false }, { - "U128": "195793708823119404329594645648077531660" - } - ] - } - }, - "max_gas_amount": "15156470291225489005", - "gas_unit_price": "12860663242782441493", - "expiration_timestamp_secs": "9814150118819918291", - "chain_id": 173 - }, - "signed_txn_bcs": "c1ba58be8f01dae46304ef12e16f5ef0edcf7e41e745a4e2449a061797a804dc7bbc27c247ba4982000e4d2a7adaf0540f0f2b85e0acc2cd00070330571cb038bae02be546e861058a5c326108632029a7ab397ad2c581df4e8fde0501027dea5fd946c645eee0a9471b3bf1a9ed0404132c7da602c6e9eff28181510de1a2b063a98332020500020caae81f7d51aeb1540c810f267f4c936dae416d6d9956d21580f8a114417ab2d3719e1489dd3288ad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bf81c2ababc8192cf17a91ceefaee539c3004906d1391c1d78a34b1e218b6fcc2668bb06f88c200f7213b7e72b5a9d733313513046bbadedc66628cf82c18e0d", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c48a7e4388eeb87b4911d0d7e06d71bde41140470e89185e2c2c427d07d0f837", - "sequence_number": "11109762177366031093", - "payload": { - "Script": { - "code": "a122d96f968ebca5", - "ty_args": [], - "args": [ + "Bool": false + }, { - "U128": "45077997921317895071198074102829683367" + "Bool": false }, { - "U8": 167 + "U128": "194090749148390769775460304387217641849" }, { - "U128": "94599078468267412910149511684199585296" + "Bool": false } ] } }, - "max_gas_amount": "3220965574846946392", - "gas_unit_price": "3980648369345363322", - "expiration_timestamp_secs": "10188780789372192095", - "chain_id": 66 + "max_gas_amount": "4879103659518400818", + "gas_unit_price": "10044714951574220916", + "expiration_timestamp_secs": "18004133680754939116", + "chain_id": 192 }, - "signed_txn_bcs": "c48a7e4388eeb87b4911d0d7e06d71bde41140470e89185e2c2c427d07d0f837f5faf898d6cd2d9a0008a122d96f968ebca5000302a7127add6dec2f483cd8a3eee3b4e92100a70210967484f95d1b2b9e5eddc6aa1e2b47589c83fa1f2bb32c7a7d91fe991a3e375f85da3c25d2658d42002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440803c5c4b9aafe22535c018121013a577d3d6120a0cd78120552d7ee67045f23c0fa1b8c15e1d1862b8d09f47d023beb84cc230f10b458872324f263292d6000f", + "signed_txn_bcs": "a7cca0278bb399cfa9ee82a0eea6c90cfa20a7bcbfd9b60b4c87d65cf28bbb51d4652ef38dfdb2490001d007079a6f279399cf5d6e585e9a87fde31cdb49362e8835569bcba367f3709feecc2a0a4f5877665573784b46321a764f78764d7a626b6d55705647496953554d4e4276587144444c0006000607dee55c3b1b7a1616f3661ba2d5d8ee931999c75881fa59bc3d06da50a289c9c10b6e5a6b6c5a684b417763780d5a6171475a4c5871625649657a000789e8154e9f0ab0f0edd4ca6a08109679c84989d6f0d4dac289826566d76ed71202783005744d65503800072a4340fabbdda0b6348a6c806f39103cf15787ba8173747a54d40d3355dca586114261506d4e496151776e614f7a78466c771f78436c535867584547664a4f46595a4f746e6a6742464e73447351734154310006074f765754fcd331bca469603a4af73603539a5bf5e9f1e5da8582c1a434fe94a91656534b676f4e786e4777564e72567a4f71416a4955350953646d6355595a7264000607c5dd214165b0115f0e0fb21e6e23f29321c5cfc5665b527e9facbe093f5902af1341755a4d684b53486e5642644561786a4268341b71564b75457341684d575153554f496d694476497750554b6b7739000a02802a8f0cc5d058be1af15f0e41db5113040ea26bde0ea1eaae47120ad576faa900a201a755f823abe31c1203046214b96f7e55a6ed579b630f38a740bc6f8ec0b7cbaccdd8150c2f0ee72ece05000500050002795105e5e2647a5556e97117c184049205003219e77fed0eb64374f0a27e07ff658bec540b523188dbf9c0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e07ef3e5c7f5363ac19b49de4e2c74daa7e0dc4d0a5a72fa551393dc7b4b193a6ac3d162504df0afdac73429cfb7c8ea2192f8f89cb5316171b592e487650005", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bb0ba357d91acbb2f5f0a7b988f5ae9a5bea8c18a9a5ce5c5a2513cc57314cba", - "sequence_number": "6093216383570124492", + "sender": "0486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d6", + "sequence_number": "665348431662327138", "payload": { "Script": { - "code": "9f3ee6a2df1da127bee0e32fdd5ff4", + "code": "cf8cf3", "ty_args": [], "args": [ { - "U8": 126 + "U64": "11707063606211854951" + }, + { + "U128": "139620163540106684070863785733306811456" + }, + { + "U128": "111931529506956067538841559824815852142" + }, + { + "Bool": false + }, + { + "U8Vector": "04bdeebfdc35eb" + }, + { + "Address": "c9db5e6e2c0079a6d255f07b997471c4cfc36417dd58fa94b1cff6b7ee6e9357" }, { - "U8": 252 + "U8Vector": "a8cdc5dcdc" } ] } }, - "max_gas_amount": "1625956033161485284", - "gas_unit_price": "13144010732074727349", - "expiration_timestamp_secs": "197079322304101729", - "chain_id": 38 + "max_gas_amount": "1083417168633788325", + "gas_unit_price": "1923148079119374375", + "expiration_timestamp_secs": "4591469829133248893", + "chain_id": 193 }, - "signed_txn_bcs": "bb0ba357d91acbb2f5f0a7b988f5ae9a5bea8c18a9a5ce5c5a2513cc57314cbacc9e498204748f54000f9f3ee6a2df1da127bee0e32fdd5ff40002007e00fce45bfec0658e9016b5773cf11ee868b661bd8276992abc0226002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a06b4362aac78a7d1c35aee2d2c9dad50c933ff2fafd3c38b555d17020df09e417fce322ca008244a91e8b8ab0bd3703a537f9d65442f224a0675cb214fddd0a", + "signed_txn_bcs": "0486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662a51899dfca3b090003cf8cf3000701674229bb52d877a2024084a5a647bb85d80e59c38e89dd0969026e8a6bc7aeb0b0c03236b9087b3a35540500040704bdeebfdc35eb03c9db5e6e2c0079a6d255f07b997471c4cfc36417dd58fa94b1cff6b7ee6e93570405a8cdc5dcdca5f7f9b72c12090f2798621afd64b01a7d2969a27b2db83fc1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cbaed7a0fdfe7bce9ef37dce398c8effaf69b4e55401f893defd89263f98312a6d1f6fad2b1c3e1e4deaa5a383e83ef2f6a592b62ea1ab4438d53fda06804a0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e07128e285ac3faa0dd2dfee7664b266b296ad121a58ce14affd267e6e82f0cb", - "sequence_number": "17784040071166682866", + "sender": "1a58ce14affd267e6e82f0cbf23810e5949a23a8ae74b6ed1c56ab183db9c3fd", + "sequence_number": "2456727406725119419", "payload": { "Script": { - "code": "2ec0711303", + "code": "f3e7b6e3a6b2b53da76dc9", "ty_args": [ { "vector": { "vector": "u8" } }, - { - "vector": { - "struct": { - "address": "f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662df", - "module": "oYezCOpm", - "name": "CCfVnyTZRPIQiIshitFGtfMxcMDvjY", - "type_args": [] - } - } - }, { "struct": { - "address": "817f8b397e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f3", - "module": "yNNPhfaMRtNQMgW6", - "name": "lfrRILbqMaLRMeWPqwDoQxtLslCurkL1", + "address": "e9ba2bc7dfe32acfe41ab6d433b327feb8ecaa9493803032f9de6d852ae78c4e", + "module": "pCQBcWjHieaAvLGpMAtbSVO8", + "name": "xMVlkxypvn", "type_args": [] } }, { - "vector": { - "vector": "u64" - } - }, - { - "vector": { - "vector": "bool" + "struct": { + "address": "faad1bf563f2deacb647cd571ffec31d31e460d7c16f1c19afd2a1432027935c", + "module": "Jc", + "name": "QGQwaKDOjRsbZWQbwdYcVQHoaEokDcix", + "type_args": [] } }, { "struct": { - "address": "45317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067028380b2", - "module": "QQevQeQbQw0", - "name": "WzDFa4", + "address": "a13e92589ba3e02a71e2a29e20c3747b7ef84cdbd971eb1e97c0199215c685ec", + "module": "WqjVIkkkwChmIqtTsvTB", + "name": "ZzEwAuItNuyahCbzv", "type_args": [] } }, { "struct": { - "address": "68150a87dea4460a5c3760070a38003f78f7ebb012661fd8a762f284dbff22db", - "module": "Ss0", - "name": "sExASogoTWc", + "address": "decde1f145317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067", + "module": "GIlQARFPNbhsUeQGmuxd8", + "name": "jhQUDqUqYoRH7", "type_args": [] } } ], "args": [ { - "U8": 179 + "Address": "964d43a10e68dc5948292613116170513e9ba4afa713c0f545a0f11d8b2ca978" }, { - "U128": "41913946970560315782656879538600815227" + "U8Vector": "cce80534" }, { - "U128": "30241266543890506402994956609964705390" + "U8": 18 } ] } }, - "max_gas_amount": "13609061798892567444", - "gas_unit_price": "4445232778290510883", - "expiration_timestamp_secs": "8402715135250614288", - "chain_id": 174 + "max_gas_amount": "3664686011449254850", + "gas_unit_price": "15579694643738237657", + "expiration_timestamp_secs": "13256897693341282297", + "chain_id": 38 }, - "signed_txn_bcs": "e07128e285ac3faa0dd2dfee7664b266b296ad121a58ce14affd267e6e82f0cbf2e63389389acdf600052ec0711303070606010607f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662df086f59657a434f706d1e434366566e79545a52504951694973686974464774664d78634d44766a590007817f8b397e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f310794e4e506866614d52744e514d675736206c667252494c62714d614c524d6557507177446f5178744c736c4375726b4c31000606020606000745317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067028380b20b515165765165516251773006577a44466134000768150a87dea4460a5c3760070a38003f78f7ebb012661fd8a762f284dbff22db035373300b73457841536f676f545763000300b3027b2adec82922e4795c3397602255881f026e86271dfd2be67734bbda698e41c016947b54299a19ddbc23bcedf5a8a3b03d10486961e5709c74ae002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401cb34c68fa5060af7f805c5a86cd6363f64b0bc25b291a5ac0a60e6165856b67dd16209cd97a85853f00a57e95f7d0b1ee8ae4c874e6edf821d339367b546d09", + "signed_txn_bcs": "1a58ce14affd267e6e82f0cbf23810e5949a23a8ae74b6ed1c56ab183db9c3fdbb3dd1638f0c1822000bf3e7b6e3a6b2b53da76dc90506060107e9ba2bc7dfe32acfe41ab6d433b327feb8ecaa9493803032f9de6d852ae78c4e187043514263576a4869656141764c47704d41746253564f380a784d566c6b787970766e0007faad1bf563f2deacb647cd571ffec31d31e460d7c16f1c19afd2a1432027935c024a632051475177614b444f6a5273625a575162776459635651486f61456f6b446369780007a13e92589ba3e02a71e2a29e20c3747b7ef84cdbd971eb1e97c0199215c685ec1457716a56496b6b6b7743686d4971745473765442115a7a4577417549744e7579616843627a760007decde1f145317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f910671547496c51415246504e626873556551476d757864380d6a68515544715571596f524837000303964d43a10e68dc5948292613116170513e9ba4afa713c0f545a0f11d8b2ca9780404cce805340012c2a3c6d58294db32d9da12d5bb3136d8f96f4dcb36f6f9b726002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f25ff5407d7efd132feac98e712957c7ad2bd5b13cbd63a0c62f0c511cc775b34530a44c9915c40d59fda7a6cc5c0c1976ff6c947b24d2ab2e9c37eef1559d0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1f8e6a9fa279601985378ee664f2348d551ab93a96e6f70bcf771b234c23bfe0", - "sequence_number": "16950474678649250918", + "sender": "2aabddb611f372855b53d7e160c266cda6010b855e2a4f8641bc3f8e01a399e3", + "sequence_number": "4608167762538335583", "payload": { "Script": { - "code": "d29d157c4fd8bc", + "code": "42f91d7c2bfeec4dfdb0fefb", "ty_args": [ { "vector": { - "struct": { - "address": "05ecfc3048baf2edccacddbfe85b751f5582795cd472e392337cd245b6f2aada", - "module": "YNCGGjPIwQgLPmwrEL7", - "name": "YzQEdhxbqWsWZZFpTzRqCaZKaRPFOjxM2", - "type_args": [] + "vector": { + "vector": "u8" } } }, { - "vector": { - "vector": "u8" + "struct": { + "address": "7ba4b4100047139fc611ff753fe48861986324b6dbbf242675a18d06a36f4960", + "module": "OtCchPZxHm", + "name": "SqGMsrtEKaSfGZvUYIbdnHoVCtKGrykp5", + "type_args": [] } }, { "struct": { - "address": "277f1829044362989e4b910e041d097b57a14f62ee36bc620168d62da4eb7302", - "module": "iwzUkFwVWiTwAAwROlmPTYwDObVsSUP", - "name": "MlDaEdfRgtSmrtkmJvdVpewARsuVkV5", + "address": "48f0cb8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad", + "module": "TpTEasGAPRawKeJyKqb3", + "name": "NTektcsw", "type_args": [] } - } - ], - "args": [ - { - "Bool": true - }, - { - "U128": "228895819552789049808880313259319031790" - }, - { - "U64": "6732905901992753485" }, - { - "U64": "5422052687078449972" - } - ] - } - }, - "max_gas_amount": "9178518397033043993", - "gas_unit_price": "3848803411630323426", - "expiration_timestamp_secs": "11840717114376118439", - "chain_id": 78 - }, - "signed_txn_bcs": "1f8e6a9fa279601985378ee664f2348d551ab93a96e6f70bcf771b234c23bfe0666424abe92e3ceb0007d29d157c4fd8bc03060705ecfc3048baf2edccacddbfe85b751f5582795cd472e392337cd245b6f2aada13594e4347476a50497751674c506d7772454c3721597a514564687862715773575a5a4670547a527143615a4b615250464f6a784d320006060107277f1829044362989e4b910e041d097b57a14f62ee36bc620168d62da4eb73021f69777a556b46775657695477414177524f6c6d50545977444f6256735355501f4d6c4461456466526774536d72746b6d4a76645670657741527375566b56350004050102eef706ee7c9c70f6dc55979e36bb33ac014db968d23e16705d013463c30e31003f4b19d88a2bdaa5607fe27689a04fb26935a7e046107bad52a44e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f15c8c4e596a491ce24b9b92a71e33a9a8b159742ea12d52df4e231b9909bc2dbc71a2eb4e9ba810f94c4afa14ed8f81f92debd980d866565eed5ee19296bc0f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "bc7990945a2e63ff6356cad8e00e3701531221a2e6d0c620c0b3b396fb53ba7d", - "sequence_number": "17545374257061755347", - "payload": { - "Script": { - "code": "7ad1abad", - "ty_args": [ { "vector": { "struct": { - "address": "d14cf0994a93163142d24e60d61d85e76c98db2b7bf6fdca6c8f5bd53f1266d3", - "module": "VGPAbSWbKYiTHPUNWD", - "name": "BwWeQHONmhtKbclefwRf5", + "address": "7cd245b6f2aadaf5b5b889bbe6685d273d2ac50fb8cbdb6f8fa053ef9a4c1c2a", + "module": "AADkbuZnnMItlokObZwQXRlwYVqRQJwy7", + "name": "oFsvYqa6", "type_args": [] } } @@ -348,116 +373,122 @@ { "vector": { "struct": { - "address": "cefb54736f58b4f5f109191849af0f45ad159806219e55ee2dd528e6170bb50c", - "module": "mNiOyPs", - "name": "PMGSdzoXnIcTQ", + "address": "b0af757b2577c913940e16e53c26c13c601721b758a65d98992b395e5011dd3f", + "module": "kSXbuyBKc", + "name": "y0", "type_args": [] } } }, - { - "struct": { - "address": "66c5f841dc5f5f16127f4c980ada4799163f76377a87451288edbbef7d312b87", - "module": "sEKszBDzbxSdv2", - "name": "fUU6", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "1303d5aaca229ec93e9b9e50cb0e84a11633686d652280867781bdb1fed38a7b", - "module": "mBAxmhhbiieZcZNfX0", - "name": "FcPMRJTEWiEThOYfdtzDLW", + "address": "34083de9a25920bfbc71b98948a6b9a227dd6fe970c015892abe8d3f7227979a", + "module": "rpwixScZ6", + "name": "Fv", "type_args": [] } } }, { "vector": { - "struct": { - "address": "3fad006d5433de2340b293361e7d83ca1d957a1ec59320443082812d784ee6e3", - "module": "cpKYfDCif", - "name": "zaoCdBmXPjJ", - "type_args": [] + "vector": { + "vector": "u128" } } }, { "struct": { - "address": "e6d5cae8d1d1a24d30ac0a8398bcea3c3f867f2aa7f17350be0241c0367b68ff", - "module": "NeTfOUZbDKnh", - "name": "EhPAuKoRlHgDqGCPCsLyP5", - "type_args": [] - } - }, - { - "struct": { - "address": "125f4a403ddf3a0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0", - "module": "m", - "name": "iPRSZTBSYwhW", + "address": "08bd580c714f642f28579c0649a3ed597aa502ed2454c3755d153630812625b5", + "module": "AMnzFbFlfLxTTExbOvMn", + "name": "WtkcPjvjehPSvaNVEXwPCH8", "type_args": [] } - }, - { - "vector": { - "struct": { - "address": "96fd5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418a", - "module": "kFEKnJFyH", - "name": "GWqQZyNGBRPQ", - "type_args": [] - } - } } ], "args": [ { - "U8": 87 + "U8": 55 + }, + { + "Bool": true + }, + { + "U64": "9742342893388317998" }, { - "U128": "28392322025090209641960477563633994233" + "Bool": true }, { - "U128": "233132878765093455377962454144140377008" + "U128": "66131818607320732354043527631890030391" }, { - "U64": "12971809279381426289" + "U64": "8536089777481325465" }, { - "U8Vector": "db80dcc7997c5fcee3774ed345" + "U64": "6368203391322889181" }, { - "U64": "13300572078824693014" + "U64": "279191632959094547" } ] } }, - "max_gas_amount": "16008713040735597115", - "gas_unit_price": "6125932074628081907", - "expiration_timestamp_secs": "4040826562623066682", - "chain_id": 84 + "max_gas_amount": "9253418150885725265", + "gas_unit_price": "12828784947872612421", + "expiration_timestamp_secs": "750545610171665819", + "chain_id": 202 }, - "signed_txn_bcs": "bc7990945a2e63ff6356cad8e00e3701531221a2e6d0c620c0b3b396fb53ba7dd3f9726bedb07df300047ad1abad080607d14cf0994a93163142d24e60d61d85e76c98db2b7bf6fdca6c8f5bd53f1266d31256475041625357624b5969544850554e5744154277576551484f4e6d68744b62636c656677526635000607cefb54736f58b4f5f109191849af0f45ad159806219e55ee2dd528e6170bb50c076d4e694f7950730d504d4753647a6f586e49635451000766c5f841dc5f5f16127f4c980ada4799163f76377a87451288edbbef7d312b870e73454b737a42447a62785364763204665555360006071303d5aaca229ec93e9b9e50cb0e84a11633686d652280867781bdb1fed38a7b126d4241786d6868626969655a635a4e665830164663504d524a544557694554684f596664747a444c570006073fad006d5433de2340b293361e7d83ca1d957a1ec59320443082812d784ee6e30963704b5966444369660b7a616f4364426d58506a4a0007e6d5cae8d1d1a24d30ac0a8398bcea3c3f867f2aa7f17350be0241c0367b68ff0c4e6554664f555a62444b6e681645685041754b6f526c4867447147435043734c7950350007125f4a403ddf3a0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0016d0c695052535a5442535977685700060796fd5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418a096b46454b6e4a4679480c475771515a794e47425250510006005702f90927ffd342213c55f024aa8d295c1502b0fbba53a6947adb16be78785cc263af017150a5dfcf1f05b4040ddb80dcc7997c5fcee3774ed34501161dd313d61f95b83b723558b15f2adef3e860eac3ae03553a521c7859e6133854002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402ef7f01ba5b5f6d5c9d04910ec6080fdbd3514e613e530b5f1b95ad7de96f9450d78e373ab4c62905116892697e155a70b952f2d6ad04123111940923d86c10e", + "signed_txn_bcs": "2aabddb611f372855b53d7e160c266cda6010b855e2a4f8641bc3f8e01a399e35f0d81372a80f33f000c42f91d7c2bfeec4dfdb0fefb0806060601077ba4b4100047139fc611ff753fe48861986324b6dbbf242675a18d06a36f49600a4f74436368505a78486d215371474d737274454b615366475a7655594962646e486f5643744b4772796b7035000748f0cb8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad145470544561734741505261774b654a794b716233084e54656b746373770006077cd245b6f2aadaf5b5b889bbe6685d273d2ac50fb8cbdb6f8fa053ef9a4c1c2a214141446b62755a6e6e4d49746c6f6b4f625a775158526c7759567152514a777937086f46737659716136000607b0af757b2577c913940e16e53c26c13c601721b758a65d98992b395e5011dd3f096b5358627579424b6302793000060734083de9a25920bfbc71b98948a6b9a227dd6fe970c015892abe8d3f7227979a09727077697853635a3602467600060606030708bd580c714f642f28579c0649a3ed597aa502ed2454c3755d153630812625b514414d6e7a4662466c664c7854544578624f764d6e1757746b63506a766a6568505376614e5645587750434838000800370501012e4576903ec13387050102371f806e8e32f515e646d1a56486c03101991b9e2d6d48767601dd1b3d853e6760580113bfc99a4fe3df035114b211c8be6a804540d3b5f0ff08b29bcd028241796a0aca002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e5cc017a8eeb9856fe456a261ed17b648d7165d3199aacee59e491f53911c8f20bb7cb59e2a30f1dd9c090bc96b47988c7f5d1868f3f5c413de902784ec4bc0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f95347eeeb2494465bcf9a46d602100d2dee62332f4047bab8674a7c8249d75a", - "sequence_number": "3431580643192205041", + "sender": "eb8b6d459630be1a6054d5a38a4e219b1badba23a6b46efdb6547069b8a00bb2", + "sequence_number": "5198429413034048659", "payload": { "Script": { - "code": "5097ee675259c000bbe0e3bf6aad", + "code": "ed1c227bbe66", "ty_args": [ + { + "struct": { + "address": "f6fdca6c8f5bd53f1266d392d55b7fbe7bb39bd3ee82e8db543c0a1cb5ffd90f", + "module": "onmsIS", + "name": "sFYBDSYrjOJNMzp", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "589b69209f3bd3dda63d4f42514b5e79d29c30b86f11de5beb4f3bb607714c2a", - "module": "y6", - "name": "QYUCYzlVjhHOhvfBzSsioaMuREnH", - "type_args": [] + "vector": { + "struct": { + "address": "c125da5d2951c5105a10836d39b82749289487eebe73ad4a3aa87cf295863fea", + "module": "fcHwQuNBdqHZmXeFTqDeoDJfCWn5", + "name": "kDranhwTsrWcNvqiGKO3", + "type_args": [] + } } } }, + { + "struct": { + "address": "bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e4", + "module": "NLZHfRRePhLtpH8", + "name": "InKOUtWKttONPLxDpORUygBjUfAZUzv", + "type_args": [] + } + }, + { + "vector": "signer" + }, + { + "struct": { + "address": "8106e32c84f676629587416c467d4dd4aaccd223935177e99707a26597b5cd4d", + "module": "byresAEiGssZaUMVcTjrGlK", + "name": "vEqdWldQuAInqJLolzaaipom5", + "type_args": [] + } + }, { "vector": { "vector": "u128" @@ -465,58 +496,117 @@ }, { "struct": { - "address": "b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13517667a0", - "module": "cEngMnzORtQRUQTkdJPPF5", - "name": "vOQuHEpMiqMbA", + "address": "0d113e9954d341f1c484d49ef783a376d4d17aae43af877dd0a0ef64edf301e3", + "module": "BEXhJcWHDnWiSQdPxNoO", + "name": "uSfvTxRUlW", + "type_args": [] + } + }, + { + "struct": { + "address": "c4a214697e460da917612558b12269ea8fd5dd6fe4271c8f262dfdc4e1417297", + "module": "vNGnrqrLlzmrxDRPCQ", + "name": "dPcebKrUpTlqHp", "type_args": [] } }, { "struct": { - "address": "a05e67668c21a36654c24b1441d11f53e1a28142507a75f42cf0f7ee4f3b26ce", - "module": "P", - "name": "hTFOZVSRwiKeWDtPKLGXDtAaLXrAtfMQ1", + "address": "0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0463984ff594e62", + "module": "GWVTMOJrCHgTknHbCcXZKhfxTzk0", + "name": "FW3", "type_args": [] } }, { "struct": { - "address": "f38a66eb91ea85caef654165a4ec5277e6e75b9744bf59affae477a73c569f1b", - "module": "ZVzVIHmQVcS8", - "name": "oARTMIaJqbyFrbVDBxJZYJugtDhJg", + "address": "273fcfafc03d424d5048d072c54d58090dad85418ae1cadefc37d0dca737df4a", + "module": "xEsHQiJxRJjsrPGRHHlkQEwokfG3", + "name": "dBGFZkZQoAtKgdIQYbr5", "type_args": [] } + } + ], + "args": [ + { + "U8Vector": "dc0b835efd8bffec9a9e" + } + ] + } + }, + "max_gas_amount": "16020561696894556420", + "gas_unit_price": "4902116123370541945", + "expiration_timestamp_secs": "9719021368655792451", + "chain_id": 107 + }, + "signed_txn_bcs": "eb8b6d459630be1a6054d5a38a4e219b1badba23a6b46efdb6547069b8a00bb2933cd639028824480006ed1c227bbe660a07f6fdca6c8f5bd53f1266d392d55b7fbe7bb39bd3ee82e8db543c0a1cb5ffd90f066f6e6d7349530f73465942445359726a4f4a4e4d7a7000060607c125da5d2951c5105a10836d39b82749289487eebe73ad4a3aa87cf295863fea1c6663487751754e426471485a6d586546547144656f444a6643576e35146b4472616e687754737257634e767169474b4f330007bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e40f4e4c5a486652526550684c747048381f496e4b4f5574574b74744f4e504c7844704f52557967426a5566415a557a76000605078106e32c84f676629587416c467d4dd4aaccd223935177e99707a26597b5cd4d1762797265734145694773735a61554d5663546a72476c4b1976457164576c64517541496e714a4c6f6c7a616169706f6d3500060603070d113e9954d341f1c484d49ef783a376d4d17aae43af877dd0a0ef64edf301e314424558684a635748446e576953516450784e6f4f0a75536676547852556c570007c4a214697e460da917612558b12269ea8fd5dd6fe4271c8f262dfdc4e141729712764e476e7271724c6c7a6d727844525043510e64506365624b725570546c71487000070eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0463984ff594e621c475756544d4f4a72434867546b6e48624363585a4b686678547a6b30034657330007273fcfafc03d424d5048d072c54d58090dad85418ae1cadefc37d0dca737df4a1c7845734851694a78524a6a737250475248486c6b5145776f6b66473314644247465a6b5a516f41744b67644951596272350001040adc0b835efd8bffec9a9e0419a195fb7754de79533745a4d0074443c928f370e6e0866b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b65b4c4ec89d6b38c40e8a65f8c78e1c884f798eaffe39e5e3f1065e7aabb6f4ea69a3ba3a14c1fad3af3c6ccdf20d66078a48662b6bc00c3c7d02874c38a009", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8d62ea7ad9d18690287e70e487a895d9ba2be639596704331e6d83707b5a6f68", + "sequence_number": "2572310825440540822", + "payload": { + "Script": { + "code": "ea2cfad47af4f76f", + "ty_args": [ + { + "vector": { + "vector": "u8" + } }, { "struct": { - "address": "7c548d772ec75da3918fa6c00fe1434ed304cb015522ea4bd35a40bb7cd8daff", - "module": "ymQVnikQNweC", - "name": "pVrwwnvVSzShlZHOeHNtdcNKMfAmv", + "address": "12531fbe37a26d3ffc41e39af8a1f50194906aa1aee74d999f64e6640182e21f", + "module": "pxp1", + "name": "TuShpodIQolkNBBEZwhPdaciVjyaYv2", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": "u128" } }, { "vector": { "struct": { - "address": "2ca7d5d82c407a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab", - "module": "dG", - "name": "hmHbammgZWESzMxvOjfPQSGjCbWIaSM8", + "address": "ee5d0374459724681daeffc9ba14e4293bb9a775867fcb2a9f6cffe8ae505f0e", + "module": "yUswDZXESjdusBciUy4", + "name": "mnnZqpLvLwZaeBi8", "type_args": [] } } }, + { + "vector": { + "struct": { + "address": "e96e83a5a47429ff4693c7f0cd3500b586f00007b39a493bc98552af4e0835f3", + "module": "Gq7", + "name": "qNLDPkTBbVvkBvJ9", + "type_args": [] + } + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "5069fb47d5620a2b8cb9a064ced887cc065c59ea5720eba6f9b890a36ecbe6d2", + "module": "DaeWFRDTnsCrbLzGPUGKMKZDn6", + "name": "pwYlNFMyEZbyIRyZ8", + "type_args": [] + } + } + } + }, { "vector": { "vector": { "struct": { - "address": "2cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375ee", - "module": "WBwRridqLYwuxLhEAdd0", - "name": "C", + "address": "686e7d23c57bb4c3108deb5661c2244cd43096b42297892ada78962f7b817047", + "module": "dIXhxrrmpbCzMVLqfnaOXBaw2", + "name": "u4", "type_args": [] } } @@ -525,829 +615,755 @@ ], "args": [ { - "U64": "11890275679649734087" - }, - { - "Bool": true - }, - { - "U128": "211326598592605503961921466601160637814" - }, - { - "U8": 29 - }, - { - "Bool": true - }, - { - "U8Vector": "cfe4fcb46cff68b8fb" - }, - { - "U8": 58 + "U128": "45963502836960241715715009736023054062" } ] } }, - "max_gas_amount": "6333199691283183015", - "gas_unit_price": "6979750436888388414", - "expiration_timestamp_secs": "13766757096412574883", - "chain_id": 248 + "max_gas_amount": "5978513436980869405", + "gas_unit_price": "8517019043616324231", + "expiration_timestamp_secs": "6051718683617614515", + "chain_id": 159 }, - "signed_txn_bcs": "f95347eeeb2494465bcf9a46d602100d2dee62332f4047bab8674a7c8249d75af1ee93e7696c9f2f000e5097ee675259c000bbe0e3bf6aad090607589b69209f3bd3dda63d4f42514b5e79d29c30b86f11de5beb4f3bb607714c2a0279361c51595543597a6c566a68484f687666427a5373696f614d7552456e480006060307b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13517667a01663456e674d6e7a4f527451525551546b644a505046350d764f51754845704d69714d62410007a05e67668c21a36654c24b1441d11f53e1a28142507a75f42cf0f7ee4f3b26ce0150216854464f5a56535277694b65574474504b4c4758447441614c58724174664d51310007f38a66eb91ea85caef654165a4ec5277e6e75b9744bf59affae477a73c569f1b0c5a567a5649486d51566353381d6f4152544d49614a716279467262564442784a5a594a75677444684a6700077c548d772ec75da3918fa6c00fe1434ed304cb015522ea4bd35a40bb7cd8daff0c796d51566e696b514e7765431d70567277776e7656537a53686c5a484f65484e7464634e4b4d66416d760006060506072ca7d5d82c407a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab02644720686d4862616d6d675a5745537a4d78764f6a66505153476a4362574961534d38000606072cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375ee1457427752726964714c597775784c6845416464300143000701c71dfdb6bbbe02a505010276fd5422b9a130c1863703cfbd05fc9e001d05010409cfe4fcb46cff68b8fb003aa7358c82900be4573e239cc30a0edd60a374c2c8a3580dbff8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c18771e47eafa03cba45a57f8c911b5178e27976632c3918d6e4ca85c62218057fb6f15204c32839050d7dc95a2afc8a4050d19b06d60584a0f40d7372853003", + "signed_txn_bcs": "8d62ea7ad9d18690287e70e487a895d9ba2be639596704331e6d83707b5a6f689678462a11afb2230008ea2cfad47af4f76f070606010712531fbe37a26d3ffc41e39af8a1f50194906aa1aee74d999f64e6640182e21f04707870311f54755368706f6449516f6c6b4e4242455a77685064616369566a7961597632000606030607ee5d0374459724681daeffc9ba14e4293bb9a775867fcb2a9f6cffe8ae505f0e1379557377445a5845536a647573426369557934106d6e6e5a71704c764c775a6165426938000607e96e83a5a47429ff4693c7f0cd3500b586f00007b39a493bc98552af4e0835f30347713710714e4c44506b54426256766b42764a39000606075069fb47d5620a2b8cb9a064ced887cc065c59ea5720eba6f9b890a36ecbe6d21a44616557465244546e734372624c7a475055474b4d4b5a446e36117077596c4e464d79455a62794952795a3800060607686e7d23c57bb4c3108deb5661c2244cd43096b42297892ada78962f7b81704719644958687872726d7062437a4d564c71666e614f5842617732027534000102ee9685076550b9c81a990f48a73f94221df924a04bf2f75287fafcefb1873276b35a9f511406fc539f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba22eee7cfbe28a429a35e78478b49b0981efe022752aff290301cfac703fab87da113f43fe7d8e21731f1f141c452b4f1c46cd845a4177b53b46c7139f9140d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4cc4e4ab1728c8abc6cbae7698ed55b11e7c941911c88e002a3df4d2dac06253", - "sequence_number": "5166986925766650006", + "sender": "e0f192ac663f415b70f2858642d4c477a9129e3db242d3cb115143f7b4c67bd0", + "sequence_number": "2646633000989045210", "payload": { "Script": { - "code": "5d9017fc", + "code": "623f685ddab2eb1dc2280aa939a9", "ty_args": [ - { - "struct": { - "address": "a5e888fc1a702231948093ced0c3c81a7e27874cf74ef80e716267b294f0c501", - "module": "KQCdzpUWYjrAUaklu", - "name": "vXCdojUBdwrdDYIaL1", - "type_args": [] - } - }, { "vector": { - "vector": "u128" + "struct": { + "address": "15833a6017a76152f3630fe01825339daa1847726cf8c046d561471803b333fa", + "module": "VZClZKpGuBydbdUBLPucvhPF", + "name": "ewDngaWpghVVruExayEtmAt", + "type_args": [] + } } }, { "vector": { - "vector": "address" + "struct": { + "address": "e7875f023b19d67332c261296604a38a2f720110aeab1ee46c45b9c72b1b7b12", + "module": "WlkgaSEOnKhgStfdmVqsgsLmCYab", + "name": "vzZmGFRalUmJM", + "type_args": [] + } } }, { - "struct": { - "address": "33cb0fc67095461c81c4afee376affb68b39d169cdcf96c5d638c2d181f7fb5a", - "module": "HRXYdzedz", - "name": "WdYyKig5", - "type_args": [] + "vector": { + "struct": { + "address": "0edcbcfbf1185399cf35af0b8467d40dddc0771ac492ef75c98f175cfeec0997", + "module": "CQi5", + "name": "EjqJu", + "type_args": [] + } } } ], "args": [ { - "Address": "c8a6a8a636d50aa7ef72757839db19c3cf12359c04409451ac00f16403fbdf25" + "U8": 43 }, { - "U128": "157331703291025202463992733642664352818" + "U128": "5967268949439651005934301882302361787" } ] } }, - "max_gas_amount": "4716318631450662867", - "gas_unit_price": "8648061684764613470", - "expiration_timestamp_secs": "3476223040702190383", - "chain_id": 100 + "max_gas_amount": "6399467889325266872", + "gas_unit_price": "6665082992972751287", + "expiration_timestamp_secs": "193767705983652603", + "chain_id": 5 }, - "signed_txn_bcs": "4cc4e4ab1728c8abc6cbae7698ed55b11e7c941911c88e002a3df4d2dac0625396a868ad3bd3b44700045d9017fc0407a5e888fc1a702231948093ced0c3c81a7e27874cf74ef80e716267b294f0c501114b5143647a705557596a724155616b6c7512765843646f6a554264777264445949614c31000606030606040733cb0fc67095461c81c4afee376affb68b39d169cdcf96c5d638c2d181f7fb5a0948525859647a65647a08576459794b696735000203c8a6a8a636d50aa7ef72757839db19c3cf12359c04409451ac00f16403fbdf2502329cb2987ed402cc586dc90cdefb5c76d3572ca3ceba73415e9b0f6c481604782f13150d70063e3064002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444057b9114c752bb201f08c59c9393a6a3778635e2d2e73df6216ec5d369b2716ccce6cbbb6ec209d07322543c61de96096ad9d3648007241a61c7bacf62cd55109", + "signed_txn_bcs": "e0f192ac663f415b70f2858642d4c477a9129e3db242d3cb115143f7b4c67bd0da31c722b1baba24000e623f685ddab2eb1dc2280aa939a903060715833a6017a76152f3630fe01825339daa1847726cf8c046d561471803b333fa18565a436c5a4b704775427964626455424c50756376685046176577446e676157706768565672754578617945746d4174000607e7875f023b19d67332c261296604a38a2f720110aeab1ee46c45b9c72b1b7b121c576c6b676153454f6e4b6867537466646d56717367734c6d435961620d767a5a6d474652616c556d4a4d0006070edcbcfbf1185399cf35af0b8467d40dddc0771ac492ef75c98f175cfeec0997044351693505456a714a750002002b02bb707024e4a206df062762f612417d04b857c0b6237acf58b761a342ab217f5cfb1219b4b366b00205002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440673a5a8c867e438310fe8f39544c4d2feda4f736b01d1dec25a37d9b6694a61bd4b6a8d42159c3168290b766697bb3f0328c09594e9f79d17024d5430500890c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7e0a9a15e0ad717f235636ad80275fe49715cd8d364a00d3dcbaf5b39ade76c8", - "sequence_number": "7227984514519167296", + "sender": "f7dcde955e9874518dcd915eeea994fb4b9fe152919e9606661d1dd7543ba2f2", + "sequence_number": "14709205516768297372", "payload": { "Script": { - "code": "b0aabb", - "ty_args": [], - "args": [ - { - "Address": "b3c41862018b1739867390c1f277db7adf7dda8bf74e777b08eecb08c15a5caf" - }, - { - "U8Vector": "9dfaec44" - }, - { - "U8Vector": "8ad7f7ccb7ca33fe0ce4ae" - }, - { - "U128": "114397681220791908685918816472162765191" - }, - { - "U8Vector": "3f9a878b854eeb6cacefd2" - }, + "code": "814a2a1fc5af9fcf4bebfad44daace", + "ty_args": [ { - "U8Vector": "d4d728b9b5" + "vector": { + "struct": { + "address": "4b6357156afce2e7993ea6613f27dda8d6d21de9e1f11a9cdff76d2919ead7a1", + "module": "RWipnFAtwce", + "name": "qImZFqzNNrAwan", + "type_args": [] + } + } }, { - "U8": 100 + "struct": { + "address": "f901dd0841d725ac6588a44c25f47850a956f9f810269caf3eb101eb5756c978", + "module": "JuWEFEZNGKAmCr", + "name": "zghDEJZisOI", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "2419250657686819403", - "gas_unit_price": "10664924541046458205", - "expiration_timestamp_secs": "8777437622354548390", - "chain_id": 130 + "max_gas_amount": "10121544640024291411", + "gas_unit_price": "693523612328745626", + "expiration_timestamp_secs": "450304319726693670", + "chain_id": 215 }, - "signed_txn_bcs": "7e0a9a15e0ad717f235636ad80275fe49715cd8d364a00d3dcbaf5b39ade76c84071f0d59ef54e640003b0aabb000703b3c41862018b1739867390c1f277db7adf7dda8bf74e777b08eecb08c15a5caf04049dfaec44040b8ad7f7ccb7ca33fe0ce4ae0287091e3a99d11a824da4ecce25311056040b3f9a878b854eeb6cacefd20405d4d728b9b500644b920dcaa7e792215d876b695d6c0194a696973e03b9cf7982002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440891a26cd99df89775855bedabb754c922a757c6970fe822b719a852a2e265460fb5f4684379c741c137338e7b7df37a72b73aa619952031145e3107fafaabf06", + "signed_txn_bcs": "f7dcde955e9874518dcd915eeea994fb4b9fe152919e9606661d1dd7543ba2f29cc1301b7c9821cc000f814a2a1fc5af9fcf4bebfad44daace0206074b6357156afce2e7993ea6613f27dda8d6d21de9e1f11a9cdff76d2919ead7a10b525769706e4641747763650e71496d5a46717a4e4e724177616e0007f901dd0841d725ac6588a44c25f47850a956f9f810269caf3eb101eb5756c9780e4a75574546455a4e474b416d43720b7a676844454a5a69734f4900005328e84e39f3768c9a5a330c0de49f09262d229a64cd3f06d7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440da09569cc62f634fe0348b9f89809759e215b01c262c6fe60c17a2bf81fefd9be0880a78182968b7b64b5d52c5e4332ebc0b7e5dff1645a9cc17f4b70c1da106", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e84d4fc3f1d14df2fa279a8656b23c32c59c1d8186ea2393b37091bee2ac5b06", - "sequence_number": "350987295300083611", + "sender": "c01c51c7f1a215858722a7288fcb285b1353eb24e25ee1e9b397bf701803d617", + "sequence_number": "9125347005557893276", "payload": { "Script": { - "code": "1efd32f9e9c8", + "code": "d17a9ebee9c9ceeaef8c2cc1", "ty_args": [ { "struct": { - "address": "018d89e73a42f25146ebb0343257befb955f5d7a423669ef968e07b96d2a23e4", - "module": "PtAk6", - "name": "EtDpmzBNJbnnG8", + "address": "2130c6d10d6cee52eaf92cf212b3974eaa044bf9ec7fb4f8a070d49af1ccace9", + "module": "xUjoVbDUGORjsMsPXkKtcW", + "name": "xIbkCGdv", "type_args": [] } }, { - "vector": "u128" - } - ], - "args": [ - { - "Address": "7c36813dd317e424ea642b2a656b74212f6ce9f26eb960c3a36c77890546c92b" + "vector": { + "vector": { + "struct": { + "address": "fdaf8e4593a18d7b234b5d09a3139f0acfe0b57e1238a97f3af95347eeeb2494", + "module": "BvCMchEDd3", + "name": "fzpM", + "type_args": [] + } + } + } }, { - "U128": "275771500081230549234015361492539735011" + "vector": { + "struct": { + "address": "6fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f", + "module": "RxONPUYsUR9", + "name": "frRfxRlVctBbMmUZEmjzAeaMCIlpErAJ1", + "type_args": [] + } + } }, { - "Bool": false + "struct": { + "address": "2bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db", + "module": "eFHXEusORmvUSIclJW", + "name": "woItodFBReSjBgTuVwDxpVCo7", + "type_args": [] + } }, { - "U64": "17977028123766152978" + "struct": { + "address": "856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a", + "module": "j5", + "name": "MQaSdweM", + "type_args": [] + } }, { - "U128": "151526128532424140838094688808140732364" + "struct": { + "address": "400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef", + "module": "lJuuIKvao", + "name": "qGglBigfJIEqljouDsqIQElwey4", + "type_args": [] + } }, { - "Address": "4d372edb8e5f5a45b4db39d97af8a280ce427f869b4da7aa29cdd97cf5e483ec" + "struct": { + "address": "b68b39d169cdcf96c5d638c2d181f7fb5abab5c7567fc9d994cd9e21ba7bf888", + "module": "R3", + "name": "lYyDDBoxxlTfUZsPvdHyOBm4", + "type_args": [] + } + } + ], + "args": [ + { + "U8": 114 } ] } }, - "max_gas_amount": "6793051906045157290", - "gas_unit_price": "13633036682382135220", - "expiration_timestamp_secs": "7745521548611890597", - "chain_id": 253 + "max_gas_amount": "9951943570233611203", + "gas_unit_price": "5943447743841487415", + "expiration_timestamp_secs": "15423464442069995182", + "chain_id": 224 }, - "signed_txn_bcs": "e84d4fc3f1d14df2fa279a8656b23c32c59c1d8186ea2393b37091bee2ac5b069b5f09e115f5de0400061efd32f9e9c80207018d89e73a42f25146ebb0343257befb955f5d7a423669ef968e07b96d2a23e4055074416b360e457444706d7a424e4a626e6e473800060306037c36813dd317e424ea642b2a656b74212f6ce9f26eb960c3a36c77890546c92b02e3fb94ae56a8d5ba5e9b0303b3a877cf05000112df490ad53b7bf902ccf7469e843d5a9ebb6717b3eedefe71034d372edb8e5f5a45b4db39d97af8a280ce427f869b4da7aa29cdd97cf5e483ecaa9f9ca8b7c4455eb4cf41b7a14632bda52d2599cf9e7d6bfd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444032a7db01f62235db4fee8b95872a4da02617a1ee4e899adfcbeebc0d97ce7b608f93a57440fa8cfed39c5a4207ca57b2ac07a4f3dd6f693c41b1c2f956b2680d", + "signed_txn_bcs": "c01c51c7f1a215858722a7288fcb285b1353eb24e25ee1e9b397bf701803d6179ce873dec0bea37e000cd17a9ebee9c9ceeaef8c2cc107072130c6d10d6cee52eaf92cf212b3974eaa044bf9ec7fb4f8a070d49af1ccace91678556a6f56624455474f526a734d7350586b4b746357087849626b4347647600060607fdaf8e4593a18d7b234b5d09a3139f0acfe0b57e1238a97f3af95347eeeb24940a4276434d63684544643304667a704d0006076fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f0b52784f4e50555973555239216672526678526c56637442624d6d555a456d6a7a4165614d43496c704572414a3100072bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db12654648584575734f526d76555349636c4a5719776f49746f6446425265536a42675475567744787056436f370007856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a026a35084d5161536477654d0007400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef096c4a7575494b76616f1b7147676c426967664a4945716c6a6f754473714951456c776579340007b68b39d169cdcf96c5d638c2d181f7fb5abab5c7567fc9d994cd9e21ba7bf888025233186c59794444426f78786c5466555a7350766448794f426d3400010072c3d38110f3671c8a37cac4b83b5e7b52ae4e736b31270bd6e0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440978cf0997597bce11383d42df0a261e009a9e8bd4afd49018282f807b4c7e861a1ccb99411e141304f5b9bcd15be0d9e4287c612f2a675203d570a9c2aa54502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb707e8702", - "sequence_number": "14992661250520904036", + "sender": "befb955f5d7a423669ef968e07b96d2a23e4a12f8695b523a2128c8b05718970", + "sequence_number": "16374847433563205325", "payload": { "Script": { - "code": "3537e3b9d4b5a03723ffe54df4cf5e", + "code": "8efcbc3689076eb5a4", "ty_args": [ { - "struct": { - "address": "7a30a956a42fc89e306c95adadccd6697a0546e028438fd792aa3435f9c43fc6", - "module": "mghCKNjLQgqLzCSetgWhlW", - "name": "CRhDpIVieEyvD", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "4c7c8c5aecba884bd982a7e78dc6b61a609274a3d82aa57c2a718f4c216666c5", + "module": "YRuMK2", + "name": "utHAZkNFdriHmhpt3", + "type_args": [] + } + } } }, { "struct": { - "address": "33427a3a031fac11fa17dffb1700e66d0daf5dbbec9a865bfd14ee6d3eb67cff", - "module": "VChRFfNA", - "name": "T", + "address": "6e169abfde9cd9677b866ecaf088b414cf1c53b79fcaf65d2a02f4132001ed7e", + "module": "XaStMZDwJFOyJRjHssrEQRwYI", + "name": "pCKIsVD", "type_args": [] } }, { "vector": { - "struct": { - "address": "db41eaaa9446a7b9aa9dd3c467413654a23a8c94b7bec39dfb9dc2c16d004345", - "module": "MOSeM3", - "name": "YSJHDaOmcRvEJyyHMQQ0", - "type_args": [] + "vector": { + "vector": { + "vector": "address" + } } } }, { "struct": { - "address": "ba2acfbf55d9a965f0cfbd44923526526e39412dba879722e1f0d5368dfb0882", - "module": "hIDaJUSdxgqeCUtPHSvszZUm", - "name": "KOFtyMVQguTTXxsfG", + "address": "d41bcb623760eb0809eca630f2141804da67c31c88815a15cbce68782ad3bb13", + "module": "ZrfDTzRmpMyuCouHTwNw", + "name": "FpS", + "type_args": [] + } + }, + { + "struct": { + "address": "3e9ea560d38262d6b2613f3e883507e0ddbba82f19cf8cafc36e662e3004ebf5", + "module": "lzSfnYvNbRFCvn", + "name": "AsiZfBehGDsuNy6", + "type_args": [] + } + }, + { + "struct": { + "address": "a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df536944", + "module": "EBPb", + "name": "dOuHUjejEpWS", "type_args": [] } } ], "args": [ { - "Address": "ccb8872a8b69546647fcf64a12f4ccc1d4546f1bc9c8e3c11863a99dde74b091" + "U8Vector": "bd2b584ab2d0b88e602acfceb1ca8b69" }, { - "U8": 199 - } - ] - } - }, - "max_gas_amount": "6898781826993812256", - "gas_unit_price": "15421261541659152626", - "expiration_timestamp_secs": "15551876510667012352", - "chain_id": 45 - }, - "signed_txn_bcs": "9ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb707e870264f10f0bf9a110d0000f3537e3b9d4b5a03723ffe54df4cf5e04077a30a956a42fc89e306c95adadccd6697a0546e028438fd792aa3435f9c43fc6166d6768434b4e6a4c5167714c7a435365746757686c570d43526844704956696545797644000733427a3a031fac11fa17dffb1700e66d0daf5dbbec9a865bfd14ee6d3eb67cff085643685246664e410154000607db41eaaa9446a7b9aa9dd3c467413654a23a8c94b7bec39dfb9dc2c16d004345064d4f53654d331459534a4844614f6d635276454a7979484d5151300007ba2acfbf55d9a965f0cfbd44923526526e39412dba879722e1f0d5368dfb088218684944614a5553647867716543557450485376737a5a556d114b4f4674794d5651677554545878736647000203ccb8872a8b69546647fcf64a12f4ccc1d4546f1bc9c8e3c11863a99dde74b09100c720f3e2348565bd5ff290fcb2aa5303d600790c014a5dd3d72d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400b886edd30fed09d08bb867f01832c9c5c29090aea4018ce5c061defbe7bd767beb6c3b51193d8f0df09fbe6038fe768729ef2e547cdbf887f28c196a783d003", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cf7c638f0041cb968497e22d091a304415052fb15679c0f253a2a6f7bc716798", - "sequence_number": "11745274922679138599", - "payload": { - "Script": { - "code": "0f9a78ea8cbce8c7164cb4a4", - "ty_args": [], - "args": [ + "Bool": true + }, { - "Address": "4589457a00474b1b5e00971bb4ba7b970581287d244bb0ee7911bea1aedd2078" + "U8": 31 }, { - "U128": "247733931560227065529341776975280050698" + "U8": 205 }, { - "U64": "9293165213621309782" + "Bool": true } ] } }, - "max_gas_amount": "13100034624844546052", - "gas_unit_price": "4838957551341363502", - "expiration_timestamp_secs": "6246074009986970437", - "chain_id": 204 + "max_gas_amount": "12017997239567011546", + "gas_unit_price": "7070718548572320482", + "expiration_timestamp_secs": "16765325951114236141", + "chain_id": 133 }, - "signed_txn_bcs": "cf7c638f0041cb968497e22d091a304415052fb15679c0f253a2a6f7bc71679827f997235099ffa2000c0f9a78ea8cbce8c7164cb4a40003034589457a00474b1b5e00971bb4ba7b970581287d244bb0ee7911bea1aedd2078020a923d93bd7f9a558675ae12d8d15fba015651ea4486f4f78004402d9715acccb52e61e54a416e274345b3120e3883ae56cc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a4e89a211a6bcd3dcea6de5b59af68307e92397546e2c99b1e2c76549eef914da70dc05d7d65d2b7985bf3a2efd1811ff040be61eaedb0d18b8ce667428d2b0a", + "signed_txn_bcs": "befb955f5d7a423669ef968e07b96d2a23e4a12f8695b523a2128c8b05718970cd6ec0b0fb243fe300098efcbc3689076eb5a4060606074c7c8c5aecba884bd982a7e78dc6b61a609274a3d82aa57c2a718f4c216666c5065952754d4b3211757448415a6b4e46647269486d6870743300076e169abfde9cd9677b866ecaf088b414cf1c53b79fcaf65d2a02f4132001ed7e19586153744d5a44774a464f794a526a487373724551527759490770434b4973564400060606060407d41bcb623760eb0809eca630f2141804da67c31c88815a15cbce68782ad3bb13145a726644547a526d704d7975436f754854774e770346705300073e9ea560d38262d6b2613f3e883507e0ddbba82f19cf8cafc36e662e3004ebf50e6c7a53666e59764e62524643766e0f4173695a66426568474473754e79360007a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df53694404454250620c644f7548556a656a4570575300050410bd2b584ab2d0b88e602acfceb1ca8b690501001f00cd0501da4e04b8d080c8a6e2326bc20e3d2062ed50cd432067aae885002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b1221b0a07548315d27c0345266c928454e8054a94c17970e6cc36bde203ac7b7b59be8a11058dc4ae8e3e32e00de3a6a6f96959736ef261bbe3f9e1e213910c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "006e9b6597e1f0c0763dd93c72d5d960dbf44b3a7f2339cf9d3858d23b04b2ca", - "sequence_number": "15439727154301880735", + "sender": "8cfa3a212f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3", + "sequence_number": "3806457624865730470", "payload": { "Script": { - "code": "1d1fe961bbb74f5bdddfa968b05edff1", + "code": "eb7412b1", "ty_args": [ { - "struct": { - "address": "a141088f1b39dcf294c0348ad152d1201d67e5da64145e4b7063d8f2eb4f105c", - "module": "uotCjNYtCLwiegHCoE0", - "name": "VlGWcNlFQaldVWzKLxZUnwueZl8", - "type_args": [] - } - }, - { - "struct": { - "address": "0ecd2b97014daf86edf7d7c31303a2ee28db4428739a309c63d3094de44b823b", - "module": "ydqUamAVzpHIpCaGrVcUbfSXfH", - "name": "Rv0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "2d8f661ac79c985f708e8b4a45536361c2d40ee6230ab8399fd8c943fcacf934", + "module": "YuGsKhve2", + "name": "JZJbUPqhKszdJZI", + "type_args": [] + } + } } } ], "args": [ { - "U64": "3513174488313567450" - }, - { - "U8Vector": "d3f4c20fde2a442df2ba3ce8c1240191" - }, - { - "U8Vector": "ce05d9aa1fada93da3c6be5c" + "Address": "486ca2cb3e30b13ef742d09758af966ec0db3396ba6f86e5d90db038d0892508" }, { - "U128": "137955332674727377407097834001997876746" + "Bool": true } ] } }, - "max_gas_amount": "7453951127712946889", - "gas_unit_price": "5417133610917930122", - "expiration_timestamp_secs": "17682353803604118289", - "chain_id": 146 + "max_gas_amount": "1864029782666557290", + "gas_unit_price": "11678867262183273717", + "expiration_timestamp_secs": "17698605108931169088", + "chain_id": 213 }, - "signed_txn_bcs": "006e9b6597e1f0c0763dd93c72d5d960dbf44b3a7f2339cf9d3858d23b04b2ca9fc91d2d0bee44d600101d1fe961bbb74f5bdddfa968b05edff10207a141088f1b39dcf294c0348ad152d1201d67e5da64145e4b7063d8f2eb4f105c13756f74436a4e5974434c7769656748436f45301b566c4757634e6c4651616c6456577a4b4c785a556e7775655a6c3800070ecd2b97014daf86edf7d7c31303a2ee28db4428739a309c63d3094de44b823b1a79647155616d41567a704849704361477256635562665358664803527630000401da18e561954dc1300410d3f4c20fde2a442df2ba3ce8c1240191040cce05d9aa1fada93da3c6be5c020acea5a85dd4430fb2b455d2093bc967c9da73d40ec171678aa4976351862d4b11cb9968195764f592002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444081871c49cfae78a1c6728ae5f3d530e6e4768d23e09dd9172c9b0b7b54cc3244031cba0099decf0e0fe8b03751d07e3bf2eb1b2dbb0b6beee9e22031c0333308", + "signed_txn_bcs": "8cfa3a212f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a6efb2d60a41d3340004eb7412b1010606072d8f661ac79c985f708e8b4a45536361c2d40ee6230ab8399fd8c943fcacf93409597547734b687665320f4a5a4a62555071684b737a644a5a49000203486ca2cb3e30b13ef742d09758af966ec0db3396ba6f86e5d90db038d089250805016ab79616365dde19f5745fcde5ab13a2408bc14993139ef5d5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440edc1f57308b8257fe0a5eea1f61aa38ccd56d26ef6e118033fab118389d34e58e88fae959f2aa7cbf0cdca8078891f144d39952638040fa75a464a4e675ba106", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e06988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472", - "sequence_number": "10487547084945647102", + "sender": "54f1ae389bc9393ba00c63352477be125da2c202096c5417d0865caf552318a3", + "sequence_number": "14261575651282797772", "payload": { "Script": { - "code": "1f", + "code": "e32fe121e1da05", "ty_args": [ { "struct": { - "address": "22d7e216f504f03a08cdf8d8d238a160e5bf90510672557e8251010b9a93994a", - "module": "zADKBHhzRAgyhxVhbVe", - "name": "VOHDvDLukcGEpfdgVDpsvbwFPioW6", - "type_args": [] - } - }, - { - "struct": { - "address": "15afeb103aafe8464d8a397f38171534efa0f45f66062483b1714cf37ae387e1", - "module": "ozDvJIYMNiiAnztyFGdShYJJ", - "name": "eSRZxuTTxDKYkfrwHThwi5", - "type_args": [] - } - }, - { - "struct": { - "address": "482f792c98dc519de41c075b38f6a300d3ed680ae5b034dcbc0f052cef15c8b5", - "module": "iFEYMoGqCGIIKzYJWOTiz7", - "name": "rHtjjDlTt", - "type_args": [] - } - }, - { - "struct": { - "address": "e228ddca62dc8cd3bee675f154e74d552ac59350b64de99eb9bfb829b12afb68", - "module": "UMWolnEbHQfmvLwxICZRPh5", - "name": "lNlRmsvVARxvGBDQKEQvCYQAoifLB", + "address": "5b5b40036a07cac4db75adfea1ba44b76e070bd0ba23b4c9123bddefea958383", + "module": "yAGNqdBhFgIklw", + "name": "tYVYfpzFAbuldgHTOgffZYJWOTfka0", "type_args": [] } }, { "vector": { "struct": { - "address": "053e5142a288b9330bc4f4609fde4b645c65131e2b186f9ef9047cd0b33df27e", - "module": "dpXnxXQXzUQBBenhQmHVLBokniUXt9", - "name": "wWyHiahMLgkqpdVwQooW", + "address": "855afc520f2b57678e25e48eb82749f090505f18a5d184c931a465098e3666de", + "module": "fqvsSKUGw7", + "name": "ilecgwKGsGMRJF", "type_args": [] } } }, { - "struct": { - "address": "33ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f", - "module": "NXNjfPcYrhtrj8", - "name": "KQUOEdbyzGmswQHCigYDrVr", - "type_args": [] + "vector": { + "struct": { + "address": "0a8e8cf46dcac3ddea29d211c7568ba1c9d300c7956287505f6f5b2afa0e11c9", + "module": "i0", + "name": "eyOgkdLXfxWvzO", + "type_args": [] + } } }, - { - "vector": "signer" - }, { "struct": { - "address": "bb214259146ba93af7320b9157ee23a4f0d6136d63639d5a787f28ec23c1d714", - "module": "KiZhdWJht8", - "name": "HMwd", + "address": "4d351dcd391e4b2da2ef6085f125e87ea46db8baa976d3853413aa84e4973b2e", + "module": "hPUeAyFytldrK", + "name": "qEL", "type_args": [] } } ], "args": [ { - "U8Vector": "eccba25eada6fcfc0e6bb53cdcee" + "Address": "151d7da2c83f4338e78d8799776b597828d1db41eaaa9446a7b9aa9dd3c46741" }, { - "U128": "76255342504606188957239480992778324548" + "U8": 162 }, { - "U64": "13942247285528114878" + "U8": 148 }, { - "U128": "207017947391519220235190917041964167342" + "U8Vector": "a136f674a2d61c25012a" }, { - "U8": 57 + "U8": 158 }, { - "U8Vector": "2aa3eb" + "U64": "1940488923066780474" }, { - "Bool": true + "Address": "8ef9ed852d439d96fe2a806eba363e3b64e0683594f24b1a3d883880fcaf1eee" } ] } }, - "max_gas_amount": "10676289091798208454", - "gas_unit_price": "10963576889334364574", - "expiration_timestamp_secs": "16522257710845683887", - "chain_id": 152 - }, - "signed_txn_bcs": "e06988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe655e2382408b9100011f080722d7e216f504f03a08cdf8d8d238a160e5bf90510672557e8251010b9a93994a137a41444b4248687a52416779687856686256651d564f484476444c756b63474570666467564470737662774650696f5736000715afeb103aafe8464d8a397f38171534efa0f45f66062483b1714cf37ae387e1186f7a44764a49594d4e6969416e7a74794647645368594a4a166553525a7875545478444b596b6672774854687769350007482f792c98dc519de41c075b38f6a300d3ed680ae5b034dcbc0f052cef15c8b516694645594d6f4771434749494b7a594a574f54697a37097248746a6a446c54740007e228ddca62dc8cd3bee675f154e74d552ac59350b64de99eb9bfb829b12afb6817554d576f6c6e45624851666d764c777849435a525068351d6c4e6c526d73765641527876474244514b455176435951416f69664c42000607053e5142a288b9330bc4f4609fde4b645c65131e2b186f9ef9047cd0b33df27e1e6470586e785851587a55514242656e68516d48564c426f6b6e695558743914775779486961684d4c676b7170645677516f6f57000733ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f0e4e584e6a66506359726874726a38174b51554f456462797a476d73775148436967594472567200060507bb214259146ba93af7320b9157ee23a4f0d6136d63639d5a787f28ec23c1d7140a4b695a6864574a68743804484d77640007040eeccba25eada6fcfc0e6bb53cdcee02448a564dadbac1bd30130942a83e5e3901beb68e7809d07cc102aeb0233dec687dd288533305d634be9b003904032aa3eb0501c68f02145dcc29949ef974e417732698af686a6ed9d94ae598002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444041155b99eb1746bbdf1475b86a750eb6cf306f002344b25c7eedb58feeb4f0ecf77bff523587c3e03d47d6d99c5d9f02113e763a07aaa15e95ada9b5c5353b0d", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "9f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0d8", - "sequence_number": "17977606044187181875", - "payload": { - "Script": { - "code": "85b61c23e0bf6c", - "ty_args": [], - "args": [] - } - }, - "max_gas_amount": "12635767792378714", - "gas_unit_price": "11925796493406539536", - "expiration_timestamp_secs": "16088173215446108219", - "chain_id": 29 + "max_gas_amount": "7559132535607383342", + "gas_unit_price": "6865154531655048702", + "expiration_timestamp_secs": "9923173966526464563", + "chain_id": 164 }, - "signed_txn_bcs": "9f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0d83343b19f72497df9000785b61c23e0bf6c00005aa3baf229e42c00108f18a5b9f080a53b889ef74cac44df1d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e2eb0ada3c48d88678df63bd55f259ec816adbe8211407aa3f7fe2cbaaca07b0f832559a44e07f800604533bcbc37401b04eac9c5b0fb6694d57778aaaa8890e", + "signed_txn_bcs": "54f1ae389bc9393ba00c63352477be125da2c202096c5417d0865caf552318a3cc4412687e4bebc50007e32fe121e1da0504075b5b40036a07cac4db75adfea1ba44b76e070bd0ba23b4c9123bddefea9583830e7941474e716442684667496b6c771e7459565966707a464162756c646748544f6766665a594a574f54666b6130000607855afc520f2b57678e25e48eb82749f090505f18a5d184c931a465098e3666de0a66717673534b554777370e696c656367774b4773474d524a460006070a8e8cf46dcac3ddea29d211c7568ba1c9d300c7956287505f6f5b2afa0e11c90269300e65794f676b644c58667857767a4f00074d351dcd391e4b2da2ef6085f125e87ea46db8baa976d3853413aa84e4973b2e0d6850556541794679746c64724b0371454c000703151d7da2c83f4338e78d8799776b597828d1db41eaaa9446a7b9aa9dd3c4674100a20094040aa136f674a2d61c25012a009e013acbf9f56400ee1a038ef9ed852d439d96fe2a806eba363e3b64e0683594f24b1a3d883880fcaf1eee2ed5f9bafd6ee768fe5d7663aced455f33c236b72532b689a4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444012b56f1e4daa6afd17a4e4ee0b9d9682fb322550d85a66cbb4229c17b07cc3ebb275d5ac1f1c81bc34ab3f52545671fdc457ccd892c6e595ebe0ece87717e001", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52654d03810da21540fa", - "sequence_number": "9927057380151577608", + "sender": "f253a2a6f7bc7167982750453804152e41cc5fdf8d4ce7dcd81793440b0e67fa", + "sequence_number": "15016318171376071630", "payload": { "Script": { - "code": "aaf84c", + "code": "d03857d2e2bdd49c0fed358cca8a", "ty_args": [ { - "struct": { - "address": "9f26d7a8f66aa573f0f1f15ab869564b1dca4756ea0d5a4df68ca3f230e688e3", - "module": "xVrzROMZiiZBWcEO8", - "name": "nGJcZCsbLcSpGzL8", - "type_args": [] + "vector": { + "vector": "u8" } }, { "struct": { - "address": "001179d4df57db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee29", - "module": "ewJCzRBhknwhUToVraNbHAyp6", - "name": "OrvkBCfdhrXJrBgkyASnLOHoWFlvg", + "address": "df86fce9a11f32295d6eff475d804ea1cc76f706b89658ee0eccb8872a8b6954", + "module": "nBTdQuBuBQBCtGROxPxJISxxWbaXDJ2", + "name": "WFCYzPU", "type_args": [] } }, { "struct": { - "address": "a73234c1689920010d6699d3b767ea4de84b327e0cf3a73c0b6ea054c8c46cf4", - "module": "MwciKYSOfJxLwkvmbopmuIeoLyKkcy", - "name": "gPKwMfPpcp", + "address": "c1105095f8a507e2bdd783d42fa6cdf60680af811c1e8f379cf7ebe751697684", + "module": "OW7", + "name": "hBpKPTnzgyiYuSWsZkbZ", "type_args": [] } }, - { - "struct": { - "address": "9b74138cfefd9027529f7e7e55167dab06d1b850751b1da8de9f9c4815713cd5", - "module": "jk", - "name": "xwSaznvYZYhMaMlYNMzYZ0", - "type_args": [] - } - } + "bool" ], "args": [ { - "U8": 217 + "U64": "15863227158632817352" + }, + { + "U64": "8543237655741033780" }, { - "U8": 97 + "Bool": false }, { - "U8": 127 + "U8": 169 }, { - "U64": "1425792806691718700" + "Address": "4766bbc297565258d667b88188219b4e0367ffebb45914bab4c6f4c9fa8c397e" }, { - "Address": "a54491ddded79b80fd012fd8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f" + "Bool": true }, { - "U64": "9677263550203145772" + "U8": 1 }, { - "U8": 153 + "Bool": false } ] } }, - "max_gas_amount": "16910529628569530931", - "gas_unit_price": "8070652017398338964", - "expiration_timestamp_secs": "4387869792080252212", - "chain_id": 61 + "max_gas_amount": "4136412553771309001", + "gas_unit_price": "12859340020265596516", + "expiration_timestamp_secs": "9777326043190247490", + "chain_id": 186 }, - "signed_txn_bcs": "a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52654d03810da21540fa08ccda6817fec3890003aaf84c04079f26d7a8f66aa573f0f1f15ab869564b1dca4756ea0d5a4df68ca3f230e688e3117856727a524f4d5a69695a425763454f38106e474a635a4373624c635370477a4c380007001179d4df57db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee291965774a437a5242686b6e776855546f5672614e6248417970361d4f72766b424366646872584a7242676b7941536e4c4f486f57466c76670007a73234c1689920010d6699d3b767ea4de84b327e0cf3a73c0b6ea054c8c46cf41e4d7763694b59534f664a784c776b766d626f706d7549656f4c794b6b63790a67504b774d665070637000079b74138cfefd9027529f7e7e55167dab06d1b850751b1da8de9f9c4815713cd5026a6b16787753617a6e76595a59684d614d6c594e4d7a595a30000700d90061007f012cc62ae6006fc91303a54491ddded79b80fd012fd8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f012caeb133ed8b4c86009933f29af21945aeea9455d1ea3fb70070344d9cf553d8e43c3d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019a42d9e347c376f1f7b6e3a07593c0ba1b7506c27396a773d3c814da4830fc5501111349da303495d6829d5b8f583f19b5f8f3cf126842510dc8cce054a000a", + "signed_txn_bcs": "f253a2a6f7bc7167982750453804152e41cc5fdf8d4ce7dcd81793440b0e67face331d27d1ad64d0000ed03857d2e2bdd49c0fed358cca8a0406060107df86fce9a11f32295d6eff475d804ea1cc76f706b89658ee0eccb8872a8b69541f6e42546451754275425142437447524f7850784a4953787857626158444a3207574643597a50550007c1105095f8a507e2bdd783d42fa6cdf60680af811c1e8f379cf7ebe751697684034f5737146842704b50546e7a67796959755357735a6b625a00000801c862a3c50d8125dc01346d2f4662ad8f76050000a9034766bbc297565258d667b88188219b4e0367ffebb45914bab4c6f4c9fa8c397e050100010500c95701504d7d67396436e5e19d8d75b242c087d93b0ab087ba002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444077e1d6577e9d4d1172fdc854b3b8ef1446858035e6d0adabc42485fe78fd2921a439d513c2baab592496244b2413525a29ba03c64aabaaa35003716cc5090402", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7613c6cb2834ee620c606f3ff75559fbba622cb087b0f79e7c8b45ae139bafec", - "sequence_number": "1706399116719379400", + "sender": "f81044b9e702312389c44f5a6442a4a4e4ff80f028de5fb6470e5dd8cb6819df", + "sequence_number": "14951616327499698008", "payload": { "Script": { - "code": "a8cfab8cccd3f447d2", + "code": "6d1dfac9bee8f7a54b7178e6", "ty_args": [ - { - "vector": { - "vector": "address" - } - }, - { - "struct": { - "address": "ac51b0c7f894a2789147d527ad2609d7459064457dc43115a3b6f442bccb980e", - "module": "FggGhQBvJcWnDXHGy3", - "name": "pFQvnPgyuXpqoxMZpplpiydMmAwli", - "type_args": [] - } - }, { "struct": { - "address": "43a51a415d8e7bae6e318b7e7f65117212544ed9d26c38c69fef987ce01763a3", - "module": "pdCgGVEAkeooPQnppavhLxV", - "name": "ewGroOjAJgs", + "address": "82095c4803d69ae9afb52e62b98c7b9a5d62f400d09497c5a1aef2b79450c21e", + "module": "sbZiurKoOnDaUHCfymCana6", + "name": "ofUyJCNnzlSnFnRdZtUn1", "type_args": [] } }, { "struct": { - "address": "9724f10eb8bdaf7b4bd77216733ec6642dd3c1321b2572d94ba931fa5771c086", - "module": "AapOJRhoCPr9", - "name": "JAwhoxMjfZZwc9", + "address": "87841872552c8a3bd9a5f20d49d5ce719a39e3484ec292b81b2510009aac4b9d", + "module": "zDVaksvAyFmN4", + "name": "sAaHZhDlmVnHbMmjHuKEk", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "f5b6f4a8943425690294db075c5b86b224f5a3b3214647e6a756513b1744ddd4", - "module": "YznIlVwk4", - "name": "YVQBPUS", - "type_args": [] - } - } - }, - { - "vector": "bool" - }, { "struct": { - "address": "7501e345cad7aa857579675eee39204409de72d4b214933c62092627d4e4a805", - "module": "OeAYzteDTWxuiosjkSXVZvBqZVHq", - "name": "yksJvLrXIAmy7", + "address": "3712950223900d9e854b650934c18ae9d9d26418f98c5e899085d2cfc57d3a9a", + "module": "mfYDkeVyxtovGjO", + "name": "ijAhyoqiX", "type_args": [] } - }, - { - "vector": { - "vector": { - "struct": { - "address": "0ef15ebcabc045328c4e014ebdced27da5ed61f76eba3777275123b67c9b57aa", - "module": "xHpRKxU6", - "name": "HOCsekUWmo", - "type_args": [] - } - } - } } ], "args": [ { - "U128": "283468200632207921301017618007671628120" - }, - { - "Bool": true + "U64": "13227480147978568088" }, { - "U64": "7204411996546967455" + "Address": "f7e6a86617d5b5646ac5bc77335cb9945140de4b2d5fcaebd4291ee6cd85b64e" }, { - "Address": "24e517350e14e596481d62a8ef7d4b1bc0fe04ff3188919690d076dfdbdd36dd" - }, - { - "U8Vector": "f254bbb83ef0afebfd50" - }, - { - "U8": 22 - }, - { - "U8Vector": "cb6aafcab7384f43f1" - }, + "U8": 189 + } + ] + } + }, + "max_gas_amount": "14295657202696819219", + "gas_unit_price": "934966119282591900", + "expiration_timestamp_secs": "743999501008191489", + "chain_id": 25 + }, + "signed_txn_bcs": "f81044b9e702312389c44f5a6442a4a4e4ff80f028de5fb6470e5dd8cb6819df58cf8c32d5cf7ecf000c6d1dfac9bee8f7a54b7178e6030782095c4803d69ae9afb52e62b98c7b9a5d62f400d09497c5a1aef2b79450c21e1773625a6975724b6f4f6e446155484366796d43616e6136156f6655794a434e6e7a6c536e466e52645a74556e31000787841872552c8a3bd9a5f20d49d5ce719a39e3484ec292b81b2510009aac4b9d0d7a4456616b73764179466d4e3415734161485a68446c6d566e48624d6d6a48754b456b00073712950223900d9e854b650934c18ae9d9d26418f98c5e899085d2cfc57d3a9a0f6d6659446b65567978746f76476a4f09696a4168796f7169580003019841cbc51c7391b703f7e6a86617d5b5646ac5bc77335cb9945140de4b2d5fcaebd4291ee6cd85b64e00bd13927ff57b6064c69c48dd58bbaaf90c0140a9b29a37530a19002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440076d3eea1538615252eb60c5dc267cc3ee2c7319e7a1b9bb5d4ee998b51a90197e3081877fd41dab6c05546226db473b813bc95b40d8517bf0242f11eaadfa04", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "919e83780a53a34ac5f0d9c830f9659899a40213ad955dc377e5b45376016993", + "sequence_number": "3713091688849788495", + "payload": { + "Script": { + "code": "8c0dc657a8b5c414ab4e21", + "ty_args": [ { - "U128": "51177119647560543826431264473193611276" + "vector": { + "vector": "signer" + } }, { - "Bool": false + "vector": "u8" } - ] + ], + "args": [] } }, - "max_gas_amount": "2602951867719947708", - "gas_unit_price": "3223517900651077899", - "expiration_timestamp_secs": "6542621566755311154", - "chain_id": 206 + "max_gas_amount": "13042946056958781552", + "gas_unit_price": "3150143652295273602", + "expiration_timestamp_secs": "10390206255665303062", + "chain_id": 131 }, - "signed_txn_bcs": "7613c6cb2834ee620c606f3ff75559fbba622cb087b0f79e7c8b45ae139bafecc85319adf458ae170009a8cfab8cccd3f447d20806060407ac51b0c7f894a2789147d527ad2609d7459064457dc43115a3b6f442bccb980e1246676747685142764a63576e4458484779331d704651766e506779755870716f784d5a70706c706979644d6d41776c69000743a51a415d8e7bae6e318b7e7f65117212544ed9d26c38c69fef987ce01763a31770644367475645416b656f6f50516e70706176684c78560b657747726f4f6a414a677300079724f10eb8bdaf7b4bd77216733ec6642dd3c1321b2572d94ba931fa5771c0860c4161704f4a52686f435072390e4a4177686f784d6a665a5a776339000607f5b6f4a8943425690294db075c5b86b224f5a3b3214647e6a756513b1744ddd409597a6e496c56776b340759565142505553000600077501e345cad7aa857579675eee39204409de72d4b214933c62092627d4e4a8051c4f6541597a74654454577875696f736a6b5358565a7642715a5648710d796b734a764c725849416d7937000606070ef15ebcabc045328c4e014ebdced27da5ed61f76eba3777275123b67c9b57aa08784870524b7855360a484f4373656b55576d6f00090258e11ebe110469dc8e4b2ea255fd41d50501019fa7be4d8a36fb630324e517350e14e596481d62a8ef7d4b1bc0fe04ff3188919690d076dfdbdd36dd040af254bbb83ef0afebfd5000160409cb6aafcab7384f43f1020c80fb76dada4056ebb790e8ce5a80260500bc15e3c2ee8a1f240ba16ba3733cbc2c328e4292a60fcc5ace002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444013395756f744fdfdc2eac8cb81d5c07e5046ca34550a15111d4df10cd4e19ce89b13b1c27b0ebe60068b6a384c8d7bf0ca87be7bd92e929f6967a5e2ea60c405", + "signed_txn_bcs": "919e83780a53a34ac5f0d9c830f9659899a40213ad955dc377e5b453760169934fce58dc378d8733000b8c0dc657a8b5c414ab4e210206060506010070289c9555da01b582ec822af68eb72b16cef8338a6d319083002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400ad1916b089d378a3d1784f4e42fe7a84bd52de1ced648b0a6706ff8d1a3ba03baf25da39469edcf92ee8a3285cd462333853ee10f4160a30a217b02998ca10a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "032e24c8cd56b9fa0834c2dac90f73a2aae14e4e0b16f652b72bb23d112c00af", - "sequence_number": "7574377721982990589", + "sender": "799480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea", + "sequence_number": "6428080728338718564", "payload": { "Script": { - "code": "fbdadeec8fca2beb9a", + "code": "f52cfda36f6d132e99bcd2", "ty_args": [ { "vector": { "vector": { "struct": { - "address": "5fd30230b935329beecac88e6bdd7bf6321e99c42910b66931bbd956f70b841b", - "module": "dUQlhinDKsyoyIHqYDRhUJeo6", - "name": "EgoxlbvqGJg", + "address": "6b2a98fd068e552c28b4b86be5e6d41ecd1b673e4f76357c01bf72e3253ab436", + "module": "pDe", + "name": "cXfLydOWjGZHLRZTt", "type_args": [] } } } }, { - "struct": { - "address": "810c21fdd35e8730962c6d8b95d0ba5c03b96f9004132d780c11d756022102b3", - "module": "LOWnJuSfgFvVfnEoFALcuVWTYpLljwkP9", - "name": "MJVVUpOykVkbNerfmroNMVcGcBvVR", - "type_args": [] + "vector": { + "struct": { + "address": "dd6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc", + "module": "PvVfxEvbioot", + "name": "dzPdCmgMJySyTZHQNSuZXmfqTYwfHGIp0", + "type_args": [] + } } }, { - "vector": { - "vector": { - "struct": { - "address": "d25df829b39ff74ef444128b7b3e6f558aee6ec123454f628ef55929e5365f48", - "module": "MbvmWWDjPIIFqdPy8", - "name": "HKDjfnSEcvuwetjPXaarWQdhwZ2", - "type_args": [] - } - } + "struct": { + "address": "f219f64678ca6cf8291acef055020c8727a7bdc3349832e64897e37a3bfa22bc", + "module": "zURlPOSJWcdOqRBZAWZIpYsOXs7", + "name": "USXUVmqqTbWpsZCYHxnGHwPHUhid", + "type_args": [] } } ], - "args": [] + "args": [ + { + "Bool": true + }, + { + "U64": "4991296121917984485" + }, + { + "U8Vector": "1c81a0fda08b" + }, + { + "U64": "780270738634991358" + }, + { + "U8": 186 + } + ] } }, - "max_gas_amount": "2075620853176563889", - "gas_unit_price": "16277998168108031144", - "expiration_timestamp_secs": "10390203313178923156", - "chain_id": 155 + "max_gas_amount": "10680423677853326845", + "gas_unit_price": "13506371687864439490", + "expiration_timestamp_secs": "14235487095123703959", + "chain_id": 231 }, - "signed_txn_bcs": "032e24c8cd56b9fa0834c2dac90f73a2aae14e4e0b16f652b72bb23d112c00affdb86d4968981d690009fbdadeec8fca2beb9a030606075fd30230b935329beecac88e6bdd7bf6321e99c42910b66931bbd956f70b841b196455516c68696e444b73796f7949487159445268554a656f360b45676f786c627671474a670007810c21fdd35e8730962c6d8b95d0ba5c03b96f9004132d780c11d756022102b3214c4f576e4a75536667467656666e456f46414c637556575459704c6c6a776b50391d4d4a565655704f796b566b624e6572666d726f4e4d566347634276565200060607d25df829b39ff74ef444128b7b3e6f558aee6ec123454f628ef55929e5365f48114d62766d5757446a5049494671645079381b484b446a666e53456376757765746a505861617257516468775a320000b178fb392b16ce1ca8dc89e01611e7e194d01d1add6a31909b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ac83471283dfbf85f5d46cb11996d4c9744c6975f16d9d51011e555628e9b351dcc332ca09069b403659843bcc71bda62451d6cab1c69627f1f26928347e9204", + "signed_txn_bcs": "799480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64df29705d213559000bf52cfda36f6d132e99bcd2030606076b2a98fd068e552c28b4b86be5e6d41ecd1b673e4f76357c01bf72e3253ab43603704465116358664c79644f576a475a484c525a5474000607dd6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc0c5076566678457662696f6f7421647a5064436d674d4a795379545a48514e53755a586d66715459776648474970300007f219f64678ca6cf8291acef055020c8727a7bdc3349832e64897e37a3bfa22bc1b7a55526c504f534a5763644f7152425a41575a497059734f5873371c55535855566d717154625770735a435948786e4748775048556869640005050101e5ceb4bb60a5444504061c81a0fda08b01fe66f84c1a14d40a00bafd5d1e69bf7c3894c2928d837d4570bb97788115179c8ec5e7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409337a380a5f706396db12c02bf2dfb5db5263f2d42f72b6166532bd71650dd8d1e500fc6586e0c7d2f45e5fb78dfa67b596e2f9118f830871038edddfbb8150c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9b45e8f59e9d6ac60a4ebd256775ae022e19625b2eb79ee88557f996bfc6c036", - "sequence_number": "14205352846149403986", + "sender": "1fad49a667854e48a305d969c3dae702db79b0d19e1215751491f2f5ab2ec782", + "sequence_number": "3555661566543083544", "payload": { "Script": { - "code": "ece1f5a7e69bf3feebe679aac8ac", + "code": "d1d07dd79331a51b0ace4613d52d", "ty_args": [ { - "struct": { - "address": "f10ab73d9799022a1e244760371f7677296d3ef09b116fce093dea6f10cc4558", - "module": "PdsFhy", - "name": "pbzQzumOrWLBwhMm", - "type_args": [] - } - }, - { - "struct": { - "address": "295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe", - "module": "ut2", - "name": "ijEXcPXHGalxtSojKDrJoU0", - "type_args": [] - } - }, - { - "struct": { - "address": "03f391db9aec24f47fceb36df7bd7df5433e751125968e576776b5be5f4c8668", - "module": "PrUXpolfbhfOlpjvESLoQSZT", - "name": "wPZCxurRmQbUSXfSWreTmqQOFluBcNy", - "type_args": [] - } + "vector": "signer" }, { "vector": { - "vector": "u64" + "vector": "u8" } }, { "vector": { "struct": { - "address": "6709402959a757bbb4731ea1f45a3c417a89a200128cc1f57108b093f6c6ac3a", - "module": "NrmuPhxcMHyUjUKTL0", - "name": "aCZKmluTDhojJwrPMe3", + "address": "ab2fdcc69ea495e33ff51f33ae10344c0f901fb1c34011bd9ea0692a9a9b37f7", + "module": "KqyZqQWPlSRcfdgmVYrxsVTEJYkoV4", + "name": "CvEgLcjsZ", "type_args": [] } } }, { - "struct": { - "address": "14b489255eb39ecea08b58411e12949f4593d4937083b52a8d106d00c4b460cb", - "module": "LfozpEyJYklJJ5", - "name": "QYWhYcAVTUxVXudWULLPhLrQHlguoxUG", - "type_args": [] + "vector": { + "vector": { + "vector": "u128" + } } } ], "args": [ { - "Bool": true + "U8": 30 }, { - "Address": "93e4754c81bdf320bc7ca4d38d55985ddaf5044e9c4dc6de285f33f76665aa73" + "U128": "129276751065345552951432700655578992622" } ] } }, - "max_gas_amount": "13481784958246247653", - "gas_unit_price": "123245906274907829", - "expiration_timestamp_secs": "13141077505956651830", - "chain_id": 26 + "max_gas_amount": "2145903621860984851", + "gas_unit_price": "13430175339104821123", + "expiration_timestamp_secs": "16181208580549465986", + "chain_id": 121 }, - "signed_txn_bcs": "9b45e8f59e9d6ac60a4ebd256775ae022e19625b2eb79ee88557f996bfc6c03652c5d17f268d23c5000eece1f5a7e69bf3feebe679aac8ac0607f10ab73d9799022a1e244760371f7677296d3ef09b116fce093dea6f10cc4558065064734668791070627a517a756d4f72574c4277684d6d0007295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe0375743217696a45586350584847616c7874536f6a4b44724a6f5530000703f391db9aec24f47fceb36df7bd7df5433e751125968e576776b5be5f4c86681850725558706f6c666268664f6c706a7645534c6f51535a541f77505a43787572526d51625553586653577265546d71514f466c7542634e790006060206076709402959a757bbb4731ea1f45a3c417a89a200128cc1f57108b093f6c6ac3a124e726d75506878634d4879556a554b544c301361435a4b6d6c755444686f6a4a7772504d6533000714b489255eb39ecea08b58411e12949f4593d4937083b52a8d106d00c4b460cb0e4c666f7a7045794a596b6c4a4a352051595768596341565455785658756457554c4c50684c7251486c67756f785547000205010393e4754c81bdf320bc7ca4d38d55985ddaf5044e9c4dc6de285f33f76665aa73e5dc786efdeb18bbb57689af7fdbb50136236c045e7c5eb61a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a3d2668cbd3538229d984ff0d359841473e46c655e8663083c59462cef340a544221ea1982d092e03a8dba7964295f1b4decd70ddb9d6e3fb941d4b22ed5a604", + "signed_txn_bcs": "1fad49a667854e48a305d969c3dae702db79b0d19e1215751491f2f5ab2ec78218384f275b3f5831000ed1d07dd79331a51b0ace4613d52d0406050606010607ab2fdcc69ea495e33ff51f33ae10344c0f901fb1c34011bd9ea0692a9a9b37f71e4b71795a715157506c5352636664676d56597278735654454a596b6f563409437645674c636a735a000606060302001e02ee4f59a4bda6e0d6bace39e9edcb416113883f7ff9c7c71d83df8d96509161ba825727e878338fe079002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b43eba0289837d5eff8353cbd1cae8070fe90f82595b3df329325d15592944174f5afbf80f296e9744ac2f470d4e67355f50123a6ffdd61af87510f96b0440c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bc9b6aca75dcafbe", - "sequence_number": "3368735613719441705", + "sender": "fdf9645a5604f72e8b5a5bd1ce147df19c32649409e6cbc843ee52e1ed9e3351", + "sequence_number": "13891525780570891155", "payload": { "Script": { - "code": "5df50201ec", + "code": "ec1e993d", "ty_args": [ { - "vector": { - "struct": { - "address": "6b95c62aabf2db9f7acbe87b8d5ddf719ec399785e2172fdaf7529bca905588b", - "module": "qLyIhirreoJUWBmi4", - "name": "EclbOsKngzgRudpVmVbJxDCciNgL0", - "type_args": [] - } + "struct": { + "address": "a44d9dc0f7c5bbf75b97481bd05e3ad0bceba9b4a3313429faad53b9ddf35a95", + "module": "HHOXhcEjkvFaDymCJuYXMhwjljylLO6", + "name": "pcxTCbyOJQazlFxlaJVkwcKYVafe", + "type_args": [] } }, { "struct": { - "address": "cd30d430f2ee2c18fc7176bef8f84c5f5cd941da18921c631e1c92baa784148f", - "module": "vRQMDCKLTAwcgrjZKzHycLluVkQ", - "name": "WPxxkqwPfhjcHDWlkjXdrDkhmSYGW", + "address": "2533ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c7", + "module": "NAzQFnYwjbYKLQZWOPiOGzdqCSCQ", + "name": "ljgIogYfAbvO3", "type_args": [] } }, { "struct": { - "address": "cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2d4205962255d096a7", - "module": "TeVLyhgRWZptEMukyevSdrx4", - "name": "yTKOBHZJtmGCQn", + "address": "4d54d77d298154b9a6eac50251833b69ba3aa3b49fae10abf3f102b62dcdc040", + "module": "Qx5", + "name": "kikXgJg5", "type_args": [] } }, { "struct": { - "address": "a4d43cc6f08278714e3f2d3587ddbb493698da04327d643d9fc13875b7536c22", - "module": "gppwbpCsFThj", - "name": "BejsTdhGdqnNNmNjKpYSmtJTHowRDU", + "address": "2d9d82ae002a8b20ef3a7d8edd9c6e13b14323f605169567019a76309b9b0c78", + "module": "YBIZGnUdVgyzpqnwCWOrhfMeffuPtM0", + "name": "QOLcXhzMt", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "struct": { + "address": "53d9ca124767f92cb2429093a2ecb40701a41f37697c2109da4f071e4593112c", + "module": "XBPZyGwvfrvRgLnsQdgDcwnbmfATu8", + "name": "Zl", + "type_args": [] + } + } } }, { - "vector": { - "vector": { - "vector": "address" - } + "struct": { + "address": "42d1cfe3093052308f73734690e1cda8579cf179d06e5e242ca76b53a517ab0c", + "module": "zihd", + "name": "PZJn8", + "type_args": [] } }, { "vector": { - "struct": { - "address": "4516bd2851ac1d9364aee2a51e87dfcb8a37dc99a622ada65994413d125ec33d", - "module": "daVlNf1", - "name": "IHRMHkZnb4", - "type_args": [] - } + "vector": "u128" } }, { - "struct": { - "address": "102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf069", - "module": "FnzPbxLxhYtCb8", - "name": "bDqVJgkYKJurYIbuTNCokjq", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "34c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83", + "module": "JaTfYxmVyMhNizGwp9", + "name": "vHsSYzynEo", + "type_args": [] + } + } } }, { "struct": { - "address": "2010184befd59e3ebc4bf661557bd028f7aef798cb72cd83ccb97d1651ebf258", - "module": "aDgRMDSqmpetuzlJMvFSNmyUF", - "name": "XvZyPUhN", + "address": "9211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f28", + "module": "LPmmTRtRrvxpy", + "name": "dDhIJxsMVzqzfZoXX", "type_args": [] } } @@ -1355,43 +1371,28 @@ "args": [] } }, - "max_gas_amount": "15980864413258155199", - "gas_unit_price": "1555563745445757059", - "expiration_timestamp_secs": "17243099985585191978", - "chain_id": 39 + "max_gas_amount": "13053965050136016325", + "gas_unit_price": "8579807345382899004", + "expiration_timestamp_secs": "1529158086750067956", + "chain_id": 145 }, - "signed_txn_bcs": "7edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bc9b6aca75dcafbe2971f43d3127c02e00055df50201ec0906076b95c62aabf2db9f7acbe87b8d5ddf719ec399785e2172fdaf7529bca905588b11714c794968697272656f4a5557426d69341d45636c624f734b6e677a6752756470566d56624a78444363694e674c300007cd30d430f2ee2c18fc7176bef8f84c5f5cd941da18921c631e1c92baa784148f1b7652514d44434b4c5441776367726a5a4b7a4879634c6c75566b511d575078786b71775066686a634844576c6b6a586472446b686d535947570007cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2d4205962255d096a7185465564c79686752575a7074454d756b79657653647278340e79544b4f42485a4a746d4743516e0007a4d43cc6f08278714e3f2d3587ddbb493698da04327d643d9fc13875b7536c220c67707077627043734654686a1e42656a735464684764716e4e4e6d4e6a4b7059536d744a54486f77524455000606000606060406074516bd2851ac1d9364aee2a51e87dfcb8a37dc99a622ada65994413d125ec33d076461566c4e66310a4948524d486b5a6e62340007102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf0690e466e7a5062784c7868597443623817624471564a676b594b4a757259496275544e436f6b6a7100072010184befd59e3ebc4bf661557bd028f7aef798cb72cd83ccb97d1651ebf25819614467524d4453716d706574757a6c4a4d7646534e6d7955460858765a795055684e0000bf04ef7b836fc7dd8340c518fc7896152a3c593b14cc4bef27002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403b41631678d5a31d3e2b7df1a94a3d62f252a69a5bda7cdc4b0c50ff878e149cef1a1fcf1503c9c2a733117ddf8e2d27eb689e6a1183a5693ebc7e75527e1907", + "signed_txn_bcs": "fdf9645a5604f72e8b5a5bd1ce147df19c32649409e6cbc843ee52e1ed9e335193e31bd3189dc8c00004ec1e993d0907a44d9dc0f7c5bbf75b97481bd05e3ad0bceba9b4a3313429faad53b9ddf35a951f48484f586863456a6b76466144796d434a7559584d68776a6c6a796c4c4f361c706378544362794f4a51617a6c46786c614a566b77634b595661666500072533ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c71c4e417a51466e59776a62594b4c515a574f50694f477a6471435343510d6c6a67496f6759664162764f3300074d54d77d298154b9a6eac50251833b69ba3aa3b49fae10abf3f102b62dcdc04003517835086b696b58674a673500072d9d82ae002a8b20ef3a7d8edd9c6e13b14323f605169567019a76309b9b0c781f5942495a476e55645667797a70716e7743574f7268664d6566667550744d3009514f4c6358687a4d740006060753d9ca124767f92cb2429093a2ecb40701a41f37697c2109da4f071e4593112c1e5842505a7947777666727652674c6e735164674463776e626d6641547538025a6c000742d1cfe3093052308f73734690e1cda8579cf179d06e5e242ca76b53a517ab0c047a69686405505a4a6e380006060306060734c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83124a61546659786d56794d684e697a477770390a76487353597a796e456f00079211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f280d4c506d6d54527452727678707911644468494a78734d567a717a665a6f58580000c5b5b8db0c0029b53cbdd5a652991177f45c27962da9381591002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440661db9ac9af5877000ae301c1a914109e8b75ebba36798ac82bfc3070ef6a5e97d0f4e8740fcbe37879ae85a8897ba3d791e604677a49f8ba90f9ecbd985ee00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "789fdeeb4d71acac26107eb686b8b2c791f746b84254d56a89549de4c2855f06", - "sequence_number": "3131219673398083535", + "sender": "e274a13f630e77305eb120c6257ed9fd7512ec11e391aa950650bb8697c2055b", + "sequence_number": "1707861502839437572", "payload": { "Script": { - "code": "cbc773eefbb245aff9f03b7a738b78", + "code": "afdf22fad5d9b2b584", "ty_args": [ { "vector": { "struct": { - "address": "4eec3ea3011bd28bb915afebbf49920baf7c4b315e3020497c730ab22f18dc01", - "module": "dGAIHRQGQJ1", - "name": "DqzbeldUoiovQxFex3", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "address" - } - }, - { - "vector": { - "struct": { - "address": "d017f45b5bc2f8bcbfd95226ada46b101ce62556ba52b11fb687677b90de4139", - "module": "fNWMXtfHc3", - "name": "FdDZjDQosPxHPzvzh", + "address": "b99f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0", + "module": "QNsmHtbHyyfOLJvVRudF", + "name": "KlArCLkREkpVsrUXquVxLpseCCsyQJL9", "type_args": [] } } @@ -1399,879 +1400,861 @@ { "vector": { "vector": { - "vector": { - "struct": { - "address": "c4e763bf2b786463771808a34f73f15f20a1218ec8762775237ce8b809768fc7", - "module": "XlvSBQUbAjtWQzsMppKasbnPbzAtqY", - "name": "FzcwoRmmKCd", - "type_args": [] - } - } - } - } - }, - { - "vector": { - "struct": { - "address": "bb881b1ceb810136155dcec32f97e4f66013d60144d835e8be906b57a42dd881", - "module": "bdnuPNkbsPrTMMAUgJQZymejJcL1", - "name": "GYzKhmNUMAlyfkelxPnsxmS5", - "type_args": [] + "vector": "u64" } } - }, - { - "struct": { - "address": "bcfd93d296c4d90573605fef28c012ead61ad84b713b95ffe8327f8b2e107877", - "module": "M5", - "name": "cYNzvxanGAGdfg7", - "type_args": [] - } } ], "args": [ { - "U8Vector": "42fc253d7f5619b1ea5b" - }, - { - "U64": "1473128561786810381" - }, - { - "Address": "c054c088beed0f3e116692fb98c71fe07cfff6daf3307a3e08242902669b0f29" - }, - { - "U8Vector": "b5796b7e" + "Address": "29628511976124646b0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005" } ] } }, - "max_gas_amount": "16830529844262677456", - "gas_unit_price": "6640323194831559980", - "expiration_timestamp_secs": "1082914194734019568", - "chain_id": 162 + "max_gas_amount": "9736704560257072061", + "gas_unit_price": "6373179767395044284", + "expiration_timestamp_secs": "4910113764382074429", + "chain_id": 206 }, - "signed_txn_bcs": "789fdeeb4d71acac26107eb686b8b2c791f746b84254d56a89549de4c2855f06cf7f9bfab353742b000fcbc773eefbb245aff9f03b7a738b780606074eec3ea3011bd28bb915afebbf49920baf7c4b315e3020497c730ab22f18dc010b6447414948525147514a311244717a62656c64556f696f76517846657833000606040607d017f45b5bc2f8bcbfd95226ada46b101ce62556ba52b11fb687677b90de41390a664e574d587466486333114664445a6a44516f73507848507a767a680006060607c4e763bf2b786463771808a34f73f15f20a1218ec8762775237ce8b809768fc71e586c765342515562416a7457517a734d70704b6173626e50627a417471590b467a63776f526d6d4b4364000607bb881b1ceb810136155dcec32f97e4f66013d60144d835e8be906b57a42dd8811c62646e75504e6b62735072544d4d4155674a515a796d656a4a634c311847597a4b686d4e554d416c79666b656c78506e73786d53350007bcfd93d296c4d90573605fef28c012ead61ad84b713b95ffe8327f8b2e107877024d350f63594e7a7678616e474147646667370004040a42fc253d7f5619b1ea5b010df0c8399f9a711403c054c088beed0f3e116692fb98c71fe07cfff6daf3307a3e08242902669b0f290404b5796b7ed02be3acb80d92e92cddb885c32a275cf07359fbb848070fa2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406855c411e32a53a309df3f2567df522585045a7a1ba4fc025a918df76b4711f2fbd6f71e9ef31927572938725f190e3a4fb4291f7e7462071d0b10d3a6564e08", + "signed_txn_bcs": "e274a13f630e77305eb120c6257ed9fd7512ec11e391aa950650bb8697c2055b04394ffafc8ab3170009afdf22fad5d9b2b584020607b99f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a014514e736d487462487979664f4c4a765652756446204b6c4172434c6b52456b705673725558717556784c70736543437379514a4c390006060602010329628511976124646b0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005bd7b0cd535b91f87bccb495d3b1572583de6bf2c743a2444ce002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408aad6954cb3795ed4438fcb1e0d9f10a20c7608ac5a602335af116bea982b74f8bfe24c29a2880c61df4f43a94530453f8df328fddcf756656937f707966ec0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b005f82c41c8735370ce3e476f72abadf43b14bd9ccdda2eaf7d9afe2adce49c", - "sequence_number": "11371359119202989976", + "sender": "7dc83737f22bb99f1a13d0de5915a1130dc0a924ac662bca83b1696b85afdbaa", + "sequence_number": "2895946074836110500", "payload": { "Script": { - "code": "ab91dd", + "code": "12e5acad90bc49", "ty_args": [ { "vector": { - "vector": "signer" + "vector": { + "vector": "u8" + } + } + }, + { + "struct": { + "address": "702b9794ea87fd2a6247455fbf2c75292ff0a1ca1f801ab28e3872e2e459b91a", + "module": "pVmydAslEqhPEWd", + "name": "OIOmCbpMF3", + "type_args": [] } }, { "struct": { - "address": "51988913ad90eacadc9c6768529b5dbd3c28349768b0ecb58bdf115e4192457c", - "module": "gFRXDPzTQU", - "name": "WbkpzJMhCZo8", + "address": "1ef6d4c80149bc94a9c53959d91321fed8292ef895909621a73234c168992001", + "module": "qAZzkpXBtIwjpacRkUBpcShuLsBFXQFd8", + "name": "ASbVZVhMubYejRySNyONUkuxgGYWlOy", "type_args": [] } }, { "struct": { - "address": "44d14eeb4058b91b58dbed7aa7071194598a85c2ad0609122ead759b921a003e", - "module": "pjhUHSwzPwNcAjW", - "name": "WEADYWJYcDluQDn4", + "address": "29235f5ceb7400bf3a0add4dfe1459834f52b20caa37100de3e05493f6cc04f7", + "module": "YTRTCfXaiYEJDuqHsSbXnaYkpInbxjx", + "name": "dpsfqqDRIIYoCVFh", "type_args": [] } }, { "vector": { - "struct": { - "address": "0ce5d870613c1c5605d20787ac0e00697dbaa960b0186d2c43e7a97a184bd297", - "module": "FUeAibcKfKKgNZmIkTPv8", - "name": "ljhskKQdpsBgzInFVGmMgkKJ", - "type_args": [] - } + "vector": "signer" } }, { "vector": { "struct": { - "address": "495d17d49349c4a35a0c0a7782c06f57e14955cf0a8a6b6ec160ec797ae67b5b", - "module": "ujPcdXxMSKfsGtwVYX", - "name": "jhBZWSnxtnzBcvqavkcIu9", + "address": "1dfbb5c2e365e5e8a44743eed8f4716800e6e40748a549fdef4bf9d99c7e4df3", + "module": "dOedQitGizMFtJrCEvKSzieqF4", + "name": "Wzqxk", "type_args": [] } } }, { - "vector": { - "vector": "u8" + "struct": { + "address": "d8324b2b02c8033418b1f8f2269b436a1dcbb27f45336178ef8e8a1848821b4e", + "module": "iAkDDXBSYDFHugKpGaJ6", + "name": "mBdfBjjTgATNzBq", + "type_args": [] } }, { "vector": { "struct": { - "address": "b1577560b93c98ee664ae48663845fa2a6915faf56991ab10db8afa26d7269c7", - "module": "UxKBGeXMNX5", - "name": "gnOruFDGpFnIsKsTQWxT3", + "address": "23daa2e0d824eb288b18861e1a81dcac662277d737fb9d3f33f2a480cc6fa540", + "module": "TG", + "name": "gflfwKxwnHWX", "type_args": [] } } }, { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "89316687675a6ad7c98163dd93f08906bcc961e4bf8d58060777cbf092ee45c3", + "module": "L", + "name": "jVrJARfUJ", + "type_args": [] } } }, { - "struct": { - "address": "8ce74ceba02dfed5629171a2999c0b33e2778036c9ce04cb9a013655056511e5", - "module": "SmutLKxHbukdKBFBzZzb9", - "name": "PziRESIDHFKrgyYErCGMDWixMO", - "type_args": [] - } - }, - { - "struct": { - "address": "d7f06c21c2de3b0b0aed06bea393bbca0665b2113a2da3fbddeeb55ca5d75aa7", - "module": "ospjfRLLhIdlNQfFqHvMxIUr2", - "name": "fdioncSOUNUjhRMxnyD5", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "07cf4105afd69a6ffa08eb3ff79ed88bb2b2cdc6d2d417f3bb52ded295a23d1a", + "module": "lWASWwvEOkKVdUKJdpHCrM", + "name": "VNmnZJEDdLJvlZPXrFbOrRFe3", + "type_args": [] + } + } } } ], - "args": [ - { - "Bool": true - }, - { - "Bool": false - } - ] + "args": [] } }, - "max_gas_amount": "9601868369686518606", - "gas_unit_price": "13290345674121224896", - "expiration_timestamp_secs": "16510887524430014979", - "chain_id": 151 + "max_gas_amount": "10998293935718974367", + "gas_unit_price": "3543300086054847203", + "expiration_timestamp_secs": "17292235556376811790", + "chain_id": 165 }, - "signed_txn_bcs": "b005f82c41c8735370ce3e476f72abadf43b14bd9ccdda2eaf7d9afe2adce49c98377ef1de2ecf9d0003ab91dd0a0606050751988913ad90eacadc9c6768529b5dbd3c28349768b0ecb58bdf115e4192457c0a6746525844507a5451550c57626b707a4a4d68435a6f38000744d14eeb4058b91b58dbed7aa7071194598a85c2ad0609122ead759b921a003e0f706a68554853777a50774e63416a57105745414459574a5963446c7551446e340006070ce5d870613c1c5605d20787ac0e00697dbaa960b0186d2c43e7a97a184bd29715465565416962634b664b4b674e5a6d496b54507638186c6a68736b4b5164707342677a496e4656476d4d676b4b4a000607495d17d49349c4a35a0c0a7782c06f57e14955cf0a8a6b6ec160ec797ae67b5b12756a50636458784d534b6673477477565958166a68425a57536e78746e7a4263767161766b63497539000606010607b1577560b93c98ee664ae48663845fa2a6915faf56991ab10db8afa26d7269c70b55784b424765584d4e583515676e4f727546444770466e49734b735451577854330006060604078ce74ceba02dfed5629171a2999c0b33e2778036c9ce04cb9a013655056511e515536d75744c4b784862756b644b4246427a5a7a62391a507a69524553494448464b72677959457243474d445769784d4f0007d7f06c21c2de3b0b0aed06bea393bbca0665b2113a2da3fbddeeb55ca5d75aa7196f73706a66524c4c6849646c4e5166467148764d7849557232146664696f6e63534f554e556a68524d786e7944350002050105004e5b39cb68b04085c02225b0f9ca70b8036a149cb97422e597002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404919f7468bfdd2e3226798275f81e2dea5baac6bf98b20621a90f5b443e3c85af780176083f45bd54c65288bfb396c9ba56393faa6a9bc75b6e96e27bc289001", + "signed_txn_bcs": "7dc83737f22bb99f1a13d0de5915a1130dc0a924ac662bca83b1696b85afdbaaa40c4b979c773028000712e5acad90bc490a0606060107702b9794ea87fd2a6247455fbf2c75292ff0a1ca1f801ab28e3872e2e459b91a0f70566d796441736c457168504557640a4f494f6d4362704d463300071ef6d4c80149bc94a9c53959d91321fed8292ef895909621a73234c1689920012171415a7a6b7058427449776a706163526b554270635368754c73424658514664381f415362565a56684d756259656a5279534e794f4e556b7578674759576c4f79000729235f5ceb7400bf3a0add4dfe1459834f52b20caa37100de3e05493f6cc04f71f59545254436658616959454a44757148735362586e61596b70496e62786a781064707366717144524949596f435646680006060506071dfbb5c2e365e5e8a44743eed8f4716800e6e40748a549fdef4bf9d99c7e4df31a644f656451697447697a4d46744a724345764b537a696571463405577a71786b0007d8324b2b02c8033418b1f8f2269b436a1dcbb27f45336178ef8e8a1848821b4e1469416b44445842535944464875674b7047614a360f6d426466426a6a546741544e7a427100060723daa2e0d824eb288b18861e1a81dcac662277d737fb9d3f33f2a480cc6fa5400254470c67666c66774b78776e48575800060789316687675a6ad7c98163dd93f08906bcc961e4bf8d58060777cbf092ee45c3014c096a56724a415266554a0006060707cf4105afd69a6ffa08eb3ff79ed88bb2b2cdc6d2d417f3bb52ded295a23d1a166c574153577776454f6b4b5664554b4a64704843724d19564e6d6e5a4a4544644c4a766c5a50587246624f725246653300009fc3dc2510caa198e302e9b1a7542c310e1938ce9e5cfaefa5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea7f6bebb7f91fa9f08a88c0de9def3902b73ece097334c73fcd7f12e90950b52eb6c8d645254bcd3ba2209235de685cca0aa03b91f473c01faeb7e9ba1c0102", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8b37e28b5c9bb57483162ccb5e1a4a713f19bd8ef06348dcc7de07e0c15652b5", - "sequence_number": "9717115411162054424", + "sender": "56a8c963a752a82d87ee5b4593253ab14b324243f82f93c1ac8e92227c9c75b8", + "sequence_number": "3947346515594680668", "payload": { "Script": { - "code": "2dcc63", + "code": "39408f7b7a92c574bf7c1705c3", "ty_args": [ { - "vector": { - "struct": { - "address": "c40a3c773ec8605a6290c99e2a2fb7eb349a6f472a9258d982435b5ea263bfb2", - "module": "waemqzmJCfhzBsldQAGGeGb1", - "name": "BlecvqTChOVtbtciOEczko", - "type_args": [] - } + "vector": "u8" + }, + { + "struct": { + "address": "7328d0be15ab151b4cefd447f8fde5180ff23d27eb3f5e73ed0478a9ca7c1592", + "module": "Oh", + "name": "hgoNkJxaLEOboekTWyMe", + "type_args": [] } }, { "struct": { - "address": "cd2d58a88c338de7dcc426502f0ef4e5bfb0a4ae268dd41372820d304243834e", - "module": "rPOoguqydLD9", - "name": "B8", + "address": "385d289a1449125597f52fc0d50ce55f16bb93dcf77d9ffd1d133a3fcbd5be8e", + "module": "xQBAmIhKIduDqZahyisjMVtKQx", + "name": "fMxShxHdprnRD", "type_args": [] } }, { "vector": { - "vector": { - "vector": "u64" - } + "vector": "address" } }, { "struct": { - "address": "f35bb05c1d0288cf714b5918f75f4f5bd910bda38af1de193221acf6a22ab87e", - "module": "dYusHtRuDkUM6", - "name": "vIsZcGhSWtCEtEOWzOZCpDILrne9", + "address": "1285ed7f900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e", + "module": "ecgzhvouadziQwQsVe", + "name": "gGHJtuhEBvYEwknYXKDaPKtUzsQK", "type_args": [] } }, { - "struct": { - "address": "e8b8865be5f7aeafe09e8417f3e1727855f970ab1d7364bb1217f0c2403a4641", - "module": "BUbcqFFnPdBJNRqJneixcwot", - "name": "ekYbvcVaqFOGPiZMbOtpcJWxSf5", - "type_args": [] + "vector": { + "struct": { + "address": "887467fe6af9ada54daec830abe9415e48e02b5c6599b871db100ef15ebcabc0", + "module": "GeY", + "name": "QiIQroQIAozcEUk3", + "type_args": [] + } } }, { - "struct": { - "address": "50adb5b2703afb1fb09ca217960bc0921e34ece9b8a97ee6dc5b3c2a617c3749", - "module": "nxBeRjRZTmxzALviKOAXVu", - "name": "wFBoVZc1", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "1728e1ce1184ba469aa8977e417707292ed0530a9d7b4a5ba56158118e55af30", + "module": "RYdIXZTITPLbAhtK", + "name": "iFHDWLALPiLYvHBViWGslLSjYASiDQfn", + "type_args": [] + } + } } }, { - "struct": { - "address": "2c78afd9270fca61cc039d13193147c5cba85f43b4fea76c5c8a4f5238324f51", - "module": "UxBVfEoXdHDVEd5", - "name": "vTygFcEbIv4", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "635abd03be654c6a2450fd042cace6effe0d52b62af09531313f33689132213a", + "module": "vHOEWFTdAUFgRJgbt", + "name": "pSQBxhlTJKjOG9", + "type_args": [] + } + } + } + }, + { + "vector": { + "vector": "address" } }, { "struct": { - "address": "9327244e60d4b818748cabd00597daa5bc9c0f66f74ecc171b34b2e0c3fae99e", - "module": "mXrMxUhuvhktgwpmvHcFs", - "name": "blclpfBUkRpKxUATvWNPd4", + "address": "1b28f4156bf300a23fdc85e0acf5f241d79259862e24dbf930b65ab7addf785c", + "module": "MWwOk", + "name": "sAutiJYXpjeupmUA7", "type_args": [] } } ], "args": [ { - "U64": "1456176404328498001" + "U8": 68 + }, + { + "U8": 156 + }, + { + "U8": 124 + }, + { + "U64": "7589469449094887828" + }, + { + "U8Vector": "9c6e9dff087e9af36cc5bf188e" + }, + { + "U8": 177 + }, + { + "U64": "8488512686883627308" + }, + { + "U64": "496840316488219765" }, { - "U8": 198 + "Address": "5990c4dda091b1bec74e3a3e5c89fa43233a15898a28b7291a3589ca2cb4a39b" } ] } }, - "max_gas_amount": "15667356745103459526", - "gas_unit_price": "16930683256175926446", - "expiration_timestamp_secs": "382443118719448317", - "chain_id": 214 + "max_gas_amount": "5397305908186692363", + "gas_unit_price": "7835174926084901593", + "expiration_timestamp_secs": "15040051270553271576", + "chain_id": 180 }, - "signed_txn_bcs": "8b37e28b5c9bb57483162ccb5e1a4a713f19bd8ef06348dcc7de07e0c15652b518bfc9a3fb20da8600032dcc63080607c40a3c773ec8605a6290c99e2a2fb7eb349a6f472a9258d982435b5ea263bfb2187761656d717a6d4a4366687a42736c64514147476547623116426c656376715443684f5674627463694f45637a6b6f0007cd2d58a88c338de7dcc426502f0ef4e5bfb0a4ae268dd41372820d304243834e0c72504f6f67757179644c4439024238000606060207f35bb05c1d0288cf714b5918f75f4f5bd910bda38af1de193221acf6a22ab87e0d6459757348745275446b554d361c7649735a634768535774434574454f577a4f5a437044494c726e65390007e8b8865be5f7aeafe09e8417f3e1727855f970ab1d7364bb1217f0c2403a464118425562637146466e5064424a4e52714a6e65697863776f741b656b59627663566171464f4750695a4d624f7470634a5778536635000750adb5b2703afb1fb09ca217960bc0921e34ece9b8a97ee6dc5b3c2a617c3749166e784265526a525a546d787a414c76694b4f41585675087746426f565a633100072c78afd9270fca61cc039d13193147c5cba85f43b4fea76c5c8a4f5238324f510f5578425666456f58644844564564350b765479674663456249763400079327244e60d4b818748cabd00597daa5bc9c0f66f74ecc171b34b2e0c3fae99e156d58724d7855687576686b746777706d764863467316626c636c706642556b52704b7855415476574e50643400020151434e7eb960351400c6c6443651f3a16dd9ae1c0509b8def5eafdb4107efdb54e05d6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c95d84684f4576a1c9315bd3733a87686b78dfedd3d3eeab25357bed37d847d5c336f78c32d80c24675dd6be27231c4ddf593e06ca15d24acf93dea190adf03", + "signed_txn_bcs": "56a8c963a752a82d87ee5b4593253ab14b324243f82f93c1ac8e92227c9c75b85c9965f3bdcac736000d39408f7b7a92c574bf7c1705c30a0601077328d0be15ab151b4cefd447f8fde5180ff23d27eb3f5e73ed0478a9ca7c1592024f681468676f4e6b4a78614c454f626f656b5457794d650007385d289a1449125597f52fc0d50ce55f16bb93dcf77d9ffd1d133a3fcbd5be8e1a785142416d49684b49647544715a61687969736a4d56744b51780d664d78536878486470726e524400060604071285ed7f900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e126563677a68766f7561647a695177517356651c6747484a7475684542765945776b6e59584b4461504b74557a73514b000607887467fe6af9ada54daec830abe9415e48e02b5c6599b871db100ef15ebcabc0034765591051694951726f5149416f7a6345556b33000606071728e1ce1184ba469aa8977e417707292ed0530a9d7b4a5ba56158118e55af301052596449585a544954504c624168744b2069464844574c414c50694c5976484256695747736c4c536a594153694451666e00060607635abd03be654c6a2450fd042cace6effe0d52b62af09531313f33689132213a1176484f455746546441554667524a6762740e7053514278686c544a4b6a4f473900060604071b28f4156bf300a23fdc85e0acf5f241d79259862e24dbf930b65ab7addf785c054d57774f6b1173417574694a5958706a6575706d55413700090044009c007c0194f9fad240365369040d9c6e9dff087e9af36cc5bf188e00b1012c61188d5041cd7501757c5faea221e506035990c4dda091b1bec74e3a3e5c89fa43233a15898a28b7291a3589ca2cb4a39b0bbb95992015e74ad98a562e1522bc6c187dfde8f1feb8d0b4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444038f59e7592509bb1278c290f85738ede90fee3479fb6c34eaa68ad2cb2049078e4e67eaca0afe3fabaf804e1c87774f730517fbbbb332f9a2c8b0c8211faa405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "918f46da4daa83f267fa898ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaa", - "sequence_number": "3198344470995509974", + "sender": "0ff5086c7e84e0ce82c3a640457c56b5764e89dc04d0631b4146688ec3cf8199", + "sequence_number": "11764089532947933679", "payload": { "Script": { - "code": "f94f18", + "code": "8b0f", "ty_args": [ { "struct": { - "address": "a804dcd896c931199f1a0ddf5a0905fc88a2c81848324d223a6e24ab16e6fa61", - "module": "DSOn", - "name": "zRKFDCPjuPOjuQFiEQaOuBQD8", + "address": "97c78c169e51c9a46daa5a64de281b2c08713721b0e77bd5003128a3e2c13954", + "module": "uwggPnwijwYFTjHDruiigtAQnRULV", + "name": "IpQzLHvDhsh8", "type_args": [] } }, { "vector": { - "vector": "address" + "vector": "u8" } }, { "vector": { "struct": { - "address": "8c56c6471c9b2ecf387e787994df1a093761a74293701dbeb2a240f75d83bcdf", - "module": "ecjZiumBUfCaoLXOJNEjIenVaJ", - "name": "u4", - "type_args": [] - } - } - }, - { - "vector": { - "struct": { - "address": "ffd3804df3e7a13d4447897be31928f0bb715b5f22311b7df46f791a3f899759", - "module": "WOsAElCitHqbCKESiPlqcOP", - "name": "wfKmBNUbxeJFhcNpvur", + "address": "44b5dd4b5d7becb69d9ac8262a2dcddd3a11df3e0f90f724e1d8fb88877c3d81", + "module": "BvUhBNKCel", + "name": "SonwkRKtrymYduJynEsRb", "type_args": [] } } + } + ], + "args": [ + { + "U64": "8246150575885019277" }, { - "vector": { - "vector": { - "vector": "u128" - } - } + "U128": "107641842610249000958099304350184303966" }, { - "vector": { - "vector": { - "vector": "address" - } - } + "U64": "14763856152715430698" }, { - "vector": { - "struct": { - "address": "7d022844a349705741fb7082cf6f281f4a670fc8d2b0b73b6b54242ce4b866b0", - "module": "WOWxMCWADjYQavJ2", - "name": "JpAuwYTLfIIKCCnUGYQXxcAnc", - "type_args": [] - } - } - } - ], - "args": [ + "U128": "183034631719426385601700413881596384161" + }, { - "U8Vector": "0db3a45a0c" + "U64": "789606558540120552" }, { - "U64": "7024259777566843714" + "Address": "dab93344eed8ae5bef61bc8a2c289dda0444d095b9d923c40e80dc80205b3291" }, { - "Bool": true + "Address": "94a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd101e3d7d0a85" }, { - "Bool": true + "U8Vector": "e5d696" + }, + { + "Address": "971afe6f386f14a121716a795d4a3f06c1175438254794bba8a7360b4fcba9c6" } ] } }, - "max_gas_amount": "17500826518180333788", - "gas_unit_price": "1599457683868736262", - "expiration_timestamp_secs": "13446065823184727193", - "chain_id": 185 + "max_gas_amount": "10025263189613158168", + "gas_unit_price": "15350321695262339503", + "expiration_timestamp_secs": "18414410145325957257", + "chain_id": 220 }, - "signed_txn_bcs": "918f46da4daa83f267fa898ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad6a205cf59cd622c0003f94f180707a804dcd896c931199f1a0ddf5a0905fc88a2c81848324d223a6e24ab16e6fa610444534f6e197a524b464443506a75504f6a755146694551614f75425144380006060406078c56c6471c9b2ecf387e787994df1a093761a74293701dbeb2a240f75d83bcdf1a65636a5a69756d42556643616f4c584f4a4e456a49656e56614a027534000607ffd3804df3e7a13d4447897be31928f0bb715b5f22311b7df46f791a3f89975917574f7341456c436974487162434b455369506c71634f501377664b6d424e556278654a4668634e7076757200060606030606060406077d022844a349705741fb7082cf6f281f4a670fc8d2b0b73b6b54242ce4b866b010574f57784d435741446a595161764a32194a7041757759544c6649494b43436e55475951587863416e63000404050db3a45a0c0142a3ef330d2f7b6105010501dc08e0b3fe6cdff206db43084a6a3216992c7239a0059abab9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ccfb27e5f61595612b1913ba6fe917c4d9402c76ad506c8312d6b9bb523e2410c5c56a5b288548821ad4c5592bda912a0de96d2e37969814125a6be4b4fda007", + "signed_txn_bcs": "0ff5086c7e84e0ce82c3a640457c56b5764e89dc04d0631b4146688ec3cf8199efa940f5197142a300028b0f030797c78c169e51c9a46daa5a64de281b2c08713721b0e77bd5003128a3e2c139541d75776767506e77696a775946546a484472756969677441516e52554c560c4970517a4c4876446873683800060601060744b5dd4b5d7becb69d9ac8262a2dcddd3a11df3e0f90f724e1d8fb88877c3d810a42765568424e4b43656c15536f6e776b524b7472796d5964754a796e457352620009018d68024042367072025eed9a1687599a94305d3a6b9610fb50012a8b91d9f2c0e3cc02a113b2eab30740025df25c3d1430b38901e8411a42fb3ef50a03dab93344eed8ae5bef61bc8a2c289dda0444d095b9d923c40e80dc80205b32910394a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd101e3d7d0a850403e5d69603971afe6f386f14a121716a795d4a3f06c1175438254794bba8a7360b4fcba9c6181fb13cc1e3208baf71159a404c07d589c080a476208dffdc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d024a81f4b016552add88c4d2001daf8bcb357f19d82c94368fe60d87d17c2e7fa8a40e43c28815e6e129835f9c1e68b6c069cec82e31c7455e2f0fab0b9c602", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5416bfb39dab0593f4711f5e0b56d31481dea50bb672641f816eb024d9790d58", - "sequence_number": "10706683213577597782", + "sender": "1818ba4fa3a8d2523b0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8", + "sequence_number": "14286251766004153855", "payload": { "Script": { - "code": "984db38fb88c66899f80075c", + "code": "0af6d15baa", "ty_args": [ { - "vector": { - "struct": { - "address": "d5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e623565770fa5ac", - "module": "hWjKHXvQWnQVuOUrNJfZUWMItl", - "name": "GLsFYZavJtTMBFfh", - "type_args": [] - } - } - }, - { - "vector": { - "struct": { - "address": "41ddbc7b6aa7a550f964e9ec8f32591335e52772846e118d05ce814c6d964a64", - "module": "XPBkRWOKIogTuzD4", - "name": "nqCnYrkQDvmZzZLBCYzJyqj5", - "type_args": [] - } + "struct": { + "address": "e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f27", + "module": "MhbkpfVqZMNsT", + "name": "BqIxxIbxQMAqAO", + "type_args": [] } }, { "struct": { - "address": "d81c9988b6a7762286f63e767b84c0dbfd72a9056bb0c6f0ab30602318a7cc65", - "module": "fLyDw8", - "name": "aMgiqpIENImSxAGeIuKDjINOGC9", + "address": "0657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f11", + "module": "szyxIi0", + "name": "ZeJrHJgrdDTMzgS", "type_args": [] } }, { - "vector": { - "vector": { - "vector": "u128" - } + "struct": { + "address": "66e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c", + "module": "Kw2", + "name": "Mq", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "5d35b198b8edef2fbd936b2b541dfec66c8c5771f7378bec10d22e363e01857f", - "module": "otjdXo", - "name": "NGqcOUbNLSeZFUDNCZOgQYH9", - "type_args": [] - } + "struct": { + "address": "57f42cfe025501bcb4b594253c8e6ae13d29b1ad42fac1bc3bfafd49571ee4ca", + "module": "KFKVxBmKgPR0", + "name": "ZfcSNohorLWaLZrCLQJNa", + "type_args": [] } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe", + "module": "QPpQ4", + "name": "nGYirfikySjTOuQFVmBaVlvrQTQobREo", + "type_args": [] } }, { "vector": { "struct": { - "address": "e89c61f81be7b1144085acc70c36ea1c27f012581bcb98adec99b571105ec423", - "module": "sCyRgWZIlmOIoZHSiTHcWtxRCpqGEF2", - "name": "kDChY", + "address": "dbb7a0cda2a7ea70ab90ae4940a481021b5785780efe98dcda03f391db9aec24", + "module": "JSnQzBPt7", + "name": "dXkpXq5", "type_args": [] } } - }, - { - "struct": { - "address": "13dbf86569a691c550f75e135114479119146ecf735153147c02c0ff40afa345", - "module": "mG0", - "name": "SxHHpRveETRgcSdJmHq4", - "type_args": [] - } } ], "args": [ { - "Address": "934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4e0a0a9" + "U128": "205742330523462318325428180869851245042" }, { - "Address": "d8b9e255f0fcad5e4278bda7414eea1dfac5286592cd10667f895977c1479a6c" + "U64": "2465559581404745137" }, { - "Address": "53c1a30f734be93b2162b5f799144b65059e294275ee33a3c16b70d87ab92dc1" + "U8Vector": "e1710aa4dc97861aff" }, { - "U64": "11199803512888179599" + "U8": 142 }, { - "Bool": false + "U8": 152 }, { - "U8Vector": "da08f8248ad8cbebed4adacd6a" - }, + "U64": "1924808419949941931" + } + ] + } + }, + "max_gas_amount": "14144151447906987127", + "gas_unit_price": "8417117598073422119", + "expiration_timestamp_secs": "6101300421118953170", + "chain_id": 197 + }, + "signed_txn_bcs": "1818ba4fa3a8d2523b0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff7d79144af642c600050af6d15baa0607e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f270d4d68626b706656715a4d4e73540e4271497878496278514d4171414f00070657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f1107737a79784969300f5a654a72484a67726444544d7a6753000766e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c034b7732024d71000757f42cfe025501bcb4b594253c8e6ae13d29b1ad42fac1bc3bfafd49571ee4ca0c4b464b5678426d4b67505230155a6663534e6f686f724c57614c5a72434c514a4e610007295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe055150705134206e4759697266696b79536a544f755146566d4261566c76725154516f6252456f000607dbb7a0cda2a7ea70ab90ae4940a481021b5785780efe98dcda03f391db9aec24094a536e517a425074370764586b70587135000602f2e9cd9922c2a109230b95951188c89a01b1cd304e606d37220409e1710aa4dc97861aff008e009801ab14cc530f4bb61a77acd28dcd1e4ac42701db11dc9bcf74d286bc2c682cac54c5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444035a9e3b84f182ffbc7663c8ddf7048414cea68e93b357571fc576e526ea8462a31bb29ae48787a03b4c9e66301f2d369935a5d9c00a7c1e44545d8331f5ed501", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "6e16d309245435e9e910cac58b2ed9ac71750c58818297cf6709402959a757bb", + "sequence_number": "9164924021602996", + "payload": { + "Script": { + "code": "1cbfb5d032ba4a3f3f2ba1fa", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "18122307170286939380", + "gas_unit_price": "15184117320809213500", + "expiration_timestamp_secs": "5652925324185931294", + "chain_id": 122 + }, + "signed_txn_bcs": "6e16d309245435e9e910cac58b2ed9ac71750c58818297cf6709402959a757bbb47ab328738f2000000c1cbfb5d032ba4a3f3f2ba1fa0000f4ac77f35a5e7ffb3c6eb01e41d2b8d21e8ee9c1a139734e7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440785425ea2bcc8c078560e3efca0a50f210b6b7e3dc64c3751c23431aa49e7fd925f44516ac7213c517bcf2f2475fe3cf6c74f7f46bf384c4e4af4d72adcefb09", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "05463318a70d83d99a7a2a53c6182909415f93baf8b4bfd25c6a3acd0643ec7b", + "sequence_number": "6356444125711872204", + "payload": { + "Script": { + "code": "c4b6de22", + "ty_args": [ { - "U64": "16189395170145667347" + "vector": { + "vector": "address" + } }, { - "U8Vector": "ec4de6384bfddb7245d5febbc636ab" + "vector": { + "vector": { + "vector": "signer" + } + } }, { - "U64": "2694903550936475086" + "struct": { + "address": "8bd27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be50", + "module": "cchMxTZJNdqgjUtWKBWRhmJib9", + "name": "OLoYkQmasGuIj4", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "6771618820553153754", - "gas_unit_price": "1234495723078004851", - "expiration_timestamp_secs": "4944881089605332966", - "chain_id": 8 + "max_gas_amount": "15713964331740974573", + "gas_unit_price": "4394958025515581644", + "expiration_timestamp_secs": "2336158501503025776", + "chain_id": 49 }, - "signed_txn_bcs": "5416bfb39dab0593f4711f5e0b56d31481dea50bb672641f816eb024d9790d585633ee03a8c79594000c984db38fb88c66899f80075c080607d5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e623565770fa5ac1a68576a4b48587651576e5156754f55724e4a665a55574d49746c10474c7346595a61764a74544d4246666800060741ddbc7b6aa7a550f964e9ec8f32591335e52772846e118d05ce814c6d964a64105850426b52574f4b496f6754757a4434186e71436e59726b5144766d5a7a5a4c4243597a4a79716a350007d81c9988b6a7762286f63e767b84c0dbfd72a9056bb0c6f0ab30602318a7cc6506664c794477381b614d6769717049454e496d537841476549754b446a494e4f474339000606060306075d35b198b8edef2fbd936b2b541dfec66c8c5771f7378bec10d22e363e01857f066f746a64586f184e4771634f55624e4c53655a4655444e435a4f6751594839000606050607e89c61f81be7b1144085acc70c36ea1c27f012581bcb98adec99b571105ec4231f7343795267575a496c6d4f496f5a4853695448635774785243707147454632056b44436859000713dbf86569a691c550f75e135114479119146ecf735153147c02c0ff40afa345036d4730145378484870527665455452676353644a6d487134000903934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4e0a0a903d8b9e255f0fcad5e4278bda7414eea1dfac5286592cd10667f895977c1479a6c0353c1a30f734be93b2162b5f799144b65059e294275ee33a3c16b70d87ab92dc1018f3bdfb3f4b16d9b0500040dda08f8248ad8cbebed4adacd6a011309f5d42149ace0040fec4de6384bfddb7245d5febbc636ab01cee5815980386625da9c6b91709ff95d73b0cdca51cf2111e6ef78e226bf9f4408002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c6d9ab40998fc30e14a0e93b5a69f09cb4edc782fc4f0db89a04957ab26ef095fea39ff27ad32ba391ad95559019430a5632f22501224ea1c6a9d9f463bd3a03", + "signed_txn_bcs": "05463318a70d83d99a7a2a53c6182909415f93baf8b4bfd25c6a3acd0643ec7bccb0ac2341a036580004c4b6de220306060406060605078bd27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be501a6363684d78545a4a4e6471676a5574574b425752686d4a6962390e4f4c6f596b516d61734775496a340000ed4d94b64d3713daccc09be90907fe3c70c21895c7b36b2031002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403518e11709becfab5cb2601a67327d846f82d514ebd2c6be1167c27cf3ad48141b95808c75b31a8c59f99028c6301bf5aa8e0c6c6f0f1c95e6ef4787fa989504", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5dec35ac246fbbfc7fa047e2d6b9c6044fc85d9df620647d2032b8084afaf191", - "sequence_number": "1930686019399630607", + "sender": "ab0aedf476aeb6bf7ea272d6485194d00f821031f7e2dbd9a997692203aaa713", + "sequence_number": "16648589168966582675", "payload": { "Script": { - "code": "e79fe34bfacd46b59cb511", + "code": "347cd1bec8b068bc8d", "ty_args": [ { "struct": { - "address": "93de7b3850971d5bc8dc0b7316b574d351a06cc77637afcefb51ad629010d2d7", - "module": "hMVbJtBJRZujhaRQVoSVjex5", - "name": "wwtDijeAfYQUrmY5", + "address": "961fde6a054b7130a2128e06b5f0302ba71da76cd0659c86c80dcfb65f789bc5", + "module": "IxGtlugwiTfIMeNkrurbsddJoFLsNtp", + "name": "HAbVfZwVBXSHjw1", "type_args": [] } }, { "struct": { - "address": "e332c3bb30c6a5620c60509d682b337c2624211133f22acc6d09447325ed5a95", - "module": "iqcGmhbwrYgFIQLxqPYskMupHjhI", - "name": "ppLdsxnkwRfaQVobyAHfmFJWFPjrF", + "address": "7d104d64052c5902a403f819a421ff6b95c62aabf2db9f7acbe87b8d5ddf719e", + "module": "OpuPpNEyoSrVrnZEneeGQTIiuh", + "name": "G6", "type_args": [] } }, { "struct": { - "address": "a559f100e2e908a77ee61fc90b80f79658cff531827386ac9bcb06141c3566a0", - "module": "STAZRpERwahslPuCiDQwdPlE2", - "name": "fgeCd0", + "address": "43613aa925e701542ec58dc03b76c1550d245d482fe3713505b41c02c7e70b18", + "module": "zwllKxGDaPaW", + "name": "lPcfoLCiDALrcsiuJAOzl", "type_args": [] } }, { - "vector": { - "struct": { - "address": "30a3cb3dc051c8a40a78bec7275518f5bc7f59cbeb3448875ed50e28b22347ff", - "module": "dCdwNcZVZAHMBFnhyBGLmtBuqJjvGuv", - "name": "QOhHqfCMcB", - "type_args": [] - } + "struct": { + "address": "905639dcb3dc90726c5846bb1e61bb696ecd30d430f2ee2c18fc7176bef8f84c", + "module": "ty7", + "name": "LnWUpYBbLidXrKYCObnsMBWT", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "bfa4400a24b876230302c169487fa9e864905af8f9a22edcff2e16adce187a73", - "module": "OlZwwkzEOZGSpQ7", - "name": "EW", - "type_args": [] - } + "struct": { + "address": "1d6780916986761313329d4b3be9469a17b6041eca0ee2c9b6d683a4bed839aa", + "module": "HcNuDXUDjpQnWGPRk", + "name": "DmWVCKeDHMhWdHZUdfidHmJ", + "type_args": [] } }, { - "vector": "u8" - }, - { - "vector": { - "struct": { - "address": "c22bddfe1c6710101e79702b4a24f909605be7f44fe5bf618ddc10915377f6d7", - "module": "nGyWJXG5", - "name": "AZiwPFCweKpXVPemWpkofymnF4", - "type_args": [] - } + "struct": { + "address": "e85552888bee5e278c22d011ee321a2960ccb306bf7c1d9e126032fc76ddb8e0", + "module": "WxEbUqJflRsyojBVYXwHCg6", + "name": "TisDWaYVBZqkEvCjIus", + "type_args": [] } }, { "struct": { - "address": "d290263bdbf28c68181ad4003d8eb2ff6bd4b797f2e30a984d959bbbf1fce73b", - "module": "hQTXAzOmXiqHGDPdygTcIOA", - "name": "YcCmOQZydrpABhwFgtfOsrui", + "address": "0f95ae2dce1cd67574bf60d5bf9d390217dad59330c805abe02f57ad26da97fb", + "module": "kBgE", + "name": "FueiETkGoQVJIotpdYqJWtbr9", "type_args": [] } }, { "struct": { - "address": "b3eb7c22046af41ac116aa75a5a85aafa5dbe9ecea7f255715eee00bf5f70cb8", - "module": "rhHVNfpspjmtsecymyoCEkrdUGc", - "name": "JeEvpQdOsiTPpfwFuLmiDfn", + "address": "db6e48834c7d7b8fc1a3d4935978dc45041291525656a72467dd25eb5526d4eb", + "module": "xFZpOOAoPhsjtfsHwGfQLKUdTpblUKCf", + "name": "lyOoVSiyyLJpjufKdLdT9", "type_args": [] } }, { "struct": { - "address": "853e693d1feac1b5d660b1d7f54b69b3174c14b9916a8a2fe734fb60747018be", - "module": "AMCpWUQPumHjkYcwREToNZvrFhuxOJcu4", - "name": "fVFJxq", + "address": "2bfbe6e1138767061f90ca38f06b05291d0aedfbe075e364492c58569f79ce07", + "module": "FQRCrbQkPBhhLnYWgd", + "name": "cBiaklye1", "type_args": [] } } ], "args": [ { - "Bool": false + "Address": "c32d0de8fa28ffbb40b9d319349dcf971010e7113bda5c031175578b3bbe2eda" }, { - "U128": "262930563587521952415156244747956297955" + "Bool": true }, { - "U8Vector": "03df98" + "U128": "254211244599074843831887360934135788922" }, { - "Bool": true + "U8": 66 }, { - "Address": "cf86491320ac54250a299e2e579bb435005d260f64bbe419e37268c644159ed1" + "U128": "97833133182255706541339503665876263457" }, { - "U64": "9001975557501623229" + "Address": "102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf069" }, { - "Bool": false + "U128": "104090777741055779958582672288738339321" }, { - "Address": "946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd0328075418" + "U8": 225 + }, + { + "U128": "15439701480389844381054627003488522079" } ] } }, - "max_gas_amount": "2586144858769439642", - "gas_unit_price": "9435749238933968853", - "expiration_timestamp_secs": "1472101799157070050", - "chain_id": 73 + "max_gas_amount": "10021860953213164887", + "gas_unit_price": "14185700538305981397", + "expiration_timestamp_secs": "961076190049227493", + "chain_id": 144 }, - "signed_txn_bcs": "5dec35ac246fbbfc7fa047e2d6b9c6044fc85d9df620647d2032b8084afaf1910fbf2097b42ccb1a000be79fe34bfacd46b59cb5110a0793de7b3850971d5bc8dc0b7316b574d351a06cc77637afcefb51ad629010d2d718684d56624a74424a525a756a68615251566f53566a6578351077777444696a654166595155726d59350007e332c3bb30c6a5620c60509d682b337c2624211133f22acc6d09447325ed5a951c697163476d6862777259674649514c78715059736b4d7570486a68491d70704c6473786e6b7752666151566f62794148666d464a5746506a72460007a559f100e2e908a77ee61fc90b80f79658cff531827386ac9bcb06141c3566a0195354415a52704552776168736c5075436944517764506c45320666676543643000060730a3cb3dc051c8a40a78bec7275518f5bc7f59cbeb3448875ed50e28b22347ff1f644364774e635a565a41484d42466e687942474c6d744275714a6a764775760a514f68487166434d6342000607bfa4400a24b876230302c169487fa9e864905af8f9a22edcff2e16adce187a730f4f6c5a77776b7a454f5a47537051370245570006010607c22bddfe1c6710101e79702b4a24f909605be7f44fe5bf618ddc10915377f6d7086e4779574a5847351a415a697750464377654b70585650656d57706b6f66796d6e46340007d290263bdbf28c68181ad4003d8eb2ff6bd4b797f2e30a984d959bbbf1fce73b1768515458417a4f6d586971484744506479675463494f41185963436d4f515a7964727041426877466774664f737275690007b3eb7c22046af41ac116aa75a5a85aafa5dbe9ecea7f255715eee00bf5f70cb81b726848564e667073706a6d74736563796d796f43456b7264554763174a6545767051644f7369545070667746754c6d6944666e0007853e693d1feac1b5d660b1d7f54b69b3174c14b9916a8a2fe734fb60747018be21414d437057555150756d486a6b5963775245546f4e5a7672466875784f4a637534066656464a78710008050002e3a010dbf8565f33d033476ea695cec5040303df98050103cf86491320ac54250a299e2e579bb435005d260f64bbe419e37268c644159ed101bd1ba2351371ed7c050003946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd03280754189abba70c0cd5e323d55752a8f083f282e278f86bc9f46d1449002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aca53cc6946bce8f739f637c696a4102be4d36a728982969dc0c450c8b039bc128e1f3adb816b3b21631e29ab3a37e7c7777331f50aeec0db0fee996e80af90c", + "signed_txn_bcs": "ab0aedf476aeb6bf7ea272d6485194d00f821031f7e2dbd9a997692203aaa7139341ab23a4ab0be70009347cd1bec8b068bc8d0907961fde6a054b7130a2128e06b5f0302ba71da76cd0659c86c80dcfb65f789bc51f497847746c756777695466494d654e6b727572627364644a6f464c734e74700f48416256665a7756425853486a773100077d104d64052c5902a403f819a421ff6b95c62aabf2db9f7acbe87b8d5ddf719e1a4f707550704e45796f537256726e5a456e656547515449697568024736000743613aa925e701542ec58dc03b76c1550d245d482fe3713505b41c02c7e70b180c7a776c6c4b78474461506157156c5063666f4c436944414c72637369754a414f7a6c0007905639dcb3dc90726c5846bb1e61bb696ecd30d430f2ee2c18fc7176bef8f84c03747937184c6e5755705942624c696458724b59434f626e734d42575400071d6780916986761313329d4b3be9469a17b6041eca0ee2c9b6d683a4bed839aa1148634e75445855446a70516e574750526b17446d5756434b6544484d685764485a5564666964486d4a0007e85552888bee5e278c22d011ee321a2960ccb306bf7c1d9e126032fc76ddb8e0175778456255714a666c5273796f6a425659587748436736135469734457615956425a716b4576436a49757300070f95ae2dce1cd67574bf60d5bf9d390217dad59330c805abe02f57ad26da97fb046b426745194675656945546b476f51564a496f74706459714a57746272390007db6e48834c7d7b8fc1a3d4935978dc45041291525656a72467dd25eb5526d4eb2078465a704f4f416f5068736a74667348774766514c4b55645470626c554b4366156c794f6f56536979794c4a706a75664b644c64543900072bfbe6e1138767061f90ca38f06b05291d0aedfbe075e364492c58569f79ce0712465152437262516b504268684c6e5957676409634269616b6c796531000903c32d0de8fa28ffbb40b9d319349dcf971010e7113bda5c031175578b3bbe2eda0501027af5344b68bf5c0609473282084e3fbf0042022162134f6fe592378a36500be0f9994903102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf06902f969ce3e1e823fd71094a77692274f4e00e1025fcf675e82a679a87ac2b82d0e949d0b57dda05870cd148bd5abcb037bbbddc4e552f8edb36d560d90002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408ed7f832ffdf404f68c756b4e99878f680e2d3726cae430596ecff520c469f6b956e43ac79dcc8f38ef7f367d4c6a20641b4c3b50f4697c3362d055e051efe0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4213f29dbf3fcb2bd597123262ed8f6f20de99f92384f0d44d75da9da2a606f7", - "sequence_number": "11849599448090427893", + "sender": "5366daa23bce1a85ea3967a94bc0ebf84914433cb1d78fc1f0f2c85a6e1ff032", + "sequence_number": "10838811419951474794", "payload": { "Script": { - "code": "0d3d6ac6", + "code": "0daf3f5bd99a2bcaac", "ty_args": [ { - "struct": { - "address": "0d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732ca467a610762399faf1", - "module": "MnIeqGyAjyTLR9", - "name": "PgaqXRXGEwNEaPduZGrDgcfvDjGwYEu", - "type_args": [] + "vector": { + "struct": { + "address": "ccb97d1651ebf2585133b5fafe2810970bf845d78e605b5d33ab925319defa1e", + "module": "KFHjKiChSJyxumWYymoenjrQu", + "name": "IDqlDLouzSGzotKxUdGaPG", + "type_args": [] + } } }, { - "struct": { - "address": "11a1497c9852eeee81e4220b509feadb31945a37284a945a3372d8f946de3aeb", - "module": "FPjnZxUivYyLTckvWSFk", - "name": "xOgbUt", - "type_args": [] + "vector": { + "struct": { + "address": "83fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c353cf3dc16dd", + "module": "ieJIMRiA", + "name": "QTAkPYIqHIxVGKpFLGzwK0", + "type_args": [] + } } + }, + { + "vector": "address" } ], "args": [ + { + "U64": "6321595345605947245" + }, + { + "Bool": true + }, + { + "U8Vector": "626fe00b6a3d514bd5c5a84adb7763" + }, + { + "Bool": true + }, + { + "U128": "63457244369885773050148059375950775617" + }, + { + "U64": "8603327848767259057" + }, { "Bool": false }, { - "U64": "17608128222000313866" + "U8Vector": "c57cbdcd3c" }, { - "U8": 210 + "U8Vector": "4df3278074ed1eed6d87" } ] } }, - "max_gas_amount": "13704429922159957780", - "gas_unit_price": "6109142244499550406", - "expiration_timestamp_secs": "1028314999427100147", - "chain_id": 36 + "max_gas_amount": "3834650048000301839", + "gas_unit_price": "14676635422596059984", + "expiration_timestamp_secs": "11818640550382943081", + "chain_id": 184 }, - "signed_txn_bcs": "4213f29dbf3fcb2bd597123262ed8f6f20de99f92384f0d44d75da9da2a606f7f541188aea3b72a400040d3d6ac602070d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732ca467a610762399faf10e4d6e4965714779416a79544c52391f506761715852584745774e45615064755a47724467636676446a4777594575000711a1497c9852eeee81e4220b509feadb31945a37284a945a3372d8f946de3aeb1446506a6e5a7855697659794c54636b765753466b06784f6762557400030500010af6db7753a35cf400d2141794af67ea2fbec670baf58008c854f3ed0e320b4f450e24002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dcd12cc075add40a3e72357a2db45fe481accd5fee0c3e5dcf2d441f9118d99c053d52e6cb2e4d6ccd7412c52bf6beeafbb46a1139a6c792358cba66d978bb08", + "signed_txn_bcs": "5366daa23bce1a85ea3967a94bc0ebf84914433cb1d78fc1f0f2c85a6e1ff0326aa8a7598f316b9600090daf3f5bd99a2bcaac030607ccb97d1651ebf2585133b5fafe2810970bf845d78e605b5d33ab925319defa1e194b46486a4b694368534a7978756d5759796d6f656e6a725175164944716c444c6f757a53477a6f744b7855644761504700060783fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c353cf3dc16dd0869654a494d526941165154416b5059497148497856474b70464c477a774b3000060409016def9a3c79d1ba570501040f626fe00b6a3d514bd5c5a84adb77630501024145deb41e1f9937ca4789c8b36bbd2f01b181ff971829657705000405c57cbdcd3c040a4df3278074ed1eed6d870f1bfedce669373550d3c01d28e2adcb693b9a75f63e04a4b8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c6fa69ba3853ee6dd52f8a05422505518095669e3d823dff2ba5ecaa0295a9316eba20efba5a24e98a504e9adb2f4b12b98acafe8d87aa4f7c9bae387a65ce0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "da8a0a6ea1495e03b51718c9a91051b01cf94dd16c23c538432037e743fc96d6", - "sequence_number": "2044898358789552004", + "sender": "ac0760a704c449a03193fa060e1b8c41c6b2037f2acf2b2fd7f8e60e9efc9e45", + "sequence_number": "11360494150803451654", "payload": { "Script": { - "code": "5db6d1fa", + "code": "b27fc9f0d818b154cd4da0bca6", "ty_args": [ { "struct": { - "address": "28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce99fda20d895948ba", - "module": "igaxdIgYWbGVAJBvqCPLzgvmvcrR", - "name": "C", + "address": "a0dfe99d522efe5d53309b4a72675b7628b9147b659480a91687dfe2f1707d15", + "module": "tWihgevNG", + "name": "EHdQnQRyhahLRBkXrSQysJ5", "type_args": [] } - }, + } + ], + "args": [ { - "vector": { - "struct": { - "address": "21b2895144b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec", - "module": "WIH", - "name": "aPtEtOYpGPNO", - "type_args": [] - } - } + "U64": "1040913975628432616" }, { - "vector": "signer" + "Address": "7e7b7b30dd7969baedb3dbe1e111031fec82b05225d9a46c7f6f4a8d5559b1aa" }, { - "struct": { - "address": "efe01408d1c42013f0c2f9d9f9fcf2720fd56f20b02202c459be5ddab13bed1e", - "module": "LYwOlALhkmY", - "name": "LnjkVKDRkTtMVjuIdRbs8", - "type_args": [] - } + "U128": "311376526564884573071967890926569318512" }, { - "struct": { - "address": "532f7a818988e8a96eb80d78f032ada2665a39104bbfda7921ba2dceaa45cfac", - "module": "XgefMiwMUBqkQqoJYkMSJBeJaEndf8", - "name": "ayhVkHY", - "type_args": [] - } + "U8": 240 }, { - "struct": { - "address": "72ffbf25284f16f40c21dd3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b", - "module": "eoJPTCjayex", - "name": "JVjxyGuEGHZkCGRhXhosCSbi3", - "type_args": [] - } + "U128": "181478793818321106459908050269555341146" }, - { - "vector": { - "vector": "signer" - } - } - ], - "args": [ { "Bool": false - }, - { - "U8Vector": "8b3f45c9" } ] } }, - "max_gas_amount": "18121609316144400377", - "gas_unit_price": "16900354104346654057", - "expiration_timestamp_secs": "12434008238370568224", - "chain_id": 47 + "max_gas_amount": "15229539943640243686", + "gas_unit_price": "14978038977400147217", + "expiration_timestamp_secs": "9333885236940749081", + "chain_id": 162 }, - "signed_txn_bcs": "da8a0a6ea1495e03b51718c9a91051b01cf94dd16c23c538432037e743fc96d684376e1539f0601c00045db6d1fa070728288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce99fda20d895948ba1c696761786449675957624756414a42767143504c7a67766d76637252014300060721b2895144b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec035749480c61507445744f597047504e4f00060507efe01408d1c42013f0c2f9d9f9fcf2720fd56f20b02202c459be5ddab13bed1e0b4c59774f6c414c686b6d59154c6e6a6b564b44526b54744d566a754964526273380007532f7a818988e8a96eb80d78f032ada2665a39104bbfda7921ba2dceaa45cfac1e586765664d69774d5542716b51716f4a596b4d534a42654a61456e64663807617968566b4859000772ffbf25284f16f40c21dd3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b0b656f4a5054436a61796578194a566a787947754547485a6b4347526858686f7343536269330006060502050004048b3f45c9f947321fa9e37cfb69b5e517841e8aea20b85b569d788eac2f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444029299aedac4ae9cab227efbe905d044addd7344cb59e3c5cb8dd66ad433aacf064027b8d349c4f0cd0fb83bce42f446f4b4dfbde031d4d86bce8aa7e4413c704", + "signed_txn_bcs": "ac0760a704c449a03193fa060e1b8c41c6b2037f2acf2b2fd7f8e60e9efc9e4506ef8a5b3d95a89d000db27fc9f0d818b154cd4da0bca60107a0dfe99d522efe5d53309b4a72675b7628b9147b659480a91687dfe2f1707d1509745769686765764e4717454864516e5152796861684c52426b5872535179734a35000601e88412efbe11720e037e7b7b30dd7969baedb3dbe1e111031fec82b05225d9a46c7f6f4a8d5559b1aa0270e858b89038be59bb50cfc409f040ea00f0025a37977a24b940b80c77771e598b87880500e69d4ca1e3315ad3110de4c717afdccf19b91d822b9f8881a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d27067bdcfd1e10f019b961e59cb53b2a6a2081cdea76c4059e103c3ea42fb731a6f4e5a9426abd68022bd585e48b9a209de32618748855eefd04fa4b7994505", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3016f570cbfcd2384527c0c1a1172c8aa89cd9fe7ccc03289c7b22b3c27c5e9f", - "sequence_number": "17882037105359852191", + "sender": "492cbdc0622fbbbdae0c779cc88932cac59a74250638f00cc56524a06674b843", + "sequence_number": "10014795794658293170", "payload": { "Script": { - "code": "0ae2961ee366d82abf636ef642", + "code": "53de70fc2b4aedbbea", "ty_args": [ { - "struct": { - "address": "b14d57f6cc49a80ee9617d3614870f0c9fb54d05c24255b3de4f43a5fbb183ac", - "module": "ZfHhLJcVhufPtdQoHUapcAPKKBYAeVhC", - "name": "nCuGT", - "type_args": [] + "vector": { + "struct": { + "address": "308d39e97e85043e640921a5d884a0b284fbfe204fdc07cfef91b7ac0fb037e7", + "module": "AALWePDanyHwLvIkrpEmxwToVeWHlYXV6", + "name": "ioROBFZeATokWuBx9", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "a32ae9d0aa5a2baec6cc74b5279b74252492835eb806196a7ce0d1fb3ad1ca0a", - "module": "iwNdQtv", - "name": "vS9", + "address": "b87066910ae8cf70633a76a8628085092b0d9f4885b1d1be2ef09fe88e09d809", + "module": "xrTlSQNaRIhcppBYFVuRqYr6", + "name": "aXCCkU3", "type_args": [] } } }, { "struct": { - "address": "23a98e4a854808eba299f43065bbf17fbe544fba6a043c2b16d40e2fbe67c00e", - "module": "W9", - "name": "psLoLmCSBEIKSkXuYOLNbHiYE4", + "address": "eafa512f87158bd7d28a80cafd9ba4993d61b5b2536f750432561fa6dfbb6f09", + "module": "CPHAGNEYyCFjKrGMtNUzsCE", + "name": "kIQJfWmcyIuObWPfjedqksRecTl6", "type_args": [] } }, { "struct": { - "address": "4ced9376224399222b31b9ad09996b7bbae480f1981ab26aba48df4ffef18efe", - "module": "nLMIvubaWjcVm", - "name": "UlVmctQS7", + "address": "3ef067b3f1831d6990217d886ed493804db54297edf52e90e5165cc07f4fa97b", + "module": "dIXzgF4", + "name": "xgQfItdhlnBTjjiNhYMaYpZMNK0", "type_args": [] } }, + { + "vector": { + "vector": { + "vector": "u64" + } + } + }, + { + "vector": { + "vector": { + "vector": "u8" + } + } + }, { "struct": { - "address": "09a12be6b13bedc3960b828a344c47d6521459acb7feab2af46a23ee5fa838ab", - "module": "FDemogDVBRIpzHlkw", - "name": "pv", + "address": "b999605b9ea506bd1eec7cfed0ff3a33814f3cb34a419b1ab3428498ec5cdae9", + "module": "YMyMMpGtyGfGnk4", + "name": "kiPoicVsCIOuzotgVV", "type_args": [] } } ], "args": [ { - "U8": 181 - }, - { - "U64": "5944416058970951721" - }, - { - "U8": 203 - }, - { - "U8Vector": "cfe10511ac6a92d8eff15abd0a56" - }, - { - "U128": "234889453750481879312164067104052621660" + "Address": "42057e7339ccb5559628c0ebbf0cdd54708fe98cb0f1309315b87dc7aae9e97f" }, { - "U8": 110 + "Bool": false }, { - "U8": 153 + "U8Vector": "ba" }, { - "U128": "276034989414573574914673590497258359296" + "U64": "9304155991702506264" }, { - "Address": "c995645fb4eac2dff08090ec8aef92dccabee582b067dd8af3392393c52ae51c" + "U8Vector": "66f7ffe79a28dc5d9dc59b4e" }, { - "U8": 13 + "U8Vector": "e393c5eaa4d18118ca20af" } ] } }, - "max_gas_amount": "10476342948306686394", - "gas_unit_price": "8990236584983068033", - "expiration_timestamp_secs": "17891741780155462635", - "chain_id": 77 + "max_gas_amount": "10486369804270171442", + "gas_unit_price": "6258567329192714545", + "expiration_timestamp_secs": "773546943721589078", + "chain_id": 251 }, - "signed_txn_bcs": "3016f570cbfcd2384527c0c1a1172c8aa89cd9fe7ccc03289c7b22b3c27c5e9f9f12541501c229f8000d0ae2961ee366d82abf636ef6420507b14d57f6cc49a80ee9617d3614870f0c9fb54d05c24255b3de4f43a5fbb183ac205a6648684c4a6356687566507464516f485561706341504b4b42594165566843056e43754754000607a32ae9d0aa5a2baec6cc74b5279b74252492835eb806196a7ce0d1fb3ad1ca0a0769774e6451747603765339000723a98e4a854808eba299f43065bbf17fbe544fba6a043c2b16d40e2fbe67c00e0257391a70734c6f4c6d43534245494b536b5875594f4c4e62486959453400074ced9376224399222b31b9ad09996b7bbae480f1981ab26aba48df4ffef18efe0d6e4c4d4976756261576a63566d09556c566d6374515337000709a12be6b13bedc3960b828a344c47d6521459acb7feab2af46a23ee5fa838ab114644656d6f674456425249707a486c6b77027076000a00b50129501728e9ce7e5200cb040ecfe10511ac6a92d8eff15abd0a56025c31a24a4d7e85b728aab1cc3110b6b0006e00990200caf1a3ffcad9e9d37abff4b967aacf03c995645fb4eac2dff08090ec8aef92dccabee582b067dd8af3392393c52ae51c000dba11fdca6772639181fda2ae8abcc37ceb732ec35a3c4cf84d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b5df9a65c6106d692a0b16aa7673605fafaa6e1b4bcaf5056135fbec6367e98ffdce5195d428f51326e4d9643cf3423615c735c2b9f0fbb54b6d8ba31e53b03", + "signed_txn_bcs": "492cbdc0622fbbbdae0c779cc88932cac59a74250638f00cc56524a06674b843b2f5aeeeb6b3fb8a000953de70fc2b4aedbbea070607308d39e97e85043e640921a5d884a0b284fbfe204fdc07cfef91b7ac0fb037e72141414c57655044616e7948774c76496b7270456d7877546f566557486c5958563611696f524f42465a6541546f6b5775427839000607b87066910ae8cf70633a76a8628085092b0d9f4885b1d1be2ef09fe88e09d809187872546c53514e615249686370704259465675527159723607615843436b55330007eafa512f87158bd7d28a80cafd9ba4993d61b5b2536f750432561fa6dfbb6f091743504841474e45597943466a4b72474d744e557a7343451c6b49514a66576d637949754f625750666a6564716b73526563546c3600073ef067b3f1831d6990217d886ed493804db54297edf52e90e5165cc07f4fa97b076449587a6746341b78675166497464686c6e42546a6a694e68594d6159705a4d4e4b3000060606020606060107b999605b9ea506bd1eec7cfed0ff3a33814f3cb34a419b1ab3428498ec5cdae90f594d794d4d704774794766476e6b34126b69506f6963567343494f757a6f7467565600060342057e7339ccb5559628c0ebbf0cdd54708fe98cb0f1309315b87dc7aae9e97f05000401ba01180b403494001f81040c66f7ffe79a28dc5d9dc59b4e040be393c5eaa4d18118ca20af32f5e71ec711879131a1659bd3e5da5656499dcdd830bc0afb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ec4de47a91fcf4da2568f9d83bc522e280d32e7661dc6d9eaac59227195f0ca4afc63c938de75c833c6cb9819ca09e435789be8363fe90a6dc831057aa7d090f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18d3", - "sequence_number": "8540763488405155213", + "sender": "f61270099d80975c9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115", + "sequence_number": "7074675893320599764", "payload": { "Script": { - "code": "620aef", + "code": "bf207cc4a4b7", "ty_args": [ { "struct": { - "address": "d5b5ed068f578c9c446443068a93c18a1473d9e3b783c6a9574ef8eeb983cb9a", - "module": "VxHNKaeHUXDcVwttLVsX", - "name": "tyZhoRQpRCpwpeTvZslTbKVgILHSS", + "address": "034f29cfc8a1805dc9c3ca90f59cbf7c20b96cdfebdb009b0ae131470ad0700a", + "module": "dojKcVWGsfurhtMGX", + "name": "ZKHIjStq3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "0f7e9088febd61cd3b2122e83f4ddd9fa8074fe497fc587d91ea1d179e0d58a0", - "module": "kFZgDZuIOSEXphJCiQRFbbLUnEaq", - "name": "vtumtuhmJzjf", - "type_args": [] - } + "struct": { + "address": "ac5363ea81f1d93514ed956337c5fb2a3b608f70704f215032db0ff7d572a018", + "module": "GWEthN0", + "name": "AEppHXvANtMzOLMGCGoU", + "type_args": [] } }, { "vector": { - "vector": "signer" + "struct": { + "address": "2a0a48152b4205bd1d68e4f4a440839cbb89e20f2eeaf7e41333f3ea533aca59", + "module": "hcNlScUKpawSYlfSJPuodUbl", + "name": "XasTocCZXltTquuEjgDyYarj3", + "type_args": [] + } } }, { "struct": { - "address": "7d30ac1a0579160256d64ae086f9dcd6ba0a0ec762e438e7b78fb5eb4381b5dd", - "module": "yotVjLdlYTWXHNEstCIWZ", - "name": "MOxRZCugsUYShMWCbUVHEluwNowIX3", - "type_args": [] - } - } - ], - "args": [] - } - }, - "max_gas_amount": "12082630409813889442", - "gas_unit_price": "12221669662445329259", - "expiration_timestamp_secs": "9290029090669801926", - "chain_id": 84 - }, - "signed_txn_bcs": "37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18d38ded034d24e386760003620aef0407d5b5ed068f578c9c446443068a93c18a1473d9e3b783c6a9574ef8eeb983cb9a145678484e4b61654855584463567774744c5673581d74795a686f52517052437077706554765a736c54624b5667494c4853530006070f7e9088febd61cd3b2122e83f4ddd9fa8074fe497fc587d91ea1d179e0d58a01c6b465a67445a75494f53455870684a436951524662624c556e4561710c7674756d7475686d4a7a6a6600060605077d30ac1a0579160256d64ae086f9dcd6ba0a0ec762e438e7b78fb5eb4381b5dd15796f74566a4c646c59545758484e4573744349575a1e4d4f78525a43756773555953684d574362555648456c75774e6f774958330000a2114a595720aea76bdb3808ce179ca9c6316bbe3cd0ec8054002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b7bbab116642202052b91c70d800a81049a25b427d95eacc6815b9c90e4110161ebd917bb003a81a5187e9b9ba8dba7bf3a158c55f0649acd90ba7e74dad8001", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "592f71d24a86160aee3f518a0bb78a315fe07ea9d8ca279b64f6bcb4b56e2de4", - "sequence_number": "9169727676310944314", - "payload": { - "Script": { - "code": "e86a527decf2fa6fa8", - "ty_args": [ - { - "struct": { - "address": "f251e2fdd6d84499cd3a9d6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7be", - "module": "nsrXrhJhnwnGKyFNzqSkRSFwpXExFZIk0", - "name": "EfhwJTJGLCY", + "address": "36c9ce04cb9a013655056511e54aed4e175fa45abba38f845939b45475adef62", + "module": "kTtVKvXpfZyb", + "name": "AuSKKUzSvFFlDKaTbxXAvjMPuY0", "type_args": [] } }, { "vector": { "struct": { - "address": "f4623e60e7bc825d5b97dbff3f932845c7f1fbe7d2444bf744dbc72ba6001357", - "module": "iRDvokUkJXqPOZoiIvRDiXF6", - "name": "uZlQtXgGZTiL", + "address": "039da6eae422b6e1305ea9f24ce331ced87f7731d96825978bc59de99037e457", + "module": "aZkRcWwMaYYxVCqhHWJg0", + "name": "ruLAeaINeFtStvjeUZdAEkZVWThINw9", "type_args": [] } } @@ -2279,81 +2262,89 @@ { "vector": { "vector": { - "struct": { - "address": "b00bd60e71d379119c7059c0c504e7cf98885fdddd55b775acf0a48d136355d4", - "module": "vXIlyyakEdwjPjoDLUAVYPm", - "name": "uViBV1", - "type_args": [] - } + "vector": "u8" } } - } - ], - "args": [ - { - "U128": "112155803909479183986279334731816694555" - }, - { - "U8": 247 }, { - "U64": "12310332194893902679" + "struct": { + "address": "f757bae2081bd62367a4a600e5110979c1481fe529e35fc8e0a49c411332255f", + "module": "h6", + "name": "vHMokBUhCWqQIOWQvueTXGbMO", + "type_args": [] + } }, { - "Address": "4c9b4baf5c32dabdc0ee15edf6c16a9a1e1e2aabe01d86e0f7ddfc8218cb2ba2" + "struct": { + "address": "af727b20ee9e09dfe80ca68e960a62b40b21da719ddf7d658c3de5d2046030ec", + "module": "RaOcsUoTq2", + "name": "eDyQVDCHUHvfKbmuQXWphJj5", + "type_args": [] + } }, { - "U8": 142 + "struct": { + "address": "4827703b68750a1a2bc398ce0658a6f7c995aec0d12c07877ce2b5e90c01827a", + "module": "oIQSJiMsnGzB", + "name": "EHn", + "type_args": [] + } }, { - "U8Vector": "d4f157f64b8ddad59160a98ffc8fdd" - }, + "vector": { + "vector": "u64" + } + } + ], + "args": [ { - "U8": 136 + "Bool": false }, { - "U64": "4686224094570393612" + "Address": "a1a4790ed0f2211955b6749750559945c5e6a2aab55d4b3e1fa61feebb89198b" }, { - "U64": "7233804134355271388" + "U8": 212 }, { - "Bool": false + "Bool": true } ] } }, - "max_gas_amount": "7092256970346917398", - "gas_unit_price": "16895287754651257858", - "expiration_timestamp_secs": "5754006700794787217", - "chain_id": 37 + "max_gas_amount": "4651959406551131875", + "gas_unit_price": "27169274433095166", + "expiration_timestamp_secs": "3016496912331981779", + "chain_id": 146 }, - "signed_txn_bcs": "592f71d24a86160aee3f518a0bb78a315fe07ea9d8ca279b64f6bcb4b56e2de43afa9401bd6a417f0009e86a527decf2fa6fa80307f251e2fdd6d84499cd3a9d6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7be216e73725872684a686e776e474b79464e7a71536b5253467770584578465a496b300b456668774a544a474c4359000607f4623e60e7bc825d5b97dbff3f932845c7f1fbe7d2444bf744dbc72ba600135718695244766f6b556b4a5871504f5a6f6949765244695846360c755a6c51745867475a54694c00060607b00bd60e71d379119c7059c0c504e7cf98885fdddd55b775acf0a48d136355d4177658496c7979616b4564776a506a6f444c55415659506d06755669425631000a021bf3e4099312c2385a3f14f70f6c605400f70157b3b487e815d7aa034c9b4baf5c32dabdc0ee15edf6c16a9a1e1e2aabe01d86e0f7ddfc8218cb2ba2008e040fd4f157f64b8ddad59160a98ffc8fdd0088010cb0be3efccf084101dc7effaa88a26364050016ee505d23c26c6202ccfea1b21e78ea913517bc9b56da4f25002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402db1959c1b49019975172122b4108e56f676351bdff074afef544e8fcf1a222a4c0e0cffc43287085e71070c4aba1acb95680ddc14083d599ba875148c59d00e", + "signed_txn_bcs": "f61270099d80975c9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d4c864e23d4c2e620006bf207cc4a4b70a07034f29cfc8a1805dc9c3ca90f59cbf7c20b96cdfebdb009b0ae131470ad0700a11646f6a4b635657477366757268744d4758095a4b48496a537471330007ac5363ea81f1d93514ed956337c5fb2a3b608f70704f215032db0ff7d572a0180747574574684e301441457070485876414e744d7a4f4c4d4743476f550006072a0a48152b4205bd1d68e4f4a440839cbb89e20f2eeaf7e41333f3ea533aca591868634e6c5363554b70617753596c66534a50756f6455626c19586173546f63435a586c7454717575456a6744795961726a33000736c9ce04cb9a013655056511e54aed4e175fa45abba38f845939b45475adef620c6b5474564b765870665a79621b4175534b4b557a537646466c444b615462785841766a4d50755930000607039da6eae422b6e1305ea9f24ce331ced87f7731d96825978bc59de99037e45715615a6b526357774d615959785643716848574a67301f72754c416561494e6546745374766a65555a6441456b5a56575468494e7739000606060107f757bae2081bd62367a4a600e5110979c1481fe529e35fc8e0a49c411332255f0268361976484d6f6b42556843577151494f5751767565545847624d4f0007af727b20ee9e09dfe80ca68e960a62b40b21da719ddf7d658c3de5d2046030ec0a52614f6373556f547132186544795156444348554876664b626d7551585770684a6a3500074827703b68750a1a2bc398ce0658a6f7c995aec0d12c07877ce2b5e90c01827a0c6f4951534a694d736e477a420345486e0006060204050003a1a4790ed0f2211955b6749750559945c5e6a2aab55d4b3e1fa61feebb89198b00d40501e36604e16e148f40fec563a74f866000d3439cadf5bfdc2992002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023f24f7b1010f824301f9f6f08587efc073c65649b5efee44552cd1db5f856004baf3fbf3bc66494b889697a88abebc2d31c275329d1ef01aad3196cfee8e600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5d8feb86ca256f52bdc48766ceccb284bee92b5c4cc459d337e62cb6de8ccabd", - "sequence_number": "14743781543221447808", + "sender": "86b87357d3c522af0e3ccc8de8da15385a2b209761b56b7dfa6a1bb6e010abec", + "sequence_number": "404549278413470988", "payload": { "Script": { - "code": "b9", + "code": "f6087227", "ty_args": [ { - "struct": { - "address": "5f2e7892df226d49f7b201f477bfcdc01ecfb6244a2090ad0db8af19218b4239", - "module": "iUlMBKLNdcmYmmpOOwbJmPsclEFJkcjO", - "name": "nmwugjFFiLCNeOc0", - "type_args": [] + "vector": { + "struct": { + "address": "7920ee815072911b30d570541344c4d8d197549a05f5d09e9d2e6928acc9e3ce", + "module": "NmiUWbRcYyFIuXKYhcRnMZI", + "name": "uixyc", + "type_args": [] + } } }, { "vector": { "vector": { "struct": { - "address": "40ebb1f6f66eb2d922aa9b7ea162720a2254aefa55aaf280c96565c59f60b8d0", - "module": "iasDiaSBqbsTiFYvdEtstmPCIG", - "name": "LzKNSuaiErYhk", + "address": "86b83a64f34db202eef270075540736f6d3fea21d6c399a3d4f2ce82532556b2", + "module": "egnOnGVhCVaFPBdawKUbvBtZHKJu1", + "name": "KoEWKkwqtwhc", "type_args": [] } } @@ -2361,271 +2352,313 @@ }, { "vector": { - "struct": { - "address": "f54249adaf59fa534d3dceb851077c0562d76c53034d1103c3c75c976e5f5192", - "module": "auYBereqdAa", - "name": "ysLPhowohXxVBgBXaAKaNatyLadmqH6", - "type_args": [] - } + "vector": "u128" } + } + ], + "args": [ + { + "U128": "227256863336655445251818701500700937500" }, { - "vector": "u8" + "Address": "76dbc19864fb6861367625dc5b763c941d62b316af3765176bf6206bddee65ff" }, { - "vector": { - "struct": { - "address": "1e7e91835587b43fd796e8e8d6d9bec0f7e38f646fb48bffaa8cffaec9176958", - "module": "EClydrVhoHyFbye7", - "name": "sChPfFPsAsfIByJlDmWbJ7", - "type_args": [] - } - } - } - ], - "args": [ + "U8Vector": "29" + }, + { + "U64": "6759228007510437688" + }, { - "U8Vector": "d9cadcacedea27224ada47aa4f688e87" + "U128": "22373333087657506833071305838259824444" }, { - "U64": "9013362639669053" + "Bool": false }, { - "U64": "7568998237139347555" + "Address": "34552c5f076d3a760c32b6ab87e412e23c083728c8290eb9fdf471ca3d62766f" }, { - "Address": "b710806365d3f8ec1f744abd9bc5ebbe50921c9bea037151e18bcea8bcd3c337" + "Address": "5698bbfc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b3" } ] } }, - "max_gas_amount": "1692258841077112611", - "gas_unit_price": "4274255541197264352", - "expiration_timestamp_secs": "985506230859005061", - "chain_id": 175 + "max_gas_amount": "2822368108429471272", + "gas_unit_price": "11575837400634404389", + "expiration_timestamp_secs": "5613918175603189730", + "chain_id": 201 }, - "signed_txn_bcs": "5d8feb86ca256f52bdc48766ceccb284bee92b5c4cc459d337e62cb6de8ccabd80ccac99326f9ccc0001b905075f2e7892df226d49f7b201f477bfcdc01ecfb6244a2090ad0db8af19218b42392069556c4d424b4c4e64636d596d6d704f4f77624a6d5073636c45464a6b636a4f106e6d7775676a4646694c434e654f63300006060740ebb1f6f66eb2d922aa9b7ea162720a2254aefa55aaf280c96565c59f60b8d01a6961734469615342716273546946597664457473746d504349470d4c7a4b4e53756169457259686b000607f54249adaf59fa534d3dceb851077c0562d76c53034d1103c3c75c976e5f51920b61755942657265716441611f79734c50686f776f685878564267425861414b614e6174794c61646d71483600060106071e7e91835587b43fd796e8e8d6d9bec0f7e38f646fb48bffaa8cffaec91769581045436c79647256686f487946627965371673436850664650734173664942794a6c446d57624a3700040410d9cadcacedea27224ada47aa4f688e87013d875e069b0520000163a83f5ecb7b0a6903b710806365d3f8ec1f744abd9bc5ebbe50921c9bea037151e18bcea8bcd3c337235f6a32731c7c17e0d54eccc434513b85fc480eb238ad0daf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404683eb031e047ce742ed3de8a4fb9bcac09169db72f3626367293cbc9813854996e1667cda9158de4004f098154c5af06b2db60e7fbb4cb2dbdbe2fdd16be903", + "signed_txn_bcs": "86b87357d3c522af0e3ccc8de8da15385a2b209761b56b7dfa6a1bb6e010abec0cbdf9e16c3f9d050004f60872270306077920ee815072911b30d570541344c4d8d197549a05f5d09e9d2e6928acc9e3ce174e6d6955576252635979464975584b596863526e4d5a490575697879630006060786b83a64f34db202eef270075540736f6d3fea21d6c399a3d4f2ce82532556b21d65676e4f6e4756684356614650426461774b55627642745a484b4a75310c4b6f45574b6b7771747768630006060308021ccd87a89391a04f1459fede6e14f8aa0376dbc19864fb6861367625dc5b763c941d62b316af3765176bf6206bddee65ff0401290138ef87970f9acd5d023c6787352a99bbe761756dad7cf2d41005000334552c5f076d3a760c32b6ab87e412e23c083728c8290eb9fdf471ca3d62766f035698bbfc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b3286e5450d7102b2725ae7ed2c8a2a5a0e2e7ef3ed6a4e84dc9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444054b487d7d4ad507c14102938f224836dfb5690b01f57034775f3bcf42e9e6fdf115951ef72ba73d682524f40f1425ec5bc68a65eb66ac527932038f10ea9e00d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f7c4446bd445b75ee341cfe0381b0fa1f1740e8d6610644f6b1e4bec9278f5a6", - "sequence_number": "9494789570812305745", + "sender": "fd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1ef10ca336626", + "sequence_number": "8012530865797725776", "payload": { "Script": { - "code": "d2c17dd8722d88a46d45f2bd950ad7", - "ty_args": [], + "code": "12ce8fd26a5d2b940e", + "ty_args": [ + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "struct": { + "address": "4434e41c71e37f4f985ec3ad0ad900ec8ebd23274a70416623d5becb5ea806dd", + "module": "kwq", + "name": "NBSODdkbGuAUQQThEhUotHmRdR9", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "e577cc78e9646592aa595e2863321a631695d64c5da1efedb7b4774c39f5d3a0", + "module": "OJMZMvwCbIWvLpSMjTrcnjrNlUt7", + "name": "REQAphMJXkzDXHtjXZD", + "type_args": [] + } + } + }, + { + "struct": { + "address": "bdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b80e8c46", + "module": "uOIbLtXGSuwLGLEKSDqbL", + "name": "CtfKZNkbSHHeFRwCSasVZTlqs", + "type_args": [] + } + } + ], "args": [ { - "Bool": true + "Bool": false }, { - "U8Vector": "2e9816cdff0afac22812babce8" + "U128": "87365757594906072518882772707606604623" }, { - "U8": 35 + "U64": "9321582198391004080" }, { - "U64": "2215184528335456973" + "U128": "206177304539752532775225512981783533406" }, { - "Address": "fdc85a6e02066f9a6ac6a95ec53a318ec26922d2b4b47c5cebd5cb3b0a5af493" - } - ] - } - }, - "max_gas_amount": "15272936314777272654", - "gas_unit_price": "14775369019845558883", - "expiration_timestamp_secs": "2550760206131445245", - "chain_id": 60 - }, - "signed_txn_bcs": "f7c4446bd445b75ee341cfe0381b0fa1f1740e8d6610644f6b1e4bec9278f5a651e15921cf44c483000fd2c17dd8722d88a46d45f2bd950ad700050501040d2e9816cdff0afac22812babce8002301cd4a608b97eabd1e03fdc85a6e02066f9a6ac6a95ec53a318ec26922d2b4b47c5cebd5cb3b0a5af4934e8176a7a85ef4d363c2341dd7a70ccdfdbdaa99e41e66233c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c4675a2d9486b6227a9fa85b2fb68d7e24ff10e7ff1e683fc136c33e0438516f1820aecd180d197eebe595260bcbb8880e312ca385b755b5099098e82c77fd04", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc7151819b163058", - "sequence_number": "93087573714700565", - "payload": { - "Script": { - "code": "65c3bf2be2d2aca1a840", - "ty_args": [], - "args": [ + "U64": "15049080533632696097" + }, { - "U8Vector": "48" + "Address": "6ec643c9b9101cd89c539c33ea9111fe77139e97e073205cc722d26e68dd1123" }, { - "U8": 10 + "U128": "151415075041809247393355773762258533856" }, { - "U8Vector": "8decf0ebcb87ba8a55a0af5cd4cd32" + "U64": "7219431739781086568" } ] } }, - "max_gas_amount": "12510455267995156094", - "gas_unit_price": "9919112838882768429", - "expiration_timestamp_secs": "17452032925716965600", - "chain_id": 105 + "max_gas_amount": "11706266843780901541", + "gas_unit_price": "4594881765337666540", + "expiration_timestamp_secs": "5069264976216212089", + "chain_id": 132 }, - "signed_txn_bcs": "1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc7151819b163058158944b4a7b64a01000a65c3bf2be2d2aca1a8400003040148000a040f8decf0ebcb87ba8a55a0af5cd4cd327efe4373c8109ead2db69fc092c4a789e0e8c7297b1332f269002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405467c77caa3417c717a88857f2b00327d18a430b86a1b4dc49b47a441e3e95288217b42fa7aa022069dfba46bd51b3e5b70ffd216893796c851ea96286862400", + "signed_txn_bcs": "fd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1ef10ca33662650feb9c75e3a326f000912ce8fd26a5d2b940e0406060206074434e41c71e37f4f985ec3ad0ad900ec8ebd23274a70416623d5becb5ea806dd036b77711b4e42534f44646b6247754155515154684568556f74486d52645239000607e577cc78e9646592aa595e2863321a631695d64c5da1efedb7b4774c39f5d3a01c4f4a4d5a4d767743624957764c70534d6a5472636e6a724e6c557437135245514170684d4a586b7a445848746a585a440007bdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b80e8c4615754f49624c7458475375774c474c454b534471624c194374664b5a4e6b625348486546527743536173565a546c717300080500024f2ba561f4fb7aaf24bc39f26908ba4101b05bb31f9fe95c81025e57ae7f2ad963283ca22c86f14d1c9b01213f6c0b0313d9d0036ec643c9b9101cd89c539c33ea9111fe77139e97e073205cc722d26e68dd112302e0fdb685095ab818fd6cde95927be9710168fdd4c9ea923064a56a7e05ac0375a2ec13dfef9e4cc43f7942b243a3a5594684002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea00dc6c2c4bc99746763e6c9a50325e8b580ccd824c731b7532d053fad068a7fdb8f91b7f9c3bf893357d9bf56efb1b0d725cbb2b12a4674de46d56d0371203", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e4c685f4517b068bb0c727af20429c95b788e21e4463b98443b55f0aedc781d3", - "sequence_number": "7844837829379685075", + "sender": "17f683a8f2b73390fc4ef83c67728a684c0cebd4d5887f03dac7ac33d178ef0e", + "sequence_number": "7878198917564551839", "payload": { "Script": { - "code": "4adffed56d1d9f5fea", + "code": "713fa6d13f", "ty_args": [ { - "struct": { - "address": "0b98a633bf8c25236689d8bac4ba19d24673b2db6fa869c78fec53ce0ddd0220", - "module": "PoYMCAC", - "name": "RCnUZjidUtcLlvHDjoDDPPGu9", - "type_args": [] + "vector": { + "struct": { + "address": "3b5babe04d7115442a1d96eeb09928cf9780f94bc5a376a23274043030de58eb", + "module": "wfWCEEhbcbSntARhEnTzFO", + "name": "dOChJNlLvC7", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "64a1ae397fe1da7d2381a546cb32298322e79b972aa8ee6158bae854287dd7ec", + "module": "wQjuwazivhqbhlCZEIPqgSevZoIXIm3", + "name": "nKnnTuYbJcMWWlBlytdOdVcJLKgqe1", + "type_args": [] + } } }, { "vector": { "vector": { "struct": { - "address": "aad1c4b6bdd1bb80b29f2f0a1d62388a708085ba69c3df98410a503eb3835a75", - "module": "NmJgZNXKdCv3", - "name": "ZvptIZjlgUrKfRTHLZg8", + "address": "e0fe10dcd5150f8d70201ba14a43f74d8340f78c68620cce098780878ae5d712", + "module": "CqSaKCKCQnCNOwgP", + "name": "UITzYPMGPPtMHKDyR", "type_args": [] } } } }, { - "struct": { - "address": "bb60f5ffcd1486062023a7bab4dceb68142dc014fb7c980950afbc2c88262c17", - "module": "rgwUgU9", - "name": "rhGdwoDx2", - "type_args": [] - } - }, - { - "struct": { - "address": "9f0ca7a4d79b8281da6b81e0fc580c1fac222d716ff3305dab889fff6e826262", - "module": "qizHbJCKOyALBPkh3", - "name": "DNoajqPsZTKja0", - "type_args": [] + "vector": { + "struct": { + "address": "e6528ac0f1a1a0b3d353190c02b41869bada812e7bfa7ac45939ba6bd69735de", + "module": "OZDZmXxRfZvAITlH", + "name": "lalGqeaYhREWShwRJWReMKKrPr", + "type_args": [] + } } }, { - "struct": { - "address": "1b4f0d3518b99c3df3d7b34b59bdbaefeeea7fbfb4b63404dce6c484be0141fc", - "module": "WUf8", - "name": "mYJsdBGxUQhbXBoR", - "type_args": [] + "vector": { + "struct": { + "address": "cc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b106a28", + "module": "HXBaYGKANXggcIhAXRluQBvT6", + "name": "BIpCFHqFRxhNuDxiIbDEsJzdE2", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "948892b7a161383440ad9ccdf23d3d4b9f394723d847c9ef9975c1078c869c63", - "module": "HqmPptmJfFjAzHXxdnXN", - "name": "uZtLSJwVcsvYZc0", + "address": "c3816a886b59014f83fb54e3058e8a84c68bc092c211ee44d88d4f9e7b07fc8a", + "module": "NHwrtZFcwOPcIyIBHEckP4", + "name": "tZo", "type_args": [] } } }, { "struct": { - "address": "1a8714fe28079b02eccb6cd9af073997566ccd8ce570cf50a3b3fa59ce0d3a6c", - "module": "OloswIDSjMbEgvQEXSZyPtmYTMFx", - "name": "wWnbNgQhKApwFKkgLz2", + "address": "e60c7b5003bc138a0879bbb3a509c3e47beb8eef59b2ecb2a0bf654fe0312e5c", + "module": "rlHEJ", + "name": "YNJFOxOkkbepagKlPtUgFOTQ", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": "u8" } - } - ], - "args": [ - { - "U128": "209965902554127036893218997229937319241" }, { - "U64": "12461468443567440336" + "vector": { + "vector": { + "struct": { + "address": "320df2d9228e6a4bc27946c9ea21193fa1e24b2654fa888b3b048a420db2221a", + "module": "UDHnSrjeYDpKQ2", + "name": "XmejfVyncLOuGBSAQcGkRHdQgTtSUVs9", + "type_args": [] + } + } + } }, { - "U8Vector": "dd192c06d00dd46b79" - }, + "struct": { + "address": "4e191f57cef49d470c80d5b997d3e26f08d888e454fc9eb1fed6a4954e1fa9e0", + "module": "ursvTshSeoiGpJWMZsjoFSJCBJg", + "name": "MsFMnzCcvmLVicWixNmmiBb0", + "type_args": [] + } + } + ], + "args": [ { - "U8": 179 + "Address": "53210a122cd5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e6235" }, { - "Bool": false + "U8": 15 }, { - "U128": "122818813095141469507882228666766558408" + "U8": 84 }, { - "U8": 83 + "U8": 247 } ] } }, - "max_gas_amount": "9185705063188198709", - "gas_unit_price": "5480641370307763048", - "expiration_timestamp_secs": "15236713497716522836", - "chain_id": 155 + "max_gas_amount": "788092704077831629", + "gas_unit_price": "3006259600154363039", + "expiration_timestamp_secs": "12909114088754588574", + "chain_id": 73 }, - "signed_txn_bcs": "e4c685f4517b068bb0c727af20429c95b788e21e4463b98443b55f0aedc781d3d3fab82c7176de6c00094adffed56d1d9f5fea08070b98a633bf8c25236689d8bac4ba19d24673b2db6fa869c78fec53ce0ddd022007506f594d4341431952436e555a6a69645574634c6c7648446a6f4444505047753900060607aad1c4b6bdd1bb80b29f2f0a1d62388a708085ba69c3df98410a503eb3835a750c4e6d4a675a4e584b64437633145a767074495a6a6c6755724b665254484c5a67380007bb60f5ffcd1486062023a7bab4dceb68142dc014fb7c980950afbc2c88262c1707726777556755390972684764776f44783200079f0ca7a4d79b8281da6b81e0fc580c1fac222d716ff3305dab889fff6e8262621171697a48624a434b4f79414c42506b68330e444e6f616a7150735a544b6a613000071b4f0d3518b99c3df3d7b34b59bdbaefeeea7fbfb4b63404dce6c484be0141fc0457556638106d594a73644247785551686258426f52000607948892b7a161383440ad9ccdf23d3d4b9f394723d847c9ef9975c1078c869c631448716d5070746d4a66466a417a485878646e584e0f755a744c534a7756637376595a633000071a8714fe28079b02eccb6cd9af073997566ccd8ce570cf50a3b3fa59ce0d3a6c1c4f6c6f73774944536a4d62456776514558535a7950746d59544d46781377576e624e6751684b417077464b6b674c7a32000606020702495d89a62447a832d21e34453ff6f59d01d0c193968607f0ac0409dd192c06d00dd46b7900b3050002c88475b89639403f07f0f238010b665c005335f5d646162e7a7f681b81e249260f4c54ffcad732ae73d39b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ce5d5126a1848c619b8de127d7fdc62e2fc0aee66d1edf5a9aa9f66189b1796f566dd9fe56aa08e31d0e7f32fc65a94d39c1fdfb9fcaf21f4bf5c6e4239ed40a", + "signed_txn_bcs": "17f683a8f2b73390fc4ef83c67728a684c0cebd4d5887f03dac7ac33d178ef0e9f524dcf2cfc546d0005713fa6d13f0a06073b5babe04d7115442a1d96eeb09928cf9780f94bc5a376a23274043030de58eb1677665743454568626362536e74415268456e547a464f0b644f43684a4e6c4c76433700060764a1ae397fe1da7d2381a546cb32298322e79b972aa8ee6158bae854287dd7ec1f77516a7577617a6976687162686c435a45495071675365765a6f4958496d331e6e4b6e6e547559624a634d57576c426c7974644f6456634a4c4b6771653100060607e0fe10dcd5150f8d70201ba14a43f74d8340f78c68620cce098780878ae5d71210437153614b434b43516e434e4f776750115549547a59504d475050744d484b447952000607e6528ac0f1a1a0b3d353190c02b41869bada812e7bfa7ac45939ba6bd69735de104f5a445a6d587852665a764149546c481a6c616c477165615968524557536877524a5752654d4b4b725072000607cc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b106a28194858426159474b414e5867676349684158526c7551427654361a42497043464871465278684e7544786949624445734a7a644532000607c3816a886b59014f83fb54e3058e8a84c68bc092c211ee44d88d4f9e7b07fc8a164e487772745a4663774f5063497949424845636b503403745a6f0007e60c7b5003bc138a0879bbb3a509c3e47beb8eef59b2ecb2a0bf654fe0312e5c05726c48454a18594e4a464f784f6b6b62657061674b6c50745567464f545100060601060607320df2d9228e6a4bc27946c9ea21193fa1e24b2654fa888b3b048a420db2221a0e5544486e53726a655944704b513220586d656a6656796e634c4f75474253415163476b52486451675474535556733900074e191f57cef49d470c80d5b997d3e26f08d888e454fc9eb1fed6a4954e1fa9e01b7572737654736853656f6947704a574d5a736a6f46534a43424a67184d73464d6e7a4363766d4c5669635769784e6d6d6942623000040353210a122cd5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e6235000f005400f7cddda28c23deef0a9f04cfb12d61b8299e2b3549de6226b349002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402e6edc0a17495a9f0307d0ea62ab97b81e5d3145857eb497c313ac2211e97a0dbb4223bf13b4e2fb977e2cb06f95647a25430f65ba615bab138392413f4fe306", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e5b1dbf8f47d0d746ca556103e540d955b9f77fb243cbdcc4976e1c005e26b5e", - "sequence_number": "11445035797593009101", + "sender": "77c26b26a45eb63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e", + "sequence_number": "18070014116409769794", "payload": { "Script": { - "code": "b41ada", + "code": "db963f6dd5", "ty_args": [ + { + "vector": { + "struct": { + "address": "c6d8bcff80fe95d4598249a7b4cda38b291d39704b309f81f8782c42a149bc07", + "module": "WCtjoAgEtweUYLRwZZWYFQtQvhGdN", + "name": "DjtjxYbNSbzInjbVbYzqrZqllnwqTKIX", + "type_args": [] + } + } + }, { "struct": { - "address": "26c275b9edd04fa1b643d4c5fe3c81ce8ece3654a430dfa3ec03e8c6ffc7019e", - "module": "sdZRKquotEBnvsnyz2", - "name": "dryQWfqeUEInUJezyQcMv2", + "address": "2318a7cc65c5b148d5d9bf6dd92525c7635805d83278f6219123bed6d9858477", + "module": "JWsOjapVI8", + "name": "iLiCNpIJHEawxFMKTwCv1", "type_args": [] } }, { "struct": { - "address": "58ad9e4700ae1d1246d81266cda990d02b55b83ecc2deecdb360763675c35500", - "module": "DFzUwPkunv", - "name": "KRITJmSzWJgjxCwGzAIYMAZUhw", + "address": "de5a8fdafff71f72cc13162b377920fbe3fab86c74a2b414fcdc1a733e1befe8", + "module": "roAnkhfxAhuIZAfRISv0", + "name": "J", "type_args": [] } }, { "struct": { - "address": "d8d4c60bbbce09c96038ec505c3b01efb49ee8f6ec7f5b8d85b18bc2743152b7", - "module": "OtlavkInbDZOzXylRDHD", - "name": "xyfPeLO", + "address": "25c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e", + "module": "Mvt8", + "name": "bFBEgxwspL", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, { "struct": { - "address": "d797e5319c6256a38c71c85bf283ec4fdce4f70861815556200afbb412defda9", - "module": "LeUrKOJ8", - "name": "POWRNMoSol7", + "address": "90abb4da2b4fcac66af3ffda02d0bce568e99a865c1b938a8b177921148cce0b", + "module": "xkNSG", + "name": "dowdwwUCNDtsgeW5", "type_args": [] } }, { "vector": { "struct": { - "address": "4d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd0", - "module": "E", - "name": "aDLohvvIvQKtcyACxQmaX9", + "address": "3df93d42f95f8dade6f85eddb795f7d3a74a4b3bd5e7a2f18ada43ca0ffb2c56", + "module": "nORklbjiFkxgZGBlqUNXSRJ", + "name": "HhMoC", "type_args": [] } } @@ -2633,285 +2666,343 @@ { "vector": { "struct": { - "address": "38c490d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243", - "module": "hKvQtgz4", - "name": "CNRrRDSOfGcY", + "address": "994ec3ce986fbfb646b3fcdee5d970646f49b6582a923c19d4f4a824b5ead932", + "module": "YQFmDlxqQvuIGMifHjfuGgxcaWniSkVh2", + "name": "cpZZEEHqzaFCAeVonImPS8", "type_args": [] } } - }, - { - "struct": { - "address": "db44e39dd735c3e0016017e667b2a7eee24656984cdeac42d63256a122590c98", - "module": "ZMldDyfn", - "name": "sOtxuzQgDgpTzGVRHGOGcyNfpypSBdq", - "type_args": [] - } - }, - { - "struct": { - "address": "24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d30926f", - "module": "VMWETXs5", - "name": "JijxERtfeCkoAfHUUoYORtVvR", - "type_args": [] - } } ], "args": [ { - "U128": "124542641658449678121282165522415514875" + "U128": "87529034153559330264885154409336100689" + }, + { + "U8Vector": "3ac47fa2e99af9f4cc5d006934bee0" }, { - "Address": "26189e93d8bd4c7945a23536368539d041f788e069a14999c775e500d6c4194c" + "Bool": false } ] } }, - "max_gas_amount": "1926523178893065734", - "gas_unit_price": "9422914524794285288", - "expiration_timestamp_secs": "4276564168168062919", - "chain_id": 220 + "max_gas_amount": "6916975781500037231", + "gas_unit_price": "11832574915920991358", + "expiration_timestamp_secs": "15481718037493599112", + "chain_id": 151 }, - "signed_txn_bcs": "e5b1dbf8f47d0d746ca556103e540d955b9f77fb243cbdcc4976e1c005e26b5ecd2b29656befd49e0003b41ada080726c275b9edd04fa1b643d4c5fe3c81ce8ece3654a430dfa3ec03e8c6ffc7019e1273645a524b71756f7445426e76736e797a321664727951576671655545496e554a657a7951634d7632000758ad9e4700ae1d1246d81266cda990d02b55b83ecc2deecdb360763675c355000a44467a5577506b756e761a4b5249544a6d537a574a676a784377477a4149594d415a5568770007d8d4c60bbbce09c96038ec505c3b01efb49ee8f6ec7f5b8d85b18bc2743152b7144f746c61766b496e62445a4f7a58796c524448440778796650654c4f0007d797e5319c6256a38c71c85bf283ec4fdce4f70861815556200afbb412defda9084c6555724b4f4a380b504f57524e4d6f536f6c370006074d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd001451661444c6f6876764976514b746379414378516d61583900060738c490d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b9424308684b765174677a340c434e52725244534f664763590007db44e39dd735c3e0016017e667b2a7eee24656984cdeac42d63256a122590c98085a4d6c644479666e1f734f7478757a5167446770547a47565248474f4763794e6670797053426471000724c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d30926f08564d574554587335194a696a784552746665436b6f41664855556f594f5274567652000202fb7474decb94a9ff93a0c898500ab25d0326189e93d8bd4c7945a23536368539d041f788e069a14999c775e500d6c4194c063e7ac19f62bc1ae86c3be7d5eac482c73fd2e67368593bdc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444098870a3a832e6f60e1a491a640bef7f54a80240dea3d0cc1d85f7e5582087e0e151fd32759e7b5efe956f3de1cfb47f607ac2d53c9d238fbc8af0c7c232ee006", + "signed_txn_bcs": "77c26b26a45eb63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e42ffe58e1996c5fa0005db963f6dd5080607c6d8bcff80fe95d4598249a7b4cda38b291d39704b309f81f8782c42a149bc071d5743746a6f41674574776555594c52775a5a575946517451766847644e20446a746a7859624e53627a496e6a625662597a71725a716c6c6e7771544b495800072318a7cc65c5b148d5d9bf6dd92525c7635805d83278f6219123bed6d98584770a4a57734f6a617056493815694c69434e70494a4845617778464d4b54774376310007de5a8fdafff71f72cc13162b377920fbe3fab86c74a2b414fcdc1a733e1befe814726f416e6b686678416875495a41665249537630014a000725c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e044d7674380a6246424567787773704c000606020790abb4da2b4fcac66af3ffda02d0bce568e99a865c1b938a8b177921148cce0b05786b4e534710646f7764777755434e447473676557350006073df93d42f95f8dade6f85eddb795f7d3a74a4b3bd5e7a2f18ada43ca0ffb2c56176e4f526b6c626a69466b78675a47426c71554e5853524a0548684d6f43000607994ec3ce986fbfb646b3fcdee5d970646f49b6582a923c19d4f4a824b5ead932215951466d446c787151767549474d6966486a66754767786361576e69536b5668321663705a5a454548717a6146434165566f6e496d5053380003025157392c1404f57f471614d9917ad941040f3ac47fa2e99af9f4cc5d006934bee005006f284a58d308fe5f7e14abc131c035a4884b9089871cdad697002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440567c3d9dbcb418740d5beffd07d36c4176ebf0baf6cd383022e6ce767f4b4ef834ab8d3e5a959fa8fa0cd8d13ba55676ce6cad2021ff39623342f842c46fc007", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3ab5d68b68ed89bf848d18b846c9d77f937b1eceeea9d58269fdb64058f2f7dd", - "sequence_number": "2320556455284762657", + "sender": "55d48685b2e28ae850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e", + "sequence_number": "14034884849846446851", "payload": { "Script": { - "code": "a2d327", + "code": "3b4681e86cd00c7c4b7bb37abf", "ty_args": [ { "struct": { - "address": "91d7edbeb1fe9298b472df0df8925715ec4f5c41f41f5739506d184be3731d29", - "module": "ncbIylsJCVfvITrDwpqvmrUGjzOJ", - "name": "TxsUMfNKOaasOOrvqxDs", + "address": "a77112200b7a7e70d46bdb71cdfa8f3582335d53c1a30f734be93b2162b5f799", + "module": "yparRfflLltVjAbgvSBAZKwNuJLFM7", + "name": "ydVAqhcLEvNrarkYFVYzd7", "type_args": [] } }, { "struct": { - "address": "ae67cb655eeecad53b5b8098a960de679231146ecf2b1f0a7a25baaa521ea972", - "module": "KpAHOQWHipXMVpcBrjjlWJUUvKVnc", - "name": "SYEFIaBLSqgoHfKUaSsNQp1", + "address": "6cc792b9697bcd56e1532e160f61121700ad716eb3880d25407467cffed2a52a", + "module": "VaHIwevIlJNG", + "name": "aQkWTGSjLlJceBoWMdzD", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "struct": { + "address": "690011fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc6", + "module": "EYjAdsNnVSiQxOWla", + "name": "vhlCodJaBnofJQPfmKBBvZFgxmtINzee3", + "type_args": [] + } + } + }, + { + "vector": "address" + }, { "vector": { "struct": { - "address": "7861be3b3dc94521f69aa59f604bd909645d5918ef65f4bd8b5eeddab04cde77", - "module": "IWzcWcgaHkXIpUoGSNQAYJC", - "name": "XgjwwCMeCjZOIAjzBhmR", + "address": "a0d383ad939f339ee5e8ebccfcc36750907e6a78cf5a2701fb1cd5b5e4fdeb97", + "module": "jpHKlaMIiSZycTAOFTJoNefcP", + "name": "ewkMNloFNfWkTFareNkjigAN", "type_args": [] } } }, { "struct": { - "address": "e5f0c4ba30c9f3b202f89df6f219e04e1ed679c88c0c0340402fd2abf1b43b9f", - "module": "EkfgCbLpGvRBhLwpWvqKugzORKYX", - "name": "kdrpy2", + "address": "a50bb672641f816eb024d9790d5856a8e626da7073510806ba70dff951929db4", + "module": "adLcUxXc7", + "name": "HJMFXKPUyxxyAXGkd0", + "type_args": [] + } + }, + { + "struct": { + "address": "ac1141d7d4fe13222145d87b1e65d2afcc3e5ac172a8423a1378559228fc1050", + "module": "GrZxMzRMtt", + "name": "WYMmmEylFDJMQ7", "type_args": [] } } ], "args": [ { - "U8Vector": "b7cdcafaf1e34289954f97d0" + "U128": "98434209940513369142324584340025652319" + }, + { + "U128": "321894956682793891505064759699072864634" + }, + { + "U8Vector": "d8fc2d0dd6c050" + }, + { + "U64": "7051346425801042965" + }, + { + "U8Vector": "10cb07ad8ce6dbba052b19b82b3e" + }, + { + "U64": "10338548140756552756" + }, + { + "U8Vector": "11f627bee202b811a1" + }, + { + "U64": "18319272913683637683" }, { - "U64": "3339465231986042915" + "U64": "1580206222738488545" }, { - "U128": "91959944195168597389071294253267069517" + "Address": "14a2094e545ed162523c42376004f70d0c3266978c30eea8d42292ab15740b12" } ] } }, - "max_gas_amount": "3792915403161698018", - "gas_unit_price": "18055594279998178409", - "expiration_timestamp_secs": "7340711166730222471", - "chain_id": 19 + "max_gas_amount": "9620912920125864317", + "gas_unit_price": "14042300254469599944", + "expiration_timestamp_secs": "17916949931666593283", + "chain_id": 248 }, - "signed_txn_bcs": "3ab5d68b68ed89bf848d18b846c9d77f937b1eceeea9d58269fdb64058f2f7dd21e87c1ecd4534200003a2d327040791d7edbeb1fe9298b472df0df8925715ec4f5c41f41f5739506d184be3731d291c6e636249796c734a4356667649547244777071766d7255476a7a4f4a14547873554d664e4b4f6161734f4f7276717844730007ae67cb655eeecad53b5b8098a960de679231146ecf2b1f0a7a25baaa521ea9721d4b7041484f5157486970584d56706342726a6a6c574a5555764b566e6317535945464961424c5371676f48664b556153734e5170310006077861be3b3dc94521f69aa59f604bd909645d5918ef65f4bd8b5eeddab04cde771749577a6357636761486b584970556f47534e5141594a431458676a7777434d65436a5a4f49416a7a42686d520007e5f0c4ba30c9f3b202f89df6f219e04e1ed679c88c0c0340402fd2abf1b43b9f1c456b666743624c7047765242684c77705776714b75677a4f524b5958066b64727079320003040cb7cdcafaf1e34289954f97d00123a84b6cef29582e024daa96c67436b0a94ccd65264dd72e45e27e8fa47624a33469c4ddc3555b92fa87bbb2d3e971df6513002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444039fc5505d8b250e77b8873ccb2c18f011c2d5601612c5b3e488edeb31881b67b3ba0d262b827012bfe386dfab53ac02fb2ea197a4070e7f20dd5f3ecfacbbc05", + "signed_txn_bcs": "55d48685b2e28ae850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e03eb9b3269edc5c2000d3b4681e86cd00c7c4b7bb37abf0807a77112200b7a7e70d46bdb71cdfa8f3582335d53c1a30f734be93b2162b5f7991e797061725266666c4c6c74566a416267765342415a4b774e754a4c464d3716796456417168634c45764e7261726b594656597a643700076cc792b9697bcd56e1532e160f61121700ad716eb3880d25407467cffed2a52a0c56614849776576496c4a4e471461516b575447536a4c6c4a6365426f574d647a44000606020607690011fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc61145596a4164734e6e56536951784f576c612176686c436f644a61426e6f664a5150666d4b4242765a4667786d74494e7a6565330006040607a0d383ad939f339ee5e8ebccfcc36750907e6a78cf5a2701fb1cd5b5e4fdeb97196a70484b6c614d4969535a796354414f46544a6f4e656663501865776b4d4e6c6f464e66576b54466172654e6b6a6967414e0007a50bb672641f816eb024d9790d5856a8e626da7073510806ba70dff951929db40961644c63557858633712484a4d46584b5055797878794158476b64300007ac1141d7d4fe13222145d87b1e65d2afcc3e5ac172a8423a1378559228fc10500a47725a784d7a524d74740e57594d6d6d45796c46444a4d5137000a025f34fa4dbff80e2aae2c8f553fbd0d4a027ad1233fca8fe39cafc24ba3aeb62af20407d8fc2d0dd6c05001156c17f2366adb61040e10cb07ad8ce6dbba052b19b82b3e0134cc110fc2e6798f040911f627bee202b811a101b3658cc3a7213bfe01e17c30f22f05ee150314a2094e545ed162523c42376004f70d0c3266978c30eea8d42292ab15740b127d7911bb53598485c8b209a1ae45e0c2035672e708cba5f8f8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444077668cf5a746e704526dcdfa6677fa891dc634a22a87c788560d4c38cafa8cde39a294570dbab42ad3a42f67bee5625c5134d1cd7eec688a35c7b7a5933bd802", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7356f4b0079984a3e1194582e8bffdacd5a164c5d77ef09abcc4f1fd5af99b60", - "sequence_number": "5825701095339355035", + "sender": "102cd984b63283aaf4e39ae449ba3dc83fece8fba3f83da5778ea0a3810843e3", + "sequence_number": "6989147576989387327", "payload": { "Script": { - "code": "649a", + "code": "cfa8309dbbb2bb91", "ty_args": [ - { - "vector": { - "struct": { - "address": "60eb5719c967063d38367d3ee3c38e4435e13ddd24862fdeb93f44ab31a10e62", - "module": "kGRTOIkFlJuGesgMiY6", - "name": "dGyjsgZzYdTnKxMMpfflRlhHZBRIga2", - "type_args": [] - } - } - }, { "struct": { - "address": "5de474aa4008092f002e28521c3efff6448d6887c07d0198c3382e17bf1fe70c", - "module": "MgfVFLXwuQJfLMbrchhUZrjUHV", - "name": "ytcmdICmreIzHWOKDpvQGas", + "address": "2409a98e42ff9b359d6bac28a56c0d738d81cc27e8357c0c65f582877ad269d5", + "module": "DYwVIlpghJXkOk5", + "name": "WqFPz4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "ba824a6d89ef327ba374de0b1d50ee19a828042e4141d15929a8f351417178fe", - "module": "hzdlfHqYXOVFdTvTnLis", - "name": "LzJOGGrlXgXSrGyNGJBwVlcUiSFrTdnV9", - "type_args": [] - } + "struct": { + "address": "027885b9be806599b0bef97dedc23022df50077e22741c578f2a9d6dbd328d1f", + "module": "SoDEckgcxhnGYRYnZWOQrmPOV1", + "name": "bwlvltwI", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "e76ead5c5c0d44a1b1abe493b3e3502bd74d03fa50891661e099ad4fd0bf034a", - "module": "HXykC", - "name": "YvbPrbLBXTGRHyPAWtEkrFi9", - "type_args": [] - } + "struct": { + "address": "618ddc10915377f6d7cf87e08645e2be5594bcb94e4845da3d4ca5a8624bcf0a", + "module": "KnjpUsiGqik", + "name": "nngIJlYQOLgZZrYtPFOXSyhcMW", + "type_args": [] } }, { - "vector": { - "vector": { - "vector": { - "struct": { - "address": "03b8a0e0dde1db9d42a874a367381effa55cdf94abec15c19baec5fcea039946", - "module": "iNKaBNSss7", - "name": "yzCwMydKUOUQJzRxKeBPFcsg1", - "type_args": [] - } - } - } + "struct": { + "address": "44e167ba4ba8e4f494cc083f7d4832ad57ac9cf0bc578ceb1262044cf376ffa5", + "module": "leOBGBQY6", + "name": "eXDczwTswaFnQiLtEMEGzcm0", + "type_args": [] } } ], "args": [ { - "U64": "11197693848083373671" - }, - { - "U8": 228 - }, - { - "U8Vector": "37bdcbb4aebfd3dac0ed5fbf9eddda05" - }, - { - "U128": "255703811106046701869778741362779795070" - }, - { - "U8Vector": "bfcdd9bcf8923ea154b5610e76febb9d" + "U128": "243664118736732188932597356670613141623" } ] } }, - "max_gas_amount": "1627589315093971743", - "gas_unit_price": "14878407516917835187", - "expiration_timestamp_secs": "849845923837689512", - "chain_id": 225 + "max_gas_amount": "3085025885905844913", + "gas_unit_price": "2386665543726565458", + "expiration_timestamp_secs": "5818427994280985010", + "chain_id": 65 }, - "signed_txn_bcs": "7356f4b0079984a3e1194582e8bffdacd5a164c5d77ef09abcc4f1fd5af99b609b6b4ec3470cd9500002649a05060760eb5719c967063d38367d3ee3c38e4435e13ddd24862fdeb93f44ab31a10e62136b4752544f496b466c4a75476573674d6959361f6447796a73675a7a5964546e4b784d4d7066666c526c68485a42524967613200075de474aa4008092f002e28521c3efff6448d6887c07d0198c3382e17bf1fe70c1a4d676656464c587775514a664c4d6272636868555a726a554856177974636d6449436d7265497a48574f4b44707651476173000607ba824a6d89ef327ba374de0b1d50ee19a828042e4141d15929a8f351417178fe14687a646c66487159584f5646645476546e4c6973214c7a4a4f4747726c586758537247794e474a4277566c63556953467254646e5639000607e76ead5c5c0d44a1b1abe493b3e3502bd74d03fa50891661e099ad4fd0bf034a054858796b43185976625072624c4258544752487950415774456b72466939000606060703b8a0e0dde1db9d42a874a367381effa55cdf94abec15c19baec5fcea0399460a694e4b61424e5373733719797a43774d79644b554f55514a7a52784b6542504663736731000501671e96163a33669b00e4041037bdcbb4aebfd3dac0ed5fbf9eddda05027eaef84c38be134351647b5c3ec35ec00410bfcdd9bcf8923ea154b5610e76febb9d1fc365d6db5b9616b3a563b5ceb87acea8be28745d42cb0be1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409271b625cb4f49d2f8f3df871138d4740266ff8d1d10d480db2bd0890d80d9b20f947268bf9ca7fea70824ed9e2bbc4bc58ee0fbac2954d538e85e7bdf904500", + "signed_txn_bcs": "102cd984b63283aaf4e39ae449ba3dc83fece8fba3f83da5778ea0a3810843e33f0a3cf1b070fe600008cfa8309dbbb2bb9104072409a98e42ff9b359d6bac28a56c0d738d81cc27e8357c0c65f582877ad269d50f44597756496c7067684a586b4f6b3506577146507a340007027885b9be806599b0bef97dedc23022df50077e22741c578f2a9d6dbd328d1f1a536f4445636b676378686e475952596e5a574f51726d504f56310862776c766c7477490007618ddc10915377f6d7cf87e08645e2be5594bcb94e4845da3d4ca5a8624bcf0a0b4b6e6a705573694771696b1a6e6e67494a6c59514f4c675a5a72597450464f58537968634d57000744e167ba4ba8e4f494cc083f7d4832ad57ac9cf0bc578ceb1262044cf376ffa5096c654f42474251593618655844637a7754737761466e51694c74454d45477a636d300001027738abddc36e73e9c9ccb36c940050b7b17a4db4b236d02a52887cbbaa231f21b2814ef66e35bf5041002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444064017db6a013179c1864a9fc1f240b4625ca7b609195de38a27348217ecd1378648d614eea403e43f7df31ba76a11a83b434c67456b429aed29caf7cfb1a2b0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c8e", - "sequence_number": "4844760987894299668", + "sender": "f04944a59d7219321ee03823407c03e4a378b0e32dbb6a9f91eed4c69d424ab4", + "sequence_number": "17678564563898859448", "payload": { "Script": { - "code": "8af4d7a74f6f100f4f73aef7", + "code": "14fb14", "ty_args": [ { "vector": { "struct": { - "address": "6f968802b0807dc58df080ed68118e9eb1aba512d47f3ca4cb806138ca83c3b0", - "module": "cttxYpFecKCcpI5", - "name": "vuUkNkWkLHXrmoE8", + "address": "5548612ae2e52b8e606750eff79ddaa364607917639aeb216515c72464362ac4", + "module": "nuuGXoJlvZCHctUzhxQbacxhEEBwz8", + "name": "irzsOebDyNcfGFixkKLEgFJwchyffmWY3", "type_args": [] } } }, { - "vector": { + "struct": { + "address": "c131e320d8b96857e4dd2187bb4358b4ccd7db4e9ad8e472b8de3dc286899d6f", + "module": "vWc", + "name": "nchvFt", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "54ba2751dfc8f8bbd6ce1dcc5abf40f2199cace04460b5a9f5e899a20f4df6a8", + "module": "wyZTdnOZs5", + "name": "YYmgQtzRsaXfvNrBt8", + "type_args": [] + } + } + }, + { + "struct": { + "address": "d35815011368a2e142bc4427ae3239440c2d534a6f15193c68354f2e967e1de1", + "module": "BsTimRbxCmRQuToEMTjxN6", + "name": "hd4", + "type_args": [] + } + }, + { + "vector": { "struct": { - "address": "145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165efe9", - "module": "PUdGh8", - "name": "ljgkFE", + "address": "170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6a74735082d28b14a9ed23b", + "module": "myPlcSTjHkqIsqkVtaJYbrHIdEiw5", + "name": "YUSKQadMheiDFGDwKdHtykBJFXKW", "type_args": [] } } }, { "struct": { - "address": "b3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c09a12f66", - "module": "OkgVxgFYYeJBeSPKaBojVI", - "name": "GrumAkFtkIRmoneMFaJCXTWiktteFnGz", + "address": "34475e87effa7803de00fec92afd9893cb50f91e263df58084a4f2b1811f6cc4", + "module": "HrQuRQZtHSdqhdTGzBBaGwosgGFY", + "name": "Naf", + "type_args": [] + } + }, + { + "struct": { + "address": "18c257269086e72ed05eef67e76903ce78c388f50a66c91f968209e7139bf930", + "module": "ZHTpmyszyizbuUSTUBEJFiuUJElW", + "name": "czDhpk6", "type_args": [] } } ], "args": [ { - "Address": "6050cd12df115d42f559590784243cfd6d24b2987617c278e967842f650751e5" + "U64": "3553575050996659418" + }, + { + "U64": "4975158244011507856" + }, + { + "U8": 35 }, { - "U128": "102656740297815742676618895381284238036" + "Bool": false }, { "Bool": false }, { - "U128": "175842861174649112373128126531069423702" + "Address": "946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd0328075418" + }, + { + "U64": "1472101799157070050" + }, + { + "U8": 213 } ] } }, - "max_gas_amount": "2403789431177497853", - "gas_unit_price": "14949880805531151743", - "expiration_timestamp_secs": "7114375590957426350", - "chain_id": 32 + "max_gas_amount": "10680405262183461876", + "gas_unit_price": "9452163127402016207", + "expiration_timestamp_secs": "2356159463261813315", + "chain_id": 2 }, - "signed_txn_bcs": "6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c8e143c1c29730c3c43000c8af4d7a74f6f100f4f73aef70306076f968802b0807dc58df080ed68118e9eb1aba512d47f3ca4cb806138ca83c3b00f6374747859704665634b4363704935107675556b4e6b576b4c4858726d6f4538000607145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165efe906505564476838066c6a676b46450007b3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c09a12f66164f6b67567867465959654a426553504b61426f6a5649204772756d416b46746b49526d6f6e654d46614a43585457696b747465466e477a0004036050cd12df115d42f559590784243cfd6d24b2987617c278e967842f650751e502d4b263f94872640e834e044111f83a4d050002563066163b745515a44243496a1a4a84fd4c2c78c0f95b217f6d1d8062a578cfae26ba09e856bb6220002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444002f546f4eecbe607f697c87bd8ed96d690b0fe9221d5edb2501a6d761a2712d462103a5ecccbea9cb3c9e7fe0894eac1f7b503cff42c26a704c81a9da726a105", + "signed_txn_bcs": "f04944a59d7219321ee03823407c03e4a378b0e32dbb6a9f91eed4c69d424ab4b8ffff49cee056f5000314fb140706075548612ae2e52b8e606750eff79ddaa364607917639aeb216515c72464362ac41e6e757547586f4a6c765a43486374557a6878516261637868454542777a382169727a734f656244794e6366474669786b4b4c4567464a7763687966666d5759330007c131e320d8b96857e4dd2187bb4358b4ccd7db4e9ad8e472b8de3dc286899d6f03765763066e636876467400060754ba2751dfc8f8bbd6ce1dcc5abf40f2199cace04460b5a9f5e899a20f4df6a80a77795a54646e4f5a73351259596d6751747a5273615866764e724274380007d35815011368a2e142bc4427ae3239440c2d534a6f15193c68354f2e967e1de116427354696d526278436d525175546f454d546a784e3603686434000607170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6a74735082d28b14a9ed23b1d6d79506c6353546a486b714973716b5674614a596272484964456977351c5955534b5161644d68656944464744774b644874796b424a46584b57000734475e87effa7803de00fec92afd9893cb50f91e263df58084a4f2b1811f6cc41c4872517552515a7448536471686454477a42426147776f7367474659034e6166000718c257269086e72ed05eef67e76903ce78c388f50a66c91f968209e7139bf9301c5a4854706d79737a79697a62755553545542454a466975554a456c5707637a4468706b36000801dab45865aed55031019080a93b10500b4500230500050003946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd032807541801e278f86bc9f46d1400d5f473a8adff6b3894cfadd7df48d42c83433ae5618cc2b22002002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd58c08d34a8794a1f6e9023355517c14e65faf4899429b7d5aa37af0dbf2990ccc164992e27ffaf978bd60966ab4256b0837eacc0cb09e8fb5fd3efbab8f303", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ac9d11d59e90d32cfa6a6cf2f3296aaabab1f1460834e7543f417938c32f0bba", - "sequence_number": "17045144598194283172", + "sender": "8813e338423594083097dae790b8298ff79ebe210c01bdf753851ad07f4a73da", + "sequence_number": "883909938445623171", "payload": { "Script": { - "code": "002f24e6f598be8ec1d90b80efaf2b", + "code": "47bf5924b313acea3c1b", "ty_args": [ { "struct": { - "address": "e6d3c74816d2075d551f68ed79b573f92f67003aa966964dd4b2eaefb967d2bb", - "module": "uvwrsmSEyCpez1", - "name": "nVfggJtBSwNN2", + "address": "0f9cf37c55747bb1c792cb59087b232e191e4057ce2a0e60219fd76aa2727b12", + "module": "ctKbufgZg", + "name": "MJ9", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "4e7dd6d327e593895a471c9a7eaee5ac9caa420475a5e804a08325f4597526b9", + "module": "hI7", + "name": "mjRhNjEdGsCdWSIptjkizcWsRiLS", + "type_args": [] + } + } + }, { "vector": { "vector": { "vector": { "struct": { - "address": "cb9dae4e5ddfec806ce4807617a2bdd7521237eaf7648064623f967dba38800d", - "module": "nvkAUZBgBleALwFImFTRF6", - "name": "EX", + "address": "f5a5c4079dc5b103a11025b8e9eb1d444d0361d71267ba41799be42dbc539227", + "module": "Nby8", + "name": "SkQZqOCdfwqBZSOGmjd", "type_args": [] } } @@ -2920,162 +3011,212 @@ }, { "struct": { - "address": "5f205230891ca4e458ac9d67b74002fcb384a28371430f9a3e9cbbe06eeb70d1", - "module": "tYZGVlQRmnnvIZQyoZqFucKXsYsHI9", - "name": "wTD", + "address": "b35e1ff57ac16e8fb143bd40d36edf20fcfeeaef07571c776056c958bca8e107", + "module": "COCOnC5", + "name": "aRJlZqhgtcnpjpCZsAILebBkMuAfJbv", "type_args": [] } }, { "vector": { "struct": { - "address": "d8738bad7a1883e430352f1589a5a990b2bd2ca6bdfdbf5ca023205cf3926f15", - "module": "SFczufzEUMqrMdiABKkEHwBJYXjk2", - "name": "vKZSSDaxXccOhCVmYNZV9", + "address": "0a2a3345f3d04518b1537b19c66325c7d13edcbcacbab89fdd940b9ee4fe85c0", + "module": "qVvBPmsFWyCfjfGdDDOfcrBDgKpqmBlv", + "name": "WOVieUcQG", "type_args": [] } } }, { - "vector": { - "struct": { - "address": "711a5d37396334320fbe57df9fcbf5809fcb8b6999385207483dd9ced15eba67", - "module": "JHRjTCpxFienQUITRrrou", - "name": "sGjbRrwWJyGL", - "type_args": [] - } + "struct": { + "address": "2e610e8a0c1b5f2726282d661375e0918869067ef14b105f81c90e37f810e6ec", + "module": "jNdnBRwzwkvYGBEQMNY6", + "name": "BtNAxI", + "type_args": [] } + } + ], + "args": [ + { + "Address": "108ec586862e0bcbf21fee198922a90a126d58504682bc5c95880a530853d242" + }, + { + "Address": "7984fe4e8f8ae0aafd11107466d9a4fd419610697b5f6b71e7a928c8346159fe" + }, + { + "Bool": true + }, + { + "U64": "4545657304924097671" }, + { + "Address": "cdfd803a7f0da20361f7b25a9409ce99fda20d895948baf64ce531c4aea1c5c8" + } + ] + } + }, + "max_gas_amount": "7264225699521684428", + "gas_unit_price": "13411789687573686515", + "expiration_timestamp_secs": "6762716022413094369", + "chain_id": 241 + }, + "signed_txn_bcs": "8813e338423594083097dae790b8298ff79ebe210c01bdf753851ad07f4a73da831f7de66747440c000a47bf5924b313acea3c1b06070f9cf37c55747bb1c792cb59087b232e191e4057ce2a0e60219fd76aa2727b120963744b627566675a67034d4a390006074e7dd6d327e593895a471c9a7eaee5ac9caa420475a5e804a08325f4597526b9036849371c6d6a52684e6a45644773436457534970746a6b697a63577352694c530006060607f5a5c4079dc5b103a11025b8e9eb1d444d0361d71267ba41799be42dbc539227044e62793813536b515a714f4364667771425a534f476d6a640007b35e1ff57ac16e8fb143bd40d36edf20fcfeeaef07571c776056c958bca8e10707434f434f6e43351f61524a6c5a71686774636e706a70435a7341494c6562426b4d7541664a62760006070a2a3345f3d04518b1537b19c66325c7d13edcbcacbab89fdd940b9ee4fe85c02071567642506d7346577943666a66476444444f6663724244674b70716d426c7609574f5669655563514700072e610e8a0c1b5f2726282d661375e0918869067ef14b105f81c90e37f810e6ec146a4e646e4252777a776b7659474245514d4e59360642744e417849000503108ec586862e0bcbf21fee198922a90a126d58504682bc5c95880a530853d242037984fe4e8f8ae0aafd11107466d9a4fd419610697b5f6b71e7a928c8346159fe050101870ca9223c6b153f03cdfd803a7f0da20361f7b25a9409ce99fda20d895948baf64ce531c4aea1c5c8cce34044c9b6cf64f3a81382a93f20bae16dc65864fed95df1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a96fa35cbd5c9196a7e834f8f865c95fec3498ca284fe072db24f1f442e99d3b74cbc99e41b1391aa40adf68261ad862ba9cedcdfde9c0c202a35faf5628fa0a", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "606b67953fd5bcd590635954afc21b25200f72ffbf25284f16f40c21dd3d3bac", + "sequence_number": "635684488432411632", + "payload": { + "Script": { + "code": "66b9fd2abe3e9bcdba382fbfa987e0", + "ty_args": [ { "struct": { - "address": "0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2297f3e7ec86", - "module": "STGxMvmHCPnTQDfArZEUJIRHYeIyx1", - "name": "kGnAxyhSTgaGXpi7", + "address": "581a6fdb0efccd6d339b784c11275bd202869957ad6352440d9df40787eb433d", + "module": "bu", + "name": "aJ", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": { + "vector": { + "vector": "u8" + } + } } }, { - "struct": { - "address": "e845393a1b337f39dab3afc43de85c91ca35bcd2263c039dd3d438828eb1f98b", - "module": "AALTzBcsvKOWVbrp", - "name": "vsTcBBJcG2", - "type_args": [] + "vector": { + "struct": { + "address": "5d25089c677dae1abe0f4505f94e94c9e7de897efe9d9c7dc05bdf4b2a3a3f33", + "module": "NFjrjNiKoxasebpjq", + "name": "Vjapwn3", + "type_args": [] + } } }, { "vector": { "vector": { - "struct": { - "address": "f89325957cdda0d8080687e8074d3a480231f532c36baa3eb077c1a5787ce5dc", - "module": "CJOiux", - "name": "feXRrc", - "type_args": [] - } + "vector": "u64" + } + } + }, + { + "vector": { + "struct": { + "address": "e365a7c5904ad705c3a0f2d0d609af7cb5d60885becc7655715acd6f32d93297", + "module": "ScPAyaoNNKXjFyPJdCJPqCYycku", + "name": "UGuDwoWdXhthdJKNDVJXhl", + "type_args": [] } } } ], "args": [ { - "U128": "284647226096586039146447832453055478128" + "U64": "11338045746867582339" }, { - "U8": 42 + "U64": "10295715561298037260" }, { - "Address": "77773fab98855cf984b9f100ab2af513935cad2e59e03edca28fbea32bc1f9d7" + "U8": 168 }, { - "U8Vector": "fbb46a85632c2a448e16" + "U128": "221940221782822424795979897138330631780" + }, + { + "U128": "308553076537417435682747259167237353455" + }, + { + "Bool": true } ] } }, - "max_gas_amount": "8475223550754311714", - "gas_unit_price": "4050192680872727420", - "expiration_timestamp_secs": "7896248004655782942", - "chain_id": 183 + "max_gas_amount": "17928996185255220527", + "gas_unit_price": "5225265107742083515", + "expiration_timestamp_secs": "8444797716586235371", + "chain_id": 213 }, - "signed_txn_bcs": "ac9d11d59e90d32cfa6a6cf2f3296aaabab1f1460834e7543f417938c32f0bbaa4e289f8b3848cec000f002f24e6f598be8ec1d90b80efaf2b0907e6d3c74816d2075d551f68ed79b573f92f67003aa966964dd4b2eaefb967d2bb0e75767772736d5345794370657a310d6e566667674a744253774e4e320006060607cb9dae4e5ddfec806ce4807617a2bdd7521237eaf7648064623f967dba38800d166e766b41555a4267426c65414c7746496d465452463602455800075f205230891ca4e458ac9d67b74002fcb384a28371430f9a3e9cbbe06eeb70d11e74595a47566c51526d6e6e76495a51796f5a714675634b5873597348493903775444000607d8738bad7a1883e430352f1589a5a990b2bd2ca6bdfdbf5ca023205cf3926f151d5346637a75667a45554d71724d646941424b6b454877424a59586a6b3215764b5a53534461785863634f6843566d594e5a5639000607711a5d37396334320fbe57df9fcbf5809fcb8b6999385207483dd9ced15eba67154a48526a544370784669656e515549545272726f750c73476a62527277574a79474c00070c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2297f3e7ec861e535447784d766d4843506e5451446641725a45554a495248596549797831106b476e417879685354676147587069370006060507e845393a1b337f39dab3afc43de85c91ca35bcd2263c039dd3d438828eb1f98b1041414c547a426373764b4f57566272700a7673546342424a63473200060607f89325957cdda0d8080687e8074d3a480231f532c36baa3eb077c1a5787ce5dc06434a4f697578066665585272630004027079abb6747475435f34be27c70f25d6002a0377773fab98855cf984b9f100ab2af513935cad2e59e03edca28fbea32bc1f9d7040afbb46a85632c2a448e16224ebc6eea0a9e757c534ecfc82c35381e1ce55fb91b956db7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aa60a79ba27eaf939538d2afbc13b877c40789d4d93e564827f7dad43ce635d3ff78392055e39eb811667d4db73ff6307b79bb376a22d33d40548dce0f955705", + "signed_txn_bcs": "606b67953fd5bcd590635954afc21b25200f72ffbf25284f16f40c21dd3d3bacf0633d9aac67d208000f66b9fd2abe3e9bcdba382fbfa987e00507581a6fdb0efccd6d339b784c11275bd202869957ad6352440d9df40787eb433d02627502614a00060606060106075d25089c677dae1abe0f4505f94e94c9e7de897efe9d9c7dc05bdf4b2a3a3f33114e466a726a4e694b6f7861736562706a7107566a6170776e3300060606020607e365a7c5904ad705c3a0f2d0d609af7cb5d60885becc7655715acd6f32d932971b5363504179616f4e4e4b586a4679504a64434a5071435979636b751655477544776f576458687468644a4b4e44564a58686c00060183b52b0589d4589d010c8aa103c1bae18e00a802647e2ae1b3349ab686de352bc421f8a602ef2f9e055146502c932fae41342921e805012f9578e10997d0f8bbc9354ceede8348eb0527e1c7f23175d5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0c53825ee0c782f397a2a4a3d6a2853ad245307418f7cdcd2ded0033f46f09cdb297050dcd07c0e41dd9f5c399405f42235083b320c0efcd584996a3f7b4d03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "25cefe006c9ca9bd117dd7f5a077e292edbd27c1b4ad87fd29d7552008c090c6", - "sequence_number": "785122008010187244", + "sender": "c67d986d9ed7b80ae86f530c10cc588a8415ce913b734ee17c9600e227f71d99", + "sequence_number": "12734893865027769132", "payload": { "Script": { - "code": "24202989b6ec491eed87639e", - "ty_args": [ + "code": "add7d1368f074746bddbfdee0b89c7ae", + "ty_args": [], + "args": [ { - "struct": { - "address": "dd9f9dcf6d644ace56538e6a43d02b0df83edb2dd02e23796438b5eeb5175dc2", - "module": "NPsFZEDmmDPytSMirI1", - "name": "HwBDpWDw2", - "type_args": [] - } + "U64": "3993307104017215887" }, { - "struct": { - "address": "abc4c28533297f50800f801c4c3454230bc1f869c3d7d145b0fca6ff15a68844", - "module": "oZVwmtVbYjriLjXyjPCuvLSqmntaUf3", - "name": "CkilJFHtbTydXWOERH6", - "type_args": [] - } + "Address": "10a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e3" }, { - "struct": { - "address": "4019770c56b353b2804f8cafd71203409a5d43754a2bebb9f4ac2208d19e3d54", - "module": "meYNtGwIZIiopiVXv3", - "name": "VsnkvpMYUfIu3", - "type_args": [] - } + "U128": "153769828724711268800887548148281294368" }, { - "vector": { - "vector": "u64" - } + "U64": "9501229679438455053" }, + { + "U64": "13382853789626215589" + } + ] + } + }, + "max_gas_amount": "8365807898758044472", + "gas_unit_price": "10594160532785386233", + "expiration_timestamp_secs": "16173895361808194721", + "chain_id": 90 + }, + "signed_txn_bcs": "c67d986d9ed7b80ae86f530c10cc588a8415ce913b734ee17c9600e227f71d992c1348757f6ebbb00010add7d1368f074746bddbfdee0b89c7ae0005018f71fd55a7136b370310a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e30220be5c1262f0e97554d10889e4fdae73010de153c40d26db8301a52ca9c39d72b9b9385ba1c0f5511974f9d222d2df040693a15cea7a233875e05a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e8b1b2fe0c18f7de9cfeab8eded2384a6fb995d0909fb9aa703412abdc1f14ce50b9f4f7dcff0f84c47e8b7cfee611d29708381b0df306ccbd48d1ec3b80c500", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8de3d2fe69f9040114f0eddc73809b7581ea3d959407d2792afcbe98bab628c3", + "sequence_number": "3828648834406245551", + "payload": { + "Script": { + "code": "57f5", + "ty_args": [ { "vector": { - "struct": { - "address": "165942394b3c9dc32cdd8f4c65e17f1368d8b66ec15047a8a2d14ed31537d3ed", - "module": "tBkNENjdeSZtxlKu", - "name": "XWbKlhUtSbTOswWZfmqaApuglbiyKcw1", - "type_args": [] - } + "vector": "signer" } }, { "struct": { - "address": "9d2bd0c6dade5ffea765fe0bf0579196f3e6bf1a96eb5b572e0edbc5c65379a4", - "module": "FwesGYZCbTliAUw", - "name": "pjeHRSAUYHApNZR5", + "address": "63703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a6ea1495e03b517", + "module": "fVpCXJbmKsAkzFPxZMmZkOozszfFIMI8", + "name": "jE4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "33e754710707eb1ee41fa64c0d023e930e2198e3da5e297c979cff522678c90b", - "module": "OJcldGQCHS0", - "name": "AY8", - "type_args": [] - } + "struct": { + "address": "824c7e1321aca36efa9fba391ea26ea528165784a2199bfb50e4003a6e86d650", + "module": "uWJPJeoHBziRFFEeWDrVw8", + "name": "haRpDqZKKnpqhMBJQoSg", + "type_args": [] } }, { "vector": { "vector": { "struct": { - "address": "06f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4caa647dcefa4", - "module": "XcHzmgRqxEOeCRMRFgUbvLu7", - "name": "JPMDcmZYW0", + "address": "93456813ba68b80a7820875fdf6a5f2a9545db09460259fa80f41bf5e3307b7e", + "module": "VMogcuxZyVjVPjOhJpI7", + "name": "bekDGQcqWHF6", "type_args": [] } } @@ -3083,280 +3224,224 @@ }, { "struct": { - "address": "a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe", - "module": "sEpQncZWVLBuOHUgFBsaZcrqdB8", - "name": "MbfUqumYoMKuKrPKIGtsWrkcvKwLk2", - "type_args": [] - } - }, - { - "struct": { - "address": "d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7", - "module": "KLSHfHnHsvFRSaknh", - "name": "YhIbxVeETPuEVhdY", + "address": "4722bc99a0a02f3ae3d09eb8db371a9abd8ec5f334528d51f60704484a73786e", + "module": "wbtFDSnTSLd0", + "name": "cegRVREmWRsdHRmWiBvCzw9", "type_args": [] } } ], "args": [ { - "U128": "310313545942415089976197901925240488815" + "U8": 200 }, { - "Bool": false + "U64": "8105345358869507537" }, { - "U8": 22 + "Address": "709de7e77078e3ecaecdb23abe1148f35976ea3d4378b9aca4da1413fc167f30" }, { - "U128": "110281736843605731954589936240845032401" + "U8Vector": "27b1d4f7ce5f1720fe" }, { - "Address": "5b21e40515a52e64b51768b646fb8824c6c46ee6c0676f800eb960edfbc95e2d" + "Bool": false }, { - "Bool": true + "Address": "3fdda215dcd84b12ae3b39d38cb23c20e8e3d58a4c2d1dec6c0210f962816f5e" } ] } }, - "max_gas_amount": "715937801192525421", - "gas_unit_price": "8582137578423854300", - "expiration_timestamp_secs": "15275376885070959758", - "chain_id": 18 + "max_gas_amount": "11653455633830677408", + "gas_unit_price": "1884770236608181706", + "expiration_timestamp_secs": "5018182781233168552", + "chain_id": 157 }, - "signed_txn_bcs": "25cefe006c9ca9bd117dd7f5a077e292edbd27c1b4ad87fd29d7552008c090c6ece1c9784e50e50a000c24202989b6ec491eed87639e0a07dd9f9dcf6d644ace56538e6a43d02b0df83edb2dd02e23796438b5eeb5175dc2134e5073465a45446d6d44507974534d69724931094877424470574477320007abc4c28533297f50800f801c4c3454230bc1f869c3d7d145b0fca6ff15a688441f6f5a56776d745662596a72694c6a58796a504375764c53716d6e746155663313436b696c4a4648746254796458574f4552483600074019770c56b353b2804f8cafd71203409a5d43754a2bebb9f4ac2208d19e3d54126d65594e744777495a49696f7069565876330d56736e6b76704d595566497533000606020607165942394b3c9dc32cdd8f4c65e17f1368d8b66ec15047a8a2d14ed31537d3ed1074426b4e454e6a6465535a74786c4b75205857624b6c6855745362544f7377575a666d7161417075676c6269794b63773100079d2bd0c6dade5ffea765fe0bf0579196f3e6bf1a96eb5b572e0edbc5c65379a40f4677657347595a4362546c6941557710706a654852534155594841704e5a523500060733e754710707eb1ee41fa64c0d023e930e2198e3da5e297c979cff522678c90b0b4f4a636c64475143485330034159380006060706f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4caa647dcefa4185863487a6d67527178454f6543524d5246675562764c75370a4a504d44636d5a5957300007a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe1b734570516e635a57564c42754f485567464273615a6372716442381e4d62665571756d596f4d4b754b72504b4947747357726b63764b774c6b320007d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7114b4c534866486e487376465253616b6e6810596849627856654554507545566864590006026f4333241b8ff4447a0255120c3774e90500001602d18b3a9edacbb3381497b9176c7df752035b21e40515a52e64b51768b646fb8824c6c46ee6c0676f800eb960edfbc95e2d05016dce5a11a385ef09dc247c4fa8e019778e14de34580afdd312002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409e9e88676c5ba1093cb10cd9332f60cf6f7cd3a99a08fb0dda1765ed0821a739d2b41f23f4ee24c62a992a32c8896a1175a82ffc51d37db474aa1e4e84410209", + "signed_txn_bcs": "8de3d2fe69f9040114f0eddc73809b7581ea3d959407d2792afcbe98bab628c3af647f70d4172235000257f5050606050763703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a6ea1495e03b5172066567043584a626d4b73416b7a4650785a4d6d5a6b4f6f7a737a6646494d4938036a45340007824c7e1321aca36efa9fba391ea26ea528165784a2199bfb50e4003a6e86d6501675574a504a656f48427a695246464565574472567738146861527044715a4b4b6e7071684d424a516f53670006060793456813ba68b80a7820875fdf6a5f2a9545db09460259fa80f41bf5e3307b7e14564d6f676375785a79566a56506a4f684a7049370c62656b44475163715748463600074722bc99a0a02f3ae3d09eb8db371a9abd8ec5f334528d51f60704484a73786e0c7762744644536e54534c643017636567525652456d5752736448526d57694276437a7739000600c801d12d47f1a8f87b7003709de7e77078e3ecaecdb23abe1148f35976ea3d4378b9aca4da1413fc167f30040927b1d4f7ce5f1720fe0500033fdda215dcd84b12ae3b39d38cb23c20e8e3d58a4c2d1dec6c0210f962816f5ea08b40042864b9a1ca7542548b0c281aa88062eda62aa4459d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059be01c9a11afad4448736ffa9caa6ec855b1dd11f7d89e9ccf4b064ad5bbb9f25e7a81f72eda1389369dcafef6f7ff0b51a7531e8a276a8f529c58f314b5608", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8e1ebc9679e32f24bf90850c31f83d681ad1138e7ad91961c4bc15ddc584efb5", - "sequence_number": "1531774979442275390", + "sender": "c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892caf395", + "sequence_number": "15924010228039490380", "payload": { "Script": { - "code": "6647c660dfe07df5", + "code": "39f4174e0ac563", "ty_args": [ - { - "struct": { - "address": "e85db5cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc", - "module": "MSuNqwhNEfGvb1", - "name": "yrCDYUlDqeQwcxiGDlU", - "type_args": [] - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "cb8cbf9c51e07a54be472f2639b172a6a91347b1621fd2547add7bd01a77964a", - "module": "cRsKxkleYYGYIisHe", - "name": "gvKMPUxXqFaAEGdFWmaleJi", - "type_args": [] - } - } - } - }, { "vector": { "struct": { - "address": "08d8987cee18bc8dbf51fca7ff09d60c29fc3a62b0658da52ebed8e794f67a58", - "module": "msHSoLYCBEsGvZGklcLfZdzFk", - "name": "QPaKwoJP", + "address": "1880c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f5", + "module": "sED", + "name": "rERUJKqfEvpeRpGWKGo0", "type_args": [] } } }, { "struct": { - "address": "28cc7d7defb0995a4a090dea42606751838e9d0d38071243b39e29c7e1f89a96", - "module": "hM", - "name": "qCGyqsVCxrRvuXGoup", + "address": "c47a106ea9f4bb0e6de0e5260779cbb5ca0d53aef66fb374ba6975a2648c8796", + "module": "hdN8", + "name": "zGbptcNRsthDJBdkGGeUtOfqdZN", "type_args": [] } }, { - "struct": { - "address": "af3328043fa96fef86dede6fc3c1ff4827638c8d85a408facc72c86c87d7ed27", - "module": "QxZMIOIyCytpMMBTw", - "name": "wfXdyMbiDCXjzRZVwtEqntfyGwoCP", - "type_args": [] - } + "vector": "signer" }, { "vector": { - "vector": "bool" + "vector": "u8" } }, { "struct": { - "address": "dfb50f6666fa7249fb853ad6286362bdb79cabefe60d16756275deabcaa2f8bd", - "module": "mbtFxPaFhGrQomAPnKYtNewWqyFToL7", - "name": "LXAQqWK7", + "address": "30738ea0c6caee779663874e581bfabcd474b26b1475ebcf0ec995645fb4eac2", + "module": "ROpQpcZNdyryWoRuAqIbYxMo", + "name": "JDRVAMdWxU2", "type_args": [] } }, { "struct": { - "address": "51802da9a7b1d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae", - "module": "hiYjzzDVIGGLJfGfreSwBZ", - "name": "EmUJztlpNLToECb3", + "address": "fb48e4c94ebbabd71c188bd193302764cc0228159d16a1430c1b03f830137c33", + "module": "sYzGzBJOn", + "name": "ziIAzfBYeWezEvYoJNTShHFMz", "type_args": [] } }, { - "struct": { - "address": "272d0814aacf69e4748d140c8b4a2a339192246afe8a0cfb1fb57e6c6bd7efc8", - "module": "sbQzUs", - "name": "sdKfYtgxFC", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } } + }, + { + "vector": "bool" + }, + { + "vector": "signer" } ], "args": [ { - "U64": "14152186213602291517" + "U128": "67228802430822539503780027228672268104" }, { - "U128": "194960027815502236621641780540778789210" - } - ] - } - }, - "max_gas_amount": "11270702748945352126", - "gas_unit_price": "16393096032874889482", - "expiration_timestamp_secs": "15583782261484208381", - "chain_id": 147 - }, - "signed_txn_bcs": "8e1ebc9679e32f24bf90850c31f83d681ad1138e7ad91961c4bc15ddc584efb53ef47c653af5411500086647c660dfe07df50907e85db5cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc0e4d53754e7177684e456647766231137972434459556c447165517763786947446c5500060607cb8cbf9c51e07a54be472f2639b172a6a91347b1621fd2547add7bd01a77964a116352734b786b6c655959475949697348651767764b4d505578587146614145476446576d616c654a6900060708d8987cee18bc8dbf51fca7ff09d60c29fc3a62b0658da52ebed8e794f67a58196d7348536f4c594342457347765a476b6c634c665a647a466b085150614b776f4a50000728cc7d7defb0995a4a090dea42606751838e9d0d38071243b39e29c7e1f89a9602684d127143477971735643787252767558476f75700007af3328043fa96fef86dede6fc3c1ff4827638c8d85a408facc72c86c87d7ed271151785a4d494f4979437974704d4d4254771d77665864794d62694443586a7a525a56777445716e74667947776f43500006060007dfb50f6666fa7249fb853ad6286362bdb79cabefe60d16756275deabcaa2f8bd1f6d62744678506146684772516f6d41506e4b59744e657757717946546f4c37084c58415171574b37000751802da9a7b1d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae166869596a7a7a44564947474c4a66476672655377425a10456d554a7a746c704e4c546f454362330007272d0814aacf69e4748d140c8b4a2a339192246afe8a0cfb1fb57e6c6bd7efc8067362517a55730a73644b665974677846430002013deff13861aa66c4025ab9f4bb6b97f6bb3c74266480efab92be05e8776f94699c0a815fd0fcf97fe3fdc0cc8066b744d893002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402df284e8a7025ab59f860da3779572d9bf63fa86e0d839823d2f6ce47e21ecb0f8910a1f96c25c1689f1c587fbb124cdbe1ad93c3e23ef8ade4ed2140ada620f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "fcd3a9fb8963cb187eed9d8581333546177e293deed637ef97802236473fa440", - "sequence_number": "13958774376282326110", - "payload": { - "Script": { - "code": "f80aaf8624857dc2f9fa8a3e863b", - "ty_args": [ - { - "vector": { - "vector": { - "vector": "u64" - } - } + "U8": 51 }, { - "vector": { - "vector": { - "vector": "u128" - } - } + "U8Vector": "37dcce" }, { - "vector": { - "struct": { - "address": "843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d59dbb74a", - "module": "XtghGaCEIONXYfcNzsXBdOrTaPQ3", - "name": "toJTykVmQtBiQGThlPSCQVJPuA", - "type_args": [] - } - } + "Bool": false }, { - "struct": { - "address": "15242f488fd3aafea900f66c6ff7239c648cd5f1fa3052d503c529b787b862a6", - "module": "wsKXPOscMrkDZhLk", - "name": "Sqlzdbydoir3", - "type_args": [] - } - } - ], - "args": [ + "U8": 58 + }, { - "U8Vector": "8aeccdd8bdc1fced28" + "U8": 84 } ] } }, - "max_gas_amount": "2987791653114619784", - "gas_unit_price": "2432473712390999682", - "expiration_timestamp_secs": "4367410872703778418", - "chain_id": 116 + "max_gas_amount": "1017335802261363768", + "gas_unit_price": "4706034258846139448", + "expiration_timestamp_secs": "1664197215799409446", + "chain_id": 5 }, - "signed_txn_bcs": "fcd3a9fb8963cb187eed9d8581333546177e293deed637ef97802236473fa4405e0422a65687b7c1000ef80aaf8624857dc2f9fa8a3e863b0406060602060606030607843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d59dbb74a1c5874676847614345494f4e585966634e7a735842644f7254615051331a746f4a54796b566d51744269514754686c50534351564a507541000715242f488fd3aafea900f66c6ff7239c648cd5f1fa3052d503c529b787b862a61077734b58504f73634d726b445a684c6b0c53716c7a646279646f697233000104098aeccdd8bdc1fced288827c6b2adc47629828e8a20f4e1c12172feaf970c299c3c74002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bed079a278c90b2d87d7c3e491aeb2bde5b466d07a3677ae1c684e0e72ce62838ae7d10c74d71da91a4040288bf377d86037a3f9c2104086d0954fa724f1230d", + "signed_txn_bcs": "c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892caf3954c1bfbf1ee72fddc000739f4174e0ac5630906071880c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f50373454414724552554a4b716645767065527047574b476f300007c47a106ea9f4bb0e6de0e5260779cbb5ca0d53aef66fb374ba6975a2648c87960468644e381b7a47627074634e52737468444a42646b47476555744f6671645a4e0006050606010730738ea0c6caee779663874e581bfabcd474b26b1475ebcf0ec995645fb4eac218524f705170635a4e64797279576f52754171496259784d6f0b4a445256414d64577855320007fb48e4c94ebbabd71c188bd193302764cc0228159d16a1430c1b03f830137c330973597a477a424a4f6e197a6949417a6642596557657a4576596f4a4e54536848464d7a00060606050600060506024897807e8088897ca1437e14dfcb93320033040337dcce0500003a0054385c13a7854d1e0e38c4578b39314f4126fbeaeb8c6a181705002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fbb546e7dcf26ad5f04cf8ab5f2526f14f760209473c8550095686c1e0b1052f2d4c82f677f295091847f060d244b11f5dedc4acb732df1944160ab747fec10d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8c5db5d33a1df20826b289a2ca85ece7419a15e58af4d382ab492d6aa625c4eb", - "sequence_number": "1090973585839028943", + "sender": "4d50f4c12e01baae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337", + "sequence_number": "9471017033331266559", "payload": { "Script": { - "code": "bf1c59cf0baa493976bff76331b9", + "code": "debef9b128", "ty_args": [ { - "vector": { - "struct": { - "address": "963c5883f1e7a92e44fc732ab84a5c03bd99ff6d6105b7ce018898328e75f3be", - "module": "aryQWAArhiCdGRdLtEHB9", - "name": "uGJfWKnwjVKGAXSzZvXhGi0", - "type_args": [] - } + "struct": { + "address": "b5dd8f205c57d6832740124dba5338ec4def3e5f0c05ce66b3dc92edd72ee42a", + "module": "rneDZZQYrTYjPHAkOt6", + "name": "NXBybToidd2", + "type_args": [] } }, { "struct": { - "address": "2c4457c7c3879fcc0df5466d0213af9bb79083d70b78cd9d2edcae3ef32077d6", - "module": "vknOCbGlZxPsmRIGvfFAvWC1", - "name": "FaJVsEHUlhZ4", + "address": "2a005fccec34d22363828f2537eb23a5189db6fd7537541685a7ebbff0b74a51", + "module": "UOtsc", + "name": "TzTqPqvEHnyCuipYajoUclzsX", "type_args": [] } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "ee37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18", + "module": "ntqyAKjQcuG", + "name": "iqkSFFEWleqvKkDYjwHLHRVRNamWoac9", + "type_args": [] + } + }, + { + "struct": { + "address": "6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7beaa600b1e94d2bc2b3ac719", + "module": "sOEiY4", + "name": "KpiNlsDnhnwgKsxpmDKDUfxw3", + "type_args": [] } }, { "struct": { - "address": "dad07b8742e46016a90d64418e3d2b6d9f48d18b4a80589994575f02bf93b4bc", - "module": "RUeCPDuj", - "name": "QBqXtpVBTsYElifqUgDImkWeRCuiQJT2", + "address": "3641bbff5cd093affb7e3e6424b01cc8bfd8a01f5553afd58ec6c0ec8032e1d0", + "module": "zIzGC6", + "name": "jZMFuMJblJKwLZRNC3", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "vector": "u128" + } } }, { "vector": { - "vector": "signer" + "struct": { + "address": "579c8b019621fed5a2a5659a45b9f705c783c8d8ee3ce294726c3e8ec64c0ba7", + "module": "qfOsq3", + "name": "zGcbzTYEdIlMDZezTUffhlmnq", + "type_args": [] + } } } ], "args": [ { - "U128": "11498965134222276024643446538925200043" + "U128": "192491556015919642584328801971437344312" }, { - "U128": "40220626748274954768399808851027050712" + "Address": "769da8c9395ad4d2cd3ffc7d3b5c506864ed0d9265bc3354270465acae2babfb" }, { - "U8": 129 + "U8Vector": "0efc8c81acf01d06e4a9" }, { - "U8": 200 + "U8": 179 }, { - "U8": 184 + "U128": "315077671688090229400148984499658756826" }, { - "U64": "6380118867066596080" + "Bool": false }, { - "Bool": false + "U128": "65705937973926824295544856324934735466" }, { "Bool": false @@ -3364,513 +3449,687 @@ ] } }, - "max_gas_amount": "5957574110157586789", - "gas_unit_price": "18235895432617489712", - "expiration_timestamp_secs": "14750702199615523789", - "chain_id": 136 + "max_gas_amount": "16439330115351780794", + "gas_unit_price": "15831311977517755346", + "expiration_timestamp_secs": "8542313520942612831", + "chain_id": 233 }, - "signed_txn_bcs": "8c5db5d33a1df20826b289a2ca85ece7419a15e58af4d382ab492d6aa625c4ebcffa4433b2ea230f000ebf1c59cf0baa493976bff76331b9060607963c5883f1e7a92e44fc732ab84a5c03bd99ff6d6105b7ce018898328e75f3be156172795157414172686943644752644c74454842391775474a66574b6e776a564b474158537a5a76586847693000072c4457c7c3879fcc0df5466d0213af9bb79083d70b78cd9d2edcae3ef32077d618766b6e4f4362476c5a7850736d52494776664641765743310c46614a56734548556c685a340006060207dad07b8742e46016a90d64418e3d2b6d9f48d18b4a80589994575f02bf93b4bc08525565435044756a205142715874705642547359456c696671556744496d6b576552437569514a5432000606000606050802ab5277d47d0e0fcbefe3dbb7c09ea60802d840c69d92fcb8e547c438670036421e008100c800b801f0aa45684ebc8a580500050065c101af168ead523075552e47ea12fdcd0ba87b7f05b5cc88002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ecbb63562fff2f90d3b0f1ce3e0a101ac87734e51075ca24c8d498567c2710e6ce53bb7e9866f454f9115c49204f8f22ea063dd992f797bce4a7caef9c32d008", + "signed_txn_bcs": "4d50f4c12e01baae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ff5362edcfcf6f830005debef9b1280707b5dd8f205c57d6832740124dba5338ec4def3e5f0c05ce66b3dc92edd72ee42a13726e65445a5a51597254596a5048416b4f74360b4e58427962546f6964643200072a005fccec34d22363828f2537eb23a5189db6fd7537541685a7ebbff0b74a5105554f74736319547a547150717645486e794375697059616a6f55636c7a73580007ee37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd180b6e747179414b6a516375472069716b53464645576c6571764b6b44596a77484c485256524e616d576f61633900076dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7beaa600b1e94d2bc2b3ac71906734f45695934194b70694e6c73446e686e77674b7378706d444b44556678773300073641bbff5cd093affb7e3e6424b01cc8bfd8a01f5553afd58ec6c0ec8032e1d0067a497a474336126a5a4d46754d4a626c4a4b774c5a524e433300060606030607579c8b019621fed5a2a5659a45b9f705c783c8d8ee3ce294726c3e8ec64c0ba70671664f737133197a4763627a54594564496c4d445a657a54556666686c6d6e710008023896585d4485151b6fd995047286d09003769da8c9395ad4d2cd3ffc7d3b5c506864ed0d9265bc3354270465acae2babfb040a0efc8c81acf01d06e4a900b302da12937e3c9a5472a33840d894c009ed0500026a1698b2e328d4dc5c080c56db806e310500ba9decfea33b24e4d22b559c5d1eb4db5f01cd5fe3648c76e9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ab366fc4627c973f47f14ee9fe4bab7ecc195a8920571c172c7cc3a8a6ed8cd068cd7ee8e6e4b33adc761614424766a33f804adc8513586d3e1a576c22e2ad0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "26cf3699b9e805ec28839231e73bff9390bcc8599f279ca5ad5f0fdde2713662", - "sequence_number": "3837411713125595783", + "sender": "79d9b4031d6fee835f5eeba9add0cb2eafac14b75b4270c9882bc0331cf4f6f8", + "sequence_number": "11221441559277894029", "payload": { "Script": { - "code": "7a2aabaeefb8294ac2", - "ty_args": [], - "args": [ + "code": "91ba8fdf0e1593677ad3ebedee51beca", + "ty_args": [ { - "Bool": true + "vector": { + "struct": { + "address": "e02c89f2d2aa2d29a646236c2c4b738570480d25967526c2c60445d39f6700d0", + "module": "UVwLK", + "name": "avrVUjQmQzKaAxyCoo", + "type_args": [] + } + } }, { - "U64": "3474333142161611273" + "struct": { + "address": "6082686acaf755abab06205587b9651ef61f66d2feaf6927043d969aecc8a79f", + "module": "lSKi", + "name": "nmFWqxyirLUgCAGvEqAq3", + "type_args": [] + } }, { - "Bool": false + "vector": { + "struct": { + "address": "f2270ea8dda05f6be736502ba28eab40726ad1e4e433b7461b31dfc6d8633713", + "module": "hIOTcNPREIFOILDIe", + "name": "PVjaNsEEIiA", + "type_args": [] + } + } }, { - "U128": "210275219742270604359323107769974579373" + "struct": { + "address": "0e133c46a1444f425dba67536b4d6a3d8dd7a92d3b99dcf014625c2129c69194", + "module": "ZyHXbuOHUVurbH0", + "name": "UkmraNY", + "type_args": [] + } }, { - "U64": "17806591079525347967" + "struct": { + "address": "5cad39a475562104801796a215cbefb9cc3ee4132485146129299ef7bef46732", + "module": "YtnHgwNGdDrZsdHqLYeWVdVcy7", + "name": "NSYboeSAJDtfsYtICRDvKGx2", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "077c0562d76c53034d1103c3c75c976e5f5192e361ee493b789aa49bd0e0d5ad", + "module": "J", + "name": "zByxsMCNCFbuSxMWYhlNxI2", + "type_args": [] + } }, { - "Bool": false + "vector": { + "vector": { + "vector": "address" + } + } + }, + { + "struct": { + "address": "6556c5a22712d8050a89ce283dc2d678c910e40215ab91e95e13601bed4cd252", + "module": "SjrPGbQvGRJFjWipQPsOlbevcw8", + "name": "bChjkDgoFmHK", + "type_args": [] + } + }, + { + "vector": { + "vector": "u8" + } }, { - "U64": "179749017677351005" + "struct": { + "address": "20536a0be579aa23b615ab7c222cad8a4430c6e8065be9890108095ab704067f", + "module": "RBdpkSE8", + "name": "z5", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "17551628816525803969", - "gas_unit_price": "976402986023287607", - "expiration_timestamp_secs": "1412463201473963225", - "chain_id": 74 + "max_gas_amount": "415783401751606302", + "gas_unit_price": "14633880235777633592", + "expiration_timestamp_secs": "7303237492838149505", + "chain_id": 248 }, - "signed_txn_bcs": "26cf3699b9e805ec28839231e73bff9390bcc8599f279ca5ad5f0fdde2713662873ac6219f39413500097a2aabaeefb8294ac2000805010109dae8c1954f3730050002ade03c0a02bfa63e8ae51d10c388319e017f72bf533eb81df705000500015d48627bc7987e02c1c187866ae993f3377b8cb357e18c0dd9a42a56cc139a134a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb7713dde0084ceb521da5fad43a0cb8b9985a8cc797d3335fc7a6faeeecf6a532645dbc81168b9526ecedf08e1ccebeeec5dbfccd8729b7e1759cc20e354302", + "signed_txn_bcs": "79d9b4031d6fee835f5eeba9add0cb2eafac14b75b4270c9882bc0331cf4f6f88d7990f8a491ba9b001091ba8fdf0e1593677ad3ebedee51beca0a0607e02c89f2d2aa2d29a646236c2c4b738570480d25967526c2c60445d39f6700d0055556774c4b1261767256556a516d517a4b61417879436f6f00076082686acaf755abab06205587b9651ef61f66d2feaf6927043d969aecc8a79f046c534b69156e6d465771787969724c5567434147764571417133000607f2270ea8dda05f6be736502ba28eab40726ad1e4e433b7461b31dfc6d86337131168494f54634e50524549464f494c4449650b50566a614e73454549694100070e133c46a1444f425dba67536b4d6a3d8dd7a92d3b99dcf014625c2129c691940f5a79485862754f485556757262483007556b6d72614e5900075cad39a475562104801796a215cbefb9cc3ee4132485146129299ef7bef467321a59746e4867774e476444725a736448714c596557566456637937184e5359626f6553414a44746673597449435244764b4778320007077c0562d76c53034d1103c3c75c976e5f5192e361ee493b789aa49bd0e0d5ad014a177a427978734d434e4346627553784d5759686c4e7849320006060604076556c5a22712d8050a89ce283dc2d678c910e40215ab91e95e13601bed4cd2521b536a72504762517647524a466a5769705150734f6c6265766377380c6243686a6b44676f466d484b000606010720536a0be579aa23b615ab7c222cad8a4430c6e8065be9890108095ab704067f08524264706b534538027a3500001e74e80ccd28c50538ad22738afc15cb81adee36ce4f5a65f8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ebfaff60548c97e767560610e21ee3db6dfd4ed33068f40f5df2ba5317814cf375785e21351d28327325291d823e1ffa6234b3702517e233d6786b18343b2506", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014ccf4d4d11", - "sequence_number": "952304163986397957", + "sender": "fd91737f1f2564120a47f2654ab4fe40d1ab066d3c2cc3c35eb6d641cfeb5f45", + "sequence_number": "2650617817229611596", "payload": { "Script": { - "code": "2273eef7aadb2feb28d7bb8b9c", + "code": "48", "ty_args": [ + "address", { "vector": { "struct": { - "address": "c902c19db898215966dcbbf40418bb60eccade43af61131fc6ac54d958a1ffd2", - "module": "J5", - "name": "aQPIryAbyAZE", + "address": "5ffced1e7dd63f89bbe53def9834e6f1c114ec1a191739dd3030f648212cf854", + "module": "QcBearFRJCibyU2", + "name": "dI8", "type_args": [] } } }, { "struct": { - "address": "1ecb60f2e987df96f74549169b7e447ea48608c2b6bb641e62e55c02e26fe57f", - "module": "eRIOnKdGOmiLJuGulektKiSpNUTGq", - "name": "lOqPMftEbXuvoZ8", + "address": "cd0f33c5c4bf7352239bb0547a2833d7f14eab2f2366e8aad462b07c682fead3", + "module": "GzbZvhfcbBXKbbslaiJ6", + "name": "PqjcKNg", "type_args": [] } - } - ], - "args": [ - { - "U128": "232387967613288644351367840724258676038" }, { - "U8": 77 + "vector": { + "vector": { + "struct": { + "address": "c081b92e0652063e7e3d1e92631daa2e4fff507a91ce173fbdeac451bf8b4510", + "module": "qGzT", + "name": "TrzFMzCJFefTzMxCWpSZ", + "type_args": [] + } + } + } }, { - "U8": 45 - }, + "struct": { + "address": "1c9bea037151e18bcea8bcd3c3375d8feb86ca256f52bdc48766ceccb284bee9", + "module": "XApCxzfxiMgPbjDAqouZKJaxddeIFZWW", + "name": "sBvPhXMQIqNHBgCgvpaBHiQCuXY8", + "type_args": [] + } + } + ], + "args": [ { - "Address": "b029d244fa4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1" + "U128": "327594961058430596899094752992007146957" }, { - "Bool": false + "Bool": true }, { - "Address": "4ca80644f26fcf50ee912d11d8c10608f4dc9f6873fcbb7ab3000f8aac023a99" + "Bool": true }, { - "U8": 158 + "Bool": true }, { - "U8Vector": "978c05f9caba352ccbd8de8ddeab6b" + "Address": "ea5c6a3e632cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a" }, { - "U64": "9930114374004042041" + "Bool": true } ] } }, - "max_gas_amount": "2160534189671687279", - "gas_unit_price": "11793001753851515959", - "expiration_timestamp_secs": "13217010274385529707", - "chain_id": 242 + "max_gas_amount": "14517550843959167445", + "gas_unit_price": "11705723287556020675", + "expiration_timestamp_secs": "3608535604572905763", + "chain_id": 162 }, - "signed_txn_bcs": "486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014ccf4d4d1105db88749743370d000d2273eef7aadb2feb28d7bb8b9c020607c902c19db898215966dcbbf40418bb60eccade43af61131fc6ac54d958a1ffd2024a350c615150497279416279415a4500071ecb60f2e987df96f74549169b7e447ea48608c2b6bb641e62e55c02e26fe57f1d6552494f6e4b64474f6d694c4a7547756c656b744b6953704e555447710f6c4f71504d667445625875766f5a38000902465df88be98efbbeef41f9e6674bd4ae004d002d03b029d244fa4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c10500034ca80644f26fcf50ee912d11d8c10608f4dc9f6873fcbb7ab3000f8aac023a99009e040f978c05f9caba352ccbd8de8ddeab6b0139e9824169dace896fa4770466c2fb1d37d4e0f59c28a9a36b0b705dd1406cb7f2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c8113d2cc236097cbe532fb4fcf17a630bf62dd9d97fbeaa185ff271e1f99a4ad55b1bf57b77515d7f0ed3a0b344d52a3a03c3ddf3f0a9cdd044b5ef75cf0200", + "signed_txn_bcs": "fd91737f1f2564120a47f2654ab4fe40d1ab066d3c2cc3c35eb6d641cfeb5f454cd24a77dce2c824000148050406075ffced1e7dd63f89bbe53def9834e6f1c114ec1a191739dd3030f648212cf8540f51634265617246524a436962795532036449380007cd0f33c5c4bf7352239bb0547a2833d7f14eab2f2366e8aad462b07c682fead314477a625a766866636242584b6262736c61694a360750716a634b4e6700060607c081b92e0652063e7e3d1e92631daa2e4fff507a91ce173fbdeac451bf8b45100471477a541454727a464d7a434a466566547a4d78435770535a00071c9bea037151e18bcea8bcd3c3375d8feb86ca256f52bdc48766ceccb284bee92058417043787a6678694d6750626a4441716f755a4b4a617864646549465a57571c7342765068584d5149714e4842674367767061424869514375585938000602cdcda97cd696c21457de1d6c987e74f605010501050103ea5c6a3e632cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a0501d5c9db4693b378c9c359cb794f1573a223e1ea7503181432a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444049cb88b2dc313df7808025a5a2747661dcf4f4cb61ab3dc80fd9c85faae9552472cf0f06bcf031d6415cd3dd4430a48755496afc07a3074662173195e2279706", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "69a703bc29521209bc81a7a30a8910ddc0403728f624968cd7df9c3aa85c1778", - "sequence_number": "11014360300890509205", + "sender": "b496b45da267963eb32879cf4e6242c4bac5e42638e8a27f639c43d9bced74b8", + "sequence_number": "9116319703090776671", "payload": { "Script": { - "code": "cff2ff50feb339023490fb16afadad", + "code": "65ac1043baf8", "ty_args": [ + { + "vector": { + "vector": "address" + } + }, { "struct": { - "address": "258f9943eaa590e8e17023f2b221a414203e6559274f9e542a889bb5fde471da", - "module": "eeHEIukXLGamvkyKwsduSAsAM", - "name": "ozObeLbirdvMLJErXZUg8", + "address": "191d254641229a20ed1c926f587c1bef78c6366d2c2aa8ed90e8cad026ab16b3", + "module": "lLDAonOfGfJdIzsSylpNVyoVVKJ7", + "name": "AJMDmcfCmDqktVEohvhartHPcx6", "type_args": [] } - } - ], - "args": [ - { - "U128": "117050558650263471822715105162506020147" }, { - "U64": "6781022535632576491" + "struct": { + "address": "0a65ab615f5414a69ff8976c8d3cc27ac858786d4f7ada52a7b0ec0af6788527", + "module": "tdjxwS0", + "name": "QJIArbWjwCMsFpiajzPFsvjcIHVNuUP9", + "type_args": [] + } }, - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "4879753392121320192", - "gas_unit_price": "13407482513661342686", - "expiration_timestamp_secs": "5942918218619123171", - "chain_id": 118 - }, - "signed_txn_bcs": "69a703bc29521209bc81a7a30a8910ddc0403728f624968cd7df9c3aa85c1778954fbe4a56deda98000fcff2ff50feb339023490fb16afadad0107258f9943eaa590e8e17023f2b221a414203e6559274f9e542a889bb5fde471da196565484549756b584c47616d766b794b77736475534173414d156f7a4f62654c62697264764d4c4a4572585a5567380003023325b04ee41d9282e7079f741a1e0f5801eb5f4c9a11081b5e05000013e628db5db843deb30b6f4ff210bae375fd05a27c795276002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a098dd6df76c938183b6a653723e5b13b797f687c60e7d25755f26983836c6908c7365227e576c69a2e6198c5f6b29491270abe5ae0fc415e5ddb7dc1532cd05", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cb8e1ede05c66b884d7ef63335bf26c5a09226e573550f9ec44e56531fb2cf40", - "sequence_number": "969269243045527319", - "payload": { - "Script": { - "code": "1b7100", - "ty_args": [ { "struct": { - "address": "295304bf743f1814c6b997191454a279d7e41bc8e3935aa010725a41f4fa1053", - "module": "xv", - "name": "WcoTQGHpLYIZbLlCvWBTpNqxtSYUtJ0", + "address": "595cee5c556ce602d702dd878a1bd2bfe2efcd59c1ee2a88af95b1033682f134", + "module": "jSINWBqmLgEVUBCnXQNuPnPFtjavGl", + "name": "njqpRFsAxgrcjcFqwHdhTehrftcWR", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "8e971631daed54a847955df25f5a8252001d36886356be2617b44125825e635c", + "module": "CGoWoQgDAUzuHgNOwQoLHG", + "name": "pHGfOAPWesKZZlycdEjPJLp8", + "type_args": [] + } + } + }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "5907e32695a4ea0dbb4d770c4dfc1cf41a0cd811d6e8bcbbc96881dfecc8150d", + "module": "ucpjUkgJhEyfQwdEXUWiZ", + "name": "trA", + "type_args": [] + } } } }, { "vector": { - "vector": "bool" + "struct": { + "address": "0c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e8d81", + "module": "w3", + "name": "AZACBTQVhjjrzoCdpJwaNdZiqE", + "type_args": [] + } + } + }, + { + "struct": { + "address": "d51c524062b2c07f8c08d8d4332a9bcfe3e4ef286858c1cba97cc5923e3eef17", + "module": "TZnEeU6", + "name": "gTVpTgvAxuXitKkXAeL", + "type_args": [] } } ], "args": [ { - "U8Vector": "7b7b16c11bba" + "U8Vector": "ba2fa7d8330e" }, { - "U8": 218 + "U8Vector": "cb501d5cdc" }, { - "U8Vector": "46c9" + "U128": "89570550819865856735458984007533375076" }, { - "U8Vector": "e8c62a152bd2e1" + "Bool": false }, { "Bool": false }, { - "Address": "084fe2fced7a6b69c27292e167499b1dd350d456f65e0b517f53ab7ee75301f6" + "U128": "19565242277200864594553890093588396337" }, { - "U64": "11393535352084719867" + "U8": 43 }, { - "U8Vector": "399bd44d667a58c26c6e0fc6c7" + "Address": "efeeea7fbfb4b63404dce6c484be0141fc60cde3c8ca570cf9ef4df33220caa5" }, { - "Bool": false + "U128": "238033984331132102971666449500149121802" }, { - "U8": 76 + "U64": "14292111081056986895" } ] } }, - "max_gas_amount": "14082883475045409068", - "gas_unit_price": "10635544574547446870", - "expiration_timestamp_secs": "12054556410856265370", - "chain_id": 216 + "max_gas_amount": "12863496450124996033", + "gas_unit_price": "2494701448280716011", + "expiration_timestamp_secs": "4720182960744506747", + "chain_id": 162 }, - "signed_txn_bcs": "cb8e1ede05c66b884d7ef63335bf26c5a09226e573550f9ec44e56531fb2cf4017bf70bb3d89730d00031b71000307295304bf743f1814c6b997191454a279d7e41bc8e3935aa010725a41f4fa10530278761f57636f54514748704c59495a624c6c4376574254704e717874535955744a3000060606040606000a04067b7b16c11bba00da040246c90407e8c62a152bd2e1050003084fe2fced7a6b69c27292e167499b1dd350d456f65e0b517f53ab7ee75301f601fb68dd8409f81d9e040d399bd44d667a58c26c6e0fc6c70500004c2ce14cffe77370c356ccbbe6700b99939ad6fe1930634aa7d8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405a5502d8c0b752d558fbd3b0c4d1653a08786645d584a799c9cc10b64dc0466311bd9dd655abe495f23395209913cf45fc8a8abec99e31527ed4ae1411227905", + "signed_txn_bcs": "b496b45da267963eb32879cf4e6242c4bac5e42638e8a27f639c43d9bced74b85fca9e3978ac837e000665ac1043baf80806060407191d254641229a20ed1c926f587c1bef78c6366d2c2aa8ed90e8cad026ab16b31c6c4c44416f6e4f6647664a64497a7353796c704e56796f56564b4a371b414a4d446d6366436d44716b7456456f687668617274485063783600070a65ab615f5414a69ff8976c8d3cc27ac858786d4f7ada52a7b0ec0af67885270774646a7877533020514a49417262576a77434d73467069616a7a504673766a634948564e755550390007595cee5c556ce602d702dd878a1bd2bfe2efcd59c1ee2a88af95b1033682f1341e6a53494e5742716d4c6745565542436e58514e75506e5046746a6176476c1d6e6a717052467341786772636a634671774864685465687266746357520006078e971631daed54a847955df25f5a8252001d36886356be2617b44125825e635c1643476f576f51674441557a7548674e4f77516f4c484718704847664f41505765734b5a5a6c796364456a504a4c7038000606075907e32695a4ea0dbb4d770c4dfc1cf41a0cd811d6e8bcbbc96881dfecc8150d157563706a556b674a6845796651776445585557695a037472410006070c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e8d810277331a415a414342545156686a6a727a6f4364704a77614e645a6971450007d51c524062b2c07f8c08d8d4332a9bcfe3e4ef286858c1cba97cc5923e3eef1707545a6e4565553613675456705467764178755869744b6b5841654c000a0406ba2fa7d8330e0405cb501d5cdc0264aeb89ed416bb090ebc80d01ca96243050005000231b9f91204b7d095bf6713bdeb20b80e002b03efeeea7fbfb4b63404dce6c484be0141fc60cde3c8ca570cf9ef4df33220caa5020a032cad637fd4e6fca427a585ad13b3010f67d32c4ec757c6c1dd321fde5184b2ebb26cedbff59e227b2507ea64758141a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406aa6c4e66e633208cb1d16e63f71a6d0bbc42bffa525914709b17e0268dc641d42f06c05093bb70c40753d60c829cc3c839738a35dc426dff0163a4707588b02", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6c4d06761ddf84c64496cfd4e90bb6dfa21f6d8edfb3dac808ea82fd6f4af666", - "sequence_number": "13469864845076407220", + "sender": "1817204690db3824f9f05d4ec6f43557a1c5882654df1ad325885b8c294b349a", + "sequence_number": "4029562605877010109", "payload": { "Script": { - "code": "d881b00aff4131", - "ty_args": [], - "args": [ + "code": "afb458bee86c", + "ty_args": [ { - "U64": "4718097164583779556" + "vector": { + "struct": { + "address": "aa88062e8f3b136b417d538421f5e3f4ca896584b68afdfe5a59f514a9f642fa", + "module": "QSgKXtFOJQJlLnlxuONxMluoyj", + "name": "ttbSKjBIxeVQPHoWmushBPHoF", + "type_args": [] + } + } }, { - "Address": "eeaed7fc702189e3d378e03411df26e29d5921214ae0129b39984f9dbf64cf8e" + "struct": { + "address": "091f829b206cd6c9fdb5ab2f465e36648f1a8714fe28079b02eccb6cd9af0739", + "module": "CFuzeaNxb", + "name": "blOTEHc", + "type_args": [] + } }, { - "U128": "256345448976444894725098292547615511212" + "struct": { + "address": "be687ea156deebf0cf880924fb04d51c01d6062b96d5f9f1e58d5560e3f8052e", + "module": "frvnhwBafhO", + "name": "QMCsRIbWoqDXVDp", + "type_args": [] + } }, { - "Bool": true + "struct": { + "address": "8ee875c54848f73b1809b94f9ab84f4d703b93909defdbd9a76f51c611e01136", + "module": "GZoOPEgq5", + "name": "WUW8", + "type_args": [] + } }, { - "U128": "330487666557371312528993012441621356572" + "struct": { + "address": "e05d59c85624c04ed7d9a21f17303f4539fb44fd6eaf9abea168182057b6f189", + "module": "U2", + "name": "puCl6", + "type_args": [] + } }, { - "U64": "423311800870371780" + "struct": { + "address": "78695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e26", + "module": "aHI2", + "name": "xAhcdPQRvPXvFso0", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "f50c5960c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f", + "module": "dWIFFjnLDauAkdNYleDhEABlX2", + "name": "H4", + "type_args": [] + } }, { - "U8Vector": "3ff737252b62b3" - } - ] - } - }, - "max_gas_amount": "14310406112985531978", - "gas_unit_price": "503010067782432092", - "expiration_timestamp_secs": "5290525690940886077", - "chain_id": 188 - }, - "signed_txn_bcs": "6c4d06761ddf84c64496cfd4e90bb6dfa21f6d8edfb3dac808ea82fd6f4af666b4234dcfb592eeba0007d881b00aff4131000801e43ccba65f0c7a4103eeaed7fc702189e3d378e03411df26e29d5921214ae0129b39984f9dbf64cf8e02acd2a45d17e776bfd6968cdc6e56dac00501021c60a21c34aee8a3452993e0fc9ba1f801c4011c10d7e7df05050004073ff737252b62b34ac6143c8ac698c65cf59dd8fd0cfb063d0c9ce315b96b49bc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404f473d1aa408bef577f6b9d74ba18581d126ba6a347293f88911d478ed8bee135d9eefa38776de4a7ec95fcc4180a0134e2b728ba3eba5b28877d9c7ee949205", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "37ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c63d3f53516c939c6", - "sequence_number": "5365422232441453102", - "payload": { - "Script": { - "code": "21", - "ty_args": [ + "struct": { + "address": "6925a8ba7189706479aae9b165ca82f1cef225ff753ebcc69c69a637257cc55e", + "module": "nMXsBxTlZDYoPXGHTJGcKBwrJTbp", + "name": "JBgYeFnMcKrWjbCrWqDmS6", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "16120a8d6a5ed7c1b2bb348adc2cf33b2fc5a99aa3b13f7ada39157e1f777040", - "module": "DZdTpBexKFDEgGLwgSUWjaaWcBqDV", - "name": "QQBFp0", + "address": "dd72f39e2b279d53ba8de746e3c6c466d9b87e5b8ffa6c52d6ec4ba7dd0bc896", + "module": "JuEAiOLX", + "name": "GBwZSMZ7", "type_args": [] } } + }, + { + "struct": { + "address": "1d30f9180d8555cd4ef355a6c54cf93a982866b52730062f54999f929ff3ee35", + "module": "jeUJQqQoaSuVyRLfpfncRfTCNvTC", + "name": "SEJySte9", + "type_args": [] + } } ], "args": [ { - "U64": "13902666144100980934" - }, - { - "U128": "19767269901051689400272223097837913919" - }, - { - "U8": 175 + "Bool": true }, { - "U64": "7212250821232717834" + "U8Vector": "fc3b709b93" }, { - "Bool": false + "U64": "539015909240454383" }, { - "U8Vector": "3cb19dab5014dd6bea" + "U8Vector": "663c8c64e1ebde9f933db973c3" }, { - "Address": "898b34e3ed5a1017e7a170092b363d89e400898dae2c89f96b259fd616a26ebd" + "U128": "295100329759719467903817925573479009762" }, { - "U64": "4264585990717292329" + "U8": 85 }, { "Bool": false }, { - "U8": 105 + "Bool": false } ] } }, - "max_gas_amount": "4506247237582036488", - "gas_unit_price": "4160030373782694693", - "expiration_timestamp_secs": "2642486563502286357", - "chain_id": 131 + "max_gas_amount": "3737336546645264515", + "gas_unit_price": "12905892364096598225", + "expiration_timestamp_secs": "12729379616073566242", + "chain_id": 254 }, - "signed_txn_bcs": "37ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c63d3f53516c939c62efaa7da17cf754a00012101060716120a8d6a5ed7c1b2bb348adc2cf33b2fc5a99aa3b13f7ada39157e1f7770401d445a6454704265784b46444567474c77675355576a616157634271445606515142467030000a01c618fdd53231f0c0023f0729aab70582dc93f6a4d8a609df0e00af010a7098e6e80f1764050004093cb19dab5014dd6bea03898b34e3ed5a1017e7a170092b363d89e400898dae2c89f96b259fd616a26ebd0129bfcf225dda2e3b05000069089e29cafc67893e252b278c9565bb3915e64b6d87ffab2483002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd48d2401e93cdbd3a339bf7c78daeb7ea6ba21e7617c2a1fe0c2a0c1300c159dc8b5544d142c7caaed2102fafbf6585be5fd20bbd991c8b98c26ab80b47f10b", + "signed_txn_bcs": "1817204690db3824f9f05d4ec6f43557a1c5882654df1ad325885b8c294b349abd1e7f2bd7e1eb370006afb458bee86c0a0607aa88062e8f3b136b417d538421f5e3f4ca896584b68afdfe5a59f514a9f642fa1a5153674b5874464f4a514a6c4c6e6c78754f4e784d6c756f796a19747462534b6a42497865565150486f576d7573684250486f460007091f829b206cd6c9fdb5ab2f465e36648f1a8714fe28079b02eccb6cd9af0739094346757a65614e786207626c4f544548630007be687ea156deebf0cf880924fb04d51c01d6062b96d5f9f1e58d5560e3f8052e0b6672766e6877426166684f0f514d4373524962576f71445856447000078ee875c54848f73b1809b94f9ab84f4d703b93909defdbd9a76f51c611e0113609475a6f4f504567713504575557380007e05d59c85624c04ed7d9a21f17303f4539fb44fd6eaf9abea168182057b6f189025532057075436c36000778695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e2604614849321078416863645051527650587646736f300007f50c5960c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1a64574946466a6e4c446175416b644e596c6544684541426c583202483400076925a8ba7189706479aae9b165ca82f1cef225ff753ebcc69c69a637257cc55e1c6e4d58734278546c5a44596f50584748544a47634b4277724a546270164a42675965466e4d634b72576a6243725771446d5336000607dd72f39e2b279d53ba8de746e3c6c466d9b87e5b8ffa6c52d6ec4ba7dd0bc896084a754541694f4c58084742775a534d5a3700071d30f9180d8555cd4ef355a6c54cf93a982866b52730062f54999f929ff3ee351c6a65554a5171516f6153755679524c6670666e63526654434e7654430853454a7953746539000805010405fc3b709b9301efbc8f161df87a07040d663c8c64e1ebde9f933db973c302e28d889201b0d55e2d368d3e944102de0055050005008348e0b4c9afdd33d170670fbaf01ab322c8295351d7a7b0fe002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c65b3a17592d876127ffcc3551362e9b3641fa749628f71120e43517bcb46c9477f2d9dcc03c10ec07770431854804ab0f9847ebe02b124ab5fdbe15db296d03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6dd40d41", - "sequence_number": "5837377380404227635", + "sender": "c85186271e150dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77", + "sequence_number": "9007599062242443603", "payload": { "Script": { - "code": "3c0d88a48ec0e1bfc0dc0936", + "code": "f61d5deb3d3a4cee24", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "5676ad8838a31b2c93550d3b9e34484843ed652a5be2a36dae7629cfae4da90c", - "module": "EKfsRy", - "name": "TCriPDrcumkPSfdpqmrRKdXVZMNwE4", - "type_args": [] - } - } + "struct": { + "address": "5b743ad3a9a964703db5bcd8923f1a9680fc7285f7eaa0670980bb3a6095d0c0", + "module": "hhRxURnzlKiTvVsHFvU4", + "name": "EyVKMhbBV", + "type_args": [] } }, { - "vector": { - "vector": { - "vector": "bool" - } + "struct": { + "address": "610b0d3fd1f4066c47cb2b2de32e0884ec455e6f4785bce0a7897a06f2ae3935", + "module": "yvbEsysOeqLGubWjqAYaiGL5", + "name": "DsxooJiNeouvPHavarBgKThLlmEca", + "type_args": [] + } + }, + { + "struct": { + "address": "1d61afa6a3d12d1aaf8edc78fc906572c28849c38914332a9946d6a5d1c9fca4", + "module": "kzqmVgnoPohcTuyMNFZTH7", + "name": "tQzRExmvgYOSnhmFIQKDca", + "type_args": [] } }, { "vector": { "struct": { - "address": "ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e78", - "module": "wzkpUTOnbJbeDbwPNiaHyqxVjTfrR2", - "name": "GngSehrhNLMtXmUGfvQ", + "address": "6fd2f83b882f8719db44e39dd735c3e0016017e667b2a7eee24656984cdeac42", + "module": "PDzMdzglNjXVMlfCSuGYPqXdMUD8", + "name": "wNJB", "type_args": [] } } - } - ], - "args": [ - { - "Address": "49d7daf6cf3f60defb822cdb3ebcaaedc3e703ddcffd0240482e68c2b809738f" }, { - "U64": "15184151781367649819" + "struct": { + "address": "4859c5c2661b58eff7ea25cd488075c5a1ee7c205be0ae24ca26eb0c9993a69d", + "module": "vturrZDOSQxSKc4", + "name": "HFoqbhQcTOLHUosyPtBkeAAnv8", + "type_args": [] + } }, { - "U64": "15632735920676928943" + "struct": { + "address": "e96478e91826d1417d9eed694b479585d15e7509a2a20f352e99423d84022a16", + "module": "lGtwrJ0", + "name": "fUewPcSOLbpHrzEHg", + "type_args": [] + } }, { - "U64": "11991635335206315829" + "vector": { + "vector": "u128" + } + } + ], + "args": [ + { + "U128": "118372847108559400719492021265429286852" }, { - "U8Vector": "61e071b895c703af3a9e" + "U8Vector": "6e" }, { - "Address": "cb93021d3aa8be2e3df32bc0fea68994d29ec5ce15059fddc9b7daec204561ff" + "U128": "21458443027750733995186292840990338962" }, { - "U64": "17286979860819331334" + "U64": "13026082275583392372" }, { - "Bool": false + "U64": "14174837382319505091" }, { - "U64": "6308942936716947076" + "U128": "68442354932695970041146911119044597488" }, { - "U64": "7475543113224185616" + "U128": "2360618083786172535065555526279216460" } ] } }, - "max_gas_amount": "12571397295076794938", - "gas_unit_price": "7557422626387433805", - "expiration_timestamp_secs": "1864149713697490987", - "chain_id": 210 + "max_gas_amount": "15783062434960069755", + "gas_unit_price": "3231898998924662970", + "expiration_timestamp_secs": "4365332986977757373", + "chain_id": 32 }, - "signed_txn_bcs": "b615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6dd40d4133eee4bacc870251000c3c0d88a48ec0e1bfc0dc0936030606075676ad8838a31b2c93550d3b9e34484843ed652a5be2a36dae7629cfae4da90c06454b667352791e5443726950447263756d6b5053666470716d72524b6458565a4d4e77453400060606000607ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e781e777a6b7055544f6e624a6265446277504e696148797178566a546672523213476e6753656872684e4c4d74586d5547667651000a0349d7daf6cf3f60defb822cdb3ebcaaedc3e703ddcffd0240482e68c2b809738f011b96089898f1b8d201affd6f7b7ea2f2d80135a7fe8ecdd86aa6040a61e071b895c703af3a9e03cb93021d3aa8be2e3df32bc0fea68994d29ec5ce15059fddc9b7daec204561ff0106c977d397b0e7ef050001842e39bb2cde8d57011067d8b6da76be673ae25bd73b9376ae4d995277d65be1682bc815b549cade19d2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404a0fef4d1deaf6461b86d0deab6655f9c1f445c4c453198ecca99d3068287dd82ad90963c9789c205727873b7d32826852b5ffeb019f66b5f8b869cdbb911900", + "signed_txn_bcs": "c85186271e150dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b7753411a709f6b017d0009f61d5deb3d3a4cee2407075b743ad3a9a964703db5bcd8923f1a9680fc7285f7eaa0670980bb3a6095d0c0146868527855526e7a6c4b69547656734846765534094579564b4d686242560007610b0d3fd1f4066c47cb2b2de32e0884ec455e6f4785bce0a7897a06f2ae393518797662457379734f65714c477562576a7141596169474c351d4473786f6f4a694e656f757650486176617242674b54684c6c6d45636100071d61afa6a3d12d1aaf8edc78fc906572c28849c38914332a9946d6a5d1c9fca4166b7a716d56676e6f506f68635475794d4e465a5448371674517a5245786d7667594f536e686d4649514b4463610006076fd2f83b882f8719db44e39dd735c3e0016017e667b2a7eee24656984cdeac421c50447a4d647a676c4e6a58564d6c664353754759507158644d55443804774e4a4200074859c5c2661b58eff7ea25cd488075c5a1ee7c205be0ae24ca26eb0c9993a69d0f76747572725a444f535178534b63341a48466f7162685163544f4c48556f73795074426b6541416e76380007e96478e91826d1417d9eed694b479585d15e7509a2a20f352e99423d84022a16076c477477724a3011665565775063534f4c627048727a454867000606030702c4cfb51601054f6b510ea82df5c70d5904016e02926f3903570bc573151901aaecbe24100174fa2883d0f0c5b401c3fe146a7f23b7c402f05679f8b24553660e302715a1847d33024cbd6bd0d1d957a32700661875a3c6017b549b8fa9b308dbba58d8240403da2cbda81a1f39c7943c20002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403dd689902d1abc96ac1a205a9157f441013f170424473607e984f96a6cefa29cb16aef8d85a040d8738f6078ccb2479921292b24385d228aba2e42da80fa4d01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d20716d9d7f808c6088d116727cb3f9c65f7c62857e9ce1a3887af299ac36591", - "sequence_number": "15405229642529301844", + "sender": "0147bb288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047", + "sequence_number": "15252492502399378930", "payload": { "Script": { - "code": "d7bbdfc1783cc3da", + "code": "f3aedf9d4df710ebf259b13cb8c4c3", "ty_args": [ { - "vector": { - "vector": { - "vector": "u8" - } + "struct": { + "address": "7eae77bcc63d8168d3a0ca378f687baa3c3cd7bd11f9c3b01d921f99d8497875", + "module": "lYWcELGPwsLhoWDHWtAydc0", + "name": "gHwsxrgVfpqakecKfKSaIPo", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66e393b4a7a1", - "module": "EHayJadNGZBmyvnpqmUKKOmDEliX2", - "name": "JXMXofsFBbOmOLFs9", - "type_args": [] - } + "struct": { + "address": "5801c7ff9ed37b121259c09a6a133ba4570ea06d763639bb481440da7f0e80da", + "module": "qRWLrsQQzzykOUqVnvkdyXlQmsYvWT", + "name": "NrxpAOtQAvKioLl", + "type_args": [] + } + }, + { + "struct": { + "address": "f4b49a2684d4acf72151905715970573db51b2bf33f59eaaba5bc0aa8f394119", + "module": "SvOWVkNjGqJAFwJLMMXqTjMHhsCSwW1", + "name": "CnVSY5", + "type_args": [] } } ], "args": [ { - "U8": 0 + "Bool": true + }, + { + "U128": "121528544243717186204597139324948943328" }, { - "U64": "7464551970126444647" + "U64": "5305951097543336481" + }, + { + "U8": 54 + }, + { + "U64": "13184475694240485098" + }, + { + "U8": 42 } ] } }, - "max_gas_amount": "15911564735358519201", - "gas_unit_price": "5059319936941745829", - "expiration_timestamp_secs": "15501906556986466005", - "chain_id": 108 + "max_gas_amount": "17934905217570785534", + "gas_unit_price": "10417178966175803834", + "expiration_timestamp_secs": "12882391350330850198", + "chain_id": 30 }, - "signed_txn_bcs": "d20716d9d7f808c6088d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154e5464ebd5ecad50008d7bbdfc1783cc3da02060606010607ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66e393b4a7a11d454861794a61644e475a426d79766e70716d554b4b4f6d44456c695832114a584d586f66734642624f6d4f4c46733900020000016738d4ca776a9767a147addfd23bd1dca5e6765ead503646d51e7a86e1d521d76c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400150e63d43fe69f4bbd534460cbf5390843c4ecdf0cd9e9a62ab5ed5ec14329a735270fec3c026da87d60d0b5fc538be81f154b91fa23049c281ec195a23430e", + "signed_txn_bcs": "0147bb288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f2e5d2a81ebdabd3000ff3aedf9d4df710ebf259b13cb8c4c303077eae77bcc63d8168d3a0ca378f687baa3c3cd7bd11f9c3b01d921f99d8497875176c595763454c475077734c686f57444857744179646330176748777378726756667071616b65634b664b536149506f00075801c7ff9ed37b121259c09a6a133ba4570ea06d763639bb481440da7f0e80da1e7152574c727351517a7a796b4f5571566e766b6479586c516d73597657540f4e727870414f745141764b696f4c6c0007f4b49a2684d4acf72151905715970573db51b2bf33f59eaaba5bc0aa8f3941191f53764f57566b4e6a47714a4146774a4c4d4d5871546a4d486873435377573106436e565359350006050102e091efa94e8404471eb5b3c1d68b6d5b012122aa3c6986a249003601eacef920caaaf8b6002afe489bad4595e5f8ba6994c01341919096fb08e6ad72c7b21e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444075bd8966ddc98a0f6c75f583b2a9d1f99a2e2f196f1ba82810751d6be38452d242a1409280ec3bb045b2c409561a04d979ae8109f0303665153f14ee3e72cc0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "18e7979c691c519b4a74ce0d3bd524299c382182c23d00ec3f6a19e1d370d85e", - "sequence_number": "4362907959864234135", + "sender": "45cceac62a473dcab06238ac17c2557d46faea4df748ffe7484c5ddb343806f0", + "sequence_number": "6118075719813831122", "payload": { "Script": { - "code": "d8a6cad3", + "code": "11eb", "ty_args": [ { - "struct": { - "address": "610cd183e2c4d54352ffc06f614b48f372913d4c8c65161b174d33f965f0f580", - "module": "E2", - "name": "EbIzWaRLFoXkBxZ5", - "type_args": [] + "vector": { + "vector": "bool" } }, { "vector": { - "vector": "address" + "vector": { + "struct": { + "address": "c5294e55ae70a7e6221772d0cce62e803a24ba844f070cba8c3a643adf9ff16e", + "module": "qVuGjFGgFEij", + "name": "cuMS6", + "type_args": [] + } + } } }, { "struct": { - "address": "69f03134932c7a20173b356f8cae864dd5a648c1c5ee64db10e006f6cb4ad11c", - "module": "qxTTkNHkxKSIBk8", - "name": "dtcUmN3", + "address": "70d15cf5bc798916d754b3dfac986d023ea7a4f7a5d5e8a29060762230f10f26", + "module": "kbqoUXH6", + "name": "oqexLOksCIPsbNPmAB2", "type_args": [] } }, { "struct": { - "address": "d282c1fb69662432e03b6db45fb6bc7062e181874468c0f173fc51e22e0450a1", - "module": "FinNXBvkRFrWwZvEiwAH6", - "name": "oodrwDjAuogpknElOhILIQ0", + "address": "3b6f554cd81b5aeaeb871f8cdad1b1ebd1ea5574ea88f9db6f0a1783eec05cab", + "module": "vIhsDahTOiJhjHbRorweZZuTHa3", + "name": "DfkURGhxXUZYrZYErowTZVrm3", "type_args": [] } + } + ], + "args": [ + { + "U128": "214108435312937267759021862276698029454" }, { - "struct": { - "address": "53832e11a4c1d922c3febf5cf4a6412bb7ee90844aa35287448fdb798350fc4b", - "module": "iJBXOSOuzozUbOUbkVDn6", - "name": "zBWHOwH", - "type_args": [] - } + "U8": 36 }, + { + "U64": "7110860009704152941" + }, + { + "U8": 230 + }, + { + "U8": 203 + }, + { + "Bool": true + } + ] + } + }, + "max_gas_amount": "6076078913143743136", + "gas_unit_price": "2197487445196182763", + "expiration_timestamp_secs": "9166162987362567251", + "chain_id": 163 + }, + "signed_txn_bcs": "45cceac62a473dcab06238ac17c2557d46faea4df748ffe7484c5ddb343806f0d21972c473c5e754000211eb04060600060607c5294e55ae70a7e6221772d0cce62e803a24ba844f070cba8c3a643adf9ff16e0c715675476a4647674645696a0563754d5336000770d15cf5bc798916d754b3dfac986d023ea7a4f7a5d5e8a29060762230f10f26086b62716f55584836136f7165784c4f6b7343495073624e506d41423200073b6f554cd81b5aeaeb871f8cdad1b1ebd1ea5574ea88f9db6f0a1783eec05cab1b76496873446168544f694a686a4862526f7277655a5a75544861331944666b555247687858555a59725a5945726f77545a56726d330006028e3ded374498655835c0ed8ae1c813a10024016d5ff2fd80d9ae6200e600cb0501a0a22c3d94915254eb944c49300b7f1e5344142facc0347fa3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444030b018088eaec9f825b17253fda532a880137d691d87d63ce59a6884541a0b9f717657b0ed1833f61e677b302d513c3ecd19a12e648fa5bf68858f737b962b0b", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "024612fed776ac4b9b3d1183e42bcaeb6e142b0e8a9c18cf3e74b7c644d007f2", + "sequence_number": "11058167725027665747", + "payload": { + "Script": { + "code": "9b63", + "ty_args": [ { "vector": { "struct": { - "address": "566544163696f3543a02d49bb4da0c47a1b32ea7fb982cebaeb5ea179dace470", - "module": "YlhuymArhMAZWDRAbSLYPHhBTux5", - "name": "IRQDayvBDSoPyTCbXyqdIY", + "address": "f4b4f567dfcc3affcec015e52b4cda2ff7762d29c6ed0545a2a808d166f37276", + "module": "PyzwxznUXXygmMOL5", + "name": "NbswNdhwNhRSWrbOPfNJSeQQnRo2", "type_args": [] } } @@ -3878,9 +4137,9 @@ { "vector": { "struct": { - "address": "b54465f5cbaefbae3117df4f9edbb2f99039c919af9bdd8e5c621b2fb1292ed3", - "module": "litO", - "name": "uJEiNvLgpQzUMMdIMfz", + "address": "811dcb065a2be9eee32bc911b254a53ca4bcb55cefda940e6629a37662f1db36", + "module": "SecjHWcpfdqadohTsJabASiGsglm", + "name": "powFnYaWLVtkdGxzqhMUYpiADqUP", "type_args": [] } } @@ -3888,205 +4147,299 @@ { "vector": { "struct": { - "address": "d820541f8f7e124120250c327fed390fe57dc099302e20f167ece61dc55e2057", - "module": "cmPHPYwWKscx", - "name": "qUAypgGvIkdYWczqwM", + "address": "31cc079679423bc49322a21ee60c275499dd0b7bc50e47674680a109402988bb", + "module": "PnuuADrxcQqCTtOJ3", + "name": "bLmeRbuOKCUXtOdEXwdWNVXJTfDqxoun", "type_args": [] } } }, { - "struct": { - "address": "8904f71b7567e980d6d944dde4339b639399a487243b17821e2bcf1300c76dbc", - "module": "Kznx1", - "name": "zJBJmGHBxTYwjXSfbAvXipjHTcZ5", - "type_args": [] + "vector": { + "struct": { + "address": "718ee7b87ba8f334ee9d96ef9aa7b0e76ead5c5c0d44a1b1abe493b3e3502bd7", + "module": "ATmJCQvOISCfO", + "name": "zyoWNgvMNWiEwdMQrXYBAYiReCcKzst9", + "type_args": [] + } } } ], "args": [ { - "U64": "3687411726281348093" + "U8": 68 }, { - "Bool": false + "U64": "13676000934817443644" + }, + { + "U128": "40310899289190009276175955026044235859" + }, + { + "U128": "148899498661687295357316993543427667006" + }, + { + "Bool": true } ] } }, - "max_gas_amount": "14120676573151442337", - "gas_unit_price": "8947925908516791181", - "expiration_timestamp_secs": "1773433781802022082", - "chain_id": 35 + "max_gas_amount": "11312876955957371312", + "gas_unit_price": "8418976261203799233", + "expiration_timestamp_secs": "12144148242640435391", + "chain_id": 167 }, - "signed_txn_bcs": "18e7979c691c519b4a74ce0d3bd524299c382182c23d00ec3f6a19e1d370d85e97906e7fac298c3c0004d8a6cad30907610cd183e2c4d54352ffc06f614b48f372913d4c8c65161b174d33f965f0f580024532104562497a5761524c466f586b42785a35000606040769f03134932c7a20173b356f8cae864dd5a648c1c5ee64db10e006f6cb4ad11c0f717854546b4e486b784b5349426b3807647463556d4e330007d282c1fb69662432e03b6db45fb6bc7062e181874468c0f173fc51e22e0450a11546696e4e5842766b52467257775a76456977414836176f6f647277446a41756f67706b6e456c4f68494c495130000753832e11a4c1d922c3febf5cf4a6412bb7ee90844aa35287448fdb798350fc4b15694a42584f534f757a6f7a55624f55626b56446e36077a4257484f7748000607566544163696f3543a02d49bb4da0c47a1b32ea7fb982cebaeb5ea179dace4701c596c6875796d4172684d415a5744524162534c59504868425475783516495251446179764244536f5079544362587971644959000607b54465f5cbaefbae3117df4f9edbb2f99039c919af9bdd8e5c621b2fb1292ed3046c69744f13754a45694e764c6770517a554d4d64494d667a000607d820541f8f7e124120250c327fed390fe57dc099302e20f167ece61dc55e20570c636d5048505977574b736378127155417970674776496b645957637a71774d00078904f71b7567e980d6d944dde4339b639399a487243b17821e2bcf1300c76dbc054b7a6e78311c7a4a424a6d474842785459776a5853666241765869706a4854635a35000201fd139ca56d512c330500a135df5a87b8f6c38d63a8a5346b2d7cc2b4fce4a0809c1823002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444081e9ddd7000c9d02ca6551e249a4993c29042094570172db55d339277a5ac4eca931f163d5ba2d8381200263310acf6ee484c394cb1ecb5b78dfe43ad4f1880c", + "signed_txn_bcs": "024612fed776ac4b9b3d1183e42bcaeb6e142b0e8a9c18cf3e74b7c644d007f253a7f60cf580769900029b63040607f4b4f567dfcc3affcec015e52b4cda2ff7762d29c6ed0545a2a808d166f372761150797a77787a6e55585879676d4d4f4c351c4e6273774e6468774e6852535772624f50664e4a536551516e526f32000607811dcb065a2be9eee32bc911b254a53ca4bcb55cefda940e6629a37662f1db361c5365636a4857637066647161646f6854734a61624153694773676c6d1c706f77466e5961574c56746b6447787a71684d55597069414471555000060731cc079679423bc49322a21ee60c275499dd0b7bc50e47674680a109402988bb11506e7575414472786351714354744f4a3320624c6d655262754f4b435558744f6445587764574e56584a54664471786f756e000607718ee7b87ba8f334ee9d96ef9aa7b0e76ead5c5c0d44a1b1abe493b3e3502bd70d41546d4a4351764f495343664f207a796f574e67764d4e57694577644d5172585942415969526543634b7a73743900050044013c2fb44364eacabd0253b03f6929a73e158a99830ec898531e023e34ed4f83c1b0a5b138c5d1140005700501b0a18a3ba769ff9cc1ac7fcd4d36d674bf7844f67bae88a8a7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444087d61aa31f282534aaf498aacd2b0bf8704c7495a6b041e7d62a9c9947f9e4585557cb2a8f8e0bfaf9ffbe6076a8f63b92140747fe803f91c30712022f74d70d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "44222ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824", - "sequence_number": "283426149573850337", + "sender": "3a5950e423a8f6e4e1753ae07ffe7d5dfcddfe3ad965ef6c055d4f32f9961bcb", + "sequence_number": "7532924430507795912", "payload": { "Script": { - "code": "c887e314cb5ad003e5d67bdbcc", + "code": "a5de", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "9595889026010961157", + "gas_unit_price": "9852539364742002166", + "expiration_timestamp_secs": "5507062235127362974", + "chain_id": 232 + }, + "signed_txn_bcs": "3a5950e423a8f6e4e1753ae07ffe7d5dfcddfe3ad965ef6c055d4f32f9961bcbc86547c0db528a680002a5de000005d5735b3a722b85f6f5ffea5940bb889e35bcd8ec036d4ce8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403d0c20d30fbd1eba5b6361de23f20bdb776932e967c1193092b65e8b35bcf7025cbcf14c25b03b3b41ef569e4e4dec8a6e54d329c15c2412de1a63561ac98d08", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "4579ae923262e0410b6f3f8a271d8ac1905230c2050059cc25a3cc1790476616", + "sequence_number": "16976452507296608360", + "payload": { + "Script": { + "code": "450c4bfdb21fa26f", "ty_args": [ { - "struct": { - "address": "753f59cb62a5880149377fd49f45ee1a1f8d96af8575463f014b6b312d505dad", - "module": "AadcbPaPFtQItBmKdOrJDgcXWu0", - "name": "lQrsJfVrPjDsw", - "type_args": [] + "vector": { + "struct": { + "address": "0a052634bce17b953273ec15475397ba9428ed61d3473708fa2f282d88d157bd", + "module": "YRTl", + "name": "AnZoihoJapjFKZPCExXAu7", + "type_args": [] + } } }, { "struct": { - "address": "613528f7ffc05353db4b055b0a0d23c38f5dabbcf49b9d4aab209027dd38de64", - "module": "wOvKLAavjblSoPumHYOKVcWOYoVhSDU", - "name": "MUUApEJUGSiLplAdjYfyRYzFVVw", + "address": "356786e68ed618ac575632846940c9351bc855deb6f95aae6166aaec08f3b925", + "module": "KuPMTIjhElVBQZJiAQPqmnNysEkPfz", + "name": "JaafSY1", "type_args": [] } + } + ], + "args": [ + { + "U128": "104046641615441813557234973536285860546" }, { - "struct": { - "address": "c30e93df9d6ca3211e4da05b1229a39d7cf4a507bf37172c25b34c392dc2426c", - "module": "JLEcUKwlE", - "name": "VJtugYcvxvvAp", - "type_args": [] - } + "Bool": true }, + { + "U64": "14382015018320333836" + } + ] + } + }, + "max_gas_amount": "10997993042044025262", + "gas_unit_price": "13574570577267536110", + "expiration_timestamp_secs": "6019553334104423048", + "chain_id": 87 + }, + "signed_txn_bcs": "4579ae923262e0410b6f3f8a271d8ac1905230c2050059cc25a3cc17904766166830b43b9c7998eb0008450c4bfdb21fa26f0206070a052634bce17b953273ec15475397ba9428ed61d3473708fa2f282d88d157bd045952546c16416e5a6f69686f4a61706a464b5a50434578584175370007356786e68ed618ac575632846940c9351bc855deb6f95aae6166aaec08f3b9251e4b75504d54496a68456c5642515a4a69415150716d6e4e7973456b50667a074a616166535931000302c2a2a3d9f8f60e5012804a3d7ea7464e0501010c0c51c1752e97c7ae7940e166b8a098ee3080d4049062bc88facf49ddbf895357002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ca6bdcab9bbbbee044627b5a3a768b3e844e6b8e0c42674471b82e97575653bd72b1e3f4f7061822ecb3fd46d5b1457a96de8d4bdf097fe1de98aead9a85b404", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "81cfc7eaa52fd59eda217417cf11c5a504e069186fd12e90619f5a913e96b250", + "sequence_number": "711278242712846207", + "payload": { + "Script": { + "code": "169e4cf20dc137d90f32ec7e", + "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "88dd8a250268408cfc4472167d91d41fbaa554fc07ebf675e1bf8e1a56933e70", - "module": "sHaRy8", - "name": "PymterSuABYUrVvROqhyzBBVwEZE1", - "type_args": [] - } - } + "vector": "u64" } }, { "vector": { "struct": { - "address": "8067864a2daa34ee5aeb0ee8c4a0d404990ebe852ca863d2816f121e126355d9", - "module": "lUMWgYpnBOodt", - "name": "YMVwKeinECCCEEVrdccGTon9", + "address": "25bf0d45b18a42d3243c94c090fbac661ffa2e5e04516d2e134d40a0dd3fb2a2", + "module": "hqgRtTyrpCCjc4", + "name": "kqANPrwaVPnnzMpXeyAdpF9", "type_args": [] } } }, { "struct": { - "address": "228d8ff01f52a2206ba80489952945a3d00a1ba0cc39bb57918fab2b21b0cb5f", - "module": "VvdiuNifYOroQIlpRfGXMcnQN0", - "name": "kCSJ7", + "address": "198306e869e0fcc10918627b9018694da21fe2194d0a45150a40516543b73270", + "module": "fSbrMgMcBU", + "name": "jKgooCsmxAxYf6", "type_args": [] } }, { "struct": { - "address": "44ed43b73682171092fa2b9a5e5a2fd79bf1a7461735ece8e5fe752460b09955", - "module": "VmKsnhrcVWiVViQUFSxDui", - "name": "v0", + "address": "47a40e611cad85d89bf849340b41df21d1d19231500d5b4453f205b531e03c2b", + "module": "KmnAmiOobbnDvnWykBUCkG6", + "name": "TzRKKrZipVeA", "type_args": [] } }, { "struct": { - "address": "a73fa612e44b298bd5c5231a8db9927f47d259361c4b3480bc9b8ec5f8a990af", - "module": "SryFIckVxCSLMd6", - "name": "MRNfQhRfmOllFOVBmHWxG", + "address": "f103cb3f53b7b978ea5c88d526be57be593721f1a63b5841db5a87bd9de9a77d", + "module": "ajRpCVa", + "name": "tSTbwqOTNNHWZfdeHZmy", "type_args": [] } }, { "struct": { - "address": "a14cd86e4541d90b5902d5864a21ae60811a18560aca58de0e829a9ad8fe71be", - "module": "RYGxsPEWkmwZkobOUvgTxinccoGKstf3", - "name": "BE8", + "address": "64a55ab954875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31", + "module": "FxUYAjDbqTvkhVnYbcV1", + "name": "ZqAtOSxlwhEdFWTCIFBc", "type_args": [] } + }, + { + "vector": "address" } ], + "args": [ + { + "Address": "de4fd609ed3ed41cab3d3d32701685781b7eff676a958414a9ed7b73e1a18f33" + }, + { + "U8Vector": "26faefccc6daf30e0ffdfed1" + }, + { + "Bool": true + }, + { + "Address": "c7ede605da94bd1a67c228bebc312eb6f89dad1cf74afab545df2802b034bdfd" + }, + { + "U8": 165 + } + ] + } + }, + "max_gas_amount": "7606180589862811393", + "gas_unit_price": "10059064723437699714", + "expiration_timestamp_secs": "14776157625751617020", + "chain_id": 154 + }, + "signed_txn_bcs": "81cfc7eaa52fd59eda217417cf11c5a504e069186fd12e90619f5a913e96b2507fff5c11cbf7de09000c169e4cf20dc137d90f32ec7e07060602060725bf0d45b18a42d3243c94c090fbac661ffa2e5e04516d2e134d40a0dd3fb2a20e68716752745479727043436a6334176b71414e5072776156506e6e7a4d7058657941647046390007198306e869e0fcc10918627b9018694da21fe2194d0a45150a40516543b732700a665362724d674d6342550e6a4b676f6f43736d784178596636000747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f205b531e03c2b174b6d6e416d694f6f62626e44766e57796b4255436b47360c547a524b4b725a69705665410007f103cb3f53b7b978ea5c88d526be57be593721f1a63b5841db5a87bd9de9a77d07616a5270435661147453546277714f544e4e48575a666465485a6d79000764a55ab954875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a311446785559416a44627154766b68566e5962635631145a7141744f53786c7768456446575443494642630006040503de4fd609ed3ed41cab3d3d32701685781b7eff676a958414a9ed7b73e1a18f33040c26faefccc6daf30e0ffdfed1050103c7ede605da94bd1a67c228bebc312eb6f89dad1cf74afab545df2802b034bdfd00a501773e7cf2948e6982c22a1d12fa988bfcbd1abc12750fcd9a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440989a3f3f41e5f454d3e123ebd45a2c9c135973e00915c32d465f122bdc23ad289a3153d03c06f98badfa3cb57eb46ba324345236474d4325cfdd0c3df0dd9004", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a46a6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b852821", + "sequence_number": "13425116749930332988", + "payload": { + "Script": { + "code": "64", + "ty_args": [], "args": [] } }, - "max_gas_amount": "14430727083845081031", - "gas_unit_price": "7556689492896447026", - "expiration_timestamp_secs": "6142095777508616633", - "chain_id": 242 + "max_gas_amount": "7114375590957426350", + "gas_unit_price": "2403789431177497853", + "expiration_timestamp_secs": "4844760987894299668", + "chain_id": 127 }, - "signed_txn_bcs": "44222ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e1f467d594eeee03000dc887e314cb5ad003e5d67bdbcc0907753f59cb62a5880149377fd49f45ee1a1f8d96af8575463f014b6b312d505dad1b41616463625061504674514974426d4b644f724a446763585775300d6c5172734a665672506a4473770007613528f7ffc05353db4b055b0a0d23c38f5dabbcf49b9d4aab209027dd38de641f774f764b4c4161766a626c536f50756d48594f4b5663574f596f56685344551b4d55554170454a554753694c706c41646a59667952597a465656770007c30e93df9d6ca3211e4da05b1229a39d7cf4a507bf37172c25b34c392dc2426c094a4c4563554b776c450d564a74756759637678767641700006060788dd8a250268408cfc4472167d91d41fbaa554fc07ebf675e1bf8e1a56933e70067348615279381d50796d746572537541425955725676524f7168797a42425677455a45310006078067864a2daa34ee5aeb0ee8c4a0d404990ebe852ca863d2816f121e126355d90d6c554d576759706e424f6f647418594d56774b65696e454343434545567264636347546f6e390007228d8ff01f52a2206ba80489952945a3d00a1ba0cc39bb57918fab2b21b0cb5f1a56766469754e6966594f726f51496c70526647584d636e514e30056b43534a37000744ed43b73682171092fa2b9a5e5a2fd79bf1a7461735ece8e5fe752460b0995516566d4b736e68726356576956566951554653784475690276300007a73fa612e44b298bd5c5231a8db9927f47d259361c4b3480bc9b8ec5f8a990af0f5372794649636b567843534c4d6436154d524e66516852666d4f6c6c464f56426d485778470007a14cd86e4541d90b5902d5864a21ae60811a18560aca58de0e829a9ad8fe71be2052594778735045576b6d775a6b6f624f5576675478696e63636f474b73746633034245380000c7d73153d33d44c832fa04860ec1de68b9e9d342911b3d55f2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b147ea5773d5ee90ccb09ca0715adf07bc67a646b90477bf17bfdf410de8c90ef04e60f3d2ba91598e9964d20d1aff3d6125f0c11d01102dc661b6c77f182f0b", + "signed_txn_bcs": "a46a6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c83be038e984fba0001640000ae26ba09e856bb62fd4c2c78c0f95b21143c1c29730c3c437f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea788ab0fb659cdda200cdce311c228ae10baa46909ff1e89d9378faeb05e3c407a64f37a83f72e6cde646f8c0afff951c9fa9bd6d33fccbefe184601a36ee06", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4aa7b8854e9e9c510f0586aade10554ebaf87fec1f5d3a1b28b96b89cb829355", - "sequence_number": "1450217912299015648", + "sender": "3d805897cbbf59173aeb2d936e00728a72c441b3c879ba2387cd0a42d23bcb85", + "sequence_number": "3746467104349212564", "payload": { "Script": { - "code": "b4", + "code": "b7aa029e34ee0e6d49f8c7ec8c", "ty_args": [ { "struct": { - "address": "87262487e5b93d502885c2cf3a9b5592b1941ce8c6a8aa14bfe312daa2512e66", - "module": "RyXIbYDcfhp8", - "name": "bJQBOYlZYOjIWeQNi8", + "address": "4132ac9dc2980dc332e2fe1b331739aebb04e99c6fd8172ae043c0b36db51c55", + "module": "pyVWutFGzdUtqyBNRKxDGdYWmcRh", + "name": "zdflNrWd9", "type_args": [] } }, { - "struct": { - "address": "45e6de8b55b4a9fef01ab392a015a73edf0fc211ccac66e996f6f52d286d049d", - "module": "gMkfjhLPRvbuJZxYFzzohBqe1", - "name": "OhAhMvolTIAyoPtInGFMQw", - "type_args": [] + "vector": "signer" + }, + { + "vector": { + "struct": { + "address": "3457e80850406e524ceb354d1dfa8595139bec8a4739de232706528c13a53387", + "module": "hQunQI8", + "name": "aPhmC", + "type_args": [] + } } }, { "struct": { - "address": "d18a5e0d803170b7738b064796ef10f7d745b86b6f9c230fd4b9f386ebe06c0a", - "module": "AehCzDfyCKk", - "name": "UpZMGf6", + "address": "0ef16609bdd1d0aaba7ee85708fd62aceeed466825f2034070d74954b93f8777", + "module": "rUgSK", + "name": "LKFsXYBaRvvVVztOizPRRtykcGYeVZJA", "type_args": [] } }, { "struct": { - "address": "38758fe0d002df8f457a41e4f51efd906a78b101ec45005dc1b1e7e3bdb51060", - "module": "kdsdHgOFrH3", - "name": "mGXnTbEYYdTuVugsTbfykfvoGmDQb", + "address": "1826f9e1574059792e75c6f40be4357802412309240c3107eebb42010e521729", + "module": "oIECFWJfmJydYJCLjGXFxHWtKcCI", + "name": "qVRfIuAVtZcnmEsH6", "type_args": [] } }, { - "struct": { - "address": "9bb23cb0683f1f0b36b3d3322906c1a276ccd1576d8e206739f9e65c823e0f6c", - "module": "DmHc", - "name": "cHEASgyNWFstPRtgDFoEjPdTEVSYKKZ", - "type_args": [] + "vector": { + "struct": { + "address": "d532214513d5ff89e969539127d42beb9a8aa4e389f75ed5b41dc628c2892dac", + "module": "JBJn3", + "name": "hoqApLntVxQv", + "type_args": [] + } } }, { "struct": { - "address": "2ee2064f1e615717bed69460b84349d17adc7b66ca5c45cd9d7d40b45c6398ef", - "module": "vnjep", - "name": "ZxfVzlbjojltjt", + "address": "42cf66bc7ecca3f98bc85d2a75a81fd14dbe96db07a5a57f53b781a94ec0906d", + "module": "AeMxQWFyz", + "name": "nwmByQRzyJlIRJKQOWdxi", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + }, { "vector": "u128" }, { "vector": { "vector": { - "struct": { - "address": "24ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f95", - "module": "duNcJjBHgAHkdXewauVAYtUKbtA7", - "name": "IrLfksNXACbOWzPVXSLZCPtViTQljsMy", - "type_args": [] + "vector": { + "vector": "u8" } } } @@ -4094,600 +4447,678 @@ ], "args": [ { - "U8Vector": "7992cd65e825e9ea24263b" - }, - { - "U8Vector": "5dcdbaf47dfa2bae0bad894b" - }, - { - "Bool": true - }, - { - "U8": 170 - }, - { - "U8Vector": "c05e" + "U64": "14643706405178757101" }, { - "U8Vector": "ae4a9317afda4ece3eddd8fcaf3e4e9d" - }, - { - "U64": "8242106911441398398" - }, - { - "U64": "9229237050746261132" - }, - { - "Bool": true - }, - { - "U64": "1017682496720226605" + "Bool": false } ] } }, - "max_gas_amount": "16967000839206206196", - "gas_unit_price": "8760237806306588359", - "expiration_timestamp_secs": "6671490437646032492", - "chain_id": 239 + "max_gas_amount": "5912313607436414234", + "gas_unit_price": "11783603220958470423", + "expiration_timestamp_secs": "6999602012720126811", + "chain_id": 235 }, - "signed_txn_bcs": "4aa7b8854e9e9c510f0586aade10554ebaf87fec1f5d3a1b28b96b89cb829355e0cd7df5813520140001b4080787262487e5b93d502885c2cf3a9b5592b1941ce8c6a8aa14bfe312daa2512e660c52795849625944636668703812624a51424f596c5a594f6a495765514e6938000745e6de8b55b4a9fef01ab392a015a73edf0fc211ccac66e996f6f52d286d049d19674d6b666a684c50527662754a5a7859467a7a6f6842716531164f6841684d766f6c544941796f5074496e47464d51770007d18a5e0d803170b7738b064796ef10f7d745b86b6f9c230fd4b9f386ebe06c0a0b416568437a446679434b6b0755705a4d476636000738758fe0d002df8f457a41e4f51efd906a78b101ec45005dc1b1e7e3bdb510600b6b64736448674f467248331d6d47586e546245595964547556756773546266796b66766f476d44516200079bb23cb0683f1f0b36b3d3322906c1a276ccd1576d8e206739f9e65c823e0f6c04446d48631f634845415367794e574673745052746744466f456a506454455653594b4b5a00072ee2064f1e615717bed69460b84349d17adc7b66ca5c45cd9d7d40b45c6398ef05766e6a65700e5a7866567a6c626a6f6a6c746a7400060306060724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f951c64754e634a6a42486741486b64586577617556415974554b627441372049724c666b734e584143624f577a505658534c5a435074566954516c6a734d79000a040b7992cd65e825e9ea24263b040c5dcdbaf47dfa2bae0bad894b050100aa0402c05e0410ae4a9317afda4ece3eddd8fcaf3e4e9d017eaa414191d86172018cce9af532d614800501012d4924bfd6881f0ef4faa3445ee576ebc7f6d900df9d92796c9e4eba34e5955cef002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401bf16e1c51eb6d3b4dae71dec29eeb511fb2826fbec9569fa605ff77e6e733658e829a035a3d1b719947d39e768e8d42b17fdaa7277aeda9f7bf53bf11d1560a", + "signed_txn_bcs": "3d805897cbbf59173aeb2d936e00728a72c441b3c879ba2387cd0a42d23bcb8594cf6b55fb1ffe33000db7aa029e34ee0e6d49f8c7ec8c0a074132ac9dc2980dc332e2fe1b331739aebb04e99c6fd8172ae043c0b36db51c551c70795657757446477a6455747179424e524b7844476459576d635268097a64666c4e7257643900060506073457e80850406e524ceb354d1dfa8595139bec8a4739de232706528c13a53387076851756e514938056150686d4300070ef16609bdd1d0aaba7ee85708fd62aceeed466825f2034070d74954b93f877705725567534b204c4b46735859426152767656567a744f697a50525274796b63475965565a4a4100071826f9e1574059792e75c6f40be4357802412309240c3107eebb42010e5217291c6f49454346574a666d4a7964594a434c6a475846784857744b634349117156526649754156745a636e6d45734836000607d532214513d5ff89e969539127d42beb9a8aa4e389f75ed5b41dc628c2892dac054a424a6e330c686f7141704c6e7456785176000742cf66bc7ecca3f98bc85d2a75a81fd14dbe96db07a5a57f53b781a94ec0906d0941654d78515746797a156e776d427951527a794a6c49524a4b514f5764786900060600060306060606010201edcfcacb63e538cb05001aadf4b3e6c10c5217e1607fb2c487a35bdb4af1f1942361eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f7b2f5ecd3d484ad0c718dd8841312b4da92e7ec70c4996efd060b303bdab9847c90aa867a93a7d324a6620d26a810a14294248c80e06fa8c91082a771ea7c0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df01011641a3f", - "sequence_number": "9541883071816858300", + "sender": "ab4b5acae40a5b6613e3b6ff3850f424b28842f89325957cdda0d8080687e807", + "sequence_number": "12164948521843264589", "payload": { "Script": { - "code": "685f28ddeefd596aa279e67188ef", + "code": "f55a57", "ty_args": [ { "vector": { - "struct": { - "address": "3903b0ce42b03dbc1eec6f6e36a4d179be2081d124857fa907702f3e2be9feb4", - "module": "asEUHDWhRxmSSUpQjeqTSbMrZnlzqwF6", - "name": "y", - "type_args": [] - } + "vector": "signer" } }, { "vector": { "vector": { - "struct": { - "address": "0cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d619", - "module": "GM", - "name": "yKNbTAtXrLbaLeDryqFNsGNFQTJTrbgy2", - "type_args": [] - } + "vector": "bool" } } + }, + { + "struct": { + "address": "2db6932dfd073b2d6036ecea1d3e86ab301d976bb8e8d880cd91e407cf9f3a3e", + "module": "N6", + "name": "OrhTtdDQzycsanzVcaRIoJCEBjZ4", + "type_args": [] + } } ], "args": [ { - "U8Vector": "21adb535cfb0" + "Bool": false + }, + { + "Address": "de8d9be3bfcb042cd7796af690798d16012fd7ccc7dbae2037a7a6c34d9b2d7e" }, { - "U64": "2780841581946207986" + "U64": "15023193589304839973" }, { - "Address": "f30cad00aa2b1a0ad18f524b598a8523d56d1b65fd2f9a61b254e03e116ea56a" + "Bool": true }, { - "U8Vector": "beca63e9cfa8dc5c8efc6a0cf2ccb1f0" + "U8": 38 }, { - "U128": "192227257179974796427444501406979264718" + "U8": 215 }, { - "U64": "4433355884256655353" + "U128": "107441138282805897602104491545465274579" + }, + { + "U8": 173 + }, + { + "Bool": true } ] } }, - "max_gas_amount": "12959706881503430118", - "gas_unit_price": "9336195391619533489", - "expiration_timestamp_secs": "13582988879818119321", - "chain_id": 254 + "max_gas_amount": "2745873013984181297", + "gas_unit_price": "11444160966442979378", + "expiration_timestamp_secs": "17341343472857252680", + "chain_id": 107 }, - "signed_txn_bcs": "441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df01011641a3fbcfaf44719946b84000e685f28ddeefd596aa279e67188ef0206073903b0ce42b03dbc1eec6f6e36a4d179be2081d124857fa907702f3e2be9feb420617345554844576852786d53535570516a65715453624d725a6e6c7a717746360179000606070cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d61902474d21794b4e6254417458724c62614c6544727971464e73474e4651544a5472626779320006040621adb535cfb001f2fe896caf88972603f30cad00aa2b1a0ad18f524b598a8523d56d1b65fd2f9a61b254e03e116ea56a0410beca63e9cfa8dc5c8efc6a0cf2ccb1f002ce1075244e793b7e78f0dfb6819f9d9001f9770114b071863de68532c9be20dab3b10a1f4f3ed4908199d8a3a16b7880bcfe002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b817870bb734e3f9fc045bc4eafdd8ee4ce93d04950dbbab1af24eddae1761cfa1d3ab8f4cae41f2f944e34ecd01a6ed02bc266b062dc30c2356727edf3fdd0b", + "signed_txn_bcs": "ab4b5acae40a5b6613e3b6ff3850f424b28842f89325957cdda0d8080687e8074d8c615b3a94d2a80003f55a570306060506060600072db6932dfd073b2d6036ecea1d3e86ab301d976bb8e8d880cd91e407cf9f3a3e024e361c4f726854746444517a796373616e7a56636152496f4a4345426a5a340009050003de8d9be3bfcb042cd7796af690798d16012fd7ccc7dbae2037a7a6c34d9b2d7e0125cf7022f91a7dd00501002600d702d34045cecdf93b4931eff5a81969d45000ad050131bcdb3cf54c1b26329039e5c3d3d19e4803b29b02d4a8f06b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444086e6dbc320ca4daf14941d30b8c31655479c77b22586da9a17e611d9885061d8117e73788f2bbd49a17be0829c1047e302a5928640c741c40c6c305d93228202", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "61b8ddf45ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778", - "sequence_number": "3212491976351734433", + "sender": "989410a1c746118cbac9fa3715d2e55db51a306afaf629430c6c521429c8e461", + "sequence_number": "12558573004730147143", "payload": { "Script": { - "code": "ba0d", + "code": "7ddef6a0", "ty_args": [ + { + "struct": { + "address": "0046e75f00dd6f8d91e169399bae6ec0c7f636673b6bac61306b19a8434af339", + "module": "AJqcbVzMtnreJUPu7", + "name": "JEps", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "92b0f3db859899f0fa3800af6025e9302a6304699daf9991a909500300d6d5d0", - "module": "omAypCVPvaQA", - "name": "qqYIBBeHvTrUyyvkqfOjTySPBIF0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "85ba76b985c0e8d7136d50b9d6379dc181cbfd04ab55d6aa8faa8ff2be0632ed", + "module": "aLwPmX", + "name": "cwSlZRWWvKZICfFFytwIVgtCgwG", + "type_args": [] + } + } } } + }, + { + "vector": "u128" + }, + { + "struct": { + "address": "0fa5510d3969294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6", + "module": "tGicVGZVxtYsuQeLwIFyPRswnepjy", + "name": "AismbdviMnYRRBomQYjH", + "type_args": [] + } + }, + { + "struct": { + "address": "5b7edd8739ec790d7f4b19280e8e73298a20dc5ecabdcc3453990fc576159a45", + "module": "GrlYvXWpbFmqmEuXOcLXkSfxSWlELvG1", + "name": "GVlvYFUESIVyjskjzzMpmrXWgfy2", + "type_args": [] + } } ], "args": [ { - "U64": "142094399836878917" + "Address": "9f6c5d6d22e03d1ade727299588085a949dc743119e7ce3bd3b01df1f25c4bc2" + }, + { + "Bool": false + }, + { + "U8": 58 + }, + { + "U8": 233 + }, + { + "U128": "144238845553776560038062209844056854386" }, { - "U8": 80 + "Bool": true + }, + { + "Bool": true + }, + { + "Bool": false + }, + { + "Address": "598b457a8e064b814a78e43727c31df86c58f53337e2ad25492cb9b4f1f07c08" } ] } }, - "max_gas_amount": "13152095560504917519", - "gas_unit_price": "8194314105725481846", - "expiration_timestamp_secs": "3020176361718574651", - "chain_id": 169 + "max_gas_amount": "1297830983944135860", + "gas_unit_price": "6906583924764589407", + "expiration_timestamp_secs": "12970449795987964072", + "chain_id": 3 }, - "signed_txn_bcs": "61b8ddf45ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a1da3c966e10952c0002ba0d01060792b0f3db859899f0fa3800af6025e9302a6304699daf9991a909500300d6d5d00c6f6d417970435650766151411c7171594942426548765472557979766b71664f6a54795350424946300002014578d9921ad2f80100500f3ee3bf3aa185b67673bd89430db8713b6e443f66d2e929a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406fd25f678cb44b8197fd9754c99316493f058612329f5d26d0f2da570517f6b70c009952ffd23f63d1fa8718e1b59a181c51dbfe982b9fb416d76d26ef61710d", + "signed_txn_bcs": "989410a1c746118cbac9fa3715d2e55db51a306afaf629430c6c521429c8e4614721c0109c0349ae00047ddef6a005070046e75f00dd6f8d91e169399bae6ec0c7f636673b6bac61306b19a8434af33911414a716362567a4d746e72654a55507537044a457073000606060785ba76b985c0e8d7136d50b9d6379dc181cbfd04ab55d6aa8faa8ff2be0632ed06614c77506d581b6377536c5a525757764b5a49436646467974774956677443677747000603070fa5510d3969294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a61d7447696356475a56787459737551654c77494679505273776e65706a79144169736d626476694d6e595252426f6d51596a4800075b7edd8739ec790d7f4b19280e8e73298a20dc5ecabdcc3453990fc576159a452047726c597658577062466d716d4575584f634c586b53667853576c454c7647311c47566c7659465545534956796a736b6a7a7a4d706d725857676679320009039f6c5d6d22e03d1ade727299588085a949dc743119e7ce3bd3b01df1f25c4bc20500003a00e902728f624f6ae1e76b7d726a582464836c05010501050003598b457a8e064b814a78e43727c31df86c58f53337e2ad25492cb9b4f1f07c08b4647c5867d202125f3d04a77c1dd95fa880e67a5e4b00b403002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c66569f93b7599bc078b82c0579a08ce4aa300469b750b9d566ebe601e3dd2d295b2eea05a68bd87ac54feaf7372890bb6e4de528ea6e236b7b1dc6563d0e80f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4eda6e8eefbdfa3ee1c11073c7f94a97f91da12097685d0f5f1ffe54175acee0", - "sequence_number": "18175735931542196744", + "sender": "e1543e28c5da0cef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce", + "sequence_number": "8294062215890220949", "payload": { "Script": { - "code": "89d7e8db1fb98aceff4f429eaf66", + "code": "5a", "ty_args": [ { "vector": { - "vector": { - "vector": "u128" + "struct": { + "address": "97d185c3a8c46c71f0246b10165942394b3c9dc32cdd8f4c65e17f1368d8b66e", + "module": "XFPJMCKCxXflQCEOknXUBmluCZCf3", + "name": "wlHJQAEtlIrOStKAlKhHpnzE3", + "type_args": [] } } }, + { + "vector": { + "vector": "u64" + } + }, + { + "struct": { + "address": "f67fa62940c3472220abe9e18619a54656d9cf5ad985adce71a87fe8941ec5b3", + "module": "mMVKamxMzFkOATNBU", + "name": "EKiQrmEXEnWpPFVWaYLcWXNAJjhAjkw", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "5a0f659986dba9af858d3208d945eee00f9d039ab1f24eecc30dfc6eb6f595c7", - "module": "SyQ5", - "name": "PTqriMpePAiJqgwnPrkettbXAath", + "address": "0db31a172a0f0f5a827cbd692d4cd110385f8f87c50433e7a2aba59cfd4ac829", + "module": "msvJgUcz", + "name": "LmiKtoHYBKLnOoCm5", "type_args": [] } } - } - ], - "args": [] - } - }, - "max_gas_amount": "11041327343616192605", - "gas_unit_price": "5916981571310921152", - "expiration_timestamp_secs": "15095098698483063373", - "chain_id": 79 - }, - "signed_txn_bcs": "4eda6e8eefbdfa3ee1c11073c7f94a97f91da12097685d0f5f1ffe54175acee00852e0d2872f3dfc000e89d7e8db1fb98aceff4f429eaf66020606060306075a0f659986dba9af858d3208d945eee00f9d039ab1f24eecc30dfc6eb6f595c704537951351c50547172694d70655041694a7167776e50726b65747462584161746800005df00c35b8ac3a99c02585bc63571d524d5a8bfc49907cd14f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400cbf2e5832ab699c8c58f662b1f1d60b62b9f4f00d763206285a0ee25f06dba0dc17d4620adacff71342d2b25b52c206afec913f5a8062696831779b40455b09", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "62730bf48724ca92aa775838ed73b3faaf5309fe52faa1eb74bce6868db33aef", - "sequence_number": "10556944518786229831", - "payload": { - "Script": { - "code": "e2ad17ad1ba64f3fcf116cf3b2274e", - "ty_args": [ + }, { "struct": { - "address": "209809ccd9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62", - "module": "rrlkbypSCBJdpVvyBEeu", - "name": "IxcEwKuzKuEMLurnFBpwHgj", + "address": "044a4de5e29038d6d1ce953b8849d496d5da2ffa08c8f03467c6f04aa76cc71c", + "module": "iYDcMrnhmVmVUGZFHqcFgcDanEs1", + "name": "VzqmTvXUyRoagQFsDMnZ1", "type_args": [] } - } - ], - "args": [] - } - }, - "max_gas_amount": "14395772647879255167", - "gas_unit_price": "13398674410878513211", - "expiration_timestamp_secs": "7479244747097403500", - "chain_id": 103 - }, - "signed_txn_bcs": "62730bf48724ca92aa775838ed73b3faaf5309fe52faa1eb74bce6868db33aef47a6c2531bcd8192000fe2ad17ad1ba64f3fcf116cf3b2274e0107209809ccd9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe621472726c6b6279705343424a6470567679424565751749786345774b757a4b75454d4c75726e4642707748676a00007fa42080f30ec8c73bb0873163a7f1b96c70f282789dcb6767002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402c57f607bb7ec4fee2c4f5808147aaee2164e0687477e57d9db079e6f303c864665b5aba8036a3f547464fb480ee1e889630d4523d1a454ab1529a74011f2904", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "07360613a42e0911c55556a6b95d7d75f3b2ac275ef04513a0be712d3fc96075", - "sequence_number": "3115872219421417690", - "payload": { - "Script": { - "code": "dbe9a4a939fae7a14ca1024eeaef", - "ty_args": [ + }, + { + "struct": { + "address": "0d4b2a9a78836bf90c02df0257af021948205aa6c83228d4177e912e82a1f4eb", + "module": "CxJ5", + "name": "qaHjzynVtZucakHLiCcKiKWy4", + "type_args": [] + } + }, + { + "struct": { + "address": "0926fd406fe0370168a89b3b6fcd17ba4b40009ca29fb9d3ffc754ddc758050e", + "module": "uM", + "name": "xsHdASItWuk", + "type_args": [] + } + }, { "vector": { "vector": { - "struct": { - "address": "178a131a43a79b9c16f68d9613c79225756237814d6777d36e8ff2bee66e71f1", - "module": "RiLnzOGSRNnVBThRVCMUkgYe", - "name": "THUDxy3", - "type_args": [] - } + "vector": "address" + } + } + }, + { + "vector": { + "struct": { + "address": "41c3a34677bb78bdb5b57c46644421812f59696241a7d9b52acb2c5950571782", + "module": "ZydPHgZCtwBevFLyk3", + "name": "hBxCXhWkvxDmYFPBIfvMYPgmEe2", + "type_args": [] } } }, { "struct": { - "address": "aac8d1201799209af0b18541b91cce7ed006a09e61a4b0520d42310a872744fd", - "module": "JcWexNKqniTVaMBTQmySnWgQAjbE5", - "name": "IChGIFrmunOTbFTdPWFwpUYApolh4", + "address": "cfe9818db1d2bbf167fa473e5c4bec8ad0347bd774f262db245a585b3a906e53", + "module": "HRvDwawmtvtmQxLpChftyOLwEFGJuX8", + "name": "JPlLFZ4", "type_args": [] } } ], "args": [ { - "U128": "297717619728410700700382732537971135833" - }, - { - "U128": "125999204074353536081384399435688995445" - }, - { - "U8": 116 + "U64": "10112216091735588454" }, { - "U64": "8167598841516669270" + "Bool": false }, { - "Bool": true + "U128": "317989941949335886294221571572048072363" } ] } }, - "max_gas_amount": "6313298336391918973", - "gas_unit_price": "14925550415676924965", - "expiration_timestamp_secs": "6678369736510502456", - "chain_id": 32 + "max_gas_amount": "17080536540619536888", + "gas_unit_price": "15671376401493888273", + "expiration_timestamp_secs": "8193437490374087183", + "chain_id": 131 }, - "signed_txn_bcs": "07360613a42e0911c55556a6b95d7d75f3b2ac275ef04513a0be712d3fc96075da201f6446cd3d2b000edbe9a4a939fae7a14ca1024eeaef02060607178a131a43a79b9c16f68d9613c79225756237814d6777d36e8ff2bee66e71f11852694c6e7a4f4753524e6e564254685256434d556b67596507544855447879330007aac8d1201799209af0b18541b91cce7ed006a09e61a4b0520d42310a872744fd1d4a635765784e4b716e695456614d4254516d79536e576751416a6245351d494368474946726d756e4f54624654645057467770555941706f6c683400050259d5b0f643255e62c51eb8fcef53fadf02756abe2e2979c5bdc6b279ee6290ca5e00740156397e60df23597105017d75b43d63579d5725649b2b063522cf38766d4fe455ae5c20002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ec8670c530958c5944d35e509bac04e2f531382a0e42efac7aa134cf16a1a15157b54a1230fb868d69d571ff755f64c6d27274fb563cb621d78ca447bbf2a408", + "signed_txn_bcs": "e1543e28c5da0cef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce9537203ba46d1a7300015a0a060797d185c3a8c46c71f0246b10165942394b3c9dc32cdd8f4c65e17f1368d8b66e1d5846504a4d434b437858666c5143454f6b6e5855426d6c75435a43663319776c484a514145746c49724f53744b416c4b6848706e7a45330006060207f67fa62940c3472220abe9e18619a54656d9cf5ad985adce71a87fe8941ec5b3116d4d564b616d784d7a466b4f41544e42551f454b6951726d4558456e57705046565761594c6357584e414a6a68416a6b770006070db31a172a0f0f5a827cbd692d4cd110385f8f87c50433e7a2aba59cfd4ac829086d73764a6755637a114c6d694b746f4859424b4c6e4f6f436d350007044a4de5e29038d6d1ce953b8849d496d5da2ffa08c8f03467c6f04aa76cc71c1c695944634d726e686d566d5655475a4648716346676344616e45733115567a716d5476585579526f6167514673444d6e5a3100070d4b2a9a78836bf90c02df0257af021948205aa6c83228d4177e912e82a1f4eb0443784a35197161486a7a796e56745a7563616b484c6943634b694b57793400070926fd406fe0370168a89b3b6fcd17ba4b40009ca29fb9d3ffc754ddc758050e02754d0b787348644153497457756b0006060604060741c3a34677bb78bdb5b57c46644421812f59696241a7d9b52acb2c5950571782125a79645048675a437477426576464c796b331b684278435868576b7678446d594650424966764d5950676d4565320007cfe9818db1d2bbf167fa473e5c4bec8ad0347bd774f262db245a585b3a906e531f485276447761776d7476746d51784c7043686674794f4c774546474a755838074a506c4c465a34000301667ee367f5ce558c050002ab0ed86d8b2a1d32a15e395197a23aeff8f9b4b47c410aed118d7b80cee97bd90f921d9ffcefb47183002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444097af3f8677a46a8a17ca6571c0dda30a37a2333a6a155eefaf868c7393aaaf4e3b71bdd73a43687204ca8b3f6a2f6bf1c53d2795c87f5bed2ade19b4bac09107", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0456d5e204ce08283c3e11193387ec351956074c843228aa64ebc4a5ccd83637", - "sequence_number": "9952221749218452634", + "sender": "41b9f50a50ea506e61fdccb02526967426e115814d1a27810498e70744810e44", + "sequence_number": "3169051079518170606", "payload": { "Script": { - "code": "0d51", + "code": "635a94be9a626aace3b7", "ty_args": [ + { + "vector": { + "struct": { + "address": "2d9afe46b41d01211e589c5ba29c1bbc46211454e74e791581d50c9f6c373f3d", + "module": "tyPbaDVOoFMzJGMSnmJPEluy7", + "name": "jbgudGQYml", + "type_args": [] + } + } + }, { "struct": { - "address": "f55d7856b8bed9212aa359eea9ff7949fd9f46141a066b4f34727574ac497214", - "module": "SomZbWlWFzWyOlhKLHnQn", - "name": "nky2", + "address": "56fe9573b96d45001142200ef7c09efdf2c81aa8f979533db6f41c9d46130b02", + "module": "MWzoyYLMYzOvnyvEa", + "name": "PQwa", "type_args": [] } }, { "vector": { "struct": { - "address": "6830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307413167e56229ed", - "module": "SkpquyJWAzZYuEpoGlSPzui4", - "name": "hDJJmIOBOyhdvbPVqi", + "address": "5fbd9127c6c9d3606cc2afa04b4d1d1bb905ad4682df24e11ae2e56af8876836", + "module": "QhACo", + "name": "nZQrdgcPsXBpGAoqNMipNsnrwESgfapC", "type_args": [] } } }, { "struct": { - "address": "caf185f139725d867896546f628376edd832c7bd751e90b04630263abebe0754", - "module": "uTDTxouigFleWbQuB", - "name": "GdybKVNrKauVckJ", + "address": "ac117a15b4e6846d8c509bb821c9752cc6370a74fcdb4c39211148e02dbbf97c", + "module": "QqPoXhEpRhctDxYgnoQDNBUehyO8", + "name": "vQPbUselGHQUgNyoYHo8", "type_args": [] } }, { "struct": { - "address": "117d8b4d6819ae3a247f82dcde9d2076c087ef97250a3c5d51d6e95528ab8e27", - "module": "cFOtdRxsHcIZouhbKVjskjiVbBU", - "name": "zdZYBaCrPAwGtBc", + "address": "e08e6ebb7ea489e6bf0a920cb245916271a8dd4d7b041dc5b09406cea1400fc4", + "module": "ELFDO", + "name": "AvNXvetGPpTpIUptOIYdHyhWCrEAS", "type_args": [] } }, { "vector": "signer" }, - { - "vector": "bool" - }, { "struct": { - "address": "159b3a6d9115d32f95215621c51ee2528ee9293624743db144e8ad3519501914", - "module": "vzAHzulEjkdZfLciMYEWTROWenubMlUA9", - "name": "rVgCQWDyrIDYcCUjTBhEplm5", + "address": "c6a51a4b837704807f4ac74edb431cab2ecdf24bed2c6db23b8ec4058f1df7c7", + "module": "xnWrYNLyMUfmopPjfHdICeMzcAmE8", + "name": "wRrGocQyEVi", "type_args": [] } + } + ], + "args": [ + { + "Address": "7c50618da0ce06282deba37c5040b1ebaa26979a3b602c6c3e6a969190584e19" }, { - "vector": { - "vector": "bool" - } + "U64": "278800393134973744" }, { - "struct": { - "address": "bf535000de174f1dcc6dc183f7815b0a2e9b112224bfde9232b82d51a04ca046", - "module": "eZoaiviMlDNQysTOEUeKeMtn", - "name": "iUqhrKwJKTLzTK5", - "type_args": [] - } + "Bool": true }, { - "struct": { - "address": "a17e352a212c178aa3c77f3c29926f9b162d542ee1476e1bb27a359533f71726", - "module": "hvSKvkSpzijIaI5", - "name": "rPhQzdaNIwMwSPT", - "type_args": [] - } - } - ], - "args": [ + "U8": 250 + }, + { + "U64": "15335735909415376237" + }, + { + "U128": "79816927670890525972803969110632030421" + }, + { + "U64": "17930027732171610781" + }, + { + "Address": "3cb9bdb07f2f8daa5aac91c4505edf29331cad8ca1a428b4146cf9d690a22383" + }, { - "U128": "83212402971793114539665000330304910125" + "U8": 166 }, { - "U64": "1621105024004393239" + "U128": "312305964016387277572647613022444348585" } ] } }, - "max_gas_amount": "14344898315039182053", - "gas_unit_price": "10754005830704235827", - "expiration_timestamp_secs": "6867936405135539567", - "chain_id": 28 + "max_gas_amount": "15715777892768735142", + "gas_unit_price": "8113771906591471746", + "expiration_timestamp_secs": "4423052659580801412", + "chain_id": 242 }, - "signed_txn_bcs": "0456d5e204ce08283c3e11193387ec351956074c843228aa64ebc4a5ccd836379a2415a8f3641d8a00020d510a07f55d7856b8bed9212aa359eea9ff7949fd9f46141a066b4f34727574ac49721415536f6d5a62576c57467a57794f6c684b4c486e516e046e6b79320006076830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307413167e56229ed18536b707175794a57417a5a597545706f476c53507a7569341268444a4a6d494f424f7968647662505671690007caf185f139725d867896546f628376edd832c7bd751e90b04630263abebe07541175544454786f756967466c6557625175420f476479624b564e724b617556636b4a0007117d8b4d6819ae3a247f82dcde9d2076c087ef97250a3c5d51d6e95528ab8e271b63464f74645278734863495a6f7568624b566a736b6a69566242550f7a645a594261437250417747744263000605060007159b3a6d9115d32f95215621c51ee2528ee9293624743db144e8ad351950191421767a41487a756c456a6b645a664c63694d59455754524f57656e75624d6c554139187256674351574479724944596343556a54426845706c6d350006060007bf535000de174f1dcc6dc183f7815b0a2e9b112224bfde9232b82d51a04ca04618655a6f616976694d6c444e517973544f4555654b654d746e0f69557168724b774a4b544c7a544b350007a17e352a212c178aa3c77f3c29926f9b162d542ee1476e1bb27a359533f717260f6876534b766b53707a696a496149350f725068517a64614e49774d775350540002022d7323b31160db497e35098b38209a3e011709622b6e527f16e58c02d7035113c733059b6b53e73d956fbd13c8c5cf4f5f1c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dd147d7ba3fbbcfd9ff9f77ad0973594652a2f2fb418946f245bc4084372ca1dd5341b5c6327fcea7ca1f66160258d38985296ebe900e4efed0a2f1806e34506", + "signed_txn_bcs": "41b9f50a50ea506e61fdccb02526967426e115814d1a27810498e70744810e44eeadbf9d2abbfa2b000a635a94be9a626aace3b70706072d9afe46b41d01211e589c5ba29c1bbc46211454e74e791581d50c9f6c373f3d19747950626144564f6f464d7a4a474d536e6d4a50456c7579370a6a626775644751596d6c000756fe9573b96d45001142200ef7c09efdf2c81aa8f979533db6f41c9d46130b02114d577a6f79594c4d597a4f766e7976456104505177610006075fbd9127c6c9d3606cc2afa04b4d1d1bb905ad4682df24e11ae2e56af887683605516841436f206e5a5172646763507358427047416f714e4d69704e736e7277455367666170430007ac117a15b4e6846d8c509bb821c9752cc6370a74fcdb4c39211148e02dbbf97c1c5171506f5868457052686374447859676e6f51444e42556568794f3814765150625573656c47485155674e796f59486f380007e08e6ebb7ea489e6bf0a920cb245916271a8dd4d7b041dc5b09406cea1400fc405454c46444f1d41764e587665744750705470495570744f49596448796857437245415300060507c6a51a4b837704807f4ac74edb431cab2ecdf24bed2c6db23b8ec4058f1df7c71d786e5772594e4c794d55666d6f70506a6648644943654d7a63416d45380b775272476f635179455669000a037c50618da0ce06282deba37c5040b1ebaa26979a3b602c6c3e6a969190584e190130a30cfc7a7fde03050100fa016dd5e7b18e7ad3d402d5e06b492531ad5906eedb075d2e0c3c019ddafd9c3941d4f8033cb9bdb07f2f8daa5aac91c4505edf29331cad8ca1a428b4146cf9d690a2238300a602a96446a4ac10cdb7230c9fadd7f0f3eaa6df6a4bbaa819da82b8ed788fe89970841129a5f5d6613df2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f7aab8724aff5c2b39130d1e5315cdc09f3dfd10abae2e2270fca0b51a4b424b36437b93891f89465fc1cada655cfdd059d34ccc2c5b8bffbf2cace5fcaa5b09", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9f8ae0665c221eab106be5608d96146cbd7f5825a07586606e1ceea473e3b7b2", - "sequence_number": "16067698781839025786", + "sender": "7cd7b709714bbd423e8ef860629574fe317196d63125a625e329a4284f5b1951", + "sequence_number": "5946583572668348617", "payload": { "Script": { - "code": "c5ffd5fd130ee2f74f80b0fffb9a4b38", + "code": "188c101d4f5f2efb4b5bba", "ty_args": [ { "vector": { - "struct": { - "address": "ad42e70ec430100b014220bdb7f48149fe8f480f3565573f023ff55964d72acf", - "module": "zoqPVreJGvJIYDBRVdjWudwROvby", - "name": "zGAmHoUhLbutrLAfYwGJYFLb4", - "type_args": [] + "vector": { + "struct": { + "address": "58d44a7a65c18fad7154d96e289ad1e99289491a42f14b9bb0fe57dfb50f6666", + "module": "jBPAbjmfmaOLx", + "name": "SrYpsJgF", + "type_args": [] + } } } + } + ], + "args": [ + { + "Address": "905e8281f6b0274c0c64702dfd53bb75eab8ba74607ca205cb8fba10f19b3d21" }, { - "struct": { - "address": "455581f4752f77cbe78b98ba07e114a6506e1ec72f1a3e9829785b253a0def36", - "module": "RaKkCdSvlQmslhcXRnyohXJEZIoJ3", - "name": "pltkiDKwiVwGsthlcvME", - "type_args": [] - } + "U64": "7780955474889081499" + }, + { + "U8Vector": "74" + }, + { + "U128": "248693895592419659934728610523660644337" + }, + { + "Bool": false + }, + { + "U8Vector": "30f5fbd8cd50cad5ab36f6ab417f" + }, + { + "U8Vector": "fa25ce11ecaaec88017efc3335" + }, + { + "Address": "a659920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b983" + }, + { + "U8Vector": "dbb43eef" + }, + { + "Bool": true } - ], - "args": [] + ] } }, - "max_gas_amount": "15535092722645356811", - "gas_unit_price": "8173556935965178537", - "expiration_timestamp_secs": "15109467814014306650", - "chain_id": 104 + "max_gas_amount": "69315318454741073", + "gas_unit_price": "3933576690278203516", + "expiration_timestamp_secs": "4439421401642006109", + "chain_id": 99 }, - "signed_txn_bcs": "9f8ae0665c221eab106be5608d96146cbd7f5825a07586606e1ceea473e3b7b27ae67d69e9eefbde0010c5ffd5fd130ee2f74f80b0fffb9a4b38020607ad42e70ec430100b014220bdb7f48149fe8f480f3565573f023ff55964d72acf1c7a6f71505672654a47764a495944425256646a57756477524f766279197a47416d486f55684c627574724c41665977474a59464c62340007455581f4752f77cbe78b98ba07e114a6506e1ec72f1a3e9829785b253a0def361d52614b6b436453766c516d736c686358526e796f68584a455a496f4a3314706c746b69444b77695677477374686c63764d4500000b5108d685bc97d7a97aa257ba4e6e715a498567ec9cafd168002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444043a2a9970c3415fae326f2c380f546b83b54b59c8942ac24506529970fa4158f8c33b06c04eede32de9332e8b628a5f29e989d8168a225b1b1a119e209958c05", + "signed_txn_bcs": "7cd7b709714bbd423e8ef860629574fe317196d63125a625e329a4284f5b1951c9f811c440828652000b188c101d4f5f2efb4b5bba0106060758d44a7a65c18fad7154d96e289ad1e99289491a42f14b9bb0fe57dfb50f66660d6a425041626a6d666d614f4c780853725970734a6746000a03905e8281f6b0274c0c64702dfd53bb75eab8ba74607ca205cb8fba10f19b3d21019b02e575c781fb6b04017402f16f1fc288b83cdf58678099b9b318bb0500040e30f5fbd8cd50cad5ab36f6ab417f040dfa25ce11ecaaec88017efc333503a659920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9830404dbb43eef050151e8fc35ea41f6007c00caa828df96365d7623653efe9b3d63002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf137c10147f9dedc72bd4cb1d71f76de4bad23af3254e8a0f7560647a1c897555df72ca6f617a5f389bcbe7be2b1fbf7c0329db3e36bea403897ea6c954505", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b029849cbdd9f2172b6ab1aba3a573e3cb37c3f615af7a427f2358ce3dbcefb1", - "sequence_number": "17505806273866944451", + "sender": "4390a3543f4655c043d2231ab893ad05bea5acbc1006795d6a167ba02ca6e09d", + "sequence_number": "9114109835453485267", "payload": { "Script": { - "code": "f77719", + "code": "bc45ef1715", "ty_args": [ { "struct": { - "address": "c6162d0be80674dc1f413a5ac35ee88bb7770e1a61ce15d61cd49e35f3316093", - "module": "yaztxczgZGXsgazqlWkUKayCzAiwrq", - "name": "SLKzurZuFZJCQHoAjgytPHDSzfNM", + "address": "9c4554d4e22a7cb9d3b277814ea6cf81f12a25f0c4aa55484d05f9d666e36259", + "module": "sZMgSdkVmbLAqkzcYDGtfTievihby", + "name": "VmtRRuBLUoXFOFKcyIipjZcsAs5", "type_args": [] } }, { "struct": { - "address": "55e715a9ca321673d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c63", - "module": "bziZXOFOXTXwNLOwTYnHPe7", - "name": "WPWCN", + "address": "e58079576ce1ec2004331d76ff0ed4c93ece96dd9c6c8deebe8ba316ef238178", + "module": "DknaFLEtuOMQhTYRdcJZJvRKwTlr", + "name": "vSwnSqhPuEfzicFCqVzyMFsiUlEi5", "type_args": [] } }, - { - "vector": "u8" - }, { "vector": { "struct": { - "address": "b89879c47f13fe4803c4f521427649b676597afec86f406d88bf46f70be034ff", - "module": "Q", - "name": "VSSQFQkVNDgnQNhLwtHAKpminLfCX", + "address": "82fb31f25b072e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f907", + "module": "bvUkUPXVtmohPUEWqvmNFxwIJUWEvCgN", + "name": "gCj2", "type_args": [] } } + }, + { + "struct": { + "address": "dc799013edeadc8de7b9e5a04dd2354a0d26d04df81300225c95967af8a288f4", + "module": "CHiL", + "name": "oKynBQeAYSnKknx", + "type_args": [] + } + }, + { + "vector": { + "vector": "u128" + } } ], "args": [ { - "U64": "17577370735988215262" + "U64": "1108539902270911603" + }, + { + "Address": "5bb5c35e19e69a93924c12a0b9f9dc35f2e1d66c858af101ee5467d8b69370b5" }, { - "U64": "8346918520968356006" + "Bool": true }, { - "U8Vector": "3f00f0373f" + "U64": "9417897524974853842" }, { - "U64": "15051991286521375549" + "U64": "533426335464637558" }, { - "U8": 160 + "U8Vector": "b0ba8cfb4f1395ffaf" }, { - "U64": "10086890048705212034" + "Address": "752d772cedfd6485311d264c764ea9783b61d9877ffda4e425fad55dd73e53b0" } ] } }, - "max_gas_amount": "13487501960493552671", - "gas_unit_price": "457913481097952844", - "expiration_timestamp_secs": "4772752131770310249", - "chain_id": 71 + "max_gas_amount": "12089713127047329427", + "gas_unit_price": "2067815035718419322", + "expiration_timestamp_secs": "660625096132194620", + "chain_id": 5 }, - "signed_txn_bcs": "b029849cbdd9f2172b6ab1aba3a573e3cb37c3f615af7a427f2358ce3dbcefb1c3cfa46c0e1ef1f20003f777190407c6162d0be80674dc1f413a5ac35ee88bb7770e1a61ce15d61cd49e35f33160931e79617a7478637a675a47587367617a716c576b554b6179437a41697772711c534c4b7a75725a75465a4a4351486f416a677974504844537a664e4d000755e715a9ca321673d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c6317627a695a584f464f585458774e4c4f7754596e4850653705575057434e0006010607b89879c47f13fe4803c4f521427649b676597afec86f406d88bf46f70be034ff01511d5653535146516b564e44676e514e684c777448414b706d696e4c664358000601de8dec338e5deff301a6a072c32b36d67304053f00f0373f013dab6183536ae3d000a001822e7f810ed5fb8b1f549abe923b2dbb4cbeb48ae2d55a06695e28d7c6383c4247002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb18467eabd8fe6d7b2e0bb0d160f8346352a363bdf0b3ef82a2ad8a5df88b1562f624a4274d5a69ec44a541c64e0699b3f98d35f79989d7135ed1e504e02a01", + "signed_txn_bcs": "4390a3543f4655c043d2231ab893ad05bea5acbc1006795d6a167ba02ca6e09dd35019529bd27b7e0005bc45ef171505079c4554d4e22a7cb9d3b277814ea6cf81f12a25f0c4aa55484d05f9d666e362591d735a4d6753646b566d624c41716b7a63594447746654696576696862791b566d74525275424c556f58464f464b63794969706a5a63734173350007e58079576ce1ec2004331d76ff0ed4c93ece96dd9c6c8deebe8ba316ef2381781c446b6e61464c4574754f4d516854595264634a5a4a76524b77546c721d7653776e537168507545667a6963464371567a794d467369556c45693500060782fb31f25b072e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f907206276556b55505856746d6f685055455771766d4e467877494a5557457643674e0467436a320007dc799013edeadc8de7b9e5a04dd2354a0d26d04df81300225c95967af8a288f4044348694c0f6f4b796e4251654159536e4b6b6e78000606030701733434f62a53620f035bb5c35e19e69a93924c12a0b9f9dc35f2e1d66c858af101ee5467d8b69370b5050101d21e289be617b38201764435076d1c67070409b0ba8cfb4f1395ffaf03752d772cedfd6485311d264c764ea9783b61d9877ffda4e425fad55dd73e53b0937608f6084ac7a77a4335b9d15ab21c3cf1aa5806032b0905002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444001ca631a7ca6776f139ae6638e8c6045ca829501394810c451c5925702c98f6b8c041840452ec1115cfce483ed84e3e9535c63e9bf23ec4af75ffa8e13fd270a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "39762179f2ea0ef705922c9303e55911914918748fa7a7ac7e20d9f55ae53124", - "sequence_number": "16835706463422638052", + "sender": "6d4cd4e592a6e58c33bdc372dfbfc910c010b4381daf241f0bd373a372881505", + "sequence_number": "16465024613591909859", "payload": { "Script": { - "code": "84f30c4a5e93d1", + "code": "0ec4c1ddebe82603bac8678e8a609b", "ty_args": [ { "struct": { - "address": "8f49903978a240df50e659f9523c3ac6acbca3753b92a1fe978ecaf2eba5eb80", - "module": "rmNoFtPSvnYbOToKNdawenwgUqQRS", - "name": "iSVIL3", + "address": "e7b692911a6ede107887fc48be8eaa54f8336fe59e82f852cd9ad8b21a2fcb0d", + "module": "PFrvkYFRHexdr2", + "name": "DEhxqNDmulBOlTpntiMCQwyEBaaberkB", "type_args": [] } + }, + { + "vector": { + "vector": { + "vector": "u128" + } + } } ], "args": [ { - "Bool": false - }, - { - "Bool": false - }, - { - "U128": "323385331272803013858506194106500612350" - }, - { - "U8": 43 + "U128": "181708444721642633521082875558100582905" }, { - "U8Vector": "621efbef335af268d5a2378633" + "Bool": true }, { - "U64": "8782399549394235126" + "U128": "8929027186322074994452394208945006336" }, { - "U8": 20 + "Bool": true } ] } }, - "max_gas_amount": "538368058380050410", - "gas_unit_price": "2285502343222694818", - "expiration_timestamp_secs": "11082384882239754792", - "chain_id": 185 + "max_gas_amount": "11294129881830650036", + "gas_unit_price": "17293583353315745254", + "expiration_timestamp_secs": "12222469843586822661", + "chain_id": 145 }, - "signed_txn_bcs": "39762179f2ea0ef705922c9303e55911914918748fa7a7ac7e20d9f55ae53124e4e70d3fd471a4e9000784f30c4a5e93d101078f49903978a240df50e659f9523c3ac6acbca3753b92a1fe978ecaf2eba5eb801d726d4e6f46745053766e59624f546f4b4e646177656e7767557151525306695356494c3300070500050002fe80a53738cd00f94af9e49bd2bf49f3002b040d621efbef335af268d5a237863301f6ae31e9db59e1790014eadf288ee5aa7807a2931ca545bcb71f28520f5a558acc99b9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407035db7fbec3367c1ccf6d71dcc18340c75da5587b03f603659fffc44ae07a71aa412f9b092476460819e0687b52c67f594991d622c1736e1596baa6d02f020f", + "signed_txn_bcs": "6d4cd4e592a6e58c33bdc372dfbfc910c010b4381daf241f0bd373a372881505e385358fa6847fe4000f0ec4c1ddebe82603bac8678e8a609b0207e7b692911a6ede107887fc48be8eaa54f8336fe59e82f852cd9ad8b21a2fcb0d0e504672766b5946524865786472322044456878714e446d756c424f6c54706e74694d43517779454261616265726b4200060606030402f9c149d77ae803046a52da0703c6b388050102006724f98839118bfa87cc8007abb7060501b4f0a3e549cfbc9ce65dfe3b6f26ffef05b2eab890ef9ea991002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099c025f9dbff18db512ef118df319c65ead913bf53f74624ef0b5119f61c5db6a62e6b49411b635f1f2d8ff3f2e8cbcbc7a19f1a0d6df7c5e9bcd59201fd3600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b", - "sequence_number": "5990529320530598198", + "sender": "cf686fd4b7f9f13c5455fc499c1efc8ba7c3db97af5930745d14770cbd2b769b", + "sequence_number": "3931114927032381043", "payload": { "Script": { - "code": "6ee7a41943ce", + "code": "0fbb", "ty_args": [ { "vector": { - "struct": { - "address": "33fe6f903ef85d3d0ed04c30d52e42e38d95fe71811dc1bccc0238593da714e8", - "module": "XiRJKgrqGJHscAhBdnsj", - "name": "zcbscyemYDcPerSycmAynPrMZwyHKrDF2", - "type_args": [] + "vector": { + "struct": { + "address": "9e274e72df7c2db25965e524d59286473ded7b164337f8e6b38fcaee99286cc6", + "module": "iuFiCYHJmVaHmjgjDCmblmIEYif1", + "name": "ZnzQrVfWdiVQHMaISKmJy", + "type_args": [] + } } } }, { - "struct": { - "address": "0649f4e161ed646973ef3a05fe74843342bbcd264a861a73595a143e65f69ec4", - "module": "zoQmiZnKVkt6", - "name": "ToDhpYxgJeDyICnCTkKQYWenmQsXTk", - "type_args": [] + "vector": { + "vector": { + "vector": { + "vector": "u128" + } + } } }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73bff", + "module": "KoVBUfJJiblnZgIymrGblSibHjTu", + "name": "adGktSLCFwtMJpvuIGHbfJxElI", + "type_args": [] + } } } }, { "struct": { - "address": "c7ef0f7142bef199cb92dde852e452e03f31d77d32d3f9b9448c3bd8f0f267a9", - "module": "gApJWbMzzxuXRHfnOUMCZsfVavKgFTl", - "name": "iRObtGcQALNrXTpv2", + "address": "17cbf70b2e2565ce120f2513d9d89a35f5b2207aa9b7521b2e1cb0134e775d73", + "module": "GeQBQkbhTROvRfUVzreGvUSaeEI5", + "name": "FlEAPlKEUKaraCyj7", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "2a29bee359fcdc6681238d17788656cbe2525e80581b260fd294ea17b271d3b2", - "module": "OunRsQyGoDmVyBAf", - "name": "XIWhjJlGnBlpcCu9", - "type_args": [] - } + "struct": { + "address": "88a831634ecf8cc8f42452a7781526b014482fd9d461f808c984fefd47041f49", + "module": "KibK", + "name": "BzfGWXNl", + "type_args": [] } } }, { - "vector": { - "vector": { - "struct": { - "address": "397c400442707ccefcf2e5b57f4223777de07a221a7c1ed8e1e5059b73ed711e", - "module": "trxJgLmytBzzkyjCMVZrzvSCpZeE0", - "name": "QCy8", - "type_args": [] - } - } + "struct": { + "address": "8c0a77f45c479a6c680d739058fa97a0e1fad612c80b44390fdffe25f86d1a1e", + "module": "yFqWvSUY", + "name": "LhSlSWKfc", + "type_args": [] } }, { "vector": { - "vector": "u128" + "vector": "u64" } }, { - "struct": { - "address": "686a17d57183a4c54bc99f9b5add4536738ba67e698eb939809f3aa9b3adbe81", - "module": "ZXYV7", - "name": "vIrPMTSbsAsUGbfNtxq1", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed8961a6b550", + "module": "nFRHqyrLNJSS", + "name": "LyF4", + "type_args": [] + } + } } }, { "struct": { - "address": "a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d2755", - "module": "apNSsfnEbjL", - "name": "wzNgbHKIoYEBWiTWwoQTXAjYuwOkf2", + "address": "daf64b6b07a5d8a4711b742d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b7", + "module": "TTioLpxRgl4", + "name": "JNVsfCiUFbaTRkygNhfhcEKQFd1", "type_args": [] } } @@ -4695,1212 +5126,1178 @@ "args": [] } }, - "max_gas_amount": "12149949148592631079", - "gas_unit_price": "5755966100836256336", - "expiration_timestamp_secs": "489257404244072347", - "chain_id": 62 + "max_gas_amount": "13482906663579605794", + "gas_unit_price": "10124702418907107086", + "expiration_timestamp_secs": "9093570556160162731", + "chain_id": 249 }, - "signed_txn_bcs": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b36d9c986ada2225300066ee7a41943ce09060733fe6f903ef85d3d0ed04c30d52e42e38d95fe71811dc1bccc0238593da714e8145869524a4b677271474a487363416842646e736a217a6362736379656d5944635065725379636d41796e50724d5a7779484b7244463200070649f4e161ed646973ef3a05fe74843342bbcd264a861a73595a143e65f69ec40c7a6f516d695a6e4b566b74361e546f4468705978674a65447949436e43546b4b515957656e6d517358546b000606060407c7ef0f7142bef199cb92dde852e452e03f31d77d32d3f9b9448c3bd8f0f267a91f6741704a57624d7a7a7875585248666e4f554d435a73665661764b6746546c1169524f6274476351414c4e725854707632000606072a29bee359fcdc6681238d17788656cbe2525e80581b260fd294ea17b271d3b2104f756e52735179476f446d567942416610584957686a4a6c476e426c706343753900060607397c400442707ccefcf2e5b57f4223777de07a221a7c1ed8e1e5059b73ed711e1d7472784a674c6d7974427a7a6b796a434d565a727a765343705a65453004514379380006060307686a17d57183a4c54bc99f9b5add4536738ba67e698eb939809f3aa9b3adbe81055a5859563714764972504d545362734173554762664e747871310007a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d27550b61704e5373666e45626a4c1e777a4e6762484b496f59454257695457776f515458416a5975774f6b66320000276deca0604a9da8500a891bac4ce14f9b97b2570431ca063e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e2ee665b20d025446be4ed9b9b59294c4a0869d2361b920e23ac0b96c9d4b0fef1228c914035f7dd3610a5af098127c3a6dc4aecf9551d424e14f8e36226cf0b", + "signed_txn_bcs": "cf686fd4b7f9f13c5455fc499c1efc8ba7c3db97af5930745d14770cbd2b769b732e00bd32208e3600020fbb090606079e274e72df7c2db25965e524d59286473ded7b164337f8e6b38fcaee99286cc61c697546694359484a6d5661486d6a676a44436d626c6d494559696631155a6e7a517256665764695651484d6149534b6d4a79000606060603060607454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73bff1c4b6f564255664a4a69626c6e5a6749796d7247626c536962486a54751a6164476b74534c434677744d4a70767549474862664a78456c49000717cbf70b2e2565ce120f2513d9d89a35f5b2207aa9b7521b2e1cb0134e775d731c47655142516b626854524f76526655567a726547765553616545493511466c4541506c4b45554b61726143796a3700060788a831634ecf8cc8f42452a7781526b014482fd9d461f808c984fefd47041f49044b69624b08427a664757584e6c00078c0a77f45c479a6c680d739058fa97a0e1fad612c80b44390fdffe25f86d1a1e087946715776535559094c68536c53574b666300060602060607efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed8961a6b5500c6e4652487179724c4e4a5353044c7946340007daf64b6b07a5d8a4711b742d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b70b5454696f4c707852676c341b4a4e56736643695546626154526b79674e68666863454b51466431000022db68ce2ce81cbb0e0f7fff342b828cabbbe0b33dda327ef9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402d5a1a49ee5b31a5c61f8ccf184333924d785285a072c02ac0147e2d71c19589b1c12908887c13318871c5e81149dd24a63b4e5c1415ef39f47553dc61040903", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e69c58", - "sequence_number": "12443942011090498040", + "sender": "d3112a35dab263116706c212783a531bda65e83bdb8e0bb5644faa0af1c892ae", + "sequence_number": "11317395760043438969", "payload": { "Script": { - "code": "cab45ece", + "code": "6f3f91075131651beb3bb2cf28ae5d", "ty_args": [ { "vector": { "struct": { - "address": "196ee7b2979364764cd99d4c5051c3e6b4dea09d915119f7fe92210e73fd1725", - "module": "QtsGcLjaFwDCfnzBNjQtQRZCJStN0", - "name": "iqYIehRZLIukWTNKdEceclSLddGGG4", + "address": "b662609f3e7e3d908909c2dd19465dc380d572a2c7429436962ab403440f4dbd", + "module": "d", + "name": "mMcXpJSqWKPIFFlGTmdy3", "type_args": [] } } }, { "struct": { - "address": "8b357f77f3954a80cf32ee4ec074a8b07b3cf1da3d20ae73d03411add1b07332", - "module": "JdOgRHgwAPJrhuRf9", - "name": "sGSccohAyxFuaeeXSsjJh", + "address": "9ac158f8861d80ef42b68278386f9d0691dccdfde790351c6a66a62997a7bd8b", + "module": "OKFecgHTVpZHzLsXtOqvsyxrQP0", + "name": "dctktPLuJIaMgfPMDF", "type_args": [] } }, { "vector": { "struct": { - "address": "3c377c7057729ed56b5b17ceb4b0df142c247aecd3668476cb556c93a02f7243", - "module": "tVGIyvbGmMZss", - "name": "LTzGSyAvkYBgfWjc0", + "address": "5ddafdfbc369023736bcc2e4434220899ac43087040388c482ffac70ff3a4b1f", + "module": "FjSbsSeefLlFMUPyouYCTfgLYEiiY", + "name": "DpsokrMSRWNQPjhQFvjypNOtSm5", "type_args": [] } } }, - { - "struct": { - "address": "f1f669f0a7e7e572a103e5f7b0abca0ab8240a29b81c62d6474900d61a512fd5", - "module": "HSLQLMXrqqjFsn", - "name": "zISALalM9", - "type_args": [] - } - }, { "vector": { - "vector": { - "vector": "u128" - } + "vector": "u128" } }, { "vector": { - "vector": "address" + "struct": { + "address": "f05ed751f2647fbfb6b4f329aee3ef998d1fe1cbd54fcfc2b408991c67fc2ef7", + "module": "VLbPDZgrpNnEafDrCyAcrnwtQC3", + "name": "c", + "type_args": [] + } } } ], "args": [ - { - "U8": 63 - }, - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "7789358680916156578", - "gas_unit_price": "14274096670257788678", - "expiration_timestamp_secs": "3686056827652387823", - "chain_id": 110 - }, - "signed_txn_bcs": "fa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e69c58f8f19b0854c3b1ac0004cab45ece060607196ee7b2979364764cd99d4c5051c3e6b4dea09d915119f7fe92210e73fd17251d51747347634c6a6146774443666e7a424e6a517451525a434a53744e301e697159496568525a4c49756b57544e4b64456365636c534c64644747473400078b357f77f3954a80cf32ee4ec074a8b07b3cf1da3d20ae73d03411add1b07332114a644f675248677741504a7268755266391573475363636f6841797846756165655853736a4a680006073c377c7057729ed56b5b17ceb4b0df142c247aecd3668476cb556c93a02f72430d74564749797662476d4d5a7373114c547a47537941766b59426766576a63300007f1f669f0a7e7e572a103e5f7b0abca0ab8240a29b81c62d6474900d61a512fd50e48534c514c4d587271716a46736e097a4953414c616c4d39000606060306060402003f0500a2e01c54735c196c06374d504bc717c6efb31fba278127336e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b9b1b8ed215afa9b9b329627eb192c83674cad8d83cdca0d1ee5040a89e843971acc5f07e254c259f10dc63c38920d391ed8f0f6952217de11793a5b0cac7f0b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "5803037f4d99acc1c20e7a4a46716a09a2b183500884e068f6cf18a94e333b38", - "sequence_number": "7558017470450256172", - "payload": { - "Script": { - "code": "9a9a8f70c8f0af2fe64ee5", - "ty_args": [], - "args": [ - { - "Address": "2a10c8e530150ee166811213522efc2d67435cbdbd5941ed44f7f5c335f9caf8" - }, - { - "U128": "211467621562724105686418323837114622526" - }, { "Bool": true }, { - "U64": "10684441934317049199" + "U64": "16592985250054899238" }, { - "U64": "17788765030610950021" + "U8Vector": "7a20" }, { - "Bool": false + "U64": "8184392632415910142" }, { - "Address": "af8068cdae12d46daf749cd1bd70cc466bfb7a7bec59907d5c9f278bc498f306" + "U8": 6 }, { - "U128": "197001163778025359920518866930209026593" + "U8": 221 }, { - "U8Vector": "2c33cacb18516edbf353948bee" - } - ] - } - }, - "max_gas_amount": "3943902040477750761", - "gas_unit_price": "7909560873518593690", - "expiration_timestamp_secs": "5948534100489374172", - "chain_id": 139 - }, - "signed_txn_bcs": "5803037f4d99acc1c20e7a4a46716a09a2b183500884e068f6cf18a94e333b382c496264d878e368000b9a9a8f70c8f0af2fe64ee50009032a10c8e530150ee166811213522efc2d67435cbdbd5941ed44f7f5c335f9caf8023ea2e3014f6ff7fb1cf839efb52e179f0501016f5541a654c346940185d774e28b63def6050003af8068cdae12d46daf749cd1bd70cc466bfb7a7bec59907d5c9f278bc498f3060221728e9fa4a3d4c94c584e33460b3594040d2c33cacb18516edbf353948beee9559d97028ebb369a766733b567c46ddc89f7693f708d528b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440609437722e4eafac62c23ac65794f47f5c4d3d26b35045c334407529c4fb711b82556da3241c4de18a8113262799d33e62a516f1f12143b40c1e6a7099f05305", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "582efb6d94a3c0f0e4c72d738aea1476cdbc8ed122218332333d204e9587c18a", - "sequence_number": "18269217945718730999", - "payload": { - "Script": { - "code": "9a7c3231d3cf0aeca85b", - "ty_args": [ - { - "vector": { - "struct": { - "address": "608013bb952138be454b9556d31d508b4fc714e5751023fb946ef0b35a4bdfd6", - "module": "GbVHriaO3", - "name": "iyTVBnAZyPNyUZEFsKkH3", - "type_args": [] - } - } + "Bool": true }, { - "struct": { - "address": "46dfb20b08affd8c5307766a11af9afb214cef9f7a08a232e47d7208ff3dec92", - "module": "XyYRdGQsQhkzfMjmSRheW0", - "name": "EzkPAMNfkn", - "type_args": [] - } - } - ], - "args": [ - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "8768983532547004881", - "gas_unit_price": "11116067293793949526", - "expiration_timestamp_secs": "2092107220378183561", - "chain_id": 231 - }, - "signed_txn_bcs": "582efb6d94a3c0f0e4c72d738aea1476cdbc8ed122218332333d204e9587c18af7b0c15aed4c89fd000a9a7c3231d3cf0aeca85b020607608013bb952138be454b9556d31d508b4fc714e5751023fb946ef0b35a4bdfd609476256487269614f331569795456426e415a79504e79555a4546734b6b4833000746dfb20b08affd8c5307766a11af9afb214cef9f7a08a232e47d7208ff3dec9216587959526447517351686b7a664d6a6d5352686557300a457a6b50414d4e666b6e00010500d1d9b61210b0b1795617ede94e34449a89e7abb66ea8081de7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ff4b1dbb62a8001533becb19e46d8cd736e510e483a35206e191e53c53f1a19e8e7805a43e53abcc486965f278103f078eb657573a7fd02b9631368796702902", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "2a0ca74777f44e535ce53f25a06a9a3b846e6a782064daeb565ec88a7463574e", - "sequence_number": "14449257996875173549", - "payload": { - "Script": { - "code": "ba8c2e94d5d09ecc726e", - "ty_args": [ - { - "struct": { - "address": "89be520ddcd6c2f58b8840fe5ae0468de0ac318ce8ece1f223515da6b62ff329", - "module": "ciBfgqnAcSKMkoxBVwLJKhmEHgAK6", - "name": "UOGFiTeGvybGeTPf2", - "type_args": [] - } - } - ], - "args": [ - { - "Bool": true + "U8Vector": "b5584deae793bb152fdb03a8bf" }, { - "U128": "266447769348689817799891676368920039257" + "Address": "dd13e9400371db0a7153a0f778dd4d53f647fdcb72cc31094c2f76e2d8ce5575" }, { - "Address": "14c466c68c3cc1311b2db031ae62398584ceb79de51bb1b3cad6da679a136724" + "U64": "4632402690727099796" } ] } }, - "max_gas_amount": "16376512804615235462", - "gas_unit_price": "4534528246782129563", - "expiration_timestamp_secs": "13164474123173948316", - "chain_id": 85 + "max_gas_amount": "18144409603821775609", + "gas_unit_price": "13916502754957037740", + "expiration_timestamp_secs": "6472631485891458202", + "chain_id": 238 }, - "signed_txn_bcs": "2a0ca74777f44e535ce53f25a06a9a3b846e6a782064daeb565ec88a7463574ead8eb7bb971386c8000aba8c2e94d5d09ecc726e010789be520ddcd6c2f58b8840fe5ae0468de0ac318ce8ece1f223515da6b62ff3291d6369426667716e4163534b4d6b6f784256774c4a4b686d454867414b3611554f474669546547767962476554506632000305010259cfd2c63b76d1274313455c48f973c80314c466c68c3cc1311b2db031ae62398584ceb79de51bb1b3cad6da679a1367248627ba1aa10f45e39b756c5d6ae1ed3e9ceb9a76779bb1b655002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444014f918e6fd43d357b0b30743c71b99b765c2c73f266ea0eecf6a4edd8d37223f97f0bdf13422bbbe4a4e2d3c1db3b1b4af5cc284142a44d49e48015cf9444407", + "signed_txn_bcs": "d3112a35dab263116706c212783a531bda65e83bdb8e0bb5644faa0af1c892ae79b3e64b7b770f9d000f6f3f91075131651beb3bb2cf28ae5d050607b662609f3e7e3d908909c2dd19465dc380d572a2c7429436962ab403440f4dbd0164156d4d6358704a5371574b504946466c47546d64793300079ac158f8861d80ef42b68278386f9d0691dccdfde790351c6a66a62997a7bd8b1b4f4b46656367485456705a487a4c7358744f717673797872515030126463746b74504c754a49614d6766504d44460006075ddafdfbc369023736bcc2e4434220899ac43087040388c482ffac70ff3a4b1f1d466a536273536565664c6c464d5550796f7559435466674c59456969591b4470736f6b724d5352574e51506a685146766a79704e4f74536d35000606030607f05ed751f2647fbfb6b4f329aee3ef998d1fe1cbd54fcfc2b408991c67fc2ef71b564c6250445a6772704e6e456166447243794163726e77745143330163000a0501012686d1e82b2046e604027a2001fe787985bccd9471000600dd0501040db5584deae793bb152fdb03a8bf03dd13e9400371db0a7153a0f778dd4d53f647fdcb72cc31094c2f76e2d8ce557501943d5a25b4994940f9aafbc666e4cdfbac90f5d8855921c19ab491fe0a68d359ee002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a74153d68f54fc3459921e2f8c567f81d48d814c77a45672298ea22359fb83c266e7068bbdbb2b4767c9a53b108bb54cae33939f9e1c14508827e6ab3fec400a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d6af5a859c66d291a4f0248576fae16302f2c17034027b8ee7e650747d9afb32", - "sequence_number": "14431430428798177451", + "sender": "5c308848ee650e3ef92696f3a4df69ac86010f6a8adcdd09e1c0eae525a6a736", + "sequence_number": "7343474801930024784", "payload": { "Script": { - "code": "bae08fe4098a75ad5f1320c4332e", - "ty_args": [ - { - "vector": { - "struct": { - "address": "e9803129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5f", - "module": "UJmFlEZhGK", - "name": "qJRQ", - "type_args": [] - } - } - }, - "u64", - { - "vector": "signer" - }, + "code": "ab9a97ae66ddbd8c1fced2eb", + "ty_args": [ { "vector": { - "vector": { - "vector": "signer" + "struct": { + "address": "920ab33fee5ccbe23e98e07154736f78ed9b329bcd5b9a17dfeaf5c8955c7c97", + "module": "FTKofRBQcPe4", + "name": "XZCptBtfmshlbVGOFVrKOH", + "type_args": [] } } }, - { - "vector": "bool" - }, { "struct": { - "address": "617ca08c0a1bb611d19d08c2636f58e58a0ed65e09222065c879c25fbc0aaa2a", - "module": "SmYjorLSnDsFhpytSqDTuGeYQTqdrZM0", - "name": "WgHDixhNVsuGUL", + "address": "5e98c3d263e427045a00b5899aa0134ef55aaf7c5359db754fb767f52c7df470", + "module": "nRrumqLDo1", + "name": "ALOZZwfLCbsSuEimzDUD", "type_args": [] } }, { - "vector": { - "struct": { - "address": "3c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec", - "module": "mfXGN", - "name": "LFktQYHMnOxZTNeitJdla2", - "type_args": [] - } + "struct": { + "address": "c5562d915f2779c7627cc96db73c424b72d1a01047bef0c8c74dacccd0ca2817", + "module": "CEKLAnoThdclgBMPotYEi", + "name": "wEsGZxTuHRzFeRsNBtJomRGCo8", + "type_args": [] } } ], - "args": [] + "args": [ + { + "U8Vector": "deb31e3bb573" + }, + { + "U64": "7854546456176212918" + }, + { + "U8": 242 + }, + { + "U8": 26 + } + ] } }, - "max_gas_amount": "13282057214705936327", - "gas_unit_price": "12993000192595888241", - "expiration_timestamp_secs": "59644643332691307", - "chain_id": 78 + "max_gas_amount": "17509046379295504281", + "gas_unit_price": "15361126804883023941", + "expiration_timestamp_secs": "14472674886141213698", + "chain_id": 255 }, - "signed_txn_bcs": "d6af5a859c66d291a4f0248576fae16302f2c17034027b8ee7e650747d9afb32ab50479583bd46c8000ebae08fe4098a75ad5f1320c4332e070607e9803129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5f0a554a6d466c455a68474b04714a52510002060506060605060007617ca08c0a1bb611d19d08c2636f58e58a0ed65e09222065c879c25fbc0aaa2a20536d596a6f724c536e44734668707974537144547547655951547164725a4d300e576748446978684e56737547554c0006073c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec056d6658474e164c466b745159484d6e4f785a544e6569744a646c61320000c727f658aa5853b8718842d6d56850b46b9599b27ce6d3004e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444015ed6c93b34960e1215c2e1edceb29cf1d9ff967c0fa31863ec456e05ce48a6ddd8a44bb24ed88ffae24d43f981e4c1513065488999219203c12c45d2598880c", + "signed_txn_bcs": "5c308848ee650e3ef92696f3a4df69ac86010f6a8adcdd09e1c0eae525a6a736503712ca6c43e965000cab9a97ae66ddbd8c1fced2eb030607920ab33fee5ccbe23e98e07154736f78ed9b329bcd5b9a17dfeaf5c8955c7c970c46544b6f665242516350653416585a4370744274666d73686c6256474f4656724b4f4800075e98c3d263e427045a00b5899aa0134ef55aaf7c5359db754fb767f52c7df4700a6e5272756d714c446f3114414c4f5a5a77664c436273537545696d7a4455440007c5562d915f2779c7627cc96db73c424b72d1a01047bef0c8c74dacccd0ca28171543454b4c416e6f546864636c67424d506f745945691a774573475a78547548527a466552734e42744a6f6d5247436f3800040406deb31e3bb57301b6bb2f0063f4006d00f2001a9977bf41eaa0fcf245a8c83a71af2dd502fc29222145d9c8ff002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d73a75e46a89668e480b5236553372c0c2923149acdfe289273991f652166fc6d1d0d91866045fdc020d60cb4194eda00e5591efd09b4601c81fca543ba7430b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9330fe8690527058ffc0eed628605af78468ebb885217ae2c8f2ba9e98ae49a7", - "sequence_number": "1167799286041149258", + "sender": "4360f1b2fa4286b8a94e7807e04445980f7776fa49fe10e5f5101f1e8eb82877", + "sequence_number": "1088039576809455787", "payload": { "Script": { - "code": "f2ac01aeb917e5e833", + "code": "fc22b6b3bdd9", "ty_args": [ + { + "vector": "u128" + }, { "vector": { "struct": { - "address": "116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a64347a17280", - "module": "QJAW0", - "name": "mDH2", + "address": "4b704080af3509d6aae5e899498f06577a400f305af4c367d8800b7d702b7c57", + "module": "AgbBlNyCcoGSnoQN3", + "name": "TlaDxMWfaMb7", "type_args": [] } } }, { - "struct": { - "address": "17a720727f2a9fa3b579a9aa5b0e542c0dd602fa608005cf4045aed3191b5fe8", - "module": "bHsRimTHdSAlgXw", - "name": "HebEFGt8", - "type_args": [] - } - }, - { - "struct": { - "address": "dc39ee55c23d19d622ecfa20f044bf93981dec863aff79d7a1d90dced00c259e", - "module": "UmLoM6", - "name": "wClPdHE4", - "type_args": [] + "vector": { + "struct": { + "address": "6fd201c30b3d5d902bf4666aa53521f25a2358387900e6269e56232d3906b494", + "module": "FdhDKDOrcYeweEgwjFVOKwRHcNQRBxZ6", + "name": "QuFAjXVosgOFnMKBWyy", + "type_args": [] + } } }, { - "struct": { - "address": "5a92439ccfbae326662a5a1df94f20312f8412daf282e1f464c085324b87657d", - "module": "pwsNLHWDZqh", - "name": "O7", - "type_args": [] + "vector": { + "struct": { + "address": "0db290cbf49a27766d762c3a0d1fc3694ab36793c455ddada3629f10b6cf6b5c", + "module": "caWqwlwgrCKcgLhFvZmYzSSZEYThwCpt", + "name": "GUXWleFY1", + "type_args": [] + } } }, { "struct": { - "address": "7929a3b61682743a07de91840f74db88dbbe7fdc8a500c481b086beaac77fce9", - "module": "IVy", - "name": "iLcgDwSKqDCiWQhKRGc9", + "address": "c707bb40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb34", + "module": "qytqbYJTHdxGms", + "name": "dWxiKGKFEyPipaVfgfBPIbt9", "type_args": [] } }, { "vector": { "vector": { - "struct": { - "address": "1f0129546e094f42bf8ce5f9b2c9ef0f82c46e0d6bda61a1b919d33732cc7da8", - "module": "CthAAgQhiNjNSHedSkKrVqxqEzwmuxF", - "name": "t6", - "type_args": [] - } + "vector": "bool" } } }, - { - "vector": { - "vector": "u8" - } - }, { "struct": { - "address": "d791dcf6ed40542ced7c78017176bfa79e6e3c4c8a94cdb4ac964ee672626956", - "module": "VfPMgIb3", - "name": "nWlWhgZXhuRobh0", + "address": "8fc63289be2dcfc0df5913f3e8571708375d8670086e053a1f9d8aa69340dc4c", + "module": "QRrguqRKDRcMoNkwQfIqICbDCvaWKzf8", + "name": "aqtYUWHjrZUdsRESzfMgfEHFZjVfeTV5", "type_args": [] } }, { "struct": { - "address": "726c7de6d1741b122f0a7439625859e4c815397aec0f4c6a05a495f803ba3101", - "module": "aE7", - "name": "WKPEGoDMHYkzcFpqBu3", + "address": "efebc6f0e878e0e364fe466fbb8c7913b8ae0b516e8e426eafeeb6f8dc2a690e", + "module": "JnDBificMJxcAfHyYoSQioHYmwGyT0", + "name": "tDpRBV", "type_args": [] } } ], "args": [ { - "U8Vector": "3fbe4c971a6dddf6eb12e7a9e893" + "U8Vector": "f86abdaf3fc16e21cba1ca" }, { - "Address": "472ed38d548432cb9b538c7b6d208702a4de9f8c898eed4e890e76f80b8eaf63" + "U128": "166535325407266626037271017678494386296" }, { - "Bool": false + "U128": "244945400911735842573953173064461037442" }, { - "U64": "10538815536394318937" + "U8Vector": "1b5fbd2879f646fe0dc6bc6df7440f" }, { - "U8Vector": "5a4a" + "U8Vector": "9cdc683ddc" + }, + { + "Address": "5773408336f6d8cd0e7a574cb2b8eb6e9dc05fb9a9b20dff4dbc6fb81668d179" }, { "Bool": true }, { - "U8": 105 + "U128": "218806341931895708613213624837905906964" + }, + { + "Bool": false } ] } }, - "max_gas_amount": "17060233067279520784", - "gas_unit_price": "8945305671794026200", - "expiration_timestamp_secs": "15716723434029534256", - "chain_id": 14 + "max_gas_amount": "14644889091342839495", + "gas_unit_price": "12449067845467013138", + "expiration_timestamp_secs": "9006737639653211879", + "chain_id": 44 }, - "signed_txn_bcs": "9330fe8690527058ffc0eed628605af78468ebb885217ae2c8f2ba9e98ae49a74aff6f6d43db34100009f2ac01aeb917e5e833090607116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a64347a1728005514a415730046d444832000717a720727f2a9fa3b579a9aa5b0e542c0dd602fa608005cf4045aed3191b5fe80f62487352696d54486453416c6758770848656245464774380007dc39ee55c23d19d622ecfa20f044bf93981dec863aff79d7a1d90dced00c259e06556d4c6f4d360877436c506448453400075a92439ccfbae326662a5a1df94f20312f8412daf282e1f464c085324b87657d0b7077734e4c4857445a7168024f3700077929a3b61682743a07de91840f74db88dbbe7fdc8a500c481b086beaac77fce90349567914694c63674477534b714443695751684b52476339000606071f0129546e094f42bf8ce5f9b2c9ef0f82c46e0d6bda61a1b919d33732cc7da81f4374684141675168694e6a4e53486564536b4b7256717871457a776d7578460274360006060107d791dcf6ed40542ced7c78017176bfa79e6e3c4c8a94cdb4ac964ee672626956085666504d674962330f6e576c5768675a586875526f6268300007726c7de6d1741b122f0a7439625859e4c815397aec0f4c6a05a495f803ba31010361453713574b5045476f444d48596b7a634670714275330007040e3fbe4c971a6dddf6eb12e7a9e89303472ed38d548432cb9b538c7b6d208702a4de9f8c898eed4e890e76f80b8eaf6305000159b426b0e464419204025a4a05010069109491f0951fc2ecd8e6913e1d1c247c304c6346b1041dda0e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444049c46de007e358258ce3f407e96d33537bb85136c7db95ae0cd0f69d1a12ae7a3530fb01ce0d5d44594f9956553b5915a828bb30fc6a150300b1fd0eb6f3f707", + "signed_txn_bcs": "4360f1b2fa4286b8a94e7807e04445980f7776fa49fe10e5f5101f1e8eb82877ab404bfd3a7e190f0006fc22b6b3bdd908060306074b704080af3509d6aae5e899498f06577a400f305af4c367d8800b7d702b7c5711416762426c4e7943636f47536e6f514e330c546c6144784d5766614d62370006076fd201c30b3d5d902bf4666aa53521f25a2358387900e6269e56232d3906b49420466468444b444f7263596577654567776a46564f4b775248634e515242785a3613517546416a58566f73674f466e4d4b425779790006070db290cbf49a27766d762c3a0d1fc3694ab36793c455ddada3629f10b6cf6b5c2063615771776c776772434b63674c6846765a6d597a53535a455954687743707409475558576c654659310007c707bb40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb340e7179747162594a54486478476d7318645778694b474b46457950697061566667664250496274390006060600078fc63289be2dcfc0df5913f3e8571708375d8670086e053a1f9d8aa69340dc4c20515272677571524b4452634d6f4e6b775166497149436244437661574b7a663820617174595557486a725a5564735245537a664d67664548465a6a5666655456350007efebc6f0e878e0e364fe466fbb8c7913b8ae0b516e8e426eafeeb6f8dc2a690e1e4a6e4442696669634d4a786341664879596f5351696f48596d7747795430067444705242560009040bf86abdaf3fc16e21cba1ca027848367d5d6f55d7cb9934d57889497d0282afbfd8f2f6c71008995816abc446b8040f1b5fbd2879f646fe0dc6bc6df7440f04059cdc683ddc035773408336f6d8cd0e7a574cb2b8eb6e9dc05fb9a9b20dff4dbc6fb81668d17905010214fd88de7cd4fca393b7906e8f919ca40500c7ae7b6009193dcb1280cc593ff9c3ace77eabdc295cfe7c2c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402f6ffa823b4caebdfdbda3189dd4a716041a33e849d6ac9925e3ddbb20b6efb9a6c0194864ebe50a1a274a5eb9b8272437fc2031af6a4b8a0d33a89762e7dd0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "cf7dc51873af9d146d59be68a0f281f88a7f7066744b4c917f94aa78c2b5fce3", - "sequence_number": "10098718141568347637", + "sender": "b57db763e8e4e9ae06f23700c6e00b3c7cc3dccccc2bec8188b9f2b7bb340e39", + "sequence_number": "7909989780314925760", "payload": { "Script": { - "code": "55226e87077519ac06db851e79", + "code": "de1a9ec1486c", "ty_args": [ - { - "vector": { - "vector": { - "vector": "bool" - } - } - }, - { - "struct": { - "address": "92ab41f3ad9d77bd8edf551b1d983e45ecfa323b0e3f1840fb6e2836f08da41c", - "module": "BsbkkQvXFOPRcYjoeXYS5", - "name": "dEpWkXanDJkxRGHkLqsBRMGok1", - "type_args": [] - } - }, { "struct": { - "address": "f42aef540899e3ae26d251798abf0cf103869d63d40ce97c194277de0c550102", - "module": "xbRgIUE", - "name": "HCfinHmBpGL", + "address": "ccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b018a3", + "module": "lITPUDfINGysgSGOnSSlk", + "name": "yYVwjOaFH4", "type_args": [] } }, { "struct": { - "address": "482e553d04de7c836dacb358985076283bcd28af41120f2f9cbec5e70c5f776c", - "module": "IQPAKhEUbhhTavuVgtRu7", - "name": "LgJmzaancmyHpv", + "address": "ec0c2a50cf25cbe7ae74fd07174af6868efb6fddc3f3dd8637217960d72a61d8", + "module": "QzCknM9", + "name": "tHGnXAlrlLnWFrSreFBpbjFVBr", "type_args": [] } }, { - "struct": { - "address": "7827ed21f961c7173316264d8190f78f77f8c4e3ab583d14bf7b862a1b740e2f", - "module": "OxdiVYuqQXBSEWGeqYLzqIMcWZ", - "name": "fCEoKsVCugKqbJoXhLlWunQmmLiAuhh1", - "type_args": [] + "vector": { + "vector": "u128" } } ], "args": [ { - "U128": "6347413909970404825473117070013011153" + "U64": "15830664374836198020" + }, + { + "U8Vector": "d2c513d4ac" }, { - "U8Vector": "d048ea9a0b" + "U8Vector": "b864bb5e87" }, { - "U8": 223 + "U8": 249 }, { - "Address": "776299c891e0d2fd61e58f0f922c4ad5c9a046fcd57deb9858d19111ad571b31" + "U8Vector": "86b3cb40aa6286dc8232d59f" }, { - "U64": "10723821603705179403" + "Bool": true }, { - "U8Vector": "ae" + "Bool": false }, { - "U64": "9669193803797871633" + "U128": "169178792675421688294448796037298234339" }, { - "Address": "f0d14908960656b4d2ed844731e232818a1e718f7b578e10771bd1b0ea9b0f41" + "Address": "7377813d25ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66" }, { - "U128": "195755553405654857702698412326685789095" + "U8Vector": "d2ed9f7036dcd3e3d5" } ] } }, - "max_gas_amount": "11833728329949603988", - "gas_unit_price": "6579074447514022924", - "expiration_timestamp_secs": "11901977016832333977", + "max_gas_amount": "17311090139685803557", + "gas_unit_price": "14494414453570357900", + "expiration_timestamp_secs": "12242362978143905725", "chain_id": 250 }, - "signed_txn_bcs": "cf7dc51873af9d146d59be68a0f281f88a7f7066744b4c917f94aa78c2b5fce3f56df9faa4da258c000d55226e87077519ac06db851e7905060606000792ab41f3ad9d77bd8edf551b1d983e45ecfa323b0e3f1840fb6e2836f08da41c154273626b6b517658464f505263596a6f65585953351a644570576b58616e444a6b785247486b4c717342524d476f6b310007f42aef540899e3ae26d251798abf0cf103869d63d40ce97c194277de0c55010207786252674955450b484366696e486d4270474c0007482e553d04de7c836dacb358985076283bcd28af41120f2f9cbec5e70c5f776c15495150414b684555626868546176755667745275370e4c674a6d7a61616e636d7948707600077827ed21f961c7173316264d8190f78f77f8c4e3ab583d14bf7b862a1b740e2f1a4f78646956597571515842534557476571594c7a71494d63575a206643456f4b73564375674b71624a6f58684c6c57756e516d6d4c694175686831000902d19410c730a76f438cede0ecaa77c6040405d048ea9a0b00df03776299c891e0d2fd61e58f0f922c4ad5c9a046fcd57deb9858d19111ad571b31010bcd816beeaad2940401ae0111bcc7f388e02f8603f0d14908960656b4d2ed844731e232818a1e718f7b578e10771bd1b0ea9b0f4102a74bb46e79fca62e0c826afcf025459394681fe337d939a40c34ec425a914d5b9998279509512ca5fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf1fdb6a6cc0c4ce131b633236432d546a266c061f4cfedacb39472303fb46ff7be104e42c2f99b5e88a5c9659a2277603e9a2002d7d2faba1f9519b400ab0c", + "signed_txn_bcs": "b57db763e8e4e9ae06f23700c6e00b3c7cc3dccccc2bec8188b9f2b7bb340e39c02aa4d8cbedc56d0006de1a9ec1486c0307ccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b018a3156c495450554466494e4779736753474f6e53536c6b0a795956776a4f614648340007ec0c2a50cf25cbe7ae74fd07174af6868efb6fddc3f3dd8637217960d72a61d807517a436b6e4d391a7448476e58416c726c4c6e574672537265464270626a46564272000606030a0184fa8adc5fd1b1db0405d2c513d4ac0405b864bb5e8700f9040c86b3cb40aa6286dc8232d59f0501050002e3a39b4352c6456fdcfbcc8b78a6467f037377813d25ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f660409d2ed9f7036dcd3e3d52556bd92c3583df08c4a599c268126c9bd27a90b449ce5a9fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a013bd69fac7ac3acca794bbab5018098b9ce30a0251d4a6b784680170bbf8960753fee6e22e1f84b26c95df750bccfc006b6b3ec3dfa92605e156170da10b00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b0efd226a", - "sequence_number": "6614832036659731813", + "sender": "48098623eb0a1f4ae6d44bcd3f3cb69ae46826bedc5c607edb8d5cbbb2f2205c", + "sequence_number": "10418745558998481016", "payload": { "Script": { - "code": "eaeabe", + "code": "8dd18fcd01c7c292219dfcefb9b1", "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "ce4b4dde706c46ceb664cd29f42b0ce7e04b5e328b2bc2efb43cbb9296715c26", - "module": "UNkNCNGaVDkq", - "name": "dIDMSdocGhOLHHCUIN4", - "type_args": [] - } + "struct": { + "address": "3666fc9ea3df4dd4c4c7622a0df2d99fced4574d483b89f1a361563b71e018f5", + "module": "RCiivXSevKFBFGXvVqKR6", + "name": "jnohJfjQyYRXoKqftrR6", + "type_args": [] } } }, { "vector": { - "vector": { - "struct": { - "address": "dd6bf3cde98f8669d8e5538f0cfa637d3c772a93a2df9d3557dbbb85bb26c8ef", - "module": "jKO", - "name": "AgPPRXuwNaV8", - "type_args": [] - } + "struct": { + "address": "0ce40354edc1db6139450796fbe0cc57224b82de0595cf754067118037b4c0f7", + "module": "kuVh8", + "name": "XWTebBdGosOlqmpSfkOtitgKak", + "type_args": [] } } }, { "struct": { - "address": "9d0cda26de396227b133d51a95ae68f7c507922abdeb6aca025cf90459d36160", - "module": "zKvTaWbbLsmiKdhIahNc0", - "name": "yCESQRAJZ9", + "address": "e181874468c0f173fc51e22e0450a158b81de61d7a374d9340404eb88b50b29b", + "module": "liGRw8", + "name": "QggKthqnQhZoEpiRiTv", "type_args": [] } }, { "struct": { - "address": "b518d81436af19eb7940e96ce76a36c572e74af455e0df5fb8210ef562af7b04", - "module": "kOAzXYdoIrEzKruCYzHeIA", - "name": "GNRiRYIXNkbbSMbEmzgIxUyCVhnjgsQ5", + "address": "f299bf450a3623d1c69ce82bacb8d7af24a907f727cfb39649e3658471aaa5ea", + "module": "vXInCkmUOkVEPFOMTkEUmdmLTWDCav5", + "name": "CexxXvfapiiGw4", "type_args": [] } }, { "struct": { - "address": "e08286c79ee58bbe707b6143006bbf113fbe015cff13657e960a210ab8ade34e", - "module": "XQlWNadYy", - "name": "FLz", + "address": "7ad015299ec3f723818ad8a8154f4d8d050cd46edc3d0a59bc90c8d77fac381b", + "module": "FuOGRrFsyxyqNHfIVULxpq", + "name": "tbDpHbE", "type_args": [] } }, { "struct": { - "address": "4667a592abecc33dcfe5edfa72b7cb641cf1de3d911cfcdb1021f0756683ad80", - "module": "pGuoInvydyBep", - "name": "wahdd", + "address": "70406a395cd12cb757f790e79b8aa1544f2f91ccef68d732c2c11773bbb0af9e", + "module": "UebmmV", + "name": "CzwsgteYXIILILgPdMQj", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "5e735494528d4f1b1285c6ff6d287ac1ff05d34bec5ccfa9490c8ea85e3b3c84", - "module": "WRKeWGivFK4", - "name": "dZbPYzDovaylercjnCiEghjUgwapkix6", - "type_args": [] - } - } - }, { "struct": { - "address": "613fad17707e69b934c6103669e27b0123a3daca2382ca0eb21f7b5b712d9a58", - "module": "ZKavrZCqQMsybXt8", - "name": "bVKfdLIQxxxINJFImCdAwzEuiwyja1", + "address": "dd4fe1ab6703821868d7977353916f47983fe1a8e24dd8d920d5772d1b3b4bc4", + "module": "Ycc", + "name": "KHLmcuNELUCwv", "type_args": [] } } ], "args": [ { - "U64": "1764369398606935485" - }, - { - "U8": 100 - }, - { - "U8": 144 - }, - { - "U128": "83140352232770170850150048524016911181" - }, - { - "U8": 22 - }, - { - "U64": "15700772822954277568" - }, - { - "U128": "262273053620126370962401425373527742539" - }, - { - "Address": "4ca6cf5e4e29827a055362eb3f62cf75d454a81b029996480c047d3b9176b2fe" + "Address": "e7e26febdff9143b1a27ce110190d834bd968f2b6a163d62cc8abd43586d4e25" }, { - "Bool": false + "U64": "15376622668004256954" }, { - "Bool": true + "U8": 4 } ] } }, - "max_gas_amount": "8986133668028382376", - "gas_unit_price": "16673083440310656290", - "expiration_timestamp_secs": "2325140547591945145", - "chain_id": 22 + "max_gas_amount": "11807527580054520646", + "gas_unit_price": "11814128229025072429", + "expiration_timestamp_secs": "1845872271018643928", + "chain_id": 162 }, - "signed_txn_bcs": "3ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b0efd226a651dfac1b09acc5b0003eaeabe08060607ce4b4dde706c46ceb664cd29f42b0ce7e04b5e328b2bc2efb43cbb9296715c260c554e6b4e434e476156446b71136449444d53646f6347684f4c48484355494e3400060607dd6bf3cde98f8669d8e5538f0cfa637d3c772a93a2df9d3557dbbb85bb26c8ef036a4b4f0c41675050525875774e61563800079d0cda26de396227b133d51a95ae68f7c507922abdeb6aca025cf90459d36160157a4b7654615762624c736d694b64684961684e63300a794345535152414a5a390007b518d81436af19eb7940e96ce76a36c572e74af455e0df5fb8210ef562af7b04166b4f417a5859646f4972457a4b727543597a4865494120474e5269525949584e6b6262534d62456d7a67497855794356686e6a677351350007e08286c79ee58bbe707b6143006bbf113fbe015cff13657e960a210ab8ade34e0958516c574e6164597903464c7a00074667a592abecc33dcfe5edfa72b7cb641cf1de3d911cfcdb1021f0756683ad800d7047756f496e767964794265700577616864640006075e735494528d4f1b1285c6ff6d287ac1ff05d34bec5ccfa9490c8ea85e3b3c840b57524b6557476976464b3420645a6250597a446f7661796c6572636a6e43694567686a55677761706b6978360007613fad17707e69b934c6103669e27b0123a3daca2382ca0eb21f7b5b712d9a58105a4b6176725a4371514d7379625874381e62564b66644c4951787878494e4a46496d436441777a45756977796a6131000a01bd3589b89e4c7c1800640090024d83618fee312353e34f215dd83f8c3e001601c0fa4b3bb259e4d9024b18fb3f576f09423e34d1e6e7f34fc5034ca6cf5e4e29827a055362eb3f62cf75d454a81b029996480c047d3b9176b2fe05000501a87c02e3f528b57c221d2a1a0db162e7b93b1348028f442016002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440260aea8940dbcdd07ea54edf4175c091dbf3cef446fecd3b5d121f481956c897e8c619060da53904c9dd2030e7c6c895c8d61e009d4d187f816a2cb7be996e0d", + "signed_txn_bcs": "48098623eb0a1f4ae6d44bcd3f3cb69ae46826bedc5c607edb8d5cbbb2f2205c78784891e2d19690000e8dd18fcd01c7c292219dfcefb9b10706073666fc9ea3df4dd4c4c7622a0df2d99fced4574d483b89f1a361563b71e018f5155243696976585365764b46424647587656714b5236146a6e6f684a666a51795952586f4b7166747252360006070ce40354edc1db6139450796fbe0cc57224b82de0595cf754067118037b4c0f7056b755668381a58575465624264476f734f6c716d7053666b4f746974674b616b0007e181874468c0f173fc51e22e0450a158b81de61d7a374d9340404eb88b50b29b066c6947527738135167674b7468716e51685a6f457069526954760007f299bf450a3623d1c69ce82bacb8d7af24a907f727cfb39649e3658471aaa5ea1f7658496e436b6d554f6b564550464f4d546b45556d646d4c545744436176350e436578785876666170696947773400077ad015299ec3f723818ad8a8154f4d8d050cd46edc3d0a59bc90c8d77fac381b1646754f4752724673797879714e48664956554c7870710774624470486245000770406a395cd12cb757f790e79b8aa1544f2f91ccef68d732c2c11773bbb0af9e065565626d6d5614437a7773677465595849494c494c6750644d516a0007dd4fe1ab6703821868d7977353916f47983fe1a8e24dd8d920d5772d1b3b4bc4035963630d4b484c6d63754e454c55437776000303e7e26febdff9143b1a27ce110190d834bd968f2b6a163d62cc8abd43586d4e2501baec9c03d9bc64d500044603c76cc6c3dca32d45f4c50737f4a3d851cff60cdb9d19a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407cfe99aee1592c0e1e8d51911dea1aa619a2f0de42ecef2ab2ea024785095f55273d4ac0e9f166d65d6ef5f0168dc025c0b27711834bb55a4c8e3b299a8f2f00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "809a13ccf5c7db175f08263d2822058f5df64b16d498993cc3e45ee92ca9e635", - "sequence_number": "2564923877260231936", + "sender": "c7e4533bd6136c67852cca49aea796476f03449f3198093278f04dda01bf7724", + "sequence_number": "13216997792481252917", "payload": { "Script": { - "code": "025aacbdb9b1e3591f5e24", + "code": "b38e9cb1dfda55c8facaafc4", "ty_args": [ { "vector": { - "struct": { - "address": "f909f83e7690072cae1ea1f0111735b313c82ab22ee7fbd2b450b6ec46efc898", - "module": "hWQtBdUEDeXHYWVsKfIvPknQBmY4", - "name": "tiUNWisSDlZJItHKkMdVpyo", - "type_args": [] + "vector": { + "vector": "bool" } } }, { - "vector": { - "struct": { - "address": "fbb4fa525b92792e2e3993473aa57e9b735cc369e262e1fb4da656f864bed28e", - "module": "ShXtoRlmDEBkXFfhoeAUdCUylQ", - "name": "nnkssGoHRTRDAegkkN2", - "type_args": [] - } - } + "vector": "u8" }, { - "vector": { - "vector": "address" + "struct": { + "address": "20570aaf91ae56c4e3f12f41ddd0a128e73d6ff325f0b9309236d0fd6b667979", + "module": "BnGEeVSefxrUqjGIuFf2", + "name": "dhkdApqYyxGvpXIQUegYgWjyaDhSIw4", + "type_args": [] } }, { "vector": { "struct": { - "address": "026ff2203fb44a373fc11f6d13e6222415ec4b3e2aa91aabc5b34bfc01264787", - "module": "TOekZfhdHGmKVljoahyh7", - "name": "yiERYDyuTXLrKEHn", + "address": "72ac0a80b986003ddcf8b147edaddecd41d66ed844b57c069cdb1fed21baf409", + "module": "NervIzGQHNzofHuOI8", + "name": "BxpAjzxdvksq", "type_args": [] } } }, { "struct": { - "address": "1486e8226428dcb7fa634e7a433a535a07a9bc502305a4ebe2d97553931bd6c5", - "module": "nvNUmtiPgsCmQpfEkdH", - "name": "OfjoYQFszqENxaVEC", + "address": "e6dbb41a954ccb031787abdd2e26616bdd13ff5f3b0659d1d5d72329afb50573", + "module": "GuxCKNKAWjdIsYivzyXVJxjP2", + "name": "KHAxwnxBamAhVEJzsSwloSLR3", "type_args": [] } }, { "struct": { - "address": "064212cbee8b80b4ea9a2baf02e749a896ded724309c0797094d82866b47cd18", - "module": "RvZhTVDZQVewqdKBElMfygZsLmM", - "name": "GMgxTFezTQgOLYBhMmRjOBm1", + "address": "2c18f9c34799f7a00132c5a34e868514e03956becafe45a876eef1fc68033331", + "module": "jHXkJwThvDClO", + "name": "vmOqvGKzIETAMPPJXX8", "type_args": [] } - } - ], - "args": [ - { - "U8": 170 }, { - "U8": 62 - }, - { - "U8": 22 - }, - { - "U8": 71 + "vector": { + "struct": { + "address": "fdabae2c150585567e8dfb0c33753f59cb62a5880149377fd49f45ee1a1f8d96", + "module": "rKaJfBKctkabKx9", + "name": "hYfMZDhJGlnjsoNIKGiE", + "type_args": [] + } + } }, { - "Bool": false - }, + "vector": { + "struct": { + "address": "68996e8362eac97be042f0fb46b4802c7b332af0b96ed4234d7b0d7b44663bee", + "module": "g8", + "name": "jJRFnzUOXlnBo0", + "type_args": [] + } + } + } + ], + "args": [ { - "Bool": true + "Address": "05439264af08eddc5394f111e7caa60ca5e2c208a2283fa2c3ec7c7ca6ace331" }, { - "Address": "eb418f0ed9fcb378cc68df855c963b4eb098909725cd1fae6eb4358e0f5b5384" + "U64": "14218076558200407721" }, { - "Address": "59ec18ab4544ff8fa2da89149a620d291b40ec905c072f2eb2ba4b5d076c5482" + "U64": "8331309585300069520" }, { - "Address": "ec2214391259896d012dfc4b3f35ba587baff4a59f85447b7f558b0e8f680268" + "Bool": false }, { - "U128": "214978350937184170951630500255633230472" + "Address": "212b6ef78f1e4f5c9f8858d394b841a7c2603a64d63e9161aa6931fc41c43f3c" } ] } }, - "max_gas_amount": "1264925446907894872", - "gas_unit_price": "12272290939450114635", - "expiration_timestamp_secs": "10850854884466199341", - "chain_id": 13 + "max_gas_amount": "1113308163642896686", + "gas_unit_price": "10833942846498038489", + "expiration_timestamp_secs": "14727499257998517032", + "chain_id": 166 }, - "signed_txn_bcs": "809a13ccf5c7db175f08263d2822058f5df64b16d498993cc3e45ee92ca9e63500850344ad709823000b025aacbdb9b1e3591f5e24060607f909f83e7690072cae1ea1f0111735b313c82ab22ee7fbd2b450b6ec46efc8981c685751744264554544655848595756734b664976506b6e51426d5934177469554e57697353446c5a4a4974484b6b4d645670796f000607fbb4fa525b92792e2e3993473aa57e9b735cc369e262e1fb4da656f864bed28e1a536858746f526c6d4445426b584666686f654155644355796c51136e6e6b7373476f48525452444165676b6b4e32000606040607026ff2203fb44a373fc11f6d13e6222415ec4b3e2aa91aabc5b34bfc0126478715544f656b5a66686448476d4b566c6a6f616879683710796945525944797554584c724b45486e00071486e8226428dcb7fa634e7a433a535a07a9bc502305a4ebe2d97553931bd6c5136e764e556d7469506773436d517066456b6448114f666a6f595146737a71454e78615645430007064212cbee8b80b4ea9a2baf02e749a896ded724309c0797094d82866b47cd181b52765a685456445a5156657771644b42456c4d6679675a734c6d4d18474d67785446657a5451674f4c5942684d6d526a4f426d31000a00aa003e001600470500050103eb418f0ed9fcb378cc68df855c963b4eb098909725cd1fae6eb4358e0f5b53840359ec18ab4544ff8fa2da89149a620d291b40ec905c072f2eb2ba4b5d076c548203ec2214391259896d012dfc4b3f35ba587baff4a59f85447b7f558b0e8f6802680288ca8b62fdcafe44efc0235f0853bba1581c4cfafdea8d114b422b8a96ef4faa2d8bebf106fb95960d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440013475e3e87c41e29aa8f2243017aff662ace872537057ef5409c8c4ec6873e944bc0543a6e6081f2ce7a3d183e4995f2a659393d235bbe1ed8548e8eff23c01", + "signed_txn_bcs": "c7e4533bd6136c67852cca49aea796476f03449f3198093278f04dda01bf77243596f73177356cb7000cb38e9cb1dfda55c8facaafc4080606060006010720570aaf91ae56c4e3f12f41ddd0a128e73d6ff325f0b9309236d0fd6b66797914426e47456556536566787255716a4749754666321f64686b644170715979784776705849515565675967576a796144685349773400060772ac0a80b986003ddcf8b147edaddecd41d66ed844b57c069cdb1fed21baf409124e657276497a4751484e7a6f6648754f49380c427870416a7a7864766b73710007e6dbb41a954ccb031787abdd2e26616bdd13ff5f3b0659d1d5d72329afb5057319477578434b4e4b41576a6449735969767a7958564a786a5032194b484178776e7842616d416856454a7a7353776c6f534c523300072c18f9c34799f7a00132c5a34e868514e03956becafe45a876eef1fc680333310d6a48586b4a7754687644436c4f13766d4f7176474b7a494554414d50504a585838000607fdabae2c150585567e8dfb0c33753f59cb62a5880149377fd49f45ee1a1f8d960f724b614a66424b63746b61624b7839146859664d5a44684a476c6e6a736f4e494b47694500060768996e8362eac97be042f0fb46b4802c7b332af0b96ed4234d7b0d7b44663bee0267380e6a4a52466e7a554f586c6e426f3000050305439264af08eddc5394f111e7caa60ca5e2c208a2283fa2c3ec7c7ca6ace33101a906d8904cc150c501901c9e39edc19e73050003212b6ef78f1e4f5c9f8858d394b841a7c2603a64d63e9161aa6931fc41c43f3c2e317a53e043730fd96266429ee5599628a3d4a68b9662cca6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b7172bdb73965602a79dad87974bcfeb6ded4357b8fff583128db4b7eb2ba5bb34610c06a6d6075ec81c2b3b07b224328f654a863bcbe4c3455bef4b7e2870a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "49aa3bc1aecf0874bca007638f1910b483bba9dd8dc74316080bc0f12265b238", - "sequence_number": "943915736789503137", + "sender": "4dd9c00406596e06c5c0324bf340bac59695967d5aec3cfb2f3c48aabca7b6db", + "sequence_number": "14826440523967436776", "payload": { "Script": { - "code": "a9049d096a177780df4b8f", + "code": "9fdee51ee924", "ty_args": [ - { - "vector": "u128" - }, - { - "struct": { - "address": "3cea18934fc97b661f7cd4b9dedbc44088f8c262f4e2b09db952bbf1deca67b1", - "module": "ro", - "name": "aLGqgfYqIvmEKBbAEsSSaOV", - "type_args": [] - } - }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "f817e5d4c57ef9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea7", + "module": "aNxUJlrlgP", + "name": "VyUtvtRIhFMrfMnN", + "type_args": [] + } } } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "e32f66b65bb65ccbb243f8a7d832bc34d78e13396288dd8a250268408cfc4472", + "module": "qxELNRDFkfDxyedQaRypNcQMerLvuDQ4", + "name": "HndJ4", + "type_args": [] + } + } } - }, + } + ], + "args": [ { - "struct": { - "address": "e874563f4cd75ac50bc0bcaf9326a0ac6729e04114dd3b8b5894cdd043f70cf6", - "module": "icFxIgTvJrrsinAXT", - "name": "ZAdO", - "type_args": [] - } + "Bool": false }, + { + "U64": "1189101587387096878" + } + ] + } + }, + "max_gas_amount": "10838446097219818562", + "gas_unit_price": "11389042524445608135", + "expiration_timestamp_secs": "8538611105845132942", + "chain_id": 222 + }, + "signed_txn_bcs": "4dd9c00406596e06c5c0324bf340bac59695967d5aec3cfb2f3c48aabca7b6dbe817894a1a19c2cd00069fdee51ee92402060607f817e5d4c57ef9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea70a614e78554a6c726c675010567955747674524968464d72664d6e4e00060607e32f66b65bb65ccbb243f8a7d832bc34d78e13396288dd8a250268408cfc4472207178454c4e5244466b66447879656451615279704e63514d65724c767544513405486e644a3400020500012e9f0ff697898010429401064de56996c7086691d5010e9e8ebe1aaf8f3d7f76de002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444075cd140f3d48dab431bd68fe7c260d906f9ce085c9ea2988d429c11fa1f4b328b451dc0a913f161aa2777d8f985f4d64311b76751ecde912bb432cc09f120101", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311e0c3110858e67", + "sequence_number": "14649111383586666489", + "payload": { + "Script": { + "code": "b93870f7eaf96afa", + "ty_args": [ { "struct": { - "address": "8a3db5b4a583000436eb8c1396d55cd8a8d544be63a2049de2ca3d965486aff6", - "module": "IQEjxSCQKk3", - "name": "JjH", + "address": "41a2f0e04048c7ede38d6e511d2e4e59a7a9d3965cae8eb0d4e4dd39b6b64247", + "module": "DSWaykVxgdOEsqfQYo", + "name": "vCvtCskSuWyGB2", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "5a127b0f6a2c2b86548f6698a53a3f846ec7414376d6f698e3a53245e5742051", - "module": "VTKR6", - "name": "abmissDJDWwPpIyFdSonZlXRDWwKa", - "type_args": [] - } + "struct": { + "address": "545e1ca22490451d45991eb0aa18536b282e09b08851afc5b3df538c95ae7e75", + "module": "QqKqfmihNOPxbjZUvaCshgiZ6", + "name": "hNwziIggfMFonUqtAooWaRPRGDqa9", + "type_args": [] } } }, { - "struct": { - "address": "8b216b3e597a2f726b1f6d6d3b8a6bd7c02ccacac3c4e28b9eb2ba77c3aec1a7", - "module": "AjujgnmAOzieMm8", - "name": "wkkAzD9", - "type_args": [] + "vector": { + "struct": { + "address": "7e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e545", + "module": "bRXhTvyCjyvt", + "name": "LlusnjFjr0", + "type_args": [] + } } }, + "u128", { "struct": { - "address": "7c29b2ae3bd898ad398efe68e4cafa958b82f81be6b2b6966dafc9ed4f358b99", - "module": "TwWWYxpLsOpfdprAVzQF", - "name": "UlXINCTbFKtvLMUNRKwKSQEIIIWVZ", + "address": "e9c087222aae35ee37821d62d664ec223f2f5aa57af0cb6b29797b492c2bcc3b", + "module": "ICxMUhgIRAKDgxQr", + "name": "xmAekiqsZH", "type_args": [] } } ], "args": [ { - "U128": "184978467638395630235234185117781944136" + "U8Vector": "1d9ece57c28193" }, { - "U64": "2616397024289982492" + "U64": "17272415624117048522" }, { - "U128": "254139950712531940234997650499677123735" + "U8": 84 }, { - "Bool": false + "U128": "222874246534065957883798634403783466686" + }, + { + "U8Vector": "cc" + }, + { + "Address": "2ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e194" }, { - "U64": "7536268907478363538" + "U64": "14435402601205272797" }, { - "U8": 218 + "Bool": true }, { - "U128": "251754068884130696264236728203220304292" + "U128": "107213817717410373703941531578311036100" } ] } }, - "max_gas_amount": "7047151181682270977", - "gas_unit_price": "4142074427579536419", - "expiration_timestamp_secs": "2255642673682054664", - "chain_id": 112 + "max_gas_amount": "12840238355444255864", + "gas_unit_price": "12794017514012234033", + "expiration_timestamp_secs": "11793030871588086569", + "chain_id": 63 }, - "signed_txn_bcs": "49aa3bc1aecf0874bca007638f1910b483bba9dd8dc74316080bc0f12265b238a14c3d8d5c76190d000ba9049d096a177780df4b8f090603073cea18934fc97b661f7cd4b9dedbc44088f8c262f4e2b09db952bbf1deca67b102726f17614c47716766597149766d454b42624145735353614f56000606060406060207e874563f4cd75ac50bc0bcaf9326a0ac6729e04114dd3b8b5894cdd043f70cf61169634678496754764a727273696e415854045a41644f00078a3db5b4a583000436eb8c1396d55cd8a8d544be63a2049de2ca3d965486aff60b4951456a785343514b6b33034a6a48000606075a127b0f6a2c2b86548f6698a53a3f846ec7414376d6f698e3a53245e57420510556544b52361d61626d697373444a445777507049794664536f6e5a6c58524457774b6100078b216b3e597a2f726b1f6d6d3b8a6bd7c02ccacac3c4e28b9eb2ba77c3aec1a70f416a756a676e6d414f7a69654d6d3807776b6b417a443900077c29b2ae3bd898ad398efe68e4cafa958b82f81be6b2b6966dafc9ed4f358b9914547757575978704c734f706664707241567a51461d556c58494e435462464b74764c4d554e524b774b53514549494957565a00070248679f967446e588048188d7968e298b011c8831383b4f4f240297f426237e4e9093b36e8c26f99231bf05000192ad117aa434966800da02a44163b19f0f0736915aa4c4ea1166bd0163a58ea982cc6123941b09bf9a7b3908fe07910fa74d1f70002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440318ea6f4b998cab6005abab3730b2345c0f98e6a6ccadfd30806f162522c175b55d5b4042511f37caaabc54b9e17a85fec885617ac0c224af7dd0b3f85d0670c", + "signed_txn_bcs": "aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311e0c3110858e67f977d06530194ccb0008b93870f7eaf96afa050741a2f0e04048c7ede38d6e511d2e4e59a7a9d3965cae8eb0d4e4dd39b6b642471244535761796b567867644f4573716651596f0e7643767443736b53755779474232000607545e1ca22490451d45991eb0aa18536b282e09b08851afc5b3df538c95ae7e751951714b71666d69684e4f5078626a5a55766143736867695a361d684e777a69496767664d466f6e557174416f6f576152505247447161390006077e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e5450c62525868547679436a7976740a4c6c75736e6a466a7230000307e9c087222aae35ee37821d62d664ec223f2f5aa57af0cb6b29797b492c2bcc3b104943784d5568674952414b44677851720a786d41656b6971735a48000904071d9ece57c2819301ca5467387ff2b3ef005402be5ef7319d02995c2a2fe7f0bd04aca70401cc032ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e19401dd10970a2fda54c8050102c4ccc65263c9d3b00f2a84bf54a1a85078cc99f7c0b031b23151d3b4247b8db1292339761843a9a33f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b2c68ef98cd53b7e6ad96dcda0f4bd90eee6e29d43c2bb439c85ef68fdcad357aad16dc38685f15d550d836187866d6152da3cae9051268e30a7cb0b337e3105", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "91526aadbcbb28706a7f1e3fd72a57760b773c613bc0a90c3febda52a28dbf8d", - "sequence_number": "16514684600105100779", + "sender": "c0032ffd5c674b7eac32e0e070bc19e7bc139727294a51893900fbed4e03f8ee", + "sequence_number": "5014040751203557078", "payload": { "Script": { - "code": "5d", + "code": "57", "ty_args": [ { "struct": { - "address": "b1f2e2166e7aeb01393b3d2d1a92fac238d975dd25a76c99004d9ac957359085", - "module": "fqsfycztZoODfSSLWaeStcsS", - "name": "s8", + "address": "cf631a24c27cc5a63772d0438cab36cd15aa027ccb9722a4fd00766cb8adb876", + "module": "eajfhRGYXAjcEPZXcgXTV", + "name": "sFxmIbksDBjuAfjIqlnbDnJauTILTdpp", "type_args": [] } + }, + { + "vector": { + "vector": { + "struct": { + "address": "0b0a47c2ce208201d824ee7e12ff729505b68e4b4b8c603b5d6680353c6b8ec9", + "module": "GSnuszeFuQeY3", + "name": "wPCPwZ", + "type_args": [] + } + } + } + }, + { + "vector": { + "struct": { + "address": "690399796bf911ec455b356d2b11e1dd1060724f7c51a22d4a828ae42f101d7c", + "module": "Kj3", + "name": "ZcGNKaorwrwJSWWDBuPORCelHPWTi6", + "type_args": [] + } + } + }, + { + "vector": "u64" + }, + { + "vector": { + "struct": { + "address": "b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff7451", + "module": "abpaSVxoEbYyYGEmEaSiveidFfLcPuW4", + "name": "xHiVgmvfEXqplIXjHxIYsmZHBCy1", + "type_args": [] + } + } + }, + { + "vector": { + "vector": "u8" + } + }, + { + "vector": { + "vector": "address" + } } ], "args": [ { - "U8Vector": "c2340c5af8edf856eb577815" + "U8": 173 + }, + { + "Address": "0b890df4cb58a6c57a48e3ce7b7fd008d2f1e4bc9d7b03af9c6bb76215ab3c6f" + }, + { + "U64": "15901890813245339400" }, { - "U64": "15161469171796677350" + "Address": "0b1016483f692feca9d86c8593456979b400646ed7807d593ae9ea456ed794c0" }, { - "U8": 170 + "U8": 74 + }, + { + "U8": 120 + }, + { + "Bool": false } ] } }, - "max_gas_amount": "15825405578611127592", - "gas_unit_price": "10384103424025831782", - "expiration_timestamp_secs": "11019528035513869122", - "chain_id": 128 + "max_gas_amount": "6067536402263779936", + "gas_unit_price": "14201549918304428720", + "expiration_timestamp_secs": "10540034508853713370", + "chain_id": 161 }, - "signed_txn_bcs": "91526aadbcbb28706a7f1e3fd72a57760b773c613bc0a90c3febda52a28dbf8debe5e02e25f22fe500015d0107b1f2e2166e7aeb01393b3d2d1a92fac238d975dd25a76c99004d9ac957359085186671736679637a745a6f4f446653534c57616553746373530273380003040cc2340c5af8edf856eb57781501e612fa01e25b68d200aa28f599f386229fdb6629fafb0bbf1b90422343455d3aed9880002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440608badf6f83185c0fecdb2b09b8ea5eb42835d267b18bdc20d62af8c74c5e81b3191d7c75c70a560449747f28f741e29047a4ae9df998cc61d34745a27156d0d", + "signed_txn_bcs": "c0032ffd5c674b7eac32e0e070bc19e7bc139727294a51893900fbed4e03f8eed61ed2687f7395450001570707cf631a24c27cc5a63772d0438cab36cd15aa027ccb9722a4fd00766cb8adb8761565616a666852475958416a6345505a586367585456207346786d49626b7344426a7541666a49716c6e62446e4a617554494c54647070000606070b0a47c2ce208201d824ee7e12ff729505b68e4b4b8c603b5d6680353c6b8ec90d47536e75737a654675516559330677504350775a000607690399796bf911ec455b356d2b11e1dd1060724f7c51a22d4a828ae42f101d7c034b6a331e5a63474e4b616f727772774a535757444275504f5243656c4850575469360006020607b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff745120616270615356786f456259795947456d456153697665696446664c63507557341c78486956676d7666455871706c49586a48784959736d5a4842437931000606010606040700ad030b890df4cb58a6c57a48e3ce7b7fd008d2f1e4bc9d7b03af9c6bb76215ab3c6f010837895c71ddaedc030b1016483f692feca9d86c8593456979b400646ed7807d593ae9ea456ed794c0004a00780500602aafee35383454b062835c680a16c5da9995d48ab94592a1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bdffe8554083491fc3902827be34b7575acbdb71e58bcb25d43dfa9b14c7d0a2476a7d93098c71652049937f670c637a57db0dc98a2d56f6e1e5b55e31ed9502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a50b4b5b6fffe00d147c375018f4f62380f3de157b20f72e29909f1c994bbcf6", - "sequence_number": "16835229308990646972", + "sender": "07d2d9d47555a2cb6d8f2ebe2ace211be4ac7b427190da9e82d0529d84fa593b", + "sequence_number": "7910615762214382748", "payload": { "Script": { - "code": "f6da83992d", + "code": "f37bf4eff88f4c", "ty_args": [ + { + "struct": { + "address": "bb1bee0d6e6a075ce110bfb62a5719c2b3e1a1148c925aaf40368c081815cac7", + "module": "EcbotWWWoGhiZcrrkUM", + "name": "E1", + "type_args": [] + } + }, { "vector": { - "vector": "u64" + "struct": { + "address": "8724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f", + "module": "i9", + "name": "HPINdbCuPHWYieJDdcrzhDXYmgZPxhb", + "type_args": [] + } + } + }, + { + "struct": { + "address": "62aa6f94583893de69e3a7343ba05211552eb60adeeac3b6dbedb3883ec6b2df", + "module": "hTHgQvlgRauAjMclCLyh", + "name": "epgWalfymVPmSMBG", + "type_args": [] + } + }, + { + "struct": { + "address": "17e74ee1a03fffa75cfb38cb97b1cdb6406f2e59db05ebcea7f390bd5dea20a6", + "module": "cjKvAtURRiTovgdgfnfHhxMoSqwflk8", + "name": "rphlzORmvtxYMq3", + "type_args": [] } }, { "struct": { - "address": "2ef68a7e9947f4b43ab42c7d68621939fffb6465176219745f9ee1023ac8614c", - "module": "QGMzzFoSrxfttVaMKmINOLUYXwkxH9", - "name": "EhicIJOlzjUtqJcPOWamXuiP", + "address": "cdc5d7fd0eeef750cc7247b83eb0aa09153455577b5b356facc2d64f3e950846", + "module": "wVccunfXRtmzBPiEWftAfH0", + "name": "KUOmRPPiijLjybgEzulh8", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "ee2862aebcbf7b1516baea15664b888ed3bdd53a140352ef925aa0125a0e0c5e", + "module": "QPbsDoJlVSdcj2", + "name": "nugHzaCtpLwGBapNHaNIXvIEWN", + "type_args": [] + } + } + }, { "struct": { - "address": "58299d2e16f139f19d71939c1142e63426448712aeffbfc8684cf706ff228ccb", - "module": "uKADNMSseOhhqWDIJsbhM3", - "name": "xxbBTedOaGVluJzbizrfJEMP4", + "address": "9f1f637929cf2aa569adc169780e0146da97e6ca7082acb99fd46222f0628898", + "module": "NxKxxhxCxxPyOVgbnK8", + "name": "GxMAkJerHqnD", "type_args": [] } } ], "args": [ { - "U64": "10171033063516062128" + "U128": "306786671993115455744181353170353173379" + }, + { + "U8Vector": "df48d77ea8f0bc" + }, + { + "U8": 156 + }, + { + "U8": 74 + }, + { + "U64": "7429020534841168214" + }, + { + "U8": 225 } ] } }, - "max_gas_amount": "4013181934439521811", - "gas_unit_price": "4593988229141740668", - "expiration_timestamp_secs": "16855507443251563415", - "chain_id": 151 + "max_gas_amount": "17637792777810475238", + "gas_unit_price": "6543983681056533918", + "expiration_timestamp_secs": "13531786298246877595", + "chain_id": 165 }, - "signed_txn_bcs": "a50b4b5b6fffe00d147c375018f4f62380f3de157b20f72e29909f1c994bbcf6bceaa112dcbfa2e90005f6da83992d03060602072ef68a7e9947f4b43ab42c7d68621939fffb6465176219745f9ee1023ac8614c1e51474d7a7a466f53727866747456614d4b6d494e4f4c555958776b7848391845686963494a4f6c7a6a5574714a63504f57616d58756950000758299d2e16f139f19d71939c1142e63426448712aeffbfc8684cf706ff228ccb16754b41444e4d5373654f6868715744494a7362684d3319787862425465644f6147566c754a7a62697a72664a454d5034000101b0c1a0cdaec4268d135e48e5b4afb1377cbc5154f41fc13f974bf61fb7caeae997002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e627ad44cbc5dcc99c95d01dac18dce3e8582d3d47c130088d780c66c36cc79ccedea02cf6bde6f97de1c02a12ea20bff7358920b552310fa112c7d8554dc200", + "signed_txn_bcs": "07d2d9d47555a2cb6d8f2ebe2ace211be4ac7b427190da9e82d0529d84fa593b9cec649d1f27c86d0007f37bf4eff88f4c0707bb1bee0d6e6a075ce110bfb62a5719c2b3e1a1148c925aaf40368c081815cac7134563626f745757576f4768695a6372726b554d0245310006078724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f0269391f4850494e646243755048575969654a446463727a684458596d675a50786862000762aa6f94583893de69e3a7343ba05211552eb60adeeac3b6dbedb3883ec6b2df146854486751766c67526175416a4d636c434c79681065706757616c66796d56506d534d4247000717e74ee1a03fffa75cfb38cb97b1cdb6406f2e59db05ebcea7f390bd5dea20a61f636a4b76417455525269546f76676467666e664868784d6f537177666c6b380f7270686c7a4f526d767478594d71330007cdc5d7fd0eeef750cc7247b83eb0aa09153455577b5b356facc2d64f3e9508461777566363756e665852746d7a4250694557667441664830154b554f6d52505069696a4c6a796267457a756c6838000607ee2862aebcbf7b1516baea15664b888ed3bdd53a140352ef925aa0125a0e0c5e0e51506273446f4a6c565364636a321a6e7567487a614374704c77474261704e48614e4958764945574e00079f1f637929cf2aa569adc169780e0146da97e6ca7082acb99fd46222f0628898134e784b7878687843787850794f5667626e4b380c47784d416b4a657248716e4400060283b3ca855dda3b95b905a273bcf6cce60407df48d77ea8f0bc009c004a0156514ad8d02e196700e1e6f857171507c6f49eed53857ce6d05a9bd1809bf18fcabba5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444088ed8381490548b7ae0d3bf6428939b9276da5152b5830ae924283939a3c65a325fef60026d93dd198326803b11c8a4c10af27695a2cd0e378d3a8b3987f090b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fb420db4689874e7cfe605c6420fafa22035b995b6c4013cfb03cceab95bacb1", - "sequence_number": "5826606718587375740", + "sender": "e197a41f55d5a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d", + "sequence_number": "15985993478924758817", "payload": { "Script": { - "code": "4315c1468b2c490d", + "code": "7cfd68cc42ab84a48311db8fd00e", "ty_args": [ { - "struct": { - "address": "d22bc0c0cdc3889aaacaeabcb68e9c8dd8e84de731d58aeb0572c3100e7d8611", - "module": "EtgbHUO7", - "name": "tBDkxunfwqcxmAyU", - "type_args": [] + "vector": { + "vector": { + "vector": "u8" + } + } + }, + { + "vector": { + "vector": { + "vector": "u64" + } } }, { "struct": { - "address": "f52b94584877600a12b6478c6c035753bc625578cd655055876ff8d5485fd61e", - "module": "wxiFgOVxniIqDGvaMgIQKYmpBXQ2", - "name": "ErVoyupK", + "address": "f1e41beeaa472b049fe85e838b6a9982855b39a0f0a6f2bca90247f732ea7c1f", + "module": "Wtek", + "name": "NRGKVVlQxePzEnfMr3", "type_args": [] } }, { "struct": { - "address": "7a677c2e367633f817a1d81f52b2bd1a26ef9add44d2e32a5e7bdd5b07daf5aa", - "module": "mIiFLyjTaXUxaYTRZzdbfPSj", - "name": "i8", + "address": "496c1afd43e76b5bd9b6aedd0b185fa17c45c700f58bd5ed025b88d8311f0338", + "module": "rBu3", + "name": "fgTpkbjNruHbvHffkXaYozPkfMZYNkj0", "type_args": [] } }, { - "vector": { - "vector": "address" + "struct": { + "address": "cb2f4c5296102b1b5435597480352325e9875f8aa0d9d1363cb71b1a9646c480", + "module": "nYjkPeipwDMcVwS7", + "name": "VVDtIRorxNg2", + "type_args": [] } }, { "vector": { "struct": { - "address": "a9eac72834be97f81bef842fcba58ed64206dcebd8374b0d6db056bc2759a307", - "module": "r6", - "name": "qRH", + "address": "721577b2f653fe725c4f6efd658ff4d2e5a64737a69ff57fb57dff1648bc01d3", + "module": "QMmGIMCgXuJjahiruMNkNPvWIujuLZ", + "name": "msXkGEddwHkRMgGEsLkcoSokHSWCHby", "type_args": [] } } + }, + { + "struct": { + "address": "884dfbeee68f767ee33ff547074f33cfd72a7e148e009581db80436716a4299f", + "module": "friXLwOSCNPtrudcNuKETXcsECDm6", + "name": "dHVrGFkHkKBeATMz", + "type_args": [] + } } ], "args": [ { - "U8Vector": "58ebbe5f792fe99bbdaa2ecda6" + "Address": "0d52581587c27234112a1f90778feda2d8670e88a5250c8d6ea13c782d016ebd" }, { - "U128": "72177508439034498538853631892127474356" + "Bool": false }, { - "U128": "156027757285584213157579780422170453880" + "U128": "118192579823141803869441249422430204340" }, { - "Bool": false + "U8Vector": "f96fabdfdff14c1b2bccddd87d" + }, + { + "U128": "14923363319826848102844136152729516787" + }, + { + "Address": "8a74b993f4bd5bf250bc448c99333e57e1cc71c78506ecaa580e10ddaf549c95" + }, + { + "U128": "136551542986760826840617261584197226574" }, { - "U8Vector": "3c43bb8cc7ec09ca1b95ca30" + "U64": "14291322353618468924" + }, + { + "Bool": true + }, + { + "U128": "40203162341521008532440479979341511068" } ] } }, - "max_gas_amount": "2783700821253608093", - "gas_unit_price": "2335682078354024113", - "expiration_timestamp_secs": "5219432038205066666", - "chain_id": 169 + "max_gas_amount": "1732126496613337009", + "gas_unit_price": "9370383186405701075", + "expiration_timestamp_secs": "9708959958149694766", + "chain_id": 250 }, - "signed_txn_bcs": "fb420db4689874e7cfe605c6420fafa22035b995b6c4013cfb03cceab95bacb17c104e9bf043dc5000084315c1468b2c490d0507d22bc0c0cdc3889aaacaeabcb68e9c8dd8e84de731d58aeb0572c3100e7d8611084574676248554f37107442446b78756e66777163786d4179550007f52b94584877600a12b6478c6c035753bc625578cd655055876ff8d5485fd61e1c77786946674f56786e694971444776614d6749514b596d7042585132084572566f7975704b00077a677c2e367633f817a1d81f52b2bd1a26ef9add44d2e32a5e7bdd5b07daf5aa186d4969464c796a5461585578615954525a7a64626650536a026938000606040607a9eac72834be97f81bef842fcba58ed64206dcebd8374b0d6db056bc2759a307027236037152480005040d58ebbe5f792fe99bbdaa2ecda602b4e29bf869a16c1380e10f4deae14c36027827a6926bbcc83c11ad6ca15dda61750500040c3c43bb8cc7ec09ca1b95ca309dd2c8f325b1a126b1a689ac79026a20aa8d81f6c8256f48a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406000f2e2e75b2f7eb368ab2c81d76713c568fb07de1c7ab34f698cf31a84f35d58e833c4e310b9ddba9cfc5ca3a609274202824383f5973e48253ccba7cf100c", + "signed_txn_bcs": "e197a41f55d5a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d216f05255fa8d9dd000e7cfd68cc42ab84a48311db8fd00e07060606010606060207f1e41beeaa472b049fe85e838b6a9982855b39a0f0a6f2bca90247f732ea7c1f045774656b124e52474b56566c517865507a456e664d72330007496c1afd43e76b5bd9b6aedd0b185fa17c45c700f58bd5ed025b88d8311f0338047242753320666754706b626a4e72754862764866666b5861596f7a506b664d5a594e6b6a300007cb2f4c5296102b1b5435597480352325e9875f8aa0d9d1363cb71b1a9646c480106e596a6b5065697077444d63567753370c5656447449526f72784e6732000607721577b2f653fe725c4f6efd658ff4d2e5a64737a69ff57fb57dff1648bc01d31e514d6d47494d436758754a6a61686972754d4e6b4e50765749756a754c5a1f6d73586b4745646477486b524d674745734c6b636f536f6b485357434862790007884dfbeee68f767ee33ff547074f33cfd72a7e148e009581db80436716a4299f1d667269584c774f53434e5074727564634e754b45545863734543446d36106448567247466b486b4b426541544d7a000a030d52581587c27234112a1f90778feda2d8670e88a5250c8d6ea13c782d016ebd050002b471a0d4e1b91082830eb1271810eb58040df96fabdfdff14c1b2bccddd87d02f3fa593b17b273f4c1c1d55b9e223a0b038a74b993f4bd5bf250bc448c99333e57e1cc71c78506ecaa580e10ddaf549c95024e10f28b169788c934e931f5dcdeba66013c400742f6f954c60501029c79221d247c229f88298499f0d83e1eb107ae18dfbf0918d3350193dc490a822e050144a427bd86fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440714442e38dd5122dd2392396bdc9392850f1c39a8618b4ba287a23a589e34c33796d3f93280bb9052077c3de9ae92e742ab52d50a96c3d5991b75803323f9b03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5df8f1df59ce813caf86bb7814ce9aedca45b0f6ef792d908f6e0efc6444bab", - "sequence_number": "12821437480896073078", + "sender": "584e27862d6a7a6459c385052e56b16ba7c033bc6f1284c19d06f35befdcce01", + "sequence_number": "3042360372311368557", "payload": { "Script": { - "code": "a1c3e8ec18ffb0bdcb", + "code": "4a0756c70f06", "ty_args": [ { "vector": { "struct": { - "address": "2f97bc3fa65e29780a23c2b40e79c57f4e8f681bfa59068b12608ec3b66bd88b", - "module": "ASqosndJldXnQThJrPwyMSpuspcpkqP", - "name": "XxkLRcpsXwMkWpdaVIaZ", + "address": "8d631ad9e2c07be487b793e5c082707d3a3b8595bf73ee94a7f04655a48f66e1", + "module": "mnMuxgWoKQflOvwrXBMFIQzLYgMFXapm5", + "name": "QaMLRIfXTPzLaErVbmoGaOYGIJRi", "type_args": [] } } }, - { - "struct": { - "address": "82748436ed02a86d3ce308f63fa072ad5daca827b15baa953b119b7259d95626", - "module": "oIftGGK4", - "name": "gswkSgp7", - "type_args": [] - } - }, { "vector": { "vector": { - "struct": { - "address": "9bccb36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8", - "module": "smrEi6", - "name": "OOvzVAcsWTWVUEOfflU", - "type_args": [] - } + "vector": "u8" } } }, { "vector": { - "struct": { - "address": "b206bb8c4b591984976e8e53d2c6d44a0792afe964384ab3410c80f3aa677c8e", - "module": "mGMnzhETHGqQ1", - "name": "bF6", - "type_args": [] - } - } - }, - { - "struct": { - "address": "ce2fd627c60af9089ed5d45173f5327614dd9d579670ae3d986c0e5d5ba86e4b", - "module": "kzgNWxrDn0", - "name": "iGhrXCoRZsAVrrwEwJEojLBrdEy4", - "type_args": [] + "vector": "address" } }, { "vector": { - "struct": { - "address": "191ff413706125dd8a337e91668f2e6a8268066de50d794619904b741481eda8", - "module": "cmNdEaBcS5", - "name": "VmOFYNLaqaRuUkDaTV5", - "type_args": [] + "vector": { + "struct": { + "address": "e712972ac65c88c0c7829585a24aec902fc8a7da5944411c792004d5a51bee07", + "module": "amtZlxtca", + "name": "HJIAe", + "type_args": [] + } } } } ], "args": [ { - "U8": 220 + "Bool": true + }, + { + "U64": "1129289047097439740" + }, + { + "Bool": true }, { - "U8": 138 + "U128": "82499140802586845079355174818694921217" }, { - "Address": "a0dc0e5c0b6a56b24f6db3640348cbf4d437159d46ca53ae0462ebae9580efb9" + "U64": "7102508758265109256" } ] } }, - "max_gas_amount": "5957046504815328649", - "gas_unit_price": "16926931739088385739", - "expiration_timestamp_secs": "13040940422862090611", - "chain_id": 10 + "max_gas_amount": "2622500318438106821", + "gas_unit_price": "15327403766450772212", + "expiration_timestamp_secs": "13907208539078655062", + "chain_id": 225 }, - "signed_txn_bcs": "d5df8f1df59ce813caf86bb7814ce9aedca45b0f6ef792d908f6e0efc6444bab768db03e75e5eeb10009a1c3e8ec18ffb0bdcb0606072f97bc3fa65e29780a23c2b40e79c57f4e8f681bfa59068b12608ec3b66bd88b1f4153716f736e644a6c64586e5154684a725077794d537075737063706b71501458786b4c5263707358774d6b577064615649615a000782748436ed02a86d3ce308f63fa072ad5daca827b15baa953b119b7259d95626086f49667447474b34086773776b53677037000606079bccb36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f806736d72456936134f4f767a564163735754575655454f66666c55000607b206bb8c4b591984976e8e53d2c6d44a0792afe964384ab3410c80f3aa677c8e0d6d474d6e7a6845544847715131036246360007ce2fd627c60af9089ed5d45173f5327614dd9d579670ae3d986c0e5d5ba86e4b0a6b7a674e577872446e301c6947687258436f525a73415672727745774a456f6a4c427264457934000607191ff413706125dd8a337e91668f2e6a8268066de50d794619904b741481eda80a636d4e6445614263533513566d4f46594e4c6171615275556b4461545635000300dc008a03a0dc0e5c0b6a56b24f6db3640348cbf4d437159d46ca53ae0462ebae9580efb989fdfffd3baeab52cbf6a5e5bb8ae8ea7331ba8138bafab40a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440911dbb82048e9b7f226e7f44489a9bb6fad609a54418291338d547d2d5d19bf1edb3c0a7b9774f5d27bd1881d4b5634a7cf9806fbc887bd170e964a740fe330d", + "signed_txn_bcs": "584e27862d6a7a6459c385052e56b16ba7c033bc6f1284c19d06f35befdcce016d2358b6a3a2382a00064a0756c70f060406078d631ad9e2c07be487b793e5c082707d3a3b8595bf73ee94a7f04655a48f66e1216d6e4d757867576f4b51666c4f76777258424d4649517a4c59674d465861706d351c51614d4c5249665854507a4c61457256626d6f47614f5947494a52690006060601060604060607e712972ac65c88c0c7829585a24aec902fc8a7da5944411c792004d5a51bee0709616d745a6c7874636105484a4941650005050101fc75fbb4670aac0f050102017c757da8279bc10544b64baec1103e01081b7ebe152e9162c526da1f25fe6424f458487c84e0b5d456fc0f957b5400c1e1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f26d6db4fdfdc177c5fa316d52d89ab2f0c835943bee34ef504881332b5fbc9db4499886c5603c3107980861ec9934afc71d16cf0a233aad0360fc5078f82102", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "42c53ee250a5ed6f23e98c6c5b170be36d2dbaa0270a5c0135323d26ebf2fd02", - "sequence_number": "9287665328597658750", + "sender": "0b9c2120a042949babc98c0154fec9d0bf28f02730a0fd52149b1ee5467cc0d2", + "sequence_number": "8418523283924709462", "payload": { "Script": { - "code": "cda6c0", + "code": "4076ad2be2c5efef2cd3", "ty_args": [ { - "struct": { - "address": "52d78828abeec6a65c2f1262cdba27244469eb67bf2ad2510806302a4036977c", - "module": "dHCmBfZdzkGfiMieNsmsej", - "name": "x0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "c267be4d1528680991fdc479fdd022e72f925ea43ccc3fa38de0287b1606d843", + "module": "bKrUdcAPssHEWqRTBjaFp7", + "name": "JpACqrtCGlAjGNJxOps", + "type_args": [] + } + } } }, { - "struct": { - "address": "5e492f2dbb9d0651d62955ae8ebfbf40c1c64091542af3778f6199f4bccdbece", - "module": "yDwxyz", - "name": "GLHXDmS4", - "type_args": [] + "vector": { + "vector": "u8" + } + }, + { + "vector": { + "vector": "u128" } }, { "struct": { - "address": "afa47f59857d33e239e653b1ae45f7e93c24fe2bd5dff624c3e0fef498b8afba", - "module": "NlKxMgenzkGsWMMAFrNrkhxRdcnydHCB", - "name": "WtxIBpuiAqRJvBdnByLn", + "address": "d1097175be1dafa0765bc144e174d9be0dc05b6e3a9e247bbb2ea208bd964eea", + "module": "jeHtzDAyRVUjzrzfEjQr8", + "name": "PvRftigRNAFsAEbCuODm5", "type_args": [] } }, { - "vector": { - "struct": { - "address": "247f0956ffb1144123117bea3efe3f286025323565519de336b5bb3ad52f865f", - "module": "MQRSndErPrGiOxfKcJ1", - "name": "rNUCjlDRdrNQihETLWmDCkiXkuMEBTOL0", - "type_args": [] - } + "struct": { + "address": "29d4d7b1214bbcd48383245d0492c4a7e2c90c3992168708cc2096c8b47ab238", + "module": "zSOemu", + "name": "M2", + "type_args": [] } }, { "struct": { - "address": "f2c69f158ceab61223207cca99ff0b731deb2b89782c44a602a10c6f8b2afacf", - "module": "kPvrxfetmfFquJTaLatnIYGlqfBlQgo", - "name": "cNSKGmXPddsdHoRhYLoNNVONPLubeMVq8", + "address": "8b118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932", + "module": "bSuBvSGKAvlkDTiGdNoJkf6", + "name": "qCCpzppIZvyVAbQfrskOVIvCcvKp", "type_args": [] } }, { "struct": { - "address": "2fb958330e94313e56938ac293bd0f18fc0687655e17e4e8f6553fdb288f8222", - "module": "LbxwzmPLrtjpBmeBfxrDKO", - "name": "CdJwZSspwQZygYRWC9", + "address": "bb4a8b5383e6a91016a46ec8dfda31ac1198ee6260100974151b2f09220dc2f9", + "module": "hHhSUcUo", + "name": "UgDQmERiuYejDQsaWIsatuoUzG6", "type_args": [] } } ], "args": [ { - "U8Vector": "26ae4fc52b5abc8fefc24db8e2" - }, - { - "Address": "efdeca410a2abd580ddbefa435f4327755d059f60c4ab0efbe479668aa2267dc" - }, - { - "Bool": false + "Address": "cd79d6d0e581e422e4bc11988bbe0bef2dfebbcb45f00ebef181d7c040f735e4" }, { - "U8": 161 + "U128": "68942842412514201517218368923699049517" }, { - "U128": "188265901547279518962912897258701323103" + "U8": 216 } ] } }, - "max_gas_amount": "4333006260350701639", - "gas_unit_price": "17455251202340989571", - "expiration_timestamp_secs": "4321074352408813668", - "chain_id": 145 + "max_gas_amount": "7720715308021314329", + "gas_unit_price": "1563391181758931021", + "expiration_timestamp_secs": "18033160152886928644", + "chain_id": 191 }, - "signed_txn_bcs": "42c53ee250a5ed6f23e98c6c5b170be36d2dbaa0270a5c0135323d26ebf2fd027e6cc67f686ae4800003cda6c0060752d78828abeec6a65c2f1262cdba27244469eb67bf2ad2510806302a4036977c166448436d42665a647a6b4766694d69654e736d73656a02783000075e492f2dbb9d0651d62955ae8ebfbf40c1c64091542af3778f6199f4bccdbece0679447778797a08474c4858446d53340007afa47f59857d33e239e653b1ae45f7e93c24fe2bd5dff624c3e0fef498b8afba204e6c4b784d67656e7a6b4773574d4d4146724e726b68785264636e79644843421457747849427075694171524a7642646e42794c6e000607247f0956ffb1144123117bea3efe3f286025323565519de336b5bb3ad52f865f134d5152536e644572507247694f78664b634a3121724e55436a6c445264724e51696845544c576d44436b69586b754d4542544f4c300007f2c69f158ceab61223207cca99ff0b731deb2b89782c44a602a10c6f8b2afacf1f6b507672786665746d664671754a54614c61746e4959476c7166426c51676f21634e534b476d585064647364486f5268594c6f4e4e564f4e504c7562654d56713800072fb958330e94313e56938ac293bd0f18fc0687655e17e4e8f6553fdb288f8222164c6278777a6d504c72746a70426d6542667872444b4f1243644a775a53737077515a796759525743390005040d26ae4fc52b5abc8fefc24db8e203efdeca410a2abd580ddbefa435f4327755d059f60c4ab0efbe479668aa2267dc050000a1025ffbd9415f304c3758acf64498b1a28d4750bf8d3cee213c83aabe947c823df264e060bf3a8af73b91002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400a571edb19b7f97e05738e44a4b86a5198739e6b066414225a77362a13ef019a0bb4f633d0b425143c638e2d7bee156d4d1e39f40d68441ae96e6624361f1807", + "signed_txn_bcs": "0b9c2120a042949babc98c0154fec9d0bf28f02730a0fd52149b1ee5467cc0d256f0afcf529ad474000a4076ad2be2c5efef2cd307060607c267be4d1528680991fdc479fdd022e72f925ea43ccc3fa38de0287b1606d84316624b7255646341507373484557715254426a61467037134a70414371727443476c416a474e4a784f70730006060106060307d1097175be1dafa0765bc144e174d9be0dc05b6e3a9e247bbb2ea208bd964eea156a6548747a4441795256556a7a727a66456a5172381550765266746967524e41467341456243754f446d35000729d4d7b1214bbcd48383245d0492c4a7e2c90c3992168708cc2096c8b47ab238067a534f656d75024d3200078b118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c93217625375427653474b41766c6b44546947644e6f4a6b66361c714343707a7070495a7679564162516672736b4f5649764363764b700007bb4a8b5383e6a91016a46ec8dfda31ac1198ee6260100974151b2f09220dc2f908684868535563556f1b556744516d4552697559656a445173615749736174756f557a4736000303cd79d6d0e581e422e4bc11988bbe0bef2dfebbcb45f00ebef181d7c040f735e4022df4a40933d121827f5a4a2f91e8dd3300d819f387a2aa7d256b4d20b821ff47b21504e58d829da742fabf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059c6779aa02293415326f155ad1b08d309329f1b8d505a1dde1e65baaaa212e2357d164e5c697f6e78bc96883865e21a36e5e4352bcc2f5b86f9e0032770b703", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "aa332235096dae1896447526be2aaf823cadc4072c85431a568a14721ed44c4e", - "sequence_number": "9809558636918014699", + "sender": "ab6b2b8e1a11486830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307", + "sequence_number": "12601294073069459265", "payload": { "Script": { - "code": "adf87b26", + "code": "7e693a91ea669472cf6e70", "ty_args": [ { "vector": { - "struct": { - "address": "2adb820d7f64fda7c4c987cab5b751513c8871d2d22b15f884b4d447a9c67d3b", - "module": "MowDeQUqQciyaPmYdkYwAvIzPxr3", - "name": "KrixLDeQa", - "type_args": [] - } + "vector": "u128" } }, { - "vector": { - "vector": { - "struct": { - "address": "85bd10d584274dd9481f0a1831b85905fd2930b0c5e02cf728f847297d3e99de", - "module": "aMwyLBIBKIFWiEhROqhwktSzRNyqMoAe4", - "name": "URLGRXmhHItBYpUWxSCHkOmt", - "type_args": [] - } - } - } + "vector": "u128" }, { "struct": { - "address": "a006f96390783ee993b522a0421cc0cd3281212aa95f4f429f7e0295c3a23ef3", - "module": "KcabCqVaUeVaVbQmVHDeFTY0", - "name": "vimrlNKMMCAZ", + "address": "e5cffc16cc1cce1ec1cb6cbf2b64200929ab6cda926d0fe8791fafbe5aead50a", + "module": "qzopxs0", + "name": "IOmqEdvJxsgYJ", "type_args": [] } }, { "struct": { - "address": "c3e35240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170", - "module": "ipxmHxgotFcWYImAsHdwgy", - "name": "qEPzGfeDtijruyXRfEfqGNC", + "address": "0971476864e3cfca7f8b43223ab985e110b60c626849a62cd122a86fe5b90886", + "module": "YQtiOcIpCLaxKhOsVkfexGlesyQm", + "name": "jWSJTXETJLQpmIHZQgkZo", "type_args": [] } }, { - "vector": { - "struct": { - "address": "86213050de96e43aedefe586b233ce77840abd49735ba701e2155530a1f4bb38", - "module": "wEDSTAhzxhvOYu2", - "name": "gwYzMGquaFuIc", - "type_args": [] - } + "struct": { + "address": "391824e42ca3c28efd452ce03bfc0dc79091e29bec7b496f7261cd3f3acb2192", + "module": "DBKsgzfEfRYYnRjh7", + "name": "BB", + "type_args": [] } }, { "vector": { "struct": { - "address": "2dc5670499c357b06313e8569f54635cfd6550d58dd88fe6a6122ae2cabec984", - "module": "gVrxGRiaBIZJS", - "name": "jZU1", + "address": "64b9726e58bc4c5943c5ef8a71b3a2c39b303fe3bd73c0364d248586f007d934", + "module": "saKFWQ6", + "name": "ZEBvhSJQtm", "type_args": [] } } @@ -5908,234 +6305,300 @@ ], "args": [ { - "U128": "288030427202234136605094063789654441825" - }, - { - "U8": 134 - }, - { - "Bool": false - }, - { - "U128": "319501370971646994301660070280920866705" + "Bool": true }, { - "Address": "6bee732c90d85b47facb213a3f80615027ef1a2f9900b40f9e92c02410d475f7" + "U8Vector": "ddf22eeded981b6b14a3a26a25e1" }, { - "Address": "d5be5dc7ce66492758e868df31f58c0eb73718100e8f47aa2dd15203794d1175" + "U64": "4609310245914815820" }, { - "Bool": true + "U8Vector": "e5" } ] } }, - "max_gas_amount": "7840909704778509361", - "gas_unit_price": "2099018007977147000", - "expiration_timestamp_secs": "17693806140635264453", - "chain_id": 22 + "max_gas_amount": "11024527293977263202", + "gas_unit_price": "5729072554979043309", + "expiration_timestamp_secs": "11085322295844090727", + "chain_id": 163 }, - "signed_txn_bcs": "aa332235096dae1896447526be2aaf823cadc4072c85431a568a14721ed44c4eeb02dd649b8d22880004adf87b260606072adb820d7f64fda7c4c987cab5b751513c8871d2d22b15f884b4d447a9c67d3b1c4d6f7744655155715163697961506d59646b59774176497a50787233094b7269784c446551610006060785bd10d584274dd9481f0a1831b85905fd2930b0c5e02cf728f847297d3e99de21614d77794c4249424b494657694568524f7168776b74537a524e79714d6f4165341855524c4752586d684849744259705557785343486b4f6d740007a006f96390783ee993b522a0421cc0cd3281212aa95f4f429f7e0295c3a23ef3184b63616243715661556556615662516d56484465465459300c76696d726c4e4b4d4d43415a0007c3e35240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170166970786d4878676f7446635759496d41734864776779177145507a4766654474696a727579585266456671474e4300060786213050de96e43aedefe586b233ce77840abd49735ba701e2155530a1f4bb380f774544535441687a7868764f5975320d6777597a4d47717561467549630006072dc5670499c357b06313e8569f54635cfd6550d58dd88fe6a6122ae2cabec9840d675672784752696142495a4a53046a5a5531000702617fe8865e3ad3c640470e8b78a4b0d80086050002919fe854ad58c6dd7f18b395cbb95df0036bee732c90d85b47facb213a3f80615027ef1a2f9900b40f9e92c02410d475f703d5be5dc7ce66492758e868df31f58c0eb73718100e8f47aa2dd15203794d11750501316c3c65d581d06c783aa0d6c135211dc5b53069f0068df516002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409a26537b03484dce60d68f2641df036d165d8eb0b7fb5846a3d5d641ed6a6a15bc4b8785caebce4b088059ed19311e4d76a15d78c6fc8474cf8033f3fdd46a08", + "signed_txn_bcs": "ab6b2b8e1a11486830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e30741578ae731cae0ae000b7e693a91ea669472cf6e7006060603060307e5cffc16cc1cce1ec1cb6cbf2b64200929ab6cda926d0fe8791fafbe5aead50a07717a6f707873300d494f6d714564764a787367594a00070971476864e3cfca7f8b43223ab985e110b60c626849a62cd122a86fe5b908861c595174694f634970434c61784b684f73566b666578476c657379516d156a57534a545845544a4c51706d49485a51676b5a6f0007391824e42ca3c28efd452ce03bfc0dc79091e29bec7b496f7261cd3f3acb21921144424b73677a6645665259596e526a683702424200060764b9726e58bc4c5943c5ef8a71b3a2c39b303fe3bd73c0364d248586f007d9340773614b465751360a5a45427668534a51746d00040501040eddf22eeded981b6b14a3a26a25e1014c2d525b3f8ff73f0401e562fc1cd629fdfe98ed27f78322c1814f67338140e5f9d699a3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444096970f338a8c920dd8d4cde4512fb4bfc34a4ce482b57e745073255ed42be8f597b5345148b8b19690362726069404c5b586f0aa2f220d7130a597593d06ab08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5c73f1dc1f6bf87873865caed16e3527ae148e3e403cba5b03416aadb48fbc54", - "sequence_number": "1815782951030465357", + "sender": "2c3b9404a0bbfb161c21b5bdd8cfab322dfd3e0d7ec5957716d232de67a1f4e3", + "sequence_number": "8264196253837583744", "payload": { "Script": { - "code": "aca45bb904", + "code": "8a54c2ae8a7a8ff9a741bf5fccb2d675", "ty_args": [ { "struct": { - "address": "e31b67000cae580a5d7bfaaa7bd63fa896d52f848f485ed1db5c07ed072083f7", - "module": "PWXSxukpGaGHmFqId2", - "name": "wuXlqciznFlqdbiBhC", + "address": "e674b9995fafd64ad8486793c63dacd98e3ff5c6d2b795d371097c8a5af47e0f", + "module": "GZMzqFR", + "name": "OSXBkkFIrBucmzVU3", "type_args": [] } }, { "struct": { - "address": "2880740b32162044eb600a2f5edad8dfc5fbb5c3eeccd6bde90fe993acd96675", - "module": "UmulCdRnzJQSt", - "name": "mYQdeCtsVbbRVupDdgjAAepqxxEH4", + "address": "6eb77c9141dea54f4e58a29f4c9b69c688a34474e9a920634d85555d1752f68a", + "module": "LrnStE", + "name": "XNjMtPLuHfweqtuvjLVEGsBfPqCIVNJ", "type_args": [] } + }, + { + "vector": { + "vector": "u8" + } } ], - "args": [] + "args": [ + { + "U8Vector": "6a4597d9d8" + }, + { + "Address": "b1968253ed1254407d38e569f3827fb6a1a8d928ddd5accef0351d562282920e" + }, + { + "U128": "186707421460848458310452463163448828768" + }, + { + "Bool": true + }, + { + "U128": "208868171904263487706822830267964677768" + }, + { + "U128": "64306121334804148670540023868498182337" + } + ] } }, - "max_gas_amount": "17350715829852566773", - "gas_unit_price": "7220038959882769063", - "expiration_timestamp_secs": "11902278560671980246", - "chain_id": 3 + "max_gas_amount": "11556856339225058913", + "gas_unit_price": "10456992466620457051", + "expiration_timestamp_secs": "5205563897016189139", + "chain_id": 29 }, - "signed_txn_bcs": "5c73f1dc1f6bf87873865caed16e3527ae148e3e403cba5b03416aadb48fbc544da36139f9f432190005aca45bb9040207e31b67000cae580a5d7bfaaa7bd63fa896d52f848f485ed1db5c07ed072083f7125057585378756b70476147486d4671496432127775586c7163697a6e466c7164626942684300072880740b32162044eb600a2f5edad8dfc5fbb5c3eeccd6bde90fe993acd966750d556d756c4364526e7a4a5153741d6d59516465437473566262525675704464676a414165707178784548340000f5f41b851e20caf0a7124b3c2ebb3264d6da993a4a632da503002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444002569dba114cc73b5c8de66c19459e8ce43ed4d4a25b589d5d61338db8eab6ee71a2d210b4080c0eaab88a92a0c1aa3fe05af4dcbcc7078073e3c2d7452b710a", + "signed_txn_bcs": "2c3b9404a0bbfb161c21b5bdd8cfab322dfd3e0d7ec5957716d232de67a1f4e380651a10b552b07200108a54c2ae8a7a8ff9a741bf5fccb2d6750307e674b9995fafd64ad8486793c63dacd98e3ff5c6d2b795d371097c8a5af47e0f07475a4d7a714652114f5358426b6b4649724275636d7a56553300076eb77c9141dea54f4e58a29f4c9b69c688a34474e9a920634d85555d1752f68a064c726e5374451f584e6a4d74504c7548667765717475766a4c56454773426650714349564e4a000606010604056a4597d9d803b1968253ed1254407d38e569f3827fb6a1a8d928ddd5accef0351d562282920e026023a900761b1e38d6eed414988a768c050102885ea17337ecaabab2c16790f28b229d02c1004944de2003410b9e186691e86030611ebb139c3362a05b20d9af3eb31e91d3803fb9c8e03d481d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444043f78dcbd3051b9ccca90d631d2c8fd124172e15f544b8e8e51f17eaaed5390eafbbfd2055766575135e142248b0edfd883a90ceec0ae9fa0ae32cc728810002", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159001bf698f4a2", - "sequence_number": "4381573132213259014", + "sender": "ab257292d77ad98187cea46d5f8b5600a822ea922519674a85067bb1ad3b9f7d", + "sequence_number": "15646642158652465588", "payload": { "Script": { - "code": "fd9c223f", + "code": "fda70ecc5da7f9eeb59e9d9ec7", "ty_args": [ { "struct": { - "address": "0e9f311a1967ddaf37c8a28e7e315027948274a5fc5798ae54c6433bd7662b5a", - "module": "gnoPpzujudDLsdvzzQQRGGSma0", - "name": "kKbpKuJTTyzXI", + "address": "6b4ebbbdc32e991fb39ab48a65e8196c3cf58e14d685d0e7c4e4721c8c609af5", + "module": "bedZvt7", + "name": "HCpeNWMZmgscWevQEI2", + "type_args": [] + } + }, + { + "struct": { + "address": "7516ed2a1bb03fd908ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedb", + "module": "AdlDYeDQvBHQTl9", + "name": "IHsXlwcp5", + "type_args": [] + } + }, + { + "vector": { + "vector": "u128" + } + }, + { + "struct": { + "address": "11468b661fe4c358a3135e30ed8f83f72d93aff977defdceaba8ab4ab7ee10bd", + "module": "LJCQY8", + "name": "pnbAhaBhFXdx1", "type_args": [] } } ], "args": [ { - "U128": "84021873993414384437526647783736021062" + "U8": 248 }, { - "U128": "30908192967921401892113355560787711387" + "U64": "3845388220096084976" }, { - "U8Vector": "aeeaf3" + "U128": "159549754998025519505546147122868533032" }, { - "U128": "68568069113358875780695410855098908361" + "U128": "102790906798126818129379643752370009989" }, { - "U8": 63 + "U128": "54365632605266578775850984755293158987" }, { - "U8": 208 - }, - { - "Bool": true + "Address": "da70a211267cb243822295440e5048c064713eaf5decef02e7bea94a1cb5fc18" } ] } }, - "max_gas_amount": "16976842943183761884", - "gas_unit_price": "10405226585714504255", - "expiration_timestamp_secs": "9006712950649754982", - "chain_id": 43 + "max_gas_amount": "1558339676583077653", + "gas_unit_price": "12351108678222572812", + "expiration_timestamp_secs": "8706299470873983090", + "chain_id": 161 }, - "signed_txn_bcs": "9c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159001bf698f4a2068bf7968c79ce3c0004fd9c223f01070e9f311a1967ddaf37c8a28e7e315027948274a5fc5798ae54c6433bd7662b5a1a676e6f50707a756a7564444c7364767a7a5151524747536d61300d6b4b62704b754a5454797a5849000702461009ab49620808ecd09d3a3906363f029b1521b835296a7d5d68b05591b340170403aeeaf302c9feaebef3c47f233688ce1ed1ba9533003f00d00501dcb110acb5dc99eb3fb2f65073ca669066956381b545fe7c2b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f69b2a03cc8fe8075f0b57e620174bb460d1ca932bb211e1985443c64bedbf0839f1f08836d4a50a6a1a07f488a6e0f3eb0fa58c94c7dc3e0d219a525bf6f03", + "signed_txn_bcs": "ab257292d77ad98187cea46d5f8b5600a822ea922519674a85067bb1ad3b9f7db4a121d2240a24d9000dfda70ecc5da7f9eeb59e9d9ec704076b4ebbbdc32e991fb39ab48a65e8196c3cf58e14d685d0e7c4e4721c8c609af5076265645a76743713484370654e574d5a6d6773635765765145493200077516ed2a1bb03fd908ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedb0f41646c445965445176424851546c3909494873586c77637035000606030711468b661fe4c358a3135e30ed8f83f72d93aff977defdceaba8ab4ab7ee10bd064c4a435159380d706e6241686142684658647831000600f801f07b4c6236905d3502283752596db6c6c8f03c107d422a08780285f7d9dbd60149acd2b76b90fcce544d024b7e81478a7460c32f430166a270e62803da70a211267cb243822295440e5048c064713eaf5decef02e7bea94a1cb5fc1815a721eead55a0150c6db363e7f367ab72789da53dfdd278a1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d6fea51eeb72a9cd4ed94660f6ed6542033d2d0f71da0ec00ac2cdfd545ca0806ea1a680515b99059ae737a2205647b33f562bee506c89b9ff13c818aeb6b70b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f72d9f3def738b0b374b7a7534021b8a7d6a02c79590b5b9922a41933d1c532b", - "sequence_number": "7747399145951486354", + "sender": "e525149bd1029f4fc46f14aa3ed67109bb66af459a377267494b83f05048cd7f", + "sequence_number": "17142836387107613736", "payload": { "Script": { - "code": "8f2eac", + "code": "c4ffbfa6c3244d9fcadcb20c0612", "ty_args": [ { "vector": { "struct": { - "address": "410ccc541f5f4d9fd25f6b291d95e8afe20dd4eded4dd512866e415733125fbf", - "module": "zs", - "name": "SrLImwwtahmuJRUuSEbPKKHlycyZpn5", + "address": "59ecdd64d239ace94e3979b7c5963c95d4af3612d839e8c4ae601d1c6e72ae0d", + "module": "KBMXWmsqhhqHJtBJE2", + "name": "nrr", "type_args": [] } } + } + ], + "args": [ + { + "Address": "1e3747702f94ebde1778d62e03786317014a753834427c29fb241a67904a2fe5" }, + { + "U128": "320905206663419734484647629456963149928" + } + ] + } + }, + "max_gas_amount": "17715802104690965765", + "gas_unit_price": "17403895568628907430", + "expiration_timestamp_secs": "12646372252762467533", + "chain_id": 79 + }, + "signed_txn_bcs": "e525149bd1029f4fc46f14aa3ed67109bb66af459a377267494b83f05048cd7f28ac3010de96e7ed000ec4ffbfa6c3244d9fcadcb20c061201060759ecdd64d239ace94e3979b7c5963c95d4af3612d839e8c4ae601d1c6e72ae0d124b424d58576d7371686871484a74424a4532036e72720002031e3747702f94ebde1778d62e03786317014a753834427c29fb241a67904a2fe50268202ef31024b55a6a7927193d186cf105fd38e1262cdbf5a6fd1e54cf0e87f1cd6c437f8ff080af4f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e02bff099011ee805ba1ed112949bdb15ec9c38a61d3a749b4be2db65450a7e193a3bb7ea6734519d5ebbdd5e4030992b70c80923c19c49f66b24eebacb7fe0d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "08796761c3dfa0d73a786a96bd5639f57d041ba6adb827255508c7cf7eaa1e4f", + "sequence_number": "2295289120988170088", + "payload": { + "Script": { + "code": "371dd94ea40c8b4f1e79c8", + "ty_args": [ { "struct": { - "address": "9e12edf91b29e016be387b3edd57cea74af8737a6e2ba978e04f75484f43dea9", - "module": "kmiGvcEy", - "name": "TIpzIHqOVLUC2", + "address": "79bc62298b2ec2f2d8100fc7ae97a3b05bd13f928b11a1ab582ec703be173007", + "module": "BniIVqoMTp", + "name": "ocGbYChwQnAkSjMKSJcGAECaFkUxFiOv7", "type_args": [] } }, - { - "vector": "signer" - }, { "struct": { - "address": "0c01770935d275c2038ae020886649761c841d81c183b1901075b292c12c941e", - "module": "lmpIYFbHRaSvkxkFuh", - "name": "v2", + "address": "07e114a6506e1ec72f1a3e9829785b253a0def36be8ed2cf291ab88070ac8537", + "module": "azEMxjJSxvYIQiizNLVmxBzD3", + "name": "MexYMYlstiuVbJwEuHacQYbHnNJ", "type_args": [] } }, { - "vector": { - "vector": "u8" - } + "vector": "u8" }, { - "struct": { - "address": "19c59c35d3754a15ed133f7f0b564789b2ffd369ec71457c1705fd30bee25dab", - "module": "ISgWebuLdNZgHiBUkyGFDQ5", - "name": "QnvjRaJ6", - "type_args": [] + "vector": { + "struct": { + "address": "608d96146cbd7f5825a07586606e1ceea473e3b7b27ae95aec0b85a9ba6868e9", + "module": "OBElTBLFDTdknTpRURynXZdzQP4", + "name": "mnJIxZCIhWfLEVkTVBN", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "4957806cfe9daa528f82ab81e6151f1a487309f6e4df1a3da4b7d9c91711142a", - "module": "hhLmHbpQGXYLrQhRDAKCaFt1", - "name": "CdP5", + "address": "874fb484ea2cc5b62972fd201f57a52978e2cc6165e38f8ce51feb7c9b8fe4f9", + "module": "FKwZipwRsWjY", + "name": "pTlYCkoRcFrXZGupMCkYEzQV", "type_args": [] } } }, + { + "vector": "address" + }, { "struct": { - "address": "cc990406c9acecf0c27fcd5573b92018d2fceab2ed587af7ae44be9df31a349f", - "module": "cJYAeSuwUY4", - "name": "AsYFZxnQnqlUWWswANdhRPBVNFkL5", + "address": "748207cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee7", + "module": "jFzbxnSMbgiLqKaLD8", + "name": "HLVbUkHVlsVtf9", "type_args": [] } } ], "args": [ { - "U128": "10208642586978738564512370034247999400" - }, - { - "U8Vector": "ad" - }, - { - "Address": "7b3fa80afacdb4b7042b0d58ea675073945cd4d3eaac05e7f48e3922632a09a0" - }, - { - "U64": "17312150182304003873" - }, - { - "Address": "81b1c7746db97cfced0723a5fa65d18862eb74e1b7ffc7729c866811df9d38e9" + "U8": 112 } ] } }, - "max_gas_amount": "8974567084832537115", - "gas_unit_price": "12238280730371531235", - "expiration_timestamp_secs": "13505924667837049376", - "chain_id": 255 + "max_gas_amount": "7037993816267440905", + "gas_unit_price": "5634125986179912929", + "expiration_timestamp_secs": "3808962854621067214", + "chain_id": 64 }, - "signed_txn_bcs": "f72d9f3def738b0b374b7a7534021b8a7d6a02c79590b5b9922a41933d1c532b92619acb794a846b00038f2eac080607410ccc541f5f4d9fd25f6b291d95e8afe20dd4eded4dd512866e415733125fbf027a731f53724c496d77777461686d754a525575534562504b4b486c7963795a706e3500079e12edf91b29e016be387b3edd57cea74af8737a6e2ba978e04f75484f43dea9086b6d6947766345790d5449707a4948714f564c554332000605070c01770935d275c2038ae020886649761c841d81c183b1901075b292c12c941e126c6d704959466248526153766b786b467568027632000606010719c59c35d3754a15ed133f7f0b564789b2ffd369ec71457c1705fd30bee25dab17495367576562754c644e5a67486942556b79474644513508516e766a52614a360006074957806cfe9daa528f82ab81e6151f1a487309f6e4df1a3da4b7d9c91711142a1868684c6d486270514758594c7251685244414b436146743104436450350007cc990406c9acecf0c27fcd5573b92018d2fceab2ed587af7ae44be9df31a349f0b634a5941655375775559341d417359465a786e516e716c5557577377414e6468525042564e466b4c35000502a81f78107e09318881ff0f84f01cae070401ad037b3fa80afacdb4b7042b0d58ea675073945cd4d3eaac05e7f48e3922632a09a00121b771fadd1c41f00381b1c7746db97cfced0723a5fa65d18862eb74e1b7ffc7729c866811df9d38e91b3a5be036118c7ce3a14dab7b1bd7a920ea9c8dedae6ebbff002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ebe889e36791a5c05f91e9509e5ef17d314dd8163ea9a201e644696a4b57af5fc1ec571bc3232c780bec24e9f74e78388e5f87f087dd854d589f3c4616fdb80f", + "signed_txn_bcs": "08796761c3dfa0d73a786a96bd5639f57d041ba6adb827255508c7cf7eaa1e4f688751694b81da1f000b371dd94ea40c8b4f1e79c8070779bc62298b2ec2f2d8100fc7ae97a3b05bd13f928b11a1ab582ec703be1730070a426e694956716f4d5470216f63476259436877516e416b536a4d4b534a634741454361466b557846694f7637000707e114a6506e1ec72f1a3e9829785b253a0def36be8ed2cf291ab88070ac853719617a454d786a4a53787659495169697a4e4c566d78427a44331b4d6578594d596c7374697556624a774575486163515962486e4e4a0006010607608d96146cbd7f5825a07586606e1ceea473e3b7b27ae95aec0b85a9ba6868e91b4f42456c54424c464454646b6e5470525552796e585a647a515034136d6e4a49785a43496857664c45566b5456424e000607874fb484ea2cc5b62972fd201f57a52978e2cc6165e38f8ce51feb7c9b8fe4f90c464b775a6970775273576a591870546c59436b6f52634672585a4775704d436b59457a515600060407748207cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee7126a467a62786e534d6267694c714b614c44380e484c5662556b48566c7356746639000100700943044616faab61e1140dcabb6f304eceb758188927dc3440002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440006c8b59051e3a56aa0fe8420cf7d151a121131580650eea0a9ff234b64a5dfb5ec2b7c83bffa74a806ac8e1a94433cb94a04c5578ecbbf08444906ff541840e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d1e5dc19f001ae32443bcb34a32c3d8a700c65c09342b3f48ac631fd79f3c417", - "sequence_number": "8739409712431927954", + "sender": "2134d8254bc405ccaa6ca9cfdea59a0331985b4c51fbf458850323d333fe6f90", + "sequence_number": "11273164043936601406", "payload": { "Script": { - "code": "7f506fb9b7b087c3a04c", + "code": "0fb6e140a345efabef8c", "ty_args": [ + { + "struct": { + "address": "6ef66904cd56087b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f", + "module": "Rqgc", + "name": "SQ", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "d122646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa831389", + "module": "mQvdIVpcRVFaQoa", + "name": "BxWBSJh4", + "type_args": [] + } + } + }, { "vector": { "vector": { "struct": { - "address": "505492d6d3d42002b608d225b5ee33d13ca3f036c36d4d7a84963d823c56d08e", - "module": "nxHCQJnXqWvZAtVrSW", - "name": "WXibNzVpoXHFfNzTAPxA2", + "address": "173582243bcbc79c1b68823512e8dddcf82138c3b5e11252b22decf525f13c0d", + "module": "BcHQNvGWOYGROrG", + "name": "dNKEVnvfZHzZXKotoT", "type_args": [] } } @@ -6143,1088 +6606,1216 @@ }, { "struct": { - "address": "4474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e", - "module": "fPROplAQR3", - "name": "BdJcspIEAxrSpNxNHkXSUeqdKvO0", + "address": "7854086b46eb5c753037bfbdc3a568cd2ddc23a50a8fde6234cc98eef41c1a8f", + "module": "nMiE", + "name": "hVgr7", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "0a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73", + "module": "FAhOANFOTjpR", + "name": "H", + "type_args": [] + } } }, { "struct": { - "address": "5a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b", - "module": "epPFGCJFNr", - "name": "JFcjqMaInQD6", + "address": "22dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c", + "module": "lHAkawXUQaNWTIovCKxwNrqzrV", + "name": "LZEmkKROvwJaoqSkliLmSDNVJJPHcjP", "type_args": [] } }, { - "vector": { - "struct": { - "address": "c6207e6170b9e5b9224cfcdb4710f87e24950d711f8e218ad131cf0cefba17c1", - "module": "vaAEkpBhDTazIxHhpuVRk", - "name": "SNvrFvGeaKaiCPdjZ", - "type_args": [] - } + "struct": { + "address": "fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f2", + "module": "pVsvVQfbPvx1", + "name": "IJykNT", + "type_args": [] + } + }, + { + "struct": { + "address": "93714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de97", + "module": "HLtKraXORTK1", + "name": "GTiSSKaApmlRPlrjTrnuOL7", + "type_args": [] } }, { "struct": { - "address": "5831fdeef9a88830947725a17ded113832ed5d6412495fc7a35f2f25843115b0", - "module": "LA3", - "name": "olEEKEEWUaNmVpJAvdWsAS", + "address": "ba567c0f7c361d0fd2ef324b6f1b584ab56a94a27702704a353b36769e412dbe", + "module": "IbhYQgjqUc7", + "name": "AHhzyvJJzWcGL", "type_args": [] } }, { "struct": { - "address": "831184a076a98e25d5fa2a1ae7c0e8ecbc490da7533bc8d2199fb0a33416ab97", - "module": "NMYXQnYaDUZgHO", - "name": "uTDnZiSlelWQz", + "address": "4943c75e5cd666a9003f3ba5e3b1cd624d3458ef907851a500db640fca47db8b", + "module": "GuxRmIlq0", + "name": "JDsfBekBKnXpu1", "type_args": [] } } ], - "args": [] + "args": [ + { + "U64": "18166531275790253375" + }, + { + "Bool": true + }, + { + "U64": "1966265504895757521" + }, + { + "U8": 47 + }, + { + "Bool": false + }, + { + "U128": "339730435431780618589547627944501577736" + }, + { + "Address": "8b86227a5f79904155609c7f6edab6e7d1368bb06fe078e9b62d99b884253a46" + }, + { + "Address": "8496f0a3239bdffe2e82c1c25e1e03e436d0ac7b54dcb4823adc5740a858266b" + } + ] } }, - "max_gas_amount": "399246007634378942", - "gas_unit_price": "4462090929251500417", - "expiration_timestamp_secs": "11258660708475125563", - "chain_id": 124 + "max_gas_amount": "16773073868372672270", + "gas_unit_price": "5453199651213076556", + "expiration_timestamp_secs": "11489967142195648349", + "chain_id": 213 }, - "signed_txn_bcs": "d1e5dc19f001ae32443bcb34a32c3d8a700c65c09342b3f48ac631fd79f3c41792921a80d49e4879000a7f506fb9b7b087c3a04c07060607505492d6d3d42002b608d225b5ee33d13ca3f036c36d4d7a84963d823c56d08e126e784843514a6e587157765a41745672535715575869624e7a56706f584846664e7a54415078413200074474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e0a6650524f706c415152331c42644a637370494541787253704e784e486b5853556571644b764f3000060604075a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b0a6570504647434a464e720c4a46636a714d61496e514436000607c6207e6170b9e5b9224cfcdb4710f87e24950d711f8e218ad131cf0cefba17c115766141456b7042684454617a49784868707556526b11534e767246764765614b61694350646a5a00075831fdeef9a88830947725a17ded113832ed5d6412495fc7a35f2f25843115b0034c4133166f6c45454b45455755614e6d56704a417664577341530007831184a076a98e25d5fa2a1ae7c0e8ecbc490da7533bc8d2199fb0a33416ab970e4e4d5958516e596144555a67484f0d7554446e5a69536c656c57517a0000be400aef20688a05814187190f88ec3d3bbf4e6f43cc3e9c7c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404277cb4b2ecb638c7aaa3d07fedb21cd3d1446fe2d4e50822639c1ff4dca497ee1a6beafff673bcb627a900699218e34c726cfc25c7d16a39436b10ead42d20e", + "signed_txn_bcs": "2134d8254bc405ccaa6ca9cfdea59a0331985b4c51fbf458850323d333fe6f903e158c5df852729c000a0fb6e140a345efabef8c0a076ef66904cd56087b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f0452716763025351000607d122646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313890f6d5176644956706352564661516f610842785742534a683400060607173582243bcbc79c1b68823512e8dddcf82138c3b5e11252b22decf525f13c0d0f426348514e7647574f5947524f724712644e4b45566e76665a487a5a584b6f746f5400077854086b46eb5c753037bfbdc3a568cd2ddc23a50a8fde6234cc98eef41c1a8f046e4d69450568566772370006070a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc730c4641684f414e464f546a70520148000722dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c1a6c48416b6177585551614e5754496f76434b78774e72717a72561f4c5a456d6b4b524f76774a616f71536b6c694c6d53444e564a4a5048636a500007fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f20c70567376565166625076783106494a796b4e54000793714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de970c484c744b7261584f52544b311747546953534b6141706d6c52506c726a54726e754f4c370007ba567c0f7c361d0fd2ef324b6f1b584ab56a94a27702704a353b36769e412dbe0b4962685951676a715563370d4148687a79764a4a7a5763474c00074943c75e5cd666a9003f3ba5e3b1cd624d3458ef907851a500db640fca47db8b09477578526d496c71300e4a44736642656b424b6e587075310008013f7d80e6f17b1cfc050101d16c6a190f94491b002f05000208086c400a38cd95ef1ba736adb395ff038b86227a5f79904155609c7f6edab6e7d1368bb06fe078e9b62d99b884253a46038496f0a3239bdffe2e82c1c25e1e03e436d0ac7b54dcb4823adc5740a858266b0e7fbdd3d0edc5e84ce8d6c330a8ad4b5d577b473d90749fd5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d4da2863fb7d0302791812ff14f0b4bdfeef65b3fc36ee7f1b59f15d7bd8164691aa8d87f77995edb17eb7d4984a3252546527bcf5865e3e3b864f3f5ab5d90a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bfe4cb128df10e145d28d1b17c93023af18197f7508c755edf2089a4d31832d0", - "sequence_number": "9536922386635308482", + "sender": "0411361366dce3abb32fe8a55af3438e90514f5f0a5b56625f96ce658b1a7627", + "sequence_number": "6973500397045173521", "payload": { "Script": { - "code": "ba0b8fb6f9cf", + "code": "6f", "ty_args": [ { "struct": { - "address": "88d0f332f949254dc9194001db868ffe473ac72580408242aae127e9a9b34055", - "module": "upqHSLcVSifFqNbLF4", - "name": "ZqbTzbDFdYwuvluoOrS", + "address": "be1b1a30034a1689991761f989853f123536267bc6ab24a681191055009a412f", + "module": "QSB", + "name": "ZGbetbzJsmMvpJRAoVQW2", "type_args": [] } }, { - "vector": { - "vector": "bool" + "struct": { + "address": "182f37ced1c4ab08188b55b2f7977c43d83611a18dd07aa577fa44f7bf5784e9", + "module": "FTXKTijikfOinbDWPuynSPat5", + "name": "qJyvCxVEnTUVHPRawFhENOyhyEEtjwY", + "type_args": [] } }, { - "vector": "bool" + "vector": "u64" }, { "struct": { - "address": "0b54d3bb94e052a7185a43c0c575b7d45dffbb236b46f98996a0325984810454", - "module": "adWQXtMtacjViLhug7", - "name": "MbtgicogQgVIXBZHIQmUIRzh4", + "address": "327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c", + "module": "QowCjPkDpjgbmkipk3", + "name": "uR2", "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": "address" } }, { - "struct": { - "address": "ca8485b992043dc3da8c82b9f961b520b14b088a48f00da722803212935bc604", - "module": "WSrGGmnMl7", - "name": "pkYlSVUkzcldiewqpgxqslSuILJsGwNy", - "type_args": [] + "vector": { + "struct": { + "address": "569775b184bf4beb0327611aa621b1712c302aa774b4779e15479c681087808c", + "module": "wubCfjkaZACnlAe", + "name": "SRtfqxNwNFKTFpLHdFYORtNkFrhoOOiS4", + "type_args": [] + } } }, { - "vector": "u64" + "vector": { + "struct": { + "address": "9da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e", + "module": "sTcxImSQiLOXChkjwGvNrWZc8", + "name": "YjpAOWYUzqPRPAx", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "37e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e787", + "module": "dGMGHGeUvnWQlWCVtX7", + "name": "sVbznwxXoNAINJOd0", + "type_args": [] + } + } } ], "args": [ { - "Bool": false + "U64": "4326550357321837148" }, { "Bool": false }, { - "Bool": false + "Address": "83949bca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e" }, { - "Bool": false + "U64": "9196770266735518645" + }, + { + "U128": "184753456356789213655870323073355165438" + }, + { + "U8": 119 + }, + { + "Bool": true + }, + { + "U8Vector": "5a76fab9a295fdd469dfbab43e74" }, { - "U8": 155 + "U8": 0 + }, + { + "Address": "78e619c7511b7132ce6b019bddd2dfc9d9364cc4affa679cfdfc78ea88088782" } ] } }, - "max_gas_amount": "12997735213505085827", - "gas_unit_price": "3433525629701912474", - "expiration_timestamp_secs": "3280625629164775885", - "chain_id": 241 + "max_gas_amount": "2895609843429665187", + "gas_unit_price": "11826031002099742760", + "expiration_timestamp_secs": "13341225763917567843", + "chain_id": 77 }, - "signed_txn_bcs": "bfe4cb128df10e145d28d1b17c93023af18197f7508c755edf2089a4d31832d0c23ddec161f459840006ba0b8fb6f9cf070788d0f332f949254dc9194001db868ffe473ac72580408242aae127e9a9b340551275707148534c635653696646714e624c4634135a7162547a62444664597775766c756f4f7253000606000600070b54d3bb94e052a7185a43c0c575b7d45dffbb236b46f98996a0325984810454126164575158744d7461636a56694c68756737194d62746769636f675167564958425a4849516d5549527a68340006060107ca8485b992043dc3da8c82b9f961b520b14b088a48f00da722803212935bc6040a57537247476d6e4d6c3720706b596c5356556b7a636c646965777170677871736c5375494c4a7347774e79000602050500050005000500009b83818ecd4f3b61b49af7945d5e55a62fcda968d3a01f872df1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440446e12bce40a7c14eb6658a112c9e74df6ff1b13c3d2d9e2ff1f924d52f626444506a543aa5e9c325c3f67de9cebb98e51eda015fc864a0ee7654abc27f38d02", + "signed_txn_bcs": "0411361366dce3abb32fe8a55af3438e90514f5f0a5b56625f96ce658b1a7627114decf6a9d9c66000016f0807be1b1a30034a1689991761f989853f123536267bc6ab24a681191055009a412f03515342155a47626574627a4a736d4d76704a52416f565157320007182f37ced1c4ab08188b55b2f7977c43d83611a18dd07aa577fa44f7bf5784e9194654584b54696a696b664f696e6244575075796e53506174351f714a7976437856456e54555648505261774668454e4f7968794545746a775900060207327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c12516f77436a506b44706a67626d6b69706b3303755232000606040607569775b184bf4beb0327611aa621b1712c302aa774b4779e15479c681087808c0f77756243666a6b615a41436e6c4165215352746671784e774e464b5446704c486446594f52744e6b4672686f4f4f6953340006079da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e1973546378496d5351694c4f5843686b6a7747764e72575a63380f596a70414f5759557a71505250417800060737e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e7871364474d4748476555766e57516c574356745837117356627a6e7778586f4e41494e4a4f6430000a015cea017fa0fe0a3c05000383949bca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e01b523a5bdd47da17f02fe2e25b4c4df83906cf77130ad38fe8a00770501040e5a76fab9a295fdd469dfbab43e7400000378e619c7511b7132ce6b019bddd2dfc9d9364cc4affa679cfdfc78ea88088782a3e9bf9dcf452f282878e9168a801ea4639798be258e25b94d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ddc1d9a29325cf44f9320704dc2e71c96fbdd585186821f7e10f513f1ddb131957aea343926fb4e392f2001c235bb6d673b74f3592090f6edcc585956698e206", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a83b178defbdb6dada0889078f964732cacf7ca9ec7618de05438e93bcdfac48", - "sequence_number": "13732763229123254603", + "sender": "f7b0abca0ab8240a29b81c62d6474900d61a512fd5072a6326d3a1c8d44cfabc", + "sequence_number": "2824333326381802296", "payload": { "Script": { - "code": "efddd2", + "code": "ad9b5be7c5c70ef9bbad0debf2", "ty_args": [ { - "vector": { - "vector": { - "vector": { - "vector": "address" - } - } + "struct": { + "address": "c436baf14dcecc5e1ca161c35a3a5c8a16b3607052914fa51bf713d35bbac9e4", + "module": "qGTdWwVoaGqVYXYNOYOxVSTsdJo0", + "name": "koQwMjeBQtJjAFZHJkHQsJh7", + "type_args": [] } }, { "struct": { - "address": "668932d808b604101a2ba5a4e3372c4483f2311ef9da69bdb16a55b061b84c49", - "module": "l2", - "name": "nCAdbJhJWpykdKykSZlSRBbXYszj2", + "address": "a3251b4cff7348a2a51c9ebc219890800a8938d3946d84df48f6032b88b9c611", + "module": "VqNGPDlBmrwxZbtxhPwWDSM5", + "name": "shjzgoysFMQuFcoSXEFgEW1", "type_args": [] } }, { "vector": { - "struct": { - "address": "39410dc16318fc5a75a123ed54af40f2c41cfde253f2da25b408b1ca0c9ef246", - "module": "o8", - "name": "pEGncqbqrKRQwulvCcQnk5", - "type_args": [] - } + "vector": "u8" } }, { "struct": { - "address": "22688f8ce4ffe443e1859d2c18b9a898feb35ab364dd8244539488f5bc7525af", - "module": "jWpLdrmJiHrqJXapyYWhwHhdxChSXFtL", - "name": "qcj", + "address": "710025aa324fee54bef9a2dda3af9629266447a96c5aba9e960fbe9835d9782b", + "module": "DpUtUADPLsIgqJXQieNyuMyCZkrzv3", + "name": "OEwYFfPbfDGOOeuVY", "type_args": [] } - } - ], - "args": [ + }, { - "U8": 196 + "struct": { + "address": "40d5143bfd1bd052d04f49c8f979699cdd66ccb633d75ab9268273a5e589d4b5", + "module": "dgSEMBozEBPYByYaRUCqPUQSl", + "name": "E2", + "type_args": [] + } }, { - "U64": "13778504220115306745" + "struct": { + "address": "deb10d4a9040182aa948ea0420c690896371806276c54c326b837e85eaab506e", + "module": "ZDJ", + "name": "FThIAWTCaHVeoCdfgbyexhoSgYRIuhG2", + "type_args": [] + } }, { - "Address": "5b79dd8c597e168948c87b6b9c90caba3827cef831c89c861867033cd8269aed" + "vector": { + "struct": { + "address": "59d5464e58793bbb67c19996a5934f58e45946ed5162226efe5c478a4de2d4f8", + "module": "pNQON", + "name": "hAKXFhnxtKxGCQyIkmUpBWdmivXcMMHh9", + "type_args": [] + } + } + } + ], + "args": [ + { + "U64": "16526179801449030834" }, { - "Address": "54a7a285fcf24bc6bd854f703e268769bd160e36d2e0d22c0e537e89cbb3a3b1" + "Address": "ecb01e48b014fae2035255f3999b864001a431b772e49ffdf1f669f0a7e7e572" }, { - "U64": "1106225910981390324" + "U8": 229 } ] } }, - "max_gas_amount": "11345108606844796263", - "gas_unit_price": "16552614547007878935", - "expiration_timestamp_secs": "12172438902837304755", - "chain_id": 214 + "max_gas_amount": "2550987853934352734", + "gas_unit_price": "13158722821141889234", + "expiration_timestamp_secs": "1644979020586007368", + "chain_id": 27 }, - "signed_txn_bcs": "a83b178defbdb6dada0889078f964732cacf7ca9ec7618de05438e93bcdfac484b1970c8659394be0003efddd204060606060407668932d808b604101a2ba5a4e3372c4483f2311ef9da69bdb16a55b061b84c49026c321d6e434164624a684a5770796b644b796b535a6c535242625859737a6a3200060739410dc16318fc5a75a123ed54af40f2c41cfde253f2da25b408b1ca0c9ef246026f38167045476e63716271724b525177756c764363516e6b35000722688f8ce4ffe443e1859d2c18b9a898feb35ab364dd8244539488f5bc7525af206a57704c64726d4a694872714a5861707959576877486864784368535846744c0371636a000500c401f9883128961437bf035b79dd8c597e168948c87b6b9c90caba3827cef831c89c861867033cd8269aed0354a7a285fcf24bc6bd854f703e268769bd160e36d2e0d22c0e537e89cbb3a3b101f4ef60e19a1a5a0f67fd35412bec719d17375e223bb3b6e5b35dc395b030eda8d6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440663393fb528485f6409924f0538ffd484d013ca13851286b050a7f9e7f5938917e1eaffefd08cab408ac2c805fa5a2555013f9e3d22bfb006655a81a9649240a", + "signed_txn_bcs": "f7b0abca0ab8240a29b81c62d6474900d61a512fd5072a6326d3a1c8d44cfabc38e34846320c3227000dad9b5be7c5c70ef9bbad0debf20707c436baf14dcecc5e1ca161c35a3a5c8a16b3607052914fa51bf713d35bbac9e41c714754645777566f614771565958594e4f594f7856535473644a6f30186b6f51774d6a654251744a6a41465a484a6b4851734a68370007a3251b4cff7348a2a51c9ebc219890800a8938d3946d84df48f6032b88b9c6111856714e4750446c426d7277785a6274786850775744534d351773686a7a676f7973464d517546636f53584546674557310006060107710025aa324fee54bef9a2dda3af9629266447a96c5aba9e960fbe9835d9782b1e44705574554144504c734967714a585169654e79754d79435a6b727a7633114f457759466650626644474f4f65755659000740d5143bfd1bd052d04f49c8f979699cdd66ccb633d75ab9268273a5e589d4b519646753454d426f7a454250594279596152554371505551536c0245320007deb10d4a9040182aa948ea0420c690896371806276c54c326b837e85eaab506e035a444a204654684941575443614856656f4364666762796578686f53675952497568473200060759d5464e58793bbb67c19996a5934f58e45946ed5162226efe5c478a4de2d4f805704e514f4e2168414b5846686e78744b7847435179496b6d55704257646d697658634d4d486839000301b2e49a4ff8c858e503ecb01e48b014fae2035255f3999b864001a431b772e49ffdf1f669f0a7e7e57200e55ed917fcefed6623d200fd1bb02c9db648bbff28b423d4161b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dcdfb5820c1b30c138bc9968da95cedde5e972dee62cd62f41544a1364589544238bb3b3400d150a5391d5d00fe4928c734b865e0cb4a27179295653da21bc03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "56cfa34ca1b88841d37f126e6557a40e2881b56b886477aea098021707b5b789", - "sequence_number": "2661617152235426414", + "sender": "2bfcfd9c3016c935ab35627dd38b5eeea514cbb5c0a13748783edcc42f4f4543", + "sequence_number": "17728406288952106544", "payload": { "Script": { - "code": "f68912", + "code": "c291", "ty_args": [ { "vector": { "vector": { - "struct": { - "address": "56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56e6", - "module": "RvFzUidMBlIjvdsVlIhN", - "name": "XbbMWCEAgDpglKDPWjEN", - "type_args": [] - } + "vector": "address" } } }, + { + "struct": { + "address": "357bfa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e6", + "module": "sIDMzQlNLpIWaeVkP1", + "name": "AuIsyvsdHgwbBFxPxR5", + "type_args": [] + } + }, { "vector": { "vector": { - "vector": { - "struct": { - "address": "09b85a76927f05df7713216b6297ccf67f215f865caca6dfdbed9692f491ad78", - "module": "WlbDHBmVOZpqUseRWKEOP9", - "name": "tggAOCgXGeMhR3", - "type_args": [] - } - } + "vector": "u64" } } }, { "struct": { - "address": "17db59bfa5590f5ec7e79a64ef418573571d7cf587aba84e1b9f16509e391825", - "module": "uWBKkPkBPBLUUJOaErcrkBqzldumkAqm9", - "name": "OtsOqJIhdiAcikMBwRZlnh", + "address": "5d3af3303e4f1cb584d8866e191cb93d8712947b6248af9973731558c46e4232", + "module": "NLXzJBaymCLGDyKnbdivYMCnQtNKt7", + "name": "PwmdAaJnNKAkKnKkCgyYUYbj", "type_args": [] } }, { "struct": { - "address": "00f0656f48c37c8cccd3e3863cd8d1acb3cb49bb5fc3d1cbe20070842c52a538", - "module": "pagraxyxbvBPODGdZUiydCPiLkXeXJts", - "name": "efBwmxWfsbFtn8", + "address": "cdc9de0778287782d575545f39181b9e9d5a73bf50343a53f50e18baec8edbea", + "module": "vrxGHpGF", + "name": "F9", "type_args": [] } }, + { + "vector": { + "vector": { + "struct": { + "address": "dabeb8f45f4fde087997371f7fdf3f3359925cc9bedfd6077defcc6503199de5", + "module": "uQMgueUHHSTdNZPKeFEAwpsXxQ9", + "name": "wNNRBfFg", + "type_args": [] + } + } + } + }, { "struct": { - "address": "645904bfe308e5c742eafd74823ed8c6ec6f17ec84c35c40fa2cce49bd01887e", - "module": "tl6", - "name": "kNMWnpu", + "address": "300f1e392c363a797dc1becfc4c9c2c25025568e4478174efb226a5b43b11ff2", + "module": "uVfPoqthstxajLKPCVLWqyTlbfocpGF4", + "name": "VOfoDMs4", "type_args": [] } }, { "vector": { - "vector": "u128" + "struct": { + "address": "2cdbce8cca373ea765fa811e67acb46b499514332d51a05e2b800ffb28d12aa7", + "module": "ilUQyaRzpRSPTap7", + "name": "qfRtXDbJzDrAPObzt", + "type_args": [] + } } }, { "struct": { - "address": "e7c6d5328605060187182c7102c18467e94e2682b8ad62fe3a84b0b685099232", - "module": "oWDLjWQgDJKjCNSTrEvD", - "name": "JccfpTHzyjDaownTckKvtHm9", + "address": "5629c2f4a048917feb30482a26b16caf9e8a365f39bc77c3fdcf0d9c80673ae6", + "module": "fWShWPnshxXsYYFq", + "name": "DLVXhCgFcrgLrgRUDyWoLFVeZabHu9", "type_args": [] } } ], "args": [ { - "Address": "f55b231ad5722bb091953b75fe65f4414a87c549bd11b0e0944f6db788d8ac70" - }, - { - "U64": "18131286182979262564" - }, - { - "U64": "16511952788643100658" - }, - { - "Address": "8e24b2d7fa65b3a316c53ff4405438b77ea313f2f952e1b27211a8d4e55d5d3e" - }, - { - "U8": 57 - }, - { - "Bool": true - }, - { - "Address": "97e90fd47cc5733b0f835bc7fb1d80ee6f5fc5e01d3da28d8713d0bc470ba0df" - }, - { - "Bool": true - }, - { - "U128": "302950496867062496659949831159537244545" + "Address": "5e0faf71c1ce1633d8cc0a5625b2fcdf7214f754df6b097ae011802e301b0141" } ] } }, - "max_gas_amount": "4433652520108920145", - "gas_unit_price": "1517921566327502147", - "expiration_timestamp_secs": "17462184974355895389", + "max_gas_amount": "7247968693703850901", + "gas_unit_price": "698183644497723964", + "expiration_timestamp_secs": "2291547024516551779", "chain_id": 70 }, - "signed_txn_bcs": "56cfa34ca1b88841d37f126e6557a40e2881b56b886477aea098021707b5b7896e5214b7b2f6ef240003f689120706060756e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56e6145276467a5569644d426c496a766473566c49684e145862624d57434541674470676c4b4450576a454e000606060709b85a76927f05df7713216b6297ccf67f215f865caca6dfdbed9692f491ad7816576c624448426d564f5a707155736552574b454f50390e746767414f43675847654d685233000717db59bfa5590f5ec7e79a64ef418573571d7cf587aba84e1b9f16509e391825217557424b6b506b4250424c55554a4f61457263726b42717a6c64756d6b41716d39164f74734f714a496864694163696b4d4277525a6c6e68000700f0656f48c37c8cccd3e3863cd8d1acb3cb49bb5fc3d1cbe20070842c52a538207061677261787978627642504f4447645a556979644350694c6b5865584a74730e656642776d785766736246746e380007645904bfe308e5c742eafd74823ed8c6ec6f17ec84c35c40fa2cce49bd01887e03746c36076b4e4d576e70750006060307e7c6d5328605060187182c7102c18467e94e2682b8ad62fe3a84b0b685099232146f57444c6a575167444a4b6a434e535472457644184a6363667054487a796a44616f776e54636b4b7674486d39000903f55b231ad5722bb091953b75fe65f4414a87c549bd11b0e0944f6db788d8ac700164586d41b8449ffb01f2b717c3933d26e5038e24b2d7fa65b3a316c53ff4405438b77ea313f2f952e1b27211a8d4e55d5d3e003905010397e90fd47cc5733b0f835bc7fb1d80ee6f5fc5e01d3da28d8713d0bc470ba0df05010281993c2feadbe79bf6d89c21b324eae3518d9bfe797f873d43f5da4d9fbd10155d94a52eb72456f246002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aff566ff82b5142d364486805177f71e286502882478aa702652cf6e6050252dbab491d3ec7d040a818ec9fdd01455ada5cf4fd3c014c6038e6477f152b7b30d", + "signed_txn_bcs": "2bfcfd9c3016c935ab35627dd38b5eeea514cbb5c0a13748783edcc42f4f4543309eca3697f307f60002c291090606060407357bfa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e6127349444d7a516c4e4c7049576165566b503113417549737976736448677762424678507852350006060602075d3af3303e4f1cb584d8866e191cb93d8712947b6248af9973731558c46e42321e4e4c587a4a4261796d434c4744794b6e62646976594d436e51744e4b74371850776d6441614a6e4e4b416b4b6e4b6b436779595559626a0007cdc9de0778287782d575545f39181b9e9d5a73bf50343a53f50e18baec8edbea08767278474870474602463900060607dabeb8f45f4fde087997371f7fdf3f3359925cc9bedfd6077defcc6503199de51b75514d6775655548485354644e5a504b654645417770735878513908774e4e52426646670007300f1e392c363a797dc1becfc4c9c2c25025568e4478174efb226a5b43b11ff220755666506f717468737478616a4c4b5043564c577179546c62666f637047463408564f666f444d73340006072cdbce8cca373ea765fa811e67acb46b499514332d51a05e2b800ffb28d12aa710696c55517961527a705253505461703711716652745844624a7a447241504f627a7400075629c2f4a048917feb30482a26b16caf9e8a365f39bc77c3fdcf0d9c80673ae6106657536857506e7368785873595946711e444c5658684367466372674c726752554479576f4c4656655a61624875390001035e0faf71c1ce1633d8cc0a5625b2fcdf7214f754df6b097ae011802e301b014195bb5e2320f595643c4246565372b009639469aee035cd1f46002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404233dfdb4234352bd2020519e8a2554f0faaf94b34df0795852d250ffc5f27d8ddc56d20c165d001d8c23fc1f850c9c59dc4b8d1a50a02c41b6272fba840af09", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "95a53b704ee1f8e73e4e246fab1d57bb6ab5a2a099b0972246d34a3d0a268b00", - "sequence_number": "15551757094686444239", + "sender": "ab2cc0e183ecc287a10596c3900a6057f651742884daad6b3e4bdf6c6d782a3d", + "sequence_number": "3872313872576232138", "payload": { "Script": { - "code": "6ae5c30e3ca525acabdf5983f3a17e7c", - "ty_args": [], - "args": [ + "code": "c9cbf5ee14fa", + "ty_args": [ { - "U8": 164 + "vector": "u128" }, { - "Bool": false + "struct": { + "address": "70bb4310288e401dd5d24b1630f9c1c19bccae220b9a177ef2ba0cd922f6ea5d", + "module": "C2", + "name": "lZrYaTwozjWekyb", + "type_args": [] + } }, { - "U8": 171 + "vector": "address" }, { - "U8": 152 + "struct": { + "address": "c0586a30923e198a0bb95df9da43d1b25c5a8fa578037443f9524ddd6da2d42a", + "module": "oogmjeeKjmcUDq8", + "name": "LXNngWBNnoGHBntTZse", + "type_args": [] + } }, { - "U64": "17461360269322427740" + "vector": { + "struct": { + "address": "e9477373e6cc9fc52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdd", + "module": "MrTJNooDIQdUbxnbvekJNX1", + "name": "wPJJLvwynzUzsI2", + "type_args": [] + } + } }, { - "U8Vector": "d11d4f1007cbeee4" - } - ] - } - }, - "max_gas_amount": "9394619420418217017", - "gas_unit_price": "4444541433715188081", - "expiration_timestamp_secs": "6573402207503295407", - "chain_id": 45 - }, - "signed_txn_bcs": "95a53b704ee1f8e73e4e246fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cf4af24daef0d2d700106ae5c30e3ca525acabdf5983f3a17e7c000600a4050000ab0098015c1d1594a63653f20408d11d4f1007cbeee43994038a96646082716119c2e22eae3dafa300f87a6a395b2d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440199ab2addd2a03c2f8b69beed26d5a0e9f1311e8e9b245e24140d4d5461f6a8d9778c5c35a87fb232097b6b4d810828c449e8b392a80e5b959f07db679e35506", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "54307a4673ffa5c3e0d43c442c5f4726745fbf423f4fc6d0a99af4a31d001f1d", - "sequence_number": "6856937665810920871", - "payload": { - "Script": { - "code": "fb6cd1c76f4ea8", - "ty_args": [ - { - "struct": { - "address": "c4ab6e294155b17791649b3594f56c69d562fa4dba0f0d2d35ad06a3ee650730", - "module": "Nth", - "name": "gPcCvzFSShzGowhIUk5", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } } }, { "struct": { - "address": "6478795882e33e5565d58dd8aa865e9e7eb2987a22616c23cd1901571a424f82", - "module": "xpuvrkKVYSkhNFLALaf1", - "name": "mnCQuVcHIpsGBJfV", + "address": "9b04392eafe7e207d9551ae84ddd28551ac1ff948393e09acf142a6d728c611b", + "module": "CgWtNPUgxZSKGhbWQFbU7", + "name": "ZvPucHYikMqg7", "type_args": [] } } ], "args": [ { - "U128": "98059321511487480325801574385003714109" - }, - { - "U64": "12468083047052168348" + "Address": "20cca3b087189deee3331d5adff745068ef1244bcc3dea1b95b4fadd88d40108" } ] } }, - "max_gas_amount": "12229459776087095658", - "gas_unit_price": "469563520749451787", - "expiration_timestamp_secs": "17094626840501200692", - "chain_id": 102 + "max_gas_amount": "8588131319440127613", + "gas_unit_price": "7322459796803828037", + "expiration_timestamp_secs": "11745573920069745845", + "chain_id": 90 }, - "signed_txn_bcs": "54307a4673ffa5c3e0d43c442c5f4726745fbf423f4fc6d0a99af4a31d001f1da7f5a7397abc285f0007fb6cd1c76f4ea80207c4ab6e294155b17791649b3594f56c69d562fa4dba0f0d2d35ad06a3ee650730034e74681367506343767a465353687a476f776849556b3500076478795882e33e5565d58dd8aa865e9e7eb2987a22616c23cd1901571a424f821478707576726b4b5659536b684e464c414c616631106d6e43517556634849707347424a66560002023dd6268c858c467b617f6620d289c549019c4c9df9788707ad6a799934dfc4b7a90bbac0c58839840634a7ee4b8a503ced66002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c98e15b4b00a2f36d4224f670ce13559db6b170f2f4457210decc276588dd8fd96df556c6761005e07dbceef39252ab6252f23a07a64f4a7dced45c23f5b870f", + "signed_txn_bcs": "ab2cc0e183ecc287a10596c3900a6057f651742884daad6b3e4bdf6c6d782a3dca3ab961f338bd350006c9cbf5ee14fa0706030770bb4310288e401dd5d24b1630f9c1c19bccae220b9a177ef2ba0cd922f6ea5d0243320f6c5a72596154776f7a6a57656b796200060407c0586a30923e198a0bb95df9da43d1b25c5a8fa578037443f9524ddd6da2d42a0f6f6f676d6a65654b6a6d6355447138134c584e6e6757424e6e6f4748426e74545a7365000607e9477373e6cc9fc52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdd174d72544a4e6f6f444951645562786e6276656b4a4e58310f77504a4a4c7677796e7a557a7349320006060605079b04392eafe7e207d9551ae84ddd28551ac1ff948393e09acf142a6d728c611b15436757744e505567785a534b4768625751466255370d5a765075634859696b4d71673700010320cca3b087189deee3331d5adff745068ef1244bcc3dea1b95b4fadd88d401087db6a2e3ee2b2f774539929e639a9e65b57cd9e43fa900a35a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409d5538754711d04e9d9b39c6845936b51cfed09de735197868b0ca5885b77737dc239f4dd514d6ac5a17d90273b93bcc1fcb7cd362fa4969e27d3ae3b41bfc0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9609bc85db874a966e97c96a33d7829f1ac9170802b93eecd7d43b561e3891be", - "sequence_number": "17687558104016224339", + "sender": "3729c5e3a74f6ec7a51d1a6774b86ead94d8726a8a08500d8ea476d56e9ca067", + "sequence_number": "12305060499781852653", "payload": { "Script": { - "code": "fb5f50d42e74", + "code": "83", "ty_args": [ - { - "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "u64" - } - }, - "u128", { "struct": { - "address": "4b921ff487969a24d4571b406d031ecf73f0e957b82ef97e5b902403b5e0af82", - "module": "mXJiAqzuxylBINpvkf", - "name": "McognWSTKwAshXNDRxJKDVGLeQR8", + "address": "6ccf83e014a223e796a90cea4f296cbb083f858d2ffaff5f66d6d44c2646700f", + "module": "HhwaXnGeINDGjhDAWCdHOGNLNFZb", + "name": "xTfgiugoHmrnSHNChOxjDmk", "type_args": [] } - }, + } + ], + "args": [ { - "vector": { - "struct": { - "address": "a3b76af16a405fb30fa9320e618171ccb5af821a6e097d61d07225e35b6dad3b", - "module": "SIUjfUEe5", - "name": "VlPzwlqaAsWAmFPxLOLRvhzcHRUjI7", - "type_args": [] - } - } + "Address": "0c5ef3bffebddbde6ea4ad2320eb01871952e9ab20ec28e64ef7571c3d22bbe4" }, { - "vector": { - "struct": { - "address": "507a39ff0c7865e44d50d4dc8f5eb39bee70f939fe7ad049c8f70bd096461b82", - "module": "RzDPRMo", - "name": "evkwoCqZRtgQQbwIJw", - "type_args": [] - } - } + "U8Vector": "dc25facd1897abb0d19ac6d6" }, { - "struct": { - "address": "c80ba36748f4d73b44c8b1f850d484285ab6bdcf840a96b4c97b83b834106a7e", - "module": "mhFAyVxDUDfFgXZL", - "name": "GVPwRYUGCLtpIvtrLsStaZTknkxDgz", - "type_args": [] - } + "U8Vector": "cc9f3a3d2b916eb8" }, { - "struct": { - "address": "c9fde90db3c04efc49815ce426d2e45ef2e466805d82cdf7a61aa6230a8e3f08", - "module": "AnbVOlaNYeLMSNFPdgPZvRJWMCpGLbpQ2", - "name": "lPZwFrPCiZmDT", - "type_args": [] - } + "U64": "14639135242141902991" }, { - "vector": { - "struct": { - "address": "2306889929128220567bb14c474c030215d41e4d2f2357cba4b315c522e0c260", - "module": "IhBgEyJbIisvtGTKYKl1", - "name": "OxcHQyXybjwAwMPsDSInsoghRXjCJ5", - "type_args": [] - } - } - } - ], - "args": [ - { - "Bool": true + "U64": "6842359644889251257" }, { - "U128": "280985065801775361285127062301290532394" + "U64": "7531166228595667584" }, { - "U64": "8144600650747321330" + "Address": "6e158bc58007be6517fc605439d8d6af5a859c66d291a4f0248576fae16302f2" }, { - "U64": "14648556027250784588" + "Address": "7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b426e1454cf" }, { - "U8Vector": "eaedf01c0242cd0bb7" + "U128": "99101526061378840795639220189646180090" }, { - "U64": "8564468921085257152" - }, + "U128": "251440031276578871427245521626970165109" + } + ] + } + }, + "max_gas_amount": "14794125858309214756", + "gas_unit_price": "17410790857721714324", + "expiration_timestamp_secs": "18199854647864929323", + "chain_id": 214 + }, + "signed_txn_bcs": "3729c5e3a74f6ec7a51d1a6774b86ead94d8726a8a08500d8ea476d56e9ca067ed1d305d545bc4aa00018301076ccf83e014a223e796a90cea4f296cbb083f858d2ffaff5f66d6d44c2646700f1c48687761586e4765494e44476a684441574364484f474e4c4e465a6217785466676975676f486d726e53484e43684f786a446d6b000a030c5ef3bffebddbde6ea4ad2320eb01871952e9ab20ec28e64ef7571c3d22bbe4040cdc25facd1897abb0d19ac6d60408cc9f3a3d2b916eb8018f28c5f6f0a728cb01b97d173bd8f1f45e0180f2dc77c8138468036e158bc58007be6517fc605439d8d6af5a859c66d291a4f0248576fae16302f2037abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b426e1454cf02fa4eaa0360f34942852fc7eb78428e4a02758f6778ec6dbe1fb0f200e8aa9629bd2412f1e2154b4fcd94161fed098e9ff12b2cbb1160df92fcd6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440151f1016b8fc14e1164b1ed22166820fde5861e9d46562f905e306c44ccf05765fb76ca22440683e59ed3f768b50b8d60452be2c1b8bff29cf3961f6c9b2950d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "016a3d46ad439f01a5f36d8e7ce11930576f48f4115971495837293e32eb8d16", + "sequence_number": "12046995388962542349", + "payload": { + "Script": { + "code": "808df58a87bdac1eeb", + "ty_args": [ { - "U128": "327396226602606374060509883176823284409" + "vector": { + "struct": { + "address": "b68417f1d65a9c3c373e7bcddd13d07ee1affcf953390c628a19c7ef9069bf99", + "module": "MhkWrRaGVGMYQMhsxfKHnUWv", + "name": "saCDsfEsXvJYbsmWWO2", + "type_args": [] + } + } }, { - "Bool": true - }, + "struct": { + "address": "9a85171dfae9f53f5dafb758db2930e24e227bff5e337c0701b7601de820a82b", + "module": "fYeJHUrf", + "name": "XUnxiyPhcPxCDrbDGxdlzPydExojrihd", + "type_args": [] + } + } + ], + "args": [ { - "Address": "0fadfac3e30fafba196a143987d11147c236868dd968dde0c7e05e4ccbafeb02" + "U8Vector": "e292774bde40fe8638fddce2" } ] } }, - "max_gas_amount": "8839770948383055560", - "gas_unit_price": "18074078266046854559", - "expiration_timestamp_secs": "16903064721136039343", - "chain_id": 6 + "max_gas_amount": "11627145617221000123", + "gas_unit_price": "3585734865993914012", + "expiration_timestamp_secs": "5928218249849684188", + "chain_id": 187 }, - "signed_txn_bcs": "9609bc85db874a966e97c96a33d7829f1ac9170802b93eecd7d43b561e3891be5300f80562d476f50006fb5f50d42e740906060506060203074b921ff487969a24d4571b406d031ecf73f0e957b82ef97e5b902403b5e0af82126d584a6941717a7578796c42494e70766b661c4d636f676e5753544b77417368584e4452784a4b4456474c65515238000607a3b76af16a405fb30fa9320e618171ccb5af821a6e097d61d07225e35b6dad3b095349556a66554565351e566c507a776c7161417357416d4650784c4f4c5276687a634852556a4937000607507a39ff0c7865e44d50d4dc8f5eb39bee70f939fe7ad049c8f70bd096461b8207527a4450524d6f1265766b776f43715a52746751516277494a770007c80ba36748f4d73b44c8b1f850d484285ab6bdcf840a96b4c97b83b834106a7e106d684641795678445544664667585a4c1e4756507752595547434c7470497674724c735374615a546b6e6b7844677a0007c9fde90db3c04efc49815ce426d2e45ef2e466805d82cdf7a61aa6230a8e3f0821416e62564f6c614e59654c4d534e46506467505a76524a574d4370474c627051320d6c505a7746725043695a6d44540006072306889929128220567bb14c474c030215d41e4d2f2357cba4b315c522e0c260144968426745794a62496973767447544b594b6c311e4f78634851795879626a7741774d50734453496e736f676852586a434a3500090501022a0eb83dee2922e7e654a5ca55c163d301f29b35d1236f0771014cb9b06c18204acb0409eaedf01c0242cd0bb701c0e528731b1bdb7602b9e2afe6abdc238495cb55f03a384ef60501030fadfac3e30fafba196a143987d11147c236868dd968dde0c7e05e4ccbafeb02c89e30aad72cad7a9fb554226c06d4faaf35c0becebf93ea06002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405a84979273b97ead3a414fbb416e6f92dec825035ed9b763f9864fe46560c4fb5a0b462f409555bc1f3eb89a0147a91fcc7fe138c176b06f1838445edb61a701", + "signed_txn_bcs": "016a3d46ad439f01a5f36d8e7ce11930576f48f4115971495837293e32eb8d160d93e1817a862fa70009808df58a87bdac1eeb020607b68417f1d65a9c3c373e7bcddd13d07ee1affcf953390c628a19c7ef9069bf99184d686b577252614756474d59514d687378664b486e55577613736143447366457358764a5962736d57574f3200079a85171dfae9f53f5dafb758db2930e24e227bff5e337c0701b7601de820a82b086659654a485572662058556e786979506863507843447262444778646c7a50796445786f6a726968640001040ce292774bde40fe8638fddce2bb9b32ea55eb5ba19cd64cd2dc16c331dc4047d516434552bb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b25bb11fded2d1cb1c65a8d270aae09bc56afe457870985a8c3edaba5fbfd6b992bb27987ea800f4b0063b93c0edea01ea32eb4faa9d013da1c7aaa8737e906", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e7295426efa93d91b6947909b0c285640e0aaf3692d49609d286d1378d48422d", - "sequence_number": "335287349186502855", + "sender": "0e5fe28a2c7a00c81d6506a682ee2c81e0ec23786e80c3e677ba4c47d1c4e992", + "sequence_number": "2478245332043816803", "payload": { "Script": { - "code": "dbfd85ea7ffca2f94a7fb2dddb22b6", + "code": "a492e90aa3a2add467edb1def57b", "ty_args": [ { "struct": { - "address": "b392e8cce86d06a0f7036bb0879c6bb4ff3b1b4e76be1bf9864b1785eecce1e9", - "module": "xPSeyWQ7", - "name": "TZHTsMJxeSAfslDdvSBeAnRooWZJGABN", + "address": "4e634593ef15a4775e7570f0d7b6ca03be9edf70de759338e1df4086826d9f1d", + "module": "TvxRYw", + "name": "NwLfBPjLGhZo", "type_args": [] } }, { "vector": { - "vector": { - "vector": "bool" + "struct": { + "address": "983554a65374c024e5bbf41052dfe3d4df26ee37febf4953b6bd91d459c4f09a", + "module": "OTaTKrNi", + "name": "M", + "type_args": [] } } }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "f4189c4e4a7f7678ab74b3b63a4cfb6c5c13b913ee73dba2012c99ef19459f64", - "module": "GFBqjSNSQfxVUjQSqKjqE", - "name": "xPCB", + "address": "350f06db2a20d3ea38640b44d9cff7844a7a2808177a27dcbd925952edcba8f4", + "module": "YmadSaIvuK", + "name": "UebrniDMdthDWBCdVG", "type_args": [] } }, { "struct": { - "address": "8a4c5b439f547ed413258c6676b2caee11984252b623cfc8e36c43267be90f29", - "module": "GSeAqwLnuoaLdfYgxdBfUOqgKhBDa3", - "name": "TXxflpbnxRBGywbvkpxmRs6", + "address": "5915a4691187100e0b0f629600b337237f6a15db4917904a11d0cafec18598da", + "module": "fnboSHGIUCmOPJRASoOUhKpypLMjIlZj", + "name": "IHCJUcYNODRBT1", "type_args": [] } }, { "vector": { - "struct": { - "address": "6c4d670da786d58cc35ca96b5d6c32656aa1b38ff1a473ae14cefdafdee3202d", - "module": "voBHBByHgRLboxjfUPAqUnNWHXa", - "name": "PdnejAmyhQVSn", - "type_args": [] + "vector": { + "struct": { + "address": "2a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa79e6e3c4c", + "module": "exutxfOpuSgcIzEcx9", + "name": "GMPttXizQBmjhMuLmq", + "type_args": [] + } } } }, { "struct": { - "address": "19fccf25a0a35123ea099e6bbbb37da8885423c0b30cb0cbf46a0b193ad94076", - "module": "bq", - "name": "UwyaZU2", + "address": "dbe31366f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b", + "module": "bXhRlWZljGYEOVjKiKvUd4", + "name": "aqgnSPsMMAicd6", "type_args": [] } }, { - "struct": { - "address": "883a661c70cf5dc8f05ec874640d7deccac42ae271d6660f433ea295c2d3d0b0", - "module": "p", - "name": "iIoZQQ", - "type_args": [] + "vector": { + "struct": { + "address": "b93c3282275d0a19e02caa5137c85c81e2374543fcee8354b005cb7b529290f7", + "module": "TgjGWbSPo", + "name": "rWQVNBvIFUMmlVdtRkHC", + "type_args": [] + } } }, { - "vector": { - "vector": { - "struct": { - "address": "7ef1a39a0be7c90d3b92ecdeea0a937fa07b221c79db67630bb55261eb54bfc2", - "module": "zYLVapaZUK4", - "name": "RnKLLFNmfWnJvszOFgDl7", - "type_args": [] - } - } + "struct": { + "address": "9162e6e039204a75d7fd99dc47b288557c8e7b0bcbd41dfea24c0e9d678c76ce", + "module": "cwsEkWGyAbPGcmZELeXrtH", + "name": "YDRpMSoEqjnaV1", + "type_args": [] } }, { "vector": { "struct": { - "address": "1ac85bab5127b192e1b8d03eae28fd33343e66e398748d88aa2f4a80ff0c0c11", - "module": "bxIeMwCE8", - "name": "Rorcqlr5", + "address": "af631e085fe882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3", + "module": "uaQkyFmO0", + "name": "JNRLoFDOZvBoSkNHYdyj1", "type_args": [] } } + }, + { + "struct": { + "address": "a09dc20fcfeb340aeb349eb3ef10d31428b84b5b60aa2d5b7358782327d440f2", + "module": "rAkAbYcynJQXOqivMp1", + "name": "xRkeyEwloYVNY", + "type_args": [] + } } ], "args": [ { - "U64": "11125017316911219746" + "Bool": true + }, + { + "U64": "3044188842724663537" + }, + { + "Bool": true + }, + { + "Address": "9278e51af271afce316e06f25c2e5505e5603b7e70c2d57e557697d4945406fa" }, { - "U128": "224090288159002228037611019592564033184" + "U128": "287388840358859522288757710645111650039" }, { - "Address": "5ef3a554d37ccd4d78508d9a67b8ca9d68934572fea4ff0028069837097e4cb9" + "U64": "3215015169696812189" }, { - "U64": "9762548323170607058" + "U8": 3 }, { - "U8": 10 + "Address": "346c60d8b1242b4d1f09a86b609ea5816863dc87d7a9d89a58e3d19d83eb7bd8" + } + ] + } + }, + "max_gas_amount": "3210935520263238788", + "gas_unit_price": "16963736859640883248", + "expiration_timestamp_secs": "8859820784511795774", + "chain_id": 113 + }, + "signed_txn_bcs": "0e5fe28a2c7a00c81d6506a682ee2c81e0ec23786e80c3e677ba4c47d1c4e99263dfbdcaff7e6422000ea492e90aa3a2add467edb1def57b0a074e634593ef15a4775e7570f0d7b6ca03be9edf70de759338e1df4086826d9f1d065476785259770c4e774c6642506a4c47685a6f000607983554a65374c024e5bbf41052dfe3d4df26ee37febf4953b6bd91d459c4f09a084f5461544b724e69014d0007350f06db2a20d3ea38640b44d9cff7844a7a2808177a27dcbd925952edcba8f40a596d616453614976754b12556562726e69444d6474684457424364564700075915a4691187100e0b0f629600b337237f6a15db4917904a11d0cafec18598da20666e626f5348474955436d4f504a5241536f4f55684b7079704c4d6a496c5a6a0e4948434a5563594e4f4452425431000606072a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa79e6e3c4c126578757478664f7075536763497a4563783912474d50747458697a51426d6a684d754c6d710007dbe31366f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b16625868526c575a6c6a4759454f566a4b694b765564340e6171676e5350734d4d4169636436000607b93c3282275d0a19e02caa5137c85c81e2374543fcee8354b005cb7b529290f70954676a47576253506f14725751564e42764946554d6d6c566474526b484300079162e6e039204a75d7fd99dc47b288557c8e7b0bcbd41dfea24c0e9d678c76ce16637773456b57477941625047636d5a454c65587274480e594452704d536f45716a6e615631000607af631e085fe882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3097561516b79466d4f30154a4e524c6f46444f5a76426f536b4e485964796a310007a09dc20fcfeb340aeb349eb3ef10d31428b84b5b60aa2d5b7358782327d440f21372416b41625963796e4a51584f7169764d70310d78526b657945776c6f59564e590008050101f1a0cfa79f213f2a0501039278e51af271afce316e06f25c2e5505e5603b7e70c2d57e557697d4945406fa02f7762922a7ba8c5791b33118cc1335d8019d4c455143079e2c000303346c60d8b1242b4d1f09a86b609ea5816863dc87d7a9d89a58e3d19d83eb7bd88474f9e9d7888f2c306818cecb4c6beb3ec272ea0f68f47a71002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403913563f581df8cd0223c7e8c383005eb5392e1b40ff46a5a73352dba69defdec3924d4f5eafcf0508f8810b72d9957aa99ceba3f107628868cf203e6fd29e0e", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "4196f31db04e5283fac8f4bba9e8eee73d2e69b9f9f1b0849a9e68d1754c0ba2", + "sequence_number": "1577710948971570034", + "payload": { + "Script": { + "code": "9be2786dd5272fdf2f1b32", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "2225013669346353923", + "gas_unit_price": "17638595618307636652", + "expiration_timestamp_secs": "13918323580338658277", + "chain_id": 218 + }, + "signed_txn_bcs": "4196f31db04e5283fac8f4bba9e8eee73d2e69b9f9f1b0849a9e68d1754c0ba272e3b1bfbf27e515000b9be2786dd5272fdf2f1b3200000323c7c524d6e01eacfdfcf542e1c8f4e55b07cb8dd127c1da002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444030d24f2f2ead539b0910b27d4745c54f8de52cb3e97fa6d99169c1dc456c46c31ce5639236c622511a266bf7b0b9a89e5f6a852a4951188302568180030ad10d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "6e346246a63c983c51aa36c6af408d82e135dff579db9531c5faf37a1a3d866c", + "sequence_number": "8171628192841034801", + "payload": { + "Script": { + "code": "c0dac3bfd9dd528eb197d0", + "ty_args": [], + "args": [ + { + "U128": "31156802096962552737543799420199911103" }, { - "U8": 243 + "U128": "299007279878533710233315308632219582057" }, { - "U128": "249722772252919954218220255248461892336" + "Bool": false }, { - "Address": "dbcc9c640567df9c88856c6ff04a5b9c848882ad3a8866b2edaa90a9fbff91de" + "U128": "116748484421061774065981085981354642036" }, { "Bool": true }, { - "Bool": true + "U8Vector": "a3e2" } ] } }, - "max_gas_amount": "3254761518834885712", - "gas_unit_price": "5052221458502361444", - "expiration_timestamp_secs": "3883634640262817181", - "chain_id": 164 + "max_gas_amount": "12341950535458896099", + "gas_unit_price": "11550643287287996765", + "expiration_timestamp_secs": "15575045573907471887", + "chain_id": 45 }, - "signed_txn_bcs": "e7295426efa93d91b6947909b0c285640e0aaf3692d49609d286d1378d48422dc7a0f151112ea704000fdbfd85ea7ffca2f94a7fb2dddb22b60a07b392e8cce86d06a0f7036bb0879c6bb4ff3b1b4e76be1bf9864b1785eecce1e908785053657957513720545a4854734d4a7865534166736c446476534265416e526f6f575a4a4741424e000606060006060007f4189c4e4a7f7678ab74b3b63a4cfb6c5c13b913ee73dba2012c99ef19459f6415474642716a534e5351667856556a5153714b6a7145047850434200078a4c5b439f547ed413258c6676b2caee11984252b623cfc8e36c43267be90f291e4753654171774c6e756f614c6466596778644266554f71674b684244613317545878666c70626e78524247797762766b70786d5273360006076c4d670da786d58cc35ca96b5d6c32656aa1b38ff1a473ae14cefdafdee3202d1b766f42484242794867524c626f786a6655504171556e4e574858610d50646e656a416d79685156536e000719fccf25a0a35123ea099e6bbbb37da8885423c0b30cb0cbf46a0b193ad9407602627107557779615a55320007883a661c70cf5dc8f05ec874640d7deccac42ae271d6660f433ea295c2d3d0b001700669496f5a5151000606077ef1a39a0be7c90d3b92ecdeea0a937fa07b221c79db67630bb55261eb54bfc20b7a594c566170615a554b3415526e4b4c4c464e6d66576e4a76737a4f4667446c370006071ac85bab5127b192e1b8d03eae28fd33343e66e398748d88aa2f4a80ff0c0c1109627849654d7743453808526f7263716c7235000a012204908e4e00649a02a04689d7010a628583f2f317393896a8035ef3a554d37ccd4d78508d9a67b8ca9d68934572fea4ff0028069837097e4cb901d25f2bc9f9897b87000a00f302f08ae4c6857d1959f58ca2c742dbdebb03dbcc9c640567df9c88856c6ff04a5b9c848882ad3a8866b2edaa90a9fbff91de0501050150a4c35e5b3c2b2d64a1a310a6181d469d6544022171e535a4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405538e9a304543ba8240bc8a8810fdbbe2295968a1392a048c7dc1778e2aea84acb16cda8927c18452523892e429c9bafd64302b2de08d289ef985efb0d019f07", + "signed_txn_bcs": "6e346246a63c983c51aa36c6af408d82e135dff579db9531c5faf37a1a3d866c316cdbd68b746771000bc0dac3bfd9dd528eb197d0000602bf3ef87740e5f36908f12eb2f19470170269fed338b87af295d119fc8f17b5f2e0050002744ae6017fe8e4eda17c43a8b1f0d45705010402a3e2e338781d9f6a47ab5d210d32df204ca00f5e46e96dad25d82d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f4b7abe9685100e466565ed8b4079783fa3e279dbd71fe46b7bcc655c81083991ae7b9b2c2e28ca3a0570369764800a4bf15c992c105f21285cf333e280bd00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fdc8b629d10795b4982c942cb09046a34a7836ac2eed00f6b5e794ce233be1cd", - "sequence_number": "10067822224099704130", + "sender": "81c1ee891cdec0435f07c5bd5b1c50148cac3940e245a2d1c5ed131587bb44e4", + "sequence_number": "7078771148902522948", "payload": { "Script": { - "code": "77e294db47ca749d2b252fa5a2", + "code": "7afc", "ty_args": [ { - "vector": { - "vector": "signer" + "struct": { + "address": "8b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b8de69c980f59", + "module": "QHiWUvRpqvrXblpRTGqtBhfljjKJdmJn", + "name": "auCfzSrgxRAvHhTRIGlTqo1", + "type_args": [] } }, { - "vector": { - "vector": { - "struct": { - "address": "6b0da0caee4f0ef1aed1fbe5966b3009c0d48597774f05d8591eb70b58092150", - "module": "QBsfyQLxFpkbpRWOlmFGpOMVWwZG", - "name": "LpuP", - "type_args": [] - } - } + "struct": { + "address": "a9d21d0e991d933a94ff9a7b18580ed1b1289e0c22fec86d369ec517f7f31a1e", + "module": "uYEsTLFDsOPc0", + "name": "xZsvQinSQkxozI4", + "type_args": [] } }, { "struct": { - "address": "9b8ec02e07b06be9fb557277b781aeff75239deb922faa2b49fe421889239fc7", - "module": "ljDkjwuUZDRdFzpDHkzfCC", - "name": "jktYqStwMNmglONFpdRbEZlqp2", + "address": "2ac9cc5b70aec0b3d4b40ea533884a8a749f791e527c18e8f2f96de1dad5c1a8", + "module": "tnNwlEqipVeMhmz7", + "name": "nSXSwTWRmnwvhliLbgtZUABzXjUzrzCA3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "e6105010fe0e7b2e67b3e5d2d0197daab7a52bc3e6125ac4168e857cc35db90a", - "module": "cLukHIvDJrp2", - "name": "oWrXYFziWrAvjnfIvglO", - "type_args": [] - } + "struct": { + "address": "9b2dc2dfa48de05743a134fe98aae4be4a3f06f5f35cc142e0b72cceacadbb98", + "module": "zQmichuaGaWUcaFEsIR2", + "name": "FJRPcyclEwuoTcYomGcHr4", + "type_args": [] } }, { "struct": { - "address": "3eaa4c96ab9aad6a6dd8a454e9b88a4eb62cdf8dbb10564465925ab91c252f9b", - "module": "qnruScnogXuERnbWj", - "name": "aSwsxATxCWivmbqGSDoCbQowpWaXhr", + "address": "85470bee2cbf10af3c8b1c36c4e9cd95f8e756fac9b8b84d8f70012aed716ffd", + "module": "KXjshTgScbwt4", + "name": "qLDgcLU2", "type_args": [] } }, { "vector": { "struct": { - "address": "1418d2ba78e3e41c4ecedca0959d1759a1bd5e240984df5c02bffe22d664d48b", - "module": "NVP", - "name": "yfLHCRXnVTYIvSUBk8", + "address": "e7acdbd83dad196ec9b678613830bae2f53421a9500a6c24dfcd1dff74cf9569", + "module": "fzZsTtWcRUcYxRlNFwBHE", + "name": "Qxp", "type_args": [] } } }, + { + "vector": { + "vector": "u8" + } + }, { "struct": { - "address": "aa6dd613a33115476a76190705e2742a570fb6ec3c4ba5091283338e9884a3ab", - "module": "MiFiBEiwDfwKse7", - "name": "XBPbLiFlUJKjBxJMITEDScNv", + "address": "1c3ebbb79823f6462519d34dc6fa162daf29b6c8a35c86a58027b7afaa127032", + "module": "tEvJM", + "name": "iSbAIzbvPaUiriQQWUeqvQSZgmGAGIO", "type_args": [] } } ], "args": [ { - "U8Vector": "26b2e0a8" + "U8": 119 }, { - "Address": "e10319cba37b3ccf0c309d137c95030e703f914353ca830c21d19d39dda78763" + "Bool": false }, { - "Address": "895f6dd4379494615192bf4dcbd0e22e29392c4a038a5c6edfbc230db354c07f" + "U64": "4793160774261931186" }, { - "U8Vector": "a284805c4bf6d3f9" + "U64": "16301314610666142679" }, { - "U128": "79081000444503330652015900608976219124" + "U8": 102 }, { - "U128": "324253899910341760689708112208275606064" + "Address": "ca7fa4b82b9a12f98ddfe6828921f5be6b9258e0db8ade555d2022dd6bf3cde9" }, { - "Bool": false + "Address": "0ab5d98305da5c3a0647008b62f210df7fd336fb0cdb848b9e5059a694ff49d9" }, { - "U8Vector": "fb42ca494a036bd55ef3145fdda1fdf6" + "Address": "fc9eb5df7fd6c91fae44b8324070ebf9d27eaac668b587641b5f9a56609891f8" }, { - "U64": "3507681983389876459" + "U64": "8357029262025990126" } ] } }, - "max_gas_amount": "15520459568698736870", - "gas_unit_price": "6526723669730002879", - "expiration_timestamp_secs": "10335115094460958137", - "chain_id": 180 + "max_gas_amount": "7174009825256145777", + "gas_unit_price": "2106946568972138902", + "expiration_timestamp_secs": "3010894555185195363", + "chain_id": 171 }, - "signed_txn_bcs": "fdc8b629d10795b4982c942cb09046a34a7836ac2eed00f6b5e794ce233be1cd42fd3ea1f816b88b000d77e294db47ca749d2b252fa5a2070606050606076b0da0caee4f0ef1aed1fbe5966b3009c0d48597774f05d8591eb70b580921501c5142736679514c7846706b627052574f6c6d4647704f4d5657775a47044c70755000079b8ec02e07b06be9fb557277b781aeff75239deb922faa2b49fe421889239fc7166c6a446b6a7775555a445264467a7044486b7a6643431a6a6b7459715374774d4e6d676c4f4e4670645262455a6c717032000607e6105010fe0e7b2e67b3e5d2d0197daab7a52bc3e6125ac4168e857cc35db90a0c634c756b484976444a727032146f57725859467a69577241766a6e664976676c4f00073eaa4c96ab9aad6a6dd8a454e9b88a4eb62cdf8dbb10564465925ab91c252f9b11716e727553636e6f67587545526e62576a1e6153777378415478435769766d62714753446f4362516f777057615868720006071418d2ba78e3e41c4ecedca0959d1759a1bd5e240984df5c02bffe22d664d48b034e56501279664c484352586e56545949765355426b380007aa6dd613a33115476a76190705e2742a570fb6ec3c4ba5091283338e9884a3ab0f4d694669424569774466774b73653718584250624c69466c554a4b6a42784a4d4954454453634e760009040426b2e0a803e10319cba37b3ccf0c309d137c95030e703f914353ca830c21d19d39dda7876303895f6dd4379494615192bf4dcbd0e22e29392c4a038a5c6edfbc230db354c07f0408a284805c4bf6d3f902f46bad09c8c4fac8d584fe8a59727e3b02308a868f08ed65a3819f50139007f1f305000410fb42ca494a036bd55ef3145fdda1fdf601ebc0fdec2dcaad30e6c0192fbfbf63d7bf0764f99894935ab9851fae6bb46d8fb4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fbfcb1b3085b87d880e8c933c63cbfcff407baf068243611931a022f0ec76d10fdba9769bfd2d5439a4d19a8636e039a30dbc006b283058be1ae40ecfe3a9f07", + "signed_txn_bcs": "81c1ee891cdec0435f07c5bd5b1c50148cac3940e245a2d1c5ed131587bb44e444609ee0dad83c6200027afc08078b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b8de69c980f5920514869575576527071767258626c7052544771744268666c6a6a4b4a646d4a6e17617543667a537267785241764868545249476c54716f310007a9d21d0e991d933a94ff9a7b18580ed1b1289e0c22fec86d369ec517f7f31a1e0d75594573544c4644734f5063300f785a737651696e53516b786f7a493400072ac9cc5b70aec0b3d4b40ea533884a8a749f791e527c18e8f2f96de1dad5c1a810746e4e776c4571697056654d686d7a37216e535853775457526d6e7776686c694c6267745a5541427a586a557a727a43413300079b2dc2dfa48de05743a134fe98aae4be4a3f06f5f35cc142e0b72cceacadbb98147a516d696368756147615755636146457349523216464a52506379636c4577756f5463596f6d4763487234000785470bee2cbf10af3c8b1c36c4e9cd95f8e756fac9b8b84d8f70012aed716ffd0d4b586a7368546753636277743408714c4467634c5532000607e7acdbd83dad196ec9b678613830bae2f53421a9500a6c24dfcd1dff74cf956915667a5a73547457635255635978526c4e46774248450351787000060601071c3ebbb79823f6462519d34dc6fa162daf29b6c8a35c86a58027b7afaa127032057445764a4d1f69536241497a62765061556972695151575565717651535a676d474147494f00090077050001b2fc373554ba844201d7fba33445e739e2006603ca7fa4b82b9a12f98ddfe6828921f5be6b9258e0db8ade555d2022dd6bf3cde9030ab5d98305da5c3a0647008b62f210df7fd336fb0cdb848b9e5059a694ff49d903fc9eb5df7fd6c91fae44b8324070ebf9d27eaac668b587641b5f9a56609891f801ee9f9a1cd621fa7371038e31ed338f6396f94fccbd603d1d63a9f841a5d8c829ab002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd6ec1e77ba9388e110b1f8a1214e7cf4f3254c4c7d510a125fd8ef05eec3d5ac08570e0d0934b217af65c18ce1e70f1a184f4b91695b5df18f9c8487b5d9508", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "473e9c1307184af1e7405946563fa381ce43377f97abae3d76a167b8cb6b24ae", - "sequence_number": "9782011366124380318", + "sender": "a1255740fc5f70ba70152de7fda251b396088682bee801513a79223a37a51d7d", + "sequence_number": "12660138461313456493", "payload": { "Script": { - "code": "f5d7cbb18b06f039ce85d0be43d81b", + "code": "35039c", "ty_args": [ { "struct": { - "address": "4af91f3a95cc6d2a843d79f2c5386f35d22d11396166993ea6f7d0fe0733b365", - "module": "gbtrtCLXRsxvNwboLlxriivIgqdOZKrR4", - "name": "mWfdrTKGGjjJoRhBIe0", + "address": "c39014f0f7d1698584901fbd0c668f55daf916c48217cf43a2cc475d4eda57cf", + "module": "Y2", + "name": "jmCzwBXCvroVtXLTPOscSjWMsmyXB", "type_args": [] } }, { - "vector": { - "vector": { - "vector": "address" - } + "struct": { + "address": "27fd810e6a53337d18fb3772e1a14a238817174c4a0b1d8d0e64da410234b363", + "module": "YUfnjrYWhL", + "name": "uzyqZVGknbygGvaqkY1", + "type_args": [] } }, { "struct": { - "address": "95bd2723119be8e25a1e1d8b07771d666bacb6987cd4fbb442eb3002afaa4fa1", - "module": "qcaQLvzVkoklmlgCWHlEPXuHDijHnL", - "name": "DRVMoHnPeOOmyHfCIQVGNJO8", + "address": "5c77e525fab7e96403356b7d876bb6a78c77ec7460d992466e5d32c9788b91dc", + "module": "lzBNKGKnXwLilDUrhcQFyLtQc", + "name": "FLqQTPgunrTPWtDgdnsa9", "type_args": [] } }, { - "vector": { - "vector": { - "struct": { - "address": "e2fcf69af1f844228f17f74d34a31bb8941cb752c04ac1beb24720e9caf83f36", - "module": "YeePRvOVJEMxeLYTdrT0", - "name": "fJuYUXbxrNJYZiAZpGrw4", - "type_args": [] - } - } + "struct": { + "address": "7832ecca47a228a2c156343eb95e1c1ec2906c3706762fcdbf95997102dfbbdf", + "module": "OaZlRdaRRJbKVDjkgB2", + "name": "OBmavFC", + "type_args": [] } }, { - "vector": "bool" + "struct": { + "address": "3b3c842346407e1b722150a948e92315a71702c0b9ef1393b9683ebc9d970026", + "module": "H2", + "name": "bTXlGLswKXYpJQkGIbDPuYPxMZZN", + "type_args": [] + } }, { "struct": { - "address": "982e8ccbb5cf02bb8f9160d5c7e1e749e0abcd0e989689d20d216437fcda9f35", - "module": "lThQePlP", - "name": "mQFICDpAAFAAhNjSQnqxmksmEMTaSk", + "address": "10a95c649a12057087b1c10b6444c47fc5b7dd398ff14f233afc92b3e01f15bb", + "module": "fLpDikfIeUdijqk5", + "name": "ZuhDHLQCOCuJLwhthnN0", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": "u128" } } ], "args": [ { - "Address": "f902a5d08c4d2047391f8e3ad608263a6e93f7c5b5e9f4b3be8a0eaa7aeb8ab6" + "U8Vector": "ad0cf03fce1afd8c5ca2ce" }, { - "U8": 148 + "U64": "17836449646785977896" + }, + { + "Bool": false }, { - "U64": "14276210385800183890" + "Bool": true + }, + { + "Address": "9176b2fedec19bf39bdd629f40267bcb570684ce2643bed66bbfbd8c45371249" }, { - "U128": "291785481323107682230268245528037982596" + "U64": "16974329509336560348" }, { - "U128": "280103279105506602879011102937134709228" + "Address": "41b28c753ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b" }, { - "U128": "205315309024393168796546883567362855978" + "U8Vector": "ee181a6dfac80a19ea2f1bf2c7157f" }, { - "U8Vector": "e4" + "Address": "65c419d72ca71253efdfa8b72e38f8ebbca06765f26ad51438fe4cbed630a770" }, { - "U64": "13253358204309939585" + "Bool": true } ] } }, - "max_gas_amount": "12332363216131018363", - "gas_unit_price": "17597597511299893800", - "expiration_timestamp_secs": "15434991086228552512", - "chain_id": 201 + "max_gas_amount": "369064747035258644", + "gas_unit_price": "18066323232969855987", + "expiration_timestamp_secs": "2829102044765843053", + "chain_id": 8 }, - "signed_txn_bcs": "473e9c1307184af1e7405946563fa381ce43377f97abae3d76a167b8cb6b24ae9e60ad9a82afc087000ff5d7cbb18b06f039ce85d0be43d81b07074af91f3a95cc6d2a843d79f2c5386f35d22d11396166993ea6f7d0fe0733b365216762747274434c58527378764e77626f4c6c7872696976496771644f5a4b725234136d57666472544b47476a6a4a6f52684249653000060606040795bd2723119be8e25a1e1d8b07771d666bacb6987cd4fbb442eb3002afaa4fa11e716361514c767a566b6f6b6c6d6c674357486c455058754844696a486e4c184452564d6f486e50654f4f6d79486643495156474e4a4f3800060607e2fcf69af1f844228f17f74d34a31bb8941cb752c04ac1beb24720e9caf83f36145965655052764f564a454d78654c59546472543015664a755955586278724e4a595a69415a704772773400060007982e8ccbb5cf02bb8f9160d5c7e1e749e0abcd0e989689d20d216437fcda9f35086c54685165506c501e6d5146494344704141464141684e6a53516e71786d6b736d454d5461536b000606020803f902a5d08c4d2047391f8e3ad608263a6e93f7c5b5e9f4b3be8a0eaa7aeb8ab600940152c05c10b5491fc602848162b09588f843873a90d4eed683db02ecb97c66b6f3336027a1fcf7e4edb9d2022a5419bb8a3b4a9b56b6ff85484a769a0401e4018125e7481163edb77b4e9562015b25ab280a5451b33937f4403bf9659d1a34d6c9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444022f47b6fa58d8bba9b730aaddfa7d822ad449e91a676354775384b3f8bc34b32a7d268d6ffe25fff719c3e61f0b229347a5d3d94bc0f6050bac75744028e4d01", + "signed_txn_bcs": "a1255740fc5f70ba70152de7fda251b396088682bee801513a79223a37a51d7d6d59d9b1dad8b1af000335039c0707c39014f0f7d1698584901fbd0c668f55daf916c48217cf43a2cc475d4eda57cf0259321d6a6d437a7742584376726f5674584c54504f7363536a574d736d795842000727fd810e6a53337d18fb3772e1a14a238817174c4a0b1d8d0e64da410234b3630a5955666e6a725957684c13757a79715a56476b6e627967477661716b593100075c77e525fab7e96403356b7d876bb6a78c77ec7460d992466e5d32c9788b91dc196c7a424e4b474b6e58774c696c44557268635146794c74516315464c7151545067756e72545057744467646e73613900077832ecca47a228a2c156343eb95e1c1ec2906c3706762fcdbf95997102dfbbdf134f615a6c52646152524a624b56446a6b674232074f426d6176464300073b3c842346407e1b722150a948e92315a71702c0b9ef1393b9683ebc9d9700260248321c6254586c474c73774b5859704a516b4749624450755950784d5a5a4e000710a95c649a12057087b1c10b6444c47fc5b7dd398ff14f233afc92b3e01f15bb10664c7044696b6649655564696a716b35145a756844484c51434f43754a4c776874686e4e30000606030a040bad0cf03fce1afd8c5ca2ce0128ded1c273cc87f705000501039176b2fedec19bf39bdd629f40267bcb570684ce2643bed66bbfbd8c4537124901dcb26f40c1ee90eb0341b28c753ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b040fee181a6dfac80a19ea2f1bf2c7157f0365c419d72ca71253efdfa8b72e38f8ebbca06765f26ad51438fe4cbed630a770050114ef279a6e2e1f05f3138eca4279b8fa6d6e990b52fd422708002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444048b298ec1336eb62f7774f0932a6f7f3bd9d0288474c51129ec2189909fd5f1c4ce8116c2c2865668f7b9ae230d5ca44fac7abc635c18b755a28acb0b3ada509", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c3c4d4428c5a4cc64439c28db0bb94cce540cc24bb0e9052eb9b873fd0066e55", - "sequence_number": "8073277356858258859", + "sender": "1545c8b01ee468f662a577e203e28e51349889f3fc1024591024413d35000205", + "sequence_number": "16804998618124462611", "payload": { "Script": { - "code": "65f4ce9d4dbb3dcdb7cc28", - "ty_args": [], - "args": [ + "code": "e55dbf4ec764df175a85ad365d09", + "ty_args": [ { - "U64": "11085638268145166188" + "struct": { + "address": "26866f33fbf98f48dc73d2666c6552cd9ed54496637abc64c873fac9c2bd3d62", + "module": "XuccNuVKyOKwPDPgSH", + "name": "alIPMhafxJ7", + "type_args": [] + } }, { - "U64": "5323767124305874940" + "struct": { + "address": "41df9a9447769d483e58c4e48760c3db9e860db63c55255420da2f7627914d1a", + "module": "QlpfHysJdSvQAlVMXrbQ", + "name": "jxnjhGKOZuhZpMk", + "type_args": [] + } }, { - "U64": "11769484486888837404" + "vector": { + "struct": { + "address": "a77e681efb21d41e65d3e133eaa2ce81340af29b8ad2fcdd27c7d6022f078439", + "module": "XltNQatsemdKmDMKnkDYJHzXZPy", + "name": "uSjWbRBmQMflPBCUQNEXKHaGpZZQeOYG3", + "type_args": [] + } + } }, { - "U8Vector": "782c" + "vector": { + "struct": { + "address": "394821fa139da46a04130bf29863d3e2dbb2cdea4b5d5b92430e529597381e49", + "module": "SoAdW", + "name": "BmeQBCZgiyNHkyAOvnEbRcZusF", + "type_args": [] + } + } }, { - "Bool": false + "vector": { + "struct": { + "address": "825d7b3801d9fd0288557f252752ca3e826d9e79229174269de7e65b874da4f0", + "module": "YBGKoKLFOkhcAYfZ", + "name": "PhXwYLVw8", + "type_args": [] + } + } }, { - "U128": "314204467941148495762212499050548115845" + "struct": { + "address": "242e77a5440292d8f6954b75af180b1d951bb3030e84ec124f7556b9adb8284e", + "module": "KZIPIhLtoKlDJgq", + "name": "VdfMLVhHczCDlOAAIZvzNcLyS", + "type_args": [] + } + } + ], + "args": [ + { + "U64": "11558429351014721328" }, { - "U128": "4584345534997736242174311336492322340" + "Bool": false }, { - "Address": "485cc9f6a698f8ce1e4f0f12a77f1cb8dbe3c87c071ca300cc6f55d135446edf" + "U128": "174821211453018074747865826924333359885" }, { - "U128": "303931106742206111661078089684253045527" + "Address": "8474cc4af4f4c2664642f93e4f3e21048b61a7e719fc3170cc5e5b5f56584cd6" } ] } }, - "max_gas_amount": "2289790510539497089", - "gas_unit_price": "9882869995972678909", - "expiration_timestamp_secs": "15307158103760537138", - "chain_id": 85 + "max_gas_amount": "7370179406592730488", + "gas_unit_price": "5225626897218240416", + "expiration_timestamp_secs": "10680669731652310010", + "chain_id": 197 }, - "signed_txn_bcs": "c3c4d4428c5a4cc64439c28db0bb94cce540cc24bb0e9052eb9b873fd0066e55abb5bd64fb0a0a70000b65f4ce9d4dbb3dcdb7cc280009016ce744494519d89901fc8f2737fed1e149011cd17a8ec89b55a30402782c05000285390f0a4948e383ea5b9912509461ec0224ce7a2931fad5a7322a527fafe9720303485cc9f6a698f8ce1e4f0f12a77f1cb8dbe3c87c071ca300cc6f55d135446edf0217731aaddef89589e2b0e9d47f00a7e4815ec46656f8c61ffd54514fe6012789328663cf31f36dd455002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408bf598a20fb0532e8b14f9b0458392cae048ad0f3f67fe6b9db570fda965dbdddbf96e612fa4ebd91a248b809c8604af587c0215756f403d3d13fdb2614a820e", + "signed_txn_bcs": "1545c8b01ee468f662a577e203e28e51349889f3fc1024591024413d35000205132a3ddc345937e9000ee55dbf4ec764df175a85ad365d09060726866f33fbf98f48dc73d2666c6552cd9ed54496637abc64c873fac9c2bd3d6212587563634e75564b794f4b775044506753480b616c49504d686166784a37000741df9a9447769d483e58c4e48760c3db9e860db63c55255420da2f7627914d1a14516c70664879734a64537651416c564d587262510f6a786e6a68474b4f5a75685a704d6b000607a77e681efb21d41e65d3e133eaa2ce81340af29b8ad2fcdd27c7d6022f0784391b586c744e51617473656d644b6d444d4b6e6b44594a487a585a50792175536a576252426d514d666c50424355514e45584b486147705a5a51654f594733000607394821fa139da46a04130bf29863d3e2dbb2cdea4b5d5b92430e529597381e4905536f4164571a426d655142435a6769794e486b79414f766e456252635a757346000607825d7b3801d9fd0288557f252752ca3e826d9e79229174269de7e65b874da4f0105942474b6f4b4c464f6b68634159665a0950685877594c5677380007242e77a5440292d8f6954b75af180b1d951bb3030e84ec124f7556b9adb8284e0f4b5a495049684c746f4b6c444a6771195664664d4c566848637a43446c4f4141495a767a4e634c79530004013067ae6c41ca67a00500020de3e77aece261cb4fde09e631578583038474cc4af4f4c2664642f93e4f3e21048b61a7e719fc3170cc5e5b5f56584cd678e5db141f234866a07f6bf9f9278548fa136746885c3994c5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0c5e64fe4e1880fa3f6067726296c8990cb28acca52738d73cfb376c0fa1c74b1f70cfc400b025704d720ec7aeb879989fc6f8a1e3e9396258f9b488a672308", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "66318dca6e1664da5cd9aba49cb53eb045f8867220093ef4de07d43aab02eb60", - "sequence_number": "6861844787957671690", + "sender": "650e1ca68403d34b17a77508c23ea4df5abc5d0e62ee949e3ac5aeb7beac6559", + "sequence_number": "12460075618115661006", "payload": { "Script": { - "code": "fcaacc3a69cf804cacff1babab3fee22", + "code": "0ddcfdba304f25afda", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "442233ffc3bb0531077766bc83c0094e0b87e58660c3165c4dd340b326709c0a", - "module": "gSKXEErUH", - "name": "fZxahSEatYnoShUwxhG8", - "type_args": [] - } - } + "struct": { + "address": "11800983819d279a1e19b51529663c4bce11b26594294f11fa598a574b7bda1c", + "module": "LoDncMdIjVazkcmjEyFERultARs", + "name": "kxrdmiZxIxsMXhruaEZvAlGgN3", + "type_args": [] + } + }, + { + "struct": { + "address": "2e3d1ec8fc2b4ff4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9e", + "module": "BmfcHSVLyGEoad", + "name": "UOpDmRZJPRJjVbmhKJVlSaaDZkibg5", + "type_args": [] } } ], + "args": [] + } + }, + "max_gas_amount": "639181661965572466", + "gas_unit_price": "2075643314198606976", + "expiration_timestamp_secs": "2141029323575591627", + "chain_id": 27 + }, + "signed_txn_bcs": "650e1ca68403d34b17a77508c23ea4df5abc5d0e62ee949e3ac5aeb7beac6559ce2c4a24c214ebac00090ddcfdba304f25afda020711800983819d279a1e19b51529663c4bce11b26594294f11fa598a574b7bda1c1b4c6f446e634d64496a56617a6b636d6a4579464552756c744152731a6b7872646d695a784978734d5868727561455a76416c47674e3300072e3d1ec8fc2b4ff4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9e0e426d66634853564c7947456f61641e554f70446d525a4a50524a6a56626d684b4a566c536161445a6b69626735000072d966c455d4de0880f438d7982ace1ccb026b7dd376b61d1b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444024e67a2317010b0e7648039b4520f5d3566a285ebef2a4f829daca03ba29feb3e85bbbce4c3d86ead7ba8b62b444162c06dee9b3910faa9a33100b4ea55e330b", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "43feea62f0fe51f723e4b478193455657f96f4348f1db5b0a4ce5992885227e9", + "sequence_number": "13278693470332108686", + "payload": { + "Script": { + "code": "71ec487db3cccc0fef68ab77f3", + "ty_args": [], "args": [ { - "Bool": false - }, - { - "Bool": false - }, - { - "U64": "14717097353069105624" - }, - { - "Address": "a04cc448418c0733dbc09b52a0a277924f0d473e4e339baf026defdc1241c473" - }, - { - "Bool": false - }, - { - "U128": "272904463939657246664530984336417128996" - }, - { - "Address": "5fda40bf58888cffca9eb89259ffa094ed7d99a1ad0e6978a13d6936cf564230" + "U64": "17212120449677473728" } ] } }, - "max_gas_amount": "6506413227801536550", - "gas_unit_price": "13998435644183772162", - "expiration_timestamp_secs": "2507554841301947435", - "chain_id": 171 + "max_gas_amount": "16107300990561446519", + "gas_unit_price": "6013620086228886065", + "expiration_timestamp_secs": "4502156261695870772", + "chain_id": 19 }, - "signed_txn_bcs": "66318dca6e1664da5cd9aba49cb53eb045f8867220093ef4de07d43aab02eb600a2715a27a2b3a5f0010fcaacc3a69cf804cacff1babab3fee2201060607442233ffc3bb0531077766bc83c0094e0b87e58660c3165c4dd340b326709c0a0967534b58454572554814665a78616853456174596e6f536855777868473800070500050001d891866e11a23dcc03a04cc448418c0733dbc09b52a0a277924f0d473e4e339baf026defdc1241c473050002248290d3c961249e61558d65e77c4fcd035fda40bf58888cffca9eb89259ffa094ed7d99a1ad0e6978a13d6936cf564230266803b55b6c4b5a027cbd2e0d6f44c22b149db2d79fcc22ab002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ab3238c78d8f89eb324e55bf2080681e6c2182a2eb8a9beff7774d2b2715b77ed389467fe86543628312ba3ee10b7c66a86694cb231e3f42074facfb0508ae06", + "signed_txn_bcs": "43feea62f0fe51f723e4b478193455657f96f4348f1db5b0a4ce5992885227e98ebf71945b6547b8000d71ec487db3cccc0fef68ab77f3000101c03743f25abcddee776ab628e9a088df31a2d35d9bab745334d7ae3d44df7a3e13002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dee4910512894656b90e6105c05e41bc3ce61d31e11c30f6b16cd8844fd17ed54fe64152fc3e89a3d0f4daac782f5923e08f52d1ce40eb1fb2aafd117084160d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "53c6a20e460e61c02ef6929f19345d7bcb7392f4ec816be5f49a83850f81db1a", - "sequence_number": "15578517666318777960", + "sender": "8f836387d1bcb38c1f228b9ed7d21c4477c624de28111c88e07ae56f1a6589f6", + "sequence_number": "9950409979139359963", "payload": { "Script": { - "code": "7eff72796f", + "code": "67841f8946c50a2fcab7eab03f83", "ty_args": [ { "struct": { - "address": "f708ee98fb4d613c35009d11ebd50b90d6eb65e66ff7659f7b10aa6bd15a18aa", - "module": "uVbeqBfOwhPIUBl1", - "name": "sshZLWTYosfzXMOFqClf", + "address": "e7c50b00e9ffc34885e2482cd79605b372e42ad5e69a1990cd7648ca1325a2ee", + "module": "kEkYdShbkvOQsDjwdAuHghNCO", + "name": "xnTRunsvGTWphTeQZkoBBAsct9", "type_args": [] } }, { "struct": { - "address": "0ec36b27bab4551aa36bfcb677cccb4231d5545d9f394cdb679a863179575b72", - "module": "HlQjcDqETcRAvDQo7", - "name": "WyqgiKBFzKaGHFv", + "address": "cae841b78fcba8e607bfe6302641170123917995db53f518ac40456d369901f1", + "module": "brRRYgoOdvWLrPrmBALThNgqusaIEGuM5", + "name": "vPRLYedoBQbXVAUXlhsgiBNhoSwFPuF9", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "b67282202df0777ff7616205f0d52d746d9494b6375e2fff527dd64bfb662bbe", - "module": "JWBkcVIFixBeXfAOuEyrO8", - "name": "UCVEKjZrYTXSvlWZhTHlvCAyzQzZb0", - "type_args": [] - } - } + "vector": "address" } }, { "struct": { - "address": "7eb23c3cc8a165ec44b8df598722585a9f52e54b223cf2a9bdc86cf954cd0d66", - "module": "AbrzHCWGTaCLkxjvB", - "name": "iczxuJQFqiLIZVfkBI7", + "address": "eb82b083ba94e320953dd73399a18b9b9d57349f0602090b4bf9179ec38be984", + "module": "XliXLWiYaBF6", + "name": "eNHth0", "type_args": [] } }, { "struct": { - "address": "dac8d8adfe18cf3ecc7e46a159c8152e69472d15933903202392bf83672a7898", - "module": "RWAGafqKOBdbHBdTPKx7", - "name": "iwnfrrQexFwl7", + "address": "f70cf6f34bfac4803a0a17b29bc8ba06b1b04b8bc12511b67ea6dd1a0f2b923e", + "module": "B", + "name": "dXS", "type_args": [] } }, { "struct": { - "address": "4cdd8edfa149dd2fc0c872020704fe3292c0f8df207f6c4c09bbd9f60481691e", - "module": "ktkWSXjgMXBVokjPmLATTtRyXPIH", - "name": "QwqdwYYvXpjSUkiGwi", + "address": "9c4fcb2c59dd6675d8161e0555ebc6d464c7bde04e7bf7b7bb169a0932a98fff", + "module": "CbumHBwfwigajZfWlcWQIjriyF", + "name": "ZkIcWjtzeDWJcbbuEMMGM4", "type_args": [] } } ], - "args": [] - } - }, - "max_gas_amount": "18117267148020982538", - "gas_unit_price": "3586885016193938819", - "expiration_timestamp_secs": "7606986017144337215", - "chain_id": 146 - }, - "signed_txn_bcs": "53c6a20e460e61c02ef6929f19345d7bcb7392f4ec816be5f49a83850f81db1a68fe136c470332d800057eff72796f0607f708ee98fb4d613c35009d11ebd50b90d6eb65e66ff7659f7b10aa6bd15a18aa10755662657142664f7768504955426c31147373685a4c5754596f73667a584d4f4671436c6600070ec36b27bab4551aa36bfcb677cccb4231d5545d9f394cdb679a863179575b7211486c516a63447145546352417644516f370f57797167694b42467a4b614748467600060607b67282202df0777ff7616205f0d52d746d9494b6375e2fff527dd64bfb662bbe164a57426b63564946697842655866414f754579724f381e554356454b6a5a7259545853766c575a6854486c764341797a517a5a623000077eb23c3cc8a165ec44b8df598722585a9f52e54b223cf2a9bdc86cf954cd0d66114162727a484357475461434c6b786a76421369637a78754a514671694c495a56666b4249370007dac8d8adfe18cf3ecc7e46a159c8152e69472d15933903202392bf83672a789814525741476166714b4f42646248426454504b78370d69776e66727251657846776c3700074cdd8edfa149dd2fc0c872020704fe3292c0f8df207f6c4c09bbd9f60481691e1c6b746b5753586a674d5842566f6b6a506d4c4154547452795850494812517771647759597658706a53556b6947776900000a23a5527b766dfb83356908eb2cc7313f7340a37a71916992002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444048101cde99588eeaae522c381bc0376fd8fdba10d761a72116a493c8c11b472677844623a4dd447008b5611a551a8bddc42e42353c6e15cbae21afd455c0710c", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "88afc70e42a0581de2a0f8a2203ba6561119cfcf5c700a5af04a5cc1cd7b1a3a", - "sequence_number": "16120235932136881982", - "payload": { - "Script": { - "code": "2f3f", - "ty_args": [ + "args": [ { - "vector": { - "vector": { - "struct": { - "address": "7e5e718b46fd88b60652c76817cdf54ea65f09df094556296748debd14bf52db", - "module": "zrXpKvIzgXjcRBcEnIKBhQeGlp1", - "name": "bMzmAlVVA3", - "type_args": [] - } - } - } + "U128": "14140931011640362963876395461809917561" }, { - "struct": { - "address": "2169cde70e0da53b3e9b21eaa69d3f8d048b3e81b463e18924d62ba8f682a90f", - "module": "oEDHLzZsAKHHBRLydwSyJN", - "name": "CtNqBi0", - "type_args": [] - } - } - ], - "args": [ + "U64": "1123097944319240555" + }, { - "Address": "cf0b6010934d009f145b18293dc105c91af47d3b0ddd919775f195c9f945ef1a" + "U64": "17864694468739376037" }, { - "Bool": true + "U64": "14494955386954077556" }, { - "Bool": false + "Address": "22dd3ae19101df11c7b57d184a33b7d08cf8fa67a8536f6542f6385aa329c5a8" + }, + { + "U64": "2662883762553180001" }, { - "U128": "265100979247294034163966764865660825792" + "Bool": true }, { - "U64": "2444078154558270811" + "U128": "308535887565064038273400162331148444955" }, { - "Bool": false + "U8Vector": "459e8b0d72cc0e8fde38a1f1bbaeba" }, { - "Address": "9b81e31773c73929717fdc08fa557a72b4a8b61b7a868ee433912a3e24d286a5" + "Bool": false } ] } }, - "max_gas_amount": "14612169717085905559", - "gas_unit_price": "13086807626326515660", - "expiration_timestamp_secs": "10010401325028931018", - "chain_id": 136 + "max_gas_amount": "11216059455577111357", + "gas_unit_price": "14327256314869360691", + "expiration_timestamp_secs": "8884530080395915140", + "chain_id": 172 }, - "signed_txn_bcs": "88afc70e42a0581de2a0f8a2203ba6561119cfcf5c700a5af04a5cc1cd7b1a3a3ebf81ee2b95b6df00022f3f020606077e5e718b46fd88b60652c76817cdf54ea65f09df094556296748debd14bf52db1b7a7258704b76497a67586a63524263456e494b42685165476c70310a624d7a6d416c5656413300072169cde70e0da53b3e9b21eaa69d3f8d048b3e81b463e18924d62ba8f682a90f166f4544484c7a5a73414b484842524c79647753794a4e0743744e71426930000703cf0b6010934d009f145b18293dc105c91af47d3b0ddd919775f195c9f945ef1a0501050002c0b0f692262eec5f1c28886c679770c7015bedbcdd211ceb210500039b81e31773c73929717fdc08fa557a72b4a8b61b7a868ee433912a3e24d286a59722a068f0dac8cacc9f100333ae9db5caf572bdf716ec8a88002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405bad7c727f36868e5739db1a31a0fe90cec947703e419df10006be73012a242980db35bce2f4d3ae149cdbc1d13ce77b82c5db6ae49959206abf5ec186c1a30d", + "signed_txn_bcs": "8f836387d1bcb38c1f228b9ed7d21c4477c624de28111c88e07ae56f1a6589f6db841a1028f5168a000e67841f8946c50a2fcab7eab03f830607e7c50b00e9ffc34885e2482cd79605b372e42ad5e69a1990cd7648ca1325a2ee196b456b59645368626b764f5173446a776441754867684e434f1a786e5452756e737647545770685465515a6b6f424241736374390007cae841b78fcba8e607bfe6302641170123917995db53f518ac40456d369901f1216272525259676f4f6476574c7250726d42414c54684e6771757361494547754d35207650524c5965646f42516258564155586c68736769424e686f537746507546390006060407eb82b083ba94e320953dd73399a18b9b9d57349f0602090b4bf9179ec38be9840c586c69584c5769596142463606654e487468300007f70cf6f34bfac4803a0a17b29bc8ba06b1b04b8bc12511b67ea6dd1a0f2b923e01420364585300079c4fcb2c59dd6675d8161e0555ebc6d464c7bde04e7bf7b7bb169a0932a98fff1a4362756d48427766776967616a5a66576c635751496a72697946165a6b4963576a747a6544574a63626275454d4d474d34000a0279ce5d2b9220bcc5dfc75637ba71a30a016ba91e43a10b960f01a5a318d6f724ecf7017455887a206d28c90322dd3ae19101df11c7b57d184a33b7d08cf8fa67a8536f6542f6385aa329c5a801614f2369ac76f4240501021b65fcb5178433ebd9be85ecb8d91de8040f459e8b0d72cc0e8fde38a1f1bbaeba05003dbb554da672a79b33a8c295b5a3d4c6846f452e09314c7bac002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d559570e40d4e10e3304239f3cf40766299462b8d7809f344d421fe7478700561cdce8f6d057d64203e3d77e2ad593995f7cab632bd1d820c8f175653cbd5e0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" } ] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer.json index 8340f651426..1d41d4f905c 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer.json @@ -1,10 +1,61 @@ { + "version": "5", "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "10", + "success": false, + "vm_status": "Move abort in 0x1::fungible_asset: EINSUFFICIENT_BALANCE(0x10004): Insufficient balance to withdraw or transfer.", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::aptos_account::transfer", "type_arguments": [], @@ -16,9 +67,28 @@ }, "signature": { "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", - "signature": "0xbdc9e553e86cdee876de3318bccd8c6499923b719ab5f189e8b43ba91771645f01c3ded4061e20b3bb85767e475dfe24f76b4aed46860c9328baf28d11d2c701", + "signature": "0x609170382f6feb1e025984a1a5dab4e8d2aff7de72c9290738089365b2b214f584bc4e474802ff04a9cfd1749bdf276c96068857a53c437d4d68a1d4239c8403", "type": "ed25519_signature" }, "replay_protection_nonce": null, - "type": "pending_transaction" + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "6", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "10" + } + } + ], + "timestamp": "1000000", + "type": "user_transaction" } + diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_orderless.json new file mode 100644 index 00000000000..4886d5adf89 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_orderless.json @@ -0,0 +1,60 @@ +{ + "version": "5", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "9", + "success": false, + "vm_status": "Move abort in 0x1::fungible_asset: EINSUFFICIENT_BALANCE(0x10004): Insufficient balance to withdraw or transfer.", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x75bc000000000000", + "value": "0x00000100013c0000000000000034bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f01010000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000155005300000001000134bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + "0x1", + "1" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0x3396b12d9b8d0f829884bec19ba2c6e5c10a06572ead792bb9289130b927699d7bf948f4e79f39efcf8bd3e67abdcfb7f3d2c193bbbcb9688fed709ce49c1f0e", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "6860028705977903330", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "6", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "9" + } + } + ], + "timestamp": "1000000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_payload_v2.json new file mode 100644 index 00000000000..3aac40ba983 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transaction_by_hash_with_delayed_internal_indexer_payload_v2.json @@ -0,0 +1,93 @@ +{ + "version": "5", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "10", + "success": false, + "vm_status": "Move abort in 0x1::fungible_asset: EINSUFFICIENT_BALANCE(0x10004): Insufficient balance to withdraw or transfer.", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + "0x1", + "1" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0xd01717d90548dc20267dd080cbb1d2b277e9024ef752ac5adc117e8e87140bef1b105dffb350d1b11ecdc3dda3c12fba587c148c869bdea69b19344e2434970b", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "6", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "10" + } + } + ], + "timestamp": "1000000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_empty_range.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_empty_range.json new file mode 100644 index 00000000000..fd44de5bd1d --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_empty_range.json @@ -0,0 +1,5 @@ +{ + "message": "Given start value (100) is higher than the current ledger version, it must be < 0", + "error_code": "invalid_input", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_limit.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_limit.json new file mode 100644 index 00000000000..d4e29ed85de --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_limit.json @@ -0,0 +1,5 @@ +{ + "message": "failed to parse parameter `limit`: failed to parse \"integer(uint16)\": invalid digit found in string (occurred while parsing \"optional\")", + "error_code": "web_framework_error", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_start_version.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_start_version.json new file mode 100644 index 00000000000..12c3112c4ea --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_invalid_start_version.json @@ -0,0 +1,5 @@ +{ + "message": "failed to parse parameter `start_version`: failed to parse \"string(U64)\": Parsing u64 string \"invalid\" failed, caused by error: invalid digit found in string", + "error_code": "web_framework_error", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_start_version_too_large.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_start_version_too_large.json new file mode 100644 index 00000000000..962f374a3fb --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_auxiliary_info_start_version_too_large.json @@ -0,0 +1,5 @@ +{ + "message": "Given start value (1000000) is higher than the current ledger version, it must be < 0", + "error_code": "invalid_input", + "vm_error_code": null +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload.json index 97fa4e43078..87b65c4e6d0 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload.json @@ -245,7 +245,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -256,7 +256,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x95915d42cd822b6195581e9be3c164b70afeb9228ebb68c2e3f14240e3f43a164caabae8096163c6a341fc3830b36618b4619b7d5f2edcd603690e91a62fdb05", + "signature": "0x87785983b4007292a001db5489ef3ea273d54833c3b90bb7a262b6639444e7572630ddb3c35245796e99577df54c8a7e5096cb061a94ccabd0bd76dfe1374e09", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_orderless.json new file mode 100644 index 00000000000..8b951e263b6 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_orderless.json @@ -0,0 +1,272 @@ +[ + { + "version": "1", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "1", + "new_block_events": { + "counter": "2", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 2, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "2" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "1" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::state_storage::StateStorageUsage", + "data": "state storage omitted" + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x01000000", + "value": "0x16838657edfae09cb9a71eb219025c4c87a67c4aaa86f20ac0aa792bc121ee42010000000000000001000000000000000100000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0020a1070000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x16838657edfae09cb9a71eb219025c4c87a67c4aaa86f20ac0aa792bc121ee42", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "1", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "1", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "500000", + "type": "block_metadata_transaction" + }, + { + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x3506000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c184ebe980f904d10c901010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c184ebe980f904d10c9013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x252dcf1ac634087648853d44cb216ff427d10e109c974c8f4ddf6feaf71b121777890aba49470c071a2791e7a67c64726beb0f4192c628c0372d7b70c54cbf07", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "14488165282383183438", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" + }, + { + "version": "3", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 2098 + }, + "type": "block_epilogue_transaction" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_payload_v2.json new file mode 100644 index 00000000000..06b18c98a41 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_output_user_transaction_with_entry_function_payload_payload_v2.json @@ -0,0 +1,303 @@ +[ + { + "version": "1", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "1", + "new_block_events": { + "counter": "2", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 2, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "2" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "1" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::state_storage::StateStorageUsage", + "data": "state storage omitted" + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x01000000", + "value": "0x4e9016838657edfae09cb9a71eb219025c4c87a67c4aaa86f20ac0aa792bc121010000000000000001000000000000000100000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0020a1070000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x4e9016838657edfae09cb9a71eb219025c4c87a67c4aaa86f20ac0aa792bc121", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "1", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "1", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "500000", + "type": "block_metadata_transaction" + }, + { + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa5a7c7e10f3329999eb018de4dd05d03829f79585327b3df63121a8526acef61", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x4d6a3f993b270af855850e6daa469524858865013dc1eb665a2e0e94fbca73540c28c0e03e2cfe7143abde25030f432772518e275342d43fef9f15414a4e4e04", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" + }, + { + "version": "3", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 2050 + }, + "type": "block_epilogue_transaction" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified.json index c0223234bee..bdf262d1b1b 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified.json @@ -256,7 +256,7 @@ "sequence_number": "12", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "66", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -267,7 +267,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xb30ffdbedfdee10b517ea68e45f0b1818bee51711e67be37f781873e42880e7676f340dc5f4efb3251a04b4579223102781f62613f6195b912ff0e86ee4fae04", + "signature": "0x7d7195aa31edee149b74dd55f0e6213ccc8b0856759a3d52c89e37610c57ab17ecbfa37fc9865cd0dd4532e1b68d2f31f6143f142145febcc639b9b303415200", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -548,7 +548,7 @@ "sequence_number": "13", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "66", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -559,7 +559,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x8586d3ba1d54c630418b039a45414e672f5c24345d902ecce6972e461c4f668018916956d25214202958cf708152d35319522396626d2badecc22a7613861b0c", + "signature": "0x76481ac6f346493c2aa82ff7b1cd9a8f5d3d962ab0d6c716c861ded848f6b92ea31fa9b8948f923b74f9f2433c75187dafe80e6d4da4bbb8b9cec41203286309", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -840,7 +840,7 @@ "sequence_number": "14", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "67", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -851,7 +851,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xf50c815eeb949b00002a33446a1b7247967a3957f928555b4cfae68022e5a1c76b0f7be98458300c98b5268d1df86e5b80d49ab7cbdb1207617427f580d1f405", + "signature": "0x9d47179318f912409ae709c68367d77a833db4a9598eea7154d7f3fd304294a69fd6ff28586ad7bccca12d143d7179eb7f229c238c2e0111ec2271e73d1d6c09", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -1132,7 +1132,7 @@ "sequence_number": "15", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "67", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -1143,7 +1143,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xbb3b9d47694bcd53e6ede0450d9f601703cd4a1a5fc6481f93ed866e398d895f97903d0f61a9c84d20e7f3d0ea84d2974694f3441f936474014bc050dbc69506", + "signature": "0x8632c38d870ba6b409761146b57647de201d508e98e2a894cae808a978ed4e882770d159e9fd6a0530af2c1466ac65f655043c66c032d577a34fdb292a58a50c", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -1424,7 +1424,7 @@ "sequence_number": "16", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "68", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -1435,7 +1435,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xe68c4ac0f33d1fb117a69706fb8c50a5422e83b5b1807431f0b8773f4c3fe9c33182f8cdc8baca1a11a64eafd40bbcaa42ee49c7043cb3d8860bdb3338ee790a", + "signature": "0x18a8be4e23e58f7dcf93d5c1f80cbc57b97687793f5f7bf368d809af8b700f7caf45eeca2befacc19bbb59b64c13b0b74d476e33d369696d777d49527d09b903", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -1716,7 +1716,7 @@ "sequence_number": "17", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "68", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -1727,7 +1727,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x008d33c2cb967f335b0487d09ed2fee498e87b106072027cd01233e8a35a9c74dbe27251e244b64904a6e2f00b9deefb9dcc0dd890313c834f2a6437baf49a03", + "signature": "0x0ac71506de7c8c46fdcc953ac04fc8fff35dcef968c41ef4351dc290950ab66ca567b4526c05cb481c1a6bb59cd1538405e5a61e74aa8da219a8cc1349a1cf0c", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -2008,7 +2008,7 @@ "sequence_number": "18", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "69", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -2019,7 +2019,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xcfd0d47f1932e231f48ef37538494b0360bee0c3ada183b1bc6f3e1e88c5d20ddb9c569a62a857efde687d908e32490f652676e1e3c87e035378bbb5ffe34e09", + "signature": "0xa20d74914f7b1a11655340f59b948c71e7b2cea728e9ed35f07e95c93e0d66cccb4aeca19664948f74d99ca4cdac997575164008270476dae41d8863c595d700", "type": "ed25519_signature" }, "replay_protection_nonce": null, @@ -2300,7 +2300,7 @@ "sequence_number": "19", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "69", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -2311,7 +2311,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xc531868a2a5691f5abe36a969e7657581fee8c99688627fffe26093aea423801c8a72178c47bc9f6ab2b7bd49a5fccbcb3c8d058d59bcf315b4197b5a52d3306", + "signature": "0x7d8398d7c316a5b443093ad32c5e903f4066d7214449358121add843520164343c1f9dba7b4365f6bb2098dfd8d19fc3a77426a772af903e85d188eb2b89e20a", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_orderless.json new file mode 100644 index 00000000000..fe137fccf5e --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_orderless.json @@ -0,0 +1,2110 @@ +[ + { + "version": "36", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "6000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "37", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "13", + "new_block_events": { + "counter": "14", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 14, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "14" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "13" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "6500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0d000000", + "value": "0x44bc4748768277b694cee503ea339ebb53fc221a6fc07f89f8048c6071e64607010000000000000001000000000000000d00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00a02e630000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x44bc4748768277b694cee503ea339ebb53fc221a6fc07f89f8048c6071e64607", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "13", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "13", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "6500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "6500000", + "type": "block_metadata_transaction" + }, + { + "version": "38", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xd49f48d99d681d4f9dc8e509f81e10cb66295a3112b5a12a635e2e46c819e98c", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xd49f48d99d681d4f9dc8e509f81e10cb66295a3112b5a12a635e2e46c819e98c", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x3054c2b469c941d36fc9eb2f2eaeaa8bc930dd016139363bc00d5218f29b6e49", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xd49f48d99d681d4f9dc8e509f81e10cb66295a3112b5a12a635e2e46c819e98c", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x0708000000000000", + "value": "0x00000100014200000000000000000000000000000000000000000000000000000000000000000000000a550c188d4ec4169ec51eac01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c188d4ec4169ec51eac0142000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "66", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x3054c2b469c941d36fc9eb2f2eaeaa8bc930dd016139363bc00d5218f29b6e49" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x5f966498770082de7dbe5d61a203597298d1c39084c38dcb7b0d799aaee894e0d2e9b63b0c9c4016e1aefea60a45f390d5a99d7ba740bbbcb488a6650c99480b", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12402567706602393229", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "6500000", + "type": "user_transaction" + }, + { + "version": "39", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "6500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "40", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "14", + "new_block_events": { + "counter": "15", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 15, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "15" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "14" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "7000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0e000000", + "value": "0xabc5297c436e67164ec8ea033ddcb6c382270184cb1c0e7044b272ba0b2382d2010000000000000001000000000000000e00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00c0cf6a0000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xabc5297c436e67164ec8ea033ddcb6c382270184cb1c0e7044b272ba0b2382d2", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "14", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "14", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "7000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "7000000", + "type": "block_metadata_transaction" + }, + { + "version": "41", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x3f564352f1c9fca61064327a84ee5f29cb0ae5094565e7fc8698e9f153451e9c", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x3f564352f1c9fca61064327a84ee5f29cb0ae5094565e7fc8698e9f153451e9c", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x7ca017f77d59c03ff6ed49667c2f1c975faba10e9a740e144a8751e513cb402e", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x3f564352f1c9fca61064327a84ee5f29cb0ae5094565e7fc8698e9f153451e9c", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0xda12000000000000", + "value": "0x00000100014200000000000000000000000000000000000000000000000000000000000000000000000a550c187e0398e87379048601010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c187e0398e8737904860142000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "66", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x7ca017f77d59c03ff6ed49667c2f1c975faba10e9a740e144a8751e513cb402e" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x3c48062a9f380ae8c1273aa48236ffbc0fdf06ea996e03ab926c717014e29bef9981c21d51ed029574b6da901bb37a3ec1e808fc7e1d18bf6428c35d1133dd0f", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "9656977039719662462", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "7000000", + "type": "user_transaction" + }, + { + "version": "42", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "7000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "43", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "15", + "new_block_events": { + "counter": "16", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 16, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "16" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "15" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "7500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0f000000", + "value": "0xdbef1abe62cb97d5716d5d05da6e72c49bf2791775d0465453e709d3d46d8aae010000000000000001000000000000000f00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00e070720000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xdbef1abe62cb97d5716d5d05da6e72c49bf2791775d0465453e709d3d46d8aae", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "15", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "15", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "7500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "7500000", + "type": "block_metadata_transaction" + }, + { + "version": "44", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xb60c29c3b9e81381675b796e82b4e17fb959b801eba4aafdfed93347c643da52", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xb60c29c3b9e81381675b796e82b4e17fb959b801eba4aafdfed93347c643da52", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x8f93dcfdcc2a8174fe9f75f6694c526e2b4d2a302fe4e50a374dc3640372bd19", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xb60c29c3b9e81381675b796e82b4e17fb959b801eba4aafdfed93347c643da52", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0xd993000000000000", + "value": "0x00000100014300000000000000000000000000000000000000000000000000000000000000000000000a550c18fa95d61536aac11c01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18fa95d61536aac11c0143000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "67", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x8f93dcfdcc2a8174fe9f75f6694c526e2b4d2a302fe4e50a374dc3640372bd19" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x628de2b1d61b6be73908bf76de1e154fdcfbeff59436083a479274fe634a0c523f5e0d9978be83f93bb1907445d99bba203fb6aa343b6b4a2bfa06a38118bd0d", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "2072124452838479354", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "7500000", + "type": "user_transaction" + }, + { + "version": "45", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "7500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "46", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "16", + "new_block_events": { + "counter": "17", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 17, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "17" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "16" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "8000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x10000000", + "value": "0x77db5fa5015d6961d2d00107d2f0b1323b9e27213f8b003f78a5cdd081007bd1010000000000000001000000000000001000000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0000127a0000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x77db5fa5015d6961d2d00107d2f0b1323b9e27213f8b003f78a5cdd081007bd1", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "16", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "16", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "8000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "8000000", + "type": "block_metadata_transaction" + }, + { + "version": "47", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xb20d59b2df01ec16f2e29c8e845a4ea7c6b512755c0e8dd151246299ea36ff5", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xb20d59b2df01ec16f2e29c8e845a4ea7c6b512755c0e8dd151246299ea36ff5", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xf4eaa4a8e7e3679b5b3e951c4ff5ffe3b1fcaa8124c48364f92841ce8fab0925", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xb20d59b2df01ec16f2e29c8e845a4ea7c6b512755c0e8dd151246299ea36ff5", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x6022000000000000", + "value": "0x00000100014300000000000000000000000000000000000000000000000000000000000000000000000a550c180e1cf81ce61e95d901010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c180e1cf81ce61e95d90143000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "67", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0xf4eaa4a8e7e3679b5b3e951c4ff5ffe3b1fcaa8124c48364f92841ce8fab0925" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x32de7e5bd2b3b3a214de0736ef403c5463f09f379157272bce9964686ff853e497561307b8c4b49961ed9c6deb27a79a0a12a15b9dff943a03e232b23ee8ee05", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "15678471651437583374", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "8000000", + "type": "user_transaction" + }, + { + "version": "48", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "8000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "49", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "17", + "new_block_events": { + "counter": "18", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 18, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "18" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "17" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "8500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x11000000", + "value": "0x7747a12ad1e8a8d6521a26daafda96dacf7f582cb1dbdc84c06e7953e5f1c769010000000000000001000000000000001100000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0020b3810000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x7747a12ad1e8a8d6521a26daafda96dacf7f582cb1dbdc84c06e7953e5f1c769", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "17", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "17", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "8500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "8500000", + "type": "block_metadata_transaction" + }, + { + "version": "50", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xedb8ebfc19f092c43bc531502fe161ad23745998b3d8843fc77fd369c023f616", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xedb8ebfc19f092c43bc531502fe161ad23745998b3d8843fc77fd369c023f616", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x19c02925b669c8a41ed35f90de405aaa00b17022318dfb20f2d8be840fd1da6f", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xedb8ebfc19f092c43bc531502fe161ad23745998b3d8843fc77fd369c023f616", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x3492000000000000", + "value": "0x00000100014400000000000000000000000000000000000000000000000000000000000000000000000a550c183da27e66ceaf2d6c01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c183da27e66ceaf2d6c0144000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "68", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x19c02925b669c8a41ed35f90de405aaa00b17022318dfb20f2d8be840fd1da6f" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x1cf6d4bf575b6328cfbf647f97a877ac6c098c74a0b7f186e288a50dc8f1c15933c9a5323275a204a1a1ca785831968f71e162687ef559c4e37f328651ce2a0a", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "7795079831065895485", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "8500000", + "type": "user_transaction" + }, + { + "version": "51", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "8500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "52", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "18", + "new_block_events": { + "counter": "19", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 19, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "19" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "18" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "9000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x12000000", + "value": "0x8082b67f142c31e08bfca525c34fa8a59ebcb300e72586225d613eb0af32ce80010000000000000001000000000000001200000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef004054890000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x8082b67f142c31e08bfca525c34fa8a59ebcb300e72586225d613eb0af32ce80", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "18", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "18", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "9000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "9000000", + "type": "block_metadata_transaction" + }, + { + "version": "53", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xfa956201a97b75f027cfb4d64d82d23d94f472d3ee7d5dad8c34f0b459b0dddd", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xfa956201a97b75f027cfb4d64d82d23d94f472d3ee7d5dad8c34f0b459b0dddd", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x7c1263324d545a1a6391f5a7d942803c6e0e774935f2461e2fc72b6476294a74", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xfa956201a97b75f027cfb4d64d82d23d94f472d3ee7d5dad8c34f0b459b0dddd", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x6951000000000000", + "value": "0x00000100014400000000000000000000000000000000000000000000000000000000000000000000000a550c18d0fa1d1755eff6c201010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18d0fa1d1755eff6c20144000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "68", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x7c1263324d545a1a6391f5a7d942803c6e0e774935f2461e2fc72b6476294a74" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xe96dc14a55afa5c4db1ee0f2579de1c65aa1f7ff58c63dabbc7e50ac527c369cdd139aa1dadaf0e12798dc1c16738800654fcd9a547b82013e490cffb1ac040b", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "14048679236367940304", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "9000000", + "type": "user_transaction" + }, + { + "version": "54", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "9000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "55", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "19", + "new_block_events": { + "counter": "20", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 20, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "20" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "19" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "9500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x13000000", + "value": "0x9350f6ce4988f3b078f37f863539358646c46f14aa24caa8745bf26f63f76d85010000000000000001000000000000001300000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0060f5900000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x9350f6ce4988f3b078f37f863539358646c46f14aa24caa8745bf26f63f76d85", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "19", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "19", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "9500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "9500000", + "type": "block_metadata_transaction" + }, + { + "version": "56", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x9f98c7053963daa3b87d278c7c6c7b749e274d65e8939cb9d0e8c17a4f0d49a3", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x9f98c7053963daa3b87d278c7c6c7b749e274d65e8939cb9d0e8c17a4f0d49a3", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xc865b12b1a24eca5eb06c33344f19dc1b9559389718c228ae7b58d29385667e1", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x9f98c7053963daa3b87d278c7c6c7b749e274d65e8939cb9d0e8c17a4f0d49a3", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x9158000000000000", + "value": "0x00000100014500000000000000000000000000000000000000000000000000000000000000000000000a550c1880512a0fa37a6c8201010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c1880512a0fa37a6c820145000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "69", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0xc865b12b1a24eca5eb06c33344f19dc1b9559389718c228ae7b58d29385667e1" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x3a54f64b19603a256add18fdff6be2abd2245591511744636197ba0f016283a899c39825d661b731a571386b412655e89252d7b764d0b6095cbee5843126ec05", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "9398021363168072064", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "9500000", + "type": "user_transaction" + }, + { + "version": "57", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "9500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "58", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "20", + "new_block_events": { + "counter": "21", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 21, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "21" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "20" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "10000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x14000000", + "value": "0xb630835e1130f3706c99a15b7ec96c7a55304cfdea53323fe5d5b0e962b18cd8010000000000000001000000000000001400000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef008096980000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xb630835e1130f3706c99a15b7ec96c7a55304cfdea53323fe5d5b0e962b18cd8", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "20", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "20", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "10000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "10000000", + "type": "block_metadata_transaction" + }, + { + "version": "59", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1c5491752bfbc0a6d7baae2588335309724a9771e6bd09226fbec1195f669770", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1c5491752bfbc0a6d7baae2588335309724a9771e6bd09226fbec1195f669770", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xc1dd38dc3c46578e98fb9aeb7b3119736c1eef281e203ed5514935304ea0a715", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1c5491752bfbc0a6d7baae2588335309724a9771e6bd09226fbec1195f669770", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0xd091000000000000", + "value": "0x00000100014500000000000000000000000000000000000000000000000000000000000000000000000a550c183fa15980873a1c6a01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c183fa15980873a1c6a0145000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "69", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0xc1dd38dc3c46578e98fb9aeb7b3119736c1eef281e203ed5514935304ea0a715" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x57b2c3b20fcffd399534b95013622785c3c2e07e19bd0e2f86107d8948df236b95810892d6fc643449fe1a976125ecb41512416be985e2113bf6db0bd1cdc102", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "7646050621016613183", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "10000000", + "type": "user_transaction" + }, + { + "version": "60", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "10000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1976 + }, + "type": "block_epilogue_transaction" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_payload_v2.json new file mode 100644 index 00000000000..6d21201fe8d --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_transactions_returns_last_page_when_start_version_is_not_specified_payload_v2.json @@ -0,0 +1,2358 @@ +[ + { + "version": "36", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "6000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "37", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "13", + "new_block_events": { + "counter": "14", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 14, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "14" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "13" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "6500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0d000000", + "value": "0x8c9a041f736278db6559cb7f1de04381d82258dc80fa9e128d9e44bc47487682010000000000000001000000000000000d00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00a02e630000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x8c9a041f736278db6559cb7f1de04381d82258dc80fa9e128d9e44bc47487682", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "13", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "13", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "6500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "6500000", + "type": "block_metadata_transaction" + }, + { + "version": "38", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "13", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xadb2885ebb15b1f40f722f5e0a80179ff8b0ede32bbfb642c934516b1e057058", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xadb2885ebb15b1f40f722f5e0a80179ff8b0ede32bbfb642c934516b1e057058", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x48a951fe0ed12b29517867e00a3a09da55fcf859497b3f04bbed911cb75669c9", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xadb2885ebb15b1f40f722f5e0a80179ff8b0ede32bbfb642c934516b1e057058", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "12", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "66", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x48a951fe0ed12b29517867e00a3a09da55fcf859497b3f04bbed911cb75669c9" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x7d93fc8f62297cb558e40f4c599952926c24906374774c71cdb343475d8cd3b5e9df4c9e2c5854031d417de6f5a6ce66fdd53be3b8cc4891072fd5bfe84c1b03", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "6500000", + "type": "user_transaction" + }, + { + "version": "39", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "6500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "40", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "14", + "new_block_events": { + "counter": "15", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 15, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "15" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "14" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "7000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0e000000", + "value": "0x9ebb53fc221a6fc07f89f8048c6071e6460792b92ffe078247a77e73abc5297c010000000000000001000000000000000e00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00c0cf6a0000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x9ebb53fc221a6fc07f89f8048c6071e6460792b92ffe078247a77e73abc5297c", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "14", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "14", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "7000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "7000000", + "type": "block_metadata_transaction" + }, + { + "version": "41", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "14", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa0bab603226725093b82456fce79fc6ffd0b0242da7a447905f54a6e1564bb5e", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xa0bab603226725093b82456fce79fc6ffd0b0242da7a447905f54a6e1564bb5e", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x95f70f0272707f73ce63f9b09497324a7b2c9118d5d5fb22cb373efd916a681", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa0bab603226725093b82456fce79fc6ffd0b0242da7a447905f54a6e1564bb5e", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "13", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "66", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x95f70f0272707f73ce63f9b09497324a7b2c9118d5d5fb22cb373efd916a681" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x0d76c2ac744b1934b37fd95ecfb99de736a6270f596d5c01c9651e6dee3b8ab354cb3ebbbcb6b727a7c2f98afa86a4120b9cb728ad3799f68a96dd749a88e40f", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "7000000", + "type": "user_transaction" + }, + { + "version": "42", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "7000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "43", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "15", + "new_block_events": { + "counter": "16", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 16, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "16" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "15" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "7500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0f000000", + "value": "0x3ddcb6c382270184cb1c0e7044b272ba0b2382d21b06966dd5ff00f5fa36dbef010000000000000001000000000000000f00000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef00e070720000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x3ddcb6c382270184cb1c0e7044b272ba0b2382d21b06966dd5ff00f5fa36dbef", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "15", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "15", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "7500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "7500000", + "type": "block_metadata_transaction" + }, + { + "version": "44", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "15", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xb8fb34fff0d4667cca610f6a39f46fb185a0c38c4b3f2180e8243baae09a9233", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xb8fb34fff0d4667cca610f6a39f46fb185a0c38c4b3f2180e8243baae09a9233", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x4c989e245d6ce3f3735edb8ef9f84c34d5e6f0991bea502b05cd1ea74d327a22", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xb8fb34fff0d4667cca610f6a39f46fb185a0c38c4b3f2180e8243baae09a9233", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "14", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "67", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x4c989e245d6ce3f3735edb8ef9f84c34d5e6f0991bea502b05cd1ea74d327a22" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x0c536b0d8b0f50ee4645b3921dafa22320f266e430950f3f3ebbe5696839690509c93f869617fff7e5c327ebf247bfb1881cb92480bfbc00c74485a640404403", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "7500000", + "type": "user_transaction" + }, + { + "version": "45", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "7500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "46", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "16", + "new_block_events": { + "counter": "17", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 17, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "17" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "16" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "8000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x10000000", + "value": "0x5d05da6e72c49bf2791775d0465453e709d3d46d8aae837610781514ae1b0ee6010000000000000001000000000000001000000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0000127a0000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x5d05da6e72c49bf2791775d0465453e709d3d46d8aae837610781514ae1b0ee6", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "16", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "16", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "8000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "8000000", + "type": "block_metadata_transaction" + }, + { + "version": "47", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "16", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xe28877394a60cd44b093e5d03e2468425f3ca413142b14041ad9fe608057eb43", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xe28877394a60cd44b093e5d03e2468425f3ca413142b14041ad9fe608057eb43", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x46925daed0a8767bb9437ccccfdf31a1d349a05659710ca0ebe6205d0e5d737e", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xe28877394a60cd44b093e5d03e2468425f3ca413142b14041ad9fe608057eb43", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "15", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "67", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x46925daed0a8767bb9437ccccfdf31a1d349a05659710ca0ebe6205d0e5d737e" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xef9d14d4af480f997de05ab361d3460e75842b2bf9722a5f52ec2e82f9f117bdf590e029344b81bf5d356375c6ed0134d1e35b417f93bcb776d6d4f183799109", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "8000000", + "type": "user_transaction" + }, + { + "version": "48", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "8000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "49", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "17", + "new_block_events": { + "counter": "18", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 18, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "18" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "17" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "8500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x11000000", + "value": "0xd2d00107d2f0b1323b9e27213f8b003f78a5cdd081007bd11f09b7e6fa232b0a010000000000000001000000000000001100000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0020b3810000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xd2d00107d2f0b1323b9e27213f8b003f78a5cdd081007bd11f09b7e6fa232b0a", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "17", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "17", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "8500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "8500000", + "type": "block_metadata_transaction" + }, + { + "version": "50", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "17", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xdfae4941c4dbe0c7ed4543feece09d34c7f34960cf2da0ea2f2cc2c0dc34b448", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xdfae4941c4dbe0c7ed4543feece09d34c7f34960cf2da0ea2f2cc2c0dc34b448", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xfcad780f86d4ee8a3a200bb9289f77eb824bf1d6c155c8d007fc128bfbc33e06", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xdfae4941c4dbe0c7ed4543feece09d34c7f34960cf2da0ea2f2cc2c0dc34b448", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "16", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "68", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0xfcad780f86d4ee8a3a200bb9289f77eb824bf1d6c155c8d007fc128bfbc33e06" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xdff22c4c07958ffc0cdedcac0436c45ed8e530e0641eddb7d7e8ea14f491462cad8c69d11bc1463b53e49dbfd0e265d2b5563475a2965c78fb81db5f8b5e7001", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "8500000", + "type": "user_transaction" + }, + { + "version": "51", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "8500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "52", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "18", + "new_block_events": { + "counter": "19", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 19, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "19" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "18" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "9000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x12000000", + "value": "0xa8d6521a26daafda96dacf7f582cb1dbdc84c06e7953e5f1c769ef8a93dcbeb3010000000000000001000000000000001200000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef004054890000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xa8d6521a26daafda96dacf7f582cb1dbdc84c06e7953e5f1c769ef8a93dcbeb3", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "18", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "18", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "9000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "9000000", + "type": "block_metadata_transaction" + }, + { + "version": "53", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "18", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xbcb8fb1dda89003b79b30b8a5c2e0714119e8648cdd87779174bfd4f3ca29b4a", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xbcb8fb1dda89003b79b30b8a5c2e0714119e8648cdd87779174bfd4f3ca29b4a", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x99acce340661e0c847ca95ff58ced5f474bc30ca7972106e6a90055c1bdeb26", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xbcb8fb1dda89003b79b30b8a5c2e0714119e8648cdd87779174bfd4f3ca29b4a", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "17", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "68", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x99acce340661e0c847ca95ff58ced5f474bc30ca7972106e6a90055c1bdeb26" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xc143a045fc3ab2cc5d3dbf3b3adb1b6011a6f96f5c03be62b9a51a1f61ed1bef8985730d0b34f9aabe0be462141e1755830cc4dca895ef266e90aadbc0b8d406", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "9000000", + "type": "user_transaction" + }, + { + "version": "54", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "9000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "55", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "19", + "new_block_events": { + "counter": "20", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 20, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "20" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "19" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "9500000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x13000000", + "value": "0x142c31e08bfca525c34fa8a59ebcb300e72586225d613eb0af32ce80b0e9529f010000000000000001000000000000001300000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef0060f5900000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0x142c31e08bfca525c34fa8a59ebcb300e72586225d613eb0af32ce80b0e9529f", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "19", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "19", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "9500000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "9500000", + "type": "block_metadata_transaction" + }, + { + "version": "56", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "19", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x20e001b1c0a729eb30c28f728001e410b406a2fd8d4d72f49e7c6aefdc926974", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x20e001b1c0a729eb30c28f728001e410b406a2fd8d4d72f49e7c6aefdc926974", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0xe9be740413c5f028e58ca77e0540355874c210b49bcd8a75db8880a7ac3273cd", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x20e001b1c0a729eb30c28f728001e410b406a2fd8d4d72f49e7c6aefdc926974", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "18", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "69", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0xe9be740413c5f028e58ca77e0540355874c210b49bcd8a75db8880a7ac3273cd" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xf91f99ef707824f8fdddfda7b3d4b0bcfe999c8ae28cfe9e78e9582b89487d2ee6abfad966ca80fc2eb4135fa058c26ca8cdf1878684e684a5ff8e403623800d", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "9500000", + "type": "user_transaction" + }, + { + "version": "57", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "9500000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + }, + { + "version": "58", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::BlockResource", + "data": { + "epoch_interval": "86400000000", + "height": "20", + "new_block_events": { + "counter": "21", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "3" + } + } + }, + "update_epoch_interval_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x1", + "creation_num": "4" + } + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::block::CommitHistory", + "data": { + "max_capacity": 2000, + "next_idx": 21, + "table": { + "inner": { + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97" + }, + "length": "21" + } + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::stake::ValidatorPerformance", + "data": { + "validators": [ + { + "failed_proposals": "0", + "successful_proposals": "20" + } + ] + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::timestamp::CurrentTimeMicroseconds", + "data": { + "microseconds": "10000000" + } + }, + "type": "write_resource" + }, + { + "address": "0x1", + "state_key_hash": "", + "data": { + "type": "0x1::randomness::PerBlockRandomness", + "data": { + "epoch": "1", + "round": "1", + "seed": { + "vec": [] + } + } + }, + "type": "write_resource" + }, + { + "state_key_hash": "", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x14000000", + "value": "0xf6ce4988f3b078f37f863539358646c46f14aa24caa8745bf26f63f76d85fdbd010000000000000001000000000000001400000000000000010066b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef008096980000000000", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "id": "0xf6ce4988f3b078f37f863539358646c46f14aa24caa8745bf26f63f76d85fdbd", + "epoch": "1", + "round": "1", + "events": [ + { + "guid": { + "creation_number": "3", + "account_address": "0x1" + }, + "sequence_number": "20", + "type": "0x1::block::NewBlockEvent", + "data": { + "epoch": "1", + "failed_proposer_indices": [], + "hash": "", + "height": "20", + "previous_block_votes_bitvec": "0x00", + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "round": "1", + "time_microseconds": "10000000" + } + } + ], + "previous_block_votes_bitvec": [ + 0 + ], + "proposer": "0x66b22b7465af92a9dc8d07d2878716d9dffbbb280830a7d8cf80334b5da812ef", + "failed_proposer_indices": [], + "timestamp": "10000000", + "type": "block_metadata_transaction" + }, + { + "version": "59", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "8", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "20", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + }, + { + "address": "0xcb28bc22052a55ddaf1dcea8de7c24318d46b6c72f1b7b869d142fa5dfcd5a79", + "state_key_hash": "", + "data": { + "type": "0x1::fungible_asset::FungibleStore", + "data": { + "balance": "0", + "frozen": false, + "metadata": { + "inner": "0xa" + } + } + }, + "type": "write_resource" + }, + { + "address": "0xcb28bc22052a55ddaf1dcea8de7c24318d46b6c72f1b7b869d142fa5dfcd5a79", + "state_key_hash": "", + "data": { + "type": "0x1::object::ObjectCore", + "data": { + "allow_ungated_transfer": false, + "guid_creation_num": "1125899906842625", + "owner": "0x626d590a97d6b59c93711a3cdc7aea92eca7fc5c3615084f43394791f1d6d300", + "transfer_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xcb28bc22052a55ddaf1dcea8de7c24318d46b6c72f1b7b869d142fa5dfcd5a79", + "creation_num": "1125899906842624" + } + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "19", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "69", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x626d590a97d6b59c93711a3cdc7aea92eca7fc5c3615084f43394791f1d6d300" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x8af185d5f77942e4717cf54336ade5b67ecf13b88b4147c828236526bfffbbe3ed61e8d1e5817c5ae88f9c1caf4ff49aefa0d0fa0bda119987959d04cae51305", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "8" + } + } + ], + "timestamp": "10000000", + "type": "user_transaction" + }, + { + "version": "60", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": "", + "gas_used": "0", + "success": true, + "vm_status": "Executed successfully", + "accumulator_root_hash": "", + "changes": [], + "timestamp": "10000000", + "block_end_info": { + "block_gas_limit_reached": false, + "block_output_limit_reached": false, + "block_effective_block_gas_units": 18, + "block_approx_output_size": 1928 + }, + "type": "block_epilogue_transaction" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation.json index af527327a9b..5957587fa66 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::Coin::transfer", "type_arguments": [ @@ -69,7 +69,7 @@ }, "signature": { "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", - "signature": "0x72e5b26a971d06d000f7e4a805b46623428d610f66d8425baa81e60522da00ab5c8e874377b2619dae1ddbf9141f41f71a97aed927b8eee2e6683e6b19e4ae00", + "signature": "0xc0db41f2f9edb1af7ad1e1f8351256f81662b82bb6cc8c7c2637cbe4379a931d702db53ff265324fdb88e91b3d6bca477262d9a9b1164e1b9668b320e8206600", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_orderless.json new file mode 100644 index 00000000000..21e7232bb78 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_orderless.json @@ -0,0 +1,62 @@ +{ + "version": "5", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x75bc000000000000", + "value": "0x00000100013c0000000000000034bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f01010000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000155005300000001000134bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x7b00000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0xf8f6a45f5a5e2d1a6360a1077e2b23a715e831199245d3ec77c4d316204089b533d22895db0cb95422c9c893ac383aad79a7622d333fa47f2093e94e0b77aa0c", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "6860028705977903330", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "1000000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_payload_v2.json new file mode 100644 index 00000000000..8c7d9d658a6 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_entry_function_validation_payload_v2.json @@ -0,0 +1,95 @@ +{ + "version": "5", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "4", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x7b00000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0xef331b1da837200b9c664cc6c91fa759914feaa320d7ec5e5b8ecadb4deedf95ec2870d3774645347181fe132dfa51464156f7e98d7c8d4f3833278493452e00", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "1", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "4" + } + } + ], + "timestamp": "1000000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address.json index e6e8e5d8149..1bd2c3f6c5c 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1222::Coin::transfer", "type_arguments": [ @@ -69,7 +69,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xf2193dc55d63b63b5e45cee43d38e5a77dc127fc57f4bea7aff6ee09806332850eaa321f2fb7cf6662568c9dd65654642a240b3272d9ad06b2700cb2ff246004", + "signature": "0xb12a7a0e0967958e6f8bb92d1b77eef24c51605fe3f596648cdb2eefe504f347476559be2e27adefa955dc17c4bbea63b55a6785e39289170c35beca86217009", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_orderless.json new file mode 100644 index 00000000000..a5a382e49db --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_orderless.json @@ -0,0 +1,62 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1222::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x1fe15468067821b68a690ae156359ff4ebfb5daffbcebfb8083447c552f62da709e570b9512d7d3da8867d96efe5a8bf2badade3315d156b3c28b6f5cef5e705", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_payload_v2.json new file mode 100644 index 00000000000..7a08f3b00f7 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_address_payload_v2.json @@ -0,0 +1,95 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1222::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x0cbf78232cbeb10c9bae50ef038dd8491f73696dbb64f20b72dd5ccd30c35b14bf0815fb0f510d5e7c75d29b63ff464f6daf4a9069ae09fe45bc65fc8683e50a", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments.json index fc4b49a8f9d..e2ec9d3b782 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::Coin::transfer", "type_arguments": [ @@ -69,7 +69,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x20e1f74f12aa955275a9d1a63190065d77e1903cc53b0116b704b3ace98fd7a57d303738799840523688cdaaad74ee0c73b6bee53517e4dcd6e7589296711108", + "signature": "0x70a98987e413c5174b0118da5390e867c8bd6da19fb951a4b8b335754accf3cb6e71d1da7067ea45212702526e8dc644efc9e8443343788eebea85f5367b850f", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_orderless.json new file mode 100644 index 00000000000..88db8dd1e68 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_orderless.json @@ -0,0 +1,62 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x01" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x98b18bc09fcc90c04ab8e6c6d8b3054c6a18026958a03008c53083b781204c7e1e5ccb1a61ebff3a929710a883dab1f95ab2123f0edd0f90adf56571db27db06", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_payload_v2.json new file mode 100644 index 00000000000..836c8ff063a --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_arguments_payload_v2.json @@ -0,0 +1,95 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x01" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x11d7e739f4ef83cb553746812bc31ca60eeed177ce3340050ea38abbd24d62d2ec209a7ceae90504045721040a8e98775fb5ffa766379eaf63f9535c2b1b5e00", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name.json index 7b5393b67c1..4f458a5edaa 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::CoinInvalid::transfer", "type_arguments": [ @@ -69,7 +69,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xb194e9398f2af5e20642ff606d0f456b449333966533965b55551498551058dff8c23f9b92033e6536c5b37e9b41d8ce2619dfd5d9c05cd9159849172bc77e09", + "signature": "0xdcfe51287625832fdc5ba59a739a991ddb8d3e2495507e069c9ad21827d417baa036c473bc9f542ab42b6880394f6f38e3a17ee2156342ca3b27b3b917d4fc09", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_orderless.json new file mode 100644 index 00000000000..d1aa6895a85 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_orderless.json @@ -0,0 +1,62 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::CoinInvalid::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xb2e86ede7857ec640a89b83006d61d87acdb198a7b8218520464a0669051dd0f8ec1539ae712f5bc4ad0f71e96119379f920bb8b9385806369b1491d040e960e", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_payload_v2.json new file mode 100644 index 00000000000..e9b6113727e --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_module_name_payload_v2.json @@ -0,0 +1,95 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::CoinInvalid::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xeb9668fc96e9fe1f2ce4469fa44426010c5ce622644f484300d4849b58b3caad53183d3096eeff318f8d81a456452391cbb874ef4344cfbc9fa647dc68f0910e", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name.json index 379395bb1df..d04468cd7ad 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::Coin::transfer_invalid", "type_arguments": [ @@ -69,7 +69,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xd6b761a82e7f6d3e79a7e27873ef1c07ba8c1a0abbd577f1829b164c9be1844672da3ed41880815ce00068d0f7dccf685b97ff4dc12bbb5548f4cd91d1354c0b", + "signature": "0x18ac41fd53b49bd18888e0f29597c021bc78d96baec85ec14e68bf9cdd628caf3b79c29d51f642406c05f30a3a6a532a0123fdee8933b2986bec511bf2a0df07", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_orderless.json new file mode 100644 index 00000000000..53e524ec062 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_orderless.json @@ -0,0 +1,62 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer_invalid", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xf58401f3da14c3e8bdd45c689d538069e7cf46dcd36a1ad77ee36939dd1528e167355600375b49dc766d440cb42223f1e6df5791ef1fb32ddaa6d0a1b8906005", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_payload_v2.json new file mode 100644 index 00000000000..6e675dc07a5 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_entry_function_name_payload_v2.json @@ -0,0 +1,95 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer_invalid", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x79abcd16c93d1c86b74a1694793c41709a0546d1a104b51807852fffcce2265dc9519da650ea4b56f9af108e5710ab514701207c7454f2832bf4a8eae16ae607", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode.json index 3c255cff84f..c778ced5986 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "code": { "bytecode": "0xa11ceb0b030000", @@ -67,7 +67,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x236b781174b798468499e339c4f0da5a93ed0ac5570d0b1d7d81f36438a571406e1d8c1d68832208efa680ae60165e80a5f11f7fc516cac2331a71c03722980c", + "signature": "0x8e73997d04f84f10d5554e9fa7425dddee00ce0d21d0c46e5c800fc2a1aa59f9f98825ad3b363528dec8ab2d914e7937be922448645904269ac0f22a8ba31602", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_orderless.json new file mode 100644 index 00000000000..7456183ba76 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_orderless.json @@ -0,0 +1,60 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "CODE_DESERIALIZATION_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "code": { + "bytecode": "0xa11ceb0b030000", + "abi": null + }, + "type_arguments": [], + "arguments": [], + "type": "script_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x29a463016ef1b754402049e4c83bfaba390acded7e680a795d2a2ecaf56501210f86a61e973160e9d083dfbb45e36a93ea77492267e7efae2b629fd55e44fd02", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_payload_v2.json new file mode 100644 index 00000000000..5e500ce075e --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_invalid_script_payload_bytecode_payload_v2.json @@ -0,0 +1,93 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "CODE_DESERIALIZATION_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "code": { + "bytecode": "0xa11ceb0b030000", + "abi": null + }, + "type_arguments": [], + "arguments": [], + "type": "script_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0xe6916390f16899d3b0a1803d5146ff25830c0daa1831b9a77563f1184ccbcdf346c3a557d9da143881ba861821c64660ae7dbb148f35118fe933217395f1a60c", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments.json index 9dde7e254ed..060a182f854 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments.json @@ -55,7 +55,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::Coin::transfer", "type_arguments": [ @@ -68,7 +68,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0xf7a1aed9f810371e18921418a19686855e0e705101c048f907038df2ea4094c526ef26906fae5bb4f381ec5dd80e8459aea72e709e4f07d4a633658317a99b0b", + "signature": "0xcb99ebc01e99b7c909a4286be751db0e8b3714761635c31f846cabb7436a3cf920440639738617410c536aecbd659f65ec4df11bd254b3f87edcfa78a021800c", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_orderless.json new file mode 100644 index 00000000000..a9c927cf357 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_orderless.json @@ -0,0 +1,61 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": null, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x855088fc095867bd113d6ae3b11752d80daadf4783083863bc6ff63c3eac75c463d5280ad2863b121ae287469ef89d95c374dd90f6c61b0ba7ec1c8594850703", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_payload_v2.json new file mode 100644 index 00000000000..88da69fe9a7 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_get_txn_execute_failed_by_missing_entry_function_arguments_payload_v2.json @@ -0,0 +1,94 @@ +{ + "version": "2", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::Coin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x7ebf97bef9445b0e57eac9752da324964d7f2f3b53b92867b9f30f9f146039c9140b236c3bac11df1a341eba4f9441c6dbcd123dc9bd2d8db5395663624db301", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "500000", + "type": "user_transaction" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction.json b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction.json index 3bb570f7789..b25d97f6ca5 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction.json @@ -4,7 +4,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::aptos_account::create_account", "type_arguments": [], @@ -15,7 +15,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x95915d42cd822b6195581e9be3c164b70afeb9228ebb68c2e3f14240e3f43a164caabae8096163c6a341fc3830b36618b4619b7d5f2edcd603690e91a62fdb05", + "signature": "0x87785983b4007292a001db5489ef3ea273d54833c3b90bb7a262b6639444e7572630ddb3c35245796e99577df54c8a7e5096cb061a94ccabd0bd76dfe1374e09", "type": "ed25519_signature" }, "replay_protection_nonce": null diff --git a/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_orderless.json new file mode 100644 index 00000000000..470115da8d5 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_orderless.json @@ -0,0 +1,22 @@ +{ + "hash": "", + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x252dcf1ac634087648853d44cb216ff427d10e109c974c8f4ddf6feaf71b121777890aba49470c071a2791e7a67c64726beb0f4192c628c0372d7b70c54cbf07", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "14488165282383183438" +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_payload_v2.json new file mode 100644 index 00000000000..5ceca66579c --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_post_bcs_format_transaction_payload_v2.json @@ -0,0 +1,22 @@ +{ + "hash": "", + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::create_account", + "type_arguments": [], + "arguments": [ + "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x4d6a3f993b270af855850e6daa469524858865013dc1eb665a2e0e94fbca73540c28c0e03e2cfe7143abde25030f432772518e275342d43fef9f15414a4e4e04", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null +} diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error.json index fb33493e443..e5bd6115fa9 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error.json @@ -56,7 +56,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::MemeCoin::transfer", "type_arguments": [ @@ -70,7 +70,7 @@ }, "signature": { "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", - "signature": "0x1d4f1d6c0b140deb6c63e81c742ffd546c832683a14970c687fa823641d34395197548c242c126ea7226730ce66b9ab2f695a2bcda982f30944163179f9a3c08", + "signature": "0xd707033e15d4423b64ffff6fe0df9ac3feffa948bc0528f877ee5f1d73937911206237f4e3c9c14886294da213c30aef57eb41530dc7b923479864fa8ab0fa07", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_orderless.json new file mode 100644 index 00000000000..bb2b7352f64 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_orderless.json @@ -0,0 +1,65 @@ +[ + { + "version": "0", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR\nExecution failed with message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000001::MemeCoin doesn't exist", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x540f000000000000", + "value": "0x00000100013c00000000000000000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad01010000000000000000000000000000000000000a00000000000000010000000000000000000000000100000000000000010000000000000001550053000000010001000000000000000000000000000000000000000000000000000000000a550c18e5a688742b47c5ad013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0xa550c18", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::MemeCoin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x87d02d3b1dbea4748e382f80e0c6a440f921a7873ed49dc391d9d93772bd390bcec0b366c3dbb0dd81bbe3327731a9cf1bd3580ecf186842edb5a9b5c1a3d800", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "12521492590937810661", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "0" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_payload_v2.json new file mode 100644 index 00000000000..bdd44ffd709 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_detail_error_payload_v2.json @@ -0,0 +1,96 @@ +[ + { + "version": "0", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "3", + "success": false, + "vm_status": "LINKER_ERROR\nExecution failed with message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000001::MemeCoin doesn't exist", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0xa550c18", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0xcef8ffd1ab9017e96132df8a56b22de39a8155e1c3fc32affbbf93eb624b532a", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0xa550c18", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0xa550c18", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::MemeCoin::transfer", + "type_arguments": [ + "0x1::aptos_coin::AptosCoin" + ], + "arguments": [ + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x0100000000000000" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0x14418f867a0bd6d42abb2daa50cd68a5a869ce208282481f57504f630510d0d3", + "signature": "0x5dfea1a4ea3d405634e1cc2257742582f6312c549ce9db5113985a82662be88c6d50423830f20e299e90414e11312344e7d416b891c5e02aac8c620d9b8f4900", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "3", + "io_gas_units": "0", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "3" + } + } + ], + "timestamp": "0" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering.json index f6f6ef3bf76..35ad258a286 100644 --- a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering.json +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering.json @@ -56,7 +56,7 @@ "sequence_number": "0", "max_gas_amount": "100000000", "gas_unit_price": "0", - "expiration_timestamp_secs": "18446744073709551615", + "expiration_timestamp_secs": "60", "payload": { "function": "0x1::aptos_account::transfer", "type_arguments": [], @@ -68,7 +68,7 @@ }, "signature": { "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", - "signature": "0x0090fadcba9d32d9918286f8b651772a4d04a23633cc9d10f4339ad4d0b1b7c4ca4829542aa9a8b5a6a28e0e63dfd52863d38ca1ba1d2a57c4bf1efc72c0fb06", + "signature": "0xdfb01d03aa6b7a9761f847294546ad8ff5b5fd5a91d4da659ce0288bf240105aa1938fa40e8b3fc72c47cb37a16801f911f53fe7907eb67540c93abab3204b0c", "type": "ed25519_signature" }, "replay_protection_nonce": null, diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_orderless.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_orderless.json new file mode 100644 index 00000000000..291acb685e3 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_orderless.json @@ -0,0 +1,63 @@ +[ + { + "version": "3", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "9", + "success": false, + "vm_status": "Move abort in 0x1::fungible_asset: EINSUFFICIENT_BALANCE(0x10004): Insufficient balance to withdraw or transfer.", + "accumulator_root_hash": "", + "changes": [ + { + "state_key_hash": "", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0x75bc000000000000", + "value": "0x00000100013c0000000000000034bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f01010000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000155005300000001000134bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afafe2a8cb18c3b7335f013c000000000000000000000000000000000000000000000000000a0000000000000001000000000000000000000000010000000000000001000000000000000166005500", + "data": { + "data": null + }, + "type": "write_table_item" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "18446744073709551615", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + "0x1", + "999999999999999999" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0x164f0a1bc359da6e509275fa368df787bea736807b1638e7c7d5714d012348ccf5dc83883a6f79082420b2819b3e41ceb1a4c31ef0e04ce022afea5e646fb107", + "type": "ed25519_signature" + }, + "replay_protection_nonce": "6860028705977903330", + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "5", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "9" + } + } + ], + "timestamp": "500000" + } +] diff --git a/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_payload_v2.json b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_payload_v2.json new file mode 100644 index 00000000000..278aca509c0 --- /dev/null +++ b/api/goldens/aptos_api__tests__transactions_test__test_simulation_failure_with_move_abort_error_rendering_payload_v2.json @@ -0,0 +1,94 @@ +[ + { + "version": "3", + "hash": "", + "state_change_hash": "", + "event_root_hash": "", + "state_checkpoint_hash": null, + "gas_used": "10", + "success": false, + "vm_status": "Move abort in 0x1::fungible_asset: EINSUFFICIENT_BALANCE(0x10004): Insufficient balance to withdraw or transfer.", + "accumulator_root_hash": "", + "changes": [ + { + "address": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "state_key_hash": "", + "data": { + "type": "0x1::account::Account", + "data": { + "authentication_key": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "coin_register_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "0" + } + } + }, + "guid_creation_num": "2", + "key_rotation_events": { + "counter": "0", + "guid": { + "id": { + "addr": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "creation_num": "1" + } + } + }, + "rotation_capability_offer": { + "for": { + "vec": [] + } + }, + "sequence_number": "1", + "signer_capability_offer": { + "for": { + "vec": [] + } + } + } + }, + "type": "write_resource" + } + ], + "sender": "0x34bf7e2d17674feb234371a7ea58efd715f0e56ba20ebf13789480d9d643afaf", + "sequence_number": "0", + "max_gas_amount": "100000000", + "gas_unit_price": "0", + "expiration_timestamp_secs": "60", + "payload": { + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + "0x1", + "999999999999999999" + ], + "type": "entry_function_payload" + }, + "signature": { + "public_key": "0xd5a781494d2bf1a174ddffde1e02cb8881cff6dab70e61cbdef393deac0ce639", + "signature": "0xdc2cecb49a3a0cfd6820dafd1e6be428f03bbbc73080662d3c52cc6991aaba0bda917010a22740ab3c3ff3d3b444db272685e8ef6102dd9b703cb7f7f9637508", + "type": "ed25519_signature" + }, + "replay_protection_nonce": null, + "events": [ + { + "guid": { + "creation_number": "0", + "account_address": "0x0" + }, + "sequence_number": "0", + "type": "0x1::transaction_fee::FeeStatement", + "data": { + "execution_gas_units": "4", + "io_gas_units": "6", + "storage_fee_octas": "0", + "storage_fee_refund_octas": "0", + "total_charge_gas_units": "10" + } + } + ], + "timestamp": "500000" + } +] diff --git a/api/goldens/aptos_api__tests__view_function__test_simple_view_invalid.json b/api/goldens/aptos_api__tests__view_function__test_simple_view_invalid.json index 7d32adc125b..e7bf7fd7930 100644 --- a/api/goldens/aptos_api__tests__view_function__test_simple_view_invalid.json +++ b/api/goldens/aptos_api__tests__view_function__test_simple_view_invalid.json @@ -1 +1 @@ -{"message":"PartialVMError with status INVALID_MAIN_FUNCTION_SIGNATURE and message 'function not marked as view function'","error_code":"invalid_input","vm_error_code":null} \ No newline at end of file +{"message":"function not marked as view function","error_code":"invalid_input","vm_error_code":1011} \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_does_not_exist.json b/api/goldens/aptos_api__tests__view_function__test_view_does_not_exist.json new file mode 100644 index 00000000000..8c34a578273 --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_does_not_exist.json @@ -0,0 +1 @@ +{"message":"could not find view function by 0x1::aptos_account::fake_function","error_code":"invalid_input","vm_error_code":null} \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_error_move_abort.json b/api/goldens/aptos_api__tests__view_function__test_view_error_move_abort.json new file mode 100644 index 00000000000..9a7bb75ef2a --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_error_move_abort.json @@ -0,0 +1 @@ +{"message":"Move abort in 0x1::account: ENO_SUCH_ROTATION_CAPABILITY_OFFER(0x60012): The specified rotation capability offer does not exist at the specified offerer address","error_code":"invalid_input","vm_error_code":4016} \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_error_type_resolution_error.json b/api/goldens/aptos_api__tests__view_function__test_view_error_type_resolution_error.json new file mode 100644 index 00000000000..175a6277410 --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_error_type_resolution_error.json @@ -0,0 +1 @@ +{"message":"Struct 0x1::aptos_coin::NewCoin does not exist","error_code":"invalid_input","vm_error_code":2021} \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_option.json b/api/goldens/aptos_api__tests__view_function__test_view_option.json new file mode 100644 index 00000000000..024952663be --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_option.json @@ -0,0 +1 @@ +[{"vec":[]}] \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_option_some.json b/api/goldens/aptos_api__tests__view_function__test_view_option_some.json new file mode 100644 index 00000000000..2aab72ee8da --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_option_some.json @@ -0,0 +1 @@ +[{"vec":["1"]}] \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_option_struct.json b/api/goldens/aptos_api__tests__view_function__test_view_option_struct.json new file mode 100644 index 00000000000..9e16729c3fc --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_option_struct.json @@ -0,0 +1 @@ +[{"o":{"vec":["2"]}}] \ No newline at end of file diff --git a/api/goldens/aptos_api__tests__view_function__test_view_option_vec.json b/api/goldens/aptos_api__tests__view_function__test_view_option_vec.json new file mode 100644 index 00000000000..43df952a8c9 --- /dev/null +++ b/api/goldens/aptos_api__tests__view_function__test_view_option_vec.json @@ -0,0 +1 @@ +[[{"vec":["3"]},{"vec":[]}]] \ No newline at end of file diff --git a/api/src/basic.rs b/api/src/basic.rs index ae6fd8fb5c3..31af7f1b6d7 100644 --- a/api/src/basic.rs +++ b/api/src/basic.rs @@ -74,6 +74,8 @@ impl BasicApi { )] async fn info(&self) -> Json> { let mut info = HashMap::new(); + + // Insert state sync configuration information info.insert( "bootstrapping_mode".to_string(), serde_json::to_value( @@ -96,6 +98,8 @@ impl BasicApi { ) .unwrap(), ); + + // Insert storage configuration information info.insert( "new_storage_format".to_string(), serde_json::to_value( @@ -112,6 +116,20 @@ impl BasicApi { serde_json::to_value(&self.context.node_config.indexer_db_config).unwrap(), ); + // Insert node identity information + if let Some(validator_network) = &self.context.node_config.validator_network { + info.insert( + "validator_network_peer_id".to_string(), + serde_json::to_value(validator_network.peer_id()).unwrap(), + ); + } + for fullnode_network in &self.context.node_config.full_node_networks { + info.insert( + format!("fullnode_network_peer_id_{}", fullnode_network.network_id), + serde_json::to_value(fullnode_network.peer_id()).unwrap(), + ); + } + Json(info) } diff --git a/api/src/context.rs b/api/src/context.rs index f15d374193c..b1426847b5b 100644 --- a/api/src/context.rs +++ b/api/src/context.rs @@ -540,7 +540,7 @@ impl Context { if converter.is_resource_group(&tag) { // An error here means a storage invariant has been violated bcs::from_bytes::(&value) - .map(|map| map.into_iter().map(|(t, v)| (t, v)).collect::>()) + .map(|map| map.into_iter().collect::>()) .map_err(|e| e.into()) } else { Ok(vec![(tag, value)]) @@ -837,10 +837,11 @@ impl Context { ) -> Result> { let data = self .db - .get_transaction_outputs(start_version, limit as u64, ledger_version)?; + .get_transaction_outputs(start_version, limit as u64, ledger_version)? + .consume_output_list_with_proof(); let txn_start_version = data - .first_transaction_output_version + .get_first_output_version() .ok_or_else(|| format_err!("no start version from database"))?; ensure!( txn_start_version == start_version, @@ -1075,6 +1076,7 @@ impl Context { let (_, txn_output) = &self .db .get_transaction_outputs(txn.version, 1, txn.version)? + .consume_output_list_with_proof() .transactions_and_outputs[0]; self.get_accumulator_root_hash(txn.version) .map(|h| (txn, h, txn_output).into()) diff --git a/api/src/error_converter.rs b/api/src/error_converter.rs index 204375b76da..4d7ca3373b9 100644 --- a/api/src/error_converter.rs +++ b/api/src/error_converter.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_api_types::{mime_types::JSON, AptosError, AptosErrorCode}; +use aptos_logger::error; use poem::{ http::header::{HeaderValue, CONTENT_TYPE}, IntoResponse, Response, }; use poem_openapi::payload::Json; - +use std::any::Any; // The way I'm determining which errors are framework errors is very janky, as // is the way I'm building the response. See: // - https://github.com/poem-web/poem/issues/343 @@ -44,3 +45,16 @@ fn build_error_response(error_string: String) -> Response { )) .into_response() } + +pub fn panic_handler(err: Box) -> Response { + error!("Panic captured: {:?}", err); + build_panic_response("internal error".into()) +} + +fn build_panic_response(error_string: String) -> Response { + Json(AptosError::new_with_error_code( + error_string, + AptosErrorCode::InternalError, + )) + .into_response() +} diff --git a/api/src/log.rs b/api/src/log.rs index b9ee7a2ab4d..4a9a9645e46 100644 --- a/api/src/log.rs +++ b/api/src/log.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::metrics::{HISTOGRAM, POST_BODY_BYTES, REQUEST_SOURCE_CLIENT, RESPONSE_STATUS}; -use aptos_api_types::X_APTOS_CLIENT; +use aptos_api_types::{TRACEPARENT, X_APTOS_CLIENT}; use aptos_logger::{ debug, info, prelude::{sample, SampleRate}, @@ -22,12 +22,41 @@ const REQUEST_SOURCE_CLIENT_UNKNOWN: &str = "unknown"; static REQUEST_SOURCE_CLIENT_REGEX: Lazy = Lazy::new(|| Regex::new(r"aptos-[a-zA-Z\-]+/[0-9A-Za-z\.\-]+").unwrap()); +/// Extracts trace_id and span_id from the traceparent header (W3C Trace Context format). +/// Format: version-trace_id-parent_id-trace_flags +/// Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01 +/// Returns (trace_id, span_id) if valid, otherwise generates them. +fn extract_trace_context(request: &Request) -> (Option, Option) { + // First, try to extract from traceparent header + if let Some(traceparent) = request.headers().get(TRACEPARENT) { + if let Ok(traceparent_str) = traceparent.to_str() { + // W3C Trace Context format: version-trace_id-parent_id-trace_flags + let parts: Vec<&str> = traceparent_str.split('-').collect(); + if parts.len() == 4 && parts[1].len() == 32 && parts[2].len() == 16 { + return (Some(parts[1].to_string()), Some(parts[2].to_string())); + } + } + } + + // If no traceparent header or invalid format, generate IDs + // Use a simple timestamp-based ID as fallback + let nanos = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_nanos(); + let trace_id = format!("{:032x}", nanos); + let span_id = format!("{:016x}", nanos & 0xFFFFFFFFFFFFFFFF); + (Some(trace_id), Some(span_id)) +} + /// Logs information about the request and response if the response status code /// is >= 500, to help us debug since this will be an error on our side. /// We also do general logging of the status code alone regardless of what it is. pub async fn middleware_log(next: E, request: Request) -> Result { let start = std::time::Instant::now(); + let (trace_id, span_id) = extract_trace_context(&request); + let mut log = HttpRequestLog { remote_addr: request.remote_addr().as_socket_addr().cloned(), method: request.method().clone(), @@ -54,6 +83,8 @@ pub async fn middleware_log(next: E, request: Request) -> Result, content_length: Option, + trace_id: Option, + span_id: Option, } diff --git a/api/src/response.rs b/api/src/response.rs index 6f874daafc5..e7082f4ed73 100644 --- a/api/src/response.rs +++ b/api/src/response.rs @@ -91,6 +91,14 @@ macro_rules! generate_error_traits { error_code: aptos_api_types::AptosErrorCode, ) -> Self where Self: Sized; + #[allow(unused)] + fn [<$trait_name:snake _with_optional_vm_status_and_ledger_info>]( + err: Err, + error_code: aptos_api_types::AptosErrorCode, + vm_status: Option, + ledger_info: Option<&aptos_api_types::LedgerInfo> + ) -> Self where Self: Sized; + #[allow(unused)] fn [<$trait_name:snake _with_vm_status>]( err: Err, @@ -199,6 +207,30 @@ macro_rules! generate_error_response { None, )) } + fn [<$name:snake _with_optional_vm_status_and_ledger_info>]( + err: Err, + error_code: aptos_api_types::AptosErrorCode, + vm_status: Option, + ledger_info: Option<&aptos_api_types::LedgerInfo> + ) -> Self where Self: Sized { + let error = if let Some(vm_status) = vm_status { + aptos_api_types::AptosError::new_with_vm_status(err, error_code, vm_status) + } else { + aptos_api_types::AptosError::new_with_error_code(err, error_code) + }; + let payload = poem_openapi::payload::Json(Box::new(error)); + Self::from($enum_name::$name( + payload, + ledger_info.map(|info| info.chain_id), + ledger_info.map(|info| info.ledger_version.into()), + ledger_info.map(|info| info.oldest_ledger_version.into()), + ledger_info.map(|info| info.ledger_timestamp.into()), + ledger_info.map(|info| info.epoch.into()), + ledger_info.map(|info| info.block_height.into()), + ledger_info.map(|info| info.oldest_block_height.into()), + None, + )) + } fn [<$name:snake _with_vm_status>]( err: Err, diff --git a/api/src/runtime.rs b/api/src/runtime.rs index 7c3ab234378..1b7b65abd48 100644 --- a/api/src/runtime.rs +++ b/api/src/runtime.rs @@ -8,7 +8,7 @@ use crate::{ blocks::BlocksApi, check_size::PostSizeLimit, context::Context, - error_converter::convert_error, + error_converter::{convert_error, panic_handler}, events::EventsApi, index::IndexApi, log::middleware_log, @@ -29,7 +29,7 @@ use poem::{ handler, http::Method, listener::{Listener, RustlsCertificate, RustlsConfig, TcpListener}, - middleware::{Compression, Cors}, + middleware::{CatchPanic, Compression, Cors}, web::Html, EndpointExt, Route, Server, }; @@ -254,6 +254,7 @@ pub fn attach_poem_to_runtime( .with(cors) .with_if(config.api.compression_enabled, Compression::new()) .with(PostSizeLimit::new(size_limit)) + .with(CatchPanic::new().with_handler(panic_handler)) // NOTE: Make sure to keep this after all the `with` middleware. .catch_all_error(convert_error) .around(middleware_log); diff --git a/api/src/spec.rs b/api/src/spec.rs index 10293cb71e0..19939c096f7 100644 --- a/api/src/spec.rs +++ b/api/src/spec.rs @@ -27,7 +27,7 @@ where /// Create an endpoint to serve the OpenAPI specification as json. We define this /// ourselves because we need to use our custom `get_spec` function that changes the /// spec to remove charset from the content type. -pub fn spec_endpoint_json(service: &OpenApiService) -> impl Endpoint +pub fn spec_endpoint_json(service: &OpenApiService) -> impl Endpoint + use where T: OpenApi, W: Webhook, @@ -43,7 +43,7 @@ where /// Create an endpoint to serve the OpenAPI specification as yaml. We define this /// ourselves because we need to use our custom `get_spec` function that changes the /// spec to remove charset from the content type. -pub fn spec_endpoint_yaml(service: &OpenApiService) -> impl Endpoint +pub fn spec_endpoint_yaml(service: &OpenApiService) -> impl Endpoint + use where T: OpenApi, W: Webhook, diff --git a/api/src/tests/account_abstraction_test.rs b/api/src/tests/account_abstraction_test.rs index 0e507ec251f..7795da13667 100644 --- a/api/src/tests/account_abstraction_test.rs +++ b/api/src/tests/account_abstraction_test.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_crypto::{ bls12381::{PrivateKey, PublicKey}, @@ -15,14 +15,29 @@ use aptos_types::{ }; use move_core_types::{identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode}; use rand::rngs::OsRng; +use rstest::rstest; use serde_json::json; use std::{path::PathBuf, sync::Arc}; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_account_abstraction_single_signer() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_account_abstraction_single_signer( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let key_pair = Arc::new(KeyPair::::generate(&mut OsRng)); - let mut context = new_test_context(current_function_name!()); + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut account = context.create_account().await; let user_addr = account.address(); let other = context.create_account().await; @@ -68,7 +83,12 @@ async fn test_account_abstraction_single_signer() { None, factory .account_transfer(other.address(), 1) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); let txn_status = context.try_commit_block(&vec![aa_txn]).await; @@ -94,7 +114,12 @@ async fn test_account_abstraction_single_signer() { None, factory .account_transfer(other.address(), 4) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); context .expect_status_code(202) @@ -110,9 +135,24 @@ async fn test_account_abstraction_single_signer() { /// This tests a function with params (signer_a, signer_b, signer_c, d) works for the AA authentication flow. /// a, c are AA; b, d are normal ed25519 accounts. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_account_abstraction_multi_agent_with_abstracted_sender() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_account_abstraction_multi_agent_with_abstracted_sender( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let key_pair = Arc::new(KeyPair::::generate(&mut OsRng)); - let mut context = new_test_context(current_function_name!()); + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut a = context.create_account().await; let b = context.create_account().await; let mut c = context.create_account().await; @@ -128,15 +168,12 @@ async fn test_account_abstraction_multi_agent_with_abstracted_sender() { }); context.publish_package(&mut a, txn).await; - context - .commit_block(&vec![context.mint_user_account(&a).await]) - .await; - context - .commit_block(&vec![context.mint_user_account(&b).await]) - .await; - context - .commit_block(&vec![context.mint_user_account(&c).await]) - .await; + let txn1 = context.mint_user_account(&a).await; + context.commit_block(&vec![txn1]).await; + let txn2 = context.mint_user_account(&b).await; + context.commit_block(&vec![txn2]).await; + let txn3 = context.mint_user_account(&c).await; + context.commit_block(&vec![txn3]).await; // Convert c to aa context @@ -174,7 +211,12 @@ async fn test_account_abstraction_multi_agent_with_abstracted_sender() { vec![], vec![bcs::to_bytes(&d.address()).unwrap()], )) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); context .expect_status_code(202) diff --git a/api/src/tests/accounts_test.rs b/api/src/tests/accounts_test.rs index c8122a4b185..a9e52e59990 100644 --- a/api/src/tests/accounts_test.rs +++ b/api/src/tests/accounts_test.rs @@ -2,8 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; -use crate::tests::new_test_context_with_db_sharding_and_internal_indexer; +use super::{new_test_context, new_test_context_with_orderless_flags}; use aptos_api_test_context::{current_function_name, find_value, TestContext}; use aptos_api_types::{MoveModuleBytecode, MoveResource, MoveStructTag, StateKeyWrapper}; use aptos_cached_packages::aptos_stdlib; @@ -19,8 +18,9 @@ use move_core_types::{ language_storage::{ModuleId, TypeTag}, move_resource::MoveStructType, }; +use rstest::rstest; use serde_json::json; -use std::str::FromStr; +use std::{path::PathBuf, str::FromStr}; /* TODO: reactivate once cause of failure for `"8"` vs `8` in the JSON output is known. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -55,8 +55,7 @@ async fn test_get_account_resources_by_valid_account_address() { res.push(resp); } - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let shard_context = new_test_context(current_function_name!()); let mut shard_res = vec![]; for address in &addresses { let resp = shard_context.get(&account_resources(address)).await; @@ -122,12 +121,29 @@ async fn test_account_modules_structs() { } async fn test_account_resources_by_ledger_version_with_context(mut context: TestContext) { + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); + + let initial_resources = context + .get(&account_resources( + &context.root_account().await.address().to_hex_literal(), + )) + .await; + let root_account = find_value(&initial_resources, |f| f["type"] == "0x1::account::Account"); + let initial_sequence_number = root_account["data"]["sequence_number"] + .as_str() + .unwrap() + .parse::() + .unwrap(); + let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn.clone()]).await; if let Some(indexer_reader) = context.context.indexer_reader.as_ref() { - indexer_reader.wait_for_internal_indexer(2).unwrap(); + // Waiting for the above transaction, block metadata and state checkpoint to get indexed. + indexer_reader + .wait_for_internal_indexer(initial_ledger_version + 3) + .unwrap(); } let ledger_version_1_resources = context @@ -138,29 +154,82 @@ async fn test_account_resources_by_ledger_version_with_context(mut context: Test let root_account = find_value(&ledger_version_1_resources, |f| { f["type"] == "0x1::account::Account" }); - assert_eq!(root_account["data"]["sequence_number"], "1"); + if context.use_orderless_transactions { + // Orderless transactions don't update sequence number + assert_eq!( + root_account["data"]["sequence_number"] + .as_str() + .unwrap() + .parse::() + .unwrap(), + initial_sequence_number + ); + } else { + assert_eq!( + root_account["data"]["sequence_number"] + .as_str() + .unwrap() + .parse::() + .unwrap(), + initial_sequence_number + 1 + ); + } let ledger_version_0_resources = context .get(&account_resources_with_ledger_version( &context.root_account().await.address().to_hex_literal(), - 0, + initial_ledger_version as i128, )) .await; let root_account = find_value(&ledger_version_0_resources, |f| { f["type"] == "0x1::account::Account" }); - assert_eq!(root_account["data"]["sequence_number"], "0"); + assert_eq!( + root_account["data"]["sequence_number"] + .as_str() + .unwrap() + .parse::() + .unwrap(), + initial_sequence_number + ); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_resources_by_ledger_version() { - let context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_resources_by_ledger_version( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); test_account_resources_by_ledger_version_with_context(context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_resources_by_ledger_version_with_shard_context() { - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_resources_by_ledger_version_with_shard_context( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let shard_context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); test_account_resources_by_ledger_version_with_context(shard_context).await; } @@ -218,8 +287,22 @@ async fn test_account_auto_creation() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_balance() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_balance( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let root_account = context.root_account().await; // First check coin balance @@ -229,11 +312,19 @@ async fn test_get_account_balance() { APTOS_COIN_TYPE_STR, )) .await; - - // Migrate to fungible store - let txn = root_account.sign_with_transaction_builder(context.transaction_factory().payload( - aptos_stdlib::coin_migrate_to_fungible_store(AptosCoinType::type_tag()), - )); + let txn = root_account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(aptos_stdlib::coin_migrate_to_fungible_store( + AptosCoinType::type_tag(), + )) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); context.commit_block(&vec![txn.clone()]).await; // Check coin balance after migration @@ -253,19 +344,26 @@ async fn test_get_account_balance() { )) .await; assert_eq!(coin_balance_after, fa_balance); - - // Upgrade to concurrent store - let txn = root_account.sign_with_transaction_builder(context.transaction_factory().payload( - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::TEN, - Identifier::new("fungible_asset").unwrap(), + // upgrade to concurrent store + let txn = root_account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::TEN, + Identifier::new("fungible_asset").unwrap(), + ), + Identifier::new("upgrade_store_to_concurrent").unwrap(), + vec![TypeTag::Struct(Box::new(ObjectCoreResource::struct_tag()))], + vec![bcs::to_bytes(&primary_apt_store(root_account.address())).unwrap()], + ))) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, ), - Identifier::new("upgrade_store_to_concurrent").unwrap(), - vec![TypeTag::Struct(Box::new(ObjectCoreResource::struct_tag()))], - vec![bcs::to_bytes(&primary_apt_store(root_account.address())).unwrap()], - )), - )); + ); context.commit_block(&vec![txn.clone()]).await; // Check concurrent fungible asset balance @@ -279,16 +377,29 @@ async fn test_get_account_balance() { } async fn test_get_account_modules_by_ledger_version_with_context(mut context: TestContext) { + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let payload = aptos_stdlib::publish_module_source("test_module", "module 0xa550c18::test_module {}"); let root_account = context.root_account().await; - let txn = - root_account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let txn = root_account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); context.commit_block(&vec![txn.clone()]).await; if let Some(indexer_reader) = context.context.indexer_reader.as_ref() { - indexer_reader.wait_for_internal_indexer(2).unwrap(); + // Waiting for the above transaction, block metadata, and state checkpoint to be indexed. + indexer_reader + .wait_for_internal_indexer(initial_ledger_version + 3) + .unwrap(); } let modules = context @@ -298,24 +409,109 @@ async fn test_get_account_modules_by_ledger_version_with_context(mut context: Te .await; assert_ne!(modules, json!([])); + // Making sure the module is not in the account modules initially. let modules = context .get(&account_modules_with_ledger_version( &context.root_account().await.address().to_hex_literal(), - 0, + initial_ledger_version, )) .await; assert_eq!(modules, json!([])); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_modules_by_ledger_version() { - let context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_modules_by_ledger_version( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); test_get_account_modules_by_ledger_version_with_context(context).await; - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let shard_context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); test_get_account_modules_by_ledger_version_with_context(shard_context).await; } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn account_resource_created_only_by_seq_number_based_txns( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + + // Prepare accounts + let mut user = context.create_account().await; + let user_addr = user.address(); + + let resp = context + .get(&account_resources(&user_addr.to_hex_literal())) + .await + .to_string(); + assert!(!resp.contains("0x1::account::Account")); + + // Publish packages + let named_addresses = vec![("event".to_string(), user_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("../aptos-move/move-examples/event"); + TestContext::build_package(path, named_addresses) + }); + context.publish_package(&mut user, txn).await; + + let resp = context + .get(&account_resources(&user_addr.to_hex_literal())) + .await + .to_string(); + if use_orderless_transactions { + assert!(!resp.contains("0x1::account::Account")); + } else { + assert!(resp.contains("0x1::account::Account")); + } + + context + .api_execute_entry_function( + &mut user, + &format!("0x{}::event::emit", user_addr.to_hex()), + json!([]), + json!(["7"]), + ) + .await; + + let resp = context + .get(&account_resources(&user_addr.to_hex_literal())) + .await + .to_string(); + if use_orderless_transactions { + assert!(!resp.contains("0x1::account::Account")); + } else { + assert!(resp.contains("0x1::account::Account")); + } +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_core_account_data() { let mut context = new_test_context(current_function_name!()); @@ -532,7 +728,7 @@ fn account_balance(address: &str, coin_type: &str) -> String { format!("/accounts/{}/balance/{}", address, coin_type) } -fn account_modules_with_ledger_version(address: &str, ledger_version: i128) -> String { +fn account_modules_with_ledger_version(address: &str, ledger_version: u64) -> String { format!( "{}?ledger_version={}", account_modules(address), diff --git a/api/src/tests/event_v2_translation_test.rs b/api/src/tests/event_v2_translation_test.rs index c63e683704e..c996dc1127c 100644 --- a/api/src/tests/event_v2_translation_test.rs +++ b/api/src/tests/event_v2_translation_test.rs @@ -2,12 +2,14 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::{new_test_context, new_test_context_with_db_sharding_and_internal_indexer}; +use super::new_test_context; +use crate::tests::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_crypto::{ed25519::Ed25519PrivateKey, SigningKey, ValidCryptoMaterial}; use aptos_sdk::types::LocalAccount; use aptos_types::account_config::RotationProofChallenge; use move_core_types::{account_address::AccountAddress, language_storage::CORE_CODE_ADDRESS}; +use rstest::rstest; use serde_json::{json, Value}; use std::path::PathBuf; @@ -44,8 +46,7 @@ fn matches_event_details( #[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[ignore] async fn test_event_v2_translation_coin_deposit_event() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let context = &mut new_test_context(current_function_name!()); // Start with the MODULE_EVENT_MIGRATION feature disabled context.disable_feature(MODULE_EVENT_MIGRATION).await; @@ -88,6 +89,7 @@ async fn test_event_v2_translation_coin_deposit_event() { context .api_execute_aptos_account_transfer(account2, account1.address(), 102) .await; + context.wait_for_internal_indexer_caught_up().await; // Check the event_by_creation_number API outputs the translated V1 event let resp = context @@ -106,21 +108,33 @@ async fn test_event_v2_translation_coin_deposit_event() { assert!(is_expected_event(resp.as_array().unwrap().last().unwrap())); // Check the accounts-transactions API outputs the translated V1 event + if !context.use_orderless_transactions { + // /accounts/:address/transactions only outputs sequence number based transactions from the account + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + account2.address().to_hex_literal() + ) + .as_str(), + ) + .await; + assert!(resp[0]["events"] + .as_array() + .unwrap() + .iter() + .any(is_expected_event)); + }; let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", account2.address().to_hex_literal() ) .as_str(), ) .await; - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(is_expected_event)); - let hash = resp[0]["hash"].as_str().unwrap(); + let hash = resp[0]["transaction_hash"].as_str().unwrap(); let version = resp[0]["version"].as_str().unwrap(); // Check the transactions API outputs the translated V1 event @@ -157,8 +171,7 @@ async fn test_event_v2_translation_coin_deposit_event() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[ignore] async fn test_event_v2_translation_coin_withdraw_event() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let context = &mut new_test_context(current_function_name!()); // Start with the MODULE_EVENT_MIGRATION feature disabled context.disable_feature(MODULE_EVENT_MIGRATION).await; @@ -209,6 +222,7 @@ async fn test_event_v2_translation_coin_withdraw_event() { context .api_execute_aptos_account_transfer(account2, account1.address(), 102) .await; + context.wait_for_internal_indexer_caught_up().await; // Check the event_by_creation_number API outputs the translated V1 event let resp = context @@ -227,21 +241,33 @@ async fn test_event_v2_translation_coin_withdraw_event() { assert!(is_expected_event(resp.as_array().unwrap().last().unwrap())); // Check the accounts-transactions API outputs the translated V1 event + if !context.use_orderless_transactions { + // /accounts/:address/transactions only outputs sequence number based transactions from the account + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + account2.address().to_hex_literal() + ) + .as_str(), + ) + .await; + assert!(resp[0]["events"] + .as_array() + .unwrap() + .iter() + .any(is_expected_event)); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", account2.address().to_hex_literal() ) .as_str(), ) .await; - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(is_expected_event)); - let hash = resp[0]["hash"].as_str().unwrap(); + let hash = resp[0]["transaction_hash"].as_str().unwrap(); let version = resp[0]["version"].as_str().unwrap(); // Check the transactions API outputs the translated V1 event @@ -278,8 +304,7 @@ async fn test_event_v2_translation_coin_withdraw_event() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[ignore] async fn test_event_v2_translation_account_coin_register_event() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let context = &mut new_test_context(current_function_name!()); // Make sure that the MODULE_EVENT_MIGRATION feature is enabled context.enable_feature(MODULE_EVENT_MIGRATION).await; @@ -312,6 +337,7 @@ async fn test_event_v2_translation_account_coin_register_event() { context .api_execute_aptos_account_transfer(account1, account2.address(), 102) .await; + context.wait_for_internal_indexer_caught_up().await; // Check the event_by_creation_number API outputs the translated V1 event let resp = context @@ -330,21 +356,33 @@ async fn test_event_v2_translation_account_coin_register_event() { assert!(is_expected_event(resp.as_array().unwrap().last().unwrap())); // Check the accounts-transactions API outputs the translated V1 event + if !context.use_orderless_transactions { + // /accounts/:address/transactions only outputs sequence number based transactions from the account + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + account1.address().to_hex_literal() + ) + .as_str(), + ) + .await; + assert!(resp[0]["events"] + .as_array() + .unwrap() + .iter() + .any(is_expected_event)); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", account1.address().to_hex_literal() ) .as_str(), ) .await; - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(is_expected_event)); - let hash = resp[0]["hash"].as_str().unwrap(); + let hash = resp[0]["transaction_hash"].as_str().unwrap(); let version = resp[0]["version"].as_str().unwrap(); // Check the transactions API outputs the translated V1 event @@ -420,9 +458,22 @@ fn rotate_authentication_key_payload( } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_event_v2_translation_account_key_rotation_event() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_event_v2_translation_account_key_rotation_event( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = &mut new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Make sure that the MODULE_EVENT_MIGRATION feature is enabled context.enable_feature(MODULE_EVENT_MIGRATION).await; @@ -481,21 +532,33 @@ async fn test_event_v2_translation_account_key_rotation_event() { assert!(resp.as_array().unwrap().iter().any(is_expected_event)); // Check the accounts-transactions API outputs the translated V1 event + if !context.use_orderless_transactions { + // /accounts/:address/transactions only outputs sequence number based transactions from the account + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + account1.address().to_hex_literal() + ) + .as_str(), + ) + .await; + assert!(resp[0]["events"] + .as_array() + .unwrap() + .iter() + .any(is_expected_event)); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", account1.address().to_hex_literal() ) .as_str(), ) .await; - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(is_expected_event)); - let hash = resp[0]["hash"].as_str().unwrap(); + let hash = resp[0]["transaction_hash"].as_str().unwrap(); let version = resp[0]["version"].as_str().unwrap(); // Check the transactions API outputs the translated V1 event @@ -529,10 +592,90 @@ async fn test_event_v2_translation_account_key_rotation_event() { .any(is_expected_event)); } +fn check_for_event_v2_translation_token_objects( + resp: Value, + creator_addr: AccountAddress, + user_addr: AccountAddress, +) -> String { + // Test TransferTranslator + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x1::object::TransferEvent" + && e["sequence_number"] == "0" + && e["data"]["from"] == creator_addr.to_hex_literal() + && e["data"]["to"] == user_addr.to_hex_literal() + })); + + // Test TokenMutationTranslator + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x4::token::MutationEvent" + && e["sequence_number"] == "0" + && e["data"]["mutated_field_name"] == *"uri" + })); + + // Test CollectionMutationTranslator + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x4::collection::MutationEvent" + && e["sequence_number"] == "0" + && e["data"]["mutated_field_name"] == *"uri" + })); + + // Test MintTranslator + // The example Move package uses ConcurrentSupply which doesn't have the mint event handle. + // So, the mint event is not translated in this case. + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x4::collection::Mint" + && e["guid"]["account_address"] == *"0x0" + && e["sequence_number"] == "0" + })); + + let object_address = resp["events"] + .as_array() + .unwrap() + .iter() + .filter(|e| { + e["type"] == "0x4::collection::Mint" + && e["guid"]["account_address"] == *"0x0" + && e["sequence_number"] == "0" + }) + .collect::>()[0]["data"]["token"] + .clone() + .to_string(); + + // The first and last char is double quotes. Remove them to get the object address. + object_address[1..object_address.len() - 1].to_string() + // The cases with FixedSupply and UnlimitedSupply have been tested in the localnet. + // In those cases, the mint event is translated correctly as follows: + // Object { + // "guid": Object { + // "creation_number": String("1125899906842626"), + // "account_address": String("0x999a601c1abf720ccb54acae160a980f9a35209611a12b1e31e091172ed061fc"), + // }, + // "sequence_number": String("0"), + // "type": String("0x4::collection::MintEvent"), + // "data": Object { + // "index": String("1"), + // "token": String("0x7dbdec16c12211da2db477a15941df2495218ceb6c221da7bd3efcb93d75cffe"), + // }, + // }, +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_event_v2_translation_token_objects() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_event_v2_translation_token_objects( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = &mut new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Make sure that the MODULE_EVENT_MIGRATION feature is enabled context.enable_feature(MODULE_EVENT_MIGRATION).await; @@ -563,100 +706,98 @@ async fn test_event_v2_translation_token_objects() { }); context.api_execute_txn(creator, payload).await; context.wait_for_internal_indexer_caught_up().await; + + if !context.use_orderless_transactions { + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + creator_addr.to_hex_literal() + ) + .as_str(), + ) + .await; + check_for_event_v2_translation_token_objects(resp[0].clone(), creator_addr, user_addr); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", creator_addr.to_hex_literal() ) .as_str(), ) .await; + let hash = resp[0]["transaction_hash"].as_str().unwrap(); + let version = resp[0]["version"].as_str().unwrap(); - // Test TransferTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x1::object::TransferEvent" - && e["sequence_number"] == "0" - && e["data"]["from"] == creator_addr.to_hex_literal() - && e["data"]["to"] == user_addr.to_hex_literal() - })); - - // Test TokenMutationTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x4::token::MutationEvent" - && e["sequence_number"] == "0" - && e["data"]["mutated_field_name"] == *"uri" - })); - - // Test CollectionMutationTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x4::collection::MutationEvent" - && e["sequence_number"] == "0" - && e["data"]["mutated_field_name"] == *"uri" - })); + // Check the transactions API outputs the translated V1 event + let resp = context + .get(format!("/transactions?start={}&limit=1", version).as_str()) + .await; + check_for_event_v2_translation_token_objects(resp[0].clone(), creator_addr, user_addr); - // Test MintTranslator - // The example Move package uses ConcurrentSupply which doesn't have the mint event handle. - // So, the mint event is not translated in this case. - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x4::collection::Mint" - && e["guid"]["account_address"] == *"0x0" - && e["sequence_number"] == "0" - })); - // The cases with FixedSupply and UnlimitedSupply have been tested in the localnet. - // In those cases, the mint event is translated correctly as follows: - // Object { - // "guid": Object { - // "creation_number": String("1125899906842626"), - // "account_address": String("0x999a601c1abf720ccb54acae160a980f9a35209611a12b1e31e091172ed061fc"), - // }, - // "sequence_number": String("0"), - // "type": String("0x4::collection::MintEvent"), - // "data": Object { - // "index": String("1"), - // "token": String("0x7dbdec16c12211da2db477a15941df2495218ceb6c221da7bd3efcb93d75cffe"), - // }, - // }, + // Check the transactions_by_hash API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_hash/{}", hash).as_str()) + .await; + check_for_event_v2_translation_token_objects(resp, creator_addr, user_addr); + // Check the transactions_by_version API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_version/{}", version).as_str()) + .await; + let object_address = + check_for_event_v2_translation_token_objects(resp, creator_addr, user_addr); let payload = json!({ "type": "entry_function_payload", "function": format!("{}::token_objects::burn", creator_addr.to_hex_literal()), "type_arguments": [], "arguments": [ - "0x7dbdec16c12211da2db477a15941df2495218ceb6c221da7bd3efcb93d75cffe" + object_address ] }); context.api_execute_txn(creator, payload).await; context.wait_for_internal_indexer_caught_up().await; + + if !context.use_orderless_transactions { + // /accounts/:address/transactions only outputs sequence number based transactions from the account + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + creator_addr.to_hex_literal() + ) + .as_str(), + ) + .await; + // Test BurnTranslator + // The example Move package uses ConcurrentSupply which doesn't have the burn event handle. + // So, the burn event is not translated in this case. + assert!(resp[0]["events"] + .as_array() + .unwrap() + .iter() + .any(|e: &Value| { + e["type"] == "0x4::collection::Burn" + && e["guid"]["account_address"] == *"0x0" + && e["sequence_number"] == "0" + })); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", creator_addr.to_hex_literal() ) .as_str(), ) .await; - - // Test BurnTranslator - // The example Move package uses ConcurrentSupply which doesn't have the burn event handle. - // So, the burn event is not translated in this case. + let hash = resp[0]["transaction_hash"].as_str().unwrap(); + let version = resp[0]["version"].as_str().unwrap(); + let resp = context + .get(format!("/transactions?start={}&limit=1", version).as_str()) + .await; assert!(resp[0]["events"] .as_array() .unwrap() @@ -666,6 +807,27 @@ async fn test_event_v2_translation_token_objects() { && e["guid"]["account_address"] == *"0x0" && e["sequence_number"] == "0" })); + + // Check the transactions_by_hash API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_hash/{}", hash).as_str()) + .await; + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x4::collection::Burn" + && e["guid"]["account_address"] == *"0x0" + && e["sequence_number"] == "0" + })); + + // Check the transactions_by_version API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_version/{}", version).as_str()) + .await; + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x4::collection::Burn" + && e["guid"]["account_address"] == *"0x0" + && e["sequence_number"] == "0" + })); + // The cases with FixedSupply and UnlimitedSupply have been tested in the localnet. // In those cases, the burn event is translated correctly as follows: // Object { @@ -683,9 +845,22 @@ async fn test_event_v2_translation_token_objects() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_event_v2_translation_token_v1() { - let context = - &mut new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_event_v2_translation_token_v1( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = &mut new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Make sure that the MODULE_EVENT_MIGRATION feature is enabled context.enable_feature(MODULE_EVENT_MIGRATION).await; @@ -715,222 +890,180 @@ async fn test_event_v2_translation_token_v1() { }); context.api_execute_txn(creator, payload).await; context.wait_for_internal_indexer_caught_up().await; + if !context.use_orderless_transactions { + let resp = context + .get( + format!( + "/accounts/{}/transactions?limit=1", + creator_addr.to_hex_literal() + ) + .as_str(), + ) + .await; + check_for_event_v2_translation_token_v1(resp[0].clone(), creator_addr); + } let resp = context .get( format!( - "/accounts/{}/transactions?limit=1", + "/accounts/{}/transaction_summaries?limit=1", creator_addr.to_hex_literal() ) .as_str(), ) .await; + let hash = resp[0]["transaction_hash"].as_str().unwrap(); + let version = resp[0]["version"].as_str().unwrap(); + + // Check the transactions API outputs the translated V1 event + let resp = context + .get(format!("/transactions?start={}&limit=1", version).as_str()) + .await; + check_for_event_v2_translation_token_v1(resp[0].clone(), creator_addr); + + // Check the transactions_by_hash API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_hash/{}", hash).as_str()) + .await; + check_for_event_v2_translation_token_v1(resp, creator_addr); + + // Check the transactions_by_version API outputs the translated V1 event + let resp = context + .get(format!("/transactions/by_version/{}", version).as_str()) + .await; + check_for_event_v2_translation_token_v1(resp, creator_addr); +} +fn check_for_event_v2_translation_token_v1(resp: Value, creator_addr: AccountAddress) { // Test TokenDepositTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::DepositEvent" - && e["sequence_number"] == "4" - && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::DepositEvent" + && e["sequence_number"] == "4" + && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() + })); // Test TokenWithdrawTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::WithdrawEvent" - && e["sequence_number"] == "4" - && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::WithdrawEvent" + && e["sequence_number"] == "4" + && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() + })); // Test BurnTokenTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::BurnTokenEvent" - && e["sequence_number"] == "0" - && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::BurnTokenEvent" + && e["sequence_number"] == "0" + && e["data"]["id"]["token_data_id"]["creator"] == creator_addr.to_hex_literal() + })); // Test MutatePropertyMapTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::MutateTokenPropertyMapEvent" - && e["sequence_number"] == "0" - && e["data"]["new_id"]["property_version"] == "1" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::MutateTokenPropertyMapEvent" + && e["sequence_number"] == "0" + && e["data"]["new_id"]["property_version"] == "1" + })); // Test MintTokenTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::MintTokenEvent" - && e["sequence_number"] == "0" - && e["data"]["amount"] == "10" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::MintTokenEvent" + && e["sequence_number"] == "0" + && e["data"]["amount"] == "10" + })); // Test CreateCollectionTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::CreateCollectionEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::CreateCollectionEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test TokenDataCreationTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token::CreateTokenDataEvent" - && e["sequence_number"] == "0" - && e["data"]["name"] == "Token 1" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token::CreateTokenDataEvent" + && e["sequence_number"] == "0" + && e["data"]["name"] == "Token 1" + })); // Test OfferTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_transfers::TokenOfferEvent" - && e["sequence_number"] == "1" - && e["data"]["amount"] == "1" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_transfers::TokenOfferEvent" + && e["sequence_number"] == "1" + && e["data"]["amount"] == "1" + })); // Test CancelOfferTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_transfers::TokenCancelOfferEvent" - && e["sequence_number"] == "0" - && e["data"]["amount"] == "1" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_transfers::TokenCancelOfferEvent" + && e["sequence_number"] == "0" + && e["data"]["amount"] == "1" + })); // Test ClaimTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_transfers::TokenClaimEvent" - && e["sequence_number"] == "0" - && e["data"]["amount"] == "1" - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_transfers::TokenClaimEvent" + && e["sequence_number"] == "0" + && e["data"]["amount"] == "1" + })); // Test CollectionDescriptionMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::CollectionDescriptionMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator_addr"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::CollectionDescriptionMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator_addr"] == creator_addr.to_hex_literal() + })); // Test CollectionUriMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::CollectionUriMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator_addr"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::CollectionUriMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator_addr"] == creator_addr.to_hex_literal() + })); // Test CollectionMaximumMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::CollectionMaxiumMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator_addr"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::CollectionMaxiumMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator_addr"] == creator_addr.to_hex_literal() + })); // Test UriMutationTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::UriMutationEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::UriMutationEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test DefaultPropertyMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::DefaultPropertyMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::DefaultPropertyMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test DescriptionMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::DescriptionMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::DescriptionMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test RoyaltyMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::RoyaltyMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::RoyaltyMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test MaximumMutateTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::MaxiumMutateEvent" - && e["sequence_number"] == "0" - && e["data"]["creator"] == creator_addr.to_hex_literal() - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::MaxiumMutateEvent" + && e["sequence_number"] == "0" + && e["data"]["creator"] == creator_addr.to_hex_literal() + })); // Test OptInTransferTranslator - assert!(resp[0]["events"] - .as_array() - .unwrap() - .iter() - .any(|e: &Value| { - e["type"] == "0x3::token_event_store::OptInTransferEvent" - && e["sequence_number"] == "0" - && e["data"]["opt_in"] == Value::Bool(true) - })); + assert!(resp["events"].as_array().unwrap().iter().any(|e: &Value| { + e["type"] == "0x3::token_event_store::OptInTransferEvent" + && e["sequence_number"] == "0" + && e["data"]["opt_in"] == Value::Bool(true) + })); } diff --git a/api/src/tests/events_test.rs b/api/src/tests/events_test.rs index 9f64a6da04c..7b42623d599 100644 --- a/api/src/tests/events_test.rs +++ b/api/src/tests/events_test.rs @@ -3,9 +3,10 @@ // SPDX-License-Identifier: Apache-2.0 use super::new_test_context; -use crate::tests::new_test_context_with_db_sharding_and_internal_indexer; +use crate::tests::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; +use rstest::rstest; use serde_json::json; use std::path::PathBuf; @@ -13,8 +14,19 @@ static ACCOUNT_ADDRESS: &str = "0xa550c18"; static CREATION_NUMBER: &str = "0"; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_events() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_events(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let resp = context .get(format!("/accounts/{}/events/{}", ACCOUNT_ADDRESS, CREATION_NUMBER).as_str()) @@ -24,8 +36,22 @@ async fn test_get_events() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_events_filter_by_start_sequence_number() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_events_filter_by_start_sequence_number( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let resp = context .get( @@ -39,8 +65,11 @@ async fn test_get_events_filter_by_start_sequence_number() { context.check_golden_output(resp.clone()); // assert the same resp after db sharding migration with internal indexer turned on - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let shard_context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let new_resp = shard_context .get( format!( @@ -101,8 +130,7 @@ async fn test_get_events_by_account_event_handle() { .await; context.check_golden_output(resp.clone()); - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); + let shard_context = new_test_context(current_function_name!()); let new_resp = shard_context .get("/accounts/0x1/events/0x1::reconfiguration::Configuration/events") .await; @@ -161,8 +189,19 @@ async fn test_get_events_by_invalid_account_event_handle_field_type() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_module_events() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_module_events(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Prepare accounts let mut user = context.create_account().await; @@ -186,12 +225,40 @@ async fn test_module_events() { ) .await; - let resp = context + let resp_txns = context .get(format!("/accounts/{}/transactions", user.address()).as_str()) .await; - let txn = &resp.as_array().unwrap()[1]; + let resp_summaries = context + .get(format!("/accounts/{}/transaction_summaries", user.address()).as_str()) + .await; + assert_eq!(resp_summaries.as_array().unwrap().len(), 2); + + if use_orderless_transactions { + // "/accounts/{}/transactions" endpoint returns only ordered transactions committed by an account. + assert_eq!(resp_txns.as_array().unwrap().len(), 0); + } else { + assert_eq!(resp_txns.as_array().unwrap().len(), 2); + + assert_eq!( + resp_txns.as_array().unwrap()[0]["hash"], + resp_summaries.as_array().unwrap()[0]["transaction_hash"] + ); + assert_eq!( + resp_txns.as_array().unwrap()[1]["hash"], + resp_summaries.as_array().unwrap()[1]["transaction_hash"] + ); + } + let resp = context - .get(format!("/transactions/by_hash/{}", txn["hash"].as_str().unwrap()).as_str()) + .get( + format!( + "/transactions/by_hash/{}", + resp_summaries.as_array().unwrap()[1]["transaction_hash"] + .as_str() + .unwrap() + ) + .as_str(), + ) .await; let events = resp["events"] diff --git a/api/src/tests/function_value_test.rs b/api/src/tests/function_value_test.rs index 9c3659873f9..f7203aaa560 100644 --- a/api/src/tests/function_value_test.rs +++ b/api/src/tests/function_value_test.rs @@ -2,14 +2,26 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; use serde_json::json; use std::path::PathBuf; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_function_values() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_function_values(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut account = context.create_account().await; let account_addr = account.address(); @@ -82,3 +94,129 @@ async fn test_function_values() { .unwrap()["data"]; assert_eq!(state, &json!({"__variant__": "Value", "_0": "33"})); } + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_function_values_with_references( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let addr = account.address(); + + let named_addresses = vec![("account".to_string(), addr)]; + let txn = futures::executor::block_on(async move { + let path = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_function_values"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + let resource = format!("{}::test::FunctionStore", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + let expected_name = format!("{}::test::freeze_ref", addr); + assert_eq!( + response["data"], + json!({ + "f": { + "__fun_name__": &expected_name, + "__mask__": "0", + } + }) + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_function_values_with_captured_struct( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let addr = account.address(); + + let named_addresses = vec![("account".to_string(), addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src/tests/move/pack_function_values_with_struct"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + let resource = format!("{}::test::FunctionStore", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + let expected_name = format!("{}::test::id", addr); + assert_eq!( + response["data"], + json!({ + "f": { + "__captured__": [ {"_0": "1"} ], + "__fun_name__": &expected_name, + "__mask__": "1", + } + }) + ); + + let resource = format!("{}::test::R2<0x1::option::Option>", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + assert_eq!( + response["data"], + json!({ + "_0": {"vec": []}, + }) + ); + + let resource = format!("{}::test::R2<0x1::option::Option>", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + assert_eq!( + response["data"], + json!({ + "_0": {"vec": [1]}, + }) + ); + + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::test::entry_function", addr.to_hex()), + json!([]), + json!([{"vec": ["1"]}]), + ) + .await; + + let resource = format!("{}::test::R2<0x1::option::Option>", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + assert_eq!( + response["data"], + json!({ + "_0": {"vec":["1"]}, + }) + ); +} diff --git a/api/src/tests/invalid_post_request_test.rs b/api/src/tests/invalid_post_request_test.rs index c4d849da813..a82e6ce1d61 100644 --- a/api/src/tests/invalid_post_request_test.rs +++ b/api/src/tests/invalid_post_request_test.rs @@ -2,120 +2,217 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; -use aptos_api_test_context::current_function_name; +use super::new_test_context_with_orderless_flags; +use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; use serde_json::{json, Value}; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_type_argument_data_type() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_type_argument_data_type(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["type_arguments"] = json!([true]); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_argument_data_type() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_argument_data_type(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["arguments"][0] = json!(true); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_argument_u64_string() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_argument_u64_string(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["arguments"][0] = json!("invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_argument_address_type() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_argument_address_type(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["arguments"][0] = json!(1); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_argument_address_string() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_argument_address_string(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["arguments"][0] = json!("invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_missing_entry_function_arguments() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_missing_entry_function_arguments(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["arguments"] = json!([]); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_function_name() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_function_name(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["function"] = json!("0x1::account::invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_module_name() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_module_name(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["function"] = json!("0x1::invalid::invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_module_address() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_module_address(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["function"] = json!("0x2342342342::Invalid::invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_entry_function_function_id() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_entry_function_function_id(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["function"] = json!("invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_payload_type() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_payload_type(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"]["type"] = json!("invalid"); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_payload_data_type() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_payload_data_type(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["payload"] = json!(1234); - response_error_msg(req, current_function_name!()).await; + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_sender_address() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_sender_address(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["sender"] = json!("invalid"); + + response_error_msg(req, context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_invalid_sequence_number() { - let mut req = signing_message_request(); +#[rstest(use_orderless_transactions, case(false), case(true))] +async fn test_invalid_sequence_number(use_orderless_transactions: bool) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + true, + use_orderless_transactions, + ); + let mut req = signing_message_request(context.use_orderless_transactions); req["sequence_number"] = json!("invalid"); + + response_error_msg(req, context).await; +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_invalid_replay_protection_nonce() { + let context = new_test_context_with_orderless_flags(current_function_name!(), true, true); + let mut req = signing_message_request(context.use_orderless_transactions); + req["replay_protection_nonce"] = json!("invalid"); + + response_error_msg(req, context).await; } -async fn response_error_msg(req: Value, test_name: String) { - let mut context = new_test_context(test_name); +async fn response_error_msg(req: Value, mut context: TestContext) { let resp = context .expect_status_code(400) .post("/transactions/encode_submission", req) @@ -123,8 +220,8 @@ async fn response_error_msg(req: Value, test_name: String) { context.check_golden_output(resp) } -fn signing_message_request() -> Value { - json!({ +fn signing_message_request(use_orderless_transactions: bool) -> Value { + let mut request = json!({ "sender": "0xdd", "sequence_number": "0", "gas_unit_price": "0", @@ -133,11 +230,16 @@ fn signing_message_request() -> Value { "payload": { "type": "entry_function_payload", "function": "0x1::aptos_account::create_account", - "type_arguments": [ - ], + "type_arguments": [], "arguments": [ "0x00000000000000000000000001234567", // address ] } - }) + }); + + if use_orderless_transactions { + request["replay_protection_nonce"] = json!("1342341341"); + } + + request } diff --git a/api/src/tests/mod.rs b/api/src/tests/mod.rs index b3aeb0f2980..35fcf3fc7b3 100644 --- a/api/src/tests/mod.rs +++ b/api/src/tests/mod.rs @@ -14,8 +14,10 @@ mod invalid_post_request_test; mod modules; mod multisig_transactions_test; mod objects; +mod option_test; mod resource_groups; mod secp256k1_ecdsa; +mod signed_int_test; mod simulation_test; mod state_test; mod string_resource_test; @@ -28,19 +30,24 @@ use aptos_api_test_context::{new_test_context_inner as super_new_test_context, T use aptos_config::config::{internal_indexer_db_config::InternalIndexerDBConfig, NodeConfig}; fn new_test_context(test_name: String) -> TestContext { - new_test_context_with_config(test_name, NodeConfig::default()) + new_test_context_with_config(test_name, NodeConfig::default(), false, false) } -fn new_test_context_with_config(test_name: String, node_config: NodeConfig) -> TestContext { - super_new_test_context(test_name, node_config, false, None) -} - -#[cfg(test)] -fn new_test_context_with_db_sharding_and_internal_indexer(test_name: String) -> TestContext { - let mut node_config = NodeConfig::default(); - node_config.storage.rocksdb_configs.enable_storage_sharding = true; +fn new_test_context_with_config( + test_name: String, + mut node_config: NodeConfig, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) -> TestContext { node_config.indexer_db_config = InternalIndexerDBConfig::new(true, true, true, 0, true, 10); - let test_context = super_new_test_context(test_name, node_config, false, None); + let test_context = super_new_test_context( + test_name, + node_config, + false, + None, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let _ = test_context .get_indexer_reader() .unwrap() @@ -48,12 +55,15 @@ fn new_test_context_with_db_sharding_and_internal_indexer(test_name: String) -> test_context } -fn new_test_context_with_sharding_and_delayed_internal_indexer( +fn new_test_context_with_orderless_flags( test_name: String, - end_version: Option, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> TestContext { - let mut node_config = NodeConfig::default(); - node_config.storage.rocksdb_configs.enable_storage_sharding = true; - node_config.indexer_db_config = InternalIndexerDBConfig::new(true, true, true, 0, true, 1); - super_new_test_context(test_name, node_config, false, end_version) + new_test_context_with_config( + test_name, + NodeConfig::default(), + use_txn_payload_v2_format, + use_orderless_transactions, + ) } diff --git a/api/src/tests/modules.rs b/api/src/tests/modules.rs index 66131a72f0d..7c524cc111e 100644 --- a/api/src/tests/modules.rs +++ b/api/src/tests/modules.rs @@ -1,13 +1,25 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; use std::path::PathBuf; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_abi() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_abi(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut account = context.create_account().await; // Publish packages @@ -83,4 +95,30 @@ async fn test_abi() { .unwrap(); assert_eq!(my_struct["is_event"], false); + + // Confirm that MyEnum is considered an enum. + let my_enum = structs + .iter() + .find(|s| s["name"].as_str().unwrap() == "MyEnum") + .unwrap(); + + assert_eq!(my_enum["is_enum"], true); + + // Confirm that State is not considered an enum. + assert_eq!(my_struct["is_enum"], false); + + let test_option = structs + .iter() + .find(|s| s["name"].as_str().unwrap() == "TestOption") + .unwrap(); + assert_eq!(test_option["fields"][0]["name"], "o"); + + let option_module = context.get("/accounts/0x1/module/option").await; + + let option_structs = option_module["abi"]["structs"].as_array().unwrap(); + + assert_eq!(option_structs[0]["name"], "Option"); + assert_eq!(option_structs[0]["fields"][0]["name"], "vec"); + assert_eq!(option_structs[0]["is_enum"], false); + assert_eq!(option_structs[0]["fields"][0]["type"], "vector"); } diff --git a/api/src/tests/move/pack_abi/sources/test.move b/api/src/tests/move/pack_abi/sources/test.move index 5bf35cbe4b2..252781c0432 100644 --- a/api/src/tests/move/pack_abi/sources/test.move +++ b/api/src/tests/move/pack_abi/sources/test.move @@ -1,14 +1,24 @@ module abi::test { + use std::option; struct State has key { value: u64 } + enum MyEnum has drop, store { + This, + That + } + #[event] struct MyEvent has store { value: u64 } + struct TestOption has drop, copy { + o: option::Option + } + public fun public_function(s: &signer, state: State) { move_to(s, state) } diff --git a/api/src/tests/move/pack_function_values/Move.toml b/api/src/tests/move/pack_function_values/Move.toml new file mode 100644 index 00000000000..bcd2fe040c3 --- /dev/null +++ b/api/src/tests/move/pack_function_values/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "pack_function_values" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } + +[addresses] +account = "_" diff --git a/api/src/tests/move/pack_function_values/sources/test.move b/api/src/tests/move/pack_function_values/sources/test.move new file mode 100644 index 00000000000..60eeefa4d4c --- /dev/null +++ b/api/src/tests/move/pack_function_values/sources/test.move @@ -0,0 +1,15 @@ +module account::test { + + struct FunctionStore has key { + f: |&mut u64|&u64 has copy+drop+store, + } + + public fun freeze_ref(x: &mut u64): &u64 { + x + } + + fun init_module(account: &signer) { + let f: |&mut u64|&u64 has copy+drop+store = |s| freeze_ref(s); + move_to(account, FunctionStore { f }); + } +} diff --git a/api/src/tests/move/pack_function_values_with_struct/Move.toml b/api/src/tests/move/pack_function_values_with_struct/Move.toml new file mode 100644 index 00000000000..bcd2fe040c3 --- /dev/null +++ b/api/src/tests/move/pack_function_values_with_struct/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "pack_function_values" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } + +[addresses] +account = "_" diff --git a/api/src/tests/move/pack_function_values_with_struct/sources/test.move b/api/src/tests/move/pack_function_values_with_struct/sources/test.move new file mode 100644 index 00000000000..0105fc65949 --- /dev/null +++ b/api/src/tests/move/pack_function_values_with_struct/sources/test.move @@ -0,0 +1,30 @@ +module account::test { + use std::option; + + struct FunctionStore has key { + f: ||R has copy+drop+store, + } + + struct R(u64) has copy, drop, key, store; + + public fun id(x: R): R { + x + } + + struct R2(T) has copy, drop, key, store; + + fun init_module(account: &signer) { + let v = R(1); + let v2 = R2(option::none()); + let v3 = R2(option::some(1)); + let f: ||R has copy+drop+store = || id(v); + move_to(account, FunctionStore { f }); + move_to(account, v2); + move_to(account, v3); + } + + entry fun entry_function(account: &signer, o: option::Option) { + let v = R2(o); + move_to(account, v); + } +} diff --git a/api/src/tests/move/pack_rand/Move.toml b/api/src/tests/move/pack_rand/Move.toml new file mode 100644 index 00000000000..f344a479797 --- /dev/null +++ b/api/src/tests/move/pack_rand/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "pack_rand" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } + +[addresses] +addr = "_" diff --git a/api/src/tests/move/pack_rand/sources/counter.move b/api/src/tests/move/pack_rand/sources/counter.move new file mode 100644 index 00000000000..1bc5793205d --- /dev/null +++ b/api/src/tests/move/pack_rand/sources/counter.move @@ -0,0 +1,9 @@ +module addr::rand { + use 0x1::randomness::u64_integer; + + + #[randomness] + entry fun rand_integer() { + let _ = u64_integer(); + } +} diff --git a/api/src/tests/move/test_option/Move.toml b/api/src/tests/move/test_option/Move.toml new file mode 100644 index 00000000000..26b7fa6ca52 --- /dev/null +++ b/api/src/tests/move/test_option/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "test_option" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } + +[addresses] +account = "_" diff --git a/api/src/tests/move/test_option/sources/test.move b/api/src/tests/move/test_option/sources/test.move new file mode 100644 index 00000000000..d8b1d9f5b1b --- /dev/null +++ b/api/src/tests/move/test_option/sources/test.move @@ -0,0 +1,28 @@ +module account::test_module { + use std::option; + + struct OptionTest has copy, drop { + o: option::Option, + } + + #[view] + public fun return_none(): option::Option { + option::none() + } + + #[view] + public fun return_some(): option::Option { + option::some(1) + } + + #[view] + public fun return_option_test(): OptionTest { + OptionTest { o: option::some(2) } + } + + #[view] + public fun return_vector_of_option(): vector> { + vector[option::some(3), option::none()] + } + +} diff --git a/api/src/tests/multisig_transactions_test.rs b/api/src/tests/multisig_transactions_test.rs index 3daa99d66e9..22e5b22e5b7 100644 --- a/api/src/tests/multisig_transactions_test.rs +++ b/api/src/tests/multisig_transactions_test.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_types::{ account_address::AccountAddress, @@ -12,10 +12,26 @@ use move_core_types::{ language_storage::{ModuleId, CORE_CODE_ADDRESS}, value::{serialize_values, MoveValue}, }; +use proptest::num::usize; +use rstest::rstest; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_payload_succeeds() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_payload_succeeds( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -50,8 +66,22 @@ async fn test_multisig_transaction_with_payload_succeeds() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_existing_account() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_existing_account( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let multisig_account = &mut context.create_account().await; let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; @@ -103,8 +133,22 @@ async fn test_multisig_transaction_with_existing_account() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_to_update_owners() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_to_update_owners( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -189,8 +233,22 @@ async fn test_multisig_transaction_to_update_owners() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_update_signature_threshold() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_update_signature_threshold( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let multisig_account = context @@ -231,8 +289,22 @@ async fn test_multisig_transaction_update_signature_threshold() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_insufficient_balance_to_cover_gas() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_insufficient_balance_to_cover_gas( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; // Owner 2 has no APT balance. let owner_account_2 = &mut context.gen_account(); @@ -256,8 +328,22 @@ async fn test_multisig_transaction_with_insufficient_balance_to_cover_gas() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_payload_and_failing_execution() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_payload_and_failing_execution( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -279,8 +365,22 @@ async fn test_multisig_transaction_with_payload_and_failing_execution() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_payload_hash() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_payload_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -310,8 +410,22 @@ async fn test_multisig_transaction_with_payload_hash() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_payload_hash_and_failing_execution() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_payload_hash_and_failing_execution( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -344,8 +458,22 @@ async fn test_multisig_transaction_with_payload_hash_and_failing_execution() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_payload_not_matching_hash() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_payload_not_matching_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -374,8 +502,23 @@ async fn test_multisig_transaction_with_payload_not_matching_hash() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_matching_payload() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] + +async fn test_multisig_transaction_with_matching_payload( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -401,8 +544,22 @@ async fn test_multisig_transaction_with_matching_payload() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_with_mismatching_payload() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_with_mismatching_payload( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account(owner_account, vec![], 1, 1000) @@ -441,8 +598,22 @@ async fn test_multisig_transaction_with_mismatching_payload() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_simulation() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_simulation( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -485,8 +656,22 @@ async fn test_multisig_transaction_simulation() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_simulation_2_of_3() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_simulation_2_of_3( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -533,8 +718,22 @@ async fn test_multisig_transaction_simulation_2_of_3() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_simulation_fail() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_simulation_fail( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -578,8 +777,22 @@ async fn test_multisig_transaction_simulation_fail() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multisig_transaction_simulation_fail_2_of_3_insufficient_approvals() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multisig_transaction_simulation_fail_2_of_3_insufficient_approvals( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account_1 = &mut context.create_account().await; let owner_account_2 = &mut context.create_account().await; let owner_account_3 = &mut context.create_account().await; @@ -617,8 +830,22 @@ async fn test_multisig_transaction_simulation_fail_2_of_3_insufficient_approvals } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulate_multisig_transaction_should_charge_gas_against_sender() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulate_multisig_transaction_should_charge_gas_against_sender( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let owner_account = &mut context.create_account().await; let multisig_account = context .create_multisig_account( diff --git a/api/src/tests/objects.rs b/api/src/tests/objects.rs index 3fca5229f6a..7120ac4c8a7 100644 --- a/api/src/tests/objects.rs +++ b/api/src/tests/objects.rs @@ -1,9 +1,10 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_types::account_address::{self, AccountAddress}; +use rstest::rstest; use serde_json::{json, Value}; use std::{collections::BTreeMap, path::PathBuf}; @@ -14,8 +15,19 @@ use std::{collections::BTreeMap, path::PathBuf}; // 4. Transfer to cause transfer event // 4. Read emitted event #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gen_object() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gen_object(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Prepare account let mut user = context.create_account().await; diff --git a/api/src/tests/option_test.rs b/api/src/tests/option_test.rs new file mode 100644 index 00000000000..5a213e51ac1 --- /dev/null +++ b/api/src/tests/option_test.rs @@ -0,0 +1,82 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use super::new_test_context_with_orderless_flags; +use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; +use serde_json::json; +use std::path::PathBuf; + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn run_option(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = + PathBuf::from(std::env!("CARGO_MANIFEST_DIR")).join("src/tests/move/test_option"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + // Run view function + let function = format!("{}::test_module::return_some", account.address()); + let resp = context + .post( + "/view", + json!({ + "function": function, + "arguments": [], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("src/tests/move/pack_function_values_with_struct"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + // Run entry function with option as argument + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::test::entry_function", account_addr.to_hex()), + json!([]), + json!([{"vec": ["1"]}]), + ) + .await; + + let resource = format!("{}::test::R2<0x1::option::Option>", account_addr); + let response = &context + .gen_resource(&account_addr, &resource) + .await + .unwrap(); + + assert_eq!( + response["data"], + json!({ + "_0": {"vec":["1"]}, + }) + ); +} diff --git a/api/src/tests/resource_groups.rs b/api/src/tests/resource_groups.rs index 5715f7672ea..2e79541f214 100644 --- a/api/src/tests/resource_groups.rs +++ b/api/src/tests/resource_groups.rs @@ -1,8 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; use serde_json::json; use std::path::PathBuf; @@ -18,8 +19,22 @@ use std::path::PathBuf; // 9. Init data for that resource group / member // 10. Read and ensure data is present #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gen_resource_group() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gen_resource_group( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); // Prepare accounts let mut admin0 = context.create_account().await; @@ -91,11 +106,39 @@ async fn test_gen_resource_group() { let response = context.gen_resource(&user.address(), &secondary).await; assert_eq!(response.unwrap()["data"]["value"], 55); - let resp = context + let user_txns = context .get(format!("/accounts/{}/transactions", user.address()).as_str()) .await; - let secondary_tx = &resp.as_array().unwrap()[0]; - assert_writeset_contains_secondary_changes(&resp.as_array().unwrap()[1]); + + if use_orderless_transactions { + // `/accounts/{}/transactions` only returns sequence number based transactions. + assert_eq!(user_txns.as_array().unwrap().len(), 0); + } else { + assert_eq!(user_txns.as_array().unwrap().len(), 2); + } + let txn_summaries = context + .get(format!("/accounts/{}/transaction_summaries", user.address()).as_str()) + .await; + assert_eq!(txn_summaries.as_array().unwrap().len(), 2); + let mut user_txns_from_summaries = vec![]; + for txn_summary in txn_summaries.as_array().unwrap() { + let txn = context + .get( + format!( + "/transactions/by_hash/{}", + txn_summary["transaction_hash"].as_str().unwrap() + ) + .as_str(), + ) + .await; + user_txns_from_summaries.push(txn); + } + if !use_orderless_transactions { + assert_eq!(user_txns, json!(user_txns_from_summaries)); + } + + let secondary_tx = &user_txns_from_summaries[0]; + assert_writeset_contains_secondary_changes(&user_txns_from_summaries[1]); let resp = context .get( format!( diff --git a/api/src/tests/secp256k1_ecdsa.rs b/api/src/tests/secp256k1_ecdsa.rs index 3a0121bf41a..0863b9d9ad2 100644 --- a/api/src/tests/secp256k1_ecdsa.rs +++ b/api/src/tests/secp256k1_ecdsa.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::current_function_name; use aptos_crypto::{ed25519::Ed25519PrivateKey, secp256k1_ecdsa, SigningKey}; use aptos_sdk::types::{ @@ -16,11 +16,29 @@ use aptos_sdk::types::{ LocalAccount, }; use rand::{rngs::StdRng, SeedableRng}; +use rstest::rstest; use std::convert::TryInto; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multi_secp256k1_ecdsa() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_multi_secp256k1_ecdsa( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let other = context.create_account().await; let mut rng: StdRng = SeedableRng::from_seed([0; 32]); @@ -44,6 +62,7 @@ async fn test_multi_secp256k1_ecdsa() { let txn2 = context.create_user_account(&other).await; context.commit_block(&vec![txn2]).await; + let current_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let ed22519_txn = context.account_transfer(&mut account, &other, 5); let raw_txn = ed22519_txn.into_raw_transaction(); @@ -67,13 +86,36 @@ async fn test_multi_secp256k1_ecdsa() { balance_start + 5, context.get_apt_balance(other.address()).await ); - let txns = context.get("/transactions?start=14&limit=1").await; + + let txns = context + .get(&format!( + "/transactions?start={}&limit=1", + current_ledger_version + 2 + )) + .await; context.check_golden_output(txns[0]["signature"].clone()); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_secp256k1_ecdsa() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_secp256k1_ecdsa( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let other = context.create_account().await; let mut rng: StdRng = SeedableRng::from_seed([0; 32]); @@ -95,6 +137,7 @@ async fn test_secp256k1_ecdsa() { let txn2 = context.create_user_account(&other).await; context.commit_block(&vec![txn2]).await; + let current_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let ed22519_txn = context.account_transfer(&mut account, &other, 5); let secp256k1_ecdsa_txn = ed22519_txn .into_raw_transaction() @@ -111,6 +154,12 @@ async fn test_secp256k1_ecdsa() { balance_start + 5, context.get_apt_balance(other.address()).await ); - let txns = context.get("/transactions?start=14&limit=1").await; + + let txns = context + .get(&format!( + "/transactions?start={}&limit=1", + current_ledger_version + 2 + )) + .await; context.check_golden_output(txns[0]["signature"].clone()); } diff --git a/api/src/tests/signed_int_test.rs b/api/src/tests/signed_int_test.rs new file mode 100644 index 00000000000..df715c871bd --- /dev/null +++ b/api/src/tests/signed_int_test.rs @@ -0,0 +1,206 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use super::new_test_context_with_orderless_flags; +use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; +use serde_json::json; +use std::path::PathBuf; + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_signed_ints(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("../aptos-move/move-examples/signed_int/calculator"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + + // Init state: `-1i64` + context.publish_package(&mut account, txn).await; + let state_resource = format!("{}::{}::{}", account_addr, "calculator", "State"); + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "-1"})); + + // Reset state: `0i64` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::number", account_addr.to_hex()), + json!([]), + json!(["0"]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "0"})); + + // Add `2i8` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::add", account_addr.to_hex()), + json!([]), + json!([2]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "2"})); + + // Sub `-2i16` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::sub", account_addr.to_hex()), + json!([]), + json!([-2]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "4"})); + + // Mul `2i32` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::mul", account_addr.to_hex()), + json!([]), + json!([2]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "8"})); + + // Div `2i128` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::div", account_addr.to_hex()), + json!([]), + json!(["2"]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "4"})); + + // Mod `-3i256` + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::calculator::mod", account_addr.to_hex()), + json!([]), + json!(["-3"]), + ) + .await; + let state = &context + .gen_resource(&account_addr, &state_resource) + .await + .unwrap()["data"]; + assert_eq!(state, &json!({"__variant__": "Value", "_0": "1"})); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i8", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!([1])); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i16", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!([1])); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i32", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!([1])); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i64", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!(["1"])); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i128", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!(["1"])); + + let resp = context + .post( + "/view", + json!({ + "function": &format!("0x{}::calculator::view_i256", account_addr.to_hex()), + "arguments": vec![account_addr.to_string()], + "type_arguments": [], + }), + ) + .await; + assert_eq!(resp, json!(["1"])); +} diff --git a/api/src/tests/simulation_test.rs b/api/src/tests/simulation_test.rs index a70d4f9fe4e..ee8c6b69497 100644 --- a/api/src/tests/simulation_test.rs +++ b/api/src/tests/simulation_test.rs @@ -1,20 +1,20 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use crate::tests::{new_test_context, new_test_context_with_orderless_flags}; use aptos_api_test_context::{current_function_name, pretty, TestContext}; use aptos_crypto::ed25519::Ed25519Signature; use aptos_types::{ account_address::AccountAddress, transaction::{ authenticator::{AccountAuthenticator, TransactionAuthenticator}, - EntryFunction, RawTransaction, SignedTransaction, TransactionPayload, + EntryFunction, ReplayProtector, SignedTransaction, TransactionPayload, }, }; use move_core_types::{ident_str, language_storage::ModuleId}; +use rstest::rstest; use serde_json::json; use std::path::PathBuf; -const ACCOUNT_ABSTRACTION: u64 = 85; async fn simulate_aptos_transfer( context: &mut TestContext, @@ -35,32 +35,45 @@ async fn simulate_aptos_transfer( signature, } = txn.authenticator_ref() { - let signature = use_valid_signature - .then(|| signature.to_string()) - .unwrap_or(Ed25519Signature::dummy_signature().to_string()); + let signature = if use_valid_signature { + signature.to_string() + } else { + Ed25519Signature::dummy_signature().to_string() + }; + + let mut request = json!({ + "sender": txn.sender().to_string(), + "sequence_number": txn.sequence_number().to_string(), + "max_gas_amount": txn.max_gas_amount().to_string(), + "gas_unit_price": txn.gas_unit_price().to_string(), + "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), + "payload": { + "type": "entry_function_payload", + "function": "0x1::aptos_account::transfer", + "type_arguments": [], + "arguments": [ + bob.address().to_standard_string(), transfer_amount.to_string(), + ] + }, + "signature": { + "type": "ed25519_signature", + "public_key": public_key.to_string(), + "signature": signature, + }, + }); + + if context.use_orderless_transactions { + let nonce = match txn.replay_protector() { + ReplayProtector::SequenceNumber(_) => 0, + ReplayProtector::Nonce(nonce) => nonce, + }; + request["replay_protection_nonce"] = json!(nonce.to_string()); + } + let req = warp::test::request() .method("POST") .path("/v1/transactions/simulate") - .json(&json!({ - "sender": txn.sender().to_string(), - "sequence_number": txn.sequence_number().to_string(), - "max_gas_amount": txn.max_gas_amount().to_string(), - "gas_unit_price": txn.gas_unit_price().to_string(), - "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), - "payload": { - "type": "entry_function_payload", - "function": "0x1::aptos_account::transfer", - "type_arguments": [], - "arguments": [ - bob.address().to_standard_string(), transfer_amount.to_string(), - ] - }, - "signature": { - "type": "ed25519_signature", - "public_key": public_key.to_string(), - "signature": signature, - } - })); + .json(&request); let resp = context.expect_status_code(expected_status).reply(req).await; // Assert the gas used header is present if expected. if assert_gas_used { @@ -81,48 +94,203 @@ async fn simulate_aptos_transfer( } } +async fn simulate_aptos_transfer_bcs( + context: &mut TestContext, + use_valid_signature: bool, + transfer_amount: u64, + expected_status: u16, + assert_gas_used: bool, +) -> serde_json::Value { + let alice = &mut context.gen_account(); + let bob = &mut context.gen_account(); + let txn = context.mint_user_account(alice).await; + context.commit_block(&vec![txn]).await; + + let txn = context.account_transfer_to(alice, bob.address(), transfer_amount); + + if let TransactionAuthenticator::Ed25519 { + public_key, + signature, + } = txn.authenticator_ref() + { + let signature = if use_valid_signature { + signature.clone() + } else { + Ed25519Signature::dummy_signature() + }; + + let txn = SignedTransaction::new( + txn.clone().into_raw_transaction(), + public_key.clone(), + signature.clone(), + ); + let bcs_txn = bcs::to_bytes(&txn).unwrap(); + + let resp = context + .expect_status_code(expected_status) + .post_bcs_txn("/transactions/simulate", bcs_txn) + .await; + if assert_gas_used { + let gas_used = resp[0]["gas_used"].to_string(); + let gas_used = gas_used[1..gas_used.len() - 1].parse::().unwrap(); // Removing double quotes in the string + assert!(gas_used > 0); + } + resp + } else { + unreachable!("Simulation uses Ed25519 authenticator."); + } +} + const SMALL_TRANSFER_AMOUNT: u64 = 10; const LARGE_TRANSFER_AMOUNT: u64 = 1_000_000_000; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulate_transaction_with_valid_signature() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + // TODO[Orderless]: When the input is given in JSON format, the /transactions endpoint will use payload v1 format + // to construct the transactions. So, the supplied signature that is signed on payload v2 format will not match. + // case(true, false), + case(true, true) +)] +async fn test_simulate_transaction_with_valid_signature( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let resp = simulate_aptos_transfer(&mut context, true, SMALL_TRANSFER_AMOUNT, 400, false).await; context.check_golden_output(resp); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulate_transaction_with_not_valid_signature() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulate_transaction_with_valid_signature_bcs( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let resp = + simulate_aptos_transfer_bcs(&mut context, true, SMALL_TRANSFER_AMOUNT, 400, false).await; + context.check_golden_output(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulate_transaction_with_not_valid_signature( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let resp = + simulate_aptos_transfer_bcs(&mut context, false, SMALL_TRANSFER_AMOUNT, 200, true).await; + assert!(resp[0]["success"].as_bool().is_some_and(|v| v)); + let resp = simulate_aptos_transfer(&mut context, false, SMALL_TRANSFER_AMOUNT, 200, true).await; assert!(resp[0]["success"].as_bool().is_some_and(|v| v)); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulate_transaction_with_insufficient_balance() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulate_transaction_with_insufficient_balance( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let resp = + simulate_aptos_transfer_bcs(&mut context, false, LARGE_TRANSFER_AMOUNT, 200, true).await; + assert!(!resp[0]["success"].as_bool().is_some_and(|v| v)); + let resp = simulate_aptos_transfer(&mut context, false, LARGE_TRANSFER_AMOUNT, 200, true).await; assert!(!resp[0]["success"].as_bool().is_some_and(|v| v)); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_simulate_fee_payer_transaction_without_gas_fee_check_with_aa_disabled() { - let mut context = new_test_context(current_function_name!()); - context.disable_feature(ACCOUNT_ABSTRACTION).await; +#[rstest(use_txn_payload_v2_format, case(false), case(true))] +async fn test_bcs_simulate_fee_payer_transaction_without_gas_fee_check_with_aa_disabled( + use_txn_payload_v2_format: bool, +) { + // Orderless transactions use the new prologue methods introduced when account abstraction is introduced. + // Hence, not testing orderless transactions here. + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + false, + ); + context + .disable_feature(aptos_types::on_chain_config::FeatureFlag::ACCOUNT_ABSTRACTION as u64) + .await; bcs_simulate_fee_payer_transaction_without_gas_fee_check(&mut context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_simulate_fee_payer_transaction_without_gas_fee_check() { - let mut context = new_test_context(current_function_name!()); - context.disable_feature(ACCOUNT_ABSTRACTION).await; +#[rstest(use_txn_payload_v2_format, case(false), case(true))] +async fn test_bcs_simulate_fee_payer_transaction_without_gas_fee_check( + use_txn_payload_v2_format: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + false, + ); + context + .disable_feature(aptos_types::on_chain_config::FeatureFlag::ACCOUNT_ABSTRACTION as u64) + .await; bcs_simulate_fee_payer_transaction_without_gas_fee_check(&mut context).await; } // Enable the MODULE_EVENT_MIGRATION feature #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulate_txn_with_aggregator() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulate_txn_with_aggregator( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; let named_addresses = vec![("addr".to_string(), account.address())]; @@ -137,36 +305,51 @@ async fn test_simulate_txn_with_aggregator() { vec![], vec![], )); - let txn = account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let txn = account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); if let TransactionAuthenticator::Ed25519 { public_key, signature: _, } = txn.authenticator_ref() { let function = format!("{}::counter::increment_counter", account.address()); + let mut request = json!({ + "sender": txn.sender().to_string(), + "sequence_number": txn.sequence_number().to_string(), + "max_gas_amount": txn.max_gas_amount().to_string(), + "gas_unit_price": txn.gas_unit_price().to_string(), + "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), + "payload": { + "type": "entry_function_payload", + "function": function, + "type_arguments": [], + "arguments": [] + }, + "signature": { + "type": "ed25519_signature", + "public_key": public_key.to_string(), + "signature": Ed25519Signature::dummy_signature().to_string(), + }, + }); + if context.use_orderless_transactions { + let replay_protection_nonce = match txn.replay_protector() { + ReplayProtector::SequenceNumber(_) => 0, + ReplayProtector::Nonce(nonce) => nonce, + }; + request["replay_protection_nonce"] = json!(replay_protection_nonce.to_string()); + } let resp = context .expect_status_code(200) - .post( - "/transactions/simulate", - json!({ - "sender": txn.sender().to_string(), - "sequence_number": txn.sequence_number().to_string(), - "max_gas_amount": txn.max_gas_amount().to_string(), - "gas_unit_price": txn.gas_unit_price().to_string(), - "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), - "payload": { - "type": "entry_function_payload", - "function": function, - "type_arguments": [], - "arguments": [] - }, - "signature": { - "type": "ed25519_signature", - "public_key": public_key.to_string(), - "signature": Ed25519Signature::dummy_signature().to_string(), - } - }), - ) + .post("/transactions/simulate", request) .await; assert!(resp[0]["success"].as_bool().is_some_and(|v| v)); } else { @@ -175,10 +358,24 @@ async fn test_simulate_txn_with_aggregator() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_simulate_simple() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_bcs_simulate_simple( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let transfer_amount: u64 = SMALL_TRANSFER_AMOUNT; - let mut context = new_test_context(current_function_name!()); + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let alice = &mut context.gen_account(); let bob = &mut context.gen_account(); let txn = context.mint_user_account(alice).await; @@ -221,10 +418,24 @@ async fn test_bcs_simulate_simple() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_simulate_without_auth_key_check() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_bcs_simulate_without_auth_key_check( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let transfer_amount: u64 = SMALL_TRANSFER_AMOUNT; - let mut context = new_test_context(current_function_name!()); + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let alice = &mut context.gen_account(); let bob = &mut context.gen_account(); let txn = context.mint_user_account(alice).await; @@ -258,15 +469,8 @@ async fn bcs_simulate_fee_payer_transaction_without_gas_fee_check(context: &mut let transfer_amount: u64 = SMALL_TRANSFER_AMOUNT; let txn = context.account_transfer_to(alice, bob.address(), transfer_amount); - let raw_txn = RawTransaction::new( - txn.sender(), - txn.sequence_number(), - txn.payload().clone(), - txn.max_gas_amount(), - 100, - txn.expiration_timestamp_secs(), - txn.chain_id(), - ); + let mut raw_txn = txn.clone().into_raw_transaction(); + raw_txn.set_gas_unit_price(100); let txn = SignedTransaction::new_signed_transaction( raw_txn.clone(), TransactionAuthenticator::FeePayer { @@ -311,22 +515,29 @@ async fn bcs_simulate_fee_payer_transaction_without_gas_fee_check(context: &mut } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_simulate_automated_account_creation() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_bcs_simulate_automated_account_creation( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let alice = &mut context.gen_account(); let bob = &mut context.gen_account(); let transfer_amount: u64 = 0; let txn = context.account_transfer_to(alice, bob.address(), transfer_amount); - let raw_txn = RawTransaction::new( - txn.sender(), - txn.sequence_number(), - txn.payload().clone(), - txn.max_gas_amount(), - 100, - txn.expiration_timestamp_secs(), - txn.chain_id(), - ); + let mut raw_txn = txn.clone().into_raw_transaction(); + raw_txn.set_gas_unit_price(100); // Replace the authenticator with a NoAccountAuthenticator in the transaction. let txn = SignedTransaction::new_signed_transaction( raw_txn.clone(), @@ -342,14 +553,31 @@ async fn test_bcs_simulate_automated_account_creation() { .post_bcs_txn("/transactions/simulate", body) .await; assert!(!resp[0]["success"].as_bool().unwrap(), "{}", pretty(&resp)); - assert!( - resp[0]["vm_status"] - .as_str() - .unwrap() - .contains("INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE"), - "{}", - pretty(&resp) - ); + if !context.use_orderless_transactions + && !context + .is_feature_enabled( + aptos_types::on_chain_config::FeatureFlag::ORDERLESS_TRANSACTIONS as u64, + ) + .await + { + assert!( + resp[0]["vm_status"] + .as_str() + .unwrap() + .contains("INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE"), + "{}", + pretty(&resp) + ); + } else { + assert!( + resp[0]["vm_status"] + .as_str() + .unwrap() + .contains("INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE"), + "{}", + pretty(&resp) + ); + } let txn = SignedTransaction::new_signed_transaction(raw_txn, TransactionAuthenticator::FeePayer { @@ -368,10 +596,24 @@ async fn test_bcs_simulate_automated_account_creation() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_execute_simple_no_authenticator_fail() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_bcs_execute_simple_no_authenticator_fail( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let transfer_amount: u64 = SMALL_TRANSFER_AMOUNT; - let mut context = new_test_context(current_function_name!()); + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let alice = &mut context.gen_account(); let bob = &mut context.gen_account(); let txn = context.mint_user_account(alice).await; @@ -401,8 +643,22 @@ async fn test_bcs_execute_simple_no_authenticator_fail() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_bcs_execute_fee_payer_transaction_no_authenticator_fail() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_bcs_execute_fee_payer_transaction_no_authenticator_fail( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let alice = &mut context.gen_account(); let bob = &mut context.gen_account(); let txn = context.mint_user_account(alice).await; @@ -410,16 +666,8 @@ async fn test_bcs_execute_fee_payer_transaction_no_authenticator_fail() { let transfer_amount: u64 = SMALL_TRANSFER_AMOUNT; let txn = context.account_transfer_to(alice, bob.address(), transfer_amount); - let raw_txn = RawTransaction::new( - txn.sender(), - txn.sequence_number(), - txn.payload().clone(), - txn.max_gas_amount(), - 100, - txn.expiration_timestamp_secs(), - txn.chain_id(), - ); - + let mut raw_txn = txn.clone().into_raw_transaction(); + raw_txn.set_gas_unit_price(100); let txn = SignedTransaction::new_signed_transaction( raw_txn.clone(), TransactionAuthenticator::FeePayer { @@ -440,3 +688,64 @@ async fn test_bcs_execute_fee_payer_transaction_no_authenticator_fail() { .unwrap() .contains("INVALID_SIGNATURE")); } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_simulate_txn_with_randomness() { + let mut context = new_test_context(current_function_name!()); + let account = context.root_account().await; + + let named_addresses = vec![("addr".to_string(), account.address())]; + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_rand"); + let payload = TestContext::build_package(path, named_addresses); + let txn = account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + context.commit_block(&vec![txn]).await; + + let payload = TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new(account.address(), ident_str!("rand").to_owned()), + ident_str!("rand_integer").to_owned(), + vec![], + vec![], + )); + let txn = account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); + if let TransactionAuthenticator::Ed25519 { + public_key, + signature: _, + } = txn.authenticator_ref() + { + let function = format!("{}::rand::rand_integer", account.address()); + let request = json!({ + "sender": txn.sender().to_string(), + "sequence_number": txn.sequence_number().to_string(), + "max_gas_amount": txn.max_gas_amount().to_string(), + "gas_unit_price": txn.gas_unit_price().to_string(), + "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), + "payload": { + "type": "entry_function_payload", + "function": function, + "type_arguments": [], + "arguments": [] + }, + "signature": { + "type": "ed25519_signature", + "public_key": public_key.to_string(), + "signature": Ed25519Signature::dummy_signature().to_string(), + }, + }); + let resp = context + .expect_status_code(200) + .post("/transactions/simulate", request) + .await; + assert!(resp[0]["success"].as_bool().is_some_and(|v| v)); + } else { + unreachable!("Simulation uses Ed25519 authenticator."); + } +} diff --git a/api/src/tests/state_test.rs b/api/src/tests/state_test.rs index a22e5e9ebc2..7c078c711e7 100644 --- a/api/src/tests/state_test.rs +++ b/api/src/tests/state_test.rs @@ -1,11 +1,12 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::{new_test_context, new_test_context_with_orderless_flags}; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_sdk::{transaction_builder::aptos_stdlib::aptos_token_stdlib, types::LocalAccount}; use aptos_storage_interface::DbReader; use move_core_types::account_address::AccountAddress; +use rstest::rstest; use serde::Serialize; use serde_json::{json, Value}; use std::path::PathBuf; @@ -122,11 +123,26 @@ async fn test_get_account_module_not_found() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_merkle_leaves_with_nft_transfer() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_merkle_leaves_with_nft_transfer( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut ctx = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let num_block_resource = 1; + // For orderless transaction, 1 nonce table bucket and 1 storage slots in big ordered map are created + let num_nonce_table_resource = if use_orderless_transactions { 1 } else { 0 }; - let ctx = &mut context; let creator = &mut ctx.gen_account(); let owner = &mut ctx.gen_account(); let txn1 = ctx.mint_user_account(creator).await; @@ -134,35 +150,46 @@ async fn test_merkle_leaves_with_nft_transfer() { let collection_name = "collection name".to_owned().into_bytes(); let token_name = "token name".to_owned().into_bytes(); - let collection_builder = - ctx.transaction_factory() - .payload(aptos_token_stdlib::token_create_collection_script( - collection_name.clone(), - "description".to_owned().into_bytes(), - "uri".to_owned().into_bytes(), - 20_000_000, - vec![false, false, false], - )); + let collection_builder = ctx + .transaction_factory() + .payload(aptos_token_stdlib::token_create_collection_script( + collection_name.clone(), + "description".to_owned().into_bytes(), + "uri".to_owned().into_bytes(), + 20_000_000, + vec![false, false, false], + )) + .expiration_timestamp_secs(ctx.get_expiration_time()) + .upgrade_payload_with_rng( + &mut ctx.rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let collection_txn = creator.sign_with_transaction_builder(collection_builder); - - let token_builder = - ctx.transaction_factory() - .payload(aptos_token_stdlib::token_create_token_script( - collection_name.clone(), - token_name.clone(), - "collection description".to_owned().into_bytes(), - 3, - 4, - "uri".to_owned().into_bytes(), - creator.address(), - 1, - 0, - vec![false, false, false, false, true], - vec!["age".as_bytes().to_vec()], - vec!["3".as_bytes().to_vec()], - vec!["int".as_bytes().to_vec()], - )); + let token_builder = ctx + .transaction_factory() + .payload(aptos_token_stdlib::token_create_token_script( + collection_name.clone(), + token_name.clone(), + "collection description".to_owned().into_bytes(), + 3, + 4, + "uri".to_owned().into_bytes(), + creator.address(), + 1, + 0, + vec![false, false, false, false, true], + vec!["age".as_bytes().to_vec()], + vec!["3".as_bytes().to_vec()], + vec!["int".as_bytes().to_vec()], + )) + .expiration_timestamp_secs(ctx.get_expiration_time()) + .upgrade_payload_with_rng( + &mut ctx.rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let token_txn = creator.sign_with_transaction_builder(token_builder); @@ -183,7 +210,13 @@ async fn test_merkle_leaves_with_nft_transfer() { token_name.clone(), 0, 1, - )), + )) + .expiration_timestamp_secs(ctx.get_expiration_time()) + .upgrade_payload_with_rng( + &mut ctx.rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ), ); ctx.commit_block(&vec![transfer_to_owner_txn]).await; let num_leaves_after_transfer_nft = ctx @@ -192,7 +225,7 @@ async fn test_merkle_leaves_with_nft_transfer() { .unwrap(); assert_eq!( num_leaves_after_transfer_nft, - num_leaves_at_beginning + 3 /* 1 token store + 1 token + 1 account resource */ + num_block_resource + num_leaves_at_beginning + 3 /* 1 token store + 1 token + 1 account resource */ + num_block_resource + num_nonce_table_resource ); let transfer_to_creator_txn = owner.sign_multi_agent_with_transaction_builder( @@ -204,7 +237,13 @@ async fn test_merkle_leaves_with_nft_transfer() { token_name.clone(), 0, 1, - )), + )) + .expiration_timestamp_secs(ctx.get_expiration_time()) + .upgrade_payload_with_rng( + &mut ctx.rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ), ); ctx.commit_block(&vec![transfer_to_creator_txn]).await; let num_leaves_after_return_nft = ctx @@ -214,7 +253,7 @@ async fn test_merkle_leaves_with_nft_transfer() { assert_eq!( num_leaves_after_return_nft, - num_leaves_at_beginning + 2 + num_block_resource * 2 + num_leaves_at_beginning + 2 + num_block_resource * 2 + 2 * num_nonce_table_resource ); } diff --git a/api/src/tests/string_resource_test.rs b/api/src/tests/string_resource_test.rs index e94655109db..05c4495b109 100644 --- a/api/src/tests/string_resource_test.rs +++ b/api/src/tests/string_resource_test.rs @@ -2,14 +2,29 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; +use super::new_test_context_with_orderless_flags; use aptos_api_test_context::{current_function_name, TestContext}; +use rstest::rstest; use serde_json::json; use std::path::PathBuf; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_renders_move_acsii_string_into_utf8_string() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_renders_move_acsii_string_into_utf8_string( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut account = context.root_account().await; let addr = account.address(); @@ -17,7 +32,17 @@ async fn test_renders_move_acsii_string_into_utf8_string() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_string_resource"); let payload = TestContext::build_package(path, named_addresses); - let txn = account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let txn = account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); context.commit_block(&vec![txn]).await; context diff --git a/api/src/tests/transaction_vector_test.rs b/api/src/tests/transaction_vector_test.rs index 22f0e4f9a3d..8434e1a9bb5 100644 --- a/api/src/tests/transaction_vector_test.rs +++ b/api/src/tests/transaction_vector_test.rs @@ -16,7 +16,7 @@ **************************************************************************************/ use super::new_test_context; -use aptos_api_test_context::current_function_name; +use aptos_api_test_context::{current_function_name, TestContext}; use aptos_crypto::{ ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, SigningKey, Uniform, @@ -177,28 +177,28 @@ fn script_strategy() -> impl Strategy { } #[cfg(test)] -fn gen_u64(gen: &mut ValueGenerator) -> u64 { - gen.generate(any::()) +fn gen_u64(r#gen: &mut ValueGenerator) -> u64 { + r#gen.generate(any::()) } #[cfg(test)] -fn gen_chain_id(gen: &mut ValueGenerator) -> u8 { - gen.generate(chain_id_strategy()) +fn gen_chain_id(r#gen: &mut ValueGenerator) -> u8 { + r#gen.generate(chain_id_strategy()) } #[cfg(test)] -fn gen_address(gen: &mut ValueGenerator) -> AccountAddress { - gen.generate(any::()) +fn gen_address(r#gen: &mut ValueGenerator) -> AccountAddress { + r#gen.generate(any::()) } #[cfg(test)] -fn gen_entry_function(gen: &mut ValueGenerator) -> EntryFunction { - gen.generate(entry_function_strategy()) +fn gen_entry_function(r#gen: &mut ValueGenerator) -> EntryFunction { + r#gen.generate(entry_function_strategy()) } #[cfg(test)] -fn gen_script(gen: &mut ValueGenerator) -> Script { - gen.generate(script_strategy()) +fn gen_script(r#gen: &mut ValueGenerator) -> Script { + r#gen.generate(script_strategy()) } #[cfg(test)] @@ -240,17 +240,28 @@ fn byte_array_to_hex(v: &mut serde_json::Value) -> serde_json::Value { serde_json::Value::String(hex::encode(byte_array)) } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_entry_function_payload() { +async fn entry_function_payload(context: &mut TestContext) -> Vec { // The purpose of patches is to convert bytes arrays to hex-coded strings. // Patches the serde_json result is easier comparing to implement a customized serializer. - fn patch(raw_txn_json: &mut serde_json::Value) { - let args = visit_json_field(raw_txn_json, &[ - "raw_txn", - "payload", - "EntryFunction", - "args", - ]); + fn patch(raw_txn_json: &mut serde_json::Value, use_txn_payload_v2_format: bool) { + let args = if use_txn_payload_v2_format { + visit_json_field(raw_txn_json, &[ + "raw_txn", + "payload", + "Payload", + "V1", + "executable", + "EntryFunction", + "args", + ]) + } else { + visit_json_field(raw_txn_json, &[ + "raw_txn", + "payload", + "EntryFunction", + "args", + ]) + }; let mut hex_args: Vec = vec![]; for arg in args.as_array_mut().unwrap() { @@ -260,8 +271,6 @@ async fn test_entry_function_payload() { *args = json!(hex_args); } - let mut context = new_test_context(current_function_name!()); - let mut value_gen = ValueGenerator::deterministic(); let mut txns = vec![]; for _ in 0..100 { @@ -274,23 +283,56 @@ async fn test_entry_function_payload() { .max_gas_amount(gen_u64(&mut value_gen)) .gas_unit_price(gen_u64(&mut value_gen)) .chain_id(ChainId::new(gen_chain_id(&mut value_gen))) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ) .build(); let mut signed_txn = sign_transaction(raw_txn); - patch(&mut signed_txn); + patch(&mut signed_txn, context.use_txn_payload_v2_format); txns.push(signed_txn); } + txns +} +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_entry_function_payload() { + let mut context = new_test_context(current_function_name!()); + let txns = entry_function_payload(&mut context).await; context.check_golden_output(json!(txns)); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_script_payload() { - fn patch(raw_txn_json: &mut serde_json::Value) { - let code = visit_json_field(raw_txn_json, &["raw_txn", "payload", "Script", "code"]); +async fn script_payload(context: &mut TestContext) -> Vec { + fn patch(raw_txn_json: &mut serde_json::Value, use_txn_payload_v2_format: bool) { + let code = if use_txn_payload_v2_format { + visit_json_field(raw_txn_json, &[ + "raw_txn", + "payload", + "Payload", + "V1", + "executable", + "Script", + "code", + ]) + } else { + visit_json_field(raw_txn_json, &["raw_txn", "payload", "Script", "code"]) + }; *code = byte_array_to_hex(code); - let args = visit_json_field(raw_txn_json, &["raw_txn", "payload", "Script", "args"]); - + let args = if use_txn_payload_v2_format { + visit_json_field(raw_txn_json, &[ + "raw_txn", + "payload", + "Payload", + "V1", + "executable", + "Script", + "args", + ]) + } else { + visit_json_field(raw_txn_json, &["raw_txn", "payload", "Script", "args"]) + }; for arg in args.as_array_mut().unwrap() { let arg_obj = arg.as_object_mut().unwrap(); @@ -300,8 +342,6 @@ async fn test_script_payload() { } } - let mut context = new_test_context(current_function_name!()); - let mut value_gen = ValueGenerator::deterministic(); let mut txns = vec![]; for _ in 0..100 { @@ -314,11 +354,22 @@ async fn test_script_payload() { .max_gas_amount(gen_u64(&mut value_gen)) .gas_unit_price(gen_u64(&mut value_gen)) .chain_id(ChainId::new(gen_chain_id(&mut value_gen))) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ) .build(); let mut signed_txn = sign_transaction(raw_txn); - patch(&mut signed_txn); + patch(&mut signed_txn, context.use_txn_payload_v2_format); txns.push(signed_txn); } + txns +} +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_script_payload() { + let mut context = new_test_context(current_function_name!()); + let txns = script_payload(&mut context).await; context.check_golden_output(json!(txns)); } diff --git a/api/src/tests/transactions_test.rs b/api/src/tests/transactions_test.rs index 829c863227f..83c394e8e70 100644 --- a/api/src/tests/transactions_test.rs +++ b/api/src/tests/transactions_test.rs @@ -3,24 +3,22 @@ // SPDX-License-Identifier: Apache-2.0 use super::new_test_context; -use crate::tests::{ - new_test_context_with_config, new_test_context_with_db_sharding_and_internal_indexer, - new_test_context_with_sharding_and_delayed_internal_indexer, -}; +use crate::tests::{new_test_context_with_config, new_test_context_with_orderless_flags}; use aptos_api_test_context::{assert_json, current_function_name, pretty, TestContext}; -use aptos_config::config::{GasEstimationStaticOverride, NodeConfig}; +use aptos_config::config::{GasEstimationStaticOverride, NodeConfig, TransactionFilterConfig}; use aptos_crypto::{ ed25519::{Ed25519PrivateKey, Ed25519Signature}, multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey}, PrivateKey, SigningKey, Uniform, }; use aptos_sdk::types::{AccountKey, LocalAccount}; +use aptos_transaction_filters::transaction_filter::TransactionFilter; use aptos_types::{ account_address::AccountAddress, account_config::aptos_test_root_address, transaction::{ authenticator::{AuthenticationKey, TransactionAuthenticator}, - EntryFunction, Script, SignedTransaction, + EntryFunction, ReplayProtector, Script, SignedTransaction, }, utility_coin::{AptosCoinType, CoinType}, }; @@ -30,7 +28,8 @@ use move_core_types::{ }; use poem_openapi::types::ParseFromJSON; use rand::{distributions::Alphanumeric, thread_rng, Rng}; -use serde_json::json; +use rstest::rstest; +use serde_json::{json, Value}; use std::{path::PathBuf, time::Duration}; use tokio::time::sleep; @@ -53,8 +52,24 @@ async fn test_get_transactions_output_genesis_transaction() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_transactions_returns_last_page_when_start_version_is_not_specified() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_transactions_returns_last_page_when_start_version_is_not_specified( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut root_account = context.root_account().await; for _i in 0..20 { @@ -117,20 +132,56 @@ async fn test_get_transactions_param_limit_exceeds_limit() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_transactions_output_user_transaction_with_entry_function_payload() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_transactions_output_user_transaction_with_entry_function_payload( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn.clone()]).await; let txns = context.get("/transactions?start=1").await; - assert_eq!(3, txns.as_array().unwrap().len()); + assert_eq!( + (initial_ledger_version + 3) as usize, + txns.as_array().unwrap().len() + ); context.check_golden_output(txns); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_post_bcs_format_transaction() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_post_bcs_format_transaction( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; let body = bcs::to_bytes(&txn).unwrap(); @@ -141,15 +192,33 @@ async fn test_post_bcs_format_transaction() { context.check_golden_output(resp.clone()); // ensure ed25519 sig txn can be submitted into mempool by JSON format - context - .expect_status_code(202) - .post("/transactions", resp) - .await; + // TODO[Orderless]: When the input is given in JSON format, the /transactions endpoint will use payload v1 format + // to construct the transactions. So, the supplied signature that is signed on payload v2 format will not match. + if !context.use_txn_payload_v2_format || context.use_orderless_transactions { + context + .expect_status_code(202) + .post("/transactions", resp) + .await; + } } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_post_invalid_bcs_format_transaction() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_post_invalid_bcs_format_transaction( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let resp = context .expect_status_code(400) @@ -159,8 +228,22 @@ async fn test_post_invalid_bcs_format_transaction() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_post_invalid_signature_transaction() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_post_invalid_signature_transaction( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let txn = context.create_invalid_signature_transaction().await; let body = bcs::to_bytes(&txn).unwrap(); let resp = context @@ -171,8 +254,22 @@ async fn test_post_invalid_signature_transaction() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_post_transaction_rejected_by_mempool() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_post_transaction_rejected_by_mempool( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account1 = context.gen_account(); let account2 = context.gen_account(); let txn1 = context.create_user_account(&account1).await; @@ -183,30 +280,60 @@ async fn test_post_transaction_rejected_by_mempool() { .post_bcs_txn("/transactions", &bcs::to_bytes(&txn1).unwrap()) .await; - let resp = context - .expect_status_code(400) - .post_bcs_txn("/transactions", &bcs::to_bytes(&txn2).unwrap()) - .await; - context.check_golden_output(resp); + // If txn1 and txn2 are sequence number based transactions, both of them have same sequence number. + // So, txn2 will be rejected by mempool. + // But if txn1 and txn2 are orderless transactions, both transactions should be accepted by mempool. + if context.use_orderless_transactions { + context + .expect_status_code(202) + .post_bcs_txn("/transactions", &bcs::to_bytes(&txn2).unwrap()) + .await; + } else { + let resp = context + .expect_status_code(400) + .post_bcs_txn("/transactions", &bcs::to_bytes(&txn2).unwrap()) + .await; + context.check_golden_output(resp); + } } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_multi_agent_signed_transaction() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_multi_agent_signed_transaction( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let secondary = context.gen_account(); let factory = context.transaction_factory(); let mut root_account = context.root_account().await; // Create secondary signer account - context - .commit_block(&[context.create_user_account_by(&mut root_account, &secondary)]) - .await; + let txn1 = context.create_user_account_by(&mut root_account, &secondary); + context.commit_block(&[txn1]).await; // Create a new account with a multi-agent signer let txn = root_account.sign_multi_agent_with_transaction_builder( vec![&secondary], - factory.create_user_account(account.public_key()), + factory + .create_user_account(account.public_key()) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); let body = bcs::to_bytes(&txn).unwrap(); @@ -249,29 +376,53 @@ async fn test_multi_agent_signed_transaction() { ); // ensure multi agent txns can be submitted into mempool by JSON format - context - .expect_status_code(202) - .post("/transactions", resp) - .await; + // TODO[Orderless]: When the input is given in JSON format, the /transactions endpoint will use payload v1 format + // to construct the transactions. So, the supplied signature that is signed on payload v2 format will not match. + if !context.use_txn_payload_v2_format || context.use_orderless_transactions { + context + .expect_status_code(202) + .post("/transactions", resp) + .await; + } } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_fee_payer_signed_transaction() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_fee_payer_signed_transaction( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let fee_payer = context.create_account().await; let factory = context.transaction_factory(); let mut root_account = context.root_account().await; - context - .commit_block(&[context.create_user_account_by(&mut root_account, &fee_payer)]) - .await; + let txn1 = context.create_user_account_by(&mut root_account, &fee_payer); + context.commit_block(&[txn1]).await; // Create a new account with a multi-agent signer let txn = root_account.sign_fee_payer_with_transaction_builder( vec![], &fee_payer, - factory.create_user_account(account.public_key()), + factory + .create_user_account(account.public_key()) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); let body = bcs::to_bytes(&txn).unwrap(); @@ -316,10 +467,14 @@ async fn test_fee_payer_signed_transaction() { ); // ensure fee payer txns can be submitted into mempool by JSON format - context - .expect_status_code(202) - .post("/transactions", resp) - .await; + // TODO[Orderless]: When the input is given in JSON format, the /transactions endpoint will use payload v1 format + // to construct the transactions. So, the supplied signature that is signed on payload v2 format will not match. + if !context.use_txn_payload_v2_format || context.use_orderless_transactions { + context + .expect_status_code(202) + .post("/transactions", resp) + .await; + } // Now test for the new format where the fee payer is unset... this also tests account creation let another_account = context.gen_account(); @@ -331,7 +486,13 @@ async fn test_fee_payer_signed_transaction() { factory .create_user_account(yet_another_account.public_key()) .max_gas_amount(200_000) - .gas_unit_price(1), + .gas_unit_price(1) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ) .into_raw_transaction(); let another_txn = another_raw_txn @@ -399,10 +560,14 @@ async fn test_fee_payer_signed_transaction() { .expect_status_code(202) .post_bcs_txn("/transactions", body) .await; - context - .expect_status_code(202) - .post("/transactions", resp) - .await; + // TODO[Orderless]: When the input is given in JSON format, the /transactions endpoint will use payload v1 format + // to construct the transactions. So, the supplied signature that is signed on payload v2 format will not match. + if !context.use_txn_payload_v2_format || context.use_orderless_transactions { + context + .expect_status_code(202) + .post("/transactions", resp) + .await; + } } #[ignore] @@ -418,7 +583,14 @@ async fn test_multi_ed25519_signed_transaction() { let root_account = context.root_account().await; // TODO: migrate once multi-ed25519 is supported let create_account_txn = root_account.sign_with_transaction_builder( - factory.create_user_account(&Ed25519PrivateKey::generate_for_testing().public_key()), + factory + .create_user_account(&Ed25519PrivateKey::generate_for_testing().public_key()) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); context.commit_block(&vec![create_account_txn]).await; @@ -426,7 +598,12 @@ async fn test_multi_ed25519_signed_transaction() { .mint(auth_key.account_address(), 1000) .sender(auth_key.account_address()) .sequence_number(0) - .expiration_timestamp_secs(u64::MAX) // set timestamp to max to ensure static raw transaction + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ) .build(); let signature = private_key.sign(&raw_txn).unwrap(); @@ -474,8 +651,22 @@ async fn test_multi_ed25519_signed_transaction() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_transaction_by_hash() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_transaction_by_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn.clone()]).await; @@ -492,34 +683,6 @@ async fn test_get_transaction_by_hash() { assert_json(resp, txns[0].clone()); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_transaction_by_hash_with_delayed_internal_indexer() { - let mut context = new_test_context_with_sharding_and_delayed_internal_indexer( - current_function_name!(), - Some(2), - ); - - let mut account = context.gen_account(); - let txn = context.create_user_account(&account).await; - context.commit_block(&vec![txn.clone()]).await; - let txn1 = context.account_transfer_to( - &mut account, - AccountAddress::from_hex_literal("0x1").unwrap(), - 1, - ); - context.commit_block(&vec![txn1.clone()]).await; - let committed_hash = txn1.committed_hash().to_hex_literal(); - - let _ = context - .get_indexer_reader() - .unwrap() - .wait_for_internal_indexer(1); - let resp = context - .get(&format!("/transactions/by_hash/{}", committed_hash)) - .await; - context.check_golden_output(resp); -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_transaction_by_hash_not_found() { let mut context = new_test_context(current_function_name!()); @@ -554,8 +717,22 @@ async fn test_get_transaction_by_version_not_found() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_transaction_by_version() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_transaction_by_version( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn.clone()]).await; @@ -568,8 +745,22 @@ async fn test_get_transaction_by_version() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_pending_transaction_by_hash() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_pending_transaction_by_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; let body = bcs::to_bytes(&txn).unwrap(); @@ -603,10 +794,25 @@ async fn test_get_pending_transaction_by_hash() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_wait_transaction_by_hash() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_wait_transaction_by_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.wait_by_hash_timeout_ms = 2_000; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn.clone()]).await; @@ -646,7 +852,8 @@ async fn test_wait_transaction_by_hash_not_found() { async fn test_wait_transaction_by_invalid_hash() { let mut node_config = NodeConfig::default(); node_config.api.wait_by_hash_timeout_ms = 2_000; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = + new_test_context_with_config(current_function_name!(), node_config, false, false); let start_time = std::time::Instant::now(); let resp = context @@ -659,10 +866,25 @@ async fn test_wait_transaction_by_invalid_hash() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_wait_pending_transaction_by_hash() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_wait_pending_transaction_by_hash( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.wait_by_hash_timeout_ms = 2_000; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; let body = bcs::to_bytes(&txn).unwrap(); @@ -699,8 +921,25 @@ async fn test_wait_pending_transaction_by_hash() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_signing_message_with_entry_function_payload() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + // TODO[Orderless]: `/transactions/encode_submission` API currently encodes transactions using payload v1 format + // unless a nonce is supplied. So, not testing with payload v2 format here. After the API is updated to use payload v2 format, + // we can also test with payload v2 format here. + // case(true, false), + case(true, true) +)] +async fn test_signing_message_with_entry_function_payload( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; let payload = json!({ @@ -720,15 +959,26 @@ async fn test_signing_message_with_payload( payload: serde_json::Value, ) { let sender = context.root_account().await; - let mut body = json!({ - "sender": sender.address().to_hex_literal(), - "sequence_number": sender.sequence_number().to_string(), - "gas_unit_price": txn.gas_unit_price().to_string(), - "max_gas_amount": txn.max_gas_amount().to_string(), - "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), - "payload": payload, - }); - + let mut body = { + let mut json = json!({ + "sender": sender.address().to_hex_literal(), + "sequence_number": txn.sequence_number().to_string(), + "gas_unit_price": txn.gas_unit_price().to_string(), + "max_gas_amount": txn.max_gas_amount().to_string(), + "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), + "payload": payload, + }); + + if context.use_orderless_transactions { + let nonce = match txn.replay_protector() { + ReplayProtector::Nonce(n) => n, + _ => rand::thread_rng().r#gen(), + }; + json["replay_protection_nonce"] = json!(nonce.to_string()); + } + + json + }; let resp = context .post("/transactions/encode_submission", body.clone()) .await; @@ -781,50 +1031,148 @@ async fn test_signing_message_with_payload( assert_eq!(ledger["ledger_version"].as_str().unwrap(), "3"); // metadata + user txn + state checkpoint } -async fn test_account_transaction_with_context(mut context: TestContext) { - let account = context.gen_account(); - let txn = context.create_user_account(&account).await; - context.commit_block(&vec![txn]).await; +async fn match_transactions_with_expected_value( + context: &TestContext, + addr: AccountAddress, + initial_sequence_number: u64, + initial_ledger_version: u64, + expected_txns: Value, + expected_num_txns: usize, +) { + assert_eq!(expected_txns.as_array().unwrap().len(), expected_num_txns); + let txns = context + .get( + format!( + "/accounts/{}/transactions?start={}", + addr, initial_sequence_number, + ) + .as_str(), + ) + .await; - if let Some(indexer_reader) = context.context.indexer_reader.as_ref() { - indexer_reader.wait_for_internal_indexer(2).unwrap(); + if context.use_orderless_transactions { + assert_eq!(txns.as_array().unwrap().len(), 0); + } else { + assert_eq!( + txns.as_array().unwrap().len(), + expected_txns.as_array().unwrap().len() + ); } - - let txns = context + let txn_summaries = context .get( format!( - "/accounts/{}/transactions", - context.root_account().await.address() + "/accounts/{}/transaction_summaries?start_version={}", + addr, + initial_ledger_version + 2, ) .as_str(), ) .await; - assert_eq!(1, txns.as_array().unwrap().len()); - let expected_txns = context.get("/transactions?start=2&limit=1").await; - assert_json(txns, expected_txns); + assert_eq!( + txn_summaries.as_array().unwrap().len(), + expected_txns.as_array().unwrap().len() + ); + let mut txns_from_summaries = Vec::new(); + for txn_summary in txn_summaries.as_array().unwrap() { + let txn = context + .get( + format!( + "/transactions/by_hash/{}", + txn_summary["transaction_hash"].as_str().unwrap() + ) + .as_str(), + ) + .await; + txns_from_summaries.push(txn); + } + if context.use_orderless_transactions { + assert_eq!(json!(txns_from_summaries), expected_txns); + assert_json(json!(txns_from_summaries), expected_txns); + } else { + assert_eq!(txns, json!(txns_from_summaries)); + assert_eq!(txns, expected_txns); + assert_json(txns, expected_txns); + } +} + +async fn test_account_transaction_with_context(mut context: TestContext) { + let initial_sequence_number = context.root_account().await.sequence_number(); + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); + let account = context.gen_account(); + let txn = context.create_user_account(&account).await; + context.commit_block(&vec![txn]).await; + + if let Some(indexer_reader) = context.context.indexer_reader.as_ref() { + indexer_reader + .wait_for_internal_indexer(initial_ledger_version + 2) + .unwrap(); + } + let expected_txns = context + .get(&format!( + "/transactions?start={}&limit=1", + initial_ledger_version + 2 + )) + .await; + match_transactions_with_expected_value( + &context, + context.root_account().await.address(), + initial_sequence_number, + initial_ledger_version, + expected_txns, + 1, + ) + .await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_transactions() { - let context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_transactions( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); test_account_transaction_with_context(context).await; - let shard_context = - new_test_context_with_db_sharding_and_internal_indexer(current_function_name!()); - test_account_transaction_with_context(shard_context).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_transactions_filter_transactions_by_start_sequence_number() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + // Not testing for orderless transactions as orderless transactions don't have sequence number + // case(true, true) +)] +async fn test_get_account_transactions_filter_transactions_by_start_sequence_number( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let initial_sequence_number = context.root_account().await.sequence_number(); let account = context.gen_account(); let txn = context.create_user_account(&account).await; - context.commit_block(&vec![txn]).await; + context.commit_block(&vec![txn.clone()]).await; let txns = context .get( format!( - "/accounts/{}/transactions?start=1", - context.root_account().await.address() + "/accounts/{}/transactions?start={}", + context.root_account().await.address(), + initial_sequence_number + 1 ) .as_str(), ) @@ -833,8 +1181,22 @@ async fn test_get_account_transactions_filter_transactions_by_start_sequence_num } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_transactions_filter_transactions_by_start_sequence_number_is_too_large() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_transactions_filter_transactions_by_start_sequence_number_is_too_large( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); let txn = context.create_user_account(&account).await; context.commit_block(&vec![txn]).await; @@ -852,55 +1214,128 @@ async fn test_get_account_transactions_filter_transactions_by_start_sequence_num } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_account_transactions_filter_transactions_by_limit() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_account_transactions_filter_transactions_by_limit( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut root_account = context.root_account().await; + let initial_sequence_number = root_account.sequence_number(); + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let account1 = context.gen_account(); let txn1 = context.create_user_account_by(&mut root_account, &account1); let account2 = context.gen_account(); let txn2 = context.create_user_account_by(&mut root_account, &account2); context.commit_block(&vec![txn1, txn2]).await; - let txns = context - .get( - format!( - "/accounts/{}/transactions?start=0&limit=1", - context.root_account().await.address() + if !context.use_orderless_transactions { + let txns = context + .get( + format!( + "/accounts/{}/transactions?start={}&limit=1", + context.root_account().await.address(), + initial_sequence_number, + ) + .as_str(), ) - .as_str(), - ) - .await; - assert_eq!(txns.as_array().unwrap().len(), 1); - - let txns = context - .get( - format!( - "/accounts/{}/transactions?start=0&limit=2", - context.root_account().await.address() + .await; + assert_eq!(txns.as_array().unwrap().len(), 1); + + let txns = context + .get( + format!( + "/accounts/{}/transactions?start={}&limit=2", + context.root_account().await.address(), + initial_sequence_number, + ) + .as_str(), ) - .as_str(), - ) + .await; + assert_eq!(txns.as_array().unwrap().len(), 2); + } + + let expected_txns = context + .get(&format!( + "/transactions?start={}&limit=2", + initial_ledger_version + 2 + )) .await; - assert_eq!(txns.as_array().unwrap().len(), 2); + match_transactions_with_expected_value( + &context, + context.root_account().await.address(), + initial_sequence_number, + initial_ledger_version, + expected_txns, + 2, + ) + .await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_invalid_script_payload_bytecode() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_invalid_script_payload_bytecode( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let root_account = context.root_account().await; let invalid_bytecode = hex::decode("a11ceb0b030000").unwrap(); let txn = root_account.sign_with_transaction_builder( context .transaction_factory() .script(Script::new(invalid_bytecode, vec![], vec![])) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); test_transaction_vm_status(context, txn, false).await } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_invalid_entry_function_address() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_invalid_entry_function_address( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -918,8 +1353,24 @@ async fn test_get_txn_execute_failed_by_invalid_entry_function_address() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_invalid_entry_function_module_name() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_invalid_entry_function_module_name( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -937,8 +1388,24 @@ async fn test_get_txn_execute_failed_by_invalid_entry_function_module_name() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_invalid_entry_function_name() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_invalid_entry_function_name( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -956,8 +1423,24 @@ async fn test_get_txn_execute_failed_by_invalid_entry_function_name() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_invalid_entry_function_arguments() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_invalid_entry_function_arguments( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -975,8 +1458,24 @@ async fn test_get_txn_execute_failed_by_invalid_entry_function_arguments() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_missing_entry_function_arguments() { - let context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_missing_entry_function_arguments( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -994,12 +1493,27 @@ async fn test_get_txn_execute_failed_by_missing_entry_function_arguments() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_entry_function_validation() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_get_txn_execute_failed_by_entry_function_validation( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); - context - .commit_block(&vec![context.create_user_account(&account).await]) - .await; + let txn1 = context.create_user_account(&account).await; + context.commit_block(&vec![txn1]).await; test_get_txn_execute_failed_by_invalid_entry_function( context, @@ -1017,12 +1531,25 @@ async fn test_get_txn_execute_failed_by_entry_function_validation() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_entry_function_invalid_module_name() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_txn_execute_failed_by_entry_function_invalid_module_name( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); - context - .commit_block(&vec![context.create_user_account(&account).await]) - .await; + let txn1 = context.create_user_account(&account).await; + context.commit_block(&vec![txn1]).await; test_submit_entry_function_api_validation( context, @@ -1040,12 +1567,25 @@ async fn test_get_txn_execute_failed_by_entry_function_invalid_module_name() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_entry_function_invalid_function_name() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_txn_execute_failed_by_entry_function_invalid_function_name( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.gen_account(); - context - .commit_block(&vec![context.create_user_account(&account).await]) - .await; + let txn1 = context.create_user_account(&account).await; + context.commit_block(&vec![txn1]).await; test_submit_entry_function_api_validation( context, @@ -1063,8 +1603,22 @@ async fn test_get_txn_execute_failed_by_entry_function_invalid_function_name() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_get_txn_execute_failed_by_entry_function_execution_failure() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_get_txn_execute_failed_by_entry_function_execution_failure( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let mut admin = context.create_account().await; let named_addresses = vec![("entry_func_fail".to_string(), admin.address())]; @@ -1092,7 +1646,7 @@ async fn test_get_txn_execute_failed_by_entry_function_execution_failure() { #[ignore] // re-enable after cleaning compiled code #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_txn_execute_failed_by_script_execution_failure() { - let context = new_test_context(current_function_name!()); + let mut context = new_test_context(current_function_name!()); // script { // fun main() { @@ -1106,7 +1660,13 @@ async fn test_get_txn_execute_failed_by_script_execution_failure() { let txn = root_account.sign_with_transaction_builder( context .transaction_factory() - .script(Script::new(script, vec![], vec![])), + .script(Script::new(script, vec![], vec![])) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); test_transaction_vm_status(context, txn, false).await @@ -1144,7 +1704,12 @@ async fn test_submit_entry_function_api_validation( ty_args, args, )) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); let body = bcs::to_bytes(&txn).unwrap(); @@ -1157,7 +1722,7 @@ async fn test_submit_entry_function_api_validation( } async fn test_get_txn_execute_failed_by_invalid_entry_function( - context: TestContext, + mut context: TestContext, account: LocalAccount, address: &str, module_id: &str, @@ -1177,7 +1742,12 @@ async fn test_get_txn_execute_failed_by_invalid_entry_function( ty_args, args, )) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), ); test_transaction_vm_status(context, txn, false).await @@ -1246,8 +1816,22 @@ async fn test_submit_transaction_rejects_payload_too_large_json_body() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_submit_transaction_rejects_invalid_content_type() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_submit_transaction_rejects_invalid_content_type( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let req = warp::test::request() .header("content-type", "invalid") .method("POST") @@ -1259,8 +1843,22 @@ async fn test_submit_transaction_rejects_invalid_content_type() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_submit_transaction_rejects_invalid_json() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_submit_transaction_rejects_invalid_json( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let req = warp::test::request() .header("content-type", "application/json") .method("POST") @@ -1289,8 +1887,22 @@ async fn test_create_signing_message_rejects_payload_too_large_json_body() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_create_signing_message_rejects_invalid_content_type() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_create_signing_message_rejects_invalid_content_type( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let req = warp::test::request() .header("content-type", "invalid") .method("POST") @@ -1302,8 +1914,22 @@ async fn test_create_signing_message_rejects_invalid_content_type() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_create_signing_message_rejects_invalid_json() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_create_signing_message_rejects_invalid_json( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let req = warp::test::request() .header("content-type", "application/json") .method("POST") @@ -1315,8 +1941,22 @@ async fn test_create_signing_message_rejects_invalid_json() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_create_signing_message_rejects_no_content_length_request() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_create_signing_message_rejects_no_content_length_request( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let req = warp::test::request() .header("content-type", "application/json") .method("POST") @@ -1328,10 +1968,25 @@ async fn test_create_signing_message_rejects_no_content_length_request() { // Note: in tests, the min gas unit price is 0 #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_empty() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_empty( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = true; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let resp = context.get("/estimate_gas_price").await; assert!(context.last_updated_gas_schedule().is_some()); @@ -1351,10 +2006,25 @@ async fn fill_block( } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_ten_blocks() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_ten_blocks( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = true; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let ctx = &mut context; let creator = &mut ctx.gen_account(); @@ -1379,10 +2049,25 @@ async fn test_gas_estimation_ten_blocks() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_ten_empty_blocks() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_ten_empty_blocks( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = true; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let ctx = &mut context; // First block is ignored in gas estimate, so make 11 @@ -1400,7 +2085,17 @@ async fn test_gas_estimation_ten_empty_blocks() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_cache() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_cache( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = true; // Sets max cache size to 10 @@ -1410,7 +2105,12 @@ async fn test_gas_estimation_cache() { node_config.api.gas_estimation.aggressive_block_history = max_block_history; let sleep_duration = Duration::from_millis(node_config.api.gas_estimation.cache_expiration_ms * 2); - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let ctx = &mut context; // First block is ignored in gas estimate, so expect 4 entries @@ -1458,10 +2158,25 @@ async fn test_gas_estimation_cache() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_disabled() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_disabled( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = false; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let ctx = &mut context; let creator = &mut ctx.gen_account(); @@ -1486,7 +2201,17 @@ async fn test_gas_estimation_disabled() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_gas_estimation_static_override() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_gas_estimation_static_override( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); node_config.api.gas_estimation.enabled = true; node_config.api.gas_estimation.static_override = Some(GasEstimationStaticOverride { @@ -1494,7 +2219,12 @@ async fn test_gas_estimation_static_override() { market: 200, aggressive: 300, }); - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let ctx = &mut context; let creator = &mut ctx.gen_account(); @@ -1519,8 +2249,22 @@ async fn test_gas_estimation_static_override() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulation_failure_error_message() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulation_failure_error_message( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let admin0 = context.root_account().await; // script { @@ -1547,8 +2291,24 @@ async fn test_simulation_failure_error_message() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulation_failure_with_move_abort_error_rendering() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_simulation_failure_with_move_abort_error_rendering( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.create_account().await; let raw_txn = context .transaction_factory() @@ -1566,7 +2326,12 @@ async fn test_simulation_failure_with_move_abort_error_rendering() { )) .sender(account.address()) .sequence_number(account.sequence_number()) - .expiration_timestamp_secs(u64::MAX) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ) .build(); let invalid_key = AccountKey::generate(&mut context.rng()); @@ -1583,8 +2348,24 @@ async fn test_simulation_failure_with_move_abort_error_rendering() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulation_failure_with_detail_error() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + case("", false, false), + case("_payload_v2", true, false), + case("_orderless", true, true) +)] +async fn test_simulation_failure_with_detail_error( + case_name: &str, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!() + case_name, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; let raw_txn = context .transaction_factory() @@ -1602,7 +2383,12 @@ async fn test_simulation_failure_with_detail_error() { )) .sender(account.address()) .sequence_number(account.sequence_number()) - .expiration_timestamp_secs(u64::MAX) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ) .build(); let invalid_key = AccountKey::generate(&mut context.rng()); let txn = raw_txn @@ -1618,39 +2404,66 @@ async fn test_simulation_failure_with_detail_error() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_runtime_error_message_in_interpreter() { - let context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_runtime_error_message_in_interpreter( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; let named_addresses = vec![("addr".to_string(), account.address())]; let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_exceed_limit"); let payload = TestContext::build_package(path, named_addresses); - let txn = account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let txn = account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); let body = bcs::to_bytes(&txn).unwrap(); let resp = context .expect_status_code(202) .post_bcs_txn("/transactions", body) .await; + let mut payload = json!({ + "sender": resp["sender"], + "sequence_number": resp["sequence_number"], + "max_gas_amount": resp["max_gas_amount"], + "gas_unit_price": resp["gas_unit_price"], + "expiration_timestamp_secs": resp["expiration_timestamp_secs"], + "payload": resp["payload"], + "signature": { + "type": resp["signature"]["type"], + "public_key": resp["signature"]["public_key"], + "signature": Ed25519Signature::dummy_signature().to_string(), + } + }); + + if context.use_orderless_transactions { + let nonce = rand::thread_rng().r#gen::(); + payload["replay_protection_nonce"] = json!(nonce.to_string()); + } let resp = context .expect_status_code(200) - .post( - "/transactions/simulate", - json!({ - "sender": resp["sender"], - "sequence_number": resp["sequence_number"], - "max_gas_amount": resp["max_gas_amount"], - "gas_unit_price": resp["gas_unit_price"], - "expiration_timestamp_secs":resp["expiration_timestamp_secs"], - "payload": resp["payload"], - "signature": { - "type": resp["signature"]["type"], - "public_key": resp["signature"]["public_key"], - "signature": Ed25519Signature::dummy_signature().to_string(), - } - }), - ) + .post("/transactions/simulate", payload) .await; assert!(!resp[0]["success"].as_bool().unwrap()); @@ -1661,15 +2474,30 @@ async fn test_runtime_error_message_in_interpreter() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulation_filter_deny() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulation_filter_deny( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); // Blocklist the balance function. - let mut filter = node_config.api.simulation_filter.clone(); - filter = filter.add_all_filter(false); - node_config.api.simulation_filter = filter; + let transaction_filter = TransactionFilter::empty().add_all_filter(false); + let transaction_filter_config = TransactionFilterConfig::new(true, transaction_filter); + node_config.transaction_filters.api_filter = transaction_filter_config; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let admin0 = context.root_account().await; @@ -1686,16 +2514,32 @@ async fn test_simulation_filter_deny() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simulation_filter_allow_sender() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simulation_filter_allow_sender( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { let mut node_config = NodeConfig::default(); // Allow the root sender only. - let mut filter = node_config.api.simulation_filter.clone(); - filter = filter.add_sender_filter(true, aptos_test_root_address()); - filter = filter.add_all_filter(false); - node_config.api.simulation_filter = filter; + let transaction_filter = TransactionFilter::empty() + .add_sender_filter(true, aptos_test_root_address()) + .add_all_filter(false); + let transaction_filter_config = TransactionFilterConfig::new(true, transaction_filter); + node_config.transaction_filters.api_filter = transaction_filter_config; - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let admin0 = context.root_account().await; let other_account = context.create_account().await; @@ -1735,3 +2579,199 @@ fn gen_string(len: u64) -> String { fn build_path(path: &str) -> String { format!("/v1/transactions{}", path) } + +// Tests for the /transactions/auxiliary_info endpoint +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_with_valid_params() { + let mut context = new_test_context(current_function_name!()); + + // Create and commit transactions individually to ensure they're properly added to the ledger + let account1 = context.gen_account(); + let account2 = context.gen_account(); + let account3 = context.gen_account(); + + // Get root account and create transactions with proper sequence number management + let mut root_account = context.root_account().await; + + // Create all transactions with consecutive sequence numbers + let txn1 = context.create_user_account_by(&mut root_account, &account1); + let txn2 = context.create_user_account_by(&mut root_account, &account2); + let txn3 = context.create_user_account_by(&mut root_account, &account3); + + // Commit all transactions in a single block with auxiliary info + // This will create: [BlockMetadata(idx=0), UserTxn1(idx=1), UserTxn2(idx=2), UserTxn3(idx=3)] + context.try_commit_block(&vec![txn1, txn2, txn3]).await; + + // Based on debug output, we know we have versions 0-5 after the commit + // Test starting from version 1 (skip genesis) to version 4 + let (start_version, limit) = (1u64, 4u16); + + println!( + "Testing auxiliary info with start_version={}, limit={} (should get versions 1-4 with transaction_index 0-3)", + start_version, limit + ); + + let resp = context + .get(&format!( + "/transactions/auxiliary_info?start_version={}&limit={}", + start_version, limit + )) + .await; + + // Should return an array of auxiliary info objects + assert!(resp.is_array()); + let aux_info_array = resp.as_array().unwrap(); + assert_eq!(aux_info_array.len() as u16, limit); + + // Assert auxiliary info structure - should contain transaction indices + for (i, aux_info) in aux_info_array.iter().enumerate() { + let version = start_version + i as u64; + let expected_tx_index = i as u32; // Sequential indices: 0, 1, 2, 3 + + // Verify structure: object with transaction_index field that has the correct value + let obj = aux_info.as_object().unwrap(); + assert_eq!( + obj.len(), + 1, + "Version {} should have exactly 1 field", + version + ); + assert!( + obj.contains_key("transaction_index"), + "Version {} missing transaction_index", + version + ); + assert_eq!( + obj["transaction_index"].as_u64().unwrap(), + expected_tx_index as u64, + "Version {} should have transaction_index {}", + version, + expected_tx_index + ); + + // Verify exact JSON serialization + let serialized = serde_json::to_string(aux_info).unwrap(); + assert_eq!( + serialized, + format!("{{\"transaction_index\":{}}}", expected_tx_index), + "Version {} incorrect JSON format", + version + ); + } + + // Verify overall response format - all entries should have sequential transaction indices + let response_str = serde_json::to_string(&resp).unwrap(); + let expected_entries: Vec = (0..limit) + .map(|i| format!("{{\"transaction_index\":{}}}", i)) + .collect(); + let expected_response = format!("[{}]", expected_entries.join(",")); + assert_eq!( + response_str, expected_response, + "Response should be array of sequential transaction indices" + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_invalid_start_version() { + let mut context = new_test_context(current_function_name!()); + + // Test with invalid start_version parameter - should return 400 + let resp = context + .expect_status_code(400) + .get("/transactions/auxiliary_info?start_version=invalid&limit=5") + .await; + + context.check_golden_output(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_invalid_limit() { + let mut context = new_test_context(current_function_name!()); + + // Test with invalid limit parameter - should return 400 + let resp = context + .expect_status_code(400) + .get("/transactions/auxiliary_info?start_version=0&limit=invalid") + .await; + + context.check_golden_output(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_start_version_too_large() { + let mut context = new_test_context(current_function_name!()); + + // Test with start_version beyond ledger version - should return 400 + let resp = context + .expect_status_code(400) + .get("/transactions/auxiliary_info?start_version=1000000&limit=5") + .await; + + context.check_golden_output(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_pagination() { + let mut context = new_test_context(current_function_name!()); + + // Create several transactions to test pagination using root account to avoid sequence issues + let mut root_account = context.root_account().await; + let mut transactions = vec![]; + + for _i in 0..5 { + let account = context.gen_account(); + let txn = context.create_user_account_by(&mut root_account, &account); + transactions.push(txn); + } + + // Commit all transactions in one block to ensure they exist + context.commit_block(&transactions).await; + + // Test first page + let resp1 = context + .get("/transactions/auxiliary_info?start_version=0&limit=3") + .await; + assert!(resp1.is_array()); + let page1 = resp1.as_array().unwrap(); + assert_eq!(page1.len(), 3); + + // Test second page + let resp2 = context + .get("/transactions/auxiliary_info?start_version=3&limit=3") + .await; + assert!(resp2.is_array()); + let page2 = resp2.as_array().unwrap(); + assert!(!page2.is_empty()); // Should have at least some transactions + + // Since all auxiliary info is currently {"transaction_index":null}, pages will have same structure + // but different starting versions - validate the pagination worked by checking both pages are valid + for aux_info in page1.iter().chain(page2.iter()) { + assert!(aux_info.is_object()); + let obj = aux_info.as_object().unwrap(); + assert!(obj.contains_key("transaction_index")); + assert_eq!(obj.len(), 1); + } + + println!("✅ Page 1: {} entries", page1.len()); + println!("✅ Page 2: {} entries", page2.len()); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_transactions_auxiliary_info_empty_range() { + let mut context = new_test_context(current_function_name!()); + + // Get current ledger info to find a valid empty range + let ledger_info = context.get_latest_ledger_info(); + let ledger_version = u64::from(ledger_info.ledger_version); + + // Request range beyond current ledger version + let resp = context + .expect_status_code(400) + .get(&format!( + "/transactions/auxiliary_info?start_version={}&limit=5", + ledger_version + 100 + )) + .await; + + context.check_golden_output(resp); +} diff --git a/api/src/tests/view_function.rs b/api/src/tests/view_function.rs index 26373850200..573786f3591 100644 --- a/api/src/tests/view_function.rs +++ b/api/src/tests/view_function.rs @@ -1,11 +1,14 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use super::{new_test_context, new_test_context_with_config}; +use super::{ + new_test_context, new_test_context_with_config, new_test_context_with_orderless_flags, +}; use aptos_api_test_context::{current_function_name, TestContext}; use aptos_cached_packages::aptos_stdlib; use aptos_config::config::{NodeConfig, ViewFilter, ViewFunctionId}; use aptos_types::account_address::AccountAddress; +use rstest::rstest; use serde_json::{json, Value}; use std::{path::PathBuf, str::FromStr}; @@ -27,8 +30,19 @@ fn build_coin_decimals_request() -> Value { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simple_view() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simple_view(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); let txn1 = context.mint_user_account(creator).await; @@ -44,14 +58,29 @@ async fn test_simple_view() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_view_gas_used_header() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_gas_used_header( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); let txn1 = context.mint_user_account(creator).await; let txn2 = context.account_transfer(creator, owner, 100_000); context.commit_block(&vec![txn1, txn2]).await; + context.wait_for_internal_indexer_caught_up().await; let req = warp::test::request() .method("POST") @@ -75,7 +104,14 @@ async fn test_view_gas_used_header() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_view_allowlist() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_allowlist(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { let mut node_config = NodeConfig::default(); // Allowlist only the balance function. @@ -85,7 +121,12 @@ async fn test_view_allowlist() { function_name: "balance".to_string(), }]); - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); @@ -110,7 +151,14 @@ async fn test_view_allowlist() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_view_blocklist() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_blocklist(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { let mut node_config = NodeConfig::default(); // Blocklist the balance function. @@ -120,7 +168,12 @@ async fn test_view_blocklist() { function_name: "balance".to_string(), }]); - let mut context = new_test_context_with_config(current_function_name!(), node_config); + let mut context = new_test_context_with_config( + current_function_name!(), + node_config, + use_txn_payload_v2_format, + use_orderless_transactions, + ); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); @@ -145,7 +198,83 @@ async fn test_view_blocklist() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_simple_view_invalid() { +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_error_move_abort( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let creator = &mut context.gen_account(); + let owner = &mut context.gen_account(); + let txn1 = context.mint_user_account(creator).await; + let txn2 = context.account_transfer(creator, owner, 100_000); + + context.commit_block(&vec![txn1, txn2]).await; + + let resp = context + .expect_status_code(400) + .post( + "/view", + json!({ + "function":"0x1::account::get_rotation_capability_offer_for", // Rotation capability does not exist + "arguments": vec![owner.address().to_string()], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_error_type_resolution_error( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let creator = &mut context.gen_account(); + let owner = &mut context.gen_account(); + let txn1 = context.mint_user_account(creator).await; + let txn2 = context.account_transfer(creator, owner, 100_000); + + context.commit_block(&vec![txn1, txn2]).await; + + let resp = context + .expect_status_code(400) + .post( + "/view", + json!({ + "function":"0x1::coin::is_account_registered", + "arguments": vec![AccountAddress::random().to_string()], + "type_arguments": ["0x1::aptos_coin::NewCoin"], // Does not exist + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_view_does_not_exist() { let mut context = new_test_context(current_function_name!()); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); @@ -154,6 +283,45 @@ async fn test_simple_view_invalid() { context.commit_block(&vec![txn1, txn2]).await; + let resp = context + .expect_status_code(400) + .post( + "/view", + json!({ + "function":"0x1::aptos_account::fake_function", + "arguments": vec![owner.address().to_string()], + "type_arguments": [], + }), + ) + .await; + + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_simple_view_invalid( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let creator = &mut context.gen_account(); + let owner = &mut context.gen_account(); + let txn1 = context.mint_user_account(creator).await; + let txn2 = context.account_transfer(creator, owner, 100_000); + + context.commit_block(&vec![txn1, txn2]).await; + let resp = context .expect_status_code(400) .post( @@ -170,10 +338,25 @@ async fn test_simple_view_invalid() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_versioned_simple_view() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_versioned_simple_view( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let creator = &mut context.gen_account(); let owner = &mut context.gen_account(); + let initial_ledger_version = u64::from(context.get_latest_ledger_info().ledger_version); let txn1 = context.mint_user_account(creator).await; let txn2 = context.account_transfer(creator, owner, 100_000); let txn3 = context.account_transfer(creator, owner, 100_000); @@ -182,7 +365,7 @@ async fn test_versioned_simple_view() { let resp = context .post( - "/view?ledger_version=3", + &format!("/view?ledger_version={}", initial_ledger_version + 3), json!({ "function":"0x1::coin::balance", "arguments": vec![owner.address().to_string()], @@ -195,8 +378,19 @@ async fn test_versioned_simple_view() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_view_tuple() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_tuple(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let payload = aptos_stdlib::publish_module_source( "test_module", r#" @@ -210,8 +404,17 @@ async fn test_view_tuple() { ); let root_account = context.root_account().await; - let module_txn = - root_account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let module_txn = root_account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); context.commit_block(&vec![module_txn]).await; @@ -229,14 +432,35 @@ async fn test_view_tuple() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_view_aggregator() { - let mut context = new_test_context(current_function_name!()); +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_aggregator(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let account = context.root_account().await; let named_addresses = vec![("addr".to_string(), account.address())]; let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_counter"); let payload = TestContext::build_package(path, named_addresses); - let txn = account.sign_with_transaction_builder(context.transaction_factory().payload(payload)); + let txn = account.sign_with_transaction_builder( + context + .transaction_factory() + .payload(payload) + .expiration_timestamp_secs(context.get_expiration_time()) + .upgrade_payload_with_rng( + &mut context.rng, + context.use_txn_payload_v2_format, + context.use_orderless_transactions, + ), + ); context.commit_block(&vec![txn]).await; let function = format!("{}::counter::add_and_get_counter_value", account.address()); @@ -252,3 +476,177 @@ async fn test_view_aggregator() { .await; context.check_golden_output_no_prune(resp); } + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_option(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/test_option"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + let function = format!("{}::test_module::return_none", account.address()); + let resp = context + .post( + "/view", + json!({ + "function": function, + "arguments": [], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + enable_framework_for_option, + case(false, false, false), + case(false, false, true), + case(true, false, false), + case(true, true, false) +)] +async fn test_view_option_some( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, + enable_framework_for_option: bool, +) { + const FEATURE_FLAG_ENABLE_FRAMEWORK_FOR_OPTION: u64 = 103; + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + if enable_framework_for_option { + context + .enable_feature(FEATURE_FLAG_ENABLE_FRAMEWORK_FOR_OPTION) + .await; + } else { + context + .disable_feature(FEATURE_FLAG_ENABLE_FRAMEWORK_FOR_OPTION) + .await; + } + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/test_option"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + let function = format!("{}::test_module::return_some", account.address()); + let resp = context + .post( + "/view", + json!({ + "function": function, + "arguments": [], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_option_vec(use_txn_payload_v2_format: bool, use_orderless_transactions: bool) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/test_option"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + let function = format!( + "{}::test_module::return_vector_of_option", + account.address() + ); + let resp = context + .post( + "/view", + json!({ + "function": function, + "arguments": [], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) +)] +async fn test_view_option_struct( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, +) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); + let mut account = context.create_account().await; + let account_addr = account.address(); + + // Publish packages + let named_addresses = vec![("account".to_string(), account_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/test_option"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + let function = format!("{}::test_module::return_option_test", account.address()); + let resp = context + .post( + "/view", + json!({ + "function": function, + "arguments": [], + "type_arguments": [], + }), + ) + .await; + context.check_golden_output_no_prune(resp); +} diff --git a/api/src/tests/webauthn_secp256r1_ecdsa.rs b/api/src/tests/webauthn_secp256r1_ecdsa.rs index 31a544b8f43..48a0ca07502 100644 --- a/api/src/tests/webauthn_secp256r1_ecdsa.rs +++ b/api/src/tests/webauthn_secp256r1_ecdsa.rs @@ -2,11 +2,9 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::new_test_context; - #[cfg(test)] mod tests { - use super::new_test_context; + use crate::tests::new_test_context_with_orderless_flags; use aptos_api_test_context::current_function_name; use aptos_crypto::{ ed25519::Ed25519PrivateKey, @@ -30,6 +28,7 @@ mod tests { Bytes, }; use rand::{prelude::StdRng, SeedableRng}; + use rstest::rstest; /// Sample `AuthenticatorData` static AUTHENTICATOR_DATA: &[u8] = &[ @@ -85,8 +84,22 @@ mod tests { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_webauthn_secp256r1_ecdsa() { - let mut context = new_test_context(current_function_name!()); + #[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) + )] + async fn test_webauthn_secp256r1_ecdsa( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, + ) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let other = context.create_account().await; let mut rng: StdRng = SeedableRng::from_seed([0; 32]); @@ -136,8 +149,22 @@ mod tests { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_webauthn_secp256r1_ecdsa_failure() { - let mut context = new_test_context(current_function_name!()); + #[rstest( + use_txn_payload_v2_format, + use_orderless_transactions, + case(false, false), + case(true, false), + case(true, true) + )] + async fn test_webauthn_secp256r1_ecdsa_failure( + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, + ) { + let mut context = new_test_context_with_orderless_flags( + current_function_name!(), + use_txn_payload_v2_format, + use_orderless_transactions, + ); let other = context.create_account().await; let mut rng: StdRng = SeedableRng::from_seed([0; 32]); diff --git a/api/src/transactions.rs b/api/src/transactions.rs index f435cd51415..78547389760 100644 --- a/api/src/transactions.rs +++ b/api/src/transactions.rs @@ -17,16 +17,17 @@ use crate::{ BasicErrorWith404, BasicResponse, BasicResponseStatus, BasicResult, BasicResultWith404, ForbiddenError, InsufficientStorageError, InternalError, }, + view_function::convert_view_function_error, ApiTags, }; use anyhow::Context as AnyhowContext; use aptos_api_types::{ - transaction::TransactionSummary, verify_function_identifier, verify_module_identifier, Address, - AptosError, AptosErrorCode, AsConverter, EncodeSubmissionRequest, GasEstimation, - GasEstimationBcs, HashValue, HexEncodedBytes, LedgerInfo, MoveType, PendingTransaction, - SubmitTransactionRequest, Transaction, TransactionData, TransactionOnChainData, - TransactionsBatchSingleSubmissionFailure, TransactionsBatchSubmissionResult, UserTransaction, - VerifyInput, VerifyInputWithRecursion, U64, + transaction::{PersistedAuxiliaryInfo, TransactionSummary}, + verify_function_identifier, verify_module_identifier, Address, AptosError, AptosErrorCode, + AsConverter, EncodeSubmissionRequest, GasEstimation, GasEstimationBcs, HashValue, + HexEncodedBytes, LedgerInfo, MoveType, PendingTransaction, SubmitTransactionRequest, + Transaction, TransactionData, TransactionOnChainData, TransactionsBatchSingleSubmissionFailure, + TransactionsBatchSubmissionResult, UserTransaction, VerifyInput, VerifyInputWithRecursion, U64, }; use aptos_crypto::{hash::CryptoHash, signing_message}; use aptos_logger::error; @@ -306,6 +307,42 @@ impl TransactionsApi { .await } + /// Get transactions auxiliary info + /// + /// Retrieves persisted auxiliary information (such as transaction indices within blocks) for + /// transactions in a given version range. + /// + /// If the version range has been pruned, a 410 will be returned. + #[oai( + path = "/transactions/auxiliary_info", + method = "get", + operation_id = "get_transactions_auxiliary_info", + tag = "ApiTags::Transactions" + )] + async fn get_transactions_auxiliary_info( + &self, + accept_type: AcceptType, + /// Starting ledger version to retrieve auxiliary info for + start_version: Query, + /// Max number of transactions to retrieve auxiliary info for. + /// + /// If not provided, defaults to default page size + limit: Query>, + ) -> BasicResultWith404> { + fail_point_poem("endpoint_get_transactions_auxiliary_info")?; + self.context + .check_api_output_enabled("Get transactions auxiliary info", &accept_type)?; + + let page = Page::new( + Some(start_version.0 .0), + limit.0, + self.context.max_transactions_page_size(), + ); + + let api = self.clone(); + api_spawn_blocking(move || api.list_auxiliary_infos(&accept_type, page)).await + } + /// Get account transactions /// /// Retrieves on-chain committed sequence-number based transactions from an account. @@ -580,15 +617,13 @@ impl TransactionsApi { let ledger_info = context.get_latest_ledger_info()?; let mut signed_transaction = api.get_signed_transaction(&ledger_info, data)?; - // Confirm the simulation filter allows the transaction. We use HashValue::zero() - // here for the block ID because we don't allow filtering by block ID for the - // simulation filters. See the ConfigSanitizer for ApiConfig. - if !context.node_config.api.simulation_filter.allows( - aptos_crypto::HashValue::zero(), - ledger_info.epoch(), - ledger_info.timestamp(), - &signed_transaction, - ) { + // Confirm the API simulation filter allows the transaction + let api_filter = &context.node_config.transaction_filters.api_filter; + if api_filter.is_enabled() + && !api_filter + .transaction_filter() + .allows_transaction(&signed_transaction) + { return Err(SubmitTransactionError::forbidden_with_code( "Transaction not allowed by simulation filter", AptosErrorCode::InvalidInput, @@ -641,10 +676,14 @@ impl TransactionsApi { vec![signed_transaction.sender().to_vec()], context.node_config.api.max_gas_view_function, ); - let values = output.values.map_err(|err| { - SubmitTransactionError::bad_request_with_code_no_info( - err, + let values = output.values.map_err(|status| { + let (err_string, vm_error_code) = + convert_view_function_error(&status, &state_view, &context); + SubmitTransactionError::bad_request_with_optional_vm_status_and_ledger_info( + anyhow::anyhow!(err_string), AptosErrorCode::InvalidInput, + vm_error_code, + Some(&ledger_info), ) })?; let balance: u64 = bcs::from_bytes(&values[0]).map_err(|err| { @@ -1255,6 +1294,13 @@ impl TransactionsApi { } }, }, + TransactionPayload::EncryptedPayload(_) => { + return Err(SubmitTransactionError::bad_request_with_code( + "Encrypted Transaction is not supported yet", + AptosErrorCode::InvalidInput, + ledger_info, + )); + }, } // TODO: Verify script args? @@ -1405,6 +1451,10 @@ impl TransactionsApi { format!("Transaction was rejected with status {}", mempool_status,), AptosErrorCode::InternalError, )), + MempoolStatusCode::RejectedByFilter => Err(AptosError::new_with_error_code( + mempool_status.message, + AptosErrorCode::RejectedByFilter, + )), } } @@ -1537,6 +1587,18 @@ impl TransactionsApi { )); } + if txn + .raw_transaction_ref() + .payload_ref() + .is_encrypted_variant() + { + return Err(SubmitTransactionError::bad_request_with_code( + "Encrypted transactions cannot be simulated", + AptosErrorCode::InvalidInput, + &ledger_info, + )); + } + // Simulate transaction let state_view = self.context.latest_state_view_poem(&ledger_info)?; let (vm_status, output) = @@ -1596,6 +1658,9 @@ impl TransactionsApi { }; stats_key }, + TransactionPayload::EncryptedPayload(_) => { + unreachable!("Encrypted transactions must not be simulated") + }, }; self.context .simulate_txn_stats() @@ -1612,6 +1677,7 @@ impl TransactionsApi { None, output.gas_used(), exe_status, + None, ); let mut events = output.events().to_vec(); let _ = self @@ -1733,6 +1799,69 @@ impl TransactionsApi { BasicResponseStatus::Ok, )) } + + fn list_auxiliary_infos( + &self, + accept_type: &AcceptType, + page: Page, + ) -> BasicResultWith404> { + let latest_ledger_info = self.context.get_latest_ledger_info()?; + let ledger_version = latest_ledger_info.ledger_version; + + let limit = page.limit(&latest_ledger_info)?; + let start_version = page.compute_start(limit, ledger_version.0, &latest_ledger_info)?; + + // Use iterator for more efficient batch retrieval + let iterator = self + .context + .db + .get_persisted_auxiliary_info_iterator(start_version, limit as usize) + .context("Failed to get auxiliary info iterator from storage") + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &latest_ledger_info, + ) + })?; + + let mut raw_auxiliary_infos = Vec::new(); + for result in iterator { + let raw_aux_info = result + .context("Failed to read auxiliary info from iterator") + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &latest_ledger_info, + ) + })?; + raw_auxiliary_infos.push(raw_aux_info); + } + + match accept_type { + AcceptType::Json => { + // Transform to API types for JSON (user-friendly, extensible) + let api_auxiliary_infos: Vec = raw_auxiliary_infos + .into_iter() + .map(PersistedAuxiliaryInfo::from) + .collect(); + BasicResponse::try_from_json(( + api_auxiliary_infos, + &latest_ledger_info, + BasicResponseStatus::Ok, + )) + }, + AcceptType::Bcs => { + // Use raw core types for BCS (backward compatible, versioned enum) + BasicResponse::try_from_bcs(( + raw_auxiliary_infos, + &latest_ledger_info, + BasicResponseStatus::Ok, + )) + }, + } + } } fn override_gas_parameters( diff --git a/api/src/view_function.rs b/api/src/view_function.rs index cc640c5ff1f..6e2ef0969c1 100644 --- a/api/src/view_function.rs +++ b/api/src/view_function.rs @@ -18,6 +18,7 @@ use aptos_api_types::{ U64, }; use aptos_bcs_utils::serialize_uleb128; +use aptos_types::{state_store::StateView, transaction::ViewFunctionError, vm_status::StatusCode}; use aptos_vm::AptosVM; use itertools::Itertools; use move_core_types::language_storage::TypeTag; @@ -30,6 +31,24 @@ pub struct ViewFunctionApi { pub context: Arc, } +pub fn convert_view_function_error( + error: &ViewFunctionError, + state_view: &impl StateView, + context: &Context, +) -> (String, Option) { + match error { + ViewFunctionError::MoveAbort(status, vm_error_code) => { + let vm_status = state_view + .as_converter(context.db.clone(), context.indexer_reader.clone()) + .explain_vm_status(status, None); + (vm_status, *vm_error_code) + }, + ViewFunctionError::ErrorMessage(message, vm_error_code) => { + (message.clone(), *vm_error_code) + }, + } +} + #[derive(ApiRequest, Debug)] pub enum ViewFunctionRequest { #[oai(content_type = "application/json")] @@ -140,8 +159,16 @@ fn view_request( view_function.args.clone(), context.node_config.api.max_gas_view_function, ); - let values = output.values.map_err(|err| { - BasicErrorWith404::bad_request_with_code_no_info(err, AptosErrorCode::InvalidInput) + + let values = output.values.map_err(|status| { + let (err_string, vm_error_code) = + convert_view_function_error(&status, &state_view, &context); + BasicErrorWith404::bad_request_with_optional_vm_status_and_ledger_info( + anyhow::anyhow!(err_string), + AptosErrorCode::InvalidInput, + vm_error_code, + Some(&ledger_info), + ) })?; let result = match accept_type { AcceptType::Bcs => { diff --git a/api/test-context/src/test_context.rs b/api/test-context/src/test_context.rs index be9c7c11d35..4486c7e0272 100644 --- a/api/test-context/src/test_context.rs +++ b/api/test-context/src/test_context.rs @@ -38,7 +38,7 @@ use aptos_temppath::TempPath; use aptos_types::{ account_address::{create_multisig_account_address, AccountAddress}, aggregate_signature::AggregateSignature, - block_executor::config::BlockExecutorConfigFromOnchain, + block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, block_info::BlockInfo, block_metadata::BlockMetadata, chain_id::ChainId, @@ -46,15 +46,15 @@ use aptos_types::{ indexer::indexer_db_reader::IndexerReader, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, transaction::{ - signature_verified_transaction::into_signature_verified_block, Transaction, - TransactionPayload, TransactionStatus, Version, + signature_verified_transaction::into_signature_verified_block, AuxiliaryInfo, + AuxiliaryInfoTrait, Transaction, TransactionPayload, TransactionStatus, Version, }, }; use aptos_vm::aptos_vm::AptosVMBlockExecutor; use aptos_vm_validator::vm_validator::PooledVMValidator; use bytes::Bytes; use hyper::{HeaderMap, Response}; -use rand::SeedableRng; +use rand::{Rng, SeedableRng}; use serde_json::{json, Value}; use std::{ boxed::Box, @@ -109,7 +109,14 @@ pub fn new_test_context( node_config: NodeConfig, use_db_with_indexer: bool, ) -> TestContext { - new_test_context_inner(test_name, node_config, use_db_with_indexer, None) + new_test_context_inner( + test_name, + node_config, + use_db_with_indexer, + None, + false, + false, + ) } pub fn new_test_context_inner( @@ -117,6 +124,8 @@ pub fn new_test_context_inner( mut node_config: NodeConfig, use_db_with_indexer: bool, end_version: Option, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> TestContext { // Speculative logging uses a global variable and when many instances use it together, they // panic, so we disable this to run tests. @@ -222,6 +231,8 @@ pub fn new_test_context_inner( db, test_name, api_specific_config, + use_txn_payload_v2_format, + use_orderless_transactions, ) } @@ -231,7 +242,7 @@ pub struct TestContext { pub validator_owner: AccountAddress, pub mempool: Arc, pub db: Arc, - rng: rand::rngs::StdRng, + pub rng: rand::rngs::StdRng, root_key: ConfigKey, executor: Arc, expect_status_code: u16, @@ -239,6 +250,8 @@ pub struct TestContext { golden_output: Option, fake_time_usecs: u64, pub api_specific_config: ApiSpecificConfig, + pub use_txn_payload_v2_format: bool, + pub use_orderless_transactions: bool, } impl TestContext { @@ -252,6 +265,8 @@ impl TestContext { db: Arc, test_name: String, api_specific_config: ApiSpecificConfig, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> Self { Self { context, @@ -266,6 +281,8 @@ impl TestContext { golden_output: None, fake_time_usecs: 0, api_specific_config, + use_txn_payload_v2_format, + use_orderless_transactions, } } @@ -289,7 +306,6 @@ impl TestContext { let msg = pretty(&Self::prune_golden(msg)); let re = regex::Regex::new("hash\": \".*\"").unwrap(); let msg = re.replace_all(&msg, "hash\": \"\""); - self.golden_output.as_ref().unwrap().log(&msg); } @@ -447,7 +463,12 @@ impl TestContext { let txn = root.sign_with_transaction_builder( factory .account_transfer(account.address(), TRANSFER_AMOUNT) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); let bcs_txn = bcs::to_bytes(&txn).unwrap(); @@ -498,23 +519,28 @@ impl TestContext { } } - pub async fn create_user_account(&self, account: &LocalAccount) -> SignedTransaction { + pub async fn create_user_account(&mut self, account: &LocalAccount) -> SignedTransaction { let mut tc = self.root_account().await; self.create_user_account_by(&mut tc, account) } - pub async fn mint_user_account(&self, account: &LocalAccount) -> SignedTransaction { + pub async fn mint_user_account(&mut self, account: &LocalAccount) -> SignedTransaction { let tc = self.root_account().await; let factory = self.transaction_factory(); tc.sign_with_transaction_builder( factory .account_transfer(account.address(), TRANSFER_AMOUNT) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ) } pub async fn add_dispatchable_authentication_function( - &self, + &mut self, account: &LocalAccount, func: FunctionInfo, ) -> SignedTransaction { @@ -522,7 +548,12 @@ impl TestContext { account.sign_with_transaction_builder( factory .add_dispatchable_authentication_function(func) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ) } @@ -586,13 +617,15 @@ impl TestContext { let create_multisig_txn = account.sign_with_transaction_builder( factory .create_multisig_account(additional_owners, signatures_required) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); - self.commit_block(&vec![ - create_multisig_txn, - self.account_transfer_to(account, multisig_address, initial_balance), - ]) - .await; + let txn2 = self.account_transfer_to(account, multisig_address, initial_balance); + self.commit_block(&vec![create_multisig_txn, txn2]).await; multisig_address } @@ -604,16 +637,19 @@ impl TestContext { initial_balance: u64, ) { let factory = self.transaction_factory(); - let txn = account.sign_with_transaction_builder( + let txn1 = account.sign_with_transaction_builder( factory .create_multisig_account_with_existing_account(owners, signatures_required) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); - self.commit_block(&vec![ - txn, - self.account_transfer_to(account, account.address(), initial_balance), - ]) - .await; + let txn2 = self.account_transfer_to(account, account.address(), initial_balance); + + self.commit_block(&vec![txn1, txn2]).await; } pub async fn create_multisig_transaction( @@ -626,7 +662,12 @@ impl TestContext { let txn = owner.sign_with_transaction_builder( factory .create_multisig_transaction(multisig_account, payload) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); self.commit_block(&vec![txn]).await; } @@ -641,7 +682,12 @@ impl TestContext { let txn = owner.sign_with_transaction_builder( factory .approve_multisig_transaction(multisig_account, transaction_id) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); self.commit_block(&vec![txn]).await; } @@ -656,7 +702,12 @@ impl TestContext { let txn = owner.sign_with_transaction_builder( factory .reject_multisig_transaction(multisig_account, transaction_id) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); self.commit_block(&vec![txn]).await; } @@ -671,13 +722,18 @@ impl TestContext { let txn = owner.sign_with_transaction_builder( factory .create_multisig_transaction_with_payload_hash(multisig_account, payload) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ); self.commit_block(&vec![txn]).await; } pub fn account_transfer( - &self, + &mut self, sender: &mut LocalAccount, receiver: &LocalAccount, amount: u64, @@ -686,7 +742,7 @@ impl TestContext { } pub fn account_transfer_to( - &self, + &mut self, sender: &mut LocalAccount, receiver: AccountAddress, amount: u64, @@ -695,12 +751,18 @@ impl TestContext { sender.sign_with_transaction_builder( factory .account_transfer(receiver, amount) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .sequence_number(sender.sequence_number()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ) } pub fn create_user_account_by( - &self, + &mut self, creator: &mut LocalAccount, account: &LocalAccount, ) -> SignedTransaction { @@ -708,7 +770,13 @@ impl TestContext { creator.sign_with_transaction_builder( factory .create_user_account(account.public_key()) - .expiration_timestamp_secs(u64::MAX), + .expiration_timestamp_secs(self.get_expiration_time()) + .sequence_number(creator.sequence_number()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), ) } @@ -719,6 +787,12 @@ impl TestContext { .transfer(root_account.address(), 1) .sender(root_account.address()) .sequence_number(root_account.sequence_number()) + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ) .build(); let invalid_key = AccountKey::generate(self.rng()); txn.sign(invalid_key.private_key(), root_account.public_key().clone()) @@ -790,8 +864,16 @@ impl TestContext { publisher: &mut LocalAccount, payload: TransactionPayload, ) -> SignedTransaction { - let txn = - publisher.sign_with_transaction_builder(self.transaction_factory().payload(payload)); + let txn = publisher.sign_with_transaction_builder( + self.transaction_factory() + .payload(payload) + .expiration_timestamp_secs(self.get_expiration_time()) + .upgrade_payload_with_rng( + &mut self.rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, + ), + ); let bcs_txn = bcs::to_bytes(&txn).unwrap(); self.expect_status_code(202) .post_bcs_txn("/transactions", bcs_txn) @@ -825,10 +907,20 @@ impl TestContext { // Check that txn execution was successful. let parent_id = self.executor.committed_block_id(); + + // Create proper auxiliary info with transaction indices + let sig_verified_txns = into_signature_verified_block(txns.clone()); + let auxiliary_info: Vec = (0..sig_verified_txns.len()) + .map(|i| AuxiliaryInfo::auxiliary_info_at_txn_index(i as u32)) + .collect(); + + let executable_block = + ExecutableBlock::new(metadata.id(), sig_verified_txns.into(), auxiliary_info); + let result = self .executor .execute_block( - (metadata.id(), into_signature_verified_block(txns.clone())).into(), + executable_block, parent_id, BlockExecutorConfigFromOnchain::on_but_large_for_test(), ) @@ -1036,14 +1128,28 @@ impl TestContext { payload: Value, status_code: u16, ) { - let mut request = json!({ - "sender": account.address(), - "sequence_number": account.sequence_number().to_string(), - "gas_unit_price": "100", - "max_gas_amount": "1000000", - "expiration_timestamp_secs": "16373698888888", - "payload": payload, - }); + let mut request = if self.use_orderless_transactions { + let mut rng = rand::thread_rng(); + let replay_protection_nonce: u64 = rng.r#gen(); + json!({ + "sender": account.address(), + "sequence_number": (u64::MAX).to_string(), + "gas_unit_price": "100", + "max_gas_amount": "1000000", + "expiration_timestamp_secs": self.get_expiration_time().to_string(), + "payload": payload, + "replay_protection_nonce": replay_protection_nonce.to_string(), + }) + } else { + json!({ + "sender": account.address(), + "sequence_number": account.sequence_number().to_string(), + "gas_unit_price": "100", + "max_gas_amount": "1000000", + "expiration_timestamp_secs": "16373698888888", + "payload": payload, + }) + }; let resp = self .post( @@ -1070,7 +1176,9 @@ impl TestContext { .post("/transactions", request) .await; self.commit_mempool_txns(1).await; - account.increment_sequence_number(); + if !self.use_orderless_transactions { + account.increment_sequence_number(); + } } pub async fn simulate_multisig_transaction( @@ -1105,14 +1213,28 @@ impl TestContext { payload: Value, status_code: u16, ) -> Value { - let mut request = json!({ - "sender": sender.address(), - "sequence_number": sender.sequence_number().to_string(), - "gas_unit_price": "0", - "max_gas_amount": "1000000", - "expiration_timestamp_secs": "16373698888888", - "payload": payload, - }); + let mut request = if self.use_orderless_transactions { + let mut rng = rand::thread_rng(); + let replay_protection_nonce: u64 = rng.r#gen(); + json!({ + "sender": sender.address(), + "sequence_number": (u64::MAX).to_string(), + "gas_unit_price": "0", + "max_gas_amount": "1000000", + "expiration_timestamp_secs": self.get_expiration_time().to_string(), + "payload": payload, + "replay_protection_nonce": replay_protection_nonce.to_string(), + }) + } else { + json!({ + "sender": sender.address(), + "sequence_number": sender.sequence_number().to_string(), + "gas_unit_price": "0", + "max_gas_amount": "1000000", + "expiration_timestamp_secs": "16373698888888", + "payload": payload, + }) + }; // We're intentionally using invalid signatures since simulation API rejects valid ones. let random_account = self.gen_account(); @@ -1186,7 +1308,7 @@ impl TestContext { pub fn get_routes_with_poem( &self, poem_address: SocketAddr, - ) -> impl Filter + Clone { + ) -> impl Filter,), Error = Rejection> + Clone + use<> { warp::path!("v1" / ..).and(reverse_proxy_filter( "v1".to_string(), format!("http://{}/v1", poem_address), @@ -1194,6 +1316,7 @@ impl TestContext { } pub async fn execute(&self, req: warp::test::RequestBuilder) -> Value { + self.wait_for_internal_indexer_caught_up().await; let resp = self.reply(req).await; let headers = resp.headers(); @@ -1266,4 +1389,8 @@ impl TestContext { ); LedgerInfoWithSignatures::new(info, AggregateSignature::empty()) } + + pub fn get_expiration_time(&self) -> u64 { + Duration::from_micros(self.fake_time_usecs).as_secs() + 60 + } } diff --git a/api/types/src/bytecode.rs b/api/types/src/bytecode.rs index 43d57a2f43f..55fbad24c0a 100644 --- a/api/types/src/bytecode.rs +++ b/api/types/src/bytecode.rs @@ -20,7 +20,11 @@ use move_binary_format::{ StructFieldInformation, StructHandle, StructHandleIndex, }, }; -use move_core_types::{account_address::AccountAddress, identifier::IdentStr}; +use move_core_types::{ + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage::{ModuleId, LEGACY_OPTION_VEC}, +}; use std::borrow::Borrow; pub trait Bytecode { @@ -54,6 +58,13 @@ pub trait Bytecode { } } + fn struct_is_enum(&self, def: &StructDefinition) -> bool { + matches!( + def.field_information, + StructFieldInformation::DeclaredVariants(_) + ) + } + fn new_move_struct_field(&self, def: &FieldDefinition) -> MoveStructField { MoveStructField { name: self.identifier_at(def.name).to_owned().into(), @@ -85,6 +96,12 @@ pub trait Bytecode { SignatureToken::U64 => MoveType::U64, SignatureToken::U128 => MoveType::U128, SignatureToken::U256 => MoveType::U256, + SignatureToken::I8 => MoveType::I8, + SignatureToken::I16 => MoveType::I16, + SignatureToken::I32 => MoveType::I32, + SignatureToken::I64 => MoveType::I64, + SignatureToken::I128 => MoveType::I128, + SignatureToken::I256 => MoveType::I256, SignatureToken::Address => MoveType::Address, SignatureToken::Signer => MoveType::Signer, SignatureToken::Vector(t) => MoveType::Vector { @@ -120,6 +137,7 @@ pub trait Bytecode { fn new_move_struct(&self, def: &StructDefinition) -> MoveStruct { let handle = self.struct_handle_at(def.struct_handle); + let mut is_enum = self.struct_is_enum(def); let (is_native, fields) = match &def.field_information { StructFieldInformation::Native => (true, vec![]), StructFieldInformation::Declared(fields) => ( @@ -129,9 +147,29 @@ pub trait Bytecode { .map(|f| self.new_move_struct_field(f)) .collect(), ), - StructFieldInformation::DeclaredVariants(..) => { - // TODO(#13806): implement for enums. Currently we pretend they don't have fields - (false, vec![]) + StructFieldInformation::DeclaredVariants(variant_defs) => { + // For `Option`, we want to keep it backwards compatible with the old representation + // instead of enum representation, we convert it to a struct with `vec` field. + let module_handle = self.module_handle_at(handle.module); + let mid = ModuleId { + address: *self.address_identifier_at(module_handle.address), + name: self.identifier_at(module_handle.name).to_owned(), + }; + if mid.is_option() && variant_defs.len() == 2 { + is_enum = false; + let variant = &variant_defs[1]; + let field_type = MoveType::Vector { + items: Box::new(self.new_move_type(&variant.fields[0].signature.0)), + }; + let field = MoveStructField { + name: Identifier::new(LEGACY_OPTION_VEC).unwrap().into(), + typ: field_type, + }; + (false, vec![field]) + } else { + // TODO(#13806): implement for enums. Currently we pretend they don't have fields + (false, vec![]) + } }, }; let name = self.identifier_at(handle.name).to_owned(); @@ -150,6 +188,7 @@ pub trait Bytecode { name: name.into(), is_native, is_event, + is_enum, abilities, generic_type_params, fields, diff --git a/api/types/src/convert.rs b/api/types/src/convert.rs index 015473d224d..ecfc688514a 100644 --- a/api/types/src/convert.rs +++ b/api/types/src/convert.rs @@ -32,8 +32,8 @@ use aptos_types::{ StateView, }, transaction::{ - BlockEndInfo, BlockEpiloguePayload, EntryFunction, ExecutionStatus, Multisig, - RawTransaction, Script, SignedTransaction, TransactionAuxiliaryData, + BlockEndInfo, EntryFunction, ExecutionStatus, Multisig, RawTransaction, Script, + SignedTransaction, TransactionAuxiliaryData, }, vm::module_metadata::get_metadata, vm_status::AbortLocation, @@ -139,11 +139,7 @@ impl<'a, S: StateView> MoveConverter<'a, S> { bytes: &[u8], ) -> Result> { let resources_with_tag: Vec<(StructTag, Vec)> = bcs::from_bytes::(bytes) - .map(|map| { - map.into_iter() - .map(|(key, value)| (key, value)) - .collect::>() - })?; + .map(|map| map.into_iter().collect::>())?; resources_with_tag .iter() @@ -217,26 +213,27 @@ impl<'a, S: StateView> MoveConverter<'a, S> { }) }, BlockEpilogue(block_epilogue_payload) => { + let block_end_info = block_epilogue_payload + .try_as_block_end_info() + .unwrap() + .clone(); + let block_end_info = match block_end_info { + BlockEndInfo::V0 { + block_gas_limit_reached, + block_output_limit_reached, + block_effective_block_gas_units, + block_approx_output_size, + } => Some(crate::transaction::BlockEndInfo { + block_gas_limit_reached, + block_output_limit_reached, + block_effective_block_gas_units, + block_approx_output_size, + }), + }; Transaction::BlockEpilogueTransaction(BlockEpilogueTransaction { info, timestamp: timestamp.into(), - block_end_info: match block_epilogue_payload { - BlockEpiloguePayload::V0 { - block_end_info: - BlockEndInfo::V0 { - block_gas_limit_reached, - block_output_limit_reached, - block_effective_block_gas_units, - block_approx_output_size, - }, - .. - } => Some(crate::transaction::BlockEndInfo { - block_gas_limit_reached, - block_output_limit_reached, - block_effective_block_gas_units, - block_approx_output_size, - }), - }, + block_end_info, }) }, aptos_types::transaction::Transaction::ValidatorTransaction(txn) => { @@ -406,6 +403,9 @@ impl<'a, S: StateView> MoveConverter<'a, S> { }, // Deprecated. ModuleBundle(_) => bail!("Module bundle payload has been removed"), + EncryptedPayload(_) => { + bail!("Encrypted payload isn't supported yet") + }, }; Ok(ret) } @@ -919,6 +919,12 @@ impl<'a, S: StateView> MoveConverter<'a, S> { MoveTypeLayout::U64 => serde_json::from_value::(val)?.into(), MoveTypeLayout::U128 => serde_json::from_value::(val)?.into(), MoveTypeLayout::U256 => serde_json::from_value::(val)?.into(), + MoveTypeLayout::I8 => I8(serde_json::from_value::(val)?), + MoveTypeLayout::I16 => I16(serde_json::from_value::(val)?), + MoveTypeLayout::I32 => I32(serde_json::from_value::(val)?), + MoveTypeLayout::I64 => serde_json::from_value::(val)?.into(), + MoveTypeLayout::I128 => serde_json::from_value::(val)?.into(), + MoveTypeLayout::I256 => serde_json::from_value::(val)?.into(), MoveTypeLayout::Address => serde_json::from_value::(val)?.into(), MoveTypeLayout::Vector(item_layout) => { self.try_into_vm_value_vector(item_layout.as_ref(), val)? @@ -1027,10 +1033,10 @@ impl<'a, S: StateView> MoveConverter<'a, S> { let code = self.inner.view_existing_module(&module.clone().into())? as Arc; let func = code .find_function(function.name.0.as_ident_str()) - .ok_or_else(|| format_err!("could not find entry function by {}", function))?; + .ok_or_else(|| format_err!("could not find view function by {}", function))?; ensure!( func.generic_type_params.len() == type_arguments.len(), - "expected {} type arguments for entry function {}, but got {}", + "expected {} type arguments for view function {}, but got {}", func.generic_type_params.len(), function, type_arguments.len() @@ -1059,7 +1065,7 @@ impl<'a, S: StateView> MoveConverter<'a, S> { Ok(None) } - fn explain_vm_status( + pub fn explain_vm_status( &self, status: &ExecutionStatus, txn_aux_data: Option, @@ -1176,7 +1182,7 @@ pub trait AsConverter { &self, db: Arc, indexer_reader: Option>, - ) -> MoveConverter; + ) -> MoveConverter<'_, R>; } impl AsConverter for R { @@ -1184,7 +1190,7 @@ impl AsConverter for R { &self, db: Arc, indexer_reader: Option>, - ) -> MoveConverter { + ) -> MoveConverter<'_, R> { MoveConverter::new(self, db, indexer_reader) } } diff --git a/api/types/src/derives.rs b/api/types/src/derives.rs index b55cccb47da..da456a9c8a2 100644 --- a/api/types/src/derives.rs +++ b/api/types/src/derives.rs @@ -21,7 +21,7 @@ use crate::{ move_types::{MoveAbility, MoveStructValue}, Address, AssetType, EntryFunctionId, HashValue, HexEncodedBytes, IdentifierWrapper, - MoveModuleId, MoveStructTag, MoveType, StateKeyWrapper, U128, U256, U64, + MoveModuleId, MoveStructTag, MoveType, StateKeyWrapper, I128, I256, I64, U128, U256, U64, }; use aptos_openapi::{impl_poem_parameter, impl_poem_type}; use indoc::indoc; @@ -177,9 +177,9 @@ impl_poem_type!( Move `bool` type value is serialized into `boolean`. - Move `u8`, `u16` and `u32` type value is serialized into `integer`. + Move `u8`, `u16`, `u32`, `i8`, `i16`, and `i32` type value is serialized into `integer`. - Move `u64`, `u128` and `u256` type value is serialized into `string`. + Move `u64`, `u128`, `u256`, `i64`, `i128`, and `i256` type value is serialized into `string`. Move `address` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string. For example: @@ -217,7 +217,7 @@ impl_poem_type!( "string", ( pattern = - Some("^(bool|u8|u64|u128|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$".to_string()), + Some("^(bool|u8|u16|u32|u64|u128|u256|i8|i16|i32|i64|i128|i256|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$".to_string()), description = Some(indoc! {" String representation of an on-chain Move type tag that is exposed in transaction payload. Values: @@ -228,6 +228,12 @@ impl_poem_type!( - u64 - u128 - u256 + - i8 + - i16 + - i32 + - i64 + - i128 + - i256 - address - signer - vector: `vector<{non-reference MoveTypeId}>` @@ -309,6 +315,51 @@ impl_poem_type!( ) ); +impl_poem_type!( + I64, + "string", + ( + example = Some(serde_json::Value::String("-32425224034".to_string())), + format = Some("int64"), + description = Some(indoc! {" + A string containing a 64-bit signed integer. + + We represent i64 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i64s in JSON natively. + "}) + ) +); + +impl_poem_type!( + I128, + "string", + ( + example = Some(serde_json::Value::String("-32425224034".to_string())), + format = Some("int128"), + description = Some(indoc! {" + A string containing a 128-bit signed integer. + + We represent i128 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i128s in JSON natively. + "}) + ) +); + +impl_poem_type!( + I256, + "string", + ( + example = Some(serde_json::Value::String("-32425224034".to_string())), + format = Some("int256"), + description = Some(indoc! {" + A string containing a 256-bit signed integer. + + We represent i256 values as a string to ensure compatibility with languages such + as JavaScript that do not parse i256s in JSON natively. + "}) + ) +); + impl_poem_parameter!( Address, AssetType, @@ -318,5 +369,7 @@ impl_poem_parameter!( MoveStructTag, StateKeyWrapper, U64, - U128 + U128, + I64, + I128 ); diff --git a/api/types/src/error.rs b/api/types/src/error.rs index 3f7454f50c9..a2d4c2fd80c 100644 --- a/api/types/src/error.rs +++ b/api/types/src/error.rs @@ -96,6 +96,8 @@ pub enum AptosErrorCode { SequenceNumberTooOld = 402, /// The submitted transaction failed VM checks. VmError = 403, + /// The transaction was rejected due to a transaction filter. + RejectedByFilter = 404, /// Health check failed. HealthCheckFailed = 500, diff --git a/api/types/src/headers.rs b/api/types/src/headers.rs index a2fb3b28f75..04dac9c60fa 100644 --- a/api/types/src/headers.rs +++ b/api/types/src/headers.rs @@ -22,3 +22,5 @@ pub const X_APTOS_CURSOR: &str = "X-Aptos-Cursor"; pub const X_APTOS_GAS_USED: &str = "X-Aptos-Gas-Used"; /// Provided by the client to identify what client it is. pub const X_APTOS_CLIENT: &str = "x-aptos-client"; +/// W3C Trace Context traceparent header for distributed tracing +pub const TRACEPARENT: &str = "traceparent"; diff --git a/api/types/src/lib.rs b/api/types/src/lib.rs index e1258f8b0ec..c1372d95fe3 100644 --- a/api/types/src/lib.rs +++ b/api/types/src/lib.rs @@ -38,14 +38,14 @@ pub use move_types::{ HexEncodedBytes, MoveAbility, MoveFunction, MoveFunctionGenericTypeParam, MoveFunctionVisibility, MoveModule, MoveModuleBytecode, MoveModuleId, MoveResource, MoveScriptBytecode, MoveStruct, MoveStructField, MoveStructTag, MoveType, MoveValue, - ResourceGroup, MAX_RECURSIVE_TYPES_ALLOWED, U128, U256, U64, + ResourceGroup, I128, I256, I64, MAX_RECURSIVE_TYPES_ALLOWED, U128, U256, U64, }; use serde::{Deserialize, Deserializer}; pub use state::RawStateValueRequest; use std::str::FromStr; pub use table::{RawTableItemRequest, TableItemRequest}; pub use transaction::{ - AbstractionSignature, AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, + AbstractSignature, AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, DeleteTableItem, DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, EntryFunctionPayload, Event, FeePayerSignature, GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction, MultiAgentSignature, MultiEd25519Signature, diff --git a/api/types/src/move_types.rs b/api/types/src/move_types.rs index 325d2b9a10a..c8d352e12ef 100644 --- a/api/types/src/move_types.rs +++ b/api/types/src/move_types.rs @@ -16,7 +16,9 @@ use move_core_types::{ ability::{Ability, AbilitySet}, account_address::AccountAddress, identifier::Identifier, - language_storage::{FunctionTag, ModuleId, StructTag, TypeTag}, + language_storage::{ + FunctionParamOrReturnTag, FunctionTag, ModuleId, StructTag, TypeTag, LEGACY_OPTION_VEC, + }, parser::{parse_struct_tag, parse_type_tag}, transaction_argument::TransactionArgument, }; @@ -127,7 +129,19 @@ macro_rules! define_integer_type { define_integer_type!(U64, u64, "A string encoded U64."); define_integer_type!(U128, u128, "A string encoded U128."); -define_integer_type!(U256, move_core_types::u256::U256, "A string encoded U256."); +define_integer_type!( + U256, + move_core_types::int256::U256, + "A string encoded U256." +); + +define_integer_type!(I64, i64, "A string encoded I64."); +define_integer_type!(I128, i128, "A string encoded I128."); +define_integer_type!( + I256, + move_core_types::int256::I256, + "A string encoded I256." +); /// Hex encoded bytes to allow for having bytes represented in JSON #[derive(Clone, Debug, PartialEq, Eq)] @@ -226,6 +240,35 @@ impl TryFrom for MoveStructValue { fn try_from(s: AnnotatedMoveStruct) -> anyhow::Result { let mut map = BTreeMap::new(); + // This guarantees generated json is backwards compatible. + if s.ty_tag.is_option() { + if let Some((_, name)) = &s.variant_info { + if name.to_string() == "None" { + if !s.value.is_empty() { + return Err(anyhow::anyhow!("None must not have any value")); + } + map.insert( + IdentifierWrapper::from_str(LEGACY_OPTION_VEC)?, + MoveValue::Vector(vec![]).json()?, + ); + } else if name.to_string() == "Some" { + if s.value.len() != 1 { + return Err(anyhow::anyhow!("Some must have exactly one value")); + } + let v = s.value.into_iter().next().unwrap().1; + map.insert( + IdentifierWrapper::from_str(LEGACY_OPTION_VEC)?, + MoveValue::Vector(vec![MoveValue::try_from(v)?]).json()?, + ); + } else { + return Err(anyhow::anyhow!( + "Invalid option variant: {}", + name.to_string() + )); + } + return Ok(Self(map)); + } + } if let Some((_, name)) = s.variant_info { map.insert( IdentifierWrapper::from_str("__variant__")?, @@ -252,7 +295,7 @@ impl TryFrom for MoveStructValue { } for (pos, val) in s.field_values.into_iter().enumerate() { map.insert( - IdentifierWrapper::from_str(&pos.to_string())?, + IdentifierWrapper::from_str(format!("_{}", pos).as_str())?, MoveValue::try_from(val)?.json()?, ); } @@ -324,6 +367,12 @@ pub enum MoveValue { U64(U64), U128(U128), U256(U256), + I8(i8), + I16(i16), + I32(i32), + I64(I64), + I128(I128), + I256(I256), /// A bool Move type Bool(bool), Address(Address), @@ -375,6 +424,12 @@ impl TryFrom for MoveValue { AnnotatedMoveValue::U64(v) => MoveValue::U64(U64(v)), AnnotatedMoveValue::U128(v) => MoveValue::U128(U128(v)), AnnotatedMoveValue::U256(v) => MoveValue::U256(U256(v)), + AnnotatedMoveValue::I8(v) => MoveValue::I8(v), + AnnotatedMoveValue::I16(v) => MoveValue::I16(v), + AnnotatedMoveValue::I32(v) => MoveValue::I32(v), + AnnotatedMoveValue::I64(v) => MoveValue::I64(I64(v)), + AnnotatedMoveValue::I128(v) => MoveValue::I128(I128(v)), + AnnotatedMoveValue::I256(v) => MoveValue::I256(I256(v)), AnnotatedMoveValue::Bool(v) => MoveValue::Bool(v), AnnotatedMoveValue::Address(v) => MoveValue::Address(v.into()), AnnotatedMoveValue::Vector(_, vals) => MoveValue::Vector( @@ -405,6 +460,12 @@ impl From for MoveValue { TransactionArgument::U64(v) => MoveValue::U64(U64(v)), TransactionArgument::U128(v) => MoveValue::U128(U128(v)), TransactionArgument::U256(v) => MoveValue::U256(U256(v)), + TransactionArgument::I8(v) => MoveValue::I8(v), + TransactionArgument::I16(v) => MoveValue::I16(v), + TransactionArgument::I32(v) => MoveValue::I32(v), + TransactionArgument::I64(v) => MoveValue::I64(I64(v)), + TransactionArgument::I128(v) => MoveValue::I128(I128(v)), + TransactionArgument::I256(v) => MoveValue::I256(I256(v)), TransactionArgument::Bool(v) => MoveValue::Bool(v), TransactionArgument::Address(v) => MoveValue::Address(v.into()), TransactionArgument::U8Vector(bytes) => MoveValue::Bytes(HexEncodedBytes(bytes)), @@ -422,6 +483,12 @@ impl Serialize for MoveValue { MoveValue::U64(v) => v.serialize(serializer), MoveValue::U128(v) => v.serialize(serializer), MoveValue::U256(v) => v.serialize(serializer), + MoveValue::I8(v) => v.serialize(serializer), + MoveValue::I16(v) => v.serialize(serializer), + MoveValue::I32(v) => v.serialize(serializer), + MoveValue::I64(v) => v.serialize(serializer), + MoveValue::I128(v) => v.serialize(serializer), + MoveValue::I256(v) => v.serialize(serializer), MoveValue::Bool(v) => v.serialize(serializer), MoveValue::Address(v) => v.serialize(serializer), MoveValue::Vector(v) => v.serialize(serializer), @@ -580,6 +647,18 @@ pub enum MoveType { U128, /// A 256-bit unsigned int U256, + /// An 8-bit signed int + I8, + /// A 16-bit signed int + I16, + /// A 32-bit signed int + I32, + /// A 64-bit signed int + I64, + /// A 128-bit signed int + I128, + /// A 256-bit signed int + I256, /// A 32-byte account address Address, /// An account signer @@ -650,6 +729,12 @@ impl MoveType { MoveType::U64 => "string".to_owned(), MoveType::U128 => "string".to_owned(), MoveType::U256 => "string".to_owned(), + MoveType::I8 => "integer".to_owned(), + MoveType::I16 => "integer".to_owned(), + MoveType::I32 => "integer".to_owned(), + MoveType::I64 => "string".to_owned(), + MoveType::I128 => "string".to_owned(), + MoveType::I256 => "string".to_owned(), MoveType::Signer | MoveType::Address => "string
".to_owned(), MoveType::Bool => "boolean".to_owned(), MoveType::Vector { items } => { @@ -681,6 +766,12 @@ impl fmt::Display for MoveType { MoveType::U64 => write!(f, "u64"), MoveType::U128 => write!(f, "u128"), MoveType::U256 => write!(f, "u256"), + MoveType::I8 => write!(f, "i8"), + MoveType::I16 => write!(f, "i16"), + MoveType::I32 => write!(f, "i32"), + MoveType::I64 => write!(f, "i64"), + MoveType::I128 => write!(f, "i128"), + MoveType::I256 => write!(f, "i256"), MoveType::Address => write!(f, "address"), MoveType::Signer => write!(f, "signer"), MoveType::Bool => write!(f, "bool"), @@ -790,6 +881,12 @@ impl From<&TypeTag> for MoveType { TypeTag::U64 => MoveType::U64, TypeTag::U128 => MoveType::U128, TypeTag::U256 => MoveType::U256, + TypeTag::I8 => MoveType::I8, + TypeTag::I16 => MoveType::I16, + TypeTag::I32 => MoveType::I32, + TypeTag::I64 => MoveType::I64, + TypeTag::I128 => MoveType::I128, + TypeTag::I256 => MoveType::I256, TypeTag::Address => MoveType::Address, TypeTag::Signer => MoveType::Signer, TypeTag::Vector(v) => MoveType::Vector { @@ -807,7 +904,21 @@ fn from_function_tag(f: &FunctionTag) -> MoveType { results, abilities, } = f; - let from_vec = |tys: &[TypeTag]| tys.iter().map(MoveType::from).collect::>(); + let from_vec = |ts: &[FunctionParamOrReturnTag]| { + ts.iter() + .map(|t| match t { + FunctionParamOrReturnTag::Reference(t) => MoveType::Reference { + mutable: false, + to: Box::new(MoveType::from(t)), + }, + FunctionParamOrReturnTag::MutableReference(t) => MoveType::Reference { + mutable: true, + to: Box::new(MoveType::from(t)), + }, + FunctionParamOrReturnTag::Value(t) => MoveType::from(t), + }) + .collect::>() + }; MoveType::Function { args: from_vec(args), results: from_vec(results), @@ -827,6 +938,12 @@ impl TryFrom<&MoveType> for TypeTag { MoveType::U64 => TypeTag::U64, MoveType::U128 => TypeTag::U128, MoveType::U256 => TypeTag::U256, + MoveType::I8 => TypeTag::I8, + MoveType::I16 => TypeTag::I16, + MoveType::I32 => TypeTag::I32, + MoveType::I64 => TypeTag::I64, + MoveType::I128 => TypeTag::I128, + MoveType::I256 => TypeTag::I256, MoveType::Address => TypeTag::Address, MoveType::Signer => TypeTag::Signer, MoveType::Vector { items } => TypeTag::Vector(Box::new(items.as_ref().try_into()?)), @@ -838,7 +955,19 @@ impl TryFrom<&MoveType> for TypeTag { } => { let try_vec = |tys: &[MoveType]| { tys.iter() - .map(Self::try_from) + .map(|t| { + Ok(match t { + MoveType::Reference { mutable, to } => { + let tag = to.as_ref().try_into()?; + if *mutable { + FunctionParamOrReturnTag::MutableReference(tag) + } else { + FunctionParamOrReturnTag::Reference(tag) + } + }, + t => FunctionParamOrReturnTag::Value(t.try_into()?), + }) + }) .collect::>() }; TypeTag::Function(Box::new(FunctionTag { @@ -848,7 +977,7 @@ impl TryFrom<&MoveType> for TypeTag { })) }, MoveType::GenericTypeParam { index: _ } => TypeTag::Address, // Dummy type, allows for Object - _ => { + MoveType::Reference { .. } | MoveType::Unparsable(_) => { return Err(anyhow::anyhow!( "Invalid move type for converting into `TypeTag`: {:?}", &tag @@ -985,6 +1114,8 @@ pub struct MoveStruct { pub is_native: bool, /// Whether the struct is marked with the #[event] annotation pub is_event: bool, + /// Whether the struct is an enum (i.e. enum MyEnum vs struct MyStruct). + pub is_enum: bool, /// Abilities associated with the struct pub abilities: Vec, /// Generic types associated with the struct @@ -1368,8 +1499,17 @@ mod tests { } assert_serialize(Bool, json!("bool")); assert_serialize(U8, json!("u8")); + assert_serialize(U16, json!("u16")); + assert_serialize(U32, json!("u32")); assert_serialize(U64, json!("u64")); assert_serialize(U128, json!("u128")); + assert_serialize(U256, json!("u256")); + assert_serialize(I8, json!("i8")); + assert_serialize(I16, json!("i16")); + assert_serialize(I32, json!("i32")); + assert_serialize(I64, json!("i64")); + assert_serialize(I128, json!("i128")); + assert_serialize(I256, json!("i256")); assert_serialize(Address, json!("address")); assert_serialize(Signer, json!("signer")); diff --git a/api/types/src/transaction.rs b/api/types/src/transaction.rs index 57ebf47291e..d534b57bad1 100755 --- a/api/types/src/transaction.rs +++ b/api/types/src/transaction.rs @@ -27,8 +27,9 @@ use aptos_types::{ keyless, transaction::{ authenticator::{ - AccountAuthenticator, AnyPublicKey, AnySignature, MultiKey, MultiKeyAuthenticator, - SingleKeyAuthenticator, TransactionAuthenticator, MAX_NUM_OF_SIGS, + AbstractAuthenticator, AccountAuthenticator, AnyPublicKey, AnySignature, MultiKey, + MultiKeyAuthenticator, SingleKeyAuthenticator, TransactionAuthenticator, + MAX_NUM_OF_SIGS, }, webauthn::{PartialAuthenticatorAssertionResponse, MAX_WEBAUTHN_SIGNATURE_BYTES}, Script, SignedTransaction, TransactionOutput, TransactionWithProof, @@ -43,7 +44,6 @@ use std::{ convert::{From, Into, TryFrom, TryInto}, fmt, str::FromStr, - time::{SystemTime, UNIX_EPOCH}, }; static DUMMY_GUID: Lazy = Lazy::new(|| EventGuid { @@ -489,15 +489,6 @@ pub struct UserTransactionRequestInner { impl VerifyInput for UserTransactionRequestInner { fn verify(&self) -> anyhow::Result<()> { - if let Ok(now) = SystemTime::now().duration_since(UNIX_EPOCH) { - if self.expiration_timestamp_secs.0 <= now.as_secs() { - bail!( - "Expiration time for transaction is in the past, {}", - self.expiration_timestamp_secs.0 - ) - } - } - self.payload.verify() } } @@ -516,6 +507,16 @@ pub struct UserTransactionRequest { pub replay_protection_nonce: Option, } +impl UserTransactionRequest { + pub fn replay_protector(&self) -> aptos_types::transaction::ReplayProtector { + if let Some(nonce) = self.replay_protection_nonce { + aptos_types::transaction::ReplayProtector::Nonce(nonce.0) + } else { + aptos_types::transaction::ReplayProtector::SequenceNumber(self.sequence_number.0) + } + } +} + /// Request to create signing messages #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] pub struct UserCreateSigningMessageRequest { @@ -1942,12 +1943,12 @@ impl VerifyInput for NoAccountSignature { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] -pub struct AbstractionSignature { +pub struct AbstractSignature { pub function_info: String, pub auth_data: HexEncodedBytes, } -impl VerifyInput for AbstractionSignature { +impl VerifyInput for AbstractSignature { fn verify(&self) -> anyhow::Result<()> { Ok(()) } @@ -1970,13 +1971,15 @@ impl TryFrom<&NoAccountSignature> for AccountAuthenticator { } } -impl TryFrom<&AbstractionSignature> for AccountAuthenticator { +impl TryFrom<&AbstractSignature> for AccountAuthenticator { type Error = anyhow::Error; - fn try_from(value: &AbstractionSignature) -> Result { - Ok(AccountAuthenticator::Abstraction { - function_info: FunctionInfo::from_str(&value.function_info)?, - auth_data: bcs::from_bytes(value.auth_data.inner())?, + fn try_from(value: &AbstractSignature) -> Result { + Ok(AccountAuthenticator::Abstract { + authenticator: AbstractAuthenticator::new( + FunctionInfo::from_str(&value.function_info)?, + bcs::from_bytes(value.auth_data.inner())?, + ), }) } } @@ -1997,7 +2000,7 @@ pub enum AccountSignature { SingleKeySignature(SingleKeySignature), MultiKeySignature(MultiKeySignature), NoAccountSignature(NoAccountSignature), - AbstractionSignature(AbstractionSignature), + AbstractSignature(AbstractSignature), } impl VerifyInput for AccountSignature { @@ -2008,7 +2011,7 @@ impl VerifyInput for AccountSignature { AccountSignature::SingleKeySignature(inner) => inner.verify(), AccountSignature::MultiKeySignature(inner) => inner.verify(), AccountSignature::NoAccountSignature(inner) => inner.verify(), - AccountSignature::AbstractionSignature(inner) => inner.verify(), + AccountSignature::AbstractSignature(inner) => inner.verify(), } } } @@ -2023,7 +2026,7 @@ impl TryFrom<&AccountSignature> for AccountAuthenticator { AccountSignature::SingleKeySignature(s) => s.try_into()?, AccountSignature::MultiKeySignature(s) => s.try_into()?, AccountSignature::NoAccountSignature(s) => s.try_into()?, - AccountSignature::AbstractionSignature(s) => s.try_into()?, + AccountSignature::AbstractSignature(s) => s.try_into()?, }) } } @@ -2182,12 +2185,9 @@ impl From<&AccountAuthenticator> for AccountSignature { }) }, NoAccountAuthenticator => AccountSignature::NoAccountSignature(NoAccountSignature), - Abstraction { - function_info, - auth_data, - } => Self::AbstractionSignature(AbstractionSignature { - function_info: function_info.to_string(), - auth_data: to_bytes(auth_data) + Abstract { authenticator } => Self::AbstractSignature(AbstractSignature { + function_info: authenticator.function_info().to_string(), + auth_data: to_bytes(authenticator.auth_data()) .expect("bcs serialization cannot fail") .into(), }), @@ -2399,3 +2399,23 @@ pub struct GasEstimation { /// The prioritized estimate for the gas unit price pub prioritized_gas_estimate: Option, } + +/// API representation of persisted auxiliary transaction information +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] +pub struct PersistedAuxiliaryInfo { + /// Optional transaction index in the block (None indicates no auxiliary info available) + pub transaction_index: Option, +} + +impl From for PersistedAuxiliaryInfo { + fn from(info: aptos_types::transaction::PersistedAuxiliaryInfo) -> Self { + match info { + aptos_types::transaction::PersistedAuxiliaryInfo::None => Self { + transaction_index: None, + }, + aptos_types::transaction::PersistedAuxiliaryInfo::V1 { transaction_index } => Self { + transaction_index: Some(transaction_index), + }, + } + } +} diff --git a/aptos-move/aptos-abstract-gas-usage/Cargo.toml b/aptos-move/aptos-abstract-gas-usage/Cargo.toml index d1a5026aea7..86877135810 100644 --- a/aptos-move/aptos-abstract-gas-usage/Cargo.toml +++ b/aptos-move/aptos-abstract-gas-usage/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "aptos-abstract-gas-usage" version = "0.1.0" -edition = "2021" +edition = { workspace = true } license = { workspace = true } [dependencies] diff --git a/aptos-move/aptos-abstract-gas-usage/src/algebra.rs b/aptos-move/aptos-abstract-gas-usage/src/algebra.rs index e0998444e7e..037dc9f79e3 100644 --- a/aptos-move/aptos-abstract-gas-usage/src/algebra.rs +++ b/aptos-move/aptos-abstract-gas-usage/src/algebra.rs @@ -7,7 +7,9 @@ use aptos_gas_algebra::{ }; use aptos_gas_meter::GasAlgebra; use aptos_gas_schedule::VMGasParameters; -use aptos_vm_types::storage::{io_pricing::IoPricing, space_pricing::DiskSpacePricing}; +use aptos_vm_types::storage::{ + io_pricing::IoPricing, space_pricing::DiskSpacePricing, StorageGasParameters, +}; use move_binary_format::errors::PartialVMResult; use std::sync::{Arc, Mutex}; @@ -30,6 +32,10 @@ impl GasAlgebra for CalibrationAlgebra { self.base.vm_gas_params() } + fn storage_gas_params(&self) -> &StorageGasParameters { + self.base.storage_gas_params() + } + fn io_pricing(&self) -> &IoPricing { self.base.io_pricing() } diff --git a/aptos-move/aptos-aggregator/Cargo.toml b/aptos-move/aptos-aggregator/Cargo.toml index 6c73b0b750b..986a4ffd1a1 100644 --- a/aptos-move/aptos-aggregator/Cargo.toml +++ b/aptos-move/aptos-aggregator/Cargo.toml @@ -19,6 +19,7 @@ claims = { workspace = true } move-binary-format = { workspace = true } move-core-types = { workspace = true } move-vm-types = { workspace = true } +triomphe = { workspace = true } [dev-dependencies] once_cell = { workspace = true } diff --git a/aptos-move/aptos-aggregator/src/delta_change_set.rs b/aptos-move/aptos-aggregator/src/delta_change_set.rs index ab7a6161289..425245404f7 100644 --- a/aptos-move/aptos-aggregator/src/delta_change_set.rs +++ b/aptos-move/aptos-aggregator/src/delta_change_set.rs @@ -229,10 +229,8 @@ mod test { use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{value::MoveTypeLayout, vm_status::StatusCode}; use once_cell::sync::Lazy; - use std::{ - collections::{BTreeMap, HashSet}, - sync::Arc, - }; + use std::collections::{BTreeMap, HashSet}; + use triomphe::Arc as TriompheArc; fn delta_add_with_history(v: u128, max_value: u128, max: u128, min: u128) -> DeltaOp { let mut delta = delta_add(v, max_value); @@ -542,7 +540,7 @@ mod test { _delayed_write_set_keys: &HashSet, _skip: &HashSet, ) -> Result< - BTreeMap)>, + BTreeMap)>, PanicError, > { unimplemented!("Irrelevant for the test") diff --git a/aptos-move/aptos-aggregator/src/delta_math.rs b/aptos-move/aptos-aggregator/src/delta_math.rs index f0712ad3cc8..48204d05db0 100644 --- a/aptos-move/aptos-aggregator/src/delta_math.rs +++ b/aptos-move/aptos-aggregator/src/delta_math.rs @@ -315,11 +315,11 @@ impl DeltaHistory { pub fn stricter_than(&self, other: &DeltaHistory) -> bool { self.max_achieved_positive_delta >= other.max_achieved_positive_delta && self.min_achieved_negative_delta >= other.min_achieved_negative_delta - && other.min_overflow_positive_delta.map_or(true, |other_v| { + && other.min_overflow_positive_delta.is_none_or(|other_v| { self.min_overflow_positive_delta .is_some_and(|self_v| self_v <= other_v) }) - && other.max_underflow_negative_delta.map_or(true, |other_v| { + && other.max_underflow_negative_delta.is_none_or(|other_v| { self.max_underflow_negative_delta .is_some_and(|self_v| self_v <= other_v) }) diff --git a/aptos-move/aptos-aggregator/src/resolver.rs b/aptos-move/aptos-aggregator/src/resolver.rs index 20063312973..91a6f3eb862 100644 --- a/aptos-move/aptos-aggregator/src/resolver.rs +++ b/aptos-move/aptos-aggregator/src/resolver.rs @@ -22,8 +22,8 @@ use move_vm_types::delayed_values::delayed_field_id::DelayedFieldID; use std::{ collections::{BTreeMap, HashSet}, fmt::Debug, - sync::Arc, }; +use triomphe::Arc as TriompheArc; /// We differentiate between deprecated way to interact with aggregators (TAggregatorV1View), /// and new, more general, TDelayedFieldView. @@ -181,7 +181,7 @@ pub trait TDelayedFieldView { delayed_write_set_ids: &HashSet, skip: &HashSet, ) -> Result< - BTreeMap)>, + BTreeMap)>, PanicError, >; @@ -260,7 +260,7 @@ where _delayed_write_set_ids: &HashSet, _skip: &HashSet, ) -> Result< - BTreeMap)>, + BTreeMap)>, PanicError, > { unimplemented!("get_reads_needing_exchange not implemented") diff --git a/aptos-move/aptos-aggregator/src/tests/types.rs b/aptos-move/aptos-aggregator/src/tests/types.rs index 18096caae79..7bbb6e7f0fe 100644 --- a/aptos-move/aptos-aggregator/src/tests/types.rs +++ b/aptos-move/aptos-aggregator/src/tests/types.rs @@ -21,8 +21,8 @@ use move_vm_types::delayed_values::delayed_field_id::{DelayedFieldID, ExtractUni use std::{ cell::RefCell, collections::{BTreeMap, HashMap, HashSet}, - sync::Arc, }; +use triomphe::Arc as TriompheArc; pub fn aggregator_v1_id_for_test(key: u128) -> AggregatorID { AggregatorID(aggregator_v1_state_key_for_test(key)) @@ -132,7 +132,7 @@ impl TDelayedFieldView for FakeAggregatorView { _delayed_write_set_keys: &HashSet, _skip: &HashSet, ) -> Result< - BTreeMap)>, + BTreeMap)>, PanicError, > { unimplemented!(); diff --git a/aptos-move/aptos-debugger/src/aptos_debugger.rs b/aptos-move/aptos-debugger/src/aptos_debugger.rs index 9a77ebfeb4d..df713a94656 100644 --- a/aptos-move/aptos-debugger/src/aptos_debugger.rs +++ b/aptos-move/aptos-debugger/src/aptos_debugger.rs @@ -14,9 +14,9 @@ use aptos_types::{ contract_event::ContractEvent, state_store::TStateView, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, - SignedTransaction, Transaction, TransactionExecutableRef, TransactionInfo, - TransactionOutput, TransactionPayload, Version, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, BlockOutput, + PersistedAuxiliaryInfo, SignedTransaction, Transaction, TransactionExecutableRef, + TransactionInfo, TransactionOutput, TransactionPayload, Version, }, vm_status::VMStatus, }; @@ -55,7 +55,11 @@ impl AptosDebugger { &self, begin: Version, limit: u64, - ) -> anyhow::Result<(Vec, Vec)> { + ) -> anyhow::Result<( + Vec, + Vec, + Vec, + )> { self.debugger.get_committed_transactions(begin, limit).await } @@ -63,12 +67,20 @@ impl AptosDebugger { &self, version: Version, txns: Vec, + auxiliary_infos: Vec, repeat_execution_times: u64, concurrency_levels: &[usize], ) -> anyhow::Result> { let sig_verified_txns: Vec = txns.into_iter().map(|x| x.into()).collect::>(); - let txn_provider = DefaultTxnProvider::new(sig_verified_txns); + + // Convert persisted auxiliary infos to auxiliary infos + let auxiliary_infos = auxiliary_infos + .into_iter() + .map(|persisted_info| AuxiliaryInfo::new(persisted_info, None)) + .collect::>(); + + let txn_provider = DefaultTxnProvider::new(sig_verified_txns, auxiliary_infos); let state_view = DebuggerStateView::new(self.debugger.clone(), version); print_transaction_stats(txn_provider.get_txns(), version); @@ -119,6 +131,7 @@ impl AptosDebugger { &self, version: Version, txn: SignedTransaction, + auxiliary_info: AuxiliaryInfo, ) -> anyhow::Result<(VMStatus, VMOutput, TransactionGasLog)> { let state_view = DebuggerStateView::new(self.debugger.clone(), version); let log_context = AdapterLogSchema::new(state_view.id(), 0); @@ -142,7 +155,7 @@ impl AptosDebugger { &txn, &log_context, |gas_meter| { - let gas_profiler = match txn + match txn .executable_ref() .expect("Module bundle payload has been removed") { @@ -159,9 +172,9 @@ impl AptosDebugger { // TODO[Orderless]: Implement this unimplemented!("not supported yet") }, - }; - gas_profiler + } }, + &auxiliary_info, )?; Ok((status, output, gas_profiler.finish())) @@ -175,7 +188,8 @@ impl AptosDebugger { repeat_execution_times: u64, concurrency_levels: &[usize], ) -> anyhow::Result> { - let (txns, txn_infos) = self.get_committed_transactions(begin, limit).await?; + let (txns, txn_infos, auxiliary_infos) = + self.get_committed_transactions(begin, limit).await?; if use_same_block_boundaries { // when going block by block, no need to worry about epoch boundaries @@ -184,6 +198,7 @@ impl AptosDebugger { .execute_transactions_by_block( begin, txns.clone(), + auxiliary_infos.clone(), repeat_execution_times, concurrency_levels, ) @@ -193,6 +208,7 @@ impl AptosDebugger { limit, begin, txns, + auxiliary_infos, repeat_execution_times, concurrency_levels, txn_infos, @@ -241,12 +257,14 @@ impl AptosDebugger { &self, begin: Version, txns: Vec, + auxiliary_infos: Vec, repeat_execution_times: u64, concurrency_levels: &[usize], ) -> anyhow::Result> { let results = self.execute_transactions_at_version( begin, txns, + auxiliary_infos, repeat_execution_times, concurrency_levels, )?; @@ -270,6 +288,7 @@ impl AptosDebugger { mut limit: u64, mut begin: u64, mut txns: Vec, + mut auxiliary_infos: Vec, repeat_execution_times: u64, concurrency_levels: &[usize], mut txn_infos: Vec, @@ -285,6 +304,7 @@ impl AptosDebugger { .execute_transactions_until_epoch_end( begin, txns.clone(), + auxiliary_infos.clone(), repeat_execution_times, concurrency_levels, ) @@ -292,6 +312,7 @@ impl AptosDebugger { begin += epoch_result.len() as u64; limit -= epoch_result.len() as u64; txns = txns.split_off(epoch_result.len()); + auxiliary_infos = auxiliary_infos.split_off(epoch_result.len()); let epoch_txn_infos = txn_infos.drain(0..epoch_result.len()).collect::>(); Self::print_mismatches(&epoch_result, &epoch_txn_infos, begin); @@ -304,18 +325,22 @@ impl AptosDebugger { &self, begin: Version, txns: Vec, + auxiliary_infos: Vec, repeat_execution_times: u64, concurrency_levels: &[usize], ) -> anyhow::Result> { let mut ret = vec![]; let mut cur = vec![]; + let mut cur_aux_infos = vec![]; let mut cur_version = begin; - for txn in txns { + for (txn, aux_info) in txns.into_iter().zip(auxiliary_infos.into_iter()) { if txn.is_block_start() && !cur.is_empty() { let to_execute = std::mem::take(&mut cur); + let to_execute_aux_infos = std::mem::take(&mut cur_aux_infos); let results = self.execute_transactions_at_version( cur_version, to_execute, + to_execute_aux_infos, repeat_execution_times, concurrency_levels, )?; @@ -323,11 +348,13 @@ impl AptosDebugger { ret.extend(results); } cur.push(txn); + cur_aux_infos.push(aux_info); } if !cur.is_empty() { let results = self.execute_transactions_at_version( cur_version, cur, + cur_aux_infos, repeat_execution_times, concurrency_levels, )?; @@ -350,15 +377,19 @@ impl AptosDebugger { pub async fn get_committed_transaction_at_version( &self, version: Version, - ) -> anyhow::Result<(Transaction, TransactionInfo)> { - let (mut txns, mut info) = self.debugger.get_committed_transactions(version, 1).await?; + ) -> anyhow::Result<(Transaction, TransactionInfo, PersistedAuxiliaryInfo)> { + let (mut txns, mut info, mut aux_infos) = + self.get_committed_transactions(version, 1).await?; let txn = txns.pop().expect("there must be exactly 1 txn in the vec"); let info = info .pop() .expect("there must be exactly 1 txn info in the vec"); + let aux_info = aux_infos + .pop() + .expect("there must be exactly 1 auxiliary info in the vec"); - Ok((txn, info)) + Ok((txn, info, aux_info)) } pub fn state_view_at_version(&self, version: Version) -> DebuggerStateView { @@ -441,7 +472,7 @@ fn is_reconfiguration(vm_output: &TransactionOutput) -> bool { } fn execute_block_no_limit( - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &DebuggerStateView, concurrency_level: usize, ) -> Result, VMStatus> { diff --git a/aptos-move/aptos-debugger/src/bin/remote-gas-profiler.rs b/aptos-move/aptos-debugger/src/bin/remote-gas-profiler.rs index cc4c02aee36..c00861dbaab 100644 --- a/aptos-move/aptos-debugger/src/bin/remote-gas-profiler.rs +++ b/aptos-move/aptos-debugger/src/bin/remote-gas-profiler.rs @@ -4,7 +4,7 @@ use anyhow::{bail, Result}; use aptos_move_debugger::aptos_debugger::AptosDebugger; use aptos_rest_client::Client; -use aptos_types::transaction::Transaction; +use aptos_types::transaction::{AuxiliaryInfo, Transaction}; use aptos_vm::AptosVM; use clap::{Parser, Subcommand}; use std::path::{Path, PathBuf}; @@ -45,7 +45,7 @@ async fn main() -> Result<()> { }; // Execute the transaction w/ the gas profiler - let (txn, _txn_info) = debugger + let (txn, _txn_info, aux_info) = debugger .get_committed_transaction_at_version(version) .await?; @@ -54,8 +54,12 @@ async fn main() -> Result<()> { _ => bail!("not a user transaction"), }; - let (_status, output, gas_log) = - debugger.execute_transaction_at_version_with_gas_profiler(version, txn)?; + // Use the auxiliary info retrieved from the database + let (_status, output, gas_log) = debugger.execute_transaction_at_version_with_gas_profiler( + version, + txn, + AuxiliaryInfo::new(aux_info, None), + )?; let txn_output = output.try_materialize_into_transaction_output(&debugger.state_view_at_version(version))?; diff --git a/aptos-move/aptos-debugger/src/execute_pending_block.rs b/aptos-move/aptos-debugger/src/execute_pending_block.rs index 7235dff6e9b..f16d511c0c5 100644 --- a/aptos-move/aptos-debugger/src/execute_pending_block.rs +++ b/aptos-move/aptos-debugger/src/execute_pending_block.rs @@ -49,44 +49,66 @@ impl Command { unreachable!("Must provide one target."); }; - let user_txns = if let Some(block_rest_endpoint) = self.block_rest_endpoint { - info!( - "Getting block {:?} from {block_rest_endpoint:?}.", - self.block_id - ); - let base_url = - Url::parse(&block_rest_endpoint)?.join("/debug/consensus/block?bcs=true")?; - let url = if let Some(block_id) = self.block_id { - base_url.join(&format!("&block_id={block_id:?}"))? + let (user_txns, auxiliary_infos) = + if let Some(block_rest_endpoint) = self.block_rest_endpoint { + info!( + "Getting block {:?} from {block_rest_endpoint:?}.", + self.block_id + ); + + // Get the pending transactions from the REST endpoint + let base_url = + Url::parse(&block_rest_endpoint)?.join("/debug/consensus/block?bcs=true")?; + let url = if let Some(block_id) = self.block_id { + base_url.join(&format!("&block_id={block_id:?}"))? + } else { + base_url + }; + info!("GET {url:?}..."); + let body = reqwest::get(url).await?.bytes().await?; + let pending_txns: Vec<_> = bcs::from_bytes(&body)?; + + // Question[MI Counter]: Is it okay to use these auxiliary infos here? + let pending_aux_infos = (0..pending_txns.len()) + .map(|i| aptos_types::transaction::PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }) + .collect::>(); + + (pending_txns, pending_aux_infos) + } else if let Some(consensus_db_path) = self.consensus_db_path { + info!( + "Getting block {:?} from {consensus_db_path:?}.", + self.block_id + ); + let cmd = aptos_consensus::util::db_tool::Command { + db_dir: consensus_db_path, + block_id: self.block_id, + }; + let txns = cmd.dump_pending_txns()?; + + // For consensus DB path, create auxiliary infos with sequential indices + let aux_infos = (0..txns.len()) + .map(|i| aptos_types::transaction::PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }) + .collect::>(); + + (txns, aux_infos) } else { - base_url + unreachable!("Must provide one target."); }; - info!("GET {url:?}..."); - let body = reqwest::get(url).await?.bytes().await?; - bcs::from_bytes(&body)? - } else if let Some(consensus_db_path) = self.consensus_db_path { - info!( - "Getting block {:?} from {consensus_db_path:?}.", - self.block_id - ); - let cmd = aptos_consensus::util::db_tool::Command { - db_dir: consensus_db_path, - block_id: self.block_id, - }; - cmd.dump_pending_txns()? - } else { - unreachable!("Must provide one target."); - }; - let block = if self.add_system_txns { + let (block, block_auxiliary_infos) = if self.add_system_txns { todo!("Add block metadata txn and state checkpoint txn if necessary."); } else { - user_txns + (user_txns, auxiliary_infos) }; let txn_outputs = debugger.execute_transactions_at_version( self.begin_version, block, + block_auxiliary_infos, self.repeat_execution_times.unwrap_or(1), &self.opts.concurrency_level, )?; diff --git a/aptos-move/aptos-e2e-comparison-testing/Cargo.toml b/aptos-move/aptos-e2e-comparison-testing/Cargo.toml index 6e0462d8177..15ca8367f49 100644 --- a/aptos-move/aptos-e2e-comparison-testing/Cargo.toml +++ b/aptos-move/aptos-e2e-comparison-testing/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/aptos-labs/aptos-core" homepage = "https://aptoslabs.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } default-run = "aptos-comparison-testing" [dependencies] diff --git a/aptos-move/aptos-e2e-comparison-testing/src/data_collection.rs b/aptos-move/aptos-e2e-comparison-testing/src/data_collection.rs index 4cb63d52a47..9f177251418 100644 --- a/aptos-move/aptos-e2e-comparison-testing/src/data_collection.rs +++ b/aptos-move/aptos-e2e-comparison-testing/src/data_collection.rs @@ -12,8 +12,8 @@ use aptos_rest_client::Client; use aptos_types::{ state_store::{state_key::StateKey, state_value::StateValue, TStateView}, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, Transaction, - TransactionOutput, Version, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, + PersistedAuxiliaryInfo, Transaction, TransactionOutput, Version, }, write_set::TOTAL_SUPPLY_STATE_KEY, }; @@ -84,6 +84,7 @@ impl DataCollection { fn execute_transactions_at_version_with_state_view( txns: Vec, + auxiliary_infos: Vec, debugger_state_view: &DataStateView, ) -> Result> { let sig_verified_txns: Vec = @@ -93,7 +94,14 @@ impl DataCollection { // FIXME(#10412): remove the assert let val = debugger_state_view.get_state_value(TOTAL_SUPPLY_STATE_KEY.deref()); assert!(val.is_ok() && val.unwrap().is_some()); - let txn_provider = DefaultTxnProvider::new(sig_verified_txns); + + // Convert persisted auxiliary info to auxiliary info for execution + let auxiliary_infos = auxiliary_infos + .into_iter() + .map(|persisted_aux_info| AuxiliaryInfo::new(persisted_aux_info, None)) + .collect::>(); + + let txn_provider = DefaultTxnProvider::new(sig_verified_txns, auxiliary_infos); AptosVMBlockExecutor::new() .execute_block_no_limit(&txn_provider, debugger_state_view) .map_err(|err| format_err!("Unexpected VM Error: {:?}", err)) @@ -210,9 +218,27 @@ impl DataCollection { DataStateView::new_with_data_reads(self.debugger.clone(), version); let txn_execution_thread = tokio::task::spawn_blocking(move || { + // Get auxiliary info for this transaction from the debugger + let aux_info = tokio::runtime::Handle::current().block_on(async { + match state_view + .debugger() + .get_committed_transactions(version, 1) + .await + { + Ok((_, _, mut aux_infos)) => { + aux_infos.pop().unwrap_or(PersistedAuxiliaryInfo::None) + }, + Err(_) => { + // Fallback to default auxiliary info if not found + PersistedAuxiliaryInfo::None + }, + } + }); + let epoch_result_res = Self::execute_transactions_at_version_with_state_view( vec![txn.clone()], + vec![aux_info], &state_view, ); if let Err(err) = epoch_result_res { diff --git a/aptos-move/aptos-e2e-comparison-testing/src/data_state_view.rs b/aptos-move/aptos-e2e-comparison-testing/src/data_state_view.rs index 7037beb31ba..b9afce304fd 100644 --- a/aptos-move/aptos-e2e-comparison-testing/src/data_state_view.rs +++ b/aptos-move/aptos-e2e-comparison-testing/src/data_state_view.rs @@ -18,6 +18,7 @@ use std::{ pub struct DataStateView { debugger_view: DebuggerStateView, + debugger: Arc, code_data: Option, data_read_state_keys: Option>>>, } @@ -29,7 +30,8 @@ impl DataStateView { code_data: InMemoryStateStore, ) -> Self { Self { - debugger_view: DebuggerStateView::new(db, version), + debugger_view: DebuggerStateView::new(db.clone(), version), + debugger: db, code_data: Some(code_data), data_read_state_keys: None, } @@ -40,7 +42,8 @@ impl DataStateView { version: Version, ) -> Self { Self { - debugger_view: DebuggerStateView::new(db, version), + debugger_view: DebuggerStateView::new(db.clone(), version), + debugger: db, code_data: None, data_read_state_keys: Some(Arc::new(Mutex::new(HashMap::new()))), } @@ -49,6 +52,10 @@ impl DataStateView { pub fn get_state_keys(self) -> Arc>> { self.data_read_state_keys.unwrap() } + + pub fn debugger(&self) -> &Arc { + &self.debugger + } } impl TStateView for DataStateView { diff --git a/aptos-move/aptos-e2e-comparison-testing/src/execution.rs b/aptos-move/aptos-e2e-comparison-testing/src/execution.rs index 48b721b7013..a19ea84b20b 100644 --- a/aptos-move/aptos-e2e-comparison-testing/src/execution.rs +++ b/aptos-move/aptos-e2e-comparison-testing/src/execution.rs @@ -162,8 +162,8 @@ impl Execution { while ver_res.is_err() { ver_res = index_reader.get_next_version(); } - if ver_res.is_ok() { - if let Some(ver) = ver_res.unwrap() { + if let Ok(ver) = ver_res { + if let Some(ver) = ver { cur_version = ver; } else { break; @@ -365,7 +365,7 @@ impl Execution { // Update features if needed to the correct binary format used by V2 compiler. let mut features = Features::fetch_config(&state).unwrap_or_default(); if v2_flag { - features.enable(FeatureFlag::VM_BINARY_FORMAT_V8); + features.enable(FeatureFlag::VM_BINARY_FORMAT_V9); } else { features.enable(FeatureFlag::VM_BINARY_FORMAT_V6); } diff --git a/aptos-move/aptos-e2e-comparison-testing/src/lib.rs b/aptos-move/aptos-e2e-comparison-testing/src/lib.rs index f4135e475c0..ada3193fc5a 100644 --- a/aptos-move/aptos-e2e-comparison-testing/src/lib.rs +++ b/aptos-move/aptos-e2e-comparison-testing/src/lib.rs @@ -69,12 +69,11 @@ impl IndexWriter { pub fn new(root: &Path) -> Self { let create_file = |file_name: &str| -> File { let path = root.to_path_buf().join(file_name); - let file = if !path.exists() { + if !path.exists() { File::create(path).expect("Error encountered while creating file!") } else { OpenOptions::new().append(true).open(path).unwrap() - }; - file + } }; let index_file = create_file(INDEX_FILE); let err_log = create_file(ERR_LOG); @@ -485,7 +484,7 @@ fn dump_and_compile_from_package_metadata( File::create(module_path.clone()).expect("Error encountered while creating file!"); }; let source_str = unzip_metadata_str(&module.source).unwrap(); - std::fs::write(&module_path.clone(), source_str).unwrap(); + std::fs::write(module_path.clone(), source_str).unwrap(); } // step 2: unzip, parse the manifest file diff --git a/aptos-move/aptos-gas-calibration/Cargo.toml b/aptos-move/aptos-gas-calibration/Cargo.toml index b2375eaccde..1f20da3100a 100644 --- a/aptos-move/aptos-gas-calibration/Cargo.toml +++ b/aptos-move/aptos-gas-calibration/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "aptos-gas-calibration" version = "0.1.0" -edition = "2021" +edition = { workspace = true } license = { workspace = true } [dependencies] diff --git a/aptos-move/aptos-gas-meter/src/algebra.rs b/aptos-move/aptos-gas-meter/src/algebra.rs index c7673901966..95e55a74a5c 100644 --- a/aptos-move/aptos-gas-meter/src/algebra.rs +++ b/aptos-move/aptos-gas-meter/src/algebra.rs @@ -107,28 +107,6 @@ where } } -impl StandardGasAlgebra<'_, T> -where - T: BlockSynchronizationKillSwitch, -{ - fn charge(&mut self, amount: InternalGas) -> (InternalGas, PartialVMResult<()>) { - match self.balance.checked_sub(amount) { - Some(new_balance) => { - self.balance = new_balance; - (amount, Ok(())) - }, - None => { - let old_balance = self.balance; - self.balance = 0.into(); - ( - old_balance, - Err(PartialVMError::new(StatusCode::OUT_OF_GAS)), - ) - }, - } - } -} - impl GasAlgebra for StandardGasAlgebra<'_, T> where T: BlockSynchronizationKillSwitch, @@ -141,6 +119,10 @@ where &self.vm_gas_params } + fn storage_gas_params(&self) -> &StorageGasParameters { + &self.storage_gas_params + } + fn io_pricing(&self) -> &IoPricing { &self.storage_gas_params.io_pricing } @@ -187,6 +169,7 @@ where Ok(()) } + #[inline(always)] fn charge_execution( &mut self, abstract_amount: impl GasExpression + Debug, @@ -203,15 +186,21 @@ where let amount = abstract_amount.evaluate(self.feature_version, &self.vm_gas_params); - let (actual, res) = self.charge(amount); - if self.feature_version >= 12 { - self.execution_gas_used += actual; - } - res?; + match self.balance.checked_sub(amount) { + Some(new_balance) => { + self.balance = new_balance; + self.execution_gas_used += amount; + }, + None => { + let old_balance = self.balance; + self.balance = 0.into(); + if self.feature_version >= 12 { + self.execution_gas_used += old_balance; + } + return Err(PartialVMError::new(StatusCode::OUT_OF_GAS)); + }, + }; - if self.feature_version < 12 { - self.execution_gas_used += amount; - } if self.feature_version >= 7 && self.execution_gas_used > self.max_execution_gas { Err(PartialVMError::new(StatusCode::EXECUTION_LIMIT_REACHED)) } else { @@ -225,15 +214,21 @@ where ) -> PartialVMResult<()> { let amount = abstract_amount.evaluate(self.feature_version, &self.vm_gas_params); - let (actual, res) = self.charge(amount); - if self.feature_version >= 12 { - self.io_gas_used += actual; - } - res?; + match self.balance.checked_sub(amount) { + Some(new_balance) => { + self.balance = new_balance; + self.io_gas_used += amount; + }, + None => { + let old_balance = self.balance; + self.balance = 0.into(); + if self.feature_version >= 12 { + self.io_gas_used += old_balance; + } + return Err(PartialVMError::new(StatusCode::OUT_OF_GAS)); + }, + }; - if self.feature_version < 12 { - self.io_gas_used += amount; - } if self.feature_version >= 7 && self.io_gas_used > self.max_io_gas { Err(PartialVMError::new(StatusCode::IO_LIMIT_REACHED)) } else { @@ -278,17 +273,23 @@ where }, ); - let (actual, res) = self.charge(gas_consumed_internal); - if self.feature_version >= 12 { - self.storage_fee_in_internal_units += actual; - self.storage_fee_used += amount; - } - res?; + match self.balance.checked_sub(gas_consumed_internal) { + Some(new_balance) => { + self.balance = new_balance; + self.storage_fee_in_internal_units += gas_consumed_internal; + self.storage_fee_used += amount; + }, + None => { + let old_balance = self.balance; + self.balance = 0.into(); + if self.feature_version >= 12 { + self.storage_fee_in_internal_units += old_balance; + self.storage_fee_used += amount; + } + return Err(PartialVMError::new(StatusCode::OUT_OF_GAS)); + }, + }; - if self.feature_version < 12 { - self.storage_fee_in_internal_units += gas_consumed_internal; - self.storage_fee_used += amount; - } if self.feature_version >= 7 && self.storage_fee_used > self.max_storage_fee { return Err(PartialVMError::new(StatusCode::STORAGE_LIMIT_REACHED)); } diff --git a/aptos-move/aptos-gas-meter/src/lib.rs b/aptos-move/aptos-gas-meter/src/lib.rs index 3c8b890a56e..503380d191f 100644 --- a/aptos-move/aptos-gas-meter/src/lib.rs +++ b/aptos-move/aptos-gas-meter/src/lib.rs @@ -10,4 +10,4 @@ mod traits; pub use algebra::StandardGasAlgebra; pub use meter::StandardGasMeter; -pub use traits::{AptosGasMeter, GasAlgebra}; +pub use traits::{AptosGasMeter, CacheValueSizes, GasAlgebra}; diff --git a/aptos-move/aptos-gas-meter/src/meter.rs b/aptos-move/aptos-gas-meter/src/meter.rs index 379a2d39108..b66e3cf0f4d 100644 --- a/aptos-move/aptos-gas-meter/src/meter.rs +++ b/aptos-move/aptos-gas-meter/src/meter.rs @@ -1,8 +1,11 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::traits::{AptosGasMeter, GasAlgebra}; -use aptos_gas_algebra::{Fee, FeePerGasUnit, NumTypeNodes}; +use crate::{ + traits::{AptosGasMeter, GasAlgebra}, + CacheValueSizes, +}; +use aptos_gas_algebra::{AbstractValueSize, Fee, FeePerGasUnit, NumTypeNodes}; use aptos_gas_schedule::{ gas_feature_versions::*, gas_params::{instr::*, txn::*}, @@ -22,7 +25,7 @@ use move_core_types::{ vm_status::StatusCode, }; use move_vm_types::{ - gas::{DependencyGasMeter, GasMeter, NativeGasMeter, SimpleInstruction}, + gas::{DependencyGasMeter, DependencyKind, GasMeter, NativeGasMeter, SimpleInstruction}, views::{TypeView, ValueView}, }; @@ -53,7 +56,7 @@ where #[inline] fn charge_dependency( &mut self, - _is_new: bool, + _kind: DependencyKind, addr: &AccountAddress, _name: &IdentStr, size: NumBytes, @@ -137,6 +140,14 @@ where LdU64 => LD_U64, LdU128 => LD_U128, LdU256 => LD_U256, + + LdI8 => LD_I8, + LdI16 => LD_I16, + LdI32 => LD_I32, + LdI64 => LD_I64, + LdI128 => LD_I128, + LdI256 => LD_I256, + LdTrue => LD_TRUE, LdFalse => LD_FALSE, @@ -162,11 +173,19 @@ where CastU128 => CAST_U128, CastU256 => CAST_U256, + CastI8 => CAST_I8, + CastI16 => CAST_I16, + CastI32 => CAST_I32, + CastI64 => CAST_I64, + CastI128 => CAST_I128, + CastI256 => CAST_I256, + Add => ADD, Sub => SUB, Mul => MUL, Mod => MOD_, Div => DIV, + Negate => NEGATE, BitOr => BIT_OR, BitAnd => BIT_AND, @@ -288,9 +307,7 @@ where .abs_val .abstract_value_size_stack_and_heap(val, self.feature_version())?; - // Note(Gas): this makes a deep copy so we need to charge for the full value size - self.algebra - .charge_execution(COPY_LOC_BASE + COPY_LOC_PER_ABS_VAL_UNIT * (stack_size + heap_size)) + self.charge_copy_loc_cached(stack_size, heap_size) } #[inline] @@ -339,6 +356,24 @@ where } } + #[inline] + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let num_args = NumArgs::new(args.len() as u64); + + match is_generic { + false => self + .algebra + .charge_execution(PACK_CLOSURE_BASE + PACK_CLOSURE_PER_ARG * num_args), + true => self.algebra.charge_execution( + PACK_CLOSURE_GENERIC_BASE + PACK_CLOSURE_GENERIC_PER_ARG * num_args, + ), + } + } + #[inline] fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()> { let (stack_size, heap_size) = self @@ -347,9 +382,7 @@ where .abs_val .abstract_value_size_stack_and_heap(val, self.feature_version())?; - // Note(Gas): this makes a deep copy so we need to charge for the full value size - self.algebra - .charge_execution(READ_REF_BASE + READ_REF_PER_ABS_VAL_UNIT * (stack_size + heap_size)) + self.charge_read_ref_cached(stack_size, heap_size) } #[inline] @@ -448,9 +481,8 @@ where } #[inline] - fn charge_vec_pack<'a>( + fn charge_vec_pack( &mut self, - _ty: impl TypeView + 'a, args: impl ExactSizeIterator, ) -> PartialVMResult<()> { let num_args = NumArgs::new(args.len() as u64); @@ -462,7 +494,6 @@ where #[inline] fn charge_vec_unpack( &mut self, - _ty: impl TypeView, expect_num_elements: NumArgs, _elems: impl ExactSizeIterator, ) -> PartialVMResult<()> { @@ -471,17 +502,12 @@ where } #[inline] - fn charge_vec_len(&mut self, _ty: impl TypeView) -> PartialVMResult<()> { + fn charge_vec_len(&mut self) -> PartialVMResult<()> { self.algebra.charge_execution(VEC_LEN_BASE) } #[inline] - fn charge_vec_borrow( - &mut self, - is_mut: bool, - _ty: impl TypeView, - _is_success: bool, - ) -> PartialVMResult<()> { + fn charge_vec_borrow(&mut self, is_mut: bool) -> PartialVMResult<()> { match is_mut { false => self.algebra.charge_execution(VEC_IMM_BORROW_BASE), true => self.algebra.charge_execution(VEC_MUT_BORROW_BASE), @@ -489,25 +515,17 @@ where } #[inline] - fn charge_vec_push_back( - &mut self, - _ty: impl TypeView, - _val: impl ValueView, - ) -> PartialVMResult<()> { + fn charge_vec_push_back(&mut self, _val: impl ValueView) -> PartialVMResult<()> { self.algebra.charge_execution(VEC_PUSH_BACK_BASE) } #[inline] - fn charge_vec_pop_back( - &mut self, - _ty: impl TypeView, - _val: Option, - ) -> PartialVMResult<()> { + fn charge_vec_pop_back(&mut self, _val: Option) -> PartialVMResult<()> { self.algebra.charge_execution(VEC_POP_BACK_BASE) } #[inline] - fn charge_vec_swap(&mut self, _ty: impl TypeView) -> PartialVMResult<()> { + fn charge_vec_swap(&mut self) -> PartialVMResult<()> { self.algebra.charge_execution(VEC_SWAP_BASE) } @@ -600,3 +618,29 @@ where .map_err(|e| e.finish(Location::Undefined)) } } + +impl CacheValueSizes for StandardGasMeter +where + A: GasAlgebra, +{ + #[inline] + fn charge_read_ref_cached( + &mut self, + stack_size: AbstractValueSize, + heap_size: AbstractValueSize, + ) -> PartialVMResult<()> { + self.algebra + .charge_execution(READ_REF_BASE + READ_REF_PER_ABS_VAL_UNIT * (stack_size + heap_size)) + } + + #[inline] + fn charge_copy_loc_cached( + &mut self, + stack_size: AbstractValueSize, + heap_size: AbstractValueSize, + ) -> PartialVMResult<()> { + // Note(Gas): this makes a deep copy so we need to charge for the full value size + self.algebra + .charge_execution(COPY_LOC_BASE + COPY_LOC_PER_ABS_VAL_UNIT * (stack_size + heap_size)) + } +} diff --git a/aptos-move/aptos-gas-meter/src/traits.rs b/aptos-move/aptos-gas-meter/src/traits.rs index a18e66127d5..35f5dd05b94 100644 --- a/aptos-move/aptos-gas-meter/src/traits.rs +++ b/aptos-move/aptos-gas-meter/src/traits.rs @@ -1,7 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_gas_algebra::{Fee, FeePerGasUnit, Gas, GasExpression, GasScalingFactor, Octa}; +use aptos_gas_algebra::{ + AbstractValueSize, Fee, FeePerGasUnit, Gas, GasExpression, GasScalingFactor, Octa, +}; use aptos_gas_schedule::{gas_feature_versions::RELEASE_V1_30, VMGasParameters}; use aptos_types::{ contract_event::ContractEvent, state_store::state_key::StateKey, write_set::WriteOpSize, @@ -13,6 +15,7 @@ use aptos_vm_types::{ storage::{ io_pricing::IoPricing, space_pricing::{ChargeAndRefund, DiskSpacePricing}, + StorageGasParameters, }, }; use move_binary_format::errors::{Location, PartialVMResult, VMResult}; @@ -26,9 +29,12 @@ pub trait GasAlgebra { /// Returns the gas feature version. fn feature_version(&self) -> u64; - /// Returns the struct containing all (regular) gas parameters. + /// Returns the struct containing all (non-storage) gas parameters. fn vm_gas_params(&self) -> &VMGasParameters; + /// Returns the struct containing all (storage) gas parameters. + fn storage_gas_params(&self) -> &StorageGasParameters; + /// Returns the struct containing the storage-specific gas parameters. fn io_pricing(&self) -> &IoPricing; @@ -264,3 +270,17 @@ pub trait AptosGasMeter: MoveGasMeter { .map_err(|e| e.finish(Location::Undefined)) } } + +pub trait CacheValueSizes: AptosGasMeter { + fn charge_read_ref_cached( + &mut self, + stack_size: AbstractValueSize, + heap_size: AbstractValueSize, + ) -> PartialVMResult<()>; + + fn charge_copy_loc_cached( + &mut self, + stack_size: AbstractValueSize, + heap_size: AbstractValueSize, + ) -> PartialVMResult<()>; +} diff --git a/aptos-move/aptos-gas-profiling/src/aggregate.rs b/aptos-move/aptos-gas-profiling/src/aggregate.rs index 5c9b23f6320..3a2b6234fbc 100644 --- a/aptos-move/aptos-gas-profiling/src/aggregate.rs +++ b/aptos-move/aptos-gas-profiling/src/aggregate.rs @@ -2,10 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + erased::Node, log::{ExecutionAndIOCosts, ExecutionGasEvent}, render::{Render, TableKey}, }; -use aptos_gas_algebra::{GasQuantity, GasScalingFactor, InternalGas}; +use aptos_gas_algebra::{GasQuantity, GasScalingFactor, InternalGas, InternalGasUnit}; use std::collections::{btree_map, BTreeMap}; /// Represents an aggregation of execution gas events, including the count and total gas costs for each type of event. @@ -22,6 +23,8 @@ pub struct AggregatedExecutionGasEvents { // TODO: Make this more strongly typed? pub ops: Vec<(String, usize, InternalGas)>, + pub methods: Vec<(String, usize, InternalGas)>, + pub methods_self: Vec<(String, usize, InternalGas)>, pub transaction_write: InternalGas, pub event_writes: Vec<(String, usize, InternalGas)>, pub storage_reads: Vec<(String, usize, InternalGas)>, @@ -126,11 +129,19 @@ impl ExecutionAndIOCosts { insert_or_add(&mut storage_writes, key, write.cost); } + let tree = self.to_erased(false).tree; + let mut methods = BTreeMap::new(); + compute_method_recursive_cost(&tree, &mut methods); + let mut methods_self = BTreeMap::new(); + compute_method_self_cost(&tree, &mut methods_self); + AggregatedExecutionGasEvents { gas_scaling_factor: self.gas_scaling_factor, total: self.total, ops: into_sorted_vec(ops), + methods: into_sorted_vec(methods), + methods_self: into_sorted_vec(methods_self), transaction_write: self.transaction_transient.unwrap_or_else(|| 0.into()), event_writes: into_sorted_vec(event_writes), storage_reads: into_sorted_vec(storage_reads), @@ -138,3 +149,35 @@ impl ExecutionAndIOCosts { } } } + +fn compute_method_recursive_cost( + node: &Node>, + methods: &mut BTreeMap)>, +) -> GasQuantity { + let mut sum = node.val; + for child in &node.children { + sum += compute_method_recursive_cost(child, methods); + } + + if !node.children.is_empty() { + insert_or_add(methods, node.text.clone(), sum); + } + sum +} + +fn compute_method_self_cost( + node: &Node>, + methods: &mut BTreeMap)>, +) { + let mut sum = node.val; + for child in &node.children { + compute_method_self_cost(child, methods); + + // method invocation cost itself is counted to both parent and child. + sum += child.val; + } + + if !node.children.is_empty() { + insert_or_add(methods, node.text.clone(), sum); + } +} diff --git a/aptos-move/aptos-gas-profiling/src/erased.rs b/aptos-move/aptos-gas-profiling/src/erased.rs index df4da854f22..bca2aead539 100644 --- a/aptos-move/aptos-gas-profiling/src/erased.rs +++ b/aptos-move/aptos-gas-profiling/src/erased.rs @@ -129,13 +129,13 @@ impl Node { } impl ExecutionGasEvent { - fn to_erased(&self) -> Node { + fn to_erased(&self, keep_generic_types: bool) -> Node { use ExecutionGasEvent::*; match self { Loc(offset) => Node::new(format!("@{}", offset), 0), Bytecode { op, cost } => Node::new(format!("{:?}", op).to_ascii_lowercase(), *cost), - Call(frame) => frame.to_erased(), + Call(frame) => frame.to_erased(keep_generic_types), CallNative { module_id, fn_name, @@ -144,7 +144,15 @@ impl ExecutionGasEvent { } => Node::new( format!( "{}", - Render(&(module_id, fn_name.as_ident_str(), ty_args.as_slice())) + Render(&( + module_id, + fn_name.as_ident_str(), + if keep_generic_types { + ty_args.as_slice() + } else { + &[] + } + )) ), *cost, ), @@ -158,9 +166,10 @@ impl ExecutionGasEvent { } impl CallFrame { - fn to_erased(&self) -> Node { + fn to_erased(&self, keep_generic_types: bool) -> Node { let name = match &self.name { FrameName::Script => "script".to_string(), + FrameName::TransactionBatch => "transaction batch".to_string(), FrameName::Function { module_id, name, @@ -168,7 +177,15 @@ impl CallFrame { } => { format!( "{}", - Render(&(module_id, name.as_ident_str(), ty_args.as_slice())) + Render(&( + module_id, + name.as_ident_str(), + if keep_generic_types { + ty_args.as_slice() + } else { + &[] + } + )) ) }, }; @@ -176,7 +193,7 @@ impl CallFrame { let children = self .events .iter() - .map(|event| event.to_erased()) + .map(|event| event.to_erased(keep_generic_types)) .collect::>(); Node::new_with_children(name, 0, children) @@ -200,20 +217,13 @@ impl WriteTransient { impl Dependency { fn to_erased(&self) -> Node { - Node::new( - format!( - "{}{}", - Render(&self.id), - if self.is_new { " (new)" } else { "" } - ), - self.cost, - ) + Node::new(self.render(), self.cost) } } impl ExecutionAndIOCosts { /// Convert the gas log into a type-erased representation. - pub fn to_erased(&self) -> TypeErasedExecutionAndIoCosts { + pub fn to_erased(&self, keep_generic_types: bool) -> TypeErasedExecutionAndIoCosts { let mut nodes = vec![]; nodes.push(Node::new("intrinsic", self.intrinsic_cost)); @@ -229,7 +239,7 @@ impl ExecutionAndIOCosts { nodes.push(deps); } - nodes.push(self.call_graph.to_erased()); + nodes.push(self.call_graph.to_erased(keep_generic_types)); nodes.push(self.ledger_writes()); @@ -304,9 +314,9 @@ impl StorageFees { impl TransactionGasLog { /// Convert the gas log into a type-erased representation. - pub fn to_erased(&self) -> TypeErasedGasLog { + pub fn to_erased(&self, keep_generic_types: bool) -> TypeErasedGasLog { TypeErasedGasLog { - exec_io: self.exec_io.to_erased(), + exec_io: self.exec_io.to_erased(keep_generic_types), storage: self.storage.to_erased(), } } diff --git a/aptos-move/aptos-gas-profiling/src/flamegraph.rs b/aptos-move/aptos-gas-profiling/src/flamegraph.rs index c2459f8341e..4f3bcae8770 100644 --- a/aptos-move/aptos-gas-profiling/src/flamegraph.rs +++ b/aptos-move/aptos-gas-profiling/src/flamegraph.rs @@ -115,11 +115,7 @@ impl ExecutionAndIOCosts { for dep in &self.dependencies { lines.push( - format!( - "dependencies;{}{}", - Render(&dep.id), - if dep.is_new { "(new)" } else { "" } - ), + format!("dependencies;{}", dep.render().trim_start(),), dep.cost, ) } @@ -162,7 +158,7 @@ impl ExecutionAndIOCosts { } } - self.lines.push(&self.path(), frame_cost); + self.lines.push(self.path(), frame_cost); self.path.pop(); } diff --git a/aptos-move/aptos-gas-profiling/src/lib.rs b/aptos-move/aptos-gas-profiling/src/lib.rs index 6cf93525dfc..c09c5ef8470 100644 --- a/aptos-move/aptos-gas-profiling/src/lib.rs +++ b/aptos-move/aptos-gas-profiling/src/lib.rs @@ -9,6 +9,7 @@ mod misc; mod profiler; mod render; mod report; +mod unique_stack; pub use log::{FrameName, TransactionGasLog}; pub use profiler::GasProfiler; diff --git a/aptos-move/aptos-gas-profiling/src/log.rs b/aptos-move/aptos-gas-profiling/src/log.rs index b198d273536..b0ef32fc6c0 100644 --- a/aptos-move/aptos-gas-profiling/src/log.rs +++ b/aptos-move/aptos-gas-profiling/src/log.rs @@ -1,6 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use crate::render::Render; use aptos_gas_algebra::{Fee, GasScalingFactor, InternalGas, NumBytes}; use aptos_types::state_store::state_key::StateKey; use move_binary_format::{file_format::CodeOffset, file_format_common::Opcodes}; @@ -9,6 +10,7 @@ use move_core_types::{ identifier::Identifier, language_storage::{ModuleId, TypeTag}, }; +use move_vm_types::gas::DependencyKind; use smallvec::{smallvec, SmallVec}; /// An event occurred during the execution of a function, along with the @@ -42,7 +44,7 @@ pub enum ExecutionGasEvent { /// An enum representing the name of a call frame. /// Could be either a script or a function. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum FrameName { Script, Function { @@ -50,6 +52,7 @@ pub enum FrameName { name: Identifier, ty_args: Vec, }, + TransactionBatch, } /// A struct containing information about a function call, including the name of the @@ -106,12 +109,22 @@ pub struct EventStorage { #[derive(Debug, Clone)] /// Struct representing the cost of a dependency. pub struct Dependency { - pub is_new: bool, + pub kind: DependencyKind, pub id: ModuleId, pub size: NumBytes, pub cost: InternalGas, } +impl Dependency { + pub(crate) fn render(&self) -> String { + let kind = match self.kind { + DependencyKind::New => " (new)", + DependencyKind::Existing => "", + }; + format!("{}{}", Render(&self.id), kind,) + } +} + /// Struct containing all execution and io costs. #[derive(Debug, Clone)] pub struct ExecutionAndIOCosts { @@ -145,8 +158,8 @@ pub struct StorageFees { pub struct TransactionGasLog { pub exec_io: ExecutionAndIOCosts, pub storage: StorageFees, + pub num_txns: usize, } - pub struct GasEventIter<'a> { stack: SmallVec<[(&'a CallFrame, usize); 16]>, } @@ -196,6 +209,14 @@ impl CallFrame { native_gas: 0.into(), } } + + pub fn new_transaction_batch() -> Self { + Self { + name: FrameName::TransactionBatch, + events: vec![], + native_gas: 0.into(), + } + } } impl StorageFees { diff --git a/aptos-move/aptos-gas-profiling/src/profiler.rs b/aptos-move/aptos-gas-profiling/src/profiler.rs index 87433532c79..e5d54391a19 100644 --- a/aptos-move/aptos-gas-profiling/src/profiler.rs +++ b/aptos-move/aptos-gas-profiling/src/profiler.rs @@ -26,7 +26,7 @@ use move_core_types::{ language_storage::{ModuleId, TypeTag}, }; use move_vm_types::{ - gas::{DependencyGasMeter, GasMeter, NativeGasMeter, SimpleInstruction}, + gas::{DependencyGasMeter, DependencyKind, GasMeter, NativeGasMeter, SimpleInstruction}, views::{TypeView, ValueView}, }; @@ -164,17 +164,17 @@ where { fn charge_dependency( &mut self, - is_new: bool, + kind: DependencyKind, addr: &AccountAddress, name: &IdentStr, size: NumBytes, ) -> PartialVMResult<()> { let (cost, res) = - self.delegate_charge(|base| base.charge_dependency(is_new, addr, name, size)); + self.delegate_charge(|base| base.charge_dependency(kind, addr, name, size)); if !cost.is_zero() { self.dependencies.push(Dependency { - is_new, + kind, id: ModuleId::new(*addr, name.to_owned()), size, cost, @@ -267,6 +267,13 @@ where args: impl ExactSizeIterator + Clone, ) -> PartialVMResult<()>; + [PACK_CLOSURE] + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator + Clone, + ) -> PartialVMResult<()>; + [READ_REF] fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()>; @@ -327,45 +334,39 @@ where [VEC_PACK] fn charge_vec_pack<'a>( &mut self, - ty: impl TypeView + 'a, args: impl ExactSizeIterator + Clone, ) -> PartialVMResult<()>; [VEC_LEN] - fn charge_vec_len(&mut self, ty: impl TypeView) -> PartialVMResult<()>; + fn charge_vec_len(&mut self) -> PartialVMResult<()>; [VEC_IMM_BORROW] fn charge_vec_borrow( &mut self, is_mut: bool, - ty: impl TypeView, - is_success: bool, ) -> PartialVMResult<()>; [VEC_PUSH_BACK] fn charge_vec_push_back( &mut self, - ty: impl TypeView, val: impl ValueView, ) -> PartialVMResult<()>; [VEC_POP_BACK] fn charge_vec_pop_back( &mut self, - ty: impl TypeView, val: Option, ) -> PartialVMResult<()>; [VEC_UNPACK] fn charge_vec_unpack( &mut self, - ty: impl TypeView, expect_num_elements: NumArgs, elems: impl ExactSizeIterator + Clone, ) -> PartialVMResult<()>; [VEC_SWAP] - fn charge_vec_swap(&mut self, ty: impl TypeView) -> PartialVMResult<()>; + fn charge_vec_swap(&mut self) -> PartialVMResult<()>; } fn balance_internal(&self) -> InternalGas { @@ -398,7 +399,7 @@ where name, ty_args, } => (module_id, name, ty_args), - FrameName::Script => unreachable!(), + FrameName::Script | FrameName::TransactionBatch => unreachable!(), }; // The following line of code is needed for correctness. @@ -743,6 +744,10 @@ where }); storage.assert_consistency(); - TransactionGasLog { exec_io, storage } + TransactionGasLog { + exec_io, + storage, + num_txns: 1, + } } } diff --git a/aptos-move/aptos-gas-profiling/src/render.rs b/aptos-move/aptos-gas-profiling/src/render.rs index e19dc982f75..6ec60f0750c 100644 --- a/aptos-move/aptos-gas-profiling/src/render.rs +++ b/aptos-move/aptos-gas-profiling/src/render.rs @@ -58,6 +58,7 @@ impl Display for FrameName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Script => write!(f, " + + diff --git a/aptos-move/move-examples/my_first_dapp/frontend/package.json b/aptos-move/move-examples/my_first_dapp/frontend/package.json new file mode 100644 index 00000000000..6dbdc794a90 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/package.json @@ -0,0 +1,63 @@ +{ + "name": "boilerplate-template", + "private": true, + "version": "0.0.0", + "license": "Apache-2.0", + "scripts": { + "move:test": "node ./scripts/move/test", + "move:compile": "node ./scripts/move/compile", + "move:publish": "node ./scripts/move/publish", + "move:upgrade": "node ./scripts/move/upgrade", + "dev": "vite", + "build": "tsc && vite build", + "deploy": "vercel", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "_fmt": "prettier 'src/**/*.ts'", + "fmt": "npm run _fmt -- --write" + }, + "dependencies": { + "@aptos-labs/ts-sdk": "^2.0.0", + "@aptos-labs/wallet-adapter-react": "^6.0.1", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-toast": "^1.2.1", + "@radix-ui/react-slot": "^1.0.2", + "@tanstack/react-query": "^5.51.23", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "lucide-react": "^0.383.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.23.1", + "tailwind-merge": "^2.3.0", + "tailwindcss-animate": "^1.0.7", + "buffer": "^6.0.3", + "process": "^0.11.10", + "stream-browserify": "^3.0.0", + "util": "^0.12.5" + }, + "devDependencies": { + "@types/node": "^20.14.1", + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.6", + "postcss": "^8.4.38", + "prettier": "^3.3.2", + "tailwindcss": "^3.4.3", + "typescript": "^5.2.2", + "vite": "^5.2.0", + "vite-plugin-notifier": "^0.1.5", + "tree-kill": "1.2.2", + "dotenv": "16.3.1", + "vercel": "^35.2.4" + } +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/postcss.config.js b/aptos-move/move-examples/my_first_dapp/frontend/postcss.config.js new file mode 100644 index 00000000000..12a703d900d --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/aptos-move/move-examples/my_first_dapp/frontend/public/aptos.png b/aptos-move/move-examples/my_first_dapp/frontend/public/aptos.png new file mode 100644 index 00000000000..5aa7e657b48 Binary files /dev/null and b/aptos-move/move-examples/my_first_dapp/frontend/public/aptos.png differ diff --git a/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-192x192.png b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-192x192.png new file mode 100644 index 00000000000..0470cc31e51 Binary files /dev/null and b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-192x192.png differ diff --git a/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-384x384.png b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-384x384.png new file mode 100644 index 00000000000..259c8459b8c Binary files /dev/null and b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-384x384.png differ diff --git a/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-512x512.png b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-512x512.png new file mode 100644 index 00000000000..4a515d5f7b3 Binary files /dev/null and b/aptos-move/move-examples/my_first_dapp/frontend/public/icons/icon-512x512.png differ diff --git a/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/compile.js b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/compile.js new file mode 100644 index 00000000000..85eb236528c --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/compile.js @@ -0,0 +1,22 @@ +require("dotenv").config(); +const cli = require("@aptos-labs/ts-sdk/dist/common/cli/index.js"); + +async function compile() { + + if (!process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS) { + throw new Error( + "VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS variable is not set, make sure you have set the publisher account address", + ); + } + + const move = new cli.Move(); + + await move.compile({ + packageDirectoryPath: "contract", + namedAddresses: { + // Compile module with account address + todolist_addr: process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS, + }, + }); +} +compile(); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/publish.js b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/publish.js new file mode 100644 index 00000000000..dce609fea43 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/publish.js @@ -0,0 +1,58 @@ +require("dotenv").config(); +const fs = require("node:fs"); +const cli = require("@aptos-labs/ts-sdk/dist/common/cli/index.js"); +const aptosSDK = require("@aptos-labs/ts-sdk") + +async function publish() { + + if (!process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS) { + throw new Error( + "VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY variable is not set, make sure you have set the publisher account address", + ); + } + + if (!process.env.VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY) { + throw new Error( + "VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY variable is not set, make sure you have set the publisher account private key", + ); + } + + const move = new cli.Move(); + + move + .createObjectAndPublishPackage({ + packageDirectoryPath: "contract", + addressName: "todolist_addr", + namedAddresses: { + // Publish module to new object, but since we create the object on the fly, we fill in the publisher's account address here + todolist_addr: process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS, + }, + extraArguments: [`--private-key=${process.env.VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY}`,`--url=${aptosSDK.NetworkToNodeAPI[process.env.VITE_APP_NETWORK]}`], + }) + .then((response) => { + const filePath = ".env"; + let envContent = ""; + + // Check .env file exists and read it + if (fs.existsSync(filePath)) { + envContent = fs.readFileSync(filePath, "utf8"); + } + + // Regular expression to match the VITE_MODULE_ADDRESS variable + const regex = /^VITE_MODULE_ADDRESS=.*$/m; + const newEntry = `VITE_MODULE_ADDRESS=${response.objectAddress}`; + + // Check if VITE_MODULE_ADDRESS is already defined + if (envContent.match(regex)) { + // If the variable exists, replace it with the new value + envContent = envContent.replace(regex, newEntry); + } else { + // If the variable does not exist, append it + envContent += `\n${newEntry}`; + } + + // Write the updated content back to the .env file + fs.writeFileSync(filePath, envContent, "utf8"); + }); +} +publish(); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/test.js b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/test.js new file mode 100644 index 00000000000..d17cb60ccea --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/test.js @@ -0,0 +1,15 @@ +require("dotenv").config(); + +const cli = require("@aptos-labs/ts-sdk/dist/common/cli/index.js"); + +async function test() { + const move = new cli.Move(); + + await move.test({ + packageDirectoryPath: "contract", + namedAddresses: { + todolist_addr: process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS, + }, + }); +} +test(); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/upgrade.js b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/upgrade.js new file mode 100644 index 00000000000..4b52d277984 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/scripts/move/upgrade.js @@ -0,0 +1,24 @@ +require("dotenv").config(); +const cli = require("@aptos-labs/ts-sdk/dist/common/cli/index.js"); +const aptosSDK = require("@aptos-labs/ts-sdk") + +async function publish() { + if (!process.env.VITE_MODULE_ADDRESS) { + throw new Error( + "VITE_MODULE_ADDRESS variable is not set, make sure you have published the module before upgrading it", + ); + } + + const move = new cli.Move(); + + move.upgradeObjectPackage({ + packageDirectoryPath: "contract", + objectAddress: process.env.VITE_MODULE_ADDRESS, + namedAddresses: { + // Upgrade module from an object + todolist_addr: process.env.VITE_MODULE_PUBLISHER_ACCOUNT_ADDRESS, + }, + extraArguments: [`--private-key=${process.env.VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY}`,`--url=${aptosSDK.NetworkToNodeAPI[process.env.VITE_APP_NETWORK]}`], + }); +} +publish(); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/App.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/App.tsx new file mode 100644 index 00000000000..9d86c60b358 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/App.tsx @@ -0,0 +1,203 @@ +import { useEffect, useState } from "react" + +import { Header } from "@/components/Header"; +import { TopBanner } from "@/components/TopBanner"; +import { useWallet, InputTransactionData } from "@aptos-labs/wallet-adapter-react"; + +import { MODULE_ADDRESS } from "./constants"; +import { aptosClient } from "./utils/aptosClient"; +import { Button } from "./components/ui/button"; +import { Input } from "./components/ui/input"; + +const moduleAddress = MODULE_ADDRESS; + +type Task = { + address: string; + completed: boolean; + content: string; + task_id: string; +}; + +function App() { + const { account, signAndSubmitTransaction } = useWallet(); + + const [accountHasList, setAccountHasList] = useState(false); + const [transactionInProgress, setTransactionInProgress] = + useState(false); + const [tasks, setTasks] = useState([]); + const [newTask, setNewTask] = useState(""); + + useEffect(() => { + fetchList(); + }, [account?.address]); + + const fetchList = async () => { + if (!account) return []; + try { + const todoListResource = await aptosClient().getAccountResource({ + accountAddress:account?.address, + resourceType:`${moduleAddress}::todolist::TodoList` + }); + setAccountHasList(true); + // tasks table handle + const tableHandle = (todoListResource as any).tasks.handle; + // tasks table counter + const taskCounter = (todoListResource as any).task_counter; + + let tasks = []; + let counter = 1; + while (counter <= taskCounter) { + const tableItem = { + key_type: "u64", + value_type: `${moduleAddress}::todolist::Task`, + key: `${counter}`, + }; + const task = await aptosClient().getTableItem({handle:tableHandle, data:tableItem}); + tasks.push(task); + counter++; + } + // set tasks in local state + setTasks(tasks); + } catch (e: any) { + setAccountHasList(false); + } + }; + + const addNewList = async () => { + if (!account) return []; + + const transaction: InputTransactionData = { + data: { + function:`${moduleAddress}::todolist::create_list`, + functionArguments:[] + } + } + try { + // sign and submit transaction to chain + const response = await signAndSubmitTransaction(transaction); + // wait for transaction + await aptosClient().waitForTransaction({transactionHash:response.hash}); + setAccountHasList(true); + } catch (error: any) { + setAccountHasList(false); + } + }; + + const onTaskAdded = async () => { + // check for connected account + if (!account) return; + setTransactionInProgress(true); + const transaction: InputTransactionData = { + data: { + function: `${moduleAddress}::todolist::create_task`, + functionArguments: [newTask], + }, + }; + + // hold the latest task.task_id from our local state + const latestId = tasks.length > 0 ? parseInt(tasks[tasks.length - 1].task_id) + 1 : 1; + + // build a newTaskToPush object into our local state + const newTaskToPush: Task = { + address: account.address.toString(), + completed: false, + content: newTask, + task_id: latestId + "", + }; + + try { + // sign and submit transaction to chain + const response = await signAndSubmitTransaction(transaction); + // wait for transaction + await aptosClient().waitForTransaction({ transactionHash: response.hash }); + + // Create a new array based on current state: + let newTasks = [...tasks]; + + // Add item to the tasks array + newTasks.push(newTaskToPush); + // Set state + setTasks(newTasks); + // clear input text + setNewTask(""); + } catch (error: any) { + console.log("error", error); + } finally { + setTransactionInProgress(false); + } + }; + + const onCheckboxChange = async (event: React.ChangeEvent, taskId: string) => { + if (!account) return; + if (!event.target.checked) return; + setTransactionInProgress(true); + const transaction: InputTransactionData = { + data: { + function: `${moduleAddress}::todolist::complete_task`, + functionArguments: [taskId], + }, + }; + + try { + // sign and submit transaction to chain + const response = await signAndSubmitTransaction(transaction); + // wait for transaction + await aptosClient().waitForTransaction({ transactionHash: response.hash }); + + setTasks((prevState) => { + const newState = prevState.map((obj) => { + // if task_id equals the checked taskId, update completed property + if (obj.task_id === taskId) { + return { ...obj, completed: true }; + } + + // otherwise return object as is + return obj; + }); + + return newState; + }); + } catch (error: any) { + console.log("error", error); + } finally { + setTransactionInProgress(false); + } + }; + + return ( + <> + +
+
+ {!accountHasList ? ( + + ) : ( +
+
+ setNewTask(e.target.value)} /> + +
+ {tasks && + tasks.length > 0 && + tasks.map((task) => ( +
+

{task.content}

+
+ {task.completed ? ( + + ) : ( + onCheckboxChange(event, task.task_id)} /> + )} +
+
+ ))} +
+ )} +
+ + ); +} + +export default App; \ No newline at end of file diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/Header.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/Header.tsx new file mode 100644 index 00000000000..bc272e94780 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/Header.tsx @@ -0,0 +1,13 @@ +import { WalletSelector } from "./WalletSelector"; + +export function Header() { + return ( +
+

Boilerplate Template

+ +
+ +
+
+ ); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/TopBanner.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/TopBanner.tsx new file mode 100644 index 00000000000..ed034b97e2b --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/TopBanner.tsx @@ -0,0 +1,25 @@ +import { AlertTriangle } from "lucide-react"; + +export function TopBanner() { + return ( +
+ ); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletProvider.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletProvider.tsx new file mode 100644 index 00000000000..20c1a3a92ba --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletProvider.tsx @@ -0,0 +1,26 @@ +import { PropsWithChildren } from "react"; +import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react"; +// Internal components +import { useToast } from "@/components/ui/use-toast"; +// Internal constants +import { APTOS_API_KEY, NETWORK } from "@/constants"; + +export function WalletProvider({ children }: PropsWithChildren) { + const { toast } = useToast(); + + return ( + { + toast({ + variant: "destructive", + title: "Error", + description: error || "Unknown wallet error", + }); + }} + > + {children} + + ); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletSelector.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletSelector.tsx new file mode 100644 index 00000000000..cc3f492a068 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WalletSelector.tsx @@ -0,0 +1,239 @@ +import { + APTOS_CONNECT_ACCOUNT_URL, + AboutAptosConnect, + AboutAptosConnectEducationScreen, + AdapterWallet, + AdapterNotDetectedWallet, + AptosPrivacyPolicy, + WalletItem, + groupAndSortWallets, + isAptosConnectWallet, + isInstallRequired, + truncateAddress, + useWallet, +} from "@aptos-labs/wallet-adapter-react"; +import { ArrowLeft, ArrowRight, ChevronDown, Copy, LogOut, User } from "lucide-react"; +import { useCallback, useState } from "react"; +// Internal components +import { Button } from "@/components/ui/button"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { useToast } from "@/components/ui/use-toast"; + +export function WalletSelector() { + const { account, connected, disconnect, wallet } = useWallet(); + const { toast } = useToast(); + const [isDialogOpen, setIsDialogOpen] = useState(false); + + const closeDialog = useCallback(() => setIsDialogOpen(false), []); + + const copyAddress = useCallback(async () => { + if (!account?.address.toStringLong()) return; + try { + await navigator.clipboard.writeText(account.address.toStringLong()); + toast({ + title: "Success", + description: "Copied wallet address to clipboard.", + }); + } catch { + toast({ + variant: "destructive", + title: "Error", + description: "Failed to copy wallet address.", + }); + } + }, [account?.address, toast]); + + return connected ? ( + + + + + + + Copy address + + {wallet && isAptosConnectWallet(wallet) && ( + + + Account + + + )} + + Disconnect + + + + ) : ( + + + + + + + ); +} + +interface ConnectWalletDialogProps { + close: () => void; +} + +function ConnectWalletDialog({ close }: ConnectWalletDialogProps) { + const { wallets = [], notDetectedWallets = [] } = useWallet(); + const { aptosConnectWallets, availableWallets, installableWallets } = groupAndSortWallets([...wallets, ...notDetectedWallets]); + + const hasAptosConnectWallets = !!aptosConnectWallets.length; + + return ( + + + + + {hasAptosConnectWallets ? ( + <> + Log in or sign up + with Social + Aptos Connect + + ) : ( + "Connect Wallet" + )} + + + + {hasAptosConnectWallets && ( +
+ {aptosConnectWallets.map((wallet) => ( + + ))} +

+ Learn more about{" "} + + Aptos Connect + +

+ +

+ {" "} + + . +

+ +
+
+
+ Or +
+
+
+ )} + +
+ {availableWallets.map((wallet) => ( + + ))} + {!!installableWallets.length && ( + + + + + + {installableWallets.map((wallet) => ( + + ))} + + + )} +
+ + + ); +} + +interface WalletRowProps { + wallet: AdapterWallet | AdapterNotDetectedWallet; + onConnect?: () => void; +} + +function WalletRow({ wallet, onConnect }: WalletRowProps) { + return ( + +
+ + +
+ {isInstallRequired(wallet) ? ( + + ) : ( + + + + )} +
+ ); +} + +function AptosConnectWalletRow({ wallet, onConnect }: WalletRowProps) { + return ( + + + + + + ); +} + +function renderEducationScreen(screen: AboutAptosConnectEducationScreen) { + return ( + <> + + + About Aptos Connect + + +
+ +
+
+ + +
+ +
+ +
+ {screen.screenIndicators.map((ScreenIndicator, i) => ( + +
+ + ))} +
+ +
+ + ); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/WrongNetworkAlert.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WrongNetworkAlert.tsx new file mode 100644 index 00000000000..15d9d257d07 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/WrongNetworkAlert.tsx @@ -0,0 +1,28 @@ +import { NETWORK } from "@/constants"; +import { useWallet } from "@aptos-labs/wallet-adapter-react"; +import * as Dialog from "@radix-ui/react-dialog"; + +export function WrongNetworkAlert() { + const { network, connected } = useWallet(); + + return !connected || network?.name === NETWORK ? ( + <> + ) : ( + + + + +
+ + Wrong Network + + + Your wallet is currently on {network?.name}. Please switch to{" "} + {NETWORK} to continue using the app. + +
+
+
+
+ ); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/button.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/button.tsx new file mode 100644 index 00000000000..2608ba5c38c --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/button.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 gap-1", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + green: + "focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + icon: "border bg-background hover:bg-accent hover:text-accent-foreground", + }, + size: { + default: "h-10 px-4 py-2 rounded-md", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10 rounded-full", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/collapsible.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/collapsible.tsx new file mode 100644 index 00000000000..a23e7a28128 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/collapsible.tsx @@ -0,0 +1,9 @@ +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" + +const Collapsible = CollapsiblePrimitive.Root + +const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger + +const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dialog.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dialog.tsx new file mode 100644 index 00000000000..c23630eb841 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dialog.tsx @@ -0,0 +1,120 @@ +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dropdown-menu.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dropdown-menu.tsx new file mode 100644 index 00000000000..769ff7aa709 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,198 @@ +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/input.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/input.tsx new file mode 100644 index 00000000000..677d05fd6c1 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toast.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toast.tsx new file mode 100644 index 00000000000..a8224775341 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toast.tsx @@ -0,0 +1,127 @@ +import * as React from "react" +import * as ToastPrimitives from "@radix-ui/react-toast" +import { cva, type VariantProps } from "class-variance-authority" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const ToastProvider = ToastPrimitives.Provider + +const ToastViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastViewport.displayName = ToastPrimitives.Viewport.displayName + +const toastVariants = cva( + "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", + { + variants: { + variant: { + default: "border bg-background text-foreground", + destructive: + "destructive group border-destructive bg-destructive text-destructive-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Toast = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, ...props }, ref) => { + return ( + + ) +}) +Toast.displayName = ToastPrimitives.Root.displayName + +const ToastAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastAction.displayName = ToastPrimitives.Action.displayName + +const ToastClose = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +ToastClose.displayName = ToastPrimitives.Close.displayName + +const ToastTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastTitle.displayName = ToastPrimitives.Title.displayName + +const ToastDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastDescription.displayName = ToastPrimitives.Description.displayName + +type ToastProps = React.ComponentPropsWithoutRef + +type ToastActionElement = React.ReactElement + +export { + type ToastProps, + type ToastActionElement, + ToastProvider, + ToastViewport, + Toast, + ToastTitle, + ToastDescription, + ToastClose, + ToastAction, +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toaster.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toaster.tsx new file mode 100644 index 00000000000..a2209ba5866 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/toaster.tsx @@ -0,0 +1,33 @@ +import { + Toast, + ToastClose, + ToastDescription, + ToastProvider, + ToastTitle, + ToastViewport, +} from "@/components/ui/toast" +import { useToast } from "@/components/ui/use-toast" + +export function Toaster() { + const { toasts } = useToast() + + return ( + + {toasts.map(function ({ id, title, description, action, ...props }) { + return ( + +
+ {title && {title}} + {description && ( + {description} + )} +
+ {action} + +
+ ) + })} + +
+ ) +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/use-toast.ts b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/use-toast.ts new file mode 100644 index 00000000000..9831bce67d4 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/components/ui/use-toast.ts @@ -0,0 +1,187 @@ +// Inspired by react-hot-toast library +import * as React from "react"; + +import type { ToastActionElement, ToastProps } from "@/components/ui/toast"; + +const TOAST_LIMIT = 1; +const TOAST_REMOVE_DELAY = 1000000; + +type ToasterToast = ToastProps & { + id: string; + title?: React.ReactNode; + description?: React.ReactNode; + action?: ToastActionElement; +}; + +const actionTypes = { + ADD_TOAST: "ADD_TOAST", + UPDATE_TOAST: "UPDATE_TOAST", + DISMISS_TOAST: "DISMISS_TOAST", + REMOVE_TOAST: "REMOVE_TOAST", +} as const; + +let count = 0; + +function genId() { + count = (count + 1) % Number.MAX_SAFE_INTEGER; + return count.toString(); +} + +type ActionType = typeof actionTypes; + +type Action = + | { + type: ActionType["ADD_TOAST"]; + toast: ToasterToast; + } + | { + type: ActionType["UPDATE_TOAST"]; + toast: Partial; + } + | { + type: ActionType["DISMISS_TOAST"]; + toastId?: ToasterToast["id"]; + } + | { + type: ActionType["REMOVE_TOAST"]; + toastId?: ToasterToast["id"]; + }; + +interface State { + toasts: ToasterToast[]; +} + +const toastTimeouts = new Map>(); + +const addToRemoveQueue = (toastId: string) => { + if (toastTimeouts.has(toastId)) { + return; + } + + const timeout = setTimeout(() => { + toastTimeouts.delete(toastId); + dispatch({ + type: "REMOVE_TOAST", + toastId: toastId, + }); + }, TOAST_REMOVE_DELAY); + + toastTimeouts.set(toastId, timeout); +}; + +export const reducer = (state: State, action: Action): State => { + switch (action.type) { + case "ADD_TOAST": + return { + ...state, + toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), + }; + + case "UPDATE_TOAST": + return { + ...state, + toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)), + }; + + case "DISMISS_TOAST": { + const { toastId } = action; + + // ! Side effects ! - This could be extracted into a dismissToast() action, + // but I'll keep it here for simplicity + if (toastId) { + addToRemoveQueue(toastId); + } else { + state.toasts.forEach((toast) => { + addToRemoveQueue(toast.id); + }); + } + + return { + ...state, + toasts: state.toasts.map((t) => + t.id === toastId || toastId === undefined + ? { + ...t, + open: false, + } + : t, + ), + }; + } + case "REMOVE_TOAST": + if (action.toastId === undefined) { + return { + ...state, + toasts: [], + }; + } + return { + ...state, + toasts: state.toasts.filter((t) => t.id !== action.toastId), + }; + } +}; + +const listeners: Array<(state: State) => void> = []; + +let memoryState: State = { toasts: [] }; + +function dispatch(action: Action) { + memoryState = reducer(memoryState, action); + listeners.forEach((listener) => { + listener(memoryState); + }); +} + +type Toast = Omit; + +function toast({ ...props }: Toast) { + const id = genId(); + + const update = (props: ToasterToast) => + dispatch({ + type: "UPDATE_TOAST", + toast: { ...props, id }, + }); + const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }); + + dispatch({ + type: "ADD_TOAST", + toast: { + ...props, + id, + open: true, + onOpenChange: (open) => { + if (!open) dismiss(); + }, + }, + }); + + return { + id: id, + dismiss, + update, + }; +} + +function useToast() { + const [state, setState] = React.useState(memoryState); + + React.useEffect(() => { + listeners.push(setState); + return () => { + const index = listeners.indexOf(setState); + if (index > -1) { + listeners.splice(index, 1); + } + }; + }, [state]); + + return { + ...state, + toast, + dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), + }; +} + +export { useToast, toast }; diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/constants.ts b/aptos-move/move-examples/my_first_dapp/frontend/src/constants.ts new file mode 100644 index 00000000000..4261ec590e8 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/constants.ts @@ -0,0 +1,3 @@ +export const NETWORK = import.meta.env.VITE_APP_NETWORK ?? "testnet"; +export const MODULE_ADDRESS = import.meta.env.VITE_MODULE_ADDRESS; +export const APTOS_API_KEY = import.meta.env.VITE_APTOS_API_KEY; diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/index.css b/aptos-move/move-examples/my_first_dapp/frontend/src/index.css new file mode 100644 index 00000000000..aa056644644 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/index.css @@ -0,0 +1,77 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --secondary-text: 215, 16%, 47%; + + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/lib/utils.ts b/aptos-move/move-examples/my_first_dapp/frontend/src/lib/utils.ts new file mode 100644 index 00000000000..365058cebd7 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/main.tsx b/aptos-move/move-examples/my_first_dapp/frontend/src/main.tsx new file mode 100644 index 00000000000..f14c8a2edad --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/main.tsx @@ -0,0 +1,26 @@ +import "../vite.polyfills"; +import "./index.css"; + +import React from "react"; +import ReactDOM from "react-dom/client"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; + +import App from "@/App.tsx"; +// Internal components +import { Toaster } from "@/components/ui/toaster.tsx"; +import { WalletProvider } from "@/components/WalletProvider.tsx"; +import { WrongNetworkAlert } from "@/components/WrongNetworkAlert"; + +const queryClient = new QueryClient(); + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + + + + + + + , +); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/src/utils/aptosClient.ts b/aptos-move/move-examples/my_first_dapp/frontend/src/utils/aptosClient.ts new file mode 100644 index 00000000000..13eeffa7226 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/src/utils/aptosClient.ts @@ -0,0 +1,9 @@ +import { NETWORK, APTOS_API_KEY } from "@/constants"; +import { Aptos, AptosConfig } from "@aptos-labs/ts-sdk"; + +const aptos = new Aptos(new AptosConfig({ network: NETWORK, clientConfig: { API_KEY: APTOS_API_KEY } })); + +// Reuse same Aptos instance to utilize cookie based sticky routing +export function aptosClient() { + return aptos; +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/tailwind.config.js b/aptos-move/move-examples/my_first_dapp/frontend/tailwind.config.js new file mode 100644 index 00000000000..c33a7755e03 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/tailwind.config.js @@ -0,0 +1,184 @@ +const plugin = require("tailwindcss/plugin"); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: ["class"], + content: ["./src/**/*.{ts,tsx}"], + prefix: "", + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + text: "hsl(var(--secondary-text))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + fontFamily: { + sans: ["sans-serif"], + inter: ["Inter", "sans-serif"], + }, + fontSize: { + 12: "0.75rem", + 14: "0.875rem", + 16: "1rem", + 18: "1.125rem", + 20: "1.25rem", + 24: "1.5rem", + 26: "1.625rem", + 30: "1.875rem", + 39: "2.4375rem", + 48: "3rem", + 51: "3.1875rem", + 68: "4.25rem", + 110: "6.875rem", + }, + lineHeight: { + 16: "1rem", + 18: "1.125rem", + 20: "1.25rem", + 22: "1.375rem", + 24: "1.5rem", + 26: "1.625rem", + 28: "1.75rem", + 32: "2rem", + 34: "2.125rem", + 42: "2.625rem", + 52: "3.25rem", + 62: "3.875rem", + 72: "4.5rem", + 116: "7.25rem", + }, + }, + }, + plugins: [ + require("tailwindcss-animate"), + + plugin(function addTextStyles({ addComponents, theme }) { + addComponents({ + // Component Regular Text Styles + ".body-sm": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.16"), + lineHeight: theme("lineHeight.28"), + fontWeight: theme("fontWeight.regular"), + }, + ".body-md": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.18"), + lineHeight: theme("lineHeight.28"), + fontWeight: theme("fontWeight.regular"), + }, + + // Component Semibold Text Styles + ".body-sm-semibold": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.16"), + lineHeight: theme("lineHeight.28"), + fontWeight: theme("fontWeight.semibold"), + }, + ".body-md-semibold": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.18"), + lineHeight: theme("lineHeight.28"), + fontWeight: theme("fontWeight.semibold"), + }, + + // Label Text Styles + ".label-sm": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.14"), + lineHeight: theme("lineHeight.24"), + color: theme("colors.secondary.text"), + }, + + // Title Text Styles + ".title-md": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.48"), + lineHeight: theme("lineHeight.48"), + fontWeight: theme("fontWeight.bold"), + letterSpacing: "-1.2%", + }, + + // Heading Text Styles + ".heading-sm": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.24"), + lineHeight: theme("lineHeight.32"), + fontWeight: theme("fontWeight.semibold"), + letterSpacing: "-0.6%", + }, + ".heading-md": { + fontFamily: theme("fontFamily.inter"), + fontSize: theme("fontSize.30"), + lineHeight: theme("lineHeight.36"), + fontWeight: theme("fontWeight.semibold"), + }, + + // Display Text Styles + ".display": { + fontFamily: theme("fontFamily.inter"), + fontSize: "32px", + lineHeight: "52px", + fontWeight: theme("fontWeight.bold"), + }, + }); + }), + ], +}; diff --git a/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.json b/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.json new file mode 100644 index 00000000000..6814c136ac6 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + // "allowSyntheticDefaultImports": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "vite-env.d.ts"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.node.json b/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.node.json new file mode 100644 index 00000000000..97ede7ee6f2 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/aptos-move/move-examples/my_first_dapp/frontend/vite-env.d.ts b/aptos-move/move-examples/my_first_dapp/frontend/vite-env.d.ts new file mode 100644 index 00000000000..11f02fe2a00 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/aptos-move/move-examples/my_first_dapp/frontend/vite.config.ts b/aptos-move/move-examples/my_first_dapp/frontend/vite.config.ts new file mode 100644 index 00000000000..16ab13087af --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/vite.config.ts @@ -0,0 +1,34 @@ +import path from "path"; +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + outDir: "dist", + rollupOptions: { + external: ['buffer'], + }, + }, + server: { + open: true, + }, + plugins: [ + react(), + ], + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + buffer: 'buffer', + process: 'process/browser', + stream: 'stream-browserify', + util: 'util', + }, + }, + optimizeDeps: { + esbuildOptions: { + define: { + global: 'globalThis', + }, + }, + }, +}); diff --git a/aptos-move/move-examples/my_first_dapp/frontend/vite.polyfills.ts b/aptos-move/move-examples/my_first_dapp/frontend/vite.polyfills.ts new file mode 100644 index 00000000000..5c1c48dba27 --- /dev/null +++ b/aptos-move/move-examples/my_first_dapp/frontend/vite.polyfills.ts @@ -0,0 +1,13 @@ +import { Buffer } from 'buffer'; + +// Polyfill Buffer +window.Buffer = Buffer; + +// Add other polyfills if needed +if (typeof (window as any).global === 'undefined') { + (window as any).global = window; +} + +if (typeof (window as any).process === 'undefined') { + (window as any).process = { env: {} }; +} diff --git a/aptos-move/move-examples/my_first_dapp/move/.gitignore b/aptos-move/move-examples/my_first_dapp/move/.gitignore deleted file mode 100644 index f930c403b45..00000000000 --- a/aptos-move/move-examples/my_first_dapp/move/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -.aptos \ No newline at end of file diff --git a/aptos-move/move-examples/my_first_dapp/move/Move.toml b/aptos-move/move-examples/my_first_dapp/move/Move.toml deleted file mode 100644 index eae36aa3f1e..00000000000 --- a/aptos-move/move-examples/my_first_dapp/move/Move.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = 'my_todo_list' -version = '1.0.0' -[dependencies.AptosFramework] -git = 'https://github.com/aptos-labs/aptos-framework.git' -rev = 'main' -subdir = 'aptos-framework' -[addresses] -todolist_addr='_' \ No newline at end of file diff --git a/aptos-move/move-examples/my_first_dapp/move/sources/todolist.move b/aptos-move/move-examples/my_first_dapp/move/sources/todolist.move deleted file mode 100644 index 80472423bab..00000000000 --- a/aptos-move/move-examples/my_first_dapp/move/sources/todolist.move +++ /dev/null @@ -1,114 +0,0 @@ -module todolist_addr::todolist { - - use aptos_framework::account; - use std::signer; - use aptos_framework::event; - use std::string::String; - use aptos_std::table::{Self, Table}; - #[test_only] - use std::string; - - // Errors - const E_NOT_INITIALIZED: u64 = 1; - const ETASK_DOESNT_EXIST: u64 = 2; - const ETASK_IS_COMPLETED: u64 = 3; - - struct TodoList has key { - tasks: Table, - task_counter: u64 - } - - #[event] - struct Task has store, drop, copy { - task_id: u64, - address: address, - content: String, - completed: bool, - } - - public entry fun create_list(account: &signer) { - let todo_list = TodoList { - tasks: table::new(), - task_counter: 0 - }; - // move the TodoList resource under the signer account - move_to(account, todo_list); - } - - public entry fun create_task(account: &signer, content: String) acquires TodoList { - // gets the signer address - let signer_address = signer::address_of(account); - // assert signer has created a list - assert!(exists(signer_address), E_NOT_INITIALIZED); - // gets the TodoList resource - let todo_list = borrow_global_mut(signer_address); - // increment task counter - let counter = todo_list.task_counter + 1; - // creates a new Task - let new_task = Task { - task_id: counter, - address: signer_address, - content, - completed: false - }; - // adds the new task into the tasks table - table::upsert(&mut todo_list.tasks, counter, new_task); - // sets the task counter to be the incremented counter - todo_list.task_counter = counter; - // fires a new task created event - event::emit(new_task); - } - - public entry fun complete_task(account: &signer, task_id: u64) acquires TodoList { - // gets the signer address - let signer_address = signer::address_of(account); - // assert signer has created a list - assert!(exists(signer_address), E_NOT_INITIALIZED); - // gets the TodoList resource - let todo_list = borrow_global_mut(signer_address); - // assert task exists - assert!(table::contains(&todo_list.tasks, task_id), ETASK_DOESNT_EXIST); - // gets the task matched the task_id - let task_record = table::borrow_mut(&mut todo_list.tasks, task_id); - // assert task is not completed - assert!(task_record.completed == false, ETASK_IS_COMPLETED); - // update task as completed - task_record.completed = true; - } - - #[test(admin = @0x123)] - public entry fun test_flow(admin: signer) acquires TodoList { - // creates an admin @todolist_addr account for test - account::create_account_for_test(signer::address_of(&admin)); - // initialize contract with admin account - create_list(&admin); - - // creates a task by the admin account - create_task(&admin, string::utf8(b"New Task")); - let todo_list = borrow_global(signer::address_of(&admin)); - assert!(todo_list.task_counter == 1, 5); - let task_record = table::borrow(&todo_list.tasks, todo_list.task_counter); - assert!(task_record.task_id == 1, 6); - assert!(task_record.completed == false, 7); - assert!(task_record.content == string::utf8(b"New Task"), 8); - assert!(task_record.address == signer::address_of(&admin), 9); - - // updates task as completed - complete_task(&admin, 1); - let todo_list = borrow_global(signer::address_of(&admin)); - let task_record = table::borrow(&todo_list.tasks, 1); - assert!(task_record.task_id == 1, 10); - assert!(task_record.completed == true, 11); - assert!(task_record.content == string::utf8(b"New Task"), 12); - assert!(task_record.address == signer::address_of(&admin), 13); - } - - #[test(admin = @0x123)] - #[expected_failure(abort_code = E_NOT_INITIALIZED)] - public entry fun account_can_not_update_task(admin: signer) acquires TodoList { - // creates an admin @todolist_addr account for test - account::create_account_for_test(signer::address_of(&admin)); - // account can not toggle task as no list was created - complete_task(&admin, 2); - } -} diff --git a/aptos-move/move-examples/signed_int/calculator/Move.toml b/aptos-move/move-examples/signed_int/calculator/Move.toml new file mode 100644 index 00000000000..e9af0c86909 --- /dev/null +++ b/aptos-move/move-examples/signed_int/calculator/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "calculator" +version = "0.0.0" + +[addresses] +account = "_" + +[dependencies] +AptosFramework = { local = "../../../framework/aptos-framework" } +AptosStdlib = { local = "../../../framework/aptos-stdlib" } diff --git a/aptos-move/move-examples/signed_int/calculator/sources/calculator.move b/aptos-move/move-examples/signed_int/calculator/sources/calculator.move new file mode 100644 index 00000000000..f9f79bfddd8 --- /dev/null +++ b/aptos-move/move-examples/signed_int/calculator/sources/calculator.move @@ -0,0 +1,102 @@ +module account::calculator { + use std::signer::address_of; + + /// Input to the calculator + enum Input { + Number(i64), + Add(i8), + Sub(i16), + Mul(i32), + Div(i128), + Mod(i256), + } + + /// State of the calculator + enum State has key, copy, drop { + Value(i64), + } + + /// Process input in the current state. + fun process(s: &signer, input: Input) acquires State { + let addr = address_of(s); + match ((move_from(addr), input)) { + (Value(_), Number(x)) => move_to(s, State::Value(x)), + (Value(x), Add(y)) => move_to(s, State::Value(x + (y as i64))), + (Value(x), Sub(y)) => move_to(s, State::Value(x - (y as i64))), + (Value(x), Mul(y)) => move_to(s, State::Value(x * (y as i64))), + (Value(x), Div(y)) => move_to(s, State::Value(x / (y as i64))), + (Value(x), Mod(y)) => move_to(s, State::Value(x % (y as i64))), + } + } + + fun init_module(s: &signer) { + move_to(s, State::Value(-1)) + } + + /// Entry point functions + entry fun number(s: &signer, x: i64) acquires State { + process(s, Input::Number(x)); + } + + entry fun add(s: &signer, x: i8) acquires State { + process(s, Input::Add(x)) + } + + entry fun sub(s: &signer, x: i16) acquires State { + process(s, Input::Sub(x)) + } + + entry fun mul(s: &signer, x: i32) acquires State { + process(s, Input::Mul(x)) + } + + entry fun div(s: &signer, x: i128) acquires State { + process(s, Input::Div(x)) + } + + entry fun mod(s: &signer, x: i256) acquires State { + process(s, Input::Mod(x)) + } + + #[view] + fun view_i8(a: address): i8 acquires State { + match (&State[a]) { + Value(x) => *x as i8, + } + } + + #[view] + fun view_i16(a: address): i16 acquires State { + match (&State[a]) { + Value(x) => *x as i16, + } + } + + #[view] + fun view_i32(a: address): i32 acquires State { + match (&State[a]) { + Value(x) => *x as i32, + } + } + + #[view] + fun view_i64(a: address): i64 acquires State { + match (&State[a]) { + Value(x) => *x, + } + } + + #[view] + fun view_i128(a: address): i128 acquires State { + match (&State[a]) { + Value(x) => *x as i128, + } + } + + #[view] + fun view_i256(a: address): i256 acquires State { + match (&State[a]) { + Value(x) => *x as i256, + } + } +} diff --git a/aptos-move/move-examples/swap/sources/tests/coin_wrapper_tests.move b/aptos-move/move-examples/swap/sources/tests/coin_wrapper_tests.move index 78d581d07d7..ac1ab8aff64 100644 --- a/aptos-move/move-examples/swap/sources/tests/coin_wrapper_tests.move +++ b/aptos-move/move-examples/swap/sources/tests/coin_wrapper_tests.move @@ -11,14 +11,23 @@ module swap::coin_wrapper_tests { fun test_e2e(user: &signer, deployer: &signer) { test_helpers::set_up(deployer); account::create_account_for_test(signer::address_of(user)); - coin::create_fake_money(user, user, 1000); + coin::create_fake_money(user, 1000); let coins = coin::withdraw(user, 1000); let fa = coin_wrapper::wrap(coins); let metadata = fungible_asset::asset_metadata(&fa); assert!(fungible_asset::amount(&fa) == 1000, 0); - assert!(fungible_asset::name(metadata) == coin::name(), 0); - assert!(fungible_asset::symbol(metadata) == coin::symbol(), 0); - assert!(fungible_asset::decimals(metadata) == coin::decimals(), 0); + assert!( + fungible_asset::name(metadata) == coin::name(), + 0 + ); + assert!( + fungible_asset::symbol(metadata) == coin::symbol(), + 0 + ); + assert!( + fungible_asset::decimals(metadata) == coin::decimals(), + 0 + ); let coins = coin_wrapper::unwrap(fa); assert!(coin::value(&coins) == 1000, 0); coin::deposit(signer::address_of(user), coins); diff --git a/aptos-move/move-examples/tests/move_unit_tests.rs b/aptos-move/move-examples/tests/move_unit_tests.rs index 4aeae3c5c92..05322e47acd 100644 --- a/aptos-move/move-examples/tests/move_unit_tests.rs +++ b/aptos-move/move-examples/tests/move_unit_tests.rs @@ -8,7 +8,11 @@ use aptos_types::{ on_chain_config::{aptos_test_feature_flags_genesis, Features, TimedFeaturesBuilder}, }; use aptos_vm::natives; -use move_cli::base::test::{run_move_unit_tests, UnitTestResult}; +use move_cli::base::{ + test::{run_move_unit_tests, UnitTestResult}, + test_validation, +}; +use move_model::model::GlobalEnv; use move_package::{source_package::std_lib::StdVersion, CompilerConfig}; use move_unit_test::UnitTestingConfig; use move_vm_runtime::native_functions::NativeFunctionTable; @@ -24,6 +28,14 @@ where path } +/// Configures the move-cli unit test validation hook to run the extended checker. +fn configure_extended_checks_for_unit_test() { + fn validate(env: &GlobalEnv) { + extended_checks::run_extended_checks(env); + } + test_validation::set_validation_hook(Box::new(validate)); +} + pub fn run_tests_for_pkg( path_to_pkg: impl Into, named_addr: BTreeMap, @@ -50,6 +62,7 @@ pub fn run_tests_for_pkg( /* cost_table */ None, /* compute_coverage */ false, &mut std::io::stdout(), + true, ); if ok.is_err() || ok.is_ok_and(|r| r == UnitTestResult::Failure) { panic!("move unit tests failed") @@ -58,7 +71,7 @@ pub fn run_tests_for_pkg( pub fn aptos_test_natives() -> NativeFunctionTable { natives::configure_for_unit_test(); - extended_checks::configure_extended_checks_for_unit_test(); + configure_extended_checks_for_unit_test(); natives::aptos_natives( LATEST_GAS_FEATURE_VERSION, NativeGasParameters::zeros(), diff --git a/aptos-move/move-examples/token_objects/ambassador/Move.toml b/aptos-move/move-examples/token_objects/ambassador/Move.toml index 5ce9f3c141c..54468ab7ec1 100644 --- a/aptos-move/move-examples/token_objects/ambassador/Move.toml +++ b/aptos-move/move-examples/token_objects/ambassador/Move.toml @@ -1,5 +1,5 @@ [package] -name = 'ambassador' +name = 'ambassador_token' version = '1.0.0' # do not change to "_", concrete address needed for module-publish testing framework diff --git a/aptos-move/mvhashmap/Cargo.toml b/aptos-move/mvhashmap/Cargo.toml index 09a679ca6a4..f2af491f240 100644 --- a/aptos-move/mvhashmap/Cargo.toml +++ b/aptos-move/mvhashmap/Cargo.toml @@ -15,21 +15,28 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } aptos-aggregator = { workspace = true } +aptos-infallible = { workspace = true } aptos-types = { workspace = true } aptos-vm-types = { workspace = true } bytes = { workspace = true } claims = { workspace = true } crossbeam = { workspace = true } dashmap = { workspace = true } +equivalent = { workspace = true } +fail = { workspace = true } move-binary-format = { workspace = true } move-core-types = { workspace = true } move-vm-runtime = { workspace = true } move-vm-types = { workspace = true } serde = { workspace = true } +triomphe = { workspace = true } [dev-dependencies] aptos-aggregator = { workspace = true, features = ["testing"] } +concurrent-queue = { workspace = true } +fail = { workspace = true, features = ["failpoints"] } move-vm-runtime = { workspace = true } +num_cpus = { workspace = true } proptest = { workspace = true } proptest-derive = { workspace = true } rayon = { workspace = true } diff --git a/aptos-move/mvhashmap/src/lib.rs b/aptos-move/mvhashmap/src/lib.rs index 5f26c1191f8..b185f36e513 100644 --- a/aptos-move/mvhashmap/src/lib.rs +++ b/aptos-move/mvhashmap/src/lib.rs @@ -16,6 +16,7 @@ use move_vm_types::code::{ModuleCache, ModuleCode, SyncModuleCache, SyncScriptCa use serde::Serialize; use std::{fmt::Debug, hash::Hash, sync::Arc}; +mod registered_dependencies; pub mod types; pub mod unsync_map; pub mod versioned_data; @@ -32,8 +33,12 @@ mod unit_tests; /// given key, it holds exclusive access and doesn't need to explicitly synchronize /// with other reader/writers. /// -/// TODO: separate V into different generic types for data and code modules with specialized -/// traits (currently both WriteOp for executor). +/// TODO(BlockSTMv2): consider handling the baseline retrieval inside MVHashMap, by +/// providing a lambda during construction. This would simplify the caller logic and +/// allow unifying initialization logic e.g. for resource groups that span two +/// different multi-version data-structures (MVData and MVGroupData). It would also +/// allow performing a check on the path once during initialization (to determine +/// if the path is for a resource or a group), and then checking invariants. pub struct MVHashMap { data: VersionedData, group_data: VersionedGroupData, @@ -48,7 +53,7 @@ impl MVHashMap where K: ModulePath + Hash + Clone + Eq + Debug, T: Hash + Clone + Eq + Debug + Serialize, - V: TransactionWrite, + V: TransactionWrite + PartialEq, I: Copy + Clone + Eq + Hash + Debug, { #[allow(clippy::new_without_default)] @@ -108,7 +113,7 @@ where ModuleId, Arc>, ), - > { + > + use { self.module_cache.take_modules_iter() } diff --git a/aptos-move/mvhashmap/src/registered_dependencies.rs b/aptos-move/mvhashmap/src/registered_dependencies.rs new file mode 100644 index 00000000000..b18bd9f8cf6 --- /dev/null +++ b/aptos-move/mvhashmap/src/registered_dependencies.rs @@ -0,0 +1,277 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::types::{Incarnation, TxnIndex}; +use aptos_infallible::Mutex; +use aptos_types::error::{code_invariant_error, PanicError}; +use std::collections::{btree_map::Entry, BTreeMap}; + +// Checks the invariant that the lowest dependency is strictly greater than +// provided txn_idx. This is a sanity check e.g. for dependencies stored at +// an entry at txn_idx in the multi-versioned data structure. +pub(crate) fn check_lowest_dependency_idx( + dependencies: &BTreeMap, + txn_idx: TxnIndex, +) -> Result<(), PanicError> { + if let Some((lowest_dep_idx, _)) = dependencies.first_key_value() { + if *lowest_dep_idx <= txn_idx { + return Err(code_invariant_error(format!( + "Dependency for txn {} recorded at idx {}", + *lowest_dep_idx, txn_idx + ))); + } + } + Ok(()) +} + +// A wrapper around recorded read dependencies used in multi-versioned data structures. +// Does not expose the inner field to avoid bugs, such as merging different sets of +// dependencies, when it is important to keep the latest incarnation of each txn. +#[derive(Debug)] +pub(crate) struct RegisteredReadDependencies { + /// A map of txn_idx to incarnation that have registered a read of this entry. + /// The reason for using the map is to store at most one (latest) incarnation + /// per txn_idx (since a dependency on an outdated incarnation can safely be removed). + // TODO(BlockSTMv2): Add support for behavioral validation (read kind). + dependencies: BTreeMap, +} + +impl RegisteredReadDependencies { + pub(crate) fn new() -> Self { + Self { + dependencies: BTreeMap::new(), + } + } + + pub(crate) fn from_dependencies(dependencies: BTreeMap) -> Self { + Self { dependencies } + } + + // Returns a PanicError if the incarnation is lower than the previous incarnation, + // as an invariant that caller monotonically increases the incarnation is assumed. + pub(crate) fn insert( + &mut self, + txn_idx: TxnIndex, + incarnation: Incarnation, + ) -> Result<(), PanicError> { + if let Some(prev_incarnation) = self.dependencies.insert(txn_idx, incarnation) { + if prev_incarnation > incarnation { + // A higher incarnation may not have been recorded before, as + // incarnations for each txn index are monotonically incremented. + // + // TODO(BlockSTMv2): Consider also checking the cases when the + // incarnations are equal, but local caching should have ensured that the + // read with the same incarnation was not performed twice. + return Err(code_invariant_error(format!( + "Recording dependency on txn {} incarnation {}, found incarnation {}", + txn_idx, incarnation, prev_incarnation + ))); + } + } + + Ok(()) + } + + fn extend_impl( + self_dependencies: &mut BTreeMap, + other_dependencies: BTreeMap, + ) { + for (txn_idx, incarnation) in other_dependencies { + match self_dependencies.entry(txn_idx) { + Entry::Occupied(mut entry) => { + if *entry.get() < incarnation { + entry.insert(incarnation); + } + }, + Entry::Vacant(entry) => { + entry.insert(incarnation); + }, + } + } + } + + // When we extend recorded dependencies with other dependencies in a general sense + // (e.g. these might be invalidated dependencies from different data-structures), + // we need to make sure to keep the latest incarnation per txn index. + pub(crate) fn extend(&mut self, other: BTreeMap) { + Self::extend_impl(&mut self.dependencies, other); + } + + // This method merges other dependencies, but expects that it contains strictly + // larger txn indices. This invariant holds when removing an entry from a data-structure, + // and migrating dependencies (that still pass validation) to a different entry. + // The index of the entry acts as a separator between the indices in both sets. + pub(crate) fn extend_with_higher_dependencies( + &mut self, + other: BTreeMap, + ) -> Result<(), PanicError> { + let dependencies = &mut self.dependencies; + if let Some((highest_dep_idx, _)) = dependencies.last_key_value() { + // Highest dependency in self should be strictly less than other dependencies. + check_lowest_dependency_idx(&other, *highest_dep_idx)?; + } + + Self::extend_impl(dependencies, other); + + Ok(()) + } + + // Split off dependencies above (and including) txn_idx and return as BTreeMap. + pub(crate) fn split_off(&mut self, txn_idx: TxnIndex) -> BTreeMap { + self.dependencies.split_off(&txn_idx) + } + + pub(crate) fn take(self) -> BTreeMap { + self.dependencies + } + + #[cfg(test)] + pub(crate) fn clone_dependencies_for_test(&self) -> BTreeMap { + self.dependencies.clone() + } +} + +pub(crate) fn take_dependencies( + dependencies_in_mutex: &Mutex, +) -> BTreeMap { + std::mem::take(&mut dependencies_in_mutex.lock().dependencies) +} + +#[cfg(test)] +mod tests { + use super::*; + use claims::{assert_err, assert_ok}; + + #[test] + fn test_check_lowest_dependency_idx() { + let mut deps = BTreeMap::new(); + // Ok on empty. + assert_ok!(check_lowest_dependency_idx(&deps, 5)); + + deps.insert(10, 1); + deps.insert(12, 1); + + // Ok when lowest dependency (10) > txn_idx (5). + assert_ok!(check_lowest_dependency_idx(&deps, 5)); + // Ok when lowest dependency (10) > txn_idx (9). + assert_ok!(check_lowest_dependency_idx(&deps, 9)); + + // Err when lowest dependency (10) == txn_idx (10). + assert_err!(check_lowest_dependency_idx(&deps, 10)); + // Err when lowest dependency (10) < txn_idx (11). + assert_err!(check_lowest_dependency_idx(&deps, 11)); + } + + #[test] + fn test_dependencies_construction_and_insertion() { + // Test `new` and `from_dependencies`. + let deps = RegisteredReadDependencies::new(); + assert!(deps.dependencies.is_empty()); + + let initial_map = BTreeMap::from([(10, 1), (20, 2)]); + let mut deps = RegisteredReadDependencies::from_dependencies(initial_map.clone()); + assert_eq!(deps.dependencies, initial_map); + + // Test `insert`. + // Insert new dependency. + assert_ok!(deps.insert(30, 3)); + assert_eq!(deps.dependencies.get(&30), Some(&3)); + + // Insert with higher incarnation for existing dependency. + assert_ok!(deps.insert(20, 5)); + assert_eq!(deps.dependencies.get(&20), Some(&5)); + + // Insert with the same incarnation for existing dependency + // (should not error for the time being). + assert_ok!(deps.insert(20, 5)); + assert_eq!(deps.dependencies.get(&20), Some(&5)); + + // Insert with lower incarnation for existing dependency (must error). + assert_err!(deps.insert(20, 4)); + } + + #[test] + fn test_extend_and_extend_with_higher() { + let mut deps = RegisteredReadDependencies::from_dependencies(BTreeMap::from([ + (10, 5), + (11, 3), + (20, 5), + ])); + + // Test `extend`. + let other1 = BTreeMap::from([(11, 4), (15, 6), (20, 3), (25, 6)]); + deps.extend(other1); + let final_map = deps.clone_dependencies_for_test(); + assert_eq!(final_map.get(&10), Some(&5)); // Unchanged. + assert_eq!(final_map.get(&11), Some(&4)); // Took higher incarnation from other1. + assert_eq!(final_map.get(&15), Some(&6)); // New. + assert_eq!(final_map.get(&20), Some(&5)); // Kept higher incarnation. + assert_eq!(final_map.get(&25), Some(&6)); // New. + assert_eq!(final_map.len(), 5); + + // Test `extend_with_higher_dependencies`. + // Success case. + let other2 = BTreeMap::from([(30, 1), (40, 1)]); + assert_ok!(deps.extend_with_higher_dependencies(other2)); + assert_eq!(deps.clone_dependencies_for_test().len(), 7); + + // Failure case: overlapping index. + let other3 = BTreeMap::from([(40, 2), (50, 2)]); + assert_err!(deps.extend_with_higher_dependencies(other3)); + + // Failure case: lower index. + let other4 = BTreeMap::from([(35, 2)]); + assert_err!(deps.extend_with_higher_dependencies(other4)); + } + + #[test] + fn test_split_off() { + let mut deps = RegisteredReadDependencies::from_dependencies(BTreeMap::from([ + (10, 1), + (20, 1), + (30, 1), + (40, 1), + (50, 1), + ])); + + // Split at an existing key. + let split_map = deps.split_off(30); + assert_eq!( + deps.clone_dependencies_for_test(), + BTreeMap::from([(10, 1), (20, 1)]) + ); + assert_eq!(split_map, BTreeMap::from([(30, 1), (40, 1), (50, 1)])); + + // Split at a non-existing key. + let split_map_2 = deps.split_off(15); + assert_eq!( + deps.clone_dependencies_for_test(), + BTreeMap::from([(10, 1)]) + ); + assert_eq!(split_map_2, BTreeMap::from([(20, 1)])); + + // Split everything off. + let split_map_3 = deps.split_off(0); + assert!(deps.clone_dependencies_for_test().is_empty()); + assert_eq!(split_map_3, BTreeMap::from([(10, 1)])); + } + + #[test] + fn test_take_and_clone() { + let initial_map = BTreeMap::from([(10, 1), (20, 2)]); + let deps = RegisteredReadDependencies::from_dependencies(initial_map.clone()); + + // Test clone. + let cloned_deps = deps.clone_dependencies_for_test(); + assert_eq!(cloned_deps, initial_map); + // Original dependencies should be untouched. + assert_eq!(deps.dependencies, initial_map); + + // Test take. + let deps = Mutex::new(deps); + let taken_deps = take_dependencies(&deps); + assert_eq!(taken_deps, initial_map); + // Original dependencies should now be empty. + assert!(deps.lock().dependencies.is_empty()); + } +} diff --git a/aptos-move/mvhashmap/src/types.rs b/aptos-move/mvhashmap/src/types.rs index 4e6d2459e3f..0ed78150a4a 100644 --- a/aptos-move/mvhashmap/src/types.rs +++ b/aptos-move/mvhashmap/src/types.rs @@ -6,8 +6,10 @@ use aptos_types::{ error::PanicOr, write_set::{TransactionWrite, WriteOpKind}, }; +use fail::fail_point; use move_core_types::value::MoveTypeLayout; -use std::sync::{atomic::AtomicU32, Arc}; +use std::sync::atomic::AtomicU32; +use triomphe::Arc; pub type AtomicTxnIndex = AtomicU32; pub type TxnIndex = u32; @@ -158,6 +160,7 @@ impl ValueWithLayout { } pub fn bytes_len(&self) -> Option { + fail_point!("value_with_layout_bytes_len", |_| { Some(10) }); match self { ValueWithLayout::RawFromStorage(value) | ValueWithLayout::Exchanged(value, _) => { value.bytes().map(|b| b.len()) @@ -193,7 +196,7 @@ pub(crate) mod test { use bytes::Bytes; use claims::{assert_err, assert_ok_eq}; use move_core_types::{account_address::AccountAddress, identifier::IdentStr}; - use std::{fmt::Debug, hash::Hash, sync::Arc}; + use std::{fmt::Debug, hash::Hash}; #[derive(Clone, Eq, Hash, PartialEq, Debug)] pub(crate) struct KeyType( diff --git a/aptos-move/mvhashmap/src/unit_tests/dependencies.rs b/aptos-move/mvhashmap/src/unit_tests/dependencies.rs new file mode 100644 index 00000000000..ec325cf1c2e --- /dev/null +++ b/aptos-move/mvhashmap/src/unit_tests/dependencies.rs @@ -0,0 +1,274 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use super::{ + types::{test::KeyType, Incarnation, MVDataError, MVDataOutput, TxnIndex, ValueWithLayout}, + MVHashMap, +}; +use crate::{types::ShiftedTxnIndex, unit_tests::proptest_types::MockValue}; +use claims::{assert_matches, assert_ok}; +use concurrent_queue::ConcurrentQueue; +use proptest::{ + collection::vec, prelude::*, sample::Index, strategy::ValueTree, test_runner::TestRunner, +}; +use std::{ + collections::{BTreeMap, HashMap}, + fmt::Debug, + sync::atomic::{AtomicUsize, Ordering}, + thread::sleep, + time::Duration, +}; +use test_case::test_case; +use triomphe::Arc; + +#[derive(Debug, Clone)] +enum Operator { + Insert(V), + // InsertAndRemove transforms into two operations, with the second + // operation taking place after the first operation is completed. + InsertAndRemove(V), + Read, +} + +fn operator_strategy() -> impl Strategy> { + prop_oneof![ + 1 => any::().prop_map(Operator::Insert), + 1 => any::().prop_map(Operator::InsertAndRemove), + 1 => Just(Operator::Read), + ] +} + +/// This test works as follows: +/// 1. We generate a sequence of transactions based on the above Operator and +/// generate the expected baseline. +/// 2. The worker threads pick transactions from the queue and execute them. +/// 3. For the reads, the final result is recorded, and reads are rescheduled +/// when a write_v2 or remove_v2 invalidate the previous dependency record. +/// 4. In the end we simply ensure that the final result matches the expected +/// baseline, and is recorded once as a dependency in the corresponding entry. +#[test_case(30, 2, 1, 30, 5)] +#[test_case(50, 4, 3, 20, 5)] +#[test_case(100, 8, 3, 50, 0)] +#[test_case(1000, 16, 10, 1, 1)] +#[test_case(20, 6, 1, 100, 1)] +fn test_dependencies( + num_txns: usize, + num_workers: usize, + universe_size: usize, + num_random_generations: usize, + sleep_millis: u64, +) { + if num_workers > num_cpus::get() { + // Ideally, we would want: + // https://users.rust-lang.org/t/how-to-programatically-ignore-a-unit-test/64096/5 + return; + } + + let mut runner = TestRunner::default(); + + for _ in 0..num_random_generations { + // Generate universe & transactions. + let universe = vec(any::<[u8; 32]>(), universe_size) + .new_tree(&mut runner) + .expect("creating universe should succeed") + .current(); + let transactions = vec((any::(), operator_strategy::<[u8; 32]>()), num_txns) + .new_tree(&mut runner) + .expect("creating transactions should succeed") + .current() + .into_iter() + .map(|(idx, op)| (*idx.get(&universe), op)) + .collect::>(); + + let mut baseline = universe + .iter() + .map(|key| (*key, BTreeMap::new())) + .collect::>(); + for (idx, (key, op)) in transactions.iter().enumerate() { + if let Operator::Insert(v) = op { + baseline + .entry(*key) + .or_default() + .insert(idx as TxnIndex, MockValue::new(Some(*v))); + } + } + + let map = MVHashMap::, usize, MockValue<[u8; 32]>, ()>::new(); + + // Each read may get invalidated and be rescheduled, but since each original + // txn performs at most one read, total number of rescheduled reads at any given + // time is bounded by num_txns. + let rescheduled_reads = ConcurrentQueue::<(TxnIndex, Incarnation)>::bounded(num_txns); + // When a read occurs, if it does not read the correct value, the corresponding + // correct_read flag is set to false (initialized to true since not all txns + // contain a read), o.w. to true (if correct value is read). With each invalidations + // causing a rescheduling, eventually all correct_read flags should be set to true. + // The flag is stored in the least significant bit, while prefix is incarnation * 2, + // so that (using fetch_max)the flag from the latest incarnation is recorded in the end. + let correct_read = (0..num_txns) + .map(|_| AtomicUsize::new(1)) + .collect::>(); + + let current_idx: AtomicUsize = AtomicUsize::new(0); + rayon::scope(|s| { + for _ in 0..num_workers { + s.spawn(|_| loop { + let process_deps = |invalidated_deps: BTreeMap| { + for (txn_idx, incarnation) in invalidated_deps { + assert_ok!(rescheduled_reads.push((txn_idx, incarnation + 1))); + } + }; + + let maybe_perform_read = if current_idx.load(Ordering::Relaxed) < num_txns { + let idx = current_idx.fetch_add(1, Ordering::Relaxed); + if idx < num_txns { + let key = KeyType(transactions[idx].0); + match &transactions[idx].1 { + Operator::Read => Some((transactions[idx].0, idx as TxnIndex, 0)), + Operator::Insert(v) => { + process_deps( + map.data() + .write_v2::( + key, + idx as TxnIndex, + 0, + Arc::new(MockValue::new(Some(*v))), + None, + ) + .unwrap(), + ); + None + }, + Operator::InsertAndRemove(v) => { + process_deps( + map.data() + .write_v2::( + key.clone(), + idx as TxnIndex, + 0, + Arc::new(MockValue::new(Some(*v))), + None, + ) + .unwrap(), + ); + sleep(Duration::from_millis(sleep_millis)); + process_deps( + map.data() + .remove_v2::<_, false>(&key, idx as TxnIndex) + .unwrap(), + ); + None + }, + } + } else { + None + } + } else { + let ret = rescheduled_reads.pop().ok().map(|(txn_idx, incarnation)| { + assert_matches!(&transactions[txn_idx as usize].1, Operator::Read); + (transactions[txn_idx as usize].0, txn_idx, incarnation) + }); + if ret.is_none() { + break; + } + ret + }; + + if let Some((key, txn_idx, incarnation)) = maybe_perform_read { + let speculative_read_value = map.data().fetch_data_and_record_dependency( + &KeyType(key), + txn_idx, + incarnation, + ); + let correct = match speculative_read_value { + Ok(MVDataOutput::Versioned(_version, value)) => { + baseline + .get(&key) + .expect("key should exist in baseline") + .range(..txn_idx) + .next_back() + .map_or_else( + || { + // Comparison ignores version since push invalidation + // is based only on values. + value + == ValueWithLayout::Exchanged( + Arc::new(MockValue::new(None)), + None, + ) + }, + |(_expected_txn_idx, expected_output)| { + // Comparison ignores expected_txn_idx since push + // validation is based only on values. + value + == ValueWithLayout::Exchanged( + Arc::new(expected_output.clone()), + None, + ) + }, + ) + }, + Err(MVDataError::Uninitialized) => { + map.data().set_base_value( + KeyType(key), + ValueWithLayout::Exchanged( + Arc::new(MockValue::new(None)), + None, + ), + ); + assert_ok!(rescheduled_reads.push((txn_idx, incarnation + 1))); + false + }, + _ => unreachable!("Should be versioned or uninitialized"), + }; + + correct_read[txn_idx as usize].fetch_max( + incarnation as usize * 2 + correct as usize, + Ordering::Relaxed, + ); + } + }); + } + }); + + assert_eq!(rescheduled_reads.len(), 0); + assert!(correct_read + .iter() + .all(|correct_flag| correct_flag.load(Ordering::Relaxed) & 1 == 1)); + + let mut expected_deps: HashMap< + KeyType<[u8; 32]>, + BTreeMap>, + > = HashMap::new(); + for (idx, txn) in transactions.iter().enumerate() { + if let Operator::Read = txn.1 { + let expected_idx = baseline + .get(&txn.0) + .expect("key should exist in baseline") + .range(..idx as TxnIndex) + .next_back() + .map_or(ShiftedTxnIndex::zero_idx(), |(txn_idx, _)| { + ShiftedTxnIndex::new(*txn_idx) + }); + + expected_deps + .entry(KeyType(txn.0)) + .or_default() + .entry(expected_idx.clone()) + .or_default() + .insert( + idx as TxnIndex, + correct_read[idx].load(Ordering::Relaxed) as u32 / 2, + ); + } + } + + for (key, expected_deps) in expected_deps { + for (expected_idx, expected_deps) in expected_deps { + let recorded_deps = map.data().get_dependencies(&key, expected_idx.clone()); + assert_eq!(recorded_deps, expected_deps); + } + } + } +} diff --git a/aptos-move/mvhashmap/src/unit_tests/mod.rs b/aptos-move/mvhashmap/src/unit_tests/mod.rs index 03883f9fdd0..48f8c455907 100644 --- a/aptos-move/mvhashmap/src/unit_tests/mod.rs +++ b/aptos-move/mvhashmap/src/unit_tests/mod.rs @@ -23,7 +23,9 @@ use aptos_types::{ }; use bytes::Bytes; use claims::{assert_err_eq, assert_none, assert_ok_eq, assert_some_eq}; -use std::sync::Arc; +use triomphe::Arc; + +mod dependencies; mod proptest_types; fn match_unresolved( @@ -131,7 +133,7 @@ fn create_write_read_placeholder_struct() { let mvtbl: MVHashMap>, usize, TestValue, ()> = MVHashMap::new(); // Reads that should go the DB return Err(Uninitialized) - let r_db = mvtbl.data().fetch_data(&ap1, 5); + let r_db = mvtbl.data().fetch_data_no_record(&ap1, 5); assert_eq!(Err(Uninitialized), r_db); // Write by txn 10. @@ -140,14 +142,14 @@ fn create_write_read_placeholder_struct() { .write(ap1.clone(), 10, 1, arc_value_for(10, 1), None); // Reads that should go the DB return Err(Uninitialized) - let r_db = mvtbl.data().fetch_data(&ap1, 9); + let r_db = mvtbl.data().fetch_data_no_record(&ap1, 9); assert_eq!(Err(Uninitialized), r_db); // Reads return entries from smaller txns, not txn 10. - let r_db = mvtbl.data().fetch_data(&ap1, 10); + let r_db = mvtbl.data().fetch_data_no_record(&ap1, 10); assert_eq!(Err(Uninitialized), r_db); // Reads for a higher txn return the entry written by txn 10. - let r_10 = mvtbl.data().fetch_data(&ap1, 15); + let r_10 = mvtbl.data().fetch_data_no_record(&ap1, 15); assert_eq!( Ok(Versioned( Ok((10, 1)), @@ -168,7 +170,7 @@ fn create_write_read_placeholder_struct() { .add_delta(ap1.clone(), 13, delta_sub(74, u128::MAX)); // Reads have to go traverse deltas until a write is found. - let r_sum = mvtbl.data().fetch_data(&ap1, 14); + let r_sum = mvtbl.data().fetch_data_no_record(&ap1, 14); assert_eq!(Ok(Resolved(u128_for(10, 1) + 11 + 12 - (61 + 13))), r_sum); // More writes. @@ -180,9 +182,9 @@ fn create_write_read_placeholder_struct() { .write(ap1.clone(), 8, 3, arc_value_for(8, 3), None); // Verify reads. - let r_12 = mvtbl.data().fetch_data(&ap1, 15); + let r_12 = mvtbl.data().fetch_data_no_record(&ap1, 15); assert_eq!(Ok(Resolved(u128_for(12, 0) - (61 + 13))), r_12); - let r_10 = mvtbl.data().fetch_data(&ap1, 11); + let r_10 = mvtbl.data().fetch_data_no_record(&ap1, 11); assert_eq!( Ok(Versioned( Ok((10, 1)), @@ -190,7 +192,7 @@ fn create_write_read_placeholder_struct() { )), r_10 ); - let r_8 = mvtbl.data().fetch_data(&ap1, 10); + let r_8 = mvtbl.data().fetch_data_no_record(&ap1, 10); assert_eq!( Ok(Versioned( Ok((8, 3)), @@ -203,11 +205,11 @@ fn create_write_read_placeholder_struct() { mvtbl.data().mark_estimate(&ap1, 10); // Read for txn 11 must observe a dependency. - let r_10 = mvtbl.data().fetch_data(&ap1, 11); + let r_10 = mvtbl.data().fetch_data_no_record(&ap1, 11); assert_eq!(Err(Dependency(10)), r_10); // Read for txn 12 must observe a dependency when resolving deltas at txn 11. - let r_11 = mvtbl.data().fetch_data(&ap1, 12); + let r_11 = mvtbl.data().fetch_data_no_record(&ap1, 12); assert_eq!(Err(Dependency(10)), r_11); // Delete the entry written by 10, write to a different ap. @@ -217,7 +219,7 @@ fn create_write_read_placeholder_struct() { .write(ap2.clone(), 10, 2, arc_value_for(10, 2), None); // Read by txn 11 no longer observes entry from txn 10. - let r_8 = mvtbl.data().fetch_data(&ap1, 11); + let r_8 = mvtbl.data().fetch_data_no_record(&ap1, 11); assert_eq!( Ok(Versioned( Ok((8, 3)), @@ -233,7 +235,7 @@ fn create_write_read_placeholder_struct() { mvtbl .data() .write(ap3.clone(), 20, 4, arc_value_for(20, 4), None); - let r_5 = mvtbl.data().fetch_data(&ap2, 10); + let r_5 = mvtbl.data().fetch_data_no_record(&ap2, 10); assert_eq!( Ok(Versioned( Ok((5, 0)), @@ -241,7 +243,7 @@ fn create_write_read_placeholder_struct() { )), r_5 ); - let r_20 = mvtbl.data().fetch_data(&ap3, 21); + let r_20 = mvtbl.data().fetch_data_no_record(&ap3, 21); assert_eq!( Ok(Versioned( Ok((20, 4)), @@ -257,14 +259,14 @@ fn create_write_read_placeholder_struct() { // Reads from ap1 and ap3 go to db. match_unresolved( - mvtbl.data().fetch_data(&ap1, 30), + mvtbl.data().fetch_data_no_record(&ap1, 30), SignedU128::Negative((61 + 13) - 11), ); - let r_db = mvtbl.data().fetch_data(&ap3, 30); + let r_db = mvtbl.data().fetch_data_no_record(&ap3, 30); assert_eq!(Err(Uninitialized), r_db); // Read entry by txn 10 at ap2. - let r_10 = mvtbl.data().fetch_data(&ap2, 15); + let r_10 = mvtbl.data().fetch_data_no_record(&ap2, 15); assert_eq!( Ok(Versioned( Ok((10, 2)), @@ -276,7 +278,7 @@ fn create_write_read_placeholder_struct() { // Both delta-write and delta-delta application failures are detected. mvtbl.data().add_delta(ap1.clone(), 30, delta_add(30, 32)); mvtbl.data().add_delta(ap1.clone(), 31, delta_add(31, 32)); - let r_33 = mvtbl.data().fetch_data(&ap1, 33); + let r_33 = mvtbl.data().fetch_data_no_record(&ap1, 33); assert_eq!(Err(DeltaApplicationFailure), r_33); let val = arc_value_for(10, 3); @@ -286,7 +288,7 @@ fn create_write_read_placeholder_struct() { mvtbl .data() .add_delta(ap2.clone(), 30, delta_sub(30 + sub_base, u128::MAX)); - let r_31 = mvtbl.data().fetch_data(&ap2, 31); + let r_31 = mvtbl.data().fetch_data_no_record(&ap2, 31); assert_eq!(Err(DeltaApplicationFailure), r_31); } @@ -302,7 +304,7 @@ fn materialize_delta_shortcut() { vd.add_delta(ap.clone(), 8, delta_add(20, limit)); vd.add_delta(ap.clone(), 11, delta_add(30, limit)); - match_unresolved(vd.fetch_data(&ap, 10), SignedU128::Positive(30)); + match_unresolved(vd.fetch_data_no_record(&ap, 10), SignedU128::Positive(30)); assert_err_eq!( vd.materialize_delta(&ap, 8), DeltaOp::new(SignedU128::Positive(30), limit, DeltaHistory { @@ -324,16 +326,16 @@ fn materialize_delta_shortcut() { // With base set, commit delta should now succeed. assert_ok_eq!(vd.materialize_delta(&ap, 8), 35); - assert_eq!(vd.fetch_data(&ap, 10), Ok(Resolved(35))); + assert_eq!(vd.fetch_data_no_record(&ap, 10), Ok(Resolved(35))); // Make sure shortcut is committed by adding a delta at a lower txn idx // and ensuring tha fetch_data output no longer changes. vd.add_delta(ap.clone(), 6, delta_add(15, limit)); - assert_eq!(vd.fetch_data(&ap, 10), Ok(Resolved(35))); + assert_eq!(vd.fetch_data_no_record(&ap, 10), Ok(Resolved(35))); // However, if we add a delta at txn_idx = 9, it should have an effect. vd.add_delta(ap.clone(), 9, delta_add(15, limit)); - assert_eq!(vd.fetch_data(&ap, 10), Ok(Resolved(50))); + assert_eq!(vd.fetch_data_no_record(&ap, 10), Ok(Resolved(50))); } #[test] diff --git a/aptos-move/mvhashmap/src/unit_tests/proptest_types.rs b/aptos-move/mvhashmap/src/unit_tests/proptest_types.rs index a7ad47c00e5..b2d996684d2 100644 --- a/aptos-move/mvhashmap/src/unit_tests/proptest_types.rs +++ b/aptos-move/mvhashmap/src/unit_tests/proptest_types.rs @@ -20,11 +20,9 @@ use std::{ collections::{BTreeMap, HashMap, HashSet}, fmt::Debug, hash::Hash, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, + sync::atomic::{AtomicUsize, Ordering}, }; +use triomphe::Arc; const DEFAULT_TIMEOUT: u64 = 30; @@ -37,7 +35,7 @@ enum Operator { } #[derive(Debug, Clone, PartialEq, Eq)] -enum ExpectedOutput { +enum ExpectedOutput { NotInMap, Deleted, Value(V), @@ -46,14 +44,14 @@ enum ExpectedOutput { Failure, } -#[derive(Debug, Clone)] -struct Value { +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct MockValue { maybe_value: Option, maybe_bytes: Option, } -impl> + Clone> Value { - fn new(maybe_value: Option) -> Self { +impl> + Clone + Eq + PartialEq> MockValue { + pub(crate) fn new(maybe_value: Option) -> Self { let maybe_bytes = maybe_value.clone().map(|v| { let mut bytes = v.into(); bytes.resize(16, 0); @@ -66,7 +64,7 @@ impl> + Clone> Value { } } -impl> + Clone + Debug> TransactionWrite for Value { +impl> + Clone + Debug + Eq + PartialEq> TransactionWrite for MockValue { fn bytes(&self) -> Option<&Bytes> { self.maybe_bytes.as_ref() } @@ -88,23 +86,23 @@ impl> + Clone + Debug> TransactionWrite for Value { } } -enum Data { - Write(Value), +enum Data { + Write(MockValue), Delta(DeltaOp), } -struct Baseline(HashMap>>); +struct Baseline(HashMap>>); impl Baseline where K: Hash + Eq + Clone + Debug, - V: Clone + Into> + Debug + PartialEq, + V: Clone + Into> + Debug + Eq + PartialEq, { pub fn new(txns: &[(K, Operator)], ignore_updates: bool) -> Self { let mut baseline: HashMap>> = HashMap::new(); for (idx, (k, op)) in txns.iter().enumerate() { let value_to_update = match op { - Operator::Insert(v) => Data::Write(Value::new(Some(v.clone()))), - Operator::Remove => Data::Write(Value::new(None)), + Operator::Insert(v) => Data::Write(MockValue::new(Some(v.clone()))), + Operator::Remove => Data::Write(MockValue::new(None)), Operator::Update(d) => { if ignore_updates { continue; @@ -195,7 +193,7 @@ fn operator_strategy() -> impl Strategy Just(Operator::Remove), @@ -213,7 +211,7 @@ fn run_and_assert( ) -> Result<(), TestCaseError> where K: PartialOrd + Send + Clone + Hash + Eq + Sync + Debug, - V: Send + Into> + Debug + Clone + PartialEq + Sync, + V: Send + Into> + Debug + Clone + Eq + PartialEq + Sync, { let transactions: Vec<(K, Operator)> = transaction_gens .into_iter() @@ -221,7 +219,7 @@ where .collect::>(); let baseline = Baseline::new(transactions.as_slice(), test_group); - let map = MVHashMap::, usize, Value, ()>::new(); + let map = MVHashMap::, usize, MockValue, ()>::new(); // make ESTIMATE placeholders for all versions to be updated. // allows to test that correct values appear at the end of concurrent execution. @@ -236,7 +234,7 @@ where .collect::>(); for (key, idx) in versions_to_write { let key = KeyType(key); - let value = Value::new(None); + let value = MockValue::new(None); let idx = idx as TxnIndex; if test_group { map.group_data @@ -252,8 +250,9 @@ where HashSet::new(), ) .unwrap(); + let tags_5: Vec = vec![5]; map.group_data() - .mark_estimate(&key, idx, [5usize].into_iter().collect()); + .mark_estimate(&key, idx, tags_5.iter().collect()); } else { map.data().write(key.clone(), idx, 0, Arc::new(value), None); map.data().mark_estimate(&key, idx); @@ -279,7 +278,7 @@ where use MVDataOutput::*; let baseline = baseline.get(key, idx as TxnIndex); - let assert_value = |v: ValueWithLayout>| match v + let assert_value = |v: ValueWithLayout>| match v .extract_value_no_layout() .maybe_value .as_ref() @@ -295,7 +294,7 @@ where let mut retry_attempts = 0; loop { if test_group { - match map.group_data.fetch_tagged_data( + match map.group_data.fetch_tagged_data_no_record( &KeyType(key.clone()), &5, idx as TxnIndex, @@ -314,7 +313,7 @@ where } else { match map .data() - .fetch_data(&KeyType(key.clone()), idx as TxnIndex) + .fetch_data_no_record(&KeyType(key.clone()), idx as TxnIndex) { Ok(Versioned(_, v)) => { assert_value(v); @@ -358,7 +357,7 @@ where }, Operator::Remove => { let key = KeyType(key.clone()); - let value = Value::new(None); + let value = MockValue::new(None); if test_group { map.group_data() .write( @@ -377,7 +376,7 @@ where }, Operator::Insert(v) => { let key = KeyType(key.clone()); - let value = Value::new(Some(v.clone())); + let value = MockValue::new(Some(v.clone())); if test_group { map.group_data() .write( @@ -408,8 +407,6 @@ where Ok(()) } -// TODO: proptest MVHashMap delete and dependency handling! - proptest! { #[test] fn single_key_proptest( diff --git a/aptos-move/mvhashmap/src/unsync_map.rs b/aptos-move/mvhashmap/src/unsync_map.rs index e8eafb81045..097d073d1b1 100644 --- a/aptos-move/mvhashmap/src/unsync_map.rs +++ b/aptos-move/mvhashmap/src/unsync_map.rs @@ -29,6 +29,7 @@ use std::{ Arc, }, }; +use triomphe::Arc as TriompheArc; /// UnsyncMap is designed to mimic the functionality of MVHashMap for sequential execution. /// In this case only the latest recorded version is relevant, simplifying the implementation. @@ -126,7 +127,7 @@ impl< ) -> anyhow::Result<()> { let base_map: HashMap> = base_values .into_iter() - .map(|(t, v)| (t, ValueWithLayout::RawFromStorage(Arc::new(v)))) + .map(|(t, v)| (t, ValueWithLayout::RawFromStorage(TriompheArc::new(v)))) .collect(); let base_size = group_size_as_sum( base_map @@ -155,7 +156,7 @@ impl< group_key: K, tag: T, value: V, - layout: Option>, + layout: Option>, ) { self.group_cache .borrow_mut() @@ -163,7 +164,10 @@ impl< .expect("Unable to fetch the entry for the group key in group_cache") .borrow_mut() .0 - .insert(tag, ValueWithLayout::Exchanged(Arc::new(value), layout)); + .insert( + tag, + ValueWithLayout::Exchanged(TriompheArc::new(value), layout), + ); } pub fn get_group_size(&self, group_key: &K) -> Option { @@ -196,7 +200,7 @@ impl< &self, group_key: &K, ) -> ( - impl Iterator)>, + impl Iterator)> + use, ResourceGroupSize, ) { let binding = self.group_cache.borrow(); @@ -211,7 +215,7 @@ impl< pub fn insert_group_ops( &self, group_key: &K, - group_ops: impl IntoIterator>))>, + group_ops: impl IntoIterator>))>, group_size: ResourceGroupSize, ) -> Result<(), PanicError> { for (value_tag, (group_op, maybe_layout)) in group_ops.into_iter() { @@ -231,7 +235,7 @@ impl< group_key: &K, value_tag: T, v: V, - maybe_layout: Option>, + maybe_layout: Option>, ) -> Result<(), PanicError> { use aptos_types::write_set::WriteOpKind::*; use std::collections::hash_map::Entry::*; @@ -249,10 +253,16 @@ impl< entry.remove(); }, (Occupied(mut entry), Modification) => { - entry.insert(ValueWithLayout::Exchanged(Arc::new(v), maybe_layout)); + entry.insert(ValueWithLayout::Exchanged( + TriompheArc::new(v), + maybe_layout, + )); }, (Vacant(entry), Creation) => { - entry.insert(ValueWithLayout::Exchanged(Arc::new(v), maybe_layout)); + entry.insert(ValueWithLayout::Exchanged( + TriompheArc::new(v), + maybe_layout, + )); }, (l, r) => { return Err(code_invariant_error(format!( @@ -272,21 +282,28 @@ impl< self.resource_map.borrow().get(key).cloned() } - pub fn fetch_exchanged_data(&self, key: &K) -> Option<(Arc, Arc)> { - if let Some(ValueWithLayout::Exchanged(value, Some(layout))) = self.fetch_data(key) { - Some((value, layout)) + pub fn fetch_exchanged_data( + &self, + key: &K, + ) -> Result<(TriompheArc, TriompheArc), PanicError> { + let data = self.fetch_data(key); + if let Some(ValueWithLayout::Exchanged(value, Some(layout))) = data { + Ok((value, layout)) } else { - None + Err(code_invariant_error(format!( + "Read value needing exchange {:?} does not exist or not in Exchanged format", + data + ))) } } - pub fn fetch_group_data(&self, key: &K) -> Option, ValueWithLayout)>> { + pub fn fetch_group_data(&self, key: &K) -> Option, ValueWithLayout)>> { self.group_cache.borrow().get(key).map(|group_map| { group_map .borrow() .0 .iter() - .map(|(tag, value)| (Arc::new(tag.clone()), value.clone())) + .map(|(tag, value)| (TriompheArc::new(tag.clone()), value.clone())) .collect() }) } @@ -295,7 +312,12 @@ impl< self.delayed_field_map.borrow().get(id).cloned() } - pub fn write(&self, key: K, value: Arc, layout: Option>) { + pub fn write( + &self, + key: K, + value: TriompheArc, + layout: Option>, + ) { self.resource_map .borrow_mut() .insert(key, ValueWithLayout::Exchanged(value, layout)); @@ -358,15 +380,15 @@ mod test { assert_eq!(committed.len(), 3); assert_some_eq!( committed.get(&1), - &ValueWithLayout::RawFromStorage(Arc::new(TestValue::with_kind(1, true))) + &ValueWithLayout::RawFromStorage(TriompheArc::new(TestValue::with_kind(1, true))) ); assert_some_eq!( committed.get(&2), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(202, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(202, false)), None) ); assert_some_eq!( committed.get(&3), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(203, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(203, false)), None) ); assert_ok!(map.insert_group_op(&ap, 3, TestValue::with_kind(303, false), None)); @@ -375,19 +397,19 @@ mod test { assert_eq!(committed.len(), 4); assert_some_eq!( committed.get(&1), - &ValueWithLayout::RawFromStorage(Arc::new(TestValue::with_kind(1, true))) + &ValueWithLayout::RawFromStorage(TriompheArc::new(TestValue::with_kind(1, true))) ); assert_some_eq!( committed.get(&2), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(202, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(202, false)), None) ); assert_some_eq!( committed.get(&3), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(303, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(303, false)), None) ); assert_some_eq!( committed.get(&4), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(304, true)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(304, true)), None) ); assert_ok!(map.insert_group_op(&ap, 0, TestValue::with_kind(100, true), None)); @@ -397,20 +419,20 @@ mod test { assert_eq!(committed.len(), 4); assert_some_eq!( committed.get(&0), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(100, true)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(100, true)), None) ); assert_none!(committed.get(&1)); assert_some_eq!( committed.get(&2), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(202, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(202, false)), None) ); assert_some_eq!( committed.get(&3), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(303, false)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(303, false)), None) ); assert_some_eq!( committed.get(&4), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(304, true)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(304, true)), None) ); assert_ok!(map.insert_group_op(&ap, 0, TestValue::deletion(), None)); @@ -422,7 +444,7 @@ mod test { assert_eq!(committed.len(), 1); assert_some_eq!( committed.get(&1), - &ValueWithLayout::Exchanged(Arc::new(TestValue::with_kind(400, true)), None) + &ValueWithLayout::Exchanged(TriompheArc::new(TestValue::with_kind(400, true)), None) ); } @@ -567,7 +589,7 @@ mod test { for i in 1..5 { assert_ok_eq!( map.fetch_group_tagged_data(&ap, &i), - ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(i)),) + ValueWithLayout::RawFromStorage(TriompheArc::new(TestValue::creation_with_len(i)),) ); } assert_err_eq!( @@ -589,11 +611,11 @@ mod test { ); assert_ok_eq!( map.fetch_group_tagged_data(&ap, &3), - ValueWithLayout::Exchanged(Arc::new(TestValue::modification_with_len(8)), None,) + ValueWithLayout::Exchanged(TriompheArc::new(TestValue::modification_with_len(8)), None,) ); assert_ok_eq!( map.fetch_group_tagged_data(&ap, &6), - ValueWithLayout::Exchanged(Arc::new(TestValue::creation_with_len(9)), None,) + ValueWithLayout::Exchanged(TriompheArc::new(TestValue::creation_with_len(9)), None,) ); // others unaffected. @@ -603,11 +625,11 @@ mod test { ); assert_ok_eq!( map.fetch_group_tagged_data(&ap, &2), - ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(2)),) + ValueWithLayout::RawFromStorage(TriompheArc::new(TestValue::creation_with_len(2)),) ); assert_ok_eq!( map.fetch_group_tagged_data(&ap, &4), - ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(4)),) + ValueWithLayout::RawFromStorage(TriompheArc::new(TestValue::creation_with_len(4)),) ); } } diff --git a/aptos-move/mvhashmap/src/versioned_data.rs b/aptos-move/mvhashmap/src/versioned_data.rs index aed65b5a9bd..ddbf02f3ad5 100644 --- a/aptos-move/mvhashmap/src/versioned_data.rs +++ b/aptos-move/mvhashmap/src/versioned_data.rs @@ -2,25 +2,31 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::types::{ - Incarnation, MVDataError, MVDataOutput, ShiftedTxnIndex, TxnIndex, ValueWithLayout, +use crate::{ + registered_dependencies::{ + check_lowest_dependency_idx, take_dependencies, RegisteredReadDependencies, + }, + types::{Incarnation, MVDataError, MVDataOutput, ShiftedTxnIndex, TxnIndex, ValueWithLayout}, }; use anyhow::Result; use aptos_aggregator::delta_change_set::DeltaOp; -use aptos_types::write_set::TransactionWrite; -use claims::assert_some; +use aptos_infallible::Mutex; +use aptos_types::{ + error::{code_invariant_error, PanicError}, + write_set::TransactionWrite, +}; +use claims::{assert_ok, assert_some}; use crossbeam::utils::CachePadded; use dashmap::DashMap; +use equivalent::Equivalent; use move_core_types::value::MoveTypeLayout; use std::{ collections::btree_map::{self, BTreeMap}, fmt::Debug, hash::Hash, - sync::{ - atomic::{AtomicBool, AtomicU64, Ordering}, - Arc, - }, + sync::atomic::{AtomicBool, AtomicU64, Ordering}, }; +use triomphe::Arc; pub(crate) const FLAG_DONE: bool = false; pub(crate) const FLAG_ESTIMATE: bool = true; @@ -43,7 +49,11 @@ enum EntryCell { /// has: 1) Incarnation number of the transaction that wrote the entry (note /// that TxnIndex is part of the key and not recorded here), 2) actual data /// stored in a shared pointer (to ensure ownership and avoid clones). - Write(Incarnation, ValueWithLayout), + ResourceWrite { + incarnation: Incarnation, + value_with_layout: ValueWithLayout, + dependencies: Mutex, + }, /// Recorded in the shared multi-version data-structure for each delta. /// Option is a shortcut to aggregated value (to avoid traversing down @@ -63,8 +73,16 @@ pub struct VersionedData { total_base_value_size: AtomicU64, } -fn new_write_entry(incarnation: Incarnation, value: ValueWithLayout) -> Entry> { - Entry::new(EntryCell::Write(incarnation, value)) +fn new_write_entry( + incarnation: Incarnation, + value: ValueWithLayout, + dependencies: BTreeMap, +) -> Entry> { + Entry::new(EntryCell::ResourceWrite { + incarnation, + value_with_layout: value, + dependencies: Mutex::new(RegisteredReadDependencies::from_dependencies(dependencies)), + }) } fn new_delta_entry(data: DeltaOp) -> Entry> { @@ -115,14 +133,124 @@ impl Default for VersionedValue { } } -impl VersionedValue { - fn read(&self, txn_idx: TxnIndex) -> anyhow::Result, MVDataError> { +// TODO(BlockSTMv2): remove TransactionWrite trait requirement from V, even if +// AggregatorV1 code is not removed by definining a more specialized trait that can +// runtime assert in other variants. Add other variants to stored cells that allow +// storing group metadata and group size together at the group key (currently metadata +// is stored in a fake write entry, and group size is stored in MVGroupData map). +impl VersionedValue { + // Extracts read dependencies from the data-structure that are affected by a write + // of 'data' at 'txn_idx'. Some of these dependencies that remain valid can be + // relocated by a caller to a different (new) entry in the data-structure. The + // boolean flag indicates whether the dependency is still valid after the write. + fn split_off_affected_read_dependencies( + &self, + txn_idx: TxnIndex, + new_data: &Arc, + new_maybe_layout: &Option>, + ) -> (BTreeMap, bool) { + let mut affected_deps = BTreeMap::new(); + let mut still_valid = false; + + // Look at entries at or below txn_idx, which is where all the affected + // dependencies may be stored. Here, for generality, we assume that there + // may also be an entry at txn_idx, which could be getting overwritten, + // in which case all of its dependencies would be considered affected. + if let Some((_, entry)) = self + .versioned_map + .range(..=ShiftedTxnIndex::new(txn_idx)) + .next_back() + { + // Non-exchanged format is default validation failure. + if let EntryCell::ResourceWrite { + incarnation: _, + value_with_layout, + dependencies, + } = &entry.value + { + // Take dependencies above txn_idx + affected_deps = dependencies.lock().split_off(txn_idx + 1); + if !affected_deps.is_empty() { + if let ValueWithLayout::Exchanged( + previous_entry_value, + previous_entry_maybe_layout, + ) = value_with_layout + { + still_valid = compare_values_and_layouts::( + previous_entry_value, + new_data, + previous_entry_maybe_layout.as_ref(), + new_maybe_layout.as_ref(), + ); + } + } + } + } + (affected_deps, still_valid) + } + + /// Handle dependencies from a removed entry by validating against the next (lower) entry. + /// The caller MUST ensure that the entry at txn_idx has been removed from versioned_map + /// before calling this method. If the lower entry does not exist, all dependencies are + /// considered invalidated. A re-execution of the read can then create a baseline sentinel + /// entry, if needed. Data is the value that was stored in the removed entry. + fn handle_removed_dependencies( + &mut self, + txn_idx: TxnIndex, + mut dependencies: BTreeMap, + removed_data: &Arc, + removed_maybe_layout: &Option>, + ) -> Result, PanicError> { + // If we have dependencies and a next (lower) entry exists, validate against it. + if !dependencies.is_empty() { + if let Some((idx, next_lower_entry)) = self + .versioned_map + .range(..=ShiftedTxnIndex::new(txn_idx)) + .next_back() + { + assert_ne!( + idx.idx(), + Ok(txn_idx), + "Entry at txn_idx must be removed before calling handle_removed_dependencies" + ); + + // Non-exchanged format is default validation failure. + if let EntryCell::ResourceWrite { + incarnation: _, + value_with_layout: ValueWithLayout::Exchanged(entry_value, entry_maybe_layout), + dependencies: next_lower_deps, + } = &next_lower_entry.value + { + let still_valid = compare_values_and_layouts::( + entry_value, + removed_data, + entry_maybe_layout.as_ref(), + removed_maybe_layout.as_ref(), + ); + + if still_valid { + next_lower_deps + .lock() + .extend_with_higher_dependencies(std::mem::take(&mut dependencies))?; + } + } + } + } + Ok(dependencies) + } + + // 'maybe_reader_incarnation' is None for BlockSTMv1 and always set for BlockSTMv2. + fn read( + &self, + reader_txn_idx: TxnIndex, + maybe_reader_incarnation: Option, + ) -> Result, MVDataError> { use MVDataError::*; use MVDataOutput::*; let mut iter = self .versioned_map - .range(ShiftedTxnIndex::zero_idx()..ShiftedTxnIndex::new(txn_idx)); + .range(ShiftedTxnIndex::zero_idx()..ShiftedTxnIndex::new(reader_txn_idx)); // If read encounters a delta, it must traverse the block of transactions // (top-down) until it encounters a write or reaches the end of the block. @@ -130,6 +258,10 @@ impl VersionedValue { let mut accumulator: Option> = None; while let Some((idx, entry)) = iter.next_back() { if entry.is_estimate() { + debug_assert!( + maybe_reader_incarnation.is_none(), + "Entry must not be marked as estimate for BlockSTMv2" + ); // Found a dependency. return Err(Dependency( idx.idx().expect("May not depend on storage version"), @@ -137,17 +269,41 @@ impl VersionedValue { } match (&entry.value, accumulator.as_mut()) { - (EntryCell::Write(incarnation, data), None) => { + ( + EntryCell::ResourceWrite { + incarnation, + value_with_layout, + dependencies, + }, + None, + ) => { + // Record the read dependency (only in V2 case, not to add contention to V1). + if let Some(reader_incarnation) = maybe_reader_incarnation { + // TODO(BlockSTMv2): convert to PanicErrors after MVHashMap refactoring. + assert_ok!(dependencies + .lock() + .insert(reader_txn_idx, reader_incarnation)); + } + // Resolve to the write if no deltas were applied in between. return Ok(Versioned( idx.idx().map(|idx| (idx, *incarnation)), - data.clone(), + value_with_layout.clone(), )); }, - (EntryCell::Write(incarnation, data), Some(accumulator)) => { + ( + EntryCell::ResourceWrite { + incarnation, + value_with_layout, + // We ignore dependencies here because accumulator is set, i.e. + // we are dealing with AggregatorV1 flow w.o. push validation. + dependencies: _, + }, + Some(accumulator), + ) => { // Deltas were applied. We must deserialize the value // of the write and apply the aggregated delta accumulator. - let value = data.extract_value_no_layout(); + let value = value_with_layout.extract_value_no_layout(); return match value .as_u128() .expect("Aggregator value must deserialize to u128") @@ -158,7 +314,7 @@ impl VersionedValue { // over any speculative delta accumulation errors on top. Ok(Versioned( idx.idx().map(|idx| (idx, *incarnation)), - data.clone(), + value_with_layout.clone(), )) }, Some(value) => { @@ -221,7 +377,34 @@ impl VersionedValue { } } -impl VersionedData { +// Helper function to perform push validation whereby a read of an entry containing +// prev_value with prev_maybe_layout would now be reading an entry containing new_value +// with new_maybe_layout. +fn compare_values_and_layouts< + const ONLY_COMPARE_METADATA: bool, + V: TransactionWrite + PartialEq, +>( + prev_value: &V, + new_value: &V, + prev_maybe_layout: Option<&Arc>, + new_maybe_layout: Option<&Arc>, +) -> bool { + // ONLY_COMPARE_METADATA is a const static flag that indicates that these entries are + // versioning metadata only, and not the actual value (Currently, only used for versioning + // resource group metadata). Hence, validation is only performed on the metadata. + if ONLY_COMPARE_METADATA { + prev_value.as_state_value_metadata() == new_value.as_state_value_metadata() + } else { + // Layouts pass validation only if they are both None. Otherwise, validation pessimistically + // fails. This is a simple logic that avoids potentially costly layout comparisons. + prev_maybe_layout.is_none() && new_maybe_layout.is_none() && prev_value == new_value + } + // TODO(BlockSTMv2): optimize layout validation (potentially based on size, or by having + // a more efficient representation. Optimizing value validation by having a configurable + // size threshold above which validation can automatically pessimistically fail. +} + +impl VersionedData { pub(crate) fn empty() -> Self { Self { values: DashMap::new(), @@ -247,7 +430,14 @@ impl VersionedData { /// Mark an entry from transaction 'txn_idx' at access path 'key' as an estimated write /// (for future incarnation). Will panic if the entry is not in the data-structure. - pub fn mark_estimate(&self, key: &K, txn_idx: TxnIndex) { + /// Use the Equivalent trait for key lookup. This avoids having to clone the key when + /// only a reference is needed. + pub fn mark_estimate(&self, key: &Q, txn_idx: TxnIndex) + where + Q: Equivalent + Hash, + { + // Use dashmap's get method which accepts a reference when Borrow is implemented + // The equivalent crate automatically implements the right traits. let v = self.values.get(key).expect("Path must exist"); v.versioned_map .get(&ShiftedTxnIndex::new(txn_idx)) @@ -257,7 +447,10 @@ impl VersionedData { /// Delete an entry from transaction 'txn_idx' at access path 'key'. Will panic /// if the corresponding entry does not exist. - pub fn remove(&self, key: &K, txn_idx: TxnIndex) { + pub fn remove(&self, key: &Q, txn_idx: TxnIndex) + where + Q: Equivalent + Hash, + { // TODO: investigate logical deletion. let mut v = self.values.get_mut(key).expect("Path must exist"); assert_some!( @@ -266,62 +459,148 @@ impl VersionedData { ); } - pub fn fetch_data( + /// Delete an entry from transaction 'txn_idx' at access path 'key' for BlockSTMv2. + /// Returns read dependencies from the entry that are no longer valid, panics if + /// the entry does not exist. + pub fn remove_v2( &self, - key: &K, + key: &Q, + txn_idx: TxnIndex, + ) -> Result, PanicError> + where + Q: Equivalent + Hash + Debug, + { + let mut v = self.values.get_mut(key).ok_or_else(|| { + code_invariant_error(format!("Path must exist for remove_v2: {:?}", key)) + })?; + + // Get the entry to be removed + let removed_entry = v + .versioned_map + .remove(&ShiftedTxnIndex::new(txn_idx)) + .ok_or_else(|| { + code_invariant_error(format!( + "Entry for key / idx must exist to be deleted: {:?}, {}", + key, txn_idx + )) + })?; + + if let EntryCell::ResourceWrite { + incarnation: _, + value_with_layout, + dependencies, + } = &removed_entry.value + { + match value_with_layout { + ValueWithLayout::RawFromStorage(_) => { + unreachable!( + "Removed value written by txn {txn_idx} may not be RawFromStorage" + ); + }, + ValueWithLayout::Exchanged(data, layout) => { + let removed_deps = take_dependencies(dependencies); + v.handle_removed_dependencies::( + txn_idx, + removed_deps, + data, + layout, + ) + }, + } + } else { + Ok(BTreeMap::new()) + } + } + + // Fetches data but does not record a read dependency. This is used for BlockSTMv1 + // or for BlockSTMv2 post-commit final (for safety) validation. + pub fn fetch_data_no_record( + &self, + key: &Q, txn_idx: TxnIndex, - ) -> anyhow::Result, MVDataError> { + ) -> anyhow::Result, MVDataError> + where + Q: Equivalent + Hash, + { self.values .get(key) - .map(|v| v.read(txn_idx)) + .map(|v| v.read(txn_idx, None)) .unwrap_or(Err(MVDataError::Uninitialized)) } - pub fn fetch_exchanged_data( + // Fetches data and records a read dependency. This is used for BlockSTMv2 reads. + // TODO(BlockSTMv2): Have a dispatch or dedicated interfaces for reading data, + // metadata, size, and exists predicate. Return the appropriately cast value, record + // the kind of each read dependency, then validate accordingly on write / removal. + pub fn fetch_data_and_record_dependency( &self, - key: &K, + key: &Q, txn_idx: TxnIndex, - ) -> Option<(Arc, Arc)> { - if let Ok(MVDataOutput::Versioned(_, ValueWithLayout::Exchanged(value, Some(layout)))) = - self.fetch_data(key, txn_idx) - { - Some((value, layout)) - } else { - None - } + incarnation: Incarnation, + ) -> Result, MVDataError> + where + Q: Equivalent + Hash, + { + self.values + .get(key) + .map(|v| v.read(txn_idx, Some(incarnation))) + .unwrap_or(Err(MVDataError::Uninitialized)) } - pub fn set_base_value(&self, key: K, value: ValueWithLayout) { + // The caller needs to repeat the read after set_base_value (concurrent caller might have + // exchanged and stored a different delayed field ID). + pub fn set_base_value(&self, key: K, base_value_with_layout: ValueWithLayout) { let mut v = self.values.entry(key).or_default(); // For base value, incarnation is irrelevant, and is always set to 0. use btree_map::Entry::*; use ValueWithLayout::*; match v.versioned_map.entry(ShiftedTxnIndex::zero_idx()) { - Vacant(v) => { - if let Some(base_size) = value.bytes_len() { + Vacant(vacant_entry) => { + if let Some(base_size) = base_value_with_layout.bytes_len() { self.total_base_value_size .fetch_add(base_size as u64, Ordering::Relaxed); } - v.insert(CachePadded::new(new_write_entry(0, value))); + vacant_entry.insert(CachePadded::new(new_write_entry( + 0, + base_value_with_layout, + BTreeMap::new(), + ))); }, Occupied(mut o) => { - if let EntryCell::Write(i, existing_value) = &o.get().value { - assert!(*i == 0); - match (existing_value, &value) { - (RawFromStorage(ev), RawFromStorage(v)) => { + if let EntryCell::ResourceWrite { + incarnation, + value_with_layout: existing_value_with_layout, + dependencies, + } = &o.get().value + { + assert!(*incarnation == 0); + match (existing_value_with_layout, &base_value_with_layout) { + (RawFromStorage(existing_value), RawFromStorage(base_value)) => { // Base value from storage needs to be identical // Assert the length of bytes for efficiency (instead of full equality) - assert!(v.bytes().map(|b| b.len()) == ev.bytes().map(|b| b.len())) + assert!( + base_value.bytes().map(|b| b.len()) + == existing_value.bytes().map(|b| b.len()) + ); }, (Exchanged(_, _), RawFromStorage(_)) => { // Stored value contains more info, nothing to do. }, (RawFromStorage(_), Exchanged(_, _)) => { - // Received more info, update. - o.insert(CachePadded::new(new_write_entry(0, value))); + // Received more info, update, but keep the same dependencies. + // TODO(BlockSTMv2): Once we support dependency kind, here we could check + // that carried over dependencies can be only size & metadata. + o.insert(CachePadded::new(new_write_entry( + 0, + base_value_with_layout, + take_dependencies(dependencies), + ))); }, - (Exchanged(ev, e_layout), Exchanged(v, layout)) => { + ( + Exchanged(existing_value, existing_layout), + Exchanged(base_value, base_layout), + ) => { // base value may have already been provided by another transaction // executed simultaneously and asking for the same resource. // Value from storage must be identical, but then delayed field @@ -330,9 +609,12 @@ impl VersionedData { // If maybe_layout is None, they are required to be identical // If maybe_layout is Some, there might have been an exchange // Assert the length of bytes for efficiency (instead of full equality) - assert_eq!(e_layout.is_some(), layout.is_some()); - if layout.is_none() { - assert_eq!(v.bytes().map(|b| b.len()), ev.bytes().map(|b| b.len())); + assert_eq!(existing_layout.is_some(), base_layout.is_some()); + if existing_layout.is_none() { + assert_eq!( + existing_value.bytes().map(|b| b.len()), + base_value.bytes().map(|b| b.len()) + ); } }, } @@ -341,34 +623,95 @@ impl VersionedData { }; } - /// Versioned write of data at a given key (and version). - pub fn write( - &self, - key: K, + fn write_impl( + versioned_values: &mut VersionedValue, txn_idx: TxnIndex, incarnation: Incarnation, - data: Arc, - maybe_layout: Option>, + value: ValueWithLayout, + dependencies: BTreeMap, ) { - let mut v = self.values.entry(key).or_default(); - let prev_entry = v.versioned_map.insert( + let prev_entry = versioned_values.versioned_map.insert( ShiftedTxnIndex::new(txn_idx), - CachePadded::new(new_write_entry( - incarnation, - ValueWithLayout::Exchanged(data, maybe_layout), - )), + CachePadded::new(new_write_entry(incarnation, value, dependencies)), ); // Assert that the previous entry for txn_idx, if present, had lower incarnation. - assert!(prev_entry.map_or(true, |entry| -> bool { - if let EntryCell::Write(i, _) = entry.value { - i < incarnation + assert!(prev_entry.is_none_or(|entry| -> bool { + if let EntryCell::ResourceWrite { + incarnation: prev_incarnation, + .. + } = &entry.value + { + // For BlockSTMv1, the dependencies are always empty. + *prev_incarnation < incarnation + // TODO(BlockSTMv2): when AggregatorV1 is deprecated, we can assert that + // prev_dependencies is empty: they must have been drained beforehand + // (into dependencies) if there was an entry at the same index before. } else { true } })); } + pub fn write( + &self, + key: K, + txn_idx: TxnIndex, + incarnation: Incarnation, + data: Arc, + maybe_layout: Option>, + ) { + let mut v = self.values.entry(key).or_default(); + Self::write_impl( + &mut v, + txn_idx, + incarnation, + ValueWithLayout::Exchanged(data, maybe_layout), + BTreeMap::new(), + ); + } + + /// Write a value at a given key (and version) for BlockSTMv2. + /// Returns invalidated affected read dependencies (dependencies that failed push validation). + pub fn write_v2( + &self, + key: K, + txn_idx: TxnIndex, + incarnation: Incarnation, + data: Arc, + maybe_layout: Option>, + ) -> Result, PanicError> { + let mut v = self.values.entry(key).or_default(); + let (affected_dependencies, validation_passed) = v + .split_off_affected_read_dependencies::( + txn_idx, + &data, + &maybe_layout, + ); + + // Asserted (local, easily checkable invariant), since affected dependencies are obtained + // by calling split_off at txn_idx + 1. + assert!(check_lowest_dependency_idx(&affected_dependencies, txn_idx).is_ok()); + + // If validation passed, keep the dependencies (pass to write_impl), o.w. return them + // (invalidated read dependencies) to the caller. + let (deps_to_retain, deps_to_return) = if validation_passed { + (affected_dependencies, BTreeMap::new()) + } else { + (BTreeMap::new(), affected_dependencies) + }; + + Self::write_impl( + &mut v, + txn_idx, + incarnation, + ValueWithLayout::Exchanged(data, maybe_layout), + deps_to_retain, + ); + + Ok(deps_to_return) + } + /// Versioned write of metadata at a given resource group key (and version). Returns true /// if the previously stored metadata has changed as observed by later transactions (e.g. /// metadata of a deletion can never be observed by later transactions). @@ -387,14 +730,19 @@ impl VersionedData { CachePadded::new(new_write_entry( incarnation, ValueWithLayout::Exchanged(arc_data.clone(), None), + BTreeMap::new(), )), ); // Changes versioned metadata that was stored. - prev_entry.map_or(true, |entry| -> bool { - if let EntryCell::Write(_, existing_v) = &entry.value { + prev_entry.is_none_or(|entry| -> bool { + if let EntryCell::ResourceWrite { + value_with_layout: existing_value_with_layout, + .. + } = &entry.value + { arc_data.as_state_value_metadata() - != existing_v + != existing_value_with_layout .extract_value_no_layout() .as_state_value_metadata() } else { @@ -414,7 +762,7 @@ impl VersionedData { let mut v = self.values.get_mut(key).expect("Path must exist"); // +1 makes sure we include the delta from txn_idx. - match v.read(txn_idx + 1) { + match v.read(txn_idx + 1, None) { Ok(MVDataOutput::Resolved(value)) => { v.versioned_map .get_mut(&ShiftedTxnIndex::new(txn_idx)) @@ -430,4 +778,688 @@ impl VersionedData { ), } } + + #[cfg(test)] + pub(crate) fn get_dependencies( + &self, + key: &K, + shifted_txn_idx: ShiftedTxnIndex, + ) -> BTreeMap { + match &self + .values + .get(key) + .expect("Entry must exist for the given key") + .versioned_map + .get(&shifted_txn_idx) + .expect("Entry must exist for the given txn_idx") + .value + { + EntryCell::ResourceWrite { dependencies, .. } => { + dependencies.lock().clone_dependencies_for_test() + }, + _ => unreachable!("Dependencies can only be recorded for resource writes"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::StorageVersion; + use aptos_aggregator::{bounded_math::SignedU128, delta_math::DeltaHistory}; + use aptos_types::{ + on_chain_config::CurrentTimeMicroseconds, + state_store::state_value::{StateValue, StateValueMetadata}, + write_set::{TransactionWrite, WriteOpKind}, + }; + use bytes::Bytes; + use claims::{assert_err, assert_ok_eq}; + use fail::FailScenario; + use test_case::test_case; + + #[derive(Debug, Clone, PartialEq, Eq)] + struct TestValueWithMetadata { + value: u64, + metadata: u64, + } + + impl TestValueWithMetadata { + fn new(value: u64, metadata: u64) -> Self { + Self { value, metadata } + } + } + + impl TransactionWrite for TestValueWithMetadata { + fn bytes(&self) -> Option<&Bytes> { + unimplemented!("Irrelevant for the test") + } + + fn write_op_kind(&self) -> WriteOpKind { + unimplemented!("Irrelevant for the test") + } + + fn from_state_value(_maybe_state_value: Option) -> Self { + unimplemented!("Irrelevant for the test") + } + + fn as_state_value(&self) -> Option { + unimplemented!("Irrelevant for the test") + } + + fn set_bytes(&mut self, _bytes: Bytes) { + unimplemented!("Irrelevant for the test") + } + + fn as_state_value_metadata(&self) -> Option { + Some(StateValueMetadata::legacy( + self.metadata, + &CurrentTimeMicroseconds { + microseconds: self.metadata, + }, + )) + } + } + + fn get_deps_from_entry( + entry: &Entry>, + ) -> BTreeMap { + if let EntryCell::ResourceWrite { dependencies, .. } = &entry.value { + dependencies.lock().clone_dependencies_for_test() + } else { + unreachable!() + } + } + + #[test_case(1, BTreeMap::from([(2, 0), (3, 1), (7, 1)]), true; "deps > 1 from idx 0 write, pass validation")] + #[test_case(7, BTreeMap::from([(8, 1), (9, 0), (10, 2)]), false; "deps > 7 from idx 7 write, fail validation")] + #[test_case(5, BTreeMap::from([(7, 1)]), true; "deps > 5 from write at idx 0, pass validation")] + #[test_case(0, BTreeMap::from([(1, 0), (2, 0), (3, 1), (7, 1)]), true; "all deps > 0 from idx 0 write, pass validation")] + #[test_case(9, BTreeMap::from([(10, 2)]), false; "deps > 9 from write at idx 7, fail validation")] + #[test_case(12, BTreeMap::from([]), false; "entries >= idx 12 - no deps, default fail validation")] + #[test_case(7, BTreeMap::from([(8, 1), (9, 0), (10, 2)]), false; "all deps from write at idx 7, fail validation")] + fn test_split_off_affected_read_dependencies( + idx: TxnIndex, + expected_deps: BTreeMap, + expected_validation_result: bool, + ) { + let mut v = VersionedValue::::default(); + + // Setup: Create some writes with dependencies. + let deps_idx0 = BTreeMap::from([(1, 0), (2, 0)]); + let deps_idx7 = BTreeMap::from([(8, 1), (9, 0), (10, 1)]); + + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + deps_idx0, + )), + ); + v.versioned_map.insert( + ShiftedTxnIndex::new(7), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(20, 200)), None), + deps_idx7, + )), + ); + + // Add some dependencies via read() calls. + let _ = v.read(3, Some(0)); // This adds (3, 0) to latest write <= 3 (write at idx 0). + let _ = v.read(3, Some(1)); // Add another incarnation of txn 3. + let _ = v.read(7, Some(1)); // This adds (7, 1) to write at idx 0. + // TODO: when using PanicErrors, check is_ok(), and is_err() when adding duplicate or + // outdated incarnation. + let _ = v.read(10, Some(2)); // Only the latest added (higher) incarnations must be recorded. + + // Get pre-call state of dependencies. + let mut recorded_deps_idx0 = + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()); + let mut recorded_deps_idx7 = + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(7)).unwrap()); + + // Get the actual dependencies and verify they match expected. + let (affected_deps, validation_passed) = v.split_off_affected_read_dependencies::( + idx, + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ); + assert_eq!( + affected_deps, expected_deps, + "Dependencies above idx don't match expected." + ); + assert_eq!( + validation_passed, expected_validation_result, + "Validation result doesn't match expected." + ); + + // Verify that the remaining dependencies in entries match what we expect. + if idx < 7 { + let (remaining_deps, _) = v.split_off_affected_read_dependencies::( + 6, + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ); + assert!(remaining_deps.is_empty()); + recorded_deps_idx0.retain(|txn_idx, _| *txn_idx <= idx); + } else { + recorded_deps_idx7.retain(|txn_idx, _| *txn_idx <= idx); + } + + let final_deps_idx0 = + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()); + assert_eq!( + final_deps_idx0, recorded_deps_idx0, + "Dependencies in write at idx 0 don't match expected." + ); + + let final_deps_idx7 = + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(7)).unwrap()); + assert_eq!( + final_deps_idx7, recorded_deps_idx7, + "Dependencies in write at idx 7 don't match expected." + ); + } + + #[should_panic] + #[test_case(0)] + #[test_case(1)] + fn test_read_panic_outdated_incarnation(outdated_incarnation: Incarnation) { + let mut v = VersionedValue::::default(); + v.versioned_map.insert( + ShiftedTxnIndex::new(2), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + BTreeMap::from([(5, 2)]), + )), + ); + + let _ = v.read(5, Some(outdated_incarnation)); + } + + #[test] + fn test_split_off_affected_read_dependencies_delta_only() { + let mut v = VersionedValue::::default(); + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_delta_entry(DeltaOp::new( + SignedU128::Positive(10), + 1000, + DeltaHistory { + max_achieved_positive_delta: 10, + min_achieved_negative_delta: 0, + min_overflow_positive_delta: None, + max_underflow_negative_delta: None, + }, + ))), + ); + v.versioned_map.insert( + ShiftedTxnIndex::new(5), + CachePadded::new(new_delta_entry(DeltaOp::new( + SignedU128::Positive(20), + 1000, + DeltaHistory { + max_achieved_positive_delta: 20, + min_achieved_negative_delta: 0, + min_overflow_positive_delta: None, + max_underflow_negative_delta: None, + }, + ))), + ); + let (deps, _) = v.split_off_affected_read_dependencies::( + 3, + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ); + assert_eq!(deps, BTreeMap::new()); + } + + #[test] + fn test_value_metadata_layout_comparison() { + macro_rules! test_metadata_layout_case { + ($only_compare_metadata:expr) => { + // Test all combinations of value/metadata/layout comparison parameters + for same_value in [true, false] { + for same_metadata in [true, false] { + for no_layouts in [true, false] { + let mut v = VersionedValue::::default(); + + // Setup: Create a write with value 10, metadata 100 and one dependency + let deps = BTreeMap::from([(1, 0)]); + let layout = if no_layouts { None } else { Some(Arc::new(MoveTypeLayout::Bool)) }; + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry(0, ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), layout), deps)), + ); + + // Create test value based on parameters + let test_value = TestValueWithMetadata::new( + if same_value { 10 } else { 20 }, + if same_metadata { 100 } else { 200 } + ); + + // Compute expected validation result + let expected_validation = if $only_compare_metadata { + same_metadata + } else { + same_value && same_metadata && no_layouts + }; + + // Test split_off_affected_read_dependencies + let (deps, validation_passed) = v.split_off_affected_read_dependencies::<{ $only_compare_metadata }>( + 0, + &Arc::new(test_value.clone()), + &None, + ); + + // Verify results + assert_eq!( + validation_passed, + expected_validation, + "Validation failed for same_value={}, same_metadata={}, only_compare_metadata={}, no_layouts={}", + same_value, same_metadata, $only_compare_metadata, no_layouts + ); + assert_eq!( + deps, + BTreeMap::from([(1, 0)]), + "Dependencies don't match for same_value={}, same_metadata={}, only_compare_metadata={}, no_layouts={}", + same_value, same_metadata, $only_compare_metadata, no_layouts + ); + + // Test handle_removed_dependencies + let remaining_deps = v.handle_removed_dependencies::<{ $only_compare_metadata }>( + 1, + BTreeMap::from([(2, 0)]), + &Arc::new(test_value), + &None, + ).unwrap(); + + if expected_validation { + assert!(remaining_deps.is_empty()); + // Verify that (2,0) is recorded in 0-th entry + assert_eq!(get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()), BTreeMap::from([(2, 0)])); + } else { + assert_eq!(remaining_deps, BTreeMap::from([(2, 0)])); + // Verify that dependencies are empty in 0-th entry + assert_eq!(get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()).len(), 0); + } + } + } + } + }; + } + + // Test both cases + test_metadata_layout_case!(true); + test_metadata_layout_case!(false); + } + + #[test] + fn test_same_layout_validation_fails() { + let mut v = VersionedValue::::default(); + + // Setup: Create a write with value 10, metadata 100 and layout Some(Bool) + let deps = BTreeMap::from([(1, 0)]); + let layout = Some(Arc::new(MoveTypeLayout::Bool)); + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged( + Arc::new(TestValueWithMetadata::new(10, 100)), + layout.clone(), + ), + deps, + )), + ); + + // Create test value with same value, metadata, and layout + let test_value = TestValueWithMetadata::new(10, 100); + + // Test split_off_affected_read_dependencies with ONLY_COMPARE_METADATA = false + let (deps, validation_passed) = v.split_off_affected_read_dependencies::( + 0, + &Arc::new(test_value.clone()), + &layout, + ); + + // Validation should fail because both layouts are Some, even though they're identical + assert!( + !validation_passed, + "Validation should fail when both layouts are Some, even if identical" + ); + assert_eq!( + deps, + BTreeMap::from([(1, 0)]), + "Dependencies should be returned" + ); + + // Test handle_removed_dependencies + let remaining_deps = v + .handle_removed_dependencies::( + 1, + BTreeMap::from([(2, 0)]), + &Arc::new(test_value), + &layout, + ) + .unwrap(); + + assert_eq!( + remaining_deps, + BTreeMap::from([(2, 0)]), + "Dependencies should be returned when validation fails" + ); + // Verify that dependencies are empty in 0-th entry (invalidated) + assert_eq!( + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()).len(), + 0, + "Dependencies should be cleared when validation fails" + ); + } + + #[test] + fn test_raw_from_storage_validation() { + macro_rules! test_raw_from_storage_case { + ($only_compare_metadata:expr) => { + let mut v = VersionedValue::::default(); + + // Setup: Create a write with RawFromStorage value and one dependency + let deps = BTreeMap::from([(1, 0)]); + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry(0, ValueWithLayout::RawFromStorage(Arc::new(TestValueWithMetadata::new(10, 100))), deps)), + ); + + // Test split_off_affected_read_dependencies with Exchanged value + let (deps, validation_passed) = v.split_off_affected_read_dependencies::<{ $only_compare_metadata }>( + 0, + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ); + + // Verify results - validation should fail even with same value and metadata + assert!(!validation_passed, "Validation should fail when comparing with RawFromStorage (only_compare_metadata={})", $only_compare_metadata); + assert_eq!(deps, BTreeMap::from([(1, 0)]), "Dependencies should be returned even when validation fails (only_compare_metadata={})", $only_compare_metadata); + + // Test handle_removed_dependencies + let remaining_deps = v.handle_removed_dependencies::<{ $only_compare_metadata }>( + 1, + BTreeMap::from([(2, 0)]), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ).unwrap(); + + // Verify that dependencies are not passed and returned + assert_eq!( + remaining_deps, + BTreeMap::from([(2, 0)]), + "Dependencies should be returned when validation fails (only_compare_metadata={})", + $only_compare_metadata + ); + assert_eq!( + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()).len(), + 0, + "Dependencies should not be passed to next entry when validation fails (only_compare_metadata={})", + $only_compare_metadata + ); + }; + } + + // Test both cases + test_raw_from_storage_case!(true); + test_raw_from_storage_case!(false); + } + + #[test] + #[should_panic( + expected = "Entry at txn_idx must be removed before calling handle_removed_dependencies" + )] + fn test_handle_removed_dependencies_panic() { + let mut v = VersionedValue::::default(); + + // Setup: Create a write entry + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + BTreeMap::new(), + )), + ); + + v.handle_removed_dependencies::( + 0, + BTreeMap::from([(2, 0)]), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ) + .unwrap(); + } + + #[test] + fn test_remove_v2_storage_version() { + let mut v = VersionedValue::::default(); + + // Setup: Create an irrelevant (higher index) write entry. + v.versioned_map.insert( + ShiftedTxnIndex::new(3), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + BTreeMap::new(), + )), + ); + + let dependency_2_0 = BTreeMap::from([(2, 0)]); + assert_eq!( + dependency_2_0, + v.handle_removed_dependencies::( + 1, + dependency_2_0.clone(), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ) + .unwrap() + ); + assert_eq!( + dependency_2_0, + v.handle_removed_dependencies::( + 1, + dependency_2_0.clone(), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ) + .unwrap() + ); + + // Now insert a new entry at index 0 that will retain the dependencies. + v.versioned_map.insert( + ShiftedTxnIndex::new(0), + CachePadded::new(new_write_entry( + 0, + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + BTreeMap::new(), + )), + ); + assert_eq!( + v.handle_removed_dependencies::( + 1, + dependency_2_0.clone(), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ) + .unwrap() + .len(), + 0 + ); + assert_eq!( + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()), + dependency_2_0 + ); + + // Error since storage version contains a dependency for txn 2, but the call implies + // there was (now removed) entry at idx 1. + assert_err!(v.handle_removed_dependencies::( + 1, + dependency_2_0.clone(), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + )); + // Error if removed dependencies contain a smaller or equal idx than itself. + assert_err!(v.handle_removed_dependencies::( + 2, + dependency_2_0, + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + )); + + assert_eq!( + v.handle_removed_dependencies::( + 2, + BTreeMap::from([(3, 1)]), + &Arc::new(TestValueWithMetadata::new(10, 100)), + &None, + ) + .unwrap() + .len(), + 0 + ); + assert_eq!( + get_deps_from_entry(v.versioned_map.get(&ShiftedTxnIndex::new(0)).unwrap()), + BTreeMap::from([(2, 0), (3, 1)]) + ); + } + + fn check_versioned_data_deps( + versioned_data: &VersionedData<(), TestValueWithMetadata>, + shifted_txn_idx: ShiftedTxnIndex, + expected_deps: BTreeMap, + ) { + assert_eq!( + get_deps_from_entry( + versioned_data + .values + .get(&()) + .unwrap() + .versioned_map + .get(&shifted_txn_idx) + .unwrap() + ), + expected_deps + ); + } + + #[test] + fn test_base_value_dep_transfer() { + let versioned_data = VersionedData::<(), TestValueWithMetadata>::empty(); + + let scenario = FailScenario::setup(); + assert!(fail::has_failpoints()); + // Failpoint returns 10 as bytes length. + fail::cfg("value_with_layout_bytes_len", "return").unwrap(); + assert!(!fail::list().is_empty()); + + versioned_data.set_base_value( + (), + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + ); + assert_eq!(versioned_data.total_base_value_size(), 10); + scenario.teardown(); + + assert_ok_eq!( + versioned_data.fetch_data_and_record_dependency(&(), 5, 1), + MVDataOutput::Versioned( + Err(StorageVersion), + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + ), + ); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::zero_idx(), + BTreeMap::from([(5, 1)]), + ); + + assert!(versioned_data + .write_v2::( + (), + 1, + 1, + Arc::new(TestValueWithMetadata::new(10, 100)), + None, + ) + .unwrap() + .is_empty()); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::zero_idx(), + BTreeMap::new(), + ); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::new(1), + BTreeMap::from([(5, 1)]), + ); + + versioned_data + .write_v2::( + (), + 3, + 0, + Arc::new(TestValueWithMetadata::new(10, 100)), + None, + ) + .unwrap(); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::zero_idx(), + BTreeMap::new(), + ); + check_versioned_data_deps(&versioned_data, ShiftedTxnIndex::new(1), BTreeMap::new()); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::new(3), + BTreeMap::from([(5, 1)]), + ); + + assert_ok_eq!( + versioned_data.fetch_data_and_record_dependency(&(), 2, 0), + MVDataOutput::Versioned( + Ok((1, 1)), + ValueWithLayout::Exchanged(Arc::new(TestValueWithMetadata::new(10, 100)), None), + ), + ); + assert_eq!( + versioned_data.remove_v2::<_, false>(&(), 3).unwrap().len(), + 0 + ); + assert_eq!( + versioned_data.remove_v2::<_, true>(&(), 1).unwrap().len(), + 0 + ); + check_versioned_data_deps( + &versioned_data, + ShiftedTxnIndex::zero_idx(), + BTreeMap::from([(2, 0), (5, 1)]), + ); + } + + #[test] + fn test_remove_v2_err_no_entry() { + let versioned_data = VersionedData::<(), TestValueWithMetadata>::empty(); + + // Add an entry at index 0 + versioned_data.write( + (), + 0, + 0, + Arc::new(TestValueWithMetadata::new(10, 100)), + None, + ); + + // Try to remove a non-existent entry at index 1 + assert_err!(versioned_data.remove_v2::<_, false>(&(), 1)); + assert_err!(versioned_data.remove_v2::<_, true>(&(), 1)); + } } diff --git a/aptos-move/mvhashmap/src/versioned_delayed_fields.rs b/aptos-move/mvhashmap/src/versioned_delayed_fields.rs index 042e0024c8d..4f2ef540422 100644 --- a/aptos-move/mvhashmap/src/versioned_delayed_fields.rs +++ b/aptos-move/mvhashmap/src/versioned_delayed_fields.rs @@ -105,7 +105,14 @@ impl VersionedValue { let bypass = match o.get().as_ref().deref() { Value(_, maybe_apply) => maybe_apply.clone().map_or(NoBypass, Bypass), Apply(apply) => Bypass(apply.clone()), - Estimate(_) => unreachable!("Entry already marked estimate"), + Estimate(_) => { + // No longer asserting here as preparing for block epilogue execution + // can rarely re-mark an entry as estimate (if the block was cut due to + // block gas limit and the txn at the index was aborted before block + // execution was halted). Return value does not matter as the entries + // will be removed before block epilogue execution. + NoBypass + }, }; o.insert(Box::new(CachePadded::new(Estimate(bypass)))); @@ -114,8 +121,15 @@ impl VersionedValue { }; } - fn remove(&mut self, txn_idx: TxnIndex) { + fn remove(&mut self, txn_idx: TxnIndex, is_blockstm_v2: bool) { let deleted_entry = self.versioned_map.remove(&txn_idx); + + // TODO(BlockSTMv2): deal w. V2 & estimates and potentially bring back the check + // that removed entry must be an estimate (but with PanicError). + if is_blockstm_v2 { + return; + } + // Entries should only be deleted if the transaction that produced them is // aborted and re-executed, but abort must have marked the entry as an Estimate. assert_matches!( @@ -165,11 +179,13 @@ impl VersionedValue { // Bypass stored in the estimate does not match the new entry. (Estimate(_), _) => false, - (cur, new) => { - return Err(code_invariant_error(format!( - "Replaced entry must be an Estimate, {:?} to {:?}", - cur, new, - ))) + (_cur, _new) => { + // TODO(BlockSTMv2): V2 currently does not mark estimate. + // For V1, used to return Err(code_invariant_error(format!( + // "Replaced entry must be an Estimate, {:?} to {:?}", + // cur, new, + //))) + true }, } { // TODO[agg_v2](optimize): See if we want to invalidate, when we change read_estimate_deltas @@ -506,11 +522,22 @@ impl VersionedDelayedFields { .mark_estimate(txn_idx); } - pub fn remove(&self, id: &K, txn_idx: TxnIndex) { + pub fn remove( + &self, + id: &K, + txn_idx: TxnIndex, + is_blockstm_v2: bool, + ) -> Result<(), PanicError> { self.values .get_mut(id) - .expect("VersionedValue for an (resolved) ID must already exist") - .remove(txn_idx); + .ok_or_else(|| { + code_invariant_error(format!( + "VersionedValue for an (resolved) ID {:?} must already exist", + id + )) + })? + .remove(txn_idx, is_blockstm_v2); + Ok(()) } /// Moves the commit index, and computes exact values for delayed fields having @@ -518,7 +545,11 @@ impl VersionedDelayedFields { /// before given idx are in Value state. /// /// Must be called for each transaction index, in order. - pub fn try_commit(&self, idx_to_commit: TxnIndex, ids: Vec) -> Result<(), CommitError> { + pub fn try_commit( + &self, + idx_to_commit: TxnIndex, + ids_iter: impl Iterator, + ) -> Result<(), CommitError> { // we may not need to return values here, we can just read them. use DelayedApplyEntry::*; @@ -532,7 +563,7 @@ impl VersionedDelayedFields { let mut todo_deltas = Vec::new(); let mut todo_derived = Vec::new(); - for id in ids { + for id in ids_iter { let mut versioned_value = self .values .get_mut(&id) @@ -646,8 +677,6 @@ impl VersionedDelayedFields { versioned_value.insert_final_value(idx_to_commit, new_entry); } - // Should be guaranteed, as this is the only function modifying the idx, - // and value is checked at the start. // Need to assert, because if not matching we are in an inconsistent state. assert_eq!( idx_to_commit, @@ -927,26 +956,6 @@ mod test { v.mark_estimate(5); } - #[should_panic] - #[test] - fn mark_estimate_wrong_entry() { - let mut v = VersionedValue::new(None); - v.insert_speculative_value(3, aggregator_entry(VALUE_AGGREGATOR).unwrap()) - .unwrap(); - v.mark_estimate(3); - - // Marking an Estimate (first we confirm) as estimate is not allowed. - assert_matches!( - v.versioned_map - .get(&3) - .expect("Expecting an Estimate entry") - .as_ref() - .deref(), - VersionEntry::Estimate(EstimatedEntry::NoBypass) - ); - v.mark_estimate(3); - } - #[should_panic] // Inserting estimates isn't allowed, must use mark_estimate. #[test] @@ -1167,7 +1176,7 @@ mod test { if let Some(entry) = aggregator_entry(type_index) { v.insert_speculative_value(10, entry).unwrap(); } - v.remove(10); + v.remove(10, false); } #[test] @@ -1176,26 +1185,10 @@ mod test { v.insert_speculative_value(3, aggregator_entry(VALUE_AGGREGATOR).unwrap()) .unwrap(); v.mark_estimate(3); - v.remove(3); + v.remove(3, false); assert!(!v.read_estimate_deltas); } - #[should_panic] - #[test_case(APPLY_AGGREGATOR)] - #[test_case(APPLY_SNAPSHOT)] - #[test_case(APPLY_DERIVED)] - fn insert_twice_no_value(type_index: usize) { - let mut v = VersionedValue::new(None); - if let Some(entry) = aggregator_entry(type_index) { - v.insert_speculative_value(10, entry).unwrap(); - } - // Should fail because inserting can only overwrite an Estimate entry or - // be inserting a Value when the transaction commits. - if let Some(entry) = aggregator_entry(type_index) { - v.insert_speculative_value(10, entry).unwrap(); - } - } - #[should_panic] #[test_case(APPLY_AGGREGATOR)] #[test_case(APPLY_SNAPSHOT)] diff --git a/aptos-move/mvhashmap/src/versioned_group_data.rs b/aptos-move/mvhashmap/src/versioned_group_data.rs index 70352fc8fdc..c1814ce1f35 100644 --- a/aptos-move/mvhashmap/src/versioned_group_data.rs +++ b/aptos-move/mvhashmap/src/versioned_group_data.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + registered_dependencies::{take_dependencies, RegisteredReadDependencies}, types::{ Incarnation, MVDataError, MVDataOutput, MVGroupError, ShiftedTxnIndex, TxnIndex, ValueWithLayout, Version, @@ -10,13 +11,16 @@ use crate::{ VersionedData, }; use anyhow::anyhow; +use aptos_aggregator::types::ReadPosition; +use aptos_infallible::Mutex; use aptos_types::{ error::{code_invariant_error, PanicError}, write_set::{TransactionWrite, WriteOpKind}, }; use aptos_vm_types::{resolver::ResourceGroupSize, resource_group_adapter::group_size_as_sum}; -use claims::assert_some; +use claims::{assert_ok, assert_some}; use dashmap::DashMap; +use equivalent::Equivalent; use move_core_types::value::MoveTypeLayout; use serde::Serialize; use std::{ @@ -26,12 +30,38 @@ use std::{ }, fmt::Debug, hash::Hash, - sync::Arc, }; +use triomphe::Arc; +struct SizeAndDependencies { + size: ResourceGroupSize, + dependencies: Mutex, +} + +impl SizeAndDependencies { + fn from_size(size: ResourceGroupSize) -> Self { + Self { + size, + dependencies: Mutex::new(RegisteredReadDependencies::new()), + } + } + + fn from_size_and_dependencies( + size: ResourceGroupSize, + dependencies: BTreeMap, + ) -> Self { + Self { + size, + dependencies: Mutex::new(RegisteredReadDependencies::from_dependencies(dependencies)), + } + } +} + +// TODO(BlockSTMv2): Refactoring of Data and Groups multi-versioned map logic +// so size dependencies can be handled in a unified way. #[derive(Default)] struct VersionedGroupSize { - size_entries: BTreeMap>, + size_entries: BTreeMap>, // Determines whether it is safe for size queries to read the value from an entry marked as // ESTIMATE. The heuristic checks on every write, whether the same size would be returned // after the respective write took effect. Once set, the flag remains set to true. @@ -46,7 +76,7 @@ pub struct VersionedGroupData { // such as get, where only & of the key is needed. values: VersionedData<(K, T), V>, // TODO: Once AggregatorV1 is deprecated (no V: TransactionWrite trait bound), - // switch to VersionedVersionedData. + // switch to VersionedData. // If an entry exists for a group key in Dashmap, the group is considered initialized. group_sizes: DashMap, @@ -62,10 +92,47 @@ pub struct VersionedGroupData { group_tags: DashMap>, } +// This struct allows us to reference a group key and tag without cloning +#[derive(Clone)] +struct GroupKeyRef<'a, K, T> { + group_key: &'a K, + tag: &'a T, +} + +// Implement Equivalent for GroupKeyRef so it can be used to look up (K, T) keys +impl<'a, K, T> Equivalent<(K, T)> for GroupKeyRef<'a, K, T> +where + K: Eq, + T: Eq, +{ + fn equivalent(&self, key: &(K, T)) -> bool { + self.group_key == &key.0 && self.tag == &key.1 + } +} + +// Implement Hash for GroupKeyRef to satisfy dashmap's key requirements +impl<'a, K: Hash, T: Hash> std::hash::Hash for GroupKeyRef<'a, K, T> { + fn hash(&self, state: &mut H) { + // Hash the same way as (K, T) would hash + self.group_key.hash(state); + self.tag.hash(state); + } +} + +// Implement Debug for better error messages +impl<'a, K: Debug, T: Debug> Debug for GroupKeyRef<'a, K, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("GroupKeyRef") + .field("group_key", &self.group_key) + .field("tag", &self.tag) + .finish() + } +} + impl< K: Hash + Clone + Debug + Eq, T: Hash + Clone + Debug + Eq + Serialize, - V: TransactionWrite, + V: TransactionWrite + PartialEq, > VersionedGroupData { pub(crate) fn empty() -> Self { @@ -87,6 +154,7 @@ impl< ) -> anyhow::Result<()> { let mut group_sizes = self.group_sizes.entry(group_key.clone()).or_default(); + // Currently the size & value are written while holding the sizes lock. if let Vacant(entry) = group_sizes.size_entries.entry(ShiftedTxnIndex::zero_idx()) { // Perform group size computation if base not already provided. let group_size = group_size_as_sum::( @@ -102,7 +170,7 @@ impl< ) })?; - entry.insert(SizeEntry::new(group_size)); + entry.insert(SizeEntry::new(SizeAndDependencies::from_size(group_size))); let mut superset_tags = self.group_tags.entry(group_key.clone()).or_default(); for (tag, value) in base_values.into_iter() { @@ -142,68 +210,37 @@ impl< incarnation: Incarnation, values: impl IntoIterator>))>, size: ResourceGroupSize, - mut prev_tags: HashSet, + prev_tags: HashSet, ) -> Result { - let mut ret = false; - let mut tags_to_write = vec![]; - - { - let superset_tags = self.group_tags.get(&group_key).ok_or_else(|| { - // Due to read-before-write. - code_invariant_error("Group (tags) must be initialized to write to") - })?; - - for (tag, (value, layout)) in values.into_iter() { - if !superset_tags.contains(&tag) { - tags_to_write.push(tag.clone()); - } - - ret |= !prev_tags.remove(&tag); - - self.values.write( - (group_key.clone(), tag), - txn_idx, - incarnation, - Arc::new(value), - layout, - ); - } - } - - for prev_tag in prev_tags { - let key = (group_key.clone(), prev_tag); - self.values.remove(&key, txn_idx); - } - - if !tags_to_write.is_empty() { - let mut superset_tags = self - .group_tags - .get_mut(&group_key) - .expect("Group must be initialized"); - superset_tags.extend(tags_to_write); - } - let mut group_sizes = self.group_sizes.get_mut(&group_key).ok_or_else(|| { // Due to read-before-write. code_invariant_error("Group (sizes) must be initialized to write to") })?; + let (mut ret, _) = self.data_write_impl::( + &group_key, + txn_idx, + incarnation, + values, + prev_tags.iter().collect(), + )?; if !(group_sizes.size_has_changed && ret) { - let (size_changed, update_flag) = group_sizes - .size_entries - .range(ShiftedTxnIndex::zero_idx()..ShiftedTxnIndex::new(txn_idx + 1)) - .next_back() - .ok_or_else(|| { - code_invariant_error("Initialized group sizes must contain storage version") - }) - .map(|(idx, prev_size)| { - ( - prev_size.value != size, - // Update the size_has_changed flag if the entry isn't the base value - // (which may be non-existent) or if the incarnation > 0. - *idx != ShiftedTxnIndex::zero_idx() || incarnation > 0, - ) - })?; + let (size_changed, update_flag) = Self::get_latest_entry( + &group_sizes.size_entries, + txn_idx, + ReadPosition::AfterCurrentTxn, + ) + .ok_or_else(|| { + code_invariant_error("Initialized group sizes must contain storage version") + }) + .map(|(idx, prev_size)| { + ( + prev_size.value.size != size, + // Update the size_has_changed flag if the entry isn't the base value + // (which may be non-existent) or if the incarnation > 0. + *idx != ShiftedTxnIndex::zero_idx() || incarnation > 0, + ) + })?; if size_changed { ret = true; @@ -213,19 +250,80 @@ impl< } } - group_sizes - .size_entries - .insert(ShiftedTxnIndex::new(txn_idx), SizeEntry::new(size)); + group_sizes.size_entries.insert( + ShiftedTxnIndex::new(txn_idx), + SizeEntry::new(SizeAndDependencies::from_size(size)), + ); Ok(ret) } + pub fn write_v2( + &self, + group_key: K, + txn_idx: TxnIndex, + incarnation: Incarnation, + values: impl IntoIterator>))>, + size: ResourceGroupSize, + prev_tags: HashSet<&T>, + ) -> Result, PanicError> { + let (_, mut invalidated_dependencies) = + self.data_write_impl::(&group_key, txn_idx, incarnation, values, prev_tags)?; + + // We write data first, without holding the sizes lock, then write size. + // Hence when size is observed, values should already be written. + let mut group_sizes = self.group_sizes.get_mut(&group_key).ok_or_else(|| { + // Currently, we rely on read-before-write to make sure the group would have + // been initialized, which would have created an entry in group_sizes. Group + // being initialized sets up data-structures, such as superset_tags, which + // is used in write_v2, hence the code invariant error. Note that in read API + // (fetch_tagged_data) we return Uninitialized / TagNotFound errors, because + // currently that is a part of expected initialization flow. + // TODO(BlockSTMv2): when we refactor MVHashMap and group initialization logic, + // also revisit and address the read-before-write assumption. + code_invariant_error("Group (sizes) must be initialized to write to") + })?; + + // In store deps, we compute any read dependencies of txns that, based on the + // index, would now read the same size but from the new entry created at txn_idx. + // In other words, reads that can be kept valid, even though they were previously + // reading an entry by a lower txn index. However, if the size has changed, then + // those read dependencies will be added to invalidated_dependencies, and the + // store_deps variable will be empty. + let store_deps: BTreeMap = Self::get_latest_entry( + &group_sizes.size_entries, + txn_idx, + ReadPosition::AfterCurrentTxn, + ) + .map_or_else(BTreeMap::new, |(_, size_entry)| { + let new_deps = size_entry.value.dependencies.lock().split_off(txn_idx + 1); + + if size_entry.value.size == size { + // Validation passed. + new_deps + } else { + invalidated_dependencies.extend(new_deps); + BTreeMap::new() + } + }); + + group_sizes.size_entries.insert( + ShiftedTxnIndex::new(txn_idx), + SizeEntry::new(SizeAndDependencies::from_size_and_dependencies( + size, store_deps, + )), + ); + + Ok(invalidated_dependencies.take()) + } + /// Mark all entry from transaction 'txn_idx' at access path 'key' as an estimated write /// (for future incarnation). Will panic if the entry is not in the data-structure. - pub fn mark_estimate(&self, group_key: &K, txn_idx: TxnIndex, tags: HashSet) { + pub fn mark_estimate(&self, group_key: &K, txn_idx: TxnIndex, tags: HashSet<&T>) { for tag in tags { - let key = (group_key.clone(), tag); - self.values.mark_estimate(&key, txn_idx); + // Use GroupKeyRef to avoid cloning the group_key + let key_ref = GroupKeyRef { group_key, tag }; + self.values.mark_estimate(&key_ref, txn_idx); } self.group_sizes @@ -239,10 +337,13 @@ impl< /// Remove all entries from transaction 'txn_idx' at access path 'key'. pub fn remove(&self, group_key: &K, txn_idx: TxnIndex, tags: HashSet) { - for tag in tags { - let key = (group_key.clone(), tag); - self.values.remove(&key, txn_idx); - } + self.remove_impl::( + group_key, + txn_idx, + tags.iter().collect(), + &mut RegisteredReadDependencies::new(), + ) + .expect("remove_impl with V1 never fails"); // TODO: consider setting size_has_changed flag if e.g. the size observed // after remove is different. @@ -256,56 +357,146 @@ impl< ); } + pub fn remove_v2( + &self, + group_key: &K, + txn_idx: TxnIndex, + tags: HashSet<&T>, + ) -> Result, PanicError> { + let mut invalidated_dependencies = RegisteredReadDependencies::new(); + self.remove_impl::(group_key, txn_idx, tags, &mut invalidated_dependencies)?; + + let mut group_sizes = self.group_sizes.get_mut(group_key).ok_or_else(|| { + code_invariant_error(format!( + "Group sizes at key {:?} must exist for remove_v2", + group_key + )) + })?; + let removed_size_entry = group_sizes + .size_entries + .remove(&ShiftedTxnIndex::new(txn_idx)) + .ok_or_else(|| { + code_invariant_error(format!( + "Group size entry at key {:?} for the txn {} must exist for remove_v2", + group_key, txn_idx + )) + })?; + + // Handle dependencies for the removed size entry. + let mut removed_size_deps = take_dependencies(&removed_size_entry.value.dependencies); + if let Some((_, next_lower_entry)) = Self::get_latest_entry( + &group_sizes.size_entries, + txn_idx, + ReadPosition::BeforeCurrentTxn, + ) { + // If the entry that will be read after removal contains the same size, + // then the dependencies on size can be registered there and not invalidated. + // In this case, removed_size_deps gets drained. + if next_lower_entry.value.size == removed_size_entry.value.size { + next_lower_entry + .value + .dependencies + .lock() + .extend_with_higher_dependencies(std::mem::take(&mut removed_size_deps))?; + } + } + + // If removed_size_deps was not drained (into the preceding entry's dependencies), + // then those dependencies also need to be invalidated. + invalidated_dependencies.extend(removed_size_deps); + Ok(invalidated_dependencies.take()) + } + /// Read the latest value corresponding to a tag at a given group (identified by key). /// Return the size of the group (if requested), as defined above, alongside the version /// information (None if storage/pre-block version). /// If the layout of the resource is current UnSet, this function sets the layout of the /// group to the provided layout. - pub fn fetch_tagged_data( + pub fn fetch_tagged_data_no_record( &self, group_key: &K, tag: &T, txn_idx: TxnIndex, ) -> Result<(Version, ValueWithLayout), MVGroupError> { - let key = (group_key.clone(), tag.clone()); + let key_ref = GroupKeyRef { group_key, tag }; + + // We are accessing group_sizes and values non-atomically, hence the order matters. + // It is important that initialization check happens before fetch data below. O.w. + // we could incorrectly get a TagNotFound error (do not find data, but then find + // size initialized in between the calls). In fact, we always write size after data, + // and sometimes (e.g. during initialization) even hold the sizes lock during writes. + // It is fine to observe initialized = false, but find data, in convert_tagged_data. let initialized = self.group_sizes.contains_key(group_key); - match self.values.fetch_data(&key, txn_idx) { - Ok(MVDataOutput::Versioned(version, value)) => Ok((version, value)), - Err(MVDataError::Uninitialized) => Err(if initialized { - MVGroupError::TagNotFound - } else { - MVGroupError::Uninitialized - }), - Err(MVDataError::Dependency(dep_idx)) => Err(MVGroupError::Dependency(dep_idx)), - Ok(MVDataOutput::Resolved(_)) - | Err(MVDataError::Unresolved(_)) - | Err(MVDataError::DeltaApplicationFailure) => { - unreachable!("Not using aggregatorV1") + let data_value = self.values.fetch_data_no_record(&key_ref, txn_idx); + self.convert_tagged_data(data_value, initialized) + } + + // Used in BlockSTMv2, registers the read dependency on returned data. + pub fn fetch_tagged_data_and_record_dependency( + &self, + group_key: &K, + tag: &T, + txn_idx: TxnIndex, + incarnation: Incarnation, + ) -> Result<(Version, ValueWithLayout), MVGroupError> { + let key_ref = GroupKeyRef { group_key, tag }; + + // We are accessing group_sizes and values non-atomically, hence the order matters. + // It is important that initialization check happens before fetch data below. O.w. + // we could incorrectly get a TagNotFound error (do not find data, but then find + // size initialized in between the calls). In fact, we always write size after data, + // and sometimes (e.g. during initialization) even hold the sizes lock during writes. + // It is fine to observe initialized = false, but find data, in convert_tagged_data. + // TODO(BlockSTMv2): complete overhaul of initialization logic. + let initialized = self.group_sizes.contains_key(group_key); + + let data_value = + self.values + .fetch_data_and_record_dependency(&key_ref, txn_idx, incarnation); + self.convert_tagged_data(data_value, initialized) + } + + // Used in BlockSTMv1 w. certain heuristics for dealing with estimate flag, + // and does not register the read dependency. + pub fn get_group_size_no_record( + &self, + group_key: &K, + txn_idx: TxnIndex, + ) -> Result { + match self.group_sizes.get(group_key) { + Some(g) => { + Self::get_latest_entry(&g.size_entries, txn_idx, ReadPosition::BeforeCurrentTxn) + .map_or(Err(MVGroupError::Uninitialized), |(idx, size)| { + if size.is_estimate() && g.size_has_changed { + Err(MVGroupError::Dependency( + idx.idx().expect("May not depend on storage version"), + )) + } else { + Ok(size.value.size) + } + }) }, + None => Err(MVGroupError::Uninitialized), } } - pub fn get_group_size( + // Used in BlockSTMv2, registers the read dependency on returned size. + pub fn get_group_size_and_record_dependency( &self, group_key: &K, txn_idx: TxnIndex, + incarnation: Incarnation, ) -> Result { match self.group_sizes.get(group_key) { - Some(g) => g - .size_entries - .range(ShiftedTxnIndex::zero_idx()..ShiftedTxnIndex::new(txn_idx)) - .next_back() - .map(|(idx, size)| { - if size.is_estimate() && g.size_has_changed { - Err(MVGroupError::Dependency( - idx.idx().expect("May not depend on storage version"), - )) - } else { - Ok(size.value) - } - }) - .unwrap_or(Err(MVGroupError::Uninitialized)), + Some(g) => { + Self::get_latest_entry(&g.size_entries, txn_idx, ReadPosition::BeforeCurrentTxn) + .map_or(Err(MVGroupError::Uninitialized), |(_, size)| { + // TODO(BlockSTMv2): convert to PanicErrors after MVHashMap refactoring. + assert_ok!(size.value.dependencies.lock().insert(txn_idx, incarnation)); + Ok(size.value.size) + }) + }, None => Err(MVGroupError::Uninitialized), } } @@ -316,7 +507,7 @@ impl< txn_idx: TxnIndex, group_size_to_validate: ResourceGroupSize, ) -> bool { - self.get_group_size(group_key, txn_idx) == Ok(group_size_to_validate) + self.get_group_size_no_record(group_key, txn_idx) == Ok(group_size_to_validate) } /// For a given key that corresponds to a group, and an index of a transaction the last @@ -346,7 +537,7 @@ impl< let committed_group = superset_tags .into_iter() .map( - |tag| match self.fetch_tagged_data(group_key, &tag, txn_idx + 1) { + |tag| match self.fetch_tagged_data_no_record(group_key, &tag, txn_idx + 1) { Ok((_, value)) => Ok((value.write_op_kind() != WriteOpKind::Deletion) .then(|| (tag, value.clone()))), Err(MVGroupError::TagNotFound) => Ok(None), @@ -362,16 +553,148 @@ impl< .collect(); Ok(( committed_group, - self.get_group_size(group_key, txn_idx + 1).map_err(|e| { - code_invariant_error(format!( - "Unexpected error in finalize group get size {:?}", - e - )) - })?, + self.get_group_size_no_record(group_key, txn_idx + 1) + .map_err(|e| { + code_invariant_error(format!( + "Unexpected error in finalize group get size {:?}", + e + )) + })?, )) } } +// Private methods. +impl< + K: Hash + Clone + Debug + Eq, + T: Hash + Clone + Debug + Eq + Serialize, + V: TransactionWrite + PartialEq, + > VersionedGroupData +{ + /// Private utility method to find the latest entry before a given transaction index, + /// inclusive or exclusive depending on the read position. Encapsulates the common + /// pattern of range(..ShiftedTxnIndex::new(some index)).next_back() + fn get_latest_entry( + entries: &BTreeMap, + txn_idx: TxnIndex, + read_position: ReadPosition, + ) -> Option<(&ShiftedTxnIndex, &Entry)> { + let before_idx = match read_position { + ReadPosition::BeforeCurrentTxn => txn_idx, + ReadPosition::AfterCurrentTxn => txn_idx + 1, + }; + entries + .range(..ShiftedTxnIndex::new(before_idx)) + .next_back() + } + + // Modifies invalidated dependencies in place via interior mutability. + fn remove_impl( + &self, + group_key: &K, + txn_idx: TxnIndex, + tags: HashSet<&T>, + invalidated_deps: &mut RegisteredReadDependencies, + ) -> Result<(), PanicError> { + for tag in tags { + let key_ref = GroupKeyRef { group_key, tag }; + if V2 { + invalidated_deps.extend(self.values.remove_v2::<_, false>(&key_ref, txn_idx)?); + } else { + self.values.remove(&key_ref, txn_idx); + } + } + Ok(()) + } + + // Unified inner implementation interface for BlockSTMv1 and V2. A pair is returned, + // where only the first element matters for V1, and the second element for V2. + // For V1, the bool indicates whether a new tag was written as opposed to previous + // incarnation (which necessitates certain validations). + // For V2, the BTreeSet contains read dependencies (version of the txn that performed + // the read) invalidated by writing the values. + fn data_write_impl( + &self, + group_key: &K, + txn_idx: TxnIndex, + incarnation: Incarnation, + values: impl IntoIterator>))>, + mut prev_tags: HashSet<&T>, + ) -> Result<(bool, RegisteredReadDependencies), PanicError> { + let mut ret_v1 = false; + // Creating a RegisteredReadDependencies wrapper in order to do proper extending. + let mut ret_v2 = RegisteredReadDependencies::new(); + let mut tags_to_write = vec![]; + + { + let superset_tags = self.group_tags.get(group_key).ok_or_else(|| { + // Due to read-before-write. + code_invariant_error("Group (tags) must be initialized to write to") + })?; + + for (tag, (value, layout)) in values.into_iter() { + if !superset_tags.contains(&tag) { + tags_to_write.push(tag.clone()); + } + + ret_v1 |= !prev_tags.remove(&tag); + + if V2 { + ret_v2.extend(self.values.write_v2::( + (group_key.clone(), tag), + txn_idx, + incarnation, + Arc::new(value), + layout, + )?); + } else { + self.values.write( + (group_key.clone(), tag), + txn_idx, + incarnation, + Arc::new(value), + layout, + ); + } + } + } + + if !tags_to_write.is_empty() { + // We extend here while acquiring a write access (implicit lock), while the + // processing above only requires a read access. + self.group_tags + .get_mut(group_key) + .expect("Group must be initialized") + .extend(tags_to_write); + } + + self.remove_impl::(group_key, txn_idx, prev_tags, &mut ret_v2)?; + + Ok((ret_v1, ret_v2)) + } + + fn convert_tagged_data( + &self, + data_value: anyhow::Result, MVDataError>, + initialized: bool, + ) -> Result<(Version, ValueWithLayout), MVGroupError> { + match data_value { + Ok(MVDataOutput::Versioned(version, value)) => Ok((version, value)), + Err(MVDataError::Uninitialized) => Err(if initialized { + MVGroupError::TagNotFound + } else { + MVGroupError::Uninitialized + }), + Err(MVDataError::Dependency(dep_idx)) => Err(MVGroupError::Dependency(dep_idx)), + Ok(MVDataOutput::Resolved(_)) + | Err(MVDataError::Unresolved(_)) + | Err(MVDataError::DeltaApplicationFailure) => { + unreachable!("Not using aggregatorV1") + }, + } + } +} + #[cfg(test)] mod test { use super::*; @@ -385,6 +708,437 @@ mod test { use std::collections::HashMap; use test_case::test_case; + // Test for dependency tracking in V2 interfaces. Notice that due to the implementation, + // while the size of the base entry is computed at the time of the write, we can determine + // the recorded sizes for other entries - which allows flexibility in test cases. We test + // values and sizes separately (and keep the other from invalidating the same dependencies). + #[test_case(true, true, false; "value test: mid value high, mid size low")] + #[test_case(true, false, false; "value test: mid value low, mid size low")] + #[test_case(false, false, true; "size test: mid size high, mid value low")] + #[test_case(false, false, false; "size test: mid size low, mid value low")] + fn test_dependency_tracking( + test_value_or_size: bool, + mid_value_matches_low: bool, + mid_size_matches_low: bool, + ) { + // Initialize test data + let group_key = KeyType(b"/group/test".to_vec()); + let tag: usize = 1; + + // Create values and determine which one to use for mid_value + let base_value = TestValue::creation_with_len(1); + let high_value = TestValue::creation_with_len(2); + let mid_value = if mid_value_matches_low { + base_value.clone() + } else { + high_value.clone() + }; + + // Calculate base_size based on the actual values (as it will be computed by set_raw_base_values). + // Set high size arbitrary and determine mid_size. + let one_entry_len = base_value.bytes().unwrap().len(); + let base_size = group_size_as_sum(vec![(&tag, one_entry_len)].into_iter()).unwrap(); + let high_size = ResourceGroupSize::Combined { + num_tagged_resources: 3, + all_tagged_resources_size: 20, + }; + let mid_size = if mid_size_matches_low { + base_size + } else { + high_size + }; + + // Fixed indices for our test + let mid_idx: TxnIndex = 5; // Middle index for the write that may invalidate + let high_idx: TxnIndex = 10; // High index for the first write + let inc_1: Incarnation = 1; // Fixed incarnation for simplicity + + // Create a new VersionedGroupData instance and initialize it with base & high values. + let group_data = VersionedGroupData::>, usize, TestValue>::empty(); + assert_ok!( + group_data.set_raw_base_values(group_key.clone(), vec![(tag, base_value.clone())],) + ); + assert_ok!(group_data.write_v2( + group_key.clone(), + high_idx, + inc_1, + vec![(tag, (high_value.clone(), None))], + high_size, + HashSet::new(), + )); + + // Define indices for dependencies + let dependency_indices = [ + 15, 20, // > high_idx + 6, 10, // (mid_idx, high_idx] + 2, 5, // ..=mid_idx + ]; + + let mut all_value_deps = BTreeMap::new(); + let mut all_size_deps = BTreeMap::new(); + for idx in dependency_indices { + if test_value_or_size { + // Create value dependency + let res = group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag, idx, inc_1) + .unwrap(); + assert_eq!( + res.0, + if idx > high_idx { + Ok((high_idx, inc_1)) + } else { + Err(StorageVersion) + } + ); + assert_eq!( + res.1, + if idx > high_idx { + ValueWithLayout::Exchanged(Arc::new(high_value.clone()), None) + } else { + ValueWithLayout::RawFromStorage(Arc::new(base_value.clone())) + } + ); + all_value_deps.insert(idx, inc_1); + } else { + // Create size dependency + // Create size dependency + assert_ok!(group_data.get_group_size_and_record_dependency(&group_key, idx, inc_1)); + all_size_deps.insert(idx, inc_1); + } + } + + // Make sure the base value actually matches based on layout / Exchanged. + group_data.update_tagged_base_value_with_layout( + group_key.clone(), + tag, + base_value.clone(), + None, + ); + assert_eq!( + group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag, 2, 1) + .unwrap(), + ( + Err(StorageVersion), + ValueWithLayout::Exchanged(Arc::new(base_value.clone()), None) + ) + ); + + // Write another value at a middle index and check dependency handling. + let write_invalidated_deps = group_data + .write_v2( + group_key.clone(), + mid_idx, + inc_1, + vec![(tag, (mid_value.clone(), None))], + mid_size, + HashSet::new(), + ) + .unwrap(); + let expected_invalidated = all_value_deps + .clone() + .into_iter() + .filter(|&(idx, _)| idx > mid_idx && idx <= high_idx && !mid_value_matches_low) + .chain( + all_size_deps + .clone() + .into_iter() + .filter(|&(idx, _)| idx > mid_idx && idx <= high_idx && !mid_size_matches_low), + ) + .collect::>(); + assert_eq!(write_invalidated_deps, expected_invalidated); + // Remove the high index entry and check dependency handling + let remove_invalidated_deps = group_data + .remove_v2(&group_key, high_idx, HashSet::from([&tag])) + .unwrap(); + let expected_invalidated = all_value_deps + .into_iter() + // matching low value means not matching high in the test + .filter(|&(idx, _)| idx > high_idx && mid_value_matches_low) + .chain( + all_size_deps + .clone() + .into_iter() + .filter(|&(idx, _)| idx > high_idx && mid_size_matches_low), + ) + .collect::>(); + assert_eq!(remove_invalidated_deps, expected_invalidated); + + // Verify stored size dependencies in the data structure + let group_sizes = group_data.group_sizes.get(&group_key).unwrap(); + { + let mid_deps = &group_sizes + .size_entries + .get(&ShiftedTxnIndex::new(mid_idx)) + .unwrap() + .value + .dependencies; + assert_eq!( + take_dependencies(mid_deps), + all_size_deps + .clone() + .into_iter() + .filter( + |&(idx, _)| (idx > mid_idx && idx <= high_idx && mid_size_matches_low) + || (idx > high_idx && !mid_size_matches_low) + ) + .collect::>() + ); + } + { + let base_deps = &group_sizes + .size_entries + .get(&ShiftedTxnIndex::zero_idx()) + .unwrap() + .value + .dependencies; + assert_eq!( + take_dependencies(base_deps), + all_size_deps + .into_iter() + .filter(|&(idx, _)| idx <= mid_idx) + .collect::>() + ); + } + + // Verify we can access the value and size from mid write + let (_, value) = group_data + .fetch_tagged_data_and_record_dependency( + &group_key, &tag, 21, inc_1, // higher than any idx. + ) + .unwrap(); + assert_eq!(value, ValueWithLayout::Exchanged(Arc::new(mid_value), None)); + let size = group_data + .get_group_size_and_record_dependency(&group_key, 21, inc_1) + .unwrap(); + assert_eq!(size, mid_size); + } + + // Entries from storage may contain a special layout, which has not been processed yet. + // It has to be validated (and fail) against a processed (Exchanged) layout (e.g. with + // IDs for delayed fields contained within). The other case checks that if the correct + // layout was provided and set (for transaction 0, the previous test instead provides + // layout for storage version), then it passes validation. + #[test_case(true; "raw storage layout fails validation")] + #[test_case(false; "exchanged layout passes validation")] + fn test_raw_storage_layout_validation(raw_storage_layout: bool) { + let group_key = KeyType(b"/group/test".to_vec()); + let tag: usize = 1; + + let group_data = VersionedGroupData::>, usize, TestValue>::empty(); + let base_value = TestValue::creation_with_len(1); + let one_entry_len = base_value.bytes().unwrap().len(); + let base_size = group_size_as_sum(vec![(&tag, one_entry_len)].into_iter()).unwrap(); + + assert_ok!( + group_data.set_raw_base_values(group_key.clone(), vec![(tag, base_value.clone())]) + ); + if !raw_storage_layout { + assert_ok!(group_data.write_v2( + group_key.clone(), + 0, + 1, + vec![(tag, (base_value.clone(), None))], + base_size, + HashSet::new(), + )); + } + + let (version, value) = group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag, 5, 2) + .unwrap(); + assert_eq!( + version, + if raw_storage_layout { + Err(StorageVersion) + } else { + Ok((0, 1)) + } + ); + assert_eq!( + value, + if raw_storage_layout { + ValueWithLayout::RawFromStorage(Arc::new(base_value.clone())) + } else { + ValueWithLayout::Exchanged(Arc::new(base_value.clone()), None) + } + ); + + let invalidated_deps = group_data + .write_v2( + group_key.clone(), + 2, + 1, + vec![(tag, (base_value.clone(), None))], + base_size, + HashSet::new(), + ) + .unwrap(); + assert_eq!( + invalidated_deps, + if raw_storage_layout { + BTreeMap::from([(5, 2)]) + } else { + BTreeMap::new() + } + ); + } + + // This tests the case when after a write and remove, some entries in the group may pass + // validation while others fail. The test ensures the proper dependencies are invalidated + // and returned. The test setup looks as follows: + // + // Group Contents: + // TAG 0 TAG 1 + // + // txn 10 depB0 depB1 + // txn 9 B B + // | | + // txn 8 depA0 depA1 + // txn 7 test writes (A, B) or (B, A) + // | | + // txn 6 A A + // + // We ensure that if (A, B) is written, depA1 is invalidated, and vice versa. Then, a + // similar test considers the removal of txn 9's output. + // + // A != B for validation purposes, but the second parameter determines whether the + // values are different, or whether the layouts are set for both A and B (in which + // case validation fails instead of performing a deep layout comparison). + #[test_case(true, true; "partial: A, B, different values")] + #[test_case(true, false; "partial: A, B, set layouts")] + #[test_case(false, true; "partial: B, A, different values")] + #[test_case(false, false; "partial: B, A, set layouts")] + fn test_partial_invalidation(case_a_b: bool, different_values: bool) { + let group_key = KeyType(b"/group/test".to_vec()); + let tag0: usize = 0; + let tag1: usize = 1; + + let group_data = VersionedGroupData::>, usize, TestValue>::empty(); + + // Create base values A and B + let value_a = TestValue::creation_with_len(1); + let value_b = TestValue::creation_with_len(2); + let invariant_size = ResourceGroupSize::Combined { + num_tagged_resources: 3, + all_tagged_resources_size: 20, + }; + + // Create pairs based on different_values parameter + // When different_values=true: use (value, None) so validation is based on value differences + // When different_values=false: use same value with (value, Some(layout)) so validation fails due to layout comparison being avoided + let pair_a = if different_values { + (value_a.clone(), None) + } else { + (value_a.clone(), Some(Arc::new(MoveTypeLayout::Bool))) + }; + let pair_b = if different_values { + (value_b.clone(), None) + } else { + (value_a.clone(), Some(Arc::new(MoveTypeLayout::Bool))) // Same value as pair_a when different_values=false + }; + + // Need to initialize the group - detected by missing size entry. + assert_ok!(group_data.set_raw_base_values(group_key.clone(), vec![])); + + // Initial setup: Write A at txn 6. Register dependencies for both tags at txn 8. + assert_ok!(group_data.write_v2( + group_key.clone(), + 6, + 1, + vec![(tag0, pair_a.clone()), (tag1, pair_a.clone())], + invariant_size, + HashSet::new(), + )); + assert_eq!( + group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag0, 8, 0) + .unwrap() + .0, + Ok((6, 1)) + ); + assert_eq!( + group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag1, 8, 1) + .unwrap() + .0, + Ok((6, 1)) + ); + + // Write B at txn 9 & register dependencies at txn 10. Encode tag in incarnation. + assert_ok!(group_data.write_v2( + group_key.clone(), + 9, + 1, + vec![(tag0, pair_b.clone()), (tag1, pair_b.clone())], + invariant_size, + HashSet::new(), + )); + assert_eq!( + group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag0, 10, 0) + .unwrap() + .0, + Ok((9, 1)) + ); + assert_eq!( + group_data + .fetch_tagged_data_and_record_dependency(&group_key, &tag1, 10, 1) + .unwrap() + .0, + Ok((9, 1)) + ); + + // Test write at txn 7 based on case_a_b + let write_value = if case_a_b { + vec![(tag0, pair_a.clone()), (tag1, pair_b.clone())] + } else { + vec![(tag0, pair_b.clone()), (tag1, pair_a.clone())] + }; + + let write_invalidated = group_data + .write_v2( + group_key.clone(), + 7, + 1, + write_value, + invariant_size, + HashSet::new(), + ) + .unwrap(); + let expected_invalidated = if different_values { + if case_a_b { + // If writing (A, B), depA1 should be invalidated (incarnation = tag) + BTreeMap::from([(8, 1)]) + } else { + // If writing (B, A), depA0 should be invalidated + BTreeMap::from([(8, 0)]) + } + } else { + // When different_values=false, both A and B are the same value with layouts set, + // so validation fails for both and both dependencies should be invalidated + BTreeMap::from([(8, 0), (8, 1)]) + }; + assert_eq!(write_invalidated, expected_invalidated); + + // Remove txn 9's output + let remove_invalidated = group_data + .remove_v2(&group_key, 9, HashSet::from([&tag0, &tag1])) + .unwrap(); + let expected_invalidated = if different_values { + if case_a_b { + BTreeMap::from([(10, 0)]) + } else { + BTreeMap::from([(10, 1)]) + } + } else { + // When different_values=false, both A and B are the same value with layouts set, + // so validation fails for both and both dependencies should be invalidated + BTreeMap::from([(10, 0), (10, 1)]) + }; + assert_eq!(remove_invalidated, expected_invalidated); + } + #[should_panic] #[test_case(0)] #[test_case(1)] @@ -461,7 +1215,8 @@ mod test { .size_entries .get(&ShiftedTxnIndex::new(idx)) .unwrap() - .value, + .value + .size, size ); }; @@ -506,9 +1261,12 @@ mod test { let ap_empty = KeyType(b"/foo/b".to_vec()); let map = VersionedGroupData::>, usize, TestValue>::empty(); - assert_matches!(map.get_group_size(&ap, 3), Err(MVGroupError::Uninitialized)); assert_matches!( - map.fetch_tagged_data(&ap, &1, 3), + map.get_group_size_no_record(&ap, 3), + Err(MVGroupError::Uninitialized) + ); + assert_matches!( + map.fetch_tagged_data_no_record(&ap, &1, 3), Err(MVGroupError::Uninitialized) ); @@ -540,24 +1298,24 @@ mod test { )); // Check sizes. - assert_ok_eq!(map.get_group_size(&ap, 4), idx_3_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 4), idx_3_size); assert_ok_eq!( - map.get_group_size(&ap, 3), + map.get_group_size_no_record(&ap, 3), ResourceGroupSize::zero_combined() ); // Check values. assert_matches!( - map.fetch_tagged_data(&ap, &1, 3), + map.fetch_tagged_data_no_record(&ap, &1, 3), Err(MVGroupError::TagNotFound) ); assert_matches!( - map.fetch_tagged_data(&ap, &3, 4), + map.fetch_tagged_data_no_record(&ap, &3, 4), Err(MVGroupError::TagNotFound) ); // ... but idx = 4 should find the previously stored value. assert_eq!( - map.fetch_tagged_data(&ap, &1, 4).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 4).unwrap(), ( Ok((3, 1)), ValueWithLayout::Exchanged(Arc::new(TestValue::creation_with_len(1)), None) @@ -566,11 +1324,11 @@ mod test { // ap_empty should still be uninitialized. assert_matches!( - map.fetch_tagged_data(&ap_empty, &1, 3), + map.fetch_tagged_data_no_record(&ap_empty, &1, 3), Err(MVGroupError::Uninitialized) ); assert_matches!( - map.get_group_size(&ap_empty, 3), + map.get_group_size_no_record(&ap_empty, 3), Err(MVGroupError::Uninitialized) ); } @@ -598,29 +1356,29 @@ mod test { )); assert_matches!( - map.fetch_tagged_data(&ap, &2, 4), + map.fetch_tagged_data_no_record(&ap, &2, 4), Err(MVGroupError::TagNotFound) ); assert_matches!( - map.fetch_tagged_data(&ap, &3, 5), + map.fetch_tagged_data_no_record(&ap, &3, 5), Err(MVGroupError::TagNotFound) ); assert_eq!( - map.fetch_tagged_data(&ap, &2, 5).unwrap(), + map.fetch_tagged_data_no_record(&ap, &2, 5).unwrap(), ( Ok((4, 0)), ValueWithLayout::Exchanged(Arc::new(TestValue::creation_with_len(4)), None) ) ); assert_eq!( - map.fetch_tagged_data(&ap, &1, 4).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 4).unwrap(), ( Err(StorageVersion), ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(2))) ) ); assert_eq!( - map.fetch_tagged_data(&ap, &0, 6).unwrap(), + map.fetch_tagged_data_no_record(&ap, &0, 6).unwrap(), ( Err(StorageVersion), ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(1))) @@ -650,7 +1408,7 @@ mod test { HashSet::new(), )); assert_eq!( - map.fetch_tagged_data(&ap, &1, 12).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 12).unwrap(), ( Ok((5, 3)), ValueWithLayout::Exchanged(Arc::new(TestValue::new(vec![5, 3])), None) @@ -666,36 +1424,46 @@ mod test { HashSet::new(), )); assert_eq!( - map.fetch_tagged_data(&ap, &1, 12).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 12).unwrap(), ( Ok((10, 1)), ValueWithLayout::Exchanged(Arc::new(TestValue::new(vec![10, 1])), None) ) ); - map.mark_estimate(&ap, 10, (1..3).collect()); - assert_matches!(map.fetch_tagged_data(&ap, &1, 12), Err(Dependency(10))); - assert_matches!(map.fetch_tagged_data(&ap, &2, 12), Err(Dependency(10))); - assert_matches!(map.fetch_tagged_data(&ap, &3, 12), Err(TagNotFound)); + let tags_012: Vec = (1..3).collect(); + map.mark_estimate(&ap, 10, tags_012.iter().collect()); + assert_matches!( + map.fetch_tagged_data_no_record(&ap, &1, 12), + Err(Dependency(10)) + ); + assert_matches!( + map.fetch_tagged_data_no_record(&ap, &2, 12), + Err(Dependency(10)) + ); + assert_matches!( + map.fetch_tagged_data_no_record(&ap, &3, 12), + Err(TagNotFound) + ); assert_eq!( - map.fetch_tagged_data(&ap, &0, 12).unwrap(), + map.fetch_tagged_data_no_record(&ap, &0, 12).unwrap(), ( Ok((5, 3)), ValueWithLayout::Exchanged(Arc::new(TestValue::new(vec![5, 3])), None) ) ); - assert_matches!(map.get_group_size(&ap, 12), Err(Dependency(10))); + assert_matches!(map.get_group_size_no_record(&ap, 12), Err(Dependency(10))); map.remove(&ap, 10, (1..3).collect()); assert_eq!( - map.fetch_tagged_data(&ap, &0, 12).unwrap(), + map.fetch_tagged_data_no_record(&ap, &0, 12).unwrap(), ( Ok((5, 3)), ValueWithLayout::Exchanged(Arc::new(TestValue::new(vec![5, 3])), None) ) ); assert_eq!( - map.fetch_tagged_data(&ap, &1, 12).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 12).unwrap(), ( Ok((5, 3)), ValueWithLayout::Exchanged(Arc::new(TestValue::new(vec![5, 3])), None) @@ -703,7 +1471,7 @@ mod test { ); // Size should also be removed at 10. - assert_ok_eq!(map.get_group_size(&ap, 12), idx_5_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 12), idx_5_size); } #[test] @@ -746,14 +1514,15 @@ mod test { // Incarnation 0 and base values should not affect size_changed flag. assert!(!map.group_sizes.get(&ap).unwrap().size_has_changed); - assert_ok_eq!(map.get_group_size(&ap, 5), base_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 5), base_size); assert!(map.validate_group_size(&ap, 4, base_size)); assert!(!map.validate_group_size(&ap, 5, idx_5_size)); - assert_ok_eq!(map.get_group_size(&ap, 6), idx_5_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 6), idx_5_size); // Despite estimates, should still return size. - map.mark_estimate(&ap, 5, (0..2).collect()); - assert_ok_eq!(map.get_group_size(&ap, 12), idx_5_size); + let tags_01: Vec = (0..2).collect(); + map.mark_estimate(&ap, 5, tags_01.iter().collect()); + assert_ok_eq!(map.get_group_size_no_record(&ap, 12), idx_5_size); assert!(map.validate_group_size(&ap, 12, idx_5_size)); assert!(!map.validate_group_size(&ap, 12, ResourceGroupSize::zero_combined())); @@ -770,15 +1539,15 @@ mod test { true ); assert!(!map.group_sizes.get(&ap).unwrap().size_has_changed); - map.mark_estimate(&ap, 5, (0..2).collect()); - assert_ok_eq!(map.get_group_size(&ap, 12), idx_5_size); + map.mark_estimate(&ap, 5, tags_01.iter().collect()); + assert_ok_eq!(map.get_group_size_no_record(&ap, 12), idx_5_size); assert!(map.validate_group_size(&ap, 12, idx_5_size)); assert!(!map.validate_group_size(&ap, 12, ResourceGroupSize::zero_concrete())); // Remove currently does not affect size_has_changed. map.remove(&ap, 5, (0..3).collect()); assert!(!map.group_sizes.get(&ap).unwrap().size_has_changed); - assert_ok_eq!(map.get_group_size(&ap, 4), base_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 4), base_size); assert!(map.validate_group_size(&ap, 6, base_size)); assert_ok!(map.write( @@ -791,14 +1560,15 @@ mod test { )); // Size has changed between speculative writes. assert!(map.group_sizes.get(&ap).unwrap().size_has_changed); - assert_ok_eq!(map.get_group_size(&ap, 10), idx_5_size_with_ones); + assert_ok_eq!(map.get_group_size_no_record(&ap, 10), idx_5_size_with_ones); assert!(map.validate_group_size(&ap, 10, idx_5_size_with_ones)); assert!(!map.validate_group_size(&ap, 10, idx_5_size)); - assert_ok_eq!(map.get_group_size(&ap, 3), base_size); + assert_ok_eq!(map.get_group_size_no_record(&ap, 3), base_size); - map.mark_estimate(&ap, 5, (0..3).collect()); + let tags_012: Vec = (0..3).collect(); + map.mark_estimate(&ap, 5, tags_012.iter().collect()); assert_matches!( - map.get_group_size(&ap, 12), + map.get_group_size_no_record(&ap, 12), Err(MVGroupError::Dependency(5)) ); assert!(!map.validate_group_size(&ap, 12, idx_5_size_with_ones)); @@ -933,7 +1703,7 @@ mod test { // Finalize returns size recorded by txn 3, while get_group_size at txn index // 3 must return the size recorded below it. assert_eq!(size_3, idx_3_size); - assert_ok_eq!(map.get_group_size(&ap, 3), base_size,); + assert_ok_eq!(map.get_group_size_no_record(&ap, 3), base_size,); // The value at tag 1 is from base, while 2 and 3 are from txn 3. // (Arc compares with value equality) @@ -1036,7 +1806,7 @@ mod test { assert_ok!(map.set_raw_base_values(ap.clone(), vec![(1, TestValue::creation_with_len(1))],)); assert_eq!( - map.fetch_tagged_data(&ap, &1, 6).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 6).unwrap(), ( Err(StorageVersion), ValueWithLayout::RawFromStorage(Arc::new(TestValue::creation_with_len(1))) @@ -1050,11 +1820,117 @@ mod test { None, ); assert_eq!( - map.fetch_tagged_data(&ap, &1, 6).unwrap(), + map.fetch_tagged_data_no_record(&ap, &1, 6).unwrap(), ( Err(StorageVersion), ValueWithLayout::Exchanged(Arc::new(TestValue::creation_with_len(1)), None) ) ); } + + #[test] + fn group_key_ref_equivalence_and_hashing() { + use std::hash::{DefaultHasher, Hash, Hasher}; + + let dashmap: DashMap<(u32, u32), String> = DashMap::new(); + + // Test with a range of keys and tags (1..50 x 1..50 = 2500 combinations) + for k in 1u32..50u32 { + for t in 1u32..50u32 { + let tuple_key = (k, t); + let ref_key = GroupKeyRef { + group_key: &k, + tag: &t, + }; + let expected_value = format!("value_{}_{}", k, t); + + // Test 1: Verify that (K, T) and GroupKeyRef hash to the same value + let mut hasher1 = DefaultHasher::new(); + tuple_key.hash(&mut hasher1); + let tuple_hash = hasher1.finish(); + + let mut hasher2 = DefaultHasher::new(); + ref_key.hash(&mut hasher2); + let ref_hash = hasher2.finish(); + + assert_eq!( + tuple_hash, ref_hash, + "Tuple ({}, {}) and GroupKeyRef should hash to the same value", + k, t + ); + + // Test 2: Test equivalence trait directly + assert!( + ref_key.equivalent(&tuple_key), + "GroupKeyRef should be equivalent to corresponding tuple ({}, {})", + k, + t + ); + // Test with different values to ensure non-equivalence + let different_tuple = (k, t + 1000); + assert!( + !ref_key.equivalent(&different_tuple), + "GroupKeyRef should not be equivalent to different tuple ({}, {})", + k, + t + 1000 + ); + + // Test 3: Insert using tuple key + dashmap.insert(tuple_key, expected_value.clone()); + + // Test 4: Access using GroupKeyRef - should find the same entry + let retrieved = dashmap.get(&ref_key); + assert!( + retrieved.is_some(), + "Should be able to access entry ({}, {}) using GroupKeyRef", + k, + t + ); + assert_eq!( + retrieved.unwrap().as_str(), + expected_value, + "Retrieved value should match expected value for ({}, {})", + k, + t + ); + + // Test 5: Remove using GroupKeyRef and verify it's the correct entry + let removed = dashmap.remove(&ref_key); + assert!( + removed.is_some(), + "Should be able to remove entry ({}, {}) using GroupKeyRef", + k, + t + ); + let (removed_key, removed_value) = removed.unwrap(); + assert_eq!( + removed_key, tuple_key, + "Removed key should match original tuple key ({}, {})", + k, t + ); + assert_eq!( + removed_value, expected_value, + "Removed value should match expected value for ({}, {})", + k, t + ); + + // Verify entry is actually removed + assert!( + dashmap.get(&ref_key).is_none(), + "Entry ({}, {}) should be removed and not accessible", + k, + t + ); + assert!( + dashmap.get(&tuple_key).is_none(), + "Entry ({}, {}) should be removed and not accessible via tuple key", + k, + t + ); + } + } + + // Verify all entries are removed + assert_eq!(dashmap.len(), 0, "All entries should be removed"); + } } diff --git a/aptos-move/replay-benchmark/src/commands/benchmark.rs b/aptos-move/replay-benchmark/src/commands/benchmark.rs index a732303512d..4c86a010dcc 100644 --- a/aptos-move/replay-benchmark/src/commands/benchmark.rs +++ b/aptos-move/replay-benchmark/src/commands/benchmark.rs @@ -9,7 +9,9 @@ use crate::{ }; use anyhow::{anyhow, bail}; use aptos_logger::Level; -use aptos_vm_environment::prod_configs::set_paranoid_type_checks; +use aptos_vm_environment::prod_configs::{ + set_async_runtime_checks, set_layout_caches, set_paranoid_type_checks, +}; use clap::Parser; use std::path::PathBuf; use tokio::fs; @@ -69,6 +71,13 @@ pub struct BenchmarkCommand { help = "If false, Move VM runs in paranoid mode, if true, paranoid mode is not used" )] disable_paranoid_mode: bool, + + #[clap( + long, + default_value_t = false, + help = "If true, Move VM runs traces execution, and Block-STM performs checks later" + )] + async_runtime_checks: bool, } impl BenchmarkCommand { @@ -117,7 +126,9 @@ impl BenchmarkCommand { }) .collect::>(); + set_layout_caches(true); set_paranoid_type_checks(!self.disable_paranoid_mode); + set_async_runtime_checks(self.async_runtime_checks); BenchmarkRunner::new( self.concurrency_levels, self.num_repeats, diff --git a/aptos-move/replay-benchmark/src/commands/download.rs b/aptos-move/replay-benchmark/src/commands/download.rs index c86374a7839..4269f88ab56 100644 --- a/aptos-move/replay-benchmark/src/commands/download.rs +++ b/aptos-move/replay-benchmark/src/commands/download.rs @@ -50,7 +50,7 @@ impl DownloadCommand { // Explicitly get transaction corresponding to the end, so we can verify that blocks are // fully selected. let limit = self.end_version - self.begin_version + 1; - let (mut txns, _) = debugger + let (mut txns, _, _) = debugger .get_committed_transactions(self.begin_version, limit) .await?; diff --git a/aptos-move/replay-benchmark/src/diff.rs b/aptos-move/replay-benchmark/src/diff.rs index e4741f83541..d96375a3e70 100644 --- a/aptos-move/replay-benchmark/src/diff.rs +++ b/aptos-move/replay-benchmark/src/diff.rs @@ -2,19 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_types::{ - account_config::CoinStoreResource, + account_config::{ + CoinStoreResource, ConcurrentSupplyResource, FungibleStoreResource, ObjectGroupResource, + }, contract_event::ContractEvent, fee_statement::FeeStatement, state_store::state_key::StateKey, transaction::{ExecutionStatus, TransactionOutput}, - write_set::{WriteOp, WriteSet, TOTAL_SUPPLY_STATE_KEY}, + write_set::{TransactionWrite, WriteOp, WriteSet, TOTAL_SUPPLY_STATE_KEY}, AptosCoinType, }; -use claims::{assert_ok, assert_some}; +use claims::assert_ok; use move_core_types::{ account_address::AccountAddress, language_storage::TypeTag, move_resource::MoveStructType, }; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, str::FromStr}; /// Different parts of [TransactionOutput] that can be different: /// 1. gas used, @@ -79,35 +81,32 @@ impl TransactionDiff { let left = left.as_ref(); let right = right.as_ref(); - if left.is_none() { - let event_name = right.unwrap().type_tag().to_canonical_string(); - println!("{}", "========".yellow()); - println!("{}", format!("event {:?} emitted", event_name).red()); - } else if right.is_none() { - let event_name = left.unwrap().type_tag().to_canonical_string(); - println!("{}", format!("event {:?} emitted", event_name).green()); - println!("{}", "========".yellow()); - } else { - let event_name = left.unwrap().type_tag().to_canonical_string(); - println!( - "{}", - format!( - "event {:?} data: {:?}", - event_name, - left.unwrap().event_data() + match (left, right) { + (None, Some(right)) => { + let event_name = right.type_tag().to_canonical_string(); + println!("{}", "========".yellow()); + println!("{}", format!("event {:?} emitted", event_name).red()); + }, + (Some(left), None) => { + let event_name = left.type_tag().to_canonical_string(); + println!("{}", format!("event {:?} emitted", event_name).green()); + println!("{}", "========".yellow()); + }, + (Some(left), Some(right)) => { + let event_name = left.type_tag().to_canonical_string(); + println!( + "{}", + format!("event {:?} data: {:?}", event_name, left.event_data()) + .green() + ); + println!("{}", "========".yellow()); + println!( + "{}", + format!("event {:?} data: {:?}", event_name, right.event_data()) + .red() ) - .green() - ); - println!("{}", "========".yellow()); - println!( - "{}", - format!( - "event {:?} data: {:?}", - event_name, - right.unwrap().event_data() - ) - .red() - ); + }, + _ => (), } }, Diff::WriteSet { @@ -251,9 +250,43 @@ impl TransactionDiffBuilder { right: WriteSet, fee_payer: Option, ) -> Vec { - let left = left.into_mut().into_inner(); + let mut left = left.into_mut().into_inner(); let mut right = right.into_mut().into_inner(); + let filter_gas_related_ops = |ops: &mut BTreeMap| { + // Skip total coin APT supply comparisons. + ops.remove(&*TOTAL_SUPPLY_STATE_KEY); + + // Total supply for fungible store. Note that this sadly does not work well for + // comparisons between FA and non-FA since we write the full group, so even if supply + // changes are removed, we still fail comparison on the rest of the group members... + patch_object_group(ops, &AccountAddress::from_str("0xa").unwrap(), |group| { + group.group.remove(&ConcurrentSupplyResource::struct_tag()); + }); + + if let Some(fee_payer) = fee_payer { + // Skip changes to fee payer's coin balance. + let coin_resource_key = StateKey::resource( + &fee_payer, + &CoinStoreResource::::struct_tag(), + ) + .unwrap(); + ops.remove(&coin_resource_key); + + // Skip changes to fee payer's FA balance. + patch_object_group(ops, &fee_payer, |group| { + group.group.remove(&FungibleStoreResource::struct_tag()); + }); + } + }; + + // For comparison without gas, we can simply evict all gas-related ops (and inner ops in + // resource groups). + if self.allow_different_gas_usage { + filter_gas_related_ops(&mut left); + filter_gas_related_ops(&mut right); + } + let mut diffs = vec![]; for (state_key, left_write_op) in left { let maybe_right_write_op = right.remove(&state_key); @@ -265,30 +298,6 @@ impl TransactionDiffBuilder { continue; } - if self.allow_different_gas_usage { - // Skip total APT supply comparisons. Those should always be part of the write set. - if state_key == *TOTAL_SUPPLY_STATE_KEY { - assert_some!(maybe_right_write_op); - continue; - } - - // Skip changes to fee payer's balance. - if let Some(fee_payer) = fee_payer { - if state_key - == StateKey::resource( - &fee_payer, - &CoinStoreResource::::struct_tag(), - ) - .unwrap() - { - // Sanity check: other write set should also contain balance changes. - assert_some!(maybe_right_write_op); - - continue; - } - } - } - diffs.push(Diff::WriteSet { state_key, left: Some(left_write_op), @@ -307,6 +316,21 @@ impl TransactionDiffBuilder { } } +fn patch_object_group(ops: &mut BTreeMap, addr: &AccountAddress, action: F) +where + F: FnOnce(&mut ObjectGroupResource), +{ + let object_group_key = StateKey::resource_group(addr, &ObjectGroupResource::struct_tag()); + if let Some(w) = ops.get_mut(&object_group_key) { + if let Some(bytes) = w.bytes().cloned() { + let mut group = bcs::from_bytes::(&bytes).unwrap(); + action(&mut group); + let patched_bytes = bcs::to_bytes(&group).unwrap(); + w.set_bytes(patched_bytes.into()); + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/aptos-move/replay-benchmark/src/execution.rs b/aptos-move/replay-benchmark/src/execution.rs index e078fa43ce2..5748b55c7e6 100644 --- a/aptos-move/replay-benchmark/src/execution.rs +++ b/aptos-move/replay-benchmark/src/execution.rs @@ -22,6 +22,7 @@ pub(crate) fn execute_workload( ) -> Vec { let config = BlockExecutorConfig { local: BlockExecutorLocalConfig { + blockstm_v2: false, concurrency_level, allow_fallback: true, discard_failed_blocks: false, diff --git a/aptos-move/replay-benchmark/src/state_view.rs b/aptos-move/replay-benchmark/src/state_view.rs index 6638b0f1682..8910919b942 100644 --- a/aptos-move/replay-benchmark/src/state_view.rs +++ b/aptos-move/replay-benchmark/src/state_view.rs @@ -1,9 +1,12 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_types::state_store::{ - state_key::StateKey, state_storage_usage::StateStorageUsage, state_value::StateValue, - StateView, StateViewResult, TStateView, +use aptos_types::{ + state_store::{ + state_key::StateKey, state_slot::StateSlot, state_storage_usage::StateStorageUsage, + state_value::StateValue, StateView, StateViewResult, TStateView, + }, + transaction::Version, }; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; @@ -18,8 +21,19 @@ pub(crate) struct ReadSet { impl TStateView for ReadSet { type Key = StateKey; - fn get_state_value(&self, state_key: &Self::Key) -> StateViewResult> { - Ok(self.data.get(state_key).cloned()) + fn next_version(&self) -> Version { + 0 + } + + fn get_state_slot(&self, state_key: &Self::Key) -> StateViewResult { + let slot = match self.data.get(state_key) { + Some(state_value) => StateSlot::ColdOccupied { + value_version: 0, + value: state_value.clone(), + }, + None => StateSlot::ColdVacant, + }; + Ok(slot) } fn get_usage(&self) -> StateViewResult { @@ -75,30 +89,37 @@ impl<'s, S: StateView> ReadSetCapturingStateView<'s, S> { impl TStateView for ReadSetCapturingStateView<'_, S> { type Key = StateKey; - fn get_state_value(&self, state_key: &Self::Key) -> StateViewResult> { + fn get_state_slot(&self, state_key: &Self::Key) -> StateViewResult { // Check the read-set first. if let Some(state_value) = self.captured_reads.lock().get(state_key) { - return Ok(Some(state_value.clone())); + return Ok(StateSlot::ColdOccupied { + value_version: 0, + value: state_value.clone(), + }); } // We do not allow failures because then benchmarking will not be correct (we miss a read). // Plus, these failures should not happen when replaying past transactions. - let maybe_state_value = self + let slot = self .state_view - .get_state_value(state_key) + .get_state_slot(state_key) .unwrap_or_else(|err| { panic!("Failed to fetch state value for {:?}: {:?}", state_key, err) }); // Capture the read on first access. - if let Some(state_value) = &maybe_state_value { + if let Some(state_value) = slot.as_state_value_opt() { let mut captured_reads = self.captured_reads.lock(); if !captured_reads.contains_key(state_key) { captured_reads.insert(state_key.clone(), state_value.clone()); } } - Ok(maybe_state_value) + Ok(slot) + } + + fn next_version(&self) -> Version { + 0 } fn get_usage(&self) -> StateViewResult { diff --git a/aptos-move/replay-benchmark/src/workload.rs b/aptos-move/replay-benchmark/src/workload.rs index f9408945045..fb138f7e386 100644 --- a/aptos-move/replay-benchmark/src/workload.rs +++ b/aptos-move/replay-benchmark/src/workload.rs @@ -8,7 +8,7 @@ use aptos_types::{ signature_verified_transaction::{ into_signature_verified_block, SignatureVerifiedTransaction, }, - Transaction, Version, + AuxiliaryInfo, Transaction, Version, }, }; use serde::{Deserialize, Serialize}; @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; /// start and end versions of these transactions. pub(crate) struct Workload { /// Stores a non-empty block of signature verified transactions ready for execution. - pub(crate) txn_provider: DefaultTxnProvider, + pub(crate) txn_provider: DefaultTxnProvider, /// Stores metadata for the version range of a block, corresponding to [begin, end) versions. /// It is always set to [TransactionSliceMetadata::Chunk]. pub(crate) transaction_slice_metadata: TransactionSliceMetadata, @@ -41,7 +41,7 @@ impl From for Workload { TransactionSliceMetadata::chunk(txn_block.begin_version, end); let signature_verified_txns = into_signature_verified_block(txn_block.transactions); - let txn_provider = DefaultTxnProvider::new(signature_verified_txns); + let txn_provider = DefaultTxnProvider::new_without_info(signature_verified_txns); Self { txn_provider, diff --git a/aptos-move/script-composer/src/builder.rs b/aptos-move/script-composer/src/builder.rs index 25308810333..e1fbb5c1cf8 100644 --- a/aptos-move/script-composer/src/builder.rs +++ b/aptos-move/script-composer/src/builder.rs @@ -114,10 +114,10 @@ impl TransactionComposer { parameters: vec![], locals_availability: vec![], locals_ty: vec![], - parameters_ty: std::iter::repeat(SignatureToken::Reference(Box::new( - SignatureToken::Signer, - ))) - .take(signer_count.into()) + parameters_ty: std::iter::repeat_n( + SignatureToken::Reference(Box::new(SignatureToken::Signer)), + signer_count.into(), + ) .collect(), #[cfg(test)] diff --git a/aptos-move/script-composer/src/decompiler.rs b/aptos-move/script-composer/src/decompiler.rs index 72c38795ff3..8231e7fd667 100644 --- a/aptos-move/script-composer/src/decompiler.rs +++ b/aptos-move/script-composer/src/decompiler.rs @@ -203,6 +203,12 @@ impl LocalState { SignatureToken::U64 => TypeTag::U64, SignatureToken::U128 => TypeTag::U128, SignatureToken::U256 => TypeTag::U256, + SignatureToken::I8 => TypeTag::I8, + SignatureToken::I16 => TypeTag::I16, + SignatureToken::I32 => TypeTag::I32, + SignatureToken::I64 => TypeTag::I64, + SignatureToken::I128 => TypeTag::I128, + SignatureToken::I256 => TypeTag::I256, SignatureToken::Bool => TypeTag::Bool, SignatureToken::Signer => TypeTag::Signer, SignatureToken::Vector(s) => { diff --git a/aptos-move/script-composer/src/helpers.rs b/aptos-move/script-composer/src/helpers.rs index adb27fe8bea..16e155aa795 100644 --- a/aptos-move/script-composer/src/helpers.rs +++ b/aptos-move/script-composer/src/helpers.rs @@ -9,7 +9,7 @@ use move_binary_format::{ }; use move_core_types::{ identifier::IdentStr, - language_storage::{ModuleId, TypeTag}, + language_storage::{FunctionParamOrReturnTag, ModuleId, TypeTag}, transaction_argument::TransactionArgument, vm_status::StatusCode, }; @@ -29,11 +29,6 @@ pub(crate) fn import_type_tag( type_tag: &TypeTag, module_resolver: &BTreeMap, ) -> PartialVMResult { - let to_list = |script_builder: &mut CompiledScriptBuilder, ts: &[TypeTag]| { - ts.iter() - .map(|t| import_type_tag(script_builder, t, module_resolver)) - .collect::>>() - }; Ok(match type_tag { TypeTag::Address => SignatureToken::Address, TypeTag::U8 => SignatureToken::U8, @@ -42,6 +37,12 @@ pub(crate) fn import_type_tag( TypeTag::U64 => SignatureToken::U64, TypeTag::U128 => SignatureToken::U128, TypeTag::U256 => SignatureToken::U256, + TypeTag::I8 => SignatureToken::I8, + TypeTag::I16 => SignatureToken::I16, + TypeTag::I32 => SignatureToken::I32, + TypeTag::I64 => SignatureToken::I64, + TypeTag::I128 => SignatureToken::I128, + TypeTag::I256 => SignatureToken::I256, TypeTag::Bool => SignatureToken::Bool, TypeTag::Signer => SignatureToken::Signer, TypeTag::Vector(t) => SignatureToken::Vector(Box::new(import_type_tag( @@ -56,17 +57,44 @@ pub(crate) fn import_type_tag( if s.type_args.is_empty() { SignatureToken::Struct(struct_idx) } else { - SignatureToken::StructInstantiation( - struct_idx, - to_list(script_builder, &s.type_args)?, - ) + let type_args = s + .type_args + .iter() + .map(|t| import_type_tag(script_builder, t, module_resolver)) + .collect::>>()?; + SignatureToken::StructInstantiation(struct_idx, type_args) } }, - TypeTag::Function(f) => SignatureToken::Function( - to_list(script_builder, &f.args)?, - to_list(script_builder, &f.results)?, - f.abilities, - ), + TypeTag::Function(f) => { + let to_list = |script_builder: &mut CompiledScriptBuilder, + ts: &[FunctionParamOrReturnTag]| { + ts.iter() + .map(|t| { + Ok(match t { + FunctionParamOrReturnTag::Reference(t) => SignatureToken::Reference( + Box::new(import_type_tag(script_builder, t, module_resolver)?), + ), + FunctionParamOrReturnTag::MutableReference(t) => { + SignatureToken::MutableReference(Box::new(import_type_tag( + script_builder, + t, + module_resolver, + )?)) + }, + FunctionParamOrReturnTag::Value(t) => { + import_type_tag(script_builder, t, module_resolver)? + }, + }) + }) + .collect::>>() + }; + + SignatureToken::Function( + to_list(script_builder, &f.args)?, + to_list(script_builder, &f.results)?, + f.abilities, + ) + }, }) } diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index db59a96c5c4..f07c9199963 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -17,7 +17,10 @@ use aptos_gas_schedule::{ AptosGasParameters, InitialGasSchedule, ToOnChainGasSchedule, LATEST_GAS_FEATURE_VERSION, }; use aptos_types::{ - account_config::{self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS}, + account_config::{ + self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS, + EXPERIMENTAL_CODE_ADDRESS, + }, chain_id::ChainId, contract_event::{ContractEvent, ContractEventV1}, executable::ModulePath, @@ -156,6 +159,9 @@ pub fn encode_aptos_mainnet_genesis_transaction( let genesis_change_set_configs = genesis_vm.genesis_change_set_configs(); let mut session = genesis_vm.new_genesis_session(&resolver, HashValue::zero()); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + // On-chain genesis process. let consensus_config = OnChainConsensusConfig::default_for_genesis(); let execution_config = OnChainExecutionConfig::default_for_genesis(); @@ -163,6 +169,7 @@ pub fn encode_aptos_mainnet_genesis_transaction( initialize( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config, &consensus_config, @@ -172,23 +179,45 @@ pub fn encode_aptos_mainnet_genesis_transaction( initialize_features( &mut session, &module_storage, + &mut traversal_context, genesis_config .initial_features_override .clone() .map(Features::into_flag_vec), ); - initialize_aptos_coin(&mut session, &module_storage); - initialize_on_chain_governance(&mut session, &module_storage, genesis_config); - create_accounts(&mut session, &module_storage, accounts); - create_employee_validators(&mut session, &module_storage, employees, genesis_config); - create_and_initialize_validators_with_commission(&mut session, &module_storage, validators); - set_genesis_end(&mut session, &module_storage); + initialize_aptos_coin(&mut session, &module_storage, &mut traversal_context); + initialize_on_chain_governance( + &mut session, + &module_storage, + &mut traversal_context, + genesis_config, + ); + create_accounts( + &mut session, + &module_storage, + &mut traversal_context, + accounts, + ); + create_employee_validators( + &mut session, + &module_storage, + &mut traversal_context, + employees, + genesis_config, + ); + create_and_initialize_validators_with_commission( + &mut session, + &module_storage, + &mut traversal_context, + validators, + ); + set_genesis_end(&mut session, &module_storage, &mut traversal_context); // Reconfiguration should happen after all on-chain invocations. - emit_new_block_and_epoch_event(&mut session, &module_storage); + emit_new_block_and_epoch_event(&mut session, &module_storage, &mut traversal_context); // Create a change set with all initialized resources. - let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage)); + let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage,)); // Publish the framework, using a different session id, in case both sessions create tables. let mut new_id = [0u8; 32]; @@ -258,10 +287,14 @@ pub fn encode_genesis_change_set( let genesis_change_set_configs = genesis_vm.genesis_change_set_configs(); let mut session = genesis_vm.new_genesis_session(&resolver, HashValue::zero()); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + // On-chain genesis process. initialize( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config, consensus_config, @@ -271,61 +304,94 @@ pub fn encode_genesis_change_set( initialize_features( &mut session, &module_storage, + &mut traversal_context, genesis_config .initial_features_override .clone() .map(Features::into_flag_vec), ); if genesis_config.is_test { - initialize_core_resources_and_aptos_coin(&mut session, &module_storage, core_resources_key); + initialize_core_resources_and_aptos_coin( + &mut session, + &module_storage, + &mut traversal_context, + core_resources_key, + ); } else { - initialize_aptos_coin(&mut session, &module_storage); + initialize_aptos_coin(&mut session, &module_storage, &mut traversal_context); } // Initialize the governed gas pool with a default seed - initialize_governed_gas_pool(&mut session, &module_storage); - initialize_config_buffer(&mut session, &module_storage); - initialize_dkg(&mut session, &module_storage); - initialize_reconfiguration_state(&mut session, &module_storage); + initialize_governed_gas_pool(&mut session, &module_storage, &mut traversal_context); + initialize_config_buffer(&mut session, &module_storage, &mut traversal_context); + initialize_dkg(&mut session, &module_storage, &mut traversal_context); + initialize_reconfiguration_state(&mut session, &module_storage, &mut traversal_context); let randomness_config = genesis_config .randomness_config_override .clone() .unwrap_or_else(OnChainRandomnessConfig::default_for_genesis); - initialize_randomness_api_v0_config(&mut session, &module_storage); - initialize_randomness_config_seqnum(&mut session, &module_storage); - initialize_randomness_config(&mut session, &module_storage, randomness_config); - initialize_randomness_resources(&mut session, &module_storage); - initialize_on_chain_governance(&mut session, &module_storage, genesis_config); - let not_skip_aa: bool = if let Some(features) = &genesis_config.initial_features_override { + initialize_randomness_api_v0_config(&mut session, &module_storage, &mut traversal_context); + initialize_randomness_config_seqnum(&mut session, &module_storage, &mut traversal_context); + initialize_randomness_config( + &mut session, + &module_storage, + &mut traversal_context, + randomness_config, + ); + initialize_randomness_resources(&mut session, &module_storage, &mut traversal_context); + initialize_on_chain_governance( + &mut session, + &module_storage, + &mut traversal_context, + genesis_config, + ); + let not_skip_aa: bool = if let Some(features) = &genesis_config.initial_features_override { features.is_enabled(FeatureFlag::ACCOUNT_ABSTRACTION) || features.is_enabled(FeatureFlag::DERIVABLE_ACCOUNT_ABSTRACTION) } else { false }; if not_skip_aa { - initialize_account_abstraction(&mut session, &module_storage); + initialize_account_abstraction(&mut session, &module_storage, &mut traversal_context); } - create_and_initialize_validators(&mut session, &module_storage, validators); + create_and_initialize_validators( + &mut session, + &module_storage, + &mut traversal_context, + validators, + ); if genesis_config.is_test { - allow_core_resources_to_set_version(&mut session, &module_storage); + allow_core_resources_to_set_version(&mut session, &module_storage, &mut traversal_context); } let jwk_consensus_config = genesis_config .jwk_consensus_config_override .clone() .unwrap_or_else(OnChainJWKConsensusConfig::default_for_genesis); - initialize_jwk_consensus_config(&mut session, &module_storage, &jwk_consensus_config); - initialize_jwks_resources(&mut session, &module_storage); + initialize_jwk_consensus_config( + &mut session, + &module_storage, + &mut traversal_context, + &jwk_consensus_config, + ); + initialize_jwks_resources(&mut session, &module_storage, &mut traversal_context); initialize_keyless_accounts( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config.initial_jwks.clone(), genesis_config.keyless_groth16_vk.clone(), ); - set_genesis_end(&mut session, &module_storage); + initialize_confidential_asset( + &mut session, + &module_storage, + chain_id, + &mut traversal_context, + ); + set_genesis_end(&mut session, &module_storage, &mut traversal_context); // Reconfiguration should happen after all on-chain invocations. - emit_new_block_and_epoch_event(&mut session, &module_storage); + emit_new_block_and_epoch_event(&mut session, &module_storage, &mut traversal_context); - let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage)); + let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage,)); // Publish the framework, using a different id, in case both sessions create tables. let mut new_id = [0u8; 32]; @@ -382,28 +448,30 @@ fn validate_genesis_config(genesis_config: &GenesisConfiguration) { ); } -fn exec_function( +fn exec_function_internal( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, module_name: &str, function_name: &str, ty_args: Vec, args: Vec>, + address: AccountAddress, ) { - let storage = TraversalStorage::new(); session .execute_function_bypass_visibility( - &ModuleId::new(CORE_CODE_ADDRESS, Identifier::new(module_name).unwrap()), + &ModuleId::new(address, Identifier::new(module_name).unwrap()), &Identifier::new(function_name).unwrap(), ty_args, args, &mut UnmeteredGasMeter, - &mut TraversalContext::new(&storage), + traversal_context, module_storage, ) .unwrap_or_else(|e| { panic!( - "Error calling {}.{}: ({:#x}) {}", + "Error calling {}.{}.{}: ({:#x}) {}", + address, module_name, function_name, e.sub_status().unwrap_or_default(), @@ -412,9 +480,52 @@ fn exec_function( }); } +fn exec_function( + session: &mut SessionExt, + module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, + module_name: &str, + function_name: &str, + ty_args: Vec, + args: Vec>, +) { + exec_function_internal( + session, + module_storage, + traversal_context, + module_name, + function_name, + ty_args, + args, + CORE_CODE_ADDRESS, + ); +} + +fn exec_experimental_function( + session: &mut SessionExt, + module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, + module_name: &str, + function_name: &str, + ty_args: Vec, + args: Vec>, +) { + exec_function_internal( + session, + module_storage, + traversal_context, + module_name, + function_name, + ty_args, + args, + EXPERIMENTAL_CODE_ADDRESS, + ); +} + fn initialize( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, chain_id: ChainId, genesis_config: &GenesisConfiguration, consensus_config: &OnChainConsensusConfig, @@ -445,6 +556,7 @@ fn initialize( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize", vec![], @@ -469,6 +581,7 @@ fn initialize( fn initialize_features( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, features_override: Option>, ) { let features: Vec = features_override @@ -484,6 +597,7 @@ fn initialize_features( exec_function( session, module_storage, + traversal_context, "features", "change_feature_flags_internal", vec![], @@ -494,10 +608,12 @@ fn initialize_features( fn initialize_aptos_coin( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_aptos_coin", vec![], @@ -508,11 +624,13 @@ fn initialize_aptos_coin( fn initialize_governed_gas_pool( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { let delegation_pool_creation_seed = b"aptos_framework::governed_gas_pool"; exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_governed_gas_pool", vec![], @@ -526,10 +644,12 @@ fn initialize_governed_gas_pool( fn initialize_config_buffer( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, CONFIG_BUFFER_MODULE_NAME, "initialize", vec![], @@ -540,10 +660,12 @@ fn initialize_config_buffer( fn initialize_dkg( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, DKG_MODULE_NAME, "initialize", vec![], @@ -554,10 +676,12 @@ fn initialize_dkg( fn initialize_randomness_config_seqnum( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_CONFIG_SEQNUM_MODULE_NAME, "initialize", vec![], @@ -568,10 +692,12 @@ fn initialize_randomness_config_seqnum( fn initialize_randomness_api_v0_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_API_V0_CONFIG_MODULE_NAME, "initialize", vec![], @@ -586,11 +712,13 @@ fn initialize_randomness_api_v0_config( fn initialize_randomness_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, randomness_config: OnChainRandomnessConfig, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_CONFIG_MODULE_NAME, "initialize", vec![], @@ -604,10 +732,12 @@ fn initialize_randomness_config( fn initialize_randomness_resources( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_MODULE_NAME, "initialize", vec![], @@ -618,10 +748,12 @@ fn initialize_randomness_resources( fn initialize_account_abstraction( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "initialize", vec![], @@ -631,6 +763,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -647,6 +780,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -661,6 +795,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -671,15 +806,32 @@ fn initialize_account_abstraction( "authenticate".to_string().as_move_value(), ]), ); + + exec_function( + session, + module_storage, + traversal_context, + ACCOUNT_ABSTRACTION_MODULE_NAME, + "register_derivable_authentication_function", + vec![], + serialize_values(&vec![ + MoveValue::Signer(CORE_CODE_ADDRESS), + MoveValue::Address(AccountAddress::ONE), + "sui_derivable_account".to_string().as_move_value(), + "authenticate".to_string().as_move_value(), + ]), + ); } fn initialize_reconfiguration_state( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RECONFIGURATION_STATE_MODULE_NAME, "initialize", vec![], @@ -690,11 +842,13 @@ fn initialize_reconfiguration_state( fn initialize_jwk_consensus_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, jwk_consensus_config: &OnChainJWKConsensusConfig, ) { exec_function( session, module_storage, + traversal_context, JWK_CONSENSUS_CONFIG_MODULE_NAME, "initialize", vec![], @@ -708,10 +862,12 @@ fn initialize_jwk_consensus_config( fn initialize_jwks_resources( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, JWKS_MODULE_NAME, "initialize", vec![], @@ -722,10 +878,12 @@ fn initialize_jwks_resources( fn set_genesis_end( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "set_genesis_end", vec![], @@ -736,12 +894,14 @@ fn set_genesis_end( fn initialize_core_resources_and_aptos_coin( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, core_resources_key: &Ed25519PublicKey, ) { let core_resources_auth_key = AuthenticationKey::ed25519(core_resources_key); exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_core_resources_and_aptos_coin", vec![], @@ -756,11 +916,13 @@ fn initialize_core_resources_and_aptos_coin( fn initialize_on_chain_governance( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, genesis_config: &GenesisConfiguration, ) { exec_function( session, module_storage, + traversal_context, GOVERNANCE_MODULE_NAME, "initialize", vec![], @@ -776,6 +938,7 @@ fn initialize_on_chain_governance( fn initialize_keyless_accounts( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, chain_id: ChainId, mut initial_jwks: Vec, vk: Option, @@ -784,6 +947,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, KEYLESS_ACCOUNT_MODULE_NAME, "update_configuration", vec![], @@ -797,6 +961,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, KEYLESS_ACCOUNT_MODULE_NAME, "update_groth16_verification_key", vec![], @@ -828,6 +993,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, JWKS_MODULE_NAME, "set_patches", vec![], @@ -839,9 +1005,29 @@ fn initialize_keyless_accounts( } } +fn initialize_confidential_asset( + session: &mut SessionExt, + module_storage: &impl AptosModuleStorage, + chain_id: ChainId, + traversal_context: &mut TraversalContext, +) { + if !chain_id.is_mainnet() && !chain_id.is_testnet() { + exec_experimental_function( + session, + module_storage, + traversal_context, + "confidential_asset", + "init_module_for_genesis", + vec![], + serialize_values(&vec![MoveValue::Signer(EXPERIMENTAL_CODE_ADDRESS)]), + ); + } +} + fn create_accounts( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, accounts: &[AccountBalance], ) { let accounts_bytes = bcs::to_bytes(accounts).expect("AccountMaps can be serialized"); @@ -850,6 +1036,7 @@ fn create_accounts( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_accounts", vec![], @@ -860,6 +1047,7 @@ fn create_accounts( fn create_employee_validators( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, employees: &[EmployeePool], genesis_config: &GenesisConfiguration, ) { @@ -873,6 +1061,7 @@ fn create_employee_validators( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_employee_validators", vec![], @@ -886,6 +1075,7 @@ fn create_employee_validators( fn create_and_initialize_validators( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, validators: &[Validator], ) { let validators_bytes = bcs::to_bytes(validators).expect("Validators can be serialized"); @@ -894,6 +1084,7 @@ fn create_and_initialize_validators( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_initialize_validators", vec![], @@ -904,6 +1095,7 @@ fn create_and_initialize_validators( fn create_and_initialize_validators_with_commission( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, validators: &[ValidatorWithCommissionRate], ) { let validators_bytes = bcs::to_bytes(validators).expect("Validators can be serialized"); @@ -915,6 +1107,7 @@ fn create_and_initialize_validators_with_commission( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_initialize_validators_with_commission", vec![], @@ -925,10 +1118,12 @@ fn create_and_initialize_validators_with_commission( fn allow_core_resources_to_set_version( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, VERSION_MODULE_NAME, "initialize_for_test", vec![], @@ -939,12 +1134,14 @@ fn allow_core_resources_to_set_version( fn initialize_package( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, addr: AccountAddress, package: &ReleasePackage, ) { exec_function( session, module_storage, + traversal_context, CODE_MODULE_NAME, "initialize", vec![], @@ -1034,6 +1231,9 @@ fn publish_framework( let resolver = state_view.as_move_resolver(); let mut session = genesis_vm.new_genesis_session(&resolver, hash_value); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + for pack in &framework.packages { // Unfortunately, package does not contain address information, so we have to access its // modules to extract the destination address. @@ -1044,11 +1244,17 @@ fn publish_framework( .1 .self_id() .address(); - initialize_package(&mut session, &module_storage, addr, pack); + initialize_package( + &mut session, + &module_storage, + &mut traversal_context, + addr, + pack, + ); } let change_set = - assert_ok!(session.finish(&genesis_vm.genesis_change_set_configs(), &module_storage)); + assert_ok!(session.finish(&genesis_vm.genesis_change_set_configs(), &module_storage,)); (change_set, module_write_set) } @@ -1056,10 +1262,12 @@ fn publish_framework( fn emit_new_block_and_epoch_event( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, "block", "emit_genesis_block_event", vec![], @@ -1070,6 +1278,7 @@ fn emit_new_block_and_epoch_event( exec_function( session, module_storage, + traversal_context, "reconfiguration", "emit_genesis_reconfiguration_event", vec![], @@ -1194,11 +1403,11 @@ impl TestValidator { pub fn new_test_set(count: Option, initial_stake: Option) -> Vec { let mut rng = rand::SeedableRng::from_seed([1u8; 32]); (0..count.unwrap_or(10)) - .map(|_| TestValidator::gen(&mut rng, initial_stake)) + .map(|_| TestValidator::r#gen(&mut rng, initial_stake)) .collect() } - fn gen(rng: &mut StdRng, initial_stake: Option) -> TestValidator { + fn r#gen(rng: &mut StdRng, initial_stake: Option) -> TestValidator { let key = Ed25519PrivateKey::generate(rng); let auth_key = AuthenticationKey::ed25519(&key.public_key()); let owner_address = auth_key.account_address(); @@ -1565,7 +1774,7 @@ pub fn test_mainnet_end_to_end() { panic!("Invalid WriteSetPayload"); }; - let writeset = changeset.write_set().expect_v0(); + let writeset = changeset.write_set().as_v0(); let state_key = StateKey::on_chain_config::().unwrap(); let bytes = writeset diff --git a/aptos-node/Cargo.toml b/aptos-node/Cargo.toml index 70b0686356e..cbef8c9ac94 100644 --- a/aptos-node/Cargo.toml +++ b/aptos-node/Cargo.toml @@ -70,6 +70,8 @@ either = { workspace = true } fail = { workspace = true } futures = { workspace = true } hex = { workspace = true } +move-vm-runtime = { workspace = true } +move-vm-types = { workspace = true } num_cpus = { workspace = true } rand = { workspace = true } rayon = { workspace = true } @@ -82,10 +84,7 @@ ureq = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [target.'cfg(target_os = "linux")'.dependencies] rstack-self = { workspace = true } @@ -101,4 +100,4 @@ tokio-console = ["aptos-logger/tokio-console", "aptos-config/tokio-console"] smoke-test = ["aptos-jwk-consensus/smoke-test", "aptos-dkg-runtime/smoke-test"] [package.metadata.cargo-machete] -ignored = ["aptos-crypto"] +ignored = ["aptos-crypto", "move-vm-types"] diff --git a/aptos-node/src/consensus.rs b/aptos-node/src/consensus.rs index f1b84c307cb..d7da1d735b7 100644 --- a/aptos-node/src/consensus.rs +++ b/aptos-node/src/consensus.rs @@ -113,7 +113,7 @@ pub fn create_jwk_consensus_runtime( jwk_consensus_network_interfaces: Option>, vtxn_pool: &VTxnPoolState, ) -> Option { - let jwk_consensus_runtime = match jwk_consensus_network_interfaces { + match jwk_consensus_network_interfaces { Some(interfaces) => { let ApplicationNetworkInterfaces { network_client, @@ -135,8 +135,7 @@ pub fn create_jwk_consensus_runtime( Some(jwk_consensus_runtime) }, _ => None, - }; - jwk_consensus_runtime + } } /// Creates and starts the consensus observer and publisher (if enabled) diff --git a/aptos-node/src/lib.rs b/aptos-node/src/lib.rs index d26eee3e8a7..ae1ed8b07de 100644 --- a/aptos-node/src/lib.rs +++ b/aptos-node/src/lib.rs @@ -323,13 +323,13 @@ where framework, rng, )?; - if let Some(ref test_config_override_path) = test_config_override_path { + if let Some(test_config_override_path) = test_config_override_path { println!( "\tMerged default config with override from path: {:?}", test_config_override_path ); } - if let Some(ref config_path) = config_path { + if let Some(config_path) = config_path { println!("\tUsed user-provided config from path: {:?}", config_path); } config @@ -371,6 +371,12 @@ pub fn start_test_environment_node( config.indexer_grpc.address ); } + if config.admin_service.enabled.unwrap_or(false) { + println!( + "\tAdmin service: http://{}:{}/", + config.admin_service.address, config.admin_service.port + ); + } if enable_lazy_mode { println!("\tLazy mode is enabled"); } diff --git a/aptos-node/src/main.rs b/aptos-node/src/main.rs index a3095017580..6f25454a91e 100644 --- a/aptos-node/src/main.rs +++ b/aptos-node/src/main.rs @@ -15,6 +15,9 @@ fn main() { // Check that we are not including any Move test natives aptos_vm::natives::assert_no_test_natives(ERROR_MSG_BAD_FEATURE_FLAGS); + // Check that we do have the Move VM's tracing feature enabled + move_vm_runtime::tracing::assert_move_vm_tracing_feature_disabled(ERROR_MSG_BAD_FEATURE_FLAGS); + // Start the node AptosNodeArgs::parse().run() } diff --git a/aptos-node/src/state_sync.rs b/aptos-node/src/state_sync.rs index 8c309744895..94b7c848820 100644 --- a/aptos-node/src/state_sync.rs +++ b/aptos-node/src/state_sync.rs @@ -274,7 +274,11 @@ fn setup_state_sync_storage_service( let storage_service_runtime = aptos_runtimes::spawn_named_runtime("stor-server".into(), None); // Spawn the state sync storage service servers on the runtime - let storage_reader = StorageReader::new(config.storage_service, Arc::clone(&db_rw.reader)); + let storage_reader = StorageReader::new( + config.storage_service, + Arc::clone(&db_rw.reader), + TimeService::real(), + ); let service = StorageServiceServer::new( config, storage_service_runtime.handle().clone(), diff --git a/aptos-node/src/tests.rs b/aptos-node/src/tests.rs index f41079d37c2..942d2e6c9f1 100644 --- a/aptos-node/src/tests.rs +++ b/aptos-node/src/tests.rs @@ -114,3 +114,26 @@ fn test_create_single_node_test_config() { .bootstrapping_mode ); } + +#[test] +fn test_verifier_cache_enabled_for_aptos_node() { + use std::process::{Command, Stdio}; + // Run the shell command `cargo tree -p aptos-node -e features` + let output = Command::new("cargo") + .arg("tree") + .arg("-p") + .arg("aptos-node") + .arg("-e") + .arg("features") + .stdout(Stdio::piped()) + .output() + .expect("Failed to execute `cargo tree -p aptos-node -e features`"); + let output = String::from_utf8_lossy(&output.stdout); + + let feature = "disable_verifier_cache"; + assert!( + !output.contains(feature), + "Feature `{}` should not be enabled for aptos-node", + feature + ); +} diff --git a/aptos-node/src/utils.rs b/aptos-node/src/utils.rs index 01fdf1e8a83..a735ebaeb6c 100644 --- a/aptos-node/src/utils.rs +++ b/aptos-node/src/utils.rs @@ -12,8 +12,9 @@ use aptos_types::{ account_config::ChainIdResource, chain_id::ChainId, on_chain_config::OnChainConfig, }; use aptos_vm::AptosVM; -use aptos_vm_environment::prod_configs::set_paranoid_type_checks; -use std::cmp::min; +use aptos_vm_environment::prod_configs::{ + set_async_runtime_checks, set_layout_caches, set_paranoid_type_checks, +}; /// Error message to display when non-production features are enabled pub const ERROR_MSG_BAD_FEATURE_FLAGS: &str = r#" @@ -22,9 +23,9 @@ aptos-node was compiled with feature flags that shouldn't be enabled. This is caused by cargo's feature unification. When you compile two crates with a shared dependency, if one enables a feature flag for the dependency, then it is also enabled for the other crate. -PLEASE RECOMPILE APTOS-NODE SEPARATELY using the following command: - cargo build --package aptos-node - +To resolve this issue, try the following methods: +- Recompile `aptos-node` SEPARATELY +- Check if a disallowed feature flag is enabled by a dependency in the build tree "#; /// Initializes a global rayon thread pool iff `create_global_rayon_pool` is true @@ -50,12 +51,11 @@ pub fn fetch_chain_id(db: &DbReaderWriter) -> anyhow::Result { /// Sets the Aptos VM configuration based on the node configurations pub fn set_aptos_vm_configurations(node_config: &NodeConfig) { + set_layout_caches(node_config.execution.layout_caches_enabled); set_paranoid_type_checks(node_config.execution.paranoid_type_verification); + set_async_runtime_checks(node_config.execution.async_runtime_checks); let effective_concurrency_level = if node_config.execution.concurrency_level == 0 { - min( - DEFAULT_EXECUTION_CONCURRENCY_LEVEL, - (num_cpus::get() / 2) as u16, - ) + ((num_cpus::get() / 2) as u16).clamp(1, DEFAULT_EXECUTION_CONCURRENCY_LEVEL) } else { node_config.execution.concurrency_level }; @@ -64,6 +64,7 @@ pub fn set_aptos_vm_configurations(node_config: &NodeConfig) { AptosVM::set_num_proof_reading_threads_once( node_config.execution.num_proof_reading_threads as usize, ); + AptosVM::set_blockstm_v2_enabled_once(node_config.execution.blockstm_v2_enabled); if node_config .execution diff --git a/config/Cargo.toml b/config/Cargo.toml index b9c45b0436e..808dbe9624b 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -20,6 +20,7 @@ aptos-logger = { workspace = true } aptos-secure-storage = { workspace = true } aptos-short-hex-str = { workspace = true } aptos-temppath = { workspace = true } +aptos-transaction-filters = { workspace = true } aptos-types = { workspace = true } arr_macro = { workspace = true } bcs = { workspace = true } diff --git a/config/src/config/admin_service_config.rs b/config/src/config/admin_service_config.rs index e4096b108c0..d2c6f2a1ea0 100644 --- a/config/src/config/admin_service_config.rs +++ b/config/src/config/admin_service_config.rs @@ -20,6 +20,7 @@ pub struct AdminServiceConfig { pub port: u16, // If empty, will allow all requests without authentication. (Not allowed on mainnet.) pub authentication_configs: Vec, + pub malloc_stats_max_len: usize, } #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] @@ -44,6 +45,7 @@ impl Default for AdminServiceConfig { address: "0.0.0.0".to_string(), port: 9102, authentication_configs: vec![], + malloc_stats_max_len: 2 * 1024 * 1024, } } } diff --git a/config/src/config/api_config.rs b/config/src/config/api_config.rs index a70d17411de..d736dad227e 100644 --- a/config/src/config/api_config.rs +++ b/config/src/config/api_config.rs @@ -2,7 +2,6 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::transaction_filter_type::{Filter, Matcher}; use crate::{ config::{ config_sanitizer::ConfigSanitizer, gas_estimation_config::GasEstimationConfig, @@ -80,8 +79,6 @@ pub struct ApiConfig { pub gas_estimation: GasEstimationConfig, /// Periodically call gas estimation pub periodic_gas_estimation_ms: Option, - /// Configuration to filter simulation requests. - pub simulation_filter: Filter, /// Configuration to filter view function requests. pub view_filter: ViewFilter, /// Periodically log stats for view function and simulate transaction usage @@ -139,7 +136,6 @@ impl Default for ApiConfig { runtime_worker_multiplier: 2, gas_estimation: GasEstimationConfig::default(), periodic_gas_estimation_ms: Some(30_000), - simulation_filter: Filter::default(), view_filter: ViewFilter::default(), periodic_function_stats_sec: Some(60), wait_by_hash_timeout_ms: 1_000, @@ -194,16 +190,6 @@ impl ConfigSanitizer for ApiConfig { )); } - // We don't support Block ID based simulation filters. - for rule in api_config.simulation_filter.rules() { - if let Matcher::BlockId(_) = rule.matcher() { - return Err(Error::ConfigSanitizerFailed( - sanitizer_name, - "Block ID based simulation filters are not supported!".into(), - )); - } - } - // Sanitize the gas estimation config GasEstimationConfig::sanitize(node_config, node_type, chain_id)?; diff --git a/config/src/config/config_optimizer.rs b/config/src/config/config_optimizer.rs index 0165cbadb97..c32949da417 100644 --- a/config/src/config/config_optimizer.rs +++ b/config/src/config/config_optimizer.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use super::{ - ConsensusObserverConfig, Identity, IdentityFromConfig, IdentitySource, IndexerGrpcConfig, - StorageConfig, + ConsensusConfig, ConsensusObserverConfig, Identity, IdentityFromConfig, IdentitySource, + IndexerGrpcConfig, StorageConfig, }; use crate::{ config::{ @@ -111,6 +111,9 @@ impl ConfigOptimizer for NodeConfig { if AdminServiceConfig::optimize(node_config, local_config_yaml, node_type, chain_id)? { optimizers_with_modifications.push(AdminServiceConfig::get_optimizer_name()); } + if ConsensusConfig::optimize(node_config, local_config_yaml, node_type, chain_id)? { + optimizers_with_modifications.push(ConsensusConfig::get_optimizer_name()); + } if ConsensusObserverConfig::optimize(node_config, local_config_yaml, node_type, chain_id)? { optimizers_with_modifications.push(ConsensusObserverConfig::get_optimizer_name()); } @@ -349,7 +352,14 @@ mod tests { // Optimize the node config for mainnet VFNs and verify modifications are made let modified_config = NodeConfig::optimize( &mut node_config, - &serde_yaml::from_str("{}").unwrap(), // An empty local config + &serde_yaml::from_str( + r#" + storage: + rocksdb_configs: + enable_storage_sharding: true + "#, + ) + .unwrap(), NodeType::ValidatorFullnode, Some(ChainId::mainnet()), ) diff --git a/config/src/config/consensus_config.rs b/config/src/config/consensus_config.rs index 04c4c058470..dbe40f4fe91 100644 --- a/config/src/config/consensus_config.rs +++ b/config/src/config/consensus_config.rs @@ -6,17 +6,20 @@ use super::DEFEAULT_MAX_BATCH_TXNS; use crate::config::{ - config_sanitizer::ConfigSanitizer, node_config_loader::NodeType, Error, NodeConfig, - QuorumStoreConfig, ReliableBroadcastConfig, SafetyRulesConfig, BATCH_PADDING_BYTES, + config_optimizer::ConfigOptimizer, config_sanitizer::ConfigSanitizer, + node_config_loader::NodeType, Error, NodeConfig, QuorumStoreConfig, ReliableBroadcastConfig, + SafetyRulesConfig, BATCH_PADDING_BYTES, }; use aptos_crypto::_once_cell::sync::Lazy; use aptos_types::chain_id::ChainId; use cfg_if::cfg_if; use serde::{Deserialize, Serialize}; +use serde_yaml::Value; use std::path::PathBuf; // NOTE: when changing, make sure to update QuorumStoreBackPressureConfig::backlog_txn_limit_count as well. const MAX_SENDING_BLOCK_TXNS_AFTER_FILTERING: u64 = 1800; +const MAX_SENDING_OPT_BLOCK_TXNS_AFTER_FILTERING: u64 = 1000; const MAX_SENDING_BLOCK_TXNS: u64 = 5000; pub(crate) static MAX_RECEIVING_BLOCK_TXNS: Lazy = Lazy::new(|| 10000.max(2 * MAX_SENDING_BLOCK_TXNS)); @@ -32,6 +35,7 @@ pub struct ConsensusConfig { pub max_network_channel_size: usize, pub max_sending_block_txns: u64, pub max_sending_block_txns_after_filtering: u64, + pub max_sending_opt_block_txns_after_filtering: u64, pub max_sending_block_bytes: u64, pub max_sending_inline_txns: u64, pub max_sending_inline_bytes: u64, @@ -49,7 +53,8 @@ pub struct ConsensusConfig { // Only sync committed transactions but not vote for any pending blocks. This is useful when // validators coordinate on the latest version to apply a manual transaction. pub sync_only: bool, - pub channel_size: usize, + // The size of the round/recovery manager and proposal buffer channels. + pub internal_per_key_channel_size: usize, pub quorum_store_pull_timeout_ms: u64, // Decides how long the leader waits before proposing empty block if there's no txns in mempool pub quorum_store_poll_time_ms: u64, @@ -95,7 +100,8 @@ pub struct ConsensusConfig { pub max_pending_rounds_in_commit_vote_cache: u64, pub optimistic_sig_verification: bool, pub enable_round_timeout_msg: bool, - pub enable_pipeline: bool, + pub enable_optimistic_proposal_rx: bool, + pub enable_optimistic_proposal_tx: bool, } /// Deprecated @@ -142,6 +148,21 @@ pub struct ExecutionBackpressureTxnLimitConfig { pub min_calibrated_txns_per_block: u64, } +impl Default for ExecutionBackpressureTxnLimitConfig { + fn default() -> Self { + Self { + lookback_config: ExecutionBackpressureLookbackConfig { + num_blocks_to_look_at: 18, + min_block_time_ms_to_activate: 50, + min_blocks_to_activate: 4, + metric: ExecutionBackpressureMetric::Percentile(0.5), + target_block_time_ms: 90, + }, + min_calibrated_txns_per_block: 30, + } + } +} + /// Execution backpressure which handles gas/s variance, /// and adjusts gas limit to "recalibrate it" to wanted range. #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -151,6 +172,22 @@ pub struct ExecutionBackpressureGasLimitConfig { pub min_calibrated_block_gas_limit: u64, } +impl Default for ExecutionBackpressureGasLimitConfig { + fn default() -> Self { + Self { + lookback_config: ExecutionBackpressureLookbackConfig { + num_blocks_to_look_at: 30, + min_block_time_ms_to_activate: 10, + min_blocks_to_activate: 4, + metric: ExecutionBackpressureMetric::Mean, + target_block_time_ms: 90, + }, + block_execution_overhead_ms: 10, + min_calibrated_block_gas_limit: 2000, + } + } +} + #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ExecutionBackpressureConfig { pub txn_limit: Option, @@ -187,6 +224,7 @@ impl Default for ConsensusConfig { max_network_channel_size: 1024, max_sending_block_txns: MAX_SENDING_BLOCK_TXNS, max_sending_block_txns_after_filtering: MAX_SENDING_BLOCK_TXNS_AFTER_FILTERING, + max_sending_opt_block_txns_after_filtering: MAX_SENDING_OPT_BLOCK_TXNS_AFTER_FILTERING, max_sending_block_bytes: 3 * 1024 * 1024, // 3MB max_receiving_block_txns: *MAX_RECEIVING_BLOCK_TXNS, max_sending_inline_txns: 100, @@ -202,7 +240,7 @@ impl Default for ConsensusConfig { round_timeout_backoff_max_exponent: 6, safety_rules: SafetyRulesConfig::default(), sync_only: false, - channel_size: 30, // hard-coded + internal_per_key_channel_size: 10, quorum_store_pull_timeout_ms: 400, quorum_store_poll_time_ms: 300, // disable wait_for_full until fully tested @@ -217,30 +255,11 @@ impl Default for ConsensusConfig { // increase uncontrollably, and we know when to go to state sync. // Considering block gas limit and pipeline backpressure should keep number of blocks // in the pipline very low, we can keep this limit pretty low, too. - vote_back_pressure_limit: 7, + vote_back_pressure_limit: 12, min_max_txns_in_block_after_filtering_from_backpressure: MIN_BLOCK_TXNS_AFTER_FILTERING, execution_backpressure: Some(ExecutionBackpressureConfig { - txn_limit: Some(ExecutionBackpressureTxnLimitConfig { - lookback_config: ExecutionBackpressureLookbackConfig { - num_blocks_to_look_at: 18, - min_block_time_ms_to_activate: 100, - min_blocks_to_activate: 4, - metric: ExecutionBackpressureMetric::Percentile(0.5), - target_block_time_ms: 120, - }, - min_calibrated_txns_per_block: 8, - }), - gas_limit: Some(ExecutionBackpressureGasLimitConfig { - lookback_config: ExecutionBackpressureLookbackConfig { - num_blocks_to_look_at: 30, - min_block_time_ms_to_activate: 10, - min_blocks_to_activate: 4, - metric: ExecutionBackpressureMetric::Mean, - target_block_time_ms: 120, - }, - block_execution_overhead_ms: 10, - min_calibrated_block_gas_limit: 2000, - }), + txn_limit: Some(ExecutionBackpressureTxnLimitConfig::default()), + gas_limit: Some(ExecutionBackpressureGasLimitConfig::default()), }), pipeline_backpressure: vec![ PipelineBackpressureValues { @@ -363,7 +382,8 @@ impl Default for ConsensusConfig { max_pending_rounds_in_commit_vote_cache: 100, optimistic_sig_verification: true, enable_round_timeout_msg: true, - enable_pipeline: true, + enable_optimistic_proposal_rx: true, + enable_optimistic_proposal_tx: true, } } } @@ -513,6 +533,29 @@ impl ConfigSanitizer for ConsensusConfig { } } +// TODO: Re-enable pre-commit for VFNs and PFNs once the feature supports +// a rollback mechanism (to tolerate execution divergence in fullnodes). +impl ConfigOptimizer for ConsensusConfig { + fn optimize( + node_config: &mut NodeConfig, + local_config_yaml: &Value, + node_type: NodeType, + _chain_id: Option, + ) -> Result { + let consensus_config = &mut node_config.consensus; + let local_consensus_config_yaml = &local_config_yaml["consensus"]; + + // Disable pre-commit for VFNs and PFNs (if they are not manually set) + let mut modified_config = false; + if local_consensus_config_yaml["enable_pre_commit"].is_null() && !node_type.is_validator() { + consensus_config.enable_pre_commit = false; + modified_config = true; + } + + Ok(modified_config) + } +} + /// Returns true iff consensus-only-perf-test is enabled fn is_consensus_only_perf_test_enabled() -> bool { cfg_if! { @@ -773,4 +816,72 @@ mod test { ConsensusConfig::sanitize(&node_config, NodeType::ValidatorFullnode, None).unwrap_err(); assert!(matches!(error, Error::ConfigSanitizerFailed(_, _))); } + + #[test] + fn test_optimize_pre_commit() { + // Create a node config with pre-commit enabled + let mut node_config = create_config_with_pre_commit_enabled(); + + // Optimize the config for a validator + let modified_config = ConsensusConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::Validator, + None, + ) + .unwrap(); + + // Verify that the config was not modified, and that pre-commit is still enabled + assert!(!modified_config); + assert!(node_config.consensus.enable_pre_commit); + + // Next, optimize the config for a validator fullnode + let modified_config = ConsensusConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::ValidatorFullnode, + None, + ) + .unwrap(); + + // Verify that the config was modified, and that pre-commit is disabled + assert!(modified_config); + assert!(!node_config.consensus.enable_pre_commit); + + // Create a node config with pre-commit enabled + let mut node_config = create_config_with_pre_commit_enabled(); + + // Create a local config with pre-commit manually enabled + let local_config_yaml = serde_yaml::from_str( + r#" + consensus: + enable_pre_commit: false + "#, + ) + .unwrap(); + + // Optimize the config for a public fullnode (using the local config) + let modified_config = ConsensusConfig::optimize( + &mut node_config, + &local_config_yaml, + NodeType::PublicFullnode, + None, + ) + .unwrap(); + + // Verify that the config was not modified, and that pre-commit is still enabled + assert!(!modified_config); + assert!(node_config.consensus.enable_pre_commit); + } + + /// Creates a node config with pre-commit enabled + fn create_config_with_pre_commit_enabled() -> NodeConfig { + NodeConfig { + consensus: ConsensusConfig { + enable_pre_commit: true, + ..Default::default() + }, + ..Default::default() + } + } } diff --git a/config/src/config/consensus_observer_config.rs b/config/src/config/consensus_observer_config.rs index 0cbd8dd9d01..7c6a8079ad2 100644 --- a/config/src/config/consensus_observer_config.rs +++ b/config/src/config/consensus_observer_config.rs @@ -13,6 +13,9 @@ const ENABLE_ON_VALIDATORS: bool = true; const ENABLE_ON_VALIDATOR_FULLNODES: bool = true; const ENABLE_ON_PUBLIC_FULLNODES: bool = false; +// Maximum number of pending blocks for test networks (e.g., devnet) +const MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS: u64 = 300; + #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct ConsensusObserverConfig { @@ -20,8 +23,6 @@ pub struct ConsensusObserverConfig { pub observer_enabled: bool, /// Whether the consensus publisher is enabled pub publisher_enabled: bool, - /// Whether to use new pipeline - pub enable_pipeline: bool, /// Maximum number of pending network messages pub max_network_channel_size: u64, @@ -64,22 +65,21 @@ impl Default for ConsensusObserverConfig { Self { observer_enabled: false, publisher_enabled: false, - enable_pipeline: true, max_network_channel_size: 1000, max_parallel_serialization_tasks: num_cpus::get(), // Default to the number of CPUs network_request_timeout_ms: 5_000, // 5 seconds garbage_collection_interval_ms: 60_000, // 60 seconds - max_num_pending_blocks: 100, // 100 blocks - progress_check_interval_ms: 5_000, // 5 seconds - max_concurrent_subscriptions: 2, // 2 streams should be sufficient - max_subscription_sync_timeout_ms: 15_000, // 15 seconds - max_subscription_timeout_ms: 15_000, // 15 seconds - subscription_peer_change_interval_ms: 180_000, // 3 minutes - subscription_refresh_interval_ms: 600_000, // 10 minutes - observer_fallback_duration_ms: 600_000, // 10 minutes - observer_fallback_startup_period_ms: 60_000, // 60 seconds - observer_fallback_progress_threshold_ms: 10_000, // 10 seconds - observer_fallback_sync_lag_threshold_ms: 15_000, // 15 seconds + max_num_pending_blocks: 150, // 150 blocks (sufficient for existing production networks) + progress_check_interval_ms: 5_000, // 5 seconds + max_concurrent_subscriptions: 2, // 2 streams should be sufficient + max_subscription_sync_timeout_ms: 15_000, // 15 seconds + max_subscription_timeout_ms: 15_000, // 15 seconds + subscription_peer_change_interval_ms: 180_000, // 3 minutes + subscription_refresh_interval_ms: 600_000, // 10 minutes + observer_fallback_duration_ms: 600_000, // 10 minutes + observer_fallback_startup_period_ms: 60_000, // 60 seconds + observer_fallback_progress_threshold_ms: 10_000, // 10 seconds + observer_fallback_sync_lag_threshold_ms: 15_000, // 15 seconds } } } @@ -96,7 +96,7 @@ impl ConfigOptimizer for ConsensusObserverConfig { node_config: &mut NodeConfig, local_config_yaml: &Value, node_type: NodeType, - _chain_id: Option, + chain_id: Option, ) -> Result { let consensus_observer_config = &mut node_config.consensus_observer; let local_observer_config_yaml = &local_config_yaml["consensus_observer"]; @@ -137,6 +137,139 @@ impl ConfigOptimizer for ConsensusObserverConfig { }, } + // Optimize the max number of pending blocks to accommodate increased block rates. + // Note: we currently only do this for test networks (e.g., devnet). + if let Some(chain_id) = chain_id { + if local_observer_config_yaml["max_num_pending_blocks"].is_null() + && !chain_id.is_testnet() + && !chain_id.is_mainnet() + { + consensus_observer_config.max_num_pending_blocks = + MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS; + modified_config = true; + } + } + Ok(modified_config) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_enable_on_validators() { + // Create a node config with consensus observer and publisher disabled + let mut node_config = create_observer_config(false, false); + + // Optimize the config and verify modifications are made + let modified_config = ConsensusObserverConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::Validator, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(modified_config); + + // Verify the optimized observer and publisher settings + assert!(!node_config.consensus_observer.observer_enabled); + assert!(node_config.consensus_observer.publisher_enabled); + } + + #[test] + fn test_enable_on_validator_fullnodes() { + // Create a node config with consensus observer and publisher disabled + let mut node_config = create_observer_config(false, false); + + // Optimize the config and verify modifications are made + let modified_config = ConsensusObserverConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::ValidatorFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(modified_config); + + // Verify the optimized observer and publisher settings + assert!(node_config.consensus_observer.observer_enabled); + assert!(node_config.consensus_observer.publisher_enabled); + } + + #[test] + fn test_enable_on_public_fullnodes() { + // Create a node config with consensus observer and publisher disabled + let mut node_config = create_observer_config(false, false); + + // Optimize the config and verify no modifications are made + let modified_config = ConsensusObserverConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::PublicFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(!modified_config); + + // Verify the optimized observer and publisher settings + assert!(!node_config.consensus_observer.observer_enabled); + assert!(!node_config.consensus_observer.publisher_enabled); + } + + #[test] + fn test_max_num_pending_blocks_mainnet() { + // Create a node config with consensus observer and publisher enabled + let mut node_config = create_observer_config(true, true); + node_config.consensus_observer.max_num_pending_blocks = 112; + + // Optimize the config and verify no modifications are made + let modified_config = ConsensusObserverConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::PublicFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(!modified_config); + + // Verify the max number of pending blocks remains unchanged + assert_eq!(node_config.consensus_observer.max_num_pending_blocks, 112); + } + + #[test] + fn test_max_num_pending_blocks_devnet() { + // Create a node config with consensus observer and publisher enabled + let mut node_config = create_observer_config(true, true); + node_config.consensus_observer.max_num_pending_blocks = 112; + + // Optimize the config and verify modifications are made + let modified_config = ConsensusObserverConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::PublicFullnode, + Some(ChainId::new(22)), // Test devnet chain ID + ) + .unwrap(); + assert!(modified_config); + + // Verify the max number of pending blocks has been changed + assert_eq!( + node_config.consensus_observer.max_num_pending_blocks, + MAX_NUM_PENDING_BLOCKS_FOR_TEST_NETWORKS + ); + } + + /// Creates a node config with the given consensus observer settings + fn create_observer_config(enable_observer: bool, enable_publisher: bool) -> NodeConfig { + NodeConfig { + consensus_observer: ConsensusObserverConfig { + observer_enabled: enable_observer, + publisher_enabled: enable_publisher, + ..Default::default() + }, + ..Default::default() + } + } +} diff --git a/config/src/config/execution_config.rs b/config/src/config/execution_config.rs index 0959ba8aa9d..2e9abd48507 100644 --- a/config/src/config/execution_config.rs +++ b/config/src/config/execution_config.rs @@ -5,8 +5,7 @@ use super::WaypointConfig; use crate::config::{ config_optimizer::ConfigOptimizer, config_sanitizer::ConfigSanitizer, - node_config_loader::NodeType, transaction_filter_type::Filter, utils::RootPath, Error, - NodeConfig, + node_config_loader::NodeType, utils::RootPath, Error, NodeConfig, }; use aptos_types::{chain_id::ChainId, transaction::Transaction, waypoint::Waypoint}; use serde::{Deserialize, Serialize}; @@ -50,10 +49,15 @@ pub struct ExecutionConfig { pub paranoid_hot_potato_verification: bool, /// Enables enhanced metrics around processed transactions pub processed_transactions_detailed_counters: bool, - /// Enables filtering of transactions before they are sent to execution - pub transaction_filter: Filter, /// Used during DB bootstrapping pub genesis_waypoint: Option, + /// Whether to use BlockSTMv2 for parallel execution. + pub blockstm_v2_enabled: bool, + /// Enables long-living concurrent caches for Move type layouts. + pub layout_caches_enabled: bool, + /// If enabled, runtime checks like paranoid type checks may be performed in parallel in post + /// commit hook in Block-STM. + pub async_runtime_checks: bool, } impl std::fmt::Debug for ExecutionConfig { @@ -84,8 +88,11 @@ impl Default for ExecutionConfig { paranoid_hot_potato_verification: true, discard_failed_blocks: false, processed_transactions_detailed_counters: false, - transaction_filter: Filter::empty(), genesis_waypoint: None, + blockstm_v2_enabled: false, + // TODO: consider setting to be true by default. + layout_caches_enabled: false, + async_runtime_checks: false, } } } diff --git a/config/src/config/inspection_service_config.rs b/config/src/config/inspection_service_config.rs index ea510d5b4ca..e729d109df2 100644 --- a/config/src/config/inspection_service_config.rs +++ b/config/src/config/inspection_service_config.rs @@ -18,6 +18,7 @@ pub struct InspectionServiceConfig { pub address: String, pub port: u16, pub expose_configuration: bool, + pub expose_identity_information: bool, pub expose_peer_information: bool, pub expose_system_information: bool, } @@ -28,6 +29,7 @@ impl Default for InspectionServiceConfig { address: "0.0.0.0".to_string(), port: 9101, expose_configuration: false, + expose_identity_information: true, expose_peer_information: true, expose_system_information: true, } @@ -85,6 +87,11 @@ impl ConfigOptimizer for InspectionServiceConfig { modified_config = true; } + if local_inspection_config_yaml["expose_identity_information"].is_null() { + inspection_service_config.expose_identity_information = true; + modified_config = true; + } + if local_inspection_config_yaml["expose_peer_information"].is_null() { inspection_service_config.expose_peer_information = true; modified_config = true; @@ -111,6 +118,7 @@ mod tests { let mut node_config = NodeConfig { inspection_service: InspectionServiceConfig { expose_configuration: false, + expose_identity_information: false, expose_peer_information: false, expose_system_information: false, ..Default::default() @@ -130,6 +138,7 @@ mod tests { // Verify all endpoints are still disabled assert!(!node_config.inspection_service.expose_configuration); + assert!(!node_config.inspection_service.expose_identity_information); assert!(!node_config.inspection_service.expose_peer_information); assert!(!node_config.inspection_service.expose_system_information); } @@ -159,6 +168,7 @@ mod tests { // Verify all endpoints are now enabled assert!(node_config.inspection_service.expose_configuration); + assert!(node_config.inspection_service.expose_identity_information); assert!(node_config.inspection_service.expose_peer_information); assert!(node_config.inspection_service.expose_system_information); } @@ -197,6 +207,7 @@ mod tests { // Verify only the system information endpoint is now enabled assert!(!node_config.inspection_service.expose_configuration); + assert!(node_config.inspection_service.expose_identity_information); assert!(node_config.inspection_service.expose_peer_information); assert!(node_config.inspection_service.expose_system_information); } diff --git a/config/src/config/mempool_config.rs b/config/src/config/mempool_config.rs index d171d9ab1c0..b62549513bb 100644 --- a/config/src/config/mempool_config.rs +++ b/config/src/config/mempool_config.rs @@ -54,6 +54,8 @@ pub struct MempoolConfig { pub max_broadcasts_per_peer: usize, /// Maximum number of inbound network messages to the Mempool application pub max_network_channel_size: usize, + /// The maximum amount of time a node can be out of sync before being considered unhealthy + pub max_sync_lag_before_unhealthy_secs: usize, /// The interval to take a snapshot of the mempool to logs, only used when trace logging is enabled pub mempool_snapshot_interval_secs: u64, /// The maximum amount of time to wait for an ACK of Mempool submission to an upstream node. @@ -114,6 +116,7 @@ impl Default for MempoolConfig { shared_mempool_ack_timeout_ms: 2_000, shared_mempool_max_concurrent_inbound_syncs: 4, max_broadcasts_per_peer: 20, + max_sync_lag_before_unhealthy_secs: 30, // 30 seconds max_network_channel_size: 1024, mempool_snapshot_interval_secs: 180, capacity: 2_000_000, diff --git a/config/src/config/mod.rs b/config/src/config/mod.rs index bc67df4381f..a11e9e87d43 100644 --- a/config/src/config/mod.rs +++ b/config/src/config/mod.rs @@ -37,7 +37,7 @@ mod safety_rules_config; mod secure_backend_config; mod state_sync_config; mod storage_config; -pub mod transaction_filter_type; +mod transaction_filters_config; mod utils; // All public usage statements should be declared below @@ -69,3 +69,4 @@ pub use safety_rules_config::*; pub use secure_backend_config::*; pub use state_sync_config::*; pub use storage_config::*; +pub use transaction_filters_config::*; diff --git a/config/src/config/network_config.rs b/config/src/config/network_config.rs index 8ecd0964a67..37cb90260be 100644 --- a/config/src/config/network_config.rs +++ b/config/src/config/network_config.rs @@ -274,7 +274,7 @@ impl NetworkConfig { match &mut self.identity { Identity::FromStorage(_) => (), Identity::None => { - let mut rng = StdRng::from_seed(OsRng.gen()); + let mut rng = StdRng::from_seed(OsRng.r#gen()); let key = x25519::PrivateKey::generate(&mut rng); let peer_id = from_identity_public_key(key.public_key()); self.identity = Identity::from_config_auto_generated(key, peer_id); diff --git a/config/src/config/node_config.rs b/config/src/config/node_config.rs index f124dee3b2a..f1991e38400 100644 --- a/config/src/config/node_config.rs +++ b/config/src/config/node_config.rs @@ -8,9 +8,10 @@ use crate::{ internal_indexer_db_config::InternalIndexerDBConfig, jwk_consensus_config::JWKConsensusConfig, netbench_config::NetbenchConfig, node_config_loader::NodeConfigLoader, node_startup_config::NodeStartupConfig, - persistable_config::PersistableConfig, utils::RootPath, AdminServiceConfig, ApiConfig, - BaseConfig, ConsensusConfig, Error, ExecutionConfig, IndexerConfig, IndexerGrpcConfig, - InspectionServiceConfig, LoggerConfig, MempoolConfig, NetworkConfig, + persistable_config::PersistableConfig, + transaction_filters_config::TransactionFiltersConfig, utils::RootPath, AdminServiceConfig, + ApiConfig, BaseConfig, ConsensusConfig, Error, ExecutionConfig, IndexerConfig, + IndexerGrpcConfig, InspectionServiceConfig, LoggerConfig, MempoolConfig, NetworkConfig, PeerMonitoringServiceConfig, SafetyRulesTestConfig, StateSyncConfig, StorageConfig, }, network_id::NetworkId, @@ -83,6 +84,8 @@ pub struct NodeConfig { #[serde(default)] pub storage: StorageConfig, #[serde(default)] + pub transaction_filters: TransactionFiltersConfig, + #[serde(default)] pub validator_network: Option, #[serde(default)] pub indexer_db_config: InternalIndexerDBConfig, diff --git a/config/src/config/override_node_config.rs b/config/src/config/override_node_config.rs index c8648c00d5a..b74601dcc73 100644 --- a/config/src/config/override_node_config.rs +++ b/config/src/config/override_node_config.rs @@ -219,7 +219,7 @@ mod test { config.full_node_networks.push(Default::default()); let diff_yaml = override_config.get_yaml().unwrap(); - let default_node_config = serde_yaml::to_value(&NetworkConfig::default()).unwrap(); + let default_node_config = serde_yaml::to_value(NetworkConfig::default()).unwrap(); let mut expected_yaml: serde_yaml::Value = serde_yaml::Value::Null; expected_yaml["full_node_networks"] = serde_yaml::Value::Sequence(vec![default_node_config.clone(), default_node_config]); @@ -238,7 +238,7 @@ mod test { // Note, the diff will include the entire vector, not just the non-equal elements let diff_yaml = override_config.get_yaml().unwrap(); - let default_node_config = serde_yaml::to_value(&NetworkConfig::default()).unwrap(); + let default_node_config = serde_yaml::to_value(NetworkConfig::default()).unwrap(); let mut expected_yaml: serde_yaml::Value = serde_yaml::Value::Null; expected_yaml["full_node_networks"] = serde_yaml::Value::Sequence(vec![default_node_config.clone(), default_node_config]); diff --git a/config/src/config/peer_monitoring_config.rs b/config/src/config/peer_monitoring_config.rs index e9d8ce6729a..8847ddf7058 100644 --- a/config/src/config/peer_monitoring_config.rs +++ b/config/src/config/peer_monitoring_config.rs @@ -81,7 +81,7 @@ pub struct NodeMonitoringConfig { impl Default for NodeMonitoringConfig { fn default() -> Self { Self { - node_info_request_interval_ms: 20_000, // 20 seconds + node_info_request_interval_ms: 15_000, // 15 seconds node_info_request_timeout_ms: 10_000, // 10 seconds } } diff --git a/config/src/config/quorum_store_config.rs b/config/src/config/quorum_store_config.rs index e4c87be9e2e..7272feb4643 100644 --- a/config/src/config/quorum_store_config.rs +++ b/config/src/config/quorum_store_config.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use std::time::Duration; pub const BATCH_PADDING_BYTES: usize = 160; -pub const DEFEAULT_MAX_BATCH_TXNS: usize = 250; +pub const DEFEAULT_MAX_BATCH_TXNS: usize = 50; const DEFAULT_MAX_NUM_BATCHES: usize = 10; #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] @@ -107,7 +107,7 @@ impl Default for QuorumStoreConfig { channel_size: 1000, proof_timeout_ms: 10000, batch_generation_poll_interval_ms: 25, - batch_generation_min_non_empty_interval_ms: 100, + batch_generation_min_non_empty_interval_ms: 50, batch_generation_max_interval_ms: 250, sender_max_batch_txns: DEFEAULT_MAX_BATCH_TXNS, // TODO: on next release, remove BATCH_PADDING_BYTES @@ -116,7 +116,7 @@ impl Default for QuorumStoreConfig { sender_max_total_txns: 1500, // TODO: on next release, remove DEFAULT_MAX_NUM_BATCHES * BATCH_PADDING_BYTES sender_max_total_bytes: 4 * 1024 * 1024 - DEFAULT_MAX_NUM_BATCHES * BATCH_PADDING_BYTES, - receiver_max_batch_txns: 250, + receiver_max_batch_txns: 100, receiver_max_batch_bytes: 1024 * 1024 + BATCH_PADDING_BYTES, receiver_max_num_batches: 20, receiver_max_total_txns: 2000, @@ -125,7 +125,7 @@ impl Default for QuorumStoreConfig { + BATCH_PADDING_BYTES, batch_request_num_peers: 5, batch_request_retry_limit: 10, - batch_request_retry_interval_ms: 1000, + batch_request_retry_interval_ms: 500, batch_request_rpc_timeout_ms: 5000, batch_expiry_gap_when_init_usecs: Duration::from_secs(60).as_micros() as u64, remote_batch_expiry_gap_when_init_usecs: Duration::from_millis(500).as_micros() as u64, @@ -137,8 +137,8 @@ impl Default for QuorumStoreConfig { num_workers_for_remote_batches: 10, batch_buckets: DEFAULT_BUCKETS.to_vec(), allow_batches_without_pos_in_proposal: true, - enable_opt_quorum_store: false, - opt_qs_minimum_batch_age_usecs: Duration::from_millis(20).as_micros() as u64, + enable_opt_quorum_store: true, + opt_qs_minimum_batch_age_usecs: Duration::from_millis(50).as_micros() as u64, enable_payload_v2: false, } } diff --git a/config/src/config/state_sync_config.rs b/config/src/config/state_sync_config.rs index 8a9fe4e2f1b..78ae45a60b2 100644 --- a/config/src/config/state_sync_config.rs +++ b/config/src/config/state_sync_config.rs @@ -10,8 +10,16 @@ use aptos_types::chain_id::ChainId; use serde::{Deserialize, Serialize}; use serde_yaml::Value; +// Whether to enable size and time-aware chunking (for non-production networks). +// Note: once this becomes stable, we should enable it for all networks (e.g., Mainnet). +const ENABLE_SIZE_AND_TIME_AWARE_CHUNKING: bool = true; + // The maximum message size per state sync message -const MAX_MESSAGE_SIZE: usize = 10 * 1024 * 1024; /* 10 MiB */ +const SERVER_MAX_MESSAGE_SIZE: usize = 10 * 1024 * 1024; // 10 MiB + +// The maximum message size per state sync message (for v2 data requests) +const CLIENT_MAX_MESSAGE_SIZE_V2: usize = 20 * 1024 * 1024; // 20 MiB (used for v2 data requests) +const SERVER_MAX_MESSAGE_SIZE_V2: usize = 40 * 1024 * 1024; // 40 MiB (used for v2 data requests) // The maximum chunk sizes for data client requests and response const MAX_EPOCH_CHUNK_SIZE: u64 = 200; @@ -152,6 +160,10 @@ impl Default for StateSyncDriverConfig { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct StorageServiceConfig { + /// Whether to enable size and time-aware chunking + pub enable_size_and_time_aware_chunking: bool, + /// Whether transaction data v2 is enabled + pub enable_transaction_data_v2: bool, /// Maximum number of epoch ending ledger infos per chunk pub max_epoch_chunk_size: u64, /// Maximum number of invalid requests per peer @@ -162,12 +174,16 @@ pub struct StorageServiceConfig { pub max_network_channel_size: u64, /// Maximum number of bytes to send per network message pub max_network_chunk_bytes: u64, + /// Maximum number of bytes to send per network message (for v2 data) + pub max_network_chunk_bytes_v2: u64, /// Maximum number of active subscriptions (per peer) pub max_num_active_subscriptions: u64, /// Maximum period (ms) of pending optimistic fetch requests pub max_optimistic_fetch_period_ms: u64, /// Maximum number of state keys and values per chunk pub max_state_chunk_size: u64, + /// Maximum time (ms) to wait for storage before truncating a response + pub max_storage_read_wait_time_ms: u64, /// Maximum period (ms) of pending subscription requests pub max_subscription_period_ms: u64, /// Maximum number of transactions per chunk @@ -185,15 +201,19 @@ pub struct StorageServiceConfig { impl Default for StorageServiceConfig { fn default() -> Self { Self { + enable_size_and_time_aware_chunking: false, + enable_transaction_data_v2: true, max_epoch_chunk_size: MAX_EPOCH_CHUNK_SIZE, max_invalid_requests_per_peer: 500, max_lru_cache_size: 500, // At ~0.6MiB per chunk, this should take no more than 0.5GiB max_network_channel_size: 4000, - max_network_chunk_bytes: MAX_MESSAGE_SIZE as u64, + max_network_chunk_bytes: SERVER_MAX_MESSAGE_SIZE as u64, + max_network_chunk_bytes_v2: SERVER_MAX_MESSAGE_SIZE_V2 as u64, max_num_active_subscriptions: 30, max_optimistic_fetch_period_ms: 5000, // 5 seconds max_state_chunk_size: MAX_STATE_CHUNK_SIZE, - max_subscription_period_ms: 30_000, // 30 seconds + max_storage_read_wait_time_ms: 10_000, // 10 seconds + max_subscription_period_ms: 30_000, // 30 seconds max_transaction_chunk_size: MAX_TRANSACTION_CHUNK_SIZE, max_transaction_output_chunk_size: MAX_TRANSACTION_OUTPUT_CHUNK_SIZE, min_time_to_ignore_peers_secs: 300, // 5 minutes @@ -397,6 +417,8 @@ impl Default for AptosLatencyFilteringConfig { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct AptosDataClientConfig { + /// Whether transaction data v2 is enabled + pub enable_transaction_data_v2: bool, /// The aptos data poller config for the data client pub data_poller_config: AptosDataPollerConfig, /// The aptos data multi-fetch config for the data client @@ -409,10 +431,16 @@ pub struct AptosDataClientConfig { pub latency_monitor_loop_interval_ms: u64, /// Maximum number of epoch ending ledger infos per chunk pub max_epoch_chunk_size: u64, - /// Maximum number of output reductions before transactions are returned + /// Maximum number of output reductions (division by 2) before transactions are returned, + /// e.g., if 1000 outputs are requested in a single data chunk, and this is set to 1, then + /// we'll accept anywhere between 1000 and 500 outputs. Any less, and the server should + /// return transactions instead of outputs. + // TODO: migrate away from this, and use cleaner chunk packing configs and logic. pub max_num_output_reductions: u64, /// Maximum lag (in seconds) we'll tolerate when sending optimistic fetch requests pub max_optimistic_fetch_lag_secs: u64, + /// Maximum number of bytes to send in a single response + pub max_response_bytes: u64, /// Maximum timeout (in ms) when waiting for a response (after exponential increases) pub max_response_timeout_ms: u64, /// Maximum number of state keys and values per chunk @@ -425,6 +453,8 @@ pub struct AptosDataClientConfig { pub max_transaction_output_chunk_size: u64, /// Timeout (in ms) when waiting for an optimistic fetch response pub optimistic_fetch_timeout_ms: u64, + /// The duration (in seconds) after which to panic if no progress has been made + pub progress_check_max_stall_time_secs: u64, /// First timeout (in ms) when waiting for a response pub response_timeout_ms: u64, /// Timeout (in ms) when waiting for a subscription response @@ -436,6 +466,7 @@ pub struct AptosDataClientConfig { impl Default for AptosDataClientConfig { fn default() -> Self { Self { + enable_transaction_data_v2: true, data_poller_config: AptosDataPollerConfig::default(), data_multi_fetch_config: AptosDataMultiFetchConfig::default(), ignore_low_score_peers: true, @@ -444,13 +475,15 @@ impl Default for AptosDataClientConfig { max_epoch_chunk_size: MAX_EPOCH_CHUNK_SIZE, max_num_output_reductions: 0, max_optimistic_fetch_lag_secs: 20, // 20 seconds - max_response_timeout_ms: 60_000, // 60 seconds + max_response_bytes: CLIENT_MAX_MESSAGE_SIZE_V2 as u64, + max_response_timeout_ms: 60_000, // 60 seconds max_state_chunk_size: MAX_STATE_CHUNK_SIZE, max_subscription_lag_secs: 20, // 20 seconds max_transaction_chunk_size: MAX_TRANSACTION_CHUNK_SIZE, max_transaction_output_chunk_size: MAX_TRANSACTION_OUTPUT_CHUNK_SIZE, - optimistic_fetch_timeout_ms: 5000, // 5 seconds - response_timeout_ms: 10_000, // 10 seconds + optimistic_fetch_timeout_ms: 5000, // 5 seconds + progress_check_max_stall_time_secs: 86400, // 24 hours (long enough to debug any issues at runtime) + response_timeout_ms: 10_000, // 10 seconds subscription_response_timeout_ms: 15_000, // 15 seconds (longer than a regular timeout because of prefetching) use_compression: true, } @@ -499,9 +532,11 @@ impl ConfigOptimizer for StateSyncConfig { node_type: NodeType, chain_id: Option, ) -> Result { - // Optimize the driver and data streaming service configs + // Optimize the driver let modified_driver_config = StateSyncDriverConfig::optimize(node_config, local_config_yaml, node_type, chain_id)?; + + // Optimize the data streaming service let modified_data_streaming_config = DataStreamingServiceConfig::optimize( node_config, local_config_yaml, @@ -509,7 +544,13 @@ impl ConfigOptimizer for StateSyncConfig { chain_id, )?; - Ok(modified_driver_config || modified_data_streaming_config) + // Optimize the storage service + let modified_storage_service_config = + StorageServiceConfig::optimize(node_config, local_config_yaml, node_type, chain_id)?; + + Ok(modified_driver_config + || modified_data_streaming_config + || modified_storage_service_config) } } @@ -572,6 +613,32 @@ impl ConfigOptimizer for DataStreamingServiceConfig { } } +impl ConfigOptimizer for StorageServiceConfig { + fn optimize( + node_config: &mut NodeConfig, + local_config_yaml: &Value, + _node_type: NodeType, + chain_id: Option, + ) -> Result { + let storage_service_config = &mut node_config.state_sync.storage_service; + let local_storage_config_yaml = &local_config_yaml["state_sync"]["storage_service"]; + + // Potentially enable size and time-aware chunking for all networks except Mainnet + let mut modified_config = false; + if let Some(chain_id) = chain_id { + if ENABLE_SIZE_AND_TIME_AWARE_CHUNKING + && !chain_id.is_mainnet() + && local_storage_config_yaml["enable_size_and_time_aware_chunking"].is_null() + { + storage_service_config.enable_size_and_time_aware_chunking = true; + modified_config = true; + } + } + + Ok(modified_config) + } +} + #[cfg(test)] mod tests { use super::*; @@ -770,6 +837,103 @@ mod tests { ); } + #[test] + fn test_optimize_storage_service_devnet() { + // Create a node config with size and time-aware chunking disabled + let mut node_config = NodeConfig { + state_sync: StateSyncConfig { + storage_service: StorageServiceConfig { + enable_size_and_time_aware_chunking: false, + ..Default::default() + }, + ..Default::default() + }, + ..Default::default() + }; + + // Optimize the config and verify modifications are made + let modified_config = StateSyncConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::ValidatorFullnode, + Some(ChainId::new(40)), // Not mainnet or testnet + ) + .unwrap(); + assert!(modified_config); + + // Verify that size and time-aware chunking is enabled + let storage_service_config = &node_config.state_sync.storage_service; + assert!(storage_service_config.enable_size_and_time_aware_chunking); + } + + #[test] + fn test_optimize_storage_service_mainnet() { + // Create a node config with size and time-aware chunking disabled + let mut node_config = NodeConfig { + state_sync: StateSyncConfig { + storage_service: StorageServiceConfig { + enable_size_and_time_aware_chunking: false, + ..Default::default() + }, + ..Default::default() + }, + ..Default::default() + }; + + // Optimize the config and verify modifications are made + let modified_config = StateSyncConfig::optimize( + &mut node_config, + &serde_yaml::from_str("{}").unwrap(), // An empty local config, + NodeType::PublicFullnode, + Some(ChainId::mainnet()), + ) + .unwrap(); + assert!(modified_config); + + // Verify that size and time-aware chunking is still disabled + let storage_service_config = &node_config.state_sync.storage_service; + assert!(!storage_service_config.enable_size_and_time_aware_chunking); + } + + #[test] + fn test_optimize_storage_service_no_override() { + // Create a node config with size and time-aware chunking disabled + let mut node_config = NodeConfig { + state_sync: StateSyncConfig { + storage_service: StorageServiceConfig { + enable_size_and_time_aware_chunking: false, + ..Default::default() + }, + ..Default::default() + }, + ..Default::default() + }; + + // Create a local config YAML with size and time-aware chunking disabled + let local_config_yaml = serde_yaml::from_str( + r#" + state_sync: + storage_service: + enable_size_and_time_aware_chunking: false + "#, + ) + .unwrap(); + + // Optimize the config and verify modifications are made + let modified_config = StateSyncConfig::optimize( + &mut node_config, + &local_config_yaml, + NodeType::ValidatorFullnode, + Some(ChainId::testnet()), + ) + .unwrap(); + assert!(modified_config); + + // Verify that size and time-aware chunking is still disabled + let storage_service_config = &node_config.state_sync.storage_service; + assert!(!storage_service_config.enable_size_and_time_aware_chunking); + } + #[test] fn test_sanitize_auto_bootstrapping_fast_sync() { // Create a node config with fast sync and diff --git a/config/src/config/storage_config.rs b/config/src/config/storage_config.rs index a737bf71393..41482133164 100644 --- a/config/src/config/storage_config.rs +++ b/config/src/config/storage_config.rs @@ -103,24 +103,63 @@ impl ShardedDbPathConfig { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum RocksDBStatsLevel { + ExceptHistogramOrTimers, + ExceptTimers, + ExceptDetailedTimers, + ExceptTimeForMutex, + All, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum IndexType { + BinarySearch, + HashSearch, + TwoLevelIndexSearch, +} + /// Port selected RocksDB options for tuning underlying rocksdb instance of AptosDB. /// see /// for detailed explanations. -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct RocksdbConfig { /// Maximum number of files open by RocksDB at one time pub max_open_files: i32, /// Maximum size of the RocksDB write ahead log (WAL) pub max_total_wal_size: u64, - /// Maximum number of background threads for Rocks DB + /// Maximum number of background jobs for Rocks DB pub max_background_jobs: i32, /// Block cache size for Rocks DB + /// DEPRECATED: use `shared_block_cache_size` in `RocksdbConfigs` instead. pub block_cache_size: u64, /// Block size for Rocks DB pub block_size: u64, - /// Whether cache index and filter blocks into block cache. + /// Index type used for tables. + pub index_type: IndexType, + /// Use partitioned filters. + pub partition_filters: bool, + /// Whether to cache index and filter blocks into block cache. pub cache_index_and_filter_blocks: bool, + /// Whether to pin L0 filters and indexes in memory. Only makes sense if + /// `cache_index_and_filter_blocks` is `true`. + pub pin_l0_filter_and_index_blocks_in_cache: bool, + /// The level of details for statistics. Higher level might cause more overhead. `None` means + /// disabling everything. + pub stats_level: Option, + /// If not zero, dump stats to LOG every this many seconds. `None` means using RocksDB's + /// default. + pub stats_dump_period_sec: Option, + /// Enable bloom filters with given space per key. + pub bloom_filter_bits: Option, + /// If not `None`, use hybrid ribbon filter policy. + pub bloom_before_level: Option, +} + +impl RocksdbConfig { + /// Default block size is 4KB, + const DEFAULT_BLOCK_SIZE: u64 = 4 * (1 << 10); } impl Default for RocksdbConfig { @@ -131,20 +170,28 @@ impl Default for RocksdbConfig { // For now we set the max total WAL size to be 1G. This config can be useful when column // families are updated at non-uniform frequencies. max_total_wal_size: 1u64 << 30, - // This includes threads for flashing and compaction. Rocksdb will decide the # of - // threads to use internally. - max_background_jobs: 16, - // Default block cache size is 8MB, - block_cache_size: 8 * (1u64 << 20), - // Default block cache size is 4KB, - block_size: 4 * (1u64 << 10), - // Whether cache index and filter blocks into block cache. - cache_index_and_filter_blocks: false, + // This includes jobs for flush and compaction. + max_background_jobs: 4, + // Not used. Only kept for backward compatibility. + block_cache_size: 0, + block_size: Self::DEFAULT_BLOCK_SIZE, + index_type: IndexType::TwoLevelIndexSearch, + partition_filters: true, + // Count index/filter blocks in block cache usage by default. + cache_index_and_filter_blocks: true, + // L0 index/filter blocks are usually small and used frequently. + pin_l0_filter_and_index_blocks_in_cache: true, + // Enable but use a less detailed option by default since there might be some overhead. + stats_level: Some(RocksDBStatsLevel::ExceptHistogramOrTimers), + // Use RocksDB's default if not specified. + stats_dump_period_sec: None, + bloom_filter_bits: None, + bloom_before_level: None, } } } -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct RocksdbConfigs { // TODO(grao): Add RocksdbConfig for individual ledger DBs when necessary. @@ -152,8 +199,21 @@ pub struct RocksdbConfigs { pub state_merkle_db_config: RocksdbConfig, pub state_kv_db_config: RocksdbConfig, pub index_db_config: RocksdbConfig, - // Note: Not ready for production use yet. + #[serde(default = "default_to_true")] pub enable_storage_sharding: bool, + pub high_priority_background_threads: i32, + pub low_priority_background_threads: i32, + /// The size of the single block cache shared by all the DB instances in `AptosDB`. + pub shared_block_cache_size: usize, +} + +impl RocksdbConfigs { + /// Default block cache size is 24GB. + pub const DEFAULT_BLOCK_CACHE_SIZE: usize = 24 * (1 << 30); +} + +fn default_to_true() -> bool { + true } impl Default for RocksdbConfigs { @@ -161,17 +221,24 @@ impl Default for RocksdbConfigs { Self { ledger_db_config: RocksdbConfig::default(), state_merkle_db_config: RocksdbConfig::default(), - state_kv_db_config: RocksdbConfig::default(), + state_kv_db_config: RocksdbConfig { + bloom_filter_bits: Some(10.0), + bloom_before_level: Some(2), + ..Default::default() + }, index_db_config: RocksdbConfig { max_open_files: 1000, ..Default::default() }, - enable_storage_sharding: false, + enable_storage_sharding: true, + high_priority_background_threads: 4, + low_priority_background_threads: 2, + shared_block_cache_size: Self::DEFAULT_BLOCK_CACHE_SIZE, } } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] pub struct StorageConfig { pub backup_service_address: SocketAddr, @@ -440,7 +507,7 @@ impl StorageDirPaths { .unwrap_or(&self.default_path) } - pub fn state_kv_db_shard_root_path(&self, shard_id: u8) -> &PathBuf { + pub fn state_kv_db_shard_root_path(&self, shard_id: usize) -> &PathBuf { self.state_kv_db_paths .shard_path(shard_id) .unwrap_or(&self.default_path) @@ -452,13 +519,13 @@ impl StorageDirPaths { .unwrap_or(&self.default_path) } - pub fn state_merkle_db_shard_root_path(&self, shard_id: u8) -> &PathBuf { + pub fn state_merkle_db_shard_root_path(&self, shard_id: usize) -> &PathBuf { self.state_merkle_db_paths .shard_path(shard_id) .unwrap_or(&self.default_path) } - pub fn hot_state_kv_db_shard_root_path(&self, shard_id: u8) -> &PathBuf { + pub fn hot_state_kv_db_shard_root_path(&self, shard_id: usize) -> &PathBuf { self.hot_state_kv_db_paths .shard_path(shard_id) .unwrap_or(&self.default_path) @@ -514,8 +581,8 @@ impl ShardedDbPaths { self.metadata_path.as_ref() } - fn shard_path(&self, shard_id: u8) -> Option<&PathBuf> { - self.shard_paths[shard_id as usize].as_ref() + fn shard_path(&self, shard_id: usize) -> Option<&PathBuf> { + self.shard_paths[shard_id].as_ref() } } @@ -541,6 +608,11 @@ impl ConfigOptimizer for StorageConfig { config.assert_rlimit_nofile = true; modified_config = true; } + if (chain_id.is_testnet() || chain_id.is_mainnet()) + && config_yaml["rocksdb_configs"]["enable_storage_sharding"].as_bool() != Some(true) + { + panic!("Storage sharding (AIP-97) is not enabled in node config. Please follow the guide to migration your node, and set storage.rocksdb_configs.enable_storage_sharding to true explicitly in your node config. https://aptoslabs.notion.site/DB-Sharding-Migration-Public-Full-Nodes-1978b846eb7280b29f17ceee7d480730"); + } } Ok(modified_config) @@ -739,9 +811,17 @@ mod test { assert_eq!(node_config.storage.ensure_rlimit_nofile, 0); assert!(!node_config.storage.assert_rlimit_nofile); + let yaml = serde_yaml::from_str( + r#" + storage: + rocksdb_configs: + enable_storage_sharding: true + "#, + ) + .unwrap(); let modified_config = StorageConfig::optimize( &mut node_config, - &serde_yaml::from_str("{}").unwrap(), // An empty local config, + &yaml, NodeType::Validator, Some(ChainId::mainnet()), ) @@ -753,7 +833,7 @@ mod test { let modified_config = StorageConfig::optimize( &mut node_config, - &serde_yaml::from_str("{}").unwrap(), // An empty local config, + &yaml, NodeType::Validator, Some(ChainId::testnet()), ) diff --git a/config/src/config/transaction_filter_type.rs b/config/src/config/transaction_filter_type.rs deleted file mode 100644 index 8804d629535..00000000000 --- a/config/src/config/transaction_filter_type.rs +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_crypto::HashValue; -use aptos_types::{ - account_address::AccountAddress, - transaction::{SignedTransaction, TransactionExecutableRef}, -}; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub enum Matcher { - All, // Matches any transactions - BlockId(HashValue), // Matches transactions in a specific block (identified by block ID) - BlockTimeStampGreaterThan(u64), // Matches transactions in blocks with timestamps greater than the specified value - BlockTimeStampLessThan(u64), // Matches transactions in blocks with timestamps less than the specified value - TransactionId(HashValue), // Matches a specific transaction by its ID - Sender(AccountAddress), // Matches transactions sent by a specific account address - ModuleAddress(AccountAddress), // Matches transactions that call a module at a specific address - EntryFunction(AccountAddress, String, String), // Matches transactions that call a specific entry function in a module - BlockEpochGreaterThan(u64), // Matches transactions in blocks with epochs greater than the specified value - BlockEpochLessThan(u64), // Matches transactions in blocks with epochs less than the specified value - MatchesAllOf(Vec), // Matches transactions that satisfy all the provided conditions (i.e., logical AND) -} - -impl Matcher { - fn matches( - &self, - block_id: HashValue, - block_epoch: u64, - block_timestamp: u64, - txn: &SignedTransaction, - ) -> bool { - match self { - Matcher::All => true, - Matcher::BlockId(id) => block_id == *id, - Matcher::BlockTimeStampGreaterThan(timestamp) => block_timestamp > *timestamp, - Matcher::BlockTimeStampLessThan(timestamp) => block_timestamp < *timestamp, - Matcher::TransactionId(id) => txn.committed_hash() == *id, - Matcher::Sender(sender) => txn.sender() == *sender, - Matcher::ModuleAddress(address) => match txn.payload().executable_ref() { - Ok(TransactionExecutableRef::EntryFunction(entry_function)) - if !txn.payload().is_multisig() => - { - *entry_function.module().address() == *address - }, - _ => false, - }, - Matcher::EntryFunction(address, module_name, function) => { - match txn.payload().executable_ref() { - Ok(TransactionExecutableRef::EntryFunction(entry_function)) - if !txn.payload().is_multisig() => - { - *entry_function.module().address() == *address - && entry_function.module().name().to_string() == *module_name - && entry_function.function().to_string() == *function - }, - _ => false, - } - }, - Matcher::BlockEpochGreaterThan(epoch) => block_epoch > *epoch, - Matcher::BlockEpochLessThan(epoch) => block_epoch < *epoch, - Matcher::MatchesAllOf(matchers) => matchers - .iter() - .all(|matcher| matcher.matches(block_id, block_epoch, block_timestamp, txn)), - } - } -} - -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub enum Rule { - Allow(Matcher), - Deny(Matcher), -} - -impl Rule { - pub fn matcher(&self) -> &Matcher { - match self { - Rule::Allow(matcher) => matcher, - Rule::Deny(matcher) => matcher, - } - } -} - -enum EvalResult { - Allow, - Deny, - NoMatch, -} - -impl Rule { - fn eval( - &self, - block_id: HashValue, - block_epoch: u64, - block_timestamp: u64, - txn: &SignedTransaction, - ) -> EvalResult { - match self { - Rule::Allow(matcher) => { - if matcher.matches(block_id, block_epoch, block_timestamp, txn) { - EvalResult::Allow - } else { - EvalResult::NoMatch - } - }, - Rule::Deny(matcher) => { - if matcher.matches(block_id, block_epoch, block_timestamp, txn) { - EvalResult::Deny - } else { - EvalResult::NoMatch - } - }, - } - } -} - -/// A filter that can be used to allow or deny transactions from being executed. It contains a -/// set of rules that are evaluated one by one in the order of declaration. If a rule matches, -/// the transaction is either allowed or denied depending on the rule. If no rule matches, -/// the transaction is allowed. -/// -/// For example, a filter might look like this: -/// rules: -/// - Allow: -/// Sender: f8871acf2c827d40e23b71f6ff2b9accef8dbb17709b88bd9eb95e6bb748c25a -/// - Allow: -/// MatchesAllOf: -/// - Sender: 0xcd3357a925307983f7fbf1a433e87e49eda93fbb94d0d31974e68b5d60e09f3a -/// - BlockEpochGreaterThan: 10 -/// - Allow: -/// ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" -/// - Allow: -/// EntryFunction: -/// - "0000000000000000000000000000000000000000000000000000000000000002" -/// - test -/// - check -/// - Allow: -/// EntryFunction: -/// - "0000000000000000000000000000000000000000000000000000000000000002" -/// - test -/// - new -/// - Deny: All -/// This filter allows transactions with the following properties: -/// - Sender with address f8871acf2c827d40e23b71f6ff2b9accef8dbb17709b88bd9eb95e6bb748c25a. -/// - Sender with address cd3357a925307983f7fbf1a433e87e49eda93fbb94d0d31974e68b5d60e09f3a, and -/// block epoch greater than 10. -/// - Transactions for the module with address 0000000000000000000000000000000000000000000000000000000000000001. -/// - Transactions that call the entry function test::check or test::new from the module with -/// address 0000000000000000000000000000000000000000000000000000000000000002. -/// All other transactions are denied. -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub struct Filter { - rules: Vec, -} - -impl Filter { - pub fn empty() -> Self { - Self { rules: vec![] } - } - - pub fn is_empty(&self) -> bool { - self.rules.is_empty() - } - - fn add_match_rule(mut self, allow: bool, matcher: Matcher) -> Self { - if allow { - self.rules.push(Rule::Allow(matcher)); - } else { - self.rules.push(Rule::Deny(matcher)); - } - self - } - - pub fn add_all_filter(self, allow: bool) -> Self { - let matcher = Matcher::All; - self.add_match_rule(allow, matcher) - } - - pub fn add_block_id_filter(self, allow: bool, block_id: HashValue) -> Self { - let matcher = Matcher::BlockId(block_id); - self.add_match_rule(allow, matcher) - } - - pub fn add_block_timestamp_greater_than_filter(self, allow: bool, timestamp: u64) -> Self { - let matcher = Matcher::BlockTimeStampGreaterThan(timestamp); - self.add_match_rule(allow, matcher) - } - - pub fn add_block_timestamp_less_than_filter(self, allow: bool, timestamp: u64) -> Self { - let matcher = Matcher::BlockTimeStampLessThan(timestamp); - self.add_match_rule(allow, matcher) - } - - pub fn add_transaction_id_filter(self, allow: bool, txn_id: HashValue) -> Self { - let matcher = Matcher::TransactionId(txn_id); - self.add_match_rule(allow, matcher) - } - - pub fn add_sender_filter(self, allow: bool, sender: AccountAddress) -> Self { - let matcher = Matcher::Sender(sender); - self.add_match_rule(allow, matcher) - } - - pub fn add_module_address_filter(self, allow: bool, address: AccountAddress) -> Self { - let matcher = Matcher::ModuleAddress(address); - self.add_match_rule(allow, matcher) - } - - pub fn add_entry_function_filter( - self, - allow: bool, - address: AccountAddress, - module_name: String, - function: String, - ) -> Self { - let matcher = Matcher::EntryFunction(address, module_name, function); - self.add_match_rule(allow, matcher) - } - - pub fn add_block_epoch_greater_than_filter(self, allow: bool, epoch: u64) -> Self { - let matcher = Matcher::BlockEpochGreaterThan(epoch); - self.add_match_rule(allow, matcher) - } - - pub fn add_block_epoch_less_than_filter(self, allow: bool, epoch: u64) -> Self { - let matcher = Matcher::BlockEpochLessThan(epoch); - self.add_match_rule(allow, matcher) - } - - pub fn add_matches_all_of_filter(self, allow: bool, matchers: Vec) -> Self { - let matcher = Matcher::MatchesAllOf(matchers); - self.add_match_rule(allow, matcher) - } - - pub fn rules(&self) -> &[Rule] { - &self.rules - } - - pub fn allows( - &self, - block_id: HashValue, - block_epoch: u64, - block_timestamp: u64, - txn: &SignedTransaction, - ) -> bool { - for rule in &self.rules { - // Rules are evaluated in the order and the first rule that matches is used. If no rule - // matches, the transaction is allowed. - match rule.eval(block_id, block_epoch, block_timestamp, txn) { - EvalResult::Allow => return true, - EvalResult::Deny => return false, - EvalResult::NoMatch => continue, - } - } - true - } -} diff --git a/config/src/config/transaction_filters_config.rs b/config/src/config/transaction_filters_config.rs new file mode 100644 index 00000000000..7560db5463c --- /dev/null +++ b/config/src/config/transaction_filters_config.rs @@ -0,0 +1,123 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_transaction_filters::{ + batch_transaction_filter::BatchTransactionFilter, + block_transaction_filter::BlockTransactionFilter, transaction_filter::TransactionFilter, +}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct TransactionFiltersConfig { + pub api_filter: TransactionFilterConfig, // Filter for the API (e.g., txn simulation) + pub consensus_filter: BlockTransactionFilterConfig, // Filter for consensus (e.g., proposal voting) + pub execution_filter: BlockTransactionFilterConfig, // Filter for execution (e.g., block execution) + pub mempool_filter: TransactionFilterConfig, // Filter for mempool (e.g., txn submission) + pub quorum_store_filter: BatchTransactionFilterConfig, // Filter for quorum store (e.g., batch voting) +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct TransactionFilterConfig { + filter_enabled: bool, // Whether the filter is enabled + transaction_filter: TransactionFilter, // The transaction filter to apply +} + +impl TransactionFilterConfig { + pub fn new(filter_enabled: bool, transaction_filter: TransactionFilter) -> Self { + Self { + filter_enabled, + transaction_filter, + } + } + + /// Returns true iff the filter is enabled and not empty + pub fn is_enabled(&self) -> bool { + self.filter_enabled && !self.transaction_filter.is_empty() + } + + /// Returns a reference to the transaction filter + pub fn transaction_filter(&self) -> &TransactionFilter { + &self.transaction_filter + } +} + +impl Default for TransactionFilterConfig { + fn default() -> Self { + Self { + filter_enabled: false, // Disable the filter + transaction_filter: TransactionFilter::empty(), // Use an empty filter + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct BatchTransactionFilterConfig { + filter_enabled: bool, // Whether the filter is enabled + batch_transaction_filter: BatchTransactionFilter, // The batch transaction filter to apply +} + +impl BatchTransactionFilterConfig { + pub fn new(filter_enabled: bool, batch_transaction_filter: BatchTransactionFilter) -> Self { + Self { + filter_enabled, + batch_transaction_filter, + } + } + + /// Returns true iff the filter is enabled and not empty + pub fn is_enabled(&self) -> bool { + self.filter_enabled && !self.batch_transaction_filter.is_empty() + } + + /// Returns a reference to the batch transaction filter + pub fn batch_transaction_filter(&self) -> &BatchTransactionFilter { + &self.batch_transaction_filter + } +} + +impl Default for BatchTransactionFilterConfig { + fn default() -> Self { + Self { + filter_enabled: false, // Disable the filter + batch_transaction_filter: BatchTransactionFilter::empty(), // Use an empty filter + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct BlockTransactionFilterConfig { + filter_enabled: bool, // Whether the filter is enabled + block_transaction_filter: BlockTransactionFilter, // The block transaction filter to apply +} + +impl BlockTransactionFilterConfig { + pub fn new(filter_enabled: bool, block_transaction_filter: BlockTransactionFilter) -> Self { + Self { + filter_enabled, + block_transaction_filter, + } + } + + /// Returns true iff the filter is enabled and not empty + pub fn is_enabled(&self) -> bool { + self.filter_enabled && !self.block_transaction_filter.is_empty() + } + + /// Returns a reference to the block transaction filter + pub fn block_transaction_filter(&self) -> &BlockTransactionFilter { + &self.block_transaction_filter + } +} + +impl Default for BlockTransactionFilterConfig { + fn default() -> Self { + Self { + filter_enabled: false, // Disable the filter + block_transaction_filter: BlockTransactionFilter::empty(), // Use an empty filter + } + } +} diff --git a/config/src/utils.rs b/config/src/utils.rs index 8ce9adbd455..13f9bc5dba3 100644 --- a/config/src/utils.rs +++ b/config/src/utils.rs @@ -30,13 +30,7 @@ const PORT_SEED: [u8; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ]; // See https://nexte.st/book/env-vars.html#environment-variables-nextest-sets -static NEXTEST_RUN_ID: Lazy> = Lazy::new(|| { - if let Ok(run_id) = env::var("NEXTEST_RUN_ID") { - Some(run_id) - } else { - None - } -}); +static NEXTEST_RUN_ID: Lazy> = Lazy::new(|| env::var("NEXTEST_RUN_ID").ok()); static PORT_VECTOR: Lazy> = Lazy::new(|| { let mut ports: Vec<_> = UNIQUE_PORT_RANGE.collect(); let mut rng = rand::rngs::StdRng::from_seed(PORT_SEED); diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 84eac7943ac..3b8dcb17ca1 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -37,6 +37,7 @@ aptos-metrics-core = { workspace = true } aptos-network = { workspace = true } aptos-peer-monitoring-service-types = { workspace = true } aptos-reliable-broadcast = { workspace = true } +aptos-resource-viewer = { workspace = true } aptos-runtimes = { workspace = true } aptos-safety-rules = { workspace = true } aptos-schemadb = { workspace = true } @@ -45,6 +46,7 @@ aptos-short-hex-str = { workspace = true } aptos-storage-interface = { workspace = true } aptos-temppath = { workspace = true } aptos-time-service = { workspace = true } +aptos-transaction-filters = { workspace = true } aptos-types = { workspace = true } aptos-validator-transaction-pool = { workspace = true } aptos-vm = { workspace = true } @@ -67,6 +69,7 @@ maplit = { workspace = true } mini-moka = { workspace = true } mirai-annotations = { workspace = true } move-core-types = { workspace = true } +move-vm-runtime = { workspace = true } num-derive = { workspace = true } num-traits = { workspace = true } once_cell = { workspace = true } @@ -77,7 +80,6 @@ scopeguard = { workspace = true } serde = { workspace = true } serde_bytes = { workspace = true } serde_json = { workspace = true } -serde_yaml = { workspace = true } sha3 = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true } @@ -96,9 +98,9 @@ aptos-mempool = { workspace = true, features = ["fuzzing"] } aptos-netcore = { workspace = true } aptos-network = { workspace = true, features = ["fuzzing"] } aptos-safety-rules = { workspace = true, features = ["testing"] } +aptos-transaction-filters = { workspace = true, features = ["fuzzing"] } aptos-types = { workspace = true, features = ["testing"] } aptos-vm = { workspace = true, features = ["fuzzing"] } -aptos-vm-validator = { workspace = true } claims = { workspace = true } mockall = { workspace = true } move-core-types = { workspace = true } diff --git a/consensus/consensus-types/src/block.rs b/consensus/consensus-types/src/block.rs index 95c6c2c3ead..0e448a3ea64 100644 --- a/consensus/consensus-types/src/block.rs +++ b/consensus/consensus-types/src/block.rs @@ -5,9 +5,10 @@ use crate::{ block_data::{BlockData, BlockType}, common::{Author, Payload, Round}, + opt_block_data::OptBlockData, quorum_cert::QuorumCert, }; -use anyhow::{bail, ensure, format_err}; +use anyhow::{bail, ensure, format_err, Result}; use aptos_bitvec::BitVec; use aptos_crypto::{bls12381, hash::CryptoHash, HashValue}; use aptos_infallible::duration_since_epoch; @@ -124,6 +125,83 @@ impl Block { } } + /// Returns the number of proofs, the number of txns in the proofs, and the bytes of txns in the proofs + pub fn proof_stats(&self) -> (usize, usize, usize) { + match self.block_data.payload() { + None => (0, 0, 0), + Some(payload) => match payload { + Payload::InQuorumStore(pos) => (pos.num_proofs(), pos.num_txns(), pos.num_bytes()), + Payload::DirectMempool(_txns) => (0, 0, 0), + Payload::InQuorumStoreWithLimit(pos) => ( + pos.proof_with_data.num_proofs(), + pos.proof_with_data.num_txns(), + pos.proof_with_data.num_bytes(), + ), + Payload::QuorumStoreInlineHybrid(_inline_batches, proof_with_data, _) + | Payload::QuorumStoreInlineHybridV2(_inline_batches, proof_with_data, _) => ( + proof_with_data.num_proofs(), + proof_with_data.num_txns(), + proof_with_data.num_bytes(), + ), + Payload::OptQuorumStore(opt_quorum_store_payload) => ( + opt_quorum_store_payload.proof_with_data().num_proofs(), + opt_quorum_store_payload.proof_with_data().num_txns(), + opt_quorum_store_payload.proof_with_data().num_bytes(), + ), + }, + } + } + + /// Returns the number of inline batches, the number of txns in the inline batches, and the bytes of txns in the inline batches + pub fn inline_batch_stats(&self) -> (usize, usize, usize) { + match self.block_data.payload() { + None => (0, 0, 0), + Some(payload) => match payload { + Payload::QuorumStoreInlineHybrid(inline_batches, _proof_with_data, _) + | Payload::QuorumStoreInlineHybridV2(inline_batches, _proof_with_data, _) => ( + inline_batches.len(), + inline_batches + .iter() + .map(|(b, _)| b.num_txns() as usize) + .sum(), + inline_batches + .iter() + .map(|(b, _)| b.num_bytes() as usize) + .sum(), + ), + Payload::OptQuorumStore(opt_quorum_store_payload) => ( + opt_quorum_store_payload.inline_batches().num_batches(), + opt_quorum_store_payload.inline_batches().num_txns(), + opt_quorum_store_payload.inline_batches().num_bytes(), + ), + _ => (0, 0, 0), + }, + } + } + + /// Returns the number of opt batches, the number of txns in the opt batches, and the bytes of txns in the opt batches + pub fn opt_batch_stats(&self) -> (usize, usize, usize) { + match self.block_data.payload() { + None => (0, 0, 0), + Some(payload) => match payload { + Payload::OptQuorumStore(opt_quorum_store_payload) => ( + opt_quorum_store_payload.opt_batches().len(), + opt_quorum_store_payload + .opt_batches() + .iter() + .map(|b| b.num_txns() as usize) + .sum(), + opt_quorum_store_payload + .opt_batches() + .iter() + .map(|b| b.num_bytes() as usize) + .sum(), + ), + _ => (0, 0, 0), + }, + } + } + pub fn quorum_cert(&self) -> &QuorumCert { self.block_data.quorum_cert() } @@ -169,6 +247,10 @@ impl Block { self.block_data.is_nil_block() } + pub fn is_opt_block(&self) -> bool { + self.block_data.is_opt_block() + } + #[cfg(any(test, feature = "fuzzing"))] pub fn make_genesis_block() -> Self { Self::make_genesis_block_from_ledger_info(&LedgerInfo::mock_genesis(None)) @@ -313,6 +395,15 @@ impl Block { } } + pub fn new_from_opt(opt_block_data: OptBlockData, quorum_cert: QuorumCert) -> Self { + let block_data = BlockData::new_from_opt(opt_block_data, quorum_cert); + Block { + id: block_data.hash(), + block_data, + signature: None, + } + } + pub fn validator_txns(&self) -> Option<&Vec> { self.block_data.validator_txns() } @@ -328,16 +419,33 @@ impl Block { .signature .as_ref() .ok_or_else(|| format_err!("Missing signature in Proposal"))?; - validator.verify(*author, &self.block_data, signature)?; - self.quorum_cert().verify(validator) + let (res1, res2) = rayon::join( + || validator.verify(*author, &self.block_data, signature), + || self.quorum_cert().verify(validator), + ); + res1?; + res2 }, BlockType::ProposalExt(proposal_ext) => { let signature = self .signature .as_ref() .ok_or_else(|| format_err!("Missing signature in Proposal"))?; - validator.verify(*proposal_ext.author(), &self.block_data, signature)?; - self.quorum_cert().verify(validator) + let (res1, res2) = rayon::join( + || validator.verify(*proposal_ext.author(), &self.block_data, signature), + || self.quorum_cert().verify(validator), + ); + res1?; + res2 + }, + BlockType::OptimisticProposal(p) => { + // Note: Optimistic proposal is not signed by proposer unlike normal proposal + let (res1, res2) = rayon::join( + || p.grandparent_qc().verify(validator), + || self.quorum_cert().verify(validator), + ); + res1?; + res2 }, BlockType::DAGBlock { .. } => bail!("We should not accept DAG block from others"), } @@ -362,7 +470,7 @@ impl Block { ); if parent.has_reconfiguration() { ensure!( - self.payload().map_or(true, |p| p.is_empty()), + self.payload().is_none_or(|p| p.is_empty()), "Reconfiguration suffix should not carry payload" ); } @@ -450,11 +558,15 @@ impl Block { .collect() } + /// Returns the voters, as BitVec, of the parent block for a normal proposal or + /// the grandparent block for an optimistic proposal. fn previous_bitvec(&self) -> BitVec { - if let BlockType::DAGBlock { parents_bitvec, .. } = self.block_data.block_type() { - parents_bitvec.clone() - } else { - self.quorum_cert().ledger_info().get_voters_bitvec().clone() + match self.block_data.block_type() { + BlockType::DAGBlock { parents_bitvec, .. } => parents_bitvec.clone(), + BlockType::OptimisticProposal(p) => { + p.grandparent_qc().ledger_info().get_voters_bitvec().clone() + }, + _ => self.quorum_cert().ledger_info().get_voters_bitvec().clone(), } } diff --git a/consensus/consensus-types/src/block_data.rs b/consensus/consensus-types/src/block_data.rs index af846280673..dcda858eb30 100644 --- a/consensus/consensus-types/src/block_data.rs +++ b/consensus/consensus-types/src/block_data.rs @@ -4,13 +4,17 @@ use crate::{ common::{Author, Payload, Round}, - proposal_ext::ProposalExt, + opt_block_data::OptBlockData, + proposal_ext::{OptBlockBody, ProposalExt}, quorum_cert::QuorumCert, vote_data::VoteData, }; use aptos_bitvec::BitVec; -use aptos_crypto::hash::HashValue; -use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use aptos_crypto::{ + hash::{CryptoHash, CryptoHasher}, + HashValue, +}; +use aptos_crypto_derive::CryptoHasher; use aptos_types::{ aggregate_signature::AggregateSignature, block_info::BlockInfo, @@ -49,6 +53,9 @@ pub enum BlockType { /// Proposal with extensions (e.g. system transactions). ProposalExt(ProposalExt), + /// Optimistic proposal. + OptimisticProposal(OptBlockBody), + /// A virtual block that's constructed by nodes from DAG, this is purely a local thing so /// we hide it from serde #[serde(skip_deserializing)] @@ -63,7 +70,7 @@ pub enum BlockType { }, } -#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, CryptoHasher)] /// Block has the core data of a consensus block that should be persistent when necessary. /// Each block must know the id of its parent and keep the QuorurmCertificate to that parent. pub struct BlockData { @@ -96,6 +103,37 @@ pub struct BlockData { block_type: BlockType, } +impl CryptoHash for BlockData { + type Hasher = BlockDataHasher; + + fn hash(&self) -> HashValue { + let mut state = Self::Hasher::default(); + if self.is_opt_block() { + #[derive(Serialize)] + struct OptBlockDataForHash<'a> { + epoch: u64, + round: Round, + timestamp_usecs: u64, + quorum_cert_vote_data: &'a VoteData, + block_type: &'a BlockType, + } + + let opt_block_data_for_hash = OptBlockDataForHash { + epoch: self.epoch, + round: self.round, + timestamp_usecs: self.timestamp_usecs, + quorum_cert_vote_data: self.quorum_cert.vote_data(), + block_type: &self.block_type, + }; + bcs::serialize_into(&mut state, &opt_block_data_for_hash) + .expect("OptBlockDataForHash must be serializable"); + } else { + bcs::serialize_into(&mut state, &self).expect("BlockData must be serializable"); + } + state.finish() + } +} + impl BlockData { pub fn author(&self) -> Option { match &self.block_type { @@ -103,6 +141,7 @@ impl BlockData { Some(*author) }, BlockType::ProposalExt(p) => Some(*p.author()), + BlockType::OptimisticProposal(p) => Some(*p.author()), _ => None, } } @@ -132,13 +171,15 @@ impl BlockData { Some(payload) }, BlockType::ProposalExt(p) => p.payload(), + BlockType::OptimisticProposal(p) => Some(p.payload()), _ => None, } } pub fn validator_txns(&self) -> Option<&Vec> { match &self.block_type { - BlockType::ProposalExt(proposal_ext) => proposal_ext.validator_txns(), + BlockType::ProposalExt(p) => p.validator_txns(), + BlockType::OptimisticProposal(p) => p.validator_txns(), BlockType::Proposal { .. } | BlockType::NilBlock { .. } | BlockType::Genesis => None, BlockType::DAGBlock { validator_txns, .. } => Some(validator_txns), } @@ -176,6 +217,10 @@ impl BlockData { matches!(self.block_type, BlockType::NilBlock { .. }) } + pub fn is_opt_block(&self) -> bool { + matches!(self.block_type, BlockType::OptimisticProposal { .. }) + } + /// the list of consecutive proposers from the immediately preceeding /// rounds that didn't produce a successful block pub fn failed_authors(&self) -> Option<&Vec<(Round, Author)>> { @@ -184,7 +229,7 @@ impl BlockData { | BlockType::NilBlock { failed_authors, .. } | BlockType::DAGBlock { failed_authors, .. } => Some(failed_authors), BlockType::ProposalExt(p) => Some(p.failed_authors()), - BlockType::Genesis => None, + BlockType::OptimisticProposal(_) | BlockType::Genesis => None, } } @@ -384,6 +429,25 @@ impl BlockData { } } + /// Returns an instance of BlockData by converting the OptBlockData to BlockData + /// and adding QC and failed_authors + pub fn new_from_opt(opt_block_data: OptBlockData, quorum_cert: QuorumCert) -> Self { + let OptBlockData { + epoch, + round, + timestamp_usecs, + block_body: proposal_body, + .. + } = opt_block_data; + Self { + epoch, + round, + timestamp_usecs, + quorum_cert, + block_type: BlockType::OptimisticProposal(proposal_body), + } + } + /// It's a reconfiguration suffix block if the parent block's executed state indicates next epoch. pub fn is_reconfiguration_suffix(&self) -> bool { self.quorum_cert.certified_block().has_reconfiguration() diff --git a/consensus/consensus-types/src/block_test.rs b/consensus/consensus-types/src/block_test.rs index fa952f02078..04bcd9f6c90 100644 --- a/consensus/consensus-types/src/block_test.rs +++ b/consensus/consensus-types/src/block_test.rs @@ -57,7 +57,7 @@ fn test_nil_block() { let signer = ValidatorSigner::random(None); let parent_block_info = nil_block.quorum_cert().certified_block(); let nil_block_qc = gen_test_certificate( - &[signer.clone()], + std::slice::from_ref(&signer), nil_block.gen_block_info( parent_block_info.executed_state_id(), parent_block_info.version(), diff --git a/consensus/consensus-types/src/common.rs b/consensus/consensus-types/src/common.rs index 888d4e5f799..0597d0cb3a7 100644 --- a/consensus/consensus-types/src/common.rs +++ b/consensus/consensus-types/src/common.rs @@ -160,11 +160,11 @@ impl BatchSizeLimits { #[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct ProofWithData { - pub proofs: Vec, + pub proofs: Vec>, } impl ProofWithData { - pub fn new(proofs: Vec) -> Self { + pub fn new(proofs: Vec>) -> Self { Self { proofs } } @@ -176,7 +176,11 @@ impl ProofWithData { self.proofs.extend(other.proofs); } - pub fn len(&self) -> usize { + pub fn num_proofs(&self) -> usize { + self.proofs.len() + } + + pub fn num_txns(&self) -> usize { self.proofs .iter() .map(|proof| proof.num_txns() as usize) @@ -313,15 +317,15 @@ impl Payload { pub fn len(&self) -> usize { match self { Payload::DirectMempool(txns) => txns.len(), - Payload::InQuorumStore(proof_with_status) => proof_with_status.len(), + Payload::InQuorumStore(proof_with_status) => proof_with_status.num_txns(), Payload::InQuorumStoreWithLimit(proof_with_status) => { // here we return the actual length of the payload; limit is considered at the stage // where we prepare the block from the payload - proof_with_status.proof_with_data.len() + proof_with_status.proof_with_data.num_txns() }, Payload::QuorumStoreInlineHybrid(inline_batches, proof_with_data, _) | Payload::QuorumStoreInlineHybridV2(inline_batches, proof_with_data, _) => { - proof_with_data.len() + proof_with_data.num_txns() + inline_batches .iter() .map(|(_, txns)| txns.len()) @@ -334,18 +338,18 @@ impl Payload { pub fn len_for_execution(&self) -> u64 { match self { Payload::DirectMempool(txns) => txns.len() as u64, - Payload::InQuorumStore(proof_with_status) => proof_with_status.len() as u64, + Payload::InQuorumStore(proof_with_status) => proof_with_status.num_txns() as u64, Payload::InQuorumStoreWithLimit(proof_with_status) => { // here we return the actual length of the payload; limit is considered at the stage // where we prepare the block from the payload - (proof_with_status.proof_with_data.len() as u64) + (proof_with_status.proof_with_data.num_txns() as u64) .min(proof_with_status.max_txns_to_execute.unwrap_or(u64::MAX)) }, Payload::QuorumStoreInlineHybrid( inline_batches, proof_with_data, max_txns_to_execute, - ) => ((proof_with_data.len() + ) => ((proof_with_data.num_txns() + inline_batches .iter() .map(|(_, txns)| txns.len()) @@ -360,7 +364,7 @@ impl Payload { inline_batches, proof_with_data, execution_limit, - ) => ((proof_with_data.len() + ) => ((proof_with_data.num_txns() + inline_batches .iter() .map(|(_, txns)| txns.len()) @@ -545,16 +549,16 @@ impl Payload { } fn verify_with_cache( - proofs: &[ProofOfStore], + proofs: &[ProofOfStore], validator: &ValidatorVerifier, - proof_cache: &ProofCache, + proof_cache: &ProofCache, ) -> anyhow::Result<()> { let unverified: Vec<_> = proofs .iter() .filter(|proof| { - proof_cache.get(proof.info()).map_or(true, |cached_proof| { - cached_proof != *proof.multi_signature() - }) + proof_cache + .get(proof.info()) + .is_none_or(|cached_proof| cached_proof != *proof.multi_signature()) }) .collect(); unverified @@ -604,7 +608,7 @@ impl Payload { pub fn verify( &self, verifier: &ValidatorVerifier, - proof_cache: &ProofCache, + proof_cache: &ProofCache, quorum_store_enabled: bool, size_limits: BatchSizeLimits, ) -> anyhow::Result<()> { @@ -893,9 +897,9 @@ impl fmt::Display for PayloadFilter { #[cfg(test)] mod tests { use super::*; - use crate::proof_of_store::{BatchId, BatchInfo}; + use crate::proof_of_store::BatchInfo; use aptos_crypto::HashValue; - use aptos_types::PeerId; + use aptos_types::{quorum_store::BatchId, PeerId}; fn make_batch(num_txns: u64, num_bytes: u64) -> BatchInfo { BatchInfo::new( diff --git a/consensus/consensus-types/src/lib.rs b/consensus/consensus-types/src/lib.rs index 27ca8b6f928..216fa059c49 100644 --- a/consensus/consensus-types/src/lib.rs +++ b/consensus/consensus-types/src/lib.rs @@ -9,13 +9,14 @@ pub mod block_data; pub mod block_retrieval; pub mod common; pub mod epoch_retrieval; +pub mod opt_block_data; +pub mod opt_proposal_msg; pub mod order_vote; pub mod order_vote_msg; pub mod order_vote_proposal; pub mod payload; pub mod payload_pull_params; pub mod pipeline; -pub mod pipeline_execution_result; pub mod pipelined_block; pub mod proof_of_store; pub mod proposal_ext; diff --git a/consensus/consensus-types/src/opt_block_data.rs b/consensus/consensus-types/src/opt_block_data.rs new file mode 100644 index 00000000000..99e48bfd245 --- /dev/null +++ b/consensus/consensus-types/src/opt_block_data.rs @@ -0,0 +1,140 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + common::{Author, Payload, Round}, + proposal_ext::OptBlockBody, + quorum_cert::QuorumCert, +}; +use anyhow::ensure; +use aptos_crypto::HashValue; +use aptos_crypto_derive::CryptoHasher; +use aptos_infallible::duration_since_epoch; +use aptos_types::{block_info::BlockInfo, validator_txn::ValidatorTransaction}; +use serde::{Deserialize, Serialize}; +use std::{ + fmt::{Display, Formatter}, + ops::Deref, +}; + +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, CryptoHasher)] +/// Same as BlockData, without QC and with parent id +pub struct OptBlockData { + pub epoch: u64, + pub round: Round, + pub timestamp_usecs: u64, + pub parent: BlockInfo, + pub block_body: OptBlockBody, +} + +impl OptBlockData { + pub fn new( + validator_txns: Vec, + payload: Payload, + author: Author, + epoch: u64, + round: Round, + timestamp_usecs: u64, + parent: BlockInfo, + grandparent_qc: QuorumCert, + ) -> Self { + Self { + epoch, + round, + timestamp_usecs, + parent, + block_body: OptBlockBody::V0 { + validator_txns, + payload, + author, + grandparent_qc, + }, + } + } + + pub fn epoch(&self) -> u64 { + self.epoch + } + + pub fn parent_id(&self) -> HashValue { + self.parent.id() + } + + pub fn parent(&self) -> &BlockInfo { + &self.parent + } + + pub fn timestamp_usecs(&self) -> u64 { + self.timestamp_usecs + } + + pub fn round(&self) -> Round { + self.round + } + + pub fn verify_well_formed(&self) -> anyhow::Result<()> { + let parent = self.parent(); + let grandparent_qc = self.grandparent_qc().certified_block(); + ensure!( + grandparent_qc.round() + 1 == parent.round(), + "Block's parent's round {} must be one more than grandparent's round {}", + parent.round(), + grandparent_qc.round(), + ); + ensure!( + parent.round() + 1 == self.round(), + "Block's round {} must be one more than parent's round {}", + self.round(), + parent.round(), + ); + ensure!( + grandparent_qc.epoch() == self.epoch() && parent.epoch() == self.epoch(), + "Block's parent and grantparent should be in the same epoch" + ); + ensure!( + !grandparent_qc.has_reconfiguration(), + "Optimistic proposals are disallowed after the reconfiguration block" + ); + + self.payload().verify_epoch(self.epoch())?; + + ensure!( + self.timestamp_usecs() > parent.timestamp_usecs() + && parent.timestamp_usecs() > grandparent_qc.timestamp_usecs(), + "Blocks must have strictly increasing timestamps" + ); + + let current_ts = duration_since_epoch(); + + // we can say that too far is 5 minutes in the future + const TIMEBOUND: u64 = 300_000_000; + ensure!( + self.timestamp_usecs() <= (current_ts.as_micros() as u64).saturating_add(TIMEBOUND), + "Blocks must not be too far in the future" + ); + Ok(()) + } +} + +impl Deref for OptBlockData { + type Target = OptBlockBody; + + fn deref(&self) -> &Self::Target { + &self.block_body + } +} + +impl Display for OptBlockData { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + write!( + f, + "[author: {}, epoch: {}, round: {:02}, parent_id: {}, timestamp: {}]", + self.author(), + self.epoch(), + self.round(), + self.parent_id(), + self.timestamp_usecs(), + ) + } +} diff --git a/consensus/consensus-types/src/opt_proposal_msg.rs b/consensus/consensus-types/src/opt_proposal_msg.rs new file mode 100644 index 00000000000..0268ad2d66e --- /dev/null +++ b/consensus/consensus-types/src/opt_proposal_msg.rs @@ -0,0 +1,291 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + common::{Author, BatchSizeLimits}, + opt_block_data::OptBlockData, + proof_of_store::{BatchInfo, ProofCache}, + sync_info::SyncInfo, +}; +use anyhow::{ensure, Context, Result}; +use aptos_types::validator_verifier::ValidatorVerifier; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct OptProposalMsg { + block_data: OptBlockData, + sync_info: SyncInfo, +} + +impl OptProposalMsg { + pub fn new(block_data: OptBlockData, sync_info: SyncInfo) -> Self { + Self { + block_data, + sync_info, + } + } + + pub fn block_data(&self) -> &OptBlockData { + &self.block_data + } + + pub fn take_block_data(self) -> OptBlockData { + self.block_data + } + + pub fn epoch(&self) -> u64 { + self.block_data.epoch() + } + + pub fn round(&self) -> u64 { + self.block_data.round() + } + + pub fn timestamp_usecs(&self) -> u64 { + self.block_data.timestamp_usecs() + } + + pub fn proposer(&self) -> Author { + *self.block_data.author() + } + + pub fn sync_info(&self) -> &SyncInfo { + &self.sync_info + } + + /// Verifies that the ProposalMsg is well-formed. + pub fn verify_well_formed(&self) -> Result<()> { + self.block_data + .verify_well_formed() + .context("Fail to verify OptProposalMsg's data")?; + ensure!( + self.block_data.round() > 1, + "Proposal for {} has round <= 1", + self.block_data, + ); + ensure!( + self.block_data.epoch() == self.sync_info.epoch(), + "ProposalMsg has different epoch number from SyncInfo" + ); + // Ensure the sync info has the grandparent QC + ensure!( + self.block_data.grandparent_qc().certified_block().id() + == self.sync_info.highest_quorum_cert().certified_block().id(), + "Proposal HQC in SyncInfo certifies {}, but block grandparent id is {}", + self.sync_info.highest_quorum_cert().certified_block().id(), + self.block_data.grandparent_qc().certified_block().id(), + ); + let grandparent_round = self + .block_data + .round() + .checked_sub(2) + .ok_or_else(|| anyhow::anyhow!("proposal round overflowed!"))?; + + let highest_certified_round = self.block_data.grandparent_qc().certified_block().round(); + ensure!( + grandparent_round == highest_certified_round, + "Proposal {} does not have a certified round {}", + self.block_data, + grandparent_round + ); + // Optimistic proposal shouldn't have a timeout certificate + ensure!( + self.sync_info.highest_2chain_timeout_cert().is_none(), + "Optimistic proposal shouldn't have a timeout certificate" + ); + Ok(()) + } + + pub fn verify( + &self, + sender: Author, + validator: &ValidatorVerifier, + proof_cache: &ProofCache, + quorum_store_enabled: bool, + size_limits: BatchSizeLimits, + ) -> Result<()> { + ensure!( + self.proposer() == sender, + "OptProposal author {:?} doesn't match sender {:?}", + self.proposer(), + sender + ); + + let (payload_verify_result, qc_verify_result) = rayon::join( + || { + self.block_data() + .payload() + .verify(validator, proof_cache, quorum_store_enabled, size_limits) + }, + || self.block_data().grandparent_qc().verify(validator), + ); + payload_verify_result?; + qc_verify_result?; + + // Note that we postpone the verification of SyncInfo until it's being used. + self.verify_well_formed() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + block::block_test_utils::{certificate_for_genesis, gen_test_certificate}, + common::{Payload, Round}, + }; + use aptos_crypto::HashValue; + use aptos_types::{ + block_info::BlockInfo, validator_signer::ValidatorSigner, + validator_verifier::random_validator_verifier, + }; + + // Helper to create a OptProposalMsg for testing + fn create_opt_proposal_msg( + round: Round, + epoch: u64, + signer: &ValidatorSigner, + ) -> OptProposalMsg { + let grandparent_round = round.saturating_sub(2); + let grandparent_block = BlockInfo::new( + epoch, + grandparent_round, + HashValue::zero(), + HashValue::zero(), + 0, + grandparent_round * 1000, + None, + ); + + // Create a parent block info for the QC (the block before grandparent) + let parent_of_grandparent = BlockInfo::new( + epoch, + grandparent_round.saturating_sub(1), + HashValue::zero(), + HashValue::zero(), + 0, + grandparent_round.saturating_sub(1) * 1000, + None, + ); + + let parent_round = round.saturating_sub(1); + // Parent block's id should be the grandparent block's id + let parent_block = BlockInfo::new( + epoch, + parent_round, + grandparent_block.id(), // Parent points to grandparent + HashValue::zero(), + 0, + parent_round * 1000, + None, + ); + + let grandparent_qc = gen_test_certificate( + std::slice::from_ref(signer), + grandparent_block.clone(), + parent_of_grandparent, // Use proper parent instead of BlockInfo::empty() + None, + ); + + let opt_block_data = OptBlockData::new( + vec![], + Payload::empty(false, true), + signer.author(), + epoch, + round, + round * 1000, + parent_block, + grandparent_qc.clone(), + ); + + let sync_info = SyncInfo::new( + grandparent_qc.clone(), + grandparent_qc.into_wrapped_ledger_info(), + None, + ); + + OptProposalMsg::new(opt_block_data, sync_info) + } + + // ========== verify() Tests ========== + + #[test] + fn test_verify_success() { + let (signers, validators) = random_validator_verifier(1, None, false); + let signer = signers.first().unwrap(); + let msg = create_opt_proposal_msg(3, 1, signer); + let proof_cache = ProofCache::new(1024); + assert!(msg + .verify(signer.author(), &validators, &proof_cache, false, BatchSizeLimits::new(100, 1000)) + .is_ok()); + } + + #[test] + fn test_verify_failures() { + let (signers, validators) = random_validator_verifier(1, None, false); + let signer = signers.first().unwrap(); + let proof_cache = ProofCache::new(1024); + + // Test round too low + let msg_round_1 = create_opt_proposal_msg(1, 1, signer); + assert!(msg_round_1 + .verify(signer.author(), &validators, &proof_cache, false, BatchSizeLimits::new(100, 1000)) + .is_err()); + + // Test epoch mismatch + let msg = create_opt_proposal_msg(3, 1, signer); + let genesis_qc = certificate_for_genesis(); + let sync_info = SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ); + let block_data = msg.take_block_data(); + let epoch_2_block_data = OptBlockData::new( + vec![], + Payload::empty(false, true), + signer.author(), + 2, // Different epoch + block_data.round(), + block_data.timestamp_usecs(), + block_data.parent().clone(), + block_data.grandparent_qc().clone(), + ); + let msg_epoch_mismatch = OptProposalMsg::new(epoch_2_block_data, sync_info); + assert!(msg_epoch_mismatch + .verify(signer.author(), &validators, &proof_cache, false, BatchSizeLimits::new(100, 1000)) + .is_err()); + + // Test with timeout cert + let msg = create_opt_proposal_msg(3, 1, signer); + let block_data = msg.take_block_data(); + let grandparent_qc = block_data.grandparent_qc().clone(); + use crate::timeout_2chain::{TwoChainTimeout, TwoChainTimeoutCertificate}; + let timeout = TwoChainTimeout::new(1, 2, grandparent_qc.clone()); + let timeout_cert = TwoChainTimeoutCertificate::new(timeout); + let sync_info = SyncInfo::new( + grandparent_qc.clone(), + grandparent_qc.into_wrapped_ledger_info(), + Some(timeout_cert), + ); + let msg_with_tc = OptProposalMsg::new(block_data, sync_info); + assert!(msg_with_tc + .verify(signer.author(), &validators, &proof_cache, false, BatchSizeLimits::new(100, 1000)) + .is_err()); + } + + #[test] + fn test_verify_sender_mismatch() { + let (signers, validators) = random_validator_verifier(2, None, false); + let signer1 = &signers[0]; + let signer2 = &signers[1]; + + let msg = create_opt_proposal_msg(3, 1, signer1); + let proof_cache = ProofCache::new(1024); + + assert!(msg + .verify(signer2.author(), &validators, &proof_cache, false, BatchSizeLimits::new(100, 1000)) + .is_err()); + } +} diff --git a/consensus/consensus-types/src/payload.rs b/consensus/consensus-types/src/payload.rs index 1c3ae2f4f14..7c5c941da78 100644 --- a/consensus/consensus-types/src/payload.rs +++ b/consensus/consensus-types/src/payload.rs @@ -13,7 +13,7 @@ use std::{ pub type OptBatches = BatchPointer; -pub type ProofBatches = BatchPointer; +pub type ProofBatches = BatchPointer>; pub trait TDataInfo { fn num_txns(&self) -> u64; @@ -44,6 +44,10 @@ where self.batch_summary.extend(other.batch_summary); } + pub fn num_proofs(&self) -> usize { + self.batch_summary.len() + } + pub fn num_txns(&self) -> usize { self.batch_summary .iter() @@ -210,14 +214,18 @@ impl InlineBatch { pub struct InlineBatches(Vec); impl InlineBatches { - fn num_txns(&self) -> usize { + pub fn num_batches(&self) -> usize { + self.0.len() + } + + pub fn num_txns(&self) -> usize { self.0 .iter() .map(|batch| batch.batch_info.num_txns() as usize) .sum() } - fn num_bytes(&self) -> usize { + pub fn num_bytes(&self) -> usize { self.0 .iter() .map(|batch| batch.batch_info.num_bytes() as usize) @@ -302,6 +310,10 @@ impl OptQuorumStorePayloadV1 { self.execution_limits.max_txns_to_execute() } + pub fn block_gas_limit(&self) -> Option { + self.execution_limits.block_gas_limit() + } + pub fn check_epoch(&self, epoch: u64) -> anyhow::Result<()> { ensure!( self.inline_batches @@ -374,7 +386,7 @@ impl OptQuorumStorePayload { &self.inline_batches } - pub fn proof_with_data(&self) -> &BatchPointer { + pub fn proof_with_data(&self) -> &BatchPointer> { &self.proofs } diff --git a/consensus/consensus-types/src/pipeline_execution_result.rs b/consensus/consensus-types/src/pipeline_execution_result.rs deleted file mode 100644 index 813a105c097..00000000000 --- a/consensus/consensus-types/src/pipeline_execution_result.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_executor_types::{state_compute_result::StateComputeResult, ExecutorResult}; -use aptos_types::transaction::SignedTransaction; -use derivative::Derivative; -use futures::future::BoxFuture; -use std::time::Duration; - -#[derive(Derivative)] -#[derivative(Debug)] -pub struct PipelineExecutionResult { - pub input_txns: Vec, - pub result: StateComputeResult, - pub execution_time: Duration, - #[derivative(Debug = "ignore")] - pub pre_commit_fut: BoxFuture<'static, ExecutorResult<()>>, -} - -impl PipelineExecutionResult { - pub fn new( - input_txns: Vec, - result: StateComputeResult, - execution_time: Duration, - pre_commit_fut: BoxFuture<'static, ExecutorResult<()>>, - ) -> Self { - Self { - input_txns, - result, - execution_time, - pre_commit_fut, - } - } -} diff --git a/consensus/consensus-types/src/pipelined_block.rs b/consensus/consensus-types/src/pipelined_block.rs index ebcdaac4feb..5d49e7a49b2 100644 --- a/consensus/consensus-types/src/pipelined_block.rs +++ b/consensus/consensus-types/src/pipelined_block.rs @@ -7,7 +7,6 @@ use crate::{ common::{Payload, Round}, order_vote_proposal::OrderVoteProposal, pipeline::commit_vote::CommitVote, - pipeline_execution_result::PipelineExecutionResult, quorum_cert::QuorumCert, vote_proposal::VoteProposal, wrapped_ledger_info::WrappedLedgerInfo, @@ -70,6 +69,9 @@ pub type TaskResult = Result; pub type TaskFuture = Shared>>; pub type PrepareResult = (Arc>, Option); +// First Option is whether randomness is enabled +// Second Option is whether randomness is skipped +pub type RandResult = (Option>, bool); pub type ExecuteResult = Duration; pub type LedgerUpdateResult = (StateComputeResult, Duration, Option); pub type PostLedgerUpdateResult = (); @@ -82,6 +84,7 @@ pub type PostCommitResult = (); #[derive(Clone)] pub struct PipelineFutures { pub prepare_fut: TaskFuture, + pub rand_check_fut: TaskFuture, pub execute_fut: TaskFuture, pub ledger_update_fut: TaskFuture, pub post_ledger_update_fut: TaskFuture, @@ -200,7 +203,6 @@ pub struct PipelinedBlock { randomness: OnceCell, pipeline_insertion_time: OnceCell, execution_summary: OnceCell, - pre_commit_fut: Mutex>>>, /// pipeline related fields pipeline_futs: Mutex>, pipeline_tx: Mutex>, @@ -321,24 +323,6 @@ impl PipelinedBlock { } } - pub fn set_execution_result(&self, pipeline_execution_result: PipelineExecutionResult) { - let PipelineExecutionResult { - input_txns: _, - result, - execution_time, - pre_commit_fut, - } = pipeline_execution_result; - - *self.pre_commit_fut.lock() = Some(pre_commit_fut); - - self.set_compute_result(result, execution_time); - } - - #[cfg(any(test, feature = "fuzzing"))] - pub fn mark_successful_pre_commit_for_test(&self) { - *self.pre_commit_fut.lock() = Some(Box::pin(async { Ok(()) })); - } - // GUARD: keep this function a pure write to `self.randomness`. // `ShareAggregator` runs synchronously in `consensus/src/rand/rand_gen/rand_store.rs` // and its result reaches `set_randomness` through a channel, with no @@ -349,7 +333,7 @@ impl PipelinedBlock { // https://github.com/aptos-labs/aptos-core/pull/18699 (upstream optimization that introduced the cycle) // https://github.com/aptos-labs/aptos-core/pull/19359 (corrective patch) // https://github.com/aptos-labs/aptos-core/commit/fefcfade3edf26f0396d63963f7ea04364f3666f - // https://github.com/movementlabsxyz/aptos-core/pull/322 (full analysis with diagrams) + // https://github.com/movement-network/aptos-core/pull/322 (full analysis with diagrams) // // If a similar change is ever introduced here — anything that makes // rand aggregation wait on a pipeline-derived future — this function @@ -363,13 +347,6 @@ impl PipelinedBlock { assert!(self.pipeline_insertion_time.set(Instant::now()).is_ok()); } - pub fn take_pre_commit_fut(&self) -> BoxFuture<'static, ExecutorResult<()>> { - self.pre_commit_fut - .lock() - .take() - .expect("pre_commit_result_rx missing.") - } - pub fn set_qc(&self, qc: Arc) { *self.block_qc.lock() = Some(qc.clone()); if let Some(tx) = self.pipeline_tx().lock().as_mut() { @@ -411,7 +388,6 @@ impl PipelinedBlock { randomness: OnceCell::new(), pipeline_insertion_time: OnceCell::new(), execution_summary: OnceCell::new(), - pre_commit_fut: Mutex::new(None), pipeline_futs: Mutex::new(None), pipeline_tx: Mutex::new(None), pipeline_abort_handle: Mutex::new(None), @@ -539,12 +515,6 @@ impl PipelinedBlock { /// Pipeline related functions impl PipelinedBlock { - pub fn pipeline_enabled(&self) -> bool { - // if the pipeline_tx is set, the pipeline is enabled, - // we don't use pipeline fut here because it can't be taken when abort - self.pipeline_tx.lock().is_some() - } - pub fn pipeline_futs(&self) -> Option { self.pipeline_futs.lock().clone() } diff --git a/consensus/consensus-types/src/proof_of_store.rs b/consensus/consensus-types/src/proof_of_store.rs index e8952446950..ccedaa9a8d9 100644 --- a/consensus/consensus-types/src/proof_of_store.rs +++ b/consensus/consensus-types/src/proof_of_store.rs @@ -3,67 +3,32 @@ use crate::{payload::TDataInfo, utils::PayloadTxnsSize}; use anyhow::{bail, ensure, Context}; -use aptos_crypto::{bls12381, CryptoMaterialError, HashValue}; +use aptos_crypto::{bls12381, hash::CryptoHash, CryptoMaterialError, HashValue}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use aptos_types::{ aggregate_signature::AggregateSignature, ledger_info::SignatureWithStatus, - validator_signer::ValidatorSigner, validator_verifier::ValidatorVerifier, PeerId, + quorum_store::BatchId, validator_signer::ValidatorSigner, + validator_verifier::ValidatorVerifier, PeerId, }; use mini_moka::sync::Cache; use rand::{seq::SliceRandom, thread_rng}; use serde::{Deserialize, Serialize}; use std::{ - cmp::Ordering, - fmt::{Display, Formatter}, + fmt::{Debug, Display, Formatter}, hash::Hash, ops::Deref, }; -#[derive( - Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash, CryptoHasher, BCSCryptoHash, -)] -pub struct BatchId { - pub id: u64, - /// A number that is stored in the DB and updated only if the value does not exist in - /// the DB: (a) at the start of an epoch, or (b) the DB was wiped. When the nonce is updated, - /// id starts again at 0. Using the current system time allows the nonce to be ordering. - pub nonce: u64, -} - -impl BatchId { - pub fn new(nonce: u64) -> Self { - Self { id: 0, nonce } - } +pub trait TBatchInfo: Serialize + CryptoHash + Debug + Clone + Hash + Eq { + fn epoch(&self) -> u64; - pub fn new_for_test(id: u64) -> Self { - Self { id, nonce: 0 } - } + fn expiration(&self) -> u64; - pub fn increment(&mut self) { - self.id += 1; - } -} - -impl PartialOrd for BatchId { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} + fn num_txns(&self) -> u64; -impl Ord for BatchId { - fn cmp(&self, other: &Self) -> Ordering { - match self.nonce.cmp(&other.nonce) { - Ordering::Equal => {}, - ordering => return ordering, - } - self.id.cmp(&other.id) - } -} + fn num_bytes(&self) -> u64; -impl Display for BatchId { - fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!(f, "({}, {})", self.id, self.nonce) - } + fn as_batch_info(&self) -> &BatchInfo; } #[derive( @@ -140,6 +105,28 @@ impl BatchInfo { } } +impl TBatchInfo for BatchInfo { + fn epoch(&self) -> u64 { + self.epoch + } + + fn expiration(&self) -> u64 { + self.expiration + } + + fn num_txns(&self) -> u64 { + self.num_txns + } + + fn num_bytes(&self) -> u64 { + self.num_bytes + } + + fn as_batch_info(&self) -> &BatchInfo { + self + } +} + impl Display for BatchInfo { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { write!(f, "({}:{}:{})", self.author, self.batch_id, self.digest) @@ -165,12 +152,15 @@ impl TDataInfo for BatchInfo { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct SignedBatchInfoMsg { - signed_infos: Vec, +pub struct SignedBatchInfoMsg { + signed_infos: Vec>, } -impl SignedBatchInfoMsg { - pub fn new(signed_infos: Vec) -> Self { +impl SignedBatchInfoMsg +where + T: TBatchInfo, +{ + pub fn new(signed_infos: Vec>) -> Self { Self { signed_infos } } @@ -208,21 +198,24 @@ impl SignedBatchInfoMsg { Ok(epoch) } - pub fn take(self) -> Vec { + pub fn take(self) -> Vec> { self.signed_infos } } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct SignedBatchInfo { - info: BatchInfo, +pub struct SignedBatchInfo { + info: T, signer: PeerId, signature: SignatureWithStatus, } -impl SignedBatchInfo { +impl SignedBatchInfo +where + T: TBatchInfo, +{ pub fn new( - batch_info: BatchInfo, + batch_info: T, validator_signer: &ValidatorSigner, ) -> Result { let signature = validator_signer.sign(&batch_info)?; @@ -235,7 +228,7 @@ impl SignedBatchInfo { } pub fn new_with_signature( - batch_info: BatchInfo, + batch_info: T, signer: PeerId, signature: bls12381::Signature, ) -> Self { @@ -247,7 +240,7 @@ impl SignedBatchInfo { } #[cfg(any(test, feature = "fuzzing"))] - pub fn dummy(batch_info: BatchInfo, signer: PeerId) -> Self { + pub fn dummy(batch_info: T, signer: PeerId) -> Self { Self::new_with_signature(batch_info, signer, bls12381::Signature::dummy_signature()) } @@ -288,13 +281,13 @@ impl SignedBatchInfo { &self.signature } - pub fn batch_info(&self) -> &BatchInfo { + pub fn batch_info(&self) -> &T { &self.info } } -impl Deref for SignedBatchInfo { - type Target = BatchInfo; +impl Deref for SignedBatchInfo { + type Target = T; fn deref(&self) -> &Self::Target { &self.info @@ -314,12 +307,15 @@ pub enum SignedBatchInfoError { } #[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] -pub struct ProofOfStoreMsg { - proofs: Vec, +pub struct ProofOfStoreMsg { + proofs: Vec>, } -impl ProofOfStoreMsg { - pub fn new(proofs: Vec) -> Self { +impl ProofOfStoreMsg +where + T: TBatchInfo + Send + Sync + 'static, +{ + pub fn new(proofs: Vec>) -> Self { Self { proofs } } @@ -327,7 +323,7 @@ impl ProofOfStoreMsg { &self, max_num_proofs: usize, validator: &ValidatorVerifier, - cache: &ProofCache, + cache: &ProofCache, ) -> anyhow::Result<()> { ensure!(!self.proofs.is_empty(), "Empty message"); ensure!( @@ -356,28 +352,35 @@ impl ProofOfStoreMsg { Ok(epoch) } - pub fn take(self) -> Vec { + pub fn take(self) -> Vec> { self.proofs } } -pub type ProofCache = Cache; +pub type ProofCache = Cache; #[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] -pub struct ProofOfStore { - info: BatchInfo, +pub struct ProofOfStore { + info: T, multi_signature: AggregateSignature, } -impl ProofOfStore { - pub fn new(info: BatchInfo, multi_signature: AggregateSignature) -> Self { +impl ProofOfStore +where + T: TBatchInfo + Send + Sync + 'static, +{ + pub fn new(info: T, multi_signature: AggregateSignature) -> Self { Self { info, multi_signature, } } - pub fn verify(&self, validator: &ValidatorVerifier, cache: &ProofCache) -> anyhow::Result<()> { + pub fn verify( + &self, + validator: &ValidatorVerifier, + cache: &ProofCache, + ) -> anyhow::Result<()> { if let Some(signature) = cache.get(&self.info) { if signature == self.multi_signature { return Ok(()); @@ -401,7 +404,7 @@ impl ProofOfStore { ret } - pub fn info(&self) -> &BatchInfo { + pub fn info(&self) -> &T { &self.info } @@ -410,25 +413,28 @@ impl ProofOfStore { } } -impl Deref for ProofOfStore { - type Target = BatchInfo; +impl Deref for ProofOfStore { + type Target = T; fn deref(&self) -> &Self::Target { &self.info } } -impl TDataInfo for ProofOfStore { +impl TDataInfo for ProofOfStore +where + T: TBatchInfo + Send + Sync + 'static, +{ fn num_txns(&self) -> u64 { - self.num_txns + self.info.num_txns() } fn num_bytes(&self) -> u64 { - self.num_bytes + self.info.num_bytes() } fn info(&self) -> &BatchInfo { - self.info() + self.info.as_batch_info() } fn signers(&self, ordered_authors: &[PeerId]) -> Vec { diff --git a/consensus/consensus-types/src/proposal_ext.rs b/consensus/consensus-types/src/proposal_ext.rs index a61aa94010c..e7dbbaa7c3f 100644 --- a/consensus/consensus-types/src/proposal_ext.rs +++ b/consensus/consensus-types/src/proposal_ext.rs @@ -1,10 +1,52 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::common::{Author, Payload, Round}; +use crate::{ + common::{Author, Payload, Round}, + quorum_cert::QuorumCert, +}; use aptos_types::validator_txn::ValidatorTransaction; use serde::{Deserialize, Serialize}; +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] +pub enum OptBlockBody { + V0 { + validator_txns: Vec, + // T of the block (e.g. one or more transaction(s) + payload: Payload, + // Author of the block that can be validated by the author's public key and the signature + author: Author, + // QC of the grandparent block + grandparent_qc: QuorumCert, + }, +} + +impl OptBlockBody { + pub fn author(&self) -> &Author { + match self { + OptBlockBody::V0 { author, .. } => author, + } + } + + pub fn validator_txns(&self) -> Option<&Vec> { + match self { + OptBlockBody::V0 { validator_txns, .. } => Some(validator_txns), + } + } + + pub fn payload(&self) -> &Payload { + match self { + OptBlockBody::V0 { payload, .. } => payload, + } + } + + pub fn grandparent_qc(&self) -> &QuorumCert { + match self { + OptBlockBody::V0 { grandparent_qc, .. } => grandparent_qc, + } + } +} + #[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub enum ProposalExt { V0 { diff --git a/consensus/consensus-types/src/proposal_msg.rs b/consensus/consensus-types/src/proposal_msg.rs index 0fe3b94fa98..08e6cc9761b 100644 --- a/consensus/consensus-types/src/proposal_msg.rs +++ b/consensus/consensus-types/src/proposal_msg.rs @@ -2,7 +2,12 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{block::Block, common::{Author, BatchSizeLimits}, proof_of_store::ProofCache, sync_info::SyncInfo}; +use crate::{ + block::Block, + common::{Author, BatchSizeLimits}, + proof_of_store::{BatchInfo, ProofCache}, + sync_info::SyncInfo, +}; use anyhow::{anyhow, ensure, format_err, Context, Result}; use aptos_short_hex_str::AsShortHexStr; use aptos_types::validator_verifier::ValidatorVerifier; @@ -84,7 +89,7 @@ impl ProposalMsg { &self, sender: Author, validator: &ValidatorVerifier, - proof_cache: &ProofCache, + proof_cache: &ProofCache, quorum_store_enabled: bool, size_limits: BatchSizeLimits, ) -> Result<()> { @@ -96,18 +101,21 @@ impl ProposalMsg { sender ); } - self.proposal().payload().map_or(Ok(()), |p| { - p.verify( - validator, - proof_cache, - quorum_store_enabled, - size_limits, - ) - })?; + let (payload_result, sig_result) = rayon::join( + || { + self.proposal().payload().map_or(Ok(()), |p| { + p.verify(validator, proof_cache, quorum_store_enabled, size_limits) + }) + }, + || { + self.proposal() + .validate_signature(validator) + .map_err(|e| format_err!("{:?}", e)) + }, + ); + payload_result?; + sig_result?; - self.proposal() - .validate_signature(validator) - .map_err(|e| format_err!("{:?}", e))?; // if there is a timeout certificate, verify its signatures if let Some(tc) = self.sync_info.highest_2chain_timeout_cert() { tc.verify(validator).map_err(|e| format_err!("{:?}", e))?; diff --git a/consensus/consensus-types/src/timeout_2chain.rs b/consensus/consensus-types/src/timeout_2chain.rs index 2e9315416d9..471516862b7 100644 --- a/consensus/consensus-types/src/timeout_2chain.rs +++ b/consensus/consensus-types/src/timeout_2chain.rs @@ -140,28 +140,34 @@ impl TwoChainTimeoutCertificate { /// 2. all signatures are properly formed (timeout.epoch, timeout.round, round) /// 3. timeout.hqc_round == max(signed round) pub fn verify(&self, validators: &ValidatorVerifier) -> anyhow::Result<()> { - // Verify the highest timeout validity. - self.timeout.verify(validators)?; let hqc_round = self.timeout.hqc_round(); - let timeout_messages: Vec<_> = self - .signatures_with_rounds - .get_voters_and_rounds( - &validators - .get_ordered_account_addresses_iter() - .collect_vec(), - ) - .into_iter() - .map(|(_, round)| TimeoutSigningRepr { - epoch: self.timeout.epoch(), - round: self.timeout.round(), - hqc_round: round, - }) - .collect(); - let timeout_messages_ref: Vec<_> = timeout_messages.iter().collect(); - validators.verify_aggregate_signatures( - &timeout_messages_ref, - self.signatures_with_rounds.sig(), - )?; + // Verify the highest timeout validity. + let (timeout_result, sig_result) = rayon::join( + || self.timeout.verify(validators), + || { + let timeout_messages: Vec<_> = self + .signatures_with_rounds + .get_voters_and_rounds( + &validators + .get_ordered_account_addresses_iter() + .collect_vec(), + ) + .into_iter() + .map(|(_, round)| TimeoutSigningRepr { + epoch: self.timeout.epoch(), + round: self.timeout.round(), + hqc_round: round, + }) + .collect(); + let timeout_messages_ref: Vec<_> = timeout_messages.iter().collect(); + validators.verify_aggregate_signatures( + &timeout_messages_ref, + self.signatures_with_rounds.sig(), + ) + }, + ); + timeout_result?; + sig_result?; let signed_hqc = self .signatures_with_rounds .rounds() @@ -230,7 +236,7 @@ impl TwoChainTimeoutWithPartialSignatures { /// Returns the signatures certifying the round pub fn signers(&self) -> impl Iterator { - self.signatures.signatures().iter().map(|(k, _)| k) + self.signatures.signatures().keys() } /// Add a new timeout message from author, the timeout should already be verified in upper layer. diff --git a/consensus/safety-rules/src/remote_service.rs b/consensus/safety-rules/src/remote_service.rs index fc7ec1b944f..4d9cad3e70b 100644 --- a/consensus/safety-rules/src/remote_service.rs +++ b/consensus/safety-rules/src/remote_service.rs @@ -29,7 +29,7 @@ pub trait RemoteService { } pub fn execute(storage: PersistentSafetyStorage, listen_addr: SocketAddr, network_timeout_ms: u64) { - let mut safety_rules = SafetyRules::new(storage); + let mut safety_rules = SafetyRules::new(storage, false); if let Err(e) = safety_rules.consensus_state() { warn!("Unable to print consensus state: {}", e); } diff --git a/consensus/safety-rules/src/safety_rules.rs b/consensus/safety-rules/src/safety_rules.rs index af8e30627b2..0ca5d4c5706 100644 --- a/consensus/safety-rules/src/safety_rules.rs +++ b/consensus/safety-rules/src/safety_rules.rs @@ -43,16 +43,20 @@ pub struct SafetyRules { pub(crate) persistent_storage: PersistentSafetyStorage, pub(crate) validator_signer: Option, pub(crate) epoch_state: Option, + // Skip verification of signatures and well-formed, this can be set if it's used in local mode + // where consensus already verifies. + pub(crate) skip_sig_verify: bool, } impl SafetyRules { /// Constructs a new instance of SafetyRules with the given persistent storage and the /// consensus private keys - pub fn new(persistent_storage: PersistentSafetyStorage) -> Self { + pub fn new(persistent_storage: PersistentSafetyStorage, skip_sig_verify: bool) -> Self { Self { persistent_storage, validator_signer: None, epoch_state: None, + skip_sig_verify, } } @@ -67,9 +71,11 @@ impl SafetyRules { self.verify_epoch(proposed_block.epoch(), &safety_data)?; self.verify_qc(proposed_block.quorum_cert())?; - proposed_block - .validate_signature(&self.epoch_state()?.verifier) - .map_err(|error| Error::InvalidProposal(error.to_string()))?; + if !self.skip_sig_verify { + proposed_block + .validate_signature(&self.epoch_state()?.verifier) + .map_err(|error| Error::InvalidProposal(error.to_string()))?; + } proposed_block .verify_well_formed() .map_err(|error| Error::InvalidProposal(error.to_string()))?; @@ -231,8 +237,10 @@ impl SafetyRules { pub(crate) fn verify_qc(&self, qc: &QuorumCert) -> Result<(), Error> { let epoch_state = self.epoch_state()?; - qc.verify(&epoch_state.verifier) - .map_err(|e| Error::InvalidQuorumCertificate(e.to_string()))?; + if !self.skip_sig_verify { + qc.verify(&epoch_state.verifier) + .map_err(|e| Error::InvalidQuorumCertificate(e.to_string()))?; + } Ok(()) } @@ -398,9 +406,11 @@ impl SafetyRules { } // Verify that ledger_info contains at least 2f + 1 dostinct signatures - ledger_info - .verify_signatures(&self.epoch_state()?.verifier) - .map_err(|error| Error::InvalidQuorumCertificate(error.to_string()))?; + if !self.skip_sig_verify { + ledger_info + .verify_signatures(&self.epoch_state()?.verifier) + .map_err(|error| Error::InvalidQuorumCertificate(error.to_string()))?; + } // TODO: add guarding rules in unhappy path // TODO: add extension check diff --git a/consensus/safety-rules/src/safety_rules_2chain.rs b/consensus/safety-rules/src/safety_rules_2chain.rs index e93d2cd1874..7218165c22e 100644 --- a/consensus/safety-rules/src/safety_rules_2chain.rs +++ b/consensus/safety-rules/src/safety_rules_2chain.rs @@ -25,9 +25,11 @@ impl SafetyRules { self.signer()?; let mut safety_data = self.persistent_storage.safety_data()?; self.verify_epoch(timeout.epoch(), &safety_data)?; - timeout - .verify(&self.epoch_state()?.verifier) - .map_err(|e| Error::InvalidTimeout(e.to_string()))?; + if !self.skip_sig_verify { + timeout + .verify(&self.epoch_state()?.verifier) + .map_err(|e| Error::InvalidTimeout(e.to_string()))?; + } if let Some(tc) = timeout_cert { self.verify_tc(tc)?; } @@ -179,8 +181,10 @@ impl SafetyRules { fn verify_tc(&self, tc: &TwoChainTimeoutCertificate) -> Result<(), Error> { let epoch_state = self.epoch_state()?; - tc.verify(&epoch_state.verifier) - .map_err(|e| Error::InvalidTimeoutCertificate(e.to_string()))?; + if !self.skip_sig_verify { + tc.verify(&epoch_state.verifier) + .map_err(|e| Error::InvalidTimeoutCertificate(e.to_string()))?; + } Ok(()) } diff --git a/consensus/safety-rules/src/safety_rules_manager.rs b/consensus/safety-rules/src/safety_rules_manager.rs index 7d87297789d..9b2eb1c7656 100644 --- a/consensus/safety-rules/src/safety_rules_manager.rs +++ b/consensus/safety-rules/src/safety_rules_manager.rs @@ -130,7 +130,7 @@ impl SafetyRulesManager { } pub fn new_local(storage: PersistentSafetyStorage) -> Self { - let safety_rules = SafetyRules::new(storage); + let safety_rules = SafetyRules::new(storage, true); Self { internal_safety_rules: SafetyRulesWrapper::Local(Arc::new(RwLock::new(safety_rules))), } @@ -144,7 +144,7 @@ impl SafetyRulesManager { } pub fn new_serializer(storage: PersistentSafetyStorage) -> Self { - let safety_rules = SafetyRules::new(storage); + let safety_rules = SafetyRules::new(storage, false); let serializer_service = SerializerService::new(safety_rules); Self { internal_safety_rules: SafetyRulesWrapper::Serializer(Arc::new(RwLock::new( diff --git a/consensus/safety-rules/src/test_utils.rs b/consensus/safety-rules/src/test_utils.rs index ce161c0a5fb..09058801dbd 100644 --- a/consensus/safety-rules/src/test_utils.rs +++ b/consensus/safety-rules/src/test_utils.rs @@ -178,7 +178,9 @@ pub fn make_proposal_with_parent_and_overrides( let qc = QuorumCert::new( vote_data, ledger_info_with_signatures - .aggregate_signatures(&generate_validator_verifier(&[validator_signer.clone()])) + .aggregate_signatures(&generate_validator_verifier(std::slice::from_ref( + validator_signer, + ))) .unwrap(), ); @@ -213,7 +215,7 @@ pub fn make_timeout_cert( let signature = timeout.sign(signer).unwrap(); tc_partial.add(signer.author(), timeout, signature); tc_partial - .aggregate_signatures(&generate_validator_verifier(&[signer.clone()])) + .aggregate_signatures(&generate_validator_verifier(std::slice::from_ref(signer))) .unwrap() } @@ -248,7 +250,7 @@ pub fn test_safety_rules() -> SafetyRules { let storage = test_storage(&signer); let (epoch_change_proof, _) = make_genesis(&signer); - let mut safety_rules = SafetyRules::new(storage); + let mut safety_rules = SafetyRules::new(storage, false); safety_rules.initialize(&epoch_change_proof).unwrap(); safety_rules } @@ -257,7 +259,7 @@ pub fn test_safety_rules() -> SafetyRules { pub fn test_safety_rules_uninitialized() -> SafetyRules { let signer = ValidatorSigner::from_int(0); let storage = test_storage(&signer); - SafetyRules::new(storage) + SafetyRules::new(storage, false) } /// Returns a simple serializer for testing purposes. diff --git a/consensus/safety-rules/src/tests/local.rs b/consensus/safety-rules/src/tests/local.rs index 14fa8784937..f5b7363c88e 100644 --- a/consensus/safety-rules/src/tests/local.rs +++ b/consensus/safety-rules/src/tests/local.rs @@ -7,7 +7,7 @@ use aptos_types::validator_signer::ValidatorSigner; #[test] fn test() { - suite::run_test_suite(&safety_rules()); + suite::run_test_suite_without_sig_check(&safety_rules()); } fn safety_rules() -> suite::Callback { diff --git a/consensus/safety-rules/src/tests/safety_rules.rs b/consensus/safety-rules/src/tests/safety_rules.rs index a392ab0cbe2..bae6ddda69d 100644 --- a/consensus/safety-rules/src/tests/safety_rules.rs +++ b/consensus/safety-rules/src/tests/safety_rules.rs @@ -14,7 +14,7 @@ fn safety_rules() -> suite::Callback { Box::new(move || { let signer = ValidatorSigner::from_int(0); let storage = test_utils::test_storage(&signer); - let safety_rules = Box::new(SafetyRules::new(storage)); + let safety_rules = Box::new(SafetyRules::new(storage, false)); (safety_rules, signer) }) } diff --git a/consensus/safety-rules/src/tests/suite.rs b/consensus/safety-rules/src/tests/suite.rs index e8f96e69c65..c8bd53d0fc8 100644 --- a/consensus/safety-rules/src/tests/suite.rs +++ b/consensus/safety-rules/src/tests/suite.rs @@ -81,6 +81,27 @@ pub fn run_test_suite(safety_rules: &Callback) { test_order_votes_with_timeout(safety_rules); } +pub fn run_test_suite_without_sig_check(safety_rules: &Callback) { + test_end_to_end(safety_rules); + test_initialize(safety_rules); + test_voting_bad_epoch(safety_rules); + test_sign_old_proposal(safety_rules); + test_sign_proposal_with_bad_signer(safety_rules); + // test_sign_proposal_with_invalid_qc(safety_rules); + test_sign_proposal_with_early_preferred_round(safety_rules); + test_uninitialized_signer(safety_rules); + test_validator_not_in_set(safety_rules); + test_key_not_in_store(safety_rules); + test_2chain_rules(safety_rules); + // test_2chain_timeout(safety_rules); + // test_sign_commit_vote(safety_rules); + test_bad_execution_output(safety_rules); + test_order_votes_correct_execution(safety_rules); + test_order_votes_out_of_order_execution(safety_rules); + test_order_votes_incorrect_qc(safety_rules); + test_order_votes_with_timeout(safety_rules); +} + fn test_order_votes_correct_execution(safety_rules: &Callback) { let (mut safety_rules, signer) = safety_rules(); diff --git a/consensus/src/block_preparer.rs b/consensus/src/block_preparer.rs index f911659ab9f..f64b4db9480 100644 --- a/consensus/src/block_preparer.rs +++ b/consensus/src/block_preparer.rs @@ -2,22 +2,24 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - counters::{self, MAX_TXNS_FROM_BLOCK_TO_EXECUTE, TXN_SHUFFLE_SECONDS}, + counters::{self, MAX_TXNS_FROM_BLOCK_TO_EXECUTE, TXNS_IN_BLOCK, TXN_SHUFFLE_SECONDS}, payload_manager::TPayloadManager, transaction_deduper::TransactionDeduper, - transaction_filter::TransactionFilter, transaction_shuffler::TransactionShuffler, }; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{block::Block, quorum_cert::QuorumCert}; +use aptos_crypto::HashValue; use aptos_executor_types::ExecutorResult; use aptos_types::transaction::SignedTransaction; use fail::fail_point; use futures::future::Shared; +use move_core_types::account_address::AccountAddress; use std::{future::Future, sync::Arc, time::Instant}; pub struct BlockPreparer { payload_manager: Arc, - txn_filter: Arc, + txn_filter_config: Arc, txn_deduper: Arc, txn_shuffler: Arc, } @@ -25,13 +27,13 @@ pub struct BlockPreparer { impl BlockPreparer { pub fn new( payload_manager: Arc, - txn_filter: Arc, + txn_filter_config: Arc, txn_deduper: Arc, txn_shuffler: Arc, ) -> Self { Self { payload_manager, - txn_filter, + txn_filter_config, txn_deduper, txn_shuffler, } @@ -60,16 +62,29 @@ impl BlockPreparer { result } }?; - let txn_filter = self.txn_filter.clone(); + TXNS_IN_BLOCK + .with_label_values(&["before_filter"]) + .observe(txns.len() as f64); + + let txn_filter_config = self.txn_filter_config.clone(); let txn_deduper = self.txn_deduper.clone(); let txn_shuffler = self.txn_shuffler.clone(); + let block_id = block.id(); + let block_author = block.author(); let block_epoch = block.epoch(); let block_timestamp_usecs = block.timestamp_usecs(); + // Transaction filtering, deduplication and shuffling are CPU intensive tasks, so we run them in a blocking task. let result = tokio::task::spawn_blocking(move || { - let filtered_txns = - txn_filter.filter(block_id, block_epoch, block_timestamp_usecs, txns); + let filtered_txns = filter_block_transactions( + txn_filter_config, + block_id, + block_author, + block_epoch, + block_timestamp_usecs, + txns, + ); let deduped_txns = txn_deduper.dedup(filtered_txns); let mut shuffled_txns = { let _timer = TXN_SHUFFLE_SECONDS.start_timer(); @@ -80,6 +95,9 @@ impl BlockPreparer { if let Some(max_txns_from_block_to_execute) = max_txns_from_block_to_execute { shuffled_txns.truncate(max_txns_from_block_to_execute as usize); } + TXNS_IN_BLOCK + .with_label_values(&["after_filter"]) + .observe(shuffled_txns.len() as f64); MAX_TXNS_FROM_BLOCK_TO_EXECUTE.observe(shuffled_txns.len() as f64); Ok(shuffled_txns) }) @@ -89,3 +107,29 @@ impl BlockPreparer { result.map(|result| (result, block_gas_limit)) } } + +/// Filters transactions in a block based on the filter configuration +fn filter_block_transactions( + txn_filter_config: Arc, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp_usecs: u64, + txns: Vec, +) -> Vec { + // If the transaction filter is disabled, return early + if !txn_filter_config.is_enabled() { + return txns; + } + + // Otherwise, filter the transactions + txn_filter_config + .block_transaction_filter() + .filter_block_transactions( + block_id, + block_author, + block_epoch, + block_timestamp_usecs, + txns, + ) +} diff --git a/consensus/src/block_storage/block_store.rs b/consensus/src/block_storage/block_store.rs index c2a294708f4..2aedf6f9719 100644 --- a/consensus/src/block_storage/block_store.rs +++ b/consensus/src/block_storage/block_store.rs @@ -22,6 +22,7 @@ use crate::{ }; use anyhow::{bail, ensure, format_err, Context}; use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::Round, @@ -57,6 +58,12 @@ pub mod sync_manager; fn update_counters_for_ordered_blocks(ordered_blocks: &[Arc]) { for block in ordered_blocks { observe_block(block.block().timestamp_usecs(), BlockStage::ORDERED); + if block.block().is_opt_block() { + observe_block( + block.block().timestamp_usecs(), + BlockStage::ORDERED_OPT_BLOCK, + ); + } } } @@ -327,8 +334,6 @@ impl BlockStore { assert!(!blocks_to_commit.is_empty()); - let block_tree = self.inner.clone(); - let storage = self.storage.clone(); let finality_proof_clone = finality_proof.clone(); self.pending_blocks .lock() @@ -340,25 +345,8 @@ impl BlockStore { .insert_ordered_cert(finality_proof_clone.clone()); update_counters_for_ordered_blocks(&blocks_to_commit); - let window_size = self.window_size; - // This callback is invoked synchronously with and could be used for multiple batches of blocks. self.execution_client - .finalize_order( - blocks_to_commit, - finality_proof.clone(), - Box::new( - move |committed_blocks: &[Arc], - commit_decision: LedgerInfoWithSignatures| { - block_tree.write().commit_callback_deprecated( - storage, - committed_blocks, - finality_proof, - commit_decision, - window_size, - ); - }, - ), - ) + .finalize_order(blocks_to_commit, finality_proof.clone()) .await .expect("Failed to persist commit"); @@ -503,7 +491,7 @@ impl BlockStore { } }, ); - pipeline_builder.build( + pipeline_builder.build_for_consensus( &pipelined_block, parent_block.pipeline_futs().ok_or_else(|| { anyhow::anyhow!("Parent future doesn't exist, potentially epoch ended") @@ -554,6 +542,12 @@ impl BlockStore { pipelined_block.block().timestamp_usecs(), BlockStage::QC_ADDED, ); + if pipelined_block.block().is_opt_block() { + observe_block( + pipelined_block.block().timestamp_usecs(), + BlockStage::QC_ADDED_OPT_BLOCK, + ); + } pipelined_block.set_qc(Arc::new(qc.clone())); }, None => bail!("Insert {} without having the block in store first", qc), @@ -603,6 +597,15 @@ impl BlockStore { Ok(()) } + pub fn check_denied_inline_transactions( + &self, + block: &Block, + block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()> { + self.payload_manager + .check_denied_inline_transactions(block, block_txn_filter_config) + } + pub fn check_payload(&self, proposal: &Block) -> Result<(), BitVec> { self.payload_manager.check_payload_availability(proposal) } @@ -614,6 +617,18 @@ impl BlockStore { pub fn pre_commit_status(&self) -> Option>> { self.pre_commit_status.clone() } + + pub async fn abort_pipeline_for_state_sync(&self) { + let blocks = self.inner.read().get_all_blocks(); + // the blocks are not ordered by round here, so we need to abort all then wait + let futs: Vec<_> = blocks + .into_iter() + .filter_map(|b| b.abort_pipeline()) + .collect(); + for f in futs { + f.wait_until_finishes().await; + } + } } impl BlockReader for BlockStore { @@ -771,7 +786,7 @@ impl BlockReader for BlockStore { match cur_block { Some(block) => { if let Some(execution_time_and_size) = block.get_execution_summary() { - info!( + debug!( "Found execution time for {}, {:?}", block.id(), execution_time_and_size diff --git a/consensus/src/block_storage/block_tree.rs b/consensus/src/block_storage/block_tree.rs index 945c352ea41..066b2d5cf0f 100644 --- a/consensus/src/block_storage/block_tree.rs +++ b/consensus/src/block_storage/block_tree.rs @@ -4,7 +4,6 @@ use crate::{ counters, - counters::update_counters_for_committed_blocks, logging::{LogEvent, LogSchema}, persistent_liveness_storage::PersistentLivenessStorage, util::calculate_window_start_round, @@ -566,29 +565,6 @@ impl BlockTree { } /// Update the counters for committed blocks and prune them from the in-memory and persisted store. - pub fn commit_callback_deprecated( - &mut self, - storage: Arc, - blocks_to_commit: &[Arc], - finality_proof: WrappedLedgerInfo, - commit_decision: LedgerInfoWithSignatures, - window_size: Option, - ) { - update_counters_for_committed_blocks(blocks_to_commit); - - let last_block = blocks_to_commit.last().expect("pipeline is empty").clone(); - let (block_id, block_round) = (last_block.id(), last_block.round()); - - self.commit_callback( - storage, - block_id, - block_round, - finality_proof, - commit_decision, - window_size, - ); - } - pub fn commit_callback( &mut self, storage: Arc, @@ -623,6 +599,13 @@ impl BlockTree { self.update_window_root(window_root_id); self.update_highest_commit_cert(commit_proof); } + + pub fn get_all_blocks(&self) -> Vec> { + self.id_to_block + .values() + .map(|b| b.executed_block().clone()) + .collect() + } } #[cfg(any(test, feature = "fuzzing"))] diff --git a/consensus/src/block_storage/pending_blocks.rs b/consensus/src/block_storage/pending_blocks.rs index 8975ae122e1..9f137b31911 100644 --- a/consensus/src/block_storage/pending_blocks.rs +++ b/consensus/src/block_storage/pending_blocks.rs @@ -5,9 +5,10 @@ use crate::{ block_storage::block_store::sync_manager::TargetBlockRetrieval, counters::BLOCK_RETRIEVAL_LOCAL_FULFILL_COUNT, }; -use aptos_consensus_types::{block::Block, common::Round}; +use aptos_consensus_types::{block::Block, common::Round, opt_block_data::OptBlockData}; use aptos_crypto::HashValue; -use aptos_logger::info; +use aptos_logger::{info, warn}; +use aptos_short_hex_str::AsShortHexStr; use futures_channel::oneshot; use std::collections::{BTreeMap, HashMap}; @@ -16,6 +17,7 @@ use std::collections::{BTreeMap, HashMap}; pub struct PendingBlocks { blocks_by_hash: HashMap, blocks_by_round: BTreeMap, + opt_blocks_by_round: BTreeMap, pending_request: Option<(TargetBlockRetrieval, oneshot::Sender)>, } @@ -24,6 +26,7 @@ impl PendingBlocks { Self { blocks_by_hash: HashMap::new(), blocks_by_round: BTreeMap::new(), + opt_blocks_by_round: BTreeMap::new(), pending_request: None, } } @@ -53,6 +56,34 @@ impl PendingBlocks { } } + pub fn insert_opt_block(&mut self, opt_block_data: OptBlockData) { + info!( + "Pending opt block inserted: ({}, {})", + opt_block_data.author().short_str(), + opt_block_data.round() + ); + self.opt_blocks_by_round + .insert(opt_block_data.round(), opt_block_data.clone()); + + let Some(parent_opt_block) = self + .opt_blocks_by_round + .remove(&opt_block_data.parent().round()) + else { + return; + }; + + if parent_opt_block.parent_id() == opt_block_data.grandparent_qc().certified_block().id() { + let block = + Block::new_from_opt(parent_opt_block, opt_block_data.grandparent_qc().clone()); + self.insert_block(block); + } else { + warn!( + "Pending Opt Block entry in cache doesn't match QC: {} != {}", + parent_opt_block, opt_block_data + ); + } + } + pub fn insert_request( &mut self, target_block_retrieval_payload: TargetBlockRetrieval, @@ -94,6 +125,7 @@ impl PendingBlocks { to_remove.push(*r); } for r in to_remove { + self.opt_blocks_by_round.remove(&r); if let Some(block) = self.blocks_by_round.remove(&r) { self.blocks_by_hash.remove(&block.id()); } diff --git a/consensus/src/block_storage/sync_manager.rs b/consensus/src/block_storage/sync_manager.rs index 14685f2a855..ca92255c9ce 100644 --- a/consensus/src/block_storage/sync_manager.rs +++ b/consensus/src/block_storage/sync_manager.rs @@ -64,12 +64,14 @@ impl BlockStore { /// Check if we're far away from this ledger info and need to sync. /// This ensures that the block referred by the ledger info is not in buffer manager. pub fn need_sync_for_ledger_info(&self, li: &LedgerInfoWithSignatures) -> bool { + const MAX_PRECOMMIT_GAP: u64 = 200; let block_not_exist = self.ordered_root().round() < li.commit_info().round() && !self.block_exists(li.commit_info().id()); // TODO move min gap to fallback (30) to config, and if configurable make sure the value is // larger than buffer manager MAX_BACKLOG (20) let max_commit_gap = 30.max(2 * self.vote_back_pressure_limit); let min_commit_round = li.commit_info().round().saturating_sub(max_commit_gap); + let current_commit_round = self.commit_root().round(); if let Some(pre_commit_status) = self.pre_commit_status() { let mut status_guard = pre_commit_status.lock(); @@ -81,10 +83,13 @@ impl BlockStore { status_guard.pause(); true } else { + if current_commit_round + MAX_PRECOMMIT_GAP < status_guard.round() { + status_guard.pause(); + } false } } else { - block_not_exist || self.commit_root().round() < min_commit_round + block_not_exist || current_commit_round < min_commit_round } } @@ -297,6 +302,7 @@ impl BlockStore { self.payload_manager.clone(), self.order_vote_enabled, self.window_size, + Some(self), ) .await? .take(); @@ -366,6 +372,7 @@ impl BlockStore { payload_manager: Arc, order_vote_enabled: bool, window_size: Option, + maybe_block_store: Option<&'a BlockStore>, ) -> anyhow::Result { info!( LogSchema::new(LogEvent::StateSync).remote_peer(retriever.preferred_peer), @@ -495,7 +502,14 @@ impl BlockStore { })?; storage.save_tree(blocks.clone(), quorum_certs.clone())?; - + // abort any pending executor tasks before entering state sync + // with zaptos, things can run before hitting buffer manager + if let Some(block_store) = maybe_block_store { + monitor!( + "abort_pipeline_for_state_sync", + block_store.abort_pipeline_for_state_sync().await + ); + } execution_client .sync_to_target(highest_commit_cert.ledger_info().clone()) .await?; @@ -709,6 +723,21 @@ impl BlockRetriever { loop { tokio::select! { + biased; + Some((peer, response)) = futures.next() => { + match response { + Ok(result) => return Ok(result), + e => { + warn!( + remote_peer = peer, + block_id = block_id, + "{:?}, Failed to fetch block", + e, + ); + failed_attempt += 1; + }, + } + }, _ = interval.tick() => { // send batch request to a set of peers of size request_num_peers (or 1 for the first time) let next_peers = if cur_retry < num_retries { @@ -745,20 +774,6 @@ impl BlockRetriever { futures.push(async move { (remote_peer, future.await) }.boxed()); } } - Some((peer, response)) = futures.next() => { - match response { - Ok(result) => return Ok(result), - e => { - warn!( - remote_peer = peer, - block_id = block_id, - "{:?}, Failed to fetch block", - e, - ); - failed_attempt += 1; - }, - } - }, } } }) diff --git a/consensus/src/block_storage/tracing.rs b/consensus/src/block_storage/tracing.rs index 7e8f819ac54..396a12600dd 100644 --- a/consensus/src/block_storage/tracing.rs +++ b/consensus/src/block_storage/tracing.rs @@ -10,16 +10,27 @@ pub struct BlockStage; impl BlockStage { pub const COMMITTED: &'static str = "committed"; + pub const COMMITTED_OPT_BLOCK: &'static str = "committed_opt_block"; pub const COMMIT_CERTIFIED: &'static str = "commit_certified"; pub const EPOCH_MANAGER_RECEIVED: &'static str = "epoch_manager_received"; + pub const EPOCH_MANAGER_RECEIVED_OPT_PROPOSAL: &'static str = + "epoch_manager_received_opt_proposal"; pub const EPOCH_MANAGER_VERIFIED: &'static str = "epoch_manager_verified"; + pub const EPOCH_MANAGER_VERIFIED_OPT_PROPOSAL: &'static str = + "epoch_manager_verified_opt_proposal"; pub const EXECUTED: &'static str = "executed"; - pub const EXECUTION_PIPELINE_INSERTED: &'static str = "execution_pipeline_inserted"; pub const NETWORK_RECEIVED: &'static str = "network_received"; + pub const NETWORK_RECEIVED_OPT_PROPOSAL: &'static str = "network_received_opt_proposal"; pub const OC_ADDED: &'static str = "ordered_cert_created"; + // Optimistic Proposal + pub const OPT_PROPOSED: &'static str = "opt_proposed"; pub const ORDERED: &'static str = "ordered"; + pub const ORDERED_OPT_BLOCK: &'static str = "ordered_opt_block"; pub const ORDER_VOTED: &'static str = "order_voted"; + pub const ORDER_VOTED_OPT_BLOCK: &'static str = "order_voted_opt_block"; + pub const PROCESS_OPT_PROPOSAL: &'static str = "process_opt_proposal"; pub const QC_ADDED: &'static str = "qc_added"; + pub const QC_ADDED_OPT_BLOCK: &'static str = "qc_added_opt_block"; pub const QC_AGGREGATED: &'static str = "qc_aggregated"; pub const RAND_ADD_DECISION: &'static str = "rand_add_decision"; pub const RAND_ADD_ENOUGH_SHARE_FAST: &'static str = "rand_add_enough_share_fast"; @@ -27,9 +38,13 @@ impl BlockStage { pub const RAND_ENTER: &'static str = "rand_enter"; pub const RAND_READY: &'static str = "rand_ready"; pub const ROUND_MANAGER_RECEIVED: &'static str = "round_manager_received"; + pub const ROUND_MANAGER_RECEIVED_OPT_PROPOSAL: &'static str = + "round_manager_received_opt_proposal"; pub const SIGNED: &'static str = "signed"; pub const SYNCED: &'static str = "synced"; + pub const SYNCED_OPT_BLOCK: &'static str = "synced_opt_block"; pub const VOTED: &'static str = "voted"; + pub const VOTED_OPT_BLOCK: &'static str = "voted_opt_block"; } /// Record the time during each stage of a block. diff --git a/consensus/src/consensus_observer/network/observer_client.rs b/consensus/src/consensus_observer/network/observer_client.rs index 33c4ce902af..364050f9d87 100644 --- a/consensus/src/consensus_observer/network/observer_client.rs +++ b/consensus/src/consensus_observer/network/observer_client.rs @@ -144,7 +144,7 @@ impl> request_timeout_ms: u64, ) -> Result { // Generate a random request ID - let request_id = rand::thread_rng().gen(); + let request_id = rand::thread_rng().r#gen(); // Increment the request counter metrics::increment_counter( diff --git a/consensus/src/consensus_observer/network/observer_message.rs b/consensus/src/consensus_observer/network/observer_message.rs index 19618b34bce..2b8415d34a8 100644 --- a/consensus/src/consensus_observer/network/observer_message.rs +++ b/consensus/src/consensus_observer/network/observer_message.rs @@ -379,11 +379,11 @@ impl CommitDecision { #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct PayloadWithProof { transactions: Vec, - proofs: Vec, + proofs: Vec>, } impl PayloadWithProof { - pub fn new(transactions: Vec, proofs: Vec) -> Self { + pub fn new(transactions: Vec, proofs: Vec>) -> Self { Self { transactions, proofs, @@ -439,7 +439,7 @@ impl TransactionsWithProof { } } - pub fn proofs(&self) -> Vec { + pub fn proofs(&self) -> Vec> { match self { TransactionsWithProof::TransactionsWithProofAndLimits(payload) => { payload.payload_with_proof.proofs.clone() @@ -512,7 +512,7 @@ impl BlockTransactionPayload { /// Creates a returns a new InQuorumStore transaction payload pub fn new_in_quorum_store( transactions: Vec, - proofs: Vec, + proofs: Vec>, ) -> Self { let payload_with_proof = PayloadWithProof::new(transactions, proofs); Self::DeprecatedInQuorumStore(payload_with_proof) @@ -521,7 +521,7 @@ impl BlockTransactionPayload { /// Creates a returns a new InQuorumStoreWithLimit transaction payload pub fn new_in_quorum_store_with_limit( transactions: Vec, - proofs: Vec, + proofs: Vec>, limit: Option, ) -> Self { let payload_with_proof = PayloadWithProof::new(transactions, proofs); @@ -532,7 +532,7 @@ impl BlockTransactionPayload { /// Creates a returns a new QuorumStoreInlineHybrid transaction payload pub fn new_quorum_store_inline_hybrid( transactions: Vec, - proofs: Vec, + proofs: Vec>, transaction_limit: Option, gas_limit: Option, inline_batches: Vec, @@ -557,13 +557,14 @@ impl BlockTransactionPayload { pub fn new_opt_quorum_store( transactions: Vec, - proofs: Vec, - limit: Option, + proofs: Vec>, + transaction_limit: Option, + gas_limit: Option, batch_infos: Vec, ) -> Self { let payload_with_proof = PayloadWithProof::new(transactions, proofs); let proof_with_limits = TransactionsWithProof::TransactionsWithProofAndLimits( - TransactionsWithProofAndLimits::new(payload_with_proof, limit, None), + TransactionsWithProofAndLimits::new(payload_with_proof, transaction_limit, gas_limit), ); Self::OptQuorumStore(proof_with_limits, batch_infos) } @@ -612,7 +613,7 @@ impl BlockTransactionPayload { } /// Returns the proofs of the transaction payload - pub fn payload_proofs(&self) -> Vec { + pub fn payload_proofs(&self) -> Vec> { match self { BlockTransactionPayload::DeprecatedInQuorumStore(payload) => payload.proofs.clone(), BlockTransactionPayload::DeprecatedInQuorumStoreWithLimit(payload) => { @@ -714,7 +715,7 @@ impl BlockTransactionPayload { } /// Verifies the payload batches against the expected batches - fn verify_batches(&self, expected_proofs: &[ProofOfStore]) -> Result<(), Error> { + fn verify_batches(&self, expected_proofs: &[ProofOfStore]) -> Result<(), Error> { // Get the batches in the block transaction payload let payload_proofs = self.payload_proofs(); let payload_batches: Vec<&BatchInfo> = @@ -748,7 +749,7 @@ impl BlockTransactionPayload { let inline_batches: Vec<&BatchInfo> = match self { BlockTransactionPayload::QuorumStoreInlineHybrid(_, inline_batches) | BlockTransactionPayload::QuorumStoreInlineHybridV2(_, inline_batches) => { - inline_batches.iter().map(|batch_info| batch_info).collect() + inline_batches.iter().collect() }, _ => { return Err(Error::InvalidMessageError( @@ -1047,7 +1048,6 @@ mod test { ProofBatches, }, pipelined_block::OrderedBlockWindow, - proof_of_store::BatchId, quorum_cert::QuorumCert, }; use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue, PrivateKey, SigningKey, Uniform}; @@ -1055,6 +1055,7 @@ mod test { aggregate_signature::AggregateSignature, chain_id::ChainId, ledger_info::LedgerInfo, + quorum_store::BatchId, transaction::{RawTransaction, Script, TransactionPayload}, validator_signer::ValidatorSigner, validator_verifier::{ValidatorConsensusInfo, ValidatorVerifier}, @@ -1241,6 +1242,7 @@ mod test { vec![], proofs.clone(), transaction_limit, + None, opt_and_inline_batches.clone(), ); @@ -1343,6 +1345,7 @@ mod test { vec![], proofs, Some(100), + None, opt_and_inline_batches, ); @@ -1851,7 +1854,7 @@ mod test { fn create_block_payload( block_info: Option, signed_transactions: &[SignedTransaction], - proofs: &[ProofOfStore], + proofs: &[ProofOfStore], inline_batches: &[BatchInfo], ) -> BlockPayload { // Create the transaction payload @@ -1875,7 +1878,7 @@ mod test { fn create_block_optqs_payload( block_info: Option, signed_transactions: &[SignedTransaction], - proofs: &[ProofOfStore], + proofs: &[ProofOfStore], opt_and_inline_batches: &[BatchInfo], ) -> BlockPayload { // Create the transaction payload @@ -1883,6 +1886,7 @@ mod test { signed_transactions.to_vec(), proofs.to_vec(), None, + None, opt_and_inline_batches.to_vec(), ); @@ -1906,7 +1910,7 @@ mod test { fn create_mixed_expiration_proofs( block_timestamp: u64, signed_transactions: &[SignedTransaction], - ) -> (Vec, Vec) { + ) -> (Vec>, Vec) { let mut proofs = vec![]; let mut non_expired_transactions = vec![]; diff --git a/consensus/src/consensus_observer/observer/block_data.rs b/consensus/src/consensus_observer/observer/block_data.rs index cb3a6d118e3..5a124a1df3a 100644 --- a/consensus/src/consensus_observer/observer/block_data.rs +++ b/consensus/src/consensus_observer/observer/block_data.rs @@ -89,17 +89,6 @@ impl ObserverBlockData { self.block_payload_store.all_payloads_exist(blocks) } - /// Returns true iff the root epoch and round match the given values - pub fn check_root_epoch_and_round(&self, epoch: u64, round: Round) -> bool { - // Get the expected epoch and round - let root = self.root(); - let expected_epoch = root.commit_info().epoch(); - let expected_round = root.commit_info().round(); - - // Check if the expected epoch and round match the given values - expected_epoch == epoch && expected_round == round - } - /// Clears all block data and returns the root ledger info pub fn clear_block_data(&mut self) -> LedgerInfoWithSignatures { // Clear the payload store @@ -394,7 +383,7 @@ mod test { ); // Verify that the payload does not exist - assert!(!observer_block_data.all_payloads_exist(&[pipelined_block.clone()])); + assert!(!observer_block_data.all_payloads_exist(std::slice::from_ref(&pipelined_block))); // Insert the block payload into the store observer_block_data.insert_block_payload(block_payload.clone(), true); @@ -403,33 +392,6 @@ mod test { assert!(observer_block_data.all_payloads_exist(&[pipelined_block])); } - #[test] - fn test_check_root_epoch_and_round() { - // Create a root ledger info - let epoch = 10; - let round = 5; - let root = create_ledger_info(epoch, round); - - // Create the observer block data - let mut observer_block_data = - ObserverBlockData::new_with_root(ConsensusObserverConfig::default(), root); - - // Check the root epoch and round - assert!(observer_block_data.check_root_epoch_and_round(epoch, round)); - assert!(!observer_block_data.check_root_epoch_and_round(epoch, round + 1)); - assert!(!observer_block_data.check_root_epoch_and_round(epoch + 1, round)); - - // Update the root ledger info - let new_epoch = epoch + 10; - let new_round = round + 100; - let new_root = create_ledger_info(new_epoch, new_round); - observer_block_data.update_root(new_root.clone()); - - // Check the updated root epoch and round - assert!(!observer_block_data.check_root_epoch_and_round(epoch, round)); - assert!(observer_block_data.check_root_epoch_and_round(new_epoch, new_round)); - } - #[test] fn test_clear_block_data() { // Create a root ledger info diff --git a/consensus/src/consensus_observer/observer/consensus_observer.rs b/consensus/src/consensus_observer/observer/consensus_observer.rs index e4deb765daf..6a379308f16 100644 --- a/consensus/src/consensus_observer/observer/consensus_observer.rs +++ b/consensus/src/consensus_observer/observer/consensus_observer.rs @@ -255,41 +255,34 @@ impl ConsensusObserver { )) ); - // If the new pipeline is enabled, build the pipeline for the ordered blocks - if self.pipeline_enabled() { - let block = ordered_block.first_block(); - let get_parent_pipeline_futs = self - .observer_block_data - .lock() - .get_parent_pipeline_futs(&block, self.pipeline_builder()); + let block = ordered_block.first_block(); + let get_parent_pipeline_futs = self + .observer_block_data + .lock() + .get_parent_pipeline_futs(&block, self.pipeline_builder()); - let mut parent_fut = if let Some(futs) = get_parent_pipeline_futs { - Some(futs) - } else { - warn!( - LogSchema::new(LogEntry::ConsensusObserver).message(&format!( - "Parent block's pipeline futures for ordered block is missing! Ignoring: {:?}", - ordered_block.proof_block_info() - )) - ); - return; - }; - - for block in ordered_block.blocks() { - let commit_callback = - block_data::create_commit_callback(self.observer_block_data.clone()); - self.pipeline_builder().build( - block, - parent_fut.take().expect("future should be set"), - commit_callback, - ); - parent_fut = Some(block.pipeline_futs().expect("pipeline futures just built")); - } - } + let mut parent_fut = if let Some(futs) = get_parent_pipeline_futs { + Some(futs) + } else { + warn!( + LogSchema::new(LogEntry::ConsensusObserver).message(&format!( + "Parent block's pipeline futures for ordered block is missing! Ignoring: {:?}", + ordered_block.proof_block_info() + )) + ); + return; + }; - // Create the commit callback (to be called after the execution pipeline) - let commit_callback = - block_data::create_commit_callback_deprecated(self.observer_block_data.clone()); + for block in ordered_block.blocks() { + let commit_callback = + block_data::create_commit_callback(self.observer_block_data.clone()); + self.pipeline_builder().build_for_observer( + block, + parent_fut.take().expect("future should be set"), + commit_callback, + ); + parent_fut = Some(block.pipeline_futs().expect("pipeline futures just built")); + } // Send the ordered block to the execution pipeline if let Err(error) = self @@ -297,7 +290,6 @@ impl ConsensusObserver { .finalize_order( ordered_block.blocks().clone(), WrappedLedgerInfo::new(VoteData::dummy(), ordered_block.ordered_proof().clone()), - commit_callback, ) .await { @@ -980,14 +972,14 @@ impl ConsensusObserver { ) { // Get the epoch and round for the synced commit decision let ledger_info = latest_synced_ledger_info.ledger_info(); - let epoch = ledger_info.epoch(); - let round = ledger_info.round(); + let synced_epoch = ledger_info.epoch(); + let synced_round = ledger_info.round(); // Log the state sync notification info!( LogSchema::new(LogEntry::ConsensusObserver).message(&format!( - "Received state sync notification for commit completion! Epoch {}, round: {}!", - epoch, round + "Received state sync notification for commit completion! Synced epoch {}, round: {}!", + synced_epoch, synced_round )) ); @@ -1000,26 +992,41 @@ impl ConsensusObserver { return; } - // Verify that the state sync notification is for the current epoch and round - if !self - .observer_block_data - .lock() - .check_root_epoch_and_round(epoch, round) - { + // Get the block data root epoch and round + let block_data_root = self.observer_block_data.lock().root(); + let block_data_epoch = block_data_root.ledger_info().epoch(); + let block_data_round = block_data_root.ledger_info().round(); + + // If the commit sync notification is behind the block data root, ignore it. This + // is possible due to a race condition where we started syncing to a newer commit + // at the same time that state sync sent the notification for a previous commit. + if (synced_epoch, synced_round) < (block_data_epoch, block_data_round) { + info!( + LogSchema::new(LogEntry::ConsensusObserver).message(&format!( + "Ignoring old commit sync notification for epoch: {}, round: {}! Current root: {:?}", + synced_epoch, synced_round, block_data_root + )) + ); + return; + } + + // If the commit sync notification is ahead the block data root, something has gone wrong! + if (synced_epoch, synced_round) > (block_data_epoch, block_data_round) { // Log the error, reset the state sync manager and return early error!( LogSchema::new(LogEntry::ConsensusObserver).message(&format!( "Received invalid commit sync notification for epoch: {}, round: {}! Current root: {:?}", - epoch, round, self.observer_block_data.lock().root() + synced_epoch, synced_round, block_data_root )) ); self.state_sync_manager.clear_active_commit_sync(); return; } - // If the epoch has changed, end the current epoch and start the latest one + // Otherwise, the commit sync notification matches the block data root. + // If the epoch has changed, end the current epoch and start the latest one. let current_epoch_state = self.get_epoch_state(); - if epoch > current_epoch_state.epoch { + if synced_epoch > current_epoch_state.epoch { // Wait for the latest epoch to start self.execution_client.end_epoch().await; self.wait_for_epoch_start().await; @@ -1086,13 +1093,10 @@ impl ConsensusObserver { None, // fast_rand_config rand_msg_rx, 0, // highest_committed_round - self.observer_epoch_state.pipeline_enabled(), None, // Consensus observer doesn't use virtual genesis ) .await; - if self.pipeline_enabled() { - self.pipeline_builder = Some(self.execution_client.pipeline_builder(signer)) - } + self.pipeline_builder = Some(self.execution_client.pipeline_builder(signer)); } /// Starts the consensus observer loop that processes incoming @@ -1139,11 +1143,6 @@ impl ConsensusObserver { .message("The consensus observer loop exited unexpectedly!")); } - /// Returns whether the pipeline is enabled - pub fn pipeline_enabled(&self) -> bool { - self.observer_epoch_state.pipeline_enabled() - } - /// Returns the builder, should only be called if pipeline is enabled pub fn pipeline_builder(&self) -> &PipelineBuilder { self.pipeline_builder diff --git a/consensus/src/consensus_observer/observer/epoch_state.rs b/consensus/src/consensus_observer/observer/epoch_state.rs index f42cb2d06b9..2c2e1232817 100644 --- a/consensus/src/consensus_observer/observer/epoch_state.rs +++ b/consensus/src/consensus_observer/observer/epoch_state.rs @@ -125,11 +125,6 @@ impl ObserverEpochState { randomness_config, ) } - - /// Returns whether the pipeline is enabled - pub fn pipeline_enabled(&self) -> bool { - self.node_config.consensus_observer.enable_pipeline - } } /// A simple helper function that extracts the on-chain configs from the reconfig events diff --git a/consensus/src/consensus_observer/observer/execution_pool.rs b/consensus/src/consensus_observer/observer/execution_pool.rs index 2430861e850..edcc4899cd1 100644 --- a/consensus/src/consensus_observer/observer/execution_pool.rs +++ b/consensus/src/consensus_observer/observer/execution_pool.rs @@ -30,7 +30,7 @@ impl ObservedOrderedBlock { /// Creates a new observed ordered block for testing. /// Note: the observed type is determined randomly. pub fn new_for_testing(ordered_block: OrderedBlock) -> Self { - if OsRng.gen::() % 2 == 0 { + if OsRng.r#gen::() % 2 == 0 { ObservedOrderedBlock::new(ordered_block.clone()) } else { let ordered_block_with_window = OrderedBlockWithWindow::new( diff --git a/consensus/src/consensus_observer/observer/payload_store.rs b/consensus/src/consensus_observer/observer/payload_store.rs index b87b94eec97..9ef2866769b 100644 --- a/consensus/src/consensus_observer/observer/payload_store.rs +++ b/consensus/src/consensus_observer/observer/payload_store.rs @@ -284,7 +284,7 @@ mod test { block_data::{BlockData, BlockType}, common::{Author, Payload, ProofWithData}, pipelined_block::OrderedBlockWindow, - proof_of_store::{BatchId, BatchInfo, ProofOfStore}, + proof_of_store::{BatchInfo, ProofOfStore}, quorum_cert::QuorumCert, }; use aptos_crypto::HashValue; @@ -292,6 +292,7 @@ mod test { aggregate_signature::AggregateSignature, block_info::{BlockInfo, Round}, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, + quorum_store::BatchId, transaction::Version, validator_signer::ValidatorSigner, validator_verifier::{ValidatorConsensusInfo, ValidatorVerifier}, diff --git a/consensus/src/consensus_provider.rs b/consensus/src/consensus_provider.rs index 1343f58b426..4699baf8039 100644 --- a/consensus/src/consensus_provider.rs +++ b/consensus/src/consensus_provider.rs @@ -20,7 +20,6 @@ use crate::{ quorum_store::quorum_store_db::QuorumStoreDB, rand::rand_gen::storage::db::RandDb, state_computer::ExecutionProxy, - transaction_filter::TransactionFilter, txn_notifier::MempoolNotifier, util::time_service::ClockTimeService, }; @@ -68,8 +67,7 @@ pub fn start_consensus( Arc::new(BlockExecutor::::new(aptos_db)), txn_notifier, state_sync_notifier, - runtime.handle(), - TransactionFilter::new(node_config.execution.transaction_filter.clone()), + node_config.transaction_filters.execution_filter.clone(), node_config.consensus.enable_pre_commit, ); @@ -161,8 +159,7 @@ pub fn start_consensus_observer( Arc::new(BlockExecutor::::new(aptos_db.clone())), txn_notifier, state_sync_notifier, - consensus_observer_runtime.handle(), - TransactionFilter::new(node_config.execution.transaction_filter.clone()), + node_config.transaction_filters.execution_filter.clone(), node_config.consensus.enable_pre_commit, ); diff --git a/consensus/src/consensusdb/mod.rs b/consensus/src/consensusdb/mod.rs index d9b80a9c948..b40b0828d00 100644 --- a/consensus/src/consensusdb/mod.rs +++ b/consensus/src/consensusdb/mod.rs @@ -155,7 +155,7 @@ impl ConsensusDB { /// Write the whole schema batch including all data necessary to mutate the ledger /// state of some transaction by leveraging rocksdb atomicity support. fn commit(&self, batch: SchemaBatch) -> Result<(), DbError> { - self.db.write_schemas(batch)?; + self.db.write_schemas_relaxed(batch)?; Ok(()) } diff --git a/consensus/src/counters.rs b/consensus/src/counters.rs index 944a1fc758d..29e1ee2a8c2 100644 --- a/consensus/src/counters.rs +++ b/consensus/src/counters.rs @@ -11,7 +11,7 @@ use crate::{ use aptos_consensus_types::{block::Block, pipelined_block::PipelinedBlock}; use aptos_crypto::HashValue; use aptos_executor_types::{state_compute_result::StateComputeResult, ExecutorError}; -use aptos_logger::prelude::{error, warn}; +use aptos_logger::prelude::warn; use aptos_metrics_core::{ exponential_buckets, op_counters::DurationHistogram, register_avg_counter, register_counter, register_gauge, register_gauge_vec, register_histogram, register_histogram_vec, @@ -30,8 +30,15 @@ pub const TXN_COMMIT_SUCCESS_LABEL: &str = "success"; pub const TXN_COMMIT_FAILED_LABEL: &str = "failed"; /// Transaction commit failed (will not be retried) because of a duplicate pub const TXN_COMMIT_FAILED_DUPLICATE_LABEL: &str = "failed_duplicate"; +/// Transaction commit failed because the sequence number is too new (out of order) +pub const TXN_COMMIT_SEQNUM_TOO_NEW_LABEL: &str = "failed_seqnum_too_new"; /// Transaction commit failed (will not be retried) because it expired pub const TXN_COMMIT_FAILED_EXPIRED_LABEL: &str = "failed_expired"; +/// Transaction commit failed (will not be retried) because the nonce is already used in a previous transaction +pub const TXN_COMMIT_FAILED_NONCE_ALREADY_USED_LABEL: &str = "failed_nonce_already_used"; +/// Transaction commit failed (will not be retried) because the transaction expiration time is too far in the future +pub const TXN_COMMIT_FAILED_TXN_EXPIRATION_TOO_FAR_IN_FUTURE_LABEL: &str = + "failed_txn_expiration_too_far_in_future"; /// Transaction commit was unsuccessful, but will be retried pub const TXN_COMMIT_RETRY_LABEL: &str = "retry"; @@ -50,6 +57,16 @@ fn gas_buckets() -> Vec { pub static OP_COUNTERS: Lazy = Lazy::new(|| aptos_metrics_core::op_counters::OpMetrics::new_and_registered("consensus")); +/// Count of the total number of blocks of whether randomness is required +pub static RAND_BLOCK: Lazy = Lazy::new(|| { + register_int_counter_vec!( + "aptos_consensus_rand_block_count", + "Count of the total number of blocks of whether randomness is required", + &["type"] + ) + .unwrap() +}); + /// Counts the total number of errors pub static ERROR_COUNT: Lazy = Lazy::new(|| { register_int_gauge!( @@ -68,6 +85,15 @@ pub static LAST_COMMITTED_ROUND: Lazy = Lazy::new(|| { .unwrap() }); +/// The counter corresponds to the round of the highest committed opt block. +pub static LAST_COMMITTED_OPT_BLOCK_ROUND: Lazy = Lazy::new(|| { + register_int_gauge!( + "aptos_consensus_last_committed_opt_block_round", + "The counter corresponds to the round of the highest committed opt block." + ) + .unwrap() +}); + /// The counter corresponds to the version of the last committed ledger info. pub static LAST_COMMITTED_VERSION: Lazy = Lazy::new(|| { register_int_gauge!( @@ -95,6 +121,15 @@ pub static COMMITTED_BLOCKS_COUNT: Lazy = Lazy::new(|| { .unwrap() }); +/// Count of the committed opt blocks since last restart. +pub static COMMITTED_OPT_BLOCKS_COUNT: Lazy = Lazy::new(|| { + register_int_counter!( + "aptos_consensus_committed_opt_blocks_count", + "Count of the committed opt blocks since last restart." + ) + .unwrap() +}); + /// Count of the committed transactions since last restart. pub static COMMITTED_TXNS_COUNT: Lazy = Lazy::new(|| { register_int_counter_vec!( @@ -1151,7 +1186,6 @@ pub fn log_executor_error_occurred( e: ExecutorError, counter: &Lazy, block_id: HashValue, - new_pipeline_enabled: bool, ) { match e { ExecutorError::CouldNotGetData => { @@ -1170,17 +1204,10 @@ pub fn log_executor_error_occurred( }, e => { counter.with_label_values(&["UnexpectedError"]).inc(); - if new_pipeline_enabled { - warn!( - block_id = block_id, - "Execution error {:?} for {}", e, block_id - ); - } else { - error!( - block_id = block_id, - "Execution error {:?} for {}", e, block_id - ); - } + warn!( + block_id = block_id, + "Execution error {:?} for {}", e, block_id + ); }, } } @@ -1244,6 +1271,26 @@ pub static UNEXPECTED_PROPOSAL_EXT_COUNT: Lazy = Lazy::new(|| { .unwrap() }); +/// Count of the number of rejected proposals due to denied inline transactions +pub static REJECTED_PROPOSAL_DENY_TXN_COUNT: Lazy = Lazy::new(|| { + register_int_counter!( + "aptos_consensus_rejected_proposal_deny_txn_count", + "Count of the number of rejected proposals due to denied inline transactions" + ) + .unwrap() +}); + +/// Histogram for the number of txns in a block. +pub static TXNS_IN_BLOCK: Lazy = Lazy::new(|| { + register_histogram_vec!( + "txns_in_block", + "Histogram for the number of txns to be executed in a block.", + &["type"], + exponential_buckets(/*start=*/ 1.5, /*factor=*/ 1.5, /*count=*/ 25).unwrap(), + ) + .unwrap() +}); + /// Histogram for the number of txns to be executed in a block. pub static MAX_TXNS_FROM_BLOCK_TO_EXECUTE: Lazy = Lazy::new(|| { register_histogram!( @@ -1280,6 +1327,11 @@ pub fn update_counters_for_block(block: &Block) { NUM_BYTES_PER_BLOCK.observe(block.payload().map_or(0, |payload| payload.size()) as f64); COMMITTED_BLOCKS_COUNT.inc(); LAST_COMMITTED_ROUND.set(block.round() as i64); + if block.is_opt_block() { + observe_block(block.timestamp_usecs(), BlockStage::COMMITTED_OPT_BLOCK); + COMMITTED_OPT_BLOCKS_COUNT.inc(); + LAST_COMMITTED_OPT_BLOCK_ROUND.set(block.round() as i64); + } let failed_rounds = block .block_data() .failed_authors() @@ -1288,7 +1340,7 @@ pub fn update_counters_for_block(block: &Block) { if failed_rounds > 0 { COMMITTED_FAILED_ROUNDS_COUNT.inc_by(failed_rounds as u64); } - quorum_store::counters::NUM_BATCH_PER_BLOCK.observe(block.payload_size() as f64); + quorum_store::counters::update_batch_stats(block); } pub fn update_counters_for_compute_result(compute_result: &StateComputeResult) { @@ -1300,11 +1352,15 @@ pub fn update_counters_for_compute_result(compute_result: &StateComputeResult) { TransactionStatus::Keep(_) => TXN_COMMIT_SUCCESS_LABEL, TransactionStatus::Discard(reason) => { if *reason == DiscardedVMStatus::SEQUENCE_NUMBER_TOO_NEW { - TXN_COMMIT_RETRY_LABEL + TXN_COMMIT_SEQNUM_TOO_NEW_LABEL } else if *reason == DiscardedVMStatus::SEQUENCE_NUMBER_TOO_OLD { TXN_COMMIT_FAILED_DUPLICATE_LABEL } else if *reason == DiscardedVMStatus::TRANSACTION_EXPIRED { TXN_COMMIT_FAILED_EXPIRED_LABEL + } else if *reason == DiscardedVMStatus::NONCE_ALREADY_USED { + TXN_COMMIT_FAILED_NONCE_ALREADY_USED_LABEL + } else if *reason == DiscardedVMStatus::TRANSACTION_EXPIRATION_TOO_FAR_IN_FUTURE { + TXN_COMMIT_FAILED_TXN_EXPIRATION_TOO_FAR_IN_FUTURE_LABEL } else { TXN_COMMIT_FAILED_LABEL } diff --git a/consensus/src/dag/adapter.rs b/consensus/src/dag/adapter.rs index d04e02efda9..1f72197dbdc 100644 --- a/consensus/src/dag/adapter.rs +++ b/consensus/src/dag/adapter.rs @@ -9,7 +9,6 @@ use crate::{ block_storage::tracing::{observe_block, BlockStage}, consensusdb::{CertifiedNodeSchema, ConsensusDB, DagVoteSchema, NodeSchema}, counters, - counters::update_counters_for_committed_blocks, dag::{ storage::{CommitEvent, DAGStorage}, CertifiedNode, Node, NodeId, Vote, @@ -199,14 +198,11 @@ impl OrderedNotifier for OrderedNotifierAdapter { StateComputeResult::new_dummy(), )); let block_info = block.block_info(); - let ledger_info_provider = self.ledger_info_provider.clone(); - let dag = self.dag.clone(); *self.parent_block_info.write() = block_info.clone(); self.block_ordered_ts .write() .insert(block_info.round(), Instant::now()); - let block_created_ts = self.block_ordered_ts.clone(); observe_block(block.block().timestamp_usecs(), BlockStage::ORDERED); @@ -216,20 +212,22 @@ impl OrderedNotifier for OrderedNotifierAdapter { LedgerInfo::new(block_info, anchor.digest()), AggregateSignature::empty(), ), - callback: Box::new( - move |committed_blocks: &[Arc], - commit_decision: LedgerInfoWithSignatures| { - block_created_ts - .write() - .retain(|&round, _| round > commit_decision.commit_info().round()); - dag.commit_callback(commit_decision.commit_info().round()); - ledger_info_provider - .write() - .notify_commit_proof(commit_decision); - update_counters_for_committed_blocks(committed_blocks); - }, - ), + // TODO: this needs to be properly integrated with pipeline_builder + // callback: Box::new( + // move |committed_blocks: &[Arc], + // commit_decision: LedgerInfoWithSignatures| { + // block_created_ts + // .write() + // .retain(|&round, _| round > commit_decision.commit_info().round()); + // dag.commit_callback(commit_decision.commit_info().round()); + // ledger_info_provider + // .write() + // .notify_commit_proof(commit_decision); + // update_counters_for_committed_blocks(committed_blocks); + // }, + // ), }; + // if self .executor_channel .unbounded_send(blocks_to_send) diff --git a/consensus/src/dag/dag_driver.rs b/consensus/src/dag/dag_driver.rs index fa0caee1faa..aaa8c9ddb2d 100644 --- a/consensus/src/dag/dag_driver.rs +++ b/consensus/src/dag/dag_driver.rs @@ -275,7 +275,6 @@ impl DagDriver { block_timestamp: self.time_service.now_unix_time(), }, sys_payload_filter, - Box::pin(async {}), ) .await { diff --git a/consensus/src/dag/dag_fetcher.rs b/consensus/src/dag/dag_fetcher.rs index 43f7b456e16..b98369ded85 100644 --- a/consensus/src/dag/dag_fetcher.rs +++ b/consensus/src/dag/dag_fetcher.rs @@ -214,7 +214,7 @@ impl DagFetcherService { &mut self, node: &Node, responders: Vec, - ) -> anyhow::Result>>> { + ) -> anyhow::Result> + use<>>> { let remote_request = { let dag_reader = self.dag.read(); ensure!( diff --git a/consensus/src/dag/dag_store.rs b/consensus/src/dag/dag_store.rs index 86f28637d52..a42eddce977 100644 --- a/consensus/src/dag/dag_store.rs +++ b/consensus/src/dag/dag_store.rs @@ -303,7 +303,7 @@ impl InMemDag { &mut self, from: &Arc, until: Option, - ) -> impl Iterator { + ) -> impl Iterator + use<'_> { let until = until.unwrap_or(self.lowest_round()); let mut reachable_filter = Self::reachable_filter(vec![from.digest()]); self.nodes_by_round diff --git a/consensus/src/dag/health/chain_health.rs b/consensus/src/dag/health/chain_health.rs index 6b9845407ae..d0f4a759080 100644 --- a/consensus/src/dag/health/chain_health.rs +++ b/consensus/src/dag/health/chain_health.rs @@ -60,9 +60,7 @@ impl ChainHealthBackoff { let voting_power_ratio = self .commit_history .get_voting_power_participation_ratio(round); - let chain_health_backoff = self.config.get_backoff(voting_power_ratio); - - chain_health_backoff + self.config.get_backoff(voting_power_ratio) } } diff --git a/consensus/src/dag/rb_handler.rs b/consensus/src/dag/rb_handler.rs index f1dc9c8455c..3d3daac6196 100644 --- a/consensus/src/dag/rb_handler.rs +++ b/consensus/src/dag/rb_handler.rs @@ -102,8 +102,8 @@ impl NodeBroadcastHandler { .iter() .flat_map(|(r, peer_and_digest)| { peer_and_digest - .iter() - .map(|(author, _)| NodeId::new(self.epoch_state.epoch, *r, *author)) + .keys() + .map(|author| NodeId::new(self.epoch_state.epoch, *r, *author)) }) .collect(); self.storage.delete_votes(to_delete) diff --git a/consensus/src/dag/tests/helpers.rs b/consensus/src/dag/tests/helpers.rs index 949ea5aaeb0..cb8debd71e1 100644 --- a/consensus/src/dag/tests/helpers.rs +++ b/consensus/src/dag/tests/helpers.rs @@ -9,6 +9,7 @@ use crate::{ payload_manager::TPayloadManager, }; use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::{Author, Payload, Round}, @@ -27,6 +28,14 @@ impl TPayloadManager for MockPayloadManager { fn notify_commit(&self, _block_timestamp: u64, _payloads: Vec) {} + fn check_denied_inline_transactions( + &self, + _block: &Block, + _block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()> { + Ok(()) + } + fn check_payload_availability(&self, _block: &Block) -> Result<(), BitVec> { unimplemented!() } diff --git a/consensus/src/dag/tests/order_rule_tests.rs b/consensus/src/dag/tests/order_rule_tests.rs index 8dbdd1a7c7b..34af9ba7c4d 100644 --- a/consensus/src/dag/tests/order_rule_tests.rs +++ b/consensus/src/dag/tests/order_rule_tests.rs @@ -33,14 +33,13 @@ fn generate_virtual_dag( let num_strong_links = num_nodes * 2 / 3 + 1; assert!(num_holes <= num_nodes - num_strong_links); // This only has length of num_nodes - num_holes which ignores holes - let strong_links: Vec = std::iter::repeat(false) - .take(num_nodes - num_holes - num_strong_links) - .chain(std::iter::repeat(true).take(num_strong_links)) - .collect(); + let strong_links: Vec = + std::iter::repeat_n(false, num_nodes - num_holes - num_strong_links) + .chain(std::iter::repeat_n(true, num_strong_links)) + .collect(); // This has length of num_nodes - let nodes: Vec = std::iter::repeat(false) - .take(num_holes) - .chain(std::iter::repeat(true).take(num_nodes - num_holes)) + let nodes: Vec = std::iter::repeat_n(false, num_holes) + .chain(std::iter::repeat_n(true, num_nodes - num_holes)) .collect(); // For every round, we shuffle the nodes bitmask to generate holes // For every node, we shuffle the compressed strong links if the node is not a hole diff --git a/consensus/src/epoch_manager.rs b/consensus/src/epoch_manager.rs index 701dc998469..e08df79f771 100644 --- a/consensus/src/epoch_manager.rs +++ b/consensus/src/epoch_manager.rs @@ -58,12 +58,15 @@ use crate::{ use anyhow::{anyhow, bail, ensure, Context}; use aptos_bounded_executor::BoundedExecutor; use aptos_channels::{aptos_channel, message_queues::QueueStyle}; -use aptos_config::config::{ConsensusConfig, DagConsensusConfig, ExecutionConfig, NodeConfig}; +use aptos_config::config::{ + BatchTransactionFilterConfig, BlockTransactionFilterConfig, ConsensusConfig, + DagConsensusConfig, NodeConfig, +}; use aptos_consensus_types::{ block_retrieval::BlockRetrievalRequest, common::{Author, Round}, epoch_retrieval::EpochRetrievalRequest, - proof_of_store::ProofCache, + proof_of_store::{BatchInfo, ProofCache}, utils::PayloadTxnsSize, }; use aptos_crypto::bls12381::PrivateKey; @@ -116,9 +119,9 @@ use std::{ /// Range of rounds (window) that we might be calling proposer election /// functions with at any given time, in addition to the proposer history length. const PROPOSER_ELECTION_CACHING_WINDOW_ADDITION: usize = 3; -/// Number of rounds we expect storage to be ahead of the proposer round, +/// Number of rounds we expect storage to be behind the proposer round, /// used for fetching data from DB. -const PROPOSER_ROUND_BEHIND_STORAGE_BUFFER: usize = 10; +const PROPOSER_ROUND_BEHIND_STORAGE_BUFFER: usize = 30; #[allow(clippy::large_enum_variant)] pub enum LivenessStorageData { @@ -131,8 +134,6 @@ pub enum LivenessStorageData { pub struct EpochManager { author: Author, config: ConsensusConfig, - #[allow(unused)] - execution_config: ExecutionConfig, randomness_override_seq_num: u64, time_service: Arc, self_sender: aptos_channels::UnboundedSender>, @@ -171,10 +172,13 @@ pub struct EpochManager { dag_config: DagConsensusConfig, payload_manager: Arc, rand_storage: Arc>, - proof_cache: ProofCache, + proof_cache: ProofCache, consensus_publisher: Option>, pending_blocks: Arc>, key_storage: PersistentSafetyStorage, + + consensus_txn_filter_config: BlockTransactionFilterConfig, + quorum_store_txn_filter_config: BatchTransactionFilterConfig, } impl EpochManager

{ @@ -198,15 +202,17 @@ impl EpochManager

{ ) -> Self { let author = node_config.validator_network.as_ref().unwrap().peer_id(); let config = node_config.consensus.clone(); - let execution_config = node_config.execution.clone(); let dag_config = node_config.dag_consensus.clone(); let sr_config = &node_config.consensus.safety_rules; let safety_rules_manager = SafetyRulesManager::new(sr_config); let key_storage = safety_rules_manager::storage(sr_config); + let consensus_txn_filter_config = node_config.transaction_filters.consensus_filter.clone(); + let quorum_store_txn_filter_config = + node_config.transaction_filters.quorum_store_filter.clone(); + Self { author, config, - execution_config, randomness_override_seq_num: node_config.randomness_override_seq_num, time_service, self_sender, @@ -246,6 +252,8 @@ impl EpochManager

{ consensus_publisher, pending_blocks: Arc::new(Mutex::new(PendingBlocks::new())), key_storage, + consensus_txn_filter_config, + quorum_store_txn_filter_config, } } @@ -565,7 +573,7 @@ impl EpochManager

{ ) { let (request_tx, mut request_rx) = aptos_channel::new::<_, IncomingBlockRetrievalRequest>( QueueStyle::KLAST, - 10, + self.config.internal_per_key_channel_size, Some(&counters::BLOCK_RETRIEVAL_TASK_MSGS), ); let task = async move { @@ -677,7 +685,7 @@ impl EpochManager

{ ) { let (recovery_manager_tx, recovery_manager_rx) = aptos_channel::new( QueueStyle::KLAST, - 10, + self.config.internal_per_key_channel_size, Some(&counters::ROUND_MANAGER_CHANNEL_MSGS), ); self.round_manager_tx = Some(recovery_manager_tx); @@ -727,6 +735,7 @@ impl EpochManager

{ self.author, epoch_state.verifier.len() as u64, quorum_store_config, + self.quorum_store_txn_filter_config.clone(), consensus_to_quorum_store_rx, self.quorum_store_to_mempool_sender.clone(), self.config.mempool_txn_pull_timeout_ms, @@ -864,18 +873,13 @@ impl EpochManager

{ fast_rand_config.clone(), rand_msg_rx, recovery_data.commit_root_block().round(), - self.config.enable_pipeline, virtual_genesis_block_id, ) .await; let consensus_sk = consensus_key; - let maybe_pipeline_builder = if self.config.enable_pipeline { - let signer = Arc::new(ValidatorSigner::new(self.author, consensus_sk)); - Some(self.execution_client.pipeline_builder(signer)) - } else { - None - }; + let signer = Arc::new(ValidatorSigner::new(self.author, consensus_sk)); + let pipeline_builder = self.execution_client.pipeline_builder(signer); info!(epoch = epoch, "Create BlockStore"); // Read the last vote, before "moving" `recovery_data` let last_vote = recovery_data.last_vote(); @@ -890,7 +894,7 @@ impl EpochManager

{ onchain_consensus_config.order_vote_enabled(), onchain_consensus_config.window_size(), self.pending_blocks.clone(), - maybe_pipeline_builder, + Some(pipeline_builder), )); let failures_tracker = Arc::new(Mutex::new(ExponentialWindowFailureTracker::new( @@ -904,6 +908,11 @@ impl EpochManager

{ )); info!(epoch = epoch, "Create ProposalGenerator"); + let max_sending_block_txns_after_filtering = if self.config.enable_optimistic_proposal_tx { + self.config.max_sending_opt_block_txns_after_filtering + } else { + self.config.max_sending_block_txns_after_filtering + }; // txn manager is required both by proposal generator (to pull the proposers) // and by event processor (to update their status). let proposal_generator = ProposalGenerator::new( @@ -916,7 +925,7 @@ impl EpochManager

{ self.config.max_sending_block_txns, self.config.max_sending_block_bytes, ), - self.config.max_sending_block_txns_after_filtering, + max_sending_block_txns_after_filtering, PayloadTxnsSize::new( self.config.max_sending_inline_txns, self.config.max_sending_inline_bytes, @@ -939,15 +948,19 @@ impl EpochManager

{ ); let (round_manager_tx, round_manager_rx) = aptos_channel::new( QueueStyle::KLAST, - 10, + self.config.internal_per_key_channel_size, Some(&counters::ROUND_MANAGER_CHANNEL_MSGS), ); let (buffered_proposal_tx, buffered_proposal_rx) = aptos_channel::new( QueueStyle::KLAST, - 10, + self.config.internal_per_key_channel_size, Some(&counters::ROUND_MANAGER_CHANNEL_MSGS), ); + + let (opt_proposal_loopback_tx, opt_proposal_loopback_rx) = + aptos_channels::new_unbounded(&counters::OP_COUNTERS.gauge("opt_proposal_queue")); + self.round_manager_tx = Some(round_manager_tx.clone()); self.buffered_proposal_tx = Some(buffered_proposal_tx.clone()); let max_blocks_allowed = self @@ -965,18 +978,25 @@ impl EpochManager

{ self.storage.clone(), onchain_consensus_config, buffered_proposal_tx, + self.consensus_txn_filter_config.clone(), self.config.clone(), onchain_randomness_config, onchain_jwk_consensus_config, fast_rand_config, failures_tracker, + opt_proposal_loopback_tx, ); round_manager.init(last_vote).await; let (close_tx, close_rx) = oneshot::channel(); self.round_manager_close_tx = Some(close_tx); - tokio::spawn(round_manager.start(round_manager_rx, buffered_proposal_rx, close_rx)); + tokio::spawn(round_manager.start( + round_manager_rx, + buffered_proposal_rx, + opt_proposal_loopback_rx, + close_rx, + )); self.spawn_block_retrieval_task(epoch, block_store, max_blocks_allowed); } @@ -1254,7 +1274,7 @@ impl EpochManager

{ let (rand_msg_tx, rand_msg_rx) = aptos_channel::new::( QueueStyle::KLAST, - 10, + self.config.internal_per_key_channel_size, None, ); @@ -1429,7 +1449,6 @@ impl EpochManager

{ fast_rand_config, rand_msg_rx, highest_committed_round, - self.config.enable_pipeline, None, // DAG doesn't use virtual genesis ) .await; @@ -1506,6 +1525,24 @@ impl EpochManager

{ BlockStage::EPOCH_MANAGER_RECEIVED, ); } + if let ConsensusMsg::OptProposalMsg(proposal) = &consensus_msg { + if !self.config.enable_optimistic_proposal_rx { + bail!( + "Unexpected OptProposalMsg. Feature is disabled. Author: {}, Epoch: {}, Round: {}", + proposal.block_data().author(), + proposal.epoch(), + proposal.round() + ) + } + observe_block( + proposal.timestamp_usecs(), + BlockStage::EPOCH_MANAGER_RECEIVED, + ); + observe_block( + proposal.timestamp_usecs(), + BlockStage::EPOCH_MANAGER_RECEIVED_OPT_PROPOSAL, + ); + } // we can't verify signatures from a different epoch let maybe_unverified_event = self.check_epoch(peer_id, consensus_msg).await?; @@ -1584,6 +1621,7 @@ impl EpochManager

{ ) -> anyhow::Result> { match msg { ConsensusMsg::ProposalMsg(_) + | ConsensusMsg::OptProposalMsg(_) | ConsensusMsg::SyncInfo(_) | ConsensusMsg::VoteMsg(_) | ConsensusMsg::RoundTimeoutMsg(_) @@ -1696,6 +1734,16 @@ impl EpochManager

{ BlockStage::EPOCH_MANAGER_VERIFIED, ); } + if let VerifiedEvent::OptProposalMsg(proposal) = &event { + observe_block( + proposal.timestamp_usecs(), + BlockStage::EPOCH_MANAGER_VERIFIED, + ); + observe_block( + proposal.timestamp_usecs(), + BlockStage::EPOCH_MANAGER_VERIFIED_OPT_PROPOSAL, + ); + } if let Err(e) = match event { quorum_store_event @ (VerifiedEvent::SignedBatchInfo(_) | VerifiedEvent::ProofOfStoreMsg(_) @@ -1718,6 +1766,21 @@ impl EpochManager

{ Self::forward_event_to(buffered_proposal_tx, peer_id, proposal_event) .context("proposal precheck sender") }, + opt_proposal_event @ VerifiedEvent::OptProposalMsg(_) => { + if let VerifiedEvent::OptProposalMsg(p) = &opt_proposal_event { + payload_manager.prefetch_payload_data( + p.block_data().payload(), + p.proposer(), + p.timestamp_usecs(), + ); + pending_blocks + .lock() + .insert_opt_block(p.block_data().clone()); + } + + Self::forward_event_to(buffered_proposal_tx, peer_id, opt_proposal_event) + .context("proposal precheck sender") + }, round_manager_event => Self::forward_event_to( round_manager_tx, (peer_id, discriminant(&round_manager_event)), diff --git a/consensus/src/execution_pipeline.rs b/consensus/src/execution_pipeline.rs deleted file mode 100644 index d2f470841bb..00000000000 --- a/consensus/src/execution_pipeline.rs +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -#![forbid(unsafe_code)] - -use crate::{ - block_preparer::BlockPreparer, - counters::{self, log_executor_error_occurred}, - monitor, - pipeline::pipeline_phase::CountedRequest, - state_computer::StateComputeResultFut, - transaction_shuffler::TransactionShuffler, -}; -use aptos_consensus_types::{ - block::Block, pipeline_execution_result::PipelineExecutionResult, quorum_cert::QuorumCert, -}; -use aptos_crypto::HashValue; -use aptos_executor_types::{ - state_compute_result::StateComputeResult, BlockExecutorTrait, ExecutorError, ExecutorResult, -}; -use aptos_experimental_runtimes::thread_manager::optimal_min_len; -use aptos_logger::{debug, warn}; -use aptos_types::{ - block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, - block_metadata_ext::BlockMetadataExt, - transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, SignedTransaction, - }, -}; -use fail::fail_point; -use futures::{future::BoxFuture, FutureExt}; -use once_cell::sync::Lazy; -use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; -use std::{ - sync::Arc, - time::{Duration, Instant}, -}; -use tokio::sync::{mpsc, oneshot}; - -/// Smallest number of transactions Rayon should put into a single worker task. -/// Same as in execution/executor-benchmark/src/block_preparation.rs -pub const SIG_VERIFY_RAYON_MIN_THRESHOLD: usize = 32; - -pub type PreCommitHook = - Box BoxFuture<'static, ()> + Send>; - -#[allow(clippy::unwrap_used)] -pub static SIG_VERIFY_POOL: Lazy> = Lazy::new(|| { - Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(8) // More than 8 threads doesn't seem to help much - .thread_name(|index| format!("signature-checker-{}", index)) - .build() - .unwrap(), - ) -}); - -pub struct ExecutionPipeline { - prepare_block_tx: mpsc::UnboundedSender, -} - -impl ExecutionPipeline { - pub fn spawn( - executor: Arc, - runtime: &tokio::runtime::Handle, - enable_pre_commit: bool, - ) -> Self { - let (prepare_block_tx, prepare_block_rx) = mpsc::unbounded_channel(); - let (execute_block_tx, execute_block_rx) = mpsc::unbounded_channel(); - let (ledger_apply_tx, ledger_apply_rx) = mpsc::unbounded_channel(); - let (pre_commit_tx, pre_commit_rx) = mpsc::unbounded_channel(); - - runtime.spawn(Self::prepare_block_stage( - prepare_block_rx, - execute_block_tx, - )); - runtime.spawn(Self::execute_stage( - execute_block_rx, - ledger_apply_tx, - executor.clone(), - )); - runtime.spawn(Self::ledger_apply_stage( - ledger_apply_rx, - pre_commit_tx, - executor.clone(), - enable_pre_commit, - )); - runtime.spawn(Self::pre_commit_stage(pre_commit_rx, executor)); - - Self { prepare_block_tx } - } - - pub async fn queue( - &self, - block: Block, - metadata: BlockMetadataExt, - parent_block_id: HashValue, - block_qc: Option>, - txn_generator: BlockPreparer, - block_executor_onchain_config: BlockExecutorConfigFromOnchain, - pre_commit_hook: PreCommitHook, - lifetime_guard: CountedRequest<()>, - shuffler: Arc, - ) -> StateComputeResultFut { - let (result_tx, result_rx) = oneshot::channel(); - let block_id = block.id(); - self.prepare_block_tx - .send(PrepareBlockCommand { - block, - metadata, - block_executor_onchain_config, - parent_block_id, - block_preparer: txn_generator, - result_tx, - command_creation_time: Instant::now(), - pre_commit_hook, - lifetime_guard, - block_qc, - shuffler, - }) - .expect("Failed to send block to execution pipeline."); - - Box::pin(async move { - result_rx - .await - .map_err(|err| ExecutorError::InternalError { - error: format!( - "Failed to receive execution result for block {}: {:?}.", - block_id, err - ), - })? - }) - } - - async fn prepare_block( - execute_block_tx: mpsc::UnboundedSender, - command: PrepareBlockCommand, - ) { - let PrepareBlockCommand { - block, - metadata, - block_executor_onchain_config, - parent_block_id, - block_preparer, - pre_commit_hook, - result_tx, - command_creation_time, - lifetime_guard, - block_qc, - shuffler, - } = command; - counters::PREPARE_BLOCK_WAIT_TIME.observe_duration(command_creation_time.elapsed()); - debug!("prepare_block received block {}.", block.id()); - let prepare_block_result = block_preparer - .prepare_block(&block, async { block_qc }.shared()) - .await; - if let Err(e) = prepare_block_result { - result_tx - .send(Err(e)) - .unwrap_or_else(log_failed_to_send_result("prepare_block", block.id())); - return; - } - let validator_txns = block.validator_txns().cloned().unwrap_or_default(); - let (input_txns, block_gas_limit) = - prepare_block_result.expect("prepare_block must return Ok"); - let block_executor_onchain_config = - block_executor_onchain_config.with_block_gas_limit_override(block_gas_limit); - tokio::task::spawn_blocking(move || { - let txns_to_execute = - Block::combine_to_input_transactions(validator_txns, input_txns.clone(), metadata); - let sig_verification_start = Instant::now(); - let sig_verified_txns: Vec = - SIG_VERIFY_POOL.install(|| { - let num_txns = txns_to_execute.len(); - txns_to_execute - .into_par_iter() - .with_min_len(optimal_min_len(num_txns, SIG_VERIFY_RAYON_MIN_THRESHOLD)) - .map(|t| t.into()) - .collect::>() - }); - counters::PREPARE_BLOCK_SIG_VERIFICATION_TIME - .observe_duration(sig_verification_start.elapsed()); - execute_block_tx - .send(ExecuteBlockCommand { - input_txns, - block: (block.id(), sig_verified_txns).into(), - parent_block_id, - block_executor_onchain_config, - pre_commit_hook, - result_tx, - command_creation_time: Instant::now(), - lifetime_guard, - shuffler, - }) - .expect("Failed to send block to execution pipeline."); - }) - .await - .expect("Failed to spawn_blocking."); - } - - async fn prepare_block_stage( - mut prepare_block_rx: mpsc::UnboundedReceiver, - execute_block_tx: mpsc::UnboundedSender, - ) { - while let Some(command) = prepare_block_rx.recv().await { - monitor!( - "prepare_block", - Self::prepare_block(execute_block_tx.clone(), command).await - ); - } - debug!("prepare_block_stage quitting."); - } - - async fn execute_stage( - mut block_rx: mpsc::UnboundedReceiver, - ledger_apply_tx: mpsc::UnboundedSender, - executor: Arc, - ) { - while let Some(ExecuteBlockCommand { - input_txns, - block, - parent_block_id, - block_executor_onchain_config, - pre_commit_hook, - result_tx, - command_creation_time, - lifetime_guard, - shuffler: _, - }) = block_rx.recv().await - { - counters::EXECUTE_BLOCK_WAIT_TIME.observe_duration(command_creation_time.elapsed()); - let block_id = block.block_id; - debug!("execute_stage received block {}.", block_id); - let executor = executor.clone(); - let execution_time = monitor!( - "execute_block", - tokio::task::spawn_blocking(move || { - fail_point!("consensus::compute", |_| { - Err(ExecutorError::InternalError { - error: "Injected error in compute".into(), - }) - }); - let start = Instant::now(); - executor - .execute_and_update_state( - block, - parent_block_id, - block_executor_onchain_config, - ) - .map(|_| start.elapsed()) - }) - .await - ) - .expect("Failed to spawn_blocking."); - - ledger_apply_tx - .send(LedgerApplyCommand { - input_txns, - block_id, - parent_block_id, - execution_time, - pre_commit_hook, - result_tx, - command_creation_time: Instant::now(), - lifetime_guard, - }) - .expect("Failed to send block to ledger_apply stage."); - } - debug!("execute_stage quitting."); - } - - async fn ledger_apply_stage( - mut block_rx: mpsc::UnboundedReceiver, - pre_commit_tx: mpsc::UnboundedSender, - executor: Arc, - enable_pre_commit: bool, - ) { - while let Some(LedgerApplyCommand { - input_txns, - block_id, - parent_block_id, - execution_time, - pre_commit_hook, - result_tx, - command_creation_time, - lifetime_guard, - }) = block_rx.recv().await - { - counters::APPLY_LEDGER_WAIT_TIME.observe_duration(command_creation_time.elapsed()); - debug!("ledger_apply stage received block {}.", block_id); - - let res = async { - let execution_duration = execution_time?; - let executor = executor.clone(); - monitor!( - "ledger_apply", - tokio::task::spawn_blocking(move || { - executor.ledger_update(block_id, parent_block_id) - }) - .await - ) - .expect("Failed to spawn_blocking().") - .map(|output| (output, execution_duration)) - } - .await; - let pipeline_res = res.map(|(output, execution_duration)| { - let pre_commit_hook_fut = pre_commit_hook(&output); - let pre_commit_fut: BoxFuture<'static, ExecutorResult<()>> = - if output.epoch_state().is_some() || !enable_pre_commit { - // hack: it causes issue if pre-commit is finished at an epoch ending, and - // we switch to state sync, so we do the pre-commit only after we actually - // decide to commit (in the commit phase) - let executor = executor.clone(); - Box::pin(async move { - tokio::task::spawn_blocking(move || { - executor.pre_commit_block(block_id) - }) - .await - .expect("failed to spawn_blocking")?; - pre_commit_hook_fut.await; - Ok(()) - }) - } else { - // kick off pre-commit right away - let (pre_commit_result_tx, pre_commit_result_rx) = oneshot::channel(); - // schedule pre-commit - pre_commit_tx - .send(PreCommitCommand { - block_id, - pre_commit_hook_fut, - result_tx: pre_commit_result_tx, - lifetime_guard, - }) - .expect("Failed to send block to pre_commit stage."); - Box::pin(async { - pre_commit_result_rx - .await - .map_err(ExecutorError::internal_err)? - }) - }; - - PipelineExecutionResult::new(input_txns, output, execution_duration, pre_commit_fut) - }); - result_tx - .send(pipeline_res) - .unwrap_or_else(log_failed_to_send_result("ledger_apply", block_id)); - } - debug!("ledger_apply stage quitting."); - } - - async fn pre_commit_stage( - mut block_rx: mpsc::UnboundedReceiver, - executor: Arc, - ) { - while let Some(PreCommitCommand { - block_id, - pre_commit_hook_fut, - result_tx, - lifetime_guard, - }) = block_rx.recv().await - { - debug!("pre_commit stage received block {}.", block_id); - let res = async { - let executor = executor.clone(); - monitor!( - "pre_commit", - tokio::task::spawn_blocking(move || { executor.pre_commit_block(block_id) }) - ) - .await - .expect("Failed to spawn_blocking().")?; - pre_commit_hook_fut.await; - Ok(()) - } - .await; - result_tx - .send(res) - .unwrap_or_else(log_failed_to_send_result("pre_commit", block_id)); - drop(lifetime_guard); - } - debug!("pre_commit stage quitting."); - } -} - -struct PrepareBlockCommand { - block: Block, - metadata: BlockMetadataExt, - block_executor_onchain_config: BlockExecutorConfigFromOnchain, - // The parent block id. - parent_block_id: HashValue, - block_preparer: BlockPreparer, - pre_commit_hook: PreCommitHook, - result_tx: oneshot::Sender>, - command_creation_time: Instant, - lifetime_guard: CountedRequest<()>, - block_qc: Option>, - shuffler: Arc, -} - -struct ExecuteBlockCommand { - input_txns: Vec, - block: ExecutableBlock, - parent_block_id: HashValue, - block_executor_onchain_config: BlockExecutorConfigFromOnchain, - pre_commit_hook: PreCommitHook, - result_tx: oneshot::Sender>, - command_creation_time: Instant, - lifetime_guard: CountedRequest<()>, - #[allow(dead_code)] - shuffler: Arc, -} - -struct LedgerApplyCommand { - input_txns: Vec, - block_id: HashValue, - parent_block_id: HashValue, - execution_time: ExecutorResult, - pre_commit_hook: PreCommitHook, - result_tx: oneshot::Sender>, - command_creation_time: Instant, - lifetime_guard: CountedRequest<()>, -} - -struct PreCommitCommand { - block_id: HashValue, - pre_commit_hook_fut: BoxFuture<'static, ()>, - result_tx: oneshot::Sender>, - lifetime_guard: CountedRequest<()>, -} - -fn log_failed_to_send_result( - from_stage: &'static str, - block_id: HashValue, -) -> impl FnOnce(ExecutorResult) { - move |value| { - warn!( - from_stage = from_stage, - block_id = block_id, - is_err = value.is_err(), - "Failed to send back execution/pre_commit result. (rx dropped)", - ); - if let Err(e) = value { - // receive channel discarding error, log for debugging. - log_executor_error_occurred( - e, - &counters::PIPELINE_DISCARDED_EXECUTOR_ERROR_COUNT, - block_id, - false, - ); - } - } -} diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index a38b66912e1..2c831d4bc3e 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -40,8 +40,6 @@ mod rand; mod recovery_manager; mod round_manager; mod state_computer; -#[cfg(test)] -mod state_computer_tests; mod state_replication; #[cfg(any(test, feature = "fuzzing"))] mod test_utils; @@ -56,12 +54,10 @@ pub mod consensus_observer; pub mod consensus_provider; /// Required by the telemetry service pub mod counters; -mod execution_pipeline; /// AptosNet interface. pub mod network_interface; mod payload_manager; mod transaction_deduper; -mod transaction_filter; mod transaction_shuffler; #[cfg(feature = "fuzzing")] pub use transaction_shuffler::transaction_shuffler_fuzzing; diff --git a/consensus/src/liveness/proposal_generator.rs b/consensus/src/liveness/proposal_generator.rs index 355f0a18ce3..76e3c15e3f4 100644 --- a/consensus/src/liveness/proposal_generator.rs +++ b/consensus/src/liveness/proposal_generator.rs @@ -26,7 +26,8 @@ use aptos_consensus_types::{ block::Block, block_data::BlockData, common::{Author, Payload, PayloadFilter, Round}, - payload_pull_params::PayloadPullParameters, + opt_block_data::OptBlockData, + payload_pull_params::{OptQSPayloadPullParams, PayloadPullParameters}, pipelined_block::ExecutionSummary, quorum_cert::QuorumCert, utils::PayloadTxnsSize, @@ -34,9 +35,10 @@ use aptos_consensus_types::{ use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_infallible::Mutex; use aptos_logger::{error, sample, sample::SampleRate, warn}; -use aptos_types::{on_chain_config::ValidatorTxnConfig, validator_txn::ValidatorTransaction}; +use aptos_types::{ + block_info::BlockInfo, on_chain_config::ValidatorTxnConfig, validator_txn::ValidatorTransaction, +}; use aptos_validator_transaction_pool as vtxn_pool; -use futures::future::BoxFuture; use itertools::Itertools; use std::{ collections::{BTreeMap, HashSet}, @@ -405,6 +407,8 @@ pub struct ProposalGenerator { allow_batches_without_pos_in_proposal: bool, opt_qs_payload_param_provider: Arc, + + proposal_under_backpressure: Mutex, } impl ProposalGenerator { @@ -447,6 +451,7 @@ impl ProposalGenerator { vtxn_config, allow_batches_without_pos_in_proposal, opt_qs_payload_param_provider, + proposal_under_backpressure: Mutex::new(false), } } @@ -471,6 +476,14 @@ impl ProposalGenerator { Ok(Block::new_nil(round, quorum_cert, failed_authors)) } + pub fn can_propose_in_round(&self, round: Round) -> bool { + *self.last_round_generated.lock() < round + } + + pub fn is_proposal_under_backpressure(&self) -> bool { + *self.proposal_under_backpressure.lock() + } + /// The function generates a new proposal block: the returned future is fulfilled when the /// payload is delivered by the PayloadClient implementation. At most one proposal can be /// generated per round (no proposal equivocation allowed). @@ -485,16 +498,7 @@ impl ProposalGenerator { &self, round: Round, proposer_election: Arc, - wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result { - { - let mut last_round_generated = self.last_round_generated.lock(); - if *last_round_generated < round { - *last_round_generated = round; - } else { - bail!("Already proposed in the round {}", round); - } - } let maybe_optqs_payload_pull_params = self.opt_qs_payload_param_provider.get_params(); let hqc = self.ensure_highest_quorum_cert(round)?; @@ -511,120 +515,13 @@ impl ProposalGenerator { hqc.certified_block().timestamp_usecs(), ) } else { - // One needs to hold the blocks with the references to the payloads while get_block is - // being executed: pending blocks vector keeps all the pending ancestors of the extended branch. - let mut pending_blocks = self - .block_store - .path_from_commit_root(hqc.certified_block().id()) - .ok_or_else(|| format_err!("HQC {} already pruned", hqc.certified_block().id()))?; - // Avoid txn manager long poll if the root block has txns, so that the leader can - // deliver the commit proof to others without delay. - pending_blocks.push(self.block_store.commit_root()); - - // Exclude all the pending transactions: these are all the ancestors of - // parent (including) up to the root (including). - let exclude_payload: Vec<_> = pending_blocks - .iter() - .flat_map(|block| block.payload()) - .collect(); - let payload_filter = PayloadFilter::from(&exclude_payload); - - let pending_ordering = self - .block_store - .path_from_ordered_root(hqc.certified_block().id()) - .ok_or_else(|| format_err!("HQC {} already pruned", hqc.certified_block().id()))? - .iter() - .any(|block| !block.payload().map_or(true, |txns| txns.is_empty())); - - // All proposed blocks in a branch are guaranteed to have increasing timestamps - // since their predecessor block will not be added to the BlockStore until - // the local time exceeds it. - let timestamp = self.time_service.get_current_timestamp(); - - let voting_power_ratio = proposer_election.get_voting_power_participation_ratio(round); - - let ( - max_block_txns, - max_block_txns_after_filtering, - max_txns_from_block_to_execute, - block_gas_limit_override, - proposal_delay, - ) = self - .calculate_max_block_sizes(voting_power_ratio, timestamp, round) - .await; - - PROPOSER_MAX_BLOCK_TXNS_AFTER_FILTERING.observe(max_block_txns_after_filtering as f64); - if let Some(max_to_execute) = max_txns_from_block_to_execute { - PROPOSER_MAX_BLOCK_TXNS_TO_EXECUTE.observe(max_to_execute as f64); - } - - PROPOSER_DELAY_PROPOSAL.observe(proposal_delay.as_secs_f64()); - if !proposal_delay.is_zero() { - tokio::time::sleep(proposal_delay).await; - } - - let max_pending_block_size = pending_blocks - .iter() - .map(|block| { - block.payload().map_or(PayloadTxnsSize::zero(), |p| { - PayloadTxnsSize::new(p.len() as u64, p.size() as u64) - }) - }) - .reduce(PayloadTxnsSize::maximum) - .unwrap_or_default(); - // Use non-backpressure reduced values for computing fill_fraction - let max_fill_fraction = - (max_pending_block_size.count() as f32 / self.max_block_txns.count() as f32).max( - max_pending_block_size.size_in_bytes() as f32 - / self.max_block_txns.size_in_bytes() as f32, - ); - PROPOSER_PENDING_BLOCKS_COUNT.set(pending_blocks.len() as i64); - PROPOSER_PENDING_BLOCKS_FILL_FRACTION.set(max_fill_fraction as f64); - - let pending_validator_txn_hashes: HashSet = pending_blocks - .iter() - .filter_map(|block| block.validator_txns()) - .flatten() - .map(ValidatorTransaction::hash) - .collect(); - let validator_txn_filter = - vtxn_pool::TransactionFilter::PendingTxnHashSet(pending_validator_txn_hashes); - - let (validator_txns, mut payload) = self - .payload_client - .pull_payload( - PayloadPullParameters { - max_poll_time: self.quorum_store_poll_time.saturating_sub(proposal_delay), - max_txns: max_block_txns, - max_txns_after_filtering: max_block_txns_after_filtering, - soft_max_txns_after_filtering: max_txns_from_block_to_execute - .unwrap_or(max_block_txns_after_filtering), - max_inline_txns: self.max_inline_txns, - maybe_optqs_payload_pull_params, - user_txn_filter: payload_filter, - pending_ordering, - pending_uncommitted_blocks: pending_blocks.len(), - recent_max_fill_fraction: max_fill_fraction, - block_timestamp: timestamp, - }, - validator_txn_filter, - wait_callback, - ) - .await - .context("Fail to retrieve payload")?; - - if !payload.is_direct() - && max_txns_from_block_to_execute.is_some() - && max_txns_from_block_to_execute.is_some_and(|v| payload.len() as u64 > v) - { - payload = payload.transform_to_quorum_store_v2( - max_txns_from_block_to_execute, - block_gas_limit_override, - ); - } else if block_gas_limit_override.is_some() { - payload = payload.transform_to_quorum_store_v2(None, block_gas_limit_override); - } - (validator_txns, payload, timestamp.as_micros() as u64) + self.generate_proposal_inner( + round, + hqc.certified_block().id(), + proposer_election.clone(), + maybe_optqs_payload_pull_params, + ) + .await? }; let quorum_cert = hqc.as_ref().clone(); @@ -659,6 +556,187 @@ impl ProposalGenerator { Ok(block) } + async fn generate_proposal_inner( + &self, + round: Round, + parent_id: HashValue, + proposer_election: Arc, + maybe_optqs_payload_pull_params: Option, + ) -> anyhow::Result<(Vec, Payload, u64)> { + { + let mut last_round_generated = self.last_round_generated.lock(); + if *last_round_generated < round { + *last_round_generated = round; + } else { + bail!("Already proposed in the round {}", round); + } + } + // One needs to hold the blocks with the references to the payloads while get_block is + // being executed: pending blocks vector keeps all the pending ancestors of the extended branch. + let mut pending_blocks = self + .block_store + .path_from_commit_root(parent_id) + .ok_or_else(|| format_err!("Parent block {} already pruned", parent_id))?; + // Avoid txn manager long poll if the root block has txns, so that the leader can + // deliver the commit proof to others without delay. + pending_blocks.push(self.block_store.commit_root()); + + // Exclude all the pending transactions: these are all the ancestors of + // parent (including) up to the root (including). + let exclude_payload: Vec<_> = pending_blocks + .iter() + .flat_map(|block| block.payload()) + .collect(); + let payload_filter = PayloadFilter::from(&exclude_payload); + + let pending_ordering = self + .block_store + .path_from_ordered_root(parent_id) + .ok_or_else(|| format_err!("Parent block {} already pruned", parent_id))? + .iter() + .any(|block| !block.payload().is_none_or(|txns| txns.is_empty())); + + // All proposed blocks in a branch are guaranteed to have increasing timestamps + // since their predecessor block will not be added to the BlockStore until + // the local time exceeds it. + let timestamp = self.time_service.get_current_timestamp(); + + let voting_power_ratio = proposer_election.get_voting_power_participation_ratio(round); + + let ( + max_block_txns, + max_block_txns_after_filtering, + max_txns_from_block_to_execute, + block_gas_limit_override, + proposal_delay, + ) = self + .calculate_max_block_sizes(voting_power_ratio, timestamp, round) + .await; + + PROPOSER_MAX_BLOCK_TXNS_AFTER_FILTERING.observe(max_block_txns_after_filtering as f64); + if let Some(max_to_execute) = max_txns_from_block_to_execute { + PROPOSER_MAX_BLOCK_TXNS_TO_EXECUTE.observe(max_to_execute as f64); + } + + PROPOSER_DELAY_PROPOSAL.observe(proposal_delay.as_secs_f64()); + if !proposal_delay.is_zero() { + tokio::time::sleep(proposal_delay).await; + } + + let max_pending_block_size = pending_blocks + .iter() + .map(|block| { + block.payload().map_or(PayloadTxnsSize::zero(), |p| { + PayloadTxnsSize::new(p.len() as u64, p.size() as u64) + }) + }) + .reduce(PayloadTxnsSize::maximum) + .unwrap_or_default(); + // Use non-backpressure reduced values for computing fill_fraction + let max_fill_fraction = + (max_pending_block_size.count() as f32 / self.max_block_txns.count() as f32).max( + max_pending_block_size.size_in_bytes() as f32 + / self.max_block_txns.size_in_bytes() as f32, + ); + PROPOSER_PENDING_BLOCKS_COUNT.set(pending_blocks.len() as i64); + PROPOSER_PENDING_BLOCKS_FILL_FRACTION.set(max_fill_fraction as f64); + + let pending_validator_txn_hashes: HashSet = pending_blocks + .iter() + .filter_map(|block| block.validator_txns()) + .flatten() + .map(ValidatorTransaction::hash) + .collect(); + let validator_txn_filter = + vtxn_pool::TransactionFilter::PendingTxnHashSet(pending_validator_txn_hashes); + + let (validator_txns, mut payload) = self + .payload_client + .pull_payload( + PayloadPullParameters { + max_poll_time: self.quorum_store_poll_time.saturating_sub(proposal_delay), + max_txns: max_block_txns, + max_txns_after_filtering: max_block_txns_after_filtering, + soft_max_txns_after_filtering: max_txns_from_block_to_execute + .unwrap_or(max_block_txns_after_filtering), + max_inline_txns: self.max_inline_txns, + maybe_optqs_payload_pull_params, + user_txn_filter: payload_filter, + pending_ordering, + pending_uncommitted_blocks: pending_blocks.len(), + recent_max_fill_fraction: max_fill_fraction, + block_timestamp: timestamp, + }, + validator_txn_filter, + ) + .await + .context("Fail to retrieve payload")?; + + if !payload.is_direct() + && max_txns_from_block_to_execute.is_some() + && max_txns_from_block_to_execute.is_some_and(|v| payload.len() as u64 > v) + { + payload = payload.transform_to_quorum_store_v2( + max_txns_from_block_to_execute, + block_gas_limit_override, + ); + } else if block_gas_limit_override.is_some() { + payload = payload.transform_to_quorum_store_v2(None, block_gas_limit_override); + } + Ok((validator_txns, payload, timestamp.as_micros() as u64)) + } + + pub async fn generate_opt_proposal( + &self, + epoch: u64, + round: Round, + parent: BlockInfo, + grandparent_qc: QuorumCert, + proposer_election: Arc, + ) -> anyhow::Result { + let maybe_optqs_payload_pull_params = self.opt_qs_payload_param_provider.get_params(); + + let hqc = self.ensure_highest_quorum_cert(round)?; + + ensure!( + hqc.certified_block().round() + 2 == round, + "[OptProposal] Given round {} is not equal to hqc round {} + 2, should generate regular proposal instead of optimistic", + round, + hqc.certified_block().round() + ); + + let (validator_txns, payload, timestamp) = if hqc.certified_block().has_reconfiguration() { + bail!("[OptProposal] HQC has reconfiguration!"); + } else { + self.generate_proposal_inner( + round, + parent.id(), + proposer_election, + maybe_optqs_payload_pull_params, + ) + .await? + }; + + let validator_txns = if self.vtxn_config.enabled() { + validator_txns + } else { + vec![] + }; + + let block = OptBlockData::new( + validator_txns, + payload, + self.author, + epoch, + round, + timestamp, + parent, + grandparent_qc, + ); + + Ok(block) + } + async fn calculate_max_block_sizes( &self, voting_power_ratio: f64, @@ -775,6 +853,8 @@ impl ProposalGenerator { "Proposal generation backpressure details", ); + *self.proposal_under_backpressure.lock() = !proposal_delay.is_zero(); + ( max_block_size, max_block_txns_after_filtering, diff --git a/consensus/src/liveness/proposal_generator_test.rs b/consensus/src/liveness/proposal_generator_test.rs index d4099030572..934061b9ff0 100644 --- a/consensus/src/liveness/proposal_generator_test.rs +++ b/consensus/src/liveness/proposal_generator_test.rs @@ -22,15 +22,10 @@ use aptos_consensus_types::{ utils::PayloadTxnsSize, }; use aptos_types::{on_chain_config::ValidatorTxnConfig, validator_signer::ValidatorSigner}; -use futures::{future::BoxFuture, FutureExt}; use std::{sync::Arc, time::Duration}; const MAX_BLOCK_GAS_LIMIT: u64 = 30_000; -fn empty_callback() -> BoxFuture<'static, ()> { - async move {}.boxed() -} - struct MockOptQSPayloadProvider {} impl TOptQSPullParamsProvider for MockOptQSPayloadProvider { @@ -69,7 +64,7 @@ async fn test_proposal_generation_empty_tree() { // Generate proposals for an empty tree. let proposal_data = proposal_generator - .generate_proposal(1, proposer_election.clone(), empty_callback()) + .generate_proposal(1, proposer_election.clone()) .await .unwrap(); let proposal = Block::new_proposal_from_block_data(proposal_data, &signer).unwrap(); @@ -80,7 +75,7 @@ async fn test_proposal_generation_empty_tree() { // Duplicate proposals on the same round are not allowed let proposal_err = proposal_generator - .generate_proposal(1, proposer_election.clone(), empty_callback()) + .generate_proposal(1, proposer_election.clone()) .await .err(); assert!(proposal_err.is_some()); @@ -121,7 +116,7 @@ async fn test_proposal_generation_parent() { .await; let original_res = proposal_generator - .generate_proposal(10, proposer_election.clone(), empty_callback()) + .generate_proposal(10, proposer_election.clone()) .await .unwrap(); // With no certifications the parent is genesis @@ -135,7 +130,7 @@ async fn test_proposal_generation_parent() { // Once a1 is certified, it should be the one to choose from inserter.insert_qc_for_block(a1.as_ref(), None); let a1_child_res = proposal_generator - .generate_proposal(11, proposer_election.clone(), empty_callback()) + .generate_proposal(11, proposer_election.clone()) .await .unwrap(); assert_eq!(a1_child_res.parent_id(), a1.id()); @@ -150,7 +145,7 @@ async fn test_proposal_generation_parent() { // Once b1 is certified, it should be the one to choose from inserter.insert_qc_for_block(b1.as_ref(), None); let b1_child_res = proposal_generator - .generate_proposal(15, proposer_election.clone(), empty_callback()) + .generate_proposal(15, proposer_election.clone()) .await .unwrap(); assert_eq!(b1_child_res.parent_id(), b1.id()); @@ -196,7 +191,7 @@ async fn test_old_proposal_generation() { inserter.insert_qc_for_block(a1.as_ref(), None); let proposal_err = proposal_generator - .generate_proposal(1, proposer_election.clone(), empty_callback()) + .generate_proposal(1, proposer_election.clone()) .await .err(); assert!(proposal_err.is_some()); @@ -234,7 +229,7 @@ async fn test_correct_failed_authors() { let genesis = block_store.ordered_root(); let result = proposal_generator - .generate_proposal(6, proposer_election.clone(), empty_callback()) + .generate_proposal(6, proposer_election.clone()) .await .unwrap(); // With no certifications the parent is genesis diff --git a/consensus/src/logging.rs b/consensus/src/logging.rs index a6eb19cfc65..e8308eabcd7 100644 --- a/consensus/src/logging.rs +++ b/consensus/src/logging.rs @@ -58,6 +58,11 @@ pub enum LogEvent { // randomness fast path BroadcastRandShareFastPath, ReceiveRandShareFastPath, + // optimistic proposal + OptPropose, + NetworkReceiveOptProposal, + ReceiveOptProposal, + ProcessOptProposal, } impl LogSchema { diff --git a/consensus/src/network.rs b/consensus/src/network.rs index 3a57d55b6d3..214fc50a14e 100644 --- a/consensus/src/network.rs +++ b/consensus/src/network.rs @@ -25,9 +25,12 @@ use aptos_config::network_id::NetworkId; use aptos_consensus_types::{ block_retrieval::{BlockRetrievalRequest, BlockRetrievalRequestV1, BlockRetrievalResponse}, common::Author, + opt_proposal_msg::OptProposalMsg, order_vote_msg::OrderVoteMsg, pipeline::{commit_decision::CommitDecision, commit_vote::CommitVote}, - proof_of_store::{ProofOfStore, ProofOfStoreMsg, SignedBatchInfo, SignedBatchInfoMsg}, + proof_of_store::{ + BatchInfo, ProofOfStore, ProofOfStoreMsg, SignedBatchInfo, SignedBatchInfoMsg, + }, proposal_msg::ProposalMsg, round_timeout::RoundTimeoutMsg, sync_info::SyncInfo, @@ -201,15 +204,18 @@ pub trait QuorumStoreSender: Send + Clone { async fn send_signed_batch_info_msg( &self, - signed_batch_infos: Vec, + signed_batch_infos: Vec>, recipients: Vec, ); async fn broadcast_batch_msg(&mut self, batches: Vec); - async fn broadcast_proof_of_store_msg(&mut self, proof_of_stores: Vec); + async fn broadcast_proof_of_store_msg(&mut self, proof_of_stores: Vec>); - async fn send_proof_of_store_msg_to_self(&mut self, proof_of_stores: Vec); + async fn send_proof_of_store_msg_to_self( + &mut self, + proof_of_stores: Vec>, + ); } /// Implements the actual networking support for all consensus messaging. @@ -406,6 +412,12 @@ impl NetworkSender { self.broadcast(msg).await } + pub async fn broadcast_opt_proposal(&self, proposal_msg: OptProposalMsg) { + fail_point!("consensus::send::broadcast_opt_proposal", |_| ()); + let msg = ConsensusMsg::OptProposalMsg(Box::new(proposal_msg)); + self.broadcast(msg).await + } + pub async fn broadcast_sync_info(&self, sync_info_msg: SyncInfo) { fail_point!("consensus::send::broadcast_sync_info", |_| ()); let msg = ConsensusMsg::SyncInfo(Box::new(sync_info_msg)); @@ -455,6 +467,12 @@ impl NetworkSender { self.broadcast(msg).await } + pub async fn broadcast_commit_vote(&self, commit_vote_msg: CommitVote) { + fail_point!("consensus::send::commit_vote", |_| ()); + let msg = ConsensusMsg::CommitVoteMsg(Box::new(commit_vote_msg)); + self.broadcast(msg).await + } + pub async fn broadcast_fast_share(&self, share: FastShare) { fail_point!("consensus::send::broadcast_share", |_| ()); let msg = tokio::task::spawn_blocking(|| { @@ -543,7 +561,7 @@ impl QuorumStoreSender for NetworkSender { async fn send_signed_batch_info_msg( &self, - signed_batch_infos: Vec, + signed_batch_infos: Vec>, recipients: Vec, ) { fail_point!("consensus::send::signed_batch_info", |_| ()); @@ -558,13 +576,13 @@ impl QuorumStoreSender for NetworkSender { self.broadcast(msg).await } - async fn broadcast_proof_of_store_msg(&mut self, proofs: Vec) { + async fn broadcast_proof_of_store_msg(&mut self, proofs: Vec>) { fail_point!("consensus::send::proof_of_store", |_| ()); let msg = ConsensusMsg::ProofOfStoreMsg(Box::new(ProofOfStoreMsg::new(proofs))); self.broadcast(msg).await } - async fn send_proof_of_store_msg_to_self(&mut self, proofs: Vec) { + async fn send_proof_of_store_msg_to_self(&mut self, proofs: Vec>) { fail_point!("consensus::send::proof_of_store", |_| ()); let msg = ConsensusMsg::ProofOfStoreMsg(Box::new(ProofOfStoreMsg::new(proofs))); self.send(msg, vec![self.author]).await @@ -793,6 +811,7 @@ impl NetworkTask { }; }, consensus_msg @ (ConsensusMsg::ProposalMsg(_) + | ConsensusMsg::OptProposalMsg(_) | ConsensusMsg::VoteMsg(_) | ConsensusMsg::RoundTimeoutMsg(_) | ConsensusMsg::OrderVoteMsg(_) @@ -811,6 +830,23 @@ impl NetworkTask { block_hash = proposal.proposal().id(), ); } + if let ConsensusMsg::OptProposalMsg(proposal) = &consensus_msg { + observe_block( + proposal.timestamp_usecs(), + BlockStage::NETWORK_RECEIVED, + ); + observe_block( + proposal.timestamp_usecs(), + BlockStage::NETWORK_RECEIVED_OPT_PROPOSAL, + ); + info!( + LogSchema::new(LogEvent::NetworkReceiveOptProposal) + .remote_peer(peer_id), + block_author = proposal.proposer(), + block_epoch = proposal.epoch(), + block_round = proposal.round(), + ); + } Self::push_msg(peer_id, consensus_msg, &self.consensus_messages_tx); }, // TODO: get rid of the rpc dummy value diff --git a/consensus/src/network_interface.rs b/consensus/src/network_interface.rs index e7d351895bd..04add8da598 100644 --- a/consensus/src/network_interface.rs +++ b/consensus/src/network_interface.rs @@ -14,9 +14,10 @@ use aptos_config::network_id::{NetworkId, PeerNetworkId}; use aptos_consensus_types::{ block_retrieval::{BlockRetrievalRequest, BlockRetrievalRequestV1, BlockRetrievalResponse}, epoch_retrieval::EpochRetrievalRequest, + opt_proposal_msg::OptProposalMsg, order_vote_msg::OrderVoteMsg, pipeline::{commit_decision::CommitDecision, commit_vote::CommitVote}, - proof_of_store::{ProofOfStoreMsg, SignedBatchInfoMsg}, + proof_of_store::{BatchInfo, ProofOfStoreMsg, SignedBatchInfoMsg}, proposal_msg::ProposalMsg, round_timeout::RoundTimeoutMsg, sync_info::SyncInfo, @@ -70,9 +71,9 @@ pub enum ConsensusMsg { BatchResponse(Box), /// Quorum Store: Send a signed batch digest. This is a vote for the batch and a promise that /// the batch of transactions was received and will be persisted until batch expiration. - SignedBatchInfo(Box), + SignedBatchInfo(Box>), /// Quorum Store: Broadcast a certified proof of store (a digest that received 2f+1 votes). - ProofOfStoreMsg(Box), + ProofOfStoreMsg(Box>), /// DAG protocol message DAGMessage(DAGNetworkMessage), /// Commit message @@ -88,6 +89,8 @@ pub enum ConsensusMsg { RoundTimeoutMsg(Box), /// RPC to get a chain of block of the given length starting from the given block id, using epoch and round. BlockRetrievalRequest(Box), + /// OptProposalMsg contains the optimistic proposal and sync info. + OptProposalMsg(Box), } /// Network type for consensus @@ -100,6 +103,7 @@ impl ConsensusMsg { ConsensusMsg::BlockRetrievalResponse(_) => "BlockRetrievalResponse", ConsensusMsg::EpochRetrievalRequest(_) => "EpochRetrievalRequest", ConsensusMsg::ProposalMsg(_) => "ProposalMsg", + ConsensusMsg::OptProposalMsg(_) => "OptProposalMsg", ConsensusMsg::SyncInfo(_) => "SyncInfo", ConsensusMsg::EpochChangeProof(_) => "EpochChangeProof", ConsensusMsg::VoteMsg(_) => "VoteMsg", diff --git a/consensus/src/payload_client/mixed.rs b/consensus/src/payload_client/mixed.rs index afc981ab4a3..bb9c38c80cc 100644 --- a/consensus/src/payload_client/mixed.rs +++ b/consensus/src/payload_client/mixed.rs @@ -12,7 +12,6 @@ use aptos_logger::debug; use aptos_types::{on_chain_config::ValidatorTxnConfig, validator_txn::ValidatorTransaction}; use aptos_validator_transaction_pool::TransactionFilter; use fail::fail_point; -use futures::future::BoxFuture; use std::{cmp::min, sync::Arc, time::Instant}; pub struct MixedPayloadClient { @@ -60,7 +59,6 @@ impl PayloadClient for MixedPayloadClient { &self, params: PayloadPullParameters, validator_txn_filter: TransactionFilter, - wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result<(Vec, Payload), QuorumStoreError> { // Pull validator txns first. let validator_txn_pull_timer = Instant::now(); @@ -100,10 +98,7 @@ impl PayloadClient for MixedPayloadClient { .saturating_sub(validator_txn_pull_timer.elapsed()); // Pull user payload. - let user_payload = self - .user_payload_client - .pull(user_txn_pull_params, wait_callback) - .await?; + let user_payload = self.user_payload_client.pull(user_txn_pull_params).await?; Ok((validator_txns, user_payload)) } @@ -159,7 +154,6 @@ mod tests { aptos_infallible::duration_since_epoch(), ), vtxn_pool::TransactionFilter::PendingTxnHashSet(HashSet::new()), - Box::pin(async {}), ) .await .unwrap() @@ -187,7 +181,6 @@ mod tests { aptos_infallible::duration_since_epoch(), ), vtxn_pool::TransactionFilter::PendingTxnHashSet(HashSet::new()), - Box::pin(async {}), ) .await .unwrap() @@ -215,7 +208,6 @@ mod tests { aptos_infallible::duration_since_epoch(), ), vtxn_pool::TransactionFilter::PendingTxnHashSet(HashSet::new()), - Box::pin(async {}), ) .await .unwrap() @@ -243,7 +235,6 @@ mod tests { aptos_infallible::duration_since_epoch(), ), vtxn_pool::TransactionFilter::PendingTxnHashSet(HashSet::new()), - Box::pin(async {}), ) .await .unwrap() @@ -289,7 +280,6 @@ mod tests { aptos_infallible::duration_since_epoch(), ), vtxn_pool::TransactionFilter::PendingTxnHashSet(HashSet::new()), - Box::pin(async {}), ) .await .unwrap() diff --git a/consensus/src/payload_client/mod.rs b/consensus/src/payload_client/mod.rs index e38ba319432..716687f6897 100644 --- a/consensus/src/payload_client/mod.rs +++ b/consensus/src/payload_client/mod.rs @@ -5,7 +5,6 @@ use crate::error::QuorumStoreError; use aptos_consensus_types::{common::Payload, payload_pull_params::PayloadPullParameters}; use aptos_types::validator_txn::ValidatorTransaction; use aptos_validator_transaction_pool::TransactionFilter; -use futures::future::BoxFuture; pub mod mixed; pub mod user; @@ -17,6 +16,5 @@ pub trait PayloadClient: Send + Sync { &self, config: PayloadPullParameters, validator_txn_filter: TransactionFilter, - wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result<(Vec, Payload), QuorumStoreError>; } diff --git a/consensus/src/payload_client/user/mod.rs b/consensus/src/payload_client/user/mod.rs index e3f2ca8acba..57fd99a174b 100644 --- a/consensus/src/payload_client/user/mod.rs +++ b/consensus/src/payload_client/user/mod.rs @@ -5,7 +5,6 @@ use crate::error::QuorumStoreError; use aptos_consensus_types::{common::Payload, payload_pull_params::PayloadPullParameters}; #[cfg(test)] use aptos_types::transaction::SignedTransaction; -use futures::future::BoxFuture; #[cfg(test)] use std::time::Duration; #[cfg(test)] @@ -18,7 +17,6 @@ pub trait UserPayloadClient: Send + Sync { async fn pull( &self, params: PayloadPullParameters, - wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result; } @@ -41,7 +39,6 @@ impl UserPayloadClient for DummyClient { async fn pull( &self, mut params: PayloadPullParameters, - _wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result { use aptos_consensus_types::utils::PayloadTxnsSize; diff --git a/consensus/src/payload_client/user/quorum_store_client.rs b/consensus/src/payload_client/user/quorum_store_client.rs index c8c541208c8..74a91fbf9b1 100644 --- a/consensus/src/payload_client/user/quorum_store_client.rs +++ b/consensus/src/payload_client/user/quorum_store_client.rs @@ -13,7 +13,6 @@ use aptos_consensus_types::{ }; use aptos_logger::info; use fail::fail_point; -use futures::future::BoxFuture; use futures_channel::{mpsc, oneshot}; use std::time::{Duration, Instant}; use tokio::time::{sleep, timeout}; @@ -93,7 +92,6 @@ impl UserPayloadClient for QuorumStoreClient { async fn pull( &self, params: PayloadPullParameters, - wait_callback: BoxFuture<'static, ()>, ) -> anyhow::Result { let return_non_full = params.recent_max_fill_fraction < self.wait_for_full_blocks_above_recent_fill_threshold @@ -105,7 +103,6 @@ impl UserPayloadClient for QuorumStoreClient { fail_point!("consensus::pull_payload", |_| { Err(anyhow::anyhow!("Injected error in pull_payload").into()) }); - let mut callback_wrapper = Some(wait_callback); // keep polling QuorumStore until there's payloads available or there's still pending payloads let start_time = Instant::now(); @@ -125,9 +122,6 @@ impl UserPayloadClient for QuorumStoreClient { ) .await?; if payload.is_empty() && !return_empty && !done { - if let Some(callback) = callback_wrapper.take() { - callback.await; - } sleep(Duration::from_millis(NO_TXN_DELAY)).await; continue; } diff --git a/consensus/src/payload_manager/co_payload_manager.rs b/consensus/src/payload_manager/co_payload_manager.rs index 358fa7f90bd..590afda4ef5 100644 --- a/consensus/src/payload_manager/co_payload_manager.rs +++ b/consensus/src/payload_manager/co_payload_manager.rs @@ -10,6 +10,7 @@ use crate::{ payload_manager::TPayloadManager, }; use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::{Author, Payload, Round}, @@ -97,6 +98,14 @@ impl TPayloadManager for ConsensusObserverPayloadManager { fn prefetch_payload_data(&self, _payload: &Payload, _author: Author, _timestamp: u64) {} + fn check_denied_inline_transactions( + &self, + _block: &Block, + _block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()> { + Ok(()) // Consensus observer doesn't filter transactions + } + fn check_payload_availability(&self, _block: &Block) -> Result<(), BitVec> { unreachable!("this method isn't used in ConsensusObserver") } diff --git a/consensus/src/payload_manager/direct_mempool_payload_manager.rs b/consensus/src/payload_manager/direct_mempool_payload_manager.rs index 1d3b8b6220a..08130e459b2 100644 --- a/consensus/src/payload_manager/direct_mempool_payload_manager.rs +++ b/consensus/src/payload_manager/direct_mempool_payload_manager.rs @@ -3,6 +3,7 @@ use crate::payload_manager::TPayloadManager; use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::{Author, Payload}, @@ -26,6 +27,48 @@ impl TPayloadManager for DirectMempoolPayloadManager { fn prefetch_payload_data(&self, _payload: &Payload, _author: Author, _timestamp: u64) {} + fn check_denied_inline_transactions( + &self, + block: &Block, + block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()> { + // If the filter is disabled, return early + if !block_txn_filter_config.is_enabled() { + return Ok(()); + } + + // Get the inline transactions for the block proposal. Note: all + // transactions in a direct mempool payload are inline transactions. + let (inline_transactions, _, _) = get_transactions_from_block(block)?; + if inline_transactions.is_empty() { + return Ok(()); + } + + // Fetch the block metadata + let block_id = block.id(); + let block_author = block.author(); + let block_epoch = block.epoch(); + let block_timestamp = block.timestamp_usecs(); + + // Identify any denied inline transactions + let block_transaction_filter = block_txn_filter_config.block_transaction_filter(); + let denied_inline_transactions = block_transaction_filter.get_denied_block_transactions( + block_id, + block_author, + block_epoch, + block_timestamp, + inline_transactions, + ); + if !denied_inline_transactions.is_empty() { + return Err(anyhow::anyhow!( + "Inline transactions for DirectMempoolPayload denied by block transaction filter: {:?}", + denied_inline_transactions + )); + } + + Ok(()) // No transactions were denied + } + fn check_payload_availability(&self, _block: &Block) -> Result<(), BitVec> { Ok(()) } @@ -35,19 +78,26 @@ impl TPayloadManager for DirectMempoolPayloadManager { block: &Block, _block_signers: Option, ) -> ExecutorResult<(Vec, Option, Option)> { - let Some(payload) = block.payload() else { - return Ok((Vec::new(), None, None)); - }; - - match payload { - Payload::DirectMempool(txns) => Ok((txns.clone(), None, None)), - _ => unreachable!( - "DirectMempoolPayloadManager: Unacceptable payload type {}. Epoch: {}, Round: {}, Block: {}", - payload, - block.block_data().epoch(), - block.block_data().round(), - block.id() - ), - } + get_transactions_from_block(block) + } +} + +/// Returns the direct mempool transactions from a block's payload. +fn get_transactions_from_block( + block: &Block, +) -> ExecutorResult<(Vec, Option, Option)> { + let Some(payload) = block.payload() else { + return Ok((Vec::new(), None, None)); + }; + + match payload { + Payload::DirectMempool(txns) => Ok((txns.clone(), None, None)), + _ => unreachable!( + "DirectMempoolPayloadManager: Unacceptable payload type {}. Epoch: {}, Round: {}, Block: {}", + payload, + block.block_data().epoch(), + block.block_data().round(), + block.id() + ), } } diff --git a/consensus/src/payload_manager/mod.rs b/consensus/src/payload_manager/mod.rs index 537fc8563b4..1aedb806563 100644 --- a/consensus/src/payload_manager/mod.rs +++ b/consensus/src/payload_manager/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::{Author, Payload}, @@ -16,6 +17,8 @@ mod quorum_store_payload_manager; pub use co_payload_manager::ConsensusObserverPayloadManager; pub use direct_mempool_payload_manager::DirectMempoolPayloadManager; +#[cfg(test)] +pub use quorum_store_payload_manager::TQuorumStoreCommitNotifier; pub use quorum_store_payload_manager::{QuorumStoreCommitNotifier, QuorumStorePayloadManager}; /// A trait that defines the interface for a payload manager. The payload manager is responsible for @@ -30,6 +33,15 @@ pub trait TPayloadManager: Send + Sync { /// available when block is executed. fn prefetch_payload_data(&self, payload: &Payload, author: Author, timestamp: u64); + /// Check if the block contains any inline transactions that need + /// to be denied (e.g., due to block transaction filtering). + /// This is only used when processing block proposals. + fn check_denied_inline_transactions( + &self, + block: &Block, + block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()>; + /// Check if the transactions corresponding are available. This is specific to payload /// manager implementations. For optimistic quorum store, we only check if optimistic /// batches are available locally. diff --git a/consensus/src/payload_manager/quorum_store_payload_manager.rs b/consensus/src/payload_manager/quorum_store_payload_manager.rs index 0aa3950a08b..f655eda0ba2 100644 --- a/consensus/src/payload_manager/quorum_store_payload_manager.rs +++ b/consensus/src/payload_manager/quorum_store_payload_manager.rs @@ -11,6 +11,7 @@ use crate::{ quorum_store::{batch_store::BatchReader, quorum_store_coordinator::CoordinatorCommand}, }; use aptos_bitvec::BitVec; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_types::{ block::Block, common::{Author, Payload, ProofWithData}, @@ -289,6 +290,47 @@ impl TPayloadManager for QuorumStorePayloadManager { }; } + fn check_denied_inline_transactions( + &self, + block: &Block, + block_txn_filter_config: &BlockTransactionFilterConfig, + ) -> anyhow::Result<()> { + // If the filter is disabled, return early + if !block_txn_filter_config.is_enabled() { + return Ok(()); + } + + // Get the inline transactions for the block proposal + let inline_transactions = get_inline_transactions(block); + if inline_transactions.is_empty() { + return Ok(()); + } + + // Fetch the block metadata + let block_id = block.id(); + let block_author = block.author(); + let block_epoch = block.epoch(); + let block_timestamp = block.timestamp_usecs(); + + // Identify any denied inline transactions + let block_transaction_filter = block_txn_filter_config.block_transaction_filter(); + let denied_inline_transactions = block_transaction_filter.get_denied_block_transactions( + block_id, + block_author, + block_epoch, + block_timestamp, + inline_transactions, + ); + if !denied_inline_transactions.is_empty() { + return Err(anyhow::anyhow!( + "Inline transactions for QuorumStorePayload denied by block transaction filter: {:?}", + denied_inline_transactions + )); + } + + Ok(()) // No transactions were denied + } + fn check_payload_availability(&self, block: &Block) -> Result<(), BitVec> { let Some(payload) = block.payload() else { return Ok(()); @@ -457,6 +499,7 @@ impl TPayloadManager for QuorumStorePayloadManager { all_txns, opt_qs_payload.proof_with_data().deref().clone(), opt_qs_payload.max_txns_to_execute(), + opt_qs_payload.block_gas_limit(), [ opt_qs_payload.opt_batches().deref().clone(), opt_qs_payload.inline_batches().batch_infos(), @@ -489,6 +532,36 @@ impl TPayloadManager for QuorumStorePayloadManager { } } +/// Extracts and returns all inline transactions from the payload in the given block +fn get_inline_transactions(block: &Block) -> Vec { + // If the block has no payload, return an empty vector + let Some(payload) = block.payload() else { + return vec![]; + }; + + // Fetch the inline transactions from the payload + match payload { + Payload::QuorumStoreInlineHybrid(inline_batches, ..) => { + // Flatten the inline batches and return the transactions + inline_batches + .iter() + .flat_map(|(_batch_info, txns)| txns.clone()) + .collect() + }, + Payload::QuorumStoreInlineHybridV2(inline_batches, ..) => { + // Flatten the inline batches and return the transactions + inline_batches + .iter() + .flat_map(|(_batch_info, txns)| txns.clone()) + .collect() + }, + Payload::OptQuorumStore(opt_qs_payload) => opt_qs_payload.inline_batches().transactions(), + _ => { + vec![] // Other payload types do not have inline transactions + }, + } +} + async fn process_optqs_payload( data_ptr: &BatchPointer, batch_reader: Arc, diff --git a/consensus/src/pipeline/buffer.rs b/consensus/src/pipeline/buffer.rs index ed4514bd20d..e9e4a0c9a43 100644 --- a/consensus/src/pipeline/buffer.rs +++ b/consensus/src/pipeline/buffer.rs @@ -114,7 +114,7 @@ impl Buffer { } pub fn exist(&self, cursor: &Cursor) -> bool { - cursor.map_or(false, |key| self.map.contains_key(&key)) + cursor.is_some_and(|key| self.map.contains_key(&key)) } /// find_elem returns the first item non-prior to `cursor` that compare(item) is true diff --git a/consensus/src/pipeline/buffer_item.rs b/consensus/src/pipeline/buffer_item.rs index 6840b26e43d..bb263f737b6 100644 --- a/consensus/src/pipeline/buffer_item.rs +++ b/consensus/src/pipeline/buffer_item.rs @@ -2,9 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{ - counters, pipeline::hashable::Hashable, state_replication::StateComputerCommitCallBackType, -}; +use crate::{counters, pipeline::hashable::Hashable}; use anyhow::anyhow; use aptos_consensus_types::{ common::{Author, Round}, @@ -61,7 +59,6 @@ pub struct OrderedItem { // This can happen in the fast forward sync path, where we can receive the commit proof // from peers. pub commit_proof: Option, - pub callback: StateComputerCommitCallBackType, pub ordered_blocks: Vec>, pub ordered_proof: LedgerInfoWithSignatures, } @@ -69,7 +66,6 @@ pub struct OrderedItem { pub struct ExecutedItem { pub executed_blocks: Vec>, pub partial_commit_proof: SignatureAggregator, - pub callback: StateComputerCommitCallBackType, pub commit_info: BlockInfo, pub ordered_proof: LedgerInfoWithSignatures, } @@ -77,7 +73,6 @@ pub struct ExecutedItem { pub struct SignedItem { pub executed_blocks: Vec>, pub partial_commit_proof: SignatureAggregator, - pub callback: StateComputerCommitCallBackType, pub commit_vote: CommitVote, pub rb_handle: Option<(Instant, DropGuard)>, } @@ -85,7 +80,6 @@ pub struct SignedItem { pub struct AggregatedItem { pub executed_blocks: Vec>, pub commit_proof: LedgerInfoWithSignatures, - pub callback: StateComputerCommitCallBackType, } pub enum BufferItem { @@ -107,13 +101,11 @@ impl BufferItem { pub fn new_ordered( ordered_blocks: Vec>, ordered_proof: LedgerInfoWithSignatures, - callback: StateComputerCommitCallBackType, unverified_votes: HashMap, ) -> Self { Self::Ordered(Box::new(OrderedItem { unverified_votes, commit_proof: None, - callback, ordered_blocks, ordered_proof, })) @@ -133,7 +125,6 @@ impl BufferItem { ordered_blocks, commit_proof, unverified_votes, - callback, ordered_proof, } = *ordered_item; for (b1, b2) in zip_eq(ordered_blocks.iter(), executed_blocks.iter()) { @@ -164,7 +155,6 @@ impl BufferItem { Self::Aggregated(Box::new(AggregatedItem { executed_blocks, commit_proof, - callback, })) } else { let commit_ledger_info = generate_commit_ledger_info( @@ -188,13 +178,11 @@ impl BufferItem { Self::Aggregated(Box::new(AggregatedItem { executed_blocks, commit_proof, - callback, })) } else { Self::Executed(Box::new(ExecutedItem { executed_blocks, partial_commit_proof, - callback, commit_info, ordered_proof, })) @@ -212,7 +200,6 @@ impl BufferItem { Self::Executed(executed_item) => { let ExecutedItem { executed_blocks, - callback, partial_commit_proof, .. } = *executed_item; @@ -230,7 +217,6 @@ impl BufferItem { Self::Signed(Box::new(SignedItem { executed_blocks, - callback, partial_commit_proof, commit_vote, rb_handle: None, @@ -252,7 +238,6 @@ impl BufferItem { Self::Signed(signed_item) => { let SignedItem { executed_blocks, - callback, partial_commit_proof: local_commit_proof, .. } = *signed_item; @@ -266,14 +251,12 @@ impl BufferItem { ); Self::Aggregated(Box::new(AggregatedItem { executed_blocks, - callback, commit_proof, })) }, Self::Executed(executed_item) => { let ExecutedItem { executed_blocks, - callback, commit_info, .. } = *executed_item; @@ -284,7 +267,6 @@ impl BufferItem { ); Self::Aggregated(Box::new(AggregatedItem { executed_blocks, - callback, commit_proof, })) }, @@ -332,7 +314,6 @@ impl BufferItem { return Self::Aggregated(Box::new(AggregatedItem { executed_blocks: signed_item.executed_blocks, commit_proof, - callback: signed_item.callback, })); } } @@ -358,7 +339,6 @@ impl BufferItem { return Self::Aggregated(Box::new(AggregatedItem { executed_blocks: executed_item.executed_blocks, commit_proof, - callback: executed_item.callback, })); } } @@ -577,7 +557,6 @@ mod test { let mut ordered_item = BufferItem::new_ordered( vec![pipelined_block.clone()], ordered_proof.clone(), - Box::new(move |_, _| {}), cached_commit_votes, ); @@ -682,7 +661,6 @@ mod test { let mut ordered_item = BufferItem::new_ordered( vec![pipelined_block.clone()], ordered_proof.clone(), - Box::new(move |_, _| {}), cached_commit_votes, ); diff --git a/consensus/src/pipeline/buffer_manager.rs b/consensus/src/pipeline/buffer_manager.rs index 9576105a374..3d2748c7c04 100644 --- a/consensus/src/pipeline/buffer_manager.rs +++ b/consensus/src/pipeline/buffer_manager.rs @@ -22,7 +22,6 @@ use crate::{ pipeline_phase::CountedRequest, signing_phase::{SigningRequest, SigningResponse}, }, - state_replication::StateComputerCommitCallBackType, }; use aptos_bounded_executor::BoundedExecutor; use aptos_config::config::ConsensusObserverConfig; @@ -81,7 +80,6 @@ pub struct ResetRequest { pub struct OrderedBlocks { pub ordered_blocks: Vec>, pub ordered_proof: LedgerInfoWithSignatures, - pub callback: StateComputerCommitCallBackType, } impl OrderedBlocks { @@ -139,10 +137,6 @@ pub struct BufferManager { block_rx: UnboundedReceiver, reset_rx: UnboundedReceiver, - // self channel to retry execution schedule phase - execution_schedule_retry_tx: UnboundedSender<()>, - execution_schedule_retry_rx: UnboundedReceiver<()>, - stop: bool, epoch_state: Arc, @@ -177,7 +171,6 @@ pub struct BufferManager { // Items are popped from the buffer when sending to the persisting phase since callback is not clonable. // but we need to keep the pending blocks for reset. pending_commit_blocks: BTreeMap>, - new_pipeline_enabled: bool, } impl BufferManager { @@ -209,7 +202,6 @@ impl BufferManager { consensus_observer_config: ConsensusObserverConfig, consensus_publisher: Option>, max_pending_rounds_in_commit_vote_cache: u64, - new_pipeline_enabled: bool, ) -> Self { let buffer = Buffer::::new(); @@ -217,7 +209,6 @@ impl BufferManager { .factor(50) .max_delay(Duration::from_secs(5)); - let (tx, rx) = unbounded(); Self { author, @@ -252,9 +243,6 @@ impl BufferManager { block_rx, reset_rx, - execution_schedule_retry_tx: tx, - execution_schedule_retry_rx: rx, - stop: false, epoch_state, @@ -275,7 +263,6 @@ impl BufferManager { max_pending_rounds_in_commit_vote_cache, pending_commit_votes: BTreeMap::new(), pending_commit_blocks: BTreeMap::new(), - new_pipeline_enabled, } } @@ -324,23 +311,16 @@ impl BufferManager { let round = commit_proof.commit_info().round(); let block_id = commit_proof.commit_info().id(); if self.highest_committed_round < round { - if self.pending_commit_proofs.len() < MAX_PENDING_COMMIT_PROOFS { - self.pending_commit_proofs.insert(round, commit_proof); - - info!( - round = round, - block_id = block_id, - "Added pending commit proof." - ); - true - } else { - warn!( - round = round, - block_id = block_id, - "Too many pending commit proofs, ignored." - ); - false + info!( + round = round, + block_id = block_id, + "Added pending commit proof." + ); + self.pending_commit_proofs.insert(round, commit_proof); + if self.pending_commit_proofs.len() == MAX_PENDING_COMMIT_PROOFS { + let _ = self.pending_commit_proofs.pop_first(); } + true } else { debug!( round = round, @@ -356,6 +336,10 @@ impl BufferManager { let block_id = vote.commit_info().id(); let round = vote.commit_info().round(); + // Don't need to store commit vote if we have already committed up to that round + if round <= self.highest_committed_round { + true + } else // Store the commit vote only if it is for one of the next 100 rounds. if round > self.highest_committed_round && self.highest_committed_round + self.max_pending_rounds_in_commit_vote_cache > round @@ -399,19 +383,19 @@ impl BufferManager { let OrderedBlocks { ordered_blocks, ordered_proof, - callback, } = ordered_blocks; info!( - "Receive {} ordered block ends with {}, the queue size is {}", + "Receive {} ordered block ends with [epoch: {}, round: {}, id: {}], the queue size is {}", ordered_blocks.len(), - ordered_proof.commit_info(), + ordered_proof.commit_info().epoch(), + ordered_proof.commit_info().round(), + ordered_proof.commit_info().id(), self.buffer.len() + 1, ); let request = self.create_new_request(ExecutionRequest { ordered_blocks: ordered_blocks.clone(), - lifetime_guard: self.create_new_request(()), }); if let Some(consensus_publisher) = &self.consensus_publisher { let message = ConsensusObserverMessage::new_ordered_block_message( @@ -435,8 +419,7 @@ impl BufferManager { } } } - let item = - BufferItem::new_ordered(ordered_blocks, ordered_proof, callback, unverified_votes); + let item = BufferItem::new_ordered(ordered_blocks, ordered_proof, unverified_votes); self.buffer.push_back(item); } @@ -454,9 +437,12 @@ impl BufferManager { // Schedule retry. self.execution_root } else { - info!( - "Advance execution root from {:?} to {:?}", - cursor, self.execution_root + sample!( + SampleRate::Frequency(2), + info!( + "Advance execution root from {:?} to {:?}", + cursor, self.execution_root + ) ); // Otherwise do nothing, because the execution wait phase is driven by the response of // the execution schedule phase, which is in turn fed as soon as the ordered blocks @@ -474,9 +460,12 @@ impl BufferManager { .find_elem_from(cursor.or_else(|| *self.buffer.head_cursor()), |item| { item.is_executed() }); - info!( - "Advance signing root from {:?} to {:?}", - cursor, self.signing_root + sample!( + SampleRate::Frequency(2), + info!( + "Advance signing root from {:?} to {:?}", + cursor, self.signing_root + ) ); if self.signing_root.is_some() { let item = self.buffer.get(&self.signing_root); @@ -522,11 +511,6 @@ impl BufferManager { // As all the validators broadcast commit votes directly to all other validators, // the proposer do not have to broadcast commit decision again. let commit_proof = aggregated_item.commit_proof.clone(); - if commit_proof.ledger_info().ends_epoch() { - // the epoch ends, reset to avoid executing more blocks, execute after - // this persisting request will result in BlockNotFound - self.reset().await; - } if let Some(consensus_publisher) = &self.consensus_publisher { let message = ConsensusObserverMessage::new_commit_decision_message(commit_proof.clone()); @@ -540,16 +524,14 @@ impl BufferManager { .send(self.create_new_request(PersistingRequest { blocks: blocks_to_persist, commit_ledger_info: aggregated_item.commit_proof, - // we use the last callback - // this is okay because the callback function (from BlockStore::commit) - // takes in the actual blocks and ledger info from the state computer - // the encoded values are references to the block_tree, storage, and a commit root - // the block_tree and storage are the same for all the callbacks in the current epoch - // the commit root is used in logging only. - callback: aggregated_item.callback, })) .await .expect("Failed to send persist request"); + if commit_proof.ledger_info().ends_epoch() { + // the epoch ends, reset to avoid executing more blocks, execute after + // this persisting request will result in BlockNotFound + self.reset().await; + } info!("Advance head to {:?}", self.buffer.head_cursor()); self.previous_commit_time = Instant::now(); return; @@ -580,7 +562,13 @@ impl BufferManager { self.previous_commit_time = Instant::now(); self.commit_proof_rb_handle.take(); // purge the incoming blocks queue - while let Ok(Some(_)) = self.block_rx.try_next() {} + while let Ok(Some(blocks)) = self.block_rx.try_next() { + for b in blocks.ordered_blocks { + if let Some(futs) = b.abort_pipeline() { + futs.wait_until_finishes().await; + } + } + } // Wait for ongoing tasks to finish before sending back ack. while self.ongoing_tasks.load(Ordering::SeqCst) > 0 { tokio::time::sleep(Duration::from_millis(10)).await; @@ -591,9 +579,6 @@ impl BufferManager { async fn process_reset_request(&mut self, request: ResetRequest) { let ResetRequest { tx, signal } = request; info!("Receive reset"); - if !self.new_pipeline_enabled { - self.reset_flag.store(true, Ordering::SeqCst); - } match signal { ResetSignal::Stop => self.stop = true, @@ -607,9 +592,6 @@ impl BufferManager { self.reset().await; let _ = tx.send(ResetAck::default()); - if !self.new_pipeline_enabled { - self.reset_flag.store(false, Ordering::SeqCst); - } info!("Reset finishes"); } @@ -622,29 +604,7 @@ impl BufferManager { .expect("Failed to send execution wait request."); } - async fn retry_schedule_phase(&mut self) { - let mut cursor = self.execution_root; - let mut count = 0; - while cursor.is_some() { - let ordered_blocks = self.buffer.get(&cursor).get_blocks().clone(); - let request = self.create_new_request(ExecutionRequest { - ordered_blocks, - lifetime_guard: self.create_new_request(()), - }); - count += 1; - self.execution_schedule_phase_tx - .send(request) - .await - .expect("Failed to send execution schedule request."); - cursor = self.buffer.get_next(&cursor); - } - info!( - "Reschedule {} execution requests from {:?}", - count, self.execution_root - ); - } - - /// If the response is successful, advance the item to Executed, otherwise panic (TODO fix). + /// If the response is successful, advance the item to Executed. #[allow(clippy::unwrap_used)] async fn process_execution_response(&mut self, response: ExecutionResponse) { let ExecutionResponse { block_id, inner } = response; @@ -661,7 +621,6 @@ impl BufferManager { e, &counters::BUFFER_MANAGER_RECEIVED_EXECUTOR_ERROR_COUNT, block_id, - self.new_pipeline_enabled, ); return; }, @@ -994,29 +953,12 @@ impl BufferManager { })}, Some(response) = self.execution_wait_phase_rx.next() => { monitor!("buffer_manager_process_execution_wait_response", { - let response_block_id = response.block_id; self.process_execution_response(response).await; - if let Some(block_id) = self.advance_execution_root() { - // if the response is for the current execution root, retry the schedule phase - if response_block_id == block_id { - let mut tx = self.execution_schedule_retry_tx.clone(); - tokio::spawn(async move { - tokio::time::sleep(Duration::from_millis(100)).await; - // buffer manager can be dropped at the point of sending retry - let _ = tx.send(()).await; - }); - } - } + self.advance_execution_root(); if self.signing_root.is_none() { self.advance_signing_root().await; }}); }, - _ = self.execution_schedule_retry_rx.next() => { - if !self.new_pipeline_enabled { - monitor!("buffer_manager_process_execution_schedule_retry", - self.retry_schedule_phase().await); - } - }, Some(response) = self.signing_phase_rx.next() => { monitor!("buffer_manager_process_signing_response", { self.process_signing_response(response).await; diff --git a/consensus/src/pipeline/decoupled_execution_utils.rs b/consensus/src/pipeline/decoupled_execution_utils.rs index 1f3488031f2..b704ece27c3 100644 --- a/consensus/src/pipeline/decoupled_execution_utils.rs +++ b/consensus/src/pipeline/decoupled_execution_utils.rs @@ -13,7 +13,6 @@ use crate::{ pipeline_phase::{CountedRequest, PipelinePhase}, signing_phase::{CommitSignerProvider, SigningPhase, SigningRequest, SigningResponse}, }, - state_replication::StateComputer, }; use aptos_bounded_executor::BoundedExecutor; use aptos_channels::aptos_channel::Receiver; @@ -30,11 +29,9 @@ use std::sync::{ #[allow(clippy::too_many_arguments)] pub fn prepare_phases_and_buffer_manager( author: Author, - execution_proxy: Arc, safety_rules: Arc, - commit_msg_tx: NetworkSender, + commit_msg_tx: Arc, commit_msg_rx: Receiver, - persisting_proxy: Arc, block_rx: UnboundedReceiver, sync_rx: UnboundedReceiver, epoch_state: Arc, @@ -45,7 +42,6 @@ pub fn prepare_phases_and_buffer_manager( consensus_observer_config: ConsensusObserverConfig, consensus_publisher: Option>, max_pending_rounds_in_commit_vote_cache: u64, - new_pipeline_enabled: bool, ) -> ( PipelinePhase, PipelinePhase, @@ -61,7 +57,7 @@ pub fn prepare_phases_and_buffer_manager( create_channel::>(); let (execution_schedule_phase_response_tx, execution_schedule_phase_response_rx) = create_channel::(); - let execution_schedule_phase_processor = ExecutionSchedulePhase::new(execution_proxy); + let execution_schedule_phase_processor = ExecutionSchedulePhase::new(); let execution_schedule_phase = PipelinePhase::new( execution_schedule_phase_request_rx, Some(execution_schedule_phase_response_tx), @@ -99,9 +95,9 @@ pub fn prepare_phases_and_buffer_manager( let (persisting_phase_request_tx, persisting_phase_request_rx) = create_channel::>(); let (persisting_phase_response_tx, persisting_phase_response_rx) = create_channel(); - let commit_msg_tx = Arc::new(commit_msg_tx); + let commit_msg_tx = commit_msg_tx; - let persisting_phase_processor = PersistingPhase::new(persisting_proxy, commit_msg_tx.clone()); + let persisting_phase_processor = PersistingPhase::new(commit_msg_tx.clone()); let persisting_phase = PipelinePhase::new( persisting_phase_request_rx, Some(persisting_phase_response_tx), @@ -138,7 +134,6 @@ pub fn prepare_phases_and_buffer_manager( consensus_observer_config, consensus_publisher, max_pending_rounds_in_commit_vote_cache, - new_pipeline_enabled, ), ) } diff --git a/consensus/src/pipeline/execution_client.rs b/consensus/src/pipeline/execution_client.rs index 74a3f4e8291..cb6276983b8 100644 --- a/consensus/src/pipeline/execution_client.rs +++ b/consensus/src/pipeline/execution_client.rs @@ -22,7 +22,7 @@ use crate::{ types::{AugmentedData, RandConfig, Share}, }, state_computer::ExecutionProxy, - state_replication::{StateComputer, StateComputerCommitCallBackType}, + state_replication::StateComputer, transaction_deduper::create_transaction_deduper, transaction_shuffler::create_transaction_shuffler, }; @@ -71,7 +71,6 @@ pub trait TExecutionClient: Send + Sync { fast_rand_config: Option, rand_msg_rx: aptos_channel::Receiver, highest_committed_round: Round, - new_pipeline_enabled: bool, virtual_genesis_block_id: Option, ); @@ -83,7 +82,6 @@ pub trait TExecutionClient: Send + Sync { &self, blocks: Vec>, ordered_proof: WrappedLedgerInfo, - callback: StateComputerCommitCallBackType, ) -> ExecutorResult<()>; fn send_commit_msg( @@ -211,15 +209,8 @@ impl ExecutionProxyClient { buffer_manager_back_pressure_enabled: bool, consensus_observer_config: ConsensusObserverConfig, consensus_publisher: Option>, - new_pipeline_enabled: bool, + network_sender: Arc, ) { - let network_sender = NetworkSender::new( - self.author, - self.network_sender.clone(), - self.self_sender.clone(), - epoch_state.verifier.clone(), - ); - let (reset_buffer_manager_tx, reset_buffer_manager_rx) = unbounded::(); let (commit_msg_tx, commit_msg_rx) = @@ -244,7 +235,7 @@ impl ExecutionProxyClient { rand_config, fast_rand_config, rand_ready_block_tx, - Arc::new(network_sender.clone()), + network_sender.clone(), self.rand_storage.clone(), self.bounded_executor.clone(), &self.consensus_config.rand_rb_config, @@ -283,11 +274,9 @@ impl ExecutionProxyClient { buffer_manager, ) = prepare_phases_and_buffer_manager( self.author, - self.execution_proxy.clone(), commit_signer_provider, network_sender, commit_msg_rx, - self.execution_proxy.clone(), execution_ready_block_rx, reset_buffer_manager_rx, epoch_state, @@ -299,7 +288,6 @@ impl ExecutionProxyClient { consensus_publisher, self.consensus_config .max_pending_rounds_in_commit_vote_cache, - new_pipeline_enabled, ); tokio::spawn(execution_schedule_phase.start()); @@ -325,9 +313,14 @@ impl TExecutionClient for ExecutionProxyClient { fast_rand_config: Option, rand_msg_rx: aptos_channel::Receiver, highest_committed_round: Round, - new_pipeline_enabled: bool, virtual_genesis_block_id: Option, ) { + let network_sender = Arc::new(NetworkSender::new( + self.author, + self.network_sender.clone(), + self.self_sender.clone(), + epoch_state.verifier.clone(), + )); self.spawn_decoupled_execution( maybe_consensus_key, commit_signer_provider, @@ -340,17 +333,20 @@ impl TExecutionClient for ExecutionProxyClient { self.consensus_config.enable_pre_commit, self.consensus_observer_config, self.consensus_publisher.clone(), - new_pipeline_enabled, + network_sender.clone(), ); let transaction_shuffler = create_transaction_shuffler(onchain_execution_config.transaction_shuffler_type()); - let block_executor_onchain_config = + let block_executor_onchain_config: aptos_types::block_executor::config::BlockExecutorConfigFromOnchain = onchain_execution_config.block_executor_onchain_config(); let transaction_deduper = create_transaction_deduper(onchain_execution_config.transaction_deduper_type()); let randomness_enabled = onchain_consensus_config.is_vtxn_enabled() && onchain_randomness_config.randomness_enabled(); + + let aux_version = onchain_execution_config.persisted_auxiliary_info_version(); + self.execution_proxy.new_epoch( &epoch_state, payload_manager, @@ -358,8 +354,10 @@ impl TExecutionClient for ExecutionProxyClient { block_executor_onchain_config, transaction_deduper, randomness_enabled, - onchain_consensus_config.order_vote_enabled(), virtual_genesis_block_id, + onchain_consensus_config.clone(), + aux_version, + network_sender, ); } @@ -371,7 +369,6 @@ impl TExecutionClient for ExecutionProxyClient { &self, blocks: Vec>, ordered_proof: WrappedLedgerInfo, - callback: StateComputerCommitCallBackType, ) -> ExecutorResult<()> { assert!(!blocks.is_empty()); let mut execute_tx = match self.handle.read().execute_tx.clone() { @@ -395,7 +392,6 @@ impl TExecutionClient for ExecutionProxyClient { .send(OrderedBlocks { ordered_blocks: blocks, ordered_proof: ordered_proof.ledger_info().clone(), - callback, }) .await .is_err() @@ -546,7 +542,6 @@ impl TExecutionClient for DummyExecutionClient { _fast_rand_config: Option, _rand_msg_rx: aptos_channel::Receiver, _highest_committed_round: Round, - _new_pipeline_enabled: bool, _virtual_genesis_block_id: Option, ) { } @@ -559,7 +554,6 @@ impl TExecutionClient for DummyExecutionClient { &self, _: Vec>, _: WrappedLedgerInfo, - _: StateComputerCommitCallBackType, ) -> ExecutorResult<()> { Ok(()) } diff --git a/consensus/src/pipeline/execution_schedule_phase.rs b/consensus/src/pipeline/execution_schedule_phase.rs index 4c3882290e4..16df7a00091 100644 --- a/consensus/src/pipeline/execution_schedule_phase.rs +++ b/consensus/src/pipeline/execution_schedule_phase.rs @@ -1,19 +1,13 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - pipeline::{ - execution_wait_phase::ExecutionWaitRequest, - pipeline_phase::{CountedRequest, StatelessPipeline}, - }, - state_replication::StateComputer, +use crate::pipeline::{ + execution_wait_phase::ExecutionWaitRequest, pipeline_phase::StatelessPipeline, }; use aptos_consensus_types::pipelined_block::PipelinedBlock; use aptos_crypto::HashValue; -use aptos_executor_types::ExecutorError; -use aptos_logger::debug; use async_trait::async_trait; -use futures::{FutureExt, TryFutureExt}; +use futures::FutureExt; use std::{ fmt::{Debug, Display, Formatter}, sync::Arc, @@ -21,13 +15,10 @@ use std::{ /// [ This class is used when consensus.decoupled = true ] /// ExecutionSchedulePhase is a singleton that receives ordered blocks from -/// the buffer manager and send them to the ExecutionPipeline. +/// the buffer manager and schedules a future that awaits their per-block compute results. pub struct ExecutionRequest { pub ordered_blocks: Vec>, - // Pass down a CountedRequest to the ExecutionPipeline stages in order to guarantee the executor - // doesn't get reset with pending tasks stuck in the pipeline. - pub lifetime_guard: CountedRequest<()>, } impl Debug for ExecutionRequest { @@ -42,13 +33,11 @@ impl Display for ExecutionRequest { } } -pub struct ExecutionSchedulePhase { - execution_proxy: Arc, -} +pub struct ExecutionSchedulePhase; impl ExecutionSchedulePhase { - pub fn new(execution_proxy: Arc) -> Self { - Self { execution_proxy } + pub fn new() -> Self { + Self } } @@ -60,13 +49,10 @@ impl StatelessPipeline for ExecutionSchedulePhase { const NAME: &'static str = "execution_schedule"; async fn process(&self, req: ExecutionRequest) -> ExecutionWaitRequest { - let ExecutionRequest { - mut ordered_blocks, - lifetime_guard, - } = req; + let ExecutionRequest { mut ordered_blocks } = req; - let (block_id, pipeline_enabled) = match ordered_blocks.last() { - Some(block) => (block.id(), block.pipeline_enabled()), + let block_id = match ordered_blocks.last() { + Some(block) => block.id(), None => { return ExecutionWaitRequest { block_id: HashValue::zero(), @@ -75,53 +61,20 @@ impl StatelessPipeline for ExecutionSchedulePhase { }, }; - let fut = if pipeline_enabled { - for b in &ordered_blocks { - if let Some(tx) = b.pipeline_tx().lock().as_mut() { - tx.rand_tx.take().map(|tx| tx.send(b.randomness().cloned())); - } + for b in &ordered_blocks { + if let Some(tx) = b.pipeline_tx().lock().as_mut() { + tx.rand_tx.take().map(|tx| tx.send(b.randomness().cloned())); } + } - async move { - for b in ordered_blocks.iter_mut() { - let (compute_result, execution_time) = b.wait_for_compute_result().await?; - b.set_compute_result(compute_result, execution_time); - } - Ok(ordered_blocks) - } - .boxed() - } else { - // Call schedule_compute() for each block here (not in the fut being returned) to - // make sure they are scheduled in order. - let mut futs = vec![]; - for b in &ordered_blocks { - let fut = self - .execution_proxy - .schedule_compute( - b.block(), - b.parent_id(), - b.randomness().cloned(), - b.qc(), - lifetime_guard.spawn(()), - ) - .await; - futs.push(fut) + let fut = async move { + for b in ordered_blocks.iter_mut() { + let (compute_result, execution_time) = b.wait_for_compute_result().await?; + b.set_compute_result(compute_result, execution_time); } - - // In the future being returned, wait for the compute results in order. - tokio::task::spawn(async move { - let mut results = vec![]; - for (block, fut) in itertools::zip_eq(ordered_blocks, futs) { - debug!("try to receive compute result for block {}", block.id()); - block.set_execution_result(fut.await?); - results.push(block); - } - Ok(results) - }) - .map_err(ExecutorError::internal_err) - .and_then(|res| async { res }) - .boxed() - }; + Ok(ordered_blocks) + } + .boxed(); ExecutionWaitRequest { block_id, fut } } diff --git a/consensus/src/pipeline/execution_wait_phase.rs b/consensus/src/pipeline/execution_wait_phase.rs index 9666a05ee81..b394f71f146 100644 --- a/consensus/src/pipeline/execution_wait_phase.rs +++ b/consensus/src/pipeline/execution_wait_phase.rs @@ -14,7 +14,7 @@ use std::{ /// [ This class is used when consensus.decoupled = true ] /// ExecutionWaitPhase is a singleton that receives scheduled execution futures -/// from ExecutionSchedulePhase and waits for the results from the ExecutionPipeline. +/// from ExecutionSchedulePhase and waits for their execution results. pub struct ExecutionWaitRequest { pub block_id: HashValue, diff --git a/consensus/src/pipeline/persisting_phase.rs b/consensus/src/pipeline/persisting_phase.rs index e6c4d707136..f8c9f9a50c5 100644 --- a/consensus/src/pipeline/persisting_phase.rs +++ b/consensus/src/pipeline/persisting_phase.rs @@ -2,11 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{ - network::NetworkSender, - pipeline::pipeline_phase::StatelessPipeline, - state_replication::{StateComputer, StateComputerCommitCallBackType}, -}; +use crate::{network::NetworkSender, pipeline::pipeline_phase::StatelessPipeline}; use aptos_consensus_types::{common::Round, pipelined_block::PipelinedBlock}; use aptos_executor_types::ExecutorResult; use aptos_types::{epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures}; @@ -24,7 +20,6 @@ use std::{ pub struct PersistingRequest { pub blocks: Vec>, pub commit_ledger_info: LedgerInfoWithSignatures, - pub callback: StateComputerCommitCallBackType, } impl Debug for PersistingRequest { @@ -46,19 +41,12 @@ impl Display for PersistingRequest { pub type PersistingResponse = ExecutorResult; pub struct PersistingPhase { - persisting_handle: Arc, commit_msg_tx: Arc, } impl PersistingPhase { - pub fn new( - persisting_handle: Arc, - commit_msg_tx: Arc, - ) -> Self { - Self { - persisting_handle, - commit_msg_tx, - } + pub fn new(commit_msg_tx: Arc) -> Self { + Self { commit_msg_tx } } } @@ -73,31 +61,18 @@ impl StatelessPipeline for PersistingPhase { let PersistingRequest { blocks, commit_ledger_info, - callback, } = req; - let response = if blocks - .last() - .expect("Blocks can't be empty") - .pipeline_enabled() - { - for b in &blocks { - if let Some(tx) = b.pipeline_tx().lock().as_mut() { - tx.commit_proof_tx - .take() - .map(|tx| tx.send(commit_ledger_info.clone())); - } - b.wait_for_commit_ledger().await; + for b in &blocks { + if let Some(tx) = b.pipeline_tx().lock().as_mut() { + tx.commit_proof_tx + .take() + .map(|tx| tx.send(commit_ledger_info.clone())); } + b.wait_for_commit_ledger().await; + } - Ok(blocks.last().expect("Blocks can't be empty").round()) - } else { - let round = commit_ledger_info.ledger_info().round(); - self.persisting_handle - .commit(blocks, commit_ledger_info.clone(), callback) - .await - .map(|_| round) - }; + let response = Ok(blocks.last().expect("Blocks can't be empty").round()); if commit_ledger_info.ledger_info().ends_epoch() { self.commit_msg_tx .send_epoch_change(EpochChangeProof::new(vec![commit_ledger_info], false)) diff --git a/consensus/src/pipeline/pipeline_builder.rs b/consensus/src/pipeline/pipeline_builder.rs index 749698f4697..568708fe5bb 100644 --- a/consensus/src/pipeline/pipeline_builder.rs +++ b/consensus/src/pipeline/pipeline_builder.rs @@ -5,8 +5,8 @@ use crate::{ block_preparer::BlockPreparer, block_storage::tracing::{observe_block, BlockStage}, counters::{self, update_counters_for_block, update_counters_for_compute_result}, - execution_pipeline::SIG_VERIFY_POOL, monitor, + network::NetworkSender, payload_manager::TPayloadManager, txn_notifier::TxnNotifier, IntGaugeGuard, @@ -15,13 +15,13 @@ use anyhow::anyhow; use aptos_consensus_notifications::ConsensusNotificationSender; use aptos_consensus_types::{ block::Block, - common::Round, + common::{Author, Round}, pipeline::commit_vote::CommitVote, pipelined_block::{ CommitLedgerResult, CommitVoteResult, ExecuteResult, LedgerUpdateResult, NotifyStateSyncResult, PipelineFutures, PipelineInputRx, PipelineInputTx, PipelinedBlock, - PostCommitResult, PostLedgerUpdateResult, PreCommitResult, PrepareResult, TaskError, - TaskFuture, TaskResult, + PostCommitResult, PostLedgerUpdateResult, PreCommitResult, PrepareResult, RandResult, + TaskError, TaskFuture, TaskResult, }, quorum_cert::QuorumCert, wrapped_ledger_info::WrappedLedgerInfo, @@ -30,27 +30,47 @@ use aptos_crypto::HashValue; use aptos_executor_types::{state_compute_result::StateComputeResult, BlockExecutorTrait}; use aptos_experimental_runtimes::thread_manager::optimal_min_len; use aptos_infallible::Mutex; -use aptos_logger::{error, info, warn}; +use aptos_logger::{error, info, trace, warn}; +use aptos_resource_viewer::module_view::CachedModuleView; +use aptos_storage_interface::state_store::state_view::cached_state_view::CachedStateView; use aptos_types::{ + account_config::randomness_event::RANDOMNESS_GENERATED_EVENT_MOVE_TYPE_TAG, block_executor::config::BlockExecutorConfigFromOnchain, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, + on_chain_config::OnChainConsensusConfig, randomness::Randomness, + state_store::StateViewId, transaction::{ signature_verified_transaction::{SignatureVerifiedTransaction, TransactionProvider}, - SignedTransaction, Transaction, + AuxiliaryInfo, EphemeralAuxiliaryInfo, PersistedAuxiliaryInfo, SignedTransaction, + Transaction, TransactionExecutableRef, }, validator_signer::ValidatorSigner, + vm::module_metadata::get_randomness_annotation_for_entry_function, }; use futures::FutureExt; use move_core_types::account_address::AccountAddress; +use move_vm_runtime::ModuleStorage; +use once_cell::sync::Lazy; use rayon::prelude::*; use std::{ future::Future, + ops::Deref, sync::Arc, time::{Duration, Instant}, }; use tokio::{select, sync::oneshot, task::AbortHandle}; +static SIG_VERIFY_POOL: Lazy> = Lazy::new(|| { + Arc::new( + rayon::ThreadPoolBuilder::new() + .num_threads(16) + .thread_name(|index| format!("signature-checker-{}", index)) + .build() + .expect("Failed to create signature verification thread pool"), + ) +}); + /// Status to help synchornize the pipeline and sync_manager /// It is used to track the round of the block that could be pre-committed and sync manager decides /// whether to enter state sync or not and pause pre-commit during state sync to avoid race condition @@ -113,6 +133,10 @@ pub struct PipelineBuilder { txn_notifier: Arc, pre_commit_status: Arc>, order_vote_enabled: bool, + persisted_auxiliary_info_version: u8, + rand_check_enabled: bool, + module_cache: Arc>>>, + network_sender: Arc, } fn spawn_shared_fut< @@ -182,9 +206,12 @@ impl Tracker { } fn log_start(&self) { - info!( + trace!( "[Pipeline] Block {} {} {} enters {}", - self.block_id, self.epoch, self.round, self.name + self.block_id, + self.epoch, + self.round, + self.name ); } @@ -200,7 +227,7 @@ impl Tracker { counters::PIPELINE_TRACING .with_label_values(&[self.name, "work_time"]) .observe(work_time.as_secs_f64()); - info!( + trace!( "[Pipeline] Block {} {} {} finishes {}, waits {}ms, takes {}ms", self.block_id, self.epoch, @@ -230,8 +257,11 @@ impl PipelineBuilder { payload_manager: Arc, txn_notifier: Arc, enable_pre_commit: bool, - order_vote_enabled: bool, + consensus_onchain_config: &OnChainConsensusConfig, + persisted_auxiliary_info_version: u8, + network_sender: Arc, ) -> Self { + let module_cache = Arc::new(Mutex::new(None)); Self { block_preparer, executor, @@ -243,7 +273,11 @@ impl PipelineBuilder { payload_manager, txn_notifier, pre_commit_status: Arc::new(Mutex::new(PreCommitStatus::new(0, enable_pre_commit))), - order_vote_enabled, + order_vote_enabled: consensus_onchain_config.order_vote_enabled(), + persisted_auxiliary_info_version, + rand_check_enabled: consensus_onchain_config.rand_check_enabled(), + module_cache, + network_sender, } } @@ -297,6 +331,7 @@ impl PipelineBuilder { commit_proof: LedgerInfoWithSignatures, ) -> PipelineFutures { let prepare_fut = spawn_ready_fut((Arc::new(vec![]), None)); + let rand_check_fut = spawn_ready_fut((None, false)); let execute_fut = spawn_ready_fut(Duration::from_millis(0)); let ledger_update_fut = spawn_ready_fut((compute_result.clone(), Duration::from_millis(0), None)); @@ -314,6 +349,7 @@ impl PipelineBuilder { let post_commit_fut = spawn_ready_fut(()); PipelineFutures { prepare_fut, + rand_check_fut, execute_fut, ledger_update_fut, post_ledger_update_fut, @@ -325,18 +361,54 @@ impl PipelineBuilder { } } - pub fn build( + pub fn build_for_observer( + &self, + pipelined_block: &PipelinedBlock, + parent_futs: PipelineFutures, + block_store_callback: Box< + dyn FnOnce(WrappedLedgerInfo, LedgerInfoWithSignatures) + Send + Sync, + >, + ) { + Self::build( + self, + pipelined_block, + parent_futs, + block_store_callback, + true, + ); + } + + pub fn build_for_consensus( + &self, + pipelined_block: &PipelinedBlock, + parent_futs: PipelineFutures, + block_store_callback: Box< + dyn FnOnce(WrappedLedgerInfo, LedgerInfoWithSignatures) + Send + Sync, + >, + ) { + Self::build( + self, + pipelined_block, + parent_futs, + block_store_callback, + false, + ); + } + + fn build( &self, pipelined_block: &PipelinedBlock, parent_futs: PipelineFutures, block_store_callback: Box< dyn FnOnce(WrappedLedgerInfo, LedgerInfoWithSignatures) + Send + Sync, >, + observer_enabled: bool, ) { let (futs, tx, abort_handles) = self.build_internal( parent_futs, Arc::new(pipelined_block.block().clone()), block_store_callback, + observer_enabled, ); pipelined_block.set_pipeline_futs(futs); pipelined_block.set_pipeline_tx(tx); @@ -350,6 +422,7 @@ impl PipelineBuilder { block_store_callback: Box< dyn FnOnce(WrappedLedgerInfo, LedgerInfoWithSignatures) + Send + Sync, >, + observer_enabled: bool, ) -> (PipelineFutures, PipelineInputTx, Vec) { let mut abort_handles = vec![]; let (tx, rx) = Self::channel(&mut abort_handles); @@ -365,40 +438,65 @@ impl PipelineBuilder { Self::prepare(self.block_preparer.clone(), block.clone(), qc_rx), Some(&mut abort_handles), ); - let execute_fut = spawn_shared_fut( - Self::execute( + let rand_check_fut = spawn_shared_fut( + Self::rand_check( prepare_fut.clone(), parent.execute_fut.clone(), rand_rx, self.executor.clone(), block.clone(), self.is_randomness_enabled, + self.rand_check_enabled, + self.module_cache.clone(), + ), + Some(&mut abort_handles), + ); + let execute_fut = spawn_shared_fut( + Self::execute( + prepare_fut.clone(), + parent.execute_fut.clone(), + rand_check_fut.clone(), + self.executor.clone(), + block.clone(), self.validators.clone(), self.block_executor_onchain_config.clone(), + self.persisted_auxiliary_info_version, ), - Some(&mut abort_handles), + None, ); let ledger_update_fut = spawn_shared_fut( Self::ledger_update( + rand_check_fut.clone(), execute_fut.clone(), parent.ledger_update_fut.clone(), self.executor.clone(), block.clone(), ), - Some(&mut abort_handles), - ); - let commit_vote_fut = spawn_shared_fut( - Self::sign_commit_vote( - ledger_update_fut.clone(), - order_vote_rx, - order_proof_fut.clone(), - commit_proof_fut.clone(), - self.signer.clone(), - block.clone(), - self.order_vote_enabled, - ), - Some(&mut abort_handles), + None, ); + let commit_vote_fut = if !observer_enabled { + spawn_shared_fut( + Self::sign_and_broadcast_commit_vote( + ledger_update_fut.clone(), + order_vote_rx, + order_proof_fut.clone(), + commit_proof_fut.clone(), + self.signer.clone(), + block.clone(), + self.order_vote_enabled, + self.network_sender.clone(), + ), + Some(&mut abort_handles), + ) + } else { + spawn_ready_fut(CommitVote::new_with_signature( + Author::ONE, + LedgerInfo::dummy(), + self.signer + .sign(&LedgerInfo::dummy()) + .expect("Signing should succeed"), + )) + }; let pre_commit_fut = spawn_shared_fut( Self::pre_commit( ledger_update_fut.clone(), @@ -409,7 +507,7 @@ impl PipelineBuilder { block.clone(), self.pre_commit_status(), ), - Some(&mut abort_handles), + None, ); let commit_ledger_fut = spawn_shared_fut( Self::commit_ledger( @@ -419,7 +517,7 @@ impl PipelineBuilder { self.executor.clone(), block.clone(), ), - Some(&mut abort_handles), + None, ); let post_ledger_update_fut = spawn_shared_fut( @@ -456,6 +554,7 @@ impl PipelineBuilder { ); let all_fut = PipelineFutures { prepare_fut, + rand_check_fut, execute_fut, ledger_update_fut, post_ledger_update_fut, @@ -522,29 +621,131 @@ impl PipelineBuilder { Ok((Arc::new(sig_verified_txns), block_gas_limit)) } + /// Precondition: 1. prepare finishes, 2. parent block's execution phase finishes + /// What it does: decides if the block requires a randomness seed and return the value + async fn rand_check( + prepare_fut: TaskFuture, + parent_block_execute_fut: TaskFuture, + rand_rx: oneshot::Receiver>, + executor: Arc, + block: Arc, + is_randomness_enabled: bool, + rand_check_enabled: bool, + module_cache: Arc>>>, + ) -> TaskResult { + let mut tracker = Tracker::start_waiting("rand_check", &block); + parent_block_execute_fut.await?; + let (user_txns, _) = prepare_fut.await?; + + tracker.start_working(); + if !is_randomness_enabled { + return Ok((None, false)); + } + let grand_parent_id = block.quorum_cert().parent_block().id(); + let parent_state_view = executor + .state_view(block.parent_id()) + .map_err(anyhow::Error::from)?; + + let mut has_randomness = false; + // scope to drop the lock, compiler seems not able to figure out manual drop with async point + { + let mut cache_guard = module_cache.lock(); + if let Some(cache_mut) = cache_guard.as_mut() { + // flush the cache if the execution state view is not linear + // in case of speculative executing a forked block + let previous_state_view = cache_mut.state_view_id(); + let expected_state_view = StateViewId::BlockExecution { + block_id: grand_parent_id, + }; + if previous_state_view == expected_state_view { + cache_mut.reset_state_view(parent_state_view); + } else { + counters::RAND_BLOCK + .with_label_values(&["reset_cache"]) + .inc(); + cache_mut.reset_all(parent_state_view); + } + } else { + *cache_guard = Some(CachedModuleView::new(parent_state_view)); + } + let cache_ref = cache_guard.as_mut().expect("just set"); + + for txn in user_txns.iter() { + if let Some(txn) = txn.borrow_into_inner().try_as_signed_user_txn() { + if let Ok(TransactionExecutableRef::EntryFunction(entry_fn)) = + txn.executable_ref() + { + // use the deserialized API to avoid cloning the metadata + // should migrate once we move metadata into the extension and avoid cloning + if let Ok(Some(module)) = cache_ref.unmetered_get_deserialized_module( + entry_fn.module().address(), + entry_fn.module().name(), + ) { + if get_randomness_annotation_for_entry_function( + entry_fn, + &module.metadata, + ) + .is_some() + { + has_randomness = true; + break; + } + } + } + } + } + } + let label = if has_randomness { + "has_rand" + } else { + "no_rand" + }; + counters::RAND_BLOCK.with_label_values(&[label]).inc(); + if has_randomness { + info!( + "[Pipeline] Block {} {} {} has randomness txn", + block.id(), + block.epoch(), + block.round() + ); + } + drop(tracker); + // if rand check is enabled and no txn requires randomness, we skip waiting for randomness + let mut tracker = Tracker::start_waiting("rand_gen", &block); + tracker.start_working(); + let maybe_rand = if rand_check_enabled && !has_randomness { + None + } else { + rand_rx + .await + .map_err(|_| anyhow!("randomness tx cancelled"))? + }; + Ok((Some(maybe_rand), has_randomness)) + } + /// Precondition: 1. prepare finishes, 2. parent block's phase finishes 3. randomness is available /// What it does: Execute all transactions in block executor async fn execute( prepare_fut: TaskFuture, parent_block_execute_fut: TaskFuture, - randomness_rx: oneshot::Receiver>, + rand_check: TaskFuture, executor: Arc, block: Arc, - is_randomness_enabled: bool, validator: Arc<[AccountAddress]>, onchain_execution_config: BlockExecutorConfigFromOnchain, + persisted_auxiliary_info_version: u8, ) -> TaskResult { let mut tracker = Tracker::start_waiting("execute", &block); parent_block_execute_fut.await?; let (user_txns, block_gas_limit) = prepare_fut.await?; let onchain_execution_config = onchain_execution_config.with_block_gas_limit_override(block_gas_limit); - let maybe_rand = randomness_rx - .await - .map_err(|_| anyhow!("randomness tx cancelled"))?; + + let (rand_result, _has_randomness) = rand_check.await?; tracker.start_working(); - let metadata_txn = if is_randomness_enabled { + // if randomness is disabled, the metadata skips DKG and triggers immediate reconfiguration + let metadata_txn = if let Some(maybe_rand) = rand_result { block.new_metadata_with_randomness(&validator, maybe_rand) } else { block.new_block_metadata(&validator).into() @@ -564,11 +765,40 @@ impl PipelineBuilder { user_txns.as_ref().clone(), ] .concat(); + let proposer_index = block + .author() + .and_then(|proposer| validator.iter().position(|&v| v == proposer)); + + let auxiliary_info: Vec<_> = txns + .iter() + .enumerate() + .map(|(txn_index, txn)| { + let persisted_auxiliary_info = match persisted_auxiliary_info_version { + 0 => PersistedAuxiliaryInfo::None, + 1 => PersistedAuxiliaryInfo::V1 { + transaction_index: txn_index as u32, + }, + _ => unimplemented!("Unsupported persisted auxiliary info version"), + }; + + let ephemeral_auxiliary_info = txn + .borrow_into_inner() + .try_as_signed_user_txn() + .and_then(|_| { + proposer_index.map(|index| EphemeralAuxiliaryInfo { + proposer_index: index as u64, + }) + }); + + AuxiliaryInfo::new(persisted_auxiliary_info, ephemeral_auxiliary_info) + }) + .collect(); + let start = Instant::now(); tokio::task::spawn_blocking(move || { executor .execute_and_update_state( - (block.id(), txns).into(), + (block.id(), txns, auxiliary_info).into(), block.parent_id(), onchain_execution_config, ) @@ -583,6 +813,7 @@ impl PipelineBuilder { /// What it does: Generate state compute result from the execution, it's split from execution for more parallelism /// It carries block timestamp from epoch-ending block to all suffix block async fn ledger_update( + rand_check: TaskFuture, execute_fut: TaskFuture, parent_block_ledger_update_fut: TaskFuture, executor: Arc, @@ -593,14 +824,15 @@ impl PipelineBuilder { let execution_time = execute_fut.await?; tracker.start_working(); - let timestamp = block.timestamp_usecs(); + let block_clone = block.clone(); let result = tokio::task::spawn_blocking(move || { executor - .ledger_update(block.id(), block.parent_id()) + .ledger_update(block_clone.id(), block_clone.parent_id()) .map_err(anyhow::Error::from) }) .await .expect("spawn blocking failed")?; + let timestamp = block.timestamp_usecs(); observe_block(timestamp, BlockStage::EXECUTED); let epoch_end_timestamp = if result.has_reconfiguration() && !result.compute_status_for_input_txns().is_empty() { @@ -608,6 +840,24 @@ impl PipelineBuilder { } else { prev_epoch_end_timestamp }; + // check for randomness consistency + let (_, has_randomness) = rand_check.await?; + if !has_randomness { + let mut label = "consistent"; + for event in result.execution_output.subscribable_events.get(None) { + if event.type_tag() == RANDOMNESS_GENERATED_EVENT_MOVE_TYPE_TAG.deref() { + error!( + "[Pipeline] Block {} {} {} generated randomness event without has_randomness being true!", + block.id(), + block.epoch(), + block.round() + ); + label = "inconsistent"; + break; + } + } + counters::RAND_BLOCK.with_label_values(&[label]).inc(); + } Ok((result, execution_time, epoch_end_timestamp)) } @@ -662,8 +912,8 @@ impl PipelineBuilder { } /// Precondition: 1. ledger update finishes, 2. order vote or order proof or commit proof is received - /// What it does: Sign the commit vote with execution result, it needs to update the timestamp for reconfig suffix blocks - async fn sign_commit_vote( + /// What it does: Sign the commit vote with execution result and broadcast, it needs to update the timestamp for reconfig suffix blocks + async fn sign_and_broadcast_commit_vote( ledger_update_fut: TaskFuture, order_vote_rx: oneshot::Receiver<()>, order_proof_fut: TaskFuture, @@ -671,6 +921,7 @@ impl PipelineBuilder { signer: Arc, block: Arc, order_vote_enabled: bool, + network_sender: Arc, ) -> TaskResult { let mut tracker = Tracker::start_waiting("sign_commit_vote", &block); let (compute_result, _, epoch_end_timestamp) = ledger_update_fut.await?; @@ -709,11 +960,11 @@ impl PipelineBuilder { let ledger_info = LedgerInfo::new(block_info, consensus_data_hash); info!("[Pipeline] Signed ledger info {ledger_info}"); let signature = signer.sign(&ledger_info).expect("Signing should succeed"); - Ok(CommitVote::new_with_signature( - signer.author(), - ledger_info, - signature, - )) + let commit_vote = CommitVote::new_with_signature(signer.author(), ledger_info, signature); + network_sender + .broadcast_commit_vote(commit_vote.clone()) + .await; + Ok(commit_vote) } /// Precondition: 1. ledger update finishes, 2. parent block's phase finishes 2. order proof is received @@ -866,6 +1117,7 @@ impl PipelineBuilder { async fn monitor(epoch: u64, round: Round, block_id: HashValue, all_futs: PipelineFutures) { let PipelineFutures { prepare_fut, + rand_check_fut: _, execute_fut, ledger_update_fut, post_ledger_update_fut: _, diff --git a/consensus/src/pipeline/tests/buffer_manager_tests.rs b/consensus/src/pipeline/tests/buffer_manager_tests.rs index df8b01ba3e5..8a52a45ccf4 100644 --- a/consensus/src/pipeline/tests/buffer_manager_tests.rs +++ b/consensus/src/pipeline/tests/buffer_manager_tests.rs @@ -20,8 +20,7 @@ use crate::{ tests::test_utils::prepare_executed_blocks_with_ledger_info, }, test_utils::{ - consensus_runtime, timed_block_on, EmptyStateComputer, MockStorage, - RandomComputeResultStateComputer, + consensus_runtime, timed_block_on, MockStorage, RandomComputeResultStateComputer, }, }; use aptos_bounded_executor::BoundedExecutor; @@ -115,20 +114,19 @@ pub fn prepare_buffer_manager( let (self_loop_tx, self_loop_rx) = aptos_channels::new_unbounded_test(); let validators = Arc::new(validators); - let network = NetworkSender::new( + let network = Arc::new(NetworkSender::new( author, consensus_network_client, self_loop_tx, validators.clone(), - ); + )); let (msg_tx, msg_rx) = aptos_channel::new::< AccountAddress, (AccountAddress, IncomingCommitRequest), >(QueueStyle::FIFO, channel_size, None); - let (result_tx, result_rx) = create_channel::(); - let state_computer = Arc::new(EmptyStateComputer::new(result_tx)); + let (_result_tx, result_rx) = create_channel::(); let (block_tx, block_rx) = create_channel::(); let (buffer_reset_tx, buffer_reset_rx) = create_channel::(); @@ -144,11 +142,9 @@ pub fn prepare_buffer_manager( buffer_manager, ) = prepare_phases_and_buffer_manager( author, - mocked_execution_proxy, Arc::new(Mutex::new(safety_rules)), network, msg_rx, - state_computer, block_rx, buffer_reset_rx, Arc::new(EpochState { @@ -162,7 +158,6 @@ pub fn prepare_buffer_manager( ConsensusObserverConfig::default(), None, 100, - true, ); ( @@ -281,6 +276,7 @@ async fn assert_results( } #[test] +#[ignore] fn buffer_manager_happy_path_test() { // happy path let ( @@ -326,7 +322,6 @@ fn buffer_manager_happy_path_test() { .send(OrderedBlocks { ordered_blocks: batches[i].clone(), ordered_proof: proofs[i].clone(), - callback: Box::new(move |_, _| {}), }) .await .ok(); @@ -346,6 +341,7 @@ fn buffer_manager_happy_path_test() { } #[test] +#[ignore] fn buffer_manager_sync_test() { // happy path let ( @@ -393,7 +389,6 @@ fn buffer_manager_sync_test() { .send(OrderedBlocks { ordered_blocks: batches[i].clone(), ordered_proof: proofs[i].clone(), - callback: Box::new(move |_, _| {}), }) .await .ok(); @@ -423,7 +418,6 @@ fn buffer_manager_sync_test() { .send(OrderedBlocks { ordered_blocks: batches[i].clone(), ordered_proof: proofs[i].clone(), - callback: Box::new(move |_, _| {}), }) .await .ok(); diff --git a/consensus/src/pipeline/tests/execution_phase_tests.rs b/consensus/src/pipeline/tests/execution_phase_tests.rs deleted file mode 100644 index 807a22ca10c..00000000000 --- a/consensus/src/pipeline/tests/execution_phase_tests.rs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright © Aptos Foundation -// Parts of the project are originally copyright © Meta Platforms, Inc. -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - pipeline::{ - buffer_manager::create_channel, - execution_schedule_phase::{ExecutionRequest, ExecutionSchedulePhase}, - execution_wait_phase::{ExecutionResponse, ExecutionWaitPhase}, - pipeline_phase::{CountedRequest, PipelinePhase, StatelessPipeline}, - tests::phase_tester::PhaseTester, - }, - state_replication::StateComputer, - test_utils::{consensus_runtime, RandomComputeResultStateComputer}, -}; -use aptos_consensus_types::{ - block::{block_test_utils::certificate_for_genesis, Block}, - common::Payload, - pipelined_block::PipelinedBlock, - quorum_cert::QuorumCert, -}; -use aptos_crypto::HashValue; -use aptos_executor_types::{state_compute_result::StateComputeResult, ExecutorError}; -use aptos_types::{ledger_info::LedgerInfo, validator_verifier::random_validator_verifier}; -use async_trait::async_trait; -use std::sync::{ - atomic::{AtomicBool, AtomicU64}, - Arc, -}; - -// ExecutionSchedulePhase and ExecutionWaitPhase chained together. -// In BufferManager they are chained through the main loop. -pub struct ExecutionPhaseForTest { - schedule_phase: ExecutionSchedulePhase, - wait_phase: ExecutionWaitPhase, -} - -impl ExecutionPhaseForTest { - pub fn new(execution_proxy: Arc) -> Self { - let schedule_phase = ExecutionSchedulePhase::new(execution_proxy); - let wait_phase = ExecutionWaitPhase; - Self { - schedule_phase, - wait_phase, - } - } -} - -#[async_trait] -impl StatelessPipeline for ExecutionPhaseForTest { - type Request = ExecutionRequest; - type Response = ExecutionResponse; - - const NAME: &'static str = "execution"; - - async fn process(&self, req: ExecutionRequest) -> ExecutionResponse { - let wait_req = self.schedule_phase.process(req).await; - self.wait_phase.process(wait_req).await - } -} - -pub fn prepare_execution_phase() -> (HashValue, ExecutionPhaseForTest) { - let execution_proxy = Arc::new(RandomComputeResultStateComputer::new()); - let random_hash_value = execution_proxy.get_root_hash(); - let execution_phase = ExecutionPhaseForTest::new(execution_proxy); - - (random_hash_value, execution_phase) -} - -fn dummy_guard() -> CountedRequest<()> { - CountedRequest::new((), Arc::new(AtomicU64::new(0))) -} - -fn add_execution_phase_test_cases( - phase_tester: &mut PhaseTester, - random_hash_value: HashValue, -) { - let genesis_qc = certificate_for_genesis(); - let (signers, _validators) = random_validator_verifier(1, None, false); - let block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc, - &signers[0], - Vec::new(), - ) - .unwrap(); - - // happy path - phase_tester.add_test_case( - ExecutionRequest { - ordered_blocks: vec![Arc::new(PipelinedBlock::new( - block, - vec![], - StateComputeResult::new_dummy(), - ))], - lifetime_guard: dummy_guard(), - }, - Box::new(move |resp| { - assert_eq!( - resp.inner.unwrap()[0].compute_result().root_hash(), - random_hash_value - ); - }), - ); - - // empty block - phase_tester.add_test_case( - ExecutionRequest { - ordered_blocks: vec![], - lifetime_guard: dummy_guard(), - }, - Box::new(move |resp| assert!(matches!(resp.inner, Err(ExecutorError::EmptyBlocks)))), - ); - - // bad parent id - let bad_qc = QuorumCert::certificate_for_genesis_from_ledger_info( - &LedgerInfo::mock_genesis(None), - random_hash_value, - ); - let bad_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - bad_qc, - &signers[0], - Vec::new(), - ) - .unwrap(); - phase_tester.add_test_case( - ExecutionRequest { - ordered_blocks: vec![Arc::new(PipelinedBlock::new( - bad_block, - vec![], - StateComputeResult::new_dummy(), - ))], - lifetime_guard: dummy_guard(), - }, - Box::new(move |resp| assert!(matches!(resp.inner, Err(ExecutorError::BlockNotFound(_))))), - ); -} - -#[test] -fn execution_phase_tests() { - let runtime = consensus_runtime(); - - // unit tests - let (random_hash_value, execution_phase) = prepare_execution_phase(); - let mut unit_phase_tester = PhaseTester::::new(); - add_execution_phase_test_cases(&mut unit_phase_tester, random_hash_value); - unit_phase_tester.unit_test(&execution_phase); - - // e2e tests - let (in_channel_tx, in_channel_rx) = create_channel::>(); - let (out_channel_tx, out_channel_rx) = create_channel::(); - let reset_flag = Arc::new(AtomicBool::new(false)); - - let execution_phase_pipeline = PipelinePhase::new( - in_channel_rx, - Some(out_channel_tx), - Box::new(execution_phase), - reset_flag, - ); - - runtime.spawn(execution_phase_pipeline.start()); - - let mut e2e_phase_tester = PhaseTester::::new(); - add_execution_phase_test_cases(&mut e2e_phase_tester, random_hash_value); - e2e_phase_tester.e2e_test(in_channel_tx, out_channel_rx); -} diff --git a/consensus/src/pipeline/tests/mod.rs b/consensus/src/pipeline/tests/mod.rs index 2d681651415..9f5bdee653e 100644 --- a/consensus/src/pipeline/tests/mod.rs +++ b/consensus/src/pipeline/tests/mod.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: Apache-2.0 mod buffer_manager_tests; -mod execution_phase_tests; mod integration_tests; mod ordering_state_computer_tests; mod phase_tester; diff --git a/consensus/src/pipeline/tests/test_utils.rs b/consensus/src/pipeline/tests/test_utils.rs index add86853cf6..c09c50bcfdf 100644 --- a/consensus/src/pipeline/tests/test_utils.rs +++ b/consensus/src/pipeline/tests/test_utils.rs @@ -46,7 +46,7 @@ pub fn prepare_safety_rules() -> (Arc>, Vec> = proposals .iter() diff --git a/consensus/src/quorum_store/batch_coordinator.rs b/consensus/src/quorum_store/batch_coordinator.rs index 268f6591711..392cbb49048 100644 --- a/consensus/src/quorum_store/batch_coordinator.rs +++ b/consensus/src/quorum_store/batch_coordinator.rs @@ -14,6 +14,7 @@ use crate::{ }, }; use anyhow::ensure; +use aptos_config::config::BatchTransactionFilterConfig; use aptos_consensus_types::{common::BatchSizeLimits, payload::TDataInfo}; use aptos_logger::prelude::*; use aptos_short_hex_str::AsShortHexStr; @@ -42,6 +43,7 @@ pub struct BatchCoordinator { max_total_txns: u64, max_total_bytes: u64, batch_expiry_gap_when_init_usecs: u64, + transaction_filter_config: BatchTransactionFilterConfig, } impl BatchCoordinator { @@ -56,6 +58,7 @@ impl BatchCoordinator { max_total_txns: u64, max_total_bytes: u64, batch_expiry_gap_when_init_usecs: u64, + transaction_filter_config: BatchTransactionFilterConfig, ) -> Self { Self { my_peer_id, @@ -68,6 +71,7 @@ impl BatchCoordinator { max_total_txns, max_total_bytes, batch_expiry_gap_when_init_usecs, + transaction_filter_config, } } @@ -135,7 +139,7 @@ impl BatchCoordinator { Ok(()) } - async fn handle_batches_msg(&mut self, author: PeerId, batches: Vec) { + pub(crate) async fn handle_batches_msg(&mut self, author: PeerId, batches: Vec) { if let Err(e) = self.ensure_max_limits(&batches) { error!("Batch from {}: {}", author, e); counters::RECEIVED_BATCH_MAX_LIMIT_FAILED.inc(); @@ -147,6 +151,32 @@ impl BatchCoordinator { return; }; + // Filter the transactions in the batches. If any transaction is rejected, + // the message will be dropped, and all batches will be rejected. + if self.transaction_filter_config.is_enabled() { + let transaction_filter = &self.transaction_filter_config.batch_transaction_filter(); + for batch in batches.iter() { + for transaction in batch.txns() { + if !transaction_filter.allows_transaction( + batch.batch_info().batch_id(), + batch.author(), + batch.digest(), + transaction, + ) { + error!( + "Transaction {}, in batch {}, from {}, was rejected by the filter. Dropping {} batches!", + transaction.committed_hash(), + batch.batch_info().batch_id(), + author.short_str().as_str(), + batches.len() + ); + counters::RECEIVED_BATCH_REJECTED_BY_FILTER.inc(); + return; + } + } + } + } + let approx_created_ts_usecs = batch .info() .expiration() diff --git a/consensus/src/quorum_store/batch_generator.rs b/consensus/src/quorum_store/batch_generator.rs index 37bfe05634a..251f5e9bcb3 100644 --- a/consensus/src/quorum_store/batch_generator.rs +++ b/consensus/src/quorum_store/batch_generator.rs @@ -14,12 +14,12 @@ use crate::{ use aptos_config::config::QuorumStoreConfig; use aptos_consensus_types::{ common::{TransactionInProgress, TransactionSummary}, - proof_of_store::{BatchId, BatchInfo}, + proof_of_store::BatchInfo, }; use aptos_experimental_runtimes::thread_manager::optimal_min_len; use aptos_logger::prelude::*; use aptos_mempool::QuorumStoreRequest; -use aptos_types::{transaction::SignedTransaction, PeerId}; +use aptos_types::{quorum_store::BatchId, transaction::SignedTransaction, PeerId}; use futures_channel::mpsc::Sender; use rayon::prelude::*; use std::{ diff --git a/consensus/src/quorum_store/batch_proof_queue.rs b/consensus/src/quorum_store/batch_proof_queue.rs index 01a16cef86c..7f67b5d97ca 100644 --- a/consensus/src/quorum_store/batch_proof_queue.rs +++ b/consensus/src/quorum_store/batch_proof_queue.rs @@ -37,7 +37,7 @@ struct QueueItem { /// Contains the proof associated with the batch. /// It is optional as the proof can be updated after the summary. - proof: Option, + proof: Option>, /// The time when the proof is inserted into this item. proof_insertion_time: Option, } @@ -173,7 +173,7 @@ impl BatchProofQueue { } /// Add the ProofOfStore to proof queue. - pub(crate) fn insert_proof(&mut self, proof: ProofOfStore) { + pub(crate) fn insert_proof(&mut self, proof: ProofOfStore) { if proof.expiration() <= self.latest_block_timestamp { counters::inc_rejected_pos_count(counters::POS_EXPIRED_LABEL); return; @@ -342,7 +342,7 @@ impl BatchProofQueue { fn log_remaining_data_after_pull( &self, excluded_batches: &HashSet, - pulled_proofs: &[ProofOfStore], + pulled_proofs: &[ProofOfStore], ) { let mut num_proofs_remaining_after_pull = 0; let mut num_txns_remaining_after_pull = 0; @@ -406,7 +406,7 @@ impl BatchProofQueue { soft_max_txns_after_filtering: u64, return_non_full: bool, block_timestamp: Duration, - ) -> (Vec, PayloadTxnsSize, u64, bool) { + ) -> (Vec>, PayloadTxnsSize, u64, bool) { let (result, all_txns, unique_txns, is_full) = self.pull_internal( false, excluded_batches, diff --git a/consensus/src/quorum_store/batch_requester.rs b/consensus/src/quorum_store/batch_requester.rs index 5f5c4410ad0..f3391cb541a 100644 --- a/consensus/src/quorum_store/batch_requester.rs +++ b/consensus/src/quorum_store/batch_requester.rs @@ -41,7 +41,7 @@ impl BatchRequesterState { if self.num_retries == 0 { let mut rng = rand::thread_rng(); // make sure nodes request from the different set of nodes - self.next_index = rng.gen::() % signers.len(); + self.next_index = rng.r#gen::() % signers.len(); counters::SENT_BATCH_REQUEST_COUNT.inc_by(num_peers as u64); } else { counters::SENT_BATCH_REQUEST_RETRY_COUNT.inc_by(num_peers as u64); diff --git a/consensus/src/quorum_store/batch_store.rs b/consensus/src/quorum_store/batch_store.rs index e565946952f..02364580a8b 100644 --- a/consensus/src/quorum_store/batch_store.rs +++ b/consensus/src/quorum_store/batch_store.rs @@ -381,7 +381,7 @@ impl BatchStore { fn generate_signed_batch_info( &self, batch_info: BatchInfo, - ) -> Result { + ) -> Result, CryptoMaterialError> { fail_point!("quorum_store::create_invalid_signed_batch_info", |_| { Ok(SignedBatchInfo::new_with_signature( batch_info.clone(), @@ -392,7 +392,7 @@ impl BatchStore { SignedBatchInfo::new(batch_info, &self.validator_signer) } - fn persist_inner(&self, persist_request: PersistedValue) -> Option { + fn persist_inner(&self, persist_request: PersistedValue) -> Option> { match self.save(&persist_request) { Ok(needs_db) => { let batch_info = persist_request.batch_info().clone(); @@ -483,7 +483,7 @@ impl BatchStore { } impl BatchWriter for BatchStore { - fn persist(&self, persist_requests: Vec) -> Vec { + fn persist(&self, persist_requests: Vec) -> Vec> { let mut signed_infos = vec![]; for persist_request in persist_requests.into_iter() { if let Some(signed_info) = self.persist_inner(persist_request.clone()) { @@ -545,8 +545,6 @@ impl BatchReaderImpl { let responders = Arc::new(Mutex::new(responders)); let responders_clone = responders.clone(); - let subscriber_rx = self.batch_store.subscribe(*batch_info.digest()); - let inflight_requests_clone = self.inflight_fetch_requests.clone(); let batch_store = self.batch_store.clone(); let requester = self.batch_requester.clone(); @@ -561,6 +559,7 @@ impl BatchReaderImpl { } else { // Quorum store metrics counters::MISSED_BATCHES_COUNT.inc(); + let subscriber_rx = batch_store.subscribe(*batch_info.digest()); let payload = requester .request_batch( batch_digest, @@ -611,5 +610,5 @@ impl BatchReader for Batch } pub trait BatchWriter: Send + Sync { - fn persist(&self, persist_requests: Vec) -> Vec; + fn persist(&self, persist_requests: Vec) -> Vec>; } diff --git a/consensus/src/quorum_store/counters.rs b/consensus/src/quorum_store/counters.rs index 3299fc7e233..86c080e4182 100644 --- a/consensus/src/quorum_store/counters.rs +++ b/consensus/src/quorum_store/counters.rs @@ -3,6 +3,7 @@ #![allow(clippy::unwrap_used)] +use aptos_consensus_types::block::Block; use aptos_metrics_core::{ exponential_buckets, op_counters::DurationHistogram, register_avg_counter, register_histogram, register_histogram_vec, register_int_counter, register_int_counter_vec, Histogram, @@ -162,15 +163,75 @@ pub static BATCH_GENERATOR_DROPPED_OVERSIZED_TXNS: Lazy = Lazy::new( /// Histograms /// Histogram for the number of batches per (committed) blocks. -pub static NUM_BATCH_PER_BLOCK: Lazy = Lazy::new(|| { - register_histogram!( - "quorum_store_num_batch_per_block", +/// types: proof, inline_batch, opt_batch +pub static BATCH_NUM_PER_BLOCK: Lazy = Lazy::new(|| { + register_histogram_vec!( + "quorum_store_batch_num_per_block", "Histogram for the number of batches per (committed) blocks.", + &["type"], TRANSACTION_COUNT_BUCKETS.clone(), ) .unwrap() }); +/// Histogram for the number of txns per batch type in (committed) blocks. +/// types: proof, inline_batch, opt_batch +pub static TXN_NUM_PER_BATCH_TYPE_PER_BLOCK: Lazy = Lazy::new(|| { + register_histogram_vec!( + "quorum_store_txn_num_per_batch_type_per_block", + "Histogram for the number of txns per batch type in (committed) blocks.", + &["type"], + TRANSACTION_COUNT_BUCKETS.clone(), + ) + .unwrap() +}); + +/// Histogram for the txn bytes per batch type in (committed) blocks. +/// types: proof, inline_batch, opt_batch +pub static TXN_BYTES_PER_BATCH_TYPE_PER_BLOCK: Lazy = Lazy::new(|| { + register_histogram_vec!( + "quorum_store_txn_bytes_per_batch_type_per_block", + "Histogram for the txn bytes per batch type in (committed) blocks.", + &["type"], + BYTE_BUCKETS.clone(), + ) + .unwrap() +}); + +pub fn update_batch_stats(block: &Block) { + let (proof_num, proof_txn_num, proof_txn_bytes) = block.proof_stats(); + BATCH_NUM_PER_BLOCK + .with_label_values(&["proof"]) + .observe(proof_num as f64); + TXN_NUM_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["proof"]) + .observe(proof_txn_num as f64); + TXN_BYTES_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["proof"]) + .observe(proof_txn_bytes as f64); + let (inline_batch_num, inline_batch_txn_num, inline_batch_txn_bytes) = + block.inline_batch_stats(); + BATCH_NUM_PER_BLOCK + .with_label_values(&["inline_batch"]) + .observe(inline_batch_num as f64); + TXN_NUM_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["inline_batch"]) + .observe(inline_batch_txn_num as f64); + TXN_BYTES_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["inline_batch"]) + .observe(inline_batch_txn_bytes as f64); + let (opt_batch_num, opt_batch_txn_num, opt_batch_txn_bytes) = block.opt_batch_stats(); + BATCH_NUM_PER_BLOCK + .with_label_values(&["opt_batch"]) + .observe(opt_batch_num as f64); + TXN_NUM_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["opt_batch"]) + .observe(opt_batch_txn_num as f64); + TXN_BYTES_PER_BATCH_TYPE_PER_BLOCK + .with_label_values(&["opt_batch"]) + .observe(opt_batch_txn_bytes as f64); +} + /// Histogram for the number of transactions per batch. static NUM_TXN_PER_BATCH: Lazy = Lazy::new(|| { register_histogram_vec!( @@ -664,6 +725,15 @@ pub static RECEIVED_BATCH_MAX_LIMIT_FAILED: Lazy = Lazy::new(|| { .unwrap() }); +/// Count of the batch messages that contained transactions rejected by the filter +pub static RECEIVED_BATCH_REJECTED_BY_FILTER: Lazy = Lazy::new(|| { + register_int_counter!( + "quorum_store_received_batch_rejected_by_filter", + "Count of the batch messages that contained transactions rejected by the filter" + ) + .unwrap() +}); + /// Count of the missed batches when execute. pub static MISSED_BATCHES_COUNT: Lazy = Lazy::new(|| { register_int_counter!( diff --git a/consensus/src/quorum_store/proof_coordinator.rs b/consensus/src/quorum_store/proof_coordinator.rs index ff5bba176a0..506250464c7 100644 --- a/consensus/src/quorum_store/proof_coordinator.rs +++ b/consensus/src/quorum_store/proof_coordinator.rs @@ -37,7 +37,7 @@ use tokio::{ #[derive(Debug)] pub(crate) enum ProofCoordinatorCommand { - AppendSignature(PeerId, SignedBatchInfoMsg), + AppendSignature(PeerId, SignedBatchInfoMsg), CommitNotification(Vec), Shutdown(TokioOneshot::Sender<()>), } @@ -76,7 +76,7 @@ impl IncrementalProofState { fn add_signature( &mut self, - signed_batch_info: &SignedBatchInfo, + signed_batch_info: &SignedBatchInfo, validator_verifier: &ValidatorVerifier, ) -> Result<(), SignedBatchInfoError> { if signed_batch_info.batch_info() != self.signature_aggregator.data() { @@ -138,7 +138,7 @@ impl IncrementalProofState { pub fn aggregate_and_verify( &mut self, validator_verifier: &ValidatorVerifier, - ) -> Result { + ) -> Result, SignedBatchInfoError> { if self.completed { panic!("Cannot call take twice, unexpected issue occurred"); } @@ -168,7 +168,7 @@ pub(crate) struct ProofCoordinator { timeouts: Timeouts, batch_reader: Arc, batch_generator_cmd_tx: tokio::sync::mpsc::Sender, - proof_cache: ProofCache, + proof_cache: ProofCache, broadcast_proofs: bool, batch_expiry_gap_when_init_usecs: u64, } @@ -180,7 +180,7 @@ impl ProofCoordinator { peer_id: PeerId, batch_reader: Arc, batch_generator_cmd_tx: tokio::sync::mpsc::Sender, - proof_cache: ProofCache, + proof_cache: ProofCache, broadcast_proofs: bool, batch_expiry_gap_when_init_usecs: u64, ) -> Self { @@ -200,7 +200,7 @@ impl ProofCoordinator { fn init_proof( &mut self, - signed_batch_info: &SignedBatchInfo, + signed_batch_info: &SignedBatchInfo, ) -> Result<(), SignedBatchInfoError> { // Check if the signed digest corresponding to our batch if signed_batch_info.author() != self.peer_id { @@ -235,9 +235,9 @@ impl ProofCoordinator { fn add_signature( &mut self, - signed_batch_info: SignedBatchInfo, + signed_batch_info: SignedBatchInfo, validator_verifier: &ValidatorVerifier, - ) -> Result, SignedBatchInfoError> { + ) -> Result>, SignedBatchInfoError> { if !self .batch_info_to_proof .contains_key(signed_batch_info.batch_info()) diff --git a/consensus/src/quorum_store/proof_manager.rs b/consensus/src/quorum_store/proof_manager.rs index de6913ed8ae..3201574adab 100644 --- a/consensus/src/quorum_store/proof_manager.rs +++ b/consensus/src/quorum_store/proof_manager.rs @@ -21,7 +21,7 @@ use std::{cmp::min, collections::HashSet, sync::Arc, time::Duration}; #[derive(Debug)] pub enum ProofManagerCommand { - ReceiveProofs(ProofOfStoreMsg), + ReceiveProofs(ProofOfStoreMsg), ReceiveBatches(Vec<(BatchInfo, Vec)>), CommitNotification(u64, Vec), Shutdown(tokio::sync::oneshot::Sender<()>), @@ -62,7 +62,7 @@ impl ProofManager { } } - pub(crate) fn receive_proofs(&mut self, proofs: Vec) { + pub(crate) fn receive_proofs(&mut self, proofs: Vec>) { for proof in proofs.into_iter() { self.batch_proof_queue.insert_proof(proof); } diff --git a/consensus/src/quorum_store/quorum_store_builder.rs b/consensus/src/quorum_store/quorum_store_builder.rs index 33ec29b08a4..949b77fa407 100644 --- a/consensus/src/quorum_store/quorum_store_builder.rs +++ b/consensus/src/quorum_store/quorum_store_builder.rs @@ -28,9 +28,11 @@ use crate::{ round_manager::VerifiedEvent, }; use aptos_channels::{aptos_channel, message_queues::QueueStyle}; -use aptos_config::config::QuorumStoreConfig; +use aptos_config::config::{BatchTransactionFilterConfig, QuorumStoreConfig}; use aptos_consensus_types::{ - common::Author, proof_of_store::ProofCache, request_response::GetPayloadCommand, + common::Author, + proof_of_store::{BatchInfo, ProofCache}, + request_response::GetPayloadCommand, }; use aptos_crypto::bls12381::PrivateKey; use aptos_logger::prelude::*; @@ -125,13 +127,14 @@ pub struct InnerBuilder { author: Author, num_validators: u64, config: QuorumStoreConfig, + transaction_filter_config: BatchTransactionFilterConfig, consensus_to_quorum_store_receiver: Receiver, quorum_store_to_mempool_sender: Sender, mempool_txn_pull_timeout_ms: u64, aptos_db: Arc, network_sender: NetworkSender, verifier: Arc, - proof_cache: ProofCache, + proof_cache: ProofCache, coordinator_tx: Sender, coordinator_rx: Option>, batch_generator_cmd_tx: tokio::sync::mpsc::Sender, @@ -160,13 +163,14 @@ impl InnerBuilder { author: Author, num_validators: u64, config: QuorumStoreConfig, + transaction_filter_config: BatchTransactionFilterConfig, consensus_to_quorum_store_receiver: Receiver, quorum_store_to_mempool_sender: Sender, mempool_txn_pull_timeout_ms: u64, aptos_db: Arc, network_sender: NetworkSender, verifier: Arc, - proof_cache: ProofCache, + proof_cache: ProofCache, quorum_store_storage: Arc, broadcast_proofs: bool, consensus_key: Arc, @@ -199,6 +203,7 @@ impl InnerBuilder { author, num_validators, config, + transaction_filter_config, consensus_to_quorum_store_receiver, quorum_store_to_mempool_sender, mempool_txn_pull_timeout_ms, @@ -327,6 +332,7 @@ impl InnerBuilder { self.config.receiver_max_total_txns as u64, self.config.receiver_max_total_bytes as u64, self.config.batch_expiry_gap_when_init_usecs, + self.transaction_filter_config.clone(), ); #[allow(unused_variables)] let name = format!("batch_coordinator-{}", i); diff --git a/consensus/src/quorum_store/quorum_store_db.rs b/consensus/src/quorum_store/quorum_store_db.rs index bc78d6ed456..38c81a5c3de 100644 --- a/consensus/src/quorum_store/quorum_store_db.rs +++ b/consensus/src/quorum_store/quorum_store_db.rs @@ -9,10 +9,14 @@ use crate::{ }, }; use anyhow::Result; -use aptos_consensus_types::proof_of_store::BatchId; use aptos_crypto::HashValue; use aptos_logger::prelude::*; -use aptos_schemadb::{batch::SchemaBatch, Options, DB}; +use aptos_schemadb::{ + batch::{SchemaBatch, WriteBatch}, + schema::Schema, + Options, DB, +}; +use aptos_types::quorum_store::BatchId; use std::{collections::HashMap, path::Path, time::Instant}; pub trait QuorumStoreStorage: Sync + Send { @@ -59,6 +63,15 @@ impl QuorumStoreDB { Self { db } } + + /// Relaxed writes instead of sync writes. + pub fn put(&self, key: &S::Key, value: &S::Value) -> Result<(), DbError> { + // Not necessary to use a batch, but we'd like a central place to bump counters. + let mut batch = self.db.new_native_batch(); + batch.put::(key, value)?; + self.db.write_schemas_relaxed(batch)?; + Ok(()) + } } impl QuorumStoreStorage for QuorumStoreDB { @@ -68,7 +81,7 @@ impl QuorumStoreStorage for QuorumStoreDB { trace!("QS: db delete digest {}", digest); batch.delete::(digest)?; } - self.db.write_schemas(batch)?; + self.db.write_schemas_relaxed(batch)?; Ok(()) } @@ -85,7 +98,7 @@ impl QuorumStoreStorage for QuorumStoreDB { batch.digest(), batch.expiration() ); - Ok(self.db.put::(batch.digest(), &batch)?) + self.put::(batch.digest(), &batch) } fn get_batch(&self, digest: &HashValue) -> Result, DbError> { @@ -95,7 +108,7 @@ impl QuorumStoreStorage for QuorumStoreDB { fn delete_batch_id(&self, epoch: u64) -> Result<(), DbError> { let mut batch = SchemaBatch::new(); batch.delete::(&epoch)?; - self.db.write_schemas(batch)?; + self.db.write_schemas_relaxed(batch)?; Ok(()) } @@ -118,7 +131,7 @@ impl QuorumStoreStorage for QuorumStoreDB { } fn save_batch_id(&self, epoch: u64, batch_id: BatchId) -> Result<(), DbError> { - Ok(self.db.put::(&epoch, &batch_id)?) + self.put::(&epoch, &batch_id) } } diff --git a/consensus/src/quorum_store/schema.rs b/consensus/src/quorum_store/schema.rs index f6213c463c9..4de503c9cc3 100644 --- a/consensus/src/quorum_store/schema.rs +++ b/consensus/src/quorum_store/schema.rs @@ -3,12 +3,12 @@ use crate::quorum_store::types::PersistedValue; use anyhow::Result; -use aptos_consensus_types::proof_of_store::BatchId; use aptos_crypto::HashValue; use aptos_schemadb::{ schema::{KeyCodec, Schema, ValueCodec}, ColumnFamilyName, }; +use aptos_types::quorum_store::BatchId; pub(crate) const BATCH_CF_NAME: ColumnFamilyName = "batch"; pub(crate) const BATCH_ID_CF_NAME: ColumnFamilyName = "batch_ID"; diff --git a/consensus/src/quorum_store/tests/batch_coordinator_test.rs b/consensus/src/quorum_store/tests/batch_coordinator_test.rs new file mode 100644 index 00000000000..999e689c8cf --- /dev/null +++ b/consensus/src/quorum_store/tests/batch_coordinator_test.rs @@ -0,0 +1,207 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + network::NetworkSender, + network_interface::ConsensusNetworkClient, + quorum_store::{ + batch_coordinator::BatchCoordinator, batch_generator::BatchGeneratorCommand, + batch_store::BatchStore, proof_manager::ProofManagerCommand, + quorum_store_db::MockQuorumStoreDB, types::Batch, + }, +}; +use aptos_config::config::BatchTransactionFilterConfig; +use aptos_consensus_types::common::Author; +use aptos_crypto::{ed25519::Ed25519PrivateKey, PrivateKey, SigningKey, Uniform}; +use aptos_network::application::{interface::NetworkClient, storage::PeersAndMetadata}; +use aptos_transaction_filters::batch_transaction_filter::BatchTransactionFilter; +use aptos_types::{ + chain_id::ChainId, + quorum_store::BatchId, + transaction::{RawTransaction, Script, SignedTransaction, TransactionPayload}, + validator_signer::ValidatorSigner, + validator_verifier::ValidatorVerifier, + PeerId, +}; +use futures::FutureExt; +use move_core_types::account_address::AccountAddress; +use std::{collections::HashMap, sync::Arc, time::Duration}; +use tokio::{ + sync::mpsc::{channel, Sender}, + time::timeout, +}; + +#[tokio::test(flavor = "multi_thread")] +async fn test_handle_batches_msg_filter_disabled() { + // Create the message channels + let (sender_to_proof_manager, _receiver_for_proof_manager) = channel(100); + let (sender_to_batch_generator, mut receiver_for_batch_generator) = channel(100); + + // Create a filtering config with filtering disabled + let transaction_filter = BatchTransactionFilter::empty(); + let transaction_filter_config = BatchTransactionFilterConfig::new(false, transaction_filter); + + // Create a batch coordinator + let mut batch_coordinator = create_batch_coordinator( + sender_to_proof_manager, + sender_to_batch_generator, + transaction_filter_config, + ); + + // Create a single batch with some transactions + let transactions = create_signed_transactions(10); + let account_address = AccountAddress::random(); + let batch = Batch::new( + BatchId::new_for_test(100), + transactions.clone(), + 1, + 1, + account_address, + 0, + ); + + // Handle a batches message + batch_coordinator + .handle_batches_msg(account_address, vec![batch.clone()]) + .await; + + // Verify that the receiver for the batch generator received the batch + let received_message = timeout(Duration::from_secs(10), receiver_for_batch_generator.recv()) + .await + .unwrap() + .unwrap(); + if let BatchGeneratorCommand::RemoteBatch(remote_batch) = received_message { + assert_eq!(remote_batch.batch_info(), batch.batch_info()); + } else { + panic!( + "Expected a RemoteBatch command! Received: {:?}", + received_message + ); + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_handle_batches_msg_filter_enabled() { + // Create the message channels + let (sender_to_proof_manager, _receiver_for_proof_manager) = channel(100); + let (sender_to_batch_generator, mut receiver_for_batch_generator) = channel(100); + + // Create a filtering config with filtering enabled (the first transaction sender is rejected) + let transactions = create_signed_transactions(10); + let transaction_filter = + BatchTransactionFilter::empty().add_sender_filter(false, transactions[0].sender()); + let transaction_filter_config = BatchTransactionFilterConfig::new(true, transaction_filter); + + // Create a batch coordinator + let mut batch_coordinator = create_batch_coordinator( + sender_to_proof_manager, + sender_to_batch_generator, + transaction_filter_config, + ); + + // Create a single batch + let account_address = AccountAddress::random(); + let batch = Batch::new( + BatchId::new_for_test(109), + transactions.clone(), + 1, + 1, + account_address, + 0, + ); + + // Handle a batches message + batch_coordinator + .handle_batches_msg(account_address, vec![batch]) + .await; + + // Verify that the receiver for the batch generator does not receive the batch + assert!(receiver_for_batch_generator.recv().now_or_never().is_none()); +} + +/// Creates and returns a new batch coordinator with the specified parameters +fn create_batch_coordinator( + sender_to_proof_manager: Sender, + sender_to_batch_generator: Sender, + transaction_filter_config: BatchTransactionFilterConfig, +) -> BatchCoordinator { + // Create the consensus network sender and batch store + let consensus_network_sender = create_consensus_network_sender(); + let batch_store = create_batch_store(); + + // Create the batch coordinator + BatchCoordinator::new( + PeerId::random(), + consensus_network_sender, + sender_to_proof_manager, + sender_to_batch_generator, + Arc::new(batch_store), + 10_000, + 10_000, + 10_000, + 10_000, + 10_000, + transaction_filter_config, + ) +} + +/// Creates and returns a mock batch store +fn create_batch_store() -> BatchStore { + let qs_storage = Arc::new(MockQuorumStoreDB::new()); + let validator_signer = ValidatorSigner::random(None); + BatchStore::new(0, false, 0, qs_storage, 0, 0, 0, validator_signer, 0) +} + +/// Creates and returns a mock consensus network sender +fn create_consensus_network_sender() -> NetworkSender { + // Create the consensus network client + let peers_and_metadata = PeersAndMetadata::new(&[]); + let network_client = + NetworkClient::new(vec![], vec![], HashMap::new(), peers_and_metadata.clone()); + let consensus_network_client = ConsensusNetworkClient::new(network_client.clone()); + + // Create the self sender and validator verifier + let (self_sender, _self_receiver) = aptos_channels::new_unbounded_test(); + let validator_verifier = Arc::new(ValidatorVerifier::new(vec![])); + + // Create a network sender + NetworkSender::new( + Author::random(), + consensus_network_client, + self_sender, + validator_verifier, + ) +} + +/// Creates and returns a raw transaction +fn create_raw_transaction() -> RawTransaction { + RawTransaction::new( + AccountAddress::random(), + 0, + TransactionPayload::Script(Script::new(vec![], vec![], vec![])), + 0, + 0, + 0, + ChainId::new(10), + ) +} + +/// Creates and returns the specified number of signed transactions +fn create_signed_transactions(num_transactions: u64) -> Vec { + let mut signed_transactions = Vec::new(); + + for _ in 0..num_transactions { + let raw_transaction = create_raw_transaction(); + let private_key_1 = Ed25519PrivateKey::generate_for_testing(); + let signature = private_key_1.sign(&raw_transaction).unwrap(); + + let signed_transaction = SignedTransaction::new( + raw_transaction.clone(), + private_key_1.public_key(), + signature.clone(), + ); + signed_transactions.push(signed_transaction); + } + + signed_transactions +} diff --git a/consensus/src/quorum_store/tests/batch_generator_test.rs b/consensus/src/quorum_store/tests/batch_generator_test.rs index f7ef05ec274..e2ad4419c02 100644 --- a/consensus/src/quorum_store/tests/batch_generator_test.rs +++ b/consensus/src/quorum_store/tests/batch_generator_test.rs @@ -14,10 +14,10 @@ use crate::{ use aptos_config::config::QuorumStoreConfig; use aptos_consensus_types::{ common::{TransactionInProgress, TransactionSummary}, - proof_of_store::{BatchId, SignedBatchInfo}, + proof_of_store::{BatchInfo, SignedBatchInfo}, }; use aptos_mempool::{QuorumStoreRequest, QuorumStoreResponse}; -use aptos_types::transaction::SignedTransaction; +use aptos_types::{quorum_store::BatchId, transaction::SignedTransaction}; use futures::{ channel::mpsc::{channel, Receiver}, StreamExt, @@ -35,7 +35,7 @@ impl MockBatchWriter { } impl BatchWriter for MockBatchWriter { - fn persist(&self, _persist_requests: Vec) -> Vec { + fn persist(&self, _persist_requests: Vec) -> Vec> { vec![] } } diff --git a/consensus/src/quorum_store/tests/batch_proof_queue_test.rs b/consensus/src/quorum_store/tests/batch_proof_queue_test.rs index 04fd143a0c9..a75e031f1ce 100644 --- a/consensus/src/quorum_store/tests/batch_proof_queue_test.rs +++ b/consensus/src/quorum_store/tests/batch_proof_queue_test.rs @@ -6,11 +6,14 @@ use crate::quorum_store::{ }; use aptos_consensus_types::{ common::TxnSummaryWithExpiration, - proof_of_store::{BatchId, BatchInfo, ProofOfStore}, + proof_of_store::{BatchInfo, ProofOfStore}, utils::PayloadTxnsSize, }; use aptos_crypto::HashValue; -use aptos_types::{aggregate_signature::AggregateSignature, transaction::ReplayProtector, PeerId}; +use aptos_types::{ + aggregate_signature::AggregateSignature, quorum_store::BatchId, transaction::ReplayProtector, + PeerId, +}; use maplit::hashset; use std::{collections::HashSet, time::Duration}; @@ -20,7 +23,7 @@ fn proof_of_store( batch_id: BatchId, gas_bucket_start: u64, expiration: u64, -) -> ProofOfStore { +) -> ProofOfStore { ProofOfStore::new( BatchInfo::new( author, @@ -42,7 +45,7 @@ fn proof_of_store_with_size( gas_bucket_start: u64, expiration: u64, num_txns: u64, -) -> ProofOfStore { +) -> ProofOfStore { ProofOfStore::new( BatchInfo::new( author, @@ -97,7 +100,7 @@ async fn test_proof_queue_sorting() { ); let mut count_author_0 = 0; let mut count_author_1 = 0; - let mut prev: Option<&ProofOfStore> = None; + let mut prev: Option<&ProofOfStore> = None; for batch in &pulled { if let Some(prev) = prev { assert!(prev.gas_bucket_start() >= batch.gas_bucket_start()); @@ -126,7 +129,7 @@ async fn test_proof_queue_sorting() { ); let mut count_author_0 = 0; let mut count_author_1 = 0; - let mut prev: Option<&ProofOfStore> = None; + let mut prev: Option<&ProofOfStore> = None; for batch in &pulled { if let Some(prev) = prev { assert!(prev.gas_bucket_start() >= batch.gas_bucket_start()); diff --git a/consensus/src/quorum_store/tests/batch_requester_test.rs b/consensus/src/quorum_store/tests/batch_requester_test.rs index 578d232e151..01476e90eec 100644 --- a/consensus/src/quorum_store/tests/batch_requester_test.rs +++ b/consensus/src/quorum_store/tests/batch_requester_test.rs @@ -11,7 +11,7 @@ use crate::{ }; use aptos_consensus_types::{ common::Author, - proof_of_store::{BatchId, ProofOfStore, SignedBatchInfo}, + proof_of_store::{BatchInfo, ProofOfStore, SignedBatchInfo}, }; use aptos_crypto::HashValue; use aptos_infallible::Mutex; @@ -19,6 +19,7 @@ use aptos_types::{ aggregate_signature::PartialSignatures, block_info::BlockInfo, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, + quorum_store::BatchId, validator_signer::ValidatorSigner, validator_verifier::{ValidatorConsensusInfo, ValidatorVerifier}, }; @@ -55,7 +56,7 @@ impl QuorumStoreSender for MockBatchRequester { async fn send_signed_batch_info_msg( &self, - _signed_batch_infos: Vec, + _signed_batch_infos: Vec>, _recipients: Vec, ) { unimplemented!() @@ -65,11 +66,17 @@ impl QuorumStoreSender for MockBatchRequester { unimplemented!() } - async fn broadcast_proof_of_store_msg(&mut self, _proof_of_stores: Vec) { + async fn broadcast_proof_of_store_msg( + &mut self, + _proof_of_stores: Vec>, + ) { unimplemented!() } - async fn send_proof_of_store_msg_to_self(&mut self, _proof_of_stores: Vec) { + async fn send_proof_of_store_msg_to_self( + &mut self, + _proof_of_stores: Vec>, + ) { unimplemented!() } } diff --git a/consensus/src/quorum_store/tests/batch_store_test.rs b/consensus/src/quorum_store/tests/batch_store_test.rs index 2992700b05d..a2704c2bf80 100644 --- a/consensus/src/quorum_store/tests/batch_store_test.rs +++ b/consensus/src/quorum_store/tests/batch_store_test.rs @@ -6,11 +6,11 @@ use crate::quorum_store::{ quorum_store_db::QuorumStoreDB, types::{PersistedValue, StorageMode}, }; -use aptos_consensus_types::proof_of_store::{BatchId, BatchInfo}; +use aptos_consensus_types::proof_of_store::BatchInfo; use aptos_crypto::HashValue; use aptos_temppath::TempPath; use aptos_types::{ - account_address::AccountAddress, transaction::SignedTransaction, + account_address::AccountAddress, quorum_store::BatchId, transaction::SignedTransaction, validator_verifier::random_validator_verifier, }; use claims::{assert_err, assert_ok, assert_ok_eq}; diff --git a/consensus/src/quorum_store/tests/mod.rs b/consensus/src/quorum_store/tests/mod.rs index fc7c97f6de9..00cb5daf8d6 100644 --- a/consensus/src/quorum_store/tests/mod.rs +++ b/consensus/src/quorum_store/tests/mod.rs @@ -1,6 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +mod batch_coordinator_test; mod batch_generator_test; mod batch_proof_queue_test; mod batch_requester_test; diff --git a/consensus/src/quorum_store/tests/proof_coordinator_test.rs b/consensus/src/quorum_store/tests/proof_coordinator_test.rs index 4bd4277f3ef..efb2e40136d 100644 --- a/consensus/src/quorum_store/tests/proof_coordinator_test.rs +++ b/consensus/src/quorum_store/tests/proof_coordinator_test.rs @@ -10,13 +10,12 @@ use crate::{ }, test_utils::{create_vec_signed_transactions, mock_quorum_store_sender::MockQuorumStoreSender}, }; -use aptos_consensus_types::proof_of_store::{ - BatchId, BatchInfo, SignedBatchInfo, SignedBatchInfoMsg, -}; +use aptos_consensus_types::proof_of_store::{BatchInfo, SignedBatchInfo, SignedBatchInfoMsg}; use aptos_crypto::HashValue; use aptos_executor_types::ExecutorResult; use aptos_types::{ - transaction::SignedTransaction, validator_verifier::random_validator_verifier, PeerId, + quorum_store::BatchId, transaction::SignedTransaction, + validator_verifier::random_validator_verifier, PeerId, }; use futures::future::Shared; use mini_moka::sync::Cache; diff --git a/consensus/src/quorum_store/tests/proof_manager_test.rs b/consensus/src/quorum_store/tests/proof_manager_test.rs index 1c10027d53f..9f188e71598 100644 --- a/consensus/src/quorum_store/tests/proof_manager_test.rs +++ b/consensus/src/quorum_store/tests/proof_manager_test.rs @@ -6,12 +6,12 @@ use crate::quorum_store::{ }; use aptos_consensus_types::{ common::{Payload, PayloadFilter}, - proof_of_store::{BatchId, BatchInfo, ProofOfStore}, + proof_of_store::{BatchInfo, ProofOfStore}, request_response::{GetPayloadCommand, GetPayloadRequest, GetPayloadResponse}, utils::PayloadTxnsSize, }; use aptos_crypto::HashValue; -use aptos_types::{aggregate_signature::AggregateSignature, PeerId}; +use aptos_types::{aggregate_signature::AggregateSignature, quorum_store::BatchId, PeerId}; use futures::channel::oneshot; use std::{cmp::max, collections::HashSet}; @@ -20,7 +20,7 @@ fn create_proof_manager() -> ProofManager { ProofManager::new(PeerId::random(), 10, 10, batch_store, true, true, 1) } -fn create_proof(author: PeerId, expiration: u64, batch_sequence: u64) -> ProofOfStore { +fn create_proof(author: PeerId, expiration: u64, batch_sequence: u64) -> ProofOfStore { create_proof_with_gas(author, expiration, batch_sequence, 0) } @@ -29,7 +29,7 @@ fn create_proof_with_gas( expiration: u64, batch_sequence: u64, gas_bucket_start: u64, -) -> ProofOfStore { +) -> ProofOfStore { let digest = HashValue::random(); let batch_id = BatchId::new_for_test(batch_sequence); ProofOfStore::new( @@ -72,7 +72,7 @@ async fn get_proposal( fn assert_payload_response( payload: Payload, - expected: &[ProofOfStore], + expected: &[ProofOfStore], max_txns_from_block_to_execute: Option, expected_block_gas_limit: Option, ) { @@ -116,7 +116,7 @@ async fn get_proposal_and_assert( proof_manager: &mut ProofManager, max_txns: u64, filter: &[BatchInfo], - expected: &[ProofOfStore], + expected: &[ProofOfStore], ) { assert_payload_response( get_proposal(proof_manager, max_txns, filter).await, diff --git a/consensus/src/quorum_store/tests/quorum_store_db_test.rs b/consensus/src/quorum_store/tests/quorum_store_db_test.rs index 2bdc060abc4..9d526499e97 100644 --- a/consensus/src/quorum_store/tests/quorum_store_db_test.rs +++ b/consensus/src/quorum_store/tests/quorum_store_db_test.rs @@ -8,9 +8,8 @@ use crate::{ }, test_utils::create_vec_signed_transactions, }; -use aptos_consensus_types::proof_of_store::BatchId; use aptos_temppath::TempPath; -use aptos_types::account_address::AccountAddress; +use aptos_types::{account_address::AccountAddress, quorum_store::BatchId}; use claims::assert_ok; #[test] diff --git a/consensus/src/quorum_store/tests/types_test.rs b/consensus/src/quorum_store/tests/types_test.rs index 81bafe86959..7ec22efc24d 100644 --- a/consensus/src/quorum_store/tests/types_test.rs +++ b/consensus/src/quorum_store/tests/types_test.rs @@ -5,9 +5,9 @@ use crate::{ quorum_store::types::{Batch, BatchRequest}, test_utils::create_vec_signed_transactions, }; -use aptos_consensus_types::{common::BatchPayload, proof_of_store::BatchId}; +use aptos_consensus_types::common::BatchPayload; use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_types::account_address::AccountAddress; +use aptos_types::{account_address::AccountAddress, quorum_store::BatchId}; use claims::{assert_err, assert_ok}; #[test] diff --git a/consensus/src/quorum_store/types.rs b/consensus/src/quorum_store/types.rs index 62e781ce9dd..3254305b6d8 100644 --- a/consensus/src/quorum_store/types.rs +++ b/consensus/src/quorum_store/types.rs @@ -4,11 +4,11 @@ use anyhow::ensure; use aptos_consensus_types::{ common::{BatchPayload, TxnSummaryWithExpiration}, - proof_of_store::{BatchId, BatchInfo}, + proof_of_store::BatchInfo, }; use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_types::{ - ledger_info::LedgerInfoWithSignatures, transaction::SignedTransaction, + ledger_info::LedgerInfoWithSignatures, quorum_store::BatchId, transaction::SignedTransaction, validator_verifier::ValidatorVerifier, PeerId, }; use serde::{Deserialize, Serialize}; @@ -177,7 +177,11 @@ impl Batch { ensure!( txn.gas_unit_price() >= self.gas_bucket_start(), "Payload gas unit price doesn't match batch info" - ) + ); + ensure!( + !txn.payload().is_encrypted_variant(), + "Encrypted transaction is not supported yet" + ); } Ok(()) } diff --git a/consensus/src/quorum_store/utils.rs b/consensus/src/quorum_store/utils.rs index 74dcc0fdac0..91e8d61d9e3 100644 --- a/consensus/src/quorum_store/utils.rs +++ b/consensus/src/quorum_store/utils.rs @@ -4,11 +4,11 @@ use crate::monitor; use aptos_consensus_types::{ common::{TransactionInProgress, TransactionSummary}, - proof_of_store::{BatchId, BatchInfo}, + proof_of_store::BatchInfo, }; use aptos_logger::prelude::*; use aptos_mempool::{QuorumStoreRequest, QuorumStoreResponse}; -use aptos_types::{transaction::SignedTransaction, PeerId}; +use aptos_types::{quorum_store::BatchId, transaction::SignedTransaction, PeerId}; use chrono::Utc; use futures::channel::{mpsc::Sender, oneshot}; use std::{ diff --git a/consensus/src/rand/rand_gen/network_messages.rs b/consensus/src/rand/rand_gen/network_messages.rs index c8d5df200c4..18d7a17dc17 100644 --- a/consensus/src/rand/rand_gen/network_messages.rs +++ b/consensus/src/rand/rand_gen/network_messages.rs @@ -161,7 +161,7 @@ mod tests { use aptos_consensus_types::common::Author; use aptos_crypto::{bls12381, Uniform}; use aptos_dkg::{ - pvss::{traits::Transcript, Player, WeightedConfig}, + pvss::{traits::Transcript, Player, WeightedConfigBlstrs}, weighted_vuf::traits::WeightedVUF, }; use aptos_types::{ @@ -253,6 +253,7 @@ mod tests { &input, 0, &bundles[0].bls_sk, + &bundles[0].bls_pk, ); // Pull this validator's secret WVUF share, then augment it. @@ -281,10 +282,10 @@ mod tests { } } - fn weighted_threshold_config(weights: &[u64]) -> WeightedConfig { + fn weighted_threshold_config(weights: &[u64]) -> WeightedConfigBlstrs { let usize_weights: Vec = weights.iter().map(|w| *w as usize).collect(); let total: usize = usize_weights.iter().sum(); - WeightedConfig::new(total / 2, usize_weights).unwrap() + WeightedConfigBlstrs::new(total / 2, usize_weights).unwrap() } /// Minimal fixture for exercising `RandMessage::verify`. The cryptographic diff --git a/consensus/src/rand/rand_gen/rand_store.rs b/consensus/src/rand/rand_gen/rand_store.rs index 33b04639a3d..861f0f1c20e 100644 --- a/consensus/src/rand/rand_gen/rand_store.rs +++ b/consensus/src/rand/rand_gen/rand_store.rs @@ -349,7 +349,7 @@ mod tests { use aptos_consensus_types::common::Author; use aptos_crypto::{bls12381, HashValue, Uniform}; use aptos_dkg::{ - pvss::{traits::Transcript, Player, WeightedConfig}, + pvss::{traits::Transcript, Player, WeightedConfigBlstrs}, weighted_vuf::traits::WeightedVUF, }; use aptos_types::{ @@ -421,6 +421,7 @@ mod tests { &input_secret, 0, &private_keys[0], + &public_keys[0], ); let (sk, pk) = DefaultDKG::decrypt_secret_share_from_transcript( &dkg_pub_params, @@ -444,7 +445,7 @@ mod tests { let rand_keys = RandKeys::new(ask, apk, pk_shares, num_validators); let weights: Vec = weights.into_iter().map(|x| x as usize).collect(); let half_total_weights = weights.clone().into_iter().sum::() / 2; - let weighted_config = WeightedConfig::new(half_total_weights, weights).unwrap(); + let weighted_config = WeightedConfigBlstrs::new(half_total_weights, weights).unwrap(); let rand_config = RandConfig::new( authors[my_index], target_epoch, diff --git a/consensus/src/rand/rand_gen/test_utils.rs b/consensus/src/rand/rand_gen/test_utils.rs index 29b9f4aa1a1..6323fa70fa7 100644 --- a/consensus/src/rand/rand_gen/test_utils.rs +++ b/consensus/src/rand/rand_gen/test_utils.rs @@ -48,7 +48,6 @@ pub fn create_ordered_blocks(rounds: Vec) -> OrderedBlocks { LedgerInfo::mock_genesis(None), AggregateSignature::empty(), ), - callback: Box::new(move |_, _| {}), } } diff --git a/consensus/src/rand/rand_gen/types.rs b/consensus/src/rand/rand_gen/types.rs index 61a31c33ec4..2545ae1e939 100644 --- a/consensus/src/rand/rand_gen/types.rs +++ b/consensus/src/rand/rand_gen/types.rs @@ -6,7 +6,7 @@ use aptos_consensus_types::common::{Author, Round}; use aptos_crypto::bls12381::Signature; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use aptos_dkg::{ - pvss::{Player, WeightedConfig}, + pvss::{Player, WeightedConfigBlstrs}, weighted_vuf::traits::WeightedVUF, }; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; @@ -587,7 +587,7 @@ pub struct RandConfig { // key shares for weighted VUF keys: Arc, // weighted config for weighted VUF - wconfig: WeightedConfig, + wconfig: WeightedConfigBlstrs, } impl Debug for RandConfig { @@ -607,7 +607,7 @@ impl RandConfig { validator: Arc, vuf_pp: WvufPP, keys: RandKeys, - wconfig: WeightedConfig, + wconfig: WeightedConfigBlstrs, ) -> Self { Self { author, diff --git a/consensus/src/recovery_manager.rs b/consensus/src/recovery_manager.rs index 5474141aca7..1137ecf4269 100644 --- a/consensus/src/recovery_manager.rs +++ b/consensus/src/recovery_manager.rs @@ -110,6 +110,7 @@ impl RecoveryManager { self.payload_manager.clone(), self.order_vote_enabled, self.window_size, + None, ) .await?; diff --git a/consensus/src/round_manager.rs b/consensus/src/round_manager.rs index 6ad77675b82..a4711e82a1b 100644 --- a/consensus/src/round_manager.rs +++ b/consensus/src/round_manager.rs @@ -35,15 +35,17 @@ use crate::{ }; use anyhow::{bail, ensure, Context}; use aptos_channels::aptos_channel; -use aptos_config::config::ConsensusConfig; +use aptos_config::config::{BlockTransactionFilterConfig, ConsensusConfig}; use aptos_consensus_types::{ block::Block, block_data::BlockType, common::{Author, BatchSizeLimits, Round}, + opt_block_data::OptBlockData, + opt_proposal_msg::OptProposalMsg, order_vote::OrderVote, order_vote_msg::OrderVoteMsg, pipelined_block::PipelinedBlock, - proof_of_store::{ProofCache, ProofOfStoreMsg, SignedBatchInfoMsg}, + proof_of_store::{BatchInfo, ProofCache, ProofOfStoreMsg, SignedBatchInfoMsg}, proposal_msg::ProposalMsg, quorum_cert::QuorumCert, round_timeout::{RoundTimeout, RoundTimeoutMsg, RoundTimeoutReason}, @@ -73,10 +75,13 @@ use aptos_types::{ PeerId, }; use fail::fail_point; -use futures::{channel::oneshot, stream::FuturesUnordered, Future, FutureExt, StreamExt}; +use futures::{channel::oneshot, stream::FuturesUnordered, Future, FutureExt, SinkExt, StreamExt}; use lru::LruCache; use serde::Serialize; -use std::{mem::Discriminant, pin::Pin, sync::Arc, time::Duration}; +use std::{ + collections::BTreeMap, mem::Discriminant, num::NonZeroUsize, ops::Add, pin::Pin, sync::Arc, + time::Duration, +}; use tokio::{ sync::oneshot as TokioOneshot, time::{sleep, Instant}, @@ -90,8 +95,9 @@ pub enum UnverifiedEvent { OrderVoteMsg(Box), SyncInfo(Box), BatchMsg(Box), - SignedBatchInfo(Box), - ProofOfStoreMsg(Box), + SignedBatchInfo(Box>), + ProofOfStoreMsg(Box>), + OptProposalMsg(Box), } pub const BACK_PRESSURE_POLLING_INTERVAL_MS: u64 = 10; @@ -101,7 +107,7 @@ impl UnverifiedEvent { self, peer_id: PeerId, validator: &ValidatorVerifier, - proof_cache: &ProofCache, + proof_cache: &ProofCache, quorum_store_enabled: bool, self_message: bool, max_num_batches: usize, @@ -120,6 +126,15 @@ impl UnverifiedEvent { } VerifiedEvent::ProposalMsg(p) }, + UnverifiedEvent::OptProposalMsg(p) => { + if !self_message { + p.verify(peer_id, validator, proof_cache, quorum_store_enabled, size_limits)?; + counters::VERIFY_MSG + .with_label_values(&["opt_proposal"]) + .observe(start_time.elapsed().as_secs_f64()); + } + VerifiedEvent::OptProposalMsg(p) + }, UnverifiedEvent::VoteMsg(v) => { if !self_message { v.verify(peer_id, validator)?; @@ -187,6 +202,7 @@ impl UnverifiedEvent { pub fn epoch(&self) -> anyhow::Result { match self { UnverifiedEvent::ProposalMsg(p) => Ok(p.epoch()), + UnverifiedEvent::OptProposalMsg(p) => Ok(p.epoch()), UnverifiedEvent::VoteMsg(v) => Ok(v.epoch()), UnverifiedEvent::OrderVoteMsg(v) => Ok(v.epoch()), UnverifiedEvent::SyncInfo(s) => Ok(s.epoch()), @@ -202,6 +218,7 @@ impl From for UnverifiedEvent { fn from(value: ConsensusMsg) -> Self { match value { ConsensusMsg::ProposalMsg(m) => UnverifiedEvent::ProposalMsg(m), + ConsensusMsg::OptProposalMsg(m) => UnverifiedEvent::OptProposalMsg(m), ConsensusMsg::VoteMsg(m) => UnverifiedEvent::VoteMsg(m), ConsensusMsg::OrderVoteMsg(m) => UnverifiedEvent::OrderVoteMsg(m), ConsensusMsg::SyncInfo(m) => UnverifiedEvent::SyncInfo(m), @@ -224,17 +241,18 @@ pub enum VerifiedEvent { OrderVoteMsg(Box), UnverifiedSyncInfo(Box), BatchMsg(Box), - SignedBatchInfo(Box), - ProofOfStoreMsg(Box), + SignedBatchInfo(Box>), + ProofOfStoreMsg(Box>), // local messages LocalTimeout(Round), // Shutdown the NetworkListener Shutdown(TokioOneshot::Sender<()>), + OptProposalMsg(Box), } #[cfg(test)] -#[path = "round_manager_test.rs"] -mod round_manager_test; +#[path = "round_manager_tests/mod.rs"] +mod round_manager_tests; #[cfg(feature = "fuzzing")] #[path = "round_manager_fuzzing.rs"] @@ -257,6 +275,7 @@ pub struct RoundManager { onchain_config: OnChainConsensusConfig, vtxn_config: ValidatorTxnConfig, buffered_proposal_tx: aptos_channel::Sender, + block_txn_filter_config: BlockTransactionFilterConfig, local_config: ConsensusConfig, randomness_config: OnChainRandomnessConfig, jwk_consensus_config: OnChainJWKConsensusConfig, @@ -271,6 +290,8 @@ pub struct RoundManager { Pin, Block, Instant)> + Send>>, >, proposal_status_tracker: Arc, + pending_opt_proposals: BTreeMap, + opt_proposal_loopback_tx: aptos_channels::UnboundedSender, } impl RoundManager { @@ -286,11 +307,13 @@ impl RoundManager { storage: Arc, onchain_config: OnChainConsensusConfig, buffered_proposal_tx: aptos_channel::Sender, + block_txn_filter_config: BlockTransactionFilterConfig, local_config: ConsensusConfig, randomness_config: OnChainRandomnessConfig, jwk_consensus_config: OnChainJWKConsensusConfig, fast_rand_config: Option, proposal_status_tracker: Arc, + opt_proposal_loopback_tx: aptos_channels::UnboundedSender, ) -> Self { // when decoupled execution is false, // the counter is still static. @@ -314,14 +337,19 @@ impl RoundManager { onchain_config, vtxn_config, buffered_proposal_tx, + block_txn_filter_config, local_config, randomness_config, jwk_consensus_config, fast_rand_config, pending_order_votes: PendingOrderVotes::new(), - blocks_with_broadcasted_fast_shares: LruCache::new(5), + blocks_with_broadcasted_fast_shares: LruCache::new( + NonZeroUsize::new(5).expect("LRU capacity should be non-zero."), + ), futures: FuturesUnordered::new(), proposal_status_tracker, + pending_opt_proposals: BTreeMap::new(), + opt_proposal_loopback_tx, } } @@ -404,7 +432,23 @@ impl RoundManager { self.proposal_status_tracker .push(new_round_event.reason.clone()); - if is_current_proposer { + // Process pending opt proposal for the new round. + // The existence of pending optimistic proposal and being the current proposer are mutually + // exclusive. Note that the opt proposal is checked for valid proposer before inserting into + // the pending queue. + if let Some(opt_proposal) = self.pending_opt_proposals.remove(&new_round) { + self.opt_proposal_loopback_tx + .send(opt_proposal) + .await + .expect("Sending to a self loopback unbounded channel cannot fail"); + } + + // If the current proposer is the leading, try to propose a regular block if not opt proposed already + if is_current_proposer + && self + .proposal_generator + .can_propose_in_round(new_round_event.round) + { let epoch_state = self.epoch_state.clone(); let network = self.network.clone(); let sync_info = self.block_store.sync_info(); @@ -446,7 +490,6 @@ impl RoundManager { epoch_state.clone(), new_round_event, sync_info, - network.clone(), proposal_generator, safety_rules, proposer_election, @@ -468,6 +511,31 @@ impl RoundManager { Ok(()) } + async fn generate_and_send_opt_proposal( + epoch_state: Arc, + round: Round, + parent: BlockInfo, + grandparent_qc: QuorumCert, + network: Arc, + sync_info: SyncInfo, + proposal_generator: Arc, + proposer_election: Arc, + ) -> anyhow::Result<()> { + let proposal_msg = Self::generate_opt_proposal( + epoch_state.clone(), + round, + parent, + grandparent_qc, + sync_info, + proposal_generator, + proposer_election, + ) + .await?; + network.broadcast_opt_proposal(proposal_msg).await; + counters::PROPOSALS_COUNT.inc(); + Ok(()) + } + fn log_collected_vote_stats(epoch_state: Arc, new_round_event: &NewRoundEvent) { let prev_round_votes_for_li = new_round_event .prev_round_votes @@ -553,7 +621,6 @@ impl RoundManager { self.epoch_state.clone(), new_round_event, self.block_store.sync_info(), - self.network.clone(), self.proposal_generator.clone(), self.safety_rules.clone(), self.proposer_election.clone(), @@ -565,20 +632,12 @@ impl RoundManager { epoch_state: Arc, new_round_event: NewRoundEvent, sync_info: SyncInfo, - network: Arc, proposal_generator: Arc, safety_rules: Arc>, proposer_election: Arc, ) -> anyhow::Result { - // Proposal generator will ensure that at most one proposal is generated per round - let callback_sync_info = sync_info.clone(); - let callback = async move { - network.broadcast_sync_info(callback_sync_info).await; - } - .boxed(); - let proposal = proposal_generator - .generate_proposal(new_round_event.round, proposer_election, callback) + .generate_proposal(new_round_event.round, proposer_election) .await?; let signature = safety_rules.lock().sign_proposal(&proposal)?; let signed_proposal = @@ -595,6 +654,35 @@ impl RoundManager { Ok(ProposalMsg::new(signed_proposal, sync_info)) } + async fn generate_opt_proposal( + epoch_state: Arc, + round: Round, + parent: BlockInfo, + grandparent_qc: QuorumCert, + sync_info: SyncInfo, + proposal_generator: Arc, + proposer_election: Arc, + ) -> anyhow::Result { + // Proposal generator will ensure that at most one proposal is generated per round + + let proposal = proposal_generator + .generate_opt_proposal( + epoch_state.epoch, + round, + parent, + grandparent_qc, + proposer_election, + ) + .await?; + observe_block(proposal.timestamp_usecs(), BlockStage::OPT_PROPOSED); + info!(Self::new_log_with_round_epoch( + LogEvent::OptPropose, + round, + epoch_state.epoch + ),); + Ok(OptProposalMsg::new(proposal, sync_info)) + } + /// Process the proposal message: /// 1. ensure after processing sync info, we're at the same round as the proposal /// 2. execute and decide whether to vote for the proposal @@ -651,6 +739,104 @@ impl RoundManager { self.process_verified_proposal(proposal).await } + /// Process the optimistic proposal message: + /// If entered the round of opt proposal, process the opt proposal directly. + /// Otherwise, buffer the opt proposal and process it later when parent QC is available. + pub async fn process_opt_proposal_msg( + &mut self, + proposal_msg: OptProposalMsg, + ) -> anyhow::Result<()> { + ensure!(self.local_config.enable_optimistic_proposal_rx, + "Opt proposal is disabled, but received opt proposal msg of epoch {} round {} from peer {}", + proposal_msg.block_data().epoch(), proposal_msg.round(), proposal_msg.proposer() + ); + + fail_point!("consensus::process_opt_proposal_msg", |_| { + Err(anyhow::anyhow!( + "Injected error in process_opt_proposal_msg" + )) + }); + + observe_block( + proposal_msg.block_data().timestamp_usecs(), + BlockStage::ROUND_MANAGER_RECEIVED, + ); + observe_block( + proposal_msg.block_data().timestamp_usecs(), + BlockStage::ROUND_MANAGER_RECEIVED_OPT_PROPOSAL, + ); + info!( + self.new_log(LogEvent::ReceiveOptProposal), + block_author = proposal_msg.proposer(), + block_epoch = proposal_msg.block_data().epoch(), + block_round = proposal_msg.round(), + block_parent_hash = proposal_msg.block_data().parent_id(), + ); + + self.sync_up(proposal_msg.sync_info(), proposal_msg.proposer()) + .await?; + + if self.round_state.current_round() == proposal_msg.round() { + self.opt_proposal_loopback_tx + .send(proposal_msg.take_block_data()) + .await + .expect("Sending to a self loopback unbounded channel cannot fail"); + } else { + // Pre-check that proposal is from valid proposer before queuing it. + // This check is done after syncing up to sync info to ensure proposer + // election provider is up to date. + ensure!( + self.proposer_election + .is_valid_proposer(proposal_msg.proposer(), proposal_msg.round()), + "[OptProposal] Not a valid proposer for round {}: {}", + proposal_msg.round(), + proposal_msg.proposer() + ); + self.pending_opt_proposals + .insert(proposal_msg.round(), proposal_msg.take_block_data()); + } + + Ok(()) + } + + /// Process the optimistic proposal: + /// 1. Ensure the highest quorum cert certifies the parent block of the opt block + /// 2. Create a regular proposal by adding QC and failed_authors to the opt block + /// 3. Process the proposal using exsiting logic + async fn process_opt_proposal(&mut self, opt_block_data: OptBlockData) -> anyhow::Result<()> { + ensure!( + self.block_store + .get_block_for_round(opt_block_data.round()) + .is_none(), + "Proposal has already been processed for round: {}", + opt_block_data.round() + ); + let hqc = self.block_store.highest_quorum_cert().as_ref().clone(); + ensure!( + hqc.certified_block().round() + 1 == opt_block_data.round(), + "Opt proposal round {} is not the next round after the highest qc round {}", + opt_block_data.round(), + hqc.certified_block().round() + ); + ensure!( + hqc.certified_block().id() == opt_block_data.parent_id(), + "Opt proposal parent id {} is not the same as the highest qc certified block id {}", + opt_block_data.parent_id(), + hqc.certified_block().id() + ); + let proposal = Block::new_from_opt(opt_block_data, hqc); + observe_block(proposal.timestamp_usecs(), BlockStage::PROCESS_OPT_PROPOSAL); + info!( + self.new_log(LogEvent::ProcessOptProposal), + block_author = proposal.author(), + block_epoch = proposal.epoch(), + block_round = proposal.round(), + block_hash = proposal.id(), + block_parent_hash = proposal.quorum_cert().certified_block().id(), + ); + self.process_proposal(proposal).await + } + /// Sync to the sync info sending from peer if it has newer certificates. async fn sync_up(&mut self, sync_info: &SyncInfo, author: Author) -> anyhow::Result<()> { let local_sync_info = self.block_store.sync_info(); @@ -897,7 +1083,7 @@ impl RoundManager { ) { counters::UNEXPECTED_PROPOSAL_EXT_COUNT.inc(); - bail!("ProposalExt unexpected while the feature is disabled."); + bail!("ProposalExt unexpected while the vtxn feature is disabled."); } if let Some(vtxns) = proposal.validator_txns() { @@ -976,20 +1162,36 @@ impl RoundManager { proposal, ); - // Validate that failed_authors list is correctly specified in the block. - let expected_failed_authors = self.proposal_generator.compute_failed_authors( - proposal.round(), - proposal.quorum_cert().certified_block().round(), - false, - self.proposer_election.clone(), - ); - ensure!( - proposal.block_data().failed_authors().is_some_and(|failed_authors| *failed_authors == expected_failed_authors), - "[RoundManager] Proposal for block {} has invalid failed_authors list {:?}, expected {:?}", - proposal.round(), - proposal.block_data().failed_authors(), - expected_failed_authors, - ); + // If the proposal contains any inline transactions that need to be denied + // (e.g., due to filtering) drop the message and do not vote for the block. + if let Err(error) = self + .block_store + .check_denied_inline_transactions(&proposal, &self.block_txn_filter_config) + { + counters::REJECTED_PROPOSAL_DENY_TXN_COUNT.inc(); + bail!( + "[RoundManager] Proposal for block {} contains denied inline transactions: {}. Dropping proposal!", + proposal.id(), + error + ); + } + + if !proposal.is_opt_block() { + // Validate that failed_authors list is correctly specified in the block. + let expected_failed_authors = self.proposal_generator.compute_failed_authors( + proposal.round(), + proposal.quorum_cert().certified_block().round(), + false, + self.proposer_election.clone(), + ); + ensure!( + proposal.block_data().failed_authors().is_some_and(|failed_authors| *failed_authors == expected_failed_authors), + "[RoundManager] Proposal for block {} has invalid failed_authors list {:?}, expected {:?}", + proposal.round(), + proposal.block_data().failed_authors(), + expected_failed_authors, + ); + } let block_time_since_epoch = Duration::from_micros(proposal.timestamp_usecs()); @@ -1002,6 +1204,9 @@ impl RoundManager { ); observe_block(proposal.timestamp_usecs(), BlockStage::SYNCED); + if proposal.is_opt_block() { + observe_block(proposal.timestamp_usecs(), BlockStage::SYNCED_OPT_BLOCK); + } // Since processing proposal is delayed due to backpressure or payload availability, we add // the block to the block store so that we don't need to fetch it from remote once we @@ -1009,7 +1214,7 @@ impl RoundManager { // guaranteed to add the block to the block store if we don't get out of the backpressure // before the timeout, so this is needed to ensure that the proposed block is added to // the block store irrespective. Also, it is possible that delayed processing of proposal - // tries to add the same block again, which is okay as `execute_and_insert_block` call + // tries to add the same block again, which is okay as `insert_block` call // is idempotent. self.block_store .insert_block(proposal.clone()) @@ -1139,6 +1344,7 @@ impl RoundManager { pub async fn process_verified_proposal(&mut self, proposal: Block) -> anyhow::Result<()> { let proposal_round = proposal.round(); + let parent_qc = proposal.quorum_cert().clone(); let sync_info = self.block_store.sync_info(); if proposal_round <= sync_info.highest_round() { @@ -1174,6 +1380,78 @@ impl RoundManager { ); self.network.send_vote(vote_msg, vec![recipient]).await; } + + if let Err(e) = self.start_next_opt_round(vote, parent_qc) { + debug!("Cannot start next opt round: {}", e); + }; + Ok(()) + } + + fn start_next_opt_round( + &self, + parent_vote: Vote, + grandparent_qc: QuorumCert, + ) -> anyhow::Result<()> { + // Optimistic Proposal: + // When receiving round r block, send optimistic proposal for round r+1 if: + // 0. opt proposal is enabled + // 1. it is the leader of the next round r+1 + // 2. voted for round r block + // 3. the round r block contains QC of round r-1 + // 4. does not propose in round r+1 + if !self.local_config.enable_optimistic_proposal_tx { + return Ok(()); + }; + + ensure!( + !self.proposal_generator.is_proposal_under_backpressure(), + "Cannot start next opt round due to backpressure" + ); + + let parent = parent_vote.vote_data().proposed().clone(); + let opt_proposal_round = parent.round() + 1; + if self + .proposer_election + .is_valid_proposer(self.proposal_generator.author(), opt_proposal_round) + { + let expected_grandparent_round = parent + .round() + .checked_sub(1) + .ok_or_else(|| anyhow::anyhow!("Invalid parent round {}", parent.round()))?; + ensure!( + grandparent_qc.certified_block().round() == expected_grandparent_round, + "Cannot start Optimistic Round. Grandparent QC is not for round minus one: {} < {}", + grandparent_qc.certified_block().round(), + parent.round() + ); + + let epoch_state = self.epoch_state.clone(); + let network = self.network.clone(); + let sync_info = self.block_store.sync_info(); + let proposal_generator = self.proposal_generator.clone(); + let proposer_election = self.proposer_election.clone(); + tokio::spawn(async move { + if let Err(e) = monitor!( + "generate_and_send_opt_proposal", + Self::generate_and_send_opt_proposal( + epoch_state, + opt_proposal_round, + parent, + grandparent_qc, + network, + sync_info, + proposal_generator, + proposer_election, + ) + .await + ) { + warn!( + "[OptProposal] Error generating and sending opt proposal: {}", + e + ); + } + }); + } Ok(()) } @@ -1214,6 +1492,13 @@ impl RoundManager { observe_block(block_arc.block().timestamp_usecs(), BlockStage::VOTED); } + if block_arc.block().is_opt_block() { + observe_block( + block_arc.block().timestamp_usecs(), + BlockStage::VOTED_OPT_BLOCK, + ); + } + self.storage .save_vote(&vote) .context("[RoundManager] Fail to persist last vote")?; @@ -1288,11 +1573,14 @@ impl RoundManager { self.block_store.sync_info().highest_ordered_round() ) ); - debug!( - "Received an order vote not in the next 100 rounds. Order vote round: {:?}, Highest ordered round: {:?}", - order_vote_msg.order_vote().ledger_info().round(), - self.block_store.sync_info().highest_ordered_round() - ) + sample!( + SampleRate::Frequency(2), + debug!( + "Received an order vote not in the next 100 rounds. Order vote round: {:?}, Highest ordered round: {:?}", + order_vote_msg.order_vote().ledger_info().round(), + self.block_store.sync_info().highest_ordered_round() + ) + ); } } Ok(()) @@ -1341,12 +1629,23 @@ impl RoundManager { BlockStage::ORDER_VOTED, ); } + if proposed_block.block().is_opt_block() { + observe_block( + proposed_block.block().timestamp_usecs(), + BlockStage::ORDER_VOTED_OPT_BLOCK, + ); + } let order_vote_msg = OrderVoteMsg::new(order_vote, qc.as_ref().clone()); info!( self.new_log(LogEvent::BroadcastOrderVote), "{}", order_vote_msg ); self.network.broadcast_order_vote(order_vote_msg).await; + if proposed_block.pipeline_futs().is_some() { + if let Some(tx) = proposed_block.pipeline_tx().lock().as_mut() { + let _ = tx.order_vote_tx.take().map(|tx| tx.send(())); + } + } ORDER_VOTE_BROADCASTED.inc(); } Ok(()) @@ -1729,6 +2028,7 @@ impl RoundManager { (Author, VerifiedEvent), >, mut buffered_proposal_rx: aptos_channel::Receiver, + mut opt_proposal_loopback_rx: aptos_channels::UnboundedReceiver, close_rx: oneshot::Receiver>, ) { info!(epoch = self.epoch_state.epoch, "RoundManager started"); @@ -1742,6 +2042,18 @@ impl RoundManager { } break; } + opt_proposal = opt_proposal_loopback_rx.select_next_some() => { + self.pending_opt_proposals = self.pending_opt_proposals.split_off(&opt_proposal.round().add(1)); + let result = monitor!("process_opt_proposal_loopback", self.process_opt_proposal(opt_proposal).await); + let round_state = self.round_state(); + match result { + Ok(_) => trace!(RoundStateLogSchema::new(round_state)), + Err(e) => { + counters::ERROR_COUNT.inc(); + warn!(kind = error_kind(&e), RoundStateLogSchema::new(round_state), "Error: {:#}", e); + } + } + } proposal = buffered_proposal_rx.select_next_some() => { let mut proposals = vec![proposal]; while let Some(Some(proposal)) = buffered_proposal_rx.next().now_or_never() { @@ -1751,6 +2063,7 @@ impl RoundManager { match event { VerifiedEvent::ProposalMsg(p) => p.proposal().round(), VerifiedEvent::VerifiedProposalMsg(p) => p.round(), + VerifiedEvent::OptProposalMsg(p) => p.round(), unexpected_event => unreachable!("Unexpected event {:?}", unexpected_event), } }; @@ -1774,6 +2087,12 @@ impl RoundManager { self.process_delayed_proposal_msg(*proposal_msg).await ) } + VerifiedEvent::OptProposalMsg(proposal_msg) => { + monitor!( + "process_opt_proposal", + self.process_opt_proposal_msg(*proposal_msg).await + ) + } unexpected_event => unreachable!("Unexpected event: {:?}", unexpected_event), }; let round_state = self.round_state(); diff --git a/consensus/src/round_manager_fuzzing.rs b/consensus/src/round_manager_fuzzing.rs index 28eeca56118..8858b0055e6 100644 --- a/consensus/src/round_manager_fuzzing.rs +++ b/consensus/src/round_manager_fuzzing.rs @@ -6,6 +6,7 @@ use crate::{ block_storage::{pending_blocks::PendingBlocks, BlockStore}, + counters, liveness::{ proposal_generator::{ ChainHealthBackoffConfig, PipelineBackpressureConfig, ProposalGenerator, @@ -26,7 +27,10 @@ use crate::{ util::{mock_time_service::SimulatedTimeService, time_service::TimeService}, }; use aptos_channels::{self, aptos_channel, message_queues::QueueStyle}; -use aptos_config::{config::ConsensusConfig, network_id::NetworkId}; +use aptos_config::{ + config::{BlockTransactionFilterConfig, ConsensusConfig}, + network_id::NetworkId, +}; use aptos_consensus_types::{proposal_msg::ProposalMsg, utils::PayloadTxnsSize}; use aptos_infallible::Mutex; use aptos_network::{ @@ -132,7 +136,7 @@ fn create_node_for_fuzzing() -> RoundManager { // TODO: remove let proof = make_initial_epoch_change_proof(&signer); - let mut safety_rules = SafetyRules::new(test_utils::test_storage(&signer)); + let mut safety_rules = SafetyRules::new(test_utils::test_storage(&signer), false); safety_rules.initialize(&proof).unwrap(); // TODO: mock channels @@ -196,6 +200,9 @@ fn create_node_for_fuzzing() -> RoundManager { let (round_manager_tx, _) = aptos_channel::new(QueueStyle::LIFO, 1, None); + let (opt_proposal_loopback_tx, _) = + aptos_channels::new_unbounded(&counters::OP_COUNTERS.gauge("opt_proposal_loopback_queue")); + // event processor RoundManager::new( epoch_state, @@ -211,11 +218,13 @@ fn create_node_for_fuzzing() -> RoundManager { storage, OnChainConsensusConfig::default(), round_manager_tx, + BlockTransactionFilterConfig::default(), ConsensusConfig::default(), OnChainRandomnessConfig::default_enabled(), OnChainJWKConsensusConfig::default_enabled(), None, Arc::new(MockPastProposalStatusTracker {}), + opt_proposal_loopback_tx, ) } diff --git a/consensus/src/round_manager_test.rs b/consensus/src/round_manager_test.rs deleted file mode 100644 index adeaaf98da1..00000000000 --- a/consensus/src/round_manager_test.rs +++ /dev/null @@ -1,2775 +0,0 @@ -// Copyright © Aptos Foundation -// Parts of the project are originally copyright © Meta Platforms, Inc. -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - block_storage::{pending_blocks::PendingBlocks, BlockReader, BlockStore}, - counters, - liveness::{ - proposal_generator::{ - ChainHealthBackoffConfig, PipelineBackpressureConfig, ProposalGenerator, - }, - proposer_election::ProposerElection, - rotating_proposer_election::RotatingProposer, - round_state::{ExponentialTimeInterval, RoundState}, - }, - metrics_safety_rules::MetricsSafetyRules, - network::{IncomingBlockRetrievalRequest, NetworkSender}, - network_interface::{CommitMessage, ConsensusMsg, ConsensusNetworkClient, DIRECT_SEND, RPC}, - network_tests::{NetworkPlayground, TwinId}, - payload_manager::DirectMempoolPayloadManager, - persistent_liveness_storage::RecoveryData, - pipeline::buffer_manager::OrderedBlocks, - round_manager::RoundManager, - test_utils::{ - consensus_runtime, create_vec_signed_transactions, - mock_execution_client::MockExecutionClient, timed_block_on, MockOptQSPayloadProvider, - MockPastProposalStatusTracker, MockPayloadManager, MockStorage, TreeInserter, - }, - util::time_service::{ClockTimeService, TimeService}, -}; -use aptos_channels::{self, aptos_channel, message_queues::QueueStyle}; -use aptos_config::{ - config::ConsensusConfig, - network_id::{NetworkId, PeerNetworkId}, -}; -use aptos_consensus_types::{ - block::{ - block_test_utils::{certificate_for_genesis, gen_test_certificate}, - Block, - }, - block_retrieval::{BlockRetrievalRequest, BlockRetrievalRequestV1, BlockRetrievalStatus}, - common::{Author, Payload, Round}, - order_vote_msg::OrderVoteMsg, - pipeline::commit_decision::CommitDecision, - proposal_msg::ProposalMsg, - round_timeout::RoundTimeoutMsg, - sync_info::SyncInfo, - timeout_2chain::{TwoChainTimeout, TwoChainTimeoutWithPartialSignatures}, - utils::PayloadTxnsSize, - vote_msg::VoteMsg, -}; -use aptos_crypto::HashValue; -use aptos_infallible::Mutex; -use aptos_logger::prelude::info; -use aptos_network::{ - application::interface::NetworkClient, - peer_manager::{ConnectionRequestSender, PeerManagerRequestSender}, - protocols::{ - network, - network::{Event, NetworkEvents, NewNetworkEvents, NewNetworkSender}, - wire::handshake::v1::ProtocolIdSet, - }, - transport::ConnectionMetadata, - ProtocolId, -}; -use aptos_safety_rules::{PersistentSafetyStorage, SafetyRulesManager}; -use aptos_secure_storage::Storage; -use aptos_types::{ - dkg::{real_dkg::RealDKG, DKGSessionMetadata, DKGTrait, DKGTranscript}, - epoch_state::EpochState, - jwks::QuorumCertifiedUpdate, - ledger_info::LedgerInfo, - on_chain_config::{ - ConsensusAlgorithmConfig, ConsensusConfigV1, OnChainConsensusConfig, - OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, - ValidatorTxnConfig, DEFAULT_WINDOW_SIZE, - }, - transaction::SignedTransaction, - validator_signer::ValidatorSigner, - validator_txn::ValidatorTransaction, - validator_verifier::{ - generate_validator_verifier, random_validator_verifier, - random_validator_verifier_with_voting_power, ValidatorConsensusInfoMoveStruct, - ValidatorVerifier, - }, - waypoint::Waypoint, -}; -use futures::{ - channel::{mpsc, oneshot}, - executor::block_on, - stream::select, - FutureExt, Stream, StreamExt, -}; -use maplit::hashmap; -use rand::{rngs::ThreadRng, thread_rng}; -use std::{ - collections::VecDeque, - iter::FromIterator, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, - time::Duration, -}; -use tokio::{ - runtime::{Handle, Runtime}, - task::JoinHandle, - time::timeout, -}; - -/// Auxiliary struct that is setting up node environment for the test. -pub struct NodeSetup { - block_store: Arc, - round_manager: RoundManager, - storage: Arc, - signer: ValidatorSigner, - proposers: Vec, - safety_rules_manager: SafetyRulesManager, - pending_network_events: Vec>, - all_network_events: Box> + Send + Unpin>, - ordered_blocks_events: mpsc::UnboundedReceiver, - mock_execution_client: Arc, - _state_sync_receiver: mpsc::UnboundedReceiver>, - id: usize, - onchain_consensus_config: OnChainConsensusConfig, - local_consensus_config: ConsensusConfig, - onchain_randomness_config: OnChainRandomnessConfig, - onchain_jwk_consensus_config: OnChainJWKConsensusConfig, - vote_queue: VecDeque, - order_vote_queue: VecDeque, - proposal_queue: VecDeque, - round_timeout_queue: VecDeque, - commit_decision_queue: VecDeque, -} - -impl NodeSetup { - fn create_round_state(time_service: Arc) -> RoundState { - let base_timeout = Duration::new(60, 0); - let time_interval = Box::new(ExponentialTimeInterval::fixed(base_timeout)); - let (round_timeout_sender, _) = aptos_channels::new_test(1_024); - RoundState::new(time_interval, time_service, round_timeout_sender) - } - - fn create_proposer_election(proposers: Vec) -> Arc { - Arc::new(RotatingProposer::new(proposers, 1)) - } - - fn create_nodes( - playground: &mut NetworkPlayground, - executor: Handle, - num_nodes: usize, - proposer_indices: Option>, - onchain_consensus_config: Option, - local_consensus_config: Option, - onchain_randomness_config: Option, - onchain_jwk_consensus_config: Option, - ) -> Vec { - Self::create_nodes_with_validator_set( - playground, - executor, - num_nodes, - proposer_indices, - onchain_consensus_config, - local_consensus_config, - onchain_randomness_config, - onchain_jwk_consensus_config, - None, - ) - } - - fn create_nodes_with_validator_set( - playground: &mut NetworkPlayground, - executor: Handle, - num_nodes: usize, - proposer_indices: Option>, - onchain_consensus_config: Option, - local_consensus_config: Option, - onchain_randomness_config: Option, - onchain_jwk_consensus_config: Option, - validator_set: Option<(Vec, ValidatorVerifier)>, - ) -> Vec { - let mut onchain_consensus_config = onchain_consensus_config.unwrap_or_default(); - // With order votes feature, the validators additionally send order votes. - // next_proposal and next_vote functions could potentially break because of it. - if let OnChainConsensusConfig::V4 { - alg: - ConsensusAlgorithmConfig::JolteonV2 { - main: _, - quorum_store_enabled: _, - order_vote_enabled, - }, - vtxn: _, - window_size: _, - } = &mut onchain_consensus_config - { - *order_vote_enabled = false; - } - let onchain_randomness_config = - onchain_randomness_config.unwrap_or_else(OnChainRandomnessConfig::default_if_missing); - let onchain_jwk_consensus_config = onchain_jwk_consensus_config - .unwrap_or_else(OnChainJWKConsensusConfig::default_if_missing); - let local_consensus_config = local_consensus_config.unwrap_or_default(); - let (signers, validators) = - validator_set.unwrap_or_else(|| random_validator_verifier(num_nodes, None, false)); - let proposers = proposer_indices - .unwrap_or_else(|| vec![0]) - .iter() - .map(|i| signers[*i].author()) - .collect::>(); - let validator_set = (&validators).into(); - let waypoint = - Waypoint::new_epoch_boundary(&LedgerInfo::mock_genesis(Some(validator_set))).unwrap(); - - let mut nodes = vec![]; - // pre-initialize the mapping to avoid race conditions (peer try to broadcast to someone not added yet) - let peers_and_metadata = playground.peer_protocols(); - for signer in signers.iter().take(num_nodes) { - let peer_id = signer.author(); - let mut conn_meta = ConnectionMetadata::mock(peer_id); - conn_meta.application_protocols = ProtocolIdSet::from_iter([ - ProtocolId::ConsensusDirectSendJson, - ProtocolId::ConsensusDirectSendBcs, - ProtocolId::ConsensusRpcBcs, - ]); - let peer_network_id = PeerNetworkId::new(NetworkId::Validator, peer_id); - peers_and_metadata - .insert_connection_metadata(peer_network_id, conn_meta) - .unwrap(); - } - for (id, signer) in signers.iter().take(num_nodes).enumerate() { - let (initial_data, storage) = MockStorage::start_for_testing((&validators).into()); - - let safety_storage = PersistentSafetyStorage::initialize( - Storage::from(aptos_secure_storage::InMemoryStorage::new()), - signer.author(), - signer.private_key().clone(), - waypoint, - true, - ); - let safety_rules_manager = SafetyRulesManager::new_local(safety_storage); - - nodes.push(Self::new( - playground, - executor.clone(), - signer.to_owned(), - proposers.clone(), - storage, - initial_data, - safety_rules_manager, - id, - onchain_consensus_config.clone(), - local_consensus_config.clone(), - onchain_randomness_config.clone(), - onchain_jwk_consensus_config.clone(), - )); - } - nodes - } - - fn new( - playground: &mut NetworkPlayground, - executor: Handle, - signer: ValidatorSigner, - proposers: Vec, - storage: Arc, - initial_data: RecoveryData, - safety_rules_manager: SafetyRulesManager, - id: usize, - onchain_consensus_config: OnChainConsensusConfig, - local_consensus_config: ConsensusConfig, - onchain_randomness_config: OnChainRandomnessConfig, - onchain_jwk_consensus_config: OnChainJWKConsensusConfig, - ) -> Self { - let _entered_runtime = executor.enter(); - let epoch_state = Arc::new(EpochState::new(1, storage.get_validator_set().into())); - let validators = epoch_state.verifier.clone(); - let (network_reqs_tx, network_reqs_rx) = aptos_channel::new(QueueStyle::FIFO, 8, None); - let (connection_reqs_tx, _) = aptos_channel::new(QueueStyle::FIFO, 8, None); - let (consensus_tx, consensus_rx) = aptos_channel::new(QueueStyle::FIFO, 8, None); - let (_conn_mgr_reqs_tx, conn_mgr_reqs_rx) = aptos_channels::new_test(8); - let network_sender = network::NetworkSender::new( - PeerManagerRequestSender::new(network_reqs_tx), - ConnectionRequestSender::new(connection_reqs_tx), - ); - let network_client = NetworkClient::new( - DIRECT_SEND.into(), - RPC.into(), - hashmap! {NetworkId::Validator => network_sender}, - playground.peer_protocols(), - ); - let consensus_network_client = ConsensusNetworkClient::new(network_client); - let network_events = NetworkEvents::new(consensus_rx, None, true); - let author = signer.author(); - - let twin_id = TwinId { id, author }; - - playground.add_node(twin_id, consensus_tx, network_reqs_rx, conn_mgr_reqs_rx); - - let (self_sender, self_receiver) = aptos_channels::new_unbounded_test(); - let network = Arc::new(NetworkSender::new( - author, - consensus_network_client, - self_sender, - validators, - )); - - let all_network_events = Box::new(select(network_events, self_receiver)); - - let last_vote_sent = initial_data.last_vote(); - let (ordered_blocks_tx, ordered_blocks_events) = mpsc::unbounded::(); - let (state_sync_client, _state_sync_receiver) = mpsc::unbounded(); - let mock_execution_client = Arc::new(MockExecutionClient::new( - state_sync_client.clone(), - ordered_blocks_tx.clone(), - Arc::clone(&storage), - )); - let time_service = Arc::new(ClockTimeService::new(executor)); - - let window_size = onchain_consensus_config.window_size(); - let block_store = Arc::new(BlockStore::new( - storage.clone(), - initial_data, - mock_execution_client.clone(), - 10, // max pruned blocks in mem - time_service.clone(), - 10, - Arc::from(DirectMempoolPayloadManager::new()), - false, - window_size, - Arc::new(Mutex::new(PendingBlocks::new())), - None, - )); - - let proposer_election = Self::create_proposer_election(proposers.clone()); - let proposal_generator = ProposalGenerator::new( - author, - block_store.clone(), - Arc::new(MockPayloadManager::new(None)), - time_service.clone(), - Duration::ZERO, - PayloadTxnsSize::new(20, 1000), - 10, - PayloadTxnsSize::new(5, 500), - 10, - 1, - Some(30_000), - PipelineBackpressureConfig::new_no_backoff(), - ChainHealthBackoffConfig::new_no_backoff(), - false, - onchain_consensus_config.effective_validator_txn_config(), - true, - Arc::new(MockOptQSPayloadProvider {}), - ); - - let round_state = Self::create_round_state(time_service); - let mut safety_rules = - MetricsSafetyRules::new(safety_rules_manager.client(), storage.clone()); - safety_rules.perform_initialize().unwrap(); - - let (round_manager_tx, _) = aptos_channel::new(QueueStyle::LIFO, 1, None); - - let local_config = local_consensus_config.clone(); - - let mut round_manager = RoundManager::new( - epoch_state, - Arc::clone(&block_store), - round_state, - proposer_election, - proposal_generator, - Arc::new(Mutex::new(safety_rules)), - network, - storage.clone(), - onchain_consensus_config.clone(), - round_manager_tx, - local_config, - onchain_randomness_config.clone(), - onchain_jwk_consensus_config.clone(), - None, - Arc::new(MockPastProposalStatusTracker {}), - ); - block_on(round_manager.init(last_vote_sent)); - Self { - block_store, - round_manager, - storage, - signer, - proposers, - safety_rules_manager, - pending_network_events: Vec::new(), - all_network_events, - ordered_blocks_events, - mock_execution_client, - _state_sync_receiver, - id, - onchain_consensus_config, - local_consensus_config, - onchain_randomness_config, - onchain_jwk_consensus_config, - vote_queue: VecDeque::new(), - order_vote_queue: VecDeque::new(), - proposal_queue: VecDeque::new(), - round_timeout_queue: VecDeque::new(), - commit_decision_queue: VecDeque::new(), - } - } - - pub fn restart(self, playground: &mut NetworkPlayground, executor: Handle) -> Self { - let recover_data = self - .storage - .try_start( - self.onchain_consensus_config.order_vote_enabled(), - self.onchain_consensus_config.window_size(), - ) - .unwrap_or_else(|e| panic!("fail to restart due to: {}", e)); - Self::new( - playground, - executor, - self.signer, - self.proposers, - self.storage, - recover_data, - self.safety_rules_manager, - self.id, - self.onchain_consensus_config.clone(), - self.local_consensus_config.clone(), - self.onchain_randomness_config.clone(), - self.onchain_jwk_consensus_config.clone(), - ) - } - - pub fn identity_desc(&self) -> String { - format!("{} [{}]", self.id, self.signer.author()) - } - - fn poll_next_network_event(&mut self) -> Option> { - if !self.pending_network_events.is_empty() { - Some(self.pending_network_events.remove(0)) - } else { - self.all_network_events - .next() - .now_or_never() - .map(|v| v.unwrap()) - } - } - - pub async fn next_network_event(&mut self) -> Event { - if !self.pending_network_events.is_empty() { - self.pending_network_events.remove(0) - } else { - self.all_network_events.next().await.unwrap() - } - } - - pub async fn next_network_message(&mut self) { - let consensus_msg = match self.next_network_event().await { - Event::Message(_, msg) => msg, - Event::RpcRequest(_, msg, _, _) if matches!(msg, ConsensusMsg::CommitMessage(_)) => msg, - Event::RpcRequest(_, msg, _, _) => { - panic!( - "Unexpected event, got RpcRequest, expected Message: {:?} on node {}", - msg, - self.identity_desc() - ) - }, - }; - - match consensus_msg { - ConsensusMsg::ProposalMsg(proposal) => { - self.proposal_queue.push_back(*proposal); - }, - ConsensusMsg::VoteMsg(vote) => { - self.vote_queue.push_back(*vote); - }, - ConsensusMsg::OrderVoteMsg(order_vote) => { - self.order_vote_queue.push_back(*order_vote); - }, - ConsensusMsg::RoundTimeoutMsg(round_timeout) => { - self.round_timeout_queue.push_back(*round_timeout); - }, - ConsensusMsg::CommitDecisionMsg(commit_decision) => { - self.commit_decision_queue.push_back(*commit_decision); - }, - ConsensusMsg::CommitMessage(d) if matches!(*d, CommitMessage::Decision(_)) => { - match *d { - CommitMessage::Decision(commit_decision) => { - self.commit_decision_queue.push_back(commit_decision); - }, - _ => unreachable!(), - } - }, - msg => panic!( - "Unexpected Consensus Message: {:?} on node {}", - msg, - self.identity_desc() - ), - } - } - - pub fn no_next_msg(&mut self) { - match self.poll_next_network_event() { - Some(Event::RpcRequest(_, msg, _, _)) | Some(Event::Message(_, msg)) => panic!( - "Unexpected Consensus Message: {:?} on node {}", - msg, - self.identity_desc() - ), - None => {}, - } - } - - pub async fn next_proposal(&mut self) -> ProposalMsg { - while self.proposal_queue.is_empty() { - self.next_network_message().await; - } - self.proposal_queue.pop_front().unwrap() - } - - pub async fn next_vote(&mut self) -> VoteMsg { - while self.vote_queue.is_empty() { - self.next_network_message().await; - } - self.vote_queue.pop_front().unwrap() - } - - #[allow(unused)] - pub async fn next_order_vote(&mut self) -> OrderVoteMsg { - while self.order_vote_queue.is_empty() { - self.next_network_message().await; - } - self.order_vote_queue.pop_front().unwrap() - } - - pub async fn next_timeout(&mut self) -> RoundTimeoutMsg { - while self.round_timeout_queue.is_empty() { - self.next_network_message().await; - } - self.round_timeout_queue.pop_front().unwrap() - } - - pub async fn next_commit_decision(&mut self) -> CommitDecision { - while self.commit_decision_queue.is_empty() { - self.next_network_message().await; - } - self.commit_decision_queue.pop_front().unwrap() - } - - pub async fn poll_block_retrieval(&mut self) -> Option { - match self.poll_next_network_event() { - Some(Event::RpcRequest(_, msg, protocol, response_sender)) => match msg { - ConsensusMsg::DeprecatedBlockRetrievalRequest(v) => { - Some(IncomingBlockRetrievalRequest { - req: BlockRetrievalRequest::V1(*v), - protocol, - response_sender, - }) - }, - ConsensusMsg::BlockRetrievalRequest(v) => Some(IncomingBlockRetrievalRequest { - req: *v, - protocol, - response_sender, - }), - msg => panic!( - "Unexpected Consensus Message: {:?} on node {}", - msg, - self.identity_desc() - ), - }, - Some(Event::Message(_, msg)) => panic!( - "Unexpected Consensus Message: {:?} on node {}", - msg, - self.identity_desc() - ), - None => None, - } - } - - pub fn no_next_ordered(&mut self) { - if self.ordered_blocks_events.next().now_or_never().is_some() { - panic!("Unexpected Ordered Blocks Event"); - } - } - - pub async fn commit_next_ordered(&mut self, expected_rounds: &[Round]) { - info!( - "Starting commit_next_ordered to wait for {:?} on node {:?}", - expected_rounds, - self.identity_desc() - ); - let ordered_blocks = self.ordered_blocks_events.next().await.unwrap(); - let rounds = ordered_blocks - .ordered_blocks - .iter() - .map(|b| b.round()) - .collect::>(); - assert_eq!(&rounds, expected_rounds); - self.mock_execution_client - .commit_to_storage(ordered_blocks) - .await - .unwrap(); - } -} - -fn config_with_round_timeout_msg_disabled() -> ConsensusConfig { - // Disable RoundTimeoutMsg to unless expliclity enabled. - ConsensusConfig { - enable_round_timeout_msg: false, - ..Default::default() - } -} - -fn start_replying_to_block_retreival(nodes: Vec) -> ReplyingRPCHandle { - let done = Arc::new(AtomicBool::new(false)); - let mut handles = Vec::new(); - for mut node in nodes.into_iter() { - let done_clone = done.clone(); - handles.push(tokio::spawn(async move { - while !done_clone.load(Ordering::Relaxed) { - info!("Asking for RPC request on {:?}", node.identity_desc()); - let maybe_request = node.poll_block_retrieval().await; - if let Some(request) = maybe_request { - info!( - "RPC request received: {:?} on {:?}", - request, - node.identity_desc() - ); - let wrapped_request = IncomingBlockRetrievalRequest { - req: request.req, - protocol: request.protocol, - response_sender: request.response_sender, - }; - node.block_store - .process_block_retrieval(wrapped_request) - .await - .unwrap(); - } else { - tokio::time::sleep(Duration::from_millis(50)).await; - } - } - node - })); - } - ReplyingRPCHandle { handles, done } -} - -struct ReplyingRPCHandle { - handles: Vec>, - done: Arc, -} - -impl ReplyingRPCHandle { - async fn join(self) -> Vec { - self.done.store(true, Ordering::Relaxed); - let mut result = Vec::new(); - for handle in self.handles.into_iter() { - result.push(handle.await.unwrap()); - } - info!( - "joined nodes in order: {:?}", - result.iter().map(|v| v.id).collect::>() - ); - result - } -} - -fn process_and_vote_on_proposal( - runtime: &Runtime, - nodes: &mut [NodeSetup], - next_proposer: usize, - down_nodes: &[usize], - process_votes: bool, - apply_commit_prev_proposer: Option, - apply_commit_on_votes: bool, - expected_round: u64, - expected_qc_ordered_round: u64, - expected_qc_committed_round: u64, -) { - info!( - "Called {} with current {} and apply commit prev {:?}", - expected_round, next_proposer, apply_commit_prev_proposer - ); - let mut num_votes = 0; - - for node in nodes.iter_mut() { - info!("Waiting on next_proposal on node {}", node.identity_desc()); - if down_nodes.contains(&node.id) { - // Drop the proposal on down nodes - timed_block_on(runtime, node.next_proposal()); - info!("Dropping proposal on down node {}", node.identity_desc()); - } else { - // Proccess proposal on other nodes - let proposal_msg = timed_block_on(runtime, node.next_proposal()); - info!("Processing proposal on {}", node.identity_desc()); - - assert_eq!(proposal_msg.proposal().round(), expected_round); - assert_eq!( - proposal_msg.sync_info().highest_ordered_round(), - expected_qc_ordered_round - ); - assert_eq!( - proposal_msg.sync_info().highest_commit_round(), - expected_qc_committed_round - ); - - timed_block_on( - runtime, - node.round_manager.process_proposal_msg(proposal_msg), - ) - .unwrap(); - info!("Finish process proposal on {}", node.identity_desc()); - num_votes += 1; - } - } - - for node in nodes.iter_mut() { - info!( - "Fetching {} votes in round {} on node {}", - num_votes, - expected_round, - node.identity_desc() - ); - if down_nodes.contains(&node.id) { - // Drop the votes on down nodes - info!("Dropping votes on down node {}", node.identity_desc()); - for _ in 0..num_votes { - timed_block_on(runtime, node.next_vote()); - } - } else { - let mut votes = Vec::new(); - for _ in 0..num_votes { - votes.push(timed_block_on(runtime, node.next_vote())); - } - - info!("Processing votes on node {}", node.identity_desc()); - if process_votes { - for vote_msg in votes { - timed_block_on(runtime, node.round_manager.process_vote_msg(vote_msg)).unwrap(); - } - if apply_commit_prev_proposer.is_some() - && expected_round > 1 - && apply_commit_on_votes - { - info!( - "Applying next commit {} on proposer node {}", - expected_round - 2, - node.identity_desc() - ); - timed_block_on(runtime, node.commit_next_ordered(&[expected_round - 1])); - } - } - } - } -} - -#[test] -fn new_round_on_quorum_cert() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let node = &mut nodes[0]; - let genesis = node.block_store.ordered_root(); - timed_block_on(&runtime, async { - // round 1 should start - let proposal_msg = node.next_proposal().await; - assert_eq!( - proposal_msg.proposal().quorum_cert().certified_block().id(), - genesis.id() - ); - let b1_id = proposal_msg.proposal().id(); - assert_eq!(proposal_msg.proposer(), node.signer.author()); - - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - let vote_msg = node.next_vote().await; - // Adding vote to form a QC - node.round_manager.process_vote_msg(vote_msg).await.unwrap(); - - // round 2 should start - let proposal_msg = node.next_proposal().await; - let proposal = proposal_msg.proposal(); - assert_eq!(proposal.round(), 2); - assert_eq!(proposal.parent_id(), b1_id); - assert_eq!(proposal.quorum_cert().certified_block().id(), b1_id); - }); -} - -#[test] -/// If the proposal is valid, a vote should be sent -fn vote_on_successful_proposal() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let node = &mut nodes[0]; - - let genesis_qc = certificate_for_genesis(); - timed_block_on(&runtime, async { - // Start round 1 and clear the message queue - node.next_proposal().await; - - let proposal = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let proposal_id = proposal.id(); - node.round_manager.process_proposal(proposal).await.unwrap(); - let vote_msg = node.next_vote().await; - assert_eq!(vote_msg.vote().author(), node.signer.author()); - assert_eq!(vote_msg.vote().vote_data().proposed().id(), proposal_id); - let consensus_state = node.round_manager.consensus_state(); - assert_eq!(consensus_state.epoch(), 1); - assert_eq!(consensus_state.last_voted_round(), 1); - assert_eq!(consensus_state.preferred_round(), 0); - assert!(consensus_state.in_validator_set()); - }); -} - -#[test] -/// In back pressure mode, verify that the proposals are processed after we get out of back pressure. -fn delay_proposal_processing_in_sync_only() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let node = &mut nodes[0]; - - let genesis_qc = certificate_for_genesis(); - timed_block_on(&runtime, async { - // Start round 1 and clear the message queue - node.next_proposal().await; - - // Set sync only to true so that new proposal processing is delayed. - node.round_manager - .block_store - .set_back_pressure_for_test(true); - let proposal = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let proposal_id = proposal.id(); - node.round_manager - .process_proposal(proposal.clone()) - .await - .unwrap(); - - // Wait for some time to ensure that the proposal was not processed - timeout(Duration::from_millis(200), node.next_vote()) - .await - .unwrap_err(); - - // Clear the sync only mode and process verified proposal and ensure it is processed now - node.round_manager - .block_store - .set_back_pressure_for_test(false); - - node.round_manager - .process_verified_proposal(proposal) - .await - .unwrap(); - - let vote_msg = node.next_vote().await; - assert_eq!(vote_msg.vote().author(), node.signer.author()); - assert_eq!(vote_msg.vote().vote_data().proposed().id(), proposal_id); - let consensus_state = node.round_manager.consensus_state(); - assert_eq!(consensus_state.epoch(), 1); - assert_eq!(consensus_state.last_voted_round(), 1); - assert_eq!(consensus_state.preferred_round(), 0); - assert!(consensus_state.in_validator_set()); - }); -} - -#[test] -/// If the proposal does not pass voting rules, -/// No votes are sent, but the block is still added to the block tree. -fn no_vote_on_old_proposal() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let node = &mut nodes[0]; - let genesis_qc = certificate_for_genesis(); - let new_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let new_block_id = new_block.id(); - let old_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 2, - genesis_qc, - &node.signer, - Vec::new(), - ) - .unwrap(); - timed_block_on(&runtime, async { - // clear the message queue - node.next_proposal().await; - - node.round_manager - .process_proposal(new_block) - .await - .unwrap(); - node.round_manager - .process_proposal(old_block) - .await - .unwrap_err(); - let vote_msg = node.next_vote().await; - assert_eq!(vote_msg.vote().vote_data().proposed().id(), new_block_id); - }); -} - -#[test] -/// We don't vote for proposals that 'skips' rounds -/// After that when we then receive proposal for correct round, we vote for it -/// Basically it checks that adversary can not send proposal and skip rounds violating round_state -/// rules -fn no_vote_on_mismatch_round() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut node = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ) - .pop() - .unwrap(); - let genesis_qc = certificate_for_genesis(); - let correct_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let block_skip_round = Block::new_proposal( - Payload::empty(false, true), - 2, - 2, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - timed_block_on(&runtime, async { - let bad_proposal = ProposalMsg::new( - block_skip_round, - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - assert!(node - .round_manager - .process_proposal_msg(bad_proposal) - .await - .is_err()); - let good_proposal = ProposalMsg::new( - correct_block.clone(), - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - node.round_manager - .process_proposal_msg(good_proposal) - .await - .unwrap(); - }); -} - -#[test] -/// Ensure that after the vote messages are broadcasted upon timeout, the receivers -/// have the highest quorum certificate (carried by the SyncInfo of the vote message) -fn sync_info_carried_on_timeout_vote() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(config_with_round_timeout_msg_disabled()), - None, - None, - ); - let mut node = nodes.pop().unwrap(); - - timed_block_on(&runtime, async { - let proposal_msg = node.next_proposal().await; - let block_0 = proposal_msg.proposal().clone(); - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - node.next_vote().await; - let parent_block_info = block_0.quorum_cert().certified_block(); - // Populate block_0 and a quorum certificate for block_0 on non_proposer - let block_0_quorum_cert = gen_test_certificate( - &[node.signer.clone()], - // Follow MockStateComputer implementation - block_0.gen_block_info( - parent_block_info.executed_state_id(), - parent_block_info.version(), - parent_block_info.next_epoch_state().cloned(), - ), - parent_block_info.clone(), - None, - ); - node.block_store - .insert_single_quorum_cert(block_0_quorum_cert.clone()) - .unwrap(); - - node.round_manager.round_state.process_certificates( - SyncInfo::new( - block_0_quorum_cert.clone(), - block_0_quorum_cert.into_wrapped_ledger_info(), - None, - ), - &generate_validator_verifier(&[node.signer.clone()]), - ); - node.round_manager - .process_local_timeout(2) - .await - .unwrap_err(); - let vote_msg_on_timeout = node.next_vote().await; - assert!(vote_msg_on_timeout.vote().is_timeout()); - assert_eq!( - *vote_msg_on_timeout.sync_info().highest_quorum_cert(), - block_0_quorum_cert - ); - }); -} - -#[test] -/// We don't vote for proposals that comes from proposers that are not valid proposers for round -fn no_vote_on_invalid_proposer() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 2, - None, - None, - None, - None, - None, - ); - let incorrect_proposer = nodes.pop().unwrap(); - let mut node = nodes.pop().unwrap(); - let genesis_qc = certificate_for_genesis(); - let correct_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let block_incorrect_proposer = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &incorrect_proposer.signer, - Vec::new(), - ) - .unwrap(); - timed_block_on(&runtime, async { - let bad_proposal = ProposalMsg::new( - block_incorrect_proposer, - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - assert!(node - .round_manager - .process_proposal_msg(bad_proposal) - .await - .is_err()); - let good_proposal = ProposalMsg::new( - correct_block.clone(), - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - - node.round_manager - .process_proposal_msg(good_proposal.clone()) - .await - .unwrap(); - }); -} - -#[test] -/// We allow to 'skip' round if proposal carries timeout certificate for next round -fn new_round_on_timeout_certificate() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut node = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ) - .pop() - .unwrap(); - let genesis_qc = certificate_for_genesis(); - let correct_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let block_skip_round = Block::new_proposal( - Payload::empty(false, true), - 2, - 2, - genesis_qc.clone(), - &node.signer, - vec![(1, node.signer.author())], - ) - .unwrap(); - let timeout = TwoChainTimeout::new(1, 1, genesis_qc.clone()); - let timeout_signature = timeout.sign(&node.signer).unwrap(); - - let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); - tc_partial.add(node.signer.author(), timeout, timeout_signature); - - let tc = tc_partial - .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) - .unwrap(); - timed_block_on(&runtime, async { - let skip_round_proposal = ProposalMsg::new( - block_skip_round, - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - Some(tc), - ), - ); - node.round_manager - .process_proposal_msg(skip_round_proposal) - .await - .unwrap(); - let old_good_proposal = ProposalMsg::new( - correct_block.clone(), - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - let before = counters::ERROR_COUNT.get(); - assert!(node - .round_manager - .process_proposal_msg(old_good_proposal) - .await - .is_ok()); // we eat the error - assert_eq!(counters::ERROR_COUNT.get(), before + 1); // but increase the counter - }); -} - -#[test] -/// We allow to 'skip' round if proposal carries timeout certificate for next round -fn reject_invalid_failed_authors() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut node = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ) - .pop() - .unwrap(); - let genesis_qc = certificate_for_genesis(); - - let create_timeout = |round: Round| { - let timeout = TwoChainTimeout::new(1, round, genesis_qc.clone()); - let timeout_signature = timeout.sign(&node.signer).unwrap(); - let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); - tc_partial.add(node.signer.author(), timeout, timeout_signature); - - tc_partial - .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) - .unwrap() - }; - - let create_proposal = |round: Round, failed_authors: Vec<(Round, Author)>| { - let block = Block::new_proposal( - Payload::empty(false, true), - round, - 2, - genesis_qc.clone(), - &node.signer, - failed_authors, - ) - .unwrap(); - ProposalMsg::new( - block, - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - if round > 1 { - Some(create_timeout(round - 1)) - } else { - None - }, - ), - ) - }; - - let extra_failed_authors_proposal = create_proposal(2, vec![(1, Author::random())]); - let missing_failed_authors_proposal = create_proposal(2, vec![]); - let wrong_failed_authors_proposal = create_proposal(2, vec![(1, Author::random())]); - let not_enough_failed_proposal = create_proposal(3, vec![(2, node.signer.author())]); - let valid_proposal = create_proposal( - 4, - (1..4).map(|i| (i as Round, node.signer.author())).collect(), - ); - - timed_block_on(&runtime, async { - assert!(node - .round_manager - .process_proposal_msg(extra_failed_authors_proposal) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal_msg(missing_failed_authors_proposal) - .await - .is_err()); - }); - - timed_block_on(&runtime, async { - assert!(node - .round_manager - .process_proposal_msg(wrong_failed_authors_proposal) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal_msg(not_enough_failed_proposal) - .await - .is_err()); - - node.round_manager - .process_proposal_msg(valid_proposal) - .await - .unwrap() - }); -} - -#[test] -fn response_on_block_retrieval() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut node = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ) - .pop() - .unwrap(); - - let genesis_qc = certificate_for_genesis(); - let block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - let block_id = block.id(); - let proposal = ProposalMsg::new( - block, - SyncInfo::new( - genesis_qc.clone(), - genesis_qc.into_wrapped_ledger_info(), - None, - ), - ); - - timed_block_on(&runtime, async { - node.round_manager - .process_proposal_msg(proposal) - .await - .unwrap(); - - // first verify that we can retrieve the block if it's in the tree - let (tx1, rx1) = oneshot::channel(); - let single_block_request = IncomingBlockRetrievalRequest { - req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(block_id, 1)), - protocol: ProtocolId::ConsensusRpcBcs, - response_sender: tx1, - }; - node.block_store - .process_block_retrieval(single_block_request) - .await - .unwrap(); - match rx1.await { - Ok(Ok(bytes)) => { - let response = match bcs::from_bytes(&bytes) { - Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, - _ => panic!("block retrieval failure"), - }; - assert_eq!(response.status(), BlockRetrievalStatus::Succeeded); - assert_eq!(response.blocks().first().unwrap().id(), block_id); - }, - _ => panic!("block retrieval failure"), - } - - // verify that if a block is not there, return ID_NOT_FOUND - let (tx2, rx2) = oneshot::channel(); - let missing_block_request = IncomingBlockRetrievalRequest { - req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(HashValue::random(), 1)), - protocol: ProtocolId::ConsensusRpcBcs, - response_sender: tx2, - }; - - node.block_store - .process_block_retrieval(missing_block_request) - .await - .unwrap(); - match rx2.await { - Ok(Ok(bytes)) => { - let response = match bcs::from_bytes(&bytes) { - Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, - _ => panic!("block retrieval failure"), - }; - assert_eq!(response.status(), BlockRetrievalStatus::IdNotFound); - assert!(response.blocks().is_empty()); - }, - _ => panic!("block retrieval failure"), - } - - // if asked for many blocks, return NOT_ENOUGH_BLOCKS - let (tx3, rx3) = oneshot::channel(); - let many_block_request = IncomingBlockRetrievalRequest { - req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(block_id, 3)), - protocol: ProtocolId::ConsensusRpcBcs, - response_sender: tx3, - }; - node.block_store - .process_block_retrieval(many_block_request) - .await - .unwrap(); - match rx3.await { - Ok(Ok(bytes)) => { - let response = match bcs::from_bytes(&bytes) { - Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, - _ => panic!("block retrieval failure"), - }; - assert_eq!(response.status(), BlockRetrievalStatus::NotEnoughBlocks); - assert_eq!(block_id, response.blocks().first().unwrap().id()); - assert_eq!( - node.block_store.ordered_root().id(), - response.blocks().get(1).unwrap().id() - ); - }, - _ => panic!("block retrieval failure"), - } - }); -} - -#[test] -/// rebuild a node from previous storage without violating safety guarantees. -fn recover_on_restart() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut node = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ) - .pop() - .unwrap(); - let inserter = TreeInserter::new_with_store(node.signer.clone(), node.block_store.clone()); - - let genesis_qc = certificate_for_genesis(); - let mut data = Vec::new(); - let num_proposals = 100; - // insert a few successful proposals - for i in 1..=num_proposals { - let proposal = inserter.create_block_with_qc( - genesis_qc.clone(), - i, - i, - Payload::empty(false, true), - (std::cmp::max(1, i.saturating_sub(10))..i) - .map(|i| (i, inserter.signer().author())) - .collect(), - ); - let timeout = TwoChainTimeout::new(1, i - 1, genesis_qc.clone()); - let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); - tc_partial.add( - inserter.signer().author(), - timeout.clone(), - timeout.sign(inserter.signer()).unwrap(), - ); - - let tc = tc_partial - .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) - .unwrap(); - - data.push((proposal, tc)); - } - - timed_block_on(&runtime, async { - for (proposal, tc) in &data { - let proposal_msg = ProposalMsg::new( - proposal.clone(), - SyncInfo::new( - proposal.quorum_cert().clone(), - genesis_qc.into_wrapped_ledger_info(), - Some(tc.clone()), - ), - ); - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - } - }); - - // verify after restart we recover the data - node = node.restart(&mut playground, runtime.handle().clone()); - let consensus_state = node.round_manager.consensus_state(); - assert_eq!(consensus_state.epoch(), 1); - assert_eq!(consensus_state.last_voted_round(), num_proposals); - assert_eq!(consensus_state.preferred_round(), 0); - assert!(consensus_state.in_validator_set()); - for (block, _) in data { - assert!(node.block_store.block_exists(block.id())); - } -} - -#[test] -/// Generate a NIL vote extending HQC upon timeout if no votes have been sent in the round. -fn nil_vote_on_timeout() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(config_with_round_timeout_msg_disabled()), - None, - None, - ); - let node = &mut nodes[0]; - let genesis = node.block_store.ordered_root(); - timed_block_on(&runtime, async { - node.next_proposal().await; - // Process the outgoing vote message and verify that it contains a round signature - // and that the vote extends genesis. - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - let vote_msg = node.next_vote().await; - - let vote = vote_msg.vote(); - - assert!(vote.is_timeout()); - // NIL block doesn't change timestamp - assert_eq!( - vote.vote_data().proposed().timestamp_usecs(), - genesis.timestamp_usecs() - ); - assert_eq!(vote.vote_data().proposed().round(), 1); - assert_eq!( - vote.vote_data().parent().id(), - node.block_store.ordered_root().id() - ); - }); -} - -#[test] -/// Generate a Timeout upon timeout if no votes have been sent in the round. -fn timeout_round_on_timeout() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let local_config = ConsensusConfig { - enable_round_timeout_msg: true, - ..Default::default() - }; - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(local_config), - None, - None, - ); - let node = &mut nodes[0]; - let genesis = node.block_store.ordered_root(); - timed_block_on(&runtime, async { - node.next_proposal().await; - // Process the outgoing vote message and verify that it contains a round signature - // and that the vote extends genesis. - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - let timeout_msg = node.next_timeout().await; - - let timeout = timeout_msg.timeout(); - - assert_eq!(timeout.round(), 1); - assert_eq!(timeout.author(), node.signer.author()); - assert_eq!(timeout.epoch(), 1); - assert_eq!(timeout.two_chain_timeout().hqc_round(), genesis.round()); - }); -} - -#[test] -/// If the node votes in a round, upon timeout the same vote is re-sent with a timeout signature. -fn vote_resent_on_timeout() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(config_with_round_timeout_msg_disabled()), - None, - None, - ); - let node = &mut nodes[0]; - timed_block_on(&runtime, async { - let proposal_msg = node.next_proposal().await; - let id = proposal_msg.proposal().id(); - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - let vote_msg = node.next_vote().await; - let vote = vote_msg.vote(); - assert!(!vote.is_timeout()); - assert_eq!(vote.vote_data().proposed().id(), id); - // Process the outgoing vote message and verify that it contains a round signature - // and that the vote is the same as above. - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - let timeout_vote_msg = node.next_vote().await; - let timeout_vote = timeout_vote_msg.vote(); - - assert!(timeout_vote.is_timeout()); - assert_eq!(timeout_vote.vote_data(), vote.vote_data()); - }); -} - -#[test] -/// If the node votes in a round, upon timeout the same vote is re-sent with a timeout signature. -fn timeout_sent_on_timeout_after_vote() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let local_config = ConsensusConfig { - enable_round_timeout_msg: true, - ..Default::default() - }; - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(local_config), - None, - None, - ); - let node = &mut nodes[0]; - timed_block_on(&runtime, async { - let proposal_msg = node.next_proposal().await; - let id = proposal_msg.proposal().id(); - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - let vote_msg = node.next_vote().await; - let vote = vote_msg.vote(); - assert!(!vote.is_timeout()); - assert_eq!(vote.vote_data().proposed().id(), id); - // Process the outgoing vote message and verify that it contains a round signature - // and that the vote is the same as above. - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - let timeout_msg = node.next_timeout().await; - - assert_eq!(timeout_msg.round(), vote.vote_data().proposed().round()); - assert_eq!(timeout_msg.sync_info(), vote_msg.sync_info()); - }); -} - -#[test] -#[ignore] // TODO: this test needs to be fixed! -fn sync_on_partial_newer_sync_info() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let mut node = nodes.pop().unwrap(); - runtime.spawn(playground.start()); - timed_block_on(&runtime, async { - // commit block 1 after 4 rounds - for _ in 1..=4 { - let proposal_msg = node.next_proposal().await; - - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - let vote_msg = node.next_vote().await; - // Adding vote to form a QC - node.round_manager.process_vote_msg(vote_msg).await.unwrap(); - } - let block_4 = node.next_proposal().await; - node.round_manager - .process_proposal_msg(block_4.clone()) - .await - .unwrap(); - // commit genesis and block 1 - for i in 0..2 { - node.commit_next_ordered(&[i]).await; - } - let vote_msg = node.next_vote().await; - let vote_data = vote_msg.vote().vote_data(); - let block_4_qc = gen_test_certificate( - &[node.signer.clone()], - vote_data.proposed().clone(), - vote_data.parent().clone(), - None, - ); - // Create a sync info with newer quorum cert but older commit cert - let sync_info = SyncInfo::new( - block_4_qc.clone(), - certificate_for_genesis().into_wrapped_ledger_info(), - None, - ); - node.round_manager - .ensure_round_and_sync_up( - sync_info.highest_round() + 1, - &sync_info, - node.signer.author(), - ) - .await - .unwrap(); - // QuorumCert added - assert_eq!(*node.block_store.highest_quorum_cert(), block_4_qc); - }); -} - -#[test] -fn safety_rules_crash() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - Some(config_with_round_timeout_msg_disabled()), - None, - None, - ); - let mut node = nodes.pop().unwrap(); - runtime.spawn(playground.start()); - - fn reset_safety_rules(node: &mut NodeSetup) { - let safety_storage = PersistentSafetyStorage::initialize( - Storage::from(aptos_secure_storage::InMemoryStorage::new()), - node.signer.author(), - node.signer.private_key().clone(), - node.round_manager.consensus_state().waypoint(), - true, - ); - - node.safety_rules_manager = SafetyRulesManager::new_local(safety_storage); - let safety_rules = - MetricsSafetyRules::new(node.safety_rules_manager.client(), node.storage.clone()); - let safety_rules_container = Arc::new(Mutex::new(safety_rules)); - node.round_manager.set_safety_rules(safety_rules_container); - } - - timed_block_on(&runtime, async { - for _ in 0..2 { - let proposal_msg = node.next_proposal().await; - - reset_safety_rules(&mut node); - // construct_and_sign_vote - node.round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - - let vote_msg = node.next_vote().await; - - // sign_timeout - reset_safety_rules(&mut node); - let round = vote_msg.vote().vote_data().proposed().round(); - node.round_manager - .process_local_timeout(round) - .await - .unwrap_err(); - let vote_msg = node.next_vote().await; - - // sign proposal - reset_safety_rules(&mut node); - node.round_manager.process_vote_msg(vote_msg).await.unwrap(); - } - - // verify the last sign proposal happened - node.next_proposal().await; - }); -} - -#[test] -fn echo_timeout() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 4, - None, - None, - Some(config_with_round_timeout_msg_disabled()), - None, - None, - ); - runtime.spawn(playground.start()); - timed_block_on(&runtime, async { - // clear the message queue - for node in &mut nodes { - node.next_proposal().await; - } - // timeout 3 nodes - for node in &mut nodes[1..] { - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - } - let node_0 = &mut nodes[0]; - // node 0 doesn't timeout and should echo the timeout after 2 timeout message - for i in 0..3 { - let timeout_vote = node_0.next_vote().await; - let result = node_0.round_manager.process_vote_msg(timeout_vote).await; - // first and third message should not timeout - if i == 0 || i == 2 { - assert!(result.is_ok()); - } - if i == 1 { - // timeout is an Error - assert!(result.is_err()); - } - } - - let node_1 = &mut nodes[1]; - // it receives 4 timeout messages (1 from each) and doesn't echo since it already timeout - for _ in 0..4 { - let timeout_vote = node_1.next_vote().await; - // Verifying only some vote messages to check that round manager can accept both - // verified and unverified votes - node_1 - .round_manager - .process_vote_msg(timeout_vote) - .await - .unwrap(); - } - }); -} - -#[test] -fn echo_round_timeout_msg() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 4, - None, - None, - None, - None, - None, - ); - runtime.spawn(playground.start()); - timed_block_on(&runtime, async { - // clear the message queue - for node in &mut nodes { - node.next_proposal().await; - } - // timeout 3 nodes - for node in &mut nodes[1..] { - node.round_manager - .process_local_timeout(1) - .await - .unwrap_err(); - } - let node_0 = &mut nodes[0]; - // node 0 doesn't timeout and should echo the timeout after 2 timeout message - for i in 0..3 { - let timeout_vote = node_0.next_timeout().await; - let result = node_0 - .round_manager - .process_round_timeout_msg(timeout_vote) - .await; - // first and third message should not timeout - if i == 0 || i == 2 { - assert!(result.is_ok()); - } - if i == 1 { - // timeout is an Error - assert!(result.is_err()); - } - } - - let node_1 = &mut nodes[1]; - // it receives 4 timeout messages (1 from each) and doesn't echo since it already timeout - for _ in 0..4 { - let timeout_vote = node_1.next_timeout().await; - node_1 - .round_manager - .process_round_timeout_msg(timeout_vote) - .await - .unwrap(); - } - }); -} - -#[test] -fn no_next_test() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 4, - None, - None, - None, - None, - None, - ); - runtime.spawn(playground.start()); - - timed_block_on(&runtime, async { - // clear the message queue - for node in &mut nodes { - node.next_proposal().await; - } - - tokio::time::sleep(Duration::from_secs(1)).await; - - for node in nodes.iter_mut() { - node.no_next_msg(); - } - tokio::time::sleep(Duration::from_secs(1)).await; - - for node in nodes.iter_mut() { - node.no_next_msg(); - } - }); -} - -#[test] -fn commit_pipeline_test() { - let runtime = consensus_runtime(); - let proposers = vec![0, 0, 0, 0, 5]; - - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 7, - Some(proposers.clone()), - None, - None, - None, - None, - ); - runtime.spawn(playground.start()); - let behind_node = 6; - for i in 0..10 { - let next_proposer = proposers[(i + 2) as usize % proposers.len()]; - let prev_proposer = proposers[(i + 1) as usize % proposers.len()]; - info!("processing {}", i); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - next_proposer, - &[behind_node], - true, - Some(prev_proposer), - true, - i + 1, - i.saturating_sub(1), - i.saturating_sub(2), - ); - - std::thread::sleep(Duration::from_secs(1)); - - for node in nodes.iter_mut() { - node.no_next_ordered(); - } - } -} - -#[test] -fn block_retrieval_test() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 4, - Some(vec![0, 1]), - None, - None, - None, - None, - ); - runtime.spawn(playground.start()); - - for i in 0..4 { - info!("processing {}", i); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - i as usize % 2, - &[3], - true, - None, - true, - i + 1, - i.saturating_sub(1), - 0, - ); - } - - timed_block_on(&runtime, async { - let mut behind_node = nodes.pop().unwrap(); - - // Drain the queue on other nodes - for node in nodes.iter_mut() { - let _ = node.next_proposal().await; - } - - info!( - "Processing proposals for behind node {}", - behind_node.identity_desc() - ); - let handle = start_replying_to_block_retreival(nodes); - let proposal_msg = behind_node.next_proposal().await; - behind_node - .round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap(); - - handle.join().await; - }); -} - -#[test] -fn block_retrieval_timeout_test() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 4, - Some(vec![0, 1]), - None, - None, - None, - None, - ); - let timeout_config = playground.timeout_config(); - runtime.spawn(playground.start()); - - for i in 0..4 { - info!("processing {}", i); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - i as usize % 2, - &[3], - true, - None, - true, - i + 1, - i.saturating_sub(1), - 0, - ); - } - - timed_block_on(&runtime, async { - let mut behind_node = nodes.pop().unwrap(); - - for node in nodes.iter() { - timeout_config.write().timeout_message_for( - &TwinId { - id: behind_node.id, - author: behind_node.signer.author(), - }, - &TwinId { - id: node.id, - author: node.signer.author(), - }, - ); - } - - // Drain the queue on other nodes - for node in nodes.iter_mut() { - let _ = node.next_proposal().await; - } - - info!( - "Processing proposals for behind node {}", - behind_node.identity_desc() - ); - - let proposal_msg = behind_node.next_proposal().await; - behind_node - .round_manager - .process_proposal_msg(proposal_msg) - .await - .unwrap_err(); - }); -} - -#[ignore] // TODO: turn this test back on once the flakes have resolved. -#[test] -pub fn forking_retrieval_test() { - let runtime = consensus_runtime(); - - let proposal_node = 0; - let behind_node = 6; - let forking_node = 5; - - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 7, - Some(vec![ - proposal_node, - proposal_node, - proposal_node, - proposal_node, - proposal_node, - forking_node, - proposal_node, - proposal_node, - ]), - None, - None, - None, - None, - ); - runtime.spawn(playground.start()); - - info!("Propose vote and commit on first block"); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node], - true, - Some(proposal_node), - true, - 1, - 0, - 0, - ); - - info!("Propose vote and commit on second block"); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node], - true, - Some(proposal_node), - true, - 2, - 0, - 0, - ); - - info!("Propose vote and commit on second block"); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node], - true, - Some(proposal_node), - true, - 3, - 1, - 0, - ); - - info!("Propose vote and commit on third (dangling) block"); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - forking_node, - &[behind_node, forking_node], - false, - Some(proposal_node), - true, - 4, - 2, - 1, - ); - - timed_block_on(&runtime, async { - info!("Insert local timeout to all nodes on next round"); - let mut timeout_votes = 0; - for node in nodes.iter_mut() { - if node.id != behind_node && node.id != forking_node { - node.round_manager - .process_local_timeout(4) - .await - .unwrap_err(); - timeout_votes += 1; - } - } - - info!("Process all local timeouts"); - for node in nodes.iter_mut() { - info!("Timeouts on {}", node.id); - for i in 0..timeout_votes { - info!("Timeout {} on {}", i, node.id); - if node.id == forking_node && (2..4).contains(&i) { - info!("Got {}", node.next_commit_decision().await); - } - - let vote_msg_on_timeout = node.next_vote().await; - assert!(vote_msg_on_timeout.vote().is_timeout()); - if node.id != behind_node { - let result = node - .round_manager - .process_vote_msg(vote_msg_on_timeout) - .await; - - if node.id == forking_node && i == 2 { - result.unwrap_err(); - } else { - result.unwrap(); - } - } - } - } - }); - - timed_block_on(&runtime, async { - for node in nodes.iter_mut() { - let vote_msg_on_timeout = node.next_vote().await; - assert!(vote_msg_on_timeout.vote().is_timeout()); - } - - info!("Got {}", nodes[forking_node].next_commit_decision().await); - }); - - info!("Create forked block"); - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node], - true, - Some(forking_node), - false, - 5, - 2, - 1, - ); - - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node, forking_node], - true, - None, - false, - 6, - 3, - 3, - ); - - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[behind_node, forking_node], - true, - None, - false, - 7, - 5, - 3, - ); - - let mut nodes = timed_block_on(&runtime, async { - let mut behind_node_obj = nodes.pop().unwrap(); - - // Drain the queue on other nodes - let mut proposals = Vec::new(); - for node in nodes.iter_mut() { - proposals.push(node.next_proposal().await); - } - - info!( - "Processing proposals for behind node {}", - behind_node_obj.identity_desc() - ); - let handle = start_replying_to_block_retreival(nodes); - let proposal_msg = behind_node_obj.next_proposal().await; - behind_node_obj - .round_manager - .process_proposal_msg(proposal_msg.clone()) - .await - .unwrap(); - - nodes = handle.join().await; - behind_node_obj.no_next_msg(); - - for (proposal, node) in proposals.into_iter().zip(nodes.iter_mut()) { - node.pending_network_events.push(Event::Message( - node.signer.author(), - ConsensusMsg::ProposalMsg(Box::new(proposal)), - )); - } - behind_node_obj.pending_network_events.push(Event::Message( - behind_node_obj.signer.author(), - ConsensusMsg::ProposalMsg(Box::new(proposal_msg)), - )); - - nodes.push(behind_node_obj); - nodes - }); - - // confirm behind node can participate in consensus after state sync - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[forking_node, behind_node], - true, - None, - false, - 8, - 6, - 3, - ); - - // let next_message = timed_block_on(&runtime, nodes[proposal_node].next_network_message()); - // match next_message { - // ConsensusMsg::VoteMsg(_) => info!("Skip extra vote msg"), - // ConsensusMsg::ProposalMsg(msg) => { - // // put the message back in the queue. - // // actual peer doesn't matter, it is ignored, so use self. - // let peer = nodes[proposal_node].signer.author(); - // nodes[proposal_node] - // .pending_network_events - // .push(Event::Message(peer, ConsensusMsg::ProposalMsg(msg))) - // }, - // _ => panic!("unexpected network message {:?}", next_message), - // } - process_and_vote_on_proposal( - &runtime, - &mut nodes, - proposal_node, - &[forking_node], - true, - None, - false, - 9, - 7, - 3, - ); -} - -#[test] -/// If ProposalExt feature is disabled, ProposalExt should be rejected -/// No votes are sent, but the block is still added to the block tree. -fn no_vote_on_proposal_ext_when_feature_disabled() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - // In order to observe the votes we're going to check proposal processing on the non-proposer - // node (which will send the votes to the proposer). - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - None, - None, - None, - None, - ); - let node = &mut nodes[0]; - let genesis_qc = certificate_for_genesis(); - - let invalid_block = Block::new_proposal_ext( - vec![ValidatorTransaction::dummy(vec![0xFF]); 5], - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - let valid_block = Block::new_proposal( - Payload::empty(false, true), - 1, - 1, - genesis_qc, - &node.signer, - Vec::new(), - ) - .unwrap(); - - timed_block_on(&runtime, async { - // clear the message queue - node.next_proposal().await; - - assert!(node - .round_manager - .process_proposal(invalid_block) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal(valid_block) - .await - .is_ok()); - }); -} - -#[test] -fn no_vote_on_proposal_with_unexpected_vtxns() { - let vtxns = vec![ValidatorTransaction::ObservedJWKUpdate( - QuorumCertifiedUpdate::dummy(), - )]; - - assert_process_proposal_result( - None, - None, - Some(OnChainJWKConsensusConfig::default_disabled()), - vtxns.clone(), - false, - ); - - assert_process_proposal_result( - None, - None, - Some(OnChainJWKConsensusConfig::default_enabled()), - vtxns, - true, - ); -} - -#[test] -fn no_vote_on_proposal_with_uncertified_dkg_result() { - test_dkg_result_handling( - &[25_000_000; 4], - 1, - RealDKG::sample_secret_and_generate_transcript, - false, - ); -} - -#[test] -fn no_vote_on_proposal_with_inconsistent_secret_dkg_result() { - test_dkg_result_handling( - &[10_000_000, 70_000_000, 10_000_000, 10_000_000], - 1, - RealDKG::generate_transcript_for_inconsistent_secrets, - false, - ); -} - -#[test] -fn no_vote_on_proposal_with_dup_dealers_in_dkg_transcript() { - test_dkg_result_handling( - &[10_000_000, 40_000_000, 10_000_000, 40_000_000], - 1, - RealDKG::deal_twice_and_aggregate, - false, - ); -} - -#[test] -fn vote_on_proposal_with_valid_dkg_result() { - test_dkg_result_handling( - &[10_000_000, 70_000_000, 10_000_000, 10_000_000], - 1, - RealDKG::sample_secret_and_generate_transcript, - true, - ); -} - -fn test_dkg_result_handling( - voting_powers: &[u64], - dealer_idx: usize, - trx_gen_func: F, - should_accept: bool, -) where - F: Fn( - &mut ThreadRng, - &::PublicParams, - u64, - &::DealerPrivateKey, - ) -> ::Transcript, -{ - let mut rng = thread_rng(); - let epoch = 123; - let num_validators = voting_powers.len(); - let (signers, verifier) = - random_validator_verifier_with_voting_power(num_validators, None, false, voting_powers); - let validator_set: Vec = verifier - .validator_infos - .clone() - .into_iter() - .map(ValidatorConsensusInfoMoveStruct::from) - .collect(); - - let dkg_session_metadata = DKGSessionMetadata { - dealer_epoch: epoch, - randomness_config: RandomnessConfigMoveStruct::from( - OnChainRandomnessConfig::default_enabled(), - ), - dealer_validator_set: validator_set.clone(), - target_validator_set: validator_set, - }; - let public_params = RealDKG::new_public_params(&dkg_session_metadata); - let trx = trx_gen_func( - &mut rng, - &public_params, - dealer_idx as u64, - signers[dealer_idx].private_key(), - ); - let trx_bytes = bcs::to_bytes(&trx).unwrap(); - let vtxns = vec![ValidatorTransaction::DKGResult(DKGTranscript::new( - epoch, - verifier.get_ordered_account_addresses()[dealer_idx], - trx_bytes, - ))]; - - assert_process_proposal_result( - Some((signers, verifier)), - Some(OnChainRandomnessConfig::default_enabled()), - Some(OnChainJWKConsensusConfig::default_enabled()), - vtxns.clone(), - should_accept, - ); -} - -/// Setup a node with default configs and an optional `Features` override. -/// Create a block, fill it with the given vtxns, and process it with the `RoundManager` from the setup. -/// Assert the processing result. -fn assert_process_proposal_result( - validator_set: Option<(Vec, ValidatorVerifier)>, - randomness_config: Option, - jwk_consensus_config: Option, - vtxns: Vec, - expected_result: bool, -) { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - let mut nodes = NodeSetup::create_nodes_with_validator_set( - &mut playground, - runtime.handle().clone(), - 1, - None, - Some(OnChainConsensusConfig::default_for_genesis()), - None, - randomness_config, - jwk_consensus_config, - validator_set, - ); - - let node = &mut nodes[0]; - let genesis_qc = certificate_for_genesis(); - let block = Block::new_proposal_ext( - vtxns, - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - timed_block_on(&runtime, async { - // clear the message queue - node.next_proposal().await; - - assert_eq!( - expected_result, - node.round_manager - .process_proposal(block.clone()) - .await - .is_ok() - ); - }); -} - -#[ignore] -#[test] -/// If receiving txn num/block size limit is exceeded, ProposalExt should be rejected. -/// TODO: re-implement dummy vtxn and re-enable. -fn no_vote_on_proposal_ext_when_receiving_limit_exceeded() { - let runtime = consensus_runtime(); - let mut playground = NetworkPlayground::new(runtime.handle().clone()); - - let alg_config = ConsensusAlgorithmConfig::JolteonV2 { - main: ConsensusConfigV1::default(), - quorum_store_enabled: true, - order_vote_enabled: false, - }; - let vtxn_config = ValidatorTxnConfig::V1 { - per_block_limit_txn_count: 5, - per_block_limit_total_bytes: 400, - }; - - let local_config = ConsensusConfig { - max_receiving_block_txns: 10, - max_receiving_block_bytes: 800, - ..Default::default() - }; - - let randomness_config = OnChainRandomnessConfig::default_enabled(); - let mut nodes = NodeSetup::create_nodes( - &mut playground, - runtime.handle().clone(), - 1, - None, - Some(OnChainConsensusConfig::V4 { - alg: alg_config, - vtxn: vtxn_config, - window_size: DEFAULT_WINDOW_SIZE, - }), - Some(local_config), - Some(randomness_config), - None, - ); - let node = &mut nodes[0]; - let genesis_qc = certificate_for_genesis(); - - let block_too_many_txns = Block::new_proposal_ext( - vec![], - Payload::DirectMempool(create_vec_signed_transactions(11)), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - let block_too_many_vtxns = Block::new_proposal_ext( - vec![ValidatorTransaction::dummy(vec![0xFF; 20]); 6], - Payload::DirectMempool(create_vec_signed_transactions(4)), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - let block_too_large = Block::new_proposal_ext( - vec![ValidatorTransaction::dummy(vec![0xFF; 200]); 1], // total_bytes >= 200 * 1 = 200 - Payload::DirectMempool(create_vec_signed_transactions(9)), // = total_bytes >= 69 * 9 = 621 - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - let block_vtxns_too_large = Block::new_proposal_ext( - vec![ValidatorTransaction::dummy(vec![0xFF; 200]); 5], // total_bytes >= 200 * 5 = 1000 - Payload::empty(false, true), - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - let valid_block = Block::new_proposal_ext( - vec![ValidatorTransaction::dummy(vec![0xFF; 20]); 5], // total_bytes >= 60 * 5 = 300 - Payload::DirectMempool(create_vec_signed_transactions(5)), // total_bytes >= 69 * 5 = 345 - 1, - 1, - genesis_qc.clone(), - &node.signer, - Vec::new(), - ) - .unwrap(); - - timed_block_on(&runtime, async { - // clear the message queue - node.next_proposal().await; - - assert!(node - .round_manager - .process_proposal(block_too_many_txns) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal(block_too_many_vtxns) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal(block_too_large) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal(block_vtxns_too_large) - .await - .is_err()); - - assert!(node - .round_manager - .process_proposal(valid_block) - .await - .is_ok()); - }); -} diff --git a/consensus/src/round_manager_tests/consensus_test.rs b/consensus/src/round_manager_tests/consensus_test.rs new file mode 100644 index 00000000000..a8cd1973985 --- /dev/null +++ b/consensus/src/round_manager_tests/consensus_test.rs @@ -0,0 +1,1944 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 +// Parts of the project are originally copyright © Meta Platforms, Inc. + +use crate::{ + block_storage::BlockReader, + counters, + metrics_safety_rules::MetricsSafetyRules, + network::IncomingBlockRetrievalRequest, + network_interface::ConsensusMsg, + network_tests::{NetworkPlayground, TwinId}, + round_manager::round_manager_tests::{ + config_with_round_timeout_msg_disabled, start_replying_to_block_retreival, NodeSetup, + ProposalMsgType, + }, + test_utils::{consensus_runtime, timed_block_on, TreeInserter}, +}; +use aptos_config::config::ConsensusConfig; +use aptos_consensus_types::{ + block::{ + block_test_utils::{certificate_for_genesis, gen_test_certificate}, + Block, + }, + block_retrieval::{BlockRetrievalRequest, BlockRetrievalRequestV1, BlockRetrievalStatus}, + common::{Author, Payload, Round}, + opt_proposal_msg::OptProposalMsg, + proposal_msg::ProposalMsg, + sync_info::SyncInfo, + timeout_2chain::{TwoChainTimeout, TwoChainTimeoutWithPartialSignatures}, +}; +use aptos_crypto::HashValue; +use aptos_infallible::Mutex; +use aptos_logger::prelude::info; +use aptos_network::{protocols::network::Event, ProtocolId}; +use aptos_safety_rules::{PersistentSafetyStorage, SafetyRulesManager}; +use aptos_secure_storage::Storage; +use aptos_types::validator_verifier::generate_validator_verifier; +use futures::{channel::oneshot, StreamExt}; +use std::{sync::Arc, time::Duration}; +use tokio::{runtime::Runtime, time::timeout}; + +pub(super) fn process_and_vote_opt_proposal( + runtime: &Runtime, + node: &mut NodeSetup, + opt_proposal_msg: OptProposalMsg, + expected_round: Round, + expected_qc_ordered_round: Round, + expected_qc_committed_round: Round, +) { + info!("Processing opt proposal on {}", node.identity_desc()); + + assert_eq!(opt_proposal_msg.round(), expected_round); + assert_eq!( + opt_proposal_msg.sync_info().highest_ordered_round(), + expected_qc_ordered_round.saturating_sub(1) + ); + assert_eq!( + opt_proposal_msg.sync_info().highest_commit_round(), + expected_qc_committed_round + ); + + timed_block_on( + runtime, + node.round_manager + .process_opt_proposal_msg(opt_proposal_msg), + ) + .unwrap(); + info!("Finish process opt proposal on {}", node.identity_desc()); + + info!( + "Processing proposal (from opt proposal) on {}", + node.identity_desc() + ); + + let opt_block_data = timed_block_on(runtime, node.processed_opt_proposal_rx.next()).unwrap(); + timed_block_on( + runtime, + node.round_manager.process_opt_proposal(opt_block_data), + ) + .unwrap(); + + info!( + "Finish process proposal (from opt proposal) on {}", + node.identity_desc() + ); +} + +pub(super) fn process_and_vote_on_proposal( + runtime: &Runtime, + nodes: &mut [NodeSetup], + next_proposer: usize, + down_nodes: &[usize], + process_votes: bool, + apply_commit_prev_proposer: Option, + apply_commit_on_votes: bool, + expected_round: u64, + expected_qc_ordered_round: u64, + expected_qc_committed_round: u64, +) { + info!( + "Called {} with current {} and apply commit prev {:?}", + expected_round, next_proposer, apply_commit_prev_proposer + ); + let mut num_votes = 0; + + for node in nodes.iter_mut() { + info!("Waiting on next_proposal on node {}", node.identity_desc()); + if down_nodes.contains(&node.id) { + // Drop the proposal on down nodes + timed_block_on(runtime, node.next_opt_or_normal_proposal()); + info!("Dropping proposal on down node {}", node.identity_desc()); + } else { + // Proccess proposal on other nodes + let proposal_msg_type = timed_block_on(runtime, node.next_opt_or_normal_proposal()); + match proposal_msg_type { + ProposalMsgType::Normal(proposal_msg) => { + info!("Processing proposal on {}", node.identity_desc()); + + assert_eq!(proposal_msg.proposal().round(), expected_round); + assert_eq!( + proposal_msg.sync_info().highest_ordered_round(), + expected_qc_ordered_round + ); + assert_eq!( + proposal_msg.sync_info().highest_commit_round(), + expected_qc_committed_round + ); + + timed_block_on( + runtime, + node.round_manager.process_proposal_msg(proposal_msg), + ) + .unwrap(); + info!("Finish process proposal on {}", node.identity_desc()); + }, + ProposalMsgType::Optimistic(opt_proposal_msg) => process_and_vote_opt_proposal( + runtime, + node, + opt_proposal_msg, + expected_round, + expected_qc_ordered_round, + expected_qc_committed_round, + ), + } + num_votes += 1; + } + } + + for node in nodes.iter_mut() { + info!( + "Fetching {} votes in round {} on node {}", + num_votes, + expected_round, + node.identity_desc() + ); + if down_nodes.contains(&node.id) { + // Drop the votes on down nodes + info!("Dropping votes on down node {}", node.identity_desc()); + for _ in 0..num_votes { + timed_block_on(runtime, node.next_vote()); + } + } else { + let mut votes = Vec::new(); + for _ in 0..num_votes { + votes.push(timed_block_on(runtime, node.next_vote())); + } + + info!("Processing votes on node {}", node.identity_desc()); + if process_votes { + for vote_msg in votes { + timed_block_on(runtime, node.round_manager.process_vote_msg(vote_msg)).unwrap(); + } + if apply_commit_prev_proposer.is_some() + && expected_round > 1 + && apply_commit_on_votes + { + info!( + "Applying next commit {} on proposer node {}", + expected_round - 2, + node.identity_desc() + ); + timed_block_on(runtime, node.commit_next_ordered(&[expected_round - 1])); + } + } + } + } +} + +#[test] +fn new_round_on_quorum_cert() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let node = &mut nodes[0]; + let genesis = node.block_store.ordered_root(); + timed_block_on(&runtime, async { + // round 1 should start + let proposal_msg = node.next_proposal().await; + assert_eq!( + proposal_msg.proposal().quorum_cert().certified_block().id(), + genesis.id() + ); + let b1_id = proposal_msg.proposal().id(); + assert_eq!(proposal_msg.proposer(), node.signer.author()); + + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + + let vote_msg = node.next_vote().await; + // Adding vote to form a QC + node.round_manager.process_vote_msg(vote_msg).await.unwrap(); + + // round 2 should start + let proposal_msg_type = node.next_opt_or_normal_proposal().await; + match proposal_msg_type { + ProposalMsgType::Normal(proposal_msg) => { + let proposal = proposal_msg.proposal(); + assert_eq!(proposal.round(), 2); + assert_eq!(proposal.parent_id(), b1_id); + assert_eq!(proposal.quorum_cert().certified_block().id(), b1_id); + }, + ProposalMsgType::Optimistic(opt_proposal_msg) => { + let proposal = opt_proposal_msg.block_data(); + assert_eq!(proposal.round(), 2); + assert_eq!(proposal.parent_id(), b1_id); + assert_eq!( + proposal.grandparent_qc().certified_block().id(), + genesis.id() + ); + }, + } + }); +} + +#[test] +/// If the proposal is valid, a vote should be sent +fn vote_on_successful_proposal() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let node = &mut nodes[0]; + + let genesis_qc = certificate_for_genesis(); + timed_block_on(&runtime, async { + // Start round 1 and clear the message queue + node.next_proposal().await; + + let proposal = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let proposal_id = proposal.id(); + node.round_manager.process_proposal(proposal).await.unwrap(); + let vote_msg = node.next_vote().await; + assert_eq!(vote_msg.vote().author(), node.signer.author()); + assert_eq!(vote_msg.vote().vote_data().proposed().id(), proposal_id); + let consensus_state = node.round_manager.consensus_state(); + assert_eq!(consensus_state.epoch(), 1); + assert_eq!(consensus_state.last_voted_round(), 1); + assert_eq!(consensus_state.preferred_round(), 0); + assert!(consensus_state.in_validator_set()); + }); +} + +#[test] +/// In back pressure mode, verify that the proposals are processed after we get out of back pressure. +fn delay_proposal_processing_in_sync_only() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let node = &mut nodes[0]; + + let genesis_qc = certificate_for_genesis(); + timed_block_on(&runtime, async { + // Start round 1 and clear the message queue + node.next_proposal().await; + + // Set sync only to true so that new proposal processing is delayed. + node.block_store.set_back_pressure_for_test(true); + let proposal = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let proposal_id = proposal.id(); + node.round_manager + .process_proposal(proposal.clone()) + .await + .unwrap(); + + // Wait for some time to ensure that the proposal was not processed + timeout(Duration::from_millis(200), node.next_vote()) + .await + .unwrap_err(); + + // Clear the sync only mode and process verified proposal and ensure it is processed now + node.block_store.set_back_pressure_for_test(false); + + node.round_manager + .process_verified_proposal(proposal) + .await + .unwrap(); + + let vote_msg = node.next_vote().await; + assert_eq!(vote_msg.vote().author(), node.signer.author()); + assert_eq!(vote_msg.vote().vote_data().proposed().id(), proposal_id); + let consensus_state = node.round_manager.consensus_state(); + assert_eq!(consensus_state.epoch(), 1); + assert_eq!(consensus_state.last_voted_round(), 1); + assert_eq!(consensus_state.preferred_round(), 0); + assert!(consensus_state.in_validator_set()); + }); +} + +#[test] +/// If the proposal does not pass voting rules, +/// No votes are sent, but the block is still added to the block tree. +fn no_vote_on_old_proposal() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let node = &mut nodes[0]; + let genesis_qc = certificate_for_genesis(); + let new_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let new_block_id = new_block.id(); + let old_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 2, + genesis_qc, + &node.signer, + Vec::new(), + ) + .unwrap(); + timed_block_on(&runtime, async { + // clear the message queue + node.next_proposal().await; + + node.round_manager + .process_proposal(new_block) + .await + .unwrap(); + node.round_manager + .process_proposal(old_block) + .await + .unwrap_err(); + let vote_msg = node.next_vote().await; + assert_eq!(vote_msg.vote().vote_data().proposed().id(), new_block_id); + }); +} + +#[test] +/// We don't vote for proposals that 'skips' rounds +/// After that when we then receive proposal for correct round, we vote for it +/// Basically it checks that adversary can not send proposal and skip rounds violating round_state +/// rules +fn no_vote_on_mismatch_round() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut node = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ) + .pop() + .unwrap(); + let genesis_qc = certificate_for_genesis(); + let correct_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let block_skip_round = Block::new_proposal( + Payload::empty(false, true), + 2, + 2, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + timed_block_on(&runtime, async { + let bad_proposal = ProposalMsg::new( + block_skip_round, + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + assert!(node + .round_manager + .process_proposal_msg(bad_proposal) + .await + .is_err()); + let good_proposal = ProposalMsg::new( + correct_block.clone(), + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + node.round_manager + .process_proposal_msg(good_proposal) + .await + .unwrap(); + }); +} + +#[test] +/// Ensure that after the vote messages are broadcasted upon timeout, the receivers +/// have the highest quorum certificate (carried by the SyncInfo of the vote message) +fn sync_info_carried_on_timeout_vote() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_round_timeout_msg_disabled()), + None, + None, + false, + ); + let mut node = nodes.pop().unwrap(); + + timed_block_on(&runtime, async { + let proposal_msg = node.next_proposal().await; + let block_0 = proposal_msg.proposal().clone(); + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + node.next_vote().await; + let parent_block_info = block_0.quorum_cert().certified_block(); + // Populate block_0 and a quorum certificate for block_0 on non_proposer + let block_0_quorum_cert = gen_test_certificate( + &[node.signer.clone()], + // Follow MockStateComputer implementation + block_0.gen_block_info( + parent_block_info.executed_state_id(), + parent_block_info.version(), + parent_block_info.next_epoch_state().cloned(), + ), + parent_block_info.clone(), + None, + ); + node.block_store + .insert_single_quorum_cert(block_0_quorum_cert.clone()) + .unwrap(); + + node.round_manager.round_state.process_certificates( + SyncInfo::new( + block_0_quorum_cert.clone(), + block_0_quorum_cert.into_wrapped_ledger_info(), + None, + ), + &generate_validator_verifier(&[node.signer.clone()]), + ); + node.round_manager + .process_local_timeout(2) + .await + .unwrap_err(); + let vote_msg_on_timeout = node.next_vote().await; + assert!(vote_msg_on_timeout.vote().is_timeout()); + assert_eq!( + *vote_msg_on_timeout.sync_info().highest_quorum_cert(), + block_0_quorum_cert + ); + }); +} + +#[test] +/// We don't vote for proposals that comes from proposers that are not valid proposers for round +fn no_vote_on_invalid_proposer() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 2, + None, + None, + None, + None, + None, + None, + false, + ); + let incorrect_proposer = nodes.pop().unwrap(); + let mut node = nodes.pop().unwrap(); + let genesis_qc = certificate_for_genesis(); + let correct_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let block_incorrect_proposer = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &incorrect_proposer.signer, + Vec::new(), + ) + .unwrap(); + timed_block_on(&runtime, async { + let bad_proposal = ProposalMsg::new( + block_incorrect_proposer, + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + assert!(node + .round_manager + .process_proposal_msg(bad_proposal) + .await + .is_err()); + let good_proposal = ProposalMsg::new( + correct_block.clone(), + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + + node.round_manager + .process_proposal_msg(good_proposal.clone()) + .await + .unwrap(); + }); +} + +#[test] +/// We allow to 'skip' round if proposal carries timeout certificate for next round +fn new_round_on_timeout_certificate() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut node = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ) + .pop() + .unwrap(); + let genesis_qc = certificate_for_genesis(); + let correct_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let block_skip_round = Block::new_proposal( + Payload::empty(false, true), + 2, + 2, + genesis_qc.clone(), + &node.signer, + vec![(1, node.signer.author())], + ) + .unwrap(); + let timeout = TwoChainTimeout::new(1, 1, genesis_qc.clone()); + let timeout_signature = timeout.sign(&node.signer).unwrap(); + + let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); + tc_partial.add(node.signer.author(), timeout, timeout_signature); + + let tc = tc_partial + .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) + .unwrap(); + timed_block_on(&runtime, async { + let skip_round_proposal = ProposalMsg::new( + block_skip_round, + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + Some(tc), + ), + ); + node.round_manager + .process_proposal_msg(skip_round_proposal) + .await + .unwrap(); + let old_good_proposal = ProposalMsg::new( + correct_block.clone(), + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + let before = counters::ERROR_COUNT.get(); + assert!(node + .round_manager + .process_proposal_msg(old_good_proposal) + .await + .is_ok()); // we eat the error + assert_eq!(counters::ERROR_COUNT.get(), before + 1); // but increase the counter + }); +} + +#[test] +/// We allow to 'skip' round if proposal carries timeout certificate for next round +fn reject_invalid_failed_authors() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut node = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ) + .pop() + .unwrap(); + let genesis_qc = certificate_for_genesis(); + + let create_timeout = |round: Round| { + let timeout = TwoChainTimeout::new(1, round, genesis_qc.clone()); + let timeout_signature = timeout.sign(&node.signer).unwrap(); + let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); + tc_partial.add(node.signer.author(), timeout, timeout_signature); + + tc_partial + .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) + .unwrap() + }; + + let create_proposal = |round: Round, failed_authors: Vec<(Round, Author)>| { + let block = Block::new_proposal( + Payload::empty(false, true), + round, + 2, + genesis_qc.clone(), + &node.signer, + failed_authors, + ) + .unwrap(); + ProposalMsg::new( + block, + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + if round > 1 { + Some(create_timeout(round - 1)) + } else { + None + }, + ), + ) + }; + + let extra_failed_authors_proposal = create_proposal(2, vec![(1, Author::random())]); + let missing_failed_authors_proposal = create_proposal(2, vec![]); + let wrong_failed_authors_proposal = create_proposal(2, vec![(1, Author::random())]); + let not_enough_failed_proposal = create_proposal(3, vec![(2, node.signer.author())]); + let valid_proposal = create_proposal( + 4, + (1..4).map(|i| (i as Round, node.signer.author())).collect(), + ); + + timed_block_on(&runtime, async { + assert!(node + .round_manager + .process_proposal_msg(extra_failed_authors_proposal) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal_msg(missing_failed_authors_proposal) + .await + .is_err()); + }); + + timed_block_on(&runtime, async { + assert!(node + .round_manager + .process_proposal_msg(wrong_failed_authors_proposal) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal_msg(not_enough_failed_proposal) + .await + .is_err()); + + node.round_manager + .process_proposal_msg(valid_proposal) + .await + .unwrap() + }); +} + +#[test] +fn response_on_block_retrieval() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut node = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ) + .pop() + .unwrap(); + + let genesis_qc = certificate_for_genesis(); + let block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let block_id = block.id(); + let proposal = ProposalMsg::new( + block, + SyncInfo::new( + genesis_qc.clone(), + genesis_qc.into_wrapped_ledger_info(), + None, + ), + ); + + timed_block_on(&runtime, async { + node.round_manager + .process_proposal_msg(proposal) + .await + .unwrap(); + + // first verify that we can retrieve the block if it's in the tree + let (tx1, rx1) = oneshot::channel(); + let single_block_request = IncomingBlockRetrievalRequest { + req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(block_id, 1)), + protocol: ProtocolId::ConsensusRpcBcs, + response_sender: tx1, + }; + node.block_store + .process_block_retrieval(single_block_request) + .await + .unwrap(); + match rx1.await { + Ok(Ok(bytes)) => { + let response = match bcs::from_bytes(&bytes) { + Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, + _ => panic!("block retrieval failure"), + }; + assert_eq!(response.status(), BlockRetrievalStatus::Succeeded); + assert_eq!(response.blocks().first().unwrap().id(), block_id); + }, + _ => panic!("block retrieval failure"), + } + + // verify that if a block is not there, return ID_NOT_FOUND + let (tx2, rx2) = oneshot::channel(); + let missing_block_request = IncomingBlockRetrievalRequest { + req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(HashValue::random(), 1)), + protocol: ProtocolId::ConsensusRpcBcs, + response_sender: tx2, + }; + + node.block_store + .process_block_retrieval(missing_block_request) + .await + .unwrap(); + match rx2.await { + Ok(Ok(bytes)) => { + let response = match bcs::from_bytes(&bytes) { + Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, + _ => panic!("block retrieval failure"), + }; + assert_eq!(response.status(), BlockRetrievalStatus::IdNotFound); + assert!(response.blocks().is_empty()); + }, + _ => panic!("block retrieval failure"), + } + + // if asked for many blocks, return NOT_ENOUGH_BLOCKS + let (tx3, rx3) = oneshot::channel(); + let many_block_request = IncomingBlockRetrievalRequest { + req: BlockRetrievalRequest::V1(BlockRetrievalRequestV1::new(block_id, 3)), + protocol: ProtocolId::ConsensusRpcBcs, + response_sender: tx3, + }; + node.block_store + .process_block_retrieval(many_block_request) + .await + .unwrap(); + match rx3.await { + Ok(Ok(bytes)) => { + let response = match bcs::from_bytes(&bytes) { + Ok(ConsensusMsg::BlockRetrievalResponse(resp)) => *resp, + _ => panic!("block retrieval failure"), + }; + assert_eq!(response.status(), BlockRetrievalStatus::NotEnoughBlocks); + assert_eq!(block_id, response.blocks().first().unwrap().id()); + assert_eq!( + node.block_store.ordered_root().id(), + response.blocks().get(1).unwrap().id() + ); + }, + _ => panic!("block retrieval failure"), + } + }); +} + +#[test] +/// rebuild a node from previous storage without violating safety guarantees. +fn recover_on_restart() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut node = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ) + .pop() + .unwrap(); + let inserter = TreeInserter::new_with_store(node.signer.clone(), node.block_store.clone()); + + let genesis_qc = certificate_for_genesis(); + let mut data = Vec::new(); + let num_proposals = 100; + // insert a few successful proposals + for i in 1..=num_proposals { + let proposal = inserter.create_block_with_qc( + genesis_qc.clone(), + i, + i, + Payload::empty(false, true), + (std::cmp::max(1, i.saturating_sub(10))..i) + .map(|i| (i, inserter.signer().author())) + .collect(), + ); + let timeout = TwoChainTimeout::new(1, i - 1, genesis_qc.clone()); + let mut tc_partial = TwoChainTimeoutWithPartialSignatures::new(timeout.clone()); + tc_partial.add( + inserter.signer().author(), + timeout.clone(), + timeout.sign(inserter.signer()).unwrap(), + ); + + let tc = tc_partial + .aggregate_signatures(&generate_validator_verifier(&[node.signer.clone()])) + .unwrap(); + + data.push((proposal, tc)); + } + + timed_block_on(&runtime, async { + for (proposal, tc) in &data { + let proposal_msg = ProposalMsg::new( + proposal.clone(), + SyncInfo::new( + proposal.quorum_cert().clone(), + genesis_qc.into_wrapped_ledger_info(), + Some(tc.clone()), + ), + ); + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + } + }); + + // verify after restart we recover the data + node = node.restart(&mut playground, runtime.handle().clone()); + let consensus_state = node.round_manager.consensus_state(); + assert_eq!(consensus_state.epoch(), 1); + assert_eq!(consensus_state.last_voted_round(), num_proposals); + assert_eq!(consensus_state.preferred_round(), 0); + assert!(consensus_state.in_validator_set()); + for (block, _) in data { + assert!(node.block_store.block_exists(block.id())); + } +} + +#[test] +/// Generate a NIL vote extending HQC upon timeout if no votes have been sent in the round. +fn nil_vote_on_timeout() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_round_timeout_msg_disabled()), + None, + None, + false, + ); + let node = &mut nodes[0]; + let genesis = node.block_store.ordered_root(); + timed_block_on(&runtime, async { + node.next_proposal().await; + // Process the outgoing vote message and verify that it contains a round signature + // and that the vote extends genesis. + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + let vote_msg = node.next_vote().await; + + let vote = vote_msg.vote(); + + assert!(vote.is_timeout()); + // NIL block doesn't change timestamp + assert_eq!( + vote.vote_data().proposed().timestamp_usecs(), + genesis.timestamp_usecs() + ); + assert_eq!(vote.vote_data().proposed().round(), 1); + assert_eq!( + vote.vote_data().parent().id(), + node.block_store.ordered_root().id() + ); + }); +} + +#[test] +/// Generate a Timeout upon timeout if no votes have been sent in the round. +fn timeout_round_on_timeout() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let local_config = ConsensusConfig { + enable_round_timeout_msg: true, + ..Default::default() + }; + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(local_config), + None, + None, + false, + ); + let node = &mut nodes[0]; + let genesis = node.block_store.ordered_root(); + timed_block_on(&runtime, async { + node.next_proposal().await; + // Process the outgoing vote message and verify that it contains a round signature + // and that the vote extends genesis. + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + let timeout_msg = node.next_timeout().await; + + let timeout = timeout_msg.timeout(); + + assert_eq!(timeout.round(), 1); + assert_eq!(timeout.author(), node.signer.author()); + assert_eq!(timeout.epoch(), 1); + assert_eq!(timeout.two_chain_timeout().hqc_round(), genesis.round()); + }); +} + +#[test] +/// If the node votes in a round, upon timeout the same vote is re-sent with a timeout signature. +fn vote_resent_on_timeout() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_round_timeout_msg_disabled()), + None, + None, + false, + ); + let node = &mut nodes[0]; + timed_block_on(&runtime, async { + let proposal_msg = node.next_proposal().await; + let id = proposal_msg.proposal().id(); + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + let vote_msg = node.next_vote().await; + let vote = vote_msg.vote(); + assert!(!vote.is_timeout()); + assert_eq!(vote.vote_data().proposed().id(), id); + // Process the outgoing vote message and verify that it contains a round signature + // and that the vote is the same as above. + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + let timeout_vote_msg = node.next_vote().await; + let timeout_vote = timeout_vote_msg.vote(); + + assert!(timeout_vote.is_timeout()); + assert_eq!(timeout_vote.vote_data(), vote.vote_data()); + }); +} + +#[test] +/// If the node votes in a round, upon timeout the same vote is re-sent with a timeout signature. +fn timeout_sent_on_timeout_after_vote() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let local_config = ConsensusConfig { + enable_round_timeout_msg: true, + ..Default::default() + }; + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(local_config), + None, + None, + false, + ); + let node = &mut nodes[0]; + timed_block_on(&runtime, async { + let proposal_msg = node.next_proposal().await; + let id = proposal_msg.proposal().id(); + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + let vote_msg = node.next_vote().await; + let vote = vote_msg.vote(); + assert!(!vote.is_timeout()); + assert_eq!(vote.vote_data().proposed().id(), id); + // Process the outgoing vote message and verify that it contains a round signature + // and that the vote is the same as above. + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + let timeout_msg = node.next_timeout().await; + + assert_eq!(timeout_msg.round(), vote.vote_data().proposed().round()); + assert_eq!(timeout_msg.sync_info(), vote_msg.sync_info()); + }); +} + +#[test] +#[ignore] // TODO: this test needs to be fixed! +fn sync_on_partial_newer_sync_info() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let mut node = nodes.pop().unwrap(); + runtime.spawn(playground.start()); + timed_block_on(&runtime, async { + // commit block 1 after 4 rounds + for _ in 1..=4 { + let proposal_msg = node.next_proposal().await; + + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + let vote_msg = node.next_vote().await; + // Adding vote to form a QC + node.round_manager.process_vote_msg(vote_msg).await.unwrap(); + } + let block_4 = node.next_proposal().await; + node.round_manager + .process_proposal_msg(block_4.clone()) + .await + .unwrap(); + // commit genesis and block 1 + for i in 0..2 { + node.commit_next_ordered(&[i]).await; + } + let vote_msg = node.next_vote().await; + let vote_data = vote_msg.vote().vote_data(); + let block_4_qc = gen_test_certificate( + &[node.signer.clone()], + vote_data.proposed().clone(), + vote_data.parent().clone(), + None, + ); + // Create a sync info with newer quorum cert but older commit cert + let sync_info = SyncInfo::new( + block_4_qc.clone(), + certificate_for_genesis().into_wrapped_ledger_info(), + None, + ); + node.round_manager + .ensure_round_and_sync_up( + sync_info.highest_round() + 1, + &sync_info, + node.signer.author(), + ) + .await + .unwrap(); + // QuorumCert added + assert_eq!(*node.block_store.highest_quorum_cert(), block_4_qc); + }); +} + +#[test] +fn safety_rules_crash() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_round_timeout_msg_disabled()), + None, + None, + false, + ); + let mut node = nodes.pop().unwrap(); + runtime.spawn(playground.start()); + + fn reset_safety_rules(node: &mut NodeSetup) { + let safety_storage = PersistentSafetyStorage::initialize( + Storage::from(aptos_secure_storage::InMemoryStorage::new()), + node.signer.author(), + node.signer.private_key().clone(), + node.round_manager.consensus_state().waypoint(), + true, + ); + + node.safety_rules_manager = SafetyRulesManager::new_local(safety_storage); + let safety_rules = + MetricsSafetyRules::new(node.safety_rules_manager.client(), node.storage.clone()); + let safety_rules_container = Arc::new(Mutex::new(safety_rules)); + node.round_manager.set_safety_rules(safety_rules_container); + } + + timed_block_on(&runtime, async { + for _ in 0..2 { + let proposal_msg_type = node.next_opt_or_normal_proposal().await; + + reset_safety_rules(&mut node); + + match proposal_msg_type { + ProposalMsgType::Normal(proposal_msg) => { + // construct_and_sign_vote + node.round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(); + }, + ProposalMsgType::Optimistic(opt_proposal_msg) => { + node.round_manager + .process_opt_proposal_msg(opt_proposal_msg) + .await + .unwrap(); + let opt_block_data = node.processed_opt_proposal_rx.next().await.unwrap(); + node.round_manager + .process_opt_proposal(opt_block_data) + .await + .unwrap(); + }, + } + + let vote_msg = node.next_vote().await; + + // sign_timeout + reset_safety_rules(&mut node); + let round = vote_msg.vote().vote_data().proposed().round(); + node.round_manager + .process_local_timeout(round) + .await + .unwrap_err(); + let vote_msg = node.next_vote().await; + + // sign proposal + reset_safety_rules(&mut node); + node.round_manager.process_vote_msg(vote_msg).await.unwrap(); + } + + // verify the last sign proposal happened + node.next_opt_or_normal_proposal().await; + }); +} + +#[test] +fn echo_timeout() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 4, + None, + None, + None, + Some(config_with_round_timeout_msg_disabled()), + None, + None, + false, + ); + runtime.spawn(playground.start()); + timed_block_on(&runtime, async { + // clear the message queue + for node in &mut nodes { + node.next_proposal().await; + } + // timeout 3 nodes + for node in &mut nodes[1..] { + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + } + let node_0 = &mut nodes[0]; + // node 0 doesn't timeout and should echo the timeout after 2 timeout message + for i in 0..3 { + let timeout_vote = node_0.next_vote().await; + let result = node_0.round_manager.process_vote_msg(timeout_vote).await; + // first and third message should not timeout + if i == 0 || i == 2 { + assert!(result.is_ok()); + } + if i == 1 { + // timeout is an Error + assert!(result.is_err()); + } + } + + let node_1 = &mut nodes[1]; + // it receives 4 timeout messages (1 from each) and doesn't echo since it already timeout + for _ in 0..4 { + let timeout_vote = node_1.next_vote().await; + // Verifying only some vote messages to check that round manager can accept both + // verified and unverified votes + node_1 + .round_manager + .process_vote_msg(timeout_vote) + .await + .unwrap(); + } + }); +} + +#[test] +fn echo_round_timeout_msg() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 4, + None, + None, + None, + None, + None, + None, + false, + ); + runtime.spawn(playground.start()); + timed_block_on(&runtime, async { + // clear the message queue + for node in &mut nodes { + node.next_proposal().await; + } + // timeout 3 nodes + for node in &mut nodes[1..] { + node.round_manager + .process_local_timeout(1) + .await + .unwrap_err(); + } + let node_0 = &mut nodes[0]; + // node 0 doesn't timeout and should echo the timeout after 2 timeout message + for i in 0..3 { + let timeout_vote = node_0.next_timeout().await; + let result = node_0 + .round_manager + .process_round_timeout_msg(timeout_vote) + .await; + // first and third message should not timeout + if i == 0 || i == 2 { + assert!(result.is_ok()); + } + if i == 1 { + // timeout is an Error + assert!(result.is_err()); + } + } + + let node_1 = &mut nodes[1]; + // it receives 4 timeout messages (1 from each) and doesn't echo since it already timeout + for _ in 0..4 { + let timeout_vote = node_1.next_timeout().await; + node_1 + .round_manager + .process_round_timeout_msg(timeout_vote) + .await + .unwrap(); + } + }); +} + +#[test] +fn no_next_test() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 4, + None, + None, + None, + None, + None, + None, + false, + ); + runtime.spawn(playground.start()); + + timed_block_on(&runtime, async { + // clear the message queue + for node in &mut nodes { + node.next_proposal().await; + } + + tokio::time::sleep(Duration::from_secs(1)).await; + + for node in nodes.iter_mut() { + node.no_next_msg(); + } + tokio::time::sleep(Duration::from_secs(1)).await; + + for node in nodes.iter_mut() { + node.no_next_msg(); + } + }); +} + +#[test] +fn commit_pipeline_test() { + let runtime = consensus_runtime(); + let proposers = vec![0, 0, 0, 0, 5]; + + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 7, + Some(proposers.clone()), + None, + None, + None, + None, + None, + false, + ); + runtime.spawn(playground.start()); + let behind_node = 6; + for i in 0..10 { + let next_proposer = proposers[(i + 2) as usize % proposers.len()]; + let prev_proposer = proposers[(i + 1) as usize % proposers.len()]; + info!("processing {}", i); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + next_proposer, + &[behind_node], + true, + Some(prev_proposer), + true, + i + 1, + i.saturating_sub(1), + i.saturating_sub(2), + ); + + std::thread::sleep(Duration::from_secs(1)); + + for node in nodes.iter_mut() { + node.no_next_ordered(); + } + } +} + +#[test] +fn block_retrieval_test() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 4, + Some(vec![0, 1]), + None, + None, + None, + None, + None, + false, + ); + runtime.spawn(playground.start()); + + for i in 0..4 { + info!("processing {}", i); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + i as usize % 2, + &[3], + true, + None, + true, + i + 1, + i.saturating_sub(1), + 0, + ); + } + + timed_block_on(&runtime, async { + let mut behind_node = nodes.pop().unwrap(); + + // Drain the queue on other nodes + for node in nodes.iter_mut() { + let _ = node.next_opt_or_normal_proposal().await; + } + + info!( + "Processing proposals for behind node {}", + behind_node.identity_desc() + ); + let handle = start_replying_to_block_retreival(nodes); + + let proposal_msg_type = behind_node.next_opt_or_normal_proposal().await; + info!("got proposal msg: {:?}", proposal_msg_type); + match proposal_msg_type { + ProposalMsgType::Normal(proposal_msg) => behind_node + .round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap(), + ProposalMsgType::Optimistic(opt_proposal_msg) => { + behind_node + .round_manager + .process_opt_proposal_msg(opt_proposal_msg) + .await + .unwrap(); + }, + } + + handle.join().await; + }); +} + +#[test] +fn block_retrieval_timeout_test() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 4, + Some(vec![0, 1]), + None, + None, + None, + None, + None, + false, + ); + let timeout_config = playground.timeout_config(); + runtime.spawn(playground.start()); + + for i in 0..4 { + info!("processing {}", i); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + i as usize % 2, + &[3], + true, + None, + true, + i + 1, + i.saturating_sub(1), + 0, + ); + } + + timed_block_on(&runtime, async { + let mut behind_node = nodes.pop().unwrap(); + + for node in nodes.iter() { + timeout_config.write().timeout_message_for( + &TwinId { + id: behind_node.id, + author: behind_node.signer.author(), + }, + &TwinId { + id: node.id, + author: node.signer.author(), + }, + ); + } + + // Drain the queue on other nodes + for node in nodes.iter_mut() { + let _ = node.next_opt_or_normal_proposal().await; + } + + info!( + "Processing proposals for behind node {}", + behind_node.identity_desc() + ); + + let proposal_msg_type = behind_node.next_opt_or_normal_proposal().await; + match proposal_msg_type { + ProposalMsgType::Normal(proposal_msg) => { + behind_node + .round_manager + .process_proposal_msg(proposal_msg) + .await + .unwrap_err(); + }, + ProposalMsgType::Optimistic(opt_proposal_msg) => { + behind_node + .round_manager + .process_opt_proposal_msg(opt_proposal_msg) + .await + .unwrap_err(); + }, + } + }); +} + +#[ignore] // TODO: turn this test back on once the flakes have resolved. +#[test] +pub fn forking_retrieval_test() { + let runtime = consensus_runtime(); + + let proposal_node = 0; + let behind_node = 6; + let forking_node = 5; + + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 7, + Some(vec![ + proposal_node, + proposal_node, + proposal_node, + proposal_node, + proposal_node, + forking_node, + proposal_node, + proposal_node, + ]), + None, + None, + None, + None, + None, + false, + ); + runtime.spawn(playground.start()); + + info!("Propose vote and commit on first block"); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node], + true, + Some(proposal_node), + true, + 1, + 0, + 0, + ); + + info!("Propose vote and commit on second block"); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node], + true, + Some(proposal_node), + true, + 2, + 0, + 0, + ); + + info!("Propose vote and commit on second block"); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node], + true, + Some(proposal_node), + true, + 3, + 1, + 0, + ); + + info!("Propose vote and commit on third (dangling) block"); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + forking_node, + &[behind_node, forking_node], + false, + Some(proposal_node), + true, + 4, + 2, + 1, + ); + + timed_block_on(&runtime, async { + info!("Insert local timeout to all nodes on next round"); + let mut timeout_votes = 0; + for node in nodes.iter_mut() { + if node.id != behind_node && node.id != forking_node { + node.round_manager + .process_local_timeout(4) + .await + .unwrap_err(); + timeout_votes += 1; + } + } + + info!("Process all local timeouts"); + for node in nodes.iter_mut() { + info!("Timeouts on {}", node.id); + for i in 0..timeout_votes { + info!("Timeout {} on {}", i, node.id); + if node.id == forking_node && (2..4).contains(&i) { + info!("Got {}", node.next_commit_decision().await); + } + + let vote_msg_on_timeout = node.next_vote().await; + assert!(vote_msg_on_timeout.vote().is_timeout()); + if node.id != behind_node { + let result = node + .round_manager + .process_vote_msg(vote_msg_on_timeout) + .await; + + if node.id == forking_node && i == 2 { + result.unwrap_err(); + } else { + result.unwrap(); + } + } + } + } + }); + + timed_block_on(&runtime, async { + for node in nodes.iter_mut() { + let vote_msg_on_timeout = node.next_vote().await; + assert!(vote_msg_on_timeout.vote().is_timeout()); + } + + info!("Got {}", nodes[forking_node].next_commit_decision().await); + }); + + info!("Create forked block"); + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node], + true, + Some(forking_node), + false, + 5, + 2, + 1, + ); + + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node, forking_node], + true, + None, + false, + 6, + 3, + 3, + ); + + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[behind_node, forking_node], + true, + None, + false, + 7, + 5, + 3, + ); + + let mut nodes = timed_block_on(&runtime, async { + let mut behind_node_obj = nodes.pop().unwrap(); + + // Drain the queue on other nodes + let mut proposals = Vec::new(); + for node in nodes.iter_mut() { + proposals.push(node.next_proposal().await); + } + + info!( + "Processing proposals for behind node {}", + behind_node_obj.identity_desc() + ); + let handle = start_replying_to_block_retreival(nodes); + let proposal_msg = behind_node_obj.next_proposal().await; + behind_node_obj + .round_manager + .process_proposal_msg(proposal_msg.clone()) + .await + .unwrap(); + + nodes = handle.join().await; + behind_node_obj.no_next_msg(); + + for (proposal, node) in proposals.into_iter().zip(nodes.iter_mut()) { + node.pending_network_events.push(Event::Message( + node.signer.author(), + ConsensusMsg::ProposalMsg(Box::new(proposal)), + )); + } + behind_node_obj.pending_network_events.push(Event::Message( + behind_node_obj.signer.author(), + ConsensusMsg::ProposalMsg(Box::new(proposal_msg)), + )); + + nodes.push(behind_node_obj); + nodes + }); + + // confirm behind node can participate in consensus after state sync + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[forking_node, behind_node], + true, + None, + false, + 8, + 6, + 3, + ); + + // let next_message = timed_block_on(&runtime, nodes[proposal_node].next_network_message()); + // match next_message { + // ConsensusMsg::VoteMsg(_) => info!("Skip extra vote msg"), + // ConsensusMsg::ProposalMsg(msg) => { + // // put the message back in the queue. + // // actual peer doesn't matter, it is ignored, so use self. + // let peer = nodes[proposal_node].signer.author(); + // nodes[proposal_node] + // .pending_network_events + // .push(Event::Message(peer, ConsensusMsg::ProposalMsg(msg))) + // }, + // _ => panic!("unexpected network message {:?}", next_message), + // } + process_and_vote_on_proposal( + &runtime, + &mut nodes, + proposal_node, + &[forking_node], + true, + None, + false, + 9, + 7, + 3, + ); +} diff --git a/consensus/src/round_manager_tests/mod.rs b/consensus/src/round_manager_tests/mod.rs new file mode 100644 index 00000000000..15b3d64229c --- /dev/null +++ b/consensus/src/round_manager_tests/mod.rs @@ -0,0 +1,761 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + block_storage::{pending_blocks::PendingBlocks, BlockStore}, + counters, + liveness::{ + proposal_generator::{ + ChainHealthBackoffConfig, PipelineBackpressureConfig, ProposalGenerator, + }, + proposer_election::ProposerElection, + rotating_proposer_election::RotatingProposer, + round_state::{ExponentialTimeInterval, RoundState}, + }, + metrics_safety_rules::MetricsSafetyRules, + network::{IncomingBlockRetrievalRequest, NetworkSender}, + network_interface::{CommitMessage, ConsensusMsg, ConsensusNetworkClient, DIRECT_SEND, RPC}, + network_tests::{NetworkPlayground, TwinId}, + payload_manager::{ + DirectMempoolPayloadManager, QuorumStorePayloadManager, TPayloadManager, + TQuorumStoreCommitNotifier, + }, + persistent_liveness_storage::RecoveryData, + pipeline::buffer_manager::OrderedBlocks, + quorum_store::batch_store::BatchReader, + round_manager::RoundManager, + test_utils::{ + mock_execution_client::MockExecutionClient, MockOptQSPayloadProvider, + MockPastProposalStatusTracker, MockPayloadManager, MockStorage, + }, + util::time_service::{ClockTimeService, TimeService}, +}; +use aptos_channels::{self, aptos_channel, message_queues::QueueStyle}; +use aptos_config::{ + config::{BlockTransactionFilterConfig, ConsensusConfig}, + network_id::{NetworkId, PeerNetworkId}, +}; +use aptos_consensus_types::{ + block_retrieval::BlockRetrievalRequest, + common::{Author, Round}, + opt_block_data::OptBlockData, + opt_proposal_msg::OptProposalMsg, + order_vote_msg::OrderVoteMsg, + pipeline::commit_decision::CommitDecision, + proof_of_store::BatchInfo, + proposal_msg::ProposalMsg, + round_timeout::RoundTimeoutMsg, + utils::PayloadTxnsSize, + vote_msg::VoteMsg, + wrapped_ledger_info::WrappedLedgerInfo, +}; +use aptos_crypto::HashValue; +use aptos_executor_types::ExecutorResult; +use aptos_infallible::Mutex; +use aptos_logger::prelude::info; +use aptos_network::{ + application::interface::NetworkClient, + peer_manager::{ConnectionRequestSender, PeerManagerRequestSender}, + protocols::{ + network, + network::{Event, NetworkEvents, NewNetworkEvents, NewNetworkSender}, + wire::handshake::v1::ProtocolIdSet, + }, + transport::ConnectionMetadata, + ProtocolId, +}; +use aptos_safety_rules::{PersistentSafetyStorage, SafetyRulesManager}; +use aptos_secure_storage::Storage; +use aptos_types::{ + epoch_state::EpochState, + ledger_info::LedgerInfo, + on_chain_config::{ + ConsensusAlgorithmConfig, OnChainConsensusConfig, OnChainJWKConsensusConfig, + OnChainRandomnessConfig, + }, + transaction::SignedTransaction, + validator_signer::ValidatorSigner, + validator_verifier::{random_validator_verifier, ValidatorVerifier}, + waypoint::Waypoint, + PeerId, +}; +use futures::{ + channel::mpsc, executor::block_on, future::Shared, stream::select, FutureExt, Stream, StreamExt, +}; +use maplit::hashmap; +use std::{ + collections::VecDeque, + future::Future, + iter::FromIterator, + pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, +}; +use tokio::{runtime::Handle, task::JoinHandle}; + +mod consensus_test; +mod opt_proposal_test; +mod txn_filter_proposal_test; +mod vtxn_on_proposal_test; + +fn config_with_round_timeout_msg_disabled() -> ConsensusConfig { + // Disable RoundTimeoutMsg to unless expliclity enabled. + ConsensusConfig { + enable_round_timeout_msg: false, + ..Default::default() + } +} + +fn start_replying_to_block_retreival(nodes: Vec) -> ReplyingRPCHandle { + let done = Arc::new(AtomicBool::new(false)); + let mut handles = Vec::new(); + for mut node in nodes.into_iter() { + let done_clone = done.clone(); + handles.push(tokio::spawn(async move { + while !done_clone.load(Ordering::Relaxed) { + info!("Asking for RPC request on {:?}", node.identity_desc()); + let maybe_request = node.poll_block_retrieval().await; + if let Some(request) = maybe_request { + info!( + "RPC request received: {:?} on {:?}", + request, + node.identity_desc() + ); + let wrapped_request = IncomingBlockRetrievalRequest { + req: request.req, + protocol: request.protocol, + response_sender: request.response_sender, + }; + node.block_store + .process_block_retrieval(wrapped_request) + .await + .unwrap(); + } else { + tokio::time::sleep(Duration::from_millis(50)).await; + } + } + node + })); + } + ReplyingRPCHandle { handles, done } +} + +struct ReplyingRPCHandle { + handles: Vec>, + done: Arc, +} + +impl ReplyingRPCHandle { + async fn join(self) -> Vec { + self.done.store(true, Ordering::Relaxed); + let mut result = Vec::new(); + for handle in self.handles.into_iter() { + result.push(handle.await.unwrap()); + } + info!( + "joined nodes in order: {:?}", + result.iter().map(|v| v.id).collect::>() + ); + result + } +} + +#[derive(Debug)] +pub enum ProposalMsgType { + Normal(ProposalMsg), + Optimistic(OptProposalMsg), +} + +/// Auxiliary struct that is setting up node environment for the test. +pub struct NodeSetup { + pub block_store: Arc, + round_manager: RoundManager, + storage: Arc, + signer: ValidatorSigner, + proposers: Vec, + safety_rules_manager: SafetyRulesManager, + pending_network_events: Vec>, + all_network_events: Box> + Send + Unpin>, + ordered_blocks_events: mpsc::UnboundedReceiver, + mock_execution_client: Arc, + _state_sync_receiver: mpsc::UnboundedReceiver>, + id: usize, + onchain_consensus_config: OnChainConsensusConfig, + block_txn_filter_config: BlockTransactionFilterConfig, + local_consensus_config: ConsensusConfig, + onchain_randomness_config: OnChainRandomnessConfig, + onchain_jwk_consensus_config: OnChainJWKConsensusConfig, + vote_queue: VecDeque, + order_vote_queue: VecDeque, + proposal_queue: VecDeque, + opt_proposal_queue: VecDeque, + round_timeout_queue: VecDeque, + commit_decision_queue: VecDeque, + processed_opt_proposal_rx: aptos_channels::UnboundedReceiver, + use_quorum_store_payloads: bool, +} + +impl NodeSetup { + fn create_round_state(time_service: Arc) -> RoundState { + let base_timeout = Duration::new(60, 0); + let time_interval = Box::new(ExponentialTimeInterval::fixed(base_timeout)); + let (round_timeout_sender, _) = aptos_channels::new_test(1_024); + RoundState::new(time_interval, time_service, round_timeout_sender) + } + + fn create_proposer_election(proposers: Vec) -> Arc { + Arc::new(RotatingProposer::new(proposers, 1)) + } + + fn create_nodes( + playground: &mut NetworkPlayground, + executor: Handle, + num_nodes: usize, + proposer_indices: Option>, + onchain_consensus_config: Option, + block_txn_filter_config: Option, + local_consensus_config: Option, + onchain_randomness_config: Option, + onchain_jwk_consensus_config: Option, + use_quorum_store_payloads: bool, + ) -> Vec { + Self::create_nodes_with_validator_set( + playground, + executor, + num_nodes, + proposer_indices, + onchain_consensus_config, + block_txn_filter_config, + local_consensus_config, + onchain_randomness_config, + onchain_jwk_consensus_config, + None, + use_quorum_store_payloads, + ) + } + + fn create_nodes_with_validator_set( + playground: &mut NetworkPlayground, + executor: Handle, + num_nodes: usize, + proposer_indices: Option>, + onchain_consensus_config: Option, + block_txn_filter_config: Option, + local_consensus_config: Option, + onchain_randomness_config: Option, + onchain_jwk_consensus_config: Option, + validator_set: Option<(Vec, ValidatorVerifier)>, + use_quorum_store_payloads: bool, + ) -> Vec { + let mut onchain_consensus_config = onchain_consensus_config.unwrap_or_default(); + // With order votes feature, the validators additionally send order votes. + // next_proposal and next_vote functions could potentially break because of it. + if let OnChainConsensusConfig::V4 { + alg: + ConsensusAlgorithmConfig::JolteonV2 { + main: _, + quorum_store_enabled: _, + order_vote_enabled, + }, + vtxn: _, + window_size: _, + } = &mut onchain_consensus_config + { + *order_vote_enabled = false; + } + let onchain_randomness_config = + onchain_randomness_config.unwrap_or_else(OnChainRandomnessConfig::default_if_missing); + let onchain_jwk_consensus_config = onchain_jwk_consensus_config + .unwrap_or_else(OnChainJWKConsensusConfig::default_if_missing); + let block_txn_filter_config = block_txn_filter_config.unwrap_or_default(); + let local_consensus_config = local_consensus_config.unwrap_or_default(); + let (signers, validators) = + validator_set.unwrap_or_else(|| random_validator_verifier(num_nodes, None, false)); + let proposers = proposer_indices + .unwrap_or_else(|| vec![0]) + .iter() + .map(|i| signers[*i].author()) + .collect::>(); + let validator_set = (&validators).into(); + let waypoint = + Waypoint::new_epoch_boundary(&LedgerInfo::mock_genesis(Some(validator_set))).unwrap(); + + let mut nodes = vec![]; + // pre-initialize the mapping to avoid race conditions (peer try to broadcast to someone not added yet) + let peers_and_metadata = playground.peer_protocols(); + for signer in signers.iter().take(num_nodes) { + let peer_id = signer.author(); + let mut conn_meta = ConnectionMetadata::mock(peer_id); + conn_meta.application_protocols = ProtocolIdSet::from_iter([ + ProtocolId::ConsensusDirectSendJson, + ProtocolId::ConsensusDirectSendBcs, + ProtocolId::ConsensusRpcBcs, + ]); + let peer_network_id = PeerNetworkId::new(NetworkId::Validator, peer_id); + peers_and_metadata + .insert_connection_metadata(peer_network_id, conn_meta) + .unwrap(); + } + for (id, signer) in signers.iter().take(num_nodes).enumerate() { + let (initial_data, storage) = MockStorage::start_for_testing((&validators).into()); + + let safety_storage = PersistentSafetyStorage::initialize( + Storage::from(aptos_secure_storage::InMemoryStorage::new()), + signer.author(), + signer.private_key().clone(), + waypoint, + true, + ); + let safety_rules_manager = SafetyRulesManager::new_local(safety_storage); + + nodes.push(Self::new( + playground, + executor.clone(), + signer.to_owned(), + proposers.clone(), + storage, + initial_data, + safety_rules_manager, + id, + onchain_consensus_config.clone(), + block_txn_filter_config.clone(), + local_consensus_config.clone(), + onchain_randomness_config.clone(), + onchain_jwk_consensus_config.clone(), + use_quorum_store_payloads, + )); + } + nodes + } + + fn new( + playground: &mut NetworkPlayground, + executor: Handle, + signer: ValidatorSigner, + proposers: Vec, + storage: Arc, + initial_data: RecoveryData, + safety_rules_manager: SafetyRulesManager, + id: usize, + onchain_consensus_config: OnChainConsensusConfig, + block_txn_filter_config: BlockTransactionFilterConfig, + local_consensus_config: ConsensusConfig, + onchain_randomness_config: OnChainRandomnessConfig, + onchain_jwk_consensus_config: OnChainJWKConsensusConfig, + use_quorum_store_payloads: bool, + ) -> Self { + let _entered_runtime = executor.enter(); + let epoch_state = Arc::new(EpochState::new(1, storage.get_validator_set().into())); + let validators = epoch_state.verifier.clone(); + let (network_reqs_tx, network_reqs_rx) = aptos_channel::new(QueueStyle::FIFO, 8, None); + let (connection_reqs_tx, _) = aptos_channel::new(QueueStyle::FIFO, 8, None); + let (consensus_tx, consensus_rx) = aptos_channel::new(QueueStyle::FIFO, 8, None); + let (_conn_mgr_reqs_tx, conn_mgr_reqs_rx) = aptos_channels::new_test(8); + let network_sender = network::NetworkSender::new( + PeerManagerRequestSender::new(network_reqs_tx), + ConnectionRequestSender::new(connection_reqs_tx), + ); + let network_client = NetworkClient::new( + DIRECT_SEND.into(), + RPC.into(), + hashmap! {NetworkId::Validator => network_sender}, + playground.peer_protocols(), + ); + let consensus_network_client = ConsensusNetworkClient::new(network_client); + let network_events = NetworkEvents::new(consensus_rx, None, true); + let author = signer.author(); + + let twin_id = TwinId { id, author }; + + playground.add_node(twin_id, consensus_tx, network_reqs_rx, conn_mgr_reqs_rx); + + let (self_sender, self_receiver) = aptos_channels::new_unbounded_test(); + let network = Arc::new(NetworkSender::new( + author, + consensus_network_client, + self_sender, + validators, + )); + + let all_network_events = Box::new(select(network_events, self_receiver)); + + let last_vote_sent = initial_data.last_vote(); + let (ordered_blocks_tx, ordered_blocks_events) = mpsc::unbounded::(); + let (state_sync_client, _state_sync_receiver) = mpsc::unbounded(); + let mock_execution_client = Arc::new(MockExecutionClient::new( + state_sync_client.clone(), + ordered_blocks_tx.clone(), + Arc::clone(&storage), + )); + let time_service = Arc::new(ClockTimeService::new(executor)); + + let payload_manager: Arc = if use_quorum_store_payloads { + Arc::new(QuorumStorePayloadManager::new( + Arc::new(MockBatchReader) as Arc, + Box::new(MockQuorumStoreCommitNotifier) as Box, + None, + vec![], + hashmap![], + false, + )) + } else { + Arc::new(DirectMempoolPayloadManager::new()) + }; + + let window_size = onchain_consensus_config.window_size(); + let block_store = Arc::new(BlockStore::new( + storage.clone(), + initial_data, + mock_execution_client.clone(), + 10, // max pruned blocks in mem + time_service.clone(), + 10, + payload_manager, + false, + window_size, + Arc::new(Mutex::new(PendingBlocks::new())), + None, + )); + let block_store_clone = Arc::clone(&block_store); + let callback = Box::new( + move |block_id: HashValue, block_round: Round, commit_proof: WrappedLedgerInfo| { + block_store_clone.commit_callback(block_id, block_round, commit_proof, None) + }, + ); + mock_execution_client.set_callback(callback); + + let proposer_election = Self::create_proposer_election(proposers.clone()); + let proposal_generator = ProposalGenerator::new( + author, + block_store.clone(), + Arc::new(MockPayloadManager::new(None)), + time_service.clone(), + Duration::ZERO, + PayloadTxnsSize::new(20, 1000), + 10, + PayloadTxnsSize::new(5, 500), + 10, + 1, + Some(30_000), + PipelineBackpressureConfig::new_no_backoff(), + ChainHealthBackoffConfig::new_no_backoff(), + false, + onchain_consensus_config.effective_validator_txn_config(), + true, + Arc::new(MockOptQSPayloadProvider {}), + ); + + let round_state = Self::create_round_state(time_service); + let mut safety_rules = + MetricsSafetyRules::new(safety_rules_manager.client(), storage.clone()); + safety_rules.perform_initialize().unwrap(); + + let (round_manager_tx, _) = aptos_channel::new(QueueStyle::LIFO, 1, None); + + let (opt_proposal_loopback_tx, opt_proposal_loopback_rx) = aptos_channels::new_unbounded( + &counters::OP_COUNTERS.gauge("opt_proposal_loopback_queue"), + ); + + let local_config = local_consensus_config.clone(); + + let mut round_manager = RoundManager::new( + epoch_state, + Arc::clone(&block_store), + round_state, + proposer_election, + proposal_generator, + Arc::new(Mutex::new(safety_rules)), + network, + storage.clone(), + onchain_consensus_config.clone(), + round_manager_tx, + block_txn_filter_config.clone(), + local_config, + onchain_randomness_config.clone(), + onchain_jwk_consensus_config.clone(), + None, + Arc::new(MockPastProposalStatusTracker {}), + opt_proposal_loopback_tx, + ); + block_on(round_manager.init(last_vote_sent)); + Self { + block_store, + round_manager, + storage, + signer, + proposers, + safety_rules_manager, + pending_network_events: Vec::new(), + all_network_events, + ordered_blocks_events, + mock_execution_client, + _state_sync_receiver, + id, + onchain_consensus_config, + block_txn_filter_config, + local_consensus_config, + onchain_randomness_config, + onchain_jwk_consensus_config, + vote_queue: VecDeque::new(), + order_vote_queue: VecDeque::new(), + proposal_queue: VecDeque::new(), + opt_proposal_queue: VecDeque::new(), + round_timeout_queue: VecDeque::new(), + commit_decision_queue: VecDeque::new(), + processed_opt_proposal_rx: opt_proposal_loopback_rx, + use_quorum_store_payloads, + } + } + + pub fn restart(self, playground: &mut NetworkPlayground, executor: Handle) -> Self { + let recover_data = self + .storage + .try_start( + self.onchain_consensus_config.order_vote_enabled(), + self.onchain_consensus_config.window_size(), + ) + .unwrap_or_else(|e| panic!("fail to restart due to: {}", e)); + Self::new( + playground, + executor, + self.signer, + self.proposers, + self.storage, + recover_data, + self.safety_rules_manager, + self.id, + self.onchain_consensus_config.clone(), + self.block_txn_filter_config.clone(), + self.local_consensus_config.clone(), + self.onchain_randomness_config.clone(), + self.onchain_jwk_consensus_config.clone(), + self.use_quorum_store_payloads, + ) + } + + pub fn identity_desc(&self) -> String { + format!("{} [{}]", self.id, self.signer.author()) + } + + fn poll_next_network_event(&mut self) -> Option> { + if !self.pending_network_events.is_empty() { + Some(self.pending_network_events.remove(0)) + } else { + self.all_network_events + .next() + .now_or_never() + .map(|v| v.unwrap()) + } + } + + pub async fn next_network_event(&mut self) -> Event { + if !self.pending_network_events.is_empty() { + self.pending_network_events.remove(0) + } else { + self.all_network_events.next().await.unwrap() + } + } + + pub async fn next_network_message(&mut self) { + let consensus_msg = match self.next_network_event().await { + Event::Message(_, msg) => msg, + Event::RpcRequest(_, msg, _, _) if matches!(msg, ConsensusMsg::CommitMessage(_)) => msg, + Event::RpcRequest(_, msg, _, _) => { + panic!( + "Unexpected event, got RpcRequest, expected Message: {:?} on node {}", + msg, + self.identity_desc() + ) + }, + }; + + match consensus_msg { + ConsensusMsg::ProposalMsg(proposal) => { + self.proposal_queue.push_back(*proposal); + }, + ConsensusMsg::OptProposalMsg(opt_proposal) => { + self.opt_proposal_queue.push_back(*opt_proposal); + }, + ConsensusMsg::VoteMsg(vote) => { + self.vote_queue.push_back(*vote); + }, + ConsensusMsg::OrderVoteMsg(order_vote) => { + self.order_vote_queue.push_back(*order_vote); + }, + ConsensusMsg::RoundTimeoutMsg(round_timeout) => { + self.round_timeout_queue.push_back(*round_timeout); + }, + ConsensusMsg::CommitDecisionMsg(commit_decision) => { + self.commit_decision_queue.push_back(*commit_decision); + }, + ConsensusMsg::CommitMessage(d) if matches!(*d, CommitMessage::Decision(_)) => { + match *d { + CommitMessage::Decision(commit_decision) => { + self.commit_decision_queue.push_back(commit_decision); + }, + _ => unreachable!(), + } + }, + msg => panic!( + "Unexpected Consensus Message: {:?} on node {}", + msg, + self.identity_desc() + ), + } + } + + pub fn no_next_msg(&mut self) { + match self.poll_next_network_event() { + Some(Event::RpcRequest(_, msg, _, _)) | Some(Event::Message(_, msg)) => panic!( + "Unexpected Consensus Message: {:?} on node {}", + msg, + self.identity_desc() + ), + None => {}, + } + } + + pub async fn next_proposal(&mut self) -> ProposalMsg { + while self.proposal_queue.is_empty() { + self.next_network_message().await; + } + self.proposal_queue.pop_front().unwrap() + } + + pub async fn next_opt_proposal(&mut self) -> OptProposalMsg { + while self.opt_proposal_queue.is_empty() { + self.next_network_message().await; + } + self.opt_proposal_queue.pop_front().unwrap() + } + + pub async fn next_opt_or_normal_proposal(&mut self) -> ProposalMsgType { + while self.opt_proposal_queue.is_empty() && self.proposal_queue.is_empty() { + self.next_network_message().await; + } + + if !self.opt_proposal_queue.is_empty() { + return ProposalMsgType::Optimistic(self.opt_proposal_queue.pop_front().unwrap()); + } + + ProposalMsgType::Normal(self.proposal_queue.pop_front().unwrap()) + } + + pub async fn next_vote(&mut self) -> VoteMsg { + while self.vote_queue.is_empty() { + self.next_network_message().await; + } + self.vote_queue.pop_front().unwrap() + } + + #[allow(unused)] + pub async fn next_order_vote(&mut self) -> OrderVoteMsg { + while self.order_vote_queue.is_empty() { + self.next_network_message().await; + } + self.order_vote_queue.pop_front().unwrap() + } + + pub async fn next_timeout(&mut self) -> RoundTimeoutMsg { + while self.round_timeout_queue.is_empty() { + self.next_network_message().await; + } + self.round_timeout_queue.pop_front().unwrap() + } + + pub async fn next_commit_decision(&mut self) -> CommitDecision { + while self.commit_decision_queue.is_empty() { + self.next_network_message().await; + } + self.commit_decision_queue.pop_front().unwrap() + } + + pub async fn poll_block_retrieval(&mut self) -> Option { + match self.poll_next_network_event() { + Some(Event::RpcRequest(_, msg, protocol, response_sender)) => match msg { + ConsensusMsg::DeprecatedBlockRetrievalRequest(v) => { + Some(IncomingBlockRetrievalRequest { + req: BlockRetrievalRequest::V1(*v), + protocol, + response_sender, + }) + }, + ConsensusMsg::BlockRetrievalRequest(v) => Some(IncomingBlockRetrievalRequest { + req: *v, + protocol, + response_sender, + }), + msg => panic!( + "Unexpected Consensus Message: {:?} on node {}", + msg, + self.identity_desc() + ), + }, + Some(Event::Message(_, msg)) => panic!( + "Unexpected Consensus Message: {:?} on node {}", + msg, + self.identity_desc() + ), + None => None, + } + } + + pub fn no_next_ordered(&mut self) { + if self.ordered_blocks_events.next().now_or_never().is_some() { + panic!("Unexpected Ordered Blocks Event"); + } + } + + pub async fn commit_next_ordered(&mut self, expected_rounds: &[Round]) { + info!( + "Starting commit_next_ordered to wait for {:?} on node {:?}", + expected_rounds, + self.identity_desc() + ); + let ordered_blocks = self.ordered_blocks_events.next().await.unwrap(); + let rounds = ordered_blocks + .ordered_blocks + .iter() + .map(|b| b.round()) + .collect::>(); + assert_eq!(&rounds, expected_rounds); + self.mock_execution_client + .commit_to_storage(ordered_blocks) + .await + .unwrap(); + } +} + +/// A mock quorum store commit notifier that provides limited functionality +struct MockQuorumStoreCommitNotifier; + +impl TQuorumStoreCommitNotifier for MockQuorumStoreCommitNotifier { + fn notify(&self, _block_timestamp: u64, _batches: Vec) { + unimplemented!() + } +} + +/// A mock batch reader that provides limited functionality +struct MockBatchReader; + +impl BatchReader for MockBatchReader { + fn exists(&self, _digest: &HashValue) -> Option { + None + } + + fn get_batch( + &self, + _batch_info: BatchInfo, + _signers: Vec, + ) -> Shared>> + Send>>> { + unimplemented!() + } + + fn update_certified_timestamp(&self, _certified_time: u64) { + unimplemented!() + } +} diff --git a/consensus/src/round_manager_tests/opt_proposal_test.rs b/consensus/src/round_manager_tests/opt_proposal_test.rs new file mode 100644 index 00000000000..9a86a2a64a5 --- /dev/null +++ b/consensus/src/round_manager_tests/opt_proposal_test.rs @@ -0,0 +1,317 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + block_storage::BlockReader, + liveness::round_state::{NewRoundEvent, NewRoundReason}, + network_tests::NetworkPlayground, + round_manager::{ + round_manager_tests::{ + consensus_test::{process_and_vote_on_proposal, process_and_vote_opt_proposal}, + NodeSetup, + }, + RoundManager, + }, + test_utils::{consensus_runtime, timed_block_on}, +}; +use aptos_config::config::ConsensusConfig; +use aptos_consensus_types::{ + common::Payload, opt_block_data::OptBlockData, opt_proposal_msg::OptProposalMsg, +}; +use futures::StreamExt; + +fn config_with_opt_proposal_enabled() -> ConsensusConfig { + ConsensusConfig { + enable_optimistic_proposal_rx: true, + enable_optimistic_proposal_tx: true, + ..Default::default() + } +} + +/// Asserts that optimistic proposal is proposed and votes for rounds 2 to n +/// in the absence of failures +#[test] +fn test_opt_proposal_proposed_no_failures() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_opt_proposal_enabled()), + None, + None, + false, + ); + let genesis = nodes[0].block_store.ordered_root(); + + // Process and vote on a normal proposal for round 1 + process_and_vote_on_proposal(&runtime, &mut nodes, 0, &[], true, Some(0), true, 1, 0, 0); + + let node = &mut nodes[0]; + let mut expected_grandparent_qc = genesis.id(); + for round in 2..10 { + let opt_proposal_msg = timed_block_on(&runtime, async { node.next_opt_proposal().await }); + assert_eq!(opt_proposal_msg.round(), round); + assert_eq!( + opt_proposal_msg + .block_data() + .grandparent_qc() + .certified_block() + .id(), + expected_grandparent_qc + ); + expected_grandparent_qc = opt_proposal_msg.block_data().parent_id(); + // process and vote on the optimistic proposal only + process_and_vote_opt_proposal( + &runtime, + node, + opt_proposal_msg, + round, + round.saturating_sub(2), + 0, + ); + // process vote to gather QC and enter the next round + timed_block_on(&runtime, async { + let vote_msg = node.next_vote().await; + // Adding vote to form a QC + node.round_manager.process_vote_msg(vote_msg).await.unwrap(); + }); + } +} + +/// Asserts that two consecutive opt-proposal rounds timeout and that +/// the round after the timeout rounds is always a normal round. +#[test] +fn test_normal_proposal_after_opt_proposal_timeout() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_opt_proposal_enabled()), + None, + None, + false, + ); + let genesis = nodes[0].block_store.ordered_root(); + + // Process and vote on a normal proposal for round 1 + process_and_vote_on_proposal(&runtime, &mut nodes, 0, &[], true, Some(0), true, 1, 0, 0); + + let node = &mut nodes[0]; + let expected_grandparent_qc = genesis.id(); + + let round = 2; + let opt_proposal_msg = timed_block_on(&runtime, async { node.next_opt_proposal().await }); + assert_eq!(opt_proposal_msg.round(), round); + assert_eq!( + opt_proposal_msg + .block_data() + .grandparent_qc() + .certified_block() + .id(), + expected_grandparent_qc + ); + // process and vote on the optimistic proposal only + process_and_vote_opt_proposal( + &runtime, + node, + opt_proposal_msg, + round, + round.saturating_sub(2), + 0, + ); + + timed_block_on(&runtime, async { + // process round 2 timeout. + let round = 2; + node.round_manager + .process_local_timeout(round) + .await + .unwrap_err(); + let timeout_msg = node.next_timeout().await; + node.round_manager + .process_round_timeout_msg(timeout_msg) + .await + .unwrap(); + + // process round 3 timeout. + let round = 3; + node.round_manager + .process_local_timeout(round) + .await + .unwrap_err(); + let timeout_msg = node.next_timeout().await; + node.round_manager + .process_round_timeout_msg(timeout_msg) + .await + .unwrap(); + + node.next_proposal().await; + }); +} + +/// Asserts that either optimistic proposal or a normal proposal can be +/// created in a given round and not both. +#[test] +fn test_one_proposal_per_round_honest_proposer() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_opt_proposal_enabled()), + None, + None, + false, + ); + let genesis = nodes[0].block_store.ordered_root(); + let node = &mut nodes[0]; + + timed_block_on(&runtime, async { + let round_manager = &node.round_manager; + let epoch_state = round_manager.epoch_state.clone(); + let network = round_manager.network.clone(); + let sync_info = round_manager.block_store.sync_info(); + let proposal_generator = round_manager.proposal_generator.clone(); + let proposer_election = round_manager.proposer_election.clone(); + let safety_rules = round_manager.safety_rules.clone(); + + // Ensure that an opt proposal cannot be created + RoundManager::generate_and_send_opt_proposal( + epoch_state.clone(), + 1, + genesis.block_info(), + genesis.quorum_cert().clone(), + network.clone(), + sync_info.clone(), + proposal_generator.clone(), + proposer_election.clone(), + ) + .await + .unwrap_err(); + + // Ensure an opt proposal can be created. + RoundManager::generate_and_send_opt_proposal( + epoch_state.clone(), + 2, + genesis.block_info(), + genesis.quorum_cert().clone(), + network.clone(), + sync_info.clone(), + proposal_generator.clone(), + proposer_election.clone(), + ) + .await + .unwrap(); + + // Ensure a proposal cannot be created after an opt proposal in same round + let new_round_event = NewRoundEvent { + round: 2, + reason: NewRoundReason::QCReady, + timeout: Default::default(), + prev_round_votes: vec![], + prev_round_timeout_votes: None, + }; + RoundManager::generate_and_send_proposal( + epoch_state.clone(), + new_round_event, + network.clone(), + sync_info.clone(), + proposal_generator.clone(), + safety_rules.clone(), + proposer_election.clone(), + ) + .await + .unwrap_err(); + + // Ensure a proposal can be created if opt proposal is not + let new_round_event = NewRoundEvent { + round: 3, + reason: NewRoundReason::QCReady, + timeout: Default::default(), + prev_round_votes: vec![], + prev_round_timeout_votes: None, + }; + RoundManager::generate_and_send_proposal( + epoch_state, + new_round_event, + network, + sync_info, + proposal_generator, + safety_rules, + proposer_election, + ) + .await + .unwrap(); + }); +} + +/// Don't process an optimistic proposal if a normal proposal is processed. +#[test] +fn test_process_either_optimistic_or_normal_proposal() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + Some(config_with_opt_proposal_enabled()), + None, + None, + false, + ); + let genesis = nodes[0].block_store.ordered_root(); + let node = &mut nodes[0]; + + timed_block_on(&runtime, async { + let proposal_msg = node.next_proposal().await; + node.round_manager + .process_proposal_msg(proposal_msg.clone()) + .await + .unwrap(); + + let opt_block_data = OptBlockData::new( + Vec::new(), + Payload::empty(false, false), + proposal_msg.proposer(), + proposal_msg.proposal().epoch(), + proposal_msg.proposal().round(), + proposal_msg.proposal().timestamp_usecs(), + proposal_msg.proposal().quorum_cert().parent_block().clone(), + genesis.quorum_cert().clone(), + ); + let opt_proposal_msg = + OptProposalMsg::new(opt_block_data, proposal_msg.sync_info().clone()); + node.round_manager + .process_opt_proposal_msg(opt_proposal_msg) + .await + .unwrap(); + let opt_block_data = node.processed_opt_proposal_rx.next().await.unwrap(); + + let error = node + .round_manager + .process_opt_proposal(opt_block_data) + .await + .unwrap_err(); + assert_eq!( + error.to_string(), + "Proposal has already been processed for round: 1" + ); + }) +} diff --git a/consensus/src/round_manager_tests/txn_filter_proposal_test.rs b/consensus/src/round_manager_tests/txn_filter_proposal_test.rs new file mode 100644 index 00000000000..1965f054459 --- /dev/null +++ b/consensus/src/round_manager_tests/txn_filter_proposal_test.rs @@ -0,0 +1,277 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + network_tests::NetworkPlayground, + round_manager::round_manager_tests::NodeSetup, + test_utils::{consensus_runtime, timed_block_on}, +}; +use aptos_config::config::BlockTransactionFilterConfig; +use aptos_consensus_types::{ + block::{block_test_utils::certificate_for_genesis, Block}, + common::{Payload, ProofWithData}, + proof_of_store::BatchInfo, +}; +use aptos_crypto::{ + ed25519::{Ed25519PrivateKey, Ed25519Signature}, + HashValue, PrivateKey, Uniform, +}; +use aptos_transaction_filters::{ + block_transaction_filter::{BlockTransactionFilter, BlockTransactionMatcher}, + transaction_filter::TransactionMatcher, +}; +use aptos_types::{ + account_address::AccountAddress, + chain_id::ChainId, + quorum_store::BatchId, + transaction::{RawTransaction, Script, SignedTransaction, TransactionPayload}, + PeerId, +}; + +// Verify that the round manager will not vote if a block +// proposal contains any denied inline transactions. +#[test] +fn test_no_vote_on_denied_inline_transactions() { + // Test both direct mempool and quorum store payloads + for use_quorum_store_payloads in [false, true] { + // Create test transactions + let transactions = create_test_transactions(); + + // Create a block filter config that denies the first transaction sender + let block_txn_filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[0].sender()), + )]) + .add_all_filter(true); + let block_txn_filter_config = BlockTransactionFilterConfig::new(true, block_txn_filter); + + // Create a new network playground + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + + // Create a new consensus node. Note: To observe the votes we're + // going to check proposal processing on the non-proposer node + // (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + Some(block_txn_filter_config), + None, + None, + None, + use_quorum_store_payloads, + ); + let node = &mut nodes[0]; + + // Create a block proposal with inline transactions that will be denied + let payload = create_payload(transactions, use_quorum_store_payloads); + let denied_block = Block::new_proposal( + payload, + 1, + 1, + certificate_for_genesis(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + // Verify that the node does not vote on a block with denied inline transactions + timed_block_on(&runtime, async { + assert!(node + .round_manager + .process_proposal(denied_block) + .await + .is_err()); + }); + } +} + +// Verify that the round manager will not invoke +// the filter if the config is disabled. +#[test] +fn test_vote_on_disabled_filter() { + // Test both direct mempool and quorum store payloads + for use_quorum_store_payloads in [false, true] { + // Create a block filter config that denies all transactions, however, + // the filter is disabled, so it should not be invoked. + let block_txn_filter = BlockTransactionFilter::empty().add_all_filter(false); + let block_txn_filter_config = BlockTransactionFilterConfig::new(false, block_txn_filter); + + // Create a new network playground + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + + // Create a new consensus node. Note: To observe the votes we're + // going to check proposal processing on the non-proposer node + // (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + Some(block_txn_filter_config), + None, + None, + None, + use_quorum_store_payloads, + ); + let node = &mut nodes[0]; + + // Create a block proposal with inline transactions + let transactions = create_test_transactions(); + let payload = create_payload(transactions, use_quorum_store_payloads); + let allowed_block = Block::new_proposal( + payload, + 1, + 1, + certificate_for_genesis(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let allowed_block_id = allowed_block.id(); + + // Verify that the node votes on the block correctly + timed_block_on(&runtime, async { + node.round_manager + .process_proposal(allowed_block) + .await + .unwrap(); + let vote_msg = node.next_vote().await; + assert_eq!( + vote_msg.vote().vote_data().proposed().id(), + allowed_block_id + ); + }); + } +} + +// Verify that the round manager will still vote on a block +// if there are no denied inline transactions that match. +#[test] +fn test_vote_on_no_filter_matches() { + // Test both direct mempool and quorum store payloads + for use_quorum_store_payloads in [false, true] { + // Create test transactions + let transactions = create_test_transactions(); + + // Create a block filter config that denies the first transaction sender + let block_txn_filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[0].sender()), + )]) + .add_all_filter(true); + let block_txn_filter_config = BlockTransactionFilterConfig::new(true, block_txn_filter); + + // Create a new network playground + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + + // Create a new consensus node. Note: To observe the votes we're + // going to check proposal processing on the non-proposer node + // (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + Some(block_txn_filter_config), + None, + None, + None, + use_quorum_store_payloads, + ); + let node = &mut nodes[0]; + + // Create a block proposal with inline transactions that don't include the denied sender + let payload = create_payload(transactions[1..].to_vec(), use_quorum_store_payloads); + let allowed_block = Block::new_proposal( + payload, + 1, + 1, + certificate_for_genesis(), + &node.signer, + Vec::new(), + ) + .unwrap(); + let allowed_block_id = allowed_block.id(); + + // Verify that the node votes on the block correctly + timed_block_on(&runtime, async { + node.round_manager + .process_proposal(allowed_block) + .await + .unwrap(); + let vote_msg = node.next_vote().await; + assert_eq!( + vote_msg.vote().vote_data().proposed().id(), + allowed_block_id + ); + }); + } +} + +/// Creates and returns a new batch info with the specified number of transactions +fn create_batch_info(num_transactions: usize) -> BatchInfo { + BatchInfo::new( + PeerId::ZERO, + BatchId::new(0), + 1, + 0, + HashValue::random(), + num_transactions as u64, + 1, + 0, + ) +} + +/// Creates and returns a payload based on the provided transactions and whether to use QS +fn create_payload( + transactions: Vec, + use_quorum_store_payloads: bool, +) -> Payload { + if use_quorum_store_payloads { + let inline_batch = (create_batch_info(transactions.len()), transactions); + Payload::QuorumStoreInlineHybrid(vec![inline_batch], ProofWithData::empty(), None) + } else { + Payload::DirectMempool(transactions) + } +} + +/// Creates and returns a list of test transactions +fn create_test_transactions() -> Vec { + let mut transactions = vec![]; + + for i in 0..10 { + // Create the raw transaction + let transaction_payload = TransactionPayload::Script(Script::new(vec![], vec![], vec![])); + let raw_transaction = RawTransaction::new( + AccountAddress::random(), + i, + transaction_payload, + 0, + 0, + 0, + ChainId::new(10), + ); + + // Create a signed transaction + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = private_key.public_key(); + let signed_transaction = SignedTransaction::new( + raw_transaction, + public_key, + Ed25519Signature::dummy_signature(), + ); + + // Add the signed transaction to the list + transactions.push(signed_transaction); + } + + transactions +} diff --git a/consensus/src/round_manager_tests/vtxn_on_proposal_test.rs b/consensus/src/round_manager_tests/vtxn_on_proposal_test.rs new file mode 100644 index 00000000000..53e185b6b69 --- /dev/null +++ b/consensus/src/round_manager_tests/vtxn_on_proposal_test.rs @@ -0,0 +1,401 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 +// Parts of the project are originally copyright © Meta Platforms, Inc. + +use crate::{ + network_tests::NetworkPlayground, + round_manager::round_manager_tests::NodeSetup, + test_utils::{consensus_runtime, create_vec_signed_transactions, timed_block_on}, +}; +use aptos_config::config::ConsensusConfig; +use aptos_consensus_types::{ + block::{block_test_utils::certificate_for_genesis, Block}, + common::Payload, +}; +use aptos_types::{ + dkg::{real_dkg::RealDKG, DKGSessionMetadata, DKGTrait, DKGTranscript}, + jwks::QuorumCertifiedUpdate, + on_chain_config::{ + ConsensusAlgorithmConfig, ConsensusConfigV1, OnChainConsensusConfig, + OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, + ValidatorTxnConfig, DEFAULT_WINDOW_SIZE, + }, + validator_signer::ValidatorSigner, + validator_txn::ValidatorTransaction, + validator_verifier::{ + random_validator_verifier_with_voting_power, ValidatorConsensusInfoMoveStruct, + ValidatorVerifier, + }, +}; +use rand::{rngs::ThreadRng, thread_rng}; + +#[test] +/// If ProposalExt feature is disabled, ProposalExt should be rejected +/// No votes are sent, but the block is still added to the block tree. +fn no_vote_on_proposal_ext_when_feature_disabled() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + // In order to observe the votes we're going to check proposal processing on the non-proposer + // node (which will send the votes to the proposer). + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + None, + None, + None, + None, + None, + false, + ); + let node = &mut nodes[0]; + let genesis_qc = certificate_for_genesis(); + + let invalid_block = Block::new_proposal_ext( + vec![ValidatorTransaction::dummy(vec![0xFF]); 5], + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + let valid_block = Block::new_proposal( + Payload::empty(false, true), + 1, + 1, + genesis_qc, + &node.signer, + Vec::new(), + ) + .unwrap(); + + timed_block_on(&runtime, async { + // clear the message queue + node.next_proposal().await; + + assert!(node + .round_manager + .process_proposal(invalid_block) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal(valid_block) + .await + .is_ok()); + }); +} + +#[test] +fn no_vote_on_proposal_with_unexpected_vtxns() { + let vtxns = vec![ValidatorTransaction::ObservedJWKUpdate( + QuorumCertifiedUpdate::dummy(), + )]; + + assert_process_proposal_result( + None, + None, + Some(OnChainJWKConsensusConfig::default_disabled()), + vtxns.clone(), + false, + ); + + assert_process_proposal_result( + None, + None, + Some(OnChainJWKConsensusConfig::default_enabled()), + vtxns, + true, + ); +} + +#[test] +fn no_vote_on_proposal_with_uncertified_dkg_result() { + test_dkg_result_handling( + &[25_000_000; 4], + 1, + RealDKG::sample_secret_and_generate_transcript, + false, + ); +} + +#[test] +fn no_vote_on_proposal_with_inconsistent_secret_dkg_result() { + test_dkg_result_handling( + &[10_000_000, 70_000_000, 10_000_000, 10_000_000], + 1, + RealDKG::generate_transcript_for_inconsistent_secrets, + false, + ); +} + +#[test] +fn no_vote_on_proposal_with_dup_dealers_in_dkg_transcript() { + test_dkg_result_handling( + &[10_000_000, 40_000_000, 10_000_000, 40_000_000], + 1, + RealDKG::deal_twice_and_aggregate, + false, + ); +} + +#[test] +fn vote_on_proposal_with_valid_dkg_result() { + test_dkg_result_handling( + &[10_000_000, 70_000_000, 10_000_000, 10_000_000], + 1, + RealDKG::sample_secret_and_generate_transcript, + true, + ); +} + +fn test_dkg_result_handling( + voting_powers: &[u64], + dealer_idx: usize, + trx_gen_func: F, + should_accept: bool, +) where + F: Fn( + &mut ThreadRng, + &::PublicParams, + u64, + &::DealerPrivateKey, + &::DealerPublicKey, + ) -> ::Transcript, +{ + let mut rng = thread_rng(); + let epoch = 123; + let num_validators = voting_powers.len(); + let (signers, verifier) = + random_validator_verifier_with_voting_power(num_validators, None, false, voting_powers); + let validator_set: Vec = verifier + .validator_infos + .clone() + .into_iter() + .map(ValidatorConsensusInfoMoveStruct::from) + .collect(); + + let dkg_session_metadata = DKGSessionMetadata { + dealer_epoch: epoch, + randomness_config: RandomnessConfigMoveStruct::from( + OnChainRandomnessConfig::default_enabled(), + ), + dealer_validator_set: validator_set.clone(), + target_validator_set: validator_set, + }; + let public_params = RealDKG::new_public_params(&dkg_session_metadata); + let trx = trx_gen_func( + &mut rng, + &public_params, + dealer_idx as u64, + signers[dealer_idx].private_key(), + &signers[dealer_idx].public_key(), + ); + let trx_bytes = bcs::to_bytes(&trx).unwrap(); + let vtxns = vec![ValidatorTransaction::DKGResult(DKGTranscript::new( + epoch, + verifier.get_ordered_account_addresses()[dealer_idx], + trx_bytes, + ))]; + + assert_process_proposal_result( + Some((signers, verifier)), + Some(OnChainRandomnessConfig::default_enabled()), + Some(OnChainJWKConsensusConfig::default_enabled()), + vtxns.clone(), + should_accept, + ); +} + +/// Setup a node with default configs and an optional `Features` override. +/// Create a block, fill it with the given vtxns, and process it with the `RoundManager` from the setup. +/// Assert the processing result. +fn assert_process_proposal_result( + validator_set: Option<(Vec, ValidatorVerifier)>, + randomness_config: Option, + jwk_consensus_config: Option, + vtxns: Vec, + expected_result: bool, +) { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + let mut nodes = NodeSetup::create_nodes_with_validator_set( + &mut playground, + runtime.handle().clone(), + 1, + None, + Some(OnChainConsensusConfig::default_for_genesis()), + None, + None, + randomness_config, + jwk_consensus_config, + validator_set, + false, + ); + + let node = &mut nodes[0]; + let genesis_qc = certificate_for_genesis(); + let block = Block::new_proposal_ext( + vtxns, + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + timed_block_on(&runtime, async { + // clear the message queue + node.next_proposal().await; + + assert_eq!( + expected_result, + node.round_manager + .process_proposal(block.clone()) + .await + .is_ok() + ); + }); +} + +#[ignore] +#[test] +/// If receiving txn num/block size limit is exceeded, ProposalExt should be rejected. +/// TODO: re-implement dummy vtxn and re-enable. +fn no_vote_on_proposal_ext_when_receiving_limit_exceeded() { + let runtime = consensus_runtime(); + let mut playground = NetworkPlayground::new(runtime.handle().clone()); + + let alg_config = ConsensusAlgorithmConfig::JolteonV2 { + main: ConsensusConfigV1::default(), + quorum_store_enabled: true, + order_vote_enabled: false, + }; + let vtxn_config = ValidatorTxnConfig::V1 { + per_block_limit_txn_count: 5, + per_block_limit_total_bytes: 400, + }; + + let local_config = ConsensusConfig { + max_receiving_block_txns: 10, + max_receiving_block_bytes: 800, + ..Default::default() + }; + + let randomness_config = OnChainRandomnessConfig::default_enabled(); + let mut nodes = NodeSetup::create_nodes( + &mut playground, + runtime.handle().clone(), + 1, + None, + Some(OnChainConsensusConfig::V4 { + alg: alg_config, + vtxn: vtxn_config, + window_size: DEFAULT_WINDOW_SIZE, + }), + None, + Some(local_config), + Some(randomness_config), + None, + false, + ); + let node = &mut nodes[0]; + let genesis_qc = certificate_for_genesis(); + + let block_too_many_txns = Block::new_proposal_ext( + vec![], + Payload::DirectMempool(create_vec_signed_transactions(11)), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + let block_too_many_vtxns = Block::new_proposal_ext( + vec![ValidatorTransaction::dummy(vec![0xFF; 20]); 6], + Payload::DirectMempool(create_vec_signed_transactions(4)), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + let block_too_large = Block::new_proposal_ext( + vec![ValidatorTransaction::dummy(vec![0xFF; 200]); 1], // total_bytes >= 200 * 1 = 200 + Payload::DirectMempool(create_vec_signed_transactions(9)), // = total_bytes >= 69 * 9 = 621 + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + let block_vtxns_too_large = Block::new_proposal_ext( + vec![ValidatorTransaction::dummy(vec![0xFF; 200]); 5], // total_bytes >= 200 * 5 = 1000 + Payload::empty(false, true), + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + let valid_block = Block::new_proposal_ext( + vec![ValidatorTransaction::dummy(vec![0xFF; 20]); 5], // total_bytes >= 60 * 5 = 300 + Payload::DirectMempool(create_vec_signed_transactions(5)), // total_bytes >= 69 * 5 = 345 + 1, + 1, + genesis_qc.clone(), + &node.signer, + Vec::new(), + ) + .unwrap(); + + timed_block_on(&runtime, async { + // clear the message queue + node.next_proposal().await; + + assert!(node + .round_manager + .process_proposal(block_too_many_txns) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal(block_too_many_vtxns) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal(block_too_large) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal(block_vtxns_too_large) + .await + .is_err()); + + assert!(node + .round_manager + .process_proposal(valid_block) + .await + .is_ok()); + }); +} diff --git a/consensus/src/state_computer.rs b/consensus/src/state_computer.rs index 31b22f29e50..ad9ca38be0d 100644 --- a/consensus/src/state_computer.rs +++ b/consensus/src/state_computer.rs @@ -3,51 +3,28 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - block_preparer::BlockPreparer, - block_storage::tracing::{observe_block, BlockStage}, - counters, - error::StateSyncError, - execution_pipeline::{ExecutionPipeline, PreCommitHook}, - monitor, - payload_manager::TPayloadManager, - pipeline::{pipeline_builder::PipelineBuilder, pipeline_phase::CountedRequest}, - state_replication::{StateComputer, StateComputerCommitCallBackType}, - transaction_deduper::TransactionDeduper, - transaction_filter::TransactionFilter, - transaction_shuffler::TransactionShuffler, - txn_notifier::TxnNotifier, + block_preparer::BlockPreparer, error::StateSyncError, monitor, network::NetworkSender, + payload_manager::TPayloadManager, pipeline::pipeline_builder::PipelineBuilder, + state_replication::StateComputer, transaction_deduper::TransactionDeduper, + transaction_shuffler::TransactionShuffler, txn_notifier::TxnNotifier, }; use anyhow::Result; +use aptos_config::config::BlockTransactionFilterConfig; use aptos_consensus_notifications::ConsensusNotificationSender; -use aptos_consensus_types::{ - block::Block, common::Round, pipeline_execution_result::PipelineExecutionResult, - pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, -}; +use aptos_consensus_types::common::Round; use aptos_crypto::HashValue; -use aptos_executor_types::{ - state_compute_result::StateComputeResult, BlockExecutorTrait, ExecutorResult, -}; +use aptos_executor_types::BlockExecutorTrait; use aptos_infallible::RwLock; use aptos_logger::prelude::*; -use aptos_metrics_core::IntGauge; use aptos_types::{ account_address::AccountAddress, block_executor::config::BlockExecutorConfigFromOnchain, - epoch_state::EpochState, ledger_info::LedgerInfoWithSignatures, randomness::Randomness, - validator_signer::ValidatorSigner, + epoch_state::EpochState, ledger_info::LedgerInfoWithSignatures, + on_chain_config::OnChainConsensusConfig, validator_signer::ValidatorSigner, }; use fail::fail_point; -use futures::{future::BoxFuture, SinkExt, StreamExt}; -use std::{ - boxed::Box, - sync::Arc, - time::{Duration, Instant}, -}; +use std::{boxed::Box, sync::Arc, time::Duration}; use tokio::sync::Mutex as AsyncMutex; -pub type StateComputeResultFut = BoxFuture<'static, ExecutorResult>; - -type NotificationType = BoxFuture<'static, ()>; - #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] struct LogicalTime { epoch: u64, @@ -68,7 +45,9 @@ struct MutableState { block_executor_onchain_config: BlockExecutorConfigFromOnchain, transaction_deduper: Arc, is_randomness_enabled: bool, - order_vote_enabled: bool, + consensus_onchain_config: OnChainConsensusConfig, + persisted_auxiliary_info_version: u8, + network_sender: Arc, } /// Basic communication with the Execution module; @@ -77,11 +56,8 @@ pub struct ExecutionProxy { executor: Arc, txn_notifier: Arc, state_sync_notifier: Arc, - pre_commit_notifier: aptos_channels::Sender, - commit_notifier: aptos_channels::Sender, write_mutex: AsyncMutex, - transaction_filter: Arc, - execution_pipeline: ExecutionPipeline, + txn_filter_config: Arc, state: RwLock>, enable_pre_commit: bool, } @@ -91,102 +67,20 @@ impl ExecutionProxy { executor: Arc, txn_notifier: Arc, state_sync_notifier: Arc, - handle: &tokio::runtime::Handle, - txn_filter: TransactionFilter, + txn_filter_config: BlockTransactionFilterConfig, enable_pre_commit: bool, ) -> Self { - let pre_commit_notifier = Self::spawn_future_runner( - handle, - "pre-commit", - &counters::PENDING_STATE_SYNC_NOTIFICATION, - ); - let commit_notifier = - Self::spawn_future_runner(handle, "commit", &counters::PENDING_COMMIT_NOTIFICATION); - - let execution_pipeline = - ExecutionPipeline::spawn(executor.clone(), handle, enable_pre_commit); Self { executor, txn_notifier, state_sync_notifier, - pre_commit_notifier, - commit_notifier, write_mutex: AsyncMutex::new(LogicalTime::new(0, 0)), - transaction_filter: Arc::new(txn_filter), - execution_pipeline, + txn_filter_config: Arc::new(txn_filter_config), state: RwLock::new(None), enable_pre_commit, } } - fn spawn_future_runner( - handle: &tokio::runtime::Handle, - name: &'static str, - pending_notifications_gauge: &IntGauge, - ) -> aptos_channels::Sender { - let (tx, mut rx) = aptos_channels::new::(10, pending_notifications_gauge); - let _join_handle = handle.spawn(async move { - while let Some(fut) = rx.next().await { - fut.await - } - info!(name = name, "Future runner stopped.") - }); - tx - } - - fn pre_commit_hook(&self) -> PreCommitHook { - let mut pre_commit_notifier = self.pre_commit_notifier.clone(); - let state_sync_notifier = self.state_sync_notifier.clone(); - Box::new(move |state_compute_result: &StateComputeResult| { - let state_compute_result = state_compute_result.clone(); - Box::pin(async move { - pre_commit_notifier - .send(Box::pin(async move { - let _timer = counters::OP_COUNTERS.timer("pre_commit_notify"); - - let txns = state_compute_result.transactions_to_commit().to_vec(); - let subscribable_events = - state_compute_result.subscribable_events().to_vec(); - if let Err(e) = monitor!( - "notify_state_sync", - state_sync_notifier - .notify_new_commit(txns, subscribable_events) - .await - ) { - error!(error = ?e, "Failed to notify state synchronizer"); - } - })) - .await - .expect("Failed to send pre-commit notification"); - }) - }) - } - - fn commit_hook( - &self, - blocks: &[Arc], - callback: StateComputerCommitCallBackType, - finality_proof: LedgerInfoWithSignatures, - ) -> NotificationType { - let payload_manager = self - .state - .read() - .as_ref() - .expect("must be set within an epoch") - .payload_manager - .clone(); - let blocks = blocks.to_vec(); - Box::pin(async move { - for block in blocks.iter() { - let payload = block.payload().cloned(); - let payload_vec = payload.into_iter().collect(); - let timestamp = block.timestamp_usecs(); - payload_manager.notify_commit(timestamp, payload_vec); - } - callback(&blocks, finality_proof); - }) - } - pub fn pipeline_builder(&self, commit_signer: Arc) -> PipelineBuilder { let MutableState { validators, @@ -195,7 +89,9 @@ impl ExecutionProxy { block_executor_onchain_config, transaction_deduper, is_randomness_enabled, - order_vote_enabled, + consensus_onchain_config, + persisted_auxiliary_info_version, + network_sender, } = self .state .read() @@ -205,7 +101,7 @@ impl ExecutionProxy { let block_preparer = Arc::new(BlockPreparer::new( payload_manager.clone(), - self.transaction_filter.clone(), + self.txn_filter_config.clone(), transaction_deduper.clone(), transaction_shuffler.clone(), )); @@ -220,165 +116,15 @@ impl ExecutionProxy { payload_manager, self.txn_notifier.clone(), self.enable_pre_commit, - order_vote_enabled, + &consensus_onchain_config, + persisted_auxiliary_info_version, + network_sender, ) } } #[async_trait::async_trait] impl StateComputer for ExecutionProxy { - async fn schedule_compute( - &self, - // The block to be executed. - block: &Block, - // The parent block id. - parent_block_id: HashValue, - randomness: Option, - block_qc: Option>, - lifetime_guard: CountedRequest<()>, - ) -> StateComputeResultFut { - let block_id = block.id(); - debug!( - block = %block, - parent_id = parent_block_id, - "Executing block", - ); - let MutableState { - validators, - payload_manager, - transaction_shuffler, - block_executor_onchain_config, - transaction_deduper, - is_randomness_enabled, - .. - } = self - .state - .read() - .as_ref() - .cloned() - .expect("must be set within an epoch"); - - let txn_notifier = self.txn_notifier.clone(); - let transaction_generator = BlockPreparer::new( - payload_manager, - self.transaction_filter.clone(), - transaction_deduper.clone(), - transaction_shuffler.clone(), - ); - - let block_executor_onchain_config = block_executor_onchain_config.clone(); - - let timestamp = block.timestamp_usecs(); - let metadata = if is_randomness_enabled { - block.new_metadata_with_randomness(&validators, randomness) - } else { - block.new_block_metadata(&validators).into() - }; - - let pipeline_entry_time = Instant::now(); - let fut = self - .execution_pipeline - .queue( - block.clone(), - metadata.clone(), - parent_block_id, - block_qc, - transaction_generator, - block_executor_onchain_config, - self.pre_commit_hook(), - lifetime_guard, - transaction_shuffler, - ) - .await; - observe_block(timestamp, BlockStage::EXECUTION_PIPELINE_INSERTED); - counters::PIPELINE_ENTRY_TO_INSERTED_TIME.observe_duration(pipeline_entry_time.elapsed()); - let pipeline_inserted_timestamp = Instant::now(); - - Box::pin(async move { - let pipeline_execution_result = fut.await?; - debug!( - block_id = block_id, - "Got state compute result, post processing." - ); - let user_txns = &pipeline_execution_result.input_txns; - let result = &pipeline_execution_result.result; - - observe_block(timestamp, BlockStage::EXECUTED); - counters::PIPELINE_INSERTION_TO_EXECUTED_TIME - .observe_duration(pipeline_inserted_timestamp.elapsed()); - - let compute_status = result.compute_status_for_input_txns(); - // the length of compute_status is user_txns.len() + num_vtxns + 1 due to having blockmetadata - if user_txns.len() >= compute_status.len() { - // reconfiguration suffix blocks don't have any transactions - // otherwise, this is an error - if !compute_status.is_empty() { - error!( - "Expected compute_status length and actual compute_status length mismatch! user_txns len: {}, compute_status len: {}, has_reconfiguration: {}", - user_txns.len(), - compute_status.len(), - result.has_reconfiguration(), - ); - } - } else { - let user_txn_status = &compute_status[compute_status.len() - user_txns.len()..]; - - // notify mempool about failed transaction - if let Err(e) = txn_notifier - .notify_failed_txn(user_txns, user_txn_status) - .await - { - error!( - error = ?e, "Failed to notify mempool of rejected txns", - ); - } - } - - Ok(pipeline_execution_result) - }) - } - - /// Send a successful commit. A future is fulfilled when the state is finalized. - async fn commit( - &self, - blocks: Vec>, - finality_proof: LedgerInfoWithSignatures, - callback: StateComputerCommitCallBackType, - ) -> ExecutorResult<()> { - let mut latest_logical_time = self.write_mutex.lock().await; - let logical_time = LogicalTime::new( - finality_proof.ledger_info().epoch(), - finality_proof.ledger_info().round(), - ); - - // wait until all blocks are committed - for block in &blocks { - block.take_pre_commit_fut().await? - } - - let executor = self.executor.clone(); - let proof = finality_proof.clone(); - monitor!( - "commit_block", - tokio::task::spawn_blocking(move || { - executor - .commit_ledger(proof) - .expect("Failed to commit blocks"); - }) - .await - ) - .expect("spawn_blocking failed"); - - self.commit_notifier - .clone() - .send(self.commit_hook(&blocks, callback, finality_proof)) - .await - .expect("Failed to send commit notification"); - - *latest_logical_time = logical_time; - Ok(()) - } - /// Best effort state synchronization for the specified duration async fn sync_for_duration( &self, @@ -491,8 +237,10 @@ impl StateComputer for ExecutionProxy { block_executor_onchain_config: BlockExecutorConfigFromOnchain, transaction_deduper: Arc, randomness_enabled: bool, - order_vote_enabled: bool, virtual_genesis_block_id: Option, + consensus_onchain_config: OnChainConsensusConfig, + persisted_auxiliary_info_version: u8, + network_sender: Arc, ) { // Reset the executor with the virtual genesis block ID if provided if let Some(virtual_genesis_id) = virtual_genesis_block_id { @@ -514,7 +262,9 @@ impl StateComputer for ExecutionProxy { block_executor_onchain_config, transaction_deduper, is_randomness_enabled: randomness_enabled, - order_vote_enabled, + consensus_onchain_config, + persisted_auxiliary_info_version, + network_sender, }); } @@ -524,172 +274,3 @@ impl StateComputer for ExecutionProxy { self.state.write().take(); } } - -#[tokio::test] -async fn test_commit_sync_race() { - use crate::{ - error::MempoolError, payload_manager::DirectMempoolPayloadManager, - transaction_deduper::create_transaction_deduper, - transaction_shuffler::create_transaction_shuffler, - }; - use aptos_config::config::transaction_filter_type::Filter; - use aptos_consensus_notifications::Error; - use aptos_infallible::Mutex; - use aptos_types::{ - aggregate_signature::AggregateSignature, - block_executor::partitioner::ExecutableBlock, - block_info::BlockInfo, - contract_event::ContractEvent, - ledger_info::LedgerInfo, - on_chain_config::{TransactionDeduperType, TransactionShufflerType}, - transaction::{SignedTransaction, Transaction, TransactionStatus}, - }; - - struct RecordedCommit { - time: Mutex, - } - - impl BlockExecutorTrait for RecordedCommit { - fn committed_block_id(&self) -> HashValue { - HashValue::zero() - } - - fn reset(&self) -> Result<()> { - Ok(()) - } - - fn execute_block( - &self, - _block: ExecutableBlock, - _parent_block_id: HashValue, - _onchain_config: BlockExecutorConfigFromOnchain, - ) -> ExecutorResult { - Ok(StateComputeResult::new_dummy()) - } - - fn execute_and_update_state( - &self, - _block: ExecutableBlock, - _parent_block_id: HashValue, - _onchain_config: BlockExecutorConfigFromOnchain, - ) -> ExecutorResult<()> { - todo!() - } - - fn ledger_update( - &self, - _block_id: HashValue, - _parent_block_id: HashValue, - ) -> ExecutorResult { - todo!() - } - - fn pre_commit_block(&self, _block_id: HashValue) -> ExecutorResult<()> { - todo!() - } - - fn commit_ledger( - &self, - ledger_info_with_sigs: LedgerInfoWithSignatures, - ) -> ExecutorResult<()> { - *self.time.lock() = LogicalTime::new( - ledger_info_with_sigs.ledger_info().epoch(), - ledger_info_with_sigs.ledger_info().round(), - ); - Ok(()) - } - - fn finish(&self) {} - } - - #[async_trait::async_trait] - impl TxnNotifier for RecordedCommit { - async fn notify_failed_txn( - &self, - _txns: &[SignedTransaction], - _compute_results: &[TransactionStatus], - ) -> Result<(), MempoolError> { - Ok(()) - } - } - - #[async_trait::async_trait] - impl ConsensusNotificationSender for RecordedCommit { - async fn notify_new_commit( - &self, - _transactions: Vec, - _subscribable_events: Vec, - ) -> std::result::Result<(), Error> { - Ok(()) - } - - async fn sync_for_duration( - &self, - _duration: std::time::Duration, - ) -> std::result::Result { - Err(Error::UnexpectedErrorEncountered( - "sync_for_duration() is not supported by the RecordedCommit!".into(), - )) - } - - async fn sync_to_target( - &self, - target: LedgerInfoWithSignatures, - ) -> std::result::Result<(), Error> { - let logical_time = - LogicalTime::new(target.ledger_info().epoch(), target.ledger_info().round()); - if logical_time <= *self.time.lock() { - return Err(Error::NotificationError( - "Decreasing logical time".to_string(), - )); - } - *self.time.lock() = logical_time; - Ok(()) - } - } - - let callback = Box::new(move |_a: &[Arc], _b: LedgerInfoWithSignatures| {}); - let recorded_commit = Arc::new(RecordedCommit { - time: Mutex::new(LogicalTime::new(0, 0)), - }); - let generate_li = |epoch, round| { - LedgerInfoWithSignatures::new( - LedgerInfo::new( - BlockInfo::random_with_epoch(epoch, round), - HashValue::zero(), - ), - AggregateSignature::empty(), - ) - }; - let executor = ExecutionProxy::new( - recorded_commit.clone(), - recorded_commit.clone(), - recorded_commit.clone(), - &tokio::runtime::Handle::current(), - TransactionFilter::new(Filter::empty()), - true, - ); - - executor.new_epoch( - &EpochState::empty(), - Arc::new(DirectMempoolPayloadManager {}), - create_transaction_shuffler(TransactionShufflerType::NoShuffling), - BlockExecutorConfigFromOnchain::new_no_block_limit(), - create_transaction_deduper(TransactionDeduperType::NoDedup), - false, - false, - None, - ); - executor - .commit(vec![], generate_li(1, 1), callback.clone()) - .await - .unwrap(); - executor - .commit(vec![], generate_li(1, 10), callback) - .await - .unwrap(); - assert!(executor.sync_to_target(generate_li(1, 8)).await.is_ok()); - assert_eq!(*recorded_commit.time.lock(), LogicalTime::new(1, 10)); - assert!(executor.sync_to_target(generate_li(2, 8)).await.is_ok()); - assert_eq!(*recorded_commit.time.lock(), LogicalTime::new(2, 8)); -} diff --git a/consensus/src/state_computer_tests.rs b/consensus/src/state_computer_tests.rs deleted file mode 100644 index 9d93efa9e4e..00000000000 --- a/consensus/src/state_computer_tests.rs +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - error::MempoolError, pipeline::pipeline_phase::CountedRequest, state_computer::ExecutionProxy, - state_replication::StateComputer, transaction_deduper::NoOpDeduper, - transaction_filter::TransactionFilter, transaction_shuffler::NoOpShuffler, - txn_notifier::TxnNotifier, -}; -use aptos_config::config::transaction_filter_type::Filter; -use aptos_consensus_notifications::{ConsensusNotificationSender, Error}; -use aptos_consensus_types::{block::Block, block_data::BlockData}; -use aptos_crypto::HashValue; -use aptos_executor_types::{ - state_compute_result::StateComputeResult, BlockExecutorTrait, ExecutorResult, -}; -use aptos_infallible::Mutex; -use aptos_types::{ - block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, - contract_event::ContractEvent, - epoch_state::EpochState, - ledger_info::LedgerInfoWithSignatures, - transaction::{SignedTransaction, Transaction, TransactionStatus}, - validator_txn::ValidatorTransaction, -}; -use std::{ - sync::{atomic::AtomicU64, Arc}, - time::Duration, -}; -use tokio::{runtime::Handle, sync::Mutex as AsyncMutex}; - -struct DummyStateSyncNotifier { - invocations: Mutex, Vec)>>, - tx: tokio::sync::mpsc::Sender<()>, - rx: AsyncMutex>, -} - -impl DummyStateSyncNotifier { - fn new() -> Self { - let (tx, rx) = tokio::sync::mpsc::channel(10); - Self { - invocations: Mutex::new(vec![]), - tx, - rx: AsyncMutex::new(rx), - } - } - - async fn wait_for_notification(&self) { - self.rx.lock().await.recv().await; - } -} - -#[async_trait::async_trait] -impl ConsensusNotificationSender for DummyStateSyncNotifier { - async fn notify_new_commit( - &self, - transactions: Vec, - subscribable_events: Vec, - ) -> Result<(), Error> { - self.invocations - .lock() - .push((transactions, subscribable_events)); - self.tx.send(()).await.unwrap(); - Ok(()) - } - - async fn sync_for_duration( - &self, - _duration: Duration, - ) -> Result { - Err(Error::UnexpectedErrorEncountered( - "sync_for_duration() is not supported by the DummyStateSyncNotifier!".into(), - )) - } - - async fn sync_to_target(&self, _target: LedgerInfoWithSignatures) -> Result<(), Error> { - unreachable!() - } -} - -struct DummyTxnNotifier {} - -#[async_trait::async_trait] -impl TxnNotifier for DummyTxnNotifier { - async fn notify_failed_txn( - &self, - _txns: &[SignedTransaction], - _statuses: &[TransactionStatus], - ) -> anyhow::Result<(), MempoolError> { - Ok(()) - } -} - -struct DummyBlockExecutor { - blocks_received: Mutex>, -} - -impl DummyBlockExecutor { - fn new() -> Self { - Self { - blocks_received: Mutex::new(vec![]), - } - } -} - -impl BlockExecutorTrait for DummyBlockExecutor { - fn committed_block_id(&self) -> HashValue { - HashValue::zero() - } - - fn reset(&self) -> anyhow::Result<()> { - Ok(()) - } - - fn execute_and_update_state( - &self, - block: ExecutableBlock, - _parent_block_id: HashValue, - _onchain_config: BlockExecutorConfigFromOnchain, - ) -> ExecutorResult<()> { - self.blocks_received.lock().push(block); - Ok(()) - } - - fn ledger_update( - &self, - _block_id: HashValue, - _parent_block_id: HashValue, - ) -> ExecutorResult { - let txns = self - .blocks_received - .lock() - .last() - .unwrap() - .transactions - .clone() - .into_txns() - .into_iter() - .map(|t| t.into_inner()) - .collect(); - - Ok(StateComputeResult::new_dummy_with_input_txns(txns)) - } - - fn pre_commit_block(&self, _block_id: HashValue) -> ExecutorResult<()> { - Ok(()) - } - - fn commit_ledger( - &self, - _ledger_info_with_sigs: LedgerInfoWithSignatures, - ) -> ExecutorResult<()> { - Ok(()) - } - - fn finish(&self) {} -} - -#[tokio::test] -#[cfg(test)] -async fn should_see_and_notify_validator_txns() { - use crate::payload_manager::DirectMempoolPayloadManager; - - let executor = Arc::new(DummyBlockExecutor::new()); - - let state_sync_notifier = Arc::new(DummyStateSyncNotifier::new()); - let execution_policy = ExecutionProxy::new( - executor.clone(), - Arc::new(DummyTxnNotifier {}), - state_sync_notifier.clone(), - &Handle::current(), - TransactionFilter::new(Filter::empty()), - true, - ); - - let validator_txn_0 = ValidatorTransaction::dummy(vec![0xFF; 99]); - let validator_txn_1 = ValidatorTransaction::dummy(vec![0xFF; 999]); - - let block = Block::new_for_testing( - HashValue::zero(), - BlockData::dummy_with_validator_txns(vec![ - validator_txn_0.clone(), - validator_txn_1.clone(), - ]), - None, - ); - - let epoch_state = EpochState::empty(); - - execution_policy.new_epoch( - &epoch_state, - Arc::new(DirectMempoolPayloadManager::new()), - Arc::new(NoOpShuffler {}), - BlockExecutorConfigFromOnchain::new_no_block_limit(), - Arc::new(NoOpDeduper {}), - false, - false, - None, - ); - - // Ensure the dummy executor has received the txns. - let _ = execution_policy - .schedule_compute(&block, HashValue::zero(), None, None, dummy_guard()) - .await - .await - .unwrap(); - - // Get the txns from the view of the dummy executor. - let txns = executor.blocks_received.lock()[0] - .transactions - .clone() - .into_txns(); - - let supposed_validator_txn_0 = txns[1].expect_valid().try_as_validator_txn().unwrap(); - let supposed_validator_txn_1 = txns[2].expect_valid().try_as_validator_txn().unwrap(); - assert_eq!(&validator_txn_0, supposed_validator_txn_0); - assert_eq!(&validator_txn_1, supposed_validator_txn_1); - - // Get all txns that state sync was notified with (when pre-commit finishes) - state_sync_notifier.wait_for_notification().await; - let (txns, _) = state_sync_notifier.invocations.lock()[0].clone(); - - let supposed_validator_txn_0 = txns[1].try_as_validator_txn().unwrap(); - let supposed_validator_txn_1 = txns[2].try_as_validator_txn().unwrap(); - assert_eq!(&validator_txn_0, supposed_validator_txn_0); - assert_eq!(&validator_txn_1, supposed_validator_txn_1); -} - -fn dummy_guard() -> CountedRequest<()> { - CountedRequest::new((), Arc::new(AtomicU64::new(0))) -} diff --git a/consensus/src/state_replication.rs b/consensus/src/state_replication.rs index 18e5e0fa313..14c2ff78ed7 100644 --- a/consensus/src/state_replication.rs +++ b/consensus/src/state_replication.rs @@ -3,19 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - error::StateSyncError, payload_manager::TPayloadManager, - pipeline::pipeline_phase::CountedRequest, state_computer::StateComputeResultFut, + error::StateSyncError, network::NetworkSender, payload_manager::TPayloadManager, transaction_deduper::TransactionDeduper, transaction_shuffler::TransactionShuffler, }; use anyhow::Result; -use aptos_consensus_types::{ - block::Block, pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, -}; -use aptos_crypto::HashValue; -use aptos_executor_types::ExecutorResult; +use aptos_consensus_types::pipelined_block::PipelinedBlock; use aptos_types::{ block_executor::config::BlockExecutorConfigFromOnchain, epoch_state::EpochState, - ledger_info::LedgerInfoWithSignatures, randomness::Randomness, + ledger_info::LedgerInfoWithSignatures, on_chain_config::OnChainConsensusConfig, }; use std::{sync::Arc, time::Duration}; @@ -27,27 +22,6 @@ pub type StateComputerCommitCallBackType = /// StateComputer is using proposed block ids for identifying the transactions. #[async_trait::async_trait] pub trait StateComputer: Send + Sync { - async fn schedule_compute( - &self, - // The block that will be computed. - _block: &Block, - // The parent block root hash. - _parent_block_id: HashValue, - _randomness: Option, - _block_qc: Option>, - _lifetime_guard: CountedRequest<()>, - ) -> StateComputeResultFut { - unimplemented!(); - } - - /// Send a successful commit. A future is fulfilled when the state is finalized. - async fn commit( - &self, - blocks: Vec>, - finality_proof: LedgerInfoWithSignatures, - callback: StateComputerCommitCallBackType, - ) -> ExecutorResult<()>; - /// Best effort state synchronization for the specified duration. /// This function returns the latest synced ledger info after state syncing. /// Note: it is possible that state sync may run longer than the specified @@ -72,8 +46,10 @@ pub trait StateComputer: Send + Sync { block_executor_onchain_config: BlockExecutorConfigFromOnchain, transaction_deduper: Arc, randomness_enabled: bool, - order_vote_enabled: bool, virtual_genesis_block_id: Option, + consensus_onchain_config: OnChainConsensusConfig, + persisted_auxiliary_info_version: u8, + network_sender: Arc, ); // Reconfigure to clear epoch state at end of epoch. diff --git a/consensus/src/test_utils/mock_execution_client.rs b/consensus/src/test_utils/mock_execution_client.rs index 767d76c7034..7caf0d34274 100644 --- a/consensus/src/test_utils/mock_execution_client.rs +++ b/consensus/src/test_utils/mock_execution_client.rs @@ -11,7 +11,6 @@ use crate::{ pipeline_builder::PipelineBuilder, signing_phase::CommitSignerProvider, }, rand::rand_gen::types::RandConfig, - state_replication::StateComputerCommitCallBackType, test_utils::mock_storage::MockStorage, }; use anyhow::{anyhow, format_err, Result}; @@ -19,6 +18,7 @@ use aptos_channels::aptos_channel; use aptos_consensus_types::{ common::{Payload, Round}, pipelined_block::PipelinedBlock, + vote_data::VoteData, wrapped_ledger_info::WrappedLedgerInfo, }; use aptos_crypto::{bls12381::PrivateKey, HashValue}; @@ -43,6 +43,8 @@ pub struct MockExecutionClient { consensus_db: Arc, block_cache: Mutex>, payload_manager: Arc, + block_store_callback: + Mutex>>, } impl MockExecutionClient { @@ -57,18 +59,34 @@ impl MockExecutionClient { consensus_db, block_cache: Mutex::new(HashMap::new()), payload_manager: Arc::from(DirectMempoolPayloadManager::new()), + block_store_callback: Mutex::new(None), } } + pub fn set_callback( + &self, + callback: Box, + ) { + *self.block_store_callback.lock() = Some(callback); + } + pub async fn commit_to_storage(&self, blocks: OrderedBlocks) -> ExecutorResult<()> { let OrderedBlocks { ordered_blocks, ordered_proof, - callback, } = blocks; self.consensus_db .commit_to_storage(ordered_proof.ledger_info().clone()); + if let Some(callback) = self.block_store_callback.lock().as_ref() { + for block in &ordered_blocks { + callback( + block.id(), + block.round(), + WrappedLedgerInfo::new(VoteData::dummy(), ordered_proof.clone()), + ); + } + } // mock sending commit notif to state sync let mut txns = vec![]; for block in &ordered_blocks { @@ -85,8 +103,6 @@ impl MockExecutionClient { // they may fail during shutdown let _ = self.state_sync_client.unbounded_send(txns); - callback(&ordered_blocks, ordered_proof); - Ok(()) } } @@ -106,7 +122,6 @@ impl TExecutionClient for MockExecutionClient { _fast_rand_config: Option, _rand_msg_rx: aptos_channel::Receiver, _highest_committed_round: Round, - _new_pipeline_enabled: bool, _virtual_genesis_block_id: Option, ) { } @@ -119,7 +134,6 @@ impl TExecutionClient for MockExecutionClient { &self, blocks: Vec>, finality_proof: WrappedLedgerInfo, - callback: StateComputerCommitCallBackType, ) -> ExecutorResult<()> { assert!(!blocks.is_empty()); info!( @@ -143,7 +157,6 @@ impl TExecutionClient for MockExecutionClient { .send(OrderedBlocks { ordered_blocks: blocks, ordered_proof: finality_proof.ledger_info().clone(), - callback, }) .await .is_err() diff --git a/consensus/src/test_utils/mock_payload_manager.rs b/consensus/src/test_utils/mock_payload_manager.rs index 43da1a164e2..0dd3a80d44a 100644 --- a/consensus/src/test_utils/mock_payload_manager.rs +++ b/consensus/src/test_utils/mock_payload_manager.rs @@ -16,7 +16,7 @@ use aptos_types::{ vm_status::StatusCode, }; use aptos_validator_transaction_pool as vtxn_pool; -use futures::{channel::mpsc, future::BoxFuture}; +use futures::channel::mpsc; use rand::Rng; #[allow(dead_code)] @@ -56,7 +56,6 @@ impl PayloadClient for MockPayloadManager { &self, _params: PayloadPullParameters, _validator_txn_filter: vtxn_pool::TransactionFilter, - _wait_callback: BoxFuture<'static, ()>, ) -> Result<(Vec, Payload), QuorumStoreError> { // generate 1k txn is too slow with coverage instrumentation Ok(( diff --git a/consensus/src/test_utils/mock_quorum_store_sender.rs b/consensus/src/test_utils/mock_quorum_store_sender.rs index bd962d348b5..f7a7ddd5dff 100644 --- a/consensus/src/test_utils/mock_quorum_store_sender.rs +++ b/consensus/src/test_utils/mock_quorum_store_sender.rs @@ -8,7 +8,9 @@ use crate::{ }; use aptos_consensus_types::{ common::Author, - proof_of_store::{ProofOfStore, ProofOfStoreMsg, SignedBatchInfo, SignedBatchInfoMsg}, + proof_of_store::{ + BatchInfo, ProofOfStore, ProofOfStoreMsg, SignedBatchInfo, SignedBatchInfoMsg, + }, }; use std::time::Duration; use tokio::sync::mpsc::Sender; @@ -37,7 +39,7 @@ impl QuorumStoreSender for MockQuorumStoreSender { async fn send_signed_batch_info_msg( &self, - signed_batch_infos: Vec, + signed_batch_infos: Vec>, recipients: Vec, ) { self.tx @@ -55,7 +57,10 @@ impl QuorumStoreSender for MockQuorumStoreSender { unimplemented!() } - async fn broadcast_proof_of_store_msg(&mut self, proof_of_stores: Vec) { + async fn broadcast_proof_of_store_msg( + &mut self, + proof_of_stores: Vec>, + ) { self.tx .send(( ConsensusMsg::ProofOfStoreMsg(Box::new(ProofOfStoreMsg::new(proof_of_stores))), @@ -65,7 +70,10 @@ impl QuorumStoreSender for MockQuorumStoreSender { .expect("We should be able to send the proof of store message"); } - async fn send_proof_of_store_msg_to_self(&mut self, _proof_of_stores: Vec) { + async fn send_proof_of_store_msg_to_self( + &mut self, + _proof_of_stores: Vec>, + ) { unimplemented!() } } diff --git a/consensus/src/test_utils/mock_state_computer.rs b/consensus/src/test_utils/mock_state_computer.rs index 11e11a6c0eb..a008f0c411b 100644 --- a/consensus/src/test_utils/mock_state_computer.rs +++ b/consensus/src/test_utils/mock_state_computer.rs @@ -3,101 +3,17 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - error::StateSyncError, - payload_manager::TPayloadManager, - pipeline::{buffer_manager::OrderedBlocks, pipeline_phase::CountedRequest}, - state_computer::StateComputeResultFut, - state_replication::{StateComputer, StateComputerCommitCallBackType}, - transaction_deduper::TransactionDeduper, - transaction_shuffler::TransactionShuffler, + error::StateSyncError, payload_manager::TPayloadManager, state_replication::StateComputer, + transaction_deduper::TransactionDeduper, transaction_shuffler::TransactionShuffler, }; use anyhow::{anyhow, Result}; -use aptos_consensus_types::{ - block::Block, pipeline_execution_result::PipelineExecutionResult, - pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, -}; use aptos_crypto::HashValue; -use aptos_executor_types::{ - state_compute_result::StateComputeResult, ExecutorError, ExecutorResult, -}; -use aptos_logger::debug; use aptos_types::{ block_executor::config::BlockExecutorConfigFromOnchain, epoch_state::EpochState, - ledger_info::LedgerInfoWithSignatures, randomness::Randomness, + ledger_info::LedgerInfoWithSignatures, on_chain_config::OnChainConsensusConfig, }; -use futures::SinkExt; -use futures_channel::mpsc::UnboundedSender; use std::{sync::Arc, time::Duration}; -pub struct EmptyStateComputer { - executor_channel: UnboundedSender, -} - -impl EmptyStateComputer { - pub fn new(executor_channel: UnboundedSender) -> Self { - Self { executor_channel } - } -} - -#[async_trait::async_trait] -impl StateComputer for EmptyStateComputer { - async fn commit( - &self, - blocks: Vec>, - commit: LedgerInfoWithSignatures, - call_back: StateComputerCommitCallBackType, - ) -> ExecutorResult<()> { - assert!(!blocks.is_empty()); - - if self - .executor_channel - .clone() - .send(OrderedBlocks { - ordered_blocks: blocks, - ordered_proof: commit, - callback: call_back, - }) - .await - .is_err() - { - debug!("Failed to send to buffer manager, maybe epoch ends"); - } - - Ok(()) - } - - async fn sync_for_duration( - &self, - _duration: Duration, - ) -> Result { - Err(StateSyncError::from(anyhow!( - "sync_for_duration() is not supported by the EmptyStateComputer!" - ))) - } - - async fn sync_to_target( - &self, - _target: LedgerInfoWithSignatures, - ) -> Result<(), StateSyncError> { - Ok(()) - } - - fn new_epoch( - &self, - _: &EpochState, - _: Arc, - _: Arc, - _: BlockExecutorConfigFromOnchain, - _: Arc, - _: bool, - _: bool, - _: Option, - ) { - } - - fn end_epoch(&self) {} -} - /// Random Compute Result State Computer /// When compute(), if parent id is random_compute_result_root_hash, it returns Err(Error::BlockNotFound(parent_block_id)) /// Otherwise, it returns a dummy StateComputeResult with root hash as random_compute_result_root_hash. @@ -119,42 +35,6 @@ impl RandomComputeResultStateComputer { #[async_trait::async_trait] impl StateComputer for RandomComputeResultStateComputer { - async fn schedule_compute( - &self, - _block: &Block, - parent_block_id: HashValue, - _randomness: Option, - _block_qc: Option>, - _lifetime_guard: CountedRequest<()>, - ) -> StateComputeResultFut { - // trapdoor for Execution Error - let res = if parent_block_id == self.random_compute_result_root_hash { - Err(ExecutorError::BlockNotFound(parent_block_id)) - } else { - Ok(StateComputeResult::new_dummy_with_root_hash( - self.random_compute_result_root_hash, - )) - }; - let pipeline_execution_res = res.map(|res| { - PipelineExecutionResult::new( - vec![], - res, - Duration::from_secs(0), - Box::pin(async { Ok(()) }), - ) - }); - Box::pin(async move { pipeline_execution_res }) - } - - async fn commit( - &self, - _blocks: Vec>, - _commit: LedgerInfoWithSignatures, - _call_back: StateComputerCommitCallBackType, - ) -> ExecutorResult<()> { - Ok(()) - } - async fn sync_for_duration( &self, _duration: Duration, @@ -179,8 +59,10 @@ impl StateComputer for RandomComputeResultStateComputer { _: BlockExecutorConfigFromOnchain, _: Arc, _: bool, - _: bool, _: Option, + _: OnChainConsensusConfig, + _: u8, + _: Arc, ) { } diff --git a/consensus/src/test_utils/mod.rs b/consensus/src/test_utils/mod.rs index c451f2c447f..35cad6da3d3 100644 --- a/consensus/src/test_utils/mod.rs +++ b/consensus/src/test_utils/mod.rs @@ -49,8 +49,6 @@ use aptos_types::{ }; pub use mock_payload_manager::MockPayloadManager; #[cfg(test)] -pub use mock_state_computer::EmptyStateComputer; -#[cfg(test)] pub use mock_state_computer::RandomComputeResultStateComputer; pub use mock_storage::{EmptyStorage, MockStorage}; use move_core_types::account_address::AccountAddress; @@ -237,7 +235,7 @@ impl TreeInserter { committed_block: Option, ) -> QuorumCert { gen_test_certificate( - &[self.signer.clone()], + std::slice::from_ref(&self.signer), block.block_info(), block.quorum_cert().certified_block().clone(), committed_block, diff --git a/consensus/src/transaction_filter/mod.rs b/consensus/src/transaction_filter/mod.rs deleted file mode 100644 index 6b9573cbe81..00000000000 --- a/consensus/src/transaction_filter/mod.rs +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_config::config::transaction_filter_type::Filter; -use aptos_crypto::HashValue; -use aptos_types::transaction::SignedTransaction; - -pub struct TransactionFilter { - filter: Filter, -} - -impl TransactionFilter { - pub(crate) fn new(filter: Filter) -> Self { - Self { filter } - } - - pub fn filter( - &self, - block_id: HashValue, - block_epoch: u64, - block_timestamp: u64, - txns: Vec, - ) -> Vec { - // Special case for no filter to avoid unnecessary iteration through all transactions in the default case - if self.filter.is_empty() { - return txns; - } - - txns.into_iter() - .filter(|txn| { - self.filter - .allows(block_id, block_epoch, block_timestamp, txn) - }) - .collect() - } -} - -#[cfg(test)] -mod test { - use crate::transaction_filter::TransactionFilter; - use aptos_config::config::transaction_filter_type::{Filter, Matcher}; - use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue, PrivateKey, SigningKey, Uniform}; - use aptos_types::{ - chain_id::ChainId, - move_utils::MemberId, - transaction::{ - EntryFunction, RawTransaction, SignedTransaction, TransactionExecutableRef, - TransactionPayload, - }, - }; - use move_core_types::account_address::AccountAddress; - - fn create_signed_transaction(function: MemberId) -> SignedTransaction { - let private_key = Ed25519PrivateKey::generate_for_testing(); - let public_key = private_key.public_key(); - let sender = AccountAddress::random(); - let sequence_number = 0; - let MemberId { - module_id, - member_id: function_id, - } = function; - - // TODO[Orderless]: Test with payload v2 format as well. - let payload = TransactionPayload::EntryFunction(EntryFunction::new( - module_id, - function_id, - vec![], - vec![], - )); - let raw_transaction = - RawTransaction::new(sender, sequence_number, payload, 0, 0, 0, ChainId::new(10)); - - SignedTransaction::new( - raw_transaction.clone(), - public_key.clone(), - private_key.sign(&raw_transaction).unwrap(), - ) - } - - fn get_transactions() -> Vec { - vec![ - create_signed_transaction(str::parse("0x0::test0::add").unwrap()), - create_signed_transaction(str::parse("0x1::test1::check").unwrap()), - create_signed_transaction(str::parse("0x2::test2::new").unwrap()), - create_signed_transaction(str::parse("0x3::test3::sub").unwrap()), - create_signed_transaction(str::parse("0x4::test4::mul").unwrap()), - create_signed_transaction(str::parse("0x5::test5::div").unwrap()), - create_signed_transaction(str::parse("0x6::test6::mod").unwrap()), - ] - } - - fn get_block_id_and_transactions() -> (HashValue, Vec) { - let txns = get_transactions(); - let block_id = HashValue::random(); - (block_id, txns) - } - - fn get_module_address(txn: &SignedTransaction) -> AccountAddress { - match txn.payload().executable_ref() { - Ok(TransactionExecutableRef::EntryFunction(entry_func)) => { - *entry_func.module().address() - }, - _ => panic!("Unexpected transaction payload"), - } - } - - fn get_module_name(txn: &SignedTransaction) -> String { - match txn.payload().executable_ref() { - Ok(TransactionExecutableRef::EntryFunction(entry_func)) => { - entry_func.module().name().to_string() - }, - _ => panic!("Unexpected transaction payload"), - } - } - - fn get_function_name(txn: &SignedTransaction) -> String { - match txn.payload().executable_ref() { - Ok(TransactionExecutableRef::EntryFunction(entry_func)) => { - entry_func.function().to_string() - }, - _ => panic!("Unexpected transaction payload"), - } - } - - #[test] - fn test_empty_filter() { - // Create an empty filter - let filter = TransactionFilter::new(Filter::empty()); - - // Verify that it returns all transactions - let (block_id, txns) = get_block_id_and_transactions(); - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - } - - #[test] - fn test_all_filter() { - // Create a filter that allows all transactions - let filter = TransactionFilter::new(Filter::empty().add_all_filter(true)); - - // Verify that it returns all transactions - let (block_id, txns) = get_block_id_and_transactions(); - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Create a filter that denies all transactions - let filter = TransactionFilter::new(Filter::empty().add_all_filter(false)); - - // Verify that it returns no transactions - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - #[test] - fn test_block_id_filter() { - // Create a filter that only allows transactions with a specific block ID - let (block_id, txns) = get_block_id_and_transactions(); - let filter = TransactionFilter::new( - Filter::empty() - .add_block_id_filter(true, block_id) - .add_all_filter(false), - ); - - // Verify that it returns all transactions with the specified block ID - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Verify that it returns no transactions with a different block ID - let different_block_id = HashValue::random(); - let filtered_txns = filter.filter(different_block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - - // Create a filter that denies transactions with a specific block ID - let filter = TransactionFilter::new( - Filter::empty() - .add_block_id_filter(false, block_id) - .add_all_filter(true), - ); - - // Verify that it returns all transactions except those with the specified block ID - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - - // Verify that it returns all transactions with a different block ID - let different_block_id = HashValue::random(); - let filtered_txns = filter.filter(different_block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - } - - #[test] - fn test_block_timestamp_greater_than_filter() { - // Create a filter that only allows transactions with a block timestamp greater than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_timestamp_greater_than_filter(true, 1000) - .add_all_filter(false), - ); - - // Verify that it returns no transactions with a block timestamp less than or equal to 1000 - let (block_id, txns) = get_block_id_and_transactions(); - for block_timestamp in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, 0, block_timestamp, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - // Verify that it returns all transactions with a block timestamp greater than 1000 - let filtered_txns = filter.filter(block_id, 0, 1001, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Create a filter that denies transactions with a block timestamp greater than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_timestamp_greater_than_filter(false, 1000) - .add_all_filter(true), - ); - - // Verify that it returns all transactions with a block timestamp less than or equal to 1000 - for block_timestamp in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, 0, block_timestamp, txns.clone()); - assert_eq!(filtered_txns, txns); - } - - // Verify that it returns no transactions with a block timestamp greater than 1000 - let filtered_txns = filter.filter(block_id, 0, 1001, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - #[test] - fn test_block_timestamp_less_than_filter() { - // Create a filter that only allows transactions with a block timestamp less than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_timestamp_less_than_filter(true, 1000) - .add_all_filter(false), - ); - - // Verify that it returns all transactions with a block timestamp less than 1000 - let (block_id, txns) = get_block_id_and_transactions(); - let filtered_txns = filter.filter(block_id, 0, 999, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Verify that it returns no transactions with a block timestamp greater than or equal to 1000 - for block_timestamp in [1000, 1001] { - let filtered_txns = filter.filter(block_id, 0, block_timestamp, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - // Create a filter that denies transactions with a block timestamp less than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_timestamp_less_than_filter(false, 1000) - .add_all_filter(true), - ); - - // Verify that it returns no transactions with a block timestamp less than 1000 - let filtered_txns = filter.filter(block_id, 0, 999, txns.clone()); - assert_eq!(filtered_txns, vec![]); - - // Verify that it returns all transactions with a block timestamp greater than or equal to 1000 - for block_timestamp in [1000, 1001] { - let filtered_txns = filter.filter(block_id, 0, block_timestamp, txns.clone()); - assert_eq!(filtered_txns, txns); - } - } - - #[test] - fn test_transaction_id_filter() { - // Create a filter that only allows transactions with a specific transaction ID (txn 0) - let (block_id, txns) = get_block_id_and_transactions(); - let filter = TransactionFilter::new( - Filter::empty() - .add_transaction_id_filter(true, txns[0].committed_hash()) - .add_all_filter(false), - ); - - // Verify that it returns the transaction with the specified ID - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, vec![txns[0].clone()]); - - // Create a filter that denies transactions with a specific transaction ID (txn 0) - let filter = TransactionFilter::new( - Filter::empty() - .add_transaction_id_filter(false, txns[0].committed_hash()) - .add_all_filter(true), - ); - - // Verify that it returns all transactions except the one with the specified ID - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[1..].to_vec()); - } - - #[test] - fn test_sender_filter() { - // Create a filter that only allows transactions from a specific sender (txn 0 and txn 1) - let (block_id, txns) = get_block_id_and_transactions(); - let filter = TransactionFilter::new( - Filter::empty() - .add_sender_filter(true, txns[0].sender()) - .add_sender_filter(true, txns[1].sender()) - .add_all_filter(false), - ); - - // Verify that it returns transactions from the specified senders - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[0..2].to_vec()); - - // Create a filter that denies transactions from a specific sender (txn 0, txn 1 and txn 2) - let filter = TransactionFilter::new( - Filter::empty() - .add_sender_filter(false, txns[0].sender()) - .add_sender_filter(false, txns[1].sender()) - .add_sender_filter(false, txns[2].sender()), - ); - - // Verify that it returns transactions from other senders - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[3..].to_vec()); - } - - #[test] - fn test_module_address_filter() { - // Create a filter that only allows transactions from a specific module address (txn 0 and txn 1) - let (block_id, txns) = get_block_id_and_transactions(); - let filter = TransactionFilter::new( - Filter::empty() - .add_module_address_filter(true, get_module_address(&txns[0])) - .add_module_address_filter(true, get_module_address(&txns[1])) - .add_all_filter(false), - ); - - // Verify that it returns transactions from the specified module addresses - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[0..2].to_vec()); - - // Create a filter that denies transactions from a specific module address (txn 0) - let filter = TransactionFilter::new( - Filter::empty().add_module_address_filter(false, get_module_address(&txns[0])), - ); - - // Verify that it returns transactions from other module addresses - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[1..].to_vec()); - } - - #[test] - fn test_entry_function_filter() { - // Create a filter that only allows transactions with specific entry functions (txn 0 and txn 1) - let filter = TransactionFilter::new( - Filter::empty() - .add_entry_function_filter( - true, - get_module_address(&get_transactions()[0]), - get_module_name(&get_transactions()[0]), - get_function_name(&get_transactions()[0]), - ) - .add_entry_function_filter( - true, - get_module_address(&get_transactions()[1]), - get_module_name(&get_transactions()[1]), - get_function_name(&get_transactions()[1]), - ) - .add_all_filter(false), - ); - - // Verify that it returns transactions with the specified entry functions - let (block_id, txns) = get_block_id_and_transactions(); - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[0..2].to_vec()); - - // Create a filter that denies transactions with specific entry functions (txn 0) - let filter = TransactionFilter::new(Filter::empty().add_entry_function_filter( - false, - get_module_address(&get_transactions()[0]), - get_module_name(&get_transactions()[0]), - get_function_name(&get_transactions()[0]), - )); - - // Verify that it returns transactions with other entry functions - let filtered_txns = filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[1..].to_vec()); - } - - #[test] - fn test_block_epoch_greater_than_filter() { - // Create a filter that only allows transactions with a block epoch greater than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_epoch_greater_than_filter(true, 1000) - .add_all_filter(false), - ); - - // Verify that it returns no transactions with a block epoch less than or equal to 1000 - let (block_id, txns) = get_block_id_and_transactions(); - for block_epoch in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, block_epoch, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - // Verify that it returns all transactions with a block epoch greater than 1000 - let filtered_txns = filter.filter(block_id, 1001, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Create a filter that denies transactions with a block epoch greater than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_epoch_greater_than_filter(false, 1000) - .add_all_filter(true), - ); - - // Verify that it returns all transactions with a block epoch less than or equal to 1000 - for block_epoch in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, block_epoch, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - } - - // Verify that it returns no transactions with a block epoch greater than 1000 - let filtered_txns = filter.filter(block_id, 1001, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - #[test] - fn test_block_epoch_less_than_filter() { - // Create a filter that only allows transactions with a block epoch less than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_epoch_less_than_filter(true, 1000) - .add_all_filter(false), - ); - - // Verify that it returns all transactions with a block epoch less than 1000 - let (block_id, txns) = get_block_id_and_transactions(); - let filtered_txns = filter.filter(block_id, 999, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - - // Verify that it returns no transactions with a block epoch greater than or equal to 1000 - for block_epoch in [1000, 1001] { - let filtered_txns = filter.filter(block_id, block_epoch, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - // Create a filter that denies transactions with a block epoch less than a specific value - let filter = TransactionFilter::new( - Filter::empty() - .add_block_epoch_less_than_filter(false, 1000) - .add_all_filter(true), - ); - - // Verify that it returns no transactions with a block epoch less than 1000 - let filtered_txns = filter.filter(block_id, 999, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - - // Verify that it returns all transactions with a block epoch greater than or equal to 1000 - for block_epoch in [1000, 1001] { - let filtered_txns = filter.filter(block_id, block_epoch, 0, txns.clone()); - assert_eq!(filtered_txns, txns); - } - } - - #[test] - fn test_matches_all_of_filter() { - // Create a filter that only matches transactions with epoch greater than 1000 and a specific sender (only txn 0) - let (block_id, txns) = get_block_id_and_transactions(); - let matchers = vec![ - Matcher::BlockEpochGreaterThan(1000), - Matcher::Sender(txns[0].sender()), - ]; - let filter = TransactionFilter::new( - Filter::empty() - .add_matches_all_of_filter(true, matchers) - .add_all_filter(false), - ); - - // Verify that it returns no transactions with block epoch less than or equal to 1000 - for block_epoch in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, block_epoch, 0, txns.clone()); - assert_eq!(filtered_txns, vec![]); - } - - // Verify that it returns transactions with block epoch greater than 1000 and the specified sender - let filtered_txns = filter.filter(block_id, 1001, 0, txns.clone()); - assert_eq!(filtered_txns, txns[0..1].to_vec()); - - // Create a filter that denies transactions with timestamp greater than 1000 and a specific sender (only txn 0) - let matchers = vec![ - Matcher::BlockTimeStampGreaterThan(1000), - Matcher::Sender(txns[0].sender()), - ]; - let filter = TransactionFilter::new( - Filter::empty() - .add_matches_all_of_filter(false, matchers) - .add_all_filter(true), - ); - - // Verify that it returns all transactions with block timestamp less than or equal to 1000 - for block_timestamp in [0, 999, 1000] { - let filtered_txns = filter.filter(block_id, 0, block_timestamp, txns.clone()); - assert_eq!(filtered_txns, txns); - } - - // Verify that it returns no transactions with block timestamp greater than 1000 and the specified sender - let filtered_txns = filter.filter(block_id, 0, 1001, txns.clone()); - assert_eq!(filtered_txns, txns[1..].to_vec()); - } - - #[test] - fn test_composite_allow_list_filter() { - // Create a filter that only allows transactions based on multiple criteria - let (block_id, txns) = get_block_id_and_transactions(); - let filter_string = format!( - r#" - rules: - - Allow: - Sender: "{}" - - Allow: - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" - - Allow: - EntryFunction: - - "0000000000000000000000000000000000000000000000000000000000000002" - - test2 - - new - - Allow: - EntryFunction: - - "0000000000000000000000000000000000000000000000000000000000000003" - - test3 - - sub - - Deny: All - "#, - txns[0].sender().to_standard_string() - ); - let filter = serde_yaml::from_str::(&filter_string).unwrap(); - let allow_list_filter = TransactionFilter::new(filter); - - // Verify that only the first four transactions are allowed - let filtered_txns = allow_list_filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[0..4].to_vec()); - } - - #[test] - fn test_composite_block_list_filter() { - // Create a filter that denies transactions based on multiple criteria - let (block_id, txns) = get_block_id_and_transactions(); - let filter_string = format!( - r#" - rules: - - Deny: - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" - - Deny: - Sender: "{}" - - Deny: - EntryFunction: - - "0000000000000000000000000000000000000000000000000000000000000002" - - test2 - - new - - Deny: - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000003" - - Allow: All - "#, - txns[1].sender().to_standard_string() - ); - let filter = serde_yaml::from_str::(&filter_string).unwrap(); - let block_list_filter = TransactionFilter::new(filter); - - // Verify that the first four transactions are denied - let filtered_txns = block_list_filter.filter(block_id, 0, 0, txns.clone()); - assert_eq!(filtered_txns, txns[4..].to_vec()); - } - - #[test] - fn test_composite_matches_all_of_filter() { - // Create a filter that denies transactions based on the matches all of rule - let (block_id, txns) = get_block_id_and_transactions(); - let filter_string = format!( - r#" - rules: - - Deny: - MatchesAllOf: - - Sender: "{}" - - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" - - BlockEpochGreaterThan: 10 - - Deny: - MatchesAllOf: - - Sender: "{}" - - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" - - BlockEpochGreaterThan: 10 - - BlockTimeStampGreaterThan: 1000 - - Deny: - MatchesAllOf: - - Sender: "{}" - - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000002" - - BlockEpochGreaterThan: 10 - - BlockTimeStampGreaterThan: 1000 - - BlockId: "{}" - - Allow: All - "#, - txns[0].sender().to_standard_string(), - txns[1].sender().to_standard_string(), - txns[2].sender().to_standard_string(), - block_id.to_hex() - ); - let filter = serde_yaml::from_str::(&filter_string).unwrap(); - let block_list_filter = TransactionFilter::new(filter); - - // Filter transactions with a block epoch of 11, timestamp of 1001, and the expected block ID - let filtered_txns = block_list_filter.filter(block_id, 11, 1001, txns.clone()); - - // Verify that only the first three transactions are denied - assert_eq!(filtered_txns, txns[3..].to_vec()); - - // Filter transactions with a block epoch of 11, timestamp of 1001, and a random block ID - let random_block_id = HashValue::random(); - let filtered_txns = block_list_filter.filter(random_block_id, 11, 1001, txns.clone()); - - // Verify that only the first two transactions are denied - assert_eq!(filtered_txns, txns[2..].to_vec()); - - // Filter transactions with a block epoch of 11, timestamp of 999, and the expected block ID - let filtered_txns = block_list_filter.filter(block_id, 11, 999, txns.clone()); - - // Verify that only the first transaction is denied - assert_eq!(filtered_txns, txns[1..].to_vec()); - } -} diff --git a/consensus/src/twins/basic_twins_test.rs b/consensus/src/twins/basic_twins_test.rs index 9893efebd5c..524f2bbf3e7 100644 --- a/consensus/src/twins/basic_twins_test.rs +++ b/consensus/src/twins/basic_twins_test.rs @@ -25,6 +25,7 @@ use std::collections::HashMap; /// /// Run the test: /// cargo xtest -p consensus basic_start_test -- --nocapture +#[ignore] fn basic_start_test() { let runtime = consensus_runtime(); let mut playground = NetworkPlayground::new(runtime.handle().clone()); diff --git a/consensus/src/twins/twins_node.rs b/consensus/src/twins/twins_node.rs index a469bc6094a..a1b511cb8c9 100644 --- a/consensus/src/twins/twins_node.rs +++ b/consensus/src/twins/twins_node.rs @@ -279,7 +279,6 @@ impl SMRNode { config.base.waypoint = WaypointConfig::FromConfig(waypoint); // Disable timeout in twins test to avoid flakiness config.consensus.round_initial_timeout_ms = 2_000_000; - config.consensus.enable_pipeline = false; let author = author_from_config(&config); diff --git a/consensus/src/txn_hash_and_authenticator_deduper.rs b/consensus/src/txn_hash_and_authenticator_deduper.rs index 3311d0c9534..ff139a63654 100644 --- a/consensus/src/txn_hash_and_authenticator_deduper.rs +++ b/consensus/src/txn_hash_and_authenticator_deduper.rs @@ -333,9 +333,7 @@ mod tests { .sign(&sender.privkey, sender.pubkey) .unwrap() .into_inner(); - let txns: Vec<_> = std::iter::repeat(txn.clone()) - .take(PERF_TXN_PER_BLOCK) - .collect(); + let txns: Vec<_> = std::iter::repeat_n(txn.clone(), PERF_TXN_PER_BLOCK).collect(); let expected = block(vec![&txn]); let deduped_txns = deduper.dedup(txns.clone()); assert_eq!(expected.len(), deduped_txns.len()); @@ -375,9 +373,7 @@ mod tests { .sign(&sender.privkey, sender.pubkey) .unwrap() .into_inner(); - let txns: Vec<_> = std::iter::repeat(txn.clone()) - .take(PERF_TXN_PER_BLOCK) - .collect(); + let txns: Vec<_> = std::iter::repeat_n(txn.clone(), PERF_TXN_PER_BLOCK).collect(); let expected = block(vec![&txn]); let deduped_txns = deduper.dedup(txns.clone()); assert_eq!(expected.len(), deduped_txns.len()); diff --git a/crates/aptos-admin-service/Cargo.toml b/crates/aptos-admin-service/Cargo.toml index a430be43bf9..1b7111a619c 100644 --- a/crates/aptos-admin-service/Cargo.toml +++ b/crates/aptos-admin-service/Cargo.toml @@ -31,3 +31,7 @@ hyper = { workspace = true } sha256 = { workspace = true } tokio = { workspace = true } url = { workspace = true } + +[target.'cfg(unix)'.dependencies] +jemalloc-ctl = { workspace = true } +jemalloc-sys = { workspace = true } diff --git a/crates/aptos-admin-service/src/server/malloc.rs b/crates/aptos-admin-service/src/server/malloc.rs new file mode 100644 index 00000000000..a1762c3451c --- /dev/null +++ b/crates/aptos-admin-service/src/server/malloc.rs @@ -0,0 +1,76 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_system_utils::utils::{reply_with, reply_with_status}; +use hyper::{Body, Response, StatusCode}; +use std::{ + ffi::{CStr, CString}, + os::raw::{c_char, c_void}, + time::SystemTime, +}; + +const PROFILE_PATH_PREFIX: &str = "/tmp/heap-profile"; + +unsafe extern "C" fn write_cb(buf: *mut c_void, s: *const c_char) { + let out = unsafe { &mut *(buf as *mut Vec) }; + let stats_cstr = unsafe { CStr::from_ptr(s).to_bytes() }; + // We do not want any memory allocation in the callback. + let len = std::cmp::min(out.capacity(), stats_cstr.len()); + out.extend_from_slice(&stats_cstr[0..len]); +} + +fn get_jemalloc_stats_string(max_len: usize) -> anyhow::Result { + let _ = jemalloc_ctl::epoch::advance(); + + let mut stats = Vec::with_capacity(max_len); + unsafe { + jemalloc_sys::malloc_stats_print( + Some(write_cb), + &mut stats as *mut _ as *mut c_void, + std::ptr::null(), + ); + } + Ok(String::from_utf8(stats)?) +} + +pub fn handle_malloc_stats_request(max_len: usize) -> hyper::Result> { + match get_jemalloc_stats_string(max_len) { + Ok(stats) => Ok(reply_with(Vec::new(), Body::from(stats))), + Err(e) => Ok(reply_with_status( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to get malloc stats: {e}"), + )), + } +} + +fn dump_heap_profile() -> anyhow::Result { + let _ = jemalloc_ctl::epoch::advance(); + + let key = b"prof.dump\0"; + let path = format!( + "{}.{}", + PROFILE_PATH_PREFIX, + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_millis() + ); + let value = CString::new(path.clone())?; + unsafe { + jemalloc_ctl::raw::write(key, value.as_ptr()) + .map_err(|e| anyhow::anyhow!("prof.dump error: {e}"))?; + } + Ok(path) +} + +pub fn handle_dump_profile_request() -> hyper::Result> { + match dump_heap_profile() { + Ok(path) => Ok(reply_with( + Vec::new(), + Body::from(format!("Successfully dumped heap profile to {path}")), + )), + Err(e) => Ok(reply_with_status( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to dump heap profile: {e}"), + )), + } +} diff --git a/crates/aptos-admin-service/src/server/mod.rs b/crates/aptos-admin-service/src/server/mod.rs index bc72d791ed8..9badc2fc7ed 100644 --- a/crates/aptos-admin-service/src/server/mod.rs +++ b/crates/aptos-admin-service/src/server/mod.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_config::config::{AuthenticationConfig, NodeConfig}; +use aptos_config::config::{AdminServiceConfig, AuthenticationConfig, NodeConfig}; use aptos_consensus::{ persistent_liveness_storage::StorageWriteProxy, quorum_store::quorum_store_db::QuorumStoreDB, }; @@ -27,11 +27,13 @@ use std::{ use tokio::runtime::Runtime; mod consensus; +#[cfg(unix)] +mod malloc; mod mempool; #[derive(Default)] pub struct Context { - authentication_configs: Vec, + config: AdminServiceConfig, aptos_db: RwLock>>, consensus_db: RwLock>>, @@ -67,9 +69,10 @@ impl AdminService { /// Starts the admin service that listens on the configured address and handles various endpoint /// requests. pub fn new(node_config: &NodeConfig) -> Self { + let config = node_config.admin_service.clone(); // Fetch the service port and address - let service_port = node_config.admin_service.port; - let service_address = node_config.admin_service.address.clone(); + let service_port = config.port; + let service_address = config.address.clone(); // Create the admin service socket address let address: SocketAddr = (service_address.as_str(), service_port) @@ -86,16 +89,15 @@ impl AdminService { // Create a runtime for the admin service let runtime = aptos_runtimes::spawn_named_runtime("admin".into(), None); + // TODO(grao): Consider support enabling the service through an authenticated request. + let enabled = config.enabled.unwrap_or(false); let admin_service = Self { runtime, context: Arc::new(Context { - authentication_configs: node_config.admin_service.authentication_configs.clone(), + config, ..Default::default() }), }; - - // TODO(grao): Consider support enabling the service through an authenticated request. - let enabled = node_config.admin_service.enabled.unwrap_or(false); admin_service.start(address, enabled); admin_service @@ -150,10 +152,10 @@ impl AdminService { } let mut authenticated = false; - if context.authentication_configs.is_empty() { + if context.config.authentication_configs.is_empty() { authenticated = true; } else { - for authentication_config in &context.authentication_configs { + for authentication_config in &context.config.authentication_configs { match authentication_config { AuthenticationConfig::PasscodeSha256(passcode_sha256) => { let query = req.uri().query().unwrap_or(""); @@ -183,6 +185,12 @@ impl AdminService { (hyper::Method::GET, "/profilez") => handle_cpu_profiling_request(req).await, #[cfg(target_os = "linux")] (hyper::Method::GET, "/threadz") => handle_thread_dump_request(req).await, + #[cfg(unix)] + (hyper::Method::GET, "/malloc/stats") => { + malloc::handle_malloc_stats_request(context.config.malloc_stats_max_len) + }, + #[cfg(unix)] + (hyper::Method::GET, "/malloc/dump_profile") => malloc::handle_dump_profile_request(), (hyper::Method::GET, "/debug/consensus/consensusdb") => { let consensus_db = context.consensus_db.read().clone(); if let Some(consensus_db) = consensus_db { @@ -208,13 +216,10 @@ impl AdminService { (hyper::Method::GET, "/debug/consensus/block") => { let consensus_db = context.consensus_db.read().clone(); let quorum_store_db = context.quorum_store_db.read().clone(); - if consensus_db.is_some() && quorum_store_db.is_some() { - consensus::handle_dump_block_request( - req, - consensus_db.unwrap(), - quorum_store_db.unwrap(), - ) - .await + if let Some(consensus_db) = consensus_db + && let Some(quorum_store_db) = quorum_store_db + { + consensus::handle_dump_block_request(req, consensus_db, quorum_store_db).await } else { Ok(reply_with_status( StatusCode::NOT_FOUND, @@ -224,12 +229,9 @@ impl AdminService { }, (hyper::Method::GET, "/debug/mempool/parking-lot/addresses") => { let mempool_client_sender = context.mempool_client_sender.read().clone(); - if mempool_client_sender.is_some() { - mempool::mempool_handle_parking_lot_address_request( - req, - mempool_client_sender.unwrap(), - ) - .await + if let Some(mempool_client_sender) = mempool_client_sender { + mempool::mempool_handle_parking_lot_address_request(req, mempool_client_sender) + .await } else { Ok(reply_with_status( StatusCode::NOT_FOUND, diff --git a/crates/aptos-build-info/src/lib.rs b/crates/aptos-build-info/src/lib.rs index bd0b7f663c3..ba59f06cb4e 100644 --- a/crates/aptos-build-info/src/lib.rs +++ b/crates/aptos-build-info/src/lib.rs @@ -125,9 +125,12 @@ mod tests { let build_branch = String::from("branch-1"); let build_tag = String::from("release-1"); - std::env::set_var("GIT_SHA", commit_hash.clone()); - std::env::set_var("GIT_BRANCH", build_branch.clone()); - std::env::set_var("GIT_TAG", build_tag.clone()); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + std::env::set_var("GIT_SHA", commit_hash.clone()); + std::env::set_var("GIT_BRANCH", build_branch.clone()); + std::env::set_var("GIT_TAG", build_tag.clone()); + } let info = get_build_information(); diff --git a/crates/aptos-compression/src/tests.rs b/crates/aptos-compression/src/tests.rs index 7062c86113d..e191c1264b3 100644 --- a/crates/aptos-compression/src/tests.rs +++ b/crates/aptos-compression/src/tests.rs @@ -27,7 +27,7 @@ const MIB: usize = 1024 * 1024; #[test] fn test_basic_compression() { // Test compress random bytes - let raw_bytes: Vec<_> = (0..MIB).map(|_| rand::thread_rng().gen::()).collect(); + let raw_bytes: Vec<_> = (0..MIB).map(|_| rand::thread_rng().r#gen::()).collect(); test_compress_and_decompress(raw_bytes); // Test epoch ending ledger infos diff --git a/crates/aptos-crypto-derive/src/lib.rs b/crates/aptos-crypto-derive/src/lib.rs index b4edac8e5eb..39aafc9b5d6 100644 --- a/crates/aptos-crypto-derive/src/lib.rs +++ b/crates/aptos-crypto-derive/src/lib.rs @@ -115,15 +115,15 @@ pub fn silent_display(source: TokenStream) -> TokenStream { let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - let gen = quote! { + quote! { // In order to ensure that secrets are never leaked, Display is elided impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(f, "", stringify!(#name)) } } - }; - gen.into() + } + .into() } #[proc_macro_derive(SilentDebug)] @@ -132,15 +132,15 @@ pub fn silent_debug(source: TokenStream) -> TokenStream { let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - let gen = quote! { + quote! { // In order to ensure that secrets are never leaked, Debug is elided impl #impl_generics ::std::fmt::Debug for #name #ty_generics #where_clause { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(f, "", stringify!(#name)) } } - }; - gen.into() + } + .into() } #[proc_macro_attribute] @@ -154,7 +154,7 @@ pub fn deserialize_key(source: TokenStream) -> TokenStream { let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); let name = &ast.ident; let name_string = find_key_name(&ast, name.to_string()); - let gen = quote! { + quote! { impl<'de> ::serde::Deserialize<'de> for #name { fn deserialize(deserializer: D) -> std::result::Result where @@ -179,8 +179,7 @@ pub fn deserialize_key(source: TokenStream) -> TokenStream { } } } - }; - gen.into() + }.into() } /// Serialize into a human readable format where applicable @@ -189,7 +188,7 @@ pub fn serialize_key(source: TokenStream) -> TokenStream { let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); let name = &ast.ident; let name_string = find_key_name(&ast, name.to_string()); - let gen = quote! { + quote! { impl ::serde::Serialize for #name { fn serialize(&self, serializer: S) -> std::result::Result where @@ -208,8 +207,8 @@ pub fn serialize_key(source: TokenStream) -> TokenStream { } } } - }; - gen.into() + } + .into() } fn find_key_name(ast: &DeriveInput, name: String) -> String { @@ -371,9 +370,10 @@ pub fn hasher_dispatch(input: TokenStream) -> TokenStream { let param = if item.generics.params.is_empty() { quote!() } else { - let args = proc_macro2::TokenStream::from_iter( - std::iter::repeat(quote!((),)).take(item.generics.params.len()), - ); + let args = proc_macro2::TokenStream::from_iter(std::iter::repeat_n( + quote!((),), + item.generics.params.len(), + )); quote!(<#args>) }; @@ -465,6 +465,50 @@ pub fn bcs_crypto_hash_dispatch(input: TokenStream) -> TokenStream { out.into() } +/// Derive macro for structs acting as witnesses in Sigma protocols. +/// +/// Applies to structs with named fields only. +#[proc_macro_derive(SigmaProtocolWitness)] +pub fn derive_sigma_protocol_witness(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + let fields = if let syn::Data::Struct(data) = &input.data { + match &data.fields { + syn::Fields::Named(fields_named) => &fields_named.named, + _ => panic!("SigmaProtocolWitness derive only supports named fields"), + } + } else { + panic!("SigmaProtocolWitness derive only supports structs"); + }; + + let field_names: Vec<_> = fields.iter().map(|f| &f.ident).collect(); + + let expanded = quote! { + impl sigma_protocol::Witness for #name { + type Scalar = Scalar; + + fn scaled_add(self, other: &Self, c: E::ScalarField) -> Self { + Self { + #( + #field_names: self.#field_names.scaled_add(&other.#field_names, c), + )* + } + } + + fn rand(&self, rng: &mut R) -> Self { + Self { + #( + #field_names: self.#field_names.rand(rng), + )* + } + } + } + }; + + TokenStream::from(expanded) +} + fn add_trait_bounds(mut generics: syn::Generics) -> syn::Generics { for param in generics.params.iter_mut() { if let syn::GenericParam::Type(type_param) = param { diff --git a/crates/aptos-crypto/Cargo.toml b/crates/aptos-crypto/Cargo.toml index 5437518b8ee..191e788f5e7 100644 --- a/crates/aptos-crypto/Cargo.toml +++ b/crates/aptos-crypto/Cargo.toml @@ -17,32 +17,43 @@ aes-gcm = { workspace = true } anyhow = { workspace = true } aptos-crypto-derive = { workspace = true } arbitrary = { workspace = true, features = ["derive"], optional = true } +ark-bls12-381 = { workspace = true } ark-bn254 = { workspace = true } ark-ec = { workspace = true } ark-ff = { workspace = true } ark-groth16 = { workspace = true } +ark-poly = { workspace = true } +ark-relations = { workspace = true } +ark-serialize = { workspace = true } +ark-snark = { workspace = true } ark-std = { workspace = true } base64 = { workspace = true } bcs = { workspace = true } +bls12_381 = { workspace = true } blst = { workspace = true } +blstrs = { workspace = true } bulletproofs = { workspace = true } bytes = { workspace = true } curve25519-dalek = { workspace = true } curve25519-dalek-ng = { workspace = true } digest = { workspace = true } +dudect-bencher = { workspace = true } ed25519-dalek = { workspace = true } ff = { workspace = true } +group = { workspace = true } hex = { workspace = true } hkdf = { workspace = true } +itertools = { workspace = true } libsecp256k1 = { workspace = true } merlin = { workspace = true } more-asserts = { workspace = true } neptune = { workspace = true } num-bigint = { workspace = true } num-integer = { workspace = true } +num-traits = { workspace = true } once_cell = { workspace = true } p256 = { workspace = true } -poseidon-ark = { workspace = true } +pairing = { workspace = true } proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } rand = { workspace = true } @@ -64,8 +75,12 @@ x25519-dalek = { workspace = true } [dev-dependencies] arbitrary = { workspace = true, features = ["derive"] } ark-bls12-381 = { workspace = true } +ark-bls12-381-old = { package = "ark-bls12-381", version = "0.4.0" } ark-bn254 = { workspace = true } +ark-ec-old = { package = "ark-ec", version = "0.4.0" } +ark-ff-old = { package = "ark-ff", version = "0.4.0" } ark-serialize = { workspace = true } +ark-serialize-old = { package = "ark-serialize", version = "0.4.0" } ark-std = { workspace = true } bitvec = { workspace = true } blake2 = { workspace = true } @@ -79,6 +94,7 @@ trybuild = { workspace = true } [features] default = [] +arkworks-upgrade-compat-test = [] assert-private-keys-not-cloneable = [] cloneable-private-keys = [] fuzzing = ["proptest", "proptest-derive", "cloneable-private-keys", "arbitrary"] @@ -93,15 +109,19 @@ name = "ark_bn254" harness = false [[bench]] -name = "bls12381" +name = "ark_groth16" harness = false [[bench]] -name = "bulletproofs" +name = "ark_rand" harness = false [[bench]] -name = "bulletproofs_batch_verify" +name = "bls12381" +harness = false + +[[bench]] +name = "bulletproofs" harness = false [[bench]] @@ -117,13 +137,19 @@ name = "noise" harness = false [[bench]] -name = "ristretto255" +name = "random" harness = false [[bench]] -name = "secp256k1" +name = "ristretto255" harness = false [[bench]] -name = "poseidon_bn254" +name = "secp256k1" harness = false + +[[example]] +name = "is_blstrs_constant_time" + +[[example]] +name = "is_zkcrypto_constant_time" diff --git a/crates/aptos-crypto/benches/.gitignore b/crates/aptos-crypto/benches/.gitignore new file mode 100644 index 00000000000..afed0735dc9 --- /dev/null +++ b/crates/aptos-crypto/benches/.gitignore @@ -0,0 +1 @@ +*.csv diff --git a/crates/aptos-crypto/benches/README.md b/crates/aptos-crypto/benches/README.md new file mode 100644 index 00000000000..378f91817f8 --- /dev/null +++ b/crates/aptos-crypto/benches/README.md @@ -0,0 +1,21 @@ +# Benchmarks + +## Batched Bulletproofs and DeKART + +Go to `aptos-crypto`: +``` +cd crates/aptos-crypto +``` + +Install [`criterion-means`](https://crates.io/crates/cargo-criterion-means): + +``` +cargo install criterion-means +``` + +Run the Bulletproof and DeKART benchmarks in one line via: +``` +./run-range-proof-benches.sh +``` + +This will generate CSV data with the benchmark data, format it as Markdown and copy it to your clipboard! diff --git a/crates/aptos-crypto/benches/ark_bls12_381.rs b/crates/aptos-crypto/benches/ark_bls12_381.rs index 77d1feb751d..d0b05c21d4a 100644 --- a/crates/aptos-crypto/benches/ark_bls12_381.rs +++ b/crates/aptos-crypto/benches/ark_bls12_381.rs @@ -15,9 +15,9 @@ use aptos_crypto::test_utils::random_bytes; use ark_bls12_381::{Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; use ark_ec::{ hashing::HashToCurve, pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, - Group, + PrimeGroup, }; -use ark_ff::{One, UniformRand, Zero}; +use ark_ff::{AdditiveGroup, One, UniformRand, Zero}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::test_rng; use criterion::{BenchmarkId, Criterion}; diff --git a/crates/aptos-crypto/benches/ark_bn254.rs b/crates/aptos-crypto/benches/ark_bn254.rs index ad6ce0d33d9..d931828aed5 100644 --- a/crates/aptos-crypto/benches/ark_bn254.rs +++ b/crates/aptos-crypto/benches/ark_bn254.rs @@ -12,8 +12,8 @@ use crate::bench_utils::{ bench_function_sub, }; use ark_bn254::{Bn254, Fq, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; -use ark_ec::{pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, Group}; -use ark_ff::{UniformRand, Zero}; +use ark_ec::{pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, PrimeGroup}; +use ark_ff::{AdditiveGroup, UniformRand, Zero}; use ark_groth16::Groth16; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::test_rng; diff --git a/crates/aptos-crypto/benches/ark_groth16.rs b/crates/aptos-crypto/benches/ark_groth16.rs new file mode 100644 index 00000000000..68c8008228a --- /dev/null +++ b/crates/aptos-crypto/benches/ark_groth16.rs @@ -0,0 +1,151 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 +extern crate criterion; + +use ark_bn254::Bn254; +use ark_ff::Field; +use ark_groth16::Groth16; +use ark_relations::r1cs::{ + ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, +}; +use ark_snark::SNARK; +use ark_std::rand::{thread_rng, Rng}; +use criterion::{ + criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId, Criterion, +}; + +/// Target dimensions for the Keyless NP relation +const NUM_CONSTRAINTS: usize = 1_438_805; +const NUM_VARIABLES: usize = 1_406_686; // includes 1 public input + +/// Helper: produce a witness of length (NUM_VARIABLES - 1) with 128-bit field elements. +fn random_128bit_witness(len: usize) -> Vec { + let mut rng = thread_rng(); + // Sample u128 and embed into Fr; BN254 field is ~254 bits, so u128 values fit naturally. + (0..len) + .map(|_| { + let x: u128 = rng.r#gen(); + F::from(x) + }) + .collect() +} + +/// Minimal dummy circuit with precise size. +#[derive(Clone)] +struct SizedCircuit +where + F: Field, +{ + num_constraints: usize, + num_variables: usize, + // Optional witness vector; when None, witnesses default to 1. + // When Some(vec), `vec.len()` must be num_variables - 1 (excluding x0). + witness: Option>, +} + +impl ConstraintSynthesizer for SizedCircuit { + fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { + // Public input x0 = 1 + let x0 = cs.new_input_variable(|| Ok(F::one()))?; + + // Allocate witnesses so total vars == num_variables + // If self.witness is provided, use those values. Otherwise use 1s. + let mut vars = Vec::with_capacity(self.num_variables); + vars.push(x0); + + if let Some(w) = self.witness { + assert_eq!(w.len(), self.num_variables - 1, "witness length mismatch"); + for val in w { + vars.push(cs.new_witness_variable(|| Ok(val))?); + } + } else { + for _ in 0..(self.num_variables - 1) { + vars.push(cs.new_witness_variable(|| Ok(F::one()))?); + } + } + + // Enforce `v * 1 = v` repeatedly to reach exactly num_constraints constraints. + // This preserves the matrix size but does NOT force any relation between + // different variables—so arbitrary (e.g., 128-bit) witnesses are valid. + let one: LinearCombination = LinearCombination::from((F::one(), Variable::One)); + // We'll cycle across the witness indices [1..num_variables) to touch them uniformly. + let w_count = self.num_variables.saturating_sub(1).max(1); + for i in 0..self.num_constraints { + let idx = 1 + (i % w_count); // skip x0 at index 0 + let v: LinearCombination = LinearCombination::from(vars[idx]); + cs.enforce_constraint(v.clone(), one.clone(), v)?; + } + + Ok(()) + } +} + +/// Build the proving key once (excluded from the benchmark measurements). +fn setup_bn254_pk() -> (SizedCircuit, ark_groth16::ProvingKey) { + let mut rng = thread_rng(); + // Shape-only circuit (no witness values needed) + let circuit = SizedCircuit { + num_variables: NUM_VARIABLES, + num_constraints: NUM_CONSTRAINTS, + witness: None, + }; + let (pk, _vk) = Groth16::::circuit_specific_setup(circuit.clone(), &mut rng) + .expect("setup should succeed"); + + println!("a_query: {}", pk.a_query.len()); + println!("b_g1_query: {}", pk.b_g1_query.len()); + println!("b_g2_query: {}", pk.b_g2_query.len()); + // TODO: |h_query| = the smallest power of 2 less than the # of constraints. Why? And what is it? + println!("h_query: {}", pk.h_query.len()); + println!("l_query: {}", pk.l_query.len()); + + (circuit, pk) +} + +fn bench_group(c: &mut Criterion) { + // One-time setup (not timed) + let (mut circuit, pk) = setup_bn254_pk(); + + let mut group = c.benchmark_group("ark_groth16"); + + // Tweak these knobs if runs are too long/short on your machine. + group.sample_size(10); + group.warm_up_time(std::time::Duration::from_secs(2)); + group.measurement_time(std::time::Duration::from_secs(30)); + group.throughput(criterion::Throughput::Elements(NUM_CONSTRAINTS as u64)); + + // Benchmark the circuit with a norm-1 witness vector + bench_bn254_circuit(circuit.clone(), &pk, &mut group, "1"); + + // Benchmark the circuit with a "large-norm" witness vector: each entry is 128-bit. + let witness = random_128bit_witness(NUM_VARIABLES - 1); + circuit.witness = Some(witness); + bench_bn254_circuit(circuit, &pk, &mut group, "128-bit"); + + group.finish(); +} + +fn bench_bn254_circuit( + circuit: SizedCircuit, + pk: &ark_groth16::ProvingKey, + group: &mut BenchmarkGroup, + norm: &str, +) { + group.bench_function( + BenchmarkId::new("bn254/prove/multithreaded/norm", norm.to_string()), + |b| { + b.iter(|| { + // Clone because Groth16::prove consumes the circuit + let proof = Groth16::::prove(pk, circuit.clone(), &mut thread_rng()) + .expect("proving"); + criterion::black_box(proof); + }); + }, + ); +} + +criterion_group!( + name = ark_groth16; + config = Criterion::default().sample_size(10); + targets = bench_group); +criterion_main!(ark_groth16); diff --git a/crates/aptos-crypto/benches/ark_rand.rs b/crates/aptos-crypto/benches/ark_rand.rs new file mode 100644 index 00000000000..6fb47dcbcc6 --- /dev/null +++ b/crates/aptos-crypto/benches/ark_rand.rs @@ -0,0 +1,45 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::random::{sample_field_element, scalar_from_uniform_be_bytes}; +use ark_ff::PrimeField; +use criterion::{criterion_group, criterion_main, Criterion}; +use rand::thread_rng; + +/// Benchmarks rejection sampling for an arbitrary field F +fn bench_sample_field_element_generic(c: &mut Criterion, curve_name: &str) { + let mut rng = thread_rng(); + // results are similar for e.g. rand::rngs::StdRng::seed_from_u64(42); + + c.bench_function(&format!("{}: sample_field_element", curve_name), |b| { + b.iter(|| { + let _scalar: F = sample_field_element(&mut rng); + }); + }); +} + +/// Benchmarks double-sized byte reduction for an arbitrary field F +fn bench_scalar_from_uniform_be_bytes_generic(c: &mut Criterion, curve_name: &str) { + let mut rng = thread_rng(); + + c.bench_function( + &format!("{}: scalar_from_uniform_be_bytes", curve_name), + |b| { + b.iter(|| { + let _scalar: F = scalar_from_uniform_be_bytes(&mut rng); + }); + }, + ); +} + +/// Runs benchmarks for multiple fields +fn criterion_benchmark(c: &mut Criterion) { + bench_sample_field_element_generic::(c, "BN254"); + bench_scalar_from_uniform_be_bytes_generic::(c, "BN254"); + + bench_sample_field_element_generic::(c, "BLS12-381"); + bench_scalar_from_uniform_be_bytes_generic::(c, "BLS12-381"); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/crates/aptos-crypto/benches/bulletproofs.rs b/crates/aptos-crypto/benches/bulletproofs.rs index 493a47230e4..cbceb80cd85 100644 --- a/crates/aptos-crypto/benches/bulletproofs.rs +++ b/crates/aptos-crypto/benches/bulletproofs.rs @@ -9,6 +9,28 @@ use criterion::{measurement::Measurement, BenchmarkGroup, BenchmarkId, Criterion use curve25519_dalek_ng::scalar::Scalar; use merlin::Transcript; use rand::{thread_rng, Rng}; +use rand_core::RngCore; + +const DST: &[u8] = b"dummy DST"; + +/// WARNING: Do not change this, since our range proof benchmark instructions in README.md rely on it. +const GROUP_NAME: &str = "bulletproofs"; + +/// WARNING: See `GROUP_NAME`. +const PROVE_BENCH_ID: &str = "range_prove"; +/// WARNING: See `GROUP_NAME`. +const VERIFY_BENCH_ID: &str = "range_verify"; + +/// WARNING: See `GROUP_NAME`. +fn get_benchmark_subid(batch_size: usize, num_bits: usize) -> String { + format!("batch={}/bits={}", batch_size, num_bits) +} + +/// WARNING: These are the relevant batch sizes we want benchmarked to compare against DeKART +const BATCH_SIZES: [usize; 11] = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]; + +/// WARNING: These are the relevant bit widths we want benchmarked to compare against DeKART +const BIT_WIDTHS: [usize; 4] = [8, 16, 32, 64]; fn get_values(num_bits: usize, batch_size: usize) -> (Vec, Vec) { let mut rng = thread_rng(); @@ -19,21 +41,28 @@ fn get_values(num_bits: usize, batch_size: usize) -> (Vec, Vec) { // Sigh, some RngCore incompatibilities I don't want to deal with right now. let b = (0..batch_size) - .map(|_| Scalar::hash_from_bytes::(b"some random blinder")) + .map(|_| { + let mut scalar = [0u8; 32]; + rng.fill_bytes(&mut scalar); + + Scalar::from_bytes_mod_order(scalar) + }) .collect::>(); (v, b) } fn bench_group(c: &mut Criterion) { - let mut group = c.benchmark_group("bulletproofs"); + let mut group = c.benchmark_group(GROUP_NAME); - for num_bits in [32, 64] { - range_proof_deserialize(&mut group, num_bits); - } + // NOTE: Commented out since these take < 1 microsecond. + // for num_bits in [32, 64] { + // range_proof_deserialize(&mut group, num_bits); + // } - for batch_size in [1, 2] { - for num_bits in [32, 64] { + // WARNING: These test cases were picked to benchmark against univariate DeKART + for batch_size in BATCH_SIZES { + for num_bits in BIT_WIDTHS { range_prove(&mut group, num_bits, batch_size); range_verify(&mut group, num_bits, batch_size); } @@ -48,15 +77,12 @@ fn range_prove(g: &mut BenchmarkGroup, num_bits: usize, batch g.throughput(Throughput::Elements(batch_size as u64)); g.bench_function( - BenchmarkId::new( - "range_prove", - format!("batch={}/bits={}", batch_size, num_bits), - ), + BenchmarkId::new(PROVE_BENCH_ID, get_benchmark_subid(batch_size, num_bits)), move |b| { b.iter_with_setup( || get_values(num_bits, batch_size), |(v, b)| { - let mut t_prv = Transcript::new(b"some DST"); + let mut t_prv = Transcript::new(DST); assert!(RangeProof::prove_multiple( &bg, &pg, @@ -72,6 +98,8 @@ fn range_prove(g: &mut BenchmarkGroup, num_bits: usize, batch ); } +#[allow(dead_code)] +/// Note: For now, this only benchmarks deserialization of a range proof for 1 value. fn range_proof_deserialize(g: &mut BenchmarkGroup, num_bits: usize) { let bp_gens = BulletproofGens::new(num_bits, 1); let pc_gens = PedersenGens::default(); @@ -84,7 +112,7 @@ fn range_proof_deserialize(g: &mut BenchmarkGroup, num_bits: || { let (v, b) = get_values(num_bits, 1); - let mut t = merlin::Transcript::new(b"AptosBenchmark"); + let mut t = Transcript::new(DST); let proof = RangeProof::prove_multiple( &bp_gens, @@ -111,16 +139,13 @@ fn range_verify(g: &mut BenchmarkGroup, num_bits: usize, batc g.throughput(Throughput::Elements(batch_size as u64)); g.bench_function( - BenchmarkId::new( - "range_verify", - format!("batch={}/bits={}", batch_size, num_bits), - ), + BenchmarkId::new(VERIFY_BENCH_ID, get_benchmark_subid(batch_size, num_bits)), move |b| { b.iter_with_setup( || { let (v, b) = get_values(num_bits, batch_size); - let mut t = merlin::Transcript::new(b"AptosBenchmark"); + let mut t = Transcript::new(DST); RangeProof::prove_multiple( &bp_gens, @@ -133,7 +158,7 @@ fn range_verify(g: &mut BenchmarkGroup, num_bits: usize, batc .unwrap() }, |(proof, comm)| { - let mut t = merlin::Transcript::new(b"AptosBenchmark"); + let mut t = Transcript::new(DST); assert!(proof .verify_multiple(&bp_gens, &pc_gens, &mut t, &comm, num_bits) @@ -144,5 +169,8 @@ fn range_verify(g: &mut BenchmarkGroup, num_bits: usize, batc ); } -criterion_group!(bulletproofs_benches, bench_group); +criterion_group!( + name = bulletproofs_benches; + config = Criterion::default().sample_size(10); + targets = bench_group); criterion_main!(bulletproofs_benches); diff --git a/crates/aptos-crypto/benches/bulletproofs_batch_verify.rs b/crates/aptos-crypto/benches/bulletproofs_batch_verify.rs deleted file mode 100644 index 6c62ddf0ddc..00000000000 --- a/crates/aptos-crypto/benches/bulletproofs_batch_verify.rs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -#[macro_use] -extern crate criterion; - -use aptos_crypto::bulletproofs::MAX_RANGE_BITS; -use bulletproofs::{BulletproofGens, PedersenGens, RangeProof}; -use criterion::{measurement::Measurement, BenchmarkGroup, BenchmarkId, Criterion, Throughput}; -use curve25519_dalek_ng::scalar::Scalar; -use merlin::Transcript; -use rand::{thread_rng, Rng}; -use rand_core::RngCore; - -fn get_values(num_bits: usize, batch_size: usize) -> (Vec, Vec) { - let mut rng = thread_rng(); - - let v = (0..batch_size) - .map(|_| rng.gen_range(0u64, (2u128.pow(num_bits as u32) - 1u128) as u64)) - .collect::>(); - - // Sigh, some RngCore incompatibilities I don't want to deal with right now. - let b = (0..batch_size) - .map(|_| { - let mut scalar = [0u8; 32]; - rng.fill_bytes(&mut scalar); - - Scalar::from_bytes_mod_order(scalar) - }) - .collect::>(); - - (v, b) -} - -fn bench_group(c: &mut Criterion) { - let mut group = c.benchmark_group("bulletproofs_batch_verify"); - - for batch_size in [1, 2, 4, 8, 16] { - for num_bits in [8, 16, 32, 64] { - range_batch_prove(&mut group, num_bits, batch_size); - range_batch_verify(&mut group, num_bits, batch_size); - } - } - - group.finish(); -} - -fn range_batch_prove( - g: &mut BenchmarkGroup, - num_bits: usize, - batch_size: usize, -) { - let pg = PedersenGens::default(); - let bg = BulletproofGens::new(MAX_RANGE_BITS, 16); - - g.throughput(Throughput::Elements(batch_size as u64)); - g.bench_function( - BenchmarkId::new( - "range_prove", - format!("batch={}/bits={}", batch_size, num_bits), - ), - move |b| { - b.iter_with_setup( - || get_values(num_bits, batch_size), - |(v, b)| { - let mut dst = [0_u8; 256]; - thread_rng().fill(&mut dst); - let mut t_prv = Transcript::new(&dst); - assert!(RangeProof::prove_multiple( - &bg, - &pg, - &mut t_prv, - v.as_slice(), - b.as_slice(), - num_bits - ) - .is_ok()); - }, - ) - }, - ); -} - -fn range_batch_verify( - g: &mut BenchmarkGroup, - num_bits: usize, - batch_size: usize, -) { - let bp_gens = BulletproofGens::new(MAX_RANGE_BITS, 16); - let pc_gens = PedersenGens::default(); - - g.throughput(Throughput::Elements(batch_size as u64)); - g.bench_function( - BenchmarkId::new( - "range_verify", - format!("batch={}/bits={}", batch_size, num_bits), - ), - move |b| { - b.iter_with_setup( - || { - let (v, b) = get_values(num_bits, batch_size); - let mut dst = [0_u8; 256]; - thread_rng().fill(&mut dst); - let mut t = Transcript::new(&dst); - - let (proof, comm) = RangeProof::prove_multiple( - &bp_gens, - &pc_gens, - &mut t, - v.as_slice(), - b.as_slice(), - num_bits, - ) - .unwrap(); - - (dst, proof.to_bytes(), comm) - }, - |(dst, proof_bytes, comm)| { - let mut t = Transcript::new(&dst); - - let proof = RangeProof::from_bytes(&proof_bytes[..]).unwrap(); - - assert!(proof - .verify_multiple(&bp_gens, &pc_gens, &mut t, &comm, num_bits) - .is_ok()); - }, - ) - }, - ); -} - -criterion_group!(bulletproofs_benches, bench_group); -criterion_main!(bulletproofs_benches); diff --git a/crates/aptos-crypto/benches/poseidon_bn254.rs b/crates/aptos-crypto/benches/poseidon_bn254.rs deleted file mode 100644 index 0c4e88a9324..00000000000 --- a/crates/aptos-crypto/benches/poseidon_bn254.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -#[macro_use] -extern crate criterion; - -use aptos_crypto::{poseidon_bn254, test_utils::random_bytes}; -use ark_ff::PrimeField; -use criterion::{measurement::Measurement, BenchmarkGroup, BenchmarkId, Criterion, Throughput}; -use poseidon_ark::Poseidon; -use rand::thread_rng; - -/// Runs all the benchmarks. -fn bench_group(c: &mut Criterion) { - let mut group = c.benchmark_group("zk"); - - //let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); - //group.plot_config(plot_config); - group.sample_size(50); - - for n in 1..=16 { - poseidon_bn254_ark(&mut group, n); - poseidon_bn254_neptune(&mut group, n); - } - - group.finish(); -} - -fn poseidon_bn254_neptune(g: &mut BenchmarkGroup, n: usize) { - let mut rng = thread_rng(); - - g.throughput(Throughput::Elements(n as u64)); - - g.bench_function(BenchmarkId::new("poseidon-bn254-neptune", n), move |b| { - b.iter_with_setup( - || { - (0..n) - .map(|_| { - let bytes = random_bytes(&mut rng, n); - ark_bn254::Fr::from_le_bytes_mod_order(bytes.as_slice()) - }) - .collect::>() - }, - |scalars| { - assert_eq!(scalars.len(), n); - - poseidon_bn254::hash_scalars(scalars).unwrap() - }, - ) - }); -} - -fn poseidon_bn254_ark(g: &mut BenchmarkGroup, n: usize) { - let mut rng = thread_rng(); - - g.throughput(Throughput::Elements(n as u64)); - - let hash = Poseidon::new(); - - g.bench_function(BenchmarkId::new("poseidon-bn254-ark", n), move |b| { - b.iter_with_setup( - || { - (0..n) - .map(|_| { - let bytes = random_bytes(&mut rng, n); - ark_bn254::Fr::from_le_bytes_mod_order(bytes.as_slice()) - }) - .collect::>() - }, - |scalars| { - assert_eq!(scalars.len(), n); - - hash.hash(scalars).unwrap() - }, - ) - }); -} - -criterion_group!( - name = zk_benches; - config = Criterion::default(); //.measurement_time(Duration::from_secs(100)); - targets = bench_group); -criterion_main!(zk_benches); diff --git a/crates/aptos-crypto/benches/print-markdown-table.py b/crates/aptos-crypto/benches/print-markdown-table.py new file mode 100755 index 00000000000..2f4722e67ed --- /dev/null +++ b/crates/aptos-crypto/benches/print-markdown-table.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python3 +import sys, csv, re, math +from collections import defaultdict + +HEADER = [ + "Scheme", + "n", + "Proving time (ms)", + "Verify time (ms)", + "Total time (ms)", + "Proof size (bytes)", +] + +BP_NAME = "Bulletproofs" +DE_NAME = "DeKART (BLS12-381)" + +BP_PROVE_ID = "range_prove" +BP_VERIFY_ID = "range_verify" +DE_PROVE_ID = "prove" +DE_VERIFY_ID = "verify" + +bp_re = re.compile(r"batch=(\d+)_bits=(\d+)") +de_re = re.compile(r"ell=(\d+)_n=(\d+)") + + +def bp_proof_size(n, ell): + """Bulletproofs proof size = 32 * (9 + 2 log2(n·ell))""" + return int(32 * (9 + 2 * math.log2(n * ell))) + +def de_proof_size(n, ell): + """DeKART proof size = (ell+5)*48 + (ell+4)*32""" + return int((ell + 5) * 48 + (ell + 4) * 32) + +def read_rows(fp): + reader = csv.DictReader(fp) + for row in reader: + for k in row: + if isinstance(row[k], str): + row[k] = row[k].strip() + yield row + +def parse_param_bulletproofs(param): + m = bp_re.fullmatch(param) + if not m: return None + n = int(m.group(1)) + ell = int(m.group(2)) + return n, ell + +def parse_param_dekart(param): + m = de_re.fullmatch(param) + if not m: return None + ell = int(m.group(1)) + n = int(m.group(2)) + return n, ell + +def ns_to_ms(ns): + return round(float(ns) / 1e6, 2) + +def fmt_ms(x): + return f"{x:,.2f}" + +def fmt_ratio(r): + return f"{r:.2f}x" + +def fmt_int(x: int) -> str: + return f"{x:,}" + +GREEN = 'color:#15803d' # bold green when faster +RED = 'color:#dc2626' # red when slower + +def decorate_dekart(value_ms, ratio): + """ + Returns: + display_text: plain text '1,234.56 (1.20x)' for width calculation + render_text: HTML-styled number only; ratio stays uncolored + faster (ratio < 1.0): bold green number + slower (ratio > 1.0): red number + equal (ratio == 1.0): unstyled number + """ + num_txt = fmt_ms(value_ms) + ratio_txt = f" ({fmt_ratio(ratio)})" + display = num_txt + ratio_txt + + if ratio < 1.0: + # slower → red number, ratio uncolored + render = f"{num_txt}{ratio_txt}" + elif ratio > 1.0: + # faster → bold green number, ratio uncolored + render = f"{num_txt}{ratio_txt}" + else: + # equal → no styling + render = display + + return display, render + +def decorate_dekart_size(value_bytes: int, ratio: float): + """ + Like decorate_dekart, but for integer byte sizes. + Colors ONLY the number; leaves ' (1.23x)' uncolored. + Uses your current color rule inside decorate_dekart (green if ratio>1, red if ratio<1). + """ + num_txt = fmt_int(value_bytes) + ratio_txt = f" ({fmt_ratio(ratio)})" + display = num_txt + ratio_txt + + # Reuse your current logic: red when ratio > 1.0, green when ratio < 1.0 + if ratio < 1.0: + render = f"{num_txt}{ratio_txt}" + elif ratio > 1.0: + render = f"{num_txt}{ratio_txt}" + else: + render = display + + return display, render + +def next_pow2_ge(x: int) -> int: + """Small helper: next power of two >= x.""" + if x <= 1: + return 1 + p = 1 + while p < x: + p <<= 1 + return p + +def accumulate(rows): + """ + Build dicts keyed by (n, ell) -> {"prove": ns, "verify": ns} + separately for Bulletproofs and DeKART. + """ + bp = defaultdict(dict) + de = defaultdict(dict) + ells_seen = set() + + for r in rows: + group = r.get("Group", "") + ident = r.get("Id", "") + param = r.get("Parameter", "") + mean_ns = r.get("Mean(ns)", "") + + if mean_ns == "" or mean_ns is None: + continue + try: + mean_ns = float(mean_ns) + except ValueError: + continue + + if group == "bulletproofs": + parsed = parse_param_bulletproofs(param) + if not parsed: continue + n, ell = parsed + ells_seen.add(ell) + if ident == BP_PROVE_ID: + bp[(n, ell)]["prove"] = mean_ns + elif ident == BP_VERIFY_ID: + bp[(n, ell)]["verify"] = mean_ns + + elif group.startswith("dekart"): + parsed = parse_param_dekart(param) + if not parsed: continue + n, ell = parsed + ells_seen.add(ell) + if ident == DE_PROVE_ID: + de[(n, ell)]["prove"] = mean_ns + elif ident == DE_VERIFY_ID: + de[(n, ell)]["verify"] = mean_ns + + return bp, de, sorted(ells_seen) + +def make_rows_for_ell(bp_map, de_map, ell): + """ + Alternate rows: Bulletproofs (n asc) then DeKART (n asc). + DeKART ratios are computed vs Bulletproofs at the *next power of two* batch size: + compare DeKART n = 2^k - 1 against Bulletproofs n = 2^k. + Only include rows where each scheme has both prove & verify for its own n. + """ + # Collect valid ns per scheme for this ell + bp_ns = sorted(n for (n,e),dv in bp_map.items() if e==ell and "prove" in dv and "verify" in dv) + de_ns = sorted(n for (n,e),dv in de_map.items() if e==ell and "prove" in dv and "verify" in dv) + + # Lookup tables in ms + bp_vals = {} + for n in bp_ns: + dv = bp_map[(n, ell)] + p = ns_to_ms(dv["prove"]); v = ns_to_ms(dv["verify"]); t = round(p+v, 2) + bp_vals[n] = (p, v, t) + + de_vals = {} + for n in de_ns: + dv = de_map[(n, ell)] + p = ns_to_ms(dv["prove"]); v = ns_to_ms(dv["verify"]); t = round(p+v, 2) + de_vals[n] = (p, v, t) + + # Alternate output + out = [] + i = j = 0 + while i < len(bp_ns) or j < len(de_ns): + if i < len(bp_ns): + n = bp_ns[i]; i += 1 + bp_p, bp_v, bp_t = bp_vals[n] + bp_size = bp_proof_size(n, ell) + out.append({ + "Scheme": BP_NAME, + "n": str(n), + "p_display": fmt_ms(bp_p), "p_render": fmt_ms(bp_p), + "v_display": fmt_ms(bp_v), "v_render": fmt_ms(bp_v), + "t_display": fmt_ms(bp_t), "t_render": fmt_ms(bp_t), + "s_display": fmt_int(bp_size), + "s_render": fmt_int(bp_size), + }) + if j < len(de_ns): + n = de_ns[j]; j += 1 + de_p, de_v, de_t = de_vals[n] + # Baseline Bulletproofs = next power of two of (n+1) (for 2^k-1 -> 2^k) + baseline_n = next_pow2_ge(n + 1) + de_size = de_proof_size(n, ell) + if baseline_n in bp_vals: + bp_p, bp_v, bp_t = bp_vals[baseline_n] + rp = bp_p / de_p if bp_p else float("inf") + rv = bp_v / de_v if bp_v else float("inf") + rt = bp_t / de_t if bp_t else float("inf") + p_disp, p_rend = decorate_dekart(de_p, rp) + v_disp, v_rend = decorate_dekart(de_v, rv) + t_disp, t_rend = decorate_dekart(de_t, rt) + + # proof-size ratio: DeKART vs BP baseline, same direction & coloring as verify time + bp_size = bp_proof_size(baseline_n, ell) + rs = de_size / bp_size if bp_size else float("inf") + s_disp, s_rend = decorate_dekart_size(de_size, rs) + else: + # No BP baseline available; print plain values + p_disp = p_rend = fmt_ms(de_p) + v_disp = v_rend = fmt_ms(de_v) + t_disp = t_rend = fmt_ms(de_t) + s_disp = s_rend = fmt_int(de_size) + + out.append({ + "Scheme": DE_NAME, + "n": str(n), + "p_display": p_disp, "p_render": p_rend, + "v_display": v_disp, "v_render": v_rend, + "t_display": t_disp, "t_render": t_rend, + "s_display": s_disp, "s_render": s_rend, + }) + return out + +def padded_table(rows): + """ + Compute widths from the plain display strings, then emit + padded Markdown rows with the render strings (HTML-styled). + """ + cols = HEADER + display_map = { + "Scheme": "Scheme", + "n": "n", + "Proving time (ms)": "p_display", + "Verify time (ms)": "v_display", + "Total time (ms)": "t_display", + "Proof size (bytes)": "s_display", + } + render_map = { + "Scheme": "Scheme", + "n": "n", + "Proving time (ms)": "p_render", + "Verify time (ms)": "v_render", + "Total time (ms)": "t_render", + "Proof size (bytes)": "s_render", + } + + widths = {c: len(c) for c in cols} + for r in rows: + for c in cols: + widths[c] = max(widths[c], len(str(r.get(display_map[c], "")))) + + left_cols = {"Scheme", "n", "Proof size (bytes)"} + right_cols = {"Proving time (ms)", "Verify time (ms)", "Total time (ms)"} + + def pad(c, s, align): + s = str(s) + if align == "right": + return " " + s.rjust(widths[c]) + " " + return " " + s.ljust(widths[c]) + " " + + header_line = "|" + "|".join(pad(c, c, "left") for c in cols) + "|" + sep_line = "|" + "|".join("-" * (widths[c] + 2) for c in cols) + "|" + + body_lines = [] + for r in rows: + cells = [] + for c in cols: + align = "right" if c in right_cols else "left" + # use display to compute width, render for content + content = r.get(render_map[c], "") + cells.append(pad(c, content, align)) + body_lines.append("|" + "|".join(cells) + "|") + + return "\n".join([header_line, sep_line] + body_lines) + +def main(): + # Read CSV from file or stdin + if len(sys.argv) > 1 and sys.argv[1] != "-": + with open(sys.argv[1], newline="") as f: + rows = list(read_rows(f)) + else: + rows = list(read_rows(sys.stdin)) + + bp_map, de_map, ells = accumulate(rows) + + first = True + for ell in ells: + tbl_rows = make_rows_for_ell(bp_map, de_map, ell) + if not tbl_rows: + continue + if not first: + print() + first = False + print(f"#### $\\ell = {ell}$ numbers\n") + print(padded_table(tbl_rows)) + +if __name__ == "__main__": + main() + diff --git a/crates/aptos-crypto/benches/random.rs b/crates/aptos-crypto/benches/random.rs new file mode 100644 index 00000000000..162c8a5b1ef --- /dev/null +++ b/crates/aptos-crypto/benches/random.rs @@ -0,0 +1,69 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::random::{ + unsafe_random_point, unsafe_random_point_slow, unsafe_random_points, unsafe_random_points_slow, +}; +use ark_ec::{pairing::Pairing, CurveGroup}; +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +const SAMPLE_SIZE: usize = 4_064; // 254 * 16 + +// ---------------------- Batch Benchmark ---------------------- + +fn bench_unsafe_random_points(c: &mut Criterion, label: &str) { + let mut group = c.benchmark_group(label); + + // Slow version (scalar multiple) + group.bench_function("unsafe_random_points_slow (batch)", |b| { + b.iter_batched( + || StdRng::seed_from_u64(0xDEADBEEF), + |mut rng| unsafe_random_points_slow::(SAMPLE_SIZE, &mut rng), + BatchSize::PerIteration, + ) + }); + + // Hash-to-curve version + group.bench_function("unsafe_random_points_hash (batch)", |b| { + b.iter_batched( + || StdRng::seed_from_u64(0xCAFEBABE), + |mut rng| unsafe_random_points::(SAMPLE_SIZE, &mut rng), + BatchSize::PerIteration, + ) + }); +} + +// ---------------------- Single-Point Benchmark ---------------------- + +fn bench_single_random_points(c: &mut Criterion, label: &str) { + let mut group = c.benchmark_group(label); + + // Slow version (single point) + group.bench_function("unsafe_random_point_slow (single)", |b| { + b.iter_batched( + || StdRng::seed_from_u64(0xBADF00D), + |mut rng| unsafe_random_point_slow::(&mut rng), + BatchSize::PerIteration, + ) + }); + + // Hash-to-curve version (single point) + group.bench_function("unsafe_random_point_hash (single)", |b| { + b.iter_batched( + || StdRng::seed_from_u64(0xB16B00B5), + |mut rng: StdRng| unsafe_random_point::(&mut rng), + BatchSize::PerIteration, + ) + }); +} + +fn criterion_benchmark(c: &mut Criterion) { + type G1 = ::G1; + + bench_unsafe_random_points::(c, "Unsafe Random Point Benchmarks (batch)"); + bench_single_random_points::(c, "Unsafe Random Point Benchmarks (single)"); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/crates/aptos-crypto/benches/run-range-proof-benches.sh b/crates/aptos-crypto/benches/run-range-proof-benches.sh new file mode 100755 index 00000000000..aa0cec70d6e --- /dev/null +++ b/crates/aptos-crypto/benches/run-range-proof-benches.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -e + +scriptdir=$(cd $(dirname $0); pwd -P) + +repo_root=$(readlink -f $scriptdir/../../../) +#echo "Repo root: $repo_root" + +read -p "Delete past benchmark results and re-run? (Otherwise, will use extant data in $repo_root/target/criterion) [y/N]: " ANS + +if [ "$ANS" == "y" ]; then + echo "Cleaning previous Bulletproof criterion benchmark results..." + rm -r $repo_root/target/criterion/bulletproofs + + echo "Benchmarking Bulletproofs..." + RAYON_NUM_THREADS=1 cargo bench -- bulletproofs + + echo "Cleaning previous DeKART criterion benchmark results..." + rm -r $repo_root/target/criterion/dekart* + + echo "Benchmarking DeKART..." + cd $repo_root/crates/aptos-dkg/ + RAYON_NUM_THREADS=1 cargo bench -- dekart-rs/bls12-381 + cd - &>/dev/null +fi + +cd $repo_root +csv_data=`cargo criterion-means | grep -E '^(bulletproofs|dekart-rs|Group)'` + +csv_file=`mktemp` +echo "Wrote CSV file to $csv_file..." +echo "$csv_data" >$csv_file + +md_tables=`$scriptdir/print-markdown-table.py $csv_file` + +echo "$md_tables" + +echo "$md_tables" | pbcopy +echo +echo "Copied to clipboard!" diff --git a/crates/aptos-crypto/examples/README.md b/crates/aptos-crypto/examples/README.md new file mode 100644 index 00000000000..3c87a9e039f --- /dev/null +++ b/crates/aptos-crypto/examples/README.md @@ -0,0 +1,30 @@ +# "Dude, is my code constant-time?" checks + +Run from the `crates/aptos-crypto` directory via: +``` +cargo run --release --example is_zkcrypto_constant_time +cargo run --release --example is_blstrs_constant_time +``` + +Quoting from the original README [here](https://docs.rs/dudect-bencher/latest/dudect_bencher/): +The program output will look like: + +``` +bench constant_time::blstrs_scalar_mul::run_bench seeded with 0xc41137dfdf1b2629 +bench constant_time::blstrs_scalar_mul::run_bench ... +# of 1 bits in scalars for "left" class is in [1, 4) +# of 1 bits in scalars for "right" class is always 250 +: n == +0.010M, max t = +1.86799, max tau = +0.01869, (5/tau)^2 = 71538 +``` + +It is interpreted as follows. +Firstly, note that the runtime distributions are cropped at different percentiles and about 100 t-tests are performed. +Of these t-tests, the one that produces the largest absolute t-value is printed as max_t. +The other values printed are: + + - `n`, indicating the number of samples used in computing this t-value + - `max_tau`, which is the t-value scaled for the samples size (formally, `max_tau = max_t / sqrt(n)`) + - `(5/tau)^2`, which indicates the number of measurements that would be needed to distinguish the two distributions with `t > 5` + +t-values outside (-5, 5) (i.e., of absolute value > 5) are generally considered a good indication that the function is not constant time. +t-values in (-5, 5) does not necessarily imply that the function is constant-time, since there may be other input distributions under which the function behaves significantly differently. diff --git a/crates/aptos-crypto/examples/is_blstrs_constant_time.rs b/crates/aptos-crypto/examples/is_blstrs_constant_time.rs new file mode 100644 index 00000000000..ff5469779f2 --- /dev/null +++ b/crates/aptos-crypto/examples/is_blstrs_constant_time.rs @@ -0,0 +1,8 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub use aptos_crypto::constant_time; +use dudect_bencher::ctbench_main; + +// Note: This runs the "fixed base" test. You'd need another Rust file to run the "random base" test. +ctbench_main!(constant_time::blstrs_scalar_mul::run_bench_with_fixed_bases); diff --git a/crates/aptos-crypto/examples/is_zkcrypto_constant_time.rs b/crates/aptos-crypto/examples/is_zkcrypto_constant_time.rs new file mode 100644 index 00000000000..4e6017ecc96 --- /dev/null +++ b/crates/aptos-crypto/examples/is_zkcrypto_constant_time.rs @@ -0,0 +1,7 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub use aptos_crypto::constant_time; +use dudect_bencher::ctbench_main; + +ctbench_main!(constant_time::zkcrypto_scalar_mul::run_bench); diff --git a/crates/aptos-crypto/src/arkworks/differentiate.rs b/crates/aptos-crypto/src/arkworks/differentiate.rs new file mode 100644 index 00000000000..d8f0289dbf5 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/differentiate.rs @@ -0,0 +1,85 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines a trait `DifferentiableFn` for differentiable functions (like polynomials), +//! and provides an implementation for `DensePolynomial` from the arkworks library. + +use ark_ff::Field; +use ark_poly::univariate::DensePolynomial; + +/// A trait for functions that can be differentiated. +pub trait DifferentiableFn { + /// Differentiate `self` in place + fn differentiate_in_place(&mut self); + + /// Return a new differentiated instance + fn differentiate(&self) -> Self + where + Self: Clone, + { + let mut copy = self.clone(); + copy.differentiate_in_place(); + copy + } +} + +impl DifferentiableFn for DensePolynomial { + fn differentiate_in_place(&mut self) { + if self.coeffs.len() <= 1 { + // Zero or constant polynomial + self.coeffs.clear(); + return; + } + + for i in 1..self.coeffs.len() { + self.coeffs[i - 1] = self.coeffs[i] * F::from(i as u64); + } + self.coeffs.pop(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_bn254::Fr; + use ark_ff::UniformRand; + use ark_poly::DenseUVPolynomial; + use ark_std::{rand::thread_rng, Zero}; + + #[test] + fn test_zero() { + let p = DensePolynomial::::zero(); + let d = p.differentiate(); + assert!(d.coeffs.is_empty()); // derivative of zero polynomial is zero + } + + #[test] + fn test_constant() { + let mut rng = thread_rng(); + let constant = Fr::rand(&mut rng); + let p = DensePolynomial::from_coefficients_vec(vec![constant]); + let d = p.differentiate(); + assert!(d.coeffs.is_empty()); // derivative of constant is zero + } + + #[test] + fn test_differentiate_linear() { + let mut rng = thread_rng(); + let a0 = Fr::rand(&mut rng); + let a1 = Fr::rand(&mut rng); + let p = DensePolynomial::from_coefficients_vec(vec![a0, a1]); + let d = p.differentiate(); + assert_eq!(d.coeffs, vec![a1]); // derivative of a0 + a1*x is a1 + } + + #[test] + fn test_differentiate_quadratic() { + let mut rng = thread_rng(); + let a0 = Fr::rand(&mut rng); + let a1 = Fr::rand(&mut rng); + let a2 = Fr::rand(&mut rng); + let p = DensePolynomial::from_coefficients_vec(vec![a0, a1, a2]); + let d = p.differentiate(); + assert_eq!(d.coeffs, vec![a1, a2 + a2]); // derivative of a0 + a1*x + a2*x² is a1 + 2*a2*x + } +} diff --git a/crates/aptos-crypto/src/arkworks/hashing.rs b/crates/aptos-crypto/src/arkworks/hashing.rs new file mode 100644 index 00000000000..d01e955b0cd --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/hashing.rs @@ -0,0 +1,121 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Provides an "unsafe" hash-to-curve implementation for elliptic curve affine points. + +use ark_ec::AffineRepr; +use digest::Digest; + +/// Iteration behavior and failure probability: +/// +/// By Hasse's theorem, the order of the elliptic curve is approximately equal +/// to the order of the underlying field Fq. Each x-coordinate either corresponds +/// to exactly two curve points, (x, y) and (x, -y), or to zero points. +/// +/// As a result, each iteration of this algorithm has roughly a 50% chance of producing +/// a valid point when given a uniformly random input (assuming the hash function behaves +/// as a random oracle). Consequently, the probability that this function fails on a random +/// input is approximately 1/2^256. +/// +/// Note: This algorithm is probabilistic and may be vulnerable to +/// side-channel attacks. For more details, see `MapToGroup` in: +/// Boneh, D., Lynn, B., & Shacham, H. (2004). "Short Signatures from the Weil Pairing." +/// Journal of Cryptology, 17, 297–319. DOI: 10.1007/s00145-004-0314-9. +/// +/// +/// For RFC9380 see: https://www.rfc-editor.org/rfc/rfc9380.html +pub fn unsafe_hash_to_affine(msg: &[u8], dst: &[u8]) -> P { + let dst_len = u8::try_from(dst.len()) + .expect("DST is too long; its length must be <= 255, as in RFC 9380 (Section 5.3.1)"); + + let mut buf = Vec::with_capacity(msg.len() + dst.len() + 1); + buf.extend_from_slice(msg); + buf.extend_from_slice(dst); + buf.push(dst_len); + buf.push(0); // placeholder for counter + + for ctr in 0..=u8::MAX { + *buf.last_mut() + .expect("Could not access last byte of buffer") = ctr; + + let hashed = sha3::Sha3_512::digest(&buf); + + // `from_random_bytes()` first tries to construct an x-coordinate, and then a y-coordinate from that, see e.g.: + // https://github.com/arkworks-rs/algebra/blob/c1f4f5665504154a9de2345f464b0b3da72c28ec/ec/src/models/short_weierstrass/affine.rs#L264 + if let Some(p) = P::from_random_bytes(&hashed) { + return p.mul_by_cofactor(); // is needed to ensure that `p` lies in the prime order subgroup + } + } + + panic!("Failed to hash to affine group element"); +} + +#[cfg(test)] +mod test_hash_to_affine { + use super::*; + use ark_ec::short_weierstrass; + + // Restricting this test to short Weierstrass curves because that's needed + // for `is_on_curve()` and `is_in_correct_subgroup_assuming_on_curve()` + fn test_point_validity() + where + C: short_weierstrass::SWCurveConfig, + { + let msg = b"point validity test"; + let dst = b"domain"; + + let p: short_weierstrass::Affine = unsafe_hash_to_affine(msg, dst); + + assert!(p.is_on_curve(), "Point is not on the curve"); + assert!( + p.is_in_correct_subgroup_assuming_on_curve(), + "Point is not in the correct subgroup" + ); + } + + fn test_determinism() { + let msg = b"hello world"; + let dst = b"my-domain-separator"; + + let p1: P = unsafe_hash_to_affine(msg, dst); + let p2: P = unsafe_hash_to_affine(msg, dst); + + assert_eq!(p1, p2); + } + + fn test_domain_separation() { + let msg = b"hello world"; + let p1: P = unsafe_hash_to_affine(msg, b"dst-1"); + let p2: P = unsafe_hash_to_affine(msg, b"dst-2"); + + assert_ne!(p1, p2); + } + + fn test_message_sensitivity() { + let dst = b"test-domain"; + let p1: P = unsafe_hash_to_affine(b"abc", dst); + let p2: P = unsafe_hash_to_affine(b"abd", dst); + + assert_ne!(p1, p2); + } + + #[test] + fn bn254_tests() { + use ark_bn254::G1Affine; + + test_point_validity::(); + test_determinism::(); + test_domain_separation::(); + test_message_sensitivity::(); + } + + #[test] + fn bls12_381_tests() { + use ark_bls12_381::G1Affine; + + test_point_validity::(); + test_determinism::(); + test_domain_separation::(); + test_message_sensitivity::(); + } +} diff --git a/crates/aptos-crypto/src/arkworks/mod.rs b/crates/aptos-crypto/src/arkworks/mod.rs new file mode 100644 index 00000000000..335b860a140 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/mod.rs @@ -0,0 +1,96 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides some helper functions for arkworks. + +pub mod differentiate; +pub mod hashing; +pub mod random; +pub mod scrape; +pub mod serialization; +pub mod shamir; +pub mod vanishing_poly; +pub mod weighted_sum; + +use ark_ec::{pairing::Pairing, AffineRepr}; +use ark_ff::{BigInteger, FftField, Field, PrimeField}; +use ark_poly::EvaluationDomain; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; + +/// A pair of canonical group generators for a pairing-friendly elliptic curve. +#[derive(CanonicalSerialize, CanonicalDeserialize, Debug, Clone, PartialEq, Eq)] +pub struct GroupGenerators { + /// The generator of the G₁ group (affine coordinates). + pub g1: E::G1Affine, + /// The generator of the G₂ group (affine coordinates). + pub g2: E::G2Affine, +} + +impl Default for GroupGenerators { + fn default() -> Self { + Self { + g1: E::G1Affine::generator(), + g2: E::G2Affine::generator(), + } + } +} + +/// Returns the first `ell` powers of two as scalar field elements, so +/// [1, 2, 4, 8, 16, ..., 2^{ell - 1}] +/// TODO: Ought to be slightly faster than using `powers()` from `utils`, but haven't tested this +pub fn powers_of_two(ell: usize) -> Vec { + (0..ell).map(|j| F::from(1u64 << j)).collect() +} + +/// Commit to scalars by multiplying a base group element (in affine representation) +/// with each scalar. +/// +/// Equivalent to `[base * s for s in scalars]`. +pub fn commit_to_scalars( + commitment_base: &P, + scalars: &[P::ScalarField], +) -> Vec { + scalars.iter().map(|s| *commitment_base * s).collect() +} + +// TODO: There's probably a better way to do this? +/// Converts a prime field scalar into a `u32`, if possible. Using +/// `PrimeField` because `into_bigint()` needs it for some reason. +pub fn scalar_to_u32(scalar: &F) -> Option { + let mut bytes = scalar.into_bigint().to_bytes_le(); + + while bytes.last() == Some(&0) { + bytes.pop(); + } + + if bytes.len() > 4 { + // More than 4 bytes → cannot fit in u32 + return None; + } + + // Pad bytes to 4 bytes for u32 conversion + let mut padded = [0u8; 4]; + padded[..bytes.len()].copy_from_slice(&bytes); + + Some(u32::from_le_bytes(padded)) +} + +/// Computes all `num_omegas`-th roots of unity in the scalar field, where `num_omegas` must be a power of two. +pub fn compute_roots_of_unity(num_omegas: usize) -> Vec { + let eval_dom = ark_poly::Radix2EvaluationDomain::::new(num_omegas) + .expect("Could not reconstruct evaluation domain"); + eval_dom.elements().collect() +} + +#[cfg(test)] +mod test_scalar_to_u32 { + use super::scalar_to_u32; + + #[test] + fn test_round_trip_for_valid_values() { + for i in [0, 1, 42, 255, 65_535, 1_000_000, u32::MAX] { + let scalar = ark_bn254::Fr::from(i as u64); + assert_eq!(scalar_to_u32(&scalar), Some(i)); + } + } +} diff --git a/crates/aptos-crypto/src/arkworks/random.rs b/crates/aptos-crypto/src/arkworks/random.rs new file mode 100644 index 00000000000..e1d0d82c8a3 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/random.rs @@ -0,0 +1,104 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides functions to sample random elements from cryptographic +//! structures such as prime fields and elliptic curve groups; `arkworks` can +//! do this by itself but the point here is to do it with our version of the +//! `rand` crate, which may differ from the version used by `arkworks` and thus +//! would not be accepted directly. + +use ark_ec::CurveGroup; +use ark_ff::PrimeField; +use rand::Rng; + +/// A version of `ark_ff`'s UniformRand but for our older RNGs +pub trait UniformRand { + /// Securely generate a random instance of self + fn rand(rng: &mut R) -> Self; +} + +/// NOTE: This function is "unsafe" in the sense that the caller learns the discrete log of the +/// random point w.r.t. the generator. In many applications, this is not acceptable. +/// Benches suggest that when generating a single point, it's roughly as fast as `unsafe_random_point()` - about 30µs +pub fn unsafe_random_point_slow(rng: &mut R) -> C +where + R: rand_core::RngCore + rand_core::CryptoRng, +{ + let r: C::ScalarField = sample_field_element(rng); + + C::generator().mul(r) +} + +/// Samples `n` uniformly random elements from the group, but is unsafe in the sense +/// that the caller learns the discrete log of the random point. +/// Benches show it's about 3.5x slower than `unsafe_random_points`. I guess the expensive parts +/// of hashing get reused? // TODO: Remove in the future +pub fn unsafe_random_points_slow(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand_core::CryptoRng, +{ + (0..n) + .map(|_| unsafe_random_point_slow::(rng)) + .collect() +} + +/// Faster "unsafe" random point by hashing some random bytes to the curve +/// But still not very fast // TODO: make proper benchmarks, then probably remove the other version +pub fn unsafe_random_point(rng: &mut R) -> C +where + R: rand_core::RngCore + rand_core::CryptoRng, +{ + // Generate some random bytes + let mut buf = [0u8; 32]; + rng.fill_bytes(&mut buf); + + // Hash to curve (using unsafe_hash_to_affine) + let p: C::Affine = + crate::arkworks::hashing::unsafe_hash_to_affine(&buf, b"unsafe_random_point"); + + p.into() // TODO: change signature to output affine +} + +/// Samples `n` uniformly random elements from the group, but is somewhat unsafe +/// because it involves a hashing function which is sensitive to timing attacks +pub fn unsafe_random_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand_core::CryptoRng, +{ + (0..n).map(|_| unsafe_random_point::(rng)).collect() +} + +/// Samples `n` uniformly random elements from the prime field `F`. +pub fn sample_field_elements(n: usize, rng: &mut R) -> Vec { + (0..n).map(|_| sample_field_element::(rng)).collect() +} + +/// Samples a uniformly random element from the prime field `F`, using rejection sampling. +/// Benchmarks suggest it is ~10x faster than the function `scalar_from_uniform_be_bytes()` below. +pub fn sample_field_element(rng: &mut R) -> F { + loop { + // Number of bytes needed for F + let num_bits = F::MODULUS_BIT_SIZE as usize; + let num_bytes = num_bits.div_ceil(8); + + // Draw enough random bytes to cover the field size + let mut bytes = vec![0u8; num_bytes]; + rng.fill_bytes(&mut bytes); + + // Interpret as little-endian integer mod p + if let Some(f) = F::from_random_bytes(&bytes) { + return f; + } + } +} + +/// Creates a scalar from a double-sized little-endian byte array by reducing modulo the field order. +pub fn scalar_from_uniform_be_bytes(rng: &mut R) -> F { + let num_bits = F::MODULUS_BIT_SIZE as usize; + let num_bytes = num_bits.div_ceil(8); + + let mut bytes = vec![0u8; 2 * num_bytes]; + rng.fill_bytes(&mut bytes); + + F::from_le_bytes_mod_order(&bytes) +} diff --git a/crates/aptos-crypto/src/arkworks/scrape.rs b/crates/aptos-crypto/src/arkworks/scrape.rs new file mode 100644 index 00000000000..1a46683029a --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/scrape.rs @@ -0,0 +1,292 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides a mechanism to check whether a set of polynomial evaluations +//! corresponds to a polynomial of bounded degree. It implements the dual code word +//! approach of the SCRAPE protocol [CD17e]. + +use crate::{arkworks, arkworks::random}; +use anyhow::{bail, ensure, Context}; +use ark_ec::CurveGroup; +use ark_ff::{FftField, PrimeField}; +use ark_poly::domain::{EvaluationDomain, Radix2EvaluationDomain}; +use ark_std::vec::Vec; + +/// A dual code word polynomial $f$ of degree $n-t-1$ for checking that the $n$ evaluations of another +/// polynomial (typically at the roots-of-unity $p(\omega^i)$, \forall i \in [0, n)$) encode a degree +/// $\le t-1$ polynomial. +/// +/// When `includes_zero` is true, $n-1$ of the $n$ evaluations are at the roots of unity and the $n$th +/// evaluation is at zero. +pub struct LowDegreeTest<'a, F: FftField> { + f: Vec, + includes_zero: bool, + t: usize, + n: usize, + batch_dom: &'a Radix2EvaluationDomain, // TODO: maybe make this more general than Radix2EvaluationDomain? +} + +impl<'a, F: PrimeField> LowDegreeTest<'a, F> { + /// Creates a new LDT given a pre-generated random polynomial `f` of expected degree `n-t-1`. + pub fn new( + f: Vec, + t: usize, + n: usize, + includes_zero: bool, + batch_dom: &'a Radix2EvaluationDomain, + ) -> anyhow::Result { + let min_size = if includes_zero { n - 1 } else { n }; + if batch_dom.size() < min_size { + bail!( + "expected batch evaluation domain size {} to be >= {}", + batch_dom.size(), + min_size + ); + } + + if t > n { + bail!("expected threshold {} to be <= {}", t, n) + } + + if f.len() != n - t { + bail!( + "random polynomial f degree is {}; expected degree n - t - 1 = {}", + f.len() - 1, + n - t - 1 + ) + } + + if f.is_empty() && t != n { + bail!("expected polynomial f to be non-empty when t != n"); + } + + Ok(Self { + f, + includes_zero, + t, + n, + batch_dom, + }) + } + + /// Creates a new LDT by picking a random polynomial `f` of expected degree `n-t-1`. + pub fn random( + mut rng: &mut R, + t: usize, + n: usize, + includes_zero: bool, + batch_dom: &'a Radix2EvaluationDomain, + ) -> Self { + Self::new( + random::sample_field_elements(n - t, &mut rng), + t, + n, + includes_zero, + batch_dom, + ) + .unwrap() + } + + /// When `include_zero` is false, checks if the evaluations $p(\omega^i)$, \forall i \in [0, n)$ stored + /// in `evals[i]` encode a degree $\le t-1$ polynomial. + /// + /// When `include_zero` is true, checks if the evaluations $p(0)$ in `evals[n-1]` and + /// $p(\omega^i)$ in `evals[i]` encode a degree $\le t-1$ polynomial (i.e., there are only $n-1$ + /// evaluations at the roots of unity). + pub fn low_degree_test(&self, evals: &[F]) -> anyhow::Result<()> { + // This includes the extra evaluation at zero when `includes_zero` is true. + if evals.len() != self.n { + bail!("Expected {} evaluations; got {}", self.n, evals.len()); + } + + // In this case, $n$ evaluations will always encode a degree $\le n-1$ polynomial, so we + // return true. + if self.t == self.n { + return Ok(()); + } + + let v_times_f = self.dual_code_word(); + + // Let v_i be the coefficients returned by `all_lagrange_denominators` inside the + // `dual_code_word` call. + // + // When `includes_zero` is false, computes \sum_{i \in [0, n)} p(\omega^i) v_i f(\omega^i), which + // should be zero. + // When `includes_zero` is true, computes the same as above, but times an extra term v_n f(0). + debug_assert_eq!( + evals.len(), + v_times_f.len(), + "Lengh of evals and v_times_f did not match" + ); + + let zero: F = evals + .iter() + .zip(v_times_f.iter()) + .map(|(p, vf)| p.mul(vf)) + .sum(); + + (zero.is_zero()).then_some(()).context(format!( + "the LDT scalar inner product should return zero, but instead returned {}", + zero + )) + } + + /// Performs the LDT given group elements $G^{p(\omega^i)} \in + pub fn low_degree_test_group>( + self, + evals: &[C], + ) -> anyhow::Result<()> { + if evals.len() != self.n { + bail!("Expected {} evaluations; got {}", self.n, evals.len()) + } + + if self.t == self.n { + return Ok(()); + } + + let v_times_f = self.dual_code_word(); + + debug_assert_eq!(evals.len(), v_times_f.len()); + let msm_result = C::msm(&C::normalize_batch(evals), v_times_f.as_slice()).unwrap(); + + ensure!( + msm_result == C::ZERO, + "the LDT MSM should have returned zero, but returned {}", + msm_result + ); + + Ok(()) + } + + /// Returns the dual code word for the SCRAPE low-degree test (as per Section 2.1 in [CD17e]) + /// on a polynomial of degree `deg` evaluated over either: + /// + /// - all $n$ roots of unity in `batch_dom`, if `include_zero` is false + /// - 0 and all $n-1$ roots of unity in `batch_dom`, if `include_zero` is true + /// + /// [CD17e] SCRAPE: Scalable Randomness Attested by Public Entities; by Ignacio Cascudo and + /// Bernardo David; in Cryptology ePrint Archive, Report 2017/216; 2017; + /// https://eprint.iacr.org/2017/216 + pub fn dual_code_word(&self) -> Vec { + // Accounts for the size of `f` being the `n` evaluations of f(X) at the roots-of-unity and f(0) + // when `include_zero` is true. + let fft_size = if self.includes_zero { + self.n - 1 + } else { + self.n + }; + let f_0 = self.f[0]; + + // Compute $f(\omega^i)$ for all $i \in [0, n)$ + let mut f_evals = self.batch_dom.fft(&self.f); + f_evals.truncate(fft_size); + + // Compute Lagrange denominators + let v = arkworks::shamir::all_lagrange_denominators( + self.batch_dom, + fft_size, + self.includes_zero, + ); + + // Append f(0), if `include_zero` is true + let mut extra = Vec::with_capacity(1); + if self.includes_zero { + extra.push(f_0); + } + + // Compute $v_i f(\omega^i), \forall i \in [0, n)$, and $v_n f(0)$ if `include_zero` is true. + debug_assert_eq!(f_evals.len() + extra.len(), v.len()); + f_evals + .iter() + .chain(extra.iter()) + .zip(v.iter()) + .map(|(v, f)| v.mul(f)) + .collect::>() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::arkworks::shamir::ShamirThresholdConfig; + use ark_bn254::Fr; + use ark_ff::PrimeField; + use ark_std::vec::Vec; + use rand::thread_rng; + + /// Helper to simulate sampling a random polynomial, by sampling its coefficients + fn sample_random_polynomial(degree: usize, rng: &mut R) -> Vec { + random::sample_field_elements(degree + 1, rng) + } + + #[test] + fn test_ldt_correctness() { + let mut rng = thread_rng(); + + // TODO: Move get_threshold_configs_for_testing() and the ThresholdConfig trait to aptos-crypto + for t in 1..8 { + for n in (t + 1)..(3 * t + 1) { + let sc = ShamirThresholdConfig::new(t, n); + + // A degree t-1 polynomial p(X) + let p = sample_random_polynomial::(t - 1, &mut rng); + + let mut evals = sc.domain.fft(&p); + evals.truncate(n); + + // Test deg(p) < t, given evals at n roots of unity over a domain with N = n.next_power_of_two() roots of unity + let ldt = LowDegreeTest::random(&mut rng, sc.t, sc.n, false, &sc.domain); + assert!(ldt.low_degree_test(&evals).is_ok()); + + if sc.t < sc.n { + // Test deg(p) < t + 1, given evals at roots of unity + let ldt = LowDegreeTest::random(&mut rng, sc.t + 1, sc.n, false, &sc.domain); + assert!(ldt.low_degree_test(&evals).is_ok()); + } + + // Test deg(p) < t, given evals at roots of unity and given p(0) + evals.push(p[0]); + let ldt = LowDegreeTest::random(&mut rng, sc.t, sc.n + 1, true, &sc.domain); + assert!(ldt.low_degree_test(&evals).is_ok()); + } + } + } + + #[test] + fn test_ldt_soundness() { + let mut rng = thread_rng(); + + for t in 1..8 { + for n in (t + 1)..(3 * t + 1) { + let sc = ShamirThresholdConfig::new(t, n); + + // A degree t polynomial f(X), higher by 1 than what the LDT expects + let p = sample_random_polynomial::(t, &mut rng); + + let mut evals = sc.domain.fft(&p); + evals.truncate(n); + + // Test deg(p) < t, given evals at roots of unity + // This should fail, since deg(p) = t + let ldt = LowDegreeTest::random(&mut rng, sc.t, sc.n, false, &sc.domain); + assert!( + ldt.low_degree_test(&evals).is_err(), + "LDT unexpectedly passed. n: {}, t: {}", + n, + t + ); + + // Test deg(p) < t, given evals at roots of unity and given p(0) + // This should fail, since deg(p) = t + evals.push(p[0]); + let ldt = LowDegreeTest::random(&mut rng, sc.t, sc.n + 1, true, &sc.domain); // Here using n+1 because p(0) is added + assert!( + ldt.low_degree_test(&evals).is_err(), + "LDT unexpectedly passed. n: {}, t: {}", + n, + t + ); + } + } + } +} diff --git a/crates/aptos-crypto/src/arkworks/serialization.rs b/crates/aptos-crypto/src/arkworks/serialization.rs new file mode 100644 index 00000000000..223547d77e6 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/serialization.rs @@ -0,0 +1,34 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Copied from https://github.com/arkworks-rs/algebra/issues/178#issuecomment-1413219278 + +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate}; + +/// Serializes a type implementing `CanonicalSerialize` into bytes (with compression) using the +/// [`ark_serialize`](https://docs.rs/ark-serialize) format and writes it to a Serde serializer. +/// +/// This is useful for integrating Arkworks types (e.g., elliptic curve elements, field elements) +/// with Serde-compatible formats such as JSON, CBOR, or MessagePack. +pub fn ark_se(a: &A, s: S) -> Result +where + S: serde::Serializer, +{ + let mut bytes = vec![]; + a.serialize_with_mode(&mut bytes, Compress::Yes) + .map_err(serde::ser::Error::custom)?; + s.serialize_bytes(&bytes) +} + +/// Deserializes a type implementing `CanonicalDeserialize` from bytes produced by [`ark_se`]. +/// +/// This function allows Arkworks types to be deserialized from Serde-compatible data sources. +/// It assumes the data was serialized with compression, and attempts to check its correctness. +pub fn ark_de<'de, D, A: CanonicalDeserialize>(data: D) -> Result +where + D: serde::de::Deserializer<'de>, +{ + let s: Vec = serde::de::Deserialize::deserialize(data)?; + let a = A::deserialize_with_mode(s.as_slice(), Compress::Yes, Validate::Yes); + a.map_err(serde::de::Error::custom) +} diff --git a/crates/aptos-crypto/src/arkworks/shamir.rs b/crates/aptos-crypto/src/arkworks/shamir.rs new file mode 100644 index 00000000000..4bc83eacad1 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/shamir.rs @@ -0,0 +1,469 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Contains a version of shamir secret sharing and `ThresholdConfig` for arkworks + +use crate::{ + arkworks::{differentiate::DifferentiableFn, vanishing_poly, weighted_sum::WeightedSum}, + player::Player, + traits, + traits::SecretSharingConfig, +}; +use anyhow::{anyhow, Result}; +use ark_ec::CurveGroup; +use ark_ff::{batch_inversion, FftField, Field}; +use ark_poly::{EvaluationDomain, Radix2EvaluationDomain}; +use ark_std::fmt; +use rand::{seq::IteratorRandom, Rng}; +use rand_core::{CryptoRng, RngCore}; +use serde::{Deserialize, Deserializer, Serialize}; +use std::collections::HashSet; + +/// A Shamir share consisting of a player and their associated share value. +#[allow(type_alias_bounds)] +pub type ShamirShare = (Player, F); +/// A Shamir share specialized for elliptic curve groups. +#[allow(type_alias_bounds)] +pub type ShamirGroupShare = ShamirShare; + +/// All dealt secret keys should be reconstructable from a subset of \[dealt secret key\] shares. +pub trait Reconstructable: Sized { + /// The "share" type. Minor nit: this is a slight misnomer; you can't actually reconstruct + /// using just a vec of shares, you need a vec of pairs (Player, Self::Share). So the pair + /// itself corresponds more closely to the definition of a share + type ShareValue: Clone; + + /// The reconstruct function + fn reconstruct(sc: &SSC, shares: &[ShamirShare]) -> Result; +} + +/// Configuration for a threshold cryptography scheme. Usually one restricts `F` to `Primefield` +/// but any field is theoretically possible. +#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)] +pub struct ShamirThresholdConfig { + /// Total number of participants (shares) + pub n: usize, + /// Threshold number of shares required to reconstruct the secret. Note that in + /// MPC literature `t` usually denotes the maximal adversary threshold, so `t + 1` + /// shares would be required to reconstruct the secret + pub t: usize, + /// Used for FFT-based polynomial operations. Recomputed from `n` on deserialize + #[serde(skip)] + pub domain: Radix2EvaluationDomain, +} + +impl traits::SecretSharingConfig for ShamirThresholdConfig { + /// For testing only. + fn get_random_player(&self, rng: &mut R) -> Player + where + R: RngCore + CryptoRng, + { + Player { + id: rng.gen_range(0, self.n), + } + } + + /// For testing only. + fn get_random_eligible_subset_of_players(&self, mut rng: &mut R) -> Vec + where + R: RngCore, + { + (0..self.get_total_num_shares()) + .choose_multiple(&mut rng, self.t) + .into_iter() + .map(|i| self.get_player(i)) + .collect::>() + } + + fn get_total_num_players(&self) -> usize { + self.n + } + + fn get_total_num_shares(&self) -> usize { + self.n + } +} + +impl traits::ThresholdConfig for ShamirThresholdConfig { + fn new(t: usize, n: usize) -> Result { + let domain = Radix2EvaluationDomain::new(n) // Note that `new(n)` internally does `n.next_power_of_two()` + .expect("Invalid domain size: {}"); + Ok(Self { n, t, domain }) + } + + fn get_threshold(&self) -> usize { + self.t + } +} + +impl fmt::Display for ShamirThresholdConfig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ThresholdConfig {{ n: {}, t: {} }}", self.n, self.t) + } +} + +impl<'de, F: FftField> Deserialize<'de> for ShamirThresholdConfig { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct BasicFields { + n: usize, + t: usize, + } + + let BasicFields { n, t } = BasicFields::deserialize(deserializer)?; + + let domain = Radix2EvaluationDomain::new(n) // Note that `new(n)` internally does `n.next_power_of_two()` + .ok_or_else(|| serde::de::Error::custom(format!("Invalid domain size: {}", n)))?; + + Ok(ShamirThresholdConfig { n, t, domain }) + } +} + +// This one will be used for benchmarks only (TODO) +#[allow(dead_code)] +fn naive_all_lagrange_coefficients(xs: &HashSet) -> Vec<(F, F)> { + let xs_vec: Vec = xs.iter().cloned().collect(); + let n = xs_vec.len(); + + // Step 1: Collect denominators for all i + let mut denominators = Vec::with_capacity(n); + + for (i, &xi) in xs_vec.iter().enumerate() { + let mut denom = F::one(); + for (j, &xj) in xs_vec.iter().enumerate() { + if i == j { + continue; + } + denom *= xi - xj; + } + denominators.push(denom); + } + // Step 2: Invert all denominators at once + let mut denom_invs = denominators.clone(); + batch_inversion(&mut denom_invs); + + // Step 3: Compute numerators (product of -x_j for j != i) + let mut results = Vec::with_capacity(n); + for i in 0..n { + let xi = xs_vec[i]; + let mut num = F::one(); + for (j, &xj) in xs_vec.iter().enumerate() { + if i == j { + continue; + } + num *= -xj; + } + + let li = num * denom_invs[i]; + results.push((xi, li)); + } + + results +} + +/// Computes the Lagrange denominators for a set of evaluation points in a Radix-2 FFT domain. +/// +/// Specifically, for a polynomial evaluated at points `\omega^0, \dots, \omega^{n-1}` in `dom`, +/// the Lagrange denominators are given by: +/// +/// ```text +/// v_i = 1 / \prod_{j \ne i} (\omega^i - \omega^j) +/// ``` +#[allow(non_snake_case)] +pub fn all_lagrange_denominators( + dom: &Radix2EvaluationDomain, + n: usize, + include_zero: bool, +) -> Vec { + // A(X) = \prod_{i \in [0, n-1]} (X - \omega^i) + let omegas: Vec = dom.elements().take(n).collect(); + debug_assert_eq!(F::ONE, omegas[0]); + for i in 1..n { + debug_assert_eq!( + omegas[i - 1] * omegas[1], + omegas[i], + "omegas are not in sequence at index {}", + i + ); + } + + // This is **not** X^n - 1, because the \omega^i are not n-th roots of unity, they are N-th roots of unity where N is some power of 2 + let mut A = vanishing_poly::from_roots(&omegas); + + // A'(X) = \sum_{i \in [0, n-1]} \prod_{j \ne i, j \in [0, n-1]} (X - \omega^j) + A.differentiate_in_place(); + let A_prime = A; + + // A'(\omega^i) = \prod_{j\ne i, j \in [n] } (\omega^i - \omega^j) + let mut denoms = dom.fft(&A_prime); + denoms.truncate(n); + + // If `include_zero`, need to: + if include_zero { + // 1. Augment A'(\omega_i) = A'(\omega_i) * \omega^i, for all i\ in [0, n) + for (i, denom) in denoms.iter_mut().enumerate().take(n) { + *denom *= omegas[i]; + } + + // 2. Compute A'(0) = \prod_{j \in [0, n)} (0 - \omega^j) + denoms.push((0..n).map(|i| -omegas[i]).product()); + } + + batch_inversion(&mut denoms); + + denoms +} + +impl ShamirThresholdConfig { + /// This initializes a `(t, n)` threshold scheme configuration. + /// The `domain` is automatically computed as a radix-2 evaluation domain + /// of size `n.next_power_of_two()` for use in FFT-based polynomial operations. + pub fn new(t: usize, n: usize) -> Self { + debug_assert!(t <= n, "Expected t <= n, but t = {} and n = {}", t, n); + let domain = Radix2EvaluationDomain::new(n).unwrap(); + ShamirThresholdConfig { n, t, domain } + } + + /// Returns the threshold `t` for this `(t, n)` Shamir secret sharing scheme. + pub fn get_threshold(&self) -> usize { + self.t + } + + /// Returns the total number of players `n` in this `(t, n)` Shamir secret sharing + pub fn get_total_num_players(&self) -> usize { + self.n + } + + /// Fast lagrange coefficient computation algorithm, taken from the paper + /// "Towards Scalable Threshold Cryptosystems" by Alin Tomescu, Robert Chen, Yiming Zheng, Ittai + /// Abraham, Benny Pinkas, Guy Golan Gueta and Srinivas Devadas + /// (which I think takes it from Modern Computer Algebra, by von zur Gathen and Gerhard) + /// + /// Takes as input a subset of the roots-of-unity domain, represented by a slice of indices. + /// Outputs the Lagrange coefficients of those x-coordinates. + pub fn lagrange_for_subset(&self, indices: &[usize]) -> Vec { + // Step 0: check that subset is large enough + assert!( + indices.len() >= self.t, + "subset size {} is smaller than threshold t={}", + indices.len(), + self.t + ); + + let xs_vec: Vec = indices.iter().map(|i| self.domain.element(*i)).collect(); + + // Step 1: compute poly w/ roots at all x in xs, compute eval at 0 + let vanishing_poly = vanishing_poly::from_roots(&xs_vec); + let vanishing_poly_at_0 = vanishing_poly.coeffs[0]; // vanishing_poly(0) = const term + + // Step 2 (numerators): for each x in xs, divide poly eval from step 1 by (-x) using batch inversion + let mut neg_xs: Vec = xs_vec.iter().map(|&x| -x).collect(); + batch_inversion(&mut neg_xs); + let numerators: Vec = neg_xs + .iter() + .map(|&inv_neg_x| vanishing_poly_at_0 * inv_neg_x) + .collect(); + + // Step 3a (denominators): Compute derivative of poly from step 1, and its evaluations + let derivative = vanishing_poly.differentiate(); + let derivative_evals = derivative.evaluate_over_domain(self.domain).evals; // TODO: with a filter perhaps we don't have to store all evals, but then batch inversion becomes a bit more tedious + + // Step 3b: Only keep the relevant evaluations, then perform a batch inversion + let mut denominators: Vec = indices.iter().map(|i| derivative_evals[*i]).collect(); + batch_inversion(&mut denominators); + + // Step 4: compute Lagrange coefficients + numerators + .into_iter() + .zip(denominators) + .map(|(numerator, denom_inv)| numerator * denom_inv) + .collect() + } + + /// This method creates `n` shares of a secret using + /// a `(t, n)` Shamir Secret Sharing scheme: + /// 1. A random polynomial of degree `t-1` is given as input. We are deliberately generating + /// it outside of this file so it won't depend on the specific version of the `rand` crate. + /// 2. The polynomial is evaluated over the `domain` using FFT to produce all evaluations, + /// which are subsequently trunked. + pub fn share(&self, coeffs: &[F]) -> Vec> { + debug_assert_eq!(coeffs.len(), self.t); + let evals = self.domain.fft(coeffs); + (0..self.n).map(|i| self.get_player(i)).zip(evals).collect() + } +} + +impl Reconstructable> for T { + type ShareValue = T; + + fn reconstruct( + sc: &ShamirThresholdConfig, + shares: &[ShamirShare], + ) -> Result { + if shares.len() != sc.t { + Err(anyhow!("Incorrect number of shares provided")) + } else { + let (roots_of_unity_indices, bases): (Vec, Vec) = + shares.iter().map(|(p, g_y)| (p.get_id(), g_y)).collect(); + + let lagrange_coeffs = sc.lagrange_for_subset(&roots_of_unity_indices); + + Ok(T::weighted_sum(&bases, &lagrange_coeffs)) + } + } +} + +#[cfg(test)] +mod shamir_tests { + use super::*; + use crate::arkworks::random::sample_field_elements; + use ark_bn254::{Fr, G1Affine}; + use ark_ec::AffineRepr as _; + use ark_ff::One; + use itertools::Itertools; + + fn single_lagrange(i: usize, xs_indices: &[usize], xs: &[Fr]) -> Fr { + let mut prod = Fr::one(); + + for &i_prime in xs_indices { + if i == i_prime { + continue; + } else { + prod *= -xs[i_prime]; + prod /= xs[i] - xs[i_prime]; + } + } + + prod + } + + #[test] + fn test_all_lagrange() { + use itertools::Itertools; + + for n in 2..8 { + for t in 1..=n { + let config = ShamirThresholdConfig::new(t, n); + + let elements: Vec = (0..n).collect(); + + for subset in elements.iter().cloned().combinations(t) { + let lagrange_for_subset = config.lagrange_for_subset(&subset); + + for (i, lagrange) in subset.iter().zip(&lagrange_for_subset) { + let expected = single_lagrange( + *i, + &subset, + &config.domain.elements().collect::>(), + ); + assert_eq!( + *lagrange, expected, + "Mismatch at i={:?}, subset={:?}, domain size={:?}", + i, subset, n + ); + } + } + } + } + } + + fn sample_shares( + rng: &mut impl rand::RngCore, + t: usize, + n: usize, + ) -> (ShamirThresholdConfig, Fr, Vec>) { + let sharing_scheme = ShamirThresholdConfig::new(t, n); + + let coeffs = sample_field_elements(t, rng); + + let shares = sharing_scheme.share(&coeffs); + (sharing_scheme, coeffs[0], shares) + } + + #[test] + fn test_reconstruct() { + let mut rng = rand::thread_rng(); + for n in 2..6 { + // Can increase this a bit if desired, the test is very fast + for t in 1..=n { + let (sharing_scheme, secret, shares) = sample_shares(&mut rng, t, n); + + for reconstruct_shares in shares.iter().combinations(t) { + let reconstruct_shares_vec: Vec> = + reconstruct_shares.into_iter().cloned().collect(); + + assert_eq!( + Fr::reconstruct(&sharing_scheme, &reconstruct_shares_vec).unwrap(), + secret + ); + } + } + } + } + + #[test] + fn test_reconstruct_in_exponent() { + let mut rng = rand::thread_rng(); + for n in 2..8 { + for t in 1..=n { + let (sharing_scheme, secret, shares) = sample_shares(&mut rng, t, n); + + let shares_g1: Vec> = shares + .into_iter() + .map(|(player, y)| (player, (G1Affine::generator() * y).into())) + .collect(); + + for reconstruct_shares_g1 in shares_g1.into_iter().combinations(t) { + assert_eq!( + G1Affine::reconstruct(&sharing_scheme, &reconstruct_shares_g1).unwrap(), + G1Affine::generator() * secret + ); + } + } + } + } + + #[test] + fn test_all_lagrange_denominators_no_zero() { + for n in [4, 8, 16] { + let dom = Radix2EvaluationDomain::::new(n).unwrap(); + + // Compute denominators + let denoms = all_lagrange_denominators(&dom, n, false); + assert_eq!(denoms.len(), n); + + // Manual check: for small n, v_i = 1 / Π_{j≠i} (ω^i - ω^j) + let omegas: Vec = dom.elements().collect(); + for i in 0..n { + let mut expected = Fr::one(); + for j in 0..n { + if i != j { + expected *= omegas[i] - omegas[j]; + } + } + expected = expected.inverse().unwrap(); + assert_eq!(denoms[i], expected, "Mismatch at index {}", i); + } + } + } + + #[test] + fn test_all_lagrange_denominators_with_zero() { + for n in [4, 8, 16] { + let dom = Radix2EvaluationDomain::::new(n).unwrap(); + + let denoms = all_lagrange_denominators(&dom, n, true); + assert_eq!(denoms.len(), n + 1); // should include the zero term + + let omegas: Vec = dom.elements().collect(); + + // Check last element corresponds to point at zero + let expected_zero_term_inv: Fr = (0..n).map(|i| -omegas[i]).product(); + let expected_zero_term = expected_zero_term_inv.inverse().unwrap(); + assert_eq!(denoms[n], expected_zero_term); + } + } +} diff --git a/crates/aptos-crypto/src/arkworks/vanishing_poly.rs b/crates/aptos-crypto/src/arkworks/vanishing_poly.rs new file mode 100644 index 00000000000..ff9a21d2d4c --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/vanishing_poly.rs @@ -0,0 +1,57 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Auxiliary function for Lagrange interpolation + +use ark_ff::FftField; +use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial}; + +/// Recursively computes the **vanishing polynomial** for a given set of points +/// using a divide-and-conquer approach. +/// +/// A vanishing polynomial `V(x)` is a polynomial that evaluates to zero at each +/// of the points in `xs`. Formally: +/// ```text +/// V(x_i) = 0 for all x_i in xs +/// ``` +pub fn from_roots(roots: &[F]) -> DensePolynomial { + match roots.len() { + 0 => DensePolynomial::from_coefficients_vec(vec![F::one()]), // Empty product = 1 + 1 => DensePolynomial::from_coefficients_vec(vec![-roots[0], F::one()]), // Single root + _ => { + let mid = roots.len() / 2; + let left = from_roots(&roots[..mid]); + let right = from_roots(&roots[mid..]); + &left * &right // This uses FftField + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_bn254::Fr; + use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial}; + use ark_std::{rand::thread_rng, One, UniformRand}; + + #[test] + fn test_compute_product() { + let mut rng = thread_rng(); + + for num_roots in 1..=16 { + let frs: Vec = (0..num_roots).map(|_| Fr::rand(&mut rng)).collect(); + + // Compute product using recursive function + let product = from_roots(&frs); + + // Naive computation of product + let expected: DensePolynomial = frs + .into_iter() + .map(|u| DensePolynomial::from_coefficients_vec(vec![-u, Fr::one()])) + .reduce(|acc, f| acc * f) + .unwrap(); + + assert_eq!(product, expected); + } + } +} diff --git a/crates/aptos-crypto/src/arkworks/weighted_sum.rs b/crates/aptos-crypto/src/arkworks/weighted_sum.rs new file mode 100644 index 00000000000..6282ff31512 --- /dev/null +++ b/crates/aptos-crypto/src/arkworks/weighted_sum.rs @@ -0,0 +1,40 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Weighted sum utilities for scalars and elliptic curve points. + +use ark_ec::{ + short_weierstrass::{Affine, SWCurveConfig}, + AffineRepr, VariableBaseMSM as _, +}; +use ark_ff::{Fp, FpConfig, PrimeField}; + +/// Trait for computing a **weighted sum** (linear combination) of elements. +pub trait WeightedSum: Copy { + /// The type of scalar weights used in the linear combination. + type Scalar: PrimeField; + + /// Computes the weighted sum of the provided bases and scalars. + /// Returns the linear combination `∑ s_i * b_i`. + fn weighted_sum(bases: &[Self], scalars: &[Self::Scalar]) -> Self; +} + +impl> WeightedSum for Fp { + type Scalar = Fp; + + fn weighted_sum(bases: &[Self], scalars: &[Self::Scalar]) -> Self { + assert_eq!(bases.len(), scalars.len()); + + bases.iter().zip(scalars).map(|(b, s)| b * s).sum() + } +} + +impl WeightedSum for Affine

{ + type Scalar = P::ScalarField; + + fn weighted_sum(bases: &[Self], scalars: &[Self::Scalar]) -> Self { + ::Group::msm(bases, scalars) + .expect("MSM failed weighted_sum()") + .into() + } +} diff --git a/crates/aptos-dkg/src/algebra/evaluation_domain.rs b/crates/aptos-crypto/src/blstrs/evaluation_domain.rs similarity index 92% rename from crates/aptos-dkg/src/algebra/evaluation_domain.rs rename to crates/aptos-crypto/src/blstrs/evaluation_domain.rs index 0328c5f536b..1f38b828ffc 100644 --- a/crates/aptos-dkg/src/algebra/evaluation_domain.rs +++ b/crates/aptos-crypto/src/blstrs/evaluation_domain.rs @@ -1,7 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_crypto::CryptoMaterialError; +//! Evaluation domains and batched evaluation domains for radix-2 FFTs over the BLS12-381 scalar field. + +use crate::CryptoMaterialError; use blstrs::Scalar; use ff::{Field, PrimeField}; use more_asserts::{assert_gt, assert_le}; @@ -55,6 +57,10 @@ pub fn smallest_power_of_2_greater_than_or_eq(n: usize) -> (usize, usize) { } (N, log_N) + // TODO: Replace with: + // let N = n.next_power_of_two(); + // let log_N = N.trailing_zeros() as usize; + // (N, log_N) } impl EvaluationDomain { @@ -146,6 +152,7 @@ impl BatchEvaluationDomain { } } + /// Returns the size `N` of the batch evaluation domain. #[allow(non_snake_case)] pub fn N(&self) -> usize { self.omegas.len() @@ -168,12 +175,13 @@ impl BatchEvaluationDomain { // i.e., omega = omega.square(); idx *= 2; } + // TODO: idx == 2^(self.log_N - log_K) let N = self.omegas.len(); - let omega = self.omegas[idx % N]; + let omega = self.omegas[idx % N]; // TODO: %N seems unnecessary debug_assert!(Self::is_order(&omega, K)); - let omega_inverse = self.omegas[(N - idx) % N]; + let omega_inverse = self.omegas[(N - idx) % N]; // TODO: %N seems unnecessary debug_assert_eq!(omega_inverse.invert().unwrap(), omega); EvaluationDomain { @@ -200,7 +208,7 @@ impl BatchEvaluationDomain { #[allow(non_snake_case)] fn is_order(omega: &Scalar, K: usize) -> bool { assert_gt!(K, 0); - let mut acc = omega.clone(); + let mut acc = *omega; // First, check that \omega^1, \omega^2, \omega^{K-1} are NOT the identity. for _ in 1..=K - 1 { @@ -218,6 +226,6 @@ impl BatchEvaluationDomain { } // println!(); - return true; + true } } diff --git a/crates/aptos-crypto/src/blstrs/fft.rs b/crates/aptos-crypto/src/blstrs/fft.rs new file mode 100644 index 00000000000..6bcb21c902a --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/fft.rs @@ -0,0 +1,226 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Fast Fourier Transform (FFT) utilities over the BLS12-381 scalar field. + +use crate::blstrs::evaluation_domain::EvaluationDomain; +use blstrs::{G1Projective, G2Projective, Scalar}; +use ff::Field; +use std::ops::{AddAssign, MulAssign, SubAssign}; + +/// Computes a Discrete Fourier Transform (DFT), a.k.a., an FFT, on the polynomial $f(X)$ in `poly`, +/// returning all the $N$ evaluations at the roots of unity: $f(\omega^0), f(\omega^1), \ldots, f(\omega^{N-1})$ +/// where `dom.log_N` is $\log_2{N}$ and `dom.omega` is $\omega$. +pub fn fft_assign(poly: &mut Vec, dom: &EvaluationDomain) { + // Pad with zeros, if necessary + if poly.len() < dom.N { + poly.resize(dom.N, Scalar::ZERO); + } + + serial_fft_assign(poly.as_mut_slice(), &dom.omega, dom.log_N as u32) +} + +/// Computes the forward Fast Fourier Transform (FFT) of a polynomial. +pub fn fft(poly: &[Scalar], dom: &EvaluationDomain) -> Vec { + let mut evals = Vec::with_capacity(dom.N); + evals.resize(poly.len(), Scalar::ZERO); + evals.copy_from_slice(poly); + + fft_assign(&mut evals, dom); + + evals +} + +/// Computes the inverse of `fft_assign`. +pub fn ifft_assign(poly: &mut Vec, dom: &EvaluationDomain) { + serial_fft_assign(poly.as_mut_slice(), &dom.omega_inverse, dom.log_N as u32); + + for coeff in poly { + coeff.mul_assign(&dom.N_inverse); + } +} + +/// TODO: dedup with macro or something +pub fn ifft_assign_g1(poly: &mut Vec, dom: &EvaluationDomain) { + serial_fft_assign_g1(poly.as_mut_slice(), &dom.omega_inverse, dom.log_N as u32); + + for coeff in poly { + coeff.mul_assign(&dom.N_inverse); + } +} + +/// TODO: dedup with macro or something +pub fn ifft_assign_g2(poly: &mut Vec, dom: &EvaluationDomain) { + serial_fft_assign_g2(poly.as_mut_slice(), &dom.omega_inverse, dom.log_N as u32); + + for coeff in poly { + coeff.mul_assign(&dom.N_inverse); + } +} + +/// `bellman`'s FFT code adapted to `blstrs::Scalar`. +fn serial_fft_assign(a: &mut [Scalar], omega: &Scalar, log_n: u32) { + fn bitreverse(mut n: u32, l: u32) -> u32 { + let mut r = 0; + for _ in 0..l { + r = (r << 1) | (n & 1); + n >>= 1; + } + r + } + + let n = a.len() as u32; + assert_eq!(n, 1 << log_n); + + for k in 0..n { + let rk = bitreverse(k, log_n); + if k < rk { + a.swap(rk as usize, k as usize); + } + } + + let mut m = 1; + for _ in 0..log_n { + // TODO(Performance): Could have these precomputed via BatchEvaluationDomain, but need to + // update all upstream calls to pass in the `BatchEvaluationDomain`. + let w_m = omega.pow_vartime([u64::from(n / (2 * m))]); + + let mut k = 0; + while k < n { + let mut w = Scalar::ONE; + for j in 0..m { + let mut t = a[(k + j + m) as usize]; + t.mul_assign(&w); + let mut tmp = a[(k + j) as usize]; + tmp.sub_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); + w.mul_assign(&w_m); + } + + k += 2 * m; + } + + m *= 2; + } +} + +/// TODO: dedup with macro or something +pub fn serial_fft_assign_g1(a: &mut [G1Projective], omega: &Scalar, log_n: u32) { + fn bitreverse(mut n: u32, l: u32) -> u32 { + let mut r = 0; + for _ in 0..l { + r = (r << 1) | (n & 1); + n >>= 1; + } + r + } + + let n = a.len() as u32; + assert_eq!(n, 1 << log_n); + + for k in 0..n { + let rk = bitreverse(k, log_n); + if k < rk { + a.swap(rk as usize, k as usize); + } + } + + let mut m = 1; + for _ in 0..log_n { + // TODO(Performance): Could have these precomputed via BatchEvaluationDomain, but need to + // update all upstream calls to pass in the `BatchEvaluationDomain`. + let w_m = omega.pow_vartime([u64::from(n / (2 * m))]); + + let mut k = 0; + while k < n { + let mut w = Scalar::ONE; + for j in 0..m { + let mut t = a[(k + j + m) as usize]; + t.mul_assign(&w); + let mut tmp = a[(k + j) as usize]; + tmp.sub_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); + w.mul_assign(&w_m); + } + + k += 2 * m; + } + + m *= 2; + } +} + +/// TODO: dedup with macro or something +pub fn serial_fft_assign_g2(a: &mut [G2Projective], omega: &Scalar, log_n: u32) { + fn bitreverse(mut n: u32, l: u32) -> u32 { + let mut r = 0; + for _ in 0..l { + r = (r << 1) | (n & 1); + n >>= 1; + } + r + } + + let n = a.len() as u32; + assert_eq!(n, 1 << log_n); + + for k in 0..n { + let rk = bitreverse(k, log_n); + if k < rk { + a.swap(rk as usize, k as usize); + } + } + + let mut m = 1; + for _ in 0..log_n { + // TODO(Performance): Could have these precomputed via BatchEvaluationDomain, but need to + // update all upstream calls to pass in the `BatchEvaluationDomain`. + let w_m = omega.pow_vartime([u64::from(n / (2 * m))]); + + let mut k = 0; + while k < n { + let mut w = Scalar::ONE; + for j in 0..m { + let mut t = a[(k + j + m) as usize]; + t.mul_assign(&w); + let mut tmp = a[(k + j) as usize]; + tmp.sub_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); + w.mul_assign(&w_m); + } + + k += 2 * m; + } + + m *= 2; + } +} + +#[cfg(test)] +mod test { + use crate::blstrs::{ + evaluation_domain::{smallest_power_of_2_greater_than_or_eq, EvaluationDomain}, + fft::fft_assign, + random::random_scalars, + }; + use rand::thread_rng; + + #[test] + #[allow(non_snake_case)] + fn fft_assign_full_domain() { + for n in [1, 2, 3, 5, 7, 8, 10, 16] { + let dom = EvaluationDomain::new(n).unwrap(); + let (N, _) = smallest_power_of_2_greater_than_or_eq(n); + + let mut rng = thread_rng(); + let mut f = random_scalars(n, &mut rng); + + assert_eq!(f.len(), n); + fft_assign(&mut f, &dom); + assert_eq!(f.len(), N); + } + } +} diff --git a/crates/aptos-dkg/src/algebra/lagrange.rs b/crates/aptos-crypto/src/blstrs/lagrange.rs similarity index 93% rename from crates/aptos-dkg/src/algebra/lagrange.rs rename to crates/aptos-crypto/src/blstrs/lagrange.rs index 2e9f742a792..926dd9809d1 100644 --- a/crates/aptos-dkg/src/algebra/lagrange.rs +++ b/crates/aptos-crypto/src/blstrs/lagrange.rs @@ -1,7 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::algebra::{ +//! Utilities for computing Lagrange coefficients and related polynomials over FFT evaluation domains. + +use crate::blstrs::{ evaluation_domain::BatchEvaluationDomain, fft::{fft, fft_assign}, polynomials::{accumulator_poly, poly_differentiate, poly_eval, poly_mul_slow}, @@ -34,9 +36,7 @@ pub fn all_n_lagrange_coefficients(dom: &BatchEvaluationDomain, alpha: &Scalar) let lhs_numerator = N_inverse * one_minus_alpha_to_N; // (1 - \alpha^N) / N let omegas = dom.get_all_roots_of_unity(); // \omega^i, for all i let mut denominators = omegas.clone(); // clone - for i in 0..dom.N() { - denominators[i] -= alpha // \omega^i - \alpha - } + denominators.iter_mut().for_each(|d| *d -= alpha); denominators.batch_invert(); // (\omega^i - \alpha)^{-1} @@ -105,9 +105,10 @@ pub fn all_lagrange_denominators( // If `include_zero`, need to: if include_zero { // 1. Augment A'(\omega_i) = A'(\omega_i) * \omega^i, for all i\ in [0, n) - for i in 0..n { - denoms[i] *= batch_dom.get_root_of_unity(i); - } + denoms + .iter_mut() + .enumerate() + .for_each(|(i, d)| *d *= batch_dom.get_root_of_unity(i)); // 2. Compute A'(0) = \prod_{j \in [0, n)} (0 - \omega^j) denoms.push((0..n).map(|i| -batch_dom.get_root_of_unity(i)).product()); @@ -206,7 +207,8 @@ fn accumulator_poly_helper(dom: &BatchEvaluationDomain, T: &[usize]) -> Vec Vec Vec, T: &[usize], Z_0: &Scalar) -> Vec { +fn compute_numerators_at_zero(omegas: &[Scalar], T: &[usize], Z_0: &Scalar) -> Vec { let N = omegas.len(); let mut numerators = Vec::with_capacity(T.len()); @@ -282,7 +282,7 @@ fn compute_numerators_at_zero(omegas: &Vec, T: &[usize], Z_0: &Scalar) - #[allow(non_snake_case)] fn compute_numerators( Z: &Vec, - omegas: &Vec, + omegas: &[Scalar], ids: &[usize], alpha: &Scalar, ) -> Vec { @@ -299,9 +299,9 @@ fn compute_numerators( // (\alpha - \omega^i)^{-1} numerators.batch_invert(); - for i in 0..numerators.len() { - // Z(\alpha) / (\alpha - \omega^i)^{-1} - numerators[i].mul_assign(Z_of_alpha); + for numerator in numerators.iter_mut() { + // Z(α) / (α - ω^i)^{-1} + numerator.mul_assign(Z_of_alpha); } numerators @@ -309,14 +309,13 @@ fn compute_numerators( #[cfg(test)] mod test { - use crate::{ - algebra::{ - evaluation_domain::BatchEvaluationDomain, - fft::fft_assign, - lagrange::{all_n_lagrange_coefficients, lagrange_coefficients, FFT_THRESH}, - polynomials::poly_eval, - }, - utils::random::{random_scalar, random_scalars}, + use crate::blstrs::{ + evaluation_domain::BatchEvaluationDomain, + fft::fft_assign, + lagrange::{all_n_lagrange_coefficients, lagrange_coefficients, FFT_THRESH}, + polynomials::poly_eval, + random::random_scalars, + random_scalar, }; use blstrs::Scalar; use ff::Field; diff --git a/crates/aptos-crypto/src/blstrs/mod.rs b/crates/aptos-crypto/src/blstrs/mod.rs new file mode 100644 index 00000000000..61c7ac39ead --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/mod.rs @@ -0,0 +1,194 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Utilities and helpers for working with BLS12-381 primitives used in Aptos. + +pub mod evaluation_domain; +pub mod fft; +pub mod lagrange; +pub mod polynomials; +pub mod random; +pub mod scalar_secret_key; +pub mod threshold_config; + +use crate::CryptoMaterialError; +use blstrs::{Bls12, G1Affine, G1Projective, G2Prepared, G2Projective, Gt, Scalar}; +use ff::Field; +use group::Curve; +use num_bigint::{BigUint, RandBigInt}; +use num_integer::Integer; +use num_traits::Zero; +use once_cell::sync::Lazy; +use pairing::{MillerLoopResult, MultiMillerLoop}; + +/// The size in bytes of a scalar. +pub const SCALAR_NUM_BYTES: usize = 32; + +/// The size in bytes of a compressed G1 point (efficiently deserializable into projective coordinates) +pub const G1_PROJ_NUM_BYTES: usize = 48; + +/// The size in bytes of a compressed G2 point (efficiently deserializable into projective coordinates) +pub const G2_PROJ_NUM_BYTES: usize = 96; + +/// The order of the BLS12-381 scalar field as a BigUint +pub static SCALAR_FIELD_ORDER: Lazy = Lazy::new(get_scalar_field_order_as_biguint); + +/// Returns the order of the scalar field in our implementation's choice of an elliptic curve group. +pub(crate) fn get_scalar_field_order_as_biguint() -> BigUint { + let r = BigUint::from_bytes_be( + hex::decode("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") + .unwrap() + .as_slice(), + ); + + // Here, we paranoically assert that r is correct, by checking 0 - 1 mod r (computed via Scalar) equals r-1 (computed from the constant above) + let minus_one = Scalar::ZERO - Scalar::ONE; + let max = &r - 1u8; + assert_eq!( + minus_one.to_bytes_le().as_slice(), + max.to_bytes_le().as_slice() + ); + + r +} + +/// Converts a BigUint to a scalar, asserting it fits, panicking otherwise. +/// +/// Useful when picking a random scalar and when hashing a message into a scalar. +pub fn biguint_to_scalar(big_uint: &BigUint) -> Scalar { + // `blstrs`'s `Scalar::from_bytes_le` needs `SCALAR_NUM_BYTES` bytes. The current + // implementation of `BigUint::to_bytes_le()` does not always return `SCALAR_NUM_BYTES` bytes + // when the integer is smaller than 32 bytes. So we have to pad it. + let mut bytes = big_uint.to_bytes_le(); + + while bytes.len() < SCALAR_NUM_BYTES { + bytes.push(0u8); + } + + debug_assert_eq!(BigUint::from_bytes_le(&bytes), *big_uint); + + let slice = match <&[u8; SCALAR_NUM_BYTES]>::try_from(bytes.as_slice()) { + Ok(slice) => slice, + Err(_) => { + panic!( + "WARNING: Got {} bytes instead of {SCALAR_NUM_BYTES} (i.e., got {})", + bytes.as_slice().len(), + big_uint + ); + }, + }; + + Scalar::from_bytes_le(slice) + .expect("Deserialization of randomly-generated num_bigint::BigUint failed.") +} + +/// Creates a scalar from a big-endian array of bytes, by reducing the number modulo the scalar field order. +/// +/// WARNING: Proceed with caution, if using this to sample a random scalar from a seed, then the +/// number of bytes should >= 2 * SCALAR_NUM_BYTES. +pub fn scalar_from_uniform_be_bytes(bytes: &[u8]) -> Scalar { + let bignum = BigUint::from_bytes_be(bytes); + let remainder = bignum.mod_floor(&SCALAR_FIELD_ORDER); + + biguint_to_scalar(&remainder) +} + +/// Helper method to *securely* parse a sequence of bytes into a `G1Projective` point. +/// NOTE: This function will check for prime-order subgroup membership in $\mathbb{G}_1$. +pub fn g1_proj_from_bytes(bytes: &[u8]) -> Result { + let slice = match <&[u8; G1_PROJ_NUM_BYTES]>::try_from(bytes) { + Ok(slice) => slice, + Err(_) => return Err(CryptoMaterialError::WrongLengthError), + }; + + let a = G1Projective::from_compressed(slice); + + if a.is_some().unwrap_u8() == 1u8 { + Ok(a.unwrap()) + } else { + Err(CryptoMaterialError::DeserializationError) + } +} + +/// Helper method to *securely* parse a sequence of bytes into a `G2Projective` point. +/// NOTE: This function will check for prime-order subgroup membership in $\mathbb{G}_2$. +pub fn g2_proj_from_bytes(bytes: &[u8]) -> Result { + let slice = match <&[u8; G2_PROJ_NUM_BYTES]>::try_from(bytes) { + Ok(slice) => slice, + Err(_) => return Err(CryptoMaterialError::WrongLengthError), + }; + + let a = G2Projective::from_compressed(slice); + + if a.is_some().unwrap_u8() == 1u8 { + Ok(a.unwrap()) + } else { + Err(CryptoMaterialError::DeserializationError) + } +} + +/// Helper method to *securely* parse a sequence of bytes into a `Scalar`. +pub fn scalar_from_bytes_le(bytes: &[u8]) -> Result { + let slice = match <&[u8; SCALAR_NUM_BYTES]>::try_from(bytes) { + Ok(slice) => slice, + Err(_) => return Err(CryptoMaterialError::WrongLengthError), + }; + + let opt = Scalar::from_bytes_le(slice); + if opt.is_some().unwrap_u8() == 1u8 { + Ok(opt.unwrap()) + } else { + Err(CryptoMaterialError::DeserializationError) + } +} + +/// Computes a multi-pairing. +pub fn multi_pairing<'a, I1, I2>(lhs: I1, rhs: I2) -> Gt +where + I1: Iterator, + I2: Iterator, +{ + let res = ::multi_miller_loop( + lhs.zip(rhs) + .map(|(g1, g2)| (g1.to_affine(), G2Prepared::from(g2.to_affine()))) + .collect::>() + .iter() + .map(|(g1, g2)| (g1, g2)) + .collect::>() + .as_slice(), + ); + + res.final_exponentiation() +} + +/// Returns a random `blstrs::Scalar`. +/// +/// Pretty fast: 623 nanosecond / call. +pub fn random_scalar(rng: &mut R) -> Scalar +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + random_scalar_internal(rng, false) +} + +/// Returns a random `blstrs::Scalar`, optionally restricted to be non-zero. +pub fn random_scalar_internal(rng: &mut R, exclude_zero: bool) -> Scalar +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut big_uint; + + loop { + // NOTE(Alin): This uses rejection-sampling (e.g., https://cs.stackexchange.com/a/2578/54866) + // An alternative would be to sample twice the size of the scalar field and use + // `random_scalar_from_uniform_bytes`, but that is actually slower (950ns vs 623ns) + big_uint = rng.gen_biguint_below(&SCALAR_FIELD_ORDER); + + // Some key material cannot be zero since it needs to have an inverse in the scalar field. + if !exclude_zero || !big_uint.is_zero() { + break; + } + } + + biguint_to_scalar(&big_uint) +} diff --git a/crates/aptos-crypto/src/blstrs/polynomials.rs b/crates/aptos-crypto/src/blstrs/polynomials.rs new file mode 100644 index 00000000000..260e9a72e65 --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/polynomials.rs @@ -0,0 +1,666 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Polynomial utilities and threshold secret sharing for BLSTRS-based cryptography. + +use crate::{ + blstrs::{ + evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, + fft, + random::random_scalars, + threshold_config::ThresholdConfigBlstrs, + }, + input_secret::InputSecret, +}; +use ark_ff::Field; +use blstrs::Scalar; +use ff::Field as FieldOld; +use more_asserts::debug_assert_le; +use std::ops::{AddAssign, Mul, MulAssign, SubAssign}; + +/// Checks whether a given `usize` is a power of two. +#[inline] +pub fn is_power_of_two(n: usize) -> bool { + n != 0 && (n & (n - 1) == 0) +} + +/// Computes the derivative of a polynomial given its coefficients. +pub fn differentiate(coeffs: &[F]) -> Vec { + let degree = coeffs.len().saturating_sub(1); + let mut result = Vec::with_capacity(degree); + + for i in 0..degree { + result.push(coeffs[i + 1].mul(F::from((i + 1) as u64))); + } + + result +} + +/// Computes the derivative of a polynomial in-place, modifying the input vector. +pub fn differentiate_in_place(coeffs: &mut Vec) { + let degree = coeffs.len() - 1; + for i in 0..degree { + coeffs[i] = coeffs[i + 1].mul(F::from((i + 1) as u64)); + } + + coeffs.truncate(degree); +} + +/// Computes a batch of quotient evaluations of the form `(f_i - y) / (x_i - x)` +/// for slices of field elements `f_vals` and `x_vals`. +/// +/// Useful to compute the scalars needed to interpolate a KZG proof (i.e., a quotient commitment) for $f(\gamma) = y$ as +/// $\pi = sum_i ( f(\omega^i) - f(\gamma) ) / (\omega^i - \gamma) ) * L_i$ +/// Here, $y_i = f(\omega^i), x_i$ = \omega^i, y=f(\gamma) and $x=\gamma$. +/// +/// # Arguments +/// * `f_vals` - Slice of field elements representing `f_i`. +/// * `x_vals` - Slice of field elements representing `x_i`. Must have the same length as `f_vals`. +/// * `x` - The field element `x` appearing in each denominator `(x_i - x)`. +/// * `y` - The field element `y` subtracted from each `f_i` in the numerator. +/// +/// # Returns +/// A `Vec` containing the evaluations of `(f_i - y) / (x_i - x)` for each index `i`. +/// Or will panic if one of the `x_i` equals `x`. +pub fn quotient_evaluations_batch(f_vals: &[F], x_vals: &[F], x: F, y: F) -> Vec { + assert_eq!(f_vals.len(), x_vals.len()); + + // Step 1: compute denominators x_i - x + let mut denoms: Vec = x_vals.iter().map(|&xi| xi - x).collect(); + + // Step 2: batch inversion in place + ark_ff::batch_inversion(&mut denoms); + + // Step 3: multiply numerators by inverses + f_vals + .iter() + .zip(denoms.iter()) + .map(|(&f_val, &denom_inv)| (f_val - y) * denom_inv) + .collect() +} + +/// Evaluate a polynomial given in Lagrange basis (i.e., given by its values at roots of unity) +/// using the barycentric formula in a field `F`. +/// +/// `evals[j] = f(roots_of_unity_in_eval_dom[j])` +/// +/// # Arguments +/// * `evals` - evaluations of the polynomial at the roots of unity +/// * `roots_of_unity_in_eval_dom` - the roots of unity +/// * `x` - the point at which to evaluate the polynomial +/// * `n_inv` - precomputed inverse of n, where n is the number roots of unity +/// +/// # Returns +/// * `f(x)` in `F` +pub fn barycentric_eval( + evals: &[F], + roots_of_unity_in_eval_dom: &[F], + x: F, + n_inv: F, +) -> F { + let n = evals.len(); + assert_eq!(n, roots_of_unity_in_eval_dom.len()); + debug_assert_eq!(n_inv, F::from(n as u64).inverse().unwrap()); + + let mut denoms = Vec::with_capacity(roots_of_unity_in_eval_dom.len()); + + for (&omega_j, &val) in roots_of_unity_in_eval_dom.iter().zip(evals.iter()) { + let denom = x - omega_j; + if denom.is_zero() { + // x exactly matches a root, so we can return early + return val; + } + denoms.push(denom); + } + + // Compute prefactor: (x^n - 1) / n + let mut z_pow_n = x.pow([n as u64]); + z_pow_n -= F::one(); + let prefactor = z_pow_n * n_inv; + + // Efficient batch inversion + ark_ff::batch_inversion(&mut denoms); // Using `batch_inversion_and_mul()` here instead shouldn't speed things up + + // Compute sum_j (omega^j * f(omega^j) * (prefactor / (x - omega^j))) + let mut sum = F::zero(); + for ((omega_j, &f_j), &inv_pref_denom_j) in roots_of_unity_in_eval_dom + .iter() + .zip(evals.iter()) + .zip(denoms.iter()) + { + sum += *omega_j * f_j * inv_pref_denom_j; + } + sum *= prefactor; + sum +} + +/// Returns $\[1, \tau, \tau^2, \tau^3, \ldots, \tau^{n-1}\]$. +pub fn get_powers_of_tau(tau: &Scalar, n: usize) -> Vec { + if n == 0 { + return vec![]; + } + + let mut taus = Vec::with_capacity(n); + + taus.push(Scalar::ONE); + + for _ in 0..n - 1 { + taus.push(taus.last().unwrap().mul(tau)); + } + debug_assert_eq!(taus.len(), n); + + taus +} + +/// Returns $\[\tau, \tau^2, \tau^3, \ldots, \tau^n\]$. +pub fn get_nonzero_powers_of_tau(tau: &Scalar, n: usize) -> Vec { + let mut taus = Vec::with_capacity(n); + + taus.push(*tau); + + for _ in 0..n - 1 { + taus.push(taus.last().unwrap().mul(tau)); + } + debug_assert_eq!(taus.len(), n); + + taus +} + +/// Returns the size of the evaluation domain needed to multiply these two polynomials via FFT. +pub fn get_evaluation_dom_size_for_multiplication(f: &[Scalar], g: &[Scalar]) -> usize { + //println!("get_eval_dom: |f| = {}, |g| = {}", f.len(), g.len()); + let f_deg = f.len() - 1; + let g_deg = g.len() - 1; + + // The degree $d$ of $f \cdot g$ will be $\deg{f} + \deg{g}$. + let fg_deg = f_deg + g_deg; + // But we need $d+1$ evaluations to interpolate a degree $d$ polynomial. + fg_deg + 1 +} + +/// Returns an evaluation domain for an FFT of size the number of coefficients in the polynomial $f(X) \cdot g(X)$. +pub fn get_evaluation_dom_for_multiplication(f: &[Scalar], g: &[Scalar]) -> EvaluationDomain { + let num_evals = get_evaluation_dom_size_for_multiplication(f, g); + EvaluationDomain::new(num_evals).unwrap() +} + +/// Returns $f(x)$ for a polynomial $f$ and a point $x$. +pub fn poly_eval(f: &Vec, x: &Scalar) -> Scalar { + assert!(!f.is_empty()); + + //let deg = f.len() - 1; + let mut eval = Scalar::ZERO; // f(x) + let mut x_i = Scalar::ONE; // x^i, i = {0, 1, ..., deg(f)} + for c_i in f { + eval += c_i * x_i; + + x_i *= x; + } + + eval +} + +/// Lets $f(X) = f(X) + g(X)$. Stores the result in `f` so assumes $\deg(f) \ge \deg(g)$. +pub fn poly_add_assign(f: &mut Vec, g: &[Scalar]) { + if g.len() > f.len() { + f.resize(g.len(), Scalar::ZERO); + } + + for i in 0..g.len() { + f[i].add_assign(g[i]); + } +} + +/// Lets $f(X) = f(X) - g(X)$. Stores the result in `f` so assumes $\deg(f) \ge \deg(g)$. +pub fn poly_sub_assign(f: &mut Vec, g: &[Scalar]) { + if g.len() > f.len() { + f.resize(g.len(), Scalar::ZERO); + } + for i in 0..g.len() { + f[i].sub_assign(g[i]); + } +} + +/// Returns $g(X) = a f(X)$. +pub fn poly_mul_scalar(f: &[Scalar], a: Scalar) -> Vec { + let mut g = f.to_owned(); + for c in g.iter_mut() { + c.mul_assign(&a); + } + g +} + +/// Divide `f(x)` by `x^n+c`. Polys are in coef repr, least significant coef first. +pub fn poly_div_xnc(mut coefs: Vec, n: usize, c: Scalar) -> (Vec, Vec) { + let max_degree = coefs.len() - 1 - n; + let mut quotient = vec![Scalar::ZERO; max_degree + 1]; + for i in (n..coefs.len()).rev() { + let coef = coefs.pop().unwrap(); + quotient[i - n] = coef; + coefs[i - n] -= c * coef; + } + (quotient, coefs) +} + +/// Computes the product of $f$ and $g$, letting $f = f \cdot g$ and $g = FFT(g)$. +/// Let $d = \deg(f) + \deg(g)$. Takes $O(d\log{d})$ time via three FFT. +/// +/// Note: If you already have an `EvaluationDomain` for $n = \deg(f) + \deg(g) + 1$, use the faster +/// `poly_mul_assign_fft_with_dom` which avoids recomputing the roots of unity and the other inverses. +pub fn poly_mul_assign_fft(f: &mut Vec, g: &mut Vec) { + debug_assert!(!f.is_empty()); + debug_assert!(!g.is_empty()); + + poly_mul_assign_fft_with_dom(f, g, &get_evaluation_dom_for_multiplication(f, g)) +} + +/// Like `poly_mul_assign` but returns the result, instead of modifying the arguments. +pub fn poly_mul_fft(f: &[Scalar], g: &[Scalar]) -> Vec { + debug_assert!(!f.is_empty()); + debug_assert!(!g.is_empty()); + + let mut f_copy = f.to_owned(); + let mut g_copy = g.to_owned(); + + poly_mul_assign_fft_with_dom( + &mut f_copy, + &mut g_copy, + &get_evaluation_dom_for_multiplication(f, g), + ); + + f_copy +} + +/// If the caller already has an `EvaluationDomain` for $n = \deg(f) + \deg(g) + 1$, this function +/// will avoid some redundant field operations and be slightly faster than `poly_mul_assign_fft`. +pub fn poly_mul_assign_fft_with_dom( + f: &mut Vec, + g: &mut Vec, + dom: &EvaluationDomain, +) { + debug_assert!(!f.is_empty()); + debug_assert!(!g.is_empty()); + debug_assert_eq!((f.len() - 1) + (g.len() - 1) + 1, dom.n); + + fft::fft_assign(f, dom); + fft::fft_assign(g, dom); + for i in 0..dom.N { + f[i].mul_assign(g[i]); + } + + fft::ifft_assign(f, dom); + f.truncate(dom.n); +} + +/// Like `poly_mul_assign_fft` but slower in time $\deg(f) \cdot \deg(g)$ and returns the product in +/// `out`, leaving `f` and `g` untouched. +/// TODO(Performance): Can we do this in-place over `f` or `g` without a separate `out`. +pub fn poly_mul_assign_slow(f: &[Scalar], g: &[Scalar], out: &mut Vec) { + assert!(!f.is_empty()); + assert!(!g.is_empty()); + + let f_len = f.len(); + let g_len = g.len(); + + // Set `out` to all zeros. + out.truncate(0); // Rust docs say "Note that this method has no effect on the allocated capacity of the vector." + out.resize(f_len + g_len - 1, Scalar::ZERO); + for (i1, a) in f.iter().enumerate() { + for (i2, b) in g.iter().enumerate() { + let mut prod = *a; + prod.mul_assign(b); + out[i1 + i2].add_assign(&prod); + } + } +} + +/// Like `poly_mul_fft` but slower: runs in time $\deg(f) \cdot \deg(g)$. +/// Returns the product, leaving `f` and `g` untouched. +/// +/// Performance notes: Beats FFT for $t \ge 32$. +pub fn poly_mul_slow(f: &[Scalar], g: &[Scalar]) -> Vec { + let mut out = Vec::with_capacity(get_evaluation_dom_size_for_multiplication(f, g)); + // println!( + // "poly_mul_slow: |f| = {}, |g| = {}, |out| = {}", + // f.len(), + // g.len(), + // out.capacity() + // ); + poly_mul_assign_slow(f, g, &mut out); + out +} + +/// Like `poly_mul_assign_fft` but runs in time $O(n)^{1.58})$. +/// Assumes that $\deg{f} - 1 = \deg{g} - 1 = 2^k$ for some $k$. +/// Returns the product in `out`, leaving `f` and `g` untouched. +/// +/// Performance notes: Starts beating `poly_mul_slow` after $t \ge 512$. Never beats FFT, so useless +/// because FFT beats naive after $t > 64$. +pub fn poly_mul_assign_less_slow(f: &Vec, g: &Vec, out: &mut Vec) { + let mut result = poly_mul_less_slow(f.as_slice(), g.as_slice()); + + out.truncate(0); + out.append(&mut result); +} + +/// Multiplies two polynomials over the scalar field using a divide-and-conquer approach. +pub fn poly_mul_less_slow(f: &[Scalar], g: &[Scalar]) -> Vec { + let n = f.len(); + assert!(is_power_of_two(n)); + + // TODO(Performance): Let the base case be the naive n^2 multiplication for any f_len < threshold? + // handle base case + if n == 1 { + return vec![f[0].mul(g[0])]; + } + + let g_len = g.len(); + let half_n = n / 2; + assert_eq!(n, g_len); + + // split f into halves + let f_0 = &f[0..half_n]; + let f_1 = &f[half_n..n]; + debug_assert_eq!(f_0.len() + f_1.len(), n); + + // split g into halves + let g_0 = &g[0..half_n]; + let g_1 = &g[half_n..n]; + debug_assert_eq!(g_0.len() + g_1.len(), n); + + // let f_01 = f_0 + f_1 + let mut f_01 = Vec::with_capacity(half_n); + f_0.clone_into(&mut f_01); + for i in 0..half_n { + f_01[i].add_assign(f_1[i]); + } + + // let g_01 = g_0 + g_1 + let mut g_01 = Vec::with_capacity(half_n); + g_0.clone_into(&mut g_01); + for i in 0..half_n { + g_01[i].add_assign(g_1[i]); + } + + // $y = (f_0 + f_1) \cdot (g_0 + g_1)$ + let mut y = poly_mul_less_slow(&f_01, &g_01); + // $z = f_0 \cdot g_0$ + let mut z = poly_mul_less_slow(f_1, g_1); + // $u = f_1 \cdot g_0$ + let mut u = poly_mul_less_slow(f_0, g_0); + + // first, compute (y - u - z) + poly_sub_assign(&mut y, &u); + poly_sub_assign(&mut y, &z); + + // second, compute (y - u - z) * X^{n/2} + poly_xnmul_assign(&mut y, half_n); + + // third, compute z * X^n + poly_xnmul_assign(&mut z, n); + + // fourth, add everything up with $u(X)$ + poly_add_assign(&mut u, &y); + poly_add_assign(&mut u, &z); + + u +} + +/// Sets $f(X) = f(X) \cdot X^n$, by simply shifting the coefficients. +/// As always we assume $\deg{f}$ is `f.len() - 1`. +pub fn poly_xnmul_assign(f: &mut Vec, n: usize) { + if n == 0 { + return; + } + + let old_len = f.len(); + + // extend with zero coefficients for X^n, X^{n-1}, \dots, X + f.resize(old_len + n, Scalar::ZERO); + + // Shift coefficients by `n` positions + f.copy_within(0..old_len, n); + + // Set the last n coefficients $f_{n-1}, \cdots, f_0$ to 0. + f[..n].fill(Scalar::ZERO); +} + +/// Like `poly_mul_by_xn_assign` but returns the result. +pub fn poly_xnmul(f: &[Scalar], n: usize) -> Vec { + if n == 0 { + return f.to_owned(); + } + + let len = n + f.len(); + + // let result = f + let mut result = Vec::with_capacity(len); + result.resize(f.len(), Scalar::ZERO); + result.copy_from_slice(f); + + poly_xnmul_assign(&mut result, n); + + result +} + +/// Calculates the derivative of $f(X)$. +pub fn poly_differentiate(f: &mut Vec) { + let f_deg = f.len() - 1; + + for i in 0..f_deg { + f[i] = f[i + 1].mul(Scalar::from((i + 1) as u64)); + } + + f.truncate(f_deg); +} + +/// Given a set $S$ of scalars, returns the *accumulator* polynomial $Z(X) = \prod_{a \in S} (X - a)$. +#[allow(non_snake_case)] +pub fn accumulator_poly_slow(S: &[Scalar]) -> Vec { + let set_size = S.len(); + // println!("len: {len}"); + + if set_size == 0 { + return vec![]; + } else if set_size == 1 { + // println!("Returning (X - {})", S[0]); + return vec![-S[0], Scalar::ONE]; + } + + let m = set_size / 2; + // println!("m: {m}"); + + let left = &S[0..m]; + // println!("left: {}", left.len()); + let right = &S[m..set_size]; + // println!("right: {}", right.len()); + + let mut left_poly = accumulator_poly_slow(left); + let mut right_poly = accumulator_poly_slow(right); + if left_poly.is_empty() { + return right_poly; + } + if right_poly.is_empty() { + return left_poly; + } + + poly_mul_assign_fft(&mut left_poly, &mut right_poly); + + left_poly +} + +/// Like `accumulator_poly_slow` but: +/// - Avoids recomputing too many different roots of unity (EvaluationDomain::new takes 3.5 microsecs +/// and `accumulator_poly_slow` makes around 2000 calls to it). Saves 10 milliseconds out of total of 70. +/// - Avoids FFTs when multiplying polynomials with $\deg{f} + \deg{g} - 1 \le fft_thresh$. +/// Saves 35 milliseconds. +#[allow(non_snake_case)] +pub fn accumulator_poly( + S: &[Scalar], + batch_dom: &BatchEvaluationDomain, + fft_thresh: usize, +) -> Vec { + let set_size = S.len(); + + if set_size == 0 { + return vec![]; + } else if set_size == 1 { + return vec![-S[0], Scalar::ONE]; + } else if set_size == 2 { + return vec![ + S[0] * S[1], // X^0 coeff is (-1)^0 (S[0] S[1]) = S[0] S[1] + -(S[0] + S[1]), // X^1 coeff is (-1)^1 (S[0] + S[1]) = -(S[0] + S[1]) + Scalar::ONE, // X^2 coeff is 1 + ]; + } else if set_size == 3 { + // https://math.stackexchange.com/questions/88917/relation-betwen-coefficients-and-roots-of-a-polynomial + let s1_add_s2 = S[1] + S[2]; + let s1_mul_s2 = S[1] * S[2]; + + return vec![ + -(S[0] * s1_mul_s2), // X^3 coeff is -(S[0] S[1] S[2]) + S[0] * s1_add_s2 + s1_mul_s2, // X^2 coeff is S[0] S[1] + S[0] S[2] + S[1] S[2] + -(S[0] + S[1] + S[2]), // X^1 coeff is -(S[0] + S[1] + S[2]) + Scalar::ONE, // X^0 coeff is 1 + ]; + } + + let m = set_size / 2; + + let left = &S[0..m]; + let right = &S[m..set_size]; + + let mut left_poly = accumulator_poly(left, batch_dom, fft_thresh); + let mut right_poly = accumulator_poly(right, batch_dom, fft_thresh); + if left_poly.is_empty() { + return right_poly; + } + if right_poly.is_empty() { + return left_poly; + } + + let dom_size = get_evaluation_dom_size_for_multiplication(&left_poly, &right_poly); + if dom_size < fft_thresh { + poly_mul_slow(&left_poly, &right_poly) + } else { + poly_mul_assign_fft_with_dom( + &mut left_poly, + &mut right_poly, + &batch_dom.get_subdomain(dom_size), + ); + left_poly + } +} + +/// More wisely schedules the sizes of the polynomials that are multiplied via FFT. Specifically, +/// always ensures we are multiplying degree (2^k - 1) by degree 2^k, to get a degree (2^{k+1} - 1) +/// polynomial. This ensures optimal usage of the 3 FFTs: the first two FFTs on the degree 2^k - 1 +/// and degree 2^k have 50% usage, while the last inverse FFT that outputs 2^{k+1} coefficients has +/// 100% usage. +/// +/// Expected this to be much faster than `accumulator_poly` but seems to beat by at most 1 millisecond +/// for the following parameters: +/// +/// 128 FFT thresh, 256 naive -thresh > 15.4 ms +/// 256 FFT thresh, 512 naive thresh -> 14.8 ms +/// 256 FFT thresh, 128 naive thresh -> 14.1 ms +#[allow(non_snake_case)] +pub fn accumulator_poly_scheduled( + S: &[Scalar], + batch_dom: &BatchEvaluationDomain, + naive_thresh: usize, + fft_thresh: usize, +) -> Vec { + let mut n = S.len() + 1; + + if S.len() < naive_thresh { + // println!("Directly returning accumulator for set size {}", S.len()); + return accumulator_poly(S, batch_dom, fft_thresh); + } + + let mut batch_size = 1; + while n != 1 { + n /= 2; + batch_size *= 2; + } + batch_size -= 1; // 2^k - 1 <= |S| + + debug_assert_le!(batch_size, S.len()); + assert!(is_power_of_two(batch_size + 1)); + + let left = + accumulator_poly_scheduled_inner(&S[0..batch_size], batch_dom, naive_thresh, fft_thresh); + if batch_size == S.len() { + left + } else { + let right = + accumulator_poly_scheduled(&S[batch_size..], batch_dom, naive_thresh, fft_thresh); + + poly_mul_fft(&left, &right) + } +} + +#[allow(non_snake_case)] +fn accumulator_poly_scheduled_inner( + S: &[Scalar], + batch_dom: &BatchEvaluationDomain, + naive_thresh: usize, + fft_thresh: usize, +) -> Vec { + let len = S.len(); + debug_assert!(is_power_of_two(len + 1)); + + if len < naive_thresh { + // println!("Directly returning accumulator for set size {len}"); + return accumulator_poly(S, batch_dom, fft_thresh); + } + + let batch_size = len.div_ceil(2) - 1; + debug_assert_eq!(batch_size * 2 + 1, len); + + let mut b1 = + accumulator_poly_scheduled_inner(&S[0..batch_size], batch_dom, naive_thresh, fft_thresh); + debug_assert_eq!(b1.len(), batch_size + 1); + let b2 = accumulator_poly_scheduled_inner( + &S[batch_size..2 * batch_size], + batch_dom, + naive_thresh, + fft_thresh, + ); + debug_assert_eq!(b2.len(), batch_size + 1); + let deg1 = accumulator_poly(&S[2 * batch_size..], batch_dom, fft_thresh); + debug_assert_eq!(deg1.len(), 2); + + // println!( + // "Multiplying deg-{} by deg-{}", + // b1.len() - 1, + // b2.len() - 1 + deg1.len() - 1 + // ); + + let mut b2 = poly_mul_slow(°1, &b2); + poly_mul_assign_fft_with_dom(&mut b1, &mut b2, &batch_dom.get_subdomain(len + 1)); + + b1 +} + +/// Deals a secret `s` in a `t`-out-of-`n` fashion (as per `sc`) returning (1) the degree `t-1` +/// polynomial encoding the secret and (2) its evaluations at all the `n` $N$th roots-of-unity where +/// $N$ is the smallest power of two $\ge n$. +/// +/// Any `t` evaluations are sufficient to reconstruct the secret `s`. +pub fn shamir_secret_share< + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +>( + sc: &ThresholdConfigBlstrs, + s: &InputSecret, + rng: &mut R, +) -> (Vec, Vec) { + // A random, degree t-1 polynomial $f(X) = [a_0, \dots, a_{t-1}]$, with $a_0$ set to `s.a` + let mut f = random_scalars(sc.t, rng); + f[0] = *s.get_secret_a(); + + // Evaluate $f$ at all the $N$th roots of unity. + let mut f_evals = fft::fft(&f, sc.get_evaluation_domain()); + f_evals.truncate(sc.n); + (f, f_evals) +} diff --git a/crates/aptos-crypto/src/blstrs/random.rs b/crates/aptos-crypto/src/blstrs/random.rs new file mode 100644 index 00000000000..e617cdc34fe --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/random.rs @@ -0,0 +1,203 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Utilities for generating random scalars and elliptic curve points for BLS12-381. + +use crate::blstrs::{ + biguint_to_scalar, G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_FIELD_ORDER, SCALAR_NUM_BYTES, +}; +/// TODO(Security): This file is a workaround for the `rand_core_hell` issue, briefly described below. +/// +/// Ideally, we would write the following sane code: +/// +/// ```ignore +/// let mut dk = Scalar::random(rng); +/// while dk.is_zero() { +/// dk = Scalar::random(rng); +/// } +/// ``` +/// +/// But we can't due to `aptos-crypto`'s dependency on an older version of `rand` and `rand_core` +/// compared to `blstrs`'s dependency. +use blstrs::{G1Projective, G2Projective, Gt, Scalar}; +use group::Group; +use num_bigint::BigUint; +use num_integer::Integer; +use std::ops::Mul; + +/// Domain-separator for hash-based randomness generation that works around `rand_core_hell`. +pub const DST_RAND_CORE_HELL: &[u8; 24] = b"APTOS_RAND_CORE_HELL_DST"; + +/// Returns a random non-zero `blstrs::Scalar`. +pub fn random_nonzero_scalar(rng: &mut R) -> Scalar +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + crate::blstrs::random_scalar_internal(rng, true) +} + +/// Generates a `blstrs::Scalar` from a uniform byte array. +pub fn random_scalar_from_uniform_bytes(bytes: &[u8; 2 * SCALAR_NUM_BYTES]) -> Scalar { + let bignum = BigUint::from_bytes_le(&bytes[..]); + let remainder = bignum.mod_floor(&SCALAR_FIELD_ORDER); + + biguint_to_scalar(&remainder) +} + +/// Generates a random 128-bit `blstrs::Scalar`. +pub fn random_128bit_scalar(rng: &mut R) -> Scalar +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut low_bytes = [0u8; SCALAR_NUM_BYTES / 2]; + rng.fill(&mut low_bytes[..]); + + // Create a 32-byte array (little-endian) by extending the 128-bit number with zeros + let mut full_bytes = [0u8; SCALAR_NUM_BYTES]; + + // Copy the 128-bit random number to the lower half of the 32-byte array + full_bytes[..SCALAR_NUM_BYTES / 2].copy_from_slice(&low_bytes); + + Scalar::from_bytes_le(&full_bytes).unwrap() +} + +/// Returns a random `blstrs::G1Projective` given an older RNG as input. +/// +/// Slow: Takes 50 microseconds. +pub fn random_g1_point(rng: &mut R) -> G1Projective +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut rand_seed = [0u8; 2 * G1_PROJ_NUM_BYTES]; + rng.fill(rand_seed.as_mut_slice()); + + G1Projective::hash_to_curve(rand_seed.as_slice(), DST_RAND_CORE_HELL, b"G1") +} + +/// Returns a random `blstrs::G2Projective` given an older RNG as input. +/// +/// Slow: Takes 150 microseconds. +pub fn random_g2_point(rng: &mut R) -> G2Projective +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut rand_seed = [0u8; 2 * G2_PROJ_NUM_BYTES]; + rng.fill(rand_seed.as_mut_slice()); + + G2Projective::hash_to_curve(rand_seed.as_slice(), DST_RAND_CORE_HELL, b"G2") +} + +/// Returns a random `blstrs::GTProjective` given an older RNG as input. +/// +/// Takes 507 microseconds. +/// +/// NOTE: This function is "insecure" in the sense that the caller learns the discrete log of the +/// random G_T point w.r.t. the generator. In many applications, this is not acceptable. +pub fn insecure_random_gt_point(rng: &mut R) -> Gt +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let s = crate::blstrs::random_scalar(rng); + + // TODO(TestingPerf): Cannot sample more efficiently than this because `fp12::Fp12` is not exposed. + Gt::generator().mul(s) +} + +/// Returns a vector of random `blstrs::Scalar`'s, given an RNG as input. +pub fn random_scalars(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut v = Vec::with_capacity(n); + + for _ in 0..n { + v.push(crate::blstrs::random_scalar(rng)); + } + + debug_assert_eq!(v.len(), n); + + v +} + +/// Returns a vector of random `blstrs::G1Projective`'s, given an RNG as input. +pub fn random_g1_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut v = Vec::with_capacity(n); + + for _ in 0..n { + v.push(random_g1_point(rng)); + } + + debug_assert_eq!(v.len(), n); + + v +} + +/// Returns a vector of random `blstrs::G2Projective`'s, given an RNG as input. +pub fn random_g2_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut v = Vec::with_capacity(n); + + for _ in 0..n { + v.push(random_g2_point(rng)); + } + + debug_assert_eq!(v.len(), n); + + v +} + +/// Returns a vector of random `blstrs::GT`'s, given an RNG as input. +/// +/// WARNING: Insecure. See `insecure_random_gt_point` comments. +pub fn insecure_random_gt_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let mut v = Vec::with_capacity(n); + + for _ in 0..n { + v.push(insecure_random_gt_point(rng)); + } + + debug_assert_eq!(v.len(), n); + + v +} + +/// Sometimes we will want to generate somewhat random-looking points for benchmarking, so we will +/// use this faster **insecure** function instead. +pub fn insecure_random_g1_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let point = random_g1_point(rng); + let shift = random_g1_point(rng); + let mut acc = point; + (0..n) + .map(|_| { + acc = acc.double() + shift; + acc + }) + .collect::>() +} + +/// Like `insecure_random_g1_points` but for G_2. +pub fn insecure_random_g2_points(n: usize, rng: &mut R) -> Vec +where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, +{ + let point = random_g2_point(rng); + let shift = random_g2_point(rng); + let mut acc = point; + (0..n) + .map(|_| { + acc = acc.double() + shift; + acc + }) + .collect::>() +} diff --git a/crates/aptos-crypto/src/blstrs/scalar_secret_key.rs b/crates/aptos-crypto/src/blstrs/scalar_secret_key.rs new file mode 100644 index 00000000000..a518588fae2 --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/scalar_secret_key.rs @@ -0,0 +1,45 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Implements unweighted threshold secret reconstruction for BLSTRS scalars. + +use crate::{ + arkworks::shamir::{Reconstructable, ShamirShare}, + blstrs::{lagrange::lagrange_coefficients, threshold_config::ThresholdConfigBlstrs}, + traits::{SecretSharingConfig as _, ThresholdConfig as _}, +}; +use blstrs::Scalar; +use ff::Field; +use more_asserts::{assert_ge, assert_le}; + +impl Reconstructable for Scalar { + type ShareValue = Scalar; + + fn reconstruct( + sc: &ThresholdConfigBlstrs, + shares: &[ShamirShare], + ) -> anyhow::Result { + assert_ge!(shares.len(), sc.get_threshold()); + assert_le!(shares.len(), sc.get_total_num_players()); + + let ids = shares.iter().map(|(p, _)| p.id).collect::>(); + let lagr = lagrange_coefficients( + sc.get_batch_evaluation_domain(), + ids.as_slice(), + &Scalar::ZERO, + ); + let shares = shares + .iter() + .map(|(_, share)| *share) + .collect::>(); + + // TODO should this return a + assert_eq!(lagr.len(), shares.len()); + + Ok(shares + .iter() + .zip(lagr.iter()) + .map(|(&share, &lagr)| share * lagr) + .sum::()) + } +} diff --git a/crates/aptos-crypto/src/blstrs/threshold_config.rs b/crates/aptos-crypto/src/blstrs/threshold_config.rs new file mode 100644 index 00000000000..b83ef1d3ea9 --- /dev/null +++ b/crates/aptos-crypto/src/blstrs/threshold_config.rs @@ -0,0 +1,154 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Threshold secret sharing configuration for BLSTRS-based PVSS. + +use crate::{ + blstrs::evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, + player::Player, + traits::{self, ThresholdConfig as _}, +}; +use anyhow::anyhow; +use rand::{seq::IteratorRandom, Rng}; +use rand_core::{CryptoRng, RngCore}; +use serde::{Deserialize, Deserializer, Serialize}; +use std::fmt::{Display, Formatter}; + +/// Encodes the *threshold configuration* for a normal/unweighted PVSS: i.e., the threshold $t$ and +/// the number of players $n$ such that any $t$ or more players can reconstruct a dealt secret given +/// a PVSS transcript. Due to the last fields, this struct should only be used in the context of `blstrs` +#[derive(Clone, PartialEq, Serialize, Debug, Eq)] +pub struct ThresholdConfigBlstrs { + /// The reconstruction threshold $t$ that must be exceeded in order to reconstruct the dealt + /// secret; i.e., $t$ or more shares are needed + pub t: usize, + /// The total number of players involved in the PVSS protocol + pub n: usize, + /// Evaluation domain consisting of the $N$th root of unity and other auxiliary information + /// needed to compute an FFT of size $N$. + #[serde(skip)] + dom: EvaluationDomain, + /// Batch evaluation domain, consisting of all the $N$th roots of unity (in the scalar field), + /// where N is the smallest power of two such that n <= N. + #[serde(skip)] + batch_dom: BatchEvaluationDomain, +} + +impl<'de> Deserialize<'de> for ThresholdConfigBlstrs { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Deserialize only the serializable fields (t, n) + #[derive(Deserialize)] + struct SerializedFields { + t: usize, + n: usize, + } + + let serialized = SerializedFields::deserialize(deserializer)?; + + // Rebuild the skipped fields using `new` + ThresholdConfigBlstrs::new(serialized.t, serialized.n).map_err(serde::de::Error::custom) + } +} + +impl ThresholdConfigBlstrs { + /// Returns a reference to the precomputed batch evaluation domain. + pub fn get_batch_evaluation_domain(&self) -> &BatchEvaluationDomain { + &self.batch_dom + } + + /// Returns a reference to the primary evaluation domain. + pub fn get_evaluation_domain(&self) -> &EvaluationDomain { + &self.dom + } +} + +impl Display for ThresholdConfigBlstrs { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "threshold/{}-out-of-{}", self.t, self.n) + } +} + +impl traits::SecretSharingConfig for ThresholdConfigBlstrs { + /// For testing only. + fn get_random_player(&self, rng: &mut R) -> Player + where + R: RngCore + CryptoRng, + { + Player { + id: rng.gen_range(0, self.n), + } + } + + /// For testing only. + fn get_random_eligible_subset_of_players(&self, mut rng: &mut R) -> Vec + where + R: RngCore, + { + (0..self.get_total_num_shares()) + .choose_multiple(&mut rng, self.t) + .into_iter() + .map(|i| self.get_player(i)) + .collect::>() + } + + fn get_total_num_players(&self) -> usize { + self.n + } + + fn get_total_num_shares(&self) -> usize { + self.n + } +} + +impl traits::ThresholdConfig for ThresholdConfigBlstrs { + /// Creates a new $t$ out of $n$ secret sharing configuration where any subset of $t$ or more + /// players can reconstruct the secret. + fn new(t: usize, n: usize) -> anyhow::Result { + if t == 0 { + return Err(anyhow!("expected the reconstruction threshold to be > 0")); + } + + if n == 0 { + return Err(anyhow!("expected the number of shares to be > 0")); + } + + if t > n { + return Err(anyhow!( + "expected the reconstruction threshold {t} to be < than the number of shares {n}" + )); + } + + let batch_dom = BatchEvaluationDomain::new(n); + let dom = batch_dom.get_subdomain(n); + Ok(ThresholdConfigBlstrs { + t, + n, + dom, + batch_dom, + }) + } + + /// Returns the threshold $t$. Recall that $\ge t$ shares are needed to reconstruct. + fn get_threshold(&self) -> usize { + self.t + } +} + +#[cfg(test)] +mod test { + use crate::{blstrs::threshold_config::ThresholdConfigBlstrs, traits::ThresholdConfig as _}; + + #[test] + fn create_many_configs() { + let mut _tcs = vec![]; + + for t in 1..100 { + for n in t..100 { + _tcs.push(ThresholdConfigBlstrs::new(t, n).unwrap()) + } + } + } +} diff --git a/crates/aptos-crypto/src/constant_time/blstrs_scalar_mul.rs b/crates/aptos-crypto/src/constant_time/blstrs_scalar_mul.rs new file mode 100644 index 00000000000..f1116d76c1d --- /dev/null +++ b/crates/aptos-crypto/src/constant_time/blstrs_scalar_mul.rs @@ -0,0 +1,124 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use blstrs::{G1Projective, Scalar}; +use dudect_bencher::{ + rand::{seq::SliceRandom, CryptoRng, Rng, RngCore}, + BenchRng, Class, CtRunner, +}; +use group::Group; +use num_bigint::BigUint; +use std::{hint::black_box, ops::Mul}; + +const BIT_SIZE: usize = 255; +const N: usize = 5_000; + +/// Runs a statistical test to check that blst's scalar multiplication on G1 is constant time +/// This function pick random bases for all scalar multiplications. +pub fn run_bench_with_random_bases(runner: &mut CtRunner, rng: &mut BenchRng) { + build_and_run_bench(runner, rng, true, N); +} + +/// Runs a statistical test to check that blst's scalar multiplication on G1 is constant time +/// This function keeps the multiplied base the same: the generator of G1. +pub fn run_bench_with_fixed_bases(runner: &mut CtRunner, rng: &mut BenchRng) { + build_and_run_bench(runner, rng, false, N); +} + +fn random_scalar_with_k_bits_set(rng: &mut R, k: usize) -> Scalar { + const NUM_BYTES: usize = BIT_SIZE.div_ceil(8); + // Note: if k == 255 => all bits will be set to 1 => infinite loop + // (i.e., the sorted version of `selected` will always be [0, 1, ..., 254]) + assert!( + k < BIT_SIZE, + "k must be < the field's bit size {}", + BIT_SIZE + ); + + loop { + // uniformly pick k distinct bit positions + let mut positions: Vec = (0..(BIT_SIZE as u64)).collect(); + positions.shuffle(rng); + let selected = &positions[..k]; + + // build the integer with those bits set + let mut bigint = BigUint::default(); + for &bit in selected { + bigint.set_bit(bit, true); + } + + // accept only if < modulus (i.e., a valid canonical representative) + let mut bytes = bigint.to_bytes_le(); + while bytes.len() < NUM_BYTES { + bytes.push(0u8); + } + let opt = Scalar::from_bytes_le(<&[u8; NUM_BYTES]>::try_from(bytes.as_slice()).unwrap()); + if opt.is_some().unwrap_u8() == 1 { + return opt.unwrap(); + } + // else: resample; this keeps the result uniform over valid k-bit elements + } +} + +/// WARNING: Blindly following the same "pattern" as in the dudect examples for how to "build" the +/// testcases. This coin flipping to decided whether to pick "left" or "right" feels awkward to me, +/// but I'd need to read their paper to understand better. It could've also been done by the +/// framework itself. The queing up of the inputs is also odd: why not run the benchmark immediately +/// after generating the input? +/// +/// Note: We could technically implement this more abstractly via traits (may be painful) or macros, +/// since this is duplicated across this file and the `zkcrypto` file. +pub fn build_and_run_bench( + runner: &mut CtRunner, + rng: &mut BenchRng, + random_bases: bool, + num_iters: usize, +) { + let mut inputs: Vec<(Class, usize, Scalar, G1Projective)> = Vec::with_capacity(N); + + let min_num_bits_left = 1; + let max_num_bits_left = 4; + let num_bits_right = 200; //BIT_SIZE.div_ceil(2) + 1; + eprintln!(); + eprintln!( + "# of 1 bits in scalars for \"left\" class is in [{}, {})", + min_num_bits_left, max_num_bits_left + ); + eprintln!( + "# of 1 bits in scalars for \"right\" class is always {}", + num_bits_right + ); + + for _ in 0..num_iters { + let base = if random_bases { + G1Projective::random(&mut *rng) + } else { + G1Projective::generator() + }; + let choice = rng.r#gen::(); + + if choice { + // WARNING: `blstrs` is faster when the scalar is exactly 0! + let num_bits_left = rng.gen_range(min_num_bits_left..max_num_bits_left); + inputs.push(( + Class::Left, + num_bits_left, + random_scalar_with_k_bits_set(rng, num_bits_left), + base, + )); + } else { + inputs.push(( + Class::Right, + num_bits_right, + random_scalar_with_k_bits_set(rng, num_bits_right), + base, + )); + } + } + + for (class, _k, sk, base) in inputs { + runner.run_one(class, || { + let _ = black_box(base.mul(&sk)); + }) + } +} diff --git a/crates/aptos-crypto/src/constant_time/mod.rs b/crates/aptos-crypto/src/constant_time/mod.rs new file mode 100644 index 00000000000..7a3443cc83a --- /dev/null +++ b/crates/aptos-crypto/src/constant_time/mod.rs @@ -0,0 +1,10 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides implementations of "dudect" statistical tests to check some of our code +//! is constant-time (e.g., like scalar multiplication). + +/// Module for testing that blstrs scalar multiplication is constant-time +pub mod blstrs_scalar_mul; +/// Module for testing that zkcrypto scalar multiplication is constant-time +pub mod zkcrypto_scalar_mul; diff --git a/crates/aptos-crypto/src/constant_time/zkcrypto_scalar_mul.rs b/crates/aptos-crypto/src/constant_time/zkcrypto_scalar_mul.rs new file mode 100644 index 00000000000..c8eb1201c35 --- /dev/null +++ b/crates/aptos-crypto/src/constant_time/zkcrypto_scalar_mul.rs @@ -0,0 +1,103 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use bls12_381::{G1Projective, Scalar}; +use dudect_bencher::{ + rand::{seq::SliceRandom, CryptoRng, Rng, RngCore}, + BenchRng, Class, CtRunner, +}; +use num_bigint::BigUint; +use std::{hint::black_box, ops::Mul}; + +const BIT_SIZE: usize = 255; + +/// Runs a statistical test to check that zkcrypto's scalar multiplication on G1 is constant time. +pub fn run_bench(runner: &mut CtRunner, rng: &mut BenchRng) { + build_and_run_bench(runner, rng, |sk, g1| g1.mul(sk)); +} + +fn random_scalar_with_k_bits_set(rng: &mut R, k: usize) -> Scalar { + const NUM_BYTES: usize = BIT_SIZE.div_ceil(8); + // Note: if k == 255 => all bits will be set to 1 => infinite loop + // (i.e., the sorted version of `selected` will always be [0, 1, ..., 254]) + assert!( + k < BIT_SIZE, + "k must be < the field's bit size {}", + BIT_SIZE + ); + + loop { + // uniformly pick k distinct bit positions + let mut positions: Vec = (0..(BIT_SIZE as u64)).collect(); + positions.shuffle(rng); + let selected = &positions[..k]; + + // build the integer with those bits set + let mut bigint = BigUint::default(); + for &bit in selected { + bigint.set_bit(bit, true); + } + + // accept only if < modulus (i.e., a valid canonical representative) + let mut bytes = bigint.to_bytes_le(); + while bytes.len() < NUM_BYTES { + bytes.push(0u8); + } + let opt = Scalar::from_bytes(<&[u8; NUM_BYTES]>::try_from(bytes.as_slice()).unwrap()); + if opt.is_some().unwrap_u8() == 1 { + return opt.unwrap(); + } + // else: resample; this keeps the result uniform over valid k-bit elements + } +} + +/// WARNING: See comment in `build_and_run_bench` in blstrs_scalar_mul.rs +fn build_and_run_bench(runner: &mut CtRunner, rng: &mut BenchRng, scalar_mul_fn: F) +where + F: Fn(&Scalar, &G1Projective) -> G1Projective, +{ + let g1 = G1Projective::generator(); + + const N: usize = 10_000; + + let mut inputs: Vec<(Class, usize, Scalar, G1Projective)> = Vec::with_capacity(N); + + let min_num_bits_left = 0; + let max_num_bits_left = 4; + let num_bits_right = BIT_SIZE.div_ceil(2) + 1; + eprintln!(); + eprintln!( + "# of 1 bits in scalars for \"left\" class is in [{}, {})", + min_num_bits_left, max_num_bits_left + ); + eprintln!( + "# of 1 bits in scalars for \"right\" class is always {}", + num_bits_right + ); + for _ in 0..N { + let choice = rng.r#gen::(); + + if choice { + let num_bits_left = rng.gen_range(min_num_bits_left..max_num_bits_left); + inputs.push(( + Class::Left, + num_bits_left, + random_scalar_with_k_bits_set(rng, num_bits_left), + g1, + )); + } else { + inputs.push(( + Class::Right, + num_bits_right, + random_scalar_with_k_bits_set(rng, num_bits_right), + g1, + )); + } + } + + for (class, _k, sk, base) in inputs { + runner.run_one(class, || { + black_box(scalar_mul_fn(&sk, &base)); + }) + } +} diff --git a/crates/aptos-crypto/src/hash.rs b/crates/aptos-crypto/src/hash.rs index fef36b66f86..ab45494e9fc 100644 --- a/crates/aptos-crypto/src/hash.rs +++ b/crates/aptos-crypto/src/hash.rs @@ -164,7 +164,7 @@ impl HashValue { /// Creates a random instance with given rng. Useful in unit tests. pub fn random_with_rng(rng: &mut R) -> Self { - rng.gen() + rng.r#gen() } /// Convenience function that computes a `HashValue` internally equal to @@ -413,7 +413,7 @@ impl FromStr for HashValue { impl Distribution for Standard { fn sample(&self, rng: &mut R) -> HashValue { - HashValue { hash: rng.gen() } + HashValue { hash: rng.r#gen() } } } diff --git a/crates/aptos-crypto/src/input_secret.rs b/crates/aptos-crypto/src/input_secret.rs new file mode 100644 index 00000000000..868ad277d9c --- /dev/null +++ b/crates/aptos-crypto/src/input_secret.rs @@ -0,0 +1,82 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Input secrets for the PVSS (Publicly Verifiable Secret Sharing) dealing protocol. + +use crate::{blstrs::random_scalar, Uniform}; +use aptos_crypto_derive::{SilentDebug, SilentDisplay}; +use blstrs::Scalar; +use ff::Field; +use num_traits::Zero; +use rand_core::{CryptoRng, RngCore}; +use std::ops::{Add, AddAssign}; + +/// The *input secret* that will be given as input to the PVSS dealing algorithm. This will be of a +/// different type than the *dealt secret* that will be returned by the PVSS reconstruction algorithm. +/// +/// This secret will NOT need to be stored by validators because a validator (1) picks such a secret +/// and (2) deals it via the PVSS. If the validator crashes during dealing, the entire task will be +/// restarted with a freshly-generated input secret. +#[derive(SilentDebug, SilentDisplay, PartialEq)] +pub struct InputSecret { + /// The actual secret being dealt; a scalar $a \in F$. + a: Scalar, +} + +/// Make sure input secrets can be added together. +impl Add<&InputSecret> for InputSecret { + type Output = InputSecret; + + fn add(self, rhs: &InputSecret) -> Self::Output { + InputSecret { + a: self.a.add(rhs.a), + } + } +} + +impl AddAssign<&InputSecret> for InputSecret { + fn add_assign(&mut self, rhs: &InputSecret) { + self.a.add_assign(rhs.a) + } +} + +impl Add for InputSecret { + type Output = InputSecret; + + fn add(self, rhs: InputSecret) -> Self::Output { + InputSecret { + a: self.a.add(rhs.a), + } + } +} + +impl Zero for InputSecret { + fn zero() -> Self { + InputSecret { a: Scalar::ZERO } + } + + fn is_zero(&self) -> bool { + self.a.is_zero_vartime() + } +} + +#[cfg(feature = "assert-private-keys-not-cloneable")] +static_assertions::assert_not_impl_any!(InputSecret: Clone); + +impl InputSecret { + /// Returns a reference to the underlying scalar value of the input secret. + pub fn get_secret_a(&self) -> &Scalar { + &self.a + } +} + +impl Uniform for InputSecret { + fn generate(rng: &mut R) -> Self + where + R: RngCore + CryptoRng, + { + let a = random_scalar(rng); + + InputSecret { a } + } +} diff --git a/crates/aptos-crypto/src/lib.rs b/crates/aptos-crypto/src/lib.rs index 2141f191d4a..b9f7e788643 100644 --- a/crates/aptos-crypto/src/lib.rs +++ b/crates/aptos-crypto/src/lib.rs @@ -6,25 +6,32 @@ #![deny(missing_docs)] //! A library supplying various cryptographic primitives +pub mod arkworks; pub mod asymmetric_encryption; pub mod bls12381; pub mod bulletproofs; pub mod compat; +pub mod constant_time; pub mod ed25519; pub mod elgamal; pub mod encoding_type; pub mod error; pub mod hash; pub mod hkdf; +pub mod input_secret; pub mod multi_ed25519; pub mod noise; +pub mod player; pub mod secp256k1_ecdsa; pub mod secp256r1_ecdsa; pub mod test_utils; pub mod traits; +pub mod utils; pub mod validatable; +pub mod weighted_config; pub mod x25519; +pub mod blstrs; pub mod poseidon_bn254; #[cfg(test)] mod unit_tests; diff --git a/crates/aptos-crypto/src/multi_ed25519.rs b/crates/aptos-crypto/src/multi_ed25519.rs index 5d988c44d6d..cdbfb25bdee 100644 --- a/crates/aptos-crypto/src/multi_ed25519.rs +++ b/crates/aptos-crypto/src/multi_ed25519.rs @@ -525,7 +525,8 @@ impl Signature for MultiEd25519Signature { )) }, }; - if bitmap_count_ones(self.bitmap) < public_key.threshold as u32 { + let num_ones_in_bitmap = bitmap_count_ones(self.bitmap); + if num_ones_in_bitmap < public_key.threshold as u32 { return Err(anyhow!( "{}", CryptoMaterialError::BitVecError( @@ -533,13 +534,25 @@ impl Signature for MultiEd25519Signature { ) )); } + if num_ones_in_bitmap != self.signatures.len() as u32 { + return Err(anyhow!( + "{}", + CryptoMaterialError::BitVecError( + "Bitmap ones and signatures count are not equal".to_string() + ) + )); + } let mut bitmap_index = 0; // TODO: Eventually switch to deterministic batch verification for sig in &self.signatures { while !bitmap_get_bit(self.bitmap, bitmap_index) { bitmap_index += 1; } - sig.verify_arbitrary_msg(message, &public_key.public_keys[bitmap_index])?; + let pk = public_key + .public_keys + .get(bitmap_index) + .ok_or_else(|| anyhow::anyhow!("Public key index {bitmap_index} out of bounds"))?; + sig.verify_arbitrary_msg(message, pk)?; bitmap_index += 1; } Ok(()) diff --git a/crates/aptos-crypto/src/player.rs b/crates/aptos-crypto/src/player.rs new file mode 100644 index 00000000000..e65a83ab8fb --- /dev/null +++ b/crates/aptos-crypto/src/player.rs @@ -0,0 +1,34 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Defines a struct to represents a participant (player) in a protocol. + +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use serde::{Deserialize, Serialize}; + +/// An identifier from 0 to n-1 for the n players involved in the PVSS protocol. +#[derive( + CanonicalSerialize, + CanonicalDeserialize, + Copy, + Debug, + PartialEq, + Eq, + Clone, + Serialize, + Deserialize, +)] +pub struct Player { + /// A number from 0 to n-1. + pub id: usize, +} + +/// The point of Player is to provide type-safety: ensure nobody creates out-of-range player IDs. +/// So there is no `new()` method; only the SecretSharingConfig trait is allowed to create them. +// TODO: AFAIK the only way to really enforce this is to put both traits inside the same module (or use unsafe Rust) +impl Player { + /// Returns the numeric ID of the player. + pub fn get_id(&self) -> usize { + self.id + } +} diff --git a/crates/aptos-crypto/src/traits.rs b/crates/aptos-crypto/src/traits.rs deleted file mode 100644 index 0d392851888..00000000000 --- a/crates/aptos-crypto/src/traits.rs +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright © Aptos Foundation -// Parts of the project are originally copyright © Meta Platforms, Inc. -// SPDX-License-Identifier: Apache-2.0 - -//! This module provides a generic set of traits for dealing with cryptographic primitives. -//! -//! For examples on how to use these traits, see the implementations of the [`crate::ed25519`] - -use crate::hash::{CryptoHash, CryptoHasher}; -use anyhow::Result; -use core::convert::{From, TryFrom}; -use rand::{rngs::StdRng, CryptoRng, RngCore, SeedableRng}; -use serde::{de::DeserializeOwned, Serialize}; -use std::{fmt::Debug, hash::Hash}; -use thiserror::Error; - -/// An error type for key and signature validation issues, see [`ValidCryptoMaterial`]. -/// -/// This enum reflects there are two interesting causes of validation -/// failure for the ingestion of key or signature material: deserialization errors -/// (often, due to mangled material or curve equation failure for ECC) and -/// validation errors (material recognizable but unacceptable for use, -/// e.g. unsafe). -#[derive(Clone, Debug, PartialEq, Eq, Error)] -#[error("{:?}", self)] -pub enum CryptoMaterialError { - /// Struct to be signed does not serialize correctly. - SerializationError, - /// Key or signature material does not deserialize correctly. - DeserializationError, - /// Key or signature material deserializes, but is otherwise not valid. - ValidationError, - /// Key, threshold or signature material does not have the expected size. - WrongLengthError, - /// Part of the signature or key is not canonical resulting to malleability issues. - CanonicalRepresentationError, - /// A curve point (i.e., a public key) lies on a small group. - SmallSubgroupError, - /// A curve point (i.e., a public key) does not satisfy the curve equation. - PointNotOnCurveError, - /// BitVec errors in accountable multi-sig schemes. - BitVecError(String), -} - -/// The serialized length of the data that enables macro derived serialization and deserialization. -pub trait Length { - /// The serialized length of the data - fn length(&self) -> usize; -} - -/// Key or more generally crypto material with a notion of byte validation. -/// -/// A type family for material that knows how to serialize and -/// deserialize, as well as validate byte-encoded material. The -/// validation must be implemented as a [`TryFrom`] which -/// classifies its failures against the above -/// [`CryptoMaterialError`]. -/// -/// This provides an implementation for a validation that relies on a -/// round-trip to bytes and corresponding [`TryFrom`]. -pub trait ValidCryptoMaterial: - // The for<'a> exactly matches the assumption "deserializable from any lifetime". - for<'a> TryFrom<&'a [u8], Error=CryptoMaterialError> + Serialize + DeserializeOwned -{ - /// Prefix for AIP-80 e.g. ed25519-priv - const AIP_80_PREFIX: &'static str; - - /// Convert the valid crypto material to bytes. - fn to_bytes(&self) -> Vec; -} - -/// An extension to/from Strings for [`ValidCryptoMaterial`]. -/// -/// Relies on [`hex`] for string encoding / decoding. -/// No required fields, provides a default implementation. -pub trait ValidCryptoMaterialStringExt: ValidCryptoMaterial { - /// When trying to convert from bytes, we simply decode the string into - /// bytes before checking if we can convert. - fn from_encoded_string(encoded_str: &str) -> std::result::Result { - let mut str = encoded_str; - // First strip the AIP-80 prefix - str = str.strip_prefix(Self::AIP_80_PREFIX).unwrap_or(str); - - // Strip 0x at beginning if there is one - str = str.strip_prefix("0x").unwrap_or(str); - - let bytes_out = ::hex::decode(str); - // We defer to `try_from` to make sure we only produce valid crypto materials. - bytes_out - // We reinterpret a failure to serialize: key is mangled someway. - .or(Err(CryptoMaterialError::DeserializationError)) - .and_then(|ref bytes| Self::try_from(bytes)) - } - - /// A function to encode into hex-string after serializing. - fn to_encoded_string(&self) -> Result { - Ok(format!("0x{}", ::hex::encode(self.to_bytes()))) - } - - /// Creates an AIP-80 formatted string for the crypto material - fn to_aip_80_string(&self) -> Result { - let bytes = self.to_encoded_string()?; - Ok(format!("{}{}", Self::AIP_80_PREFIX, bytes)) - } -} - -// There's nothing required in this extension, so let's just derive it -// for anybody that has a ValidCryptoMaterial. -impl ValidCryptoMaterialStringExt for T {} - -/// A type family for key material that should remain secret and has an -/// associated type of the [`PublicKey`] family. -pub trait PrivateKey: Sized { - /// We require public / private types to be coupled, i.e. their - /// associated type is each other. - type PublicKeyMaterial: PublicKey; - - /// Returns the associated public key - fn public_key(&self) -> Self::PublicKeyMaterial { - self.into() - } -} - -/// A type family of valid keys that know how to sign. -/// -/// This trait has a requirement on a `pub(crate)` marker trait meant to -/// specifically limit its implementations to the present crate. -/// -/// A trait for a [`ValidCryptoMaterial`] which knows how to sign a -/// message, and return an associated `Signature` type. -pub trait SigningKey: - PrivateKey::VerifyingKeyMaterial> - + ValidCryptoMaterial - + private::Sealed -{ - /// The associated verifying key type for this signing key. - type VerifyingKeyMaterial: VerifyingKey; - /// The associated signature type for this signing key. - type SignatureMaterial: Signature; - - /// Signs an object that has an distinct domain-separation hasher and - /// that we know how to serialize. There is no pre-hashing into a - /// `HashValue` to be done by the caller. - /// - /// Note: this assumes serialization is infallible. See crates::bcs::ser - /// for a discussion of this assumption. - fn sign( - &self, - message: &T, - ) -> Result; - - /// Signs a non-hash input message. For testing only. - #[cfg(any(test, feature = "fuzzing"))] - fn sign_arbitrary_message(&self, message: &[u8]) -> Self::SignatureMaterial; - - /// Returns the associated verifying key - fn verifying_key(&self) -> Self::VerifyingKeyMaterial { - self.public_key() - } -} - -/// Returns the signing message for the given message. -/// It is used by `SigningKey#sign` function. -pub fn signing_message( - message: &T, -) -> Result, CryptoMaterialError> { - let mut bytes = ::seed().to_vec(); - bcs::serialize_into(&mut bytes, &message) - .map_err(|_| CryptoMaterialError::SerializationError)?; - Ok(bytes) -} - -/// A type for key material that can be publicly shared, and in asymmetric -/// fashion, can be obtained from a [`PrivateKey`] -/// reference. -/// This convertibility requirement ensures the existence of a -/// deterministic, canonical public key construction from a private key. -pub trait PublicKey: Sized + Clone + Eq + Hash + ValidCryptoMaterial + - // This unsightly turbofish type parameter is the precise constraint - // needed to require that there exists an - // - // ``` - // impl From<&MyPrivateKeyMaterial> for MyPublicKeyMaterial - // ``` - // - // declaration, for any `MyPrivateKeyMaterial`, `MyPublicKeyMaterial` - // on which we register (respectively) `PublicKey` and `PrivateKey` - // implementations. - for<'a> From<&'a ::PrivateKeyMaterial> { - /// We require public / private types to be coupled, i.e. their - /// associated type is each other. - type PrivateKeyMaterial: PrivateKey; -} - -/// A type family of public keys that are used for signing. -/// -/// This trait has a requirement on a `pub(crate)` marker trait meant to -/// specifically limit its implementations to the present crate. -/// -/// It is linked to a type of the Signature family, which carries the -/// verification implementation. -pub trait VerifyingKey: - PublicKey::SigningKeyMaterial> - + ValidCryptoMaterial - + private::Sealed -{ - /// The associated signing key type for this verifying key. - type SigningKeyMaterial: SigningKey; - /// The associated signature type for this verifying key. - type SignatureMaterial: Signature; - - /// We provide the striaghtfoward implementation which dispatches to the signature. - fn verify_struct_signature( - &self, - message: &T, - signature: &Self::SignatureMaterial, - ) -> Result<()> { - signature.verify(message, self) - } - - /// We provide the implementation which dispatches to the signature. - fn batch_verify( - message: &T, - keys_and_signatures: Vec<(Self, Self::SignatureMaterial)>, - ) -> Result<()> { - Self::SignatureMaterial::batch_verify(message, keys_and_signatures) - } -} - -/// A type family for signature material that knows which public key type -/// is needed to verify it, and given such a public key, knows how to -/// verify. -/// -/// This trait simply requires an association to some type of the -/// [`PublicKey`] family of which we are the `SignatureMaterial`. -/// -/// This trait has a requirement on a `pub(crate)` marker trait meant to -/// specifically limit its implementations to the present crate. -/// -/// It should be possible to write a generic signature function that -/// checks signature material passed as `&[u8]` and only returns Ok when -/// that material de-serializes to a signature of the expected concrete -/// scheme. This would be done as an extension trait of -/// [`Signature`]. -pub trait Signature: - for<'a> TryFrom<&'a [u8], Error = CryptoMaterialError> - + Sized - + Debug - + Clone - + Eq - + Hash - + private::Sealed -{ - /// The associated verifying key type for this signature. - type VerifyingKeyMaterial: VerifyingKey; - /// The associated signing key type for this signature - type SigningKeyMaterial: SigningKey; - - /// Verification for a struct we unabmiguously know how to serialize and - /// that we have a domain separation prefix for. - fn verify( - &self, - message: &T, - public_key: &Self::VerifyingKeyMaterial, - ) -> Result<()>; - - /// Native verification function. - fn verify_arbitrary_msg( - &self, - message: &[u8], - public_key: &Self::VerifyingKeyMaterial, - ) -> Result<()>; - - /// Convert the signature into a byte representation. - fn to_bytes(&self) -> Vec; - - /// The implementer can override a batch verification implementation - /// that by default iterates over each signature. More efficient - /// implementations exist and should be implemented for many schemes. - fn batch_verify( - message: &T, - keys_and_signatures: Vec<(Self::VerifyingKeyMaterial, Self)>, - ) -> Result<()> { - for (key, signature) in keys_and_signatures { - signature.verify(message, &key)? - } - Ok(()) - } -} - -/// A type family for schemes which know how to generate key material from -/// a cryptographically-secure [`CryptoRng`]. -pub trait Uniform { - /// Generate key material from a cryptographically-secure RNG. - fn generate(rng: &mut R) -> Self - where - R: RngCore + CryptoRng; - - /// Generate a random key using the shared TEST_SEED - fn generate_for_testing() -> Self - where - Self: Sized, - { - let mut rng: StdRng = SeedableRng::from_seed(crate::test_utils::TEST_SEED); - Self::generate(&mut rng) - } -} - -/// A type family with a by-convention notion of genesis private key. -pub trait Genesis: PrivateKey { - /// Produces the genesis private key. - fn genesis() -> Self; -} - -/// A pub(crate) mod hiding a Sealed trait and its implementations, allowing -/// us to make sure implementations are constrained to the crypto crate. -// See https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed -pub(crate) mod private { - pub trait Sealed {} - - impl Sealed for crate::bls12381::PrivateKey {} - impl Sealed for crate::bls12381::PublicKey {} - impl Sealed for crate::bls12381::Signature {} - impl Sealed for crate::bls12381::ProofOfPossession {} - - impl Sealed for crate::ed25519::Ed25519PrivateKey {} - impl Sealed for crate::ed25519::Ed25519PublicKey {} - impl Sealed for crate::ed25519::Ed25519Signature {} - - impl Sealed for crate::multi_ed25519::MultiEd25519PrivateKey {} - impl Sealed for crate::multi_ed25519::MultiEd25519PublicKey {} - impl Sealed for crate::multi_ed25519::MultiEd25519Signature {} - - impl Sealed for crate::secp256r1_ecdsa::PrivateKey {} - impl Sealed for crate::secp256r1_ecdsa::PublicKey {} - impl Sealed for crate::secp256r1_ecdsa::Signature {} - - impl Sealed for crate::secp256k1_ecdsa::PrivateKey {} - impl Sealed for crate::secp256k1_ecdsa::PublicKey {} - impl Sealed for crate::secp256k1_ecdsa::Signature {} -} diff --git a/crates/aptos-crypto/src/traits/mod.rs b/crates/aptos-crypto/src/traits/mod.rs new file mode 100644 index 00000000000..dfb7a420248 --- /dev/null +++ b/crates/aptos-crypto/src/traits/mod.rs @@ -0,0 +1,385 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides a generic set of traits for dealing with cryptographic primitives. +//! +//! For examples on how to use these traits, see the implementations of the [`crate::ed25519`] + +use crate::{ + hash::{CryptoHash, CryptoHasher}, + player::Player, +}; +use anyhow::Result; +use core::convert::{From, TryFrom}; +use more_asserts::assert_lt; +use rand::{rngs::StdRng, CryptoRng, RngCore, SeedableRng}; +use serde::{de::DeserializeOwned, Serialize}; +use std::{ + fmt::{Debug, Display}, + hash::Hash, +}; +use thiserror::Error; + +/// An error type for key and signature validation issues, see [`ValidCryptoMaterial`]. +/// +/// This enum reflects there are two interesting causes of validation +/// failure for the ingestion of key or signature material: deserialization errors +/// (often, due to mangled material or curve equation failure for ECC) and +/// validation errors (material recognizable but unacceptable for use, +/// e.g. unsafe). +#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[error("{:?}", self)] +pub enum CryptoMaterialError { + /// Struct to be signed does not serialize correctly. + SerializationError, + /// Key or signature material does not deserialize correctly. + DeserializationError, + /// Key or signature material deserializes, but is otherwise not valid. + ValidationError, + /// Key, threshold or signature material does not have the expected size. + WrongLengthError, + /// Part of the signature or key is not canonical resulting to malleability issues. + CanonicalRepresentationError, + /// A curve point (i.e., a public key) lies on a small group. + SmallSubgroupError, + /// A curve point (i.e., a public key) does not satisfy the curve equation. + PointNotOnCurveError, + /// BitVec errors in accountable multi-sig schemes. + BitVecError(String), +} + +/// The serialized length of the data that enables macro derived serialization and deserialization. +pub trait Length { + /// The serialized length of the data + fn length(&self) -> usize; +} + +/// Key or more generally crypto material with a notion of byte validation. +/// +/// A type family for material that knows how to serialize and +/// deserialize, as well as validate byte-encoded material. The +/// validation must be implemented as a [`TryFrom`] which +/// classifies its failures against the above +/// [`CryptoMaterialError`]. +/// +/// This provides an implementation for a validation that relies on a +/// round-trip to bytes and corresponding [`TryFrom`]. +pub trait ValidCryptoMaterial: + // The for<'a> exactly matches the assumption "deserializable from any lifetime". + for<'a> TryFrom<&'a [u8], Error=CryptoMaterialError> + Serialize + DeserializeOwned +{ + /// Prefix for AIP-80 e.g. ed25519-priv + const AIP_80_PREFIX: &'static str; + + /// Convert the valid crypto material to bytes. + fn to_bytes(&self) -> Vec; +} + +/// An extension to/from Strings for [`ValidCryptoMaterial`]. +/// +/// Relies on [`hex`] for string encoding / decoding. +/// No required fields, provides a default implementation. +pub trait ValidCryptoMaterialStringExt: ValidCryptoMaterial { + /// When trying to convert from bytes, we simply decode the string into + /// bytes before checking if we can convert. + fn from_encoded_string(encoded_str: &str) -> std::result::Result { + let mut str = encoded_str; + // First strip the AIP-80 prefix + str = str.strip_prefix(Self::AIP_80_PREFIX).unwrap_or(str); + + // Strip 0x at beginning if there is one + str = str.strip_prefix("0x").unwrap_or(str); + + let bytes_out = ::hex::decode(str); + // We defer to `try_from` to make sure we only produce valid crypto materials. + bytes_out + // We reinterpret a failure to serialize: key is mangled someway. + .or(Err(CryptoMaterialError::DeserializationError)) + .and_then(|ref bytes| Self::try_from(bytes)) + } + + /// A function to encode into hex-string after serializing. + fn to_encoded_string(&self) -> Result { + Ok(format!("0x{}", ::hex::encode(self.to_bytes()))) + } + + /// Creates an AIP-80 formatted string for the crypto material + fn to_aip_80_string(&self) -> Result { + let bytes = self.to_encoded_string()?; + Ok(format!("{}{}", Self::AIP_80_PREFIX, bytes)) + } +} + +// There's nothing required in this extension, so let's just derive it +// for anybody that has a ValidCryptoMaterial. +impl ValidCryptoMaterialStringExt for T {} + +/// A type family for key material that should remain secret and has an +/// associated type of the [`PublicKey`] family. +pub trait PrivateKey: Sized { + /// We require public / private types to be coupled, i.e. their + /// associated type is each other. + type PublicKeyMaterial: PublicKey; + + /// Returns the associated public key + fn public_key(&self) -> Self::PublicKeyMaterial { + self.into() + } +} + +/// A type family of valid keys that know how to sign. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// A trait for a [`ValidCryptoMaterial`] which knows how to sign a +/// message, and return an associated `Signature` type. +pub trait SigningKey: + PrivateKey::VerifyingKeyMaterial> + + ValidCryptoMaterial + + private::Sealed +{ + /// The associated verifying key type for this signing key. + type VerifyingKeyMaterial: VerifyingKey; + /// The associated signature type for this signing key. + type SignatureMaterial: Signature; + + /// Signs an object that has an distinct domain-separation hasher and + /// that we know how to serialize. There is no pre-hashing into a + /// `HashValue` to be done by the caller. + /// + /// Note: this assumes serialization is infallible. See crates::bcs::ser + /// for a discussion of this assumption. + fn sign( + &self, + message: &T, + ) -> Result; + + /// Signs a non-hash input message. For testing only. + #[cfg(any(test, feature = "fuzzing"))] + fn sign_arbitrary_message(&self, message: &[u8]) -> Self::SignatureMaterial; + + /// Returns the associated verifying key + fn verifying_key(&self) -> Self::VerifyingKeyMaterial { + self.public_key() + } +} + +/// Returns the signing message for the given message. +/// It is used by `SigningKey#sign` function. +pub fn signing_message( + message: &T, +) -> Result, CryptoMaterialError> { + let mut bytes = ::seed().to_vec(); + bcs::serialize_into(&mut bytes, &message) + .map_err(|_| CryptoMaterialError::SerializationError)?; + Ok(bytes) +} + +/// A type for key material that can be publicly shared, and in asymmetric +/// fashion, can be obtained from a [`PrivateKey`] +/// reference. +/// This convertibility requirement ensures the existence of a +/// deterministic, canonical public key construction from a private key. +pub trait PublicKey: Sized + Clone + Eq + Hash + ValidCryptoMaterial + + // This unsightly turbofish type parameter is the precise constraint + // needed to require that there exists an + // + // ``` + // impl From<&MyPrivateKeyMaterial> for MyPublicKeyMaterial + // ``` + // + // declaration, for any `MyPrivateKeyMaterial`, `MyPublicKeyMaterial` + // on which we register (respectively) `PublicKey` and `PrivateKey` + // implementations. + for<'a> From<&'a ::PrivateKeyMaterial> { + /// We require public / private types to be coupled, i.e. their + /// associated type is each other. + type PrivateKeyMaterial: PrivateKey; +} + +/// A type family of public keys that are used for signing. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// It is linked to a type of the Signature family, which carries the +/// verification implementation. +pub trait VerifyingKey: + PublicKey::SigningKeyMaterial> + + ValidCryptoMaterial + + private::Sealed +{ + /// The associated signing key type for this verifying key. + type SigningKeyMaterial: SigningKey; + /// The associated signature type for this verifying key. + type SignatureMaterial: Signature; + + /// We provide the straightforward implementation which dispatches to the signature. + fn verify_struct_signature( + &self, + message: &T, + signature: &Self::SignatureMaterial, + ) -> Result<()> { + signature.verify(message, self) + } + + /// We provide the implementation which dispatches to the signature. + fn batch_verify( + message: &T, + keys_and_signatures: Vec<(Self, Self::SignatureMaterial)>, + ) -> Result<()> { + Self::SignatureMaterial::batch_verify(message, keys_and_signatures) + } +} + +/// A type family for signature material that knows which public key type +/// is needed to verify it, and given such a public key, knows how to +/// verify. +/// +/// This trait simply requires an association to some type of the +/// [`PublicKey`] family of which we are the `SignatureMaterial`. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// It should be possible to write a generic signature function that +/// checks signature material passed as `&[u8]` and only returns Ok when +/// that material de-serializes to a signature of the expected concrete +/// scheme. This would be done as an extension trait of +/// [`Signature`]. +pub trait Signature: + for<'a> TryFrom<&'a [u8], Error = CryptoMaterialError> + + Sized + + Debug + + Clone + + Eq + + Hash + + private::Sealed +{ + /// The associated verifying key type for this signature. + type VerifyingKeyMaterial: VerifyingKey; + /// The associated signing key type for this signature + type SigningKeyMaterial: SigningKey; + + /// Verification for a struct we unabmiguously know how to serialize and + /// that we have a domain separation prefix for. + fn verify( + &self, + message: &T, + public_key: &Self::VerifyingKeyMaterial, + ) -> Result<()>; + + /// Native verification function. + fn verify_arbitrary_msg( + &self, + message: &[u8], + public_key: &Self::VerifyingKeyMaterial, + ) -> Result<()>; + + /// Convert the signature into a byte representation. + fn to_bytes(&self) -> Vec; + + /// The implementer can override a batch verification implementation + /// that by default iterates over each signature. More efficient + /// implementations exist and should be implemented for many schemes. + fn batch_verify( + message: &T, + keys_and_signatures: Vec<(Self::VerifyingKeyMaterial, Self)>, + ) -> Result<()> { + for (key, signature) in keys_and_signatures { + signature.verify(message, &key)? + } + Ok(()) + } +} + +/// A type family for schemes which know how to generate key material from +/// a cryptographically-secure [`CryptoRng`]. +pub trait Uniform { + /// Generate key material from a cryptographically-secure RNG. + fn generate(rng: &mut R) -> Self + where + R: RngCore + CryptoRng; + + /// Generate a random key using the shared TEST_SEED + fn generate_for_testing() -> Self + where + Self: Sized, + { + let mut rng: StdRng = SeedableRng::from_seed(crate::test_utils::TEST_SEED); + Self::generate(&mut rng) + } +} + +/// A type family with a by-convention notion of genesis private key. +pub trait Genesis: PrivateKey { + /// Produces the genesis private key. + fn genesis() -> Self; +} + +/// Trait defining the interface for secret sharing schemes. +pub trait SecretSharingConfig: Display { + /// Creates a new player ID; a number from 0 to `n-1`, where `n = get_total_num_players(&self)`. + fn get_player(&self, i: usize) -> Player { + let n = self.get_total_num_players(); + assert_lt!(i, n); + + Player { id: i } + } + + /// Useful during testing. + fn get_random_player(&self, rng: &mut R) -> Player + where + R: rand_core::RngCore + rand_core::CryptoRng; + + /// Returns a random subset of players who are capable of reconstructing the secret. + /// Useful during testing. + fn get_random_eligible_subset_of_players(&self, rng: &mut R) -> Vec + where + R: rand_core::RngCore; + + /// Returns the total number of players in the scheme. + fn get_total_num_players(&self) -> usize; + + /// Returns the total number of shares in the scheme. + fn get_total_num_shares(&self) -> usize; +} + +/// Trait for secret sharing schemes that expose a threshold `t`. +pub trait ThresholdConfig: SecretSharingConfig + Sized { + /// Constructs a new threshold configuration given `t` (threshold) and `n` (number of players). Only used in `get_threshold_configs_for_testing()`, maybe not ideal here + fn new(t: usize, n: usize) -> anyhow::Result; + + /// Returns the threshold `t` required to reconstruct the secret. + fn get_threshold(&self) -> usize; +} + +/// A pub(crate) mod hiding a Sealed trait and its implementations, allowing +/// us to make sure implementations are constrained to the crypto crate. +// See https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +pub(crate) mod private { + pub trait Sealed {} + + impl Sealed for crate::bls12381::PrivateKey {} + impl Sealed for crate::bls12381::PublicKey {} + impl Sealed for crate::bls12381::Signature {} + impl Sealed for crate::bls12381::ProofOfPossession {} + + impl Sealed for crate::ed25519::Ed25519PrivateKey {} + impl Sealed for crate::ed25519::Ed25519PublicKey {} + impl Sealed for crate::ed25519::Ed25519Signature {} + + impl Sealed for crate::multi_ed25519::MultiEd25519PrivateKey {} + impl Sealed for crate::multi_ed25519::MultiEd25519PublicKey {} + impl Sealed for crate::multi_ed25519::MultiEd25519Signature {} + + impl Sealed for crate::secp256r1_ecdsa::PrivateKey {} + impl Sealed for crate::secp256r1_ecdsa::PublicKey {} + impl Sealed for crate::secp256r1_ecdsa::Signature {} + + impl Sealed for crate::secp256k1_ecdsa::PrivateKey {} + impl Sealed for crate::secp256k1_ecdsa::PublicKey {} + impl Sealed for crate::secp256k1_ecdsa::Signature {} +} diff --git a/crates/aptos-crypto/src/unit_tests/arkworks_upgrade.rs b/crates/aptos-crypto/src/unit_tests/arkworks_upgrade.rs new file mode 100644 index 00000000000..6439d5fd66a --- /dev/null +++ b/crates/aptos-crypto/src/unit_tests/arkworks_upgrade.rs @@ -0,0 +1,192 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use ark_bls12_381::{Bls12_381 as Bls12_381New, G1Projective as G1New, G2Projective as G2New}; +use ark_bls12_381_old::{Bls12_381 as Bls12_381Old, G1Projective as G1Old, G2Projective as G2Old}; +use ark_ec::{pairing::Pairing as PairingNew, CurveGroup, PrimeGroup}; +use ark_ec_old::{pairing::Pairing as PairingOld, CurveGroup as CurveGroupOld, Group}; +use ark_ff::{BigInt as BigIntNew, BigInteger, Field, PrimeField, UniformRand}; +use ark_ff_old::{ + BigInt as BigIntOld, BigInteger as BigIntegerOld, Field as OldField, + PrimeField as PrimeFieldOld, Zero, +}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_serialize_old::{ + CanonicalDeserialize as CanonicalDeserializeOld, CanonicalSerialize as CanonicalSerializeOld, +}; +use ark_std::{rand::RngCore, test_rng}; + +#[test] +fn test_bigint_layout_compatibility() { + let mut rng = test_rng(); + let mut cases = vec![0u64, 1, u64::MAX, 1234567890123456789]; + + for _ in 0..100 { + cases.push(rng.next_u64()); + } + + for (i, &n) in cases.iter().enumerate() { + let old = BigIntOld::<4>::from(n); + let new = BigIntNew::<4>::from(n); + + let bits_old = old.to_bits_le(); + let bits_new = new.to_bits_le(); + assert_eq!(bits_old, bits_new, "Bit mismatch case {} (value={})", i, n); + + let new_from_old = BigIntNew::<4>::from_bits_le(&bits_old); + assert_eq!(new_from_old.to_bits_le(), bits_old); + + let old_from_new = BigIntOld::<4>::from_bits_le(&bits_new); + assert_eq!(old_from_new.to_bits_le(), bits_new); + } +} + +#[cfg(test)] +fn roundtrip_old_to_new(old: &TOld) -> TNew +where + TOld: CanonicalSerializeOld, + TNew: CanonicalDeserialize, +{ + let mut buf = Vec::new(); + old.serialize_compressed(&mut buf).unwrap(); + TNew::deserialize_compressed(&*buf).unwrap() +} + +#[cfg(test)] +fn roundtrip_new_to_old(old: &TOld) -> TNew +where + TOld: CanonicalSerialize, + TNew: CanonicalDeserializeOld, +{ + let mut buf = Vec::new(); + old.serialize_compressed(&mut buf).unwrap(); + TNew::deserialize_compressed(&*buf).unwrap() +} + +#[test] +fn test_roundtrip_and_serialization() { + let mut rng = test_rng(); + + // Prepare test cases: generator + random points + let mut test_cases = vec![G1Old::generator()]; + test_cases.extend((0..20).map(|_| G1Old::rand(&mut rng))); + + for p_old in test_cases { + // Convert old → new + let p_new = roundtrip_old_to_new::<_, G1New>(&p_old); + + // Generator check + if p_old == G1Old::generator() { + assert_eq!(p_new, G1New::generator()); + } + + // Roundtrip old → new → old + let p_old_back = roundtrip_new_to_old::<_, G1Old>(&p_new); + assert_eq!(p_old_back, p_old, "Roundtrip old → new → old failed"); + + // Serialization compatibility + let mut buf_old = Vec::new(); + p_old.serialize_compressed(&mut buf_old).unwrap(); + + let mut buf_new = Vec::new(); + p_new.serialize_compressed(&mut buf_new).unwrap(); + + assert_eq!(buf_old.len(), buf_new.len()); + assert_eq!(buf_old, buf_new, "Compressed serialization mismatch"); + } +} + +#[test] +fn test_addition_consistency() { + let mut rng = test_rng(); + let mut points_old = vec![G1Old::generator(), G1Old::generator() + G1Old::generator()]; + + for _ in 0..10 { + points_old.push(G1Old::rand(&mut rng)); + } + + for (i, p_old) in points_old.iter().enumerate() { + let sum_old = *p_old + *p_old; + let p_new = roundtrip_old_to_new::<_, G1New>(p_old); + let sum_new = roundtrip_old_to_new::<_, G1New>(&sum_old); + + assert_eq!(p_new + p_new, sum_new, "Addition mismatch in case {}", i); + } + + // Pairwise random sums + for _ in 0..10 { + let p_old = G1Old::rand(&mut rng); + let q_old = G1Old::rand(&mut rng); + let sum_old = p_old + q_old; + + let p_new = roundtrip_old_to_new::<_, G1New>(&p_old); + let q_new = roundtrip_old_to_new::<_, G1New>(&q_old); + let sum_new = roundtrip_old_to_new::<_, G1New>(&sum_old); + + assert_eq!(p_new + q_new, sum_new); + } +} + +#[test] +fn test_scalar_multiplication_consistency() { + let mut rng = test_rng(); + + for _ in 0..10 { + let scalar_old = ark_bls12_381_old::Fr::rand(&mut rng); + let scalar_new = roundtrip_old_to_new::<_, ark_bls12_381::Fr>(&scalar_old); + + let g_old = G1Old::generator().mul_bigint(scalar_old.into_bigint()); + let g_new_expected = G1New::generator().mul_bigint(scalar_new.into_bigint()); + + let g_new = roundtrip_old_to_new::<_, G1New>(&g_old); + assert_eq!(g_new, g_new_expected); + } +} + +#[test] +fn test_fr_operations_consistency() { + let mut rng = test_rng(); + for _ in 0..50 { + let a_old = ark_bls12_381_old::Fr::rand(&mut rng); + let b_old = ark_bls12_381_old::Fr::rand(&mut rng); + + let a_new = roundtrip_old_to_new::<_, ark_bls12_381::Fr>(&a_old); + let b_new = roundtrip_old_to_new::<_, ark_bls12_381::Fr>(&b_old); + + assert_eq!(a_old + b_old, roundtrip_new_to_old(&(a_new + b_new))); + assert_eq!(a_old - b_old, roundtrip_new_to_old(&(a_new - b_new))); + assert_eq!(a_old * b_old, roundtrip_new_to_old(&(a_new * b_new))); + + if !a_old.is_zero() { + assert_eq!( + a_old.inverse().unwrap(), + roundtrip_new_to_old(&a_new.inverse().unwrap()) + ); + } + } +} + +#[test] +fn test_pairing_consistency() { + let mut rng = test_rng(); + + // Random pairing checks + for _ in 0..10 { + let a_old = G1Old::rand(&mut rng); + let b_old = G2Old::rand(&mut rng); + + let a_new = roundtrip_old_to_new::<_, G1New>(&a_old); + let b_new = roundtrip_old_to_new::<_, G2New>(&b_old); + + let e_old = ::pairing(a_old.into_affine(), b_old.into_affine()); + let e_new = ::pairing(a_new.into_affine(), b_new.into_affine()); + + let mut buf_old = Vec::new(); + e_old.serialize_compressed(&mut buf_old).unwrap(); + + let mut buf_new = Vec::new(); + e_new.serialize_compressed(&mut buf_new).unwrap(); + + assert_eq!(buf_old, buf_new, "Pairing mismatch on random inputs"); + } +} diff --git a/crates/aptos-crypto/src/unit_tests/constant_time_test.rs b/crates/aptos-crypto/src/unit_tests/constant_time_test.rs new file mode 100644 index 00000000000..062f622ce5b --- /dev/null +++ b/crates/aptos-crypto/src/unit_tests/constant_time_test.rs @@ -0,0 +1,63 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::constant_time; +use dudect_bencher::ctbench::{run_bench, BenchName}; +use more_asserts::assert_le; +use num_traits::ToPrimitive; + +#[test] +#[ignore] +/// WARNING: This is marked as "ignored" because unit tests are typically run in debug mode, and we +/// would need this to run in release mode to make sure the dudect framework's statistical measurements +/// are meaningful. +/// +/// Nonetheless, we wrote this test to serve as an example for how to call the dudect framework +/// manually, without using the macros that would generate a `main` function, which would not work +/// if we want to run these tests in some other `main` function (like the pepper service). +/// +/// To run this test properly, do: +/// +/// cargo test --release test_blstrs_fixed_base_g1_scalar_mul_is_constant_time -- --ignored --nocapture +/// +fn test_blstrs_fixed_base_g1_scalar_mul_is_constant_time() { + let ct_summary = run_bench( + &BenchName("blstrs_scalar_mul_fixed_base"), + constant_time::blstrs_scalar_mul::run_bench_with_fixed_bases, + None, + ) + .1; + + eprintln!("{:?}", ct_summary); + + let max_t = ct_summary + .max_t + .abs() + .to_i64() + .expect("Floating point arithmetic went awry."); + assert_le!(max_t, 5); +} + +#[test] +#[ignore] +/// To run this test properly, do: +/// +/// cargo test --release test_blstrs_random_base_g1_scalar_mul_is_constant_time -- --ignored --nocapture +/// +fn test_blstrs_random_base_g1_scalar_mul_is_constant_time() { + let ct_summary = run_bench( + &BenchName("blstrs_scalar_mul_random_base"), + constant_time::blstrs_scalar_mul::run_bench_with_random_bases, + None, + ) + .1; + + eprintln!("{:?}", ct_summary); + + let max_t = ct_summary + .max_t + .abs() + .to_i64() + .expect("Floating point arithmetic went awry."); + assert_le!(max_t, 5); +} diff --git a/crates/aptos-crypto/src/unit_tests/hash_test.rs b/crates/aptos-crypto/src/unit_tests/hash_test.rs index 47253749760..19382909c8d 100644 --- a/crates/aptos-crypto/src/unit_tests/hash_test.rs +++ b/crates/aptos-crypto/src/unit_tests/hash_test.rs @@ -82,7 +82,7 @@ fn test_random_with_rng() { } { let mut rng: StdRng = SeedableRng::from_seed(seed); - hash3 = rng.gen(); + hash3 = rng.r#gen(); } assert_eq!(hash1, hash2); assert_eq!(hash1, hash3); @@ -149,7 +149,7 @@ fn test_get_nibble() { let mut bytes = [0u8; HashValue::LENGTH]; let mut nibbles = vec![]; for byte in bytes.iter_mut().take(HashValue::LENGTH) { - *byte = rand::thread_rng().gen(); + *byte = rand::thread_rng().r#gen(); nibbles.push(*byte >> 4); nibbles.push(*byte & 0x0F); } diff --git a/crates/aptos-crypto/src/unit_tests/mod.rs b/crates/aptos-crypto/src/unit_tests/mod.rs index 34cf3348c43..a9babb31939 100644 --- a/crates/aptos-crypto/src/unit_tests/mod.rs +++ b/crates/aptos-crypto/src/unit_tests/mod.rs @@ -1,10 +1,13 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "arkworks-upgrade-compat-test")] +mod arkworks_upgrade; mod bcs_test; mod bls12381_test; mod bulletproofs_test; mod compat_test; +mod constant_time_test; mod cross_test; mod cryptohasher; mod ed25519_test; diff --git a/crates/aptos-crypto/src/unit_tests/multi_ed25519_test.rs b/crates/aptos-crypto/src/unit_tests/multi_ed25519_test.rs index 8622a327349..addf4d264a2 100644 --- a/crates/aptos-crypto/src/unit_tests/multi_ed25519_test.rs +++ b/crates/aptos-crypto/src/unit_tests/multi_ed25519_test.rs @@ -472,7 +472,7 @@ fn test_multi_ed25519_signature_verification() { fn test_invalid_multi_ed25519_signature_bitmap() { let priv_keys_3 = generate_keys(3); - let multi_private_key_2of3 = MultiEd25519PrivateKey::new(priv_keys_3, 2).unwrap(); + let multi_private_key_2of3 = MultiEd25519PrivateKey::new(priv_keys_3.clone(), 2).unwrap(); let multi_public_key_2of3 = MultiEd25519PublicKey::from(&multi_private_key_2of3); let multi_signature_2of3 = multi_private_key_2of3.sign(message()).unwrap(); @@ -502,6 +502,50 @@ fn test_invalid_multi_ed25519_signature_bitmap() { assert!(multi_signature_1of3 .verify(message(), &multi_public_key_2of3) .is_err()); + + let multi_signature_3of3_invalid_bitmap = MultiEd25519Signature::new_with_signatures_and_bitmap( + priv_keys_3 + .iter() + .map(|x| x.sign(message()).unwrap()) + .collect(), + [0b1100_0000, 0u8, 0u8, 0u8], + ); + + // Bitmap is invalid + assert_eq!( + multi_signature_3of3_invalid_bitmap + .verify(message(), &multi_public_key_2of3) + .unwrap_err() + .to_string(), + "BitVecError(\"Bitmap ones and signatures count are not equal\")".to_string() + ); + + let multi_signature_3of3 = MultiEd25519Signature::new_with_signatures_and_bitmap( + priv_keys_3 + .iter() + .map(|x| x.sign(message()).unwrap()) + .collect(), + [0b1110_0000, 0u8, 0u8, 0u8], + ); + let multi_public_key_2of3_2only = MultiEd25519PublicKey::new( + multi_public_key_2of3 + .public_keys() + .iter() + .take(2) + .cloned() + .collect(), + 2, + ) + .unwrap(); + + // Bitmap is valid but fewer public keys provided + assert_eq!( + multi_signature_3of3 + .verify(message(), &multi_public_key_2of3_2only) + .unwrap_err() + .to_string(), + "BitVecError(\"Signature index is out of range\")".to_string() + ); } /// Used for generating test cases for the MultiEd25519 Move module. diff --git a/crates/aptos-crypto/src/utils.rs b/crates/aptos-crypto/src/utils.rs new file mode 100644 index 00000000000..7232f9df6be --- /dev/null +++ b/crates/aptos-crypto/src/utils.rs @@ -0,0 +1,25 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Utility functions for general-purpose operations. +//! Currently contains only a `powers()` function for computing sequential powers of a base element. + +use ark_std::ops::MulAssign; +use num_traits::One; + +/// Returns the first `count` powers of a given `base` element, so +/// [1, base, base^2, base^3, ..., base^{count - 1}] +pub fn powers(base: T, count: usize) -> Vec +where + T: MulAssign + One + Copy, +{ + let mut powers = Vec::with_capacity(count); + let mut current = T::one(); + + for _ in 0..count { + powers.push(current); + current *= base; + } + + powers +} diff --git a/crates/aptos-crypto/src/weighted_config.rs b/crates/aptos-crypto/src/weighted_config.rs new file mode 100644 index 00000000000..90b3e71ea14 --- /dev/null +++ b/crates/aptos-crypto/src/weighted_config.rs @@ -0,0 +1,433 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Weighted threshold secret sharing configuration for BLSTRS-based PVSS. + +use crate::{ + arkworks::shamir::{Reconstructable, ShamirShare, ShamirThresholdConfig}, + blstrs::{ + evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, + threshold_config::ThresholdConfigBlstrs, + }, + player::Player, + traits::{self, SecretSharingConfig as _, ThresholdConfig}, +}; +use anyhow::anyhow; +use ark_ff::FftField; +use more_asserts::assert_lt; +use rand::Rng; +use rand_core::{CryptoRng, RngCore}; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; + +/// Encodes the *threshold configuration* for a *weighted* PVSS: i.e., the minimum weight $w$ and +/// the total weight $W$ such that any subset of players with weight $\ge w$ can reconstruct a +/// dealt secret given a PVSS transcript. +#[allow(non_snake_case)] +#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] +pub struct WeightedConfig { + /// A weighted config is a $w$-out-of-$W$ threshold config, where $w$ is the minimum weight + /// needed to reconstruct the secret and $W$ is the total weight. + tc: TC, + /// The total number of players in the protocol. + num_players: usize, + /// Each player's weight + weights: Vec, + /// Player's starting index `a` in a vector of all `W` shares, such that this player owns shares + /// `W[a, a + weight[player])`. Useful during weighted secret reconstruction. + starting_index: Vec, + /// The maximum weight of any player. + max_weight: usize, + /// The minimum weight of any player. + min_weight: usize, +} + +/// Weighted config for the BLSTRS-based PVSS +pub type WeightedConfigBlstrs = WeightedConfig; + +/// Weighted config for the Arkworks-based PVSS +#[allow(type_alias_bounds)] +pub type WeightedConfigArkworks = WeightedConfig>; + +impl WeightedConfig { + #[allow(non_snake_case)] + /// Initializes a weighted secret sharing configuration with threshold weight `threshold_weight` + /// and the $i$th player's weight stored in `weight[i]`. + pub fn new(threshold_weight: usize, weights: Vec) -> anyhow::Result { + if threshold_weight == 0 { + return Err(anyhow!( + "expected the minimum reconstruction weight to be > 0" + )); + } + + if weights.is_empty() { + return Err(anyhow!("expected a non-empty vector of player weights")); + } + let max_weight = *weights.iter().max().unwrap(); + let min_weight = *weights.iter().min().unwrap(); + + let n = weights.len(); + let W = weights.iter().sum(); + + // e.g., Suppose the weights for players 0, 1 and 2 are [2, 4, 3] + // Then, our PVSS transcript implementation will store a vector of 2 + 4 + 3 = 9 shares, + // such that: + // - Player 0 will own the shares at indices [0..2), i.e.,starting index 0 + // - Player 1 will own the shares at indices [2..2 + 4) = [2..6), i.e.,starting index 2 + // - Player 2 will own the shares at indices [6, 6 + 3) = [6..9), i.e., starting index 6 + let mut starting_index = Vec::with_capacity(weights.len()); + starting_index.push(0); + + for w in weights.iter().take(n - 1) { + starting_index.push(starting_index.last().unwrap() + w); + } + + let tc = TC::new(threshold_weight, W)?; + Ok(WeightedConfig { + tc, + num_players: n, + weights, + starting_index, + max_weight, + min_weight, + }) + } + + /// Returns the minimum weight among all players in this weighted secret sharing configuration. + pub fn get_min_weight(&self) -> usize { + self.min_weight + } + + /// Returns _a_ player who has the smallest weight. + pub fn get_min_weight_player(&self) -> Player { + if let Some((i, _weight)) = self + .weights + .iter() + .enumerate() + .min_by_key(|&(_, &weight)| weight) + { + // println!("Player {} has the smallest weight: {}", i, _weight); + self.get_player(i) + } else { + panic!("Weights vector should not be empty"); + } + } + + /// Returns _a_ player who has the largest weight. + pub fn get_max_weight_player(&self) -> Player { + if let Some((i, _weight)) = self + .weights + .iter() + .enumerate() + .max_by_key(|&(_, &weight)| weight) + { + // println!("Player {} has the largest weight: {}", i, _weight); + self.get_player(i) + } else { + panic!("Weights vector should not be empty"); + } + } + + /// Returns the maximum weight among all players in this weighted secret sharing configuration. + pub fn get_max_weight(&self) -> usize { + self.max_weight + } + + /// Returns a reference to the underlying unweighted threshold configuration. + pub fn get_threshold_config(&self) -> &TC { + &self.tc + } + + /// Returns the threshold weight required to reconstruct the secret. + pub fn get_threshold_weight(&self) -> usize { + self.tc.get_threshold() + } + + /// Returns the total weight of all players combined. + pub fn get_total_weight(&self) -> usize { + self.tc.get_total_num_shares() + } + + /// Returns the weight of a specific player. + pub fn get_player_weight(&self, player: &Player) -> usize { + self.weights[player.id] + } + + /// Returns the starting index of a player's shares in the flattened vector of all weighted shares. + pub fn get_player_starting_index(&self, player: &Player) -> usize { + self.starting_index[player.id] + } + + /// In an unweighted secret sharing scheme, each player has one share. We can weigh such a scheme + /// by splitting a player into as many "virtual" players as that player's weight, assigning one + /// share per "virtual player." + /// + /// This function returns the "virtual" player associated with the $i$th sub-share of this player. + pub fn get_virtual_player(&self, player: &Player, j: usize) -> Player { + // println!("WeightedConfig::get_virtual_player({player}, {i})"); + assert_lt!(j, self.weights[player.id]); + + let id = self.get_share_index(player.id, j).unwrap(); + + Player { id } + } + + /// Returns all "virtual" players corresponding to a given player based on their weight. + pub fn get_all_virtual_players(&self, player: &Player) -> Vec { + let w = self.get_player_weight(player); + + (0..w) + .map(|i| self.get_virtual_player(player, i)) + .collect::>() + } + + /// `i` is the player's index, from 0 to `self.tc.n` + /// `j` is the player's share #, from 0 to `self.weight[i]` + /// + /// Returns the index of this player's share in the vector of shares, or None if out of bounds. + pub fn get_share_index(&self, i: usize, j: usize) -> Option { + if j < self.weights[i] { + Some(self.starting_index[i] + j) + } else { + None + } + } + + /// NOTE: RNG is passed in to maintain function signature compatibility with + /// `SecretSharingConfig::get_random_eligible_subset_of_players`, so as to easily benchmark + /// with different methods of sampling subsets. + pub fn get_best_case_eligible_subset_of_players( + &self, + _rng: &mut R, + ) -> Vec { + let mut player_and_weights = self.sort_players_by_weight(); + + self.pop_eligible_subset(&mut player_and_weights) + } + + /// NOTE: RNG is passed in to maintain function signature compatibility with + /// `SecretSharingConfig::get_random_eligible_subset_of_players`, so as to easily benchmark + /// with different methods of sampling subsets. + pub fn get_worst_case_eligible_subset_of_players( + &self, + _rng: &mut R, + ) -> Vec { + let mut player_and_weights = self.sort_players_by_weight(); + + player_and_weights.reverse(); + + self.pop_eligible_subset(&mut player_and_weights) + } + + /// Computes the average size of a randomly selected eligible subset of players. + pub fn get_average_size_of_eligible_subset( + &self, + sample_size: usize, + rng: &mut R, + ) -> usize { + let mut average = 0; + for _ in 0..sample_size { + average += self.get_random_eligible_subset_of_players(rng).len(); + } + average / sample_size + } + + fn sort_players_by_weight(&self) -> Vec<(Player, usize)> { + // the set of remaining players that we are picking a "capable" subset from + let mut player_and_weights = self + .weights + .iter() + .enumerate() + .map(|(i, w)| (self.get_player(i), *w)) + .collect::>(); + + player_and_weights.sort_by(|a, b| a.1.cmp(&b.1)); + player_and_weights + } + + fn pop_eligible_subset(&self, player_and_weights: &mut Vec<(Player, usize)>) -> Vec { + let mut picked_players = vec![]; + + let mut current_weight = 0; + while current_weight < self.tc.get_threshold() { + let (player, weight) = player_and_weights.pop().unwrap(); + + picked_players.push(player); + + // rinse and repeat until the picked players jointly have enough weight + current_weight += weight; + } + + picked_players + } +} + +impl WeightedConfigBlstrs { + /// Returns a reference to the precomputed batch evaluation domain. + pub fn get_batch_evaluation_domain(&self) -> &BatchEvaluationDomain { + self.tc.get_batch_evaluation_domain() + } + + /// Returns a reference to the primary evaluation domain. + pub fn get_evaluation_domain(&self) -> &EvaluationDomain { + self.tc.get_evaluation_domain() + } +} + +impl Display for WeightedConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "weighted/{}-out-of-{}/{}-players", + self.tc.get_threshold(), + self.tc.get_total_num_shares(), + self.num_players + ) + } +} + +impl traits::SecretSharingConfig for WeightedConfig { + /// For testing only. + fn get_random_player(&self, rng: &mut R) -> Player + where + R: RngCore + CryptoRng, + { + Player { + id: rng.gen_range(0, self.get_total_num_players()), + } + } + + fn get_random_eligible_subset_of_players(&self, rng: &mut R) -> Vec + where + R: RngCore, + { + // the randomly-picked "capable" subset of players who can reconstruct the secret + let mut picked_players = vec![]; + // the set of remaining players that we are picking a "capable" subset from + let mut player_and_weights = self + .weights + .iter() + .enumerate() + .map(|(i, w)| (i, *w)) + .collect::>(); + let mut current_weight = 0; + + while current_weight < self.tc.get_threshold() { + // pick a random player, and move it to the picked set + let idx = rng.gen_range(0, player_and_weights.len()); + let (player_id, weight) = player_and_weights[idx]; + picked_players.push(self.get_player(player_id)); + + // efficiently remove the picked player from the set of remaining players + let len = player_and_weights.len(); + if len > 1 { + player_and_weights.swap(idx, len - 1); + player_and_weights.pop(); + } + + // rinse and repeat until the picked players jointly have enough weight + current_weight += weight; + } + + // println!(); + // println!( + // "Returned random capable subset {{ {} }}", + // vec_to_str!(picked_players) + // ); + picked_players + } + + fn get_total_num_players(&self) -> usize { + self.num_players + } + + fn get_total_num_shares(&self) -> usize { + self.tc.get_total_num_shares() + } +} + +/// Implements weighted reconstruction of a secret `SK` through the existing unweighted reconstruction +/// implementation of `SK`. +impl> Reconstructable for SK { + type ShareValue = Vec; + + fn reconstruct( + sc: &WeightedConfigBlstrs, + shares: &[ShamirShare], + ) -> anyhow::Result { + let mut flattened_shares = Vec::with_capacity(sc.get_total_weight()); + + // println!(); + for (player, sub_shares) in shares { + // println!( + // "Flattening {} share(s) for player {player}", + // sub_shares.len() + // ); + for (pos, share) in sub_shares.iter().enumerate() { + let virtual_player = sc.get_virtual_player(player, pos); + + // println!( + // " + Adding share {pos} as virtual player {virtual_player}: {:?}", + // share + // ); + // TODO(Performance): Avoiding the cloning here might be nice + let tuple = (virtual_player, share.clone()); + flattened_shares.push(tuple); + } + } + + SK::reconstruct(sc.get_threshold_config(), &flattened_shares) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn bvt() { + // 1-out-of-1 weighted + let wc = WeightedConfigBlstrs::new(1, vec![1]).unwrap(); + assert_eq!(wc.starting_index.len(), 1); + assert_eq!(wc.starting_index[0], 0); + assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); + + // 1-out-of-2, weights 2 + let wc = WeightedConfigBlstrs::new(1, vec![2]).unwrap(); + assert_eq!(wc.starting_index.len(), 1); + assert_eq!(wc.starting_index[0], 0); + assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); + assert_eq!(wc.get_virtual_player(&wc.get_player(0), 1).id, 1); + + // 1-out-of-2, weights 1, 1 + let wc = WeightedConfigBlstrs::new(1, vec![1, 1]).unwrap(); + assert_eq!(wc.starting_index.len(), 2); + assert_eq!(wc.starting_index[0], 0); + assert_eq!(wc.starting_index[1], 1); + assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); + assert_eq!(wc.get_virtual_player(&wc.get_player(1), 0).id, 1); + + // 3-out-of-5, some weights are 0. + let wc = WeightedConfigBlstrs::new(1, vec![0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0]) + .unwrap(); + assert_eq!( + vec![0, 0, 0, 0, 2, 4, 6, 6, 6, 6, 9, 12, 15, 15, 15], + wc.starting_index + ); + assert_eq!(wc.get_virtual_player(&wc.get_player(3), 0).id, 0); + assert_eq!(wc.get_virtual_player(&wc.get_player(3), 1).id, 1); + assert_eq!(wc.get_virtual_player(&wc.get_player(4), 0).id, 2); + assert_eq!(wc.get_virtual_player(&wc.get_player(4), 1).id, 3); + assert_eq!(wc.get_virtual_player(&wc.get_player(5), 0).id, 4); + assert_eq!(wc.get_virtual_player(&wc.get_player(5), 1).id, 5); + assert_eq!(wc.get_virtual_player(&wc.get_player(9), 0).id, 6); + assert_eq!(wc.get_virtual_player(&wc.get_player(9), 1).id, 7); + assert_eq!(wc.get_virtual_player(&wc.get_player(9), 2).id, 8); + assert_eq!(wc.get_virtual_player(&wc.get_player(10), 0).id, 9); + assert_eq!(wc.get_virtual_player(&wc.get_player(10), 1).id, 10); + assert_eq!(wc.get_virtual_player(&wc.get_player(10), 2).id, 11); + assert_eq!(wc.get_virtual_player(&wc.get_player(11), 0).id, 12); + assert_eq!(wc.get_virtual_player(&wc.get_player(11), 1).id, 13); + assert_eq!(wc.get_virtual_player(&wc.get_player(11), 2).id, 14); + } +} diff --git a/crates/aptos-crypto/src/x25519.rs b/crates/aptos-crypto/src/x25519.rs index 025e0f601a2..9ded1ea170c 100644 --- a/crates/aptos-crypto/src/x25519.rs +++ b/crates/aptos-crypto/src/x25519.rs @@ -11,6 +11,7 @@ //! # Examples //! //! ``` +//! # fn main() -> Result<(), aptos_crypto::traits::CryptoMaterialError> { //! use aptos_crypto::{x25519, Uniform, test_utils::TEST_SEED}; //! use rand::{rngs::StdRng, SeedableRng}; //! @@ -21,7 +22,6 @@ //! //! // Deserialize an hexadecimal private or public key //! use aptos_crypto::traits::ValidCryptoMaterialStringExt; -//! # fn main() -> Result<(), aptos_crypto::traits::CryptoMaterialError> { //! let private_key = "404acc8ec6a0f18df7359a6ee7823f19dd95616b10fed8bdb0de030e891b945a"; //! let private_key = x25519::PrivateKey::from_encoded_string(&private_key)?; //! let public_key = "080e287879c918794170e258bfaddd75acac5b3e350419044655e4983a487120"; diff --git a/crates/aptos-debugger/Cargo.toml b/crates/aptos-debugger/Cargo.toml index 1fd814f0060..3409aced5e0 100644 --- a/crates/aptos-debugger/Cargo.toml +++ b/crates/aptos-debugger/Cargo.toml @@ -23,7 +23,4 @@ clap = { workspace = true } tokio = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/crates/aptos-dkg/Cargo.toml b/crates/aptos-dkg/Cargo.toml index e6463336d18..ed0f7308c19 100644 --- a/crates/aptos-dkg/Cargo.toml +++ b/crates/aptos-dkg/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "aptos-dkg" -version = "0.1.0" -edition = "2021" +version = "0.2.0" +edition = { workspace = true } license = { workspace = true } [dependencies] @@ -9,10 +9,18 @@ anyhow = { workspace = true } aptos-crypto = { workspace = true } aptos-crypto-derive = { workspace = true } aptos-runtimes = { workspace = true } -bcs = { workspace = true } +ark-bls12-381 = { workspace = true } +ark-bn254 = { workspace = true } +ark-ec = { workspace = true } +ark-ff = { workspace = true } +ark-poly = { workspace = true } +ark-serialize = { workspace = true } +ark-std = { workspace = true } +bcs = { workspace = true } blst = { workspace = true } blstrs = { workspace = true } criterion = { workspace = true } +derive_more = { workspace = true } ff = { workspace = true } group = { workspace = true } hex = { workspace = true } @@ -21,7 +29,6 @@ more-asserts = { workspace = true } num-bigint = { workspace = true } num-integer = { workspace = true } num-traits = { workspace = true } -once_cell = { workspace = true } pairing = { workspace = true } rand = { workspace = true } rand_core = { workspace = true } @@ -37,6 +44,11 @@ num_cpus = { workspace = true } [features] assert-private-keys-not-cloneable = [] fuzzing = [] +range_proof_timing = [] + +[[bench]] +name = "bsgs" +harness = false [[bench]] name = "crypto" @@ -50,6 +62,10 @@ harness = false name = "pvss" harness = false +[[bench]] +name = "range_proof" +harness = false + [[bench]] name = "weighted_vuf" harness = false diff --git a/crates/aptos-dkg/benches/bsgs.rs b/crates/aptos-dkg/benches/bsgs.rs new file mode 100644 index 00000000000..efeb67bcb44 --- /dev/null +++ b/crates/aptos-dkg/benches/bsgs.rs @@ -0,0 +1,128 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_dkg::dlog::{bsgs, table}; +use ark_ec::{pairing::Pairing, CurveGroup, PrimeGroup}; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, Rng, SeedableRng}; +use std::collections::HashMap; + +/// Generic benchmark for the discrete log computation using Baby-step Giant-step +#[allow(non_snake_case)] +fn bench_dlog(c: &mut Criterion, curve_name: &str) +where + E::G1: CurveGroup, +{ + let mut group = c.benchmark_group(format!("dlog_bsgs_{}", curve_name)); + + // Parameters + let range_limit = 1 << 16; + let table_sizes = [1 << 8, 1 << 12]; // 256 and 4096 entries + let num_samples = 16usize; // For the vector benchmark + + // Deterministic RNG for reproducibility + let mut rng = StdRng::seed_from_u64(42); + + let G = E::G1::generator(); + + for &table_size in &table_sizes { + // Precompute baby-step table + let baby_table: HashMap, u32> = table::build::(G, table_size); + + // --- Single benchmark + group.bench_with_input( + BenchmarkId::new("single_dlog", format!("table_size_{}", table_size)), + &table_size, + |b, &_ts| { + b.iter_with_setup( + // setup: generate fresh scalar and point for this iteration + || { + let x: u32 = rng.gen_range(0, range_limit); + let H = G * E::ScalarField::from(x); + (x, H) + }, + // actual benchmark: compute discrete log + |(x, H)| { + let recovered = bsgs::dlog(G, H, &baby_table, range_limit) + .expect("Discrete log not found"); + assert_eq!(recovered, x); + }, + ); + }, + ); + + // --- Vector benchmark --- + group.bench_with_input( + BenchmarkId::new("vector_dlog", format!("table_size_{}", table_size)), + &table_size, + |b, &_ts| { + b.iter_with_setup( + // setup: generate fresh batch of scalars and points + || { + let xs: Vec = (0..num_samples) + .map(|_| rng.gen_range(0, range_limit)) + .collect(); + let Hs: Vec = + xs.iter().map(|&x| G * E::ScalarField::from(x)).collect(); + (xs, Hs) + }, + // benchmark: compute discrete logs for the batch + |(xs, Hs)| { + let recovered = bsgs::dlog_vec(G, &Hs, &baby_table, range_limit) + .expect("Discrete log not found"); + assert_eq!(recovered, xs); + }, + ); + }, + ); + } + + group.finish(); +} + +#[allow(non_snake_case)] +fn bench_table_build(c: &mut Criterion, curve_name: &str) +where + E::G1: CurveGroup, +{ + let mut group = c.benchmark_group(format!("dlog_table_build_{}", curve_name)); + + // Limit Criterion to exactly 10 measurement iterations, because tables can be big (24 bits takes 1-2 min) + group.sample_size(10); // It can't do less than 10 + + // Time seems almost linear in the size of the table, so doesn't make sense to benchmark many values + let table_sizes: &[u32] = &[1u32 << 16]; + + let G = E::G1::generator(); + + for &table_size in table_sizes { + group.bench_with_input( + BenchmarkId::from_parameter(table_size), + &table_size, + |b, &_ts| { + b.iter(|| { + // Measure table build time only + let table: HashMap, u32> = table::build::(G, table_size); + let table_len: u32 = table.len().try_into().unwrap(); + assert_eq!(table_len, table_size, "Unexpected table length"); + }); + }, + ); + } + + group.finish(); +} + +fn criterion_benchmark(c: &mut Criterion) { + use ark_bls12_381::Bls12_381; + use ark_bn254::Bn254; + + bench_dlog::(c, "bn254"); + bench_table_build::(c, "bn254"); + + bench_dlog::(c, "bls12_381"); + bench_table_build::(c, "bls12_381"); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/crates/aptos-dkg/benches/crypto.rs b/crates/aptos-dkg/benches/crypto.rs index c9f73c629e0..74b5cd588e2 100644 --- a/crates/aptos-dkg/benches/crypto.rs +++ b/crates/aptos-dkg/benches/crypto.rs @@ -3,6 +3,7 @@ #![allow(clippy::useless_conversion)] +use aptos_crypto::blstrs::{multi_pairing, random_scalar}; use aptos_dkg::{ algebra::{ evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, @@ -10,16 +11,16 @@ use aptos_dkg::{ polynomials, }, utils::{ - g1_multi_exp, g2_multi_exp, hash_to_scalar, multi_pairing, parallel_multi_pairing, + g1_multi_exp, g2_multi_exp, hash_to_scalar, parallel_multi_pairing, random::{ insecure_random_gt_point, insecure_random_gt_points, random_g1_point, random_g1_points, - random_g2_point, random_g2_points, random_scalar, random_scalars, + random_g2_point, random_g2_points, random_scalars, }, }, weighted_vuf::pinkas::MIN_MULTIPAIR_NUM_JOBS, }; use aptos_runtimes::spawn_rayon_thread_pool; -use blstrs::{G1Projective, G2Projective, Gt}; +use blstrs::{G1Projective, G2Projective, Gt, Scalar}; use criterion::{ criterion_group, criterion_main, measurement::Measurement, BenchmarkGroup, BenchmarkId, Criterion, Throughput, @@ -40,7 +41,10 @@ pub const LARGE_SIZES: [usize; 3] = [8192, 16_384, 32_768]; pub fn crypto_group(c: &mut Criterion) { let mut group = c.benchmark_group("crypto"); - for thresh in [333, 666, 3_333, 6_6666] { + field_ops(1_000_000, &mut group, "field_additions", |a, b| a + b); + field_ops(1_000_000, &mut group, "field_multiplications", |a, b| a * b); + + for thresh in [333, 666, 3_333, 6_666] { batch_evaluation_domain_new(thresh, &mut group); fft_assign_bench(thresh, &mut group); @@ -443,6 +447,31 @@ fn parallel_multipairing(n: usize, g: &mut BenchmarkGroup, nu ); } +fn field_ops( + n: usize, + g: &mut BenchmarkGroup, + name: &str, + op: impl Fn(Scalar, Scalar) -> Scalar + Copy, +) { + let mut rng = thread_rng(); + g.throughput(Throughput::Elements(n as u64)); + + g.bench_function(BenchmarkId::new(name, n), move |b| { + b.iter_with_setup( + || { + let a = random_scalars(n, &mut rng); + let b = random_scalars(n, &mut rng); + (a, b) + }, + |(a, b)| { + for i in 0..a.len() { + let _c = op(a[i], b[i]); + } + }, + ) + }); +} + fn g1_multiexp(n: usize, g: &mut BenchmarkGroup) { let mut rng = thread_rng(); diff --git a/crates/aptos-dkg/benches/pvss.rs b/crates/aptos-dkg/benches/pvss.rs index 1bca3a728d9..6e98ce1f52e 100644 --- a/crates/aptos-dkg/benches/pvss.rs +++ b/crates/aptos-dkg/benches/pvss.rs @@ -4,21 +4,20 @@ #![allow(clippy::ptr_arg)] #![allow(clippy::needless_borrow)] -use aptos_crypto::Uniform; +use aptos_crypto::{traits::SecretSharingConfig as _, Uniform}; use aptos_dkg::{ algebra::evaluation_domain::BatchEvaluationDomain, - pvss, pvss::{ - test_utils, + self, test_utils::{ - get_threshold_configs_for_benchmarking, get_weighted_configs_for_benchmarking, - DealingArgs, NoAux, + self, get_threshold_configs_for_benchmarking, get_weighted_configs_for_benchmarking, + DealingArgs, NoAux, BENCHMARK_CONFIGS, }, - traits::{ - transcript::{MalleableTranscript, Transcript}, - SecretSharingConfig, + traits::transcript::{ + Aggregatable, AggregatableTranscript, HasAggregatableSubtranscript, + MalleableTranscript, Transcript, WithMaxNumShares, }, - LowDegreeTest, WeightedConfig, + LowDegreeTest, WeightedConfigBlstrs, }, }; use criterion::{ @@ -30,14 +29,19 @@ use more_asserts::assert_le; use rand::{rngs::ThreadRng, thread_rng, Rng}; pub fn all_groups(c: &mut Criterion) { - // unweighted PVSS + // unweighted BN254 PVSS with aggregatable subscript for tc in get_threshold_configs_for_benchmarking() { - pvss_group::(&tc, c); + subaggregatable_pvss_group::>(&tc, c); + } + + // unweighted aggregatable PVSS + for tc in get_threshold_configs_for_benchmarking() { + aggregatable_pvss_group::(&tc, c); } // weighted PVSS for wc in get_weighted_configs_for_benchmarking() { - let d = pvss_group::(&wc, c); + let d = aggregatable_pvss_group::(&wc, c); weighted_pvss_group(&wc, d, c); // Note: Insecure, so not interested in benchmarks. @@ -49,19 +53,16 @@ pub fn all_groups(c: &mut Criterion) { ldt_group(c); } +// TODO: benchmark both blstrs and arkworks LDT? pub fn ldt_group(c: &mut Criterion) { let mut rng = thread_rng(); + let mut group = c.benchmark_group("ldt"); - for sc in get_threshold_configs_for_benchmarking() { - let mut group = c.benchmark_group("ldt"); - - group.bench_function(format!("dual_code_word/{}", sc), move |b| { + for &(t, n) in BENCHMARK_CONFIGS { + group.bench_function(format!("dual_code_word/t{}/n{}", t, n), |b| { b.iter_with_setup( || { - let n = sc.get_total_num_players(); - let t = sc.get_threshold(); let batch_dom = BatchEvaluationDomain::new(n); - (n, t, batch_dom) }, |(n, t, batch_dom)| { @@ -73,7 +74,7 @@ pub fn ldt_group(c: &mut Criterion) { } } -pub fn pvss_group( +pub fn aggregatable_pvss_group( sc: &T::SecretSharingConfig, c: &mut Criterion, ) -> DealingArgs { @@ -85,17 +86,48 @@ pub fn pvss_group( let d = test_utils::setup_dealing::(sc, &mut rng); // pvss_transcript_random::(sc, &mut group); - pvss_deal::(sc, &d.pp, &d.ssks, &d.eks, &mut group); + pvss_deal::(sc, &d.pp, &d.ssks, &d.spks, &d.eks, &mut group); pvss_aggregate::(sc, &mut group); pvss_verify::(sc, &d.pp, &d.ssks, &d.spks, &d.eks, &mut group); - pvss_decrypt_own_share::(sc, &d.pp, &d.ssks, &d.dks, &d.eks, &d.s, &mut group); + pvss_decrypt_own_share::( + sc, &d.pp, &d.ssks, &d.spks, &d.dks, &d.eks, &d.s, &mut group, + ); + + group.finish(); + + d +} + +// TODO: combine with function above, rather than copy-paste +pub fn subaggregatable_pvss_group< + T: HasAggregatableSubtranscript + MalleableTranscript, +>( + sc: &T::SecretSharingConfig, + c: &mut Criterion, +) -> DealingArgs { + let name = T::scheme_name(); + let mut group = c.benchmark_group(format!("pvss/{}", name)); + let mut rng = thread_rng(); + + // TODO: use a lazy pattern to avoid this expensive step when no benchmarks are run + let d = test_utils::setup_dealing::(sc, &mut rng); + + // pvss_transcript_random::(sc, &mut group); + pvss_deal::(sc, &d.pp, &d.ssks, &d.spks, &d.eks, &mut group); + pvss_subaggregate::(sc, &mut group); + pvss_verify::(sc, &d.pp, &d.ssks, &d.spks, &d.eks, &mut group); + pvss_decrypt_own_share::( + sc, &d.pp, &d.ssks, &d.spks, &d.dks, &d.eks, &d.s, &mut group, + ); group.finish(); d } -pub fn weighted_pvss_group>( +pub fn weighted_pvss_group< + T: AggregatableTranscript + MalleableTranscript, +>( sc: &T::SecretSharingConfig, d: DealingArgs, c: &mut Criterion, @@ -123,6 +155,7 @@ fn pvss_deal( sc: &T::SecretSharingConfig, pp: &T::PublicParameters, ssks: &Vec, + spks: &Vec, eks: &Vec, g: &mut BenchmarkGroup, ) { @@ -141,6 +174,7 @@ fn pvss_deal( &sc, &pp, &ssks[0], + &spks[0], &eks, &s, &NoAux, @@ -152,7 +186,7 @@ fn pvss_deal( }); } -fn pvss_aggregate( +fn pvss_aggregate( sc: &T::SecretSharingConfig, g: &mut BenchmarkGroup, ) { @@ -162,11 +196,45 @@ fn pvss_aggregate( g.bench_function(format!("aggregate/{}", sc), move |b| { b.iter_with_setup( || { - let trx = T::generate(&sc, &mut rng); + let trx = T::generate( + &sc, + &T::PublicParameters::with_max_num_shares(sc.get_total_num_shares()), + &mut rng, + ); (trx.clone(), trx) }, |(mut first, second)| { - first.aggregate_with(&sc, &second); + first.aggregate_with(&sc, &second).unwrap(); + }, + ) + }); +} + +fn pvss_subaggregate< + T: Transcript + HasAggregatableSubtranscript, + M: Measurement, +>( + sc: &T::SecretSharingConfig, + g: &mut BenchmarkGroup, +) { + g.throughput(Throughput::Elements(sc.get_total_num_shares() as u64)); + let mut rng = thread_rng(); + + g.bench_function(format!("aggregate/{}", sc), move |b| { + b.iter_with_setup( + || { + let trx = T::generate( + &sc, + &T::PublicParameters::with_max_num_shares(sc.get_total_num_shares()), + &mut rng, + ); + (trx.clone(), trx) + }, + |(first, second)| { + first + .get_subtranscript() + .aggregate_with(&sc, &second.get_subtranscript()) + .unwrap(); }, ) }); @@ -192,6 +260,7 @@ fn pvss_verify( &sc, &pp, &ssks[0], + &spks[0], &eks, &s, &NoAux, @@ -207,7 +276,7 @@ fn pvss_verify( }); } -fn pvss_aggregate_verify( +fn pvss_aggregate_verify( sc: &T::SecretSharingConfig, pp: &T::PublicParameters, ssks: &Vec, @@ -239,6 +308,7 @@ fn pvss_aggregate_verify( &sc, &pp, &ssks[0], + &spks[0], &eks, iss, &NoAux, @@ -269,6 +339,7 @@ fn pvss_decrypt_own_share( sc: &T::SecretSharingConfig, pp: &T::PublicParameters, ssks: &Vec, + spks: &Vec, dks: &Vec, eks: &Vec, s: &T::InputSecret, @@ -282,6 +353,7 @@ fn pvss_decrypt_own_share( &sc, &pp, &ssks[0], + &spks[0], &eks, &s, &NoAux, @@ -293,7 +365,7 @@ fn pvss_decrypt_own_share( b.iter_with_setup( || rng.gen_range(0, sc.get_total_num_players()), |i| { - trx.decrypt_own_share(&sc, &sc.get_player(i), &dks[i]); + trx.decrypt_own_share(&sc, &sc.get_player(i), &dks[i], pp); }, ) }); @@ -309,7 +381,13 @@ fn pvss_transcript_random( let mut rng = thread_rng(); g.bench_function(format!("transcript-random/{}", sc), move |b| { - b.iter(|| T::generate(&sc, &mut rng)) + b.iter(|| { + T::generate( + &sc, + &T::PublicParameters::with_max_num_shares(sc.get_total_num_shares()), + &mut rng, + ) + }) }); } diff --git a/crates/aptos-dkg/benches/range_proof.rs b/crates/aptos-dkg/benches/range_proof.rs new file mode 100644 index 00000000000..275454d3fac --- /dev/null +++ b/crates/aptos-dkg/benches/range_proof.rs @@ -0,0 +1,137 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::GroupGenerators; +use aptos_dkg::{ + range_proofs::{ + dekart_univariate::Proof as UnivariateDeKART, + dekart_univariate_v2::Proof as UnivariateDeKARTv2, traits::BatchedRangeProof, + }, + utils::test_utils::{self}, +}; +use ark_bls12_381::Bls12_381; +use ark_bn254::Bn254; +use ark_ec::pairing::Pairing; +use criterion::{ + criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId, Criterion, +}; +use rand::thread_rng; + +/// WARNING: Do not change this, since our range proof benchmark instructions in +/// `crates/aptos-crypto/README.md` rely on it. +const BROKEN_DEKART_RS_SCHEME_NAME: &str = "dekart-rs-broken"; +const DEKART_RS_SCHEME_NAME: &str = "dekart-rs"; +const BN254: &str = "bn254"; +const BLS12_381: &str = "bls12-381"; + +/// WARNING: These are the relevant batch sizes we want benchmarked to compare against Bulletproofs +const BATCH_SIZES: [usize; 11] = [1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047]; + +/// WARNING: These are the relevant bit widths we want benchmarked to compare against Bulletproofs +const BIT_WIDTHS: [usize; 4] = [8, 16, 32, 64]; + +fn bench_groups(c: &mut Criterion) { + bench_range_proof::>(c, BROKEN_DEKART_RS_SCHEME_NAME, BN254); + bench_range_proof::>( + c, + BROKEN_DEKART_RS_SCHEME_NAME, + BLS12_381, + ); + + bench_range_proof::>(c, DEKART_RS_SCHEME_NAME, BN254); + bench_range_proof::>( + c, + DEKART_RS_SCHEME_NAME, + BLS12_381, + ); +} + +/// Generic benchmark function over any pairing curve and range proof +fn bench_range_proof>( + c: &mut Criterion, + scheme_name: &str, + curve_name: &str, +) { + let mut group = c.benchmark_group(format!("{}/{}", scheme_name, curve_name)); + + let l = std::env::var("L") + .ok() + .and_then(|s| s.parse::().ok()); + let n = std::env::var("N") + .ok() + .and_then(|s| s.parse::().ok()); + + match (l, n) { + (Some(ell), Some(n)) => { + bench_prove::(&mut group, ell, n); + bench_verify::(&mut group, ell, n); + }, + (_, _) => { + for n in BATCH_SIZES { + for ell in BIT_WIDTHS { + bench_prove::(&mut group, ell, n); + bench_verify::(&mut group, ell, n); + } + } + }, + } +} + +fn bench_verify>( + group: &mut BenchmarkGroup, + ell: usize, + n: usize, +) { + group.bench_function( + BenchmarkId::new("verify", format!("ell={ell}/n={n}")), + |b| { + b.iter_with_setup( + || { + let mut rng = thread_rng(); + let group_generators = GroupGenerators::default(); + let (pk, vk) = B::setup(n, ell, group_generators, &mut rng); + let (values, comm, r) = + test_utils::range_proof_random_instance::<_, B, _>(&pk, n, ell, &mut rng); + let proof = B::prove(&pk, &values, ell, &comm, &r, &mut rng); + (vk, n, ell, comm, proof) + }, + |(vk, n, ell, comm, proof)| { + proof.verify(&vk, n, ell, &comm).unwrap(); + }, + ) + }, + ); +} + +fn bench_prove>( + group: &mut BenchmarkGroup, + ell: usize, + n: usize, +) { + group.bench_function( + BenchmarkId::new("prove", format!("ell={ell}/n={n}")), + move |b| { + b.iter_with_setup( + || { + let mut rng = thread_rng(); + let group_generators = GroupGenerators::default(); + let (pk, _) = B::setup(n, ell, group_generators, &mut rng); + let (values, comm, r) = + test_utils::range_proof_random_instance::<_, B, _>(&pk, n, ell, &mut rng); + (pk, values, comm, r) + }, + |(pk, values, comm, r)| { + let mut rng = thread_rng(); + let _proof = B::prove(&pk, &values, ell, &comm, &r, &mut rng); + }, + ) + }, + ); +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = bench_groups +); +criterion_main!(benches); diff --git a/crates/aptos-dkg/benches/weighted_vuf.rs b/crates/aptos-dkg/benches/weighted_vuf.rs index 81bf126e7e8..4faecdd3ae2 100644 --- a/crates/aptos-dkg/benches/weighted_vuf.rs +++ b/crates/aptos-dkg/benches/weighted_vuf.rs @@ -6,14 +6,15 @@ #![allow(clippy::extra_unused_type_parameters)] #![allow(clippy::needless_borrow)] +use aptos_crypto::traits::SecretSharingConfig as _; use aptos_dkg::{ pvss::{ das, dealt_secret_key::g1::DealtSecretKey, insecure_field, test_utils::{get_weighted_configs_for_benchmarking, setup_dealing, NoAux}, - traits::{SecretSharingConfig, Transcript}, - GenericWeighting, Player, WeightedConfig, + traits::Transcript, + GenericWeighting, Player, WeightedConfigBlstrs, }, utils::random::{random_g1_points, random_g2_points}, weighted_vuf::{ @@ -49,7 +50,7 @@ pub fn all_groups(c: &mut Criterion) { fn pinkas_wvuf_derive_eval_micro_benches( bench_cases: Vec<( - WeightedConfig, + WeightedConfigBlstrs, PublicParameters, DealtSecretKey, ::DealtPubKey, @@ -88,7 +89,7 @@ fn pinkas_wvuf_derive_eval_micro_benches( &apks, &mut group, &mut rng, - WeightedConfig::get_worst_case_eligible_subset_of_players, + WeightedConfigBlstrs::get_worst_case_eligible_subset_of_players, "worst_case", ); @@ -99,7 +100,7 @@ fn pinkas_wvuf_derive_eval_micro_benches( &apks, &mut group, &mut rng, - WeightedConfig::get_worst_case_eligible_subset_of_players, + WeightedConfigBlstrs::get_worst_case_eligible_subset_of_players, "worst_case", *num_threads, ); @@ -108,7 +109,7 @@ fn pinkas_wvuf_derive_eval_micro_benches( &wc, &mut group, &mut rng, - WeightedConfig::get_worst_case_eligible_subset_of_players, + WeightedConfigBlstrs::get_worst_case_eligible_subset_of_players, "worst_case", *num_threads, ); @@ -117,7 +118,7 @@ fn pinkas_wvuf_derive_eval_micro_benches( } pub fn wvuf_benches< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKey = WT::DealtPubKey, @@ -127,7 +128,7 @@ pub fn wvuf_benches< >( group: &mut BenchmarkGroup, ) -> Vec<( - WeightedConfig, + WeightedConfigBlstrs, ::PublicParameters, ::DealtSecretKey, ::DealtPubKey, @@ -161,6 +162,7 @@ where &wc, &d.pp, &d.ssks[0], + &d.spks[0], &d.eks, &d.iss[0], &NoAux, @@ -180,7 +182,7 @@ where WT::scheme_name() ); for i in 0..wc.get_total_num_players() { - let (sk, pk) = trx.decrypt_own_share(&wc, &wc.get_player(i), &d.dks[i]); + let (sk, pk) = trx.decrypt_own_share(&wc, &wc.get_player(i), &d.dks[i], &d.pp); let (ask, apk) = WVUF::augment_key_pair(&vuf_pp, sk.clone(), pk.clone(), &mut rng); sks.push(sk); @@ -253,17 +255,20 @@ where ); // benchmarks the sequence of WVUF::verify_share calls on shares from a specific subset of players - let bc: Vec<(fn(&WeightedConfig, &mut ThreadRng) -> Vec, String)> = vec![ + let bc: Vec<( + fn(&WeightedConfigBlstrs, &mut ThreadRng) -> Vec, + String, + )> = vec![ ( - WeightedConfig::get_random_eligible_subset_of_players, + WeightedConfigBlstrs::get_random_eligible_subset_of_players, "random".to_string(), ), ( - WeightedConfig::get_best_case_eligible_subset_of_players, + WeightedConfigBlstrs::get_best_case_eligible_subset_of_players, "best_case".to_string(), ), ( - WeightedConfig::get_worst_case_eligible_subset_of_players, + WeightedConfigBlstrs::get_worst_case_eligible_subset_of_players, "worst_case".to_string(), ), ]; @@ -324,7 +329,7 @@ where } fn wvuf_augment_random_keypair< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -333,7 +338,7 @@ fn wvuf_augment_random_keypair< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, sks: &Vec, pks: &Vec, @@ -355,7 +360,7 @@ fn wvuf_augment_random_keypair< } fn wvuf_augment_all_pubkeys< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -364,7 +369,7 @@ fn wvuf_augment_all_pubkeys< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, pks: &Vec, deltas: &Vec, @@ -385,7 +390,7 @@ fn wvuf_augment_all_pubkeys< } fn wvuf_augment_random_pubkey< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -394,7 +399,7 @@ fn wvuf_augment_random_pubkey< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, pks: &Vec, deltas: &Vec, @@ -419,7 +424,7 @@ fn wvuf_augment_random_pubkey< } fn wvuf_create_share_random< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -427,7 +432,7 @@ fn wvuf_create_share_random< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec, group: &mut BenchmarkGroup, rng: &mut R, @@ -446,7 +451,7 @@ fn wvuf_create_share_random< } fn wvuf_create_share_specific< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -454,7 +459,7 @@ fn wvuf_create_share_specific< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec, group: &mut BenchmarkGroup, player: &Player, @@ -471,7 +476,7 @@ fn wvuf_create_share_specific< } fn wvuf_create_share_average< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -479,7 +484,7 @@ fn wvuf_create_share_average< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec, group: &mut BenchmarkGroup, ) where @@ -513,7 +518,7 @@ fn wvuf_create_share_average< } fn wvuf_verify_share_random< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -521,7 +526,7 @@ fn wvuf_verify_share_random< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, asks: &Vec, apks: &Vec, @@ -544,7 +549,7 @@ fn wvuf_verify_share_random< } fn wvuf_verify_share_average< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -552,7 +557,7 @@ fn wvuf_verify_share_average< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, asks: &Vec, apks: &Vec, @@ -587,7 +592,7 @@ fn wvuf_verify_share_average< } fn wvuf_many_verify_shares< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -596,11 +601,11 @@ fn wvuf_many_verify_shares< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, asks: &Vec, apks: &Vec, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, name: &str, group: &mut BenchmarkGroup, rng: &mut R, @@ -620,7 +625,7 @@ fn wvuf_many_verify_shares< } fn wvuf_verify_share_specific< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, @@ -628,7 +633,7 @@ fn wvuf_verify_share_specific< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, vuf_pp: &WVUF::PublicParameters, asks: &Vec, apks: &Vec, @@ -650,7 +655,7 @@ fn wvuf_verify_share_specific< } fn wvuf_aggregate_shares< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKey = WT::DealtPubKey, @@ -660,12 +665,12 @@ fn wvuf_aggregate_shares< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec, apks: &Vec, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &String, ) where WVUF::PublicParameters: for<'a> From<&'a WT::PublicParameters>, @@ -684,7 +689,7 @@ fn wvuf_aggregate_shares< } fn wvuf_verify_proof< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKey = WT::DealtPubKey, @@ -694,14 +699,14 @@ fn wvuf_verify_proof< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, pp: &WVUF::PublicParameters, pk: &WVUF::PubKey, asks: &Vec, apks: &Vec, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &String, ) where WVUF::PublicParameters: for<'a> From<&'a WT::PublicParameters>, @@ -728,7 +733,7 @@ fn wvuf_verify_proof< } fn wvuf_derive_eval< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKey = WT::DealtPubKey, @@ -738,13 +743,13 @@ fn wvuf_derive_eval< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, pp: &WVUF::PublicParameters, asks: &Vec, apks: &Vec, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &String, num_threads: usize, ) where @@ -783,12 +788,12 @@ fn pinkas_wvuf_derive_eval_collect_lagrange_shares_and_rks< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec<::AugmentedSecretKeyShare>, apks: &Vec<::AugmentedPubKeyShare>, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &str, ) { group.bench_function( @@ -823,12 +828,12 @@ fn pinkas_wvuf_derive_eval_collect_lagrange_shares_and_rks< fn pinkas_wvuf_derive_eval_rks_multiexps( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec<::AugmentedSecretKeyShare>, apks: &Vec<::AugmentedPubKeyShare>, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &str, num_threads: usize, ) { @@ -871,7 +876,7 @@ fn pinkas_wvuf_derive_eval_rks_multiexps>>(); + let rks = rks.iter().collect::>>(); let _ = PinkasWUF::rk_multiexps(&proof, rks, &lagr, &ranges, &pool); }, ) @@ -881,10 +886,10 @@ fn pinkas_wvuf_derive_eval_rks_multiexps( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, group: &mut BenchmarkGroup, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, subset_type: &str, num_threads: usize, ) { @@ -914,7 +919,7 @@ fn pinkas_wvuf_derive_eval_multipairing, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKey = WT::DealtPubKey, @@ -924,11 +929,11 @@ fn get_apks_and_proofs< R: rand_core::RngCore + rand_core::CryptoRng, >( // For efficiency, we re-use the PVSS transcript - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, asks: &Vec, apks: &Vec, rng: &mut R, - pick_subset_fn: fn(&WeightedConfig, &mut R) -> Vec, + pick_subset_fn: fn(&WeightedConfigBlstrs, &mut R) -> Vec, ) -> Vec<(Player, WVUF::AugmentedPubKeyShare, WVUF::ProofShare)> { let players = pick_subset_fn(wc, rng); @@ -945,14 +950,14 @@ fn get_apks_and_proofs< } fn wvuf_eval< - WT: Transcript, + WT: Transcript, WVUF: WeightedVUF< SecretKey = WT::DealtSecretKey, PubKeyShare = WT::DealtPubKeyShare, SecretKeyShare = WT::DealtSecretKeyShare, >, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, sk: &WVUF::SecretKey, group: &mut BenchmarkGroup, ) where diff --git a/crates/aptos-dkg/src/algebra/fft.rs b/crates/aptos-dkg/src/algebra/fft.rs deleted file mode 100644 index 1dfffcfe27d..00000000000 --- a/crates/aptos-dkg/src/algebra/fft.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::algebra::evaluation_domain::EvaluationDomain; -use blstrs::Scalar; -use ff::Field; -use std::ops::{AddAssign, MulAssign, SubAssign}; - -/// Computes a Discrete Fourier Transform (DFT), a.k.a., an FFT, on the polynomial $f(X)$ in `poly`, -/// returning all the $N$ evaluations at the roots of unity: $f(\omega^0), f(\omega^1), \ldots, f(\omega^{N-1})$ -/// where `dom.log_N` is $\log_2{N}$ and `dom.omega` is $\omega$. -pub fn fft_assign(poly: &mut Vec, dom: &EvaluationDomain) { - // Pad with zeros, if necessary - if poly.len() < dom.N { - poly.resize(dom.N, Scalar::ZERO); - } - - serial_fft_assign(poly.as_mut_slice(), &dom.omega, dom.log_N as u32) -} - -pub fn fft(poly: &Vec, dom: &EvaluationDomain) -> Vec { - let mut evals = Vec::with_capacity(dom.N); - evals.resize(poly.len(), Scalar::ZERO); - evals.copy_from_slice(&poly); - - fft_assign(&mut evals, dom); - - evals -} - -/// Computes the inverse of `fft_assign`. -pub fn ifft_assign(poly: &mut Vec, dom: &EvaluationDomain) { - serial_fft_assign(poly.as_mut_slice(), &dom.omega_inverse, dom.log_N as u32); - - for coeff in poly { - coeff.mul_assign(&dom.N_inverse); - } -} - -/// `bellman`'s FFT code adapted to `blstrs::Scalar`. -fn serial_fft_assign(a: &mut [Scalar], omega: &Scalar, log_n: u32) { - fn bitreverse(mut n: u32, l: u32) -> u32 { - let mut r = 0; - for _ in 0..l { - r = (r << 1) | (n & 1); - n >>= 1; - } - r - } - - let n = a.len() as u32; - assert_eq!(n, 1 << log_n); - - for k in 0..n { - let rk = bitreverse(k, log_n); - if k < rk { - a.swap(rk as usize, k as usize); - } - } - - let mut m = 1; - for _ in 0..log_n { - // TODO(Performance): Could have these precomputed via BatchEvaluationDomain, but need to - // update all upstream calls to pass in the `BatchEvaluationDomain`. - let w_m = omega.pow_vartime([u64::from(n / (2 * m))]); - - let mut k = 0; - while k < n { - let mut w = Scalar::ONE; - for j in 0..m { - let mut t = a[(k + j + m) as usize]; - t.mul_assign(&w); - let mut tmp = a[(k + j) as usize]; - tmp.sub_assign(&t); - a[(k + j + m) as usize] = tmp; - a[(k + j) as usize].add_assign(&t); - w.mul_assign(&w_m); - } - - k += 2 * m; - } - - m *= 2; - } -} - -#[cfg(test)] -mod test { - use crate::{ - algebra::{ - evaluation_domain::{smallest_power_of_2_greater_than_or_eq, EvaluationDomain}, - fft::fft_assign, - }, - utils::random::random_scalars, - }; - use rand::thread_rng; - - #[test] - #[allow(non_snake_case)] - fn fft_assign_full_domain() { - for n in [1, 2, 3, 5, 7, 8, 10, 16] { - let dom = EvaluationDomain::new(n).unwrap(); - let (N, _) = smallest_power_of_2_greater_than_or_eq(n); - - let mut rng = thread_rng(); - let mut f = random_scalars(n, &mut rng); - - assert_eq!(f.len(), n); - fft_assign(&mut f, &dom); - assert_eq!(f.len(), N); - } - } -} diff --git a/crates/aptos-dkg/src/algebra/mod.rs b/crates/aptos-dkg/src/algebra/mod.rs deleted file mode 100644 index 647deecdf78..00000000000 --- a/crates/aptos-dkg/src/algebra/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -pub mod evaluation_domain; -pub mod fft; -pub mod lagrange; -pub mod polynomials; diff --git a/crates/aptos-dkg/src/algebra/polynomials.rs b/crates/aptos-dkg/src/algebra/polynomials.rs deleted file mode 100644 index a4b83c6c245..00000000000 --- a/crates/aptos-dkg/src/algebra/polynomials.rs +++ /dev/null @@ -1,529 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - algebra::{ - evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, - fft, - }, - pvss::{input_secret::InputSecret, ThresholdConfig}, - utils::{is_power_of_two, random::random_scalars}, -}; -use blstrs::Scalar; -use ff::Field; -use more_asserts::debug_assert_le; -use std::ops::{AddAssign, Mul, MulAssign, SubAssign}; - -/// Returns $\[1, \tau, \tau^2, \tau^3, \ldots, \tau^{n-1}\]$. -pub fn get_powers_of_tau(tau: &Scalar, n: usize) -> Vec { - if n == 0 { - return vec![]; - } - - let mut taus = Vec::with_capacity(n); - - taus.push(Scalar::ONE); - - for _ in 0..n - 1 { - taus.push(taus.last().unwrap().mul(tau)); - } - debug_assert_eq!(taus.len(), n); - - taus -} - -/// Returns $\[\tau, \tau^2, \tau^3, \ldots, \tau^n\]$. -pub fn get_nonzero_powers_of_tau(tau: &Scalar, n: usize) -> Vec { - let mut taus = Vec::with_capacity(n); - - taus.push(*tau); - - for _ in 0..n - 1 { - taus.push(taus.last().unwrap().mul(tau)); - } - debug_assert_eq!(taus.len(), n); - - taus -} - -/// Returns the size of the evaluation domain needed to multiply these two polynomials via FFT. -pub fn get_evaluation_dom_size_for_multiplication(f: &Vec, g: &Vec) -> usize { - //println!("get_eval_dom: |f| = {}, |g| = {}", f.len(), g.len()); - let f_deg = f.len() - 1; - let g_deg = g.len() - 1; - - // The degree $d$ of $f \cdot g$ will be $\deg{f} + \deg{g}$. - let fg_deg = f_deg + g_deg; - // But we need $d+1$ evaluations to interpolate a degree $d$ polynomial. - let num_evals = fg_deg + 1; - - num_evals -} - -/// Returns an evaluation domain for an FFT of size the number of coefficients in the polynomial $f(X) \cdot g(X)$. -pub fn get_evaluation_dom_for_multiplication(f: &Vec, g: &Vec) -> EvaluationDomain { - let num_evals = get_evaluation_dom_size_for_multiplication(f, g); - EvaluationDomain::new(num_evals).unwrap() -} - -/// Returns $f(x)$ for a polynomial $f$ and a point $x$. -pub fn poly_eval(f: &Vec, x: &Scalar) -> Scalar { - assert!(!f.is_empty()); - - //let deg = f.len() - 1; - let mut eval = Scalar::ZERO; // f(x) - let mut x_i = Scalar::ONE; // x^i, i = {0, 1, ..., deg(f)} - for c_i in f { - eval += c_i * x_i; - - x_i *= x; - } - - eval -} - -/// Lets $f(X) = f(X) + g(X)$. Stores the result in `f` so assumes $\deg(f) \ge \deg(g)$. -pub fn poly_add_assign(f: &mut Vec, g: &[Scalar]) { - if g.len() > f.len() { - f.resize(g.len(), Scalar::ZERO); - } - - for i in 0..g.len() { - f[i].add_assign(g[i]); - } -} - -/// Lets $f(X) = f(X) - g(X)$. Stores the result in `f` so assumes $\deg(f) \ge \deg(g)$. -pub fn poly_sub_assign(f: &mut Vec, g: &[Scalar]) { - if g.len() > f.len() { - f.resize(g.len(), Scalar::ZERO); - } - for i in 0..g.len() { - f[i].sub_assign(g[i]); - } -} - -/// Computes the product of $f$ and $g$, letting $f = f \cdot g$ and $g = FFT(g)$. -/// Let $d = \deg(f) + \deg(g)$. Takes $O(d\log{d})$ time via three FFT. -/// -/// Note: If you already have an `EvaluationDomain` for $n = \deg(f) + \deg(g) + 1$, use the faster -/// `poly_mul_assign_fft_with_dom` which avoids recomputing the roots of unity and the other inverses. -pub fn poly_mul_assign_fft(f: &mut Vec, g: &mut Vec) { - debug_assert!(!f.is_empty()); - debug_assert!(!g.is_empty()); - - poly_mul_assign_fft_with_dom(f, g, &get_evaluation_dom_for_multiplication(f, g)) -} - -/// Like `poly_mul_assign` but returns the result, instead of modifying the arguments. -pub fn poly_mul_fft(f: &Vec, g: &Vec) -> Vec { - debug_assert!(!f.is_empty()); - debug_assert!(!g.is_empty()); - - let mut f_copy = f.clone(); - let mut g_copy = g.clone(); - - poly_mul_assign_fft_with_dom( - &mut f_copy, - &mut g_copy, - &get_evaluation_dom_for_multiplication(f, g), - ); - - f_copy -} - -/// If the caller already has an `EvaluationDomain` for $n = \deg(f) + \deg(g) + 1$, this function -/// will avoid some redundant field operations and be slightly faster than `poly_mul_assign_fft`. -pub fn poly_mul_assign_fft_with_dom( - f: &mut Vec, - g: &mut Vec, - dom: &EvaluationDomain, -) { - debug_assert!(!f.is_empty()); - debug_assert!(!g.is_empty()); - debug_assert_eq!((f.len() - 1) + (g.len() - 1) + 1, dom.n); - - fft::fft_assign(f, &dom); - fft::fft_assign(g, &dom); - for i in 0..dom.N { - f[i].mul_assign(g[i]); - } - - fft::ifft_assign(f, &dom); - f.truncate(dom.n); -} - -/// Like `poly_mul_assign_fft` but slower in time $\deg(f) \cdot \deg(g)$ and returns the product in -/// `out`, leaving `f` and `g` untouched. -/// TODO(Performance): Can we do this in-place over `f` or `g` without a separate `out`. -pub fn poly_mul_assign_slow(f: &Vec, g: &Vec, out: &mut Vec) { - assert!(!f.is_empty()); - assert!(!g.is_empty()); - - let f_len = f.len(); - let g_len = g.len(); - - // Set `out` to all zeros. - out.truncate(0); // Rust docs say "Note that this method has no effect on the allocated capacity of the vector." - out.resize(f_len + g_len - 1, Scalar::ZERO); - for (i1, a) in f.iter().enumerate() { - for (i2, b) in g.iter().enumerate() { - let mut prod = *a; - prod.mul_assign(b); - out[i1 + i2].add_assign(&prod); - } - } -} - -/// Like `poly_mul_fft` but slower: runs in time $\deg(f) \cdot \deg(g)$. -/// Returns the product, leaving `f` and `g` untouched. -/// -/// Performance notes: Beats FFT for $t \ge 32$. -pub fn poly_mul_slow(f: &Vec, g: &Vec) -> Vec { - let mut out = Vec::with_capacity(get_evaluation_dom_size_for_multiplication(f, g)); - // println!( - // "poly_mul_slow: |f| = {}, |g| = {}, |out| = {}", - // f.len(), - // g.len(), - // out.capacity() - // ); - poly_mul_assign_slow(f, g, &mut out); - out -} - -/// Like `poly_mul_assign_fft` but runs in time $O(n)^{1.58})$. -/// Assumes that $\deg{f} - 1 = \deg{g} - 1 = 2^k$ for some $k$. -/// Returns the product in `out`, leaving `f` and `g` untouched. -/// -/// Performance notes: Starts beating `poly_mul_slow` after $t \ge 512$. Never beats FFT, so useless -/// because FFT beats naive after $t > 64$. -pub fn poly_mul_assign_less_slow(f: &Vec, g: &Vec, out: &mut Vec) { - let mut result = poly_mul_less_slow(f.as_slice(), g.as_slice()); - - out.truncate(0); - out.append(&mut result); -} - -pub fn poly_mul_less_slow(f: &[Scalar], g: &[Scalar]) -> Vec { - let n = f.len(); - assert!(is_power_of_two(n)); - - // TODO(Performance): Let the base case be the naive n^2 multiplication for any f_len < threshold? - // handle base case - if n == 1 { - return vec![f[0].mul(g[0])]; - } - - let g_len = g.len(); - let half_n = n / 2; - assert_eq!(n, g_len); - - // split f into halves - let f_0 = &f[0..half_n]; - let f_1 = &f[half_n..n]; - debug_assert_eq!(f_0.len() + f_1.len(), n); - - // split g into halves - let g_0 = &g[0..half_n]; - let g_1 = &g[half_n..n]; - debug_assert_eq!(g_0.len() + g_1.len(), n); - - // let f_01 = f_0 + f_1 - let mut f_01 = Vec::with_capacity(half_n); - f_0.clone_into(&mut f_01); - for i in 0..half_n { - f_01[i].add_assign(f_1[i]); - } - - // let g_01 = g_0 + g_1 - let mut g_01 = Vec::with_capacity(half_n); - g_0.clone_into(&mut g_01); - for i in 0..half_n { - g_01[i].add_assign(g_1[i]); - } - - // $y = (f_0 + f_1) \cdot (g_0 + g_1)$ - let mut y = poly_mul_less_slow(&f_01, &g_01); - // $z = f_0 \cdot g_0$ - let mut z = poly_mul_less_slow(f_1, g_1); - // $u = f_1 \cdot g_0$ - let mut u = poly_mul_less_slow(f_0, g_0); - - // first, compute (y - u - z) - poly_sub_assign(&mut y, &u); - poly_sub_assign(&mut y, &z); - - // second, compute (y - u - z) * X^{n/2} - poly_xnmul_assign(&mut y, half_n); - - // third, compute z * X^n - poly_xnmul_assign(&mut z, n); - - // fourth, add everything up with $u(X)$ - poly_add_assign(&mut u, &y); - poly_add_assign(&mut u, &z); - - u.into() -} -/// Sets $f(X) = f(X) \cdot X^n$, by simply shifting the coefficients. -/// As always we assume $\deg{f}$ is `f.len() - 1`. -pub fn poly_xnmul_assign(f: &mut Vec, n: usize) { - if n == 0 { - return; - } - - let old_len = f.len(); - - // extend with zero coefficients for X^n, X^{n-1}, \dots, X - f.resize(old_len + n, Scalar::ZERO); - - // Shift coefficients by `n` positions - for i in (0..old_len).rev() { - f[i + n] = f[i] - } - - // Set the last n coefficients $f_{n-1}, \cdots, f_0$ to 0. - for i in 0..n { - f[i] = Scalar::ZERO; - } -} - -/// Like `poly_mul_by_xn_assign` but returns the result. -pub fn poly_xnmul(f: &Vec, n: usize) -> Vec { - if n == 0 { - return f.clone(); - } - - let len = n + f.len(); - - // let result = f - let mut result = Vec::with_capacity(len); - result.resize(f.len(), Scalar::ZERO); - result.copy_from_slice(f); - - poly_xnmul_assign(&mut result, n); - - result -} - -/// Calculates the derivative of $f(X)$. -pub fn poly_differentiate(f: &mut Vec) { - let f_deg = f.len() - 1; - - for i in 0..f_deg { - f[i] = f[i + 1].mul(Scalar::from((i + 1) as u64)); - } - - f.truncate(f_deg); -} - -/// Given a set $S$ of scalars, returns the *accumulator* polynomial $Z(X) = \prod_{a \in S} (X - a)$. -#[allow(non_snake_case)] -pub fn accumulator_poly_slow(S: &[Scalar]) -> Vec { - let set_size = S.len(); - // println!("len: {len}"); - - if set_size == 0 { - return vec![]; - } else if set_size == 1 { - // println!("Returning (X - {})", S[0]); - return vec![-S[0], Scalar::ONE]; - } - - let m = set_size / 2; - // println!("m: {m}"); - - let left = &S[0..m]; - // println!("left: {}", left.len()); - let right = &S[m..set_size]; - // println!("right: {}", right.len()); - - let mut left_poly = accumulator_poly_slow(left); - let mut right_poly = accumulator_poly_slow(right); - if left_poly.is_empty() { - return right_poly; - } - if right_poly.is_empty() { - return left_poly; - } - - poly_mul_assign_fft(&mut left_poly, &mut right_poly); - - left_poly -} - -/// Like `accumulator_poly_slow` but: -/// - Avoids recomputing too many different roots of unity (EvaluationDomain::new takes 3.5 microsecs -/// and `accumulator_poly_slow` makes around 2000 calls to it). Saves 10 milliseconds out of total of 70. -/// - Avoids FFTs when multiplying polynomials with $\deg{f} + \deg{g} - 1 \le fft_thresh$. -/// Saves 35 milliseconds. -#[allow(non_snake_case)] -pub fn accumulator_poly( - S: &[Scalar], - batch_dom: &BatchEvaluationDomain, - fft_thresh: usize, -) -> Vec { - let set_size = S.len(); - - if set_size == 0 { - return vec![]; - } else if set_size == 1 { - return vec![-S[0], Scalar::ONE]; - } else if set_size == 2 { - return vec![ - S[0] * S[1], // X^0 coeff is (-1)^0 (S[0] S[1]) = S[0] S[1] - -(S[0] + S[1]), // X^1 coeff is (-1)^1 (S[0] + S[1]) = -(S[0] + S[1]) - Scalar::ONE, // X^2 coeff is 1 - ]; - } else if set_size == 3 { - // https://math.stackexchange.com/questions/88917/relation-betwen-coefficients-and-roots-of-a-polynomial - let s1_add_s2 = S[1] + S[2]; - let s1_mul_s2 = S[1] * S[2]; - - return vec![ - -(S[0] * s1_mul_s2), // X^3 coeff is -(S[0] S[1] S[2]) - S[0] * s1_add_s2 + s1_mul_s2, // X^2 coeff is S[0] S[1] + S[0] S[2] + S[1] S[2] - -(S[0] + S[1] + S[2]), // X^1 coeff is -(S[0] + S[1] + S[2]) - Scalar::ONE, // X^0 coeff is 1 - ]; - } - - let m = set_size / 2; - - let left = &S[0..m]; - let right = &S[m..set_size]; - - let mut left_poly = accumulator_poly(left, batch_dom, fft_thresh); - let mut right_poly = accumulator_poly(right, batch_dom, fft_thresh); - if left_poly.is_empty() { - return right_poly; - } - if right_poly.is_empty() { - return left_poly; - } - - let dom_size = get_evaluation_dom_size_for_multiplication(&left_poly, &right_poly); - if dom_size < fft_thresh { - poly_mul_slow(&left_poly, &right_poly) - } else { - poly_mul_assign_fft_with_dom( - &mut left_poly, - &mut right_poly, - &batch_dom.get_subdomain(dom_size), - ); - left_poly - } -} - -/// More wisely schedules the sizes of the polynomials that are multiplied via FFT. Specifically, -/// always ensures we are multiplying degree (2^k - 1) by degree 2^k, to get a degree (2^{k+1} - 1) -/// polynomial. This ensures optimal usage of the 3 FFTs: the first two FFTs on the degree 2^k - 1 -/// and degree 2^k have 50% usage, while the last inverse FFT that outputs 2^{k+1} coefficients has -/// 100% usage. -/// -/// Expected this to be much faster than `accumulator_poly` but seems to beat by at most 1 millisecond -/// for the following parameters: -/// -/// 128 FFT thresh, 256 naive -thresh > 15.4 ms -/// 256 FFT thresh, 512 naive thresh -> 14.8 ms -/// 256 FFT thresh, 128 naive thresh -> 14.1 ms -#[allow(non_snake_case)] -pub fn accumulator_poly_scheduled( - S: &[Scalar], - batch_dom: &BatchEvaluationDomain, - naive_thresh: usize, - fft_thresh: usize, -) -> Vec { - let mut n = S.len() + 1; - - if S.len() < naive_thresh { - // println!("Directly returning accumulator for set size {}", S.len()); - return accumulator_poly(S, batch_dom, fft_thresh); - } - - let mut batch_size = 1; - while n != 1 { - n /= 2; - batch_size *= 2; - } - batch_size -= 1; // 2^k - 1 <= |S| - - debug_assert_le!(batch_size, S.len()); - assert!(is_power_of_two(batch_size + 1)); - - let left = - accumulator_poly_scheduled_inner(&S[0..batch_size], batch_dom, naive_thresh, fft_thresh); - if batch_size == S.len() { - left - } else { - let right = - accumulator_poly_scheduled(&S[batch_size..], batch_dom, naive_thresh, fft_thresh); - - poly_mul_fft(&left, &right) - } -} - -#[allow(non_snake_case)] -fn accumulator_poly_scheduled_inner( - S: &[Scalar], - batch_dom: &BatchEvaluationDomain, - naive_thresh: usize, - fft_thresh: usize, -) -> Vec { - let len = S.len(); - debug_assert!(is_power_of_two(len + 1)); - - if len < naive_thresh { - // println!("Directly returning accumulator for set size {len}"); - return accumulator_poly(S, batch_dom, fft_thresh); - } - - let batch_size = len.div_ceil(2) - 1; - debug_assert_eq!(batch_size * 2 + 1, len); - - let mut b1 = - accumulator_poly_scheduled_inner(&S[0..batch_size], batch_dom, naive_thresh, fft_thresh); - debug_assert_eq!(b1.len(), batch_size + 1); - let b2 = accumulator_poly_scheduled_inner( - &S[batch_size..2 * batch_size], - batch_dom, - naive_thresh, - fft_thresh, - ); - debug_assert_eq!(b2.len(), batch_size + 1); - let deg1 = accumulator_poly(&S[2 * batch_size..], batch_dom, fft_thresh); - debug_assert_eq!(deg1.len(), 2); - - // println!( - // "Multiplying deg-{} by deg-{}", - // b1.len() - 1, - // b2.len() - 1 + deg1.len() - 1 - // ); - - let mut b2 = poly_mul_slow(°1, &b2); - poly_mul_assign_fft_with_dom(&mut b1, &mut b2, &batch_dom.get_subdomain(len + 1)); - - b1 -} - -/// Deals a secret `s` in a `t`-out-of-`n` fashion (as per `sc`) returning (1) the degree `t-1` -/// polynomial encoding the secret and (2) its evaluations at all the `n` $N$th roots-of-unity where -/// $N$ is the smallest power of two $\ge n$. -/// -/// Any `t` evaluations are sufficient to reconstruct the secret `s`. -pub fn shamir_secret_share< - R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, ->( - sc: &ThresholdConfig, - s: &InputSecret, - rng: &mut R, -) -> (Vec, Vec) { - // A random, degree t-1 polynomial $f(X) = [a_0, \dots, a_{t-1}]$, with $a_0$ set to `s.a` - let mut f = random_scalars(sc.t, rng); - f[0] = *s.get_secret_a(); - - // Evaluate $f$ at all the $N$th roots of unity. - let mut f_evals = fft::fft(&f, sc.get_evaluation_domain()); - f_evals.truncate(sc.n); - (f, f_evals) -} diff --git a/crates/aptos-dkg/src/constants.rs b/crates/aptos-dkg/src/constants.rs deleted file mode 100644 index 135bdf453bc..00000000000 --- a/crates/aptos-dkg/src/constants.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use num_bigint::BigUint; -use once_cell::sync::Lazy; - -// -// Sizes -// - -/// The size in bytes of a compressed G1 point (efficiently deserializable into projective coordinates) -pub const G1_PROJ_NUM_BYTES: usize = 48; - -/// The size in bytes of a compressed G2 point (efficiently deserializable into projective coordinates) -pub const G2_PROJ_NUM_BYTES: usize = 96; - -/// The size in bytes of a scalar. -pub const SCALAR_NUM_BYTES: usize = 32; - -pub(crate) const SCALAR_FIELD_ORDER: Lazy = - Lazy::new(crate::utils::biguint::get_scalar_field_order_as_biguint); diff --git a/crates/aptos-dkg/src/dlog/bsgs.rs b/crates/aptos-dkg/src/dlog/bsgs.rs new file mode 100644 index 00000000000..52efc372a0c --- /dev/null +++ b/crates/aptos-dkg/src/dlog/bsgs.rs @@ -0,0 +1,94 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use ark_ec::CurveGroup; +use std::collections::HashMap; + +/// Compute discrete log using baby-step giant-step with a precomputed table +/// +/// # Arguments +/// - `G`: base of the exponentiation +/// - `H`: target point +/// - `baby_table`: precomputed HashMap from `C.to_compressed()` |---> exponent +/// - `range_limit`: maximum size of the exponent we're trying to obtain. TODO: Change to u64? +// +// TODO:: ensure that G is also the element used to build the baby_table? So turn baby_table into a struct? +#[allow(non_snake_case)] +pub fn dlog( + G: C, + H: C, + baby_table: &HashMap, u32>, + range_limit: u32, +) -> Option { + let byte_size = G.compressed_size(); + + let m = baby_table + .len() + .try_into() + .expect("Table seems rather large"); + let n = range_limit.div_ceil(m); + + let G_neg_m = G * -C::ScalarField::from(m); + + let mut gamma = H; + + for i in 0..n { + let mut buf = vec![0u8; byte_size]; + gamma.serialize_compressed(&mut buf[..]).unwrap(); + + if let Some(&j) = baby_table.get(&buf) { + return Some(i * m + j); + } + + gamma += G_neg_m; + } + + None +} + +#[allow(non_snake_case)] +pub fn dlog_vec( + G: C, + H_vec: &[C], + baby_table: &HashMap, u32>, + range_limit: u32, +) -> Option> { + let mut result = Vec::with_capacity(H_vec.len()); + + for H in H_vec { + if let Some(x) = dlog(G, *H, baby_table, range_limit) { + result.push(x); + } else { + return None; // fail early if any element cannot be solved + } + } + + Some(result) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::dlog; + use ark_bn254::G1Projective; + use ark_ec::PrimeGroup; + + #[allow(non_snake_case)] + #[test] + fn test_bsgs_bn254_exhaustive() { + let G = G1Projective::generator(); + let range_limit = 1 << 8; + + let baby_table = dlog::table::build::(G, 1 << 4); + + // Test **all** values of x from 0 to `range_limit - 1` + for x in 0..range_limit { + let H = G * ark_bn254::Fr::from(x); + + let recovered = dlog::(G, H, &baby_table, range_limit) + .expect("Failed to recover discrete log"); + + assert_eq!(recovered, x, "Discrete log mismatch for x = {}", x); + } + } +} diff --git a/crates/aptos-dkg/src/dlog/mod.rs b/crates/aptos-dkg/src/dlog/mod.rs new file mode 100644 index 00000000000..fe4c13ee99b --- /dev/null +++ b/crates/aptos-dkg/src/dlog/mod.rs @@ -0,0 +1,5 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod bsgs; +pub mod table; diff --git a/crates/aptos-dkg/src/dlog/table.rs b/crates/aptos-dkg/src/dlog/table.rs new file mode 100644 index 00000000000..42860e27d21 --- /dev/null +++ b/crates/aptos-dkg/src/dlog/table.rs @@ -0,0 +1,31 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use ark_ec::CurveGroup; +use std::collections::HashMap; + +/// Build a baby-step table of size `table_size` +/// +/// Returns a HashMap: `C.to_compressed() |---> exponent` +#[allow(non_snake_case)] +pub fn build(G: C, table_size: u32) -> HashMap, u32> { + let byte_size = G.compressed_size(); + + let mut table = HashMap::with_capacity(table_size as usize); + let mut current = C::zero(); + + for j in 0..table_size { + let mut buf = vec![0u8; byte_size]; + current.serialize_compressed(&mut &mut buf[..]).unwrap(); + table.insert(buf, j); + current += G; + } + + table +} + +#[allow(non_snake_case)] +pub fn build_default(table_size: u32) -> HashMap, u32> { + let G = C::generator(); + build(G, table_size) +} diff --git a/crates/aptos-dkg/src/fiat_shamir.rs b/crates/aptos-dkg/src/fiat_shamir.rs new file mode 100644 index 00000000000..335abbffb61 --- /dev/null +++ b/crates/aptos-dkg/src/fiat_shamir.rs @@ -0,0 +1,230 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! For what it's worth, I don't understand why the `merlin` library wants the user to first define +//! a trait with their 'append' operations and then implement that trait on `merlin::Transcript`. +//! I also don't understand how that doesn't break the orphan rule in Rust. +//! I suspect the reason they want the developer to do things these ways is to force them to cleanly +//! define all the things that are appended to the transcript. + +use crate::{ + range_proofs::traits::BatchedRangeProof, sigma_protocol, sigma_protocol::homomorphism, Scalar, +}; +use ark_ec::pairing::Pairing; +use ark_ff::PrimeField; +use ark_serialize::CanonicalSerialize; +use serde::Serialize; + +/// Helper trait for deriving random scalars from a transcript. +/// +/// Not every Fiat–Shamir call needs higher-level operations +/// (like appending PVSS information), but most do require scalar +/// derivation. This basic trait provides that functionality. +/// +/// ⚠️ This trait is intentionally private: functions like `challenge_scalars` +/// should **only** be used internally to ensure properly +/// labelled scalar generation across Fiat-Shamir protocols. +// +// TODO: Again, seems that ideally Scalar should become Scalar instead +trait ScalarProtocol { + fn challenge_full_scalars(&mut self, label: &[u8], num_scalars: usize) -> Vec>; + + fn challenge_full_scalar(&mut self, label: &[u8]) -> Scalar { + self.challenge_full_scalars(label, 1)[0] + } + + fn challenge_128bit_scalars(&mut self, label: &[u8], num_scalars: usize) -> Vec>; +} + +impl ScalarProtocol for merlin::Transcript { + fn challenge_full_scalars(&mut self, label: &[u8], num_scalars: usize) -> Vec> { + let byte_size = (E::ScalarField::MODULUS_BIT_SIZE as usize) / 8; + let mut buf = vec![0u8; 2 * num_scalars * byte_size]; + self.challenge_bytes(label, &mut buf); + + buf.chunks(2 * byte_size) + .map(|chunk| Scalar(E::ScalarField::from_le_bytes_mod_order(chunk))) + .collect() + } + + fn challenge_128bit_scalars(&mut self, label: &[u8], num_scalars: usize) -> Vec> { + let mut buf = vec![0u8; num_scalars * 16]; + self.challenge_bytes(label, &mut buf); + + buf.chunks(16) + .map(|chunk| { + Scalar(E::ScalarField::from_le_bytes_mod_order( + chunk.try_into().unwrap(), + )) + }) + .collect() + } +} + +pub trait RangeProof> { + fn append_sep(&mut self, dst: &[u8]); + + fn append_vk(&mut self, vk: &B::VerificationKey); + + fn append_public_statement(&mut self, public_statement: B::PublicStatement); + + fn append_hat_f_commitment(&mut self, commitment: &A); + + fn append_sigma_proof(&mut self, sigma_proof: &A); + + fn append_f_j_commitments(&mut self, f_j_commitments: &A); + + fn append_h_commitment(&mut self, commitment: &A); + + fn challenges_for_quotient_polynomials(&mut self, ell: usize) -> Vec; + + fn challenges_for_linear_combination(&mut self, ell: usize) -> Vec; + + fn challenge_from_verifier(&mut self) -> E::ScalarField; +} + +#[allow(private_bounds)] +pub trait SigmaProtocol: ScalarProtocol { + /// Append the "context" of a sigma protocol, e.g. session identifiers + fn append_sigma_protocol_ctxt(&mut self, ctxt: &C); + + /// Append the MSM bases of a sigma protocol. + fn append_sigma_protocol_msm_bases(&mut self, hom: &H); + + /// Append the claim of a sigma protocol. + fn append_sigma_protocol_public_statement(&mut self, public_statement: &H::Codomain); + + /// Append the first message (the commitment) in a sigma protocol. + fn append_sigma_protocol_first_prover_message(&mut self, prover_first_message: &H::Codomain); + + // Returns a single scalar `r` for use in a Sigma protocol + fn challenge_for_sigma_protocol(&mut self) -> E::ScalarField; +} + +#[allow(non_snake_case)] +impl> RangeProof for merlin::Transcript { + fn append_sep(&mut self, dst: &[u8]) { + self.append_message(b"dom-sep", dst); + } + + fn append_vk(&mut self, vk: &B::VerificationKey) { + let mut vk_bytes = Vec::new(); + vk.serialize_compressed(&mut vk_bytes) + .expect("vk serialization should succeed"); + self.append_message(b"vk", vk_bytes.as_slice()); + } + + fn append_public_statement(&mut self, public_statement: B::PublicStatement) { + let mut public_statement_bytes = Vec::new(); + public_statement + .serialize_compressed(&mut public_statement_bytes) + .expect("public_statement0 serialization should succeed"); + self.append_message(b"public-statements", public_statement_bytes.as_slice()); + } + + fn append_hat_f_commitment(&mut self, commitment: &A) { + let mut commitment_bytes = Vec::new(); + commitment + .serialize_compressed(&mut commitment_bytes) + .expect("hat_f_commitment serialization should succeed"); + self.append_message(b"hat_f_commitment", commitment_bytes.as_slice()); + } + + fn append_sigma_proof(&mut self, sigma_proof: &A) { + let mut sigma_proof_bytes = Vec::new(); + sigma_proof + .serialize_compressed(&mut sigma_proof_bytes) + .expect("sigma proof serialization should succeed"); + self.append_message(b"sigma_proof_commitment", sigma_proof_bytes.as_slice()); + } + + fn append_f_j_commitments(&mut self, f_j_commitments: &A) { + let mut f_j_commitments_bytes = Vec::new(); + f_j_commitments + .serialize_compressed(&mut f_j_commitments_bytes) + .expect("f_j_commitments serialization should succeed"); + self.append_message(b"f_j_commitments", f_j_commitments_bytes.as_slice()); + } + + fn append_h_commitment(&mut self, commitment: &A) { + let mut commitment_bytes = Vec::new(); + commitment + .serialize_compressed(&mut commitment_bytes) + .expect("h_commitment serialization should succeed"); + self.append_message(b"h_commitment", commitment_bytes.as_slice()); + } + + fn challenges_for_quotient_polynomials(&mut self, ell: usize) -> Vec { + let challenges = >::challenge_128bit_scalars( + self, + b"challenge_for_quotient_polynomials", + ell + 1, + ); + + Scalar::::vec_into_inner(challenges) + } + + fn challenges_for_linear_combination(&mut self, num: usize) -> Vec { + let challenges = >::challenge_128bit_scalars( + self, + b"challenge_for_linear_combination", + num, + ); + + Scalar::::vec_into_inner(challenges) + } + + fn challenge_from_verifier(&mut self) -> E::ScalarField { + >::challenge_full_scalar( + self, + b"verifier_challenge_for_linear_combination", + ) + .0 + } +} + +impl SigmaProtocol + for merlin::Transcript +where + H::Domain: sigma_protocol::Witness, + H::Codomain: sigma_protocol::Statement, +{ + fn append_sigma_protocol_ctxt(&mut self, ctxt: &C) { + let ctxt_bytes = bcs::to_bytes(ctxt).expect("ctxt data serialization should succeed"); + self.append_message(b"aux", ctxt_bytes.as_slice()); + } + + fn append_sigma_protocol_msm_bases(&mut self, hom: &H) { + let mut hom_bytes = Vec::new(); + hom.serialize_compressed(&mut hom_bytes) + .expect("hom MSM bases serialization should succeed"); + self.append_message(b"hom-msm-bases", hom_bytes.as_slice()); + } + + fn append_sigma_protocol_public_statement(&mut self, public_statement: &H::Codomain) { + let mut public_statement_bytes = Vec::new(); + public_statement + .serialize_compressed(&mut public_statement_bytes) + .expect("public_statement serialization should succeed"); + self.append_message(b"sigma-protocol-claim", public_statement_bytes.as_slice()); + } + + fn append_sigma_protocol_first_prover_message(&mut self, prover_first_message: &H::Codomain) { + let mut prover_first_message_bytes = Vec::new(); + prover_first_message + .serialize_compressed(&mut prover_first_message_bytes) + .expect("sigma protocol first message serialization should succeed"); + self.append_message( + b"sigma-protocol-first-message", + prover_first_message_bytes.as_slice(), + ); + } + + fn challenge_for_sigma_protocol(&mut self) -> E::ScalarField { + >::challenge_full_scalar( + self, + b"challenge_sigma_protocol", + ) + .0 + } +} diff --git a/crates/aptos-dkg/src/lib.rs b/crates/aptos-dkg/src/lib.rs index b71dedc1ca7..5e71da33ea0 100644 --- a/crates/aptos-dkg/src/lib.rs +++ b/crates/aptos-dkg/src/lib.rs @@ -17,12 +17,109 @@ #![allow(clippy::to_string_in_format_args)] #![allow(clippy::borrow_interior_mutable_const)] -use crate::constants::SCALAR_FIELD_ORDER; -pub use constants::{G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_NUM_BYTES}; +use crate::pvss::{traits, Player}; +use aptos_crypto::arkworks::{ + random::{sample_field_element, UniformRand}, + shamir::{Reconstructable, ShamirThresholdConfig}, +}; +pub use aptos_crypto::{ + blstrs as algebra, + blstrs::{G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_NUM_BYTES}, +}; +use ark_ec::pairing::Pairing; +use ark_ff::{Fp, FpConfig}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use more_asserts::{assert_ge, assert_le}; +use rand::Rng; pub use utils::random::DST_RAND_CORE_HELL; -pub mod algebra; -pub mod constants; +pub mod dlog; +pub(crate) mod fiat_shamir; +pub mod pcs; pub mod pvss; +pub mod range_proofs; +pub mod sigma_protocol; pub mod utils; pub mod weighted_vuf; +use aptos_crypto::arkworks::shamir::ShamirShare; + +/// A wrapper around `E::ScalarField` to prevent overlapping trait implementations. +/// +/// Without this wrapper, implementing a trait both for `blstrs::Scalar` and for +/// `E::ScalarField` would cause conflicts. For example, Rust would reject: +/// - `impl for blstrs::Scalar` +/// - `impl for E::ScalarField` +/// +/// because some pairing engine `E` might (now or in the future) define +/// `E::ScalarField = blstrs::Scalar`. +/// +/// Similarly, this issue also arises with blanket implementations like: +/// `impl for Vec`, since `Vec` could itself be an +/// `E::ScalarField`. +#[repr(transparent)] +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Copy, Debug, PartialEq, Eq)] +pub struct Scalar(pub E::ScalarField); // TODO: Maybe this should be Scalar ?? (PrimeField is needed for ThresholdConfig below) + +impl Scalar { + /// Converts a `&[Scalar]` into a `&[E::ScalarField]`; could do this without copying + /// (and similarly for the other functions below) by using `#[repr(transparent)]` and + /// unsafe Rust, but we want to avoid that + pub fn slice_as_inner(slice: &[Self]) -> Vec + where + E::ScalarField: Clone, + { + slice.iter().map(|s| s.0.clone()).collect() + } + + /// Converts a `Vec>` into a `Vec` safely. + pub fn vec_into_inner(v: Vec) -> Vec { + v.into_iter().map(|s| s.0).collect() + } + + /// Converts a `Vec` into a `Vec>` safely. + pub fn vec_from_inner(v: Vec) -> Vec { + v.into_iter().map(Self).collect() + } + + /// Converts a `Vec>` into a `Vec>>` safely. + pub fn vecvec_from_inner(vv: Vec>) -> Vec> { + vv.into_iter().map(Self::vec_from_inner).collect() + } + + /// Converts a `&[E::ScalarField]` into a `Vec>` safely. + pub fn vec_from_inner_slice(slice: &[E::ScalarField]) -> Vec { + slice.iter().copied().map(Self).collect() + } +} + +impl UniformRand for Scalar { + fn rand(rng: &mut R) -> Self { + Scalar(sample_field_element(rng)) + } +} + +// TODO: maybe move the Reconstructable trait to the SecretSharingConfig in the PVSS trait, with associated Scalar equal to InputSecret +// then make the existing implementation of `fn reconstruct()` part of a trait... and then we can remove the trivial implementation below! +impl, E: Pairing>> + Reconstructable> for Scalar +{ + type ShareValue = Scalar; + + fn reconstruct( + sc: &ShamirThresholdConfig, + shares: &[ShamirShare], + ) -> anyhow::Result { + assert_ge!(shares.len(), sc.get_threshold()); + assert_le!(shares.len(), sc.get_total_num_players()); + + let shares_destructured: Vec<(Player, E::ScalarField)> = shares + .iter() + .map(|(player, scalar)| (*player, scalar.0)) + .collect(); + + Ok(Scalar(E::ScalarField::reconstruct( + &sc, + &shares_destructured, + )?)) + } +} diff --git a/crates/aptos-dkg/src/pcs/mod.rs b/crates/aptos-dkg/src/pcs/mod.rs new file mode 100644 index 00000000000..e9f4bdf64d2 --- /dev/null +++ b/crates/aptos-dkg/src/pcs/mod.rs @@ -0,0 +1,5 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod univariate_hiding_kzg; +pub mod univariate_kzg; diff --git a/crates/aptos-dkg/src/pcs/univariate_hiding_kzg.rs b/crates/aptos-dkg/src/pcs/univariate_hiding_kzg.rs new file mode 100644 index 00000000000..0eb9a86fa7c --- /dev/null +++ b/crates/aptos-dkg/src/pcs/univariate_hiding_kzg.rs @@ -0,0 +1,397 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + algebra::polynomials, + sigma_protocol, + sigma_protocol::{ + homomorphism, + homomorphism::{fixed_base_msms, fixed_base_msms::Trait as FixedBaseMsmsTrait, Trait}, + }, + Scalar, +}; +use anyhow::ensure; +#[allow(unused_imports)] // This is used but due to some bug it is not noticed by the compiler +use aptos_crypto::arkworks::random::UniformRand; +use aptos_crypto::{ + arkworks::{ + random::{sample_field_element, unsafe_random_point}, + GroupGenerators, + }, + utils, +}; +use aptos_crypto_derive::SigmaProtocolWitness; +use ark_ec::{ + pairing::{Pairing, PairingOutput}, + AdditiveGroup, CurveGroup, VariableBaseMSM, +}; +use ark_ff::Field; +use ark_poly::EvaluationDomain; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use rand::{CryptoRng, RngCore}; +use sigma_protocol::homomorphism::TrivialShape as CodomainShape; +use std::fmt::Debug; + +pub type Commitment = CodomainShape<::G1>; + +pub type CommitmentRandomness = Scalar; + +#[derive(CanonicalSerialize, CanonicalDeserialize, Debug, PartialEq, Eq, Clone)] +pub struct OpeningProof { + pub(crate) pi_1: Commitment, + pub(crate) pi_2: E::G1, +} + +impl OpeningProof { + /// Generates a random looking opening proof (but not a valid one). + /// Useful for testing and benchmarking. TODO: might be able to derive this through macros etc + pub fn generate(rng: &mut R) -> Self { + Self { + pi_1: sigma_protocol::homomorphism::TrivialShape(unsafe_random_point(rng)), + pi_2: unsafe_random_point(rng), + } + } +} + +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct VerificationKey { + pub xi_2: E::G2Affine, + pub tau_2: E::G2Affine, + pub group_generators: GroupGenerators, +} + +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct CommitmentKey { + pub xi_1: E::G1Affine, + pub tau_1: E::G1Affine, + pub lagr_g1: Vec, + pub eval_dom: ark_poly::Radix2EvaluationDomain, + pub roots_of_unity_in_eval_dom: Vec, + pub one_1: E::G1Affine, + pub m_inv: E::ScalarField, +} + +#[derive(CanonicalSerialize, Debug, Clone)] +pub struct Trapdoor { + // Not sure this is the ideal location for tau... + pub xi: E::ScalarField, + pub tau: E::ScalarField, +} + +impl Trapdoor { + pub fn rand(rng: &mut R) -> Self { + Self { + xi: sample_field_element(rng), + tau: sample_field_element(rng), + } + } +} + +pub fn lagrange_basis( + n: usize, + g1: E::G1Affine, + eval_dom: ark_poly::Radix2EvaluationDomain, + tau: E::ScalarField, +) -> Vec { + let powers_of_tau = utils::powers(tau, n); + let lagr_basis_scalars = eval_dom.ifft(&powers_of_tau); + debug_assert!(lagr_basis_scalars.iter().sum::() == E::ScalarField::ONE); + + let lagr_g1_proj: Vec = lagr_basis_scalars.iter().map(|s| g1 * s).collect(); + E::G1::normalize_batch(&lagr_g1_proj) +} + +pub fn setup( + m: usize, + group_generators: GroupGenerators, + trapdoor: Trapdoor, + _rng: &mut R, +) -> (VerificationKey, CommitmentKey) { + assert!( + m.is_power_of_two(), + "Parameter m must be a power of 2, but got {}", + m + ); + + let GroupGenerators { + g1: one_1, + g2: one_2, + } = group_generators; + let Trapdoor { xi, tau } = trapdoor; + + let xi_1 = (one_1 * xi).into_affine(); + let tau_1 = (one_1 * tau).into_affine(); + + let xi_2 = (one_2 * xi).into_affine(); + let tau_2 = (one_2 * tau).into_affine(); + + let eval_dom = ark_poly::Radix2EvaluationDomain::::new(m) + .expect("Could not construct evaluation domain"); + let lagr_g1 = lagrange_basis::(m, one_1, eval_dom, tau); + let roots_of_unity_in_eval_dom: Vec = eval_dom.elements().collect(); + + let m_inv = E::ScalarField::from(m as u64).inverse().unwrap(); + + ( + VerificationKey { + xi_2, + tau_2, + group_generators, + }, + CommitmentKey { + xi_1, + tau_1, + lagr_g1, + eval_dom, + roots_of_unity_in_eval_dom, + one_1, + m_inv, + }, + ) +} + +pub fn commit_with_randomness( + ck: &CommitmentKey, + values: &[E::ScalarField], + r: &CommitmentRandomness, +) -> Commitment { + let commitment_hom: CommitmentHomomorphism<'_, E> = CommitmentHomomorphism { + lagr_g1: &ck.lagr_g1, + xi_1: ck.xi_1, + }; + + let input = Witness { + hiding_randomness: r.clone(), + values: Scalar::vec_from_inner_slice(values), + }; + + commitment_hom.apply(&input) +} + +impl<'a, E: Pairing> CommitmentHomomorphism<'a, E> { + pub fn open( + ck: &CommitmentKey, + f_evals: Vec, + rho: E::ScalarField, + x: E::ScalarField, + y: E::ScalarField, + s: &CommitmentRandomness, + ) -> OpeningProof { + if ck.roots_of_unity_in_eval_dom.contains(&x) { + panic!("x is not allowed to be a root of unity"); + } + let q_evals = + polynomials::quotient_evaluations_batch(&f_evals, &ck.roots_of_unity_in_eval_dom, x, y); + + let pi_1 = commit_with_randomness(ck, &q_evals, s); + + // For this small MSM, the direct approach seems to be faster than using `E::G1::msm()` + let pi_2 = (ck.one_1 * rho) - (ck.tau_1 - ck.one_1 * x) * s.0; + + OpeningProof { pi_1, pi_2 } + } + + #[allow(non_snake_case)] + pub fn verify( + vk: VerificationKey, + C: Commitment, + x: E::ScalarField, + y: E::ScalarField, + pi: OpeningProof, + ) -> anyhow::Result<()> { + let VerificationKey { + xi_2, + tau_2, + group_generators: + GroupGenerators { + g1: one_1, + g2: one_2, + }, + } = vk; + let OpeningProof { pi_1, pi_2 } = pi; + + let check = E::multi_pairing(vec![C.0 - one_1 * y, -pi_1.0, -pi_2], vec![ + one_2, + (tau_2 - one_2 * x).into_affine(), + xi_2, + ]); + ensure!( + PairingOutput::::ZERO == check, + "Hiding KZG verification failed" + ); + + Ok(()) + } +} + +/// A fixed-base homomorphism used for computing commitments in the +/// *Hiding KZG (HKZG)* commitment scheme. +/// +/// # Overview +/// +/// This struct defines a homomorphism used to map scalars +/// (the polynomial evaluations and blinding factor) into an elliptic curve point, +/// producing a commitment in the HKZG scheme as (presumably) described in Zeromorph [^KT23e]. +/// +/// The homomorphism implements the following formula: +/// +/// \\[ +/// C = \rho \cdot \xi_1 + \sum_i f(\theta^i) \cdot \ell_i(\tau)_1 +/// \\] +/// +/// where: +/// - `ρ` is the blinding scalar, +/// - `ξ₁` is the fixed base obtained from a trapdoor `ξ`, +/// - `f(ωᵢ)` are polynomial evaluations at roots of unity ωᵢ, +/// - `ℓᵢ(τ)₁` are the Lagrange basis polynomials evaluated at trapdoor `τ`, +/// +/// This homomorphism can be expressed as a *multi-scalar multiplication (MSM)* +/// over fixed bases, making it compatible with the `fixed_base_msms` framework. +/// +/// +/// # Fields +/// +/// - `lagr_g1`: A slice of precomputed Lagrange basis elements \\(\ell_i(\tau) \cdot g_1\\), +/// used to commit to polynomial evaluations. +/// - `xi_1`: The base point corresponding to the blinding term \\(\xi_1 = ξ \cdot g_1\\). +/// +/// +/// # Implementation Notes +/// +/// For consistency with `univariate_kzg.rs` and use in future sigma protocols, this implementation uses the +/// `fixed_base_msms::Trait` to express the homomorphism as a sequence of `(base, scalar)` pairs: +/// - The first pair encodes the hiding term `(ξ₁, ρ)`. +/// - The remaining pairs encode the polynomial evaluation commitments `(ℓᵢ(τ)₁, f(ωᵢ))`. +/// +/// The MSM evaluation is then performed using `E::G1::msm()`. +/// +/// TODO: Since this code is quite similar to that of ordinary KZG, it may be possible to reduce it a bit +#[derive(CanonicalSerialize, Debug, Clone, PartialEq, Eq)] +pub struct CommitmentHomomorphism<'a, E: Pairing> { + pub lagr_g1: &'a [E::G1Affine], + pub xi_1: E::G1Affine, +} + +#[derive( + SigmaProtocolWitness, CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq, +)] +pub struct Witness { + pub hiding_randomness: CommitmentRandomness, + pub values: Vec>, +} + +impl homomorphism::Trait for CommitmentHomomorphism<'_, E> { + type Codomain = CodomainShape; + type Domain = Witness; + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + self.apply_msm(self.msm_terms(input)) + } +} + +impl fixed_base_msms::Trait for CommitmentHomomorphism<'_, E> { + type Base = E::G1Affine; + type CodomainShape + = CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = fixed_base_msms::MsmInput; + type MsmOutput = E::G1; + type Scalar = E::ScalarField; + + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + assert!( + self.lagr_g1.len() >= input.values.len(), + "Not enough Lagrange basis elements for univariate hiding KZG: required {}, got {}", + input.values.len(), + self.lagr_g1.len() + ); + + let mut scalars = Vec::with_capacity(input.values.len() + 1); + scalars.push(input.hiding_randomness.0); + scalars.extend(input.values.iter().map(|s| s.0.clone())); + + let mut bases = Vec::with_capacity(input.values.len() + 1); + bases.push(self.xi_1); + bases.extend(&self.lagr_g1[..input.values.len()]); + + CodomainShape(fixed_base_msms::MsmInput { bases, scalars }) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + E::G1::msm(bases, &scalars).expect("MSM computation failed in univariate KZG") + } +} + +impl<'a, E: Pairing> sigma_protocol::Trait for CommitmentHomomorphism<'a, E> { + fn dst(&self) -> Vec { + b"APTOS_HIDING_KZG_SIGMA_PROTOCOL_DST".to_vec() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use aptos_crypto::arkworks::random::{sample_field_element, sample_field_elements}; + use ark_ec::pairing::Pairing; + use ark_poly::{univariate::DensePolynomial, Polynomial}; + use rand::thread_rng; + + // TODO: Should set up a PCS trait, then make these tests generic? + fn assert_kzg_opening_correctness() { + let mut rng = thread_rng(); + let group_data = GroupGenerators::default(); + + type Fr = ::ScalarField; + + let m = 64; + let xi = sample_field_element(&mut rng); + let tau = sample_field_element(&mut rng); + let (vk, ck) = setup::(m, group_data, Trapdoor { xi, tau }, &mut rng); + + let f_coeffs: Vec> = sample_field_elements(m, &mut rng); + let poly = DensePolynomial::> { coeffs: f_coeffs }; + + // Polynomial values at the roots of unity + let f_evals: Vec> = ck + .roots_of_unity_in_eval_dom + .iter() + .map(|&gamma| poly.evaluate(&gamma)) + .collect(); + + let rho = CommitmentRandomness::rand(&mut rng); + let s = CommitmentRandomness::rand(&mut rng); + let x = sample_field_element(&mut rng); + let y = + polynomials::barycentric_eval(&f_evals, &ck.roots_of_unity_in_eval_dom, x, ck.m_inv); + + // Commit to f + let comm = super::commit_with_randomness(&ck, &f_evals, &rho); + + // Open at x, will fail when x is a root of unity but the odds of that should be negligible + let proof = CommitmentHomomorphism::::open(&ck, f_evals, rho.0, x, y, &s); + + // Verify proof + let verification = CommitmentHomomorphism::::verify(vk, comm, x, y, proof); + + assert!( + verification.is_ok(), + "Verification should succeed for correct proof" + ); + } + + macro_rules! kzg_roundtrip_test { + ($name:ident, $curve:ty) => { + #[test] + fn $name() { + assert_kzg_opening_correctness::<$curve>(); + } + }; + } + + kzg_roundtrip_test!(assert_kzg_opening_correctness_for_bn254, ark_bn254::Bn254); + kzg_roundtrip_test!( + assert_kzg_opening_correctness_for_bls12_381, + ark_bls12_381::Bls12_381 + ); +} diff --git a/crates/aptos-dkg/src/pcs/univariate_kzg.rs b/crates/aptos-dkg/src/pcs/univariate_kzg.rs new file mode 100644 index 00000000000..03177a12133 --- /dev/null +++ b/crates/aptos-dkg/src/pcs/univariate_kzg.rs @@ -0,0 +1,68 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::sigma_protocol::{ + homomorphism, + homomorphism::{fixed_base_msms, fixed_base_msms::Trait, TrivialShape as CodomainShape}, +}; +use ark_ec::{pairing::Pairing, VariableBaseMSM}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use std::fmt::Debug; + +/// Homomorphism for univariate KZG commitments using a Lagrange basis. +/// +/// # Description +/// - Maps values (domain), combined with randomness, to a G1 group element (codomain). +/// - Input domain: +/// - `E::ScalarField`: blinding factor, thought of as f(omega^0) +/// - `Vec`: the remaining values, which will correspond to f(omega^i) for i > 0 +/// - Uses `lagr_g1` because the input represents **evaluations**, not coefficients. +/// +/// For the sake of modularity, we might refactor this in the future to have this homomorphism feed into a homomorphism whose input are only values (by concatenating the inputs into one Vec). +#[derive(CanonicalSerialize)] +pub struct Homomorphism<'a, E: Pairing> { + pub lagr_g1: &'a [E::G1Affine], +} + +impl<'a, E: Pairing> homomorphism::Trait for Homomorphism<'a, E> { + type Codomain = CodomainShape; + /// Input domain: (blinding factor, remaining values) + type Domain = (E::ScalarField, Vec); + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + self.apply_msm(self.msm_terms(input)) + } +} + +impl<'a, E: Pairing> fixed_base_msms::Trait for Homomorphism<'a, E> { + type Base = E::G1Affine; + type CodomainShape + = CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = fixed_base_msms::MsmInput; + type MsmOutput = E::G1; + type Scalar = E::ScalarField; + + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + debug_assert!( + self.lagr_g1.len() > input.1.len(), + "Not enough Lagrange basis elements for univariate KZG: required {}, got {}", + input.1.len() + 1, + self.lagr_g1.len() + ); + + let mut scalars = Vec::with_capacity(input.1.len() + 1); + scalars.push(input.0); + scalars.extend_from_slice(&input.1); + + CodomainShape(fixed_base_msms::MsmInput { + bases: self.lagr_g1[..1 + input.1.len()].to_vec(), + scalars, + }) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + E::G1::msm(bases, &scalars).expect("MSM failed in univariate KZG") + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/chunked_elgamal.rs b/crates/aptos-dkg/src/pvss/chunky/chunked_elgamal.rs new file mode 100644 index 00000000000..4e532042cff --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/chunked_elgamal.rs @@ -0,0 +1,394 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + sigma_protocol, + sigma_protocol::homomorphism::{self, fixed_base_msms, fixed_base_msms::Trait, EntrywiseMap}, + Scalar, +}; +use aptos_crypto::arkworks::{hashing, random::sample_field_element}; +use aptos_crypto_derive::SigmaProtocolWitness; +use ark_ec::{pairing::Pairing, VariableBaseMSM}; +use ark_ff::PrimeField; +use ark_serialize::{ + CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Write, +}; +use ark_std::fmt::Debug; + +pub const DST: &[u8; 35] = b"APTOS_CHUNKED_ELGAMAL_GENERATOR_DST"; // This is used to create public parameters, see `default()` below + +// TODO: Change this to PublicParameters. Would first require changing Scalar to Scalar, which would be a bit of work +#[derive(CanonicalSerialize, CanonicalDeserialize, PartialEq, Clone, Eq, Debug)] +#[allow(non_snake_case)] +pub struct PublicParameters { + /// A group element $G$ that is raised to the encrypted message + pub G: E::G1Affine, + /// A group element $H$ that is used to exponentiate both + /// (1) the ciphertext randomness and (2) the DSK when computing its EK. + pub H: E::G1Affine, +} + +#[allow(non_snake_case)] +impl PublicParameters { + pub fn new(G: E::G1Affine, H: E::G1Affine) -> Self { + Self { G, H } + } + + pub fn message_base(&self) -> &E::G1Affine { + &self.G + } + + pub fn pubkey_base(&self) -> &E::G1Affine { + &self.H + } + + pub fn default() -> Self { + let G = hashing::unsafe_hash_to_affine(b"G", DST); + let H = hashing::unsafe_hash_to_affine(b"H", DST); + debug_assert_ne!(G, H); + Self { G, H } + } +} + +/// Formally, given: +/// - `G_1, H_1` ∈ G₁ (group generators) +/// - `ek_i` ∈ G₁ (encryption keys) +/// - `z_i,j` ∈ Scalar (plaintext scalars z_i, chunked into z_i,j) +/// - `r_j` ∈ Scalar (randomness for each `column` of chunks z_i,j) +/// +/// The homomorphism maps input `[z_i,j]` and randomness `[r_j]` to +/// the following codomain elements: +/// +/// ```text +/// C_i,j = G_1 * z_i,j + ek_i * r_j +/// R_j = H_1 * r_j +/// ``` +/// +/// The `C_i,j` represent "chunked" homomorphic encryptions of the plaintexts, +/// and `R_j` carry the corresponding randomness contributions. +#[derive(Debug, Clone, PartialEq, Eq)] +#[allow(non_snake_case)] +pub struct Homomorphism<'a, E: Pairing> { + pub pp: &'a PublicParameters, // This is small so could clone it here, then no custom `CanonicalSerialize` is needed + pub eks: &'a [E::G1Affine], +} + +// Need to manually implement `CanonicalSerialize` because `Homomorphism` has references instead of owned values +impl<'a, E: Pairing> CanonicalSerialize for Homomorphism<'a, E> { + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.pp.G.serialize_with_mode(&mut writer, compress)?; + self.pp.H.serialize_with_mode(&mut writer, compress)?; + for ek in self.eks { + ek.serialize_with_mode(&mut writer, compress)?; + } + Ok(()) + } + + fn serialized_size(&self, compress: Compress) -> usize { + self.pp.G.serialized_size(compress) + + self.pp.H.serialized_size(compress) + + self + .eks + .iter() + .map(|ek| ek.serialized_size(compress)) + .sum::() + } +} + +/// This struct is used as `CodomainShape`, but the same layout also applies to the `Witness` type. +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct CodomainShape { + pub chunks: Vec>, // Depending on T these can be chunked ciphertexts, or their MSM representations + pub randomness: Vec, // Same story, depending on T +} + +// Witness shape happens to be identical to CodomainShape, this is mostly coincidental +// Setting `type Witness = CodomainShape>` would later require deriving SigmaProtocolWitness for CodomainShape +// (and would be overkill anyway), but this leads to issues as it expects T to be a Pairing, so we'll simply redefine it: +#[derive( + SigmaProtocolWitness, CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq, +)] +pub struct Witness { + pub plaintext_chunks: Vec>>, + pub plaintext_randomness: Vec>, +} + +impl homomorphism::Trait for Homomorphism<'_, E> { + type Codomain = CodomainShape; + type Domain = Witness; + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + self.apply_msm(self.msm_terms(input)) + } +} + +// TODO: Can problably do EntrywiseMap with another derive macro +impl EntrywiseMap + for CodomainShape +{ + type Output = + CodomainShape; + + fn map(self, f: F) -> Self::Output + where + F: Fn(T) -> U, + U: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq, + { + let chunks = self + .chunks + .into_iter() + .map(|row| row.into_iter().map(&f).collect()) + .collect(); + + let randomness = self.randomness.into_iter().map(f).collect(); + + CodomainShape { chunks, randomness } + } +} + +// TODO: Use a derive macro? +impl IntoIterator for CodomainShape { + type IntoIter = std::vec::IntoIter; + type Item = T; + + fn into_iter(self) -> Self::IntoIter { + let mut combined: Vec = self.chunks.into_iter().flatten().collect(); // Temporary Vec can probably be avoided, but might require unstable Rust or a lot of lines + combined.extend(self.randomness); + combined.into_iter() + } +} + +#[allow(non_snake_case)] +impl<'a, E: Pairing> fixed_base_msms::Trait for Homomorphism<'a, E> { + type Base = E::G1Affine; + type CodomainShape + = CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = fixed_base_msms::MsmInput; + type MsmOutput = E::G1; + type Scalar = E::ScalarField; + + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + // C_{i,j} = z_{i,j} * G_1 + r_j * ek[i] + let Cs = input + .plaintext_chunks + .iter() + .enumerate() + .map(|(i, z_i)| { + z_i.iter() + .zip(input.plaintext_randomness.iter()) + .map(|(&z_ij, &r_j)| fixed_base_msms::MsmInput { + bases: vec![self.pp.G, self.eks[i]], + scalars: vec![z_ij.0, r_j.0], + }) + .collect() + }) + .collect(); + + // R_j = r_j * H_1 + let Rs = input + .plaintext_randomness + .iter() + .map(|&r_j| fixed_base_msms::MsmInput { + bases: vec![self.pp.H], + scalars: vec![r_j.0], + }) + .collect(); + + CodomainShape { + chunks: Cs, + randomness: Rs, + } + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + E::G1::msm(bases, scalars).expect("MSM failed in ChunkedElgamal") + } +} + +impl<'a, E: Pairing> sigma_protocol::Trait for Homomorphism<'a, E> { + fn dst(&self) -> Vec { + b"APTOS_CHUNKED_ELGAMAL_SIGMA_PROTOCOL_DST".to_vec() + } +} + +pub(crate) fn correlated_randomness(rng: &mut R, radix: u64, num_chunks: u32) -> Vec +where + F: ark_ff::PrimeField, + R: rand_core::RngCore + rand_core::CryptoRng, +{ + let mut r_vals = Vec::with_capacity(num_chunks as usize); + r_vals.push(F::zero()); // placeholder for r_0 + let mut remainder = F::zero(); + + // Precompute radix as F once + let radix_f = F::from(radix); + let mut cur_base = radix_f; + + // Fill r_1 .. r_{num_chunks-1} randomly + for _ in 1..num_chunks { + let r = sample_field_element(rng); + r_vals.push(r); + remainder -= r * cur_base; + cur_base *= radix_f; + } + + r_vals[0] = remainder; + + r_vals +} + +pub(crate) fn num_chunks_per_scalar(ell: u8) -> u32 { + E::ScalarField::MODULUS_BIT_SIZE.div_ceil(ell as u32) // Maybe add `as usize` here? +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{dlog, dlog::bsgs, pvss::chunky::chunks, sigma_protocol::homomorphism::Trait as _}; + use aptos_crypto::{ + arkworks::random::{sample_field_elements, unsafe_random_points}, + utils, + }; + use ark_ec::{AffineRepr, CurveGroup}; + use rand::thread_rng; + use std::ops::Sub; + + fn prepare_chunked_witness( + num_values: usize, + ell: u8, + ) -> (Vec, Witness, u8, u32) { + let mut rng = thread_rng(); + + // 1. Generate random values + let zs = sample_field_elements(num_values, &mut rng); + + // 2. Compute number of chunks + let number_of_chunks = num_chunks_per_scalar::(ell); + + // 3. Generate correlated randomness + let rs: Vec = correlated_randomness(&mut rng, 1 << ell, number_of_chunks); + + // 4. Convert values into little-endian chunks + let chunked_values: Vec> = zs + .iter() + .map(|z| chunks::scalar_to_le_chunks(ell, z)) + .collect(); + + // 5. Build witness + let witness = Witness { + plaintext_chunks: Scalar::::vecvec_from_inner(chunked_values), + plaintext_randomness: Scalar::vec_from_inner(rs), + }; + + (zs, witness, ell, number_of_chunks) + } + + #[allow(non_snake_case)] + fn test_reconstruct_ciphertexts() { + let (zs, witness, radix_exponent, _num_chunks) = prepare_chunked_witness::(2, 16); + + // 6. Initialize the homomorphism + let pp = PublicParameters::default(); + + let hom = Homomorphism { + pp: &pp, + eks: &E::G1::normalize_batch(&unsafe_random_points(2, &mut thread_rng())), // Randomly generate encryption keys, we won't use them + }; + + // 7. Apply homomorphism to obtain chunked ciphertexts + let CodomainShape { chunks: Cs, .. } = hom.apply(&witness); + + // 8. Reconstruct original values from the chunked ciphertexts + for (i, &orig_val) in zs.iter().enumerate() { + let powers_of_radix: Vec = + utils::powers(E::ScalarField::from(1u64 << radix_exponent), Cs[i].len()); + + // perform the MSM to reconstruct the encryption of z_i + let reconstructed = E::G1::msm(&E::G1::normalize_batch(&Cs[i]), &powers_of_radix) + .expect("MSM reconstruction failed"); + + let expected = *pp.message_base() * orig_val; + assert_eq!( + reconstructed, expected, + "Reconstructed value {} does not match original", + i + ); + } + } + + // This is essentially a more advanced version of the previous test... so remove that one? + #[allow(non_snake_case)] + fn test_decrypt_roundtrip() { + let (zs, witness, radix_exponent, _num_chunks) = prepare_chunked_witness::(2, 16); + + // 6. Initialize the homomorphism + let pp = PublicParameters::default(); + let dks: Vec = sample_field_elements(2, &mut thread_rng()); + + let hom = Homomorphism { + pp: &pp, + eks: &E::G1::normalize_batch(&[pp.H * dks[0], pp.H * dks[1]]), + }; + + // 7. Apply homomorphism to obtain chunked ciphertexts + let CodomainShape { + chunks: Cs, + randomness: Rs, + } = hom.apply(&witness); + + // 8. Build a baby-step giant-step table for computing discrete logs + let table = dlog::table::build::(pp.G.into(), 1u32 << (radix_exponent / 2)); + + // 9. Perform decryption of each ciphertext and reconstruct plaintexts + let mut decrypted_scalars = Vec::new(); + for i in 0..2 { + // Compute C - d_k * R for all chunks + let exponentiated_chunks: Vec = Cs[i] + .iter() + .zip(Rs.iter()) + .map(|(C_ij, &R_j)| C_ij.sub(R_j * dks[i])) + .collect(); + + // Recover plaintext chunk values + let chunks: Vec<_> = bsgs::dlog_vec( + pp.G.into_group(), + &exponentiated_chunks, + &table, + 1 << radix_exponent, + ) + .expect("dlog_vec failed") + .into_iter() + .map(|x| E::ScalarField::from(x)) + .collect(); + + // Convert chunks back to scalar + let recovered = chunks::le_chunks_to_scalar(radix_exponent, &chunks); + decrypted_scalars.push(recovered); + } + + // 10. Compare decrypted scalars to original plaintexts + for (i, (orig, recovered)) in zs.iter().zip(decrypted_scalars.iter()).enumerate() { + assert_eq!( + orig, recovered, + "Decrypted plaintext {} does not match original", + i + ); + } + } + + #[test] + fn test_reconstruct_ciphertexts_bn254() { + test_reconstruct_ciphertexts::(); + } + + #[test] + fn test_decrypt_roundtrip_bn254() { + test_decrypt_roundtrip::(); + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/chunks.rs b/crates/aptos-dkg/src/pvss/chunky/chunks.rs new file mode 100644 index 00000000000..018d056ae2c --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/chunks.rs @@ -0,0 +1,76 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use ark_ff::{BigInteger, PrimeField}; + +/// Converts a field element into little-endian chunks of `num_bits` bits. +pub(crate) fn scalar_to_le_chunks(num_bits: u8, scalar: &F) -> Vec { + assert!( + num_bits.is_multiple_of(8) && num_bits > 0 && num_bits <= 64, + "Invalid chunk size" + ); + + let bytes = scalar.into_bigint().to_bytes_le(); + let num_bytes = num_bits / 8; + let num_chunks = bytes.len().div_ceil(num_bytes as usize); + + let mut chunks = Vec::with_capacity(num_chunks); + + for bytes_chunk in bytes.chunks(num_bytes as usize) { + let mut padded = [0u8; 8]; // The last chunk might be shorter, so this guarantee a fixed 8-byte buffer + padded[..bytes_chunk.len()].copy_from_slice(bytes_chunk); + + let chunk_val = u64::from_le_bytes(padded); + let chunk = F::from(chunk_val); + chunks.push(chunk); + } + + chunks +} + +/// Reconstructs a field element from `num_bits`-bit chunks (little-endian order). +pub(crate) fn le_chunks_to_scalar(num_bits: u8, chunks: &[F]) -> F { + assert!( + num_bits.is_multiple_of(8) && num_bits > 0 && num_bits <= 64, // TODO: so make num_bits a u8? + "Invalid chunk size" + ); + + let base = F::from(1u128 << num_bits); // need u128 in the case where `num_bits` is 64, because of `chunk * multiplier` + let mut acc = F::zero(); + let mut multiplier = F::one(); + + for &chunk in chunks { + acc += chunk * multiplier; + multiplier *= base; + } + + acc +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_bls12_381::Fr; + use ark_ff::UniformRand; + use ark_std::test_rng; + + #[test] + fn test_chunk_unchunk_roundtrip() { + let mut rng = test_rng(); + let num_bits_list = [8, 16, 32, 64]; + + for &num_bits in &num_bits_list { + for _ in 0..100 { + let original: Fr = Fr::rand(&mut rng); + let chunks = scalar_to_le_chunks(num_bits, &original); + let reconstructed = le_chunks_to_scalar(num_bits, &chunks); + + assert_eq!( + original, reconstructed, + "Roundtrip failed for num_bits={}", + num_bits + ); + } + } + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/hkzg_chunked_elgamal.rs b/crates/aptos-dkg/src/pvss/chunky/hkzg_chunked_elgamal.rs new file mode 100644 index 00000000000..bcf473679e9 --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/hkzg_chunked_elgamal.rs @@ -0,0 +1,195 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + pcs::univariate_hiding_kzg, + pvss::chunky::chunked_elgamal, + sigma_protocol::{ + self, + homomorphism::{ + tuple::{TupleCodomainShape, TupleHomomorphism}, + LiftHomomorphism, TrivialShape, + }, + traits::FirstProofItem, + }, + Scalar, +}; +use aptos_crypto::arkworks::random::{sample_field_element, unsafe_random_point, UniformRand}; +use aptos_crypto_derive::SigmaProtocolWitness; +use ark_ec::{pairing::Pairing, AdditiveGroup}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; + +/// Witness data for the `chunked_elgamal_field` PVSS protocol. +/// +/// In this PVSS scheme, plaintexts (which are shares) are first divided into chunks. Then +/// two more (independent) pieces of data are generated: +/// +/// - **HKZG randomness** is generated and used in the DeKARTv2 range proof, +/// to prove that the chunks lie in the correct range. +/// - **ElGamal randomness** is generated and used to encrypt the chunks. +/// +/// To prove consistency between these components, we thus construct a Σ-protocol +/// defined over a domain that jointly includes: +/// - the HKZG randomness, +/// - the chunked plaintexts, and +/// - the ElGamal randomness. +#[derive( + SigmaProtocolWitness, CanonicalSerialize, CanonicalDeserialize, Debug, Clone, PartialEq, Eq, +)] +pub struct HkzgElgamalWitness { + pub hkzg_randomness: univariate_hiding_kzg::CommitmentRandomness, + pub chunked_plaintexts: Vec>>, + pub elgamal_randomness: Vec>, +} + +/// The two components described earlier — (1) generating HKZG randomness for the DeKARTv2 proof +/// and (2) encrypting with ElGamal randomness — are part of a single Σ-protocol +/// proving knowledge of a *preimage* under a tuple homomorphism, consisting of: +/// +/// (i) the HKZG commitment homomorphism, and +/// (ii) the `chunked_elgamal` homomorphism. +/// +/// On the domain side, each of the two parts of this tuple homomorphism corresponds to one of the +/// two components: in each case, the witness omits (or “ignores”) one of its three fields, then applies +/// a homomorphism. Thus, the overall homomorphism of the Σ-protocol can be viewed as a tuple of two +/// *lifted* homomorphisms. +type LiftedHkzg<'a, E> = + LiftHomomorphism, HkzgElgamalWitness>; +type LiftedChunkedElgamal<'a, E> = + LiftHomomorphism, HkzgElgamalWitness>; + +// ┌───────────────────────────────┐ +// │ HkzgElgamalWitness │ +// │-------------------------------│ +// │ hkzg_randomness │ +// │ chunked_plaintexts │ +// │ elgamal_randomness │ +// └───────────────┬───────────────┘ +// │ +// ┌────────────────────────────────┬─╫─┬──────────────────────────┐ +// │ ║ ╫ ║ │ +// projection_1 │ lifted HKZG hom ╔══════╝ ╫ ╚══════╗ lifted Chunked │ projection_2 +// │ ║ ╫ ║ ElGamal hom │ +// ▼ ║ ╫ ║ ▼ +// ┌───────────────────────────────────┐ ║ ╫ ║ ┌──────────────────────────────┐ +// │ univariate_hiding_kzg::Witness │ ║ ╫ ║ │ chunked_elgamal:: Witness │ +// │-----------------------------------│ ║ ╫ ║ │------------------------------│ +// │ hkzg_randomness │ ║ ╫ ║ │ chunked_plaintexts │ +// │ flattened_chunked_plaintexts │ ║ ╫ ║ │ elgamal_randomness │ +// └──────────────┬────────────────────┘ ║ ╫ ║ └──────────────┬───────────────┘ +// │ ╔════════════════════╝ ╫ ╚═══════════════╗ │ +// HKZG hom │ ║ ╫ ║ │ Chunked ElGamal hom +// │ ║ ╫ TupleHomomorphism ║ │ +// ▼ ▼ ╫ ▼ ▼ +// ┌──────────────────────────┐ ╫ ┌──────────────────────────┐ +// │ HKZG output (commitment) │ ╫ │ Chunked ElGamal output │ +// └──────────────┬───────────┘ ╫ └──────────────┬───────────┘ +// │ ╫ │ +// └─────────────────────────────►╫◄───────────────────────┘ +// ╫ +// ▼ +// ┌──────────────────────────────────┐ +// │ TupleHomomorphism output │ +// │ (pair of HKZG image and │ +// │ Chunked ElGamal image) │ +// └──────────────────────────────────┘ +// +// +// In other words, the tuple homomorphism is roughly given as follows: +// +// ( rho, z_{i,j} , r_j ) │----> ( HKZG(rho, (0, z_{i,j}) ) , chunked_elgamal( z_{i,j} , r_j ) +// = ( +// \rho [\xi]_1 + \sum_i,j z_i,j [\ell_{i * B + j + 1}(\tau)]_1, +// ( z_i,j G_1 + r_j ek_i )_i,j, +// ( r_j H_1 )_j, +// ) +// where B denotes the number of chunks. +// +// TODO: note here that we had to put a zero before z_{i,j}, because that's what DeKARTv2 is doing. So maybe +// it would make more sense to say this is a tuple homomorphism consisting of (lifts of) the +// DeKARTv2::commitment_homomorphism together with the chunked_elgamal::homomorphism. +pub type Homomorphism<'a, E> = TupleHomomorphism, LiftedChunkedElgamal<'a, E>>; + +pub type Proof<'a, E> = sigma_protocol::Proof>; + +impl<'a, E: Pairing> Proof<'a, E> { + /// Generates a random looking proof (but not a valid one). + /// Useful for testing and benchmarking. + pub fn generate( + n: usize, + number_of_chunks: usize, + rng: &mut R, + ) -> Self { + // or should number_of_chunks be a const? + Self { + first_proof_item: FirstProofItem::Commitment(TupleCodomainShape( + TrivialShape(unsafe_random_point(rng)), // because TrivialShape is the codomain of univariate_hiding_kzg::CommitmentHomomorphism. TODO: develop generate() methods there? Maybe make it part of sigma_protocol::Trait ? + chunked_elgamal::CodomainShape { + chunks: vec![vec![unsafe_random_point(rng); number_of_chunks]; n], + randomness: vec![unsafe_random_point(rng); number_of_chunks], + }, + )), + z: HkzgElgamalWitness { + hkzg_randomness: univariate_hiding_kzg::CommitmentRandomness::::rand(rng), + chunked_plaintexts: vec![ + vec![Scalar(sample_field_element(rng)); number_of_chunks]; + n + ], + elgamal_randomness: vec![Scalar(sample_field_element(rng)); number_of_chunks], + }, + } + } +} + +#[allow(non_snake_case)] +impl<'a, E: Pairing> Homomorphism<'a, E> { + pub fn new( + lagr_g1: &'a [E::G1Affine], + xi_1: E::G1Affine, + pp: &'a chunked_elgamal::PublicParameters, + eks: &'a [E::G1Affine], + ) -> Self { + // Set up the HKZG homomorphism, and use a projection map to lift it to HkzgElgamalWitness + let lifted_hkzg = LiftedHkzg:: { + hom: univariate_hiding_kzg::CommitmentHomomorphism { lagr_g1, xi_1 }, + // The projection map ignores the `elgamal_randomness` component, and flattens the vector of chunked plaintexts after adding a zero + projection: |dom: &HkzgElgamalWitness| { + let HkzgElgamalWitness { + hkzg_randomness, + chunked_plaintexts, + .. + } = dom; + let flattened_chunked_plaintexts: Vec> = + std::iter::once(Scalar(E::ScalarField::ZERO)) + .chain(chunked_plaintexts.iter().flatten().cloned()) + .collect(); + univariate_hiding_kzg::Witness:: { + hiding_randomness: hkzg_randomness.clone(), + values: flattened_chunked_plaintexts, + } + }, + }; + // Set up the chunked_elgamal homomorphism, and use a projection map to lift it to HkzgElgamalWitness + let lifted_chunked_elgamal = LiftedChunkedElgamal:: { + hom: chunked_elgamal::Homomorphism { pp, eks }, + // The projection map simply ignores the `hkzg_randomness` component + projection: |dom: &HkzgElgamalWitness| { + let HkzgElgamalWitness { + chunked_plaintexts, + elgamal_randomness, + .. + } = dom; + chunked_elgamal::Witness { + plaintext_chunks: chunked_plaintexts.clone(), + plaintext_randomness: elgamal_randomness.clone(), + } + }, + }; + + // Combine the two lifted homomorphisms just constructed, into the required TupleHomomorphism + Self { + hom1: lifted_hkzg, + hom2: lifted_chunked_elgamal, + } + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/input_secret.rs b/crates/aptos-dkg/src/pvss/chunky/input_secret.rs new file mode 100644 index 00000000000..cfe7d5511f7 --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/input_secret.rs @@ -0,0 +1,58 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{pvss::chunky::public_parameters::PublicParameters, traits::Convert, Scalar}; +use aptos_crypto::{arkworks, Uniform}; +use aptos_crypto_derive::{SilentDebug, SilentDisplay}; +use ark_ec::pairing::Pairing; +use derive_more::Add; +use num_traits::Zero; +use std::ops::AddAssign; + +#[derive(SilentDebug, SilentDisplay, PartialEq, Add)] +pub struct InputSecret { + /// The actual secret being dealt; a scalar $a \in F$. + a: F, +} + +#[cfg(feature = "assert-private-keys-not-cloneable")] +static_assertions::assert_not_impl_any!(InputSecret: Clone); + +impl Uniform for InputSecret { + fn generate(rng: &mut R) -> Self + where + R: rand::RngCore + rand::CryptoRng, + { + Self { + a: arkworks::random::sample_field_element(rng), + } + } +} + +impl AddAssign<&InputSecret> for InputSecret { + fn add_assign(&mut self, other: &InputSecret) { + self.a += other.a; + } +} + +impl Zero for InputSecret { + fn zero() -> Self { + InputSecret { a: F::ZERO } + } + + fn is_zero(&self) -> bool { + self.a.is_zero() + } +} + +impl InputSecret { + pub fn get_secret_a(&self) -> &F { + &self.a + } +} + +impl Convert, PublicParameters> for InputSecret { + fn to(&self, _with: &PublicParameters) -> Scalar { + Scalar(*self.get_secret_a()) + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/keys.rs b/crates/aptos-dkg/src/pvss/chunky/keys.rs new file mode 100644 index 00000000000..11448112959 --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/keys.rs @@ -0,0 +1,101 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{pvss::chunky::chunked_elgamal, traits, Scalar}; +use aptos_crypto::{ + arkworks, + arkworks::serialization::{ark_de, ark_se}, + CryptoMaterialError, Uniform, ValidCryptoMaterial, +}; +use aptos_crypto_derive::{SilentDebug, SilentDisplay}; +use ark_ec::{pairing::Pairing, CurveGroup}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use serde::{Deserialize, Serialize}; +use std::ops::Mul; + +/// The *encryption (public)* key used to encrypt shares of the dealt secret for each PVSS player. +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] +pub struct EncryptPubKey { + /// A group element $H^{dk^{-1}} \in G_1$. + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + pub(crate) ek: E::G1Affine, +} + +impl ValidCryptoMaterial for EncryptPubKey { + const AIP_80_PREFIX: &'static str = ""; + + fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + self.ek.serialize_compressed(&mut bytes).unwrap(); + bytes + } +} + +impl TryFrom<&[u8]> for EncryptPubKey { + type Error = CryptoMaterialError; + + fn try_from(bytes: &[u8]) -> Result { + let ek = ::deserialize_compressed(bytes) + .map_err(|_| CryptoMaterialError::DeserializationError)?; + + Ok(EncryptPubKey { ek }) + } +} + +/// The *decryption (secret) key* used by each PVSS player to decrypt their share of the dealt secret. +#[derive(SilentDisplay, SilentDebug)] +pub struct DecryptPrivKey { + /// A scalar $dk \in F$. + pub(crate) dk: E::ScalarField, +} + +impl Uniform for DecryptPrivKey { + fn generate(rng: &mut R) -> Self + where + R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, + { + DecryptPrivKey:: { + dk: arkworks::random::sample_field_element(rng), + } + } +} + +impl traits::Convert, chunked_elgamal::PublicParameters> + for DecryptPrivKey +{ + /// Given a decryption key $dk$, computes its associated encryption key $H^{dk}$ + fn to(&self, pp_elgamal: &chunked_elgamal::PublicParameters) -> EncryptPubKey { + EncryptPubKey:: { + ek: pp_elgamal.pubkey_base().mul(self.dk).into_affine(), + } + } +} + +#[allow(non_snake_case)] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct DealtPubKey { + /// A group element $G$ \in G_2$ + G: E::G2Affine, +} + +#[allow(non_snake_case)] +impl DealtPubKey { + pub fn new(G: E::G2Affine) -> Self { + Self { G } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct DealtPubKeyShare(pub(crate) DealtPubKey); // TODO: Copied from `das`, but should review this at some point!! + +impl DealtPubKeyShare { + pub fn new(dealt_pk: DealtPubKey) -> Self { + DealtPubKeyShare(dealt_pk) + } +} + +// TODO: maybe make these actual structs +#[allow(type_alias_bounds)] +pub type DealtSecretKey = Scalar; +#[allow(type_alias_bounds)] +pub type DealtSecretKeyShare = Scalar; diff --git a/crates/aptos-dkg/src/pvss/chunky/mod.rs b/crates/aptos-dkg/src/pvss/chunky/mod.rs new file mode 100644 index 00000000000..e7df8df7764 --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/mod.rs @@ -0,0 +1,13 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +mod chunked_elgamal; +mod chunks; +mod hkzg_chunked_elgamal; +mod input_secret; +mod keys; +mod public_parameters; +mod transcript; +// mod weighted_transcript; TODO: to add soon + +pub use transcript::Transcript; diff --git a/crates/aptos-dkg/src/pvss/chunky/public_parameters.rs b/crates/aptos-dkg/src/pvss/chunky/public_parameters.rs new file mode 100644 index 00000000000..bb203460e1d --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/public_parameters.rs @@ -0,0 +1,199 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This submodule implements the *public parameters* for this "chunked_elgamal_field" PVSS scheme. + +use crate::{ + dlog, + pvss::{ + chunky::{ + chunked_elgamal, chunked_elgamal::num_chunks_per_scalar, input_secret::InputSecret, + keys, + }, + traits, + }, + range_proofs::{dekart_univariate_v2, traits::BatchedRangeProof}, + traits::transcript::WithMaxNumShares, +}; +use aptos_crypto::{ + arkworks::{ + hashing, + serialization::{ark_de, ark_se}, + GroupGenerators, + }, + utils, CryptoMaterialError, ValidCryptoMaterial, +}; +use ark_ec::{pairing::Pairing, CurveGroup}; +use ark_serialize::{SerializationError, Valid}; +use rand::{thread_rng, CryptoRng, RngCore}; +use serde::{Deserialize, Deserializer, Serialize}; +use std::{collections::HashMap, ops::Mul}; + +const DST: &[u8] = b"APTOS_CHUNKED_ELGAMAL_FIELD_PVSS_DST"; // This DST will be used in setting up a group generator `G_2`, see below + +fn compute_powers_of_radix(ell: u8) -> Vec { + utils::powers( + E::ScalarField::from(1u64 << ell), + num_chunks_per_scalar::(ell) as usize, + ) +} + +// TODO: If we need it later, let's derive CanonicalSerialize/CanonicalDeserialize from Serialize/Deserialize? E.g. the opposite of ark_se/de... +#[derive(Serialize, Clone, Debug, PartialEq, Eq)] +#[allow(non_snake_case)] +pub struct PublicParameters { + #[serde(serialize_with = "ark_se")] + pub pp_elgamal: chunked_elgamal::PublicParameters, // TODO: make this or instead of ? + + #[serde(serialize_with = "ark_se")] + pub pk_range_proof: dekart_univariate_v2::ProverKey, + + /// Base for the commitments to the polynomial evaluations (and for the dealt public key [shares]) + #[serde(serialize_with = "ark_se")] + G_2: E::G2Affine, + + pub ell: u8, + + #[serde(skip)] + pub table: HashMap, u32>, + + #[serde(skip)] + pub powers_of_radix: Vec, +} + +#[allow(non_snake_case)] +impl<'de, E: Pairing> Deserialize<'de> for PublicParameters { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Deserialize the serializable fields directly + #[derive(Deserialize)] + struct SerializedFields { + #[serde(deserialize_with = "ark_de")] + pp_elgamal: chunked_elgamal::PublicParameters, + #[serde(deserialize_with = "ark_de")] + pk_range_proof: dekart_univariate_v2::ProverKey, + #[serde(deserialize_with = "ark_de")] + G_2: E::G2Affine, + ell: u8, + } + + let serialized = SerializedFields::::deserialize(deserializer)?; + let G: E::G1 = serialized.pp_elgamal.G.into(); + + Ok(Self { + pp_elgamal: serialized.pp_elgamal, + pk_range_proof: serialized.pk_range_proof, + G_2: serialized.G_2, + ell: serialized.ell, + table: dlog::table::build::(G, 1u32 << (serialized.ell / 2)), + powers_of_radix: compute_powers_of_radix::(serialized.ell), + }) + } +} + +impl PublicParameters { + pub fn get_commitment_base(&self) -> E::G2Affine { + self.G_2 + } +} + +impl Valid for PublicParameters { + fn check(&self) -> Result<(), SerializationError> { + Ok(()) + } +} + +impl traits::HasEncryptionPublicParams for PublicParameters { + type EncryptionPublicParameters = chunked_elgamal::PublicParameters; + + fn get_encryption_public_params(&self) -> &Self::EncryptionPublicParameters { + &self.pp_elgamal + } +} + +impl traits::Convert, PublicParameters> + for InputSecret +{ + /// Computes the public key associated with the given input secret. + /// NOTE: In the SCRAPE PVSS, a `DealtPublicKey` cannot be computed from a `DealtSecretKey` directly. + fn to(&self, pp: &PublicParameters) -> keys::DealtPubKey { + keys::DealtPubKey::new( + pp.get_commitment_base() + .mul(self.get_secret_a()) + .into_affine(), + ) + } +} + +#[allow(non_snake_case)] +impl TryFrom<&[u8]> for PublicParameters { + type Error = CryptoMaterialError; + + fn try_from(bytes: &[u8]) -> Result { + bcs::from_bytes::>(bytes) + .map_err(|_| CryptoMaterialError::DeserializationError) + } +} + +#[allow(non_snake_case)] +impl PublicParameters { + /// Verifiably creates Aptos-specific public parameters. + pub fn new(max_num_shares: usize, ell: u8, rng: &mut R) -> Self { + let max_num_chunks_padded = + ((max_num_shares * num_chunks_per_scalar::(ell) as usize) + 1).next_power_of_two() + - 1; + + let group_generators = GroupGenerators::default(); // TODO: At least one of these should come from a powers of tau ceremony? + let pp_elgamal = chunked_elgamal::PublicParameters::default(); + let G = *pp_elgamal.message_base(); + let pp = Self { + pp_elgamal, + pk_range_proof: dekart_univariate_v2::Proof::setup( + max_num_chunks_padded, + ell as usize, + group_generators, + rng, + ) + .0, + G_2: hashing::unsafe_hash_to_affine(b"G_2", DST), + ell, + table: dlog::table::build::(G.into(), 1u32 << (ell / 2)), + powers_of_radix: compute_powers_of_radix::(ell), + }; + + pp + } +} + +impl ValidCryptoMaterial for PublicParameters { + const AIP_80_PREFIX: &'static str = ""; + + fn to_bytes(&self) -> Vec { + bcs::to_bytes(&self).expect("unexpected error during PVSS transcript serialization") + } +} + +const DEFAULT_ELL_FOR_TESTING: u8 = 16; // TODO: made this a const to emphasize that the parameter is completely fixed wherever this value used (namely below), might not be ideal + +impl Default for PublicParameters { + // This is only used for testing and benchmarking + fn default() -> Self { + let mut rng = thread_rng(); + Self::new(1, DEFAULT_ELL_FOR_TESTING, &mut rng) + } +} + +impl WithMaxNumShares for PublicParameters { + fn with_max_num_shares(n: usize) -> Self { + let mut rng = thread_rng(); + Self::new(n, DEFAULT_ELL_FOR_TESTING, &mut rng) + } + + // The only thing from `pp` that `generate()` uses is `pp.ell`, so make the rest as small as possible. + fn with_max_num_shares_for_generate(_n: usize) -> Self { + let mut rng = thread_rng(); + Self::new(1, DEFAULT_ELL_FOR_TESTING, &mut rng) + } +} diff --git a/crates/aptos-dkg/src/pvss/chunky/transcript.rs b/crates/aptos-dkg/src/pvss/chunky/transcript.rs new file mode 100644 index 00000000000..7db6f4db7da --- /dev/null +++ b/crates/aptos-dkg/src/pvss/chunky/transcript.rs @@ -0,0 +1,696 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + dlog::bsgs, + pcs::univariate_hiding_kzg, + pvss::{ + chunky::{ + chunked_elgamal::{self, num_chunks_per_scalar}, + chunks, + hkzg_chunked_elgamal::{self, HkzgElgamalWitness}, + input_secret::InputSecret, + keys, + public_parameters::PublicParameters, + }, + traits::{ + self, + transcript::{Aggregatable, MalleableTranscript}, + HasEncryptionPublicParams, + }, + Player, + }, + range_proofs::{dekart_univariate_v2, traits::BatchedRangeProof}, + sigma_protocol::{ + self, + homomorphism::{tuple::TupleCodomainShape, Trait as _}, + traits::Trait as _, + }, + traits::transcript::HasAggregatableSubtranscript, + Scalar, +}; +use anyhow::bail; +use aptos_crypto::{ + arkworks::{ + self, + random::{ + sample_field_element, sample_field_elements, unsafe_random_point, unsafe_random_points, + UniformRand, + }, + scrape::LowDegreeTest, + serialization::{ark_de, ark_se}, + shamir::ShamirThresholdConfig, + }, + bls12381::{self, PrivateKey}, + utils, CryptoMaterialError, SecretSharingConfig as _, Signature, SigningKey, Uniform, + ValidCryptoMaterial, +}; +use ark_ec::{ + pairing::{Pairing, PairingOutput}, + AffineRepr, CurveGroup, VariableBaseMSM, +}; +use ark_ff::{AdditiveGroup, Fp, FpConfig}; +use ark_poly::EvaluationDomain; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use serde::{Deserialize, Serialize}; +use std::ops::{Mul, Sub}; + +/// Domain-separator tag (DST) for the Fiat-Shamir hashing used to derive randomness from the transcript. +pub const DST: &[u8; 32] = b"APTOS_CHUNK_EG_FIELD_PVSS_FS_DST"; + +#[allow(non_snake_case)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct Transcript { + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + utrs: UnsignedTranscript, + sgn: bls12381::Signature, +} + +#[allow(non_snake_case)] +#[derive( + CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, +)] +pub struct UnsignedTranscript { + dealer: Player, + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + pub subtranscript: SubTranscript, + /// Proof (of knowledge) showing that the s_{i,j}'s in C are base-B representations (of the s_i's in V, but this is not part of the proof), and that the r_j's in R are used in C + #[serde(serialize_with = "ark_se", deserialize_with = "ark_de")] + pub sharing_proof: SharingProof, +} + +#[allow(non_snake_case)] +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct SubTranscript { + pub Vs: Vec, + /// First chunked ElGamal component: C[i][j] = s_{i,j} * G + r_j * ek_i. Here s_i = \sum_j s_{i,j} * B^j // TODO: change notation because B is not a group element? + pub Cs: Vec>, // TODO: maybe make this and the other fields affine? The verifier will have to do it anyway... and we are trying to speed that up + /// Second chunked ElGamal component: R[j] = r_j * H + pub Rs: Vec, +} + +impl HasAggregatableSubtranscript> + for Transcript +{ + type SubTranscript = SubTranscript; + + fn get_subtranscript(&self) -> Self::SubTranscript { + self.utrs.subtranscript.clone() + } +} + +impl Aggregatable> for SubTranscript { + fn aggregate_with( + &mut self, + sc: &SecretSharingConfig, + other: &Self, + ) -> anyhow::Result<()> { + debug_assert_eq!(self.Cs.len(), sc.n); + debug_assert_eq!(self.Vs.len(), sc.n + 1); + debug_assert_eq!(self.Cs.len(), other.Cs.len()); + debug_assert_eq!(self.Rs.len(), other.Rs.len()); + debug_assert_eq!(self.Vs.len(), other.Vs.len()); + + for i in 0..sc.n { + self.Vs[i] += other.Vs[i]; + for j in 0..self.Cs[i].len() { + self.Cs[i][j] += other.Cs[i][j]; + } + } + self.Vs[sc.n] += other.Vs[sc.n]; + + for (r_self, r_other) in self.Rs.iter_mut().zip(&other.Rs) { + *r_self += r_other; + } + + Ok(()) + } +} + +// ================================================================ +// IMPLEMENTATION OF UNSIGNED TRANSCRIPT HASHER +// ================================================================ + +/// Cryptographic hasher for an BCS-serializable UnsignedTranscript +#[derive(Clone)] +pub struct UnsignedTranscriptHasher(aptos_crypto::hash::DefaultHasher); + +impl UnsignedTranscriptHasher { + fn new() -> Self { + const DOMAIN: &[u8] = b"UnsignedTranscript"; + + UnsignedTranscriptHasher(aptos_crypto::hash::DefaultHasher::new(DOMAIN)) + } +} + +static UNSIGNED_TRANSCRIPT_HASHER: aptos_crypto::_once_cell::sync::Lazy = + aptos_crypto::_once_cell::sync::Lazy::new(|| UnsignedTranscriptHasher::new()); + +impl Default for UnsignedTranscriptHasher { + fn default() -> Self { + UNSIGNED_TRANSCRIPT_HASHER.clone() + } +} + +impl aptos_crypto::hash::CryptoHasher for UnsignedTranscriptHasher { + fn seed() -> &'static [u8; 32] { + // Directly compute a fixed seed from the domain string. + const DOMAIN: &[u8] = b"UnsignedTranscript"; + + // Compute once and leak to get 'static + Box::leak(Box::new(aptos_crypto::hash::DefaultHasher::prefixed_hash( + DOMAIN, + ))) + } + + fn update(&mut self, bytes: &[u8]) { + self.0.update(bytes); + } + + fn finish(self) -> aptos_crypto::hash::HashValue { + self.0.finish() + } +} + +impl std::io::Write for UnsignedTranscriptHasher { + fn write(&mut self, bytes: &[u8]) -> std::io::Result { + self.0.update(bytes); + Ok(bytes.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +// ================================================================ +// END IMPLEMENTATION OF UNSIGNED TRANSCRIPT HASHER +// ================================================================ + +// ================================================================ +// IMPLEMENTATION OF UNSIGNED TRANSCRIPT BCS HASH +// ================================================================ + +use aptos_crypto::hash::{CryptoHash, HashValue}; + +/// Manual implementation of `BCSCryptoHash` for `UnsignedTranscript` +impl CryptoHash for UnsignedTranscript +where + UnsignedTranscript: Serialize, +{ + type Hasher = UnsignedTranscriptHasher; + + fn hash(&self) -> HashValue { + use aptos_crypto::hash::CryptoHasher; + + let mut state = Self::Hasher::default(); + // If BCS serialization fails, this is a programmer error + bcs::serialize_into(&mut state, &self) + .expect("BCS serialization of UnsignedTranscript should not fail"); + state.finish() + } +} + +// ================================================================ +// END IMPLEMENTATION OF UNSIGNED TRANSCRIPT BCS HASH +// ================================================================ + +#[allow(non_snake_case)] +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct SharingProof { + /// Proof showing knowledge of `witnesses` s_{i,j} yielding the commitment and the C and the R + pub PoK: sigma_protocol::Proof>, // static because we don't want the lifetime of the Proof to depend on the Homomorphism TODO: try removing it? + /// A batched range proof showing that all committed values s_{i,j} lie in some range + pub range_proof: dekart_univariate_v2::Proof, + /// A KZG-style commitment to the values s_{i,j} going into the range proof + pub range_proof_commitment: + as BatchedRangeProof>::Commitment, +} + +impl ValidCryptoMaterial for Transcript { + const AIP_80_PREFIX: &'static str = ""; + + fn to_bytes(&self) -> Vec { + // TODO: using `Result>` and `.map_err(|_| CryptoMaterialError::DeserializationError)` would be more consistent here? + bcs::to_bytes(&self).expect("Unexpected error during PVSS transcript serialization") + } +} + +impl TryFrom<&[u8]> for Transcript { + type Error = CryptoMaterialError; + + fn try_from(bytes: &[u8]) -> Result { + bcs::from_bytes::>(bytes) + .map_err(|_| CryptoMaterialError::DeserializationError) + } +} + +// Temporary hack, will deal with this at some point +#[allow(type_alias_bounds)] +type SokContext<'a, A: Serialize + Clone, E: Pairing> = ( + ShamirThresholdConfig, + bls12381::PublicKey, + &'a A, + usize, + Vec, +); + +// Not sure this alias is very useful +type SecretSharingConfig = ShamirThresholdConfig; + +impl, E: Pairing>> traits::Transcript + for Transcript +{ + type DealtPubKey = keys::DealtPubKey; + type DealtPubKeyShare = keys::DealtPubKeyShare; + type DealtSecretKey = keys::DealtSecretKey; + type DealtSecretKeyShare = keys::DealtSecretKeyShare; + type DecryptPrivKey = keys::DecryptPrivKey; + type EncryptPubKey = keys::EncryptPubKey; + type InputSecret = InputSecret; + type PublicParameters = PublicParameters; + type SecretSharingConfig = SecretSharingConfig; + type SigningPubKey = bls12381::PublicKey; + type SigningSecretKey = bls12381::PrivateKey; + + fn scheme_name() -> String { + "chunky_pvss".to_string() + } + + fn dst() -> Vec { + DST.to_vec() + } + + #[allow(non_snake_case)] + fn deal( + sc: &Self::SecretSharingConfig, + pp: &Self::PublicParameters, + ssk: &Self::SigningSecretKey, + spk: &Self::SigningPubKey, + eks: &Vec, + s: &Self::InputSecret, + session_id: &A, + dealer: &Player, + rng: &mut R, + ) -> Self { + debug_assert_eq!( + eks.len(), + sc.n, + "Number of encryption keys must equal number of players" + ); + + // Initialize the PVSS Fiat-Shamir context + let sok_ctxt = (*sc, spk.clone(), session_id, dealer.id, DST.to_vec()); // This is a bit hacky; also get rid of DST here and use self.dst? + + // Generate the Shamir secret sharing polynomial + let mut f = vec![*s.get_secret_a()]; // constant term of polynomial + f.extend(sample_field_elements::( + sc.get_threshold() - 1, + rng, + )); // these are the remaining coefficients; total degree is `t - 1` + + // Generate its `n` evaluations (shares) by doing an FFT over the whole domain, then truncating + let mut f_evals = sc.domain.fft(&f); + f_evals.truncate(sc.n); + debug_assert_eq!(f_evals.len(), sc.n); + + // Encrypt the chunked shares and generate the sharing proof + let (Cs, Rs, sharing_proof) = + Self::encrypt_chunked_shares(&f_evals, eks, sc, pp, sok_ctxt, rng); + + // Add constant term for the `\mathbb{G}_2` commitment (we're doing this + // **after** the previous step because we're now mutating `f_evals` by enlarging it; this is a silly + // technicality however, it has no impact on computational complexity whatsoever as we could simply + // modify the `commit_to_scalars()` function to take another input) + f_evals.push(f[0]); // or *s.get_secret_a() + + // Commit to polynomial evaluations + constant term + let G_2 = pp.get_commitment_base(); + let Vs = arkworks::commit_to_scalars(&G_2, &f_evals); + debug_assert_eq!(Vs.len(), sc.n + 1); + + // Construct the **unsigned** transcript struct with all computed values + let utrs = UnsignedTranscript { + dealer: *dealer, + subtranscript: SubTranscript { Vs, Cs, Rs }, + sharing_proof, + }; + + // Now sign this transcript + let sgn = ssk + .sign(&utrs) + .expect("signing of `chunky` PVSS transcript failed"); + + Transcript { utrs, sgn } + } + + #[allow(non_snake_case)] + fn verify( + &self, + sc: &Self::SecretSharingConfig, + pp: &Self::PublicParameters, + spks: &Vec, + eks: &Vec, + session_ids: &Vec, + ) -> anyhow::Result<()> { + if eks.len() != sc.n { + bail!("Expected {} encryption keys, but got {}", sc.n, eks.len()); + } + if self.utrs.subtranscript.Cs.len() != sc.n { + bail!( + "Expected {} arrays of chunked ciphertexts, but got {}", + sc.n, + self.utrs.subtranscript.Cs.len() + ); + } + if self.utrs.subtranscript.Vs.len() != sc.n + 1 { + bail!( + "Expected {} commitment elements, but got {}", + sc.n + 1, + self.utrs.subtranscript.Vs.len() + ); + } + + // Initialize the PVSS Fiat-Shamir context + let sok_ctxt = ( + *sc, + &spks[self.utrs.dealer.id], + session_ids[self.utrs.dealer.id].clone(), + self.utrs.dealer.id, + DST.to_vec(), + ); // This is a bit hacky; also get rid of DST here and use self.dst? + + // Verify the transcript signature + self.sgn.verify(&self.utrs, &spks[self.utrs.dealer.id])?; + + { + // Verify the PoK + let eks_inner: Vec<_> = eks.iter().map(|ek| ek.ek).collect(); + let hom = hkzg_chunked_elgamal::Homomorphism::new( + &pp.pk_range_proof.ck_S.lagr_g1, + pp.pk_range_proof.ck_S.xi_1, + &pp.pp_elgamal, + &eks_inner, + ); + if let Err(err) = hom.verify( + &TupleCodomainShape( + self.utrs.sharing_proof.range_proof_commitment.clone(), + chunked_elgamal::CodomainShape { + chunks: self.utrs.subtranscript.Cs.clone(), + randomness: self.utrs.subtranscript.Rs.clone(), + }, + ), + &self.utrs.sharing_proof.PoK, + &sok_ctxt, + ) { + bail!("PoK verification failed: {:?}", err); + } + + // Verify the range proof + if let Err(err) = self.utrs.sharing_proof.range_proof.verify( + &pp.pk_range_proof.vk, + sc.n * num_chunks_per_scalar::(pp.ell) as usize, + pp.ell as usize, + &self.utrs.sharing_proof.range_proof_commitment, + ) { + bail!("Range proof batch verification failed: {:?}", err); + } + } + + let mut rng = rand::thread_rng(); // TODO: make `rng` a parameter of fn verify()? + + // Do the SCRAPE LDT + let ldt = LowDegreeTest::random(&mut rng, sc.t, sc.n + 1, true, &sc.domain); // includes_zero is true here means it includes a commitment to f(0), which is in V[n] + ldt.low_degree_test_group(&self.utrs.subtranscript.Vs)?; + + // Now compute the final MSM // TODO: merge this multi_exp with the PoK verification, as in YOLO YOSO? + let mut base_vec = Vec::new(); + let mut exp_vec = Vec::new(); + + let beta = sample_field_element(&mut rng); + let powers_of_beta = utils::powers(beta, self.utrs.subtranscript.Cs.len() + 1); + + for i in 0..self.utrs.subtranscript.Cs.len() { + for j in 0..self.utrs.subtranscript.Cs[i].len() { + let base = self.utrs.subtranscript.Cs[i][j]; + let exp = pp.powers_of_radix[j] * powers_of_beta[i]; + base_vec.push(base); + exp_vec.push(exp); + } + } + + let weighted_Cs = E::G1::msm(&E::G1::normalize_batch(&base_vec), &exp_vec) + .expect("Failed to compute MSM of Cs in chunky"); + + let weighted_Vs = E::G2::msm( + &E::G2::normalize_batch( + &self.utrs.subtranscript.Vs[..self.utrs.subtranscript.Cs.len()], + ), + &powers_of_beta[..self.utrs.subtranscript.Cs.len()], + ) + .expect("Failed to compute MSM of Vs in chunky"); + + let res = E::multi_pairing( + [ + weighted_Cs.into_affine(), + *pp.get_encryption_public_params().message_base(), + ], + [pp.get_commitment_base(), (-weighted_Vs).into_affine()], + ); // Making things affine here rather than converting the two bases to group elements, since that's probably what they would be converted to anyway: https://github.com/arkworks-rs/algebra/blob/c1f4f5665504154a9de2345f464b0b3da72c28ec/ec/src/models/bls12/g1.rs#L14 + + if PairingOutput::::ZERO != res { + return Err(anyhow::anyhow!("Expected zero during multi-pairing check")); + } + + Ok(()) + } + + fn get_dealers(&self) -> Vec { + vec![self.utrs.dealer] + } + + fn get_public_key_share( + &self, + _sc: &Self::SecretSharingConfig, + player: &Player, + ) -> Self::DealtPubKeyShare { + Self::DealtPubKeyShare::new(Self::DealtPubKey::new( + self.utrs.subtranscript.Vs[player.id].into_affine(), + )) + } + + fn get_dealt_public_key(&self) -> Self::DealtPubKey { + Self::DealtPubKey::new( + self.utrs + .subtranscript + .Vs + .last() + .expect("V is empty somehow") + .into_affine(), + ) + } + + #[allow(non_snake_case)] + fn decrypt_own_share( + &self, + _sc: &Self::SecretSharingConfig, + player: &Player, + dk: &Self::DecryptPrivKey, + pp: &Self::PublicParameters, + ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare) { + let C_i = &self.utrs.subtranscript.Cs[player.id]; // where in notation `C_i`, `i` denotes `player.id` + + let ephemeral_keys: Vec<_> = self + .utrs + .subtranscript + .Rs + .iter() + .map(|R_i| R_i.mul(dk.dk)) + .collect(); + assert_eq!( + ephemeral_keys.len(), + C_i.len(), + "Number of ephemeral keys does not match the number of ciphertext chunks" + ); + let dealt_encrypted_secret_key_share_chunks: Vec<_> = C_i + .iter() + .zip(ephemeral_keys.iter()) + .map(|(C_ij, ephemeral_key)| C_ij.sub(ephemeral_key)) + .collect(); + + let dealt_chunked_secret_key_share = bsgs::dlog_vec( + pp.pp_elgamal.G.into_group(), + &dealt_encrypted_secret_key_share_chunks, + &pp.table, + 1 << pp.ell as u32, + ) + .expect("BSGS dlog failed"); + + let dealt_chunked_secret_key_share_fr: Vec = dealt_chunked_secret_key_share + .iter() + .map(|&x| E::ScalarField::from(x)) + .collect(); + + let dealt_secret_key_share = + chunks::le_chunks_to_scalar(pp.ell, &dealt_chunked_secret_key_share_fr); + + let dealt_pub_key_share = self.utrs.subtranscript.Vs[player.id].into_affine(); // G_2^{f(\omega^i}) + + ( + Scalar(dealt_secret_key_share), + Self::DealtPubKeyShare::new(Self::DealtPubKey::new(dealt_pub_key_share)), // TODO: review this formalism + ) + } + + #[allow(non_snake_case)] + fn generate(sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, rng: &mut R) -> Self + where + R: rand_core::RngCore + rand_core::CryptoRng, + { + let num_chunks_per_share = num_chunks_per_scalar::(pp.ell) as usize; + let utrs = UnsignedTranscript { + dealer: sc.get_player(0), + subtranscript: SubTranscript { + Vs: unsafe_random_points::(sc.n + 1, rng), + Cs: (0..sc.n) + .map(|_| unsafe_random_points(num_chunks_per_share, rng)) + .collect::>(), // TODO: would this become faster if generated in one batch and flattened? + Rs: unsafe_random_points(num_chunks_per_share, rng), + }, + sharing_proof: SharingProof { + range_proof_commitment: sigma_protocol::homomorphism::TrivialShape( + unsafe_random_point(rng), + ), + PoK: hkzg_chunked_elgamal::Proof::generate( + (sc.n - 1).next_power_of_two() - 1, + num_chunks_per_share, + rng, + ), + range_proof: dekart_univariate_v2::Proof::generate(pp.ell, rng), + }, + }; + + let ssk = PrivateKey::generate(rng); + + let sgn = ssk + .sign(&utrs) + .expect("signing of PVSS transcript should have succeeded"); + + Transcript { utrs, sgn } + } +} + +impl, E: Pairing>> Transcript { + // why are N and P needed? TODO: maybe integrate into deal() + #[allow(non_snake_case)] + pub fn encrypt_chunked_shares< + 'a, + A: Serialize + Clone, + R: rand_core::RngCore + rand_core::CryptoRng, + >( + f_evals: &[E::ScalarField], + eks: &[keys::EncryptPubKey], + _sc: &ShamirThresholdConfig, + pp: &PublicParameters, + sok_ctxt: SokContext<'a, A, E>, + rng: &mut R, + ) -> (Vec>, Vec, SharingProof) { + let sc = sok_ctxt.0; + + // Generate the required randomness + let hkzg_randomness = univariate_hiding_kzg::CommitmentRandomness::rand(rng); + + let elgamal_randomness = Scalar::vec_from_inner(chunked_elgamal::correlated_randomness( + rng, + 1 << pp.ell as u64, + num_chunks_per_scalar::(pp.ell), + )); + + // Chunk and flatten the shares + let f_evals_chunked: Vec> = f_evals + .iter() + .map(|f_eval| chunks::scalar_to_le_chunks(pp.ell, f_eval)) + .collect(); + // Flatten it now before `f_evals_chunked` is consumed in the next step + let f_evals_chunked_flat: Vec = + f_evals_chunked.iter().flatten().copied().collect(); + + // Now generate the encrypted shares and range proof commitment, together with its PoK, so: + // (1) Set up the witness + let witness = HkzgElgamalWitness { + hkzg_randomness, + chunked_plaintexts: Scalar::vecvec_from_inner(f_evals_chunked), + elgamal_randomness, + }; + // (2) Compute its image under the corresponding homomorphism, and prove knowledge of an inverse + // (2a) Set up the tuple homomorphism + let eks_inner: Vec<_> = eks.iter().map(|ek| ek.ek).collect(); // TODO: this is a bit ugly + let hom = hkzg_chunked_elgamal::Homomorphism::new( + &pp.pk_range_proof.ck_S.lagr_g1, + pp.pk_range_proof.ck_S.xi_1, + &pp.pp_elgamal, + &eks_inner, + ); + // (2b) Compute its image (the public statement), so the range proof commitment and chunked_elgamal encryptions + let statement = hom.apply(&witness); + // (2c) Prove knowledge of its inverse + let PoK = hom + .prove(&witness, &statement, &sok_ctxt, rng) + .change_lifetime(); // Make sure the lifetime of the proof is not coupled to `hom` which has references + // TODO: don't do &mut but just pass it + + // Destructure the "public statement" of the above sigma protocol + let TupleCodomainShape( + range_proof_commitment, + chunked_elgamal::CodomainShape { + chunks: Cs, + randomness: Rs, + }, + ) = statement; + + debug_assert_eq!( + Cs.len(), + sc.n, + "Number of encrypted chunks must equal number of players" + ); + + // Generate the batch range proof, given the `range_proof_commitment` produced in the PoK + let range_proof = dekart_univariate_v2::Proof::prove( + &pp.pk_range_proof, + &f_evals_chunked_flat, + pp.ell as usize, + &range_proof_commitment, + &hkzg_randomness, + rng, + ); // TODO: don't do &mut fs_t but just pass it + + // Assemble the sharing proof + let sharing_proof = SharingProof { + PoK, + range_proof, + range_proof_commitment, + }; + + (Cs, Rs, sharing_proof) + } +} + +impl, E: Pairing>> MalleableTranscript + for Transcript +{ + fn maul_signature( + &mut self, + _ssk: &Self::SigningSecretKey, + _aux: &A, + _player: &Player, + ) { + // TODO: We're not using this but it probably fails if we don't; but that would probably mean recomputing almost the entire transcript... but then that would require eks and pp + panic!("Doesn't work for this PVSS, at least for now"); + // self.utrs.dealer = *player; + + // let sgn = ssk + // .sign(&self.utrs) + // .expect("signing of `chunky` PVSS transcript failed"); + // self.sgn = sgn; + } +} diff --git a/crates/aptos-dkg/src/pvss/das/public_parameters.rs b/crates/aptos-dkg/src/pvss/das/public_parameters.rs index cb4eacdc893..0a5f0c3f427 100644 --- a/crates/aptos-dkg/src/pvss/das/public_parameters.rs +++ b/crates/aptos-dkg/src/pvss/das/public_parameters.rs @@ -4,10 +4,13 @@ //! This submodule implements the *public parameters* for this PVSS scheme. use crate::{ - constants::G2_PROJ_NUM_BYTES, pvss::{encryption_elgamal, traits}, + traits::transcript::WithMaxNumShares, +}; +use aptos_crypto::{ + blstrs::G2_PROJ_NUM_BYTES, CryptoMaterialError, ValidCryptoMaterial, + ValidCryptoMaterialStringExt, }; -use aptos_crypto::{CryptoMaterialError, ValidCryptoMaterial, ValidCryptoMaterialStringExt}; use aptos_crypto_derive::{DeserializeKey, SerializeKey}; use blstrs::{G1Projective, G2Projective}; use pairing::group::Group; @@ -90,6 +93,17 @@ impl ValidCryptoMaterial for PublicParameters { } } +impl WithMaxNumShares for PublicParameters { + fn with_max_num_shares(_n: usize) -> Self { + Self::default() + } + + // Setup is fast enough + fn with_max_num_shares_for_generate(_n: usize) -> Self { + Self::default() + } +} + impl Default for PublicParameters { /// Verifiably creates Aptos-specific public parameters. fn default() -> Self { diff --git a/crates/aptos-dkg/src/pvss/das/unweighted_protocol.rs b/crates/aptos-dkg/src/pvss/das/unweighted_protocol.rs index 353f2cc736f..2be29bf9414 100644 --- a/crates/aptos-dkg/src/pvss/das/unweighted_protocol.rs +++ b/crates/aptos-dkg/src/pvss/das/unweighted_protocol.rs @@ -3,33 +3,39 @@ use crate::{ algebra::polynomials::{get_nonzero_powers_of_tau, shamir_secret_share}, - pvss, pvss::{ + self, contribution::{batch_verify_soks, Contribution, SoK}, - das, encryption_dlog, fiat_shamir, schnorr, traits, - traits::{transcript::MalleableTranscript, HasEncryptionPublicParams, SecretSharingConfig}, - LowDegreeTest, Player, ThresholdConfig, + das, encryption_dlog, schnorr, + traits::{self, transcript::MalleableTranscript, HasEncryptionPublicParams}, + LowDegreeTest, Player, ThresholdConfigBlstrs, }, + traits::transcript::Aggregatable, utils::{ - g1_multi_exp, g2_multi_exp, multi_pairing, + g1_multi_exp, g2_multi_exp, random::{ insecure_random_g1_points, insecure_random_g2_points, random_g1_point, random_g2_point, - random_scalar, + random_scalars, }, }, }; use anyhow::bail; -use aptos_crypto::{bls12381, CryptoMaterialError, Genesis, SigningKey, ValidCryptoMaterial}; +use aptos_crypto::{ + bls12381, + blstrs::{multi_pairing, random_scalar}, + traits::SecretSharingConfig as _, + CryptoMaterialError, Genesis, SigningKey, ValidCryptoMaterial, +}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use blstrs::{G1Projective, G2Projective, Gt}; use group::Group; +use rand::thread_rng; use serde::{Deserialize, Serialize}; use std::ops::{Add, Mul, Neg, Sub}; pub const DAS_SK_IN_G1: &'static str = "das_sk_in_g1"; /// Domain-separator tag (DST) for the Fiat-Shamir hashing used to derive randomness from the transcript. -const DAS_PVSS_FIAT_SHAMIR_DST: &[u8; 30] = b"APTOS_DAS_PVSS_FIAT_SHAMIR_DST"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, BCSCryptoHash, CryptoHasher)] #[allow(non_snake_case)] @@ -80,10 +86,14 @@ impl traits::Transcript for Transcript { type EncryptPubKey = encryption_dlog::g1::EncryptPubKey; type InputSecret = pvss::input_secret::InputSecret; type PublicParameters = das::PublicParameters; - type SecretSharingConfig = ThresholdConfig; + type SecretSharingConfig = ThresholdConfigBlstrs; type SigningPubKey = bls12381::PublicKey; type SigningSecretKey = bls12381::PrivateKey; + fn dst() -> Vec { + b"APTOS_DAS_PVSS_FIAT_SHAMIR_DST".to_vec() + } + fn scheme_name() -> String { DAS_SK_IN_G1.to_string() } @@ -93,6 +103,7 @@ impl traits::Transcript for Transcript { sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, ssk: &Self::SigningSecretKey, + _spk: &Self::SigningPubKey, eks: &Vec, s: &Self::InputSecret, aux: &A, @@ -165,18 +176,9 @@ impl traits::Transcript for Transcript { ); } - // Derive challenges deterministically via Fiat-Shamir; easier to debug for distributed systems - // TODO: benchmark this - let (f, extra) = fiat_shamir::fiat_shamir( - self, - sc, - pp, - spks, - eks, - auxs, - &DAS_PVSS_FIAT_SHAMIR_DST[..], - 2, - ); + // Deriving challenges by flipping coins: less complex to implement & less likely to get wrong. Creates bad RNG risks but we deem that acceptable. + let mut rng = thread_rng(); + let extra = random_scalars(2, &mut rng); // Verify signature(s) on the secret commitment, player ID and `aux` let g_2 = *pp.get_commitment_base(); @@ -190,7 +192,13 @@ impl traits::Transcript for Transcript { )?; // Verify the committed polynomial is of the right degree - let ldt = LowDegreeTest::new(f, sc.t, sc.n + 1, true, sc.get_batch_evaluation_domain())?; + let ldt = LowDegreeTest::random( + &mut rng, + sc.t, + sc.n + 1, + true, + sc.get_batch_evaluation_domain(), + ); ldt.low_degree_test_on_g2(&self.V)?; // @@ -240,27 +248,6 @@ impl traits::Transcript for Transcript { .collect::>() } - fn aggregate_with(&mut self, sc: &Self::SecretSharingConfig, other: &Transcript) { - debug_assert_eq!(self.C.len(), sc.n); - debug_assert_eq!(self.V.len(), sc.n + 1); - - self.hat_w += other.hat_w; - self.C_0 += other.C_0; - - for i in 0..sc.n { - self.C[i] += other.C[i]; - self.V[i] += other.V[i]; - } - self.V[sc.n] += other.V[sc.n]; - - for sok in &other.soks { - self.soks.push(sok.clone()); - } - - debug_assert_eq!(self.C.len(), other.C.len()); - debug_assert_eq!(self.V.len(), other.V.len()); - } - fn get_public_key_share( &self, _sc: &Self::SecretSharingConfig, @@ -278,6 +265,7 @@ impl traits::Transcript for Transcript { _sc: &Self::SecretSharingConfig, player: &Player, dk: &Self::DecryptPrivKey, + _pp: &Self::PublicParameters, ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare) { let ctxt = self.C[player.id]; // C_i = h_1^m \ek_i^r = h_1^m g_1^{r sk_i} let ephemeral_key = self.C_0.mul(dk.dk); // (g_1^r)^{sk_i} = ek_i^r @@ -291,7 +279,11 @@ impl traits::Transcript for Transcript { } #[allow(non_snake_case)] - fn generate(sc: &Self::SecretSharingConfig, rng: &mut R) -> Self + fn generate( + sc: &Self::SecretSharingConfig, + _pp: &Self::PublicParameters, + rng: &mut R, + ) -> Self where R: rand_core::RngCore + rand_core::CryptoRng, { @@ -316,6 +308,35 @@ impl traits::Transcript for Transcript { } } +impl Aggregatable for Transcript { + fn aggregate_with( + &mut self, + sc: &ThresholdConfigBlstrs, + other: &Transcript, + ) -> anyhow::Result<()> { + debug_assert_eq!(self.C.len(), sc.n); + debug_assert_eq!(self.V.len(), sc.n + 1); + + self.hat_w += other.hat_w; + self.C_0 += other.C_0; + + for i in 0..sc.n { + self.C[i] += other.C[i]; + self.V[i] += other.V[i]; + } + self.V[sc.n] += other.V[sc.n]; + + for sok in &other.soks { + self.soks.push(sok.clone()); + } + + debug_assert_eq!(self.C.len(), other.C.len()); + debug_assert_eq!(self.V.len(), other.V.len()); + + Ok(()) + } +} + impl MalleableTranscript for Transcript { fn maul_signature( &mut self, diff --git a/crates/aptos-dkg/src/pvss/das/weighted_protocol.rs b/crates/aptos-dkg/src/pvss/das/weighted_protocol.rs index 937796ff3eb..9a300e6ce2f 100644 --- a/crates/aptos-dkg/src/pvss/das/weighted_protocol.rs +++ b/crates/aptos-dkg/src/pvss/das/weighted_protocol.rs @@ -3,24 +3,30 @@ use crate::{ algebra::polynomials::shamir_secret_share, - pvss, pvss::{ + self, contribution::{batch_verify_soks, Contribution, SoK}, - das, encryption_dlog, fiat_shamir, schnorr, traits, - traits::{transcript::MalleableTranscript, HasEncryptionPublicParams, SecretSharingConfig}, - LowDegreeTest, Player, WeightedConfig, + das, encryption_dlog, schnorr, + traits::{self, transcript::MalleableTranscript, HasEncryptionPublicParams}, + LowDegreeTest, Player, ThresholdConfigBlstrs, WeightedConfigBlstrs, }, + traits::transcript::Aggregatable, utils::{ - g1_multi_exp, g2_multi_exp, multi_pairing, + g1_multi_exp, g2_multi_exp, random::{ - insecure_random_g1_points, insecure_random_g2_points, random_g1_point, random_scalar, - random_scalars, + insecure_random_g1_points, insecure_random_g2_points, random_g1_point, random_scalars, }, HasMultiExp, }, }; use anyhow::bail; -use aptos_crypto::{bls12381, CryptoMaterialError, Genesis, SigningKey, ValidCryptoMaterial}; +use aptos_crypto::{ + bls12381, + blstrs::{multi_pairing, random_scalar}, + traits::SecretSharingConfig as _, + weighted_config::WeightedConfig, + CryptoMaterialError, Genesis, SigningKey, ValidCryptoMaterial, +}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use blstrs::{pairing, G1Affine, G1Projective, G2Affine, G2Projective, Gt}; use group::{Curve, Group}; @@ -30,10 +36,6 @@ use std::ops::{Add, Mul, Neg, Sub}; /// Scheme name pub const WEIGHTED_DAS_SK_IN_G1: &'static str = "provable_weighted_das_sk_in_g1"; -/// Domain-separator tag (DST) for the Fiat-Shamir hashing used to derive randomness from the transcript. -const DAS_WEIGHTED_PVSS_FIAT_SHAMIR_DST: &[u8; 48] = - b"APTOS_DAS_WEIGHTED_PROVABLY_PVSS_FIAT_SHAMIR_DST"; - /// A weighted transcript where the max player weight is $M$. /// Each player has weight $w_i$ and the threshold weight is $w$. /// The total weight is $W = \sum_{i=1}^n w_i$. @@ -93,10 +95,14 @@ impl traits::Transcript for Transcript { type EncryptPubKey = encryption_dlog::g1::EncryptPubKey; type InputSecret = pvss::input_secret::InputSecret; type PublicParameters = das::PublicParameters; - type SecretSharingConfig = WeightedConfig; + type SecretSharingConfig = WeightedConfigBlstrs; type SigningPubKey = bls12381::PublicKey; type SigningSecretKey = bls12381::PrivateKey; + fn dst() -> Vec { + b"APTOS_DAS_WEIGHTED_PROVABLY_PVSS_FIAT_SHAMIR_DST".to_vec() + } + fn scheme_name() -> String { WEIGHTED_DAS_SK_IN_G1.to_string() } @@ -106,6 +112,7 @@ impl traits::Transcript for Transcript { sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, ssk: &Self::SigningSecretKey, + _spk: &Self::SigningPubKey, eks: &Vec, s: &Self::InputSecret, aux: &A, @@ -193,17 +200,9 @@ impl traits::Transcript for Transcript { } let W = sc.get_total_weight(); - // Derive challenges deterministically via Fiat-Shamir; easier to debug for distributed systems - let (f, extra) = fiat_shamir::fiat_shamir( - self, - sc.get_threshold_config(), - pp, - spks, - eks, - auxs, - &DAS_WEIGHTED_PVSS_FIAT_SHAMIR_DST[..], - 2 + W * 3, // 3W+1 for encryption check, 1 for SoK verification. - ); + // Deriving challenges by flipping coins: less complex to implement & less likely to get wrong. Creates bad RNG risks but we deem that acceptable. + let mut rng = rand::thread_rng(); + let extra = random_scalars(2 + W * 3, &mut rng); let sok_vrfy_challenge = &extra[W * 3 + 1]; let g_2 = pp.get_commitment_base(); @@ -217,13 +216,13 @@ impl traits::Transcript for Transcript { sok_vrfy_challenge, )?; - let ldt = LowDegreeTest::new( - f, + let ldt = LowDegreeTest::random( + &mut rng, sc.get_threshold_weight(), W + 1, true, sc.get_batch_evaluation_domain(), - )?; + ); ldt.low_degree_test_on_g1(&self.V)?; // @@ -292,29 +291,6 @@ impl traits::Transcript for Transcript { .collect::>() } - #[allow(non_snake_case)] - fn aggregate_with(&mut self, sc: &Self::SecretSharingConfig, other: &Transcript) { - let W = sc.get_total_weight(); - - debug_assert!(self.check_sizes(sc).is_ok()); - debug_assert!(other.check_sizes(sc).is_ok()); - - for i in 0..self.V.len() { - self.V[i] += other.V[i]; - self.V_hat[i] += other.V_hat[i]; - } - - for i in 0..W { - self.R[i] += other.R[i]; - self.R_hat[i] += other.R_hat[i]; - self.C[i] += other.C[i]; - } - - for sok in &other.soks { - self.soks.push(sok.clone()); - } - } - fn get_public_key_share( &self, sc: &Self::SecretSharingConfig, @@ -343,6 +319,7 @@ impl traits::Transcript for Transcript { sc: &Self::SecretSharingConfig, player: &Player, dk: &Self::DecryptPrivKey, + _pp: &Self::PublicParameters, ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare) { let weight = sc.get_player_weight(player); let mut sk_shares = Vec::with_capacity(weight); @@ -364,7 +341,11 @@ impl traits::Transcript for Transcript { } #[allow(non_snake_case)] - fn generate(sc: &Self::SecretSharingConfig, rng: &mut R) -> Self + fn generate( + sc: &Self::SecretSharingConfig, + _pp: &Self::PublicParameters, + rng: &mut R, + ) -> Self where R: rand_core::RngCore + rand_core::CryptoRng, { @@ -391,9 +372,40 @@ impl traits::Transcript for Transcript { } } +impl Aggregatable> for Transcript { + #[allow(non_snake_case)] + fn aggregate_with( + &mut self, + sc: &WeightedConfig, + other: &Transcript, + ) -> anyhow::Result<()> { + let W = sc.get_total_weight(); + + debug_assert!(self.check_sizes(sc).is_ok()); + debug_assert!(other.check_sizes(sc).is_ok()); + + for i in 0..self.V.len() { + self.V[i] += other.V[i]; + self.V_hat[i] += other.V_hat[i]; + } + + for i in 0..W { + self.R[i] += other.R[i]; + self.R_hat[i] += other.R_hat[i]; + self.C[i] += other.C[i]; + } + + for sok in &other.soks { + self.soks.push(sok.clone()); + } + + Ok(()) + } +} + impl Transcript { #[allow(non_snake_case)] - fn check_sizes(&self, sc: &WeightedConfig) -> anyhow::Result<()> { + fn check_sizes(&self, sc: &WeightedConfigBlstrs) -> anyhow::Result<()> { let W = sc.get_total_weight(); if self.V.len() != W + 1 { @@ -439,7 +451,7 @@ impl Transcript { #[allow(non_snake_case, unused)] fn slow_verify( &self, - sc: &WeightedConfig, + sc: &WeightedConfigBlstrs, pp: &das::PublicParameters, eks: &Vec, ) -> anyhow::Result<()> { diff --git a/crates/aptos-dkg/src/pvss/dealt_pub_key.rs b/crates/aptos-dkg/src/pvss/dealt_pub_key.rs index 822cd8d921c..60ac4216e00 100644 --- a/crates/aptos-dkg/src/pvss/dealt_pub_key.rs +++ b/crates/aptos-dkg/src/pvss/dealt_pub_key.rs @@ -3,8 +3,8 @@ macro_rules! dealt_pub_key_impl { ($GT_PROJ_NUM_BYTES:ident, $gt_proj_from_bytes:ident, $GTProjective:ident) => { - use crate::{constants::$GT_PROJ_NUM_BYTES, utils::serialization::$gt_proj_from_bytes}; use aptos_crypto::{ + blstrs::{$GT_PROJ_NUM_BYTES, $gt_proj_from_bytes}, CryptoMaterialError, ValidCryptoMaterial, ValidCryptoMaterialStringExt, }; use aptos_crypto_derive::{DeserializeKey, SerializeKey}; diff --git a/crates/aptos-dkg/src/pvss/dealt_secret_key.rs b/crates/aptos-dkg/src/pvss/dealt_secret_key.rs index eb8ee26a263..2f45ded3c6b 100644 --- a/crates/aptos-dkg/src/pvss/dealt_secret_key.rs +++ b/crates/aptos-dkg/src/pvss/dealt_secret_key.rs @@ -9,20 +9,24 @@ macro_rules! dealt_secret_key_impl { $GTProjective:ident, $gt:ident ) => { + use aptos_crypto::blstrs::{$GT_PROJ_NUM_BYTES, $gt_proj_from_bytes}; use crate::{ algebra::lagrange::lagrange_coefficients, - constants::$GT_PROJ_NUM_BYTES, pvss::{ - dealt_secret_key_share::$gt::DealtSecretKeyShare, player::Player, - threshold_config::ThresholdConfig, traits, traits::SecretSharingConfig, + dealt_secret_key_share::$gt::DealtSecretKeyShare, + threshold_config::ThresholdConfigBlstrs, }, - utils::{serialization::$gt_proj_from_bytes, $gt_multi_exp}, + utils::{$gt_multi_exp}, }; use aptos_crypto::CryptoMaterialError; use aptos_crypto_derive::{SilentDebug, SilentDisplay}; use blstrs::{$GTProjective, Scalar}; use ff::Field; use more_asserts::{assert_ge, assert_le}; + use aptos_crypto::traits::{SecretSharingConfig as _}; + use aptos_crypto::traits::{ThresholdConfig as _}; + use aptos_crypto::arkworks::shamir::Reconstructable; + use aptos_crypto::arkworks::shamir::ShamirShare; /// The size of a serialized *dealt secret key*. pub(crate) const DEALT_SK_NUM_BYTES: usize = $GT_PROJ_NUM_BYTES; @@ -79,12 +83,12 @@ macro_rules! dealt_secret_key_impl { } } - impl traits::Reconstructable for DealtSecretKey { - type Share = DealtSecretKeyShare; + impl Reconstructable for DealtSecretKey { + type ShareValue = DealtSecretKeyShare; /// Reconstructs the `DealtSecretKey` given a sufficiently-large subset of shares from players. /// Mainly used for testing the PVSS transcript dealing and decryption. - fn reconstruct(sc: &ThresholdConfig, shares: &Vec<(Player, Self::Share)>) -> Self { + fn reconstruct(sc: &ThresholdConfigBlstrs, shares: &[ShamirShare]) -> anyhow::Result { assert_ge!(shares.len(), sc.get_threshold()); assert_le!(shares.len(), sc.get_total_num_players()); @@ -112,9 +116,9 @@ macro_rules! dealt_secret_key_impl { assert_eq!(lagr.len(), bases.len()); - DealtSecretKey { + Ok(DealtSecretKey { h_hat: $gt_multi_exp(bases.as_slice(), lagr.as_slice()), - } + }) } } }; diff --git a/crates/aptos-dkg/src/pvss/encryption_dlog.rs b/crates/aptos-dkg/src/pvss/encryption_dlog.rs index 102931a29a7..3d09b21865c 100644 --- a/crates/aptos-dkg/src/pvss/encryption_dlog.rs +++ b/crates/aptos-dkg/src/pvss/encryption_dlog.rs @@ -49,13 +49,7 @@ macro_rules! encryption_dlog_pp_impl { /// any function of the SK via the `crate::pvss::traits::Convert` trait (e.g., $pk = h^{sk^{-1}}$). macro_rules! encryption_dlog_keys_impl { ($GT_PROJ_NUM_BYTES:ident, $gt_proj_from_bytes:ident, $GTProjective:ident) => { - use crate::{ - constants::{$GT_PROJ_NUM_BYTES, SCALAR_NUM_BYTES}, - utils::{ - random::random_scalar, - serialization::{scalar_from_bytes_le, $gt_proj_from_bytes}, - }, - }; + use aptos_crypto::blstrs::{$GT_PROJ_NUM_BYTES, $gt_proj_from_bytes, random_scalar, scalar_from_bytes_le, SCALAR_NUM_BYTES}; use aptos_crypto::{ CryptoMaterialError, Length, Uniform, ValidCryptoMaterial, ValidCryptoMaterialStringExt, }; diff --git a/crates/aptos-dkg/src/pvss/encryption_elgamal.rs b/crates/aptos-dkg/src/pvss/encryption_elgamal.rs index 00d783ecfdc..5b7500b0cff 100644 --- a/crates/aptos-dkg/src/pvss/encryption_elgamal.rs +++ b/crates/aptos-dkg/src/pvss/encryption_elgamal.rs @@ -5,8 +5,8 @@ /// is the message base and $g$ is the PK base. macro_rules! encryption_elgamal_pp_impl { ($GT_PROJ_NUM_BYTES:ident, $gt_proj_from_bytes:ident, $GTProjective:ident) => { - use crate::{constants::$GT_PROJ_NUM_BYTES, utils::serialization::$gt_proj_from_bytes}; use aptos_crypto::{ + blstrs::{$GT_PROJ_NUM_BYTES, $gt_proj_from_bytes}, CryptoMaterialError, ValidCryptoMaterial, ValidCryptoMaterialStringExt, }; use aptos_crypto_derive::{DeserializeKey, SerializeKey}; diff --git a/crates/aptos-dkg/src/pvss/fiat_shamir.rs b/crates/aptos-dkg/src/pvss/fiat_shamir.rs deleted file mode 100644 index 57929b397b4..00000000000 --- a/crates/aptos-dkg/src/pvss/fiat_shamir.rs +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -//! For what it's worth, I don't understand why the `merlin` library wants the user to first define -//! a trait with their 'append' operations and them implement that trait on `merlin::Transcript`. -//! I also don't understand how that doesn't break the orphan rule in Rust. -//! I suspect the reason they want the developer to do things these ways is to force them to cleanly -//! define all the things that are appended to the transcript. - -use crate::{ - pvss::{threshold_config::ThresholdConfig, traits::Transcript}, - utils::random::random_scalar_from_uniform_bytes, - SCALAR_NUM_BYTES, -}; -use aptos_crypto::ValidCryptoMaterial; -use blstrs::Scalar; -use ff::PrimeField; -use serde::Serialize; - -pub const PVSS_DOM_SEP: &[u8; 21] = b"APTOS_SCRAPE_PVSS_DST"; - -#[allow(non_snake_case)] -pub trait FiatShamirProtocol { - /// Append a domain separator for the PVSS protocol, consisting of a sharing configuration `sc`, - /// which locks in the $t$ out of $n$ threshold. - fn pvss_domain_sep(&mut self, sc: &ThresholdConfig); - - /// Append the public parameters `pp`. - fn append_public_parameters(&mut self, pp: &T::PublicParameters); - - /// Append the signing pub keys. - fn append_signing_pub_keys(&mut self, spks: &Vec); - - /// Append the encryption keys `eks`. - fn append_encryption_keys(&mut self, eks: &Vec); - - /// Append the aux data. - fn append_auxs(&mut self, aux: &Vec); - - /// Appends the transcript - fn append_transcript(&mut self, trx: &T); - - /// Returns a random dual-code word check polynomial for the SCRAPE LDT test. - fn challenge_dual_code_word_polynomial(&mut self, t: usize, n: usize) -> Vec; - - /// Returns one or more scalars `r` useful for doing linear combinations (e.g., combining - /// pairings in the SCRAPE multipairing check using coefficients $1, r, r^2, r^3, \ldots$ - fn challenge_linear_combination_scalars(&mut self, num_scalars: usize) -> Vec; - - #[allow(dead_code)] - fn challenge_linear_combination_128bit(&mut self, num_scalars: usize) -> Vec; -} - -#[allow(non_snake_case)] -impl FiatShamirProtocol for merlin::Transcript { - fn pvss_domain_sep(&mut self, sc: &ThresholdConfig) { - self.append_message(b"dom-sep", PVSS_DOM_SEP); - self.append_message(b"scheme-name", T::scheme_name().as_bytes()); - self.append_u64(b"t", sc.t as u64); - self.append_u64(b"n", sc.n as u64); - } - - fn append_public_parameters(&mut self, pp: &T::PublicParameters) { - self.append_message(b"pp", pp.to_bytes().as_slice()); - } - - fn append_signing_pub_keys(&mut self, spks: &Vec) { - self.append_u64(b"signing-pub-keys", spks.len() as u64); - - for spk in spks { - self.append_message(b"spk", spk.to_bytes().as_slice()) - } - } - - fn append_encryption_keys(&mut self, eks: &Vec) { - self.append_u64(b"encryption-keys", eks.len() as u64); - - for ek in eks { - self.append_message(b"ek", ek.to_bytes().as_slice()) - } - } - - fn append_auxs(&mut self, auxs: &Vec) { - self.append_u64(b"auxs", auxs.len() as u64); - - for aux in auxs { - let aux_bytes = bcs::to_bytes(aux).expect("aux data serialization should succeed"); - self.append_message(b"aux", aux_bytes.as_slice()) - } - } - - fn append_transcript(&mut self, trx: &T) { - self.append_message(b"transcript", trx.to_bytes().as_slice()); - } - - fn challenge_dual_code_word_polynomial(&mut self, t: usize, n_plus_1: usize) -> Vec { - let num_coeffs = n_plus_1 - t; - - let num_bytes = num_coeffs * 2 * SCALAR_NUM_BYTES; - let mut buf = vec![0u8; num_bytes]; - - self.challenge_bytes(b"challenge_dual_code_word_polynomial", &mut buf); - - let mut f = Vec::with_capacity(num_coeffs); - - for chunk in buf.chunks(2 * SCALAR_NUM_BYTES) { - match chunk.try_into() { - Ok(chunk) => { - f.push(random_scalar_from_uniform_bytes(chunk)); - }, - Err(_) => panic!("Expected a slice of size 64, but got a different size"), - } - } - - assert_eq!(f.len(), num_coeffs); - - f - } - - fn challenge_linear_combination_scalars(&mut self, num_scalars: usize) -> Vec { - let mut buf = vec![0u8; num_scalars * 2 * SCALAR_NUM_BYTES]; - self.challenge_bytes(b"challenge_linear_combination", &mut buf); - - let mut v = Vec::with_capacity(num_scalars); - - // To ensure we pick a uniform Scalar, we sample twice the number of bytes in a scalar and - // reduce those bytes modulo the order of the scalar field. - for chunk in buf.chunks(2 * SCALAR_NUM_BYTES) { - match chunk.try_into() { - Ok(chunk) => { - v.push(random_scalar_from_uniform_bytes(chunk)); - }, - Err(_) => panic!("Expected a 64-byte slice, but got a different size"), - } - } - - assert_eq!(v.len(), num_scalars); - - v - } - - fn challenge_linear_combination_128bit(&mut self, num_scalars: usize) -> Vec { - let mut buf = vec![0u8; num_scalars * 16]; - self.challenge_bytes(b"challenge_linear_combination", &mut buf); - - let mut v = Vec::with_capacity(num_scalars); - - for chunk in buf.chunks(16) { - match chunk.try_into() { - Ok(chunk) => { - v.push(Scalar::from_u128(u128::from_le_bytes(chunk))); - }, - Err(_) => panic!("Expected a 16-byte slice, but got a different size"), - } - } - - assert_eq!(v.len(), num_scalars); - - v - } -} - -/// Securely derives a Fiat-Shamir challenge via Merlin. -/// Returns (n+1-t) random scalars for the SCRAPE LDT test (i.e., the random polynomial itself). -/// Additionally returns `num_scalars` random scalars for some linear combinations. -pub(crate) fn fiat_shamir( - trx: &T, - sc: &ThresholdConfig, - pp: &T::PublicParameters, - spks: &Vec, - eks: &Vec, - auxs: &Vec, - dst: &'static [u8], - num_scalars: usize, -) -> (Vec, Vec) { - let mut fs_t = merlin::Transcript::new(dst); - - >::pvss_domain_sep(&mut fs_t, sc); - >::append_public_parameters(&mut fs_t, pp); - >::append_signing_pub_keys(&mut fs_t, spks); - >::append_encryption_keys(&mut fs_t, eks); - >::append_auxs(&mut fs_t, auxs); - >::append_transcript(&mut fs_t, trx); - - ( - >::challenge_dual_code_word_polynomial( - &mut fs_t, - sc.t, - sc.n + 1, - ), - >::challenge_linear_combination_scalars( - &mut fs_t, - num_scalars, - ), - ) -} diff --git a/crates/aptos-dkg/src/pvss/input_secret.rs b/crates/aptos-dkg/src/pvss/input_secret.rs deleted file mode 100644 index 3773841fdaf..00000000000 --- a/crates/aptos-dkg/src/pvss/input_secret.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::utils::random::random_scalar; -use aptos_crypto::Uniform; -use aptos_crypto_derive::{SilentDebug, SilentDisplay}; -use blstrs::Scalar; -use ff::Field; -use num_traits::Zero; -use rand_core::{CryptoRng, RngCore}; -use std::ops::{Add, AddAssign}; - -/// The *input secret* that will be given as input to the PVSS dealing algorithm. This will be of a -/// different type than the *dealt secret* that will be returned by the PVSS reconstruction algorithm. -/// -/// This secret will NOT need to be stored by validators because a validator (1) picks such a secret -/// and (2) deals it via the PVSS. If the validator crashes during dealing, the entire task will be -/// restarted with a freshly-generated input secret. -#[derive(SilentDebug, SilentDisplay, PartialEq)] -pub struct InputSecret { - /// The actual secret being dealt; a scalar $a \in F$. - a: Scalar, -} - -/// Make sure input secrets can be added together. -impl Add<&InputSecret> for InputSecret { - type Output = InputSecret; - - fn add(self, rhs: &InputSecret) -> Self::Output { - InputSecret { - a: self.a.add(rhs.a), - } - } -} - -impl AddAssign<&InputSecret> for InputSecret { - fn add_assign(&mut self, rhs: &InputSecret) { - self.a.add_assign(rhs.a) - } -} - -impl Add for InputSecret { - type Output = InputSecret; - - fn add(self, rhs: InputSecret) -> Self::Output { - InputSecret { - a: self.a.add(rhs.a), - } - } -} - -impl Zero for InputSecret { - fn zero() -> Self { - InputSecret { a: Scalar::ZERO } - } - - fn is_zero(&self) -> bool { - self.a.is_zero_vartime() - } -} - -#[cfg(feature = "assert-private-keys-not-cloneable")] -static_assertions::assert_not_impl_any!(InputSecret: Clone); - -impl InputSecret { - pub fn get_secret_a(&self) -> &Scalar { - &self.a - } -} - -impl Uniform for InputSecret { - fn generate(rng: &mut R) -> Self - where - R: RngCore + CryptoRng, - { - let a = random_scalar(rng); - - InputSecret { a } - } -} diff --git a/crates/aptos-dkg/src/pvss/insecure_field/transcript.rs b/crates/aptos-dkg/src/pvss/insecure_field/transcript.rs index 97a7b645612..042ed0e5f7f 100644 --- a/crates/aptos-dkg/src/pvss/insecure_field/transcript.rs +++ b/crates/aptos-dkg/src/pvss/insecure_field/transcript.rs @@ -3,19 +3,21 @@ use crate::{ algebra::polynomials::shamir_secret_share, - pvss, pvss::{ - das, encryption_dlog, traits, - traits::{transcript::MalleableTranscript, Convert, SecretSharingConfig}, - Player, ThresholdConfig, + self, das, encryption_dlog, + traits::{self, transcript::MalleableTranscript, Convert}, + Player, ThresholdConfigBlstrs, }, + traits::transcript::Aggregatable, utils::{ random::{insecure_random_g2_points, random_scalars}, HasMultiExp, }, }; use anyhow::bail; -use aptos_crypto::{bls12381, CryptoMaterialError, ValidCryptoMaterial}; +use aptos_crypto::{ + bls12381, traits::SecretSharingConfig as _, CryptoMaterialError, ValidCryptoMaterial, +}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use blstrs::{G2Projective, Scalar}; use rand::thread_rng; @@ -63,10 +65,14 @@ impl traits::Transcript for Transcript { type EncryptPubKey = encryption_dlog::g1::EncryptPubKey; type InputSecret = pvss::input_secret::InputSecret; type PublicParameters = das::PublicParameters; - type SecretSharingConfig = ThresholdConfig; + type SecretSharingConfig = ThresholdConfigBlstrs; type SigningPubKey = bls12381::PublicKey; type SigningSecretKey = bls12381::PrivateKey; + fn dst() -> Vec { + b"APTOS_INSECURE_FIELD_PVSS_FIAT_SHAMIR_DST".to_vec() + } + fn scheme_name() -> String { "insecure_field_pvss".to_string() } @@ -76,6 +82,7 @@ impl traits::Transcript for Transcript { sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, _ssk: &Self::SigningSecretKey, + _spk: &Self::SigningPubKey, eks: &Vec, s: &Self::InputSecret, _aux: &A, @@ -150,21 +157,6 @@ impl traits::Transcript for Transcript { self.dealers.clone() } - fn aggregate_with(&mut self, sc: &Self::SecretSharingConfig, other: &Transcript) { - debug_assert_eq!(self.C.len(), sc.n); - debug_assert_eq!(self.V.len(), sc.n + 1); - - for i in 0..sc.n { - self.C[i] += other.C[i]; - self.V[i] += other.V[i]; - } - self.V[sc.n] += other.V[sc.n]; - self.dealers.extend_from_slice(other.dealers.as_slice()); - - debug_assert_eq!(self.C.len(), other.C.len()); - debug_assert_eq!(self.V.len(), other.V.len()); - } - fn get_public_key_share( &self, _sc: &Self::SecretSharingConfig, @@ -182,12 +174,17 @@ impl traits::Transcript for Transcript { sc: &Self::SecretSharingConfig, player: &Player, _dk: &Self::DecryptPrivKey, + _pp: &Self::PublicParameters, ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare) { (self.C[player.id], self.get_public_key_share(sc, player)) } #[allow(non_snake_case)] - fn generate(sc: &Self::SecretSharingConfig, rng: &mut R) -> Self + fn generate( + sc: &Self::SecretSharingConfig, + _pp: &Self::PublicParameters, + rng: &mut R, + ) -> Self where R: rand_core::RngCore + rand_core::CryptoRng, { @@ -199,6 +196,29 @@ impl traits::Transcript for Transcript { } } +impl Aggregatable for Transcript { + fn aggregate_with( + &mut self, + sc: &ThresholdConfigBlstrs, + other: &Transcript, + ) -> anyhow::Result<()> { + debug_assert_eq!(self.C.len(), sc.n); + debug_assert_eq!(self.V.len(), sc.n + 1); + + for i in 0..sc.n { + self.C[i] += other.C[i]; + self.V[i] += other.V[i]; + } + self.V[sc.n] += other.V[sc.n]; + self.dealers.extend_from_slice(other.dealers.as_slice()); + + debug_assert_eq!(self.C.len(), other.C.len()); + debug_assert_eq!(self.V.len(), other.V.len()); + + Ok(()) + } +} + impl MalleableTranscript for Transcript { fn maul_signature( &mut self, diff --git a/crates/aptos-dkg/src/pvss/low_degree_test.rs b/crates/aptos-dkg/src/pvss/low_degree_test.rs index 930820213a6..2a924e2c534 100644 --- a/crates/aptos-dkg/src/pvss/low_degree_test.rs +++ b/crates/aptos-dkg/src/pvss/low_degree_test.rs @@ -240,9 +240,10 @@ impl<'a> LowDegreeTest<'a> { mod test { use crate::{ algebra::{evaluation_domain::BatchEvaluationDomain, fft::fft_assign}, - pvss::{test_utils, LowDegreeTest, ThresholdConfig}, + pvss::{test_utils, LowDegreeTest, ThresholdConfigBlstrs}, utils::random::random_scalars, }; + use aptos_crypto::traits::ThresholdConfig as _; use blstrs::Scalar; use rand::{prelude::ThreadRng, thread_rng}; @@ -278,8 +279,8 @@ mod test { for t in 1..8 { for n in (t + 1)..(3 * t + 1) { - let sc = ThresholdConfig::new(t, n).unwrap(); - let sc_higher_degree = ThresholdConfig::new(sc.t + 1, sc.n).unwrap(); + let sc = ThresholdConfigBlstrs::new(t, n).unwrap(); + let sc_higher_degree = ThresholdConfigBlstrs::new(sc.t + 1, sc.n).unwrap(); // A degree t polynomial p(X), higher by 1 than what the LDT expects let (p_0, batch_dom, mut evals) = @@ -301,7 +302,7 @@ mod test { fn random_polynomial_evals( mut rng: &mut ThreadRng, - sc: &ThresholdConfig, + sc: &ThresholdConfigBlstrs, ) -> (Scalar, BatchEvaluationDomain, Vec) { let p = random_scalars(sc.t, &mut rng); let p_0 = p[0]; diff --git a/crates/aptos-dkg/src/pvss/mod.rs b/crates/aptos-dkg/src/pvss/mod.rs index 44dce33ed41..21daf214cda 100644 --- a/crates/aptos-dkg/src/pvss/mod.rs +++ b/crates/aptos-dkg/src/pvss/mod.rs @@ -1,6 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +pub mod chunky; mod contribution; pub mod das; pub(crate) mod dealt_pub_key; @@ -9,19 +10,17 @@ pub mod dealt_secret_key; pub(crate) mod dealt_secret_key_share; pub mod encryption_dlog; pub(crate) mod encryption_elgamal; -mod fiat_shamir; -pub mod input_secret; pub mod insecure_field; mod low_degree_test; -mod player; -pub mod scalar_secret_key; mod schnorr; pub mod test_utils; -mod threshold_config; pub mod traits; pub mod weighted; +pub use aptos_crypto::{ + blstrs::{scalar_secret_key, threshold_config, threshold_config::ThresholdConfigBlstrs}, + input_secret, + player::Player, +}; pub use low_degree_test::LowDegreeTest; -pub use player::Player; -pub use threshold_config::ThresholdConfig; -pub use weighted::{GenericWeighting, WeightedConfig}; +pub use weighted::{GenericWeighting, WeightedConfigBlstrs}; diff --git a/crates/aptos-dkg/src/pvss/player.rs b/crates/aptos-dkg/src/pvss/player.rs deleted file mode 100644 index 874d6977de6..00000000000 --- a/crates/aptos-dkg/src/pvss/player.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use serde::{Deserialize, Serialize}; - -/// An identifier from 0 to n-1 for the n players involved in the PVSS protocol. -#[derive(Copy, Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] -pub struct Player { - /// A number from 0 to n-1. - pub id: usize, -} - -impl Player { - pub fn get_id(&self) -> usize { - self.id - } -} diff --git a/crates/aptos-dkg/src/pvss/scalar_secret_key.rs b/crates/aptos-dkg/src/pvss/scalar_secret_key.rs deleted file mode 100644 index ef6dddcf107..00000000000 --- a/crates/aptos-dkg/src/pvss/scalar_secret_key.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - algebra::lagrange::lagrange_coefficients, - pvss::{ - traits::{Reconstructable, SecretSharingConfig}, - Player, ThresholdConfig, - }, -}; -use blstrs::Scalar; -use ff::Field; -use more_asserts::{assert_ge, assert_le}; - -impl Reconstructable for Scalar { - type Share = Scalar; - - fn reconstruct(sc: &ThresholdConfig, shares: &Vec<(Player, Self::Share)>) -> Self { - assert_ge!(shares.len(), sc.get_threshold()); - assert_le!(shares.len(), sc.get_total_num_players()); - - let ids = shares.iter().map(|(p, _)| p.id).collect::>(); - let lagr = lagrange_coefficients( - sc.get_batch_evaluation_domain(), - ids.as_slice(), - &Scalar::ZERO, - ); - let shares = shares - .iter() - .map(|(_, share)| *share) - .collect::>(); - - assert_eq!(lagr.len(), shares.len()); - - shares - .iter() - .zip(lagr.iter()) - .map(|(&share, &lagr)| share * lagr) - .sum::() - } -} diff --git a/crates/aptos-dkg/src/pvss/schnorr.rs b/crates/aptos-dkg/src/pvss/schnorr.rs index d8d51783908..7838d115b28 100644 --- a/crates/aptos-dkg/src/pvss/schnorr.rs +++ b/crates/aptos-dkg/src/pvss/schnorr.rs @@ -1,9 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::utils::{hash_to_scalar, random::random_scalar, HasMultiExp}; +use crate::utils::{hash_to_scalar, HasMultiExp}; use anyhow::bail; -use aptos_crypto::signing_message; +use aptos_crypto::{blstrs::random_scalar, signing_message}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use blstrs::Scalar; use ff::Field; diff --git a/crates/aptos-dkg/src/pvss/test_utils.rs b/crates/aptos-dkg/src/pvss/test_utils.rs index aa5c8cdfb39..7a79bb6b51f 100644 --- a/crates/aptos-dkg/src/pvss/test_utils.rs +++ b/crates/aptos-dkg/src/pvss/test_utils.rs @@ -2,10 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 use crate::pvss::{ - traits::{transcript::Transcript, Convert, HasEncryptionPublicParams, SecretSharingConfig}, - Player, ThresholdConfig, WeightedConfig, + traits::{ + transcript::{Transcript, WithMaxNumShares}, + Convert, HasEncryptionPublicParams, + }, + Player, ThresholdConfigBlstrs, WeightedConfigBlstrs, +}; +use aptos_crypto::{ + arkworks::shamir::Reconstructable, + traits::{self, SecretSharingConfig as _, ThresholdConfig as _}, + SigningKey, Uniform, }; -use aptos_crypto::{hash::CryptoHash, SigningKey, Uniform}; use num_traits::Zero; use rand::{prelude::ThreadRng, thread_rng}; use serde::Serialize; @@ -48,7 +55,7 @@ pub fn setup_dealing(_: &T) { println!("{}", std::any::type_name::()) } -pub fn get_threshold_config_and_rng(t: usize, n: usize) -> (ThresholdConfig, ThreadRng) { - let sc = ThresholdConfig::new(t, n).unwrap(); +pub fn get_threshold_config_and_rng(t: usize, n: usize) -> (ThresholdConfigBlstrs, ThreadRng) { + let sc = ThresholdConfigBlstrs::new(t, n).unwrap(); (sc, thread_rng()) } @@ -119,16 +126,29 @@ macro_rules! vec_to_str { }; } -use crate::pvss::traits::Reconstructable; #[allow(unused)] pub(crate) use vec_to_str; -pub fn get_threshold_configs_for_testing() -> Vec { +pub fn get_threshold_configs_for_testing() -> Vec { let mut tcs = vec![]; for t in 1..8 { for n in t..8 { - let tc = ThresholdConfig::new(t, n).unwrap(); + let tc = T::new(t, n).unwrap(); + tcs.push(tc) + } + } + + tcs +} + +// When setup is slow, we reduce the number of test cases to keep the tests fast +pub fn get_threshold_configs_for_testing_smaller() -> Vec { + let mut tcs = vec![]; + + for t in 1..4 { + for n in t..5 { + let tc = T::new(t, n).unwrap(); tcs.push(tc) } } @@ -136,57 +156,76 @@ pub fn get_threshold_configs_for_testing() -> Vec { tcs } -pub fn get_weighted_configs_for_testing() -> Vec { +pub fn get_weighted_configs_for_testing() -> Vec { let mut wcs = vec![]; // 1-out-of-1 weighted - wcs.push(WeightedConfig::new(1, vec![1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(1, vec![1]).unwrap()); // 1-out-of-2, weights 2 0 - wcs.push(WeightedConfig::new(1, vec![2]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(1, vec![2]).unwrap()); // 1-out-of-2, weights 1 1 - wcs.push(WeightedConfig::new(1, vec![1, 1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(1, vec![1, 1]).unwrap()); // 2-out-of-2, weights 1 1 - wcs.push(WeightedConfig::new(2, vec![1, 1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(2, vec![1, 1]).unwrap()); // 1-out-of-3, weights 1 1 1 - wcs.push(WeightedConfig::new(1, vec![1, 1, 1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(1, vec![1, 1, 1]).unwrap()); // 2-out-of-3, weights 1 1 1 - wcs.push(WeightedConfig::new(2, vec![1, 1, 1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(2, vec![1, 1, 1]).unwrap()); // 3-out-of-3, weights 1 1 1 - wcs.push(WeightedConfig::new(3, vec![1, 1, 1]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(3, vec![1, 1, 1]).unwrap()); // 3-out-of-5, weights 2 1 2 - wcs.push(WeightedConfig::new(3, vec![2, 1, 2]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(3, vec![2, 1, 2]).unwrap()); // 3-out-of-7, weights 2 3 2 - wcs.push(WeightedConfig::new(3, vec![2, 3, 2]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(3, vec![2, 3, 2]).unwrap()); // 50-out-of-100, weights [11, 13, 9, 10, 12, 8, 7, 14, 10, 6] - wcs.push(WeightedConfig::new(50, vec![11, 13, 9, 10, 12, 8, 7, 14, 10, 6]).unwrap()); + wcs.push(WeightedConfigBlstrs::new(50, vec![11, 13, 9, 10, 12, 8, 7, 14, 10, 6]).unwrap()); // 7-out-of-15, weights [0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0] - wcs.push(WeightedConfig::new(7, vec![0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0]).unwrap()); + wcs.push( + WeightedConfigBlstrs::new(7, vec![0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0]).unwrap(), + ); wcs } -pub fn get_threshold_configs_for_benchmarking() -> Vec { - // [XDL+24] The Latency Price of Threshold Cryptosystem in Blockchains; by Zhuolun Xiang et al; 2024 - vec![ - ThresholdConfig::new(143, 254).unwrap(), // from XDL+24 - ThresholdConfig::new(184, 254).unwrap(), // from XDL+24 - ThresholdConfig::new(548, 821).unwrap(), // from initial deployment - ThresholdConfig::new(333, 1_000).unwrap(), - ThresholdConfig::new(666, 1_000).unwrap(), - ThresholdConfig::new(3_333, 10_000).unwrap(), - ThresholdConfig::new(6_666, 10_000).unwrap(), - ] +pub const BENCHMARK_CONFIGS: &[(usize, usize)] = &[ + (143, 254), + (184, 254), + (548, 821), + (333, 1_000), + (666, 1_000), + (3_333, 10_000), + (6_666, 10_000), +]; + +pub fn get_threshold_configs_for_benchmarking() -> Vec { + BENCHMARK_CONFIGS + .iter() + .map(|&(t, n)| T::new(t, n).unwrap()) + .collect() } -pub fn get_weighted_configs_for_benchmarking() -> Vec { +pub fn get_weighted_configs_for_benchmarking() -> Vec { let mut wcs = vec![]; + // This one was produced mid-Nov 2025 + let weights = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 7, + ]; + let threshold = 129; // slow path + wcs.push(WeightedConfigBlstrs::new(threshold, weights.clone()).unwrap()); + let threshold = 166; // fast path + wcs.push(WeightedConfigBlstrs::new(threshold, weights).unwrap()); + let weights = vec![ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, @@ -196,7 +235,7 @@ pub fn get_weighted_configs_for_benchmarking() -> Vec { ]; let total_weight: usize = weights.iter().sum(); let threshold = total_weight * 2 / 3 + 1; - wcs.push(WeightedConfig::new(threshold, weights).unwrap()); + wcs.push(WeightedConfigBlstrs::new(threshold, weights).unwrap()); let weights = vec![ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -207,7 +246,7 @@ pub fn get_weighted_configs_for_benchmarking() -> Vec { ]; let total_weight: usize = weights.iter().sum(); let threshold = total_weight * 2 / 3 + 1; - wcs.push(WeightedConfig::new(threshold, weights).unwrap()); + wcs.push(WeightedConfigBlstrs::new(threshold, weights).unwrap()); let weights = vec![ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -218,16 +257,17 @@ pub fn get_weighted_configs_for_benchmarking() -> Vec { ]; let total_weight: usize = weights.iter().sum(); let threshold = total_weight * 2 / 3 + 1; - wcs.push(WeightedConfig::new(threshold, weights).unwrap()); + wcs.push(WeightedConfigBlstrs::new(threshold, weights).unwrap()); wcs } -pub fn reconstruct_dealt_secret_key_randomly( +pub fn reconstruct_dealt_secret_key_randomly( sc: &::SecretSharingConfig, rng: &mut R, dks: &Vec<::DecryptPrivKey>, trx: T, + pp: &T::PublicParameters, ) -> ::DealtSecretKey where R: rand_core::RngCore, @@ -237,7 +277,7 @@ where .get_random_eligible_subset_of_players(rng) .into_iter() .map(|p| { - let (sk, pk) = trx.decrypt_own_share(sc, &p, &dks[p.get_id()]); + let (sk, pk) = trx.decrypt_own_share(sc, &p, &dks[p.get_id()], pp); assert_eq!(pk, trx.get_public_key_share(sc, &p)); @@ -245,5 +285,5 @@ where }) .collect::>(); - T::DealtSecretKey::reconstruct(sc, &players_and_shares) + T::DealtSecretKey::reconstruct(sc, &players_and_shares).unwrap() } diff --git a/crates/aptos-dkg/src/pvss/threshold_config.rs b/crates/aptos-dkg/src/pvss/threshold_config.rs deleted file mode 100644 index b3ce08f4333..00000000000 --- a/crates/aptos-dkg/src/pvss/threshold_config.rs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - algebra::evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, - pvss::{traits, Player}, -}; -use anyhow::anyhow; -use rand::{seq::IteratorRandom, Rng}; -use rand_core::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; - -/// Encodes the *threshold configuration* for a normal/unweighted PVSS: i.e., the threshold $t$ and -/// the number of players $n$ such that any $t$ or more players can reconstruct a dealt secret given -/// a PVSS transcript. this is Alin leaving his laptop open again... -#[derive(Clone, PartialEq, Deserialize, Serialize, Debug, Eq)] -pub struct ThresholdConfig { - /// The reconstruction threshold $t$ that must be exceeded in order to reconstruct the dealt - /// secret; i.e., $t$ or more shares are needed - pub(crate) t: usize, - /// The total number of players involved in the PVSS protocol - pub(crate) n: usize, - /// Evaluation domain consisting of the $N$th root of unity and other auxiliary information - /// needed to compute an FFT of size $N$. - dom: EvaluationDomain, - /// Batch evaluation domain, consisting of all the $N$th roots of unity (in the scalar field), - /// where N is the smallest power of two such that n <= N. - batch_dom: BatchEvaluationDomain, -} - -impl ThresholdConfig { - /// Creates a new $t$ out of $n$ secret sharing configuration where any subset of $t$ or more - /// players can reconstruct the secret. - pub fn new(t: usize, n: usize) -> anyhow::Result { - if t == 0 { - return Err(anyhow!("expected the reconstruction threshold to be > 0")); - } - - if n == 0 { - return Err(anyhow!("expected the number of shares to be > 0")); - } - - if t > n { - return Err(anyhow!( - "expected the reconstruction threshold {t} to be < than the number of shares {n}" - )); - } - - let batch_dom = BatchEvaluationDomain::new(n); - let dom = batch_dom.get_subdomain(n); - Ok(ThresholdConfig { - t, - n, - dom, - batch_dom, - }) - } - - /// Returns the threshold $t$. Recall that $\ge t$ shares are needed to reconstruct. - pub fn get_threshold(&self) -> usize { - self.t - } - - pub fn get_batch_evaluation_domain(&self) -> &BatchEvaluationDomain { - &self.batch_dom - } - - pub fn get_evaluation_domain(&self) -> &EvaluationDomain { - &self.dom - } -} - -impl Display for ThresholdConfig { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "threshold/{}-out-of-{}", self.t, self.n) - } -} - -impl traits::SecretSharingConfig for ThresholdConfig { - /// For testing only. - fn get_random_player(&self, rng: &mut R) -> Player - where - R: RngCore + CryptoRng, - { - Player { - id: rng.gen_range(0, self.n), - } - } - - /// For testing only. - fn get_random_eligible_subset_of_players(&self, mut rng: &mut R) -> Vec - where - R: RngCore, - { - (0..self.get_total_num_shares()) - .choose_multiple(&mut rng, self.t) - .into_iter() - .map(|i| self.get_player(i)) - .collect::>() - } - - fn get_total_num_players(&self) -> usize { - self.n - } - - fn get_total_num_shares(&self) -> usize { - self.n - } -} - -#[cfg(test)] -mod test { - use crate::pvss::ThresholdConfig; - - #[test] - fn create_many_configs() { - let mut _tcs = vec![]; - - for t in 1..100 { - for n in t..100 { - _tcs.push(ThresholdConfig::new(t, n).unwrap()) - } - } - } -} diff --git a/crates/aptos-dkg/src/pvss/traits/mod.rs b/crates/aptos-dkg/src/pvss/traits/mod.rs index 5681afc858f..55240cb6e57 100644 --- a/crates/aptos-dkg/src/pvss/traits/mod.rs +++ b/crates/aptos-dkg/src/pvss/traits/mod.rs @@ -3,10 +3,8 @@ pub mod transcript; -use crate::pvss::player::Player; -use more_asserts::assert_lt; -use std::fmt::Display; -pub use transcript::Transcript; +pub use aptos_crypto::arkworks::shamir::Reconstructable; +pub use transcript::{AggregatableTranscript, Transcript}; /// Converts a type `Self` to `ToType` using auxiliary data from type `AuxType`. pub trait Convert { @@ -19,35 +17,3 @@ pub trait HasEncryptionPublicParams { fn get_encryption_public_params(&self) -> &Self::EncryptionPublicParameters; } - -pub trait SecretSharingConfig: Display { - /// Creates a new player ID; a number from 0 to `n-1`, where `n = get_total_num_players(&self)`. - fn get_player(&self, i: usize) -> Player { - let n = self.get_total_num_players(); - assert_lt!(i, n); - - Player { id: i } - } - - /// Useful during testing. - fn get_random_player(&self, rng: &mut R) -> Player - where - R: rand_core::RngCore + rand_core::CryptoRng; - - /// Returns a random subset of players who are capable of reconstructing the secret. - /// Useful during testing. - fn get_random_eligible_subset_of_players(&self, rng: &mut R) -> Vec - where - R: rand_core::RngCore; - - fn get_total_num_players(&self) -> usize; - - fn get_total_num_shares(&self) -> usize; -} - -/// All dealt secret keys should be reconstructable from a subset of \[dealt secret key\] shares. -pub trait Reconstructable { - type Share: Clone; - - fn reconstruct(sc: &SSC, shares: &Vec<(Player, Self::Share)>) -> Self; -} diff --git a/crates/aptos-dkg/src/pvss/traits/transcript.rs b/crates/aptos-dkg/src/pvss/traits/transcript.rs index 682d770708b..07f00b7169b 100644 --- a/crates/aptos-dkg/src/pvss/traits/transcript.rs +++ b/crates/aptos-dkg/src/pvss/traits/transcript.rs @@ -48,11 +48,14 @@ //! does not hold. use crate::pvss::{ - traits::{Convert, HasEncryptionPublicParams, Reconstructable, SecretSharingConfig}, + traits::{Convert, HasEncryptionPublicParams}, Player, }; use anyhow::bail; -use aptos_crypto::{SigningKey, Uniform, ValidCryptoMaterial, VerifyingKey}; +use aptos_crypto::{ + arkworks::shamir::Reconstructable, SecretSharingConfig, SigningKey, Uniform, + ValidCryptoMaterial, VerifyingKey, +}; use num_traits::Zero; use serde::{de::DeserializeOwned, Serialize}; use std::{fmt::Debug, ops::AddAssign}; @@ -72,6 +75,7 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { + Eq; type PublicParameters: HasEncryptionPublicParams + + WithMaxNumShares + Default + ValidCryptoMaterial + DeserializeOwned @@ -86,7 +90,7 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { type DealtSecretKeyShare: PartialEq + Clone; type DealtPubKeyShare: Debug + PartialEq + Clone; type DealtSecretKey: PartialEq - + Reconstructable; + + Reconstructable; type DealtPubKey; type InputSecret: Uniform @@ -108,6 +112,9 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { ::EncryptionPublicParameters, >; + /// Domain-separator tag (DST) for the Fiat-Shamir hashing used to derive randomness from the transcript. + fn dst() -> Vec; + /// Return a developer-friendly name of the PVSS scheme (e.g., "vanilla_scrape") that can be /// used in, say, criterion benchmark names. fn scheme_name() -> String; @@ -122,9 +129,10 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, ssk: &Self::SigningSecretKey, + spk: &Self::SigningPubKey, eks: &Vec, s: &Self::InputSecret, - aux: &A, + session_id: &A, dealer: &Player, rng: &mut R, ) -> Self; @@ -142,7 +150,7 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { pp: &Self::PublicParameters, spks: &Vec, eks: &Vec, - aux: &Vec, + session_ids: &Vec, ) -> anyhow::Result<()>; /// Returns the set of player IDs who have contributed to this transcript. @@ -151,28 +159,6 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { /// other transcripts, in which case the set will be of size `n`. fn get_dealers(&self) -> Vec; - /// Aggregates two transcripts. - fn aggregate_with(&mut self, sc: &Self::SecretSharingConfig, other: &Self); - - /// Helper function for aggregating a vector of transcripts - fn aggregate(sc: &Self::SecretSharingConfig, mut trxs: Vec) -> anyhow::Result { - if trxs.is_empty() { - bail!("Cannot aggregate empty vector of transcripts") - } - - let n = trxs.len(); - let (first, last) = trxs.split_at_mut(1); - - for other in last { - first[0].aggregate_with(sc, other); - } - - trxs.truncate(1); - let trx = trxs.pop().unwrap(); - assert_eq!(trx.get_dealers().len(), n); - Ok(trx) - } - /// Returns the dealt pubkey shore of `player`. fn get_public_key_share( &self, @@ -191,15 +177,62 @@ pub trait Transcript: Debug + ValidCryptoMaterial + Clone + PartialEq + Eq { sc: &Self::SecretSharingConfig, player: &Player, dk: &Self::DecryptPrivKey, + pp: &Self::PublicParameters, ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare); /// Generates a random looking transcript (but not a valid one). /// Useful for testing and benchmarking. - fn generate(sc: &Self::SecretSharingConfig, rng: &mut R) -> Self + fn generate( + sc: &Self::SecretSharingConfig, + pp: &Self::PublicParameters, + rng: &mut R, + ) -> Self where R: rand_core::RngCore + rand_core::CryptoRng; } +pub trait Aggregatable: Sized { + // Sized was somehow needed for the type alias below + /// Aggregates two transcripts using a generic config type. + fn aggregate_with(&mut self, sc: &C, other: &Self) -> anyhow::Result<()>; + + /// Helper function for aggregating a vector of transcripts. + /// Used primarily for benchmarks and tests. + fn aggregate(sc: &C, mut trxs: Vec) -> anyhow::Result { + if trxs.is_empty() { + bail!("Cannot aggregate empty vector of transcripts"); + } + + let (first, rest) = trxs.split_at_mut(1); + + for other in rest { + first[0].aggregate_with(sc, other)?; + } + + // `first[0]` has accumulated everything, return it + trxs.truncate(1); + let trx = trxs.pop().unwrap(); + + Ok(trx) + } +} + +/// Workaround for the trait alias `AggregatableTranscript = Transcript + Aggregatable<::SecretSharingConfig>` +pub trait AggregatableTranscript: + Transcript + Aggregatable<::SecretSharingConfig> +{ +} +impl AggregatableTranscript for T where + T: Transcript + Aggregatable<::SecretSharingConfig> +{ +} + +pub trait HasAggregatableSubtranscript { + type SubTranscript: Aggregatable; + + fn get_subtranscript(&self) -> Self::SubTranscript; +} + /// This traits defines testing-only and benchmarking-only interfaces. pub trait MalleableTranscript: Transcript { /// This is useful for generating many PVSS transcripts from different dealers from a single @@ -208,7 +241,15 @@ pub trait MalleableTranscript: Transcript { fn maul_signature( &mut self, ssk: &Self::SigningSecretKey, - aux: &A, + session_id: &A, dealer: &Player, ); } + +/// This is needed instead of Default because `max_n` influences the public parameters of the DeKARTv2 range proof, and hence the public parameters of `chunky` +pub trait WithMaxNumShares { + fn with_max_num_shares(n: usize) -> Self; + + /// This is a modified function which might create public parameters that are fairly nonsensical, but which are sufficient for `generate()` + fn with_max_num_shares_for_generate(n: usize) -> Self; +} diff --git a/crates/aptos-dkg/src/pvss/weighted/generic_weighting.rs b/crates/aptos-dkg/src/pvss/weighted/generic_weighting.rs index a3891cebf3e..c4932d64617 100644 --- a/crates/aptos-dkg/src/pvss/weighted/generic_weighting.rs +++ b/crates/aptos-dkg/src/pvss/weighted/generic_weighting.rs @@ -6,10 +6,17 @@ /// WARNING: This will **NOT** necessarily be secure for any PVSS scheme, since it will reuse encryption /// keys, which might not be safe depending on the PVSS scheme. use crate::pvss::{ - traits::{transcript::MalleableTranscript, Reconstructable, SecretSharingConfig, Transcript}, - Player, ThresholdConfig, WeightedConfig, + traits::{ + transcript::{AggregatableTranscript, MalleableTranscript}, + Transcript, + }, + Player, ThresholdConfigBlstrs, WeightedConfigBlstrs, +}; +use crate::traits::transcript::Aggregatable; +use aptos_crypto::{ + traits::SecretSharingConfig as _, weighted_config::WeightedConfig, CryptoMaterialError, + ValidCryptoMaterial, }; -use aptos_crypto::{CryptoMaterialError, ValidCryptoMaterial}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use rand_core::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; @@ -22,37 +29,6 @@ pub struct GenericWeighting { trx: T, } -/// Implements weighted reconstruction of a secret `SK` through the existing unweighted reconstruction -/// implementation of `SK`. -impl> Reconstructable for SK { - type Share = Vec; - - fn reconstruct(sc: &WeightedConfig, shares: &Vec<(Player, Self::Share)>) -> Self { - let mut flattened_shares = Vec::with_capacity(sc.get_total_weight()); - - // println!(); - for (player, sub_shares) in shares { - // println!( - // "Flattening {} share(s) for player {player}", - // sub_shares.len() - // ); - for (pos, share) in sub_shares.iter().enumerate() { - let virtual_player = sc.get_virtual_player(player, pos); - - // println!( - // " + Adding share {pos} as virtual player {virtual_player}: {:?}", - // share - // ); - // TODO(Performance): Avoiding the cloning here might be nice - let tuple = (virtual_player, share.clone()); - flattened_shares.push(tuple); - } - } - - SK::reconstruct(sc.get_threshold_config(), &flattened_shares) - } -} - impl ValidCryptoMaterial for GenericWeighting { const AIP_80_PREFIX: &'static str = ""; @@ -71,7 +47,7 @@ impl TryFrom<&[u8]> for GenericWeighting { impl GenericWeighting { fn to_weighted_encryption_keys( - sc: &WeightedConfig, + sc: &WeightedConfigBlstrs, eks: &Vec, ) -> Vec { // Re-organize the encryption key vector so that we deal multiple shares to each player, @@ -90,7 +66,9 @@ impl GenericWeighting { } } -impl> Transcript for GenericWeighting { +impl> Transcript + for GenericWeighting +{ type DealtPubKey = T::DealtPubKey; type DealtPubKeyShare = Vec; type DealtSecretKey = T::DealtSecretKey; @@ -101,10 +79,17 @@ impl> Transcript for Generi type EncryptPubKey = T::EncryptPubKey; type InputSecret = T::InputSecret; type PublicParameters = T::PublicParameters; - type SecretSharingConfig = WeightedConfig; + type SecretSharingConfig = WeightedConfigBlstrs; + // Can probably change this to T::SecretSharingConfig, after editing Reconstructable... but not worth the effort atm type SigningPubKey = T::SigningPubKey; type SigningSecretKey = T::SigningSecretKey; + fn dst() -> Vec { + let mut result = b"WEIGHTED_".to_vec(); + result.extend(T::dst()); + result + } + fn scheme_name() -> String { format!("generic_weighted_{}", T::scheme_name()) } @@ -113,6 +98,7 @@ impl> Transcript for Generi sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, ssk: &Self::SigningSecretKey, + spk: &Self::SigningPubKey, eks: &Vec, s: &Self::InputSecret, aux: &A, @@ -127,6 +113,7 @@ impl> Transcript for Generi sc.get_threshold_config(), pp, ssk, + spk, &duplicated_eks, s, aux, @@ -160,10 +147,6 @@ impl> Transcript for Generi T::get_dealers(&self.trx) } - fn aggregate_with(&mut self, sc: &Self::SecretSharingConfig, other: &Self) { - T::aggregate_with(&mut self.trx, sc.get_threshold_config(), &other.trx) - } - fn get_public_key_share( &self, sc: &Self::SecretSharingConfig, @@ -195,6 +178,7 @@ impl> Transcript for Generi sc: &Self::SecretSharingConfig, player: &Player, dk: &Self::DecryptPrivKey, + pp: &Self::PublicParameters, ) -> (Self::DealtSecretKeyShare, Self::DealtPubKeyShare) { let weight = sc.get_player_weight(player); @@ -204,8 +188,13 @@ impl> Transcript for Generi for i in 0..weight { // println!("Decrypting share {i} for player {player} with DK {:?}", dk); let virtual_player = sc.get_virtual_player(player, i); - let (dsk_share, dpk_share) = - T::decrypt_own_share(&self.trx, sc.get_threshold_config(), &virtual_player, dk); + let (dsk_share, dpk_share) = T::decrypt_own_share( + &self.trx, + sc.get_threshold_config(), + &virtual_player, + dk, + pp, + ); weighted_dsk_share.push(dsk_share); weighted_dpk_share.push(dpk_share); } @@ -213,17 +202,31 @@ impl> Transcript for Generi (weighted_dsk_share, weighted_dpk_share) } - fn generate(sc: &Self::SecretSharingConfig, rng: &mut R) -> Self + fn generate(sc: &Self::SecretSharingConfig, pp: &Self::PublicParameters, rng: &mut R) -> Self where R: RngCore + CryptoRng, { GenericWeighting { - trx: T::generate(sc.get_threshold_config(), rng), + trx: T::generate(sc.get_threshold_config(), pp, rng), } } } -impl> MalleableTranscript +impl Aggregatable> for GenericWeighting +where + T: AggregatableTranscript + Transcript, +{ + fn aggregate_with( + &mut self, + sc: &WeightedConfig, + other: &Self, + ) -> anyhow::Result<()> { + T::aggregate_with(&mut self.trx, sc.get_threshold_config(), &other.trx)?; + Ok(()) + } +} + +impl> MalleableTranscript for GenericWeighting { fn maul_signature( diff --git a/crates/aptos-dkg/src/pvss/weighted/mod.rs b/crates/aptos-dkg/src/pvss/weighted/mod.rs index 3f41a781277..46a4146aac2 100644 --- a/crates/aptos-dkg/src/pvss/weighted/mod.rs +++ b/crates/aptos-dkg/src/pvss/weighted/mod.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 pub mod generic_weighting; -mod weighted_config; +pub use aptos_crypto::weighted_config::WeightedConfigBlstrs; pub use generic_weighting::GenericWeighting; -pub use weighted_config::WeightedConfig; diff --git a/crates/aptos-dkg/src/pvss/weighted/weighted_config.rs b/crates/aptos-dkg/src/pvss/weighted/weighted_config.rs deleted file mode 100644 index f5adc881040..00000000000 --- a/crates/aptos-dkg/src/pvss/weighted/weighted_config.rs +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - algebra::evaluation_domain::{BatchEvaluationDomain, EvaluationDomain}, - pvss::{traits, traits::SecretSharingConfig, Player, ThresholdConfig}, -}; -use anyhow::anyhow; -use more_asserts::assert_lt; -use rand::Rng; -use rand_core::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; - -/// Encodes the *threshold configuration* for a *weighted* PVSS: i.e., the minimum weight $w$ and -/// the total weight $W$ such that any subset of players with weight $\ge w$ can reconstruct a -/// dealt secret given a PVSS transcript. -#[allow(non_snake_case)] -#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] -pub struct WeightedConfig { - /// A weighted config is a $w$-out-of-$W$ threshold config, where $w$ is the minimum weight - /// needed to reconstruct the secret and $W$ is the total weight. - tc: ThresholdConfig, - /// The total number of players in the protocol. - num_players: usize, - /// Each player's weight - weight: Vec, - /// Player's starting index `a` in a vector of all `W` shares, such that this player owns shares - /// `W[a, a + weight[player])`. Useful during weighted secret reconstruction. - starting_index: Vec, - /// The maximum weight of any player. - max_weight: usize, - /// The minimum weight of any player. - min_weight: usize, -} - -impl WeightedConfig { - #[allow(non_snake_case)] - /// Initializes a weighted secret sharing configuration with threshold weight `threshold_weight` - /// and the $i$th player's weight stored in `weight[i]`. - pub fn new(threshold_weight: usize, weights: Vec) -> anyhow::Result { - if threshold_weight == 0 { - return Err(anyhow!( - "expected the minimum reconstruction weight to be > 0" - )); - } - - if weights.is_empty() { - return Err(anyhow!("expected a non-empty vector of player weights")); - } - let max_weight = *weights.iter().max().unwrap(); - let min_weight = *weights.iter().min().unwrap(); - - let n = weights.len(); - let W = weights.iter().sum(); - - // e.g., Suppose the weights for players 0, 1 and 2 are [2, 4, 3] - // Then, our PVSS transcript implementation will store a vector of 2 + 4 + 3 = 9 shares, - // such that: - // - Player 0 will own the shares at indices [0..2), i.e.,starting index 0 - // - Player 1 will own the shares at indices [2..2 + 4) = [2..6), i.e.,starting index 2 - // - Player 2 will own the shares at indices [6, 6 + 3) = [6..9), i.e., starting index 6 - let mut starting_index = Vec::with_capacity(weights.len()); - starting_index.push(0); - - for w in weights.iter().take(n - 1) { - starting_index.push(starting_index.last().unwrap() + w); - } - - let tc = ThresholdConfig::new(threshold_weight, W)?; - Ok(WeightedConfig { - tc, - num_players: n, - weight: weights, - starting_index, - max_weight, - min_weight, - }) - } - - pub fn get_min_weight(&self) -> usize { - self.min_weight - } - - /// Returns _a_ player who has the smallest weight. - pub fn get_min_weight_player(&self) -> Player { - if let Some((i, _weight)) = self - .weight - .iter() - .enumerate() - .min_by_key(|&(_, &weight)| weight) - { - // println!("Player {} has the smallest weight: {}", i, _weight); - self.get_player(i) - } else { - panic!("Weights vector should not be empty"); - } - } - - /// Returns _a_ player who has the largest weight. - pub fn get_max_weight_player(&self) -> Player { - if let Some((i, _weight)) = self - .weight - .iter() - .enumerate() - .max_by_key(|&(_, &weight)| weight) - { - // println!("Player {} has the largest weight: {}", i, _weight); - self.get_player(i) - } else { - panic!("Weights vector should not be empty"); - } - } - - pub fn get_max_weight(&self) -> usize { - self.max_weight - } - - pub fn get_threshold_config(&self) -> &ThresholdConfig { - &self.tc - } - - pub fn get_threshold_weight(&self) -> usize { - self.tc.t - } - - pub fn get_total_weight(&self) -> usize { - self.tc.n - } - - pub fn get_player_weight(&self, player: &Player) -> usize { - self.weight[player.id] - } - - pub fn get_player_starting_index(&self, player: &Player) -> usize { - self.starting_index[player.id] - } - - /// In an unweighted secret sharing scheme, each player has one share. We can weigh such a scheme - /// by splitting a player into as many "virtual" players as that player's weight, assigning one - /// share per "virtual player." - /// - /// This function returns the "virtual" player associated with the $i$th sub-share of this player. - pub fn get_virtual_player(&self, player: &Player, j: usize) -> Player { - // println!("WeightedConfig::get_virtual_player({player}, {i})"); - assert_lt!(j, self.weight[player.id]); - - let id = self.get_share_index(player.id, j).unwrap(); - - Player { id } - } - - pub fn get_all_virtual_players(&self, player: &Player) -> Vec { - let w = self.get_player_weight(player); - - (0..w) - .map(|i| self.get_virtual_player(player, i)) - .collect::>() - } - - /// `i` is the player's index, from 0 to `self.tc.n` - /// `j` is the player's share #, from 0 to `self.weight[i]` - /// - /// Returns the index of this player's share in the vector of shares, or None if out of bounds. - pub fn get_share_index(&self, i: usize, j: usize) -> Option { - if j < self.weight[i] { - Some(self.starting_index[i] + j) - } else { - None - } - } - - pub fn get_batch_evaluation_domain(&self) -> &BatchEvaluationDomain { - &self.tc.get_batch_evaluation_domain() - } - - pub fn get_evaluation_domain(&self) -> &EvaluationDomain { - &self.tc.get_evaluation_domain() - } - - /// NOTE: RNG is passed in to maintain function signature compatibility with - /// `SecretSharingConfig::get_random_eligible_subset_of_players`, so as to easily benchmark - /// with different methods of sampling subsets. - pub fn get_best_case_eligible_subset_of_players( - &self, - _rng: &mut R, - ) -> Vec { - let mut player_and_weights = self.sort_players_by_weight(); - - self.pop_eligible_subset(&mut player_and_weights) - } - - /// NOTE: RNG is passed in to maintain function signature compatibility with - /// `SecretSharingConfig::get_random_eligible_subset_of_players`, so as to easily benchmark - /// with different methods of sampling subsets. - pub fn get_worst_case_eligible_subset_of_players( - &self, - _rng: &mut R, - ) -> Vec { - let mut player_and_weights = self.sort_players_by_weight(); - - player_and_weights.reverse(); - - self.pop_eligible_subset(&mut player_and_weights) - } - - pub fn get_average_size_of_eligible_subset( - &self, - sample_size: usize, - rng: &mut R, - ) -> usize { - let mut average = 0; - for _ in 0..sample_size { - average += self.get_random_eligible_subset_of_players(rng).len(); - } - average / sample_size - } - - fn sort_players_by_weight(&self) -> Vec<(Player, usize)> { - // the set of remaining players that we are picking a "capable" subset from - let mut player_and_weights = self - .weight - .iter() - .enumerate() - .map(|(i, w)| (self.get_player(i), *w)) - .collect::>(); - - player_and_weights.sort_by(|a, b| a.1.cmp(&b.1)); - player_and_weights - } - - fn pop_eligible_subset(&self, player_and_weights: &mut Vec<(Player, usize)>) -> Vec { - let mut picked_players = vec![]; - - let mut current_weight = 0; - while current_weight < self.tc.t { - let (player, weight) = player_and_weights.pop().unwrap(); - - picked_players.push(player); - - // rinse and repeat until the picked players jointly have enough weight - current_weight += weight; - } - - picked_players - } -} - -impl Display for WeightedConfig { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "weighted/{}-out-of-{}/{}-players", - self.tc.t, self.tc.n, self.num_players - ) - } -} - -impl traits::SecretSharingConfig for WeightedConfig { - /// For testing only. - fn get_random_player(&self, rng: &mut R) -> Player - where - R: RngCore + CryptoRng, - { - Player { - id: rng.gen_range(0, self.get_total_num_players()), - } - } - - fn get_random_eligible_subset_of_players(&self, rng: &mut R) -> Vec - where - R: RngCore, - { - // the randomly-picked "capable" subset of players who can reconstruct the secret - let mut picked_players = vec![]; - // the set of remaining players that we are picking a "capable" subset from - let mut player_and_weights = self - .weight - .iter() - .enumerate() - .map(|(i, w)| (i, *w)) - .collect::>(); - let mut current_weight = 0; - - while current_weight < self.tc.t { - // pick a random player, and move it to the picked set - let idx = rng.gen_range(0, player_and_weights.len()); - let (player_id, weight) = player_and_weights[idx]; - picked_players.push(self.get_player(player_id)); - - // efficiently remove the picked player from the set of remaining players - let len = player_and_weights.len(); - if len > 1 { - player_and_weights.swap(idx, len - 1); - player_and_weights.pop(); - } - - // rinse and repeat until the picked players jointly have enough weight - current_weight += weight; - } - - // println!(); - // println!( - // "Returned random capable subset {{ {} }}", - // vec_to_str!(picked_players) - // ); - picked_players - } - - fn get_total_num_players(&self) -> usize { - self.num_players - } - - fn get_total_num_shares(&self) -> usize { - self.tc.n - } -} - -#[cfg(test)] -mod test { - use crate::pvss::{traits::SecretSharingConfig, WeightedConfig}; - - #[test] - fn bvt() { - // 1-out-of-1 weighted - let wc = WeightedConfig::new(1, vec![1]).unwrap(); - assert_eq!(wc.starting_index.len(), 1); - assert_eq!(wc.starting_index[0], 0); - assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); - - // 1-out-of-2, weights 2 - let wc = WeightedConfig::new(1, vec![2]).unwrap(); - assert_eq!(wc.starting_index.len(), 1); - assert_eq!(wc.starting_index[0], 0); - assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); - assert_eq!(wc.get_virtual_player(&wc.get_player(0), 1).id, 1); - - // 1-out-of-2, weights 1, 1 - let wc = WeightedConfig::new(1, vec![1, 1]).unwrap(); - assert_eq!(wc.starting_index.len(), 2); - assert_eq!(wc.starting_index[0], 0); - assert_eq!(wc.starting_index[1], 1); - assert_eq!(wc.get_virtual_player(&wc.get_player(0), 0).id, 0); - assert_eq!(wc.get_virtual_player(&wc.get_player(1), 0).id, 1); - - // 3-out-of-5, some weights are 0. - let wc = WeightedConfig::new(1, vec![0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0]).unwrap(); - assert_eq!( - vec![0, 0, 0, 0, 2, 4, 6, 6, 6, 6, 9, 12, 15, 15, 15], - wc.starting_index - ); - assert_eq!(wc.get_virtual_player(&wc.get_player(3), 0).id, 0); - assert_eq!(wc.get_virtual_player(&wc.get_player(3), 1).id, 1); - assert_eq!(wc.get_virtual_player(&wc.get_player(4), 0).id, 2); - assert_eq!(wc.get_virtual_player(&wc.get_player(4), 1).id, 3); - assert_eq!(wc.get_virtual_player(&wc.get_player(5), 0).id, 4); - assert_eq!(wc.get_virtual_player(&wc.get_player(5), 1).id, 5); - assert_eq!(wc.get_virtual_player(&wc.get_player(9), 0).id, 6); - assert_eq!(wc.get_virtual_player(&wc.get_player(9), 1).id, 7); - assert_eq!(wc.get_virtual_player(&wc.get_player(9), 2).id, 8); - assert_eq!(wc.get_virtual_player(&wc.get_player(10), 0).id, 9); - assert_eq!(wc.get_virtual_player(&wc.get_player(10), 1).id, 10); - assert_eq!(wc.get_virtual_player(&wc.get_player(10), 2).id, 11); - assert_eq!(wc.get_virtual_player(&wc.get_player(11), 0).id, 12); - assert_eq!(wc.get_virtual_player(&wc.get_player(11), 1).id, 13); - assert_eq!(wc.get_virtual_player(&wc.get_player(11), 2).id, 14); - } -} diff --git a/crates/aptos-dkg/src/range_proofs/dekart_univariate.rs b/crates/aptos-dkg/src/range_proofs/dekart_univariate.rs new file mode 100644 index 00000000000..dee49d55c26 --- /dev/null +++ b/crates/aptos-dkg/src/range_proofs/dekart_univariate.rs @@ -0,0 +1,732 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + algebra::polynomials, fiat_shamir, pcs::univariate_kzg, range_proofs::traits, + sigma_protocol::homomorphism::Trait, utils, Scalar, +}; +use anyhow::ensure; +use aptos_crypto::arkworks::{random::sample_field_element, GroupGenerators}; +use ark_ec::{ + pairing::{Pairing, PairingOutput}, + CurveGroup, PrimeGroup, VariableBaseMSM, +}; +use ark_ff::{AdditiveGroup, Field, PrimeField}; +use ark_poly::{self, EvaluationDomain, Radix2EvaluationDomain}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError}; +#[cfg(feature = "range_proof_timing")] +use ff::derive::bitvec::macros::internal::funty::Fundamental; +use rand::{CryptoRng, RngCore}; +#[cfg(feature = "range_proof_timing")] +use std::time::{Duration, Instant}; +use std::{ + io::Write, + iter::once, + ops::{AddAssign, Mul}, +}; + +pub const DST: &[u8; 42] = b"APTOS_UNIVARIATE_DEKART_V1_RANGE_PROOF_DST"; + +#[derive(CanonicalSerialize, CanonicalDeserialize, Debug, Clone, PartialEq, Eq)] +pub struct Proof { + d: E::G1, // commitment to h(X) = \sum_{j=0}^{\ell-1} beta_j h_j(X) + c: Vec, // of size \ell + c_hat: Vec, // of size \ell +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PowersOfTau { + t1: Vec, // g_1, g_1^{tau}, g_1^{tau^2}, ..., g_1^{tau^max_n}, where `max_n` is the maximum batch size + t2: Vec, // TODO: Should probably use E::G1Affine instead? +} + +pub fn powers_of_tau( + group_generators: GroupGenerators, + rng: &mut R, + n: usize, +) -> PowersOfTau +where + R: RngCore + CryptoRng, +{ + let tau: E::ScalarField = sample_field_element(rng); + let mut t1 = vec![group_generators.g1.into()]; + let mut t2 = vec![group_generators.g2.into()]; + for i in 0..n { + t1.push(t1[i] * tau); + t2.push(t2[i] * tau); + } + PowersOfTau { t1, t2 } +} + +#[derive(CanonicalSerialize, CanonicalDeserialize, Debug, Clone, PartialEq, Eq)] +pub struct Commitment(E::G1); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ProverKey { + max_n: usize, + max_ell: usize, + taus: PowersOfTau, // g_1, g_1^{tau}, g_1^{tau^2}, ..., g_1^{tau^n}, + lagr_g1: Vec, // of size n + 1 + lagr_g2: Vec, // of size n + 1 + eval_dom: Radix2EvaluationDomain, + roots_of_unity_in_eval_dom: Vec, + roots_of_unity_minus_one: Vec, // [omega - 1, ..., omega^n - 1] + vk: VerificationKey, // Needed for Fiat-Shamir +} + +#[derive(CanonicalSerialize)] +pub struct PublicStatement { + n: usize, + ell: usize, + comm: Commitment, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VerificationKey { + max_ell: usize, + tau_1: E::G1, + tau_2: E::G2, + vanishing_com: E::G2, // commitment to deg-n vanishing polynomial (X^{n+1} - 1) / (X - 1) used to test h(X) + powers_of_two: Vec, // [1, 2, 4, ..., 2^{max_ell - 1}] +} + +impl CanonicalSerialize for VerificationKey { + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.max_ell.serialize_with_mode(&mut writer, compress)?; + self.tau_1.serialize_with_mode(&mut writer, compress)?; + self.tau_2.serialize_with_mode(&mut writer, compress)?; + self.vanishing_com + .serialize_with_mode(&mut writer, compress)?; + // NOTE: powers_of_two is intentionally not serialized + Ok(()) + } + + fn serialized_size(&self, compress: Compress) -> usize { + let mut size = 0; + size += self.max_ell.serialized_size(compress); + size += self.tau_1.serialized_size(compress); + size += self.tau_2.serialized_size(compress); + size += self.vanishing_com.serialized_size(compress); + size + } +} + +impl traits::BatchedRangeProof for Proof { + type Commitment = Commitment; + type CommitmentKey = ProverKey; + type CommitmentRandomness = Scalar; + type Input = E::ScalarField; + type ProverKey = ProverKey; + type PublicStatement = PublicStatement; + type VerificationKey = VerificationKey; + + const DST: &[u8] = DST; + + fn commitment_key_from_prover_key(pk: &Self::ProverKey) -> Self::CommitmentKey { + pk.clone() + } + + // The main bottlenecks are `powers_of_tau` and the IFFT steps. + fn setup( + max_n: usize, + max_ell: usize, + group_generators: GroupGenerators, + rng: &mut R, + ) -> (ProverKey, VerificationKey) { + let max_n = (max_n + 1).next_power_of_two() - 1; + let num_omegas = max_n + 1; + debug_assert!(num_omegas.is_power_of_two()); + + let taus = powers_of_tau(group_generators, rng, max_n); // The taus have length `max_n+1` + + let eval_dom = Radix2EvaluationDomain::::new(num_omegas) + .expect("Could not construct evaluation domain"); + let roots_of_unity_in_eval_dom: Vec = eval_dom.elements().collect(); + let roots_of_unity_minus_one: Vec<_> = roots_of_unity_in_eval_dom + .iter() + .skip(1) // skip index 0 + .map(|&omega| omega - E::ScalarField::ONE) + .collect(); + + // Lagrange bases + let lagr_g1_proj = eval_dom.ifft(&taus.t1); + let lagr_g2_proj = eval_dom.ifft(&taus.t2); + + let lagr_g1 = E::G1::normalize_batch(&lagr_g1_proj); + let lagr_g2 = E::G2::normalize_batch(&lagr_g2_proj); + + // Vanishing polynomial that we test h(X) with is (X^{n+1} - 1) / (X - 1) + // + // Zhoujun's faster algorithm in Lagrange basis: + // Let $V(X) = \frac{X^{n+1} - 1}{X - 1}$ denote the vanishing polynomial. + + // Note that the $0$-th Lagrange polynomial (w.r.t. our $(n+1)$-sized FFT evaluation domain) is $\ell_0(X) = \frac{V(X)}{ \prod_{i > 0} (1 - \omega^i) }$. + + // Therefore, we can commit to $V(X)$ by simply scaling it down by $\prod_{i > 0} (1 - \omega^i)$! + + // Notice that $\prod_{i > 0} (1 - \omega^i)$ is the evaluation of (X^{n+1} - 1) / (X - 1) = 1 + X + ... + X^n at X = 1, which is just n + 1. + let vanishing_com = { lagr_g2_proj[0] * E::ScalarField::from((max_n + 1) as u64) }; + + let powers_of_two: Vec = + std::iter::successors(Some(E::ScalarField::ONE), |x| Some(x.double())) + .take(max_ell) + .collect(); + + let vk = VerificationKey { + max_ell, + tau_1: taus.t1[0], + tau_2: taus.t2[0], + vanishing_com, + powers_of_two, + }; + + let pk = ProverKey { + max_n, + max_ell, + taus, + lagr_g1, + lagr_g2, + eval_dom, + roots_of_unity_in_eval_dom, + roots_of_unity_minus_one, + vk: vk.clone(), + }; + + (pk, vk) + } + + fn commit_with_randomness( + pk: &Self::ProverKey, + values: &[Self::Input], + r: &Self::CommitmentRandomness, + ) -> Commitment { + let kzg_commit_hom: univariate_kzg::Homomorphism<'_, E> = univariate_kzg::Homomorphism { + lagr_g1: &pk.lagr_g1, + }; + + let input = (r.0, values.to_vec()); + + Commitment(kzg_commit_hom.apply(&input).0) + } + + #[allow(non_snake_case)] + fn prove( + pk: &ProverKey, + values: &[Self::Input], + ell: usize, + comm: &Self::Commitment, + r: &Self::CommitmentRandomness, + rng: &mut R, + ) -> Proof + where + R: rand_core::RngCore + rand_core::CryptoRng, + { + let mut fs_transcript = merlin::Transcript::new(Self::DST); + + let n = values.len(); + assert!( + n <= pk.max_n, + "n (got {}) must be ≤ max_n (which is {})", + n, + pk.max_n + ); + assert!( + ell <= pk.max_ell, + "ell (got {}) must be ≤ max_ell (which is {})", + ell, + pk.max_ell + ); + + let mut zz = values.to_vec(); + zz.resize(pk.max_n, E::ScalarField::ZERO); + + debug_assert_eq!(zz.len(), pk.max_n); + assert_eq!(pk.taus.t1.len(), pk.max_n + 1); // g_1, g_1^{tau}, g_1^{tau^2}, ..., g_1^{tau^max_n} + assert_eq!(pk.taus.t2.len(), pk.max_n + 1); + + #[cfg(feature = "range_proof_timing")] + println!("n = {:?}, ell = {:?}", pp.n, pp.ell); + #[cfg(feature = "range_proof_timing")] + let mut cumulative = Duration::ZERO; + #[cfg(feature = "range_proof_timing")] + let mut print_cumulative = |duration: Duration| { + cumulative += duration; + println!(" \\--> Cumulative time: {:?}", cumulative); + }; + + // Step 1: Convert z_i's to bits. + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + + let bits: Vec> = zz + .iter() + .map(|z_val| { + utils::scalar_to_bits_le::(z_val) + .into_iter() + .take(ell) + .collect::>() + }) + .collect(); + + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: Chunking {:?} z_i's into bits", + duration.as_micros().as_f64(), + pp.n + ); + print_cumulative(duration); + } + + assert_eq!(pk.max_n, bits.len()); + assert_eq!(ell, bits[0].len()); + + // Step 2: Sample correlated randomness r_j for each f_j polynomial commitment. + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + + let r = correlated_randomness(rng, 2, ell, &r.0); + + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: Correlating {:?} pieces of randomness", + duration.as_micros().as_f64(), + pp.ell + ); + print_cumulative(duration); + } + + assert_eq!(ell, r.len()); + + // Step 3: Compute f_j(X) = \sum_{i=0}^{n-1} z_i[j] \ell_i(X) + r[j] \ell_n(X), + // where \ell_i(X) is the ith Lagrange polynomial for the (n+1)th roots-of-unity evaluation domain. + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + // f_evals[j] = the evaluations of f_j(x) at all the (n+1)-th roots of unity. + // = (r[j], z_0[j], ..., z_{n-1}[j]), where z_i[j] is the j-th bit of z_i. + let f_evals_without_r: Vec> = (0..ell) + .map(|j| bits.iter().map(|row| row[j]).collect()) + .collect(); // This is just transposing the bits matrix + // Assert f_evals is either 0 or 1s or r_j + // for (j, evals) in f_evals.iter().enumerate() { + // for (i, e) in evals.iter().take(pp.n).enumerate() { + // assert!(e.eq(&Scalar::ZERO) || e.eq(&Scalar::ONE), "f_evals[{}][{}] = {}", j, i, e); + // } + // } + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: Convert {:?} z_{{i,j}} bits to scalars", + duration.as_micros().as_f64(), + pp.ell * pp.n + ); + print_cumulative(duration); + } + // Step 4: Compute c_j = g_1^{f_j(\tau)} + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + // c[j] = c_j = g_1^{f_j(\tau)} + let c: Vec = (0..ell) + // Note on blstrs: Using a multiexp will be 10-20% slower than manually multiplying. + // .map(|j| + // g1_multi_exp(&pp.lagrange_basis, &f_evals[j])) + .map(|j| { + // TODO(Performance): Can we speed this up with tables? There are `n` bits, so a single + // (2^n)-sized table that maps `n` bits into their multiproduct \prod_{i=0}^{n} L_i^{f_j(\omega_i)} + // would be too large: e.g., for n = 24 such a table would take 768 MiB. + // If we pick a chunk size of `c` bits such that it evenly divides `n`, we would have + // `k = n / c` chunks. (Assuming `n` is a power of two for now; can tweak later.) + // So we could have `k` tables, each of size 2^c. Each table `j \in[0, k)` maps + // exponents into their multiproduct `\prod_{i=j*c}^{(j+1)*c} L_i^{f_j(\omega_i)}` + // For example, if we want to handle n = 2048, we can set c = 16, which gives + // `k = \ell / c = 2048 / 16 = 128` tables, each of size 2^c => 2^{16} * 48 bytes = + // 3 MiB / table => 384 MiB total. + let mut c_j: ::G1 = pk.lagr_g1[0].mul(&r[j]); // start with r[j] * lagr_g1[0] + c_j.add_assign(&utils::msm_bool( + &pk.lagr_g1[1..=pk.max_n], // TODO: why are we padding? + &f_evals_without_r[j], + )); + c_j + }) + .collect(); + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: All {:?} deg-{:?} f_j G_1 commitments", + duration.as_micros().as_f64(), + pp.ell, + pp.n + ); + print_cumulative(duration); + println!(" + Each c_j took: {:?}", duration / pp.ell as u32); + } + + // Step 5: Compute c_hat[j] = \hat{c}_j = g_2^{f_j(\tau)} + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + let c_hat: Vec = (0..ell) + // Note: Using a multiexp will be 10-20% slower than manually multiplying. + // .map(|j| g2_multi_exp(&pp.lagrange_basis_g2, &f_evals[j])) + .map(|j| { + let mut c_hat_j: ::G2 = pk.lagr_g2[0].mul(&r[j]); + c_hat_j.add_assign(&utils::msm_bool( + &pk.lagr_g2[1..=pk.max_n], + &f_evals_without_r[j], + )); + c_hat_j + }) + .collect(); + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: All {:?} deg-{:?} f_j G_2 commitments", + duration.as_micros().as_f64(), + pp.ell, + pp.n + ); + print_cumulative(duration); + println!( + " + Each \\hat{{c}}_j took: {:?}", + duration / pp.ell as u32 + ); + } + + let num_omegas = pk.max_n + 1; + + // Step 6: + // 1. Compute each f_j(X) in coefficient form via a size-(n+1) FFT on f_j(X) + // 2. Compute f'_j(X) via a differentiation. + // 3. Evaluate f'_j at all (n+1)th roots of unity via a size-(n+1) FFT. + // 5. for i = 0, compute N_j'(\omega^i) = r_j(r_j - 1) + // 4. \forall i > 0, compute N_j'(\omega^i) = (\omega^i - 1) f_j'(\omega^i)(2f_j(\omega^i) - 1) + // 6. \forall i \in [0,n], compute h_j(\omega^i) = N_j'(\omega^i) / ( (n+1)\omega^{i n} ) + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + // let omega_n = pp.roots_of_unity_in_eval_dom[pp.n]; + let n1_inv = E::ScalarField::from((pk.max_n + 1) as u64) + .inverse() + .unwrap(); + + let f_evals: Vec> = f_evals_without_r + .iter() + .enumerate() + .map(|(j, col)| { + once(r[j]) + .chain(col.iter().map(|&b| E::ScalarField::from(b))) + .collect() + }) + .collect(); + + let h: Vec> = (0..ell) + .map(|j| { + // Interpolate f_j coeffs + let mut f_j = f_evals[j].clone(); + pk.eval_dom.ifft_in_place(&mut f_j); + assert_eq!(f_j.len(), pk.max_n + 1); + + // Compute f'_j derivative + let mut diff_f_j = f_j.clone(); + polynomials::differentiate_in_place(&mut diff_f_j); + assert_eq!(diff_f_j.len(), pk.max_n); + + // Evaluate f'_j at all (n+1)th roots of unity + let mut diff_f_j_evals = diff_f_j.clone(); + pk.eval_dom.fft_in_place(&mut diff_f_j_evals); + assert_eq!(diff_f_j_evals.len(), pk.max_n + 1); + + // N'_j(\omega^0) = r_j(r_j - 1) + let mut diff_n_j_evals = Vec::with_capacity(num_omegas); + diff_n_j_evals.push(r[j].square() - r[j]); + + // \forall i > 0, N'_j(\omega^i) = (\omega^i - 1) f_j'(\omega^i)(2f_j(\omega^i) - 1) + for i in 1..(pk.max_n + 1) { + diff_n_j_evals.push( + (pk.roots_of_unity_minus_one[i - 1]) + * diff_f_j_evals[i] + * (f_evals[j][i].double() - E::ScalarField::ONE), + ); + } + assert_eq!(diff_n_j_evals.len(), num_omegas); + + // \forall i \in [0,n], h_j(\omega^i) + // = N_j'(\omega^i) / ( (n+1)\omega^{i n} ) + // = N_j'(\omega^i) * (\omega^i / (n+1)) + let mut h_j = Vec::with_capacity(num_omegas); + for i in 0..pk.max_n + 1 { + h_j.push( + diff_n_j_evals[i] + .mul(pk.roots_of_unity_in_eval_dom[i]) + .mul(n1_inv), + ); + } + assert_eq!(h_j.len(), num_omegas); + + h_j + }) + .collect(); + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: All {:?} deg-{:?} h_j(X) coeffs", + duration.as_micros().as_f64(), + pp.ell, + num_omegas - 1 + ); + print_cumulative(duration); + } + // Step 7: Fiat-Shamir transform for beta_j's. + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + // Note: The first output of `fiat_shamir_challenges` is unused, it is intended for the verifier. + // This is not ideal, but it should not significantly affect performance. + let public_statement = PublicStatement { + n, + ell, + comm: comm.clone(), + }; + let c_aff = E::G1::normalize_batch(&c); + let c_hat_aff = E::G2::normalize_batch(&c_hat); + let bit_commitments = (c_aff.as_slice(), c_hat_aff.as_slice()); + let (_, betas) = fiat_shamir_challenges( + &pk.vk, + public_statement, + &bit_commitments, + c.as_slice().len(), + &mut fs_transcript, + ); + assert_eq!(ell, betas.len()); + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: {:?} Fiat-Shamir challenges", + duration.as_micros().as_f64(), + betas.len() + ); + print_cumulative(duration); + } + // Step 8: Compute h(X) = \sum_{j=0}^{ell-1} beta_j h_j(X) + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + let mut hh: Vec = vec![E::ScalarField::ZERO; pk.max_n + 1]; + for (h_j, &beta_j) in h.iter().zip(&betas) { + for (hh_coeff, &h_coeff) in hh.iter_mut().zip(h_j) { + *hh_coeff += h_coeff * beta_j; + } + } + assert_eq!(hh.len(), num_omegas); + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: h(X) as a size-{:?} linear combination of h_j(X)'s", + duration.as_micros().as_f64(), + betas.len() + ); + print_cumulative(duration); + } + + // Step 9: Compute d = g_1^{h(X)} + #[cfg(feature = "range_proof_timing")] + let start = Instant::now(); + let d = + VariableBaseMSM::msm(&pk.lagr_g1[0..num_omegas], &hh).expect("Failed computing msm"); // TODO: Not very "variable base"... + #[cfg(feature = "range_proof_timing")] + { + let duration = start.elapsed(); + println!( + "{:>8.2} mus: deg-{:?} h(X) commitment", + duration.as_micros().as_f64(), + hh.len() - 1 + ); + print_cumulative(duration); + } + + Proof { + d, + c: c_aff, + c_hat: c_hat_aff, + } + } + + fn verify( + &self, + vk: &Self::VerificationKey, + n: usize, + ell: usize, + comm: &Self::Commitment, + ) -> anyhow::Result<()> { + let mut fs_t = merlin::Transcript::new(Self::DST); + + assert!( + ell <= vk.max_ell, + "ell (got {}) must be ≤ max_ell (which is {})", + ell, + vk.max_ell + ); + + let commitment_recomputed: E::G1 = + VariableBaseMSM::msm(&self.c, &vk.powers_of_two[..ell]).expect("Failed to compute msm"); + ensure!(comm.0 == commitment_recomputed); + + let public_statement = PublicStatement { + n, + ell, + comm: comm.clone(), + }; + let bit_commitments = (&self.c[..], &self.c_hat[..]); + let (alphas, betas) = fiat_shamir_challenges( + &vk, + public_statement, + &bit_commitments, + self.c.len(), + &mut fs_t, + ); + + // Verify h(\tau) + let h_check = E::multi_pairing( + (0..ell) + .map(|j| self.c[j] * betas[j]) // E::G1 + .chain(once(-self.d)) // add -d + .collect::>(), // collect into Vec + (0..ell) + .map(|j| self.c_hat[j] - vk.tau_2) // E::G2 + .chain(once(vk.vanishing_com)) // add vanishing commitment + .collect::>(), // collect into Vec + ); + ensure!(PairingOutput::::ZERO == h_check); + + // Ensure duality: c[j] matches c_hat[j]. + + // Compute MSM in G1: sum_j (alphas[j] * proof.c[j]) + let g1_comb = VariableBaseMSM::msm(&self.c, &alphas).unwrap(); + + // Compute MSM in G2: sum_j (alphas[j] * proof.c_hat[j]) + let g2_comb = VariableBaseMSM::msm(&self.c_hat, &alphas).unwrap(); + let c_check = E::multi_pairing( + vec![ + g1_comb, // from MSM in G1 + -vk.tau_1, // subtract tau_1 + ], + vec![ + vk.tau_2, // tau_2 + g2_comb, // from MSM in G2 + ], + ); + ensure!(PairingOutput::::ZERO == c_check); + + Ok(()) + } + + fn maul(&mut self) { + self.c[0] = (self.c[0] + E::G1::generator()).into_affine(); + } +} + +/// Compute alpha, beta. +fn fiat_shamir_challenges( + vk: &VerificationKey, + public_statement: PublicStatement, + bit_commitments: &(&[E::G1Affine], &[E::G2Affine]), // TODO: make this generic over B? + num_scalars: usize, + fs_transcript: &mut merlin::Transcript, +) -> (Vec, Vec) { + >>::append_sep(fs_transcript, DST); + + >>::append_vk(fs_transcript, vk); + + >>::append_public_statement( + fs_transcript, + public_statement, + ); + + >>::append_f_j_commitments( + fs_transcript, + bit_commitments, + ); + + // Generate the Fiat–Shamir challenges from the updated transcript + let beta_vals = + >>::challenges_for_linear_combination( + fs_transcript, + num_scalars, + ); + + let alpha_vals = + >>::challenges_for_linear_combination( + fs_transcript, + num_scalars, + ); + + (alpha_vals, beta_vals) +} + +/// Generate correlated random values whose weighted sum equals `target_sum`. +/// +/// Returns `num_chunks` field elements `[r_0, ..., r_{num_chunks-1}]` such that: +/// `r_0 + r_1 * radix + r_2 * radix^2 + ... + r_{num_chunks-1} * radix^{num_chunks-1} = target_sum`. +pub fn correlated_randomness( + rng: &mut R, + radix: u64, + num_chunks: usize, + target_sum: &F, +) -> Vec +where + F: PrimeField, // PrimeField because of sample_field_element() + R: rand_core::RngCore + rand_core::CryptoRng, +{ + let mut r_vals = vec![F::zero(); num_chunks]; + let mut remaining = *target_sum; + let radix_f = F::from(radix); + let mut cur_base = radix_f; + + for i in 1..num_chunks { + r_vals[i] = sample_field_element(rng); + remaining -= r_vals[i] * cur_base; + cur_base *= radix_f; + } + r_vals[0] = remaining; + + r_vals +} + +#[cfg(test)] +mod tests { + use crate::range_proofs::dekart_univariate::correlated_randomness; + use ark_ff::PrimeField; + use rand::thread_rng; + + #[cfg(test)] + fn test_correlated_randomness_generic() { + let mut rng = thread_rng(); + let target_sum = F::one(); + let radix: u64 = 4; + let num_chunks: usize = 8; + + let coefs = correlated_randomness(&mut rng, radix, num_chunks, &target_sum); + + // Compute actual sum: Σ coef[i] * radix^i + let actual_sum: F = (0..num_chunks) + .map(|i| coefs[i] * F::from(radix.pow(i as u32))) + .sum(); + + assert_eq!(target_sum, actual_sum); + } + + #[test] + fn test_correlated_randomness_bn254() { + use ark_bn254::Fr; + test_correlated_randomness_generic::(); + } +} diff --git a/crates/aptos-dkg/src/range_proofs/dekart_univariate_v2.rs b/crates/aptos-dkg/src/range_proofs/dekart_univariate_v2.rs new file mode 100644 index 00000000000..a1270d1e363 --- /dev/null +++ b/crates/aptos-dkg/src/range_proofs/dekart_univariate_v2.rs @@ -0,0 +1,988 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +// This file implements the range proof described here: https://alinush.github.io/dekart + +use crate::{ + algebra::polynomials, + pcs::univariate_hiding_kzg, + range_proofs::traits, + sigma_protocol::{self, homomorphism, homomorphism::Trait as _, Trait as _}, + utils, Scalar, +}; +use aptos_crypto::arkworks::{ + self, + random::{ + sample_field_element, sample_field_elements, unsafe_random_point, unsafe_random_points, + }, + GroupGenerators, +}; +use ark_ec::{pairing::Pairing, CurveGroup, PrimeGroup, VariableBaseMSM}; +use ark_ff::{AdditiveGroup, Field}; +use ark_poly::{self, EvaluationDomain, Polynomial}; +use ark_serialize::{ + CanonicalDeserialize, CanonicalSerialize, Compress, Read, SerializationError, Valid, Validate, +}; +use num_integer::Roots; +use rand::{CryptoRng, RngCore}; +use std::{fmt::Debug, io::Write}; + +#[allow(non_snake_case)] +#[derive(CanonicalSerialize, Debug, PartialEq, Eq, Clone, CanonicalDeserialize)] +pub struct Proof { + hatC: E::G1, + pi_PoK: sigma_protocol::Proof>, + Cs: Vec, // has length ell + D: E::G1, + a: E::ScalarField, + a_h: E::ScalarField, + a_js: Vec, // has length ell + pi_gamma: univariate_hiding_kzg::OpeningProof, +} + +impl Proof { + /// Generates a random looking proof (but not a valid one). + /// Useful for testing and benchmarking. TODO: might be able to derive this through macros etc + pub fn generate(ell: u8, rng: &mut R) -> Self { + Self { + hatC: unsafe_random_point(rng), + pi_PoK: two_term_msm::Proof::generate(rng), + Cs: unsafe_random_points(ell as usize, rng), + D: unsafe_random_point(rng), + a: sample_field_element(rng), + a_h: sample_field_element(rng), + a_js: sample_field_elements(ell as usize, rng), + pi_gamma: univariate_hiding_kzg::OpeningProof::generate(rng), + } + } +} + +#[allow(non_snake_case)] +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct ProverKey { + pub(crate) vk: VerificationKey, + pub(crate) ck_S: univariate_hiding_kzg::CommitmentKey, + pub(crate) max_n: usize, + pub(crate) prover_precomputed: ProverPrecomputed, +} + +#[derive(CanonicalSerialize)] +pub struct PublicStatement { + n: usize, + ell: usize, + comm: univariate_hiding_kzg::Commitment, +} + +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct VerificationKey { + xi_1: E::G1Affine, + lagr_0: E::G1Affine, + vk_hkzg: univariate_hiding_kzg::VerificationKey, + verifier_precomputed: VerifierPrecomputed, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ProverPrecomputed { + pub(crate) powers_of_two: Vec, + h_denom_eval: Vec, +} + +// Custom `CanonicalSerialize/CanonicalDeserialize` for `VerifierPrecomputed` because most of it can be recomputed +impl CanonicalSerialize for ProverPrecomputed { + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.powers_of_two + .len() + .serialize_with_mode(&mut writer, compress)?; + let triangular_number = self.h_denom_eval[0] + .inverse() + .expect("Could not invert h_denom_eval[0]"); + let num_omegas = floored_triangular_root( + arkworks::scalar_to_u32(&triangular_number) + .expect("triangular number did not fit in u32") as usize, + ) + 1; + num_omegas.serialize_with_mode(&mut writer, compress)?; + + Ok(()) + } + + fn serialized_size(&self, compress: Compress) -> usize { + let mut size = 0; + size += 2 * self.powers_of_two.len().serialized_size(compress); // `num_omegas` is also a usize + size + } +} + +impl CanonicalDeserialize for ProverPrecomputed { + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: Validate, + ) -> Result { + let powers_len = usize::deserialize_with_mode(&mut reader, compress, validate)?; + let num_omegas = usize::deserialize_with_mode(&mut reader, compress, validate)?; + + let powers_of_two = arkworks::powers_of_two::(powers_len); + + let roots_of_unity = arkworks::compute_roots_of_unity::(num_omegas); + let h_denom_eval = compute_h_denom_eval::(&roots_of_unity); + + Ok(Self { + powers_of_two, + h_denom_eval, + }) + } +} + +// Required by `CanonicalDeserialize` +impl Valid for ProverPrecomputed { + #[inline] + fn check(&self) -> Result<(), SerializationError> { + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VerifierPrecomputed { + powers_of_two: Vec, + roots_of_unity: Vec, +} + +// Custom `CanonicalSerialize/CanonicalDeserialize` for `VerifierPrecomputed` because most of it can be recomputed +impl CanonicalSerialize for VerifierPrecomputed { + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.roots_of_unity + .len() + .serialize_with_mode(&mut writer, compress)?; + self.powers_of_two + .len() + .serialize_with_mode(&mut writer, compress)?; + + Ok(()) + } + + fn serialized_size(&self, compress: Compress) -> usize { + let mut size = 0; + size += self.roots_of_unity.len().serialized_size(compress); + size += self.roots_of_unity[1].serialized_size(compress); + size += self.powers_of_two.len().serialized_size(compress); + + size + } +} + +impl CanonicalDeserialize for VerifierPrecomputed { + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: Validate, + ) -> Result { + let num_omegas = usize::deserialize_with_mode(&mut reader, compress, validate)?; + let max_ell = usize::deserialize_with_mode(&mut reader, compress, validate)?; + + let roots_of_unity = arkworks::compute_roots_of_unity::(num_omegas); + let powers_of_two = arkworks::powers_of_two::(max_ell); + + // Reconstruct the VerificationKey + Ok(Self { + roots_of_unity, + powers_of_two, + }) + } +} + +// Required by CanonicalDeserialize +impl Valid for VerifierPrecomputed { + #[inline] + fn check(&self) -> Result<(), SerializationError> { + Ok(()) + } +} + +fn compute_h_denom_eval( + roots_of_unity_in_eval_dom: &Vec, +) -> Vec { + let num_omegas = roots_of_unity_in_eval_dom.len(); + let mut h_denom_eval = Vec::with_capacity(num_omegas); + + // First element: inverse of (max_n * (max_n + 1) / 2) + h_denom_eval.push( + E::ScalarField::from(((num_omegas - 1) * num_omegas / 2) as u64) + .inverse() + .expect("Value should be invertible"), + ); + + // Remaining elements: h_denom_eval[i] is the inverse of (max_n + 1) / (ω^i (ω^i - 1) ) + h_denom_eval.extend(roots_of_unity_in_eval_dom.iter().skip(1).map(|&root| { + (root * (root - E::ScalarField::ONE)) / E::ScalarField::from(num_omegas as u64) + })); + + h_denom_eval +} + +impl traits::BatchedRangeProof for Proof { + type Commitment = univariate_hiding_kzg::Commitment; + type CommitmentKey = univariate_hiding_kzg::CommitmentKey; + type CommitmentRandomness = univariate_hiding_kzg::CommitmentRandomness; + type Input = E::ScalarField; + type ProverKey = ProverKey; + type PublicStatement = PublicStatement; + type VerificationKey = VerificationKey; + + const DST: &[u8] = b"APTOS_UNIVARIATE_DEKART_V2_RANGE_PROOF_DST"; + + fn commitment_key_from_prover_key(pk: &Self::ProverKey) -> Self::CommitmentKey { + pk.ck_S.clone() + } + + #[allow(non_snake_case)] + fn setup( + max_n: usize, + max_ell: usize, + group_generators: GroupGenerators, + rng: &mut R, + ) -> (ProverKey, VerificationKey) { + let num_omegas = max_n + 1; + assert!(num_omegas.is_power_of_two()); + + // Generate trapdoor elements + let trapdoor = univariate_hiding_kzg::Trapdoor::::rand(rng); + let xi_1_proj: E::G1 = group_generators.g1 * trapdoor.xi; + + let (vk_hkzg, ck_S) = + univariate_hiding_kzg::setup(max_n + 1, group_generators.clone(), trapdoor, rng); + + let h_denom_eval = compute_h_denom_eval::(&ck_S.roots_of_unity_in_eval_dom); + + let powers_of_two = arkworks::powers_of_two::(max_ell); + + let prover_precomputed = ProverPrecomputed { + powers_of_two: powers_of_two.clone(), + h_denom_eval, + }; + + let verifier_precomputed = VerifierPrecomputed { + powers_of_two, + roots_of_unity: ck_S.roots_of_unity_in_eval_dom.clone(), + }; + + let vk = VerificationKey { + xi_1: xi_1_proj.into_affine(), + lagr_0: ck_S.lagr_g1[0], + vk_hkzg, + verifier_precomputed, + }; + let prk = ProverKey { + vk: vk.clone(), + ck_S, + max_n, + prover_precomputed, + }; + + (prk, vk) + } + + #[allow(non_snake_case)] + fn commit_with_randomness( + ck_S: &Self::CommitmentKey, + values: &[Self::Input], + rho: &Self::CommitmentRandomness, + ) -> Self::Commitment { + let mut values_shifted = vec![E::ScalarField::ZERO]; // start with 0, + values_shifted.extend(values); // then append all values from the original vector + + univariate_hiding_kzg::commit_with_randomness(ck_S, &values_shifted, rho) + } + + #[allow(non_snake_case)] + fn prove( + pk: &ProverKey, + values: &[Self::Input], + ell: usize, + comm: &Self::Commitment, + rho: &Self::CommitmentRandomness, + rng: &mut R, + ) -> Proof + where + R: rand_core::RngCore + rand_core::CryptoRng, + { + let mut fs_t = merlin::Transcript::new(Self::DST); + + // Step 1a + let ProverKey { + vk, + ck_S, + max_n, + prover_precomputed, + } = pk; + + let n = values.len(); + let max_ell = prover_precomputed.powers_of_two.len(); + + assert!( + n <= *max_n, + "n (got {}) must be ≤ max_n (which is {})", + n, + max_n + ); + // TODO: Use a subdomain to make the FFTs smaller, when n is much smaller than max_n + assert!( + ell <= max_ell, + "ell (got {}) must be ≤ max_ell (which is {})", + ell, + max_ell + ); + + let num_omegas = max_n + 1; + + let univariate_hiding_kzg::CommitmentKey { + xi_1, + lagr_g1, + eval_dom, + m_inv: num_omegas_inv, + .. + } = ck_S; + + debug_assert_eq!( + *num_omegas_inv, + E::ScalarField::from(num_omegas as u64).inverse().unwrap() + ); + + // Step 1b + fiat_shamir::append_initial_data(&mut fs_t, Self::DST, vk, PublicStatement { + n, + ell, + comm: comm.clone(), + }); + + // Step 2a + let r = sample_field_element(rng); + let delta_rho = sample_field_element(rng); + let hatC = *xi_1 * delta_rho + lagr_g1[0] * r + comm.0; + + // Step 2b + fiat_shamir::append_hat_f_commitment::(&mut fs_t, &hatC); + + // Step 3a + let pi_PoK = two_term_msm::Homomorphism { + base_1: lagr_g1[0], + base_2: *xi_1, + } + .prove( + &two_term_msm::Witness { + poly_randomness: Scalar(r), + hiding_kzg_randomness: Scalar(delta_rho), + }, + &two_term_msm::CodomainShape(hatC - comm.0), + &Self::DST, + rng, + ); + + // Step 3b + fiat_shamir::append_sigma_proof(&mut fs_t, &pi_PoK); + + // Step 4a + let rs: Vec = (0..ell).map(|_| sample_field_element(rng)).collect(); + + let f_js_evals: Vec> = { + let mut f_js_evals = vec![Vec::with_capacity(num_omegas); ell]; + + for j in 0..ell { + f_js_evals[j].push(rs[j]); + } + + for &val in values.iter() { + let bits = utils::scalar_to_bits_le::(&val); + for j in 0..ell { + f_js_evals[j].push(E::ScalarField::from(bits[j])); + } + } + + for f_j in &mut f_js_evals { + f_j.resize(num_omegas, E::ScalarField::ZERO); + } + + f_js_evals + }; + + let rhos: Vec = std::iter::repeat_with(|| sample_field_element(rng)) + .take(ell) + .collect(); + + let hkzg_commitment_hom = univariate_hiding_kzg::CommitmentHomomorphism:: { + lagr_g1, + xi_1: *xi_1, + }; + let Cs: Vec<_> = f_js_evals + .iter() + .zip(rhos.iter()) + .map(|(f_j, &rho)| { + let hkzg_commit_input = univariate_hiding_kzg::Witness { + hiding_randomness: Scalar(rho), // because univariate_hiding_kzg::CommitmentRandomness is an alias for Scalar... TODO: should maybe make a constructor method? + values: Scalar::vec_from_inner_slice(f_j), + }; + hkzg_commitment_hom.apply(&hkzg_commit_input).0 + }) + .collect(); + + // Step 4b + fiat_shamir::append_f_j_commitments::(&mut fs_t, &Cs); + + // Step 6 + let (beta, betas) = fiat_shamir::get_beta_challenges::(&mut fs_t, ell); + + let hat_f_evals: Vec = { + let mut v = Vec::with_capacity(num_omegas); + v.push(r); + v.extend_from_slice(values); + v.resize(num_omegas, E::ScalarField::ZERO); + v + }; + + let hat_f_coeffs = eval_dom.ifft(&hat_f_evals); + debug_assert_eq!(hat_f_coeffs.len(), pk.max_n + 1); + + let diff_hat_f_evals: Vec = { + let mut result = polynomials::differentiate(&hat_f_coeffs); + eval_dom.fft_in_place(&mut result); + result + }; + + let f_j_coeffs: Vec> = (0..ell) + .map(|j| { + let mut f_j = f_js_evals[j].clone(); + debug_assert_eq!(f_j.len(), pk.max_n + 1); + eval_dom.ifft_in_place(&mut f_j); + debug_assert_eq!(f_j.len(), pk.max_n + 1); + f_j + }) + .collect(); + + let diff_f_js_evals: Vec> = f_js_evals + .iter() + .map(|f_j_eval| { + let mut result = eval_dom.ifft(f_j_eval); // Convert to coefficients + polynomials::differentiate_in_place(&mut result); // Differentiate + eval_dom.fft_in_place(&mut result); // Convert back to evaluations + result + }) + .collect(); + + let h_evals: Vec = { + let mut result = Vec::with_capacity(num_omegas); + + let first_h_eval = { + let mut pow2 = E::ScalarField::ONE; + let mut sum_pow2_rs = E::ScalarField::ZERO; + for r_j in &rs { + sum_pow2_rs += pow2 * r_j; + pow2 = pow2.double(); + } + + let sum_betas_term: E::ScalarField = betas + .iter() + .zip(&rs) + .map(|(&beta_j, r_j)| beta_j * r_j * (*r_j - E::ScalarField::ONE)) + .sum(); + + let numerator = beta * (r - sum_pow2_rs) + sum_betas_term; + numerator * num_omegas_inv + }; + result.push(first_h_eval); + + for i in 1..num_omegas { + // First term: beta * diff_hat_f_evals[i] + let mut val = diff_hat_f_evals[i]; + + // Second term: -beta * sum_j 2^j * f_j_evals[j][i] + let sum1: E::ScalarField = diff_f_js_evals + .iter() + .enumerate() + .map(|(j, diff_f_j)| E::ScalarField::from(1u64 << j) * diff_f_j[i]) + .sum(); + val = (val - sum1) * beta; + + // Third term: sum_j betas[j] * diff_f_j * (2*f_j - 1) + let sum2: E::ScalarField = diff_f_js_evals + .iter() + .zip(f_js_evals.iter()) + .enumerate() + .map(|(j, (diff_f_j, f_j))| { + betas[j] + * diff_f_j[i] + * (E::ScalarField::from(2u64) * f_j[i] - E::ScalarField::ONE) + }) + .sum(); + val += sum2; + + // Divide by precomputed denominator + val *= prover_precomputed.h_denom_eval[i]; + + result.push(val); + } + + result + }; + + let rho_h = sample_field_element(rng); + let D = hkzg_commitment_hom + .apply(&univariate_hiding_kzg::Witness { + hiding_randomness: Scalar(rho_h), + values: Scalar::vec_from_inner_slice(&h_evals), + }) + .0; + // Step 7b + fiat_shamir::append_h_commitment::(&mut fs_t, &D); + + // Step 8 + let (mu, mu_h, mus) = fiat_shamir::get_mu_challenges::(&mut fs_t, ell); + + let u_values: Vec<_> = (0..num_omegas) + .map(|i| { + mu * hat_f_evals[i] + + mu_h * h_evals[i] + + mus + .iter() + .zip(&f_js_evals) + .map(|(&mu_j, f_j)| mu_j * f_j[i]) + .sum::() + }) + .collect(); + + // Step 9 + let gamma = + fiat_shamir::get_gamma_challenge::(&mut fs_t, &ck_S.roots_of_unity_in_eval_dom); + + let a: E::ScalarField = { + let poly = ark_poly::univariate::DensePolynomial { + coeffs: hat_f_coeffs, + }; + poly.evaluate(&gamma) + }; // This algorithm should be Horner's, hence a bit faster than barycentric interpolation + + let a_h = polynomials::barycentric_eval( + &h_evals, + &ck_S.roots_of_unity_in_eval_dom, + gamma, + *num_omegas_inv, + ); + + let a_js: Vec = (0..ell) + .map(|i| { + let poly = ark_poly::univariate::DensePolynomial { + coeffs: f_j_coeffs[i].clone(), + }; + poly.evaluate(&gamma) + }) // Again, using Horner's here + .collect(); + + // Step 10 + let s = sample_field_element(rng); + + let rho_u = mu * (rho.0 + delta_rho) + + mu_h * rho_h + + mus + .iter() + .zip(&rhos) + .map(|(&mu_j, &rho_j)| mu_j * rho_j) + .sum::(); + + let u_val = polynomials::barycentric_eval( + &u_values, + &ck_S.roots_of_unity_in_eval_dom, + gamma, + *num_omegas_inv, + ); + let pi_gamma = univariate_hiding_kzg::CommitmentHomomorphism::open( + ck_S, + u_values, + rho_u, + gamma, + u_val, + &Scalar(s), + ); + + Proof { + hatC, + pi_PoK, + Cs, + D, + a, + a_h, + a_js, + pi_gamma, + } + } + + #[allow(non_snake_case)] + fn verify( + &self, + vk: &Self::VerificationKey, + n: usize, + ell: usize, + comm: &Self::Commitment, + ) -> anyhow::Result<()> { + let mut fs_t = merlin::Transcript::new(Self::DST); + + // Step 1 + let VerificationKey { + xi_1, + lagr_0, + vk_hkzg, + verifier_precomputed, + } = vk; + + assert!( + ell <= verifier_precomputed.powers_of_two.len(), + "ell (got {}) must be ≤ max_ell (which is {})", + ell, + verifier_precomputed.powers_of_two.len() + ); // Easy to work around this if it fails... + + let Proof { + hatC, + pi_PoK, + Cs, + D, + a, + a_h, + a_js, + pi_gamma, + } = self; + + // Step 2a + fiat_shamir::append_initial_data(&mut fs_t, Self::DST, vk, PublicStatement { + n, + ell, + comm: comm.clone(), + }); + + // Step 2b + fiat_shamir::append_hat_f_commitment::(&mut fs_t, &hatC); + + // Step 3 + two_term_msm::Homomorphism { + base_1: *lagr_0, + base_2: *xi_1, + } + .verify( + &(two_term_msm::CodomainShape(*hatC - comm.0)), + pi_PoK, + &Self::DST, + )?; + + // Step 4a + fiat_shamir::append_sigma_proof(&mut fs_t, &pi_PoK); + + // Step 4b + fiat_shamir::append_f_j_commitments::(&mut fs_t, &Cs); + + // Step 5 + let (beta, beta_js) = fiat_shamir::get_beta_challenges::(&mut fs_t, ell); + + // Step 6 + fiat_shamir::append_h_commitment::(&mut fs_t, &D); + + // Step 7 + let (mu, mu_h, mu_js) = fiat_shamir::get_mu_challenges::(&mut fs_t, ell); + + // Step 8 + let U_bases: Vec = { + let mut v = Vec::with_capacity(2 + Cs.len()); + v.push(*hatC); + v.push(*D); + v.extend_from_slice(&Cs); + E::G1::normalize_batch(&v) + }; + + let U_scalars: Vec = { + let mut v = Vec::with_capacity(2 + mu_js.len()); + v.push(mu); + v.push(mu_h); + v.extend_from_slice(&mu_js); + v + }; + + let U = E::G1::msm(&U_bases, &U_scalars).expect("Failed to compute MSM in DeKARTv2"); + + // Step 9 + let gamma = + fiat_shamir::get_gamma_challenge::(&mut fs_t, &verifier_precomputed.roots_of_unity); + + // Step 10 + let a_u = *a * mu + + *a_h * mu_h + + a_js + .iter() + .zip(&mu_js) + .map(|(&a_j, &mu_j)| a_j * mu_j) + .sum::(); + + use sigma_protocol::homomorphism::TrivialShape as HkzgCommitment; + univariate_hiding_kzg::CommitmentHomomorphism::verify( + vk_hkzg.clone(), + HkzgCommitment(U), // TODO: Ugh univariate_hiding_kzg::Commitment(U) does not work because it's a tuple struct, see https://github.com/rust-lang/rust/issues/17422; So make it a struct with one named field? + gamma, + a_u, + pi_gamma.clone(), + )?; + + // Step 11 + let num_omegas = verifier_precomputed.roots_of_unity.len(); + + let LHS = { + // First compute V_SS^*(gamma), where V_SS^*(X) is the polynomial (X^{max_n + 1} - 1) / (X - 1) + let V_eval_gamma = { + let gamma_pow = gamma.pow([num_omegas as u64]); + (gamma_pow - E::ScalarField::ONE) * (gamma - E::ScalarField::ONE).inverse().unwrap() + }; + + *a_h * V_eval_gamma + }; + + let RHS = { + // Compute sum_j 2^j a_j + let sum1: E::ScalarField = verifier_precomputed + .powers_of_two + .iter() + .zip(a_js.iter()) + .map(|(&power_of_two, aj)| power_of_two * aj) + .sum(); + + // Compute sum_j beta_j a_j (a_j - 1) + let sum2: E::ScalarField = beta_js + .iter() + .zip(a_js.iter()) + .map(|(beta, &a)| a * (a - E::ScalarField::ONE) * beta) // TODO: submit PR to change arkworks so beta can be on the left... + .sum(); + + beta * (*a - sum1) + sum2 + }; + + anyhow::ensure!(LHS == RHS); + + Ok(()) + } + + fn maul(&mut self) { + self.D += E::G1::generator(); + } +} + +mod fiat_shamir { + use super::*; + use crate::fiat_shamir::RangeProof; + use merlin::Transcript; + + pub(crate) fn append_initial_data( + fs_t: &mut Transcript, + dst: &[u8], + vk: &VerificationKey, + ps: PublicStatement, + ) { + >>::append_sep(fs_t, dst); + >>::append_vk(fs_t, vk); + >>::append_public_statement(fs_t, ps); + } + + #[allow(non_snake_case)] + pub(crate) fn append_hat_f_commitment( + fs_transcript: &mut Transcript, + hatC: &E::G1, + ) { + >>::append_hat_f_commitment(fs_transcript, hatC); + } + + #[allow(non_snake_case)] + pub(crate) fn append_sigma_proof( + fs_transcript: &mut Transcript, + pi_PoK: &sigma_protocol::Proof>, + ) { + >>::append_sigma_proof(fs_transcript, pi_PoK); + } + + #[allow(non_snake_case)] + pub(crate) fn append_f_j_commitments( + fs_transcript: &mut Transcript, + Cs: &Vec, + ) { + >>::append_f_j_commitments(fs_transcript, Cs); + } + + pub(crate) fn get_beta_challenges( + fs_transcript: &mut Transcript, + ell: usize, + ) -> (E::ScalarField, Vec) { + let mut betas = + >>::challenges_for_quotient_polynomials( + fs_transcript, + ell, + ); + let beta = betas + .pop() + .expect("The betas must have at least one element"); + (beta, betas) + } + + #[allow(non_snake_case)] + pub(crate) fn append_h_commitment(fs_transcript: &mut Transcript, D: &E::G1) { + >>::append_h_commitment(fs_transcript, D); + } + + pub(crate) fn get_mu_challenges( + fs_transcript: &mut Transcript, + ell: usize, + ) -> (E::ScalarField, E::ScalarField, Vec) { + let mut mus = >>::challenges_for_linear_combination( + fs_transcript, + ell + 2, + ); + + let mu = mus.pop().expect("The mus must have at least one element"); + let mu_h = mus.pop().expect("The mus must have at least two elements"); + + (mu, mu_h, mus) + } + + #[allow(non_snake_case)] + pub(crate) fn get_gamma_challenge( + fs_transcript: &mut Transcript, + roots_of_unity: &Vec, + ) -> E::ScalarField { + loop { + let gamma = + >>::challenge_from_verifier(fs_transcript); + if !roots_of_unity.contains(&gamma) { + return gamma; + } + } + } +} + +/// This module defines a homomorphism that takes two scalar inputs and +/// maps them to a single group element output using two fixed base points. +/// Conceptually, this behaves similarly to a Pedersen commitment: +/// +/// `output = base_1 * scalar_1 + base_2 * scalar_2` +pub mod two_term_msm { + // TODO: maybe fixed_base_msms should become a folder and put its code inside mod.rs? Then put this mod inside of that folder? + use super::*; + use crate::sigma_protocol::{homomorphism::fixed_base_msms, traits::FirstProofItem}; + use aptos_crypto::arkworks::random::UniformRand; + use aptos_crypto_derive::SigmaProtocolWitness; + pub use sigma_protocol::homomorphism::TrivialShape as CodomainShape; + pub type Proof = sigma_protocol::Proof>; + + impl Proof { + /// Generates a random looking proof (but not a valid one). + /// Useful for testing and benchmarking. TODO: might be able to derive this through macros etc + pub fn generate(rng: &mut R) -> Self { + Self { + first_proof_item: FirstProofItem::Commitment(CodomainShape(unsafe_random_point( + rng, + ))), + z: Witness { + poly_randomness: Scalar::rand(rng), + hiding_kzg_randomness: Scalar::rand(rng), + }, + } + } + } + + /// Represents a homomorphism with two base points over an elliptic curve group. + /// + /// This structure defines a map from two scalars to one group element: + /// `f(x1, x2) = base_1 * x1 + base_2 * x2`. + #[derive(CanonicalSerialize, Clone, Debug, PartialEq, Eq)] + pub struct Homomorphism { + pub base_1: E::G1Affine, + pub base_2: E::G1Affine, + } + + #[derive( + SigmaProtocolWitness, CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq, + )] + pub struct Witness { + pub poly_randomness: Scalar, + pub hiding_kzg_randomness: Scalar, + } + + impl homomorphism::Trait for Homomorphism { + type Codomain = CodomainShape; + type Domain = Witness; + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + // Not doing `self.apply_msm(self.msm_terms(input))` because E::G1::msm is slower! + // `msm_terms()` is still useful for verification though: there the code will use it to produce an MSM + // of size 2+2 (the latter two are for the first prover message A and the statement P) + CodomainShape( + self.base_1 * input.poly_randomness.0 + self.base_2 * input.hiding_kzg_randomness.0, + ) + } + } + + impl fixed_base_msms::Trait for Homomorphism { + type Base = E::G1Affine; + type CodomainShape + = CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Eq + Debug; + type MsmInput = fixed_base_msms::MsmInput; + type MsmOutput = E::G1; + type Scalar = E::ScalarField; + + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + let mut scalars = Vec::with_capacity(2); + scalars.push(input.poly_randomness.0); + scalars.push(input.hiding_kzg_randomness.0); + + let mut bases = Vec::with_capacity(2); + bases.push(self.base_1); + bases.push(self.base_2); + + CodomainShape(fixed_base_msms::MsmInput { bases, scalars }) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + E::G1::msm(bases, scalars).expect("MSM failed in TwoTermMSM") + } + } + + impl sigma_protocol::Trait for Homomorphism { + fn dst(&self) -> Vec { + b"DEKART_V2_SIGMA_PROTOCOL".to_vec() + } + } +} + +/// The `n`th triangular number is the sum of the `n` natural numbers from 1 to `n`. +/// Here we compute the maximum `n` such that `1 + 2 + ... + n <= a`, using integer +/// arithmetic and the num_integer crate. +fn floored_triangular_root(a: usize) -> usize { + // Solve `n*(n+1)/2 <= a`, or equivalently `n^2 + n - 2a <= 0` + let discriminant = 1 + 8 * a; + let sqrt_disc = discriminant.sqrt(); // integer sqrt + (sqrt_disc - 1) / 2 +} + +#[cfg(test)] +mod test_floored_triangular_root { + use super::floored_triangular_root; + + #[test] + fn test_invert_triangular_number_small_values() { + assert_eq!(floored_triangular_root(0), 0); + assert_eq!(floored_triangular_root(1), 1); // 1 <= 1 + assert_eq!(floored_triangular_root(2), 1); // 1+2 > 2 + assert_eq!(floored_triangular_root(3), 2); // 1+2=3 <= 3 + assert_eq!(floored_triangular_root(5), 2); // 1+2+3=6 > 5 + assert_eq!(floored_triangular_root(6), 3); + } +} diff --git a/crates/aptos-dkg/src/range_proofs/mod.rs b/crates/aptos-dkg/src/range_proofs/mod.rs new file mode 100644 index 00000000000..baf86065129 --- /dev/null +++ b/crates/aptos-dkg/src/range_proofs/mod.rs @@ -0,0 +1,6 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod dekart_univariate; +pub mod dekart_univariate_v2; +pub mod traits; diff --git a/crates/aptos-dkg/src/range_proofs/traits.rs b/crates/aptos-dkg/src/range_proofs/traits.rs new file mode 100644 index 00000000000..cf19ce26386 --- /dev/null +++ b/crates/aptos-dkg/src/range_proofs/traits.rs @@ -0,0 +1,64 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::{random::UniformRand, GroupGenerators}; +use ark_ec::pairing::Pairing; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use rand::{CryptoRng, RngCore}; + +pub trait BatchedRangeProof: Clone + CanonicalSerialize + CanonicalDeserialize { + type PublicStatement: CanonicalSerialize; + type ProverKey; + type VerificationKey: Clone + CanonicalSerialize; // Serialization is needed because this key is often appended to a Fiat-Shamir transcript + type Input: From; // TODO: slightly hacky. It's used in `range_proof_random_instance()` to generate (chunks of) inputs that have a certain bit size + type Commitment; + type CommitmentRandomness: Clone + UniformRand; + type CommitmentKey; + + const DST: &[u8]; + + fn commitment_key_from_prover_key(pk: &Self::ProverKey) -> Self::CommitmentKey; + + /// Setup generates the prover and verifier keys used in the batched range proof. + fn setup( + max_n: usize, + max_ell: usize, // TODO: change this to u8? + group_generators: GroupGenerators, + rng: &mut R, + ) -> (Self::ProverKey, Self::VerificationKey); + + fn commit( + ck: &Self::CommitmentKey, + values: &[Self::Input], + rng: &mut R, + ) -> (Self::Commitment, Self::CommitmentRandomness) { + let r = Self::CommitmentRandomness::rand(rng); + let comm = Self::commit_with_randomness(ck, values, &r.clone()); + (comm, r) + } + + fn commit_with_randomness( + ck: &Self::CommitmentKey, + values: &[Self::Input], + r: &Self::CommitmentRandomness, + ) -> Self::Commitment; + + fn prove( + pk: &Self::ProverKey, + values: &[Self::Input], + ell: usize, // TODO: change this to u8? + comm: &Self::Commitment, + r: &Self::CommitmentRandomness, + rng: &mut R, + ) -> Self; + + fn verify( + &self, + vk: &Self::VerificationKey, + n: usize, + ell: usize, + comm: &Self::Commitment, + ) -> anyhow::Result<()>; + + fn maul(&mut self); +} diff --git a/crates/aptos-dkg/src/sigma_protocol/homomorphism/fixed_base_msms.rs b/crates/aptos-dkg/src/sigma_protocol/homomorphism/fixed_base_msms.rs new file mode 100644 index 00000000000..30169d6ef73 --- /dev/null +++ b/crates/aptos-dkg/src/sigma_protocol/homomorphism/fixed_base_msms.rs @@ -0,0 +1,181 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + sigma_protocol, + sigma_protocol::{homomorphism, homomorphism::EntrywiseMap, Witness}, +}; +use ark_ec::pairing::Pairing; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use std::fmt::Debug; + +/// A `FixedBaseMsms` instance represents a homomorphism whose outputs can be expressed as +/// one or more **fixed-base multi-scalar multiplications (MSMs)**, sharing consistent base and scalar types. +/// +/// When such homomorphisms are used in a Σ-protocol, the resulting verification equations can be batched efficiently +/// via a Schwartz–Zippel–style random linear combination. This requires uniformly iterating over all MSMs involved +/// in the proof and public statement. +/// +/// Typically, MSM bases are fixed early in the protocol (e.g., as powers of τ or other public parameters), +/// and only the scalars vary as inputs. +/// +/// This trait provides: +/// - Methods for computing the MSM representations of a homomorphism input. +/// - A uniform “shape” abstraction for collecting and flattening MSM outputs +/// for batch verification in Σ-protocols. +pub trait Trait: homomorphism::Trait> { + /// The scalar type used in the MSMs. + type Scalar: Clone; + + /// The group/base type used in the MSMs. Current instantiations always use E::G1Affine but as explained + /// in the TODO of doc comment of `fn verify_msm_hom`, we might want to be working with enums here in the future. + type Base: Clone; + + /// Type representing a single MSM input (a set of bases and scalars). Normally, this would default + /// to `MsmInput`, but stable Rust does not yet support associated type defaults, + /// hence we introduce a trait `IsMsmInput` and struct `MsmInput` below. + type MsmInput: CanonicalSerialize + + CanonicalDeserialize + + Clone + + IsMsmInput + + Debug + + Eq; + + /// The output type of evaluating an MSM. `Codomain` should equal `CodomainShape`, in the current version + /// of the code. In a future version where MsmOutput might be an enum (E::G1 or E::G2), Codomain should probably follow suit. + /// (TODO: Think this over) + type MsmOutput: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + + /// Represents the **shape** of the homomorphism's output, parameterized by an inner type `T`. + /// + /// ### Overview + /// The codomain of a homomorphism is often a **nested structure** — for example, `Vec>`. + /// In the case of a `FixedBaseMsms`, the homomorphism then factorizes as: + /// + /// Domain ─▶ Vec> ─▶ Vec> = Codomain + /// + /// For **efficient batch verification**, it’s useful to collect all MSM terms together and + /// combine them with the sigma proof’s *commitment* (the first prover message) and the public statement. + /// To do this consistently, we need a uniform way to iterate over nested structures such as `Vec>` + /// to access all elements in a **consistent** order. + /// + /// ### TODO + /// - The use of `IntoIterator` leads to cloning, which might not be very efficient + type CodomainShape: EntrywiseMap = Self::CodomainShape> + + IntoIterator + + CanonicalSerialize + + CanonicalDeserialize + + Clone + + Debug + + Eq + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + + /// Returns the MSM terms corresponding to a given homomorphism input. + /// + /// The result is structured such that applying MSM evaluation elementwise + /// yields the homomorphism’s output. + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape; + + /// Evaluates a single MSM instance given slices of bases and scalars. Current instantiations always use E::G1Affine + /// for the base, but we might want to use enums for the base and output in the future. + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput; + + /// Applies `msm_eval` elementwise to a collection of MSM inputs. + fn apply_msm( + &self, + msms: Self::CodomainShape, + ) -> Self::CodomainShape + where + Self::CodomainShape: EntrywiseMap< + Self::MsmInput, + Output = Self::CodomainShape, + >, + { + msms.map(|msm_input| Self::msm_eval(&msm_input.bases(), &msm_input.scalars())) + } +} + +/// Workaround (see the main trait below) because stable Rust does not yet support associated type defaults. +pub trait IsMsmInput { + /// Returns a reference to the slice of base elements in this MSM input. + fn bases(&self) -> &[B]; + + /// Returns a reference to the slice of scalar elements in this MSM input. + fn scalars(&self) -> &[S]; +} + +/// Represents the input to a (not necessarily fixed-base) multi-scalar multiplication (MSM): +/// a collection of bases and corresponding scalars. +/// TODO: Might not be the right file for this struct, since not necessarily fixed-base +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct MsmInput< + B: CanonicalSerialize + CanonicalDeserialize, + S: CanonicalSerialize + CanonicalDeserialize, +> { + pub bases: Vec, + pub scalars: Vec, +} + +impl< + B: CanonicalSerialize + CanonicalDeserialize, + S: CanonicalSerialize + CanonicalDeserialize, + > IsMsmInput for MsmInput +{ + fn bases(&self) -> &[B] { + &self.bases + } + + fn scalars(&self) -> &[S] { + &self.scalars + } +} + +// Implements FixedBaseMsms for the LiftHomomorphism wrapper. +// This allows us to perform multi-scalar multiplications (MSM) on a "lifted" homomorphism +// by delegating the actual MSM computation to the underlying homomorphism type `H`. +impl Trait for homomorphism::LiftHomomorphism +where + H: Trait, +{ + type Base = H::Base; + type CodomainShape + = H::CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = H::MsmInput; + type MsmOutput = H::MsmOutput; + type Scalar = H::Scalar; + + /// Returns the MSM terms corresponding to a given homomorphism input. The output is shaped so that applying the MSM elementwise yields the homomorphism output. + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + let projected = (self.projection)(input); + self.hom.msm_terms(&projected) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + H::msm_eval(bases, scalars) + } +} + +impl sigma_protocol::Trait + for homomorphism::LiftHomomorphism +where + H: sigma_protocol::Trait, + LargerDomain: Witness, +{ + fn dst(&self) -> Vec { + let mut dst = Vec::new(); + + let dst_original = self.hom.dst(); + + // Domain-separate them properly so concatenation is unambiguous. + // Prefix with their lengths so [a|b] and [ab|] don't collide. + dst.extend_from_slice(b"Lift("); + dst.extend_from_slice(&(dst_original.len() as u32).to_be_bytes()); + dst.extend_from_slice(&dst_original); + dst.extend_from_slice(b")"); + + dst + } +} diff --git a/crates/aptos-dkg/src/sigma_protocol/homomorphism/mod.rs b/crates/aptos-dkg/src/sigma_protocol/homomorphism/mod.rs new file mode 100644 index 00000000000..ed349a9f9d4 --- /dev/null +++ b/crates/aptos-dkg/src/sigma_protocol/homomorphism/mod.rs @@ -0,0 +1,139 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use ark_serialize::{ + CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Write, +}; +use std::fmt::Debug; + +pub mod fixed_base_msms; +pub mod tuple; + +/// A `Homomorphism` represents a structure-preserving map between algebraic objects. +/// +/// Formally, it is a function from a `Domain` to a `Codomain` that preserves +/// the relevant algebraic structure (e.g. group, ring, or module operations). +/// +/// In the context of sigma protocols, homomorphisms are the key building blocks: +/// they capture the algebraic relations that proofs are designed to demonstrate. +/// +/// CanonicalSerialize is added here so its parameters (which will be MSM bases) +/// can be used for Fiat-Shamir challenges. +pub trait Trait: CanonicalSerialize { + type Domain; + type Codomain; + + fn apply(&self, element: &Self::Domain) -> Self::Codomain; +} + +/// `LiftHomomorphism` adapts a homomorphism `H` defined on some `Domain` +/// so that it can act on a larger `LargerDomain` by precomposing `H` +/// with a natural projection map `π`, which should also be a homomorphism. +/// +/// In other words, given: +/// - a homomorphism `h: Domain -> Codomain` +/// - another homomorphism `π: LargerDomain -> Domain` +/// +/// `LiftHomomorphism` represents the composed homomorphism: +/// `h ∘ π : LargerDomain -> Codomain`. +/// +/// # Example +/// +/// A common case is when `LargerDomain` is a Cartesian product type like `X × Y` +/// and the projection is `(x, y) ↦ x`. Then `LiftHomomorphism` +/// lets `h` act on the first component of the pair, so `(h ∘ π)(x,y) = h(x)`. +/// +/// Naturally this method immediately extends to composing arbitrary homomorphisms, +/// but we don't need that formalism for now. We are not deriving Eq here because +/// function pointer comparisons do not seem useful in this context. +#[derive(Debug, Clone)] +pub struct LiftHomomorphism +where + H: Trait, +{ + pub hom: H, + pub projection: fn(&LargerDomain) -> H::Domain, +} + +// We only care about the "bases" that are being used to define the homomorphism, so in serializing +// we ignore `projection` entirely +impl CanonicalSerialize for LiftHomomorphism +where + H: Trait, +{ + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.hom.serialize_with_mode(&mut writer, compress) + } + + fn serialized_size(&self, compress: Compress) -> usize { + self.hom.serialized_size(compress) + } +} + +/// Implements `Homomorphism` for `LiftHomomorphism` by composing +/// the original homomorphism with the projection. +/// +/// That is, applying `LiftHomomorphism` to an input `x` is equivalent to +/// first computing `projection(x)` and then applying `hom` to the result. +impl Trait for LiftHomomorphism +where + H: Trait, +{ + type Codomain = H::Codomain; + type Domain = LargerDomain; + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + let projected = (self.projection)(input); + self.hom.apply(&projected) + } +} + +/// A trait for types that support **entrywise mapping** over their contents. +/// +/// Given a value of this type, you can apply a function to each "entry" independently, +/// producing a new value of the same shape but possibly with a different inner type. +pub trait EntrywiseMap { + /// The resulting type after mapping the inner elements to type `U`. + type Output; + + fn map(self, f: F) -> Self::Output + where + F: Fn(T) -> U, + U: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; +} + +/// A trivial wrapper type for a single value. Should be used to wrap when the codomain of a homomorphism is something like E::G1 +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct TrivialShape(pub T); + +/// Implements `EntrywiseMap` for `TrivialShape`, mapping the inner value. +impl EntrywiseMap + for TrivialShape +{ + type Output = + TrivialShape; + + fn map(self, f: F) -> Self::Output + where + F: Fn(T) -> U, + U: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq, + { + TrivialShape(f(self.0)) + } +} + +/// Implements `IntoIterator` for `TrivialShape`, producing a single-element iterator. +impl IntoIterator + for TrivialShape +{ + type IntoIter = std::iter::Once; + type Item = T; + + fn into_iter(self) -> Self::IntoIter { + std::iter::once(self.0) + } +} diff --git a/crates/aptos-dkg/src/sigma_protocol/homomorphism/tuple.rs b/crates/aptos-dkg/src/sigma_protocol/homomorphism/tuple.rs new file mode 100644 index 00000000000..e0d36f81505 --- /dev/null +++ b/crates/aptos-dkg/src/sigma_protocol/homomorphism/tuple.rs @@ -0,0 +1,210 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + sigma_protocol, + sigma_protocol::{ + homomorphism, + homomorphism::{fixed_base_msms::Trait, EntrywiseMap}, + }, +}; +use ark_ec::pairing::Pairing; +use ark_serialize::{ + CanonicalDeserialize, CanonicalSerialize, Compress, Read, SerializationError, Valid, +}; +pub use ark_std::io::Write; +use std::fmt::Debug; + +/// `TupleHomomorphism` combines two homomorphisms with the same domain +/// into a single homomorphism that outputs a tuple of codomains. +/// +/// Formally, given: +/// - `h1: Domain -> Codomain1` +/// - `h2: Domain -> Codomain2` +/// +/// we obtain a new homomorphism `h: Domain -> (Codomain1, Codomain2)` defined by +/// `h(x) = (h1(x), h2(x))`. +/// +/// In category-theoretic terms, this is the composition of the diagonal map +/// `Δ: Domain -> Domain × Domain` with the product map `h1 × h2`. +#[derive(CanonicalSerialize, Debug, Clone, PartialEq, Eq)] +pub struct TupleHomomorphism +where + H1: homomorphism::Trait, + H2: homomorphism::Trait, +{ + pub hom1: H1, + pub hom2: H2, +} + +/// Implements `Homomorphism` for `TupleHomomorphism` by applying both +/// component homomorphisms to the same input and returning their results +/// as a tuple. +/// +/// In other words, for input `x: Domain`, this produces +/// `(hom1(x), hom2(x))`. For technical reasons, we then put the output inside a wrapper. +impl homomorphism::Trait for TupleHomomorphism +where + H1: homomorphism::Trait, + H2: homomorphism::Trait, + H1::Codomain: CanonicalSerialize + CanonicalDeserialize, + H2::Codomain: CanonicalSerialize + CanonicalDeserialize, +{ + type Codomain = TupleCodomainShape; + type Domain = H1::Domain; + + fn apply(&self, x: &Self::Domain) -> Self::Codomain { + TupleCodomainShape(self.hom1.apply(x), self.hom2.apply(x)) + } +} + +/// A wrapper to combine the codomain shapes of two homomorphisms into a single type. +/// +/// This is necessary because Rust tuples do **not** inherit traits like `IntoIterator`, +/// but `fixed_base_msms::CodomainShape` requires them. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TupleCodomainShape(pub A, pub B); + +impl CanonicalSerialize for TupleCodomainShape +where + A: CanonicalSerialize, + B: CanonicalSerialize, +{ + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.0.serialize_with_mode(&mut writer, compress)?; + self.1.serialize_with_mode(&mut writer, compress)?; + Ok(()) + } + + fn serialized_size(&self, compress: Compress) -> usize { + self.0.serialized_size(compress) + self.1.serialized_size(compress) + } +} + +impl CanonicalDeserialize for TupleCodomainShape +where + A: CanonicalDeserialize, + B: CanonicalDeserialize, +{ + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: ark_serialize::Validate, + ) -> Result { + let a = A::deserialize_with_mode(&mut reader, compress, validate)?; + let b = B::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self(a, b)) + } +} + +impl Valid for TupleCodomainShape +where + A: Valid, + B: Valid, +{ + fn check(&self) -> Result<(), SerializationError> { + self.0.check()?; + self.1.check()?; + Ok(()) + } +} + +impl IntoIterator for TupleCodomainShape +where + A: IntoIterator, + B: IntoIterator, +{ + type IntoIter = std::iter::Chain; + type Item = T; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter().chain(self.1.into_iter()) + } +} + +impl EntrywiseMap for TupleCodomainShape +where + A: EntrywiseMap, + B: EntrywiseMap, +{ + type Output = + TupleCodomainShape, B::Output>; + + fn map(self, f: F) -> Self::Output + where + F: Fn(T) -> U, + U: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq, + { + TupleCodomainShape(self.0.map(&f), self.1.map(f)) + } +} + +/// Implementation of `FixedBaseMsms` for a tuple of two homomorphisms. +/// +/// This allows combining two homomorphisms that share the same `Domain`. +/// For simplicity, we currently require that the MSM types (`MsmInput` and `MsmOutput`) match; +/// this ensures compatibility with batch verification in a Σ-protocol and may be relaxed in the future. +/// For the moment, we **implicitly** assume that the two msm_eval methods are identical, but is probably +/// not necessary through enums. +/// +/// The codomain shapes of the two homomorphisms are combined using `TupleCodomainShape`. +impl Trait for TupleHomomorphism +where + H1: Trait, + H2: Trait< + Domain = H1::Domain, + Scalar = H1::Scalar, + Base = H1::Base, + MsmInput = H1::MsmInput, + MsmOutput = H1::MsmOutput, + >, +{ + type Base = H1::Base; + type CodomainShape + = TupleCodomainShape, H2::CodomainShape> + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = H1::MsmInput; + type MsmOutput = H1::MsmOutput; + type Scalar = H1::Scalar; + + /// Returns the MSM terms for each homomorphism, combined into a tuple. + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + let terms1 = self.hom1.msm_terms(input); + let terms2 = self.hom2.msm_terms(input); + TupleCodomainShape(terms1, terms2) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + H1::msm_eval(bases, scalars) + } +} + +impl sigma_protocol::Trait for TupleHomomorphism +where + H1: sigma_protocol::Trait, + H2: sigma_protocol::Trait, + H2: Trait, +{ + fn dst(&self) -> Vec { + let mut dst = Vec::new(); + + let dst1 = self.hom1.dst(); + let dst2 = self.hom2.dst(); + + // Domain-separate them properly so concatenation is unambiguous. + // Prefix with their lengths so [a|b] and [ab|] don't collide. + dst.extend_from_slice(b"TupleHomomorphism("); + dst.extend_from_slice(&(dst1.len() as u32).to_be_bytes()); + dst.extend_from_slice(&dst1); + dst.extend_from_slice(&(dst2.len() as u32).to_be_bytes()); + dst.extend_from_slice(&dst2); + dst.extend_from_slice(b")"); + + dst + } +} diff --git a/crates/aptos-dkg/src/sigma_protocol/mod.rs b/crates/aptos-dkg/src/sigma_protocol/mod.rs new file mode 100644 index 00000000000..c0d8bf3dc4a --- /dev/null +++ b/crates/aptos-dkg/src/sigma_protocol/mod.rs @@ -0,0 +1,7 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub use traits::{Proof, Statement, Trait, Witness}; + +pub mod homomorphism; +pub mod traits; diff --git a/crates/aptos-dkg/src/sigma_protocol/traits.rs b/crates/aptos-dkg/src/sigma_protocol/traits.rs new file mode 100644 index 00000000000..31ca41503fb --- /dev/null +++ b/crates/aptos-dkg/src/sigma_protocol/traits.rs @@ -0,0 +1,533 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + fiat_shamir, + sigma_protocol::homomorphism::{ + self, + fixed_base_msms::{self, IsMsmInput}, + }, + Scalar, +}; +use anyhow::ensure; +use aptos_crypto::{arkworks::random::sample_field_element, utils}; +use ark_ec::{pairing::Pairing, CurveGroup, VariableBaseMSM}; +use ark_ff::AdditiveGroup; +use ark_serialize::{ + CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate, +}; +use ark_std::{io::Read, UniformRand}; +use serde::Serialize; +use std::{fmt::Debug, io::Write}; + +pub trait Trait: + fixed_base_msms::Trait< + Domain: Witness, + Scalar = E::ScalarField, + Base = E::G1Affine, + MsmOutput = E::G1, + > + Sized + + CanonicalSerialize +{ + fn dst(&self) -> Vec; + + fn prove( + &self, + witness: &Self::Domain, + statement: &Self::Codomain, + ctxt: &C, + rng: &mut R, + ) -> Proof { + prove_homomorphism(self, witness, statement, ctxt, true, rng, &self.dst()) + } + + #[allow(non_snake_case)] + fn verify( + &self, + public_statement: &Self::Codomain, + proof: &Proof, // Would like to set &Proof, but that ties the lifetime of H to that of Self, but we'd like it to be eg static + ctxt: &C, + ) -> anyhow::Result<()> + where + H: homomorphism::Trait, + { + verify_msm_hom::<_, E, Self>( + self, + public_statement, + match &proof.first_proof_item { + FirstProofItem::Commitment(A) => A, + FirstProofItem::Challenge(_) => { + anyhow::bail!("Missing implementation - expected commitment, not challenge") + }, + }, + &proof.z, + ctxt, + &self.dst(), + ) + } +} + +pub trait Witness: CanonicalSerialize + CanonicalDeserialize + Clone + Eq { + /// The scalar type associated with the domain. + type Scalar: CanonicalSerialize + CanonicalDeserialize + Copy; // Not using this atm... + + /// Computes a scaled addition: `self + c * other`. Can take ownership because the randomness is discarded by the prover afterwards + fn scaled_add(self, other: &Self, c: E::ScalarField) -> Self; + + /// Samples a random element in the domain. The prover has a witness w and calls w.sample_randomness(rng) to get the prover's first nonce (of the same "size" as w, hence why this cannot be a static method), which it then uses to compute the prover's first message in the sigma protocol. + fn rand(&self, rng: &mut R) -> Self; +} + +impl Witness for Scalar { + type Scalar = Scalar; + + fn scaled_add(self, other: &Self, c: E::ScalarField) -> Self { + Scalar(self.0 + (c) * other.0) + } + + fn rand(&self, rng: &mut R) -> Self { + Scalar(sample_field_element(rng)) + } +} + +impl> Witness for Vec { + type Scalar = W::Scalar; + + fn scaled_add(self, other: &Self, c: E::ScalarField) -> Self { + self.into_iter() + .zip(other.iter()) + .map(|(a, b)| a.scaled_add(b, c)) + .collect() + } + + fn rand(&self, rng: &mut R) -> Self { + self.iter().map(|elem| elem.rand(rng)).collect() + } +} + +// Standard method to get `trait Statement = Canonical Serialize + ...`, because type aliases are experimental in Rust +pub trait Statement: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq {} +impl Statement for T where T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq {} + +/// The “first item” recorded in a Σ-proof, which is one of: +/// - The first message of the protocol, which is the commitment from the prover. This leads to a more compact proof. +/// - The second message of the protocol, which is the challenge from the verifier. This leads to a proof which is amenable to batch verification. +/// TODO: Better name? In https://github.com/sigma-rs/sigma-proofs these would be called "compact" and "batchable" proofs +#[derive(Clone, Debug, Eq)] +pub enum FirstProofItem +where + H::Codomain: Statement, +{ + Commitment(H::Codomain), + Challenge(E::ScalarField), // In more generality, this should be H::Domain::Scalar +} + +// Manual implementation of PartialEq is required here because deriving PartialEq would +// automatically require `H` itself to implement PartialEq, which is undesirable. +impl PartialEq for FirstProofItem +where + H::Codomain: Statement, +{ + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (FirstProofItem::Commitment(a), FirstProofItem::Commitment(b)) => a == b, + (FirstProofItem::Challenge(a), FirstProofItem::Challenge(b)) => a == b, + _ => false, + } + } +} + +// The natural CanonicalSerialize/Deserialize implementations for `FirstProofItem`; we follow the usual approach for enums. +// CanonicalDeserialize needs Valid. +impl Valid for FirstProofItem +where + H::Domain: Witness, + H::Codomain: Statement + Valid, + E::ScalarField: Valid, +{ + fn check(&self) -> Result<(), SerializationError> { + match self { + FirstProofItem::Commitment(c) => c.check(), + FirstProofItem::Challenge(f) => f.check(), + } + } +} + +impl CanonicalSerialize for FirstProofItem +where + H::Domain: Witness, + H::Codomain: Statement + CanonicalSerialize, + E::ScalarField: CanonicalSerialize, +{ + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + match self { + FirstProofItem::Commitment(c) => { + 0u8.serialize_with_mode(writer.by_ref(), compress)?; + c.serialize_with_mode(writer, compress) + }, + FirstProofItem::Challenge(f) => { + 1u8.serialize_with_mode(writer.by_ref(), compress)?; + f.serialize_with_mode(writer, compress) + }, + } + } + + fn serialized_size(&self, compress: Compress) -> usize { + 1 + match self { + FirstProofItem::Commitment(c) => c.serialized_size(compress), + FirstProofItem::Challenge(f) => f.serialized_size(compress), + } + } +} + +impl CanonicalDeserialize for FirstProofItem +where + H::Domain: Witness, + H::Codomain: Statement + CanonicalDeserialize + Valid, + E::ScalarField: CanonicalDeserialize + Valid, +{ + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: Validate, + ) -> Result { + // Read the discriminant tag + let tag = u8::deserialize_with_mode(&mut reader, compress, validate)?; + + let item = match tag { + 0 => { + let c = H::Codomain::deserialize_with_mode(reader, compress, validate)?; + FirstProofItem::Commitment(c) + }, + 1 => { + let f = E::ScalarField::deserialize_with_mode(reader, compress, validate)?; + FirstProofItem::Challenge(f) + }, + _ => return Err(SerializationError::InvalidData), + }; + + // Run validity check if requested + if validate == Validate::Yes { + item.check()?; + } + + Ok(item) + } +} + +#[derive(CanonicalSerialize, Debug, CanonicalDeserialize, Clone)] +pub struct Proof +where + H::Domain: Witness, + H::Codomain: Statement, +{ + /// The “first item” recorded in the proof, which can be either: + /// - the prover's commitment (H::Codomain) + /// - the verifier's challenge (E::ScalarField) + pub first_proof_item: FirstProofItem, + /// Prover's second message (response) + pub z: H::Domain, +} + +impl Proof +where + H::Domain: Witness, + H::Codomain: Statement, +{ + /// No-op (semantically): circumvents the fact that proofs inherit the homomorphism’s lifetime. This method should do nothing at runtime. + #[allow(non_snake_case)] + pub fn change_lifetime

(self) -> Proof + where + H2: homomorphism::Trait, + { + let first = match self.first_proof_item { + FirstProofItem::Commitment(A) => FirstProofItem::Commitment(A), + FirstProofItem::Challenge(c) => FirstProofItem::Challenge(c), + }; + + Proof { + first_proof_item: first, + z: self.z, + } + } +} + +// Manual implementation of PartialEq and Eq is required here because deriving PartialEq/Eq would +// automatically require `H` itself to implement PartialEq and Eq, which is undesirable. +// Workaround would be to make `Proof` generic over `H::Domain` and `H::Codomain` instead of `H` +impl PartialEq for Proof +where + H::Domain: Witness, + H::Codomain: Statement, +{ + fn eq(&self, other: &Self) -> bool { + self.first_proof_item == other.first_proof_item && self.z == other.z + } +} + +impl Eq for Proof +where + H::Domain: Witness, + H::Codomain: Statement, +{ +} + +/// Computes the Fiat–Shamir challenge for a Σ-protocol instance. +/// +/// This function derives a non-interactive challenge scalar by appending +/// protocol-specific data to a Merlin transcript. In the abstraction used here, +/// the protocol proves knowledge of a preimage under a homomorphism. Therefore, +/// all public data relevant to that homomorphism (e.g., its MSM bases) and +/// the image under consideration are included in the transcript. +/// +/// # Arguments +/// - `ctxt`: Extra "context" material that needs to be hashed for the challenge. +/// - `hom`: The homomorphism structure carrying its public data (e.g., MSM bases). +/// - `statement`: The public statement, i.e. the image of a witness under the homomorphism. +/// - `prover_first_message`: the first message in the Σ-protocol (the prover's commitment) +/// - `dst`: A domain separation tag to ensure unique challenges per protocol. +/// +/// # Returns +/// The derived Fiat–Shamir challenge scalar, after incorporating the domain +/// separator, public data, statement, and prover’s first message into the transcript. +pub fn fiat_shamir_challenge_for_sigma_protocol< + C: Serialize, + E: Pairing, + H: homomorphism::Trait + CanonicalSerialize, +>( + ctxt: &C, + hom: &H, + statement: &H::Codomain, + prover_first_message: &H::Codomain, + dst: &[u8], +) -> E::ScalarField +where + H::Domain: Witness, + H::Codomain: Statement, +{ + // Initialise the transcript + let mut fs_t = merlin::Transcript::new(dst); + + // Append the "context" to the transcript + >::append_sigma_protocol_ctxt( + &mut fs_t, ctxt, + ); + + // Append the MSM bases to the transcript. (If the same hom is used for many proofs, maybe use a single transcript + a boolean to prevent it from repeating?) + >::append_sigma_protocol_msm_bases( + &mut fs_t, hom, + ); + + // Append the public statement (the image of the witness) to the transcript + >::append_sigma_protocol_public_statement( + &mut fs_t, + statement, + ); + + // Add the first prover message (the commitment) to the transcript + >::append_sigma_protocol_first_prover_message( + &mut fs_t, + prover_first_message, + ); + + // Generate the Fiat-Shamir challenge from the updated transcript + >::challenge_for_sigma_protocol( + &mut fs_t, + ) +} + +#[allow(non_snake_case)] +pub fn prove_homomorphism< + C: Serialize, + E: Pairing, + H: homomorphism::Trait + CanonicalSerialize, + R, +>( + homomorphism: &H, + witness: &H::Domain, + statement: &H::Codomain, + ctxt: &C, + store_prover_commitment: bool, // true = store prover's commitment, false = store Fiat-Shamir challenge + rng: &mut R, + dst: &[u8], +) -> Proof +where + H::Domain: Witness, + H::Codomain: Statement, + R: rand_core::RngCore + rand_core::CryptoRng, +{ + // Step 1: Sample randomness. Here the `witness` is used to make sure that `r` has the right dimension + let r = witness.rand(rng); + + // Step 2: Compute commitment A = Ψ(r) + let A = homomorphism.apply(&r); + + // Step 3: Obtain Fiat-Shamir challenge + let c = + fiat_shamir_challenge_for_sigma_protocol::<_, E, H>(ctxt, homomorphism, statement, &A, dst); + + // Step 4: Compute prover response + let z = r.scaled_add(&witness, c); + + // Step 5: Pick first **recorded** item + let first_proof_item = if store_prover_commitment { + FirstProofItem::Commitment(A) + } else { + FirstProofItem::Challenge(c) + }; + + Proof { + first_proof_item, + z, + } +} + +// This function is currently not used, see comments in `fn verify()` +// pub fn fiat_shamir_challenge_for_msm_verifier( +// fs_transcript: &mut merlin::Transcript, +// public_statement: &H::Codomain, +// prover_last_message: &H::Domain, +// dst: &[u8], +// ) -> E::ScalarField +// where +// H::Domain: Witness, +// H::Codomain: Statement, +// { +// // Append the Σ-protocol separator to the transcript +// >::append_sigma_protocol_sep( +// fs_transcript, +// dst, +// ); + +// // Add the last prover message (the prover's response) to the transcript +// >::append_sigma_protocol_last_message( +// fs_transcript, +// prover_last_message, +// ); + +// // Add the public statment (the image of the prover's witness) to the transcript +// >::append_sigma_protocol_public_statement( +// fs_transcript, +// public_statement, +// ); + +// // Generate the Fiat-Shamir challenge from the updated transcript +// >::challenge_for_sigma_protocol( +// fs_transcript, +// ) +// } + +/// Performs a **batch verification** of multiple Sigma protocol MSM (Multi-Scalar Multiplication) relations. +/// +/// ### Overview +/// Suppose we need to verify a family of equations of the form: +/// +/// ```text +/// ∑_i g_{i,j} * x_{i,j} = A_j + P_j * c for each index j. +/// ``` +/// +/// Instead of checking each equation individually, we batch them using a random challenge \(\beta\). +/// The verifier checks that: +/// +/// ```text +/// ∑_j β^j * ( ∑_i g_{i,j} * x_{i,j} - A_j - P_j * c ) = 0 +/// ``` +/// +/// This reduces the verification of multiple MSM-based equations to a single MSM check, +/// significantly improving efficiency. +/// +/// ### Generalization +/// This batching technique can be extended to simultaneously verify multiple protocols +/// that involve MSM relations. +/// +/// ### Notes +/// - The random challenge \(\beta\) is currently sampled locally by the verifier, for composability with larger protocols. But this could be derived via Fiat–Shamir as well. (TODO: Pending discussion) +/// +/// ### TODO +/// - The code is currently set up on the case where the MSM input representation is +/// `Vec<(Scalars, Bases)> = Vec<(E::ScalarField, E::G1Affine)>`. If we want to add a +/// homomorphism whose codomain has components in both G_1 and G_2, we should probably put +/// the `Bases` component and MsmOutput inside of enums. +#[allow(non_snake_case)] +pub fn verify_msm_hom( + homomorphism: &H, + statement: &H::Codomain, + prover_first_message: &H::Codomain, + prover_last_message: &H::Domain, + ctxt: &C, + dst: &[u8], +) -> anyhow::Result<()> +where + H: fixed_base_msms::Trait + + CanonicalSerialize, + H::Domain: Witness, +{ + // Step 1: Reproduce the prover's Fiat-Shamir challenge + let c = fiat_shamir_challenge_for_sigma_protocol::<_, E, H>( + ctxt, + homomorphism, + statement, + &prover_first_message, + dst, + ); + + // Step 2: Compute verifier-specific challenge (used for weighted MSM) + + // While this could be derived deterministically via Fiat–Shamir, doing so would require + // integrating it into the prover as well for composability. For simplicity, we follow + // the standard approach instead. + + // let beta = fiat_shamir_challenge_for_msm_verifier::( + // fs_transcript, + // public_statement, + // prover_last_message, + // dst_verifier, + // ); + let mut rng = ark_std::rand::thread_rng(); + let beta = E::ScalarField::rand(&mut rng); + + let msm_terms = homomorphism.msm_terms(prover_last_message); + let powers_of_beta = utils::powers(beta, statement.clone().into_iter().count()); // TODO: Maybe get rid of clone? Is .count() an efficient way to get the length? + + let terms_iter = msm_terms.clone().into_iter(); // TODO: get rid of these clones? + let prover_iter = prover_first_message.clone().into_iter(); + let statement_iter = statement.clone().into_iter(); + + let mut final_basis = Vec::new(); + let mut final_scalars = Vec::new(); + + for (((term, A), P), beta_power) in terms_iter + .zip(prover_iter) + .zip(statement_iter) + .zip(powers_of_beta) + { + // Destructure term and create a new MsmInput + let mut bases = term.bases().to_vec(); + let mut scalars = term.scalars().to_vec(); + + for scalar in scalars.iter_mut() { + *scalar *= beta_power; + } + + // Append bases/scalars from prover and statement + bases.push(A.clone().into_affine()); // TODO: do a batch into affine + bases.push(P.clone().into_affine()); // TODO: do a batch into affine + + scalars.push(-H::Scalar::from(1u8) * beta_power); + scalars.push(-c * beta_power); + + final_basis.extend(bases); + final_scalars.extend(scalars); + } + + // Step 7: Perform the final MSM check. TODO: Could use msm_eval here? + let msm_result = + E::G1::msm(&final_basis, &final_scalars).expect("Could not compute MSM for verifier"); + ensure!(msm_result == E::G1::ZERO); + + Ok(()) +} diff --git a/crates/aptos-dkg/src/utils/biguint.rs b/crates/aptos-dkg/src/utils/biguint.rs deleted file mode 100644 index c6c63b11837..00000000000 --- a/crates/aptos-dkg/src/utils/biguint.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::SCALAR_NUM_BYTES; -use blstrs::Scalar; -use ff::Field; -use num_bigint::BigUint; - -/// Returns the order of the scalar field in our implementation's choice of an elliptic curve group. -pub(crate) fn get_scalar_field_order_as_biguint() -> BigUint { - let r = BigUint::from_bytes_be( - hex::decode("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") - .unwrap() - .as_slice(), - ); - - // Here, we paranoically assert that r is correct, by checking 0 - 1 mod r (computed via Scalar) equals r-1 (computed from the constant above) - let minus_one = Scalar::ZERO - Scalar::ONE; - let max = &r - 1u8; - assert_eq!( - minus_one.to_bytes_le().as_slice(), - max.to_bytes_le().as_slice() - ); - - r -} - -/// Helper function useful when picking a random scalar and when hashing a message into a scalar. -pub fn biguint_to_scalar(big_uint: &BigUint) -> Scalar { - // `blstrs`'s `Scalar::from_bytes_le` needs `SCALAR_NUM_BYTES` bytes. The current - // implementation of `BigUint::to_bytes_le()` does not always return `SCALAR_NUM_BYTES` bytes - // when the integer is smaller than 32 bytes. So we have to pad it. - let mut bytes = big_uint.to_bytes_le(); - - while bytes.len() < SCALAR_NUM_BYTES { - bytes.push(0u8); - } - - debug_assert_eq!(BigUint::from_bytes_le(&bytes.as_slice()), *big_uint); - - let slice = match <&[u8; SCALAR_NUM_BYTES]>::try_from(bytes.as_slice()) { - Ok(slice) => slice, - Err(_) => { - panic!( - "WARNING: Got {} bytes instead of {SCALAR_NUM_BYTES} (i.e., got {})", - bytes.as_slice().len(), - big_uint.to_string() - ); - }, - }; - - let opt = Scalar::from_bytes_le(slice); - - if opt.is_some().unwrap_u8() == 1u8 { - opt.unwrap() - } else { - panic!("Deserialization of randomly-generated num_bigint::BigUint failed."); - } -} diff --git a/crates/aptos-dkg/src/utils/mod.rs b/crates/aptos-dkg/src/utils/mod.rs index a62a993638a..8330431ed7b 100644 --- a/crates/aptos-dkg/src/utils/mod.rs +++ b/crates/aptos-dkg/src/utils/mod.rs @@ -4,31 +4,35 @@ use crate::utils::{ parallel_multi_pairing::parallel_multi_pairing_slice, random::random_scalar_from_uniform_bytes, }; -use blstrs::{ - pairing, Bls12, G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, Gt, Scalar, -}; +use ark_ec::{pairing::Pairing, AffineRepr}; +use ark_ff::PrimeField; +use blstrs::{pairing, G1Affine, G1Projective, G2Affine, G2Projective, Gt}; use group::{Curve, Group}; -use pairing::{MillerLoopResult, MultiMillerLoop}; +use num_traits::Zero; use rayon::ThreadPool; use sha3::Digest; use std::ops::Mul; -pub(crate) mod biguint; pub mod parallel_multi_pairing; pub mod random; -pub mod serialization; +pub mod test_utils; #[inline] pub fn is_power_of_two(n: usize) -> bool { n != 0 && (n & (n - 1) == 0) } +pub(crate) fn scalar_to_bits_le(x: &E::ScalarField) -> Vec { + let bigint: ::BigInt = x.into_bigint(); + ark_ff::BitIteratorLE::new(&bigint).collect() +} + /// Hashes the specified `msg` and domain separation tag `dst` into a `Scalar` by computing a 512-bit /// number as SHA3-512(SHA3-512(dst) || msg) and reducing it modulo the order of the field. /// (Same design as in `curve25519-dalek` explained here ) /// /// NOTE: Domain separation from other SHA3-512 calls in our system is left up to the caller. -pub fn hash_to_scalar(msg: &[u8], dst: &[u8]) -> Scalar { +pub fn hash_to_scalar(msg: &[u8], dst: &[u8]) -> blstrs::Scalar { // First, hash the DST as `dst_hash = H(dst)` let mut hasher = sha3::Sha3_512::new(); hasher.update(dst); @@ -51,7 +55,7 @@ pub fn hash_to_scalar(msg: &[u8], dst: &[u8]) -> Scalar { } /// Works around the `blst_hell` bug (see README.md). -pub fn g1_multi_exp(bases: &[G1Projective], scalars: &[Scalar]) -> G1Projective { +pub fn g1_multi_exp(bases: &[G1Projective], scalars: &[blstrs::Scalar]) -> G1Projective { if bases.len() != scalars.len() { panic!( "blstrs's multiexp has heisenbugs when the # of bases != # of scalars ({} != {})", @@ -68,7 +72,7 @@ pub fn g1_multi_exp(bases: &[G1Projective], scalars: &[Scalar]) -> G1Projective } /// Works around the `blst_hell` bug (see README.md). -pub fn g2_multi_exp(bases: &[G2Projective], scalars: &[Scalar]) -> G2Projective { +pub fn g2_multi_exp(bases: &[G2Projective], scalars: &[blstrs::Scalar]) -> G2Projective { if bases.len() != scalars.len() { panic!( "blstrs's multiexp has heisenbugs when the # of bases != # of scalars ({} != {})", @@ -83,24 +87,6 @@ pub fn g2_multi_exp(bases: &[G2Projective], scalars: &[Scalar]) -> G2Projective } } -pub fn multi_pairing<'a, I1, I2>(lhs: I1, rhs: I2) -> Gt -where - I1: Iterator, - I2: Iterator, -{ - let res = ::multi_miller_loop( - lhs.zip(rhs) - .map(|(g1, g2)| (g1.to_affine(), G2Prepared::from(g2.to_affine()))) - .collect::>() - .iter() - .map(|(g1, g2)| (g1, g2)) - .collect::>() - .as_slice(), - ); - - res.final_exponentiation() -} - pub fn parallel_multi_pairing<'a, I1, I2>( lhs: I1, rhs: I2, @@ -130,7 +116,7 @@ where I1: Iterator, I2: Iterator, { - multi_pairing(lhs, rhs) + aptos_crypto::blstrs::multi_pairing(lhs, rhs) } /// Useful for macro'd WVUF code (because blstrs was not written with generics in mind...). @@ -139,7 +125,7 @@ where I1: Iterator, I2: Iterator, { - multi_pairing(rhs, lhs) + aptos_crypto::blstrs::multi_pairing(rhs, lhs) } /// Useful for macro'd WVUF code (because blstrs was not written with generics in mind...). @@ -153,9 +139,12 @@ pub fn pairing_g2_g1(lhs: &G2Affine, rhs: &G1Affine) -> Gt { } pub trait HasMultiExp: for<'a> Sized + Clone { - fn multi_exp_slice(bases: &[Self], scalars: &[Scalar]) -> Self; + fn multi_exp_slice(bases: &[Self], scalars: &[blstrs::Scalar]) -> Self; - fn multi_exp_iter<'a, 'b, I>(bases: I, scalars: impl Iterator) -> Self + fn multi_exp_iter<'a, 'b, I>( + bases: I, + scalars: impl Iterator, + ) -> Self where I: Iterator, Self: 'a, @@ -163,19 +152,31 @@ pub trait HasMultiExp: for<'a> Sized + Clone { // TODO(Perf): blstrs does not work with iterators, which leads to unnecessary cloning here. Self::multi_exp_slice( bases.cloned().collect::>().as_slice(), - scalars.cloned().collect::>().as_slice(), + scalars.cloned().collect::>().as_slice(), ) } } impl HasMultiExp for G2Projective { - fn multi_exp_slice(points: &[Self], scalars: &[Scalar]) -> Self { + fn multi_exp_slice(points: &[Self], scalars: &[blstrs::Scalar]) -> Self { g2_multi_exp(points, scalars) } } impl HasMultiExp for G1Projective { - fn multi_exp_slice(points: &[Self], scalars: &[Scalar]) -> Self { + fn multi_exp_slice(points: &[Self], scalars: &[blstrs::Scalar]) -> Self { g1_multi_exp(points, scalars) } } + +pub(crate) fn msm_bool(bases: &[G], scalars: &[bool]) -> G::Group { + assert_eq!(bases.len(), scalars.len()); + + let mut acc = G::Group::zero(); + for (base, &bit) in bases.iter().zip(scalars) { + if bit { + acc += base; + } + } + acc +} diff --git a/crates/aptos-dkg/src/utils/random.rs b/crates/aptos-dkg/src/utils/random.rs index 15f0a7728e5..7ef8f9fb770 100644 --- a/crates/aptos-dkg/src/utils/random.rs +++ b/crates/aptos-dkg/src/utils/random.rs @@ -1,6 +1,9 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use aptos_crypto::blstrs::{ + biguint_to_scalar, G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_FIELD_ORDER, SCALAR_NUM_BYTES, +}; /// TODO(Security): This file is a workaround for the `rand_core_hell` issue, briefly described below. /// /// Ideally, we would write the following sane code: @@ -14,60 +17,43 @@ /// /// But we can't due to `aptos-crypto`'s dependency on an older version of `rand` and `rand_core` /// compared to `blstrs`'s dependency. -use crate::{G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_FIELD_ORDER, SCALAR_NUM_BYTES}; use blstrs::{G1Projective, G2Projective, Gt, Scalar}; use group::Group; -use num_bigint::{BigUint, RandBigInt}; +use num_bigint::BigUint; use num_integer::Integer; -use num_traits::Zero; use std::ops::Mul; /// Domain-separator for hash-based randomness generation that works around `rand_core_hell`. pub const DST_RAND_CORE_HELL: &[u8; 24] = b"APTOS_RAND_CORE_HELL_DST"; -/// Returns a random `blstrs::Scalar` given an older RNG as input. -/// -/// Pretty fast: 623 nanosecond / call. -pub fn random_scalar(rng: &mut R) -> Scalar +pub fn random_nonzero_scalar(rng: &mut R) -> Scalar where R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, { - random_scalar_internal(rng, false) + aptos_crypto::blstrs::random_scalar_internal(rng, true) } -pub fn random_nonzero_scalar(rng: &mut R) -> Scalar -where - R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, -{ - random_scalar_internal(rng, true) +pub fn random_scalar_from_uniform_bytes(bytes: &[u8; 2 * SCALAR_NUM_BYTES]) -> Scalar { + let bignum = BigUint::from_bytes_le(&bytes[..]); + let remainder = bignum.mod_floor(&SCALAR_FIELD_ORDER); + + biguint_to_scalar(&remainder) } -pub fn random_scalar_internal(rng: &mut R, exclude_zero: bool) -> Scalar +pub fn random_128bit_scalar(rng: &mut R) -> Scalar where R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, { - let mut big_uint; - - loop { - // NOTE(Alin): This uses rejection-sampling (e.g., https://cs.stackexchange.com/a/2578/54866) - // An alternative would be to sample twice the size of the scalar field and use - // `random_scalar_from_uniform_bytes`, but that is actually slower (950ns vs 623ns) - big_uint = rng.gen_biguint_below(&SCALAR_FIELD_ORDER); - - // Some key material cannot be zero since it needs to have an inverse in the scalar field. - if !exclude_zero || !big_uint.is_zero() { - break; - } - } + let mut low_bytes = [0u8; SCALAR_NUM_BYTES / 2]; + rng.fill(&mut low_bytes[..]); - crate::utils::biguint::biguint_to_scalar(&big_uint) -} + // Create a 32-byte array (little-endian) by extending the 128-bit number with zeros + let mut full_bytes = [0u8; SCALAR_NUM_BYTES]; -pub fn random_scalar_from_uniform_bytes(bytes: &[u8; 2 * SCALAR_NUM_BYTES]) -> Scalar { - let bignum = BigUint::from_bytes_le(&bytes[..]); - let remainder = bignum.mod_floor(&SCALAR_FIELD_ORDER); + // Copy the 128-bit random number to the lower half of the 32-byte array + full_bytes[..SCALAR_NUM_BYTES / 2].copy_from_slice(&low_bytes); - crate::utils::biguint::biguint_to_scalar(&remainder) + Scalar::from_bytes_le(&full_bytes).unwrap() } /// Returns a random `blstrs::G1Projective` given an older RNG as input. @@ -106,7 +92,7 @@ pub fn insecure_random_gt_point(rng: &mut R) -> Gt where R: rand_core::RngCore + rand::Rng + rand_core::CryptoRng + rand::CryptoRng, { - let s = random_scalar(rng); + let s = aptos_crypto::blstrs::random_scalar(rng); // TODO(TestingPerf): Cannot sample more efficiently than this because `fp12::Fp12` is not exposed. Gt::generator().mul(s) @@ -120,7 +106,7 @@ where let mut v = Vec::with_capacity(n); for _ in 0..n { - v.push(random_scalar(rng)); + v.push(aptos_crypto::blstrs::random_scalar(rng)); } debug_assert_eq!(v.len(), n); diff --git a/crates/aptos-dkg/src/utils/serialization.rs b/crates/aptos-dkg/src/utils/serialization.rs deleted file mode 100644 index 51085d8205a..00000000000 --- a/crates/aptos-dkg/src/utils/serialization.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES, SCALAR_NUM_BYTES}; -use aptos_crypto::CryptoMaterialError; -use blstrs::{G1Projective, G2Projective, Scalar}; - -/// Helper method to *securely* parse a sequence of bytes into a `G1Projective` point. -/// NOTE: This function will check for prime-order subgroup membership in $\mathbb{G}_1$. -pub fn g1_proj_from_bytes(bytes: &[u8]) -> Result { - let slice = match <&[u8; G1_PROJ_NUM_BYTES]>::try_from(bytes) { - Ok(slice) => slice, - Err(_) => return Err(CryptoMaterialError::WrongLengthError), - }; - - let a = G1Projective::from_compressed(slice); - - if a.is_some().unwrap_u8() == 1u8 { - Ok(a.unwrap()) - } else { - Err(CryptoMaterialError::DeserializationError) - } -} - -/// Helper method to *securely* parse a sequence of bytes into a `G2Projective` point. -/// NOTE: This function will check for prime-order subgroup membership in $\mathbb{G}_2$. -pub fn g2_proj_from_bytes(bytes: &[u8]) -> Result { - let slice = match <&[u8; G2_PROJ_NUM_BYTES]>::try_from(bytes) { - Ok(slice) => slice, - Err(_) => return Err(CryptoMaterialError::WrongLengthError), - }; - - let a = G2Projective::from_compressed(slice); - - if a.is_some().unwrap_u8() == 1u8 { - Ok(a.unwrap()) - } else { - Err(CryptoMaterialError::DeserializationError) - } -} - -/// Helper method to *securely* parse a sequence of bytes into a `Scalar`. -pub(crate) fn scalar_from_bytes_le(bytes: &[u8]) -> Result { - let slice = match <&[u8; SCALAR_NUM_BYTES]>::try_from(bytes) { - Ok(slice) => slice, - Err(_) => return Err(CryptoMaterialError::WrongLengthError), - }; - - let opt = Scalar::from_bytes_le(slice); - if opt.is_some().unwrap_u8() == 1u8 { - Ok(opt.unwrap()) - } else { - Err(CryptoMaterialError::DeserializationError) - } -} diff --git a/crates/aptos-dkg/src/utils/test_utils.rs b/crates/aptos-dkg/src/utils/test_utils.rs new file mode 100644 index 00000000000..fcd00e915d0 --- /dev/null +++ b/crates/aptos-dkg/src/utils/test_utils.rs @@ -0,0 +1,26 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::range_proofs::traits::BatchedRangeProof; +use ark_ec::pairing::Pairing; +use rand::{CryptoRng, RngCore}; + +/// Generate a **random instance** (values + commitment) given a fixed setup. +pub fn range_proof_random_instance, R: RngCore + CryptoRng>( + pk: &B::ProverKey, + n: usize, + ell: usize, + rng: &mut R, +) -> (Vec, B::Commitment, B::CommitmentRandomness) { + // TODO: One might want to assert something like n <= pk.max_n here, for which you'd have to e.g. add a trait HasMaxN to ProverKey + let ell_bit_values: Vec = (0..n) + .map(|_| { + let val = rng.next_u64() >> (64 - ell); + B::Input::from(val) + }) + .collect(); + + let (comm, r) = B::commit(&B::commitment_key_from_prover_key(pk), &ell_bit_values, rng); + + (ell_bit_values, comm, r) +} diff --git a/crates/aptos-dkg/src/weighted_vuf/bls/mod.rs b/crates/aptos-dkg/src/weighted_vuf/bls/mod.rs index 11235ceafad..5b872ccbd8e 100644 --- a/crates/aptos-dkg/src/weighted_vuf/bls/mod.rs +++ b/crates/aptos-dkg/src/weighted_vuf/bls/mod.rs @@ -4,11 +4,12 @@ use crate::{ algebra::{lagrange::lagrange_coefficients, polynomials::get_powers_of_tau}, pvss, - pvss::{Player, WeightedConfig}, - utils::{g1_multi_exp, multi_pairing, random::random_scalar, HasMultiExp}, + pvss::{Player, WeightedConfigBlstrs}, + utils::{g1_multi_exp, HasMultiExp}, weighted_vuf::traits::WeightedVUF, }; use anyhow::bail; +use aptos_crypto::blstrs::{multi_pairing, random_scalar}; use blstrs::{G1Projective, G2Projective, Gt, Scalar}; use ff::Field; use group::Group; @@ -105,7 +106,7 @@ impl WeightedVUF for BlsWUF { } fn aggregate_shares( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, apks_and_proofs: &[(Player, Self::AugmentedPubKeyShare, Self::ProofShare)], ) -> Self::Proof { // Collect all the evaluation points associated with each player @@ -141,7 +142,7 @@ impl WeightedVUF for BlsWUF { // NOTE: This VUF has the same evaluation as its proof. fn derive_eval( - _wc: &WeightedConfig, + _wc: &WeightedConfigBlstrs, _pp: &Self::PublicParameters, _msg: &[u8], _apks: &[Option], diff --git a/crates/aptos-dkg/src/weighted_vuf/pinkas/mod.rs b/crates/aptos-dkg/src/weighted_vuf/pinkas/mod.rs index 1526ee4bd58..2579ce48e69 100644 --- a/crates/aptos-dkg/src/weighted_vuf/pinkas/mod.rs +++ b/crates/aptos-dkg/src/weighted_vuf/pinkas/mod.rs @@ -6,15 +6,13 @@ use crate::{ pvss, pvss::{ dealt_pub_key_share::g2::DealtPubKeyShare, traits::HasEncryptionPublicParams, Player, - WeightedConfig, - }, - utils::{ - g1_multi_exp, g2_multi_exp, multi_pairing, parallel_multi_pairing, - random::{random_nonzero_scalar, random_scalar}, + WeightedConfigBlstrs, }, + utils::{g1_multi_exp, g2_multi_exp, parallel_multi_pairing, random::random_nonzero_scalar}, weighted_vuf::traits::WeightedVUF, }; use anyhow::{anyhow, bail}; +use aptos_crypto::blstrs::{multi_pairing, random_scalar}; use blstrs::{pairing, G1Projective, G2Projective, Gt, Scalar}; use ff::Field; use group::{Curve, Group}; @@ -172,7 +170,7 @@ impl WeightedVUF for PinkasWUF { } fn aggregate_shares( - _wc: &WeightedConfig, + _wc: &WeightedConfigBlstrs, apks_and_proofs: &[(Player, Self::AugmentedPubKeyShare, Self::ProofShare)], ) -> Self::Proof { let mut players_and_shares = Vec::with_capacity(apks_and_proofs.len()); @@ -192,7 +190,7 @@ impl WeightedVUF for PinkasWUF { // NOTE: This VUF has the same evaluation as its proof. fn derive_eval( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, _pp: &Self::PublicParameters, _msg: &[u8], apks: &[Option], @@ -273,7 +271,7 @@ impl PinkasWUF { } pub fn collect_lagrange_coeffs_shares_and_rks<'a>( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, apks: &'a [Option<(RandomizedPKs, Vec)>], proof: &'a Vec<(Player, ::ProofShare)>, ) -> anyhow::Result<( diff --git a/crates/aptos-dkg/src/weighted_vuf/traits.rs b/crates/aptos-dkg/src/weighted_vuf/traits.rs index a649ca6613a..79fb0643e7b 100644 --- a/crates/aptos-dkg/src/weighted_vuf/traits.rs +++ b/crates/aptos-dkg/src/weighted_vuf/traits.rs @@ -6,7 +6,7 @@ //! //! As a result, we only define weighted VUF traits here. -use crate::pvss::{Player, WeightedConfig}; +use crate::pvss::{Player, WeightedConfigBlstrs}; use rayon::ThreadPool; use serde::Serialize; use std::fmt::Debug; @@ -56,7 +56,7 @@ pub trait WeightedVUF { ) -> anyhow::Result<()>; fn aggregate_shares( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, apks_and_proofs: &[(Player, Self::AugmentedPubKeyShare, Self::ProofShare)], ) -> Self::Proof; @@ -64,7 +64,7 @@ pub trait WeightedVUF { fn eval(sk: &Self::SecretKey, msg: &[u8]) -> Self::Evaluation; fn derive_eval( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, pp: &Self::PublicParameters, msg: &[u8], apks: &[Option], diff --git a/crates/aptos-dkg/tests/accumulator.rs b/crates/aptos-dkg/tests/accumulator.rs index 0f3a7995e86..08420bd7587 100644 --- a/crates/aptos-dkg/tests/accumulator.rs +++ b/crates/aptos-dkg/tests/accumulator.rs @@ -1,6 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use aptos_crypto::blstrs::random_scalar; use aptos_dkg::{ algebra::{ evaluation_domain::BatchEvaluationDomain, @@ -8,7 +9,7 @@ use aptos_dkg::{ accumulator_poly, accumulator_poly_scheduled, accumulator_poly_slow, poly_eval, }, }, - utils::random::{random_scalar, random_scalars}, + utils::random::random_scalars, }; use blstrs::Scalar; use ff::Field; diff --git a/crates/aptos-dkg/tests/barycentric_eval.rs b/crates/aptos-dkg/tests/barycentric_eval.rs new file mode 100644 index 00000000000..7fff2d2dbd9 --- /dev/null +++ b/crates/aptos-dkg/tests/barycentric_eval.rs @@ -0,0 +1,89 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_dkg::algebra::polynomials::barycentric_eval; +use ark_ec::{pairing::Pairing, AdditiveGroup}; +use ark_ff::{FftField, Field, UniformRand}; +use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial, Polynomial}; +use ark_std::{rand::Rng, test_rng}; + +#[cfg(test)] +fn run_barycentric_case(degree: usize, n: usize, sample_points: usize) { + let mut rng = test_rng(); + type Fr = ::ScalarField; + + // Generate coefficients for a random polynomial; if degree is 0, randomly sometimes replace with the zero polynomial + let poly_coeffs: Vec> = if degree == 0 && rng.gen_bool(0.5) { + vec![Fr::::ZERO] + } else { + (0..=degree).map(|_| Fr::::rand(&mut rng)).collect() + }; + let poly = DensePolynomial::from_coefficients_vec(poly_coeffs); + + // Build the interpolation domain and evaluations + let omega = Fr::::get_root_of_unity(n as u64) + .unwrap_or_else(|| panic!("No root of unity of size {} for this field", n)); + let omegas: Vec> = (0..n).map(|i| omega.pow([i as u64])).collect(); + + // Evaluate the polynomial at each root of unity + let evals: Vec> = omegas.iter().map(|&r| poly.evaluate(&r)).collect(); + + // Precompute the multiplicative inverse of n for barycentric evaluation + let n_inv = Fr::::from(n as u64).inverse().unwrap(); + + // Test barycentric interpolation at random points + for _ in 0..sample_points { + let x = Fr::::rand(&mut rng); + let expected = poly.evaluate(&x); + let val = barycentric_eval(&evals, &omegas, x, n_inv); + assert_eq!( + val, expected, + "Failed for degree {}, n = {} at x = {:?}", + degree, n, x + ); + } + + // Test barycentric interpolation at the roots themselves, so check that the function returns the known values at the domain points + for (omega, &eval) in omegas.iter().zip(evals.iter()) { + let val = barycentric_eval(&evals, &omegas, *omega, n_inv); + assert_eq!( + val, eval, + "Interpolation mismatch at root {:?} for degree {}, domain size n = {}", + omega, degree, n + ); + } +} + +#[test] +fn test_barycentric_eval() { + use ark_bls12_381::Bls12_381; + use ark_bn254::Bn254; + let cases = [ + (0, 1), + (0, 2), + (1, 2), + (0, 4), + (1, 4), + (2, 4), + (3, 4), + (0, 8), + (1, 8), + (4, 8), + (7, 8), + (0, 16), + (1, 16), + (8, 16), + (15, 16), + (0, 32), + (1, 32), + (16, 32), + (31, 32), + ]; + + for &(degree, n) in &cases { + run_barycentric_case::(degree, n, 5); + } + for &(degree, n) in &cases { + run_barycentric_case::(degree, n, 5); + } +} diff --git a/crates/aptos-dkg/tests/crypto.rs b/crates/aptos-dkg/tests/crypto.rs index ebfe7bde396..9e04efa6f59 100644 --- a/crates/aptos-dkg/tests/crypto.rs +++ b/crates/aptos-dkg/tests/crypto.rs @@ -1,13 +1,14 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use aptos_crypto::blstrs::{multi_pairing, random_scalar}; use aptos_dkg::{ algebra::polynomials::{ poly_eval, poly_mul_fft, poly_mul_less_slow, poly_mul_slow, poly_xnmul, }, utils::{ - multi_pairing, parallel_multi_pairing, - random::{random_g1_point, random_g2_point, random_scalar, random_scalars}, + parallel_multi_pairing, + random::{random_g1_point, random_g2_point, random_scalars}, }, weighted_vuf::pinkas::MIN_MULTIPAIR_NUM_JOBS, }; diff --git a/crates/aptos-dkg/tests/dkg.rs b/crates/aptos-dkg/tests/dkg.rs index 9633b3d9131..3e375092ff5 100644 --- a/crates/aptos-dkg/tests/dkg.rs +++ b/crates/aptos-dkg/tests/dkg.rs @@ -1,17 +1,13 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_crypto::hash::CryptoHash; -use aptos_dkg::{ - pvss::{ - das, - das::unweighted_protocol, - insecure_field, test_utils, - test_utils::{reconstruct_dealt_secret_key_randomly, NoAux}, - traits::{SecretSharingConfig, Transcript}, - weighted::generic_weighting::GenericWeighting, - }, - utils::random::random_scalar, +use aptos_crypto::{blstrs::random_scalar, hash::CryptoHash, traits::SecretSharingConfig as _}; +use aptos_dkg::pvss::{ + das::{self, unweighted_protocol}, + insecure_field, + test_utils::{self, reconstruct_dealt_secret_key_randomly, NoAux}, + traits::transcript::AggregatableTranscript, + weighted::generic_weighting::GenericWeighting, }; use rand::{rngs::StdRng, thread_rng}; use rand_core::SeedableRng; @@ -42,7 +38,10 @@ fn test_dkg_all_weighted() { /// Deals `n` times, aggregates all transcripts, and attempts to reconstruct the secret dealt in this /// aggregated transcript. -fn aggregatable_dkg(sc: &T::SecretSharingConfig, seed_bytes: [u8; 32]) { +fn aggregatable_dkg( + sc: &T::SecretSharingConfig, + seed_bytes: [u8; 32], +) { let mut rng = StdRng::from_seed(seed_bytes); let d = test_utils::setup_dealing::(sc, &mut rng); @@ -55,6 +54,7 @@ fn aggregatable_dkg(sc: &T::SecretSharingConfig, see sc, &d.pp, &d.ssks[i], + &d.spks[i], &d.eks, &d.iss[i], &NoAux, @@ -78,7 +78,8 @@ fn aggregatable_dkg(sc: &T::SecretSharingConfig, see ) .expect("aggregated PVSS transcript failed verification"); - if d.dsk != reconstruct_dealt_secret_key_randomly::(sc, &mut rng, &d.dks, trx) { + if d.dsk != reconstruct_dealt_secret_key_randomly::(sc, &mut rng, &d.dks, trx, &d.pp) + { panic!("Reconstructed SK did not match"); } } diff --git a/crates/aptos-dkg/tests/pvss.rs b/crates/aptos-dkg/tests/pvss.rs index 88ebc247eea..8382c5995f1 100644 --- a/crates/aptos-dkg/tests/pvss.rs +++ b/crates/aptos-dkg/tests/pvss.rs @@ -6,25 +6,26 @@ #![allow(clippy::let_and_return)] //! PVSS scheme-independent testing -use aptos_crypto::hash::CryptoHash; -use aptos_dkg::{ - constants::{G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES}, - pvss::{ - das, - das::unweighted_protocol, - insecure_field, test_utils, - test_utils::{ - get_threshold_configs_for_benchmarking, get_weighted_configs_for_benchmarking, - reconstruct_dealt_secret_key_randomly, NoAux, - }, - traits::{transcript::Transcript, SecretSharingConfig}, - GenericWeighting, ThresholdConfig, +use aptos_crypto::{ + blstrs::{random_scalar, G1_PROJ_NUM_BYTES, G2_PROJ_NUM_BYTES}, + traits::SecretSharingConfig as _, +}; +use aptos_dkg::pvss::{ + chunky, das, + das::unweighted_protocol, + insecure_field, test_utils, + test_utils::{ + get_threshold_configs_for_benchmarking, get_weighted_configs_for_benchmarking, + reconstruct_dealt_secret_key_randomly, NoAux, }, - utils::random::random_scalar, + traits::transcript::{Transcript, WithMaxNumShares}, + GenericWeighting, ThresholdConfigBlstrs, }; use rand::{rngs::StdRng, thread_rng}; use rand_core::SeedableRng; +// TODO: Add a test for public parameters serialization roundtrip? + #[test] fn test_pvss_all_unweighted() { let mut rng = thread_rng(); @@ -44,6 +45,21 @@ fn test_pvss_all_unweighted() { // Insecure testing-only field-element PVSS pvss_deal_verify_and_reconstruct::(&tc, seed.to_bytes_le()); } + + // Restarting the loop here because now it'll grab **arkworks** `ThresholdConfig`s over BN254 instead + let tcs = test_utils::get_threshold_configs_for_testing_smaller(); + for tc in tcs.iter().take(20) { + // Reduce the number of tcs to make it a bit faster? + println!("\nTesting {tc} PVSS"); + + let seed = random_scalar(&mut rng); + + // Chunky + pvss_deal_verify_and_reconstruct::>( + &tc, + seed.to_bytes_le(), + ); + } } #[test] @@ -89,6 +105,34 @@ fn test_pvss_transcript_size() { print_transcript_size::("Actual", &sc, actual_size); } + // Restarting the loop here because now it'll grab **arkworks** `ThresholdConfig`s with BN254 + // uses default chunk sizes, so probably want to modify this at some point to allow a wider range + // Ideally should iterate over a vec of (t, n), not the actual threshold configs... but won't be a bottleneck + for sc in get_threshold_configs_for_benchmarking().iter().take(1) { + // Only trying 1 for now to keep tests fast (also the second one has the same n, which means it would yield the same size...) + println!(); + let actual_size = actual_transcript_size::>(&sc); + print_transcript_size::>( + "Actual for BN254", + &sc, + actual_size, + ); + } + + // Restarting so it grabs BLS12-381 instead of BN254... TODO: could get rid of this with some work + for sc in get_threshold_configs_for_benchmarking().iter().take(1) { + // Only trying 1 for now to keep tests fast (also the second one has the same n, which means it would yield the same size...) + + println!(); + let actual_size = + actual_transcript_size::>(&sc); + print_transcript_size::>( + "Actual for BLS12_381", + &sc, + actual_size, + ); + } + for wc in get_weighted_configs_for_benchmarking() { let actual_size = actual_transcript_size::(wc.get_threshold_config()); print_transcript_size::("Actual", wc.get_threshold_config(), actual_size); @@ -98,6 +142,7 @@ fn test_pvss_transcript_size() { } } +#[cfg(test)] fn print_transcript_size(size_type: &str, sc: &T::SecretSharingConfig, size: usize) { let name = T::scheme_name(); println!("{size_type:8} transcript size for {sc} {name}: {size} bytes"); @@ -111,7 +156,8 @@ fn print_transcript_size(size_type: &str, sc: &T::SecretSharingCo /// 1. Deals a secret, creating a transcript /// 2. Verifies the transcript. /// 3. Ensures the a sufficiently-large random subset of the players can recover the dealt secret -fn pvss_deal_verify_and_reconstruct( +#[cfg(test)] +fn pvss_deal_verify_and_reconstruct( sc: &T::SecretSharingConfig, seed_bytes: [u8; 32], ) { @@ -126,6 +172,7 @@ fn pvss_deal_verify_and_reconstruct( &sc, &d.pp, &d.ssks[0], + &d.spks[0], &d.eks, &d.s, &NoAux, @@ -140,22 +187,29 @@ fn pvss_deal_verify_and_reconstruct( .expect("serialized transcript should deserialize correctly"); assert_eq!(trx, trx_deserialized); - if d.dsk != reconstruct_dealt_secret_key_randomly::(sc, &mut rng, &d.dks, trx) { + if d.dsk != reconstruct_dealt_secret_key_randomly::(sc, &mut rng, &d.dks, trx, &d.pp) + { panic!("Reconstructed SK did not match"); } } +#[cfg(test)] fn actual_transcript_size(sc: &T::SecretSharingConfig) -> usize { let mut rng = thread_rng(); - let trx = T::generate(&sc, &mut rng); + let trx = T::generate( + &sc, + &T::PublicParameters::with_max_num_shares_for_generate(sc.get_total_num_shares()), + &mut rng, + ); let actual_size = trx.to_bytes().len(); actual_size } -fn expected_transcript_size>( - sc: &ThresholdConfig, +#[cfg(test)] +fn expected_transcript_size>( + sc: &ThresholdConfigBlstrs, ) -> usize { if T::scheme_name() == unweighted_protocol::DAS_SK_IN_G1 { G2_PROJ_NUM_BYTES diff --git a/crates/aptos-dkg/tests/range_proof.rs b/crates/aptos-dkg/tests/range_proof.rs new file mode 100644 index 00000000000..6dc6291bfb6 --- /dev/null +++ b/crates/aptos-dkg/tests/range_proof.rs @@ -0,0 +1,180 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::GroupGenerators; +use aptos_dkg::{ + range_proofs::{ + dekart_univariate::Proof as UnivariateDeKART, + dekart_univariate_v2::Proof as UnivariateDeKARTv2, traits::BatchedRangeProof, + }, + utils::test_utils, +}; +use ark_bls12_381::Bls12_381; +use ark_bn254::Bn254; +use ark_ec::pairing::Pairing; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use rand::thread_rng; +use std::fmt::Debug; + +#[cfg(test)] +fn assert_range_proof_correctness>( + setup: &RangeProofUniversalSetup, + n: usize, + ell: usize, +) { + let mut rng = thread_rng(); + let RangeProofUniversalSetup { pk, vk } = setup; + let (values, comm, r) = + test_utils::range_proof_random_instance::<_, B, _>(pk, n, ell, &mut rng); + println!("setup finished, prove starting for n={}, ell={}", n, ell); + + let proof = B::prove(pk, &values, ell, &comm, &r, &mut rng); + proof.verify(vk, n, ell, &comm).unwrap(); + + // === Serialize to memory === + let encoded = { + let mut v = Vec::new(); + proof + .serialize_compressed(&mut v) + .expect("proof serialization should succeed"); + v + }; + println!( + "Serialized proof size (n={}, ell={}): {} bytes (expected for blstrs: {} bytes)", + n, + ell, + encoded.len(), + 2 * 8 + 48 + (48 + 96) * ell // Can get rid of the 2 * 8 here by turning the Vecs in `proof` into tuples + ); + + // === Round-trip deserialization === + let decoded = B::deserialize_compressed(&*encoded).expect("Deserialization failed"); + + // Verify still succeeds + decoded.verify(vk, n, ell, &comm).unwrap(); + + println!( + "Serialization round-trip test passed for n={}, ell={}", + n, ell + ); + + // Make invalid + let mut invalid_proof = decoded.clone(); + invalid_proof.maul(); + assert!(invalid_proof.verify(vk, n, ell, &comm).is_err()); +} + +#[cfg(test)] +fn assert_keys_serialization>( + setup: &RangeProofUniversalSetup, +) where + B::ProverKey: CanonicalSerialize + CanonicalDeserialize + Eq + Debug, + B::VerificationKey: CanonicalDeserialize + Eq + Debug, +{ + let RangeProofUniversalSetup { pk, vk } = setup; + + // === Prover key serialization/deserialization === + let pk_encoded = { + let mut v = Vec::new(); + pk.serialize_compressed(&mut v) + .expect("Prover key serialization should succeed"); + v + }; + println!("Serialized pk size: {} bytes", pk_encoded.len()); + + let pk_decoded = B::ProverKey::deserialize_compressed(&*pk_encoded) + .expect("Prover key deserialization should succeed"); + assert_eq!(pk, &pk_decoded, "Round-trip pk failed"); + + // === Verifier key serialization/deserialization === + let vk_encoded = { + let mut v = Vec::new(); + vk.serialize_compressed(&mut v) + .expect("Verifier key serialization should succeed"); + v + }; + println!("Serialized vk size: {} bytes", vk_encoded.len()); + + let vk_decoded = B::VerificationKey::deserialize_compressed(&*vk_encoded) + .expect("Verifier key deserialization should succeed"); + assert_eq!(vk, &vk_decoded, "Round-trip vk failed"); + + println!("Prover and Verifier key serialization round-trip passed."); +} + +#[cfg(test)] +const TEST_CASES: &[(usize, usize)] = &[ + // (n, \ell) + (3, 16), + (7, 16), + (4, 16), + (8, 16), + (16, 3), + (16, 4), + (16, 7), + (16, 8), + (16, 16), +]; + +#[cfg(test)] +/// A **reusable** setup structure. +struct RangeProofUniversalSetup> { + pk: B::ProverKey, + vk: B::VerificationKey, +} + +#[cfg(test)] +/// Generate a fixed setup for a single curve +fn make_single_curve_setup(n: usize, ell: usize) -> RangeProofUniversalSetup +where + E: Pairing, + B: BatchedRangeProof, +{ + let mut rng = thread_rng(); + let group_generators = GroupGenerators::default(); + let (pk, vk) = B::setup(n, ell, group_generators, &mut rng); + RangeProofUniversalSetup { pk, vk } +} + +#[cfg(test)] +fn assert_correctness_for_range_proof_and_curve() +where + E: Pairing, + B: BatchedRangeProof, +{ + let setups = make_single_curve_setup::(31, 16); + for &(n, ell) in TEST_CASES { + assert_range_proof_correctness::(&setups, n, ell); + } +} + +#[cfg(test)] +fn assert_correctness_and_serialization_for_range_proof_and_curve() +where + E: Pairing, + B: BatchedRangeProof, + B::ProverKey: CanonicalSerialize + CanonicalDeserialize + Eq + Debug, + B::VerificationKey: CanonicalDeserialize + Eq + Debug, +{ + let setups = make_single_curve_setup::(31, 16); + for &(n, ell) in TEST_CASES { + assert_range_proof_correctness::(&setups, n, ell); + assert_keys_serialization::(&setups); + } +} + +#[cfg(test)] +#[test] +fn assert_correctness_of_all_range_proofs() { + assert_correctness_for_range_proof_and_curve::>(); + assert_correctness_for_range_proof_and_curve::>(); + + assert_correctness_and_serialization_for_range_proof_and_curve::< + Bn254, + UnivariateDeKARTv2, + >(); + assert_correctness_and_serialization_for_range_proof_and_curve::< + Bls12_381, + UnivariateDeKARTv2, + >(); +} diff --git a/crates/aptos-dkg/tests/secret_sharing_config.rs b/crates/aptos-dkg/tests/secret_sharing_config.rs index be731cbefad..f54419c07bb 100644 --- a/crates/aptos-dkg/tests/secret_sharing_config.rs +++ b/crates/aptos-dkg/tests/secret_sharing_config.rs @@ -4,9 +4,8 @@ #![allow(clippy::ptr_arg)] #![allow(clippy::needless_borrow)] -use aptos_dkg::pvss::{ - test_utils::get_weighted_configs_for_benchmarking, traits::SecretSharingConfig, -}; +use aptos_crypto::traits::SecretSharingConfig as _; +use aptos_dkg::pvss::test_utils::get_weighted_configs_for_benchmarking; use rand::thread_rng; #[ignore] diff --git a/crates/aptos-dkg/tests/sigma_protocol.rs b/crates/aptos-dkg/tests/sigma_protocol.rs new file mode 100644 index 00000000000..9d118a3d3d6 --- /dev/null +++ b/crates/aptos-dkg/tests/sigma_protocol.rs @@ -0,0 +1,143 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::arkworks::random::sample_field_element; +use aptos_dkg::{ + sigma_protocol::{ + self, homomorphism, + homomorphism::{fixed_base_msms, fixed_base_msms::Trait, tuple::TupleHomomorphism}, + }, + Scalar, +}; +use ark_bls12_381::Bls12_381; +use ark_bn254::Bn254; +use ark_ec::{pairing::Pairing, CurveGroup, PrimeGroup}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use rand::thread_rng; +use std::fmt::Debug; + +#[cfg(test)] +pub fn test_sigma_protocol(hom: H, witness: H::Domain) +where + E: Pairing, + H: sigma_protocol::Trait, +{ + let mut rng = thread_rng(); + + let statement = hom.apply(&witness); + let ctxt = b"SIGMA-PROTOCOL-CONTEXT"; + + let proof = hom.prove(&witness, &statement, ctxt, &mut rng); + + hom.verify(&statement, &proof, ctxt) + .expect("Sigma protocol proof failed verification"); +} + +mod schnorr { + use super::*; + use ark_ec::VariableBaseMSM; + use sigma_protocol::homomorphism::TrivialShape as CodomainShape; + + #[allow(non_snake_case)] + #[derive(CanonicalSerialize, Clone, Debug)] + pub(crate) struct Schnorr { + pub G: E::G1Affine, + } + + // E::G1Affine doesn't seem to implement Default, otherwise it would've been derived for Schnorr + impl Default for Schnorr { + fn default() -> Self { + Self { + G: E::G1::generator().into_affine(), + } + } + } + + impl homomorphism::Trait for Schnorr { + type Codomain = CodomainShape; + type Domain = Scalar; + + fn apply(&self, input: &Self::Domain) -> Self::Codomain { + self.apply_msm(self.msm_terms(input)) + } + } + + impl fixed_base_msms::Trait for Schnorr { + type Base = E::G1Affine; + type CodomainShape + = CodomainShape + where + T: CanonicalSerialize + CanonicalDeserialize + Clone + Debug + Eq; + type MsmInput = fixed_base_msms::MsmInput; + type MsmOutput = E::G1; + type Scalar = E::ScalarField; + + fn msm_terms(&self, input: &Self::Domain) -> Self::CodomainShape { + CodomainShape(fixed_base_msms::MsmInput { + bases: vec![self.G], + scalars: vec![input.0], + }) + } + + fn msm_eval(bases: &[Self::Base], scalars: &[Self::Scalar]) -> Self::MsmOutput { + E::G1::msm(bases, scalars).expect("MSM failed in Schnorr") + } + } + + impl sigma_protocol::Trait for Schnorr { + fn dst(&self) -> Vec { + b"SCHNORR_SIGMA_PROTOCOL_DST".to_vec() + } + } +} + +mod chaum_pedersen { + use super::{schnorr::*, *}; + + pub type ChaumPedersen = TupleHomomorphism, Schnorr>; + + // Implementing e.g. Default here would require a wrapper, but then sigma_protocol::Trait would have to get re-implemented... + #[allow(non_snake_case)] + pub fn make_chaum_pedersen_instance() -> ChaumPedersen { + let G_1 = E::G1::generator().into_affine(); + let G_2 = (G_1 * E::ScalarField::from(123456789u64)).into_affine(); + + let schnorr1 = Schnorr { G: G_1 }; + let schnorr2 = Schnorr { G: G_2 }; + + TupleHomomorphism { + hom1: schnorr1, + hom2: schnorr2, + } + } +} + +#[test] +fn test_schnorr() { + use schnorr::*; + + let mut rng = thread_rng(); + + // ---- Bn254 ---- + let witness_bn = Scalar(sample_field_element(&mut rng)); + test_sigma_protocol::(Schnorr::default(), witness_bn); + + // ---- Bls12_381 ---- + let witness_bls = Scalar(sample_field_element(&mut rng)); + test_sigma_protocol::(Schnorr::default(), witness_bls); +} + +#[test] +fn test_chaum_pedersen() { + use chaum_pedersen::*; + + let mut rng = thread_rng(); + + // ---- Bn254 ---- + let witness_bn = Scalar(sample_field_element(&mut rng)); + test_sigma_protocol::(make_chaum_pedersen_instance(), witness_bn); + + // ---- Bls12_381 ---- + let witness_bls = Scalar(sample_field_element(&mut rng)); + test_sigma_protocol::(make_chaum_pedersen_instance(), witness_bls); +} diff --git a/crates/aptos-dkg/tests/weighted_vuf.rs b/crates/aptos-dkg/tests/weighted_vuf.rs index a4c04955e54..b5999ae8d78 100644 --- a/crates/aptos-dkg/tests/weighted_vuf.rs +++ b/crates/aptos-dkg/tests/weighted_vuf.rs @@ -4,15 +4,15 @@ #![allow(clippy::ptr_arg)] #![allow(clippy::needless_borrow)] +use aptos_crypto::{blstrs::random_scalar, traits::SecretSharingConfig as _}; use aptos_dkg::{ pvss, pvss::{ test_utils, test_utils::{DealingArgs, NoAux}, - traits::{SecretSharingConfig, Transcript}, - Player, WeightedConfig, + traits::Transcript, + Player, WeightedConfigBlstrs, }, - utils::random::random_scalar, weighted_vuf::{pinkas::PinkasWUF, traits::WeightedVUF}, }; use aptos_runtimes::spawn_rayon_thread_pool; @@ -53,7 +53,7 @@ fn test_wvuf_verify_proof_accepts_full_participation() { Vec<::SecretKeyShare>, Vec<::PubKeyShare>, ) = (0..wc.get_total_num_players()) - .map(|p| trx.decrypt_own_share(&wc, &wc.get_player(p), &d.dks[p])) + .map(|p| trx.decrypt_own_share(&wc, &wc.get_player(p), &d.dks[p], &d.pp)) .collect::>() .into_iter() .unzip(); @@ -106,7 +106,7 @@ fn test_wvuf_verify_proof_accepts_full_participation() { } fn weighted_wvuf_bvt< - T: Transcript, + T: Transcript, WVUF: WeightedVUF< SecretKey = T::DealtSecretKey, PubKey = T::DealtPubKey, @@ -132,10 +132,10 @@ where ); } -fn weighted_pvss>( +fn weighted_pvss>( rng: &mut StdRng, -) -> (WeightedConfig, DealingArgs, T) { - let wc = WeightedConfig::new(10, vec![3, 5, 3, 4, 2, 1, 1, 7]).unwrap(); +) -> (WeightedConfigBlstrs, DealingArgs, T) { + let wc = WeightedConfigBlstrs::new(10, vec![3, 5, 3, 4, 2, 1, 1, 7]).unwrap(); let d = test_utils::setup_dealing::(&wc, rng); @@ -143,6 +143,7 @@ fn weighted_pvss>( &wc, &d.pp, &d.ssks[0], + &d.spks[0], &d.eks, &d.s, &NoAux, @@ -163,7 +164,7 @@ fn weighted_pvss>( /// /// `T` is a (non-weighted) `pvss::traits::Transcript` type. fn wvuf_randomly_aggregate_verify_and_derive_eval< - T: Transcript, + T: Transcript, WVUF: WeightedVUF< SecretKey = T::DealtSecretKey, PubKey = T::DealtPubKey, @@ -172,7 +173,7 @@ fn wvuf_randomly_aggregate_verify_and_derive_eval< >, R: rand_core::RngCore + rand_core::CryptoRng, >( - wc: &WeightedConfig, + wc: &WeightedConfigBlstrs, sk: &T::DealtSecretKey, pk: &T::DealtPubKey, dks: &Vec, @@ -191,7 +192,7 @@ fn wvuf_randomly_aggregate_verify_and_derive_eval< let (mut sks, pks): (Vec, Vec) = (0..wc .get_total_num_players()) .map(|p| { - let (sk, pk) = trx.decrypt_own_share(&wc, &wc.get_player(p), &dks[p]); + let (sk, pk) = trx.decrypt_own_share(&wc, &wc.get_player(p), &dks[p], pvss_pp); (sk, pk) }) .collect::>() diff --git a/crates/aptos-drop-helper/src/async_concurrent_dropper.rs b/crates/aptos-drop-helper/src/async_concurrent_dropper.rs index 15231062e52..ebf6910b961 100644 --- a/crates/aptos-drop-helper/src/async_concurrent_dropper.rs +++ b/crates/aptos-drop-helper/src/async_concurrent_dropper.rs @@ -6,7 +6,7 @@ use crate::{ IN_ANY_DROP_POOL, }; use aptos_infallible::Mutex; -use aptos_metrics_core::{IntGaugeHelper, TimerHelper}; +use aptos_metrics_core::{IntGaugeVecHelper, TimerHelper}; use std::sync::{ mpsc::{channel, Receiver, Sender}, Arc, Condvar, diff --git a/crates/aptos-enum-conversion-derive/tests/conversion_tests.rs b/crates/aptos-enum-conversion-derive/tests/conversion_tests.rs index 00dcdd1444c..f830d9d1b0f 100644 --- a/crates/aptos-enum-conversion-derive/tests/conversion_tests.rs +++ b/crates/aptos-enum-conversion-derive/tests/conversion_tests.rs @@ -5,12 +5,19 @@ use aptos_enum_conversion_derive::EnumConversion; #[test] fn test_enum_conversion_derive_valid() { - struct TestMessage {} + #[derive(Debug, Eq, PartialEq)] + struct TestMessage { + x: u32, + } - #[derive(EnumConversion)] + #[derive(Debug, Eq, PartialEq, EnumConversion)] enum Messages { Test(TestMessage), } + + let message = TestMessage { x: 123 }; + let messages = Messages::from(message); + assert_eq!(messages, Messages::Test(TestMessage { x: 123 })); } #[test] diff --git a/crates/aptos-faucet/cli/src/main.rs b/crates/aptos-faucet/cli/src/main.rs index 981938464c2..8a9c68dbee4 100644 --- a/crates/aptos-faucet/cli/src/main.rs +++ b/crates/aptos-faucet/cli/src/main.rs @@ -3,7 +3,8 @@ use anyhow::{Context, Result}; use aptos_faucet_core::funder::{ - ApiConnectionConfig, FunderTrait, MintFunder, TransactionSubmissionConfig, + ApiConnectionConfig, AssetConfig, FunderTrait, MintAssetConfig, MintFunder, + TransactionSubmissionConfig, DEFAULT_ASSET_NAME, }; use aptos_sdk::{ crypto::ed25519::Ed25519PublicKey, @@ -13,7 +14,12 @@ use aptos_sdk::{ }, }; use clap::Parser; -use std::{collections::HashSet, str::FromStr}; +use std::{ + collections::{HashMap, HashSet}, + path::PathBuf, + str::FromStr, +}; +use tokio::sync::RwLock; #[tokio::main] async fn main() -> Result<()> { @@ -45,6 +51,12 @@ pub struct FaucetCliArgs { #[clap(long)] pub mint_account_address: Option, + /// Path to the private key file for minting coins. + /// To manually generate a keypair, use generate-key: + /// `cargo run -p generate-keypair -- -o ` + #[clap(long, default_value = "/opt/aptos/etc/mint.key")] + pub key_file_path: PathBuf, + /// The maximum amount of gas in OCTA to spend on a single transaction. #[clap(long, default_value_t = 500_000)] pub max_gas_amount: u64, @@ -52,11 +64,11 @@ pub struct FaucetCliArgs { impl FaucetCliArgs { async fn run(&self) -> Result<()> { - // Get network root key based on the connection config. - let key = self - .api_connection_args - .get_key() - .context("Failed to build root key")?; + // Create an AssetConfig to get the key + let asset_config = AssetConfig::new(None, self.key_file_path.clone()); + + // Get network root key from the asset config. + let key = asset_config.get_key().context("Failed to build root key")?; // Build the account that the MintFunder will use. let faucet_account = LocalAccount::new( @@ -79,22 +91,45 @@ impl FaucetCliArgs { true, // wait_for_transactions ); + // Create asset configuration for the default asset + let base_asset_config = AssetConfig::new(None, self.key_file_path.clone()); + let mint_asset_config = MintAssetConfig::new( + base_asset_config, + self.mint_account_address, + false, // do_not_delegate is set to false - CLI uses delegation + ); + + // Build assets map with the default asset + let mut assets = HashMap::new(); + assets.insert( + DEFAULT_ASSET_NAME.to_string(), + (mint_asset_config, RwLock::new(faucet_account)), + ); + // Build the MintFunder service. - let mut mint_funder = MintFunder::new( + let mint_funder = MintFunder::new( self.api_connection_args.node_url.clone(), self.api_connection_args.api_key.clone(), self.api_connection_args.additional_headers.clone(), self.api_connection_args.chain_id, transaction_submission_config, - faucet_account, + assets, + DEFAULT_ASSET_NAME.to_string(), + self.amount, ); // Create an account that we'll delegate mint functionality to, then use it. - mint_funder - .use_delegated_account() + let delegated_account = mint_funder + .use_delegated_account(DEFAULT_ASSET_NAME) .await .context("Failed to make MintFunder use delegated account")?; + // Update the assets map with the delegated account that has mint capabilities + mint_funder + .update_asset_account(DEFAULT_ASSET_NAME, delegated_account) + .await + .context("Failed to update asset account with delegated account")?; + let accounts: HashSet = self .accounts .trim() @@ -105,7 +140,7 @@ impl FaucetCliArgs { // Mint coins to each of the accounts. for account in accounts { let response = mint_funder - .fund(Some(self.amount), account, false, false) + .fund(Some(self.amount), account, None, false, false) .await; match response { Ok(response) => println!( diff --git a/crates/aptos-faucet/configs/testing_mint_funder_local.yaml b/crates/aptos-faucet/configs/testing_mint_funder_local.yaml index 1a859941d40..4d1ee3e3a35 100644 --- a/crates/aptos-faucet/configs/testing_mint_funder_local.yaml +++ b/crates/aptos-faucet/configs/testing_mint_funder_local.yaml @@ -9,9 +9,11 @@ funder_config: type: "MintFunder" node_url: "http://127.0.0.1:8080" chain_id: 4 - key_file_path: "/tmp/mint.key" - do_not_delegate: false - mint_account_address: "0xA550C18" + assets: + apt: + do_not_delegate: false + key_file_path: "/tmp/mint.key" + mint_account_address: "0xA550C18" handler_config: use_helpful_errors: true return_rejections_early: false diff --git a/crates/aptos-faucet/configs/testing_mint_funder_local_wait_for_txns.yaml b/crates/aptos-faucet/configs/testing_mint_funder_local_wait_for_txns.yaml index e1fa1968928..a0ae28b4c66 100644 --- a/crates/aptos-faucet/configs/testing_mint_funder_local_wait_for_txns.yaml +++ b/crates/aptos-faucet/configs/testing_mint_funder_local_wait_for_txns.yaml @@ -11,12 +11,14 @@ funder_config: type: "MintFunder" node_url: "http://127.0.0.1:8080" chain_id: 4 - key_file_path: "/tmp/mint.key" - do_not_delegate: false - mint_account_address: "0xA550C18" wait_for_transactions: true maximum_amount: 100 maximum_amount_with_bypass: 10000 + assets: + apt: + do_not_delegate: false + key_file_path: "/tmp/mint.key" + mint_account_address: "0xA550C18" handler_config: use_helpful_errors: true return_rejections_early: false diff --git a/crates/aptos-faucet/configs/testing_mint_funder_multi_assets.yaml b/crates/aptos-faucet/configs/testing_mint_funder_multi_assets.yaml new file mode 100644 index 00000000000..11e5c71b744 --- /dev/null +++ b/crates/aptos-faucet/configs/testing_mint_funder_multi_assets.yaml @@ -0,0 +1,29 @@ +server_config: + api_path_base: "" +metrics_server_config: + listen_port: 9105 +bypasser_configs: [] +checker_configs: [] +funder_config: + type: "MintFunder" + node_url: "http://127.0.0.1:8080" + chain_id: 4 + assets: + apt: + do_not_delegate: false + key_file_path: ".aptos/testnet/mint.key" + mint_account_address: "0xA550C18" + # Uses default "script" transaction method with MINTER_SCRIPT + shelbyusd: + do_not_delegate: true + key_file_path: "./shelbyusd.key" + mint_account_address: "7619a5c079936ada2b357a276d7a3feb5ce67c8cbe9969db2a4510738a93657e" + transaction_method: + type: "entry_function" + module_address: "0xe7e04d43ed9badf01ade482175f22d75b7c9f2c31a820d5623b6281fe694783d" + module_name: "shelby_usd" + function_name: "mint" + +handler_config: + use_helpful_errors: true + return_rejections_early: false \ No newline at end of file diff --git a/crates/aptos-faucet/configs/testing_redis_minter_local.yaml b/crates/aptos-faucet/configs/testing_redis_minter_local.yaml index 612085f68ae..8eb6613b284 100644 --- a/crates/aptos-faucet/configs/testing_redis_minter_local.yaml +++ b/crates/aptos-faucet/configs/testing_redis_minter_local.yaml @@ -15,9 +15,11 @@ funder_config: type: "MintFunder" node_url: "http://127.0.0.1:8080" chain_id: 4 - key_file_path: ".aptos/testnet/mint.key" - do_not_delegate: false - mint_account_address: "0xA550C18" + assets: + apt: + key_file_path: ".aptos/testnet/mint.key" + do_not_delegate: false + mint_account_address: "0xA550C18" handler_config: use_helpful_errors: true return_rejections_early: false diff --git a/crates/aptos-faucet/configs/testing_transfer_funder.yaml b/crates/aptos-faucet/configs/testing_transfer_funder.yaml index 62a12f91c59..f3ab04fa836 100644 --- a/crates/aptos-faucet/configs/testing_transfer_funder.yaml +++ b/crates/aptos-faucet/configs/testing_transfer_funder.yaml @@ -9,10 +9,12 @@ funder_config: type: "TransferFunder" node_url: "https://fullnode.devnet.aptoslabs.com" chain_id: 36 - key_file_path: "/tmp/transfer_funder_devnet.key" minimum_funds: 10000000 amount_to_fund: 2000 max_gas_amount: 50000 + assets: + apt: + key_file_path: "/tmp/transfer_funder_devnet.key" handler_config: use_helpful_errors: true return_rejections_early: false diff --git a/crates/aptos-faucet/core/Cargo.toml b/crates/aptos-faucet/core/Cargo.toml index a078e9c95de..a921c24750b 100644 --- a/crates/aptos-faucet/core/Cargo.toml +++ b/crates/aptos-faucet/core/Cargo.toml @@ -29,7 +29,7 @@ futures = { workspace = true } hex = { workspace = true } ipnet = { workspace = true } iprange = "0.6.7" -lru = "0.9.0" +lru = { workspace = true } once_cell = { workspace = true } poem = { workspace = true } poem-openapi = { workspace = true } diff --git a/crates/aptos-faucet/core/src/endpoints/fund.rs b/crates/aptos-faucet/core/src/endpoints/fund.rs index c916e00f633..b6d8435a55a 100644 --- a/crates/aptos-faucet/core/src/endpoints/fund.rs +++ b/crates/aptos-faucet/core/src/endpoints/fund.rs @@ -56,19 +56,13 @@ impl FundRequest { if let Some(auth_key) = self.auth_key.as_ref() { return match AccountAddress::from_hex_literal(auth_key) { Ok(auth_key) => Some(auth_key), - Err(_) => match AccountAddress::from_hex(auth_key) { - Ok(auth_key) => Some(auth_key), - Err(_) => None, - }, + Err(_) => AccountAddress::from_hex(auth_key).ok(), }; } if let Some(address) = self.address.as_ref() { return match AccountAddress::from_hex_literal(address) { Ok(address) => Some(address), - Err(_) => match AccountAddress::from_hex(address) { - Ok(address) => Some(address), - Err(_) => None, - }, + Err(_) => AccountAddress::from_hex(address).ok(), }; } if let Some(pub_key) = self.pub_key.as_ref() { @@ -108,6 +102,7 @@ impl FundApi { async fn fund( &self, fund_request: Json, + asset: poem_openapi::param::Query>, // This automagically uses FromRequest to get this data from the request. // It takes into things like X-Forwarded-IP and X-Real-IP. source_ip: RealIp, @@ -116,7 +111,7 @@ impl FundApi { ) -> poem::Result, AptosTapErrorResponse> { let txns = self .components - .fund_inner(fund_request.0, source_ip, header_map, false) + .fund_inner(fund_request.0, source_ip, header_map, false, asset.0) .await?; Ok(Json(FundResponse { txn_hashes: get_hashes(&txns), @@ -138,6 +133,7 @@ impl FundApi { async fn is_eligible( &self, fund_request: Json, + asset: poem_openapi::param::Query>, // This automagically uses FromRequest to get this data from the request. // It takes into things like X-Forwarded-IP and X-Real-IP. source_ip: RealIp, @@ -155,10 +151,16 @@ impl FundApi { // Call Funder.fund with `check_only` set, meaning it only does the // initial set of checks without actually submitting any transactions - // to fund the account. + // to fund the account. Pass asset directly, funder will use its configured default if None. self.components .funder - .fund(fund_request.amount, checker_data.receiver, true, bypass) + .fund( + fund_request.amount, + checker_data.receiver, + asset.0, + true, + bypass, + ) .await?; Ok(()) @@ -198,7 +200,7 @@ impl FundApiComponents { source_ip: RealIp, header_map: &HeaderMap, dry_run: bool, - ) -> poem::Result<(CheckerData, bool, Option), AptosTapError> { + ) -> poem::Result<(CheckerData, bool, Option>), AptosTapError> { let permit = match &self.concurrent_requests_semaphore { Some(semaphore) => match semaphore.try_acquire() { Ok(permit) => Some(permit), @@ -287,15 +289,23 @@ impl FundApiComponents { // Same thing, this uses FromRequest. header_map: &HeaderMap, dry_run: bool, + asset: Option, ) -> poem::Result, AptosTapError> { let (checker_data, bypass, _semaphore_permit) = self .preprocess_request(&fund_request, source_ip, header_map, dry_run) .await?; - // Fund the account. + // Fund the account - pass asset directly, funder will use its configured default if None + let asset_for_logging = asset.clone(); let fund_result = self .funder - .fund(fund_request.amount, checker_data.receiver, false, bypass) + .fund( + fund_request.amount, + checker_data.receiver, + asset, + false, + bypass, + ) .await; // This might be empty if there is an error and we never got to the @@ -311,6 +321,7 @@ impl FundApiComponents { jwt_sub = jwt_sub(checker_data.headers.clone()).ok(), address = checker_data.receiver, requested_amount = fund_request.amount, + asset = asset_for_logging, txn_hashes = txn_hashes, success = fund_result.is_ok(), ); @@ -393,7 +404,7 @@ pub async fn mint( }; let txns = fund_api_components .0 - .fund_inner(fund_request, source_ip, header_map, false) + .fund_inner(fund_request, source_ip, header_map, false, None) .await .map_err(|e| { poem::Error::from((e.status_and_retry_after().0, anyhow::anyhow!(e.message))) diff --git a/crates/aptos-faucet/core/src/funder/common.rs b/crates/aptos-faucet/core/src/funder/common.rs index d88cf44e5f4..1d3fd93ea40 100644 --- a/crates/aptos-faucet/core/src/funder/common.rs +++ b/crates/aptos-faucet/core/src/funder/common.rs @@ -41,6 +41,12 @@ const MAX_NUM_OUTSTANDING_TRANSACTIONS: u64 = 15; const DEFAULT_KEY_FILE_PATH: &str = "/opt/aptos/etc/mint.key"; +/// Default asset name used when no asset is specified in requests. +pub const DEFAULT_ASSET_NAME: &str = "apt"; + +/// Default amount of coins to fund in OCTA. +pub const DEFAULT_AMOUNT_TO_FUND: u64 = 100_000_000_000; + /// This defines configuration for any Funder that needs to interact with a real /// blockchain API. This includes the MintFunder and the TransferFunder currently. /// @@ -62,20 +68,6 @@ pub struct ApiConnectionConfig { #[clap(skip)] pub additional_headers: Option>, - /// Path to the private key for creating test account and minting coins in - /// the MintFunder case, or for transferring coins in the TransferFunder case. - /// To keep Testnet simple, we used one private key for aptos root account - /// To manually generate a keypair, use generate-key: - /// `cargo run -p generate-keypair -- -o ` - #[serde(default = "ApiConnectionConfig::default_mint_key_file_path")] - #[clap(long, default_value = DEFAULT_KEY_FILE_PATH, value_parser)] - key_file_path: PathBuf, - - /// Hex string of an Ed25519PrivateKey for minting / transferring coins. - #[serde(skip_serializing_if = "Option::is_none")] - #[clap(long, value_parser = ConfigKey::::from_encoded_string)] - key: Option>, - /// Chain ID of the network this client is connecting to. For example, for mainnet: /// "MAINNET" or 1, testnet: "TESTNET" or 2. If there is no predefined string /// alias (e.g. "MAINNET"), just use the number. Note: Chain ID of 0 is not allowed. @@ -88,49 +80,15 @@ impl ApiConnectionConfig { node_url: Url, api_key: Option, additional_headers: Option>, - key_file_path: PathBuf, - key: Option>, chain_id: ChainId, ) -> Self { Self { node_url, api_key, additional_headers, - key_file_path, - key, chain_id, } } - - fn default_mint_key_file_path() -> PathBuf { - PathBuf::from_str(DEFAULT_KEY_FILE_PATH).unwrap() - } - - pub fn get_key(&self) -> Result { - if let Some(ref key) = self.key { - return Ok(key.private_key()); - } - let key_bytes = std::fs::read(self.key_file_path.as_path()).with_context(|| { - format!( - "Failed to read key file: {}", - self.key_file_path.to_string_lossy() - ) - })?; - // decode as bcs first, fall back to a file of hex - let result = aptos_sdk::bcs::from_bytes(&key_bytes); //.with_context(|| "bad bcs"); - if let Ok(x) = result { - return Ok(x); - } - let keystr = String::from_utf8(key_bytes).map_err(|e| anyhow!(e))?; - Ok(ConfigKey::from_encoded_string(keystr.as_str()) - .with_context(|| { - format!( - "{}: key file failed as both bcs and hex", - self.key_file_path.to_string_lossy() - ) - })? - .private_key()) - } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -238,14 +196,20 @@ impl Drop for NumOutstandingTransactionsResetter { /// This function is responsible for updating our local record of the sequence /// numbers of the funder and receiver accounts. +/// +/// Each asset has its own independent queue: HashMap>. +/// This ensures requests for different assets don't interfere with each other while maintaining +/// FIFO ordering within each asset. For single-asset funders (like TransferFunder), use +/// DEFAULT_ASSET_NAME. For multi-asset funders (like MintFunder), pass the specific asset name. pub async fn update_sequence_numbers( client: &Client, funder_account: &RwLock, - // The value here is the requester address and amount requested. - outstanding_requests: &RwLock>, + // Each asset has its own queue: HashMap> + outstanding_requests: &RwLock>>, receiver_address: AccountAddress, amount: u64, wait_for_outstanding_txns_secs: u64, + asset_name: &str, ) -> Result<(u64, Option), AptosTapError> { let (mut funder_seq, mut receiver_seq) = get_sequence_numbers(client, funder_account, receiver_address).await?; @@ -263,26 +227,42 @@ pub async fn update_sequence_numbers( let _resetter = NumOutstandingTransactionsResetter; let mut set_outstanding = false; + let request_key = (receiver_address, amount); + // We shouldn't have too many outstanding txns for _ in 0..(wait_for_outstanding_txns_secs * 2) { if our_funder_seq < funder_seq + MAX_NUM_OUTSTANDING_TRANSACTIONS { // Enforce a stronger ordering of priorities based upon the MintParams that arrived // first. Then put the other folks to sleep to try again until the queue fills up. if !set_outstanding { - let mut requests = outstanding_requests.write().await; - requests.push((receiver_address, amount)); + let mut requests_map = outstanding_requests.write().await; + let queue = requests_map + .entry(asset_name.to_string()) + .or_insert_with(Vec::new); + queue.push(request_key); set_outstanding = true; } - if outstanding_requests.read().await.first() == Some(&(receiver_address, amount)) { + // Check if this request is at the front of the queue for this asset + let requests_map = outstanding_requests.read().await; + let is_at_front = if let Some(queue) = requests_map.get(asset_name) { + queue.first() == Some(&request_key) + } else { + false + }; + + if is_at_front { // There might have been two requests with the same parameters, so we ensure that // we only pop off one of them. We do a read lock first since that is cheap, // followed by a write lock. - let mut requests = outstanding_requests.write().await; - if requests.first() == Some(&(receiver_address, amount)) { - requests.remove(0); - break; + drop(requests_map); + let mut requests_map = outstanding_requests.write().await; + if let Some(queue) = requests_map.get_mut(asset_name) { + if queue.first() == Some(&request_key) { + queue.remove(0); + } } + break; } tokio::time::sleep(tokio::time::Duration::from_millis(1)).await; continue; @@ -467,3 +447,56 @@ impl GasUnitPriceManager { .gas_estimate) } } + +#[derive(Clone, Debug, Deserialize, Serialize, Parser)] +pub struct AssetConfig { + /// Path to the private key for creating test account and minting coins in + /// the MintFunder case, or for transferring coins in the TransferFunder case. + /// To keep Testnet simple, we used one private key for aptos root account + /// To manually generate a keypair, use generate-key: + /// `cargo run -p generate-keypair -- -o ` + #[serde(default = "AssetConfig::default_key_file_path")] + #[clap(long, default_value = DEFAULT_KEY_FILE_PATH, value_parser)] + pub key_file_path: PathBuf, + + /// Hex string of an Ed25519PrivateKey for minting / transferring coins. + #[serde(skip_serializing_if = "Option::is_none")] + #[clap(long, value_parser = ConfigKey::::from_encoded_string)] + pub key: Option>, +} + +impl AssetConfig { + pub fn new(key: Option>, key_file_path: PathBuf) -> Self { + Self { key, key_file_path } + } + + fn default_key_file_path() -> PathBuf { + PathBuf::from_str(DEFAULT_KEY_FILE_PATH).unwrap() + } + + pub fn get_key(&self) -> Result { + if let Some(ref key) = self.key { + return Ok(key.private_key()); + } + let key_bytes = std::fs::read(self.key_file_path.as_path()).with_context(|| { + format!( + "Failed to read key file: {}", + self.key_file_path.to_string_lossy() + ) + })?; + // decode as bcs first, fall back to a file of hex + let result = aptos_sdk::bcs::from_bytes(&key_bytes); + if let Ok(x) = result { + return Ok(x); + } + let keystr = String::from_utf8(key_bytes).map_err(|e| anyhow!(e))?; + Ok(ConfigKey::from_encoded_string(keystr.as_str()) + .with_context(|| { + format!( + "{}: key file failed as both bcs and hex", + self.key_file_path.to_string_lossy() + ) + })? + .private_key()) + } +} diff --git a/crates/aptos-faucet/core/src/funder/fake.rs b/crates/aptos-faucet/core/src/funder/fake.rs index 57e6e4a7804..8db57e17319 100644 --- a/crates/aptos-faucet/core/src/funder/fake.rs +++ b/crates/aptos-faucet/core/src/funder/fake.rs @@ -18,6 +18,7 @@ impl FunderTrait for FakeFunder { &self, _amount: Option, _receiver_address: AccountAddress, + _asset: Option, _check_only: bool, _did_bypass_checkers: bool, ) -> Result, AptosTapError> { diff --git a/crates/aptos-faucet/core/src/funder/mint.rs b/crates/aptos-faucet/core/src/funder/mint.rs index 3321d2819f7..97a2934778e 100644 --- a/crates/aptos-faucet/core/src/funder/mint.rs +++ b/crates/aptos-faucet/core/src/funder/mint.rs @@ -7,14 +7,16 @@ use crate::endpoints::{AptosTapError, AptosTapErrorCode}; use anyhow::{Context, Result}; use aptos_logger::info; use aptos_sdk::{ - crypto::ed25519::Ed25519PublicKey, + crypto::ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, + move_types::{identifier::Identifier, language_storage::ModuleId}, rest_client::{AptosBaseUrl, Client}, transaction_builder::{aptos_stdlib, TransactionFactory}, types::{ account_address::AccountAddress, chain_id::ChainId, transaction::{ - authenticator::AuthenticationKey, Script, SignedTransaction, TransactionArgument, + authenticator::AuthenticationKey, EntryFunction, Script, SignedTransaction, + TransactionArgument, TransactionPayload, }, LocalAccount, }, @@ -30,20 +32,39 @@ static MINTER_SCRIPT: &[u8] = include_bytes!( ); use super::common::{ - submit_transaction, update_sequence_numbers, ApiConnectionConfig, GasUnitPriceManager, - TransactionSubmissionConfig, + submit_transaction, update_sequence_numbers, ApiConnectionConfig, AssetConfig, + GasUnitPriceManager, TransactionSubmissionConfig, DEFAULT_AMOUNT_TO_FUND, DEFAULT_ASSET_NAME, }; -/// explain these contain additional args for the mint funder. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct MintFunderConfig { - #[serde(flatten)] - pub api_connection_config: ApiConnectionConfig, +/// Entry function identifier containing module and function information. +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct EntryFunctionId { + /// Module address for the entry function + pub module_address: AccountAddress, + /// Module name for the entry function + pub module_name: String, + /// Function name for the entry function + pub function_name: String, +} + +/// Transaction method for minting coins. +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Default)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum TransactionMethod { + /// Use a script-based transaction (default) + #[default] + Script, + /// Use an entry function transaction + EntryFunction(EntryFunctionId), +} +/// Asset configuration specific to minting, extends the base AssetConfig with mint-specific fields. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct MintAssetConfig { #[serde(flatten)] - pub transaction_submission_config: TransactionSubmissionConfig, + pub default: AssetConfig, - /// Address of the account to send transactions from. On testnet, for + /// Address of the account to send transactions from. On localnet, for /// example, this is a550c18. If not given, we use the account address /// corresponding to the given private key. pub mint_account_address: Option, @@ -51,38 +72,132 @@ pub struct MintFunderConfig { /// Just use the account given in funder args, don't make a new one and /// delegate the mint capability to it. pub do_not_delegate: bool, + + /// Transaction method: script (default) or entry_function + #[serde(default)] + pub transaction_method: TransactionMethod, +} + +impl MintAssetConfig { + pub fn new( + default: AssetConfig, + mint_account_address: Option, + do_not_delegate: bool, + ) -> Self { + Self { + default, + mint_account_address, + do_not_delegate, + transaction_method: TransactionMethod::default(), + } + } + + /// Delegate to the default AssetConfig's get_key method. + pub fn get_key(&self) -> Result { + self.default.get_key() + } +} + +/// explain these contain additional args for the mint funder. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct MintFunderConfig { + #[serde(flatten)] + pub api_connection_config: ApiConnectionConfig, + + #[serde(flatten)] + pub transaction_submission_config: TransactionSubmissionConfig, + + pub assets: HashMap, + + /// Default asset to use when no asset is specified in requests. + /// If not provided, defaults to "apt". + #[serde(default = "MintFunderConfig::get_default_asset_name")] + pub default_asset: String, + + /// Default amount of coins to fund. + /// If not provided, defaults to 100_000_000_000. + #[serde(default = "MintFunderConfig::get_default_amount_to_fund")] + pub amount_to_fund: u64, } impl MintFunderConfig { pub async fn build_funder(self) -> Result { - let key = self.api_connection_config.get_key()?; - - let faucet_account = LocalAccount::new( - self.mint_account_address.unwrap_or_else(|| { - AuthenticationKey::ed25519(&Ed25519PublicKey::from(&key)).account_address() - }), - key, - 0, - ); + // Validate we have at least one asset + if self.assets.is_empty() { + return Err(anyhow::anyhow!("No assets configured")); + } + + // Validate that the default asset exists in the assets map + self.assets.get(&self.default_asset).ok_or_else(|| { + anyhow::anyhow!( + "Default asset '{}' is not configured in assets map", + self.default_asset + ) + })?; - let mut minter = MintFunder::new( + let mut assets_with_accounts = HashMap::new(); + + for (asset_name, asset_config) in self.assets { + let key = asset_config.get_key()?; + + // Create the mint account + let mint_account = LocalAccount::new( + asset_config.mint_account_address.unwrap_or_else(|| { + AuthenticationKey::ed25519(&Ed25519PublicKey::from(&key)).account_address() + }), + key, + 0, + ); + + assets_with_accounts.insert(asset_name, (asset_config, RwLock::new(mint_account))); + } + + let minter = MintFunder::new( self.api_connection_config.node_url.clone(), self.api_connection_config.api_key.clone(), self.api_connection_config.additional_headers.clone(), self.api_connection_config.chain_id, self.transaction_submission_config, - faucet_account, + assets_with_accounts, + self.default_asset, + self.amount_to_fund, ); - if !self.do_not_delegate { - minter - .use_delegated_account() - .await - .context("Failed to make MintFunder use delegated account")?; + let asset_names: Vec = minter.assets.keys().cloned().collect(); + for asset_name in asset_names { + let (asset_config, _) = minter + .get_asset(&asset_name) + .with_context(|| format!("Asset '{}' not found", asset_name))?; + + if !asset_config.do_not_delegate { + // Delegate permissions to a new account + let delegated_account = minter + .use_delegated_account(&asset_name) + .await + .with_context(|| { + format!("Failed to delegate account for asset '{}'", asset_name) + })?; + + // Update the account in the assets map + minter + .update_asset_account(&asset_name, delegated_account) + .await + .with_context(|| { + format!("Failed to update asset account for '{}'", asset_name) + })?; + } } Ok(minter) } + + pub fn get_default_asset_name() -> String { + DEFAULT_ASSET_NAME.to_string() + } + + fn get_default_amount_to_fund() -> u64 { + DEFAULT_AMOUNT_TO_FUND + } } pub struct MintFunder { @@ -93,15 +208,20 @@ pub struct MintFunder { txn_config: TransactionSubmissionConfig, - faucet_account: RwLock, - transaction_factory: TransactionFactory, gas_unit_price_manager: GasUnitPriceManager, /// When recovering from being overloaded, this struct ensures we handle - /// requests in the order they came in. - outstanding_requests: RwLock>, + /// requests in the order they came in. Each asset has its own independent queue + /// (HashMap>), maintaining FIFO ordering + /// within each asset without interference between assets. + outstanding_requests: RwLock>>, + + // Multi-asset support: store asset configs + assets: HashMap)>, + default_asset: String, + amount_to_fund: u64, } impl MintFunder { @@ -111,7 +231,9 @@ impl MintFunder { node_additional_headers: Option>, chain_id: ChainId, txn_config: TransactionSubmissionConfig, - faucet_account: LocalAccount, + assets: HashMap)>, + default_asset: String, + amount_to_fund: u64, ) -> Self { let gas_unit_price_manager = GasUnitPriceManager::new(node_url.clone(), txn_config.get_gas_unit_price_ttl_secs()); @@ -123,10 +245,12 @@ impl MintFunder { node_api_key, node_additional_headers, txn_config, - faucet_account: RwLock::new(faucet_account), transaction_factory, gas_unit_price_manager, - outstanding_requests: RwLock::new(vec![]), + outstanding_requests: RwLock::new(HashMap::new()), + assets, + default_asset, + amount_to_fund, } } @@ -150,8 +274,10 @@ impl MintFunder { .with_gas_unit_price(self.get_gas_unit_price().await?)) } - /// todo explain / rename - pub async fn use_delegated_account(&mut self) -> Result<()> { + /// Performs the delegated account creation and delegation. The (Aptos) coin::mint function that + /// used in the MintFunder expects the caller to have the MintCapability. + /// So we need to create a new account and delegate the MintCapability to it. + pub async fn use_delegated_account(&self, asset_name: &str) -> Result { // Build a client. let client = self.get_api_client(); @@ -168,6 +294,7 @@ impl MintFunder { .account_address(), false, true, + asset_name, ) .await .context("Failed to create new account")?; @@ -179,7 +306,7 @@ impl MintFunder { // Delegate minting to the account { - let faucet_account = self.faucet_account.write().await; + let faucet_account = self.get_asset_account(asset_name)?.read().await; client .submit_and_wait(&faucet_account.sign_with_transaction_builder( transaction_factory.payload(aptos_stdlib::aptos_coin_delegate_mint_capability( @@ -199,13 +326,12 @@ impl MintFunder { .context("Failed to claim the minting capability")?; info!( - "Successfully configured MintFunder to use delegated account: {}", + "Successfully configured MintFunder to use delegated account for asset '{}': {}", + asset_name, delegated_account.address() ); - self.faucet_account = RwLock::new(delegated_account); - - Ok(()) + Ok(delegated_account) } /// Within a single request we should just call this once and use this client @@ -227,6 +353,47 @@ impl MintFunder { builder.build() } + /// Get the asset config and account for a given asset name. + /// Returns an error if the asset doesn't exist (should never happen in normal operation). + fn get_asset( + &self, + asset_name: &str, + ) -> Result<&(MintAssetConfig, RwLock), AptosTapError> { + self.assets.get(asset_name).ok_or_else(|| { + AptosTapError::new( + format!("Asset '{}' not found", asset_name), + AptosTapErrorCode::InvalidRequest, + ) + }) + } + + /// Get the account RwLock for a given asset name. + /// Returns an error if the asset doesn't exist. + fn get_asset_account(&self, asset_name: &str) -> Result<&RwLock, AptosTapError> { + self.get_asset(asset_name).map(|(_, account)| account) + } + + /// Get the asset config for a given asset name. + /// Returns an error if the asset doesn't exist. + fn get_asset_config(&self, asset_name: &str) -> Result<&MintAssetConfig, AptosTapError> { + self.get_asset(asset_name).map(|(config, _)| config) + } + + /// Update the account for a given asset name. + /// This is useful after delegating mint capabilities to a new account. + pub async fn update_asset_account( + &self, + asset_name: &str, + new_account: LocalAccount, + ) -> Result<()> { + let account_rwlock = self + .get_asset_account(asset_name) + .map_err(|e| anyhow::anyhow!("{}", e))?; + *account_rwlock.write().await = new_account; + Ok(()) + } + + /// Core processing logic that handles sequence numbers and transaction submission. pub async fn process( &self, client: &Client, @@ -234,14 +401,16 @@ impl MintFunder { receiver_address: AccountAddress, check_only: bool, wait_for_transactions: bool, + asset_name: &str, ) -> Result, AptosTapError> { let (_faucet_seq, receiver_seq) = update_sequence_numbers( client, - &self.faucet_account, + self.get_asset_account(asset_name)?, &self.outstanding_requests, receiver_address, amount, self.txn_config.wait_for_outstanding_txns_secs, + asset_name, ) .await?; @@ -259,22 +428,78 @@ impl MintFunder { return Ok(vec![]); } - let txn = - { - let faucet_account = self.faucet_account.write().await; - let transaction_factory = self.get_transaction_factory().await?; - faucet_account.sign_with_transaction_builder(transaction_factory.script( - Script::new(MINTER_SCRIPT.to_vec(), vec![], vec![ + let asset_config = self.get_asset_config(asset_name)?; + let transaction_factory = self.get_transaction_factory().await?; + + let txn = { + let faucet_account = self.get_asset_account(asset_name)?.write().await; + + let payload = match &asset_config.transaction_method { + TransactionMethod::EntryFunction(entry_function_id) => { + // Create ModuleId from module_address and module_name + let module_id = ModuleId::new( + entry_function_id.module_address, + Identifier::new(entry_function_id.module_name.as_str()).map_err(|e| { + AptosTapError::new( + format!( + "Invalid module_name '{}': {}", + entry_function_id.module_name, e + ), + AptosTapErrorCode::InvalidRequest, + ) + })?, + ); + + // Create function identifier + let function_identifier = + Identifier::new(entry_function_id.function_name.as_str()).map_err(|e| { + AptosTapError::new( + format!( + "Invalid function_name '{}': {}", + entry_function_id.function_name, e + ), + AptosTapErrorCode::InvalidRequest, + ) + })?; + + // Serialize arguments (receiver_address and amount) + use aptos_sdk::bcs; + let args = vec![ + bcs::to_bytes(&receiver_address).map_err(|e| { + AptosTapError::new( + format!("Failed to serialize receiver_address: {}", e), + AptosTapErrorCode::InvalidRequest, + ) + })?, + bcs::to_bytes(&amount).map_err(|e| { + AptosTapError::new( + format!("Failed to serialize amount: {}", e), + AptosTapErrorCode::InvalidRequest, + ) + })?, + ]; + + let entry_function = + EntryFunction::new(module_id, function_identifier, vec![], args); + + TransactionPayload::EntryFunction(entry_function) + }, + TransactionMethod::Script => { + // Default script-based approach + TransactionPayload::Script(Script::new(MINTER_SCRIPT.to_vec(), vec![], vec![ TransactionArgument::Address(receiver_address), TransactionArgument::U64(amount), - ]), - )) + ])) + }, }; + faucet_account.sign_with_transaction_builder(transaction_factory.payload(payload)) + }; + Ok(vec![ submit_transaction( client, - &self.faucet_account, + self.get_asset_account(asset_name)?, txn, &receiver_address, wait_for_transactions, @@ -290,9 +515,16 @@ impl FunderTrait for MintFunder { &self, amount: Option, receiver_address: AccountAddress, + asset: Option, check_only: bool, did_bypass_checkers: bool, ) -> Result, AptosTapError> { + // Resolve asset (use configured default if not specified) + let asset_name = asset.as_deref().unwrap_or(&self.default_asset); + + // Validate asset exists + self.get_asset_config(asset_name)?; + let client = self.get_api_client(); let amount = self.get_amount(amount, did_bypass_checkers); self.process( @@ -301,6 +533,7 @@ impl FunderTrait for MintFunder { receiver_address, check_only, self.txn_config.wait_for_transactions, + asset_name, ) .await } @@ -312,14 +545,25 @@ impl FunderTrait for MintFunder { ) { (Some(amount), Some(maximum_amount)) => std::cmp::min(amount, maximum_amount), (Some(amount), None) => amount, - (None, Some(maximum_amount)) => maximum_amount, - (None, None) => 0, + (None, Some(maximum_amount)) => std::cmp::min(self.amount_to_fund, maximum_amount), + (None, None) => self.amount_to_fund, } } /// Assert the funder account actually exists. async fn is_healthy(&self) -> FunderHealthMessage { - let account_address = self.faucet_account.read().await.address(); + let account_address = match self.get_asset_account(&self.default_asset) { + Ok(account) => account.read().await.address(), + Err(e) => { + return FunderHealthMessage { + can_process_requests: false, + message: Some(format!( + "Default asset '{}' not found: {}", + self.default_asset, e + )), + }; + }, + }; let client = self.get_api_client(); match client.get_account_bcs(account_address).await { Ok(_) => FunderHealthMessage { diff --git a/crates/aptos-faucet/core/src/funder/mod.rs b/crates/aptos-faucet/core/src/funder/mod.rs index 936b7237599..ca0dacac9e9 100644 --- a/crates/aptos-faucet/core/src/funder/mod.rs +++ b/crates/aptos-faucet/core/src/funder/mod.rs @@ -7,8 +7,8 @@ mod mint; mod transfer; pub use self::{ - common::{ApiConnectionConfig, TransactionSubmissionConfig}, - mint::MintFunderConfig, + common::{ApiConnectionConfig, AssetConfig, TransactionSubmissionConfig, DEFAULT_ASSET_NAME}, + mint::{MintAssetConfig, MintFunderConfig}, }; use self::{fake::FakeFunderConfig, transfer::TransferFunderConfig}; use crate::endpoints::AptosTapError; @@ -37,6 +37,7 @@ pub trait FunderTrait: Sync + Send + 'static { &self, amount: Option, receiver_address: AccountAddress, + asset: Option, check_only: bool, // True if a Bypasser let this request bypass the Checkers. did_bypass_checkers: bool, diff --git a/crates/aptos-faucet/core/src/funder/transfer.rs b/crates/aptos-faucet/core/src/funder/transfer.rs index d15f00ff096..9fa7ce0d40b 100644 --- a/crates/aptos-faucet/core/src/funder/transfer.rs +++ b/crates/aptos-faucet/core/src/funder/transfer.rs @@ -3,7 +3,8 @@ use super::{ common::{ - submit_transaction, ApiConnectionConfig, GasUnitPriceManager, TransactionSubmissionConfig, + submit_transaction, ApiConnectionConfig, AssetConfig, GasUnitPriceManager, + TransactionSubmissionConfig, DEFAULT_ASSET_NAME, }, FunderHealthMessage, FunderTrait, }; @@ -46,12 +47,21 @@ pub struct TransferFunderConfig { /// The amount of coins to fund the receiver account. pub amount_to_fund: AmountToFund, + + /// The assets to transfer. + pub assets: HashMap, } impl TransferFunderConfig { pub async fn build_funder(&self) -> Result { // Read in private key. - let key = self.api_connection_config.get_key()?; + let apt_asset_config = self.assets.get(DEFAULT_ASSET_NAME).ok_or_else(|| { + anyhow::anyhow!( + "TransferFunder requires an '{}' asset configuration. Please add it to the assets map.", + DEFAULT_ASSET_NAME + ) + })?; + let key = apt_asset_config.get_key()?; // Build account address from private key. let account_address = account_address_from_private_key(&key); @@ -106,8 +116,9 @@ pub struct TransferFunder { gas_unit_price_override: Option, /// When recovering from being overloaded, this struct ensures we handle - /// requests in the order they came in. - outstanding_requests: RwLock>, + /// requests in the order they came in. TransferFunder uses DEFAULT_ASSET_NAME for all requests + /// since it only handles a single asset. The queue format is Vec<(AccountAddress, u64)>. + outstanding_requests: RwLock>>, /// Amount of time we'll wait for the seqnum to catch up before resetting it. wait_for_outstanding_txns_secs: u64, @@ -147,7 +158,7 @@ impl TransferFunder { amount_to_fund, gas_unit_price_manager, gas_unit_price_override, - outstanding_requests: RwLock::new(vec![]), + outstanding_requests: RwLock::new(HashMap::new()), wait_for_outstanding_txns_secs, wait_for_transactions, } @@ -253,6 +264,7 @@ impl FunderTrait for TransferFunder { &self, amount: Option, receiver_address: AccountAddress, + _asset: Option, check_only: bool, did_bypass_checkers: bool, ) -> Result, AptosTapError> { @@ -268,6 +280,7 @@ impl FunderTrait for TransferFunder { let amount = self.get_amount(amount, did_bypass_checkers); // Update the sequence numbers of the accounts. + // TransferFunder always uses DEFAULT_ASSET_NAME since it only handles a single asset. let (_funder_seq_num, receiver_seq_num) = update_sequence_numbers( &client, &self.faucet_account, @@ -275,6 +288,7 @@ impl FunderTrait for TransferFunder { receiver_address, amount, self.wait_for_outstanding_txns_secs, + DEFAULT_ASSET_NAME, ) .await?; diff --git a/crates/aptos-faucet/core/src/server/run.rs b/crates/aptos-faucet/core/src/server/run.rs index 3152298aaa9..451ddd3ee4d 100644 --- a/crates/aptos-faucet/core/src/server/run.rs +++ b/crates/aptos-faucet/core/src/server/run.rs @@ -9,7 +9,10 @@ use crate::{ build_openapi_service, convert_error, mint, BasicApi, CaptchaApi, FundApi, FundApiComponents, }, - funder::{ApiConnectionConfig, FunderConfig, MintFunderConfig, TransactionSubmissionConfig}, + funder::{ + ApiConnectionConfig, AssetConfig, FunderConfig, MintAssetConfig, MintFunderConfig, + TransactionSubmissionConfig, DEFAULT_ASSET_NAME, + }, middleware::middleware_log, }; use anyhow::{anyhow, Context, Result}; @@ -18,14 +21,18 @@ use aptos_faucet_metrics_server::{run_metrics_server, MetricsServerConfig}; use aptos_logger::info; use aptos_sdk::{ crypto::ed25519::Ed25519PrivateKey, - types::{account_config::aptos_test_root_address, chain_id::ChainId}, + types::{ + account_address::AccountAddress, account_config::aptos_test_root_address, chain_id::ChainId, + }, }; use clap::Parser; use futures::{channel::oneshot::Sender as OneShotSender, lock::Mutex}; use poem::{http::Method, listener::TcpAcceptor, middleware::Cors, EndpointExt, Route, Server}; use reqwest::Url; use serde::{Deserialize, Serialize}; -use std::{fs::File, io::BufReader, path::PathBuf, pin::Pin, str::FromStr, sync::Arc}; +use std::{ + collections::HashMap, fs::File, io::BufReader, path::PathBuf, pin::Pin, str::FromStr, sync::Arc, +}; use tokio::{net::TcpListener, sync::Semaphore, task::JoinSet}; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -251,7 +258,7 @@ impl RunConfig { do_not_delegate: bool, chain_id: Option, ) -> Self { - let (key_file_path, key) = match funder_key { + let (key_file_path, _key) = match funder_key { FunderKeyEnum::KeyFile(key_file_path) => (key_file_path, None), FunderKeyEnum::Key(key) => (PathBuf::from_str("/dummy").unwrap(), Some(key)), }; @@ -273,8 +280,6 @@ impl RunConfig { api_url, None, None, - key_file_path, - key, chain_id.unwrap_or_else(ChainId::test), ), transaction_submission_config: TransactionSubmissionConfig::new( @@ -287,8 +292,16 @@ impl RunConfig { 35, // wait_for_outstanding_txns_secs false, // wait_for_transactions ), - mint_account_address: Some(aptos_test_root_address()), - do_not_delegate, + assets: HashMap::from([( + DEFAULT_ASSET_NAME.to_string(), + MintAssetConfig::new( + AssetConfig::new(_key, key_file_path), + Some(aptos_test_root_address()), + do_not_delegate, + ), + )]), + default_asset: MintFunderConfig::get_default_asset_name(), + amount_to_fund: 100_000_000_000, }), handler_config: HandlerConfig { use_helpful_errors: true, @@ -350,16 +363,28 @@ pub struct RunSimple { #[clap(long, default_value_t = 8081)] pub listen_port: u16, + /// Path to the private key file for the APT asset + #[clap(long, default_value = "/tmp/mint.key")] + pub key_file_path: PathBuf, + + /// Address of the mint account (optional) #[clap(long)] - do_not_delegate: bool, + pub mint_account_address: Option, + + /// Whether to skip delegation + #[clap(long)] + pub do_not_delegate: bool, } impl RunSimple { pub async fn run_simple(&self) -> Result<()> { - let key = self - .api_connection_config + // Create an AssetConfig from the CLI arguments to get the key + let asset_config = AssetConfig::new(None, self.key_file_path.clone()); + + let key = asset_config .get_key() .context("Failed to load private key")?; + let run_config = RunConfig::build_for_cli( self.api_connection_config.node_url.clone(), self.listen_address.clone(), @@ -698,7 +723,7 @@ mod test { async fn test_transfer_health() -> Result<()> { // Create a local account and store its private key at the path expected by // the config for this test. - let private_key = Ed25519PrivateKey::generate(&mut StdRng::from_seed(OsRng.gen())); + let private_key = Ed25519PrivateKey::generate(&mut StdRng::from_seed(OsRng.r#gen())); let serialized_keys = aptos_sdk::bcs::to_bytes(&private_key)?; let mut key_file = std::fs::File::create("/tmp/transfer_funder_devnet.key")?; key_file.write_all(&serialized_keys)?; diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs index c3440d5cee2..cf112106154 100644 --- a/crates/aptos-genesis/src/builder.rs +++ b/crates/aptos-genesis/src/builder.rs @@ -531,7 +531,7 @@ impl Builder { ); // Generate root key - let mut keygen = KeyGen::from_seed(rng.gen()); + let mut keygen = KeyGen::from_seed(rng.r#gen()); let root_key = keygen.generate_ed25519_private_key(); // Generate validator configs @@ -581,7 +581,7 @@ impl Builder { 0, )?; - validator.init_keys(Some(rng.gen()))?; + validator.init_keys(Some(rng.r#gen()))?; // By default, we don't start with VFNs, so ensure that the REST port is open let vfn_identity_path = validator.dir.join(VFN_IDENTITY); diff --git a/crates/aptos-in-memory-cache/Cargo.toml b/crates/aptos-in-memory-cache/Cargo.toml new file mode 100644 index 00000000000..c9016d3aa9c --- /dev/null +++ b/crates/aptos-in-memory-cache/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "aptos-in-memory-cache" +description = "In-memory cache" +version = "0.1.0" + +# Workspace inherited keys +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +parking_lot = { workspace = true } + +[dev-dependencies] +get-size = { workspace = true } +tokio = { workspace = true } diff --git a/crates/aptos-in-memory-cache/src/caches/mod.rs b/crates/aptos-in-memory-cache/src/caches/mod.rs new file mode 100644 index 00000000000..052bc64be0f --- /dev/null +++ b/crates/aptos-in-memory-cache/src/caches/mod.rs @@ -0,0 +1,6 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +mod sync_mutex; + +pub use sync_mutex::SyncMutexCache; diff --git a/crates/aptos-in-memory-cache/src/caches/sync_mutex.rs b/crates/aptos-in-memory-cache/src/caches/sync_mutex.rs new file mode 100644 index 00000000000..87a635b9e3d --- /dev/null +++ b/crates/aptos-in-memory-cache/src/caches/sync_mutex.rs @@ -0,0 +1,153 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{SizedCache, SizedCacheEntry}; +use parking_lot::Mutex; +use std::sync::atomic::{AtomicUsize, Ordering}; + +type CacheEntry = SizedCacheEntry; +type CacheEntryLock = Mutex>>; + +const DEFAULT_MAX_NUM_CACHE_ITEMS: usize = 1_000_000; + +/// An in-memory cache that uses a mutex to synchronize access to the cache entries. +/// The cache is designed with indexing use cases in mind and is backed by a fixed-size array. +/// +/// ## Example +/// +/// This in-memory cache can be used as the base for a cache that supports out of order insertion and a deterministic eviction policy that evicts the smallest value. +/// It would behave as follows: +/// +/// 1. Initialize cache with a capacity of 9 and eviction limit of 5 +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | | | | | | | | | | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +/// +/// 2. Insert 5 → `5 % 9 = 5` → `cache[5] = 5` +/// * Capacity at 1 +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | | | | | | 5 | | | | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +/// +/// 3. Insert 6, 7, 8 +/// * Capacity at 4 +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | | | | | | 5 | 6 | 7 | 8 | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +/// +/// 4. Insert 9 → `9 % 9 = 0` → `cache[0] = 9` +/// * Capacity at 5 (limit) +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | 9 | | | | | 5 | 6 | 7 | 8 | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +/// +/// 5. Insert 11 → `11 % 9 = 2` → `cache[2] = 11` +/// Evict 5 → `5 % 9 = 5` → `cache[5] = None` +/// * Capacity at 5 +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | 9 | | 11| | | | 6 | 7 | 8 | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +/// +/// 6. Insert 10 → `10 % 9 = 1` → `cache[1] = 10` +/// Evict 6 → `6 % 9 = 6` → `cache[6] = None` +/// * Capacity at 5 +/// ```text +/// +---+---+---+---+---+---+---+---+---+ +/// | 9 | 10| 11| | | | | 7 | 8 | +/// +---+---+---+---+---+---+---+---+---+ +/// ``` +#[derive(Debug)] +pub struct SyncMutexCache { + cache: Box<[CacheEntryLock]>, + capacity: usize, + size: AtomicUsize, +} + +impl SyncMutexCache +where + T: Send + Sync + Clone, +{ + /// Initializes a new [`SyncMutexCache`] with the given capacity. + pub fn with_capacity(capacity: usize) -> Self { + let mut buffer = Vec::with_capacity(capacity); + for _ in 0..capacity { + buffer.push(Mutex::new(None)); + } + + Self { + cache: buffer.into_boxed_slice(), + capacity, + size: AtomicUsize::new(0), + } + } +} + +impl Default for SyncMutexCache +where + T: Send + Sync + Clone, +{ + fn default() -> Self { + Self::with_capacity(DEFAULT_MAX_NUM_CACHE_ITEMS) + } +} + +impl SizedCache for SyncMutexCache +where + T: Send + Sync + Clone, +{ + fn get(&self, key: &usize) -> Option> { + let index = *key % self.capacity; + let lock = self.cache[index].lock(); + lock.clone() + } + + fn insert_with_size(&self, key: usize, value: T, size_in_bytes: usize) -> usize { + let index = key % self.capacity; + let mut lock = self.cache[index].lock(); + + // Update cache size + if let Some(prev) = &*lock { + self.size.fetch_sub(prev.size_in_bytes, Ordering::Relaxed); + } + + // Update cache entry + self.size.fetch_add(size_in_bytes, Ordering::Relaxed); + *lock = Some(SizedCacheEntry { + key, + value, + size_in_bytes, + }); + + index + } + + fn evict(&self, key: &usize) -> Option> { + let index = *key % self.capacity; + let mut lock = self.cache[index].lock(); + + // Update the cache size and set the value at key to none + if let Some(prev) = lock.take() { + self.size.fetch_sub(prev.size_in_bytes, Ordering::Relaxed); + return Some(prev); + } + None + } + + fn total_size(&self) -> usize { + self.size.load(Ordering::Relaxed) + } + + fn capacity(&self) -> usize { + self.capacity + } +} diff --git a/crates/aptos-in-memory-cache/src/lib.rs b/crates/aptos-in-memory-cache/src/lib.rs new file mode 100644 index 00000000000..c1c6648c116 --- /dev/null +++ b/crates/aptos-in-memory-cache/src/lib.rs @@ -0,0 +1,50 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use std::hash::Hash; + +pub mod caches; + +/// A struct that holds a single cache entry, containing its key, value, and size in bytes. +#[derive(Clone, Debug)] +pub struct SizedCacheEntry { + pub key: K, + pub value: V, + pub size_in_bytes: usize, +} + +/// A trait for a fixed capacity cache where size is tracked and values are keyed by [`usize`]. +pub trait SizedCache: Send + Sync { + /// Get the value for a given [`usize`] key. + /// Return [`None`] if the key is not in the cache. + fn get(&self, key: &K) -> Option>; + + /// Inserts a given [`usize`] key-value pair and its size into the cache. + /// Returns the index of the inserted entry. + fn insert_with_size(&self, key: K, value: V, size_in_bytes: usize) -> usize; + + /// Evicts the value for a given [`usize`] key from the cache. + fn evict(&self, key: &K) -> Option>; + + /// Returns the total size of the cache. + fn total_size(&self) -> usize; + + /// Returns the maximum number of items the cache can hold at once. + fn capacity(&self) -> usize; +} + +/// A helper trait for a cache that can be used to store key-value pairs. +pub trait Cache: Send + Sync +where + K: Eq + Hash + Clone + Send + Sync, + V: Clone + Send + Sync, +{ + /// Get the value for a given key. Return [`None`] if the key is not in the cache. + fn get(&self, key: &K) -> Option; + + /// Inserts a given key-value pair in cache. Panics if the insert fails. + fn insert(&self, key: K, value: V); + + /// Returns the total size of the cache. + fn total_size(&self) -> usize; +} diff --git a/crates/aptos-in-memory-cache/tests/common/mod.rs b/crates/aptos-in-memory-cache/tests/common/mod.rs new file mode 100644 index 00000000000..a1b0fea17de --- /dev/null +++ b/crates/aptos-in-memory-cache/tests/common/mod.rs @@ -0,0 +1,129 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_in_memory_cache::{Cache, SizedCache}; +use get_size::GetSize; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; +use tokio::{sync::Notify, task::JoinHandle}; + +#[derive(Clone, GetSize, Debug, PartialEq)] +pub struct NotATransaction { + transaction_version: i64, +} + +impl NotATransaction { + pub fn new(transaction_version: i64) -> Self { + Self { + transaction_version, + } + } +} + +#[derive(Debug, Clone)] +pub struct TestCacheMetadata { + pub eviction_trigger_size_in_bytes: usize, + pub target_size_in_bytes: usize, + pub capacity: usize, +} + +#[derive(Debug)] +pub struct TestCache + 'static> { + pub metadata: Arc, + pub cache: Arc, + pub insert_notify: Arc, + pub eviction_start: Arc, + pub eviction_task: JoinHandle<()>, +} + +impl + 'static> Drop for TestCache { + fn drop(&mut self) { + self.eviction_task.abort(); + } +} + +impl + 'static> TestCache { + pub fn with_capacity( + c: C, + eviction_trigger_size_in_bytes: usize, + target_size_in_bytes: usize, + ) -> Self { + let metadata = Arc::new(TestCacheMetadata { + eviction_trigger_size_in_bytes, + target_size_in_bytes, + capacity: c.capacity(), + }); + let cache = Arc::new(c); + let insert_notify = Arc::new(Notify::new()); + let highest_key = Arc::new(AtomicUsize::new(0)); + let task = spawn_eviction_task( + insert_notify.clone(), + highest_key.clone(), + metadata.clone(), + cache.clone(), + ); + + Self { + metadata, + cache, + insert_notify, + eviction_start: highest_key, + eviction_task: task, + } + } +} + +impl + 'static> Cache + for TestCache +{ + fn get(&self, key: &usize) -> Option { + self.cache.get(key).and_then(|entry| { + if entry.key == *key { + return Some(entry.value.clone()); + } + None + }) + } + + fn insert(&self, key: usize, value: NotATransaction) { + let size = value.get_size(); + self.cache.insert_with_size(key, value, size); + if self.cache.total_size() >= self.metadata.eviction_trigger_size_in_bytes { + self.eviction_start.store(key, Ordering::Relaxed); + self.insert_notify.notify_one(); + } + } + + fn total_size(&self) -> usize { + self.cache.total_size() + } +} + +/// Perform cache eviction on a separate task. +fn spawn_eviction_task + 'static>( + insert_notify: Arc, + highest_key: Arc, + metadata: Arc, + cache: Arc, +) -> JoinHandle<()> { + tokio::spawn(async move { + loop { + insert_notify.notified().await; + let watermark_value = highest_key.load(Ordering::Relaxed); + let mut eviction_index = (watermark_value + 1) % metadata.capacity; + + // Evict entries until the cache size is below the target size + while cache.total_size() > metadata.target_size_in_bytes { + if let Some(value) = cache.evict(&eviction_index) { + if value.key > watermark_value { + cache.insert_with_size(value.key, value.value.clone(), value.size_in_bytes); + break; + } + } + eviction_index = (eviction_index + 1) % metadata.capacity; + } + } + }) +} diff --git a/crates/aptos-in-memory-cache/tests/tests.rs b/crates/aptos-in-memory-cache/tests/tests.rs new file mode 100644 index 00000000000..428c543b3b1 --- /dev/null +++ b/crates/aptos-in-memory-cache/tests/tests.rs @@ -0,0 +1,226 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_in_memory_cache::Cache; +use common::{NotATransaction, TestCache}; +use std::time::Duration; + +pub mod common; + +#[cfg(test)] +mod tests { + use super::*; + use aptos_in_memory_cache::caches::SyncMutexCache; + + #[tokio::test(flavor = "multi_thread", worker_threads = 10)] + async fn test_insert_out_of_order() { + let c = SyncMutexCache::with_capacity(10); + let cache = TestCache::with_capacity(c, 150, 100); + let key = 100; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 101; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 105; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 103; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 102; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 104; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 10)] + async fn test_array_wrap_around() { + let c = SyncMutexCache::with_capacity(10); + let cache = TestCache::with_capacity(c, 150, 100); + let key = 7; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 8; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 12; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 10; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 9; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + + let key = 11; + let value = NotATransaction::new(key as i64); + cache.insert(key, value.clone()); + assert_eq!(cache.get(&key).clone(), Some(value)); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 10)] + async fn test_eviction_on_size_limit() { + let c = SyncMutexCache::with_capacity(10); + let cache = TestCache::with_capacity(c, 56, 48); + + // Insert initial items + for i in 0..6 { + let value = NotATransaction::new(i as i64); + cache.insert(i, value); + } + + assert_eq!( + cache.total_size(), + 6 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + tokio::time::sleep(Duration::from_micros(1)).await; + + // This insert should trigger eviction + let key = 6; + let value = NotATransaction::new(key as i64); + cache.insert(key, value); + + // Wait for eviction to occur + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 6 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + // Further inserts to ensure eviction continues correctly + for i in 7..10 { + let value = NotATransaction::new(i as i64); + cache.insert(i, value); + } + + // Wait for eviction to occur + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 6 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 10)] + async fn test_eviction_out_of_order_inserts() { + let c = SyncMutexCache::with_capacity(20); + let cache = TestCache::with_capacity(c, 88, 80); + + // Insert items out of order + let keys = [0, 5, 1, 3, 7, 2, 6, 4, 9, 8]; + for &key in &keys { + let value = NotATransaction::new(key as i64); + cache.insert(key, value); + } + + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 10 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + tokio::time::sleep(Duration::from_micros(1)).await; + + // This insert should trigger eviction + let key = 10; + let value = NotATransaction::new(key as i64); + cache.insert(key, value); + + // Wait for eviction to occur + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 10 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + tokio::time::sleep(Duration::from_micros(1)).await; + + // Further inserts to ensure eviction continues correctly + let key = 11; + let value = NotATransaction::new(key as i64); + cache.insert(key, value); + + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 10 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 10)] + async fn test_eviction_with_array_wrap_around() { + let c = SyncMutexCache::with_capacity(10); + let cache = TestCache::with_capacity(c, 48, 40); + + // Insert items to fill the cache + for i in 5..10 { + let value = NotATransaction::new(i as i64); + cache.insert(i, value); + } + + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 5 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + tokio::time::sleep(Duration::from_micros(1)).await; + + // Insert more items to cause wrap-around + for i in 10..12 { + let value = NotATransaction::new(i as i64); + cache.insert(i, value); + } + + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 5 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + + // Insert even more items to fully wrap-around + for i in 12..15 { + let value = NotATransaction::new(i as i64); + cache.insert(i, value); + } + + tokio::time::sleep(Duration::from_micros(1)).await; + + assert_eq!( + cache.total_size(), + 5 * std::mem::size_of_val(&NotATransaction::new(0)) + ); + } +} diff --git a/crates/aptos-inspection-service/src/server/identity_information.rs b/crates/aptos-inspection-service/src/server/identity_information.rs new file mode 100644 index 00000000000..2bd074b5db3 --- /dev/null +++ b/crates/aptos-inspection-service/src/server/identity_information.rs @@ -0,0 +1,52 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::server::utils::CONTENT_TYPE_TEXT; +use aptos_config::config::NodeConfig; +use hyper::{Body, StatusCode}; + +// The message to display when the identity information endpoint is disabled +pub const IDENTITY_INFO_DISABLED_MESSAGE: &str = + "This endpoint is disabled! Enable it in the node config at inspection_service.expose_identity_information: true"; + +/// Handles a new identity information request +pub fn handle_identity_information_request(node_config: &NodeConfig) -> (StatusCode, Body, String) { + // Only return identity information if the endpoint is enabled + let (status_code, body) = if node_config.inspection_service.expose_identity_information { + let identity_information = get_identity_information(node_config); + (StatusCode::OK, Body::from(identity_information)) + } else { + ( + StatusCode::FORBIDDEN, + Body::from(IDENTITY_INFO_DISABLED_MESSAGE), + ) + }; + + (status_code, body, CONTENT_TYPE_TEXT.into()) +} + +/// Returns a simple text formatted string with identity information +fn get_identity_information(node_config: &NodeConfig) -> String { + let mut identity_information = Vec::::new(); + identity_information.push("Identity Information:".into()); + + // If the validator network is configured, fetch the identity information + if let Some(validator_network) = &node_config.validator_network { + identity_information.push(format!( + "\t- Validator network ({}), peer ID: {}", + validator_network.network_id, + validator_network.peer_id() + )); + } + + // For each fullnode network, fetch the identity information + for fullnode_network in &node_config.full_node_networks { + identity_information.push(format!( + "\t- Fullnode network ({}), peer ID: {}", + fullnode_network.network_id, + fullnode_network.peer_id() + )); + } + + identity_information.join("\n") // Separate each entry with a newline to construct the output +} diff --git a/crates/aptos-inspection-service/src/server/index.rs b/crates/aptos-inspection-service/src/server/index.rs index d57f80bfde3..db88a54ea17 100644 --- a/crates/aptos-inspection-service/src/server/index.rs +++ b/crates/aptos-inspection-service/src/server/index.rs @@ -3,8 +3,8 @@ use crate::{ server::utils::CONTENT_TYPE_TEXT, CONFIGURATION_PATH, CONSENSUS_HEALTH_CHECK_PATH, - FORGE_METRICS_PATH, JSON_METRICS_PATH, METRICS_PATH, PEER_INFORMATION_PATH, - SYSTEM_INFORMATION_PATH, + FORGE_METRICS_PATH, IDENTITY_INFORMATION_PATH, JSON_METRICS_PATH, METRICS_PATH, + PEER_INFORMATION_PATH, SYSTEM_INFORMATION_PATH, }; use hyper::{Body, StatusCode}; @@ -28,6 +28,7 @@ fn get_index_response() -> String { index_response.push(format!("\t- {}", CONFIGURATION_PATH)); index_response.push(format!("\t- {}", CONSENSUS_HEALTH_CHECK_PATH)); index_response.push(format!("\t- {}", FORGE_METRICS_PATH)); + index_response.push(format!("\t- {}", IDENTITY_INFORMATION_PATH)); index_response.push(format!("\t- {}", JSON_METRICS_PATH)); index_response.push(format!("\t- {}", METRICS_PATH)); index_response.push(format!("\t- {}", PEER_INFORMATION_PATH)); diff --git a/crates/aptos-inspection-service/src/server/mod.rs b/crates/aptos-inspection-service/src/server/mod.rs index 5b442e3a351..fab098a23ea 100644 --- a/crates/aptos-inspection-service/src/server/mod.rs +++ b/crates/aptos-inspection-service/src/server/mod.rs @@ -18,6 +18,7 @@ use std::{ }; mod configuration; +mod identity_information; mod index; mod json_encoder; mod metrics; @@ -32,6 +33,7 @@ mod tests; pub const CONFIGURATION_PATH: &str = "/configuration"; pub const CONSENSUS_HEALTH_CHECK_PATH: &str = "/consensus_health_check"; pub const FORGE_METRICS_PATH: &str = "/forge_metrics"; +pub const IDENTITY_INFORMATION_PATH: &str = "/identity_information"; pub const INDEX_PATH: &str = "/"; pub const JSON_METRICS_PATH: &str = "/json_metrics"; pub const METRICS_PATH: &str = "/metrics"; @@ -122,6 +124,11 @@ async fn serve_requests( // Exposes forge encoded metrics metrics::handle_forge_metrics() }, + IDENTITY_INFORMATION_PATH => { + // /identity_information + // Exposes the identity information of the node + identity_information::handle_identity_information_request(&node_config) + }, INDEX_PATH => { // / // Exposes the index and list of available endpoints diff --git a/crates/aptos-inspection-service/src/server/tests.rs b/crates/aptos-inspection-service/src/server/tests.rs index 219201ec5f5..fdfeb7557f7 100644 --- a/crates/aptos-inspection-service/src/server/tests.rs +++ b/crates/aptos-inspection-service/src/server/tests.rs @@ -4,13 +4,14 @@ use crate::{ server::{ configuration::CONFIGURATION_DISABLED_MESSAGE, + identity_information::IDENTITY_INFO_DISABLED_MESSAGE, peer_information::PEER_INFO_DISABLED_MESSAGE, serve_requests, system_information::SYS_INFO_DISABLED_MESSAGE, utils::get_all_metrics, }, - CONFIGURATION_PATH, FORGE_METRICS_PATH, INDEX_PATH, JSON_METRICS_PATH, METRICS_PATH, - PEER_INFORMATION_PATH, SYSTEM_INFORMATION_PATH, + CONFIGURATION_PATH, FORGE_METRICS_PATH, IDENTITY_INFORMATION_PATH, INDEX_PATH, + JSON_METRICS_PATH, METRICS_PATH, PEER_INFORMATION_PATH, SYSTEM_INFORMATION_PATH, }; -use aptos_config::config::{AptosDataClientConfig, BaseConfig, NodeConfig}; +use aptos_config::config::{AptosDataClientConfig, BaseConfig, Identity, NodeConfig}; use aptos_data_client::client::AptosDataClient; use aptos_network::application::{interface::NetworkClient, storage::PeersAndMetadata}; use aptos_storage_interface::DbReader; @@ -87,6 +88,7 @@ async fn test_inspect_index() { assert_eq!(response.status(), StatusCode::OK); assert!(response_body_string.contains(CONFIGURATION_PATH)); assert!(response_body_string.contains(FORGE_METRICS_PATH)); + assert!(response_body_string.contains(IDENTITY_INFORMATION_PATH)); assert!(response_body_string.contains(JSON_METRICS_PATH)); assert!(response_body_string.contains(METRICS_PATH)); assert!(response_body_string.contains(PEER_INFORMATION_PATH)); @@ -109,6 +111,38 @@ async fn test_inspect_json_metrics() { assert!(response_body_string.contains(INT_COUNTER_NAME)); } +#[tokio::test] +async fn test_inspect_identity_information() { + // Create a validator config (with a single validator identity) + let mut config = NodeConfig::get_default_validator_config(); + if let Some(network_config) = config.validator_network.as_mut() { + network_config.identity = Identity::None; // Reset the identity + network_config + .set_listen_address_and_prepare_identity() + .unwrap(); // Generates a random identity + } + config.full_node_networks = vec![]; + + // Disable the identity information endpoint and ping it + config.inspection_service.expose_identity_information = false; + let mut response = send_get_request_to_path(&config, IDENTITY_INFORMATION_PATH).await; + let response_body = body::to_bytes(response.body_mut()).await.unwrap(); + + // Verify that the response contains an error + assert_eq!(response.status(), StatusCode::FORBIDDEN); + assert_eq!(response_body, IDENTITY_INFO_DISABLED_MESSAGE); + + // Enable the identity information endpoint and ping it + config.inspection_service.expose_identity_information = true; + let mut response = send_get_request_to_path(&config, IDENTITY_INFORMATION_PATH).await; + let response_body = body::to_bytes(response.body_mut()).await.unwrap(); + let response_body_string = read_to_string(response_body.as_ref()).unwrap(); + + // Verify that the response contains the expected information + assert_eq!(response.status(), StatusCode::OK); + assert!(response_body_string.contains("Identity Information:")); +} + #[tokio::test] async fn test_inspect_metrics() { // Create a validator config diff --git a/crates/aptos-keygen/src/lib.rs b/crates/aptos-keygen/src/lib.rs index d176b461c62..39cf0fde664 100644 --- a/crates/aptos-keygen/src/lib.rs +++ b/crates/aptos-keygen/src/lib.rs @@ -26,7 +26,7 @@ impl KeyGen { /// The random seed itself is generated using the OS rng. pub fn from_os_rng() -> Self { let mut seed_rng = OsRng; - let seed: [u8; 32] = seed_rng.gen(); + let seed: [u8; 32] = seed_rng.r#gen(); Self::from_seed(seed) } diff --git a/crates/aptos-logger/src/aptos_logger.rs b/crates/aptos-logger/src/aptos_logger.rs index 763c605fc16..2176e32be06 100644 --- a/crates/aptos-logger/src/aptos_logger.rs +++ b/crates/aptos-logger/src/aptos_logger.rs @@ -824,6 +824,8 @@ impl LoggerFilterUpdater { #[cfg(test)] mod tests { + #![allow(unsafe_code)] + use super::{text_format, AptosData, LogEntry}; use crate::{ aptos_logger::{json_format, TruncatedLogString, RUST_LOG_TELEMETRY}, @@ -1151,7 +1153,10 @@ mod tests { .telemetry_filter .enabled(debug_metadata)); - std::env::set_var(RUST_LOG_TELEMETRY, "debug"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + std::env::set_var(RUST_LOG_TELEMETRY, "debug"); + } let updater = LoggerFilterUpdater::new(logger.clone(), logger_builder); updater.update_filter(); @@ -1162,7 +1167,10 @@ mod tests { .telemetry_filter .enabled(debug_metadata)); - std::env::set_var(RUST_LOG_TELEMETRY, "debug;hyper=off"); // log values should be separated by commas not semicolons. + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + std::env::set_var(RUST_LOG_TELEMETRY, "debug;hyper=off"); // log values should be separated by commas not semicolons. + } updater.update_filter(); assert!(!logger @@ -1171,7 +1179,10 @@ mod tests { .telemetry_filter .enabled(debug_metadata)); - std::env::set_var(RUST_LOG_TELEMETRY, "debug,hyper=off"); // log values should be separated by commas not semicolons. + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + std::env::set_var(RUST_LOG_TELEMETRY, "debug,hyper=off"); // log values should be separated by commas not semicolons. + } updater.update_filter(); assert!(logger diff --git a/crates/aptos-logger/src/kv.rs b/crates/aptos-logger/src/kv.rs index a5f795e38be..940766314d0 100644 --- a/crates/aptos-logger/src/kv.rs +++ b/crates/aptos-logger/src/kv.rs @@ -36,9 +36,9 @@ impl Key { /// The value part of a logging key value pair e.g. `info!(key = value)` #[derive(Clone, Copy)] pub enum Value<'v> { - Debug(&'v (dyn fmt::Debug)), - Display(&'v (dyn fmt::Display)), - Serde(&'v (dyn erased_serde::Serialize)), + Debug(&'v dyn fmt::Debug), + Display(&'v dyn fmt::Display), + Serde(&'v dyn erased_serde::Serialize), } impl fmt::Debug for Value<'_> { diff --git a/crates/aptos-logger/src/lib.rs b/crates/aptos-logger/src/lib.rs index 26a5d0ad15e..4fde799de33 100644 --- a/crates/aptos-logger/src/lib.rs +++ b/crates/aptos-logger/src/lib.rs @@ -132,7 +132,7 @@ //! Logger::builder().level(Level::Info).build(); //! ``` -#![forbid(unsafe_code)] +#![deny(unsafe_code)] pub mod prelude { pub use crate::{ diff --git a/crates/aptos-logger/tests/derive.rs b/crates/aptos-logger/tests/derive.rs index 9df55c0dae8..18b9c2d73b3 100644 --- a/crates/aptos-logger/tests/derive.rs +++ b/crates/aptos-logger/tests/derive.rs @@ -82,7 +82,7 @@ fn error_trait_object() { impl ::std::error::Error for OurError {} - let debug_error = ::std::io::Error::new(::std::io::ErrorKind::Other, "This is an error"); + let debug_error = ::std::io::Error::other("This is an error"); let display_error = OurError; let t = Test::default() .debug_error(&debug_error) diff --git a/crates/aptos-metrics-core/Cargo.toml b/crates/aptos-metrics-core/Cargo.toml index 4da97292b0a..d5f033d501b 100644 --- a/crates/aptos-metrics-core/Cargo.toml +++ b/crates/aptos-metrics-core/Cargo.toml @@ -14,6 +14,8 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } +once_cell = { workspace = true } +paste = { workspace = true } prometheus = { workspace = true, features = ["protobuf"] } [dev-dependencies] diff --git a/crates/aptos-metrics-core/src/lib.rs b/crates/aptos-metrics-core/src/lib.rs index 5d207a8b1dd..bc8f20e2ee4 100644 --- a/crates/aptos-metrics-core/src/lib.rs +++ b/crates/aptos-metrics-core/src/lib.rs @@ -2,6 +2,10 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 +pub use crate::{ + avg_counter::{register_avg_counter, register_avg_counter_vec}, + thread_local::{ThreadLocalHistogramVec, ThreadLocalIntCounter, ThreadLocalIntCounterVec}, +}; // Re-export counter types from prometheus crate pub use prometheus::{ exponential_buckets, gather, histogram_opts, register_counter, register_gauge, @@ -12,23 +16,29 @@ pub use prometheus::{ }; mod avg_counter; -pub use avg_counter::{register_avg_counter, register_avg_counter_vec}; pub mod const_metric; pub mod op_counters; +pub mod thread_local; pub trait TimerHelper { - fn timer_with(&self, labels: &[&str]) -> HistogramTimer; + type TimerType<'a> + where + Self: 'a; + + fn timer_with<'a>(&'static self, labels: &'a [&str]) -> Self::TimerType<'a>; - fn observe_with(&self, labels: &[&str], val: f64); + fn observe_with(&'static self, labels: &[&str], val: f64); } impl TimerHelper for HistogramVec { - fn timer_with(&self, vals: &[&str]) -> HistogramTimer { - self.with_label_values(vals).start_timer() + type TimerType<'a> = HistogramTimer; + + fn timer_with<'a>(&'static self, labels: &'a [&str]) -> Self::TimerType<'a> { + self.with_label_values(labels).start_timer() } - fn observe_with(&self, labels: &[&str], val: f64) { - self.with_label_values(labels).observe(val) + fn observe_with(&'static self, labels: &[&str], val: f64) { + self.with_label_values(labels).observe(val); } } @@ -49,13 +59,13 @@ impl Drop for ConcurrencyGauge { } } -pub trait IntGaugeHelper { +pub trait IntGaugeVecHelper { fn set_with(&self, labels: &[&str], val: i64); fn concurrency_with(&self, labels: &[&str]) -> ConcurrencyGauge; } -impl IntGaugeHelper for IntGaugeVec { +impl IntGaugeVecHelper for IntGaugeVec { fn set_with(&self, labels: &[&str], val: i64) { self.with_label_values(labels).set(val) } @@ -65,22 +75,30 @@ impl IntGaugeHelper for IntGaugeVec { } } -pub trait IntCounterHelper { +pub trait IntCounterVecHelper { type IntType; - fn inc_with(&self, labels: &[&str]); + fn inc_with(&'static self, labels: &[&str]); - fn inc_with_by(&self, labels: &[&str], by: Self::IntType); + fn inc_with_by(&'static self, labels: &[&str], by: Self::IntType); } -impl IntCounterHelper for IntCounterVec { +impl IntCounterVecHelper for IntCounterVec { type IntType = u64; - fn inc_with(&self, labels: &[&str]) { + fn inc_with(&'static self, labels: &[&str]) { self.with_label_values(labels).inc() } - fn inc_with_by(&self, labels: &[&str], v: Self::IntType) { + fn inc_with_by(&'static self, labels: &[&str], v: Self::IntType) { self.with_label_values(labels).inc_by(v) } } + +pub trait IntCounterHelper { + type IntType; + + fn inc(&'static self); + + fn inc_by(&'static self, v: Self::IntType); +} diff --git a/crates/aptos-metrics-core/src/thread_local.rs b/crates/aptos-metrics-core/src/thread_local.rs new file mode 100644 index 00000000000..c8dc84292c7 --- /dev/null +++ b/crates/aptos-metrics-core/src/thread_local.rs @@ -0,0 +1,285 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod __private { + pub use once_cell::sync::Lazy; + pub use paste::paste; +} + +use crate::{IntCounterHelper, IntCounterVecHelper, TimerHelper}; +use std::{ + cell::RefCell, + thread::LocalKey, + time::{Duration, Instant}, +}; + +const FLUSH_INTERVAL: Duration = Duration::from_secs(1); + +pub struct ThreadLocalIntCounter { + inner: prometheus::local::LocalIntCounter, + last_flush: Instant, +} + +impl ThreadLocalIntCounter { + pub fn new(shared: &prometheus::IntCounter) -> Self { + Self { + inner: shared.local(), + last_flush: Instant::now(), + } + } + + fn maybe_flush(&mut self) { + let now = Instant::now(); + if now.duration_since(self.last_flush) > FLUSH_INTERVAL { + self.inner.flush(); + } + self.last_flush = now; + } +} + +impl IntCounterHelper for LocalKey> { + type IntType = u64; + + fn inc(&'static self) { + self.inc_by(1); + } + + fn inc_by(&'static self, v: Self::IntType) { + self.with_borrow_mut(|x| { + x.inner.inc_by(v); + x.maybe_flush(); + }) + } +} + +pub struct ThreadLocalIntCounterVec { + inner: prometheus::local::LocalIntCounterVec, + last_flush: Instant, +} + +impl ThreadLocalIntCounterVec { + pub fn new(shared: &prometheus::IntCounterVec) -> Self { + Self { + inner: shared.local(), + last_flush: Instant::now(), + } + } + + fn maybe_flush(&mut self) { + let now = Instant::now(); + if now.duration_since(self.last_flush) > FLUSH_INTERVAL { + self.inner.flush(); + } + self.last_flush = now; + } +} + +impl IntCounterVecHelper for LocalKey> { + type IntType = u64; + + fn inc_with(&'static self, labels: &[&str]) { + self.inc_with_by(labels, 1); + } + + fn inc_with_by(&'static self, labels: &[&str], v: Self::IntType) { + self.with_borrow_mut(|x| { + x.inner.with_label_values(labels).inc_by(v); + x.maybe_flush(); + }); + } +} + +pub struct ThreadLocalHistogramTimer<'a> { + start: Instant, + labels: &'a [&'a str], + parent: &'static LocalKey>, +} + +impl<'a> ThreadLocalHistogramTimer<'a> { + fn new( + labels: &'a [&'a str], + parent: &'static LocalKey>, + ) -> Self { + Self { + start: Instant::now(), + labels, + parent, + } + } +} + +impl Drop for ThreadLocalHistogramTimer<'_> { + fn drop(&mut self) { + self.parent + .observe_with(self.labels, self.start.elapsed().as_secs_f64()); + } +} + +pub struct ThreadLocalHistogramVec { + inner: prometheus::local::LocalHistogramVec, + last_flush: Instant, +} + +impl ThreadLocalHistogramVec { + pub fn new(shared: &prometheus::HistogramVec) -> Self { + Self { + inner: shared.local(), + last_flush: Instant::now(), + } + } + + fn maybe_flush(&mut self) { + let now = Instant::now(); + if now.duration_since(self.last_flush) > FLUSH_INTERVAL { + self.inner.flush(); + } + self.last_flush = now; + } +} + +impl TimerHelper for LocalKey> { + type TimerType<'a> = ThreadLocalHistogramTimer<'a>; + + fn timer_with<'a>(&'static self, labels: &'a [&str]) -> Self::TimerType<'a> { + // We could use `self.with_borrow_mut(|x| x.inner.with_label_values(labels).start_timer())`. + // However, this creates a `LocalHistogramTimer`, which internally stores a copy of + // `LocalHistogram`: + // https://github.com/tikv/rust-prometheus/blob/1d3174bf5ddf056dcb0fe59e06cad4ef42ebec68/src/histogram.rs#L1077-L1080. + // When the timer is dropped, the copied `LocalHistogram` is also dropped, and this always + // causes a flush: + // https://github.com/tikv/rust-prometheus/blob/1d3174bf5ddf056dcb0fe59e06cad4ef42ebec68/src/histogram.rs#L1142-L1146 + ThreadLocalHistogramTimer::new(labels, self) + } + + fn observe_with(&'static self, labels: &[&str], val: f64) { + self.with_borrow_mut(|x| { + x.inner.with_label_values(labels).observe(val); + x.maybe_flush(); + }); + } +} + +#[macro_export] +macro_rules! make_thread_local_int_counter { + ( + $(#[$attr:meta])* + $vis:vis, + $var_name:ident, + $name:expr, + $help:expr $(,)? + ) => { + $crate::thread_local::__private::paste! { + static [<__ $var_name>]: $crate::thread_local::__private::Lazy<$crate::IntCounter> = + $crate::thread_local::__private::Lazy::new(|| { + $crate::register_int_counter!($name, $help) + .expect("register_int_counter should succeed") + }); + ::std::thread_local! { + $(#[$attr])* + $vis static $var_name: ::std::cell::RefCell<$crate::thread_local::ThreadLocalIntCounter> = + ::std::cell::RefCell::new( + $crate::thread_local::ThreadLocalIntCounter::new(&[<__ $var_name>]), + ); + } + } + } +} + +#[macro_export] +macro_rules! make_thread_local_int_counter_vec { + ( + $(#[$attr:meta])* + $vis:vis, + $var_name:ident, + $name:expr, + $help:expr, + $labels_names:expr $(,)? + ) => { + $crate::thread_local::__private::paste! { + static [<__ $var_name>]: $crate::thread_local::__private::Lazy<$crate::IntCounterVec> = + $crate::thread_local::__private::Lazy::new(|| { + $crate::register_int_counter_vec!($name, $help, $labels_names) + .expect("register_int_counter_vec should succeed") + }); + ::std::thread_local! { + $(#[$attr])* + $vis static $var_name: ::std::cell::RefCell<$crate::thread_local::ThreadLocalIntCounterVec> = + ::std::cell::RefCell::new( + $crate::thread_local::ThreadLocalIntCounterVec::new(&[<__ $var_name>]), + ); + } + } + } +} + +#[macro_export] +macro_rules! make_thread_local_histogram_vec { + ( + $(#[$attr:meta])* + $vis:vis, + $var_name:ident, + $name:expr, + $help:expr, + $labels_names:expr + $(, $buckets:expr)? $(,)? + ) => { + $crate::thread_local::__private::paste! { + static [<__ $var_name>]: $crate::thread_local::__private::Lazy<$crate::HistogramVec> = + $crate::thread_local::__private::Lazy::new(|| { + $crate::register_histogram_vec!($name, $help, $labels_names $(, $buckets)?) + .expect("register_histogram_vec should succeed") + }); + ::std::thread_local! { + $(#[$attr])* + $vis static $var_name: ::std::cell::RefCell<$crate::thread_local::ThreadLocalHistogramVec> = + ::std::cell::RefCell::new( + $crate::thread_local::ThreadLocalHistogramVec::new(&[<__ $var_name>]), + ); + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::{IntCounterHelper, IntCounterVecHelper, TimerHelper}; + + make_thread_local_int_counter!( + pub(self), + TEST_INT_COUNTER, + "aptos_test_int_counter", + "this is a help message", + ); + make_thread_local_int_counter_vec!( + pub(self), + TEST_INT_COUNTER_VEC, + "aptos_test_int_counter_vec", + "this is a help message", + &["label"], + ); + make_thread_local_histogram_vec!( + pub(self), + TEST_HISTOGRAM_VEC, + "aptos_test_histogram_vec", + "this is a help message", + &["label"], + ); + + #[test] + fn test_thread_local_int_counter() { + TEST_INT_COUNTER.inc(); + TEST_INT_COUNTER.inc_by(2); + } + + #[test] + fn test_thread_local_int_counter_vec() { + TEST_INT_COUNTER_VEC.inc_with(&["foo"]); + TEST_INT_COUNTER_VEC.inc_with_by(&["foo"], 2); + } + + #[test] + fn test_thread_local_histogram_vec() { + let _timer = TEST_HISTOGRAM_VEC.timer_with(&["foo"]); + TEST_HISTOGRAM_VEC.observe_with(&["bar"], 1.0); + } +} diff --git a/crates/aptos-openapi/src/helpers.rs b/crates/aptos-openapi/src/helpers.rs index 31538778b33..44dc57632fe 100644 --- a/crates/aptos-openapi/src/helpers.rs +++ b/crates/aptos-openapi/src/helpers.rs @@ -171,12 +171,14 @@ macro_rules! impl_poem_parameter { }; } +#[cfg(test)] mod test { #[allow(unused_imports)] use poem_openapi::types::ParseFromParameter; use serde::{Deserialize, Serialize}; use std::str::FromStr; + #[allow(dead_code)] #[derive(Debug, Deserialize, Serialize)] struct This { value: String, @@ -193,13 +195,12 @@ mod test { } } + impl_poem_type!(This, "string", ()); + impl_poem_type!(That, "string", ()); + impl_poem_parameter!(That); + #[test] fn test() { - impl_poem_type!(This, "string", ()); - - impl_poem_type!(That, "string", ()); - impl_poem_parameter!(That); - assert_eq!( That::parse_from_parameter("0x1::coin::CoinStore::%3C0x1::aptos_coin::AptosCoin%3E") .unwrap() diff --git a/crates/aptos-profiler/Cargo.toml b/crates/aptos-profiler/Cargo.toml index 653ca7e7741..e22ab13a444 100644 --- a/crates/aptos-profiler/Cargo.toml +++ b/crates/aptos-profiler/Cargo.toml @@ -16,11 +16,5 @@ anyhow = { workspace = true } regex = { workspace = true } [target.'cfg(unix)'.dependencies] +jemalloc-sys = { workspace = true } pprof = { workspace = true } -backtrace = { workspace = true } -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } -jemalloc-sys = "0.5.4" - diff --git a/crates/aptos-profiler/src/cpu_profiler.rs b/crates/aptos-profiler/src/cpu_profiler.rs index 4f3ef50aaf2..51552375d4a 100644 --- a/crates/aptos-profiler/src/cpu_profiler.rs +++ b/crates/aptos-profiler/src/cpu_profiler.rs @@ -46,7 +46,7 @@ impl<'a> CpuProfiler<'a> { } } -impl Profiler for CpuProfiler<'_> { +impl Profiler for CpuProfiler<'static> { /// Perform CPU profiling for the given duration fn profile_for(&self, duration_secs: u64, _binary_path: &str) -> Result<()> { let guard = pprof::ProfilerGuard::new(self.frequency).unwrap(); @@ -90,7 +90,6 @@ impl Profiler for CpuProfiler<'_> { /// Expose the results as SVG fn expose_svg_results(&self) -> Result { - let content = convert_svg_to_string(self.svg_result_path.as_path()); - content + convert_svg_to_string(self.svg_result_path.as_path()) } } diff --git a/crates/aptos-profiler/src/memory_profiler.rs b/crates/aptos-profiler/src/memory_profiler.rs index 111cb895486..4069328c0dc 100644 --- a/crates/aptos-profiler/src/memory_profiler.rs +++ b/crates/aptos-profiler/src/memory_profiler.rs @@ -140,13 +140,11 @@ impl Profiler for MemProfiler { /// Expose the results in TXT format fn expose_text_results(&self) -> Result { - let content = convert_svg_to_string(self.txt_result_path.as_path()); - content + convert_svg_to_string(self.txt_result_path.as_path()) } /// Expose the results in SVG format fn expose_svg_results(&self) -> Result { - let content = convert_svg_to_string(self.svg_result_path.as_path()); - content + convert_svg_to_string(self.svg_result_path.as_path()) } } diff --git a/crates/aptos-rest-client/src/lib.rs b/crates/aptos-rest-client/src/lib.rs index cf200b2849a..2e4310c2a2c 100644 --- a/crates/aptos-rest-client/src/lib.rs +++ b/crates/aptos-rest-client/src/lib.rs @@ -22,11 +22,10 @@ pub use aptos_api_types::{ self, IndexResponseBcs, MoveModuleBytecode, PendingTransaction, Transaction, }; use aptos_api_types::{ - deserialize_from_string, mime_types::{BCS, BCS_SIGNED_TRANSACTION, BCS_VIEW_FUNCTION, JSON}, - AptosError, AptosErrorCode, BcsBlock, Block, GasEstimation, HexEncodedBytes, IndexResponse, - MoveModuleId, TransactionData, TransactionOnChainData, TransactionsBatchSubmissionResult, - UserTransaction, VersionedEvent, ViewFunction, ViewRequest, + AptosError, AptosErrorCode, BcsBlock, Block, GasEstimation, IndexResponse, MoveModuleId, + TransactionData, TransactionOnChainData, TransactionsBatchSubmissionResult, UserTransaction, + VersionedEvent, ViewFunction, ViewRequest, }; use aptos_crypto::HashValue; use aptos_logger::{debug, info, sample, sample::SampleRate}; @@ -37,7 +36,8 @@ use aptos_types::{ keyless::{Groth16Proof, Pepper, ZeroKnowledgeSig, ZKP}, state_store::state_key::StateKey, transaction::{ - authenticator::EphemeralSignature, IndexedTransactionSummary, SignedTransaction, + authenticator::EphemeralSignature, IndexedTransactionSummary, PersistedAuxiliaryInfo, + SignedTransaction, Version, }, }; use move_core_types::{ @@ -1009,6 +1009,21 @@ impl Client { Ok(response.and_then(|inner| bcs::from_bytes(&inner))?) } + pub async fn get_persisted_auxiliary_infos( + &self, + start: Version, + limit: u64, + ) -> AptosResult> { + let mut url = self.build_path("transactions/auxiliary_info")?; + url.set_query(Some(&format!("start_version={}&limit={}", start, limit))); + + let response = self.inner.get(url).header(ACCEPT, BCS).send().await?; + let response = self.check_and_parse_bcs_response(response).await?; + Ok(response + .and_then(|inner| bcs::from_bytes(&inner))? + .into_inner()) + } + pub async fn get_transaction_by_hash( &self, hash: HashValue, @@ -1414,23 +1429,6 @@ impl Client { start: Option, limit: Option, ) -> Result>> { - #[derive(Clone, Debug, Serialize, Deserialize)] - pub struct NewBlockEventResponse { - hash: String, - #[serde(deserialize_with = "deserialize_from_string")] - epoch: u64, - #[serde(deserialize_with = "deserialize_from_string")] - round: u64, - #[serde(deserialize_with = "deserialize_from_string")] - height: u64, - #[serde(deserialize_with = "deserialize_from_prefixed_hex_string")] - previous_block_votes_bitvec: HexEncodedBytes, - proposer: String, - failed_proposer_indices: Vec, - #[serde(deserialize_with = "deserialize_from_string")] - time_microseconds: u64, - } - let response = self .get_account_events_bcs( CORE_CODE_ADDRESS, diff --git a/crates/aptos-speculative-state-helper/src/lib.rs b/crates/aptos-speculative-state-helper/src/lib.rs index b25fcaaec1e..cae564e5424 100644 --- a/crates/aptos-speculative-state-helper/src/lib.rs +++ b/crates/aptos-speculative-state-helper/src/lib.rs @@ -101,6 +101,7 @@ impl SpeculativeEvents { /// Flush the first num_to_flush stored events asynchronously by spawning global rayon threads. pub fn flush(mut self, num_to_flush: usize) { + let num_to_flush = num_to_flush.min(self.events.len()); let to_flush = self.events.drain(..num_to_flush).collect::>(); rayon::spawn(move || { to_flush diff --git a/crates/aptos-speculative-state-helper/src/tests/proptests.rs b/crates/aptos-speculative-state-helper/src/tests/proptests.rs index f0d7aa2b3f9..fde1f5ee54d 100644 --- a/crates/aptos-speculative-state-helper/src/tests/proptests.rs +++ b/crates/aptos-speculative-state-helper/src/tests/proptests.rs @@ -76,7 +76,7 @@ fn prepare_work( // Pre-process indices and deltas and put them into worker tasks. let mut worker_tasks: Vec> = (0..4).map(|_| Vec::with_capacity(200)).collect(); - for (i, (mut idx, mut delta)) in counter_ops.iter().enumerate() { + for (i, &(mut idx, mut delta)) in counter_ops.iter().enumerate() { // Group based on modulo (num_counters + 1). Last group is for testing out of bounds. let modulo = idx % (num_counters + 1); if modulo != num_counters { @@ -134,7 +134,7 @@ fn test_counter(counter_ops: Vec<(usize, usize)>, test_total: bool) { let idx_gen = AtomicUsize::new(0); let clear_barriers: Vec>> = (0..num_counters) - .map(|_| (CachePadded::new(RwLock::new(0)))) + .map(|_| CachePadded::new(RwLock::new(0))) .collect(); rayon::scope(|s| { for _ in 0..num_workers { @@ -202,7 +202,7 @@ fn test_events(counter_ops: Vec<(usize, usize)>) { let idx_gen = AtomicUsize::new(0); let worker_done_cnt = AtomicUsize::new(0); let clear_barriers: Vec>> = (0..num_counters) - .map(|_| (CachePadded::new(RwLock::new(0)))) + .map(|_| CachePadded::new(RwLock::new(0))) .collect(); // This is the number of events we expect to be dispatched at the end. let recorded_final_event_cnt = AtomicUsize::new(0); diff --git a/crates/aptos-telemetry-service/src/constants.rs b/crates/aptos-telemetry-service/src/constants.rs index eff0370e773..db0459e16d1 100644 --- a/crates/aptos-telemetry-service/src/constants.rs +++ b/crates/aptos-telemetry-service/src/constants.rs @@ -17,3 +17,5 @@ pub const GCP_SERVICE_PROJECT_ID_ENV: &str = "GCP_METADATA_PROJECT_ID"; /// Environment variable with the container identifier for this cloud run revision /// This variable must be set by calling the metadata server pub const GCP_CLOUD_RUN_INSTANCE_ID_ENV: &str = "GCP_CLOUD_RUN_INSTANCE_ID"; +/// The IP address key +pub const IP_ADDRESS_KEY: &str = "IP_ADDRESS"; diff --git a/crates/aptos-telemetry-service/src/custom_event.rs b/crates/aptos-telemetry-service/src/custom_event.rs index e4ffba5f797..d198ce01475 100644 --- a/crates/aptos-telemetry-service/src/custom_event.rs +++ b/crates/aptos-telemetry-service/src/custom_event.rs @@ -3,6 +3,7 @@ use crate::{ auth::with_auth, + constants::IP_ADDRESS_KEY, context::Context, debug, error, errors::{CustomEventIngestError, ServiceError}, @@ -34,6 +35,7 @@ pub fn custom_event_ingest(context: Context) -> BoxedFilter<(impl Reply,)> { NodeType::UnknownFullNode, ])) .and(warp::body::json()) + .and(warp::header::optional("X-Forwarded-For")) .and_then(handle_custom_event) .boxed() } @@ -65,13 +67,23 @@ fn validate_custom_event_body( pub(crate) async fn handle_custom_event( context: Context, claims: Claims, - body: TelemetryDump, + mut body: TelemetryDump, + forwarded_for: Option, ) -> anyhow::Result { validate_custom_event_body(&claims, &body)?; let mut insert_request = TableDataInsertAllRequest::new(); - let telemetry_event = &body.events[0]; + let client_ip = forwarded_for + .as_ref() + .and_then(|xff| xff.split(',').next()) + .unwrap_or("UNKNOWN"); + + let telemetry_event = &mut body.events[0]; + telemetry_event + .params + .insert(IP_ADDRESS_KEY.into(), client_ip.into()); + let event_params: Vec = telemetry_event .params .iter() diff --git a/crates/aptos-telemetry/Cargo.toml b/crates/aptos-telemetry/Cargo.toml index 586f86c44c1..9e975a6ceb5 100644 --- a/crates/aptos-telemetry/Cargo.toml +++ b/crates/aptos-telemetry/Cargo.toml @@ -38,7 +38,6 @@ rand_core = { workspace = true } reqwest = { workspace = true } reqwest-middleware = { workspace = true } reqwest-retry = { workspace = true } -serde = { workspace = true } serde_json = { workspace = true } sysinfo = { workspace = true } tokio = { workspace = true } diff --git a/crates/aptos-telemetry/src/cli_metrics.rs b/crates/aptos-telemetry/src/cli_metrics.rs index 45314916428..af3f9d04416 100644 --- a/crates/aptos-telemetry/src/cli_metrics.rs +++ b/crates/aptos-telemetry/src/cli_metrics.rs @@ -37,9 +37,13 @@ pub async fn send_cli_telemetry_event( // Send the event (we block on the join handle to ensure the // event is processed before terminating the cli command). - let join_handle = - service::send_telemetry_event_with_ip(user_id, "NO_CHAIN".into(), None, telemetry_event) - .await; + let join_handle = service::prepare_and_send_telemetry_event( + user_id, + "NO_CHAIN".into(), + None, + telemetry_event, + ) + .await; if let Err(error) = join_handle.await { debug!( "Failed to send telemetry event with join error: {:?}", diff --git a/crates/aptos-telemetry/src/constants.rs b/crates/aptos-telemetry/src/constants.rs index abadb85d847..46994fd05a3 100644 --- a/crates/aptos-telemetry/src/constants.rs +++ b/crates/aptos-telemetry/src/constants.rs @@ -28,7 +28,6 @@ pub(crate) const APTOS_GA_API_SECRET: &str = "ArtslKPTTjeiMi1n-IR39g"; // Note: the measurement protocol requires HTTPS. // See: https://developers.google.com/analytics/devguides/collection/protocol/v1/reference#transport pub(crate) const GA4_URL: &str = "https://www.google-analytics.com/mp/collect"; -pub(crate) const HTTPBIN_URL: &str = "https://httpbin.org/ip"; pub(crate) const TELEMETRY_SERVICE_URL: &str = "https://telemetry.aptoslabs.com"; pub(crate) const MAINNET_TELEMETRY_SERVICE_URL: &str = "https://telemetry.mainnet.aptoslabs.com"; diff --git a/crates/aptos-telemetry/src/lib.rs b/crates/aptos-telemetry/src/lib.rs index 37c6e69295b..25f09d1bffd 100644 --- a/crates/aptos-telemetry/src/lib.rs +++ b/crates/aptos-telemetry/src/lib.rs @@ -1,8 +1,6 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -#![forbid(unsafe_code)] - mod constants; mod core_metrics; mod metrics; diff --git a/crates/aptos-telemetry/src/service.rs b/crates/aptos-telemetry/src/service.rs index ff0803de376..5bd7ccc9d0b 100644 --- a/crates/aptos-telemetry/src/service.rs +++ b/crates/aptos-telemetry/src/service.rs @@ -1,8 +1,6 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -#![forbid(unsafe_code)] - use crate::{ constants::*, core_metrics::create_core_metric_telemetry_event, metrics, network_metrics::create_network_metric_telemetry_event, sender::TelemetrySender, @@ -21,7 +19,6 @@ use once_cell::sync::Lazy; use rand::Rng; use rand_core::OsRng; use reqwest::Url; -use serde::Deserialize; use std::{ collections::BTreeMap, env, @@ -33,8 +30,6 @@ use uuid::Uuid; // The chain ID key const CHAIN_ID_KEY: &str = "CHAIN_ID"; -// The IP address key -const IP_ADDRESS_KEY: &str = "IP_ADDRESS"; // The telemetry token key const TELEMETRY_TOKEN_KEY: &str = "TELEMETRY_TOKEN"; // The default for unknown metric values @@ -47,52 +42,70 @@ const APTOS_NODE_CONFIG_EVENT_NAME: &str = "APTOS_NODE_CONFIG"; /// TODO(joshlind): leverage real authentication! static TELEMETRY_TOKEN: Lazy = Lazy::new(|| { let mut rng = OsRng; - let token = rng.gen::(); + let token = rng.r#gen::(); format!("TOKEN_{:?}", token) }); +/// Returns true iff the given environment variable is set to true. Note: true +/// values are "true", "t", "1", "yes" or "y" (all case-insensitive). Any other +/// values are considered false (including when the variable is not set). +#[inline] +fn is_env_variable_true(env_variable: &str) -> bool { + match env::var(env_variable) { + Ok(value) => { + matches!( + value.to_lowercase().as_str(), + "true" | "t" | "1" | "yes" | "y" + ) + }, + Err(_) => false, + } +} + /// Returns true iff telemetry is disabled #[inline] pub fn telemetry_is_disabled() -> bool { - env::var(ENV_APTOS_DISABLE_TELEMETRY).is_ok() + is_env_variable_true(ENV_APTOS_DISABLE_TELEMETRY) } /// Flag to force enabling/disabling of telemetry #[inline] fn force_enable_telemetry() -> bool { - env::var(ENV_APTOS_FORCE_ENABLE_TELEMETRY).is_ok() + is_env_variable_true(ENV_APTOS_FORCE_ENABLE_TELEMETRY) } /// Flag to control enabling/disabling prometheus push metrics #[inline] fn enable_prometheus_push_metrics() -> bool { force_enable_telemetry() - || !(telemetry_is_disabled() || env::var(ENV_APTOS_DISABLE_TELEMETRY_PUSH_METRICS).is_ok()) + || !(telemetry_is_disabled() + || is_env_variable_true(ENV_APTOS_DISABLE_TELEMETRY_PUSH_METRICS)) } #[inline] fn enable_prometheus_node_metrics() -> bool { - env::var(ENV_APTOS_DISABLE_PROMETHEUS_NODE_METRICS).is_err() + !is_env_variable_true(ENV_APTOS_DISABLE_PROMETHEUS_NODE_METRICS) } /// Flag to control enabling/disabling push logs #[inline] fn enable_push_logs() -> bool { force_enable_telemetry() - || !(telemetry_is_disabled() || env::var(ENV_APTOS_DISABLE_TELEMETRY_PUSH_LOGS).is_ok()) + || !(telemetry_is_disabled() || is_env_variable_true(ENV_APTOS_DISABLE_TELEMETRY_PUSH_LOGS)) } /// Flag to control enabling/disabling telemetry push events #[inline] fn enable_push_custom_events() -> bool { force_enable_telemetry() - || !(telemetry_is_disabled() || env::var(ENV_APTOS_DISABLE_TELEMETRY_PUSH_EVENTS).is_ok()) + || !(telemetry_is_disabled() + || is_env_variable_true(ENV_APTOS_DISABLE_TELEMETRY_PUSH_EVENTS)) } #[inline] fn enable_log_env_polling() -> bool { force_enable_telemetry() - || !(telemetry_is_disabled() || env::var(ENV_APTOS_DISABLE_LOG_ENV_POLLING).is_ok()) + || !(telemetry_is_disabled() || is_env_variable_true(ENV_APTOS_DISABLE_LOG_ENV_POLLING)) } /// Starts the telemetry service and returns the execution runtime. @@ -210,11 +223,14 @@ fn try_spawn_log_env_poll_task(sender: TelemetrySender) { env::var(RUST_LOG_TELEMETRY).ok(), env ); - env::set_var(RUST_LOG_TELEMETRY, env) + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::set_var(RUST_LOG_TELEMETRY, env) } } else if let Some(ref value) = original_value { - env::set_var(RUST_LOG_TELEMETRY, value) + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::set_var(RUST_LOG_TELEMETRY, value) } } else { - env::remove_var(RUST_LOG_TELEMETRY) + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::remove_var(RUST_LOG_TELEMETRY) } } } }); @@ -349,7 +365,7 @@ async fn send_build_information( telemetry_sender: Option, ) { let telemetry_event = create_build_info_telemetry_event(build_info).await; - send_telemetry_event_with_ip(peer_id, chain_id, telemetry_sender, telemetry_event).await; + prepare_and_send_telemetry_event(peer_id, chain_id, telemetry_sender, telemetry_event).await; } /// Collects and sends the core node metrics via telemetry @@ -376,7 +392,7 @@ async fn send_node_config( name: APTOS_NODE_CONFIG_EVENT_NAME.into(), params: node_config, }; - send_telemetry_event_with_ip(peer_id, chain_id, telemetry_sender, telemetry_event).await; + prepare_and_send_telemetry_event(peer_id, chain_id, telemetry_sender, telemetry_event).await; } /// Collects and sends the core node metrics via telemetry @@ -387,7 +403,7 @@ async fn send_node_core_metrics( telemetry_sender: Option, ) { let telemetry_event = create_core_metric_telemetry_event(node_config).await; - send_telemetry_event_with_ip(peer_id, chain_id, telemetry_sender, telemetry_event).await; + prepare_and_send_telemetry_event(peer_id, chain_id, telemetry_sender, telemetry_event).await; } /// Collects and sends the node network metrics via telemetry @@ -397,7 +413,7 @@ async fn send_node_network_metrics( telemetry_sender: Option, ) { let telemetry_event = create_network_metric_telemetry_event().await; - send_telemetry_event_with_ip(peer_id, chain_id, telemetry_sender, telemetry_event).await; + prepare_and_send_telemetry_event(peer_id, chain_id, telemetry_sender, telemetry_event).await; } /// Collects and sends the system information via telemetry @@ -407,13 +423,13 @@ async fn send_system_information( telemetry_sender: Option, ) { let telemetry_event = create_system_info_telemetry_event().await; - send_telemetry_event_with_ip(peer_id, chain_id, telemetry_sender, telemetry_event).await; + prepare_and_send_telemetry_event(peer_id, chain_id, telemetry_sender, telemetry_event).await; } /// Fetches the IP address and sends the given telemetry event /// along with the IP address. Also sends a randomly generated /// token to help correlate metrics across events. -pub(crate) async fn send_telemetry_event_with_ip( +pub(crate) async fn prepare_and_send_telemetry_event( peer_id: String, chain_id: String, telemetry_sender: Option, @@ -421,7 +437,6 @@ pub(crate) async fn send_telemetry_event_with_ip( ) -> JoinHandle<()> { // Update the telemetry event with the ip address and random token let TelemetryEvent { name, mut params } = telemetry_event; - params.insert(IP_ADDRESS_KEY.to_string(), get_origin_ip().await); params.insert(TELEMETRY_TOKEN_KEY.to_string(), TELEMETRY_TOKEN.clone()); params.insert(CHAIN_ID_KEY.into(), chain_id); let telemetry_event = TelemetryEvent { name, params }; @@ -430,19 +445,6 @@ pub(crate) async fn send_telemetry_event_with_ip( send_telemetry_event(peer_id, telemetry_sender, telemetry_event).await } -/// Gets the IP origin of the machine by pinging a url. -/// If none is found, returns UNKNOWN. -async fn get_origin_ip() -> String { - let resp = reqwest::get(HTTPBIN_URL).await; - match resp { - Ok(json) => match json.json::().await { - Ok(origin_ip) => origin_ip.origin, - Err(_) => UNKNOWN_METRIC_VALUE.into(), - }, - Err(_) => UNKNOWN_METRIC_VALUE.into(), - } -} - /// Sends the given event and params to the telemetry endpoint async fn send_telemetry_event( peer_id: String, @@ -546,9 +548,3 @@ fn spawn_event_sender_to_google_analytics( } }) } - -/// A json struct useful for fetching the machine origin/IP -#[derive(Deserialize)] -struct OriginIP { - origin: String, -} diff --git a/crates/aptos-transaction-filters/Cargo.toml b/crates/aptos-transaction-filters/Cargo.toml new file mode 100644 index 00000000000..3169ee318d2 --- /dev/null +++ b/crates/aptos-transaction-filters/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "aptos-transaction-filters" +description = "The transaction filters used by various Aptos components." +version = "0.1.0" + +# Workspace inherited keys +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +aptos-crypto = { workspace = true } +aptos-types = { workspace = true } +move-core-types = { workspace = true } +rand = { workspace = true } +serde = { workspace = true } +serde_yaml = { workspace = true } + +[dev-dependencies] +aptos-crypto = { workspace = true, features = ["fuzzing", "testing"] } + +[features] +fuzzing = [] diff --git a/crates/aptos-transaction-filters/src/batch_transaction_filter.rs b/crates/aptos-transaction-filters/src/batch_transaction_filter.rs new file mode 100644 index 00000000000..455f66ec18c --- /dev/null +++ b/crates/aptos-transaction-filters/src/batch_transaction_filter.rs @@ -0,0 +1,299 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::transaction_filter::TransactionMatcher; +use aptos_crypto::HashValue; +use aptos_types::{quorum_store::BatchId, transaction::SignedTransaction, PeerId}; +#[cfg(any(test, feature = "fuzzing"))] +use move_core_types::account_address::AccountAddress; +use serde::{Deserialize, Serialize}; + +/// A batch transaction filter that applies a set of rules to determine +/// if a transaction in a batch should be allowed or denied. +/// +/// Rules are applied in the order they are defined, and the first +/// matching rule determines the outcome for the transaction. +/// If no rules match, the transaction is allowed by default. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct BatchTransactionFilter { + batch_transaction_rules: Vec, +} + +impl BatchTransactionFilter { + pub fn new(batch_transaction_rules: Vec) -> Self { + Self { + batch_transaction_rules, + } + } + + /// Returns true iff the filter allows the transaction in the batch + pub fn allows_transaction( + &self, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: &HashValue, + signed_transaction: &SignedTransaction, + ) -> bool { + // If the filter is empty, allow the transaction by default + if self.is_empty() { + return true; + } + + // Check if any rule matches the batch transaction + for batch_transaction_rule in &self.batch_transaction_rules { + if batch_transaction_rule.matches( + batch_id, + batch_author, + batch_digest, + signed_transaction, + ) { + return match batch_transaction_rule { + BatchTransactionRule::Allow(_) => true, + BatchTransactionRule::Deny(_) => false, + }; + } + } + + true // No rules match (allow the batch transaction by default) + } + + /// Returns an empty batch transaction filter with no rules + pub fn empty() -> Self { + Self { + batch_transaction_rules: Vec::new(), + } + } + + /// Filters the transactions in the given batch and returns only those that are allowed + pub fn filter_batch_transactions( + &self, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: HashValue, + transactions: Vec, + ) -> Vec { + transactions + .into_iter() + .filter(|txn| self.allows_transaction(batch_id, batch_author, &batch_digest, txn)) + .collect() + } + + /// Returns true iff the filter is empty (i.e., has no rules) + pub fn is_empty(&self) -> bool { + self.batch_transaction_rules.is_empty() + } + + /// Adds a filter that matches all batch transactions + pub fn add_all_filter(self, allow: bool) -> Self { + let batch_matcher = BatchTransactionMatcher::Batch(BatchMatcher::All); + self.add_multiple_matchers_filter(allow, vec![batch_matcher]) + } + + /// Adds a filter rule containing multiple matchers + pub fn add_multiple_matchers_filter( + mut self, + allow: bool, + batch_transaction_matchers: Vec, + ) -> Self { + let transaction_rule = if allow { + BatchTransactionRule::Allow(batch_transaction_matchers) + } else { + BatchTransactionRule::Deny(batch_transaction_matchers) + }; + self.batch_transaction_rules.push(transaction_rule); + + self + } +} + +// These are useful test-only methods for creating and testing filters +#[cfg(any(test, feature = "fuzzing"))] +impl BatchTransactionFilter { + /// Adds a filter rule that matches a specific batch ID + pub fn add_batch_id_filter(self, allow: bool, batch_id: BatchId) -> Self { + let batch_matcher = BatchTransactionMatcher::Batch(BatchMatcher::BatchId(batch_id)); + self.add_multiple_matchers_filter(allow, vec![batch_matcher]) + } + + /// Adds a filter rule that matches a specific batch author + pub fn add_batch_author_filter(self, allow: bool, batch_author: PeerId) -> Self { + let batch_matcher = BatchTransactionMatcher::Batch(BatchMatcher::BatchAuthor(batch_author)); + self.add_multiple_matchers_filter(allow, vec![batch_matcher]) + } + + /// Adds a filter rule that matches a specific batch digest + pub fn add_batch_digest_filter(self, allow: bool, batch_digest: HashValue) -> Self { + let batch_matcher = BatchTransactionMatcher::Batch(BatchMatcher::BatchDigest(batch_digest)); + self.add_multiple_matchers_filter(allow, vec![batch_matcher]) + } + + /// Adds a filter rule that matches a specific transaction sender + pub fn add_sender_filter(self, allow: bool, sender: AccountAddress) -> Self { + let transaction_matcher = TransactionMatcher::Sender(sender); + self.add_multiple_matchers_filter(allow, vec![BatchTransactionMatcher::Transaction( + transaction_matcher, + )]) + } +} + +/// A batch transaction rule that defines whether to allow or deny +/// transactions in a batch based on a set of matchers. All matchers +/// must match for the rule to apply. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BatchTransactionRule { + Allow(Vec), + Deny(Vec), +} + +impl BatchTransactionRule { + /// Returns true iff the rule matches the given batch transaction. This + /// requires that all matchers in the rule match the batch transaction. + pub fn matches( + &self, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: &HashValue, + signed_transaction: &SignedTransaction, + ) -> bool { + let batch_transaction_matchers = match self { + BatchTransactionRule::Allow(matchers) => matchers, + BatchTransactionRule::Deny(matchers) => matchers, + }; + batch_transaction_matchers.iter().all(|matcher| { + matcher.matches(batch_id, batch_author, batch_digest, signed_transaction) + }) + } +} + +/// A matcher that defines the criteria for matching batches or transactions +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BatchTransactionMatcher { + Batch(BatchMatcher), + Transaction(TransactionMatcher), +} + +impl BatchTransactionMatcher { + /// Returns true iff the matcher matches the given batch transaction + pub fn matches( + &self, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: &HashValue, + signed_transaction: &SignedTransaction, + ) -> bool { + match self { + BatchTransactionMatcher::Batch(batch_matcher) => { + batch_matcher.matches(batch_id, batch_author, batch_digest) + }, + BatchTransactionMatcher::Transaction(transaction_matcher) => { + transaction_matcher.matches(signed_transaction) + }, + } + } +} + +/// A matcher that defines the criteria for matching batches +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BatchMatcher { + All, // Matches any batch + BatchId(BatchId), // Matches batches with the specified ID + BatchAuthor(PeerId), // Matches batches authored by the specified peer + BatchDigest(HashValue), // Matches batches with the specified digest +} + +impl BatchMatcher { + /// Returns true iff the matcher matches the given batch information + fn matches(&self, batch_id: BatchId, batch_author: PeerId, batch_digest: &HashValue) -> bool { + match self { + BatchMatcher::All => true, + BatchMatcher::BatchId(target_batch_id) => matches_batch_id(batch_id, target_batch_id), + BatchMatcher::BatchAuthor(target_author) => { + matches_batch_author(batch_author, target_author) + }, + BatchMatcher::BatchDigest(target_digest) => { + matches_batch_digest(batch_digest, target_digest) + }, + } + } +} + +/// Returns true iff the batch ID matches the target batch ID +fn matches_batch_id(batch_id: BatchId, target_batch_id: &BatchId) -> bool { + batch_id == *target_batch_id +} + +/// Returns true iff the batch author matches the target author +fn matches_batch_author(batch_author: PeerId, target_author: &PeerId) -> bool { + batch_author == *target_author +} + +/// Returns true iff the batch digest matches the target digest +fn matches_batch_digest(batch_digest: &HashValue, target_digest: &HashValue) -> bool { + batch_digest == target_digest +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_matches_batch_id() { + // Create a batch ID + let batch_id = BatchId::new_for_test(1000); + + // Verify that the batch ID matches itself + verify_matches_batch_id(batch_id, &batch_id, true); + + // Verify that a different batch ID does not match + let different_batch_id = BatchId::new_for_test(122); + verify_matches_batch_id(batch_id, &different_batch_id, false); + } + + #[test] + fn test_matches_batch_author() { + // Create a batch author + let batch_author = PeerId::random(); + + // Verify that the batch author matches itself + verify_matches_batch_author(batch_author, &batch_author, true); + + // Verify that a different batch author does not match + let different_batch_author = PeerId::random(); + verify_matches_batch_author(batch_author, &different_batch_author, false); + } + + #[test] + fn test_matches_batch_digest() { + // Create a batch digest + let batch_digest = HashValue::random(); + + // Verify that the batch digest matches itself + verify_matches_batch_digest(&batch_digest, &batch_digest, true); + + // Verify that a different batch digest does not match + let different_batch_digest = HashValue::random(); + verify_matches_batch_digest(&batch_digest, &different_batch_digest, false); + } + + /// Verifies that the batch ID matches the target batch ID + fn verify_matches_batch_id(batch_id: BatchId, target_batch_id: &BatchId, matches: bool) { + let result = matches_batch_id(batch_id, target_batch_id); + assert_eq!(matches, result); + } + + /// Verifies that the batch author matches the target author + fn verify_matches_batch_author(batch_author: PeerId, target_author: &PeerId, matches: bool) { + let result = matches_batch_author(batch_author, target_author); + assert_eq!(matches, result); + } + + /// Verifies that the batch digest matches the target digest + fn verify_matches_batch_digest( + batch_digest: &HashValue, + target_digest: &HashValue, + matches: bool, + ) { + let result = matches_batch_digest(batch_digest, target_digest); + assert_eq!(matches, result); + } +} diff --git a/crates/aptos-transaction-filters/src/block_transaction_filter.rs b/crates/aptos-transaction-filters/src/block_transaction_filter.rs new file mode 100644 index 00000000000..71f0b033bdb --- /dev/null +++ b/crates/aptos-transaction-filters/src/block_transaction_filter.rs @@ -0,0 +1,463 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::transaction_filter::TransactionMatcher; +use aptos_crypto::HashValue; +use aptos_types::transaction::SignedTransaction; +use move_core_types::account_address::AccountAddress; +use serde::{Deserialize, Serialize}; + +/// A block transaction filter that applies a set of rules to determine +/// if a transaction in a block should be allowed or denied. +/// +/// Rules are applied in the order they are defined, and the first +/// matching rule determines the outcome for the transaction. +/// If no rules match, the transaction is allowed by default. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct BlockTransactionFilter { + block_transaction_rules: Vec, +} + +impl BlockTransactionFilter { + pub fn new(block_transaction_rules: Vec) -> Self { + Self { + block_transaction_rules, + } + } + + /// Returns true iff the filter allows the transaction in the block + pub fn allows_transaction( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + signed_transaction: &SignedTransaction, + ) -> bool { + // If the filter is empty, allow the transaction by default + if self.is_empty() { + return true; + } + + // Check if any rule matches the block transaction + for block_transaction_rule in &self.block_transaction_rules { + if block_transaction_rule.matches( + block_id, + block_author, + block_epoch, + block_timestamp, + signed_transaction, + ) { + return match block_transaction_rule { + BlockTransactionRule::Allow(_) => true, + BlockTransactionRule::Deny(_) => false, + }; + } + } + + true // No rules match (allow the block transaction by default) + } + + /// Returns an empty block transaction filter with no rules + pub fn empty() -> Self { + Self { + block_transaction_rules: Vec::new(), + } + } + + /// Identifies the transactions in the given block that are denied by the filter. + /// Note: this returns the inverse of `filter_block_transactions`. + pub fn get_denied_block_transactions( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp_usecs: u64, + transactions: Vec, + ) -> Vec { + transactions + .into_iter() + .filter(|txn| { + !self.allows_transaction( + block_id, + block_author, + block_epoch, + block_timestamp_usecs, + txn, + ) + }) + .collect() + } + + /// Filters the transactions in the given block and returns only those that are allowed + pub fn filter_block_transactions( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp_usecs: u64, + transactions: Vec, + ) -> Vec { + transactions + .into_iter() + .filter(|txn| { + self.allows_transaction( + block_id, + block_author, + block_epoch, + block_timestamp_usecs, + txn, + ) + }) + .collect() + } + + /// Returns true iff the filter is empty (i.e., has no rules) + pub fn is_empty(&self) -> bool { + self.block_transaction_rules.is_empty() + } + + /// Adds a filter that matches all block transactions + pub fn add_all_filter(self, allow: bool) -> Self { + let block_matcher = BlockTransactionMatcher::Block(BlockMatcher::All); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a filter rule containing multiple matchers + pub fn add_multiple_matchers_filter( + mut self, + allow: bool, + block_transaction_matchers: Vec, + ) -> Self { + let transaction_rule = if allow { + BlockTransactionRule::Allow(block_transaction_matchers) + } else { + BlockTransactionRule::Deny(block_transaction_matchers) + }; + self.block_transaction_rules.push(transaction_rule); + + self + } +} + +// These are useful test-only methods for creating and testing filters +#[cfg(any(test, feature = "fuzzing"))] +impl BlockTransactionFilter { + /// Adds a block author matcher to the filter + pub fn add_block_author_filter(self, allow: bool, block_author: AccountAddress) -> Self { + let block_matcher = BlockTransactionMatcher::Block(BlockMatcher::Author(block_author)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a block ID matcher to the filter + pub fn add_block_id_filter(self, allow: bool, block_id: HashValue) -> Self { + let block_matcher = BlockTransactionMatcher::Block(BlockMatcher::BlockId(block_id)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a block epoch greater than matcher to the filter + pub fn add_block_epoch_greater_than_filter(self, allow: bool, epoch: u64) -> Self { + let block_matcher = + BlockTransactionMatcher::Block(BlockMatcher::BlockEpochGreaterThan(epoch)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a block epoch less than matcher to the filter + pub fn add_block_epoch_less_than_filter(self, allow: bool, epoch: u64) -> Self { + let block_matcher = BlockTransactionMatcher::Block(BlockMatcher::BlockEpochLessThan(epoch)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a block timestamp greater than matcher to the filter + pub fn add_block_timestamp_greater_than_filter(self, allow: bool, timestamp: u64) -> Self { + let block_matcher = + BlockTransactionMatcher::Block(BlockMatcher::BlockTimeStampGreaterThan(timestamp)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } + + /// Adds a block timestamp less than matcher to the filter + pub fn add_block_timestamp_less_than_filter(self, allow: bool, timestamp: u64) -> Self { + let block_matcher = + BlockTransactionMatcher::Block(BlockMatcher::BlockTimeStampLessThan(timestamp)); + self.add_multiple_matchers_filter(allow, vec![block_matcher]) + } +} + +/// A block transaction rule that defines whether to allow or deny +/// transactions in a block based on a set of matchers. All matchers +/// must match for the rule to apply. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BlockTransactionRule { + Allow(Vec), + Deny(Vec), +} + +impl BlockTransactionRule { + /// Returns true iff the rule matches the given block transaction. This + /// requires that all matchers in the rule match the block transaction. + pub fn matches( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + signed_transaction: &SignedTransaction, + ) -> bool { + let block_transaction_matchers = match self { + BlockTransactionRule::Allow(matchers) => matchers, + BlockTransactionRule::Deny(matchers) => matchers, + }; + block_transaction_matchers.iter().all(|matcher| { + matcher.matches( + block_id, + block_author, + block_epoch, + block_timestamp, + signed_transaction, + ) + }) + } +} + +/// A matcher that defines the criteria for matching blocks or transactions +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BlockTransactionMatcher { + Block(BlockMatcher), + Transaction(TransactionMatcher), +} + +impl BlockTransactionMatcher { + /// Returns true iff the matcher matches the given block transaction + pub fn matches( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + signed_transaction: &SignedTransaction, + ) -> bool { + match self { + BlockTransactionMatcher::Block(block_matcher) => { + block_matcher.matches(block_id, block_author, block_epoch, block_timestamp) + }, + BlockTransactionMatcher::Transaction(transaction_matcher) => { + transaction_matcher.matches(signed_transaction) + }, + } + } +} + +/// A matcher that defines the criteria for matching blocks +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BlockMatcher { + All, // Matches any block + Author(AccountAddress), // Matches blocks proposed by the specified author + BlockId(HashValue), // Matches blocks with the specified ID + BlockEpochGreaterThan(u64), // Matches blocks with epochs greater than the specified value + BlockEpochLessThan(u64), // Matches blocks with epochs less than the specified value + BlockTimeStampGreaterThan(u64), // Matches blocks with timestamps greater than the specified value + BlockTimeStampLessThan(u64), // Matches blocks with timestamps less than the specified value +} + +impl BlockMatcher { + /// Returns true iff the matcher matches the given block information + fn matches( + &self, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + ) -> bool { + match self { + BlockMatcher::All => true, + BlockMatcher::Author(target_author) => { + matches_block_author(block_author, target_author) + }, + BlockMatcher::BlockId(target_block_id) => matches_block_id(block_id, target_block_id), + BlockMatcher::BlockEpochGreaterThan(target_epoch) => { + matches_epoch_greater_than(block_epoch, target_epoch) + }, + BlockMatcher::BlockEpochLessThan(target_epoch) => { + matches_epoch_less_than(block_epoch, target_epoch) + }, + BlockMatcher::BlockTimeStampGreaterThan(target_timestamp) => { + matches_timestamp_greater_than(block_timestamp, target_timestamp) + }, + BlockMatcher::BlockTimeStampLessThan(target_timestamp) => { + matches_timestamp_less_than(block_timestamp, target_timestamp) + }, + } + } +} + +/// Returns true iff the block author matches the target author. +/// Note: if the block author is None, it does not match the target author. +fn matches_block_author( + block_author: Option, + target_author: &AccountAddress, +) -> bool { + match block_author { + Some(block_author) => block_author == *target_author, + None => false, + } +} + +/// Returns true iff the block ID matches the target block ID +fn matches_block_id(block_id: HashValue, target_block_id: &HashValue) -> bool { + block_id == *target_block_id +} + +/// Returns true iff the block epoch is greater than the target epoch +fn matches_epoch_greater_than(block_epoch: u64, target_epoch: &u64) -> bool { + block_epoch > *target_epoch +} + +/// Returns true iff the block epoch is less than the target epoch +fn matches_epoch_less_than(block_epoch: u64, target_epoch: &u64) -> bool { + block_epoch < *target_epoch +} + +/// Returns true iff the block timestamp is greater than the target timestamp +fn matches_timestamp_greater_than(block_timestamp: u64, target_timestamp: &u64) -> bool { + block_timestamp > *target_timestamp +} + +/// Returns true iff the block timestamp is less than the target timestamp +fn matches_timestamp_less_than(block_timestamp: u64, target_timestamp: &u64) -> bool { + block_timestamp < *target_timestamp +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_matches_block_author() { + // Create a block author + let block_author = AccountAddress::random(); + + // Verify that a missing block author does not match + assert!(!matches_block_author(None, &block_author)); + + // Verify that the block author matches itself + assert!(matches_block_author(Some(block_author), &block_author)); + + // Verify that a different block author does not match + let different_block_author = AccountAddress::random(); + assert!(!matches_block_author( + Some(block_author), + &different_block_author + )); + } + + #[test] + fn test_matches_block_id() { + // Create a block ID + let block_id = HashValue::random(); + + // Verify that the block ID matches itself + verify_matches_block_id(block_id, &block_id, true); + + // Verify that a different block ID does not match + let different_block_id = HashValue::random(); + verify_matches_block_id(block_id, &different_block_id, false); + } + + #[test] + fn test_matches_epoch_greater_than() { + // Create an epoch + let epoch = 10; + + // Verify that a greater epoch matches + verify_matches_epoch_greater_than(epoch + 1, &epoch, true); + + // Verify that an equal epoch does not match + verify_matches_epoch_greater_than(epoch, &epoch, false); + + // Verify that a lesser epoch does not match + verify_matches_epoch_greater_than(epoch - 1, &epoch, false); + } + + #[test] + fn test_matches_epoch_less_than() { + // Create an epoch + let epoch = 10; + + // Verify that a lesser epoch matches + verify_matches_epoch_less_than(epoch - 1, &epoch, true); + + // Verify that an equal epoch does not match + verify_matches_epoch_less_than(epoch, &epoch, false); + + // Verify that a greater epoch does not match + verify_matches_epoch_less_than(epoch + 1, &epoch, false); + } + + #[test] + fn test_matches_timestamp_greater_than() { + // Create a timestamp + let timestamp = 100; + + // Verify that a greater timestamp matches + verify_matches_timestamp_greater_than(timestamp + 1, ×tamp, true); + + // Verify that an equal timestamp does not match + verify_matches_timestamp_greater_than(timestamp, ×tamp, false); + + // Verify that a lesser timestamp does not match + verify_matches_timestamp_greater_than(timestamp - 1, ×tamp, false); + } + + #[test] + fn test_matches_timestamp_less_than() { + // Create a timestamp + let timestamp = 100; + + // Verify that a lesser timestamp matches + verify_matches_timestamp_less_than(timestamp - 1, ×tamp, true); + + // Verify that an equal timestamp does not match + verify_matches_timestamp_less_than(timestamp, ×tamp, false); + + // Verify that a greater timestamp does not match + verify_matches_timestamp_less_than(timestamp + 1, ×tamp, false); + } + + /// Verifies that the block ID matches the target block ID + fn verify_matches_block_id(block_id: HashValue, target_block_id: &HashValue, matches: bool) { + let result = matches_block_id(block_id, target_block_id); + assert_eq!(matches, result); + } + + /// Verifies that the block epoch is greater than the target epoch + fn verify_matches_epoch_greater_than(block_epoch: u64, target_epoch: &u64, matches: bool) { + let result = matches_epoch_greater_than(block_epoch, target_epoch); + assert_eq!(matches, result); + } + + /// Verifies that the block epoch is less than the target epoch + fn verify_matches_epoch_less_than(block_epoch: u64, target_epoch: &u64, matches: bool) { + let result = matches_epoch_less_than(block_epoch, target_epoch); + assert_eq!(matches, result); + } + + /// Verifies that the block timestamp is greater than the target timestamp + fn verify_matches_timestamp_greater_than( + block_timestamp: u64, + target_timestamp: &u64, + matches: bool, + ) { + let result = matches_timestamp_greater_than(block_timestamp, target_timestamp); + assert_eq!(matches, result); + } + + /// Verifies that the block timestamp is less than the target timestamp + fn verify_matches_timestamp_less_than( + block_timestamp: u64, + target_timestamp: &u64, + matches: bool, + ) { + let result = matches_timestamp_less_than(block_timestamp, target_timestamp); + assert_eq!(matches, result); + } +} diff --git a/crates/aptos-transaction-filters/src/lib.rs b/crates/aptos-transaction-filters/src/lib.rs new file mode 100644 index 00000000000..3e1fc2f9154 --- /dev/null +++ b/crates/aptos-transaction-filters/src/lib.rs @@ -0,0 +1,11 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +pub mod batch_transaction_filter; +pub mod block_transaction_filter; +pub mod transaction_filter; + +#[cfg(test)] +mod tests; diff --git a/crates/aptos-transaction-filters/src/tests/batch_transaction_filter.rs b/crates/aptos-transaction-filters/src/tests/batch_transaction_filter.rs new file mode 100644 index 00000000000..b62bc054a14 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/batch_transaction_filter.rs @@ -0,0 +1,335 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + batch_transaction_filter::{BatchMatcher, BatchTransactionFilter, BatchTransactionMatcher}, + tests::utils, + transaction_filter::TransactionMatcher, +}; +use aptos_crypto::HashValue; +use aptos_types::{quorum_store::BatchId, transaction::SignedTransaction, PeerId}; + +#[test] +fn test_all_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that allows all transactions + let filter = BatchTransactionFilter::empty().add_all_filter(true); + + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + verify_all_transactions_allowed( + filter, + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Create a filter that denies all transactions + let filter = BatchTransactionFilter::empty().add_all_filter(false); + + // Verify that all transactions are denied + verify_all_transactions_rejected( + filter, + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + } +} + +#[test] +fn test_batch_id_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Create a filter that only allows transactions with a specific batch ID + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BatchTransactionFilter::empty() + .add_batch_id_filter(true, batch_id) + .add_all_filter(false); + + // Verify that the filter allows transactions within the specified batch ID + verify_all_transactions_allowed( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a different batch ID + let different_batch_id = BatchId::new_for_test(1000); + verify_all_transactions_rejected( + filter.clone(), + different_batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Create a filter that denies transactions with a specific batch ID + let filter = BatchTransactionFilter::empty().add_batch_id_filter(false, batch_id); + + // Verify that the filter denies transactions within the specified batch ID + verify_all_transactions_rejected( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a different batch ID + let different_batch_id = BatchId::new_for_test(200); + verify_all_transactions_allowed( + filter.clone(), + different_batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + } +} + +#[test] +fn test_batch_author_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Create a filter that only allows transactions with a specific batch author + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BatchTransactionFilter::empty() + .add_batch_author_filter(true, batch_author) + .add_all_filter(false); + + // Verify that the filter allows transactions with the specified batch author + verify_all_transactions_allowed( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a different batch author + let different_batch_author = PeerId::random(); + verify_all_transactions_rejected( + filter.clone(), + batch_id, + different_batch_author, + batch_digest, + transactions.clone(), + ); + + // Create a filter that denies transactions with a specific batch author + let filter = BatchTransactionFilter::empty().add_batch_author_filter(false, batch_author); + + // Verify that the filter denies transactions with the specified batch author + verify_all_transactions_rejected( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a different batch author + verify_all_transactions_allowed( + filter.clone(), + batch_id, + different_batch_author, + batch_digest, + transactions.clone(), + ); + } +} + +#[test] +fn test_batch_digest_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Create a filter that only allows transactions with a specific batch digest + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BatchTransactionFilter::empty() + .add_batch_digest_filter(true, batch_digest) + .add_all_filter(false); + + // Verify that the filter allows transactions with the specified batch digest + verify_all_transactions_allowed( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a different batch digest + let different_batch_digest = HashValue::random(); + verify_all_transactions_rejected( + filter.clone(), + batch_id, + batch_author, + different_batch_digest, + transactions.clone(), + ); + + // Create a filter that denies transactions with a specific batch digest + let filter = BatchTransactionFilter::empty().add_batch_digest_filter(false, batch_digest); + + // Verify that the filter denies transactions with the specified batch digest + verify_all_transactions_rejected( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a different batch digest + verify_all_transactions_allowed( + filter.clone(), + batch_id, + batch_author, + different_batch_digest, + transactions.clone(), + ); + } +} + +#[test] +fn test_empty_filter() { + for use_new_txn_payload_format in [false, true] { + // Create an empty filter + let filter = BatchTransactionFilter::empty(); + + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + verify_all_transactions_allowed( + filter.clone(), + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + } +} + +#[test] +fn test_multiple_matchers_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a batch ID, author, and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Create a filter that only allows batch transactions with a specific author and sender (txn 0) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let batch_transaction_matchers = vec![ + BatchTransactionMatcher::Batch(BatchMatcher::BatchAuthor(batch_author)), + BatchTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[0].sender(), + )), + ]; + let filter = BatchTransactionFilter::empty() + .add_multiple_matchers_filter(true, batch_transaction_matchers) + .add_all_filter(false); + + // Verify that the filter returns no transactions with a different batch author + verify_all_transactions_rejected( + filter.clone(), + batch_id, + PeerId::random(), // Use a different author + batch_digest, + transactions.clone(), + ); + + // Verify that the filter returns transactions with the specified batch author and sender + let filtered_transactions = filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[0..1].to_vec()); + + // Create a filter that denies batch transactions with a specific author and sender (txn 0 and 1) + let batch_transaction_matchers_0 = vec![ + BatchTransactionMatcher::Batch(BatchMatcher::BatchAuthor(batch_author)), + BatchTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[0].sender(), + )), + ]; + let batch_transaction_matchers_1 = vec![ + BatchTransactionMatcher::Batch(BatchMatcher::BatchAuthor(batch_author)), + BatchTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[1].sender(), + )), + ]; + let filter = BatchTransactionFilter::empty() + .add_multiple_matchers_filter(false, batch_transaction_matchers_0) + .add_multiple_matchers_filter(false, batch_transaction_matchers_1) + .add_all_filter(true); + + // Verify that the filter returns all transaction with a different batch author + verify_all_transactions_allowed( + filter.clone(), + batch_id, + PeerId::random(), // Use a different author + batch_digest, + transactions.clone(), + ); + + // Verify that the filter rejects transactions with the specified batch author and senders + let filtered_transactions = filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + } +} + +/// Verifies that all transactions are allowed by the given filter +fn verify_all_transactions_allowed( + filter: BatchTransactionFilter, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: HashValue, + transactions: Vec, +) { + let filtered_transactions = filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions); +} + +/// Verifies that all transactions are rejected by the given filter +fn verify_all_transactions_rejected( + filter: BatchTransactionFilter, + batch_id: BatchId, + batch_author: PeerId, + batch_digest: HashValue, + transactions: Vec, +) { + let filtered_transactions = filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert!(filtered_transactions.is_empty()); +} diff --git a/crates/aptos-transaction-filters/src/tests/batch_transaction_filter_config.rs b/crates/aptos-transaction-filters/src/tests/batch_transaction_filter_config.rs new file mode 100644 index 00000000000..56881d5697b --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/batch_transaction_filter_config.rs @@ -0,0 +1,196 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{batch_transaction_filter::BatchTransactionFilter, tests::utils}; +use aptos_types::{quorum_store::BatchId, PeerId}; + +#[test] +fn test_batch_transaction_filter_config_allow() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let batch_transaction_filter_string = format!( + r#" + batch_transaction_rules: + - Allow: + - Transaction: + Sender: "{}" + - Allow: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" + - Allow: + - Transaction: + PublicKey: + Ed25519: + - "{}" + - Allow: + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000003" + - entry + - sub + - Allow: + - Transaction: + AccountAddress: "{}" + - Deny: + - Batch: + All + "#, + transactions[0].sender().to_standard_string(), + utils::get_ed25519_public_key(&transactions[2]), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let batch_transaction_filter = + serde_yaml::from_str::(&batch_transaction_filter_string) + .unwrap(); + + // Create a batch ID, author and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Verify that only the first five transactions are allowed + let filtered_transactions = batch_transaction_filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[0..5].to_vec()); + } +} + +#[test] +fn test_batch_transaction_filter_config_deny() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that denies transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let batch_transaction_filter_string = format!( + r#" + batch_transaction_rules: + - Deny: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Deny: + - Transaction: + Sender: "{}" + - Deny: + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000002" + - entry + - new + - Deny: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000003" + - Deny: + - Transaction: + AccountAddress: "{}" + - Allow: + - Transaction: + All + "#, + transactions[1].sender().to_standard_string(), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let batch_transaction_filter = + serde_yaml::from_str::(&batch_transaction_filter_string) + .unwrap(); + + // Create a batch ID, author and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Verify that the first five transactions are denied + let filtered_transactions = batch_transaction_filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[5..].to_vec()); + } +} + +#[test] +fn test_batch_transaction_filter_config_multiple_matchers() { + for use_new_txn_payload_format in [false, true] { + // Create a batch ID, author and digest + let (batch_id, batch_author, batch_digest) = utils::get_random_batch_info(); + + // Create a filter that denies transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let batch_transaction_filter_string = format!( + r#" + batch_transaction_rules: + - Deny: + - Transaction: + Sender: "{}" + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Batch: + BatchId: + id: {} + nonce: 0 + - Deny: + - Transaction: + Sender: "{}" + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000001" + - entry + - check + - Batch: + BatchId: + id: {} + nonce: 0 + - Deny: + - Transaction: + Sender: "{}" + - Batch: + BatchId: + id: 999 + nonce: 0 + - Deny: + - Batch: + BatchAuthor: {} + - Allow: + - Transaction: + All + "#, + transactions[0].sender().to_standard_string(), + batch_id.id, + transactions[1].sender().to_standard_string(), + batch_id.id, + transactions[2].sender().to_standard_string(), + batch_author.to_standard_string(), + ); + let batch_transaction_filter = + serde_yaml::from_str::(&batch_transaction_filter_string) + .unwrap(); + + // Verify that the first two transactions are denied when the batch has a different author + let filtered_transactions = batch_transaction_filter.filter_batch_transactions( + batch_id, + PeerId::random(), // Use a different author + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + + // Verify that all transactions are denied when the batch has the rejected author + let filtered_transactions = batch_transaction_filter.filter_batch_transactions( + batch_id, + batch_author, + batch_digest, + transactions.clone(), + ); + assert!(filtered_transactions.is_empty()); + + // Verify that all transactions are allowed in a different batch (different author and ID) + let filtered_transactions = batch_transaction_filter.filter_batch_transactions( + BatchId::new_for_test(0), // Use a different batch ID + PeerId::random(), // Use a different author + batch_digest, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions); + } +} diff --git a/crates/aptos-transaction-filters/src/tests/block_transaction_filter.rs b/crates/aptos-transaction-filters/src/tests/block_transaction_filter.rs new file mode 100644 index 00000000000..42d76d03312 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/block_transaction_filter.rs @@ -0,0 +1,633 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + block_transaction_filter::{BlockMatcher, BlockTransactionFilter, BlockTransactionMatcher}, + tests::utils, + transaction_filter::TransactionMatcher, +}; +use aptos_crypto::HashValue; +use aptos_types::transaction::SignedTransaction; +use move_core_types::account_address::AccountAddress; + +#[test] +fn test_all_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that allows all transactions + let filter = BlockTransactionFilter::empty().add_all_filter(true); + + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + verify_all_transactions_allowed( + filter, + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Create a filter that denies all transactions + let filter = BlockTransactionFilter::empty().add_all_filter(false); + + // Verify that all transactions are denied + verify_all_transactions_rejected( + filter, + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } +} + +#[test] +fn test_block_author_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Create a filter that only allows transactions with a specific block author + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BlockTransactionFilter::empty() + .add_block_author_filter(true, block_author) + .add_all_filter(false); + + // Verify that the filter allows transactions with the specified block author + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a different block author + let different_block_author = AccountAddress::random(); + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(different_block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a missing block author + verify_all_transactions_rejected( + filter.clone(), + block_id, + None, + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Create a filter that denies transactions with a specific block author + let filter = BlockTransactionFilter::empty().add_block_author_filter(false, block_author); + + // Verify that the filter denies transactions with the specified block author + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a different block author + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(different_block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a missing block author + verify_all_transactions_allowed( + filter.clone(), + block_id, + None, + block_epoch, + block_timestamp, + transactions.clone(), + ); + } +} + +#[test] +fn test_block_id_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Create a filter that only allows transactions with a specific block ID + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BlockTransactionFilter::empty() + .add_block_id_filter(true, block_id) + .add_all_filter(false); + + // Verify that the filter allows transactions within the specified block ID + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter denies transactions with a different block ID + let different_block_id = HashValue::random(); + verify_all_transactions_rejected( + filter.clone(), + different_block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Create a filter that denies transactions with a specific block ID + let filter = BlockTransactionFilter::empty().add_block_id_filter(false, block_id); + + // Verify that the filter denies transactions within the specified block ID + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + + // Verify that the filter allows transactions with a different block ID + let different_block_id = HashValue::random(); + verify_all_transactions_allowed( + filter.clone(), + different_block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } +} + +#[test] +fn test_block_epoch_greater_than_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with a block epoch greater than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_epoch_greater_than_filter(true, 1000) + .add_all_filter(false); + + // Create a block ID, author, and timestamp + let (block_id, block_author, _, block_timestamp) = utils::get_random_block_info(); + + // Verify that the filter only allows transactions with a block epoch greater than 1000 + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + for block_epoch in [0, 999, 1000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_epoch in [1001, 1002] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Create a filter that denies transactions with a block epoch greater than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_epoch_greater_than_filter(false, 1000) + .add_all_filter(true); + + // Verify that the filter only allows transactions with a block epoch less than or equal to 1000 + for block_epoch in [0, 999, 1000] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_epoch in [1001, 2000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + } +} + +#[test] +fn test_block_epoch_less_than_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with a block epoch less than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_epoch_less_than_filter(true, 1000) + .add_all_filter(false); + + // Create a block ID, author, and timestamp + let (block_id, block_author, _, block_timestamp) = utils::get_random_block_info(); + + // Verify that the filter only allows transactions with a block epoch less than 1000 + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + for block_epoch in [0, 999] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_epoch in [1000, 1001] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Create a filter that denies transactions with a block epoch less than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_epoch_less_than_filter(false, 1000) + .add_all_filter(true); + + // Verify that the filter only allows transactions with a block epoch greater than or equal to 1000 + for block_epoch in [0, 999] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_epoch in [1000, 1001] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + } +} + +#[test] +fn test_block_timestamp_greater_than_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with a block timestamp greater than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_timestamp_greater_than_filter(true, 1000) + .add_all_filter(false); + + // Create a block ID, author, and epoch + let (block_id, block_author, block_epoch, _) = utils::get_random_block_info(); + + // Verify that the filter only allows transactions with a block timestamp greater than 1000 + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + for block_timestamp in [0, 999, 1000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_timestamp in [1001, 2000] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Create a filter that denies transactions with a block timestamp greater than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_timestamp_greater_than_filter(false, 1000) + .add_all_filter(true); + + // Verify that the filter only allows transactions with a block timestamp less than or equal to 1000 + for block_timestamp in [0, 999, 1000] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_timestamp in [1001, 2000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + } +} + +#[test] +fn test_block_timestamp_less_than_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with a block timestamp less than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_timestamp_less_than_filter(true, 1000) + .add_all_filter(false); + + // Create a block ID, author, and epoch + let (block_id, block_author, block_epoch, _) = utils::get_random_block_info(); + + // Verify that the filter only allows transactions with a block timestamp less than 1000 + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + for block_timestamp in [0, 999] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_timestamp in [1000, 1001, 2000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Create a filter that denies transactions with a block timestamp less than a specific value + let filter = BlockTransactionFilter::empty() + .add_block_timestamp_less_than_filter(false, 1000) + .add_all_filter(true); + + // Verify that the filter only allows transactions with a block timestamp greater than or equal to 1000 + for block_timestamp in [0, 999] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + for block_timestamp in [1000, 1001, 2000] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + } +} + +#[test] +fn test_empty_filter() { + for use_new_txn_payload_format in [false, true] { + // Create an empty filter + let filter = BlockTransactionFilter::empty(); + + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } +} + +#[test] +fn test_get_denied_block_transactions() { + for use_new_txn_payload_format in [false, true] { + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Create a filter that denies transactions from specific senders + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[0].sender()), + )]) + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[1].sender()), + )]) + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[2].sender()), + )]) + .add_all_filter(true); + + // Verify that the filter denies transactions from the specified senders + let denied_transactions = filter.get_denied_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(denied_transactions, transactions[0..3].to_vec()); + + // Create a filter that allows transactions from specific senders + let filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(true, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[0].sender()), + )]) + .add_multiple_matchers_filter(true, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(transactions[1].sender()), + )]) + .add_all_filter(false); + + // Verify that the filter allows transactions from the specified senders + let denied_transactions = filter.get_denied_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(denied_transactions, transactions[2..].to_vec()); + } +} + +#[test] +fn test_multiple_matchers_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Create a filter that only allows block transactions with epoch > 1000 and a specific sender (txn 0) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let block_transaction_matchers = vec![ + BlockTransactionMatcher::Block(BlockMatcher::BlockEpochGreaterThan(1000)), + BlockTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[0].sender(), + )), + ]; + let filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(true, block_transaction_matchers) + .add_all_filter(false); + + // Verify that the filter returns no transactions with block epoch less than or equal to 1000 + for block_epoch in [0, 999, 1000] { + verify_all_transactions_rejected( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Verify that the filter returns transactions with block epoch greater than 1000 and the specified sender + for block_epoch in [1001, 2002] { + let filtered_transactions = filter.filter_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[0..1].to_vec()); + } + + // Create a filter that denies block transactions with timestamp < 1000 and a specific sender (txn 0 and 1) + let block_transaction_matchers_0 = vec![ + BlockTransactionMatcher::Block(BlockMatcher::BlockTimeStampLessThan(1000)), + BlockTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[0].sender(), + )), + ]; + let block_transaction_matchers_1 = vec![ + BlockTransactionMatcher::Block(BlockMatcher::BlockTimeStampLessThan(1000)), + BlockTransactionMatcher::Transaction(TransactionMatcher::Sender( + transactions[1].sender(), + )), + ]; + let filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(false, block_transaction_matchers_0) + .add_multiple_matchers_filter(false, block_transaction_matchers_1) + .add_all_filter(true); + + // Verify that it returns all transactions with block timestamp greater than or equal to 1000 + for block_timestamp in [1000, 1001, 2000] { + verify_all_transactions_allowed( + filter.clone(), + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + } + + // Verify that it returns no transactions with block timestamp less than 1000 and the specified senders + for block_timestamp in [0, 999] { + let filtered_transactions = filter.filter_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + } + } +} + +/// Verifies that all transactions are allowed by the given filter +fn verify_all_transactions_allowed( + filter: BlockTransactionFilter, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + transactions: Vec, +) { + let filtered_transactions = filter.filter_block_transactions( + block_id, + block_author, + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions); +} + +/// Verifies that all transactions are rejected by the given filter +fn verify_all_transactions_rejected( + filter: BlockTransactionFilter, + block_id: HashValue, + block_author: Option, + block_epoch: u64, + block_timestamp: u64, + transactions: Vec, +) { + let filtered_transactions = filter.filter_block_transactions( + block_id, + block_author, + block_epoch, + block_timestamp, + transactions, + ); + assert!(filtered_transactions.is_empty()); +} diff --git a/crates/aptos-transaction-filters/src/tests/block_transaction_filter_config.rs b/crates/aptos-transaction-filters/src/tests/block_transaction_filter_config.rs new file mode 100644 index 00000000000..985b7c40c64 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/block_transaction_filter_config.rs @@ -0,0 +1,213 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{block_transaction_filter::BlockTransactionFilter, tests::utils}; +use aptos_crypto::HashValue; +use move_core_types::account_address::AccountAddress; + +#[test] +fn test_block_transaction_filter_config_allow() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let block_transaction_filter_string = format!( + r#" + block_transaction_rules: + - Allow: + - Transaction: + Sender: "{}" + - Allow: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" + - Allow: + - Transaction: + PublicKey: + Ed25519: + - "{}" + - Allow: + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000003" + - entry + - sub + - Allow: + - Transaction: + AccountAddress: "{}" + - Deny: + - Block: + All + "#, + transactions[0].sender().to_standard_string(), + utils::get_ed25519_public_key(&transactions[2]), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let block_transaction_filter = + serde_yaml::from_str::(&block_transaction_filter_string) + .unwrap(); + + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Verify that only the first five transactions are allowed + let filtered_transactions = block_transaction_filter.filter_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[0..5].to_vec()); + } +} + +#[test] +fn test_block_transaction_filter_config_deny() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that denies transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let block_transaction_filter_string = format!( + r#" + block_transaction_rules: + - Deny: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Deny: + - Transaction: + Sender: "{}" + - Deny: + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000002" + - entry + - new + - Deny: + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000003" + - Deny: + - Transaction: + AccountAddress: "{}" + - Allow: + - Transaction: + All + "#, + transactions[1].sender().to_standard_string(), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let block_transaction_filter = + serde_yaml::from_str::(&block_transaction_filter_string) + .unwrap(); + + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Verify that the first five transactions are denied + let filtered_transactions = block_transaction_filter.filter_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[5..].to_vec()); + } +} + +#[test] +fn test_block_transaction_filter_config_multiple_matchers() { + for use_new_txn_payload_format in [false, true] { + // Create a block ID, author, epoch, and timestamp + let (block_id, block_author, block_epoch, block_timestamp) = utils::get_random_block_info(); + + // Create a malicious block author (where blocks are not allowed) + let malicious_block_author = AccountAddress::random(); + + // Create a filter that denies transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let block_transaction_filter_string = format!( + r#" + block_transaction_rules: + - Deny: + - Transaction: + Sender: "{}" + - Transaction: + ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Block: + BlockId: "{}" + - Deny: + - Transaction: + Sender: "{}" + - Transaction: + EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000001" + - entry + - check + - Block: + BlockId: "{}" + - Deny: + - Transaction: + Sender: "{}" + - Block: + BlockId: "0000000000000000000000000000000000000000000000000000000000000000" + - Deny: + - Block: + Author: "{}" + - Deny: + - Block: + BlockEpochLessThan: {} + - Allow: + - Transaction: + All + "#, + transactions[0].sender().to_standard_string(), + block_id.to_hex(), + transactions[1].sender().to_standard_string(), + block_id.to_hex(), + transactions[2].sender().to_standard_string(), + malicious_block_author, + block_epoch, + ); + let block_transaction_filter = + serde_yaml::from_str::(&block_transaction_filter_string) + .unwrap(); + + // Verify that the first two transactions are denied in the current block + let filtered_transactions = block_transaction_filter.filter_block_transactions( + block_id, + Some(block_author), + block_epoch, + block_timestamp, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + + // Verify that all transactions are denied in the previous block + let filtered_transactions = block_transaction_filter.filter_block_transactions( + HashValue::random(), + Some(block_author), + block_epoch - 1, + block_timestamp - 1, + transactions.clone(), + ); + assert!(filtered_transactions.is_empty()); + + // Verify that all transactions are allowed in a completely different block + let filtered_transactions = block_transaction_filter.filter_block_transactions( + HashValue::random(), + Some(block_author), + block_epoch + 1, + block_timestamp + 1, + transactions.clone(), + ); + assert_eq!(filtered_transactions, transactions); + + // Verify that all transactions are denied in a block with a malicious author + let filtered_transactions = block_transaction_filter.filter_block_transactions( + HashValue::random(), + Some(malicious_block_author), + block_epoch + 1, + block_timestamp + 1, + transactions.clone(), + ); + assert!(filtered_transactions.is_empty()); + } +} diff --git a/crates/aptos-transaction-filters/src/tests/mod.rs b/crates/aptos-transaction-filters/src/tests/mod.rs new file mode 100644 index 00000000000..5abb829c6b7 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/mod.rs @@ -0,0 +1,10 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +mod batch_transaction_filter; +mod batch_transaction_filter_config; +mod block_transaction_filter; +mod block_transaction_filter_config; +mod transaction_filter; +mod transaction_filter_config; +mod utils; diff --git a/crates/aptos-transaction-filters/src/tests/transaction_filter.rs b/crates/aptos-transaction-filters/src/tests/transaction_filter.rs new file mode 100644 index 00000000000..dadd4a9aa3a --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/transaction_filter.rs @@ -0,0 +1,348 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + tests::utils, + transaction_filter::{TransactionFilter, TransactionMatcher}, +}; + +#[test] +fn test_account_address_filter_simple() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from specific account addresses. + // These are: (i) txn 0 sender; (ii) txn 1 sender; and (iii) txn 2 entry function address. + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_account_address_filter(true, transactions[0].sender()) + .add_account_address_filter(true, transactions[1].sender()) + .add_account_address_filter(true, utils::get_module_address(&transactions[2])) + .add_all_filter(false); + + // Verify that the filter returns transactions from the specified account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..3].to_vec()); + + // Create a filter that denies transactions from the specified account addresses (as above) + let filter = TransactionFilter::empty() + .add_account_address_filter(false, transactions[0].sender()) + .add_account_address_filter(false, transactions[1].sender()) + .add_account_address_filter(false, utils::get_module_address(&transactions[2])) + .add_all_filter(true); + + // Verify that the filter returns transactions from other account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[3..].to_vec()); + } +} + +#[test] +fn test_account_address_filter_multisig() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from specific account addresses. + // These are: (i) txn 0 multisig address; (ii) txn 1 sender; and (iii) txn 2 multisig address. + let transactions = utils::create_multisig_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_account_address_filter(true, utils::get_multisig_address(&transactions[0])) + .add_account_address_filter(true, transactions[1].sender()) + .add_account_address_filter(true, utils::get_multisig_address(&transactions[2])) + .add_all_filter(false); + + // Verify that the filter returns transactions from the specified account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..3].to_vec()); + + // Create a filter that denies transactions from the specified account addresses (as above) + let filter = TransactionFilter::empty() + .add_account_address_filter(false, utils::get_multisig_address(&transactions[0])) + .add_account_address_filter(false, transactions[1].sender()) + .add_account_address_filter(false, utils::get_multisig_address(&transactions[2])) + .add_all_filter(true); + + // Verify that the filter returns transactions from other account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[3..].to_vec()); + } +} + +#[test] +fn test_account_address_filter_script_argument() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from specific account addresses. + // These are: (i) txn 0 script arg address; (ii) txn 1 sender; and (iii) txn 2 script arg address. + let transactions = utils::create_script_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_account_address_filter(true, utils::get_script_argument_address(&transactions[0])) + .add_account_address_filter(true, transactions[1].sender()) + .add_account_address_filter(true, utils::get_script_argument_address(&transactions[2])) + .add_all_filter(false); + + // Verify that the filter returns transactions from the specified account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..3].to_vec()); + + // Create a filter that denies transactions from the specified account addresses (as above) + let filter = TransactionFilter::empty() + .add_account_address_filter(false, utils::get_script_argument_address(&transactions[0])) + .add_account_address_filter(false, transactions[1].sender()) + .add_account_address_filter(false, utils::get_script_argument_address(&transactions[2])) + .add_all_filter(true); + + // Verify that the filter returns transactions from other account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[3..].to_vec()); + } +} + +#[test] +fn test_account_address_filter_transaction_authenticator() { + // Create a filter that only allows transactions from specific account addresses. + // These are: (i) txn 0 account authenticator; (ii) txn 1 account authenticator; and (iii) txn 2 sender. + let transactions = utils::create_fee_payer_transactions(); + let filter = TransactionFilter::empty() + .add_account_address_filter(true, utils::get_fee_payer_address(&transactions[0])) + .add_account_address_filter(true, utils::get_fee_payer_address(&transactions[1])) + .add_account_address_filter(true, transactions[2].sender()) + .add_all_filter(false); + + // Verify that the filter returns transactions from the specified account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..3].to_vec()); + + // Create a filter that denies transactions from the specified account addresses (as above) + let filter = TransactionFilter::empty() + .add_account_address_filter(false, utils::get_fee_payer_address(&transactions[0])) + .add_account_address_filter(false, utils::get_fee_payer_address(&transactions[1])) + .add_account_address_filter(false, transactions[2].sender()) + .add_all_filter(true); + + // Verify that the filter returns transactions from other account addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[3..].to_vec()); +} + +#[test] +fn test_all_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that allows all transactions + let filter = TransactionFilter::empty().add_all_filter(true); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions); + + // Create a filter that denies all transactions + let filter = TransactionFilter::empty().add_all_filter(false); + + // Verify that all transactions are denied + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert!(filtered_transactions.is_empty()); + } +} + +#[test] +fn test_empty_filter() { + for use_new_txn_payload_format in [false, true] { + // Create an empty filter + let filter = TransactionFilter::empty(); + + // Verify that all transactions are allowed + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions); + } +} + +#[test] +fn test_entry_function_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with specific entry functions (txn 0 and txn 1) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_entry_function_filter( + true, + utils::get_module_address(&transactions[0]), + utils::get_module_name(&transactions[0]), + utils::get_function_name(&transactions[0]), + ) + .add_entry_function_filter( + true, + utils::get_module_address(&transactions[1]), + utils::get_module_name(&transactions[1]), + utils::get_function_name(&transactions[1]), + ) + .add_all_filter(false); + + // Verify that the filter returns only transactions with the specified entry functions + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..2].to_vec()); + + // Create a filter that denies transactions with specific entry functions (txn 0) + let filter = TransactionFilter::empty() + .add_entry_function_filter( + false, + utils::get_module_address(&transactions[0]), + utils::get_module_name(&transactions[0]), + utils::get_function_name(&transactions[0]), + ) + .add_all_filter(true); + + // Verify that the filter returns all transactions except those with the specified entry functions + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[1..].to_vec()); + } +} + +#[test] +fn test_module_address_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from a specific module address (txn 0 and txn 1) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_module_address_filter(true, utils::get_module_address(&transactions[0])) + .add_module_address_filter(true, utils::get_module_address(&transactions[1])) + .add_all_filter(false); + + // Verify that the filter returns only transactions from the specified module addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..2].to_vec()); + + // Create a filter that denies transactions from a specific module address (txn 0 and txn 1) + let filter = TransactionFilter::empty() + .add_module_address_filter(false, utils::get_module_address(&transactions[0])) + .add_module_address_filter(false, utils::get_module_address(&transactions[1])) + .add_all_filter(true); + + // Verify that the filter returns all transactions except those from the specified module addresses + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + } +} + +#[test] +fn test_multiple_matchers_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with specific criteria (only txn 1 should match) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let transaction_matchers = vec![ + TransactionMatcher::Sender(transactions[1].sender()), + TransactionMatcher::ModuleAddress(utils::get_module_address(&transactions[1])), + TransactionMatcher::EntryFunction( + utils::get_module_address(&transactions[1]), + utils::get_module_name(&transactions[1]), + utils::get_function_name(&transactions[1]), + ), + ]; + let filter = TransactionFilter::empty() + .add_multiple_matchers_filter(true, transaction_matchers.clone()) + .add_all_filter(false); + + // Verify that the filter returns only transactions that match all specified matchers + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, vec![transactions[1].clone()]); + + // Create a filter that only allows transactions with a specific criteria (none should match) + let transaction_matchers = vec![ + TransactionMatcher::Sender(transactions[0].sender()), + TransactionMatcher::ModuleAddress(utils::get_module_address(&transactions[1])), + TransactionMatcher::ModuleAddress(utils::get_module_address(&transactions[2])), + ]; + let filter = TransactionFilter::empty() + .add_multiple_matchers_filter(true, transaction_matchers) + .add_all_filter(false); + + // Verify that the filter returns no transactions (none should match) + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert!(filtered_transactions.is_empty()); + + // Create a filter that denies transactions with a specific sender and module address (txn 0) + let transaction_matchers = vec![ + TransactionMatcher::Sender(transactions[0].sender()), + TransactionMatcher::ModuleAddress(utils::get_module_address(&transactions[0])), + ]; + let filter = TransactionFilter::empty() + .add_multiple_matchers_filter(false, transaction_matchers) + .add_all_filter(true); + + // Verify that it returns all transactions except those with the specified sender and module address + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[1..].to_vec()); + } +} + +#[test] +fn test_public_key_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from specific public keys. + // These are: (i) txn 0 authenticator public key; and (ii) txn 1 authenticator public key. + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_public_key_filter(true, utils::get_auth_public_key(&transactions[0])) + .add_public_key_filter(true, utils::get_auth_public_key(&transactions[1])) + .add_all_filter(false); + + // Verify that the filter returns transactions with the specified public keys + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..2].to_vec()); + + // Create a filter that denies transactions from the specified public keys (as above) + let filter = TransactionFilter::empty() + .add_public_key_filter(false, utils::get_auth_public_key(&transactions[0])) + .add_public_key_filter(false, utils::get_auth_public_key(&transactions[1])) + .add_all_filter(true); + + // Verify that it returns transactions from other public keys + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + } +} + +#[test] +fn test_sender_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions from a specific sender (txn 0 and txn 1) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_sender_filter(true, transactions[0].sender()) + .add_sender_filter(true, transactions[1].sender()) + .add_all_filter(false); + + // Verify that the filter returns only transactions from the specified senders + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..2].to_vec()); + + // Create a filter that denies transactions from a specific sender (txn 0 and txn 1) + let filter = TransactionFilter::empty() + .add_sender_filter(false, transactions[0].sender()) + .add_sender_filter(false, transactions[1].sender()) + .add_all_filter(true); + + // Verify that the filter returns all transactions except those from the specified senders + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[2..].to_vec()); + } +} + +#[test] +fn test_transaction_id_filter() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions with a specific transaction ID (txn 0) + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let filter = TransactionFilter::empty() + .add_transaction_id_filter(true, transactions[0].committed_hash()) + .add_all_filter(false); + + // Verify that the filter returns only the transaction with the specified ID + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, vec![transactions[0].clone()]); + + // Create a filter that denies transactions with a specific transaction ID (txn 0) + let filter = TransactionFilter::empty() + .add_transaction_id_filter(false, transactions[0].committed_hash()) + .add_all_filter(true); + + // Verify that the filter returns all transactions except the one with the specified ID + let filtered_transactions = filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[1..].to_vec()); + } +} diff --git a/crates/aptos-transaction-filters/src/tests/transaction_filter_config.rs b/crates/aptos-transaction-filters/src/tests/transaction_filter_config.rs new file mode 100644 index 00000000000..4a6442dd092 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/transaction_filter_config.rs @@ -0,0 +1,120 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{tests::utils, transaction_filter::TransactionFilter}; + +#[test] +fn test_transaction_filter_config_allow() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that only allows transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let transaction_filter_string = format!( + r#" + transaction_rules: + - Allow: + - Sender: "{}" + - Allow: + - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" + - Allow: + - PublicKey: + Ed25519: + - "{}" + - Allow: + - EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000003" + - entry + - sub + - Allow: + - AccountAddress: "{}" + - Deny: + - All + "#, + transactions[0].sender().to_standard_string(), + utils::get_ed25519_public_key(&transactions[2]), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let transaction_filter = + serde_yaml::from_str::(&transaction_filter_string).unwrap(); + + // Verify that only the first five transactions are allowed + let filtered_transactions = transaction_filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[0..5].to_vec()); + } +} + +#[test] +fn test_transaction_filter_config_deny() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that denies transactions based on multiple criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let transaction_filter_string = format!( + r#" + transaction_rules: + - Deny: + - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Deny: + - Sender: "{}" + - Deny: + - EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000002" + - entry + - new + - Deny: + - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000003" + - Deny: + - AccountAddress: "{}" + - Allow: + - All + "#, + transactions[1].sender().to_standard_string(), + utils::get_module_address(&transactions[4]).to_standard_string(), + ); + let transaction_filter = + serde_yaml::from_str::(&transaction_filter_string).unwrap(); + + // Verify that the first five transactions are denied + let filtered_transactions = transaction_filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[5..].to_vec()); + } +} + +#[test] +fn test_transaction_filter_config_multiple_matchers() { + for use_new_txn_payload_format in [false, true] { + // Create a filter that denies transactions based on multiple matching criteria + let transactions = utils::create_entry_function_transactions(use_new_txn_payload_format); + let transaction_filter_string = format!( + r#" + transaction_rules: + - Deny: + - Sender: "{}" + - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000000" + - Deny: + - Sender: "{}" + - ModuleAddress: "0000000000000000000000000000000000000000000000000000000000000001" + - Deny: + - Sender: "{}" + - EntryFunction: + - "0000000000000000000000000000000000000000000000000000000000000002" + - entry + - new + - Deny: + - Sender: "{}" + - AccountAddress: "{}" + - Allow: + - All + "#, + transactions[0].sender().to_standard_string(), + transactions[1].sender().to_standard_string(), + transactions[2].sender().to_standard_string(), + transactions[3].sender().to_standard_string(), + utils::get_module_address(&transactions[3]).to_standard_string(), + ); + let transaction_filter = + serde_yaml::from_str::(&transaction_filter_string).unwrap(); + + // Verify that the first four transactions are denied + let filtered_transactions = transaction_filter.filter_transactions(transactions.clone()); + assert_eq!(filtered_transactions, transactions[4..].to_vec()); + } +} diff --git a/crates/aptos-transaction-filters/src/tests/utils.rs b/crates/aptos-transaction-filters/src/tests/utils.rs new file mode 100644 index 00000000000..91745b78920 --- /dev/null +++ b/crates/aptos-transaction-filters/src/tests/utils.rs @@ -0,0 +1,344 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::tests::utils; +use aptos_crypto::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}, + HashValue, PrivateKey, SigningKey, Uniform, +}; +use aptos_types::{ + chain_id::ChainId, + move_utils::MemberId, + quorum_store::BatchId, + transaction::{ + authenticator::{AccountAuthenticator, AnyPublicKey, TransactionAuthenticator}, + EntryFunction, Multisig, MultisigTransactionPayload, RawTransaction, Script, + SignedTransaction, TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig, + TransactionPayload, TransactionPayloadInner, + }, + PeerId, +}; +use move_core_types::{account_address::AccountAddress, transaction_argument::TransactionArgument}; +use rand::{rngs::OsRng, thread_rng, Rng}; + +/// Creates and returns an account authenticator with the given public key +pub fn create_account_authenticator(public_key: Ed25519PublicKey) -> AccountAuthenticator { + AccountAuthenticator::Ed25519 { + public_key, + signature: Ed25519Signature::dummy_signature(), + } +} + +/// Creates and returns an entry function with the given member ID +pub fn create_entry_function(function: MemberId) -> EntryFunction { + let MemberId { + module_id, + member_id: function_id, + } = function; + EntryFunction::new(module_id, function_id, vec![], vec![]) +} + +/// Creates and returns a signed transaction with an entry function payload +pub fn create_entry_function_transaction( + function: MemberId, + use_new_txn_payload_format: bool, +) -> SignedTransaction { + let entry_function = create_entry_function(function); + let transaction_payload = if use_new_txn_payload_format { + // Use the new payload format + let executable = TransactionExecutable::EntryFunction(entry_function); + let extra_config = TransactionExtraConfig::V1 { + multisig_address: None, + replay_protection_nonce: None, + }; + TransactionPayload::Payload(TransactionPayloadInner::V1 { + executable, + extra_config, + }) + } else { + // Use the old payload format + TransactionPayload::EntryFunction(entry_function) + }; + + create_signed_transaction(transaction_payload, false) +} + +/// Creates and returns a list of signed entry function transactions +pub fn create_entry_function_transactions( + use_new_txn_payload_format: bool, +) -> Vec { + let mut entry_function_txns = vec![]; + + for (i, function_name) in [ + "add", "check", "new", "sub", "mul", "div", "mod", "pow", "exp", "sqrt", + ] + .iter() + .enumerate() + { + let transaction = create_entry_function_transaction( + str::parse(&format!("0x{}::entry::{}", i, function_name)).unwrap(), + use_new_txn_payload_format, + ); + entry_function_txns.push(transaction); + } + + entry_function_txns +} + +/// Creates and returns a signed fee payer transaction +pub fn create_fee_payer_transaction() -> SignedTransaction { + let entry_function = create_entry_function(str::parse("0x0::fee_payer::pay").unwrap()); + let transaction_payload = TransactionPayload::EntryFunction(entry_function); + + create_signed_transaction(transaction_payload, true) +} + +/// Creates and returns a list of signed fee payer transactions +pub fn create_fee_payer_transactions() -> Vec { + let mut fee_payer_transactions = vec![]; + + for _ in 0..10 { + let transaction = create_fee_payer_transaction(); + fee_payer_transactions.push(transaction) + } + + fee_payer_transactions +} + +/// Creates and returns a multisig transaction with the given multisig address and function +pub fn create_multisig_transaction( + multisig_address: AccountAddress, + function: MemberId, + use_new_txn_payload_format: bool, +) -> SignedTransaction { + let transaction_payload = if use_new_txn_payload_format { + // Use the new payload format + let executable = TransactionExecutable::EntryFunction(create_entry_function(function)); + let extra_config = TransactionExtraConfig::V1 { + multisig_address: Some(multisig_address), + replay_protection_nonce: None, + }; + TransactionPayload::Payload(TransactionPayloadInner::V1 { + executable, + extra_config, + }) + } else { + // Use the old payload format + TransactionPayload::Multisig(Multisig { + multisig_address, + transaction_payload: Some(MultisigTransactionPayload::EntryFunction( + create_entry_function(function), + )), + }) + }; + + create_signed_transaction(transaction_payload, false) +} + +/// Creates and returns a list of signed multisig transactions +pub fn create_multisig_transactions(use_new_txn_payload_format: bool) -> Vec { + let mut multisig_transactions = vec![]; + + for i in 0..10 { + let transaction = create_multisig_transaction( + AccountAddress::random(), + str::parse(&format!("0x{}::multisig::sign", i)).unwrap(), + use_new_txn_payload_format, + ); + multisig_transactions.push(transaction); + } + + multisig_transactions +} + +/// Creates and returns a signed transaction with the given payload and fee payer +pub fn create_signed_transaction( + transaction_payload: TransactionPayload, + fee_payer: bool, +) -> SignedTransaction { + let sender = AccountAddress::random(); + let sequence_number = 0; + let raw_transaction = RawTransaction::new( + sender, + sequence_number, + transaction_payload, + 0, + 0, + 0, + ChainId::new(10), + ); + + let private_key = Ed25519PrivateKey::generate(&mut thread_rng()); + let public_key = private_key.public_key(); + + if fee_payer { + SignedTransaction::new_fee_payer( + raw_transaction.clone(), + create_account_authenticator(public_key.clone()), + vec![], + vec![], + AccountAddress::random(), + create_account_authenticator(public_key.clone()), + ) + } else { + SignedTransaction::new( + raw_transaction.clone(), + public_key.clone(), + private_key.sign(&raw_transaction).unwrap(), + ) + } +} + +/// Creates and returns a script transaction with the given payload +pub fn create_script_transaction(use_new_txn_payload_format: bool) -> SignedTransaction { + let script_arguments = vec![ + TransactionArgument::U64(0), + TransactionArgument::U128(0), + TransactionArgument::Address(AccountAddress::random()), + TransactionArgument::Bool(true), + ]; + let script = Script::new(vec![], vec![], script_arguments); + + let transaction_payload = if use_new_txn_payload_format { + // Use the new payload format + let executable = TransactionExecutable::Script(script); + let extra_config = TransactionExtraConfig::V1 { + multisig_address: None, + replay_protection_nonce: None, + }; + TransactionPayload::Payload(TransactionPayloadInner::V1 { + executable, + extra_config, + }) + } else { + // Use the old payload format + TransactionPayload::Script(script) + }; + + create_signed_transaction(transaction_payload, false) +} + +/// Creates and returns a list of signed script transactions +pub fn create_script_transactions(use_new_txn_payload_format: bool) -> Vec { + let mut script_transactions = vec![]; + + for _ in 0..10 { + let transaction = create_script_transaction(use_new_txn_payload_format); + script_transactions.push(transaction); + } + + script_transactions +} + +/// Returns the first address argument of the given script +pub fn get_address_argument(script: &Script) -> AccountAddress { + for arg in script.args() { + if let TransactionArgument::Address(address) = arg { + return *address; + } + } + panic!("No address argument found in script transaction"); +} + +/// Returns the public key of the authenticator of the given transaction +pub fn get_auth_public_key(signed_transaction: &SignedTransaction) -> AnyPublicKey { + match signed_transaction.authenticator() { + TransactionAuthenticator::Ed25519 { public_key, .. } => AnyPublicKey::ed25519(public_key), + authenticator => panic!("Unexpected transaction authenticator: {:?}", authenticator), + } +} + +/// Returns the Ed25519 public key of the authenticator of the given transaction +pub fn get_ed25519_public_key(signed_transaction: &SignedTransaction) -> Ed25519PublicKey { + match signed_transaction.authenticator() { + TransactionAuthenticator::Ed25519 { public_key, .. } => public_key.clone(), + authenticator => panic!("Unexpected transaction authenticator: {:?}", authenticator), + } +} + +/// Returns the fee payer address of the given transaction +pub fn get_fee_payer_address(signed_transaction: &SignedTransaction) -> AccountAddress { + match signed_transaction.authenticator() { + TransactionAuthenticator::FeePayer { + fee_payer_address, .. + } => fee_payer_address, + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} + +/// Returns the function name of the given transaction +pub fn get_function_name(txn: &SignedTransaction) -> String { + match txn.payload().executable_ref() { + Ok(TransactionExecutableRef::EntryFunction(entry_func)) => { + entry_func.function().to_string() + }, + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} + +/// Returns the module address of the given transaction +pub fn get_module_address(txn: &SignedTransaction) -> AccountAddress { + match txn.payload().executable_ref() { + Ok(TransactionExecutableRef::EntryFunction(entry_func)) => *entry_func.module().address(), + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} + +/// Returns the module name of the given transaction +pub fn get_module_name(txn: &SignedTransaction) -> String { + match txn.payload().executable_ref() { + Ok(TransactionExecutableRef::EntryFunction(entry_func)) => { + entry_func.module().name().to_string() + }, + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} + +/// Returns the multisig address of the given transaction +pub fn get_multisig_address(txn: &SignedTransaction) -> AccountAddress { + match txn.payload() { + TransactionPayload::Multisig(multisig) => multisig.multisig_address, + TransactionPayload::Payload(TransactionPayloadInner::V1 { + extra_config: + TransactionExtraConfig::V1 { + multisig_address, .. + }, + .. + }) => multisig_address.expect("Expected multisig address!"), + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} + +/// Creates and returns a random batch ID, author, and digest. +pub fn get_random_batch_info() -> (BatchId, PeerId, HashValue) { + let batch_id = BatchId::new_for_test(get_random_u64()); + let batch_author = PeerId::random(); + let batch_digest = HashValue::random(); + (batch_id, batch_author, batch_digest) +} + +/// Creates and returns a random block ID, author, epoch, and timestamp. +pub fn get_random_block_info() -> (HashValue, AccountAddress, u64, u64) { + let block_id = HashValue::random(); + let block_author = AccountAddress::random(); + let block_epoch = utils::get_random_u64(); + let block_timestamp = utils::get_random_u64(); + (block_id, block_author, block_epoch, block_timestamp) +} + +/// Generates and returns a random number (u64) +pub fn get_random_u64() -> u64 { + OsRng.r#gen() +} + +/// Returns the script argument address of the given transaction +pub fn get_script_argument_address(txn: &SignedTransaction) -> AccountAddress { + match txn.payload() { + TransactionPayload::Script(script) => get_address_argument(script), + TransactionPayload::Payload(TransactionPayloadInner::V1 { + executable: TransactionExecutable::Script(script), + .. + }) => get_address_argument(script), + payload => panic!("Unexpected transaction payload: {:?}", payload), + } +} diff --git a/crates/aptos-transaction-filters/src/transaction_filter.rs b/crates/aptos-transaction-filters/src/transaction_filter.rs new file mode 100644 index 00000000000..8dd8948e087 --- /dev/null +++ b/crates/aptos-transaction-filters/src/transaction_filter.rs @@ -0,0 +1,987 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::{ed25519::Ed25519PublicKey, HashValue}; +use aptos_types::transaction::{ + authenticator::{AccountAuthenticator, AnyPublicKey, TransactionAuthenticator}, + EntryFunction, MultisigTransactionPayload, Script, SignedTransaction, TransactionExecutableRef, + TransactionExtraConfig, TransactionPayload, TransactionPayloadInner, +}; +use move_core_types::{account_address::AccountAddress, transaction_argument::TransactionArgument}; +use serde::{Deserialize, Serialize}; + +/// A transaction filter that applies a set of rules to determine +/// if a transaction should be allowed or denied. +/// +/// Rules are applied in the order they are defined, and the first +/// matching rule determines the outcome for the transaction. +/// If no rules match, the transaction is allowed by default. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct TransactionFilter { + transaction_rules: Vec, +} + +impl TransactionFilter { + pub fn new(transaction_rules: Vec) -> Self { + Self { transaction_rules } + } + + /// Returns true iff the filter allows the transaction + pub fn allows_transaction(&self, signed_transaction: &SignedTransaction) -> bool { + // If the filter is empty, allow the transaction by default + if self.is_empty() { + return true; + } + + // Check if any rule matches the transaction + for transaction_rule in &self.transaction_rules { + if transaction_rule.matches(signed_transaction) { + return match transaction_rule { + TransactionRule::Allow(_) => true, + TransactionRule::Deny(_) => false, + }; + } + } + + true // No rules match (allow the transaction by default) + } + + /// Returns an empty transaction filter with no rules + pub fn empty() -> Self { + Self { + transaction_rules: Vec::new(), + } + } + + /// Filters the given transactions and returns only those that are allowed + pub fn filter_transactions( + &self, + transactions: Vec, + ) -> Vec { + transactions + .into_iter() + .filter(|txn| self.allows_transaction(txn)) + .collect() + } + + /// Returns true iff the filter is empty (i.e., has no rules) + pub fn is_empty(&self) -> bool { + self.transaction_rules.is_empty() + } + + /// Adds an all matcher to the filter (matching all transactions) + pub fn add_all_filter(self, allow: bool) -> Self { + let transaction_matcher = TransactionMatcher::All; + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds a filter rule containing multiple matchers + pub fn add_multiple_matchers_filter( + mut self, + allow: bool, + transaction_matchers: Vec, + ) -> Self { + let transaction_rule = if allow { + TransactionRule::Allow(transaction_matchers) + } else { + TransactionRule::Deny(transaction_matchers) + }; + self.transaction_rules.push(transaction_rule); + + self + } +} + +// These are useful test-only methods for creating and testing filters +#[cfg(any(test, feature = "fuzzing"))] +impl TransactionFilter { + /// Adds an account address matcher to the filter + pub fn add_account_address_filter(self, allow: bool, account_address: AccountAddress) -> Self { + let transaction_matcher = TransactionMatcher::AccountAddress(account_address); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds an entry function matcher to the filter + pub fn add_entry_function_filter( + self, + allow: bool, + address: AccountAddress, + module_name: String, + function: String, + ) -> Self { + let transaction_matcher = TransactionMatcher::EntryFunction(address, module_name, function); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds a module address matcher to the filter + pub fn add_module_address_filter(self, allow: bool, address: AccountAddress) -> Self { + let transaction_matcher = TransactionMatcher::ModuleAddress(address); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds a public key matcher to the filter + pub fn add_public_key_filter(self, allow: bool, public_key: AnyPublicKey) -> Self { + let transaction_matcher = TransactionMatcher::PublicKey(public_key); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds a sender address matcher to the filter + pub fn add_sender_filter(self, allow: bool, sender: AccountAddress) -> Self { + let transaction_matcher = TransactionMatcher::Sender(sender); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } + + /// Adds a transaction ID matcher to the filter + pub fn add_transaction_id_filter(self, allow: bool, txn_id: HashValue) -> Self { + let transaction_matcher = TransactionMatcher::TransactionId(txn_id); + self.add_multiple_matchers_filter(allow, vec![transaction_matcher]) + } +} + +/// A transaction rule that defines whether to allow or deny transactions +/// based on a set of matchers. All matchers must match for the rule to apply. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum TransactionRule { + Allow(Vec), + Deny(Vec), +} + +impl TransactionRule { + /// Returns true iff the rule matches the given transaction. This + /// requires that all matchers in the rule match the transaction. + fn matches(&self, signed_transaction: &SignedTransaction) -> bool { + let transaction_matchers = match self { + TransactionRule::Allow(matchers) => matchers, + TransactionRule::Deny(matchers) => matchers, + }; + transaction_matchers + .iter() + .all(|matcher| matcher.matches(signed_transaction)) + } +} + +/// A matcher that defines the criteria for matching transactions +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum TransactionMatcher { + All, // Matches any transaction + TransactionId(HashValue), // Matches a specific transaction by its ID + Sender(AccountAddress), // Matches any transaction sent by a specific account address + ModuleAddress(AccountAddress), // Matches any transaction that calls a module at a specific address + EntryFunction(AccountAddress, String, String), // Matches any transaction that calls a specific entry function in a module + AccountAddress(AccountAddress), // Matches any transaction that involves a specific account address + PublicKey(AnyPublicKey), // Matches any transaction that involves a specific public key +} + +impl TransactionMatcher { + /// Returns true iff the matcher matches the given transaction + pub(crate) fn matches(&self, signed_transaction: &SignedTransaction) -> bool { + match self { + TransactionMatcher::All => true, + TransactionMatcher::TransactionId(id) => signed_transaction.committed_hash() == *id, + TransactionMatcher::Sender(sender) => { + matches_sender_address(signed_transaction, sender) + }, + TransactionMatcher::ModuleAddress(address) => { + matches_entry_function_module_address(signed_transaction, address) + }, + TransactionMatcher::EntryFunction(address, module_name, function) => { + matches_entry_function(signed_transaction, address, module_name, function) + }, + TransactionMatcher::AccountAddress(address) => { + matches_sender_address(signed_transaction, address) + || matches_entry_function_module_address(signed_transaction, address) + || matches_multisig_address(signed_transaction, address) + || matches_script_argument_address(signed_transaction, address) + || matches_transaction_authenticator_address(signed_transaction, address) + }, + TransactionMatcher::PublicKey(public_key) => { + matches_transaction_authenticator_public_key(signed_transaction, public_key) + }, + } + } +} + +/// Returns true iff the Ed25519 public key matches the given AnyPublicKey +fn compare_ed25519_public_key( + ed25519_public_key: &Ed25519PublicKey, + any_public_key: &AnyPublicKey, +) -> bool { + if let AnyPublicKey::Ed25519 { public_key } = any_public_key { + ed25519_public_key == public_key + } else { + false + } +} + +/// Returns true iff the entry function's module address, name, and function name +/// match the given account address, module name, and function name. +fn compare_entry_function( + entry_function: &EntryFunction, + address: &AccountAddress, + module_name: &String, + function_name: &String, +) -> bool { + entry_function.module().address() == address + && entry_function.module().name().to_string() == *module_name + && entry_function.function().to_string() == *function_name +} + +/// Returns true iff the entry function's module address matches the given account address +fn compare_entry_function_module_address( + entry_function: &EntryFunction, + address: &AccountAddress, +) -> bool { + entry_function.module().address() == address +} + +/// Returns true iff the script's arguments contain the given account address +fn compare_script_argument_address(script: &Script, address: &AccountAddress) -> bool { + script.args().iter().any(|transaction_argument| { + if let TransactionArgument::Address(argument_address) = transaction_argument { + argument_address == address + } else { + false + } + }) +} + +/// Returns true iff the account authenticator contains the given account address +fn matches_account_authenticator_address( + account_authenticator: &AccountAuthenticator, + address: &AccountAddress, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match account_authenticator { + AccountAuthenticator::Ed25519 { .. } + | AccountAuthenticator::MultiEd25519 { .. } + | AccountAuthenticator::NoAccountAuthenticator => false, + AccountAuthenticator::SingleKey { authenticator } => { + matches_any_public_key_address(authenticator.public_key(), address) + }, + AccountAuthenticator::MultiKey { authenticator } => authenticator + .public_keys() + .public_keys() + .iter() + .any(|any_public_key| matches_any_public_key_address(any_public_key, address)), + AccountAuthenticator::Abstract { authenticator } => { + authenticator.function_info().module_address == *address + }, + } +} + +/// Returns true iff the account authenticator contains the given public key +fn matches_account_authenticator_public_key( + account_authenticator: &AccountAuthenticator, + any_public_key: &AnyPublicKey, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match account_authenticator { + AccountAuthenticator::NoAccountAuthenticator | AccountAuthenticator::Abstract { .. } => { + false + }, + AccountAuthenticator::Ed25519 { public_key, .. } => { + compare_ed25519_public_key(public_key, any_public_key) + }, + AccountAuthenticator::MultiEd25519 { public_key, .. } => { + public_key.public_keys().iter().any(|ed25519_public_key| { + compare_ed25519_public_key(ed25519_public_key, any_public_key) + }) + }, + AccountAuthenticator::SingleKey { authenticator } => { + authenticator.public_key() == any_public_key + }, + AccountAuthenticator::MultiKey { authenticator } => authenticator + .public_keys() + .public_keys() + .iter() + .any(|key| key == any_public_key), + } +} + +/// Returns true iff the public key contains the given account address +fn matches_any_public_key_address(any_public_key: &AnyPublicKey, address: &AccountAddress) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match any_public_key { + AnyPublicKey::Ed25519 { .. } + | AnyPublicKey::Secp256k1Ecdsa { .. } + | AnyPublicKey::Secp256r1Ecdsa { .. } + | AnyPublicKey::Keyless { .. } => false, + AnyPublicKey::FederatedKeyless { public_key } => { + // Check if the public key's JWK address matches the given address + public_key.jwk_addr == *address + }, + } +} + +/// Returns true iff the transaction's entry function matches the given account address, module name, and function name +fn matches_entry_function( + signed_transaction: &SignedTransaction, + address: &AccountAddress, + module_name: &String, + function: &String, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.payload() { + TransactionPayload::Script(_) | TransactionPayload::ModuleBundle(_) => false, + TransactionPayload::Multisig(multisig) => multisig + .transaction_payload + .as_ref() + .map(|payload| match payload { + MultisigTransactionPayload::EntryFunction(entry_function) => { + compare_entry_function(entry_function, address, module_name, function) + }, + }) + .unwrap_or(false), + TransactionPayload::EntryFunction(entry_function) => { + compare_entry_function(entry_function, address, module_name, function) + }, + TransactionPayload::Payload(TransactionPayloadInner::V1 { executable, .. }) => { + match executable.as_ref() { + TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false, + TransactionExecutableRef::EntryFunction(entry_function) => { + compare_entry_function(entry_function, address, module_name, function) + }, + } + }, + TransactionPayload::EncryptedPayload(payload) => { + if let Ok(executable) = payload.executable_ref() { + match executable { + TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false, + TransactionExecutableRef::EntryFunction(entry_function) => { + compare_entry_function(entry_function, address, module_name, function) + }, + } + } else { + false + } + }, + } +} + +/// Returns true iff the transaction's module address matches the given account address +fn matches_entry_function_module_address( + signed_transaction: &SignedTransaction, + module_address: &AccountAddress, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.payload() { + TransactionPayload::Script(_) | TransactionPayload::ModuleBundle(_) => false, + TransactionPayload::Multisig(multisig) => multisig + .transaction_payload + .as_ref() + .map(|payload| match payload { + MultisigTransactionPayload::EntryFunction(entry_function) => { + compare_entry_function_module_address(entry_function, module_address) + }, + }) + .unwrap_or(false), + TransactionPayload::EntryFunction(entry_function) => { + compare_entry_function_module_address(entry_function, module_address) + }, + TransactionPayload::Payload(TransactionPayloadInner::V1 { executable, .. }) => { + match executable.as_ref() { + TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false, + TransactionExecutableRef::EntryFunction(entry_function) => { + compare_entry_function_module_address(entry_function, module_address) + }, + } + }, + TransactionPayload::EncryptedPayload(payload) => { + if let Ok(executable) = payload.executable_ref() { + match executable { + TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false, + TransactionExecutableRef::EntryFunction(entry_function) => { + compare_entry_function_module_address(entry_function, module_address) + }, + } + } else { + false + } + }, + } +} + +/// Returns true iff the transaction's multisig address matches the given account address +fn matches_multisig_address( + signed_transaction: &SignedTransaction, + address: &AccountAddress, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.payload() { + TransactionPayload::EntryFunction(_) + | TransactionPayload::Script(_) + | TransactionPayload::ModuleBundle(_) => false, + TransactionPayload::Multisig(multisig) => multisig.multisig_address == *address, + TransactionPayload::Payload(TransactionPayloadInner::V1 { extra_config, .. }) => { + match extra_config { + TransactionExtraConfig::V1 { + multisig_address, .. + } => multisig_address + .map(|multisig_address| multisig_address == *address) + .unwrap_or(false), + } + }, + TransactionPayload::EncryptedPayload(payload) => match payload.extra_config() { + TransactionExtraConfig::V1 { + multisig_address, .. + } => multisig_address + .map(|multisig_address| multisig_address == *address) + .unwrap_or(false), + }, + } +} + +/// Returns true iff a script argument matches the given account address +fn matches_script_argument_address( + signed_transaction: &SignedTransaction, + address: &AccountAddress, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.payload() { + TransactionPayload::EntryFunction(_) + | TransactionPayload::Multisig(_) + | TransactionPayload::ModuleBundle(_) => false, + TransactionPayload::Script(script) => compare_script_argument_address(script, address), + TransactionPayload::Payload(TransactionPayloadInner::V1 { executable, .. }) => { + match executable.as_ref() { + TransactionExecutableRef::EntryFunction(_) | TransactionExecutableRef::Empty => { + false + }, + TransactionExecutableRef::Script(script) => { + compare_script_argument_address(script, address) + }, + } + }, + TransactionPayload::EncryptedPayload(payload) => { + if let Ok(executable) = payload.executable_ref() { + match executable { + TransactionExecutableRef::EntryFunction(_) + | TransactionExecutableRef::Empty => false, + TransactionExecutableRef::Script(script) => { + compare_script_argument_address(script, address) + }, + } + } else { + false + } + }, + } +} + +/// Returns true iff the transaction's sender matches the given account address +fn matches_sender_address(signed_transaction: &SignedTransaction, sender: &AccountAddress) -> bool { + signed_transaction.sender() == *sender +} + +/// Returns true iff the transaction's authenticator contains the given account address +fn matches_transaction_authenticator_address( + signed_transaction: &SignedTransaction, + address: &AccountAddress, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.authenticator_ref() { + TransactionAuthenticator::Ed25519 { .. } + | TransactionAuthenticator::MultiEd25519 { .. } => false, + TransactionAuthenticator::MultiAgent { + sender, + secondary_signer_addresses, + secondary_signers, + } => { + matches_account_authenticator_address(sender, address) + || secondary_signer_addresses.contains(address) + || secondary_signers + .iter() + .any(|signer| matches_account_authenticator_address(signer, address)) + }, + TransactionAuthenticator::FeePayer { + sender, + secondary_signer_addresses, + secondary_signers, + fee_payer_address, + fee_payer_signer, + } => { + matches_account_authenticator_address(sender, address) + || secondary_signer_addresses.contains(address) + || secondary_signers + .iter() + .any(|signer| matches_account_authenticator_address(signer, address)) + || fee_payer_address == address + || matches_account_authenticator_address(fee_payer_signer, address) + }, + TransactionAuthenticator::SingleSender { sender } => { + matches_account_authenticator_address(sender, address) + }, + } +} + +/// Returns true iff the transaction's authenticator contains the given public key +fn matches_transaction_authenticator_public_key( + signed_transaction: &SignedTransaction, + any_public_key: &AnyPublicKey, +) -> bool { + // Match all variants explicitly to ensure future enum changes are caught during compilation + match signed_transaction.authenticator_ref() { + TransactionAuthenticator::Ed25519 { public_key, .. } => { + compare_ed25519_public_key(public_key, any_public_key) + }, + TransactionAuthenticator::MultiEd25519 { public_key, .. } => { + public_key.public_keys().iter().any(|ed25519_public_key| { + compare_ed25519_public_key(ed25519_public_key, any_public_key) + }) + }, + TransactionAuthenticator::MultiAgent { + sender, + secondary_signers, + .. + } => { + matches_account_authenticator_public_key(sender, any_public_key) + || secondary_signers + .iter() + .any(|signer| matches_account_authenticator_public_key(signer, any_public_key)) + }, + TransactionAuthenticator::FeePayer { + sender, + secondary_signers, + fee_payer_signer, + .. + } => { + matches_account_authenticator_public_key(sender, any_public_key) + || secondary_signers + .iter() + .any(|signer| matches_account_authenticator_public_key(signer, any_public_key)) + || matches_account_authenticator_public_key(fee_payer_signer, any_public_key) + }, + TransactionAuthenticator::SingleSender { sender } => { + matches_account_authenticator_public_key(sender, any_public_key) + }, + } +} + +#[cfg(test)] +mod test { + use super::*; + use aptos_crypto::{ + ed25519::Ed25519PrivateKey, + multi_ed25519::{MultiEd25519PublicKey, MultiEd25519Signature}, + secp256k1_ecdsa, secp256r1_ecdsa, PrivateKey, SigningKey, Uniform, + }; + use aptos_types::{ + chain_id::ChainId, + function_info::FunctionInfo, + keyless::test_utils::get_sample_groth16_sig_and_pk, + transaction::{ + authenticator::{AnySignature, SingleKeyAuthenticator}, + RawTransaction, + }, + }; + use rand::thread_rng; + + #[test] + fn test_matches_account_authenticator_address() { + // Create an empty account authenticator + let account_authenticator = AccountAuthenticator::NoAccountAuthenticator; + + // Verify that the authenticator doesn't match the target address + let target_address = AccountAddress::random(); + verify_matches_account_auth_address(&account_authenticator, &target_address, false); + + // Create an Ed25519 account authenticator + let raw_transaction = create_raw_transaction(); + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = private_key.public_key(); + let signature = private_key.sign(&raw_transaction).unwrap(); + let account_authenticator = AccountAuthenticator::Ed25519 { + public_key: public_key.clone(), + signature: signature.clone(), + }; + + // Verify that the authenticator doesn't match the target address + verify_matches_account_auth_address(&account_authenticator, &target_address, false); + + // Create a MultiEd25519 account authenticator + let multi_public_key = MultiEd25519PublicKey::new(vec![public_key], 1).unwrap(); + let multi_signature = MultiEd25519Signature::from(signature); + let account_authenticator = AccountAuthenticator::MultiEd25519 { + public_key: multi_public_key, + signature: multi_signature, + }; + + // Verify that the authenticator doesn't match the target address + verify_matches_account_auth_address(&account_authenticator, &target_address, false); + + // Create an Abstraction account authenticator (with the target address as the module address) + let function_info = FunctionInfo::new(target_address, "".into(), "".into()); + let account_authenticator = + AccountAuthenticator::abstraction(function_info, vec![], vec![]); + + // Verify that the authenticator matches the target address + verify_matches_account_auth_address(&account_authenticator, &target_address, true); + } + + #[test] + fn test_matches_any_public_key_address() { + // Create an Ed25519 public key + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = AnyPublicKey::ed25519(private_key.public_key()); + + // Verify that the public key doesn't match the target address + let target_address = AccountAddress::random(); + verify_matches_public_key_address(&public_key, &target_address, false); + + // Create a Secp256k1Ecdsa public key + let private_key = secp256k1_ecdsa::PrivateKey::generate_for_testing(); + let public_key = AnyPublicKey::secp256k1_ecdsa(private_key.public_key()); + + // Verify that the public key doesn't match the target address + verify_matches_public_key_address(&public_key, &target_address, false); + + // Create a Secp256r1Ecdsa public key + let private_key = secp256r1_ecdsa::PrivateKey::generate_for_testing(); + let public_key = AnyPublicKey::secp256r1_ecdsa(private_key.public_key()); + + // Verify that the public key doesn't match the target address + verify_matches_public_key_address(&public_key, &target_address, false); + + // Create a Keyless public key + let (_, keyless_public_key) = get_sample_groth16_sig_and_pk(); + let public_key = AnyPublicKey::keyless(keyless_public_key.clone()); + + // Verify that the public key doesn't match the target address + verify_matches_public_key_address(&public_key, &target_address, false); + + // Create a FederatedKeyless public key with the target address as the JWK address + let federated_keyless_public_key = aptos_types::keyless::FederatedKeylessPublicKey { + jwk_addr: target_address, + pk: keyless_public_key, + }; + let public_key = AnyPublicKey::federated_keyless(federated_keyless_public_key); + + // Verify that the public key matches the target address + verify_matches_public_key_address(&public_key, &target_address, true); + } + + #[test] + fn test_matches_transaction_authenticator_address() { + // Create an Ed25519 transaction authenticator + let raw_transaction = create_raw_transaction(); + let private_key = Ed25519PrivateKey::generate_for_testing(); + let signature = private_key.sign(&raw_transaction).unwrap(); + let signed_transaction = SignedTransaction::new( + raw_transaction.clone(), + private_key.public_key(), + signature.clone(), + ); + + // Verify that the authenticator doesn't match the target address + let target_address = AccountAddress::random(); + verify_matches_transaction_auth_address(&signed_transaction, &target_address, false); + + // Create a MultiEd25519 transaction authenticator + let multi_public_key = + MultiEd25519PublicKey::new(vec![private_key.public_key()], 1).unwrap(); + let multi_signature = MultiEd25519Signature::from(signature); + let signed_transaction = SignedTransaction::new_multisig( + raw_transaction.clone(), + multi_public_key, + multi_signature, + ); + + // Verify that the authenticator doesn't match the target address + verify_matches_transaction_auth_address(&signed_transaction, &target_address, false); + + // Create a multi-agent transaction authenticator with the target secondary signer + let signed_transaction = SignedTransaction::new_multi_agent( + raw_transaction.clone(), + AccountAuthenticator::NoAccountAuthenticator, + vec![ + AccountAddress::random(), + target_address, + AccountAddress::random(), + ], + vec![AccountAuthenticator::NoAccountAuthenticator], + ); + + // Verify that the authenticator matches the target address + verify_matches_transaction_auth_address(&signed_transaction, &target_address, true); + + // Create a fee payer transaction authenticator + let fee_payer_address = AccountAddress::random(); + let secondary_signer_address = AccountAddress::random(); + let signed_transaction = SignedTransaction::new_fee_payer( + raw_transaction.clone(), + AccountAuthenticator::NoAccountAuthenticator, + vec![secondary_signer_address], + vec![AccountAuthenticator::NoAccountAuthenticator], + fee_payer_address, + AccountAuthenticator::NoAccountAuthenticator, + ); + + // Verify that the authenticator matches the fee payer and secondary signer addresses + for address in [&fee_payer_address, &secondary_signer_address] { + verify_matches_transaction_auth_address(&signed_transaction, address, true); + } + + // Verify that the authenticator doesn't match the target address + verify_matches_transaction_auth_address(&signed_transaction, &target_address, false); + } + + #[test] + fn test_matches_account_authenticator_public_key() { + // Create an empty account authenticator + let account_authenticator = AccountAuthenticator::NoAccountAuthenticator; + + // Verify that the authenticator doesn't match the public key + let private_key_1 = get_random_private_key(); + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_1.public_key()), + false, + ); + + // Create an abstraction account authenticator + let function_info = FunctionInfo::new( + AccountAddress::random(), + "test_module".to_string(), + "test_function".to_string(), + ); + let account_authenticator = + AccountAuthenticator::abstraction(function_info, vec![], vec![]); + + // Verify that the authenticator doesn't match the public key + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_1.public_key()), + false, + ); + + // Create an Ed25519 account authenticator (using the private key) + let account_authenticator = AccountAuthenticator::Ed25519 { + public_key: private_key_1.public_key(), + signature: private_key_1.sign(&create_raw_transaction()).unwrap(), + }; + + // Verify that the authenticator matches the expected public key + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(get_random_private_key().public_key()), + false, + ); + + // Create a MultiEd25519 account authenticator + let private_key_2 = get_random_private_key(); + let multi_public_key = MultiEd25519PublicKey::new( + vec![private_key_1.public_key(), private_key_2.public_key()], + 1, + ) + .unwrap(); + let multi_signature = + MultiEd25519Signature::from(private_key_1.sign(&create_raw_transaction()).unwrap()); + let account_authenticator = AccountAuthenticator::MultiEd25519 { + public_key: multi_public_key, + signature: multi_signature, + }; + + // Verify that the authenticator matches the expected public key + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_2.public_key()), + true, + ); + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(get_random_private_key().public_key()), + false, + ); + + // Create a SingleKey account authenticator + let account_authenticator = AccountAuthenticator::SingleKey { + authenticator: SingleKeyAuthenticator::new( + AnyPublicKey::Ed25519 { + public_key: private_key_1.public_key(), + }, + AnySignature::Ed25519 { + signature: private_key_1.sign(&create_raw_transaction()).unwrap(), + }, + ), + }; + + // Verify that the authenticator matches the expected public key + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_account_auth_public_key( + &account_authenticator, + &AnyPublicKey::ed25519(private_key_2.public_key()), + false, + ); + } + + #[test] + fn test_matches_transaction_authenticator_public_key() { + // Create an Ed25519 transaction authenticator + let raw_transaction = create_raw_transaction(); + let private_key_1 = Ed25519PrivateKey::generate_for_testing(); + let signature = private_key_1.sign(&raw_transaction).unwrap(); + let signed_transaction = SignedTransaction::new( + raw_transaction.clone(), + private_key_1.public_key(), + signature.clone(), + ); + + // Verify that the authenticator matches the expected public key + let private_key_2 = get_random_private_key(); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_2.public_key()), + false, + ); + + // Create a MultiEd25519 transaction authenticator + let multi_public_key = MultiEd25519PublicKey::new( + vec![private_key_1.public_key(), private_key_2.public_key()], + 1, + ) + .unwrap(); + let multi_signature = MultiEd25519Signature::from(signature.clone()); + let signed_transaction = SignedTransaction::new_multisig( + raw_transaction.clone(), + multi_public_key, + multi_signature, + ); + + // Verify that the authenticator matches the expected public key + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_2.public_key()), + true, + ); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(get_random_private_key().public_key()), + false, + ); + + // Create a multi-agent transaction authenticator + let signed_transaction = SignedTransaction::new_multi_agent( + raw_transaction.clone(), + AccountAuthenticator::Ed25519 { + public_key: private_key_1.public_key(), + signature: signature.clone(), + }, + vec![], + vec![AccountAuthenticator::Ed25519 { + public_key: private_key_2.public_key(), + signature: signature.clone(), + }], + ); + + // Verify that the authenticator matches the expected public key + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_1.public_key()), + true, + ); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(private_key_2.public_key()), + true, + ); + verify_matches_transaction_auth_public_key( + &signed_transaction, + &AnyPublicKey::ed25519(get_random_private_key().public_key()), + false, + ); + } + + /// Creates and returns a raw transaction + fn create_raw_transaction() -> RawTransaction { + RawTransaction::new( + AccountAddress::random(), + 0, + TransactionPayload::Script(Script::new(vec![], vec![], vec![])), + 0, + 0, + 0, + ChainId::new(10), + ) + } + + /// Generates and returns a random Ed25519 private key + fn get_random_private_key() -> Ed25519PrivateKey { + Ed25519PrivateKey::generate(&mut thread_rng()) + } + + /// Verifies that the given account authenticator contains the expected address + fn verify_matches_account_auth_address( + account_authenticator: &AccountAuthenticator, + address: &AccountAddress, + matches: bool, + ) { + let result = matches_account_authenticator_address(account_authenticator, address); + assert_eq!(matches, result); + } + + /// Verifies that the given account authenticator contains the expected public key + fn verify_matches_account_auth_public_key( + account_authenticator: &AccountAuthenticator, + any_public_key: &AnyPublicKey, + matches: bool, + ) { + let result = + matches_account_authenticator_public_key(account_authenticator, any_public_key); + assert_eq!(matches, result); + } + + /// Verifies that the given public key contains the target address + fn verify_matches_public_key_address( + any_public_key: &AnyPublicKey, + address: &AccountAddress, + matches: bool, + ) { + let result = matches_any_public_key_address(any_public_key, address); + assert_eq!(matches, result); + } + + /// Verifies that the given transaction authenticator contains the expected address + fn verify_matches_transaction_auth_address( + signed_transaction: &SignedTransaction, + address: &AccountAddress, + matches: bool, + ) { + let result = matches_transaction_authenticator_address(signed_transaction, address); + assert_eq!(matches, result); + } + + /// Verifies that the given transaction authenticator contains the expected public key + fn verify_matches_transaction_auth_public_key( + signed_transaction: &SignedTransaction, + any_public_key: &AnyPublicKey, + matches: bool, + ) { + let result = + matches_transaction_authenticator_public_key(signed_transaction, any_public_key); + assert_eq!(matches, result); + } +} diff --git a/crates/aptos/CHANGELOG.md b/crates/aptos/CHANGELOG.md index 56b91842ebe..b2fb5d09805 100644 --- a/crates/aptos/CHANGELOG.md +++ b/crates/aptos/CHANGELOG.md @@ -3,7 +3,50 @@ All notable changes to the Movement CLI will be captured in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Unreleased + +## [7.11.1] +- When Move unit tests detect that the legacy struct-based Option module is being loaded, replace it with the pre-compiled binary version. + +## [7.11.0] +- When using `--bind-to 0.0.0.0`, clients created by the localnet will try to connect at 127.0.0.1, not 0.0.0.0. +- Add `--docker-network` flag to allow specifying existing Docker network. + +## [7.10.2] +- Fix backward compatibility issue of enum-based option module + +## [7.10.1] +- Add support into Move 2.2 for builtin constant `__COMPILE_FOR_TESTING__` +- Update the default version of move formatter to 1.3.7 +- Update the default version of move mutation test tool to 2.0.0 + +## [7.10.0] +- Add support into Move 2.3 for signed integer types and builtin constants (`MAX_U8`, ..., `MIN_U8`, ..., `__COMPILE_FOR_TESTING__`). Move 2.3 is not yet supported on testnet or mainnet, but can be used for local development by providing `--language-version 2.3` to the CLI. + +## [7.9.1] +- Add mem as pre-compiled module to avoid compatibility issue when using aptos-framework + +## [7.9.0] +- Set language version 2.2 and bytecode version v8 as default +- Set Move disassembler v2 and decompiler v2 as default + +## [7.8.1] +- Transaction Simulatiom Session: fixed resource deserialization bug + +## [7.8.0] +- New beta feature: Transaction Simulation Session + +## [7.7.0] +- Turn off sharding in the local testnet + +## [7.6.1] +- Mark language version 2.2 as stable. + +## [7.6.0] +- Sets up confidential assets for localnet under the experimental address 0x7 + +## [7.5.0] - Fix auto-update CLI command to work with more OS's including Mac and Linux on ARM +- Update localnet indexer processors ## [7.4.0] - UTF-8 characters are now allowed in Move source code comments (and thus error codes). diff --git a/crates/aptos/Cargo.toml b/crates/aptos/Cargo.toml index b8ee4591cbe..25a27d66b13 100644 --- a/crates/aptos/Cargo.toml +++ b/crates/aptos/Cargo.toml @@ -43,6 +43,8 @@ aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-telemetry = { workspace = true } aptos-temppath = { workspace = true } +aptos-transaction-simulation = { workspace = true } +aptos-transaction-simulation-session = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true, features = ["testing"] } aptos-vm-environment = { workspace = true } @@ -69,6 +71,7 @@ indoc = { workspace = true } itertools = { workspace = true } legacy-move-compiler = { workspace = true } maplit = { workspace = true } +move-asm = { workspace = true } move-binary-format = { workspace = true } move-bytecode-source-map = { workspace = true } move-cli = { workspace = true } @@ -76,6 +79,7 @@ move-command-line-common = { workspace = true } move-compiler-v2 = { workspace = true } move-core-types = { workspace = true } move-coverage = { workspace = true } +move-decompiler = { workspace = true } move-disassembler = { workspace = true } move-ir-types = { workspace = true } move-linter = { workspace = true } @@ -109,10 +113,7 @@ tracing-subscriber = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [features] default = [] diff --git a/crates/aptos/e2e/cases/move.py b/crates/aptos/e2e/cases/move.py index 574f55a30b0..f5fdeb64740 100644 --- a/crates/aptos/e2e/cases/move.py +++ b/crates/aptos/e2e/cases/move.py @@ -284,7 +284,7 @@ def test_move_view(run_helper: RunHelper, test_name=None): f"View function [test_big_number] did not return correct result" ) - # Test view function with with vector arguments + # Test view function with vector arguments # Follow 2 lines are for testing vector of u16-u256 response = run_helper.run_command( test_name, diff --git a/crates/aptos/homebrew/README.md b/crates/aptos/homebrew/README.md index 8aab99ccdb1..66ebdc02e0e 100644 --- a/crates/aptos/homebrew/README.md +++ b/crates/aptos/homebrew/README.md @@ -3,14 +3,14 @@ Homebrew is a package manager that works for MacOS Silicon and Intel chips as well as Linux distributions like Debian and Ubuntu. -The [Movement command line interface (CLI)](https://github.com/movementlabsxyz/aptos-core/) may be installed +The [Movement command line interface (CLI)](https://github.com/movement-network/aptos-core/) may be installed via [Homebrew](https://brew.sh/) for simplicity. This is an in-depth overview of Homebrew and the Movement formula. In this guide, we go over each section of the Homebrew formula and steps to implement changes in the future. ## Quick guide - [Formula in Homebrew GitHub](https://github.com/Homebrew/homebrew-core/blob/master/Formula/movement.rb) -- [Movement New Formula PR for GitHub]() +- [Movement New Formula PR for GitHub](link-to-PR) ## Getting started @@ -178,9 +178,9 @@ brew livecheck --debug movement end # Currently must compile with the same rustc version specified in the - # root Cargo.toml file of aptos-core (currently it is pegged to Rust + # root Cargo.toml file of aptos-core (currently it is pegged to Rust # v1.64). In the future if it becomes compatible with the latest Rust - # toolchain, we can remove the use of rustup-init, replacing it with a + # toolchain, we can remove the use of rustup-init, replacing it with a # depends_on "rust" => :build # above and build the binary without rustup as a dependency # @@ -221,7 +221,7 @@ key. - To view other Homebrew-related FAQs or ask questions yourself, visit the [discussions board](https://github.com/orgs/Homebrew/discussions). - For similar Rust-related build examples, we recommend: - - [`rustfmt.rb`](https://github.com/Homebrew/homebrew-core/blob/master/Formula/rustfmt.rb) + - [`rustfmt.rb`](https://github.com/Homebrew/homebrew-core/blob/master/Formula/rustfmt.rb) - Finally, note these key Homebew guides: - - [Homebrew Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) - - [Creating and Running Your Own Homebrew Tap - Rust Runbook](https://publishing-project.rivendellweb.net/creating-and-running-your-own-homebrew-tap/) + - [Homebrew Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) + - [Creating and Running Your Own Homebrew Tap - Rust Runbook](https://publishing-project.rivendellweb.net/creating-and-running-your-own-homebrew-tap/) diff --git a/crates/aptos/src/common/init.rs b/crates/aptos/src/common/init.rs index 74d4b7ddd3d..fc6fc754417 100644 --- a/crates/aptos/src/common/init.rs +++ b/crates/aptos/src/common/init.rs @@ -237,7 +237,7 @@ impl CliCommand<()> for InitTool { // Public key let public_key = if self.is_hardware_wallet() { - let pub_key = match aptos_ledger::get_public_key( + match aptos_ledger::get_public_key( derivation_path .ok_or_else(|| { CliError::UnexpectedError("Invalid derivation path".to_string()) @@ -252,8 +252,7 @@ impl CliCommand<()> for InitTool { err.to_string() ))) }, - }; - pub_key + } } else { private_key.clone().unwrap().public_key() }; diff --git a/crates/aptos/src/common/local_simulation.rs b/crates/aptos/src/common/local_simulation.rs index 01df2483a82..dee5c071a85 100644 --- a/crates/aptos/src/common/local_simulation.rs +++ b/crates/aptos/src/common/local_simulation.rs @@ -5,7 +5,7 @@ use crate::common::types::{CliError, CliTypedResult}; use aptos_crypto::HashValue; use aptos_gas_profiling::FrameName; use aptos_move_debugger::aptos_debugger::AptosDebugger; -use aptos_types::transaction::SignedTransaction; +use aptos_types::transaction::{AuxiliaryInfo, PersistedAuxiliaryInfo, SignedTransaction}; use aptos_vm::{data_cache::AsMoveResolver, AptosVM}; use aptos_vm_environment::environment::AptosEnvironment; use aptos_vm_logging::log_schema::AdapterLogSchema; @@ -20,6 +20,7 @@ pub fn run_transaction_using_debugger( version: u64, transaction: SignedTransaction, _hash: HashValue, + persisted_auxiliary_info: PersistedAuxiliaryInfo, ) -> CliTypedResult<(VMStatus, VMOutput)> { let state_view = debugger.state_view_at_version(version); let env = AptosEnvironment::new(&state_view); @@ -29,8 +30,13 @@ pub fn run_transaction_using_debugger( let resolver = state_view.as_move_resolver(); let code_storage = state_view.as_aptos_code_storage(&env); - let (vm_status, vm_output) = - vm.execute_user_transaction(&resolver, &code_storage, &transaction, &log_context); + let (vm_status, vm_output) = vm.execute_user_transaction( + &resolver, + &code_storage, + &transaction, + &log_context, + &AuxiliaryInfo::new(persisted_auxiliary_info, None), + ); Ok((vm_status, vm_output)) } @@ -40,6 +46,7 @@ pub fn benchmark_transaction_using_debugger( version: u64, transaction: SignedTransaction, _hash: HashValue, + persisted_auxiliary_info: PersistedAuxiliaryInfo, ) -> CliTypedResult<(VMStatus, VMOutput)> { let state_view = debugger.state_view_at_version(version); let env = AptosEnvironment::new(&state_view); @@ -48,8 +55,13 @@ pub fn benchmark_transaction_using_debugger( let resolver = state_view.as_move_resolver(); let code_storage = state_view.as_aptos_code_storage(&env); - let (vm_status, vm_output) = - vm.execute_user_transaction(&resolver, &code_storage, &transaction, &log_context); + let (vm_status, vm_output) = vm.execute_user_transaction( + &resolver, + &code_storage, + &transaction, + &log_context, + &AuxiliaryInfo::new(persisted_auxiliary_info, None), + ); let time_cold = { let n = 15; @@ -68,6 +80,7 @@ pub fn benchmark_transaction_using_debugger( &code_storage, &transaction, &log_context, + &AuxiliaryInfo::new(persisted_auxiliary_info, None), )); let t2 = Instant::now(); @@ -91,6 +104,7 @@ pub fn benchmark_transaction_using_debugger( &code_storage, &transaction, &log_context, + &AuxiliaryInfo::new(persisted_auxiliary_info, None), )); let t2 = Instant::now(); @@ -98,7 +112,7 @@ pub fn benchmark_transaction_using_debugger( } times.sort(); - times[n / 2] + times[(n / 2) as usize] }; println!("Running time (cold code cache): {:?}", time_cold); @@ -112,9 +126,14 @@ pub fn profile_transaction_using_debugger( version: u64, transaction: SignedTransaction, hash: HashValue, + persisted_auxiliary_info: PersistedAuxiliaryInfo, ) -> CliTypedResult<(VMStatus, VMOutput)> { let (vm_status, vm_output, gas_log) = debugger - .execute_transaction_at_version_with_gas_profiler(version, transaction) + .execute_transaction_at_version_with_gas_profiler( + version, + transaction, + AuxiliaryInfo::new(persisted_auxiliary_info, None), + ) .map_err(|err| { CliError::UnexpectedError(format!("failed to simulate txn with gas profiler: {}", err)) })?; @@ -124,6 +143,7 @@ pub fn profile_transaction_using_debugger( let human_readable_name = match entry_point { FrameName::Script => "script".to_string(), + FrameName::TransactionBatch => "transaction batch".to_string(), FrameName::Function { module_id, name, .. } => { diff --git a/crates/aptos/src/common/transactions.rs b/crates/aptos/src/common/transactions.rs index 09c181d626b..78f1fba8fc8 100644 --- a/crates/aptos/src/common/transactions.rs +++ b/crates/aptos/src/common/transactions.rs @@ -23,14 +23,34 @@ use aptos_types::{ chain_id::ChainId, transaction::{ authenticator::{AccountAuthenticator, TransactionAuthenticator}, - SignedTransaction, TransactionPayload, TransactionStatus, + PersistedAuxiliaryInfo, ReplayProtector, SignedTransaction, TransactionPayload, + TransactionStatus, }, }; use aptos_vm_types::output::VMOutput; use clap::Parser; use move_core_types::vm_status::VMStatus; pub use move_package::*; -use std::time::{SystemTime, UNIX_EPOCH}; +use std::{ + fmt::Display, + time::{SystemTime, UNIX_EPOCH}, +}; + +#[derive(Clone, Copy, Debug, Default, Parser, PartialEq, clap::ValueEnum)] +pub enum ReplayProtectionType { + Nonce, + #[default] + Seqnum, +} + +impl Display for ReplayProtectionType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", match self { + ReplayProtectionType::Nonce => "nonce", + ReplayProtectionType::Seqnum => "seqnum", + }) + } +} /// Common options for simulating and running transactions /// @@ -58,6 +78,13 @@ pub struct TxnOptions { pub(crate) gas_options: GasOptions, #[clap(flatten)] pub prompt_options: PromptOptions, + /// Replay protection mechanism to use when generating the transaction. + /// + /// When "nonce" is chosen, the transaction will be an orderless transaction and contains a replay protection nonce. + /// + /// When "seqnum" is chosen, the transaction will contain a sequence number that matches with the sender's onchain sequence number. + #[clap(long, default_value_t = ReplayProtectionType::Seqnum)] + pub(crate) replay_protection_type: ReplayProtectionType, } impl TxnOptions { @@ -137,6 +164,7 @@ impl TxnOptions { pub async fn simulate_remotely( &self, + rng: &mut rand::rngs::StdRng, payload: TransactionPayload, ) -> CliTypedResult { let client = self.rest_client()?; @@ -171,12 +199,15 @@ impl TxnOptions { let transaction_factory = TransactionFactory::new(chain_id).with_gas_unit_price(gas_unit_price); - let unsigned_transaction = transaction_factory + let mut txn_builder = transaction_factory .payload(payload.clone()) .sender(sender_address) .sequence_number(sequence_number) - .expiration_timestamp_secs(expiration_time_secs) - .build(); + .expiration_timestamp_secs(expiration_time_secs); + if self.replay_protection_type == ReplayProtectionType::Nonce { + txn_builder = txn_builder.upgrade_payload_with_rng(rng, true, true); + } + let unsigned_transaction = txn_builder.build(); // TODO: Support other transaction authenticator types, like multi-agent and fee-payer let signed_transaction = SignedTransaction::new_signed_transaction( @@ -200,7 +231,11 @@ impl TxnOptions { gas_unit_price: Some(user_txn.gas_unit_price()), pending: None, sender: Some(user_txn.sender()), - sequence_number: Some(user_txn.sequence_number()), + replay_protector: Some(user_txn.replay_protector()), + sequence_number: match user_txn.replay_protector() { + ReplayProtector::SequenceNumber(sequence_number) => Some(sequence_number), + _ => None, + }, success: Some(simulated_txn.info.status().is_success()), timestamp_us: None, version: Some(simulated_txn.version), @@ -220,6 +255,7 @@ impl TxnOptions { u64, SignedTransaction, aptos_crypto::HashValue, + PersistedAuxiliaryInfo, ) -> CliTypedResult<(VMStatus, VMOutput)>, { let client = self.rest_client()?; @@ -263,7 +299,13 @@ impl TxnOptions { let hash = transaction.committed_hash(); let debugger = AptosDebugger::rest_client(client)?; - let (vm_status, vm_output) = execute(&debugger, version, transaction, hash)?; + let (vm_status, vm_output) = execute( + &debugger, + version, + transaction, + hash, + PersistedAuxiliaryInfo::None, + )?; let success = match vm_output.status() { TransactionStatus::Keep(exec_status) => Some(exec_status.is_success()), @@ -276,7 +318,8 @@ impl TxnOptions { gas_unit_price: Some(gas_unit_price), pending: None, sender: Some(sender_address), - sequence_number: None, // The transaction is not committed so there is no new sequence number. + sequence_number: None, + replay_protector: None, // The transaction is not committed so there is no new sequence number. success, timestamp_us: None, version: Some(version), // The transaction is not committed so there is no new version. diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 493ef23057c..3c9ed944776 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -6,6 +6,7 @@ use crate::{ common::{ init::Network, local_simulation, + transactions::ReplayProtectionType, utils::{ check_if_file_exists, create_dir_if_not_exist, deserialize_address_str, deserialize_material_with_prefix, dir_default_to_current, get_account_with_state, @@ -42,11 +43,15 @@ use aptos_sdk::{ transaction_builder::TransactionFactory, types::{HardwareWalletAccount, HardwareWalletType, LocalAccount, TransactionSigner}, }; +use aptos_transaction_simulation::SimulationStateStore; +use aptos_transaction_simulation_session::Session; use aptos_types::{ + account_config::AccountResource, chain_id::ChainId, transaction::{ - authenticator::AuthenticationKey, EntryFunction, MultisigTransactionPayload, Script, - SignedTransaction, TransactionArgument, TransactionPayload, TransactionStatus, + authenticator::AuthenticationKey, EntryFunction, MultisigTransactionPayload, + PersistedAuxiliaryInfo, ReplayProtector, Script, SignedTransaction, TransactionArgument, + TransactionPayload, TransactionStatus, }, }; use aptos_vm_types::output::VMOutput; @@ -72,7 +77,7 @@ use std::{ convert::TryFrom, fmt::{Debug, Display, Formatter}, fs::OpenOptions, - path::PathBuf, + path::{Path, PathBuf}, str::FromStr, time::{Duration, Instant, SystemTime, UNIX_EPOCH}, }; @@ -1243,7 +1248,7 @@ pub struct MovePackageOptions { pub optimize: Option, /// Experiments - #[clap(long, hide(true))] + #[clap(long, hide(true), num_args = 1.., value_delimiter = ',')] pub experiments: Vec, /// ...or --bytecode BYTECODE_VERSION @@ -1497,6 +1502,8 @@ pub struct TransactionSummary { #[serde(skip_serializing_if = "Option::is_none")] pub sequence_number: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub replay_protector: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub success: Option, #[serde(skip_serializing_if = "Option::is_none")] pub timestamp_us: Option, @@ -1518,7 +1525,11 @@ impl From<&Transaction> for TransactionSummary { transaction_hash: txn.hash, pending: Some(true), sender: Some(*txn.request.sender.inner()), - sequence_number: Some(txn.request.sequence_number.0), + sequence_number: match txn.request.replay_protector() { + ReplayProtector::SequenceNumber(sequence_number) => Some(sequence_number), + _ => None, + }, + replay_protector: Some(txn.request.replay_protector()), gas_used: None, gas_unit_price: None, success: None, @@ -1534,7 +1545,11 @@ impl From<&Transaction> for TransactionSummary { success: Some(txn.info.success), version: Some(txn.info.version.0), vm_status: Some(txn.info.vm_status.clone()), - sequence_number: Some(txn.request.sequence_number.0), + sequence_number: match txn.request.replay_protector() { + ReplayProtector::SequenceNumber(sequence_number) => Some(sequence_number), + _ => None, + }, + replay_protector: Some(txn.request.replay_protector()), timestamp_us: Some(txn.timestamp.0), pending: None, }, @@ -1548,6 +1563,7 @@ impl From<&Transaction> for TransactionSummary { gas_unit_price: None, pending: None, sequence_number: None, + replay_protector: None, timestamp_us: None, }, Transaction::BlockMetadataTransaction(txn) => TransactionSummary { @@ -1561,6 +1577,7 @@ impl From<&Transaction> for TransactionSummary { gas_unit_price: None, pending: None, sequence_number: None, + replay_protector: None, }, Transaction::StateCheckpointTransaction(txn) => TransactionSummary { transaction_hash: txn.info.hash, @@ -1573,6 +1590,7 @@ impl From<&Transaction> for TransactionSummary { gas_unit_price: None, pending: None, sequence_number: None, + replay_protector: None, }, Transaction::BlockEpilogueTransaction(txn) => TransactionSummary { transaction_hash: txn.info.hash, @@ -1585,6 +1603,7 @@ impl From<&Transaction> for TransactionSummary { gas_unit_price: None, pending: None, sequence_number: None, + replay_protector: None, }, Transaction::ValidatorTransaction(txn) => TransactionSummary { transaction_hash: txn.transaction_info().hash, @@ -1593,6 +1612,7 @@ impl From<&Transaction> for TransactionSummary { pending: None, sender: None, sequence_number: None, + replay_protector: None, success: Some(txn.transaction_info().success), timestamp_us: Some(txn.timestamp().0), version: Some(txn.transaction_info().version.0), @@ -1781,6 +1801,18 @@ pub struct TransactionOptions { /// flamegraphs that reflect the gas usage. #[clap(long)] pub(crate) profile_gas: bool, + + /// If this option is set, simulate the transaction using a local session. + #[clap(long)] + pub(crate) session: Option, + + /// Replay protection mechanism to use when generating the transaction. + /// + /// When "nonce" is chosen, the transaction will be an orderless transaction and contains a replay protection nonce. + /// + /// When "seqnum" is chosen, the transaction will contain a sequence number that matches with the sender's onchain sequence number. + #[clap(long, default_value_t = ReplayProtectionType::Seqnum)] + pub(crate) replay_protection_type: ReplayProtectionType, } impl TransactionOptions { @@ -1855,11 +1887,26 @@ impl TransactionOptions { } pub async fn view(&self, payload: ViewFunction) -> CliTypedResult> { - let client = self.rest_client()?; - Ok(client - .view_bcs_with_json_response(&payload, None) - .await? - .into_inner()) + match &self.session { + None => { + let client = self.rest_client()?; + Ok(client + .view_bcs_with_json_response(&payload, None) + .await? + .into_inner()) + }, + + Some(session_path) => { + let mut sess = Session::load(session_path)?; + let output = sess.execute_view_function( + payload.module, + payload.function, + payload.ty_args, + payload.args, + )?; + Ok(output) + }, + } } /// Submit a transaction @@ -1915,12 +1962,21 @@ impl TransactionOptions { let transaction_factory = TransactionFactory::new(chain_id).with_gas_unit_price(gas_unit_price); - let unsigned_transaction = transaction_factory + let txn_builder = transaction_factory .payload(payload.clone()) .sender(sender_address) .sequence_number(sequence_number) - .expiration_timestamp_secs(expiration_time_secs) - .build(); + .expiration_timestamp_secs(expiration_time_secs); + + let unsigned_transaction = if self.replay_protection_type == ReplayProtectionType::Nonce + { + let mut rng = rand::thread_rng(); + txn_builder + .upgrade_payload_with_rng(&mut rng, true, true) + .build() + } else { + txn_builder.build() + }; let signed_transaction = SignedTransaction::new( unsigned_transaction, @@ -1972,7 +2028,12 @@ impl TransactionOptions { let (private_key, _) = self.get_key_and_address()?; let sender_account = &mut LocalAccount::new(sender_address, private_key, sequence_number); - sender_account.sign_with_transaction_builder(transaction_factory.payload(payload)) + let mut txn_builder = transaction_factory.payload(payload); + if self.replay_protection_type == ReplayProtectionType::Nonce { + let mut rng = rand::thread_rng(); + txn_builder = txn_builder.upgrade_payload_with_rng(&mut rng, true, true); + }; + sender_account.sign_with_transaction_builder(txn_builder) }, Ok(AccountType::HardwareWallet) => { let sender_account = &mut HardwareWalletAccount::new( @@ -1985,8 +2046,12 @@ impl TransactionOptions { HardwareWalletType::Ledger, sequence_number, ); - sender_account - .sign_with_transaction_builder(transaction_factory.payload(payload))? + let mut txn_builder = transaction_factory.payload(payload); + if self.replay_protection_type == ReplayProtectionType::Nonce { + let mut rng = rand::thread_rng(); + txn_builder = txn_builder.upgrade_payload_with_rng(&mut rng, true, true); + }; + sender_account.sign_with_transaction_builder(txn_builder)? }, Err(err) => return Err(err), }; @@ -2044,6 +2109,7 @@ impl TransactionOptions { u64, SignedTransaction, aptos_crypto::HashValue, + PersistedAuxiliaryInfo, ) -> CliTypedResult<(VMStatus, VMOutput)>, { let client = self.rest_client()?; @@ -2054,6 +2120,7 @@ impl TransactionOptions { const DEFAULT_MAX_GAS: u64 = 2_000_000; let (sender_key, sender_address) = self.get_key_and_address()?; + // TODO: Consider fetching the min gas unit price from the chain let gas_unit_price = self .gas_options .gas_unit_price @@ -2087,7 +2154,15 @@ impl TransactionOptions { let hash = transaction.committed_hash(); let debugger = AptosDebugger::rest_client(client).unwrap(); - let (vm_status, vm_output) = execute(&debugger, version, transaction, hash)?; + let (vm_status, vm_output) = execute( + &debugger, + version, + transaction, + hash, + PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }, + )?; let success = match vm_output.status() { TransactionStatus::Keep(exec_status) => Some(exec_status.is_success()), @@ -2100,7 +2175,8 @@ impl TransactionOptions { gas_unit_price: Some(gas_unit_price), pending: None, sender: Some(sender_address), - sequence_number: None, // The transaction is not comitted so there is no new sequence number. + sequence_number: None, + replay_protector: None, // The transaction is not comitted so there is no new sequence number. success, timestamp_us: None, version: Some(version), // The transaction is not comitted so there is no new version. @@ -2110,6 +2186,76 @@ impl TransactionOptions { Ok(summary) } + pub async fn simulate_using_session( + &self, + session_path: &Path, + payload: TransactionPayload, + ) -> CliTypedResult { + let mut sess = Session::load(session_path)?; + + let state_store = sess.state_store(); + + // Fetch the chain states required for the simulation + const DEFAULT_GAS_UNIT_PRICE: u64 = 100; + const DEFAULT_MAX_GAS: u64 = 2_000_000; + + let (sender_key, sender_address) = self.get_key_and_address()?; + + // TODO: Support orderless transactions + let account = state_store.get_resource::(sender_address)?; + let seq_num = match account { + Some(account) => account.sequence_number, + None => 0, + }; + + // TODO: Consider fetching the min gas unit price from the chain + let gas_unit_price = self + .gas_options + .gas_unit_price + .unwrap_or(DEFAULT_GAS_UNIT_PRICE); + + let balance = state_store.get_apt_balance(sender_address)?; + let max_gas = self.gas_options.max_gas.unwrap_or_else(|| { + if gas_unit_price == 0 { + DEFAULT_MAX_GAS + } else { + std::cmp::min(balance / gas_unit_price, DEFAULT_MAX_GAS) + } + }); + + let transaction_factory = TransactionFactory::new(state_store.get_chain_id()?) + .with_gas_unit_price(gas_unit_price) + .with_max_gas_amount(max_gas) + .with_transaction_expiration_time(self.gas_options.expiration_secs); + let sender_account = &mut LocalAccount::new(sender_address, sender_key, seq_num); + let transaction = + sender_account.sign_with_transaction_builder(transaction_factory.payload(payload)); + let hash = transaction.committed_hash(); + + let (vm_status, txn_output) = sess.execute_transaction(transaction)?; + + let success = match txn_output.status() { + TransactionStatus::Keep(exec_status) => Some(exec_status.is_success()), + TransactionStatus::Discard(_) | TransactionStatus::Retry => None, + }; + + let summary = TransactionSummary { + transaction_hash: hash.into(), + gas_used: Some(txn_output.gas_used()), + gas_unit_price: Some(gas_unit_price), + pending: None, + sender: Some(sender_address), + sequence_number: Some(seq_num), + replay_protector: None, + success, + timestamp_us: None, + version: None, + vm_status: Some(vm_status.to_string()), + }; + + Ok(summary) + } + /// Simulates a transaction locally. pub async fn simulate_locally( &self, diff --git a/crates/aptos/src/common/utils.rs b/crates/aptos/src/common/utils.rs index f281959e516..9b48cf6a0f5 100644 --- a/crates/aptos/src/common/utils.rs +++ b/crates/aptos/src/common/utils.rs @@ -506,8 +506,8 @@ pub fn start_logger(level: Level) { logger.build(); } -/// For transaction payload and options, either get gas profile or submit for execution. -pub async fn profile_or_submit( +/// Dispatches the transaction payload to different execution backends based on options. +pub async fn dispatch_transaction( payload: TransactionPayload, txn_options_ref: &TransactionOptions, ) -> CliTypedResult { @@ -517,8 +517,23 @@ pub async fn profile_or_submit( )); } - // Profile gas if needed. - if txn_options_ref.profile_gas { + if txn_options_ref.session.is_some() && txn_options_ref.profile_gas { + return Err(CliError::UnexpectedError( + "`--profile-gas` cannot be used with `--session yet`".to_string(), + )); + } + + if txn_options_ref.session.is_some() && txn_options_ref.benchmark { + return Err(CliError::UnexpectedError( + "`--benchmark` cannot be used with `--session yet`".to_string(), + )); + } + + if let Some(session_path) = &txn_options_ref.session { + txn_options_ref + .simulate_using_session(session_path, payload) + .await + } else if txn_options_ref.profile_gas { txn_options_ref.profile_gas(payload).await } else if txn_options_ref.benchmark { txn_options_ref.benchmark_locally(payload).await diff --git a/crates/aptos/src/genesis/mod.rs b/crates/aptos/src/genesis/mod.rs index 5e5fcca4d8e..df023804a8b 100644 --- a/crates/aptos/src/genesis/mod.rs +++ b/crates/aptos/src/genesis/mod.rs @@ -577,7 +577,7 @@ fn parse_required_option Result, T, E: std::fmt::Display>( field_name: &'static str, parse: F, ) -> Result { - if let Some(ref field) = option { + if let Some(field) = option { parse(field).map_err(|err| { CliError::CommandArgumentError(format!( "Field {} is invalid in file {}. Err: {}", @@ -601,7 +601,7 @@ fn parse_optional_option Result, T, E: std::fmt::Display>( field_name: &'static str, parse: F, ) -> Result, CliError> { - if let Some(ref field) = option { + if let Some(field) = option { parse(field) .map_err(|err| { CliError::CommandArgumentError(format!( diff --git a/crates/aptos/src/move_tool/aptos_debug_natives.rs b/crates/aptos/src/move_tool/aptos_debug_natives.rs index 926f1c48826..6b65596e127 100644 --- a/crates/aptos/src/move_tool/aptos_debug_natives.rs +++ b/crates/aptos/src/move_tool/aptos_debug_natives.rs @@ -5,8 +5,17 @@ use aptos_framework::extended_checks; use aptos_gas_schedule::{MiscGasParameters, NativeGasParameters, LATEST_GAS_FEATURE_VERSION}; use aptos_types::on_chain_config::{Features, TimedFeaturesBuilder}; use aptos_vm::natives; +use move_model::model::GlobalEnv; use move_vm_runtime::native_functions::NativeFunctionTable; +/// Configures the move-cli unit test validation hook to run the extended checker. +fn configure_extended_checks_for_unit_test() { + fn validate(env: &GlobalEnv) { + extended_checks::run_extended_checks(env); + } + move_cli::base::test_validation::set_validation_hook(Box::new(validate)); +} + // move_stdlib has the testing feature enabled to include debug native functions pub fn aptos_debug_natives( native_gas_parameters: NativeGasParameters, @@ -14,7 +23,7 @@ pub fn aptos_debug_natives( ) -> NativeFunctionTable { // As a side effect, also configure for unit testing natives::configure_for_unit_test(); - extended_checks::configure_extended_checks_for_unit_test(); + configure_extended_checks_for_unit_test(); // Return all natives -- build with the 'testing' feature, therefore containing // debug related functions. natives::aptos_natives( diff --git a/crates/aptos/src/move_tool/bytecode.rs b/crates/aptos/src/move_tool/bytecode.rs index 2d155d97b1c..80a0ebe10c0 100644 --- a/crates/aptos/src/move_tool/bytecode.rs +++ b/crates/aptos/src/move_tool/bytecode.rs @@ -14,7 +14,7 @@ use crate::{ use anyhow::Context; use aptos_types::vm::module_metadata::prelude::*; use async_trait::async_trait; -use clap::{Args, Parser}; +use clap::{Args, Parser, ValueEnum}; use itertools::Itertools; use move_binary_format::{ binary_views::BinaryIndexedView, file_format::CompiledScript, file_format_common, @@ -25,6 +25,7 @@ use move_command_line_common::files::{ MOVE_COMPILED_EXTENSION, MOVE_EXTENSION, SOURCE_MAP_EXTENSION, }; use move_coverage::coverage_map::CoverageMap; +use move_decompiler::{Decompiler, Options as DecompilerOptions}; use move_disassembler::disassembler::{Disassembler, DisassemblerOptions}; use move_ir_types::location::Spanned; use move_model::metadata::{CompilationMetadata, CompilerVersion, LanguageVersion}; @@ -37,7 +38,8 @@ use std::{ }; use tempfile::NamedTempFile; -const DISASSEMBLER_EXTENSION: &str = "mv.asm"; +const DISASSEMBLER_EXTENSION_V1: &str = "mv.asm"; +const DISASSEMBLER_EXTENSION_V2: &str = "mv.masm"; const DECOMPILER_EXTENSION: &str = "mv.move"; /// Disassemble the Move bytecode pointed to in the textual representation @@ -50,6 +52,9 @@ const DECOMPILER_EXTENSION: &str = "mv.move"; pub struct Disassemble { #[clap(flatten)] pub command: BytecodeCommand, + /// (Optional) Disassembler version to use + #[arg(long, value_enum, default_value = "v2")] + pub disassembler_version: DisassemblerVersion, } /// Decompile the Move bytecode pointed to into Move source code. @@ -61,6 +66,31 @@ pub struct Disassemble { pub struct Decompile { #[clap(flatten)] pub command: BytecodeCommand, + /// (Optional) Decompiler version to use + #[arg(long, value_enum, default_value = "v2")] + pub decompiler_version: DecompilerVersion, +} + +#[derive(Clone, Copy, Debug)] +pub enum BinaryCommandVersion { + DecompilerVersion(DecompilerVersion), + DisassemblerVersion(DisassemblerVersion), +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, ValueEnum)] +pub enum DisassemblerVersion { + /// Use the old disassembler + V1, + /// Use the new disassembler + V2, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, ValueEnum)] +pub enum DecompilerVersion { + /// Use the Revela decompiler + V1, + /// Use the new Aptos decompiler + V2, } #[derive(Debug, Args)] @@ -91,6 +121,10 @@ pub struct BytecodeCommand { /// only print out the metadata and bytecode version of the target bytecode #[clap(long)] pub print_metadata_only: bool, + + /// print out module size in kb and number of instructions in each function + #[clap(long, num_args = 0.., value_delimiter = ',', default_missing_value = "", require_equals = false, hide(true))] + pub print_code_size: Option>, } /// Allows to ensure that either one of both is selected (via the `group` attribute). @@ -123,7 +157,12 @@ impl CliCommand for Disassemble { } async fn execute(mut self) -> CliTypedResult { - self.command.execute(BytecodeCommandType::Disassemble).await + self.command + .execute( + BytecodeCommandType::Disassemble, + BinaryCommandVersion::DisassemblerVersion(self.disassembler_version), + ) + .await } } @@ -134,7 +173,12 @@ impl CliCommand for Decompile { } async fn execute(mut self) -> CliTypedResult { - self.command.execute(BytecodeCommandType::Decompile).await + self.command + .execute( + BytecodeCommandType::Decompile, + BinaryCommandVersion::DecompilerVersion(self.decompiler_version), + ) + .await } } @@ -146,7 +190,11 @@ struct BytecodeMetadata { } impl BytecodeCommand { - async fn execute(self, command_type: BytecodeCommandType) -> CliTypedResult { + async fn execute( + self, + command_type: BytecodeCommandType, + version: BinaryCommandVersion, + ) -> CliTypedResult { let inputs = if let Some(path) = self.input.bytecode_path.clone() { vec![path] } else if let Some(path) = self.input.package_path.clone() { @@ -177,12 +225,41 @@ impl BytecodeCommand { ))); } - let (output, extension) = match command_type { - BytecodeCommandType::Disassemble => { - (self.disassemble(bytecode_path)?, DISASSEMBLER_EXTENSION) + let print_code_bool = self.print_code_size.as_ref().is_some_and(|v| { + (v.len() == 1 && v[0].is_empty()) + || v.contains( + &bytecode_path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(), + ) + }); + + let (output, extension) = match (command_type, version) { + ( + BytecodeCommandType::Disassemble, + BinaryCommandVersion::DisassemblerVersion(DisassemblerVersion::V1), + ) => ( + self.disassemble(bytecode_path, DisassemblerVersion::V1, print_code_bool)?, + DISASSEMBLER_EXTENSION_V1, + ), + + ( + BytecodeCommandType::Disassemble, + BinaryCommandVersion::DisassemblerVersion(DisassemblerVersion::V2), + ) => ( + self.disassemble(bytecode_path, DisassemblerVersion::V2, print_code_bool)?, + DISASSEMBLER_EXTENSION_V2, + ), + + (BytecodeCommandType::Decompile, BinaryCommandVersion::DecompilerVersion(v)) => { + (self.decompile(bytecode_path, v)?, DECOMPILER_EXTENSION) }, - BytecodeCommandType::Decompile => { - (self.decompile(bytecode_path)?, DECOMPILER_EXTENSION) + _ => { + return Err(CliError::UnexpectedError( + "Incorrect bytecode command or incorrect version provided".to_string(), + )); }, }; @@ -232,8 +309,10 @@ impl BytecodeCommand { language_version: LanguageVersion::V1.to_string(), }; let metadata = if self.is_script { - let script = CompiledScript::deserialize(&bytecode_bytes) - .context("Script blob can't be deserialized")?; + let script = CompiledScript::deserialize(&bytecode_bytes).context(format!( + "Script blob at {} can't be deserialized", + bytecode_path.display() + ))?; if let Some(data) = get_compilation_metadata(&script) { serde_json::to_string_pretty(&data).expect("expect compilation metadata") } else { @@ -245,8 +324,10 @@ impl BytecodeCommand { compilation_metadata: get_compilation_metadata(&script).unwrap_or(v1_metadata), } } else { - let module = CompiledModule::deserialize(&bytecode_bytes) - .context("Module blob can't be deserialized")?; + let module = CompiledModule::deserialize(&bytecode_bytes).context(format!( + "Module blob at {} can't be deserialized", + bytecode_path.display() + ))?; BytecodeMetadata { aptos_metadata: get_metadata_from_compiled_code(&module), bytecode_version: module.version, @@ -260,8 +341,34 @@ impl BytecodeCommand { Ok("ok".to_string()) } - fn disassemble(&self, bytecode_path: &Path) -> Result { + fn disassemble( + &self, + bytecode_path: &Path, + version: DisassemblerVersion, + print_code_size: bool, + ) -> Result { + match version { + DisassemblerVersion::V1 => self.disassemble_v1(bytecode_path, print_code_size), + DisassemblerVersion::V2 => self.disassemble_v2(bytecode_path, print_code_size), + } + } + + fn disassemble_v1( + &self, + bytecode_path: &Path, + print_code_size: bool, + ) -> Result { let bytecode_bytes = read_from_file(bytecode_path)?; + if print_code_size { + println!( + "Code size of module {} is: {} kbs", + bytecode_path + .file_name() + .unwrap_or_default() + .to_string_lossy(), + bytecode_bytes.len() / 1024 + ); + } let source = { let move_path = bytecode_path.with_extension(MOVE_EXTENSION); @@ -305,18 +412,23 @@ impl BytecodeCommand { only_externally_visible: false, print_basic_blocks: true, print_locals: true, - print_bytecode_stats: false, + print_bytecode_stats: print_code_size, + print_code_size, }; let no_loc = Spanned::unsafe_no_loc(()).loc; let module: CompiledModule; let script: CompiledScript; let bytecode = if self.is_script { - script = CompiledScript::deserialize(&bytecode_bytes) - .context("Script blob can't be deserialized")?; + script = CompiledScript::deserialize(&bytecode_bytes).context(format!( + "Script blob at {} can't be deserialized", + bytecode_path.display() + ))?; BinaryIndexedView::Script(&script) } else { - module = CompiledModule::deserialize(&bytecode_bytes) - .context("Module blob can't be deserialized")?; + module = CompiledModule::deserialize(&bytecode_bytes).context(format!( + "Module blob at {} can't be deserialized", + bytecode_path.display() + ))?; BinaryIndexedView::Module(&module) }; @@ -348,7 +460,56 @@ impl BytecodeCommand { .map_err(|err| CliError::UnexpectedError(format!("Unable to disassemble: {}", err))) } - fn decompile(&self, bytecode_path: &Path) -> Result { + fn disassemble_v2( + &self, + bytecode_path: &Path, + print_code_size: bool, + ) -> Result { + let bytecode_bytes = read_from_file(bytecode_path)?; + if print_code_size { + println!( + "Code size of module {} is: {} kbs", + bytecode_path + .file_name() + .unwrap_or_default() + .to_string_lossy(), + bytecode_bytes.len() / 1024 + ); + } + if self.is_script { + let script = CompiledScript::deserialize(&bytecode_bytes).context(format!( + "Script blob at {} can't be deserialized", + bytecode_path.display() + ))?; + Ok(move_asm::disassembler::disassemble_script( + String::new(), + &script, + )?) + } else { + let module = CompiledModule::deserialize(&bytecode_bytes).context(format!( + "Module blob at {} can't be deserialized", + bytecode_path.display() + ))?; + Ok(move_asm::disassembler::disassemble_module( + String::new(), + &module, + print_code_size, + )?) + } + } + + fn decompile( + &self, + bytecode_path: &Path, + version: DecompilerVersion, + ) -> Result { + match version { + DecompilerVersion::V1 => self.decompile_v1(bytecode_path), + DecompilerVersion::V2 => self.decompile_v2(bytecode_path), + } + } + + fn decompile_v1(&self, bytecode_path: &Path) -> Result { let exe = get_revela_path()?; let to_cli_error = |e| CliError::IO(exe.display().to_string(), e); let mut cmd = Command::new(exe.as_path()); @@ -380,6 +541,27 @@ impl BytecodeCommand { } } + fn decompile_v2(&self, bytecode_path: &Path) -> Result { + let bytecode_bytes = read_from_file(bytecode_path)?; + let mut decompiler = Decompiler::new(DecompilerOptions::default()); + let source_map = + decompiler.empty_source_map(&bytecode_path.to_string_lossy(), &bytecode_bytes); + let res = if self.is_script { + let script = CompiledScript::deserialize(&bytecode_bytes).context(format!( + "Script blob at {} can't be deserialized", + bytecode_path.display() + ))?; + decompiler.decompile_script(script, source_map)? + } else { + let module = CompiledModule::deserialize(&bytecode_bytes).context(format!( + "Module blob at {} can't be deserialized", + bytecode_path.display() + ))?; + decompiler.decompile_module(module, source_map)? + }; + Ok(res) + } + fn downgrade_to_v6(&self, file_path: &Path) -> Result, CliError> { let error_explanation = || { format!( diff --git a/crates/aptos/src/move_tool/coverage.rs b/crates/aptos/src/move_tool/coverage.rs index c370ca2e429..7d51bab6f23 100644 --- a/crates/aptos/src/move_tool/coverage.rs +++ b/crates/aptos/src/move_tool/coverage.rs @@ -190,6 +190,7 @@ fn compile_coverage( .language_version .or_else(|| Some(LanguageVersion::latest_stable())), experiments: move_options.compute_experiments(), + print_errors: true, }, ..Default::default() }; diff --git a/crates/aptos/src/move_tool/lint.rs b/crates/aptos/src/move_tool/lint.rs index 3b2e058c43f..69d2451bfeb 100644 --- a/crates/aptos/src/move_tool/lint.rs +++ b/crates/aptos/src/move_tool/lint.rs @@ -5,6 +5,7 @@ use crate::{ common::types::{AccountAddressWrapper, CliCommand, CliTypedResult, MovePackageOptions}, move_tool::IncludedArtifacts, }; +use anyhow::bail; use aptos_framework::{BuildOptions, BuiltPackage}; use async_trait::async_trait; use clap::Parser; @@ -12,7 +13,7 @@ use move_compiler_v2::Experiment; use move_linter::MoveLintChecks; use move_model::metadata::{CompilerVersion, LanguageVersion, LATEST_STABLE_LANGUAGE_VERSION}; use move_package::source_package::std_lib::StdVersion; -use std::{collections::BTreeMap, path::PathBuf}; +use std::{collections::BTreeMap, path::PathBuf, str::FromStr}; /// Run a Lint tool to show additional warnings about the current package, in addition to ordinary /// warnings and/or errors generated by the Move 2 compiler. @@ -73,6 +74,17 @@ pub struct LintPackage { /// Experiments #[clap(long, hide(true))] pub experiments: Vec, + + /// Select the category of lint checks to run + /// + /// This can be one of: + /// - "default": Run the default lint checks, curated to minimize false positives. + /// - "strict": Run lint checks that are more strict and may produce more false positives. + /// Also runs the default checks. + /// - "experimental": Run experimental lint checks that are not yet stable. + /// Also runs the strict and default checks. + #[clap(long, verbatim_doc_comment, value_parser = clap::value_parser!(LintOptions))] + pub checks: Option, } impl LintPackage { @@ -87,6 +99,7 @@ impl LintPackage { language_version, skip_attribute_checks, experiments, + checks: _, // these are passed directly to the lint maker } = self.clone(); MovePackageOptions { dev, @@ -103,6 +116,43 @@ impl LintPackage { } } +#[derive(Clone, Debug, Default, Parser)] +pub enum LintOptions { + /// Run the default lint checks, curated to minimize false positives. + #[default] + Default, + /// Run lint checks that are more strict and may produce more false positives. + /// Also includes the default checks. + Strict, + /// Run experimental lint checks that are not yet stable. + /// Includes all strict and default checks. + Experimental, +} + +impl FromStr for LintOptions { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "" | "default" => Ok(LintOptions::Default), + "strict" => Ok(LintOptions::Strict), + "experimental" => Ok(LintOptions::Experimental), + _ => bail!("unrecognized lint option: `{}` (expected one of: `default`, `strict`, `experimental`)", s), + } + } +} + +impl LintOptions { + pub fn to_config(&self) -> BTreeMap { + let value = match self { + LintOptions::Default => "default", + LintOptions::Strict => "strict", + LintOptions::Experimental => "experimental", + }; + BTreeMap::from([("checks".to_string(), value.to_string())]) + } +} + #[async_trait] impl CliCommand<&'static str> for LintPackage { fn command_name(&self) -> &'static str { @@ -138,7 +188,9 @@ impl CliCommand<&'static str> for LintPackage { resolved_graph, build_options, build_config, - vec![MoveLintChecks::make()], + vec![MoveLintChecks::make( + self.checks.unwrap_or_default().to_config(), + )], )?; Ok("succeeded") diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs index 78b6b34b4a7..28f5394037b 100644 --- a/crates/aptos/src/move_tool/mod.rs +++ b/crates/aptos/src/move_tool/mod.rs @@ -15,7 +15,7 @@ use crate::{ }, utils::{ check_if_file_exists, create_dir_if_not_exist, dir_default_to_current, - profile_or_submit, prompt_yes_with_override, write_to_file, + dispatch_transaction, prompt_yes_with_override, write_to_file, }, }, governance::CompileScriptFunction, @@ -25,6 +25,7 @@ use crate::{ fmt::Fmt, lint::LintPackage, manifest::{Dependency, ManifestNamedAddress, MovePackageManifest, PackageInfo}, + sim::Sim, }, CliCommand, CliResult, }; @@ -51,7 +52,9 @@ use aptos_types::{ account_address::{create_resource_address, AccountAddress}, object_address::create_object_code_deployment_address, on_chain_config::aptos_test_feature_flags_genesis, - transaction::{Transaction, TransactionArgument, TransactionPayload, TransactionStatus}, + transaction::{ + ReplayProtector, Transaction, TransactionArgument, TransactionPayload, TransactionStatus, + }, }; use aptos_vm::data_cache::AsMoveResolver; use async_trait::async_trait; @@ -60,11 +63,12 @@ use colored::Colorize; use itertools::Itertools; use move_cli::{self, base::test::UnitTestResult}; use move_command_line_common::{address::NumericalAddress, env::MOVE_HOME}; -use move_core_types::{identifier::Identifier, language_storage::ModuleId, u256::U256}; +use move_core_types::{identifier::Identifier, int256::U256, language_storage::ModuleId}; use move_model::metadata::{CompilerVersion, LanguageVersion}; use move_package::{source_package::layout::SourcePackageLayout, BuildConfig, CompilerConfig}; use move_unit_test::UnitTestingConfig; pub use package_hooks::*; +use rand::SeedableRng; use serde::{Deserialize, Serialize}; use serde_json::json; use std::{ @@ -76,7 +80,6 @@ use std::{ pub use stored_package::*; use tokio::task; use url::Url; - pub mod aptos_debug_natives; mod bytecode; pub mod coverage; @@ -85,6 +88,7 @@ mod lint; mod manifest; pub mod package_hooks; mod show; +mod sim; pub mod stored_package; const HELLO_BLOCKCHAIN_EXAMPLE: &str = include_str!( @@ -133,6 +137,8 @@ pub enum MoveTool { View(ViewFunction), Replay(Replay), Fmt(Fmt), + #[clap(subcommand)] + Sim(Sim), } impl MoveTool { @@ -171,6 +177,7 @@ impl MoveTool { MoveTool::Replay(tool) => tool.execute_serialized().await, MoveTool::Fmt(tool) => tool.execute_serialized().await, MoveTool::Lint(tool) => tool.execute_serialized().await, + MoveTool::Sim(tool) => tool.execute().await, } } } @@ -207,7 +214,7 @@ impl FrameworkPackageArgs { prompt_options: PromptOptions, ) -> CliTypedResult<()> { const APTOS_FRAMEWORK: &str = "AptosFramework"; - const APTOS_GIT_PATH: &str = "https://github.com/movementlabsxyz/aptos-core.git"; + const APTOS_GIT_PATH: &str = "https://github.com/movement-network/aptos-core.git"; const SUBDIR_PATH: &str = "aptos-move/framework/aptos-framework"; const DEFAULT_BRANCH: &str = "m1"; @@ -232,30 +239,24 @@ impl FrameworkPackageArgs { // Add the framework dependency if it's provided let mut dependencies = BTreeMap::new(); if let Some(ref path) = self.framework_local_dir { - dependencies.insert( - APTOS_FRAMEWORK.to_string(), - Dependency { - local: Some(path.display().to_string()), - git: None, - rev: None, - subdir: None, - aptos: None, - address: None, - }, - ); + dependencies.insert(APTOS_FRAMEWORK.to_string(), Dependency { + local: Some(path.display().to_string()), + git: None, + rev: None, + subdir: None, + aptos: None, + address: None, + }); } else { let git_rev = self.framework_git_rev.as_deref().unwrap_or(DEFAULT_BRANCH); - dependencies.insert( - APTOS_FRAMEWORK.to_string(), - Dependency { - local: None, - git: Some(APTOS_GIT_PATH.to_string()), - rev: Some(git_rev.to_string()), - subdir: Some(SUBDIR_PATH.to_string()), - aptos: None, - address: None, - }, - ); + dependencies.insert(APTOS_FRAMEWORK.to_string(), Dependency { + local: None, + git: Some(APTOS_GIT_PATH.to_string()), + rev: Some(git_rev.to_string()), + subdir: Some(SUBDIR_PATH.to_string()), + aptos: None, + address: None, + }); } let manifest = MovePackageManifest { @@ -542,6 +543,10 @@ pub struct TestPackage { /// Dump storage state on failure. #[clap(long = "dump")] pub dump_state: bool, + + /// Fail-fast mode: stop running tests after the first failure. + #[clap(long = "fail-fast")] + pub fail_fast: bool, } pub(crate) fn fix_bytecode_version( @@ -590,6 +595,7 @@ impl CliCommand<&'static str> for TestPackage { .language_version .or_else(|| Some(LanguageVersion::latest_stable())), experiments: self.move_options.compute_experiments(), + print_errors: true, }, ..Default::default() }; @@ -600,7 +606,6 @@ impl CliCommand<&'static str> for TestPackage { config.clone(), UnitTestingConfig { filter: self.filter.clone(), - report_stacktrace_on_abort: true, report_storage_on_error: self.dump_state, ignore_compile_warnings: self.ignore_compile_warnings, named_address_values: self @@ -614,6 +619,7 @@ impl CliCommand<&'static str> for TestPackage { ) }) .collect(), + fail_fast: self.fail_fast, ..UnitTestingConfig::default() }, // TODO(Gas): we may want to switch to non-zero costs in the future @@ -626,6 +632,7 @@ impl CliCommand<&'static str> for TestPackage { None, self.compute_coverage, &mut std::io::stdout(), + true, ) .map_err(|err| CliError::UnexpectedError(format!("Failed to run tests: {:#}", err)))?; @@ -897,14 +904,11 @@ impl FromStr for IncludedArtifacts { } impl IncludedArtifacts { - pub(crate) fn build_options( - self, - move_options: &MovePackageOptions, - ) -> CliTypedResult { + pub fn build_options(self, move_options: &MovePackageOptions) -> CliTypedResult { self.build_options_with_experiments(move_options, vec![], false) } - pub(crate) fn build_options_with_experiments( + pub fn build_options_with_experiments( self, move_options: &MovePackageOptions, mut more_experiments: Vec, @@ -1061,7 +1065,7 @@ impl CliCommand for PublishPackage { .await } else { let package_publication_data: PackagePublicationData = (&self).try_into()?; - profile_or_submit(package_publication_data.payload, &self.txn_options).await + dispatch_transaction(package_publication_data.payload, &self.txn_options).await } } } @@ -2141,7 +2145,7 @@ impl CliCommand for RunFunction { } async fn execute(self) -> CliTypedResult { - profile_or_submit( + dispatch_transaction( TransactionPayload::EntryFunction(self.entry_function_args.try_into()?), &self.txn_options, ) @@ -2181,7 +2185,8 @@ impl CliCommand for Simulate { if self.local { self.txn_options.simulate_locally(payload).await } else { - self.txn_options.simulate_remotely(payload).await + let mut rng = rand::rngs::StdRng::from_entropy(); + self.txn_options.simulate_remotely(&mut rng, payload).await } } } @@ -2230,7 +2235,7 @@ impl CliCommand for RunScript { .compile_proposal_args .compile("RunScript", self.txn_options.prompt_options)?; - profile_or_submit( + dispatch_transaction( self.script_function_args.create_script_payload(bytecode)?, &self.txn_options, ) @@ -2246,6 +2251,21 @@ pub enum ReplayNetworkSelection { RestEndpoint(String), } +impl ReplayNetworkSelection { + pub fn to_base_url(&self) -> CliTypedResult { + match self { + ReplayNetworkSelection::Mainnet => Ok(AptosBaseUrl::Mainnet), + ReplayNetworkSelection::Testnet => Ok(AptosBaseUrl::Testnet), + ReplayNetworkSelection::Devnet => Ok(AptosBaseUrl::Devnet), + ReplayNetworkSelection::RestEndpoint(url) => { + Ok(AptosBaseUrl::Custom(Url::parse(url).map_err(|e| { + CliError::UnableToParse("url", e.to_string()) + })?)) + }, + } + } +} + /// Replay a comitted transaction using a local VM. #[derive(Parser, Debug)] pub struct Replay { @@ -2298,8 +2318,6 @@ impl CliCommand for Replay { } async fn execute(self) -> CliTypedResult { - use ReplayNetworkSelection::*; - if self.profile_gas && self.benchmark { return Err(CliError::UnexpectedError( "Cannot perform benchmarking and gas profiling at the same time.".to_string(), @@ -2307,10 +2325,10 @@ impl CliCommand for Replay { } let rest_endpoint = match &self.network { - Mainnet => "https://mainnet.movementnetwork.xyz", - Testnet => "https://testnet.movementnetwork.xyz", - Devnet => "https://devnet.movementnetwork.xyz", - RestEndpoint(url) => url, + ReplayNetworkSelection::Mainnet => "https://mainnet.movementnetwork.xyz", + ReplayNetworkSelection::Testnet => "https://testnet.movementnetwork.xyz", + ReplayNetworkSelection::Devnet => "https://devnet.movementnetwork.xyz", + ReplayNetworkSelection::RestEndpoint(url) => url, }; // Build the client @@ -2329,7 +2347,7 @@ impl CliCommand for Replay { let debugger = AptosDebugger::rest_client(client)?; // Fetch the transaction to replay. - let (txn, txn_info) = debugger + let (txn, txn_info, aux_info) = debugger .get_committed_transaction_at_version(self.txn_id) .await?; @@ -2353,6 +2371,7 @@ impl CliCommand for Replay { self.txn_id, txn.clone(), hash, + aux_info, )? } else if self.benchmark { println!("Benchmarking transaction..."); @@ -2361,6 +2380,7 @@ impl CliCommand for Replay { self.txn_id, txn.clone(), hash, + aux_info, )? } else { println!("Replaying transaction..."); @@ -2369,6 +2389,7 @@ impl CliCommand for Replay { self.txn_id, txn.clone(), hash, + aux_info, )? }; @@ -2403,7 +2424,11 @@ impl CliCommand for Replay { gas_unit_price: Some(txn.gas_unit_price()), pending: None, sender: Some(txn.sender()), - sequence_number: Some(txn.sequence_number()), + sequence_number: match txn.replay_protector() { + ReplayProtector::SequenceNumber(sequence_number) => Some(sequence_number), + _ => None, + }, + replay_protector: Some(txn.replay_protector()), success, timestamp_us: None, version: Some(self.txn_id), diff --git a/crates/aptos/src/move_tool/sim.rs b/crates/aptos/src/move_tool/sim.rs new file mode 100644 index 00000000000..e5c8f0b120a --- /dev/null +++ b/crates/aptos/src/move_tool/sim.rs @@ -0,0 +1,189 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + common::types::{CliCommand, CliResult, CliTypedResult}, + move_tool::ReplayNetworkSelection, +}; +use aptos_rest_client::Client; +use aptos_transaction_simulation_session::Session; +use async_trait::async_trait; +use clap::{Parser, Subcommand}; +use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; +use std::path::PathBuf; + +/// Initializes a new simulation session +#[derive(Debug, Parser)] +pub struct Init { + /// Path to the directory where the session data will be stored. + #[clap(long)] + path: PathBuf, + + /// If specified, starts the simulation by forking from a remote network state. + #[clap(long)] + network: Option, + + /// The version of the network state to fork from. + /// + /// Only used if `--network` is specified. + /// + /// If not specified, the latest version of the network will be used. + #[clap(long)] + network_version: Option, + + /// API key for connecting to the fullnode. + /// + /// It is strongly recommended to specify an API key to avoid rate limiting. + #[clap(long)] + api_key: Option, +} + +#[async_trait] +impl CliCommand<()> for Init { + fn command_name(&self) -> &'static str { + "init" + } + + async fn execute(self) -> CliTypedResult<()> { + match self.network { + Some(network) => { + let network_version = match self.network_version { + Some(txn_id) => txn_id, + None => { + let client = Client::builder(network.to_base_url()?).build(); + client.get_ledger_information().await?.inner().version + }, + }; + let base_url = network.to_base_url()?; + let url = base_url.to_url(); + + Session::init_with_remote_state(&self.path, url, network_version, self.api_key)?; + }, + None => { + Session::init(&self.path)?; + }, + } + + Ok(()) + } +} + +/// Funds an account with APT tokens +#[derive(Debug, Parser)] +pub struct Fund { + /// Path to a stored session + #[clap(long)] + session: PathBuf, + + /// Account to fund, can be an address or a CLI profile name + #[clap(long, value_parser = crate::common::types::load_account_arg)] + account: AccountAddress, + + /// Funding amount, in Octa (10^-8 APT) + #[clap(long)] + amount: u64, +} + +#[async_trait] +impl CliCommand<()> for Fund { + fn command_name(&self) -> &'static str { + "fund" + } + + async fn execute(self) -> CliTypedResult<()> { + let mut session = Session::load(&self.session)?; + + session.fund_account(self.account, self.amount)?; + + Ok(()) + } +} + +/// View a resource +#[derive(Debug, Parser)] +pub struct ViewResource { + /// Path to a stored session + #[clap(long)] + session: PathBuf, + + /// Account under which the resource is stored + #[clap(long, value_parser = crate::common::types::load_account_arg)] + account: AccountAddress, + + /// Resource to view + #[clap(long)] + resource: StructTag, +} + +#[async_trait] +impl CliCommand> for ViewResource { + fn command_name(&self) -> &'static str { + "view-resource" + } + + async fn execute(self) -> CliTypedResult> { + let mut session = Session::load(&self.session)?; + + Ok(session.view_resource(self.account, &self.resource)?) + } +} + +/// View a resource group +#[derive(Debug, Parser)] +pub struct ViewResourceGroup { + /// Path to a stored session + #[clap(long)] + session: PathBuf, + + /// Account under which the resource group is stored + #[clap(long, value_parser = crate::common::types::load_account_arg)] + account: AccountAddress, + + /// Resource group to view + #[clap(long)] + resource_group: StructTag, + + /// If specified, derives an object address from the source address and an object + #[clap(long)] + derived_object_address: Option, +} + +#[async_trait] +impl CliCommand> for ViewResourceGroup { + fn command_name(&self) -> &'static str { + "view-resource-group" + } + + async fn execute(self) -> CliTypedResult> { + let mut session = Session::load(&self.session)?; + Ok(session.view_resource_group( + self.account, + &self.resource_group, + self.derived_object_address, + )?) + } +} + +/// BETA: Commands for interacting with a local simulation session +/// +/// BETA: Subject to change +#[derive(Subcommand)] +pub enum Sim { + Init(Init), + Fund(Fund), + ViewResource(ViewResource), + ViewResourceGroup(ViewResourceGroup), +} + +impl Sim { + pub async fn execute(self) -> CliResult { + match self { + Sim::Init(init) => init.execute_serialized_success().await, + Sim::Fund(fund) => fund.execute_serialized_success().await, + Sim::ViewResource(view_resource) => view_resource.execute_serialized().await, + Sim::ViewResourceGroup(view_resource_group) => { + view_resource_group.execute_serialized().await + }, + } + } +} diff --git a/crates/aptos/src/node/local_testnet/docker.rs b/crates/aptos/src/node/local_testnet/docker.rs index 23a780cddc4..c0daf2c2711 100644 --- a/crates/aptos/src/node/local_testnet/docker.rs +++ b/crates/aptos/src/node/local_testnet/docker.rs @@ -111,6 +111,20 @@ pub async fn pull_docker_image(image_name: &str) -> Result<()> { } /// Create a network. If the network already exists, that's fine, just move on. +/// Check if a Docker network exists. +pub async fn network_exists(network_name: &str) -> Result { + let docker = get_docker().await?; + + // Try to inspect the network. If it exists, this will succeed. + match docker.inspect_network::<&str>(network_name, None).await { + Ok(_) => Ok(true), + Err(BollardError::DockerResponseServerError { + status_code: 404, .. + }) => Ok(false), + Err(err) => Err(err.into()), + } +} + pub async fn create_network(network_name: &str) -> Result<()> { let docker = get_docker().await?; diff --git a/crates/aptos/src/node/local_testnet/indexer_api.rs b/crates/aptos/src/node/local_testnet/indexer_api.rs index 5d0ca124f0d..8b8d06c5620 100644 --- a/crates/aptos/src/node/local_testnet/indexer_api.rs +++ b/crates/aptos/src/node/local_testnet/indexer_api.rs @@ -4,7 +4,7 @@ use super::{ docker::{ delete_container, get_docker, pull_docker_image, setup_docker_logging, - StopContainerShutdownStep, CONTAINER_NETWORK_NAME, + StopContainerShutdownStep, }, health_checker::HealthChecker, traits::{PostHealthyStep, ServiceManager, ShutdownStep}, @@ -70,6 +70,7 @@ pub struct IndexerApiManager { prerequisite_health_checkers: HashSet, test_dir: PathBuf, postgres_connection_string: String, + docker_network: String, } impl IndexerApiManager { @@ -79,6 +80,7 @@ impl IndexerApiManager { test_dir: PathBuf, postgres_connection_string: String, ) -> Result { + let (docker_network, _) = args.get_docker_network(); Ok(Self { indexer_api_port: args.indexer_api_args.indexer_api_port, existing_hasura_url: args.indexer_api_args.existing_hasura_url.clone(), @@ -86,6 +88,7 @@ impl IndexerApiManager { prerequisite_health_checkers, test_dir, postgres_connection_string, + docker_network: docker_network.to_string(), }) } @@ -188,7 +191,7 @@ impl ServiceManager for IndexerApiManager { // in the Postgres pre_run steps. ( self.postgres_connection_string, - Some(CONTAINER_NETWORK_NAME.to_string()), + Some(self.docker_network.clone()), ) }; diff --git a/crates/aptos/src/node/local_testnet/mod.rs b/crates/aptos/src/node/local_testnet/mod.rs index c1b59511914..ffdac039ac9 100644 --- a/crates/aptos/src/node/local_testnet/mod.rs +++ b/crates/aptos/src/node/local_testnet/mod.rs @@ -105,9 +105,26 @@ pub struct RunLocalnet { /// By default, tracing output goes to files. With this set, it goes to stdout. #[clap(long, hide = true)] log_to_stdout: bool, + + /// If set, use an existing Docker network instead of creating a new one. + /// + /// When specified, the CLI will verify that this network exists and use it for all + /// Docker containers in the localnet. If not specified, a network named + /// "aptos-local-testnet-network" will be created automatically. + #[clap(long)] + docker_network: Option, } impl RunLocalnet { + /// Get the Docker network name to use for containers and whether it already exists. + /// We assume if the user provided a network name that it exists. + pub fn get_docker_network(&self) -> (&str, bool) { + match self.docker_network { + Some(ref network_name) => (network_name, true), + None => (docker::CONTAINER_NETWORK_NAME, false), + } + } + /// Wait for many services to start up. This prints a message like "X is starting, /// please wait..." for each service and then "X is ready. Endpoint: " /// when it's ready. @@ -192,6 +209,29 @@ impl CliCommand<()> for RunLocalnet { setup_logging(None); } + if !self.indexer_api_args.with_indexer_api && self.docker_network.is_some() { + return Err(CliError::UnexpectedError( + "You cannot specify --docker-network without --with-indexer-api, Docker is only used when --with-indexer-api is set.".to_string(), + )); + } + + // If a custom Docker network is specified, verify that it exists. We only need + // to do this if the indexer API is being run, otherwise we don't use Docker. + if let Some(ref network_name) = self.docker_network { + if !docker::network_exists(network_name).await.map_err(|e| { + CliError::UnexpectedError(format!( + "Failed to check if Docker network exists: {}", + e + )) + })? { + return Err(CliError::UnexpectedError(format!( + "Docker network '{}' does not exist. Please create it first or omit --docker-network to use the default network.", + network_name + ))); + } + info!("Using existing Docker network: {}", network_name); + } + // Based on the input and global config, get the test directory. let test_dir = get_derived_test_dir(&self.test_dir)?; diff --git a/crates/aptos/src/node/local_testnet/node.rs b/crates/aptos/src/node/local_testnet/node.rs index e51a63a73fe..d1e393ccc80 100644 --- a/crates/aptos/src/node/local_testnet/node.rs +++ b/crates/aptos/src/node/local_testnet/node.rs @@ -164,6 +164,9 @@ impl NodeManager { node_config.indexer_grpc.address.set_ip(IpAddr::V4(bind_to)); node_config.admin_service.address = bind_to.to_string(); node_config.inspection_service.address = bind_to.to_string(); + node_config.indexer_db_config.enable_event = true; + node_config.indexer_db_config.enable_statekeys = true; + node_config.indexer_db_config.enable_transaction = true; Ok(NodeManager { config: node_config, @@ -173,11 +176,21 @@ impl NodeManager { } pub fn get_node_api_url(&self) -> Url { - socket_addr_to_url(&self.config.api.address, "http").unwrap() + let mut addr = self.config.api.address; + // If bound to 0.0.0.0, clients should connect to 127.0.0.1 instead. + if addr.ip().is_unspecified() { + addr.set_ip(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); + } + socket_addr_to_url(&addr, "http").unwrap() } pub fn get_data_service_url(&self) -> Url { - socket_addr_to_url(&self.config.indexer_grpc.address, "http").unwrap() + let mut addr = self.config.indexer_grpc.address; + // If bound to 0.0.0.0, clients should connect to 127.0.0.1 instead. + if addr.ip().is_unspecified() { + addr.set_ip(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); + } + socket_addr_to_url(&addr, "http").unwrap() } } @@ -195,8 +208,7 @@ impl ServiceManager for NodeManager { let mut checkers = HashSet::new(); checkers.insert(HealthChecker::NodeApi(node_api_url)); if self.config.indexer_grpc.enabled { - let data_service_url = - socket_addr_to_url(&self.config.indexer_grpc.address, "http").unwrap(); + let data_service_url = self.get_data_service_url(); checkers.insert(HealthChecker::DataServiceGrpc(data_service_url)); } checkers diff --git a/crates/aptos/src/node/local_testnet/postgres.rs b/crates/aptos/src/node/local_testnet/postgres.rs index d348d979b12..a2547aec966 100644 --- a/crates/aptos/src/node/local_testnet/postgres.rs +++ b/crates/aptos/src/node/local_testnet/postgres.rs @@ -4,7 +4,7 @@ use super::{ docker::{ create_network, create_volume, delete_container, delete_volume, get_docker, - pull_docker_image, setup_docker_logging, StopContainerShutdownStep, CONTAINER_NETWORK_NAME, + pull_docker_image, setup_docker_logging, StopContainerShutdownStep, }, health_checker::HealthChecker, traits::{ServiceManager, ShutdownStep}, @@ -121,6 +121,8 @@ pub struct PostgresManager { args: PostgresArgs, test_dir: PathBuf, force_restart: bool, + docker_network: String, + docker_network_already_exists: bool, } impl PostgresManager { @@ -130,10 +132,13 @@ impl PostgresManager { { bail!("The postgres database cannot be named postgres if --use-host-postgres is set"); } + let (docker_network, docker_network_already_exists) = args.get_docker_network(); Ok(Self { args: args.postgres_args.clone(), test_dir, force_restart: args.force_restart, + docker_network: docker_network.to_string(), + docker_network_already_exists, }) } @@ -192,8 +197,11 @@ impl ServiceManager for PostgresManager { // `run_service`. pull_docker_image(POSTGRES_IMAGE).await?; - // Create a network for the containers to talk to each other. - create_network(CONTAINER_NETWORK_NAME).await?; + // Create a network for the containers to talk to each other if a + // pre-existing network was not specified. + if !self.docker_network_already_exists { + create_network(&self.docker_network).await?; + } } Ok(()) @@ -243,7 +251,7 @@ impl ServiceManager for PostgresManager { // Bind the container to the network we created in the pre_run. This does // not prevent the binary in the container from exposing itself to the host // on 127.0.0.1. See more here: https://stackoverflow.com/a/77432636/3846032. - network_mode: Some(CONTAINER_NETWORK_NAME.to_string()), + network_mode: Some(self.docker_network.clone()), port_bindings: Some(hashmap! { POSTGRES_DEFAULT_PORT.to_string() => Some(vec![PortBinding { host_ip: Some("127.0.0.1".to_string()), diff --git a/crates/aptos/src/node/local_testnet/ready_server.rs b/crates/aptos/src/node/local_testnet/ready_server.rs index 632e4404725..0a79515f65e 100644 --- a/crates/aptos/src/node/local_testnet/ready_server.rs +++ b/crates/aptos/src/node/local_testnet/ready_server.rs @@ -108,7 +108,7 @@ struct ReadyData { } #[handler] -async fn root(health_checkers: Data<&HealthCheckers>) -> impl IntoResponse { +async fn root(health_checkers: Data<&HealthCheckers>) -> impl IntoResponse + use<> { let mut ready = vec![]; let mut not_ready = vec![]; for health_checker in &health_checkers.health_checkers { diff --git a/crates/aptos/src/node/mod.rs b/crates/aptos/src/node/mod.rs index e062e721cc9..056162b0f86 100644 --- a/crates/aptos/src/node/mod.rs +++ b/crates/aptos/src/node/mod.rs @@ -155,7 +155,7 @@ impl ValidatorConsensusKeyArgs { let consensus_public_key = if let Some(ref consensus_public_key) = self.consensus_public_key { consensus_public_key - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { &operator_config.consensus_public_key } else { return Err(CliError::CommandArgumentError( @@ -171,7 +171,7 @@ impl ValidatorConsensusKeyArgs { ) -> CliTypedResult<&'a bls12381::ProofOfPossession> { let proof_of_possession = if let Some(ref proof_of_possession) = self.proof_of_possession { proof_of_possession - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { &operator_config.consensus_proof_of_possession } else { return Err(CliError::CommandArgumentError( @@ -218,7 +218,7 @@ impl ValidatorNetworkAddressesArgs { let validator_network_public_key = if let Some(public_key) = self.validator_network_public_key { public_key - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { operator_config.validator_network_public_key } else { return Err(CliError::CommandArgumentError( @@ -230,7 +230,7 @@ impl ValidatorNetworkAddressesArgs { let full_node_network_public_key = if let Some(public_key) = self.full_node_network_public_key { Some(public_key) - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { operator_config.full_node_network_public_key } else { None @@ -238,7 +238,7 @@ impl ValidatorNetworkAddressesArgs { let validator_host = if let Some(ref host) = self.validator_host { host - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { &operator_config.validator_host } else { return Err(CliError::CommandArgumentError( @@ -248,7 +248,7 @@ impl ValidatorNetworkAddressesArgs { let full_node_host = if let Some(ref host) = self.full_node_host { Some(host) - } else if let Some(ref operator_config) = operator_config { + } else if let Some(operator_config) = operator_config { operator_config.full_node_host.as_ref() } else { None diff --git a/crates/aptos/src/test/mod.rs b/crates/aptos/src/test/mod.rs index 82149d7887d..5907c522011 100644 --- a/crates/aptos/src/test/mod.rs +++ b/crates/aptos/src/test/mod.rs @@ -858,6 +858,7 @@ impl CliTestFramework { ignore_compile_warnings: false, compute_coverage: false, dump_state: false, + fail_fast: false, } .execute() .await diff --git a/crates/aptos/src/update/move_mutation_test.rs b/crates/aptos/src/update/move_mutation_test.rs index 2335b5c757b..4c37f0d6b08 100644 --- a/crates/aptos/src/update/move_mutation_test.rs +++ b/crates/aptos/src/update/move_mutation_test.rs @@ -13,7 +13,7 @@ use self_update::update::ReleaseUpdate; use std::path::PathBuf; const MUTATION_TEST_BINARY_NAME: &str = "move-mutation-test"; -const TARGET_MUTATION_TEST_VERSION: &str = "1.0.0"; +const TARGET_MUTATION_TEST_VERSION: &str = "2.0.0"; const MUTATION_TEST_EXE_ENV: &str = "MUTATION_TEST_EXE"; #[cfg(target_os = "windows")] diff --git a/crates/aptos/src/update/movefmt.rs b/crates/aptos/src/update/movefmt.rs index 7e0440285a7..6c25b51761a 100644 --- a/crates/aptos/src/update/movefmt.rs +++ b/crates/aptos/src/update/movefmt.rs @@ -13,7 +13,7 @@ use self_update::update::ReleaseUpdate; use std::path::PathBuf; const FORMATTER_BINARY_NAME: &str = "movefmt"; -const TARGET_FORMATTER_VERSION: &str = "1.0.8"; +const TARGET_FORMATTER_VERSION: &str = "1.3.7"; const FORMATTER_EXE_ENV: &str = "FORMATTER_EXE"; #[cfg(target_os = "windows")] diff --git a/crates/indexer/src/indexer/tailer.rs b/crates/indexer/src/indexer/tailer.rs index 061ad806b5d..cd024a7dfe8 100644 --- a/crates/indexer/src/indexer/tailer.rs +++ b/crates/indexer/src/indexer/tailer.rs @@ -370,7 +370,7 @@ mod test { } } - pub fn setup_indexer() -> Result<(PgDbPool, Tailer)> { + pub async fn setup_indexer() -> Result<(PgDbPool, Tailer)> { let database_url = std::env::var("INDEXER_DATABASE_URL") .expect("must set 'INDEXER_DATABASE_URL' to run tests!"); let conn_pool = new_db_pool(database_url.as_str())?; @@ -397,7 +397,7 @@ mod test { if crate::should_skip_pg_tests() { return; } - let (conn_pool, tailer) = setup_indexer().unwrap(); + let (conn_pool, tailer) = setup_indexer().await.unwrap(); // An abridged genesis transaction let genesis_txn: Transaction = serde_json::from_value(json!( { @@ -908,7 +908,7 @@ mod test { .await .unwrap(); - let (_conn_pool, tailer) = setup_indexer().unwrap(); + let (_conn_pool, tailer) = setup_indexer().await.unwrap(); tailer.set_fetcher_version(4).await; assert!(tailer.check_or_update_chain_id().await.is_ok()); assert!(tailer.check_or_update_chain_id().await.is_ok()); diff --git a/crates/indexer/src/models/signatures.rs b/crates/indexer/src/models/signatures.rs index 1c9bef2a76a..797b455bf85 100644 --- a/crates/indexer/src/models/signatures.rs +++ b/crates/indexer/src/models/signatures.rs @@ -5,7 +5,7 @@ use crate::{models::transactions::Transaction, schema::signatures, util::standardize_address}; use anyhow::{Context, Result}; use aptos_api_types::{ - AbstractionSignature as APIAbstractionSignature, AccountSignature as APIAccountSignature, + AbstractSignature as APIAbstractSignature, AccountSignature as APIAccountSignature, Ed25519Signature as APIEd25519Signature, FeePayerSignature as APIFeePayerSignature, MultiAgentSignature as APIMultiAgentSignature, MultiEd25519Signature as APIMultiEd25519Signature, MultiKeySignature as APIMultiKeySignature, @@ -314,7 +314,7 @@ impl Signature { multi_agent_index, override_address, )], - APIAccountSignature::AbstractionSignature(sig) => { + APIAccountSignature::AbstractSignature(sig) => { vec![Self::parse_abstraction_signature( sig, sender, @@ -404,7 +404,7 @@ impl Signature { } fn parse_abstraction_signature( - _s: &APIAbstractionSignature, + _s: &APIAbstractSignature, sender: &String, transaction_version: i64, transaction_block_height: i64, diff --git a/crates/indexer/src/util.rs b/crates/indexer/src/util.rs index 9105bc5251d..6422be0b65f 100644 --- a/crates/indexer/src/util.rs +++ b/crates/indexer/src/util.rs @@ -171,20 +171,14 @@ pub fn convert_bcs_hex_new(typ: u8, value: String) -> Option { /// Convert the json serialized PropertyMap's inner BCS fields to their original value in string format pub fn convert_bcs_propertymap(s: Value) -> Option { match PropertyMap::from_bcs_encode_str(s) { - Some(e) => match serde_json::to_value(&e) { - Ok(val) => Some(val), - Err(_) => None, - }, + Some(e) => serde_json::to_value(&e).ok(), None => None, } } pub fn convert_bcs_token_object_propertymap(s: Value) -> Option { match TokenObjectPropertyMap::from_bcs_encode_str(s) { - Some(e) => match serde_json::to_value(&e) { - Ok(val) => Some(val), - Err(_) => None, - }, + Some(e) => serde_json::to_value(&e).ok(), None => None, } } diff --git a/crates/node-resource-metrics/src/collectors/disk_metrics_collector.rs b/crates/node-resource-metrics/src/collectors/disk_metrics_collector.rs index 23430662201..6ee9e4128f3 100644 --- a/crates/node-resource-metrics/src/collectors/disk_metrics_collector.rs +++ b/crates/node-resource-metrics/src/collectors/disk_metrics_collector.rs @@ -82,7 +82,7 @@ impl Collector for DiskMetricsCollector { system.refresh_disks_list(); system.refresh_disks(); - let mfs = system + system .disks() .iter() .flat_map(|disk| { @@ -110,9 +110,7 @@ impl Collector for DiskMetricsCollector { vec![total_space, available_space] }) .flat_map(|metric| metric.collect()) - .collect(); - - mfs + .collect() } } diff --git a/crates/node-resource-metrics/src/collectors/linux_collectors.rs b/crates/node-resource-metrics/src/collectors/linux_collectors.rs index 63372a27a26..4411018ec81 100644 --- a/crates/node-resource-metrics/src/collectors/linux_collectors.rs +++ b/crates/node-resource-metrics/src/collectors/linux_collectors.rs @@ -286,7 +286,7 @@ impl Collector for LinuxDiskMetricsCollector { for mount in mounts { if let Some(disk_stat) = disk_stats.get(&mount.majmin) { - let labels = &[disk_stat.name.clone()]; + let labels = std::slice::from_ref(&disk_stat.name); disk_stats_counter!(mfs, num_reads, disk_stat.reads, labels); disk_stats_counter!(mfs, num_merged_reads, disk_stat.merged, labels); disk_stats_counter!(mfs, num_sectors_read, disk_stat.sectors_read, labels); diff --git a/crates/node-resource-metrics/src/collectors/network_metrics_collector.rs b/crates/node-resource-metrics/src/collectors/network_metrics_collector.rs index a4ce83f1c5c..03558aa4f65 100644 --- a/crates/node-resource-metrics/src/collectors/network_metrics_collector.rs +++ b/crates/node-resource-metrics/src/collectors/network_metrics_collector.rs @@ -124,7 +124,7 @@ impl Collector for NetworkMetricsCollector { system.refresh_networks_list(); system.refresh_networks(); - let mfs = system + system .networks() .iter() .flat_map(|(interface_name, network)| { @@ -175,9 +175,7 @@ impl Collector for NetworkMetricsCollector { ] }) .flat_map(|metric| metric.collect()) - .collect(); - - mfs + .collect() } } diff --git a/crates/reliable-broadcast/src/lib.rs b/crates/reliable-broadcast/src/lib.rs index 7246f2b729a..c2155fe446b 100644 --- a/crates/reliable-broadcast/src/lib.rs +++ b/crates/reliable-broadcast/src/lib.rs @@ -93,7 +93,7 @@ where &self, message: S::Message, aggregating: S, - ) -> impl Future> + 'static + ) -> impl Future> + 'static + use where <>::Response as TryFrom>::Error: Debug, { @@ -106,7 +106,7 @@ where message: S::Message, aggregating: S, receivers: Vec, - ) -> impl Future> + 'static + ) -> impl Future> + 'static + use where <>::Response as TryFrom>::Error: Debug, { diff --git a/crates/transaction-emitter-lib/src/args.rs b/crates/transaction-emitter-lib/src/args.rs index 34e512d187d..d653c95b9c9 100644 --- a/crates/transaction-emitter-lib/src/args.rs +++ b/crates/transaction-emitter-lib/src/args.rs @@ -43,13 +43,13 @@ impl CoinSourceArgs { &self.coin_source_key, &self.coin_source_file, ) { - (Some(ref key), None, None, None) => Ok((key.private_key(), true)), + (Some(key), None, None, None) => Ok((key.private_key(), true)), (None, Some(path), None, None) => Ok(( EncodingType::BCS .load_key::("mint key pair", Path::new(path))?, true, )), - (None, None, Some(ref key), None) => Ok((key.private_key(), false)), + (None, None, Some(key), None) => Ok((key.private_key(), false)), (None, None, None, Some(path)) => Ok(( EncodingType::BCS .load_key::("mint key pair", Path::new(path))?, diff --git a/crates/transaction-emitter-lib/src/emitter/account_minter.rs b/crates/transaction-emitter-lib/src/emitter/account_minter.rs index dac51bcae7f..7b4d69a6b4b 100644 --- a/crates/transaction-emitter-lib/src/emitter/account_minter.rs +++ b/crates/transaction-emitter-lib/src/emitter/account_minter.rs @@ -612,7 +612,7 @@ pub async fn bulk_create_accounts( let seed = config.seed.unwrap_or_else(|| { let mut rng = StdRng::from_entropy(); - rng.gen() + rng.r#gen() }); info!( "AccountMinter Seed (reuse accounts by passing into --account-minter-seed): {:?}", @@ -651,7 +651,7 @@ pub async fn bulk_create_accounts( .all(|account| account.sequence_number() > 0); let all_source_accounts_exist = secondary_source_account .as_ref() - .map_or(true, |v| v.sequence_number() > 0); + .is_none_or(|v| v.sequence_number() > 0); info!( "Accounts exist: {}, seed accounts exist: {}, source account exists: {}", diff --git a/crates/transaction-emitter-lib/src/emitter/mod.rs b/crates/transaction-emitter-lib/src/emitter/mod.rs index 23b220f7621..b4dead31a47 100644 --- a/crates/transaction-emitter-lib/src/emitter/mod.rs +++ b/crates/transaction-emitter-lib/src/emitter/mod.rs @@ -19,7 +19,7 @@ use crate::emitter::{ use again::RetryPolicy; use anyhow::{ensure, format_err, Result}; use aptos_config::config::DEFAULT_MAX_SUBMIT_TRANSACTION_BATCH_SIZE; -use aptos_crypto::ed25519::Ed25519PrivateKey; +use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue}; use aptos_logger::{sample, sample::SampleRate}; use aptos_rest_client::{aptos_api_types::AptosErrorCode, error::RestError, Client as RestClient}; use aptos_sdk::{ @@ -31,7 +31,7 @@ use aptos_transaction_generator_lib::{ create_txn_generator_creator, AccountType, TransactionType, SEND_AMOUNT, }; use aptos_types::account_config::aptos_test_root_address; -use futures::future::{try_join_all, FutureExt}; +use futures::future::{join_all, try_join_all, FutureExt}; use log::{error, info, warn}; use once_cell::sync::Lazy; use rand::{ @@ -993,6 +993,107 @@ fn pick_client(clients: &[RestClient]) -> &RestClient { clients.choose(&mut rand::thread_rng()).unwrap() } +async fn wait_for_orderless_txns( + client: &RestClient, + account_orderless_txns: &HashMap>, + txn_expiration_ts_secs: u64, + sleep_between_cycles: Duration, +) -> HashMap> { + if account_orderless_txns.is_empty() { + return HashMap::new(); + } + let mut pending_account_txns = account_orderless_txns.clone(); + loop { + let futures = pending_account_txns.keys().map(|account| async move { + ( + *account, + FETCH_ACCOUNT_RETRY_POLICY + .retry(move || { + client.get_account_transaction_summaries(*account, None, None, None) + }) + .await, + ) + }); + + let mut latest_ledger_ts_secs = u64::MAX; + for (account, txn_summaries_result) in join_all(futures).await { + match txn_summaries_result { + Ok(response) => { + let ledger_timestamp = + Duration::from_micros(response.state().timestamp_usecs).as_secs(); + latest_ledger_ts_secs = min(ledger_timestamp, latest_ledger_ts_secs); + + for txn_summary in response.into_inner() { + let remove_account = + if let Some(txn_hashes) = pending_account_txns.get_mut(&account) { + txn_hashes.remove(&txn_summary.transaction_hash()); + txn_hashes.is_empty() + } else { + false + }; + if remove_account { + pending_account_txns.remove(&account); + } + } + }, + Err(err) => { + error!( + "Error retrieving summaries for account {}: {:?}", + account, err + ); + }, + } + } + + if pending_account_txns.is_empty() { + break; + } + + if latest_ledger_ts_secs > txn_expiration_ts_secs { + sample!( + SampleRate::Duration(Duration::from_secs(60)), + warn!( + "[{}] Ledger timestamp {} exceeded txn expiration timestamp {} for {:?}", + client.path_prefix_string(), + latest_ledger_ts_secs, + txn_expiration_ts_secs, + pending_account_txns.keys(), + ) + ); + break; + } + + sample!(SampleRate::Duration(Duration::from_secs(15)), { + warn!( + "Num accounts with pending orderless txns: {}", + pending_account_txns.len() + ); + warn!( + "Pending orderless txns per account: {:?}", + pending_account_txns + .iter() + .map(|(account, hashes)| (account, hashes.len())) + .collect::>() + ); + }); + + if aptos_infallible::duration_since_epoch().as_secs() >= txn_expiration_ts_secs + 240 { + sample!( + SampleRate::Duration(Duration::from_secs(15)), + error!( + "[{}] Client cannot catch up to needed timestamp ({}), after additional 240s, aborting", + client.path_prefix_string(), + txn_expiration_ts_secs, + ) + ); + break; + } + + time::sleep(sleep_between_cycles).await; + } + pending_account_txns +} + /// This function waits for the submitted transactions to be committed, up to /// a wait_timeout (counted from the start_time passed in, not from the function call). /// It returns number of transactions that expired without being committed, @@ -1011,6 +1112,11 @@ async fn wait_for_accounts_sequence( let mut latest_fetched_counts = HashMap::new(); let mut sum_of_completion_timestamps_millis = 0u128; + + if pending_addresses.is_empty() { + return (HashMap::new(), sum_of_completion_timestamps_millis); + } + loop { match query_sequence_numbers(client, pending_addresses.iter()).await { Ok((sequence_numbers, ledger_timestamp_secs)) => { diff --git a/crates/transaction-emitter-lib/src/emitter/submission_worker.rs b/crates/transaction-emitter-lib/src/emitter/submission_worker.rs index c8a74b7c7f7..9a8e02b5cfe 100644 --- a/crates/transaction-emitter-lib/src/emitter/submission_worker.rs +++ b/crates/transaction-emitter-lib/src/emitter/submission_worker.rs @@ -4,10 +4,11 @@ use crate::{ emitter::{ stats::{DynamicStatsTracking, StatsAccumulator}, - wait_for_accounts_sequence, + wait_for_accounts_sequence, wait_for_orderless_txns, }, EmitModeParams, }; +use aptos_crypto::HashValue; use aptos_logger::{sample, sample::SampleRate}; use aptos_rest_client::Client as RestClient; use aptos_sdk::{ @@ -15,6 +16,7 @@ use aptos_sdk::{ types::{transaction::SignedTransaction, vm_status::StatusCode, LocalAccount}, }; use aptos_transaction_generator_lib::TransactionGenerator; +use aptos_types::transaction::ReplayProtector; use core::{ cmp::{max, min}, result::Result::{Err, Ok}, @@ -27,7 +29,7 @@ use log::{debug, error, info, warn}; use rand::seq::IteratorRandom; use std::{ borrow::Borrow, - collections::HashMap, + collections::{HashMap, HashSet}, sync::{atomic::AtomicU64, Arc}, time::Instant, }; @@ -101,19 +103,29 @@ impl SubmissionWorker { let requests = self.gen_requests(); if !requests.is_empty() { let mut account_to_start_and_end_seq_num = HashMap::new(); + let mut account_to_orderless_txns: HashMap> = + HashMap::new(); for req in requests.iter() { - let cur = req.sequence_number(); - let _ = *account_to_start_and_end_seq_num - .entry(req.sender()) - .and_modify(|(start, end)| { - if *start > cur { - *start = cur; - } - if *end < cur + 1 { - *end = cur + 1; - } - }) - .or_insert((cur, cur + 1)); + match req.replay_protector() { + ReplayProtector::SequenceNumber(cur) => { + let _ = *account_to_start_and_end_seq_num + .entry(req.sender()) + .and_modify(|(start, end)| { + if *start > cur { + *start = cur; + } + if *end < cur + 1 { + *end = cur + 1; + } + }) + .or_insert((cur, cur + 1)); + }, + ReplayProtector::Nonce(_) => { + let txn_hashes = + account_to_orderless_txns.entry(req.sender()).or_default(); + txn_hashes.insert(req.committed_hash()); + }, + }; } // Some transaction generators use burner accounts, and will have different // number of accounts per transaction, so useful to very rarely log. @@ -176,6 +188,7 @@ impl SubmissionWorker { loop_start_time, txn_offset_time.load(Ordering::Relaxed) / (requests.len() as u64), account_to_start_and_end_seq_num, + account_to_orderless_txns, // skip latency if asked to check seq_num only once // even if we check more often due to stop (to not affect sampling) self.skip_latency_stats, @@ -281,6 +294,7 @@ impl SubmissionWorker { start_time: Instant, avg_txn_offset_time: u64, account_to_start_and_end_seq_num: HashMap, + account_to_orderless_txns: HashMap>, skip_latency_stats: bool, txn_expiration_ts_secs: u64, check_account_sleep_duration: Duration, @@ -296,6 +310,14 @@ impl SubmissionWorker { ) .await; + let failed_orderless_txns = wait_for_orderless_txns( + self.client(), + &account_to_orderless_txns, + txn_expiration_ts_secs, + check_account_sleep_duration, + ) + .await; + for account in self.accounts.iter_mut() { update_account_seq_num( Arc::get_mut(account).unwrap(), @@ -303,8 +325,12 @@ impl SubmissionWorker { &latest_fetched_counts, ); } - let (num_committed, num_expired) = - count_committed_expired_stats(account_to_start_and_end_seq_num, latest_fetched_counts); + let (num_committed, num_expired) = count_committed_expired_stats( + account_to_start_and_end_seq_num, + latest_fetched_counts, + account_to_orderless_txns, + failed_orderless_txns, + ); if num_expired > 0 { loop_stats @@ -331,7 +357,7 @@ impl SubmissionWorker { if !skip_latency_stats { let sum_latency = sum_of_completion_timestamps_millis - - (avg_txn_offset_time as u128 * num_committed as u128); + .saturating_sub(avg_txn_offset_time as u128 * num_committed as u128); let avg_latency = (sum_latency / num_committed as u128) as u64; loop_stats .latency @@ -410,8 +436,10 @@ fn update_account_seq_num( fn count_committed_expired_stats( account_to_start_and_end_seq_num: HashMap, latest_fetched_counts: HashMap, + account_to_orderless_txns: HashMap>, + failed_orderless_txns: HashMap>, ) -> (usize, usize) { - account_to_start_and_end_seq_num + let (seq_num_committed, seq_num_failed) = account_to_start_and_end_seq_num .iter() .map( |(address, (start_seq_num, end_seq_num))| match latest_fetched_counts.get(address) { @@ -441,7 +469,18 @@ fn count_committed_expired_stats( |(committed, expired), (cur_committed, cur_expired)| { (committed + cur_committed, expired + cur_expired) }, - ) + ); + let total_orderless_txns: usize = account_to_orderless_txns + .values() + .map(|txns| txns.len()) + .sum(); + let failed_orderless_txns: usize = failed_orderless_txns.values().map(|txns| txns.len()).sum(); + let committed_orderless_txns = total_orderless_txns - failed_orderless_txns; + + ( + seq_num_committed + committed_orderless_txns, + seq_num_failed + failed_orderless_txns, + ) } pub async fn submit_transactions( diff --git a/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs b/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs index 467f376faa4..3abe6c3ddd5 100644 --- a/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs +++ b/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs @@ -327,7 +327,7 @@ impl ReliableTransactionSubmitter for RestApiReliableTransactionSubmitter { txns: &[SignedTransaction], counters: &CounterState, ) -> Result<()> { - let run_seed: u64 = thread_rng().gen(); + let run_seed: u64 = thread_rng().r#gen(); join_all( txns.iter() diff --git a/crates/transaction-generator-lib/Cargo.toml b/crates/transaction-generator-lib/Cargo.toml index 23f0d40b362..7efacd91b4f 100644 --- a/crates/transaction-generator-lib/Cargo.toml +++ b/crates/transaction-generator-lib/Cargo.toml @@ -22,6 +22,7 @@ async-trait = { workspace = true } clap = { workspace = true } log = { workspace = true } move-binary-format = { workspace = true } +move-core-types = { workspace = true } move-package = { workspace = true } once_cell = { workspace = true } rand = { workspace = true } diff --git a/crates/transaction-generator-lib/src/call_custom_modules.rs b/crates/transaction-generator-lib/src/call_custom_modules.rs index d16e7cb85f7..105c42c4a27 100644 --- a/crates/transaction-generator-lib/src/call_custom_modules.rs +++ b/crates/transaction-generator-lib/src/call_custom_modules.rs @@ -14,7 +14,10 @@ use aptos_sdk::{ use async_trait::async_trait; use log::{error, info}; use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng}; -use std::{borrow::Borrow, sync::Arc}; +use std::{ + borrow::Borrow, + sync::{Arc, Mutex}, +}; // Fn + Send + Sync, as it will be called from multiple threads simultaneously // if you need any coordination, use Arc> fields @@ -134,19 +137,21 @@ pub struct CustomModulesDelegationGeneratorCreator { txn_factory: TransactionFactory, packages: Arc>, txn_generator: Arc, + rng: Option>, } impl CustomModulesDelegationGeneratorCreator { - #[allow(dead_code)] pub fn new_raw( txn_factory: TransactionFactory, packages: Arc>, txn_generator: Arc, + rng: Option, ) -> Self { Self { txn_factory, packages, txn_generator, + rng: rng.map(Mutex::new), } } @@ -182,6 +187,7 @@ impl CustomModulesDelegationGeneratorCreator { txn_factory, packages: Arc::new(packages), txn_generator: worker, + rng: None, } } @@ -192,7 +198,25 @@ impl CustomModulesDelegationGeneratorCreator { packages: &[(Package, LocalAccount)], workload: &mut dyn UserModuleTransactionGenerator, ) -> Arc { - let mut rng = StdRng::from_entropy(); + Self::create_worker_with_rng( + init_txn_factory, + root_account, + txn_executor, + packages, + workload, + StdRng::from_entropy(), + ) + .await + } + + pub async fn create_worker_with_rng( + init_txn_factory: TransactionFactory, + root_account: &dyn RootAccountHandle, + txn_executor: &dyn ReliableTransactionSubmitter, + packages: &[(Package, LocalAccount)], + workload: &mut dyn UserModuleTransactionGenerator, + mut rng: StdRng, + ) -> Arc { let mut requests_initialize = Vec::with_capacity(packages.len()); for (package, publisher) in packages.iter() { @@ -233,13 +257,17 @@ impl CustomModulesDelegationGeneratorCreator { ) -> Vec<(Package, LocalAccount)> { let mut rng = StdRng::from_entropy(); let mut requests_create = Vec::with_capacity(num_modules); - let mut requests_publish = Vec::with_capacity(num_modules); - let mut package_handler = PackageHandler::new(pre_built, package_name); - let mut packages = Vec::new(); + let mut accounts = Vec::new(); - let publisher_balance = publisher_balance.unwrap_or( - 4 * init_txn_factory.get_gas_unit_price() * init_txn_factory.get_max_gas_amount(), + let min_balance = + 2 * init_txn_factory.get_gas_unit_price() * init_txn_factory.get_max_gas_amount(); + let publisher_balance = publisher_balance.unwrap_or(2 * min_balance); + assert!( + publisher_balance >= min_balance, + "Balance requested for publisher must be at least {} to cover for MAX_GAS", + min_balance ); + let total_funds = (num_modules as u64) * publisher_balance; root_account .approve_funds(total_funds, "funding publishers") @@ -255,15 +283,9 @@ impl CustomModulesDelegationGeneratorCreator { publisher_balance, )); - let package = package_handler.pick_package(&mut rng, publisher.address()); - for payload in package.publish_transaction_payload(&init_txn_factory.get_chain_id()) { - requests_publish.push( - publisher.sign_with_transaction_builder(init_txn_factory.payload(payload)), - ); - } - - packages.push((package, publisher)); + accounts.push(publisher); } + info!("Creating {} publisher accounts", requests_create.len()); // all publishers are created from root account, split it up. for req_chunk in requests_create.chunks(100) { @@ -279,6 +301,41 @@ impl CustomModulesDelegationGeneratorCreator { .unwrap(); } + let packages = Self::publish_package_to_accounts( + init_txn_factory, + txn_executor, + pre_built, + package_name, + &accounts, + ) + .await; + + packages.into_iter().zip(accounts.into_iter()).collect() + } + + pub async fn publish_package_to_accounts( + init_txn_factory: TransactionFactory, + txn_executor: &dyn ReliableTransactionSubmitter, + pre_built: &'static dyn PreBuiltPackages, + package_name: &str, + accounts: &[LocalAccount], + ) -> Vec { + let mut rng = StdRng::from_entropy(); + let mut requests_publish = Vec::with_capacity(accounts.len()); + let mut package_handler = PackageHandler::new(pre_built, package_name); + let mut packages = Vec::new(); + + for publisher in accounts { + let package = package_handler.pick_package(&mut rng, publisher.address()); + for payload in package.publish_transaction_payload(&init_txn_factory.get_chain_id()) { + requests_publish.push( + publisher.sign_with_transaction_builder(init_txn_factory.payload(payload)), + ); + } + + packages.push(package); + } + info!( "Publishing {} copies of package {}", requests_publish.len(), @@ -298,8 +355,14 @@ impl CustomModulesDelegationGeneratorCreator { impl TransactionGeneratorCreator for CustomModulesDelegationGeneratorCreator { fn create_transaction_generator(&self) -> Box { + let rng = self.rng.as_ref().map_or_else(StdRng::from_entropy, |rng| { + let mut lock = rng.lock().unwrap(); + let rng_ref: &mut StdRng = &mut lock; + StdRng::from_rng(rng_ref).unwrap() + }); + Box::new(CustomModulesDelegationGenerator::new( - StdRng::from_entropy(), + rng, self.txn_factory.clone(), self.packages.clone(), self.txn_generator.clone(), diff --git a/crates/transaction-generator-lib/src/lib.rs b/crates/transaction-generator-lib/src/lib.rs index c37b9363ae2..971b07ab480 100644 --- a/crates/transaction-generator-lib/src/lib.rs +++ b/crates/transaction-generator-lib/src/lib.rs @@ -54,7 +54,10 @@ use crate::{ entry_points::EntryPointTransactionGenerator, p2p_transaction_generator::SamplingMode, workflow_delegator::WorkflowTxnGeneratorCreator, }; -pub use publishing::{entry_point_trait, prebuild_packages::create_prebuilt_packages_rs_file}; +pub use publishing::{ + entry_point_trait, + prebuild_packages::{create_prebuilt_packages_bundle, PrebuiltPackageConfig}, +}; pub const SEND_AMOUNT: u64 = 1; @@ -65,6 +68,8 @@ pub enum TransactionType { sender_use_account_pool: bool, non_conflicting: bool, use_fa_transfer: bool, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, }, AccountGeneration { add_created_accounts_to_pool: bool, @@ -92,7 +97,6 @@ pub enum TransactionType { Workflow { workflow_kind: Box, num_modules: usize, - use_account_pool: bool, progress_type: WorkflowProgress, }, } @@ -125,6 +129,8 @@ impl Default for TransactionType { sender_use_account_pool: false, non_conflicting: false, use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, } } } @@ -297,6 +303,8 @@ pub async fn create_txn_generator_creator( sender_use_account_pool, non_conflicting, use_fa_transfer, + use_txn_payload_v2_format, + use_orderless_transactions, } => wrap_accounts_pool( Box::new(P2PTransactionGeneratorCreator::new( txn_factory.clone(), @@ -309,6 +317,8 @@ pub async fn create_txn_generator_creator( } else { SamplingMode::Basic }, + use_txn_payload_v2_format, + use_orderless_transactions, )), sender_use_account_pool, &accounts_pool, @@ -394,7 +404,6 @@ pub async fn create_txn_generator_creator( }, TransactionType::Workflow { num_modules, - use_account_pool, workflow_kind, progress_type, } => Box::new( @@ -405,7 +414,6 @@ pub async fn create_txn_generator_creator( &root_account, txn_executor, num_modules, - use_account_pool.then(|| accounts_pool.clone()), cur_phase.clone(), progress_type, ) diff --git a/crates/transaction-generator-lib/src/p2p_transaction_generator.rs b/crates/transaction-generator-lib/src/p2p_transaction_generator.rs index 81c5ae7dc94..53b39764492 100644 --- a/crates/transaction-generator-lib/src/p2p_transaction_generator.rs +++ b/crates/transaction-generator-lib/src/p2p_transaction_generator.rs @@ -150,6 +150,8 @@ pub struct P2PTransactionGenerator { sampler: Box>, invalid_transaction_ratio: usize, use_fa_transfer: bool, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, } impl P2PTransactionGenerator { @@ -161,6 +163,8 @@ impl P2PTransactionGenerator { invalid_transaction_ratio: usize, use_fa_transfer: bool, sampler: Box>, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> Self { Self { rng, @@ -170,6 +174,8 @@ impl P2PTransactionGenerator { sampler, invalid_transaction_ratio, use_fa_transfer, + use_txn_payload_v2_format, + use_orderless_transactions, } } @@ -179,14 +185,29 @@ impl P2PTransactionGenerator { to: &AccountAddress, num_coins: u64, txn_factory: &TransactionFactory, + rng: &mut impl Rng, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> SignedTransaction { from.sign_with_transaction_builder( if self.use_fa_transfer { - txn_factory.payload(aptos_stdlib::aptos_account_fungible_transfer_only( - *to, num_coins, - )) + txn_factory + .payload(aptos_stdlib::aptos_account_fungible_transfer_only( + *to, num_coins, + )) + .upgrade_payload_with_rng( + rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ) } else { - txn_factory.payload(aptos_stdlib::aptos_coin_transfer(*to, num_coins)) + txn_factory + .payload(aptos_stdlib::aptos_coin_transfer(*to, num_coins)) + .upgrade_payload_with_rng( + rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ) }, ) } @@ -203,26 +224,48 @@ impl P2PTransactionGenerator { match Standard.sample(rng) { InvalidTransactionType::ChainId => { let txn_factory = &self.txn_factory.clone().with_chain_id(ChainId::new(255)); - self.gen_single_txn(sender, receiver, self.send_amount, txn_factory) + self.gen_single_txn( + sender, + receiver, + self.send_amount, + txn_factory, + rng, + false, + false, + ) }, InvalidTransactionType::Sender => self.gen_single_txn( &invalid_account, receiver, self.send_amount, &self.txn_factory, + rng, + false, + false, ), InvalidTransactionType::Receiver => self.gen_single_txn( sender, &invalid_address, self.send_amount, &self.txn_factory, + rng, + false, + false, ), InvalidTransactionType::Duplication => { // if this is the first tx, default to generate invalid tx with wrong chain id // otherwise, make a duplication of an exist valid tx if reqs.is_empty() { let txn_factory = &self.txn_factory.clone().with_chain_id(ChainId::new(255)); - self.gen_single_txn(sender, receiver, self.send_amount, txn_factory) + self.gen_single_txn( + sender, + receiver, + self.send_amount, + txn_factory, + rng, + false, + false, + ) } else { let random_index = rng.gen_range(0, reqs.len()); reqs[random_index].clone() @@ -282,18 +325,22 @@ impl TransactionGenerator for P2PTransactionGenerator { receivers.len(), num_to_create ); + let mut rng = self.rng.clone(); for i in 0..num_to_create { let receiver = receivers.get(i).expect("all_addresses can't be empty"); let request = if num_valid_tx > 0 { num_valid_tx -= 1; - self.gen_single_txn(account, receiver, self.send_amount, &self.txn_factory) - } else { - self.generate_invalid_transaction( - &mut self.rng.clone(), + self.gen_single_txn( account, receiver, - &requests, + self.send_amount, + &self.txn_factory, + &mut rng, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, ) + } else { + self.generate_invalid_transaction(&mut rng, account, receiver, &requests) }; requests.push(request); } @@ -308,6 +355,8 @@ pub struct P2PTransactionGeneratorCreator { invalid_transaction_ratio: usize, use_fa_transfer: bool, sampling_mode: SamplingMode, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, } impl P2PTransactionGeneratorCreator { @@ -318,6 +367,8 @@ impl P2PTransactionGeneratorCreator { invalid_transaction_ratio: usize, use_fa_transfer: bool, sampling_mode: SamplingMode, + use_txn_payload_v2_format: bool, + use_orderless_transactions: bool, ) -> Self { let mut rng = StdRng::from_entropy(); all_addresses.shuffle(&mut rng); @@ -329,6 +380,8 @@ impl P2PTransactionGeneratorCreator { invalid_transaction_ratio, use_fa_transfer, sampling_mode, + use_txn_payload_v2_format, + use_orderless_transactions, } } } @@ -350,6 +403,8 @@ impl TransactionGeneratorCreator for P2PTransactionGeneratorCreator { self.invalid_transaction_ratio, self.use_fa_transfer, sampler, + self.use_txn_payload_v2_format, + self.use_orderless_transactions, )) } } diff --git a/crates/transaction-generator-lib/src/publishing/entry_point_trait.rs b/crates/transaction-generator-lib/src/publishing/entry_point_trait.rs index 6ec636e2540..dbf9dc09267 100644 --- a/crates/transaction-generator-lib/src/publishing/entry_point_trait.rs +++ b/crates/transaction-generator-lib/src/publishing/entry_point_trait.rs @@ -2,18 +2,64 @@ // SPDX-License-Identifier: Apache-2.0 use super::publish_util::Package; +use crate::publishing::prebuild_packages::PrebuiltPackagesBundle; +use aptos_framework::natives::code::PackageMetadata; use aptos_sdk::{ move_types::{ account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId, }, types::transaction::{EntryFunction, TransactionPayload}, }; +use move_binary_format::{ + deserializer::DeserializerConfig, + file_format::CompiledScript, + file_format_common::{IDENTIFIER_SIZE_MAX, VERSION_DEFAULT, VERSION_MAX}, + CompiledModule, +}; use rand::rngs::StdRng; pub trait PreBuiltPackages: std::fmt::Debug + Sync + Send { - fn package_metadata(&self, package_name: &str) -> &[u8]; - fn package_modules(&self, package_name: &str) -> &[Vec]; - fn package_script(&self, package_name: &str) -> Option<&Vec>; + fn package_bundle(&self) -> &PrebuiltPackagesBundle; + + fn package_metadata(&self, package_name: &str) -> PackageMetadata { + self.package_bundle() + .get_package(package_name) + .metadata + .clone() + } + + fn package_modules(&self, package_name: &str) -> Vec<(String, CompiledModule, u32)> { + let mut results = vec![]; + let default_config = DeserializerConfig::new(VERSION_DEFAULT, IDENTIFIER_SIZE_MAX); + + let modules = &self.package_bundle().get_package(package_name).modules; + for (module_name, bytes) in modules { + let (module, binary_format_version) = if let Ok(module) = + CompiledModule::deserialize_with_config(bytes, &default_config) + { + (module, VERSION_DEFAULT) + } else { + let module = + CompiledModule::deserialize(bytes).expect("Module must always deserialize"); + (module, VERSION_MAX) + }; + results.push((module_name.to_owned(), module, binary_format_version)); + } + + results + } + + fn package_script(&self, package_name: &str) -> Option { + let scripts = &self.package_bundle().get_package(package_name).scripts; + assert!( + scripts.len() <= 1, + "Only single script per package is supported" + ); + + scripts + .last() + .map(|bytes| CompiledScript::deserialize(bytes).expect("Script must deserialize")) + } } pub enum MultiSigConfig { diff --git a/crates/transaction-generator-lib/src/publishing/prebuild_packages.rs b/crates/transaction-generator-lib/src/publishing/prebuild_packages.rs index 854908c7bfa..776fcad1e16 100644 --- a/crates/transaction-generator-lib/src/publishing/prebuild_packages.rs +++ b/crates/transaction-generator-lib/src/publishing/prebuild_packages.rs @@ -1,12 +1,15 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_framework::{BuildOptions, BuiltPackage}; +use anyhow::{anyhow, bail}; +use aptos_framework::{natives::code::PackageMetadata, BuildOptions, BuiltPackage}; use aptos_sdk::bcs; -use move_binary_format::CompiledModule; use move_package::source_package::std_lib::StdVersion; +use serde::{Deserialize, Serialize}; use std::{ - fmt::Write, + collections::BTreeMap, + fs, + io::Write, path::{Path, PathBuf}, }; @@ -23,278 +26,146 @@ fn get_local_framework_path() -> String { .to_string() } -pub fn create_prebuilt_packages_rs_file( - base_dir: impl AsRef, - packages_to_build: Vec<(&str, &str, bool)>, - output_file: impl AsRef, - in_aptos_core: bool, -) -> anyhow::Result<()> { - let mut string_buffer = "".to_string(); - // - // File header - // - writeln!( - string_buffer, - r#"// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0"# - ) - .expect("Writing header comment failed"); - - // - // Module comment - // - writeln!( - string_buffer, - r#" -// This file was generated. Do not modify! -// -// To update this code, run `cargo run -p module-publish` in aptos core. -// That test compiles the set of modules defined in -// `testsuite/simple/src/simple/sources/` -// and it writes the binaries here. -// The module name (prefixed with `MODULE_`) is a `Lazy` instance that returns the -// byte array of the module binary. -// This crate should also provide a Rust file that allows proper manipulation of each -// module defined below."# - ) - .expect("Writing header comment failed"); - - // - // use ... directives - // - writeln!( - string_buffer, - " -use aptos_transaction_generator_lib::entry_point_trait::PreBuiltPackages; -use once_cell::sync::Lazy; -use std::collections::HashMap;", - ) - .expect("Use directive failed"); - writeln!(string_buffer).expect("Empty line failed"); +/// Prebuilt package that stores metadata, modules, and scripts. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PrebuiltPackage { + pub metadata: PackageMetadata, + pub modules: BTreeMap>, + pub scripts: Vec>, +} - let mut packages = Vec::new(); - for (package_name, additional_package, use_latest_language) in packages_to_build { - let mut build_options = if use_latest_language { - BuildOptions::move_2().set_latest_language() - } else { - BuildOptions::move_2() - }; - build_options.dev = true; - if in_aptos_core { - build_options.override_std = Some(StdVersion::Local(get_local_framework_path())); - } +/// Bundle of multiple prebuilt packages. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PrebuiltPackagesBundle { + pub packages: BTreeMap, +} - packages.push(write_package( - &mut string_buffer, - base_dir.as_ref().join(additional_package), - package_name, - build_options, - )); +impl PrebuiltPackagesBundle { + /// Returns the package corresponding to the given name. Panics if such a package does not + /// exist. + pub fn get_package(&self, package_name: &str) -> &PrebuiltPackage { + self.packages + .get(package_name) + .unwrap_or_else(|| panic!("Package {package_name} does not exist")) } +} - write_accessors(&mut string_buffer, packages); - - writeln!( - string_buffer, - " -#[derive(Debug)] -pub struct PreBuiltPackagesImpl; - -impl PreBuiltPackages for PreBuiltPackagesImpl {{ - fn package_metadata(&self, package_name: &str) -> &[u8] {{ - PACKAGE_TO_METADATA.get(package_name).expect(package_name) - }} - - fn package_modules(&self, package_name: &str) -> &[Vec] {{ - PACKAGE_TO_MODULES.get(package_name).expect(package_name) - }} +/// Configuration for building a prebuilt package. +#[derive(Debug, Clone)] +pub struct PrebuiltPackageConfig { + /// If true, packages are compiled with latest (possibly unstable) version. + pub latest_language: bool, + /// If true, will use the local Aptos framework. + pub use_local_std: bool, + /// Experiments for compiler optimization. + pub experiments: Vec, +} - fn package_script(&self, package_name: &str) -> Option<&Vec> {{ - PACKAGE_TO_SCRIPT.get(package_name) - }} -}}", - ) - .expect("PreBuiltPackages failed"); +impl PrebuiltPackageConfig { + pub fn new(latest_language: bool, use_local_std: bool, experiments: Vec) -> Self { + Self { + latest_language, + use_local_std, + experiments, + } + } - let mut generic_mod = std::fs::File::create(output_file).unwrap(); - { - use std::io::Write; - write!(generic_mod, "{}", string_buffer)?; + /// Returns built options corresponding to the prebuilt config. + pub fn build_options(&self) -> BuildOptions { + let mut build_options = BuildOptions::move_2(); + build_options.dev = true; + if self.latest_language { + build_options = build_options.set_latest_language(); + } + if self.use_local_std { + build_options.override_std = Some(StdVersion::Local(get_local_framework_path())); + } + for exp in &self.experiments { + build_options = build_options.with_experiment(exp); + } + build_options } - Ok(()) } -// Write out given package -fn write_package( - file: &mut String, - package_path: PathBuf, - package_name: &str, - build_options: BuildOptions, -) -> (String, bool) { - println!("Building package {}", package_name); - // build package - let package = - BuiltPackage::build(package_path, build_options).expect("building package must succeed"); - let modules = package.extract_code(); - let mut scripts = package.extract_script_code(); - let package_metadata = package.extract_metadata().expect("Metadata must exist"); - let metadata = bcs::to_bytes(&package_metadata).expect("Metadata must serialize"); - - // write out package metadata - write_lazy( - file, - format!("PACKAGE_{}_METADATA", package_name.to_uppercase()).as_str(), - &metadata, - ); - - let mut module_names = Vec::new(); +/// Creates a [PrebuiltPackagesBundle] from the provided list of packages, serializes it and saves +/// as a file in `base_dir/prebuilt.mpb` (`base_dir` should be a Cargo crate). Also generates a +/// Rust file in that crate that allows to access prebuilt information. The output file must live +/// in the same crate. +pub fn create_prebuilt_packages_bundle( + base_dir: impl AsRef, + packages_to_build: Vec<(PathBuf, PrebuiltPackageConfig)>, + output_rust_file: impl AsRef, +) -> anyhow::Result<()> { + // Step 1: save serialized pre-built data. + let mut packages = BTreeMap::new(); + + for (package_path, config) in packages_to_build { + let package = BuiltPackage::build(package_path, config.build_options()) + .map_err(|err| anyhow!("Failed to build a package: {err:?}"))?; + + let metadata = package.extract_metadata()?; + let modules = package.module_code_iter().collect(); + let scripts = package.extract_script_code(); + if scripts.len() > 1 { + bail!("For benchmarks, define 1 script per package to make name resolution easier") + } - // write out all modules - for module in &modules { - // this is an unfortunate way to find the module name but it is not - // clear how to do it otherwise - let compiled_module = CompiledModule::deserialize(module).expect("Module must deserialize"); - let module_name = compiled_module.self_id().name().to_owned().into_string(); - // start Lazy declaration - let name: String = format!( - "MODULE_{}_{}", - package_name.to_uppercase(), - module_name.to_uppercase() - ); - writeln!(file).expect("Empty line failed"); - write_lazy(file, name.as_str(), module); - module_names.push(name); + packages.insert(package.name().to_owned(), PrebuiltPackage { + metadata, + modules, + scripts, + }); } - assert!( - scripts.len() <= 1, - "Only single script can be added per package" - ); - - let has_script = if let Some(script) = scripts.pop() { - let name: String = format!("SCRIPT_{}", package_name.to_uppercase()); - writeln!(file).expect("Empty line failed"); - write_lazy(file, name.as_str(), &script); - true - } else { - false - }; - - writeln!(file).expect("Empty line failed"); - writeln!(file, "#[rustfmt::skip]").expect("rustfmt skip failed"); - writeln!( - file, - "pub static MODULES_{}: Lazy>> = Lazy::new(|| {{ vec![", - package_name.to_uppercase(), - ) - .expect("Lazy MODULES declaration failed"); - - for module_name in module_names { - writeln!(file, "\t{}.to_vec(),", module_name).expect("Module name declaration failed"); - } + let bundle = PrebuiltPackagesBundle { packages }; + let bundle_bytes = bcs::to_bytes(&bundle) + .map_err(|err| anyhow!("Failed to serialize prebuilt packages: {err:?}"))?; + fs::write(base_dir.as_ref().join("prebuilt.mpb"), bundle_bytes) + .map_err(|err| anyhow!("Failed to save serialized packages: {err:?}"))?; - writeln!(file, "]}});").expect("Lazy declaration closing } failed"); - (package_name.to_string(), has_script) -} + // Step 2: generate implementation to access prebuilt packages. + let code = r#" +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 -fn write_accessors(file: &mut String, packages: Vec<(String, bool)>) { - writeln!(file).expect("Empty line failed"); - writeln!(file, "#[rustfmt::skip]").expect("rustfmt skip failed"); - writeln!( - file, - "pub static PACKAGE_TO_METADATA: Lazy>> = Lazy::new(|| {{ HashMap::from([", - ) - .expect("Lazy PACKAGE_TO_METADATA declaration failed"); +// This file was generated. Do not modify! +// +// To update this code, run `testsuite/benchmark-workloads/generate.py`. - for (package, _) in &packages { - writeln!( - file, - "\t(\"{}\".to_string(), PACKAGE_{}_METADATA.to_vec()),", - package, - package.to_uppercase() - ) - .expect("PACKAGE_TO_METADATA declaration failed"); - } - writeln!(file, "])}});").expect("Lazy declaration closing } failed"); +use aptos_sdk::bcs; +use aptos_transaction_generator_lib::{ + entry_point_trait::PreBuiltPackages, publishing::prebuild_packages::PrebuiltPackagesBundle, +}; +use once_cell::sync::Lazy; - writeln!(file).expect("Empty line failed"); - writeln!(file, "#[rustfmt::skip]").expect("rustfmt skip failed"); - writeln!( - file, - "pub static PACKAGE_TO_MODULES: Lazy>>> = Lazy::new(|| {{ HashMap::from([", - ) - .expect("Lazy PACKAGE_TO_MODULES declaration failed"); +/// Bytes of all pre-build packages. +#[rustfmt::skip] +const PREBUILT_BUNDLE_BYTES: &[u8] = + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/prebuilt.mpb")); - for (package, _) in &packages { - writeln!( - file, - "\t(\"{}\".to_string(), MODULES_{}.to_vec()),", - package, - package.to_uppercase() - ) - .expect("PACKAGE_TO_MODULES declaration failed"); - } - writeln!(file, "])}});").expect("Lazy declaration closing } failed"); +/// Pre-built deserialized data: for each package, stores package metadata, compiled modules and +/// scripts. +#[rustfmt::skip] +static PREBUILT_BUNDLE: Lazy = Lazy::new(|| { + bcs::from_bytes::(PREBUILT_BUNDLE_BYTES) + .expect("prebuilt.mpb can be deserialized") +}); - writeln!(file).expect("Empty line failed"); - writeln!(file, "#[rustfmt::skip]").expect("rustfmt skip failed"); - writeln!( - file, - "pub static PACKAGE_TO_SCRIPT: Lazy>> = Lazy::new(|| {{ HashMap::from([", - ) - .expect("Lazy PACKAGE_TO_SCRIPT declaration failed"); +#[rustfmt::skip] +#[derive(Debug)] +pub struct PreBuiltPackagesImpl; - for (package, has_script) in &packages { - if *has_script { - writeln!( - file, - "\t(\"{}\".to_string(), SCRIPT_{}.to_vec()),", - package, - package.to_uppercase() - ) - .expect("PACKAGE_TO_SCRIPT declaration failed"); - } +#[rustfmt::skip] +impl PreBuiltPackages for PreBuiltPackagesImpl { + fn package_bundle(&self) -> &PrebuiltPackagesBundle { + &PREBUILT_BUNDLE } - writeln!(file, "])}});").expect("Lazy declaration closing } failed"); } +"#; -// Write out a `Lazy` declaration -fn write_lazy(file: &mut String, data_name: &str, data: &[u8]) { - writeln!(file, "#[rustfmt::skip]").expect("rustfmt skip failed"); - writeln!( - file, - "pub static {}: Lazy> = Lazy::new(|| {{", - data_name, - ) - .expect("Lazy declaration failed"); - write_vector(file, data); - writeln!(file, "}});").expect("Lazy declaration closing } failed"); -} - -// count of elements on a single line -const DATA_BREAK_UP: usize = 18; + let mut file = fs::File::create(output_rust_file) + .map_err(|err| anyhow!("Failed to create output file: {err:?}"))?; + write!(file, "{}", code.trim_start())?; -// Write out a vector of bytes -fn write_vector(file: &mut String, data: &[u8]) { - writeln!(file, "\tvec![").expect("Vector header failed"); - write!(file, "\t\t").expect("Tab write failed"); - let mut newline = false; - for (idx, datum) in data.iter().enumerate() { - if (idx + 1) % DATA_BREAK_UP == 0 { - writeln!(file, "{},", datum).expect("Vector write failed"); - write!(file, "\t\t").expect("Tab write failed"); - newline = true; - } else { - if idx == data.len() - 1 { - write!(file, "{},", datum).expect("Vector write failed"); - } else { - write!(file, "{}, ", datum).expect("Vector write failed"); - } - newline = false; - } - } - if !newline { - writeln!(file).expect("Empty writeln failed"); - } - writeln!(file, "\t]").expect("Vector footer failed"); + Ok(()) } diff --git a/crates/transaction-generator-lib/src/publishing/publish_util.rs b/crates/transaction-generator-lib/src/publishing/publish_util.rs index bcc57556425..5c4e9967306 100644 --- a/crates/transaction-generator-lib/src/publishing/publish_util.rs +++ b/crates/transaction-generator-lib/src/publishing/publish_util.rs @@ -25,11 +25,10 @@ use aptos_sdk::{ }; use move_binary_format::{ access::ModuleAccess, - deserializer::DeserializerConfig, file_format::{CompiledScript, FunctionHandleIndex, IdentifierIndex, SignatureToken}, - file_format_common::{IDENTIFIER_SIZE_MAX, VERSION_DEFAULT, VERSION_MAX}, CompiledModule, }; +use move_core_types::language_storage::pseudo_script_module_id; use rand::{rngs::StdRng, Rng}; // Information used to track a publisher and what allows to identify and @@ -100,13 +99,7 @@ impl PackageHandler { (tracker.publishers.len() - 1, false) }, }; - let mut package = tracker.package.update( - tracker.publishers[idx].publisher, - 0, - // TODO cleanup. - // unnecessary to have indices for module published under different accout, - // they can all be named the same - ); + let mut package = tracker.package.update(tracker.publishers[idx].publisher); if self.is_simple { if version { update_simple_move_version(package.get_mut_module("simple")); @@ -134,13 +127,9 @@ pub enum Package { impl Package { pub fn by_name(pre_built: &'static dyn PreBuiltPackages, name: &str) -> Self { - let (modules, metadata) = Self::load_package( - pre_built.package_metadata(name), - pre_built.package_modules(name), - ); - let script = pre_built - .package_script(name) - .map(|code| CompiledScript::deserialize(code).expect("Script must deserialize")); + let modules = pre_built.package_modules(name); + let metadata = pre_built.package_metadata(name); + let script = pre_built.package_script(name); Self::Simple { modules, metadata, @@ -156,13 +145,13 @@ impl Package { let mut script = script_opt .clone() .expect("Script not defined for wanted package"); - assert_ne!(publisher, AccountAddress::MAX_ADDRESS); + assert_ne!(publisher, *pseudo_script_module_id().address()); - // Make sure dependencies link to published modules. Compiler V2 adds 0xf..ff so we need to + // Make sure dependencies link to published modules. Compiler V2 adds `pseudo_script_module_id()` so we need to // skip it. assert_eq!(script.address_identifiers.len(), 2); for address in &mut script.address_identifiers { - if address != &AccountAddress::MAX_ADDRESS { + if address != pseudo_script_module_id().address() { *address = publisher; } } @@ -174,45 +163,15 @@ impl Package { } } - fn load_package( - package_bytes: &[u8], - modules_bytes: &[Vec], - ) -> (Vec<(String, CompiledModule, u32)>, PackageMetadata) { - let metadata = bcs::from_bytes::(package_bytes) - .expect("PackageMetadata for GenericModule must deserialize"); - let mut modules = Vec::new(); - - let default_config = DeserializerConfig::new(VERSION_DEFAULT, IDENTIFIER_SIZE_MAX); - - for module_content in modules_bytes { - let (module, binary_format_version) = if let Ok(module) = - CompiledModule::deserialize_with_config(module_content, &default_config) - { - (module, VERSION_DEFAULT) - } else { - let module = CompiledModule::deserialize(module_content) - .expect("Simple.move must deserialize"); - (module, VERSION_MAX) - }; - - modules.push(( - module.self_id().name().to_string(), - module, - binary_format_version, - )); - } - (modules, metadata) - } - // Given an "original" package, updates all modules with the given publisher. - pub fn update(&self, publisher: AccountAddress, suffix: u64) -> Self { + pub fn update(&self, publisher: AccountAddress) -> Self { match self { Self::Simple { modules, metadata, script, } => { - let (new_modules, metadata) = update(modules, metadata, publisher, suffix); + let (new_modules, metadata) = update(modules, metadata, publisher); Self::Simple { modules: new_modules, metadata, @@ -297,21 +256,19 @@ fn update( modules: &[(String, CompiledModule, u32)], metadata: &PackageMetadata, publisher: AccountAddress, - suffix: u64, ) -> (Vec<(String, CompiledModule, u32)>, PackageMetadata) { let mut new_modules = Vec::new(); + let original_address = get_module_address(&modules[0].1); for (original_name, module, binary_format_version) in modules { + assert_eq!(original_address, get_module_address(module)); + let mut new_module = module.clone(); - let module_handle = new_module - .module_handles - .get(module.self_handle_idx().0 as usize) - .expect("ModuleId for self must exists"); - let original_address_idx = module_handle.address.0; - let original_address = new_module.address_identifiers[original_address_idx as usize]; - let _ = std::mem::replace( - &mut new_module.address_identifiers[original_address_idx as usize], - publisher, - ); + + for i in 0..new_module.address_identifiers.len() { + if new_module.address_identifiers[i] == original_address { + let _ = std::mem::replace(&mut new_module.address_identifiers[i], publisher); + } + } for constant in new_module.constant_pool.iter_mut() { if constant.type_ == SignatureToken::Address @@ -321,20 +278,6 @@ fn update( } } - if suffix > 0 { - for module_handle in &new_module.module_handles { - if module_handle.address.0 == original_address_idx { - let mut new_name = - new_module.identifiers[module_handle.name.0 as usize].to_string(); - new_name.push('_'); - new_name.push_str(suffix.to_string().as_str()); - let _ = std::mem::replace( - &mut new_module.identifiers[module_handle.name.0 as usize], - Identifier::new(new_name).expect("Identifier must be legal"), - ); - } - } - } if let Some(mut metadata) = get_metadata_from_compiled_code(&new_module) { metadata .struct_attributes @@ -373,17 +316,23 @@ fn update( new_modules.push((original_name.clone(), new_module, *binary_format_version)); } let mut metadata = metadata.clone(); - if suffix > 0 { - for module in &mut metadata.modules { - let mut new_name = module.name.clone(); - new_name.push('_'); - new_name.push_str(suffix.to_string().as_str()); - module.name = new_name; + for dep in &mut metadata.deps { + if dep.account == original_address { + dep.account = publisher; } } (new_modules, metadata) } +fn get_module_address(module: &CompiledModule) -> AccountAddress { + let module_handle = module + .module_handles + .get(module.self_handle_idx().0 as usize) + .expect("ModuleId for self must exists"); + let original_address_idx = module_handle.address.0; + module.address_identifiers[original_address_idx as usize] +} + // // Functions to load and update the original package // diff --git a/crates/transaction-generator-lib/src/transaction_mix_generator.rs b/crates/transaction-generator-lib/src/transaction_mix_generator.rs index eef89c664cb..58a7786850f 100644 --- a/crates/transaction-generator-lib/src/transaction_mix_generator.rs +++ b/crates/transaction-generator-lib/src/transaction_mix_generator.rs @@ -49,9 +49,9 @@ impl TransactionGenerator for PhasedTxnMixGenerator { }; let mut picked = self.rng.gen_range(0, self.total_weight_per_phase[phase]); - for (gen, weight) in &mut self.txn_mix_per_phase[phase] { + for (r#gen, weight) in &mut self.txn_mix_per_phase[phase] { if picked < *weight { - return gen.generate_transactions(account, num_to_create); + return r#gen.generate_transactions(account, num_to_create); } picked -= *weight; } diff --git a/crates/transaction-generator-lib/src/workflow_delegator.rs b/crates/transaction-generator-lib/src/workflow_delegator.rs index 1ed2a5f7088..077b9bf2f57 100644 --- a/crates/transaction-generator-lib/src/workflow_delegator.rs +++ b/crates/transaction-generator-lib/src/workflow_delegator.rs @@ -334,6 +334,7 @@ impl WorkflowTxnGeneratorCreator { txn_factory.clone(), packages.clone(), delegation_worker, + None, )), prev_pool.clone(), Some(next_pool.clone()), @@ -359,7 +360,6 @@ impl WorkflowTxnGeneratorCreator { root_account: &dyn RootAccountHandle, txn_executor: &dyn ReliableTransactionSubmitter, num_modules: usize, - _initial_account_pool: Option>>, cur_phase: Arc, progress_type: WorkflowProgress, ) -> Self { diff --git a/crates/transaction-workloads-lib/prebuilt.mpb b/crates/transaction-workloads-lib/prebuilt.mpb new file mode 100644 index 00000000000..8538d75ccb5 Binary files /dev/null and b/crates/transaction-workloads-lib/prebuilt.mpb differ diff --git a/crates/transaction-workloads-lib/src/args.rs b/crates/transaction-workloads-lib/src/args.rs index 12d3761fffb..32d8f4623e5 100644 --- a/crates/transaction-workloads-lib/src/args.rs +++ b/crates/transaction-workloads-lib/src/args.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - move_workloads::{LoopType, PreBuiltPackagesImpl}, + move_workloads::{FibonacciFunctionType, LoopType, PreBuiltPackagesImpl}, token_workflow::TokenWorkflowKind, - EntryPoints, OrderBookState, + EntryPoints, MonotonicCounterType, OrderBookState, }; use aptos_transaction_generator_lib::{TransactionType, WorkflowProgress}; use clap::{Parser, ValueEnum}; @@ -19,6 +19,7 @@ pub enum TransactionTypeArg { AptFaTransfer, CoinTransferWithInvalid, NonConflictingCoinTransfer, + OrderlessAptFaTransfer, AccountGeneration, AccountGenerationLargePool, Batch100Transfer, @@ -26,6 +27,7 @@ pub enum TransactionTypeArg { RepublishAndCall, // Simple EntryPoints NoOp, + NoOpOrderless, NoOpFeePayer, NoOp2Signers, NoOp5Signers, @@ -82,17 +84,33 @@ pub enum TransactionTypeArg { APTTransferWithMasterSigner, /// Basic market where sell and buy prices are in distinct ranges, /// and there are no matches. - OrderBookNoMatches, + OrderBookNoMatches1Market, + OrderBookNoMatches50Markets, + /// Basic market where sell and buy prices are in distinct ranges, + /// and there are no matches. /// Basic market, 25% of orders are in the "overlap" interval. /// Half of the orders are buys, half sells, and both have same size ranges. - OrderBookBalancedMatches25Pct, + OrderBookBalancedMatches25Pct1Market, + OrderBookBalancedMatches25Pct50Markets, /// Basic market, 80% of orders are in the "overlap" interval. /// Half of the orders are buys, half sells, and both have same size ranges. - OrderBookBalancedMatches80Pct, + OrderBookBalancedMatches80Pct1Market, + OrderBookBalancedMatches80Pct50Markets, /// Basic market, 80% of orders are in the "overlap" interval. /// Sells are 99 times smaller, but are 99 times more frequent than buys. /// That means we will match rarely, but single match will be creating ~100 positions - OrderBookBalancedSizeSkewed80Pct, + OrderBookBalancedSizeSkewed80Pct1Market, + OrderBookBalancedSizeSkewed80Pct50Markets, + // Monotonic counter throughput tests + MonotonicCounterSingle, + MonotonicCounterMultiple10, + MonotonicCounterMultiple100, + MonotonicCounterMultiple1000, + + // Fibonacci tests + FibonacciRecursive20, + FibonacciTailRecursive20, + FibonacciIterative20, } impl TransactionTypeArg { @@ -114,30 +132,46 @@ impl TransactionTypeArg { } }; - match self { + match &self { TransactionTypeArg::CoinTransfer => TransactionType::CoinTransfer { invalid_transaction_ratio: 0, sender_use_account_pool, non_conflicting: false, use_fa_transfer: false, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, TransactionTypeArg::AptFaTransfer => TransactionType::CoinTransfer { invalid_transaction_ratio: 0, sender_use_account_pool, non_conflicting: false, use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, TransactionTypeArg::NonConflictingCoinTransfer => TransactionType::CoinTransfer { invalid_transaction_ratio: 0, sender_use_account_pool, non_conflicting: true, use_fa_transfer: false, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, TransactionTypeArg::CoinTransferWithInvalid => TransactionType::CoinTransfer { invalid_transaction_ratio: 10, sender_use_account_pool, non_conflicting: false, use_fa_transfer: false, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, + }, + TransactionTypeArg::OrderlessAptFaTransfer => TransactionType::CoinTransfer { + invalid_transaction_ratio: 0, + sender_use_account_pool, + non_conflicting: false, + use_fa_transfer: true, + use_txn_payload_v2_format: true, + use_orderless_transactions: true, }, TransactionTypeArg::AccountGeneration => TransactionType::AccountGeneration { add_created_accounts_to_pool: true, @@ -197,6 +231,7 @@ impl TransactionTypeArg { use_account_pool: sender_use_account_pool, }, TransactionTypeArg::NoOp => call_custom_module(EntryPoints::Nop), + TransactionTypeArg::NoOpOrderless => call_custom_module(EntryPoints::NopOrderless), TransactionTypeArg::NoOpFeePayer => call_custom_module(EntryPoints::NopFeePayer), TransactionTypeArg::NoOp2Signers => call_custom_module(EntryPoints::Nop), TransactionTypeArg::NoOp5Signers => call_custom_module(EntryPoints::Nop), @@ -313,7 +348,6 @@ impl TransactionTypeArg { creation_balance: 200000, }), num_modules: 1, - use_account_pool: sender_use_account_pool, progress_type: workflow_progress_type, }, TransactionTypeArg::LiquidityPoolSwap => { @@ -372,40 +406,110 @@ impl TransactionTypeArg { TransactionTypeArg::APTTransferWithMasterSigner => { call_custom_module(EntryPoints::APTTransferWithMasterSigner) }, - TransactionTypeArg::OrderBookNoMatches => call_custom_module(EntryPoints::OrderBook { - state: OrderBookState::new(), - overlap_ratio: 0.0, - buy_frequency: 0.5, - max_sell_size: 1, - max_buy_size: 1, - }), - TransactionTypeArg::OrderBookBalancedMatches25Pct => { + TransactionTypeArg::OrderBookNoMatches1Market + | TransactionTypeArg::OrderBookNoMatches50Markets => { call_custom_module(EntryPoints::OrderBook { state: OrderBookState::new(), + num_markets: if let TransactionTypeArg::OrderBookNoMatches50Markets = self { + 50 + } else { + 1 + }, + overlap_ratio: 0.0, + buy_frequency: 0.5, + max_sell_size: 1, + max_buy_size: 1, + }) + }, + TransactionTypeArg::OrderBookBalancedMatches25Pct1Market + | TransactionTypeArg::OrderBookBalancedMatches25Pct50Markets => { + call_custom_module(EntryPoints::OrderBook { + state: OrderBookState::new(), + num_markets: if let TransactionTypeArg::OrderBookBalancedMatches25Pct50Markets = + self + { + 50 + } else { + 1 + }, overlap_ratio: 0.25, buy_frequency: 0.5, max_sell_size: 1, max_buy_size: 1, }) }, - TransactionTypeArg::OrderBookBalancedMatches80Pct => { + TransactionTypeArg::OrderBookBalancedMatches80Pct1Market + | TransactionTypeArg::OrderBookBalancedMatches80Pct50Markets => { call_custom_module(EntryPoints::OrderBook { state: OrderBookState::new(), + num_markets: if let TransactionTypeArg::OrderBookBalancedMatches80Pct50Markets = + self + { + 50 + } else { + 1 + }, overlap_ratio: 0.8, buy_frequency: 0.5, max_sell_size: 1, max_buy_size: 1, }) }, - TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct => { + TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct1Market + | TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct50Markets => { call_custom_module(EntryPoints::OrderBook { state: OrderBookState::new(), + num_markets: + if let TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct50Markets = self + { + 50 + } else { + 1 + }, overlap_ratio: 0.8, buy_frequency: 0.01, max_sell_size: 50, max_buy_size: 950, }) }, + TransactionTypeArg::MonotonicCounterSingle => { + call_custom_module(EntryPoints::MonotonicCounter { + counter_type: MonotonicCounterType::Single, + }) + }, + TransactionTypeArg::MonotonicCounterMultiple10 => { + call_custom_module(EntryPoints::MonotonicCounter { + counter_type: MonotonicCounterType::Multiple { count: 10 }, + }) + }, + TransactionTypeArg::MonotonicCounterMultiple100 => { + call_custom_module(EntryPoints::MonotonicCounter { + counter_type: MonotonicCounterType::Multiple { count: 100 }, + }) + }, + TransactionTypeArg::MonotonicCounterMultiple1000 => { + call_custom_module(EntryPoints::MonotonicCounter { + counter_type: MonotonicCounterType::Multiple { count: 1000 }, + }) + }, + TransactionTypeArg::FibonacciRecursive20 => { + call_custom_module(EntryPoints::Fibonacci { + n: 20, + function_type: FibonacciFunctionType::Recursive, + }) + }, + TransactionTypeArg::FibonacciTailRecursive20 => { + call_custom_module(EntryPoints::Fibonacci { + n: 20, + function_type: FibonacciFunctionType::TailRecursive, + }) + }, + TransactionTypeArg::FibonacciIterative20 => { + call_custom_module(EntryPoints::Fibonacci { + n: 20, + function_type: FibonacciFunctionType::Iterative, + }) + }, } } diff --git a/crates/transaction-workloads-lib/src/lib.rs b/crates/transaction-workloads-lib/src/lib.rs index 104080c5269..12b944d446d 100644 --- a/crates/transaction-workloads-lib/src/lib.rs +++ b/crates/transaction-workloads-lib/src/lib.rs @@ -5,7 +5,10 @@ pub mod args; mod move_workloads; -mod raw_module_data; +mod prebuilt_packages; mod token_workflow; -pub use move_workloads::{EntryPoints, LoopType, MapType, OrderBookState}; +pub use move_workloads::{ + EntryPoints, LoopType, MapType, MonotonicCounterType, MoveVmMicroBenchmark, OrderBookState, +}; +pub use token_workflow::TokenWorkflowKind; diff --git a/crates/transaction-workloads-lib/src/move_workloads.rs b/crates/transaction-workloads-lib/src/move_workloads.rs index 93003618d6f..16703b3fd5f 100644 --- a/crates/transaction-workloads-lib/src/move_workloads.rs +++ b/crates/transaction-workloads-lib/src/move_workloads.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 #![allow(unused)] -pub use super::raw_module_data::PreBuiltPackagesImpl; -use aptos_framework::natives::code::{MoveOption, PackageMetadata}; +pub use super::prebuilt_packages::PreBuiltPackagesImpl; +use aptos_framework::natives::code::PackageMetadata; use aptos_sdk::{ bcs, move_types::{ @@ -47,6 +47,20 @@ pub enum LoopType { BcsToBytes { len: u64 }, } +#[derive(Debug, Clone)] +pub enum FibonacciFunctionType { + Recursive, + TailRecursive, + Iterative, +} + +/// Monotonically increasing counter test variants +#[derive(Debug, Copy, Clone)] +pub enum MonotonicCounterType { + Single, // Call counter once per transaction + Multiple { count: u64 }, // Call counter multiple times per transaction +} + #[derive(Debug, Copy, Clone)] pub enum MapType { SimpleMap, @@ -70,6 +84,15 @@ impl OrderBookState { } } +#[derive(Debug, Clone)] +pub enum MoveVmMicroBenchmark { + /// Runs a function which creates many local variables (but do not do any expensive compute) + Locals, + /// Runs a function instantiation which creates many local variables (but do not do any + /// expensive compute) + LocalsGeneric, +} + // // List of entry points to expose // @@ -80,6 +103,8 @@ pub enum EntryPoints { Republish, /// Empty (NoOp) function Nop, + /// Empty (NoOp) function, with replay protection nonce + NopOrderless, /// Empty (NoOp) function, signed by publisher as fee-payer NopFeePayer, /// Empty (NoOp) function, signed by 2 accounts @@ -109,6 +134,11 @@ pub enum EntryPoints { loop_count: Option, loop_type: LoopType, }, + /// Compute the n-th fibonacci number using the given function type. + Fibonacci { + n: u64, + function_type: FibonacciFunctionType, + }, // next 2 functions, second arg must be existing account address with data // Sets `Resource` to the max from two addresses Maximize, @@ -255,6 +285,8 @@ pub enum EntryPoints { OrderBook { state: Arc, + /// Number of markets to use. + num_markets: u32, /// Buy and sell price is picked randomly from their respective ranges. /// `overlap_ratio` defines what portion of the range they overlap on. overlap_ratio: f64, @@ -265,6 +297,14 @@ pub enum EntryPoints { /// Buy size is picked randomly from [1, max_buy_size] range max_buy_size: u64, }, + + /// Test monotonically increasing counter native function throughput + MonotonicCounter { + counter_type: MonotonicCounterType, + }, + + /// Different microbenchmarks to stress-test Move VM. + MoveVmMicroBenchmark(MoveVmMicroBenchmark), } impl EntryPointTrait for EntryPoints { @@ -276,6 +316,7 @@ impl EntryPointTrait for EntryPoints { match self { EntryPoints::Republish | EntryPoints::Nop + | EntryPoints::NopOrderless | EntryPoints::NopFeePayer | EntryPoints::Nop2Signers | EntryPoints::Nop5Signers @@ -285,6 +326,7 @@ impl EntryPointTrait for EntryPoints { | EntryPoints::Double | EntryPoints::Half | EntryPoints::Loop { .. } + | EntryPoints::Fibonacci { .. } | EntryPoints::GetFromConst { .. } | EntryPoints::SetId | EntryPoints::SetName @@ -319,7 +361,8 @@ impl EntryPointTrait for EntryPoints { | EntryPoints::CoinInitAndMint | EntryPoints::FungibleAssetMint | EntryPoints::APTTransferWithPermissionedSigner - | EntryPoints::APTTransferWithMasterSigner => "framework_usecases", + | EntryPoints::APTTransferWithMasterSigner + | EntryPoints::MonotonicCounter { .. } => "framework_usecases", EntryPoints::OrderBook { .. } => "experimental_usecases", EntryPoints::TokenV2AmbassadorMint { .. } | EntryPoints::TokenV2AmbassadorBurn => { "ambassador_token" @@ -334,6 +377,9 @@ impl EntryPointTrait for EntryPoints { EntryPoints::IncGlobalMilestoneAggV2 { .. } | EntryPoints::CreateGlobalMilestoneAggV2 { .. } => "aggregator_examples", EntryPoints::DeserializeU256 => "bcs_stream", + EntryPoints::MoveVmMicroBenchmark(entrypoint) => match entrypoint { + MoveVmMicroBenchmark::Locals | MoveVmMicroBenchmark::LocalsGeneric => "locals", + }, } } @@ -341,6 +387,7 @@ impl EntryPointTrait for EntryPoints { match self { EntryPoints::Republish | EntryPoints::Nop + | EntryPoints::NopOrderless | EntryPoints::NopFeePayer | EntryPoints::Nop2Signers | EntryPoints::Nop5Signers @@ -350,6 +397,7 @@ impl EntryPointTrait for EntryPoints { | EntryPoints::Double | EntryPoints::Half | EntryPoints::Loop { .. } + | EntryPoints::Fibonacci { .. } | EntryPoints::GetFromConst { .. } | EntryPoints::SetId | EntryPoints::SetName @@ -401,7 +449,11 @@ impl EntryPointTrait for EntryPoints { EntryPoints::DeserializeU256 => "bcs_stream", EntryPoints::APTTransferWithPermissionedSigner | EntryPoints::APTTransferWithMasterSigner => "permissioned_transfer", + EntryPoints::MonotonicCounter { .. } => "transaction_context_example", EntryPoints::OrderBook { .. } => "order_book_example", + EntryPoints::MoveVmMicroBenchmark(entrypoint) => match entrypoint { + MoveVmMicroBenchmark::Locals | MoveVmMicroBenchmark::LocalsGeneric => "locals", + }, } } @@ -431,6 +483,8 @@ impl EntryPointTrait for EntryPoints { EntryPoints::Nop5Signers => { get_payload_void(module_id, ident_str!("nop_5_signers").to_owned()) }, + EntryPoints::NopOrderless => get_payload_void(module_id, ident_str!("nop").to_owned()) + .set_replay_protection_nonce(rng.expect("Must provide RNG").r#gen()), EntryPoints::Step => get_payload_void(module_id, ident_str!("step").to_owned()), EntryPoints::GetCounter => { get_payload_void(module_id, ident_str!("get_counter").to_owned()) @@ -461,6 +515,16 @@ impl EntryPointTrait for EntryPoints { }; get_payload(module_id, ident_str!(method).to_owned(), args) }, + EntryPoints::Fibonacci { n, function_type } => { + let method = match function_type { + FibonacciFunctionType::Recursive => "fibonacci_recursive", + FibonacciFunctionType::TailRecursive => "fibonacci_tail_recursive", + FibonacciFunctionType::Iterative => "fibonacci_iterative", + }; + get_payload(module_id, ident_str!(method).to_owned(), vec![ + bcs::to_bytes(&n).unwrap(), + ]) + }, EntryPoints::GetFromConst { const_idx } => get_from_random_const( module_id, const_idx.unwrap_or_else( @@ -506,9 +570,9 @@ impl EntryPointTrait for EntryPoints { max_count, } => { let rng = rng.expect("Must provide RNG"); - let mut offset: u64 = rng.gen(); + let mut offset: u64 = rng.r#gen(); offset %= max_offset; - let mut count: u64 = rng.gen(); + let mut count: u64 = rng.r#gen(); count %= max_count; get_payload( module_id, @@ -531,7 +595,7 @@ impl EntryPointTrait for EntryPoints { module_id, ident_str!("modify_bounded_agg_v2").to_owned(), vec![ - bcs::to_bytes(&rng.gen::()).unwrap(), + bcs::to_bytes(&rng.r#gen::()).unwrap(), bcs::to_bytes(&step).unwrap(), ], ) @@ -834,8 +898,20 @@ impl EntryPointTrait for EntryPoints { bcs::to_bytes(&1u64).unwrap(), ]) }, + EntryPoints::MonotonicCounter { counter_type } => match counter_type { + MonotonicCounterType::Single => get_payload_void( + module_id, + ident_str!("test_monotonic_counter_single").to_owned(), + ), + MonotonicCounterType::Multiple { count } => get_payload( + module_id, + ident_str!("test_monotonic_counter_multiple").to_owned(), + vec![bcs::to_bytes(&count).unwrap()], + ), + }, EntryPoints::OrderBook { state, + num_markets, overlap_ratio, buy_frequency, max_buy_size, @@ -843,17 +919,19 @@ impl EntryPointTrait for EntryPoints { } => { let rng: &mut StdRng = rng.expect("Must provide RNG"); + let market_id = rng.gen_range(0, *num_markets); let price_range = 1000000; - let is_buy = rng.gen_bool(*buy_frequency); - let size = rng.gen_range(1, 1 + if is_buy { max_buy_size } else { max_sell_size }); - let price = if is_buy { + let is_bid = rng.gen_bool(*buy_frequency); + let size = rng.gen_range(1, 1 + if is_bid { max_buy_size } else { max_sell_size }); + let price = if is_bid { 0 } else { (price_range as f64 * (1.0 - *overlap_ratio)) as u64 } + rng.gen_range(0, price_range); - // (account_order_id: u64, bid_price: u64, volume: u64, is_buy: bool) + // (account_order_id: u64, bid_price: u64, volume: u64, is_bid: bool) get_payload(module_id, ident_str!("place_order").to_owned(), vec![ + bcs::to_bytes(&market_id).unwrap(), bcs::to_bytes(&AccountAddress::random()).unwrap(), bcs::to_bytes( &state @@ -863,9 +941,17 @@ impl EntryPointTrait for EntryPoints { .unwrap(), bcs::to_bytes(&price).unwrap(), // bid_price bcs::to_bytes(&size).unwrap(), // volume - bcs::to_bytes(&is_buy).unwrap(), // is_buy + bcs::to_bytes(&is_bid).unwrap(), // is_bid ]) }, + EntryPoints::MoveVmMicroBenchmark(entrypoint) => match entrypoint { + MoveVmMicroBenchmark::Locals => { + get_payload_void(module_id, ident_str!("benchmark").to_owned()) + }, + MoveVmMicroBenchmark::LocalsGeneric => { + get_payload_void(module_id, ident_str!("benchmark_generic").to_owned()) + }, + }, } } @@ -925,6 +1011,7 @@ impl EntryPointTrait for EntryPoints { match self { EntryPoints::Republish => AutomaticArgs::Signer, EntryPoints::Nop + | EntryPoints::NopOrderless | EntryPoints::NopFeePayer | EntryPoints::Step | EntryPoints::GetCounter @@ -932,6 +1019,7 @@ impl EntryPointTrait for EntryPoints { | EntryPoints::Double | EntryPoints::Half | EntryPoints::Loop { .. } + | EntryPoints::Fibonacci { .. } | EntryPoints::GetFromConst { .. } | EntryPoints::SetId | EntryPoints::SetName @@ -986,7 +1074,9 @@ impl EntryPointTrait for EntryPoints { EntryPoints::CreateGlobalMilestoneAggV2 { .. } => AutomaticArgs::Signer, EntryPoints::APTTransferWithPermissionedSigner | EntryPoints::APTTransferWithMasterSigner => AutomaticArgs::Signer, + EntryPoints::MonotonicCounter { .. } => AutomaticArgs::None, EntryPoints::OrderBook { .. } => AutomaticArgs::None, + EntryPoints::MoveVmMicroBenchmark(_) => AutomaticArgs::None, } } } @@ -1004,7 +1094,7 @@ fn get_from_random_const(module_id: ModuleId, idx: u64) -> TransactionPayload { } fn set_id(rng: &mut StdRng, module_id: ModuleId) -> TransactionPayload { - let id: u64 = rng.gen(); + let id: u64 = rng.r#gen(); get_payload(module_id, ident_str!("set_id").to_owned(), vec![ bcs::to_bytes(&id).unwrap(), ]) @@ -1045,7 +1135,7 @@ fn make_or_change( str_len: usize, data_len: usize, ) -> TransactionPayload { - let id: u64 = rng.gen(); + let id: u64 = rng.r#gen(); let name: String = rand_string(rng, str_len); let mut bytes = Vec::::with_capacity(data_len); rng.fill_bytes(&mut bytes); diff --git a/crates/transaction-workloads-lib/src/prebuilt_packages.rs b/crates/transaction-workloads-lib/src/prebuilt_packages.rs new file mode 100644 index 00000000000..24dfa79fb04 --- /dev/null +++ b/crates/transaction-workloads-lib/src/prebuilt_packages.rs @@ -0,0 +1,36 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +// This file was generated. Do not modify! +// +// To update this code, run `testsuite/benchmark-workloads/generate.py`. + +use aptos_sdk::bcs; +use aptos_transaction_generator_lib::{ + entry_point_trait::PreBuiltPackages, publishing::prebuild_packages::PrebuiltPackagesBundle, +}; +use once_cell::sync::Lazy; + +/// Bytes of all pre-build packages. +#[rustfmt::skip] +const PREBUILT_BUNDLE_BYTES: &[u8] = + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/prebuilt.mpb")); + +/// Pre-built deserialized data: for each package, stores package metadata, compiled modules and +/// scripts. +#[rustfmt::skip] +static PREBUILT_BUNDLE: Lazy = Lazy::new(|| { + bcs::from_bytes::(PREBUILT_BUNDLE_BYTES) + .expect("prebuilt.mpb can be deserialized") +}); + +#[rustfmt::skip] +#[derive(Debug)] +pub struct PreBuiltPackagesImpl; + +#[rustfmt::skip] +impl PreBuiltPackages for PreBuiltPackagesImpl { + fn package_bundle(&self) -> &PrebuiltPackagesBundle { + &PREBUILT_BUNDLE + } +} diff --git a/crates/transaction-workloads-lib/src/raw_module_data.rs b/crates/transaction-workloads-lib/src/raw_module_data.rs deleted file mode 100644 index 353427c8e41..00000000000 --- a/crates/transaction-workloads-lib/src/raw_module_data.rs +++ /dev/null @@ -1,2493 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -// This file was generated. Do not modify! -// -// To update this code, run `cargo run -p module-publish` in aptos core. -// That test compiles the set of modules defined in -// `testsuite/simple/src/simple/sources/` -// and it writes the binaries here. -// The module name (prefixed with `MODULE_`) is a `Lazy` instance that returns the -// byte array of the module binary. -// This crate should also provide a Rust file that allows proper manipulation of each -// module defined below. - -use aptos_transaction_generator_lib::entry_point_trait::PreBuiltPackages; -use once_cell::sync::Lazy; -use std::collections::HashMap; - -#[rustfmt::skip] -pub static PACKAGE_SIMPLE_METADATA: Lazy> = Lazy::new(|| { - vec![ - 13, 71, 101, 110, 101, 114, 105, 99, 77, 111, 100, 117, 108, 101, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 64, 57, 51, 57, 69, 67, 66, 51, 52, 55, 65, 56, 56, - 65, 52, 66, 57, 54, 48, 54, 65, 55, 53, 54, 55, 69, 52, 48, 57, 69, 56, - 53, 53, 65, 70, 69, 68, 51, 55, 56, 57, 68, 70, 70, 70, 65, 57, 51, 54, - 68, 66, 53, 55, 67, 48, 50, 57, 52, 69, 50, 65, 50, 56, 54, 54, 132, 1, - 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 77, 139, 59, 14, 194, 48, 16, 68, - 251, 61, 133, 229, 30, 135, 11, 80, 208, 64, 197, 9, 162, 20, 43, 123, 64, 86, - 156, 93, 203, 134, 80, 32, 238, 142, 45, 1, 138, 102, 154, 249, 188, 49, 179, 159, - 249, 134, 137, 132, 23, 152, 131, 177, 103, 8, 74, 244, 23, 13, 143, 4, 75, 43, - 74, 141, 42, 125, 217, 187, 38, 75, 52, 6, 100, 72, 128, 248, 136, 58, 209, 49, - 223, 181, 158, 74, 195, 159, 90, 230, 118, 124, 153, 164, 158, 83, 71, 156, 27, 182, - 230, 126, 221, 45, 186, 98, 184, 254, 128, 111, 249, 207, 214, 188, 233, 3, 132, 221, - 66, 189, 150, 0, 0, 0, 1, 6, 115, 105, 109, 112, 108, 101, 0, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, - 111, 115, 70, 114, 97, 109, 101, 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, - 118, 101, 83, 116, 100, 108, 105, 98, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_SIMPLE_SIMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 18, 2, 18, 46, 3, 64, 205, - 1, 4, 141, 2, 10, 5, 151, 2, 159, 2, 7, 182, 4, 227, 4, 8, 153, 9, - 64, 6, 217, 9, 105, 16, 194, 10, 93, 10, 159, 11, 51, 12, 210, 11, 185, 15, - 13, 139, 27, 16, 0, 0, 1, 9, 1, 15, 1, 20, 1, 22, 1, 29, 1, 33, - 1, 40, 1, 53, 0, 1, 8, 0, 0, 3, 8, 0, 0, 5, 7, 0, 0, 6, - 8, 0, 1, 8, 4, 1, 6, 1, 0, 10, 6, 0, 0, 11, 8, 0, 2, 14, - 7, 0, 0, 17, 8, 0, 3, 19, 4, 2, 3, 1, 0, 1, 0, 21, 0, 1, - 0, 1, 4, 23, 0, 2, 0, 1, 2, 24, 3, 4, 0, 1, 0, 25, 7, 1, - 0, 1, 0, 26, 9, 1, 0, 1, 0, 27, 11, 12, 0, 1, 0, 28, 14, 1, - 0, 1, 5, 30, 0, 16, 1, 6, 1, 1, 31, 17, 1, 1, 6, 1, 0, 32, - 0, 1, 0, 1, 6, 34, 8, 8, 0, 1, 0, 35, 14, 1, 0, 1, 0, 36, - 0, 1, 0, 1, 0, 37, 0, 1, 0, 1, 0, 38, 14, 1, 0, 1, 0, 39, - 21, 1, 0, 1, 7, 41, 23, 3, 1, 0, 1, 0, 42, 14, 1, 0, 1, 0, - 43, 25, 1, 0, 1, 0, 44, 21, 1, 0, 1, 3, 45, 1, 28, 2, 3, 4, - 1, 3, 46, 29, 30, 2, 3, 2, 1, 0, 47, 32, 1, 0, 1, 0, 48, 32, - 1, 0, 1, 0, 49, 0, 1, 0, 1, 0, 50, 35, 1, 0, 1, 0, 51, 36, - 1, 0, 1, 0, 52, 37, 1, 0, 1, 8, 54, 38, 1, 0, 1, 0, 55, 0, - 1, 0, 1, 0, 56, 14, 1, 0, 1, 0, 57, 41, 1, 0, 1, 0, 58, 0, - 1, 0, 1, 7, 15, 8, 15, 16, 22, 20, 27, 21, 27, 1, 6, 12, 0, 1, - 5, 1, 10, 2, 1, 8, 7, 1, 2, 4, 8, 2, 8, 6, 7, 8, 6, 3, - 2, 7, 10, 2, 6, 10, 2, 1, 3, 2, 6, 12, 10, 2, 2, 7, 10, 2, - 8, 0, 4, 6, 8, 6, 6, 8, 6, 6, 8, 1, 6, 8, 1, 1, 6, 3, - 4, 6, 3, 6, 3, 6, 3, 6, 3, 2, 6, 12, 3, 1, 8, 5, 1, 11, - 4, 1, 9, 0, 2, 7, 11, 4, 1, 9, 0, 9, 0, 2, 5, 7, 8, 3, - 3, 10, 3, 3, 10, 3, 7, 3, 3, 3, 3, 1, 1, 1, 3, 6, 12, 3, - 3, 1, 10, 3, 1, 6, 9, 0, 3, 10, 3, 3, 10, 2, 4, 6, 12, 3, - 8, 7, 10, 2, 6, 7, 8, 6, 7, 3, 7, 8, 7, 7, 10, 2, 8, 2, - 8, 6, 2, 3, 3, 1, 11, 9, 2, 9, 0, 9, 1, 3, 7, 11, 9, 2, - 9, 0, 9, 1, 9, 0, 9, 1, 1, 7, 9, 1, 3, 5, 7, 11, 9, 2, - 3, 3, 7, 3, 2, 6, 12, 5, 7, 8, 2, 8, 6, 3, 3, 10, 2, 7, - 8, 6, 1, 7, 8, 2, 8, 6, 6, 8, 6, 3, 3, 3, 7, 8, 6, 2, - 6, 12, 6, 12, 5, 6, 12, 6, 12, 6, 12, 6, 12, 6, 12, 4, 6, 12, - 6, 12, 10, 2, 10, 10, 2, 3, 6, 12, 10, 2, 10, 10, 2, 3, 7, 8, - 6, 8, 2, 8, 6, 3, 8, 2, 8, 6, 7, 3, 2, 6, 12, 8, 7, 3, - 8, 2, 8, 6, 7, 8, 7, 2, 5, 7, 8, 1, 6, 115, 105, 109, 112, 108, - 101, 12, 66, 121, 116, 101, 82, 101, 115, 111, 117, 114, 99, 101, 4, 100, 97, 116, - 97, 7, 67, 111, 117, 110, 116, 101, 114, 5, 99, 111, 117, 110, 116, 4, 68, 97, - 116, 97, 10, 69, 118, 101, 110, 116, 83, 116, 111, 114, 101, 13, 115, 105, 109, 112, - 108, 101, 95, 101, 118, 101, 110, 116, 115, 11, 69, 118, 101, 110, 116, 72, 97, 110, - 100, 108, 101, 5, 101, 118, 101, 110, 116, 11, 83, 105, 109, 112, 108, 101, 69, 118, - 101, 110, 116, 8, 82, 101, 115, 111, 117, 114, 99, 101, 2, 105, 100, 4, 110, 97, - 109, 101, 6, 83, 116, 114, 105, 110, 103, 6, 115, 116, 114, 105, 110, 103, 8, 101, - 118, 101, 110, 116, 95, 105, 100, 10, 84, 97, 98, 108, 101, 83, 116, 111, 114, 101, - 13, 116, 97, 98, 108, 101, 95, 101, 110, 116, 114, 105, 101, 115, 5, 84, 97, 98, - 108, 101, 5, 116, 97, 98, 108, 101, 6, 100, 111, 117, 98, 108, 101, 6, 115, 105, - 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 4, 117, 116, - 102, 56, 11, 97, 112, 112, 101, 110, 100, 95, 100, 97, 116, 97, 20, 98, 121, 116, - 101, 115, 95, 109, 97, 107, 101, 95, 111, 114, 95, 99, 104, 97, 110, 103, 101, 14, - 99, 111, 112, 121, 95, 112, 97, 115, 116, 97, 95, 114, 101, 102, 11, 101, 109, 105, - 116, 95, 101, 118, 101, 110, 116, 115, 7, 97, 99, 99, 111, 117, 110, 116, 16, 110, - 101, 119, 95, 101, 118, 101, 110, 116, 95, 104, 97, 110, 100, 108, 101, 10, 101, 109, - 105, 116, 95, 101, 118, 101, 110, 116, 11, 103, 101, 116, 95, 99, 111, 117, 110, 116, - 101, 114, 5, 101, 114, 114, 111, 114, 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, - 114, 103, 117, 109, 101, 110, 116, 21, 103, 101, 116, 95, 102, 114, 111, 109, 95, 114, - 97, 110, 100, 111, 109, 95, 99, 111, 110, 115, 116, 4, 104, 97, 108, 102, 11, 105, - 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 15, 108, 111, 111, 112, 95, 97, 114, - 105, 116, 104, 109, 101, 116, 105, 99, 8, 108, 111, 111, 112, 95, 98, 99, 115, 3, - 98, 99, 115, 8, 116, 111, 95, 98, 121, 116, 101, 115, 8, 108, 111, 111, 112, 95, - 110, 111, 112, 14, 109, 97, 107, 101, 95, 111, 114, 95, 99, 104, 97, 110, 103, 101, - 20, 109, 97, 107, 101, 95, 111, 114, 95, 99, 104, 97, 110, 103, 101, 95, 116, 97, - 98, 108, 101, 3, 110, 101, 119, 23, 98, 111, 114, 114, 111, 119, 95, 109, 117, 116, - 95, 119, 105, 116, 104, 95, 100, 101, 102, 97, 117, 108, 116, 8, 109, 97, 120, 105, - 109, 105, 122, 101, 8, 109, 105, 110, 105, 109, 105, 122, 101, 3, 110, 111, 112, 13, - 110, 111, 112, 95, 50, 95, 115, 105, 103, 110, 101, 114, 115, 13, 110, 111, 112, 95, - 53, 95, 115, 105, 103, 110, 101, 114, 115, 9, 112, 117, 98, 108, 105, 115, 104, 95, - 112, 4, 99, 111, 100, 101, 19, 112, 117, 98, 108, 105, 115, 104, 95, 112, 97, 99, - 107, 97, 103, 101, 95, 116, 120, 110, 10, 114, 101, 115, 101, 116, 95, 100, 97, 116, - 97, 6, 115, 101, 116, 95, 105, 100, 8, 115, 101, 116, 95, 110, 97, 109, 101, 11, - 115, 116, 101, 112, 95, 115, 105, 103, 110, 101, 114, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 10, 2, 9, 8, 1, 35, 69, 103, 137, 171, 205, 239, 10, 2, 6, - 5, 104, 101, 108, 108, 111, 10, 3, 81, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, - 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, - 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, - 115, 58, 58, 109, 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 42, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 29, 69, 67, 79, 85, 78, 84, 69, 82, 95, 82, 69, - 83, 79, 85, 82, 67, 69, 95, 78, 79, 84, 95, 80, 82, 69, 83, 69, 78, 84, - 0, 0, 0, 0, 2, 1, 2, 10, 2, 1, 2, 1, 4, 3, 2, 2, 1, 2, - 10, 2, 3, 2, 1, 7, 11, 4, 1, 8, 5, 6, 2, 3, 12, 3, 13, 8, - 7, 2, 8, 2, 5, 2, 1, 16, 3, 8, 2, 1, 18, 11, 9, 2, 3, 3, - 0, 1, 4, 1, 4, 6, 44, 10, 0, 17, 1, 41, 4, 3, 17, 7, 0, 18, - 2, 12, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 17, 2, 11, 1, - 18, 4, 12, 2, 11, 0, 11, 2, 45, 4, 2, 11, 0, 17, 1, 42, 4, 12, - 3, 10, 3, 16, 0, 16, 1, 65, 5, 6, 2, 0, 0, 0, 0, 0, 0, 0, - 24, 12, 4, 10, 3, 16, 0, 16, 1, 65, 5, 10, 4, 35, 4, 41, 10, 3, - 15, 0, 15, 1, 49, 255, 68, 5, 5, 28, 11, 3, 1, 5, 16, 3, 0, 0, - 0, 8, 25, 10, 1, 65, 5, 12, 2, 10, 2, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 36, 4, 20, 10, 0, 10, 1, 10, 2, 6, 1, 0, 0, 0, 0, 0, - 0, 0, 23, 66, 5, 20, 68, 5, 11, 2, 6, 1, 0, 0, 0, 0, 0, 0, - 0, 23, 12, 2, 5, 3, 11, 0, 1, 11, 1, 1, 2, 4, 1, 4, 1, 0, - 10, 20, 10, 0, 17, 1, 41, 0, 4, 13, 11, 0, 17, 1, 42, 0, 15, 2, - 12, 2, 11, 1, 11, 2, 21, 2, 11, 1, 18, 0, 12, 3, 11, 0, 11, 3, - 45, 0, 5, 12, 5, 0, 0, 0, 13, 103, 10, 0, 16, 3, 12, 4, 10, 1, - 16, 3, 12, 5, 11, 4, 20, 10, 5, 20, 35, 4, 94, 11, 5, 12, 4, 10, - 2, 16, 4, 12, 5, 10, 5, 20, 10, 1, 16, 3, 20, 35, 4, 67, 11, 0, - 1, 11, 1, 1, 11, 2, 1, 11, 4, 1, 11, 5, 12, 4, 11, 3, 16, 4, - 12, 5, 10, 4, 20, 10, 5, 20, 35, 4, 62, 11, 5, 1, 10, 4, 12, 5, - 10, 4, 10, 5, 33, 4, 57, 11, 5, 1, 11, 4, 12, 7, 11, 7, 2, 11, - 4, 1, 11, 5, 12, 7, 5, 55, 11, 4, 1, 10, 5, 12, 4, 5, 47, 11, - 3, 1, 10, 4, 12, 6, 11, 0, 16, 3, 12, 7, 11, 6, 11, 7, 34, 4, - 89, 11, 4, 1, 11, 5, 1, 11, 2, 16, 4, 12, 4, 11, 1, 16, 3, 12, - 5, 5, 37, 11, 1, 1, 11, 2, 1, 5, 37, 11, 5, 1, 10, 1, 16, 3, - 12, 4, 10, 3, 16, 4, 12, 5, 5, 17, 6, 0, 0, 1, 3, 18, 34, 10, - 0, 17, 1, 12, 2, 10, 2, 41, 3, 3, 31, 10, 0, 11, 0, 56, 0, 18, - 3, 45, 3, 11, 2, 42, 3, 12, 3, 10, 1, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 36, 4, 28, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 23, 12, - 1, 10, 3, 15, 5, 10, 1, 18, 5, 56, 1, 5, 14, 11, 3, 1, 2, 11, - 0, 1, 5, 11, 9, 1, 4, 1, 1, 2, 15, 11, 0, 17, 1, 12, 1, 10, - 1, 41, 1, 4, 12, 11, 1, 43, 1, 16, 4, 20, 1, 2, 6, 1, 0, 0, - 0, 0, 0, 0, 0, 17, 10, 39, 11, 1, 4, 0, 19, 29, 7, 2, 12, 2, - 11, 0, 1, 14, 2, 65, 8, 12, 3, 10, 3, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 3, 12, 5, 28, 10, 1, 10, 3, 38, 3, 17, 5, 21, 11, 3, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 23, 12, 1, 7, 2, 12, 4, 14, 4, - 11, 1, 66, 8, 20, 1, 2, 12, 1, 4, 1, 4, 6, 44, 10, 0, 17, 1, - 41, 4, 3, 17, 7, 0, 18, 2, 12, 1, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 1, 17, 2, 11, 1, 18, 4, 12, 2, 11, 0, 11, 2, 45, 4, 2, - 11, 0, 17, 1, 42, 4, 12, 3, 10, 3, 16, 0, 16, 1, 65, 5, 6, 2, - 0, 0, 0, 0, 0, 0, 0, 26, 12, 4, 10, 3, 16, 0, 16, 1, 65, 5, - 10, 4, 36, 4, 41, 10, 3, 15, 0, 15, 1, 69, 5, 1, 5, 28, 11, 3, - 1, 5, 16, 13, 0, 0, 0, 1, 5, 11, 0, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 1, 45, 1, 2, 14, 1, 4, 0, 20, 76, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 12, 2, 11, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 3, 10, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 36, 4, 75, 11, 1, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 23, 12, 1, 11, 2, 6, 1, 0, 0, - 0, 0, 0, 0, 0, 22, 12, 4, 11, 3, 6, 1, 0, 0, 0, 0, 0, 0, - 0, 22, 12, 5, 10, 4, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 11, 4, - 23, 12, 3, 10, 5, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 10, 5, 23, - 12, 4, 10, 4, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 2, 10, 4, - 10, 2, 36, 4, 72, 10, 2, 10, 5, 36, 12, 6, 11, 6, 4, 69, 11, 5, - 10, 3, 36, 12, 7, 11, 7, 4, 66, 10, 3, 11, 4, 36, 12, 8, 11, 8, - 3, 61, 5, 6, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 1, - 5, 6, 9, 12, 8, 5, 58, 9, 12, 7, 5, 52, 9, 12, 6, 5, 46, 2, - 15, 1, 4, 0, 24, 41, 64, 8, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, - 11, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 10, 4, 10, 2, - 35, 4, 18, 13, 3, 10, 4, 68, 8, 11, 4, 6, 1, 0, 0, 0, 0, 0, - 0, 0, 22, 12, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, - 10, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 36, 4, 40, 14, 3, 56, 2, - 12, 5, 11, 2, 14, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 66, 5, 20, - 52, 22, 12, 2, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 23, 12, 1, - 5, 20, 2, 17, 1, 4, 0, 1, 10, 10, 1, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 36, 4, 9, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 23, 12, - 1, 5, 0, 2, 18, 1, 4, 1, 4, 26, 40, 10, 0, 17, 1, 41, 4, 4, - 28, 11, 0, 17, 1, 42, 4, 12, 4, 10, 4, 15, 3, 12, 5, 11, 1, 11, - 5, 21, 10, 4, 15, 6, 12, 6, 11, 2, 11, 6, 21, 11, 4, 15, 0, 15, - 1, 12, 7, 11, 3, 11, 7, 21, 2, 11, 3, 18, 2, 12, 8, 11, 1, 11, - 2, 11, 8, 18, 4, 12, 9, 11, 0, 11, 9, 45, 4, 5, 27, 19, 0, 0, - 1, 6, 31, 42, 10, 0, 17, 1, 12, 3, 10, 3, 41, 6, 3, 39, 11, 0, - 56, 3, 18, 6, 45, 6, 11, 3, 42, 6, 15, 7, 12, 4, 10, 2, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 4, 36, 11, 2, 6, 1, 0, 0, 0, 0, - 0, 0, 0, 23, 12, 2, 10, 4, 10, 1, 10, 2, 22, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 4, 12, 5, 10, 5, 20, 6, 1, 0, 0, 0, 0, 0, - 0, 0, 22, 11, 5, 21, 5, 14, 11, 4, 1, 2, 11, 0, 1, 5, 10, 22, - 1, 4, 1, 4, 33, 86, 10, 1, 41, 4, 4, 6, 11, 0, 1, 2, 10, 0, - 17, 1, 41, 4, 4, 11, 5, 23, 7, 0, 18, 2, 12, 2, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 1, 17, 2, 11, 2, 18, 4, 12, 3, 10, 0, 11, - 3, 45, 4, 10, 0, 17, 1, 43, 4, 16, 0, 16, 1, 65, 5, 10, 1, 43, - 4, 16, 0, 16, 1, 65, 5, 36, 4, 75, 11, 0, 17, 1, 43, 4, 16, 0, - 16, 1, 20, 12, 6, 11, 1, 42, 4, 12, 7, 14, 6, 65, 5, 10, 7, 16, - 0, 16, 1, 65, 5, 36, 4, 67, 8, 12, 8, 11, 8, 4, 64, 10, 7, 15, - 0, 15, 1, 14, 6, 17, 3, 5, 46, 11, 7, 1, 2, 10, 7, 16, 0, 16, - 1, 65, 5, 6, 16, 39, 0, 0, 0, 0, 0, 0, 35, 12, 8, 5, 56, 11, - 1, 43, 4, 16, 0, 16, 1, 20, 12, 6, 11, 0, 17, 1, 42, 4, 12, 7, - 5, 46, 23, 1, 4, 1, 4, 34, 76, 10, 1, 41, 4, 4, 6, 11, 0, 1, - 2, 10, 0, 17, 1, 41, 4, 4, 11, 5, 23, 7, 0, 18, 2, 12, 2, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 17, 2, 11, 2, 18, 4, 12, 3, - 10, 0, 11, 3, 45, 4, 10, 0, 17, 1, 43, 4, 10, 1, 43, 4, 12, 4, - 16, 0, 16, 1, 65, 5, 12, 5, 11, 4, 16, 0, 16, 1, 65, 5, 12, 6, - 10, 5, 10, 6, 36, 4, 66, 11, 6, 6, 2, 0, 0, 0, 0, 0, 0, 0, - 26, 12, 7, 11, 0, 17, 1, 42, 4, 12, 8, 10, 8, 16, 0, 16, 1, 65, - 5, 10, 7, 36, 4, 63, 10, 8, 15, 0, 15, 1, 69, 5, 1, 5, 50, 11, - 8, 1, 2, 11, 0, 1, 11, 5, 6, 2, 0, 0, 0, 0, 0, 0, 0, 26, - 12, 7, 11, 1, 42, 4, 12, 8, 5, 50, 24, 1, 4, 0, 1, 3, 11, 0, - 1, 2, 25, 1, 4, 0, 1, 5, 11, 0, 1, 11, 1, 1, 2, 26, 1, 4, - 0, 1, 11, 11, 0, 1, 11, 1, 1, 11, 2, 1, 11, 3, 1, 11, 4, 1, - 2, 27, 1, 4, 0, 1, 7, 11, 1, 11, 0, 1, 11, 2, 11, 3, 17, 28, - 2, 29, 1, 4, 1, 4, 39, 36, 10, 0, 17, 1, 41, 4, 4, 23, 11, 0, - 17, 1, 42, 4, 12, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 15, - 3, 21, 7, 1, 17, 2, 10, 1, 15, 6, 21, 7, 0, 11, 1, 15, 0, 15, - 1, 21, 2, 7, 0, 18, 2, 12, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 1, 17, 2, 11, 2, 18, 4, 12, 3, 11, 0, 11, 3, 45, 4, 5, 22, - 30, 1, 4, 1, 4, 40, 26, 10, 0, 17, 1, 41, 4, 3, 17, 7, 0, 18, - 2, 12, 2, 11, 1, 7, 1, 17, 2, 11, 2, 18, 4, 12, 3, 11, 0, 11, - 3, 45, 4, 2, 11, 0, 17, 1, 42, 4, 15, 3, 12, 4, 11, 1, 11, 4, - 21, 5, 16, 31, 1, 4, 1, 4, 42, 25, 10, 0, 17, 1, 41, 4, 3, 16, - 7, 0, 18, 2, 12, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 1, 11, - 2, 18, 4, 12, 3, 11, 0, 11, 3, 45, 4, 2, 11, 0, 17, 1, 42, 4, - 15, 6, 12, 4, 11, 1, 11, 4, 21, 5, 15, 32, 1, 4, 1, 1, 43, 21, - 11, 0, 17, 1, 12, 1, 10, 1, 41, 1, 4, 18, 11, 1, 42, 1, 12, 2, - 10, 2, 16, 4, 20, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 11, 2, 15, - 4, 21, 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 10, 39, 4, 2, 2, - 0, 0, 0, 4, 0, 1, 0, 3, 0, 4, 1, 6, 0, 0, - ] -}); - -#[rustfmt::skip] -pub static SCRIPT_SIMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 6, 1, 0, 2, 3, 2, 18, 5, 20, 13, - 7, 33, 55, 8, 88, 64, 16, 152, 1, 31, 1, 2, 0, 3, 2, 1, 0, 1, - 0, 4, 2, 1, 0, 1, 0, 5, 3, 1, 0, 1, 1, 6, 12, 0, 2, 6, - 12, 3, 3, 6, 12, 3, 3, 8, 60, 83, 69, 76, 70, 62, 95, 48, 4, 109, - 97, 105, 110, 6, 115, 105, 109, 112, 108, 101, 8, 108, 111, 111, 112, 95, 110, 111, - 112, 15, 108, 111, 111, 112, 95, 97, 114, 105, 116, 104, 109, 101, 116, 105, 99, 8, - 108, 111, 111, 112, 95, 98, 99, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, - 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, - 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 0, 0, 1, 20, 5, - 17, 10, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 10, 0, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 1, 11, 0, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 17, 2, 5, 13, 5, 14, 5, - 16, 5, 14, 5, 16, 2, 11, 0, 1, 5, 16, - ] -}); - -#[rustfmt::skip] -pub static MODULES_SIMPLE: Lazy>> = Lazy::new(|| { vec![ - MODULE_SIMPLE_SIMPLE.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_FRAMEWORK_USECASES_METADATA: Lazy> = Lazy::new(|| { - vec![ - 17, 70, 114, 97, 109, 101, 119, 111, 114, 107, 85, 115, 101, 99, 97, 115, 101, 115, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 57, 68, 67, 68, 67, 65, 52, 48, - 51, 55, 68, 53, 53, 56, 70, 54, 52, 69, 68, 48, 56, 69, 50, 53, 57, 66, - 69, 66, 66, 70, 52, 68, 69, 50, 51, 56, 66, 49, 54, 56, 52, 49, 66, 54, - 69, 50, 56, 48, 57, 55, 70, 65, 70, 53, 48, 65, 67, 57, 54, 56, 68, 51, - 67, 55, 215, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, 144, 187, 142, - 194, 64, 12, 69, 251, 249, 10, 107, 182, 38, 236, 15, 108, 193, 238, 138, 150, 6, - 170, 8, 33, 51, 49, 33, 100, 176, 163, 241, 240, 144, 16, 255, 78, 44, 30, 130, - 22, 100, 23, 215, 246, 189, 167, 112, 217, 97, 104, 177, 166, 185, 99, 220, 18, 252, - 128, 31, 167, 94, 28, 36, 181, 51, 165, 128, 74, 234, 221, 158, 146, 54, 194, 118, - 253, 46, 250, 242, 206, 149, 21, 117, 196, 21, 113, 104, 72, 231, 110, 212, 101, 209, - 71, 178, 55, 158, 32, 74, 192, 104, 145, 162, 24, 62, 55, 154, 117, 176, 149, 61, - 13, 87, 247, 192, 109, 249, 152, 61, 156, 175, 200, 169, 180, 196, 239, 226, 178, 133, - 95, 81, 147, 229, 134, 66, 214, 143, 136, 3, 185, 66, 140, 236, 190, 32, 147, 230, - 134, 107, 160, 99, 88, 35, 215, 38, 101, 5, 65, 88, 51, 114, 6, 172, 170, 68, - 170, 96, 20, 5, 236, 5, 197, 88, 184, 242, 182, 183, 231, 117, 187, 101, 108, 116, - 77, 105, 113, 55, 219, 163, 143, 163, 223, 191, 127, 239, 46, 112, 10, 188, 112, 161, - 1, 0, 0, 9, 18, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, 101, 120, - 97, 109, 112, 108, 101, 0, 0, 0, 12, 99, 111, 105, 110, 95, 101, 120, 97, 109, - 112, 108, 101, 0, 0, 0, 22, 102, 117, 110, 103, 105, 98, 108, 101, 95, 97, 115, - 115, 101, 116, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 12, 109, 97, 112, - 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 7, 111, 98, 106, 101, 99, - 116, 115, 0, 0, 0, 21, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 101, 100, - 95, 116, 114, 97, 110, 115, 102, 101, 114, 0, 0, 0, 23, 114, 101, 115, 111, 117, - 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, - 0, 0, 0, 8, 116, 111, 107, 101, 110, 95, 118, 49, 0, 0, 0, 14, 118, 101, - 99, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, 111, 115, - 70, 114, 97, 109, 101, 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, - 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 10, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, - 101, 110, 79, 98, 106, 101, 99, 116, 115, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_AGGREGATOR_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 8, 2, 8, 18, 3, 26, 64, - 4, 90, 8, 5, 98, 39, 7, 137, 1, 248, 1, 8, 129, 3, 64, 6, 193, 3, - 34, 16, 227, 3, 238, 1, 10, 209, 5, 21, 12, 230, 5, 232, 1, 13, 206, 7, - 6, 0, 0, 1, 4, 1, 8, 1, 13, 0, 1, 8, 0, 1, 3, 6, 1, 0, - 0, 0, 5, 8, 0, 0, 6, 8, 0, 0, 7, 0, 0, 0, 1, 2, 9, 1, - 1, 0, 1, 0, 10, 0, 0, 0, 1, 1, 11, 3, 4, 1, 0, 1, 0, 12, - 5, 0, 0, 1, 3, 14, 5, 6, 0, 1, 1, 15, 0, 7, 1, 3, 1, 1, - 16, 8, 7, 1, 3, 1, 0, 17, 9, 0, 0, 1, 1, 18, 3, 4, 1, 0, - 1, 3, 1, 6, 1, 7, 1, 9, 1, 0, 1, 3, 1, 7, 8, 2, 2, 7, - 11, 1, 1, 9, 0, 9, 0, 1, 1, 1, 6, 12, 1, 5, 1, 11, 1, 1, - 9, 0, 1, 9, 0, 2, 1, 3, 1, 7, 8, 0, 18, 97, 103, 103, 114, 101, - 103, 97, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 12, 66, 111, 117, 110, - 100, 101, 100, 65, 103, 103, 86, 50, 5, 99, 111, 117, 110, 116, 10, 65, 103, 103, - 114, 101, 103, 97, 116, 111, 114, 13, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, - 95, 118, 50, 7, 67, 111, 117, 110, 116, 101, 114, 12, 67, 111, 117, 110, 116, 101, - 114, 65, 103, 103, 86, 50, 9, 105, 110, 99, 114, 101, 109, 101, 110, 116, 5, 101, - 114, 114, 111, 114, 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, 109, - 101, 110, 116, 16, 105, 110, 99, 114, 101, 109, 101, 110, 116, 95, 97, 103, 103, 95, - 118, 50, 7, 116, 114, 121, 95, 97, 100, 100, 11, 105, 110, 105, 116, 95, 109, 111, - 100, 117, 108, 101, 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, - 115, 95, 111, 102, 27, 99, 114, 101, 97, 116, 101, 95, 117, 110, 98, 111, 117, 110, - 100, 101, 100, 95, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 17, 99, 114, 101, - 97, 116, 101, 95, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 21, 109, 111, 100, - 105, 102, 121, 95, 98, 111, 117, 110, 100, 101, 100, 95, 97, 103, 103, 95, 118, 50, - 7, 116, 114, 121, 95, 115, 117, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 5, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 20, 99, - 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, - 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, - 58, 109, 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 186, 1, 5, 1, 0, 0, - 0, 0, 0, 0, 0, 29, 69, 67, 79, 85, 78, 84, 69, 82, 95, 82, 69, 83, - 79, 85, 82, 67, 69, 95, 78, 79, 84, 95, 80, 82, 69, 83, 69, 78, 84, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 33, 69, 67, 79, 85, 78, 84, 69, 82, 95, - 65, 71, 71, 95, 82, 69, 83, 79, 85, 82, 67, 69, 95, 78, 79, 84, 95, 80, - 82, 69, 83, 69, 78, 84, 0, 3, 0, 0, 0, 0, 0, 0, 0, 33, 69, 66, - 79, 85, 78, 68, 69, 68, 95, 65, 71, 71, 95, 82, 69, 83, 79, 85, 82, 67, - 69, 95, 78, 79, 84, 95, 80, 82, 69, 83, 69, 78, 84, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 23, 69, 67, 79, 85, 78, 84, 69, 82, 95, 73, 78, 67, 82, - 69, 77, 69, 78, 84, 95, 70, 65, 73, 76, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 15, 69, 78, 79, 84, 95, 65, 85, 84, 72, 79, 82, 73, 90, 69, 68, 0, - 0, 0, 0, 2, 1, 2, 11, 1, 1, 3, 2, 2, 1, 2, 3, 3, 2, 1, - 2, 11, 1, 1, 3, 0, 1, 4, 1, 1, 2, 18, 7, 0, 41, 1, 4, 15, - 7, 0, 42, 1, 12, 0, 10, 0, 16, 0, 20, 6, 1, 0, 0, 0, 0, 0, - 0, 0, 22, 11, 0, 15, 0, 21, 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, - 17, 1, 39, 2, 1, 4, 1, 2, 0, 15, 7, 0, 41, 2, 4, 12, 7, 0, - 42, 2, 15, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 56, 0, 4, 10, 2, - 6, 4, 0, 0, 0, 0, 0, 0, 0, 39, 6, 2, 0, 0, 0, 0, 0, 0, - 0, 17, 1, 39, 4, 0, 0, 0, 0, 23, 10, 0, 17, 5, 7, 0, 33, 4, - 19, 10, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 18, 1, 45, 1, 10, 0, - 56, 1, 18, 2, 45, 2, 11, 0, 6, 100, 0, 0, 0, 0, 0, 0, 0, 56, - 2, 18, 0, 45, 0, 2, 11, 0, 1, 6, 5, 0, 0, 0, 0, 0, 0, 0, - 39, 8, 1, 4, 1, 0, 10, 23, 7, 0, 41, 0, 4, 20, 7, 0, 42, 0, - 12, 2, 11, 0, 4, 14, 11, 2, 15, 2, 11, 1, 56, 0, 1, 2, 11, 2, - 15, 2, 11, 1, 56, 3, 1, 5, 13, 6, 3, 0, 0, 0, 0, 0, 0, 0, - 17, 1, 39, 1, 0, 2, 0, 0, 0, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_COIN_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 11, 1, 0, 6, 2, 6, 4, 3, 10, 39, - 4, 49, 6, 5, 55, 29, 7, 84, 112, 8, 196, 1, 64, 6, 132, 2, 27, 16, - 159, 2, 31, 10, 190, 2, 5, 12, 195, 2, 39, 0, 0, 1, 4, 1, 8, 0, - 1, 0, 0, 0, 3, 0, 1, 0, 1, 1, 5, 3, 1, 1, 0, 1, 0, 6, - 4, 1, 0, 1, 1, 7, 0, 1, 1, 0, 1, 2, 9, 0, 5, 0, 1, 1, - 10, 6, 1, 1, 0, 1, 1, 2, 3, 2, 5, 2, 1, 6, 12, 0, 1, 8, - 0, 5, 6, 12, 10, 2, 10, 2, 2, 1, 3, 6, 12, 6, 12, 3, 1, 5, - 3, 6, 12, 5, 3, 12, 99, 111, 105, 110, 95, 101, 120, 97, 109, 112, 108, 101, - 11, 69, 120, 97, 109, 112, 108, 101, 67, 111, 105, 110, 11, 100, 117, 109, 109, 121, - 95, 102, 105, 101, 108, 100, 11, 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, - 12, 109, 97, 110, 97, 103, 101, 100, 95, 99, 111, 105, 110, 10, 105, 110, 105, 116, - 105, 97, 108, 105, 122, 101, 6, 109, 105, 110, 116, 95, 112, 8, 114, 101, 103, 105, - 115, 116, 101, 114, 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, - 115, 95, 111, 102, 4, 109, 105, 110, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 10, 2, 13, 12, 69, 120, 97, 109, 112, 108, 101, 32, 67, 111, 105, 110, 10, - 2, 8, 7, 69, 120, 97, 109, 112, 108, 101, 20, 99, 111, 109, 112, 105, 108, 97, - 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, - 48, 3, 50, 46, 49, 0, 2, 1, 2, 1, 0, 0, 0, 0, 1, 7, 11, 0, - 7, 0, 7, 1, 49, 8, 9, 56, 0, 2, 2, 1, 4, 0, 1, 8, 10, 0, - 56, 1, 11, 1, 11, 0, 17, 4, 11, 2, 56, 2, 2, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_FUNGIBLE_ASSET_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 16, 2, 16, 48, 3, 64, 152, - 1, 4, 216, 1, 16, 5, 232, 1, 216, 1, 7, 192, 3, 210, 4, 8, 146, 8, - 64, 6, 210, 8, 73, 16, 155, 9, 192, 1, 10, 219, 10, 12, 12, 231, 10, 231, - 1, 13, 206, 12, 4, 0, 0, 1, 4, 1, 12, 1, 14, 1, 16, 1, 25, 1, - 30, 1, 33, 0, 1, 8, 0, 1, 3, 6, 0, 1, 6, 6, 0, 1, 8, 6, - 0, 2, 11, 7, 1, 0, 1, 1, 13, 11, 0, 1, 18, 8, 0, 1, 23, 0, - 0, 2, 29, 2, 0, 6, 32, 7, 1, 0, 0, 7, 35, 7, 0, 0, 9, 0, - 1, 0, 1, 0, 10, 2, 3, 0, 1, 3, 15, 4, 2, 0, 1, 4, 17, 6, - 7, 1, 8, 1, 4, 19, 6, 7, 1, 8, 1, 1, 9, 9, 1, 1, 8, 1, - 0, 20, 11, 1, 0, 1, 2, 21, 12, 13, 1, 8, 1, 2, 22, 14, 2, 1, - 8, 1, 1, 20, 15, 16, 0, 1, 1, 24, 17, 1, 1, 8, 1, 5, 26, 18, - 18, 0, 1, 0, 27, 4, 1, 0, 1, 2, 28, 20, 21, 0, 1, 6, 31, 1, - 23, 1, 0, 1, 7, 34, 24, 25, 0, 1, 4, 36, 26, 1, 0, 1, 1, 37, - 27, 28, 0, 1, 1, 38, 27, 29, 0, 1, 1, 39, 27, 30, 0, 1, 2, 40, - 27, 31, 0, 1, 0, 41, 33, 1, 0, 1, 2, 42, 34, 2, 0, 1, 2, 43, - 2, 35, 1, 8, 1, 3, 5, 4, 5, 5, 8, 7, 5, 8, 5, 10, 8, 14, - 22, 23, 5, 4, 6, 12, 5, 5, 3, 0, 1, 5, 1, 11, 4, 1, 8, 5, - 1, 6, 12, 1, 8, 5, 2, 5, 11, 4, 1, 9, 0, 1, 11, 4, 1, 8, - 6, 1, 8, 6, 4, 6, 12, 11, 4, 1, 9, 0, 11, 4, 1, 9, 0, 3, - 3, 11, 4, 1, 8, 5, 11, 4, 1, 8, 6, 11, 4, 1, 8, 6, 3, 6, - 12, 5, 3, 2, 11, 4, 1, 9, 0, 5, 1, 1, 1, 6, 11, 4, 1, 9, - 0, 2, 6, 8, 1, 3, 1, 8, 7, 3, 6, 8, 2, 11, 4, 1, 9, 0, - 8, 7, 1, 3, 5, 11, 4, 1, 8, 5, 11, 4, 1, 8, 5, 6, 8, 0, - 11, 4, 1, 8, 6, 8, 7, 2, 6, 12, 10, 2, 1, 8, 8, 1, 4, 1, - 11, 9, 1, 9, 0, 1, 10, 2, 1, 8, 10, 7, 6, 8, 8, 11, 9, 1, - 4, 8, 10, 8, 10, 2, 8, 10, 8, 10, 1, 6, 8, 8, 1, 8, 1, 1, - 8, 3, 1, 8, 2, 1, 12, 7, 8, 8, 6, 8, 8, 8, 3, 12, 8, 2, - 8, 1, 8, 0, 3, 6, 12, 6, 12, 3, 2, 6, 5, 10, 2, 1, 11, 4, - 1, 9, 0, 22, 102, 117, 110, 103, 105, 98, 108, 101, 95, 97, 115, 115, 101, 116, - 95, 101, 120, 97, 109, 112, 108, 101, 20, 77, 97, 110, 97, 103, 101, 100, 70, 117, - 110, 103, 105, 98, 108, 101, 65, 115, 115, 101, 116, 8, 109, 105, 110, 116, 95, 114, - 101, 102, 7, 77, 105, 110, 116, 82, 101, 102, 14, 102, 117, 110, 103, 105, 98, 108, - 101, 95, 97, 115, 115, 101, 116, 12, 116, 114, 97, 110, 115, 102, 101, 114, 95, 114, - 101, 102, 11, 84, 114, 97, 110, 115, 102, 101, 114, 82, 101, 102, 8, 98, 117, 114, - 110, 95, 114, 101, 102, 7, 66, 117, 114, 110, 82, 101, 102, 8, 116, 114, 97, 110, - 115, 102, 101, 114, 12, 103, 101, 116, 95, 109, 101, 116, 97, 100, 97, 116, 97, 6, - 79, 98, 106, 101, 99, 116, 6, 111, 98, 106, 101, 99, 116, 8, 77, 101, 116, 97, - 100, 97, 116, 97, 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, - 115, 95, 111, 102, 22, 112, 114, 105, 109, 97, 114, 121, 95, 102, 117, 110, 103, 105, - 98, 108, 101, 95, 115, 116, 111, 114, 101, 13, 112, 114, 105, 109, 97, 114, 121, 95, - 115, 116, 111, 114, 101, 13, 70, 117, 110, 103, 105, 98, 108, 101, 83, 116, 111, 114, - 101, 27, 101, 110, 115, 117, 114, 101, 95, 112, 114, 105, 109, 97, 114, 121, 95, 115, - 116, 111, 114, 101, 95, 101, 120, 105, 115, 116, 115, 4, 109, 105, 110, 116, 8, 105, - 115, 95, 111, 119, 110, 101, 114, 14, 111, 98, 106, 101, 99, 116, 95, 97, 100, 100, - 114, 101, 115, 115, 13, 70, 117, 110, 103, 105, 98, 108, 101, 65, 115, 115, 101, 116, - 16, 100, 101, 112, 111, 115, 105, 116, 95, 119, 105, 116, 104, 95, 114, 101, 102, 5, - 101, 114, 114, 111, 114, 17, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 95, 100, - 101, 110, 105, 101, 100, 11, 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 19, - 99, 114, 101, 97, 116, 101, 95, 110, 97, 109, 101, 100, 95, 111, 98, 106, 101, 99, - 116, 14, 67, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 82, 101, 102, 6, 111, - 112, 116, 105, 111, 110, 4, 110, 111, 110, 101, 6, 79, 112, 116, 105, 111, 110, 6, - 115, 116, 114, 105, 110, 103, 4, 117, 116, 102, 56, 6, 83, 116, 114, 105, 110, 103, - 43, 99, 114, 101, 97, 116, 101, 95, 112, 114, 105, 109, 97, 114, 121, 95, 115, 116, - 111, 114, 101, 95, 101, 110, 97, 98, 108, 101, 100, 95, 102, 117, 110, 103, 105, 98, - 108, 101, 95, 97, 115, 115, 101, 116, 17, 103, 101, 110, 101, 114, 97, 116, 101, 95, - 109, 105, 110, 116, 95, 114, 101, 102, 17, 103, 101, 110, 101, 114, 97, 116, 101, 95, - 98, 117, 114, 110, 95, 114, 101, 102, 21, 103, 101, 110, 101, 114, 97, 116, 101, 95, - 116, 114, 97, 110, 115, 102, 101, 114, 95, 114, 101, 102, 15, 103, 101, 110, 101, 114, - 97, 116, 101, 95, 115, 105, 103, 110, 101, 114, 6, 109, 105, 110, 116, 95, 112, 21, - 99, 114, 101, 97, 116, 101, 95, 111, 98, 106, 101, 99, 116, 95, 97, 100, 100, 114, - 101, 115, 115, 17, 97, 100, 100, 114, 101, 115, 115, 95, 116, 111, 95, 111, 98, 106, - 101, 99, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 2, 3, 2, 70, - 65, 10, 2, 8, 7, 70, 65, 32, 67, 111, 105, 110, 10, 2, 31, 30, 104, 116, - 116, 112, 58, 47, 47, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109, 47, 102, - 97, 118, 105, 99, 111, 110, 46, 105, 99, 111, 10, 2, 19, 18, 104, 116, 116, 112, - 58, 47, 47, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109, 20, 99, 111, 109, - 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, - 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, - 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 140, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 10, 69, 78, 79, 84, 95, 79, 87, 78, 69, 82, 52, 79, 110, 108, - 121, 32, 102, 117, 110, 103, 105, 98, 108, 101, 32, 97, 115, 115, 101, 116, 32, 109, - 101, 116, 97, 100, 97, 116, 97, 32, 111, 119, 110, 101, 114, 32, 99, 97, 110, 32, - 109, 97, 107, 101, 32, 99, 104, 97, 110, 103, 101, 115, 46, 1, 20, 77, 97, 110, - 97, 103, 101, 100, 70, 117, 110, 103, 105, 98, 108, 101, 65, 115, 115, 101, 116, 1, - 3, 1, 24, 48, 120, 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, - 106, 101, 99, 116, 71, 114, 111, 117, 112, 1, 12, 103, 101, 116, 95, 109, 101, 116, - 97, 100, 97, 116, 97, 1, 1, 0, 0, 2, 3, 2, 8, 1, 5, 8, 2, 7, - 8, 3, 0, 1, 4, 0, 10, 18, 11, 1, 17, 1, 12, 4, 10, 0, 17, 2, - 10, 4, 56, 0, 12, 5, 11, 2, 11, 4, 56, 1, 12, 6, 11, 0, 11, 5, - 11, 6, 11, 3, 56, 2, 2, 6, 1, 4, 1, 0, 19, 33, 10, 0, 17, 2, - 17, 1, 12, 3, 10, 3, 12, 4, 10, 4, 11, 0, 17, 2, 56, 3, 4, 30, - 14, 4, 56, 4, 43, 0, 12, 5, 11, 1, 11, 3, 56, 1, 12, 6, 10, 5, - 16, 0, 11, 2, 17, 9, 12, 7, 11, 5, 16, 1, 11, 6, 11, 7, 56, 5, - 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 11, 39, 12, 0, 0, 0, 32, - 37, 11, 0, 7, 0, 17, 13, 12, 1, 14, 1, 12, 2, 10, 2, 56, 6, 7, - 1, 17, 15, 7, 0, 17, 15, 49, 8, 7, 2, 17, 15, 7, 3, 17, 15, 17, - 16, 10, 2, 17, 17, 10, 2, 17, 18, 12, 3, 10, 2, 17, 19, 11, 2, 17, - 20, 12, 4, 14, 4, 12, 0, 11, 3, 18, 0, 12, 7, 11, 0, 11, 7, 45, - 0, 2, 21, 1, 4, 1, 0, 1, 6, 11, 1, 11, 0, 17, 2, 11, 2, 17, - 6, 2, 1, 1, 0, 0, 1, 5, 14, 0, 7, 0, 17, 22, 56, 7, 2, 0, - 0, 0, 1, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_MAPS_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 10, 1, 0, 8, 2, 8, 36, 3, 44, 90, - 4, 134, 1, 18, 5, 152, 1, 172, 1, 7, 196, 2, 142, 2, 8, 210, 4, 64, - 16, 146, 5, 31, 10, 177, 5, 27, 12, 204, 5, 186, 7, 0, 0, 1, 4, 1, - 7, 1, 10, 0, 1, 8, 0, 1, 3, 4, 2, 4, 0, 4, 0, 0, 5, 8, - 0, 2, 6, 7, 2, 0, 0, 0, 0, 0, 8, 8, 0, 3, 9, 7, 2, 0, - 0, 0, 0, 0, 11, 0, 1, 0, 1, 1, 12, 3, 4, 2, 4, 4, 1, 1, - 13, 5, 1, 2, 7, 4, 1, 1, 14, 6, 7, 2, 7, 4, 1, 0, 15, 9, - 1, 0, 1, 2, 16, 1, 10, 2, 0, 0, 1, 2, 13, 11, 1, 2, 0, 0, - 1, 2, 14, 12, 7, 2, 2, 0, 1, 0, 17, 9, 1, 0, 1, 3, 16, 1, - 14, 2, 4, 4, 1, 3, 13, 15, 1, 2, 4, 4, 1, 3, 14, 16, 17, 2, - 4, 4, 1, 1, 2, 2, 2, 3, 2, 5, 2, 6, 2, 7, 2, 9, 2, 10, - 2, 11, 2, 5, 6, 12, 3, 3, 13, 13, 0, 2, 3, 3, 3, 13, 13, 1, - 1, 11, 1, 2, 9, 0, 9, 1, 3, 7, 11, 1, 2, 9, 0, 9, 1, 9, - 0, 9, 1, 2, 7, 11, 1, 2, 9, 0, 9, 1, 6, 9, 0, 1, 9, 1, - 10, 11, 1, 2, 3, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 3, 6, 12, - 3, 3, 1, 11, 3, 2, 9, 0, 9, 1, 3, 7, 11, 3, 2, 9, 0, 9, - 1, 9, 0, 9, 1, 2, 7, 11, 3, 2, 9, 0, 9, 1, 6, 9, 0, 10, - 11, 3, 2, 3, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 1, 11, 5, 2, - 9, 0, 9, 1, 3, 7, 11, 5, 2, 9, 0, 9, 1, 9, 0, 9, 1, 2, - 7, 11, 5, 2, 9, 0, 9, 1, 6, 9, 0, 2, 9, 0, 9, 1, 10, 11, - 5, 2, 3, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 12, 109, 97, 112, 115, - 95, 101, 120, 97, 109, 112, 108, 101, 21, 66, 105, 103, 79, 114, 100, 101, 114, 101, - 100, 77, 97, 112, 82, 101, 115, 111, 117, 114, 99, 101, 5, 118, 97, 108, 117, 101, - 13, 66, 105, 103, 79, 114, 100, 101, 114, 101, 100, 77, 97, 112, 15, 98, 105, 103, - 95, 111, 114, 100, 101, 114, 101, 100, 95, 109, 97, 112, 18, 79, 114, 100, 101, 114, - 101, 100, 77, 97, 112, 82, 101, 115, 111, 117, 114, 99, 101, 10, 79, 114, 100, 101, - 114, 101, 100, 77, 97, 112, 11, 111, 114, 100, 101, 114, 101, 100, 95, 109, 97, 112, - 17, 83, 105, 109, 112, 108, 101, 77, 97, 112, 82, 101, 115, 111, 117, 114, 99, 101, - 9, 83, 105, 109, 112, 108, 101, 77, 97, 112, 10, 115, 105, 109, 112, 108, 101, 95, - 109, 97, 112, 31, 116, 101, 115, 116, 95, 97, 100, 100, 95, 114, 101, 109, 111, 118, - 101, 95, 98, 105, 103, 95, 111, 114, 100, 101, 114, 101, 100, 95, 109, 97, 112, 15, - 110, 101, 119, 95, 119, 105, 116, 104, 95, 99, 111, 110, 102, 105, 103, 3, 97, 100, - 100, 6, 114, 101, 109, 111, 118, 101, 27, 116, 101, 115, 116, 95, 97, 100, 100, 95, - 114, 101, 109, 111, 118, 101, 95, 111, 114, 100, 101, 114, 101, 100, 95, 109, 97, 112, - 3, 110, 101, 119, 26, 116, 101, 115, 116, 95, 97, 100, 100, 95, 114, 101, 109, 111, - 118, 101, 95, 115, 105, 109, 112, 108, 101, 95, 109, 97, 112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, - 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, - 0, 2, 1, 2, 11, 1, 2, 3, 3, 2, 2, 1, 2, 11, 3, 2, 3, 3, - 4, 2, 1, 2, 11, 5, 2, 3, 3, 0, 1, 4, 0, 8, 115, 11, 3, 11, - 4, 9, 56, 0, 12, 5, 6, 210, 4, 0, 0, 0, 0, 0, 0, 12, 6, 6, - 210, 4, 0, 0, 0, 0, 0, 0, 12, 7, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 8, 9, 12, 9, 5, 15, 5, 46, 10, 9, 4, 112, 11, 8, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 12, 8, 10, 8, 10, 1, 35, 3, 26, 5, - 46, 10, 6, 12, 10, 13, 5, 10, 10, 11, 10, 56, 1, 11, 6, 6, 177, 30, - 4, 0, 0, 0, 0, 0, 22, 12, 6, 10, 6, 6, 64, 66, 15, 0, 0, 0, - 0, 0, 36, 3, 41, 5, 13, 11, 6, 6, 64, 66, 15, 0, 0, 0, 0, 0, - 23, 12, 6, 5, 13, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 9, 12, - 11, 11, 2, 12, 12, 5, 54, 5, 104, 10, 11, 4, 109, 11, 10, 6, 1, 0, - 0, 0, 0, 0, 0, 0, 22, 12, 10, 10, 10, 10, 12, 35, 3, 65, 5, 104, - 10, 6, 12, 13, 13, 5, 10, 13, 11, 13, 56, 1, 10, 7, 12, 14, 13, 5, - 14, 14, 56, 2, 1, 11, 6, 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, - 6, 10, 6, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 86, 5, 90, 11, - 6, 6, 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 6, 11, 7, 6, 177, 30, - 4, 0, 0, 0, 0, 0, 22, 12, 7, 10, 7, 6, 64, 66, 15, 0, 0, 0, - 0, 0, 36, 3, 99, 5, 52, 11, 7, 6, 64, 66, 15, 0, 0, 0, 0, 0, - 23, 12, 7, 5, 52, 11, 0, 11, 5, 18, 0, 45, 0, 2, 8, 12, 11, 5, - 60, 8, 12, 9, 5, 21, 4, 1, 4, 0, 13, 112, 56, 3, 12, 3, 6, 210, - 4, 0, 0, 0, 0, 0, 0, 12, 4, 6, 210, 4, 0, 0, 0, 0, 0, 0, - 12, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 9, 12, 7, 5, 12, - 5, 43, 10, 7, 4, 109, 11, 6, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, - 12, 6, 10, 6, 10, 1, 35, 3, 23, 5, 43, 10, 4, 12, 8, 13, 3, 10, - 8, 11, 8, 56, 4, 11, 4, 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, - 4, 10, 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 38, 5, 10, 11, - 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 4, 5, 10, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 8, 9, 12, 9, 11, 2, 12, 10, 5, 51, 5, - 101, 10, 9, 4, 106, 11, 8, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, - 8, 10, 8, 10, 10, 35, 3, 62, 5, 101, 10, 4, 12, 11, 13, 3, 10, 11, - 11, 11, 56, 4, 10, 5, 12, 12, 13, 3, 14, 12, 56, 5, 1, 11, 4, 6, - 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, 4, 10, 4, 6, 64, 66, 15, 0, - 0, 0, 0, 0, 36, 3, 83, 5, 87, 11, 4, 6, 64, 66, 15, 0, 0, 0, - 0, 0, 23, 12, 4, 11, 5, 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, - 5, 10, 5, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 96, 5, 49, 11, - 5, 6, 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 5, 5, 49, 11, 0, 11, - 3, 18, 1, 45, 1, 2, 8, 12, 9, 5, 57, 8, 12, 7, 5, 18, 8, 1, - 4, 0, 18, 113, 56, 6, 12, 3, 6, 210, 4, 0, 0, 0, 0, 0, 0, 12, - 4, 6, 210, 4, 0, 0, 0, 0, 0, 0, 12, 5, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 6, 9, 12, 7, 5, 12, 5, 43, 10, 7, 4, 110, 11, 6, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 6, 10, 6, 10, 1, 35, 3, - 23, 5, 43, 10, 4, 12, 8, 13, 3, 10, 8, 11, 8, 56, 7, 11, 4, 6, - 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, 4, 10, 4, 6, 64, 66, 15, 0, - 0, 0, 0, 0, 36, 3, 38, 5, 10, 11, 4, 6, 64, 66, 15, 0, 0, 0, - 0, 0, 23, 12, 4, 5, 10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 8, - 9, 12, 9, 11, 2, 12, 10, 5, 51, 5, 102, 10, 9, 4, 107, 11, 8, 6, - 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 8, 10, 8, 10, 10, 35, 3, 62, - 5, 102, 10, 4, 12, 11, 13, 3, 10, 11, 11, 11, 56, 7, 10, 5, 12, 12, - 13, 3, 14, 12, 56, 8, 1, 1, 11, 4, 6, 177, 30, 4, 0, 0, 0, 0, - 0, 22, 12, 4, 10, 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 84, - 5, 88, 11, 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 4, 11, 5, - 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, 5, 10, 5, 6, 64, 66, 15, - 0, 0, 0, 0, 0, 36, 3, 97, 5, 49, 11, 5, 6, 64, 66, 15, 0, 0, - 0, 0, 0, 23, 12, 5, 5, 49, 11, 0, 11, 3, 18, 2, 45, 2, 2, 8, - 12, 9, 5, 57, 8, 12, 7, 5, 18, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_OBJECTS: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 11, 1, 0, 8, 2, 8, 12, 3, 20, 42, - 5, 62, 42, 7, 104, 186, 1, 8, 162, 2, 64, 6, 226, 2, 34, 16, 132, 3, - 161, 1, 10, 165, 4, 11, 12, 176, 4, 251, 1, 13, 171, 6, 2, 0, 0, 1, - 6, 1, 9, 1, 14, 0, 1, 8, 0, 0, 3, 8, 0, 2, 11, 2, 0, 0, - 5, 0, 1, 0, 1, 1, 7, 0, 2, 0, 1, 0, 8, 3, 1, 0, 1, 2, - 10, 2, 5, 0, 1, 2, 12, 6, 7, 0, 1, 0, 13, 9, 1, 0, 1, 3, - 15, 10, 10, 0, 1, 1, 6, 12, 0, 1, 5, 3, 6, 12, 3, 3, 1, 2, - 1, 8, 2, 1, 6, 8, 2, 1, 12, 5, 5, 10, 2, 3, 8, 2, 12, 4, - 6, 12, 3, 3, 5, 1, 3, 1, 7, 8, 0, 7, 111, 98, 106, 101, 99, 116, - 115, 7, 67, 111, 117, 110, 116, 101, 114, 5, 99, 111, 117, 110, 116, 14, 65, 100, - 100, 105, 116, 105, 111, 110, 97, 108, 68, 97, 116, 97, 4, 100, 97, 116, 97, 11, - 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 6, 115, 105, 103, 110, 101, 114, - 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 14, 99, 114, 101, 97, 116, 101, - 95, 111, 98, 106, 101, 99, 116, 115, 6, 111, 98, 106, 101, 99, 116, 13, 99, 114, - 101, 97, 116, 101, 95, 111, 98, 106, 101, 99, 116, 14, 67, 111, 110, 115, 116, 114, - 117, 99, 116, 111, 114, 82, 101, 102, 15, 103, 101, 110, 101, 114, 97, 116, 101, 95, - 115, 105, 103, 110, 101, 114, 23, 99, 114, 101, 97, 116, 101, 95, 111, 98, 106, 101, - 99, 116, 115, 95, 99, 111, 110, 102, 108, 105, 99, 116, 5, 101, 114, 114, 111, 114, - 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, 109, 101, 110, 116, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 171, 205, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, - 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, - 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, 116, 97, 100, 97, 116, 97, - 95, 118, 49, 110, 2, 1, 0, 0, 0, 0, 0, 0, 0, 29, 69, 67, 79, 85, - 78, 84, 69, 82, 95, 82, 69, 83, 79, 85, 82, 67, 69, 95, 78, 79, 84, 95, - 80, 82, 69, 83, 69, 78, 84, 0, 2, 0, 0, 0, 0, 0, 0, 0, 15, 69, - 78, 79, 84, 95, 65, 85, 84, 72, 79, 82, 73, 90, 69, 68, 0, 1, 14, 65, - 100, 100, 105, 116, 105, 111, 110, 97, 108, 68, 97, 116, 97, 1, 3, 1, 24, 48, - 120, 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, 106, 101, 99, 116, - 71, 114, 111, 117, 112, 0, 0, 2, 1, 2, 3, 1, 2, 1, 4, 10, 2, 0, - 0, 0, 0, 1, 14, 10, 0, 17, 1, 7, 0, 33, 4, 10, 11, 0, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 18, 0, 45, 0, 2, 11, 0, 1, 6, 2, 0, - 0, 0, 0, 0, 0, 0, 39, 2, 1, 4, 0, 8, 48, 11, 0, 17, 1, 12, - 3, 64, 4, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 12, 5, 10, 5, 10, 2, 35, 3, 12, 5, 23, 13, 4, 10, - 5, 6, 100, 0, 0, 0, 0, 0, 0, 0, 25, 51, 68, 4, 11, 5, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 12, 5, 5, 7, 10, 1, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 36, 4, 47, 10, 3, 17, 3, 12, 6, 10, 2, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 3, 35, 5, 42, 14, 6, 17, 4, 12, 7, - 14, 7, 10, 4, 18, 1, 45, 1, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, - 0, 23, 12, 1, 5, 23, 2, 5, 1, 4, 1, 0, 11, 24, 10, 3, 41, 0, - 4, 19, 11, 3, 42, 0, 12, 4, 10, 4, 16, 0, 20, 6, 1, 0, 0, 0, - 0, 0, 0, 0, 22, 11, 4, 15, 0, 21, 11, 0, 11, 1, 11, 2, 17, 2, - 2, 11, 0, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 0, 0, - 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_PERMISSIONED_TRANSFER: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 8, 1, 0, 8, 2, 8, 4, 3, 12, 42, - 5, 54, 28, 7, 82, 237, 1, 8, 191, 2, 64, 16, 255, 2, 31, 12, 158, 3, - 54, 0, 0, 1, 2, 1, 4, 1, 8, 2, 6, 0, 0, 0, 1, 0, 1, 0, - 1, 1, 1, 0, 1, 0, 1, 0, 3, 0, 1, 0, 1, 2, 5, 2, 3, 0, - 1, 2, 7, 4, 5, 0, 1, 3, 9, 6, 1, 0, 1, 2, 10, 3, 1, 0, - 1, 3, 6, 12, 5, 3, 0, 1, 6, 12, 1, 8, 0, 1, 6, 8, 0, 1, - 12, 3, 6, 12, 6, 12, 3, 2, 8, 0, 12, 21, 112, 101, 114, 109, 105, 115, - 115, 105, 111, 110, 101, 100, 95, 116, 114, 97, 110, 115, 102, 101, 114, 8, 116, 114, - 97, 110, 115, 102, 101, 114, 13, 97, 112, 116, 111, 115, 95, 97, 99, 99, 111, 117, - 110, 116, 21, 116, 114, 97, 110, 115, 102, 101, 114, 95, 112, 101, 114, 109, 105, 115, - 115, 105, 111, 110, 101, 100, 19, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 101, - 100, 95, 115, 105, 103, 110, 101, 114, 26, 99, 114, 101, 97, 116, 101, 95, 112, 101, - 114, 109, 105, 115, 115, 105, 111, 110, 101, 100, 95, 104, 97, 110, 100, 108, 101, 18, - 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 101, 100, 72, 97, 110, 100, 108, 101, - 31, 115, 105, 103, 110, 101, 114, 95, 102, 114, 111, 109, 95, 112, 101, 114, 109, 105, - 115, 115, 105, 111, 110, 101, 100, 95, 104, 97, 110, 100, 108, 101, 22, 112, 114, 105, - 109, 97, 114, 121, 95, 102, 117, 110, 103, 105, 98, 108, 101, 95, 115, 116, 111, 114, - 101, 20, 103, 114, 97, 110, 116, 95, 97, 112, 116, 95, 112, 101, 114, 109, 105, 115, - 115, 105, 111, 110, 27, 100, 101, 115, 116, 114, 111, 121, 95, 112, 101, 114, 109, 105, - 115, 115, 105, 111, 110, 101, 100, 95, 104, 97, 110, 100, 108, 101, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, - 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, - 49, 0, 1, 4, 0, 1, 5, 11, 0, 11, 1, 11, 2, 17, 1, 2, 2, 1, - 4, 0, 7, 17, 10, 0, 17, 3, 12, 3, 14, 3, 17, 4, 12, 4, 11, 0, - 14, 4, 10, 2, 17, 5, 14, 4, 11, 1, 11, 2, 17, 1, 11, 3, 17, 6, - 2, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_RESOURCE_GROUPS_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 11, 1, 0, 8, 2, 8, 40, 3, 48, 60, - 5, 108, 95, 7, 203, 1, 199, 2, 8, 146, 4, 64, 6, 210, 4, 13, 16, 223, - 4, 146, 5, 10, 241, 9, 69, 12, 182, 10, 237, 10, 13, 163, 21, 32, 0, 0, - 1, 7, 1, 16, 1, 18, 0, 1, 0, 0, 0, 3, 8, 0, 1, 6, 7, 0, - 0, 8, 8, 0, 0, 9, 8, 0, 0, 10, 8, 0, 0, 11, 8, 0, 0, 12, - 8, 0, 0, 13, 8, 0, 0, 14, 8, 0, 0, 15, 0, 1, 0, 1, 2, 17, - 2, 3, 0, 1, 3, 19, 4, 4, 0, 1, 0, 20, 6, 1, 0, 1, 3, 21, - 4, 4, 0, 1, 1, 22, 7, 8, 0, 1, 0, 23, 10, 1, 0, 1, 0, 24, - 11, 1, 0, 1, 0, 25, 12, 1, 0, 1, 0, 26, 13, 1, 0, 1, 3, 6, - 12, 3, 8, 2, 0, 1, 6, 12, 1, 5, 1, 3, 10, 5, 7, 8, 2, 8, - 1, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8, 9, 2, 6, 12, - 3, 1, 10, 2, 1, 8, 2, 9, 5, 8, 1, 8, 3, 8, 4, 8, 5, 8, - 6, 8, 7, 8, 8, 8, 9, 5, 6, 12, 3, 3, 3, 8, 2, 4, 6, 12, - 3, 3, 8, 2, 5, 6, 12, 6, 12, 3, 3, 8, 2, 4, 6, 12, 6, 12, - 3, 8, 2, 23, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, 117, 112, - 115, 95, 101, 120, 97, 109, 112, 108, 101, 12, 69, 120, 97, 109, 112, 108, 101, 71, - 114, 111, 117, 112, 11, 100, 117, 109, 109, 121, 95, 102, 105, 101, 108, 100, 16, 69, - 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 48, 5, 118, 97, - 108, 117, 101, 4, 110, 97, 109, 101, 6, 83, 116, 114, 105, 110, 103, 6, 115, 116, - 114, 105, 110, 103, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, - 99, 101, 49, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, - 101, 50, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, - 51, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 52, - 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 53, 16, - 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 54, 16, 69, - 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 55, 3, 115, 101, - 116, 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, - 102, 5, 101, 114, 114, 111, 114, 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, 114, - 103, 117, 109, 101, 110, 116, 12, 114, 101, 97, 100, 95, 111, 114, 95, 105, 110, 105, - 116, 13, 105, 110, 118, 97, 108, 105, 100, 95, 115, 116, 97, 116, 101, 4, 117, 116, - 102, 56, 5, 115, 101, 116, 95, 51, 12, 115, 101, 116, 95, 97, 110, 100, 95, 114, - 101, 97, 100, 14, 115, 101, 116, 95, 97, 110, 100, 95, 114, 101, 97, 100, 95, 112, - 5, 115, 101, 116, 95, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 2, - 10, 9, 105, 110, 105, 116, 95, 110, 97, 109, 101, 20, 99, 111, 109, 112, 105, 108, - 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, - 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, 116, 97, - 100, 97, 116, 97, 95, 118, 49, 222, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, - 16, 69, 73, 78, 68, 69, 88, 95, 84, 79, 79, 95, 76, 65, 82, 71, 69, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 16, 69, 86, 65, 76, 85, 69, 95, 84, 79, - 79, 95, 76, 65, 82, 71, 69, 0, 9, 12, 69, 120, 97, 109, 112, 108, 101, 71, - 114, 111, 117, 112, 1, 2, 1, 6, 103, 108, 111, 98, 97, 108, 16, 69, 120, 97, - 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 48, 1, 3, 1, 45, 48, - 120, 97, 98, 99, 100, 58, 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, - 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, - 112, 108, 101, 71, 114, 111, 117, 112, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, - 115, 111, 117, 114, 99, 101, 49, 1, 3, 1, 45, 48, 120, 97, 98, 99, 100, 58, - 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, - 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, 112, 108, 101, 71, 114, 111, - 117, 112, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, - 50, 1, 3, 1, 45, 48, 120, 97, 98, 99, 100, 58, 58, 114, 101, 115, 111, 117, - 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, - 58, 58, 69, 120, 97, 109, 112, 108, 101, 71, 114, 111, 117, 112, 16, 69, 120, 97, - 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 51, 1, 3, 1, 45, 48, - 120, 97, 98, 99, 100, 58, 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, - 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, - 112, 108, 101, 71, 114, 111, 117, 112, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, - 115, 111, 117, 114, 99, 101, 52, 1, 3, 1, 45, 48, 120, 97, 98, 99, 100, 58, - 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, - 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, 112, 108, 101, 71, 114, 111, - 117, 112, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, - 53, 1, 3, 1, 45, 48, 120, 97, 98, 99, 100, 58, 58, 114, 101, 115, 111, 117, - 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, - 58, 58, 69, 120, 97, 109, 112, 108, 101, 71, 114, 111, 117, 112, 16, 69, 120, 97, - 109, 112, 108, 101, 82, 101, 115, 111, 117, 114, 99, 101, 54, 1, 3, 1, 45, 48, - 120, 97, 98, 99, 100, 58, 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, - 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, - 112, 108, 101, 71, 114, 111, 117, 112, 16, 69, 120, 97, 109, 112, 108, 101, 82, 101, - 115, 111, 117, 114, 99, 101, 55, 1, 3, 1, 45, 48, 120, 97, 98, 99, 100, 58, - 58, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, - 120, 97, 109, 112, 108, 101, 58, 58, 69, 120, 97, 109, 112, 108, 101, 71, 114, 111, - 117, 112, 0, 0, 2, 1, 2, 1, 1, 2, 2, 4, 3, 5, 8, 2, 3, 2, - 2, 4, 3, 5, 8, 2, 4, 2, 2, 4, 3, 5, 8, 2, 5, 2, 2, 4, - 3, 5, 8, 2, 6, 2, 2, 4, 3, 5, 8, 2, 7, 2, 2, 4, 3, 5, - 8, 2, 8, 2, 2, 4, 3, 5, 8, 2, 9, 2, 2, 4, 3, 5, 8, 2, - 0, 1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8, 5, 215, 1, 10, 0, 17, - 1, 12, 3, 10, 1, 6, 8, 0, 0, 0, 0, 0, 0, 0, 35, 4, 210, 1, - 10, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 33, 4, 32, 10, 3, 41, 1, - 4, 24, 11, 0, 1, 11, 3, 42, 1, 15, 0, 12, 4, 11, 2, 11, 4, 21, - 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 18, 1, 12, 5, 11, 0, - 11, 5, 45, 1, 5, 23, 10, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 33, - 4, 57, 10, 3, 41, 2, 4, 49, 11, 0, 1, 11, 3, 42, 2, 15, 1, 12, - 4, 11, 2, 11, 4, 21, 5, 23, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, - 2, 18, 2, 12, 6, 11, 0, 11, 6, 45, 2, 5, 23, 10, 1, 6, 2, 0, - 0, 0, 0, 0, 0, 0, 33, 4, 82, 10, 3, 41, 3, 4, 74, 11, 0, 1, - 11, 3, 42, 3, 15, 2, 12, 4, 11, 2, 11, 4, 21, 5, 23, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 2, 18, 3, 12, 7, 11, 0, 11, 7, 45, 3, - 5, 23, 10, 1, 6, 3, 0, 0, 0, 0, 0, 0, 0, 33, 4, 107, 10, 3, - 41, 4, 4, 99, 11, 0, 1, 11, 3, 42, 4, 15, 3, 12, 4, 11, 2, 11, - 4, 21, 5, 23, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 18, 4, 12, - 8, 11, 0, 11, 8, 45, 4, 5, 23, 10, 1, 6, 4, 0, 0, 0, 0, 0, - 0, 0, 33, 4, 132, 1, 10, 3, 41, 5, 4, 124, 11, 0, 1, 11, 3, 42, - 5, 15, 4, 12, 4, 11, 2, 11, 4, 21, 5, 23, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 11, 2, 18, 5, 12, 9, 11, 0, 11, 9, 45, 5, 5, 23, 10, - 1, 6, 5, 0, 0, 0, 0, 0, 0, 0, 33, 4, 157, 1, 10, 3, 41, 6, - 4, 149, 1, 11, 0, 1, 11, 3, 42, 6, 15, 5, 12, 4, 11, 2, 11, 4, - 21, 5, 23, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 18, 6, 12, 10, - 11, 0, 11, 10, 45, 6, 5, 23, 10, 1, 6, 6, 0, 0, 0, 0, 0, 0, - 0, 33, 4, 182, 1, 10, 3, 41, 7, 4, 174, 1, 11, 0, 1, 11, 3, 42, - 7, 15, 6, 12, 4, 11, 2, 11, 4, 21, 5, 23, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 11, 2, 18, 7, 12, 11, 11, 0, 11, 11, 45, 7, 5, 23, 11, - 1, 6, 7, 0, 0, 0, 0, 0, 0, 0, 33, 4, 207, 1, 10, 3, 41, 8, - 4, 199, 1, 11, 0, 1, 11, 3, 42, 8, 15, 7, 12, 4, 11, 2, 11, 4, - 21, 5, 23, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 18, 8, 12, 12, - 11, 0, 11, 12, 45, 8, 5, 23, 11, 0, 1, 5, 23, 11, 0, 1, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 17, 2, 39, 3, 1, 4, 8, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 248, 1, 10, 0, 17, 1, 12, 2, 10, 1, 6, 8, 0, - 0, 0, 0, 0, 0, 0, 35, 4, 243, 1, 10, 1, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 4, 37, 10, 2, 41, 1, 4, 28, 11, 0, 1, 11, 2, 42, - 1, 16, 8, 20, 6, 0, 16, 165, 212, 232, 0, 0, 0, 35, 4, 25, 5, 24, - 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 17, 5, 18, 1, 12, 3, 11, 0, 11, 3, 45, 1, - 5, 24, 10, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 33, 4, 66, 10, 2, - 41, 2, 4, 57, 11, 0, 1, 11, 2, 42, 2, 16, 9, 20, 6, 0, 16, 165, - 212, 232, 0, 0, 0, 35, 4, 54, 5, 24, 6, 2, 0, 0, 0, 0, 0, 0, - 0, 17, 4, 39, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 17, 5, 18, - 2, 12, 4, 11, 0, 11, 4, 45, 2, 5, 24, 10, 1, 6, 2, 0, 0, 0, - 0, 0, 0, 0, 33, 4, 95, 10, 2, 41, 3, 4, 86, 11, 0, 1, 11, 2, - 42, 3, 16, 10, 20, 6, 0, 16, 165, 212, 232, 0, 0, 0, 35, 4, 83, 5, - 24, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 17, 5, 18, 3, 12, 5, 11, 0, 11, 5, 45, 3, - 5, 24, 10, 1, 6, 3, 0, 0, 0, 0, 0, 0, 0, 33, 4, 124, 10, 2, - 41, 4, 4, 115, 11, 0, 1, 11, 2, 42, 4, 16, 11, 20, 6, 0, 16, 165, - 212, 232, 0, 0, 0, 35, 4, 112, 5, 24, 6, 2, 0, 0, 0, 0, 0, 0, - 0, 17, 4, 39, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 17, 5, 18, - 4, 12, 6, 11, 0, 11, 6, 45, 4, 5, 24, 10, 1, 6, 4, 0, 0, 0, - 0, 0, 0, 0, 33, 4, 153, 1, 10, 2, 41, 5, 4, 144, 1, 11, 0, 1, - 11, 2, 42, 5, 16, 12, 20, 6, 0, 16, 165, 212, 232, 0, 0, 0, 35, 4, - 141, 1, 5, 24, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 7, 0, 17, 5, 18, 5, 12, 7, 11, 0, 11, - 7, 45, 5, 5, 24, 10, 1, 6, 5, 0, 0, 0, 0, 0, 0, 0, 33, 4, - 182, 1, 10, 2, 41, 6, 4, 173, 1, 11, 0, 1, 11, 2, 42, 6, 16, 13, - 20, 6, 0, 16, 165, 212, 232, 0, 0, 0, 35, 4, 170, 1, 5, 24, 6, 2, - 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 0, 17, 5, 18, 6, 12, 8, 11, 0, 11, 8, 45, 6, 5, 24, 10, - 1, 6, 6, 0, 0, 0, 0, 0, 0, 0, 33, 4, 211, 1, 10, 2, 41, 7, - 4, 202, 1, 11, 0, 1, 11, 2, 42, 7, 16, 14, 20, 6, 0, 16, 165, 212, - 232, 0, 0, 0, 35, 4, 199, 1, 5, 24, 6, 2, 0, 0, 0, 0, 0, 0, - 0, 17, 4, 39, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 17, 5, 18, - 7, 12, 9, 11, 0, 11, 9, 45, 7, 5, 24, 11, 1, 6, 7, 0, 0, 0, - 0, 0, 0, 0, 33, 4, 240, 1, 10, 2, 41, 8, 4, 231, 1, 11, 0, 1, - 11, 2, 42, 8, 16, 15, 20, 6, 0, 16, 165, 212, 232, 0, 0, 0, 35, 4, - 228, 1, 5, 24, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 7, 0, 17, 5, 18, 8, 12, 10, 11, 0, 11, - 10, 45, 8, 5, 24, 11, 0, 1, 5, 24, 11, 0, 1, 6, 1, 0, 0, 0, - 0, 0, 0, 0, 17, 2, 39, 6, 1, 4, 8, 1, 2, 3, 4, 5, 6, 7, - 8, 1, 13, 10, 0, 11, 1, 10, 4, 17, 0, 10, 0, 11, 2, 10, 4, 17, - 0, 11, 0, 11, 3, 11, 4, 17, 0, 2, 7, 1, 4, 8, 1, 2, 3, 4, - 5, 6, 7, 8, 1, 8, 10, 0, 11, 1, 11, 3, 17, 0, 11, 0, 11, 2, - 17, 3, 2, 8, 1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 8, 11, - 1, 11, 0, 1, 11, 2, 11, 3, 11, 4, 17, 7, 2, 9, 1, 4, 8, 1, - 2, 3, 4, 5, 6, 7, 8, 1, 7, 11, 1, 11, 0, 1, 11, 2, 11, 3, - 17, 0, 2, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, - 1, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_TOKEN_V1: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 16, 2, 16, 42, 3, 58, 199, - 1, 4, 129, 2, 12, 5, 141, 2, 155, 2, 7, 168, 4, 185, 6, 8, 225, 10, - 96, 6, 193, 11, 125, 16, 190, 12, 31, 10, 221, 12, 19, 12, 240, 12, 219, 5, - 13, 203, 18, 6, 0, 0, 1, 4, 1, 7, 1, 9, 2, 11, 1, 18, 1, 20, - 1, 25, 0, 1, 8, 0, 1, 3, 6, 0, 2, 6, 4, 2, 3, 1, 0, 1, - 3, 8, 7, 1, 0, 0, 4, 10, 4, 0, 4, 13, 7, 0, 5, 17, 7, 0, - 4, 24, 7, 0, 4, 38, 7, 0, 0, 14, 0, 1, 0, 1, 1, 15, 3, 1, - 0, 1, 0, 16, 4, 5, 0, 1, 5, 19, 6, 2, 0, 1, 6, 21, 8, 5, - 1, 0, 1, 5, 22, 9, 2, 0, 1, 0, 23, 10, 11, 0, 1, 7, 26, 12, - 0, 0, 1, 1, 27, 0, 7, 0, 1, 5, 28, 13, 5, 0, 1, 0, 29, 14, - 15, 0, 1, 4, 30, 16, 17, 0, 1, 0, 31, 0, 11, 0, 1, 4, 32, 19, - 20, 0, 1, 3, 33, 21, 22, 1, 0, 1, 0, 34, 24, 2, 0, 1, 3, 35, - 22, 26, 1, 0, 1, 2, 36, 28, 2, 2, 3, 0, 1, 4, 37, 29, 30, 0, - 1, 4, 39, 31, 15, 0, 1, 0, 40, 12, 2, 0, 1, 1, 41, 34, 35, 0, - 1, 4, 42, 36, 2, 0, 1, 2, 43, 2, 37, 2, 3, 4, 1, 0, 44, 10, - 2, 0, 1, 4, 45, 39, 25, 0, 1, 0, 46, 10, 2, 0, 1, 0, 47, 10, - 2, 0, 1, 0, 48, 10, 2, 0, 1, 4, 49, 42, 2, 0, 1, 0, 50, 10, - 2, 0, 1, 0, 51, 10, 2, 0, 1, 4, 7, 4, 0, 14, 7, 16, 25, 17, - 27, 23, 27, 1, 5, 1, 12, 0, 1, 6, 8, 1, 2, 8, 6, 3, 1, 8, - 6, 2, 7, 8, 6, 10, 2, 1, 3, 1, 6, 9, 0, 2, 7, 8, 6, 8, - 6, 2, 6, 12, 5, 2, 12, 8, 7, 1, 6, 12, 1, 10, 2, 4, 6, 12, - 8, 6, 8, 6, 3, 1, 8, 5, 3, 6, 12, 8, 5, 3, 1, 8, 7, 6, - 12, 5, 8, 6, 8, 5, 8, 7, 12, 2, 5, 8, 6, 1, 11, 3, 1, 3, - 1, 7, 11, 3, 1, 9, 0, 1, 9, 0, 7, 12, 11, 3, 1, 3, 3, 8, - 6, 8, 5, 8, 7, 12, 3, 5, 5, 8, 4, 1, 8, 4, 1, 11, 3, 1, - 9, 0, 2, 5, 11, 3, 1, 8, 4, 3, 7, 11, 2, 2, 9, 0, 9, 1, - 9, 0, 9, 1, 1, 6, 10, 1, 1, 8, 8, 13, 6, 12, 8, 6, 8, 6, - 8, 6, 3, 8, 6, 5, 3, 3, 8, 8, 10, 8, 6, 10, 10, 2, 10, 8, - 6, 8, 8, 6, 8, 6, 5, 10, 1, 8, 8, 10, 8, 6, 10, 10, 2, 10, - 8, 6, 1, 2, 2, 6, 12, 10, 2, 2, 12, 8, 1, 6, 6, 12, 8, 6, - 8, 6, 8, 6, 3, 10, 1, 1, 11, 2, 2, 9, 0, 9, 1, 6, 8, 1, - 12, 8, 6, 8, 6, 8, 6, 8, 5, 3, 6, 12, 8, 7, 3, 6, 12, 6, - 12, 8, 5, 8, 7, 3, 8, 4, 3, 8, 7, 12, 8, 4, 4, 6, 12, 6, - 12, 8, 7, 3, 4, 12, 6, 12, 8, 5, 8, 7, 2, 8, 7, 12, 8, 116, - 111, 107, 101, 110, 95, 118, 49, 12, 77, 105, 110, 116, 101, 114, 67, 111, 110, 102, - 105, 103, 10, 115, 105, 103, 110, 101, 114, 95, 99, 97, 112, 16, 83, 105, 103, 110, - 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 121, 7, 97, 99, 99, 111, 117, - 110, 116, 13, 109, 105, 110, 116, 101, 100, 95, 116, 111, 107, 101, 110, 115, 5, 84, - 97, 98, 108, 101, 5, 116, 97, 98, 108, 101, 6, 79, 112, 116, 105, 111, 110, 6, - 111, 112, 116, 105, 111, 110, 5, 84, 111, 107, 101, 110, 5, 116, 111, 107, 101, 110, - 12, 116, 111, 107, 101, 110, 100, 97, 116, 97, 95, 105, 100, 11, 84, 111, 107, 101, - 110, 68, 97, 116, 97, 73, 100, 10, 103, 101, 116, 95, 115, 105, 103, 110, 101, 114, - 29, 99, 114, 101, 97, 116, 101, 95, 115, 105, 103, 110, 101, 114, 95, 119, 105, 116, - 104, 95, 99, 97, 112, 97, 98, 105, 108, 105, 116, 121, 16, 98, 117, 105, 108, 100, - 95, 116, 111, 107, 101, 110, 95, 110, 97, 109, 101, 6, 83, 116, 114, 105, 110, 103, - 6, 115, 116, 114, 105, 110, 103, 11, 97, 112, 112, 101, 110, 100, 95, 117, 116, 102, - 56, 12, 115, 116, 114, 105, 110, 103, 95, 117, 116, 105, 108, 115, 9, 116, 111, 95, - 115, 116, 114, 105, 110, 103, 6, 97, 112, 112, 101, 110, 100, 17, 109, 105, 110, 116, - 95, 110, 102, 116, 95, 112, 97, 114, 97, 108, 108, 101, 108, 7, 84, 111, 107, 101, - 110, 73, 100, 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, - 95, 111, 102, 19, 103, 101, 116, 95, 115, 101, 113, 117, 101, 110, 99, 101, 95, 110, - 117, 109, 98, 101, 114, 4, 117, 116, 102, 56, 26, 116, 111, 107, 101, 110, 95, 118, - 49, 95, 99, 114, 101, 97, 116, 101, 95, 116, 111, 107, 101, 110, 95, 100, 97, 116, - 97, 10, 109, 105, 110, 116, 95, 116, 111, 107, 101, 110, 19, 109, 105, 110, 116, 95, - 110, 102, 116, 95, 115, 101, 113, 117, 101, 110, 116, 105, 97, 108, 21, 103, 101, 116, - 95, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 95, 115, 117, 112, 112, 108, 121, - 7, 101, 120, 116, 114, 97, 99, 116, 16, 115, 101, 116, 95, 116, 111, 107, 101, 110, - 95, 109, 105, 110, 116, 101, 100, 4, 115, 111, 109, 101, 3, 97, 100, 100, 30, 99, - 114, 101, 97, 116, 101, 95, 116, 111, 107, 101, 110, 95, 109, 117, 116, 97, 98, 105, - 108, 105, 116, 121, 95, 99, 111, 110, 102, 105, 103, 21, 84, 111, 107, 101, 110, 77, - 117, 116, 97, 98, 105, 108, 105, 116, 121, 67, 111, 110, 102, 105, 103, 16, 99, 114, - 101, 97, 116, 101, 95, 116, 111, 107, 101, 110, 100, 97, 116, 97, 30, 116, 111, 107, - 101, 110, 95, 118, 49, 95, 105, 110, 105, 116, 105, 97, 108, 105, 122, 101, 95, 99, - 111, 108, 108, 101, 99, 116, 105, 111, 110, 23, 99, 114, 101, 97, 116, 101, 95, 114, - 101, 115, 111, 117, 114, 99, 101, 95, 97, 99, 99, 111, 117, 110, 116, 17, 99, 114, - 101, 97, 116, 101, 95, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 3, 110, 101, - 119, 26, 116, 111, 107, 101, 110, 95, 118, 49, 95, 109, 105, 110, 116, 95, 97, 110, - 100, 95, 115, 116, 111, 114, 101, 95, 102, 116, 14, 119, 105, 116, 104, 100, 114, 97, - 119, 95, 116, 111, 107, 101, 110, 36, 116, 111, 107, 101, 110, 95, 118, 49, 95, 109, - 105, 110, 116, 95, 97, 110, 100, 95, 115, 116, 111, 114, 101, 95, 110, 102, 116, 95, - 112, 97, 114, 97, 108, 108, 101, 108, 38, 116, 111, 107, 101, 110, 95, 118, 49, 95, - 109, 105, 110, 116, 95, 97, 110, 100, 95, 115, 116, 111, 114, 101, 95, 110, 102, 116, - 95, 115, 101, 113, 117, 101, 110, 116, 105, 97, 108, 29, 116, 111, 107, 101, 110, 95, - 118, 49, 95, 109, 105, 110, 116, 95, 97, 110, 100, 95, 116, 114, 97, 110, 115, 102, - 101, 114, 95, 102, 116, 15, 100, 105, 114, 101, 99, 116, 95, 116, 114, 97, 110, 115, - 102, 101, 114, 39, 116, 111, 107, 101, 110, 95, 118, 49, 95, 109, 105, 110, 116, 95, - 97, 110, 100, 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, 110, 102, 116, 95, 112, - 97, 114, 97, 108, 108, 101, 108, 41, 116, 111, 107, 101, 110, 95, 118, 49, 95, 109, - 105, 110, 116, 95, 97, 110, 100, 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, 110, - 102, 116, 95, 115, 101, 113, 117, 101, 110, 116, 105, 97, 108, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 10, 2, 3, 2, 32, 35, 10, 2, 18, 17, 104, 116, 116, 112, 115, 58, 47, - 47, 97, 112, 116, 111, 115, 46, 100, 101, 118, 10, 2, 23, 22, 65, 110, 32, 78, - 70, 84, 32, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 32, 78, 97, 109, 101, - 10, 2, 16, 15, 78, 70, 84, 32, 67, 111, 108, 108, 101, 99, 116, 105, 98, 108, - 101, 10, 2, 1, 0, 10, 1, 6, 5, 1, 1, 1, 1, 1, 10, 2, 30, 29, - 65, 110, 32, 78, 70, 84, 32, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 32, - 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 10, 1, 4, 3, 0, 0, 0, - 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, - 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 0, 2, 3, 2, 8, - 1, 5, 11, 2, 2, 5, 11, 3, 1, 8, 4, 12, 8, 5, 0, 0, 0, 1, - 0, 2, 5, 11, 0, 43, 0, 16, 0, 17, 1, 2, 2, 0, 0, 0, 2, 9, - 13, 0, 7, 0, 17, 3, 13, 0, 14, 1, 56, 0, 17, 5, 11, 0, 2, 6, - 0, 0, 1, 0, 18, 28, 11, 1, 17, 0, 12, 2, 10, 0, 17, 7, 12, 3, - 14, 3, 56, 1, 11, 0, 17, 7, 17, 8, 17, 2, 12, 4, 14, 2, 7, 1, - 17, 9, 11, 4, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 10, 12, 5, 14, - 2, 11, 5, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 11, 12, 6, 11, 2, - 11, 6, 2, 12, 0, 0, 1, 0, 23, 34, 11, 0, 17, 0, 12, 1, 14, 1, - 17, 7, 7, 2, 17, 9, 17, 13, 12, 2, 13, 2, 56, 2, 6, 1, 0, 0, - 0, 0, 0, 0, 0, 22, 12, 3, 7, 3, 17, 9, 11, 3, 17, 2, 12, 4, - 14, 1, 7, 1, 17, 9, 11, 4, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, - 10, 12, 5, 14, 1, 11, 5, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 11, - 12, 6, 11, 1, 11, 6, 2, 15, 0, 0, 1, 0, 2, 8, 11, 1, 42, 0, - 15, 1, 11, 0, 11, 2, 56, 3, 56, 4, 2, 10, 0, 0, 0, 32, 35, 7, - 2, 17, 9, 12, 4, 7, 4, 17, 9, 12, 5, 10, 0, 17, 7, 12, 6, 7, - 5, 12, 7, 14, 7, 17, 18, 12, 8, 64, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 9, 64, 13, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 64, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 12, 11, 11, 0, 11, 4, 11, 2, 11, 5, 11, - 3, 11, 1, 11, 6, 6, 100, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 11, 8, 11, 9, 11, 10, 11, 11, 17, 19, 2, 20, 1, - 4, 0, 38, 36, 10, 0, 64, 33, 0, 0, 0, 0, 0, 0, 0, 0, 17, 21, - 12, 1, 12, 2, 7, 2, 17, 9, 12, 3, 7, 6, 17, 9, 12, 4, 7, 4, - 17, 9, 12, 5, 14, 2, 11, 3, 11, 4, 11, 5, 6, 64, 66, 15, 0, 0, - 0, 0, 0, 7, 7, 17, 22, 14, 2, 7, 1, 17, 9, 7, 3, 17, 9, 6, - 64, 75, 76, 0, 0, 0, 0, 0, 17, 10, 12, 6, 11, 0, 11, 1, 56, 5, - 11, 6, 18, 0, 45, 0, 2, 24, 1, 4, 1, 0, 40, 26, 10, 1, 17, 0, - 12, 2, 14, 2, 12, 3, 10, 1, 43, 0, 16, 2, 20, 12, 4, 10, 3, 11, - 4, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 11, 12, 5, 11, 3, 11, 5, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 25, 12, 7, 11, 0, 17, 7, 11, - 1, 11, 7, 17, 15, 2, 26, 1, 4, 1, 0, 41, 16, 10, 0, 10, 1, 17, - 6, 12, 2, 12, 3, 14, 3, 11, 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, - 17, 25, 12, 4, 11, 0, 17, 7, 11, 1, 11, 4, 17, 15, 2, 27, 1, 4, - 1, 0, 41, 15, 10, 1, 17, 12, 12, 2, 12, 3, 14, 3, 11, 2, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 17, 25, 12, 4, 11, 0, 17, 7, 11, 1, 11, - 4, 17, 15, 2, 28, 1, 4, 1, 0, 43, 21, 10, 1, 17, 0, 12, 2, 14, - 2, 12, 3, 11, 1, 43, 0, 16, 2, 20, 12, 4, 10, 3, 11, 4, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 17, 11, 12, 5, 11, 3, 11, 0, 11, 5, 6, - 1, 0, 0, 0, 0, 0, 0, 0, 17, 29, 2, 30, 1, 4, 1, 0, 44, 11, - 10, 0, 11, 1, 17, 6, 12, 2, 12, 3, 14, 3, 11, 0, 11, 2, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 17, 29, 2, 31, 1, 4, 1, 0, 44, 10, 11, - 1, 17, 12, 12, 2, 12, 3, 14, 3, 11, 0, 11, 2, 6, 1, 0, 0, 0, - 0, 0, 0, 0, 17, 29, 2, 0, 0, 0, 1, 0, 2, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_FRAMEWORK_USECASES_VECTOR_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 8, 1, 0, 4, 3, 4, 59, 4, 63, 10, - 5, 73, 103, 7, 176, 1, 131, 1, 8, 179, 2, 64, 16, 243, 2, 31, 12, 146, - 3, 184, 3, 0, 0, 1, 3, 0, 1, 0, 1, 0, 1, 0, 2, 5, 6, 0, - 1, 1, 4, 7, 6, 1, 0, 1, 0, 5, 9, 6, 0, 1, 1, 6, 10, 11, - 1, 0, 1, 1, 7, 12, 6, 1, 0, 1, 0, 8, 9, 6, 0, 1, 1, 9, - 10, 14, 1, 0, 1, 1, 10, 15, 6, 1, 0, 1, 2, 3, 4, 3, 5, 3, - 7, 3, 8, 3, 2, 3, 3, 1, 10, 10, 3, 1, 3, 1, 10, 3, 9, 10, - 3, 3, 1, 10, 10, 3, 3, 1, 3, 10, 3, 7, 3, 5, 3, 3, 3, 3, - 3, 0, 5, 7, 10, 9, 0, 3, 3, 7, 10, 9, 0, 3, 3, 10, 10, 3, - 10, 10, 3, 1, 4, 3, 3, 3, 3, 2, 7, 10, 9, 0, 3, 1, 9, 0, - 3, 7, 10, 9, 0, 3, 9, 0, 3, 10, 10, 3, 1, 10, 3, 1, 10, 9, - 0, 2, 7, 10, 9, 0, 10, 9, 0, 3, 10, 10, 3, 1, 10, 10, 3, 14, - 118, 101, 99, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 12, 103, 101, 110, - 101, 114, 97, 116, 101, 95, 118, 101, 99, 22, 116, 101, 115, 116, 95, 109, 105, 100, - 100, 108, 101, 95, 109, 111, 118, 101, 95, 114, 97, 110, 103, 101, 6, 118, 101, 99, - 116, 111, 114, 10, 109, 111, 118, 101, 95, 114, 97, 110, 103, 101, 18, 116, 101, 115, - 116, 95, 114, 101, 109, 111, 118, 101, 95, 105, 110, 115, 101, 114, 116, 6, 114, 101, - 109, 111, 118, 101, 6, 105, 110, 115, 101, 114, 116, 16, 116, 101, 115, 116, 95, 116, - 114, 105, 109, 95, 97, 112, 112, 101, 110, 100, 4, 116, 114, 105, 109, 6, 97, 112, - 112, 101, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 20, 99, 111, 109, - 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, - 0, 3, 50, 46, 48, 3, 50, 46, 49, 0, 0, 0, 0, 4, 65, 64, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 12, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 3, 9, 12, 4, 5, 8, 5, 23, 10, 4, 4, 62, 11, 3, 6, 1, 0, - 0, 0, 0, 0, 0, 0, 22, 12, 3, 10, 3, 10, 1, 35, 3, 19, 5, 23, - 13, 2, 10, 3, 68, 2, 5, 6, 64, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 9, 12, 7, 11, 0, - 12, 8, 5, 33, 5, 57, 10, 7, 4, 59, 11, 6, 6, 1, 0, 0, 0, 0, - 0, 0, 0, 22, 12, 6, 10, 6, 10, 8, 35, 3, 44, 5, 57, 10, 2, 12, - 9, 13, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 67, 2, 12, 10, 10, 6, - 11, 10, 21, 13, 5, 11, 9, 68, 3, 5, 31, 11, 5, 2, 8, 12, 7, 5, - 39, 8, 12, 4, 5, 14, 1, 1, 4, 0, 8, 42, 10, 0, 10, 1, 17, 0, - 12, 5, 11, 0, 11, 1, 17, 0, 12, 6, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 0, 9, 12, 7, 5, 14, 5, 38, 10, 7, 4, 39, 11, 0, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 12, 0, 10, 0, 10, 4, 35, 3, 25, 5, - 38, 13, 5, 10, 2, 10, 3, 13, 6, 10, 2, 56, 0, 13, 6, 10, 2, 10, - 3, 13, 5, 10, 2, 56, 0, 5, 12, 2, 8, 12, 7, 5, 20, 3, 1, 4, - 0, 13, 34, 11, 0, 11, 1, 17, 0, 12, 4, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 12, 0, 9, 12, 5, 5, 10, 5, 30, 10, 5, 4, 31, 11, 0, 6, - 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 0, 10, 0, 10, 3, 35, 3, 21, - 5, 30, 13, 4, 10, 2, 56, 1, 12, 6, 13, 4, 10, 2, 11, 6, 56, 2, - 5, 8, 2, 8, 12, 5, 5, 16, 6, 1, 4, 0, 16, 33, 11, 0, 11, 1, - 17, 0, 12, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 9, 12, 5, - 5, 10, 5, 29, 10, 5, 4, 30, 11, 0, 6, 1, 0, 0, 0, 0, 0, 0, - 0, 22, 12, 0, 10, 0, 10, 3, 35, 3, 21, 5, 29, 13, 4, 10, 2, 56, - 3, 12, 6, 13, 4, 11, 6, 56, 4, 5, 8, 2, 8, 12, 5, 5, 16, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_FRAMEWORK_USECASES: Lazy>> = Lazy::new(|| { vec![ - MODULE_FRAMEWORK_USECASES_AGGREGATOR_EXAMPLE.to_vec(), - MODULE_FRAMEWORK_USECASES_COIN_EXAMPLE.to_vec(), - MODULE_FRAMEWORK_USECASES_FUNGIBLE_ASSET_EXAMPLE.to_vec(), - MODULE_FRAMEWORK_USECASES_MAPS_EXAMPLE.to_vec(), - MODULE_FRAMEWORK_USECASES_OBJECTS.to_vec(), - MODULE_FRAMEWORK_USECASES_PERMISSIONED_TRANSFER.to_vec(), - MODULE_FRAMEWORK_USECASES_RESOURCE_GROUPS_EXAMPLE.to_vec(), - MODULE_FRAMEWORK_USECASES_TOKEN_V1.to_vec(), - MODULE_FRAMEWORK_USECASES_VECTOR_EXAMPLE.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_EXPERIMENTAL_USECASES_METADATA: Lazy> = Lazy::new(|| { - vec![ - 20, 69, 120, 112, 101, 114, 105, 109, 101, 110, 116, 97, 108, 85, 115, 101, 99, 97, - 115, 101, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 66, 70, 49, 56, 69, - 53, 51, 51, 49, 56, 55, 67, 49, 54, 51, 56, 51, 51, 50, 48, 57, 48, 49, - 70, 54, 51, 55, 56, 67, 56, 49, 57, 50, 70, 55, 53, 51, 50, 70, 69, 54, - 50, 51, 50, 69, 70, 50, 49, 65, 70, 70, 51, 56, 69, 57, 51, 52, 65, 57, - 50, 66, 67, 68, 56, 232, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, - 209, 187, 110, 195, 48, 12, 5, 208, 93, 95, 65, 184, 115, 156, 254, 64, 135, 244, - 181, 118, 105, 39, 35, 40, 24, 249, 198, 81, 45, 83, 130, 168, 166, 6, 138, 254, - 123, 45, 228, 1, 103, 77, 32, 13, 20, 113, 121, 32, 128, 77, 100, 219, 115, 135, - 181, 17, 30, 64, 15, 84, 189, 140, 17, 201, 13, 144, 204, 254, 67, 97, 89, 161, - 149, 217, 35, 169, 11, 82, 2, 247, 245, 116, 42, 99, 154, 22, 17, 210, 66, 172, - 131, 174, 205, 42, 230, 160, 175, 105, 82, 126, 66, 234, 167, 224, 47, 249, 96, 217, - 151, 145, 186, 94, 206, 47, 151, 232, 98, 8, 123, 44, 183, 167, 129, 99, 243, 252, - 174, 232, 239, 64, 206, 255, 115, 173, 138, 153, 113, 134, 223, 67, 15, 185, 86, 204, - 101, 248, 146, 122, 219, 124, 193, 102, 189, 73, 92, 132, 3, 82, 100, 115, 71, 25, - 154, 157, 116, 132, 209, 238, 88, 186, 82, 134, 45, 217, 32, 154, 89, 50, 113, 219, - 38, 168, 82, 81, 148, 120, 42, 224, 125, 109, 154, 99, 191, 108, 37, 126, 111, 188, - 211, 29, 210, 231, 41, 92, 54, 56, 174, 30, 159, 158, 43, 243, 15, 47, 59, 21, - 168, 253, 1, 0, 0, 1, 18, 111, 114, 100, 101, 114, 95, 98, 111, 111, 107, 95, - 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, 111, 115, 70, 114, 97, 109, 101, - 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, 83, 116, 100, 108, 105, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 65, 112, - 116, 111, 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 79, 98, 106, - 101, 99, 116, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, - 17, 65, 112, 116, 111, 115, 69, 120, 112, 101, 114, 105, 109, 101, 110, 116, 97, 108, - 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_EXPERIMENTAL_USECASES_ORDER_BOOK_EXAMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 8, 0, 0, 10, 12, 1, 0, 14, 2, 14, 58, 3, 72, 124, - 4, 196, 1, 12, 5, 208, 1, 122, 7, 202, 2, 239, 3, 8, 185, 6, 96, 6, - 153, 7, 34, 16, 187, 7, 123, 10, 182, 8, 20, 12, 202, 8, 196, 1, 13, 142, - 10, 4, 0, 0, 1, 6, 1, 8, 2, 11, 2, 17, 1, 19, 2, 20, 0, 1, - 7, 0, 0, 3, 8, 0, 1, 5, 4, 0, 0, 7, 8, 0, 2, 9, 4, 1, - 7, 0, 4, 16, 7, 1, 0, 0, 5, 18, 7, 1, 7, 0, 5, 23, 7, 0, - 5, 25, 7, 0, 2, 27, 3, 1, 7, 0, 5, 29, 3, 1, 7, 0, 5, 32, - 7, 0, 0, 10, 0, 1, 0, 1, 0, 3, 12, 0, 2, 0, 1, 1, 1, 1, - 13, 1, 3, 0, 1, 1, 1, 2, 14, 1, 5, 1, 7, 1, 1, 1, 0, 15, - 6, 1, 0, 1, 1, 1, 2, 15, 7, 8, 1, 7, 1, 1, 1, 6, 21, 6, - 6, 0, 1, 1, 1, 0, 22, 9, 1, 0, 1, 1, 1, 4, 24, 1, 11, 1, - 0, 1, 1, 1, 2, 26, 13, 14, 1, 7, 1, 1, 1, 2, 28, 15, 16, 1, - 7, 1, 1, 1, 0, 30, 9, 1, 0, 1, 1, 1, 5, 31, 17, 18, 0, 1, - 1, 1, 5, 33, 1, 10, 0, 1, 1, 1, 1, 34, 19, 1, 0, 1, 1, 1, - 3, 4, 5, 4, 8, 10, 8, 12, 9, 4, 10, 4, 1, 6, 12, 0, 1, 5, - 1, 8, 2, 1, 8, 0, 1, 11, 4, 1, 9, 0, 1, 3, 3, 7, 11, 4, - 1, 9, 0, 5, 3, 1, 11, 5, 1, 11, 6, 1, 9, 0, 5, 5, 3, 3, - 3, 1, 1, 8, 7, 1, 11, 5, 1, 9, 0, 1, 8, 8, 9, 5, 3, 11, - 5, 1, 8, 7, 3, 3, 3, 1, 11, 5, 1, 8, 8, 9, 0, 1, 11, 9, - 1, 9, 0, 2, 7, 11, 4, 1, 9, 0, 11, 9, 1, 9, 0, 1, 10, 11, - 10, 1, 9, 0, 2, 5, 3, 1, 8, 11, 6, 7, 8, 2, 8, 11, 3, 8, - 7, 3, 1, 2, 8, 11, 8, 7, 18, 111, 114, 100, 101, 114, 95, 98, 111, 111, - 107, 95, 101, 120, 97, 109, 112, 108, 101, 5, 69, 109, 112, 116, 121, 11, 100, 117, - 109, 109, 121, 95, 102, 105, 101, 108, 100, 10, 65, 99, 116, 105, 118, 101, 79, 110, - 108, 121, 11, 97, 99, 116, 105, 118, 101, 95, 111, 110, 108, 121, 15, 65, 99, 116, - 105, 118, 101, 79, 114, 100, 101, 114, 66, 111, 111, 107, 17, 97, 99, 116, 105, 118, - 101, 95, 111, 114, 100, 101, 114, 95, 98, 111, 111, 107, 3, 68, 101, 120, 10, 111, - 114, 100, 101, 114, 95, 98, 111, 111, 107, 9, 79, 114, 100, 101, 114, 66, 111, 111, - 107, 11, 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 6, 115, 105, 103, 110, - 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 21, 110, 101, 119, 95, - 97, 99, 116, 105, 118, 101, 95, 111, 114, 100, 101, 114, 95, 98, 111, 111, 107, 14, - 110, 101, 119, 95, 111, 114, 100, 101, 114, 95, 98, 111, 111, 107, 12, 99, 97, 110, - 99, 101, 108, 95, 111, 114, 100, 101, 114, 6, 79, 112, 116, 105, 111, 110, 6, 111, - 112, 116, 105, 111, 110, 5, 79, 114, 100, 101, 114, 16, 111, 114, 100, 101, 114, 95, - 98, 111, 111, 107, 95, 116, 121, 112, 101, 115, 5, 101, 114, 114, 111, 114, 16, 105, - 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, 109, 101, 110, 116, 11, 112, 108, - 97, 99, 101, 95, 111, 114, 100, 101, 114, 13, 85, 110, 105, 113, 117, 101, 73, 100, - 120, 84, 121, 112, 101, 4, 110, 111, 110, 101, 16, 84, 114, 105, 103, 103, 101, 114, - 67, 111, 110, 100, 105, 116, 105, 111, 110, 17, 110, 101, 119, 95, 111, 114, 100, 101, - 114, 95, 114, 101, 113, 117, 101, 115, 116, 12, 79, 114, 100, 101, 114, 82, 101, 113, - 117, 101, 115, 116, 27, 112, 108, 97, 99, 101, 95, 111, 114, 100, 101, 114, 95, 97, - 110, 100, 95, 103, 101, 116, 95, 109, 97, 116, 99, 104, 101, 115, 16, 83, 105, 110, - 103, 108, 101, 79, 114, 100, 101, 114, 77, 97, 116, 99, 104, 28, 112, 108, 97, 99, - 101, 95, 97, 99, 116, 105, 118, 101, 95, 112, 111, 115, 116, 95, 111, 110, 108, 121, - 95, 111, 114, 100, 101, 114, 17, 110, 101, 119, 95, 111, 114, 100, 101, 114, 95, 105, - 100, 95, 116, 121, 112, 101, 11, 79, 114, 100, 101, 114, 73, 100, 84, 121, 112, 101, - 34, 103, 101, 110, 101, 114, 97, 116, 101, 95, 117, 110, 105, 113, 117, 101, 95, 105, - 100, 120, 95, 102, 105, 102, 111, 95, 116, 105, 101, 98, 114, 97, 107, 101, 114, 17, - 112, 108, 97, 99, 101, 95, 109, 97, 107, 101, 114, 95, 111, 114, 100, 101, 114, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 5, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 171, 205, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, - 116, 97, 100, 97, 116, 97, 18, 1, 3, 50, 46, 48, 12, 50, 46, 51, 45, 117, - 110, 115, 116, 97, 98, 108, 101, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, 116, - 97, 100, 97, 116, 97, 95, 118, 49, 63, 2, 1, 0, 0, 0, 0, 0, 0, 0, - 15, 69, 78, 79, 84, 95, 65, 85, 84, 72, 79, 82, 73, 90, 69, 68, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 25, 69, 68, 69, 88, 95, 82, 69, 83, 79, 85, - 82, 67, 69, 95, 78, 79, 84, 95, 80, 82, 69, 83, 69, 78, 84, 0, 0, 0, - 0, 2, 1, 2, 1, 1, 2, 1, 4, 8, 2, 3, 2, 1, 8, 11, 4, 1, - 8, 0, 0, 0, 0, 0, 1, 18, 10, 0, 17, 1, 7, 0, 33, 4, 14, 10, - 0, 17, 2, 18, 1, 45, 1, 11, 0, 56, 0, 18, 2, 45, 2, 2, 11, 0, - 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 39, 4, 1, 4, 1, 2, 1, 14, - 7, 0, 41, 2, 4, 11, 7, 0, 42, 2, 15, 0, 7, 0, 11, 0, 56, 1, - 1, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 7, 1, 4, 1, - 2, 1, 23, 7, 0, 41, 2, 4, 20, 7, 0, 42, 2, 15, 0, 11, 0, 11, - 1, 56, 2, 11, 2, 10, 3, 11, 3, 11, 4, 56, 3, 9, 18, 0, 56, 4, - 56, 5, 1, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 1, - 4, 1, 1, 20, 22, 7, 0, 41, 1, 4, 19, 7, 0, 42, 1, 11, 0, 11, - 1, 17, 12, 12, 5, 17, 13, 12, 6, 15, 1, 11, 5, 11, 2, 11, 6, 11, - 3, 11, 4, 17, 14, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, - 2, 0, 1, 0, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_EXPERIMENTAL_USECASES: Lazy>> = Lazy::new(|| { vec![ - MODULE_EXPERIMENTAL_USECASES_ORDER_BOOK_EXAMPLE.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_COMPLEX_METADATA: Lazy> = Lazy::new(|| { - vec![ - 7, 99, 111, 109, 112, 108, 101, 120, 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, - 67, 48, 56, 54, 51, 53, 54, 52, 53, 50, 54, 68, 66, 70, 66, 68, 48, 52, - 49, 52, 56, 49, 51, 68, 48, 53, 66, 52, 55, 50, 51, 70, 51, 49, 67, 65, - 48, 67, 69, 57, 57, 56, 48, 68, 68, 68, 54, 54, 49, 70, 67, 51, 51, 49, - 48, 67, 67, 49, 66, 56, 57, 52, 55, 51, 156, 1, 31, 139, 8, 0, 0, 0, - 0, 0, 2, 255, 77, 141, 77, 14, 194, 32, 16, 133, 247, 156, 130, 116, 195, 74, - 138, 7, 112, 81, 53, 94, 162, 105, 12, 194, 168, 164, 192, 16, 70, 107, 19, 227, - 221, 133, 164, 154, 38, 179, 152, 247, 229, 253, 244, 73, 155, 81, 223, 96, 96, 81, - 7, 224, 59, 46, 12, 134, 228, 97, 22, 108, 130, 76, 14, 99, 101, 91, 169, 164, - 18, 140, 245, 22, 18, 68, 11, 209, 56, 160, 129, 117, 233, 129, 116, 202, 37, 248, - 194, 60, 22, 227, 155, 123, 52, 218, 151, 175, 145, 178, 93, 159, 174, 214, 77, 192, - 9, 218, 235, 47, 176, 192, 191, 110, 248, 167, 76, 104, 107, 51, 16, 213, 254, 244, - 188, 120, 71, 119, 200, 231, 5, 214, 98, 53, 119, 251, 195, 177, 97, 95, 93, 193, - 155, 66, 186, 0, 0, 0, 4, 14, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, - 112, 111, 111, 108, 0, 0, 0, 22, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, - 112, 111, 111, 108, 95, 119, 114, 97, 112, 112, 101, 114, 0, 0, 0, 19, 115, 109, - 97, 114, 116, 95, 116, 97, 98, 108, 101, 95, 112, 105, 99, 116, 117, 114, 101, 0, - 0, 0, 14, 118, 101, 99, 116, 111, 114, 95, 112, 105, 99, 116, 117, 114, 101, 0, - 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, - 65, 112, 116, 111, 115, 70, 114, 97, 109, 101, 119, 111, 114, 107, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, - 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 10, 77, 111, 118, 101, 83, 116, 100, 108, 105, 98, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_COMPLEX_LIQUIDITY_POOL: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 13, 1, 0, 30, 2, 30, 82, 3, 112, 131, - 4, 4, 243, 4, 86, 5, 201, 5, 135, 6, 7, 208, 11, 232, 12, 8, 184, 24, - 64, 6, 248, 24, 56, 16, 176, 25, 180, 9, 10, 228, 34, 131, 1, 12, 231, 35, - 137, 23, 13, 240, 58, 38, 15, 150, 59, 2, 0, 0, 1, 4, 1, 8, 1, 16, - 1, 37, 1, 55, 1, 58, 1, 64, 1, 66, 1, 69, 1, 72, 1, 83, 1, 91, - 1, 95, 1, 97, 0, 1, 6, 0, 1, 3, 7, 1, 0, 1, 0, 5, 8, 0, - 2, 7, 11, 0, 0, 11, 8, 0, 3, 15, 4, 2, 0, 0, 0, 0, 0, 20, - 4, 0, 2, 22, 6, 0, 2, 24, 6, 0, 2, 26, 6, 0, 2, 28, 8, 0, - 0, 34, 8, 0, 4, 36, 4, 1, 0, 0, 0, 41, 6, 0, 2, 45, 0, 0, - 6, 60, 7, 0, 1, 68, 2, 0, 9, 71, 7, 1, 0, 0, 0, 44, 0, 1, - 0, 1, 2, 46, 3, 4, 0, 1, 2, 47, 3, 5, 0, 1, 0, 48, 6, 7, - 0, 1, 2, 49, 8, 1, 0, 1, 1, 50, 10, 11, 1, 8, 1, 2, 51, 13, - 5, 1, 8, 1, 2, 52, 13, 4, 1, 8, 1, 2, 53, 14, 2, 1, 8, 1, - 2, 54, 15, 1, 1, 8, 1, 5, 56, 17, 2, 1, 6, 1, 0, 57, 19, 20, - 0, 1, 6, 59, 21, 22, 0, 1, 2, 61, 13, 22, 1, 8, 1, 6, 62, 24, - 2, 0, 1, 6, 63, 25, 2, 0, 1, 7, 65, 27, 21, 1, 0, 1, 8, 62, - 28, 2, 1, 0, 1, 1, 67, 30, 31, 0, 1, 9, 70, 2, 33, 1, 0, 1, - 10, 73, 34, 2, 0, 1, 1, 74, 35, 36, 0, 1, 1, 75, 35, 13, 1, 8, - 1, 2, 76, 37, 38, 1, 8, 1, 1, 77, 39, 31, 0, 1, 0, 78, 35, 40, - 0, 1, 3, 79, 2, 42, 2, 7, 4, 1, 1, 80, 13, 44, 2, 8, 8, 1, - 4, 81, 45, 2, 1, 4, 1, 0, 82, 48, 2, 0, 1, 11, 84, 39, 11, 0, - 1, 0, 85, 49, 38, 1, 8, 1, 0, 86, 50, 2, 0, 1, 2, 87, 51, 2, - 1, 8, 1, 0, 88, 53, 2, 0, 1, 0, 0, 54, 20, 0, 1, 2, 89, 13, - 55, 1, 8, 1, 9, 90, 33, 17, 1, 0, 1, 12, 92, 32, 32, 0, 1, 2, - 93, 56, 2, 1, 8, 1, 2, 88, 57, 1, 0, 1, 2, 94, 58, 2, 1, 8, - 1, 13, 96, 7, 5, 0, 1, 14, 98, 5, 5, 0, 1, 0, 99, 54, 11, 0, - 1, 1, 100, 11, 13, 1, 8, 1, 0, 35, 2, 60, 0, 1, 4, 101, 61, 5, - 1, 0, 1, 4, 102, 62, 27, 1, 0, 1, 0, 103, 64, 65, 0, 1, 3, 104, - 66, 29, 2, 2, 0, 1, 3, 105, 67, 68, 2, 3, 0, 1, 2, 106, 13, 1, - 1, 8, 1, 0, 107, 50, 70, 0, 1, 3, 108, 71, 72, 2, 3, 0, 1, 0, - 10, 20, 29, 0, 1, 2, 109, 35, 74, 0, 1, 2, 110, 35, 75, 0, 1, 2, - 111, 35, 76, 0, 1, 10, 112, 49, 38, 1, 8, 1, 10, 113, 49, 38, 1, 8, - 1, 2, 114, 13, 29, 1, 8, 1, 2, 115, 77, 2, 1, 8, 1, 0, 116, 78, - 79, 0, 1, 0, 117, 39, 2, 0, 1, 4, 79, 2, 82, 1, 4, 1, 1, 118, - 83, 11, 0, 1, 0, 119, 54, 85, 0, 1, 0, 120, 13, 32, 1, 8, 1, 0, - 121, 2, 5, 0, 1, 0, 122, 13, 7, 1, 8, 1, 0, 123, 20, 87, 0, 1, - 0, 33, 20, 5, 0, 1, 0, 124, 2, 5, 0, 1, 10, 51, 49, 5, 1, 8, - 1, 3, 102, 66, 72, 2, 2, 0, 1, 3, 125, 88, 89, 2, 3, 2, 1, 3, - 126, 88, 2, 2, 3, 2, 1, 5, 9, 6, 12, 7, 12, 8, 12, 9, 12, 10, - 16, 13, 23, 5, 23, 16, 11, 17, 26, 16, 29, 19, 32, 22, 23, 23, 23, 26, - 41, 27, 43, 28, 20, 10, 46, 31, 9, 33, 12, 36, 9, 37, 32, 39, 9, 41, - 12, 45, 9, 47, 20, 48, 20, 50, 41, 51, 41, 52, 23, 54, 41, 59, 17, 60, - 17, 61, 12, 5, 17, 62, 12, 65, 20, 36, 17, 74, 9, 68, 9, 75, 41, 76, - 41, 77, 41, 3, 6, 12, 11, 1, 1, 8, 2, 8, 14, 1, 8, 14, 0, 1, - 6, 8, 14, 1, 11, 1, 1, 8, 3, 1, 3, 3, 11, 1, 1, 8, 2, 11, - 1, 1, 8, 3, 3, 2, 3, 3, 2, 7, 8, 14, 3, 1, 8, 2, 1, 6, - 11, 1, 1, 9, 0, 1, 5, 1, 8, 10, 1, 11, 1, 1, 9, 0, 2, 11, - 1, 1, 9, 0, 8, 14, 3, 6, 12, 11, 1, 1, 9, 0, 3, 1, 8, 13, - 1, 9, 0, 18, 11, 1, 1, 8, 3, 3, 3, 3, 8, 14, 6, 8, 2, 6, - 8, 2, 15, 15, 15, 7, 8, 4, 11, 1, 1, 8, 10, 11, 1, 1, 8, 10, - 4, 8, 14, 15, 15, 15, 4, 6, 12, 11, 1, 1, 8, 3, 11, 1, 1, 8, - 3, 1, 1, 11, 1, 1, 8, 2, 1, 10, 2, 1, 8, 15, 1, 8, 3, 2, - 7, 8, 15, 8, 15, 2, 7, 8, 15, 10, 2, 1, 2, 1, 6, 9, 0, 2, - 7, 10, 9, 0, 10, 9, 0, 1, 1, 2, 6, 12, 10, 2, 1, 8, 16, 1, - 4, 1, 11, 17, 1, 9, 0, 7, 6, 8, 16, 11, 17, 1, 4, 8, 15, 8, - 15, 2, 8, 15, 8, 15, 1, 6, 8, 16, 1, 12, 2, 6, 8, 16, 11, 1, - 1, 9, 0, 1, 11, 1, 1, 8, 10, 1, 6, 12, 1, 8, 6, 2, 5, 4, - 1, 11, 5, 2, 9, 0, 9, 1, 2, 8, 3, 8, 2, 1, 11, 1, 1, 9, - 1, 2, 7, 11, 12, 1, 9, 0, 9, 0, 1, 8, 0, 30, 7, 8, 11, 11, - 1, 1, 8, 3, 11, 1, 1, 8, 3, 11, 1, 1, 8, 3, 11, 1, 1, 8, - 3, 8, 15, 8, 15, 11, 1, 1, 8, 3, 11, 1, 1, 8, 3, 1, 10, 2, - 5, 5, 10, 2, 8, 16, 6, 8, 16, 12, 6, 12, 8, 16, 11, 1, 1, 8, - 10, 8, 16, 11, 1, 1, 8, 10, 8, 16, 11, 1, 1, 8, 10, 8, 16, 11, - 1, 1, 8, 10, 8, 6, 3, 8, 2, 11, 1, 1, 8, 2, 4, 6, 12, 11, - 1, 1, 8, 2, 5, 3, 2, 5, 11, 1, 1, 9, 0, 2, 5, 11, 1, 1, - 8, 2, 4, 6, 8, 9, 11, 1, 1, 9, 0, 11, 1, 1, 9, 0, 3, 3, - 5, 11, 1, 1, 8, 10, 11, 1, 1, 8, 10, 4, 6, 12, 8, 14, 8, 14, - 1, 3, 11, 1, 1, 8, 3, 11, 1, 1, 8, 3, 1, 1, 11, 17, 1, 4, - 3, 6, 8, 8, 11, 1, 1, 9, 0, 3, 2, 6, 8, 8, 3, 3, 6, 8, - 9, 11, 1, 1, 9, 0, 8, 14, 22, 11, 1, 1, 8, 3, 11, 1, 1, 8, - 3, 11, 1, 1, 8, 2, 11, 1, 1, 8, 10, 3, 3, 6, 8, 2, 11, 1, - 1, 8, 10, 11, 1, 1, 8, 10, 3, 3, 4, 6, 8, 8, 3, 8, 14, 3, - 3, 3, 3, 3, 3, 3, 1, 10, 11, 1, 1, 8, 2, 1, 6, 11, 12, 1, - 9, 0, 2, 6, 11, 12, 1, 9, 0, 3, 4, 6, 11, 12, 1, 11, 1, 1, - 8, 2, 10, 11, 1, 1, 8, 2, 3, 3, 3, 6, 12, 6, 12, 11, 1, 1, - 8, 2, 2, 8, 14, 8, 14, 2, 6, 11, 5, 2, 9, 0, 9, 1, 9, 0, - 2, 7, 11, 5, 2, 9, 0, 9, 1, 9, 0, 1, 9, 1, 7, 5, 6, 8, - 2, 7, 8, 4, 4, 4, 8, 14, 8, 14, 2, 4, 4, 3, 6, 11, 5, 2, - 9, 0, 9, 1, 9, 0, 6, 9, 1, 1, 6, 9, 1, 3, 6, 8, 4, 4, - 4, 1, 8, 7, 1, 8, 8, 1, 8, 9, 3, 6, 8, 9, 11, 1, 1, 9, - 0, 1, 3, 15, 15, 15, 1, 15, 14, 6, 8, 2, 15, 15, 15, 15, 3, 3, - 3, 15, 6, 8, 2, 15, 15, 15, 15, 6, 3, 15, 15, 15, 15, 15, 1, 11, - 12, 1, 9, 0, 2, 6, 5, 10, 2, 7, 5, 11, 1, 1, 8, 3, 11, 1, - 1, 8, 3, 1, 10, 2, 5, 5, 2, 1, 5, 1, 6, 8, 2, 1, 10, 11, - 1, 1, 8, 3, 3, 7, 11, 5, 2, 9, 0, 9, 1, 9, 0, 9, 1, 1, - 7, 9, 1, 15, 7, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 7, 4, 14, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, - 108, 10, 67, 114, 101, 97, 116, 101, 80, 111, 111, 108, 4, 112, 111, 111, 108, 6, - 79, 98, 106, 101, 99, 116, 6, 111, 98, 106, 101, 99, 116, 13, 76, 105, 113, 117, - 105, 100, 105, 116, 121, 80, 111, 111, 108, 7, 116, 111, 107, 101, 110, 95, 49, 8, - 77, 101, 116, 97, 100, 97, 116, 97, 14, 102, 117, 110, 103, 105, 98, 108, 101, 95, - 97, 115, 115, 101, 116, 7, 116, 111, 107, 101, 110, 95, 50, 9, 105, 115, 95, 115, - 116, 97, 98, 108, 101, 14, 70, 101, 101, 115, 65, 99, 99, 111, 117, 110, 116, 105, - 110, 103, 12, 116, 111, 116, 97, 108, 95, 102, 101, 101, 115, 95, 49, 12, 116, 111, - 116, 97, 108, 95, 102, 101, 101, 115, 95, 50, 26, 116, 111, 116, 97, 108, 95, 102, - 101, 101, 115, 95, 97, 116, 95, 108, 97, 115, 116, 95, 99, 108, 97, 105, 109, 95, - 49, 10, 83, 109, 97, 114, 116, 84, 97, 98, 108, 101, 11, 115, 109, 97, 114, 116, - 95, 116, 97, 98, 108, 101, 26, 116, 111, 116, 97, 108, 95, 102, 101, 101, 115, 95, - 97, 116, 95, 108, 97, 115, 116, 95, 99, 108, 97, 105, 109, 95, 50, 11, 99, 108, - 97, 105, 109, 97, 98, 108, 101, 95, 49, 11, 99, 108, 97, 105, 109, 97, 98, 108, - 101, 95, 50, 11, 76, 80, 84, 111, 107, 101, 110, 82, 101, 102, 115, 8, 98, 117, - 114, 110, 95, 114, 101, 102, 7, 66, 117, 114, 110, 82, 101, 102, 8, 109, 105, 110, - 116, 95, 114, 101, 102, 7, 77, 105, 110, 116, 82, 101, 102, 12, 116, 114, 97, 110, - 115, 102, 101, 114, 95, 114, 101, 102, 11, 84, 114, 97, 110, 115, 102, 101, 114, 82, - 101, 102, 13, 116, 111, 107, 101, 110, 95, 115, 116, 111, 114, 101, 95, 49, 13, 70, - 117, 110, 103, 105, 98, 108, 101, 83, 116, 111, 114, 101, 13, 116, 111, 107, 101, 110, - 95, 115, 116, 111, 114, 101, 95, 50, 12, 102, 101, 101, 115, 95, 115, 116, 111, 114, - 101, 95, 49, 12, 102, 101, 101, 115, 95, 115, 116, 111, 114, 101, 95, 50, 13, 108, - 112, 95, 116, 111, 107, 101, 110, 95, 114, 101, 102, 115, 12, 115, 119, 97, 112, 95, - 102, 101, 101, 95, 98, 112, 115, 20, 76, 105, 113, 117, 105, 100, 105, 116, 121, 80, - 111, 111, 108, 67, 111, 110, 102, 105, 103, 115, 9, 97, 108, 108, 95, 112, 111, 111, - 108, 115, 11, 83, 109, 97, 114, 116, 86, 101, 99, 116, 111, 114, 12, 115, 109, 97, - 114, 116, 95, 118, 101, 99, 116, 111, 114, 9, 105, 115, 95, 112, 97, 117, 115, 101, - 100, 14, 115, 116, 97, 98, 108, 101, 95, 102, 101, 101, 95, 98, 112, 115, 16, 118, - 111, 108, 97, 116, 105, 108, 101, 95, 102, 101, 101, 95, 98, 112, 115, 4, 83, 119, - 97, 112, 10, 102, 114, 111, 109, 95, 116, 111, 107, 101, 110, 9, 97, 109, 111, 117, - 110, 116, 95, 105, 110, 4, 115, 119, 97, 112, 13, 70, 117, 110, 103, 105, 98, 108, - 101, 65, 115, 115, 101, 116, 19, 109, 101, 116, 97, 100, 97, 116, 97, 95, 102, 114, - 111, 109, 95, 97, 115, 115, 101, 116, 6, 97, 109, 111, 117, 110, 116, 14, 103, 101, - 116, 95, 97, 109, 111, 117, 110, 116, 95, 111, 117, 116, 7, 101, 120, 116, 114, 97, - 99, 116, 14, 111, 98, 106, 101, 99, 116, 95, 97, 100, 100, 114, 101, 115, 115, 7, - 98, 97, 108, 97, 110, 99, 101, 14, 115, 116, 111, 114, 101, 95, 109, 101, 116, 97, - 100, 97, 116, 97, 7, 100, 101, 112, 111, 115, 105, 116, 8, 119, 105, 116, 104, 100, - 114, 97, 119, 5, 101, 118, 101, 110, 116, 4, 101, 109, 105, 116, 6, 99, 114, 101, - 97, 116, 101, 6, 115, 116, 114, 105, 110, 103, 4, 117, 116, 102, 56, 6, 83, 116, - 114, 105, 110, 103, 6, 115, 121, 109, 98, 111, 108, 6, 97, 112, 112, 101, 110, 100, - 11, 97, 112, 112, 101, 110, 100, 95, 117, 116, 102, 56, 3, 98, 99, 115, 8, 116, - 111, 95, 98, 121, 116, 101, 115, 6, 118, 101, 99, 116, 111, 114, 19, 99, 114, 101, - 97, 116, 101, 95, 110, 97, 109, 101, 100, 95, 111, 98, 106, 101, 99, 116, 14, 67, - 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 82, 101, 102, 6, 111, 112, 116, 105, - 111, 110, 4, 110, 111, 110, 101, 6, 79, 112, 116, 105, 111, 110, 22, 112, 114, 105, - 109, 97, 114, 121, 95, 102, 117, 110, 103, 105, 98, 108, 101, 95, 115, 116, 111, 114, - 101, 43, 99, 114, 101, 97, 116, 101, 95, 112, 114, 105, 109, 97, 114, 121, 95, 115, - 116, 111, 114, 101, 95, 101, 110, 97, 98, 108, 101, 100, 95, 102, 117, 110, 103, 105, - 98, 108, 101, 95, 97, 115, 115, 101, 116, 15, 103, 101, 110, 101, 114, 97, 116, 101, - 95, 115, 105, 103, 110, 101, 114, 27, 111, 98, 106, 101, 99, 116, 95, 102, 114, 111, - 109, 95, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 95, 114, 101, 102, 12, - 99, 114, 101, 97, 116, 101, 95, 115, 116, 111, 114, 101, 25, 99, 114, 101, 97, 116, - 101, 95, 111, 98, 106, 101, 99, 116, 95, 102, 114, 111, 109, 95, 111, 98, 106, 101, - 99, 116, 20, 99, 114, 101, 97, 116, 101, 95, 108, 112, 95, 116, 111, 107, 101, 110, - 95, 114, 101, 102, 115, 3, 110, 101, 119, 7, 99, 111, 110, 118, 101, 114, 116, 9, - 112, 117, 115, 104, 95, 98, 97, 99, 107, 8, 116, 114, 97, 110, 115, 102, 101, 114, - 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, - 21, 101, 110, 115, 117, 114, 101, 95, 108, 112, 95, 116, 111, 107, 101, 110, 95, 115, - 116, 111, 114, 101, 21, 117, 112, 100, 97, 116, 101, 95, 99, 108, 97, 105, 109, 97, - 98, 108, 101, 95, 102, 101, 101, 115, 17, 116, 114, 97, 110, 115, 102, 101, 114, 95, - 119, 105, 116, 104, 95, 114, 101, 102, 4, 109, 105, 110, 116, 6, 115, 117, 112, 112, - 108, 121, 12, 100, 101, 115, 116, 114, 111, 121, 95, 115, 111, 109, 101, 7, 109, 97, - 116, 104, 49, 50, 56, 4, 115, 113, 114, 116, 7, 109, 105, 110, 116, 95, 116, 111, - 16, 100, 101, 112, 111, 115, 105, 116, 95, 119, 105, 116, 104, 95, 114, 101, 102, 6, - 109, 97, 116, 104, 54, 52, 3, 109, 105, 110, 5, 101, 114, 114, 111, 114, 16, 105, - 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, 109, 101, 110, 116, 22, 108, 105, - 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, 95, 97, 100, 100, 114, 101, - 115, 115, 17, 97, 100, 100, 114, 101, 115, 115, 95, 116, 111, 95, 111, 98, 106, 101, - 99, 116, 6, 108, 101, 110, 103, 116, 104, 6, 98, 111, 114, 114, 111, 119, 10, 99, - 108, 97, 105, 109, 95, 102, 101, 101, 115, 8, 99, 111, 110, 116, 97, 105, 110, 115, - 6, 114, 101, 109, 111, 118, 101, 4, 122, 101, 114, 111, 14, 99, 108, 97, 105, 109, - 97, 98, 108, 101, 95, 102, 101, 101, 115, 19, 98, 111, 114, 114, 111, 119, 95, 119, - 105, 116, 104, 95, 100, 101, 102, 97, 117, 108, 116, 17, 103, 101, 110, 101, 114, 97, - 116, 101, 95, 98, 117, 114, 110, 95, 114, 101, 102, 17, 103, 101, 110, 101, 114, 97, - 116, 101, 95, 109, 105, 110, 116, 95, 114, 101, 102, 21, 103, 101, 110, 101, 114, 97, - 116, 101, 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, 114, 101, 102, 27, 101, 110, - 115, 117, 114, 101, 95, 112, 114, 105, 109, 97, 114, 121, 95, 115, 116, 111, 114, 101, - 95, 101, 120, 105, 115, 116, 115, 13, 112, 114, 105, 109, 97, 114, 121, 95, 115, 116, - 111, 114, 101, 9, 105, 115, 95, 102, 114, 111, 122, 101, 110, 15, 115, 101, 116, 95, - 102, 114, 111, 122, 101, 110, 95, 102, 108, 97, 103, 5, 103, 101, 116, 95, 121, 11, - 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 21, 99, 114, 101, 97, 116, 101, - 95, 111, 98, 106, 101, 99, 116, 95, 97, 100, 100, 114, 101, 115, 115, 27, 108, 105, - 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, 95, 97, 100, 100, 114, 101, - 115, 115, 95, 115, 97, 102, 101, 15, 108, 112, 95, 116, 111, 107, 101, 110, 95, 115, - 117, 112, 112, 108, 121, 13, 109, 105, 110, 95, 108, 105, 113, 117, 105, 100, 105, 116, - 121, 13, 112, 111, 111, 108, 95, 114, 101, 115, 101, 114, 118, 101, 115, 22, 115, 117, - 112, 112, 111, 114, 116, 101, 100, 95, 105, 110, 110, 101, 114, 95, 97, 115, 115, 101, - 116, 115, 21, 116, 111, 116, 97, 108, 95, 110, 117, 109, 98, 101, 114, 95, 111, 102, - 95, 112, 111, 111, 108, 115, 23, 98, 111, 114, 114, 111, 119, 95, 109, 117, 116, 95, - 119, 105, 116, 104, 95, 100, 101, 102, 97, 117, 108, 116, 6, 117, 112, 115, 101, 114, - 116, 22, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, 95, 119, - 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 32, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 10, 2, 4, 3, - 76, 80, 45, 10, 2, 2, 1, 45, 10, 2, 3, 2, 76, 80, 10, 2, 1, 0, - 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, - 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, - 115, 58, 58, 109, 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 128, 9, 8, 1, - 0, 0, 0, 0, 0, 0, 0, 12, 69, 90, 69, 82, 79, 95, 65, 77, 79, 85, - 78, 84, 52, 65, 109, 111, 117, 110, 116, 32, 111, 102, 32, 116, 111, 107, 101, 110, - 115, 32, 112, 114, 111, 118, 105, 100, 101, 100, 32, 109, 117, 115, 116, 32, 98, 101, - 32, 103, 114, 101, 97, 116, 101, 114, 32, 116, 104, 97, 110, 32, 122, 101, 114, 111, - 46, 2, 0, 0, 0, 0, 0, 0, 0, 30, 69, 73, 78, 83, 85, 70, 70, 73, - 67, 73, 69, 78, 84, 95, 76, 73, 81, 85, 73, 68, 73, 84, 89, 95, 77, 73, - 78, 84, 69, 68, 99, 84, 104, 101, 32, 97, 109, 111, 117, 110, 116, 32, 111, 102, - 32, 108, 105, 113, 117, 105, 100, 105, 116, 121, 32, 112, 114, 111, 118, 105, 100, 101, - 100, 32, 105, 115, 32, 115, 111, 32, 115, 109, 97, 108, 108, 32, 116, 104, 97, 116, - 32, 99, 111, 114, 114, 101, 115, 112, 111, 110, 100, 105, 110, 103, 32, 76, 80, 32, - 116, 111, 107, 101, 110, 32, 97, 109, 111, 117, 110, 116, 32, 105, 115, 32, 114, 111, - 117, 110, 100, 101, 100, 32, 116, 111, 32, 122, 101, 114, 111, 46, 3, 0, 0, 0, - 0, 0, 0, 0, 32, 69, 73, 78, 83, 85, 70, 70, 73, 67, 73, 69, 78, 84, - 95, 76, 73, 81, 85, 73, 68, 73, 84, 89, 95, 82, 69, 68, 69, 69, 77, 69, - 68, 98, 65, 109, 111, 117, 110, 116, 32, 111, 102, 32, 76, 80, 32, 116, 111, 107, - 101, 110, 115, 32, 114, 101, 100, 101, 101, 109, 101, 100, 32, 105, 115, 32, 116, 111, - 111, 32, 115, 109, 97, 108, 108, 44, 32, 115, 111, 32, 97, 109, 111, 117, 110, 116, - 115, 32, 111, 102, 32, 116, 111, 107, 101, 110, 115, 32, 114, 101, 99, 101, 105, 118, - 101, 100, 32, 98, 97, 99, 107, 32, 97, 114, 101, 32, 114, 111, 117, 110, 100, 101, - 100, 32, 116, 111, 32, 122, 101, 114, 111, 46, 4, 0, 0, 0, 0, 0, 0, 0, - 22, 69, 73, 78, 67, 79, 82, 82, 69, 67, 84, 95, 83, 87, 65, 80, 95, 65, - 77, 79, 85, 78, 84, 94, 84, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, - 100, 32, 97, 109, 111, 117, 110, 116, 32, 111, 102, 32, 111, 117, 116, 112, 117, 116, - 32, 116, 111, 107, 101, 110, 115, 32, 105, 115, 32, 105, 110, 99, 111, 114, 114, 101, - 99, 116, 32, 97, 110, 100, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 109, 97, - 105, 110, 116, 97, 105, 110, 32, 116, 104, 101, 32, 112, 111, 111, 108, 39, 115, 32, - 105, 110, 118, 97, 114, 105, 97, 110, 116, 46, 5, 0, 0, 0, 0, 0, 0, 0, - 16, 69, 78, 79, 84, 95, 83, 84, 79, 82, 69, 95, 79, 87, 78, 69, 82, 50, - 84, 104, 101, 32, 99, 97, 108, 108, 101, 114, 32, 105, 115, 32, 110, 111, 116, 32, - 116, 104, 101, 32, 111, 119, 110, 101, 114, 32, 111, 102, 32, 116, 104, 101, 32, 76, - 80, 32, 116, 111, 107, 101, 110, 32, 115, 116, 111, 114, 101, 46, 6, 0, 0, 0, - 0, 0, 0, 0, 15, 69, 78, 79, 84, 95, 65, 85, 84, 72, 79, 82, 73, 90, - 69, 68, 50, 67, 108, 97, 108, 101, 114, 32, 105, 115, 32, 110, 111, 116, 32, 97, - 117, 116, 104, 111, 114, 105, 122, 101, 100, 32, 116, 111, 32, 112, 101, 114, 102, 111, - 114, 109, 32, 116, 104, 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 46, 7, - 0, 0, 0, 0, 0, 0, 0, 17, 69, 83, 87, 65, 80, 83, 95, 65, 82, 69, - 95, 80, 65, 85, 83, 69, 68, 31, 65, 108, 108, 32, 115, 119, 97, 112, 115, 32, - 97, 114, 101, 32, 99, 117, 114, 114, 101, 110, 116, 108, 121, 32, 112, 97, 117, 115, - 101, 100, 46, 8, 0, 0, 0, 0, 0, 0, 0, 41, 69, 75, 95, 66, 69, 70, - 79, 82, 69, 95, 83, 87, 65, 80, 95, 71, 82, 69, 65, 84, 69, 82, 95, 84, - 72, 65, 78, 95, 69, 75, 95, 65, 70, 84, 69, 82, 95, 83, 87, 65, 80, 46, - 83, 119, 97, 112, 32, 108, 101, 97, 118, 101, 115, 32, 112, 111, 111, 108, 32, 105, - 110, 32, 97, 32, 119, 111, 114, 115, 101, 32, 115, 116, 97, 116, 101, 32, 116, 104, - 97, 110, 32, 98, 101, 102, 111, 114, 101, 46, 4, 4, 83, 119, 97, 112, 1, 4, - 0, 10, 67, 114, 101, 97, 116, 101, 80, 111, 111, 108, 1, 4, 0, 13, 76, 105, - 113, 117, 105, 100, 105, 116, 121, 80, 111, 111, 108, 1, 3, 1, 24, 48, 120, 49, - 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, 106, 101, 99, 116, 71, 114, - 111, 117, 112, 14, 70, 101, 101, 115, 65, 99, 99, 111, 117, 110, 116, 105, 110, 103, - 1, 3, 1, 24, 48, 120, 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, - 98, 106, 101, 99, 116, 71, 114, 111, 117, 112, 13, 9, 97, 108, 108, 95, 112, 111, - 111, 108, 115, 1, 1, 0, 9, 105, 115, 95, 115, 116, 97, 98, 108, 101, 1, 1, - 0, 12, 115, 119, 97, 112, 95, 102, 101, 101, 95, 98, 112, 115, 1, 1, 0, 13, - 109, 105, 110, 95, 108, 105, 113, 117, 105, 100, 105, 116, 121, 1, 1, 0, 13, 112, - 111, 111, 108, 95, 114, 101, 115, 101, 114, 118, 101, 115, 1, 1, 0, 14, 99, 108, - 97, 105, 109, 97, 98, 108, 101, 95, 102, 101, 101, 115, 1, 1, 0, 14, 103, 101, - 116, 95, 97, 109, 111, 117, 110, 116, 95, 111, 117, 116, 1, 1, 0, 14, 108, 105, - 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, 1, 1, 0, 15, 108, 112, - 95, 116, 111, 107, 101, 110, 95, 115, 117, 112, 112, 108, 121, 1, 1, 0, 21, 116, - 111, 116, 97, 108, 95, 110, 117, 109, 98, 101, 114, 95, 111, 102, 95, 112, 111, 111, - 108, 115, 1, 1, 0, 22, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, - 111, 108, 95, 97, 100, 100, 114, 101, 115, 115, 1, 1, 0, 22, 115, 117, 112, 112, - 111, 114, 116, 101, 100, 95, 105, 110, 110, 101, 114, 95, 97, 115, 115, 101, 116, 115, - 1, 1, 0, 27, 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, - 95, 97, 100, 100, 114, 101, 115, 115, 95, 115, 97, 102, 101, 1, 1, 0, 0, 2, - 4, 2, 11, 1, 1, 8, 2, 6, 11, 1, 1, 8, 3, 9, 11, 1, 1, 8, - 3, 10, 1, 4, 2, 6, 12, 4, 13, 4, 14, 11, 5, 2, 5, 4, 17, 11, - 5, 2, 5, 4, 18, 11, 5, 2, 5, 4, 19, 11, 5, 2, 5, 4, 6, 2, - 3, 21, 8, 7, 23, 8, 8, 25, 8, 9, 2, 2, 7, 27, 11, 1, 1, 8, - 10, 29, 11, 1, 1, 8, 10, 30, 11, 1, 1, 8, 10, 31, 11, 1, 1, 8, - 10, 32, 8, 6, 33, 3, 10, 1, 11, 2, 4, 35, 11, 12, 1, 11, 1, 1, - 8, 2, 38, 1, 39, 3, 40, 3, 13, 2, 3, 2, 5, 42, 11, 1, 1, 8, - 3, 43, 3, 0, 3, 0, 3, 1, 3, 4, 18, 186, 1, 7, 0, 43, 4, 16, - 0, 20, 3, 182, 1, 14, 2, 17, 1, 12, 3, 14, 2, 17, 2, 12, 4, 10, - 1, 10, 3, 10, 4, 17, 3, 12, 5, 12, 6, 13, 2, 10, 5, 17, 4, 12, - 7, 14, 1, 56, 0, 43, 3, 12, 8, 10, 8, 12, 9, 10, 9, 16, 1, 20, - 56, 1, 77, 12, 10, 10, 9, 16, 2, 20, 56, 1, 77, 12, 11, 11, 9, 16, - 3, 20, 4, 177, 1, 10, 10, 10, 10, 24, 10, 10, 24, 10, 11, 24, 10, 11, - 10, 11, 24, 11, 11, 24, 11, 10, 24, 22, 12, 12, 14, 1, 56, 0, 42, 1, - 12, 13, 10, 8, 16, 1, 20, 12, 14, 10, 8, 16, 2, 20, 12, 15, 11, 5, - 53, 12, 16, 10, 3, 10, 8, 16, 1, 20, 56, 2, 33, 4, 155, 1, 11, 14, - 11, 2, 56, 3, 10, 8, 16, 4, 20, 11, 7, 56, 3, 10, 13, 16, 5, 20, - 11, 16, 22, 11, 13, 15, 5, 21, 11, 0, 11, 15, 11, 6, 56, 4, 12, 17, - 11, 8, 12, 9, 10, 9, 16, 1, 20, 56, 1, 77, 12, 18, 10, 9, 16, 2, - 20, 56, 1, 77, 12, 19, 11, 9, 16, 3, 20, 4, 150, 1, 10, 18, 10, 18, - 24, 10, 18, 24, 10, 19, 24, 10, 19, 10, 19, 24, 11, 19, 24, 11, 18, 24, - 22, 12, 20, 11, 12, 11, 20, 37, 4, 148, 1, 14, 1, 56, 0, 11, 3, 11, - 4, 18, 5, 56, 5, 11, 17, 2, 6, 8, 0, 0, 0, 0, 0, 0, 0, 39, - 11, 18, 11, 19, 24, 12, 20, 5, 136, 1, 11, 15, 11, 2, 56, 3, 10, 8, - 16, 6, 20, 11, 7, 56, 3, 10, 13, 16, 7, 20, 11, 16, 22, 11, 13, 15, - 7, 21, 11, 0, 11, 14, 11, 6, 56, 4, 12, 17, 5, 102, 11, 10, 11, 11, - 24, 12, 12, 5, 59, 11, 0, 1, 6, 7, 0, 0, 0, 0, 0, 0, 0, 39, - 11, 1, 0, 1, 4, 47, 172, 1, 7, 0, 42, 4, 12, 4, 10, 1, 12, 5, - 10, 2, 12, 6, 10, 3, 10, 5, 12, 7, 10, 6, 12, 8, 7, 1, 17, 12, - 12, 9, 13, 9, 11, 7, 56, 6, 17, 14, 13, 9, 7, 2, 17, 15, 13, 9, - 11, 8, 56, 6, 17, 14, 11, 9, 12, 10, 11, 5, 12, 11, 11, 6, 12, 12, - 12, 13, 64, 26, 0, 0, 0, 0, 0, 0, 0, 0, 12, 14, 13, 14, 14, 11, - 56, 7, 12, 15, 14, 15, 56, 8, 56, 9, 13, 14, 14, 12, 56, 7, 12, 16, - 14, 16, 56, 8, 56, 9, 13, 14, 14, 13, 56, 10, 56, 9, 11, 14, 12, 17, - 11, 0, 11, 17, 17, 18, 12, 18, 14, 18, 12, 19, 10, 19, 56, 11, 11, 10, - 7, 3, 17, 12, 49, 8, 7, 4, 17, 12, 7, 4, 17, 12, 17, 20, 10, 19, - 17, 21, 12, 20, 14, 20, 12, 0, 10, 19, 56, 12, 12, 5, 10, 19, 10, 5, - 56, 13, 1, 10, 0, 12, 21, 10, 0, 10, 1, 12, 6, 17, 24, 12, 22, 14, - 22, 11, 6, 56, 13, 12, 23, 10, 0, 10, 2, 12, 6, 17, 24, 12, 24, 14, - 24, 11, 6, 56, 13, 12, 25, 10, 0, 10, 1, 12, 6, 17, 24, 12, 26, 14, - 26, 11, 6, 56, 13, 12, 27, 10, 0, 10, 2, 12, 6, 17, 24, 12, 28, 14, - 28, 11, 6, 56, 13, 12, 29, 11, 19, 17, 25, 12, 30, 10, 3, 4, 167, 1, - 10, 4, 16, 8, 20, 12, 31, 11, 23, 11, 25, 11, 27, 11, 29, 11, 30, 11, - 31, 10, 3, 18, 3, 12, 32, 11, 21, 11, 32, 45, 3, 11, 0, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 14, 56, 14, 56, - 14, 56, 14, 18, 1, 45, 1, 11, 5, 56, 15, 12, 33, 11, 4, 15, 9, 10, - 33, 56, 16, 10, 33, 11, 1, 11, 2, 11, 3, 18, 0, 56, 17, 11, 33, 2, - 10, 4, 16, 10, 20, 12, 31, 5, 131, 1, 29, 1, 4, 2, 1, 3, 52, 35, - 10, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 36, 4, 31, 11, 0, 17, 30, - 12, 4, 10, 4, 10, 1, 56, 18, 12, 5, 10, 2, 10, 1, 56, 18, 12, 6, - 11, 4, 10, 1, 17, 32, 11, 2, 10, 1, 17, 32, 14, 1, 56, 0, 43, 3, - 16, 11, 16, 12, 11, 5, 11, 6, 11, 3, 56, 19, 2, 11, 0, 1, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 39, 34, 1, 0, 2, 1, 3, 59, 175, 1, 14, - 1, 17, 1, 14, 2, 17, 1, 11, 3, 17, 35, 12, 6, 10, 0, 17, 30, 10, - 6, 56, 18, 12, 7, 14, 1, 17, 2, 12, 8, 14, 2, 17, 2, 12, 9, 10, - 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 36, 4, 172, 1, 10, 9, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 12, 3, 11, 3, 4, 168, 1, 14, 6, 56, - 0, 43, 3, 12, 10, 10, 10, 16, 1, 20, 12, 11, 10, 10, 16, 2, 20, 12, - 12, 10, 11, 56, 1, 12, 13, 10, 12, 56, 1, 12, 14, 10, 6, 56, 20, 56, - 21, 12, 15, 10, 10, 16, 11, 16, 13, 12, 16, 10, 15, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 4, 105, 11, 8, 53, - 11, 9, 53, 24, 17, 38, 52, 10, 16, 10, 6, 6, 232, 3, 0, 0, 0, 0, - 0, 0, 56, 22, 6, 232, 3, 0, 0, 0, 0, 0, 0, 23, 12, 17, 10, 17, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 36, 4, 97, 11, 11, 11, 1, 56, 3, - 11, 12, 11, 2, 56, 3, 11, 0, 17, 30, 11, 6, 17, 32, 11, 16, 11, 17, - 17, 40, 12, 18, 11, 10, 16, 11, 16, 12, 11, 7, 11, 18, 56, 23, 2, 11, - 0, 1, 11, 10, 1, 11, 16, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 39, - 11, 8, 12, 19, 10, 15, 52, 12, 20, 10, 13, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 4, 159, 1, 11, 19, 53, 11, 20, 53, 24, 11, 13, 53, 26, 52, - 12, 21, 11, 9, 12, 22, 11, 15, 52, 12, 23, 11, 14, 12, 24, 10, 24, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 4, 150, 1, 11, 22, 53, 11, 23, 53, - 24, 11, 24, 53, 26, 52, 12, 25, 11, 21, 11, 25, 17, 42, 12, 17, 5, 72, - 11, 0, 1, 11, 10, 1, 11, 16, 1, 6, 4, 0, 0, 0, 0, 0, 0, 0, - 17, 43, 39, 11, 0, 1, 11, 10, 1, 11, 16, 1, 6, 4, 0, 0, 0, 0, - 0, 0, 0, 17, 43, 39, 11, 0, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, - 39, 9, 12, 3, 5, 26, 35, 1, 0, 0, 2, 6, 11, 0, 11, 1, 11, 2, - 17, 44, 56, 24, 2, 46, 1, 0, 1, 4, 63, 30, 7, 0, 43, 4, 16, 9, - 12, 0, 64, 20, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 10, 0, 56, 25, - 12, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 10, 3, 10, 2, 35, - 4, 26, 13, 1, 10, 0, 10, 3, 56, 26, 20, 68, 20, 11, 3, 6, 1, 0, - 0, 0, 0, 0, 0, 0, 22, 12, 3, 5, 11, 11, 0, 1, 11, 1, 2, 49, - 3, 0, 2, 1, 3, 69, 85, 11, 1, 17, 30, 12, 3, 10, 3, 10, 2, 17, - 32, 14, 2, 56, 0, 43, 3, 12, 4, 14, 2, 56, 0, 42, 1, 12, 5, 10, - 5, 16, 14, 10, 3, 56, 27, 4, 82, 10, 5, 15, 14, 10, 3, 56, 28, 12, - 6, 10, 5, 16, 15, 10, 3, 56, 27, 4, 77, 11, 5, 15, 15, 11, 3, 56, - 28, 12, 7, 10, 6, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 36, 4, 70, 10, 0, 10, 4, 16, 4, 20, 11, 6, 52, 56, - 4, 12, 8, 10, 7, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 36, 4, 61, 11, 0, 11, 4, 16, 6, 20, 11, 7, 52, 56, - 4, 12, 9, 11, 8, 11, 9, 2, 11, 0, 1, 11, 4, 16, 6, 20, 56, 2, - 56, 29, 12, 9, 5, 58, 10, 4, 16, 4, 20, 56, 2, 56, 29, 12, 8, 5, - 46, 11, 5, 1, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 7, 5, 34, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 6, 5, 24, 53, 1, 0, 1, 1, 73, 21, 14, - 1, 56, 0, 43, 1, 12, 2, 10, 2, 16, 14, 10, 0, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 14, 3, 56, 30, - 20, 11, 2, 16, 15, 11, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 4, 14, 4, 56, 30, 20, 2, 55, 1, 0, 1, - 3, 2, 6, 14, 0, 56, 0, 43, 3, 16, 3, 20, 2, 25, 0, 0, 0, 2, - 8, 10, 0, 17, 56, 10, 0, 17, 57, 11, 0, 17, 58, 18, 2, 2, 31, 0, - 0, 1, 3, 38, 22, 10, 0, 10, 1, 56, 31, 1, 11, 0, 10, 1, 56, 32, - 12, 2, 10, 2, 56, 33, 4, 12, 5, 20, 14, 1, 56, 34, 43, 3, 16, 11, - 16, 12, 10, 2, 8, 56, 35, 11, 2, 2, 3, 1, 0, 1, 3, 80, 124, 14, - 0, 56, 0, 43, 3, 12, 3, 10, 3, 16, 1, 20, 56, 1, 77, 12, 4, 10, - 3, 16, 2, 20, 56, 1, 77, 12, 5, 11, 1, 10, 3, 16, 1, 20, 56, 2, - 33, 4, 119, 11, 4, 12, 6, 11, 5, 12, 7, 10, 2, 12, 8, 10, 3, 16, - 16, 20, 12, 9, 11, 8, 53, 11, 9, 53, 24, 50, 16, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 52, 12, 10, 11, 2, 10, 10, - 23, 77, 12, 11, 10, 3, 16, 3, 20, 4, 103, 11, 3, 12, 12, 10, 12, 16, - 1, 20, 56, 1, 77, 12, 13, 10, 12, 16, 2, 20, 56, 1, 77, 12, 14, 11, - 12, 16, 3, 20, 4, 98, 10, 13, 10, 13, 24, 10, 13, 24, 10, 14, 24, 10, - 14, 10, 14, 24, 11, 14, 24, 11, 13, 24, 22, 12, 15, 10, 7, 11, 11, 11, - 6, 22, 11, 15, 11, 7, 17, 63, 23, 12, 16, 11, 16, 52, 11, 10, 2, 11, - 13, 11, 14, 24, 12, 15, 5, 85, 11, 3, 1, 10, 11, 11, 7, 24, 11, 6, - 11, 11, 22, 26, 12, 16, 5, 94, 11, 3, 1, 6, 4, 0, 0, 0, 0, 0, - 0, 0, 17, 43, 39, 11, 5, 12, 6, 11, 4, 12, 7, 5, 27, 63, 0, 0, - 0, 81, 114, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 10, 3, 6, 255, - 0, 0, 0, 0, 0, 0, 0, 35, 4, 112, 10, 2, 12, 4, 10, 0, 12, 5, - 10, 2, 12, 6, 10, 5, 10, 6, 10, 6, 24, 10, 6, 24, 24, 10, 5, 10, - 5, 24, 11, 5, 24, 11, 6, 24, 22, 12, 5, 10, 5, 10, 1, 35, 4, 85, - 10, 1, 11, 5, 23, 10, 0, 12, 7, 10, 2, 12, 8, 74, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 24, 10, 8, 11, 8, 24, - 24, 10, 7, 10, 7, 24, 11, 7, 24, 22, 26, 12, 6, 11, 2, 11, 6, 22, - 12, 2, 10, 2, 10, 4, 36, 4, 76, 10, 2, 11, 4, 23, 74, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 3, 69, 5, 71, 11, 2, - 2, 11, 3, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 3, 5, 2, 11, - 4, 10, 2, 23, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 37, 3, 83, 5, 71, 11, 2, 2, 11, 5, 10, 1, 23, 10, 0, 12, 7, - 10, 2, 12, 8, 74, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 7, 24, 10, 8, 11, 8, 24, 24, 10, 7, 10, 7, 24, 11, 7, 24, - 22, 26, 12, 5, 11, 2, 11, 5, 23, 12, 2, 5, 58, 11, 2, 2, 64, 0, - 0, 0, 2, 8, 11, 0, 56, 36, 9, 6, 10, 0, 0, 0, 0, 0, 0, 0, - 6, 20, 0, 0, 0, 0, 0, 0, 0, 18, 4, 45, 4, 2, 44, 1, 0, 0, - 84, 32, 7, 0, 12, 3, 14, 3, 11, 0, 12, 4, 11, 1, 12, 5, 11, 2, - 12, 6, 64, 26, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 13, 7, 14, 4, - 56, 7, 12, 8, 14, 8, 56, 8, 56, 9, 13, 7, 14, 5, 56, 7, 12, 9, - 14, 9, 56, 8, 56, 9, 13, 7, 14, 6, 56, 10, 56, 9, 11, 7, 17, 66, - 2, 67, 1, 0, 0, 11, 9, 11, 0, 11, 1, 11, 2, 17, 44, 12, 3, 10, - 3, 41, 3, 11, 3, 2, 68, 1, 0, 0, 2, 4, 11, 0, 56, 37, 56, 21, - 2, 69, 1, 0, 0, 2, 2, 6, 232, 3, 0, 0, 0, 0, 0, 0, 2, 70, - 1, 0, 1, 3, 86, 13, 14, 0, 56, 34, 43, 3, 12, 1, 10, 1, 16, 1, - 20, 56, 1, 11, 1, 16, 2, 20, 56, 1, 2, 71, 1, 0, 1, 3, 86, 14, - 14, 0, 56, 0, 43, 3, 12, 1, 10, 1, 16, 1, 20, 56, 2, 11, 1, 16, - 2, 20, 56, 2, 64, 4, 2, 0, 0, 0, 0, 0, 0, 0, 2, 72, 1, 0, - 1, 3, 2, 6, 14, 0, 56, 0, 43, 3, 16, 16, 20, 2, 73, 1, 0, 1, - 4, 2, 5, 7, 0, 43, 4, 16, 9, 56, 25, 2, 32, 1, 4, 1, 1, 90, - 138, 1, 14, 1, 56, 0, 42, 1, 12, 2, 10, 2, 16, 5, 20, 12, 3, 10, - 2, 16, 7, 20, 12, 4, 10, 0, 10, 1, 56, 38, 53, 12, 5, 11, 1, 56, - 39, 12, 6, 10, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 36, 3, 25, 5, 117, 10, 2, 16, 17, 10, 0, 56, 40, 20, - 12, 7, 10, 2, 16, 18, 10, 0, 56, 40, 20, 12, 8, 10, 3, 11, 7, 23, - 12, 7, 10, 4, 11, 8, 23, 12, 8, 10, 5, 12, 9, 10, 6, 12, 10, 10, - 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 4, 133, 1, 11, 7, 77, 11, 9, 77, 24, 11, 10, 77, 26, 53, 12, 11, - 11, 8, 12, 12, 11, 5, 12, 13, 11, 6, 12, 14, 10, 14, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 4, 128, 1, 11, - 12, 77, 11, 13, 77, 24, 11, 14, 77, 26, 53, 12, 15, 10, 11, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 3, 88, 5, - 100, 10, 2, 15, 14, 10, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 41, 12, 16, 10, 16, 20, 11, 11, 22, 11, 16, - 21, 10, 15, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 36, 3, 105, 5, 117, 10, 2, 15, 15, 10, 0, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 41, 12, 16, 10, 16, - 20, 11, 15, 22, 11, 16, 21, 10, 2, 15, 17, 10, 0, 11, 3, 56, 42, 11, - 2, 15, 18, 11, 0, 11, 4, 56, 42, 2, 11, 2, 1, 6, 4, 0, 0, 0, - 0, 0, 0, 0, 17, 43, 39, 11, 2, 1, 6, 4, 0, 0, 0, 0, 0, 0, - 0, 17, 43, 39, 4, 1, 3, 0, 3, 1, 3, 6, 3, 2, 1, 0, 3, 3, - 1, 1, 4, 2, 4, 0, 4, 3, 3, 4, 2, 2, 2, 1, 1, 4, 1, 5, - 3, 5, 1, 2, 1, 3, 0, 127, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_COMPLEX_LIQUIDITY_POOL_WRAPPER: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 16, 2, 16, 40, 3, 56, 130, - 1, 4, 186, 1, 8, 5, 194, 1, 233, 1, 7, 171, 3, 250, 3, 8, 165, 7, - 64, 6, 229, 7, 56, 16, 157, 8, 108, 10, 137, 9, 27, 12, 164, 9, 177, 3, - 13, 213, 12, 10, 0, 0, 1, 4, 0, 6, 1, 9, 1, 15, 1, 17, 1, 27, - 1, 30, 0, 1, 8, 0, 1, 3, 7, 1, 0, 1, 2, 5, 8, 0, 3, 8, - 6, 0, 3, 12, 11, 0, 3, 20, 0, 0, 1, 26, 2, 0, 6, 29, 7, 1, - 0, 0, 7, 32, 7, 0, 0, 14, 0, 1, 0, 1, 4, 16, 2, 3, 0, 1, - 5, 18, 5, 6, 1, 8, 1, 5, 19, 7, 8, 1, 8, 1, 2, 14, 9, 8, - 0, 1, 5, 21, 10, 1, 0, 1, 3, 22, 11, 8, 0, 1, 0, 23, 13, 1, - 0, 1, 2, 22, 14, 1, 0, 1, 0, 24, 15, 16, 0, 1, 1, 25, 15, 17, - 0, 1, 6, 28, 1, 19, 1, 0, 1, 7, 31, 20, 21, 0, 1, 5, 33, 22, - 1, 0, 1, 3, 34, 23, 16, 0, 1, 0, 35, 25, 26, 0, 1, 3, 36, 27, - 28, 0, 1, 2, 37, 29, 30, 0, 1, 0, 38, 25, 1, 0, 1, 0, 39, 32, - 1, 0, 1, 2, 40, 35, 36, 1, 8, 1, 2, 4, 3, 4, 11, 18, 20, 34, - 4, 6, 12, 6, 12, 3, 1, 0, 1, 6, 12, 1, 5, 1, 8, 4, 2, 5, - 11, 1, 1, 9, 0, 1, 3, 3, 6, 12, 11, 1, 1, 9, 0, 3, 1, 8, - 5, 3, 6, 12, 11, 1, 1, 8, 2, 8, 5, 2, 5, 8, 5, 2, 6, 8, - 3, 3, 5, 6, 8, 0, 11, 1, 1, 8, 4, 6, 8, 3, 8, 5, 8, 5, - 6, 6, 12, 6, 8, 3, 6, 8, 3, 3, 3, 1, 4, 6, 12, 8, 5, 8, - 5, 1, 2, 6, 12, 10, 2, 1, 8, 3, 1, 8, 6, 1, 4, 1, 11, 7, - 1, 9, 0, 1, 10, 2, 1, 8, 8, 7, 6, 8, 6, 11, 7, 1, 4, 8, - 8, 8, 8, 2, 8, 8, 8, 8, 1, 6, 8, 6, 2, 8, 6, 6, 8, 6, - 2, 6, 12, 1, 3, 11, 1, 1, 8, 2, 8, 3, 8, 3, 1, 6, 8, 3, - 1, 11, 1, 1, 8, 4, 4, 6, 12, 11, 1, 1, 8, 4, 11, 1, 1, 8, - 4, 1, 1, 11, 1, 1, 8, 2, 2, 8, 3, 8, 3, 3, 11, 1, 1, 8, - 2, 3, 3, 5, 8, 3, 8, 3, 11, 1, 1, 8, 2, 11, 1, 1, 8, 4, - 11, 1, 1, 8, 4, 1, 8, 2, 1, 11, 1, 1, 9, 0, 2, 3, 3, 22, - 108, 105, 113, 117, 105, 100, 105, 116, 121, 95, 112, 111, 111, 108, 95, 119, 114, 97, - 112, 112, 101, 114, 9, 65, 100, 100, 114, 101, 115, 115, 101, 115, 4, 112, 111, 111, - 108, 6, 79, 98, 106, 101, 99, 116, 6, 111, 98, 106, 101, 99, 116, 13, 76, 105, - 113, 117, 105, 100, 105, 116, 121, 80, 111, 111, 108, 14, 108, 105, 113, 117, 105, 100, - 105, 116, 121, 95, 112, 111, 111, 108, 12, 116, 111, 107, 101, 110, 95, 49, 95, 109, - 105, 110, 116, 7, 77, 105, 110, 116, 82, 101, 102, 14, 102, 117, 110, 103, 105, 98, - 108, 101, 95, 97, 115, 115, 101, 116, 12, 116, 111, 107, 101, 110, 95, 50, 95, 109, - 105, 110, 116, 7, 116, 111, 107, 101, 110, 95, 49, 8, 77, 101, 116, 97, 100, 97, - 116, 97, 7, 116, 111, 107, 101, 110, 95, 50, 4, 115, 119, 97, 112, 6, 115, 105, - 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 22, 112, 114, - 105, 109, 97, 114, 121, 95, 102, 117, 110, 103, 105, 98, 108, 101, 95, 115, 116, 111, - 114, 101, 7, 98, 97, 108, 97, 110, 99, 101, 8, 119, 105, 116, 104, 100, 114, 97, - 119, 13, 70, 117, 110, 103, 105, 98, 108, 101, 65, 115, 115, 101, 116, 7, 100, 101, - 112, 111, 115, 105, 116, 4, 109, 105, 110, 116, 13, 97, 100, 100, 95, 108, 105, 113, - 117, 105, 100, 105, 116, 121, 21, 99, 114, 101, 97, 116, 101, 95, 102, 117, 110, 103, - 105, 98, 108, 101, 95, 97, 115, 115, 101, 116, 19, 99, 114, 101, 97, 116, 101, 95, - 110, 97, 109, 101, 100, 95, 111, 98, 106, 101, 99, 116, 14, 67, 111, 110, 115, 116, - 114, 117, 99, 116, 111, 114, 82, 101, 102, 6, 111, 112, 116, 105, 111, 110, 4, 110, - 111, 110, 101, 6, 79, 112, 116, 105, 111, 110, 6, 115, 116, 114, 105, 110, 103, 4, - 117, 116, 102, 56, 6, 83, 116, 114, 105, 110, 103, 43, 99, 114, 101, 97, 116, 101, - 95, 112, 114, 105, 109, 97, 114, 121, 95, 115, 116, 111, 114, 101, 95, 101, 110, 97, - 98, 108, 101, 100, 95, 102, 117, 110, 103, 105, 98, 108, 101, 95, 97, 115, 115, 101, - 116, 17, 103, 101, 110, 101, 114, 97, 116, 101, 95, 109, 105, 110, 116, 95, 114, 101, - 102, 11, 99, 114, 101, 97, 116, 101, 95, 112, 111, 111, 108, 17, 109, 105, 110, 116, - 95, 114, 101, 102, 95, 109, 101, 116, 97, 100, 97, 116, 97, 6, 99, 114, 101, 97, - 116, 101, 22, 105, 110, 105, 116, 105, 97, 108, 105, 122, 101, 95, 108, 105, 113, 117, - 105, 100, 95, 112, 97, 105, 114, 15, 118, 101, 114, 105, 102, 121, 95, 114, 101, 115, - 101, 114, 118, 101, 115, 13, 112, 111, 111, 108, 95, 114, 101, 115, 101, 114, 118, 101, - 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171, 205, 10, 2, 1, 0, 10, 2, 6, 5, 116, - 101, 115, 116, 49, 10, 2, 6, 5, 116, 101, 115, 116, 50, 20, 99, 111, 109, 112, - 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, - 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, - 116, 97, 100, 97, 116, 97, 95, 118, 49, 57, 2, 1, 0, 0, 0, 0, 0, 0, - 0, 20, 69, 65, 68, 68, 82, 69, 83, 83, 69, 83, 95, 78, 79, 84, 95, 70, - 79, 85, 78, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 69, 78, 79, 84, - 95, 80, 85, 66, 76, 73, 83, 72, 69, 82, 0, 0, 0, 0, 2, 5, 2, 11, - 1, 1, 8, 2, 7, 8, 3, 10, 8, 3, 11, 11, 1, 1, 8, 4, 13, 11, - 1, 1, 8, 4, 0, 1, 4, 1, 0, 12, 71, 10, 1, 17, 1, 7, 0, 33, - 4, 65, 7, 0, 41, 0, 4, 59, 7, 0, 43, 0, 12, 4, 11, 3, 4, 51, - 10, 4, 16, 0, 20, 12, 5, 10, 4, 16, 1, 12, 6, 10, 0, 17, 1, 10, - 5, 56, 0, 10, 2, 38, 4, 46, 11, 6, 1, 10, 0, 11, 5, 11, 2, 56, - 1, 12, 7, 11, 1, 11, 4, 16, 2, 20, 11, 7, 17, 4, 12, 8, 11, 0, - 17, 1, 11, 8, 17, 5, 2, 11, 6, 11, 2, 17, 6, 12, 7, 5, 34, 10, - 4, 16, 3, 20, 12, 5, 10, 4, 16, 4, 12, 6, 5, 20, 11, 0, 1, 11, - 1, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 39, 11, 0, 1, 11, 1, 1, - 6, 2, 0, 0, 0, 0, 0, 0, 0, 39, 7, 1, 0, 0, 1, 10, 11, 0, - 11, 1, 11, 3, 17, 6, 11, 2, 11, 4, 17, 6, 11, 5, 17, 8, 2, 9, - 1, 0, 0, 24, 21, 11, 0, 10, 1, 17, 10, 12, 2, 14, 2, 12, 3, 10, - 3, 56, 2, 10, 1, 17, 12, 11, 1, 17, 12, 49, 8, 7, 1, 17, 12, 7, - 1, 17, 12, 17, 13, 11, 3, 17, 14, 2, 15, 1, 0, 0, 31, 18, 10, 0, - 7, 2, 17, 9, 12, 2, 10, 0, 7, 3, 17, 9, 12, 3, 11, 0, 14, 2, - 17, 16, 14, 3, 17, 16, 11, 1, 17, 17, 11, 2, 11, 3, 2, 18, 1, 4, - 0, 33, 44, 10, 0, 17, 1, 7, 0, 33, 4, 40, 10, 0, 10, 1, 17, 15, - 12, 2, 12, 3, 12, 4, 10, 0, 14, 3, 14, 2, 6, 0, 225, 245, 5, 0, - 0, 0, 0, 6, 0, 194, 235, 11, 0, 0, 0, 0, 10, 1, 17, 7, 11, 1, - 4, 21, 5, 25, 10, 4, 6, 0, 225, 245, 5, 0, 0, 0, 0, 6, 0, 194, - 235, 11, 0, 0, 0, 0, 17, 19, 14, 3, 17, 16, 12, 5, 14, 2, 17, 16, - 12, 6, 11, 0, 11, 4, 11, 3, 11, 2, 11, 5, 11, 6, 18, 0, 45, 0, - 2, 11, 0, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 39, 19, 0, 0, 0, - 6, 15, 11, 0, 56, 3, 12, 3, 11, 1, 33, 4, 13, 11, 3, 11, 2, 33, - 4, 11, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 39, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 39, 0, 3, 0, 1, 0, 0, 0, 4, 0, 2, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_COMPLEX_SMART_TABLE_PICTURE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 11, 1, 0, 10, 2, 10, 20, 3, 30, 65, - 4, 95, 8, 5, 103, 73, 7, 176, 1, 226, 1, 8, 146, 3, 64, 16, 210, 3, - 190, 1, 10, 144, 5, 15, 12, 159, 5, 136, 2, 13, 167, 7, 4, 0, 0, 1, - 6, 1, 8, 1, 12, 1, 15, 0, 1, 8, 0, 0, 3, 8, 0, 1, 5, 4, - 2, 0, 0, 0, 0, 4, 17, 2, 0, 0, 7, 0, 1, 0, 1, 2, 9, 5, - 6, 1, 0, 1, 1, 10, 8, 1, 2, 3, 2, 1, 0, 11, 10, 1, 0, 1, - 3, 13, 10, 2, 0, 1, 1, 14, 1, 11, 2, 7, 4, 1, 4, 16, 2, 12, - 0, 1, 4, 18, 13, 14, 0, 1, 4, 19, 13, 2, 0, 1, 0, 20, 10, 1, - 0, 1, 1, 3, 1, 4, 2, 7, 5, 7, 4, 5, 3, 10, 3, 10, 2, 0, - 1, 5, 1, 3, 1, 2, 1, 6, 10, 9, 0, 1, 1, 2, 14, 2, 3, 7, - 11, 2, 2, 9, 0, 9, 1, 9, 0, 9, 1, 4, 7, 8, 1, 3, 14, 2, - 1, 6, 12, 1, 11, 2, 2, 9, 0, 9, 1, 1, 8, 3, 1, 6, 8, 3, - 1, 12, 5, 5, 8, 1, 8, 3, 12, 10, 5, 19, 115, 109, 97, 114, 116, 95, - 116, 97, 98, 108, 101, 95, 112, 105, 99, 116, 117, 114, 101, 11, 65, 108, 108, 80, - 97, 108, 101, 116, 116, 101, 115, 3, 97, 108, 108, 7, 80, 97, 108, 101, 116, 116, - 101, 6, 112, 105, 120, 101, 108, 115, 10, 83, 109, 97, 114, 116, 84, 97, 98, 108, - 101, 11, 115, 109, 97, 114, 116, 95, 116, 97, 98, 108, 101, 6, 117, 112, 100, 97, - 116, 101, 6, 118, 101, 99, 116, 111, 114, 8, 105, 115, 95, 101, 109, 112, 116, 121, - 6, 117, 112, 115, 101, 114, 116, 6, 99, 114, 101, 97, 116, 101, 6, 115, 105, 103, - 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 3, 110, 101, 119, - 6, 111, 98, 106, 101, 99, 116, 13, 99, 114, 101, 97, 116, 101, 95, 111, 98, 106, - 101, 99, 116, 14, 67, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 82, 101, 102, - 15, 103, 101, 110, 101, 114, 97, 116, 101, 95, 115, 105, 103, 110, 101, 114, 28, 97, - 100, 100, 114, 101, 115, 115, 95, 102, 114, 111, 109, 95, 99, 111, 110, 115, 116, 114, - 117, 99, 116, 111, 114, 95, 114, 101, 102, 11, 105, 110, 105, 116, 95, 109, 111, 100, - 117, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, - 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, - 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, - 116, 97, 100, 97, 116, 97, 95, 118, 49, 138, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 21, 69, 95, 73, 78, 68, 69, 88, 95, 79, 85, 84, 95, 79, 70, 95, - 66, 79, 85, 78, 68, 83, 68, 84, 104, 101, 32, 99, 97, 108, 108, 101, 114, 32, - 116, 114, 105, 101, 100, 32, 116, 111, 32, 109, 117, 116, 97, 116, 101, 32, 97, 110, - 32, 105, 116, 101, 109, 32, 111, 117, 116, 115, 105, 100, 101, 32, 116, 104, 101, 32, - 98, 111, 117, 110, 100, 115, 32, 111, 102, 32, 116, 104, 101, 32, 118, 101, 99, 116, - 111, 114, 46, 1, 7, 80, 97, 108, 101, 116, 116, 101, 1, 3, 1, 24, 48, 120, - 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, 106, 101, 99, 116, 71, - 114, 111, 117, 112, 0, 0, 2, 1, 2, 10, 5, 1, 2, 1, 4, 11, 2, 2, - 14, 2, 0, 1, 4, 2, 0, 1, 9, 61, 11, 0, 43, 0, 16, 0, 11, 1, - 66, 2, 20, 42, 1, 12, 4, 14, 2, 65, 3, 14, 3, 65, 4, 33, 4, 57, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 14, 2, 65, 3, 12, 5, 10, - 1, 10, 5, 35, 4, 54, 14, 2, 56, 0, 3, 50, 13, 2, 69, 3, 76, 12, - 6, 14, 3, 56, 1, 3, 46, 13, 3, 69, 4, 12, 7, 10, 4, 15, 1, 11, - 6, 11, 7, 56, 2, 11, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, - 1, 5, 19, 11, 4, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 39, 11, 4, - 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 39, 11, 4, 1, 2, 11, 4, 1, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 39, 3, 1, 4, 1, 0, 15, 38, 10, - 0, 17, 4, 12, 1, 56, 3, 18, 1, 12, 2, 10, 1, 17, 6, 12, 3, 14, - 3, 17, 7, 12, 4, 14, 4, 11, 2, 45, 1, 10, 1, 41, 0, 3, 29, 64, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 12, 5, 13, 5, 14, 3, 17, 8, 68, - 2, 11, 0, 11, 5, 18, 0, 45, 0, 2, 11, 0, 1, 11, 1, 42, 0, 15, - 0, 14, 3, 17, 8, 68, 2, 5, 28, 9, 0, 0, 0, 1, 5, 11, 0, 64, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 45, 0, 2, 0, 0, 1, 0, - 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_COMPLEX_VECTOR_PICTURE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 10, 1, 0, 8, 2, 8, 16, 3, 24, 54, - 5, 78, 63, 7, 141, 1, 209, 1, 8, 222, 2, 64, 16, 158, 3, 232, 1, 10, - 134, 5, 22, 12, 156, 5, 236, 2, 13, 136, 8, 10, 0, 0, 1, 10, 1, 13, - 1, 15, 0, 1, 8, 0, 0, 3, 8, 0, 0, 5, 7, 0, 3, 17, 2, 0, - 0, 9, 0, 1, 0, 1, 1, 11, 4, 4, 0, 1, 0, 12, 6, 1, 0, 1, - 2, 14, 7, 2, 0, 1, 3, 16, 2, 8, 0, 1, 3, 18, 9, 10, 0, 1, - 3, 19, 9, 2, 0, 1, 0, 20, 7, 1, 0, 1, 0, 21, 12, 1, 0, 1, - 6, 5, 3, 3, 2, 2, 2, 0, 1, 5, 1, 8, 2, 1, 3, 1, 7, 8, - 1, 2, 6, 12, 3, 1, 6, 12, 1, 8, 3, 1, 6, 8, 3, 1, 12, 8, - 5, 8, 2, 10, 8, 2, 3, 8, 1, 8, 3, 12, 10, 5, 3, 5, 3, 3, - 4, 7, 8, 1, 6, 8, 2, 1, 1, 14, 118, 101, 99, 116, 111, 114, 95, 112, - 105, 99, 116, 117, 114, 101, 11, 65, 108, 108, 80, 97, 108, 101, 116, 116, 101, 115, - 3, 97, 108, 108, 7, 80, 97, 108, 101, 116, 116, 101, 3, 118, 101, 99, 5, 67, - 111, 108, 111, 114, 1, 114, 1, 103, 1, 98, 6, 117, 112, 100, 97, 116, 101, 5, - 101, 114, 114, 111, 114, 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, - 109, 101, 110, 116, 6, 99, 114, 101, 97, 116, 101, 6, 115, 105, 103, 110, 101, 114, - 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 6, 111, 98, 106, 101, 99, 116, - 13, 99, 114, 101, 97, 116, 101, 95, 111, 98, 106, 101, 99, 116, 14, 67, 111, 110, - 115, 116, 114, 117, 99, 116, 111, 114, 82, 101, 102, 15, 103, 101, 110, 101, 114, 97, - 116, 101, 95, 115, 105, 103, 110, 101, 114, 28, 97, 100, 100, 114, 101, 115, 115, 95, - 102, 114, 111, 109, 95, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 95, 114, - 101, 102, 11, 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 5, 99, 104, 101, - 99, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, 105, - 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, - 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, 116, - 97, 100, 97, 116, 97, 95, 118, 49, 180, 1, 2, 1, 0, 0, 0, 0, 0, 0, - 0, 21, 69, 95, 73, 78, 68, 69, 88, 95, 79, 85, 84, 95, 79, 70, 95, 66, - 79, 85, 78, 68, 83, 68, 84, 104, 101, 32, 99, 97, 108, 108, 101, 114, 32, 116, - 114, 105, 101, 100, 32, 116, 111, 32, 109, 117, 116, 97, 116, 101, 32, 97, 110, 32, - 105, 116, 101, 109, 32, 111, 117, 116, 115, 105, 100, 101, 32, 116, 104, 101, 32, 98, - 111, 117, 110, 100, 115, 32, 111, 102, 32, 116, 104, 101, 32, 118, 101, 99, 116, 111, - 114, 46, 3, 0, 0, 0, 0, 0, 0, 0, 11, 69, 95, 77, 65, 88, 95, 67, - 79, 76, 79, 82, 21, 67, 111, 108, 111, 114, 32, 99, 104, 101, 99, 107, 101, 100, - 32, 105, 115, 32, 109, 97, 120, 46, 1, 7, 80, 97, 108, 101, 116, 116, 101, 1, - 3, 1, 24, 48, 120, 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, - 106, 101, 99, 116, 71, 114, 111, 117, 112, 0, 0, 2, 1, 2, 10, 5, 1, 2, - 1, 4, 10, 8, 2, 2, 2, 3, 6, 2, 7, 2, 8, 2, 0, 1, 4, 2, - 0, 1, 5, 29, 11, 0, 43, 0, 16, 0, 11, 1, 66, 2, 20, 42, 1, 12, - 6, 10, 2, 10, 6, 16, 1, 65, 3, 35, 4, 24, 11, 3, 11, 4, 11, 5, - 18, 2, 11, 6, 15, 1, 11, 2, 67, 3, 21, 2, 11, 6, 1, 6, 1, 0, - 0, 0, 0, 0, 0, 0, 17, 1, 39, 2, 1, 4, 1, 0, 11, 59, 10, 0, - 17, 3, 12, 2, 49, 124, 49, 213, 49, 37, 18, 2, 12, 3, 64, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, - 5, 10, 5, 10, 1, 35, 4, 24, 13, 4, 10, 3, 68, 3, 11, 5, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 12, 5, 5, 12, 11, 4, 18, 1, 12, 6, - 10, 2, 17, 4, 12, 7, 14, 7, 17, 5, 12, 8, 14, 8, 11, 6, 45, 1, - 10, 2, 41, 0, 3, 50, 64, 2, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, - 13, 9, 14, 7, 17, 6, 68, 2, 11, 0, 11, 9, 18, 0, 45, 0, 2, 11, - 0, 1, 11, 2, 42, 0, 15, 0, 14, 7, 17, 6, 68, 2, 5, 49, 7, 0, - 0, 0, 1, 5, 11, 0, 64, 2, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, - 45, 0, 2, 8, 1, 4, 2, 0, 1, 13, 58, 11, 0, 43, 0, 16, 0, 11, - 1, 66, 2, 20, 42, 1, 12, 3, 10, 2, 10, 3, 16, 1, 65, 3, 35, 4, - 53, 11, 3, 16, 1, 11, 2, 66, 3, 12, 4, 10, 4, 16, 2, 20, 49, 255, - 34, 4, 46, 8, 12, 5, 11, 5, 4, 39, 11, 4, 1, 8, 12, 6, 11, 6, - 4, 36, 2, 6, 3, 0, 0, 0, 0, 0, 0, 0, 17, 1, 39, 11, 4, 16, - 3, 20, 49, 255, 34, 12, 6, 5, 33, 10, 4, 16, 4, 20, 49, 255, 34, 12, - 5, 5, 27, 11, 3, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 1, 39, - 0, 0, 1, 0, 2, 0, 2, 2, 2, 1, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_COMPLEX: Lazy>> = Lazy::new(|| { vec![ - MODULE_COMPLEX_LIQUIDITY_POOL.to_vec(), - MODULE_COMPLEX_LIQUIDITY_POOL_WRAPPER.to_vec(), - MODULE_COMPLEX_SMART_TABLE_PICTURE.to_vec(), - MODULE_COMPLEX_VECTOR_PICTURE.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_AMBASSADOR_TOKEN_METADATA: Lazy> = Lazy::new(|| { - vec![ - 10, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 64, 68, 70, 50, 57, 50, 70, 53, 53, 56, 50, 66, 48, 57, 50, 65, - 51, 54, 55, 65, 53, 69, 55, 69, 57, 65, 48, 48, 69, 66, 51, 68, 57, 52, - 48, 55, 56, 67, 49, 54, 69, 65, 66, 65, 48, 50, 52, 69, 65, 65, 50, 52, - 57, 52, 49, 55, 70, 54, 50, 51, 52, 53, 67, 50, 48, 253, 1, 31, 139, 8, - 0, 0, 0, 0, 0, 2, 255, 173, 142, 63, 79, 195, 64, 12, 197, 247, 251, 20, - 86, 24, 186, 144, 63, 172, 72, 12, 21, 162, 43, 11, 91, 84, 161, 203, 157, 155, - 28, 73, 236, 232, 236, 20, 36, 196, 119, 231, 142, 22, 144, 16, 99, 55, 219, 239, - 249, 253, 94, 187, 88, 55, 218, 30, 247, 134, 236, 140, 112, 7, 27, 59, 119, 86, - 196, 122, 142, 27, 115, 196, 40, 129, 41, 159, 111, 170, 166, 106, 54, 198, 92, 129, - 103, 32, 86, 112, 131, 165, 30, 65, 25, 138, 231, 226, 26, 28, 147, 139, 168, 8, - 214, 251, 136, 34, 64, 136, 30, 61, 28, 56, 194, 204, 126, 157, 176, 92, 214, 110, - 10, 50, 128, 162, 104, 160, 30, 14, 49, 33, 95, 57, 142, 166, 61, 63, 161, 236, - 205, 47, 63, 97, 139, 230, 237, 126, 187, 123, 40, 140, 105, 61, 46, 72, 30, 201, - 133, 236, 218, 46, 202, 178, 251, 14, 72, 206, 119, 232, 131, 230, 143, 65, 117, 145, - 219, 186, 78, 235, 176, 118, 149, 227, 185, 182, 217, 92, 78, 182, 147, 243, 248, 67, - 174, 146, 43, 149, 151, 181, 243, 225, 139, 247, 71, 79, 90, 196, 99, 22, 102, 27, - 136, 80, 11, 248, 56, 177, 159, 120, 68, 122, 236, 94, 208, 169, 92, 26, 175, 57, - 187, 228, 83, 248, 191, 21, 62, 1, 7, 30, 19, 174, 183, 1, 0, 0, 1, 10, - 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 0, 0, 0, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, 111, 115, 70, 114, - 97, 109, 101, 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, 83, 116, - 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 17, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 79, 98, 106, 101, 99, 116, 115, - 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_AMBASSADOR_TOKEN_AMBASSADOR: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 24, 2, 24, 60, 3, 84, 157, - 2, 4, 241, 2, 18, 5, 131, 3, 212, 2, 7, 215, 5, 189, 8, 8, 148, 14, - 96, 6, 244, 14, 136, 1, 16, 252, 15, 249, 4, 10, 245, 20, 33, 12, 150, 21, - 213, 5, 13, 235, 26, 8, 0, 0, 1, 6, 1, 10, 2, 13, 2, 16, 2, 22, - 2, 24, 2, 34, 1, 39, 2, 40, 1, 43, 2, 69, 0, 1, 8, 0, 0, 3, - 8, 0, 1, 5, 6, 0, 1, 8, 6, 0, 2, 5, 6, 0, 3, 12, 7, 0, - 0, 14, 6, 0, 4, 15, 7, 1, 0, 1, 8, 38, 11, 0, 9, 42, 7, 1, - 0, 0, 4, 45, 2, 0, 4, 54, 6, 0, 4, 58, 2, 0, 2, 62, 10, 0, - 0, 19, 0, 1, 0, 1, 4, 20, 3, 4, 1, 8, 1, 1, 21, 5, 4, 1, - 8, 1, 5, 23, 6, 4, 0, 1, 2, 19, 7, 1, 0, 1, 1, 19, 8, 1, - 0, 1, 6, 25, 9, 9, 0, 1, 6, 26, 9, 9, 0, 1, 0, 2, 11, 9, - 0, 1, 0, 27, 4, 9, 0, 1, 4, 28, 4, 5, 1, 8, 1, 0, 29, 11, - 12, 0, 1, 3, 30, 13, 12, 0, 1, 2, 31, 14, 12, 1, 8, 1, 0, 32, - 4, 12, 0, 1, 0, 33, 15, 1, 0, 1, 7, 35, 16, 12, 1, 0, 1, 1, - 36, 17, 4, 0, 1, 0, 37, 6, 1, 0, 1, 9, 41, 1, 20, 1, 0, 1, - 10, 44, 21, 22, 0, 1, 0, 46, 6, 1, 0, 1, 0, 47, 24, 1, 0, 1, - 0, 48, 25, 1, 0, 1, 0, 49, 26, 1, 0, 1, 3, 50, 27, 1, 0, 1, - 1, 51, 28, 22, 0, 1, 4, 52, 29, 30, 0, 1, 4, 53, 29, 31, 0, 1, - 1, 55, 29, 32, 0, 1, 1, 56, 29, 8, 0, 1, 2, 55, 29, 7, 0, 1, - 4, 57, 33, 34, 0, 1, 4, 59, 35, 1, 0, 1, 4, 60, 33, 1, 0, 1, - 2, 61, 36, 37, 0, 1, 2, 63, 38, 1, 0, 1, 2, 64, 39, 1, 1, 2, - 1, 1, 65, 40, 22, 0, 1, 0, 66, 24, 1, 0, 1, 0, 67, 42, 1, 0, - 1, 0, 68, 43, 1, 0, 1, 11, 70, 45, 1, 1, 6, 1, 0, 71, 46, 1, - 0, 1, 2, 72, 48, 1, 1, 2, 1, 1, 73, 49, 1, 0, 1, 1, 2, 2, - 2, 10, 2, 13, 2, 16, 4, 19, 19, 37, 12, 42, 44, 44, 12, 2, 6, 12, - 11, 7, 1, 8, 1, 0, 1, 8, 1, 1, 6, 11, 7, 1, 9, 0, 1, 5, - 1, 11, 7, 1, 9, 0, 1, 6, 12, 1, 8, 4, 1, 8, 3, 1, 3, 1, - 6, 11, 7, 1, 8, 1, 1, 11, 7, 1, 8, 1, 1, 8, 5, 1, 10, 2, - 2, 6, 11, 7, 1, 9, 0, 6, 8, 5, 2, 6, 12, 6, 12, 1, 6, 9, - 0, 3, 6, 5, 6, 8, 5, 6, 8, 5, 5, 8, 5, 5, 5, 8, 5, 11, - 7, 1, 8, 1, 1, 8, 8, 1, 11, 9, 1, 9, 0, 5, 6, 12, 8, 5, - 8, 5, 11, 9, 1, 8, 8, 8, 5, 1, 8, 10, 3, 8, 5, 8, 5, 8, - 5, 5, 6, 12, 8, 5, 8, 5, 8, 5, 5, 6, 6, 12, 8, 5, 8, 5, - 8, 5, 5, 1, 4, 6, 12, 6, 12, 8, 5, 8, 5, 2, 7, 8, 5, 8, - 5, 7, 6, 12, 8, 5, 8, 5, 8, 5, 8, 5, 11, 9, 1, 8, 8, 8, - 5, 1, 6, 8, 10, 1, 12, 1, 8, 11, 1, 8, 2, 1, 6, 8, 11, 1, - 8, 12, 2, 8, 12, 5, 3, 10, 8, 5, 10, 8, 5, 10, 10, 2, 1, 8, - 13, 2, 6, 8, 10, 8, 13, 3, 6, 8, 4, 8, 5, 9, 0, 6, 6, 12, - 8, 5, 8, 5, 8, 5, 11, 9, 1, 8, 8, 8, 5, 10, 8, 5, 8, 5, - 8, 10, 12, 8, 11, 8, 4, 8, 13, 8, 3, 8, 2, 8, 1, 5, 6, 12, - 6, 12, 8, 5, 8, 5, 8, 5, 3, 6, 12, 11, 7, 1, 8, 1, 3, 1, - 8, 6, 1, 9, 0, 2, 11, 7, 1, 8, 1, 3, 3, 6, 11, 7, 1, 8, - 1, 7, 8, 0, 7, 3, 3, 6, 8, 4, 6, 8, 5, 9, 0, 2, 6, 8, - 2, 8, 5, 4, 10, 2, 6, 8, 1, 8, 5, 8, 5, 10, 97, 109, 98, 97, - 115, 115, 97, 100, 111, 114, 15, 65, 109, 98, 97, 115, 115, 97, 100, 111, 114, 76, - 101, 118, 101, 108, 16, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 108, 101, - 118, 101, 108, 15, 65, 109, 98, 97, 115, 115, 97, 100, 111, 114, 84, 111, 107, 101, - 110, 11, 109, 117, 116, 97, 116, 111, 114, 95, 114, 101, 102, 10, 77, 117, 116, 97, - 116, 111, 114, 82, 101, 102, 5, 116, 111, 107, 101, 110, 8, 98, 117, 114, 110, 95, - 114, 101, 102, 7, 66, 117, 114, 110, 82, 101, 102, 20, 112, 114, 111, 112, 101, 114, - 116, 121, 95, 109, 117, 116, 97, 116, 111, 114, 95, 114, 101, 102, 12, 112, 114, 111, - 112, 101, 114, 116, 121, 95, 109, 97, 112, 8, 98, 97, 115, 101, 95, 117, 114, 105, - 6, 83, 116, 114, 105, 110, 103, 6, 115, 116, 114, 105, 110, 103, 11, 76, 101, 118, - 101, 108, 85, 112, 100, 97, 116, 101, 6, 79, 98, 106, 101, 99, 116, 6, 111, 98, - 106, 101, 99, 116, 9, 111, 108, 100, 95, 108, 101, 118, 101, 108, 9, 110, 101, 119, - 95, 108, 101, 118, 101, 108, 4, 98, 117, 114, 110, 14, 111, 98, 106, 101, 99, 116, - 95, 97, 100, 100, 114, 101, 115, 115, 7, 99, 114, 101, 97, 116, 111, 114, 6, 115, - 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, 5, 101, - 114, 114, 111, 114, 17, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 95, 100, 101, - 110, 105, 101, 100, 9, 110, 111, 116, 95, 102, 111, 117, 110, 100, 29, 97, 109, 98, - 97, 115, 115, 97, 100, 111, 114, 95, 108, 101, 118, 101, 108, 95, 102, 114, 111, 109, - 95, 97, 100, 100, 114, 101, 115, 115, 17, 97, 100, 100, 114, 101, 115, 115, 95, 116, - 111, 95, 111, 98, 106, 101, 99, 116, 15, 97, 109, 98, 97, 115, 115, 97, 100, 111, - 114, 95, 114, 97, 110, 107, 4, 117, 116, 102, 56, 11, 114, 101, 97, 100, 95, 115, - 116, 114, 105, 110, 103, 28, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 114, - 97, 110, 107, 95, 102, 114, 111, 109, 95, 97, 100, 100, 114, 101, 115, 115, 18, 98, - 117, 114, 110, 95, 110, 97, 109, 101, 100, 95, 98, 121, 95, 117, 115, 101, 114, 12, - 115, 116, 114, 105, 110, 103, 95, 117, 116, 105, 108, 115, 9, 116, 111, 95, 115, 116, - 114, 105, 110, 103, 20, 99, 114, 101, 97, 116, 101, 95, 116, 111, 107, 101, 110, 95, - 97, 100, 100, 114, 101, 115, 115, 28, 99, 114, 101, 97, 116, 101, 95, 97, 109, 98, - 97, 115, 115, 97, 100, 111, 114, 95, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, - 7, 82, 111, 121, 97, 108, 116, 121, 7, 114, 111, 121, 97, 108, 116, 121, 6, 111, - 112, 116, 105, 111, 110, 4, 110, 111, 110, 101, 6, 79, 112, 116, 105, 111, 110, 10, - 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 27, 99, 114, 101, 97, 116, 101, 95, - 117, 110, 108, 105, 109, 105, 116, 101, 100, 95, 99, 111, 108, 108, 101, 99, 116, 105, - 111, 110, 14, 67, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 82, 101, 102, 11, - 105, 110, 105, 116, 95, 109, 111, 100, 117, 108, 101, 21, 109, 105, 110, 116, 95, 97, - 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 116, 111, 107, 101, 110, 26, 109, 105, - 110, 116, 95, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 116, 111, 107, 101, - 110, 95, 105, 109, 112, 108, 29, 109, 105, 110, 116, 95, 97, 109, 98, 97, 115, 115, - 97, 100, 111, 114, 95, 116, 111, 107, 101, 110, 95, 98, 121, 95, 117, 115, 101, 114, - 6, 97, 112, 112, 101, 110, 100, 21, 99, 114, 101, 97, 116, 101, 95, 110, 117, 109, - 98, 101, 114, 101, 100, 95, 116, 111, 107, 101, 110, 15, 103, 101, 110, 101, 114, 97, - 116, 101, 95, 115, 105, 103, 110, 101, 114, 21, 103, 101, 110, 101, 114, 97, 116, 101, - 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, 114, 101, 102, 11, 84, 114, 97, 110, - 115, 102, 101, 114, 82, 101, 102, 20, 103, 101, 110, 101, 114, 97, 116, 101, 95, 109, - 117, 116, 97, 116, 111, 114, 95, 114, 101, 102, 17, 103, 101, 110, 101, 114, 97, 116, - 101, 95, 98, 117, 114, 110, 95, 114, 101, 102, 28, 103, 101, 110, 101, 114, 97, 116, - 101, 95, 108, 105, 110, 101, 97, 114, 95, 116, 114, 97, 110, 115, 102, 101, 114, 95, - 114, 101, 102, 17, 76, 105, 110, 101, 97, 114, 84, 114, 97, 110, 115, 102, 101, 114, - 82, 101, 102, 17, 116, 114, 97, 110, 115, 102, 101, 114, 95, 119, 105, 116, 104, 95, - 114, 101, 102, 24, 100, 105, 115, 97, 98, 108, 101, 95, 117, 110, 103, 97, 116, 101, - 100, 95, 116, 114, 97, 110, 115, 102, 101, 114, 13, 112, 114, 101, 112, 97, 114, 101, - 95, 105, 110, 112, 117, 116, 11, 80, 114, 111, 112, 101, 114, 116, 121, 77, 97, 112, - 4, 105, 110, 105, 116, 9, 97, 100, 100, 95, 116, 121, 112, 101, 100, 18, 99, 114, - 101, 97, 116, 101, 95, 110, 97, 109, 101, 100, 95, 116, 111, 107, 101, 110, 30, 109, - 105, 110, 116, 95, 110, 117, 109, 98, 101, 114, 101, 100, 95, 97, 109, 98, 97, 115, - 115, 97, 100, 111, 114, 95, 116, 111, 107, 101, 110, 38, 109, 105, 110, 116, 95, 110, - 117, 109, 98, 101, 114, 101, 100, 95, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, - 95, 116, 111, 107, 101, 110, 95, 98, 121, 95, 117, 115, 101, 114, 20, 115, 101, 116, - 95, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 108, 101, 118, 101, 108, 5, - 101, 118, 101, 110, 116, 4, 101, 109, 105, 116, 22, 117, 112, 100, 97, 116, 101, 95, - 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 114, 97, 110, 107, 12, 117, 112, - 100, 97, 116, 101, 95, 116, 121, 112, 101, 100, 7, 115, 101, 116, 95, 117, 114, 105, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 254, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 10, 2, 5, 4, 82, 97, 110, 107, 10, 2, 27, 26, - 65, 109, 98, 97, 115, 115, 97, 100, 111, 114, 32, 67, 111, 108, 108, 101, 99, 116, - 105, 111, 110, 32, 78, 97, 109, 101, 10, 2, 34, 33, 65, 109, 98, 97, 115, 115, - 97, 100, 111, 114, 32, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 32, 68, 101, - 115, 99, 114, 105, 112, 116, 105, 111, 110, 10, 2, 26, 25, 65, 109, 98, 97, 115, - 115, 97, 100, 111, 114, 32, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 32, 85, - 82, 73, 10, 2, 7, 6, 66, 114, 111, 110, 122, 101, 10, 2, 1, 0, 10, 2, - 7, 6, 83, 105, 108, 118, 101, 114, 10, 2, 5, 4, 71, 111, 108, 100, 20, 99, - 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, - 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, - 58, 109, 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 197, 4, 6, 1, 0, 0, - 0, 0, 0, 0, 0, 21, 69, 84, 79, 75, 69, 78, 95, 68, 79, 69, 83, 95, - 78, 79, 84, 95, 69, 88, 73, 83, 84, 24, 84, 104, 101, 32, 116, 111, 107, 101, - 110, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 101, 120, 105, 115, 116, 2, 0, - 0, 0, 0, 0, 0, 0, 12, 69, 78, 79, 84, 95, 67, 82, 69, 65, 84, 79, - 82, 38, 84, 104, 101, 32, 112, 114, 111, 118, 105, 100, 101, 100, 32, 115, 105, 103, - 110, 101, 114, 32, 105, 115, 32, 110, 111, 116, 32, 116, 104, 101, 32, 99, 114, 101, - 97, 116, 111, 114, 3, 0, 0, 0, 0, 0, 0, 0, 18, 69, 70, 73, 69, 76, - 68, 95, 78, 79, 84, 95, 77, 85, 84, 65, 66, 76, 69, 38, 65, 116, 116, 101, - 109, 112, 116, 101, 100, 32, 116, 111, 32, 109, 117, 116, 97, 116, 101, 32, 97, 110, - 32, 105, 109, 109, 117, 116, 97, 98, 108, 101, 32, 102, 105, 101, 108, 100, 4, 0, - 0, 0, 0, 0, 0, 0, 19, 69, 84, 79, 75, 69, 78, 95, 78, 79, 84, 95, - 66, 85, 82, 78, 65, 66, 76, 69, 38, 65, 116, 116, 101, 109, 112, 116, 101, 100, - 32, 116, 111, 32, 98, 117, 114, 110, 32, 97, 32, 110, 111, 110, 45, 98, 117, 114, - 110, 97, 98, 108, 101, 32, 116, 111, 107, 101, 110, 5, 0, 0, 0, 0, 0, 0, - 0, 23, 69, 80, 82, 79, 80, 69, 82, 84, 73, 69, 83, 95, 78, 79, 84, 95, - 77, 85, 84, 65, 66, 76, 69, 54, 65, 116, 116, 101, 109, 112, 116, 101, 100, 32, - 116, 111, 32, 109, 117, 116, 97, 116, 101, 32, 97, 32, 112, 114, 111, 112, 101, 114, - 116, 121, 32, 109, 97, 112, 32, 116, 104, 97, 116, 32, 105, 115, 32, 110, 111, 116, - 32, 109, 117, 116, 97, 98, 108, 101, 6, 0, 0, 0, 0, 0, 0, 0, 26, 69, - 67, 79, 76, 76, 69, 67, 84, 73, 79, 78, 95, 68, 79, 69, 83, 95, 78, 79, - 84, 95, 69, 88, 73, 83, 84, 0, 3, 11, 76, 101, 118, 101, 108, 85, 112, 100, - 97, 116, 101, 1, 4, 0, 15, 65, 109, 98, 97, 115, 115, 97, 100, 111, 114, 76, - 101, 118, 101, 108, 1, 3, 1, 24, 48, 120, 49, 58, 58, 111, 98, 106, 101, 99, - 116, 58, 58, 79, 98, 106, 101, 99, 116, 71, 114, 111, 117, 112, 15, 65, 109, 98, - 97, 115, 115, 97, 100, 111, 114, 84, 111, 107, 101, 110, 1, 3, 1, 24, 48, 120, - 49, 58, 58, 111, 98, 106, 101, 99, 116, 58, 58, 79, 98, 106, 101, 99, 116, 71, - 114, 111, 117, 112, 4, 15, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 114, - 97, 110, 107, 1, 1, 0, 16, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, - 108, 101, 118, 101, 108, 1, 1, 0, 28, 97, 109, 98, 97, 115, 115, 97, 100, 111, - 114, 95, 114, 97, 110, 107, 95, 102, 114, 111, 109, 95, 97, 100, 100, 114, 101, 115, - 115, 1, 1, 0, 29, 97, 109, 98, 97, 115, 115, 97, 100, 111, 114, 95, 108, 101, - 118, 101, 108, 95, 102, 114, 111, 109, 95, 97, 100, 100, 114, 101, 115, 115, 1, 1, - 0, 0, 2, 1, 2, 3, 1, 2, 4, 4, 8, 2, 7, 8, 3, 9, 8, 4, - 11, 8, 5, 6, 2, 3, 6, 11, 7, 1, 8, 1, 17, 3, 18, 3, 0, 1, - 4, 2, 0, 1, 10, 37, 14, 1, 12, 2, 10, 2, 56, 0, 41, 1, 4, 30, - 11, 2, 20, 56, 1, 11, 0, 17, 3, 33, 4, 27, 14, 1, 56, 0, 44, 1, - 19, 1, 1, 14, 1, 56, 0, 44, 0, 19, 0, 1, 17, 4, 17, 5, 1, 2, - 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 0, 1, 11, 2, 1, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 7, 39, 8, 1, 0, 1, 0, 1, - 6, 14, 0, 56, 0, 43, 0, 16, 0, 20, 2, 9, 1, 0, 1, 0, 1, 4, - 11, 0, 56, 2, 17, 8, 2, 11, 1, 0, 0, 12, 7, 14, 0, 7, 0, 17, - 12, 12, 1, 14, 1, 56, 3, 2, 14, 1, 0, 0, 1, 4, 11, 0, 56, 2, - 17, 11, 2, 15, 1, 4, 2, 0, 1, 18, 22, 7, 1, 17, 12, 12, 2, 10, - 1, 17, 3, 12, 3, 14, 3, 14, 2, 11, 0, 17, 3, 12, 4, 14, 4, 56, - 4, 12, 5, 14, 5, 17, 17, 56, 2, 12, 6, 11, 1, 11, 6, 17, 0, 2, - 18, 0, 0, 0, 23, 17, 7, 2, 17, 12, 12, 1, 7, 1, 17, 12, 12, 2, - 7, 3, 17, 12, 12, 3, 11, 0, 11, 1, 11, 2, 56, 5, 11, 3, 17, 20, - 1, 2, 21, 0, 0, 0, 1, 3, 11, 0, 17, 18, 2, 22, 1, 4, 0, 1, - 8, 11, 0, 11, 1, 11, 2, 11, 3, 11, 4, 9, 17, 23, 2, 24, 1, 4, - 0, 4, 11, 11, 0, 17, 3, 12, 4, 11, 1, 11, 2, 14, 4, 56, 4, 11, - 3, 11, 4, 17, 22, 2, 23, 0, 0, 0, 41, 75, 7, 1, 17, 12, 12, 6, - 10, 3, 12, 7, 13, 7, 7, 4, 17, 12, 17, 25, 11, 5, 4, 66, 11, 0, - 11, 6, 11, 1, 11, 2, 7, 5, 17, 12, 56, 5, 11, 7, 17, 26, 12, 8, - 14, 8, 17, 27, 12, 9, 14, 8, 17, 28, 12, 10, 14, 8, 17, 29, 14, 8, - 17, 30, 14, 8, 17, 31, 12, 11, 14, 10, 17, 32, 11, 4, 17, 33, 14, 10, - 17, 34, 14, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 45, 0, 64, - 12, 0, 0, 0, 0, 0, 0, 0, 0, 64, 12, 0, 0, 0, 0, 0, 0, 0, - 0, 64, 13, 0, 0, 0, 0, 0, 0, 0, 0, 17, 35, 12, 12, 14, 8, 11, - 12, 17, 36, 14, 11, 7, 0, 17, 12, 7, 4, 17, 12, 56, 6, 11, 11, 11, - 3, 18, 1, 12, 15, 14, 9, 11, 15, 45, 1, 2, 11, 0, 11, 6, 11, 1, - 11, 2, 56, 5, 11, 7, 17, 38, 12, 8, 5, 21, 39, 1, 4, 0, 1, 8, - 11, 0, 11, 1, 11, 2, 11, 3, 11, 4, 8, 17, 23, 2, 40, 1, 4, 0, - 1, 8, 11, 1, 11, 2, 11, 3, 11, 4, 11, 0, 17, 3, 17, 39, 2, 41, - 1, 4, 2, 0, 1, 47, 44, 14, 1, 12, 3, 10, 3, 56, 0, 41, 1, 4, - 37, 11, 3, 20, 56, 1, 11, 0, 17, 3, 33, 4, 34, 14, 1, 56, 0, 42, - 0, 12, 4, 10, 1, 10, 4, 16, 0, 20, 10, 2, 18, 2, 56, 7, 11, 4, - 15, 0, 12, 5, 10, 2, 11, 5, 21, 11, 1, 11, 2, 17, 43, 2, 6, 2, - 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 0, 1, 11, 3, 1, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 17, 7, 39, 43, 0, 0, 1, 1, 50, 42, 10, - 1, 6, 10, 0, 0, 0, 0, 0, 0, 0, 35, 4, 32, 7, 4, 12, 2, 14, - 0, 56, 0, 43, 1, 12, 3, 10, 3, 16, 1, 7, 0, 17, 12, 12, 4, 14, - 4, 10, 2, 17, 12, 56, 8, 10, 3, 16, 2, 20, 12, 5, 13, 5, 11, 2, - 17, 12, 17, 25, 11, 3, 16, 3, 11, 5, 17, 45, 2, 11, 1, 6, 20, 0, - 0, 0, 0, 0, 0, 0, 35, 4, 39, 7, 6, 12, 2, 5, 6, 7, 7, 12, - 2, 5, 6, 0, 0, 1, 2, 1, 3, 1, 0, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_AMBASSADOR_TOKEN: Lazy>> = Lazy::new(|| { vec![ - MODULE_AMBASSADOR_TOKEN_AMBASSADOR.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_AGGREGATOR_EXAMPLES_METADATA: Lazy> = Lazy::new(|| { - vec![ - 19, 65, 103, 103, 114, 101, 103, 97, 116, 111, 114, 45, 101, 120, 97, 109, 112, 108, - 101, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 52, 48, 67, 54, 50, 56, - 48, 70, 57, 56, 49, 55, 65, 52, 67, 70, 66, 66, 49, 53, 69, 65, 70, 55, - 67, 66, 53, 66, 52, 66, 52, 69, 68, 65, 53, 53, 48, 68, 53, 66, 67, 68, - 65, 57, 67, 52, 49, 52, 53, 50, 48, 70, 70, 55, 68, 68, 54, 53, 70, 70, - 49, 50, 70, 68, 200, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 173, 142, - 193, 14, 130, 48, 12, 134, 239, 123, 138, 101, 103, 5, 207, 38, 30, 136, 209, 23, - 240, 104, 140, 41, 172, 142, 5, 216, 150, 117, 32, 137, 241, 221, 221, 64, 56, 121, - 52, 189, 180, 253, 191, 191, 127, 175, 14, 170, 6, 20, 222, 152, 129, 14, 249, 129, - 139, 66, 41, 143, 10, 130, 245, 91, 28, 161, 115, 45, 146, 96, 3, 122, 210, 214, - 36, 125, 151, 197, 18, 140, 93, 65, 74, 143, 68, 72, 55, 6, 171, 231, 190, 120, - 38, 116, 60, 22, 231, 83, 98, 37, 58, 52, 18, 77, 165, 19, 94, 184, 96, 233, - 18, 100, 171, 203, 136, 189, 184, 210, 33, 225, 117, 8, 142, 246, 121, 30, 199, 186, - 47, 179, 202, 118, 57, 36, 114, 219, 66, 73, 223, 246, 225, 227, 155, 79, 235, 155, - 44, 82, 98, 195, 169, 47, 165, 246, 201, 61, 235, 52, 93, 141, 130, 199, 33, 109, - 59, 208, 198, 96, 16, 252, 61, 167, 158, 23, 255, 191, 131, 87, 253, 103, 246, 7, - 28, 102, 34, 53, 103, 1, 0, 0, 1, 22, 99, 111, 117, 110, 116, 101, 114, 95, - 119, 105, 116, 104, 95, 109, 105, 108, 101, 115, 116, 111, 110, 101, 0, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, - 111, 115, 70, 114, 97, 109, 101, 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, - 118, 101, 83, 116, 100, 108, 105, 98, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_AGGREGATOR_EXAMPLES_COUNTER_WITH_MILESTONE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 12, 1, 0, 10, 2, 10, 14, 3, 24, 52, - 4, 76, 8, 5, 84, 49, 7, 133, 1, 128, 2, 8, 133, 3, 64, 6, 197, 3, - 34, 16, 231, 3, 163, 1, 10, 138, 5, 17, 12, 155, 5, 179, 1, 13, 206, 6, - 6, 0, 0, 1, 6, 1, 10, 1, 16, 1, 18, 0, 1, 8, 0, 1, 5, 6, - 1, 0, 0, 0, 7, 6, 0, 0, 9, 0, 1, 0, 1, 2, 11, 2, 3, 0, - 1, 1, 12, 1, 5, 1, 3, 1, 0, 13, 1, 1, 0, 1, 1, 14, 6, 7, - 1, 0, 1, 1, 15, 8, 7, 1, 0, 1, 3, 17, 10, 1, 1, 6, 1, 4, - 19, 4, 4, 0, 1, 2, 4, 4, 4, 5, 4, 6, 9, 2, 6, 12, 3, 0, - 1, 6, 12, 1, 5, 1, 3, 1, 11, 1, 1, 9, 0, 2, 7, 11, 1, 1, - 9, 0, 9, 0, 1, 1, 2, 6, 11, 1, 1, 9, 0, 9, 0, 1, 8, 2, - 1, 9, 0, 2, 7, 8, 0, 1, 22, 99, 111, 117, 110, 116, 101, 114, 95, 119, - 105, 116, 104, 95, 109, 105, 108, 101, 115, 116, 111, 110, 101, 16, 77, 105, 108, 101, - 115, 116, 111, 110, 101, 67, 111, 117, 110, 116, 101, 114, 14, 110, 101, 120, 116, 95, - 109, 105, 108, 101, 115, 116, 111, 110, 101, 15, 109, 105, 108, 101, 115, 116, 111, 110, - 101, 95, 101, 118, 101, 114, 121, 5, 99, 111, 117, 110, 116, 10, 65, 103, 103, 114, - 101, 103, 97, 116, 111, 114, 13, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, - 118, 50, 16, 77, 105, 108, 101, 115, 116, 111, 110, 101, 82, 101, 97, 99, 104, 101, - 100, 9, 109, 105, 108, 101, 115, 116, 111, 110, 101, 6, 99, 114, 101, 97, 116, 101, - 6, 115, 105, 103, 110, 101, 114, 10, 97, 100, 100, 114, 101, 115, 115, 95, 111, 102, - 27, 99, 114, 101, 97, 116, 101, 95, 117, 110, 98, 111, 117, 110, 100, 101, 100, 95, - 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 19, 105, 110, 99, 114, 101, 109, 101, - 110, 116, 95, 109, 105, 108, 101, 115, 116, 111, 110, 101, 7, 116, 114, 121, 95, 97, - 100, 100, 11, 105, 115, 95, 97, 116, 95, 108, 101, 97, 115, 116, 5, 101, 118, 101, - 110, 116, 4, 101, 109, 105, 116, 5, 101, 114, 114, 111, 114, 16, 105, 110, 118, 97, - 108, 105, 100, 95, 97, 114, 103, 117, 109, 101, 110, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 202, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 5, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 202, 254, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, - 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 18, 97, 112, - 116, 111, 115, 58, 58, 109, 101, 116, 97, 100, 97, 116, 97, 95, 118, 49, 112, 3, - 2, 0, 0, 0, 0, 0, 0, 0, 21, 69, 82, 69, 83, 79, 85, 82, 67, 69, - 95, 78, 79, 84, 95, 80, 82, 69, 83, 69, 78, 84, 0, 4, 0, 0, 0, 0, - 0, 0, 0, 23, 69, 67, 79, 85, 78, 84, 69, 82, 95, 73, 78, 67, 82, 69, - 77, 69, 78, 84, 95, 70, 65, 73, 76, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 15, 69, 78, 79, 84, 95, 65, 85, 84, 72, 79, 82, 73, 90, 69, 68, 0, 1, - 16, 77, 105, 108, 101, 115, 116, 111, 110, 101, 82, 101, 97, 99, 104, 101, 100, 1, - 4, 0, 0, 0, 2, 3, 2, 3, 3, 3, 4, 11, 1, 1, 3, 2, 2, 1, - 8, 3, 0, 1, 4, 0, 1, 16, 10, 0, 17, 1, 7, 0, 33, 4, 12, 11, - 0, 10, 1, 11, 1, 56, 0, 18, 0, 45, 0, 2, 11, 0, 1, 6, 5, 0, - 0, 0, 0, 0, 0, 0, 39, 3, 1, 4, 1, 0, 11, 59, 7, 0, 41, 0, - 4, 56, 7, 0, 42, 0, 12, 0, 10, 0, 15, 0, 6, 1, 0, 0, 0, 0, - 0, 0, 0, 56, 1, 4, 52, 10, 0, 16, 0, 10, 0, 16, 1, 20, 56, 2, - 4, 49, 10, 0, 16, 0, 10, 0, 16, 1, 20, 6, 1, 0, 0, 0, 0, 0, - 0, 0, 22, 56, 2, 32, 12, 1, 11, 1, 4, 46, 10, 0, 16, 1, 20, 18, - 1, 56, 3, 10, 0, 16, 1, 20, 10, 0, 16, 2, 20, 22, 11, 0, 15, 1, - 21, 2, 11, 0, 1, 5, 45, 9, 12, 1, 5, 28, 11, 0, 1, 6, 4, 0, - 0, 0, 0, 0, 0, 0, 39, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 7, - 39, 0, 2, 0, 0, 0, 1, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_AGGREGATOR_EXAMPLES: Lazy>> = Lazy::new(|| { vec![ - MODULE_AGGREGATOR_EXAMPLES_COUNTER_WITH_MILESTONE.to_vec(), -]}); -#[rustfmt::skip] -pub static PACKAGE_BCS_STREAM_METADATA: Lazy> = Lazy::new(|| { - vec![ - 9, 66, 67, 83, 83, 116, 114, 101, 97, 109, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 64, 66, 48, 65, 50, 57, 67, 53, 52, 66, 51, 55, 54, 67, 69, 56, 69, - 66, 55, 69, 49, 53, 68, 70, 57, 67, 54, 52, 66, 53, 68, 51, 53, 68, 52, - 65, 68, 67, 51, 50, 65, 57, 52, 65, 69, 57, 66, 56, 49, 50, 48, 57, 57, - 68, 48, 53, 56, 51, 67, 49, 66, 55, 49, 48, 54, 179, 1, 31, 139, 8, 0, - 0, 0, 0, 0, 2, 255, 45, 206, 205, 10, 194, 48, 12, 0, 224, 123, 159, 162, - 244, 172, 155, 103, 193, 131, 14, 125, 129, 29, 199, 144, 180, 141, 91, 217, 250, 67, - 211, 77, 65, 124, 119, 219, 41, 185, 228, 231, 75, 72, 23, 64, 77, 48, 96, 207, - 28, 88, 228, 39, 46, 46, 77, 219, 166, 136, 96, 5, 91, 49, 146, 241, 174, 116, - 15, 85, 14, 193, 88, 7, 90, 71, 36, 66, 234, 153, 84, 116, 167, 141, 110, 226, - 213, 156, 111, 215, 66, 52, 6, 116, 26, 157, 50, 69, 157, 67, 242, 212, 38, 61, - 27, 153, 217, 155, 15, 38, 21, 62, 166, 20, 232, 88, 215, 185, 28, 23, 89, 41, - 111, 107, 40, 114, 63, 131, 164, 127, 250, 136, 249, 167, 167, 143, 83, 149, 149, 216, - 113, 90, 164, 54, 177, 108, 255, 230, 180, 93, 205, 131, 136, 107, 233, 90, 48, 206, - 97, 18, 252, 195, 190, 12, 3, 21, 8, 216, 0, 0, 0, 1, 10, 98, 99, 115, - 95, 115, 116, 114, 101, 97, 109, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, - 118, 101, 83, 116, 100, 108, 105, 98, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULE_BCS_STREAM_BCS_STREAM: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 11, 1, 0, 10, 2, 10, 8, 3, 18, 103, - 4, 121, 2, 5, 123, 65, 7, 188, 1, 190, 2, 8, 250, 3, 64, 16, 186, 4, - 206, 1, 10, 136, 6, 8, 12, 144, 6, 244, 17, 13, 132, 24, 4, 0, 0, 1, - 6, 1, 8, 1, 10, 1, 16, 0, 1, 2, 0, 4, 15, 7, 0, 0, 4, 0, - 1, 0, 1, 0, 5, 3, 4, 0, 1, 1, 7, 6, 7, 1, 1, 1, 2, 9, - 0, 4, 0, 1, 3, 11, 8, 8, 0, 1, 0, 12, 3, 10, 0, 1, 3, 13, - 8, 8, 0, 1, 0, 14, 3, 12, 0, 1, 0, 17, 3, 8, 0, 1, 4, 18, - 0, 12, 0, 1, 0, 19, 3, 14, 0, 1, 0, 20, 3, 15, 0, 1, 0, 21, - 3, 16, 0, 1, 0, 22, 17, 2, 0, 1, 0, 23, 3, 18, 0, 1, 0, 24, - 3, 8, 0, 1, 0, 25, 3, 5, 0, 1, 2, 5, 1, 10, 2, 1, 8, 0, - 0, 1, 7, 8, 0, 1, 5, 1, 2, 3, 6, 10, 9, 0, 3, 3, 1, 10, - 9, 0, 1, 3, 2, 6, 10, 2, 3, 1, 1, 2, 2, 1, 1, 8, 1, 3, - 3, 6, 10, 2, 3, 1, 4, 1, 13, 1, 15, 2, 10, 2, 3, 1, 14, 5, - 3, 2, 2, 3, 1, 10, 98, 99, 115, 95, 115, 116, 114, 101, 97, 109, 9, 66, - 67, 83, 83, 116, 114, 101, 97, 109, 4, 100, 97, 116, 97, 3, 99, 117, 114, 3, - 110, 101, 119, 19, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 97, 100, - 100, 114, 101, 115, 115, 6, 118, 101, 99, 116, 111, 114, 5, 115, 108, 105, 99, 101, - 8, 102, 114, 111, 109, 95, 98, 99, 115, 10, 116, 111, 95, 97, 100, 100, 114, 101, - 115, 115, 5, 101, 114, 114, 111, 114, 12, 111, 117, 116, 95, 111, 102, 95, 114, 97, - 110, 103, 101, 16, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 98, 111, - 111, 108, 16, 105, 110, 118, 97, 108, 105, 100, 95, 97, 114, 103, 117, 109, 101, 110, - 116, 18, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 115, 116, 114, 105, - 110, 103, 6, 83, 116, 114, 105, 110, 103, 6, 115, 116, 114, 105, 110, 103, 19, 100, - 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, 108, 101, 98, 49, 50, 56, - 4, 117, 116, 102, 56, 16, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, - 117, 49, 50, 56, 15, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, - 49, 54, 16, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, 50, 53, - 54, 22, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, 50, 53, 54, - 95, 101, 110, 116, 114, 121, 15, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, - 95, 117, 51, 50, 15, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, - 54, 52, 14, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 95, 117, 56, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 254, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, 105, 108, 97, 116, - 105, 111, 110, 95, 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, - 3, 50, 46, 49, 18, 97, 112, 116, 111, 115, 58, 58, 109, 101, 116, 97, 100, 97, - 116, 97, 95, 118, 49, 154, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 15, 69, - 77, 65, 76, 70, 79, 82, 77, 69, 68, 95, 68, 65, 84, 65, 42, 84, 104, 101, - 32, 100, 97, 116, 97, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 102, 105, 116, - 32, 116, 104, 101, 32, 101, 120, 112, 101, 99, 116, 101, 100, 32, 102, 111, 114, 109, - 97, 116, 46, 2, 0, 0, 0, 0, 0, 0, 0, 13, 69, 79, 85, 84, 95, 79, - 70, 95, 66, 89, 84, 69, 83, 61, 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, - 110, 111, 116, 32, 101, 110, 111, 117, 103, 104, 32, 98, 121, 116, 101, 115, 32, 116, - 111, 32, 100, 101, 115, 101, 114, 105, 97, 108, 105, 122, 101, 32, 102, 111, 114, 32, - 116, 104, 101, 32, 103, 105, 118, 101, 110, 32, 116, 121, 112, 101, 46, 0, 0, 0, - 2, 2, 2, 10, 2, 3, 3, 0, 1, 0, 0, 2, 4, 11, 0, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 0, 2, 1, 1, 0, 0, 9, 35, 10, 0, 16, - 0, 12, 1, 10, 0, 16, 1, 20, 12, 2, 10, 2, 6, 32, 0, 0, 0, 0, - 0, 0, 0, 22, 10, 1, 65, 5, 37, 4, 28, 11, 1, 10, 2, 10, 2, 6, - 32, 0, 0, 0, 0, 0, 0, 0, 22, 56, 0, 17, 3, 11, 2, 6, 32, 0, - 0, 0, 0, 0, 0, 0, 22, 11, 0, 15, 1, 21, 2, 11, 0, 1, 11, 1, - 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 5, 1, 0, 0, 11, - 47, 10, 0, 16, 1, 20, 10, 0, 16, 0, 65, 5, 35, 4, 42, 10, 0, 16, - 0, 10, 0, 16, 1, 20, 66, 5, 20, 12, 1, 10, 0, 16, 1, 20, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 11, 0, 15, 1, 21, 10, 1, 49, 0, 33, - 4, 32, 9, 12, 2, 11, 2, 2, 11, 1, 49, 1, 33, 4, 39, 8, 12, 2, - 5, 30, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 0, 1, 6, - 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 7, 1, 0, 0, 13, 38, 10, - 0, 17, 8, 12, 1, 10, 0, 16, 0, 12, 2, 10, 0, 16, 1, 20, 12, 3, - 10, 3, 10, 1, 22, 10, 2, 65, 5, 37, 4, 31, 11, 2, 10, 3, 10, 3, - 10, 1, 22, 56, 0, 17, 9, 11, 3, 11, 1, 22, 11, 0, 15, 1, 21, 2, - 11, 0, 1, 11, 2, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, - 10, 1, 0, 0, 9, 185, 1, 10, 0, 16, 0, 12, 1, 10, 0, 16, 1, 20, - 12, 2, 10, 2, 6, 16, 0, 0, 0, 0, 0, 0, 0, 22, 10, 1, 65, 5, - 37, 4, 178, 1, 10, 1, 10, 2, 66, 5, 20, 53, 10, 1, 10, 2, 6, 1, - 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 8, 47, 27, 10, 1, - 10, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 16, - 47, 27, 10, 1, 10, 2, 6, 3, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 53, 49, 24, 47, 27, 10, 1, 10, 2, 6, 4, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 53, 49, 32, 47, 27, 10, 1, 10, 2, 6, 5, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 40, 47, 27, 10, 1, 10, 2, - 6, 6, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 48, 47, 27, - 10, 1, 10, 2, 6, 7, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, - 49, 56, 47, 27, 10, 1, 10, 2, 6, 8, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 53, 49, 64, 47, 27, 10, 1, 10, 2, 6, 9, 0, 0, 0, 0, - 0, 0, 0, 22, 66, 5, 20, 53, 49, 72, 47, 27, 10, 1, 10, 2, 6, 10, - 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 80, 47, 27, 10, 1, - 10, 2, 6, 11, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 88, - 47, 27, 10, 1, 10, 2, 6, 12, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 53, 49, 96, 47, 27, 10, 1, 10, 2, 6, 13, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 53, 49, 104, 47, 27, 10, 1, 10, 2, 6, 14, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 112, 47, 27, 11, 1, 11, 2, - 6, 15, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 53, 49, 120, 47, 27, - 10, 0, 16, 1, 20, 6, 16, 0, 0, 0, 0, 0, 0, 0, 22, 11, 0, 15, - 1, 21, 2, 11, 0, 1, 11, 1, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, - 17, 4, 39, 11, 1, 0, 0, 9, 45, 10, 0, 16, 0, 12, 1, 10, 0, 16, - 1, 20, 12, 2, 10, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 22, 10, 1, - 65, 5, 37, 4, 38, 10, 1, 10, 2, 66, 5, 20, 75, 11, 1, 11, 2, 6, - 1, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 75, 49, 8, 47, 27, 10, - 0, 16, 1, 20, 6, 2, 0, 0, 0, 0, 0, 0, 0, 22, 11, 0, 15, 1, - 21, 2, 11, 0, 1, 11, 1, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, - 4, 39, 12, 1, 0, 0, 9, 217, 2, 10, 0, 16, 0, 12, 1, 10, 0, 16, - 1, 20, 12, 2, 10, 2, 6, 32, 0, 0, 0, 0, 0, 0, 0, 22, 10, 1, - 65, 5, 37, 4, 210, 2, 10, 1, 10, 2, 66, 5, 20, 77, 10, 1, 10, 2, - 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 8, 47, 27, - 10, 1, 10, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, - 49, 16, 47, 27, 10, 1, 10, 2, 6, 3, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 77, 49, 24, 47, 27, 10, 1, 10, 2, 6, 4, 0, 0, 0, 0, - 0, 0, 0, 22, 66, 5, 20, 77, 49, 32, 47, 27, 10, 1, 10, 2, 6, 5, - 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 40, 47, 27, 10, 1, - 10, 2, 6, 6, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 48, - 47, 27, 10, 1, 10, 2, 6, 7, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 77, 49, 56, 47, 27, 10, 1, 10, 2, 6, 8, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 77, 49, 64, 47, 27, 10, 1, 10, 2, 6, 9, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 72, 47, 27, 10, 1, 10, 2, - 6, 10, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 80, 47, 27, - 10, 1, 10, 2, 6, 11, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, - 49, 88, 47, 27, 10, 1, 10, 2, 6, 12, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 77, 49, 96, 47, 27, 10, 1, 10, 2, 6, 13, 0, 0, 0, 0, - 0, 0, 0, 22, 66, 5, 20, 77, 49, 104, 47, 27, 10, 1, 10, 2, 6, 14, - 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 112, 47, 27, 10, 1, - 10, 2, 6, 15, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 120, - 47, 27, 10, 1, 10, 2, 6, 16, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 77, 49, 128, 47, 27, 10, 1, 10, 2, 6, 17, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 77, 49, 136, 47, 27, 10, 1, 10, 2, 6, 18, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 144, 47, 27, 10, 1, 10, 2, - 6, 19, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 152, 47, 27, - 10, 1, 10, 2, 6, 20, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, - 49, 160, 47, 27, 10, 1, 10, 2, 6, 21, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 77, 49, 168, 47, 27, 10, 1, 10, 2, 6, 22, 0, 0, 0, 0, - 0, 0, 0, 22, 66, 5, 20, 77, 49, 176, 47, 27, 10, 1, 10, 2, 6, 23, - 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 184, 47, 27, 10, 1, - 10, 2, 6, 24, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 192, - 47, 27, 10, 1, 10, 2, 6, 25, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 77, 49, 200, 47, 27, 10, 1, 10, 2, 6, 26, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 77, 49, 208, 47, 27, 10, 1, 10, 2, 6, 27, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 216, 47, 27, 10, 1, 10, 2, - 6, 28, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, 49, 224, 47, 27, - 10, 1, 10, 2, 6, 29, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 77, - 49, 232, 47, 27, 10, 1, 10, 2, 6, 30, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 77, 49, 240, 47, 27, 11, 1, 11, 2, 6, 31, 0, 0, 0, 0, - 0, 0, 0, 22, 66, 5, 20, 77, 49, 248, 47, 27, 10, 0, 16, 1, 20, 6, - 32, 0, 0, 0, 0, 0, 0, 0, 22, 11, 0, 15, 1, 21, 2, 11, 0, 1, - 11, 1, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 13, 1, 4, - 0, 1, 8, 11, 0, 11, 1, 18, 0, 12, 2, 13, 2, 17, 12, 1, 2, 14, - 1, 0, 0, 9, 65, 10, 0, 16, 0, 12, 1, 10, 0, 16, 1, 20, 12, 2, - 10, 2, 6, 4, 0, 0, 0, 0, 0, 0, 0, 22, 10, 1, 65, 5, 37, 4, - 58, 10, 1, 10, 2, 66, 5, 20, 76, 10, 1, 10, 2, 6, 1, 0, 0, 0, - 0, 0, 0, 0, 22, 66, 5, 20, 76, 49, 8, 47, 27, 10, 1, 10, 2, 6, - 2, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 76, 49, 16, 47, 27, 11, - 1, 11, 2, 6, 3, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 76, 49, - 24, 47, 27, 10, 0, 16, 1, 20, 6, 4, 0, 0, 0, 0, 0, 0, 0, 22, - 11, 0, 15, 1, 21, 2, 11, 0, 1, 11, 1, 1, 6, 2, 0, 0, 0, 0, - 0, 0, 0, 17, 4, 39, 15, 1, 0, 0, 9, 105, 10, 0, 16, 0, 12, 1, - 10, 0, 16, 1, 20, 12, 2, 10, 2, 6, 8, 0, 0, 0, 0, 0, 0, 0, - 22, 10, 1, 65, 5, 37, 4, 98, 10, 1, 10, 2, 66, 5, 20, 52, 10, 1, - 10, 2, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 52, 49, 8, - 47, 27, 10, 1, 10, 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, - 20, 52, 49, 16, 47, 27, 10, 1, 10, 2, 6, 3, 0, 0, 0, 0, 0, 0, - 0, 22, 66, 5, 20, 52, 49, 24, 47, 27, 10, 1, 10, 2, 6, 4, 0, 0, - 0, 0, 0, 0, 0, 22, 66, 5, 20, 52, 49, 32, 47, 27, 10, 1, 10, 2, - 6, 5, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 52, 49, 40, 47, 27, - 10, 1, 10, 2, 6, 6, 0, 0, 0, 0, 0, 0, 0, 22, 66, 5, 20, 52, - 49, 48, 47, 27, 11, 1, 11, 2, 6, 7, 0, 0, 0, 0, 0, 0, 0, 22, - 66, 5, 20, 52, 49, 56, 47, 27, 10, 0, 16, 1, 20, 6, 8, 0, 0, 0, - 0, 0, 0, 0, 22, 11, 0, 15, 1, 21, 2, 11, 0, 1, 11, 1, 1, 6, - 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 16, 1, 0, 0, 9, 30, 10, - 0, 16, 0, 12, 1, 10, 0, 16, 1, 20, 12, 2, 10, 2, 10, 1, 65, 5, - 35, 4, 23, 11, 1, 10, 2, 66, 5, 20, 11, 2, 6, 1, 0, 0, 0, 0, - 0, 0, 0, 22, 11, 0, 15, 1, 21, 2, 11, 0, 1, 11, 1, 1, 6, 2, - 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 8, 1, 0, 0, 19, 97, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 12, 1, 49, 0, 12, 2, 10, 0, 16, 1, 20, - 10, 0, 16, 0, 65, 5, 35, 4, 92, 10, 0, 16, 0, 10, 0, 16, 1, 20, - 66, 5, 20, 12, 3, 10, 0, 16, 1, 20, 6, 1, 0, 0, 0, 0, 0, 0, - 0, 22, 10, 0, 15, 1, 21, 10, 3, 49, 127, 28, 52, 12, 4, 10, 4, 10, - 2, 47, 10, 2, 48, 10, 4, 34, 4, 46, 11, 0, 1, 6, 1, 0, 0, 0, - 0, 0, 0, 0, 17, 6, 39, 11, 1, 10, 4, 10, 2, 47, 27, 12, 1, 11, - 3, 49, 128, 28, 49, 0, 33, 4, 78, 11, 0, 1, 11, 2, 49, 0, 36, 4, - 75, 11, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 33, 12, 5, 11, 5, 4, - 73, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 1, 2, 9, 12, - 5, 5, 68, 11, 2, 49, 7, 22, 12, 2, 10, 2, 49, 64, 36, 3, 87, 5, - 4, 11, 0, 1, 6, 1, 0, 0, 0, 0, 0, 0, 0, 17, 6, 39, 11, 0, - 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 17, 4, 39, 0, 0, 0, 1, 0, - ] -}); - -#[rustfmt::skip] -pub static MODULES_BCS_STREAM: Lazy>> = Lazy::new(|| { vec![ - MODULE_BCS_STREAM_BCS_STREAM.to_vec(), -]}); - -#[rustfmt::skip] -pub static PACKAGE_TO_METADATA: Lazy>> = Lazy::new(|| { HashMap::from([ - ("simple".to_string(), PACKAGE_SIMPLE_METADATA.to_vec()), - ("framework_usecases".to_string(), PACKAGE_FRAMEWORK_USECASES_METADATA.to_vec()), - ("experimental_usecases".to_string(), PACKAGE_EXPERIMENTAL_USECASES_METADATA.to_vec()), - ("complex".to_string(), PACKAGE_COMPLEX_METADATA.to_vec()), - ("ambassador_token".to_string(), PACKAGE_AMBASSADOR_TOKEN_METADATA.to_vec()), - ("aggregator_examples".to_string(), PACKAGE_AGGREGATOR_EXAMPLES_METADATA.to_vec()), - ("bcs_stream".to_string(), PACKAGE_BCS_STREAM_METADATA.to_vec()), -])}); - -#[rustfmt::skip] -pub static PACKAGE_TO_MODULES: Lazy>>> = Lazy::new(|| { HashMap::from([ - ("simple".to_string(), MODULES_SIMPLE.to_vec()), - ("framework_usecases".to_string(), MODULES_FRAMEWORK_USECASES.to_vec()), - ("experimental_usecases".to_string(), MODULES_EXPERIMENTAL_USECASES.to_vec()), - ("complex".to_string(), MODULES_COMPLEX.to_vec()), - ("ambassador_token".to_string(), MODULES_AMBASSADOR_TOKEN.to_vec()), - ("aggregator_examples".to_string(), MODULES_AGGREGATOR_EXAMPLES.to_vec()), - ("bcs_stream".to_string(), MODULES_BCS_STREAM.to_vec()), -])}); - -#[rustfmt::skip] -pub static PACKAGE_TO_SCRIPT: Lazy>> = Lazy::new(|| { HashMap::from([ - ("simple".to_string(), SCRIPT_SIMPLE.to_vec()), -])}); - -#[derive(Debug)] -pub struct PreBuiltPackagesImpl; - -impl PreBuiltPackages for PreBuiltPackagesImpl { - fn package_metadata(&self, package_name: &str) -> &[u8] { - PACKAGE_TO_METADATA.get(package_name).expect(package_name) - } - - fn package_modules(&self, package_name: &str) -> &[Vec] { - PACKAGE_TO_MODULES.get(package_name).expect(package_name) - } - - fn package_script(&self, package_name: &str) -> Option<&Vec> { - PACKAGE_TO_SCRIPT.get(package_name) - } -} diff --git a/devtools/aptos-cargo-cli/src/common.rs b/devtools/aptos-cargo-cli/src/common.rs index 00fcb7706ee..52d504d110c 100644 --- a/devtools/aptos-cargo-cli/src/common.rs +++ b/devtools/aptos-cargo-cli/src/common.rs @@ -425,7 +425,7 @@ fn recompute_merge_base_metadata( .arg("clone") .arg("--depth") .arg("500") // Clone the last 500 commits to ensure the merge base is included - .arg("https://github.com/movementlabsxyz/aptos-core.git") + .arg("https://github.com/movement-network/aptos-core.git") .arg(clone_directory.clone()) .output() .expect("failed to execute git clone"); diff --git a/dkg/src/dkg_manager/mod.rs b/dkg/src/dkg_manager/mod.rs index 5427e41a196..28e1772b5bf 100644 --- a/dkg/src/dkg_manager/mod.rs +++ b/dkg/src/dkg_manager/mod.rs @@ -52,6 +52,7 @@ impl Default for InnerState { pub struct DKGManager { dealer_sk: Arc, + dealer_pk: Arc, my_index: usize, my_addr: AccountAddress, epoch_state: Arc, @@ -91,6 +92,7 @@ impl InnerState { impl DKGManager { pub fn new( dealer_sk: Arc, + dealer_pk: Arc, my_index: usize, my_addr: AccountAddress, epoch_state: Arc, @@ -101,6 +103,7 @@ impl DKGManager { aptos_channel::new(QueueStyle::KLAST, 1, None); Self { dealer_sk, + dealer_pk, my_addr, my_index, epoch_state, @@ -332,6 +335,7 @@ impl DKGManager { &input_secret, self.my_index as u64, &self.dealer_sk, + &self.dealer_pk, ); let my_transcript = DKGTranscript::new( diff --git a/dkg/src/dkg_manager/tests.rs b/dkg/src/dkg_manager/tests.rs index 69757b38f9a..80883c73e7e 100644 --- a/dkg/src/dkg_manager/tests.rs +++ b/dkg/src/dkg_manager/tests.rs @@ -60,6 +60,7 @@ async fn test_dkg_state_transition() { let agg_node_producer = DummyAggTranscriptProducer {}; let mut dkg_manager: DKGManager = DKGManager::new( private_keys[0].clone(), + Arc::new(public_keys[0].clone()), 0, addrs[0], Arc::new(epoch_state), diff --git a/dkg/src/epoch_manager.rs b/dkg/src/epoch_manager.rs index 7561a2c49e8..100176f1061 100644 --- a/dkg/src/epoch_manager.rs +++ b/dkg/src/epoch_manager.rs @@ -235,11 +235,15 @@ impl EpochManager
1 + borrow_global R + borrow_field R, data + st_loc l2 + // @10 +l1: move_loc l2 + ld_u64 0 + vec_borrow + read_ref + ret + // @15 +l0: move_loc l1 + st_loc l2 + branch l1 + -f(k: u8, d: &vector): u64 /* def_idx: 0 */ { -L2: v: &vector -B0: - 0: MoveLoc[0](k: u8) - 1: LdU8(0) - 2: Eq - 3: BrFalse(15) -B1: - 4: MoveLoc[1](d: &vector) - 5: Pop - 6: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) - 7: ImmBorrowGlobal[0](R) - 8: ImmBorrowField[0](R.data: vector) - 9: StLoc[2](v: &vector) -B2: - 10: MoveLoc[2](v: &vector) - 11: LdU64(0) - 12: VecImmBorrow(1) - 13: ReadRef - 14: Ret -B3: - 15: MoveLoc[1](d: &vector) - 16: StLoc[2](v: &vector) - 17: Branch(10) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp b/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp index e0a8ee9fb79..7207e7ff474 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp @@ -3782,79 +3782,75 @@ fun _0::check() { ============ disassembled file-format ================== -// Move bytecode v8 -script { +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + local l1: &mut u64 + local l2: vector + local l3: &mut vector + ld_u64 0 + ld_u64 0 + eq + br_false l0 + ld_const> [104, 101, 108, 108, 111] + // @5 + ld_const> [104, 101, 108, 108, 111] + eq + br_false l1 + ld_u64 0 + st_loc l0 + // @10 + mut_borrow_loc l0 + st_loc l1 + ld_u64 1 + copy_loc l1 + write_ref + // @15 + ld_const> [104, 101, 108, 108, 111] + st_loc l2 + mut_borrow_loc l2 + st_loc l3 + ld_const> [98, 121, 101] + // @20 + copy_loc l3 + write_ref + move_loc l1 + read_ref + ld_u64 1 + // @25 + eq + br_false l2 + move_loc l3 + read_ref + ld_const> [98, 121, 101] + // @30 + eq + br_false l3 + ret + ld_u64 42 + abort + // @35 + ld_u64 42 + abort +l3: ld_u64 42 + abort +l2: move_loc l3 + // @40 + pop + ld_u64 42 + abort +l1: ld_u64 42 + abort + // @45 +l0: ld_u64 42 + abort + ld_u64 42 + abort + ld_u64 42 + // @50 + abort -main() /* def_idx: 0 */ { -L0: $t13: u64 -L1: c: &mut u64 -L2: $t16: vector -L3: b: &mut vector -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Eq - 3: BrFalse(45) -B1: - 4: LdConst[0](Vector(U8): [5, 104, 101, 108, 108, 111]) - 5: LdConst[0](Vector(U8): [5, 104, 101, 108, 108, 111]) - 6: Eq - 7: BrFalse(43) -B2: - 8: LdU64(0) - 9: StLoc[0]($t13: u64) - 10: MutBorrowLoc[0]($t13: u64) - 11: StLoc[1](c: &mut u64) - 12: LdU64(1) - 13: CopyLoc[1](c: &mut u64) - 14: WriteRef - 15: LdConst[0](Vector(U8): [5, 104, 101, 108, 108, 111]) - 16: StLoc[2]($t16: vector) - 17: MutBorrowLoc[2]($t16: vector) - 18: StLoc[3](b: &mut vector) - 19: LdConst[1](Vector(U8): [3, 98, 121, 101]) - 20: CopyLoc[3](b: &mut vector) - 21: WriteRef - 22: MoveLoc[1](c: &mut u64) - 23: ReadRef - 24: LdU64(1) - 25: Eq - 26: BrFalse(39) -B3: - 27: MoveLoc[3](b: &mut vector) - 28: ReadRef - 29: LdConst[1](Vector(U8): [3, 98, 121, 101]) - 30: Eq - 31: BrFalse(37) -B4: - 32: Ret -B5: - 33: LdU64(42) - 34: Abort -B6: - 35: LdU64(42) - 36: Abort -B7: - 37: LdU64(42) - 38: Abort -B8: - 39: MoveLoc[3](b: &mut vector) - 40: Pop - 41: LdU64(42) - 42: Abort -B9: - 43: LdU64(42) - 44: Abort -B10: - 45: LdU64(42) - 46: Abort -B11: - 47: LdU64(42) - 48: Abort -B12: - 49: LdU64(42) - 50: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/copy_ability_tuple.exp b/third_party/move/move-compiler-v2/tests/ability-transform/copy_ability_tuple.exp index 0113c027d6d..1bc208c1fd6 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/copy_ability_tuple.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/copy_ability_tuple.exp @@ -705,30 +705,30 @@ public fun M::g($t0: &signer) { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.M { -struct R has key { - f: u64 -} +// Bytecode version v9 +module 0x42::M +struct R has key + f: u64 + +// Function definition at index 0 +#[persistent] public fun f(l0: R): (R, u64) + move_loc l0 + ld_u64 0 + ret + +// Function definition at index 1 +#[persistent] public fun g(l0: &signer) + local l1: R + ld_u64 1 + pack R + call f + pop + st_loc l1 + // @5 + move_loc l0 + move_loc l1 + move_to R + ret + -public f(r: R): R * u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](r: R) - 1: LdU64(0) - 2: Ret -} -public g(s: &signer) /* def_idx: 1 */ { -L1: r: R -B0: - 0: LdU64(1) - 1: Pack[0](R) - 2: Call f(R): R * u64 - 3: Pop - 4: StLoc[1](r: R) - 5: MoveLoc[0](s: &signer) - 6: MoveLoc[1](r: R) - 7: MoveTo[0](R) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp b/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp index a608d5ea259..6b69d436c03 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp @@ -295,18 +295,16 @@ fun explicate_drop::test0(): u8 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.explicate_drop { - - -test0(): u8 /* def_idx: 0 */ { -L0: $t2: u8 -B0: - 0: LdU8(42) - 1: StLoc[0]($t2: u8) - 2: ImmBorrowLoc[0]($t2: u8) - 3: ReadRef - 4: Ret -} -} +// Bytecode version v9 +module 0x42::explicate_drop +// Function definition at index 0 +fun test0(): u8 + local l0: u8 + ld_u8 42 + st_loc l0 + borrow_loc l0 + read_ref + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/destroy_after_call.exp b/third_party/move/move-compiler-v2/tests/ability-transform/destroy_after_call.exp index fdbec23536b..fc27db0a099 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/destroy_after_call.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/destroy_after_call.exp @@ -618,28 +618,27 @@ fun m::g() { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +fun f(l0: &mut u64): &mut u64 + move_loc l0 + ret + +// Function definition at index 1 +fun g() + local l0: u64 + local l1: &mut u64 + local l2: &u64 + ld_u64 22 + st_loc l0 + mut_borrow_loc l0 + call f + pop + // @5 + borrow_loc l0 + pop + ret -f(r: &mut u64): &mut u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](r: &mut u64) - 1: Ret -} -g() /* def_idx: 1 */ { -L0: v: u64 -L1: r: &mut u64 -L2: _r: &u64 -B0: - 0: LdU64(22) - 1: StLoc[0](v: u64) - 2: MutBorrowLoc[0](v: u64) - 3: Call f(&mut u64): &mut u64 - 4: Pop - 5: ImmBorrowLoc[0](v: u64) - 6: Pop - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/drop_after_loop.exp b/third_party/move/move-compiler-v2/tests/ability-transform/drop_after_loop.exp index 4f16b1c014c..9bd5d2ce2c0 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/drop_after_loop.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/drop_after_loop.exp @@ -1351,43 +1351,40 @@ fun m::drop_after_loop() { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +fun drop_after_loop() + local l0: u64 + local l1: &mut u64 + local l2: bool + ld_u64 1 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + ld_true + // @5 + st_loc l2 +l1: move_loc l2 + br_false l0 + ld_u64 2 + copy_loc l1 + // @10 + write_ref + ld_false + st_loc l2 + branch l1 +l0: move_loc l1 + // @15 + pop + move_loc l0 + ld_u64 2 + eq + br_false l2 + // @20 + ret +l2: ld_u64 0 + abort -drop_after_loop() /* def_idx: 0 */ { -L0: l: u64 -L1: r: &mut u64 -L2: c: bool -B0: - 0: LdU64(1) - 1: StLoc[0](l: u64) - 2: MutBorrowLoc[0](l: u64) - 3: StLoc[1](r: &mut u64) - 4: LdTrue - 5: StLoc[2](c: bool) -B1: - 6: MoveLoc[2](c: bool) - 7: BrFalse(14) -B2: - 8: LdU64(2) - 9: CopyLoc[1](r: &mut u64) - 10: WriteRef - 11: LdFalse - 12: StLoc[2](c: bool) - 13: Branch(6) -B3: - 14: MoveLoc[1](r: &mut u64) - 15: Pop - 16: MoveLoc[0](l: u64) - 17: LdU64(2) - 18: Eq - 19: BrFalse(21) -B4: - 20: Ret -B5: - 21: LdU64(0) - 22: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/drop_at_branch.exp b/third_party/move/move-compiler-v2/tests/ability-transform/drop_at_branch.exp index 8ada2bdc906..f022aa07f47 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/drop_at_branch.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/drop_at_branch.exp @@ -305,21 +305,19 @@ fun explicate_drop::drop_at_branch($t0: bool): u8 { fun explicate_drop::drop_at_branch($t0: bool): u8 { var $t1: u8 # live vars: $t0 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 # live vars: 1: label L0 # live vars: 2: $t1 := 1 # live vars: $t1 - 3: label L2 - # live vars: $t1 - 4: return $t1 + 3: return $t1 # live vars: - 5: label L1 + 4: label L1 # live vars: - 6: $t1 := 0 + 5: $t1 := 0 # live vars: $t1 - 7: goto 3 + 6: return $t1 } ============ after LiveVarAnalysisProcessor: ================ @@ -328,21 +326,19 @@ fun explicate_drop::drop_at_branch($t0: bool): u8 { fun explicate_drop::drop_at_branch($t0: bool): u8 { var $t1: u8 # live vars: $t0 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 # live vars: 1: label L0 # live vars: 2: $t1 := 1 # live vars: $t1 - 3: label L2 - # live vars: $t1 - 4: return $t1 + 3: return $t1 # live vars: - 5: label L1 + 4: label L1 # live vars: - 6: $t1 := 0 + 5: $t1 := 0 # live vars: $t1 - 7: goto 3 + 6: return $t1 } ============ after LiveVarAnalysisProcessor: ================ @@ -351,21 +347,19 @@ fun explicate_drop::drop_at_branch($t0: bool): u8 { fun explicate_drop::drop_at_branch($t0: bool): u8 { var $t1: u8 # live vars: $t0 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 # live vars: 1: label L0 # live vars: 2: $t1 := 1 # live vars: $t1 - 3: label L2 - # live vars: $t1 - 4: return $t1 + 3: return $t1 # live vars: - 5: label L1 + 4: label L1 # live vars: - 6: $t1 := 0 + 5: $t1 := 0 # live vars: $t1 - 7: goto 3 + 6: return $t1 } ============ after LiveVarAnalysisProcessor: ================ @@ -374,44 +368,34 @@ fun explicate_drop::drop_at_branch($t0: bool): u8 { fun explicate_drop::drop_at_branch($t0: bool): u8 { var $t1: u8 # live vars: $t0 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 # live vars: 1: label L0 # live vars: 2: $t1 := 1 # live vars: $t1 - 3: label L2 - # live vars: $t1 - 4: return $t1 + 3: return $t1 # live vars: - 5: label L1 + 4: label L1 # live vars: - 6: $t1 := 0 + 5: $t1 := 0 # live vars: $t1 - 7: goto 3 + 6: return $t1 } ============ disassembled file-format ================== -// Move bytecode v8 -module 42.explicate_drop { - - -drop_at_branch(x: bool): u8 /* def_idx: 0 */ { -L1: return: u8 -B0: - 0: MoveLoc[0](x: bool) - 1: BrFalse(6) -B1: - 2: LdU8(1) - 3: StLoc[1](return: u8) -B2: - 4: MoveLoc[1](return: u8) - 5: Ret -B3: - 6: LdU8(0) - 7: StLoc[1](return: u8) - 8: Branch(4) -} -} +// Bytecode version v9 +module 0x42::explicate_drop +// Function definition at index 0 +fun drop_at_branch(l0: bool): u8 + move_loc l0 + br_false l0 + ld_u8 1 + ret +l0: ld_u8 0 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp b/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp index 6ed409046e4..1f3bdbc1bd1 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp @@ -2005,57 +2005,56 @@ fun m::test_for_each_mut() { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +fun test_for_each_mut() + local l0: vector + local l1: u64 + local l2: u64 + local l3: &mut vector + local l4: u64 + local l5: &mut u64 + ld_const> [1, 2, 3] + st_loc l0 + ld_u64 0 + st_loc l1 + borrow_loc l0 + // @5 + vec_len + st_loc l2 + mut_borrow_loc l0 + st_loc l3 +l1: copy_loc l1 + // @10 + copy_loc l2 + lt + br_false l0 + copy_loc l3 + copy_loc l1 + // @15 + vec_mut_borrow + st_loc l5 + ld_u64 2 + move_loc l5 + write_ref + // @20 + move_loc l1 + ld_u64 1 + add + st_loc l1 + branch l1 + // @25 +l0: move_loc l3 + pop + move_loc l0 + ld_const> [2, 3, 4] + eq + // @30 + br_false l2 + ret +l2: ld_u64 0 + abort -test_for_each_mut() /* def_idx: 0 */ { -L0: v: vector -L1: i: u64 -L2: len: u64 -L3: vr: &mut vector -L4: $t6: u64 -L5: x: &mut u64 -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: StLoc[0](v: vector) - 2: LdU64(0) - 3: StLoc[1](i: u64) - 4: ImmBorrowLoc[0](v: vector) - 5: VecLen(1) - 6: StLoc[2](len: u64) - 7: MutBorrowLoc[0](v: vector) - 8: StLoc[3](vr: &mut vector) -B1: - 9: CopyLoc[1](i: u64) - 10: CopyLoc[2](len: u64) - 11: Lt - 12: BrFalse(25) -B2: - 13: CopyLoc[3](vr: &mut vector) - 14: CopyLoc[1](i: u64) - 15: VecMutBorrow(1) - 16: StLoc[5](x: &mut u64) - 17: LdU64(2) - 18: MoveLoc[5](x: &mut u64) - 19: WriteRef - 20: MoveLoc[1](i: u64) - 21: LdU64(1) - 22: Add - 23: StLoc[1](i: u64) - 24: Branch(9) -B3: - 25: MoveLoc[3](vr: &mut vector) - 26: Pop - 27: MoveLoc[0](v: vector) - 28: LdConst[1](Vector(U64): [3, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0]) - 29: Eq - 30: BrFalse(32) -B4: - 31: Ret -B5: - 32: LdU64(0) - 33: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/mutate_return.exp b/third_party/move/move-compiler-v2/tests/ability-transform/mutate_return.exp index ba5a97f2209..4707ae29835 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/mutate_return.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/mutate_return.exp @@ -468,26 +468,25 @@ fun m::g<#0>($t0: &mut vector<#0>) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public singleton(e: Element): vector /* def_idx: 0 */ { -L1: v: vector -B0: - 0: MoveLoc[0](e: Element) - 1: VecPack(0, 1) - 2: StLoc[1](v: vector) - 3: MutBorrowLoc[1](v: vector) - 4: Call g(&mut vector) - 5: MoveLoc[1](v: vector) - 6: Ret -} -g(_v: &mut vector) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](_v: &mut vector) - 1: Pop - 2: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun singleton(l0: T0): vector + local l1: vector + move_loc l0 + vec_pack , 1 + st_loc l1 + mut_borrow_loc l1 + call g + // @5 + move_loc l1 + ret + +// Function definition at index 1 +fun g(l0: &mut vector) + move_loc l0 + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/mutate_vector.exp b/third_party/move/move-compiler-v2/tests/ability-transform/mutate_vector.exp index 3469a2fdbb8..3454965bcca 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/mutate_vector.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/mutate_vector.exp @@ -745,34 +745,35 @@ public fun m::scalar_zero(): 0x42::m::Scalar { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct Scalar has copy, drop, store { - data: vector -} +// Bytecode version v9 +module 0x42::m +struct Scalar has copy + drop + store + data: vector + +// Function definition at index 0 +#[persistent] public fun new_scalar_from_u8(l0: u8): Scalar + local l1: Scalar + local l2: &mut u8 + call scalar_zero + st_loc l1 + mut_borrow_loc l1 + mut_borrow_field Scalar, data + ld_u64 0 + // @5 + vec_mut_borrow + st_loc l2 + move_loc l0 + move_loc l2 + write_ref + // @10 + move_loc l1 + ret + +// Function definition at index 1 +#[persistent] public fun scalar_zero(): Scalar + ld_const> [0] + pack Scalar + ret + -public new_scalar_from_u8(byte: u8): Scalar /* def_idx: 0 */ { -L1: s: Scalar -L2: byte_zero: &mut u8 -B0: - 0: Call scalar_zero(): Scalar - 1: StLoc[1](s: Scalar) - 2: MutBorrowLoc[1](s: Scalar) - 3: MutBorrowField[0](Scalar.data: vector) - 4: LdU64(0) - 5: VecMutBorrow(0) - 6: StLoc[2](byte_zero: &mut u8) - 7: MoveLoc[0](byte: u8) - 8: MoveLoc[2](byte_zero: &mut u8) - 9: WriteRef - 10: MoveLoc[1](s: Scalar) - 11: Ret -} -public scalar_zero(): Scalar /* def_idx: 1 */ { -B0: - 0: LdConst[0](Vector(U8): [1, 0]) - 1: Pack[0](Scalar) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/assign.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/assign.exp index d217f6b6797..ccf18f4a769 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/assign.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/assign.exp @@ -41,11 +41,11 @@ module 0x42::assign { *x = 42; } fun assign_pattern(s: S, f: u64, h: u64): u64 { - S{f: f,g: T{h: h}} = s; + S{f: f, g: T{h: h}} = s; f + h } fun assign_struct(s: &mut S) { - *s = S{f: 42,g: T{h: 42}}; + *s = S{f: 42, g: T{h: 42}}; } } @@ -186,51 +186,52 @@ fun assign::assign_struct($t0: &mut 0x42::assign::S) { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.assign { -struct T has drop { - h: u64 -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::assign +struct T has drop + h: u64 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun assign_field(l0: &mut S, l1: u64) + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, f + st_loc l2 + move_loc l1 + move_loc l2 + // @5 + write_ref + ret + +// Function definition at index 1 +fun assign_int(l0: &mut u64) + ld_u64 42 + move_loc l0 + write_ref + ret + +// Function definition at index 2 +fun assign_pattern(l0: S, l1: u64, l2: u64): u64 + move_loc l0 + unpack S + unpack T + add + ret + +// Function definition at index 3 +fun assign_struct(l0: &mut S) + ld_u64 42 + ld_u64 42 + pack T + pack S + move_loc l0 + // @5 + write_ref + ret + -assign_field(s: &mut S, f: u64) /* def_idx: 0 */ { -L2: $t2: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: StLoc[2]($t2: &mut u64) - 3: MoveLoc[1](f: u64) - 4: MoveLoc[2]($t2: &mut u64) - 5: WriteRef - 6: Ret -} -assign_int(x: &mut u64) /* def_idx: 1 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut u64) - 2: WriteRef - 3: Ret -} -assign_pattern(s: S, f: u64, h: u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: Add - 4: Ret -} -assign_struct(s: &mut S) /* def_idx: 3 */ { -B0: - 0: LdU64(42) - 1: LdU64(42) - 2: Pack[0](T) - 3: Pack[1](S) - 4: MoveLoc[0](s: &mut S) - 5: WriteRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/assign_inline.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/assign_inline.exp index 9a618705890..880403c268a 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/assign_inline.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/assign_inline.exp @@ -70,15 +70,13 @@ public fun assign::main(): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.assign { +// Bytecode version v9 +module 0x42::assign +// Function definition at index 0 +#[persistent] public fun main(): (u64, u64) + ld_u64 1 + ld_u64 3 + ret -public main(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(3) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow.exp index 18150657fc8..3251a66e6df 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow.exp @@ -299,73 +299,75 @@ fun borrow::mut_param($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.borrow { -struct S { - f: u64 -} +// Bytecode version v9 +module 0x42::borrow +struct S + f: u64 + +// Function definition at index 0 +fun field(l0: &S): u64 + move_loc l0 + borrow_field S, f + read_ref + ret + +// Function definition at index 1 +fun local(l0: u64): u64 + local l1: u64 + ld_u64 33 + st_loc l1 + borrow_loc l1 + read_ref + ret + +// Function definition at index 2 +fun param(l0: u64): u64 + borrow_loc l0 + read_ref + ret + +// Function definition at index 3 +fun mut_field(l0: &mut S): u64 + local l1: &mut u64 + move_loc l0 + mut_borrow_field S, f + st_loc l1 + ld_u64 22 + copy_loc l1 + // @5 + write_ref + move_loc l1 + read_ref + ret + +// Function definition at index 4 +fun mut_local(l0: u64): u64 + local l1: u64 + local l2: &mut u64 + ld_u64 33 + st_loc l1 + mut_borrow_loc l1 + st_loc l2 + ld_u64 22 + // @5 + copy_loc l2 + write_ref + move_loc l2 + read_ref + ret + +// Function definition at index 5 +fun mut_param(l0: u64): u64 + local l1: &mut u64 + mut_borrow_loc l0 + st_loc l1 + ld_u64 22 + copy_loc l1 + write_ref + // @5 + move_loc l1 + read_ref + ret + -field(s: &S): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](s: &S) - 1: ImmBorrowField[0](S.f: u64) - 2: ReadRef - 3: Ret -} -local(param: u64): u64 /* def_idx: 1 */ { -L1: $t3: u64 -B0: - 0: LdU64(33) - 1: StLoc[1]($t3: u64) - 2: ImmBorrowLoc[1]($t3: u64) - 3: ReadRef - 4: Ret -} -param(param: u64): u64 /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](param: u64) - 1: ReadRef - 2: Ret -} -mut_field(s: &mut S): u64 /* def_idx: 3 */ { -L1: r: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: StLoc[1](r: &mut u64) - 3: LdU64(22) - 4: CopyLoc[1](r: &mut u64) - 5: WriteRef - 6: MoveLoc[1](r: &mut u64) - 7: ReadRef - 8: Ret -} -mut_local(param: u64): u64 /* def_idx: 4 */ { -L1: local: u64 -L2: r: &mut u64 -B0: - 0: LdU64(33) - 1: StLoc[1](local: u64) - 2: MutBorrowLoc[1](local: u64) - 3: StLoc[2](r: &mut u64) - 4: LdU64(22) - 5: CopyLoc[2](r: &mut u64) - 6: WriteRef - 7: MoveLoc[2](r: &mut u64) - 8: ReadRef - 9: Ret -} -mut_param(param: u64): u64 /* def_idx: 5 */ { -L1: r: &mut u64 -B0: - 0: MutBorrowLoc[0](param: u64) - 1: StLoc[1](r: &mut u64) - 2: LdU64(22) - 3: CopyLoc[1](r: &mut u64) - 4: WriteRef - 5: MoveLoc[1](r: &mut u64) - 6: ReadRef - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp index ab5dd9b83b2..7def2646ea7 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/borrow_deref_optimize.exp @@ -47,7 +47,7 @@ module 0x42::test { fun no_optimize_resource(): bool acquires X { - let x = &mut *borrow_global(0x1); + let x = &mut *borrow_global(@0x1); x.value } fun no_optimize_vector() { @@ -57,7 +57,7 @@ module 0x42::test { fun optimize_resource(): bool acquires X { - let x = &*borrow_global(0x1); + let x = &*borrow_global(@0x1); x.value } fun optimize_vector() { @@ -272,63 +272,66 @@ fun test::optimize_vector() { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -struct X has copy, drop, key { - value: bool -} +// Bytecode version v9 +module 0x42::test +struct X has copy + drop + key + value: bool + +// Function definition at index 0 +fun no_optimize_resource(): bool acquires X + local l0: X + ld_const
1 + borrow_global X + read_ref + st_loc l0 + mut_borrow_loc l0 + // @5 + borrow_field X, value + read_ref + ret + +// Function definition at index 1 +fun no_optimize_vector() + local l0: vector> + local l1: vector + local l2: &mut u64 + ld_const>> [[1, 2]] + st_loc l0 + borrow_loc l0 + ld_u64 0 + vec_borrow > + // @5 + read_ref + st_loc l1 + mut_borrow_loc l1 + ld_u64 1 + vec_mut_borrow + // @10 + pop + ret + +// Function definition at index 2 +fun optimize_resource(): bool acquires X + ld_const
1 + borrow_global X + borrow_field X, value + read_ref + ret + +// Function definition at index 3 +fun optimize_vector() + local l0: vector> + local l1: &mut u64 + ld_const>> [[1, 2]] + st_loc l0 + mut_borrow_loc l0 + ld_u64 0 + vec_mut_borrow > + // @5 + ld_u64 1 + vec_mut_borrow + pop + ret + -no_optimize_resource(): bool /* def_idx: 0 */ { -L0: $t2: X -B0: - 0: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) - 1: ImmBorrowGlobal[0](X) - 2: ReadRef - 3: StLoc[0]($t2: X) - 4: MutBorrowLoc[0]($t2: X) - 5: ImmBorrowField[0](X.value: bool) - 6: ReadRef - 7: Ret -} -no_optimize_vector() /* def_idx: 1 */ { -L0: $t5: vector> -L1: $t2: vector -L2: $t0: &mut u64 -B0: - 0: LdConst[1](Vector(Vector(U64)): [1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]) - 1: StLoc[0]($t5: vector>) - 2: ImmBorrowLoc[0]($t5: vector>) - 3: LdU64(0) - 4: VecImmBorrow(3) - 5: ReadRef - 6: StLoc[1]($t2: vector) - 7: MutBorrowLoc[1]($t2: vector) - 8: LdU64(1) - 9: VecMutBorrow(4) - 10: Pop - 11: Ret -} -optimize_resource(): bool /* def_idx: 2 */ { -B0: - 0: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) - 1: ImmBorrowGlobal[0](X) - 2: ImmBorrowField[0](X.value: bool) - 3: ReadRef - 4: Ret -} -optimize_vector() /* def_idx: 3 */ { -L0: x: vector> -L1: $t1: &mut u64 -B0: - 0: LdConst[1](Vector(Vector(U64)): [1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]) - 1: StLoc[0](x: vector>) - 2: MutBorrowLoc[0](x: vector>) - 3: LdU64(0) - 4: VecMutBorrow(3) - 5: LdU64(1) - 6: VecMutBorrow(4) - 7: Pop - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_update_variant_select.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_update_variant_select.exp index 69faa087477..bedd394d726 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_update_variant_select.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_update_variant_select.exp @@ -54,17 +54,17 @@ module 0x815::m { } } fun update_common_field(): u64 { - let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32}; + let common = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; common.x = 15; common.x } fun update_common_field_different_offset(): u8 { - let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32}; + let common = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; common.y = 15u8; common.y } fun update_non_common_field(): u32 { - let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32}; + let common = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; common.z = 15u32; common.z } @@ -327,124 +327,121 @@ fun m::update_non_common_field(): u32 { ============ disassembled file-format ================== -// Move bytecode v8 -module 815.m { -enum CommonFields has drop { - Foo{ - x: u64, - y: u8 - }, - Bar{ - x: u64, - y: u8, - z: u32 - }, - Baz{ - y: u8 - } -} +// Bytecode version v9 +module 0x815::m +enum CommonFields has drop + Foo + x: u64 + y: u8 + Bar + x: u64 + y: u8 + z: u32 + Baz + y: u8 + +// Function definition at index 0 +fun update_common_field(): u64 + local l0: CommonFields + ld_u64 30 + ld_u8 40 + ld_u32 50 + pack_variant CommonFields, Bar + st_loc l0 + // @5 + ld_u64 15 + mut_borrow_loc l0 + mut_borrow_variant_field CommonFields, Foo::x, Bar::x + write_ref + borrow_loc l0 + // @10 + borrow_variant_field CommonFields, Foo::x, Bar::x + read_ref + ret + +// Function definition at index 1 +fun update_common_field_different_offset(): u8 + local l0: CommonFields + local l1: u8 + local l2: &mut CommonFields + local l3: &mut u8 + local l4: &CommonFields + local l5: &u8 + ld_u64 30 + ld_u8 40 + ld_u32 50 + pack_variant CommonFields, Bar + st_loc l0 + // @5 + ld_u8 15 + st_loc l1 + mut_borrow_loc l0 + st_loc l2 + copy_loc l2 + // @10 + test_variant CommonFields, Foo + br_false l0 + branch l1 +l1: move_loc l2 + mut_borrow_variant_field CommonFields, Foo::y, Bar::y + // @15 + st_loc l3 +l7: move_loc l1 + move_loc l3 + write_ref + borrow_loc l0 + // @20 + st_loc l4 + copy_loc l4 + test_variant CommonFields, Foo + br_false l2 + branch l3 + // @25 +l3: move_loc l4 + borrow_variant_field CommonFields, Foo::y, Bar::y + st_loc l5 +l5: move_loc l5 + read_ref + // @30 + ret +l2: copy_loc l4 + test_variant CommonFields, Bar + br_false l4 + branch l3 + // @35 +l4: move_loc l4 + borrow_variant_field CommonFields, Baz::y + st_loc l5 + branch l5 +l0: copy_loc l2 + // @40 + test_variant CommonFields, Bar + br_false l6 + branch l1 +l6: move_loc l2 + mut_borrow_variant_field CommonFields, Baz::y + // @45 + st_loc l3 + branch l7 + +// Function definition at index 2 +fun update_non_common_field(): u32 + local l0: CommonFields + ld_u64 30 + ld_u8 40 + ld_u32 50 + pack_variant CommonFields, Bar + st_loc l0 + // @5 + ld_u32 15 + mut_borrow_loc l0 + mut_borrow_variant_field CommonFields, Bar::z + write_ref + borrow_loc l0 + // @10 + borrow_variant_field CommonFields, Bar::z + read_ref + ret + -update_common_field(): u64 /* def_idx: 0 */ { -L0: common: CommonFields -B0: - 0: LdU64(30) - 1: LdU8(40) - 2: LdU32(50) - 3: PackVariant[0](CommonFields/Bar) - 4: StLoc[0](common: CommonFields) - 5: LdU64(15) - 6: MutBorrowLoc[0](common: CommonFields) - 7: MutBorrowVariantField[0](Foo.x|Bar.x: u64) - 8: WriteRef - 9: ImmBorrowLoc[0](common: CommonFields) - 10: ImmBorrowVariantField[0](Foo.x|Bar.x: u64) - 11: ReadRef - 12: Ret -} -update_common_field_different_offset(): u8 /* def_idx: 1 */ { -L0: common: CommonFields -L1: $t3: u8 -L2: $t7: &mut CommonFields -L3: $t6: &mut u8 -L4: $t9: &CommonFields -L5: $t10: &u8 -B0: - 0: LdU64(30) - 1: LdU8(40) - 2: LdU32(50) - 3: PackVariant[0](CommonFields/Bar) - 4: StLoc[0](common: CommonFields) - 5: LdU8(15) - 6: StLoc[1]($t3: u8) - 7: MutBorrowLoc[0](common: CommonFields) - 8: StLoc[2]($t7: &mut CommonFields) - 9: CopyLoc[2]($t7: &mut CommonFields) - 10: TestVariant[1](CommonFields/Foo) - 11: BrFalse(39) -B1: - 12: Branch(13) -B2: - 13: MoveLoc[2]($t7: &mut CommonFields) - 14: MutBorrowVariantField[1](Foo.y|Bar.y: u8) - 15: StLoc[3]($t6: &mut u8) -B3: - 16: MoveLoc[1]($t3: u8) - 17: MoveLoc[3]($t6: &mut u8) - 18: WriteRef - 19: ImmBorrowLoc[0](common: CommonFields) - 20: StLoc[4]($t9: &CommonFields) - 21: CopyLoc[4]($t9: &CommonFields) - 22: TestVariant[1](CommonFields/Foo) - 23: BrFalse(31) -B4: - 24: Branch(25) -B5: - 25: MoveLoc[4]($t9: &CommonFields) - 26: ImmBorrowVariantField[1](Foo.y|Bar.y: u8) - 27: StLoc[5]($t10: &u8) -B6: - 28: MoveLoc[5]($t10: &u8) - 29: ReadRef - 30: Ret -B7: - 31: CopyLoc[4]($t9: &CommonFields) - 32: TestVariant[0](CommonFields/Bar) - 33: BrFalse(35) -B8: - 34: Branch(25) -B9: - 35: MoveLoc[4]($t9: &CommonFields) - 36: ImmBorrowVariantField[2](Baz.y: u8) - 37: StLoc[5]($t10: &u8) - 38: Branch(28) -B10: - 39: CopyLoc[2]($t7: &mut CommonFields) - 40: TestVariant[0](CommonFields/Bar) - 41: BrFalse(43) -B11: - 42: Branch(13) -B12: - 43: MoveLoc[2]($t7: &mut CommonFields) - 44: MutBorrowVariantField[2](Baz.y: u8) - 45: StLoc[3]($t6: &mut u8) - 46: Branch(16) -} -update_non_common_field(): u32 /* def_idx: 2 */ { -L0: common: CommonFields -B0: - 0: LdU64(30) - 1: LdU8(40) - 2: LdU32(50) - 3: PackVariant[0](CommonFields/Bar) - 4: StLoc[0](common: CommonFields) - 5: LdU32(15) - 6: MutBorrowLoc[0](common: CommonFields) - 7: MutBorrowVariantField[3](Bar.z: u32) - 8: WriteRef - 9: ImmBorrowLoc[0](common: CommonFields) - 10: ImmBorrowVariantField[3](Bar.z: u32) - 11: ReadRef - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_variant_select_autoref.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_variant_select_autoref.exp index 92fa17e39bc..6536963d970 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_variant_select_autoref.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14300_variant_select_autoref.exp @@ -95,29 +95,27 @@ fun m::test_common_access(): u8 { ============ disassembled file-format ================== -// Move bytecode v8 -module 815.m { -enum Positional has drop { - A{ - _0: u8 - }, - B{ - _0: u8 - } -} +// Bytecode version v9 +module 0x815::m +enum Positional has drop + A + _0: u8 + B + _0: u8 + +// Function definition at index 0 +fun test_common_access(): u8 + local l0: Positional + ld_u8 42 + pack_variant Positional, A + st_loc l0 + ld_u8 19 + mut_borrow_loc l0 + // @5 + mut_borrow_variant_field Positional, A::_0, B::_0 + write_ref + ld_u8 20 + ret + -test_common_access(): u8 /* def_idx: 0 */ { -L0: x: Positional -B0: - 0: LdU8(42) - 1: PackVariant[0](Positional/A) - 2: StLoc[0](x: Positional) - 3: LdU8(19) - 4: MutBorrowLoc[0](x: Positional) - 5: MutBorrowVariantField[0](A._0|B._0: u8) - 6: WriteRef - 7: LdU8(20) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp index e3a3f78e932..31b21752ab8 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14471_receiver_inference.exp @@ -54,7 +54,7 @@ module 0x815::m { public fun add_when_missing(key: address, val: u64) acquires MyMap { - let my_map = borrow_global_mut(0x815); + let my_map = borrow_global_mut(@0x815); if (!contains(&my_map.table, key)) { let wrap = ValueWrap{val: val}; add(&mut my_map.table, key, wrap); @@ -186,59 +186,58 @@ public fun m::add_when_missing($t0: address, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module 815.m { -struct MyMap has key { - table: Table -} -struct Table has store { - x: T1, - y: T2 -} -struct ValueWrap has drop, store { - val: u64 -} +// Bytecode version v9 +module 0x815::m +struct MyMap has key + table: Table + +struct Table has store + x: T0 + y: T1 + +struct ValueWrap has drop + store + val: u64 + +// Function definition at index 0 +fun contains(l0: &Table, l1: T0): bool + ld_true + move_loc l0 + pop + ret + +// Function definition at index 1 +fun add(l0: &mut Table, l1: T0, l2: T1) + move_loc l0 + pop + ret + +// Function definition at index 2 +#[persistent] public fun add_when_missing(l0: address, l1: u64) acquires MyMap + local l2: &mut MyMap + local l3: ValueWrap + ld_const
2069 + mut_borrow_global MyMap + st_loc l2 + copy_loc l2 + borrow_field MyMap, table + // @5 + copy_loc l0 + call contains + br_true l0 + move_loc l1 + pack ValueWrap + // @10 + st_loc l3 + move_loc l2 + mut_borrow_field MyMap, table + move_loc l0 + move_loc l3 + // @15 + call add + ret +l0: move_loc l2 + pop + ret + -contains(self: &Table, _key: T1): bool /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: MoveLoc[0](self: &Table) - 2: Pop - 3: Ret -} -add(self: &mut Table, _key: T1, _val: T2) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](self: &mut Table) - 1: Pop - 2: Ret -} -public add_when_missing(key: address, val: u64) /* def_idx: 2 */ { -L2: my_map: &mut MyMap -L3: wrap: ValueWrap -B0: - 0: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 21]) - 1: MutBorrowGlobal[0](MyMap) - 2: StLoc[2](my_map: &mut MyMap) - 3: CopyLoc[2](my_map: &mut MyMap) - 4: ImmBorrowField[0](MyMap.table: Table) - 5: CopyLoc[0](key: address) - 6: Call contains(&Table, address): bool - 7: BrTrue(17) -B1: - 8: MoveLoc[1](val: u64) - 9: Pack[2](ValueWrap) - 10: StLoc[3](wrap: ValueWrap) - 11: MoveLoc[2](my_map: &mut MyMap) - 12: MutBorrowField[0](MyMap.table: Table) - 13: MoveLoc[0](key: address) - 14: MoveLoc[3](wrap: ValueWrap) - 15: Call add(&mut Table, address, ValueWrap) -B2: - 16: Ret -B3: - 17: MoveLoc[2](my_map: &mut MyMap) - 18: Pop - 19: Branch(16) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14629.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14629.exp index 0794863b078..a9c0afa6e89 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14629.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_14629.exp @@ -136,32 +136,33 @@ fun M::t0_u128() { ============ disassembled file-format ================== -// Move bytecode v8 -module 8675309.M { -struct R { - r: T -} -struct X has drop, key { - r: T -} +// Bytecode version v9 +module 0x8675309::M +struct R + r: T0 + +struct X has drop + key + r: T0 + +// Function definition at index 0 +fun t0() + ld_u64 0 + pack X + pack R> + unpack R> + pop + // @5 + ret + +// Function definition at index 1 +fun t0_u128() + ld_u128 18446744073709551616 + pack X + pack R> + unpack R> + pop + // @5 + ret + -t0() /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: PackGeneric[0](X) - 2: PackGeneric[1](R>) - 3: UnpackGeneric[1](R>) - 4: Pop - 5: Ret -} -t0_u128() /* def_idx: 1 */ { -B0: - 0: LdU128(18446744073709551616) - 1: PackGeneric[2](X) - 2: PackGeneric[3](R>) - 3: UnpackGeneric[3](R>) - 4: Pop - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222.exp index 64537f6afdb..40f211b6141 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222.exp @@ -13,7 +13,7 @@ module 0xc0ffee::m { module 0xc0ffee::n { public fun test() { { - let l: 0xc0ffee::m::Lazy = m::make_lazy(); + let l: m::Lazy = m::make_lazy(); (l)(); Tuple() } @@ -26,9 +26,9 @@ module 0xc0ffee::m { 0: || has drop, } public fun make_lazy(): Lazy { - Lazy(|()| __lambda__1__make_lazy()) + Lazy(|| lambda__1__make_lazy()) } - fun __lambda__1__make_lazy() { + fun lambda__1__make_lazy() { } } module 0xc0ffee::n { @@ -40,7 +40,7 @@ module 0xc0ffee::n { Diagnostics: -error: cannot unpack a wrapper struct `m::Lazy` (defined in a different module `0xc0ffee::m`) and invoke the wrapped function value +error: cannot implicitly unpack a wrapper struct `m::Lazy` defined in a different module `0xc0ffee::m` and invoke the wrapped function value ┌─ tests/bytecode-generator/bug_16222.move:13:9 │ 13 │ l(); diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.exp new file mode 100644 index 00000000000..9a5ce7b338b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.exp @@ -0,0 +1,241 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m::Lazy(closure#0m::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m_friend::Lazy(closure#0m_friend::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test() { + { + let l: m::Lazy = m::make_lazy(); + (l)(); + Tuple() + } + } + public fun test_friend() { + { + let l: m_friend::Lazy = m_friend::make_lazy(); + (l)(); + Tuple() + } + } +} // end 0xc0ffee::n + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + friend 0xc0ffee::n; + struct Lazy has drop { + 0: || has drop, + } + public fun make_lazy(): Lazy { + Lazy(|| lambda__1__make_lazy()) + } + fun lambda__1__make_lazy() { + } +} +module 0xc0ffee::m_friend { + friend 0xc0ffee::n; + struct Lazy has drop { + 0: || has drop, + } + public fun make_lazy(): Lazy { + Lazy(|| lambda__1__make_lazy()) + } + fun lambda__1__make_lazy() { + } +} +module 0xc0ffee::n { + public fun test() { + let l = 0xc0ffee::m::make_lazy(); + l(); + } + public fun test_friend() { + let l = 0xc0ffee::m_friend::make_lazy(); + l(); + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make_lazy(): 0xc0ffee::m::Lazy { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t1 := closure#0 m::__lambda__1__make_lazy() + 1: $t0 := pack 0xc0ffee::m::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun m::__lambda__1__make_lazy() { + 0: return () +} + + +[variant baseline] +public fun m_friend::make_lazy(): 0xc0ffee::m_friend::Lazy { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t1 := closure#0 m_friend::__lambda__1__make_lazy() + 1: $t0 := pack 0xc0ffee::m_friend::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun m_friend::__lambda__1__make_lazy() { + 0: return () +} + + +[variant baseline] +public fun n::test() { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t0 := m::make_lazy() + 1: $t1 := unpack 0xc0ffee::m::Lazy($t0) + 2: invoke($t1) + 3: return () +} + + +[variant baseline] +public fun n::test_friend() { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t0 := m_friend::make_lazy() + 1: $t1 := unpack 0xc0ffee::m_friend::Lazy($t0) + 2: invoke($t1) + 3: return () +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m::Lazy(closure#0m::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m_friend::Lazy(closure#0m_friend::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test() { + { + let l: m::Lazy = m::make_lazy(); + (l)(); + Tuple() + } + } + public fun test_friend() { + { + let l: m_friend::Lazy = m_friend::make_lazy(); + (l)(); + Tuple() + } + } +} // end 0xc0ffee::n + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make_lazy(): 0xc0ffee::m::Lazy { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t1 := closure#0 m::__lambda__1__make_lazy() + 1: $t0 := pack 0xc0ffee::m::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun m::__lambda__1__make_lazy() { + 0: return () +} + + +[variant baseline] +public fun m_friend::make_lazy(): 0xc0ffee::m_friend::Lazy { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t1 := closure#0 m_friend::__lambda__1__make_lazy() + 1: $t0 := pack 0xc0ffee::m_friend::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun m_friend::__lambda__1__make_lazy() { + 0: return () +} + + +[variant baseline] +public fun n::test() { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t0 := m::make_lazy() + 1: $t1 := unpack 0xc0ffee::m::Lazy($t0) + 2: invoke($t1) + 3: return () +} + + +[variant baseline] +public fun n::test_friend() { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t0 := m_friend::make_lazy() + 1: $t1 := unpack 0xc0ffee::m_friend::Lazy($t0) + 2: invoke($t1) + 3: return () +} + + +Diagnostics: +bug: compiler internal error: struct not defined + ┌─ tests/bytecode-generator/bug_16222_fv_wrapper_unpack.move:20:16 + │ +20 │ public fun test() { + │ ^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/bytecode-generator/bug_16222_fv_wrapper_unpack.move:25:16 + │ +25 │ public fun test_friend() { + │ ^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.move new file mode 100644 index 00000000000..a9559ac76fe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack.move @@ -0,0 +1,29 @@ +module 0xc0ffee::m { + package struct Lazy(||) has drop; + + public fun make_lazy(): Lazy { + Lazy(|| {}) + } + +} + +module 0xc0ffee::m_friend { + friend 0xc0ffee::n; + friend struct Lazy(||) has drop; + + public fun make_lazy(): Lazy { + Lazy(|| {}) + } +} + +module 0xc0ffee::n { + public fun test() { + let l = 0xc0ffee::m::make_lazy(); + l(); + } + + public fun test_friend() { + let l = 0xc0ffee::m_friend::make_lazy(); + l(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.exp new file mode 100644 index 00000000000..bbc637a97d4 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.exp @@ -0,0 +1,89 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m::Lazy(closure#0m::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } + public fun make_lazy(): Lazy { + pack m_friend::Lazy(closure#0m_friend::__lambda__1__make_lazy()) + } + private fun __lambda__1__make_lazy() { + Tuple() + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test_friend() { + { + let l: m_friend::Lazy = m_friend::make_lazy(); + (l)(); + Tuple() + } + } +} // end 0xc0ffee::n +module 0xc0ffee1::n { + public fun test() { + { + let l: 0xc0ffee::m::Lazy = m::make_lazy(); + (l)(); + Tuple() + } + } +} // end 0xc0ffee1::n + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy has drop { + 0: || has drop, + } + public fun make_lazy(): Lazy { + Lazy(|| lambda__1__make_lazy()) + } + fun lambda__1__make_lazy() { + } +} +module 0xc0ffee::m_friend { + struct Lazy has drop { + 0: || has drop, + } + public fun make_lazy(): Lazy { + Lazy(|| lambda__1__make_lazy()) + } + fun lambda__1__make_lazy() { + } +} +module 0xc0ffee::n { + public fun test_friend() { + let l = 0xc0ffee::m_friend::make_lazy(); + l(); + } +} +module 0xc0ffee1::n { + public fun test() { + let l = 0xc0ffee::m::make_lazy(); + l(); + } +} + + +Diagnostics: +error: cannot implicitly unpack a wrapper struct `m_friend::Lazy` defined in a different module `0xc0ffee::m_friend` and invoke the wrapped function value because it has friend visibility + ┌─ tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.move:22:9 + │ +22 │ l(); + │ ^^^ + +error: cannot implicitly unpack a wrapper struct `m::Lazy` defined in a different module `0xc0ffee::m` and invoke the wrapped function value because it has package visibility + ┌─ tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.move:29:9 + │ +29 │ l(); + │ ^^^ diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.move new file mode 100644 index 00000000000..12975bba2da --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16222_fv_wrapper_unpack_failure.move @@ -0,0 +1,31 @@ +module 0xc0ffee::m { + package struct Lazy(||) has drop; + + public fun make_lazy(): Lazy { + Lazy(|| {}) + } + +} + +module 0xc0ffee::m_friend { + friend struct Lazy(||) has drop; + + public fun make_lazy(): Lazy { + Lazy(|| {}) + } +} + +module 0xc0ffee::n { + + public fun test_friend() { + let l = 0xc0ffee::m_friend::make_lazy(); + l(); + } +} + +module 0xc0ffee1::n { + public fun test() { + let l = 0xc0ffee::m::make_lazy(); + l(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16324.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16324.exp index d7a6e198e3a..ae3d4e60ba8 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16324.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16324.exp @@ -41,6 +41,7 @@ module 0xc0ffee::m { // -- Sourcified model before first bytecode pipeline module 0xc0ffee::m { + use std::vector; struct TestOrder has copy, drop, store { price: u64, size: u64, @@ -240,62 +241,63 @@ fun m::test_self($t0: vector<0xc0ffee::m::TestOrder>) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct TestOrder has copy, drop, store { - price: u64, - size: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct TestOrder has copy + drop + store + price: u64 + size: u64 + +// Function definition at index 0 +fun price(l0: &TestOrder): u64 + move_loc l0 + borrow_field TestOrder, price + read_ref + ret + +// Function definition at index 1 +fun size(l0: &TestOrder): u64 + move_loc l0 + borrow_field TestOrder, size + read_ref + ret + +// Function definition at index 2 +fun test_self(l0: vector) + local l1: &vector + local l2: u64 + local l3: &TestOrder + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + // @5 + copy_loc l1 + vec_len + lt + br_false l0 + copy_loc l1 + // @10 + copy_loc l2 + vec_borrow + st_loc l3 + copy_loc l3 + call price + // @15 + pop + move_loc l3 + call size + pop + move_loc l2 + // @20 + ld_u64 1 + add + st_loc l2 + branch l1 +l0: move_loc l1 + // @25 + pop + ret + -price(self: &TestOrder): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](self: &TestOrder) - 1: ImmBorrowField[0](TestOrder.price: u64) - 2: ReadRef - 3: Ret -} -size(self: &TestOrder): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](self: &TestOrder) - 1: ImmBorrowField[1](TestOrder.size: u64) - 2: ReadRef - 3: Ret -} -test_self(orders: vector) /* def_idx: 2 */ { -L1: $t2: &vector -L2: i: u64 -L3: $t8: &TestOrder -B0: - 0: ImmBorrowLoc[0](orders: vector) - 1: StLoc[1]($t2: &vector) - 2: LdU64(0) - 3: StLoc[2](i: u64) -B1: - 4: CopyLoc[2](i: u64) - 5: CopyLoc[1]($t2: &vector) - 6: VecLen(4) - 7: Lt - 8: BrFalse(24) -B2: - 9: CopyLoc[1]($t2: &vector) - 10: CopyLoc[2](i: u64) - 11: VecImmBorrow(4) - 12: StLoc[3]($t8: &TestOrder) - 13: CopyLoc[3]($t8: &TestOrder) - 14: Call price(&TestOrder): u64 - 15: Pop - 16: MoveLoc[3]($t8: &TestOrder) - 17: Call size(&TestOrder): u64 - 18: Pop - 19: MoveLoc[2](i: u64) - 20: LdU64(1) - 21: Add - 22: StLoc[2](i: u64) - 23: Branch(4) -B3: - 24: MoveLoc[1]($t2: &vector) - 25: Pop - 26: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543.exp index 16ffcde51cb..7cc5dcebb00 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543.exp @@ -5,7 +5,7 @@ module 0xc0ffee::m { } } // end 0xc0ffee::m module 0xc0ffee::n { - public fun test(): 0xc0ffee::m::Lazy { + public fun test(): m::Lazy { closure#0n::__lambda__1__test() } private fun __lambda__1__test() { @@ -20,16 +20,16 @@ module 0xc0ffee::m { } } module 0xc0ffee::n { - public fun test(): 0xc0ffee::m::Lazy { + public fun test(): m::Lazy { <> } - fun __lambda__1__test() { + fun lambda__1__test() { } } Diagnostics: -error: cannot implicitly pack a wrapper struct `0xc0ffee::m::Lazy` defined in a different module `0xc0ffee::m` +error: cannot implicitly pack a wrapper struct `m::Lazy` defined in a different module `0xc0ffee::m` ┌─ tests/bytecode-generator/bug_16543.move:8:9 │ 8 │ || {} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.exp new file mode 100644 index 00000000000..add1b7ece87 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.exp @@ -0,0 +1,161 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test(): m::Lazy { + closure#0n::__lambda__1__test() + } + public fun test_friend(): m_friend::Lazy { + closure#0n::__lambda__1__test_friend() + } + private fun __lambda__1__test() { + Tuple() + } + private fun __lambda__1__test_friend() { + Tuple() + } +} // end 0xc0ffee::n + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + friend 0xc0ffee::n; + struct Lazy has drop { + 0: || has drop, + } +} +module 0xc0ffee::m_friend { + friend 0xc0ffee::n; + struct Lazy has drop { + 0: || has drop, + } +} +module 0xc0ffee::n { + public fun test(): m::Lazy { + <> + } + public fun test_friend(): m_friend::Lazy { + <> + } + fun lambda__1__test() { + } + fun lambda__1__test_friend() { + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +public fun n::test(): 0xc0ffee::m::Lazy { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t1 := closure#0 n::__lambda__1__test() + 1: $t0 := pack 0xc0ffee::m::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +public fun n::test_friend(): 0xc0ffee::m_friend::Lazy { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t1 := closure#0 n::__lambda__1__test_friend() + 1: $t0 := pack 0xc0ffee::m_friend::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun n::__lambda__1__test() { + 0: return () +} + + +[variant baseline] +fun n::__lambda__1__test_friend() { + 0: return () +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test(): m::Lazy { + closure#0n::__lambda__1__test() + } + public fun test_friend(): m_friend::Lazy { + closure#0n::__lambda__1__test_friend() + } + private fun __lambda__1__test() { + Tuple() + } + private fun __lambda__1__test_friend() { + Tuple() + } +} // end 0xc0ffee::n + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +public fun n::test(): 0xc0ffee::m::Lazy { + var $t0: 0xc0ffee::m::Lazy + var $t1: || has drop + 0: $t1 := closure#0 n::__lambda__1__test() + 1: $t0 := pack 0xc0ffee::m::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +public fun n::test_friend(): 0xc0ffee::m_friend::Lazy { + var $t0: 0xc0ffee::m_friend::Lazy + var $t1: || has drop + 0: $t1 := closure#0 n::__lambda__1__test_friend() + 1: $t0 := pack 0xc0ffee::m_friend::Lazy($t1) + 2: return $t0 +} + + +[variant baseline] +fun n::__lambda__1__test() { + 0: return () +} + + +[variant baseline] +fun n::__lambda__1__test_friend() { + 0: return () +} + + +Diagnostics: +bug: compiler internal error: struct not defined + ┌─ tests/bytecode-generator/bug_16543_fv_wrapper_pack.move:13:16 + │ +13 │ public fun test(): 0xc0ffee::m::Lazy { + │ ^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/bytecode-generator/bug_16543_fv_wrapper_pack.move:17:16 + │ +17 │ public fun test_friend(): 0xc0ffee::m_friend::Lazy { + │ ^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.move new file mode 100644 index 00000000000..a90f4f837af --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack.move @@ -0,0 +1,20 @@ +module 0xc0ffee::m { + package struct Lazy(||) has drop; + +} + +module 0xc0ffee::m_friend { + friend 0xc0ffee::n; + friend struct Lazy(||) has drop; + +} + +module 0xc0ffee::n { + public fun test(): 0xc0ffee::m::Lazy { + || {} + } + + public fun test_friend(): 0xc0ffee::m_friend::Lazy { + || {} + } +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.exp new file mode 100644 index 00000000000..b0966eb7a59 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.exp @@ -0,0 +1,67 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct Lazy { + 0: || has drop, + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + public fun test_friend(): m_friend::Lazy { + closure#0n::__lambda__1__test_friend() + } + private fun __lambda__1__test_friend() { + Tuple() + } +} // end 0xc0ffee::n +module 0xc0ffee1::n { + public fun test(): 0xc0ffee::m::Lazy { + closure#0n::__lambda__1__test() + } + private fun __lambda__1__test() { + Tuple() + } +} // end 0xc0ffee1::n + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + struct Lazy has drop { + 0: || has drop, + } +} +module 0xc0ffee::m_friend { + struct Lazy has drop { + 0: || has drop, + } +} +module 0xc0ffee::n { + public fun test_friend(): m_friend::Lazy { + <> + } + fun lambda__1__test_friend() { + } +} +module 0xc0ffee1::n { + public fun test(): 0xc0ffee::m::Lazy { + <> + } + fun lambda__1__test() { + } +} + + +Diagnostics: +error: cannot implicitly pack a wrapper struct `m_friend::Lazy` defined in a different module `0xc0ffee::m_friend` because it has friend visibility + ┌─ tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.move:13:9 + │ +13 │ || {} + │ ^^^^^ + +error: cannot implicitly pack a wrapper struct `m::Lazy` defined in a different module `0xc0ffee::m` because it has package visibility + ┌─ tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.move:19:9 + │ +19 │ || {} + │ ^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.move new file mode 100644 index 00000000000..5b530710f0d --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/bug_16543_fv_wrapper_pack_failure.move @@ -0,0 +1,21 @@ +module 0xc0ffee::m { + package struct Lazy(||) has drop; + +} + +module 0xc0ffee::m_friend { + friend struct Lazy(||) has drop; + +} + +module 0xc0ffee::n { + public fun test_friend(): 0xc0ffee::m_friend::Lazy { + || {} + } +} + +module 0xc0ffee1::n { + public fun test(): 0xc0ffee::m::Lazy { + || {} + } +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/conditional_borrow.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/conditional_borrow.exp index 67bc99dc5e6..595778f7609 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/conditional_borrow.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/conditional_borrow.exp @@ -792,228 +792,254 @@ public fun M::testb(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 8675.M { -struct S has copy, drop { - f: u64 -} +// Bytecode version v9 +module 0x8675::M +struct S has copy + drop + f: u64 + +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 7 + call test1 + ld_u64 2 + call test1 + add + // @5 + ret + +// Function definition at index 1 +fun test1(l0: u64): u64 + local l1: u64 + local l2: u64 + local l3: &mut u64 + local l4: u64 + local l5: u64 + local l6: u64 + local l7: u64 + local l8: u64 + copy_loc l0 + ld_u64 4 + lt + br_false l0 + copy_loc l0 + // @5 + st_loc l1 +l1: mut_borrow_loc l1 + st_loc l3 + ld_u64 10 + move_loc l3 + // @10 + write_ref + move_loc l0 + st_loc l4 + mut_borrow_loc l4 + st_loc l3 + // @15 + copy_loc l3 + read_ref + ld_u64 1 + add + move_loc l3 + // @20 + write_ref + move_loc l4 + st_loc l2 + copy_loc l2 + ld_u64 0 + // @25 + add + st_loc l5 + mut_borrow_loc l5 + st_loc l3 + copy_loc l3 + // @30 + read_ref + ld_u64 2 + add + move_loc l3 + write_ref + // @35 + copy_loc l2 + st_loc l6 + mut_borrow_loc l6 + st_loc l3 + copy_loc l3 + // @40 + read_ref + ld_u64 4 + add + move_loc l3 + write_ref + // @45 + copy_loc l2 + st_loc l7 + mut_borrow_loc l7 + st_loc l3 + copy_loc l3 + // @50 + read_ref + ld_u64 8 + add + move_loc l3 + write_ref + // @55 + copy_loc l2 + st_loc l8 + mut_borrow_loc l8 + st_loc l3 + copy_loc l3 + // @60 + read_ref + ld_u64 16 + add + move_loc l3 + write_ref + // @65 + move_loc l2 + ret +l0: ld_u64 3 + st_loc l1 + branch l1 + +// Function definition at index 2 +fun test1b(l0: S): u64 + local l1: S + local l2: S + local l3: &mut S + local l4: S + local l5: S + local l6: S + local l7: S + local l8: S + local l9: &mut u64 + local l10: S + local l11: u64 + local l12: u64 + local l13: u64 + ld_u64 3 + pack S + st_loc l1 + borrow_loc l0 + borrow_field S, f + // @5 + read_ref + ld_u64 4 + lt + br_false l0 + copy_loc l0 + // @10 + st_loc l2 +l1: mut_borrow_loc l2 + st_loc l3 + ld_u64 10 + move_loc l3 + // @15 + read_ref + st_loc l4 + mut_borrow_loc l4 + mut_borrow_field S, f + write_ref + // @20 + move_loc l0 + st_loc l5 + mut_borrow_loc l5 + st_loc l3 + copy_loc l3 + // @25 + read_ref + st_loc l6 + borrow_loc l6 + borrow_field S, f + read_ref + // @30 + ld_u64 1 + add + move_loc l3 + read_ref + st_loc l7 + // @35 + mut_borrow_loc l7 + mut_borrow_field S, f + write_ref + move_loc l5 + st_loc l8 + // @40 + mut_borrow_loc l8 + mut_borrow_field S, f + st_loc l9 + copy_loc l9 + read_ref + // @45 + ld_u64 1 + add + move_loc l9 + write_ref + move_loc l8 + // @50 + st_loc l10 + borrow_loc l10 + borrow_field S, f + read_ref + st_loc l11 + // @55 + mut_borrow_loc l11 + st_loc l9 + copy_loc l9 + read_ref + ld_u64 1 + // @60 + add + move_loc l9 + write_ref + borrow_loc l10 + borrow_field S, f + // @65 + read_ref + st_loc l12 + mut_borrow_loc l12 + st_loc l9 + copy_loc l9 + // @70 + read_ref + ld_u64 8 + add + move_loc l9 + write_ref + // @75 + borrow_loc l10 + borrow_field S, f + read_ref + st_loc l13 + mut_borrow_loc l13 + // @80 + st_loc l9 + copy_loc l9 + read_ref + ld_u64 16 + add + // @85 + move_loc l9 + write_ref + borrow_loc l10 + borrow_field S, f + read_ref + // @90 + ret +l0: move_loc l1 + st_loc l2 + branch l1 + +// Function definition at index 3 +#[persistent] public fun testb(): u64 + ld_u64 7 + pack S + call test1b + ld_u64 2 + pack S + // @5 + call test1b + add + ret + -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(7) - 1: Call test1(u64): u64 - 2: LdU64(2) - 3: Call test1(u64): u64 - 4: Add - 5: Ret -} -test1(r: u64): u64 /* def_idx: 1 */ { -L1: $t3: u64 -L2: $t5: u64 -L3: tref: &mut u64 -L4: y: u64 -L5: $t15: u64 -L6: $t23: u64 -L7: $t28: u64 -L8: $t33: u64 -B0: - 0: CopyLoc[0](r: u64) - 1: LdU64(4) - 2: Lt - 3: BrFalse(67) -B1: - 4: CopyLoc[0](r: u64) - 5: StLoc[1]($t3: u64) -B2: - 6: MutBorrowLoc[1]($t3: u64) - 7: StLoc[3](tref: &mut u64) - 8: LdU64(10) - 9: MoveLoc[3](tref: &mut u64) - 10: WriteRef - 11: MoveLoc[0](r: u64) - 12: StLoc[4](y: u64) - 13: MutBorrowLoc[4](y: u64) - 14: StLoc[3](tref: &mut u64) - 15: CopyLoc[3](tref: &mut u64) - 16: ReadRef - 17: LdU64(1) - 18: Add - 19: MoveLoc[3](tref: &mut u64) - 20: WriteRef - 21: MoveLoc[4](y: u64) - 22: StLoc[2]($t5: u64) - 23: CopyLoc[2]($t5: u64) - 24: LdU64(0) - 25: Add - 26: StLoc[5]($t15: u64) - 27: MutBorrowLoc[5]($t15: u64) - 28: StLoc[3](tref: &mut u64) - 29: CopyLoc[3](tref: &mut u64) - 30: ReadRef - 31: LdU64(2) - 32: Add - 33: MoveLoc[3](tref: &mut u64) - 34: WriteRef - 35: CopyLoc[2]($t5: u64) - 36: StLoc[6]($t23: u64) - 37: MutBorrowLoc[6]($t23: u64) - 38: StLoc[3](tref: &mut u64) - 39: CopyLoc[3](tref: &mut u64) - 40: ReadRef - 41: LdU64(4) - 42: Add - 43: MoveLoc[3](tref: &mut u64) - 44: WriteRef - 45: CopyLoc[2]($t5: u64) - 46: StLoc[7]($t28: u64) - 47: MutBorrowLoc[7]($t28: u64) - 48: StLoc[3](tref: &mut u64) - 49: CopyLoc[3](tref: &mut u64) - 50: ReadRef - 51: LdU64(8) - 52: Add - 53: MoveLoc[3](tref: &mut u64) - 54: WriteRef - 55: CopyLoc[2]($t5: u64) - 56: StLoc[8]($t33: u64) - 57: MutBorrowLoc[8]($t33: u64) - 58: StLoc[3](tref: &mut u64) - 59: CopyLoc[3](tref: &mut u64) - 60: ReadRef - 61: LdU64(16) - 62: Add - 63: MoveLoc[3](tref: &mut u64) - 64: WriteRef - 65: MoveLoc[2]($t5: u64) - 66: Ret -B3: - 67: LdU64(3) - 68: StLoc[1]($t3: u64) - 69: Branch(6) -} -test1b(r: S): u64 /* def_idx: 2 */ { -L1: x: S -L2: $t5: S -L3: tref: &mut S -L4: $t13: S -L5: y: S -L6: $t19: S -L7: $t24: S -L8: z: S -L9: $t12: &mut u64 -L10: a: S -L11: $t34: u64 -L12: $t41: u64 -L13: $t48: u64 -B0: - 0: LdU64(3) - 1: Pack[0](S) - 2: StLoc[1](x: S) - 3: ImmBorrowLoc[0](r: S) - 4: ImmBorrowField[0](S.f: u64) - 5: ReadRef - 6: LdU64(4) - 7: Lt - 8: BrFalse(91) -B1: - 9: CopyLoc[0](r: S) - 10: StLoc[2]($t5: S) -B2: - 11: MutBorrowLoc[2]($t5: S) - 12: StLoc[3](tref: &mut S) - 13: LdU64(10) - 14: MoveLoc[3](tref: &mut S) - 15: ReadRef - 16: StLoc[4]($t13: S) - 17: MutBorrowLoc[4]($t13: S) - 18: MutBorrowField[0](S.f: u64) - 19: WriteRef - 20: MoveLoc[0](r: S) - 21: StLoc[5](y: S) - 22: MutBorrowLoc[5](y: S) - 23: StLoc[3](tref: &mut S) - 24: CopyLoc[3](tref: &mut S) - 25: ReadRef - 26: StLoc[6]($t19: S) - 27: ImmBorrowLoc[6]($t19: S) - 28: ImmBorrowField[0](S.f: u64) - 29: ReadRef - 30: LdU64(1) - 31: Add - 32: MoveLoc[3](tref: &mut S) - 33: ReadRef - 34: StLoc[7]($t24: S) - 35: MutBorrowLoc[7]($t24: S) - 36: MutBorrowField[0](S.f: u64) - 37: WriteRef - 38: MoveLoc[5](y: S) - 39: StLoc[8](z: S) - 40: MutBorrowLoc[8](z: S) - 41: MutBorrowField[0](S.f: u64) - 42: StLoc[9]($t12: &mut u64) - 43: CopyLoc[9]($t12: &mut u64) - 44: ReadRef - 45: LdU64(1) - 46: Add - 47: MoveLoc[9]($t12: &mut u64) - 48: WriteRef - 49: MoveLoc[8](z: S) - 50: StLoc[10](a: S) - 51: ImmBorrowLoc[10](a: S) - 52: ImmBorrowField[0](S.f: u64) - 53: ReadRef - 54: StLoc[11]($t34: u64) - 55: MutBorrowLoc[11]($t34: u64) - 56: StLoc[9]($t12: &mut u64) - 57: CopyLoc[9]($t12: &mut u64) - 58: ReadRef - 59: LdU64(1) - 60: Add - 61: MoveLoc[9]($t12: &mut u64) - 62: WriteRef - 63: ImmBorrowLoc[10](a: S) - 64: ImmBorrowField[0](S.f: u64) - 65: ReadRef - 66: StLoc[12]($t41: u64) - 67: MutBorrowLoc[12]($t41: u64) - 68: StLoc[9]($t12: &mut u64) - 69: CopyLoc[9]($t12: &mut u64) - 70: ReadRef - 71: LdU64(8) - 72: Add - 73: MoveLoc[9]($t12: &mut u64) - 74: WriteRef - 75: ImmBorrowLoc[10](a: S) - 76: ImmBorrowField[0](S.f: u64) - 77: ReadRef - 78: StLoc[13]($t48: u64) - 79: MutBorrowLoc[13]($t48: u64) - 80: StLoc[9]($t12: &mut u64) - 81: CopyLoc[9]($t12: &mut u64) - 82: ReadRef - 83: LdU64(16) - 84: Add - 85: MoveLoc[9]($t12: &mut u64) - 86: WriteRef - 87: ImmBorrowLoc[10](a: S) - 88: ImmBorrowField[0](S.f: u64) - 89: ReadRef - 90: Ret -B3: - 91: MoveLoc[1](x: S) - 92: StLoc[2]($t5: S) - 93: Branch(11) -} -public testb(): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(7) - 1: Pack[0](S) - 2: Call test1b(S): u64 - 3: LdU64(2) - 4: Pack[0](S) - 5: Call test1b(S): u64 - 6: Add - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp index e43df152bd3..dbbed914235 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/escape_autoref.exp @@ -207,49 +207,51 @@ fun m::will_autoref(): address { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct Object has copy, drop { - inner: address -} -struct ObjectCore has key { - owner: address -} +// Bytecode version v9 +module 0x42::m +struct Object has copy + drop + inner: address + +struct ObjectCore has key + owner: address + +// Function definition at index 0 +fun make(): Object + ld_u64 0 + abort + +// Function definition at index 1 +fun owner_correct(l0: Object): address acquires ObjectCore + borrow_loc l0 + borrow_field Object, inner + read_ref + borrow_global ObjectCore + borrow_field ObjectCore, owner + // @5 + read_ref + ret + +// Function definition at index 2 +fun owner_read_ref_missing(l0: Object): address acquires ObjectCore + borrow_loc l0 + borrow_field Object, inner + read_ref + borrow_global ObjectCore + borrow_field ObjectCore, owner + // @5 + read_ref + ret + +// Function definition at index 3 +fun will_autoref(): address + local l0: Object + call make + st_loc l0 + borrow_loc l0 + borrow_field Object, inner + read_ref + // @5 + ret + -make(): Object /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -owner_correct(o: Object): address /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](o: Object) - 1: ImmBorrowField[0](Object.inner: address) - 2: ReadRef - 3: ImmBorrowGlobal[1](ObjectCore) - 4: ImmBorrowField[1](ObjectCore.owner: address) - 5: ReadRef - 6: Ret -} -owner_read_ref_missing(o: Object): address /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](o: Object) - 1: ImmBorrowField[0](Object.inner: address) - 2: ReadRef - 3: ImmBorrowGlobal[1](ObjectCore) - 4: ImmBorrowField[1](ObjectCore.owner: address) - 5: ReadRef - 6: Ret -} -will_autoref(): address /* def_idx: 3 */ { -L0: $t1: Object -B0: - 0: Call make(): Object - 1: StLoc[0]($t1: Object) - 2: ImmBorrowLoc[0]($t1: Object) - 3: ImmBorrowField[0](Object.inner: address) - 4: ReadRef - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp index 1aedb607cfd..e2f2328a488 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp @@ -84,18 +84,18 @@ module 0x42::fields { x.f = v } fun write_local_direct(): S { - let x = S{f: 0,g: T{h: 0}}; + let x = S{f: 0, g: T{h: 0}}; x.g.h = 42; x } fun write_local_via_ref(): S { - let x = S{f: 0,g: T{h: 0}}; + let x = S{f: 0, g: T{h: 0}}; let r = &mut x; r.g.h = 42; x } fun write_local_via_ref_2(): S { - let x = S{f: 0,g: T{h: 0}}; + let x = S{f: 0, g: T{h: 0}}; let r = &mut x.g.h; *r = 42; x @@ -478,126 +478,134 @@ fun fields::write_val($t0: 0x42::fields::S): 0x42::fields::S { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.fields { -struct T has drop { - h: u64 -} -struct G has drop { - f: X -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::fields +struct T has drop + h: u64 + +struct G has drop + f: T0 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun read_generic_val(l0: G): u64 + borrow_loc l0 + borrow_field G, f + read_ref + ret + +// Function definition at index 1 +fun read_ref(l0: &S): u64 + move_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 2 +fun read_val(l0: S): u64 + borrow_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 3 +fun write_generic_val(l0: &mut G, l1: u64) + local l2: &mut u64 + move_loc l0 + mut_borrow_field G, f + st_loc l2 + move_loc l1 + move_loc l2 + // @5 + write_ref + ret + +// Function definition at index 4 +fun write_local_direct(): S + local l0: S + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @10 + move_loc l0 + ret + +// Function definition at index 5 +fun write_local_via_ref(): S + local l0: S + local l1: &mut S + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + mut_borrow_loc l0 + st_loc l1 + ld_u64 42 + move_loc l1 + mut_borrow_field S, g + // @10 + mut_borrow_field T, h + write_ref + move_loc l0 + ret + +// Function definition at index 6 +fun write_local_via_ref_2(): S + local l0: S + local l1: u64 + local l2: &mut u64 + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + st_loc l2 + ld_u64 42 + // @10 + move_loc l2 + write_ref + move_loc l0 + ret + +// Function definition at index 7 +fun write_param(l0: &mut S) + ld_u64 42 + move_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + ret + +// Function definition at index 8 +fun write_val(l0: S): S + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + move_loc l0 + ret + -read_generic_val(x: G): u64 /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](x: G) - 1: ImmBorrowFieldGeneric[0](G.f: X) - 2: ReadRef - 3: Ret -} -read_ref(x: &S): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: &S) - 1: ImmBorrowField[1](S.g: T) - 2: ImmBorrowField[2](T.h: u64) - 3: ReadRef - 4: Ret -} -read_val(x: S): u64 /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](x: S) - 1: ImmBorrowField[1](S.g: T) - 2: ImmBorrowField[2](T.h: u64) - 3: ReadRef - 4: Ret -} -write_generic_val(x: &mut G, v: u64) /* def_idx: 3 */ { -L2: $t2: &mut u64 -B0: - 0: MoveLoc[0](x: &mut G) - 1: MutBorrowFieldGeneric[0](G.f: X) - 2: StLoc[2]($t2: &mut u64) - 3: MoveLoc[1](v: u64) - 4: MoveLoc[2]($t2: &mut u64) - 5: WriteRef - 6: Ret -} -write_local_direct(): S /* def_idx: 4 */ { -L0: x: S -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[2](S) - 4: StLoc[0](x: S) - 5: LdU64(42) - 6: MutBorrowLoc[0](x: S) - 7: MutBorrowField[1](S.g: T) - 8: MutBorrowField[2](T.h: u64) - 9: WriteRef - 10: MoveLoc[0](x: S) - 11: Ret -} -write_local_via_ref(): S /* def_idx: 5 */ { -L0: x: S -L1: r: &mut S -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[2](S) - 4: StLoc[0](x: S) - 5: MutBorrowLoc[0](x: S) - 6: StLoc[1](r: &mut S) - 7: LdU64(42) - 8: MoveLoc[1](r: &mut S) - 9: MutBorrowField[1](S.g: T) - 10: MutBorrowField[2](T.h: u64) - 11: WriteRef - 12: MoveLoc[0](x: S) - 13: Ret -} -write_local_via_ref_2(): S /* def_idx: 6 */ { -L0: x: S -L1: $t2: u64 -L2: r: &mut u64 -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[2](S) - 4: StLoc[0](x: S) - 5: MutBorrowLoc[0](x: S) - 6: MutBorrowField[1](S.g: T) - 7: MutBorrowField[2](T.h: u64) - 8: StLoc[2](r: &mut u64) - 9: LdU64(42) - 10: MoveLoc[2](r: &mut u64) - 11: WriteRef - 12: MoveLoc[0](x: S) - 13: Ret -} -write_param(x: &mut S) /* def_idx: 7 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut S) - 2: MutBorrowField[1](S.g: T) - 3: MutBorrowField[2](T.h: u64) - 4: WriteRef - 5: Ret -} -write_val(x: S): S /* def_idx: 8 */ { -B0: - 0: LdU64(42) - 1: MutBorrowLoc[0](x: S) - 2: MutBorrowField[1](S.g: T) - 3: MutBorrowField[2](T.h: u64) - 4: WriteRef - 5: MoveLoc[0](x: S) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/freeze_mut_ref.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/freeze_mut_ref.exp index 17089194c1a..118a5bec9b5 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/freeze_mut_ref.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/freeze_mut_ref.exp @@ -105,6 +105,7 @@ module 0x42::freeze_mut_ref { // -- Sourcified model before first bytecode pipeline module 0x42::freeze_mut_ref { + use std::vector; struct G { f: u64, } @@ -705,197 +706,196 @@ fun freeze_mut_ref::t8($t0: bool, $t1: &mut 0x42::freeze_mut_ref::S, $t2: &0x42: ============ disassembled file-format ================== -// Move bytecode v8 -module 42.freeze_mut_ref { -struct G { - f: u64 -} -struct S has drop { - dummy_field: bool -} +// Bytecode version v9 +module 0x42::freeze_mut_ref +struct G + f: u64 + +struct S has drop + dummy_field: bool + +// Function definition at index 0 +#[persistent] public fun borrow_mut(l0: &mut vector): &T0 + move_loc l0 + ld_u64 0 + vec_mut_borrow + freeze_ref + ret + +// Function definition at index 1 +#[persistent] public fun borrow_mut2(l0: &mut T0): &T0 + move_loc l0 + freeze_ref + ret + +// Function definition at index 2 +#[persistent] public fun borrow_mut3(l0: &mut T0, l1: &T0): &T0 + move_loc l1 + pop + move_loc l0 + freeze_ref + ret + // @5 + move_loc l0 + pop + move_loc l1 + ret + +// Function definition at index 3 +#[persistent] public fun borrow_mut4(l0: &mut T0): &T0 + move_loc l0 + freeze_ref + ret + +// Function definition at index 4 +fun t0() + local l0: u64 + local l1: &u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + freeze_ref + pop + // @5 + ret + +// Function definition at index 5 +fun t1(l0: &mut S): &S + move_loc l0 + freeze_ref + ret + +// Function definition at index 6 +fun t2(l0: &mut u64, l1: &mut u64): (&u64, &mut u64) + local l2: &u64 + move_loc l0 + freeze_ref + move_loc l1 + ret + +// Function definition at index 7 +#[persistent] public fun t4() + local l0: u64 + local l1: &u64 + local l2: u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + freeze_ref + pop + // @5 + ld_u64 0 + st_loc l2 + mut_borrow_loc l2 + freeze_ref + pop + // @10 + ret + +// Function definition at index 8 +#[persistent] public fun t5(l0: &mut G) + local l1: &mut u64 + local l2: u64 + local l3: u64 + local l4: &mut u64 + local l5: &u64 + local l6: u64 + local l7: &mut u64 + ld_u64 0 + ld_u64 1 + add + copy_loc l0 + mut_borrow_field G, f + // @5 + st_loc l1 + ld_u64 1 + add + pop + move_loc l0 + // @10 + mut_borrow_field G, f + ld_u64 2 + st_loc l3 + mut_borrow_loc l3 + st_loc l4 + // @15 + ld_u64 2 + ld_u64 0 + move_loc l1 + write_ref + move_loc l4 + // @20 + freeze_ref + pop + st_loc l6 + st_loc l7 + move_loc l6 + // @25 + move_loc l7 + write_ref + ret + +// Function definition at index 9 +fun t6(l0: bool, l1: &mut S, l2: &S) + local l3: &S + move_loc l0 + br_false l0 + move_loc l2 + pop + copy_loc l1 + // @5 + move_loc l1 + pop + freeze_ref + pop + ret + // @10 +l0: move_loc l1 + pop + move_loc l2 + pop + ret + +// Function definition at index 10 +fun t7(l0: bool, l1: &mut S, l2: &S) + local l3: &S + local l4: &S + move_loc l0 + br_false l0 + move_loc l2 + pop + move_loc l1 + // @5 + freeze_ref + st_loc l3 +l1: move_loc l3 + pop + ret + // @10 +l0: move_loc l1 + pop + move_loc l2 + st_loc l3 + branch l1 + +// Function definition at index 11 +fun t8(l0: bool, l1: &mut S, l2: &S) + local l3: &S + move_loc l0 + br_false l0 + move_loc l2 + pop + move_loc l1 + // @5 + freeze_ref + pop + ret +l0: move_loc l1 + pop + // @10 + move_loc l2 + pop + ret + -public borrow_mut(map: &mut vector): &Element /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](map: &mut vector) - 1: LdU64(0) - 2: VecMutBorrow(2) - 3: FreezeRef - 4: Ret -} -public borrow_mut2(v: &mut Element): &Element /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](v: &mut Element) - 1: FreezeRef - 2: Ret -} -public borrow_mut3(v1: &mut Element, v2: &Element): &Element /* def_idx: 2 */ { -L2: return: &Element -B0: - 0: MoveLoc[1](v2: &Element) - 1: Pop - 2: MoveLoc[0](v1: &mut Element) - 3: FreezeRef - 4: StLoc[2](return: &Element) -B1: - 5: MoveLoc[2](return: &Element) - 6: Ret -B2: - 7: MoveLoc[0](v1: &mut Element) - 8: Pop - 9: MoveLoc[1](v2: &Element) - 10: StLoc[2](return: &Element) - 11: Branch(5) -} -public borrow_mut4(v: &mut Element): &Element /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](v: &mut Element) - 1: FreezeRef - 2: Ret -} -t0() /* def_idx: 4 */ { -L0: $t2: u64 -L1: x: &u64 -B0: - 0: LdU64(0) - 1: StLoc[0]($t2: u64) - 2: MutBorrowLoc[0]($t2: u64) - 3: FreezeRef - 4: Pop - 5: Ret -} -t1(s: &mut S): &S /* def_idx: 5 */ { -B0: - 0: MoveLoc[0](s: &mut S) - 1: FreezeRef - 2: Ret -} -t2(u1: &mut u64, u2: &mut u64): &u64 * &mut u64 /* def_idx: 6 */ { -L2: return[0]: &u64 -B0: - 0: MoveLoc[0](u1: &mut u64) - 1: FreezeRef - 2: MoveLoc[1](u2: &mut u64) - 3: Ret -} -public t4() /* def_idx: 7 */ { -L0: $t4: u64 -L1: $t2: &u64 -L2: $t7: u64 -B0: - 0: LdU64(0) - 1: StLoc[0]($t4: u64) - 2: MutBorrowLoc[0]($t4: u64) - 3: FreezeRef - 4: Pop - 5: LdU64(0) - 6: StLoc[2]($t7: u64) - 7: MutBorrowLoc[2]($t7: u64) - 8: FreezeRef - 9: Pop - 10: Ret -} -public t5(s: &mut G) /* def_idx: 8 */ { -L1: f: &mut u64 -L2: x: u64 -L3: $t13: u64 -L4: y: &mut u64 -L5: $t18: &u64 -L6: $t5: u64 -L7: g: &mut u64 -B0: - 0: LdU64(0) - 1: LdU64(1) - 2: Add - 3: CopyLoc[0](s: &mut G) - 4: MutBorrowField[0](G.f: u64) - 5: StLoc[1](f: &mut u64) - 6: LdU64(1) - 7: Add - 8: Pop - 9: MoveLoc[0](s: &mut G) - 10: MutBorrowField[0](G.f: u64) - 11: LdU64(2) - 12: StLoc[3]($t13: u64) - 13: MutBorrowLoc[3]($t13: u64) - 14: StLoc[4](y: &mut u64) - 15: LdU64(2) - 16: LdU64(0) - 17: MoveLoc[1](f: &mut u64) - 18: WriteRef - 19: MoveLoc[4](y: &mut u64) - 20: FreezeRef - 21: Pop - 22: StLoc[6]($t5: u64) - 23: StLoc[7](g: &mut u64) - 24: MoveLoc[6]($t5: u64) - 25: MoveLoc[7](g: &mut u64) - 26: WriteRef - 27: Ret -} -t6(cond: bool, s: &mut S, other: &S) /* def_idx: 9 */ { -L3: $t4: &S -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(10) -B1: - 2: MoveLoc[2](other: &S) - 3: Pop - 4: CopyLoc[1](s: &mut S) - 5: MoveLoc[1](s: &mut S) - 6: Pop - 7: FreezeRef - 8: Pop -B2: - 9: Ret -B3: - 10: MoveLoc[1](s: &mut S) - 11: Pop - 12: MoveLoc[2](other: &S) - 13: Pop - 14: Branch(9) -} -t7(cond: bool, s: &mut S, other: &S) /* def_idx: 10 */ { -L3: $t4: &S -L4: _x: &S -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(10) -B1: - 2: MoveLoc[2](other: &S) - 3: Pop - 4: MoveLoc[1](s: &mut S) - 5: FreezeRef - 6: StLoc[3]($t4: &S) -B2: - 7: MoveLoc[3]($t4: &S) - 8: Pop - 9: Ret -B3: - 10: MoveLoc[1](s: &mut S) - 11: Pop - 12: MoveLoc[2](other: &S) - 13: StLoc[3]($t4: &S) - 14: Branch(7) -} -t8(cond: bool, s: &mut S, other: &S) /* def_idx: 11 */ { -L3: _x: &S -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(8) -B1: - 2: MoveLoc[2](other: &S) - 3: Pop - 4: MoveLoc[1](s: &mut S) - 5: FreezeRef - 6: Pop -B2: - 7: Ret -B3: - 8: MoveLoc[1](s: &mut S) - 9: Pop - 10: MoveLoc[2](other: &S) - 11: Pop - 12: Branch(7) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp new file mode 100644 index 00000000000..a53260ecfe8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp @@ -0,0 +1,9 @@ + +Diagnostics: +error: cannot select field `0` since it has different types in variants of enum `Wrapper` + ┌─ tests/bytecode-generator/fv_enum_wrapper_err.move:10:10 + │ +10 │ (f.0)() + │ ^ + │ + = field `0` has type `||u64 has copy + drop` in variant `B` and type `||u64 has copy` in variant `A` diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move new file mode 100644 index 00000000000..ddfb84f3369 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move @@ -0,0 +1,19 @@ +module 0x66::fv_enum_wrapper { + + enum Wrapper { + A(||u64 has copy), + B(||u64 has copy + drop), + } + + fun call(f: Wrapper): u64 + { + (f.0)() + } + + public fun test(): u64 + { + let a = Wrapper::A(|| 42); + call(a) + } + +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp index 8e127bb9a9e..efc903b960d 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp @@ -38,7 +38,7 @@ module 0x42::globals { exists(a) } fun publish(s: &signer) { - move_to(s, R{f: 1}); + move_to(R{f: 1}, s); } fun read(a: address): u64 acquires R @@ -194,46 +194,46 @@ fun globals::write($t0: address, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.globals { -struct R has store, key { - f: u64 -} +// Bytecode version v9 +module 0x42::globals +struct R has store + key + f: u64 + +// Function definition at index 0 +fun check(l0: address): bool + move_loc l0 + exists R + ret + +// Function definition at index 1 +fun publish(l0: &signer) + move_loc l0 + ld_u64 1 + pack R + move_to R + ret + +// Function definition at index 2 +fun read(l0: address): u64 acquires R + move_loc l0 + borrow_global R + borrow_field R, f + read_ref + ret + +// Function definition at index 3 +fun write(l0: address, l1: u64): u64 acquires R + local l2: &mut R + move_loc l0 + mut_borrow_global R + st_loc l2 + ld_u64 2 + move_loc l2 + // @5 + mut_borrow_field R, f + write_ref + ld_u64 9 + ret + -check(a: address): bool /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: address) - 1: Exists[0](R) - 2: Ret -} -publish(s: &signer) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](s: &signer) - 1: LdU64(1) - 2: Pack[0](R) - 3: MoveTo[0](R) - 4: Ret -} -read(a: address): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](a: address) - 1: ImmBorrowGlobal[0](R) - 2: ImmBorrowField[0](R.f: u64) - 3: ReadRef - 4: Ret -} -write(a: address, x: u64): u64 /* def_idx: 3 */ { -L2: r: &mut R -B0: - 0: MoveLoc[0](a: address) - 1: MutBorrowGlobal[0](R) - 2: StLoc[2](r: &mut R) - 3: LdU64(2) - 4: MoveLoc[2](r: &mut R) - 5: MutBorrowField[0](R.f: u64) - 6: WriteRef - 7: LdU64(9) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/if_else.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/if_else.exp index a5bf7591e3a..c67a055ad8c 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/if_else.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/if_else.exp @@ -184,66 +184,53 @@ fun if_else::if_else_nested($t0: bool, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.if_else { +// Bytecode version v9 +module 0x42::if_else +// Function definition at index 0 +fun if_else(l0: bool, l1: u64): u64 + move_loc l0 + br_false l0 + move_loc l1 + ld_u64 1 + add + // @5 + ret +l0: move_loc l1 + ld_u64 1 + sub + ret + +// Function definition at index 1 +fun if_else_nested(l0: bool, l1: u64): u64 + local l2: u64 + local l3: u64 + move_loc l0 + br_false l0 + copy_loc l1 + ld_u64 1 + add + // @5 + st_loc l2 +l2: move_loc l2 + ld_u64 10 + gt + br_false l1 + // @10 + move_loc l1 + ld_u64 2 + mul + ret +l1: move_loc l1 + // @15 + ld_u64 2 + div + ret +l0: copy_loc l1 + ld_u64 1 + // @20 + sub + st_loc l2 + branch l2 -if_else(cond: bool, x: u64): u64 /* def_idx: 0 */ { -L2: $t3: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(8) -B1: - 2: MoveLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2]($t3: u64) -B2: - 6: MoveLoc[2]($t3: u64) - 7: Ret -B3: - 8: MoveLoc[1](x: u64) - 9: LdU64(1) - 10: Sub - 11: StLoc[2]($t3: u64) - 12: Branch(6) -} -if_else_nested(cond: bool, x: u64): u64 /* def_idx: 1 */ { -L2: $t5: u64 -L3: $t6: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(21) -B1: - 2: CopyLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2]($t5: u64) -B2: - 6: MoveLoc[2]($t5: u64) - 7: LdU64(10) - 8: Gt - 9: BrFalse(16) -B3: - 10: MoveLoc[1](x: u64) - 11: LdU64(2) - 12: Mul - 13: StLoc[3]($t6: u64) -B4: - 14: MoveLoc[3]($t6: u64) - 15: Ret -B5: - 16: MoveLoc[1](x: u64) - 17: LdU64(2) - 18: Div - 19: StLoc[3]($t6: u64) - 20: Branch(14) -B6: - 21: CopyLoc[1](x: u64) - 22: LdU64(1) - 23: Sub - 24: StLoc[2]($t5: u64) - 25: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/inline_specs.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/inline_specs.exp index c7c5ab43a41..35a12dbec6a 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/inline_specs.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/inline_specs.exp @@ -136,27 +136,26 @@ fun inline_specs::succ($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.inline_specs { - - -specs(): u64 /* def_idx: 0 */ { -L0: x: u64 -B0: - 0: Nop - 1: LdU64(0) - 2: Call succ(u64): u64 - 3: StLoc[0](x: u64) - 4: Nop - 5: MoveLoc[0](x: u64) - 6: Ret -} -succ(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -} +// Bytecode version v9 +module 0x42::inline_specs +// Function definition at index 0 +fun specs(): u64 + local l0: u64 + nop + ld_u64 0 + call succ + st_loc l0 + nop + // @5 + move_loc l0 + ret + +// Function definition at index 1 +fun succ(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/loop.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/loop.exp index ab0deb724c3..f383f0ac7f4 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/loop.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/loop.exp @@ -421,85 +421,78 @@ fun loops::while_loop_with_break_and_continue($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.loops { +// Bytecode version v9 +module 0x42::loops +// Function definition at index 0 +fun nested_loop(l0: u64): u64 +l3: copy_loc l0 + ld_u64 0 + gt + br_false l0 + copy_loc l0 + // @5 + ld_u64 10 + gt + br_true l1 + branch l2 +l1: move_loc l0 + // @10 + ld_u64 1 + sub + st_loc l0 +l2: move_loc l0 + ld_u64 1 + // @15 + sub + st_loc l0 + branch l3 +l0: move_loc l0 + ret + +// Function definition at index 1 +fun while_loop(l0: u64): u64 +l1: copy_loc l0 + ld_u64 0 + gt + br_false l0 + move_loc l0 + // @5 + ld_u64 1 + sub + st_loc l0 + branch l1 +l0: move_loc l0 + // @10 + ret + +// Function definition at index 2 +fun while_loop_with_break_and_continue(l0: u64): u64 +l4: copy_loc l0 + ld_u64 0 + gt + br_true l0 + branch l1 + // @5 +l0: copy_loc l0 + ld_u64 42 + eq + br_false l2 + branch l1 + // @10 +l1: move_loc l0 + ret +l2: copy_loc l0 + ld_u64 21 + eq + // @15 + br_false l3 + branch l4 +l3: move_loc l0 + ld_u64 1 + sub + // @20 + st_loc l0 + branch l4 -nested_loop(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(18) -B1: - 4: CopyLoc[0](x: u64) - 5: LdU64(10) - 6: Gt - 7: BrTrue(9) -B2: - 8: Branch(13) -B3: - 9: MoveLoc[0](x: u64) - 10: LdU64(1) - 11: Sub - 12: StLoc[0](x: u64) -B4: - 13: MoveLoc[0](x: u64) - 14: LdU64(1) - 15: Sub - 16: StLoc[0](x: u64) - 17: Branch(0) -B5: - 18: MoveLoc[0](x: u64) - 19: Ret -} -while_loop(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(9) -B1: - 4: MoveLoc[0](x: u64) - 5: LdU64(1) - 6: Sub - 7: StLoc[0](x: u64) - 8: Branch(0) -B2: - 9: MoveLoc[0](x: u64) - 10: Ret -} -while_loop_with_break_and_continue(x: u64): u64 /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrTrue(5) -B1: - 4: Branch(10) -B2: - 5: CopyLoc[0](x: u64) - 6: LdU64(42) - 7: Eq - 8: BrFalse(12) -B3: - 9: Branch(10) -B4: - 10: MoveLoc[0](x: u64) - 11: Ret -B5: - 12: CopyLoc[0](x: u64) - 13: LdU64(21) - 14: Eq - 15: BrFalse(17) -B6: - 16: Branch(0) -B7: - 17: MoveLoc[0](x: u64) - 18: LdU64(1) - 19: Sub - 20: StLoc[0](x: u64) - 21: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/loop_labels.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/loop_labels.exp index 6e7ed63b373..70c9c465b5a 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/loop_labels.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/loop_labels.exp @@ -139,17 +139,13 @@ fun test::f1() { ============ disassembled file-format ================== -// Move bytecode v8 -module 815.test { +// Bytecode version v9 +module 0x815::test +// Function definition at index 0 +fun f1() +l1: branch l0 + branch l1 +l0: branch l1 -f1() /* def_idx: 0 */ { -B0: - 0: Branch(2) -B1: - 1: Branch(0) -B2: - 2: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ability_err.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ability_err.exp index c1865d5078e..75ced16181d 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ability_err.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ability_err.exp @@ -91,7 +91,7 @@ module 0xc0ffee::m { fun consume(self: Inner): bool { match (self) { Inner::Inner1{x: _} => (), - Inner::Inner2{x: _,y: _} => (), + Inner::Inner2{x: _, y: _} => (), }; true } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_coverage_err.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_coverage_err.exp index fb1ac010cf5..ad37eb4d619 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_coverage_err.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_coverage_err.exp @@ -191,15 +191,15 @@ module 0xc0ffee::m { public fun exhaustive_tuple(i: &Inner) { match ((i, i)) { (Inner::Inner1{x: _},_) => (), - (Inner::Inner2{x: _,y: _},_) => (), + (Inner::Inner2{x: _, y: _},_) => (), } } public fun exhaustive_via_merge(o: &Outer) { match (o) { Outer::None{} => (), Outer::One{i: Inner::Inner1{x: _}} => (), - Outer::One{i: Inner::Inner2{x: _,y: _}} => (), - Outer::Two{i: _,b: _} => (), + Outer::One{i: Inner::Inner2{x: _, y: _}} => (), + Outer::Two{i: _, b: _} => (), } } public fun non_exhaustive(o: &Outer) { @@ -212,14 +212,14 @@ module 0xc0ffee::m { match (o) { Outer::None{} => (), Outer::One{i: _} => (), - Outer::Two{i: _,b: b} if b.x > 0 => (), + Outer::Two{i: _, b: b} if b.x > 0 => (), } } public fun non_exhaustive_because_of_nested(o: &Outer) { match (o) { Outer::None{} => (), Outer::One{i: Inner::Inner1{x: _}} => (), - Outer::Two{i: _,b: _} => (), + Outer::Two{i: _, b: _} => (), } } public fun non_exhaustive_tuple(i: &Inner) { @@ -230,14 +230,14 @@ module 0xc0ffee::m { public fun non_exhaustive_tuple2(i: &Inner) { match ((i, i)) { (Inner::Inner1{x: _},_) => (), - (_,Inner::Inner2{x: _,y: _}) => (), + (_,Inner::Inner2{x: _, y: _}) => (), } } public fun unreachable(o: &Outer) { match (o) { Outer::None{} => (), Outer::One{i: _} => (), - Outer::Two{i: _,b: _} => (), + Outer::Two{i: _, b: _} => (), _ => (), } } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ok.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ok.exp index 60b484a7e9b..10737439ff4 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ok.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_ok.exp @@ -260,7 +260,7 @@ module 0xc0ffee::m { public fun inner_value(self: Inner): u64 { match (self) { Inner::Inner1{x: x} => x, - Inner::Inner2{x: x,y: y} => x + y, + Inner::Inner2{x: x, y: y} => x + y, } } public fun is_inner1(self: &Inner): bool { @@ -292,7 +292,7 @@ module 0xc0ffee::m { match (o) { Outer::None{} => 0, Outer::One{i: i} => inner_value(i), - Outer::Two{i: i,b: b} => inner_value(i) + b.x, + Outer::Two{i: i, b: b} => inner_value(i) + b.x, } } public fun outer_value_nested(o: Outer): u64 { @@ -300,7 +300,7 @@ module 0xc0ffee::m { Outer::None{} => 0, Outer::One{i: Inner::Inner1{x: x}} => x, Outer::One{i: i} => inner_value(i), - Outer::Two{i: i,b: b} => inner_value(i) + b.x, + Outer::Two{i: i, b: b} => inner_value(i) + b.x, } } public fun outer_value_with_cond(o: Outer): u64 { @@ -308,7 +308,7 @@ module 0xc0ffee::m { Outer::None{} => 0, Outer::One{i: i} if is_inner1(&i) => inner_value(i) % 2, Outer::One{i: i} => inner_value(i), - Outer::Two{i: i,b: b} => inner_value(i) + b.x, + Outer::Two{i: i, b: b} => inner_value(i) + b.x, } } public fun outer_value_with_cond_ref(o: &Outer): bool { @@ -316,13 +316,13 @@ module 0xc0ffee::m { Outer::None{} => false, Outer::One{i: i} if is_inner1(i) => true, Outer::One{i: i} => is_inner1(i), - Outer::Two{i: i,b: _} => is_inner1(i), + Outer::Two{i: i, b: _} => is_inner1(i), } } fun select_common_fields(s: CommonFields): u64 { s.x + (match (s) { - CommonFields::Foo{x: _,y: y} => y, - CommonFields::Bar{x: _,z: z} => z, + CommonFields::Foo{x: _, y: y} => y, + CommonFields::Bar{x: _, z: z} => z, }) } fun select_common_fields_different_offset(s: CommonFieldsAtDifferentOffset): u64 { diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_refutable_err.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_refutable_err.exp index bd95a59dfa9..121feef84e2 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_refutable_err.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/matching_refutable_err.exp @@ -68,22 +68,18 @@ fun m::t($t0: 0x815::m::E): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 815.m { -enum E { - None{ +// Bytecode version v9 +module 0x815::m +enum E + None + Some + _0: u64 + +// Function definition at index 0 +fun t(l0: E): u64 + move_loc l0 + unpack_variant E, Some + ret - }, - Some{ - _0: u64 - } -} -t(self: E): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](self: E) - 1: UnpackVariant[0](E/Some) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp index 82b0738fa10..da836aa30b6 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp @@ -384,167 +384,145 @@ fun operators::order($t0: u64, $t1: u64): bool { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.operators { - - -arithm(x: u64, y: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: CopyLoc[0](x: u64) - 3: CopyLoc[1](y: u64) - 4: Sub - 5: Div - 6: MoveLoc[1](y: u64) - 7: Mul - 8: MoveLoc[0](x: u64) - 9: Mod - 10: Add - 11: Ret -} -bits(x: u64, y: u8): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[1](y: u8) - 2: Shl - 3: MoveLoc[0](x: u64) - 4: BitAnd - 5: Ret -} -bools(x: bool, y: bool): bool /* def_idx: 2 */ { -L2: $t5: bool -L3: $t4: bool -L4: $t3: bool -L5: return: bool -B0: - 0: CopyLoc[0](x: bool) - 1: BrFalse(44) -B1: - 2: CopyLoc[1](y: bool) - 3: StLoc[2]($t5: bool) -B2: - 4: MoveLoc[2]($t5: bool) - 5: BrFalse(35) -B3: - 6: LdTrue - 7: StLoc[3]($t4: bool) -B4: - 8: MoveLoc[3]($t4: bool) - 9: BrFalse(27) -B5: - 10: LdTrue - 11: StLoc[4]($t3: bool) -B6: - 12: MoveLoc[4]($t3: bool) - 13: BrFalse(18) -B7: - 14: LdTrue - 15: StLoc[5](return: bool) -B8: - 16: MoveLoc[5](return: bool) - 17: Ret -B9: - 18: MoveLoc[0](x: bool) - 19: BrTrue(24) -B10: - 20: MoveLoc[1](y: bool) - 21: Not - 22: StLoc[5](return: bool) - 23: Branch(16) -B11: - 24: LdFalse - 25: StLoc[5](return: bool) - 26: Branch(16) -B12: - 27: CopyLoc[0](x: bool) - 28: BrTrue(32) -B13: - 29: CopyLoc[1](y: bool) - 30: StLoc[4]($t3: bool) - 31: Branch(12) -B14: - 32: LdFalse - 33: StLoc[4]($t3: bool) - 34: Branch(12) -B15: - 35: CopyLoc[0](x: bool) - 36: BrFalse(41) -B16: - 37: CopyLoc[1](y: bool) - 38: Not - 39: StLoc[3]($t4: bool) - 40: Branch(8) -B17: - 41: LdFalse - 42: StLoc[3]($t4: bool) - 43: Branch(8) -B18: - 44: LdFalse - 45: StLoc[2]($t5: bool) - 46: Branch(4) -} -equality(x: T, y: T): bool /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Eq - 3: Ret -} -inequality(x: T, y: T): bool /* def_idx: 4 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Neq - 3: Ret -} -order(x: u64, y: u64): bool /* def_idx: 5 */ { -L2: $t5: bool -L3: $t8: bool -L4: $t10: bool -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: Lt - 3: BrFalse(30) -B1: - 4: CopyLoc[0](x: u64) - 5: CopyLoc[1](y: u64) - 6: Le - 7: StLoc[2]($t5: bool) -B2: - 8: MoveLoc[2]($t5: bool) - 9: BrFalse(27) -B3: - 10: CopyLoc[0](x: u64) - 11: CopyLoc[1](y: u64) - 12: Gt - 13: Not - 14: StLoc[3]($t8: bool) -B4: - 15: MoveLoc[3]($t8: bool) - 16: BrFalse(24) -B5: - 17: MoveLoc[0](x: u64) - 18: MoveLoc[1](y: u64) - 19: Ge - 20: Not - 21: StLoc[4]($t10: bool) -B6: - 22: MoveLoc[4]($t10: bool) - 23: Ret -B7: - 24: LdFalse - 25: StLoc[4]($t10: bool) - 26: Branch(22) -B8: - 27: LdFalse - 28: StLoc[3]($t8: bool) - 29: Branch(15) -B9: - 30: LdFalse - 31: StLoc[2]($t5: bool) - 32: Branch(8) -} -} +// Bytecode version v9 +module 0x42::operators +// Function definition at index 0 +fun arithm(l0: u64, l1: u64): u64 + copy_loc l0 + copy_loc l1 + copy_loc l0 + copy_loc l1 + sub + // @5 + div + move_loc l1 + mul + move_loc l0 + mod + // @10 + add + ret + +// Function definition at index 1 +fun bits(l0: u64, l1: u8): u64 + copy_loc l0 + move_loc l1 + shl + move_loc l0 + bit_and + // @5 + ret + +// Function definition at index 2 +fun bools(l0: bool, l1: bool): bool + local l2: bool + local l3: bool + local l4: bool + copy_loc l0 + br_false l0 + copy_loc l1 + st_loc l2 +l9: move_loc l2 + // @5 + br_false l1 + ld_true + st_loc l3 +l8: move_loc l3 + br_false l2 + // @10 + ld_true + st_loc l4 +l6: move_loc l4 + br_false l3 + ld_true + // @15 + ret +l3: move_loc l0 + br_true l4 + move_loc l1 + not + // @20 + ret +l4: ld_false + ret +l2: copy_loc l0 + br_true l5 + // @25 + copy_loc l1 + st_loc l4 + branch l6 +l5: ld_false + st_loc l4 + // @30 + branch l6 +l1: copy_loc l0 + br_false l7 + copy_loc l1 + not + // @35 + st_loc l3 + branch l8 +l7: ld_false + st_loc l3 + branch l8 + // @40 +l0: ld_false + st_loc l2 + branch l9 + +// Function definition at index 3 +fun equality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + eq + ret + +// Function definition at index 4 +fun inequality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + neq + ret + +// Function definition at index 5 +fun order(l0: u64, l1: u64): bool + local l2: bool + local l3: bool + copy_loc l0 + copy_loc l1 + lt + br_false l0 + copy_loc l0 + // @5 + copy_loc l1 + le + st_loc l2 +l4: move_loc l2 + br_false l1 + // @10 + copy_loc l0 + copy_loc l1 + gt + not + st_loc l3 + // @15 +l3: move_loc l3 + br_false l2 + move_loc l0 + move_loc l1 + ge + // @20 + not + ret +l2: ld_false + ret +l1: ld_false + // @25 + st_loc l3 + branch l3 +l0: ld_false + st_loc l2 + branch l4 + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_order.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_order.exp index e146ee18d07..f350ac28e93 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_order.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_order.exp @@ -57,30 +57,30 @@ module 0x42::pack_unpack { f3: u8, } fun pack1(x: u8, y: u8, z: u8): S { - S{f1: x,f2: y,f3: z} + S{f1: x, f2: y, f3: z} } fun pack2(x: u8, y: u8, z: u8): S { - let $f1 = x; - let $f3 = y; - S{f1: $f1,f2: z,f3: $f3} + let _f1 = x; + let _f3 = y; + S{f1: _f1, f2: z, f3: _f3} } fun pack3(x: u8, y: u8, z: u8): S { - let $f2 = x; - S{f1: y,f2: $f2,f3: z} + let _f2 = x; + S{f1: y, f2: _f2, f3: z} } fun pack4(x: u8, y: u8, z: u8): S { - let $f2 = x; - let $f3 = y; - S{f1: z,f2: $f2,f3: $f3} + let _f2 = x; + let _f3 = y; + S{f1: z, f2: _f2, f3: _f3} } fun pack5(x: u8, y: u8, z: u8): S { - let $f3 = x; - S{f1: y,f2: z,f3: $f3} + let _f3 = x; + S{f1: y, f2: z, f3: _f3} } fun pack6(x: u8, y: u8, z: u8): S { - let $f3 = x; - let $f2 = y; - S{f1: z,f2: $f2,f3: $f3} + let _f3 = x; + let _f2 = y; + S{f1: z, f2: _f2, f3: _f3} } } @@ -315,61 +315,60 @@ fun pack_unpack::pack6($t0: u8, $t1: u8, $t2: u8): 0x42::pack_unpack::S { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct S { - f1: u8, - f2: u8, - f3: u8 -} +// Bytecode version v9 +module 0x42::pack_unpack +struct S + f1: u8 + f2: u8 + f3: u8 + +// Function definition at index 0 +fun pack1(l0: u8, l1: u8, l2: u8): S + move_loc l0 + move_loc l1 + move_loc l2 + pack S + ret + +// Function definition at index 1 +fun pack2(l0: u8, l1: u8, l2: u8): S + move_loc l0 + move_loc l2 + move_loc l1 + pack S + ret + +// Function definition at index 2 +fun pack3(l0: u8, l1: u8, l2: u8): S + move_loc l1 + move_loc l0 + move_loc l2 + pack S + ret + +// Function definition at index 3 +fun pack4(l0: u8, l1: u8, l2: u8): S + move_loc l2 + move_loc l0 + move_loc l1 + pack S + ret + +// Function definition at index 4 +fun pack5(l0: u8, l1: u8, l2: u8): S + move_loc l1 + move_loc l2 + move_loc l0 + pack S + ret + +// Function definition at index 5 +fun pack6(l0: u8, l1: u8, l2: u8): S + move_loc l2 + move_loc l1 + move_loc l0 + pack S + ret + -pack1(x: u8, y: u8, z: u8): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: Pack[0](S) - 4: Ret -} -pack2(x: u8, y: u8, z: u8): S /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[2](z: u8) - 2: MoveLoc[1](y: u8) - 3: Pack[0](S) - 4: Ret -} -pack3(x: u8, y: u8, z: u8): S /* def_idx: 2 */ { -B0: - 0: MoveLoc[1](y: u8) - 1: MoveLoc[0](x: u8) - 2: MoveLoc[2](z: u8) - 3: Pack[0](S) - 4: Ret -} -pack4(x: u8, y: u8, z: u8): S /* def_idx: 3 */ { -B0: - 0: MoveLoc[2](z: u8) - 1: MoveLoc[0](x: u8) - 2: MoveLoc[1](y: u8) - 3: Pack[0](S) - 4: Ret -} -pack5(x: u8, y: u8, z: u8): S /* def_idx: 4 */ { -B0: - 0: MoveLoc[1](y: u8) - 1: MoveLoc[2](z: u8) - 2: MoveLoc[0](x: u8) - 3: Pack[0](S) - 4: Ret -} -pack6(x: u8, y: u8, z: u8): S /* def_idx: 5 */ { -B0: - 0: MoveLoc[2](z: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[0](x: u8) - 3: Pack[0](S) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_unpack.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_unpack.exp index 1da5bc63170..0f563f3116b 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_unpack.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/pack_unpack.exp @@ -28,10 +28,10 @@ module 0x42::pack_unpack { g: T, } fun pack(x: u64, y: u64): S { - S{f: x,g: T{h: y}} + S{f: x, g: T{h: y}} } fun unpack(s: S): (u64, u64) { - let S{f: f,g: T{h: h}} = s; + let S{f: f, g: T{h: h}} = s; (f, h) } } @@ -114,32 +114,31 @@ fun pack_unpack::unpack($t0: 0x42::pack_unpack::S): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct T { - h: u64 -} -struct S { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::pack_unpack +struct T + h: u64 + +struct S + f: u64 + g: T + +// Function definition at index 0 +fun pack(l0: u64, l1: u64): S + move_loc l0 + move_loc l1 + pack T + pack S + ret + +// Function definition at index 1 +fun unpack(l0: S): (u64, u64) + local l1: u64 + local l2: u64 + move_loc l0 + unpack S + unpack T + ret + -pack(x: u64, y: u64): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: Pack[0](T) - 3: Pack[1](S) - 4: Ret -} -unpack(s: S): u64 * u64 /* def_idx: 1 */ { -L1: h: u64 -L2: f: u64 -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/reference_conversion.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/reference_conversion.exp index 4a253d4d33d..0e48ec78b96 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/reference_conversion.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/reference_conversion.exp @@ -99,31 +99,31 @@ fun reference_conversion::use_it(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.reference_conversion { +// Bytecode version v9 +module 0x42::reference_conversion +// Function definition at index 0 +fun deref(l0: &u64): u64 + move_loc l0 + read_ref + ret + +// Function definition at index 1 +fun use_it(): u64 + local l0: u64 + local l1: &mut u64 + ld_u64 42 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + ld_u64 43 + // @5 + copy_loc l1 + write_ref + move_loc l1 + freeze_ref + call deref + // @10 + ret -deref(r: &u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](r: &u64) - 1: ReadRef - 2: Ret -} -use_it(): u64 /* def_idx: 1 */ { -L0: x: u64 -L1: r: &mut u64 -B0: - 0: LdU64(42) - 1: StLoc[0](x: u64) - 2: MutBorrowLoc[0](x: u64) - 3: StLoc[1](r: &mut u64) - 4: LdU64(43) - 5: CopyLoc[1](r: &mut u64) - 6: WriteRef - 7: MoveLoc[1](r: &mut u64) - 8: FreezeRef - 9: Call deref(&u64): u64 - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/spec_construct.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/spec_construct.exp index 8edcceb7dfc..e352ec816f5 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/spec_construct.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/spec_construct.exp @@ -14,6 +14,7 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::vector; struct E { k: u8, } @@ -75,24 +76,24 @@ public fun m::foo($t0: &0x42::m::S): u8 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct E { - k: u8 -} -struct S { - data: vector -} +// Bytecode version v9 +module 0x42::m +struct E + k: u8 + +struct S + data: vector + +// Function definition at index 0 +#[persistent] public fun foo(l0: &S): u8 + move_loc l0 + borrow_field S, data + ld_u64 0 + vec_borrow + borrow_field E, k + // @5 + read_ref + ret + -public foo(v: &S): u8 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](v: &S) - 1: ImmBorrowField[0](S.data: vector) - 2: LdU64(0) - 3: VecImmBorrow(2) - 4: ImmBorrowField[1](E.k: u8) - 5: ReadRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/vector.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/vector.exp index 7a9e7c04755..7e42dbf8eaf 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/vector.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/vector.exp @@ -45,14 +45,12 @@ fun vector::create(): vector { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.vector { +// Bytecode version v9 +module 0x42::vector +// Function definition at index 0 +fun create(): vector + ld_const> [1, 2, 3] + ret -create(): vector /* def_idx: 0 */ { -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard4.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard4.exp index 2aeea702975..c9bff1cf977 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard4.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard4.exp @@ -24,7 +24,7 @@ module 0xc0ffee::m { let x = 3; let r = &mut x; let y = &mut x; - let _ = /*freeze*/y; + let _ = freeze(y); *r = 4; } } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard5.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard5.exp index a5e331dfb02..9f1a8244cfd 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard5.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/wildcard5.exp @@ -22,8 +22,8 @@ module 0xc0ffee::m { y: u64, } public fun test() { - let s = S{x: 3,y: 4}; - let S{x: _,y: _} = s; + let s = S{x: 3, y: 4}; + let S{x: _, y: _} = s; } } @@ -78,22 +78,22 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64, - y: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + y: u64 + +// Function definition at index 0 +#[persistent] public fun test() + ld_u64 3 + ld_u64 4 + pack S + unpack S + pop + // @5 + pop + ret + -public test() /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: LdU64(4) - 2: Pack[0](S) - 3: Unpack[0](S) - 4: Pop - 5: Pop - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp b/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp index 601110318e5..cdeb24e656b 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp @@ -1,7 +1,9 @@ Diagnostics: -bug: file format generator: Inferred and Store AssignKind should be not appear here. +bug: compiler internal error: file format generator: Inferred and Store AssignKind should be not appear here. ┌─ tests/bytecode-verify-failure/equality.move:2:7 │ 2 │ fun equality(x: T, y: T): bool { │ ^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp index b2592320dba..8455d48151c 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/access_specifiers/access_not_supported.exp @@ -1,12 +1,12 @@ Diagnostics: -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:11:20 │ 11 │ fun f2() reads S { │ ^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:14:21 │ 14 │ fun f3() writes S { @@ -18,25 +18,25 @@ error: only simple resource names can be used with `acquires` 17 │ fun f4() acquires S(*) { │ ^^^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:39 │ 20 │ fun f_multiple() acquires R reads R writes T, S reads G { │ ^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:48 │ 20 │ fun f_multiple() acquires R reads R writes T, S reads G { │ ^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:51 │ 20 │ fun f_multiple() acquires R reads R writes T, S reads G { │ ^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:20:59 │ 20 │ fun f_multiple() acquires R reads R writes T, S reads G { @@ -66,13 +66,13 @@ error: only simple resource names can be used with `acquires` 38 │ fun f10(x: u64) acquires *(make_up_address(x)) { │ ^^^^^^^^^^^^^^^^^^^^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:45:22 │ 45 │ fun f11() !reads *(0x42), *(0x43) { │ ^^^^^^^ -error: not supported before language version `2.3-unstable`: read/write access specifiers. +error: not supported before language version `2.5-unstable`: read/write access specifiers. ┌─ tests/checking-lang-v2.2/access_specifiers/access_not_supported.move:45:31 │ 45 │ fun f11() !reads *(0x42), *(0x43) { diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp index 5739d8c3551..72d92fa930a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp @@ -8,7 +8,7 @@ error: missing acquires annotation for `R` 15 │ let r = borrow_global(a); │ ------------------- acquired here │ - = since Move 2.2-unstable, `acquires` is inferred by the compiler and can be omitted from the function declaration. + = since Move 2.2, `acquires` is inferred by the compiler and can be omitted from the function declaration. error: unnecessary acquires annotation ┌─ tests/checking-lang-v2.2/acquires/acquires_error.move:14:40 diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp index 70012f32f29..91bf3296a16 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_inferred.exp @@ -34,7 +34,7 @@ module 0x42::acquires_inferred { exists(a) } fun publish(s: &signer) { - move_to(s, R{f: 1}); + move_to(R{f: 1}, s); } fun read(a: address): u64 { let r = borrow_global(a); diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp new file mode 100644 index 00000000000..0cb42e6274c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp @@ -0,0 +1,75 @@ + +Diagnostics: +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:4:9 + │ +4 │ fun f() { + │ ^ + │ + = `f` uses `f<|T|>` at tests/checking-lang-v2.2/bug_16938.move:5 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:10:16 + │ +10 │ public fun foo(): || { + │ ^^^ + │ + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:11 + = `bar<|&T|>` uses `foo<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:15 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:14:9 + │ +14 │ fun bar() { + │ ^^^ + │ + = `bar` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:15 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:11 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:25:16 + │ +25 │ public fun foo(): ||(||) { + │ ^^^ + │ + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + = `bar<|&T|>` uses `maker<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:30 + = `maker<|&T|>` uses `foo<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:34 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:29:9 + │ +29 │ fun bar(): || { + │ ^^^ + │ + = `bar` uses `maker` at tests/checking-lang-v2.2/bug_16938.move:30 + = `maker` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:34 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:33:9 + │ +33 │ fun maker(): ||(||(||)) { + │ ^^^^^ + │ + = `maker` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:34 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + = `bar<|&T|>` uses `maker<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:30 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:44:16 + │ +44 │ public fun foo(): || { + │ ^^^ + │ + = `foo` uses `bar<||(T, T)>` at tests/checking-lang-v2.2/bug_16938.move:45 + = `bar<||(T, T)>` uses `foo<||(||(T, T))>` at tests/checking-lang-v2.2/bug_16938.move:49 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:48:9 + │ +48 │ fun bar() { + │ ^^^ + │ + = `bar` uses `foo<||T>` at tests/checking-lang-v2.2/bug_16938.move:49 + = `foo<||T>` uses `bar<||(||T, ||T)>` at tests/checking-lang-v2.2/bug_16938.move:45 diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move new file mode 100644 index 00000000000..c6a65e05d12 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move @@ -0,0 +1,56 @@ +module 0xc0ffee::m { + struct S { f: T } + + fun f() { + f<|T|>(); + } +} + +module 0xc0ffee::n { + public fun foo(): || { + bar<|&T|> + } + + fun bar() { + (foo())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} + +module 0xc0ffee::o { + public fun foo(): ||(||) { + bar<|&T|> + } + + fun bar(): || { + maker()()() + } + + fun maker(): ||(||(||)) { + foo + } + + fun test() { + let f = foo<||>(); + f()(); + } +} + +module 0xc0ffee::p { + public fun foo(): || { + bar<||(T, T)> + } + + fun bar() { + (foo<||T>())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/basic.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/basic.exp index 81a48586419..77feb7d1665 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/basic.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/basic.exp @@ -32,21 +32,21 @@ module 0xcafe::m { f(x) } fun no_name_clash(x: u64, c: u64): u64 { - map(x, |arg0| __lambda__1__no_name_clash(c, arg0)) + map(x, |arg0| lambda__1__no_name_clash(c, arg0)) } fun with_name_clash1(x: u64, c: u64): u64 { - map(x, |arg0| __lambda__1__with_name_clash1(c, arg0)) + map(x, |arg0| lambda__1__with_name_clash1(c, arg0)) } fun with_name_clash2(x: u64, c: u64): u64 { - map(x, |arg0| __lambda__1__with_name_clash2(c, arg0)) + map(x, |arg0| lambda__1__with_name_clash2(c, arg0)) } - fun __lambda__1__no_name_clash(c: u64, y: u64): u64 { + fun lambda__1__no_name_clash(c: u64, y: u64): u64 { y + c } - fun __lambda__1__with_name_clash1(c: u64, x: u64): u64 { + fun lambda__1__with_name_clash1(c: u64, x: u64): u64 { x + c } - fun __lambda__1__with_name_clash2(c: u64, x: u64): u64 { + fun lambda__1__with_name_clash2(c: u64, x: u64): u64 { { let x = c + 1; x diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/nested.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/nested.exp index a7df64bb3c8..9fe8870a138 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/nested.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/nested.exp @@ -26,12 +26,12 @@ module 0xcafe::m { f(x) } fun nested(x: u64, c: u64): u64 { - map1(x, |arg0| __lambda__2__nested(c, arg0)) + map1(x, |arg0| lambda__2__nested(c, arg0)) } - fun __lambda__1__nested(c: u64, y: u8): u8 { + fun lambda__1__nested(c: u64, y: u8): u8 { y + (c as u8) } - fun __lambda__2__nested(c: u64, y: u64): u64 { - map2(y - c as u8, |arg0| __lambda__1__nested(c, arg0)) as u64 + fun lambda__2__nested(c: u64, y: u64): u64 { + map2((y - c) as u8, |arg0| lambda__1__nested(c, arg0)) as u64 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/pattern.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/pattern.exp index 31141a477e4..fb8cd8eca0f 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/pattern.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda-lifting/pattern.exp @@ -3,7 +3,7 @@ module 0xcafe::m { struct S { x: T, } - private fun consume(s: S,x: T,f: |(S, T)|T): T { + private fun consume(s: S,x: T,f: |S, T|T): T { (f)(s, x) } private fun pattern(s: S,x: u64): u64 { @@ -25,14 +25,14 @@ module 0xcafe::m { struct S { x: T, } - fun consume(s: S, x: T, f: |(S, T)|T): T { + fun consume(s: S, x: T, f: |S, T|T): T { f(s, x) } fun pattern(s: S, x: u64): u64 { - consume(s, x, |(arg0,arg1)| __lambda__1__pattern(arg0, arg1)) + consume(s, x, |arg0,arg1| lambda__1__pattern(arg0, arg1)) } - fun __lambda__1__pattern(param$0: S, _y: u64): u64 { - let S{x: x} = param$0; + fun lambda__1__pattern(param_0: S, _y: u64): u64 { + let S{x: x} = param_0; let y = x; x + y } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/bug_16195.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/bug_16195.exp index 50b8a427f09..1368a74ae7a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/bug_16195.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/bug_16195.exp @@ -236,49 +236,49 @@ module 0xc0ffee::m { 0: |bool|(||bool) has copy + drop, } public fun test_bug16195(): u64 { - let f = Bug16195(|()| __lambda__2__test_bug16195()); + let f = Bug16195(|| lambda__2__test_bug16195()); f()() } public fun test_bug16195_OR_mix1(a: bool): bool { - let f = Bug16195_variant5(|()| __lambda__2__test_bug16195_OR_mix1()); + let f = Bug16195_variant5(|| lambda__2__test_bug16195_OR_mix1()); f()() || a } public fun test_bug16195_OR_mix2(a: bool, b: bool): bool { - let f = Bug16195_variant5(|()| __lambda__2__test_bug16195_OR_mix2()); + let f = Bug16195_variant5(|| lambda__2__test_bug16195_OR_mix2()); f()() || a || b } public fun test_bug16195_OR_mix3(a: bool): bool { - let f = Bug16195_variant6(|()| __lambda__5__test_bug16195_OR_mix3()); + let f = Bug16195_variant6(|| lambda__5__test_bug16195_OR_mix3()); f()()()()() || a } public fun test_bug16195_OR_mix4(a: bool, b: bool): bool { - let f = Bug16195_variant6(|()| __lambda__5__test_bug16195_OR_mix4()); + let f = Bug16195_variant6(|| lambda__5__test_bug16195_OR_mix4()); f()()()()() || a || b } public fun test_bug16195_OR_mix5(a: bool): bool { - let f = Bug16195_variant7(|()| __lambda__2__test_bug16195_OR_mix5(a)); + let f = Bug16195_variant7(|| lambda__2__test_bug16195_OR_mix5(a)); f()(true) || a } public fun test_bug16195_OR_mix6(a: bool): bool { - let f = Bug16195_variant8(|arg0| __lambda__2__test_bug16195_OR_mix6(arg0)); + let f = Bug16195_variant8(|arg0| lambda__2__test_bug16195_OR_mix6(arg0)); f(true)() || a } public fun test_bug16195_variant1(): u64 { - let f = Bug16195_variant1(|()| __lambda__2__test_bug16195_variant1()); + let f = Bug16195_variant1(|| lambda__2__test_bug16195_variant1()); f()() } public fun test_bug16195_variant2(): u64 { - let f = Bug16195_variant2(|()| __lambda__5__test_bug16195_variant2()); + let f = Bug16195_variant2(|| lambda__5__test_bug16195_variant2()); f()()()()() } public fun test_bug16195_variant3(): u64 { - let _arg = |()| __lambda__1__test_bug16195_variant3(); - let f = Bug16195_variant3(|arg0| __lambda__3__test_bug16195_variant3(arg0)); + let _arg = || lambda__1__test_bug16195_variant3(); + let f = Bug16195_variant3(|arg0| lambda__3__test_bug16195_variant3(arg0)); f(_arg)() } public fun test_bug16195_variant4(): u64 { - let _arg = |()| __lambda__1__test_bug16195_variant4(); - let f = Bug16195_variant4(|arg0| __lambda__3__test_bug16195_variant4(arg0)); + let _arg = || lambda__1__test_bug16195_variant4(); + let f = Bug16195_variant4(|arg0| lambda__3__test_bug16195_variant4(arg0)); f(_arg)() } public fun test_regular_OR_case1(a: u64, b: u64): bool { @@ -287,101 +287,101 @@ module 0xc0ffee::m { public fun test_regular_OR_case2(a: u64, b: u64, c: u64): bool { a > 10 || b > 20 || c > 20 } - fun __lambda__1__test_bug16195(): u64 { + fun lambda__1__test_bug16195(): u64 { 42 } - fun __lambda__2__test_bug16195(): ||u64 { - |()| __lambda__1__test_bug16195() + fun lambda__2__test_bug16195(): ||u64 { + || lambda__1__test_bug16195() } - fun __lambda__1__test_bug16195_OR_mix1(): bool { + fun lambda__1__test_bug16195_OR_mix1(): bool { true } - fun __lambda__2__test_bug16195_OR_mix1(): ||bool { - |()| __lambda__1__test_bug16195_OR_mix1() + fun lambda__2__test_bug16195_OR_mix1(): ||bool { + || lambda__1__test_bug16195_OR_mix1() } - fun __lambda__1__test_bug16195_OR_mix2(): bool { + fun lambda__1__test_bug16195_OR_mix2(): bool { true } - fun __lambda__2__test_bug16195_OR_mix2(): ||bool { - |()| __lambda__1__test_bug16195_OR_mix2() + fun lambda__2__test_bug16195_OR_mix2(): ||bool { + || lambda__1__test_bug16195_OR_mix2() } - fun __lambda__1__test_bug16195_OR_mix3(): bool { + fun lambda__1__test_bug16195_OR_mix3(): bool { true } - fun __lambda__2__test_bug16195_OR_mix3(): ||bool { - |()| __lambda__1__test_bug16195_OR_mix3() + fun lambda__2__test_bug16195_OR_mix3(): ||bool { + || lambda__1__test_bug16195_OR_mix3() } - fun __lambda__3__test_bug16195_OR_mix3(): ||(||bool) { - |()| __lambda__2__test_bug16195_OR_mix3() + fun lambda__3__test_bug16195_OR_mix3(): ||(||bool) { + || lambda__2__test_bug16195_OR_mix3() } - fun __lambda__4__test_bug16195_OR_mix3(): ||(||(||bool)) { - |()| __lambda__3__test_bug16195_OR_mix3() + fun lambda__4__test_bug16195_OR_mix3(): ||(||(||bool)) { + || lambda__3__test_bug16195_OR_mix3() } - fun __lambda__5__test_bug16195_OR_mix3(): ||(||(||(||bool))) { - |()| __lambda__4__test_bug16195_OR_mix3() + fun lambda__5__test_bug16195_OR_mix3(): ||(||(||(||bool))) { + || lambda__4__test_bug16195_OR_mix3() } - fun __lambda__1__test_bug16195_OR_mix4(): bool { + fun lambda__1__test_bug16195_OR_mix4(): bool { true } - fun __lambda__2__test_bug16195_OR_mix4(): ||bool { - |()| __lambda__1__test_bug16195_OR_mix4() + fun lambda__2__test_bug16195_OR_mix4(): ||bool { + || lambda__1__test_bug16195_OR_mix4() } - fun __lambda__3__test_bug16195_OR_mix4(): ||(||bool) { - |()| __lambda__2__test_bug16195_OR_mix4() + fun lambda__3__test_bug16195_OR_mix4(): ||(||bool) { + || lambda__2__test_bug16195_OR_mix4() } - fun __lambda__4__test_bug16195_OR_mix4(): ||(||(||bool)) { - |()| __lambda__3__test_bug16195_OR_mix4() + fun lambda__4__test_bug16195_OR_mix4(): ||(||(||bool)) { + || lambda__3__test_bug16195_OR_mix4() } - fun __lambda__5__test_bug16195_OR_mix4(): ||(||(||(||bool))) { - |()| __lambda__4__test_bug16195_OR_mix4() + fun lambda__5__test_bug16195_OR_mix4(): ||(||(||(||bool))) { + || lambda__4__test_bug16195_OR_mix4() } - fun __lambda__1__test_bug16195_OR_mix5(a: bool, x: bool): bool { + fun lambda__1__test_bug16195_OR_mix5(a: bool, x: bool): bool { x || a } - fun __lambda__2__test_bug16195_OR_mix5(a: bool): |bool|bool { - |arg0| __lambda__1__test_bug16195_OR_mix5(a, arg0) + fun lambda__2__test_bug16195_OR_mix5(a: bool): |bool|bool { + |arg0| lambda__1__test_bug16195_OR_mix5(a, arg0) } - fun __lambda__1__test_bug16195_OR_mix6(x: bool): bool { + fun lambda__1__test_bug16195_OR_mix6(x: bool): bool { x || true } - fun __lambda__2__test_bug16195_OR_mix6(x: bool): ||bool { - |()| __lambda__1__test_bug16195_OR_mix6(x) + fun lambda__2__test_bug16195_OR_mix6(x: bool): ||bool { + || lambda__1__test_bug16195_OR_mix6(x) } - fun __lambda__1__test_bug16195_variant1(): u64 { + fun lambda__1__test_bug16195_variant1(): u64 { 42 } - fun __lambda__2__test_bug16195_variant1(): ||u64 { - |()| __lambda__1__test_bug16195_variant1() + fun lambda__2__test_bug16195_variant1(): ||u64 { + || lambda__1__test_bug16195_variant1() } - fun __lambda__1__test_bug16195_variant2(): u64 { + fun lambda__1__test_bug16195_variant2(): u64 { 42 } - fun __lambda__2__test_bug16195_variant2(): ||u64 { - |()| __lambda__1__test_bug16195_variant2() + fun lambda__2__test_bug16195_variant2(): ||u64 { + || lambda__1__test_bug16195_variant2() } - fun __lambda__3__test_bug16195_variant2(): ||(||u64) { - |()| __lambda__2__test_bug16195_variant2() + fun lambda__3__test_bug16195_variant2(): ||(||u64) { + || lambda__2__test_bug16195_variant2() } - fun __lambda__4__test_bug16195_variant2(): ||(||(||u64)) { - |()| __lambda__3__test_bug16195_variant2() + fun lambda__4__test_bug16195_variant2(): ||(||(||u64)) { + || lambda__3__test_bug16195_variant2() } - fun __lambda__5__test_bug16195_variant2(): ||(||(||(||u64))) { - |()| __lambda__4__test_bug16195_variant2() + fun lambda__5__test_bug16195_variant2(): ||(||(||(||u64))) { + || lambda__4__test_bug16195_variant2() } - fun __lambda__1__test_bug16195_variant3() { + fun lambda__1__test_bug16195_variant3() { } - fun __lambda__2__test_bug16195_variant3(): u64 { + fun lambda__2__test_bug16195_variant3(): u64 { 42 } - fun __lambda__3__test_bug16195_variant3(_arg: ||): ||u64 { - |()| __lambda__2__test_bug16195_variant3() + fun lambda__3__test_bug16195_variant3(_arg: ||): ||u64 { + || lambda__2__test_bug16195_variant3() } - fun __lambda__1__test_bug16195_variant4() { + fun lambda__1__test_bug16195_variant4() { } - fun __lambda__2__test_bug16195_variant4(): u64 { + fun lambda__2__test_bug16195_variant4(): u64 { 42 } - fun __lambda__3__test_bug16195_variant4(_arg: ||): ||u64 { - |()| __lambda__2__test_bug16195_variant4() + fun lambda__3__test_bug16195_variant4(_arg: ||): ||u64 { + || lambda__2__test_bug16195_variant4() } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.exp new file mode 100644 index 00000000000..eff2649ffd9 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.exp @@ -0,0 +1,63 @@ + +Diagnostics: +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_1.move:11:66 + │ +11 │ let f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_1.move:16:67 + │ +16 │ let _f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore { + f: ||0x1::option::Option has copy + drop + store, + } + private entry fun entry_func() { + { + let v: 0x1::option::Option = option::none(); + { + let _f: ||0x1::option::Option has copy + drop + store = closure#1m::id(v); + Tuple() + } + } + } + public fun id(x: 0x1::option::Option): 0x1::option::Option { + x + } + private fun init_module(account: &signer) { + { + let v: 0x1::option::Option = option::none(); + { + let f: ||0x1::option::Option has copy + drop + store = closure#1m::id(v); + MoveTo(account, pack m::FunctionStore(f)); + Tuple() + } + } + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||0x1::option::Option has copy + drop + store, + } + entry fun entry_func() { + let v = 0x1::option::none(); + let _f: ||0x1::option::Option has copy + drop + store = || id(v); + } + public fun id(x: 0x1::option::Option): 0x1::option::Option { + x + } + fun init_module(account: &signer) { + let v = 0x1::option::none(); + let f: ||0x1::option::Option has copy + drop + store = || id(v); + move_to(FunctionStore{f: f}, account); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.move new file mode 100644 index 00000000000..bb3d102a065 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_1.move @@ -0,0 +1,18 @@ +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||option::Option has copy+drop+store, + } + public fun id(x: option::Option): option::Option { + x + } + fun init_module(account: &signer) { + let v = option::none(); + let f: ||option::Option has copy+drop+store = || id(v); + move_to(account, FunctionStore { f }); + } + entry fun entry_func() { + let v = option::none(); + let _f: ||option::Option has copy+drop+store = || id(v); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.exp new file mode 100644 index 00000000000..10f57f39f23 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.exp @@ -0,0 +1,48 @@ + +Diagnostics: +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_2.move:14:67 + │ +14 │ let _f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore { + f: ||0x1::option::Option has copy + drop + store, + } + struct OptionStore { + o: 0x1::option::Option, + } + private entry fun entry_func() { + { + let v: OptionStore = pack m::OptionStore(option::none()); + { + let _f: ||0x1::option::Option has copy + drop + store = closure#1m::id(v); + Tuple() + } + } + } + public fun id(x: OptionStore): 0x1::option::Option { + select m::OptionStore.o(x) + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||0x1::option::Option has copy + drop + store, + } + struct OptionStore has copy, drop, store { + o: 0x1::option::Option, + } + entry fun entry_func() { + let v = OptionStore{o: 0x1::option::none()}; + let _f: ||0x1::option::Option has copy + drop + store = || id(v); + } + public fun id(x: OptionStore): 0x1::option::Option { + x.o + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.move new file mode 100644 index 00000000000..38be81db061 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_2.move @@ -0,0 +1,16 @@ +module 0x99::m { + use std::option; + struct OptionStore has copy,drop,store { + o: option::Option, + } + struct FunctionStore has key { + f: ||option::Option has copy+drop+store, + } + public fun id(x: OptionStore): option::Option { + x.o + } + entry fun entry_func() { + let v = OptionStore { o: option::none() }; + let _f: ||option::Option has copy+drop+store = || id(v); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.exp new file mode 100644 index 00000000000..b51db357f6e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.exp @@ -0,0 +1,44 @@ + +Diagnostics: +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_3.move:12:67 + │ +12 │ let _f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + use std::vector; + struct FunctionStore { + f: ||0x1::option::Option has copy + drop + store, + } + private entry fun entry_func() { + { + let v: vector<0x1::option::Option> = vector::empty<0x1::option::Option>(); + { + let _f: ||0x1::option::Option has copy + drop + store = closure#1m::id(v); + Tuple() + } + } + } + public fun id(_x: vector<0x1::option::Option>): 0x1::option::Option { + option::none() + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + use std::vector; + struct FunctionStore has key { + f: ||0x1::option::Option has copy + drop + store, + } + entry fun entry_func() { + let v = 0x1::vector::empty<0x1::option::Option>(); + let _f: ||0x1::option::Option has copy + drop + store = || id(v); + } + public fun id(_x: vector<0x1::option::Option>): 0x1::option::Option { + 0x1::option::none() + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.move new file mode 100644 index 00000000000..8d85b380633 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_3.move @@ -0,0 +1,14 @@ +module 0x99::m { + use std::option; + use std::vector; + struct FunctionStore has key { + f: ||option::Option has copy+drop+store, + } + public fun id(_x: vector>): option::Option { + option::none() + } + entry fun entry_func() { + let v = vector::empty(); + let _f: ||option::Option has copy+drop+store = || id(v); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.exp new file mode 100644 index 00000000000..e85f9e499c3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.exp @@ -0,0 +1,69 @@ + +Diagnostics: +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_4.move:14:66 + │ +14 │ let f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +warning: capturing option values is currently not supported + ┌─ tests/checking-lang-v2.2/lambda/capturing_option_4.move:19:67 + │ +19 │ let _f: ||option::Option has copy+drop+store = || id(v); + │ ^ + +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore { + f: ||0x1::option::Option has copy + drop + store, + } + struct Store { + o: T, + } + private entry fun entry_func() { + { + let v: Store<0x1::option::Option> = pack m::Store<0x1::option::Option>(option::none()); + { + let _f: ||0x1::option::Option has copy + drop + store = closure#1m::id<0x1::option::Option>(v); + Tuple() + } + } + } + public fun id(x: Store): T { + select m::Store.o>(x) + } + private fun init_module(account: &signer) { + { + let v: Store<0x1::option::Option> = pack m::Store<0x1::option::Option>(option::none()); + { + let f: ||0x1::option::Option has copy + drop + store = closure#1m::id<0x1::option::Option>(v); + MoveTo(account, pack m::FunctionStore(f)); + Tuple() + } + } + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||0x1::option::Option has copy + drop + store, + } + struct Store has copy, drop, store { + o: T, + } + entry fun entry_func() { + let v = Store<0x1::option::Option>{o: 0x1::option::none()}; + let _f: ||0x1::option::Option has copy + drop + store = || id<0x1::option::Option>(v); + } + public fun id(x: Store): T { + x.o + } + fun init_module(account: &signer) { + let v = Store<0x1::option::Option>{o: 0x1::option::none()}; + let f: ||0x1::option::Option has copy + drop + store = || id<0x1::option::Option>(v); + move_to(FunctionStore{f: f}, account); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.move new file mode 100644 index 00000000000..50ea8386b8c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_4.move @@ -0,0 +1,21 @@ +module 0x99::m { + use std::option; + struct Store has copy,drop,store { + o: T, + } + struct FunctionStore has key { + f: ||option::Option has copy+drop+store, + } + public fun id(x: Store): T { + x.o + } + fun init_module(account: &signer) { + let v = Store { o: option::none() }; + let f: ||option::Option has copy+drop+store = || id(v); + move_to(account, FunctionStore { f }); + } + entry fun entry_func() { + let v = Store { o: option::none() }; + let _f: ||option::Option has copy+drop+store = || id(v); + } + } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.exp new file mode 100644 index 00000000000..7da6907c1ba --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.exp @@ -0,0 +1,55 @@ +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore { + f: ||u64 has copy + drop + store, + } + private entry fun entry_func() { + { + let v: |0x1::option::Option|u64 has copy + drop + store = closure#0m::id2(); + { + let _f: ||u64 has copy + drop + store = closure#1m::id(v); + Tuple() + } + } + } + public fun id(f: |0x1::option::Option|u64 has copy + drop + store): u64 { + (f)(option::some(3)) + } + public fun id2(_v: 0x1::option::Option): u64 { + 3 + } + private fun init_module(account: &signer) { + { + let v: |0x1::option::Option|u64 has copy + drop + store = closure#0m::id2(); + { + let f: ||u64 has copy + drop + store = closure#1m::id(v); + MoveTo(account, pack m::FunctionStore(f)); + Tuple() + } + } + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||u64 has copy + drop + store, + } + entry fun entry_func() { + let v: |0x1::option::Option|u64 has copy + drop + store = |arg0| id2(arg0); + let _f: ||u64 has copy + drop + store = || id(v); + } + public fun id(f: |0x1::option::Option|u64 has copy + drop + store): u64 { + f(0x1::option::some(3)) + } + public fun id2(_v: 0x1::option::Option): u64 { + 3 + } + fun init_module(account: &signer) { + let v: |0x1::option::Option|u64 has copy + drop + store = |arg0| id2(arg0); + let f: ||u64 has copy + drop + store = || id(v); + move_to(FunctionStore{f: f}, account); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.move new file mode 100644 index 00000000000..770b60e6d26 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_5_no_warning.move @@ -0,0 +1,21 @@ +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||u64 has copy+drop+store, + } + public fun id(f: |option::Option| u64 has copy+drop+store): u64 { + f(option::some(3)) + } + public fun id2(_v: option::Option): u64 { + 3 + } + fun init_module(account: &signer) { + let v :|option::Option|u64 has copy+drop+store = id2; + let f: ||u64 has copy+drop+store = || id(v); + move_to(account, FunctionStore { f }); + } + entry fun entry_func() { + let v :|option::Option|u64 has copy+drop+store = id2; + let _f: ||u64 has copy+drop+store = || id(v); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.exp new file mode 100644 index 00000000000..691b5cec75c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.exp @@ -0,0 +1,40 @@ +// -- Model dump before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore { + f: ||u64 has copy + drop + store, + } + struct OptionStore { + o: u64, + } + private entry fun entry_func() { + { + let v: OptionStore<0x1::option::Option> = pack m::OptionStore<0x1::option::Option>(3); + { + let _f: ||u64 has copy + drop + store = closure#1m::id(v); + Tuple() + } + } + } + public fun id(x: OptionStore<0x1::option::Option>): u64 { + select m::OptionStore.o>>(x) + } +} // end 0x99::m + +// -- Sourcified model before first bytecode pipeline +module 0x99::m { + use std::option; + struct FunctionStore has key { + f: ||u64 has copy + drop + store, + } + struct OptionStore has copy, drop, store { + o: u64, + } + entry fun entry_func() { + let v = OptionStore<0x1::option::Option>{o: 3}; + let _f: ||u64 has copy + drop + store = || id(v); + } + public fun id(x: OptionStore<0x1::option::Option>): u64 { + x.o + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.move new file mode 100644 index 00000000000..00b4cdf2a33 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/capturing_option_6_phantom.move @@ -0,0 +1,16 @@ +module 0x99::m { + use std::option; + struct OptionStore has copy,drop,store { + o: u64, + } + struct FunctionStore has key { + f: ||u64 has copy+drop+store, + } + public fun id(x: OptionStore>): u64 { + x.o + } + entry fun entry_func() { + let v = OptionStore { o: 3 }; + let _f: ||u64 has copy+drop+store = || id(v); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/chained_calls.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/chained_calls.exp index 608374ae946..969bc0b838c 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/chained_calls.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/chained_calls.exp @@ -14,12 +14,12 @@ module 0x66::test { // -- Sourcified model before first bytecode pipeline module 0x66::test { fun add_some(x: u64): |u64|u64 { - |arg0| __lambda__1__add_some(x, arg0) + |arg0| lambda__1__add_some(x, arg0) } fun chain(v: vector<|u64|(|u64|u64)>): u64 { (*0x1::vector::borrow<|u64|(|u64|u64)>(&v, 0))(1)(2) + add_some(1)(2) } - fun __lambda__1__add_some(x: u64, y: u64): u64 { + fun lambda__1__add_some(x: u64, y: u64): u64 { x + y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/fun_wrapper.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/fun_wrapper.exp index 96d431a2ea2..b0231163388 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/fun_wrapper.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/fun_wrapper.exp @@ -32,7 +32,7 @@ module 0x66::test { 0: |u64|u64 has drop, } fun t1(): bool { - let work = Work(|arg0| __lambda__1__t1(arg0)); + let work = Work(|arg0| lambda__1__t1(arg0)); work == <> } fun t2() { @@ -40,13 +40,13 @@ module 0x66::test { } fun take_work(_work: Work) { } - fun __lambda__1__t1(x: u64): u64 { + fun lambda__1__t1(x: u64): u64 { x + 1 } - fun __lambda__2__t1(x: u64): u64 { + fun lambda__2__t1(x: u64): u64 { x + 2 } - fun __lambda__1__t2(x: u64): u64 { + fun lambda__1__t2(x: u64): u64 { x + 1 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda.exp index 070320094c5..4984c77dd79 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda.exp @@ -108,9 +108,9 @@ module 0xc0ffee::m { while (i < 10) { i = i + 1; if (i == 5) { - brk2(|()| __lambda__1__bar()); - brk2(|()| __lambda__2__bar()); - brk2(|()| __lambda__3__bar()); + brk2(|| lambda__1__bar()); + brk2(|| lambda__2__bar()); + brk2(|| lambda__3__bar()); } }; i @@ -149,13 +149,13 @@ module 0xc0ffee::m { }; i } - fun __lambda__1__bar() { + fun lambda__1__bar() { break } - fun __lambda__2__bar() { + fun lambda__2__bar() { while (true) break } - fun __lambda__3__bar() { + fun lambda__3__bar() { while (true) continue } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda_typed.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda_typed.exp index 0574f7d7584..bb162d8c810 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/break_continue_in_lambda_typed.exp @@ -108,9 +108,9 @@ module 0xc0ffee::m { while (i < 10) { i = i + 1; if (i == 5) { - brk2(|arg0| __lambda__1__bar(arg0)); - brk2(|arg0| __lambda__2__bar(arg0)); - brk2(|arg0| __lambda__3__bar(arg0)); + brk2(|arg0| lambda__1__bar(arg0)); + brk2(|arg0| lambda__2__bar(arg0)); + brk2(|arg0| lambda__3__bar(arg0)); } }; i @@ -149,13 +149,13 @@ module 0xc0ffee::m { }; i } - fun __lambda__1__bar(_x: u64) { + fun lambda__1__bar(_x: u64) { break } - fun __lambda__2__bar(_x: u64) { + fun lambda__2__bar(_x: u64) { while (true) break } - fun __lambda__3__bar(_x: u64) { + fun lambda__3__bar(_x: u64) { while (true) continue } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991.exp index 9cff7e193b1..f9b5ad314f5 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(f: |(u64, u64)|u64,g: |(u64, u64)|u64,x: u64,_y: u64): u64 { + private fun foo(f: |u64, u64|u64,g: |u64, u64|u64,x: u64,_y: u64): u64 { Add((f)(x, _y), (g)(x, _y)) } public fun test() { @@ -27,18 +27,18 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(f: |(u64, u64)|u64, g: |(u64, u64)|u64, x: u64, _y: u64): u64 { + fun foo(f: |u64, u64|u64, g: |u64, u64|u64, x: u64, _y: u64): u64 { f(x, _y) + g(x, _y) } public fun test() { - if (foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), |(arg0,arg1)| __lambda__2__test(arg0, arg1), 10, 100) == 110) () else abort 0; + if (foo(|arg0,arg1| lambda__1__test(arg0, arg1), |arg0,arg1| lambda__2__test(arg0, arg1), 10, 100) == 110) () else abort 0; } - fun __lambda__1__test(x: u64, param$1: u64): u64 { - let _ = param$1; + fun lambda__1__test(x: u64, param_1: u64): u64 { + let _ = param_1; x } - fun __lambda__2__test(param$0: u64, y: u64): u64 { - let _ = param$0; + fun lambda__2__test(param_0: u64, y: u64): u64 { + let _ = param_0; y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam.exp index 68bad535354..301205d1221 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(f: |(u64, u64)|u64,g: |(u64, u64)|u64,x: u64,_y: u64): u64 { + private fun foo(f: |u64, u64|u64,g: |u64, u64|u64,x: u64,_y: u64): u64 { Add((f)(x, _y), (g)(x, _y)) } public fun test() { @@ -33,20 +33,20 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(f: |(u64, u64)|u64, g: |(u64, u64)|u64, x: u64, _y: u64): u64 { + fun foo(f: |u64, u64|u64, g: |u64, u64|u64, x: u64, _y: u64): u64 { f(x, _y) + g(x, _y) } public fun test() { - if (foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), |(arg0,arg1)| __lambda__2__test(arg0, arg1), 10, 100) == 13) () else abort 0; + if (foo(|arg0,arg1| lambda__1__test(arg0, arg1), |arg0,arg1| lambda__2__test(arg0, arg1), 10, 100) == 13) () else abort 0; } - fun __lambda__1__test(param$0: u64, param$1: u64): u64 { - let _ = param$1; - let _ = param$0; + fun lambda__1__test(param_0: u64, param_1: u64): u64 { + let _ = param_1; + let _ = param_0; 3 } - fun __lambda__2__test(param$0: u64, param$1: u64): u64 { - let _ = param$1; - let _ = param$0; + fun lambda__2__test(param_0: u64, param_1: u64): u64 { + let _ = param_1; + let _ = param_0; 10 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam2.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam2.exp index 4c97eda8f44..de408b5f154 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam2.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991_noparam2.exp @@ -31,14 +31,14 @@ module 0x42::Test { f(x) + g(x) } public fun test() { - if (foo(|arg0| __lambda__1__test(arg0), |arg0| __lambda__2__test(arg0), 10, 100) == 13) () else abort 0; + if (foo(|arg0| lambda__1__test(arg0), |arg0| lambda__2__test(arg0), 10, 100) == 13) () else abort 0; } - fun __lambda__1__test(param$0: u64): u64 { - let _ = param$0; + fun lambda__1__test(param_0: u64): u64 { + let _ = param_0; 3 } - fun __lambda__2__test(param$0: u64): u64 { - let _ = param$0; + fun lambda__2__test(param_0: u64): u64 { + let _ = param_0; 10 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991a.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991a.exp index 5ed03c0d1fd..a1bb5dc0537 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991a.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991a.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(f: |(u64, u64)|u64,g: |(u64, u64)|u64,h: |(u64, u64)|u64,i: |(u64, u64)|u64,x: u64,y: u64): u64 { + private fun foo(f: |u64, u64|u64,g: |u64, u64|u64,h: |u64, u64|u64,i: |u64, u64|u64,x: u64,y: u64): u64 { Add(Add(Add((f)(x, y), (g)(x, y)), (h)(x, y)), (i)(x, y)) } public fun test() { @@ -33,24 +33,24 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(f: |(u64, u64)|u64, g: |(u64, u64)|u64, h: |(u64, u64)|u64, i: |(u64, u64)|u64, x: u64, y: u64): u64 { + fun foo(f: |u64, u64|u64, g: |u64, u64|u64, h: |u64, u64|u64, i: |u64, u64|u64, x: u64, y: u64): u64 { f(x, y) + g(x, y) + h(x, y) + i(x, y) } public fun test() { - if (foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), |(arg0,arg1)| __lambda__2__test(arg0, arg1), |(arg0,arg1)| __lambda__3__test(arg0, arg1), |(arg0,arg1)| __lambda__4__test(arg0, arg1), 10, 100) == 220) () else abort 0; + if (foo(|arg0,arg1| lambda__1__test(arg0, arg1), |arg0,arg1| lambda__2__test(arg0, arg1), |arg0,arg1| lambda__3__test(arg0, arg1), |arg0,arg1| lambda__4__test(arg0, arg1), 10, 100) == 220) () else abort 0; } - fun __lambda__1__test(x: u64, param$1: u64): u64 { - let _ = param$1; + fun lambda__1__test(x: u64, param_1: u64): u64 { + let _ = param_1; x } - fun __lambda__2__test(param$0: u64, y: u64): u64 { - let _ = param$0; + fun lambda__2__test(param_0: u64, y: u64): u64 { + let _ = param_0; y } - fun __lambda__3__test(a: u64, _b: u64): u64 { + fun lambda__3__test(a: u64, _b: u64): u64 { a } - fun __lambda__4__test(_c: u64, d: u64): u64 { + fun lambda__4__test(_c: u64, d: u64): u64 { d } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991b.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991b.exp index 915c6f96c37..c9dee3b1df9 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991b.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991b.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(g: |(u64, u64)|u64,x: u64,_y: u64): u64 { + private fun foo(g: |u64, u64|u64,x: u64,_y: u64): u64 { (g)(x, _y) } public fun test() { @@ -21,14 +21,14 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(g: |(u64, u64)|u64, x: u64, _y: u64): u64 { + fun foo(g: |u64, u64|u64, x: u64, _y: u64): u64 { g(x, _y) } public fun test() { - if (foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), 10, 100) == 100) () else abort 0; + if (foo(|arg0,arg1| lambda__1__test(arg0, arg1), 10, 100) == 100) () else abort 0; } - fun __lambda__1__test(param$0: u64, y: u64): u64 { - let _ = param$0; + fun lambda__1__test(param_0: u64, y: u64): u64 { + let _ = param_0; y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991c.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991c.exp index 6656bd028fd..324a45e9e47 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991c.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_10991c.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(g: |(u64, u64, u64, u64)|u64,x: u64,y: u64,z: u64,q: u64): u64 { + private fun foo(g: |u64, u64, u64, u64|u64,x: u64,y: u64,z: u64,q: u64): u64 { (g)(x, y, z, q) } public fun test() { @@ -24,15 +24,15 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(g: |(u64, u64, u64, u64)|u64, x: u64, y: u64, z: u64, q: u64): u64 { + fun foo(g: |u64, u64, u64, u64|u64, x: u64, y: u64, z: u64, q: u64): u64 { g(x, y, z, q) } public fun test() { - if (foo(|(arg0,arg1,arg2,arg3)| __lambda__1__test(arg0, arg1, arg2, arg3), 10, 100, 1000, 10000) == 10100) () else abort 0; + if (foo(|arg0,arg1,arg2,arg3| lambda__1__test(arg0, arg1, arg2, arg3), 10, 100, 1000, 10000) == 10100) () else abort 0; } - fun __lambda__1__test(param$0: u64, y: u64, param$2: u64, q: u64): u64 { - let _ = param$2; - let _ = param$0; + fun lambda__1__test(param_0: u64, y: u64, param_2: u64, q: u64): u64 { + let _ = param_2; + let _ = param_0; y + q } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_16091.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_16091.exp index e19db2108a3..6a8c649e19e 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_16091.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/bug_16091.exp @@ -49,7 +49,7 @@ module 0x42::Test { let (t2) = (self); { let (self) = (t2); - let (_t4) = (self); + let (_v0) = (self); }; }; } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/dotdot_valid.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/dotdot_valid.exp index 034ce35d75e..35643b47ce6 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/dotdot_valid.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/dotdot_valid.exp @@ -347,44 +347,44 @@ module 0x42::test { 3: u64, } fun lambda_param(f: |S2|bool): bool { - let x = S2(true,S0{}); + let x = S2(true, S0{}); f(x) } fun nested1(x: S4) { - let S4{x: _x,y: _} = x; - let S4{x: _,y: _y} = x; - let S4{x: _,y: S3{x: _,y: _}} = x; - let S4{x: _,y: S3{x: _x,y: _}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; - let S4{x: _,y: S3{x: _,y: _y}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; + let S4{x: _x, y: _} = x; + let S4{x: _, y: _y} = x; + let S4{x: _, y: S3{x: _, y: _}} = x; + let S4{x: _, y: S3{x: _x, y: _}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; + let S4{x: _, y: S3{x: _, y: _y}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; } fun nested1_ref(x: &S4) { - let S4{x: _x,y: _} = x; - let S4{x: _,y: _y} = x; - let S4{x: _,y: S3{x: _,y: _}} = x; - let S4{x: _,y: S3{x: _x,y: _}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; - let S4{x: _,y: S3{x: _,y: _y}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; + let S4{x: _x, y: _} = x; + let S4{x: _, y: _y} = x; + let S4{x: _, y: S3{x: _, y: _}} = x; + let S4{x: _, y: S3{x: _x, y: _}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; + let S4{x: _, y: S3{x: _, y: _y}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; } fun nested2(x: S5) { - let S5(_,S1(_)) = x; + let S5(_, S1(_)) = x; } fun nested2_ref(x: &S5) { - let S5(_,S1(_)) = x; + let S5(_, S1(_)) = x; } fun nested3(x: S5>) { - let S5>(_,S4{x: _,y: _}) = x; + let S5>(_, S4{x: _, y: _}) = x; } fun nested3_ref(x: &S5>) { - let S5>(_,S4{x: _,y: _}) = x; + let S5>(_, S4{x: _, y: _}) = x; } fun nested4(x: S4) { - let S4{x: S1(_),y: _} = x; + let S4{x: S1(_), y: _} = x; } fun nested4_ref(x: &S4) { - let S4{x: S1(_),y: _} = x; + let S4{x: S1(_), y: _} = x; } fun simple_0(x: S0) { let S0{} = x; @@ -399,64 +399,64 @@ module 0x42::test { let S1(_) = x; } fun simple_2(x: S2) { - let S2(_,_) = x; - let S2(_x,_) = x; - let S2(_,_x) = x; - let S2(_,_) = x; - let S2(_,_) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; + let S2(_, _) = x; + let S2(_x, _) = x; + let S2(_, _x) = x; + let S2(_, _) = x; + let S2(_, _) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; } fun simple_2_ref(x: &S2) { - let S2(_,_) = x; - let S2(_x,_) = x; - let S2(_,_x) = x; - let S2(_,_) = x; - let S2(_,_) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; + let S2(_, _) = x; + let S2(_x, _) = x; + let S2(_, _x) = x; + let S2(_, _) = x; + let S2(_, _) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; } fun simple_3(x: S3) { - let S3{x: _,y: _} = x; - let S3{x: _x,y: _} = x; - let S3{x: _,y: _y} = x; + let S3{x: _, y: _} = x; + let S3{x: _x, y: _} = x; + let S3{x: _, y: _y} = x; } fun simple_3_ref(x: S3) { - let S3{x: _,y: _} = x; - let S3{x: _x,y: _} = x; - let S3{x: _,y: _y} = x; + let S3{x: _, y: _} = x; + let S3{x: _x, y: _} = x; + let S3{x: _, y: _y} = x; } fun simple_4(x: E1): u8 { match (x) { - E1::A(x,_) => x, + E1::A(x, _) => x, E1::B(x) => x, - E1::C{x: x,y: _} => x, + E1::C{x: x, y: _} => x, } } fun simple_4_ref(x: &E1): &u8 { match (x) { - E1::A(x,_) => x, + E1::A(x, _) => x, E1::B(x) => x, } } fun simple_5(x: E1): u8 { match (x) { - E1::A(_,y) => if (y) 1u8 else 0u8, + E1::A(_, y) => if (y) 1u8 else 0u8, E1::B(x) => x, - E1::C{x: _,y: S1(x)} => x, + E1::C{x: _, y: S1(x)} => x, } } fun simple_6(x: &S7) { - let S7(_w,_,_,_z) = x; - let S7(_w,_x,_y,_z) = x; + let S7(_w, _, _, _z) = x; + let S7(_w, _x, _y, _z) = x; } fun test_lambda_param(): bool { - lambda_param(|arg0| __lambda__1__test_lambda_param(arg0)) + lambda_param(|arg0| lambda__1__test_lambda_param(arg0)) } - fun __lambda__1__test_lambda_param(param$0: S2): bool { - let S2(x,_) = param$0; + fun lambda__1__test_lambda_param(param_0: S2): bool { + let S2(x, _) = param_0; x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eq_inline.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eq_inline.exp index c20f853a43a..34e54e866cf 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eq_inline.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eq_inline.exp @@ -18,9 +18,9 @@ module 0x42::m { fun foo(f: |&u64| has drop) { } fun g() { - foo(|arg0| __lambda__1__g(arg0)); + foo(|arg0| lambda__1__g(arg0)); } - fun __lambda__1__g(v: &u64) { + fun lambda__1__g(v: &u64) { v == &1; } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eval_ignored_param.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eval_ignored_param.exp index 9ebeaae0d96..7dc17f436e2 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eval_ignored_param.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/eval_ignored_param.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(f: |(u64, u64, u64)|u64,g: |(u64, u64, u64)|u64,x: u64,_: u64,y: u64,z: u64): u64 { + private fun foo(f: |u64, u64, u64|u64,g: |u64, u64, u64|u64,x: u64,_: u64,y: u64,z: u64): u64 { { let r1: u64 = (f)(x: u64 = Add(x, 1); x, y: u64 = Add(y, 1); @@ -45,7 +45,7 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(f: |(u64, u64, u64)|u64, g: |(u64, u64, u64)|u64, x: u64, _: u64, y: u64, z: u64): u64 { + fun foo(f: |u64, u64, u64|u64, g: |u64, u64, u64|u64, x: u64, _: u64, y: u64, z: u64): u64 { let r1 = f({ x = x + 1; x @@ -69,16 +69,16 @@ module 0x42::Test { r1 + r2 + 3 * x + 5 * y + 7 * z } public fun test() { - let r = foo(|(arg0,arg1,arg2)| __lambda__1__test(arg0, arg1, arg2), |(arg0,arg1,arg2)| __lambda__2__test(arg0, arg1, arg2), 1, 10, 100, 1000); + let r = foo(|arg0,arg1,arg2| lambda__1__test(arg0, arg1, arg2), |arg0,arg1,arg2| lambda__2__test(arg0, arg1, arg2), 1, 10, 100, 1000); if (r == 9637) () else abort r; } - fun __lambda__1__test(x: u64, param$1: u64, z: u64): u64 { - let _ = param$1; + fun lambda__1__test(x: u64, param_1: u64, z: u64): u64 { + let _ = param_1; x * z } - fun __lambda__2__test(param$0: u64, y: u64, param$2: u64): u64 { - let _ = param$2; - let _ = param$0; + fun lambda__2__test(param_0: u64, y: u64, param_2: u64): u64 { + let _ = param_2; + let _ = param_0; y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/generic_calls.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/generic_calls.exp index 0ae6c54f3b1..4d9a00becb2 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/generic_calls.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/generic_calls.exp @@ -27,6 +27,6 @@ module 0x42::m { f(s); } fun test_receiver_inference(s: S) { - inlined(|arg0| id(arg0), s) + inlined(|arg0| id(arg0), s) } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inline_fun_in_spec.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inline_fun_in_spec.exp index 3a09457b0d4..10395ca7c9f 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inline_fun_in_spec.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inline_fun_in_spec.exp @@ -104,13 +104,13 @@ module 0x42::m { inline fun get(a: address): &R { borrow_global(a) } - fun __lambda__1__function_code_spec_block(y: num): bool { + fun lambda__1__function_code_spec_block(y: num): bool { y > 0u256 } - fun __lambda__1__function_spec_block(x: num): num { + fun lambda__1__function_spec_block(x: num): num { x + 1u256 } - fun __lambda__2__function_spec_block(x: num): num { + fun lambda__2__function_spec_block(x: num): num { x + 1u256 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inlining1.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inlining1.exp index 9753b3bf9e2..f1e4f534f76 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inlining1.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/inlining1.exp @@ -31,10 +31,10 @@ module 0x42::Test { if (test() == 3) () else abort 5; } public fun test(): u64 { - foo(|arg0| __lambda__1__test(arg0), 10) + foo(|arg0| lambda__1__test(arg0), 10) } - fun __lambda__1__test(param$0: u64): u64 { - let _ = param$0; + fun lambda__1__test(param_0: u64): u64 { + let _ = param_0; 3 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_no_param.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_no_param.exp index 0ff4a9729b5..747f5ac1c3d 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_no_param.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_no_param.exp @@ -31,14 +31,14 @@ module 0xdecafbad::m { f(); } public fun one() { - foo(|()| __lambda__1__one()); + foo(|| lambda__1__one()); } public fun two(x: u64): u64 { - bar(|()| __lambda__1__two(x)) + bar(|| lambda__1__two(x)) } - fun __lambda__1__one() { + fun lambda__1__one() { } - fun __lambda__1__two(x: u64): u64 { + fun lambda__1__two(x: u64): u64 { x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param.exp index 7997dc23aa4..4de95b1d09d 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param.exp @@ -79,27 +79,27 @@ module 0x42::LambdaParam { b } fun test_lambda_symbol_param1() { - let a = inline_apply2(|arg0| __lambda__1__test_lambda_symbol_param1(arg0), 3); + let a = inline_apply2(|arg0| lambda__1__test_lambda_symbol_param1(arg0), 3); if (a == 3) () else abort 0; } fun test_lambda_symbol_param2() { - let a = inline_apply2(|arg0| __lambda__1__test_lambda_symbol_param2(arg0), 3); + let a = inline_apply2(|arg0| lambda__1__test_lambda_symbol_param2(arg0), 3); if (a == 3) () else abort 0; - let b = inline_apply(|arg0| __lambda__2__test_lambda_symbol_param2(arg0), 3); + let b = inline_apply(|arg0| lambda__2__test_lambda_symbol_param2(arg0), 3); if (b == 3) () else abort 0; - let b = inline_apply3(|arg0| __lambda__3__test_lambda_symbol_param2(arg0), 3); + let b = inline_apply3(|arg0| lambda__3__test_lambda_symbol_param2(arg0), 3); if (b == 3) () else abort 0; } - fun __lambda__1__test_lambda_symbol_param1(x: u64): u64 { + fun lambda__1__test_lambda_symbol_param1(x: u64): u64 { x } - fun __lambda__1__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__1__test_lambda_symbol_param2(x: u64): u64 { x } - fun __lambda__2__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__2__test_lambda_symbol_param2(x: u64): u64 { x } - fun __lambda__3__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__3__test_lambda_symbol_param2(x: u64): u64 { x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param_typed.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param_typed.exp index 7997dc23aa4..4de95b1d09d 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_param_typed.exp @@ -79,27 +79,27 @@ module 0x42::LambdaParam { b } fun test_lambda_symbol_param1() { - let a = inline_apply2(|arg0| __lambda__1__test_lambda_symbol_param1(arg0), 3); + let a = inline_apply2(|arg0| lambda__1__test_lambda_symbol_param1(arg0), 3); if (a == 3) () else abort 0; } fun test_lambda_symbol_param2() { - let a = inline_apply2(|arg0| __lambda__1__test_lambda_symbol_param2(arg0), 3); + let a = inline_apply2(|arg0| lambda__1__test_lambda_symbol_param2(arg0), 3); if (a == 3) () else abort 0; - let b = inline_apply(|arg0| __lambda__2__test_lambda_symbol_param2(arg0), 3); + let b = inline_apply(|arg0| lambda__2__test_lambda_symbol_param2(arg0), 3); if (b == 3) () else abort 0; - let b = inline_apply3(|arg0| __lambda__3__test_lambda_symbol_param2(arg0), 3); + let b = inline_apply3(|arg0| lambda__3__test_lambda_symbol_param2(arg0), 3); if (b == 3) () else abort 0; } - fun __lambda__1__test_lambda_symbol_param1(x: u64): u64 { + fun lambda__1__test_lambda_symbol_param1(x: u64): u64 { x } - fun __lambda__1__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__1__test_lambda_symbol_param2(x: u64): u64 { x } - fun __lambda__2__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__2__test_lambda_symbol_param2(x: u64): u64 { x } - fun __lambda__3__test_lambda_symbol_param2(x: u64): u64 { + fun lambda__3__test_lambda_symbol_param2(x: u64): u64 { x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_return.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_return.exp index f321bc07853..aa337a0b6b7 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_return.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_return.exp @@ -25,10 +25,10 @@ module 0x42::LambdaReturn { f(b) } fun test_lambda_symbol_param() { - let a = inline_apply2(|arg0| __lambda__1__test_lambda_symbol_param(arg0), 3); + let a = inline_apply2(|arg0| lambda__1__test_lambda_symbol_param(arg0), 3); if (a == 3) () else abort 0; } - fun __lambda__1__test_lambda_symbol_param(x: u64): u64 { + fun lambda__1__test_lambda_symbol_param(x: u64): u64 { x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_typed.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_typed.exp index a399d1e90bb..59f4c158b58 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/lambda_typed.exp @@ -280,6 +280,7 @@ module 0x42::LambdaTest1 { } module 0x42::LambdaTest2 { use 0x42::LambdaTest1; + use std::vector; public inline fun foreach(v: &vector, action: |&T|) { let i = 0; while (i < 0x1::vector::length(v)) { diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/masking.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/masking.exp index 6cf2fecd944..292bd9726ec 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/masking.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/masking.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - private fun foo(f: |(u64, u64)|u64,g: |(u64, u64)|u64,x: u64,_y: u64): u64 { + private fun foo(f: |u64, u64|u64,g: |u64, u64|u64,x: u64,_y: u64): u64 { Add((f)(x, _y), (g)(x, _y)) } public fun main(): u64 { @@ -22,18 +22,18 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - fun foo(f: |(u64, u64)|u64, g: |(u64, u64)|u64, x: u64, _y: u64): u64 { + fun foo(f: |u64, u64|u64, g: |u64, u64|u64, x: u64, _y: u64): u64 { f(x, _y) + g(x, _y) } public fun main(): u64 { - foo(|(arg0,arg1)| __lambda__1__main(arg0, arg1), |(arg0,arg1)| __lambda__2__main(arg0, arg1), 10, 100) + foo(|arg0,arg1| lambda__1__main(arg0, arg1), |arg0,arg1| lambda__2__main(arg0, arg1), 10, 100) } - fun __lambda__1__main(x: u64, param$1: u64): u64 { - let _ = param$1; + fun lambda__1__main(x: u64, param_1: u64): u64 { + let _ = param_1; x } - fun __lambda__2__main(param$0: u64, y: u64): u64 { - let _ = param$0; + fun lambda__2__main(param_0: u64, y: u64): u64 { + let _ = param_0; y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda.exp index f06435a4430..891bf2c83cc 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - public fun apply(f: |(u64, u64)|u64,x: u64,y: u64): u64 { + public fun apply(f: |u64, u64|u64,x: u64,y: u64): u64 { (f)(x, y) } public fun test(): u64 { @@ -16,16 +16,16 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - public fun apply(f: |(u64, u64)|u64, x: u64, y: u64): u64 { + public fun apply(f: |u64, u64|u64, x: u64, y: u64): u64 { f(x, y) } public fun test(): u64 { - apply(|(arg0,arg1)| __lambda__1__test(arg0, arg1), 1, apply(|(arg0,arg1)| __lambda__2__test(arg0, arg1), 2, 1)) + apply(|arg0,arg1| lambda__1__test(arg0, arg1), 1, apply(|arg0,arg1| lambda__2__test(arg0, arg1), 2, 1)) } - fun __lambda__1__test(x: u64, y: u64): u64 { + fun lambda__1__test(x: u64, y: u64): u64 { x + y } - fun __lambda__2__test(x: u64, y: u64): u64 { + fun lambda__2__test(x: u64, y: u64): u64 { x * y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda_module.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda_module.exp index b45d7e7a43a..dda4cc62330 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda_module.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/nested_lambda_module.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test1 { - public fun apply(f: |(u64, u64)|u64,x: u64,y: u64): u64 { + public fun apply(f: |u64, u64|u64,x: u64,y: u64): u64 { (f)(x, y) } } // end 0x42::Test1 @@ -19,19 +19,19 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test1 { - public fun apply(f: |(u64, u64)|u64, x: u64, y: u64): u64 { + public fun apply(f: |u64, u64|u64, x: u64, y: u64): u64 { f(x, y) } } module 0x42::Test { use 0x42::Test1; public fun test(): u64 { - Test1::apply(|(arg0,arg1)| __lambda__1__test(arg0, arg1), 1, Test1::apply(|(arg0,arg1)| __lambda__2__test(arg0, arg1), 2, 1)) + Test1::apply(|arg0,arg1| lambda__1__test(arg0, arg1), 1, Test1::apply(|arg0,arg1| lambda__2__test(arg0, arg1), 2, 1)) } - fun __lambda__1__test(x: u64, y: u64): u64 { + fun lambda__1__test(x: u64, y: u64): u64 { x + y } - fun __lambda__2__test(x: u64, y: u64): u64 { + fun lambda__2__test(x: u64, y: u64): u64 { x * y } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/non_lambda_arg.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/non_lambda_arg.exp index 85994fdbe6b..280bea33d09 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/non_lambda_arg.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/non_lambda_arg.exp @@ -1,13 +1,13 @@ // -- Model dump before first bytecode pipeline module 0x42::sort { use std::vector; - public fun incorrect_sort(arr: &mut vector,a_less_b: |(T, T)|bool) { + public fun incorrect_sort(arr: &mut vector,a_less_b: |T, T|bool) { { let n: u64 = vector::length(Freeze(false)(arr)); sort::incorrect_sort_recursive(arr, 0, Sub(n, 1), a_less_b) } } - public fun incorrect_sort_recursive(arr: &mut vector,low: u64,high: u64,a_less_b: |(T, T)|bool) { + public fun incorrect_sort_recursive(arr: &mut vector,low: u64,high: u64,a_less_b: |T, T|bool) { if Lt(low, high) { { let pi: u64 = Add(low, Div(high, 2)); @@ -24,11 +24,12 @@ module 0x42::sort { // -- Sourcified model before first bytecode pipeline module 0x42::sort { - public fun incorrect_sort(arr: &mut vector, a_less_b: |(T, T)|bool) { + use std::vector; + public fun incorrect_sort(arr: &mut vector, a_less_b: |T, T|bool) { let n = 0x1::vector::length(/*freeze*/arr); incorrect_sort_recursive(arr, 0, n - 1, a_less_b) } - public fun incorrect_sort_recursive(arr: &mut vector, low: u64, high: u64, a_less_b: |(T, T)|bool) { + public fun incorrect_sort_recursive(arr: &mut vector, low: u64, high: u64, a_less_b: |T, T|bool) { if (low < high) { let pi = low + high / 2; incorrect_sort_recursive(arr, low, pi - 1, a_less_b); diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/options.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/options.exp index 2562fe06c32..5478e14efc4 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/options.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/options.exp @@ -28,18 +28,20 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::map_opt { + use std::option; public fun map(t: 0x1::option::Option, f: |Element|OtherElement has drop): 0x1::option::Option { if (0x1::option::is_some(&t)) 0x1::option::some(f(0x1::option::extract(&mut t))) else 0x1::option::none() } } module 0x42::Test { + use std::option; use 0x42::map_opt; public fun test(): u64 { let t = 0x1::option::some(1); - let x = map_opt::map(t, |arg0| __lambda__1__test(arg0)); + let x = map_opt::map(t, |arg0| lambda__1__test(arg0)); 0x1::option::extract(&mut x) } - fun __lambda__1__test(e: u64): u64 { + fun lambda__1__test(e: u64): u64 { e + 1 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda.exp index 5f835ccf2c7..86a905d4eff 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda.exp @@ -3,7 +3,7 @@ module 0x42::Test { private fun adder(x: u64,y: u64): u64 { Add(x, y) } - private fun apply(f: |(u64, u64)|u64,x: u64,y: u64): u64 { + private fun apply(f: |u64, u64|u64,x: u64,y: u64): u64 { (f)(x, y) } public fun main(): u64 { @@ -19,13 +19,13 @@ module 0x42::Test { fun adder(x: u64, y: u64): u64 { x + y } - fun apply(f: |(u64, u64)|u64, x: u64, y: u64): u64 { + fun apply(f: |u64, u64|u64, x: u64, y: u64): u64 { f(x, y) } public fun main(): u64 { - apply(|(arg0,arg1)| __lambda__1__main(arg0, arg1), 10, 100) + apply(|arg0,arg1| lambda__1__main(arg0, arg1), 10, 100) } - fun __lambda__1__main(x: u64, y: u64): u64 { + fun lambda__1__main(x: u64, y: u64): u64 { adder(x, y) } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda_typed.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda_typed.exp index 348692ff839..420009acc7f 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/return_in_lambda_typed.exp @@ -3,7 +3,7 @@ module 0x42::Test { private fun adder(x: u64,y: u64): u64 { Add(x, y) } - private fun apply(f: |(u64, u64)|u64,x: u64,y: u64): u64 { + private fun apply(f: |u64, u64|u64,x: u64,y: u64): u64 { (f)(x, y) } public fun main(): u64 { @@ -27,21 +27,21 @@ module 0x42::Test { fun adder(x: u64, y: u64): u64 { x + y } - fun apply(f: |(u64, u64)|u64, x: u64, y: u64): u64 { + fun apply(f: |u64, u64|u64, x: u64, y: u64): u64 { f(x, y) } public fun main(): u64 { - apply(|(arg0,arg1)| __lambda__1__main(arg0, arg1), 10, 100); - apply(|(arg0,arg1)| __lambda__2__main(arg0, arg1), 10, 100); - apply(|(arg0,arg1)| __lambda__3__main(arg0, arg1), 10, 100) + apply(|arg0,arg1| lambda__1__main(arg0, arg1), 10, 100); + apply(|arg0,arg1| lambda__2__main(arg0, arg1), 10, 100); + apply(|arg0,arg1| lambda__3__main(arg0, arg1), 10, 100) } - fun __lambda__1__main(x: u64, y: u64): u64 { + fun lambda__1__main(x: u64, y: u64): u64 { adder(x, y) } - fun __lambda__2__main(x: u64, y: u64): u64 { + fun lambda__2__main(x: u64, y: u64): u64 { adder(x, y) } - fun __lambda__3__main(x: u64, y: u64): u64 { + fun lambda__3__main(x: u64, y: u64): u64 { adder(x, y) } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/same_names.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/same_names.exp index 0989e91669b..9e8620164b6 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/same_names.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/same_names.exp @@ -18,7 +18,7 @@ module 0x42::b { module 0x42::c { use 0x42::a; // resolved as: 0x42::a use 0x42::b; // resolved as: 0x42::b - private fun foo(f: |(a::MyList, b::MyOtherList)|,x: a::MyList,y: b::MyOtherList) { + private fun foo(f: |a::MyList, b::MyOtherList|,x: a::MyList,y: b::MyOtherList) { (f)(x, y) } private fun test(x: a::MyList,y: b::MyOtherList) { @@ -53,13 +53,13 @@ module 0x42::b { module 0x42::c { use 0x42::a; use 0x42::b; - fun foo(f: |(a::MyList, b::MyOtherList)|, x: a::MyList, y: b::MyOtherList) { + fun foo(f: |a::MyList, b::MyOtherList|, x: a::MyList, y: b::MyOtherList) { f(x, y) } fun test(x: a::MyList, y: b::MyOtherList) { - foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), x, y) + foo(|arg0,arg1| lambda__1__test(arg0, arg1), x, y) } - fun __lambda__1__test(x: a::MyList, y: b::MyOtherList) { + fun lambda__1__test(x: a::MyList, y: b::MyOtherList) { if (a::len(&x) + b::len(&y) == 1) () else abort 1 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/spec_inlining.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/spec_inlining.exp index bbd7712771c..d735bccb588 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/spec_inlining.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/spec_inlining.exp @@ -54,7 +54,7 @@ module 0x42::Test { predicate(v) } public fun test_apply(x: u64) { - let r1 = apply(x, |arg0| __lambda__1__test_apply(arg0)); + let r1 = apply(x, |arg0| lambda__1__test_apply(arg0)); /* spec { assert r1; @@ -62,7 +62,7 @@ module 0x42::Test { */ ; if (r1) () else abort 1; - let r2 = apply(x, |arg0| __lambda__2__test_apply(arg0)); + let r2 = apply(x, |arg0| lambda__2__test_apply(arg0)); /* spec { assert r2; @@ -71,10 +71,10 @@ module 0x42::Test { ; if (r2) () else abort 2; } - fun __lambda__1__test_apply(v: u64): bool { + fun lambda__1__test_apply(v: u64): bool { v >= 0 } - fun __lambda__2__test_apply(v: u64): bool { + fun lambda__2__test_apply(v: u64): bool { v != 0 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unnecessary_numerical_extreme_comparisons_warn.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unnecessary_numerical_extreme_comparisons_warn.exp index 16ce034facf..8445fb0c3b9 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unnecessary_numerical_extreme_comparisons_warn.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unnecessary_numerical_extreme_comparisons_warn.exp @@ -169,13 +169,14 @@ module 0xc0ffee::m { } public fun test5(x: u8): bool { - apply(|arg0| __lambda__1__test5(arg0), x) + apply(|arg0| lambda__1__test5(arg0), x) } - fun __lambda__1__test5(x: u8): bool { + fun lambda__1__test5(x: u8): bool { x > 255u8 } } module 0xc0ffee::no_warn { + #[lint::skip] public fun test(x: u8) { if (x < 0u8) abort 1; } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unused_lambda_param.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unused_lambda_param.exp index a218176e6fe..c06c57a1e9c 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unused_lambda_param.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/inline-parity/unused_lambda_param.exp @@ -35,22 +35,22 @@ module 0xc0ffee::m { f(p) } fun unused_lambda() { - test(0, |arg0| __lambda__1__unused_lambda(arg0)); + test(0, |arg0| lambda__1__unused_lambda(arg0)); } fun unused_lambda_suppressed1() { - test(0, |arg0| __lambda__1__unused_lambda_suppressed1(arg0)); + test(0, |arg0| lambda__1__unused_lambda_suppressed1(arg0)); } fun unused_lambda_suppressed2() { - test(0, |arg0| __lambda__1__unused_lambda_suppressed2(arg0)); + test(0, |arg0| lambda__1__unused_lambda_suppressed2(arg0)); } - fun __lambda__1__unused_lambda(x: u64): u64 { + fun lambda__1__unused_lambda(x: u64): u64 { 1 } - fun __lambda__1__unused_lambda_suppressed1(_x: u64): u64 { + fun lambda__1__unused_lambda_suppressed1(_x: u64): u64 { 1 } - fun __lambda__1__unused_lambda_suppressed2(param$0: u64): u64 { - let _ = param$0; + fun lambda__1__unused_lambda_suppressed2(param_0: u64): u64 { + let _ = param_0; 1 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/multi_return.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/multi_return.exp index 7f2d46803b5..8f3c411b85a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/multi_return.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/multi_return.exp @@ -1,13 +1,13 @@ // -- Model dump before first bytecode pipeline module 0x77::m { - private fun f(s: |(&u64, bool)|(bool, &u64)): (bool, &u64) { + private fun f(s: |&u64, bool|(bool, &u64)): (bool, &u64) { (s)(Borrow(Immutable)(1), false) } } // end 0x77::m // -- Sourcified model before first bytecode pipeline module 0x77::m { - fun f(s: |(&u64, bool)|(bool, &u64)): (bool, &u64) { + fun f(s: |&u64, bool|(bool, &u64)): (bool, &u64) { s(&1, false) } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.exp index 34746ac68f9..fef2478a828 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.exp @@ -10,7 +10,7 @@ error: lambda expression has invalid type `|&&u64|(&&u64, &&u64)` (reference to 6 │ │ }; │ ╰─────────^ -error: lambda expression has invalid type `|(&&u64, u64)|&&u64` (reference to a reference is disallowed) +error: lambda expression has invalid type `|&&u64, u64|&&u64` (reference to a reference is disallowed) ┌─ tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.move:10:17 │ 10 │ let f = |x, y| { @@ -21,7 +21,7 @@ error: lambda expression has invalid type `|(&&u64, u64)|&&u64` (reference to a 14 │ │ }; │ ╰─────────^ -error: lambda expression has invalid type `|(&&&&&&u64, &&&u64)|u64` (reference to a reference is disallowed) +error: lambda expression has invalid type `|&&&&&&u64, &&&u64|u64` (reference to a reference is disallowed) ┌─ tests/checking-lang-v2.2/lambda/ref_to_ref_inferred.move:18:17 │ 18 │ let f = |x, y| { diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp new file mode 100644 index 00000000000..67a2a4ef1fe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp @@ -0,0 +1,15 @@ + +Diagnostics: +error: script function `main` cannot be used in Move code + ┌─ tests/checking-lang-v2.2/lambda/script_uses_itself.move:2:9 + │ +2 │ fun main() { + │ ^^^^ +3 │ let _f: || has drop = main; + │ ---- used here +4 │ let _g: || has drop = || main(); + │ ------ used here +5 │ (main)(); + │ ---- used here +6 │ main(); + │ ------ used here diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move new file mode 100644 index 00000000000..4b1ae54904b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move @@ -0,0 +1,8 @@ +script { + fun main() { + let _f: || has drop = main; + let _g: || has drop = || main(); + (main)(); + main(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/sort.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/sort.exp index bee46be95a0..86e2d7f438a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/sort.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/sort.exp @@ -1,13 +1,13 @@ // -- Model dump before first bytecode pipeline module 0x42::sort { use std::vector; - public fun sort(arr: &mut vector,a_less_b: |(T, T)|bool) { + public fun sort(arr: &mut vector,a_less_b: |T, T|bool) { { let n: u64 = vector::length(Freeze(false)(arr)); sort::sort_recursive(arr, 0, Sub(n, 1), a_less_b) } } - public fun sort_recursive(arr: &mut vector,low: u64,high: u64,a_less_b: |(T, T)|bool) { + public fun sort_recursive(arr: &mut vector,low: u64,high: u64,a_less_b: |T, T|bool) { if Lt(low, high) { { let pi: u64 = Add(low, Div(high, 2)); @@ -24,11 +24,12 @@ module 0x42::sort { // -- Sourcified model before first bytecode pipeline module 0x42::sort { - public fun sort(arr: &mut vector, a_less_b: |(T, T)|bool) { + use std::vector; + public fun sort(arr: &mut vector, a_less_b: |T, T|bool) { let n = 0x1::vector::length(/*freeze*/arr); sort_recursive(arr, 0, n - 1, a_less_b) } - public fun sort_recursive(arr: &mut vector, low: u64, high: u64, a_less_b: |(T, T)|bool) { + public fun sort_recursive(arr: &mut vector, low: u64, high: u64, a_less_b: |T, T|bool) { if (low < high) { let pi = low + high / 2; sort_recursive(arr, low, pi - 1, a_less_b); diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/doable_func.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/doable_func.exp index 6ae3b13d39f..88979f55c5f 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/doable_func.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/doable_func.exp @@ -79,7 +79,7 @@ module 0x42::test { } else { if Eq(key, 11) { { - let g: |(u64, u64)|u64 = closure#0mod3::multiply(); + let g: |u64, u64|u64 = closure#0mod3::multiply(); closure#1test::__lambda__2__choose_function1(g) } } else { @@ -96,7 +96,7 @@ module 0x42::test { } } else { { - let i: |(u64, u64)|u64 = closure#0test::__lambda__5__choose_function1(); + let i: |u64, u64|u64 = closure#0test::__lambda__5__choose_function1(); closure#1test::__lambda__6__choose_function1(i) } } @@ -162,7 +162,7 @@ module 0x42::test { private fun __lambda__1__choose_function1(x: u64,y: u64,z: u64): u64 { test::multiply3(Add(x, 1), y, z) } - private fun __lambda__2__choose_function1(g: |(u64, u64)|u64,x: u64): u64 { + private fun __lambda__2__choose_function1(g: |u64, u64|u64,x: u64): u64 { (g)(11, x) } private fun __lambda__3__choose_function1(h: |u64|u64,x: u64): u64 { @@ -177,7 +177,7 @@ module 0x42::test { mod3::multiply(x, Add(q, 1)) } } - private fun __lambda__6__choose_function1(i: |(u64, u64)|u64,x: u64): u64 { + private fun __lambda__6__choose_function1(i: |u64, u64|u64,x: u64): u64 { (i)(15, x) } } // end 0x42::test @@ -223,22 +223,22 @@ module 0x42::test { } else if (key == 5) |arg0| multiply3(3, 2, arg0) else if (key == 6) |arg0| mod3::multiply(7, arg0) else if (key == 7) |arg0| multiply3(4, 2, arg0) else if (key == 8) |arg0| multiply3(3, 3, arg0) else if (key == 9) { let x = 2; let y = 5; - |arg0| __lambda__1__choose_function1(x, y, arg0) + |arg0| lambda__1__choose_function1(x, y, arg0) } else if (key == 10) { let z = 11; |arg0| mod4::alt_multiply(z, arg0) } else if (key == 11) { - let g = |(arg0,arg1)| mod3::multiply(arg0, arg1); - |arg0| __lambda__2__choose_function1(g, arg0) + let g = |arg0,arg1| mod3::multiply(arg0, arg1); + |arg0| lambda__2__choose_function1(g, arg0) } else if (key == 12) { let h = |arg0| mod3::multiply(12, arg0); - |arg0| __lambda__3__choose_function1(h, arg0) + |arg0| lambda__3__choose_function1(h, arg0) } else if (key == 14) { let i = |arg0| multiply3(2, 2, arg0); - |arg0| __lambda__4__choose_function1(i, arg0) + |arg0| lambda__4__choose_function1(i, arg0) } else { - let i = |(arg0,arg1)| __lambda__5__choose_function1(arg0, arg1); - |arg0| __lambda__6__choose_function1(i, arg0) + let i = |arg0,arg1| lambda__5__choose_function1(arg0, arg1); + |arg0| lambda__6__choose_function1(i, arg0) }; f(x) } @@ -258,23 +258,23 @@ module 0x42::test { } else break; }; } - fun __lambda__1__choose_function1(x: u64, y: u64, z: u64): u64 { + fun lambda__1__choose_function1(x: u64, y: u64, z: u64): u64 { multiply3(x + 1, y, z) } - fun __lambda__2__choose_function1(g: |(u64, u64)|u64, x: u64): u64 { + fun lambda__2__choose_function1(g: |u64, u64|u64, x: u64): u64 { g(11, x) } - fun __lambda__3__choose_function1(h: |u64|u64, x: u64): u64 { + fun lambda__3__choose_function1(h: |u64|u64, x: u64): u64 { h(x) } - fun __lambda__4__choose_function1(i: |u64|u64, z: u64): u64 { + fun lambda__4__choose_function1(i: |u64|u64, z: u64): u64 { i(z) } - fun __lambda__5__choose_function1(x: u64, y: u64): u64 { + fun lambda__5__choose_function1(x: u64, y: u64): u64 { let q = y - 1; mod3::multiply(x, q + 1) } - fun __lambda__6__choose_function1(i: |(u64, u64)|u64, x: u64): u64 { + fun lambda__6__choose_function1(i: |u64, u64|u64, x: u64): u64 { i(15, x) } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp index fee45d8f70a..a36a8411f9a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/generic_func.exp @@ -85,10 +85,11 @@ module 0x42::mod2 { exists>(addr) } public fun save_item(owner: &signer, f: F) { - move_to>(owner, Registry{func: f}); + move_to>(Registry{func: f}, owner); } } module 0x42::mod3 { + use std::signer; struct MyStruct1 has copy, store, key { x: u64, } @@ -103,11 +104,11 @@ module 0x42::mod3 { } public fun test_items(owner: signer, use_1: bool) { let struct1 = MyStruct1{x: 3}; - let f1 = |arg0| 0x42::mod2::item_exists(arg0); - let f2 = |arg0| 0x42::mod2::item_exists(arg0); + let f1: |address|bool has copy + drop + store = |arg0| 0x42::mod2::item_exists(arg0); + let f2: |address|bool has copy + drop + store = |arg0| 0x42::mod2::item_exists(arg0); let addr = 0x1::signer::address_of(&owner); 0x42::mod2::save_item(&owner, struct1); - move_to(&owner, struct1); + move_to(struct1, &owner); if (use_1) { 0x42::mod2::save_item<|address|bool has copy + drop + store>(&owner, f1); } else { diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/simplifier_func.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/simplifier_func.exp index 9aa4aa04f99..08af68a1dfc 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/simplifier_func.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/storable/simplifier_func.exp @@ -23,11 +23,11 @@ module 0x42::mod1 { x: u64, } public fun triple(x: u64): u64 { - let _f = |arg0| __lambda__1__triple(arg0); + let _f: |u64|u64 has drop = |arg0| lambda__1__triple(arg0); x * 3 } - fun __lambda__1__triple(x: u64): u64 { - let _t = S{x: 3}; + fun lambda__1__triple(x: u64): u64 { + let _v0 = S{x: 3}; x } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/unused_lambda_inference_ok.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/unused_lambda_inference_ok.exp index ed5560d613a..39e32517219 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/unused_lambda_inference_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/unused_lambda_inference_ok.exp @@ -14,9 +14,9 @@ module 0x8675309::M { // -- Sourcified model before first bytecode pipeline module 0x8675309::M { public fun f() { - let _x = |arg0| __lambda__1__f(arg0); + let _x: |u64|u64 has drop = |arg0| lambda__1__f(arg0); } - fun __lambda__1__f(i: u64): u64 { + fun lambda__1__f(i: u64): u64 { i + 1 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp new file mode 100644 index 00000000000..7aa9b6bd102 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp @@ -0,0 +1,31 @@ + +Diagnostics: +error: type `||u64 has drop` is missing required ability `copy` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:12:55 + │ +12 │ let b: vector<||u64 has drop + copy> = vector[a]; + │ ^ + +error: expected `vector<||u64 has drop>` but found a value of type `vector<||u64 has copy + drop>` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:33:9 + │ +33 │ v[0] = a; + │ ^ + +error: type `||u64 has drop` is missing required ability `copy` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:55:28 + │ +55 │ replace(&mut v[0], a); + │ ^ + +error: expected `vector<||u64 has copy + drop>` but found a value of type `vector<||u64 has drop>` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:66:9 + │ +66 │ v[0] = a; + │ ^ + +error: cannot pass `&mut ||u64 has drop` to a function which expects argument of type `&mut ||u64 has copy + drop` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:80:22 + │ +80 │ swap(&mut a, &mut b); + │ ^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move new file mode 100644 index 00000000000..424c6c2baf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move @@ -0,0 +1,82 @@ +module 0xc0ffee::m { + struct NoCopy has drop; + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: vector<||u64 has drop + copy> = vector[a]; + (b[0])(); + (b[0])(); + } +} + +module 0xc0ffee::n { + struct NoCopy has drop; + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: ||u64 has copy + drop = || 42; + + let v = vector[b]; + (v[0])(); + v[0] = a; + } +} + +module 0xc0ffee::o { + struct NoCopy has drop; + + fun replace(ref: &mut T, new: T): T { + abort 0 + } + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: ||u64 has copy + drop = || 42; + + let v = vector[b]; + replace(&mut v[0], a); + } +} + +module 0xc0ffee::p { + public fun foo() { + let a: ||u64 has copy + drop = || 1; + + let b: ||u64 has drop = || 42; + + let v = vector[b]; + v[0] = a; + v[0](); + } +} + +module 0xc0ffee::q { + fun swap(left: &mut T, right: &mut T) { + abort 0 + } + + public fun foo() { + let a: ||u64 has copy + drop = || 1; + let b: ||u64 has drop = || 42; + + swap(&mut a, &mut b); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp new file mode 100644 index 00000000000..eb7031e3a8c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp @@ -0,0 +1,43 @@ + +Diagnostics: +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:2:19 + │ +2 │ fun caller(f: ||u64 has key): u64 { + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:7:16 + │ +7 │ let f: ||u64 has key = || 1; + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:12:16 + │ +12 │ let f: ||u64 has key = || 1; + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:20:18 + │ +20 │ fun apply(f: ||S has key): S { + │ ^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:26:16 + │ +26 │ let f: ||S has key = || s; + │ ^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:38:17 + │ +38 │ let f2: || u64 has copy + key = || 2; + │ ^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:39:17 + │ +39 │ let f3: || u64 has copy + key = || 3; + │ ^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move new file mode 100644 index 00000000000..e1e1b1407dd --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move @@ -0,0 +1,43 @@ +module 0xc0ffee::m { + fun caller(f: ||u64 has key): u64 { + f() + } + + public fun test1(): u64 { + let f: ||u64 has key = || 1; + f() + } + + public fun test2(): u64 { + let f: ||u64 has key = || 1; + caller(f) + } + + struct S has key { + i: u64, + } + + fun apply(f: ||S has key): S { + f() + } + + public fun test3(): S { + let s = S { i: 1 }; + let f: ||S has key = || s; + apply(f) + } +} + +module 0xc0ffee::n { + fun wrap(x: T, y: T, z: T): vector { + vector[x, y, z] + } + + public fun test(): vector<||u64 has copy> { + let f1: || u64 has copy = || 1; + let f2: || u64 has copy + key = || 2; + let f3: || u64 has copy + key = || 3; + let v: vector<||u64 has copy> = wrap<||u64 has copy>(f2, f1, f3); + v + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.exp new file mode 100644 index 00000000000..f2b097b333a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.exp @@ -0,0 +1,23 @@ + +Diagnostics: +warning: structs/enums with visibility modifier are only supported at version 2.4-unstable or later + ┌─ tests/checking-lang-v2.2/struct_visibility_warning.move:1:1 + │ +1 │ ╭ module 0xc0ffee::m { +2 │ │ public struct S { f: T } +3 │ │ } + │ ╰─^ + +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct S { + f: T, + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + struct S { + f: T, + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.move new file mode 100644 index 00000000000..75fb38143fb --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/struct_visibility_warning.move @@ -0,0 +1,3 @@ +module 0xc0ffee::m { + public struct S { f: T } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_err.exp deleted file mode 100644 index 11b6785e5d5..00000000000 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_err.exp +++ /dev/null @@ -1,43 +0,0 @@ - -Diagnostics: -error: invalid access specifier - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:6:20 - │ -6 │ fun f1() reads undef { - │ ^^^^^^ - -error: undeclared module `undef` - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:9:20 - │ -9 │ fun f2() reads 0x42::undef::* { - │ ^^^^^^^^^^^^^^^ - -error: invalid access specifier: a wildcard cannot be followed by a non-wildcard name component - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:12:20 - │ -12 │ fun f3() reads 0x42::*::S { - │ ^^^^^^^^^^^ - -error: undeclared `y` - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:18:32 - │ -18 │ fun f5(x: address) reads *(y) { - │ ^ - -error: undeclared `y` - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:21:48 - │ -21 │ fun f6(x: address) reads *(make_up_address(y)) { - │ ^ - -error: cannot pass `u64` to a function which expects argument of type `address` - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:24:27 - │ -24 │ fun f7(x: u64) reads *(make_up_address_wrong(x)) { - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: no function named `undefined` found - ┌─ tests/checking-lang-v2.3/access_specifiers/access_err.move:27:27 - │ -27 │ fun f8(x: u64) reads *(undefined(x)) { - │ ^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.exp new file mode 100644 index 00000000000..31c96e658e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.exp @@ -0,0 +1,9 @@ + +Diagnostics: +error: cannot select field `x` since it has different types in variants of enum `Wrapper2` + ┌─ tests/checking-lang-v2.4/borrow_field.move:18:24 + │ +18 │ let x_0 = &mut x.x; + │ ^ + │ + = field `x` has type `u8` in variant `V2` and type `u64` in variant `V1` diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.move new file mode 100644 index 00000000000..2047eead5a7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/borrow_field.move @@ -0,0 +1,27 @@ +module 0xc0ffee::n { + enum Wrapper has drop { + V1(u64, u64), + V2(u8), + } + + enum Wrapper2 has drop { + V1 {x: u64, y: u64}, + V2 {z: u8, x: u8}, + } + + fun make(x: u64): Wrapper2 { + Wrapper2::V1 {x: x, y: x + 1} + } + + fun test_1() { + let x = make(22); + let x_0 = &mut x.x; + let x_1 = &mut x.y; + foo(x_0, x_1); + } + + fun foo(_x: &mut u64, _y: &mut u64) { + + } + +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.exp new file mode 100644 index 00000000000..c3a08c0b97b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.exp @@ -0,0 +1,464 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + enum Wrapper { + V1 { + 0: u64, + 1: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + pack m::Wrapper::V1(x, Add(x, 1)) + } +} // end 0xc0ffee::m +module 0xc0ffee::n { + use 0xc0ffee::m; // resolved as: 0xc0ffee::m + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun foo(_x: &mut u64,_y: &mut u64) { + Tuple() + } + private fun test_1() { + { + let x: m::Wrapper = m::make(22); + { + let x_0: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x)); + { + let x_1: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.1(x)); + n::foo(x_0, x_1); + Tuple() + } + } + } + } + private fun test_2() { + { + let x: m::Wrapper = m::make(22); + { + let x_0: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x)); + { + let x_1: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.1(x)); + x_0 = 23; + x_1 = 24; + Tuple() + } + } + } + } + private fun test_match() { + { + let x: m::Wrapper = m::make(22); + match (Borrow(Mutable)(x)) { + m::Wrapper::V2{ 0: _ } => { + Tuple() + } + m::Wrapper::V1{ 0: x_0, 1: x_1 } => { + n::foo(x_0, x_1); + Tuple() + } + } + + } + } + private fun test_no_err() { + { + let x: m::Wrapper = m::make(22); + select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x) = 23; + select_variants m::Wrapper.V1.1(x) = 24; + Tuple() + } + } +} // end 0xc0ffee::n + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + enum Wrapper has drop { + V1 { + 0: u64, + 1: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + Wrapper::V1(x, x + 1) + } +} +module 0xc0ffee::n { + use 0xc0ffee::m; + use 0xc0ffee::m; + fun foo(_x: &mut u64, _y: &mut u64) { + } + fun test_1() { + let x = m::make(22); + let x_0 = &mut x.0; + let x_1 = &mut x.1; + foo(x_0, x_1); + } + fun test_2() { + let x = m::make(22); + let x_0 = &mut x.0; + let x_1 = &mut x.1; + *x_0 = 23; + *x_1 = 24; + } + fun test_match() { + let x = m::make(22); + match (&mut x) { + m::Wrapper::V2(_) => (), + m::Wrapper::V1(x_0, x_1) => { + foo(x_0, x_1); + }, + } + } + fun test_no_err() { + let x = m::make(22); + x.0 = 23; + x.1 = 24; + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make($t0: u64): 0xc0ffee::m::Wrapper { + var $t1: 0xc0ffee::m::Wrapper + var $t2: u64 + var $t3: u64 + var $t4: u64 + var $t5: u64 + 0: $t2 := infer($t0) + 1: $t4 := infer($t0) + 2: $t5 := 1 + 3: $t3 := +($t4, $t5) + 4: $t1 := pack_variant 0xc0ffee::m::Wrapper::V1($t2, $t3) + 5: return $t1 +} + + +[variant baseline] +fun n::foo($t0: &mut u64, $t1: &mut u64) { + 0: return () +} + + +[variant baseline] +fun n::test_1() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut 0xc0ffee::m::Wrapper + var $t4: &mut u64 + var $t5: &mut 0xc0ffee::m::Wrapper + var $t6: &mut u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t3 := borrow_local($t0) + 3: $t2 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t3) + 4: $t5 := borrow_local($t0) + 5: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t5) + 6: $t6 := infer($t2) + 7: n::foo($t6, $t4) + 8: return () +} + + +[variant baseline] +fun n::test_2() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut 0xc0ffee::m::Wrapper + var $t4: &mut u64 + var $t5: &mut 0xc0ffee::m::Wrapper + var $t6: u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t3 := borrow_local($t0) + 3: $t2 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t3) + 4: $t5 := borrow_local($t0) + 5: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t5) + 6: $t6 := 23 + 7: write_ref($t2, $t6) + 8: $t7 := 24 + 9: write_ref($t4, $t7) + 10: return () +} + + +[variant baseline] +fun n::test_match() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut 0xc0ffee::m::Wrapper + var $t3: bool + var $t4: &mut u64 + var $t5: &mut u64 + var $t6: &mut u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t2 := borrow_local($t0) + 3: $t3 := test_variant 0xc0ffee::m::Wrapper::V2($t2) + 4: if ($t3) goto 5 else goto 7 + 5: label L2 + 6: goto 19 + 7: label L1 + 8: $t3 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 9: if ($t3) goto 10 else goto 16 + 10: label L4 + 11: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.0($t2) + 12: $t5 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t2) + 13: $t6 := infer($t4) + 14: n::foo($t6, $t5) + 15: goto 19 + 16: label L3 + 17: $t7 := 14566554180833181697 + 18: abort($t7) + 19: label L0 + 20: return () +} + + +[variant baseline] +fun n::test_no_err() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: u64 + var $t3: &mut u64 + var $t4: &mut 0xc0ffee::m::Wrapper + var $t5: u64 + var $t6: &mut u64 + var $t7: &mut 0xc0ffee::m::Wrapper + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t2 := 23 + 3: $t4 := borrow_local($t0) + 4: $t3 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t4) + 5: write_ref($t3, $t2) + 6: $t5 := 24 + 7: $t7 := borrow_local($t0) + 8: $t6 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t7) + 9: write_ref($t6, $t5) + 10: return () +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + enum Wrapper { + V1 { + 0: u64, + 1: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + pack m::Wrapper::V1(x, Add(x, 1)) + } +} // end 0xc0ffee::m +module 0xc0ffee::n { + use 0xc0ffee::m; // resolved as: 0xc0ffee::m + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun foo(_x: &mut u64,_y: &mut u64) { + Tuple() + } + private fun test_1() { + { + let x: m::Wrapper = m::make(22); + { + let x_0: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x)); + { + let x_1: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.1(x)); + n::foo(x_0, x_1); + Tuple() + } + } + } + } + private fun test_2() { + { + let x: m::Wrapper = m::make(22); + { + let x_0: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x)); + { + let x_1: &mut u64 = Borrow(Mutable)(select_variants m::Wrapper.V1.1(x)); + x_0 = 23; + x_1 = 24; + Tuple() + } + } + } + } + private fun test_match() { + { + let x: m::Wrapper = m::make(22); + match (Borrow(Mutable)(x)) { + m::Wrapper::V2{ 0: _ } => { + Tuple() + } + m::Wrapper::V1{ 0: x_0, 1: x_1 } => { + n::foo(x_0, x_1); + Tuple() + } + } + + } + } + private fun test_no_err() { + { + let x: m::Wrapper = m::make(22); + select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x) = 23; + select_variants m::Wrapper.V1.1(x) = 24; + Tuple() + } + } +} // end 0xc0ffee::n + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make($t0: u64): 0xc0ffee::m::Wrapper { + var $t1: 0xc0ffee::m::Wrapper + var $t2: u64 + var $t3: u64 + var $t4: u64 + var $t5: u64 + 0: $t2 := infer($t0) + 1: $t4 := infer($t0) + 2: $t5 := 1 + 3: $t3 := +($t4, $t5) + 4: $t1 := pack_variant 0xc0ffee::m::Wrapper::V1($t2, $t3) + 5: return $t1 +} + + +[variant baseline] +fun n::foo($t0: &mut u64, $t1: &mut u64) { + 0: return () +} + + +[variant baseline] +fun n::test_1() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut 0xc0ffee::m::Wrapper + var $t4: &mut u64 + var $t5: &mut 0xc0ffee::m::Wrapper + var $t6: &mut u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t3 := borrow_local($t0) + 3: $t2 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t3) + 4: $t5 := borrow_local($t0) + 5: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t5) + 6: $t6 := infer($t2) + 7: n::foo($t6, $t4) + 8: return () +} + + +[variant baseline] +fun n::test_2() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut 0xc0ffee::m::Wrapper + var $t4: &mut u64 + var $t5: &mut 0xc0ffee::m::Wrapper + var $t6: u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t3 := borrow_local($t0) + 3: $t2 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t3) + 4: $t5 := borrow_local($t0) + 5: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t5) + 6: $t6 := 23 + 7: write_ref($t2, $t6) + 8: $t7 := 24 + 9: write_ref($t4, $t7) + 10: return () +} + + +[variant baseline] +fun n::test_match() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: &mut 0xc0ffee::m::Wrapper + var $t3: bool + var $t4: &mut u64 + var $t5: &mut u64 + var $t6: &mut u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t2 := borrow_local($t0) + 3: $t3 := test_variant 0xc0ffee::m::Wrapper::V2($t2) + 4: if ($t3) goto 5 else goto 7 + 5: label L2 + 6: goto 19 + 7: label L1 + 8: $t3 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 9: if ($t3) goto 10 else goto 16 + 10: label L4 + 11: $t4 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.0($t2) + 12: $t5 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t2) + 13: $t6 := infer($t4) + 14: n::foo($t6, $t5) + 15: goto 19 + 16: label L3 + 17: $t7 := 14566554180833181697 + 18: abort($t7) + 19: label L0 + 20: return () +} + + +[variant baseline] +fun n::test_no_err() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: u64 + var $t3: &mut u64 + var $t4: &mut 0xc0ffee::m::Wrapper + var $t5: u64 + var $t6: &mut u64 + var $t7: &mut 0xc0ffee::m::Wrapper + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t2 := 23 + 3: $t4 := borrow_local($t0) + 4: $t3 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t4) + 5: write_ref($t3, $t2) + 6: $t5 := 24 + 7: $t7 := borrow_local($t0) + 8: $t6 := borrow_variant_field<0xc0ffee::m::Wrapper::V1>.1($t7) + 9: write_ref($t6, $t5) + 10: return () +} + + +Diagnostics: +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_borrow_field_err.move:16:9 + │ +16 │ fun test_1() { + │ ^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_borrow_field_err.move:41:9 + │ +41 │ fun test_match() { + │ ^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.move new file mode 100644 index 00000000000..3381ae299fe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_borrow_field_err.move @@ -0,0 +1,53 @@ +module 0xc0ffee::m { + public enum Wrapper has drop { + V1(u64, u64), + V2(u64), + } + + public fun make(x: u64): Wrapper { + Wrapper::V1(x, x + 1) + } +} + +module 0xc0ffee::n { + use 0xc0ffee::m; + use 0xc0ffee::m::Wrapper; + + fun test_1() { + let x = m::make(22); + let x_0 = &mut x.0; + let x_1 = &mut x.1; + foo(x_0, x_1); + } + + fun foo(_x: &mut u64, _y: &mut u64) { + + } + + fun test_2() { + let x = m::make(22); + let x_0 = &mut x.0; + let x_1 = &mut x.1; + *x_0 = 23; + *x_1 = 24; + } + + fun test_no_err() { + let x = m::make(22); + x.0 = 23; + x.1 = 24; + } + + fun test_match() { + let x = m::make(22); + match (&mut x) { + Wrapper::V2(_) => { + + } + Wrapper::V1(x_0, x_1) => { + foo(x_0, x_1); + } + } + } + +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.exp new file mode 100644 index 00000000000..b193b281c89 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: Invalid operation: access of the field `0` on enum type `m::Wrapper` can only be done within the defining module `0xc0ffee::m` or friend modules + ┌─ tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.move:15:9 + │ +15 │ fun test() { + │ ^^^^ +16 │ let x = m::make(22); +17 │ assert!(x.0 == 22, 1); + │ --- accessed here diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.move new file mode 100644 index 00000000000..d2f32b5c586 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_friend_err.move @@ -0,0 +1,19 @@ +module 0xc0ffee::m { + friend enum Wrapper has drop { + V1(u64), + V2(u64), + } + + public fun make(x: u64): Wrapper { + Wrapper::V1(x) + } +} + +module 0xc0ffee::n { + use 0xc0ffee::m; + + fun test() { + let x = m::make(22); + assert!(x.0 == 22, 1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.exp new file mode 100644 index 00000000000..c970306f85a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: Invalid operation: access of the field `0` on enum type `m::Wrapper` can only be done within the defining module `0xc0ffee::m` or modules in the same package + ┌─ tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.move:15:9 + │ +15 │ fun test() { + │ ^^^^ +16 │ let x = m::make(22); +17 │ assert!(x.0 == 22, 1); + │ --- accessed here diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.move new file mode 100644 index 00000000000..711352de946 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_enum_access_01_package_err.move @@ -0,0 +1,19 @@ +module 0xc0ffee::m { + package enum Wrapper has drop { + V1(u64), + V2(u64), + } + + public fun make(x: u64): Wrapper { + Wrapper::V1(x) + } +} + +module 0xc0ffee1::n { + use 0xc0ffee::m; + + fun test() { + let x = m::make(22); + assert!(x.0 == 22, 1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.exp new file mode 100644 index 00000000000..35054112539 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.exp @@ -0,0 +1,758 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct S { + x: u64, + } + struct S2 { + x: u64, + s: S, + } + enum Wrapper { + V1 { + 0: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + pack m::Wrapper::V1(x) + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct T { + x: u64, + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + use 0xc0ffee::m; // resolved as: 0xc0ffee::m + private fun test() { + { + let x: m::Wrapper = m::make(22); + if Eq(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x), 22) { + Tuple() + } else { + Abort(1) + }; + Tuple() + } + } +} // end 0xc0ffee::n +module 0xc0ffee::n2 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_pack() { + { + let _x: m::Wrapper = pack m::Wrapper::V1(22); + Tuple() + } + } +} // end 0xc0ffee::n2 +module 0xc0ffee::n3 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_unpack(w: m::Wrapper) { + { + let m::Wrapper::V1{ 0: _x } = w; + Tuple() + } + } +} // end 0xc0ffee::n3 +module 0xc0ffee::n4 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_select_variant(w: m::Wrapper): u64 { + select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(w) + } +} // end 0xc0ffee::n4 +module 0xc0ffee::n5 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_test_variant(w: m::Wrapper): bool { + test_variants m::Wrapper::V1(w) + } +} // end 0xc0ffee::n5 +module 0xc0ffee::n6 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_match(w: m::Wrapper): bool { + match (w) { + m::Wrapper::V1{ 0: _ } => { + true + } + m::Wrapper::V2{ 0: _ } => { + false + } + } + + } +} // end 0xc0ffee::n6 +module 0xc0ffee::n7 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + private fun test_pack_struct(): m::S { + pack m::S(22) + } +} // end 0xc0ffee::n7 +module 0xc0ffee::n8 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + private fun test_pack_struct(): m::S { + { + let (): (); + pack m::S(22) + } + } + private inline fun test_pack_struct_inline(): m::S { + pack m::S(22) + } +} // end 0xc0ffee::n8 +module 0xc0ffee::n9 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + use 0xc0ffee::m::{S2}; // resolved as: 0xc0ffee::m + private inline fun test_inline(x: ||) { + (x)() + } + private fun test_pack_unpack_struct_in_lambda() { + { + let (): (); + { + let (): (); + { + let x: m::S2 = pack m::S2(22, pack m::S(33)); + { + let m::S2{ x: _x, s: m::S{ x: _y } } = x; + Tuple() + } + } + } + } + } +} // end 0xc0ffee::n9 +module 0xc0ffee::n_friend { + use 0xc0ffee::m_friend::{T}; // resolved as: 0xc0ffee::m_friend + private fun test_pack_friend_struct(): m_friend::T { + pack m_friend::T(22) + } +} // end 0xc0ffee::n_friend + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + friend 0xc0ffee::n; + friend 0xc0ffee::n2; + friend 0xc0ffee::n3; + friend 0xc0ffee::n4; + friend 0xc0ffee::n5; + friend 0xc0ffee::n6; + friend 0xc0ffee::n7; + friend 0xc0ffee::n8; + friend 0xc0ffee::n9; + struct S { + x: u64, + } + struct S2 { + x: u64, + s: S, + } + enum Wrapper has drop { + V1 { + 0: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + Wrapper::V1(x) + } +} +module 0xc0ffee::m_friend { + friend 0xc0ffee::n_friend; + struct T { + x: u64, + } +} +module 0xc0ffee::n { + use 0xc0ffee::m; + fun test() { + let x = m::make(22); + if (x.0 == 22) () else abort 1; + } +} +module 0xc0ffee::n2 { + use 0xc0ffee::m; + fun test_pack() { + let _x = m::Wrapper::V1(22); + } +} +module 0xc0ffee::n3 { + use 0xc0ffee::m; + fun test_unpack(w: m::Wrapper) { + let m::Wrapper::V1(_x) = w; + } +} +module 0xc0ffee::n4 { + use 0xc0ffee::m; + fun test_select_variant(w: m::Wrapper): u64 { + w.0 + } +} +module 0xc0ffee::n5 { + use 0xc0ffee::m; + fun test_test_variant(w: m::Wrapper): bool { + w is V1 + } +} +module 0xc0ffee::n6 { + use 0xc0ffee::m; + fun test_match(w: m::Wrapper): bool { + match (w) { + m::Wrapper::V1(_) => true, + m::Wrapper::V2(_) => false, + } + } +} +module 0xc0ffee::n7 { + use 0xc0ffee::m; + fun test_pack_struct(): m::S { + m::S{x: 22} + } +} +module 0xc0ffee::n8 { + use 0xc0ffee::m; + fun test_pack_struct(): m::S { + let (); + m::S{x: 22} + } + inline fun test_pack_struct_inline(): m::S { + m::S{x: 22} + } +} +module 0xc0ffee::n9 { + use 0xc0ffee::m; + use 0xc0ffee::m; + inline fun test_inline(x: ||) { + x() + } + fun test_pack_unpack_struct_in_lambda() { + let (); + let (); + let x = m::S2{x: 22, s: m::S{x: 33}}; + let m::S2{x: _x, s: m::S{x: _y}} = x; + } +} +module 0xc0ffee::n_friend { + use 0xc0ffee::m_friend; + fun test_pack_friend_struct(): m_friend::T { + m_friend::T{x: 22} + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make($t0: u64): 0xc0ffee::m::Wrapper { + var $t1: 0xc0ffee::m::Wrapper + 0: $t1 := pack_variant 0xc0ffee::m::Wrapper::V1($t0) + 1: return $t1 +} + + +[variant baseline] +fun n::test() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: bool + var $t3: u64 + var $t4: &0xc0ffee::m::Wrapper + var $t5: &u64 + var $t6: u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t4 := borrow_local($t0) + 3: $t5 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t4) + 4: $t3 := read_ref($t5) + 5: $t6 := 22 + 6: $t2 := ==($t3, $t6) + 7: if ($t2) goto 8 else goto 10 + 8: label L0 + 9: goto 13 + 10: label L1 + 11: $t7 := 1 + 12: abort($t7) + 13: label L2 + 14: return () +} + + +[variant baseline] +fun n2::test_pack() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack_variant 0xc0ffee::m::Wrapper::V1($t1) + 2: return () +} + + +[variant baseline] +fun n3::test_unpack($t0: 0xc0ffee::m::Wrapper) { + var $t1: u64 + 0: $t1 := unpack_variant 0xc0ffee::m::Wrapper::V1($t0) + 1: return () +} + + +[variant baseline] +fun n4::test_select_variant($t0: 0xc0ffee::m::Wrapper): u64 { + var $t1: u64 + var $t2: &0xc0ffee::m::Wrapper + var $t3: &u64 + 0: $t2 := borrow_local($t0) + 1: $t3 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t2) + 2: $t1 := read_ref($t3) + 3: return $t1 +} + + +[variant baseline] +fun n5::test_test_variant($t0: 0xc0ffee::m::Wrapper): bool { + var $t1: bool + var $t2: &0xc0ffee::m::Wrapper + 0: $t2 := borrow_local($t0) + 1: $t1 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 2: return $t1 +} + + +[variant baseline] +fun n6::test_match($t0: 0xc0ffee::m::Wrapper): bool { + var $t1: bool + var $t2: &0xc0ffee::m::Wrapper + var $t3: bool + var $t4: u64 + var $t5: u64 + var $t6: u64 + 0: $t2 := borrow_local($t0) + 1: $t3 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 2: if ($t3) goto 3 else goto 7 + 3: label L2 + 4: $t4 := unpack_variant 0xc0ffee::m::Wrapper::V1($t0) + 5: $t1 := true + 6: goto 17 + 7: label L1 + 8: $t3 := test_variant 0xc0ffee::m::Wrapper::V2($t2) + 9: if ($t3) goto 10 else goto 14 + 10: label L4 + 11: $t5 := unpack_variant 0xc0ffee::m::Wrapper::V2($t0) + 12: $t1 := false + 13: goto 17 + 14: label L3 + 15: $t6 := 14566554180833181697 + 16: abort($t6) + 17: label L0 + 18: return $t1 +} + + +[variant baseline] +fun n7::test_pack_struct(): 0xc0ffee::m::S { + var $t0: 0xc0ffee::m::S + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m::S($t1) + 2: return $t0 +} + + +[variant baseline] +fun n8::test_pack_struct(): 0xc0ffee::m::S { + var $t0: 0xc0ffee::m::S + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m::S($t1) + 2: return $t0 +} + + +[variant baseline] +fun n9::test_pack_unpack_struct_in_lambda() { + var $t0: 0xc0ffee::m::S2 + var $t1: u64 + var $t2: 0xc0ffee::m::S + var $t3: u64 + var $t4: u64 + var $t5: u64 + var $t6: 0xc0ffee::m::S + 0: $t1 := 22 + 1: $t3 := 33 + 2: $t2 := pack 0xc0ffee::m::S($t3) + 3: $t0 := pack 0xc0ffee::m::S2($t1, $t2) + 4: ($t4, $t6) := unpack 0xc0ffee::m::S2($t0) + 5: $t5 := unpack 0xc0ffee::m::S($t6) + 6: return () +} + + +[variant baseline] +fun n_friend::test_pack_friend_struct(): 0xc0ffee::m_friend::T { + var $t0: 0xc0ffee::m_friend::T + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m_friend::T($t1) + 2: return $t0 +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + struct S { + x: u64, + } + struct S2 { + x: u64, + s: S, + } + enum Wrapper { + V1 { + 0: u64, + } + V2 { + 0: u64, + } + } + public fun make(x: u64): Wrapper { + pack m::Wrapper::V1(x) + } +} // end 0xc0ffee::m +module 0xc0ffee::m_friend { + struct T { + x: u64, + } +} // end 0xc0ffee::m_friend +module 0xc0ffee::n { + use 0xc0ffee::m; // resolved as: 0xc0ffee::m + private fun test() { + { + let x: m::Wrapper = m::make(22); + if Eq(select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(x), 22) { + Tuple() + } else { + Abort(1) + }; + Tuple() + } + } +} // end 0xc0ffee::n +module 0xc0ffee::n2 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_pack() { + { + let _x: m::Wrapper = pack m::Wrapper::V1(22); + Tuple() + } + } +} // end 0xc0ffee::n2 +module 0xc0ffee::n3 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_unpack(w: m::Wrapper) { + { + let m::Wrapper::V1{ 0: _x } = w; + Tuple() + } + } +} // end 0xc0ffee::n3 +module 0xc0ffee::n4 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_select_variant(w: m::Wrapper): u64 { + select_variants m::Wrapper.V1.0|m::Wrapper.V2.0(w) + } +} // end 0xc0ffee::n4 +module 0xc0ffee::n5 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_test_variant(w: m::Wrapper): bool { + test_variants m::Wrapper::V1(w) + } +} // end 0xc0ffee::n5 +module 0xc0ffee::n6 { + use 0xc0ffee::m::{Wrapper}; // resolved as: 0xc0ffee::m + private fun test_match(w: m::Wrapper): bool { + match (w) { + m::Wrapper::V1{ 0: _ } => { + true + } + m::Wrapper::V2{ 0: _ } => { + false + } + } + + } +} // end 0xc0ffee::n6 +module 0xc0ffee::n7 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + private fun test_pack_struct(): m::S { + pack m::S(22) + } +} // end 0xc0ffee::n7 +module 0xc0ffee::n8 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + private fun test_pack_struct(): m::S { + pack m::S(22) + } + private inline fun test_pack_struct_inline(): m::S { + pack m::S(22) + } +} // end 0xc0ffee::n8 +module 0xc0ffee::n9 { + use 0xc0ffee::m::{S}; // resolved as: 0xc0ffee::m + use 0xc0ffee::m::{S2}; // resolved as: 0xc0ffee::m + private inline fun test_inline(x: ||) { + (x)() + } + private fun test_pack_unpack_struct_in_lambda() { + { + let x: m::S2 = pack m::S2(22, pack m::S(33)); + { + let m::S2{ x: _x, s: m::S{ x: _y } } = x; + Tuple() + } + } + } +} // end 0xc0ffee::n9 +module 0xc0ffee::n_friend { + use 0xc0ffee::m_friend::{T}; // resolved as: 0xc0ffee::m_friend + private fun test_pack_friend_struct(): m_friend::T { + pack m_friend::T(22) + } +} // end 0xc0ffee::n_friend + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +public fun m::make($t0: u64): 0xc0ffee::m::Wrapper { + var $t1: 0xc0ffee::m::Wrapper + 0: $t1 := pack_variant 0xc0ffee::m::Wrapper::V1($t0) + 1: return $t1 +} + + +[variant baseline] +fun n::test() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + var $t2: bool + var $t3: u64 + var $t4: &0xc0ffee::m::Wrapper + var $t5: &u64 + var $t6: u64 + var $t7: u64 + 0: $t1 := 22 + 1: $t0 := m::make($t1) + 2: $t4 := borrow_local($t0) + 3: $t5 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t4) + 4: $t3 := read_ref($t5) + 5: $t6 := 22 + 6: $t2 := ==($t3, $t6) + 7: if ($t2) goto 8 else goto 10 + 8: label L0 + 9: goto 13 + 10: label L1 + 11: $t7 := 1 + 12: abort($t7) + 13: label L2 + 14: return () +} + + +[variant baseline] +fun n2::test_pack() { + var $t0: 0xc0ffee::m::Wrapper + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack_variant 0xc0ffee::m::Wrapper::V1($t1) + 2: return () +} + + +[variant baseline] +fun n3::test_unpack($t0: 0xc0ffee::m::Wrapper) { + var $t1: u64 + 0: $t1 := unpack_variant 0xc0ffee::m::Wrapper::V1($t0) + 1: return () +} + + +[variant baseline] +fun n4::test_select_variant($t0: 0xc0ffee::m::Wrapper): u64 { + var $t1: u64 + var $t2: &0xc0ffee::m::Wrapper + var $t3: &u64 + 0: $t2 := borrow_local($t0) + 1: $t3 := borrow_variant_field<0xc0ffee::m::Wrapper::V1|V2>.0($t2) + 2: $t1 := read_ref($t3) + 3: return $t1 +} + + +[variant baseline] +fun n5::test_test_variant($t0: 0xc0ffee::m::Wrapper): bool { + var $t1: bool + var $t2: &0xc0ffee::m::Wrapper + 0: $t2 := borrow_local($t0) + 1: $t1 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 2: return $t1 +} + + +[variant baseline] +fun n6::test_match($t0: 0xc0ffee::m::Wrapper): bool { + var $t1: bool + var $t2: &0xc0ffee::m::Wrapper + var $t3: bool + var $t4: u64 + var $t5: u64 + var $t6: u64 + 0: $t2 := borrow_local($t0) + 1: $t3 := test_variant 0xc0ffee::m::Wrapper::V1($t2) + 2: if ($t3) goto 3 else goto 7 + 3: label L2 + 4: $t4 := unpack_variant 0xc0ffee::m::Wrapper::V1($t0) + 5: $t1 := true + 6: goto 17 + 7: label L1 + 8: $t3 := test_variant 0xc0ffee::m::Wrapper::V2($t2) + 9: if ($t3) goto 10 else goto 14 + 10: label L4 + 11: $t5 := unpack_variant 0xc0ffee::m::Wrapper::V2($t0) + 12: $t1 := false + 13: goto 17 + 14: label L3 + 15: $t6 := 14566554180833181697 + 16: abort($t6) + 17: label L0 + 18: return $t1 +} + + +[variant baseline] +fun n7::test_pack_struct(): 0xc0ffee::m::S { + var $t0: 0xc0ffee::m::S + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m::S($t1) + 2: return $t0 +} + + +[variant baseline] +fun n8::test_pack_struct(): 0xc0ffee::m::S { + var $t0: 0xc0ffee::m::S + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m::S($t1) + 2: return $t0 +} + + +[variant baseline] +fun n9::test_pack_unpack_struct_in_lambda() { + var $t0: 0xc0ffee::m::S2 + var $t1: u64 + var $t2: 0xc0ffee::m::S + var $t3: u64 + var $t4: u64 + var $t5: u64 + var $t6: 0xc0ffee::m::S + 0: $t1 := 22 + 1: $t3 := 33 + 2: $t2 := pack 0xc0ffee::m::S($t3) + 3: $t0 := pack 0xc0ffee::m::S2($t1, $t2) + 4: ($t4, $t6) := unpack 0xc0ffee::m::S2($t0) + 5: $t5 := unpack 0xc0ffee::m::S($t6) + 6: return () +} + + +[variant baseline] +fun n_friend::test_pack_friend_struct(): 0xc0ffee::m_friend::T { + var $t0: 0xc0ffee::m_friend::T + var $t1: u64 + 0: $t1 := 22 + 1: $t0 := pack 0xc0ffee::m_friend::T($t1) + 2: return $t0 +} + + +Diagnostics: +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:35:9 + │ +35 │ fun test() { + │ ^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:44:9 + │ +44 │ fun test_pack() { + │ ^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:52:9 + │ +52 │ fun test_unpack(w: Wrapper) { + │ ^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:60:9 + │ +60 │ fun test_select_variant(w: Wrapper): u64 { + │ ^^^^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:68:9 + │ +68 │ fun test_test_variant(w: Wrapper): bool { + │ ^^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:76:9 + │ +76 │ fun test_match(w: Wrapper): bool { + │ ^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:87:9 + │ +87 │ fun test_pack_struct(): S { + │ ^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:95:9 + │ +95 │ fun test_pack_friend_struct(): T { + │ ^^^^^^^^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:107:9 + │ +107 │ fun test_pack_struct(): S { + │ ^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + +bug: compiler internal error: struct not defined + ┌─ tests/checking-lang-v2.4/cross_module_package_access_success.move:120:9 + │ +120 │ fun test_pack_unpack_struct_in_lambda() { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.move new file mode 100644 index 00000000000..32547880759 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/cross_module_package_access_success.move @@ -0,0 +1,123 @@ +module 0xc0ffee::m { + + package enum Wrapper has drop { + V1(u64), + V2(u64), + } + + public fun make(x: u64): Wrapper { + Wrapper::V1(x) + } + + public(package) struct S { + x: u64, + } + + package struct S2 { + x: u64, + s: S, + } + +} + +module 0xc0ffee::m_friend { + friend 0xc0ffee::n_friend; + + friend struct T { + x: u64, + } + +} + +module 0xc0ffee::n { + use 0xc0ffee::m; + + fun test() { + let x = m::make(22); + assert!(x.0 == 22, 1); + } +} + +module 0xc0ffee::n2 { + use 0xc0ffee::m::Wrapper; + + fun test_pack() { + let _x = Wrapper::V1(22); + } +} + +module 0xc0ffee::n3 { + use 0xc0ffee::m::Wrapper; + + fun test_unpack(w: Wrapper) { + let V1(_x) = w; + } +} + +module 0xc0ffee::n4 { + use 0xc0ffee::m::Wrapper; + + fun test_select_variant(w: Wrapper): u64 { + w.0 + } +} + +module 0xc0ffee::n5 { + use 0xc0ffee::m::Wrapper; + + fun test_test_variant(w: Wrapper): bool { + w is V1 + } +} + +module 0xc0ffee::n6 { + use 0xc0ffee::m::Wrapper; + + fun test_match(w: Wrapper): bool { + match (w) { + V1(_) => true, + V2(_) => false, + } + } +} + +module 0xc0ffee::n7 { + use 0xc0ffee::m::S; + + fun test_pack_struct(): S { + S { x: 22 } + } +} + +module 0xc0ffee::n_friend { + use 0xc0ffee::m_friend::T; + + fun test_pack_friend_struct(): T { + T { x: 22 } + } +} + +module 0xc0ffee::n8 { + use 0xc0ffee::m::S; + + inline fun test_pack_struct_inline(): S { + S { x: 22 } + } + + fun test_pack_struct(): S { + test_pack_struct_inline() + } +} + +module 0xc0ffee::n9 { + use 0xc0ffee::m::S; + use 0xc0ffee::m::S2; + + inline fun test_inline(x: ||) { + x() + } + + fun test_pack_unpack_struct_in_lambda() { + test_inline(|| {let x = S2 { x: 22, s: S { x: 33 } }; let S2 { x: _x, s: S { x: _y } } = x;} ) + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.exp new file mode 100644 index 00000000000..ec1dc7a1b3f --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.exp @@ -0,0 +1,7 @@ + +Diagnostics: +error: invalid character + ┌─ tests/checking-lang-v2.4/illegal_dollar_ident.move:7:20 + │ +7 │ public fun make$Wrapper(x: u64): Wrapper { + │ ^ Invalid character: `$` diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.move new file mode 100644 index 00000000000..8c84fb2ab80 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/illegal_dollar_ident.move @@ -0,0 +1,10 @@ +module 0xc0ffee::m { + public enum Wrapper has drop { + V1(u64, u64), + V2(u64), + } + + public fun make$Wrapper(x: u64): Wrapper { + Wrapper::V1(x, x + 1) + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.exp new file mode 100644 index 00000000000..19ebe1c9647 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.exp @@ -0,0 +1,25 @@ + +Diagnostics: +error: structs/enums with key ability cannot have public, package or friend visibility + ┌─ tests/checking-lang-v2.4/key_err.move:2:5 + │ +2 │ ╭ public enum Wrapper has key { +3 │ │ V1(u64, u64), +4 │ │ V2(u64), +5 │ │ } + │ ╰─────^ + +error: structs/enums with key ability cannot have public, package or friend visibility + ┌─ tests/checking-lang-v2.4/key_err.move:7:5 + │ + 7 │ ╭ package enum Wrapper2 has key { + 8 │ │ V1(u64, u64), + 9 │ │ V2(u64), +10 │ │ } + │ ╰─────^ + +error: structs/enums with key ability cannot have public, package or friend visibility + ┌─ tests/checking-lang-v2.4/key_err.move:16:5 + │ +16 │ friend struct Wrapper(u64, u64) has key; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.move new file mode 100644 index 00000000000..6b0dc1368a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/key_err.move @@ -0,0 +1,18 @@ +module 0xc0ffee::m { + public enum Wrapper has key { + V1(u64, u64), + V2(u64), + } + + package enum Wrapper2 has key { + V1(u64, u64), + V2(u64), + } + +} + +module 0xc0ffee::m_friend { + + friend struct Wrapper(u64, u64) has key; + +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.exp new file mode 100644 index 00000000000..511d96be22e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.exp @@ -0,0 +1,17 @@ + +Diagnostics: +error: Invalid operation: pack of `m::Inner` can only be done within the defining module `0xc0ffee::m` + ┌─ tests/checking-lang-v2.4/nest_err.move:24:9 + │ +24 │ fun test() { + │ ^^^^ +25 │ let x = Wrapper(Inner::V1(22, 23)); + │ ----------------- packed here + +error: Invalid operation: pack of `m::Inner2` can only be done within the defining module `0xc0ffee::m` or friend modules + ┌─ tests/checking-lang-v2.4/nest_err.move:28:9 + │ +28 │ fun test2() { + │ ^^^^^ +29 │ let x = Wrapper2(Inner2::V1(22, 23)); + │ ------------------ packed here diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.move new file mode 100644 index 00000000000..7a653d9b0ce --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.4/nest_err.move @@ -0,0 +1,32 @@ +module 0xc0ffee::m { + public struct Wrapper(Inner); + + enum Inner { + V1(u64, u64), + V2(u64), + } + + public struct Wrapper2(Inner2); + + friend enum Inner2 { + V1(u64, u64), + V2(u64), + } + +} + +module 0xc0ffee::m2 { + use 0xc0ffee::m::Wrapper; + use 0xc0ffee::m::Wrapper2; + use 0xc0ffee::m::Inner; + use 0xc0ffee::m::Inner2; + + fun test() { + let x = Wrapper(Inner::V1(22, 23)); + } + + fun test2() { + let x = Wrapper2(Inner2::V1(22, 23)); + } + +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp new file mode 100644 index 00000000000..cd49f667dd2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.exp @@ -0,0 +1,43 @@ + +Diagnostics: +error: invalid access specifier + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:6:20 + │ +6 │ fun f1() reads undef { + │ ^^^^^^ + +error: undeclared module `undef` + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:9:20 + │ +9 │ fun f2() reads 0x42::undef::* { + │ ^^^^^^^^^^^^^^^ + +error: invalid access specifier: a wildcard cannot be followed by a non-wildcard name component + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:12:20 + │ +12 │ fun f3() reads 0x42::*::S { + │ ^^^^^^^^^^^ + +error: undeclared `y` + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:18:32 + │ +18 │ fun f5(x: address) reads *(y) { + │ ^ + +error: undeclared `y` + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:21:48 + │ +21 │ fun f6(x: address) reads *(make_up_address(y)) { + │ ^ + +error: cannot pass `u64` to a function which expects argument of type `address` + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:24:27 + │ +24 │ fun f7(x: u64) reads *(make_up_address_wrong(x)) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: no function named `undefined` found + ┌─ tests/checking-lang-v2.5/access_specifiers/access_err.move:27:27 + │ +27 │ fun f8(x: u64) reads *(undefined(x)) { + │ ^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_err.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.move similarity index 100% rename from third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_err.move rename to third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_err.move diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_ok.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp similarity index 91% rename from third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_ok.exp rename to third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp index 7bd43a749bc..f4d87f0228d 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.exp @@ -91,12 +91,11 @@ module 0x42::m { struct S has store { } fun f10(x: u64) - reads *(m::make_up_address(x)) + reads *(make_up_address(x)) { } fun f11() - !reads *(0x42) - !reads *(0x43) + !reads *(0x42), *(0x43) { } fun f12() @@ -115,7 +114,7 @@ module 0x42::m { { } fun f5() - reads 0x42::* + reads 0x42::*::* { } fun f6() @@ -135,13 +134,11 @@ module 0x42::m { { } fun f_multiple() - reads R - writes T - writes S - reads G + reads G, R + writes S, T { } fun make_up_address(_x: u64): address { - 0x42 + @0x42 } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_ok.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.move similarity index 100% rename from third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/access_ok.move rename to third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/access_ok.move diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/acquires_list_generic.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.exp similarity index 100% rename from third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/acquires_list_generic.exp rename to third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.exp diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/acquires_list_generic.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.move similarity index 100% rename from third_party/move/move-compiler-v2/tests/checking-lang-v2.3/access_specifiers/acquires_list_generic.move rename to third_party/move/move-compiler-v2/tests/checking-lang-v2.5/access_specifiers/acquires_list_generic.move diff --git a/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp b/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp index 2e155371d09..ccbb4b13d8c 100644 --- a/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp +++ b/third_party/move/move-compiler-v2/tests/checking/abilities/v1/phantom_param_op_abilities.exp @@ -80,15 +80,15 @@ module 0x42::M { (copy x, x) } fun f5(s: &signer, x: HasKey) { - move_to>(s, x); + move_to>(x, s); } fun f6(): HasKey acquires HasKey { - move_from>(0x0) + move_from>(@0x0) } fun f7(): bool { - exists>(0x0) + exists>(@0x0) } fun f8(): RequireStore> { RequireStore>{a: HasStore{a: 1}} diff --git a/third_party/move/move-compiler-v2/tests/checking/attributes/aptos_stdlib_attributes2.exp b/third_party/move/move-compiler-v2/tests/checking/attributes/aptos_stdlib_attributes2.exp index 5f649ae1f0d..3703ebe2c8a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/attributes/aptos_stdlib_attributes2.exp +++ b/third_party/move/move-compiler-v2/tests/checking/attributes/aptos_stdlib_attributes2.exp @@ -18,6 +18,7 @@ module 0x1::M { // -- Sourcified model before first bytecode pipeline module 0x1::M { + #[testonly] fun bar() { } fun foo() { diff --git a/third_party/move/move-compiler-v2/tests/checking/attributes/attribute_placement.exp b/third_party/move/move-compiler-v2/tests/checking/attributes/attribute_placement.exp index 42f6462f75b..cb43cf59114 100644 --- a/third_party/move/move-compiler-v2/tests/checking/attributes/attribute_placement.exp +++ b/third_party/move/move-compiler-v2/tests/checking/attributes/attribute_placement.exp @@ -110,6 +110,7 @@ module _0 { // -- Sourcified model before first bytecode pipeline module 0x42::N { friend 0x42::M; + #[attr] public fun bar() { } } @@ -117,6 +118,7 @@ module 0x42::M { use 0x42::N; struct S { } + #[attr] public fun foo() { N::bar() } diff --git a/third_party/move/move-compiler-v2/tests/checking/dotdot/dotdot_valid.exp b/third_party/move/move-compiler-v2/tests/checking/dotdot/dotdot_valid.exp index c633c8f0bed..84725c039ed 100644 --- a/third_party/move/move-compiler-v2/tests/checking/dotdot/dotdot_valid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/dotdot/dotdot_valid.exp @@ -350,44 +350,44 @@ module 0x42::test { 3: u64, } inline fun lambda_param(f: |S2|bool): bool { - let x = S2(true,S0{}); + let x = S2(true, S0{}); f(x) } fun nested1(x: S4) { - let S4{x: _x,y: _} = x; - let S4{x: _,y: _y} = x; - let S4{x: _,y: S3{x: _,y: _}} = x; - let S4{x: _,y: S3{x: _x,y: _}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; - let S4{x: _,y: S3{x: _,y: _y}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; + let S4{x: _x, y: _} = x; + let S4{x: _, y: _y} = x; + let S4{x: _, y: S3{x: _, y: _}} = x; + let S4{x: _, y: S3{x: _x, y: _}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; + let S4{x: _, y: S3{x: _, y: _y}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; } fun nested1_ref(x: &S4) { - let S4{x: _x,y: _} = x; - let S4{x: _,y: _y} = x; - let S4{x: _,y: S3{x: _,y: _}} = x; - let S4{x: _,y: S3{x: _x,y: _}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; - let S4{x: _,y: S3{x: _,y: _y}} = x; - let S4{x: _x2,y: S3{x: _x1,y: _}} = x; + let S4{x: _x, y: _} = x; + let S4{x: _, y: _y} = x; + let S4{x: _, y: S3{x: _, y: _}} = x; + let S4{x: _, y: S3{x: _x, y: _}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; + let S4{x: _, y: S3{x: _, y: _y}} = x; + let S4{x: _x2, y: S3{x: _x1, y: _}} = x; } fun nested2(x: S5) { - let S5(_,S1(_)) = x; + let S5(_, S1(_)) = x; } fun nested2_ref(x: &S5) { - let S5(_,S1(_)) = x; + let S5(_, S1(_)) = x; } fun nested3(x: S5>) { - let S5>(_,S4{x: _,y: _}) = x; + let S5>(_, S4{x: _, y: _}) = x; } fun nested3_ref(x: &S5>) { - let S5>(_,S4{x: _,y: _}) = x; + let S5>(_, S4{x: _, y: _}) = x; } fun nested4(x: S4) { - let S4{x: S1(_),y: _} = x; + let S4{x: S1(_), y: _} = x; } fun nested4_ref(x: &S4) { - let S4{x: S1(_),y: _} = x; + let S4{x: S1(_), y: _} = x; } fun simple_0(x: S0) { let S0{} = x; @@ -402,63 +402,63 @@ module 0x42::test { let S1(_) = x; } fun simple_2(x: S2) { - let S2(_,_) = x; - let S2(_x,_) = x; - let S2(_,_x) = x; - let S2(_,_) = x; - let S2(_,_) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; + let S2(_, _) = x; + let S2(_x, _) = x; + let S2(_, _x) = x; + let S2(_, _) = x; + let S2(_, _) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; } fun simple_2_ref(x: &S2) { - let S2(_,_) = x; - let S2(_x,_) = x; - let S2(_,_x) = x; - let S2(_,_) = x; - let S2(_,_) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; - let S2(_x,_y) = x; + let S2(_, _) = x; + let S2(_x, _) = x; + let S2(_, _x) = x; + let S2(_, _) = x; + let S2(_, _) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; + let S2(_x, _y) = x; } fun simple_3(x: S3) { - let S3{x: _,y: _} = x; - let S3{x: _x,y: _} = x; - let S3{x: _,y: _y} = x; + let S3{x: _, y: _} = x; + let S3{x: _x, y: _} = x; + let S3{x: _, y: _y} = x; } fun simple_3_ref(x: S3) { - let S3{x: _,y: _} = x; - let S3{x: _x,y: _} = x; - let S3{x: _,y: _y} = x; + let S3{x: _, y: _} = x; + let S3{x: _x, y: _} = x; + let S3{x: _, y: _y} = x; } fun simple_4(x: E1): u8 { match (x) { - E1::A(x,_) => x, + E1::A(x, _) => x, E1::B(x) => x, - E1::C{x: x,y: _} => x, + E1::C{x: x, y: _} => x, } } fun simple_4_ref(x: &E1): &u8 { match (x) { - E1::A(x,_) => x, + E1::A(x, _) => x, E1::B(x) => x, } } fun simple_5(x: E1): u8 { match (x) { - E1::A(_,y) => if (y) 1u8 else 0u8, + E1::A(_, y) => if (y) 1u8 else 0u8, E1::B(x) => x, - E1::C{x: _,y: S1(x)} => x, + E1::C{x: _, y: S1(x)} => x, } } fun simple_6(x: &S7) { - let S7(_w,_,_,_z) = x; - let S7(_w,_x,_y,_z) = x; + let S7(_w, _, _, _z) = x; + let S7(_w, _x, _y, _z) = x; } fun test_lambda_param(): bool { let (); - let x = S2(true,S0{}); - let (S2(x,_)) = (x); + let x = S2(true, S0{}); + let (S2(x, _)) = (x); x } } diff --git a/third_party/move/move-compiler-v2/tests/checking/dotdot/extra_dotdot.exp b/third_party/move/move-compiler-v2/tests/checking/dotdot/extra_dotdot.exp index 3c60e614935..42182e58475 100644 --- a/third_party/move/move-compiler-v2/tests/checking/dotdot/extra_dotdot.exp +++ b/third_party/move/move-compiler-v2/tests/checking/dotdot/extra_dotdot.exp @@ -40,9 +40,9 @@ module 0x42::test { 2: address, } fun extra_dotdot(x: S, y: T) { - let S(_x,_,_) = x; - let S(_,_,_) = x; - let S(_,_,_) = x; - let T{x: _,y: _,z: _} = y; + let S(_x, _, _) = x; + let S(_, _, _) = x; + let S(_, _, _) = x; + let T{x: _, y: _, z: _} = y; } } diff --git a/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp b/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp index c5fcc716650..e6a3c38f74b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp +++ b/third_party/move/move-compiler-v2/tests/checking/indexing/examples_book.exp @@ -33,10 +33,10 @@ module 0x1::m { fun f1() acquires R { - let x = borrow_global_mut(0x1); + let x = borrow_global_mut(@0x1); x.value = false; - if (borrow_global(0x1).value == false) () else abort 1; - borrow_global_mut(0x1).value = true; - if (borrow_global(0x1).value == true) () else abort 2; + if (borrow_global(@0x1).value == false) () else abort 1; + borrow_global_mut(@0x1).value = true; + if (borrow_global(@0x1).value == true) () else abort 2; } } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.exp index e71291477f5..4baaf001026 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.exp @@ -14,7 +14,7 @@ error: missing acquires annotation for `Test` warning: storage operation on type `test::Test` can only be done within the defining module `0x42::test`, but `test::modify` could be called (and expanded) outside the module ┌─ tests/checking/inlining/acquires_error_msg_inline.move:10:23 │ -10 │ public inline fun modify() acquires Test { +10 │ public inline fun modify() { │ ^^^^^^ 11 │ borrow_global_mut(@0xcafe).value = 2; │ -------------------------------- called here @@ -22,7 +22,7 @@ warning: storage operation on type `test::Test` can only be done within the defi warning: access of the field `value` on type `test::Test` can only be done within the defining module `0x42::test`, but `test::modify` could be called (and expanded) outside the module ┌─ tests/checking/inlining/acquires_error_msg_inline.move:10:23 │ -10 │ public inline fun modify() acquires Test { +10 │ public inline fun modify() { │ ^^^^^^ 11 │ borrow_global_mut(@0xcafe).value = 2; │ -------------------------------------- accessed here diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.move b/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.move index 0db2a239374..28533cbc131 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.move +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/acquires_error_msg_inline.move @@ -7,7 +7,7 @@ module 0x42::test { modify(); // expect error message here } - public inline fun modify() acquires Test { + public inline fun modify() { borrow_global_mut(@0xcafe).value = 2; } } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11112.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11112.exp index cad81fe0934..45c6e779930 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11112.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11112.exp @@ -37,6 +37,7 @@ module 0xcafe::vectors { // -- Sourcified model before first bytecode pipeline module 0xcafe::vectors { + use std::vector; fun test_for_each_mut() { let v = vector[1, 2, 3]; let s = 2; diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11223.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11223.exp index 76aa3a77738..6746fcb4054 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11223.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_11223.exp @@ -20,6 +20,7 @@ module 0xcafe::vectors { // -- Sourcified model before first bytecode pipeline module 0xcafe::vectors { + use std::vector; public entry fun guess_flips_break2(flips: vector): u64 { let flipsref5 = &flips; let _v = copy flips; diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717.exp index 600db7febfa..72e34ec3904 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717.exp @@ -183,6 +183,7 @@ module 0xcafe::vectors { // -- Sourcified model before first bytecode pipeline module 0xcafe::vectors { + use std::vector; public entry fun guess_flips(flips: vector) { { let (flips) = (&flips); diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717_looponly.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717_looponly.exp index 2912b74aa70..84d0a9df6b5 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717_looponly.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/bug_9717_looponly.exp @@ -41,6 +41,7 @@ module 0xcafe::vectors { // -- Sourcified model before first bytecode pipeline module 0xcafe::vectors { + use std::vector; public entry fun guess_flips_break2(flips: vector): u64 { let i = 0; let flipsref5 = &flips; diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/double_nesting.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/double_nesting.exp index b02f941cc54..0d9ecca305e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/double_nesting.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/double_nesting.exp @@ -46,12 +46,12 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::mathtest { public inline fun fun1(a: u64, b: u64, c: u64): u64 { - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 } } module 0x42::mathtest2 { public inline fun fun2(a: u64, b: u64, c: u64): u64 { - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 } } module 0x42::test { @@ -62,20 +62,20 @@ module 0x42::test { let (a,b,c) = (2, { let (a,b,c) = (3, { let (a,b,c) = (4, 5, 6); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }, 7); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }, { let (a,b,c) = (8, 9, { let (a,b,c) = (10, { let (a,b,c) = (11, 12, 13); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }, 14); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }; if (a == 81911) () else abort 0; } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp index 45da617e456..67bbf79e90b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/function_name_shadowing.exp @@ -32,7 +32,7 @@ module 0x42::Test { public fun f(a: u64,b: u64): u64 { Mul(a, b) } - public inline fun quux(f: |(u64, u64)|u64,g: |u64|u64,i: |u8|u8,a: u64,b: u64): u64 { + public inline fun quux(f: |u64, u64|u64,g: |u64|u64,i: |u8|u8,a: u64,b: u64): u64 { Mul(Mul(Test::f(a, b), OtherModule::g(a, b)), OtherModule::h(a, b)) } public fun test_shadowing(): u64 { @@ -57,7 +57,7 @@ module 0x42::Test { public fun f(a: u64, b: u64): u64 { a * b } - public inline fun quux(f: |(u64, u64)|u64, g: |u64|u64, i: |u8|u8, a: u64, b: u64): u64 { + public inline fun quux(f: |u64, u64|u64, g: |u64|u64, i: |u8|u8, a: u64, b: u64): u64 { f(a, b) * OtherModule::g(a, b) * OtherModule::h(a, b) } public fun test_shadowing(): u64 { @@ -80,7 +80,7 @@ module 0x42::Test { public fun f(a: u64,b: u64): u64 { Mul(a, b) } - public inline fun quux(f: |(u64, u64)|u64,g: |u64|u64,i: |u8|u8,a: u64,b: u64): u64 { + public inline fun quux(f: |u64, u64|u64,g: |u64|u64,i: |u8|u8,a: u64,b: u64): u64 { Mul(Mul(Test::f(a, b), OtherModule::g(a, b)), OtherModule::h(a, b)) } public fun test_shadowing(): u64 { diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp new file mode 100644 index 00000000000..27fa2364743 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.exp @@ -0,0 +1,45 @@ + +Diagnostics: +warning: acquires and access specifiers are not applicable to inline functions and should be removed + ┌─ tests/checking/inlining/inline_disallowed_acquires.move:6:16 + │ +6 │ inline fun test() acquires R {} + │ ^^^^ + +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + struct R { + x: u64, + } + private inline fun test() + acquires R(*) + { + Tuple() + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + struct R has key { + x: u64, + } + inline fun test() + acquires R + { + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + struct R { + x: u64, + } + private inline fun test() + acquires R(*) + { + Tuple() + } +} // end 0xc0ffee::m + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.move b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.move new file mode 100644 index 00000000000..ddd2f083a77 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_acquires.move @@ -0,0 +1,7 @@ +module 0xc0ffee::m { + struct R has key { + x: u64 + } + + inline fun test() acquires R {} +} diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.exp new file mode 100644 index 00000000000..da9eee529b2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.exp @@ -0,0 +1,13 @@ + +Diagnostics: +error: inline functions cannot have the following attributes: `#[persistent]`, `#[module_lock]` + ┌─ tests/checking/inlining/inline_disallowed_attributes.move:3:16 + │ +3 │ inline fun forty_two(): u64 { + │ ^^^^^^^^^ + +error: inline functions cannot have the following attributes: `#[persistent]`, `#[module_lock]` + ┌─ tests/checking/inlining/inline_disallowed_attributes.move:8:16 + │ +8 │ inline fun fifty_five(): u64 { + │ ^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.move b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.move new file mode 100644 index 00000000000..19162715ee8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/inline_disallowed_attributes.move @@ -0,0 +1,11 @@ +module 0xc0ffee::m { + #[persistent] + inline fun forty_two(): u64 { + 42 + } + + #[module_lock] + inline fun fifty_five(): u64 { + 55 + } +} diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda.exp index 45d956eab63..80643686c38 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda.exp @@ -280,6 +280,7 @@ module 0x42::LambdaTest1 { } module 0x42::LambdaTest2 { use 0x42::LambdaTest1; + use std::vector; public inline fun foreach(v: &vector, action: |&T|) { let i = 0; while (i < 0x1::vector::length(v)) { diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_cast.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_cast.exp index 0c81b94cd1a..edeb1df546f 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_cast.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_cast.exp @@ -73,6 +73,7 @@ module 0x12391283::M { // -- Sourcified model before first bytecode pipeline module 0x12391283::M { + use std::vector; fun test_1(): u64 { let gas_schedule_blob = vector[115u8, 115u8, 95u8, 112u8, 97u8, 99u8, 107u8, 101u8, 100u8, 32u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]; let (v,init) = (gas_schedule_blob, 0 as u64); diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_typed.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_typed.exp index 45d956eab63..80643686c38 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/lambda_typed.exp @@ -280,6 +280,7 @@ module 0x42::LambdaTest1 { } module 0x42::LambdaTest2 { use 0x42::LambdaTest1; + use std::vector; public inline fun foreach(v: &vector, action: |&T|) { let i = 0; while (i < 0x1::vector::length(v)) { diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/nested_mul.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/nested_mul.exp index 338ea47f55f..27ad8a4b84e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/nested_mul.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/nested_mul.exp @@ -28,7 +28,7 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::mathtest { public inline fun mul_div(a: u64, b: u64, c: u64): u64 { - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::test { @@ -37,9 +37,9 @@ module 0x42::test { let a = { let (a,b,c) = (1, { let (a,b,c) = (1, 1, 1); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }, 1); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }; if (a == 1) () else abort 0; } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/non_lambda_arg.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/non_lambda_arg.exp index 88cfe01e12e..9a96772a24b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/non_lambda_arg.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/non_lambda_arg.exp @@ -4,10 +4,10 @@ error: Only inline functions may have function-typed parameters, but non-inline ┌─ tests/checking/inlining/non_lambda_arg.move:4:16 │ 4 │ public fun incorrect_sort(arr: &mut vector, a_less_b: |T, T| bool) { - │ ^^^^^^^^^^^^^^ -------- Parameter `a_less_b` has function-valued type `|(T, T)|bool`. + │ ^^^^^^^^^^^^^^ -------- Parameter `a_less_b` has function-valued type `|T, T|bool`. error: Only inline functions may have function-typed parameters, but non-inline function `sort::incorrect_sort_recursive` has a function parameter: ┌─ tests/checking/inlining/non_lambda_arg.move:9:16 │ 9 │ public fun incorrect_sort_recursive(arr: &mut vector, low: u64, high: u64, a_less_b: |T, T| bool) { - │ ^^^^^^^^^^^^^^^^^^^^^^^^ -------- Parameter `a_less_b` has function-valued type `|(T, T)|bool`. + │ ^^^^^^^^^^^^^^^^^^^^^^^^ -------- Parameter `a_less_b` has function-valued type `|T, T|bool`. diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/recursive_nesting.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/recursive_nesting.exp index e73e07cb99d..2928695eb63 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/recursive_nesting.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/recursive_nesting.exp @@ -66,14 +66,14 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::mathtest { public inline fun mul_div(a: u64, b: u64, c: u64): u64 { - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::mathtest2 { use 0x42::mathtest; public inline fun mul_div2(a: u64, b: u64, c: u64): u64 { let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::mathtest3 { @@ -81,7 +81,7 @@ module 0x42::mathtest3 { public inline fun mul_div3(a: u64, b: u64, c: u64): u64 { let (a,b,c) = (b, a, c); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::test { @@ -94,16 +94,16 @@ module 0x42::test { let (a,b,c) = (1, 1, 1); let (a,b,c) = (b, a, c); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }, { let (a,b,c) = (1, 1, 1); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }, { let (a,b,c) = (1, 1, 1); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }; if (a == 1) () else abort 0; } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp index faa3c7bde0d..a22a89546d0 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/resources_valid.exp @@ -15,11 +15,11 @@ module 0x42::token { struct Token { val: u64, } - public fun get_value(ref: &objects::ReaderRef): u64 + public fun get_value(ref: &obj::ReaderRef): u64 acquires Token(*) { select token::Token.val<&Token>({ - let (ref: &objects::ReaderRef): (&objects::ReaderRef) = Tuple(ref); + let (ref: &obj::ReaderRef): (&obj::ReaderRef) = Tuple(ref); BorrowGlobal(Immutable)(objects::get_addr(ref)) }) } @@ -38,16 +38,16 @@ module 0x42::objects { } } module 0x42::token { - use 0x42::objects; + use 0x42::objects as obj; struct Token has key { val: u64, } - public fun get_value(ref: &objects::ReaderRef): u64 + public fun get_value(ref: &obj::ReaderRef): u64 acquires Token { { let (ref) = (ref); - borrow_global(objects::get_addr(ref)) + borrow_global(obj::get_addr(ref)) }.val } } @@ -69,11 +69,11 @@ module 0x42::token { struct Token { val: u64, } - public fun get_value(ref: &objects::ReaderRef): u64 + public fun get_value(ref: &obj::ReaderRef): u64 acquires Token(*) { select token::Token.val<&Token>({ - let (ref: &objects::ReaderRef): (&objects::ReaderRef) = Tuple(ref); + let (ref: &obj::ReaderRef): (&obj::ReaderRef) = Tuple(ref); BorrowGlobal(Immutable)(objects::get_addr(ref)) }) } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused.exp index ce127824e64..26522682f30 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (_z: u64): (u64) = Tuple(z); { @@ -17,7 +17,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,_z: u64) { + public inline fun quux(f: |u64, u64|,_z: u64) { { let x: u64 = 3; { @@ -92,7 +92,7 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|, z: u64) { + public inline fun foo(f: |u64, u64|, z: u64) { { let (_z) = (z); let x = 3; @@ -103,7 +103,7 @@ module 0x42::Test { }; }; } - public inline fun quux(f: |(u64, u64)|, _z: u64) { + public inline fun quux(f: |u64, u64|, _z: u64) { let x = 3; let q = 5; f(x, q); @@ -144,7 +144,7 @@ module 0x42::Test { // -- Model dump before second bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (_z: u64): (u64) = Tuple(z); (f)(3, 5); @@ -152,7 +152,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,_z: u64) { + public inline fun quux(f: |u64, u64|,_z: u64) { (f)(3, 5); Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl.exp index dd31b03d3c0..b9b44b19e2b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl.exp @@ -8,7 +8,7 @@ warning: Unused parameter `z`. Consider removing or prefixing with an underscore // -- Model dump before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (z: u64): (u64) = Tuple(z); { @@ -25,7 +25,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,z: u64) { + public inline fun quux(f: |u64, u64|,z: u64) { { let x: u64 = 3; { @@ -100,7 +100,7 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|, z: u64) { + public inline fun foo(f: |u64, u64|, z: u64) { { let (z) = (z); let x = 3; @@ -111,7 +111,7 @@ module 0x42::Test { }; }; } - public inline fun quux(f: |(u64, u64)|, z: u64) { + public inline fun quux(f: |u64, u64|, z: u64) { let x = 3; let q = 5; f(x, q); @@ -152,7 +152,7 @@ module 0x42::Test { // -- Model dump before second bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (z: u64): (u64) = Tuple(z); (f)(3, 5); @@ -160,7 +160,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,z: u64) { + public inline fun quux(f: |u64, u64|,z: u64) { (f)(3, 5); Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl_typed.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl_typed.exp index 9fa68bb46b4..29be69927ea 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_nodecl_typed.exp @@ -8,7 +8,7 @@ warning: Unused parameter `z`. Consider removing or prefixing with an underscore // -- Model dump before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (z: u64): (u64) = Tuple(z); { @@ -25,7 +25,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,z: u64) { + public inline fun quux(f: |u64, u64|,z: u64) { { let x: u64 = 3; { @@ -100,7 +100,7 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|, z: u64) { + public inline fun foo(f: |u64, u64|, z: u64) { { let (z) = (z); let x = 3; @@ -111,7 +111,7 @@ module 0x42::Test { }; }; } - public inline fun quux(f: |(u64, u64)|, z: u64) { + public inline fun quux(f: |u64, u64|, z: u64) { let x = 3; let q = 5; f(x, q); @@ -152,7 +152,7 @@ module 0x42::Test { // -- Model dump before second bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (z: u64): (u64) = Tuple(z); (f)(3, 5); @@ -160,7 +160,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,z: u64) { + public inline fun quux(f: |u64, u64|,z: u64) { (f)(3, 5); Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_typed.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_typed.exp index ce127824e64..26522682f30 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/shadowing_unused_typed.exp @@ -1,6 +1,6 @@ // -- Model dump before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (_z: u64): (u64) = Tuple(z); { @@ -17,7 +17,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,_z: u64) { + public inline fun quux(f: |u64, u64|,_z: u64) { { let x: u64 = 3; { @@ -92,7 +92,7 @@ module 0x42::Test { // -- Sourcified model before first bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|, z: u64) { + public inline fun foo(f: |u64, u64|, z: u64) { { let (_z) = (z); let x = 3; @@ -103,7 +103,7 @@ module 0x42::Test { }; }; } - public inline fun quux(f: |(u64, u64)|, _z: u64) { + public inline fun quux(f: |u64, u64|, _z: u64) { let x = 3; let q = 5; f(x, q); @@ -144,7 +144,7 @@ module 0x42::Test { // -- Model dump before second bytecode pipeline module 0x42::Test { - public inline fun foo(f: |(u64, u64)|,z: u64) { + public inline fun foo(f: |u64, u64|,z: u64) { { let (_z: u64): (u64) = Tuple(z); (f)(3, 5); @@ -152,7 +152,7 @@ module 0x42::Test { }; Tuple() } - public inline fun quux(f: |(u64, u64)|,_z: u64) { + public inline fun quux(f: |u64, u64|,_z: u64) { (f)(3, 5); Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/inlining/test_12670.exp b/third_party/move/move-compiler-v2/tests/checking/inlining/test_12670.exp index 1a9eb296c81..4c4cd6bc4e3 100644 --- a/third_party/move/move-compiler-v2/tests/checking/inlining/test_12670.exp +++ b/third_party/move/move-compiler-v2/tests/checking/inlining/test_12670.exp @@ -32,6 +32,7 @@ module 0x1::Test { // -- Sourcified model before first bytecode pipeline module 0x1::Test { + use std::vector; struct S has drop { x: u8, } diff --git a/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp b/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp index 66427316d8a..83e735f8f41 100644 --- a/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp +++ b/third_party/move/move-compiler-v2/tests/checking/naming/duplicate_acquires_list_item.exp @@ -35,21 +35,15 @@ module 0x8675309::M { struct X has key { } fun t0() - acquires R - acquires X - acquires R + acquires R, X { - borrow_global_mut(0x1); - borrow_global_mut(0x1); + borrow_global_mut(@0x1); + borrow_global_mut(@0x1); } fun t1() - acquires R - acquires X - acquires R - acquires R - acquires R + acquires R, X { - borrow_global_mut(0x1); - borrow_global_mut(0x1); + borrow_global_mut(@0x1); + borrow_global_mut(@0x1); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp b/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp index fb749b373e6..dd0a3056ef5 100644 --- a/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp +++ b/third_party/move/move-compiler-v2/tests/checking/naming/global_builtin_one_type_argument.exp @@ -32,10 +32,10 @@ module 0x8675309::M { fun t(account: &signer) acquires R { - let _ = exists(0x0); - let () = move_to(account, R{}); - let _ = borrow_global(0x0); - let _ = borrow_global_mut(0x0); - let R{} = move_from(0x0); + let _ = exists(@0x0); + let () = move_to(R{}, account); + let _ = borrow_global(@0x0); + let _ = borrow_global_mut(@0x0); + let R{} = move_from(@0x0); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/naming/warning_dependency.exp b/third_party/move/move-compiler-v2/tests/checking/naming/warning_dependency.exp index 9ed2dcc9a63..d5fb977e3eb 100644 --- a/third_party/move/move-compiler-v2/tests/checking/naming/warning_dependency.exp +++ b/third_party/move/move-compiler-v2/tests/checking/naming/warning_dependency.exp @@ -34,4 +34,5 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::dependency { + use 0x42::test; } diff --git a/third_party/move/move-compiler-v2/tests/checking/positional_fields/assign_field.exp b/third_party/move/move-compiler-v2/tests/checking/positional_fields/assign_field.exp index 37f3b68f65d..fef40196768 100644 --- a/third_party/move/move-compiler-v2/tests/checking/positional_fields/assign_field.exp +++ b/third_party/move/move-compiler-v2/tests/checking/positional_fields/assign_field.exp @@ -123,16 +123,16 @@ module 0x42::test { 2: S2, } fun assign0(a: u64, b: bool) { - let x = S1(a,b); + let x = S1(a, b); while (x.1) { - x = S1(x.0 - 1,x.0 >= 1); + x = S1(x.0 - 1, x.0 >= 1); } } fun assign1(x: S1): u64 { let count = 0; while (x.1) { let y = if (x.0 > 0) x.0 - 1 else 0; - x = S1(y,y >= 1); + x = S1(y, y >= 1); count = count + 1; }; count @@ -145,7 +145,7 @@ module 0x42::test { } fun assign_enum(x: &mut E) { match (x) { - E::V1(x,y) => { + E::V1(x, y) => { *x = 42u8; *y = true; }, diff --git a/third_party/move/move-compiler-v2/tests/checking/positional_fields/bind_anonymous_field.exp b/third_party/move/move-compiler-v2/tests/checking/positional_fields/bind_anonymous_field.exp index ccb7c12d340..4511976c395 100644 --- a/third_party/move/move-compiler-v2/tests/checking/positional_fields/bind_anonymous_field.exp +++ b/third_party/move/move-compiler-v2/tests/checking/positional_fields/bind_anonymous_field.exp @@ -60,11 +60,11 @@ module 0x42::test { fun match(x: E1) { match (x) { E1::V1(S0(_x)) => (), - E1::V2(S1(_x,S0(_y))) => (), + E1::V2(S1(_x, S0(_y))) => (), } } fun nested(x: S1) { - let S1(_x,S0(_y)) = x; + let S1(_x, S0(_y)) = x; } fun simple(x: S0) { let S0(_x) = x; diff --git a/third_party/move/move-compiler-v2/tests/checking/positional_fields/decl_ok.exp b/third_party/move/move-compiler-v2/tests/checking/positional_fields/decl_ok.exp index eb7eb34bb86..cb5a9d4da77 100644 --- a/third_party/move/move-compiler-v2/tests/checking/positional_fields/decl_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking/positional_fields/decl_ok.exp @@ -64,7 +64,7 @@ module 0x42::test { fun baz() { E1::V1{}; E1::V2{}; - E1::V3(42u8,true); + E1::V3(42u8, true); } fun foo(x: S2) { x.0; diff --git a/third_party/move/move-compiler-v2/tests/checking/positional_fields/named_tuple_construct_ok.exp b/third_party/move/move-compiler-v2/tests/checking/positional_fields/named_tuple_construct_ok.exp index 22ff2b8d077..f038cd0391d 100644 --- a/third_party/move/move-compiler-v2/tests/checking/positional_fields/named_tuple_construct_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking/positional_fields/named_tuple_construct_ok.exp @@ -91,20 +91,20 @@ module 0x42::test { S1(0u8) } fun S2_inhabited(): S2 { - S2(0u8,false) + S2(0u8, false) } fun S3_test(x: T): S3 { - S3(x,0u8) + S3(x, 0u8) } fun nested_0(): S3 { - S3(S4{},0u8) + S3(S4{}, 0u8) } fun nested_1(): S5 { - S5{x: S0{},y: 0u8} + S5{x: S0{}, y: 0u8} } fun test_variant() { E1::V1{}; E1::V2{}; - E1::V3(42u8,true); + E1::V3(42u8, true); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.exp index aad7cbc7821..865bd7393e6 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.exp @@ -6,11 +6,11 @@ error: undeclared receiver function `borrow` for type `vector>` 25 │ &map.entries.borrow(self.index).key │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: undeclared receiver function `lower_bound` for type `OrderedMap` - ┌─ tests/checking/receiver/bad_receiver.move:29:27 +error: undeclared receiver function `internal_lower_bound` for type `OrderedMap` + ┌─ tests/checking/receiver/bad_receiver.move:29:36 │ -29 │ let lower_bound = self.lower_bound(key); - │ ^^^^^^^^^^^^^^^^^^^^^ +29 │ let internal_lower_bound = self.internal_lower_bound(key); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type cannot have type arguments ┌─ tests/checking/receiver/bad_receiver.move:39:36 diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.move b/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.move index da72fd481f0..64175cba77d 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.move +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/bad_receiver.move @@ -25,14 +25,14 @@ module aptos_std::ordered_map { &map.entries.borrow(self.index).key } - public fun find(self: &OrderedMap, key: &K): Iterator { - let lower_bound = self.lower_bound(key); - if (lower_bound.iter_is_end(self)) { - lower_bound - } else if (lower_bound.iter_borrow_key(self) == key) { - lower_bound + public fun internal_find(self: &OrderedMap, key: &K): Iterator { + let internal_lower_bound = self.internal_lower_bound(key); + if (internal_lower_bound.iter_is_end(self)) { + internal_lower_bound + } else if (internal_lower_bound.iter_borrow_key(self) == key) { + internal_lower_bound } else { - self.new_end_iter() + self.internal_new_end_iter() } } @@ -40,7 +40,7 @@ module aptos_std::ordered_map { self.find(key).iter_borrow(self) } - public fun new_end_iter(self: &OrderedMap): Iterator { + public fun internal_new_end_iter(self: &OrderedMap): Iterator { Iterator::End } diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp index 81966942de1..c267a8c7584 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/calls_index.exp @@ -165,9 +165,9 @@ module 0x42::m { } fun merge(self: &mut W, s: W) { { - let $t2 = s.x; - let $t1 = &mut self.x; - *$t1 = *$t1 + $t2 + let _t2 = s.x; + let _t1 = &mut self.x; + *_t1 = *_t1 + _t2 }; } fun unwrap(self: &Wrapper): T { diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/decl_errors.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/decl_errors.exp index 821dd03f59d..729e1f7647d 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/decl_errors.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/decl_errors.exp @@ -1,6 +1,6 @@ Diagnostics: -warning: parameter name `self` indicates a receiver function but the type `n::T` is declared outside of this module and new receiver functions cannot be added. Consider using a different name. +warning: parameter name `self` indicates a receiver function but the type `0x42::n::T` is declared outside of this module and new receiver functions cannot be added. Consider using a different name. ┌─ tests/checking/receiver/decl_errors.move:11:9 │ 11 │ fun receiver_for_external_type(self: T) {} @@ -18,13 +18,13 @@ warning: parameter name `self` indicates a receiver function but the type `vecto 17 │ fun receiver_for_external_vector(self: vector) {} │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: parameter name `self` indicates a receiver function but the type `m::G` must only use type parameters but instead uses `u64`. Consider using a different name. +warning: parameter name `self` indicates a receiver function but the type `0x42::m::G` must only use type parameters but instead uses `u64`. Consider using a different name. ┌─ tests/checking/receiver/decl_errors.move:20:9 │ 20 │ fun receiver_partial_instantiated(self: G) {} │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: parameter name `self` indicates a receiver function but the type `m::G` cannot use type parameter `T` more than once. Consider using a different name. +warning: parameter name `self` indicates a receiver function but the type `0x42::m::G` cannot use type parameter `T` more than once. Consider using a different name. ┌─ tests/checking/receiver/decl_errors.move:23:9 │ 23 │ fun receiver_non_linear_instantiated(self: G) {} diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/same_names.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/same_names.exp index 35ca5849954..6fd1073e29a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/same_names.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/same_names.exp @@ -18,7 +18,7 @@ module 0x42::b { module 0x42::c { use 0x42::a; // resolved as: 0x42::a use 0x42::b; // resolved as: 0x42::b - private inline fun foo(f: |(a::MyList, b::MyOtherList)|,x: a::MyList,y: b::MyOtherList) { + private inline fun foo(f: |a::MyList, b::MyOtherList|,x: a::MyList,y: b::MyOtherList) { (f)(x, y) } private fun test(x: a::MyList,y: b::MyOtherList) { @@ -56,7 +56,7 @@ module 0x42::b { module 0x42::c { use 0x42::a; use 0x42::b; - inline fun foo(f: |(a::MyList, b::MyOtherList)|, x: a::MyList, y: b::MyOtherList) { + inline fun foo(f: |a::MyList, b::MyOtherList|, x: a::MyList, y: b::MyOtherList) { f(x, y) } fun test(x: a::MyList, y: b::MyOtherList) { diff --git a/third_party/move/move-compiler-v2/tests/checking/receiver/same_names_typed.exp b/third_party/move/move-compiler-v2/tests/checking/receiver/same_names_typed.exp index 35ca5849954..6fd1073e29a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/receiver/same_names_typed.exp +++ b/third_party/move/move-compiler-v2/tests/checking/receiver/same_names_typed.exp @@ -18,7 +18,7 @@ module 0x42::b { module 0x42::c { use 0x42::a; // resolved as: 0x42::a use 0x42::b; // resolved as: 0x42::b - private inline fun foo(f: |(a::MyList, b::MyOtherList)|,x: a::MyList,y: b::MyOtherList) { + private inline fun foo(f: |a::MyList, b::MyOtherList|,x: a::MyList,y: b::MyOtherList) { (f)(x, y) } private fun test(x: a::MyList,y: b::MyOtherList) { @@ -56,7 +56,7 @@ module 0x42::b { module 0x42::c { use 0x42::a; use 0x42::b; - inline fun foo(f: |(a::MyList, b::MyOtherList)|, x: a::MyList, y: b::MyOtherList) { + inline fun foo(f: |a::MyList, b::MyOtherList|, x: a::MyList, y: b::MyOtherList) { f(x, y) } fun test(x: a::MyList, y: b::MyOtherList) { diff --git a/third_party/move/move-compiler-v2/tests/checking/specs/conditions_ok.exp b/third_party/move/move-compiler-v2/tests/checking/specs/conditions_ok.exp index eea99101f15..78330972fac 100644 --- a/third_party/move/move-compiler-v2/tests/checking/specs/conditions_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking/specs/conditions_ok.exp @@ -33,7 +33,7 @@ module 0x42::M { // -- Sourcified model before first bytecode pipeline module 0x42::M { - struct Ghost$some_global has copy, drop, store, key { + struct Ghost_some_global has copy, drop, store, key { v: u64, } fun add_some(x: &mut u64): u64 { diff --git a/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_bitvector.exp b/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_bitvector.exp index 9342ced54a2..1846d33d7a4 100644 --- a/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_bitvector.exp +++ b/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_bitvector.exp @@ -25,6 +25,7 @@ module 0x42::bit_vector_infer { // -- Sourcified model before first bytecode pipeline module 0x42::bit_vector_infer { + use std::vector; public fun new(_length: u64) { let counter = 1; if (counter > 0) { diff --git a/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_vector.exp b/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_vector.exp index 9bc861ecb16..65e8dc962fd 100644 --- a/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_vector.exp +++ b/third_party/move/move-compiler-v2/tests/checking/specs/inline_spec_inference_vector.exp @@ -16,6 +16,7 @@ module 0x42::bit_vector { // -- Sourcified model before first bytecode pipeline module 0x42::bit_vector { + use std::vector; public fun new(_length: u64) { let bit_field = 0x1::vector::empty(); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/assign_tuple_wg.exp b/third_party/move/move-compiler-v2/tests/checking/typing/assign_tuple_wg.exp index 178f866b867..40db3a701cf 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/assign_tuple_wg.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/assign_tuple_wg.exp @@ -39,6 +39,6 @@ module 0xc0ffee::dummy2 { value: u64, } fun tuple_assignments(s: &signer, state: State) { - let () = move_to(s, state); + let () = move_to(state, s); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/bad_type_argument_arity_const.exp b/third_party/move/move-compiler-v2/tests/checking/typing/bad_type_argument_arity_const.exp index 0b82e5048b7..fbdae27d1d1 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/bad_type_argument_arity_const.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/bad_type_argument_arity_const.exp @@ -20,7 +20,7 @@ error: Invalid type for constant 6 │ const S1: S = S { f: 0 }; │ --------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 0 were provided ┌─ tests/checking/typing/bad_type_argument_arity_const.move:7:15 @@ -42,7 +42,7 @@ error: Invalid type for constant 7 │ const S2: S<> = S { f: 0 }; │ ----------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 2 were provided ┌─ tests/checking/typing/bad_type_argument_arity_const.move:8:15 @@ -64,7 +64,7 @@ error: Invalid type for constant 8 │ const S3: S = S { f: 0 }; │ -------------------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 2 were provided ┌─ tests/checking/typing/bad_type_argument_arity_const.move:9:17 @@ -87,4 +87,4 @@ error: Invalid type for constant 9 │ const S4: S> = S { f: S { f: 0 } }; │ ----------------------------^^^^^^^^^^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_and_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_and_invalid.exp index 29ad78aea20..239ff11372f 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_and_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_and_invalid.exp @@ -1,24 +1,24 @@ Diagnostics: -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:8:9 │ 8 │ false & true; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:9:13 │ 9 │ 1 & false; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:10:9 │ 10 │ false & 1; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:11:9 │ 11 │ @0x0 & @0x1; @@ -30,49 +30,49 @@ error: cannot use `u128` with an operator which expects a value of type `u8` 12 │ (0: u8) & (1: u128); │ ^ -error: cannot use `R` with an operator which expects a value of type `integer` +error: cannot use `R` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:13:9 │ 13 │ r & r; │ ^ -error: cannot use `S` with an operator which expects a value of type `integer` +error: cannot use `S` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:14:9 │ 14 │ s & s; │ ^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:15:13 │ 15 │ 1 & false & @0x0 & 0; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:15:21 │ 15 │ 1 & false & @0x0 & 0; │ ^^^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:16:9 │ 16 │ () & (); │ ^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:17:13 │ 17 │ 1 & (); │ ^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:18:9 │ 18 │ (0, 1) & (0, 1, 2); │ ^^^^^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_and_invalid.move:19:9 │ 19 │ (1, 2) & (0, 1); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_or_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_or_invalid.exp index 94725800606..5bf0d80b4c2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_or_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_or_invalid.exp @@ -1,24 +1,24 @@ Diagnostics: -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:8:9 │ 8 │ false | true; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:9:13 │ 9 │ 1 | false; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:10:9 │ 10 │ false | 1; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:11:9 │ 11 │ @0x0 | @0x1; @@ -30,49 +30,49 @@ error: cannot use `u128` with an operator which expects a value of type `u8` 12 │ (0: u8) | (1: u128); │ ^ -error: cannot use `R` with an operator which expects a value of type `integer` +error: cannot use `R` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:13:9 │ 13 │ r | r; │ ^ -error: cannot use `S` with an operator which expects a value of type `integer` +error: cannot use `S` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:14:9 │ 14 │ s | s; │ ^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:15:13 │ 15 │ 1 | false | @0x0 | 0; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:15:21 │ 15 │ 1 | false | @0x0 | 0; │ ^^^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:16:9 │ 16 │ () | (); │ ^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:17:13 │ 17 │ 1 | (); │ ^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:18:9 │ 18 │ (0, 1) | (0, 1, 2); │ ^^^^^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_or_invalid.move:19:9 │ 19 │ (1, 2) | (0, 1); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_xor_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_xor_invalid.exp index f40a23d203b..a06a8a3c0ee 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_xor_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_bit_xor_invalid.exp @@ -1,24 +1,24 @@ Diagnostics: -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:8:9 │ 8 │ false ^ true; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:9:13 │ 9 │ 1 ^ false; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:10:9 │ 10 │ false ^ 1; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:11:9 │ 11 │ @0x0 ^ @0x1; @@ -30,49 +30,49 @@ error: cannot use `u128` with an operator which expects a value of type `u8` 12 │ (0: u8) ^ (1: u128); │ ^ -error: cannot use `R` with an operator which expects a value of type `integer` +error: cannot use `R` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:13:9 │ 13 │ r ^ r; │ ^ -error: cannot use `S` with an operator which expects a value of type `integer` +error: cannot use `S` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:14:9 │ 14 │ s ^ s; │ ^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:15:13 │ 15 │ 1 ^ false ^ @0x0 ^ 0; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:15:21 │ 15 │ 1 ^ false ^ @0x0 ^ 0; │ ^^^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:16:9 │ 16 │ () ^ (); │ ^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:17:13 │ 17 │ 1 ^ (); │ ^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:18:9 │ 18 │ (0, 1) ^ (0, 1, 2); │ ^^^^^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_bit_xor_invalid.move:19:9 │ 19 │ (1, 2) ^ (0, 1); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp index 0b56c64f3de..e161c2716b2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp @@ -36,6 +36,6 @@ module 0x8675309::M { (copy x) << (copy b); r.f << r.b; 1 << r.b << r.b << 0u8; - R{f: _,b: _} = r + R{f: _, b: _} = r } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp index 19f51b4d955..4829d1dc655 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp @@ -1,6 +1,6 @@ Diagnostics: -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:8:9 │ 8 │ false << true; @@ -12,13 +12,13 @@ error: cannot use `bool` with an operator which expects a value of type `u8` 9 │ 1 << false; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:10:9 │ 10 │ false << 1; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:11:9 │ 11 │ @0x0 << @0x1; @@ -30,13 +30,13 @@ error: cannot use `u128` with an operator which expects a value of type `u8` 12 │ (0: u8) << (1: u128); │ ^ -error: cannot use `R` with an operator which expects a value of type `integer` +error: cannot use `R` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:13:9 │ 13 │ r << r; │ ^ -error: cannot use `S` with an operator which expects a value of type `integer` +error: cannot use `S` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:14:9 │ 14 │ s << s; @@ -54,7 +54,7 @@ error: cannot use `address` with an operator which expects a value of type `u8` 15 │ 1 << false << @0x0 << 0; │ ^^^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:16:9 │ 16 │ () << (); @@ -66,13 +66,13 @@ error: cannot use `()` with an operator which expects a value of type `u8` 17 │ 1 << (); │ ^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:18:9 │ 18 │ (0, 1) << (0, 1, 2); │ ^^^^^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shl_invalid.move:19:9 │ 19 │ (1, 2) << (0, 1); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp index 4d9b0a6c910..ccc7dd585e2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp @@ -36,6 +36,6 @@ module 0x8675309::M { (copy x) >> (copy b); r.f >> r.b; 1 >> r.b >> r.b >> 0u8; - R{f: _,b: _} = r + R{f: _, b: _} = r } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp index 75e4b7e1349..32249a60782 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp @@ -1,6 +1,6 @@ Diagnostics: -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:8:9 │ 8 │ false >> true; @@ -12,13 +12,13 @@ error: cannot use `bool` with an operator which expects a value of type `u8` 9 │ 1 >> false; │ ^^^^^ -error: cannot use `bool` with an operator which expects a value of type `integer` +error: cannot use `bool` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:10:9 │ 10 │ false >> 1; │ ^^^^^ -error: cannot use `address` with an operator which expects a value of type `integer` +error: cannot use `address` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:11:9 │ 11 │ @0x0 >> @0x1; @@ -30,13 +30,13 @@ error: cannot use `u128` with an operator which expects a value of type `u8` 12 │ (0: u8) >> (1: u128); │ ^ -error: cannot use `R` with an operator which expects a value of type `integer` +error: cannot use `R` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:13:9 │ 13 │ r >> r; │ ^ -error: cannot use `S` with an operator which expects a value of type `integer` +error: cannot use `S` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:14:9 │ 14 │ s >> s; @@ -54,7 +54,7 @@ error: cannot use `address` with an operator which expects a value of type `u8` 15 │ 1 >> false >> @0x0 >> 0; │ ^^^^ -error: cannot use `()` with an operator which expects a value of type `integer` +error: cannot use `()` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:16:9 │ 16 │ () >> (); @@ -66,13 +66,13 @@ error: cannot use `()` with an operator which expects a value of type `u8` 17 │ 1 >> (); │ ^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:18:9 │ 18 │ (0, 1) >> (0, 1, 2); │ ^^^^^^ -error: cannot use `(integer, integer)` with an operator which expects a value of type `integer` +error: cannot use `(integer, integer)` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` ┌─ tests/checking/typing/binary_shr_invalid.move:19:9 │ 19 │ (1, 2) >> (0, 1); diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.exp b/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.exp new file mode 100644 index 00000000000..4b7e999b660 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.exp @@ -0,0 +1,25 @@ + +Diagnostics: +error: duplicate declaration of type parameter `T2` + ┌─ tests/checking/typing/bug_17081.move:4:26 + │ +4 │ struct Func1(|T1, T2|T2) has copy, drop; + │ -- ^^ + │ │ + │ previously declared here + +error: duplicate declaration of type parameter `T1` + ┌─ tests/checking/typing/bug_17081.move:6:17 + │ +6 │ enum E2 has drop { + │ -- ^^ + │ │ + │ previously declared here + +error: duplicate declaration of type parameter `T2` + ┌─ tests/checking/typing/bug_17081.move:11:26 + │ +11 │ fun local_get_x1(x1: T2, x2: T2): &T2 { + │ -- ^^ + │ │ + │ previously declared here diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.move b/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.move new file mode 100644 index 00000000000..a035f12a5e2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking/typing/bug_17081.move @@ -0,0 +1,15 @@ +module 0x42::assign { + + + struct Func1(|T1, T2|T2) has copy, drop; + + enum E2 has drop { + A {x: T1}, + B {y: T1, x: T2} + } + + fun local_get_x1(x1: T2, x2: T2): &T2 { + &x1 + } + +} diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp index 35d218e57d9..940d9f024e4 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp @@ -57,7 +57,7 @@ module 0x42::M { false } fun t5(): address { - 0x0 + @0x0 } fun t6(): vector { vector[1u8, 35u8] @@ -66,7 +66,7 @@ module 0x42::M { vector[97u8, 98u8, 99u8, 100u8] } fun t8(): vector
{ - vector[0x0, 0x1] + vector[@0x0, @0x1] } fun t9(): u8 { 0u8 @@ -78,9 +78,9 @@ script { 0; 0u128; false; - 0x0; + @0x0; vector[1u8, 35u8]; vector[97u8, 98u8, 99u8, 100u8]; - vector[0x0, 0x1]; + vector[@0x0, @0x1]; } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_inference.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_inference.exp index ed2904e90e9..0d92a9e2c5e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_inference.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_inference.exp @@ -1,6 +1,6 @@ Diagnostics: -error: cannot use `u8` with an operator which expects a value of type `u16|u32|u64|u128|u256` +error: cannot use `u8` with an operator which expects a value of type `u16|u32|u64|u128|u256|i16|i32|i64|i128|i256` ┌─ tests/checking/typing/constant_inference.move:19:27 │ 19 │ let error = 257 + r; // Should error diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_invalid_base_type.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_invalid_base_type.exp index a4828d3de57..c49e7cb9a18 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_invalid_base_type.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_invalid_base_type.exp @@ -14,7 +14,7 @@ error: Invalid type for constant 6 │ const C1: signer = abort 0; │ -------------------^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:7:19 @@ -30,7 +30,7 @@ error: Invalid type for constant 7 │ const C2: S = S{}; │ --------------^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:8:19 @@ -46,7 +46,7 @@ error: Invalid type for constant 8 │ const C3: R = R{}; │ --------------^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:9:27 @@ -62,7 +62,7 @@ error: Invalid type for constant 9 │ const C4: vector = abort 0; │ ----------------------^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:10:27 @@ -78,7 +78,7 @@ error: Invalid type for constant 10 │ const C5: vector = abort 0; │ ----------------------^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:11:35 @@ -94,7 +94,7 @@ error: Invalid type for constant 11 │ const C6: vector> = abort 0; │ ------------------------------^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/checking/typing/constant_invalid_base_type.move:12:35 @@ -110,4 +110,4 @@ error: Invalid type for constant 12 │ const C7: vector> = abort 0; │ ------------------------------^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp index d1e07c3fbf0..c0bcea28e09 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp @@ -14,7 +14,13 @@ error: Invalid type for constant 3 │ const C1: &u64 = &0; │ -----------------^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. + +error: expected `&mut u64` but found a value of type `&u64` (mutability mismatch) + ┌─ tests/checking/typing/constant_non_base_type.move:4:26 + │ +4 │ const C2: &mut u64 = &0; + │ ^^ error: Not a valid constant expression. ┌─ tests/checking/typing/constant_non_base_type.move:4:26 @@ -30,13 +36,7 @@ error: Invalid type for constant 4 │ const C2: &mut u64 = &0; │ ---------------------^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. - -error: expected `&mut u64` but found a value of type `&u64` (mutability mismatch) - ┌─ tests/checking/typing/constant_non_base_type.move:4:26 - │ -4 │ const C2: &mut u64 = &0; - │ ^^ + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Invalid type for constant ┌─ tests/checking/typing/constant_non_base_type.move:5:20 @@ -44,7 +44,7 @@ error: Invalid type for constant 5 │ const C3: () = (); │ ---------------^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Invalid type for constant ┌─ tests/checking/typing/constant_non_base_type.move:6:33 @@ -52,4 +52,4 @@ error: Invalid type for constant 6 │ const C4: (address, bool) = (@0x0, false); │ ----------------------------^^^^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/decl_unpack_references.exp b/third_party/move/move-compiler-v2/tests/checking/typing/decl_unpack_references.exp index b2f95a56766..79f747ef977 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/decl_unpack_references.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/decl_unpack_references.exp @@ -49,21 +49,21 @@ module 0x8675309::M { f: u64, } fun t0() { - let R{s1: S{f: f},s2: s2}; + let R{s1: S{f: f}, s2: s2}; f = 0; f; s2 = S{f: 0}; s2; } fun t1() { - let R{s1: S{f: f},s2: s2}; + let R{s1: S{f: f}, s2: s2}; f = &0; f; s2 = &S{f: 0}; s2; } fun t2() { - let R{s1: S{f: f},s2: s2}; + let R{s1: S{f: f}, s2: s2}; f = &mut 0; f; s2 = &mut S{f: 0}; diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp b/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp index 742d607d90b..4dfa0b7196b 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/dummy_field.exp @@ -59,6 +59,6 @@ module 0x42::test { } public entry fun test4(s: &signer) { let r = T{}; - move_to(s, r); + move_to(r, s); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp index 7534108cc4b..1d2171c4b11 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins.exp @@ -52,19 +52,19 @@ module 0x8675309::M { fun t0(a: &signer) acquires R { - let _ = exists(0x0); - let () = move_to(a, R{}); - let _ = borrow_global(0x0); - let _ = borrow_global_mut(0x0); - let R{} = move_from(0x0); + let _ = exists(@0x0); + let () = move_to(R{}, a); + let _ = borrow_global(@0x0); + let _ = borrow_global_mut(@0x0); + let R{} = move_from(@0x0); } fun t1(a: &signer) acquires R { - let _ = exists(0x0); - let () = move_to(a, R{}); - let _ = borrow_global(0x0); - let _ = borrow_global_mut(0x0); - let R{} = move_from(0x0); + let _ = exists(@0x0); + let () = move_to(R{}, a); + let _ = borrow_global(@0x0); + let _ = borrow_global_mut(@0x0); + let R{} = move_from(@0x0); } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/module_call_entry_function.exp b/third_party/move/move-compiler-v2/tests/checking/typing/module_call_entry_function.exp index 46b19713f21..15ab66ca553 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/module_call_entry_function.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/module_call_entry_function.exp @@ -63,8 +63,8 @@ module 0x2::X { } } module 0x2::M { - use 0x2::Y; use 0x2::X; + use 0x2::Y; friend fun f_friend() { } public fun f_public() { diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/nested_post_process.exp b/third_party/move/move-compiler-v2/tests/checking/typing/nested_post_process.exp index 461c0e68a2a..fa4e04a08b6 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/nested_post_process.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/nested_post_process.exp @@ -53,6 +53,9 @@ module 0x42::simple_map { // -- Sourcified model before first bytecode pipeline module 0x42::simple_map { + use std::error; + use std::option; + use std::vector; struct Element has copy, drop, store { key: Key, value: Value, diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/number_literal_too_large_256.exp b/third_party/move/move-compiler-v2/tests/checking/typing/number_literal_too_large_256.exp index 31e9d0f17ae..257c18d100a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/number_literal_too_large_256.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/number_literal_too_large_256.exp @@ -4,4 +4,4 @@ error: invalid number literal ┌─ tests/checking/typing/number_literal_too_large_256.move:3:9 │ 3 │ 115792089237316195423570985008687907853269984665640564039457584007913129639936; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into the largest possible integer type, 'u256' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into the largest possible integer type, 'u256' diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp b/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp index 8c8bfd38955..651a3f44a12 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp @@ -26,8 +26,8 @@ module 0x8675309::M { abort 0 } fun foo(x: &mut u64) { - /*freeze*/x; - /*freeze*/&mut any>(); + freeze(x); + freeze(&mut any>()); if (true && false) () else abort *x; if (true || false) () else abort 0u8 as u64; } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/shadowing.exp b/third_party/move/move-compiler-v2/tests/checking/typing/shadowing.exp index 6c80ff4925f..9c6284a9c53 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/shadowing.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/shadowing.exp @@ -90,7 +90,7 @@ module 0x8675309::M { { let x = false; { - let x = 0x0; + let x = @0x0; x; }; x; @@ -103,7 +103,7 @@ module 0x8675309::M { let (a,x) = (false, false); a && x; } else { - let x = 0x0; + let x = @0x0; x; }; x; @@ -111,7 +111,7 @@ module 0x8675309::M { fun t2() { let x = 0; loop { - let S{f: _,b: x} = S{f: 0,b: false}; + let S{f: _, b: x} = S{f: 0, b: false}; x; break }; diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/subtype_args.exp b/third_party/move/move-compiler-v2/tests/checking/typing/subtype_args.exp index 0758786b715..36380db88c3 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/subtype_args.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/subtype_args.exp @@ -28,7 +28,7 @@ module 0x8675309::M { M::imm_imm(Freeze(false)(Borrow(Mutable)(0)), Freeze(false)(Borrow(Mutable)(0))); Tuple() } - private inline fun t2(f: |(&u64, &mut u64)|) { + private inline fun t2(f: |&u64, &mut u64|) { (f)(Borrow(Mutable)(0), Borrow(Mutable)(0)); (f)(Borrow(Immutable)(0), Borrow(Mutable)(0)); Tuple() @@ -58,7 +58,7 @@ module 0x8675309::M { mut_imm(&mut 0, /*freeze*/&mut 0); imm_imm(/*freeze*/&mut 0, /*freeze*/&mut 0); } - inline fun t2(f: |(&u64, &mut u64)|) { + inline fun t2(f: |&u64, &mut u64|) { f(&mut 0, &mut 0); f(&0, &mut 0); } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_pack.exp b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_pack.exp index 0f2e839bb32..a597dfbf504 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_pack.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_pack.exp @@ -24,9 +24,9 @@ module 0x42::M { f2: T, } fun t0() { - let b = Box{f1: 0,f2: 1}; + let b = Box{f1: 0, f2: 1}; *&b; - let b2 = Box>{f1: *&b,f2: b}; + let b2 = Box>{f1: *&b, f2: b}; b2; } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack.exp b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack.exp index 81ff5a48ecd..dd1b638fee6 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack.exp @@ -32,10 +32,10 @@ module 0x8675309::M { abort 0 } fun t0() { - let Box{f1: f1,f2: f2} = new(); + let Box{f1: f1, f2: f2} = new(); f1; f2; - let Box>{f1: f1,f2: f2} = new>(); + let Box>{f1: f1, f2: f2} = new>(); f1; f2; } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack_assign.exp b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack_assign.exp index dab3a5438e3..b5e2ee50d07 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack_assign.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_single_unpack_assign.exp @@ -42,12 +42,12 @@ module 0x8675309::M { fun t0() { let f1; let f2; - Box{f1: f1,f2: f2} = new(); + Box{f1: f1, f2: f2} = new(); f1; f2; let f1; let f2; - Box>{f1: f1,f2: f2} = new>(); + Box>{f1: f1, f2: f2} = new>(); f1; f2; } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_threaded_pack.exp b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_threaded_pack.exp index 598a47c954e..ff491fa1ed9 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_threaded_pack.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/type_variable_join_threaded_pack.exp @@ -58,7 +58,7 @@ module 0x2::M { fun t0(): Box { let v = Container::new(); let x = Container::get(&v); - let b = Box{f1: x,f2: x}; + let b = Box{f1: x, f2: x}; Container::put(&mut v, 0); b } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/unused_local.exp b/third_party/move/move-compiler-v2/tests/checking/typing/unused_local.exp index aea75214b72..8b0e1119dd2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/unused_local.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/unused_local.exp @@ -100,7 +100,7 @@ module 0x8675309::M { let (x,y); } fun t2() { - let S{f: f,g: g}; + let S{f: f, g: g}; } fun two_unused(x: u64, y: bool) { } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp index 938cfac8bb6..fd7953016dc 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/multi_pool_money_market_token.exp @@ -298,18 +298,18 @@ module 0x2::Token { value: u64, } public fun create(type: ATy, value: u64): Coin { - Coin{type: type,value: value} + Coin{type: type, value: value} } public fun value(coin: &Coin): u64 { coin.value } public fun deposit(coin: &mut Coin, check: Coin) { - let Coin{type: type,value: value} = check; + let Coin{type: type, value: value} = check; if (&coin.type == &type) () else abort 42; coin.value = coin.value + value; } public fun destroy_zero(coin: Coin) { - let Coin{type: _,value: value} = coin; + let Coin{type: _, value: value} = coin; if (value == 0) () else abort 11 } public fun join(xus: Coin, coin2: Coin): Coin { @@ -323,10 +323,11 @@ module 0x2::Token { public fun withdraw(coin: &mut Coin, amount: u64): Coin { if (coin.value >= amount) () else abort 10; coin.value = coin.value - amount; - Coin{type: *&coin.type,value: amount} + Coin{type: *&coin.type, value: amount} } } module 0x3::OneToOneMarket { + use std::signer; use 0x2::Map; use 0x2::Token; struct BorrowRecord has key { @@ -342,10 +343,7 @@ module 0x3::OneToOneMarket { price: u64, } public fun borrow(account: &signer, pool_owner: address, amount: u64): Token::Coin - acquires Price - acquires Pool - acquires DepositRecord - acquires BorrowRecord + acquires BorrowRecord, DepositRecord, Pool, Price { if (amount <= max_borrow_amount(account, pool_owner)) () else abort 1025; update_borrow_record(account, pool_owner, amount); @@ -353,8 +351,7 @@ module 0x3::OneToOneMarket { Token::withdraw(&mut pool.coin, amount) } public fun deposit(account: &signer, pool_owner: address, coin: Token::Coin) - acquires Pool - acquires DepositRecord + acquires DepositRecord, Pool { let amount = Token::value(&coin); update_deposit_record(account, pool_owner, amount); @@ -364,7 +361,7 @@ module 0x3::OneToOneMarket { fun accept(account: &signer, init: Token::Coin) { let sender = 0x1::signer::address_of(account); if (!exists>(sender)) () else abort 42; - move_to>(account, Pool{coin: init}) + move_to>(Pool{coin: init}, account) } fun borrowed_amount(account: &signer, pool_owner: address): u64 acquires BorrowRecord @@ -383,10 +380,7 @@ module 0x3::OneToOneMarket { if (Map::contains_key(record, &pool_owner)) *Map::get(record, &pool_owner) else 0 } fun max_borrow_amount(account: &signer, pool_owner: address): u64 - acquires Price - acquires Pool - acquires DepositRecord - acquires BorrowRecord + acquires BorrowRecord, DepositRecord, Pool, Price { let input_deposited = deposited_amount(account, pool_owner); let output_deposited = borrowed_amount(account, pool_owner); @@ -401,13 +395,13 @@ module 0x3::OneToOneMarket { public fun register_price(account: &signer, initial_in: Token::Coin, initial_out: Token::Coin, price: u64) { accept(account, initial_in); accept(account, initial_out); - move_to>(account, Price{price: price}) + move_to>(Price{price: price}, account) } fun update_borrow_record(account: &signer, pool_owner: address, amount: u64) acquires BorrowRecord { let sender = 0x1::signer::address_of(account); - if (!exists>(sender)) move_to>(account, BorrowRecord{record: Map::empty()}); + if (!exists>(sender)) move_to>(BorrowRecord{record: Map::empty()}, account); let record = &mut borrow_global_mut>(sender).record; if (Map::contains_key(/*freeze*/record, &pool_owner)) { let old_amount = Map::remove(/*freeze*/record, &pool_owner); @@ -419,7 +413,7 @@ module 0x3::OneToOneMarket { acquires DepositRecord { let sender = 0x1::signer::address_of(account); - if (!exists>(sender)) move_to>(account, DepositRecord{record: Map::empty()}); + if (!exists>(sender)) move_to>(DepositRecord{record: Map::empty()}, account); let record = &mut borrow_global_mut>(sender).record; if (Map::contains_key(/*freeze*/record, &pool_owner)) { let old_amount = Map::remove(/*freeze*/record, &pool_owner); @@ -430,22 +424,23 @@ module 0x3::OneToOneMarket { } module 0x70dd::ToddNickels { use 0x2::Token; + use std::signer; struct T has copy, drop, store { } struct Wallet has key { nickels: Token::Coin, } public fun init(account: &signer) { - if (0x1::signer::address_of(account) == 0x70dd) () else abort 42; - move_to(account, Wallet{nickels: Token::create(T{}, 0)}) + if (0x1::signer::address_of(account) == @0x70dd) () else abort 42; + move_to(Wallet{nickels: Token::create(T{}, 0)}, account) } public fun destroy(c: Token::Coin) acquires Wallet { - Token::deposit(&mut borrow_global_mut(0x70dd).nickels, c) + Token::deposit(&mut borrow_global_mut(@0x70dd).nickels, c) } public fun mint(account: &signer): Token::Coin { - if (0x1::signer::address_of(account) == 0x70dd) () else abort 42; + if (0x1::signer::address_of(account) == @0x70dd) () else abort 42; Token::create(T{}, 5) } } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp index 96163e889e7..b8d3ce40a5e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/v1-examples/simple_money_market_token.exp @@ -253,18 +253,18 @@ module 0x2::Token { value: u64, } public fun create(type: ATy, value: u64): Coin { - Coin{type: type,value: value} + Coin{type: type, value: value} } public fun value(coin: &Coin): u64 { coin.value } public fun deposit(coin: &mut Coin, check: Coin) { - let Coin{type: type,value: value} = check; + let Coin{type: type, value: value} = check; if (&coin.type == &type) () else abort 42; coin.value = coin.value + value; } public fun destroy_zero(coin: Coin) { - let Coin{type: _,value: value} = coin; + let Coin{type: _, value: value} = coin; if (value == 0) () else abort 11 } public fun join(xus: Coin, coin2: Coin): Coin { @@ -278,31 +278,33 @@ module 0x2::Token { public fun withdraw(coin: &mut Coin, amount: u64): Coin { if (coin.value >= amount) () else abort 10; coin.value = coin.value - amount; - Coin{type: *&coin.type,value: amount} + Coin{type: *&coin.type, value: amount} } } module 0x70dd::ToddNickels { use 0x2::Token; + use std::signer; struct T has copy, drop, store { } struct Wallet has key { nickels: Token::Coin, } public fun init(account: &signer) { - if (0x1::signer::address_of(account) == 0x70dd) () else abort 42; - move_to(account, Wallet{nickels: Token::create(T{}, 0)}) + if (0x1::signer::address_of(account) == @0x70dd) () else abort 42; + move_to(Wallet{nickels: Token::create(T{}, 0)}, account) } public fun destroy(c: Token::Coin) acquires Wallet { - Token::deposit(&mut borrow_global_mut(0x70dd).nickels, c) + Token::deposit(&mut borrow_global_mut(@0x70dd).nickels, c) } public fun mint(account: &signer): Token::Coin { - if (0x1::signer::address_of(account) == 0x70dd) () else abort 42; + if (0x1::signer::address_of(account) == @0x70dd) () else abort 42; Token::create(T{}, 5) } } module 0xb055::OneToOneMarket { + use std::signer; use 0x2::Token; struct BorrowRecord has key { record: u64, @@ -317,29 +319,25 @@ module 0xb055::OneToOneMarket { price: u64, } public fun borrow(account: &signer, amount: u64): Token::Coin - acquires Price - acquires Pool - acquires DepositRecord - acquires BorrowRecord + acquires BorrowRecord, DepositRecord, Pool, Price { if (amount <= max_borrow_amount(account)) () else abort 1025; update_borrow_record(account, amount); - let pool = borrow_global_mut>(0xb055); + let pool = borrow_global_mut>(@0xb055); Token::withdraw(&mut pool.coin, amount) } public fun deposit(account: &signer, coin: Token::Coin) - acquires Pool - acquires DepositRecord + acquires DepositRecord, Pool { let amount = Token::value(&coin); update_deposit_record(account, amount); - let pool = borrow_global_mut>(0xb055); + let pool = borrow_global_mut>(@0xb055); Token::deposit(&mut pool.coin, coin) } fun accept(account: &signer, init: Token::Coin) { let sender = 0x1::signer::address_of(account); if (!exists>(sender)) () else abort 42; - move_to>(account, Pool{coin: init}) + move_to>(Pool{coin: init}, account) } fun borrowed_amount(account: &signer): u64 acquires BorrowRecord @@ -356,33 +354,30 @@ module 0xb055::OneToOneMarket { borrow_global>(sender).record } fun max_borrow_amount(account: &signer): u64 - acquires Price - acquires Pool - acquires DepositRecord - acquires BorrowRecord + acquires BorrowRecord, DepositRecord, Pool, Price { let input_deposited = deposited_amount(account); let output_deposited = borrowed_amount(account); - let input_into_output = input_deposited * borrow_global>(0xb055).price; + let input_into_output = input_deposited * borrow_global>(@0xb055).price; let max_output = if (input_into_output < output_deposited) 0 else input_into_output - output_deposited; let available_output = { - let pool = borrow_global>(0xb055); + let pool = borrow_global>(@0xb055); Token::value(&pool.coin) }; if (max_output < available_output) max_output else available_output } public fun register_price(account: &signer, initial_in: Token::Coin, initial_out: Token::Coin, price: u64) { let sender = 0x1::signer::address_of(account); - if (sender == 0xb055) () else abort 42; + if (sender == @0xb055) () else abort 42; accept(account, initial_in); accept(account, initial_out); - move_to>(account, Price{price: price}) + move_to>(Price{price: price}, account) } fun update_borrow_record(account: &signer, amount: u64) acquires BorrowRecord { let sender = 0x1::signer::address_of(account); - if (!exists>(sender)) move_to>(account, BorrowRecord{record: 0}); + if (!exists>(sender)) move_to>(BorrowRecord{record: 0}, account); let record = &mut borrow_global_mut>(sender).record; *record = *record + amount } @@ -390,7 +385,7 @@ module 0xb055::OneToOneMarket { acquires DepositRecord { let sender = 0x1::signer::address_of(account); - if (!exists>(sender)) move_to>(account, DepositRecord{record: 0}); + if (!exists>(sender)) move_to>(DepositRecord{record: 0}, account); let record = &mut borrow_global_mut>(sender).record; *record = *record + amount } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/values.exp b/third_party/move/move-compiler-v2/tests/checking/typing/values.exp index ed565f3c015..b65ba386692 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/values.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/values.exp @@ -13,7 +13,7 @@ module 0x8675309::M { // -- Sourcified model before first bytecode pipeline module 0x8675309::M { fun t() { - 0x1; + @0x1; 0; 10000; true; diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/vector_basic_cases.exp b/third_party/move/move-compiler-v2/tests/checking/typing/vector_basic_cases.exp index d27b8a6f206..d73726343f2 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/vector_basic_cases.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/vector_basic_cases.exp @@ -37,7 +37,7 @@ module 0x42::Test { vector[0u8, 1u8, 2u8]; vector[0, 1, 2]; vector[0u128, 1u128, 2u128]; - vector[0x0, 0x1]; + vector[@0x0, @0x1]; vector[X{}, X{}]; vector[vector[], vector[]]; vector[vector[vector[], vector[]], vector[]]; @@ -49,7 +49,7 @@ module 0x42::Test { vector[0u8]; vector[0]; vector[0u128]; - vector[0x0]; + vector[@0x0]; vector[X{}]; vector[vector[]]; vector[vector[vector[]]]; diff --git a/third_party/move/move-compiler-v2/tests/checking/unused/unused_enum.exp b/third_party/move/move-compiler-v2/tests/checking/unused/unused_enum.exp index 3c334d1945c..dcffb2ac58e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/unused/unused_enum.exp +++ b/third_party/move/move-compiler-v2/tests/checking/unused/unused_enum.exp @@ -14,6 +14,7 @@ module 0x42::enum_types { // -- Sourcified model before first bytecode pipeline module 0x42::enum_types { + use std::string; enum MessageHolder has drop, key { Empty, Message { diff --git a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_1.exp b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_1.exp index dbda03ef6b2..a2e5094ee9a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_1.exp +++ b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_1.exp @@ -43,7 +43,7 @@ module 0x815::m { } fun match(c: CommonFields): bool { match (c) { - CommonFields::Foo{x: x,y: _} => x > 0, + CommonFields::Foo{x: x, y: _} => x > 0, _ => false, } } diff --git a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_2.exp b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_2.exp index d101fe9f797..2e2b89afa08 100644 --- a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_2.exp +++ b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_2.exp @@ -45,9 +45,9 @@ module 0x815::m { match() } fun match(): bool { - let c = CommonFields::Foo{x: 0,y: 0u8}; + let c = CommonFields::Foo{x: 0, y: 0u8}; match (c) { - CommonFields::Foo{x: x,y: _} => x > 0, + CommonFields::Foo{x: x, y: _} => x > 0, _ => false, } } diff --git a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_3.exp b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_3.exp index 992abc4debc..ba8d2b49645 100644 --- a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_3.exp +++ b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_fun_3.exp @@ -43,7 +43,7 @@ module 0x815::m { } fun match(c: CommonFields, t: u64): bool { match (c) { - CommonFields::Foo{x: x,y: _} => x > t, + CommonFields::Foo{x: x, y: _} => x > t, _ => false, } } diff --git a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_var.exp b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_var.exp index 2825ba6be6e..3c49ed912c9 100644 --- a/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_var.exp +++ b/third_party/move/move-compiler-v2/tests/checking/variants/variants_allow_match_var.exp @@ -40,7 +40,7 @@ module 0x815::m { } fun match(c: CommonFields, t: u64): bool { match (c) { - CommonFields::Foo{x: x,y: _} => { + CommonFields::Foo{x: x, y: _} => { let match = x > t; match }, diff --git a/third_party/move/move-compiler-v2/tests/checking/variants/variants_ok.exp b/third_party/move/move-compiler-v2/tests/checking/variants/variants_ok.exp index 26ca7f79517..a2bad96b0d4 100644 --- a/third_party/move/move-compiler-v2/tests/checking/variants/variants_ok.exp +++ b/third_party/move/move-compiler-v2/tests/checking/variants/variants_ok.exp @@ -245,61 +245,61 @@ module 0x815::m { } fun t1(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t1_address_qualified(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t1_field_named(self: Color): bool { match (self) { - Color::RGB{red: r,green: g,blue: blue} => r + g + blue > 0, + Color::RGB{red: r, green: g, blue: blue} => r + g + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t1_module_qualified(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t1_uses_block(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t1_uses_block_no_comma(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, Color::Red{} => true, Color::Blue{} => false, } } fun t2(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red + green + blue > 0, + Color::RGB{red: red, green: green, blue: blue} => red + green + blue > 0, _ => true, } } fun t3(self: Color): bool { match (&self) { - Color::RGB{red: red,green: green,blue: blue} => *red + *green + *blue > 0, + Color::RGB{red: red, green: green, blue: blue} => *red + *green + *blue > 0, _ => true, } } fun t4(self: Color): Color { match (&mut self) { - Color::RGB{red: red,green: _,blue: _} => *red = 2, + Color::RGB{red: red, green: _, blue: _} => *red = 2, _ => (), }; self @@ -315,17 +315,17 @@ module 0x815::m { } fun t6_construct(self: Color): Color { match (self) { - Color::RGB{red: red,green: green,blue: blue} => Color::RGB{red: red + 1,green: green - 1,blue: blue}, + Color::RGB{red: red, green: green, blue: blue} => Color::RGB{red: red + 1, green: green - 1, blue: blue}, _ => self, } } fun t7_let_unpack(self: Color): u64 { - let Color::RGB{red: red,green: green,blue: blue} = self; + let Color::RGB{red: red, green: green, blue: blue} = self; red + green + blue } fun t8_unqualified_variant(self: Color): bool { match (self) { - Color::RGB{red: red,green: green,blue: blue} => red != green && green != blue, + Color::RGB{red: red, green: green, blue: blue} => red != green && green != blue, Color::Red{} => true, Color::Blue{} => false, } diff --git a/third_party/move/move-compiler-v2/tests/checking/visibility-checker/module_call_visibility_friend.exp b/third_party/move/move-compiler-v2/tests/checking/visibility-checker/module_call_visibility_friend.exp index ce99185267e..e74f658ed36 100644 --- a/third_party/move/move-compiler-v2/tests/checking/visibility-checker/module_call_visibility_friend.exp +++ b/third_party/move/move-compiler-v2/tests/checking/visibility-checker/module_call_visibility_friend.exp @@ -61,8 +61,8 @@ module 0x2::X { } } module 0x2::M { - use 0x2::Y; use 0x2::X; + use 0x2::Y; friend fun f_friend() { } public fun f_public() { diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.off.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.off.exp index 318743e3a2c..f0c5644041b 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.off.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.off.exp @@ -1,195 +1,184 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips(l0: vector) + local l1: &vector + local l2: u64 + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l4: copy_loc l2 + // @5 + copy_loc l1 + vec_len + lt + br_false l0 + copy_loc l1 + // @10 + copy_loc l2 + vec_borrow + read_ref + ld_u8 0 + neq + // @15 + br_false l1 + move_loc l1 + pop + branch l2 +l1: move_loc l2 + // @20 + ld_u64 1 + add + st_loc l2 + branch l3 +l0: move_loc l1 + // @25 + pop + branch l2 +l3: branch l4 +l2: ret + +// Function definition at index 1 +#[persistent] entry public fun guess_flips_directly(l0: vector) + local l1: u64 + ld_u64 0 + st_loc l1 +l4: copy_loc l1 + borrow_loc l0 + vec_len + // @5 + lt + br_false l0 + borrow_loc l0 + copy_loc l1 + vec_borrow + // @10 + read_ref + ld_u8 0 + neq + br_false l1 + branch l2 + // @15 +l1: move_loc l1 + ld_u64 1 + add + st_loc l1 + branch l3 + // @20 +l0: branch l2 +l3: branch l4 +l2: ret + +// Function definition at index 2 +#[persistent] entry public fun guess_with_break_without_inline(l0: vector) + borrow_loc l0 + call loops_with_break_no_inline + ret + +// Function definition at index 3 +#[persistent] entry public fun guess_without_break_with_inline(l0: vector) + local l1: &vector + local l2: u64 + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l5: copy_loc l2 + // @5 + copy_loc l1 + vec_len + lt + br_false l0 + copy_loc l1 + // @10 + copy_loc l2 + vec_borrow + read_ref + ld_u8 0 + eq + // @15 + br_false l1 + branch l2 +l1: move_loc l1 + pop + ld_u64 3 + // @20 + abort +l2: move_loc l2 + ld_u64 1 + add + st_loc l2 + // @25 + branch l3 +l0: move_loc l1 + pop + branch l4 +l3: branch l5 + // @30 +l4: ret + +// Function definition at index 4 +fun loops_with_break_no_inline(l0: &vector) + local l1: u64 + ld_u64 0 + st_loc l1 +l4: copy_loc l1 + copy_loc l0 + vec_len + // @5 + lt + br_false l0 + copy_loc l0 + copy_loc l1 + vec_borrow + // @10 + read_ref + ld_u8 0 + neq + br_false l1 + move_loc l0 + // @15 + pop + branch l2 +l1: move_loc l1 + ld_u64 1 + add + // @20 + st_loc l1 + branch l3 +l0: move_loc l0 + pop + branch l2 + // @25 +l3: branch l4 +l2: ret + +// Function definition at index 5 +fun test_guess_directly() + ld_const> [0, 0, 0, 0] + call guess_flips_directly + ret + +// Function definition at index 6 +fun test_guess_with_break_no_inline() + ld_const> [0, 0, 0, 0] + call guess_with_break_without_inline + ret + +// Function definition at index 7 +fun test_guess_with_inline_break() + ld_const> [0, 0, 0, 0] + call guess_flips + ret + +// Function definition at index 8 +fun test_guess_without_break() + ld_const> [0, 0, 0, 0] + call guess_without_break_with_inline + ret -entry public guess_flips(flips: vector) /* def_idx: 0 */ { -L1: $t2: &vector -L2: i: u64 -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: StLoc[1]($t2: &vector) - 2: LdU64(0) - 3: StLoc[2](i: u64) -B1: - 4: CopyLoc[2](i: u64) - 5: CopyLoc[1]($t2: &vector) - 6: VecLen(2) - 7: Lt - 8: BrFalse(24) -B2: - 9: CopyLoc[1]($t2: &vector) - 10: CopyLoc[2](i: u64) - 11: VecImmBorrow(2) - 12: ReadRef - 13: LdU8(0) - 14: Neq - 15: BrFalse(19) -B3: - 16: MoveLoc[1]($t2: &vector) - 17: Pop - 18: Branch(28) -B4: - 19: MoveLoc[2](i: u64) - 20: LdU64(1) - 21: Add - 22: StLoc[2](i: u64) - 23: Branch(27) -B5: - 24: MoveLoc[1]($t2: &vector) - 25: Pop - 26: Branch(28) -B6: - 27: Branch(4) -B7: - 28: Ret -} -entry public guess_flips_directly(flips: vector) /* def_idx: 1 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: ImmBorrowLoc[0](flips: vector) - 4: VecLen(2) - 5: Lt - 6: BrFalse(20) -B2: - 7: ImmBorrowLoc[0](flips: vector) - 8: CopyLoc[1](i: u64) - 9: VecImmBorrow(2) - 10: ReadRef - 11: LdU8(0) - 12: Neq - 13: BrFalse(15) -B3: - 14: Branch(22) -B4: - 15: MoveLoc[1](i: u64) - 16: LdU64(1) - 17: Add - 18: StLoc[1](i: u64) - 19: Branch(21) -B5: - 20: Branch(22) -B6: - 21: Branch(2) -B7: - 22: Ret -} -entry public guess_with_break_without_inline(flips: vector) /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: Call loops_with_break_no_inline(&vector) - 2: Ret -} -entry public guess_without_break_with_inline(flips: vector) /* def_idx: 3 */ { -L1: $t2: &vector -L2: i: u64 -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: StLoc[1]($t2: &vector) - 2: LdU64(0) - 3: StLoc[2](i: u64) -B1: - 4: CopyLoc[2](i: u64) - 5: CopyLoc[1]($t2: &vector) - 6: VecLen(2) - 7: Lt - 8: BrFalse(26) -B2: - 9: CopyLoc[1]($t2: &vector) - 10: CopyLoc[2](i: u64) - 11: VecImmBorrow(2) - 12: ReadRef - 13: LdU8(0) - 14: Eq - 15: BrFalse(17) -B3: - 16: Branch(21) -B4: - 17: MoveLoc[1]($t2: &vector) - 18: Pop - 19: LdU64(3) - 20: Abort -B5: - 21: MoveLoc[2](i: u64) - 22: LdU64(1) - 23: Add - 24: StLoc[2](i: u64) - 25: Branch(29) -B6: - 26: MoveLoc[1]($t2: &vector) - 27: Pop - 28: Branch(30) -B7: - 29: Branch(4) -B8: - 30: Ret -} -loops_with_break_no_inline(flips: &vector) /* def_idx: 4 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: CopyLoc[0](flips: &vector) - 4: VecLen(2) - 5: Lt - 6: BrFalse(22) -B2: - 7: CopyLoc[0](flips: &vector) - 8: CopyLoc[1](i: u64) - 9: VecImmBorrow(2) - 10: ReadRef - 11: LdU8(0) - 12: Neq - 13: BrFalse(17) -B3: - 14: MoveLoc[0](flips: &vector) - 15: Pop - 16: Branch(26) -B4: - 17: MoveLoc[1](i: u64) - 18: LdU64(1) - 19: Add - 20: StLoc[1](i: u64) - 21: Branch(25) -B5: - 22: MoveLoc[0](flips: &vector) - 23: Pop - 24: Branch(26) -B6: - 25: Branch(2) -B7: - 26: Ret -} -test_guess_directly() /* def_idx: 5 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_flips_directly(vector) - 2: Ret -} -test_guess_with_break_no_inline() /* def_idx: 6 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_with_break_without_inline(vector) - 2: Ret -} -test_guess_with_inline_break() /* def_idx: 7 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_flips(vector) - 2: Ret -} -test_guess_without_break() /* def_idx: 8 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_without_break_with_inline(vector) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.on.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.on.exp index 843fc45e77a..fb08b25463b 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.on.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/bug-10253.on.exp @@ -179,27 +179,26 @@ fun vectors::loops_with_break_no_inline($t0: &vector) { 2: $t3 := copy($t1) 3: $t4 := vector::length($t0) 4: $t2 := <($t3, $t4) - 5: if ($t2) goto 6 else goto 23 + 5: if ($t2) goto 6 else goto 22 6: label L2 7: $t8 := copy($t0) 8: $t7 := vector::borrow($t8, $t1) 9: $t6 := read_ref($t7) 10: $t9 := 0 11: $t5 := !=($t6, $t9) - 12: if ($t5) goto 13 else goto 17 + 12: if ($t5) goto 13 else goto 16 13: label L5 14: drop($t0) - 15: label L1 - 16: return () - 17: label L7 - 18: $t11 := move($t1) - 19: $t12 := 1 - 20: $t10 := +($t11, $t12) - 21: $t1 := move($t10) - 22: goto 1 - 23: label L3 - 24: drop($t0) - 25: goto 15 + 15: return () + 16: label L7 + 17: $t11 := move($t1) + 18: $t12 := 1 + 19: $t10 := +($t11, $t12) + 20: $t1 := move($t10) + 21: goto 1 + 22: label L3 + 23: drop($t0) + 24: return () } @@ -240,182 +239,175 @@ fun vectors::test_guess_without_break() { ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips(l0: vector) + local l1: &vector + local l2: u64 + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l2: copy_loc l2 + // @5 + copy_loc l1 + vec_len + lt + br_false l0 + copy_loc l1 + // @10 + copy_loc l2 + vec_borrow + read_ref + ld_u8 0 + neq + // @15 + br_false l1 + move_loc l1 + pop +l3: ret +l1: move_loc l2 + // @20 + ld_u64 1 + add + st_loc l2 + branch l2 +l0: move_loc l1 + // @25 + pop + branch l3 + +// Function definition at index 1 +#[persistent] entry public fun guess_flips_directly(l0: vector) + local l1: u64 + ld_u64 0 + st_loc l1 +l3: copy_loc l1 + borrow_loc l0 + vec_len + // @5 + lt + br_true l0 + branch l1 +l0: borrow_loc l0 + copy_loc l1 + // @10 + vec_borrow + read_ref + ld_u8 0 + neq + br_false l2 + // @15 + branch l1 +l1: ret +l2: move_loc l1 + ld_u64 1 + add + // @20 + st_loc l1 + branch l3 + +// Function definition at index 2 +#[persistent] entry public fun guess_with_break_without_inline(l0: vector) + borrow_loc l0 + call loops_with_break_no_inline + ret + +// Function definition at index 3 +#[persistent] entry public fun guess_without_break_with_inline(l0: vector) + local l1: &vector + local l2: u64 + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l2: copy_loc l2 + // @5 + copy_loc l1 + vec_len + lt + br_false l0 + copy_loc l1 + // @10 + copy_loc l2 + vec_borrow + read_ref + ld_u8 0 + eq + // @15 + br_false l1 + move_loc l2 + ld_u64 1 + add + st_loc l2 + // @20 + branch l2 +l1: move_loc l1 + pop + ld_u64 3 + abort + // @25 +l0: move_loc l1 + pop + ret + +// Function definition at index 4 +fun loops_with_break_no_inline(l0: &vector) + local l1: u64 + ld_u64 0 + st_loc l1 +l2: copy_loc l1 + copy_loc l0 + vec_len + // @5 + lt + br_false l0 + copy_loc l0 + copy_loc l1 + vec_borrow + // @10 + read_ref + ld_u8 0 + neq + br_false l1 + move_loc l0 + // @15 + pop + ret +l1: move_loc l1 + ld_u64 1 + add + // @20 + st_loc l1 + branch l2 +l0: move_loc l0 + pop + ret + +// Function definition at index 5 +fun test_guess_directly() + ld_const> [0, 0, 0, 0] + call guess_flips_directly + ret + +// Function definition at index 6 +fun test_guess_with_break_no_inline() + ld_const> [0, 0, 0, 0] + call guess_with_break_without_inline + ret + +// Function definition at index 7 +fun test_guess_with_inline_break() + ld_const> [0, 0, 0, 0] + call guess_flips + ret + +// Function definition at index 8 +fun test_guess_without_break() + ld_const> [0, 0, 0, 0] + call guess_without_break_with_inline + ret -entry public guess_flips(flips: vector) /* def_idx: 0 */ { -L1: $t2: &vector -L2: i: u64 -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: StLoc[1]($t2: &vector) - 2: LdU64(0) - 3: StLoc[2](i: u64) -B1: - 4: CopyLoc[2](i: u64) - 5: CopyLoc[1]($t2: &vector) - 6: VecLen(2) - 7: Lt - 8: BrFalse(24) -B2: - 9: CopyLoc[1]($t2: &vector) - 10: CopyLoc[2](i: u64) - 11: VecImmBorrow(2) - 12: ReadRef - 13: LdU8(0) - 14: Neq - 15: BrFalse(19) -B3: - 16: MoveLoc[1]($t2: &vector) - 17: Pop -B4: - 18: Ret -B5: - 19: MoveLoc[2](i: u64) - 20: LdU64(1) - 21: Add - 22: StLoc[2](i: u64) - 23: Branch(4) -B6: - 24: MoveLoc[1]($t2: &vector) - 25: Pop - 26: Branch(18) -} -entry public guess_flips_directly(flips: vector) /* def_idx: 1 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: ImmBorrowLoc[0](flips: vector) - 4: VecLen(2) - 5: Lt - 6: BrTrue(8) -B2: - 7: Branch(16) -B3: - 8: ImmBorrowLoc[0](flips: vector) - 9: CopyLoc[1](i: u64) - 10: VecImmBorrow(2) - 11: ReadRef - 12: LdU8(0) - 13: Neq - 14: BrFalse(17) -B4: - 15: Branch(16) -B5: - 16: Ret -B6: - 17: MoveLoc[1](i: u64) - 18: LdU64(1) - 19: Add - 20: StLoc[1](i: u64) - 21: Branch(2) -} -entry public guess_with_break_without_inline(flips: vector) /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: Call loops_with_break_no_inline(&vector) - 2: Ret -} -entry public guess_without_break_with_inline(flips: vector) /* def_idx: 3 */ { -L1: $t2: &vector -L2: i: u64 -B0: - 0: ImmBorrowLoc[0](flips: vector) - 1: StLoc[1]($t2: &vector) - 2: LdU64(0) - 3: StLoc[2](i: u64) -B1: - 4: CopyLoc[2](i: u64) - 5: CopyLoc[1]($t2: &vector) - 6: VecLen(2) - 7: Lt - 8: BrFalse(25) -B2: - 9: CopyLoc[1]($t2: &vector) - 10: CopyLoc[2](i: u64) - 11: VecImmBorrow(2) - 12: ReadRef - 13: LdU8(0) - 14: Eq - 15: BrFalse(21) -B3: - 16: MoveLoc[2](i: u64) - 17: LdU64(1) - 18: Add - 19: StLoc[2](i: u64) - 20: Branch(4) -B4: - 21: MoveLoc[1]($t2: &vector) - 22: Pop - 23: LdU64(3) - 24: Abort -B5: - 25: MoveLoc[1]($t2: &vector) - 26: Pop - 27: Ret -} -loops_with_break_no_inline(flips: &vector) /* def_idx: 4 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: CopyLoc[0](flips: &vector) - 4: VecLen(2) - 5: Lt - 6: BrFalse(22) -B2: - 7: CopyLoc[0](flips: &vector) - 8: CopyLoc[1](i: u64) - 9: VecImmBorrow(2) - 10: ReadRef - 11: LdU8(0) - 12: Neq - 13: BrFalse(17) -B3: - 14: MoveLoc[0](flips: &vector) - 15: Pop -B4: - 16: Ret -B5: - 17: MoveLoc[1](i: u64) - 18: LdU64(1) - 19: Add - 20: StLoc[1](i: u64) - 21: Branch(2) -B6: - 22: MoveLoc[0](flips: &vector) - 23: Pop - 24: Branch(16) -} -test_guess_directly() /* def_idx: 5 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_flips_directly(vector) - 2: Ret -} -test_guess_with_break_no_inline() /* def_idx: 6 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_with_break_without_inline(vector) - 2: Ret -} -test_guess_with_inline_break() /* def_idx: 7 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_flips(vector) - 2: Ret -} -test_guess_without_break() /* def_idx: 8 */ { -B0: - 0: LdConst[0](Vector(U8): [4, 0, 0, 0, 0]) - 1: Call guess_without_break_with_inline(vector) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.off.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.off.exp index dd9e1b1b746..9d7ddd46ab5 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.off.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.off.exp @@ -1,67 +1,63 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -use 0000000000000000000000000000000000000000000000000000000000000001::string; +// Bytecode version v9 +module 0x42::test +use 0x1::string +// Function definition at index 0 +fun test(l0: vector): T0 + local l1: string::String + call foo + st_loc l1 + copy_loc l1 + ld_const> [98, 111, 111, 108] + call string::utf8 + // @5 + eq + br_false l0 + move_loc l0 + call baz + call bar + // @10 + ret +l0: copy_loc l1 + ld_const> [117, 56] + call string::utf8 + eq + // @15 + br_false l1 + move_loc l0 + call baz + call bar + ret + // @20 +l1: move_loc l1 + ld_const> [117, 54, 52] + call string::utf8 + eq + br_false l2 + // @25 + move_loc l0 + call baz + call bar + ret +l2: ld_u64 0 + // @30 + abort +// Function definition at index 1 +fun bar(l0: bool): T0 + ld_u64 0 + abort +// Function definition at index 2 +fun baz(l0: vector): T0 + ld_u64 0 + abort + +// Function definition at index 3 +fun foo(): string::String + ld_u64 0 + abort -test(x: vector): T /* def_idx: 0 */ { -L1: y: String -B0: - 0: Call foo(): String - 1: StLoc[1](y: String) - 2: CopyLoc[1](y: String) - 3: LdConst[0](Vector(U8): [4, 98, 111, 111, 108]) - 4: Call string::utf8(vector): String - 5: Eq - 6: BrFalse(11) -B1: - 7: MoveLoc[0](x: vector) - 8: Call baz(vector): bool - 9: Call bar(bool): T - 10: Ret -B2: - 11: CopyLoc[1](y: String) - 12: LdConst[1](Vector(U8): [2, 117, 56]) - 13: Call string::utf8(vector): String - 14: Eq - 15: BrFalse(20) -B3: - 16: MoveLoc[0](x: vector) - 17: Call baz(vector): bool - 18: Call bar(bool): T - 19: Ret -B4: - 20: MoveLoc[1](y: String) - 21: LdConst[2](Vector(U8): [3, 117, 54, 52]) - 22: Call string::utf8(vector): String - 23: Eq - 24: BrFalse(29) -B5: - 25: MoveLoc[0](x: vector) - 26: Call baz(vector): bool - 27: Call bar(bool): T - 28: Ret -B6: - 29: LdU64(0) - 30: Abort -} -bar(_x: bool): T /* def_idx: 1 */ { -B0: - 0: LdU64(0) - 1: Abort -} -baz(_x: vector): T /* def_idx: 2 */ { -B0: - 0: LdU64(0) - 1: Abort -} -foo(): String /* def_idx: 3 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.on.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.on.exp index bc79decdaf6..09d192855e9 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.on.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/jump-label.on.exp @@ -84,68 +84,64 @@ fun test::foo<#0>(): 0x1::string::String { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -use 0000000000000000000000000000000000000000000000000000000000000001::string; +// Bytecode version v9 +module 0x42::test +use 0x1::string +// Function definition at index 0 +fun test(l0: vector): T0 + local l1: string::String + call foo + st_loc l1 + copy_loc l1 + ld_const> [98, 111, 111, 108] + call string::utf8 + // @5 + eq + br_false l0 + move_loc l0 + call baz + call bar + // @10 + ret +l0: copy_loc l1 + ld_const> [117, 56] + call string::utf8 + eq + // @15 + br_false l1 + move_loc l0 + call baz + call bar + ret + // @20 +l1: move_loc l1 + ld_const> [117, 54, 52] + call string::utf8 + eq + br_false l2 + // @25 + move_loc l0 + call baz + call bar + ret +l2: ld_u64 0 + // @30 + abort +// Function definition at index 1 +fun bar(l0: bool): T0 + ld_u64 0 + abort +// Function definition at index 2 +fun baz(l0: vector): T0 + ld_u64 0 + abort + +// Function definition at index 3 +fun foo(): string::String + ld_u64 0 + abort -test(x: vector): T /* def_idx: 0 */ { -L1: y: String -B0: - 0: Call foo(): String - 1: StLoc[1](y: String) - 2: CopyLoc[1](y: String) - 3: LdConst[0](Vector(U8): [4, 98, 111, 111, 108]) - 4: Call string::utf8(vector): String - 5: Eq - 6: BrFalse(11) -B1: - 7: MoveLoc[0](x: vector) - 8: Call baz(vector): bool - 9: Call bar(bool): T - 10: Ret -B2: - 11: CopyLoc[1](y: String) - 12: LdConst[1](Vector(U8): [2, 117, 56]) - 13: Call string::utf8(vector): String - 14: Eq - 15: BrFalse(20) -B3: - 16: MoveLoc[0](x: vector) - 17: Call baz(vector): bool - 18: Call bar(bool): T - 19: Ret -B4: - 20: MoveLoc[1](y: String) - 21: LdConst[2](Vector(U8): [3, 117, 54, 52]) - 22: Call string::utf8(vector): String - 23: Eq - 24: BrFalse(29) -B5: - 25: MoveLoc[0](x: vector) - 26: Call baz(vector): bool - 27: Call bar(bool): T - 28: Ret -B6: - 29: LdU64(0) - 30: Abort -} -bar(_x: bool): T /* def_idx: 1 */ { -B0: - 0: LdU64(0) - 1: Abort -} -baz(_x: vector): T /* def_idx: 2 */ { -B0: - 0: LdU64(0) - 1: Abort -} -foo(): String /* def_idx: 3 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.off.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.off.exp index 3cb0925e672..a98b4e3a878 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.off.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.off.exp @@ -1,12 +1,10 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { +// Bytecode version v9 +module 0x42::test +// Function definition at index 0 +fun test() +l0: branch l0 -test() /* def_idx: 0 */ { -B0: - 0: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.on.exp b/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.on.exp index 8da4949cdfa..8168fc51ed5 100644 --- a/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.on.exp +++ b/third_party/move/move-compiler-v2/tests/control-flow-simplification/loop.on.exp @@ -8,13 +8,11 @@ fun test::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { +// Bytecode version v9 +module 0x42::test +// Function definition at index 0 +fun test() +l0: branch l0 -test() /* def_idx: 0 */ { -B0: - 0: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp index fc66bb2fb5e..9212e7f41a1 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp @@ -1,73 +1,73 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:6:16 │ 6 │ public fun simple_recursion() { │ ^^^^^^^^^^^^^^^^ │ - = `simple_recursion` calls `simple_recursion>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:7 + = `simple_recursion` uses `simple_recursion>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:7 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:10:9 │ 10 │ fun two_level_recursion_0() { │ ^^^^^^^^^^^^^^^^^^^^^ │ - = `two_level_recursion_0` calls `two_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 - = `two_level_recursion_1` calls `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 + = `two_level_recursion_0` uses `two_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 + = `two_level_recursion_1` uses `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:14:9 │ 14 │ fun two_level_recursion_1() { │ ^^^^^^^^^^^^^^^^^^^^^ │ - = `two_level_recursion_1` calls `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 - = `two_level_recursion_0>` calls `two_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 + = `two_level_recursion_1` uses `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 + = `two_level_recursion_0>` uses `two_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:18:9 │ 18 │ fun three_level_recursion_0() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_0` calls `three_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 - = `three_level_recursion_1` calls `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0` uses `three_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1` uses `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:22:9 │ 22 │ fun three_level_recursion_1() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_1` calls `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 - = `three_level_recursion_0>` calls `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1` uses `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0>` uses `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:26:9 │ 26 │ fun three_level_recursion_2() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 - = `three_level_recursion_0>` calls `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 - = `three_level_recursion_1>` calls `three_level_recursion_2>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0>` uses `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1>` uses `three_level_recursion_2>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:30:9 │ 30 │ fun recurse_at_different_position() { │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ - = `recurse_at_different_position` calls `recurse_at_different_position>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:31 + = `recurse_at_different_position` uses `recurse_at_different_position>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:31 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:44:9 │ 44 │ fun test_vec() { │ ^^^^^^^^ │ - = `test_vec` calls `test_vec>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:45 + = `test_vec` uses `test_vec>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:45 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp index 1bb77ca0c24..bdcefbc06a5 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp @@ -1,29 +1,29 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:13:9 │ 13 │ fun c() { │ ^ │ - = `c` calls `d` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:15 - = `d` calls `b` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:20 - = `b` calls `c, bool>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:10 + = `c` uses `d` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:15 + = `d` uses `b` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:20 + = `b` uses `c, bool>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:10 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:26:9 │ 26 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 - = `g` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 + = `g` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:30:9 │ 30 │ fun g() { │ ^ │ - = `g` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 - = `f>` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 + = `g` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 + = `f>` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp index a4cbf1c179a..05c0c6f6181 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp @@ -1,31 +1,31 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 - = `f>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:12:9 │ 12 │ fun h() { │ ^ │ - = `h` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp index db55cc263c7..0e648a2662f 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp @@ -1,31 +1,31 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 - = `f>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:12:9 │ 12 │ fun h() { │ ^ │ - = `h` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp index 1066db9abfa..60e6e631e75 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp @@ -1,19 +1,19 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 - = `g` calls `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 + = `g` uses `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 - = `f, u64>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 + = `g` uses `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 + = `f, u64>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp index 13dda3ae7a1..54bbcd1fc45 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp @@ -1,19 +1,19 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:7:9 │ 7 │ fun f() { │ ^ │ - = `f` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 - = `g>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 + = `f` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 + = `g>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:11:9 │ 11 │ fun g() { │ ^ │ - = `g` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 - = `f` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 + = `g` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 + = `f` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp index 4c7b9af8fd5..619423018bb 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:4:9 │ 4 │ fun foo() { │ ^^^ │ - = `foo` calls `foo>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:5 + = `foo` uses `foo>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:5 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp index 4b510f95aa1..61579012c93 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:5:9 │ 5 │ fun foo() { │ ^^^ │ - = `foo` calls `foo>>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:6 + = `foo` uses `foo>>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:6 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp index aa91ac66ecc..cfa8904c56c 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:9:9 │ 9 │ fun f(n: u64, x: T): T { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:11 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:11 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp index e9041a1b054..cabf5fe3277 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:6:9 │ 6 │ fun f(x: T) { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:7 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:7 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp index 4892af9de9b..4c485cb8f74 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:7:9 │ 7 │ fun f(a: T1, x: T2) { │ ^ │ - = `f` calls `f, T1>` at tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:8 + = `f` uses `f, T1>` at tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:8 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp index ca960a47c8c..4c8de7b9532 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp @@ -1,17 +1,17 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/two_loops.move:7:9 │ 7 │ fun f() { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:8 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:8 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/two_loops.move:11:9 │ 11 │ fun g() { │ ^ │ - = `g` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:12 + = `g` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:12 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp index b5a0ebd9a7c..2d97f6c2360 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp @@ -1,139 +1,139 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:6:16 │ 6 │ public fun t() { │ ^ │ - = `t` calls `t>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:7 + = `t` uses `t>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:7 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:10:16 │ 10 │ public fun x() { │ ^ │ - = `x` calls `y>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 - = `y>` calls `x>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 + = `x` uses `y>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 + = `y>` uses `x>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:13:16 │ 13 │ public fun y() { │ ^ │ - = `y` calls `x>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 - = `x>` calls `y>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 + = `y` uses `x>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 + = `x>` uses `y>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:17:16 │ 17 │ public fun a() { │ ^ │ - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:20:16 │ 20 │ public fun b() { │ ^ │ - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:23:16 │ 23 │ public fun c() { │ ^ │ - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 - = `b>` calls `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b>` uses `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:37:16 │ 37 │ public fun z() { │ ^ │ - = `z` calls `z>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:38 + = `z` uses `z>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:38 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:41:16 │ 41 │ public fun a() { │ ^ │ - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:44:16 │ 44 │ public fun b() { │ ^ │ - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:47:16 │ 47 │ public fun c() { │ ^ │ - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b>` calls `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b>` uses `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:50:16 │ 50 │ public fun d() { │ ^ │ - = `d` calls `a` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d` uses `a` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:58:16 │ 58 │ public fun tl() { │ ^^ │ - = `tl` calls `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 - = `bl>` calls `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl` uses `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl>` uses `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:61:16 │ 61 │ public fun tr() { │ ^^ │ - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 - = `bl>` calls `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 - = `tl>` calls `tr>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl>` uses `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl>` uses `tr>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:68:16 │ 68 │ public fun bl() { │ ^^ │ - = `bl` calls `tl` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 - = `tl` calls `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl` uses `tl` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl` uses `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp index 1f42c0af5eb..7ef8ffc633b 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp @@ -200,36 +200,35 @@ fun m::one(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -bar(_x: &mut u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_x: &mut u64) - 1: Pop - 2: Ret -} -baz(_x: u64, _y: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public foo(x: u64) /* def_idx: 2 */ { -L1: t: u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](t: u64) - 2: MutBorrowLoc[0](x: u64) - 3: Call bar(&mut u64) - 4: MoveLoc[0](x: u64) - 5: MoveLoc[1](t: u64) - 6: Call baz(u64, u64) - 7: Ret -} -one(): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(1) - 1: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: &mut u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun baz(l0: u64, l1: u64) + ret + +// Function definition at index 2 +#[persistent] public fun foo(l0: u64) + local l1: u64 + call one + st_loc l1 + mut_borrow_loc l0 + call bar + move_loc l0 + // @5 + move_loc l1 + call baz + ret + +// Function definition at index 3 +fun one(): u64 + ld_u64 1 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp index 9bc21ce137b..dbae760680e 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp @@ -238,19 +238,17 @@ public fun m::test($t0: u64) { # live vars: $t0, $t1 4: $t2 := >($t0, $t1) # live vars: $t2 - 5: if ($t2) goto 8 else goto 6 - # live vars: - 6: label L3 + 5: if ($t2) goto 6 else goto 9 # live vars: - 7: goto 10 + 6: label L0 # live vars: - 8: label L0 + 7: m::foo() # live vars: - 9: m::foo() + 8: return () # live vars: - 10: label L2 + 9: label L2 # live vars: - 11: return () + 10: return () } @@ -265,41 +263,38 @@ fun m::two(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo() + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u64) + local l1: u64 + call two + st_loc l1 + move_loc l0 + call one + sub + // @5 + move_loc l1 + gt + br_false l0 + call foo + ret + // @10 +l0: ret + +// Function definition at index 3 +fun two(): u64 + ld_u64 2 + ret -foo() /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(p: u64) /* def_idx: 2 */ { -L1: e: u64 -B0: - 0: Call two(): u64 - 1: StLoc[1](e: u64) - 2: MoveLoc[0](p: u64) - 3: Call one(): u64 - 4: Sub - 5: MoveLoc[1](e: u64) - 6: Gt - 7: BrTrue(9) -B1: - 8: Branch(10) -B2: - 9: Call foo() -B3: - 10: Ret -} -two(): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(2) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp index c9ad2bcc4ad..c4ead05cb04 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp @@ -131,30 +131,30 @@ public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: &0xc0ffee::m::S, $t4: u64) ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64 -} -struct Wrap { - a: u64, - b: u64, - c: u64, - d: u64, - e: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + +struct Wrap + a: u64 + b: u64 + c: u64 + d: u64 + e: u64 + +// Function definition at index 0 +#[persistent] public fun make(l0: u64, l1: u64, l2: u64, l3: &S, l4: u64): Wrap + move_loc l0 + move_loc l1 + move_loc l2 + move_loc l3 + borrow_field S, x + // @5 + read_ref + move_loc l4 + pack Wrap + ret + -public make(a: u64, b: u64, c: u64, d: &S, e: u64): Wrap /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: u64) - 1: MoveLoc[1](b: u64) - 2: MoveLoc[2](c: u64) - 3: MoveLoc[3](d: &S) - 4: ImmBorrowField[0](S.x: u64) - 5: ReadRef - 6: MoveLoc[4](e: u64) - 7: Pack[1](Wrap) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp index 1601b678f23..389b71c0b8a 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp @@ -197,39 +197,40 @@ public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: address, $t4: u64): 0xc0ff ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has key { - x: u64, - y: u64 -} -struct Wrap { - a: u64, - b: u64, - c: u64, - d: u64, - e: u64, - f: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has key + x: u64 + y: u64 + +struct Wrap + a: u64 + b: u64 + c: u64 + d: u64 + e: u64 + f: u64 + +// Function definition at index 0 +#[persistent] public fun make(l0: u64, l1: u64, l2: u64, l3: address, l4: u64): Wrap acquires S + local l5: &S + move_loc l3 + borrow_global S + st_loc l5 + move_loc l0 + move_loc l1 + // @5 + move_loc l2 + copy_loc l5 + borrow_field S, x + read_ref + move_loc l4 + // @10 + move_loc l5 + borrow_field S, y + read_ref + pack Wrap + ret + -public make(a: u64, b: u64, c: u64, d: address, e: u64): Wrap /* def_idx: 0 */ { -L5: ref: &S -B0: - 0: MoveLoc[3](d: address) - 1: ImmBorrowGlobal[0](S) - 2: StLoc[5](ref: &S) - 3: MoveLoc[0](a: u64) - 4: MoveLoc[1](b: u64) - 5: MoveLoc[2](c: u64) - 6: CopyLoc[5](ref: &S) - 7: ImmBorrowField[0](S.x: u64) - 8: ReadRef - 9: MoveLoc[4](e: u64) - 10: MoveLoc[5](ref: &S) - 11: ImmBorrowField[1](S.y: u64) - 12: ReadRef - 13: Pack[1](Wrap) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp index c7c3bf2e3ea..4754af2e94c 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp @@ -293,45 +293,46 @@ fun m::zero($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct Wrap has drop, key { - a: u64, - b: u64, - c: u64, - d: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct Wrap has drop + key + a: u64 + b: u64 + c: u64 + d: u64 + +// Function definition at index 0 +fun bar(l0: &signer, l1: &mut u64, l2: Wrap) + move_loc l0 + pop + move_loc l1 + pop + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: signer, l1: address) acquires Wrap + local l2: &mut Wrap + move_loc l1 + mut_borrow_global Wrap + st_loc l2 + borrow_loc l0 + move_loc l2 + // @5 + mut_borrow_field Wrap, a + ld_u64 0 + ld_u64 0 + ld_u64 0 + call zero + // @10 + ld_u64 0 + pack Wrap + call bar + ret + +// Function definition at index 2 +fun zero(l0: u64): u64 + ld_u64 0 + ret + -bar(_x: &signer, _y: &mut u64, _w: Wrap) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_x: &signer) - 1: Pop - 2: MoveLoc[1](_y: &mut u64) - 3: Pop - 4: Ret -} -public test(x: signer, a: address) /* def_idx: 1 */ { -L2: ref: &mut Wrap -B0: - 0: MoveLoc[1](a: address) - 1: MutBorrowGlobal[0](Wrap) - 2: StLoc[2](ref: &mut Wrap) - 3: ImmBorrowLoc[0](x: signer) - 4: MoveLoc[2](ref: &mut Wrap) - 5: MutBorrowField[0](Wrap.a: u64) - 6: LdU64(0) - 7: LdU64(0) - 8: LdU64(0) - 9: Call zero(u64): u64 - 10: LdU64(0) - 11: Pack[0](Wrap) - 12: Call bar(&signer, &mut u64, Wrap) - 13: Ret -} -zero(_y: u64): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(0) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp index 44cd67bba0c..848a890b80d 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp @@ -208,30 +208,30 @@ public fun m::test($t0: &signer, $t1: 0xc0ffee::m::S) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has drop { - a: u64, - b: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has drop + a: u64 + b: u64 + +// Function definition at index 0 +fun foo(l0: &signer, l1: u64, l2: u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: &signer, l1: S) + move_loc l0 + borrow_loc l1 + borrow_field S, a + read_ref + borrow_loc l1 + // @5 + borrow_field S, b + read_ref + call foo + ret + -foo(_x: &signer, _y: u64, _z: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_x: &signer) - 1: Pop - 2: Ret -} -public test(x: &signer, y: S) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: &signer) - 1: ImmBorrowLoc[1](y: S) - 2: ImmBorrowField[0](S.a: u64) - 3: ReadRef - 4: ImmBorrowLoc[1](y: S) - 5: ImmBorrowField[1](S.b: u64) - 6: ReadRef - 7: Call foo(&signer, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp index 7d5b48bf6c4..f3f6720798f 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp @@ -520,69 +520,71 @@ public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: 0xc0ffee::m::S) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + +// Function definition at index 0 +fun bar(l0: &mut S, l1: u64): u64 + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, x + st_loc l2 + copy_loc l1 + move_loc l2 + // @5 + write_ref + move_loc l1 + ret + +// Function definition at index 1 +fun destroy(l0: S) + move_loc l0 + unpack S + pop + ret + +// Function definition at index 2 +fun foo(l0: &mut S, l1: u64) + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, x + st_loc l2 + move_loc l1 + move_loc l2 + // @5 + write_ref + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: &mut S, l1: S) + local l2: u64 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + ld_u64 42 + lt + // @5 + br_false l0 + copy_loc l0 + mut_borrow_loc l1 + copy_loc l2 + call bar + // @10 + call foo + move_loc l2 + ld_u64 1 + add + st_loc l2 + // @15 + branch l1 +l0: move_loc l0 + pop + move_loc l1 + call destroy + // @20 + ret + -bar(r: &mut S, i: u64): u64 /* def_idx: 0 */ { -L2: $t3: &mut u64 -B0: - 0: MoveLoc[0](r: &mut S) - 1: MutBorrowField[0](S.x: u64) - 2: StLoc[2]($t3: &mut u64) - 3: CopyLoc[1](i: u64) - 4: MoveLoc[2]($t3: &mut u64) - 5: WriteRef - 6: MoveLoc[1](i: u64) - 7: Ret -} -destroy(s: S) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[0](S) - 2: Pop - 3: Ret -} -foo(l: &mut S, i: u64) /* def_idx: 2 */ { -L2: $t2: &mut u64 -B0: - 0: MoveLoc[0](l: &mut S) - 1: MutBorrowField[0](S.x: u64) - 2: StLoc[2]($t2: &mut u64) - 3: MoveLoc[1](i: u64) - 4: MoveLoc[2]($t2: &mut u64) - 5: WriteRef - 6: Ret -} -public test(l: &mut S, r: S) /* def_idx: 3 */ { -L2: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[2](i: u64) -B1: - 2: CopyLoc[2](i: u64) - 3: LdU64(42) - 4: Lt - 5: BrFalse(16) -B2: - 6: CopyLoc[0](l: &mut S) - 7: MutBorrowLoc[1](r: S) - 8: CopyLoc[2](i: u64) - 9: Call bar(&mut S, u64): u64 - 10: Call foo(&mut S, u64) - 11: MoveLoc[2](i: u64) - 12: LdU64(1) - 13: Add - 14: StLoc[2](i: u64) - 15: Branch(2) -B3: - 16: MoveLoc[0](l: &mut S) - 17: Pop - 18: MoveLoc[1](r: S) - 19: Call destroy(S) - 20: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp index 8fcb21be859..7631232bd01 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp @@ -338,45 +338,46 @@ public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64, - y: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + y: u64 + +// Function definition at index 0 +fun bar(l0: &mut u64, l1: u64) + move_loc l1 + move_loc l0 + write_ref + ret + +// Function definition at index 1 +fun foo(l0: &mut u64, l1: u64): &mut u64 + move_loc l1 + copy_loc l0 + write_ref + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: &mut S, l1: u64) + copy_loc l0 + mut_borrow_field S, x + copy_loc l1 + copy_loc l0 + borrow_field S, y + // @5 + read_ref + div + call foo + move_loc l1 + move_loc l0 + // @10 + borrow_field S, y + read_ref + div + call bar + ret + -bar(r: &mut u64, i: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: MoveLoc[0](r: &mut u64) - 2: WriteRef - 3: Ret -} -foo(l: &mut u64, i: u64): &mut u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: CopyLoc[0](l: &mut u64) - 2: WriteRef - 3: MoveLoc[0](l: &mut u64) - 4: Ret -} -public test(s: &mut S, i: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](s: &mut S) - 1: MutBorrowField[0](S.x: u64) - 2: CopyLoc[1](i: u64) - 3: CopyLoc[0](s: &mut S) - 4: ImmBorrowField[1](S.y: u64) - 5: ReadRef - 6: Div - 7: Call foo(&mut u64, u64): &mut u64 - 8: MoveLoc[1](i: u64) - 9: MoveLoc[0](s: &mut S) - 10: ImmBorrowField[1](S.y: u64) - 11: ReadRef - 12: Div - 13: Call bar(&mut u64, u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp index 70ef4566402..e0a94c3ea6e 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp @@ -318,41 +318,42 @@ public fun m::test($t0: &0xc0ffee::m::S, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64, - y: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + y: u64 + +// Function definition at index 0 +fun bar(l0: &u64, l1: u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun foo(l0: &u64, l1: u64): &u64 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: &S, l1: u64) + copy_loc l0 + borrow_field S, x + copy_loc l1 + copy_loc l0 + borrow_field S, y + // @5 + read_ref + div + call foo + move_loc l1 + move_loc l0 + // @10 + borrow_field S, y + read_ref + div + call bar + ret + -bar(_r: &u64, _i: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_r: &u64) - 1: Pop - 2: Ret -} -foo(l: &u64, _i: u64): &u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](l: &u64) - 1: Ret -} -public test(s: &S, i: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](s: &S) - 1: ImmBorrowField[0](S.x: u64) - 2: CopyLoc[1](i: u64) - 3: CopyLoc[0](s: &S) - 4: ImmBorrowField[1](S.y: u64) - 5: ReadRef - 6: Div - 7: Call foo(&u64, u64): &u64 - 8: MoveLoc[1](i: u64) - 9: MoveLoc[0](s: &S) - 10: ImmBorrowField[1](S.y: u64) - 11: ReadRef - 12: Div - 13: Call bar(&u64, u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp index 90a69cb6b65..bc5fdab27c1 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp @@ -424,7 +424,7 @@ public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) { # live vars: $t0, $t1, $t2, $t5, $t8 8: $t4 := ==($t5, $t8) # live vars: $t0, $t1, $t2, $t4 - 9: if ($t4) goto 10 else goto 16 + 9: if ($t4) goto 10 else goto 15 # live vars: $t0, $t1, $t2 10: label L0 # live vars: $t0, $t1, $t2 @@ -434,77 +434,75 @@ public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) { # live vars: $t1, $t12 13: m::baz($t12, $t1) # live vars: - 14: label L2 - # live vars: - 15: return () + 14: return () # live vars: $t0, $t1, $t2 - 16: label L1 + 15: label L1 # live vars: $t0 - 17: drop($t0) + 16: drop($t0) # live vars: - 18: goto 14 + 17: return () } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64, - y: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + y: u64 + +// Function definition at index 0 +fun bar(l0: &mut u64, l1: u64): &mut u64 + move_loc l1 + copy_loc l0 + write_ref + move_loc l0 + ret + +// Function definition at index 1 +fun baz(l0: &mut u64, l1: u64) + move_loc l1 + move_loc l0 + write_ref + ret + +// Function definition at index 2 +fun foo(l0: &u64): u64 + move_loc l0 + read_ref + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: &mut S, l1: u64) + local l2: u64 + copy_loc l0 + borrow_field S, x + call foo + st_loc l2 + copy_loc l0 + // @5 + borrow_field S, x + read_ref + copy_loc l2 + copy_loc l0 + borrow_field S, y + // @10 + read_ref + mul + eq + br_false l0 + move_loc l0 + // @15 + mut_borrow_field S, x + move_loc l2 + call bar + move_loc l1 + call baz + // @20 + ret +l0: move_loc l0 + pop + ret + -bar(r: &mut u64, i: u64): &mut u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: CopyLoc[0](r: &mut u64) - 2: WriteRef - 3: MoveLoc[0](r: &mut u64) - 4: Ret -} -baz(r: &mut u64, i: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: MoveLoc[0](r: &mut u64) - 2: WriteRef - 3: Ret -} -foo(l: &u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](l: &u64) - 1: ReadRef - 2: Ret -} -public test(s: &mut S, v: u64) /* def_idx: 3 */ { -L2: n: u64 -B0: - 0: CopyLoc[0](s: &mut S) - 1: ImmBorrowField[0](S.x: u64) - 2: Call foo(&u64): u64 - 3: StLoc[2](n: u64) - 4: CopyLoc[0](s: &mut S) - 5: ImmBorrowField[0](S.x: u64) - 6: ReadRef - 7: CopyLoc[2](n: u64) - 8: CopyLoc[0](s: &mut S) - 9: ImmBorrowField[1](S.y: u64) - 10: ReadRef - 11: Mul - 12: Eq - 13: BrFalse(21) -B1: - 14: MoveLoc[0](s: &mut S) - 15: MutBorrowField[0](S.x: u64) - 16: MoveLoc[2](n: u64) - 17: Call bar(&mut u64, u64): &mut u64 - 18: MoveLoc[1](v: u64) - 19: Call baz(&mut u64, u64) -B2: - 20: Ret -B3: - 21: MoveLoc[0](s: &mut S) - 22: Pop - 23: Branch(20) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp index ffd1d23f0e9..358364e892c 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp @@ -517,61 +517,62 @@ public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64, - y: u64, - z: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + y: u64 + z: u64 + +// Function definition at index 0 +fun bar(l0: &mut u64, l1: u64) + move_loc l1 + move_loc l0 + write_ref + ret + +// Function definition at index 1 +fun foo(l0: &u64): u64 + move_loc l0 + read_ref + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: &mut S, l1: u64) + local l2: u64 + move_loc l1 + copy_loc l0 + borrow_field S, x + read_ref + div + // @5 + st_loc l1 + copy_loc l0 + borrow_field S, y + call foo + st_loc l2 + // @10 +l1: copy_loc l1 + copy_loc l2 + lt + br_false l0 + copy_loc l0 + // @15 + mut_borrow_field S, z + copy_loc l1 + ld_u64 1 + sub + call bar + // @20 + move_loc l1 + ld_u64 1 + add + st_loc l1 + branch l1 + // @25 +l0: move_loc l0 + pop + ret + -bar(r: &mut u64, i: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: MoveLoc[0](r: &mut u64) - 2: WriteRef - 3: Ret -} -foo(l: &u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](l: &u64) - 1: ReadRef - 2: Ret -} -public test(s: &mut S, i: u64) /* def_idx: 2 */ { -L2: $t4: u64 -B0: - 0: MoveLoc[1](i: u64) - 1: CopyLoc[0](s: &mut S) - 2: ImmBorrowField[0](S.x: u64) - 3: ReadRef - 4: Div - 5: StLoc[1](i: u64) - 6: CopyLoc[0](s: &mut S) - 7: ImmBorrowField[1](S.y: u64) - 8: Call foo(&u64): u64 - 9: StLoc[2]($t4: u64) -B1: - 10: CopyLoc[1](i: u64) - 11: CopyLoc[2]($t4: u64) - 12: Lt - 13: BrFalse(25) -B2: - 14: CopyLoc[0](s: &mut S) - 15: MutBorrowField[2](S.z: u64) - 16: CopyLoc[1](i: u64) - 17: LdU64(1) - 18: Sub - 19: Call bar(&mut u64, u64) - 20: MoveLoc[1](i: u64) - 21: LdU64(1) - 22: Add - 23: StLoc[1](i: u64) - 24: Branch(10) -B3: - 25: MoveLoc[0](s: &mut S) - 26: Pop - 27: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/move_stdlib_reduced.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/move_stdlib_reduced.exp index 702a35f55c2..00f46622c95 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/move_stdlib_reduced.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/move_stdlib_reduced.exp @@ -386,41 +386,39 @@ fun m::one(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: &mut u64, l1: u64) + move_loc l1 + move_loc l0 + write_ref + ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: &mut u64, l1: u64) +l1: copy_loc l1 + ld_u64 0 + gt + br_false l0 + copy_loc l0 + // @5 + call one + call bar + move_loc l1 + ld_u64 1 + sub + // @10 + st_loc l1 + branch l1 +l0: move_loc l0 + pop + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret -bar(x: &mut u64, i: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](i: u64) - 1: MoveLoc[0](x: &mut u64) - 2: WriteRef - 3: Ret -} -public foo(x: &mut u64, len: u64) /* def_idx: 1 */ { -B0: - 0: CopyLoc[1](len: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(12) -B1: - 4: CopyLoc[0](x: &mut u64) - 5: Call one(): u64 - 6: Call bar(&mut u64, u64) - 7: MoveLoc[1](len: u64) - 8: LdU64(1) - 9: Sub - 10: StLoc[1](len: u64) - 11: Branch(0) -B2: - 12: MoveLoc[0](x: &mut u64) - 13: Pop - 14: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/txn_reduced_01.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/txn_reduced_01.exp index 74cf9a92caa..31c1b792c68 100644 --- a/third_party/move/move-compiler-v2/tests/eager-pushes/txn_reduced_01.exp +++ b/third_party/move/move-compiler-v2/tests/eager-pushes/txn_reduced_01.exp @@ -481,56 +481,57 @@ public fun m::test($t0: &signer, $t1: vector
, $t2: vector) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun call_other(l0: &signer, l1: address, l2: u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: &signer, l1: vector
, l2: vector) + local l3: u64 + local l4: u64 + local l5: &address + local l6: &u64 + borrow_loc l1 + vec_len
+ st_loc l3 + ld_u64 0 + st_loc l4 + // @5 +l1: copy_loc l4 + copy_loc l3 + lt + br_false l0 + borrow_loc l1 + // @10 + copy_loc l4 + vec_borrow
+ st_loc l5 + borrow_loc l2 + copy_loc l4 + // @15 + vec_borrow + st_loc l6 + copy_loc l0 + move_loc l5 + read_ref + // @20 + move_loc l6 + read_ref + call call_other + move_loc l4 + ld_u64 1 + // @25 + add + st_loc l4 + branch l1 +l0: move_loc l0 + pop + // @30 + ret -call_other(_from: &signer, _to: address, _amount: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_from: &signer) - 1: Pop - 2: Ret -} -public test(from: &signer, to_vec: vector
, amount_vec: vector) /* def_idx: 1 */ { -L3: len: u64 -L4: i: u64 -L5: to: &address -L6: amount: &u64 -B0: - 0: ImmBorrowLoc[1](to_vec: vector
) - 1: VecLen(3) - 2: StLoc[3](len: u64) - 3: LdU64(0) - 4: StLoc[4](i: u64) -B1: - 5: CopyLoc[4](i: u64) - 6: CopyLoc[3](len: u64) - 7: Lt - 8: BrFalse(28) -B2: - 9: ImmBorrowLoc[1](to_vec: vector
) - 10: CopyLoc[4](i: u64) - 11: VecImmBorrow(3) - 12: StLoc[5](to: &address) - 13: ImmBorrowLoc[2](amount_vec: vector) - 14: CopyLoc[4](i: u64) - 15: VecImmBorrow(4) - 16: StLoc[6](amount: &u64) - 17: CopyLoc[0](from: &signer) - 18: MoveLoc[5](to: &address) - 19: ReadRef - 20: MoveLoc[6](amount: &u64) - 21: ReadRef - 22: Call call_other(&signer, address, u64) - 23: MoveLoc[4](i: u64) - 24: LdU64(1) - 25: Add - 26: StLoc[4](i: u64) - 27: Branch(5) -B3: - 28: MoveLoc[0](from: &signer) - 29: Pop - 30: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp index 353cbb3e951..1054c131217 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp @@ -14,55 +14,57 @@ warning: Unused value of parameter `h`. Consider removing the parameter, or pref ============ disassembled file-format ================== -// Move bytecode v8 -module 42.assign { -struct T has drop { - h: u64 -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::assign +struct T has drop + h: u64 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun assign_field(l0: &mut S, l1: u64) + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, f + st_loc l2 + move_loc l1 + move_loc l2 + // @5 + write_ref + ret + +// Function definition at index 1 +fun assign_int(l0: &mut u64) + ld_u64 42 + move_loc l0 + write_ref + ret + +// Function definition at index 2 +fun assign_pattern(l0: S, l1: u64, l2: u64): u64 + move_loc l0 + unpack S + unpack T + st_loc l2 + st_loc l1 + // @5 + move_loc l1 + move_loc l2 + add + ret + +// Function definition at index 3 +fun assign_struct(l0: &mut S) + ld_u64 42 + ld_u64 42 + pack T + pack S + move_loc l0 + // @5 + write_ref + ret + -assign_field(s: &mut S, f: u64) /* def_idx: 0 */ { -L2: $t2: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: StLoc[2]($t2: &mut u64) - 3: MoveLoc[1](f: u64) - 4: MoveLoc[2]($t2: &mut u64) - 5: WriteRef - 6: Ret -} -assign_int(x: &mut u64) /* def_idx: 1 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut u64) - 2: WriteRef - 3: Ret -} -assign_pattern(s: S, f: u64, h: u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: StLoc[2](h: u64) - 4: StLoc[1](f: u64) - 5: MoveLoc[1](f: u64) - 6: MoveLoc[2](h: u64) - 7: Add - 8: Ret -} -assign_struct(s: &mut S) /* def_idx: 3 */ { -B0: - 0: LdU64(42) - 1: LdU64(42) - 2: Pack[0](T) - 3: Pack[1](S) - 4: MoveLoc[0](s: &mut S) - 5: WriteRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.opt.exp index d0a050d90ef..3269c94717e 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.opt.exp @@ -14,51 +14,52 @@ warning: Unused value of parameter `h`. Consider removing the parameter, or pref ============ disassembled file-format ================== -// Move bytecode v8 -module 42.assign { -struct T has drop { - h: u64 -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::assign +struct T has drop + h: u64 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun assign_field(l0: &mut S, l1: u64) + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, f + st_loc l2 + move_loc l1 + move_loc l2 + // @5 + write_ref + ret + +// Function definition at index 1 +fun assign_int(l0: &mut u64) + ld_u64 42 + move_loc l0 + write_ref + ret + +// Function definition at index 2 +fun assign_pattern(l0: S, l1: u64, l2: u64): u64 + move_loc l0 + unpack S + unpack T + add + ret + +// Function definition at index 3 +fun assign_struct(l0: &mut S) + ld_u64 42 + ld_u64 42 + pack T + pack S + move_loc l0 + // @5 + write_ref + ret + -assign_field(s: &mut S, f: u64) /* def_idx: 0 */ { -L2: $t2: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: StLoc[2]($t2: &mut u64) - 3: MoveLoc[1](f: u64) - 4: MoveLoc[2]($t2: &mut u64) - 5: WriteRef - 6: Ret -} -assign_int(x: &mut u64) /* def_idx: 1 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut u64) - 2: WriteRef - 3: Ret -} -assign_pattern(s: S, f: u64, h: u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: Add - 4: Ret -} -assign_struct(s: &mut S) /* def_idx: 3 */ { -B0: - 0: LdU64(42) - 1: LdU64(42) - 2: Pack[0](T) - 3: Pack[1](S) - 4: MoveLoc[0](s: &mut S) - 5: WriteRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp index bb1d2cff73b..4ada74061e6 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp @@ -14,82 +14,86 @@ warning: Unused value of parameter `param`. Consider removing the parameter, or ============ disassembled file-format ================== -// Move bytecode v8 -module 42.borrow { -struct S { - f: u64 -} +// Bytecode version v9 +module 0x42::borrow +struct S + f: u64 + +// Function definition at index 0 +fun field(l0: &S): u64 + move_loc l0 + borrow_field S, f + read_ref + ret + +// Function definition at index 1 +fun local(l0: u64): u64 + local l1: u64 + ld_u64 33 + st_loc l1 + borrow_loc l1 + read_ref + ret + +// Function definition at index 2 +fun param(l0: u64): u64 + borrow_loc l0 + read_ref + ret + +// Function definition at index 3 +fun mut_field(l0: &mut S): u64 + local l1: u64 + local l2: &mut u64 + move_loc l0 + mut_borrow_field S, f + ld_u64 22 + st_loc l1 + st_loc l2 + // @5 + move_loc l1 + copy_loc l2 + write_ref + move_loc l2 + read_ref + // @10 + ret + +// Function definition at index 4 +fun mut_local(l0: u64): u64 + local l1: u64 + local l2: u64 + local l3: &mut u64 + ld_u64 33 + st_loc l1 + mut_borrow_loc l1 + ld_u64 22 + st_loc l2 + // @5 + st_loc l3 + move_loc l2 + copy_loc l3 + write_ref + move_loc l3 + // @10 + read_ref + ret + +// Function definition at index 5 +fun mut_param(l0: u64): u64 + local l1: u64 + local l2: &mut u64 + mut_borrow_loc l0 + ld_u64 22 + st_loc l1 + st_loc l2 + move_loc l1 + // @5 + copy_loc l2 + write_ref + move_loc l2 + read_ref + ret + -field(s: &S): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](s: &S) - 1: ImmBorrowField[0](S.f: u64) - 2: ReadRef - 3: Ret -} -local(param: u64): u64 /* def_idx: 1 */ { -L1: $t3: u64 -B0: - 0: LdU64(33) - 1: StLoc[1]($t3: u64) - 2: ImmBorrowLoc[1]($t3: u64) - 3: ReadRef - 4: Ret -} -param(param: u64): u64 /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](param: u64) - 1: ReadRef - 2: Ret -} -mut_field(s: &mut S): u64 /* def_idx: 3 */ { -L1: $t3: u64 -L2: r: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: LdU64(22) - 3: StLoc[1]($t3: u64) - 4: StLoc[2](r: &mut u64) - 5: MoveLoc[1]($t3: u64) - 6: CopyLoc[2](r: &mut u64) - 7: WriteRef - 8: MoveLoc[2](r: &mut u64) - 9: ReadRef - 10: Ret -} -mut_local(param: u64): u64 /* def_idx: 4 */ { -L1: local: u64 -L2: $t4: u64 -L3: r: &mut u64 -B0: - 0: LdU64(33) - 1: StLoc[1](local: u64) - 2: MutBorrowLoc[1](local: u64) - 3: LdU64(22) - 4: StLoc[2]($t4: u64) - 5: StLoc[3](r: &mut u64) - 6: MoveLoc[2]($t4: u64) - 7: CopyLoc[3](r: &mut u64) - 8: WriteRef - 9: MoveLoc[3](r: &mut u64) - 10: ReadRef - 11: Ret -} -mut_param(param: u64): u64 /* def_idx: 5 */ { -L1: $t3: u64 -L2: r: &mut u64 -B0: - 0: MutBorrowLoc[0](param: u64) - 1: LdU64(22) - 2: StLoc[1]($t3: u64) - 3: StLoc[2](r: &mut u64) - 4: MoveLoc[1]($t3: u64) - 5: CopyLoc[2](r: &mut u64) - 6: WriteRef - 7: MoveLoc[2](r: &mut u64) - 8: ReadRef - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.opt.exp index fa324f1bd92..1440651411d 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.opt.exp @@ -14,73 +14,75 @@ warning: Unused value of parameter `param`. Consider removing the parameter, or ============ disassembled file-format ================== -// Move bytecode v8 -module 42.borrow { -struct S { - f: u64 -} +// Bytecode version v9 +module 0x42::borrow +struct S + f: u64 + +// Function definition at index 0 +fun field(l0: &S): u64 + move_loc l0 + borrow_field S, f + read_ref + ret + +// Function definition at index 1 +fun local(l0: u64): u64 + local l1: u64 + ld_u64 33 + st_loc l1 + borrow_loc l1 + read_ref + ret + +// Function definition at index 2 +fun param(l0: u64): u64 + borrow_loc l0 + read_ref + ret + +// Function definition at index 3 +fun mut_field(l0: &mut S): u64 + local l1: &mut u64 + move_loc l0 + mut_borrow_field S, f + st_loc l1 + ld_u64 22 + copy_loc l1 + // @5 + write_ref + move_loc l1 + read_ref + ret + +// Function definition at index 4 +fun mut_local(l0: u64): u64 + local l1: u64 + local l2: &mut u64 + ld_u64 33 + st_loc l1 + mut_borrow_loc l1 + st_loc l2 + ld_u64 22 + // @5 + copy_loc l2 + write_ref + move_loc l2 + read_ref + ret + +// Function definition at index 5 +fun mut_param(l0: u64): u64 + local l1: &mut u64 + mut_borrow_loc l0 + st_loc l1 + ld_u64 22 + copy_loc l1 + write_ref + // @5 + move_loc l1 + read_ref + ret + -field(s: &S): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](s: &S) - 1: ImmBorrowField[0](S.f: u64) - 2: ReadRef - 3: Ret -} -local(param: u64): u64 /* def_idx: 1 */ { -L1: $t3: u64 -B0: - 0: LdU64(33) - 1: StLoc[1]($t3: u64) - 2: ImmBorrowLoc[1]($t3: u64) - 3: ReadRef - 4: Ret -} -param(param: u64): u64 /* def_idx: 2 */ { -B0: - 0: ImmBorrowLoc[0](param: u64) - 1: ReadRef - 2: Ret -} -mut_field(s: &mut S): u64 /* def_idx: 3 */ { -L1: r: &mut u64 -B0: - 0: MoveLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: StLoc[1](r: &mut u64) - 3: LdU64(22) - 4: CopyLoc[1](r: &mut u64) - 5: WriteRef - 6: MoveLoc[1](r: &mut u64) - 7: ReadRef - 8: Ret -} -mut_local(param: u64): u64 /* def_idx: 4 */ { -L1: local: u64 -L2: r: &mut u64 -B0: - 0: LdU64(33) - 1: StLoc[1](local: u64) - 2: MutBorrowLoc[1](local: u64) - 3: StLoc[2](r: &mut u64) - 4: LdU64(22) - 5: CopyLoc[2](r: &mut u64) - 6: WriteRef - 7: MoveLoc[2](r: &mut u64) - 8: ReadRef - 9: Ret -} -mut_param(param: u64): u64 /* def_idx: 5 */ { -L1: r: &mut u64 -B0: - 0: MutBorrowLoc[0](param: u64) - 1: StLoc[1](r: &mut u64) - 2: LdU64(22) - 3: CopyLoc[1](r: &mut u64) - 4: WriteRef - 5: MoveLoc[1](r: &mut u64) - 6: ReadRef - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.exp index cd461a9d7c1..9d2ddb5a4ef 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.exp @@ -1,38 +1,37 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.Module0 { -struct Struct0 has copy, drop { - x: bool -} +// Bytecode version v9 +module 0xcafe::Module0 +struct Struct0 has copy + drop + x: bool + +// Function definition at index 0 +#[persistent] public fun function5(l0: bool, l1: bool) + local l2: &bool + local l3: bool + local l4: &bool + borrow_loc l0 + st_loc l2 + copy_loc l0 + br_false l0 + ld_true + // @5 + st_loc l3 + branch l1 +l0: move_loc l1 + st_loc l3 +l1: borrow_loc l3 + // @10 + st_loc l4 + move_loc l2 + move_loc l4 + neq + move_loc l0 + // @15 + pack Struct0 + pop + pop + ret + -public function5(var21: bool, var23: bool) /* def_idx: 0 */ { -L2: $t3: &bool -L3: $t5: bool -L4: $t4: &bool -B0: - 0: ImmBorrowLoc[0](var21: bool) - 1: StLoc[2]($t3: &bool) - 2: CopyLoc[0](var21: bool) - 3: BrFalse(7) -B1: - 4: LdTrue - 5: StLoc[3]($t5: bool) - 6: Branch(9) -B2: - 7: MoveLoc[1](var23: bool) - 8: StLoc[3]($t5: bool) -B3: - 9: ImmBorrowLoc[3]($t5: bool) - 10: StLoc[4]($t4: &bool) - 11: MoveLoc[2]($t3: &bool) - 12: MoveLoc[4]($t4: &bool) - 13: Neq - 14: MoveLoc[0](var21: bool) - 15: Pack[0](Struct0) - 16: Pop - 17: Pop - 18: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.opt.exp index 4cbc63f0060..2bedf3b336c 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance.opt.exp @@ -1,38 +1,37 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.Module0 { -struct Struct0 has copy, drop { - x: bool -} +// Bytecode version v9 +module 0xcafe::Module0 +struct Struct0 has copy + drop + x: bool + +// Function definition at index 0 +#[persistent] public fun function5(l0: bool, l1: bool) + local l2: &bool + local l3: bool + local l4: &bool + borrow_loc l0 + st_loc l2 + copy_loc l0 + br_false l0 + ld_true + // @5 + st_loc l3 +l1: borrow_loc l3 + st_loc l4 + move_loc l2 + move_loc l4 + // @10 + neq + pop + move_loc l0 + pack Struct0 + pop + // @15 + ret +l0: move_loc l1 + st_loc l3 + branch l1 + -public function5(var21: bool, var23: bool) /* def_idx: 0 */ { -L2: $t3: &bool -L3: $t5: bool -L4: $t4: &bool -B0: - 0: ImmBorrowLoc[0](var21: bool) - 1: StLoc[2]($t3: &bool) - 2: CopyLoc[0](var21: bool) - 3: BrFalse(16) -B1: - 4: LdTrue - 5: StLoc[3]($t5: bool) -B2: - 6: ImmBorrowLoc[3]($t5: bool) - 7: StLoc[4]($t4: &bool) - 8: MoveLoc[2]($t3: &bool) - 9: MoveLoc[4]($t4: &bool) - 10: Neq - 11: Pop - 12: MoveLoc[0](var21: bool) - 13: Pack[0](Struct0) - 14: Pop - 15: Ret -B3: - 16: MoveLoc[1](var23: bool) - 17: StLoc[3]($t5: bool) - 18: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.exp index 7fd2aa8d4bc..22dd72d7335 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.exp @@ -1,101 +1,86 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -enum Data has drop { - V1{ - x: u64 - }, - V2{ - x: u64, - y: bool - }, - V3{ +// Bytecode version v9 +module 0x42::m +enum Data has drop + V1 + x: u64 + V2 + x: u64 + y: bool + V3 + +// Function definition at index 0 +fun test_v1(): bool + local l0: Data + ld_u64 43 + pack_variant Data, V1 + st_loc l0 + borrow_loc l0 + test_variant Data, V1 + // @5 + ret + +// Function definition at index 1 +fun test_v1v3(): bool + local l0: Data + local l1: &Data + local l2: bool + local l3: Data + local l4: &Data + local l5: bool + ld_u64 43 + pack_variant Data, V1 + st_loc l0 + borrow_loc l0 + st_loc l1 + // @5 + copy_loc l1 + test_variant Data, V1 + st_loc l2 + copy_loc l2 + br_false l0 + // @10 + move_loc l1 + pop + branch l1 +l0: move_loc l1 + test_variant Data, V3 + // @15 + st_loc l2 + copy_loc l2 + br_false l1 + branch l1 +l1: pack_variant Data, V3 + // @20 + st_loc l3 + move_loc l2 + br_false l2 + borrow_loc l3 + st_loc l4 + // @25 + copy_loc l4 + test_variant Data, V1 + st_loc l5 + copy_loc l5 + br_false l3 + // @30 + move_loc l4 + pop + branch l4 +l3: move_loc l4 + test_variant Data, V3 + // @35 + st_loc l5 + copy_loc l5 + br_false l4 + branch l4 +l4: branch l5 + // @40 +l2: ld_false + st_loc l5 +l5: move_loc l5 + ret - } -} -test_v1(): bool /* def_idx: 0 */ { -L0: d: Data -L1: return: bool -B0: - 0: LdU64(43) - 1: PackVariant[0](Data/V1) - 2: StLoc[0](d: Data) - 3: ImmBorrowLoc[0](d: Data) - 4: TestVariant[0](Data/V1) - 5: StLoc[1](return: bool) - 6: CopyLoc[1](return: bool) - 7: BrFalse(9) -B1: - 8: Branch(9) -B2: - 9: MoveLoc[1](return: bool) - 10: Ret -} -test_v1v3(): bool /* def_idx: 1 */ { -L0: d: Data -L1: $t4: &Data -L2: t: bool -L3: d: Data -L4: $t6: &Data -L5: return: bool -B0: - 0: LdU64(43) - 1: PackVariant[0](Data/V1) - 2: StLoc[0](d: Data) - 3: ImmBorrowLoc[0](d: Data) - 4: StLoc[1]($t4: &Data) - 5: CopyLoc[1]($t4: &Data) - 6: TestVariant[0](Data/V1) - 7: StLoc[2](t: bool) - 8: CopyLoc[2](t: bool) - 9: BrFalse(13) -B1: - 10: MoveLoc[1]($t4: &Data) - 11: Pop - 12: Branch(19) -B2: - 13: MoveLoc[1]($t4: &Data) - 14: TestVariant[1](Data/V3) - 15: StLoc[2](t: bool) - 16: CopyLoc[2](t: bool) - 17: BrFalse(19) -B3: - 18: Branch(19) -B4: - 19: PackVariant[1](Data/V3) - 20: StLoc[3](d: Data) - 21: MoveLoc[2](t: bool) - 22: BrFalse(40) -B5: - 23: ImmBorrowLoc[3](d: Data) - 24: StLoc[4]($t6: &Data) - 25: CopyLoc[4]($t6: &Data) - 26: TestVariant[0](Data/V1) - 27: StLoc[5](return: bool) - 28: CopyLoc[5](return: bool) - 29: BrFalse(33) -B6: - 30: MoveLoc[4]($t6: &Data) - 31: Pop - 32: Branch(39) -B7: - 33: MoveLoc[4]($t6: &Data) - 34: TestVariant[1](Data/V3) - 35: StLoc[5](return: bool) - 36: CopyLoc[5](return: bool) - 37: BrFalse(39) -B8: - 38: Branch(39) -B9: - 39: Branch(42) -B10: - 40: LdFalse - 41: StLoc[5](return: bool) -B11: - 42: MoveLoc[5](return: bool) - 43: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.opt.exp index 0dcaeb82f65..03439dbcd0f 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_13952_stack_balance_regression.opt.exp @@ -1,84 +1,83 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -enum Data has drop { - V1{ - x: u64 - }, - V2{ - x: u64, - y: bool - }, - V3{ +// Bytecode version v9 +module 0x42::m +enum Data has drop + V1 + x: u64 + V2 + x: u64 + y: bool + V3 + +// Function definition at index 0 +fun test_v1(): bool + local l0: Data + ld_u64 43 + pack_variant Data, V1 + st_loc l0 + borrow_loc l0 + test_variant Data, V1 + // @5 + ret + +// Function definition at index 1 +fun test_v1v3(): bool + local l0: Data + local l1: &Data + local l2: bool + local l3: Data + local l4: &Data + local l5: bool + ld_u64 43 + pack_variant Data, V1 + st_loc l0 + borrow_loc l0 + st_loc l1 + // @5 + copy_loc l1 + test_variant Data, V1 + st_loc l2 + copy_loc l2 + br_false l0 + // @10 + move_loc l1 + pop +l5: pack_variant Data, V3 + st_loc l3 + move_loc l2 + // @15 + br_false l1 + borrow_loc l3 + st_loc l4 + copy_loc l4 + test_variant Data, V1 + // @20 + st_loc l5 + copy_loc l5 + br_false l2 + move_loc l4 + pop + // @25 +l4: move_loc l5 + ret +l2: move_loc l4 + test_variant Data, V3 + st_loc l5 + // @30 + copy_loc l5 + br_true l3 + branch l4 +l3: move_loc l5 + ret + // @35 +l1: ld_false + ret +l0: move_loc l1 + test_variant Data, V3 + st_loc l2 + // @40 + branch l5 - } -} -test_v1(): bool /* def_idx: 0 */ { -L0: d: Data -B0: - 0: LdU64(43) - 1: PackVariant[0](Data/V1) - 2: StLoc[0](d: Data) - 3: ImmBorrowLoc[0](d: Data) - 4: TestVariant[0](Data/V1) - 5: Ret -} -test_v1v3(): bool /* def_idx: 1 */ { -L0: d: Data -L1: $t4: &Data -L2: t: bool -L3: d: Data -L4: $t6: &Data -L5: return: bool -B0: - 0: LdU64(43) - 1: PackVariant[0](Data/V1) - 2: StLoc[0](d: Data) - 3: ImmBorrowLoc[0](d: Data) - 4: StLoc[1]($t4: &Data) - 5: CopyLoc[1]($t4: &Data) - 6: TestVariant[0](Data/V1) - 7: StLoc[2](t: bool) - 8: CopyLoc[2](t: bool) - 9: BrFalse(34) -B1: - 10: MoveLoc[1]($t4: &Data) - 11: Pop -B2: - 12: PackVariant[1](Data/V3) - 13: StLoc[3](d: Data) - 14: MoveLoc[2](t: bool) - 15: BrFalse(31) -B3: - 16: ImmBorrowLoc[3](d: Data) - 17: StLoc[4]($t6: &Data) - 18: CopyLoc[4]($t6: &Data) - 19: TestVariant[0](Data/V1) - 20: StLoc[5](return: bool) - 21: CopyLoc[5](return: bool) - 22: BrFalse(27) -B4: - 23: MoveLoc[4]($t6: &Data) - 24: Pop -B5: - 25: MoveLoc[5](return: bool) - 26: Ret -B6: - 27: MoveLoc[4]($t6: &Data) - 28: TestVariant[1](Data/V3) - 29: StLoc[5](return: bool) - 30: Branch(25) -B7: - 31: LdFalse - 32: StLoc[5](return: bool) - 33: Branch(25) -B8: - 34: MoveLoc[1]($t4: &Data) - 35: TestVariant[1](Data/V3) - 36: StLoc[2](t: bool) - 37: Branch(12) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.exp new file mode 100644 index 00000000000..f2e6be69dbe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.exp @@ -0,0 +1,26 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +struct S has copy + drop + store + key + dummy_field: bool + +// Function definition at index 0 +#[persistent] public fun function1() acquires S + ret + call function2 + ret + +// Function definition at index 1 +#[persistent] public fun function2() acquires S + local l0: &S + ld_const
48879 + borrow_global S + st_loc l0 + move_loc l0 + pop + // @5 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.move new file mode 100644 index 00000000000..10d308debb8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.move @@ -0,0 +1,12 @@ +module 0xCAFE::Module0 { + const ADDR: address = @0xBEEF; + struct S has copy, drop, store, key { } + + public fun function1() acquires S { + return; + function2(); + } + public fun function2() acquires S { + borrow_global(ADDR); + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.opt.exp new file mode 100644 index 00000000000..36b91a448ac --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14396.opt.exp @@ -0,0 +1,21 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +struct S has copy + drop + store + key + dummy_field: bool + +// Function definition at index 0 +#[persistent] public fun function1() + ret + +// Function definition at index 1 +#[persistent] public fun function2() acquires S + local l0: &S + ld_const
48879 + borrow_global S + pop + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.exp index 37aad2861fb..ee12d7241bb 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.exp @@ -1,102 +1,99 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -use 0000000000000000000000000000000000000000000000000000000000000001::option; -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0xc0ffee::m +use 0x1::option +use 0x1::vector +struct T has copy + drop + store + issuer: vector + version: u64 +struct J has copy + drop + store + variant: u64 + +struct S has copy + drop + store + entries: vector + +// Function definition at index 0 +fun test(l0: &mut S, l1: vector): option::Option + local l2: &vector + local l3: bool + local l4: u64 + local l5: u64 + local l6: u64 + local l7: u64 + local l8: bool + local l9: option::Option + copy_loc l0 + borrow_field S, entries + st_loc l2 + ld_false + st_loc l3 + // @5 + ld_u64 0 + st_loc l4 + ld_u64 0 + copy_loc l2 + vec_len + // @10 + st_loc l5 + st_loc l6 +l4: copy_loc l6 + copy_loc l5 + lt + // @15 + br_false l0 + copy_loc l2 + copy_loc l6 + vec_borrow + borrow_field T, issuer + // @20 + read_ref + copy_loc l1 + eq + br_false l1 + ld_true + // @25 + st_loc l3 + move_loc l6 + st_loc l4 + branch l2 + branch l1 + // @30 +l1: move_loc l6 + ld_u64 1 + add + st_loc l6 + branch l3 + // @35 +l0: branch l2 +l3: branch l4 +l2: nop + move_loc l2 + pop + // @40 + move_loc l3 + move_loc l4 + st_loc l7 + st_loc l8 + move_loc l8 + // @45 + br_false l5 + move_loc l0 + mut_borrow_field S, entries + move_loc l7 + call vector::remove + // @50 + call option::some + st_loc l9 + branch l6 +l5: move_loc l0 + pop + // @55 + call option::none + st_loc l9 +l6: move_loc l9 + ret -struct T has copy, drop, store { - issuer: vector, - version: u64 -} -struct J has copy, drop, store { - variant: u64 -} -struct S has copy, drop, store { - entries: vector -} -test(s: &mut S, issuer: vector): Option /* def_idx: 0 */ { -L2: v: &vector -L3: find: bool -L4: found_index: u64 -L5: len: u64 -L6: i: u64 -L7: index: u64 -L8: found: bool -L9: ret: Option -B0: - 0: CopyLoc[0](s: &mut S) - 1: ImmBorrowField[0](S.entries: vector) - 2: StLoc[2](v: &vector) - 3: LdFalse - 4: StLoc[3](find: bool) - 5: LdU64(0) - 6: StLoc[4](found_index: u64) - 7: LdU64(0) - 8: CopyLoc[2](v: &vector) - 9: VecLen(2) - 10: StLoc[5](len: u64) - 11: StLoc[6](i: u64) -B1: - 12: CopyLoc[6](i: u64) - 13: CopyLoc[5](len: u64) - 14: Lt - 15: BrFalse(35) -B2: - 16: CopyLoc[2](v: &vector) - 17: CopyLoc[6](i: u64) - 18: VecImmBorrow(2) - 19: ImmBorrowField[1](T.issuer: vector) - 20: ReadRef - 21: CopyLoc[1](issuer: vector) - 22: Eq - 23: BrFalse(30) -B3: - 24: LdTrue - 25: StLoc[3](find: bool) - 26: MoveLoc[6](i: u64) - 27: StLoc[4](found_index: u64) - 28: Branch(37) -B4: - 29: Branch(30) -B5: - 30: MoveLoc[6](i: u64) - 31: LdU64(1) - 32: Add - 33: StLoc[6](i: u64) - 34: Branch(36) -B6: - 35: Branch(37) -B7: - 36: Branch(12) -B8: - 37: Nop - 38: MoveLoc[2](v: &vector) - 39: Pop - 40: MoveLoc[3](find: bool) - 41: MoveLoc[4](found_index: u64) - 42: StLoc[7](index: u64) - 43: StLoc[8](found: bool) - 44: MoveLoc[8](found: bool) - 45: BrFalse(53) -B9: - 46: MoveLoc[0](s: &mut S) - 47: MutBorrowField[0](S.entries: vector) - 48: MoveLoc[7](index: u64) - 49: Call vector::remove(&mut vector, u64): T - 50: Call option::some(T): Option - 51: StLoc[9](ret: Option) - 52: Branch(57) -B10: - 53: MoveLoc[0](s: &mut S) - 54: Pop - 55: Call option::none(): Option - 56: StLoc[9](ret: Option) -B11: - 57: MoveLoc[9](ret: Option) - 58: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.opt.exp index fb915511d53..4436372b6cc 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14762.opt.exp @@ -1,94 +1,92 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -use 0000000000000000000000000000000000000000000000000000000000000001::option; -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0xc0ffee::m +use 0x1::option +use 0x1::vector +struct T has copy + drop + store + issuer: vector + version: u64 +struct J has copy + drop + store + variant: u64 + +struct S has copy + drop + store + entries: vector + +// Function definition at index 0 +fun test(l0: &mut S, l1: vector): option::Option + local l2: &vector + local l3: bool + local l4: u64 + local l5: u64 + local l6: u64 + local l7: u64 + local l8: option::Option + copy_loc l0 + borrow_field S, entries + st_loc l2 + ld_false + st_loc l3 + // @5 + ld_u64 0 + st_loc l4 + ld_u64 0 + st_loc l5 + copy_loc l2 + // @10 + vec_len + st_loc l6 +l5: copy_loc l5 + copy_loc l6 + lt + // @15 + br_true l0 + branch l1 +l0: copy_loc l2 + copy_loc l5 + vec_borrow + // @20 + borrow_field T, issuer + read_ref + copy_loc l1 + eq + br_false l2 + // @25 + ld_true + st_loc l3 + move_loc l5 + st_loc l4 +l1: nop + // @30 + move_loc l2 + pop + move_loc l3 + move_loc l4 + st_loc l7 + // @35 + br_false l3 + move_loc l0 + mut_borrow_field S, entries + move_loc l7 + call vector::remove + // @40 + call option::some + st_loc l8 +l4: move_loc l8 + ret +l3: move_loc l0 + // @45 + pop + call option::none + st_loc l8 + branch l4 +l2: move_loc l5 + // @50 + ld_u64 1 + add + st_loc l5 + branch l5 -struct T has copy, drop, store { - issuer: vector, - version: u64 -} -struct J has copy, drop, store { - variant: u64 -} -struct S has copy, drop, store { - entries: vector -} -test(s: &mut S, issuer: vector): Option /* def_idx: 0 */ { -L2: v: &vector -L3: find: bool -L4: found_index: u64 -L5: i: u64 -L6: len: u64 -L7: $t12: u64 -L8: ret: Option -B0: - 0: CopyLoc[0](s: &mut S) - 1: ImmBorrowField[0](S.entries: vector) - 2: StLoc[2](v: &vector) - 3: LdFalse - 4: StLoc[3](find: bool) - 5: LdU64(0) - 6: StLoc[4](found_index: u64) - 7: LdU64(0) - 8: StLoc[5](i: u64) - 9: CopyLoc[2](v: &vector) - 10: VecLen(2) - 11: StLoc[6](len: u64) -B1: - 12: CopyLoc[5](i: u64) - 13: CopyLoc[6](len: u64) - 14: Lt - 15: BrTrue(17) -B2: - 16: Branch(29) -B3: - 17: CopyLoc[2](v: &vector) - 18: CopyLoc[5](i: u64) - 19: VecImmBorrow(2) - 20: ImmBorrowField[1](T.issuer: vector) - 21: ReadRef - 22: CopyLoc[1](issuer: vector) - 23: Eq - 24: BrFalse(49) -B4: - 25: LdTrue - 26: StLoc[3](find: bool) - 27: MoveLoc[5](i: u64) - 28: StLoc[4](found_index: u64) -B5: - 29: Nop - 30: MoveLoc[2](v: &vector) - 31: Pop - 32: MoveLoc[3](find: bool) - 33: MoveLoc[4](found_index: u64) - 34: StLoc[7]($t12: u64) - 35: BrFalse(44) -B6: - 36: MoveLoc[0](s: &mut S) - 37: MutBorrowField[0](S.entries: vector) - 38: MoveLoc[7]($t12: u64) - 39: Call vector::remove(&mut vector, u64): T - 40: Call option::some(T): Option - 41: StLoc[8](ret: Option) -B7: - 42: MoveLoc[8](ret: Option) - 43: Ret -B8: - 44: MoveLoc[0](s: &mut S) - 45: Pop - 46: Call option::none(): Option - 47: StLoc[8](ret: Option) - 48: Branch(42) -B9: - 49: MoveLoc[5](i: u64) - 50: LdU64(1) - 51: Add - 52: StLoc[5](i: u64) - 53: Branch(12) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.exp index 0daca22216a..b21ac2a6532 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.exp @@ -1,27 +1,28 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.Module0 { -struct S { - x: bool -} +// Bytecode version v9 +module 0xcafe::Module0 +struct S + x: bool + +// Function definition at index 0 +#[persistent] public fun f(): S + local l0: S + local l1: bool + ld_false + pack S + st_loc l0 + ld_true + borrow_loc l0 + // @5 + borrow_field S, x + read_ref + st_loc l1 + mut_borrow_loc l1 + write_ref + // @10 + move_loc l0 + ret + -public f(): S /* def_idx: 0 */ { -L0: s: S -L1: $t5: bool -B0: - 0: LdFalse - 1: Pack[0](S) - 2: StLoc[0](s: S) - 3: LdTrue - 4: ImmBorrowLoc[0](s: S) - 5: ImmBorrowField[0](S.x: bool) - 6: ReadRef - 7: StLoc[1]($t5: bool) - 8: MutBorrowLoc[1]($t5: bool) - 9: WriteRef - 10: MoveLoc[0](s: S) - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.opt.exp index 0daca22216a..b21ac2a6532 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_14817.opt.exp @@ -1,27 +1,28 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.Module0 { -struct S { - x: bool -} +// Bytecode version v9 +module 0xcafe::Module0 +struct S + x: bool + +// Function definition at index 0 +#[persistent] public fun f(): S + local l0: S + local l1: bool + ld_false + pack S + st_loc l0 + ld_true + borrow_loc l0 + // @5 + borrow_field S, x + read_ref + st_loc l1 + mut_borrow_loc l1 + write_ref + // @10 + move_loc l0 + ret + -public f(): S /* def_idx: 0 */ { -L0: s: S -L1: $t5: bool -B0: - 0: LdFalse - 1: Pack[0](S) - 2: StLoc[0](s: S) - 3: LdTrue - 4: ImmBorrowLoc[0](s: S) - 5: ImmBorrowField[0](S.x: bool) - 6: ReadRef - 7: StLoc[1]($t5: bool) - 8: MutBorrowLoc[1]($t5: bool) - 9: WriteRef - 10: MoveLoc[0](s: S) - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.exp index 968516bc052..bc624453396 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.exp @@ -1,99 +1,107 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has store { - keys: vector, - values: vector, - num: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has store + keys: vector + values: vector + num: u64 + +// Function definition at index 0 +fun add(l0: &mut S, l1: T0, l2: T1) + local l3: &mut u64 + copy_loc l0 + mut_borrow_field S, keys + move_loc l1 + vec_push_back + copy_loc l0 + // @5 + mut_borrow_field S, values + move_loc l2 + vec_push_back + move_loc l0 + mut_borrow_field S, num + // @10 + st_loc l3 + copy_loc l3 + read_ref + ld_u64 1 + add + // @15 + move_loc l3 + write_ref + ret + +// Function definition at index 1 +fun destroy(l0: S) + local l1: vector + local l2: vector + mut_borrow_loc l0 + mut_borrow_field S, keys + vec_pop_back + mut_borrow_loc l0 + mut_borrow_field S, values + // @5 + vec_pop_back + move_loc l0 + unpack S + pop + st_loc l1 + // @10 + st_loc l2 + move_loc l2 + vec_unpack , 0 + move_loc l1 + vec_unpack , 0 + // @15 + pop + pop + ret + +// Function definition at index 2 +fun kp(l0: &S, l1: u64): (vector, u64) + move_loc l0 + borrow_field S, keys + read_ref + move_loc l1 + ret + +// Function definition at index 3 +fun new(): S + vec_pack , 0 + vec_pack , 0 + ld_u64 0 + pack S + ret + +// Function definition at index 4 +#[persistent] public fun test() + local l0: S + local l1: &S + local l2: u64 + call new + st_loc l0 + mut_borrow_loc l0 + ld_u64 1 + ld_u64 0 + // @5 + call add + borrow_loc l0 + borrow_field S, num + read_ref + borrow_loc l0 + // @10 + st_loc l1 + st_loc l2 + move_loc l1 + move_loc l2 + call kp + // @15 + move_loc l0 + call destroy + pop + pop + ret + -add(self: &mut S, k: K, v: V) /* def_idx: 0 */ { -L3: $t1: &mut u64 -B0: - 0: CopyLoc[0](self: &mut S) - 1: MutBorrowFieldGeneric[0](S.keys: vector) - 2: MoveLoc[1](k: K) - 3: VecPushBack(3) - 4: CopyLoc[0](self: &mut S) - 5: MutBorrowFieldGeneric[1](S.values: vector) - 6: MoveLoc[2](v: V) - 7: VecPushBack(4) - 8: MoveLoc[0](self: &mut S) - 9: MutBorrowFieldGeneric[2](S.num: u64) - 10: StLoc[3]($t1: &mut u64) - 11: CopyLoc[3]($t1: &mut u64) - 12: ReadRef - 13: LdU64(1) - 14: Add - 15: MoveLoc[3]($t1: &mut u64) - 16: WriteRef - 17: Ret -} -destroy(self: S) /* def_idx: 1 */ { -L1: values: vector -L2: keys: vector -B0: - 0: MutBorrowLoc[0](self: S) - 1: MutBorrowFieldGeneric[0](S.keys: vector) - 2: VecPopBack(3) - 3: MutBorrowLoc[0](self: S) - 4: MutBorrowFieldGeneric[1](S.values: vector) - 5: VecPopBack(4) - 6: MoveLoc[0](self: S) - 7: UnpackGeneric[0](S) - 8: Pop - 9: StLoc[1](values: vector) - 10: StLoc[2](keys: vector) - 11: MoveLoc[2](keys: vector) - 12: VecUnpack(3, 0) - 13: MoveLoc[1](values: vector) - 14: VecUnpack(4, 0) - 15: Pop - 16: Pop - 17: Ret -} -kp(self: &S, i: u64): vector * u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](self: &S) - 1: ImmBorrowFieldGeneric[0](S.keys: vector) - 2: ReadRef - 3: MoveLoc[1](i: u64) - 4: Ret -} -new(): S /* def_idx: 3 */ { -B0: - 0: VecPack(3, 0) - 1: VecPack(4, 0) - 2: LdU64(0) - 3: PackGeneric[0](S) - 4: Ret -} -public test() /* def_idx: 4 */ { -L0: t: S -L1: $t9: &S -L2: n: u64 -B0: - 0: Call new(): S - 1: StLoc[0](t: S) - 2: MutBorrowLoc[0](t: S) - 3: LdU64(1) - 4: LdU64(0) - 5: Call add(&mut S, u64, u64) - 6: ImmBorrowLoc[0](t: S) - 7: ImmBorrowFieldGeneric[3](S.num: u64) - 8: ReadRef - 9: ImmBorrowLoc[0](t: S) - 10: StLoc[1]($t9: &S) - 11: StLoc[2](n: u64) - 12: MoveLoc[1]($t9: &S) - 13: MoveLoc[2](n: u64) - 14: Call kp(&S, u64): vector * u64 - 15: MoveLoc[0](t: S) - 16: Call destroy(S) - 17: Pop - 18: Pop - 19: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.opt.exp index 0d9ec5eea68..99defd57c55 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_16057.opt.exp @@ -1,94 +1,102 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has store { - keys: vector, - values: vector, - num: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has store + keys: vector + values: vector + num: u64 + +// Function definition at index 0 +fun add(l0: &mut S, l1: T0, l2: T1) + local l3: &mut u64 + copy_loc l0 + mut_borrow_field S, keys + move_loc l1 + vec_push_back + copy_loc l0 + // @5 + mut_borrow_field S, values + move_loc l2 + vec_push_back + move_loc l0 + mut_borrow_field S, num + // @10 + st_loc l3 + copy_loc l3 + read_ref + ld_u64 1 + add + // @15 + move_loc l3 + write_ref + ret + +// Function definition at index 1 +fun destroy(l0: S) + local l1: vector + mut_borrow_loc l0 + mut_borrow_field S, keys + vec_pop_back + pop + mut_borrow_loc l0 + // @5 + mut_borrow_field S, values + vec_pop_back + pop + move_loc l0 + unpack S + // @10 + pop + st_loc l1 + vec_unpack , 0 + move_loc l1 + vec_unpack , 0 + // @15 + ret + +// Function definition at index 2 +fun kp(l0: &S, l1: u64): (vector, u64) + local l2: vector + move_loc l0 + borrow_field S, keys + read_ref + move_loc l1 + ret + +// Function definition at index 3 +fun new(): S + vec_pack , 0 + vec_pack , 0 + ld_u64 0 + pack S + ret + +// Function definition at index 4 +#[persistent] public fun test() + local l0: S + local l1: u64 + call new + st_loc l0 + mut_borrow_loc l0 + ld_u64 1 + ld_u64 0 + // @5 + call add + borrow_loc l0 + borrow_field S, num + read_ref + st_loc l1 + // @10 + borrow_loc l0 + move_loc l1 + call kp + pop + pop + // @15 + move_loc l0 + call destroy + ret + -add(self: &mut S, k: K, v: V) /* def_idx: 0 */ { -L3: $t1: &mut u64 -B0: - 0: CopyLoc[0](self: &mut S) - 1: MutBorrowFieldGeneric[0](S.keys: vector) - 2: MoveLoc[1](k: K) - 3: VecPushBack(3) - 4: CopyLoc[0](self: &mut S) - 5: MutBorrowFieldGeneric[1](S.values: vector) - 6: MoveLoc[2](v: V) - 7: VecPushBack(4) - 8: MoveLoc[0](self: &mut S) - 9: MutBorrowFieldGeneric[2](S.num: u64) - 10: StLoc[3]($t1: &mut u64) - 11: CopyLoc[3]($t1: &mut u64) - 12: ReadRef - 13: LdU64(1) - 14: Add - 15: MoveLoc[3]($t1: &mut u64) - 16: WriteRef - 17: Ret -} -destroy(self: S) /* def_idx: 1 */ { -L1: values: vector -B0: - 0: MutBorrowLoc[0](self: S) - 1: MutBorrowFieldGeneric[0](S.keys: vector) - 2: VecPopBack(3) - 3: Pop - 4: MutBorrowLoc[0](self: S) - 5: MutBorrowFieldGeneric[1](S.values: vector) - 6: VecPopBack(4) - 7: Pop - 8: MoveLoc[0](self: S) - 9: UnpackGeneric[0](S) - 10: Pop - 11: StLoc[1](values: vector) - 12: VecUnpack(3, 0) - 13: MoveLoc[1](values: vector) - 14: VecUnpack(4, 0) - 15: Ret -} -kp(self: &S, i: u64): vector * u64 /* def_idx: 2 */ { -L2: return[0]: vector -B0: - 0: MoveLoc[0](self: &S) - 1: ImmBorrowFieldGeneric[0](S.keys: vector) - 2: ReadRef - 3: MoveLoc[1](i: u64) - 4: Ret -} -new(): S /* def_idx: 3 */ { -B0: - 0: VecPack(3, 0) - 1: VecPack(4, 0) - 2: LdU64(0) - 3: PackGeneric[0](S) - 4: Ret -} -public test() /* def_idx: 4 */ { -L0: t: S -L1: $t2: u64 -B0: - 0: Call new(): S - 1: StLoc[0](t: S) - 2: MutBorrowLoc[0](t: S) - 3: LdU64(1) - 4: LdU64(0) - 5: Call add(&mut S, u64, u64) - 6: ImmBorrowLoc[0](t: S) - 7: ImmBorrowFieldGeneric[3](S.num: u64) - 8: ReadRef - 9: StLoc[1]($t2: u64) - 10: ImmBorrowLoc[0](t: S) - 11: MoveLoc[1]($t2: u64) - 12: Call kp(&S, u64): vector * u64 - 13: Pop - 14: Pop - 15: MoveLoc[0](t: S) - 16: Call destroy(S) - 17: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp new file mode 100644 index 00000000000..e143e045852 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp @@ -0,0 +1,19 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +// Function definition at index 0 +#[persistent] public fun f1(l0: &bool, l1: bool) + move_loc l0 + pop + ret + +// Function definition at index 1 +#[persistent] public fun f2(l0: bool) + borrow_loc l0 + copy_loc l0 + call f1 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move new file mode 100644 index 00000000000..bcd1e495470 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move @@ -0,0 +1,6 @@ +module 0xCAFE::Module0 { + public fun f1(_a: &bool, _b: bool) {} + public fun f2(x: bool) { + f1(&x, x); + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp new file mode 100644 index 00000000000..e143e045852 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp @@ -0,0 +1,19 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +// Function definition at index 0 +#[persistent] public fun f1(l0: &bool, l1: bool) + move_loc l0 + pop + ret + +// Function definition at index 1 +#[persistent] public fun f2(l0: bool) + borrow_loc l0 + copy_loc l0 + call f1 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.exp new file mode 100644 index 00000000000..f5d5c707862 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.exp @@ -0,0 +1,88 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +enum E has copy + drop + V1 + f1: u8 + f2: S + V2 + +struct S has copy + drop + dummy_field: bool + +// Function definition at index 0 +#[persistent] public fun f() + local l0: E + local l1: &E + local l2: &S + local l3: bool + local l4: bool + local l5: &bool + local l6: bool + local l7: bool + pack_variant E, V2 + st_loc l0 + borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + test_variant E, V1 + br_false l0 + move_loc l1 + borrow_variant_field E, V1::f2 + st_loc l2 + // @10 + move_loc l2 + pop + move_loc l0 + unpack_variant E, V1 + unpack S + // @15 + ld_true + st_loc l3 + pop + pop + move_loc l3 + // @20 + br_false l1 + ld_true + st_loc l4 + branch l2 +l1: ld_false + // @25 + st_loc l4 +l2: borrow_loc l4 + st_loc l5 + move_loc l5 + pop + // @30 + branch l3 +l0: move_loc l1 + pop + move_loc l0 + ld_true + // @35 + st_loc l6 + pop + move_loc l6 + br_false l4 + ld_true + // @40 + st_loc l7 + branch l5 +l4: ld_false + st_loc l7 +l5: borrow_loc l7 + // @45 + st_loc l5 + move_loc l5 + pop + branch l3 + ld_u64 14566554180833181697 + // @50 + abort +l3: ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.move new file mode 100644 index 00000000000..d5fca8654f7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.move @@ -0,0 +1,14 @@ +//# publish +module 0xCAFE::Module0 { + struct S has copy, drop ; + enum E has copy, drop { + V1 { f1: u8, f2: S, }, + V2, + } + public fun f() { + match (E::V2) { + E::V1 { f2: S, .. } => &(*(&true) && true), + _ => &(*(&true) && true), + }; + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.opt.exp new file mode 100644 index 00000000000..98314db6a12 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17393.opt.exp @@ -0,0 +1,64 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xcafe::Module0 +enum E has copy + drop + V1 + f1: u8 + f2: S + V2 + +struct S has copy + drop + dummy_field: bool + +// Function definition at index 0 +#[persistent] public fun f() + local l0: E + local l1: &E + local l2: &S + local l3: bool + local l4: bool + local l5: &bool + local l6: bool + pack_variant E, V2 + st_loc l0 + borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + test_variant E, V1 + br_false l0 + move_loc l1 + borrow_variant_field E, V1::f2 + pop + // @10 + move_loc l0 + unpack_variant E, V1 + unpack S + pop + pop + // @15 + ld_true + st_loc l4 +l1: borrow_loc l4 + pop + ret + // @20 + ld_false + st_loc l4 + branch l1 +l0: move_loc l1 + pop + // @25 + ld_true + st_loc l6 +l2: borrow_loc l6 + pop + ret + // @30 + ld_false + st_loc l6 + branch l2 + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.exp new file mode 100644 index 00000000000..190d2a03eab --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: Invalid operation: pack of `m::S` can only be done within the defining module `0xc0ffee::m` + ┌─ tests/file-format-generator/bug_17477.move:10:16 + │ +10 │ public fun test1() { + │ ^^^^^ +11 │ spec {}; +12 │ let _ = S { x: 42 }; + │ ----------- packed here diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.move new file mode 100644 index 00000000000..8113f3cc8a2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.move @@ -0,0 +1,18 @@ +module 0xc0ffee::m { + struct S has drop { + x: u64 + } +} + +module 0xc0ffee::n { + use 0xc0ffee::m::S; + + public fun test1() { + spec {}; + let _ = S { x: 42 }; + } + + public fun test2(s: S) { + spec { assert s.x > 0; }; + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.opt.exp new file mode 100644 index 00000000000..190d2a03eab --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17477.opt.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: Invalid operation: pack of `m::S` can only be done within the defining module `0xc0ffee::m` + ┌─ tests/file-format-generator/bug_17477.move:10:16 + │ +10 │ public fun test1() { + │ ^^^^^ +11 │ spec {}; +12 │ let _ = S { x: 42 }; + │ ----------- packed here diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.exp new file mode 100644 index 00000000000..2e321964ddb --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.exp @@ -0,0 +1,30 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::test +struct T has drop + x: T0 + y: T1 + +struct S has drop + _0: T0 + _1: T1 + _2: T2 + +// Function definition at index 0 +fun test_proj_0(): u8 + local l0: u8 + ld_u8 42 + ld_const
1 + ld_true + pack S + unpack S + // @5 + pop + pop + st_loc l0 + move_loc l0 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.move new file mode 100644 index 00000000000..fd5c1c0ad6a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.move @@ -0,0 +1,18 @@ +module 0x42::test { + struct S(A, B, C) has drop; + + struct T has drop { + x: A, + y: B + } + + inline fun proj_0(self: S): A { + let S(x, ..) = self; + x + } + + fun test_proj_0(): u8 { + let x = S(42, @0x1, true); + x.proj_0() + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.opt.exp new file mode 100644 index 00000000000..00d8cbbbd97 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17602.opt.exp @@ -0,0 +1,27 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::test +struct T has drop + x: T0 + y: T1 + +struct S has drop + _0: T0 + _1: T1 + _2: T2 + +// Function definition at index 0 +fun test_proj_0(): u8 + ld_u8 42 + ld_const
1 + ld_true + pack S + unpack S + // @5 + pop + pop + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp new file mode 100644 index 00000000000..c21aaa3fd16 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp @@ -0,0 +1,22 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +struct S has key + i: u64 + +// Function definition at index 0 +#[persistent] public fun test(): S + ld_u64 1 + pack S + pack_closure __lambda__1__test, 1 + call_closure <||S> + ret + +// Function definition at index 1 +fun __lambda__1__test(l0: S): S + move_loc l0 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move new file mode 100644 index 00000000000..fbebdb6d0a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move @@ -0,0 +1,11 @@ +module 0xc0ffee::m { + struct S has key { + i: u64, + } + + public fun test(): S { + let s = S { i: 1 }; + let f = || s; + f() + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp new file mode 100644 index 00000000000..c21aaa3fd16 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp @@ -0,0 +1,22 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +struct S has key + i: u64 + +// Function definition at index 0 +#[persistent] public fun test(): S + ld_u64 1 + pack S + pack_closure __lambda__1__test, 1 + call_closure <||S> + ret + +// Function definition at index 1 +fun __lambda__1__test(l0: S): S + move_loc l0 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/const.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/const.exp index a7daec9163f..9557cd1ede9 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/const.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/const.exp @@ -68,51 +68,55 @@ warning: This assignment/binding to the left-hand-side variable `s` is unused. C ============ disassembled file-format ================== -// Move bytecode v8 -module 42.constant { - - -test_constans() /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: Call u(bool): bool - 2: LdFalse - 3: Call u(bool): bool - 4: LdU8(1) - 5: Call u(u8): u8 - 6: LdU16(7086) - 7: Call u(u16): u16 - 8: LdU32(14593408) - 9: Call u(u32): u32 - 10: LdU64(51966) - 11: Call u(u64): u64 - 12: LdU128(3735928559) - 13: Call u(u128): u128 - 14: LdU256(301490978409967) - 15: Call u(u256): u256 - 16: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66]) - 17: Call u
(address): address - 18: LdConst[1](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 19: Call u>(vector): vector - 20: LdConst[2](Vector(U8): [7, 72, 101, 108, 108, 111, 33, 10]) - 21: Call u>(vector): vector - 22: Pop - 23: Pop - 24: Pop - 25: Pop - 26: Pop - 27: Pop - 28: Pop - 29: Pop - 30: Pop - 31: Pop - 32: Pop - 33: Ret -} -u(x: T): T /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: T) - 1: Ret -} -} +// Bytecode version v9 +module 0x42::constant +// Function definition at index 0 +fun test_constans() + ld_true + call u + ld_false + call u + ld_u8 1 + // @5 + call u + ld_u16 7086 + call u + ld_u32 14593408 + call u + // @10 + ld_u64 51966 + call u + ld_u128 3735928559 + call u + ld_u256 301490978409967 + // @15 + call u + ld_const
66 + call u
+ ld_const> [1, 2, 3] + call u> + // @20 + ld_const> [72, 101, 108, 108, 111, 33, 10] + call u> + pop + pop + pop + // @25 + pop + pop + pop + pop + pop + // @30 + pop + pop + pop + ret + +// Function definition at index 1 +fun u(l0: T0): T0 + move_loc l0 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/const.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/const.opt.exp index 73ef5e1fff8..668cb0be77e 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/const.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/const.opt.exp @@ -68,51 +68,55 @@ warning: This assignment/binding to the left-hand-side variable `s` is unused. C ============ disassembled file-format ================== -// Move bytecode v8 -module 42.constant { - - -test_constans() /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: Call u(bool): bool - 2: Pop - 3: LdFalse - 4: Call u(bool): bool - 5: Pop - 6: LdU8(1) - 7: Call u(u8): u8 - 8: Pop - 9: LdU16(7086) - 10: Call u(u16): u16 - 11: Pop - 12: LdU32(14593408) - 13: Call u(u32): u32 - 14: Pop - 15: LdU64(51966) - 16: Call u(u64): u64 - 17: Pop - 18: LdU128(3735928559) - 19: Call u(u128): u128 - 20: Pop - 21: LdU256(301490978409967) - 22: Call u(u256): u256 - 23: Pop - 24: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66]) - 25: Call u
(address): address - 26: Pop - 27: LdConst[1](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 28: Call u>(vector): vector - 29: Pop - 30: LdConst[2](Vector(U8): [7, 72, 101, 108, 108, 111, 33, 10]) - 31: Call u>(vector): vector - 32: Pop - 33: Ret -} -u(x: T): T /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: T) - 1: Ret -} -} +// Bytecode version v9 +module 0x42::constant +// Function definition at index 0 +fun test_constans() + ld_true + call u + pop + ld_false + call u + // @5 + pop + ld_u8 1 + call u + pop + ld_u16 7086 + // @10 + call u + pop + ld_u32 14593408 + call u + pop + // @15 + ld_u64 51966 + call u + pop + ld_u128 3735928559 + call u + // @20 + pop + ld_u256 301490978409967 + call u + pop + ld_const
66 + // @25 + call u
+ pop + ld_const> [1, 2, 3] + call u> + pop + // @30 + ld_const> [72, 101, 108, 108, 111, 33, 10] + call u> + pop + ret + +// Function definition at index 1 +fun u(l0: T0): T0 + move_loc l0 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.exp index 2fb4fcc12bc..8ce5c6c7d6e 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u64) + move_loc l0 + call one + call one + call one + call one + // @5 + call one + call bar + ret -bar(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(x: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call bar(u64, u64, u64, u64, u64, u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.opt.exp index 2fb4fcc12bc..8ce5c6c7d6e 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_01.opt.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u64) + move_loc l0 + call one + call one + call one + call one + // @5 + call one + call bar + ret -bar(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(x: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call bar(u64, u64, u64, u64, u64, u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.exp index f8a502c51f6..bc09bce56be 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.exp @@ -1,17 +1,16 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64, l1: u64): u64 + copy_loc l0 + move_loc l1 + move_loc l0 + mul + add + // @5 + ret -test(x: u64, y: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: MoveLoc[0](x: u64) - 3: Mul - 4: Add - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.opt.exp index f8a502c51f6..bc09bce56be 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/eager_push_02.opt.exp @@ -1,17 +1,16 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64, l1: u64): u64 + copy_loc l0 + move_loc l1 + move_loc l0 + mul + add + // @5 + ret -test(x: u64, y: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: MoveLoc[0](x: u64) - 3: Mul - 4: Add - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp index 8fc0be17683..65dd56c6d45 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp @@ -1,90 +1,96 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.fields { -struct T has drop { - h: u64 -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::fields +struct T has drop + h: u64 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun read_ref(l0: &S): u64 + move_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 1 +fun read_val(l0: S): u64 + borrow_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 2 +fun write_local_direct(): S + local l0: S + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @10 + move_loc l0 + ret + +// Function definition at index 3 +fun write_local_via_ref(): S + local l0: S + local l1: u64 + local l2: &mut S + local l3: &mut u64 + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + mut_borrow_loc l0 + ld_u64 42 + st_loc l1 + st_loc l2 + move_loc l2 + // @10 + mut_borrow_field S, g + mut_borrow_field T, h + st_loc l3 + move_loc l1 + move_loc l3 + // @15 + write_ref + move_loc l0 + ret + +// Function definition at index 4 +fun write_param(l0: &mut S) + ld_u64 42 + move_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + ret + +// Function definition at index 5 +fun write_val(l0: S): S + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + move_loc l0 + ret + -read_ref(x: &S): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: &S) - 1: ImmBorrowField[0](S.g: T) - 2: ImmBorrowField[1](T.h: u64) - 3: ReadRef - 4: Ret -} -read_val(x: S): u64 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](x: S) - 1: ImmBorrowField[0](S.g: T) - 2: ImmBorrowField[1](T.h: u64) - 3: ReadRef - 4: Ret -} -write_local_direct(): S /* def_idx: 2 */ { -L0: x: S -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[1](S) - 4: StLoc[0](x: S) - 5: LdU64(42) - 6: MutBorrowLoc[0](x: S) - 7: MutBorrowField[0](S.g: T) - 8: MutBorrowField[1](T.h: u64) - 9: WriteRef - 10: MoveLoc[0](x: S) - 11: Ret -} -write_local_via_ref(): S /* def_idx: 3 */ { -L0: x: S -L1: $t6: u64 -L2: r: &mut S -L3: $t7: &mut u64 -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[1](S) - 4: StLoc[0](x: S) - 5: MutBorrowLoc[0](x: S) - 6: LdU64(42) - 7: StLoc[1]($t6: u64) - 8: StLoc[2](r: &mut S) - 9: MoveLoc[2](r: &mut S) - 10: MutBorrowField[0](S.g: T) - 11: MutBorrowField[1](T.h: u64) - 12: StLoc[3]($t7: &mut u64) - 13: MoveLoc[1]($t6: u64) - 14: MoveLoc[3]($t7: &mut u64) - 15: WriteRef - 16: MoveLoc[0](x: S) - 17: Ret -} -write_param(x: &mut S) /* def_idx: 4 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut S) - 2: MutBorrowField[0](S.g: T) - 3: MutBorrowField[1](T.h: u64) - 4: WriteRef - 5: Ret -} -write_val(x: S): S /* def_idx: 5 */ { -B0: - 0: LdU64(42) - 1: MutBorrowLoc[0](x: S) - 2: MutBorrowField[0](S.g: T) - 3: MutBorrowField[1](T.h: u64) - 4: WriteRef - 5: MoveLoc[0](x: S) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.opt.exp index 2c8bfea8865..7dabdaa6257 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.opt.exp @@ -1,84 +1,89 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.fields { -struct T has drop { - h: u64 -} -struct S has drop { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::fields +struct T has drop + h: u64 + +struct S has drop + f: u64 + g: T + +// Function definition at index 0 +fun read_ref(l0: &S): u64 + move_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 1 +fun read_val(l0: S): u64 + borrow_loc l0 + borrow_field S, g + borrow_field T, h + read_ref + ret + +// Function definition at index 2 +fun write_local_direct(): S + local l0: S + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @10 + move_loc l0 + ret + +// Function definition at index 3 +fun write_local_via_ref(): S + local l0: S + local l1: &mut S + ld_u64 0 + ld_u64 0 + pack T + pack S + st_loc l0 + // @5 + mut_borrow_loc l0 + st_loc l1 + ld_u64 42 + move_loc l1 + mut_borrow_field S, g + // @10 + mut_borrow_field T, h + write_ref + move_loc l0 + ret + +// Function definition at index 4 +fun write_param(l0: &mut S) + ld_u64 42 + move_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + ret + +// Function definition at index 5 +fun write_val(l0: S): S + ld_u64 42 + mut_borrow_loc l0 + mut_borrow_field S, g + mut_borrow_field T, h + write_ref + // @5 + move_loc l0 + ret + -read_ref(x: &S): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: &S) - 1: ImmBorrowField[0](S.g: T) - 2: ImmBorrowField[1](T.h: u64) - 3: ReadRef - 4: Ret -} -read_val(x: S): u64 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](x: S) - 1: ImmBorrowField[0](S.g: T) - 2: ImmBorrowField[1](T.h: u64) - 3: ReadRef - 4: Ret -} -write_local_direct(): S /* def_idx: 2 */ { -L0: x: S -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[1](S) - 4: StLoc[0](x: S) - 5: LdU64(42) - 6: MutBorrowLoc[0](x: S) - 7: MutBorrowField[0](S.g: T) - 8: MutBorrowField[1](T.h: u64) - 9: WriteRef - 10: MoveLoc[0](x: S) - 11: Ret -} -write_local_via_ref(): S /* def_idx: 3 */ { -L0: x: S -L1: r: &mut S -B0: - 0: LdU64(0) - 1: LdU64(0) - 2: Pack[0](T) - 3: Pack[1](S) - 4: StLoc[0](x: S) - 5: MutBorrowLoc[0](x: S) - 6: StLoc[1](r: &mut S) - 7: LdU64(42) - 8: MoveLoc[1](r: &mut S) - 9: MutBorrowField[0](S.g: T) - 10: MutBorrowField[1](T.h: u64) - 11: WriteRef - 12: MoveLoc[0](x: S) - 13: Ret -} -write_param(x: &mut S) /* def_idx: 4 */ { -B0: - 0: LdU64(42) - 1: MoveLoc[0](x: &mut S) - 2: MutBorrowField[0](S.g: T) - 3: MutBorrowField[1](T.h: u64) - 4: WriteRef - 5: Ret -} -write_val(x: S): S /* def_idx: 5 */ { -B0: - 0: LdU64(42) - 1: MutBorrowLoc[0](x: S) - 2: MutBorrowField[0](S.g: T) - 3: MutBorrowField[1](T.h: u64) - 4: WriteRef - 5: MoveLoc[0](x: S) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.exp index 4bb32431a96..0ac553538df 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.exp @@ -1,77 +1,81 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - f: u64, - g: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + f: u64 + g: u64 + +// Function definition at index 0 +fun bar(l0: &mut S): (u64, u64) + ld_u64 1 + move_loc l0 + pop + ld_u64 1 + ret + +// Function definition at index 1 +fun f1(l0: &mut S, l1: u64, l2: address): (&mut S, address, u64) + move_loc l0 + move_loc l2 + move_loc l1 + ret + +// Function definition at index 2 +fun f2(l0: address, l1: &mut S, l2: address, l3: u64, l4: &mut S) + move_loc l1 + pop + move_loc l4 + pop + ret + +// Function definition at index 3 +fun f3(l0: u64, l1: &u64) + move_loc l1 + pop + ret + +// Function definition at index 4 +fun foo(l0: address, l1: &mut S, l2: &mut S): u64 + local l3: u64 + local l4: address + local l5: address + local l6: &mut S + local l7: u64 + local l8: address + local l9: &mut S + move_loc l1 + ld_u64 1 + move_loc l0 + call f1 + st_loc l3 + // @5 + st_loc l4 + copy_loc l4 + st_loc l5 + st_loc l6 + copy_loc l6 + // @10 + move_loc l4 + copy_loc l3 + st_loc l7 + st_loc l8 + st_loc l9 + // @15 + move_loc l5 + move_loc l9 + move_loc l8 + move_loc l7 + move_loc l2 + // @20 + call f2 + copy_loc l3 + move_loc l6 + borrow_field S, g + call f3 + // @25 + move_loc l3 + ret + -bar(_r: &mut S): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: MoveLoc[0](_r: &mut S) - 2: Pop - 3: LdU64(1) - 4: Ret -} -f1(a: &mut S, b: u64, c: address): &mut S * address * u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: &mut S) - 1: MoveLoc[2](c: address) - 2: MoveLoc[1](b: u64) - 3: Ret -} -f2(_r1: address, _r2: &mut S, _r3: address, _r4: u64, _r5: &mut S) /* def_idx: 2 */ { -B0: - 0: MoveLoc[1](_r2: &mut S) - 1: Pop - 2: MoveLoc[4](_r5: &mut S) - 3: Pop - 4: Ret -} -f3(_r1: u64, _r2: &u64) /* def_idx: 3 */ { -B0: - 0: MoveLoc[1](_r2: &u64) - 1: Pop - 2: Ret -} -foo(a: address, ref1: &mut S, ref2: &mut S): u64 /* def_idx: 4 */ { -L3: c: u64 -L4: b: address -L5: $t9: address -L6: r1: &mut S -L7: $t12: u64 -L8: $t11: address -L9: $t10: &mut S -B0: - 0: MoveLoc[1](ref1: &mut S) - 1: LdU64(1) - 2: MoveLoc[0](a: address) - 3: Call f1(&mut S, u64, address): &mut S * address * u64 - 4: StLoc[3](c: u64) - 5: StLoc[4](b: address) - 6: CopyLoc[4](b: address) - 7: StLoc[5]($t9: address) - 8: StLoc[6](r1: &mut S) - 9: CopyLoc[6](r1: &mut S) - 10: MoveLoc[4](b: address) - 11: CopyLoc[3](c: u64) - 12: StLoc[7]($t12: u64) - 13: StLoc[8]($t11: address) - 14: StLoc[9]($t10: &mut S) - 15: MoveLoc[5]($t9: address) - 16: MoveLoc[9]($t10: &mut S) - 17: MoveLoc[8]($t11: address) - 18: MoveLoc[7]($t12: u64) - 19: MoveLoc[2](ref2: &mut S) - 20: Call f2(address, &mut S, address, u64, &mut S) - 21: CopyLoc[3](c: u64) - 22: MoveLoc[6](r1: &mut S) - 23: ImmBorrowField[0](S.g: u64) - 24: Call f3(u64, &u64) - 25: MoveLoc[3](c: u64) - 26: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.opt.exp index 904e0067ab3..e8876aba810 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/framework_reduced_06.opt.exp @@ -1,63 +1,65 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - f: u64, - g: u64 -} - -bar(_r: &mut S): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: MoveLoc[0](_r: &mut S) - 2: Pop - 3: LdU64(1) - 4: Ret -} -f1(a: &mut S, b: u64, c: address): &mut S * address * u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: &mut S) - 1: MoveLoc[2](c: address) - 2: MoveLoc[1](b: u64) - 3: Ret -} -f2(_r1: address, _r2: &mut S, _r3: address, _r4: u64, _r5: &mut S) /* def_idx: 2 */ { -B0: - 0: MoveLoc[1](_r2: &mut S) - 1: Pop - 2: MoveLoc[4](_r5: &mut S) - 3: Pop - 4: Ret -} -f3(_r1: u64, _r2: &u64) /* def_idx: 3 */ { -B0: - 0: MoveLoc[1](_r2: &u64) - 1: Pop - 2: Ret -} -foo(a: address, ref1: &mut S, ref2: &mut S): u64 /* def_idx: 4 */ { -L3: $t8: u64 -B0: - 0: MoveLoc[1](ref1: &mut S) - 1: LdU64(1) - 2: MoveLoc[0](a: address) - 3: Call f1(&mut S, u64, address): &mut S * address * u64 - 4: StLoc[3]($t8: u64) - 5: StLoc[0](a: address) - 6: StLoc[1](ref1: &mut S) - 7: CopyLoc[0](a: address) - 8: CopyLoc[1](ref1: &mut S) - 9: MoveLoc[0](a: address) - 10: CopyLoc[3]($t8: u64) - 11: MoveLoc[2](ref2: &mut S) - 12: Call f2(address, &mut S, address, u64, &mut S) - 13: CopyLoc[3]($t8: u64) - 14: MoveLoc[1](ref1: &mut S) - 15: ImmBorrowField[0](S.g: u64) - 16: Call f3(u64, &u64) - 17: MoveLoc[3]($t8: u64) - 18: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + f: u64 + g: u64 + +// Function definition at index 0 +fun bar(l0: &mut S): (u64, u64) + ld_u64 1 + move_loc l0 + pop + ld_u64 1 + ret + +// Function definition at index 1 +fun f1(l0: &mut S, l1: u64, l2: address): (&mut S, address, u64) + move_loc l0 + move_loc l2 + move_loc l1 + ret + +// Function definition at index 2 +fun f2(l0: address, l1: &mut S, l2: address, l3: u64, l4: &mut S) + move_loc l1 + pop + move_loc l4 + pop + ret + +// Function definition at index 3 +fun f3(l0: u64, l1: &u64) + move_loc l1 + pop + ret + +// Function definition at index 4 +fun foo(l0: address, l1: &mut S, l2: &mut S): u64 + local l3: u64 + move_loc l1 + ld_u64 1 + move_loc l0 + call f1 + st_loc l3 + // @5 + st_loc l0 + st_loc l1 + copy_loc l0 + copy_loc l1 + move_loc l0 + // @10 + copy_loc l3 + move_loc l2 + call f2 + copy_loc l3 + move_loc l1 + // @15 + borrow_field S, g + call f3 + move_loc l3 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.exp index 93f04894e0b..473d4acc378 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.exp @@ -1,19 +1,17 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +fun foo(l0: u64): u64 + move_loc l0 + call identity + ret + +// Function definition at index 1 +fun identity(l0: T0): T0 + move_loc l0 + ret -foo(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Call identity(u64): u64 - 2: Ret -} -identity(x: T): T /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: T) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.opt.exp index 93f04894e0b..473d4acc378 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/generic_call.opt.exp @@ -1,19 +1,17 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +fun foo(l0: u64): u64 + move_loc l0 + call identity + ret + +// Function definition at index 1 +fun identity(l0: T0): T0 + move_loc l0 + ret -foo(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Call identity(u64): u64 - 2: Ret -} -identity(x: T): T /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: T) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp index 5851fe4c977..090a668a1b9 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp @@ -8,52 +8,53 @@ warning: Unused value of parameter `x`. Consider removing the parameter, or pref ============ disassembled file-format ================== -// Move bytecode v8 -module 42.globals { -struct R has store, key { - f: u64 -} - -check(a: address): bool /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: address) - 1: Exists[0](R) - 2: Ret -} -publish(s: &signer) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](s: &signer) - 1: LdU64(1) - 2: Pack[0](R) - 3: MoveTo[0](R) - 4: Ret -} -read(a: address): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](a: address) - 1: ImmBorrowGlobal[0](R) - 2: ImmBorrowField[0](R.f: u64) - 3: ReadRef - 4: Ret -} -write(a: address, x: u64): u64 /* def_idx: 3 */ { -L2: $t4: u64 -L3: r: &mut R -L4: $t5: &mut u64 -B0: - 0: MoveLoc[0](a: address) - 1: MutBorrowGlobal[0](R) - 2: LdU64(2) - 3: StLoc[2]($t4: u64) - 4: StLoc[3](r: &mut R) - 5: MoveLoc[3](r: &mut R) - 6: MutBorrowField[0](R.f: u64) - 7: StLoc[4]($t5: &mut u64) - 8: MoveLoc[2]($t4: u64) - 9: MoveLoc[4]($t5: &mut u64) - 10: WriteRef - 11: LdU64(9) - 12: Ret -} -} +// Bytecode version v9 +module 0x42::globals +struct R has store + key + f: u64 + +// Function definition at index 0 +fun check(l0: address): bool + move_loc l0 + exists R + ret + +// Function definition at index 1 +fun publish(l0: &signer) + move_loc l0 + ld_u64 1 + pack R + move_to R + ret + +// Function definition at index 2 +fun read(l0: address): u64 acquires R + move_loc l0 + borrow_global R + borrow_field R, f + read_ref + ret + +// Function definition at index 3 +fun write(l0: address, l1: u64): u64 acquires R + local l2: u64 + local l3: &mut R + local l4: &mut u64 + move_loc l0 + mut_borrow_global R + ld_u64 2 + st_loc l2 + st_loc l3 + // @5 + move_loc l3 + mut_borrow_field R, f + st_loc l4 + move_loc l2 + move_loc l4 + // @10 + write_ref + ld_u64 9 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.opt.exp index 7b94ee15fbd..45269470073 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.opt.exp @@ -8,46 +8,46 @@ warning: Unused value of parameter `x`. Consider removing the parameter, or pref ============ disassembled file-format ================== -// Move bytecode v8 -module 42.globals { -struct R has store, key { - f: u64 -} - -check(a: address): bool /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: address) - 1: Exists[0](R) - 2: Ret -} -publish(s: &signer) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](s: &signer) - 1: LdU64(1) - 2: Pack[0](R) - 3: MoveTo[0](R) - 4: Ret -} -read(a: address): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](a: address) - 1: ImmBorrowGlobal[0](R) - 2: ImmBorrowField[0](R.f: u64) - 3: ReadRef - 4: Ret -} -write(a: address, x: u64): u64 /* def_idx: 3 */ { -L2: r: &mut R -B0: - 0: MoveLoc[0](a: address) - 1: MutBorrowGlobal[0](R) - 2: StLoc[2](r: &mut R) - 3: LdU64(2) - 4: MoveLoc[2](r: &mut R) - 5: MutBorrowField[0](R.f: u64) - 6: WriteRef - 7: LdU64(9) - 8: Ret -} -} +// Bytecode version v9 +module 0x42::globals +struct R has store + key + f: u64 + +// Function definition at index 0 +fun check(l0: address): bool + move_loc l0 + exists R + ret + +// Function definition at index 1 +fun publish(l0: &signer) + move_loc l0 + ld_u64 1 + pack R + move_to R + ret + +// Function definition at index 2 +fun read(l0: address): u64 acquires R + move_loc l0 + borrow_global R + borrow_field R, f + read_ref + ret + +// Function definition at index 3 +fun write(l0: address, l1: u64): u64 acquires R + local l2: &mut R + move_loc l0 + mut_borrow_global R + st_loc l2 + ld_u64 2 + move_loc l2 + // @5 + mut_borrow_field R, f + write_ref + ld_u64 9 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.exp index cbdecba108a..b1532e66fca 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.exp @@ -1,20 +1,16 @@ ============ disassembled file-format ================== -// Move bytecode v8 -script { +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ld_true + br_false l0 + branch l1 +l0: ld_u64 1 + abort + // @5 +l1: ret -main() /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: BrFalse(3) -B1: - 2: Branch(5) -B2: - 3: LdU64(1) - 4: Abort -B3: - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.opt.exp index 7a4f02edec5..3173a24accd 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/has_script.opt.exp @@ -1,15 +1,12 @@ ============ disassembled file-format ================== -// Move bytecode v8 -script { +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret + ld_u64 1 + abort -main() /* def_idx: 0 */ { -B0: - 0: Ret -B1: - 1: LdU64(1) - 2: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp index c3bda8ebda9..a003a5d7669 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp @@ -1,68 +1,64 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.if_else { +// Bytecode version v9 +module 0x42::if_else +// Function definition at index 0 +fun if_else(l0: bool, l1: u64): u64 + local l2: u64 + move_loc l0 + br_false l0 + move_loc l1 + ld_u64 1 + add + // @5 + st_loc l2 + branch l1 +l0: move_loc l1 + ld_u64 1 + sub + // @10 + st_loc l2 +l1: move_loc l2 + ret + +// Function definition at index 1 +fun if_else_nested(l0: bool, l1: u64): u64 + local l2: u64 + local l3: u64 + local l4: u64 + move_loc l0 + br_false l0 + copy_loc l1 + ld_u64 1 + add + // @5 + st_loc l2 + branch l1 +l0: copy_loc l1 + ld_u64 1 + sub + // @10 + st_loc l2 +l1: ld_u64 10 + st_loc l3 + move_loc l2 + move_loc l3 + // @15 + gt + br_false l2 + move_loc l1 + ld_u64 2 + mul + // @20 + st_loc l4 + branch l3 +l2: move_loc l1 + ld_u64 2 + div + // @25 + st_loc l4 +l3: move_loc l4 + ret -if_else(cond: bool, x: u64): u64 /* def_idx: 0 */ { -L2: return: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(7) -B1: - 2: MoveLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2](return: u64) - 6: Branch(11) -B2: - 7: MoveLoc[1](x: u64) - 8: LdU64(1) - 9: Sub - 10: StLoc[2](return: u64) -B3: - 11: MoveLoc[2](return: u64) - 12: Ret -} -if_else_nested(cond: bool, x: u64): u64 /* def_idx: 1 */ { -L2: $t4: u64 -L3: $t9: u64 -L4: return: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(7) -B1: - 2: CopyLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2]($t4: u64) - 6: Branch(11) -B2: - 7: CopyLoc[1](x: u64) - 8: LdU64(1) - 9: Sub - 10: StLoc[2]($t4: u64) -B3: - 11: LdU64(10) - 12: StLoc[3]($t9: u64) - 13: MoveLoc[2]($t4: u64) - 14: MoveLoc[3]($t9: u64) - 15: Gt - 16: BrFalse(22) -B4: - 17: MoveLoc[1](x: u64) - 18: LdU64(2) - 19: Mul - 20: StLoc[4](return: u64) - 21: Branch(26) -B5: - 22: MoveLoc[1](x: u64) - 23: LdU64(2) - 24: Div - 25: StLoc[4](return: u64) -B6: - 26: MoveLoc[4](return: u64) - 27: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.opt.exp index a0bdc241991..3cbcdcc1e7a 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.opt.exp @@ -1,65 +1,52 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.if_else { +// Bytecode version v9 +module 0x42::if_else +// Function definition at index 0 +fun if_else(l0: bool, l1: u64): u64 + move_loc l0 + br_false l0 + move_loc l1 + ld_u64 1 + add + // @5 + ret +l0: move_loc l1 + ld_u64 1 + sub + ret + +// Function definition at index 1 +fun if_else_nested(l0: bool, l1: u64): u64 + local l2: u64 + local l3: u64 + move_loc l0 + br_false l0 + copy_loc l1 + ld_u64 1 + add + // @5 + st_loc l2 +l2: move_loc l2 + ld_u64 10 + gt + br_false l1 + // @10 + move_loc l1 + ld_u64 2 + mul + ret +l1: move_loc l1 + // @15 + ld_u64 2 + div + ret +l0: copy_loc l1 + ld_u64 1 + // @20 + sub + st_loc l2 + branch l2 -if_else(cond: bool, x: u64): u64 /* def_idx: 0 */ { -L2: $t3: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(8) -B1: - 2: MoveLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2]($t3: u64) -B2: - 6: MoveLoc[2]($t3: u64) - 7: Ret -B3: - 8: MoveLoc[1](x: u64) - 9: LdU64(1) - 10: Sub - 11: StLoc[2]($t3: u64) - 12: Branch(6) -} -if_else_nested(cond: bool, x: u64): u64 /* def_idx: 1 */ { -L2: $t5: u64 -L3: $t6: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(21) -B1: - 2: CopyLoc[1](x: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[2]($t5: u64) -B2: - 6: MoveLoc[2]($t5: u64) - 7: LdU64(10) - 8: Gt - 9: BrFalse(16) -B3: - 10: MoveLoc[1](x: u64) - 11: LdU64(2) - 12: Mul - 13: StLoc[3]($t6: u64) -B4: - 14: MoveLoc[3]($t6: u64) - 15: Ret -B5: - 16: MoveLoc[1](x: u64) - 17: LdU64(2) - 18: Div - 19: StLoc[3]($t6: u64) - 20: Branch(14) -B6: - 21: CopyLoc[1](x: u64) - 22: LdU64(1) - 23: Sub - 24: StLoc[2]($t5: u64) - 25: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.exp index a64bc6e20ea..e25821c7d6f 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.exp @@ -1,58 +1,62 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -struct Coin has copy, drop { - _0: u256 -} +// Bytecode version v9 +module 0x42::test +struct Coin has copy + drop + _0: u256 + +// Function definition at index 0 +fun inc_vec_new(l0: &mut vector, l1: u64) + copy_loc l0 + freeze_ref + copy_loc l1 + vec_borrow + read_ref + // @5 + ld_u256 1 + add + move_loc l0 + move_loc l1 + vec_mut_borrow + // @10 + write_ref + ret + +// Function definition at index 1 +fun test0(l0: &mut vector, l1: u64) + local l2: &mut u256 + move_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + st_loc l2 + // @5 + move_loc l2 + pop + ret + +// Function definition at index 2 +fun test1(l0: vector, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + st_loc l2 + // @5 + move_loc l2 + pop + ret + +// Function definition at index 3 +fun test3(l0: &vector, l1: u64) + move_loc l0 + move_loc l1 + vec_borrow + read_ref + pop + // @5 + ret + -inc_vec_new(x: &mut vector, index: u64) /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: &mut vector) - 1: FreezeRef - 2: CopyLoc[1](index: u64) - 3: VecImmBorrow(2) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MoveLoc[0](x: &mut vector) - 8: MoveLoc[1](index: u64) - 9: VecMutBorrow(2) - 10: WriteRef - 11: Ret -} -test0(x: &mut vector, index: u64) /* def_idx: 1 */ { -L2: _p: &mut u256 -B0: - 0: MoveLoc[0](x: &mut vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(4) - 3: MutBorrowField[0](Coin._0: u256) - 4: StLoc[2](_p: &mut u256) - 5: MoveLoc[2](_p: &mut u256) - 6: Pop - 7: Ret -} -test1(x: vector, index: u64) /* def_idx: 2 */ { -L2: _p: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(4) - 3: MutBorrowField[0](Coin._0: u256) - 4: StLoc[2](_p: &mut u256) - 5: MoveLoc[2](_p: &mut u256) - 6: Pop - 7: Ret -} -test3(x: &vector, index: u64) /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](x: &vector) - 1: MoveLoc[1](index: u64) - 2: VecImmBorrow(4) - 3: ReadRef - 4: Pop - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.opt.exp index b761861f31d..f551085f745 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/index_then_field_select.opt.exp @@ -1,54 +1,58 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -struct Coin has copy, drop { - _0: u256 -} +// Bytecode version v9 +module 0x42::test +struct Coin has copy + drop + _0: u256 + +// Function definition at index 0 +fun inc_vec_new(l0: &mut vector, l1: u64) + copy_loc l0 + freeze_ref + copy_loc l1 + vec_borrow + read_ref + // @5 + ld_u256 1 + add + move_loc l0 + move_loc l1 + vec_mut_borrow + // @10 + write_ref + ret + +// Function definition at index 1 +fun test0(l0: &mut vector, l1: u64) + local l2: &mut u256 + move_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + pop + // @5 + ret + +// Function definition at index 2 +fun test1(l0: vector, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + pop + // @5 + ret + +// Function definition at index 3 +fun test3(l0: &vector, l1: u64) + move_loc l0 + move_loc l1 + vec_borrow + read_ref + pop + // @5 + ret + -inc_vec_new(x: &mut vector, index: u64) /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: &mut vector) - 1: FreezeRef - 2: CopyLoc[1](index: u64) - 3: VecImmBorrow(2) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MoveLoc[0](x: &mut vector) - 8: MoveLoc[1](index: u64) - 9: VecMutBorrow(2) - 10: WriteRef - 11: Ret -} -test0(x: &mut vector, index: u64) /* def_idx: 1 */ { -L2: _p: &mut u256 -B0: - 0: MoveLoc[0](x: &mut vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(4) - 3: MutBorrowField[0](Coin._0: u256) - 4: Pop - 5: Ret -} -test1(x: vector, index: u64) /* def_idx: 2 */ { -L2: _p: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(4) - 3: MutBorrowField[0](Coin._0: u256) - 4: Pop - 5: Ret -} -test3(x: &vector, index: u64) /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](x: &vector) - 1: MoveLoc[1](index: u64) - 2: VecImmBorrow(4) - 3: ReadRef - 4: Pop - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.exp index b6167ab6610..bb002e7602b 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 2 + call test1 + ld_u64 5 + call test2 + add + // @5 + ret + +// Function definition at index 1 +fun test1(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 2 +fun test2(l0: u64): u64 + move_loc l0 + ld_u64 2 + add + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(2) - 1: Call test1(u64): u64 - 2: LdU64(5) - 3: Call test2(u64): u64 - 4: Add - 5: Ret -} -test1(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -test2(x: u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(2) - 2: Add - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.opt.exp index b6167ab6610..bb002e7602b 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12404.opt.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 2 + call test1 + ld_u64 5 + call test2 + add + // @5 + ret + +// Function definition at index 1 +fun test1(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 2 +fun test2(l0: u64): u64 + move_loc l0 + ld_u64 2 + add + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(2) - 1: Call test1(u64): u64 - 2: LdU64(5) - 3: Call test2(u64): u64 - 4: Add - 5: Ret -} -test1(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -test2(x: u64): u64 /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(2) - 2: Add - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.exp index 7ba6064c982..ba8788d9b39 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.exp @@ -1,31 +1,31 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun point_add_assign(l0: &mut u64, l1: &u64): &mut u64 + local l2: &mut u64 + copy_loc l0 + freeze_ref + move_loc l1 + ld_true + call point_add_internal + // @5 + move_loc l0 + st_loc l2 + pop + move_loc l2 + ret + +// Function definition at index 1 +fun point_add_internal(l0: &u64, l1: &u64, l2: bool): u64 + move_loc l0 + read_ref + move_loc l1 + read_ref + add + // @5 + ret -public point_add_assign(a: &mut u64, b: &u64): &mut u64 /* def_idx: 0 */ { -L2: return: &mut u64 -B0: - 0: CopyLoc[0](a: &mut u64) - 1: FreezeRef - 2: MoveLoc[1](b: &u64) - 3: LdTrue - 4: Call point_add_internal(&u64, &u64, bool): u64 - 5: MoveLoc[0](a: &mut u64) - 6: StLoc[2](return: &mut u64) - 7: Pop - 8: MoveLoc[2](return: &mut u64) - 9: Ret -} -point_add_internal(a: &u64, b: &u64, _in_place: bool): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: &u64) - 1: ReadRef - 2: MoveLoc[1](b: &u64) - 3: ReadRef - 4: Add - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.opt.exp index 6c6fa6e116f..9b9a6e4d9b1 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_12540.opt.exp @@ -1,28 +1,28 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun point_add_assign(l0: &mut u64, l1: &u64): &mut u64 + copy_loc l0 + freeze_ref + move_loc l1 + ld_true + call point_add_internal + // @5 + pop + move_loc l0 + ret + +// Function definition at index 1 +fun point_add_internal(l0: &u64, l1: &u64, l2: bool): u64 + move_loc l0 + read_ref + move_loc l1 + read_ref + add + // @5 + ret -public point_add_assign(a: &mut u64, b: &u64): &mut u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](a: &mut u64) - 1: FreezeRef - 2: MoveLoc[1](b: &u64) - 3: LdTrue - 4: Call point_add_internal(&u64, &u64, bool): u64 - 5: Pop - 6: MoveLoc[0](a: &mut u64) - 7: Ret -} -point_add_internal(a: &u64, b: &u64, _in_place: bool): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: &u64) - 1: ReadRef - 2: MoveLoc[1](b: &u64) - 3: ReadRef - 4: Add - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.exp index 5a908076a7b..b43c3eb499d 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.exp @@ -1,30 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret + +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + move_loc l1 + read_ref + pop + // @10 + pop + ret -id_mut(r: &mut T): &mut T /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](r: &mut T) - 1: Ret -} -t0() /* def_idx: 1 */ { -L0: $t1: u64 -L1: x: &mut u64 -B0: - 0: LdU64(0) - 1: StLoc[0]($t1: u64) - 2: MutBorrowLoc[0]($t1: u64) - 3: StLoc[1](x: &mut u64) - 4: CopyLoc[1](x: &mut u64) - 5: Call id_mut(&mut u64): &mut u64 - 6: ReadRef - 7: MoveLoc[1](x: &mut u64) - 8: ReadRef - 9: Pop - 10: Pop - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.opt.exp index 55a1ad9ab15..1b10c59cde2 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/issue_14243.opt.exp @@ -1,30 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret + +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + pop + move_loc l1 + read_ref + // @10 + pop + ret -id_mut(r: &mut T): &mut T /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](r: &mut T) - 1: Ret -} -t0() /* def_idx: 1 */ { -L0: $t1: u64 -L1: x: &mut u64 -B0: - 0: LdU64(0) - 1: StLoc[0]($t1: u64) - 2: MutBorrowLoc[0]($t1: u64) - 3: StLoc[1](x: &mut u64) - 4: CopyLoc[1](x: &mut u64) - 5: Call id_mut(&mut u64): &mut u64 - 6: ReadRef - 7: Pop - 8: MoveLoc[1](x: &mut u64) - 9: ReadRef - 10: Pop - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp index 9a1186a17ca..7847da46caf 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp @@ -1,105 +1,90 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.loops { +// Bytecode version v9 +module 0x42::loops +// Function definition at index 0 +fun nested_loop(l0: u64): u64 +l5: copy_loc l0 + ld_u64 0 + gt + br_false l0 +l4: copy_loc l0 + // @5 + ld_u64 10 + gt + br_false l1 + move_loc l0 + ld_u64 1 + // @10 + sub + st_loc l0 + branch l2 + branch l3 +l1: branch l2 + // @15 +l3: branch l4 +l2: move_loc l0 + ld_u64 1 + sub + st_loc l0 + // @20 + branch l5 + branch l6 +l0: branch l7 +l6: branch l5 +l7: move_loc l0 + // @25 + ret + +// Function definition at index 1 +fun while_loop(l0: u64): u64 +l3: copy_loc l0 + ld_u64 0 + gt + br_false l0 + move_loc l0 + // @5 + ld_u64 1 + sub + st_loc l0 + branch l1 +l0: branch l2 + // @10 +l1: branch l3 +l2: move_loc l0 + ret + +// Function definition at index 2 +fun while_loop_with_break_and_continue(l0: u64): u64 +l4: copy_loc l0 + ld_u64 0 + gt + br_false l0 + copy_loc l0 + // @5 + ld_u64 42 + eq + br_false l1 + branch l2 + branch l1 + // @10 +l1: copy_loc l0 + ld_u64 21 + eq + br_false l3 + branch l4 + // @15 + branch l3 +l3: move_loc l0 + ld_u64 1 + sub + st_loc l0 + // @20 + branch l5 +l0: branch l2 +l5: branch l4 +l2: move_loc l0 + ret -nested_loop(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(22) -B1: - 4: CopyLoc[0](x: u64) - 5: LdU64(10) - 6: Gt - 7: BrFalse(14) -B2: - 8: MoveLoc[0](x: u64) - 9: LdU64(1) - 10: Sub - 11: StLoc[0](x: u64) - 12: Branch(16) -B3: - 13: Branch(15) -B4: - 14: Branch(16) -B5: - 15: Branch(4) -B6: - 16: MoveLoc[0](x: u64) - 17: LdU64(1) - 18: Sub - 19: StLoc[0](x: u64) - 20: Branch(0) -B7: - 21: Branch(23) -B8: - 22: Branch(24) -B9: - 23: Branch(0) -B10: - 24: MoveLoc[0](x: u64) - 25: Ret -} -while_loop(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(9) -B1: - 4: MoveLoc[0](x: u64) - 5: LdU64(1) - 6: Sub - 7: StLoc[0](x: u64) - 8: Branch(10) -B2: - 9: Branch(11) -B3: - 10: Branch(0) -B4: - 11: MoveLoc[0](x: u64) - 12: Ret -} -while_loop_with_break_and_continue(x: u64): u64 /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(21) -B1: - 4: CopyLoc[0](x: u64) - 5: LdU64(42) - 6: Eq - 7: BrFalse(10) -B2: - 8: Branch(23) -B3: - 9: Branch(10) -B4: - 10: CopyLoc[0](x: u64) - 11: LdU64(21) - 12: Eq - 13: BrFalse(16) -B5: - 14: Branch(0) -B6: - 15: Branch(16) -B7: - 16: MoveLoc[0](x: u64) - 17: LdU64(1) - 18: Sub - 19: StLoc[0](x: u64) - 20: Branch(22) -B8: - 21: Branch(23) -B9: - 22: Branch(0) -B10: - 23: MoveLoc[0](x: u64) - 24: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.opt.exp index 7fc2be39336..89869ac40c8 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.opt.exp @@ -1,84 +1,77 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.loops { +// Bytecode version v9 +module 0x42::loops +// Function definition at index 0 +fun nested_loop(l0: u64): u64 +l3: copy_loc l0 + ld_u64 0 + gt + br_false l0 + copy_loc l0 + // @5 + ld_u64 10 + gt + br_true l1 + branch l2 +l1: move_loc l0 + // @10 + ld_u64 1 + sub + st_loc l0 +l2: move_loc l0 + ld_u64 1 + // @15 + sub + st_loc l0 + branch l3 +l0: move_loc l0 + ret + +// Function definition at index 1 +fun while_loop(l0: u64): u64 +l1: copy_loc l0 + ld_u64 0 + gt + br_false l0 + move_loc l0 + // @5 + ld_u64 1 + sub + st_loc l0 + branch l1 +l0: move_loc l0 + // @10 + ret + +// Function definition at index 2 +fun while_loop_with_break_and_continue(l0: u64): u64 +l4: copy_loc l0 + ld_u64 0 + gt + br_true l0 + branch l1 + // @5 +l0: copy_loc l0 + ld_u64 42 + eq + br_false l2 + branch l1 + // @10 +l1: move_loc l0 + ret +l2: copy_loc l0 + ld_u64 21 + eq + // @15 + br_false l3 + branch l4 +l3: move_loc l0 + ld_u64 1 + sub + // @20 + st_loc l0 + branch l4 -nested_loop(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(18) -B1: - 4: CopyLoc[0](x: u64) - 5: LdU64(10) - 6: Gt - 7: BrTrue(9) -B2: - 8: Branch(13) -B3: - 9: MoveLoc[0](x: u64) - 10: LdU64(1) - 11: Sub - 12: StLoc[0](x: u64) -B4: - 13: MoveLoc[0](x: u64) - 14: LdU64(1) - 15: Sub - 16: StLoc[0](x: u64) - 17: Branch(0) -B5: - 18: MoveLoc[0](x: u64) - 19: Ret -} -while_loop(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(9) -B1: - 4: MoveLoc[0](x: u64) - 5: LdU64(1) - 6: Sub - 7: StLoc[0](x: u64) - 8: Branch(0) -B2: - 9: MoveLoc[0](x: u64) - 10: Ret -} -while_loop_with_break_and_continue(x: u64): u64 /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: LdU64(0) - 2: Gt - 3: BrTrue(5) -B1: - 4: Branch(10) -B2: - 5: CopyLoc[0](x: u64) - 6: LdU64(42) - 7: Eq - 8: BrFalse(12) -B3: - 9: Branch(10) -B4: - 10: MoveLoc[0](x: u64) - 11: Ret -B5: - 12: CopyLoc[0](x: u64) - 13: LdU64(21) - 14: Eq - 15: BrFalse(17) -B6: - 16: Branch(0) -B7: - 17: MoveLoc[0](x: u64) - 18: LdU64(1) - 19: Sub - 20: StLoc[0](x: u64) - 21: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.exp index 46cf2dd4587..0f983778994 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.exp @@ -1,21 +1,20 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: u64) + copy_loc l0 + copy_loc l0 + ld_u64 1 + move_loc l0 + call consume + // @5 + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test(x: u64) /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[0](x: u64) - 2: LdU64(1) - 3: MoveLoc[0](x: u64) - 4: Call consume(u64, u64, u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.opt.exp index 46cf2dd4587..0f983778994 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/multi_use.opt.exp @@ -1,21 +1,20 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: u64) + copy_loc l0 + copy_loc l0 + ld_u64 1 + move_loc l0 + call consume + // @5 + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test(x: u64) /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[0](x: u64) - 2: LdU64(1) - 3: MoveLoc[0](x: u64) - 4: Call consume(u64, u64, u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp index e76986789cb..f3584c853c4 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp @@ -1,174 +1,164 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.operators { +// Bytecode version v9 +module 0x42::operators +// Function definition at index 0 +fun arithm(l0: u64, l1: u64): u64 + copy_loc l0 + copy_loc l1 + copy_loc l0 + copy_loc l1 + sub + // @5 + div + move_loc l1 + mul + move_loc l0 + mod + // @10 + add + ret + +// Function definition at index 1 +fun bits(l0: u64, l1: u8): u64 + copy_loc l0 + copy_loc l1 + shl + copy_loc l0 + bit_and + // @5 + copy_loc l0 + move_loc l1 + shr + move_loc l0 + xor + // @10 + bit_or + ret + +// Function definition at index 2 +fun bools(l0: bool, l1: bool): bool + local l2: bool + local l3: bool + local l4: bool + local l5: bool + copy_loc l0 + br_false l0 + copy_loc l1 + st_loc l2 + branch l1 + // @5 +l0: ld_false + st_loc l2 +l1: move_loc l2 + br_false l2 + ld_true + // @10 + st_loc l3 + branch l3 +l2: copy_loc l0 + br_false l4 + copy_loc l1 + // @15 + not + st_loc l3 + branch l3 +l4: ld_false + st_loc l3 + // @20 +l3: move_loc l3 + br_false l5 + ld_true + st_loc l4 + branch l6 + // @25 +l5: copy_loc l0 + not + br_false l7 + copy_loc l1 + st_loc l4 + // @30 + branch l6 +l7: ld_false + st_loc l4 +l6: move_loc l4 + br_false l8 + // @35 + ld_true + st_loc l5 + branch l9 +l8: move_loc l0 + not + // @40 + br_false l10 + move_loc l1 + not + st_loc l5 + branch l9 + // @45 +l10: ld_false + st_loc l5 +l9: move_loc l5 + ret + +// Function definition at index 3 +fun equality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + eq + ret + +// Function definition at index 4 +fun inequality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + neq + ret + +// Function definition at index 5 +fun order(l0: u64, l1: u64): bool + local l2: bool + local l3: bool + local l4: bool + copy_loc l0 + copy_loc l1 + lt + br_false l0 + copy_loc l0 + // @5 + copy_loc l1 + le + st_loc l2 + branch l1 +l0: ld_false + // @10 + st_loc l2 +l1: move_loc l2 + br_false l2 + copy_loc l0 + copy_loc l1 + // @15 + gt + not + st_loc l3 + branch l3 +l2: ld_false + // @20 + st_loc l3 +l3: move_loc l3 + br_false l4 + move_loc l0 + move_loc l1 + // @25 + ge + not + st_loc l4 + branch l5 +l4: ld_false + // @30 + st_loc l4 +l5: move_loc l4 + ret -arithm(x: u64, y: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: CopyLoc[0](x: u64) - 3: CopyLoc[1](y: u64) - 4: Sub - 5: Div - 6: MoveLoc[1](y: u64) - 7: Mul - 8: MoveLoc[0](x: u64) - 9: Mod - 10: Add - 11: Ret -} -bits(x: u64, y: u8): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u8) - 2: Shl - 3: CopyLoc[0](x: u64) - 4: BitAnd - 5: CopyLoc[0](x: u64) - 6: MoveLoc[1](y: u8) - 7: Shr - 8: MoveLoc[0](x: u64) - 9: Xor - 10: BitOr - 11: Ret -} -bools(x: bool, y: bool): bool /* def_idx: 2 */ { -L2: $t5: bool -L3: $t4: bool -L4: $t3: bool -L5: return: bool -B0: - 0: CopyLoc[0](x: bool) - 1: BrFalse(5) -B1: - 2: CopyLoc[1](y: bool) - 3: StLoc[2]($t5: bool) - 4: Branch(7) -B2: - 5: LdFalse - 6: StLoc[2]($t5: bool) -B3: - 7: MoveLoc[2]($t5: bool) - 8: BrFalse(12) -B4: - 9: LdTrue - 10: StLoc[3]($t4: bool) - 11: Branch(20) -B5: - 12: CopyLoc[0](x: bool) - 13: BrFalse(18) -B6: - 14: CopyLoc[1](y: bool) - 15: Not - 16: StLoc[3]($t4: bool) - 17: Branch(20) -B7: - 18: LdFalse - 19: StLoc[3]($t4: bool) -B8: - 20: MoveLoc[3]($t4: bool) - 21: BrFalse(25) -B9: - 22: LdTrue - 23: StLoc[4]($t3: bool) - 24: Branch(33) -B10: - 25: CopyLoc[0](x: bool) - 26: Not - 27: BrFalse(31) -B11: - 28: CopyLoc[1](y: bool) - 29: StLoc[4]($t3: bool) - 30: Branch(33) -B12: - 31: LdFalse - 32: StLoc[4]($t3: bool) -B13: - 33: MoveLoc[4]($t3: bool) - 34: BrFalse(38) -B14: - 35: LdTrue - 36: StLoc[5](return: bool) - 37: Branch(47) -B15: - 38: MoveLoc[0](x: bool) - 39: Not - 40: BrFalse(45) -B16: - 41: MoveLoc[1](y: bool) - 42: Not - 43: StLoc[5](return: bool) - 44: Branch(47) -B17: - 45: LdFalse - 46: StLoc[5](return: bool) -B18: - 47: MoveLoc[5](return: bool) - 48: Ret -} -equality(x: T, y: T): bool /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Eq - 3: Ret -} -inequality(x: T, y: T): bool /* def_idx: 4 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Neq - 3: Ret -} -order(x: u64, y: u64): bool /* def_idx: 5 */ { -L2: $t4: bool -L3: $t3: bool -L4: return: bool -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: Lt - 3: BrFalse(9) -B1: - 4: CopyLoc[0](x: u64) - 5: CopyLoc[1](y: u64) - 6: Le - 7: StLoc[2]($t4: bool) - 8: Branch(11) -B2: - 9: LdFalse - 10: StLoc[2]($t4: bool) -B3: - 11: MoveLoc[2]($t4: bool) - 12: BrFalse(19) -B4: - 13: CopyLoc[0](x: u64) - 14: CopyLoc[1](y: u64) - 15: Gt - 16: Not - 17: StLoc[3]($t3: bool) - 18: Branch(21) -B5: - 19: LdFalse - 20: StLoc[3]($t3: bool) -B6: - 21: MoveLoc[3]($t3: bool) - 22: BrFalse(29) -B7: - 23: MoveLoc[0](x: u64) - 24: MoveLoc[1](y: u64) - 25: Ge - 26: Not - 27: StLoc[4](return: bool) - 28: Branch(31) -B8: - 29: LdFalse - 30: StLoc[4](return: bool) -B9: - 31: MoveLoc[4](return: bool) - 32: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.opt.exp index 0229796ab6b..1543d76323a 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.opt.exp @@ -1,172 +1,151 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.operators { +// Bytecode version v9 +module 0x42::operators +// Function definition at index 0 +fun arithm(l0: u64, l1: u64): u64 + copy_loc l0 + copy_loc l1 + copy_loc l0 + copy_loc l1 + sub + // @5 + div + move_loc l1 + mul + move_loc l0 + mod + // @10 + add + ret + +// Function definition at index 1 +fun bits(l0: u64, l1: u8): u64 + copy_loc l0 + copy_loc l1 + shl + copy_loc l0 + bit_and + // @5 + copy_loc l0 + move_loc l1 + shr + move_loc l0 + xor + // @10 + bit_or + ret + +// Function definition at index 2 +fun bools(l0: bool, l1: bool): bool + local l2: bool + local l3: bool + local l4: bool + copy_loc l0 + br_false l0 + copy_loc l1 + st_loc l2 +l9: move_loc l2 + // @5 + br_false l1 + ld_true + st_loc l3 +l8: move_loc l3 + br_false l2 + // @10 + ld_true + st_loc l4 +l6: move_loc l4 + br_false l3 + ld_true + // @15 + ret +l3: move_loc l0 + br_true l4 + move_loc l1 + not + // @20 + ret +l4: ld_false + ret +l2: copy_loc l0 + br_true l5 + // @25 + copy_loc l1 + st_loc l4 + branch l6 +l5: ld_false + st_loc l4 + // @30 + branch l6 +l1: copy_loc l0 + br_false l7 + copy_loc l1 + not + // @35 + st_loc l3 + branch l8 +l7: ld_false + st_loc l3 + branch l8 + // @40 +l0: ld_false + st_loc l2 + branch l9 + +// Function definition at index 3 +fun equality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + eq + ret + +// Function definition at index 4 +fun inequality(l0: T0, l1: T0): bool + move_loc l0 + move_loc l1 + neq + ret + +// Function definition at index 5 +fun order(l0: u64, l1: u64): bool + local l2: bool + local l3: bool + copy_loc l0 + copy_loc l1 + lt + br_false l0 + copy_loc l0 + // @5 + copy_loc l1 + le + st_loc l2 +l4: move_loc l2 + br_false l1 + // @10 + copy_loc l0 + copy_loc l1 + gt + not + st_loc l3 + // @15 +l3: move_loc l3 + br_false l2 + move_loc l0 + move_loc l1 + ge + // @20 + not + ret +l2: ld_false + ret +l1: ld_false + // @25 + st_loc l3 + branch l3 +l0: ld_false + st_loc l2 + branch l4 -arithm(x: u64, y: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: CopyLoc[0](x: u64) - 3: CopyLoc[1](y: u64) - 4: Sub - 5: Div - 6: MoveLoc[1](y: u64) - 7: Mul - 8: MoveLoc[0](x: u64) - 9: Mod - 10: Add - 11: Ret -} -bits(x: u64, y: u8): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u8) - 2: Shl - 3: CopyLoc[0](x: u64) - 4: BitAnd - 5: CopyLoc[0](x: u64) - 6: MoveLoc[1](y: u8) - 7: Shr - 8: MoveLoc[0](x: u64) - 9: Xor - 10: BitOr - 11: Ret -} -bools(x: bool, y: bool): bool /* def_idx: 2 */ { -L2: $t5: bool -L3: $t4: bool -L4: $t3: bool -L5: return: bool -B0: - 0: CopyLoc[0](x: bool) - 1: BrFalse(44) -B1: - 2: CopyLoc[1](y: bool) - 3: StLoc[2]($t5: bool) -B2: - 4: MoveLoc[2]($t5: bool) - 5: BrFalse(35) -B3: - 6: LdTrue - 7: StLoc[3]($t4: bool) -B4: - 8: MoveLoc[3]($t4: bool) - 9: BrFalse(27) -B5: - 10: LdTrue - 11: StLoc[4]($t3: bool) -B6: - 12: MoveLoc[4]($t3: bool) - 13: BrFalse(18) -B7: - 14: LdTrue - 15: StLoc[5](return: bool) -B8: - 16: MoveLoc[5](return: bool) - 17: Ret -B9: - 18: MoveLoc[0](x: bool) - 19: BrTrue(24) -B10: - 20: MoveLoc[1](y: bool) - 21: Not - 22: StLoc[5](return: bool) - 23: Branch(16) -B11: - 24: LdFalse - 25: StLoc[5](return: bool) - 26: Branch(16) -B12: - 27: CopyLoc[0](x: bool) - 28: BrTrue(32) -B13: - 29: CopyLoc[1](y: bool) - 30: StLoc[4]($t3: bool) - 31: Branch(12) -B14: - 32: LdFalse - 33: StLoc[4]($t3: bool) - 34: Branch(12) -B15: - 35: CopyLoc[0](x: bool) - 36: BrFalse(41) -B16: - 37: CopyLoc[1](y: bool) - 38: Not - 39: StLoc[3]($t4: bool) - 40: Branch(8) -B17: - 41: LdFalse - 42: StLoc[3]($t4: bool) - 43: Branch(8) -B18: - 44: LdFalse - 45: StLoc[2]($t5: bool) - 46: Branch(4) -} -equality(x: T, y: T): bool /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Eq - 3: Ret -} -inequality(x: T, y: T): bool /* def_idx: 4 */ { -B0: - 0: MoveLoc[0](x: T) - 1: MoveLoc[1](y: T) - 2: Neq - 3: Ret -} -order(x: u64, y: u64): bool /* def_idx: 5 */ { -L2: $t5: bool -L3: $t8: bool -L4: $t10: bool -B0: - 0: CopyLoc[0](x: u64) - 1: CopyLoc[1](y: u64) - 2: Lt - 3: BrFalse(30) -B1: - 4: CopyLoc[0](x: u64) - 5: CopyLoc[1](y: u64) - 6: Le - 7: StLoc[2]($t5: bool) -B2: - 8: MoveLoc[2]($t5: bool) - 9: BrFalse(27) -B3: - 10: CopyLoc[0](x: u64) - 11: CopyLoc[1](y: u64) - 12: Gt - 13: Not - 14: StLoc[3]($t8: bool) -B4: - 15: MoveLoc[3]($t8: bool) - 16: BrFalse(24) -B5: - 17: MoveLoc[0](x: u64) - 18: MoveLoc[1](y: u64) - 19: Ge - 20: Not - 21: StLoc[4]($t10: bool) -B6: - 22: MoveLoc[4]($t10: bool) - 23: Ret -B7: - 24: LdFalse - 25: StLoc[4]($t10: bool) - 26: Branch(22) -B8: - 27: LdFalse - 28: StLoc[3]($t8: bool) - 29: Branch(15) -B9: - 30: LdFalse - 31: StLoc[2]($t5: bool) - 32: Branch(8) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.exp index ca6d698e243..e3e5dadd1a5 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.exp @@ -1,52 +1,54 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test01(l0: u64) + move_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume + ret + +// Function definition at index 2 +#[persistent] public fun test02(l0: u64) + copy_loc l0 + ld_u64 1 + ld_u64 2 + move_loc l0 + ld_u64 4 + // @5 + ld_u64 5 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test03(l0: u64) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume + move_loc l0 + ld_u64 1 + ld_u64 2 + // @10 + ld_u64 3 + ld_u64 4 + ld_u64 5 + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test01(a: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: Ret -} -public test02(a: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: MoveLoc[0](a: u64) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: Ret -} -public test03(a: u64) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: MoveLoc[0](a: u64) - 8: LdU64(1) - 9: LdU64(2) - 10: LdU64(3) - 11: LdU64(4) - 12: LdU64(5) - 13: Call consume(u64, u64, u64, u64, u64, u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.opt.exp index ca6d698e243..e3e5dadd1a5 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_01.opt.exp @@ -1,52 +1,54 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test01(l0: u64) + move_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume + ret + +// Function definition at index 2 +#[persistent] public fun test02(l0: u64) + copy_loc l0 + ld_u64 1 + ld_u64 2 + move_loc l0 + ld_u64 4 + // @5 + ld_u64 5 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test03(l0: u64) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume + move_loc l0 + ld_u64 1 + ld_u64 2 + // @10 + ld_u64 3 + ld_u64 4 + ld_u64 5 + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test01(a: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: Ret -} -public test02(a: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: MoveLoc[0](a: u64) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: Ret -} -public test03(a: u64) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume(u64, u64, u64, u64, u64, u64) - 7: MoveLoc[0](a: u64) - 8: LdU64(1) - 9: LdU64(2) - 10: LdU64(3) - 11: LdU64(4) - 12: LdU64(5) - 13: Call consume(u64, u64, u64, u64, u64, u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.exp index 4a28d198124..1b748448f19 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.exp @@ -1,93 +1,99 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + +// Function definition at index 0 +fun consume1(l0: &S, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun consume2(l0: &S, l1: u64, l2: u64, l3: &S, l4: u64, l5: u64) + move_loc l0 + pop + move_loc l3 + pop + ret + +// Function definition at index 2 +fun consume3(l0: &S, l1: u64, l2: u64, l3: u64, l4: &u64, l5: u64) + move_loc l0 + pop + move_loc l4 + pop + ret + +// Function definition at index 3 +#[persistent] public fun test01(l0: &S) + move_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume1 + ret + +// Function definition at index 4 +#[persistent] public fun test02(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + move_loc l0 + ld_u64 4 + // @5 + ld_u64 5 + call consume2 + ret + +// Function definition at index 5 +#[persistent] public fun test03(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume1 + move_loc l0 + ld_u64 1 + ld_u64 2 + // @10 + ld_u64 3 + ld_u64 4 + ld_u64 5 + call consume1 + ret + +// Function definition at index 6 +#[persistent] public fun test04(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + copy_loc l0 + // @5 + borrow_field S, x + ld_u64 5 + call consume3 + copy_loc l0 + ld_u64 1 + // @10 + ld_u64 2 + ld_u64 3 + move_loc l0 + borrow_field S, x + read_ref + // @15 + ld_u64 5 + call consume1 + ret + -consume1(_a: &S, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: Ret -} -consume2(_a: &S, _b: u64, _c: u64, _d: &S, _e: u64, _f: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: MoveLoc[3](_d: &S) - 3: Pop - 4: Ret -} -consume3(_a: &S, _b: u64, _c: u64, _d: u64, _e: &u64, _f: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: MoveLoc[4](_e: &u64) - 3: Pop - 4: Ret -} -public test01(a: &S) /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume1(&S, u64, u64, u64, u64, u64) - 7: Ret -} -public test02(a: &S) /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: MoveLoc[0](a: &S) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume2(&S, u64, u64, &S, u64, u64) - 7: Ret -} -public test03(a: &S) /* def_idx: 5 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume1(&S, u64, u64, u64, u64, u64) - 7: MoveLoc[0](a: &S) - 8: LdU64(1) - 9: LdU64(2) - 10: LdU64(3) - 11: LdU64(4) - 12: LdU64(5) - 13: Call consume1(&S, u64, u64, u64, u64, u64) - 14: Ret -} -public test04(a: &S) /* def_idx: 6 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: CopyLoc[0](a: &S) - 5: ImmBorrowField[0](S.x: u64) - 6: LdU64(5) - 7: Call consume3(&S, u64, u64, u64, &u64, u64) - 8: CopyLoc[0](a: &S) - 9: LdU64(1) - 10: LdU64(2) - 11: LdU64(3) - 12: MoveLoc[0](a: &S) - 13: ImmBorrowField[0](S.x: u64) - 14: ReadRef - 15: LdU64(5) - 16: Call consume1(&S, u64, u64, u64, u64, u64) - 17: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.opt.exp index 4a28d198124..1b748448f19 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_02.opt.exp @@ -1,93 +1,99 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S + x: u64 + +// Function definition at index 0 +fun consume1(l0: &S, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun consume2(l0: &S, l1: u64, l2: u64, l3: &S, l4: u64, l5: u64) + move_loc l0 + pop + move_loc l3 + pop + ret + +// Function definition at index 2 +fun consume3(l0: &S, l1: u64, l2: u64, l3: u64, l4: &u64, l5: u64) + move_loc l0 + pop + move_loc l4 + pop + ret + +// Function definition at index 3 +#[persistent] public fun test01(l0: &S) + move_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume1 + ret + +// Function definition at index 4 +#[persistent] public fun test02(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + move_loc l0 + ld_u64 4 + // @5 + ld_u64 5 + call consume2 + ret + +// Function definition at index 5 +#[persistent] public fun test03(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + // @5 + ld_u64 5 + call consume1 + move_loc l0 + ld_u64 1 + ld_u64 2 + // @10 + ld_u64 3 + ld_u64 4 + ld_u64 5 + call consume1 + ret + +// Function definition at index 6 +#[persistent] public fun test04(l0: &S) + copy_loc l0 + ld_u64 1 + ld_u64 2 + ld_u64 3 + copy_loc l0 + // @5 + borrow_field S, x + ld_u64 5 + call consume3 + copy_loc l0 + ld_u64 1 + // @10 + ld_u64 2 + ld_u64 3 + move_loc l0 + borrow_field S, x + read_ref + // @15 + ld_u64 5 + call consume1 + ret + -consume1(_a: &S, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: Ret -} -consume2(_a: &S, _b: u64, _c: u64, _d: &S, _e: u64, _f: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: MoveLoc[3](_d: &S) - 3: Pop - 4: Ret -} -consume3(_a: &S, _b: u64, _c: u64, _d: u64, _e: &u64, _f: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](_a: &S) - 1: Pop - 2: MoveLoc[4](_e: &u64) - 3: Pop - 4: Ret -} -public test01(a: &S) /* def_idx: 3 */ { -B0: - 0: MoveLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume1(&S, u64, u64, u64, u64, u64) - 7: Ret -} -public test02(a: &S) /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: MoveLoc[0](a: &S) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume2(&S, u64, u64, &S, u64, u64) - 7: Ret -} -public test03(a: &S) /* def_idx: 5 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: LdU64(4) - 5: LdU64(5) - 6: Call consume1(&S, u64, u64, u64, u64, u64) - 7: MoveLoc[0](a: &S) - 8: LdU64(1) - 9: LdU64(2) - 10: LdU64(3) - 11: LdU64(4) - 12: LdU64(5) - 13: Call consume1(&S, u64, u64, u64, u64, u64) - 14: Ret -} -public test04(a: &S) /* def_idx: 6 */ { -B0: - 0: CopyLoc[0](a: &S) - 1: LdU64(1) - 2: LdU64(2) - 3: LdU64(3) - 4: CopyLoc[0](a: &S) - 5: ImmBorrowField[0](S.x: u64) - 6: LdU64(5) - 7: Call consume3(&S, u64, u64, u64, &u64, u64) - 8: CopyLoc[0](a: &S) - 9: LdU64(1) - 10: LdU64(2) - 11: LdU64(3) - 12: MoveLoc[0](a: &S) - 13: ImmBorrowField[0](S.x: u64) - 14: ReadRef - 15: LdU64(5) - 16: Call consume1(&S, u64, u64, u64, u64, u64) - 17: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.exp index b249f5ff6cd..124ef3f75e4 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: &mut u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun baz(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 2 +#[persistent] public fun foo(l0: u64) + mut_borrow_loc l0 + call bar + move_loc l0 + ld_u64 1 + ld_u64 2 + // @5 + call baz + ret -bar(_x: &mut u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_x: &mut u64) - 1: Pop - 2: Ret -} -baz(_x: u64, _y: u64, _z: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public foo(x: u64) /* def_idx: 2 */ { -B0: - 0: MutBorrowLoc[0](x: u64) - 1: Call bar(&mut u64) - 2: MoveLoc[0](x: u64) - 3: LdU64(1) - 4: LdU64(2) - 5: Call baz(u64, u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.opt.exp index b249f5ff6cd..124ef3f75e4 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_04.opt.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar(l0: &mut u64) + move_loc l0 + pop + ret + +// Function definition at index 1 +fun baz(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 2 +#[persistent] public fun foo(l0: u64) + mut_borrow_loc l0 + call bar + move_loc l0 + ld_u64 1 + ld_u64 2 + // @5 + call baz + ret -bar(_x: &mut u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](_x: &mut u64) - 1: Pop - 2: Ret -} -baz(_x: u64, _y: u64, _z: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public foo(x: u64) /* def_idx: 2 */ { -B0: - 0: MutBorrowLoc[0](x: u64) - 1: Call bar(&mut u64) - 2: MoveLoc[0](x: u64) - 3: LdU64(1) - 4: LdU64(2) - 5: Call baz(u64, u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.exp index e79f6c15a57..b809477e7e5 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.exp @@ -1,53 +1,53 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume1(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + move_loc l0 + ld_u64 1 + call consume1 + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: u64) + call one + move_loc l0 + ld_u64 2 + call consume1 + ret + +// Function definition at index 4 +#[persistent] public fun test3(l0: u64) + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + call one + move_loc l0 + st_loc l1 + st_loc l2 + move_loc l2 + // @5 + ld_u64 3 + st_loc l3 + st_loc l4 + move_loc l1 + move_loc l4 + // @10 + move_loc l3 + call consume1 + ret -consume1(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test1(p: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](p: u64) - 1: MoveLoc[0](p: u64) - 2: LdU64(1) - 3: Call consume1(u64, u64, u64) - 4: Ret -} -public test2(p: u64) /* def_idx: 3 */ { -B0: - 0: Call one(): u64 - 1: MoveLoc[0](p: u64) - 2: LdU64(2) - 3: Call consume1(u64, u64, u64) - 4: Ret -} -public test3(p: u64) /* def_idx: 4 */ { -L1: $t2: u64 -L2: q: u64 -L3: $t4: u64 -L4: $t3: u64 -B0: - 0: Call one(): u64 - 1: MoveLoc[0](p: u64) - 2: StLoc[1]($t2: u64) - 3: StLoc[2](q: u64) - 4: MoveLoc[2](q: u64) - 5: LdU64(3) - 6: StLoc[3]($t4: u64) - 7: StLoc[4]($t3: u64) - 8: MoveLoc[1]($t2: u64) - 9: MoveLoc[4]($t3: u64) - 10: MoveLoc[3]($t4: u64) - 11: Call consume1(u64, u64, u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.opt.exp index bcf5f5d3593..3350e45c540 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/opt_load_05.opt.exp @@ -1,44 +1,43 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume1(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + move_loc l0 + ld_u64 1 + call consume1 + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: u64) + call one + move_loc l0 + ld_u64 2 + call consume1 + ret + +// Function definition at index 4 +#[persistent] public fun test3(l0: u64) + local l1: u64 + call one + st_loc l1 + move_loc l0 + move_loc l1 + ld_u64 3 + // @5 + call consume1 + ret -consume1(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test1(p: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](p: u64) - 1: MoveLoc[0](p: u64) - 2: LdU64(1) - 3: Call consume1(u64, u64, u64) - 4: Ret -} -public test2(p: u64) /* def_idx: 3 */ { -B0: - 0: Call one(): u64 - 1: MoveLoc[0](p: u64) - 2: LdU64(2) - 3: Call consume1(u64, u64, u64) - 4: Ret -} -public test3(p: u64) /* def_idx: 4 */ { -L1: q: u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](q: u64) - 2: MoveLoc[0](p: u64) - 3: MoveLoc[1](q: u64) - 4: LdU64(3) - 5: Call consume1(u64, u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.exp index 93cd75c67c8..d63972fe2b2 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.exp @@ -1,108 +1,116 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct S { - f1: u8, - f2: u8, - f3: u8 -} +// Bytecode version v9 +module 0x42::pack_unpack +struct S + f1: u8 + f2: u8 + f3: u8 + +// Function definition at index 0 +fun pack1(l0: u8, l1: u8, l2: u8): S + move_loc l0 + move_loc l1 + move_loc l2 + pack S + ret + +// Function definition at index 1 +fun pack2(l0: u8, l1: u8, l2: u8): S + local l3: u8 + local l4: u8 + move_loc l0 + move_loc l1 + st_loc l3 + st_loc l4 + move_loc l4 + // @5 + move_loc l2 + move_loc l3 + pack S + ret + +// Function definition at index 2 +fun pack3(l0: u8, l1: u8, l2: u8): S + local l3: u8 + local l4: u8 + local l5: u8 + move_loc l0 + move_loc l1 + st_loc l3 + st_loc l4 + move_loc l4 + // @5 + st_loc l5 + move_loc l3 + move_loc l5 + move_loc l2 + pack S + // @10 + ret + +// Function definition at index 3 +fun pack4(l0: u8, l1: u8, l2: u8): S + local l3: u8 + local l4: u8 + local l5: u8 + local l6: u8 + move_loc l0 + move_loc l1 + move_loc l2 + st_loc l3 + st_loc l4 + // @5 + st_loc l5 + move_loc l5 + st_loc l6 + move_loc l3 + move_loc l6 + // @10 + move_loc l4 + pack S + ret + +// Function definition at index 4 +fun pack5(l0: u8, l1: u8, l2: u8): S + local l3: u8 + local l4: u8 + local l5: u8 + move_loc l0 + move_loc l1 + move_loc l2 + st_loc l3 + st_loc l4 + // @5 + st_loc l5 + move_loc l4 + move_loc l3 + move_loc l5 + pack S + // @10 + ret + +// Function definition at index 5 +fun pack6(l0: u8, l1: u8, l2: u8): S + local l3: u8 + local l4: u8 + local l5: u8 + local l6: u8 + move_loc l0 + move_loc l1 + move_loc l2 + st_loc l3 + st_loc l4 + // @5 + move_loc l4 + st_loc l5 + st_loc l6 + move_loc l3 + move_loc l5 + // @10 + move_loc l6 + pack S + ret + -pack1(x: u8, y: u8, z: u8): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: Pack[0](S) - 4: Ret -} -pack2(x: u8, y: u8, z: u8): S /* def_idx: 1 */ { -L3: $f3: u8 -L4: $f1: u8 -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: StLoc[3]($f3: u8) - 3: StLoc[4]($f1: u8) - 4: MoveLoc[4]($f1: u8) - 5: MoveLoc[2](z: u8) - 6: MoveLoc[3]($f3: u8) - 7: Pack[0](S) - 8: Ret -} -pack3(x: u8, y: u8, z: u8): S /* def_idx: 2 */ { -L3: $t5: u8 -L4: $f2: u8 -L5: $t6: u8 -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: StLoc[3]($t5: u8) - 3: StLoc[4]($f2: u8) - 4: MoveLoc[4]($f2: u8) - 5: StLoc[5]($t6: u8) - 6: MoveLoc[3]($t5: u8) - 7: MoveLoc[5]($t6: u8) - 8: MoveLoc[2](z: u8) - 9: Pack[0](S) - 10: Ret -} -pack4(x: u8, y: u8, z: u8): S /* def_idx: 3 */ { -L3: $t6: u8 -L4: $f3: u8 -L5: $f2: u8 -L6: $t7: u8 -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: StLoc[3]($t6: u8) - 4: StLoc[4]($f3: u8) - 5: StLoc[5]($f2: u8) - 6: MoveLoc[5]($f2: u8) - 7: StLoc[6]($t7: u8) - 8: MoveLoc[3]($t6: u8) - 9: MoveLoc[6]($t7: u8) - 10: MoveLoc[4]($f3: u8) - 11: Pack[0](S) - 12: Ret -} -pack5(x: u8, y: u8, z: u8): S /* def_idx: 4 */ { -L3: $t6: u8 -L4: $t5: u8 -L5: $f3: u8 -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: StLoc[3]($t6: u8) - 4: StLoc[4]($t5: u8) - 5: StLoc[5]($f3: u8) - 6: MoveLoc[4]($t5: u8) - 7: MoveLoc[3]($t6: u8) - 8: MoveLoc[5]($f3: u8) - 9: Pack[0](S) - 10: Ret -} -pack6(x: u8, y: u8, z: u8): S /* def_idx: 5 */ { -L3: $t6: u8 -L4: $f2: u8 -L5: $t7: u8 -L6: $f3: u8 -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: StLoc[3]($t6: u8) - 4: StLoc[4]($f2: u8) - 5: MoveLoc[4]($f2: u8) - 6: StLoc[5]($t7: u8) - 7: StLoc[6]($f3: u8) - 8: MoveLoc[3]($t6: u8) - 9: MoveLoc[5]($t7: u8) - 10: MoveLoc[6]($f3: u8) - 11: Pack[0](S) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.opt.exp index 2937a0012ef..2a0ab7eaaac 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_order.opt.exp @@ -1,60 +1,59 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct S { - f1: u8, - f2: u8, - f3: u8 -} - -pack1(x: u8, y: u8, z: u8): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[2](z: u8) - 3: Pack[0](S) - 4: Ret -} -pack2(x: u8, y: u8, z: u8): S /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u8) - 1: MoveLoc[2](z: u8) - 2: MoveLoc[1](y: u8) - 3: Pack[0](S) - 4: Ret -} -pack3(x: u8, y: u8, z: u8): S /* def_idx: 2 */ { -B0: - 0: MoveLoc[1](y: u8) - 1: MoveLoc[0](x: u8) - 2: MoveLoc[2](z: u8) - 3: Pack[0](S) - 4: Ret -} -pack4(x: u8, y: u8, z: u8): S /* def_idx: 3 */ { -B0: - 0: MoveLoc[2](z: u8) - 1: MoveLoc[0](x: u8) - 2: MoveLoc[1](y: u8) - 3: Pack[0](S) - 4: Ret -} -pack5(x: u8, y: u8, z: u8): S /* def_idx: 4 */ { -B0: - 0: MoveLoc[1](y: u8) - 1: MoveLoc[2](z: u8) - 2: MoveLoc[0](x: u8) - 3: Pack[0](S) - 4: Ret -} -pack6(x: u8, y: u8, z: u8): S /* def_idx: 5 */ { -B0: - 0: MoveLoc[2](z: u8) - 1: MoveLoc[1](y: u8) - 2: MoveLoc[0](x: u8) - 3: Pack[0](S) - 4: Ret -} -} +// Bytecode version v9 +module 0x42::pack_unpack +struct S + f1: u8 + f2: u8 + f3: u8 + +// Function definition at index 0 +fun pack1(l0: u8, l1: u8, l2: u8): S + move_loc l0 + move_loc l1 + move_loc l2 + pack S + ret + +// Function definition at index 1 +fun pack2(l0: u8, l1: u8, l2: u8): S + move_loc l0 + move_loc l2 + move_loc l1 + pack S + ret + +// Function definition at index 2 +fun pack3(l0: u8, l1: u8, l2: u8): S + move_loc l1 + move_loc l0 + move_loc l2 + pack S + ret + +// Function definition at index 3 +fun pack4(l0: u8, l1: u8, l2: u8): S + move_loc l2 + move_loc l0 + move_loc l1 + pack S + ret + +// Function definition at index 4 +fun pack5(l0: u8, l1: u8, l2: u8): S + move_loc l1 + move_loc l2 + move_loc l0 + pack S + ret + +// Function definition at index 5 +fun pack6(l0: u8, l1: u8, l2: u8): S + move_loc l2 + move_loc l1 + move_loc l0 + pack S + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp index aad9a41b8dc..220a3d69b3e 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp @@ -1,35 +1,35 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct T { - h: u64 -} -struct S { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::pack_unpack +struct T + h: u64 + +struct S + f: u64 + g: T + +// Function definition at index 0 +fun pack(l0: u64, l1: u64): S + move_loc l0 + move_loc l1 + pack T + pack S + ret + +// Function definition at index 1 +fun unpack(l0: S): (u64, u64) + local l1: u64 + local l2: u64 + move_loc l0 + unpack S + unpack T + st_loc l1 + st_loc l2 + // @5 + move_loc l2 + move_loc l1 + ret + -pack(x: u64, y: u64): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: Pack[0](T) - 3: Pack[1](S) - 4: Ret -} -unpack(s: S): u64 * u64 /* def_idx: 1 */ { -L1: h: u64 -L2: f: u64 -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: StLoc[1](h: u64) - 4: StLoc[2](f: u64) - 5: MoveLoc[2](f: u64) - 6: MoveLoc[1](h: u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.opt.exp index de70cb0949c..c43b3448b8c 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.opt.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack { -struct T { - h: u64 -} -struct S { - f: u64, - g: T -} +// Bytecode version v9 +module 0x42::pack_unpack +struct T + h: u64 + +struct S + f: u64 + g: T + +// Function definition at index 0 +fun pack(l0: u64, l1: u64): S + move_loc l0 + move_loc l1 + pack T + pack S + ret + +// Function definition at index 1 +fun unpack(l0: S): (u64, u64) + local l1: u64 + local l2: u64 + move_loc l0 + unpack S + unpack T + ret + -pack(x: u64, y: u64): S /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: Pack[0](T) - 3: Pack[1](S) - 4: Ret -} -unpack(s: S): u64 * u64 /* def_idx: 1 */ { -L1: h: u64 -L2: f: u64 -B0: - 0: MoveLoc[0](s: S) - 1: Unpack[1](S) - 2: Unpack[0](T) - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.exp index 70687fe54b4..50e6750486a 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.exp @@ -1,80 +1,87 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack_ref { -struct G { - x1: u64, - x2: u64, - s: S -} -struct S { - f: u64, - g: u64 -} +// Bytecode version v9 +module 0x42::pack_unpack_ref +struct G + x1: u64 + x2: u64 + s: S + +struct S + f: u64 + g: u64 + +// Function definition at index 0 +fun unpack_mut_ref(l0: &mut S): (u64, u64) + local l1: &mut u64 + local l2: &mut u64 + copy_loc l0 + mut_borrow_field S, f + move_loc l0 + mut_borrow_field S, g + st_loc l1 + // @5 + st_loc l2 + move_loc l2 + read_ref + move_loc l1 + read_ref + // @10 + ret + +// Function definition at index 1 +fun unpack_ref(l0: &S): (u64, u64) + local l1: &u64 + local l2: &u64 + copy_loc l0 + borrow_field S, f + move_loc l0 + borrow_field S, g + st_loc l1 + // @5 + st_loc l2 + move_loc l2 + read_ref + move_loc l1 + read_ref + // @10 + ret + +// Function definition at index 2 +fun unpack_ref_G(l0: &G): (u64, u64, u64, u64) + local l1: &S + local l2: &u64 + local l3: &u64 + local l4: &u64 + local l5: &u64 + copy_loc l0 + borrow_field G, x1 + copy_loc l0 + borrow_field G, x2 + move_loc l0 + // @5 + borrow_field G, s + st_loc l1 + copy_loc l1 + borrow_field S, f + move_loc l1 + // @10 + borrow_field S, g + st_loc l2 + st_loc l3 + st_loc l4 + st_loc l5 + // @15 + move_loc l5 + read_ref + move_loc l4 + read_ref + move_loc l3 + // @20 + read_ref + move_loc l2 + read_ref + ret + -unpack_mut_ref(s: &mut S): u64 * u64 /* def_idx: 0 */ { -L1: g: &mut u64 -L2: f: &mut u64 -B0: - 0: CopyLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: MoveLoc[0](s: &mut S) - 3: MutBorrowField[1](S.g: u64) - 4: StLoc[1](g: &mut u64) - 5: StLoc[2](f: &mut u64) - 6: MoveLoc[2](f: &mut u64) - 7: ReadRef - 8: MoveLoc[1](g: &mut u64) - 9: ReadRef - 10: Ret -} -unpack_ref(s: &S): u64 * u64 /* def_idx: 1 */ { -L1: g: &u64 -L2: f: &u64 -B0: - 0: CopyLoc[0](s: &S) - 1: ImmBorrowField[0](S.f: u64) - 2: MoveLoc[0](s: &S) - 3: ImmBorrowField[1](S.g: u64) - 4: StLoc[1](g: &u64) - 5: StLoc[2](f: &u64) - 6: MoveLoc[2](f: &u64) - 7: ReadRef - 8: MoveLoc[1](g: &u64) - 9: ReadRef - 10: Ret -} -unpack_ref_G(g: &G): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -L1: s: &S -L2: g: &u64 -L3: f: &u64 -L4: x2: &u64 -L5: x1: &u64 -B0: - 0: CopyLoc[0](g: &G) - 1: ImmBorrowField[2](G.x1: u64) - 2: CopyLoc[0](g: &G) - 3: ImmBorrowField[3](G.x2: u64) - 4: MoveLoc[0](g: &G) - 5: ImmBorrowField[4](G.s: S) - 6: StLoc[1](s: &S) - 7: CopyLoc[1](s: &S) - 8: ImmBorrowField[0](S.f: u64) - 9: MoveLoc[1](s: &S) - 10: ImmBorrowField[1](S.g: u64) - 11: StLoc[2](g: &u64) - 12: StLoc[3](f: &u64) - 13: StLoc[4](x2: &u64) - 14: StLoc[5](x1: &u64) - 15: MoveLoc[5](x1: &u64) - 16: ReadRef - 17: MoveLoc[4](x2: &u64) - 18: ReadRef - 19: MoveLoc[3](f: &u64) - 20: ReadRef - 21: MoveLoc[2](g: &u64) - 22: ReadRef - 23: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.opt.exp index 7cf200c5329..1f2f2fb3369 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack_ref.opt.exp @@ -1,71 +1,76 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.pack_unpack_ref { -struct G { - x1: u64, - x2: u64, - s: S -} -struct S { - f: u64, - g: u64 -} +// Bytecode version v9 +module 0x42::pack_unpack_ref +struct G + x1: u64 + x2: u64 + s: S + +struct S + f: u64 + g: u64 + +// Function definition at index 0 +fun unpack_mut_ref(l0: &mut S): (u64, u64) + local l1: &mut u64 + copy_loc l0 + mut_borrow_field S, f + move_loc l0 + mut_borrow_field S, g + st_loc l1 + // @5 + read_ref + move_loc l1 + read_ref + ret + +// Function definition at index 1 +fun unpack_ref(l0: &S): (u64, u64) + local l1: &u64 + copy_loc l0 + borrow_field S, f + move_loc l0 + borrow_field S, g + st_loc l1 + // @5 + read_ref + move_loc l1 + read_ref + ret + +// Function definition at index 2 +fun unpack_ref_G(l0: &G): (u64, u64, u64, u64) + local l1: &u64 + local l2: &S + local l3: &u64 + local l4: &u64 + copy_loc l0 + borrow_field G, x1 + copy_loc l0 + borrow_field G, x2 + st_loc l1 + // @5 + move_loc l0 + borrow_field G, s + st_loc l2 + copy_loc l2 + borrow_field S, f + // @10 + st_loc l3 + move_loc l2 + borrow_field S, g + st_loc l4 + read_ref + // @15 + move_loc l1 + read_ref + move_loc l3 + read_ref + move_loc l4 + // @20 + read_ref + ret + -unpack_mut_ref(s: &mut S): u64 * u64 /* def_idx: 0 */ { -L1: g: &mut u64 -B0: - 0: CopyLoc[0](s: &mut S) - 1: MutBorrowField[0](S.f: u64) - 2: MoveLoc[0](s: &mut S) - 3: MutBorrowField[1](S.g: u64) - 4: StLoc[1](g: &mut u64) - 5: ReadRef - 6: MoveLoc[1](g: &mut u64) - 7: ReadRef - 8: Ret -} -unpack_ref(s: &S): u64 * u64 /* def_idx: 1 */ { -L1: g: &u64 -B0: - 0: CopyLoc[0](s: &S) - 1: ImmBorrowField[0](S.f: u64) - 2: MoveLoc[0](s: &S) - 3: ImmBorrowField[1](S.g: u64) - 4: StLoc[1](g: &u64) - 5: ReadRef - 6: MoveLoc[1](g: &u64) - 7: ReadRef - 8: Ret -} -unpack_ref_G(g: &G): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -L1: x2: &u64 -L2: s: &S -L3: f: &u64 -L4: g: &u64 -B0: - 0: CopyLoc[0](g: &G) - 1: ImmBorrowField[2](G.x1: u64) - 2: CopyLoc[0](g: &G) - 3: ImmBorrowField[3](G.x2: u64) - 4: StLoc[1](x2: &u64) - 5: MoveLoc[0](g: &G) - 6: ImmBorrowField[4](G.s: S) - 7: StLoc[2](s: &S) - 8: CopyLoc[2](s: &S) - 9: ImmBorrowField[0](S.f: u64) - 10: StLoc[3](f: &u64) - 11: MoveLoc[2](s: &S) - 12: ImmBorrowField[1](S.g: u64) - 13: StLoc[4](g: &u64) - 14: ReadRef - 15: MoveLoc[1](x2: &u64) - 16: ReadRef - 17: MoveLoc[3](f: &u64) - 18: ReadRef - 19: MoveLoc[4](g: &u64) - 20: ReadRef - 21: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.exp index 8b42c0932a4..872f8d7856d 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.exp @@ -1,579 +1,523 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct Box has drop { - x: u64 -} -enum CommonFields { - Foo{ - x: u64, - y: u64 - }, - Bar{ - x: u64, - z: u64 - } -} -enum CommonFieldsAtDifferentOffset has drop { - Foo{ - x: u64, - y: u64 - }, - Bar{ - x: u64, - z: u64 - }, - Baz{ - z: u64 - }, - Balt{ - foo: u8, - z: u64 - } -} -enum Inner { - Inner1{ - x: u64 - }, - Inner2{ - x: u64, - y: u64 - } -} -enum Option has drop { - None{ +// Bytecode version v9 +module 0xc0ffee::m +struct Box has drop + x: u64 - }, - Some{ - value: A - } -} -enum Outer { - None{ +enum CommonFields + Foo + x: u64 + y: u64 + Bar + x: u64 + z: u64 + +enum CommonFieldsAtDifferentOffset has drop + Foo + x: u64 + y: u64 + Bar + x: u64 + z: u64 + Baz + z: u64 + Balt + foo: u8 + z: u64 + +enum Inner + Inner1 + x: u64 + Inner2 + x: u64 + y: u64 + +enum Option has drop + None + Some + value: T0 + +enum Outer + None + One + i: Inner + Two + i: Inner + b: Box + +// Function definition at index 0 +#[persistent] public fun inner_value(l0: Inner): u64 + local l1: &Inner + local l2: u64 + local l3: u64 + local l4: u64 + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Inner, Inner1 + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Inner, Inner1 + st_loc l2 + // @10 + branch l1 +l0: move_loc l1 + test_variant Inner, Inner2 + br_false l2 + move_loc l0 + // @15 + unpack_variant Inner, Inner2 + st_loc l3 + st_loc l4 + move_loc l4 + move_loc l3 + // @20 + add + st_loc l2 + branch l1 +l2: ld_u64 14566554180833181697 + abort + // @25 +l1: move_loc l2 + ret + +// Function definition at index 1 +#[persistent] public fun is_inner1(l0: &Inner): bool + move_loc l0 + test_variant Inner, Inner1 + ret + +// Function definition at index 2 +#[persistent] public fun is_some(l0: &Option): bool + local l1: bool + copy_loc l0 + test_variant Option, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + st_loc l1 + branch l1 +l0: move_loc l0 + test_variant Option, Some + // @10 + br_false l2 + ld_true + st_loc l1 + branch l1 +l2: ld_u64 14566554180833181697 + // @15 + abort +l1: move_loc l1 + ret + +// Function definition at index 3 +#[persistent] public fun is_some_dropped(l0: Option): bool + local l1: bool + borrow_loc l0 + test_variant Option, None + br_false l0 + move_loc l0 + unpack_variant Option, None + // @5 + ld_false + st_loc l1 + branch l1 +l0: move_loc l0 + ld_true + // @10 + st_loc l1 + pop + branch l1 + ld_u64 14566554180833181697 + abort + // @15 +l1: move_loc l1 + ret + +// Function definition at index 4 +#[persistent] public fun is_some_specialized(l0: &Option>): bool + local l1: bool + copy_loc l0 + test_variant Option>, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + st_loc l1 + branch l1 +l0: copy_loc l0 + test_variant Option>, Some + // @10 + br_true l2 + branch l3 +l2: copy_loc l0 + borrow_variant_field Option>, Some::value + test_variant Option, None + // @15 + br_true l4 + branch l3 +l4: move_loc l0 + pop + ld_false + // @20 + st_loc l1 + branch l1 +l3: copy_loc l0 + test_variant Option>, Some + br_true l5 + // @25 + move_loc l0 + pop + branch l6 +l5: move_loc l0 + borrow_variant_field Option>, Some::value + // @30 + test_variant Option, Some + br_true l7 + branch l6 +l7: ld_true + st_loc l1 + // @35 + branch l1 +l6: ld_u64 14566554180833181697 + abort +l1: move_loc l1 + ret + +// Function definition at index 5 +#[persistent] public fun outer_value(l0: Outer): u64 + local l1: &Outer + local l2: u64 + local l3: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + st_loc l2 + branch l1 +l0: copy_loc l1 + test_variant Outer, One + br_false l2 + // @15 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, One + call inner_value + // @20 + st_loc l2 + branch l1 +l2: move_loc l1 + test_variant Outer, Two + br_false l3 + // @25 + move_loc l0 + unpack_variant Outer, Two + st_loc l3 + call inner_value + borrow_loc l3 + // @30 + borrow_field Box, x + read_ref + add + st_loc l2 + branch l1 + // @35 +l3: ld_u64 14566554180833181697 + abort +l1: move_loc l2 + ret + +// Function definition at index 6 +#[persistent] public fun outer_value_nested(l0: Outer): u64 + local l1: &Outer + local l2: u64 + local l3: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + st_loc l2 + branch l1 +l0: copy_loc l1 + test_variant Outer, One + br_true l2 + // @15 + branch l3 +l2: copy_loc l1 + borrow_variant_field Outer, One::i + test_variant Inner, Inner1 + br_true l4 + // @20 + branch l3 +l4: move_loc l1 + pop + move_loc l0 + unpack_variant Outer, One + // @25 + unpack_variant Inner, Inner1 + st_loc l2 + branch l1 +l3: copy_loc l1 + test_variant Outer, One + // @30 + br_false l5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, One + // @35 + call inner_value + st_loc l2 + branch l1 +l5: move_loc l1 + test_variant Outer, Two + // @40 + br_false l6 + move_loc l0 + unpack_variant Outer, Two + st_loc l3 + call inner_value + // @45 + borrow_loc l3 + borrow_field Box, x + read_ref + add + st_loc l2 + // @50 + branch l1 +l6: ld_u64 14566554180833181697 + abort +l1: move_loc l2 + ret + +// Function definition at index 7 +#[persistent] public fun outer_value_with_cond(l0: Outer): u64 + local l1: &Outer + local l2: u64 + local l3: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + st_loc l2 + branch l1 +l0: copy_loc l1 + test_variant Outer, One + br_true l2 + // @15 + branch l3 +l2: copy_loc l1 + borrow_variant_field Outer, One::i + call is_inner1 + br_true l4 + // @20 + branch l3 +l4: move_loc l1 + pop + move_loc l0 + unpack_variant Outer, One + // @25 + call inner_value + ld_u64 2 + mod + st_loc l2 + branch l1 + // @30 +l3: copy_loc l1 + test_variant Outer, One + br_false l5 + move_loc l1 + pop + // @35 + move_loc l0 + unpack_variant Outer, One + call inner_value + st_loc l2 + branch l1 + // @40 +l5: move_loc l1 + test_variant Outer, Two + br_false l6 + move_loc l0 + unpack_variant Outer, Two + // @45 + st_loc l3 + call inner_value + borrow_loc l3 + borrow_field Box, x + read_ref + // @50 + add + st_loc l2 + branch l1 +l6: ld_u64 14566554180833181697 + abort + // @55 +l1: move_loc l2 + ret + +// Function definition at index 8 +#[persistent] public fun outer_value_with_cond_ref(l0: &Outer): bool + local l1: bool + copy_loc l0 + test_variant Outer, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + st_loc l1 + branch l1 +l0: copy_loc l0 + test_variant Outer, One + // @10 + br_true l2 + branch l3 +l2: copy_loc l0 + borrow_variant_field Outer, One::i + call is_inner1 + // @15 + br_true l4 + branch l3 +l4: move_loc l0 + pop + ld_true + // @20 + st_loc l1 + branch l1 +l3: copy_loc l0 + test_variant Outer, One + br_false l5 + // @25 + move_loc l0 + borrow_variant_field Outer, One::i + call is_inner1 + st_loc l1 + branch l1 + // @30 +l5: copy_loc l0 + test_variant Outer, Two + br_false l6 + move_loc l0 + borrow_variant_field Outer, Two::i + // @35 + call is_inner1 + st_loc l1 + branch l1 +l6: move_loc l0 + pop + // @40 + ld_u64 14566554180833181697 + abort +l1: move_loc l1 + ret + +// Function definition at index 9 +fun select_common_fields(l0: CommonFields): u64 + local l1: &CommonFields + local l2: bool + local l3: u64 + local l4: u64 + borrow_loc l0 + borrow_variant_field CommonFields, Foo::x, Bar::x + read_ref + borrow_loc l0 + st_loc l1 + // @5 + copy_loc l1 + test_variant CommonFields, Foo + st_loc l2 + st_loc l3 + move_loc l2 + // @10 + br_false l0 + move_loc l1 + pop + move_loc l0 + unpack_variant CommonFields, Foo + // @15 + st_loc l4 + pop + branch l1 +l0: move_loc l1 + test_variant CommonFields, Bar + // @20 + br_false l2 + move_loc l0 + unpack_variant CommonFields, Bar + st_loc l4 + pop + // @25 + branch l1 +l2: ld_u64 14566554180833181697 + abort +l1: move_loc l3 + move_loc l4 + // @30 + add + ret + +// Function definition at index 10 +fun select_common_fields_different_offset(l0: CommonFieldsAtDifferentOffset): u64 + local l1: &CommonFieldsAtDifferentOffset + local l2: &u64 + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant CommonFieldsAtDifferentOffset, Bar + br_false l0 + // @5 + branch l1 +l0: copy_loc l1 + test_variant CommonFieldsAtDifferentOffset, Balt + br_false l2 + branch l1 + // @10 +l2: branch l3 +l1: move_loc l1 + borrow_variant_field CommonFieldsAtDifferentOffset, Bar::z, Balt::z + st_loc l2 + branch l4 + // @15 +l3: move_loc l1 + borrow_variant_field CommonFieldsAtDifferentOffset, Baz::z + st_loc l2 +l4: move_loc l2 + read_ref + // @20 + ret - }, - One{ - i: Inner - }, - Two{ - i: Inner, - b: Box - } -} -public inner_value(self: Inner): u64 /* def_idx: 0 */ { -L1: $t2: &Inner -L2: return: u64 -L3: y: u64 -L4: x: u64 -B0: - 0: ImmBorrowLoc[0](self: Inner) - 1: StLoc[1]($t2: &Inner) - 2: CopyLoc[1]($t2: &Inner) - 3: TestVariant[0](Inner/Inner1) - 4: BrFalse(11) -B1: - 5: MoveLoc[1]($t2: &Inner) - 6: Pop - 7: MoveLoc[0](self: Inner) - 8: UnpackVariant[0](Inner/Inner1) - 9: StLoc[2](return: u64) - 10: Branch(25) -B2: - 11: MoveLoc[1]($t2: &Inner) - 12: TestVariant[1](Inner/Inner2) - 13: BrFalse(23) -B3: - 14: MoveLoc[0](self: Inner) - 15: UnpackVariant[1](Inner/Inner2) - 16: StLoc[3](y: u64) - 17: StLoc[4](x: u64) - 18: MoveLoc[4](x: u64) - 19: MoveLoc[3](y: u64) - 20: Add - 21: StLoc[2](return: u64) - 22: Branch(25) -B4: - 23: LdU64(14566554180833181697) - 24: Abort -B5: - 25: MoveLoc[2](return: u64) - 26: Ret -} -public is_inner1(self: &Inner): bool /* def_idx: 1 */ { -L1: return: bool -L2: $t3: &Inner -B0: - 0: CopyLoc[0](self: &Inner) - 1: TestVariant[0](Inner/Inner1) - 2: BrFalse(8) -B1: - 3: MoveLoc[0](self: &Inner) - 4: Pop - 5: LdTrue - 6: StLoc[1](return: bool) - 7: Branch(17) -B2: - 8: MoveLoc[0](self: &Inner) - 9: StLoc[2]($t3: &Inner) - 10: MoveLoc[2]($t3: &Inner) - 11: Pop - 12: LdFalse - 13: StLoc[1](return: bool) - 14: Branch(17) -B3: - 15: LdU64(14566554180833181697) - 16: Abort -B4: - 17: MoveLoc[1](return: bool) - 18: Ret -} -public is_some(x: &Option): bool /* def_idx: 2 */ { -L1: return: bool -B0: - 0: CopyLoc[0](x: &Option) - 1: TestVariantGeneric[0](Option/None) - 2: BrFalse(8) -B1: - 3: MoveLoc[0](x: &Option) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) - 7: Branch(16) -B2: - 8: MoveLoc[0](x: &Option) - 9: TestVariantGeneric[1](Option/Some) - 10: BrFalse(14) -B3: - 11: LdTrue - 12: StLoc[1](return: bool) - 13: Branch(16) -B4: - 14: LdU64(14566554180833181697) - 15: Abort -B5: - 16: MoveLoc[1](return: bool) - 17: Ret -} -public is_some_dropped(x: Option): bool /* def_idx: 3 */ { -L1: return: bool -B0: - 0: ImmBorrowLoc[0](x: Option) - 1: TestVariantGeneric[0](Option/None) - 2: BrFalse(8) -B1: - 3: MoveLoc[0](x: Option) - 4: UnpackVariantGeneric[0](Option/None) - 5: LdFalse - 6: StLoc[1](return: bool) - 7: Branch(15) -B2: - 8: MoveLoc[0](x: Option) - 9: LdTrue - 10: StLoc[1](return: bool) - 11: Pop - 12: Branch(15) -B3: - 13: LdU64(14566554180833181697) - 14: Abort -B4: - 15: MoveLoc[1](return: bool) - 16: Ret -} -public is_some_specialized(x: &Option>): bool /* def_idx: 4 */ { -L1: return: bool -B0: - 0: CopyLoc[0](x: &Option>) - 1: TestVariantGeneric[2](Option/None>) - 2: BrFalse(8) -B1: - 3: MoveLoc[0](x: &Option>) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) - 7: Branch(38) -B2: - 8: CopyLoc[0](x: &Option>) - 9: TestVariantGeneric[3](Option/Some>) - 10: BrTrue(12) -B3: - 11: Branch(22) -B4: - 12: CopyLoc[0](x: &Option>) - 13: ImmBorrowVariantFieldGeneric[0](Some.value: A) - 14: TestVariantGeneric[4](Option/None) - 15: BrTrue(17) -B5: - 16: Branch(22) -B6: - 17: MoveLoc[0](x: &Option>) - 18: Pop - 19: LdFalse - 20: StLoc[1](return: bool) - 21: Branch(38) -B7: - 22: CopyLoc[0](x: &Option>) - 23: TestVariantGeneric[3](Option/Some>) - 24: BrTrue(28) -B8: - 25: MoveLoc[0](x: &Option>) - 26: Pop - 27: Branch(36) -B9: - 28: MoveLoc[0](x: &Option>) - 29: ImmBorrowVariantFieldGeneric[0](Some.value: A) - 30: TestVariantGeneric[5](Option/Some) - 31: BrTrue(33) -B10: - 32: Branch(36) -B11: - 33: LdTrue - 34: StLoc[1](return: bool) - 35: Branch(38) -B12: - 36: LdU64(14566554180833181697) - 37: Abort -B13: - 38: MoveLoc[1](return: bool) - 39: Ret -} -public outer_value(o: Outer): u64 /* def_idx: 5 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(12) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) - 11: Branch(37) -B2: - 12: CopyLoc[1]($t2: &Outer) - 13: TestVariant[5](Outer/One) - 14: BrFalse(22) -B3: - 15: MoveLoc[1]($t2: &Outer) - 16: Pop - 17: MoveLoc[0](o: Outer) - 18: UnpackVariant[5](Outer/One) - 19: Call inner_value(Inner): u64 - 20: StLoc[2](return: u64) - 21: Branch(37) -B4: - 22: MoveLoc[1]($t2: &Outer) - 23: TestVariant[6](Outer/Two) - 24: BrFalse(35) -B5: - 25: MoveLoc[0](o: Outer) - 26: UnpackVariant[6](Outer/Two) - 27: StLoc[3](b: Box) - 28: Call inner_value(Inner): u64 - 29: ImmBorrowLoc[3](b: Box) - 30: ImmBorrowField[0](Box.x: u64) - 31: ReadRef - 32: Add - 33: StLoc[2](return: u64) - 34: Branch(37) -B6: - 35: LdU64(14566554180833181697) - 36: Abort -B7: - 37: MoveLoc[2](return: u64) - 38: Ret -} -public outer_value_nested(o: Outer): u64 /* def_idx: 6 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(12) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) - 11: Branch(53) -B2: - 12: CopyLoc[1]($t2: &Outer) - 13: TestVariant[5](Outer/One) - 14: BrTrue(16) -B3: - 15: Branch(28) -B4: - 16: CopyLoc[1]($t2: &Outer) - 17: ImmBorrowVariantField[1](One.i: Inner) - 18: TestVariant[0](Inner/Inner1) - 19: BrTrue(21) -B5: - 20: Branch(28) -B6: - 21: MoveLoc[1]($t2: &Outer) - 22: Pop - 23: MoveLoc[0](o: Outer) - 24: UnpackVariant[5](Outer/One) - 25: UnpackVariant[0](Inner/Inner1) - 26: StLoc[2](return: u64) - 27: Branch(53) -B7: - 28: CopyLoc[1]($t2: &Outer) - 29: TestVariant[5](Outer/One) - 30: BrFalse(38) -B8: - 31: MoveLoc[1]($t2: &Outer) - 32: Pop - 33: MoveLoc[0](o: Outer) - 34: UnpackVariant[5](Outer/One) - 35: Call inner_value(Inner): u64 - 36: StLoc[2](return: u64) - 37: Branch(53) -B9: - 38: MoveLoc[1]($t2: &Outer) - 39: TestVariant[6](Outer/Two) - 40: BrFalse(51) -B10: - 41: MoveLoc[0](o: Outer) - 42: UnpackVariant[6](Outer/Two) - 43: StLoc[3](b: Box) - 44: Call inner_value(Inner): u64 - 45: ImmBorrowLoc[3](b: Box) - 46: ImmBorrowField[0](Box.x: u64) - 47: ReadRef - 48: Add - 49: StLoc[2](return: u64) - 50: Branch(53) -B11: - 51: LdU64(14566554180833181697) - 52: Abort -B12: - 53: MoveLoc[2](return: u64) - 54: Ret -} -public outer_value_with_cond(o: Outer): u64 /* def_idx: 7 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(12) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) - 11: Branch(55) -B2: - 12: CopyLoc[1]($t2: &Outer) - 13: TestVariant[5](Outer/One) - 14: BrTrue(16) -B3: - 15: Branch(30) -B4: - 16: CopyLoc[1]($t2: &Outer) - 17: ImmBorrowVariantField[1](One.i: Inner) - 18: Call is_inner1(&Inner): bool - 19: BrTrue(21) -B5: - 20: Branch(30) -B6: - 21: MoveLoc[1]($t2: &Outer) - 22: Pop - 23: MoveLoc[0](o: Outer) - 24: UnpackVariant[5](Outer/One) - 25: Call inner_value(Inner): u64 - 26: LdU64(2) - 27: Mod - 28: StLoc[2](return: u64) - 29: Branch(55) -B7: - 30: CopyLoc[1]($t2: &Outer) - 31: TestVariant[5](Outer/One) - 32: BrFalse(40) -B8: - 33: MoveLoc[1]($t2: &Outer) - 34: Pop - 35: MoveLoc[0](o: Outer) - 36: UnpackVariant[5](Outer/One) - 37: Call inner_value(Inner): u64 - 38: StLoc[2](return: u64) - 39: Branch(55) -B9: - 40: MoveLoc[1]($t2: &Outer) - 41: TestVariant[6](Outer/Two) - 42: BrFalse(53) -B10: - 43: MoveLoc[0](o: Outer) - 44: UnpackVariant[6](Outer/Two) - 45: StLoc[3](b: Box) - 46: Call inner_value(Inner): u64 - 47: ImmBorrowLoc[3](b: Box) - 48: ImmBorrowField[0](Box.x: u64) - 49: ReadRef - 50: Add - 51: StLoc[2](return: u64) - 52: Branch(55) -B11: - 53: LdU64(14566554180833181697) - 54: Abort -B12: - 55: MoveLoc[2](return: u64) - 56: Ret -} -public outer_value_with_cond_ref(o: &Outer): bool /* def_idx: 8 */ { -L1: return: bool -B0: - 0: CopyLoc[0](o: &Outer) - 1: TestVariant[4](Outer/None) - 2: BrFalse(8) -B1: - 3: MoveLoc[0](o: &Outer) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) - 7: Branch(42) -B2: - 8: CopyLoc[0](o: &Outer) - 9: TestVariant[5](Outer/One) - 10: BrTrue(12) -B3: - 11: Branch(22) -B4: - 12: CopyLoc[0](o: &Outer) - 13: ImmBorrowVariantField[1](One.i: Inner) - 14: Call is_inner1(&Inner): bool - 15: BrTrue(17) -B5: - 16: Branch(22) -B6: - 17: MoveLoc[0](o: &Outer) - 18: Pop - 19: LdTrue - 20: StLoc[1](return: bool) - 21: Branch(42) -B7: - 22: CopyLoc[0](o: &Outer) - 23: TestVariant[5](Outer/One) - 24: BrFalse(30) -B8: - 25: MoveLoc[0](o: &Outer) - 26: ImmBorrowVariantField[1](One.i: Inner) - 27: Call is_inner1(&Inner): bool - 28: StLoc[1](return: bool) - 29: Branch(42) -B9: - 30: CopyLoc[0](o: &Outer) - 31: TestVariant[6](Outer/Two) - 32: BrFalse(38) -B10: - 33: MoveLoc[0](o: &Outer) - 34: ImmBorrowVariantField[2](Two.i: Inner) - 35: Call is_inner1(&Inner): bool - 36: StLoc[1](return: bool) - 37: Branch(42) -B11: - 38: MoveLoc[0](o: &Outer) - 39: Pop - 40: LdU64(14566554180833181697) - 41: Abort -B12: - 42: MoveLoc[1](return: bool) - 43: Ret -} -select_common_fields(s: CommonFields): u64 /* def_idx: 9 */ { -L1: $t6: &CommonFields -L2: $t7: bool -L3: $t2: u64 -L4: $t5: u64 -B0: - 0: ImmBorrowLoc[0](s: CommonFields) - 1: ImmBorrowVariantField[3](Foo.x|Bar.x: u64) - 2: ReadRef - 3: ImmBorrowLoc[0](s: CommonFields) - 4: StLoc[1]($t6: &CommonFields) - 5: CopyLoc[1]($t6: &CommonFields) - 6: TestVariant[7](CommonFields/Foo) - 7: StLoc[2]($t7: bool) - 8: StLoc[3]($t2: u64) - 9: MoveLoc[2]($t7: bool) - 10: BrFalse(18) -B1: - 11: MoveLoc[1]($t6: &CommonFields) - 12: Pop - 13: MoveLoc[0](s: CommonFields) - 14: UnpackVariant[7](CommonFields/Foo) - 15: StLoc[4]($t5: u64) - 16: Pop - 17: Branch(28) -B2: - 18: MoveLoc[1]($t6: &CommonFields) - 19: TestVariant[8](CommonFields/Bar) - 20: BrFalse(26) -B3: - 21: MoveLoc[0](s: CommonFields) - 22: UnpackVariant[8](CommonFields/Bar) - 23: StLoc[4]($t5: u64) - 24: Pop - 25: Branch(28) -B4: - 26: LdU64(14566554180833181697) - 27: Abort -B5: - 28: MoveLoc[3]($t2: u64) - 29: MoveLoc[4]($t5: u64) - 30: Add - 31: Ret -} -select_common_fields_different_offset(s: CommonFieldsAtDifferentOffset): u64 /* def_idx: 10 */ { -L1: $t2: &CommonFieldsAtDifferentOffset -L2: $t3: &u64 -B0: - 0: ImmBorrowLoc[0](s: CommonFieldsAtDifferentOffset) - 1: StLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 2: CopyLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 3: TestVariant[9](CommonFieldsAtDifferentOffset/Bar) - 4: BrFalse(6) -B1: - 5: Branch(11) -B2: - 6: CopyLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 7: TestVariant[10](CommonFieldsAtDifferentOffset/Balt) - 8: BrFalse(10) -B3: - 9: Branch(11) -B4: - 10: Branch(15) -B5: - 11: MoveLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 12: ImmBorrowVariantField[4](Bar.z|Balt.z: u64) - 13: StLoc[2]($t3: &u64) - 14: Branch(18) -B6: - 15: MoveLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 16: ImmBorrowVariantField[5](Baz.z: u64) - 17: StLoc[2]($t3: &u64) -B7: - 18: MoveLoc[2]($t3: &u64) - 19: ReadRef - 20: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.opt.exp index 5353153d597..1037099400f 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/struct_variants.opt.exp @@ -1,548 +1,449 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct Box has drop { - x: u64 -} -enum CommonFields { - Foo{ - x: u64, - y: u64 - }, - Bar{ - x: u64, - z: u64 - } -} -enum CommonFieldsAtDifferentOffset has drop { - Foo{ - x: u64, - y: u64 - }, - Bar{ - x: u64, - z: u64 - }, - Baz{ - z: u64 - }, - Balt{ - foo: u8, - z: u64 - } -} -enum Inner { - Inner1{ - x: u64 - }, - Inner2{ - x: u64, - y: u64 - } -} -enum Option has drop { - None{ +// Bytecode version v9 +module 0xc0ffee::m +struct Box has drop + x: u64 - }, - Some{ - value: A - } -} -enum Outer { - None{ +enum CommonFields + Foo + x: u64 + y: u64 + Bar + x: u64 + z: u64 + +enum CommonFieldsAtDifferentOffset has drop + Foo + x: u64 + y: u64 + Bar + x: u64 + z: u64 + Baz + z: u64 + Balt + foo: u8 + z: u64 + +enum Inner + Inner1 + x: u64 + Inner2 + x: u64 + y: u64 + +enum Option has drop + None + Some + value: T0 + +enum Outer + None + One + i: Inner + Two + i: Inner + b: Box + +// Function definition at index 0 +#[persistent] public fun inner_value(l0: Inner): u64 + local l1: &Inner + local l2: u64 + local l3: u64 + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Inner, Inner1 + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Inner, Inner1 + ret + // @10 +l0: move_loc l1 + test_variant Inner, Inner2 + br_false l1 + move_loc l0 + unpack_variant Inner, Inner2 + // @15 + add + ret +l1: ld_u64 14566554180833181697 + abort + +// Function definition at index 1 +#[persistent] public fun is_inner1(l0: &Inner): bool + move_loc l0 + test_variant Inner, Inner1 + ret + +// Function definition at index 2 +#[persistent] public fun is_some(l0: &Option): bool + copy_loc l0 + test_variant Option, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + ret +l0: move_loc l0 + test_variant Option, Some + br_false l1 + // @10 + ld_true + ret +l1: ld_u64 14566554180833181697 + abort + +// Function definition at index 3 +#[persistent] public fun is_some_dropped(l0: Option): bool + borrow_loc l0 + test_variant Option, None + br_false l0 + move_loc l0 + unpack_variant Option, None + // @5 + ld_false + ret +l0: ld_true + ret + +// Function definition at index 4 +#[persistent] public fun is_some_specialized(l0: &Option>): bool + copy_loc l0 + test_variant Option>, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + ret +l0: copy_loc l0 + test_variant Option>, Some + br_true l1 + // @10 + branch l2 +l2: copy_loc l0 + test_variant Option>, Some + br_true l3 + move_loc l0 + // @15 + pop +l5: ld_u64 14566554180833181697 + abort +l3: move_loc l0 + borrow_variant_field Option>, Some::value + // @20 + test_variant Option, Some + br_true l4 + branch l5 +l4: ld_true + ret + // @25 +l1: copy_loc l0 + borrow_variant_field Option>, Some::value + test_variant Option, None + br_true l6 + branch l2 + // @30 +l6: move_loc l0 + pop + ld_false + ret + +// Function definition at index 5 +#[persistent] public fun outer_value(l0: Outer): u64 + local l1: &Outer + local l2: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + ret +l0: copy_loc l1 + test_variant Outer, One + br_false l1 + move_loc l1 + // @15 + pop + move_loc l0 + unpack_variant Outer, One + call inner_value + ret + // @20 +l1: move_loc l1 + test_variant Outer, Two + br_false l2 + move_loc l0 + unpack_variant Outer, Two + // @25 + st_loc l2 + call inner_value + borrow_loc l2 + borrow_field Box, x + read_ref + // @30 + add + ret +l2: ld_u64 14566554180833181697 + abort + +// Function definition at index 6 +#[persistent] public fun outer_value_nested(l0: Outer): u64 + local l1: &Outer + local l2: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + ret +l0: copy_loc l1 + test_variant Outer, One + br_true l1 + branch l2 + // @15 +l2: copy_loc l1 + test_variant Outer, One + br_false l3 + move_loc l1 + pop + // @20 + move_loc l0 + unpack_variant Outer, One + call inner_value + ret +l3: move_loc l1 + // @25 + test_variant Outer, Two + br_false l4 + move_loc l0 + unpack_variant Outer, Two + st_loc l2 + // @30 + call inner_value + borrow_loc l2 + borrow_field Box, x + read_ref + add + // @35 + ret +l4: ld_u64 14566554180833181697 + abort +l1: copy_loc l1 + borrow_variant_field Outer, One::i + // @40 + test_variant Inner, Inner1 + br_true l5 + branch l2 +l5: move_loc l1 + pop + // @45 + move_loc l0 + unpack_variant Outer, One + unpack_variant Inner, Inner1 + ret + +// Function definition at index 7 +#[persistent] public fun outer_value_with_cond(l0: Outer): u64 + local l1: &Outer + local l2: Box + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant Outer, None + br_false l0 + // @5 + move_loc l1 + pop + move_loc l0 + unpack_variant Outer, None + ld_u64 0 + // @10 + ret +l0: copy_loc l1 + test_variant Outer, One + br_true l1 + branch l2 + // @15 +l2: copy_loc l1 + test_variant Outer, One + br_false l3 + move_loc l1 + pop + // @20 + move_loc l0 + unpack_variant Outer, One + call inner_value + ret +l3: move_loc l1 + // @25 + test_variant Outer, Two + br_false l4 + move_loc l0 + unpack_variant Outer, Two + st_loc l2 + // @30 + call inner_value + borrow_loc l2 + borrow_field Box, x + read_ref + add + // @35 + ret +l4: ld_u64 14566554180833181697 + abort +l1: copy_loc l1 + borrow_variant_field Outer, One::i + // @40 + call is_inner1 + br_true l5 + branch l2 +l5: move_loc l1 + pop + // @45 + move_loc l0 + unpack_variant Outer, One + call inner_value + ld_u64 2 + mod + // @50 + ret + +// Function definition at index 8 +#[persistent] public fun outer_value_with_cond_ref(l0: &Outer): bool + copy_loc l0 + test_variant Outer, None + br_false l0 + move_loc l0 + pop + // @5 + ld_false + ret +l0: copy_loc l0 + test_variant Outer, One + br_true l1 + // @10 + branch l2 +l2: copy_loc l0 + test_variant Outer, One + br_false l3 + move_loc l0 + // @15 + borrow_variant_field Outer, One::i + call is_inner1 + ret +l3: copy_loc l0 + test_variant Outer, Two + // @20 + br_false l4 + move_loc l0 + borrow_variant_field Outer, Two::i + call is_inner1 + ret + // @25 +l4: move_loc l0 + pop + ld_u64 14566554180833181697 + abort +l1: copy_loc l0 + // @30 + borrow_variant_field Outer, One::i + call is_inner1 + br_true l5 + branch l2 +l5: move_loc l0 + // @35 + pop + ld_true + ret + +// Function definition at index 9 +fun select_common_fields(l0: CommonFields): u64 + local l1: &CommonFields + local l2: u64 + local l3: u64 + borrow_loc l0 + borrow_variant_field CommonFields, Foo::x, Bar::x + read_ref + st_loc l2 + borrow_loc l0 + // @5 + st_loc l1 + copy_loc l1 + test_variant CommonFields, Foo + br_false l0 + move_loc l1 + // @10 + pop + move_loc l0 + unpack_variant CommonFields, Foo + st_loc l3 + pop + // @15 +l2: move_loc l2 + move_loc l3 + add + ret +l0: move_loc l1 + // @20 + test_variant CommonFields, Bar + br_false l1 + move_loc l0 + unpack_variant CommonFields, Bar + st_loc l3 + // @25 + pop + branch l2 +l1: ld_u64 14566554180833181697 + abort + +// Function definition at index 10 +fun select_common_fields_different_offset(l0: CommonFieldsAtDifferentOffset): u64 + local l1: &CommonFieldsAtDifferentOffset + local l2: &u64 + borrow_loc l0 + st_loc l1 + copy_loc l1 + test_variant CommonFieldsAtDifferentOffset, Bar + br_false l0 + // @5 + branch l1 +l1: move_loc l1 + borrow_variant_field CommonFieldsAtDifferentOffset, Bar::z, Balt::z + st_loc l2 +l3: move_loc l2 + // @10 + read_ref + ret +l0: copy_loc l1 + test_variant CommonFieldsAtDifferentOffset, Balt + br_false l2 + // @15 + branch l1 +l2: move_loc l1 + borrow_variant_field CommonFieldsAtDifferentOffset, Baz::z + st_loc l2 + branch l3 - }, - One{ - i: Inner - }, - Two{ - i: Inner, - b: Box - } -} -public inner_value(self: Inner): u64 /* def_idx: 0 */ { -L1: $t2: &Inner -L2: x: u64 -L3: y: u64 -L4: x: u64 -B0: - 0: ImmBorrowLoc[0](self: Inner) - 1: StLoc[1]($t2: &Inner) - 2: CopyLoc[1]($t2: &Inner) - 3: TestVariant[0](Inner/Inner1) - 4: BrFalse(12) -B1: - 5: MoveLoc[1]($t2: &Inner) - 6: Pop - 7: MoveLoc[0](self: Inner) - 8: UnpackVariant[0](Inner/Inner1) - 9: StLoc[2](x: u64) -B2: - 10: MoveLoc[2](x: u64) - 11: Ret -B3: - 12: MoveLoc[1]($t2: &Inner) - 13: TestVariant[1](Inner/Inner2) - 14: BrFalse(20) -B4: - 15: MoveLoc[0](self: Inner) - 16: UnpackVariant[1](Inner/Inner2) - 17: Add - 18: StLoc[2](x: u64) - 19: Branch(10) -B5: - 20: LdU64(14566554180833181697) - 21: Abort -} -public is_inner1(self: &Inner): bool /* def_idx: 1 */ { -L1: $t2: bool -B0: - 0: CopyLoc[0](self: &Inner) - 1: TestVariant[0](Inner/Inner1) - 2: BrFalse(9) -B1: - 3: MoveLoc[0](self: &Inner) - 4: Pop - 5: LdTrue - 6: StLoc[1]($t2: bool) -B2: - 7: MoveLoc[1]($t2: bool) - 8: Ret -B3: - 9: MoveLoc[0](self: &Inner) - 10: Pop - 11: LdFalse - 12: StLoc[1]($t2: bool) - 13: Branch(7) -} -public is_some(x: &Option): bool /* def_idx: 2 */ { -L1: return: bool -B0: - 0: CopyLoc[0](x: &Option) - 1: TestVariantGeneric[0](Option/None) - 2: BrFalse(9) -B1: - 3: MoveLoc[0](x: &Option) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) -B2: - 7: MoveLoc[1](return: bool) - 8: Ret -B3: - 9: MoveLoc[0](x: &Option) - 10: TestVariantGeneric[1](Option/Some) - 11: BrFalse(15) -B4: - 12: LdTrue - 13: StLoc[1](return: bool) - 14: Branch(7) -B5: - 15: LdU64(14566554180833181697) - 16: Abort -} -public is_some_dropped(x: Option): bool /* def_idx: 3 */ { -L1: $t3: bool -B0: - 0: ImmBorrowLoc[0](x: Option) - 1: TestVariantGeneric[0](Option/None) - 2: BrFalse(9) -B1: - 3: MoveLoc[0](x: Option) - 4: UnpackVariantGeneric[0](Option/None) - 5: LdFalse - 6: StLoc[1]($t3: bool) -B2: - 7: MoveLoc[1]($t3: bool) - 8: Ret -B3: - 9: LdTrue - 10: StLoc[1]($t3: bool) - 11: Branch(7) -} -public is_some_specialized(x: &Option>): bool /* def_idx: 4 */ { -L1: return: bool -B0: - 0: CopyLoc[0](x: &Option>) - 1: TestVariantGeneric[2](Option/None>) - 2: BrFalse(9) -B1: - 3: MoveLoc[0](x: &Option>) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) -B2: - 7: MoveLoc[1](return: bool) - 8: Ret -B3: - 9: CopyLoc[0](x: &Option>) - 10: TestVariantGeneric[3](Option/Some>) - 11: BrTrue(28) -B4: - 12: Branch(13) -B5: - 13: CopyLoc[0](x: &Option>) - 14: TestVariantGeneric[3](Option/Some>) - 15: BrTrue(20) -B6: - 16: MoveLoc[0](x: &Option>) - 17: Pop -B7: - 18: LdU64(14566554180833181697) - 19: Abort -B8: - 20: MoveLoc[0](x: &Option>) - 21: ImmBorrowVariantFieldGeneric[0](Some.value: A) - 22: TestVariantGeneric[4](Option/Some) - 23: BrTrue(25) -B9: - 24: Branch(18) -B10: - 25: LdTrue - 26: StLoc[1](return: bool) - 27: Branch(7) -B11: - 28: CopyLoc[0](x: &Option>) - 29: ImmBorrowVariantFieldGeneric[0](Some.value: A) - 30: TestVariantGeneric[5](Option/None) - 31: BrTrue(33) -B12: - 32: Branch(13) -B13: - 33: MoveLoc[0](x: &Option>) - 34: Pop - 35: LdFalse - 36: StLoc[1](return: bool) - 37: Branch(7) -} -public outer_value(o: Outer): u64 /* def_idx: 5 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(13) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) -B2: - 11: MoveLoc[2](return: u64) - 12: Ret -B3: - 13: CopyLoc[1]($t2: &Outer) - 14: TestVariant[5](Outer/One) - 15: BrFalse(23) -B4: - 16: MoveLoc[1]($t2: &Outer) - 17: Pop - 18: MoveLoc[0](o: Outer) - 19: UnpackVariant[5](Outer/One) - 20: Call inner_value(Inner): u64 - 21: StLoc[2](return: u64) - 22: Branch(11) -B5: - 23: MoveLoc[1]($t2: &Outer) - 24: TestVariant[6](Outer/Two) - 25: BrFalse(36) -B6: - 26: MoveLoc[0](o: Outer) - 27: UnpackVariant[6](Outer/Two) - 28: StLoc[3](b: Box) - 29: Call inner_value(Inner): u64 - 30: ImmBorrowLoc[3](b: Box) - 31: ImmBorrowField[0](Box.x: u64) - 32: ReadRef - 33: Add - 34: StLoc[2](return: u64) - 35: Branch(11) -B7: - 36: LdU64(14566554180833181697) - 37: Abort -} -public outer_value_nested(o: Outer): u64 /* def_idx: 6 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(13) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) -B2: - 11: MoveLoc[2](return: u64) - 12: Ret -B3: - 13: CopyLoc[1]($t2: &Outer) - 14: TestVariant[5](Outer/One) - 15: BrTrue(42) -B4: - 16: Branch(17) -B5: - 17: CopyLoc[1]($t2: &Outer) - 18: TestVariant[5](Outer/One) - 19: BrFalse(27) -B6: - 20: MoveLoc[1]($t2: &Outer) - 21: Pop - 22: MoveLoc[0](o: Outer) - 23: UnpackVariant[5](Outer/One) - 24: Call inner_value(Inner): u64 - 25: StLoc[2](return: u64) - 26: Branch(11) -B7: - 27: MoveLoc[1]($t2: &Outer) - 28: TestVariant[6](Outer/Two) - 29: BrFalse(40) -B8: - 30: MoveLoc[0](o: Outer) - 31: UnpackVariant[6](Outer/Two) - 32: StLoc[3](b: Box) - 33: Call inner_value(Inner): u64 - 34: ImmBorrowLoc[3](b: Box) - 35: ImmBorrowField[0](Box.x: u64) - 36: ReadRef - 37: Add - 38: StLoc[2](return: u64) - 39: Branch(11) -B9: - 40: LdU64(14566554180833181697) - 41: Abort -B10: - 42: CopyLoc[1]($t2: &Outer) - 43: ImmBorrowVariantField[1](One.i: Inner) - 44: TestVariant[0](Inner/Inner1) - 45: BrTrue(47) -B11: - 46: Branch(17) -B12: - 47: MoveLoc[1]($t2: &Outer) - 48: Pop - 49: MoveLoc[0](o: Outer) - 50: UnpackVariant[5](Outer/One) - 51: UnpackVariant[0](Inner/Inner1) - 52: StLoc[2](return: u64) - 53: Branch(11) -} -public outer_value_with_cond(o: Outer): u64 /* def_idx: 7 */ { -L1: $t2: &Outer -L2: return: u64 -L3: b: Box -B0: - 0: ImmBorrowLoc[0](o: Outer) - 1: StLoc[1]($t2: &Outer) - 2: CopyLoc[1]($t2: &Outer) - 3: TestVariant[4](Outer/None) - 4: BrFalse(13) -B1: - 5: MoveLoc[1]($t2: &Outer) - 6: Pop - 7: MoveLoc[0](o: Outer) - 8: UnpackVariant[4](Outer/None) - 9: LdU64(0) - 10: StLoc[2](return: u64) -B2: - 11: MoveLoc[2](return: u64) - 12: Ret -B3: - 13: CopyLoc[1]($t2: &Outer) - 14: TestVariant[5](Outer/One) - 15: BrTrue(42) -B4: - 16: Branch(17) -B5: - 17: CopyLoc[1]($t2: &Outer) - 18: TestVariant[5](Outer/One) - 19: BrFalse(27) -B6: - 20: MoveLoc[1]($t2: &Outer) - 21: Pop - 22: MoveLoc[0](o: Outer) - 23: UnpackVariant[5](Outer/One) - 24: Call inner_value(Inner): u64 - 25: StLoc[2](return: u64) - 26: Branch(11) -B7: - 27: MoveLoc[1]($t2: &Outer) - 28: TestVariant[6](Outer/Two) - 29: BrFalse(40) -B8: - 30: MoveLoc[0](o: Outer) - 31: UnpackVariant[6](Outer/Two) - 32: StLoc[3](b: Box) - 33: Call inner_value(Inner): u64 - 34: ImmBorrowLoc[3](b: Box) - 35: ImmBorrowField[0](Box.x: u64) - 36: ReadRef - 37: Add - 38: StLoc[2](return: u64) - 39: Branch(11) -B9: - 40: LdU64(14566554180833181697) - 41: Abort -B10: - 42: CopyLoc[1]($t2: &Outer) - 43: ImmBorrowVariantField[1](One.i: Inner) - 44: Call is_inner1(&Inner): bool - 45: BrTrue(47) -B11: - 46: Branch(17) -B12: - 47: MoveLoc[1]($t2: &Outer) - 48: Pop - 49: MoveLoc[0](o: Outer) - 50: UnpackVariant[5](Outer/One) - 51: Call inner_value(Inner): u64 - 52: LdU64(2) - 53: Mod - 54: StLoc[2](return: u64) - 55: Branch(11) -} -public outer_value_with_cond_ref(o: &Outer): bool /* def_idx: 8 */ { -L1: return: bool -B0: - 0: CopyLoc[0](o: &Outer) - 1: TestVariant[4](Outer/None) - 2: BrFalse(9) -B1: - 3: MoveLoc[0](o: &Outer) - 4: Pop - 5: LdFalse - 6: StLoc[1](return: bool) -B2: - 7: MoveLoc[1](return: bool) - 8: Ret -B3: - 9: CopyLoc[0](o: &Outer) - 10: TestVariant[5](Outer/One) - 11: BrTrue(33) -B4: - 12: Branch(13) -B5: - 13: CopyLoc[0](o: &Outer) - 14: TestVariant[5](Outer/One) - 15: BrFalse(21) -B6: - 16: MoveLoc[0](o: &Outer) - 17: ImmBorrowVariantField[1](One.i: Inner) - 18: Call is_inner1(&Inner): bool - 19: StLoc[1](return: bool) - 20: Branch(7) -B7: - 21: CopyLoc[0](o: &Outer) - 22: TestVariant[6](Outer/Two) - 23: BrFalse(29) -B8: - 24: MoveLoc[0](o: &Outer) - 25: ImmBorrowVariantField[2](Two.i: Inner) - 26: Call is_inner1(&Inner): bool - 27: StLoc[1](return: bool) - 28: Branch(7) -B9: - 29: MoveLoc[0](o: &Outer) - 30: Pop - 31: LdU64(14566554180833181697) - 32: Abort -B10: - 33: CopyLoc[0](o: &Outer) - 34: ImmBorrowVariantField[1](One.i: Inner) - 35: Call is_inner1(&Inner): bool - 36: BrTrue(38) -B11: - 37: Branch(13) -B12: - 38: MoveLoc[0](o: &Outer) - 39: Pop - 40: LdTrue - 41: StLoc[1](return: bool) - 42: Branch(7) -} -select_common_fields(s: CommonFields): u64 /* def_idx: 9 */ { -L1: $t3: &CommonFields -L2: $t2: u64 -L3: y: u64 -B0: - 0: ImmBorrowLoc[0](s: CommonFields) - 1: ImmBorrowVariantField[3](Foo.x|Bar.x: u64) - 2: ReadRef - 3: StLoc[2]($t2: u64) - 4: ImmBorrowLoc[0](s: CommonFields) - 5: StLoc[1]($t3: &CommonFields) - 6: CopyLoc[1]($t3: &CommonFields) - 7: TestVariant[7](CommonFields/Foo) - 8: BrFalse(19) -B1: - 9: MoveLoc[1]($t3: &CommonFields) - 10: Pop - 11: MoveLoc[0](s: CommonFields) - 12: UnpackVariant[7](CommonFields/Foo) - 13: StLoc[3](y: u64) - 14: Pop -B2: - 15: MoveLoc[2]($t2: u64) - 16: MoveLoc[3](y: u64) - 17: Add - 18: Ret -B3: - 19: MoveLoc[1]($t3: &CommonFields) - 20: TestVariant[8](CommonFields/Bar) - 21: BrFalse(27) -B4: - 22: MoveLoc[0](s: CommonFields) - 23: UnpackVariant[8](CommonFields/Bar) - 24: StLoc[3](y: u64) - 25: Pop - 26: Branch(15) -B5: - 27: LdU64(14566554180833181697) - 28: Abort -} -select_common_fields_different_offset(s: CommonFieldsAtDifferentOffset): u64 /* def_idx: 10 */ { -L1: $t2: &CommonFieldsAtDifferentOffset -L2: $t3: &u64 -B0: - 0: ImmBorrowLoc[0](s: CommonFieldsAtDifferentOffset) - 1: StLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 2: CopyLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 3: TestVariant[9](CommonFieldsAtDifferentOffset/Bar) - 4: BrFalse(12) -B1: - 5: Branch(6) -B2: - 6: MoveLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 7: ImmBorrowVariantField[4](Bar.z|Balt.z: u64) - 8: StLoc[2]($t3: &u64) -B3: - 9: MoveLoc[2]($t3: &u64) - 10: ReadRef - 11: Ret -B4: - 12: CopyLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 13: TestVariant[10](CommonFieldsAtDifferentOffset/Balt) - 14: BrFalse(16) -B5: - 15: Branch(6) -B6: - 16: MoveLoc[1]($t2: &CommonFieldsAtDifferentOffset) - 17: ImmBorrowVariantField[5](Baz.z: u64) - 18: StLoc[2]($t3: &u64) - 19: Branch(9) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.exp index 770e77a1aa0..a0346639925 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun take(l0: u64) + ret + +// Function definition at index 1 +fun test(l0: signer) + local l1: |signer| + pack_closure __lambda__1__test, 0 + st_loc l1 + move_loc l0 + move_loc l1 + call_closure <|signer|> + // @5 + ret + +// Function definition at index 2 +fun __lambda__1__test(l0: signer) + ld_u64 5 + call take + ret -take(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -test(s: signer) /* def_idx: 1 */ { -L1: f: |signer| -B0: - 0: PackClosure#0 __lambda__1__test(signer) - 1: StLoc[1](f: |signer|) - 2: MoveLoc[0](s: signer) - 3: MoveLoc[1](f: |signer|) - 4: CallClosure(|signer|) - 5: Ret -} -__lambda__1__test(_s: signer) /* def_idx: 2 */ { -B0: - 0: LdU64(5) - 1: Call take(u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.opt.exp index 770e77a1aa0..a0346639925 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/uncurried_arguments.opt.exp @@ -1,28 +1,27 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun take(l0: u64) + ret + +// Function definition at index 1 +fun test(l0: signer) + local l1: |signer| + pack_closure __lambda__1__test, 0 + st_loc l1 + move_loc l0 + move_loc l1 + call_closure <|signer|> + // @5 + ret + +// Function definition at index 2 +fun __lambda__1__test(l0: signer) + ld_u64 5 + call take + ret -take(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -test(s: signer) /* def_idx: 1 */ { -L1: f: |signer| -B0: - 0: PackClosure#0 __lambda__1__test(signer) - 1: StLoc[1](f: |signer|) - 2: MoveLoc[0](s: signer) - 3: MoveLoc[1](f: |signer|) - 4: CallClosure(|signer|) - 5: Ret -} -__lambda__1__test(_s: signer) /* def_idx: 2 */ { -B0: - 0: LdU64(5) - 1: Call take(u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.exp index 855a56a49f8..781a592960f 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.exp @@ -1,54 +1,51 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0x42::m +use 0x1::vector +struct E has copy + drop + store + key: T0 +struct Option has copy + drop + store + vec: vector + +// Function definition at index 0 +#[persistent] public fun destroy_none(l0: Option) + borrow_loc l0 + call is_none + br_false l0 + branch l1 +l0: ld_u64 262144 + // @5 + abort +l1: move_loc l0 + unpack Option + vec_unpack , 0 + ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: E, l1: &mut T0) + local l2: T0 + move_loc l0 + unpack E + pack E + unpack E + ld_u64 3 + // @5 + pop + st_loc l2 + move_loc l2 + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 2 +#[persistent] public fun is_none(l0: &Option): bool + move_loc l0 + borrow_field Option, vec + call vector::is_empty + ret -struct E has copy, drop, store { - key: Key -} -struct Option has copy, drop, store { - vec: vector -} -public destroy_none(t: Option) /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](t: Option) - 1: Call is_none(&Option): bool - 2: BrFalse(4) -B1: - 3: Branch(6) -B2: - 4: LdU64(262144) - 5: Abort -B3: - 6: MoveLoc[0](t: Option) - 7: UnpackGeneric[0](Option) - 8: VecUnpack(2, 0) - 9: Ret -} -public foo(data: E, v: &mut Key) /* def_idx: 1 */ { -L2: key: Key -B0: - 0: MoveLoc[0](data: E) - 1: UnpackGeneric[1](E) - 2: PackGeneric[1](E) - 3: UnpackGeneric[1](E) - 4: LdU64(3) - 5: Pop - 6: StLoc[2](key: Key) - 7: MoveLoc[2](key: Key) - 8: MoveLoc[1](v: &mut Key) - 9: WriteRef - 10: Ret -} -public is_none(t: &Option): bool /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](t: &Option) - 1: ImmBorrowFieldGeneric[0](Option.vec: vector) - 2: Call vector::is_empty(&vector): bool - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.opt.exp index 61d57a64fb5..7691ab76080 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct.opt.exp @@ -1,47 +1,44 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0x42::m +use 0x1::vector +struct E has copy + drop + store + key: T0 +struct Option has copy + drop + store + vec: vector + +// Function definition at index 0 +#[persistent] public fun destroy_none(l0: Option) + borrow_loc l0 + call is_none + br_false l0 + move_loc l0 + unpack Option + // @5 + vec_unpack , 0 + ret +l0: ld_u64 262144 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: E, l1: &mut T0) + move_loc l0 + unpack E + pack E + unpack E + move_loc l1 + // @5 + write_ref + ret + +// Function definition at index 2 +#[persistent] public fun is_none(l0: &Option): bool + move_loc l0 + borrow_field Option, vec + call vector::is_empty + ret -struct E has copy, drop, store { - key: Key -} -struct Option has copy, drop, store { - vec: vector -} -public destroy_none(t: Option) /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](t: Option) - 1: Call is_none(&Option): bool - 2: BrFalse(7) -B1: - 3: MoveLoc[0](t: Option) - 4: UnpackGeneric[0](Option) - 5: VecUnpack(2, 0) - 6: Ret -B2: - 7: LdU64(262144) - 8: Abort -} -public foo(data: E, v: &mut Key) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](data: E) - 1: UnpackGeneric[1](E) - 2: PackGeneric[1](E) - 3: UnpackGeneric[1](E) - 4: MoveLoc[1](v: &mut Key) - 5: WriteRef - 6: Ret -} -public is_none(t: &Option): bool /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](t: &Option) - 1: ImmBorrowFieldGeneric[0](Option.vec: vector) - 2: Call vector::is_empty(&vector): bool - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.exp index 855a56a49f8..781a592960f 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.exp @@ -1,54 +1,51 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0x42::m +use 0x1::vector +struct E has copy + drop + store + key: T0 +struct Option has copy + drop + store + vec: vector + +// Function definition at index 0 +#[persistent] public fun destroy_none(l0: Option) + borrow_loc l0 + call is_none + br_false l0 + branch l1 +l0: ld_u64 262144 + // @5 + abort +l1: move_loc l0 + unpack Option + vec_unpack , 0 + ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: E, l1: &mut T0) + local l2: T0 + move_loc l0 + unpack E + pack E + unpack E + ld_u64 3 + // @5 + pop + st_loc l2 + move_loc l2 + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 2 +#[persistent] public fun is_none(l0: &Option): bool + move_loc l0 + borrow_field Option, vec + call vector::is_empty + ret -struct E has copy, drop, store { - key: Key -} -struct Option has copy, drop, store { - vec: vector -} -public destroy_none(t: Option) /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](t: Option) - 1: Call is_none(&Option): bool - 2: BrFalse(4) -B1: - 3: Branch(6) -B2: - 4: LdU64(262144) - 5: Abort -B3: - 6: MoveLoc[0](t: Option) - 7: UnpackGeneric[0](Option) - 8: VecUnpack(2, 0) - 9: Ret -} -public foo(data: E, v: &mut Key) /* def_idx: 1 */ { -L2: key: Key -B0: - 0: MoveLoc[0](data: E) - 1: UnpackGeneric[1](E) - 2: PackGeneric[1](E) - 3: UnpackGeneric[1](E) - 4: LdU64(3) - 5: Pop - 6: StLoc[2](key: Key) - 7: MoveLoc[2](key: Key) - 8: MoveLoc[1](v: &mut Key) - 9: WriteRef - 10: Ret -} -public is_none(t: &Option): bool /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](t: &Option) - 1: ImmBorrowFieldGeneric[0](Option.vec: vector) - 2: Call vector::is_empty(&vector): bool - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.opt.exp index 61d57a64fb5..7691ab76080 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/unpack_generic_struct_typed.opt.exp @@ -1,47 +1,44 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -use 0000000000000000000000000000000000000000000000000000000000000001::vector; +// Bytecode version v9 +module 0x42::m +use 0x1::vector +struct E has copy + drop + store + key: T0 +struct Option has copy + drop + store + vec: vector + +// Function definition at index 0 +#[persistent] public fun destroy_none(l0: Option) + borrow_loc l0 + call is_none + br_false l0 + move_loc l0 + unpack Option + // @5 + vec_unpack , 0 + ret +l0: ld_u64 262144 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: E, l1: &mut T0) + move_loc l0 + unpack E + pack E + unpack E + move_loc l1 + // @5 + write_ref + ret + +// Function definition at index 2 +#[persistent] public fun is_none(l0: &Option): bool + move_loc l0 + borrow_field Option, vec + call vector::is_empty + ret -struct E has copy, drop, store { - key: Key -} -struct Option has copy, drop, store { - vec: vector -} -public destroy_none(t: Option) /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](t: Option) - 1: Call is_none(&Option): bool - 2: BrFalse(7) -B1: - 3: MoveLoc[0](t: Option) - 4: UnpackGeneric[0](Option) - 5: VecUnpack(2, 0) - 6: Ret -B2: - 7: LdU64(262144) - 8: Abort -} -public foo(data: E, v: &mut Key) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](data: E) - 1: UnpackGeneric[1](E) - 2: PackGeneric[1](E) - 3: UnpackGeneric[1](E) - 4: MoveLoc[1](v: &mut Key) - 5: WriteRef - 6: Ret -} -public is_none(t: &Option): bool /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](t: &Option) - 1: ImmBorrowFieldGeneric[0](Option.vec: vector) - 2: Call vector::is_empty(&vector): bool - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.exp new file mode 100644 index 00000000000..adab0abc381 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.exp @@ -0,0 +1,55 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x815::m +enum Color + RGB + red: u64 + green: u64 + blue: u64 + Red + Blue + +// Function definition at index 0 +fun test_red(l0: &Color): bool + move_loc l0 + test_variant Color, Red + ret + +// Function definition at index 1 +fun test_rgb_reduces_to_is_cascade_with_opt(l0: &Color): bool + local l1: bool + copy_loc l0 + test_variant Color, Red + br_false l0 + move_loc l0 + pop + // @5 + ld_false + st_loc l1 + branch l1 +l0: copy_loc l0 + test_variant Color, Blue + // @10 + br_false l2 + move_loc l0 + pop + ld_false + st_loc l1 + // @15 + branch l1 +l2: move_loc l0 + test_variant Color, RGB + br_false l3 + ld_true + // @20 + st_loc l1 + branch l1 +l3: ld_u64 14566554180833181697 + abort +l1: move_loc l1 + // @25 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.move b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.move new file mode 100644 index 00000000000..3b800f102af --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.move @@ -0,0 +1,24 @@ +module 0x815::m { + + enum Color { + RGB{red: u64, green: u64, blue: u64}, + Red, + Blue, + } + + fun test_rgb_reduces_to_is_cascade_with_opt(self: &Color): bool { + match (self) { + Red => false, + Blue => false, + RGB{..} => true + } + } + + fun test_red(self: &Color): bool { + match (self) { + Red => true, + _ => false + } + } + +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.opt.exp new file mode 100644 index 00000000000..f933e680bf9 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/variants_match_reduces_to_is.opt.exp @@ -0,0 +1,48 @@ + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x815::m +enum Color + RGB + red: u64 + green: u64 + blue: u64 + Red + Blue + +// Function definition at index 0 +fun test_red(l0: &Color): bool + move_loc l0 + test_variant Color, Red + ret + +// Function definition at index 1 +fun test_rgb_reduces_to_is_cascade_with_opt(l0: &Color): bool + copy_loc l0 + test_variant Color, Red + br_false l0 + move_loc l0 + pop + // @5 + ld_false + ret +l0: copy_loc l0 + test_variant Color, Blue + br_false l1 + // @10 + move_loc l0 + pop + ld_false + ret +l1: move_loc l0 + // @15 + test_variant Color, RGB + br_false l2 + ld_true + ret +l2: ld_u64 14566554180833181697 + // @20 + abort + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp index 451d534364c..6cb2443e883 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp @@ -1,110 +1,102 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.vector { -use 0000000000000000000000000000000000000000000000000000000000000001::vector as 1vector; +// Bytecode version v9 +module 0x42::vector +use 0x1::vector +// Function definition at index 0 +#[persistent] public fun remove(l0: &mut vector, l1: u64): T0 + local l2: u64 + local l3: u64 + copy_loc l0 + freeze_ref + vec_len + copy_loc l1 + st_loc l2 + // @5 + st_loc l3 + move_loc l2 + copy_loc l3 + ge + br_false l0 + // @10 + move_loc l0 + pop + ld_u64 1 + abort + branch l0 + // @15 +l0: move_loc l3 + ld_u64 1 + sub + st_loc l3 +l4: copy_loc l1 + // @20 + copy_loc l3 + lt + br_false l1 + copy_loc l0 + copy_loc l1 + // @25 + move_loc l1 + ld_u64 1 + add + st_loc l1 + copy_loc l1 + // @30 + vec_swap + branch l2 +l1: branch l3 +l2: branch l4 +l3: move_loc l0 + // @35 + vec_pop_back + ret +// Function definition at index 1 +fun create(): vector + ld_const> [1, 2, 3] + ret +// Function definition at index 2 +fun test_fold() + local l0: vector + local l1: u64 + local l2: u64 + ld_u64 0 + ld_const> [1] + st_loc l0 + mut_borrow_loc l0 + call vector::reverse + // @5 + st_loc l1 +l3: borrow_loc l0 + call vector::is_empty + not + br_false l0 + // @10 + mut_borrow_loc l0 + vec_pop_back + move_loc l1 + pop + st_loc l2 + // @15 + move_loc l2 + ld_u64 0 + st_loc l1 + pop + branch l1 + // @20 +l0: branch l2 +l1: branch l3 +l2: move_loc l1 + ld_u64 0 + eq + // @25 + br_false l4 + branch l5 +l4: ld_u64 0 + abort +l5: ret -public remove(v: &mut vector, i: u64): Element /* def_idx: 0 */ { -L2: $t6: u64 -L3: len: u64 -B0: - 0: CopyLoc[0](v: &mut vector) - 1: FreezeRef - 2: VecLen(1) - 3: CopyLoc[1](i: u64) - 4: StLoc[2]($t6: u64) - 5: StLoc[3](len: u64) - 6: MoveLoc[2]($t6: u64) - 7: CopyLoc[3](len: u64) - 8: Ge - 9: BrFalse(15) -B1: - 10: MoveLoc[0](v: &mut vector) - 11: Pop - 12: LdU64(1) - 13: Abort -B2: - 14: Branch(15) -B3: - 15: MoveLoc[3](len: u64) - 16: LdU64(1) - 17: Sub - 18: StLoc[3](len: u64) -B4: - 19: CopyLoc[1](i: u64) - 20: CopyLoc[3](len: u64) - 21: Lt - 22: BrFalse(32) -B5: - 23: CopyLoc[0](v: &mut vector) - 24: CopyLoc[1](i: u64) - 25: MoveLoc[1](i: u64) - 26: LdU64(1) - 27: Add - 28: StLoc[1](i: u64) - 29: CopyLoc[1](i: u64) - 30: VecSwap(1) - 31: Branch(33) -B6: - 32: Branch(34) -B7: - 33: Branch(19) -B8: - 34: MoveLoc[0](v: &mut vector) - 35: VecPopBack(1) - 36: Ret -} -create(): vector /* def_idx: 1 */ { -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: Ret -} -test_fold() /* def_idx: 2 */ { -L0: v: vector -L1: accu: u64 -L2: elem: u64 -B0: - 0: LdU64(0) - 1: LdConst[1](Vector(U64): [1, 1, 0, 0, 0, 0, 0, 0, 0]) - 2: StLoc[0](v: vector) - 3: MutBorrowLoc[0](v: vector) - 4: Call 1vector::reverse(&mut vector) - 5: StLoc[1](accu: u64) -B1: - 6: ImmBorrowLoc[0](v: vector) - 7: Call 1vector::is_empty(&vector): bool - 8: Not - 9: BrFalse(20) -B2: - 10: MutBorrowLoc[0](v: vector) - 11: VecPopBack(5) - 12: MoveLoc[1](accu: u64) - 13: Pop - 14: StLoc[2](elem: u64) - 15: MoveLoc[2](elem: u64) - 16: LdU64(0) - 17: StLoc[1](accu: u64) - 18: Pop - 19: Branch(21) -B3: - 20: Branch(22) -B4: - 21: Branch(6) -B5: - 22: MoveLoc[1](accu: u64) - 23: LdU64(0) - 24: Eq - 25: BrFalse(27) -B6: - 26: Branch(29) -B7: - 27: LdU64(0) - 28: Abort -B8: - 29: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.opt.exp index 7dd014cd0c0..bcf178ccf1c 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.opt.exp @@ -1,89 +1,85 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.vector { -use 0000000000000000000000000000000000000000000000000000000000000001::vector as 1vector; +// Bytecode version v9 +module 0x42::vector +use 0x1::vector +// Function definition at index 0 +#[persistent] public fun remove(l0: &mut vector, l1: u64): T0 + local l2: u64 + copy_loc l0 + freeze_ref + vec_len + st_loc l2 + copy_loc l1 + // @5 + copy_loc l2 + ge + br_false l0 + move_loc l0 + pop + // @10 + ld_u64 1 + abort +l0: move_loc l2 + ld_u64 1 + sub + // @15 + st_loc l2 +l2: copy_loc l1 + copy_loc l2 + lt + br_false l1 + // @20 + copy_loc l0 + copy_loc l1 + move_loc l1 + ld_u64 1 + add + // @25 + st_loc l1 + copy_loc l1 + vec_swap + branch l2 +l1: move_loc l0 + // @30 + vec_pop_back + ret +// Function definition at index 1 +fun create(): vector + ld_const> [1, 2, 3] + ret +// Function definition at index 2 +fun test_fold() + local l0: u64 + local l1: vector + ld_u64 0 + st_loc l0 + ld_const> [1] + st_loc l1 + mut_borrow_loc l1 + // @5 + call vector::reverse +l1: borrow_loc l1 + call vector::is_empty + br_true l0 + mut_borrow_loc l1 + // @10 + vec_pop_back + pop + ld_u64 0 + st_loc l0 + branch l1 + // @15 +l0: move_loc l0 + ld_u64 0 + eq + br_false l2 + ret + // @20 +l2: ld_u64 0 + abort -public remove(v: &mut vector, i: u64): Element /* def_idx: 0 */ { -L2: len: u64 -B0: - 0: CopyLoc[0](v: &mut vector) - 1: FreezeRef - 2: VecLen(1) - 3: StLoc[2](len: u64) - 4: CopyLoc[1](i: u64) - 5: CopyLoc[2](len: u64) - 6: Ge - 7: BrFalse(12) -B1: - 8: MoveLoc[0](v: &mut vector) - 9: Pop - 10: LdU64(1) - 11: Abort -B2: - 12: MoveLoc[2](len: u64) - 13: LdU64(1) - 14: Sub - 15: StLoc[2](len: u64) -B3: - 16: CopyLoc[1](i: u64) - 17: CopyLoc[2](len: u64) - 18: Lt - 19: BrFalse(29) -B4: - 20: CopyLoc[0](v: &mut vector) - 21: CopyLoc[1](i: u64) - 22: MoveLoc[1](i: u64) - 23: LdU64(1) - 24: Add - 25: StLoc[1](i: u64) - 26: CopyLoc[1](i: u64) - 27: VecSwap(1) - 28: Branch(16) -B5: - 29: MoveLoc[0](v: &mut vector) - 30: VecPopBack(1) - 31: Ret -} -create(): vector /* def_idx: 1 */ { -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: Ret -} -test_fold() /* def_idx: 2 */ { -L0: accu: u64 -L1: v: vector -B0: - 0: LdU64(0) - 1: StLoc[0](accu: u64) - 2: LdConst[1](Vector(U64): [1, 1, 0, 0, 0, 0, 0, 0, 0]) - 3: StLoc[1](v: vector) - 4: MutBorrowLoc[1](v: vector) - 5: Call 1vector::reverse(&mut vector) -B1: - 6: ImmBorrowLoc[1](v: vector) - 7: Call 1vector::is_empty(&vector): bool - 8: BrTrue(15) -B2: - 9: MutBorrowLoc[1](v: vector) - 10: VecPopBack(2) - 11: Pop - 12: LdU64(0) - 13: StLoc[0](accu: u64) - 14: Branch(6) -B3: - 15: MoveLoc[0](accu: u64) - 16: LdU64(0) - 17: Eq - 18: BrFalse(20) -B4: - 19: Ret -B5: - 20: LdU64(0) - 21: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.exp index 8f310c8236e..eae73a431a2 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.exp @@ -1,28 +1,28 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct E { - k: u8 -} -struct S { - data: vector -} +// Bytecode version v9 +module 0x42::m +struct E + k: u8 + +struct S + data: vector + +// Function definition at index 0 +fun bar() + nop + ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: &S): u8 + move_loc l0 + borrow_field S, data + ld_u64 0 + vec_borrow + borrow_field E, k + // @5 + read_ref + ret + -bar() /* def_idx: 0 */ { -B0: - 0: Nop - 1: Ret -} -public foo(v: &S): u8 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](v: &S) - 1: ImmBorrowField[0](S.data: vector) - 2: LdU64(0) - 3: VecImmBorrow(3) - 4: ImmBorrowField[1](E.k: u8) - 5: ReadRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.opt.exp index 8f310c8236e..eae73a431a2 100644 --- a/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.opt.exp +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/with_spec.opt.exp @@ -1,28 +1,28 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct E { - k: u8 -} -struct S { - data: vector -} +// Bytecode version v9 +module 0x42::m +struct E + k: u8 + +struct S + data: vector + +// Function definition at index 0 +fun bar() + nop + ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: &S): u8 + move_loc l0 + borrow_field S, data + ld_u64 0 + vec_borrow + borrow_field E, k + // @5 + read_ref + ret + -bar() /* def_idx: 0 */ { -B0: - 0: Nop - 1: Ret -} -public foo(v: &S): u8 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](v: &S) - 1: ImmBorrowField[0](S.data: vector) - 2: LdU64(0) - 3: VecImmBorrow(3) - 4: ImmBorrowField[1](E.k: u8) - 5: ReadRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.off.exp index d91569c5fdb..80d3cf200a5 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.off.exp @@ -1,33 +1,32 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + st_loc l0 + copy_loc l0 + call take1 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: CopyLoc[0](b: u64) - 3: Call take1(u64) - 4: MoveLoc[0](b: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.on.exp index 6608879c0b6..ce8ef77a8fe 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_01.on.exp @@ -47,34 +47,33 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + st_loc l0 + copy_loc l0 + call take1 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: CopyLoc[0](b: u64) - 3: Call take1(u64) - 4: MoveLoc[0](b: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.off.exp index 6c9f5bf42de..a6608208866 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.off.exp @@ -1,36 +1,35 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one_one + st_loc l0 + copy_loc l0 + call take1 + st_loc l1 + // @5 + move_loc l0 + move_loc l1 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: CopyLoc[0](b: u64) - 3: Call take1(u64) - 4: StLoc[1](a: u64) - 5: MoveLoc[0](b: u64) - 6: MoveLoc[1](a: u64) - 7: Call take2(u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.on.exp index 9f47e35b9df..77b0909aaa3 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_02.on.exp @@ -47,37 +47,36 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one_one + st_loc l0 + st_loc l1 + copy_loc l0 + call take1 + // @5 + move_loc l0 + move_loc l1 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: StLoc[1](a: u64) - 3: CopyLoc[0](b: u64) - 4: Call take1(u64) - 5: MoveLoc[0](b: u64) - 6: MoveLoc[1](a: u64) - 7: Call take2(u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.off.exp index 86f8545b2f0..4174a0372e0 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.off.exp @@ -1,33 +1,32 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + call take1 + st_loc l0 + copy_loc l0 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: Call take1(u64) - 2: StLoc[0](a: u64) - 3: CopyLoc[0](a: u64) - 4: MoveLoc[0](a: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.on.exp index 2fbeec7a7e1..adf9da7d0cd 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_03.on.exp @@ -47,34 +47,33 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + call take1 + st_loc l0 + copy_loc l0 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: Call take1(u64) - 2: StLoc[0](a: u64) - 3: CopyLoc[0](a: u64) - 4: MoveLoc[0](a: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.off.exp index c7772df6c97..713bdb1d686 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.off.exp @@ -1,34 +1,33 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one_one + st_loc l0 + call take1 + copy_loc l0 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: Call take1(u64) - 3: CopyLoc[0](b: u64) - 4: MoveLoc[0](b: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.on.exp index d3b45a777da..81333c68ac4 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_04.on.exp @@ -47,34 +47,33 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + st_loc l0 + call take1 + copy_loc l0 + move_loc l0 + // @5 + call take2 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: Call take1(u64) - 3: CopyLoc[0](b: u64) - 4: MoveLoc[0](b: u64) - 5: Call take2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.off.exp index 5ceeaa963a6..99a92106872 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.off.exp @@ -1,33 +1,32 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one_one + st_loc l0 + call take1 + move_loc l0 + call take1 + // @5 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: Call take1(u64) - 3: MoveLoc[0](b: u64) - 4: Call take1(u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.on.exp index 743a5534680..e3c1c84b445 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_05.on.exp @@ -44,33 +44,32 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 1 +fun take1(l0: u64) + ret + +// Function definition at index 2 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + call one_one + st_loc l0 + call take1 + move_loc l0 + call take1 + // @5 + ret -one_one(): u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -take1(_x: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: Call take1(u64) - 3: MoveLoc[0](b: u64) - 4: Call take1(u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.off.exp index e683e178024..2024c555f79 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.off.exp @@ -1,27 +1,26 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 1 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u64) + local l1: u64 + call one + st_loc l1 + move_loc l0 + move_loc l1 + call take2 + // @5 + ret -one(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(b: u64) /* def_idx: 2 */ { -L1: a: u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](a: u64) - 2: MoveLoc[0](b: u64) - 3: MoveLoc[1](a: u64) - 4: Call take2(u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.on.exp index c2db2b3ede3..9b77c6ca209 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_06.on.exp @@ -34,28 +34,27 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 1 +fun take2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u64) + local l1: u64 + call one + st_loc l1 + move_loc l0 + move_loc l1 + call take2 + // @5 + ret -one(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: Ret -} -take2(_x: u64, _y: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(b: u64) /* def_idx: 2 */ { -L1: a: u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](a: u64) - 2: MoveLoc[0](b: u64) - 3: MoveLoc[1](a: u64) - 4: Call take2(u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.off.exp index 1245f03912e..14c7f3871c7 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.off.exp @@ -1,26 +1,24 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(): u64 + call one + call foo + ret -foo(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(): u64 /* def_idx: 2 */ { -B0: - 0: Call one(): u64 - 1: Call foo(u64): u64 - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.on.exp index 7496517476a..3458d2a6741 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_07.on.exp @@ -43,27 +43,25 @@ public fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(): u64 + call one + call foo + ret -foo(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(): u64 /* def_idx: 2 */ { -B0: - 0: Call one(): u64 - 1: Call foo(u64): u64 - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.off.exp index 0596f134d5b..a82a15d3953 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.off.exp @@ -1,38 +1,38 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 1 +fun take(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call foo + st_loc l0 + st_loc l1 + st_loc l2 + st_loc l3 + // @5 + move_loc l2 + move_loc l1 + move_loc l0 + move_loc l3 + call take + // @10 + ret -foo(): u64 * u64 * u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -take(_x: u64, _y: u64, _z: u64, _w: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -L3: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 - 1: StLoc[0](d: u64) - 2: StLoc[1](c: u64) - 3: StLoc[2](b: u64) - 4: StLoc[3](a: u64) - 5: MoveLoc[2](b: u64) - 6: MoveLoc[1](c: u64) - 7: MoveLoc[0](d: u64) - 8: MoveLoc[3](a: u64) - 9: Call take(u64, u64, u64, u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.on.exp index 331b6a19600..11653e10673 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/def_use_08.on.exp @@ -52,39 +52,39 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 1 +fun take(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call foo + st_loc l0 + st_loc l1 + st_loc l2 + st_loc l3 + // @5 + move_loc l2 + move_loc l1 + move_loc l0 + move_loc l3 + call take + // @10 + ret -foo(): u64 * u64 * u64 * u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -take(_x: u64, _y: u64, _z: u64, _w: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -L3: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 - 1: StLoc[0](d: u64) - 2: StLoc[1](c: u64) - 3: StLoc[2](b: u64) - 4: StLoc[3](a: u64) - 5: MoveLoc[2](b: u64) - 6: MoveLoc[1](c: u64) - 7: MoveLoc[0](d: u64) - 8: MoveLoc[3](a: u64) - 9: Call take(u64, u64, u64, u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.off.exp index 8f7501c3443..62b67c33df7 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.off.exp @@ -1,58 +1,58 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: &u64) + move_loc l1 + pop + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: vector) + local l1: &vector + local l2: u64 + local l3: u64 + local l4: u64 + local l5: &u64 + call one + borrow_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 + // @5 + st_loc l3 +l1: copy_loc l2 + copy_loc l1 + vec_len + lt + // @10 + br_false l0 + copy_loc l1 + copy_loc l2 + vec_borrow + copy_loc l3 + // @15 + st_loc l4 + st_loc l5 + move_loc l4 + move_loc l5 + call consume + // @20 + move_loc l2 + ld_u64 1 + add + st_loc l2 + branch l1 + // @25 +l0: move_loc l1 + pop + ret -consume(_a: u64, _b: &u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](_b: &u64) - 1: Pop - 2: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(v: vector) /* def_idx: 2 */ { -L1: $t3: &vector -L2: i: u64 -L3: x: u64 -L4: $t6: u64 -L5: $t9: &u64 -B0: - 0: Call one(): u64 - 1: ImmBorrowLoc[0](v: vector) - 2: StLoc[1]($t3: &vector) - 3: LdU64(0) - 4: StLoc[2](i: u64) - 5: StLoc[3](x: u64) -B1: - 6: CopyLoc[2](i: u64) - 7: CopyLoc[1]($t3: &vector) - 8: VecLen(2) - 9: Lt - 10: BrFalse(25) -B2: - 11: CopyLoc[1]($t3: &vector) - 12: CopyLoc[2](i: u64) - 13: VecImmBorrow(2) - 14: CopyLoc[3](x: u64) - 15: StLoc[4]($t6: u64) - 16: StLoc[5]($t9: &u64) - 17: MoveLoc[4]($t6: u64) - 18: MoveLoc[5]($t9: &u64) - 19: Call consume(u64, &u64) - 20: MoveLoc[2](i: u64) - 21: LdU64(1) - 22: Add - 23: StLoc[2](i: u64) - 24: Branch(6) -B3: - 25: MoveLoc[1]($t3: &vector) - 26: Pop - 27: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.on.exp index 5b5828479ad..76a17914494 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_11.on.exp @@ -87,56 +87,56 @@ public fun m::test($t0: vector) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: &u64) + move_loc l1 + pop + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: vector) + local l1: u64 + local l2: &vector + local l3: u64 + local l4: &u64 + call one + st_loc l1 + borrow_loc l0 + st_loc l2 + ld_u64 0 + // @5 + st_loc l3 +l1: copy_loc l3 + copy_loc l2 + vec_len + lt + // @10 + br_false l0 + copy_loc l2 + copy_loc l3 + vec_borrow + st_loc l4 + // @15 + copy_loc l1 + move_loc l4 + call consume + move_loc l3 + ld_u64 1 + // @20 + add + st_loc l3 + branch l1 +l0: move_loc l2 + pop + // @25 + ret -consume(_a: u64, _b: &u64) /* def_idx: 0 */ { -B0: - 0: MoveLoc[1](_b: &u64) - 1: Pop - 2: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(v: vector) /* def_idx: 2 */ { -L1: x: u64 -L2: $t3: &vector -L3: i: u64 -L4: $t9: &u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](x: u64) - 2: ImmBorrowLoc[0](v: vector) - 3: StLoc[2]($t3: &vector) - 4: LdU64(0) - 5: StLoc[3](i: u64) -B1: - 6: CopyLoc[3](i: u64) - 7: CopyLoc[2]($t3: &vector) - 8: VecLen(2) - 9: Lt - 10: BrFalse(23) -B2: - 11: CopyLoc[2]($t3: &vector) - 12: CopyLoc[3](i: u64) - 13: VecImmBorrow(2) - 14: StLoc[4]($t9: &u64) - 15: CopyLoc[1](x: u64) - 16: MoveLoc[4]($t9: &u64) - 17: Call consume(u64, &u64) - 18: MoveLoc[3](i: u64) - 19: LdU64(1) - 20: Add - 21: StLoc[3](i: u64) - 22: Branch(6) -B3: - 23: MoveLoc[2]($t3: &vector) - 24: Pop - 25: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.off.exp index 55012be2e65..843620ecd0c 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.off.exp @@ -1,112 +1,118 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bytes(l0: &u64): vector + ld_const> [1, 2] + move_loc l0 + pop + ret + +// Function definition at index 1 +fun cons_2(l0: u64, l1: &mut u64): u64 + move_loc l1 + pop + move_loc l0 + ret + +// Function definition at index 2 +fun cons_2_another(l0: &u64, l1: u64) + move_loc l0 + pop + ret + +// Function definition at index 3 +fun cons_7(l0: vector, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64): u64 + ld_u64 0 + ret + +// Function definition at index 4 +fun id(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 5 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 6 +fun test(l0: u64): u64 + local l1: u64 + local l2: vector + local l3: u64 + local l4: u64 + local l5: u64 + local l6: vector + local l7: &u64 + local l8: u64 + local l9: u64 + local l10: u64 + local l11: u64 + copy_loc l0 + call id + st_loc l1 + borrow_loc l0 + call bytes + // @5 + st_loc l2 + borrow_loc l2 + vec_len + ld_u64 2 + eq + // @10 + br_false l0 + ld_u64 0 + st_loc l3 + copy_loc l0 + mut_borrow_loc l3 + // @15 + call cons_2 + call id + move_loc l0 + mut_borrow_loc l3 + call cons_2 + // @20 + call id + borrow_loc l1 + move_loc l2 + ld_u64 0 + move_loc l3 + // @25 + st_loc l4 + st_loc l5 + st_loc l6 + st_loc l7 + call one + // @30 + call id + call one + call id + st_loc l10 + st_loc l11 + // @35 + st_loc l8 + st_loc l9 + move_loc l6 + move_loc l5 + move_loc l4 + // @40 + move_loc l9 + move_loc l8 + move_loc l11 + move_loc l10 + call cons_7 + // @45 + st_loc l9 + move_loc l7 + move_loc l9 + call cons_2_another + move_loc l1 + // @50 + ret +l0: ld_u64 42 + abort -bytes(_x: &u64): vector /* def_idx: 0 */ { -B0: - 0: LdConst[0](Vector(U8): [2, 1, 2]) - 1: MoveLoc[0](_x: &u64) - 2: Pop - 3: Ret -} -cons_2(x: u64, _y: &mut u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](_y: &mut u64) - 1: Pop - 2: MoveLoc[0](x: u64) - 3: Ret -} -cons_2_another(_x: &u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](_x: &u64) - 1: Pop - 2: Ret -} -cons_7(_x: vector, _a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(0) - 1: Ret -} -id(x: u64): u64 /* def_idx: 4 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -one(): u64 /* def_idx: 5 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test(new_address: u64): u64 /* def_idx: 6 */ { -L1: new_account: u64 -L2: authentication_key: vector -L3: guid_creation_num: u64 -L4: $t23: u64 -L5: $t22: u64 -L6: $t21: vector -L7: $t4: &u64 -L8: $t8: u64 -L9: $t6: u64 -L10: $t29: u64 -L11: $t27: u64 -B0: - 0: CopyLoc[0](new_address: u64) - 1: Call id(u64): u64 - 2: StLoc[1](new_account: u64) - 3: ImmBorrowLoc[0](new_address: u64) - 4: Call bytes(&u64): vector - 5: StLoc[2](authentication_key: vector) - 6: ImmBorrowLoc[2](authentication_key: vector) - 7: VecLen(7) - 8: LdU64(2) - 9: Eq - 10: BrFalse(51) -B1: - 11: LdU64(0) - 12: StLoc[3](guid_creation_num: u64) - 13: CopyLoc[0](new_address: u64) - 14: MutBorrowLoc[3](guid_creation_num: u64) - 15: Call cons_2(u64, &mut u64): u64 - 16: Call id(u64): u64 - 17: MoveLoc[0](new_address: u64) - 18: MutBorrowLoc[3](guid_creation_num: u64) - 19: Call cons_2(u64, &mut u64): u64 - 20: Call id(u64): u64 - 21: ImmBorrowLoc[1](new_account: u64) - 22: MoveLoc[2](authentication_key: vector) - 23: LdU64(0) - 24: MoveLoc[3](guid_creation_num: u64) - 25: StLoc[4]($t23: u64) - 26: StLoc[5]($t22: u64) - 27: StLoc[6]($t21: vector) - 28: StLoc[7]($t4: &u64) - 29: Call one(): u64 - 30: Call id(u64): u64 - 31: Call one(): u64 - 32: Call id(u64): u64 - 33: StLoc[10]($t29: u64) - 34: StLoc[11]($t27: u64) - 35: StLoc[8]($t8: u64) - 36: StLoc[9]($t6: u64) - 37: MoveLoc[6]($t21: vector) - 38: MoveLoc[5]($t22: u64) - 39: MoveLoc[4]($t23: u64) - 40: MoveLoc[9]($t6: u64) - 41: MoveLoc[8]($t8: u64) - 42: MoveLoc[11]($t27: u64) - 43: MoveLoc[10]($t29: u64) - 44: Call cons_7(vector, u64, u64, u64, u64, u64, u64): u64 - 45: StLoc[9]($t6: u64) - 46: MoveLoc[7]($t4: &u64) - 47: MoveLoc[9]($t6: u64) - 48: Call cons_2_another(&u64, u64) - 49: MoveLoc[1](new_account: u64) - 50: Ret -B2: - 51: LdU64(42) - 52: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.on.exp index 4b93b9d1c62..1297e1bb0aa 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/framework_reduced_12.on.exp @@ -169,93 +169,96 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bytes(l0: &u64): vector + ld_const> [1, 2] + move_loc l0 + pop + ret + +// Function definition at index 1 +fun cons_2(l0: u64, l1: &mut u64): u64 + move_loc l1 + pop + move_loc l0 + ret + +// Function definition at index 2 +fun cons_2_another(l0: &u64, l1: u64) + move_loc l0 + pop + ret + +// Function definition at index 3 +fun cons_7(l0: vector, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64): u64 + ld_u64 0 + ret + +// Function definition at index 4 +fun id(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 5 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 6 +fun test(l0: u64): u64 + local l1: u64 + local l2: vector + local l3: u64 + local l4: u64 + local l5: u64 + copy_loc l0 + call id + st_loc l1 + borrow_loc l0 + call bytes + // @5 + st_loc l2 + borrow_loc l2 + vec_len + ld_u64 2 + eq + // @10 + br_false l0 + ld_u64 0 + st_loc l3 + copy_loc l0 + mut_borrow_loc l3 + // @15 + call cons_2 + call id + st_loc l4 + move_loc l0 + mut_borrow_loc l3 + // @20 + call cons_2 + call id + st_loc l5 + borrow_loc l1 + move_loc l2 + // @25 + ld_u64 0 + move_loc l3 + move_loc l4 + move_loc l5 + call one + // @30 + call id + call one + call id + call cons_7 + call cons_2_another + // @35 + move_loc l1 + ret +l0: ld_u64 42 + abort -bytes(_x: &u64): vector /* def_idx: 0 */ { -B0: - 0: LdConst[0](Vector(U8): [2, 1, 2]) - 1: MoveLoc[0](_x: &u64) - 2: Pop - 3: Ret -} -cons_2(x: u64, _y: &mut u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](_y: &mut u64) - 1: Pop - 2: MoveLoc[0](x: u64) - 3: Ret -} -cons_2_another(_x: &u64, _y: u64) /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](_x: &u64) - 1: Pop - 2: Ret -} -cons_7(_x: vector, _a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(0) - 1: Ret -} -id(x: u64): u64 /* def_idx: 4 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -one(): u64 /* def_idx: 5 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test(new_address: u64): u64 /* def_idx: 6 */ { -L1: new_account: u64 -L2: authentication_key: vector -L3: guid_creation_num: u64 -L4: $t6: u64 -L5: $t8: u64 -B0: - 0: CopyLoc[0](new_address: u64) - 1: Call id(u64): u64 - 2: StLoc[1](new_account: u64) - 3: ImmBorrowLoc[0](new_address: u64) - 4: Call bytes(&u64): vector - 5: StLoc[2](authentication_key: vector) - 6: ImmBorrowLoc[2](authentication_key: vector) - 7: VecLen(7) - 8: LdU64(2) - 9: Eq - 10: BrFalse(37) -B1: - 11: LdU64(0) - 12: StLoc[3](guid_creation_num: u64) - 13: CopyLoc[0](new_address: u64) - 14: MutBorrowLoc[3](guid_creation_num: u64) - 15: Call cons_2(u64, &mut u64): u64 - 16: Call id(u64): u64 - 17: StLoc[4]($t6: u64) - 18: MoveLoc[0](new_address: u64) - 19: MutBorrowLoc[3](guid_creation_num: u64) - 20: Call cons_2(u64, &mut u64): u64 - 21: Call id(u64): u64 - 22: StLoc[5]($t8: u64) - 23: ImmBorrowLoc[1](new_account: u64) - 24: MoveLoc[2](authentication_key: vector) - 25: LdU64(0) - 26: MoveLoc[3](guid_creation_num: u64) - 27: MoveLoc[4]($t6: u64) - 28: MoveLoc[5]($t8: u64) - 29: Call one(): u64 - 30: Call id(u64): u64 - 31: Call one(): u64 - 32: Call id(u64): u64 - 33: Call cons_7(vector, u64, u64, u64, u64, u64, u64): u64 - 34: Call cons_2_another(&u64, u64) - 35: MoveLoc[1](new_account: u64) - 36: Ret -B2: - 37: LdU64(42) - 38: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.off.exp index d55d5358704..b0351e80dc7 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.off.exp @@ -1,36 +1,35 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64) + ret + +// Function definition at index 1 +#[persistent] public fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + local l6: u64 + call one + call one + call one + call one + call one + // @5 + call one + call one + call consume + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64, _g: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: g: u64 -L1: f: u64 -L2: e: u64 -L3: d: u64 -L4: c: u64 -L5: b: u64 -L6: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: Call consume(u64, u64, u64, u64, u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.on.exp index ae4207168d7..78023fb2059 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_01.on.exp @@ -66,37 +66,36 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64) + ret + +// Function definition at index 1 +#[persistent] public fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + local l6: u64 + call one + call one + call one + call one + call one + // @5 + call one + call one + call consume + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64, _g: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: g: u64 -L1: f: u64 -L2: e: u64 -L3: d: u64 -L4: c: u64 -L5: b: u64 -L6: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: Call consume(u64, u64, u64, u64, u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.off.exp index 6a9946b1ca3..0b1dd1a1c05 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.off.exp @@ -1,32 +1,31 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ld_u64 5 + // @5 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + call foo + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: LdU64(5) - 5: Ret -} -public test() /* def_idx: 2 */ { -L0: e: u64 -L1: d: u64 -L2: c: u64 -L3: b: u64 -L4: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 * u64 - 1: Call consume(u64, u64, u64, u64, u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.on.exp index d0466dca9a6..495794f157e 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_02.on.exp @@ -58,33 +58,32 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ld_u64 5 + // @5 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + call foo + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: LdU64(5) - 5: Ret -} -public test() /* def_idx: 2 */ { -L0: e: u64 -L1: d: u64 -L2: c: u64 -L3: b: u64 -L4: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 * u64 - 1: Call consume(u64, u64, u64, u64, u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.off.exp index 40b64de9d3f..3085aea51d8 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.off.exp @@ -1,39 +1,38 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + call one + call one + call one + // @5 + call one + call consume_2 + call consume_4 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call consume_2(u64, u64) - 7: Call consume_4(u64, u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.on.exp index 35c8bd2ccb1..581508385b8 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_03.on.exp @@ -66,40 +66,39 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + call one + call one + call one + // @5 + call one + call consume_2 + call consume_4 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call consume_2(u64, u64) - 7: Call consume_4(u64, u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.off.exp index 9fe854e4da2..72b256e9c78 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.off.exp @@ -1,44 +1,42 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun four(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call four + call two + call consume_2 + call consume_4 + ret + +// Function definition at index 4 +fun two(): (u64, u64) + ld_u64 5 + ld_u64 6 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -four(): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call four(): u64 * u64 * u64 * u64 - 1: Call two(): u64 * u64 - 2: Call consume_2(u64, u64) - 3: Call consume_4(u64, u64, u64, u64) - 4: Ret -} -two(): u64 * u64 /* def_idx: 4 */ { -B0: - 0: LdU64(5) - 1: LdU64(6) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.on.exp index a62e547d31a..5d5fedc3b71 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_04.on.exp @@ -80,45 +80,43 @@ fun m::two(): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun four(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call four + call two + call consume_2 + call consume_4 + ret + +// Function definition at index 4 +fun two(): (u64, u64) + ld_u64 5 + ld_u64 6 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -four(): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call four(): u64 * u64 * u64 * u64 - 1: Call two(): u64 * u64 - 2: Call consume_2(u64, u64) - 3: Call consume_4(u64, u64, u64, u64) - 4: Ret -} -two(): u64 * u64 /* def_idx: 4 */ { -B0: - 0: LdU64(5) - 1: LdU64(6) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.off.exp index 8f5f630729e..1c0e0a96764 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.off.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call one + call one + call one + call one + call consume_2 + // @5 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -L3: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call consume_2(u64, u64) - 5: Call consume_2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.on.exp index eea0bfde484..96a6fedf8d3 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/in_order_use_05.on.exp @@ -47,32 +47,31 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call one + call one + call one + call one + call consume_2 + // @5 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -L3: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call consume_2(u64, u64) - 5: Call consume_2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.off.exp index 4059fc39293..7f70b6bc021 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.off.exp @@ -1,42 +1,40 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: u64): (u64, u64) + copy_loc l0 + move_loc l0 + ld_u64 1 + sub + ret + +// Function definition at index 1 +#[persistent] public fun test1(l0: u64) + local l1: u64 +l0: move_loc l0 + call foo + st_loc l0 + ld_u64 0 + eq + // @5 + br_false l0 + ret + +// Function definition at index 2 +#[persistent] public fun test2(l0: u64) + local l1: bool +l0: move_loc l0 + call foo + ld_u64 0 + eq + st_loc l1 + // @5 + st_loc l0 + move_loc l1 + br_false l0 + ret -foo(x: u64): u64 * u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[0](x: u64) - 2: LdU64(1) - 3: Sub - 4: Ret -} -public test1(x: u64) /* def_idx: 1 */ { -L1: y: u64 -B0: - 0: MoveLoc[0](x: u64) - 1: Call foo(u64): u64 * u64 - 2: StLoc[0](x: u64) - 3: LdU64(0) - 4: Eq - 5: BrFalse(0) -B1: - 6: Ret -} -public test2(x: u64) /* def_idx: 2 */ { -L1: $t2: bool -B0: - 0: MoveLoc[0](x: u64) - 1: Call foo(u64): u64 * u64 - 2: LdU64(0) - 3: Eq - 4: StLoc[1]($t2: bool) - 5: StLoc[0](x: u64) - 6: MoveLoc[1]($t2: bool) - 7: BrFalse(0) -B1: - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.on.exp index 987b1137c12..1b428aedf07 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/loop_01.on.exp @@ -72,42 +72,40 @@ public fun m::test2($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: u64): (u64, u64) + copy_loc l0 + move_loc l0 + ld_u64 1 + sub + ret + +// Function definition at index 1 +#[persistent] public fun test1(l0: u64) +l0: move_loc l0 + call foo + st_loc l0 + ld_u64 0 + eq + // @5 + br_false l0 + ret + +// Function definition at index 2 +#[persistent] public fun test2(l0: u64) + local l1: bool +l0: move_loc l0 + call foo + ld_u64 0 + eq + st_loc l1 + // @5 + st_loc l0 + move_loc l1 + br_false l0 + ret -foo(x: u64): u64 * u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[0](x: u64) - 2: LdU64(1) - 3: Sub - 4: Ret -} -public test1(x: u64) /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Call foo(u64): u64 * u64 - 2: StLoc[0](x: u64) - 3: LdU64(0) - 4: Eq - 5: BrFalse(0) -B1: - 6: Ret -} -public test2(x: u64) /* def_idx: 2 */ { -L1: $t2: bool -B0: - 0: MoveLoc[0](x: u64) - 1: Call foo(u64): u64 * u64 - 2: LdU64(0) - 3: Eq - 4: StLoc[1]($t2: bool) - 5: StLoc[0](x: u64) - 6: MoveLoc[1]($t2: bool) - 7: BrFalse(0) -B1: - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.off.exp index 004a1b378fe..57bbc16130d 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.off.exp @@ -1,33 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun inc(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 1 +#[persistent] public fun test() + local l0: u64 + ld_u64 0 + st_loc l0 +l1: move_loc l0 + call inc + st_loc l0 + // @5 + copy_loc l0 + ld_u64 10 + gt + br_true l0 + branch l1 + // @10 +l0: ret -inc(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -public test() /* def_idx: 1 */ { -L0: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](x: u64) -B1: - 2: MoveLoc[0](x: u64) - 3: Call inc(u64): u64 - 4: StLoc[0](x: u64) - 5: CopyLoc[0](x: u64) - 6: LdU64(10) - 7: Gt - 8: BrTrue(10) -B2: - 9: Branch(2) -B3: - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.on.exp index 02e86156be1..e92c5cb5903 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/loop_02.on.exp @@ -53,34 +53,31 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun inc(l0: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 1 +#[persistent] public fun test() + local l0: u64 + ld_u64 0 + st_loc l0 +l1: move_loc l0 + call inc + st_loc l0 + // @5 + copy_loc l0 + ld_u64 10 + gt + br_true l0 + branch l1 + // @10 +l0: ret -inc(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(1) - 2: Add - 3: Ret -} -public test() /* def_idx: 1 */ { -L0: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](x: u64) -B1: - 2: MoveLoc[0](x: u64) - 3: Call inc(u64): u64 - 4: StLoc[0](x: u64) - 5: CopyLoc[0](x: u64) - 6: LdU64(10) - 7: Gt - 8: BrTrue(10) -B2: - 9: Branch(2) -B3: - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.off.exp index 93ee92715ca..65180f4914e 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.off.exp @@ -1,50 +1,52 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64) + ret + +// Function definition at index 1 +#[persistent] public fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + local l6: u64 + call one + call one + call one + call one + call one + // @5 + call one + call one + st_loc l0 + st_loc l1 + st_loc l2 + // @10 + st_loc l3 + st_loc l4 + st_loc l5 + st_loc l6 + move_loc l5 + // @15 + move_loc l4 + move_loc l3 + move_loc l2 + move_loc l1 + move_loc l0 + // @20 + move_loc l6 + call consume + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64, _g: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: g: u64 -L1: f: u64 -L2: e: u64 -L3: d: u64 -L4: c: u64 -L5: b: u64 -L6: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: StLoc[0](g: u64) - 8: StLoc[1](f: u64) - 9: StLoc[2](e: u64) - 10: StLoc[3](d: u64) - 11: StLoc[4](c: u64) - 12: StLoc[5](b: u64) - 13: StLoc[6](a: u64) - 14: MoveLoc[5](b: u64) - 15: MoveLoc[4](c: u64) - 16: MoveLoc[3](d: u64) - 17: MoveLoc[2](e: u64) - 18: MoveLoc[1](f: u64) - 19: MoveLoc[0](g: u64) - 20: MoveLoc[6](a: u64) - 21: Call consume(u64, u64, u64, u64, u64, u64, u64) - 22: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.on.exp index 09c2ca2bcf6..9e961350979 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_01.on.exp @@ -67,39 +67,39 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64, l6: u64) + ret + +// Function definition at index 1 +#[persistent] public fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + local l6: u64 + call one + st_loc l0 + call one + call one + call one + // @5 + call one + call one + call one + move_loc l0 + call consume + // @10 + ret -public consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64, _g: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: a: u64 -L1: g: u64 -L2: f: u64 -L3: e: u64 -L4: d: u64 -L5: c: u64 -L6: b: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](a: u64) - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: Call one(): u64 - 8: MoveLoc[0](a: u64) - 9: Call consume(u64, u64, u64, u64, u64, u64, u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.off.exp index f580bf066a2..67b49c7bcb3 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.off.exp @@ -1,34 +1,34 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one + call one + st_loc l0 + st_loc l1 + copy_loc l1 + // @5 + st_loc l2 + move_loc l0 + move_loc l2 + move_loc l1 + call consume + // @10 + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: b: u64 -L1: a: u64 -L2: $t3: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: StLoc[0](b: u64) - 3: StLoc[1](a: u64) - 4: CopyLoc[1](a: u64) - 5: StLoc[2]($t3: u64) - 6: MoveLoc[0](b: u64) - 7: MoveLoc[2]($t3: u64) - 8: MoveLoc[1](a: u64) - 9: Call consume(u64, u64, u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.on.exp index 754ae9ab246..df076d06e90 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_02.on.exp @@ -40,29 +40,28 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + call one + st_loc l0 + call one + copy_loc l0 + move_loc l0 + // @5 + call consume + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: a: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](a: u64) - 2: Call one(): u64 - 3: CopyLoc[0](a: u64) - 4: MoveLoc[0](a: u64) - 5: Call consume(u64, u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.off.exp index 1b8cf2c79d2..315236ad6e0 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.off.exp @@ -1,34 +1,33 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one_one + st_loc l0 + st_loc l1 + copy_loc l1 + st_loc l2 + // @5 + move_loc l0 + move_loc l2 + move_loc l1 + call consume + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 2 */ { -L0: b: u64 -L1: a: u64 -L2: $t3: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: StLoc[1](a: u64) - 3: CopyLoc[1](a: u64) - 4: StLoc[2]($t3: u64) - 5: MoveLoc[0](b: u64) - 6: MoveLoc[2]($t3: u64) - 7: MoveLoc[1](a: u64) - 8: Call consume(u64, u64, u64) - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.on.exp index 4cf8e18053a..11fcf4f5b58 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_03.on.exp @@ -41,35 +41,34 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one_one + st_loc l0 + st_loc l1 + copy_loc l1 + st_loc l2 + // @5 + move_loc l0 + move_loc l2 + move_loc l1 + call consume + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 2 */ { -L0: b: u64 -L1: a: u64 -L2: $t3: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: StLoc[1](a: u64) - 3: CopyLoc[1](a: u64) - 4: StLoc[2]($t3: u64) - 5: MoveLoc[0](b: u64) - 6: MoveLoc[2]($t3: u64) - 7: MoveLoc[1](a: u64) - 8: Call consume(u64, u64, u64) - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.off.exp index 5d012e8314b..bc3d1dc7c63 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.off.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one + call one + st_loc l0 + st_loc l1 + copy_loc l1 + // @5 + move_loc l0 + move_loc l1 + call consume + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: b: u64 -L1: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: StLoc[0](b: u64) - 3: StLoc[1](a: u64) - 4: CopyLoc[1](a: u64) - 5: MoveLoc[0](b: u64) - 6: MoveLoc[1](a: u64) - 7: Call consume(u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.on.exp index 3e45f1106f9..e9efac5d1c0 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_04.on.exp @@ -41,32 +41,31 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + call one + st_loc l0 + call one + st_loc l1 + copy_loc l0 + // @5 + move_loc l1 + move_loc l0 + call consume + ret -consume(_a: u64, _b: u64, _c: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 2 */ { -L0: a: u64 -L1: b: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](a: u64) - 2: Call one(): u64 - 3: StLoc[1](b: u64) - 4: CopyLoc[0](a: u64) - 5: MoveLoc[1](b: u64) - 6: MoveLoc[0](a: u64) - 7: Call consume(u64, u64, u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.off.exp index a2f8a4a6d55..a5469f39c5d 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.off.exp @@ -1,46 +1,47 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + st_loc l0 + call one + call one + // @5 + call one + call one + st_loc l2 + st_loc l3 + st_loc l4 + // @10 + st_loc l5 + st_loc l1 + move_loc l0 + move_loc l1 + move_loc l5 + // @15 + move_loc l4 + move_loc l3 + move_loc l2 + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test() /* def_idx: 2 */ { -L0: $t1: u64 -L1: a: u64 -L2: $t6: u64 -L3: $t5: u64 -L4: $t4: u64 -L5: $t3: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: StLoc[0]($t1: u64) - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: StLoc[2]($t6: u64) - 8: StLoc[3]($t5: u64) - 9: StLoc[4]($t4: u64) - 10: StLoc[5]($t3: u64) - 11: StLoc[1](a: u64) - 12: MoveLoc[0]($t1: u64) - 13: MoveLoc[1](a: u64) - 14: MoveLoc[5]($t3: u64) - 15: MoveLoc[4]($t4: u64) - 16: MoveLoc[3]($t5: u64) - 17: MoveLoc[2]($t6: u64) - 18: Call consume(u64, u64, u64, u64, u64, u64) - 19: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.on.exp index c9e03cf690a..907f3187839 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_05.on.exp @@ -49,32 +49,31 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +fun test() + local l0: u64 + call one + st_loc l0 + call one + move_loc l0 + call one + // @5 + call one + call one + call one + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test() /* def_idx: 2 */ { -L0: a: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](a: u64) - 2: Call one(): u64 - 3: MoveLoc[0](a: u64) - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: Call one(): u64 - 8: Call consume(u64, u64, u64, u64, u64, u64) - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.off.exp index 4d07e06669d..aab3494693b 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.off.exp @@ -1,61 +1,64 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun multi(): (u64, u64, u64, u64, u64, u64) + call one + call one + call one + call one + call one + // @5 + call one + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call multi + call one + st_loc l0 + pop + pop + // @5 + pop + pop + pop + call one + call one + // @10 + call one + call one + st_loc l2 + st_loc l3 + st_loc l4 + // @15 + st_loc l5 + st_loc l1 + move_loc l0 + move_loc l1 + move_loc l5 + // @20 + move_loc l4 + move_loc l3 + move_loc l2 + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -multi(): u64 * u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test() /* def_idx: 3 */ { -L0: $t6: u64 -L1: a: u64 -L2: $t11: u64 -L3: $t10: u64 -L4: $t9: u64 -L5: $t8: u64 -B0: - 0: Call multi(): u64 * u64 * u64 * u64 * u64 * u64 - 1: Call one(): u64 - 2: StLoc[0]($t6: u64) - 3: Pop - 4: Pop - 5: Pop - 6: Pop - 7: Pop - 8: Call one(): u64 - 9: Call one(): u64 - 10: Call one(): u64 - 11: Call one(): u64 - 12: StLoc[2]($t11: u64) - 13: StLoc[3]($t10: u64) - 14: StLoc[4]($t9: u64) - 15: StLoc[5]($t8: u64) - 16: StLoc[1](a: u64) - 17: MoveLoc[0]($t6: u64) - 18: MoveLoc[1](a: u64) - 19: MoveLoc[5]($t8: u64) - 20: MoveLoc[4]($t9: u64) - 21: MoveLoc[3]($t10: u64) - 22: MoveLoc[2]($t11: u64) - 23: Call consume(u64, u64, u64, u64, u64, u64) - 24: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.on.exp index 2f121e815d0..a86711d60a8 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_06.on.exp @@ -79,47 +79,48 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64, l5: u64) + ret + +// Function definition at index 1 +fun multi(): (u64, u64, u64, u64, u64, u64) + call one + call one + call one + call one + call one + // @5 + call one + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +fun test() + local l0: u64 + call multi + pop + pop + pop + pop + // @5 + pop + st_loc l0 + call one + move_loc l0 + call one + // @10 + call one + call one + call one + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64, _f: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -multi(): u64 * u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -test() /* def_idx: 3 */ { -L0: a: u64 -B0: - 0: Call multi(): u64 * u64 * u64 * u64 * u64 * u64 - 1: Pop - 2: Pop - 3: Pop - 4: Pop - 5: Pop - 6: StLoc[0](a: u64) - 7: Call one(): u64 - 8: MoveLoc[0](a: u64) - 9: Call one(): u64 - 10: Call one(): u64 - 11: Call one(): u64 - 12: Call one(): u64 - 13: Call consume(u64, u64, u64, u64, u64, u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.off.exp index 16db953746f..472d0382db4 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.off.exp @@ -1,43 +1,43 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + call one + call one + call one + // @5 + call one + st_loc l0 + st_loc l1 + call consume_4 + move_loc l1 + // @10 + move_loc l0 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: StLoc[0](f: u64) - 7: StLoc[1](e: u64) - 8: Call consume_4(u64, u64, u64, u64) - 9: MoveLoc[1](e: u64) - 10: MoveLoc[0](f: u64) - 11: Call consume_2(u64, u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.on.exp index c8bb2439204..63a55c208c0 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_07.on.exp @@ -66,44 +66,44 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + call one + call one + call one + // @5 + call one + st_loc l0 + st_loc l1 + call consume_4 + move_loc l1 + // @10 + move_loc l0 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: StLoc[0](f: u64) - 7: StLoc[1](e: u64) - 8: Call consume_4(u64, u64, u64, u64) - 9: MoveLoc[1](e: u64) - 10: MoveLoc[0](f: u64) - 11: Call consume_2(u64, u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.off.exp index 46fb53a888e..9c057f36fcb 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.off.exp @@ -1,48 +1,47 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun four(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call four + call two + st_loc l0 + st_loc l1 + call consume_4 + // @5 + move_loc l1 + move_loc l0 + call consume_2 + ret + +// Function definition at index 4 +fun two(): (u64, u64) + ld_u64 5 + ld_u64 6 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -four(): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call four(): u64 * u64 * u64 * u64 - 1: Call two(): u64 * u64 - 2: StLoc[0](f: u64) - 3: StLoc[1](e: u64) - 4: Call consume_4(u64, u64, u64, u64) - 5: MoveLoc[1](e: u64) - 6: MoveLoc[0](f: u64) - 7: Call consume_2(u64, u64) - 8: Ret -} -two(): u64 * u64 /* def_idx: 4 */ { -B0: - 0: LdU64(5) - 1: LdU64(6) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.on.exp index 7d8d91ad81b..450cde4d20a 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_08.on.exp @@ -80,49 +80,48 @@ fun m::two(): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun consume_4(l0: u64, l1: u64, l2: u64, l3: u64) + ret + +// Function definition at index 2 +fun four(): (u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call four + call two + st_loc l0 + st_loc l1 + call consume_4 + // @5 + move_loc l1 + move_loc l0 + call consume_2 + ret + +// Function definition at index 4 +fun two(): (u64, u64) + ld_u64 5 + ld_u64 6 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_4(_a: u64, _b: u64, _c: u64, _d: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -four(): u64 * u64 * u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call four(): u64 * u64 * u64 * u64 - 1: Call two(): u64 * u64 - 2: StLoc[0](f: u64) - 3: StLoc[1](e: u64) - 4: Call consume_4(u64, u64, u64, u64) - 5: MoveLoc[1](e: u64) - 6: MoveLoc[0](f: u64) - 7: Call consume_2(u64, u64) - 8: Ret -} -two(): u64 * u64 /* def_idx: 4 */ { -B0: - 0: LdU64(5) - 1: LdU64(6) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.off.exp index 8b9f602566a..23a46297a0c 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.off.exp @@ -1,49 +1,50 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_5(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + call one + call one + call one + // @5 + call one + st_loc l0 + st_loc l1 + st_loc l2 + st_loc l3 + // @10 + st_loc l4 + move_loc l3 + move_loc l2 + move_loc l1 + move_loc l0 + // @15 + call consume_5 + move_loc l4 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_5(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: f: u64 -L1: e: u64 -L2: d: u64 -L3: c: u64 -L4: b: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: StLoc[0](f: u64) - 7: StLoc[1](e: u64) - 8: StLoc[2](d: u64) - 9: StLoc[3](c: u64) - 10: StLoc[4](b: u64) - 11: MoveLoc[3](c: u64) - 12: MoveLoc[2](d: u64) - 13: MoveLoc[1](e: u64) - 14: MoveLoc[0](f: u64) - 15: Call consume_5(u64, u64, u64, u64, u64) - 16: MoveLoc[4](b: u64) - 17: Call consume_1(u64) - 18: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.on.exp index 137a47bc729..e530637dec6 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_09.on.exp @@ -67,42 +67,42 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_5(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + local l5: u64 + call one + call one + st_loc l0 + call one + call one + // @5 + call one + call one + call consume_5 + move_loc l0 + call consume_1 + // @10 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_5(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: f: u64 -L2: e: u64 -L3: d: u64 -L4: c: u64 -L5: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: StLoc[0](b: u64) - 3: Call one(): u64 - 4: Call one(): u64 - 5: Call one(): u64 - 6: Call one(): u64 - 7: Call consume_5(u64, u64, u64, u64, u64) - 8: MoveLoc[0](b: u64) - 9: Call consume_1(u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.off.exp index 2b996cb3625..af4c80f6282 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.off.exp @@ -1,37 +1,36 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one + call one + call one + st_loc l0 + st_loc l1 + // @5 + call consume_1 + move_loc l1 + move_loc l0 + call consume_2 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: c: u64 -L1: b: u64 -L2: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](c: u64) - 4: StLoc[1](b: u64) - 5: Call consume_1(u64) - 6: MoveLoc[1](b: u64) - 7: MoveLoc[0](c: u64) - 8: Call consume_2(u64, u64) - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.on.exp index 1ae24b9dfa3..75772a88fdc 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_10.on.exp @@ -49,36 +49,35 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one + st_loc l0 + call one + call one + move_loc l0 + // @5 + call consume_1 + call consume_2 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: a: u64 -L1: c: u64 -L2: b: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](a: u64) - 2: Call one(): u64 - 3: Call one(): u64 - 4: MoveLoc[0](a: u64) - 5: Call consume_1(u64) - 6: Call consume_2(u64, u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.off.exp index 7f50e44658e..bc46a9d5e49 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.off.exp @@ -1,31 +1,30 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one_one + call one_one + st_loc l0 + call consume_2 + move_loc l0 + // @5 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: Call one_one(): u64 * u64 - 2: StLoc[0](d: u64) - 3: Call consume_2(u64, u64) - 4: MoveLoc[0](d: u64) - 5: Call consume_2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.on.exp index 1f68c4c144e..86e4410f19d 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_11.on.exp @@ -46,32 +46,31 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 1 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one_one + call one_one + st_loc l0 + call consume_2 + move_loc l0 + // @5 + call consume_2 + ret -consume_2(_a: u64, _b: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 2 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: Call one_one(): u64 * u64 - 2: StLoc[0](d: u64) - 3: Call consume_2(u64, u64) - 4: MoveLoc[0](d: u64) - 5: Call consume_2(u64, u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.off.exp index 5169bf7ba79..11b7f129761 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.off.exp @@ -1,40 +1,40 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_3(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 2 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call one_one + call one_one + st_loc l0 + st_loc l1 + st_loc l2 + // @5 + move_loc l1 + move_loc l0 + call consume_3 + move_loc l2 + call consume_1 + // @10 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_3(_a: u64, _b: u64, _c: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 3 */ { -L0: d: u64 -L1: c: u64 -L2: b: u64 -L3: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: Call one_one(): u64 * u64 - 2: StLoc[0](d: u64) - 3: StLoc[1](c: u64) - 4: StLoc[2](b: u64) - 5: MoveLoc[1](c: u64) - 6: MoveLoc[0](d: u64) - 7: Call consume_3(u64, u64, u64) - 8: MoveLoc[2](b: u64) - 9: Call consume_1(u64) - 10: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.on.exp index 6fd070801c5..24da55602f1 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_12.on.exp @@ -54,37 +54,36 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_3(l0: u64, l1: u64, l2: u64) + ret + +// Function definition at index 2 +fun one_one(): (u64, u64) + ld_u64 1 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + call one_one + st_loc l0 + call one_one + call consume_3 + move_loc l0 + // @5 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_3(_a: u64, _b: u64, _c: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one_one(): u64 * u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Ret -} -public test() /* def_idx: 3 */ { -L0: b: u64 -L1: d: u64 -L2: c: u64 -L3: a: u64 -B0: - 0: Call one_one(): u64 * u64 - 1: StLoc[0](b: u64) - 2: Call one_one(): u64 * u64 - 3: Call consume_3(u64, u64, u64) - 4: MoveLoc[0](b: u64) - 5: Call consume_1(u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.off.exp index 6a0025a9c17..18221894dbf 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.off.exp @@ -1,35 +1,34 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one + call one + call one + st_loc l0 + call consume_2 + // @5 + move_loc l0 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: c: u64 -L1: b: u64 -L2: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](c: u64) - 4: Call consume_2(u64, u64) - 5: MoveLoc[0](c: u64) - 6: Call consume_1(u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.on.exp index 434b9be3976..f34d9bc213b 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_13.on.exp @@ -49,36 +49,35 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + call one + call one + call one + st_loc l0 + call consume_2 + // @5 + move_loc l0 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test() /* def_idx: 3 */ { -L0: c: u64 -L1: b: u64 -L2: a: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](c: u64) - 4: Call consume_2(u64, u64) - 5: MoveLoc[0](c: u64) - 6: Call consume_1(u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.off.exp index 37522dc0727..e430df67fe6 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.off.exp @@ -1,36 +1,35 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: u64) + local l1: u64 + local l2: u64 + call one + call one + st_loc l1 + st_loc l2 + move_loc l0 + // @5 + move_loc l2 + call consume_2 + move_loc l1 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(a: u64) /* def_idx: 3 */ { -L1: c: u64 -L2: b: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: StLoc[1](c: u64) - 3: StLoc[2](b: u64) - 4: MoveLoc[0](a: u64) - 5: MoveLoc[2](b: u64) - 6: Call consume_2(u64, u64) - 7: MoveLoc[1](c: u64) - 8: Call consume_1(u64) - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.on.exp index b0584d3264c..d1c246934fc 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_14.on.exp @@ -46,34 +46,33 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: u64) + local l1: u64 + call one + st_loc l1 + call one + move_loc l0 + move_loc l1 + // @5 + call consume_2 + call consume_1 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(a: u64) /* def_idx: 3 */ { -L1: b: u64 -B0: - 0: Call one(): u64 - 1: StLoc[1](b: u64) - 2: Call one(): u64 - 3: MoveLoc[0](a: u64) - 4: MoveLoc[1](b: u64) - 5: Call consume_2(u64, u64) - 6: Call consume_1(u64) - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.off.exp index 87fcf66e5ea..a20e907415e 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.off.exp @@ -1,32 +1,31 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: u64) + local l1: u64 + local l2: u64 + call one + call one + move_loc l0 + call consume_1 + call consume_2 + // @5 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(a: u64) /* def_idx: 3 */ { -L1: c: u64 -L2: b: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: MoveLoc[0](a: u64) - 3: Call consume_1(u64) - 4: Call consume_2(u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.on.exp index f23d621d86f..153c20e0264 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/out_of_order_use_15.on.exp @@ -45,33 +45,32 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume_1(l0: u64) + ret + +// Function definition at index 1 +fun consume_2(l0: u64, l1: u64) + ret + +// Function definition at index 2 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 3 +#[persistent] public fun test(l0: u64) + local l1: u64 + local l2: u64 + call one + call one + move_loc l0 + call consume_1 + call consume_2 + // @5 + ret -consume_1(_a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_2(_a: u64, _b: u64) /* def_idx: 1 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(a: u64) /* def_idx: 3 */ { -L1: c: u64 -L2: b: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: MoveLoc[0](a: u64) - 3: Call consume_1(u64) - 4: Call consume_2(u64, u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.off.exp index 6a9946b1ca3..0b1dd1a1c05 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.off.exp @@ -1,32 +1,31 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ld_u64 5 + // @5 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + call foo + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: LdU64(5) - 5: Ret -} -public test() /* def_idx: 2 */ { -L0: e: u64 -L1: d: u64 -L2: c: u64 -L3: b: u64 -L4: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 * u64 - 1: Call consume(u64, u64, u64, u64, u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.on.exp index d0466dca9a6..495794f157e 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/tuples_in_order_use_01.on.exp @@ -58,33 +58,32 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64, l1: u64, l2: u64, l3: u64, l4: u64) + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ld_u64 4 + ld_u64 5 + // @5 + ret + +// Function definition at index 2 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + local l2: u64 + local l3: u64 + local l4: u64 + call foo + call consume + ret -consume(_a: u64, _b: u64, _c: u64, _d: u64, _e: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: LdU64(4) - 4: LdU64(5) - 5: Ret -} -public test() /* def_idx: 2 */ { -L0: e: u64 -L1: d: u64 -L2: c: u64 -L3: b: u64 -L4: a: u64 -B0: - 0: Call foo(): u64 * u64 * u64 * u64 * u64 - 1: Call consume(u64, u64, u64, u64, u64) - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.off.exp index 9dc873edf5b..da2500d137c 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.off.exp @@ -1,53 +1,54 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 1 +#[persistent] public fun test1(): (u64, u64) + local l0: u64 + local l1: u64 + call one + call one + call one + st_loc l0 + st_loc l1 + // @5 + pop + move_loc l1 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test2(): (u64, u64) + local l0: u64 + local l1: u64 + call one + call one + call one + st_loc l0 + pop + // @5 + move_loc l0 + ret + +// Function definition at index 3 +#[persistent] public fun test3(): (u64, u64) + local l0: u64 + local l1: u64 + call one + call one + call one + st_loc l0 + pop + // @5 + st_loc l1 + move_loc l0 + move_loc l1 + ret -one(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test1(): u64 * u64 /* def_idx: 1 */ { -L0: z: u64 -L1: y: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](z: u64) - 4: StLoc[1](y: u64) - 5: Pop - 6: MoveLoc[1](y: u64) - 7: MoveLoc[0](z: u64) - 8: Ret -} -public test2(): u64 * u64 /* def_idx: 2 */ { -L0: z: u64 -L1: x: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](z: u64) - 4: Pop - 5: MoveLoc[0](z: u64) - 6: Ret -} -public test3(): u64 * u64 /* def_idx: 3 */ { -L0: z: u64 -L1: x: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](z: u64) - 4: Pop - 5: StLoc[1](x: u64) - 6: MoveLoc[0](z: u64) - 7: MoveLoc[1](x: u64) - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.on.exp index 672d71724bd..d00cbecc481 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_01.on.exp @@ -75,46 +75,45 @@ public fun m::test3(): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 1 +#[persistent] public fun test1(): (u64, u64) + local l0: u64 + local l1: u64 + call one + pop + call one + call one + ret + +// Function definition at index 2 +#[persistent] public fun test2(): (u64, u64) + local l0: u64 + local l1: u64 + call one + call one + pop + call one + ret + +// Function definition at index 3 +#[persistent] public fun test3(): (u64, u64) + local l0: u64 + local l1: u64 + call one + st_loc l0 + call one + pop + call one + // @5 + move_loc l0 + ret -one(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test1(): u64 * u64 /* def_idx: 1 */ { -L0: z: u64 -L1: y: u64 -B0: - 0: Call one(): u64 - 1: Pop - 2: Call one(): u64 - 3: Call one(): u64 - 4: Ret -} -public test2(): u64 * u64 /* def_idx: 2 */ { -L0: z: u64 -L1: x: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Pop - 3: Call one(): u64 - 4: Ret -} -public test3(): u64 * u64 /* def_idx: 3 */ { -L0: x: u64 -L1: z: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](x: u64) - 2: Call one(): u64 - 3: Pop - 4: Call one(): u64 - 5: MoveLoc[0](x: u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.off.exp index 547278404c0..4429076dc52 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.off.exp @@ -1,42 +1,39 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar() + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(): (u64, u64) + local l0: u64 + local l1: u64 + local l2: bool + local l3: u64 + call one + call one + call one + st_loc l0 + ld_u64 0 + // @5 + eq + st_loc l2 + st_loc l3 + move_loc l2 + br_true l0 + // @10 + branch l1 +l0: call bar +l1: move_loc l3 + move_loc l0 + ret -bar() /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(): u64 * u64 /* def_idx: 2 */ { -L0: z: u64 -L1: y: u64 -L2: $t5: bool -L3: x: u64 -B0: - 0: Call one(): u64 - 1: Call one(): u64 - 2: Call one(): u64 - 3: StLoc[0](z: u64) - 4: LdU64(0) - 5: Eq - 6: StLoc[2]($t5: bool) - 7: StLoc[3](x: u64) - 8: MoveLoc[2]($t5: bool) - 9: BrTrue(11) -B1: - 10: Branch(12) -B2: - 11: Call bar() -B3: - 12: MoveLoc[3](x: u64) - 13: MoveLoc[0](z: u64) - 14: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.on.exp index b4b026ef9cb..6110d57ab1d 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_02.on.exp @@ -61,39 +61,36 @@ public fun m::test(): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar() + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun test(): (u64, u64) + local l0: u64 + local l1: u64 + call one + st_loc l0 + call one + call one + st_loc l1 + // @5 + ld_u64 0 + eq + br_true l0 + branch l1 +l0: call bar + // @10 +l1: move_loc l0 + move_loc l1 + ret -bar() /* def_idx: 0 */ { -B0: - 0: Ret -} -one(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Ret -} -public test(): u64 * u64 /* def_idx: 2 */ { -L0: x: u64 -L1: z: u64 -B0: - 0: Call one(): u64 - 1: StLoc[0](x: u64) - 2: Call one(): u64 - 3: Call one(): u64 - 4: StLoc[1](z: u64) - 5: LdU64(0) - 6: Eq - 7: BrTrue(9) -B1: - 8: Branch(10) -B2: - 9: Call bar() -B3: - 10: MoveLoc[0](x: u64) - 11: MoveLoc[1](z: u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.off.exp index feb98157b24..0ba25fc2942 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.off.exp @@ -1,55 +1,48 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar() + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ret + +// Function definition at index 2 +#[persistent] public fun test1() + local l0: u64 + local l1: u64 + local l2: u64 + call foo + st_loc l0 + st_loc l1 + ld_u64 0 + eq + // @5 + br_true l0 + branch l1 +l0: call bar +l1: move_loc l1 + ld_u64 0 + // @10 + eq + br_true l2 + branch l3 +l2: call bar +l3: move_loc l0 + // @15 + ld_u64 0 + eq + br_false l4 + call bar + ret + // @20 +l4: ret -bar() /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: Ret -} -public test1() /* def_idx: 2 */ { -L0: z: u64 -L1: y: u64 -L2: x: u64 -B0: - 0: Call foo(): u64 * u64 * u64 - 1: StLoc[0](z: u64) - 2: StLoc[1](y: u64) - 3: LdU64(0) - 4: Eq - 5: BrTrue(7) -B1: - 6: Branch(8) -B2: - 7: Call bar() -B3: - 8: MoveLoc[1](y: u64) - 9: LdU64(0) - 10: Eq - 11: BrTrue(13) -B4: - 12: Branch(14) -B5: - 13: Call bar() -B6: - 14: MoveLoc[0](z: u64) - 15: LdU64(0) - 16: Eq - 17: BrTrue(19) -B7: - 18: Branch(20) -B8: - 19: Call bar() -B9: - 20: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.on.exp index 136e992d5fd..7a46f7d3351 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/unused_flush_early_03.on.exp @@ -83,72 +83,63 @@ public fun m::test1() { # live vars: $t0, $t2 21: $t3 := ==($t2, $t0) # live vars: $t3 - 22: if ($t3) goto 25 else goto 23 + 22: if ($t3) goto 23 else goto 26 # live vars: - 23: label L11 + 23: label L6 # live vars: - 24: goto 27 + 24: m::bar() # live vars: - 25: label L6 + 25: return () # live vars: - 26: m::bar() + 26: label L8 # live vars: - 27: label L8 - # live vars: - 28: return () + 27: return () } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun bar() + ret + +// Function definition at index 1 +fun foo(): (u64, u64, u64) + ld_u64 1 + ld_u64 2 + ld_u64 3 + ret + +// Function definition at index 2 +#[persistent] public fun test1() + local l0: u64 + local l1: u64 + call foo + st_loc l0 + st_loc l1 + ld_u64 0 + eq + // @5 + br_true l0 + branch l1 +l0: call bar +l1: move_loc l1 + ld_u64 0 + // @10 + eq + br_true l2 + branch l3 +l2: call bar +l3: move_loc l0 + // @15 + ld_u64 0 + eq + br_false l4 + call bar + ret + // @20 +l4: ret -bar() /* def_idx: 0 */ { -B0: - 0: Ret -} -foo(): u64 * u64 * u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: LdU64(3) - 3: Ret -} -public test1() /* def_idx: 2 */ { -L0: z: u64 -L1: y: u64 -B0: - 0: Call foo(): u64 * u64 * u64 - 1: StLoc[0](z: u64) - 2: StLoc[1](y: u64) - 3: LdU64(0) - 4: Eq - 5: BrTrue(7) -B1: - 6: Branch(8) -B2: - 7: Call bar() -B3: - 8: MoveLoc[1](y: u64) - 9: LdU64(0) - 10: Eq - 11: BrTrue(13) -B4: - 12: Branch(14) -B5: - 13: Call bar() -B6: - 14: MoveLoc[0](z: u64) - 15: LdU64(0) - 16: Eq - 17: BrTrue(19) -B7: - 18: Branch(20) -B8: - 19: Call bar() -B9: - 20: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.off.exp b/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.off.exp index de7cdbbc58b..f781c37445f 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.off.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.off.exp @@ -1,19 +1,18 @@ ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64) + local l1: u64 + local l2: &mut u64 + mut_borrow_loc l0 + st_loc l2 + ld_u64 42 + move_loc l2 + write_ref + // @5 + ret -public test(x: u64) /* def_idx: 0 */ { -L1: $t2: u64 -L2: y: &mut u64 -B0: - 0: MutBorrowLoc[0](x: u64) - 1: StLoc[2](y: &mut u64) - 2: LdU64(42) - 3: MoveLoc[2](y: &mut u64) - 4: WriteRef - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.on.exp b/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.on.exp index 7edd8c0f0b3..fd7fd618397 100644 --- a/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.on.exp +++ b/third_party/move/move-compiler-v2/tests/flush-writes/write_ref_01.on.exp @@ -17,20 +17,19 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64) + local l1: u64 + local l2: &mut u64 + mut_borrow_loc l0 + st_loc l2 + ld_u64 42 + move_loc l2 + write_ref + // @5 + ret -public test(x: u64) /* def_idx: 0 */ { -L1: $t2: u64 -L2: y: &mut u64 -B0: - 0: MutBorrowLoc[0](x: u64) - 1: StLoc[2](y: &mut u64) - 2: LdU64(42) - 3: MoveLoc[2](y: &mut u64) - 4: WriteRef - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/folding/bad_type_argument_arity_const.exp b/third_party/move/move-compiler-v2/tests/folding/bad_type_argument_arity_const.exp index b7d6382330a..16b656351e7 100644 --- a/third_party/move/move-compiler-v2/tests/folding/bad_type_argument_arity_const.exp +++ b/third_party/move/move-compiler-v2/tests/folding/bad_type_argument_arity_const.exp @@ -20,7 +20,7 @@ error: Invalid type for constant 6 │ const S1: S = S { f: 0 }; │ --------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 0 were provided ┌─ tests/folding/bad_type_argument_arity_const.move:7:15 @@ -42,7 +42,7 @@ error: Invalid type for constant 7 │ const S2: S<> = S { f: 0 }; │ ----------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 2 were provided ┌─ tests/folding/bad_type_argument_arity_const.move:8:15 @@ -64,7 +64,7 @@ error: Invalid type for constant 8 │ const S3: S = S { f: 0 }; │ -------------------------^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: expected 1 type argument but 2 were provided ┌─ tests/folding/bad_type_argument_arity_const.move:9:17 @@ -87,4 +87,4 @@ error: Invalid type for constant 9 │ const S4: S> = S { f: S { f: 0 } }; │ ----------------------------^^^^^^^^^^^^^^^^^^^- │ │ - │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. diff --git a/third_party/move/move-compiler-v2/tests/folding/constant_folding_addresses.exp b/third_party/move/move-compiler-v2/tests/folding/constant_folding_addresses.exp index 846ddb075ab..9e0c18c458b 100644 --- a/third_party/move/move-compiler-v2/tests/folding/constant_folding_addresses.exp +++ b/third_party/move/move-compiler-v2/tests/folding/constant_folding_addresses.exp @@ -14,10 +14,10 @@ module 0x8675309::M { // -- Sourcified model before first bytecode pipeline module 0x8675309::M { fun const_addr(): address { - 0x1234 + @0x1234 } fun const_addr_let(): address { - let x = 0x1234; + let x = @0x1234; x } } diff --git a/third_party/move/move-compiler-v2/tests/folding/constants_blocks.exp b/third_party/move/move-compiler-v2/tests/folding/constants_blocks.exp index 407b7fe439c..18b27d58b65 100644 --- a/third_party/move/move-compiler-v2/tests/folding/constants_blocks.exp +++ b/third_party/move/move-compiler-v2/tests/folding/constants_blocks.exp @@ -60,7 +60,7 @@ error: Invalid type for constant 14 │ │ │ x + y; 15 │ │ │ }; │ ╰─│─────^ - │ ╰──────' Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ ╰──────' Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/folding/constants_blocks.move:16:25 diff --git a/third_party/move/move-compiler-v2/tests/folding/empty_tvectors.exp b/third_party/move/move-compiler-v2/tests/folding/empty_tvectors.exp index 20f8279dfd4..ce826bd7029 100644 --- a/third_party/move/move-compiler-v2/tests/folding/empty_tvectors.exp +++ b/third_party/move/move-compiler-v2/tests/folding/empty_tvectors.exp @@ -72,6 +72,9 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::bcs; + use std::string; + use std::vector; public entry fun init() { let _ = { let (v) = (vector[]); diff --git a/third_party/move/move-compiler-v2/tests/folding/empty_vectors.exp b/third_party/move/move-compiler-v2/tests/folding/empty_vectors.exp index 5c75e9b70b3..2b6b8d6ae6b 100644 --- a/third_party/move/move-compiler-v2/tests/folding/empty_vectors.exp +++ b/third_party/move/move-compiler-v2/tests/folding/empty_vectors.exp @@ -73,6 +73,7 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::vector; public entry fun init() { let _x = { let (v) = (vector[]); diff --git a/third_party/move/move-compiler-v2/tests/folding/empty_vectors2.exp b/third_party/move/move-compiler-v2/tests/folding/empty_vectors2.exp index d5f2e2198ef..bd2f6ff3385 100644 --- a/third_party/move/move-compiler-v2/tests/folding/empty_vectors2.exp +++ b/third_party/move/move-compiler-v2/tests/folding/empty_vectors2.exp @@ -73,6 +73,7 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::vector; public entry fun init() { let _x = { let (v) = (*0x1::vector::borrow>>(&vector[vector[]], 0)); diff --git a/third_party/move/move-compiler-v2/tests/folding/nonempty_tvectors.exp b/third_party/move/move-compiler-v2/tests/folding/nonempty_tvectors.exp index aa48a657178..16ee138d9a5 100644 --- a/third_party/move/move-compiler-v2/tests/folding/nonempty_tvectors.exp +++ b/third_party/move/move-compiler-v2/tests/folding/nonempty_tvectors.exp @@ -72,6 +72,9 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::bcs; + use std::string; + use std::vector; public entry fun init() { let _ = { let (v) = (vector[vector[3u8]]); diff --git a/third_party/move/move-compiler-v2/tests/folding/nonempty_vectors.exp b/third_party/move/move-compiler-v2/tests/folding/nonempty_vectors.exp index f38c1016dad..8eef94f5a80 100644 --- a/third_party/move/move-compiler-v2/tests/folding/nonempty_vectors.exp +++ b/third_party/move/move-compiler-v2/tests/folding/nonempty_vectors.exp @@ -73,6 +73,7 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::vector; public entry fun init() { let _x = { let (v) = (vector[vector[1u8]]); diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.exp new file mode 100644 index 00000000000..1b60998bba2 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.exp @@ -0,0 +1,67 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + private fun callee(a: u64,_b: u64): u64 { + { + let x: u64 = 1; + { + let y: u64 = Add(a, x); + y + } + } + } + private fun caller(): u64 { + { + let x: u64 = 1; + { + let y: u64 = 1; + m::callee(x, y) + } + } + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + fun callee(a: u64, _b: u64): u64 { + let x = 1; + let y = a + x; + y + } + fun caller(): u64 { + let x = 1; + let y = 1; + callee(x, y) + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + private fun callee(a: u64,_b: u64): u64 { + { + let y: u64 = Add(a, 1); + y + } + } + private fun caller(): u64 { + 2 + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun callee(l0: u64, l1: u64): u64 + move_loc l0 + ld_u64 1 + add + ret + +// Function definition at index 1 +fun caller(): u64 + ld_u64 2 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.move new file mode 100644 index 00000000000..8cacf30032e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/caller_callee_shadowing.move @@ -0,0 +1,13 @@ +module 0xc0ffee::m { + fun caller(): u64 { + let x = 1; + let y = 1; + callee(x, y) + } + + fun callee(a: u64, _b: u64): u64 { + let x = 1; + let y = a + x; + y + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.exp new file mode 100644 index 00000000000..546a81ff256 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.exp @@ -0,0 +1,57 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + private fun fib(n: u64): u64 { + if Lt(n, 2) { + n + } else { + Add(m::fib(Sub(n, 1)), m::fib(Sub(n, 2))) + } + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + fun fib(n: u64): u64 { + if (n < 2) n else fib(n - 1) + fib(n - 2) + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + private fun fib(n: u64): u64 { + if Lt(n, 2) { + n + } else { + Add(m::fib(Sub(n, 1)), m::fib(Sub(n, 2))) + } + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun fib(l0: u64): u64 + copy_loc l0 + ld_u64 2 + lt + br_false l0 + move_loc l0 + // @5 + ret +l0: copy_loc l0 + ld_u64 1 + sub + call fib + // @10 + move_loc l0 + ld_u64 2 + sub + call fib + add + // @15 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.move new file mode 100644 index 00000000000..b10d16a2a74 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/fib.move @@ -0,0 +1,9 @@ +module 0xc0ffee::m { + fun fib(n: u64): u64 { + if (n < 2) { + n + } else { + fib(n - 1) + fib(n - 2) + } + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.exp new file mode 100644 index 00000000000..8d3656de74c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.exp @@ -0,0 +1,87 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + public fun code(is_sell: bool): u64 { + if is_sell { + m::one() + } else { + m::two() + } + } + private fun one(): u64 { + 1 + } + private fun sum_codes(): u64 { + Add(m::code(true), m::code(false)) + } + private fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + public fun code(is_sell: bool): u64 { + if (is_sell) one() else two() + } + fun one(): u64 { + 1 + } + fun sum_codes(): u64 { + code(true) + code(false) + } + fun two(): u64 { + 2 + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + public fun code(is_sell: bool): u64 { + if is_sell { + 1 + } else { + 2 + } + } + private fun one(): u64 { + 1 + } + private fun sum_codes(): u64 { + 3 + } + private fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun code(l0: bool): u64 + move_loc l0 + br_false l0 + ld_u64 1 + ret +l0: ld_u64 2 + // @5 + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +fun sum_codes(): u64 + ld_u64 3 + ret + +// Function definition at index 3 +fun two(): u64 + ld_u64 2 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.move new file mode 100644 index 00000000000..8fa5e14da33 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/if_else_const_bool_after_inlining.move @@ -0,0 +1,21 @@ +module 0xc0ffee::m { + fun one(): u64 { + 1 + } + + fun two(): u64 { + 2 + } + + fun sum_codes(): u64 { + code(true) + code(false) + } + + public fun code(is_sell: bool): u64 { + if (is_sell) { + one() + } else { + two() + } + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.exp new file mode 100644 index 00000000000..1a45ad4d20c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.exp @@ -0,0 +1,66 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + private fun read(r: &u64): u64 { + Deref(r) + } + private fun read_then_write(r: &mut u64) { + { + let v: u64 = m::read(Freeze(false)(r)); + r = Add(v, 1); + Tuple() + } + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + fun read(r: &u64): u64 { + *r + } + fun read_then_write(r: &mut u64) { + let v = read(/*freeze*/r); + *r = v + 1; + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + private fun read(r: &u64): u64 { + Deref(r) + } + private fun read_then_write(r: &mut u64) { + { + let v: u64 = { + let (r: &u64): (&u64) = Tuple(Freeze(false)(r)); + Deref(r) + }; + r = Add(v, 1); + Tuple() + } + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun read(l0: &u64): u64 + move_loc l0 + read_ref + ret + +// Function definition at index 1 +fun read_then_write(l0: &mut u64) + copy_loc l0 + freeze_ref + read_ref + ld_u64 1 + add + // @5 + move_loc l0 + write_ref + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.move new file mode 100644 index 00000000000..28570e44e0f --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/mut_refs_freeze.move @@ -0,0 +1,10 @@ +module 0xc0ffee::m { + fun read(r: &u64): u64 { + *r + } + + fun read_then_write(r: &mut u64) { + let v = read(r); + *r = v + 1; + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.exp new file mode 100644 index 00000000000..dd6b2461305 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.exp @@ -0,0 +1,94 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + private fun inner(x: u64): u64 { + loop { + x: u64 = Add(x, 10); + break; + Tuple() + }; + x + } + private fun outer(x: u64): u64 { + loop { + m::inner(x); + x: u64 = Add(x, 1); + break; + Tuple() + }; + x + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + fun inner(x: u64): u64 { + loop { + x = x + 10; + break; + }; + x + } + fun outer(x: u64): u64 { + loop { + inner(x); + x = x + 1; + break; + }; + x + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + private fun inner(x: u64): u64 { + loop { + x: u64 = Add(x, 10); + break; + Tuple() + }; + x + } + private fun outer(x: u64): u64 { + loop { + { + let (x: u64): (u64) = Tuple(x); + loop { + x: u64 = Add(x, 10); + break; + Tuple() + }; + x + }; + x: u64 = Add(x, 1); + break; + Tuple() + }; + x + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun inner(l0: u64): u64 + move_loc l0 + ld_u64 10 + add + ret + +// Function definition at index 1 +fun outer(l0: u64): u64 + copy_loc l0 + ld_u64 10 + add + pop + move_loc l0 + // @5 + ld_u64 1 + add + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.move new file mode 100644 index 00000000000..fcd230790ac --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/nested_loop_labels.move @@ -0,0 +1,18 @@ +module 0xc0ffee::m { + fun outer(x: u64): u64 { + 'a: loop { + inner(x); + x = x + 1; + break 'a; + }; + x + } + + fun inner(x: u64): u64 { + 'a: loop { + x = x + 10; + break 'a; + }; + x + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.exp new file mode 100644 index 00000000000..7308d79fdb8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.exp @@ -0,0 +1,258 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::n { + public fun not_inlined(x: &mut u64) { + if Gt(Deref(x), 5) { + if Gt(Deref(x), 5) { + Tuple() + } else { + Abort(42) + }; + x = 42; + Tuple() + } else { + x = Add(Deref(x), 1); + Tuple() + } + } +} // end 0xc0ffee::n +module 0xc0ffee::m { + public fun compute(): u64 { + { + let x: u64 = 3; + n::not_inlined(Borrow(Mutable)(x)); + m::one(Borrow(Mutable)(x)); + Add(x, m::two()) + } + } + private fun one(x: &mut u64) { + if Gt(Deref(x), 5) { + if Gt(Deref(x), 5) { + Tuple() + } else { + Abort(42) + }; + x = 42; + Tuple() + } else { + x = Add(Deref(x), 43); + Tuple() + } + } + public fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::n { + public fun not_inlined(x: &mut u64) { + if (*x > 5) { + if (*x > 5) () else abort 42; + *x = 42; + } else { + *x = *x + 1; + } + } +} +module 0xc0ffee::m { + public fun compute(): u64 { + let x = 3; + 0xc0ffee::n::not_inlined(&mut x); + one(&mut x); + x + two() + } + fun one(x: &mut u64) { + if (*x > 5) { + if (*x > 5) () else abort 42; + *x = 42; + } else { + *x = *x + 43; + } + } + public fun two(): u64 { + 2 + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::n { + public fun not_inlined(x: &mut u64) { + if Gt(Deref(x), 5) { + if Gt(Deref(x), 5) { + Tuple() + } else { + Abort(42) + }; + x = 42; + Tuple() + } else { + x = Add(Deref(x), 1); + Tuple() + } + } +} // end 0xc0ffee::n +module 0xc0ffee::m { + public fun compute(): u64 { + { + let x: u64 = 3; + n::not_inlined(Borrow(Mutable)(x)); + { + let (x: &mut u64): (&mut u64) = Tuple(Borrow(Mutable)(x)); + if Gt(Deref(x), 5) { + if Gt(Deref(x), 5) { + Tuple() + } else { + Abort(42) + }; + x = 42; + Tuple() + } else { + x = Add(Deref(x), 43); + Tuple() + } + }; + Add(x, 2) + } + } + private fun one(x: &mut u64) { + if Gt(Deref(x), 5) { + if Gt(Deref(x), 5) { + Tuple() + } else { + Abort(42) + }; + x = 42; + Tuple() + } else { + x = Add(Deref(x), 43); + Tuple() + } + } + public fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::n +// Function definition at index 0 +#[persistent] public fun not_inlined(l0: &mut u64) + copy_loc l0 + read_ref + ld_u64 5 + gt + br_false l0 + // @5 + copy_loc l0 + read_ref + ld_u64 5 + gt + br_false l1 + // @10 + ld_u64 42 + move_loc l0 + write_ref + ret +l1: move_loc l0 + // @15 + pop + ld_u64 42 + abort +l0: copy_loc l0 + read_ref + // @20 + ld_u64 1 + add + move_loc l0 + write_ref + ret + +// Bytecode version v9 +module 0xc0ffee::m +use 0xc0ffee::n +// Function definition at index 0 +#[persistent] public fun compute(): u64 + local l0: u64 + local l1: &mut u64 + ld_u64 3 + st_loc l0 + mut_borrow_loc l0 + call n::not_inlined + mut_borrow_loc l0 + // @5 + st_loc l1 + copy_loc l1 + read_ref + ld_u64 5 + gt + // @10 + br_false l0 + copy_loc l1 + read_ref + ld_u64 5 + gt + // @15 + br_false l1 + ld_u64 42 + move_loc l1 + write_ref +l2: move_loc l0 + // @20 + ld_u64 2 + add + ret +l1: move_loc l1 + pop + // @25 + ld_u64 42 + abort +l0: copy_loc l1 + read_ref + ld_u64 43 + // @30 + add + move_loc l1 + write_ref + branch l2 + +// Function definition at index 1 +fun one(l0: &mut u64) + copy_loc l0 + read_ref + ld_u64 5 + gt + br_false l0 + // @5 + copy_loc l0 + read_ref + ld_u64 5 + gt + br_false l1 + // @10 + ld_u64 42 + move_loc l0 + write_ref + ret +l1: move_loc l0 + // @15 + pop + ld_u64 42 + abort +l0: copy_loc l0 + read_ref + // @20 + ld_u64 43 + add + move_loc l0 + write_ref + ret + +// Function definition at index 2 +#[persistent] public fun two(): u64 + ld_u64 2 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.move new file mode 100644 index 00000000000..5037df37b46 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/test_abort.move @@ -0,0 +1,42 @@ +module 0xc0ffee::n { + const ERROR_CODE_2: u64 = 42; + + // not inlined in m + public fun not_inlined(x: &mut u64) { + if (* x > 5) { + assert!(*x > 5, ERROR_CODE_2); + *x = 42; + } else { + *x = *x + 1; + } + } +} + + +module 0xc0ffee::m { + const ERROR_CODE: u64 = 42; + const N_ERROR_CODE_2: u64 = 43; + + fun one(x: &mut u64) { + if (* x > 5) { + assert!(*x > 5, ERROR_CODE); + *x = 42; + } else { + *x = *x + N_ERROR_CODE_2; + } + } + + public fun two(): u64 { + 2 + } + + public fun compute(): u64 { + use 0xc0ffee::n; + let x = 3; + // not inlined + n::not_inlined(&mut x); + // inlined + one(&mut x); + x + two() + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.exp new file mode 100644 index 00000000000..1af1a24b6c0 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.exp @@ -0,0 +1,38 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + public fun infinite() { + m::infinite(); + m::infinite(); + Tuple() + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + public fun infinite() { + infinite(); + infinite(); + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + public fun infinite() { + m::infinite(); + m::infinite(); + Tuple() + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun infinite() + call infinite + call infinite + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.move new file mode 100644 index 00000000000..57e71db007d --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/unbounded_recursion.move @@ -0,0 +1,6 @@ +module 0xc0ffee::m { + public fun infinite() { + infinite(); + infinite(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.exp new file mode 100644 index 00000000000..99f8d66719b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.exp @@ -0,0 +1,112 @@ +// -- Model dump before first bytecode pipeline +module 0x42::test { + struct T { + x: A, + y: B, + } + struct S { + 0: A, + 1: B, + 2: C, + } + private fun proj_0(self: S): A { + { + let test::S{ 0: x, 1: _, 2: _ } = self; + x + } + } + private fun test_proj_0(): u8 { + { + let x: S = pack test::S(42, 0x1, true); + test::proj_0(x) + } + } +} // end 0x42::test + +// -- Sourcified model before first bytecode pipeline +module 0x42::test { + struct T has drop { + x: A, + y: B, + } + struct S has drop { + 0: A, + 1: B, + 2: C, + } + fun proj_0(self: S): A { + let S(x, _, _) = self; + x + } + fun test_proj_0(): u8 { + let x = S(42u8, @0x1, true); + proj_0(x) + } +} + +// -- Model dump before second bytecode pipeline +module 0x42::test { + struct T { + x: A, + y: B, + } + struct S { + 0: A, + 1: B, + 2: C, + } + private fun proj_0(self: S): A { + { + let test::S{ 0: x, 1: _, 2: _ } = self; + x + } + } + private fun test_proj_0(): u8 { + { + let x: S = pack test::S(42, 0x1, true); + { + let (self: S): (S) = Tuple(x); + { + let test::S{ 0: x, 1: _, 2: _ } = self; + x + } + } + } + } +} // end 0x42::test + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::test +struct T has drop + x: T0 + y: T1 + +struct S has drop + _0: T0 + _1: T1 + _2: T2 + +// Function definition at index 0 +fun proj_0(l0: S): T0 + move_loc l0 + unpack S + pop + pop + ret + +// Function definition at index 1 +fun test_proj_0(): u8 + ld_u8 42 + ld_const
1 + ld_true + pack S + unpack S + // @5 + pop + pop + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.move new file mode 100644 index 00000000000..9aa09980e34 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/wildcard.move @@ -0,0 +1,18 @@ +module 0x42::test { + struct S(A, B, C) has drop; + + struct T has drop { + x: A, + y: B + } + + fun proj_0(self: S): A { + let S(x, ..) = self; + x + } + + fun test_proj_0(): u8 { + let x = S(42, @0x1, true); + x.proj_0() + } +} diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.exp b/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.exp new file mode 100644 index 00000000000..1b69c0c8f99 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.exp @@ -0,0 +1,60 @@ +// -- Model dump before first bytecode pipeline +module 0xc0ffee::m { + public fun compute(): u64 { + Add(m::one(), m::two()) + } + private fun one(): u64 { + 1 + } + public fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + +// -- Sourcified model before first bytecode pipeline +module 0xc0ffee::m { + public fun compute(): u64 { + one() + two() + } + fun one(): u64 { + 1 + } + public fun two(): u64 { + 2 + } +} + +// -- Model dump before second bytecode pipeline +module 0xc0ffee::m { + public fun compute(): u64 { + 3 + } + private fun one(): u64 { + 1 + } + public fun two(): u64 { + 2 + } +} // end 0xc0ffee::m + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun compute(): u64 + ld_u64 3 + ret + +// Function definition at index 1 +fun one(): u64 + ld_u64 1 + ret + +// Function definition at index 2 +#[persistent] public fun two(): u64 + ld_u64 2 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.move b/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.move new file mode 100644 index 00000000000..8f03aec8839 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/inlining-optimization/within_module_simple.move @@ -0,0 +1,13 @@ +module 0xc0ffee::m { + fun one(): u64 { + 1 + } + + public fun two(): u64 { + 2 + } + + public fun compute(): u64 { + one() + two() + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.exp b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.exp new file mode 100644 index 00000000000..6fe06d76832 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.exp @@ -0,0 +1,97 @@ + +Diagnostics: +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:4:22 + │ +4 │ const V3_64: i64 = 9223372036854775808i64; // out of upper bound: max value of i64 is 9223372036854775807 + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:6:22 + │ +6 │ const V5_64: i64 = -9223372036854775809i64; // out of lower bound: min value of i64 is -9223372036854775808 + │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:10:24 + │ +10 │ const V3_128: i128 = 170141183460469231731687303715884105728i128; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:12:24 + │ +12 │ const V5_128: i128 = -170141183460469231731687303715884105729i128; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:17:13 + │ +17 │ let c = 9223372036854775808i64; // constant does not fit into i64 && type mismatch in `res7 + c`, expected u64|u128|u256|i128, actual i64 + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:19:13 + │ +19 │ let e = -9223372036854775809i64; // constant does not fit into i64 && type mismatch in `res9 + e`, expected i128, actual i64 + │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:35:13 + │ +35 │ let c = 170141183460469231731687303715884105728i128; // type mismatch in `res7 + c`, expected u128|u256, actual i128 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:37:13 + │ +37 │ let e = -170141183460469231731687303715884105729i128; // constant does not fit into i128 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:55:22 + │ +55 │ const V3_64: i64 = 9223372036854775808i64; // out of upper bound: max value of i64 is 9223372036854775807 + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:57:22 + │ +57 │ const V5_64: i64 = -9223372036854775809i64; // out of lower bound: min value of i64 is -9223372036854775808 + │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:61:24 + │ +61 │ const V3_128: i128 = 170141183460469231731687303715884105728i128; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:63:24 + │ +63 │ const V5_128: i128 = -170141183460469231731687303715884105729i128; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:68:13 + │ +68 │ let c = 9223372036854775808i64; // constant does not fit into i64 && type mismatch in `res7 + c`, expected u64|u128|u256|i128, actual i64 + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:70:13 + │ +70 │ let e = -9223372036854775809i64; // constant does not fit into i64 && type mismatch in `res9 + e`, expected i128, actual i64 + │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i64' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:86:13 + │ +86 │ let c = 170141183460469231731687303715884105728i128; // type mismatch in `res7 + c`, expected u128|u256, actual i128 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' + +error: invalid number literal + ┌─ tests/integers/signed/invalid_constants.move:88:13 + │ +88 │ let e = -170141183460469231731687303715884105729i128; // constant does not fit into i128 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'i128' diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.move b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.move new file mode 100644 index 00000000000..ec8a607b344 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_constants.move @@ -0,0 +1,101 @@ +module 0x42::invalid_constants1 { + const V1_64: i64 = 1u64; // type mismatch: expected i64, actual u64 + const V2_64: i64 = 9223372036854775808; // out of upper bound: max value of i64 is 9223372036854775807 + const V3_64: i64 = 9223372036854775808i64; // out of upper bound: max value of i64 is 9223372036854775807 + const V4_64: i64 = -9223372036854775809; // out of lower bound: min value of i64 is -9223372036854775808 + const V5_64: i64 = -9223372036854775809i64; // out of lower bound: min value of i64 is -9223372036854775808 + const V6_64: i64 = -1i128; // type mismatch: expected i64, actual i128 + const V1_128: i128 = 1u128; // type mismatch: expected i128, actual u128 + const V2_128: i128 = 170141183460469231731687303715884105728; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + const V3_128: i128 = 170141183460469231731687303715884105728i128; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + const V4_128: i128 = -170141183460469231731687303715884105729; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + const V5_128: i128 = -170141183460469231731687303715884105729i128; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + const V6_128: i128 = -1i64; // type mismatch: expected i128, actual i64 + public fun test_i64() : i64 { + let a = 1u64; // type mismatch in `res5 + a`: expected i64, actual u64 + let b = 9223372036854775808; // interpreted as a possible u64|u128|u256|i128 + let c = 9223372036854775808i64; // constant does not fit into i64 && type mismatch in `res7 + c`, expected u64|u128|u256|i128, actual i64 + let d = -9223372036854775809; // interpreted as an i128 + let e = -9223372036854775809i64; // constant does not fit into i64 && type mismatch in `res9 + e`, expected i128, actual i64 + let res1 = V1_64 + V2_64; + let res2 = res1 + V3_64; + let res3 = res2 + V4_64; + let res4 = res3 + V5_64; + let res5 = res4 + V6_64; + let res6 = res5 + a; + let res7 = res6 + b; + let res8 = res7 + c; + let res9 = res8 + d; + let res10 = res9 + e; + res10 + } + public fun test_i128() : i128 { + let a = 1u128; // type mismatch in `res5 + a`: expected i128, actual u128 + let b = 170141183460469231731687303715884105728; // interpreted as a possible u128|u256 + let c = 170141183460469231731687303715884105728i128; // type mismatch in `res7 + c`, expected u128|u256, actual i128 + let d = -170141183460469231731687303715884105729; // no type can be inffered + let e = -170141183460469231731687303715884105729i128; // constant does not fit into i128 + let res1 = V1_128 + V2_128; + let res2 = res1 + V3_128; + let res3 = res2 + V4_128; + let res4 = res3 + V5_128; + let res5 = res4 + V6_128; + let res6 = res5 + a; + let res7 = res6 + b; + let res8 = res7 + c; + let res9 = res8 + d; + let res10 = res9 + e; + res10 + } +} + +module 0x42::invalid_constants2 { + const V1_64: i64 = 1u64; // type mismatch: expected i64, actual u64 + const V2_64: i64 = 9223372036854775808; // out of upper bound: max value of i64 is 9223372036854775807 + const V3_64: i64 = 9223372036854775808i64; // out of upper bound: max value of i64 is 9223372036854775807 + const V4_64: i64 = -9223372036854775809; // out of lower bound: min value of i64 is -9223372036854775808 + const V5_64: i64 = -9223372036854775809i64; // out of lower bound: min value of i64 is -9223372036854775808 + const V6_64: i64 = -1i128; // type mismatch: expected i64, actual i128 + const V1_128: i128 = 1u128; // type mismatch: expected i128, actual u128 + const V2_128: i128 = 170141183460469231731687303715884105728; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + const V3_128: i128 = 170141183460469231731687303715884105728i128; // out of upper bound: max value of i128 is 170141183460469231731687303715884105727 + const V4_128: i128 = -170141183460469231731687303715884105729; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + const V5_128: i128 = -170141183460469231731687303715884105729i128; // out of lower bound: min value of i64 is -170141183460469231731687303715884105728 + const V6_128: i128 = -1i64; // type mismatch: expected i128, actual i64 + public fun test_i64() : i64 { + let a = 1u64; // type mismatch in `res5 + a`: expected i64, actual u64 + let b = 9223372036854775808; // interpreted as a possible u64|u128|u256|i128 + let c = 9223372036854775808i64; // constant does not fit into i64 && type mismatch in `res7 + c`, expected u64|u128|u256|i128, actual i64 + let d = -9223372036854775809; // interpreted as an i128 + let e = -9223372036854775809i64; // constant does not fit into i64 && type mismatch in `res9 + e`, expected i128, actual i64 + let res1 = V1_64 + V2_64; + let res2 = res1 + V3_64; + let res3 = res2 + V4_64; + let res4 = res3 + V5_64; + let res5 = res4 + V6_64; + let res6 = res5 + a; + let res7 = res6 + b; + let res8 = res7 + c; + let res9 = res8 + d; + let res10 = res9 + e; + res10 + } + public fun test_i128() : i128 { + let a = 1u128; // type mismatch in `res5 + a`: expected i128, actual u128 + let b = 170141183460469231731687303715884105728; // interpreted as a possible u128|u256 + let c = 170141183460469231731687303715884105728i128; // type mismatch in `res7 + c`, expected u128|u256, actual i128 + let d = -170141183460469231731687303715884105729; // no type can be inffered + let e = -170141183460469231731687303715884105729i128; // constant does not fit into i128 + let res1 = V1_128 + V2_128; + let res2 = res1 + V3_128; + let res3 = res2 + V4_128; + let res4 = res3 + V5_128; + let res5 = res4 + V6_128; + let res6 = res5 + a; + let res7 = res6 + b; + let res8 = res7 + c; + let res9 = res8 + d; + let res10 = res9 + e; + res10 + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.exp b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.exp new file mode 100644 index 00000000000..fa996fb4abb --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.exp @@ -0,0 +1,73 @@ + +Diagnostics: +error: cannot use `&i64` with an operator which expects a value of type `integer` + ┌─ tests/integers/signed/invalid_ops.move:3:9 + │ +3 │ &x + &x + │ ^^ + +error: cannot use `&i128` with an operator which expects a value of type `integer` + ┌─ tests/integers/signed/invalid_ops.move:6:9 + │ +6 │ &x + &x + │ ^^ + +error: cannot use `i128` with an operator which expects a value of type `i64` + ┌─ tests/integers/signed/invalid_ops.move:9:13 + │ +9 │ x + y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `i64` + ┌─ tests/integers/signed/invalid_ops.move:12:13 + │ +12 │ x + y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `i64` + ┌─ tests/integers/signed/invalid_ops.move:15:13 + │ +15 │ x + y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `i64` + ┌─ tests/integers/signed/invalid_ops.move:18:13 + │ +18 │ x + y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:21:9 + │ +21 │ x && y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:24:9 + │ +24 │ x && y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:27:9 + │ +27 │ x || y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:30:9 + │ +30 │ x || y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:33:10 + │ +33 │ !x + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `bool` + ┌─ tests/integers/signed/invalid_ops.move:36:10 + │ +36 │ !x + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.move b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.move new file mode 100644 index 00000000000..b4952e43eff --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_ops.move @@ -0,0 +1,38 @@ +module 0x42::invalid_arithmetic { + fun test_add_by_ref1(x: i64): i64 { + &x + &x + } + fun test_add_by_ref2(x: i128): i128 { + &x + &x + } + fun test_add_by_mix1(x: i64, y: i128): i64 { + x + y + } + fun test_add_by_mix2(x: i64, y: i128): i128 { + x + y + } + fun test_add_by_mix3(x: i64, y: i128): i64 { + x + y + } + fun test_add_by_mix4(x: i64, y: i128): i128 { + x + y + } + fun test_logic_and1(x: i64, y: i64): bool { + x && y + } + fun test_logic_and2(x: i128, y: i128): bool { + x && y + } + fun test_logic_or1(x: i64, y: i64): bool { + x || y + } + fun test_logic_or2(x: i128, y: i128): bool { + x || y + } + fun test_logic_not1(x: i64): bool { + !x + } + fun test_logic_not(x: i128): bool { + !x + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.exp b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.exp new file mode 100644 index 00000000000..4bce00bfde3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.exp @@ -0,0 +1,129 @@ + +Diagnostics: +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:4:20 + │ +4 │ if (exists(addr)) { + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `exists` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:12:20 + │ +12 │ if (exists(addr)) { + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `exists` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:20:20 + │ +20 │ if (exists(addr)) { + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `exists` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:28:20 + │ +28 │ if (exists(addr)) { + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `exists` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:36:31 + │ +36 │ let s = borrow_global(addr); + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `borrow_global` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:41:31 + │ +41 │ let s = borrow_global(addr); + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `borrow_global` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:46:31 + │ +46 │ let s = borrow_global(addr); + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `borrow_global` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:51:31 + │ +51 │ let s = borrow_global(addr); + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `borrow_global` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:56:16 + │ +56 │ move_to(account, x) + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `move_to` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:60:16 + │ +60 │ move_to(account, x) + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `move_to` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:64:16 + │ +64 │ move_to(account, x) + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `move_to` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:68:16 + │ +68 │ move_to(account, x) + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `move_to` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:72:19 + │ +72 │ move_from(signer::address_of(account)) + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `move_from` + +error: type `i64` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:76:19 + │ +76 │ move_from(signer::address_of(account)) + │ ^^^ + │ + = required by instantiating type parameter `T:key` of function `move_from` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:80:19 + │ +80 │ move_from(signer::address_of(account)) + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `move_from` + +error: type `i128` is missing required ability `key` + ┌─ tests/integers/signed/invalid_resource.move:84:19 + │ +84 │ move_from(signer::address_of(account)) + │ ^^^^ + │ + = required by instantiating type parameter `T:key` of function `move_from` diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.move b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.move new file mode 100644 index 00000000000..78279ac6e22 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/invalid_resource.move @@ -0,0 +1,86 @@ +module 0x42::invalid_resource { + use std::signer; + fun test_exist1(addr: address): i64 { + if (exists(addr)) { + 1 + } else { + 2 + } + } + + fun test_exist2(addr: address): i64 { + if (exists(addr)) { + 1 + } else { + 2 + } + } + + fun test_exist3(addr: address): i128 { + if (exists(addr)) { + 1 + } else { + 2 + } + } + + fun test_exist4(addr: address): i128 { + if (exists(addr)) { + 1 + } else { + 2 + } + } + + fun test_borrow1(addr: address): i64 { + let s = borrow_global(addr); + *s + } + + fun test_borrow2(addr: address): i64 { + let s = borrow_global(addr); + *s + } + + fun test_borrow3(addr: address): i128 { + let s = borrow_global(addr); + *s + } + + fun test_borrow4(addr: address): i128 { + let s = borrow_global(addr); + *s + } + + fun test_move_to1(account: &signer, x: i64) { + move_to(account, x) + } + + fun test_move_to2(account: &signer, x: i64) { + move_to(account, x) + } + + fun test_move_to3(account: &signer, x: i128) { + move_to(account, x) + } + + fun test_move_to4(account: &signer, x: i128) { + move_to(account, x) + } + + fun test_move_from1(account: &signer): i64 { + move_from(signer::address_of(account)) + } + + fun test_move_from2(account: &signer): i64 { + move_from(signer::address_of(account)) + } + + fun test_move_from3(account: &signer): i128 { + move_from(signer::address_of(account)) + } + + fun test_move_from4(account: &signer): i128 { + move_from(signer::address_of(account)) + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.exp b/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.exp new file mode 100644 index 00000000000..d0ed4e56525 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.exp @@ -0,0 +1,181 @@ + +Diagnostics: +error: cannot use `i8` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:4:9 + │ +4 │ x | y + │ ^ + +error: cannot use `i16` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:8:9 + │ +8 │ x | y + │ ^ + +error: cannot use `i32` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:12:9 + │ +12 │ x | y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:16:9 + │ +16 │ x | y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:20:9 + │ +20 │ x | y + │ ^ + +error: cannot use `i256` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:24:9 + │ +24 │ x | y + │ ^ + +error: cannot use `i8` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:28:9 + │ +28 │ x & y + │ ^ + +error: cannot use `i16` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:32:9 + │ +32 │ x & y + │ ^ + +error: cannot use `i32` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:36:9 + │ +36 │ x & y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:40:9 + │ +40 │ x & y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:44:9 + │ +44 │ x & y + │ ^ + +error: cannot use `i256` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:48:9 + │ +48 │ x & y + │ ^ + +error: cannot use `i8` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:52:9 + │ +52 │ x ^ y + │ ^ + +error: cannot use `i16` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:56:9 + │ +56 │ x ^ y + │ ^ + +error: cannot use `i32` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:60:9 + │ +60 │ x ^ y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:64:9 + │ +64 │ x ^ y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:68:9 + │ +68 │ x ^ y + │ ^ + +error: cannot use `i256` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:72:9 + │ +72 │ x ^ y + │ ^ + +error: cannot use `i8` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:76:9 + │ +76 │ x << y + │ ^ + +error: cannot use `i16` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:80:9 + │ +80 │ x << y + │ ^ + +error: cannot use `i32` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:84:9 + │ +84 │ x << y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:88:9 + │ +88 │ x << y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:92:9 + │ +92 │ x << y + │ ^ + +error: cannot use `i256` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:96:9 + │ +96 │ x << y + │ ^ + +error: cannot use `i8` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:100:9 + │ +100 │ x >> y + │ ^ + +error: cannot use `i16` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:104:9 + │ +104 │ x >> y + │ ^ + +error: cannot use `i32` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:108:9 + │ +108 │ x >> y + │ ^ + +error: cannot use `i64` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:112:9 + │ +112 │ x >> y + │ ^ + +error: cannot use `i128` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:116:9 + │ +116 │ x >> y + │ ^ + +error: cannot use `i256` with an operator which expects a value of type `u8|u16|u32|u64|u128|u256` + ┌─ tests/integers/signed/non_supported_ops.move:120:9 + │ +120 │ x >> y + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.move b/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.move new file mode 100644 index 00000000000..75469193c67 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/non_supported_ops.move @@ -0,0 +1,122 @@ +module 0x42::not_supported_ops { + + fun test_or1(x: i8, y: i8): i8 { + x | y + } + + fun test_or2(x: i16, y: i16): i16 { + x | y + } + + fun test_or3(x: i32, y: i32): i32 { + x | y + } + + fun test_or4(x: i64, y: i64): i64 { + x | y + } + + fun test_or5(x: i128, y: i128): i128 { + x | y + } + + fun test_or6(x: i256, y: i256): i256 { + x | y + } + + fun test_and1(x: i8, y: i8): i64 { + x & y + } + + fun test_and2(x: i16, y: i16): i128 { + x & y + } + + fun test_and3(x: i32, y: i32): i64 { + x & y + } + + fun test_and4(x: i64, y: i64): i128 { + x & y + } + + fun test_and5(x: i128, y: i128): i64 { + x & y + } + + fun test_and6(x: i256, y: i128): i128 { + x & y + } + + fun test_xor1(x: i8, y: i8): i8 { + x ^ y + } + + fun test_xor2(x: i16, y: i16): i16 { + x ^ y + } + + fun test_xor3(x: i32, y: i32): i32 { + x ^ y + } + + fun test_xor4(x: i64, y: i64): i64 { + x ^ y + } + + fun test_xor5(x: i128, y: i128): i128 { + x ^ y + } + + fun test_xor6(x: i256, y: i256): i256 { + x ^ y + } + + fun test_lsf1(x: i8, y: u8): i64 { + x << y + } + + fun test_lsf2(x: i16, y: u8): i128 { + x << y + } + + fun test_lsf3(x: i32, y: u8): i64 { + x << y + } + + fun test_lsf4(x: i64, y: u8): i128 { + x << y + } + + fun test_lsf5(x: i128, y: u8): i64 { + x << y + } + + fun test_lsf6(x: i256, y: u8): i128 { + x << y + } + + fun test_rsf1(x: i8, y: u8): i64 { + x >> y + } + + fun test_rsf2(x: i16, y: u8): i128 { + x >> y + } + + fun test_rsf3(x: i32, y: u8): i64 { + x >> y + } + + fun test_rsf4(x: i64, y: u8): i128 { + x >> y + } + + fun test_rsf5(x: i128, y: u8): i64 { + x >> y + } + + fun test_rsf6(x: i256, y: u8): i128 { + x >> y + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.exp new file mode 100644 index 00000000000..441231544ff --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.exp @@ -0,0 +1,4615 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_arithmetic { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test_add1(x: i64): i64 { + Add(x, x) + } + private fun test_add2(x: i128): i128 { + Add(x, x) + } + private fun test_add3(s1: S1,s2: S2,s3: S3): i64 { + Add(Add(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_add4(s1: S1,s2: S2,s3: S3): i128 { + Add(Add(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_div1(x: i64,y: i64): i64 { + Div(x, y) + } + private fun test_div2(x: i128,y: i128): i128 { + Div(x, y) + } + private fun test_div3(s1: S1,s2: S2,s3: S3): i64 { + Div(Div(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_div4(s1: S1,s2: S2,s3: S3): i128 { + Div(Div(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mix1(x: i64,y: i64,z: i64): i64 { + Mod(Div(Mul(Sub(Add(x, y), z), x), y), z) + } + private fun test_mix2(x: i128,y: i128,z: i128): i128 { + Mod(Div(Mul(Sub(Add(x, y), z), x), y), z) + } + private fun test_mix3(s1: S1,s2: S2,s3: S3): i64 { + Mod(Div(Mul(Sub(Add(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)), select valid_arithmetic::S1.y(s1)), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mix4(s1: S1,s2: S2,s3: S3): i128 { + Mod(Div(Mul(Sub(Add(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)), select valid_arithmetic::S1.z(s1)), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mod1(x: i64,y: i64): i64 { + Mod(x, y) + } + private fun test_mod2(x: i128,y: i128): i128 { + Mod(x, y) + } + private fun test_mod3(s1: S1,s2: S2,s3: S3): i64 { + Mod(Mod(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mod4(s1: S1,s2: S2,s3: S3): i128 { + Mod(Mod(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mul1(x: i64,y: i64): i64 { + Mul(x, y) + } + private fun test_mul2(x: i128,y: i128): i128 { + Mul(x, y) + } + private fun test_mul3(s1: S1,s2: S2,s3: S3): i64 { + Mul(Mul(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mul4(s1: S1,s2: S2,s3: S3): i128 { + Mul(Mul(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_neg1(x: i64,y: i64): i64 { + Sub(Add(Negate(x), y), Mod(Div(Mul(Negate(x), Negate(y)), Negate(x)), Negate(y))) + } + private fun test_neg2(x: i128,y: i128): i128 { + Sub(Add(Negate(x), y), Mod(Div(Mul(Negate(x), Negate(y)), Negate(x)), Negate(y))) + } + private fun test_sub1(x: i64,y: i64): i64 { + Sub(x, y) + } + private fun test_sub2(x: i128,y: i128): i128 { + Sub(x, y) + } + private fun test_sub3(s1: S1,s2: S2,s3: S3): i64 { + Sub(Sub(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_sub4(s1: S1,s2: S2,s3: S3): i128 { + Sub(Sub(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } +} // end 0x42::valid_arithmetic + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_arithmetic { + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test_add1(x: i64): i64 { + x + x + } + fun test_add2(x: i128): i128 { + x + x + } + fun test_add3(s1: S1, s2: S2, s3: S3): i64 { + s1.y + s2.y + s3.x + } + fun test_add4(s1: S1, s2: S2, s3: S3): i128 { + s1.z + s2.z + s3.x + } + fun test_div1(x: i64, y: i64): i64 { + x / y + } + fun test_div2(x: i128, y: i128): i128 { + x / y + } + fun test_div3(s1: S1, s2: S2, s3: S3): i64 { + s1.y / s2.y / s3.x + } + fun test_div4(s1: S1, s2: S2, s3: S3): i128 { + s1.z / s2.z / s3.x + } + fun test_mix1(x: i64, y: i64, z: i64): i64 { + (x + y - z) * x / y % z + } + fun test_mix2(x: i128, y: i128, z: i128): i128 { + (x + y - z) * x / y % z + } + fun test_mix3(s1: S1, s2: S2, s3: S3): i64 { + (s1.y + s2.y - s3.x) * s1.y / s2.y % s3.x + } + fun test_mix4(s1: S1, s2: S2, s3: S3): i128 { + (s1.z + s2.z - s3.x) * s1.z / s2.z % s3.x + } + fun test_mod1(x: i64, y: i64): i64 { + x % y + } + fun test_mod2(x: i128, y: i128): i128 { + x % y + } + fun test_mod3(s1: S1, s2: S2, s3: S3): i64 { + s1.y % s2.y % s3.x + } + fun test_mod4(s1: S1, s2: S2, s3: S3): i128 { + s1.z % s2.z % s3.x + } + fun test_mul1(x: i64, y: i64): i64 { + x * y + } + fun test_mul2(x: i128, y: i128): i128 { + x * y + } + fun test_mul3(s1: S1, s2: S2, s3: S3): i64 { + s1.y * s2.y * s3.x + } + fun test_mul4(s1: S1, s2: S2, s3: S3): i128 { + s1.z * s2.z * s3.x + } + fun test_neg1(x: i64, y: i64): i64 { + -x + y - -x * -y / -x % -y + } + fun test_neg2(x: i128, y: i128): i128 { + -x + y - -x * -y / -x % -y + } + fun test_sub1(x: i64, y: i64): i64 { + x - y + } + fun test_sub2(x: i128, y: i128): i128 { + x - y + } + fun test_sub3(s1: S1, s2: S2, s3: S3): i64 { + s1.y - s2.y - s3.x + } + fun test_sub4(s1: S1, s2: S2, s3: S3): i128 { + s1.z - s2.z - s3.x + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_arithmetic::test_add1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := +($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := +($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_add4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := +($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := +($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := /($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := /($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := /($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := /($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := /($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := /($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix1($t0: i64, $t1: i64, $t2: i64): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + 0: $t8 := infer($t0) + 1: $t7 := +($t8, $t1) + 2: $t6 := -($t7, $t2) + 3: $t5 := *($t6, $t0) + 4: $t4 := /($t5, $t1) + 5: $t3 := %($t4, $t2) + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix2($t0: i128, $t1: i128, $t2: i128): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + 0: $t8 := infer($t0) + 1: $t7 := +($t8, $t1) + 2: $t6 := -($t7, $t2) + 3: $t5 := *($t6, $t0) + 4: $t4 := /($t5, $t1) + 5: $t3 := %($t4, $t2) + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i64 + var $t14: i64 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i64 + var $t17: i64 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i64 + var $t20: i64 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i64 + var $t23: i64 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i64 + 0: $t9 := borrow_local($t0) + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.y($t9) + 2: $t8 := read_ref($t10) + 3: $t12 := borrow_local($t1) + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.y($t12) + 5: $t11 := read_ref($t13) + 6: $t7 := +($t8, $t11) + 7: $t15 := borrow_local($t2) + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + 9: $t14 := read_ref($t16) + 10: $t6 := -($t7, $t14) + 11: $t18 := borrow_local($t0) + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.y($t18) + 13: $t17 := read_ref($t19) + 14: $t5 := *($t6, $t17) + 15: $t21 := borrow_local($t1) + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.y($t21) + 17: $t20 := read_ref($t22) + 18: $t4 := /($t5, $t20) + 19: $t24 := borrow_local($t2) + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + 21: $t23 := read_ref($t25) + 22: $t3 := %($t4, $t23) + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i128 + var $t14: i128 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i128 + var $t17: i128 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i128 + var $t20: i128 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i128 + var $t23: i128 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i128 + 0: $t9 := borrow_local($t0) + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.z($t9) + 2: $t8 := read_ref($t10) + 3: $t12 := borrow_local($t1) + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.z($t12) + 5: $t11 := read_ref($t13) + 6: $t7 := +($t8, $t11) + 7: $t15 := borrow_local($t2) + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + 9: $t14 := read_ref($t16) + 10: $t6 := -($t7, $t14) + 11: $t18 := borrow_local($t0) + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.z($t18) + 13: $t17 := read_ref($t19) + 14: $t5 := *($t6, $t17) + 15: $t21 := borrow_local($t1) + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.z($t21) + 17: $t20 := read_ref($t22) + 18: $t4 := /($t5, $t20) + 19: $t24 := borrow_local($t2) + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + 21: $t23 := read_ref($t25) + 22: $t3 := %($t4, $t23) + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := %($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := %($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := %($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := %($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := %($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := %($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := *($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := *($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := *($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := *($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := *($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := *($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_neg1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + 0: $t4 := -($t0) + 1: $t3 := +($t4, $t1) + 2: $t8 := -($t0) + 3: $t9 := -($t1) + 4: $t7 := *($t8, $t9) + 5: $t10 := -($t0) + 6: $t6 := /($t7, $t10) + 7: $t11 := -($t1) + 8: $t5 := %($t6, $t11) + 9: $t2 := -($t3, $t5) + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_neg2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + 0: $t4 := -($t0) + 1: $t3 := +($t4, $t1) + 2: $t8 := -($t0) + 3: $t9 := -($t1) + 4: $t7 := *($t8, $t9) + 5: $t10 := -($t0) + 6: $t6 := /($t7, $t10) + 7: $t11 := -($t1) + 8: $t5 := %($t6, $t11) + 9: $t2 := -($t3, $t5) + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := -($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := -($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := -($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := -($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_sub4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := -($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := -($t4, $t11) + 11: return $t3 +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_arithmetic::test_add1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := +($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := +($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 35 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `y`] at line 35 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 35 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `y`] at line 35 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := +($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 35 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 35 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := +($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_add4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 39 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `z`] at line 39 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 39 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `z`] at line 39 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := +($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 39 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 39 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := +($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := /($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := /($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 83 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `y`] at line 83 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 83 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `y`] at line 83 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := /($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 83 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 83 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := /($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 87 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `z`] at line 87 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 87 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `z`] at line 87 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := /($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 87 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 87 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := /($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix1($t0: i64, $t1: i64, $t2: i64): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 1: $t7 := +($t8, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 2: $t6 := -($t7, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 3: $t5 := *($t6, $t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 4: $t4 := /($t5, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 5: $t3 := %($t4, $t2) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix2($t0: i128, $t1: i128, $t2: i128): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 1: $t7 := +($t8, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 2: $t6 := -($t7, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 3: $t5 := *($t6, $t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 4: $t4 := /($t5, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 5: $t3 := %($t4, $t2) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i64 + var $t14: i64 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i64 + var $t17: i64 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i64 + var $t20: i64 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i64 + var $t23: i64 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t9 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s1`] at line 115 + # + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.y($t9) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s1`, field `y`] at line 115 + # + 2: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 3: $t12 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s2`] at line 115 + # + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.y($t12) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s2`, field `y`] at line 115 + # + 5: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t11 + # refs: [] + # + 6: $t7 := +($t8, $t11) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 7: $t15 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => #15 via [local `s3`] at line 115 + # + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t16 + # refs: [$t16 => #16] + # #16 + # + # #root + # => #16 via [local `s3`, field `x`] at line 115 + # + 9: $t14 := read_ref($t16) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t14 + # refs: [] + # + 10: $t6 := -($t7, $t14) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 11: $t18 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => #18 via [local `s1`] at line 115 + # + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.y($t18) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => #19 via [local `s1`, field `y`] at line 115 + # + 13: $t17 := read_ref($t19) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t17 + # refs: [] + # + 14: $t5 := *($t6, $t17) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 15: $t21 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t21 + # refs: [$t21 => #21] + # #21 + # + # #root + # => #21 via [local `s2`] at line 115 + # + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.y($t21) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t22 + # refs: [$t22 => #22] + # #22 + # + # #root + # => #22 via [local `s2`, field `y`] at line 115 + # + 17: $t20 := read_ref($t22) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t20 + # refs: [] + # + 18: $t4 := /($t5, $t20) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 19: $t24 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t24 + # refs: [$t24 => #24] + # #24 + # + # #root + # => #24 via [local `s3`] at line 115 + # + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + # abort state: {returns,aborts} + # live vars: $t4, $t25 + # refs: [$t25 => #25] + # #25 + # + # #root + # => #25 via [local `s3`, field `x`] at line 115 + # + 21: $t23 := read_ref($t25) + # abort state: {returns,aborts} + # live vars: $t4, $t23 + # refs: [] + # + 22: $t3 := %($t4, $t23) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i128 + var $t14: i128 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i128 + var $t17: i128 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i128 + var $t20: i128 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i128 + var $t23: i128 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t9 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s1`] at line 119 + # + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.z($t9) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s1`, field `z`] at line 119 + # + 2: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 3: $t12 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s2`] at line 119 + # + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.z($t12) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s2`, field `z`] at line 119 + # + 5: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8, $t11 + # refs: [] + # + 6: $t7 := +($t8, $t11) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 7: $t15 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => #15 via [local `s3`] at line 119 + # + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t16 + # refs: [$t16 => #16] + # #16 + # + # #root + # => #16 via [local `s3`, field `x`] at line 119 + # + 9: $t14 := read_ref($t16) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t7, $t14 + # refs: [] + # + 10: $t6 := -($t7, $t14) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 11: $t18 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => #18 via [local `s1`] at line 119 + # + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.z($t18) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => #19 via [local `s1`, field `z`] at line 119 + # + 13: $t17 := read_ref($t19) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6, $t17 + # refs: [] + # + 14: $t5 := *($t6, $t17) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 15: $t21 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t21 + # refs: [$t21 => #21] + # #21 + # + # #root + # => #21 via [local `s2`] at line 119 + # + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.z($t21) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t22 + # refs: [$t22 => #22] + # #22 + # + # #root + # => #22 via [local `s2`, field `z`] at line 119 + # + 17: $t20 := read_ref($t22) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t20 + # refs: [] + # + 18: $t4 := /($t5, $t20) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 19: $t24 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t24 + # refs: [$t24 => #24] + # #24 + # + # #root + # => #24 via [local `s3`] at line 119 + # + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + # abort state: {returns,aborts} + # live vars: $t4, $t25 + # refs: [$t25 => #25] + # #25 + # + # #root + # => #25 via [local `s3`, field `x`] at line 119 + # + 21: $t23 := read_ref($t25) + # abort state: {returns,aborts} + # live vars: $t4, $t23 + # refs: [] + # + 22: $t3 := %($t4, $t23) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := %($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := %($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 99 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `y`] at line 99 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 99 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `y`] at line 99 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := %($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 99 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 99 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := %($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 103 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `z`] at line 103 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 103 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `z`] at line 103 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := %($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 103 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 103 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := %($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := *($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := *($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 67 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `y`] at line 67 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 67 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `y`] at line 67 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := *($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 67 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 67 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := *($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 71 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `z`] at line 71 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 71 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `z`] at line 71 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := *($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 71 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 71 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := *($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_neg1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := -($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := +($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t8 := -($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 3: $t9 := -($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8, $t9 + # refs: [] + # + 4: $t7 := *($t8, $t9) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t7 + # refs: [] + # + 5: $t10 := -($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t7, $t10 + # refs: [] + # + 6: $t6 := /($t7, $t10) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t6 + # refs: [] + # + 7: $t11 := -($t1) + # abort state: {returns,aborts} + # live vars: $t3, $t6, $t11 + # refs: [] + # + 8: $t5 := %($t6, $t11) + # abort state: {returns,aborts} + # live vars: $t3, $t5 + # refs: [] + # + 9: $t2 := -($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_neg2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := -($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := +($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t8 := -($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 3: $t9 := -($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8, $t9 + # refs: [] + # + 4: $t7 := *($t8, $t9) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t7 + # refs: [] + # + 5: $t10 := -($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t7, $t10 + # refs: [] + # + 6: $t6 := /($t7, $t10) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t6 + # refs: [] + # + 7: $t11 := -($t1) + # abort state: {returns,aborts} + # live vars: $t3, $t6, $t11 + # refs: [] + # + 8: $t5 := %($t6, $t11) + # abort state: {returns,aborts} + # live vars: $t3, $t5 + # refs: [] + # + 9: $t2 := -($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := -($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3 + # refs: [] + # + 1: $t2 := -($t3, $t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 51 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `y`] at line 51 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 51 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `y`] at line 51 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := -($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 51 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 51 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := -($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_sub4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t6 := borrow_local($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t6 + # refs: [$t6 => #6] + # #6 + # + # #root + # => #6 via [local `s1`] at line 55 + # + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => #7 via [local `s1`, field `z`] at line 55 + # + 2: $t5 := read_ref($t7) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t5 + # refs: [] + # + 3: $t9 := borrow_local($t1) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t9 + # refs: [$t9 => #9] + # #9 + # + # #root + # => #9 via [local `s2`] at line 55 + # + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [local `s2`, field `z`] at line 55 + # + 5: $t8 := read_ref($t10) + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t8 + # refs: [] + # + 6: $t4 := -($t5, $t8) + # abort state: {returns,aborts} + # live vars: $t2, $t4 + # refs: [] + # + 7: $t12 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t4, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s3`] at line 55 + # + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # abort state: {returns,aborts} + # live vars: $t4, $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s3`, field `x`] at line 55 + # + 9: $t11 := read_ref($t13) + # abort state: {returns,aborts} + # live vars: $t4, $t11 + # refs: [] + # + 10: $t3 := -($t4, $t11) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 11: return $t3 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_arithmetic { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test_add1(x: i64): i64 { + Add(x, x) + } + private fun test_add2(x: i128): i128 { + Add(x, x) + } + private fun test_add3(s1: S1,s2: S2,s3: S3): i64 { + Add(Add(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_add4(s1: S1,s2: S2,s3: S3): i128 { + Add(Add(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_div1(x: i64,y: i64): i64 { + Div(x, y) + } + private fun test_div2(x: i128,y: i128): i128 { + Div(x, y) + } + private fun test_div3(s1: S1,s2: S2,s3: S3): i64 { + Div(Div(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_div4(s1: S1,s2: S2,s3: S3): i128 { + Div(Div(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mix1(x: i64,y: i64,z: i64): i64 { + Mod(Div(Mul(Sub(Add(x, y), z), x), y), z) + } + private fun test_mix2(x: i128,y: i128,z: i128): i128 { + Mod(Div(Mul(Sub(Add(x, y), z), x), y), z) + } + private fun test_mix3(s1: S1,s2: S2,s3: S3): i64 { + Mod(Div(Mul(Sub(Add(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)), select valid_arithmetic::S1.y(s1)), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mix4(s1: S1,s2: S2,s3: S3): i128 { + Mod(Div(Mul(Sub(Add(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)), select valid_arithmetic::S1.z(s1)), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mod1(x: i64,y: i64): i64 { + Mod(x, y) + } + private fun test_mod2(x: i128,y: i128): i128 { + Mod(x, y) + } + private fun test_mod3(s1: S1,s2: S2,s3: S3): i64 { + Mod(Mod(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mod4(s1: S1,s2: S2,s3: S3): i128 { + Mod(Mod(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mul1(x: i64,y: i64): i64 { + Mul(x, y) + } + private fun test_mul2(x: i128,y: i128): i128 { + Mul(x, y) + } + private fun test_mul3(s1: S1,s2: S2,s3: S3): i64 { + Mul(Mul(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_mul4(s1: S1,s2: S2,s3: S3): i128 { + Mul(Mul(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_neg1(x: i64,y: i64): i64 { + Sub(Add(Negate(x), y), Mod(Div(Mul(Negate(x), Negate(y)), Negate(x)), Negate(y))) + } + private fun test_neg2(x: i128,y: i128): i128 { + Sub(Add(Negate(x), y), Mod(Div(Mul(Negate(x), Negate(y)), Negate(x)), Negate(y))) + } + private fun test_sub1(x: i64,y: i64): i64 { + Sub(x, y) + } + private fun test_sub2(x: i128,y: i128): i128 { + Sub(x, y) + } + private fun test_sub3(s1: S1,s2: S2,s3: S3): i64 { + Sub(Sub(select valid_arithmetic::S1.y(s1), select valid_arithmetic::S2.y(s2)), select valid_arithmetic::S3.x>(s3)) + } + private fun test_sub4(s1: S1,s2: S2,s3: S3): i128 { + Sub(Sub(select valid_arithmetic::S1.z(s1), select valid_arithmetic::S2.z(s2)), select valid_arithmetic::S3.x>(s3)) + } +} // end 0x42::valid_arithmetic + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_arithmetic::test_add1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_arithmetic::test_add3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := +($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := +($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_add4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := +($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := +($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := /($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := /($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_div3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := /($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := /($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_div4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := /($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := /($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix1($t0: i64, $t1: i64, $t2: i64): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + 0: $t8 := infer($t0) + 1: $t7 := +($t8, $t1) + 2: $t6 := -($t7, $t2) + 3: $t5 := *($t6, $t0) + 4: $t4 := /($t5, $t1) + 5: $t3 := %($t4, $t2) + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix2($t0: i128, $t1: i128, $t2: i128): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + 0: $t8 := infer($t0) + 1: $t7 := +($t8, $t1) + 2: $t6 := -($t7, $t2) + 3: $t5 := *($t6, $t0) + 4: $t4 := /($t5, $t1) + 5: $t3 := %($t4, $t2) + 6: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i64 + var $t14: i64 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i64 + var $t17: i64 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i64 + var $t20: i64 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i64 + var $t23: i64 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i64 + 0: $t9 := borrow_local($t0) + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.y($t9) + 2: $t8 := read_ref($t10) + 3: $t12 := borrow_local($t1) + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.y($t12) + 5: $t11 := read_ref($t13) + 6: $t7 := +($t8, $t11) + 7: $t15 := borrow_local($t2) + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + 9: $t14 := read_ref($t16) + 10: $t6 := -($t7, $t14) + 11: $t18 := borrow_local($t0) + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.y($t18) + 13: $t17 := read_ref($t19) + 14: $t5 := *($t6, $t17) + 15: $t21 := borrow_local($t1) + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.y($t21) + 17: $t20 := read_ref($t22) + 18: $t4 := /($t5, $t20) + 19: $t24 := borrow_local($t2) + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + 21: $t23 := read_ref($t25) + 22: $t3 := %($t4, $t23) + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mix4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i128 + var $t14: i128 + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i128 + var $t17: i128 + var $t18: &0x42::valid_arithmetic::S1 + var $t19: &i128 + var $t20: i128 + var $t21: &0x42::valid_arithmetic::S2 + var $t22: &i128 + var $t23: i128 + var $t24: &0x42::valid_arithmetic::S3 + var $t25: &i128 + 0: $t9 := borrow_local($t0) + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.z($t9) + 2: $t8 := read_ref($t10) + 3: $t12 := borrow_local($t1) + 4: $t13 := borrow_field<0x42::valid_arithmetic::S2>.z($t12) + 5: $t11 := read_ref($t13) + 6: $t7 := +($t8, $t11) + 7: $t15 := borrow_local($t2) + 8: $t16 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + 9: $t14 := read_ref($t16) + 10: $t6 := -($t7, $t14) + 11: $t18 := borrow_local($t0) + 12: $t19 := borrow_field<0x42::valid_arithmetic::S1>.z($t18) + 13: $t17 := read_ref($t19) + 14: $t5 := *($t6, $t17) + 15: $t21 := borrow_local($t1) + 16: $t22 := borrow_field<0x42::valid_arithmetic::S2>.z($t21) + 17: $t20 := read_ref($t22) + 18: $t4 := /($t5, $t20) + 19: $t24 := borrow_local($t2) + 20: $t25 := borrow_field<0x42::valid_arithmetic::S3>.x($t24) + 21: $t23 := read_ref($t25) + 22: $t3 := %($t4, $t23) + 23: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := %($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := %($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mod3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := %($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := %($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mod4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := %($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := %($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := *($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := *($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_mul3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := *($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := *($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_mul4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := *($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := *($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_neg1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + 0: $t4 := -($t0) + 1: $t3 := +($t4, $t1) + 2: $t8 := -($t0) + 3: $t9 := -($t1) + 4: $t7 := *($t8, $t9) + 5: $t10 := -($t0) + 6: $t6 := /($t7, $t10) + 7: $t11 := -($t1) + 8: $t5 := %($t6, $t11) + 9: $t2 := -($t3, $t5) + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_neg2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + 0: $t4 := -($t0) + 1: $t3 := +($t4, $t1) + 2: $t8 := -($t0) + 3: $t9 := -($t1) + 4: $t7 := *($t8, $t9) + 5: $t10 := -($t0) + 6: $t6 := /($t7, $t10) + 7: $t11 := -($t1) + 8: $t5 := %($t6, $t11) + 9: $t2 := -($t3, $t5) + 10: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: i64 + 0: $t3 := infer($t0) + 1: $t2 := -($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: i128 + 0: $t3 := infer($t0) + 1: $t2 := -($t3, $t1) + 2: return $t2 +} + + +[variant baseline] +fun valid_arithmetic::test_sub3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := -($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := -($t4, $t11) + 11: return $t3 +} + + +[variant baseline] +fun valid_arithmetic::test_sub4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 + 0: $t6 := borrow_local($t0) + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + 2: $t5 := read_ref($t7) + 3: $t9 := borrow_local($t1) + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + 5: $t8 := read_ref($t10) + 6: $t4 := -($t5, $t8) + 7: $t12 := borrow_local($t2) + 8: $t13 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + 9: $t11 := read_ref($t13) + 10: $t3 := -($t4, $t11) + 11: return $t3 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_arithmetic::test_add1($t0: i64): i64 { + var $t1: i64 [unused] + var $t2: i64 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := +($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_add2($t0: i128): i128 { + var $t1: i128 [unused] + var $t2: i128 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := +($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_add3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 [unused] + var $t11: i64 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := +($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := +($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_add4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 [unused] + var $t11: i128 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := +($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := +($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_div1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: i64 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := /($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_div2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: i128 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := /($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_div3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 [unused] + var $t11: i64 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := /($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := /($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_div4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 [unused] + var $t11: i128 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := /($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := /($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_mix1($t0: i64, $t1: i64, $t2: i64): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 [unused] + var $t6: i64 [unused] + var $t7: i64 [unused] + var $t8: i64 + # live vars: $t0, $t1, $t2 + 0: $t8 := copy($t0) + # live vars: $t0, $t1, $t2, $t8 + 1: $t8 := +($t8, $t1) + # live vars: $t0, $t1, $t2, $t8 + 2: $t8 := -($t8, $t2) + # live vars: $t0, $t1, $t2, $t8 + 3: $t0 := *($t8, $t0) + # live vars: $t0, $t1, $t2 + 4: $t0 := /($t0, $t1) + # live vars: $t0, $t2 + 5: $t0 := %($t0, $t2) + # live vars: $t0 + 6: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mix2($t0: i128, $t1: i128, $t2: i128): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 [unused] + var $t6: i128 [unused] + var $t7: i128 [unused] + var $t8: i128 + # live vars: $t0, $t1, $t2 + 0: $t8 := copy($t0) + # live vars: $t0, $t1, $t2, $t8 + 1: $t8 := +($t8, $t1) + # live vars: $t0, $t1, $t2, $t8 + 2: $t8 := -($t8, $t2) + # live vars: $t0, $t1, $t2, $t8 + 3: $t0 := *($t8, $t0) + # live vars: $t0, $t1, $t2 + 4: $t0 := /($t0, $t1) + # live vars: $t0, $t2 + 5: $t0 := %($t0, $t2) + # live vars: $t0 + 6: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mix3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 [unused] + var $t6: i64 [unused] + var $t7: i64 [unused] + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i64 + var $t11: i64 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i64 [unused] + var $t14: i64 [unused] + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i64 [unused] + var $t17: i64 [unused] + var $t18: &0x42::valid_arithmetic::S1 [unused] + var $t19: &i64 [unused] + var $t20: i64 [unused] + var $t21: &0x42::valid_arithmetic::S2 [unused] + var $t22: &i64 [unused] + var $t23: i64 [unused] + var $t24: &0x42::valid_arithmetic::S3 [unused] + var $t25: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t9 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t9 + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.y($t9) + # live vars: $t0, $t1, $t2, $t10 + 2: $t8 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8 + 3: $t12 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t8, $t12 + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t12) + # live vars: $t0, $t1, $t2, $t8, $t10 + 5: $t11 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8, $t11 + 6: $t8 := +($t8, $t11) + # live vars: $t0, $t1, $t2, $t8 + 7: $t15 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t8, $t15 + 8: $t10 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # live vars: $t0, $t1, $t2, $t8, $t10 + 9: $t11 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8, $t11 + 10: $t8 := -($t8, $t11) + # live vars: $t0, $t1, $t2, $t8 + 11: $t9 := borrow_local($t0) + # live vars: $t1, $t2, $t8, $t9 + 12: $t10 := borrow_field<0x42::valid_arithmetic::S1>.y($t9) + # live vars: $t1, $t2, $t8, $t10 + 13: $t11 := read_ref($t10) + # live vars: $t1, $t2, $t8, $t11 + 14: $t8 := *($t8, $t11) + # live vars: $t1, $t2, $t8 + 15: $t12 := borrow_local($t1) + # live vars: $t2, $t8, $t12 + 16: $t10 := borrow_field<0x42::valid_arithmetic::S2>.y($t12) + # live vars: $t2, $t8, $t10 + 17: $t11 := read_ref($t10) + # live vars: $t2, $t8, $t11 + 18: $t8 := /($t8, $t11) + # live vars: $t2, $t8 + 19: $t15 := borrow_local($t2) + # live vars: $t8, $t15 + 20: $t10 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # live vars: $t8, $t10 + 21: $t11 := read_ref($t10) + # live vars: $t8, $t11 + 22: $t8 := %($t8, $t11) + # live vars: $t8 + 23: return $t8 +} + + +[variant baseline] +fun valid_arithmetic::test_mix4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 [unused] + var $t6: i128 [unused] + var $t7: i128 [unused] + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S1 + var $t10: &i128 + var $t11: i128 + var $t12: &0x42::valid_arithmetic::S2 + var $t13: &i128 [unused] + var $t14: i128 [unused] + var $t15: &0x42::valid_arithmetic::S3 + var $t16: &i128 [unused] + var $t17: i128 [unused] + var $t18: &0x42::valid_arithmetic::S1 [unused] + var $t19: &i128 [unused] + var $t20: i128 [unused] + var $t21: &0x42::valid_arithmetic::S2 [unused] + var $t22: &i128 [unused] + var $t23: i128 [unused] + var $t24: &0x42::valid_arithmetic::S3 [unused] + var $t25: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t9 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t9 + 1: $t10 := borrow_field<0x42::valid_arithmetic::S1>.z($t9) + # live vars: $t0, $t1, $t2, $t10 + 2: $t8 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8 + 3: $t12 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t8, $t12 + 4: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t12) + # live vars: $t0, $t1, $t2, $t8, $t10 + 5: $t11 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8, $t11 + 6: $t8 := +($t8, $t11) + # live vars: $t0, $t1, $t2, $t8 + 7: $t15 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t8, $t15 + 8: $t10 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # live vars: $t0, $t1, $t2, $t8, $t10 + 9: $t11 := read_ref($t10) + # live vars: $t0, $t1, $t2, $t8, $t11 + 10: $t8 := -($t8, $t11) + # live vars: $t0, $t1, $t2, $t8 + 11: $t9 := borrow_local($t0) + # live vars: $t1, $t2, $t8, $t9 + 12: $t10 := borrow_field<0x42::valid_arithmetic::S1>.z($t9) + # live vars: $t1, $t2, $t8, $t10 + 13: $t11 := read_ref($t10) + # live vars: $t1, $t2, $t8, $t11 + 14: $t8 := *($t8, $t11) + # live vars: $t1, $t2, $t8 + 15: $t12 := borrow_local($t1) + # live vars: $t2, $t8, $t12 + 16: $t10 := borrow_field<0x42::valid_arithmetic::S2>.z($t12) + # live vars: $t2, $t8, $t10 + 17: $t11 := read_ref($t10) + # live vars: $t2, $t8, $t11 + 18: $t8 := /($t8, $t11) + # live vars: $t2, $t8 + 19: $t15 := borrow_local($t2) + # live vars: $t8, $t15 + 20: $t10 := borrow_field<0x42::valid_arithmetic::S3>.x($t15) + # live vars: $t8, $t10 + 21: $t11 := read_ref($t10) + # live vars: $t8, $t11 + 22: $t8 := %($t8, $t11) + # live vars: $t8 + 23: return $t8 +} + + +[variant baseline] +fun valid_arithmetic::test_mod1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: i64 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := %($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mod2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: i128 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := %($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mod3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 [unused] + var $t11: i64 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := %($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := %($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_mod4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 [unused] + var $t11: i128 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := %($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := %($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_mul1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: i64 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := *($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mul2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: i128 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := *($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_mul3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 [unused] + var $t11: i64 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := *($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := *($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_mul4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 [unused] + var $t11: i128 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := *($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := *($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_neg1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + var $t7: i64 [unused] + var $t8: i64 + var $t9: i64 + var $t10: i64 [unused] + var $t11: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := -($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := +($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t8 := -($t0) + # live vars: $t0, $t1, $t4, $t8 + 3: $t9 := -($t1) + # live vars: $t0, $t1, $t4, $t8, $t9 + 4: $t8 := *($t8, $t9) + # live vars: $t0, $t1, $t4, $t8 + 5: $t0 := -($t0) + # live vars: $t0, $t1, $t4, $t8 + 6: $t0 := /($t8, $t0) + # live vars: $t0, $t1, $t4 + 7: $t1 := -($t1) + # live vars: $t0, $t1, $t4 + 8: $t0 := %($t0, $t1) + # live vars: $t0, $t4 + 9: $t0 := -($t4, $t0) + # live vars: $t0 + 10: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_neg2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: i128 [unused] + var $t4: i128 + var $t5: i128 [unused] + var $t6: i128 [unused] + var $t7: i128 [unused] + var $t8: i128 + var $t9: i128 + var $t10: i128 [unused] + var $t11: i128 [unused] + # live vars: $t0, $t1 + 0: $t4 := -($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := +($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t8 := -($t0) + # live vars: $t0, $t1, $t4, $t8 + 3: $t9 := -($t1) + # live vars: $t0, $t1, $t4, $t8, $t9 + 4: $t8 := *($t8, $t9) + # live vars: $t0, $t1, $t4, $t8 + 5: $t0 := -($t0) + # live vars: $t0, $t1, $t4, $t8 + 6: $t0 := /($t8, $t0) + # live vars: $t0, $t1, $t4 + 7: $t1 := -($t1) + # live vars: $t0, $t1, $t4 + 8: $t0 := %($t0, $t1) + # live vars: $t0, $t4 + 9: $t0 := -($t4, $t0) + # live vars: $t0 + 10: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_sub1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: i64 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := -($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_sub2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: i128 [unused] + # live vars: $t0, $t1 + 0: $t0 := move($t0) + # live vars: $t0, $t1 + 1: $t0 := -($t0, $t1) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_arithmetic::test_sub3($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i64 { + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i64 + var $t8: i64 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i64 [unused] + var $t11: i64 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.y($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.y($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := -($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := -($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +[variant baseline] +fun valid_arithmetic::test_sub4($t0: 0x42::valid_arithmetic::S1, $t1: 0x42::valid_arithmetic::S2, $t2: 0x42::valid_arithmetic::S3): i128 { + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: &0x42::valid_arithmetic::S1 + var $t7: &i128 + var $t8: i128 + var $t9: &0x42::valid_arithmetic::S2 + var $t10: &i128 [unused] + var $t11: i128 [unused] + var $t12: &0x42::valid_arithmetic::S3 + var $t13: &i128 [unused] + # live vars: $t0, $t1, $t2 + 0: $t6 := borrow_local($t0) + # live vars: $t1, $t2, $t6 + 1: $t7 := borrow_field<0x42::valid_arithmetic::S1>.z($t6) + # live vars: $t1, $t2, $t7 + 2: $t5 := read_ref($t7) + # live vars: $t1, $t2, $t5 + 3: $t9 := borrow_local($t1) + # live vars: $t2, $t5, $t9 + 4: $t7 := borrow_field<0x42::valid_arithmetic::S2>.z($t9) + # live vars: $t2, $t5, $t7 + 5: $t8 := read_ref($t7) + # live vars: $t2, $t5, $t8 + 6: $t5 := -($t5, $t8) + # live vars: $t2, $t5 + 7: $t12 := borrow_local($t2) + # live vars: $t5, $t12 + 8: $t7 := borrow_field<0x42::valid_arithmetic::S3>.x($t12) + # live vars: $t5, $t7 + 9: $t8 := read_ref($t7) + # live vars: $t5, $t8 + 10: $t5 := -($t5, $t8) + # live vars: $t5 + 11: return $t5 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_arithmetic +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test_add1(l0: i64): i64 + copy_loc l0 + move_loc l0 + add + ret + +// Function definition at index 1 +fun test_add2(l0: i128): i128 + copy_loc l0 + move_loc l0 + add + ret + +// Function definition at index 2 +fun test_add3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + add + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + add + ret + +// Function definition at index 3 +fun test_add4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + add + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + add + ret + +// Function definition at index 4 +fun test_div1(l0: i64, l1: i64): i64 + move_loc l0 + move_loc l1 + div + ret + +// Function definition at index 5 +fun test_div2(l0: i128, l1: i128): i128 + move_loc l0 + move_loc l1 + div + ret + +// Function definition at index 6 +fun test_div3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + div + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + div + ret + +// Function definition at index 7 +fun test_div4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + div + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + div + ret + +// Function definition at index 8 +fun test_mix1(l0: i64, l1: i64, l2: i64): i64 + copy_loc l0 + copy_loc l1 + add + copy_loc l2 + sub + // @5 + move_loc l0 + mul + move_loc l1 + div + move_loc l2 + // @10 + mod + ret + +// Function definition at index 9 +fun test_mix2(l0: i128, l1: i128, l2: i128): i128 + copy_loc l0 + copy_loc l1 + add + copy_loc l2 + sub + // @5 + move_loc l0 + mul + move_loc l1 + div + move_loc l2 + // @10 + mod + ret + +// Function definition at index 10 +fun test_mix3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + add + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + sub + borrow_loc l0 + borrow_field S1, y + read_ref + mul + // @15 + borrow_loc l1 + borrow_field S2, y + read_ref + div + borrow_loc l2 + // @20 + borrow_field S3, x + read_ref + mod + ret + +// Function definition at index 11 +fun test_mix4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + add + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + sub + borrow_loc l0 + borrow_field S1, z + read_ref + mul + // @15 + borrow_loc l1 + borrow_field S2, z + read_ref + div + borrow_loc l2 + // @20 + borrow_field S3, x + read_ref + mod + ret + +// Function definition at index 12 +fun test_mod1(l0: i64, l1: i64): i64 + move_loc l0 + move_loc l1 + mod + ret + +// Function definition at index 13 +fun test_mod2(l0: i128, l1: i128): i128 + move_loc l0 + move_loc l1 + mod + ret + +// Function definition at index 14 +fun test_mod3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + mod + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + mod + ret + +// Function definition at index 15 +fun test_mod4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + mod + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + mod + ret + +// Function definition at index 16 +fun test_mul1(l0: i64, l1: i64): i64 + move_loc l0 + move_loc l1 + mul + ret + +// Function definition at index 17 +fun test_mul2(l0: i128, l1: i128): i128 + move_loc l0 + move_loc l1 + mul + ret + +// Function definition at index 18 +fun test_mul3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + mul + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + mul + ret + +// Function definition at index 19 +fun test_mul4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + mul + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + mul + ret + +// Function definition at index 20 +fun test_neg1(l0: i64, l1: i64): i64 + copy_loc l0 + negate + copy_loc l1 + add + copy_loc l0 + // @5 + negate + copy_loc l1 + negate + mul + move_loc l0 + // @10 + negate + div + move_loc l1 + negate + mod + // @15 + sub + ret + +// Function definition at index 21 +fun test_neg2(l0: i128, l1: i128): i128 + copy_loc l0 + negate + copy_loc l1 + add + copy_loc l0 + // @5 + negate + copy_loc l1 + negate + mul + move_loc l0 + // @10 + negate + div + move_loc l1 + negate + mod + // @15 + sub + ret + +// Function definition at index 22 +fun test_sub1(l0: i64, l1: i64): i64 + move_loc l0 + move_loc l1 + sub + ret + +// Function definition at index 23 +fun test_sub2(l0: i128, l1: i128): i128 + move_loc l0 + move_loc l1 + sub + ret + +// Function definition at index 24 +fun test_sub3(l0: S1, l1: S2, l2: S3): i64 + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + sub + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + sub + ret + +// Function definition at index 25 +fun test_sub4(l0: S1, l1: S2, l2: S3): i128 + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + sub + borrow_loc l2 + borrow_field S3, x + read_ref + // @10 + sub + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.move new file mode 100644 index 00000000000..6b0092396a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_arithmetic.move @@ -0,0 +1,129 @@ +module 0x42::valid_arithmetic { + struct S1 has copy, drop { x: u64, y: i64, z: i128 } + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } + + struct S3 has copy, drop { x: T, y: S1, z: S2 } + + enum E1 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test_add1(x: i64): i64 { + x + x + } + + fun test_add2(x: i128): i128 { + x + x + } + + fun test_add3(s1: S1, s2: S2, s3: S3): i64 { + s1.y + s2.y + s3.x + } + + fun test_add4(s1: S1, s2: S2, s3: S3): i128 { + s1.z + s2.z + s3.x + } + + fun test_sub1(x: i64, y: i64): i64 { + x - y + } + + fun test_sub2(x: i128, y: i128): i128 { + x - y + } + + fun test_sub3(s1: S1, s2: S2, s3: S3): i64 { + s1.y - s2.y - s3.x + } + + fun test_sub4(s1: S1, s2: S2, s3: S3): i128 { + s1.z - s2.z - s3.x + } + + fun test_mul1(x: i64, y: i64): i64 { + x * y + } + + fun test_mul2(x: i128, y: i128): i128 { + x * y + } + + fun test_mul3(s1: S1, s2: S2, s3: S3): i64 { + s1.y * s2.y * s3.x + } + + fun test_mul4(s1: S1, s2: S2, s3: S3): i128 { + s1.z * s2.z * s3.x + } + + fun test_div1(x: i64, y: i64): i64 { + x / y + } + + fun test_div2(x: i128, y: i128): i128 { + x / y + } + + fun test_div3(s1: S1, s2: S2, s3: S3): i64 { + s1.y / s2.y / s3.x + } + + fun test_div4(s1: S1, s2: S2, s3: S3): i128 { + s1.z / s2.z / s3.x + } + + fun test_mod1(x: i64, y: i64): i64 { + x % y + } + + fun test_mod2(x: i128, y: i128): i128 { + x % y + } + + fun test_mod3(s1: S1, s2: S2, s3: S3): i64 { + s1.y % s2.y % s3.x + } + + fun test_mod4(s1: S1, s2: S2, s3: S3): i128 { + s1.z % s2.z % s3.x + } + + fun test_mix1(x: i64, y: i64, z: i64): i64 { + ((x + y) - z) * x / y % z + } + + fun test_mix2(x: i128, y: i128, z: i128): i128 { + ((x + y) - z) * x / y % z + } + + fun test_mix3(s1: S1, s2: S2, s3: S3): i64 { + ((s1.y + s2.y) - s3.x) * s1.y / s2.y % s3.x + } + + fun test_mix4(s1: S1, s2: S2, s3: S3): i128 { + ((s1.z + s2.z) - s3.x) * s1.z / s2.z % s3.x + } + + fun test_neg1(x: i64, y: i64): i64 { + (-x) + y - (-x) * (-y) / (-x) % (-y) + } + + fun test_neg2(x: i128, y: i128): i128 { + (-x) + y - (-x) * (-y) / (-x) % (-y) + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.exp new file mode 100644 index 00000000000..e20f02e7ad7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.exp @@ -0,0 +1,3970 @@ +// -- Model dump before first bytecode pipeline +module 0x42::constants { + public fun test_i128(): i128 { + { + let a_ann: i128 = 0; + { + let b_ann: i128 = 1; + { + let c_ann: i128 = -1; + { + let d_ann: i128 = 170141183460469231731687303715884105727; + { + let e_ann: i128 = -170141183460469231731687303715884105728; + { + let a: i128 = 0; + { + let b: i128 = 1; + { + let c: i128 = -1; + { + let d: i128 = 170141183460469231731687303715884105727; + { + let e: i128 = -170141183460469231731687303715884105728; + { + let (x: i128, y: i128, z: i128): (i128, i128, i128) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 170141183460469231731687303715884105727), 170141183460469231731687303715884105727), -170141183460469231731687303715884105728), -170141183460469231731687303715884105728), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } + public fun test_i16(): i16 { + { + let a_ann: i16 = 0; + { + let b_ann: i16 = 1; + { + let c_ann: i16 = -1; + { + let d_ann: i16 = 32767; + { + let e_ann: i16 = -32768; + { + let a: i16 = 0; + { + let b: i16 = 1; + { + let c: i16 = -1; + { + let d: i16 = 32767; + { + let e: i16 = -32768; + { + let (x: i16, y: i16, z: i16): (i16, i16, i16) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 32767), 32767), -32768), -32768), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } + public fun test_i256(): i256 { + { + let a_ann: i256 = 0; + { + let b_ann: i256 = 1; + { + let c_ann: i256 = -1; + { + let d_ann: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967; + { + let e_ann: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + { + let a: i256 = 0; + { + let b: i256 = 1; + { + let c: i256 = -1; + { + let d: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967; + { + let e: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + { + let (x: i256, y: i256, z: i256): (i256, i256, i256) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 57896044618658097711785492504343953926634992332820282019728792003956564819967), 57896044618658097711785492504343953926634992332820282019728792003956564819967), -57896044618658097711785492504343953926634992332820282019728792003956564819968), -57896044618658097711785492504343953926634992332820282019728792003956564819968), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } + public fun test_i32(): i32 { + { + let a_ann: i32 = 0; + { + let b_ann: i32 = 1; + { + let c_ann: i32 = -1; + { + let d_ann: i32 = 2147483647; + { + let e_ann: i32 = -2147483648; + { + let a: i32 = 0; + { + let b: i32 = 1; + { + let c: i32 = -1; + { + let d: i32 = 2147483647; + { + let e: i32 = -2147483648; + { + let (x: i32, y: i32, z: i32): (i32, i32, i32) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 2147483647), 2147483647), -2147483648), -2147483648), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } + public fun test_i64(): i64 { + { + let a_ann: i64 = 0; + { + let b_ann: i64 = 1; + { + let c_ann: i64 = -1; + { + let d_ann: i64 = 9223372036854775807; + { + let e_ann: i64 = -9223372036854775808; + { + let a: i64 = 0; + { + let b: i64 = 1; + { + let c: i64 = -1; + { + let d: i64 = 9223372036854775807; + { + let e: i64 = -9223372036854775808; + { + let (x: i64, y: i64, z: i64): (i64, i64, i64) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 9223372036854775807), 9223372036854775807), -9223372036854775808), -9223372036854775808), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } + public fun test_i8(): i8 { + { + let a_ann: i8 = 0; + { + let b_ann: i8 = 1; + { + let c_ann: i8 = -1; + { + let d_ann: i8 = 127; + { + let e_ann: i8 = -128; + { + let a: i8 = 0; + { + let b: i8 = 1; + { + let c: i8 = -1; + { + let d: i8 = 127; + { + let e: i8 = -128; + { + let (x: i8, y: i8, z: i8): (i8, i8, i8) = Tuple(-1, -2, -3); + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(0, 1), 1), -1), -1), 127), 127), -128), -128), a_ann), b_ann), c_ann), d_ann), e_ann), a), b), c), d), e), x), y), z) + } + } + } + } + } + } + } + } + } + } + } + } +} // end 0x42::constants + +// -- Sourcified model before first bytecode pipeline +module 0x42::constants { + public fun test_i128(): i128 { + let a_ann = 0i128; + let b_ann = 1i128; + let c_ann = -1i128; + let d_ann = 170141183460469231731687303715884105727i128; + let e_ann = -170141183460469231731687303715884105728i128; + let a = 0i128; + let b = 1i128; + let c = -1i128; + let d = 170141183460469231731687303715884105727i128; + let e = -170141183460469231731687303715884105728i128; + let (x,y,z) = (-1i128, -2i128, -3i128); + 0i128 + 1i128 + 1i128 + -1i128 + -1i128 + 170141183460469231731687303715884105727i128 + 170141183460469231731687303715884105727i128 + -170141183460469231731687303715884105728i128 + -170141183460469231731687303715884105728i128 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + public fun test_i16(): i16 { + let a_ann = 0i16; + let b_ann = 1i16; + let c_ann = -1i16; + let d_ann = 32767i16; + let e_ann = -32768i16; + let a = 0i16; + let b = 1i16; + let c = -1i16; + let d = 32767i16; + let e = -32768i16; + let (x,y,z) = (-1i16, -2i16, -3i16); + 0i16 + 1i16 + 1i16 + -1i16 + -1i16 + 32767i16 + 32767i16 + -32768i16 + -32768i16 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + public fun test_i256(): i256 { + let a_ann = 0i256; + let b_ann = 1i256; + let c_ann = -1i256; + let d_ann = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + let e_ann = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; + let a = 0i256; + let b = 1i256; + let c = -1i256; + let d = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + let e = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; + let (x,y,z) = (-1i256, -2i256, -3i256); + 0i256 + 1i256 + 1i256 + -1i256 + -1i256 + 57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + 57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + public fun test_i32(): i32 { + let a_ann = 0i32; + let b_ann = 1i32; + let c_ann = -1i32; + let d_ann = 2147483647i32; + let e_ann = -2147483648i32; + let a = 0i32; + let b = 1i32; + let c = -1i32; + let d = 2147483647i32; + let e = -2147483648i32; + let (x,y,z) = (-1i32, -2i32, -3i32); + 0i32 + 1i32 + 1i32 + -1i32 + -1i32 + 2147483647i32 + 2147483647i32 + -2147483648i32 + -2147483648i32 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + public fun test_i64(): i64 { + let a_ann = 0i64; + let b_ann = 1i64; + let c_ann = -1i64; + let d_ann = 9223372036854775807i64; + let e_ann = -9223372036854775808i64; + let a = 0i64; + let b = 1i64; + let c = -1i64; + let d = 9223372036854775807i64; + let e = -9223372036854775808i64; + let (x,y,z) = (-1i64, -2i64, -3i64); + 0i64 + 1i64 + 1i64 + -1i64 + -1i64 + 9223372036854775807i64 + 9223372036854775807i64 + -9223372036854775808i64 + -9223372036854775808i64 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + public fun test_i8(): i8 { + let a_ann = 0i8; + let b_ann = 1i8; + let c_ann = -1i8; + let d_ann = 127i8; + let e_ann = -128i8; + let a = 0i8; + let b = 1i8; + let c = -1i8; + let d = 127i8; + let e = -128i8; + let (x,y,z) = (-1i8, -2i8, -3i8); + 0i8 + 1i8 + 1i8 + -1i8 + -1i8 + 127i8 + 127i8 + -128i8 + -128i8 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +public fun constants::test_i128(): i128 { + var $t0: i128 + var $t1: i128 + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: i128 + var $t15: i128 + var $t16: i128 + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + var $t21: i128 + var $t22: i128 + var $t23: i128 + var $t24: i128 + var $t25: i128 + var $t26: i128 + var $t27: i128 + var $t28: i128 + var $t29: i128 + var $t30: i128 + var $t31: i128 + var $t32: i128 + var $t33: i128 + var $t34: i128 + var $t35: i128 + var $t36: i128 + var $t37: i128 + var $t38: i128 + var $t39: i128 + var $t40: i128 + var $t41: i128 + var $t42: i128 + var $t43: i128 + var $t44: i128 + var $t45: i128 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 170141183460469231731687303715884105727 + 4: $t5 := -170141183460469231731687303715884105728 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 170141183460469231731687303715884105727 + 9: $t10 := -170141183460469231731687303715884105728 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 170141183460469231731687303715884105727 + 26: $t32 := +($t33, $t42) + 27: $t43 := 170141183460469231731687303715884105727 + 28: $t31 := +($t32, $t43) + 29: $t44 := -170141183460469231731687303715884105728 + 30: $t30 := +($t31, $t44) + 31: $t45 := -170141183460469231731687303715884105728 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i16(): i16 { + var $t0: i16 + var $t1: i16 + var $t2: i16 + var $t3: i16 + var $t4: i16 + var $t5: i16 + var $t6: i16 + var $t7: i16 + var $t8: i16 + var $t9: i16 + var $t10: i16 + var $t11: i16 + var $t12: i16 + var $t13: i16 + var $t14: i16 + var $t15: i16 + var $t16: i16 + var $t17: i16 + var $t18: i16 + var $t19: i16 + var $t20: i16 + var $t21: i16 + var $t22: i16 + var $t23: i16 + var $t24: i16 + var $t25: i16 + var $t26: i16 + var $t27: i16 + var $t28: i16 + var $t29: i16 + var $t30: i16 + var $t31: i16 + var $t32: i16 + var $t33: i16 + var $t34: i16 + var $t35: i16 + var $t36: i16 + var $t37: i16 + var $t38: i16 + var $t39: i16 + var $t40: i16 + var $t41: i16 + var $t42: i16 + var $t43: i16 + var $t44: i16 + var $t45: i16 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 32767 + 4: $t5 := -32768 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 32767 + 9: $t10 := -32768 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 32767 + 26: $t32 := +($t33, $t42) + 27: $t43 := 32767 + 28: $t31 := +($t32, $t43) + 29: $t44 := -32768 + 30: $t30 := +($t31, $t44) + 31: $t45 := -32768 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i256(): i256 { + var $t0: i256 + var $t1: i256 + var $t2: i256 + var $t3: i256 + var $t4: i256 + var $t5: i256 + var $t6: i256 + var $t7: i256 + var $t8: i256 + var $t9: i256 + var $t10: i256 + var $t11: i256 + var $t12: i256 + var $t13: i256 + var $t14: i256 + var $t15: i256 + var $t16: i256 + var $t17: i256 + var $t18: i256 + var $t19: i256 + var $t20: i256 + var $t21: i256 + var $t22: i256 + var $t23: i256 + var $t24: i256 + var $t25: i256 + var $t26: i256 + var $t27: i256 + var $t28: i256 + var $t29: i256 + var $t30: i256 + var $t31: i256 + var $t32: i256 + var $t33: i256 + var $t34: i256 + var $t35: i256 + var $t36: i256 + var $t37: i256 + var $t38: i256 + var $t39: i256 + var $t40: i256 + var $t41: i256 + var $t42: i256 + var $t43: i256 + var $t44: i256 + var $t45: i256 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 4: $t5 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 9: $t10 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 26: $t32 := +($t33, $t42) + 27: $t43 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 28: $t31 := +($t32, $t43) + 29: $t44 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 30: $t30 := +($t31, $t44) + 31: $t45 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i32(): i32 { + var $t0: i32 + var $t1: i32 + var $t2: i32 + var $t3: i32 + var $t4: i32 + var $t5: i32 + var $t6: i32 + var $t7: i32 + var $t8: i32 + var $t9: i32 + var $t10: i32 + var $t11: i32 + var $t12: i32 + var $t13: i32 + var $t14: i32 + var $t15: i32 + var $t16: i32 + var $t17: i32 + var $t18: i32 + var $t19: i32 + var $t20: i32 + var $t21: i32 + var $t22: i32 + var $t23: i32 + var $t24: i32 + var $t25: i32 + var $t26: i32 + var $t27: i32 + var $t28: i32 + var $t29: i32 + var $t30: i32 + var $t31: i32 + var $t32: i32 + var $t33: i32 + var $t34: i32 + var $t35: i32 + var $t36: i32 + var $t37: i32 + var $t38: i32 + var $t39: i32 + var $t40: i32 + var $t41: i32 + var $t42: i32 + var $t43: i32 + var $t44: i32 + var $t45: i32 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 2147483647 + 4: $t5 := -2147483648 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 2147483647 + 9: $t10 := -2147483648 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 2147483647 + 26: $t32 := +($t33, $t42) + 27: $t43 := 2147483647 + 28: $t31 := +($t32, $t43) + 29: $t44 := -2147483648 + 30: $t30 := +($t31, $t44) + 31: $t45 := -2147483648 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i64(): i64 { + var $t0: i64 + var $t1: i64 + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: i64 + var $t15: i64 + var $t16: i64 + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + var $t21: i64 + var $t22: i64 + var $t23: i64 + var $t24: i64 + var $t25: i64 + var $t26: i64 + var $t27: i64 + var $t28: i64 + var $t29: i64 + var $t30: i64 + var $t31: i64 + var $t32: i64 + var $t33: i64 + var $t34: i64 + var $t35: i64 + var $t36: i64 + var $t37: i64 + var $t38: i64 + var $t39: i64 + var $t40: i64 + var $t41: i64 + var $t42: i64 + var $t43: i64 + var $t44: i64 + var $t45: i64 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 9223372036854775807 + 4: $t5 := -9223372036854775808 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 9223372036854775807 + 9: $t10 := -9223372036854775808 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 9223372036854775807 + 26: $t32 := +($t33, $t42) + 27: $t43 := 9223372036854775807 + 28: $t31 := +($t32, $t43) + 29: $t44 := -9223372036854775808 + 30: $t30 := +($t31, $t44) + 31: $t45 := -9223372036854775808 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i8(): i8 { + var $t0: i8 + var $t1: i8 + var $t2: i8 + var $t3: i8 + var $t4: i8 + var $t5: i8 + var $t6: i8 + var $t7: i8 + var $t8: i8 + var $t9: i8 + var $t10: i8 + var $t11: i8 + var $t12: i8 + var $t13: i8 + var $t14: i8 + var $t15: i8 + var $t16: i8 + var $t17: i8 + var $t18: i8 + var $t19: i8 + var $t20: i8 + var $t21: i8 + var $t22: i8 + var $t23: i8 + var $t24: i8 + var $t25: i8 + var $t26: i8 + var $t27: i8 + var $t28: i8 + var $t29: i8 + var $t30: i8 + var $t31: i8 + var $t32: i8 + var $t33: i8 + var $t34: i8 + var $t35: i8 + var $t36: i8 + var $t37: i8 + var $t38: i8 + var $t39: i8 + var $t40: i8 + var $t41: i8 + var $t42: i8 + var $t43: i8 + var $t44: i8 + var $t45: i8 + 0: $t1 := 0 + 1: $t2 := 1 + 2: $t3 := -1 + 3: $t4 := 127 + 4: $t5 := -128 + 5: $t6 := 0 + 6: $t7 := 1 + 7: $t8 := -1 + 8: $t9 := 127 + 9: $t10 := -128 + 10: $t14 := -1 + 11: $t11 := infer($t14) + 12: $t15 := -2 + 13: $t12 := infer($t15) + 14: $t16 := -3 + 15: $t13 := infer($t16) + 16: $t37 := 0 + 17: $t38 := 1 + 18: $t36 := +($t37, $t38) + 19: $t39 := 1 + 20: $t35 := +($t36, $t39) + 21: $t40 := -1 + 22: $t34 := +($t35, $t40) + 23: $t41 := -1 + 24: $t33 := +($t34, $t41) + 25: $t42 := 127 + 26: $t32 := +($t33, $t42) + 27: $t43 := 127 + 28: $t31 := +($t32, $t43) + 29: $t44 := -128 + 30: $t30 := +($t31, $t44) + 31: $t45 := -128 + 32: $t29 := +($t30, $t45) + 33: $t28 := +($t29, $t1) + 34: $t27 := +($t28, $t2) + 35: $t26 := +($t27, $t3) + 36: $t25 := +($t26, $t4) + 37: $t24 := +($t25, $t5) + 38: $t23 := +($t24, $t6) + 39: $t22 := +($t23, $t7) + 40: $t21 := +($t22, $t8) + 41: $t20 := +($t21, $t9) + 42: $t19 := +($t20, $t10) + 43: $t18 := +($t19, $t11) + 44: $t17 := +($t18, $t12) + 45: $t0 := +($t17, $t13) + 46: return $t0 +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +public fun constants::test_i128(): i128 { + var $t0: i128 + var $t1: i128 + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: i128 + var $t15: i128 + var $t16: i128 + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + var $t21: i128 + var $t22: i128 + var $t23: i128 + var $t24: i128 + var $t25: i128 + var $t26: i128 + var $t27: i128 + var $t28: i128 + var $t29: i128 + var $t30: i128 + var $t31: i128 + var $t32: i128 + var $t33: i128 + var $t34: i128 + var $t35: i128 + var $t36: i128 + var $t37: i128 + var $t38: i128 + var $t39: i128 + var $t40: i128 + var $t41: i128 + var $t42: i128 + var $t43: i128 + var $t44: i128 + var $t45: i128 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 170141183460469231731687303715884105727 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -170141183460469231731687303715884105728 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 170141183460469231731687303715884105727 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -170141183460469231731687303715884105728 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 170141183460469231731687303715884105727 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 170141183460469231731687303715884105727 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -170141183460469231731687303715884105728 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -170141183460469231731687303715884105728 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i16(): i16 { + var $t0: i16 + var $t1: i16 + var $t2: i16 + var $t3: i16 + var $t4: i16 + var $t5: i16 + var $t6: i16 + var $t7: i16 + var $t8: i16 + var $t9: i16 + var $t10: i16 + var $t11: i16 + var $t12: i16 + var $t13: i16 + var $t14: i16 + var $t15: i16 + var $t16: i16 + var $t17: i16 + var $t18: i16 + var $t19: i16 + var $t20: i16 + var $t21: i16 + var $t22: i16 + var $t23: i16 + var $t24: i16 + var $t25: i16 + var $t26: i16 + var $t27: i16 + var $t28: i16 + var $t29: i16 + var $t30: i16 + var $t31: i16 + var $t32: i16 + var $t33: i16 + var $t34: i16 + var $t35: i16 + var $t36: i16 + var $t37: i16 + var $t38: i16 + var $t39: i16 + var $t40: i16 + var $t41: i16 + var $t42: i16 + var $t43: i16 + var $t44: i16 + var $t45: i16 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 32767 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -32768 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 32767 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -32768 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 32767 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 32767 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -32768 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -32768 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i256(): i256 { + var $t0: i256 + var $t1: i256 + var $t2: i256 + var $t3: i256 + var $t4: i256 + var $t5: i256 + var $t6: i256 + var $t7: i256 + var $t8: i256 + var $t9: i256 + var $t10: i256 + var $t11: i256 + var $t12: i256 + var $t13: i256 + var $t14: i256 + var $t15: i256 + var $t16: i256 + var $t17: i256 + var $t18: i256 + var $t19: i256 + var $t20: i256 + var $t21: i256 + var $t22: i256 + var $t23: i256 + var $t24: i256 + var $t25: i256 + var $t26: i256 + var $t27: i256 + var $t28: i256 + var $t29: i256 + var $t30: i256 + var $t31: i256 + var $t32: i256 + var $t33: i256 + var $t34: i256 + var $t35: i256 + var $t36: i256 + var $t37: i256 + var $t38: i256 + var $t39: i256 + var $t40: i256 + var $t41: i256 + var $t42: i256 + var $t43: i256 + var $t44: i256 + var $t45: i256 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i32(): i32 { + var $t0: i32 + var $t1: i32 + var $t2: i32 + var $t3: i32 + var $t4: i32 + var $t5: i32 + var $t6: i32 + var $t7: i32 + var $t8: i32 + var $t9: i32 + var $t10: i32 + var $t11: i32 + var $t12: i32 + var $t13: i32 + var $t14: i32 + var $t15: i32 + var $t16: i32 + var $t17: i32 + var $t18: i32 + var $t19: i32 + var $t20: i32 + var $t21: i32 + var $t22: i32 + var $t23: i32 + var $t24: i32 + var $t25: i32 + var $t26: i32 + var $t27: i32 + var $t28: i32 + var $t29: i32 + var $t30: i32 + var $t31: i32 + var $t32: i32 + var $t33: i32 + var $t34: i32 + var $t35: i32 + var $t36: i32 + var $t37: i32 + var $t38: i32 + var $t39: i32 + var $t40: i32 + var $t41: i32 + var $t42: i32 + var $t43: i32 + var $t44: i32 + var $t45: i32 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 2147483647 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -2147483648 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 2147483647 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -2147483648 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 2147483647 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 2147483647 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -2147483648 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -2147483648 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i64(): i64 { + var $t0: i64 + var $t1: i64 + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: i64 + var $t15: i64 + var $t16: i64 + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + var $t21: i64 + var $t22: i64 + var $t23: i64 + var $t24: i64 + var $t25: i64 + var $t26: i64 + var $t27: i64 + var $t28: i64 + var $t29: i64 + var $t30: i64 + var $t31: i64 + var $t32: i64 + var $t33: i64 + var $t34: i64 + var $t35: i64 + var $t36: i64 + var $t37: i64 + var $t38: i64 + var $t39: i64 + var $t40: i64 + var $t41: i64 + var $t42: i64 + var $t43: i64 + var $t44: i64 + var $t45: i64 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 9223372036854775807 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -9223372036854775808 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 9223372036854775807 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -9223372036854775808 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 9223372036854775807 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 9223372036854775807 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -9223372036854775808 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -9223372036854775808 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + + +[variant baseline] +public fun constants::test_i8(): i8 { + var $t0: i8 + var $t1: i8 + var $t2: i8 + var $t3: i8 + var $t4: i8 + var $t5: i8 + var $t6: i8 + var $t7: i8 + var $t8: i8 + var $t9: i8 + var $t10: i8 + var $t11: i8 + var $t12: i8 + var $t13: i8 + var $t14: i8 + var $t15: i8 + var $t16: i8 + var $t17: i8 + var $t18: i8 + var $t19: i8 + var $t20: i8 + var $t21: i8 + var $t22: i8 + var $t23: i8 + var $t24: i8 + var $t25: i8 + var $t26: i8 + var $t27: i8 + var $t28: i8 + var $t29: i8 + var $t30: i8 + var $t31: i8 + var $t32: i8 + var $t33: i8 + var $t34: i8 + var $t35: i8 + var $t36: i8 + var $t37: i8 + var $t38: i8 + var $t39: i8 + var $t40: i8 + var $t41: i8 + var $t42: i8 + var $t43: i8 + var $t44: i8 + var $t45: i8 + # abort state: {returns,aborts} + # live vars: + # refs: [] + # + 0: $t1 := 0 + # abort state: {returns,aborts} + # live vars: $t1 + # refs: [] + # + 1: $t2 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2 + # refs: [] + # + 2: $t3 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3 + # refs: [] + # + 3: $t4 := 127 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4 + # refs: [] + # + 4: $t5 := -128 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5 + # refs: [] + # + 5: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6 + # refs: [] + # + 6: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7 + # refs: [] + # + 7: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 + # refs: [] + # + 8: $t9 := 127 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9 + # refs: [] + # + 9: $t10 := -128 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10 + # refs: [] + # + 10: $t14 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t14 + # refs: [] + # + 11: $t11 := infer($t14) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11 + # refs: [] + # + 12: $t15 := -2 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t15 + # refs: [] + # + 13: $t12 := infer($t15) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12 + # refs: [] + # + 14: $t16 := -3 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t16 + # refs: [] + # + 15: $t13 := infer($t16) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13 + # refs: [] + # + 16: $t37 := 0 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37 + # refs: [] + # + 17: $t38 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t37, $t38 + # refs: [] + # + 18: $t36 := +($t37, $t38) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36 + # refs: [] + # + 19: $t39 := 1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t36, $t39 + # refs: [] + # + 20: $t35 := +($t36, $t39) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35 + # refs: [] + # + 21: $t40 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t35, $t40 + # refs: [] + # + 22: $t34 := +($t35, $t40) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34 + # refs: [] + # + 23: $t41 := -1 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t34, $t41 + # refs: [] + # + 24: $t33 := +($t34, $t41) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33 + # refs: [] + # + 25: $t42 := 127 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t33, $t42 + # refs: [] + # + 26: $t32 := +($t33, $t42) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32 + # refs: [] + # + 27: $t43 := 127 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t32, $t43 + # refs: [] + # + 28: $t31 := +($t32, $t43) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31 + # refs: [] + # + 29: $t44 := -128 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t31, $t44 + # refs: [] + # + 30: $t30 := +($t31, $t44) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30 + # refs: [] + # + 31: $t45 := -128 + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t30, $t45 + # refs: [] + # + 32: $t29 := +($t30, $t45) + # abort state: {returns,aborts} + # live vars: $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t29 + # refs: [] + # + 33: $t28 := +($t29, $t1) + # abort state: {returns,aborts} + # live vars: $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t28 + # refs: [] + # + 34: $t27 := +($t28, $t2) + # abort state: {returns,aborts} + # live vars: $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t27 + # refs: [] + # + 35: $t26 := +($t27, $t3) + # abort state: {returns,aborts} + # live vars: $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t26 + # refs: [] + # + 36: $t25 := +($t26, $t4) + # abort state: {returns,aborts} + # live vars: $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t25 + # refs: [] + # + 37: $t24 := +($t25, $t5) + # abort state: {returns,aborts} + # live vars: $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t24 + # refs: [] + # + 38: $t23 := +($t24, $t6) + # abort state: {returns,aborts} + # live vars: $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t23 + # refs: [] + # + 39: $t22 := +($t23, $t7) + # abort state: {returns,aborts} + # live vars: $t8, $t9, $t10, $t11, $t12, $t13, $t22 + # refs: [] + # + 40: $t21 := +($t22, $t8) + # abort state: {returns,aborts} + # live vars: $t9, $t10, $t11, $t12, $t13, $t21 + # refs: [] + # + 41: $t20 := +($t21, $t9) + # abort state: {returns,aborts} + # live vars: $t10, $t11, $t12, $t13, $t20 + # refs: [] + # + 42: $t19 := +($t20, $t10) + # abort state: {returns,aborts} + # live vars: $t11, $t12, $t13, $t19 + # refs: [] + # + 43: $t18 := +($t19, $t11) + # abort state: {returns,aborts} + # live vars: $t12, $t13, $t18 + # refs: [] + # + 44: $t17 := +($t18, $t12) + # abort state: {returns,aborts} + # live vars: $t13, $t17 + # refs: [] + # + 45: $t0 := +($t17, $t13) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 46: return $t0 +} + +// -- Model dump before second bytecode pipeline +module 0x42::constants { + public fun test_i128(): i128 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(170141183460469231731687303715884105727, 170141183460469231731687303715884105727), -170141183460469231731687303715884105728), -170141183460469231731687303715884105728), 0), 1), -1), 170141183460469231731687303715884105727), -170141183460469231731687303715884105728), 0), 1), -1), 170141183460469231731687303715884105727), -170141183460469231731687303715884105728), -1), -2), -3) + } + public fun test_i16(): i16 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(32767, 32767), -32768), -32768), 0), 1), -1), 32767), -32768), 0), 1), -1), 32767), -32768), -1), -2), -3) + } + public fun test_i256(): i256 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(57896044618658097711785492504343953926634992332820282019728792003956564819967, 57896044618658097711785492504343953926634992332820282019728792003956564819967), -57896044618658097711785492504343953926634992332820282019728792003956564819968), -57896044618658097711785492504343953926634992332820282019728792003956564819968), 0), 1), -1), 57896044618658097711785492504343953926634992332820282019728792003956564819967), -57896044618658097711785492504343953926634992332820282019728792003956564819968), 0), 1), -1), 57896044618658097711785492504343953926634992332820282019728792003956564819967), -57896044618658097711785492504343953926634992332820282019728792003956564819968), -1), -2), -3) + } + public fun test_i32(): i32 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(2147483647, 2147483647), -2147483648), -2147483648), 0), 1), -1), 2147483647), -2147483648), 0), 1), -1), 2147483647), -2147483648), -1), -2), -3) + } + public fun test_i64(): i64 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(9223372036854775807, 9223372036854775807), -9223372036854775808), -9223372036854775808), 0), 1), -1), 9223372036854775807), -9223372036854775808), 0), 1), -1), 9223372036854775807), -9223372036854775808), -1), -2), -3) + } + public fun test_i8(): i8 { + Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(127, 127), -128), -128), 0), 1), -1), 127), -128), 0), 1), -1), 127), -128), -1), -2), -3) + } +} // end 0x42::constants + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +public fun constants::test_i128(): i128 { + var $t0: i128 + var $t1: i128 + var $t2: i128 + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: i128 + var $t15: i128 + var $t16: i128 + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + var $t21: i128 + var $t22: i128 + var $t23: i128 + var $t24: i128 + var $t25: i128 + var $t26: i128 + var $t27: i128 + var $t28: i128 + var $t29: i128 + var $t30: i128 + var $t31: i128 + var $t32: i128 + 0: $t16 := 170141183460469231731687303715884105727 + 1: $t17 := 170141183460469231731687303715884105727 + 2: $t15 := +($t16, $t17) + 3: $t18 := -170141183460469231731687303715884105728 + 4: $t14 := +($t15, $t18) + 5: $t19 := -170141183460469231731687303715884105728 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 170141183460469231731687303715884105727 + 14: $t9 := +($t10, $t23) + 15: $t24 := -170141183460469231731687303715884105728 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 170141183460469231731687303715884105727 + 24: $t4 := +($t5, $t28) + 25: $t29 := -170141183460469231731687303715884105728 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + + +[variant baseline] +public fun constants::test_i16(): i16 { + var $t0: i16 + var $t1: i16 + var $t2: i16 + var $t3: i16 + var $t4: i16 + var $t5: i16 + var $t6: i16 + var $t7: i16 + var $t8: i16 + var $t9: i16 + var $t10: i16 + var $t11: i16 + var $t12: i16 + var $t13: i16 + var $t14: i16 + var $t15: i16 + var $t16: i16 + var $t17: i16 + var $t18: i16 + var $t19: i16 + var $t20: i16 + var $t21: i16 + var $t22: i16 + var $t23: i16 + var $t24: i16 + var $t25: i16 + var $t26: i16 + var $t27: i16 + var $t28: i16 + var $t29: i16 + var $t30: i16 + var $t31: i16 + var $t32: i16 + 0: $t16 := 32767 + 1: $t17 := 32767 + 2: $t15 := +($t16, $t17) + 3: $t18 := -32768 + 4: $t14 := +($t15, $t18) + 5: $t19 := -32768 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 32767 + 14: $t9 := +($t10, $t23) + 15: $t24 := -32768 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 32767 + 24: $t4 := +($t5, $t28) + 25: $t29 := -32768 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + + +[variant baseline] +public fun constants::test_i256(): i256 { + var $t0: i256 + var $t1: i256 + var $t2: i256 + var $t3: i256 + var $t4: i256 + var $t5: i256 + var $t6: i256 + var $t7: i256 + var $t8: i256 + var $t9: i256 + var $t10: i256 + var $t11: i256 + var $t12: i256 + var $t13: i256 + var $t14: i256 + var $t15: i256 + var $t16: i256 + var $t17: i256 + var $t18: i256 + var $t19: i256 + var $t20: i256 + var $t21: i256 + var $t22: i256 + var $t23: i256 + var $t24: i256 + var $t25: i256 + var $t26: i256 + var $t27: i256 + var $t28: i256 + var $t29: i256 + var $t30: i256 + var $t31: i256 + var $t32: i256 + 0: $t16 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 1: $t17 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 2: $t15 := +($t16, $t17) + 3: $t18 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 4: $t14 := +($t15, $t18) + 5: $t19 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 14: $t9 := +($t10, $t23) + 15: $t24 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + 24: $t4 := +($t5, $t28) + 25: $t29 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + + +[variant baseline] +public fun constants::test_i32(): i32 { + var $t0: i32 + var $t1: i32 + var $t2: i32 + var $t3: i32 + var $t4: i32 + var $t5: i32 + var $t6: i32 + var $t7: i32 + var $t8: i32 + var $t9: i32 + var $t10: i32 + var $t11: i32 + var $t12: i32 + var $t13: i32 + var $t14: i32 + var $t15: i32 + var $t16: i32 + var $t17: i32 + var $t18: i32 + var $t19: i32 + var $t20: i32 + var $t21: i32 + var $t22: i32 + var $t23: i32 + var $t24: i32 + var $t25: i32 + var $t26: i32 + var $t27: i32 + var $t28: i32 + var $t29: i32 + var $t30: i32 + var $t31: i32 + var $t32: i32 + 0: $t16 := 2147483647 + 1: $t17 := 2147483647 + 2: $t15 := +($t16, $t17) + 3: $t18 := -2147483648 + 4: $t14 := +($t15, $t18) + 5: $t19 := -2147483648 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 2147483647 + 14: $t9 := +($t10, $t23) + 15: $t24 := -2147483648 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 2147483647 + 24: $t4 := +($t5, $t28) + 25: $t29 := -2147483648 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + + +[variant baseline] +public fun constants::test_i64(): i64 { + var $t0: i64 + var $t1: i64 + var $t2: i64 + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: i64 + var $t15: i64 + var $t16: i64 + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + var $t21: i64 + var $t22: i64 + var $t23: i64 + var $t24: i64 + var $t25: i64 + var $t26: i64 + var $t27: i64 + var $t28: i64 + var $t29: i64 + var $t30: i64 + var $t31: i64 + var $t32: i64 + 0: $t16 := 9223372036854775807 + 1: $t17 := 9223372036854775807 + 2: $t15 := +($t16, $t17) + 3: $t18 := -9223372036854775808 + 4: $t14 := +($t15, $t18) + 5: $t19 := -9223372036854775808 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 9223372036854775807 + 14: $t9 := +($t10, $t23) + 15: $t24 := -9223372036854775808 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 9223372036854775807 + 24: $t4 := +($t5, $t28) + 25: $t29 := -9223372036854775808 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + + +[variant baseline] +public fun constants::test_i8(): i8 { + var $t0: i8 + var $t1: i8 + var $t2: i8 + var $t3: i8 + var $t4: i8 + var $t5: i8 + var $t6: i8 + var $t7: i8 + var $t8: i8 + var $t9: i8 + var $t10: i8 + var $t11: i8 + var $t12: i8 + var $t13: i8 + var $t14: i8 + var $t15: i8 + var $t16: i8 + var $t17: i8 + var $t18: i8 + var $t19: i8 + var $t20: i8 + var $t21: i8 + var $t22: i8 + var $t23: i8 + var $t24: i8 + var $t25: i8 + var $t26: i8 + var $t27: i8 + var $t28: i8 + var $t29: i8 + var $t30: i8 + var $t31: i8 + var $t32: i8 + 0: $t16 := 127 + 1: $t17 := 127 + 2: $t15 := +($t16, $t17) + 3: $t18 := -128 + 4: $t14 := +($t15, $t18) + 5: $t19 := -128 + 6: $t13 := +($t14, $t19) + 7: $t20 := 0 + 8: $t12 := +($t13, $t20) + 9: $t21 := 1 + 10: $t11 := +($t12, $t21) + 11: $t22 := -1 + 12: $t10 := +($t11, $t22) + 13: $t23 := 127 + 14: $t9 := +($t10, $t23) + 15: $t24 := -128 + 16: $t8 := +($t9, $t24) + 17: $t25 := 0 + 18: $t7 := +($t8, $t25) + 19: $t26 := 1 + 20: $t6 := +($t7, $t26) + 21: $t27 := -1 + 22: $t5 := +($t6, $t27) + 23: $t28 := 127 + 24: $t4 := +($t5, $t28) + 25: $t29 := -128 + 26: $t3 := +($t4, $t29) + 27: $t30 := -1 + 28: $t2 := +($t3, $t30) + 29: $t31 := -2 + 30: $t1 := +($t2, $t31) + 31: $t32 := -3 + 32: $t0 := +($t1, $t32) + 33: return $t0 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +public fun constants::test_i128(): i128 { + var $t0: i128 [unused] + var $t1: i128 [unused] + var $t2: i128 [unused] + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 [unused] + var $t6: i128 [unused] + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + var $t11: i128 [unused] + var $t12: i128 [unused] + var $t13: i128 [unused] + var $t14: i128 [unused] + var $t15: i128 [unused] + var $t16: i128 + var $t17: i128 + var $t18: i128 [unused] + var $t19: i128 [unused] + var $t20: i128 [unused] + var $t21: i128 [unused] + var $t22: i128 [unused] + var $t23: i128 [unused] + var $t24: i128 [unused] + var $t25: i128 [unused] + var $t26: i128 [unused] + var $t27: i128 [unused] + var $t28: i128 [unused] + var $t29: i128 [unused] + var $t30: i128 [unused] + var $t31: i128 [unused] + var $t32: i128 [unused] + # live vars: + 0: $t16 := 170141183460469231731687303715884105727 + # live vars: $t16 + 1: $t17 := 170141183460469231731687303715884105727 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -170141183460469231731687303715884105728 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -170141183460469231731687303715884105728 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 170141183460469231731687303715884105727 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -170141183460469231731687303715884105728 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 170141183460469231731687303715884105727 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -170141183460469231731687303715884105728 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +[variant baseline] +public fun constants::test_i16(): i16 { + var $t0: i16 [unused] + var $t1: i16 [unused] + var $t2: i16 [unused] + var $t3: i16 [unused] + var $t4: i16 [unused] + var $t5: i16 [unused] + var $t6: i16 [unused] + var $t7: i16 [unused] + var $t8: i16 [unused] + var $t9: i16 [unused] + var $t10: i16 [unused] + var $t11: i16 [unused] + var $t12: i16 [unused] + var $t13: i16 [unused] + var $t14: i16 [unused] + var $t15: i16 [unused] + var $t16: i16 + var $t17: i16 + var $t18: i16 [unused] + var $t19: i16 [unused] + var $t20: i16 [unused] + var $t21: i16 [unused] + var $t22: i16 [unused] + var $t23: i16 [unused] + var $t24: i16 [unused] + var $t25: i16 [unused] + var $t26: i16 [unused] + var $t27: i16 [unused] + var $t28: i16 [unused] + var $t29: i16 [unused] + var $t30: i16 [unused] + var $t31: i16 [unused] + var $t32: i16 [unused] + # live vars: + 0: $t16 := 32767 + # live vars: $t16 + 1: $t17 := 32767 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -32768 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -32768 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 32767 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -32768 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 32767 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -32768 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +[variant baseline] +public fun constants::test_i256(): i256 { + var $t0: i256 [unused] + var $t1: i256 [unused] + var $t2: i256 [unused] + var $t3: i256 [unused] + var $t4: i256 [unused] + var $t5: i256 [unused] + var $t6: i256 [unused] + var $t7: i256 [unused] + var $t8: i256 [unused] + var $t9: i256 [unused] + var $t10: i256 [unused] + var $t11: i256 [unused] + var $t12: i256 [unused] + var $t13: i256 [unused] + var $t14: i256 [unused] + var $t15: i256 [unused] + var $t16: i256 + var $t17: i256 + var $t18: i256 [unused] + var $t19: i256 [unused] + var $t20: i256 [unused] + var $t21: i256 [unused] + var $t22: i256 [unused] + var $t23: i256 [unused] + var $t24: i256 [unused] + var $t25: i256 [unused] + var $t26: i256 [unused] + var $t27: i256 [unused] + var $t28: i256 [unused] + var $t29: i256 [unused] + var $t30: i256 [unused] + var $t31: i256 [unused] + var $t32: i256 [unused] + # live vars: + 0: $t16 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # live vars: $t16 + 1: $t17 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 57896044618658097711785492504343953926634992332820282019728792003956564819967 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -57896044618658097711785492504343953926634992332820282019728792003956564819968 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +[variant baseline] +public fun constants::test_i32(): i32 { + var $t0: i32 [unused] + var $t1: i32 [unused] + var $t2: i32 [unused] + var $t3: i32 [unused] + var $t4: i32 [unused] + var $t5: i32 [unused] + var $t6: i32 [unused] + var $t7: i32 [unused] + var $t8: i32 [unused] + var $t9: i32 [unused] + var $t10: i32 [unused] + var $t11: i32 [unused] + var $t12: i32 [unused] + var $t13: i32 [unused] + var $t14: i32 [unused] + var $t15: i32 [unused] + var $t16: i32 + var $t17: i32 + var $t18: i32 [unused] + var $t19: i32 [unused] + var $t20: i32 [unused] + var $t21: i32 [unused] + var $t22: i32 [unused] + var $t23: i32 [unused] + var $t24: i32 [unused] + var $t25: i32 [unused] + var $t26: i32 [unused] + var $t27: i32 [unused] + var $t28: i32 [unused] + var $t29: i32 [unused] + var $t30: i32 [unused] + var $t31: i32 [unused] + var $t32: i32 [unused] + # live vars: + 0: $t16 := 2147483647 + # live vars: $t16 + 1: $t17 := 2147483647 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -2147483648 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -2147483648 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 2147483647 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -2147483648 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 2147483647 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -2147483648 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +[variant baseline] +public fun constants::test_i64(): i64 { + var $t0: i64 [unused] + var $t1: i64 [unused] + var $t2: i64 [unused] + var $t3: i64 [unused] + var $t4: i64 [unused] + var $t5: i64 [unused] + var $t6: i64 [unused] + var $t7: i64 [unused] + var $t8: i64 [unused] + var $t9: i64 [unused] + var $t10: i64 [unused] + var $t11: i64 [unused] + var $t12: i64 [unused] + var $t13: i64 [unused] + var $t14: i64 [unused] + var $t15: i64 [unused] + var $t16: i64 + var $t17: i64 + var $t18: i64 [unused] + var $t19: i64 [unused] + var $t20: i64 [unused] + var $t21: i64 [unused] + var $t22: i64 [unused] + var $t23: i64 [unused] + var $t24: i64 [unused] + var $t25: i64 [unused] + var $t26: i64 [unused] + var $t27: i64 [unused] + var $t28: i64 [unused] + var $t29: i64 [unused] + var $t30: i64 [unused] + var $t31: i64 [unused] + var $t32: i64 [unused] + # live vars: + 0: $t16 := 9223372036854775807 + # live vars: $t16 + 1: $t17 := 9223372036854775807 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -9223372036854775808 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -9223372036854775808 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 9223372036854775807 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -9223372036854775808 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 9223372036854775807 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -9223372036854775808 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +[variant baseline] +public fun constants::test_i8(): i8 { + var $t0: i8 [unused] + var $t1: i8 [unused] + var $t2: i8 [unused] + var $t3: i8 [unused] + var $t4: i8 [unused] + var $t5: i8 [unused] + var $t6: i8 [unused] + var $t7: i8 [unused] + var $t8: i8 [unused] + var $t9: i8 [unused] + var $t10: i8 [unused] + var $t11: i8 [unused] + var $t12: i8 [unused] + var $t13: i8 [unused] + var $t14: i8 [unused] + var $t15: i8 [unused] + var $t16: i8 + var $t17: i8 + var $t18: i8 [unused] + var $t19: i8 [unused] + var $t20: i8 [unused] + var $t21: i8 [unused] + var $t22: i8 [unused] + var $t23: i8 [unused] + var $t24: i8 [unused] + var $t25: i8 [unused] + var $t26: i8 [unused] + var $t27: i8 [unused] + var $t28: i8 [unused] + var $t29: i8 [unused] + var $t30: i8 [unused] + var $t31: i8 [unused] + var $t32: i8 [unused] + # live vars: + 0: $t16 := 127 + # live vars: $t16 + 1: $t17 := 127 + # live vars: $t16, $t17 + 2: $t16 := +($t16, $t17) + # live vars: $t16 + 3: $t17 := -128 + # live vars: $t16, $t17 + 4: $t16 := +($t16, $t17) + # live vars: $t16 + 5: $t17 := -128 + # live vars: $t16, $t17 + 6: $t16 := +($t16, $t17) + # live vars: $t16 + 7: $t17 := 0 + # live vars: $t16, $t17 + 8: $t16 := +($t16, $t17) + # live vars: $t16 + 9: $t17 := 1 + # live vars: $t16, $t17 + 10: $t16 := +($t16, $t17) + # live vars: $t16 + 11: $t17 := -1 + # live vars: $t16, $t17 + 12: $t16 := +($t16, $t17) + # live vars: $t16 + 13: $t17 := 127 + # live vars: $t16, $t17 + 14: $t16 := +($t16, $t17) + # live vars: $t16 + 15: $t17 := -128 + # live vars: $t16, $t17 + 16: $t16 := +($t16, $t17) + # live vars: $t16 + 17: $t17 := 0 + # live vars: $t16, $t17 + 18: $t16 := +($t16, $t17) + # live vars: $t16 + 19: $t17 := 1 + # live vars: $t16, $t17 + 20: $t16 := +($t16, $t17) + # live vars: $t16 + 21: $t17 := -1 + # live vars: $t16, $t17 + 22: $t16 := +($t16, $t17) + # live vars: $t16 + 23: $t17 := 127 + # live vars: $t16, $t17 + 24: $t16 := +($t16, $t17) + # live vars: $t16 + 25: $t17 := -128 + # live vars: $t16, $t17 + 26: $t16 := +($t16, $t17) + # live vars: $t16 + 27: $t17 := -1 + # live vars: $t16, $t17 + 28: $t16 := +($t16, $t17) + # live vars: $t16 + 29: $t17 := -2 + # live vars: $t16, $t17 + 30: $t16 := +($t16, $t17) + # live vars: $t16 + 31: $t17 := -3 + # live vars: $t16, $t17 + 32: $t16 := +($t16, $t17) + # live vars: $t16 + 33: return $t16 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::constants +// Function definition at index 0 +#[persistent] public fun test_i128(): i128 + ld_i128 170141183460469231731687303715884105727 + ld_i128 170141183460469231731687303715884105727 + add + ld_i128 -170141183460469231731687303715884105728 + add + // @5 + ld_i128 -170141183460469231731687303715884105728 + add + ld_i128 0 + add + ld_i128 1 + // @10 + add + ld_i128 -1 + add + ld_i128 170141183460469231731687303715884105727 + add + // @15 + ld_i128 -170141183460469231731687303715884105728 + add + ld_i128 0 + add + ld_i128 1 + // @20 + add + ld_i128 -1 + add + ld_i128 170141183460469231731687303715884105727 + add + // @25 + ld_i128 -170141183460469231731687303715884105728 + add + ld_i128 -1 + add + ld_i128 -2 + // @30 + add + ld_i128 -3 + add + ret + +// Function definition at index 1 +#[persistent] public fun test_i16(): i16 + ld_i16 32767 + ld_i16 32767 + add + ld_i16 -32768 + add + // @5 + ld_i16 -32768 + add + ld_i16 0 + add + ld_i16 1 + // @10 + add + ld_i16 -1 + add + ld_i16 32767 + add + // @15 + ld_i16 -32768 + add + ld_i16 0 + add + ld_i16 1 + // @20 + add + ld_i16 -1 + add + ld_i16 32767 + add + // @25 + ld_i16 -32768 + add + ld_i16 -1 + add + ld_i16 -2 + // @30 + add + ld_i16 -3 + add + ret + +// Function definition at index 2 +#[persistent] public fun test_i256(): i256 + ld_i256 57896044618658097711785492504343953926634992332820282019728792003956564819967 + ld_i256 57896044618658097711785492504343953926634992332820282019728792003956564819967 + add + ld_i256 -57896044618658097711785492504343953926634992332820282019728792003956564819968 + add + // @5 + ld_i256 -57896044618658097711785492504343953926634992332820282019728792003956564819968 + add + ld_i256 0 + add + ld_i256 1 + // @10 + add + ld_i256 -1 + add + ld_i256 57896044618658097711785492504343953926634992332820282019728792003956564819967 + add + // @15 + ld_i256 -57896044618658097711785492504343953926634992332820282019728792003956564819968 + add + ld_i256 0 + add + ld_i256 1 + // @20 + add + ld_i256 -1 + add + ld_i256 57896044618658097711785492504343953926634992332820282019728792003956564819967 + add + // @25 + ld_i256 -57896044618658097711785492504343953926634992332820282019728792003956564819968 + add + ld_i256 -1 + add + ld_i256 -2 + // @30 + add + ld_i256 -3 + add + ret + +// Function definition at index 3 +#[persistent] public fun test_i32(): i32 + ld_i32 2147483647 + ld_i32 2147483647 + add + ld_i32 -2147483648 + add + // @5 + ld_i32 -2147483648 + add + ld_i32 0 + add + ld_i32 1 + // @10 + add + ld_i32 -1 + add + ld_i32 2147483647 + add + // @15 + ld_i32 -2147483648 + add + ld_i32 0 + add + ld_i32 1 + // @20 + add + ld_i32 -1 + add + ld_i32 2147483647 + add + // @25 + ld_i32 -2147483648 + add + ld_i32 -1 + add + ld_i32 -2 + // @30 + add + ld_i32 -3 + add + ret + +// Function definition at index 4 +#[persistent] public fun test_i64(): i64 + ld_i64 9223372036854775807 + ld_i64 9223372036854775807 + add + ld_i64 -9223372036854775808 + add + // @5 + ld_i64 -9223372036854775808 + add + ld_i64 0 + add + ld_i64 1 + // @10 + add + ld_i64 -1 + add + ld_i64 9223372036854775807 + add + // @15 + ld_i64 -9223372036854775808 + add + ld_i64 0 + add + ld_i64 1 + // @20 + add + ld_i64 -1 + add + ld_i64 9223372036854775807 + add + // @25 + ld_i64 -9223372036854775808 + add + ld_i64 -1 + add + ld_i64 -2 + // @30 + add + ld_i64 -3 + add + ret + +// Function definition at index 5 +#[persistent] public fun test_i8(): i8 + ld_i8 127 + ld_i8 127 + add + ld_i8 -128 + add + // @5 + ld_i8 -128 + add + ld_i8 0 + add + ld_i8 1 + // @10 + add + ld_i8 -1 + add + ld_i8 127 + add + // @15 + ld_i8 -128 + add + ld_i8 0 + add + ld_i8 1 + // @20 + add + ld_i8 -1 + add + ld_i8 127 + add + // @25 + ld_i8 -128 + add + ld_i8 -1 + add + ld_i8 -2 + // @30 + add + ld_i8 -3 + add + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.move new file mode 100644 index 00000000000..dee088cf923 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_constants.move @@ -0,0 +1,152 @@ +module 0x42::constants { + + const V1_8: i8 = 0; // constant with annotated type but non-annotated value + const V2_8: i8 = 1; // constant with annotated type but non-annotated value + const V3_8: i8 = 1i8; // constant with annotated type and annotated value + const V4_8: i8 = -1; // constant with annotated type but non-annotated negative value + const V5_8: i8 = -1i8; // constant with annotated type and annotated negative value + const V6_8: i8 = 127; // constant with annotated type but non-annotated, max value + const V7_8: i8 = 127i8; // constant with annotated type and annotated, max value + const V8_8: i8 = -128; // constant with annotated type but non-annotated, min value + const V9_8: i8 = -128i8; // constant with annotated type and annotated, min value + + const V1_16: i16 = 0; // constant with annotated type but non-annotated value + const V2_16: i16 = 1; // constant with annotated type but non-annotated value + const V3_16: i16 = 1i16; // constant with annotated type and annotated value + const V4_16: i16 = -1; // constant with annotated type but non-annotated negative value + const V5_16: i16 = -1i16; // constant with annotated type and annotated negative value + const V6_16: i16 = 32767; // constant with annotated type but non-annotated, max value + const V7_16: i16 = 32767i16; // constant with annotated type and annotated, max value + const V8_16: i16 = -32768; // constant with annotated type but non-annotated, min value + const V9_16: i16 = -32768i16; // constant with annotated type and annotated, min value + + const V1_32: i32 = 0; // constant with annotated type but non-annotated value + const V2_32: i32 = 1; // constant with annotated type but non-annotated value + const V3_32: i32 = 1i32; // constant with annotated type and annotated value + const V4_32: i32 = -1; // constant with annotated type but non-annotated negative value + const V5_32: i32 = -1i32; // constant with annotated type and annotated negative value + const V6_32: i32 = 2147483647; // constant with annotated type but non-annotated, max value + const V7_32: i32 = 2147483647i32; // constant with annotated type and annotated, max value + const V8_32: i32 = -2147483648; // constant with annotated type but non-annotated, min value + const V9_32: i32 = -2147483648i32; // constant with annotated type and annotated, min value + + const V1_64: i64 = 0; // constant with annotated type but non-annotated value + const V2_64: i64 = 1; // constant with annotated type but non-annotated value + const V3_64: i64 = 1i64; // constant with annotated type and annotated value + const V4_64: i64 = -1; // constant with annotated type but non-annotated negative value + const V5_64: i64 = -1i64; // constant with annotated type and annotated negative value + const V6_64: i64 = 9223372036854775807; // constant with annotated type but non-annotated, max value + const V7_64: i64 = 9223372036854775807i64; // constant with annotated type and annotated, max value + const V8_64: i64 = -9223372036854775808; // constant with annotated type but non-annotated, min value + const V9_64: i64 = -9223372036854775808i64; // constant with annotated type and annotated, min value + + const V1_128: i128 = 0; // constant with annotated type but non-annotated value + const V2_128: i128 = 1; // constant with annotated type but non-annotated value + const V3_128: i128 = 1i128; // constant with annotated type and annotated value + const V4_128: i128 = -1; // constant with annotated type but non-annotated negative value + const V5_128: i128 = -1i128; // constant with annotated type and annotated negative value + const V6_128: i128 = 170141183460469231731687303715884105727; // constant with annotated type but non-annotated, max value + const V7_128: i128 = 170141183460469231731687303715884105727i128; // constant with annotated type and annotated, max value + const V8_128: i128 = -170141183460469231731687303715884105728; // constant with annotated type but non-annotated, min value + const V9_128: i128 = -170141183460469231731687303715884105728i128; // constant with annotated type and annotated, min value + + const V1_256: i256 = 0; // constant with annotated type but non-annotated value + const V2_256: i256 = 1; // constant with annotated type but non-annotated value + const V3_256: i256 = 1i256; // constant with annotated type and annotated value + const V4_256: i256 = -1; // constant with annotated type but non-annotated negative value + const V5_256: i256 = -1i256; // constant with annotated type and annotated negative value + const V6_256: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967; // constant with annotated type but non-annotated, max value + const V7_256: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // constant with annotated type and annotated, max value + const V8_256: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968; // constant with annotated type but non-annotated, min value + const V9_256: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; // constant with annotated type and annotated, min value + + public fun test_i8() : i8 { + let a_ann = 0i8; // constant with non-annotated type but annotated value + let b_ann = 1i8; // constant with non-annotated type but annotated value + let c_ann = -1i8; // constant with non-annotated type but annotated, negative value + let d_ann = 127i8; // constant with non-annotated type but annotated, max value + let e_ann = -128i8; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 127; // constant with non-annotated type and non-annotated, max value + let e = -128; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_8 + V2_8 + V3_8 + V4_8 + V5_8 + V6_8 + V7_8 + V8_8 + V9_8 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + + public fun test_i16() : i16 { + let a_ann = 0i16; // constant with non-annotated type but annotated value + let b_ann = 1i16; // constant with non-annotated type but annotated value + let c_ann = -1i16; // constant with non-annotated type but annotated, negative value + let d_ann = 32767i16; // constant with non-annotated type but annotated, max value + let e_ann = -32768i16; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 32767; // constant with non-annotated type and non-annotated, max value + let e = -32768; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_16 + V2_16 + V3_16 + V4_16 + V5_16 + V6_16 + V7_16 + V8_16 + V9_16 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + + public fun test_i32() : i32 { + let a_ann = 0i32; // constant with non-annotated type but annotated value + let b_ann = 1i32; // constant with non-annotated type but annotated value + let c_ann = -1i32; // constant with non-annotated type but annotated, negative value + let d_ann = 2147483647i32; // constant with non-annotated type but annotated, max value + let e_ann = -2147483648i32; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 2147483647; // constant with non-annotated type and non-annotated, max value + let e = -2147483648; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_32 + V2_32 + V3_32 + V4_32 + V5_32 + V6_32 + V7_32 + V8_32 + V9_32 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + + public fun test_i64() : i64 { + let a_ann = 0i64; // constant with non-annotated type but annotated value + let b_ann = 1i64; // constant with non-annotated type but annotated value + let c_ann = -1i64; // constant with non-annotated type but annotated, negative value + let d_ann = 9223372036854775807i64; // constant with non-annotated type but annotated, max value + let e_ann = -9223372036854775808i64; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 9223372036854775807; // constant with non-annotated type and non-annotated, max value + let e = -9223372036854775808; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_64 + V2_64 + V3_64 + V4_64 + V5_64 + V6_64 + V7_64 + V8_64 + V9_64 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + + public fun test_i128() : i128 { + let a_ann = 0i128; // constant with non-annotated type but annotated value + let b_ann = 1i128; // constant with non-annotated type but annotated value + let c_ann = -1i128; // constant with non-annotated type but annotated, negative value + let d_ann = 170141183460469231731687303715884105727i128; // constant with non-annotated type but annotated, max value + let e_ann = -170141183460469231731687303715884105728i128; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 170141183460469231731687303715884105727; // constant with non-annotated type and non-annotated, max value + let e = -170141183460469231731687303715884105728; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_128 + V2_128 + V3_128 + V4_128 + V5_128 + V6_128 + V7_128 + V8_128 + V9_128 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } + + public fun test_i256() : i256 { + let a_ann = 0i256; // constant with non-annotated type but annotated value + let b_ann = 1i256; // constant with non-annotated type but annotated value + let c_ann = -1i256; // constant with non-annotated type but annotated, negative value + let d_ann = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // constant with non-annotated type but annotated, max value + let e_ann = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; // constant with non-annotated type but annotated, min value + let a = 0; // constant with non-annotated type and non-annotated value + let b = 1; // constant with non-annotated type and non-annotated value + let c = -1; // constant with non-annotated type and non-annotated, negative value + let d = 57896044618658097711785492504343953926634992332820282019728792003956564819967; // constant with non-annotated type and non-annotated, max value + let e = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; // constant with non-annotated type and non-annotated, min value + let (x, y, z) = (-1, -2, -3); // constants in tuple + V1_256 + V2_256 + V3_256 + V4_256 + V5_256 + V6_256 + V7_256 + V8_256 + V9_256 + a_ann + b_ann + c_ann + d_ann + e_ann + a + b + c + d + e + x + y + z + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.exp new file mode 100644 index 00000000000..28dd8b17ff7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.exp @@ -0,0 +1,1853 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_control_flow { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(x: i64,y: i64): i64 { + if Or(Gt(x, y), Eq(x, y)) { + x + } else { + y + } + } + private fun test2(x: i128,y: i128): i128 { + if Or(Gt(x, y), Eq(x, y)) { + x + } else { + y + } + } + private fun test3(x: i64,y: i64): i64 { + loop { + if Not(Eq(x, 0)) { + { + let y: i64 = Add(x, 1); + { + let z: i64 = Sub(x, 1); + { + let res: i64 = if Lt(y, z) { + y + } else { + if Lt(z, y) { + z + } else { + break + } + }; + x: i64 = Mul(x, 2); + Tuple() + } + } + } + } else { + break + } + }; + x + } + private fun test4(x: i128,y: i128): i128 { + loop { + if Not(Eq(x, 0)) { + { + let y: i128 = Add(x, 1); + { + let z: i128 = Sub(x, 1); + { + let res: i128 = if Lt(y, z) { + y + } else { + if Lt(z, y) { + z + } else { + break + } + }; + x: i128 = Mul(x, 2); + Tuple() + } + } + } + } else { + break + } + }; + x + } +} // end 0x42::valid_control_flow + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_control_flow { + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test1(x: i64, y: i64): i64 { + if (x > y || x == y) x else y + } + fun test2(x: i128, y: i128): i128 { + if (x > y || x == y) x else y + } + fun test3(x: i64, y: i64): i64 { + while (!(x == 0i64)) { + let y = x + 1i64; + let z = x - 1i64; + let res = if (y < z) y else if (z < y) z else break; + x = x * 2i64; + }; + x + } + fun test4(x: i128, y: i128): i128 { + while (!(x == 0i128)) { + let y = x + 1i128; + let z = x - 1i128; + let res = if (y < z) y else if (z < y) z else break; + x = x * 2i128; + }; + x + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_control_flow::test1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + 0: $t5 := infer($t0) + 1: $t4 := >($t5, $t1) + 2: if ($t4) goto 3 else goto 6 + 3: label L0 + 4: $t3 := true + 5: goto 9 + 6: label L1 + 7: $t6 := infer($t0) + 8: $t3 := ==($t6, $t1) + 9: label L2 + 10: if ($t3) goto 11 else goto 14 + 11: label L3 + 12: $t2 := infer($t0) + 13: goto 16 + 14: label L4 + 15: $t2 := infer($t1) + 16: label L5 + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + 0: $t5 := infer($t0) + 1: $t4 := >($t5, $t1) + 2: if ($t4) goto 3 else goto 6 + 3: label L0 + 4: $t3 := true + 5: goto 9 + 6: label L1 + 7: $t6 := infer($t0) + 8: $t3 := ==($t6, $t1) + 9: label L2 + 10: if ($t3) goto 11 else goto 14 + 11: label L3 + 12: $t2 := infer($t0) + 13: goto 16 + 14: label L4 + 15: $t2 := infer($t1) + 16: label L5 + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test3($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: bool + var $t15: i64 + var $t16: bool + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + 0: label L0 + 1: $t5 := infer($t0) + 2: $t6 := 0 + 3: $t4 := ==($t5, $t6) + 4: $t3 := !($t4) + 5: if ($t3) goto 6 else goto 35 + 6: label L2 + 7: $t8 := infer($t0) + 8: $t9 := 1 + 9: $t7 := +($t8, $t9) + 10: $t11 := infer($t0) + 11: $t12 := 1 + 12: $t10 := -($t11, $t12) + 13: $t15 := infer($t7) + 14: $t14 := <($t15, $t10) + 15: if ($t14) goto 16 else goto 19 + 16: label L5 + 17: $t13 := infer($t7) + 18: goto 29 + 19: label L6 + 20: $t17 := infer($t10) + 21: $t16 := <($t17, $t7) + 22: if ($t16) goto 23 else goto 26 + 23: label L8 + 24: $t13 := infer($t10) + 25: goto 28 + 26: label L9 + 27: goto 39 + 28: label L10 + 29: label L7 + 30: $t19 := infer($t0) + 31: $t20 := 2 + 32: $t18 := *($t19, $t20) + 33: $t0 := infer($t18) + 34: goto 37 + 35: label L3 + 36: goto 39 + 37: label L4 + 38: goto 0 + 39: label L1 + 40: $t2 := infer($t0) + 41: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test4($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: bool + var $t15: i128 + var $t16: bool + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + 0: label L0 + 1: $t5 := infer($t0) + 2: $t6 := 0 + 3: $t4 := ==($t5, $t6) + 4: $t3 := !($t4) + 5: if ($t3) goto 6 else goto 35 + 6: label L2 + 7: $t8 := infer($t0) + 8: $t9 := 1 + 9: $t7 := +($t8, $t9) + 10: $t11 := infer($t0) + 11: $t12 := 1 + 12: $t10 := -($t11, $t12) + 13: $t15 := infer($t7) + 14: $t14 := <($t15, $t10) + 15: if ($t14) goto 16 else goto 19 + 16: label L5 + 17: $t13 := infer($t7) + 18: goto 29 + 19: label L6 + 20: $t17 := infer($t10) + 21: $t16 := <($t17, $t7) + 22: if ($t16) goto 23 else goto 26 + 23: label L8 + 24: $t13 := infer($t10) + 25: goto 28 + 26: label L9 + 27: goto 39 + 28: label L10 + 29: label L7 + 30: $t19 := infer($t0) + 31: $t20 := 2 + 32: $t18 := *($t19, $t20) + 33: $t0 := infer($t18) + 34: goto 37 + 35: label L3 + 36: goto 39 + 37: label L4 + 38: goto 0 + 39: label L1 + 40: $t2 := infer($t0) + 41: return $t2 +} + + +Diagnostics: +warning: Unused value of parameter `y`. Consider removing the parameter, or prefixing with an underscore (e.g., `_y`), or binding to `_` + ┌─ tests/integers/signed/valid_control_flow.move:42:23 + │ +42 │ fun test3(x: i64, y: i64) : i64 { + │ ^ + +warning: This assignment/binding to the left-hand-side variable `res` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_res`), or renaming to `_` + ┌─ tests/integers/signed/valid_control_flow.move:47:26 + │ +47 │ if (y < z) { y } + │ ^ + +warning: This assignment/binding to the left-hand-side variable `res` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_res`), or renaming to `_` + ┌─ tests/integers/signed/valid_control_flow.move:48:31 + │ +48 │ else if (z < y) { z } + │ ^ + +warning: Unused value of parameter `y`. Consider removing the parameter, or prefixing with an underscore (e.g., `_y`), or binding to `_` + ┌─ tests/integers/signed/valid_control_flow.move:55:24 + │ +55 │ fun test4(x: i128, y: i128) : i128 { + │ ^ + +warning: This assignment/binding to the left-hand-side variable `res` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_res`), or renaming to `_` + ┌─ tests/integers/signed/valid_control_flow.move:60:26 + │ +60 │ if (y < z) { y } + │ ^ + +warning: This assignment/binding to the left-hand-side variable `res` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_res`), or renaming to `_` + ┌─ tests/integers/signed/valid_control_flow.move:61:31 + │ +61 │ else if (z < y) { z } + │ ^ + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_control_flow::test1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t5 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 1: $t4 := >($t5, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 2: if ($t4) goto 3 else goto 6 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 3: label L0 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 4: $t3 := true + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 5: goto 9 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 6: label L1 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 7: $t6 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t6 + # refs: [] + # + 8: $t3 := ==($t6, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 10: if ($t3) goto 11 else goto 14 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 11: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: $t2 := infer($t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 13: goto 16 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 14: label L4 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 15: $t2 := infer($t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 16: label L5 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t5 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 1: $t4 := >($t5, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 2: if ($t4) goto 3 else goto 6 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 3: label L0 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 4: $t3 := true + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 5: goto 9 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 6: label L1 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 7: $t6 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t6 + # refs: [] + # + 8: $t3 := ==($t6, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 10: if ($t3) goto 11 else goto 14 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 11: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: $t2 := infer($t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 13: goto 16 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 14: label L4 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 15: $t2 := infer($t1) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 16: label L5 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test3($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: bool + var $t15: i64 + var $t16: bool + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: label L0 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 1: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 2: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 3: $t4 := ==($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t3 := !($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t3 + # refs: [] + # + 5: if ($t3) goto 6 else goto 35 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 6: label L2 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 7: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t8 + # refs: [] + # + 8: $t9 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t8, $t9 + # refs: [] + # + 9: $t7 := +($t8, $t9) + # abort state: {returns,aborts} + # live vars: $t0, $t7 + # refs: [] + # + 10: $t11 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11 + # refs: [] + # + 11: $t12 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11, $t12 + # refs: [] + # + 12: $t10 := -($t11, $t12) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 13: $t15 := infer($t7) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t15 + # refs: [] + # + 14: $t14 := <($t15, $t10) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t14 + # refs: [] + # + 15: if ($t14) goto 16 else goto 19 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 16: label L5 + # abort state: {returns,aborts} + # live vars: $t0, $t7 + # refs: [] + # + 17: $t13 := infer($t7) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 18: goto 29 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 19: label L6 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 20: $t17 := infer($t10) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t17 + # refs: [] + # + 21: $t16 := <($t17, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t10, $t16 + # refs: [] + # + 22: if ($t16) goto 23 else goto 26 + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 23: label L8 + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 24: $t13 := infer($t10) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 25: goto 28 + # abort state: {returns} + # live vars: $t0, $t10 + # refs: [] + # + 26: label L9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 27: goto 39 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 28: label L10 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 29: label L7 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 30: $t19 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t19 + # refs: [] + # + 31: $t20 := 2 + # abort state: {returns,aborts} + # live vars: $t19, $t20 + # refs: [] + # + 32: $t18 := *($t19, $t20) + # abort state: {returns,aborts} + # live vars: $t18 + # refs: [] + # + 33: $t0 := infer($t18) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 34: goto 37 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 35: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 36: goto 39 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 37: label L4 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 38: goto 0 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 39: label L1 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 40: $t2 := infer($t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 41: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test4($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: bool + var $t15: i128 + var $t16: bool + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: label L0 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 1: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 2: $t6 := 0 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 3: $t4 := ==($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t3 := !($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t3 + # refs: [] + # + 5: if ($t3) goto 6 else goto 35 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 6: label L2 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 7: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t8 + # refs: [] + # + 8: $t9 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t8, $t9 + # refs: [] + # + 9: $t7 := +($t8, $t9) + # abort state: {returns,aborts} + # live vars: $t0, $t7 + # refs: [] + # + 10: $t11 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11 + # refs: [] + # + 11: $t12 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11, $t12 + # refs: [] + # + 12: $t10 := -($t11, $t12) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 13: $t15 := infer($t7) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t15 + # refs: [] + # + 14: $t14 := <($t15, $t10) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t14 + # refs: [] + # + 15: if ($t14) goto 16 else goto 19 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 16: label L5 + # abort state: {returns,aborts} + # live vars: $t0, $t7 + # refs: [] + # + 17: $t13 := infer($t7) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 18: goto 29 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 19: label L6 + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10 + # refs: [] + # + 20: $t17 := infer($t10) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t10, $t17 + # refs: [] + # + 21: $t16 := <($t17, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t10, $t16 + # refs: [] + # + 22: if ($t16) goto 23 else goto 26 + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 23: label L8 + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 24: $t13 := infer($t10) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 25: goto 28 + # abort state: {returns} + # live vars: $t0, $t10 + # refs: [] + # + 26: label L9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 27: goto 39 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 28: label L10 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 29: label L7 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 30: $t19 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t19 + # refs: [] + # + 31: $t20 := 2 + # abort state: {returns,aborts} + # live vars: $t19, $t20 + # refs: [] + # + 32: $t18 := *($t19, $t20) + # abort state: {returns,aborts} + # live vars: $t18 + # refs: [] + # + 33: $t0 := infer($t18) + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 34: goto 37 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 35: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 36: goto 39 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 37: label L4 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 38: goto 0 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 39: label L1 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 40: $t2 := infer($t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 41: return $t2 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_control_flow { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(x: i64,y: i64): i64 { + if Or(Gt(x, y), Eq(x, y)) { + x + } else { + y + } + } + private fun test2(x: i128,y: i128): i128 { + if Or(Gt(x, y), Eq(x, y)) { + x + } else { + y + } + } + private fun test3(x: i64,y: i64): i64 { + loop { + if Not(Eq(x, 0)) { + { + let y: i64 = Add(x, 1); + { + let z: i64 = Sub(x, 1); + { + let res: i64 = if Lt(y, z) { + y + } else { + if Lt(z, y) { + z + } else { + break + } + }; + x: i64 = Mul(x, 2); + Tuple() + } + } + } + } else { + break + } + }; + x + } + private fun test4(x: i128,y: i128): i128 { + loop { + if Not(Eq(x, 0)) { + { + let y: i128 = Add(x, 1); + { + let z: i128 = Sub(x, 1); + { + let res: i128 = if Lt(y, z) { + y + } else { + if Lt(z, y) { + z + } else { + break + } + }; + x: i128 = Mul(x, 2); + Tuple() + } + } + } + } else { + break + } + }; + x + } +} // end 0x42::valid_control_flow + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_control_flow::test1($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + 0: $t5 := infer($t0) + 1: $t4 := >($t5, $t1) + 2: if ($t4) goto 3 else goto 6 + 3: label L0 + 4: $t3 := true + 5: goto 9 + 6: label L1 + 7: $t6 := infer($t0) + 8: $t3 := ==($t6, $t1) + 9: label L2 + 10: if ($t3) goto 11 else goto 14 + 11: label L3 + 12: $t2 := infer($t0) + 13: goto 16 + 14: label L4 + 15: $t2 := infer($t1) + 16: label L5 + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test2($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + 0: $t5 := infer($t0) + 1: $t4 := >($t5, $t1) + 2: if ($t4) goto 3 else goto 6 + 3: label L0 + 4: $t3 := true + 5: goto 9 + 6: label L1 + 7: $t6 := infer($t0) + 8: $t3 := ==($t6, $t1) + 9: label L2 + 10: if ($t3) goto 11 else goto 14 + 11: label L3 + 12: $t2 := infer($t0) + 13: goto 16 + 14: label L4 + 15: $t2 := infer($t1) + 16: label L5 + 17: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test3($t0: i64, $t1: i64): i64 { + var $t2: i64 + var $t3: bool + var $t4: bool + var $t5: i64 + var $t6: i64 + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: i64 + var $t13: i64 + var $t14: bool + var $t15: i64 + var $t16: bool + var $t17: i64 + var $t18: i64 + var $t19: i64 + var $t20: i64 + 0: label L0 + 1: $t5 := infer($t0) + 2: $t6 := 0 + 3: $t4 := ==($t5, $t6) + 4: $t3 := !($t4) + 5: if ($t3) goto 6 else goto 35 + 6: label L2 + 7: $t8 := infer($t0) + 8: $t9 := 1 + 9: $t7 := +($t8, $t9) + 10: $t11 := infer($t0) + 11: $t12 := 1 + 12: $t10 := -($t11, $t12) + 13: $t15 := infer($t7) + 14: $t14 := <($t15, $t10) + 15: if ($t14) goto 16 else goto 19 + 16: label L5 + 17: $t13 := infer($t7) + 18: goto 29 + 19: label L6 + 20: $t17 := infer($t10) + 21: $t16 := <($t17, $t7) + 22: if ($t16) goto 23 else goto 26 + 23: label L8 + 24: $t13 := infer($t10) + 25: goto 28 + 26: label L9 + 27: goto 39 + 28: label L10 + 29: label L7 + 30: $t19 := infer($t0) + 31: $t20 := 2 + 32: $t18 := *($t19, $t20) + 33: $t0 := infer($t18) + 34: goto 37 + 35: label L3 + 36: goto 39 + 37: label L4 + 38: goto 0 + 39: label L1 + 40: $t2 := infer($t0) + 41: return $t2 +} + + +[variant baseline] +fun valid_control_flow::test4($t0: i128, $t1: i128): i128 { + var $t2: i128 + var $t3: bool + var $t4: bool + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: i128 + var $t13: i128 + var $t14: bool + var $t15: i128 + var $t16: bool + var $t17: i128 + var $t18: i128 + var $t19: i128 + var $t20: i128 + 0: label L0 + 1: $t5 := infer($t0) + 2: $t6 := 0 + 3: $t4 := ==($t5, $t6) + 4: $t3 := !($t4) + 5: if ($t3) goto 6 else goto 35 + 6: label L2 + 7: $t8 := infer($t0) + 8: $t9 := 1 + 9: $t7 := +($t8, $t9) + 10: $t11 := infer($t0) + 11: $t12 := 1 + 12: $t10 := -($t11, $t12) + 13: $t15 := infer($t7) + 14: $t14 := <($t15, $t10) + 15: if ($t14) goto 16 else goto 19 + 16: label L5 + 17: $t13 := infer($t7) + 18: goto 29 + 19: label L6 + 20: $t17 := infer($t10) + 21: $t16 := <($t17, $t7) + 22: if ($t16) goto 23 else goto 26 + 23: label L8 + 24: $t13 := infer($t10) + 25: goto 28 + 26: label L9 + 27: goto 39 + 28: label L10 + 29: label L7 + 30: $t19 := infer($t0) + 31: $t20 := 2 + 32: $t18 := *($t19, $t20) + 33: $t0 := infer($t18) + 34: goto 37 + 35: label L3 + 36: goto 39 + 37: label L4 + 38: goto 0 + 39: label L1 + 40: $t2 := infer($t0) + 41: return $t2 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_control_flow::test1($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: bool [unused] + var $t4: bool + var $t5: i64 + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 1: $t4 := >($t5, $t1) + # live vars: $t0, $t1, $t4 + 2: if ($t4) goto 3 else goto 13 + # live vars: $t0, $t1 + 3: label L0 + # live vars: $t0, $t1 + 4: $t4 := true + # live vars: $t0, $t1, $t4 + 5: label L2 + # live vars: $t0, $t1, $t4 + 6: if ($t4) goto 7 else goto 10 + # live vars: $t0, $t1 + 7: label L3 + # live vars: $t0 + 8: $t5 := move($t0) + # live vars: $t5 + 9: return $t5 + # live vars: $t0, $t1 + 10: label L4 + # live vars: $t1 + 11: $t5 := move($t1) + # live vars: $t5 + 12: return $t5 + # live vars: $t0, $t1 + 13: label L1 + # live vars: $t0, $t1 + 14: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 15: $t4 := ==($t5, $t1) + # live vars: $t0, $t1, $t4 + 16: goto 5 +} + + +[variant baseline] +fun valid_control_flow::test2($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: bool [unused] + var $t4: bool + var $t5: i128 + var $t6: i128 [unused] + # live vars: $t0, $t1 + 0: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 1: $t4 := >($t5, $t1) + # live vars: $t0, $t1, $t4 + 2: if ($t4) goto 3 else goto 13 + # live vars: $t0, $t1 + 3: label L0 + # live vars: $t0, $t1 + 4: $t4 := true + # live vars: $t0, $t1, $t4 + 5: label L2 + # live vars: $t0, $t1, $t4 + 6: if ($t4) goto 7 else goto 10 + # live vars: $t0, $t1 + 7: label L3 + # live vars: $t0 + 8: $t5 := move($t0) + # live vars: $t5 + 9: return $t5 + # live vars: $t0, $t1 + 10: label L4 + # live vars: $t1 + 11: $t5 := move($t1) + # live vars: $t5 + 12: return $t5 + # live vars: $t0, $t1 + 13: label L1 + # live vars: $t0, $t1 + 14: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 15: $t4 := ==($t5, $t1) + # live vars: $t0, $t1, $t4 + 16: goto 5 +} + + +[variant baseline] +fun valid_control_flow::test3($t0: i64, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: bool [unused] + var $t4: bool + var $t5: i64 [unused] + var $t6: i64 + var $t7: i64 [unused] + var $t8: i64 [unused] + var $t9: i64 [unused] + var $t10: i64 [unused] + var $t11: i64 [unused] + var $t12: i64 + var $t13: i64 [unused] + var $t14: bool [unused] + var $t15: i64 [unused] + var $t16: bool [unused] + var $t17: i64 [unused] + var $t18: i64 [unused] + var $t19: i64 [unused] + var $t20: i64 + # live vars: $t0, $t1 + 0: label L0 + # live vars: $t0 + 1: $t1 := copy($t0) + # live vars: $t0, $t1 + 2: $t6 := 0 + # live vars: $t0, $t1, $t6 + 3: $t4 := ==($t1, $t6) + # live vars: $t0, $t4 + 4: $t4 := !($t4) + # live vars: $t0, $t4 + 5: if ($t4) goto 8 else goto 6 + # live vars: $t0 + 6: label L9 + # live vars: $t0 + 7: goto 33 + # live vars: $t0 + 8: label L2 + # live vars: $t0 + 9: $t1 := copy($t0) + # live vars: $t0, $t1 + 10: $t6 := 1 + # live vars: $t0, $t1, $t6 + 11: $t1 := +($t1, $t6) + # live vars: $t0, $t1 + 12: $t6 := copy($t0) + # live vars: $t0, $t1, $t6 + 13: $t12 := 1 + # live vars: $t0, $t1, $t6, $t12 + 14: $t6 := -($t6, $t12) + # live vars: $t0, $t1, $t6 + 15: $t12 := copy($t1) + # live vars: $t0, $t1, $t6, $t12 + 16: $t4 := <($t12, $t6) + # live vars: $t0, $t1, $t4, $t6 + 17: if ($t4) goto 18 else goto 25 + # live vars: $t0, $t1, $t6 + 18: label L5 + # live vars: $t0 + 19: label L7 + # live vars: $t0 + 20: $t12 := move($t0) + # live vars: $t12 + 21: $t20 := 2 + # live vars: $t12, $t20 + 22: $t12 := *($t12, $t20) + # live vars: $t12 + 23: $t0 := move($t12) + # live vars: $t0 + 24: goto 0 + # live vars: $t0, $t1, $t6 + 25: label L6 + # live vars: $t0, $t1, $t6 + 26: $t6 := copy($t6) + # live vars: $t0, $t1, $t6 + 27: $t4 := <($t6, $t1) + # live vars: $t0, $t4 + 28: if ($t4) goto 31 else goto 29 + # live vars: $t0 + 29: label L10 + # live vars: $t0 + 30: goto 33 + # live vars: $t0 + 31: label L8 + # live vars: $t0 + 32: goto 19 + # live vars: $t0 + 33: label L1 + # live vars: $t0 + 34: return $t0 +} + + +[variant baseline] +fun valid_control_flow::test4($t0: i128, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: bool [unused] + var $t4: bool + var $t5: i128 [unused] + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + var $t11: i128 [unused] + var $t12: i128 + var $t13: i128 [unused] + var $t14: bool [unused] + var $t15: i128 [unused] + var $t16: bool [unused] + var $t17: i128 [unused] + var $t18: i128 [unused] + var $t19: i128 [unused] + var $t20: i128 + # live vars: $t0, $t1 + 0: label L0 + # live vars: $t0 + 1: $t1 := copy($t0) + # live vars: $t0, $t1 + 2: $t6 := 0 + # live vars: $t0, $t1, $t6 + 3: $t4 := ==($t1, $t6) + # live vars: $t0, $t4 + 4: $t4 := !($t4) + # live vars: $t0, $t4 + 5: if ($t4) goto 8 else goto 6 + # live vars: $t0 + 6: label L9 + # live vars: $t0 + 7: goto 33 + # live vars: $t0 + 8: label L2 + # live vars: $t0 + 9: $t1 := copy($t0) + # live vars: $t0, $t1 + 10: $t6 := 1 + # live vars: $t0, $t1, $t6 + 11: $t1 := +($t1, $t6) + # live vars: $t0, $t1 + 12: $t6 := copy($t0) + # live vars: $t0, $t1, $t6 + 13: $t12 := 1 + # live vars: $t0, $t1, $t6, $t12 + 14: $t6 := -($t6, $t12) + # live vars: $t0, $t1, $t6 + 15: $t12 := copy($t1) + # live vars: $t0, $t1, $t6, $t12 + 16: $t4 := <($t12, $t6) + # live vars: $t0, $t1, $t4, $t6 + 17: if ($t4) goto 18 else goto 25 + # live vars: $t0, $t1, $t6 + 18: label L5 + # live vars: $t0 + 19: label L7 + # live vars: $t0 + 20: $t12 := move($t0) + # live vars: $t12 + 21: $t20 := 2 + # live vars: $t12, $t20 + 22: $t12 := *($t12, $t20) + # live vars: $t12 + 23: $t0 := move($t12) + # live vars: $t0 + 24: goto 0 + # live vars: $t0, $t1, $t6 + 25: label L6 + # live vars: $t0, $t1, $t6 + 26: $t6 := copy($t6) + # live vars: $t0, $t1, $t6 + 27: $t4 := <($t6, $t1) + # live vars: $t0, $t4 + 28: if ($t4) goto 31 else goto 29 + # live vars: $t0 + 29: label L10 + # live vars: $t0 + 30: goto 33 + # live vars: $t0 + 31: label L8 + # live vars: $t0 + 32: goto 19 + # live vars: $t0 + 33: label L1 + # live vars: $t0 + 34: return $t0 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_control_flow +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test1(l0: i64, l1: i64): i64 + local l2: bool + copy_loc l0 + copy_loc l1 + gt + br_false l0 + ld_true + // @5 + st_loc l2 +l2: move_loc l2 + br_false l1 + move_loc l0 + ret + // @10 +l1: move_loc l1 + ret +l0: copy_loc l0 + copy_loc l1 + eq + // @15 + st_loc l2 + branch l2 + +// Function definition at index 1 +fun test2(l0: i128, l1: i128): i128 + local l2: bool + copy_loc l0 + copy_loc l1 + gt + br_false l0 + ld_true + // @5 + st_loc l2 +l2: move_loc l2 + br_false l1 + move_loc l0 + ret + // @10 +l1: move_loc l1 + ret +l0: copy_loc l0 + copy_loc l1 + eq + // @15 + st_loc l2 + branch l2 + +// Function definition at index 2 +fun test3(l0: i64, l1: i64): i64 + local l2: i64 +l3: copy_loc l0 + ld_i64 0 + eq + br_false l0 + branch l1 + // @5 +l0: copy_loc l0 + ld_i64 1 + add + st_loc l1 + copy_loc l0 + // @10 + ld_i64 1 + sub + st_loc l2 + copy_loc l1 + copy_loc l2 + // @15 + lt + br_false l2 +l5: move_loc l0 + ld_i64 2 + mul + // @20 + st_loc l0 + branch l3 +l2: copy_loc l2 + move_loc l1 + lt + // @25 + br_true l4 + branch l1 +l4: branch l5 +l1: move_loc l0 + ret + +// Function definition at index 3 +fun test4(l0: i128, l1: i128): i128 + local l2: i128 +l3: copy_loc l0 + ld_i128 0 + eq + br_false l0 + branch l1 + // @5 +l0: copy_loc l0 + ld_i128 1 + add + st_loc l1 + copy_loc l0 + // @10 + ld_i128 1 + sub + st_loc l2 + copy_loc l1 + copy_loc l2 + // @15 + lt + br_false l2 +l5: move_loc l0 + ld_i128 2 + mul + // @20 + st_loc l0 + branch l3 +l2: copy_loc l2 + move_loc l1 + lt + // @25 + br_true l4 + branch l1 +l4: branch l5 +l1: move_loc l0 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.move new file mode 100644 index 00000000000..9507a93ce8e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_control_flow.move @@ -0,0 +1,67 @@ +module 0x42::valid_control_flow { + struct S1 has copy, drop { x: u64, y: i64, z: i128 } + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } + + struct S3 has copy, drop { x: T, y: S1, z: S2 } + + enum E1 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test1(x: i64, y: i64) : i64 { + if (x > y || x == y) { + x + } else { + y + } + } + + fun test2(x: i128, y: i128) : i128 { + if (x > y || x == y) { + x + } else { + y + } + } + + fun test3(x: i64, y: i64) : i64 { + while (! (x == 0)) { + let y = x + 1; + let z = x - 1; + let res = + if (y < z) { y } + else if (z < y) { z } + else break; + x = x * 2; + }; + x + } + + fun test4(x: i128, y: i128) : i128 { + while (! (x == 0)) { + let y = x + 1; + let z = x - 1; + let res = + if (y < z) { y } + else if (z < y) { z } + else break; + x = x * 2; + }; + x + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.exp new file mode 100644 index 00000000000..3a01b0f6514 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.exp @@ -0,0 +1,2429 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_fv { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(fv1: |i64|i64 has copy + drop,x: i64): i64 { + { + let fv2: |i64|i64 has copy + drop = closure#0valid_fv::__lambda__1__test1(); + (fv1)(x) + } + } + private fun test10(fv: |E2|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let e: E2 = pack valid_fv::E2::V2(s2); + (fv)(e) + } + } + } + } + private fun test11(fv: |E3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let s3: S3 = pack valid_fv::S3(-1, s1, s2); + { + let e: E3 = pack valid_fv::E3::V3(s3); + (fv)(e) + } + } + } + } + } + private fun test12(fv: |E3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let s3: S3 = pack valid_fv::S3(-1, s1, s2); + { + let e: E3 = pack valid_fv::E3::V3(s3); + (fv)(e) + } + } + } + } + } + private fun test2(fv1: |i128|i128 has copy + drop,x: i128): i128 { + { + let fv2: |i128|i128 has copy + drop = closure#0valid_fv::__lambda__1__test2(); + (fv1)(x) + } + } + private fun test3(fv1: ||i64|i64|i64 has copy + drop,x: i64): i64 { + (fv1)(closure#0valid_fv::test_64()) + } + private fun test4(fv1: ||i128|i128|i128 has copy + drop,x: i128): i128 { + (fv1)(closure#0valid_fv::test_128()) + } + private fun test5(fv: |S1|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + (fv)(s1) + } + } + private fun test6(fv: |S2|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + (fv)(s2) + } + } + } + private fun test7(fv: |S3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + { + let s3: S3 = pack valid_fv::S3(a, s1, s2); + (fv)(s3) + } + } + } + } + private fun test8(fv: |S3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + { + let s3: S3 = pack valid_fv::S3(b, s1, s2); + (fv)(s3) + } + } + } + } + private fun test9(fv: |E1|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let e: E1 = pack valid_fv::E1::V1(s1); + (fv)(e) + } + } + } + private fun test_128(x: i128): i128 { + Add(x, x) + } + private fun test_64(x: i64): i64 { + Add(x, x) + } + private fun __lambda__1__test1(x: i64): i64 { + Mul(x, x) + } + private fun __lambda__1__test2(x: i128): i128 { + Mul(x, x) + } +} // end 0x42::valid_fv + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_fv { + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test1(fv1: |i64|i64 has copy + drop, x: i64): i64 { + let fv2: |i64|i64 has copy + drop = |arg0| lambda__1__test1(arg0); + fv1(x) + } + fun test10(fv: |E2|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let e = E2::V2{s: s2}; + fv(e) + } + fun test11(fv: |E3|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i64, y: s1, z: s2}; + let e = E3::V3{s: s3}; + fv(e) + } + fun test12(fv: |E3|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i128, y: s1, z: s2}; + let e = E3::V3{s: s3}; + fv(e) + } + fun test2(fv1: |i128|i128 has copy + drop, x: i128): i128 { + let fv2: |i128|i128 has copy + drop = |arg0| lambda__1__test2(arg0); + fv1(x) + } + fun test3(fv1: ||i64|i64|i64 has copy + drop, x: i64): i64 { + fv1(|arg0| test_64(arg0)) + } + fun test4(fv1: ||i128|i128|i128 has copy + drop, x: i128): i128 { + fv1(|arg0| test_128(arg0)) + } + fun test5(fv: |S1|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: a, z: b}; + fv(s1) + } + fun test6(fv: |S2|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: a, z: b}; + let s2 = S2{x: s1, y: a, z: b}; + fv(s2) + } + fun test7(fv: |S3|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: a, z: b}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: a, y: s1, z: s2}; + fv(s3) + } + fun test8(fv: |S3|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: a, z: b}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: b, y: s1, z: s2}; + fv(s3) + } + fun test9(fv: |E1|i64 has copy + drop, a: i64, b: i128): i64 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let e = E1::V1{s: s1}; + fv(e) + } + fun test_128(x: i128): i128 { + x + x + } + fun test_64(x: i64): i64 { + x + x + } + fun lambda__1__test1(x: i64): i64 { + x * x + } + fun lambda__1__test2(x: i128): i128 { + x * x + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_fv::test1($t0: |i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 has copy + drop + 0: $t3 := closure#0 valid_fv::__lambda__1__test1() + 1: $t2 := invoke($t1, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test10($t0: |0x42::valid_fv::E2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::E2 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t12 := pack_variant 0x42::valid_fv::E2::V2($t8) + 9: $t3 := invoke($t12, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test11($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i64 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t13 := -1 + 9: $t14 := infer($t4) + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + 12: $t3 := invoke($t15, $t0) + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test12($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i128 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t13 := -1 + 9: $t14 := infer($t4) + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + 12: $t3 := invoke($t15, $t0) + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test2($t0: |i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 has copy + drop + 0: $t3 := closure#0 valid_fv::__lambda__1__test2() + 1: $t2 := invoke($t1, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test3($t0: ||i64|i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 + 0: $t3 := closure#0 valid_fv::test_64() + 1: $t2 := invoke($t3, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test4($t0: ||i128|i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 + 0: $t3 := closure#0 valid_fv::test_128() + 1: $t2 := invoke($t3, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test5($t0: |0x42::valid_fv::S1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t3 := invoke($t4, $t0) + 4: return $t3 +} + + +[variant baseline] +fun valid_fv::test6($t0: |0x42::valid_fv::S2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t3 := invoke($t7, $t0) + 7: return $t3 +} + + +[variant baseline] +fun valid_fv::test7($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i64 + var $t12: 0x42::valid_fv::S1 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t11 := infer($t1) + 7: $t12 := infer($t4) + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + 9: $t3 := invoke($t10, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test8($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i128 + var $t12: 0x42::valid_fv::S1 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t11 := infer($t2) + 7: $t12 := infer($t4) + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + 9: $t3 := invoke($t10, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test9($t0: |0x42::valid_fv::E1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::E1 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t8 := pack_variant 0x42::valid_fv::E1::V1($t4) + 5: $t3 := invoke($t8, $t0) + 6: return $t3 +} + + +[variant baseline] +fun valid_fv::test_128($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test_64($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := *($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := *($t2, $t0) + 2: return $t1 +} + + +Diagnostics: +warning: This assignment/binding to the left-hand-side variable `fv2` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_fv2`), or renaming to `_` + ┌─ tests/integers/signed/valid_func_val.move:35:44 + │ +35 │ let fv2: |i64| i64 has copy+drop = |x| x * x; // function value involving i64 + │ ^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `fv2` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_fv2`), or renaming to `_` + ┌─ tests/integers/signed/valid_func_val.move:40:46 + │ +40 │ let fv2: |i128| i128 has copy+drop = |x| x * x; + │ ^^^^^^^^^ + +warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:44:52 + │ +44 │ fun test3(fv1: |(|i64|i64)| i64 has copy+drop, x: i64) : i64 { // function value involving nested function value with i64 + │ ^ + +warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:48:55 + │ +48 │ fun test4(fv1: |(|i128|i128)| i128 has copy+drop, x: i128) : i128 { // function value involving nested function value with i128 + │ ^ + +warning: Unused value of parameter `a`. Consider removing the parameter, or prefixing with an underscore (e.g., `_a`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:77:43 + │ +77 │ fun test9(fv: |E1| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `b`. Consider removing the parameter, or prefixing with an underscore (e.g., `_b`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:77:51 + │ +77 │ fun test9(fv: |E1| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `a`. Consider removing the parameter, or prefixing with an underscore (e.g., `_a`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:83:44 + │ +83 │ fun test10(fv: |E2| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `b`. Consider removing the parameter, or prefixing with an underscore (e.g., `_b`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:83:52 + │ +83 │ fun test10(fv: |E2| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `a`. Consider removing the parameter, or prefixing with an underscore (e.g., `_a`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:90:49 + │ +90 │ fun test11(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `b`. Consider removing the parameter, or prefixing with an underscore (e.g., `_b`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:90:57 + │ +90 │ fun test11(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `a`. Consider removing the parameter, or prefixing with an underscore (e.g., `_a`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:98:50 + │ +98 │ fun test12(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +warning: Unused value of parameter `b`. Consider removing the parameter, or prefixing with an underscore (e.g., `_b`), or binding to `_` + ┌─ tests/integers/signed/valid_func_val.move:98:58 + │ +98 │ fun test12(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + │ ^ + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_fv::test1($t0: |i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 has copy + drop + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := closure#0 valid_fv::__lambda__1__test1() + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 1: $t2 := invoke($t1, $t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test10($t0: |0x42::valid_fv::E2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::E2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 1: $t6 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 2: $t7 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6, $t7 + # refs: [] + # + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t9 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t9 + # refs: [] + # + 5: $t10 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t9, $t10 + # refs: [] + # + 6: $t11 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t9, $t10, $t11 + # refs: [] + # + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + # abort state: {returns,aborts} + # live vars: $t0, $t8 + # refs: [] + # + 8: $t12 := pack_variant 0x42::valid_fv::E2::V2($t8) + # abort state: {returns,aborts} + # live vars: $t0, $t12 + # refs: [] + # + 9: $t3 := invoke($t12, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test11($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i64 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 1: $t6 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 2: $t7 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6, $t7 + # refs: [] + # + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t9 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9 + # refs: [] + # + 5: $t10 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9, $t10 + # refs: [] + # + 6: $t11 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9, $t10, $t11 + # refs: [] + # + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t8 + # refs: [] + # + 8: $t13 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t8, $t13 + # refs: [] + # + 9: $t14 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t8, $t13, $t14 + # refs: [] + # + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + # abort state: {returns,aborts} + # live vars: $t0, $t12 + # refs: [] + # + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + # abort state: {returns,aborts} + # live vars: $t0, $t15 + # refs: [] + # + 12: $t3 := invoke($t15, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test12($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i128 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 1: $t6 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 2: $t7 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6, $t7 + # refs: [] + # + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t9 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9 + # refs: [] + # + 5: $t10 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9, $t10 + # refs: [] + # + 6: $t11 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t9, $t10, $t11 + # refs: [] + # + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t8 + # refs: [] + # + 8: $t13 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t8, $t13 + # refs: [] + # + 9: $t14 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t8, $t13, $t14 + # refs: [] + # + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + # abort state: {returns,aborts} + # live vars: $t0, $t12 + # refs: [] + # + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + # abort state: {returns,aborts} + # live vars: $t0, $t15 + # refs: [] + # + 12: $t3 := invoke($t15, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test2($t0: |i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 has copy + drop + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := closure#0 valid_fv::__lambda__1__test2() + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 1: $t2 := invoke($t1, $t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test3($t0: ||i64|i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := closure#0 valid_fv::test_64() + # abort state: {returns,aborts} + # live vars: $t0, $t3 + # refs: [] + # + 1: $t2 := invoke($t3, $t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test4($t0: ||i128|i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t3 := closure#0 valid_fv::test_128() + # abort state: {returns,aborts} + # live vars: $t0, $t3 + # refs: [] + # + 1: $t2 := invoke($t3, $t0) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test5($t0: |0x42::valid_fv::S1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5 + # refs: [] + # + 1: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t5, $t6 + # refs: [] + # + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 3: $t3 := invoke($t4, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 4: return $t3 +} + + +[variant baseline] +fun valid_fv::test6($t0: |0x42::valid_fv::S2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5 + # refs: [] + # + 1: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5, $t6 + # refs: [] + # + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4 + # refs: [] + # + 3: $t8 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 4: $t9 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t8, $t9 + # refs: [] + # + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t7 + # refs: [] + # + 6: $t3 := invoke($t7, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 7: return $t3 +} + + +[variant baseline] +fun valid_fv::test7($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i64 + var $t12: 0x42::valid_fv::S1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5 + # refs: [] + # + 1: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5, $t6 + # refs: [] + # + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4 + # refs: [] + # + 3: $t8 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4, $t8 + # refs: [] + # + 4: $t9 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4, $t8, $t9 + # refs: [] + # + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t7 + # refs: [] + # + 6: $t11 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t7, $t11 + # refs: [] + # + 7: $t12 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11, $t12 + # refs: [] + # + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 9: $t3 := invoke($t10, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test8($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i128 + var $t12: 0x42::valid_fv::S1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5 + # refs: [] + # + 1: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t5, $t6 + # refs: [] + # + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4 + # refs: [] + # + 3: $t8 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2, $t4, $t8 + # refs: [] + # + 4: $t9 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t4, $t8, $t9 + # refs: [] + # + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t4, $t7 + # refs: [] + # + 6: $t11 := infer($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t4, $t7, $t11 + # refs: [] + # + 7: $t12 := infer($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t7, $t11, $t12 + # refs: [] + # + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t10 + # refs: [] + # + 9: $t3 := invoke($t10, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test9($t0: |0x42::valid_fv::E1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::E1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t5 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t5 + # refs: [] + # + 1: $t6 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6 + # refs: [] + # + 2: $t7 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t5, $t6, $t7 + # refs: [] + # + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + # abort state: {returns,aborts} + # live vars: $t0, $t4 + # refs: [] + # + 4: $t8 := pack_variant 0x42::valid_fv::E1::V1($t4) + # abort state: {returns,aborts} + # live vars: $t0, $t8 + # refs: [] + # + 5: $t3 := invoke($t8, $t0) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 6: return $t3 +} + + +[variant baseline] +fun valid_fv::test_128($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := +($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test_64($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := +($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := *($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t1 := *($t2, $t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 2: return $t1 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_fv { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(fv1: |i64|i64 has copy + drop,x: i64): i64 { + { + let fv2: |i64|i64 has copy + drop = closure#0valid_fv::__lambda__1__test1(); + (fv1)(x) + } + } + private fun test10(fv: |E2|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let e: E2 = pack valid_fv::E2::V2(s2); + (fv)(e) + } + } + } + } + private fun test11(fv: |E3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let s3: S3 = pack valid_fv::S3(-1, s1, s2); + { + let e: E3 = pack valid_fv::E3::V3(s3); + (fv)(e) + } + } + } + } + } + private fun test12(fv: |E3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let s2: S2 = pack valid_fv::S2(s1, -1, -2); + { + let s3: S3 = pack valid_fv::S3(-1, s1, s2); + { + let e: E3 = pack valid_fv::E3::V3(s3); + (fv)(e) + } + } + } + } + } + private fun test2(fv1: |i128|i128 has copy + drop,x: i128): i128 { + { + let fv2: |i128|i128 has copy + drop = closure#0valid_fv::__lambda__1__test2(); + (fv1)(x) + } + } + private fun test3(fv1: ||i64|i64|i64 has copy + drop,x: i64): i64 { + (fv1)(closure#0valid_fv::test_64()) + } + private fun test4(fv1: ||i128|i128|i128 has copy + drop,x: i128): i128 { + (fv1)(closure#0valid_fv::test_128()) + } + private fun test5(fv: |S1|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + (fv)(s1) + } + } + private fun test6(fv: |S2|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + (fv)(s2) + } + } + } + private fun test7(fv: |S3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + { + let s3: S3 = pack valid_fv::S3(a, s1, s2); + (fv)(s3) + } + } + } + } + private fun test8(fv: |S3|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, a, b); + { + let s2: S2 = pack valid_fv::S2(s1, a, b); + { + let s3: S3 = pack valid_fv::S3(b, s1, s2); + (fv)(s3) + } + } + } + } + private fun test9(fv: |E1|i64 has copy + drop,a: i64,b: i128): i64 { + { + let s1: S1 = pack valid_fv::S1(1, -1, -2); + { + let e: E1 = pack valid_fv::E1::V1(s1); + (fv)(e) + } + } + } + private fun test_128(x: i128): i128 { + Add(x, x) + } + private fun test_64(x: i64): i64 { + Add(x, x) + } + private fun __lambda__1__test1(x: i64): i64 { + Mul(x, x) + } + private fun __lambda__1__test2(x: i128): i128 { + Mul(x, x) + } +} // end 0x42::valid_fv + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_fv::test1($t0: |i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 has copy + drop + 0: $t3 := closure#0 valid_fv::__lambda__1__test1() + 1: $t2 := invoke($t1, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test10($t0: |0x42::valid_fv::E2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::E2 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t12 := pack_variant 0x42::valid_fv::E2::V2($t8) + 9: $t3 := invoke($t12, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test11($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i64 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t13 := -1 + 9: $t14 := infer($t4) + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + 12: $t3 := invoke($t15, $t0) + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test12($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 + var $t11: i128 + var $t12: 0x42::valid_fv::S3 + var $t13: i128 + var $t14: 0x42::valid_fv::S1 + var $t15: 0x42::valid_fv::E3 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t9 := infer($t4) + 5: $t10 := -1 + 6: $t11 := -2 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t10, $t11) + 8: $t13 := -1 + 9: $t14 := infer($t4) + 10: $t12 := pack 0x42::valid_fv::S3($t13, $t14, $t8) + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + 12: $t3 := invoke($t15, $t0) + 13: return $t3 +} + + +[variant baseline] +fun valid_fv::test2($t0: |i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 has copy + drop + 0: $t3 := closure#0 valid_fv::__lambda__1__test2() + 1: $t2 := invoke($t1, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test3($t0: ||i64|i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 + var $t3: |i64|i64 + 0: $t3 := closure#0 valid_fv::test_64() + 1: $t2 := invoke($t3, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test4($t0: ||i128|i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 + var $t3: |i128|i128 + 0: $t3 := closure#0 valid_fv::test_128() + 1: $t2 := invoke($t3, $t0) + 2: return $t2 +} + + +[variant baseline] +fun valid_fv::test5($t0: |0x42::valid_fv::S1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t3 := invoke($t4, $t0) + 4: return $t3 +} + + +[variant baseline] +fun valid_fv::test6($t0: |0x42::valid_fv::S2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t3 := invoke($t7, $t0) + 7: return $t3 +} + + +[variant baseline] +fun valid_fv::test7($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i64 + var $t12: 0x42::valid_fv::S1 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t11 := infer($t1) + 7: $t12 := infer($t4) + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + 9: $t3 := invoke($t10, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test8($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 + var $t10: 0x42::valid_fv::S3 + var $t11: i128 + var $t12: 0x42::valid_fv::S1 + 0: $t5 := 1 + 1: $t6 := infer($t1) + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + 3: $t8 := infer($t4) + 4: $t9 := infer($t1) + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t9, $t2) + 6: $t11 := infer($t2) + 7: $t12 := infer($t4) + 8: $t10 := pack 0x42::valid_fv::S3($t11, $t12, $t7) + 9: $t3 := invoke($t10, $t0) + 10: return $t3 +} + + +[variant baseline] +fun valid_fv::test9($t0: |0x42::valid_fv::E1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: i128 + var $t8: 0x42::valid_fv::E1 + 0: $t5 := 1 + 1: $t6 := -1 + 2: $t7 := -2 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t7) + 4: $t8 := pack_variant 0x42::valid_fv::E1::V1($t4) + 5: $t3 := invoke($t8, $t0) + 6: return $t3 +} + + +[variant baseline] +fun valid_fv::test_128($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test_64($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := +($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test1($t0: i64): i64 { + var $t1: i64 + var $t2: i64 + 0: $t2 := infer($t0) + 1: $t1 := *($t2, $t0) + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test2($t0: i128): i128 { + var $t1: i128 + var $t2: i128 + 0: $t2 := infer($t0) + 1: $t1 := *($t2, $t0) + 2: return $t1 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_fv::test1($t0: |i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: |i64|i64 has copy + drop + # live vars: $t0, $t1 + 0: $t3 := closure#0 valid_fv::__lambda__1__test1() + # live vars: $t0, $t1 + 1: $t1 := invoke($t1, $t0) + # live vars: $t1 + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test10($t0: |0x42::valid_fv::E2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 [unused] + var $t7: i128 [unused] + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 [unused] + var $t10: i64 [unused] + var $t11: i128 [unused] + var $t12: 0x42::valid_fv::E2 + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t5 + 1: $t1 := -1 + # live vars: $t0, $t1, $t5 + 2: $t2 := -2 + # live vars: $t0, $t1, $t2, $t5 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t1, $t2) + # live vars: $t0, $t4 + 4: $t4 := move($t4) + # live vars: $t0, $t4 + 5: $t1 := -1 + # live vars: $t0, $t1, $t4 + 6: $t2 := -2 + # live vars: $t0, $t1, $t2, $t4 + 7: $t8 := pack 0x42::valid_fv::S2($t4, $t1, $t2) + # live vars: $t0, $t8 + 8: $t12 := pack_variant 0x42::valid_fv::E2::V2($t8) + # live vars: $t0, $t12 + 9: $t1 := invoke($t12, $t0) + # live vars: $t1 + 10: return $t1 +} + + +[variant baseline] +fun valid_fv::test11($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 [unused] + var $t7: i128 [unused] + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 [unused] + var $t11: i128 [unused] + var $t12: 0x42::valid_fv::S3 + var $t13: i64 [unused] + var $t14: 0x42::valid_fv::S1 [unused] + var $t15: 0x42::valid_fv::E3 + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t5 + 1: $t1 := -1 + # live vars: $t0, $t1, $t5 + 2: $t2 := -2 + # live vars: $t0, $t1, $t2, $t5 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t1, $t2) + # live vars: $t0, $t4 + 4: $t9 := copy($t4) + # live vars: $t0, $t4, $t9 + 5: $t1 := -1 + # live vars: $t0, $t1, $t4, $t9 + 6: $t2 := -2 + # live vars: $t0, $t1, $t2, $t4, $t9 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t1, $t2) + # live vars: $t0, $t4, $t8 + 8: $t1 := -1 + # live vars: $t0, $t1, $t4, $t8 + 9: $t4 := move($t4) + # live vars: $t0, $t1, $t4, $t8 + 10: $t12 := pack 0x42::valid_fv::S3($t1, $t4, $t8) + # live vars: $t0, $t12 + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + # live vars: $t0, $t15 + 12: $t1 := invoke($t15, $t0) + # live vars: $t1 + 13: return $t1 +} + + +[variant baseline] +fun valid_fv::test12($t0: |0x42::valid_fv::E3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 [unused] + var $t7: i128 [unused] + var $t8: 0x42::valid_fv::S2 + var $t9: 0x42::valid_fv::S1 + var $t10: i64 [unused] + var $t11: i128 [unused] + var $t12: 0x42::valid_fv::S3 + var $t13: i128 [unused] + var $t14: 0x42::valid_fv::S1 [unused] + var $t15: 0x42::valid_fv::E3 + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t5 + 1: $t1 := -1 + # live vars: $t0, $t1, $t5 + 2: $t2 := -2 + # live vars: $t0, $t1, $t2, $t5 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t1, $t2) + # live vars: $t0, $t4 + 4: $t9 := copy($t4) + # live vars: $t0, $t4, $t9 + 5: $t1 := -1 + # live vars: $t0, $t1, $t4, $t9 + 6: $t2 := -2 + # live vars: $t0, $t1, $t2, $t4, $t9 + 7: $t8 := pack 0x42::valid_fv::S2($t9, $t1, $t2) + # live vars: $t0, $t4, $t8 + 8: $t2 := -1 + # live vars: $t0, $t2, $t4, $t8 + 9: $t4 := move($t4) + # live vars: $t0, $t2, $t4, $t8 + 10: $t12 := pack 0x42::valid_fv::S3($t2, $t4, $t8) + # live vars: $t0, $t12 + 11: $t15 := pack_variant 0x42::valid_fv::E3::V3($t12) + # live vars: $t0, $t15 + 12: $t1 := invoke($t15, $t0) + # live vars: $t1 + 13: return $t1 +} + + +[variant baseline] +fun valid_fv::test2($t0: |i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: |i128|i128 has copy + drop + # live vars: $t0, $t1 + 0: $t3 := closure#0 valid_fv::__lambda__1__test2() + # live vars: $t0, $t1 + 1: $t1 := invoke($t1, $t0) + # live vars: $t1 + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test3($t0: ||i64|i64|i64 has copy + drop, $t1: i64): i64 { + var $t2: i64 [unused] + var $t3: |i64|i64 + # live vars: $t0, $t1 + 0: $t3 := closure#0 valid_fv::test_64() + # live vars: $t0, $t3 + 1: $t1 := invoke($t3, $t0) + # live vars: $t1 + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test4($t0: ||i128|i128|i128 has copy + drop, $t1: i128): i128 { + var $t2: i128 [unused] + var $t3: |i128|i128 + # live vars: $t0, $t1 + 0: $t3 := closure#0 valid_fv::test_128() + # live vars: $t0, $t3 + 1: $t1 := invoke($t3, $t0) + # live vars: $t1 + 2: return $t1 +} + + +[variant baseline] +fun valid_fv::test5($t0: |0x42::valid_fv::S1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t1, $t2, $t5 + 1: $t1 := move($t1) + # live vars: $t0, $t1, $t2, $t5 + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t1, $t2) + # live vars: $t0, $t4 + 3: $t1 := invoke($t4, $t0) + # live vars: $t1 + 4: return $t1 +} + + +[variant baseline] +fun valid_fv::test6($t0: |0x42::valid_fv::S2|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 [unused] + var $t9: i64 [unused] + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t1, $t2, $t5 + 1: $t6 := copy($t1) + # live vars: $t0, $t1, $t2, $t5, $t6 + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # live vars: $t0, $t1, $t2, $t4 + 3: $t4 := move($t4) + # live vars: $t0, $t1, $t2, $t4 + 4: $t1 := move($t1) + # live vars: $t0, $t1, $t2, $t4 + 5: $t7 := pack 0x42::valid_fv::S2($t4, $t1, $t2) + # live vars: $t0, $t7 + 6: $t1 := invoke($t7, $t0) + # live vars: $t1 + 7: return $t1 +} + + +[variant baseline] +fun valid_fv::test7($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_fv::S3 + var $t11: i64 [unused] + var $t12: 0x42::valid_fv::S1 [unused] + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t1, $t2, $t5 + 1: $t6 := copy($t1) + # live vars: $t0, $t1, $t2, $t5, $t6 + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # live vars: $t0, $t1, $t2, $t4 + 3: $t8 := copy($t4) + # live vars: $t0, $t1, $t2, $t4, $t8 + 4: $t6 := copy($t1) + # live vars: $t0, $t1, $t2, $t4, $t6, $t8 + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t6, $t2) + # live vars: $t0, $t1, $t4, $t7 + 6: $t1 := move($t1) + # live vars: $t0, $t1, $t4, $t7 + 7: $t4 := move($t4) + # live vars: $t0, $t1, $t4, $t7 + 8: $t10 := pack 0x42::valid_fv::S3($t1, $t4, $t7) + # live vars: $t0, $t10 + 9: $t1 := invoke($t10, $t0) + # live vars: $t1 + 10: return $t1 +} + + +[variant baseline] +fun valid_fv::test8($t0: |0x42::valid_fv::S3|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 + var $t7: 0x42::valid_fv::S2 + var $t8: 0x42::valid_fv::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_fv::S3 + var $t11: i128 [unused] + var $t12: 0x42::valid_fv::S1 [unused] + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t1, $t2, $t5 + 1: $t6 := copy($t1) + # live vars: $t0, $t1, $t2, $t5, $t6 + 2: $t4 := pack 0x42::valid_fv::S1($t5, $t6, $t2) + # live vars: $t0, $t1, $t2, $t4 + 3: $t8 := copy($t4) + # live vars: $t0, $t1, $t2, $t4, $t8 + 4: $t1 := move($t1) + # live vars: $t0, $t1, $t2, $t4, $t8 + 5: $t7 := pack 0x42::valid_fv::S2($t8, $t1, $t2) + # live vars: $t0, $t2, $t4, $t7 + 6: $t2 := move($t2) + # live vars: $t0, $t2, $t4, $t7 + 7: $t4 := move($t4) + # live vars: $t0, $t2, $t4, $t7 + 8: $t10 := pack 0x42::valid_fv::S3($t2, $t4, $t7) + # live vars: $t0, $t10 + 9: $t1 := invoke($t10, $t0) + # live vars: $t1 + 10: return $t1 +} + + +[variant baseline] +fun valid_fv::test9($t0: |0x42::valid_fv::E1|i64 has copy + drop, $t1: i64, $t2: i128): i64 { + var $t3: i64 [unused] + var $t4: 0x42::valid_fv::S1 + var $t5: u64 + var $t6: i64 [unused] + var $t7: i128 [unused] + var $t8: 0x42::valid_fv::E1 + # live vars: $t0, $t1, $t2 + 0: $t5 := 1 + # live vars: $t0, $t5 + 1: $t1 := -1 + # live vars: $t0, $t1, $t5 + 2: $t2 := -2 + # live vars: $t0, $t1, $t2, $t5 + 3: $t4 := pack 0x42::valid_fv::S1($t5, $t1, $t2) + # live vars: $t0, $t4 + 4: $t8 := pack_variant 0x42::valid_fv::E1::V1($t4) + # live vars: $t0, $t8 + 5: $t1 := invoke($t8, $t0) + # live vars: $t1 + 6: return $t1 +} + + +[variant baseline] +fun valid_fv::test_128($t0: i128): i128 { + var $t1: i128 [unused] + var $t2: i128 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := +($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_fv::test_64($t0: i64): i64 { + var $t1: i64 [unused] + var $t2: i64 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := +($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test1($t0: i64): i64 { + var $t1: i64 [unused] + var $t2: i64 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := *($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +[variant baseline] +fun valid_fv::__lambda__1__test2($t0: i128): i128 { + var $t1: i128 [unused] + var $t2: i128 + # live vars: $t0 + 0: $t2 := copy($t0) + # live vars: $t0, $t2 + 1: $t0 := *($t2, $t0) + # live vars: $t0 + 2: return $t0 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_fv +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test1(l0: |i64|i64 has copy + drop, l1: i64): i64 + pack_closure __lambda__1__test1, 0 + pop + move_loc l1 + move_loc l0 + call_closure <|i64|i64 has copy + drop> + // @5 + ret + +// Function definition at index 1 +fun test10(l0: |E2|i64 has copy + drop, l1: i64, l2: i128): i64 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + ld_i64 -1 + // @5 + ld_i128 -2 + pack S2 + pack_variant E2, V2 + move_loc l0 + call_closure <|E2|i64 has copy + drop> + // @10 + ret + +// Function definition at index 2 +fun test11(l0: |E3|i64 has copy + drop, l1: i64, l2: i128): i64 + local l3: S1 + local l4: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l3 + // @5 + copy_loc l3 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l4 + // @10 + ld_i64 -1 + move_loc l3 + move_loc l4 + pack S3 + pack_variant E3, V3 + // @15 + move_loc l0 + call_closure <|E3|i64 has copy + drop> + ret + +// Function definition at index 3 +fun test12(l0: |E3|i64 has copy + drop, l1: i64, l2: i128): i64 + local l3: S1 + local l4: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l3 + // @5 + copy_loc l3 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l4 + // @10 + ld_i128 -1 + move_loc l3 + move_loc l4 + pack S3 + pack_variant E3, V3 + // @15 + move_loc l0 + call_closure <|E3|i64 has copy + drop> + ret + +// Function definition at index 4 +fun test2(l0: |i128|i128 has copy + drop, l1: i128): i128 + pack_closure __lambda__1__test2, 0 + pop + move_loc l1 + move_loc l0 + call_closure <|i128|i128 has copy + drop> + // @5 + ret + +// Function definition at index 5 +fun test3(l0: |(|i64|i64)|i64 has copy + drop, l1: i64): i64 + pack_closure test_64, 0 + move_loc l0 + call_closure <|(|i64|i64)|i64 has copy + drop> + ret + +// Function definition at index 6 +fun test4(l0: |(|i128|i128)|i128 has copy + drop, l1: i128): i128 + pack_closure test_128, 0 + move_loc l0 + call_closure <|(|i128|i128)|i128 has copy + drop> + ret + +// Function definition at index 7 +fun test5(l0: |S1|i64 has copy + drop, l1: i64, l2: i128): i64 + ld_u64 1 + move_loc l1 + move_loc l2 + pack S1 + move_loc l0 + // @5 + call_closure <|S1|i64 has copy + drop> + ret + +// Function definition at index 8 +fun test6(l0: |S2|i64 has copy + drop, l1: i64, l2: i128): i64 + ld_u64 1 + copy_loc l1 + copy_loc l2 + pack S1 + move_loc l1 + // @5 + move_loc l2 + pack S2 + move_loc l0 + call_closure <|S2|i64 has copy + drop> + ret + +// Function definition at index 9 +fun test7(l0: |S3|i64 has copy + drop, l1: i64, l2: i128): i64 + local l3: S1 + local l4: S2 + ld_u64 1 + copy_loc l1 + copy_loc l2 + pack S1 + st_loc l3 + // @5 + copy_loc l3 + copy_loc l1 + move_loc l2 + pack S2 + st_loc l4 + // @10 + move_loc l1 + move_loc l3 + move_loc l4 + pack S3 + move_loc l0 + // @15 + call_closure <|S3|i64 has copy + drop> + ret + +// Function definition at index 10 +fun test8(l0: |S3|i64 has copy + drop, l1: i64, l2: i128): i64 + local l3: S1 + local l4: S2 + ld_u64 1 + copy_loc l1 + copy_loc l2 + pack S1 + st_loc l3 + // @5 + copy_loc l3 + move_loc l1 + copy_loc l2 + pack S2 + st_loc l4 + // @10 + move_loc l2 + move_loc l3 + move_loc l4 + pack S3 + move_loc l0 + // @15 + call_closure <|S3|i64 has copy + drop> + ret + +// Function definition at index 11 +fun test9(l0: |E1|i64 has copy + drop, l1: i64, l2: i128): i64 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + pack_variant E1, V1 + // @5 + move_loc l0 + call_closure <|E1|i64 has copy + drop> + ret + +// Function definition at index 12 +fun test_128(l0: i128): i128 + copy_loc l0 + move_loc l0 + add + ret + +// Function definition at index 13 +fun test_64(l0: i64): i64 + copy_loc l0 + move_loc l0 + add + ret + +// Function definition at index 14 +fun __lambda__1__test1(l0: i64): i64 + copy_loc l0 + move_loc l0 + mul + ret + +// Function definition at index 15 +fun __lambda__1__test2(l0: i128): i128 + copy_loc l0 + move_loc l0 + mul + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.move new file mode 100644 index 00000000000..d39ab48b066 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_func_val.move @@ -0,0 +1,105 @@ +module 0x42::valid_fv { + struct S1 has copy, drop { x: u64, y: i64, z: i128 } + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } + + struct S3 has copy, drop { x: T, y: S1, z: S2 } + + enum E1 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test_64(x: i64): i64 { + x + x + } + + fun test_128(x: i128): i128 { + x + x + } + + fun test1(fv1: |i64| i64 has copy+drop, x: i64) : i64 { + let fv2: |i64| i64 has copy+drop = |x| x * x; // function value involving i64 + fv1(x) + } + + fun test2(fv1: |i128| i128 has copy+drop, x: i128) : i128 { // function value involving i128 + let fv2: |i128| i128 has copy+drop = |x| x * x; + fv1(x) + } + + fun test3(fv1: |(|i64|i64)| i64 has copy+drop, x: i64) : i64 { // function value involving nested function value with i64 + fv1(test_64) + } + + fun test4(fv1: |(|i128|i128)| i128 has copy+drop, x: i128) : i128 { // function value involving nested function value with i128 + fv1(test_128) + } + + fun test5(fv: |S1| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: a, z: b}; + fv(s1) + } + + fun test6(fv: |S2| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: a, z: b}; + let s2 = S2 {x: s1, y: a, z: b}; + fv(s2) + } + + fun test7(fv: |S3| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: a, z: b}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: a, y: s1, z: s2}; + fv(s3) + } + + fun test8(fv: |S3| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: a, z: b}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: b, y: s1, z: s2}; + fv(s3) + } + + fun test9(fv: |E1| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let e = E1::V1{s: s1}; + fv(e) + } + + fun test10(fv: |E2| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let e = E2::V2{s: s2}; + fv(e) + } + + fun test11(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e = E3::V3{s: s3}; + fv(e) + } + + fun test12(fv: |E3| i64 has copy+drop, a: i64, b: i128) : i64 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e = E3::V3{s: s3}; + fv(e) + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.exp new file mode 100644 index 00000000000..c0eac99dd7b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.exp @@ -0,0 +1,5076 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_logic { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test_cmp1(x: i64): bool { + And(And(And(And(And(Eq(x, x), Ge(x, x)), Le(x, x)), Gt(x, x)), Lt(x, x)), Eq(Borrow(Immutable)(x), Borrow(Immutable)(x))) + } + private fun test_cmp2(x: i128): bool { + And(And(And(And(And(Eq(x, x), Ge(x, x)), Le(x, x)), Gt(x, x)), Lt(x, x)), Eq(Borrow(Immutable)(x), Borrow(Immutable)(x))) + } + private fun test_cmp3(s1: S1,s2: S2,s3: S3): bool { + And(And(And(And(And(And(Eq(select valid_logic::S1.y(s1), select valid_logic::S2.y(s2)), Le(select valid_logic::S1.y(s1), select valid_logic::S3.x>(s3))), Ge(select valid_logic::S2.y(s2), select valid_logic::S3.x>(s3))), Gt(select valid_logic::S3.x>(s3), select valid_logic::S1.y(s1))), Lt(select valid_logic::S3.x>(s3), select valid_logic::S2.y(s2))), Eq(Borrow(Immutable)(select valid_logic::S1.y(s1)), Borrow(Immutable)(select valid_logic::S2.y(s2)))), Eq(Borrow(Immutable)(select valid_logic::S1.y(s1)), Borrow(Immutable)(select valid_logic::S2.y(s2)))) + } + private fun test_cmp4(s1: S1,s2: S2,s3: S3): bool { + And(And(And(And(And(And(Eq(select valid_logic::S1.z(s1), select valid_logic::S2.z(s2)), Le(select valid_logic::S1.z(s1), select valid_logic::S3.x>(s3))), Ge(select valid_logic::S2.z(s2), select valid_logic::S3.x>(s3))), Gt(select valid_logic::S3.x>(s3), select valid_logic::S1.z(s1))), Lt(select valid_logic::S3.x>(s3), select valid_logic::S2.z(s2))), Eq(Borrow(Immutable)(select valid_logic::S1.z(s1)), Borrow(Immutable)(select valid_logic::S2.z(s2)))), Eq(Borrow(Immutable)(select valid_logic::S1.z(s1)), Borrow(Immutable)(select valid_logic::S2.z(s2)))) + } + private fun test_mix1(x: i64,y: i64): bool { + Eq(Add(x, y), Add(y, x)) + } + private fun test_mix10(x: i128,y: i128): bool { + Gt(Mul(Mod(x, 2), y), Mul(Mod(x, 3), y)) + } + private fun test_mix2(x: i128,y: i128): bool { + Le(Add(x, Mul(2, y)), Add(x, Mul(3, y))) + } + private fun test_mix3(x: i64,y: i64): bool { + Eq(Sub(x, y), Sub(y, x)) + } + private fun test_mix4(x: i128,y: i128): bool { + Gt(Sub(x, Mul(2, y)), Sub(x, Mul(3, y))) + } + private fun test_mix5(x: i64,y: i64): bool { + Eq(Mul(x, y), Mul(y, x)) + } + private fun test_mix6(x: i128,y: i128): bool { + Gt(Mul(Mul(x, 2), y), Mul(Mul(x, 3), y)) + } + private fun test_mix7(x: i64,y: i64): bool { + Eq(Div(x, y), Div(y, x)) + } + private fun test_mix8(x: i128,y: i128): bool { + Gt(Mul(Div(x, 2), y), Mul(Div(x, 3), y)) + } + private fun test_mix9(x: i64,y: i64): bool { + Eq(Mod(x, y), Mod(y, x)) + } +} // end 0x42::valid_logic + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_logic { + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test_cmp1(x: i64): bool { + x == x && x >= x && x <= x && x > x && x < x && &x == &x + } + fun test_cmp2(x: i128): bool { + x == x && x >= x && x <= x && x > x && x < x && &x == &x + } + fun test_cmp3(s1: S1, s2: S2, s3: S3): bool { + s1.y == s2.y && s1.y <= s3.x && s2.y >= s3.x && s3.x > s1.y && s3.x < s2.y && &s1.y == &s2.y && &s1.y == &s2.y + } + fun test_cmp4(s1: S1, s2: S2, s3: S3): bool { + s1.z == s2.z && s1.z <= s3.x && s2.z >= s3.x && s3.x > s1.z && s3.x < s2.z && &s1.z == &s2.z && &s1.z == &s2.z + } + fun test_mix1(x: i64, y: i64): bool { + x + y == y + x + } + fun test_mix10(x: i128, y: i128): bool { + x % 2i128 * y > x % 3i128 * y + } + fun test_mix2(x: i128, y: i128): bool { + x + 2i128 * y <= x + 3i128 * y + } + fun test_mix3(x: i64, y: i64): bool { + x - y == y - x + } + fun test_mix4(x: i128, y: i128): bool { + x - 2i128 * y > x - 3i128 * y + } + fun test_mix5(x: i64, y: i64): bool { + x * y == y * x + } + fun test_mix6(x: i128, y: i128): bool { + x * 2i128 * y > x * 3i128 * y + } + fun test_mix7(x: i64, y: i64): bool { + x / y == y / x + } + fun test_mix8(x: i128, y: i128): bool { + x / 2i128 * y > x / 3i128 * y + } + fun test_mix9(x: i64, y: i64): bool { + x % y == y % x + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_logic::test_cmp1($t0: i64): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: &i64 + var $t13: &i64 + 0: $t7 := infer($t0) + 1: $t6 := ==($t7, $t0) + 2: if ($t6) goto 3 else goto 7 + 3: label L0 + 4: $t8 := infer($t0) + 5: $t5 := >=($t8, $t0) + 6: goto 9 + 7: label L1 + 8: $t5 := false + 9: label L2 + 10: if ($t5) goto 11 else goto 15 + 11: label L3 + 12: $t9 := infer($t0) + 13: $t4 := <=($t9, $t0) + 14: goto 17 + 15: label L4 + 16: $t4 := false + 17: label L5 + 18: if ($t4) goto 19 else goto 23 + 19: label L6 + 20: $t10 := infer($t0) + 21: $t3 := >($t10, $t0) + 22: goto 25 + 23: label L7 + 24: $t3 := false + 25: label L8 + 26: if ($t3) goto 27 else goto 31 + 27: label L9 + 28: $t11 := infer($t0) + 29: $t2 := <($t11, $t0) + 30: goto 33 + 31: label L10 + 32: $t2 := false + 33: label L11 + 34: if ($t2) goto 35 else goto 40 + 35: label L12 + 36: $t12 := borrow_local($t0) + 37: $t13 := borrow_local($t0) + 38: $t1 := ==($t12, $t13) + 39: goto 42 + 40: label L13 + 41: $t1 := false + 42: label L14 + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp2($t0: i128): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: &i128 + var $t13: &i128 + 0: $t7 := infer($t0) + 1: $t6 := ==($t7, $t0) + 2: if ($t6) goto 3 else goto 7 + 3: label L0 + 4: $t8 := infer($t0) + 5: $t5 := >=($t8, $t0) + 6: goto 9 + 7: label L1 + 8: $t5 := false + 9: label L2 + 10: if ($t5) goto 11 else goto 15 + 11: label L3 + 12: $t9 := infer($t0) + 13: $t4 := <=($t9, $t0) + 14: goto 17 + 15: label L4 + 16: $t4 := false + 17: label L5 + 18: if ($t4) goto 19 else goto 23 + 19: label L6 + 20: $t10 := infer($t0) + 21: $t3 := >($t10, $t0) + 22: goto 25 + 23: label L7 + 24: $t3 := false + 25: label L8 + 26: if ($t3) goto 27 else goto 31 + 27: label L9 + 28: $t11 := infer($t0) + 29: $t2 := <($t11, $t0) + 30: goto 33 + 31: label L10 + 32: $t2 := false + 33: label L11 + 34: if ($t2) goto 35 else goto 40 + 35: label L12 + 36: $t12 := borrow_local($t0) + 37: $t13 := borrow_local($t0) + 38: $t1 := ==($t12, $t13) + 39: goto 42 + 40: label L13 + 41: $t1 := false + 42: label L14 + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp3($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i64 + var $t11: &0x42::valid_logic::S1 + var $t12: &i64 + var $t13: i64 + var $t14: &0x42::valid_logic::S2 + var $t15: &i64 + var $t16: i64 + var $t17: &0x42::valid_logic::S1 + var $t18: &i64 + var $t19: i64 + var $t20: &0x42::valid_logic::S3 + var $t21: &i64 + var $t22: i64 + var $t23: &0x42::valid_logic::S2 + var $t24: &i64 + var $t25: i64 + var $t26: &0x42::valid_logic::S3 + var $t27: &i64 + var $t28: i64 + var $t29: &0x42::valid_logic::S3 + var $t30: &i64 + var $t31: i64 + var $t32: &0x42::valid_logic::S1 + var $t33: &i64 + var $t34: i64 + var $t35: &0x42::valid_logic::S3 + var $t36: &i64 + var $t37: i64 + var $t38: &0x42::valid_logic::S2 + var $t39: &i64 + var $t40: &i64 + var $t41: &0x42::valid_logic::S1 + var $t42: &i64 + var $t43: &0x42::valid_logic::S2 + var $t44: &i64 + var $t45: &0x42::valid_logic::S1 + var $t46: &i64 + var $t47: &0x42::valid_logic::S2 + 0: $t11 := borrow_local($t0) + 1: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + 2: $t10 := read_ref($t12) + 3: $t14 := borrow_local($t1) + 4: $t15 := borrow_field<0x42::valid_logic::S2>.y($t14) + 5: $t13 := read_ref($t15) + 6: $t9 := ==($t10, $t13) + 7: if ($t9) goto 8 else goto 17 + 8: label L0 + 9: $t17 := borrow_local($t0) + 10: $t18 := borrow_field<0x42::valid_logic::S1>.y($t17) + 11: $t16 := read_ref($t18) + 12: $t20 := borrow_local($t2) + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + 14: $t19 := read_ref($t21) + 15: $t8 := <=($t16, $t19) + 16: goto 19 + 17: label L1 + 18: $t8 := false + 19: label L2 + 20: if ($t8) goto 21 else goto 30 + 21: label L3 + 22: $t23 := borrow_local($t1) + 23: $t24 := borrow_field<0x42::valid_logic::S2>.y($t23) + 24: $t22 := read_ref($t24) + 25: $t26 := borrow_local($t2) + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + 27: $t25 := read_ref($t27) + 28: $t7 := >=($t22, $t25) + 29: goto 32 + 30: label L4 + 31: $t7 := false + 32: label L5 + 33: if ($t7) goto 34 else goto 43 + 34: label L6 + 35: $t29 := borrow_local($t2) + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + 37: $t28 := read_ref($t30) + 38: $t32 := borrow_local($t0) + 39: $t33 := borrow_field<0x42::valid_logic::S1>.y($t32) + 40: $t31 := read_ref($t33) + 41: $t6 := >($t28, $t31) + 42: goto 45 + 43: label L7 + 44: $t6 := false + 45: label L8 + 46: if ($t6) goto 47 else goto 56 + 47: label L9 + 48: $t35 := borrow_local($t2) + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + 50: $t34 := read_ref($t36) + 51: $t38 := borrow_local($t1) + 52: $t39 := borrow_field<0x42::valid_logic::S2>.y($t38) + 53: $t37 := read_ref($t39) + 54: $t5 := <($t34, $t37) + 55: goto 58 + 56: label L10 + 57: $t5 := false + 58: label L11 + 59: if ($t5) goto 60 else goto 67 + 60: label L12 + 61: $t41 := borrow_local($t0) + 62: $t40 := borrow_field<0x42::valid_logic::S1>.y($t41) + 63: $t43 := borrow_local($t1) + 64: $t42 := borrow_field<0x42::valid_logic::S2>.y($t43) + 65: $t4 := ==($t40, $t42) + 66: goto 69 + 67: label L13 + 68: $t4 := false + 69: label L14 + 70: if ($t4) goto 71 else goto 78 + 71: label L15 + 72: $t45 := borrow_local($t0) + 73: $t44 := borrow_field<0x42::valid_logic::S1>.y($t45) + 74: $t47 := borrow_local($t1) + 75: $t46 := borrow_field<0x42::valid_logic::S2>.y($t47) + 76: $t3 := ==($t44, $t46) + 77: goto 80 + 78: label L16 + 79: $t3 := false + 80: label L17 + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_cmp4($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i128 + var $t11: &0x42::valid_logic::S1 + var $t12: &i128 + var $t13: i128 + var $t14: &0x42::valid_logic::S2 + var $t15: &i128 + var $t16: i128 + var $t17: &0x42::valid_logic::S1 + var $t18: &i128 + var $t19: i128 + var $t20: &0x42::valid_logic::S3 + var $t21: &i128 + var $t22: i128 + var $t23: &0x42::valid_logic::S2 + var $t24: &i128 + var $t25: i128 + var $t26: &0x42::valid_logic::S3 + var $t27: &i128 + var $t28: i128 + var $t29: &0x42::valid_logic::S3 + var $t30: &i128 + var $t31: i128 + var $t32: &0x42::valid_logic::S1 + var $t33: &i128 + var $t34: i128 + var $t35: &0x42::valid_logic::S3 + var $t36: &i128 + var $t37: i128 + var $t38: &0x42::valid_logic::S2 + var $t39: &i128 + var $t40: &i128 + var $t41: &0x42::valid_logic::S1 + var $t42: &i128 + var $t43: &0x42::valid_logic::S2 + var $t44: &i128 + var $t45: &0x42::valid_logic::S1 + var $t46: &i128 + var $t47: &0x42::valid_logic::S2 + 0: $t11 := borrow_local($t0) + 1: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + 2: $t10 := read_ref($t12) + 3: $t14 := borrow_local($t1) + 4: $t15 := borrow_field<0x42::valid_logic::S2>.z($t14) + 5: $t13 := read_ref($t15) + 6: $t9 := ==($t10, $t13) + 7: if ($t9) goto 8 else goto 17 + 8: label L0 + 9: $t17 := borrow_local($t0) + 10: $t18 := borrow_field<0x42::valid_logic::S1>.z($t17) + 11: $t16 := read_ref($t18) + 12: $t20 := borrow_local($t2) + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + 14: $t19 := read_ref($t21) + 15: $t8 := <=($t16, $t19) + 16: goto 19 + 17: label L1 + 18: $t8 := false + 19: label L2 + 20: if ($t8) goto 21 else goto 30 + 21: label L3 + 22: $t23 := borrow_local($t1) + 23: $t24 := borrow_field<0x42::valid_logic::S2>.z($t23) + 24: $t22 := read_ref($t24) + 25: $t26 := borrow_local($t2) + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + 27: $t25 := read_ref($t27) + 28: $t7 := >=($t22, $t25) + 29: goto 32 + 30: label L4 + 31: $t7 := false + 32: label L5 + 33: if ($t7) goto 34 else goto 43 + 34: label L6 + 35: $t29 := borrow_local($t2) + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + 37: $t28 := read_ref($t30) + 38: $t32 := borrow_local($t0) + 39: $t33 := borrow_field<0x42::valid_logic::S1>.z($t32) + 40: $t31 := read_ref($t33) + 41: $t6 := >($t28, $t31) + 42: goto 45 + 43: label L7 + 44: $t6 := false + 45: label L8 + 46: if ($t6) goto 47 else goto 56 + 47: label L9 + 48: $t35 := borrow_local($t2) + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + 50: $t34 := read_ref($t36) + 51: $t38 := borrow_local($t1) + 52: $t39 := borrow_field<0x42::valid_logic::S2>.z($t38) + 53: $t37 := read_ref($t39) + 54: $t5 := <($t34, $t37) + 55: goto 58 + 56: label L10 + 57: $t5 := false + 58: label L11 + 59: if ($t5) goto 60 else goto 67 + 60: label L12 + 61: $t41 := borrow_local($t0) + 62: $t40 := borrow_field<0x42::valid_logic::S1>.z($t41) + 63: $t43 := borrow_local($t1) + 64: $t42 := borrow_field<0x42::valid_logic::S2>.z($t43) + 65: $t4 := ==($t40, $t42) + 66: goto 69 + 67: label L13 + 68: $t4 := false + 69: label L14 + 70: if ($t4) goto 71 else goto 78 + 71: label L15 + 72: $t45 := borrow_local($t0) + 73: $t44 := borrow_field<0x42::valid_logic::S1>.z($t45) + 74: $t47 := borrow_local($t1) + 75: $t46 := borrow_field<0x42::valid_logic::S2>.z($t47) + 76: $t3 := ==($t44, $t46) + 77: goto 80 + 78: label L16 + 79: $t3 := false + 80: label L17 + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_mix1($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := +($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := +($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix10($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := %($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := %($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix2($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t4 := infer($t0) + 1: $t6 := 2 + 2: $t5 := *($t6, $t1) + 3: $t3 := +($t4, $t5) + 4: $t8 := infer($t0) + 5: $t10 := 3 + 6: $t9 := *($t10, $t1) + 7: $t7 := +($t8, $t9) + 8: $t2 := <=($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix3($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := -($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := -($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix4($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t4 := infer($t0) + 1: $t6 := 2 + 2: $t5 := *($t6, $t1) + 3: $t3 := -($t4, $t5) + 4: $t8 := infer($t0) + 5: $t10 := 3 + 6: $t9 := *($t10, $t1) + 7: $t7 := -($t8, $t9) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix5($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := *($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := *($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix6($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := *($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := *($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix7($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := /($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := /($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix8($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := /($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := /($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix9($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := %($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := %($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_logic::test_cmp1($t0: i64): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: &i64 + var $t13: &i64 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 0: $t7 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t7 + # refs: [] + # + 1: $t6 := ==($t7, $t0) + # abort state: {returns} + # live vars: $t0, $t6 + # refs: [] + # + 2: if ($t6) goto 3 else goto 7 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 3: label L0 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t8 + # refs: [] + # + 5: $t5 := >=($t8, $t0) + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 6: goto 9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 7: label L1 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 8: $t5 := false + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 10: if ($t5) goto 11 else goto 15 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 11: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: $t9 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t9 + # refs: [] + # + 13: $t4 := <=($t9, $t0) + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 14: goto 17 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 15: label L4 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 16: $t4 := false + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 17: label L5 + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 18: if ($t4) goto 19 else goto 23 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 19: label L6 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 20: $t10 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t10 + # refs: [] + # + 21: $t3 := >($t10, $t0) + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 22: goto 25 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 23: label L7 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 24: $t3 := false + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 25: label L8 + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 26: if ($t3) goto 27 else goto 31 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 27: label L9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 28: $t11 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t11 + # refs: [] + # + 29: $t2 := <($t11, $t0) + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 30: goto 33 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 31: label L10 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 32: $t2 := false + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 33: label L11 + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 34: if ($t2) goto 35 else goto 40 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 35: label L12 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 36: $t12 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `x`] at line 27 + # + 37: $t13 := borrow_local($t0) + # abort state: {returns} + # live vars: $t12, $t13 + # refs: [$t12 => #12, $t13 => #13] + # #12 + # + # #13 + # => #12 via [] at line 27 + # #root + # => #13 via [local `x`] at line 27 + # + 38: $t1 := ==($t12, $t13) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 39: goto 42 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 40: label L13 + # abort state: {returns} + # live vars: + # refs: [] + # + 41: $t1 := false + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 42: label L14 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp2($t0: i128): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: &i128 + var $t13: &i128 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 0: $t7 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t7 + # refs: [] + # + 1: $t6 := ==($t7, $t0) + # abort state: {returns} + # live vars: $t0, $t6 + # refs: [] + # + 2: if ($t6) goto 3 else goto 7 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 3: label L0 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t8 + # refs: [] + # + 5: $t5 := >=($t8, $t0) + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 6: goto 9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 7: label L1 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 8: $t5 := false + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t0, $t5 + # refs: [] + # + 10: if ($t5) goto 11 else goto 15 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 11: label L3 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: $t9 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t9 + # refs: [] + # + 13: $t4 := <=($t9, $t0) + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 14: goto 17 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 15: label L4 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 16: $t4 := false + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 17: label L5 + # abort state: {returns} + # live vars: $t0, $t4 + # refs: [] + # + 18: if ($t4) goto 19 else goto 23 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 19: label L6 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 20: $t10 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t10 + # refs: [] + # + 21: $t3 := >($t10, $t0) + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 22: goto 25 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 23: label L7 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 24: $t3 := false + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 25: label L8 + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [] + # + 26: if ($t3) goto 27 else goto 31 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 27: label L9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 28: $t11 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t11 + # refs: [] + # + 29: $t2 := <($t11, $t0) + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 30: goto 33 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 31: label L10 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 32: $t2 := false + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 33: label L11 + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [] + # + 34: if ($t2) goto 35 else goto 40 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 35: label L12 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 36: $t12 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `x`] at line 31 + # + 37: $t13 := borrow_local($t0) + # abort state: {returns} + # live vars: $t12, $t13 + # refs: [$t12 => #12, $t13 => #13] + # #12 + # + # #13 + # => #12 via [] at line 31 + # #root + # => #13 via [local `x`] at line 31 + # + 38: $t1 := ==($t12, $t13) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 39: goto 42 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 40: label L13 + # abort state: {returns} + # live vars: + # refs: [] + # + 41: $t1 := false + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 42: label L14 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp3($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i64 + var $t11: &0x42::valid_logic::S1 + var $t12: &i64 + var $t13: i64 + var $t14: &0x42::valid_logic::S2 + var $t15: &i64 + var $t16: i64 + var $t17: &0x42::valid_logic::S1 + var $t18: &i64 + var $t19: i64 + var $t20: &0x42::valid_logic::S3 + var $t21: &i64 + var $t22: i64 + var $t23: &0x42::valid_logic::S2 + var $t24: &i64 + var $t25: i64 + var $t26: &0x42::valid_logic::S3 + var $t27: &i64 + var $t28: i64 + var $t29: &0x42::valid_logic::S3 + var $t30: &i64 + var $t31: i64 + var $t32: &0x42::valid_logic::S1 + var $t33: &i64 + var $t34: i64 + var $t35: &0x42::valid_logic::S3 + var $t36: &i64 + var $t37: i64 + var $t38: &0x42::valid_logic::S2 + var $t39: &i64 + var $t40: &i64 + var $t41: &0x42::valid_logic::S1 + var $t42: &i64 + var $t43: &0x42::valid_logic::S2 + var $t44: &i64 + var $t45: &0x42::valid_logic::S1 + var $t46: &i64 + var $t47: &0x42::valid_logic::S2 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t11 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t11 + # refs: [$t11 => #11] + # #11 + # + # #root + # => #11 via [local `s1`] at line 35 + # + 1: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s1`, field `y`] at line 35 + # + 2: $t10 := read_ref($t12) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10 + # refs: [] + # + 3: $t14 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t14 + # refs: [$t14 => #14] + # #14 + # + # #root + # => #14 via [local `s2`] at line 35 + # + 4: $t15 := borrow_field<0x42::valid_logic::S2>.y($t14) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => #15 via [local `s2`, field `y`] at line 35 + # + 5: $t13 := read_ref($t15) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t13 + # refs: [] + # + 6: $t9 := ==($t10, $t13) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t9 + # refs: [] + # + 7: if ($t9) goto 8 else goto 17 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 8: label L0 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 9: $t17 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => #17 via [local `s1`] at line 35 + # + 10: $t18 := borrow_field<0x42::valid_logic::S1>.y($t17) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => #18 via [local `s1`, field `y`] at line 35 + # + 11: $t16 := read_ref($t18) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16 + # refs: [] + # + 12: $t20 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t20 + # refs: [$t20 => #20] + # #20 + # + # #root + # => #20 via [local `s3`] at line 35 + # + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t21 + # refs: [$t21 => #21] + # #21 + # + # #root + # => #21 via [local `s3`, field `x`] at line 35 + # + 14: $t19 := read_ref($t21) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t19 + # refs: [] + # + 15: $t8 := <=($t16, $t19) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 16: goto 19 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 17: label L1 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 18: $t8 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 19: label L2 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 20: if ($t8) goto 21 else goto 30 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 21: label L3 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 22: $t23 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t23 + # refs: [$t23 => #23] + # #23 + # + # #root + # => #23 via [local `s2`] at line 35 + # + 23: $t24 := borrow_field<0x42::valid_logic::S2>.y($t23) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t24 + # refs: [$t24 => #24] + # #24 + # + # #root + # => #24 via [local `s2`, field `y`] at line 35 + # + 24: $t22 := read_ref($t24) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22 + # refs: [] + # + 25: $t26 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t26 + # refs: [$t26 => #26] + # #26 + # + # #root + # => #26 via [local `s3`] at line 35 + # + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t27 + # refs: [$t27 => #27] + # #27 + # + # #root + # => #27 via [local `s3`, field `x`] at line 35 + # + 27: $t25 := read_ref($t27) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t25 + # refs: [] + # + 28: $t7 := >=($t22, $t25) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 29: goto 32 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 30: label L4 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 31: $t7 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 32: label L5 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 33: if ($t7) goto 34 else goto 43 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 34: label L6 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 35: $t29 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t29 + # refs: [$t29 => #29] + # #29 + # + # #root + # => #29 via [local `s3`] at line 35 + # + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t30 + # refs: [$t30 => #30] + # #30 + # + # #root + # => #30 via [local `s3`, field `x`] at line 35 + # + 37: $t28 := read_ref($t30) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28 + # refs: [] + # + 38: $t32 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t32 + # refs: [$t32 => #32] + # #32 + # + # #root + # => #32 via [local `s1`] at line 35 + # + 39: $t33 := borrow_field<0x42::valid_logic::S1>.y($t32) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t33 + # refs: [$t33 => #33] + # #33 + # + # #root + # => #33 via [local `s1`, field `y`] at line 35 + # + 40: $t31 := read_ref($t33) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t31 + # refs: [] + # + 41: $t6 := >($t28, $t31) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 42: goto 45 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 43: label L7 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 44: $t6 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 45: label L8 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 46: if ($t6) goto 47 else goto 56 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 47: label L9 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 48: $t35 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t35 + # refs: [$t35 => #35] + # #35 + # + # #root + # => #35 via [local `s3`] at line 35 + # + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + # abort state: {returns} + # live vars: $t0, $t1, $t36 + # refs: [$t36 => #36] + # #36 + # + # #root + # => #36 via [local `s3`, field `x`] at line 35 + # + 50: $t34 := read_ref($t36) + # abort state: {returns} + # live vars: $t0, $t1, $t34 + # refs: [] + # + 51: $t38 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t38 + # refs: [$t38 => #38] + # #38 + # + # #root + # => #38 via [local `s2`] at line 35 + # + 52: $t39 := borrow_field<0x42::valid_logic::S2>.y($t38) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t39 + # refs: [$t39 => #39] + # #39 + # + # #root + # => #39 via [local `s2`, field `y`] at line 35 + # + 53: $t37 := read_ref($t39) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t37 + # refs: [] + # + 54: $t5 := <($t34, $t37) + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 55: goto 58 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 56: label L10 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 57: $t5 := false + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 58: label L11 + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 59: if ($t5) goto 60 else goto 67 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 60: label L12 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 61: $t41 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t41 + # refs: [$t41 => #41] + # #41 + # + # #root + # => #41 via [local `s1`] at line 35 + # + 62: $t40 := borrow_field<0x42::valid_logic::S1>.y($t41) + # abort state: {returns} + # live vars: $t0, $t1, $t40 + # refs: [$t40 => #40] + # #40 + # + # #root + # => #40 via [local `s1`, field `y`] at line 35 + # + 63: $t43 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t40, $t43 + # refs: [$t40 => #40, $t43 => #43] + # #40 + # + # #43 + # + # #root + # => #40 via [local `s1`, field `y`] at line 35 + # => #43 via [local `s2`] at line 35 + # + 64: $t42 := borrow_field<0x42::valid_logic::S2>.y($t43) + # abort state: {returns} + # live vars: $t0, $t1, $t40, $t42 + # refs: [$t40 => #40, $t42 => #42] + # #40 + # + # #42 + # + # #root + # => #40 via [local `s1`, field `y`] at line 35 + # => #42 via [local `s2`, field `y`] at line 35 + # + 65: $t4 := ==($t40, $t42) + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 66: goto 69 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 67: label L13 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 68: $t4 := false + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 69: label L14 + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 70: if ($t4) goto 71 else goto 78 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 71: label L15 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 72: $t45 := borrow_local($t0) + # abort state: {returns} + # live vars: $t1, $t45 + # refs: [$t45 => #45] + # #45 + # + # #root + # => #45 via [local `s1`] at line 35 + # + 73: $t44 := borrow_field<0x42::valid_logic::S1>.y($t45) + # abort state: {returns} + # live vars: $t1, $t44 + # refs: [$t44 => #44] + # #44 + # + # #root + # => #44 via [local `s1`, field `y`] at line 35 + # + 74: $t47 := borrow_local($t1) + # abort state: {returns} + # live vars: $t44, $t47 + # refs: [$t44 => #44, $t47 => #47] + # #44 + # + # #47 + # + # #root + # => #44 via [local `s1`, field `y`] at line 35 + # => #47 via [local `s2`] at line 35 + # + 75: $t46 := borrow_field<0x42::valid_logic::S2>.y($t47) + # abort state: {returns} + # live vars: $t44, $t46 + # refs: [$t44 => #44, $t46 => #46] + # #44 + # + # #46 + # + # #root + # => #44 via [local `s1`, field `y`] at line 35 + # => #46 via [local `s2`, field `y`] at line 35 + # + 76: $t3 := ==($t44, $t46) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 77: goto 80 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 78: label L16 + # abort state: {returns} + # live vars: + # refs: [] + # + 79: $t3 := false + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 80: label L17 + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_cmp4($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i128 + var $t11: &0x42::valid_logic::S1 + var $t12: &i128 + var $t13: i128 + var $t14: &0x42::valid_logic::S2 + var $t15: &i128 + var $t16: i128 + var $t17: &0x42::valid_logic::S1 + var $t18: &i128 + var $t19: i128 + var $t20: &0x42::valid_logic::S3 + var $t21: &i128 + var $t22: i128 + var $t23: &0x42::valid_logic::S2 + var $t24: &i128 + var $t25: i128 + var $t26: &0x42::valid_logic::S3 + var $t27: &i128 + var $t28: i128 + var $t29: &0x42::valid_logic::S3 + var $t30: &i128 + var $t31: i128 + var $t32: &0x42::valid_logic::S1 + var $t33: &i128 + var $t34: i128 + var $t35: &0x42::valid_logic::S3 + var $t36: &i128 + var $t37: i128 + var $t38: &0x42::valid_logic::S2 + var $t39: &i128 + var $t40: &i128 + var $t41: &0x42::valid_logic::S1 + var $t42: &i128 + var $t43: &0x42::valid_logic::S2 + var $t44: &i128 + var $t45: &0x42::valid_logic::S1 + var $t46: &i128 + var $t47: &0x42::valid_logic::S2 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 0: $t11 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t11 + # refs: [$t11 => #11] + # #11 + # + # #root + # => #11 via [local `s1`] at line 39 + # + 1: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s1`, field `z`] at line 39 + # + 2: $t10 := read_ref($t12) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10 + # refs: [] + # + 3: $t14 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t14 + # refs: [$t14 => #14] + # #14 + # + # #root + # => #14 via [local `s2`] at line 39 + # + 4: $t15 := borrow_field<0x42::valid_logic::S2>.z($t14) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => #15 via [local `s2`, field `z`] at line 39 + # + 5: $t13 := read_ref($t15) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t10, $t13 + # refs: [] + # + 6: $t9 := ==($t10, $t13) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t9 + # refs: [] + # + 7: if ($t9) goto 8 else goto 17 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 8: label L0 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 9: $t17 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => #17 via [local `s1`] at line 39 + # + 10: $t18 := borrow_field<0x42::valid_logic::S1>.z($t17) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => #18 via [local `s1`, field `z`] at line 39 + # + 11: $t16 := read_ref($t18) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16 + # refs: [] + # + 12: $t20 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t20 + # refs: [$t20 => #20] + # #20 + # + # #root + # => #20 via [local `s3`] at line 39 + # + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t21 + # refs: [$t21 => #21] + # #21 + # + # #root + # => #21 via [local `s3`, field `x`] at line 39 + # + 14: $t19 := read_ref($t21) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t16, $t19 + # refs: [] + # + 15: $t8 := <=($t16, $t19) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 16: goto 19 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 17: label L1 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 18: $t8 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 19: label L2 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t8 + # refs: [] + # + 20: if ($t8) goto 21 else goto 30 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 21: label L3 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 22: $t23 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t23 + # refs: [$t23 => #23] + # #23 + # + # #root + # => #23 via [local `s2`] at line 39 + # + 23: $t24 := borrow_field<0x42::valid_logic::S2>.z($t23) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t24 + # refs: [$t24 => #24] + # #24 + # + # #root + # => #24 via [local `s2`, field `z`] at line 39 + # + 24: $t22 := read_ref($t24) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22 + # refs: [] + # + 25: $t26 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t26 + # refs: [$t26 => #26] + # #26 + # + # #root + # => #26 via [local `s3`] at line 39 + # + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t27 + # refs: [$t27 => #27] + # #27 + # + # #root + # => #27 via [local `s3`, field `x`] at line 39 + # + 27: $t25 := read_ref($t27) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t22, $t25 + # refs: [] + # + 28: $t7 := >=($t22, $t25) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 29: goto 32 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 30: label L4 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 31: $t7 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 32: label L5 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t7 + # refs: [] + # + 33: if ($t7) goto 34 else goto 43 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 34: label L6 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 35: $t29 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t29 + # refs: [$t29 => #29] + # #29 + # + # #root + # => #29 via [local `s3`] at line 39 + # + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t30 + # refs: [$t30 => #30] + # #30 + # + # #root + # => #30 via [local `s3`, field `x`] at line 39 + # + 37: $t28 := read_ref($t30) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28 + # refs: [] + # + 38: $t32 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t32 + # refs: [$t32 => #32] + # #32 + # + # #root + # => #32 via [local `s1`] at line 39 + # + 39: $t33 := borrow_field<0x42::valid_logic::S1>.z($t32) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t33 + # refs: [$t33 => #33] + # #33 + # + # #root + # => #33 via [local `s1`, field `z`] at line 39 + # + 40: $t31 := read_ref($t33) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t28, $t31 + # refs: [] + # + 41: $t6 := >($t28, $t31) + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 42: goto 45 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 43: label L7 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 44: $t6 := false + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 45: label L8 + # abort state: {returns} + # live vars: $t0, $t1, $t2, $t6 + # refs: [] + # + 46: if ($t6) goto 47 else goto 56 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 47: label L9 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 48: $t35 := borrow_local($t2) + # abort state: {returns} + # live vars: $t0, $t1, $t35 + # refs: [$t35 => #35] + # #35 + # + # #root + # => #35 via [local `s3`] at line 39 + # + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + # abort state: {returns} + # live vars: $t0, $t1, $t36 + # refs: [$t36 => #36] + # #36 + # + # #root + # => #36 via [local `s3`, field `x`] at line 39 + # + 50: $t34 := read_ref($t36) + # abort state: {returns} + # live vars: $t0, $t1, $t34 + # refs: [] + # + 51: $t38 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t38 + # refs: [$t38 => #38] + # #38 + # + # #root + # => #38 via [local `s2`] at line 39 + # + 52: $t39 := borrow_field<0x42::valid_logic::S2>.z($t38) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t39 + # refs: [$t39 => #39] + # #39 + # + # #root + # => #39 via [local `s2`, field `z`] at line 39 + # + 53: $t37 := read_ref($t39) + # abort state: {returns} + # live vars: $t0, $t1, $t34, $t37 + # refs: [] + # + 54: $t5 := <($t34, $t37) + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 55: goto 58 + # abort state: {returns} + # live vars: $t0, $t1, $t2 + # refs: [] + # + 56: label L10 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 57: $t5 := false + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 58: label L11 + # abort state: {returns} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 59: if ($t5) goto 60 else goto 67 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 60: label L12 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 61: $t41 := borrow_local($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t41 + # refs: [$t41 => #41] + # #41 + # + # #root + # => #41 via [local `s1`] at line 39 + # + 62: $t40 := borrow_field<0x42::valid_logic::S1>.z($t41) + # abort state: {returns} + # live vars: $t0, $t1, $t40 + # refs: [$t40 => #40] + # #40 + # + # #root + # => #40 via [local `s1`, field `z`] at line 39 + # + 63: $t43 := borrow_local($t1) + # abort state: {returns} + # live vars: $t0, $t1, $t40, $t43 + # refs: [$t40 => #40, $t43 => #43] + # #40 + # + # #43 + # + # #root + # => #40 via [local `s1`, field `z`] at line 39 + # => #43 via [local `s2`] at line 39 + # + 64: $t42 := borrow_field<0x42::valid_logic::S2>.z($t43) + # abort state: {returns} + # live vars: $t0, $t1, $t40, $t42 + # refs: [$t40 => #40, $t42 => #42] + # #40 + # + # #42 + # + # #root + # => #40 via [local `s1`, field `z`] at line 39 + # => #42 via [local `s2`, field `z`] at line 39 + # + 65: $t4 := ==($t40, $t42) + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 66: goto 69 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 67: label L13 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 68: $t4 := false + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 69: label L14 + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 70: if ($t4) goto 71 else goto 78 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 71: label L15 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 72: $t45 := borrow_local($t0) + # abort state: {returns} + # live vars: $t1, $t45 + # refs: [$t45 => #45] + # #45 + # + # #root + # => #45 via [local `s1`] at line 39 + # + 73: $t44 := borrow_field<0x42::valid_logic::S1>.z($t45) + # abort state: {returns} + # live vars: $t1, $t44 + # refs: [$t44 => #44] + # #44 + # + # #root + # => #44 via [local `s1`, field `z`] at line 39 + # + 74: $t47 := borrow_local($t1) + # abort state: {returns} + # live vars: $t44, $t47 + # refs: [$t44 => #44, $t47 => #47] + # #44 + # + # #47 + # + # #root + # => #44 via [local `s1`, field `z`] at line 39 + # => #47 via [local `s2`] at line 39 + # + 75: $t46 := borrow_field<0x42::valid_logic::S2>.z($t47) + # abort state: {returns} + # live vars: $t44, $t46 + # refs: [$t44 => #44, $t46 => #46] + # #44 + # + # #46 + # + # #root + # => #44 via [local `s1`, field `z`] at line 39 + # => #46 via [local `s2`, field `z`] at line 39 + # + 76: $t3 := ==($t44, $t46) + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 77: goto 80 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 78: label L16 + # abort state: {returns} + # live vars: + # refs: [] + # + 79: $t3 := false + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 80: label L17 + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_mix1($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := +($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 3: $t5 := +($t6, $t0) + # abort state: {returns} + # live vars: $t3, $t5 + # refs: [] + # + 4: $t2 := ==($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix10($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 1: $t6 := 2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5, $t6 + # refs: [] + # + 2: $t4 := %($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 3: $t3 := *($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9 + # refs: [] + # + 5: $t10 := 3 + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9, $t10 + # refs: [] + # + 6: $t8 := %($t9, $t10) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8 + # refs: [] + # + 7: $t7 := *($t8, $t1) + # abort state: {returns} + # live vars: $t3, $t7 + # refs: [] + # + 8: $t2 := >($t3, $t7) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix2($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t6 := 2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t6 + # refs: [] + # + 2: $t5 := *($t6, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 3: $t3 := +($t4, $t5) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8 + # refs: [] + # + 5: $t10 := 3 + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t10 + # refs: [] + # + 6: $t9 := *($t10, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t8, $t9 + # refs: [] + # + 7: $t7 := +($t8, $t9) + # abort state: {returns} + # live vars: $t3, $t7 + # refs: [] + # + 8: $t2 := <=($t3, $t7) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix3($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := -($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 3: $t5 := -($t6, $t0) + # abort state: {returns} + # live vars: $t3, $t5 + # refs: [] + # + 4: $t2 := ==($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix4($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t6 := 2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t6 + # refs: [] + # + 2: $t5 := *($t6, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 3: $t3 := -($t4, $t5) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8 + # refs: [] + # + 5: $t10 := 3 + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t10 + # refs: [] + # + 6: $t9 := *($t10, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t8, $t9 + # refs: [] + # + 7: $t7 := -($t8, $t9) + # abort state: {returns} + # live vars: $t3, $t7 + # refs: [] + # + 8: $t2 := >($t3, $t7) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix5($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := *($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 3: $t5 := *($t6, $t0) + # abort state: {returns} + # live vars: $t3, $t5 + # refs: [] + # + 4: $t2 := ==($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix6($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 1: $t6 := 2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5, $t6 + # refs: [] + # + 2: $t4 := *($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 3: $t3 := *($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9 + # refs: [] + # + 5: $t10 := 3 + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9, $t10 + # refs: [] + # + 6: $t8 := *($t9, $t10) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8 + # refs: [] + # + 7: $t7 := *($t8, $t1) + # abort state: {returns} + # live vars: $t3, $t7 + # refs: [] + # + 8: $t2 := >($t3, $t7) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix7($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := /($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 3: $t5 := /($t6, $t0) + # abort state: {returns} + # live vars: $t3, $t5 + # refs: [] + # + 4: $t2 := ==($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix8($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5 + # refs: [] + # + 1: $t6 := 2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t5, $t6 + # refs: [] + # + 2: $t4 := /($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 3: $t3 := *($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9 + # refs: [] + # + 5: $t10 := 3 + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t9, $t10 + # refs: [] + # + 6: $t8 := /($t9, $t10) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8 + # refs: [] + # + 7: $t7 := *($t8, $t1) + # abort state: {returns} + # live vars: $t3, $t7 + # refs: [] + # + 8: $t2 := >($t3, $t7) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix9($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t3 := %($t4, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 2: $t6 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 3: $t5 := %($t6, $t0) + # abort state: {returns} + # live vars: $t3, $t5 + # refs: [] + # + 4: $t2 := ==($t3, $t5) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 5: return $t2 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_logic { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test_cmp1(x: i64): bool { + And(And(And(And(And(Eq(x, x), Ge(x, x)), Le(x, x)), Gt(x, x)), Lt(x, x)), Eq(Borrow(Immutable)(x), Borrow(Immutable)(x))) + } + private fun test_cmp2(x: i128): bool { + And(And(And(And(And(Eq(x, x), Ge(x, x)), Le(x, x)), Gt(x, x)), Lt(x, x)), Eq(Borrow(Immutable)(x), Borrow(Immutable)(x))) + } + private fun test_cmp3(s1: S1,s2: S2,s3: S3): bool { + And(And(And(And(And(And(Eq(select valid_logic::S1.y(s1), select valid_logic::S2.y(s2)), Le(select valid_logic::S1.y(s1), select valid_logic::S3.x>(s3))), Ge(select valid_logic::S2.y(s2), select valid_logic::S3.x>(s3))), Gt(select valid_logic::S3.x>(s3), select valid_logic::S1.y(s1))), Lt(select valid_logic::S3.x>(s3), select valid_logic::S2.y(s2))), Eq(Borrow(Immutable)(select valid_logic::S1.y(s1)), Borrow(Immutable)(select valid_logic::S2.y(s2)))), Eq(Borrow(Immutable)(select valid_logic::S1.y(s1)), Borrow(Immutable)(select valid_logic::S2.y(s2)))) + } + private fun test_cmp4(s1: S1,s2: S2,s3: S3): bool { + And(And(And(And(And(And(Eq(select valid_logic::S1.z(s1), select valid_logic::S2.z(s2)), Le(select valid_logic::S1.z(s1), select valid_logic::S3.x>(s3))), Ge(select valid_logic::S2.z(s2), select valid_logic::S3.x>(s3))), Gt(select valid_logic::S3.x>(s3), select valid_logic::S1.z(s1))), Lt(select valid_logic::S3.x>(s3), select valid_logic::S2.z(s2))), Eq(Borrow(Immutable)(select valid_logic::S1.z(s1)), Borrow(Immutable)(select valid_logic::S2.z(s2)))), Eq(Borrow(Immutable)(select valid_logic::S1.z(s1)), Borrow(Immutable)(select valid_logic::S2.z(s2)))) + } + private fun test_mix1(x: i64,y: i64): bool { + Eq(Add(x, y), Add(y, x)) + } + private fun test_mix10(x: i128,y: i128): bool { + Gt(Mul(Mod(x, 2), y), Mul(Mod(x, 3), y)) + } + private fun test_mix2(x: i128,y: i128): bool { + Le(Add(x, Mul(2, y)), Add(x, Mul(3, y))) + } + private fun test_mix3(x: i64,y: i64): bool { + Eq(Sub(x, y), Sub(y, x)) + } + private fun test_mix4(x: i128,y: i128): bool { + Gt(Sub(x, Mul(2, y)), Sub(x, Mul(3, y))) + } + private fun test_mix5(x: i64,y: i64): bool { + Eq(Mul(x, y), Mul(y, x)) + } + private fun test_mix6(x: i128,y: i128): bool { + Gt(Mul(Mul(x, 2), y), Mul(Mul(x, 3), y)) + } + private fun test_mix7(x: i64,y: i64): bool { + Eq(Div(x, y), Div(y, x)) + } + private fun test_mix8(x: i128,y: i128): bool { + Gt(Mul(Div(x, 2), y), Mul(Div(x, 3), y)) + } + private fun test_mix9(x: i64,y: i64): bool { + Eq(Mod(x, y), Mod(y, x)) + } +} // end 0x42::valid_logic + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_logic::test_cmp1($t0: i64): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i64 + var $t8: i64 + var $t9: i64 + var $t10: i64 + var $t11: i64 + var $t12: &i64 + var $t13: &i64 + 0: $t7 := infer($t0) + 1: $t6 := ==($t7, $t0) + 2: if ($t6) goto 3 else goto 7 + 3: label L0 + 4: $t8 := infer($t0) + 5: $t5 := >=($t8, $t0) + 6: goto 9 + 7: label L1 + 8: $t5 := false + 9: label L2 + 10: if ($t5) goto 11 else goto 15 + 11: label L3 + 12: $t9 := infer($t0) + 13: $t4 := <=($t9, $t0) + 14: goto 17 + 15: label L4 + 16: $t4 := false + 17: label L5 + 18: if ($t4) goto 19 else goto 23 + 19: label L6 + 20: $t10 := infer($t0) + 21: $t3 := >($t10, $t0) + 22: goto 25 + 23: label L7 + 24: $t3 := false + 25: label L8 + 26: if ($t3) goto 27 else goto 31 + 27: label L9 + 28: $t11 := infer($t0) + 29: $t2 := <($t11, $t0) + 30: goto 33 + 31: label L10 + 32: $t2 := false + 33: label L11 + 34: if ($t2) goto 35 else goto 40 + 35: label L12 + 36: $t12 := borrow_local($t0) + 37: $t13 := borrow_local($t0) + 38: $t1 := ==($t12, $t13) + 39: goto 42 + 40: label L13 + 41: $t1 := false + 42: label L14 + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp2($t0: i128): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + var $t11: i128 + var $t12: &i128 + var $t13: &i128 + 0: $t7 := infer($t0) + 1: $t6 := ==($t7, $t0) + 2: if ($t6) goto 3 else goto 7 + 3: label L0 + 4: $t8 := infer($t0) + 5: $t5 := >=($t8, $t0) + 6: goto 9 + 7: label L1 + 8: $t5 := false + 9: label L2 + 10: if ($t5) goto 11 else goto 15 + 11: label L3 + 12: $t9 := infer($t0) + 13: $t4 := <=($t9, $t0) + 14: goto 17 + 15: label L4 + 16: $t4 := false + 17: label L5 + 18: if ($t4) goto 19 else goto 23 + 19: label L6 + 20: $t10 := infer($t0) + 21: $t3 := >($t10, $t0) + 22: goto 25 + 23: label L7 + 24: $t3 := false + 25: label L8 + 26: if ($t3) goto 27 else goto 31 + 27: label L9 + 28: $t11 := infer($t0) + 29: $t2 := <($t11, $t0) + 30: goto 33 + 31: label L10 + 32: $t2 := false + 33: label L11 + 34: if ($t2) goto 35 else goto 40 + 35: label L12 + 36: $t12 := borrow_local($t0) + 37: $t13 := borrow_local($t0) + 38: $t1 := ==($t12, $t13) + 39: goto 42 + 40: label L13 + 41: $t1 := false + 42: label L14 + 43: return $t1 +} + + +[variant baseline] +fun valid_logic::test_cmp3($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i64 + var $t11: &0x42::valid_logic::S1 + var $t12: &i64 + var $t13: i64 + var $t14: &0x42::valid_logic::S2 + var $t15: &i64 + var $t16: i64 + var $t17: &0x42::valid_logic::S1 + var $t18: &i64 + var $t19: i64 + var $t20: &0x42::valid_logic::S3 + var $t21: &i64 + var $t22: i64 + var $t23: &0x42::valid_logic::S2 + var $t24: &i64 + var $t25: i64 + var $t26: &0x42::valid_logic::S3 + var $t27: &i64 + var $t28: i64 + var $t29: &0x42::valid_logic::S3 + var $t30: &i64 + var $t31: i64 + var $t32: &0x42::valid_logic::S1 + var $t33: &i64 + var $t34: i64 + var $t35: &0x42::valid_logic::S3 + var $t36: &i64 + var $t37: i64 + var $t38: &0x42::valid_logic::S2 + var $t39: &i64 + var $t40: &i64 + var $t41: &0x42::valid_logic::S1 + var $t42: &i64 + var $t43: &0x42::valid_logic::S2 + var $t44: &i64 + var $t45: &0x42::valid_logic::S1 + var $t46: &i64 + var $t47: &0x42::valid_logic::S2 + 0: $t11 := borrow_local($t0) + 1: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + 2: $t10 := read_ref($t12) + 3: $t14 := borrow_local($t1) + 4: $t15 := borrow_field<0x42::valid_logic::S2>.y($t14) + 5: $t13 := read_ref($t15) + 6: $t9 := ==($t10, $t13) + 7: if ($t9) goto 8 else goto 17 + 8: label L0 + 9: $t17 := borrow_local($t0) + 10: $t18 := borrow_field<0x42::valid_logic::S1>.y($t17) + 11: $t16 := read_ref($t18) + 12: $t20 := borrow_local($t2) + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + 14: $t19 := read_ref($t21) + 15: $t8 := <=($t16, $t19) + 16: goto 19 + 17: label L1 + 18: $t8 := false + 19: label L2 + 20: if ($t8) goto 21 else goto 30 + 21: label L3 + 22: $t23 := borrow_local($t1) + 23: $t24 := borrow_field<0x42::valid_logic::S2>.y($t23) + 24: $t22 := read_ref($t24) + 25: $t26 := borrow_local($t2) + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + 27: $t25 := read_ref($t27) + 28: $t7 := >=($t22, $t25) + 29: goto 32 + 30: label L4 + 31: $t7 := false + 32: label L5 + 33: if ($t7) goto 34 else goto 43 + 34: label L6 + 35: $t29 := borrow_local($t2) + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + 37: $t28 := read_ref($t30) + 38: $t32 := borrow_local($t0) + 39: $t33 := borrow_field<0x42::valid_logic::S1>.y($t32) + 40: $t31 := read_ref($t33) + 41: $t6 := >($t28, $t31) + 42: goto 45 + 43: label L7 + 44: $t6 := false + 45: label L8 + 46: if ($t6) goto 47 else goto 56 + 47: label L9 + 48: $t35 := borrow_local($t2) + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + 50: $t34 := read_ref($t36) + 51: $t38 := borrow_local($t1) + 52: $t39 := borrow_field<0x42::valid_logic::S2>.y($t38) + 53: $t37 := read_ref($t39) + 54: $t5 := <($t34, $t37) + 55: goto 58 + 56: label L10 + 57: $t5 := false + 58: label L11 + 59: if ($t5) goto 60 else goto 67 + 60: label L12 + 61: $t41 := borrow_local($t0) + 62: $t40 := borrow_field<0x42::valid_logic::S1>.y($t41) + 63: $t43 := borrow_local($t1) + 64: $t42 := borrow_field<0x42::valid_logic::S2>.y($t43) + 65: $t4 := ==($t40, $t42) + 66: goto 69 + 67: label L13 + 68: $t4 := false + 69: label L14 + 70: if ($t4) goto 71 else goto 78 + 71: label L15 + 72: $t45 := borrow_local($t0) + 73: $t44 := borrow_field<0x42::valid_logic::S1>.y($t45) + 74: $t47 := borrow_local($t1) + 75: $t46 := borrow_field<0x42::valid_logic::S2>.y($t47) + 76: $t3 := ==($t44, $t46) + 77: goto 80 + 78: label L16 + 79: $t3 := false + 80: label L17 + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_cmp4($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool + var $t9: bool + var $t10: i128 + var $t11: &0x42::valid_logic::S1 + var $t12: &i128 + var $t13: i128 + var $t14: &0x42::valid_logic::S2 + var $t15: &i128 + var $t16: i128 + var $t17: &0x42::valid_logic::S1 + var $t18: &i128 + var $t19: i128 + var $t20: &0x42::valid_logic::S3 + var $t21: &i128 + var $t22: i128 + var $t23: &0x42::valid_logic::S2 + var $t24: &i128 + var $t25: i128 + var $t26: &0x42::valid_logic::S3 + var $t27: &i128 + var $t28: i128 + var $t29: &0x42::valid_logic::S3 + var $t30: &i128 + var $t31: i128 + var $t32: &0x42::valid_logic::S1 + var $t33: &i128 + var $t34: i128 + var $t35: &0x42::valid_logic::S3 + var $t36: &i128 + var $t37: i128 + var $t38: &0x42::valid_logic::S2 + var $t39: &i128 + var $t40: &i128 + var $t41: &0x42::valid_logic::S1 + var $t42: &i128 + var $t43: &0x42::valid_logic::S2 + var $t44: &i128 + var $t45: &0x42::valid_logic::S1 + var $t46: &i128 + var $t47: &0x42::valid_logic::S2 + 0: $t11 := borrow_local($t0) + 1: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + 2: $t10 := read_ref($t12) + 3: $t14 := borrow_local($t1) + 4: $t15 := borrow_field<0x42::valid_logic::S2>.z($t14) + 5: $t13 := read_ref($t15) + 6: $t9 := ==($t10, $t13) + 7: if ($t9) goto 8 else goto 17 + 8: label L0 + 9: $t17 := borrow_local($t0) + 10: $t18 := borrow_field<0x42::valid_logic::S1>.z($t17) + 11: $t16 := read_ref($t18) + 12: $t20 := borrow_local($t2) + 13: $t21 := borrow_field<0x42::valid_logic::S3>.x($t20) + 14: $t19 := read_ref($t21) + 15: $t8 := <=($t16, $t19) + 16: goto 19 + 17: label L1 + 18: $t8 := false + 19: label L2 + 20: if ($t8) goto 21 else goto 30 + 21: label L3 + 22: $t23 := borrow_local($t1) + 23: $t24 := borrow_field<0x42::valid_logic::S2>.z($t23) + 24: $t22 := read_ref($t24) + 25: $t26 := borrow_local($t2) + 26: $t27 := borrow_field<0x42::valid_logic::S3>.x($t26) + 27: $t25 := read_ref($t27) + 28: $t7 := >=($t22, $t25) + 29: goto 32 + 30: label L4 + 31: $t7 := false + 32: label L5 + 33: if ($t7) goto 34 else goto 43 + 34: label L6 + 35: $t29 := borrow_local($t2) + 36: $t30 := borrow_field<0x42::valid_logic::S3>.x($t29) + 37: $t28 := read_ref($t30) + 38: $t32 := borrow_local($t0) + 39: $t33 := borrow_field<0x42::valid_logic::S1>.z($t32) + 40: $t31 := read_ref($t33) + 41: $t6 := >($t28, $t31) + 42: goto 45 + 43: label L7 + 44: $t6 := false + 45: label L8 + 46: if ($t6) goto 47 else goto 56 + 47: label L9 + 48: $t35 := borrow_local($t2) + 49: $t36 := borrow_field<0x42::valid_logic::S3>.x($t35) + 50: $t34 := read_ref($t36) + 51: $t38 := borrow_local($t1) + 52: $t39 := borrow_field<0x42::valid_logic::S2>.z($t38) + 53: $t37 := read_ref($t39) + 54: $t5 := <($t34, $t37) + 55: goto 58 + 56: label L10 + 57: $t5 := false + 58: label L11 + 59: if ($t5) goto 60 else goto 67 + 60: label L12 + 61: $t41 := borrow_local($t0) + 62: $t40 := borrow_field<0x42::valid_logic::S1>.z($t41) + 63: $t43 := borrow_local($t1) + 64: $t42 := borrow_field<0x42::valid_logic::S2>.z($t43) + 65: $t4 := ==($t40, $t42) + 66: goto 69 + 67: label L13 + 68: $t4 := false + 69: label L14 + 70: if ($t4) goto 71 else goto 78 + 71: label L15 + 72: $t45 := borrow_local($t0) + 73: $t44 := borrow_field<0x42::valid_logic::S1>.z($t45) + 74: $t47 := borrow_local($t1) + 75: $t46 := borrow_field<0x42::valid_logic::S2>.z($t47) + 76: $t3 := ==($t44, $t46) + 77: goto 80 + 78: label L16 + 79: $t3 := false + 80: label L17 + 81: return $t3 +} + + +[variant baseline] +fun valid_logic::test_mix1($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := +($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := +($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix10($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := %($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := %($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix2($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t4 := infer($t0) + 1: $t6 := 2 + 2: $t5 := *($t6, $t1) + 3: $t3 := +($t4, $t5) + 4: $t8 := infer($t0) + 5: $t10 := 3 + 6: $t9 := *($t10, $t1) + 7: $t7 := +($t8, $t9) + 8: $t2 := <=($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix3($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := -($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := -($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix4($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t4 := infer($t0) + 1: $t6 := 2 + 2: $t5 := *($t6, $t1) + 3: $t3 := -($t4, $t5) + 4: $t8 := infer($t0) + 5: $t10 := 3 + 6: $t9 := *($t10, $t1) + 7: $t7 := -($t8, $t9) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix5($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := *($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := *($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix6($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := *($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := *($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix7($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := /($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := /($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix8($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 + var $t4: i128 + var $t5: i128 + var $t6: i128 + var $t7: i128 + var $t8: i128 + var $t9: i128 + var $t10: i128 + 0: $t5 := infer($t0) + 1: $t6 := 2 + 2: $t4 := /($t5, $t6) + 3: $t3 := *($t4, $t1) + 4: $t9 := infer($t0) + 5: $t10 := 3 + 6: $t8 := /($t9, $t10) + 7: $t7 := *($t8, $t1) + 8: $t2 := >($t3, $t7) + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix9($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 + var $t4: i64 + var $t5: i64 + var $t6: i64 + 0: $t4 := infer($t0) + 1: $t3 := %($t4, $t1) + 2: $t6 := infer($t1) + 3: $t5 := %($t6, $t0) + 4: $t2 := ==($t3, $t5) + 5: return $t2 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_logic::test_cmp1($t0: i64): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool [unused] + var $t6: bool + var $t7: i64 + var $t8: i64 [unused] + var $t9: i64 [unused] + var $t10: i64 [unused] + var $t11: i64 [unused] + var $t12: &i64 + var $t13: &i64 + # live vars: $t0 + 0: $t7 := copy($t0) + # live vars: $t0, $t7 + 1: $t6 := ==($t7, $t0) + # live vars: $t0, $t6 + 2: if ($t6) goto 3 else goto 40 + # live vars: $t0 + 3: label L0 + # live vars: $t0 + 4: $t7 := copy($t0) + # live vars: $t0, $t7 + 5: $t6 := >=($t7, $t0) + # live vars: $t0, $t6 + 6: label L2 + # live vars: $t0, $t6 + 7: if ($t6) goto 8 else goto 37 + # live vars: $t0 + 8: label L3 + # live vars: $t0 + 9: $t7 := copy($t0) + # live vars: $t0, $t7 + 10: $t4 := <=($t7, $t0) + # live vars: $t0, $t4 + 11: label L5 + # live vars: $t0, $t4 + 12: if ($t4) goto 13 else goto 34 + # live vars: $t0 + 13: label L6 + # live vars: $t0 + 14: $t7 := copy($t0) + # live vars: $t0, $t7 + 15: $t3 := >($t7, $t0) + # live vars: $t0, $t3 + 16: label L8 + # live vars: $t0, $t3 + 17: if ($t3) goto 18 else goto 31 + # live vars: $t0 + 18: label L9 + # live vars: $t0 + 19: $t7 := copy($t0) + # live vars: $t0, $t7 + 20: $t2 := <($t7, $t0) + # live vars: $t0, $t2 + 21: label L11 + # live vars: $t0, $t2 + 22: if ($t2) goto 23 else goto 28 + # live vars: $t0 + 23: label L12 + # live vars: $t0 + 24: $t12 := borrow_local($t0) + # live vars: $t0, $t12 + 25: $t13 := borrow_local($t0) + # live vars: $t12, $t13 + 26: $t1 := ==($t12, $t13) + # live vars: $t1 + 27: return $t1 + # live vars: $t0 + 28: label L13 + # live vars: + 29: $t1 := false + # live vars: $t1 + 30: return $t1 + # live vars: $t0 + 31: label L10 + # live vars: $t0 + 32: $t2 := false + # live vars: $t0, $t2 + 33: goto 21 + # live vars: $t0 + 34: label L7 + # live vars: $t0 + 35: $t3 := false + # live vars: $t0, $t3 + 36: goto 16 + # live vars: $t0 + 37: label L4 + # live vars: $t0 + 38: $t4 := false + # live vars: $t0, $t4 + 39: goto 11 + # live vars: $t0 + 40: label L1 + # live vars: $t0 + 41: $t6 := false + # live vars: $t0, $t6 + 42: goto 6 +} + + +[variant baseline] +fun valid_logic::test_cmp2($t0: i128): bool { + var $t1: bool + var $t2: bool + var $t3: bool + var $t4: bool + var $t5: bool [unused] + var $t6: bool + var $t7: i128 + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + var $t11: i128 [unused] + var $t12: &i128 + var $t13: &i128 + # live vars: $t0 + 0: $t7 := copy($t0) + # live vars: $t0, $t7 + 1: $t6 := ==($t7, $t0) + # live vars: $t0, $t6 + 2: if ($t6) goto 3 else goto 40 + # live vars: $t0 + 3: label L0 + # live vars: $t0 + 4: $t7 := copy($t0) + # live vars: $t0, $t7 + 5: $t6 := >=($t7, $t0) + # live vars: $t0, $t6 + 6: label L2 + # live vars: $t0, $t6 + 7: if ($t6) goto 8 else goto 37 + # live vars: $t0 + 8: label L3 + # live vars: $t0 + 9: $t7 := copy($t0) + # live vars: $t0, $t7 + 10: $t4 := <=($t7, $t0) + # live vars: $t0, $t4 + 11: label L5 + # live vars: $t0, $t4 + 12: if ($t4) goto 13 else goto 34 + # live vars: $t0 + 13: label L6 + # live vars: $t0 + 14: $t7 := copy($t0) + # live vars: $t0, $t7 + 15: $t3 := >($t7, $t0) + # live vars: $t0, $t3 + 16: label L8 + # live vars: $t0, $t3 + 17: if ($t3) goto 18 else goto 31 + # live vars: $t0 + 18: label L9 + # live vars: $t0 + 19: $t7 := copy($t0) + # live vars: $t0, $t7 + 20: $t2 := <($t7, $t0) + # live vars: $t0, $t2 + 21: label L11 + # live vars: $t0, $t2 + 22: if ($t2) goto 23 else goto 28 + # live vars: $t0 + 23: label L12 + # live vars: $t0 + 24: $t12 := borrow_local($t0) + # live vars: $t0, $t12 + 25: $t13 := borrow_local($t0) + # live vars: $t12, $t13 + 26: $t1 := ==($t12, $t13) + # live vars: $t1 + 27: return $t1 + # live vars: $t0 + 28: label L13 + # live vars: + 29: $t1 := false + # live vars: $t1 + 30: return $t1 + # live vars: $t0 + 31: label L10 + # live vars: $t0 + 32: $t2 := false + # live vars: $t0, $t2 + 33: goto 21 + # live vars: $t0 + 34: label L7 + # live vars: $t0 + 35: $t3 := false + # live vars: $t0, $t3 + 36: goto 16 + # live vars: $t0 + 37: label L4 + # live vars: $t0 + 38: $t4 := false + # live vars: $t0, $t4 + 39: goto 11 + # live vars: $t0 + 40: label L1 + # live vars: $t0 + 41: $t6 := false + # live vars: $t0, $t6 + 42: goto 6 +} + + +[variant baseline] +fun valid_logic::test_cmp3($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool [unused] + var $t9: bool + var $t10: i64 + var $t11: &0x42::valid_logic::S1 + var $t12: &i64 + var $t13: i64 + var $t14: &0x42::valid_logic::S2 + var $t15: &i64 [unused] + var $t16: i64 [unused] + var $t17: &0x42::valid_logic::S1 [unused] + var $t18: &i64 [unused] + var $t19: i64 [unused] + var $t20: &0x42::valid_logic::S3 + var $t21: &i64 [unused] + var $t22: i64 [unused] + var $t23: &0x42::valid_logic::S2 [unused] + var $t24: &i64 [unused] + var $t25: i64 [unused] + var $t26: &0x42::valid_logic::S3 [unused] + var $t27: &i64 [unused] + var $t28: i64 [unused] + var $t29: &0x42::valid_logic::S3 [unused] + var $t30: &i64 [unused] + var $t31: i64 [unused] + var $t32: &0x42::valid_logic::S1 [unused] + var $t33: &i64 [unused] + var $t34: i64 [unused] + var $t35: &0x42::valid_logic::S3 [unused] + var $t36: &i64 [unused] + var $t37: i64 [unused] + var $t38: &0x42::valid_logic::S2 [unused] + var $t39: &i64 [unused] + var $t40: &i64 [unused] + var $t41: &0x42::valid_logic::S1 [unused] + var $t42: &i64 + var $t43: &0x42::valid_logic::S2 [unused] + var $t44: &i64 [unused] + var $t45: &0x42::valid_logic::S1 [unused] + var $t46: &i64 [unused] + var $t47: &0x42::valid_logic::S2 [unused] + # live vars: $t0, $t1, $t2 + 0: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t11 + 1: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # live vars: $t0, $t1, $t2, $t12 + 2: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 3: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t10, $t14 + 4: $t12 := borrow_field<0x42::valid_logic::S2>.y($t14) + # live vars: $t0, $t1, $t2, $t10, $t12 + 5: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 6: $t9 := ==($t10, $t13) + # live vars: $t0, $t1, $t2, $t9 + 7: if ($t9) goto 8 else goto 78 + # live vars: $t0, $t1, $t2 + 8: label L0 + # live vars: $t0, $t1, $t2 + 9: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t11 + 10: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # live vars: $t0, $t1, $t2, $t12 + 11: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 12: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t10, $t20 + 13: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t10, $t12 + 14: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 15: $t9 := <=($t10, $t13) + # live vars: $t0, $t1, $t2, $t9 + 16: label L2 + # live vars: $t0, $t1, $t2, $t9 + 17: if ($t9) goto 18 else goto 75 + # live vars: $t0, $t1, $t2 + 18: label L3 + # live vars: $t0, $t1, $t2 + 19: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t14 + 20: $t12 := borrow_field<0x42::valid_logic::S2>.y($t14) + # live vars: $t0, $t1, $t2, $t12 + 21: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 22: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t10, $t20 + 23: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t10, $t12 + 24: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 25: $t7 := >=($t10, $t13) + # live vars: $t0, $t1, $t2, $t7 + 26: label L5 + # live vars: $t0, $t1, $t2, $t7 + 27: if ($t7) goto 28 else goto 72 + # live vars: $t0, $t1, $t2 + 28: label L6 + # live vars: $t0, $t1, $t2 + 29: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t20 + 30: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t12 + 31: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 32: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t10, $t11 + 33: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # live vars: $t0, $t1, $t2, $t10, $t12 + 34: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 35: $t6 := >($t10, $t13) + # live vars: $t0, $t1, $t2, $t6 + 36: label L8 + # live vars: $t0, $t1, $t2, $t6 + 37: if ($t6) goto 38 else goto 69 + # live vars: $t0, $t1, $t2 + 38: label L9 + # live vars: $t0, $t1, $t2 + 39: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t20 + 40: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t12 + 41: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t10 + 42: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t10, $t14 + 43: $t12 := borrow_field<0x42::valid_logic::S2>.y($t14) + # live vars: $t0, $t1, $t10, $t12 + 44: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t10, $t13 + 45: $t5 := <($t10, $t13) + # live vars: $t0, $t1, $t5 + 46: label L11 + # live vars: $t0, $t1, $t5 + 47: if ($t5) goto 48 else goto 66 + # live vars: $t0, $t1 + 48: label L12 + # live vars: $t0, $t1 + 49: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t11 + 50: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # live vars: $t0, $t1, $t12 + 51: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t12, $t14 + 52: $t42 := borrow_field<0x42::valid_logic::S2>.y($t14) + # live vars: $t0, $t1, $t12, $t42 + 53: $t4 := ==($t12, $t42) + # live vars: $t0, $t1, $t4 + 54: label L14 + # live vars: $t0, $t1, $t4 + 55: if ($t4) goto 56 else goto 63 + # live vars: $t0, $t1 + 56: label L15 + # live vars: $t0, $t1 + 57: $t11 := borrow_local($t0) + # live vars: $t1, $t11 + 58: $t12 := borrow_field<0x42::valid_logic::S1>.y($t11) + # live vars: $t1, $t12 + 59: $t14 := borrow_local($t1) + # live vars: $t12, $t14 + 60: $t42 := borrow_field<0x42::valid_logic::S2>.y($t14) + # live vars: $t12, $t42 + 61: $t3 := ==($t12, $t42) + # live vars: $t3 + 62: return $t3 + # live vars: $t0, $t1 + 63: label L16 + # live vars: + 64: $t3 := false + # live vars: $t3 + 65: return $t3 + # live vars: $t0, $t1 + 66: label L13 + # live vars: $t0, $t1 + 67: $t4 := false + # live vars: $t0, $t1, $t4 + 68: goto 54 + # live vars: $t0, $t1, $t2 + 69: label L10 + # live vars: $t0, $t1 + 70: $t5 := false + # live vars: $t0, $t1, $t5 + 71: goto 46 + # live vars: $t0, $t1, $t2 + 72: label L7 + # live vars: $t0, $t1, $t2 + 73: $t6 := false + # live vars: $t0, $t1, $t2, $t6 + 74: goto 36 + # live vars: $t0, $t1, $t2 + 75: label L4 + # live vars: $t0, $t1, $t2 + 76: $t7 := false + # live vars: $t0, $t1, $t2, $t7 + 77: goto 26 + # live vars: $t0, $t1, $t2 + 78: label L1 + # live vars: $t0, $t1, $t2 + 79: $t9 := false + # live vars: $t0, $t1, $t2, $t9 + 80: goto 16 +} + + +[variant baseline] +fun valid_logic::test_cmp4($t0: 0x42::valid_logic::S1, $t1: 0x42::valid_logic::S2, $t2: 0x42::valid_logic::S3): bool { + var $t3: bool + var $t4: bool + var $t5: bool + var $t6: bool + var $t7: bool + var $t8: bool [unused] + var $t9: bool + var $t10: i128 + var $t11: &0x42::valid_logic::S1 + var $t12: &i128 + var $t13: i128 + var $t14: &0x42::valid_logic::S2 + var $t15: &i128 [unused] + var $t16: i128 [unused] + var $t17: &0x42::valid_logic::S1 [unused] + var $t18: &i128 [unused] + var $t19: i128 [unused] + var $t20: &0x42::valid_logic::S3 + var $t21: &i128 [unused] + var $t22: i128 [unused] + var $t23: &0x42::valid_logic::S2 [unused] + var $t24: &i128 [unused] + var $t25: i128 [unused] + var $t26: &0x42::valid_logic::S3 [unused] + var $t27: &i128 [unused] + var $t28: i128 [unused] + var $t29: &0x42::valid_logic::S3 [unused] + var $t30: &i128 [unused] + var $t31: i128 [unused] + var $t32: &0x42::valid_logic::S1 [unused] + var $t33: &i128 [unused] + var $t34: i128 [unused] + var $t35: &0x42::valid_logic::S3 [unused] + var $t36: &i128 [unused] + var $t37: i128 [unused] + var $t38: &0x42::valid_logic::S2 [unused] + var $t39: &i128 [unused] + var $t40: &i128 [unused] + var $t41: &0x42::valid_logic::S1 [unused] + var $t42: &i128 + var $t43: &0x42::valid_logic::S2 [unused] + var $t44: &i128 [unused] + var $t45: &0x42::valid_logic::S1 [unused] + var $t46: &i128 [unused] + var $t47: &0x42::valid_logic::S2 [unused] + # live vars: $t0, $t1, $t2 + 0: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t11 + 1: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # live vars: $t0, $t1, $t2, $t12 + 2: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 3: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t10, $t14 + 4: $t12 := borrow_field<0x42::valid_logic::S2>.z($t14) + # live vars: $t0, $t1, $t2, $t10, $t12 + 5: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 6: $t9 := ==($t10, $t13) + # live vars: $t0, $t1, $t2, $t9 + 7: if ($t9) goto 8 else goto 78 + # live vars: $t0, $t1, $t2 + 8: label L0 + # live vars: $t0, $t1, $t2 + 9: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t11 + 10: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # live vars: $t0, $t1, $t2, $t12 + 11: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 12: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t10, $t20 + 13: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t10, $t12 + 14: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 15: $t9 := <=($t10, $t13) + # live vars: $t0, $t1, $t2, $t9 + 16: label L2 + # live vars: $t0, $t1, $t2, $t9 + 17: if ($t9) goto 18 else goto 75 + # live vars: $t0, $t1, $t2 + 18: label L3 + # live vars: $t0, $t1, $t2 + 19: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t2, $t14 + 20: $t12 := borrow_field<0x42::valid_logic::S2>.z($t14) + # live vars: $t0, $t1, $t2, $t12 + 21: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 22: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t10, $t20 + 23: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t10, $t12 + 24: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 25: $t7 := >=($t10, $t13) + # live vars: $t0, $t1, $t2, $t7 + 26: label L5 + # live vars: $t0, $t1, $t2, $t7 + 27: if ($t7) goto 28 else goto 72 + # live vars: $t0, $t1, $t2 + 28: label L6 + # live vars: $t0, $t1, $t2 + 29: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t2, $t20 + 30: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t2, $t12 + 31: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10 + 32: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t2, $t10, $t11 + 33: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # live vars: $t0, $t1, $t2, $t10, $t12 + 34: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t2, $t10, $t13 + 35: $t6 := >($t10, $t13) + # live vars: $t0, $t1, $t2, $t6 + 36: label L8 + # live vars: $t0, $t1, $t2, $t6 + 37: if ($t6) goto 38 else goto 69 + # live vars: $t0, $t1, $t2 + 38: label L9 + # live vars: $t0, $t1, $t2 + 39: $t20 := borrow_local($t2) + # live vars: $t0, $t1, $t20 + 40: $t12 := borrow_field<0x42::valid_logic::S3>.x($t20) + # live vars: $t0, $t1, $t12 + 41: $t10 := read_ref($t12) + # live vars: $t0, $t1, $t10 + 42: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t10, $t14 + 43: $t12 := borrow_field<0x42::valid_logic::S2>.z($t14) + # live vars: $t0, $t1, $t10, $t12 + 44: $t13 := read_ref($t12) + # live vars: $t0, $t1, $t10, $t13 + 45: $t5 := <($t10, $t13) + # live vars: $t0, $t1, $t5 + 46: label L11 + # live vars: $t0, $t1, $t5 + 47: if ($t5) goto 48 else goto 66 + # live vars: $t0, $t1 + 48: label L12 + # live vars: $t0, $t1 + 49: $t11 := borrow_local($t0) + # live vars: $t0, $t1, $t11 + 50: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # live vars: $t0, $t1, $t12 + 51: $t14 := borrow_local($t1) + # live vars: $t0, $t1, $t12, $t14 + 52: $t42 := borrow_field<0x42::valid_logic::S2>.z($t14) + # live vars: $t0, $t1, $t12, $t42 + 53: $t4 := ==($t12, $t42) + # live vars: $t0, $t1, $t4 + 54: label L14 + # live vars: $t0, $t1, $t4 + 55: if ($t4) goto 56 else goto 63 + # live vars: $t0, $t1 + 56: label L15 + # live vars: $t0, $t1 + 57: $t11 := borrow_local($t0) + # live vars: $t1, $t11 + 58: $t12 := borrow_field<0x42::valid_logic::S1>.z($t11) + # live vars: $t1, $t12 + 59: $t14 := borrow_local($t1) + # live vars: $t12, $t14 + 60: $t42 := borrow_field<0x42::valid_logic::S2>.z($t14) + # live vars: $t12, $t42 + 61: $t3 := ==($t12, $t42) + # live vars: $t3 + 62: return $t3 + # live vars: $t0, $t1 + 63: label L16 + # live vars: + 64: $t3 := false + # live vars: $t3 + 65: return $t3 + # live vars: $t0, $t1 + 66: label L13 + # live vars: $t0, $t1 + 67: $t4 := false + # live vars: $t0, $t1, $t4 + 68: goto 54 + # live vars: $t0, $t1, $t2 + 69: label L10 + # live vars: $t0, $t1 + 70: $t5 := false + # live vars: $t0, $t1, $t5 + 71: goto 46 + # live vars: $t0, $t1, $t2 + 72: label L7 + # live vars: $t0, $t1, $t2 + 73: $t6 := false + # live vars: $t0, $t1, $t2, $t6 + 74: goto 36 + # live vars: $t0, $t1, $t2 + 75: label L4 + # live vars: $t0, $t1, $t2 + 76: $t7 := false + # live vars: $t0, $t1, $t2, $t7 + 77: goto 26 + # live vars: $t0, $t1, $t2 + 78: label L1 + # live vars: $t0, $t1, $t2 + 79: $t9 := false + # live vars: $t0, $t1, $t2, $t9 + 80: goto 16 +} + + +[variant baseline] +fun valid_logic::test_mix1($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := +($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t1 := move($t1) + # live vars: $t0, $t1, $t4 + 3: $t0 := +($t1, $t0) + # live vars: $t0, $t4 + 4: $t2 := ==($t4, $t0) + # live vars: $t2 + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix10($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + # live vars: $t0, $t1 + 0: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 1: $t6 := 2 + # live vars: $t0, $t1, $t5, $t6 + 2: $t5 := %($t5, $t6) + # live vars: $t0, $t1, $t5 + 3: $t5 := *($t5, $t1) + # live vars: $t0, $t1, $t5 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t5 + 5: $t6 := 3 + # live vars: $t0, $t1, $t5, $t6 + 6: $t0 := %($t0, $t6) + # live vars: $t0, $t1, $t5 + 7: $t0 := *($t0, $t1) + # live vars: $t0, $t5 + 8: $t2 := >($t5, $t0) + # live vars: $t2 + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix2($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 [unused] + var $t4: i128 + var $t5: i128 [unused] + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t6 := 2 + # live vars: $t0, $t1, $t4, $t6 + 2: $t6 := *($t6, $t1) + # live vars: $t0, $t1, $t4, $t6 + 3: $t4 := +($t4, $t6) + # live vars: $t0, $t1, $t4 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t4 + 5: $t6 := 3 + # live vars: $t0, $t1, $t4, $t6 + 6: $t1 := *($t6, $t1) + # live vars: $t0, $t1, $t4 + 7: $t0 := +($t0, $t1) + # live vars: $t0, $t4 + 8: $t2 := <=($t4, $t0) + # live vars: $t2 + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix3($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := -($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t1 := move($t1) + # live vars: $t0, $t1, $t4 + 3: $t0 := -($t1, $t0) + # live vars: $t0, $t4 + 4: $t2 := ==($t4, $t0) + # live vars: $t2 + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix4($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 [unused] + var $t4: i128 + var $t5: i128 [unused] + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t6 := 2 + # live vars: $t0, $t1, $t4, $t6 + 2: $t6 := *($t6, $t1) + # live vars: $t0, $t1, $t4, $t6 + 3: $t4 := -($t4, $t6) + # live vars: $t0, $t1, $t4 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t4 + 5: $t6 := 3 + # live vars: $t0, $t1, $t4, $t6 + 6: $t1 := *($t6, $t1) + # live vars: $t0, $t1, $t4 + 7: $t0 := -($t0, $t1) + # live vars: $t0, $t4 + 8: $t2 := >($t4, $t0) + # live vars: $t2 + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix5($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := *($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t1 := move($t1) + # live vars: $t0, $t1, $t4 + 3: $t0 := *($t1, $t0) + # live vars: $t0, $t4 + 4: $t2 := ==($t4, $t0) + # live vars: $t2 + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix6($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + # live vars: $t0, $t1 + 0: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 1: $t6 := 2 + # live vars: $t0, $t1, $t5, $t6 + 2: $t5 := *($t5, $t6) + # live vars: $t0, $t1, $t5 + 3: $t5 := *($t5, $t1) + # live vars: $t0, $t1, $t5 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t5 + 5: $t6 := 3 + # live vars: $t0, $t1, $t5, $t6 + 6: $t0 := *($t0, $t6) + # live vars: $t0, $t1, $t5 + 7: $t0 := *($t0, $t1) + # live vars: $t0, $t5 + 8: $t2 := >($t5, $t0) + # live vars: $t2 + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix7($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := /($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t1 := move($t1) + # live vars: $t0, $t1, $t4 + 3: $t0 := /($t1, $t0) + # live vars: $t0, $t4 + 4: $t2 := ==($t4, $t0) + # live vars: $t2 + 5: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix8($t0: i128, $t1: i128): bool { + var $t2: bool + var $t3: i128 [unused] + var $t4: i128 [unused] + var $t5: i128 + var $t6: i128 + var $t7: i128 [unused] + var $t8: i128 [unused] + var $t9: i128 [unused] + var $t10: i128 [unused] + # live vars: $t0, $t1 + 0: $t5 := copy($t0) + # live vars: $t0, $t1, $t5 + 1: $t6 := 2 + # live vars: $t0, $t1, $t5, $t6 + 2: $t5 := /($t5, $t6) + # live vars: $t0, $t1, $t5 + 3: $t5 := *($t5, $t1) + # live vars: $t0, $t1, $t5 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t5 + 5: $t6 := 3 + # live vars: $t0, $t1, $t5, $t6 + 6: $t0 := /($t0, $t6) + # live vars: $t0, $t1, $t5 + 7: $t0 := *($t0, $t1) + # live vars: $t0, $t5 + 8: $t2 := >($t5, $t0) + # live vars: $t2 + 9: return $t2 +} + + +[variant baseline] +fun valid_logic::test_mix9($t0: i64, $t1: i64): bool { + var $t2: bool + var $t3: i64 [unused] + var $t4: i64 + var $t5: i64 [unused] + var $t6: i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := copy($t0) + # live vars: $t0, $t1, $t4 + 1: $t4 := %($t4, $t1) + # live vars: $t0, $t1, $t4 + 2: $t1 := move($t1) + # live vars: $t0, $t1, $t4 + 3: $t0 := %($t1, $t0) + # live vars: $t0, $t4 + 4: $t2 := ==($t4, $t0) + # live vars: $t2 + 5: return $t2 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_logic +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test_cmp1(l0: i64): bool + local l1: bool + local l2: bool + local l3: bool + local l4: bool + copy_loc l0 + copy_loc l0 + eq + br_false l0 + copy_loc l0 + // @5 + copy_loc l0 + ge + st_loc l1 +l8: move_loc l1 + br_false l1 + // @10 + copy_loc l0 + copy_loc l0 + le + st_loc l2 +l7: move_loc l2 + // @15 + br_false l2 + copy_loc l0 + copy_loc l0 + gt + st_loc l3 + // @20 +l6: move_loc l3 + br_false l3 + copy_loc l0 + copy_loc l0 + lt + // @25 + st_loc l4 +l5: move_loc l4 + br_false l4 + borrow_loc l0 + borrow_loc l0 + // @30 + eq + ret +l4: ld_false + ret +l3: ld_false + // @35 + st_loc l4 + branch l5 +l2: ld_false + st_loc l3 + branch l6 + // @40 +l1: ld_false + st_loc l2 + branch l7 +l0: ld_false + st_loc l1 + // @45 + branch l8 + +// Function definition at index 1 +fun test_cmp2(l0: i128): bool + local l1: bool + local l2: bool + local l3: bool + local l4: bool + copy_loc l0 + copy_loc l0 + eq + br_false l0 + copy_loc l0 + // @5 + copy_loc l0 + ge + st_loc l1 +l8: move_loc l1 + br_false l1 + // @10 + copy_loc l0 + copy_loc l0 + le + st_loc l2 +l7: move_loc l2 + // @15 + br_false l2 + copy_loc l0 + copy_loc l0 + gt + st_loc l3 + // @20 +l6: move_loc l3 + br_false l3 + copy_loc l0 + copy_loc l0 + lt + // @25 + st_loc l4 +l5: move_loc l4 + br_false l4 + borrow_loc l0 + borrow_loc l0 + // @30 + eq + ret +l4: ld_false + ret +l3: ld_false + // @35 + st_loc l4 + branch l5 +l2: ld_false + st_loc l3 + branch l6 + // @40 +l1: ld_false + st_loc l2 + branch l7 +l0: ld_false + st_loc l1 + // @45 + branch l8 + +// Function definition at index 2 +fun test_cmp3(l0: S1, l1: S2, l2: S3): bool + local l3: bool + local l4: bool + local l5: bool + local l6: bool + local l7: bool + borrow_loc l0 + borrow_field S1, y + read_ref + borrow_loc l1 + borrow_field S2, y + // @5 + read_ref + eq + br_false l0 + borrow_loc l0 + borrow_field S1, y + // @10 + read_ref + borrow_loc l2 + borrow_field S3, x + read_ref + le + // @15 + st_loc l3 +l10: move_loc l3 + br_false l1 + borrow_loc l1 + borrow_field S2, y + // @20 + read_ref + borrow_loc l2 + borrow_field S3, x + read_ref + ge + // @25 + st_loc l4 +l9: move_loc l4 + br_false l2 + borrow_loc l2 + borrow_field S3, x + // @30 + read_ref + borrow_loc l0 + borrow_field S1, y + read_ref + gt + // @35 + st_loc l5 +l8: move_loc l5 + br_false l3 + borrow_loc l2 + borrow_field S3, x + // @40 + read_ref + borrow_loc l1 + borrow_field S2, y + read_ref + lt + // @45 + st_loc l6 +l7: move_loc l6 + br_false l4 + borrow_loc l0 + borrow_field S1, y + // @50 + borrow_loc l1 + borrow_field S2, y + eq + st_loc l7 +l6: move_loc l7 + // @55 + br_false l5 + borrow_loc l0 + borrow_field S1, y + borrow_loc l1 + borrow_field S2, y + // @60 + eq + ret +l5: ld_false + ret +l4: ld_false + // @65 + st_loc l7 + branch l6 +l3: ld_false + st_loc l6 + branch l7 + // @70 +l2: ld_false + st_loc l5 + branch l8 +l1: ld_false + st_loc l4 + // @75 + branch l9 +l0: ld_false + st_loc l3 + branch l10 + +// Function definition at index 3 +fun test_cmp4(l0: S1, l1: S2, l2: S3): bool + local l3: bool + local l4: bool + local l5: bool + local l6: bool + local l7: bool + borrow_loc l0 + borrow_field S1, z + read_ref + borrow_loc l1 + borrow_field S2, z + // @5 + read_ref + eq + br_false l0 + borrow_loc l0 + borrow_field S1, z + // @10 + read_ref + borrow_loc l2 + borrow_field S3, x + read_ref + le + // @15 + st_loc l3 +l10: move_loc l3 + br_false l1 + borrow_loc l1 + borrow_field S2, z + // @20 + read_ref + borrow_loc l2 + borrow_field S3, x + read_ref + ge + // @25 + st_loc l4 +l9: move_loc l4 + br_false l2 + borrow_loc l2 + borrow_field S3, x + // @30 + read_ref + borrow_loc l0 + borrow_field S1, z + read_ref + gt + // @35 + st_loc l5 +l8: move_loc l5 + br_false l3 + borrow_loc l2 + borrow_field S3, x + // @40 + read_ref + borrow_loc l1 + borrow_field S2, z + read_ref + lt + // @45 + st_loc l6 +l7: move_loc l6 + br_false l4 + borrow_loc l0 + borrow_field S1, z + // @50 + borrow_loc l1 + borrow_field S2, z + eq + st_loc l7 +l6: move_loc l7 + // @55 + br_false l5 + borrow_loc l0 + borrow_field S1, z + borrow_loc l1 + borrow_field S2, z + // @60 + eq + ret +l5: ld_false + ret +l4: ld_false + // @65 + st_loc l7 + branch l6 +l3: ld_false + st_loc l6 + branch l7 + // @70 +l2: ld_false + st_loc l5 + branch l8 +l1: ld_false + st_loc l4 + // @75 + branch l9 +l0: ld_false + st_loc l3 + branch l10 + +// Function definition at index 4 +fun test_mix1(l0: i64, l1: i64): bool + copy_loc l0 + copy_loc l1 + add + move_loc l1 + move_loc l0 + // @5 + add + eq + ret + +// Function definition at index 5 +fun test_mix10(l0: i128, l1: i128): bool + copy_loc l0 + ld_i128 2 + mod + copy_loc l1 + mul + // @5 + move_loc l0 + ld_i128 3 + mod + move_loc l1 + mul + // @10 + gt + ret + +// Function definition at index 6 +fun test_mix2(l0: i128, l1: i128): bool + copy_loc l0 + ld_i128 2 + copy_loc l1 + mul + add + // @5 + move_loc l0 + ld_i128 3 + move_loc l1 + mul + add + // @10 + le + ret + +// Function definition at index 7 +fun test_mix3(l0: i64, l1: i64): bool + copy_loc l0 + copy_loc l1 + sub + move_loc l1 + move_loc l0 + // @5 + sub + eq + ret + +// Function definition at index 8 +fun test_mix4(l0: i128, l1: i128): bool + copy_loc l0 + ld_i128 2 + copy_loc l1 + mul + sub + // @5 + move_loc l0 + ld_i128 3 + move_loc l1 + mul + sub + // @10 + gt + ret + +// Function definition at index 9 +fun test_mix5(l0: i64, l1: i64): bool + copy_loc l0 + copy_loc l1 + mul + move_loc l1 + move_loc l0 + // @5 + mul + eq + ret + +// Function definition at index 10 +fun test_mix6(l0: i128, l1: i128): bool + copy_loc l0 + ld_i128 2 + mul + copy_loc l1 + mul + // @5 + move_loc l0 + ld_i128 3 + mul + move_loc l1 + mul + // @10 + gt + ret + +// Function definition at index 11 +fun test_mix7(l0: i64, l1: i64): bool + copy_loc l0 + copy_loc l1 + div + move_loc l1 + move_loc l0 + // @5 + div + eq + ret + +// Function definition at index 12 +fun test_mix8(l0: i128, l1: i128): bool + copy_loc l0 + ld_i128 2 + div + copy_loc l1 + mul + // @5 + move_loc l0 + ld_i128 3 + div + move_loc l1 + mul + // @10 + gt + ret + +// Function definition at index 13 +fun test_mix9(l0: i64, l1: i64): bool + copy_loc l0 + copy_loc l1 + mod + move_loc l1 + move_loc l0 + // @5 + mod + eq + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.move new file mode 100644 index 00000000000..4f175c6aa6b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_logic.move @@ -0,0 +1,81 @@ +module 0x42::valid_logic { + struct S1 has copy, drop { x: u64, y: i64, z: i128 } + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } + + struct S3 has copy, drop { x: T, y: S1, z: S2 } + + enum E1 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test_cmp1(x: i64): bool { + x == x && x >= x && x<= x && x > x && x < x && &x == &x + } + + fun test_cmp2(x: i128): bool { + x == x && x >= x && x<= x && x > x && x < x && &x == &x + } + + fun test_cmp3(s1: S1, s2: S2, s3: S3): bool { + s1.y == s2.y && s1.y <= s3.x && s2.y >= s3.x && s3.x > s1.y && s3.x < s2.y && &s1.y == &s2.y && &s1.y == &s2.y + } + + fun test_cmp4(s1: S1, s2: S2, s3: S3): bool { + s1.z == s2.z && s1.z <= s3.x && s2.z >= s3.x && s3.x > s1.z && s3.x < s2.z && &s1.z == &s2.z && &s1.z == &s2.z + } + + fun test_mix1(x: i64, y: i64): bool { + x + y == y + x + } + + fun test_mix2(x: i128, y: i128): bool { + x + 2*y <= x + 3*y + } + + fun test_mix3(x: i64, y: i64): bool { + x - y == y - x + } + + fun test_mix4(x: i128, y: i128): bool { + x - 2*y > x -3*y + } + + fun test_mix5(x: i64, y: i64): bool { + x * y == y * x + } + + fun test_mix6(x: i128, y: i128): bool { + x * 2*y > x * 3*y + } + + fun test_mix7(x: i64, y: i64): bool { + x / y == y / x + } + + fun test_mix8(x: i128, y: i128): bool { + x / 2*y > x / 3*y + } + + fun test_mix9(x: i64, y: i64): bool { + x % y == y % x + } + + fun test_mix10(x: i128, y: i128): bool { + x % 2*y > x % 3*y + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp new file mode 100644 index 00000000000..5314452a25e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.exp @@ -0,0 +1,1263 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_ref_resource { + use std::signer; + struct S1 { + x: u64, + y: i64, + z: i128, + } + private fun test_borrow1(a: &i64): &i64 { + a + } + private fun test_borrow2(a: &i128): &i128 { + a + } + private fun test_deref1(a: &i64): i64 { + Deref(a) + } + private fun test_deref2(a: &i128): i128 { + Deref(a) + } + private fun test_exist1(addr: address): i64 { + if exists(addr) { + { + let s: &S1 = BorrowGlobal(Immutable)(addr); + select valid_ref_resource::S1.y<&S1>(s) + } + } else { + 1 + } + } + private fun test_exist2(addr: address): i128 { + if exists(addr) { + { + let s: &S1 = BorrowGlobal(Immutable)(addr); + select valid_ref_resource::S1.z<&S1>(s) + } + } else { + 1 + } + } + private fun test_move_from(account: &signer,addr: address): i64 { + { + let s1: S1 = pack valid_ref_resource::S1(1, -1, -2); + if exists(addr) { + select valid_ref_resource::S1.y(MoveFrom(signer::address_of(account))) + } else { + select valid_ref_resource::S1.y(s1) + } + } + } + private fun test_move_to(account: &signer,addr: address) { + { + let s1: S1 = pack valid_ref_resource::S1(1, -1, -2); + if Not(exists(addr)) { + MoveTo(account, s1) + } else { + Tuple() + } + } + } +} // end 0x42::valid_ref_resource + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_ref_resource { + use std::signer; + struct S1 has copy, drop, key { + x: u64, + y: i64, + z: i128, + } + fun test_borrow1(a: &i64): &i64 { + a + } + fun test_borrow2(a: &i128): &i128 { + a + } + fun test_deref1(a: &i64): i64 { + *a + } + fun test_deref2(a: &i128): i128 { + *a + } + fun test_exist1(addr: address): i64 { + if (exists(addr)) { + let s = borrow_global(addr); + s.y + } else 1i64 + } + fun test_exist2(addr: address): i128 { + if (exists(addr)) { + let s = borrow_global(addr); + s.z + } else 1i128 + } + fun test_move_from(account: &signer, addr: address): i64 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + if (exists(addr)) move_from(0x1::signer::address_of(account)).y else s1.y + } + fun test_move_to(account: &signer, addr: address) { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + if (!exists(addr)) move_to(s1, account) + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_ref_resource::test_borrow1($t0: &i64): &i64 { + var $t1: &i64 + 0: $t1 := infer($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_borrow2($t0: &i128): &i128 { + var $t1: &i128 + 0: $t1 := infer($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref1($t0: &i64): i64 { + var $t1: i64 + 0: $t1 := read_ref($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref2($t0: &i128): i128 { + var $t1: i128 + 0: $t1 := read_ref($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist1($t0: address): i64 { + var $t1: i64 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i64 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + 1: if ($t2) goto 2 else goto 7 + 2: label L0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.y($t3) + 5: $t1 := read_ref($t4) + 6: goto 9 + 7: label L1 + 8: $t1 := 1 + 9: label L2 + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist2($t0: address): i128 { + var $t1: i128 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i128 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + 1: if ($t2) goto 2 else goto 7 + 2: label L0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.z($t3) + 5: $t1 := read_ref($t4) + 6: goto 9 + 7: label L1 + 8: $t1 := 1 + 9: label L2 + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_move_from($t0: &signer, $t1: address): i64 { + var $t2: i64 + var $t3: 0x42::valid_ref_resource::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: bool + var $t8: 0x42::valid_ref_resource::S1 + var $t9: address + var $t10: &0x42::valid_ref_resource::S1 + var $t11: &i64 + var $t12: &0x42::valid_ref_resource::S1 + var $t13: &i64 + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_ref_resource::S1($t4, $t5, $t6) + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + 5: if ($t7) goto 6 else goto 13 + 6: label L0 + 7: $t9 := signer::address_of($t0) + 8: $t8 := move_from<0x42::valid_ref_resource::S1>($t9) + 9: $t10 := borrow_local($t8) + 10: $t11 := borrow_field<0x42::valid_ref_resource::S1>.y($t10) + 11: $t2 := read_ref($t11) + 12: goto 17 + 13: label L1 + 14: $t12 := borrow_local($t3) + 15: $t13 := borrow_field<0x42::valid_ref_resource::S1>.y($t12) + 16: $t2 := read_ref($t13) + 17: label L2 + 18: return $t2 +} + + +[variant baseline] +fun valid_ref_resource::test_move_to($t0: &signer, $t1: address) { + var $t2: 0x42::valid_ref_resource::S1 + var $t3: u64 + var $t4: i64 + var $t5: i128 + var $t6: bool + var $t7: bool + var $t8: &signer + 0: $t3 := 1 + 1: $t4 := -1 + 2: $t5 := -2 + 3: $t2 := pack 0x42::valid_ref_resource::S1($t3, $t4, $t5) + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + 5: $t6 := !($t7) + 6: if ($t6) goto 7 else goto 11 + 7: label L0 + 8: $t8 := infer($t0) + 9: move_to<0x42::valid_ref_resource::S1>($t8, $t2) + 10: goto 12 + 11: label L1 + 12: label L2 + 13: return () +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_ref_resource::test_borrow1($t0: &i64): &i64 { + var $t1: &i64 + # abort state: {returns} + # live vars: $t0 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t1 := infer($t0) + # abort state: {returns} + # live vars: $t1 + # refs: [$t1 => #1] + # #1 + # + # #root + # + # + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_borrow2($t0: &i128): &i128 { + var $t1: &i128 + # abort state: {returns} + # live vars: $t0 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t1 := infer($t0) + # abort state: {returns} + # live vars: $t1 + # refs: [$t1 => #1] + # #1 + # + # #root + # + # + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref1($t0: &i64): i64 { + var $t1: i64 + # abort state: {returns} + # live vars: $t0 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t1 := read_ref($t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref2($t0: &i128): i128 { + var $t1: i128 + # abort state: {returns} + # live vars: $t0 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t1 := read_ref($t0) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist1($t0: address): i64 { + var $t1: i64 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i64 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: if ($t2) goto 2 else goto 7 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 2: label L0 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + # abort state: {returns} + # live vars: $t3 + # refs: [$t3 => #3] + # #3 + # + # #root + # -> #3 via [struct `valid_ref_resource::S1`] at line 24 + # + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.y($t3) + # abort state: {returns} + # live vars: $t4 + # refs: [$t4 => #4] + # #4 + # + # #root + # -> #4 via [struct `valid_ref_resource::S1`] at line 25 + # + 5: $t1 := read_ref($t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 6: goto 9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 7: label L1 + # abort state: {returns} + # live vars: + # refs: [] + # + 8: $t1 := 1 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist2($t0: address): i128 { + var $t1: i128 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i128 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: if ($t2) goto 2 else goto 7 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 2: label L0 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + # abort state: {returns} + # live vars: $t3 + # refs: [$t3 => #3] + # #3 + # + # #root + # -> #3 via [struct `valid_ref_resource::S1`] at line 33 + # + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.z($t3) + # abort state: {returns} + # live vars: $t4 + # refs: [$t4 => #4] + # #4 + # + # #root + # -> #4 via [struct `valid_ref_resource::S1`] at line 34 + # + 5: $t1 := read_ref($t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 6: goto 9 + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 7: label L1 + # abort state: {returns} + # live vars: + # refs: [] + # + 8: $t1 := 1 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 9: label L2 + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_move_from($t0: &signer, $t1: address): i64 { + var $t2: i64 + var $t3: 0x42::valid_ref_resource::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: bool + var $t8: 0x42::valid_ref_resource::S1 + var $t9: address + var $t10: &0x42::valid_ref_resource::S1 + var $t11: &i64 + var $t12: &0x42::valid_ref_resource::S1 + var $t13: &i64 + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 3: $t3 := pack 0x42::valid_ref_resource::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t7 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 5: if ($t7) goto 6 else goto 13 + # abort state: {returns,aborts} + # live vars: $t0, $t3 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 6: label L0 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 7: $t9 := signer::address_of($t0) + # abort state: {returns,aborts} + # live vars: $t9 + # refs: [] + # + 8: $t8 := move_from<0x42::valid_ref_resource::S1>($t9) + # abort state: {returns} + # live vars: $t8 + # refs: [] + # + 9: $t10 := borrow_local($t8) + # abort state: {returns} + # live vars: $t10 + # refs: [$t10 => #10] + # #10 + # + # #root + # => #10 via [value] at line 50 + # + 10: $t11 := borrow_field<0x42::valid_ref_resource::S1>.y($t10) + # abort state: {returns} + # live vars: $t11 + # refs: [$t11 => #11] + # #11 + # + # #root + # => #11 via [value, field `y`] at line 50 + # + 11: $t2 := read_ref($t11) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 12: goto 17 + # abort state: {returns} + # live vars: $t0, $t3 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 13: label L1 + # abort state: {returns} + # live vars: $t3 + # refs: [] + # + 14: $t12 := borrow_local($t3) + # abort state: {returns} + # live vars: $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => #12 via [local `s1`] at line 52 + # + 15: $t13 := borrow_field<0x42::valid_ref_resource::S1>.y($t12) + # abort state: {returns} + # live vars: $t13 + # refs: [$t13 => #13] + # #13 + # + # #root + # => #13 via [local `s1`, field `y`] at line 52 + # + 16: $t2 := read_ref($t13) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 17: label L2 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 18: return $t2 +} + + +[variant baseline] +fun valid_ref_resource::test_move_to($t0: &signer, $t1: address) { + var $t2: 0x42::valid_ref_resource::S1 + var $t3: u64 + var $t4: i64 + var $t5: i128 + var $t6: bool + var $t7: bool + var $t8: &signer + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 0: $t3 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 1: $t4 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t4 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 2: $t5 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t4, $t5 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 3: $t2 := pack 0x42::valid_ref_resource::S1($t3, $t4, $t5) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t2 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t7 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 5: $t6 := !($t7) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t6 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 6: if ($t6) goto 7 else goto 11 + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 7: label L0 + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 8: $t8 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t2, $t8 + # refs: [$t8 => #8] + # #8 + # + # #root + # + # + 9: move_to<0x42::valid_ref_resource::S1>($t8, $t2) + # abort state: {returns} + # live vars: + # refs: [] + # + 10: goto 12 + # abort state: {returns} + # live vars: $t0, $t2 + # refs: [$t0 => #0] + # #0 + # + # #root + # + # + 11: label L1 + # abort state: {returns} + # live vars: + # refs: [] + # + 12: label L2 + # abort state: {returns} + # live vars: + # refs: [] + # + 13: return () +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_ref_resource { + use std::signer; + struct S1 { + x: u64, + y: i64, + z: i128, + } + private fun test_borrow1(a: &i64): &i64 { + a + } + private fun test_borrow2(a: &i128): &i128 { + a + } + private fun test_deref1(a: &i64): i64 { + Deref(a) + } + private fun test_deref2(a: &i128): i128 { + Deref(a) + } + private fun test_exist1(addr: address): i64 { + if exists(addr) { + { + let s: &S1 = BorrowGlobal(Immutable)(addr); + select valid_ref_resource::S1.y<&S1>(s) + } + } else { + 1 + } + } + private fun test_exist2(addr: address): i128 { + if exists(addr) { + { + let s: &S1 = BorrowGlobal(Immutable)(addr); + select valid_ref_resource::S1.z<&S1>(s) + } + } else { + 1 + } + } + private fun test_move_from(account: &signer,addr: address): i64 { + { + let s1: S1 = pack valid_ref_resource::S1(1, -1, -2); + if exists(addr) { + select valid_ref_resource::S1.y(MoveFrom(signer::address_of(account))) + } else { + select valid_ref_resource::S1.y(s1) + } + } + } + private fun test_move_to(account: &signer,addr: address) { + { + let s1: S1 = pack valid_ref_resource::S1(1, -1, -2); + if Not(exists(addr)) { + MoveTo(account, s1) + } else { + Tuple() + } + } + } +} // end 0x42::valid_ref_resource + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_ref_resource::test_borrow1($t0: &i64): &i64 { + var $t1: &i64 + 0: $t1 := infer($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_borrow2($t0: &i128): &i128 { + var $t1: &i128 + 0: $t1 := infer($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref1($t0: &i64): i64 { + var $t1: i64 + 0: $t1 := read_ref($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref2($t0: &i128): i128 { + var $t1: i128 + 0: $t1 := read_ref($t0) + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist1($t0: address): i64 { + var $t1: i64 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i64 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + 1: if ($t2) goto 2 else goto 7 + 2: label L0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.y($t3) + 5: $t1 := read_ref($t4) + 6: goto 9 + 7: label L1 + 8: $t1 := 1 + 9: label L2 + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist2($t0: address): i128 { + var $t1: i128 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i128 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + 1: if ($t2) goto 2 else goto 7 + 2: label L0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.z($t3) + 5: $t1 := read_ref($t4) + 6: goto 9 + 7: label L1 + 8: $t1 := 1 + 9: label L2 + 10: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_move_from($t0: &signer, $t1: address): i64 { + var $t2: i64 + var $t3: 0x42::valid_ref_resource::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: bool + var $t8: 0x42::valid_ref_resource::S1 + var $t9: address + var $t10: &0x42::valid_ref_resource::S1 + var $t11: &i64 + var $t12: &0x42::valid_ref_resource::S1 + var $t13: &i64 + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_ref_resource::S1($t4, $t5, $t6) + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + 5: if ($t7) goto 6 else goto 13 + 6: label L0 + 7: $t9 := signer::address_of($t0) + 8: $t8 := move_from<0x42::valid_ref_resource::S1>($t9) + 9: $t10 := borrow_local($t8) + 10: $t11 := borrow_field<0x42::valid_ref_resource::S1>.y($t10) + 11: $t2 := read_ref($t11) + 12: goto 17 + 13: label L1 + 14: $t12 := borrow_local($t3) + 15: $t13 := borrow_field<0x42::valid_ref_resource::S1>.y($t12) + 16: $t2 := read_ref($t13) + 17: label L2 + 18: return $t2 +} + + +[variant baseline] +fun valid_ref_resource::test_move_to($t0: &signer, $t1: address) { + var $t2: 0x42::valid_ref_resource::S1 + var $t3: u64 + var $t4: i64 + var $t5: i128 + var $t6: bool + var $t7: bool + var $t8: &signer + 0: $t3 := 1 + 1: $t4 := -1 + 2: $t5 := -2 + 3: $t2 := pack 0x42::valid_ref_resource::S1($t3, $t4, $t5) + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + 5: $t6 := !($t7) + 6: if ($t6) goto 7 else goto 11 + 7: label L0 + 8: $t8 := infer($t0) + 9: move_to<0x42::valid_ref_resource::S1>($t8, $t2) + 10: goto 12 + 11: label L1 + 12: label L2 + 13: return () +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_ref_resource::test_borrow1($t0: &i64): &i64 { + var $t1: &i64 [unused] + # live vars: $t0 + 0: return $t0 +} + + +[variant baseline] +fun valid_ref_resource::test_borrow2($t0: &i128): &i128 { + var $t1: &i128 [unused] + # live vars: $t0 + 0: return $t0 +} + + +[variant baseline] +fun valid_ref_resource::test_deref1($t0: &i64): i64 { + var $t1: i64 + # live vars: $t0 + 0: $t1 := read_ref($t0) + # live vars: $t1 + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_deref2($t0: &i128): i128 { + var $t1: i128 + # live vars: $t0 + 0: $t1 := read_ref($t0) + # live vars: $t1 + 1: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist1($t0: address): i64 { + var $t1: i64 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i64 + # live vars: $t0 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + # live vars: $t0, $t2 + 1: if ($t2) goto 2 else goto 7 + # live vars: $t0 + 2: label L0 + # live vars: $t0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + # live vars: $t3 + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.y($t3) + # live vars: $t4 + 5: $t1 := read_ref($t4) + # live vars: $t1 + 6: return $t1 + # live vars: $t0 + 7: label L1 + # live vars: + 8: $t1 := 1 + # live vars: $t1 + 9: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_exist2($t0: address): i128 { + var $t1: i128 + var $t2: bool + var $t3: &0x42::valid_ref_resource::S1 + var $t4: &i128 + # live vars: $t0 + 0: $t2 := exists<0x42::valid_ref_resource::S1>($t0) + # live vars: $t0, $t2 + 1: if ($t2) goto 2 else goto 7 + # live vars: $t0 + 2: label L0 + # live vars: $t0 + 3: $t3 := borrow_global<0x42::valid_ref_resource::S1>($t0) + # live vars: $t3 + 4: $t4 := borrow_field<0x42::valid_ref_resource::S1>.z($t3) + # live vars: $t4 + 5: $t1 := read_ref($t4) + # live vars: $t1 + 6: return $t1 + # live vars: $t0 + 7: label L1 + # live vars: + 8: $t1 := 1 + # live vars: $t1 + 9: return $t1 +} + + +[variant baseline] +fun valid_ref_resource::test_move_from($t0: &signer, $t1: address): i64 { + var $t2: i64 [unused] + var $t3: 0x42::valid_ref_resource::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: bool + var $t8: 0x42::valid_ref_resource::S1 + var $t9: address [unused] + var $t10: &0x42::valid_ref_resource::S1 + var $t11: &i64 + var $t12: &0x42::valid_ref_resource::S1 [unused] + var $t13: &i64 [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_ref_resource::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + # live vars: $t0, $t3, $t7 + 5: if ($t7) goto 6 else goto 13 + # live vars: $t0, $t3 + 6: label L0 + # live vars: $t0 + 7: $t1 := signer::address_of($t0) + # live vars: $t1 + 8: $t8 := move_from<0x42::valid_ref_resource::S1>($t1) + # live vars: $t8 + 9: $t10 := borrow_local($t8) + # live vars: $t10 + 10: $t11 := borrow_field<0x42::valid_ref_resource::S1>.y($t10) + # live vars: $t11 + 11: $t5 := read_ref($t11) + # live vars: $t5 + 12: return $t5 + # live vars: $t0, $t3 + 13: label L1 + # live vars: $t0, $t3 + 14: drop($t0) + # live vars: $t3 + 15: $t10 := borrow_local($t3) + # live vars: $t10 + 16: $t11 := borrow_field<0x42::valid_ref_resource::S1>.y($t10) + # live vars: $t11 + 17: $t5 := read_ref($t11) + # live vars: $t5 + 18: return $t5 +} + + +[variant baseline] +fun valid_ref_resource::test_move_to($t0: &signer, $t1: address) { + var $t2: 0x42::valid_ref_resource::S1 + var $t3: u64 + var $t4: i64 + var $t5: i128 + var $t6: bool [unused] + var $t7: bool + var $t8: &signer + # live vars: $t0, $t1 + 0: $t3 := 1 + # live vars: $t0, $t1, $t3 + 1: $t4 := -1 + # live vars: $t0, $t1, $t3, $t4 + 2: $t5 := -2 + # live vars: $t0, $t1, $t3, $t4, $t5 + 3: $t2 := pack 0x42::valid_ref_resource::S1($t3, $t4, $t5) + # live vars: $t0, $t1, $t2 + 4: $t7 := exists<0x42::valid_ref_resource::S1>($t1) + # live vars: $t0, $t2, $t7 + 5: $t7 := !($t7) + # live vars: $t0, $t2, $t7 + 6: if ($t7) goto 7 else goto 11 + # live vars: $t0, $t2 + 7: label L0 + # live vars: $t0, $t2 + 8: $t8 := move($t0) + # live vars: $t2, $t8 + 9: move_to<0x42::valid_ref_resource::S1>($t8, $t2) + # live vars: + 10: return () + # live vars: $t0, $t2 + 11: label L1 + # live vars: $t0 + 12: drop($t0) + # live vars: + 13: return () +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_ref_resource +use 0x1::signer +struct S1 has copy + drop + key + x: u64 + y: i64 + z: i128 + +// Function definition at index 0 +fun test_borrow1(l0: &i64): &i64 + move_loc l0 + ret + +// Function definition at index 1 +fun test_borrow2(l0: &i128): &i128 + move_loc l0 + ret + +// Function definition at index 2 +fun test_deref1(l0: &i64): i64 + move_loc l0 + read_ref + ret + +// Function definition at index 3 +fun test_deref2(l0: &i128): i128 + move_loc l0 + read_ref + ret + +// Function definition at index 4 +fun test_exist1(l0: address): i64 acquires S1 + copy_loc l0 + exists S1 + br_false l0 + move_loc l0 + borrow_global S1 + // @5 + borrow_field S1, y + read_ref + ret +l0: ld_i64 1 + ret + +// Function definition at index 5 +fun test_exist2(l0: address): i128 acquires S1 + copy_loc l0 + exists S1 + br_false l0 + move_loc l0 + borrow_global S1 + // @5 + borrow_field S1, z + read_ref + ret +l0: ld_i128 1 + ret + +// Function definition at index 6 +fun test_move_from(l0: &signer, l1: address): i64 acquires S1 + local l2: S1 + local l3: S1 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + move_loc l1 + exists S1 + br_false l0 + move_loc l0 + call signer::address_of + // @10 + move_from S1 + st_loc l3 + borrow_loc l3 + borrow_field S1, y + read_ref + // @15 + ret +l0: move_loc l0 + pop + borrow_loc l2 + borrow_field S1, y + // @20 + read_ref + ret + +// Function definition at index 7 +fun test_move_to(l0: &signer, l1: address) + local l2: S1 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + move_loc l1 + exists S1 + br_true l0 + move_loc l0 + move_loc l2 + // @10 + move_to S1 + ret +l0: move_loc l0 + pop + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.move new file mode 100644 index 00000000000..afa05b898ce --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_ref_source.move @@ -0,0 +1,55 @@ +module 0x42::valid_ref_resource { + use std::signer; + + struct S1 has copy, drop, key { x: u64, y: i64, z: i128 } // struct with i64 and i128 fields + + fun test_borrow1(a: &i64): &i64 { + a + } + + fun test_borrow2(a: &i128): &i128 { + a + } + + fun test_deref1(a: &i64): i64 { + *a + } + + fun test_deref2(a: &i128): i128 { + *a + } + + fun test_exist1(addr: address): i64 { + if (exists(addr)) { + let s = borrow_global(addr); + s.y + } else { + 1 + } + } + + fun test_exist2(addr: address): i128 { + if (exists(addr)) { + let s = borrow_global(addr); + s.z + } else { + 1 + } + } + + fun test_move_to(account: &signer, addr: address) { + let s1 = S1 {x: 1, y: -1, z: -2}; + if (!exists(addr)){ + move_to(account, s1) + } + } + + fun test_move_from(account: &signer, addr: address): i64 { + let s1 = S1 {x: 1, y: -1, z: -2}; + if (exists(addr)){ + move_from(signer::address_of(account)).y + } else { + s1.y + } + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.exp new file mode 100644 index 00000000000..df29cfd0279 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.exp @@ -0,0 +1,1945 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_struct { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(a: i64,b: i128): S3 { + { + let s1: S1 = pack valid_struct::S1(1, a, b); + { + let s2: S2 = pack valid_struct::S2(s1, a, b); + { + let s3: S3 = pack valid_struct::S3(a, s1, s2); + s3 + } + } + } + } + private fun test2(): S3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + s3 + } + } + } + } + private fun test3(a: i64,b: i128): S3 { + { + let s1: S1 = pack valid_struct::S1(1, a, b); + { + let s2: S2 = pack valid_struct::S2(s1, a, b); + { + let s3: S3 = pack valid_struct::S3(b, s1, s2); + s3 + } + } + } + } + private fun test4(): S3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + s3 + } + } + } + } + private fun test5(): E1 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let e: E1 = pack valid_struct::E1::V1(s1); + e + } + } + } + private fun test6(): E2 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let e: E2 = pack valid_struct::E2::V2(s2); + e + } + } + } + } + private fun test7(): E3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + { + let e: E3 = pack valid_struct::E3::V3(s3); + e + } + } + } + } + } + private fun test8(): E3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + { + let e: E3 = pack valid_struct::E3::V3(s3); + e + } + } + } + } + } +} // end 0x42::valid_struct + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_struct { + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test1(a: i64, b: i128): S3 { + let s1 = S1{x: 1, y: a, z: b}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: a, y: s1, z: s2}; + s3 + } + fun test2(): S3 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i64, y: s1, z: s2}; + s3 + } + fun test3(a: i64, b: i128): S3 { + let s1 = S1{x: 1, y: a, z: b}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: b, y: s1, z: s2}; + s3 + } + fun test4(): S3 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i128, y: s1, z: s2}; + s3 + } + fun test5(): E1 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let e = E1::V1{s: s1}; + e + } + fun test6(): E2 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let e = E2::V2{s: s2}; + e + } + fun test7(): E3 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i64, y: s1, z: s2}; + let e = E3::V3{s: s3}; + e + } + fun test8(): E3 { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: -1i64, z: -2i128}; + let s3 = S3{x: -1i128, y: s1, z: s2}; + let e = E3::V3{s: s3}; + e + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_struct::test1($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + 3: $t7 := infer($t3) + 4: $t8 := infer($t0) + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + 6: $t10 := infer($t0) + 7: $t11 := infer($t3) + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + 9: $t2 := infer($t9) + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test2(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t0 := infer($t9) + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test3($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + 3: $t7 := infer($t3) + 4: $t8 := infer($t0) + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + 6: $t10 := infer($t1) + 7: $t11 := infer($t3) + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + 9: $t2 := infer($t9) + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test4(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t0 := infer($t9) + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test5(): 0x42::valid_struct::E1 { + var $t0: 0x42::valid_struct::E1 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::E1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t5 := pack_variant 0x42::valid_struct::E1::V1($t1) + 5: $t0 := infer($t5) + 6: return $t0 +} + + +[variant baseline] +fun valid_struct::test6(): 0x42::valid_struct::E2 { + var $t0: 0x42::valid_struct::E2 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::E2 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t9 := pack_variant 0x42::valid_struct::E2::V2($t5) + 9: $t0 := infer($t9) + 10: return $t0 +} + + +[variant baseline] +fun valid_struct::test7(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + 12: $t0 := infer($t12) + 13: return $t0 +} + + +[variant baseline] +fun valid_struct::test8(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + 12: $t0 := infer($t12) + 13: return $t0 +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_struct::test1($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 3: $t7 := infer($t3) + # abort state: {returns} + # live vars: $t0, $t1, $t3, $t7 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t3, $t7, $t8 + # refs: [] + # + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + # abort state: {returns} + # live vars: $t0, $t3, $t6 + # refs: [] + # + 6: $t10 := infer($t0) + # abort state: {returns} + # live vars: $t3, $t6, $t10 + # refs: [] + # + 7: $t11 := infer($t3) + # abort state: {returns} + # live vars: $t6, $t10, $t11 + # refs: [] + # + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 9: $t2 := infer($t9) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test2(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t6 := infer($t1) + # abort state: {returns} + # live vars: $t1, $t6 + # refs: [] + # + 5: $t7 := -1 + # abort state: {returns} + # live vars: $t1, $t6, $t7 + # refs: [] + # + 6: $t8 := -2 + # abort state: {returns} + # live vars: $t1, $t6, $t7, $t8 + # refs: [] + # + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + # abort state: {returns} + # live vars: $t1, $t5 + # refs: [] + # + 8: $t10 := -1 + # abort state: {returns} + # live vars: $t1, $t5, $t10 + # refs: [] + # + 9: $t11 := infer($t1) + # abort state: {returns} + # live vars: $t5, $t10, $t11 + # refs: [] + # + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 11: $t0 := infer($t9) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test3($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + # abort state: {returns} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := infer($t0) + # abort state: {returns} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + # abort state: {returns} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 3: $t7 := infer($t3) + # abort state: {returns} + # live vars: $t0, $t1, $t3, $t7 + # refs: [] + # + 4: $t8 := infer($t0) + # abort state: {returns} + # live vars: $t1, $t3, $t7, $t8 + # refs: [] + # + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + # abort state: {returns} + # live vars: $t1, $t3, $t6 + # refs: [] + # + 6: $t10 := infer($t1) + # abort state: {returns} + # live vars: $t3, $t6, $t10 + # refs: [] + # + 7: $t11 := infer($t3) + # abort state: {returns} + # live vars: $t6, $t10, $t11 + # refs: [] + # + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 9: $t2 := infer($t9) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test4(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t6 := infer($t1) + # abort state: {returns} + # live vars: $t1, $t6 + # refs: [] + # + 5: $t7 := -1 + # abort state: {returns} + # live vars: $t1, $t6, $t7 + # refs: [] + # + 6: $t8 := -2 + # abort state: {returns} + # live vars: $t1, $t6, $t7, $t8 + # refs: [] + # + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + # abort state: {returns} + # live vars: $t1, $t5 + # refs: [] + # + 8: $t10 := -1 + # abort state: {returns} + # live vars: $t1, $t5, $t10 + # refs: [] + # + 9: $t11 := infer($t1) + # abort state: {returns} + # live vars: $t5, $t10, $t11 + # refs: [] + # + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 11: $t0 := infer($t9) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test5(): 0x42::valid_struct::E1 { + var $t0: 0x42::valid_struct::E1 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::E1 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t5 := pack_variant 0x42::valid_struct::E1::V1($t1) + # abort state: {returns} + # live vars: $t5 + # refs: [] + # + 5: $t0 := infer($t5) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 6: return $t0 +} + + +[variant baseline] +fun valid_struct::test6(): 0x42::valid_struct::E2 { + var $t0: 0x42::valid_struct::E2 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::E2 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t6 := infer($t1) + # abort state: {returns} + # live vars: $t6 + # refs: [] + # + 5: $t7 := -1 + # abort state: {returns} + # live vars: $t6, $t7 + # refs: [] + # + 6: $t8 := -2 + # abort state: {returns} + # live vars: $t6, $t7, $t8 + # refs: [] + # + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + # abort state: {returns} + # live vars: $t5 + # refs: [] + # + 8: $t9 := pack_variant 0x42::valid_struct::E2::V2($t5) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 9: $t0 := infer($t9) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 10: return $t0 +} + + +[variant baseline] +fun valid_struct::test7(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t6 := infer($t1) + # abort state: {returns} + # live vars: $t1, $t6 + # refs: [] + # + 5: $t7 := -1 + # abort state: {returns} + # live vars: $t1, $t6, $t7 + # refs: [] + # + 6: $t8 := -2 + # abort state: {returns} + # live vars: $t1, $t6, $t7, $t8 + # refs: [] + # + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + # abort state: {returns} + # live vars: $t1, $t5 + # refs: [] + # + 8: $t10 := -1 + # abort state: {returns} + # live vars: $t1, $t5, $t10 + # refs: [] + # + 9: $t11 := infer($t1) + # abort state: {returns} + # live vars: $t5, $t10, $t11 + # refs: [] + # + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + # abort state: {returns} + # live vars: $t12 + # refs: [] + # + 12: $t0 := infer($t12) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 13: return $t0 +} + + +[variant baseline] +fun valid_struct::test8(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + # abort state: {returns} + # live vars: + # refs: [] + # + 0: $t2 := 1 + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 1: $t3 := -1 + # abort state: {returns} + # live vars: $t2, $t3 + # refs: [] + # + 2: $t4 := -2 + # abort state: {returns} + # live vars: $t2, $t3, $t4 + # refs: [] + # + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 4: $t6 := infer($t1) + # abort state: {returns} + # live vars: $t1, $t6 + # refs: [] + # + 5: $t7 := -1 + # abort state: {returns} + # live vars: $t1, $t6, $t7 + # refs: [] + # + 6: $t8 := -2 + # abort state: {returns} + # live vars: $t1, $t6, $t7, $t8 + # refs: [] + # + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + # abort state: {returns} + # live vars: $t1, $t5 + # refs: [] + # + 8: $t10 := -1 + # abort state: {returns} + # live vars: $t1, $t5, $t10 + # refs: [] + # + 9: $t11 := infer($t1) + # abort state: {returns} + # live vars: $t5, $t10, $t11 + # refs: [] + # + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + # abort state: {returns} + # live vars: $t9 + # refs: [] + # + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + # abort state: {returns} + # live vars: $t12 + # refs: [] + # + 12: $t0 := infer($t12) + # abort state: {returns} + # live vars: $t0 + # refs: [] + # + 13: return $t0 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_struct { + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(a: i64,b: i128): S3 { + { + let s1: S1 = pack valid_struct::S1(1, a, b); + { + let s2: S2 = pack valid_struct::S2(s1, a, b); + { + let s3: S3 = pack valid_struct::S3(a, s1, s2); + s3 + } + } + } + } + private fun test2(): S3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + s3 + } + } + } + } + private fun test3(a: i64,b: i128): S3 { + { + let s1: S1 = pack valid_struct::S1(1, a, b); + { + let s2: S2 = pack valid_struct::S2(s1, a, b); + { + let s3: S3 = pack valid_struct::S3(b, s1, s2); + s3 + } + } + } + } + private fun test4(): S3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + s3 + } + } + } + } + private fun test5(): E1 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let e: E1 = pack valid_struct::E1::V1(s1); + e + } + } + } + private fun test6(): E2 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let e: E2 = pack valid_struct::E2::V2(s2); + e + } + } + } + } + private fun test7(): E3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + { + let e: E3 = pack valid_struct::E3::V3(s3); + e + } + } + } + } + } + private fun test8(): E3 { + { + let s1: S1 = pack valid_struct::S1(1, -1, -2); + { + let s2: S2 = pack valid_struct::S2(s1, -1, -2); + { + let s3: S3 = pack valid_struct::S3(-1, s1, s2); + { + let e: E3 = pack valid_struct::E3::V3(s3); + e + } + } + } + } + } +} // end 0x42::valid_struct + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_struct::test1($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + 3: $t7 := infer($t3) + 4: $t8 := infer($t0) + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + 6: $t10 := infer($t0) + 7: $t11 := infer($t3) + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + 9: $t2 := infer($t9) + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test2(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t0 := infer($t9) + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test3($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + 3: $t7 := infer($t3) + 4: $t8 := infer($t0) + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t8, $t1) + 6: $t10 := infer($t1) + 7: $t11 := infer($t3) + 8: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t6) + 9: $t2 := infer($t9) + 10: return $t2 +} + + +[variant baseline] +fun valid_struct::test4(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t0 := infer($t9) + 12: return $t0 +} + + +[variant baseline] +fun valid_struct::test5(): 0x42::valid_struct::E1 { + var $t0: 0x42::valid_struct::E1 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::E1 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t5 := pack_variant 0x42::valid_struct::E1::V1($t1) + 5: $t0 := infer($t5) + 6: return $t0 +} + + +[variant baseline] +fun valid_struct::test6(): 0x42::valid_struct::E2 { + var $t0: 0x42::valid_struct::E2 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::E2 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t9 := pack_variant 0x42::valid_struct::E2::V2($t5) + 9: $t0 := infer($t9) + 10: return $t0 +} + + +[variant baseline] +fun valid_struct::test7(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i64 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + 12: $t0 := infer($t12) + 13: return $t0 +} + + +[variant baseline] +fun valid_struct::test8(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 + var $t8: i128 + var $t9: 0x42::valid_struct::S3 + var $t10: i128 + var $t11: 0x42::valid_struct::S1 + var $t12: 0x42::valid_struct::E3 + 0: $t2 := 1 + 1: $t3 := -1 + 2: $t4 := -2 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + 4: $t6 := infer($t1) + 5: $t7 := -1 + 6: $t8 := -2 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t7, $t8) + 8: $t10 := -1 + 9: $t11 := infer($t1) + 10: $t9 := pack 0x42::valid_struct::S3($t10, $t11, $t5) + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + 12: $t0 := infer($t12) + 13: return $t0 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_struct::test1($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 [unused] + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i64 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := copy($t0) + # live vars: $t0, $t1, $t4, $t5 + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + # live vars: $t0, $t1, $t3 + 3: $t7 := copy($t3) + # live vars: $t0, $t1, $t3, $t7 + 4: $t5 := copy($t0) + # live vars: $t0, $t1, $t3, $t5, $t7 + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t5, $t1) + # live vars: $t0, $t3, $t6 + 6: $t0 := move($t0) + # live vars: $t0, $t3, $t6 + 7: $t3 := move($t3) + # live vars: $t0, $t3, $t6 + 8: $t9 := pack 0x42::valid_struct::S3($t0, $t3, $t6) + # live vars: $t9 + 9: return $t9 +} + + +[variant baseline] +fun valid_struct::test2(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 [unused] + var $t8: i128 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i64 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t6 := copy($t1) + # live vars: $t1, $t6 + 5: $t3 := -1 + # live vars: $t1, $t3, $t6 + 6: $t4 := -2 + # live vars: $t1, $t3, $t4, $t6 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t3, $t4) + # live vars: $t1, $t5 + 8: $t3 := -1 + # live vars: $t1, $t3, $t5 + 9: $t1 := move($t1) + # live vars: $t1, $t3, $t5 + 10: $t9 := pack 0x42::valid_struct::S3($t3, $t1, $t5) + # live vars: $t9 + 11: return $t9 +} + + +[variant baseline] +fun valid_struct::test3($t0: i64, $t1: i128): 0x42::valid_struct::S3 { + var $t2: 0x42::valid_struct::S3 [unused] + var $t3: 0x42::valid_struct::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_struct::S2 + var $t7: 0x42::valid_struct::S1 + var $t8: i64 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i128 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := copy($t0) + # live vars: $t0, $t1, $t4, $t5 + 2: $t3 := pack 0x42::valid_struct::S1($t4, $t5, $t1) + # live vars: $t0, $t1, $t3 + 3: $t7 := copy($t3) + # live vars: $t0, $t1, $t3, $t7 + 4: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t7 + 5: $t6 := pack 0x42::valid_struct::S2($t7, $t0, $t1) + # live vars: $t1, $t3, $t6 + 6: $t1 := move($t1) + # live vars: $t1, $t3, $t6 + 7: $t3 := move($t3) + # live vars: $t1, $t3, $t6 + 8: $t9 := pack 0x42::valid_struct::S3($t1, $t3, $t6) + # live vars: $t9 + 9: return $t9 +} + + +[variant baseline] +fun valid_struct::test4(): 0x42::valid_struct::S3 { + var $t0: 0x42::valid_struct::S3 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 [unused] + var $t8: i128 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i128 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t6 := copy($t1) + # live vars: $t1, $t6 + 5: $t3 := -1 + # live vars: $t1, $t3, $t6 + 6: $t4 := -2 + # live vars: $t1, $t3, $t4, $t6 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t3, $t4) + # live vars: $t1, $t5 + 8: $t4 := -1 + # live vars: $t1, $t4, $t5 + 9: $t1 := move($t1) + # live vars: $t1, $t4, $t5 + 10: $t9 := pack 0x42::valid_struct::S3($t4, $t1, $t5) + # live vars: $t9 + 11: return $t9 +} + + +[variant baseline] +fun valid_struct::test5(): 0x42::valid_struct::E1 { + var $t0: 0x42::valid_struct::E1 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::E1 + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t5 := pack_variant 0x42::valid_struct::E1::V1($t1) + # live vars: $t5 + 5: return $t5 +} + + +[variant baseline] +fun valid_struct::test6(): 0x42::valid_struct::E2 { + var $t0: 0x42::valid_struct::E2 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 [unused] + var $t7: i64 [unused] + var $t8: i128 [unused] + var $t9: 0x42::valid_struct::E2 + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t1 := move($t1) + # live vars: $t1 + 5: $t3 := -1 + # live vars: $t1, $t3 + 6: $t4 := -2 + # live vars: $t1, $t3, $t4 + 7: $t5 := pack 0x42::valid_struct::S2($t1, $t3, $t4) + # live vars: $t5 + 8: $t9 := pack_variant 0x42::valid_struct::E2::V2($t5) + # live vars: $t9 + 9: return $t9 +} + + +[variant baseline] +fun valid_struct::test7(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 [unused] + var $t8: i128 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i64 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + var $t12: 0x42::valid_struct::E3 + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t6 := copy($t1) + # live vars: $t1, $t6 + 5: $t3 := -1 + # live vars: $t1, $t3, $t6 + 6: $t4 := -2 + # live vars: $t1, $t3, $t4, $t6 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t3, $t4) + # live vars: $t1, $t5 + 8: $t3 := -1 + # live vars: $t1, $t3, $t5 + 9: $t1 := move($t1) + # live vars: $t1, $t3, $t5 + 10: $t9 := pack 0x42::valid_struct::S3($t3, $t1, $t5) + # live vars: $t9 + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + # live vars: $t12 + 12: return $t12 +} + + +[variant baseline] +fun valid_struct::test8(): 0x42::valid_struct::E3 { + var $t0: 0x42::valid_struct::E3 [unused] + var $t1: 0x42::valid_struct::S1 + var $t2: u64 + var $t3: i64 + var $t4: i128 + var $t5: 0x42::valid_struct::S2 + var $t6: 0x42::valid_struct::S1 + var $t7: i64 [unused] + var $t8: i128 [unused] + var $t9: 0x42::valid_struct::S3 + var $t10: i128 [unused] + var $t11: 0x42::valid_struct::S1 [unused] + var $t12: 0x42::valid_struct::E3 + # live vars: + 0: $t2 := 1 + # live vars: $t2 + 1: $t3 := -1 + # live vars: $t2, $t3 + 2: $t4 := -2 + # live vars: $t2, $t3, $t4 + 3: $t1 := pack 0x42::valid_struct::S1($t2, $t3, $t4) + # live vars: $t1 + 4: $t6 := copy($t1) + # live vars: $t1, $t6 + 5: $t3 := -1 + # live vars: $t1, $t3, $t6 + 6: $t4 := -2 + # live vars: $t1, $t3, $t4, $t6 + 7: $t5 := pack 0x42::valid_struct::S2($t6, $t3, $t4) + # live vars: $t1, $t5 + 8: $t4 := -1 + # live vars: $t1, $t4, $t5 + 9: $t1 := move($t1) + # live vars: $t1, $t4, $t5 + 10: $t9 := pack 0x42::valid_struct::S3($t4, $t1, $t5) + # live vars: $t9 + 11: $t12 := pack_variant 0x42::valid_struct::E3::V3($t9) + # live vars: $t12 + 12: return $t12 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_struct +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test1(l0: i64, l1: i128): S3 + local l2: S1 + local l3: S2 + ld_u64 1 + copy_loc l0 + copy_loc l1 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + copy_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + move_loc l0 + move_loc l2 + move_loc l3 + pack S3 + ret + +// Function definition at index 1 +fun test2(): S3 + local l0: S1 + local l1: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l0 + // @5 + copy_loc l0 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l1 + // @10 + ld_i64 -1 + move_loc l0 + move_loc l1 + pack S3 + ret + +// Function definition at index 2 +fun test3(l0: i64, l1: i128): S3 + local l2: S1 + local l3: S2 + ld_u64 1 + copy_loc l0 + copy_loc l1 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + copy_loc l1 + pack S2 + st_loc l3 + // @10 + move_loc l1 + move_loc l2 + move_loc l3 + pack S3 + ret + +// Function definition at index 3 +fun test4(): S3 + local l0: S1 + local l1: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l0 + // @5 + copy_loc l0 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l1 + // @10 + ld_i128 -1 + move_loc l0 + move_loc l1 + pack S3 + ret + +// Function definition at index 4 +fun test5(): E1 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + pack_variant E1, V1 + // @5 + ret + +// Function definition at index 5 +fun test6(): E2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + ld_i64 -1 + // @5 + ld_i128 -2 + pack S2 + pack_variant E2, V2 + ret + +// Function definition at index 6 +fun test7(): E3 + local l0: S1 + local l1: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l0 + // @5 + copy_loc l0 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l1 + // @10 + ld_i64 -1 + move_loc l0 + move_loc l1 + pack S3 + pack_variant E3, V3 + // @15 + ret + +// Function definition at index 7 +fun test8(): E3 + local l0: S1 + local l1: S2 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l0 + // @5 + copy_loc l0 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l1 + // @10 + ld_i128 -1 + move_loc l0 + move_loc l1 + pack S3 + pack_variant E3, V3 + // @15 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.move new file mode 100644 index 00000000000..8a3e54a4c09 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_struct.move @@ -0,0 +1,83 @@ +module 0x42::valid_struct { + + struct S1 has copy, drop { x: u64, y: i64, z: i128 } // struct with i64 and i128 fields + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } // struct with i64 and i128 fields, as well as nested struct involving i64 and i128 + + struct S3 has copy, drop { x: T, y: S1, z: S2 } // struct with two layers of nesting, and generic types + + enum E1 has copy, drop { // enum with i64 and nested struct + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { // enum with i128 and nested struct + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { // enum with nested struct, and generic types + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test1(a: i64, b: i128): S3 { + let s1 = S1 {x: 1, y: a, z: b}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: a, y: s1, z: s2}; + s3 + } + + fun test2(): S3 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + s3 + } + + fun test3(a: i64, b: i128): S3 { + let s1 = S1 {x: 1, y: a, z: b}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: b, y: s1, z: s2}; + s3 + } + + fun test4(): S3 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + s3 + } + + fun test5(): E1 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let e = E1::V1{s: s1}; + e + } + + fun test6(): E2 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let e = E2::V2{s: s2}; + e + } + + fun test7(): E3 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e = E3::V3{s: s3}; + e + } + + fun test8(): E3 { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: -1, z: -2}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e = E3::V3{s: s3}; + e + } +} diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.exp b/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.exp new file mode 100644 index 00000000000..d7bbaba2aed --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.exp @@ -0,0 +1,3596 @@ +// -- Model dump before first bytecode pipeline +module 0x42::valid_vector { + use std::vector; + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(a: i64): vector { + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), 1); + vector::push_back(Borrow(Mutable)(v), -1); + v + } + } + private fun test10(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E3 = pack valid_vector::E3::V1(s1); + { + let e2: E3 = pack valid_vector::E3::V2(s2); + { + let e3: E3 = pack valid_vector::E3::V3(s3); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), e1); + vector::push_back>(Borrow(Mutable)(v), e2); + vector::push_back>(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test2(a: i128): vector { + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), 1); + vector::push_back(Borrow(Mutable)(v), -1); + v + } + } + private fun test3(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, a, b); + { + let s11: S1 = pack valid_vector::S1(1, -1, -2); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), s1); + vector::push_back(Borrow(Mutable)(v), s11); + v + } + } + } + } + private fun test4(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s21: S2 = pack valid_vector::S2(s1, -1, -2); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), s2); + vector::push_back(Borrow(Mutable)(v), s21); + v + } + } + } + } + } + private fun test5(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(a, s1, s2); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), s3); + vector::push_back>(Borrow(Mutable)(v), s3); + v + } + } + } + } + } + private fun test6(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(b, s1, s2); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), s3); + vector::push_back>(Borrow(Mutable)(v), s3); + v + } + } + } + } + } + private fun test7(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E1 = pack valid_vector::E1::V1(s1); + { + let e2: E1 = pack valid_vector::E1::V2(s2); + { + let e3: E1 = pack valid_vector::E1::V3(s3); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), e1); + vector::push_back(Borrow(Mutable)(v), e2); + vector::push_back(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test8(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E2 = pack valid_vector::E2::V1(s1); + { + let e2: E2 = pack valid_vector::E2::V2(s2); + { + let e3: E2 = pack valid_vector::E2::V3(s3); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), e1); + vector::push_back(Borrow(Mutable)(v), e2); + vector::push_back(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test9(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E3 = pack valid_vector::E3::V1(s1); + { + let e2: E3 = pack valid_vector::E3::V2(s2); + { + let e3: E3 = pack valid_vector::E3::V3(s3); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), e1); + vector::push_back>(Borrow(Mutable)(v), e2); + vector::push_back>(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } +} // end 0x42::valid_vector + +// -- Sourcified model before first bytecode pipeline +module 0x42::valid_vector { + use std::vector; + enum E1 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 has copy, drop { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 has copy, drop { + x: u64, + y: i64, + z: i128, + } + struct S2 has copy, drop { + x: S1, + y: i64, + z: i128, + } + struct S3 has copy, drop { + x: T, + y: S1, + z: S2, + } + fun test1(a: i64): vector { + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, a); + 0x1::vector::push_back(&mut v, a); + 0x1::vector::push_back(&mut v, 1i64); + 0x1::vector::push_back(&mut v, -1i64); + v + } + fun test10(a: i64, b: i128): vector> { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: -1i128, y: s1, z: s2}; + let e1 = E3::V1{s: s1}; + let e2 = E3::V2{s: s2}; + let e3 = E3::V3{s: s3}; + let v = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut v, e1); + 0x1::vector::push_back>(&mut v, e2); + 0x1::vector::push_back>(&mut v, e3); + v + } + fun test2(a: i128): vector { + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, a); + 0x1::vector::push_back(&mut v, a); + 0x1::vector::push_back(&mut v, 1i128); + 0x1::vector::push_back(&mut v, -1i128); + v + } + fun test3(a: i64, b: i128): vector { + let s1 = S1{x: 1, y: a, z: b}; + let s11 = S1{x: 1, y: -1i64, z: -2i128}; + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, s1); + 0x1::vector::push_back(&mut v, s11); + v + } + fun test4(a: i64, b: i128): vector { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s21 = S2{x: s1, y: -1i64, z: -2i128}; + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, s2); + 0x1::vector::push_back(&mut v, s21); + v + } + fun test5(a: i64, b: i128): vector> { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: a, y: s1, z: s2}; + let v = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut v, s3); + 0x1::vector::push_back>(&mut v, s3); + v + } + fun test6(a: i64, b: i128): vector> { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: b, y: s1, z: s2}; + let v = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut v, s3); + 0x1::vector::push_back>(&mut v, s3); + v + } + fun test7(a: i64, b: i128): vector { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: -1i64, y: s1, z: s2}; + let e1 = E1::V1{s: s1}; + let e2 = E1::V2{s: s2}; + let e3 = E1::V3{s: s3}; + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, e1); + 0x1::vector::push_back(&mut v, e2); + 0x1::vector::push_back(&mut v, e3); + v + } + fun test8(a: i64, b: i128): vector { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: -1i128, y: s1, z: s2}; + let e1 = E2::V1{s: s1}; + let e2 = E2::V2{s: s2}; + let e3 = E2::V3{s: s3}; + let v = 0x1::vector::empty(); + 0x1::vector::push_back(&mut v, e1); + 0x1::vector::push_back(&mut v, e2); + 0x1::vector::push_back(&mut v, e3); + v + } + fun test9(a: i64, b: i128): vector> { + let s1 = S1{x: 1, y: -1i64, z: -2i128}; + let s2 = S2{x: s1, y: a, z: b}; + let s3 = S3{x: -1i64, y: s1, z: s2}; + let e1 = E3::V1{s: s1}; + let e2 = E3::V2{s: s2}; + let e3 = E3::V3{s: s3}; + let v = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut v, e1); + 0x1::vector::push_back>(&mut v, e2); + 0x1::vector::push_back>(&mut v, e3); + v + } +} + +============ bytecode before first stackless bytecode pipeline ================ + +[variant baseline] +fun valid_vector::test1($t0: i64): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i64 + var $t7: &mut vector + var $t8: i64 + 0: $t2 := vector::empty() + 1: $t3 := borrow_local($t2) + 2: vector::push_back($t3, $t0) + 3: $t4 := borrow_local($t2) + 4: vector::push_back($t4, $t0) + 5: $t5 := borrow_local($t2) + 6: $t6 := 1 + 7: vector::push_back($t5, $t6) + 8: $t7 := borrow_local($t2) + 9: $t8 := -1 + 10: vector::push_back($t7, $t8) + 11: $t1 := infer($t2) + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test10($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test2($t0: i128): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i128 + var $t7: &mut vector + var $t8: i128 + 0: $t2 := vector::empty() + 1: $t3 := borrow_local($t2) + 2: vector::push_back($t3, $t0) + 3: $t4 := borrow_local($t2) + 4: vector::push_back($t4, $t0) + 5: $t5 := borrow_local($t2) + 6: $t6 := 1 + 7: vector::push_back($t5, $t6) + 8: $t7 := borrow_local($t2) + 9: $t8 := -1 + 10: vector::push_back($t7, $t8) + 11: $t1 := infer($t2) + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test3($t0: i64, $t1: i128): vector<0x42::valid_vector::S1> { + var $t2: vector<0x42::valid_vector::S1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_vector::S1 + var $t7: u64 + var $t8: i64 + var $t9: i128 + var $t10: vector<0x42::valid_vector::S1> + var $t11: &mut vector<0x42::valid_vector::S1> + var $t12: &mut vector<0x42::valid_vector::S1> + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t1) + 3: $t7 := 1 + 4: $t8 := -1 + 5: $t9 := -2 + 6: $t6 := pack 0x42::valid_vector::S1($t7, $t8, $t9) + 7: $t10 := vector::empty<0x42::valid_vector::S1>() + 8: $t11 := borrow_local($t10) + 9: vector::push_back<0x42::valid_vector::S1>($t11, $t3) + 10: $t12 := borrow_local($t10) + 11: vector::push_back<0x42::valid_vector::S1>($t12, $t6) + 12: $t2 := infer($t10) + 13: return $t2 +} + + +[variant baseline] +fun valid_vector::test4($t0: i64, $t1: i128): vector<0x42::valid_vector::S2> { + var $t2: vector<0x42::valid_vector::S2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S2 + var $t11: 0x42::valid_vector::S1 + var $t12: i64 + var $t13: i128 + var $t14: vector<0x42::valid_vector::S2> + var $t15: &mut vector<0x42::valid_vector::S2> + var $t16: &mut vector<0x42::valid_vector::S2> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t3) + 8: $t12 := -1 + 9: $t13 := -2 + 10: $t10 := pack 0x42::valid_vector::S2($t11, $t12, $t13) + 11: $t14 := vector::empty<0x42::valid_vector::S2>() + 12: $t15 := borrow_local($t14) + 13: vector::push_back<0x42::valid_vector::S2>($t15, $t7) + 14: $t16 := borrow_local($t14) + 15: vector::push_back<0x42::valid_vector::S2>($t16, $t10) + 16: $t2 := infer($t14) + 17: return $t2 +} + + +[variant baseline] +fun valid_vector::test5($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t0) + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + 11: $t14 := borrow_local($t13) + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + 13: $t15 := borrow_local($t13) + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + 15: $t2 := infer($t13) + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test6($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t1) + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + 11: $t14 := borrow_local($t13) + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + 13: $t15 := borrow_local($t13) + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + 15: $t2 := infer($t13) + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test7($t0: i64, $t1: i128): vector<0x42::valid_vector::E1> { + var $t2: vector<0x42::valid_vector::E1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E1 + var $t14: 0x42::valid_vector::E1 + var $t15: 0x42::valid_vector::E1 + var $t16: vector<0x42::valid_vector::E1> + var $t17: &mut vector<0x42::valid_vector::E1> + var $t18: &mut vector<0x42::valid_vector::E1> + var $t19: &mut vector<0x42::valid_vector::E1> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E1::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E1::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E1::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E1>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E1>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E1>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E1>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test8($t0: i64, $t1: i128): vector<0x42::valid_vector::E2> { + var $t2: vector<0x42::valid_vector::E2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E2 + var $t14: 0x42::valid_vector::E2 + var $t15: 0x42::valid_vector::E2 + var $t16: vector<0x42::valid_vector::E2> + var $t17: &mut vector<0x42::valid_vector::E2> + var $t18: &mut vector<0x42::valid_vector::E2> + var $t19: &mut vector<0x42::valid_vector::E2> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E2::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E2::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E2::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E2>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E2>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E2>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E2>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test9($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + +============ after AbortAnalysisProcessor: ================ + +[variant baseline] +fun valid_vector::test1($t0: i64): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i64 + var $t7: &mut vector + var $t8: i64 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := vector::empty() + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t3 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t3 + # refs: [$t3 => #3] + # #3 + # + # #root + # => (mut) #3 via [local `v`] at line 30 + # + 2: vector::push_back($t3, $t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 3: $t4 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t4 + # refs: [$t4 => #4] + # #4 + # + # #root + # => (mut) #4 via [local `v`] at line 31 + # + 4: vector::push_back($t4, $t0) + # abort state: {returns,aborts} + # live vars: $t2 + # refs: [] + # + 5: $t5 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t2, $t5 + # refs: [$t5 => #5] + # #5 + # + # #root + # => (mut) #5 via [local `v`] at line 32 + # + 6: $t6 := 1 + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t6 + # refs: [$t5 => #5] + # #5 + # + # #root + # => (mut) #5 via [local `v`] at line 32 + # + 7: vector::push_back($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t2 + # refs: [] + # + 8: $t7 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => (mut) #7 via [local `v`] at line 33 + # + 9: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t2, $t7, $t8 + # refs: [$t7 => #7] + # #7 + # + # #root + # => (mut) #7 via [local `v`] at line 33 + # + 10: vector::push_back($t7, $t8) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 11: $t1 := infer($t2) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test10($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 7: $t11 := -1 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t10 + # refs: [] + # + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t13 + # refs: [] + # + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [] + # + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15 + # refs: [] + # + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16 + # refs: [] + # + 14: $t17 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => (mut) #17 via [local `v`] at line 135 + # + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16 + # refs: [] + # + 16: $t18 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => (mut) #18 via [local `v`] at line 136 + # + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + # abort state: {returns,aborts} + # live vars: $t15, $t16 + # refs: [] + # + 18: $t19 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t15, $t16, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => (mut) #19 via [local `v`] at line 137 + # + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + # abort state: {returns} + # live vars: $t16 + # refs: [] + # + 20: $t2 := infer($t16) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test2($t0: i128): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i128 + var $t7: &mut vector + var $t8: i128 + # abort state: {returns,aborts} + # live vars: $t0 + # refs: [] + # + 0: $t2 := vector::empty() + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 1: $t3 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t3 + # refs: [$t3 => #3] + # #3 + # + # #root + # => (mut) #3 via [local `v`] at line 39 + # + 2: vector::push_back($t3, $t0) + # abort state: {returns,aborts} + # live vars: $t0, $t2 + # refs: [] + # + 3: $t4 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t0, $t2, $t4 + # refs: [$t4 => #4] + # #4 + # + # #root + # => (mut) #4 via [local `v`] at line 40 + # + 4: vector::push_back($t4, $t0) + # abort state: {returns,aborts} + # live vars: $t2 + # refs: [] + # + 5: $t5 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t2, $t5 + # refs: [$t5 => #5] + # #5 + # + # #root + # => (mut) #5 via [local `v`] at line 41 + # + 6: $t6 := 1 + # abort state: {returns,aborts} + # live vars: $t2, $t5, $t6 + # refs: [$t5 => #5] + # #5 + # + # #root + # => (mut) #5 via [local `v`] at line 41 + # + 7: vector::push_back($t5, $t6) + # abort state: {returns,aborts} + # live vars: $t2 + # refs: [] + # + 8: $t7 := borrow_local($t2) + # abort state: {returns,aborts} + # live vars: $t2, $t7 + # refs: [$t7 => #7] + # #7 + # + # #root + # => (mut) #7 via [local `v`] at line 42 + # + 9: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t2, $t7, $t8 + # refs: [$t7 => #7] + # #7 + # + # #root + # => (mut) #7 via [local `v`] at line 42 + # + 10: vector::push_back($t7, $t8) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 11: $t1 := infer($t2) + # abort state: {returns} + # live vars: $t1 + # refs: [] + # + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test3($t0: i64, $t1: i128): vector<0x42::valid_vector::S1> { + var $t2: vector<0x42::valid_vector::S1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_vector::S1 + var $t7: u64 + var $t8: i64 + var $t9: i128 + var $t10: vector<0x42::valid_vector::S1> + var $t11: &mut vector<0x42::valid_vector::S1> + var $t12: &mut vector<0x42::valid_vector::S1> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t4, $t5 + # refs: [] + # + 2: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t1) + # abort state: {returns,aborts} + # live vars: $t3 + # refs: [] + # + 3: $t7 := 1 + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 4: $t8 := -1 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t8 + # refs: [] + # + 5: $t9 := -2 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t8, $t9 + # refs: [] + # + 6: $t6 := pack 0x42::valid_vector::S1($t7, $t8, $t9) + # abort state: {returns,aborts} + # live vars: $t3, $t6 + # refs: [] + # + 7: $t10 := vector::empty<0x42::valid_vector::S1>() + # abort state: {returns,aborts} + # live vars: $t3, $t6, $t10 + # refs: [] + # + 8: $t11 := borrow_local($t10) + # abort state: {returns,aborts} + # live vars: $t3, $t6, $t10, $t11 + # refs: [$t11 => #11] + # #11 + # + # #root + # => (mut) #11 via [local `v`] at line 50 + # + 9: vector::push_back<0x42::valid_vector::S1>($t11, $t3) + # abort state: {returns,aborts} + # live vars: $t6, $t10 + # refs: [] + # + 10: $t12 := borrow_local($t10) + # abort state: {returns,aborts} + # live vars: $t6, $t10, $t12 + # refs: [$t12 => #12] + # #12 + # + # #root + # => (mut) #12 via [local `v`] at line 51 + # + 11: vector::push_back<0x42::valid_vector::S1>($t12, $t6) + # abort state: {returns} + # live vars: $t10 + # refs: [] + # + 12: $t2 := infer($t10) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 13: return $t2 +} + + +[variant baseline] +fun valid_vector::test4($t0: i64, $t1: i128): vector<0x42::valid_vector::S2> { + var $t2: vector<0x42::valid_vector::S2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S2 + var $t11: 0x42::valid_vector::S1 + var $t12: i64 + var $t13: i128 + var $t14: vector<0x42::valid_vector::S2> + var $t15: &mut vector<0x42::valid_vector::S2> + var $t16: &mut vector<0x42::valid_vector::S2> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 7: $t11 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t11 + # refs: [] + # + 8: $t12 := -1 + # abort state: {returns,aborts} + # live vars: $t7, $t11, $t12 + # refs: [] + # + 9: $t13 := -2 + # abort state: {returns,aborts} + # live vars: $t7, $t11, $t12, $t13 + # refs: [] + # + 10: $t10 := pack 0x42::valid_vector::S2($t11, $t12, $t13) + # abort state: {returns,aborts} + # live vars: $t7, $t10 + # refs: [] + # + 11: $t14 := vector::empty<0x42::valid_vector::S2>() + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t14 + # refs: [] + # + 12: $t15 := borrow_local($t14) + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t14, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => (mut) #15 via [local `v`] at line 60 + # + 13: vector::push_back<0x42::valid_vector::S2>($t15, $t7) + # abort state: {returns,aborts} + # live vars: $t10, $t14 + # refs: [] + # + 14: $t16 := borrow_local($t14) + # abort state: {returns,aborts} + # live vars: $t10, $t14, $t16 + # refs: [$t16 => #16] + # #16 + # + # #root + # => (mut) #16 via [local `v`] at line 61 + # + 15: vector::push_back<0x42::valid_vector::S2>($t16, $t10) + # abort state: {returns} + # live vars: $t14 + # refs: [] + # + 16: $t2 := infer($t14) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 17: return $t2 +} + + +[variant baseline] +fun valid_vector::test5($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t0, $t3, $t7 + # refs: [] + # + 7: $t11 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t10 + # refs: [] + # + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + # abort state: {returns,aborts} + # live vars: $t10, $t13 + # refs: [] + # + 11: $t14 := borrow_local($t13) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [$t14 => #14] + # #14 + # + # #root + # => (mut) #14 via [local `v`] at line 70 + # + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # abort state: {returns,aborts} + # live vars: $t10, $t13 + # refs: [] + # + 13: $t15 := borrow_local($t13) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => (mut) #15 via [local `v`] at line 71 + # + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + # abort state: {returns} + # live vars: $t13 + # refs: [] + # + 15: $t2 := infer($t13) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test6($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t7 + # refs: [] + # + 7: $t11 := infer($t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t10 + # refs: [] + # + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + # abort state: {returns,aborts} + # live vars: $t10, $t13 + # refs: [] + # + 11: $t14 := borrow_local($t13) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [$t14 => #14] + # #14 + # + # #root + # => (mut) #14 via [local `v`] at line 80 + # + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # abort state: {returns,aborts} + # live vars: $t10, $t13 + # refs: [] + # + 13: $t15 := borrow_local($t13) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t15 + # refs: [$t15 => #15] + # #15 + # + # #root + # => (mut) #15 via [local `v`] at line 81 + # + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + # abort state: {returns} + # live vars: $t13 + # refs: [] + # + 15: $t2 := infer($t13) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test7($t0: i64, $t1: i128): vector<0x42::valid_vector::E1> { + var $t2: vector<0x42::valid_vector::E1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E1 + var $t14: 0x42::valid_vector::E1 + var $t15: 0x42::valid_vector::E1 + var $t16: vector<0x42::valid_vector::E1> + var $t17: &mut vector<0x42::valid_vector::E1> + var $t18: &mut vector<0x42::valid_vector::E1> + var $t19: &mut vector<0x42::valid_vector::E1> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 7: $t11 := -1 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t10 + # refs: [] + # + 10: $t13 := pack_variant 0x42::valid_vector::E1::V1($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t13 + # refs: [] + # + 11: $t14 := pack_variant 0x42::valid_vector::E1::V2($t7) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [] + # + 12: $t15 := pack_variant 0x42::valid_vector::E1::V3($t10) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15 + # refs: [] + # + 13: $t16 := vector::empty<0x42::valid_vector::E1>() + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16 + # refs: [] + # + 14: $t17 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => (mut) #17 via [local `v`] at line 93 + # + 15: vector::push_back<0x42::valid_vector::E1>($t17, $t13) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16 + # refs: [] + # + 16: $t18 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => (mut) #18 via [local `v`] at line 94 + # + 17: vector::push_back<0x42::valid_vector::E1>($t18, $t14) + # abort state: {returns,aborts} + # live vars: $t15, $t16 + # refs: [] + # + 18: $t19 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t15, $t16, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => (mut) #19 via [local `v`] at line 95 + # + 19: vector::push_back<0x42::valid_vector::E1>($t19, $t15) + # abort state: {returns} + # live vars: $t16 + # refs: [] + # + 20: $t2 := infer($t16) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test8($t0: i64, $t1: i128): vector<0x42::valid_vector::E2> { + var $t2: vector<0x42::valid_vector::E2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E2 + var $t14: 0x42::valid_vector::E2 + var $t15: 0x42::valid_vector::E2 + var $t16: vector<0x42::valid_vector::E2> + var $t17: &mut vector<0x42::valid_vector::E2> + var $t18: &mut vector<0x42::valid_vector::E2> + var $t19: &mut vector<0x42::valid_vector::E2> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 7: $t11 := -1 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t10 + # refs: [] + # + 10: $t13 := pack_variant 0x42::valid_vector::E2::V1($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t13 + # refs: [] + # + 11: $t14 := pack_variant 0x42::valid_vector::E2::V2($t7) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [] + # + 12: $t15 := pack_variant 0x42::valid_vector::E2::V3($t10) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15 + # refs: [] + # + 13: $t16 := vector::empty<0x42::valid_vector::E2>() + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16 + # refs: [] + # + 14: $t17 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => (mut) #17 via [local `v`] at line 107 + # + 15: vector::push_back<0x42::valid_vector::E2>($t17, $t13) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16 + # refs: [] + # + 16: $t18 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => (mut) #18 via [local `v`] at line 108 + # + 17: vector::push_back<0x42::valid_vector::E2>($t18, $t14) + # abort state: {returns,aborts} + # live vars: $t15, $t16 + # refs: [] + # + 18: $t19 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t15, $t16, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => (mut) #19 via [local `v`] at line 109 + # + 19: vector::push_back<0x42::valid_vector::E2>($t19, $t15) + # abort state: {returns} + # live vars: $t16 + # refs: [] + # + 20: $t2 := infer($t16) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test9($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + # abort state: {returns,aborts} + # live vars: $t0, $t1 + # refs: [] + # + 0: $t4 := 1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4 + # refs: [] + # + 1: $t5 := -1 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5 + # refs: [] + # + 2: $t6 := -2 + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t4, $t5, $t6 + # refs: [] + # + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3 + # refs: [] + # + 4: $t8 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t0, $t1, $t3, $t8 + # refs: [] + # + 5: $t9 := infer($t0) + # abort state: {returns,aborts} + # live vars: $t1, $t3, $t8, $t9 + # refs: [] + # + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + # abort state: {returns,aborts} + # live vars: $t3, $t7 + # refs: [] + # + 7: $t11 := -1 + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11 + # refs: [] + # + 8: $t12 := infer($t3) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t11, $t12 + # refs: [] + # + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + # abort state: {returns,aborts} + # live vars: $t3, $t7, $t10 + # refs: [] + # + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + # abort state: {returns,aborts} + # live vars: $t7, $t10, $t13 + # refs: [] + # + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + # abort state: {returns,aborts} + # live vars: $t10, $t13, $t14 + # refs: [] + # + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15 + # refs: [] + # + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16 + # refs: [] + # + 14: $t17 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t13, $t14, $t15, $t16, $t17 + # refs: [$t17 => #17] + # #17 + # + # #root + # => (mut) #17 via [local `v`] at line 121 + # + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16 + # refs: [] + # + 16: $t18 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t14, $t15, $t16, $t18 + # refs: [$t18 => #18] + # #18 + # + # #root + # => (mut) #18 via [local `v`] at line 122 + # + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + # abort state: {returns,aborts} + # live vars: $t15, $t16 + # refs: [] + # + 18: $t19 := borrow_local($t16) + # abort state: {returns,aborts} + # live vars: $t15, $t16, $t19 + # refs: [$t19 => #19] + # #19 + # + # #root + # => (mut) #19 via [local `v`] at line 123 + # + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + # abort state: {returns} + # live vars: $t16 + # refs: [] + # + 20: $t2 := infer($t16) + # abort state: {returns} + # live vars: $t2 + # refs: [] + # + 21: return $t2 +} + +// -- Model dump before second bytecode pipeline +module 0x42::valid_vector { + use std::vector; + enum E1 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E2 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + enum E3 { + V1 { + s: S1, + } + V2 { + s: S2, + } + V3 { + s: S3, + } + } + struct S1 { + x: u64, + y: i64, + z: i128, + } + struct S2 { + x: S1, + y: i64, + z: i128, + } + struct S3 { + x: T, + y: S1, + z: S2, + } + private fun test1(a: i64): vector { + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), 1); + vector::push_back(Borrow(Mutable)(v), -1); + v + } + } + private fun test10(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E3 = pack valid_vector::E3::V1(s1); + { + let e2: E3 = pack valid_vector::E3::V2(s2); + { + let e3: E3 = pack valid_vector::E3::V3(s3); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), e1); + vector::push_back>(Borrow(Mutable)(v), e2); + vector::push_back>(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test2(a: i128): vector { + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), a); + vector::push_back(Borrow(Mutable)(v), 1); + vector::push_back(Borrow(Mutable)(v), -1); + v + } + } + private fun test3(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, a, b); + { + let s11: S1 = pack valid_vector::S1(1, -1, -2); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), s1); + vector::push_back(Borrow(Mutable)(v), s11); + v + } + } + } + } + private fun test4(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s21: S2 = pack valid_vector::S2(s1, -1, -2); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), s2); + vector::push_back(Borrow(Mutable)(v), s21); + v + } + } + } + } + } + private fun test5(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(a, s1, s2); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), s3); + vector::push_back>(Borrow(Mutable)(v), s3); + v + } + } + } + } + } + private fun test6(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(b, s1, s2); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), s3); + vector::push_back>(Borrow(Mutable)(v), s3); + v + } + } + } + } + } + private fun test7(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E1 = pack valid_vector::E1::V1(s1); + { + let e2: E1 = pack valid_vector::E1::V2(s2); + { + let e3: E1 = pack valid_vector::E1::V3(s3); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), e1); + vector::push_back(Borrow(Mutable)(v), e2); + vector::push_back(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test8(a: i64,b: i128): vector { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E2 = pack valid_vector::E2::V1(s1); + { + let e2: E2 = pack valid_vector::E2::V2(s2); + { + let e3: E2 = pack valid_vector::E2::V3(s3); + { + let v: vector = vector::empty(); + vector::push_back(Borrow(Mutable)(v), e1); + vector::push_back(Borrow(Mutable)(v), e2); + vector::push_back(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } + private fun test9(a: i64,b: i128): vector> { + { + let s1: S1 = pack valid_vector::S1(1, -1, -2); + { + let s2: S2 = pack valid_vector::S2(s1, a, b); + { + let s3: S3 = pack valid_vector::S3(-1, s1, s2); + { + let e1: E3 = pack valid_vector::E3::V1(s1); + { + let e2: E3 = pack valid_vector::E3::V2(s2); + { + let e3: E3 = pack valid_vector::E3::V3(s3); + { + let v: vector> = vector::empty>(); + vector::push_back>(Borrow(Mutable)(v), e1); + vector::push_back>(Borrow(Mutable)(v), e2); + vector::push_back>(Borrow(Mutable)(v), e3); + v + } + } + } + } + } + } + } + } +} // end 0x42::valid_vector + +============ bytecode before second stackless bytecode pipeline ================ + +[variant baseline] +fun valid_vector::test1($t0: i64): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i64 + var $t7: &mut vector + var $t8: i64 + 0: $t2 := vector::empty() + 1: $t3 := borrow_local($t2) + 2: vector::push_back($t3, $t0) + 3: $t4 := borrow_local($t2) + 4: vector::push_back($t4, $t0) + 5: $t5 := borrow_local($t2) + 6: $t6 := 1 + 7: vector::push_back($t5, $t6) + 8: $t7 := borrow_local($t2) + 9: $t8 := -1 + 10: vector::push_back($t7, $t8) + 11: $t1 := infer($t2) + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test10($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test2($t0: i128): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector + var $t5: &mut vector + var $t6: i128 + var $t7: &mut vector + var $t8: i128 + 0: $t2 := vector::empty() + 1: $t3 := borrow_local($t2) + 2: vector::push_back($t3, $t0) + 3: $t4 := borrow_local($t2) + 4: vector::push_back($t4, $t0) + 5: $t5 := borrow_local($t2) + 6: $t6 := 1 + 7: vector::push_back($t5, $t6) + 8: $t7 := borrow_local($t2) + 9: $t8 := -1 + 10: vector::push_back($t7, $t8) + 11: $t1 := infer($t2) + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test3($t0: i64, $t1: i128): vector<0x42::valid_vector::S1> { + var $t2: vector<0x42::valid_vector::S1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: 0x42::valid_vector::S1 + var $t7: u64 + var $t8: i64 + var $t9: i128 + var $t10: vector<0x42::valid_vector::S1> + var $t11: &mut vector<0x42::valid_vector::S1> + var $t12: &mut vector<0x42::valid_vector::S1> + 0: $t4 := 1 + 1: $t5 := infer($t0) + 2: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t1) + 3: $t7 := 1 + 4: $t8 := -1 + 5: $t9 := -2 + 6: $t6 := pack 0x42::valid_vector::S1($t7, $t8, $t9) + 7: $t10 := vector::empty<0x42::valid_vector::S1>() + 8: $t11 := borrow_local($t10) + 9: vector::push_back<0x42::valid_vector::S1>($t11, $t3) + 10: $t12 := borrow_local($t10) + 11: vector::push_back<0x42::valid_vector::S1>($t12, $t6) + 12: $t2 := infer($t10) + 13: return $t2 +} + + +[variant baseline] +fun valid_vector::test4($t0: i64, $t1: i128): vector<0x42::valid_vector::S2> { + var $t2: vector<0x42::valid_vector::S2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S2 + var $t11: 0x42::valid_vector::S1 + var $t12: i64 + var $t13: i128 + var $t14: vector<0x42::valid_vector::S2> + var $t15: &mut vector<0x42::valid_vector::S2> + var $t16: &mut vector<0x42::valid_vector::S2> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t3) + 8: $t12 := -1 + 9: $t13 := -2 + 10: $t10 := pack 0x42::valid_vector::S2($t11, $t12, $t13) + 11: $t14 := vector::empty<0x42::valid_vector::S2>() + 12: $t15 := borrow_local($t14) + 13: vector::push_back<0x42::valid_vector::S2>($t15, $t7) + 14: $t16 := borrow_local($t14) + 15: vector::push_back<0x42::valid_vector::S2>($t16, $t10) + 16: $t2 := infer($t14) + 17: return $t2 +} + + +[variant baseline] +fun valid_vector::test5($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t0) + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + 11: $t14 := borrow_local($t13) + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + 13: $t15 := borrow_local($t13) + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + 15: $t2 := infer($t13) + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test6($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := infer($t1) + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + 11: $t14 := borrow_local($t13) + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + 13: $t15 := borrow_local($t13) + 14: vector::push_back<0x42::valid_vector::S3>($t15, $t10) + 15: $t2 := infer($t13) + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test7($t0: i64, $t1: i128): vector<0x42::valid_vector::E1> { + var $t2: vector<0x42::valid_vector::E1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E1 + var $t14: 0x42::valid_vector::E1 + var $t15: 0x42::valid_vector::E1 + var $t16: vector<0x42::valid_vector::E1> + var $t17: &mut vector<0x42::valid_vector::E1> + var $t18: &mut vector<0x42::valid_vector::E1> + var $t19: &mut vector<0x42::valid_vector::E1> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E1::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E1::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E1::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E1>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E1>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E1>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E1>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test8($t0: i64, $t1: i128): vector<0x42::valid_vector::E2> { + var $t2: vector<0x42::valid_vector::E2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i128 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E2 + var $t14: 0x42::valid_vector::E2 + var $t15: 0x42::valid_vector::E2 + var $t16: vector<0x42::valid_vector::E2> + var $t17: &mut vector<0x42::valid_vector::E2> + var $t18: &mut vector<0x42::valid_vector::E2> + var $t19: &mut vector<0x42::valid_vector::E2> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E2::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E2::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E2::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E2>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E2>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E2>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E2>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test9($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 + var $t10: 0x42::valid_vector::S3 + var $t11: i64 + var $t12: 0x42::valid_vector::S1 + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> + var $t19: &mut vector<0x42::valid_vector::E3> + 0: $t4 := 1 + 1: $t5 := -1 + 2: $t6 := -2 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + 4: $t8 := infer($t3) + 5: $t9 := infer($t0) + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t9, $t1) + 7: $t11 := -1 + 8: $t12 := infer($t3) + 9: $t10 := pack 0x42::valid_vector::S3($t11, $t12, $t7) + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + 14: $t17 := borrow_local($t16) + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + 16: $t18 := borrow_local($t16) + 17: vector::push_back<0x42::valid_vector::E3>($t18, $t14) + 18: $t19 := borrow_local($t16) + 19: vector::push_back<0x42::valid_vector::E3>($t19, $t15) + 20: $t2 := infer($t16) + 21: return $t2 +} + +============ after LiveVarAnalysisProcessor: ================ + +[variant baseline] +fun valid_vector::test1($t0: i64): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector [unused] + var $t5: &mut vector [unused] + var $t6: i64 [unused] + var $t7: &mut vector [unused] + var $t8: i64 [unused] + # live vars: $t0 + 0: $t2 := vector::empty() + # live vars: $t0, $t2 + 1: $t3 := borrow_local($t2) + # live vars: $t0, $t2, $t3 + 2: vector::push_back($t3, $t0) + # live vars: $t0, $t2 + 3: $t3 := borrow_local($t2) + # live vars: $t0, $t2, $t3 + 4: vector::push_back($t3, $t0) + # live vars: $t2 + 5: $t3 := borrow_local($t2) + # live vars: $t2, $t3 + 6: $t0 := 1 + # live vars: $t0, $t2, $t3 + 7: vector::push_back($t3, $t0) + # live vars: $t2 + 8: $t3 := borrow_local($t2) + # live vars: $t2, $t3 + 9: $t0 := -1 + # live vars: $t0, $t2, $t3 + 10: vector::push_back($t3, $t0) + # live vars: $t2 + 11: $t1 := move($t2) + # live vars: $t1 + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test10($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i128 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> [unused] + var $t19: &mut vector<0x42::valid_vector::E3> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t3, $t7 + 7: $t1 := -1 + # live vars: $t1, $t3, $t7 + 8: $t8 := copy($t3) + # live vars: $t1, $t3, $t7, $t8 + 9: $t10 := pack 0x42::valid_vector::S3($t1, $t8, $t7) + # live vars: $t3, $t7, $t10 + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + # live vars: $t7, $t10, $t13 + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + # live vars: $t10, $t13, $t14 + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + # live vars: $t13, $t14, $t15 + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + # live vars: $t13, $t14, $t15, $t16 + 14: $t17 := borrow_local($t16) + # live vars: $t13, $t14, $t15, $t16, $t17 + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + # live vars: $t14, $t15, $t16 + 16: $t17 := borrow_local($t16) + # live vars: $t14, $t15, $t16, $t17 + 17: vector::push_back<0x42::valid_vector::E3>($t17, $t14) + # live vars: $t15, $t16 + 18: $t17 := borrow_local($t16) + # live vars: $t15, $t16, $t17 + 19: vector::push_back<0x42::valid_vector::E3>($t17, $t15) + # live vars: $t16 + 20: $t2 := move($t16) + # live vars: $t2 + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test2($t0: i128): vector { + var $t1: vector + var $t2: vector + var $t3: &mut vector + var $t4: &mut vector [unused] + var $t5: &mut vector [unused] + var $t6: i128 [unused] + var $t7: &mut vector [unused] + var $t8: i128 [unused] + # live vars: $t0 + 0: $t2 := vector::empty() + # live vars: $t0, $t2 + 1: $t3 := borrow_local($t2) + # live vars: $t0, $t2, $t3 + 2: vector::push_back($t3, $t0) + # live vars: $t0, $t2 + 3: $t3 := borrow_local($t2) + # live vars: $t0, $t2, $t3 + 4: vector::push_back($t3, $t0) + # live vars: $t2 + 5: $t3 := borrow_local($t2) + # live vars: $t2, $t3 + 6: $t0 := 1 + # live vars: $t0, $t2, $t3 + 7: vector::push_back($t3, $t0) + # live vars: $t2 + 8: $t3 := borrow_local($t2) + # live vars: $t2, $t3 + 9: $t0 := -1 + # live vars: $t0, $t2, $t3 + 10: vector::push_back($t3, $t0) + # live vars: $t2 + 11: $t1 := move($t2) + # live vars: $t1 + 12: return $t1 +} + + +[variant baseline] +fun valid_vector::test3($t0: i64, $t1: i128): vector<0x42::valid_vector::S1> { + var $t2: vector<0x42::valid_vector::S1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 [unused] + var $t6: 0x42::valid_vector::S1 + var $t7: u64 [unused] + var $t8: i64 [unused] + var $t9: i128 [unused] + var $t10: vector<0x42::valid_vector::S1> + var $t11: &mut vector<0x42::valid_vector::S1> + var $t12: &mut vector<0x42::valid_vector::S1> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t0 := move($t0) + # live vars: $t0, $t1, $t4 + 2: $t3 := pack 0x42::valid_vector::S1($t4, $t0, $t1) + # live vars: $t3 + 3: $t4 := 1 + # live vars: $t3, $t4 + 4: $t0 := -1 + # live vars: $t0, $t3, $t4 + 5: $t1 := -2 + # live vars: $t0, $t1, $t3, $t4 + 6: $t6 := pack 0x42::valid_vector::S1($t4, $t0, $t1) + # live vars: $t3, $t6 + 7: $t10 := vector::empty<0x42::valid_vector::S1>() + # live vars: $t3, $t6, $t10 + 8: $t11 := borrow_local($t10) + # live vars: $t3, $t6, $t10, $t11 + 9: vector::push_back<0x42::valid_vector::S1>($t11, $t3) + # live vars: $t6, $t10 + 10: $t11 := borrow_local($t10) + # live vars: $t6, $t10, $t11 + 11: vector::push_back<0x42::valid_vector::S1>($t11, $t6) + # live vars: $t10 + 12: $t2 := move($t10) + # live vars: $t2 + 13: return $t2 +} + + +[variant baseline] +fun valid_vector::test4($t0: i64, $t1: i128): vector<0x42::valid_vector::S2> { + var $t2: vector<0x42::valid_vector::S2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S2 + var $t11: 0x42::valid_vector::S1 [unused] + var $t12: i64 [unused] + var $t13: i128 [unused] + var $t14: vector<0x42::valid_vector::S2> + var $t15: &mut vector<0x42::valid_vector::S2> + var $t16: &mut vector<0x42::valid_vector::S2> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t3, $t7 + 7: $t3 := move($t3) + # live vars: $t3, $t7 + 8: $t0 := -1 + # live vars: $t0, $t3, $t7 + 9: $t1 := -2 + # live vars: $t0, $t1, $t3, $t7 + 10: $t10 := pack 0x42::valid_vector::S2($t3, $t0, $t1) + # live vars: $t7, $t10 + 11: $t14 := vector::empty<0x42::valid_vector::S2>() + # live vars: $t7, $t10, $t14 + 12: $t15 := borrow_local($t14) + # live vars: $t7, $t10, $t14, $t15 + 13: vector::push_back<0x42::valid_vector::S2>($t15, $t7) + # live vars: $t10, $t14 + 14: $t15 := borrow_local($t14) + # live vars: $t10, $t14, $t15 + 15: vector::push_back<0x42::valid_vector::S2>($t15, $t10) + # live vars: $t14 + 16: $t2 := move($t14) + # live vars: $t2 + 17: return $t2 +} + + +[variant baseline] +fun valid_vector::test5($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i64 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t5 := copy($t0) + # live vars: $t0, $t1, $t3, $t5, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t5, $t1) + # live vars: $t0, $t3, $t7 + 7: $t0 := move($t0) + # live vars: $t0, $t3, $t7 + 8: $t3 := move($t3) + # live vars: $t0, $t3, $t7 + 9: $t10 := pack 0x42::valid_vector::S3($t0, $t3, $t7) + # live vars: $t10 + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + # live vars: $t10, $t13 + 11: $t14 := borrow_local($t13) + # live vars: $t10, $t13, $t14 + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # live vars: $t10, $t13 + 13: $t14 := borrow_local($t13) + # live vars: $t10, $t13, $t14 + 14: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # live vars: $t13 + 15: $t2 := move($t13) + # live vars: $t2 + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test6($t0: i64, $t1: i128): vector<0x42::valid_vector::S3> { + var $t2: vector<0x42::valid_vector::S3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i128 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: vector<0x42::valid_vector::S3> + var $t14: &mut vector<0x42::valid_vector::S3> + var $t15: &mut vector<0x42::valid_vector::S3> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t1, $t3, $t7 + 7: $t1 := move($t1) + # live vars: $t1, $t3, $t7 + 8: $t3 := move($t3) + # live vars: $t1, $t3, $t7 + 9: $t10 := pack 0x42::valid_vector::S3($t1, $t3, $t7) + # live vars: $t10 + 10: $t13 := vector::empty<0x42::valid_vector::S3>() + # live vars: $t10, $t13 + 11: $t14 := borrow_local($t13) + # live vars: $t10, $t13, $t14 + 12: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # live vars: $t10, $t13 + 13: $t14 := borrow_local($t13) + # live vars: $t10, $t13, $t14 + 14: vector::push_back<0x42::valid_vector::S3>($t14, $t10) + # live vars: $t13 + 15: $t2 := move($t13) + # live vars: $t2 + 16: return $t2 +} + + +[variant baseline] +fun valid_vector::test7($t0: i64, $t1: i128): vector<0x42::valid_vector::E1> { + var $t2: vector<0x42::valid_vector::E1> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i64 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: 0x42::valid_vector::E1 + var $t14: 0x42::valid_vector::E1 + var $t15: 0x42::valid_vector::E1 + var $t16: vector<0x42::valid_vector::E1> + var $t17: &mut vector<0x42::valid_vector::E1> + var $t18: &mut vector<0x42::valid_vector::E1> [unused] + var $t19: &mut vector<0x42::valid_vector::E1> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t3, $t7 + 7: $t0 := -1 + # live vars: $t0, $t3, $t7 + 8: $t8 := copy($t3) + # live vars: $t0, $t3, $t7, $t8 + 9: $t10 := pack 0x42::valid_vector::S3($t0, $t8, $t7) + # live vars: $t3, $t7, $t10 + 10: $t13 := pack_variant 0x42::valid_vector::E1::V1($t3) + # live vars: $t7, $t10, $t13 + 11: $t14 := pack_variant 0x42::valid_vector::E1::V2($t7) + # live vars: $t10, $t13, $t14 + 12: $t15 := pack_variant 0x42::valid_vector::E1::V3($t10) + # live vars: $t13, $t14, $t15 + 13: $t16 := vector::empty<0x42::valid_vector::E1>() + # live vars: $t13, $t14, $t15, $t16 + 14: $t17 := borrow_local($t16) + # live vars: $t13, $t14, $t15, $t16, $t17 + 15: vector::push_back<0x42::valid_vector::E1>($t17, $t13) + # live vars: $t14, $t15, $t16 + 16: $t17 := borrow_local($t16) + # live vars: $t14, $t15, $t16, $t17 + 17: vector::push_back<0x42::valid_vector::E1>($t17, $t14) + # live vars: $t15, $t16 + 18: $t17 := borrow_local($t16) + # live vars: $t15, $t16, $t17 + 19: vector::push_back<0x42::valid_vector::E1>($t17, $t15) + # live vars: $t16 + 20: $t2 := move($t16) + # live vars: $t2 + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test8($t0: i64, $t1: i128): vector<0x42::valid_vector::E2> { + var $t2: vector<0x42::valid_vector::E2> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i128 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: 0x42::valid_vector::E2 + var $t14: 0x42::valid_vector::E2 + var $t15: 0x42::valid_vector::E2 + var $t16: vector<0x42::valid_vector::E2> + var $t17: &mut vector<0x42::valid_vector::E2> + var $t18: &mut vector<0x42::valid_vector::E2> [unused] + var $t19: &mut vector<0x42::valid_vector::E2> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t3, $t7 + 7: $t1 := -1 + # live vars: $t1, $t3, $t7 + 8: $t8 := copy($t3) + # live vars: $t1, $t3, $t7, $t8 + 9: $t10 := pack 0x42::valid_vector::S3($t1, $t8, $t7) + # live vars: $t3, $t7, $t10 + 10: $t13 := pack_variant 0x42::valid_vector::E2::V1($t3) + # live vars: $t7, $t10, $t13 + 11: $t14 := pack_variant 0x42::valid_vector::E2::V2($t7) + # live vars: $t10, $t13, $t14 + 12: $t15 := pack_variant 0x42::valid_vector::E2::V3($t10) + # live vars: $t13, $t14, $t15 + 13: $t16 := vector::empty<0x42::valid_vector::E2>() + # live vars: $t13, $t14, $t15, $t16 + 14: $t17 := borrow_local($t16) + # live vars: $t13, $t14, $t15, $t16, $t17 + 15: vector::push_back<0x42::valid_vector::E2>($t17, $t13) + # live vars: $t14, $t15, $t16 + 16: $t17 := borrow_local($t16) + # live vars: $t14, $t15, $t16, $t17 + 17: vector::push_back<0x42::valid_vector::E2>($t17, $t14) + # live vars: $t15, $t16 + 18: $t17 := borrow_local($t16) + # live vars: $t15, $t16, $t17 + 19: vector::push_back<0x42::valid_vector::E2>($t17, $t15) + # live vars: $t16 + 20: $t2 := move($t16) + # live vars: $t2 + 21: return $t2 +} + + +[variant baseline] +fun valid_vector::test9($t0: i64, $t1: i128): vector<0x42::valid_vector::E3> { + var $t2: vector<0x42::valid_vector::E3> + var $t3: 0x42::valid_vector::S1 + var $t4: u64 + var $t5: i64 + var $t6: i128 + var $t7: 0x42::valid_vector::S2 + var $t8: 0x42::valid_vector::S1 + var $t9: i64 [unused] + var $t10: 0x42::valid_vector::S3 + var $t11: i64 [unused] + var $t12: 0x42::valid_vector::S1 [unused] + var $t13: 0x42::valid_vector::E3 + var $t14: 0x42::valid_vector::E3 + var $t15: 0x42::valid_vector::E3 + var $t16: vector<0x42::valid_vector::E3> + var $t17: &mut vector<0x42::valid_vector::E3> + var $t18: &mut vector<0x42::valid_vector::E3> [unused] + var $t19: &mut vector<0x42::valid_vector::E3> [unused] + # live vars: $t0, $t1 + 0: $t4 := 1 + # live vars: $t0, $t1, $t4 + 1: $t5 := -1 + # live vars: $t0, $t1, $t4, $t5 + 2: $t6 := -2 + # live vars: $t0, $t1, $t4, $t5, $t6 + 3: $t3 := pack 0x42::valid_vector::S1($t4, $t5, $t6) + # live vars: $t0, $t1, $t3 + 4: $t8 := copy($t3) + # live vars: $t0, $t1, $t3, $t8 + 5: $t0 := move($t0) + # live vars: $t0, $t1, $t3, $t8 + 6: $t7 := pack 0x42::valid_vector::S2($t8, $t0, $t1) + # live vars: $t3, $t7 + 7: $t0 := -1 + # live vars: $t0, $t3, $t7 + 8: $t8 := copy($t3) + # live vars: $t0, $t3, $t7, $t8 + 9: $t10 := pack 0x42::valid_vector::S3($t0, $t8, $t7) + # live vars: $t3, $t7, $t10 + 10: $t13 := pack_variant 0x42::valid_vector::E3::V1($t3) + # live vars: $t7, $t10, $t13 + 11: $t14 := pack_variant 0x42::valid_vector::E3::V2($t7) + # live vars: $t10, $t13, $t14 + 12: $t15 := pack_variant 0x42::valid_vector::E3::V3($t10) + # live vars: $t13, $t14, $t15 + 13: $t16 := vector::empty<0x42::valid_vector::E3>() + # live vars: $t13, $t14, $t15, $t16 + 14: $t17 := borrow_local($t16) + # live vars: $t13, $t14, $t15, $t16, $t17 + 15: vector::push_back<0x42::valid_vector::E3>($t17, $t13) + # live vars: $t14, $t15, $t16 + 16: $t17 := borrow_local($t16) + # live vars: $t14, $t15, $t16, $t17 + 17: vector::push_back<0x42::valid_vector::E3>($t17, $t14) + # live vars: $t15, $t16 + 18: $t17 := borrow_local($t16) + # live vars: $t15, $t16, $t17 + 19: vector::push_back<0x42::valid_vector::E3>($t17, $t15) + # live vars: $t16 + 20: $t2 := move($t16) + # live vars: $t2 + 21: return $t2 +} + + +============ disassembled file-format ================== +// Bytecode version v9 +module 0x42::valid_vector +enum E1 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E2 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +enum E3 has copy + drop + V1 + s: S1 + V2 + s: S2 + V3 + s: S3 + +struct S1 has copy + drop + x: u64 + y: i64 + z: i128 + +struct S2 has copy + drop + x: S1 + y: i64 + z: i128 + +struct S3 has copy + drop + x: T0 + y: S1 + z: S2 + +// Function definition at index 0 +fun test1(l0: i64): vector + local l1: vector + vec_pack , 0 + st_loc l1 + mut_borrow_loc l1 + copy_loc l0 + vec_push_back + // @5 + mut_borrow_loc l1 + move_loc l0 + vec_push_back + mut_borrow_loc l1 + ld_i64 1 + // @10 + vec_push_back + mut_borrow_loc l1 + ld_i64 -1 + vec_push_back + move_loc l1 + // @15 + ret + +// Function definition at index 1 +fun test10(l0: i64, l1: i128): vector> + local l2: S1 + local l3: S2 + local l4: E3 + local l5: E3 + local l6: E3 + local l7: vector> + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + ld_i128 -1 + copy_loc l2 + copy_loc l3 + pack S3 + move_loc l2 + // @15 + pack_variant E3, V1 + st_loc l4 + move_loc l3 + pack_variant E3, V2 + st_loc l5 + // @20 + pack_variant E3, V3 + st_loc l6 + vec_pack >, 0 + st_loc l7 + mut_borrow_loc l7 + // @25 + move_loc l4 + vec_push_back > + mut_borrow_loc l7 + move_loc l5 + vec_push_back > + // @30 + mut_borrow_loc l7 + move_loc l6 + vec_push_back > + move_loc l7 + ret + +// Function definition at index 2 +fun test2(l0: i128): vector + local l1: vector + vec_pack , 0 + st_loc l1 + mut_borrow_loc l1 + copy_loc l0 + vec_push_back + // @5 + mut_borrow_loc l1 + move_loc l0 + vec_push_back + mut_borrow_loc l1 + ld_i128 1 + // @10 + vec_push_back + mut_borrow_loc l1 + ld_i128 -1 + vec_push_back + move_loc l1 + // @15 + ret + +// Function definition at index 3 +fun test3(l0: i64, l1: i128): vector + local l2: S1 + local l3: S1 + local l4: vector + ld_u64 1 + move_loc l0 + move_loc l1 + pack S1 + st_loc l2 + // @5 + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l3 + // @10 + vec_pack , 0 + st_loc l4 + mut_borrow_loc l4 + move_loc l2 + vec_push_back + // @15 + mut_borrow_loc l4 + move_loc l3 + vec_push_back + move_loc l4 + ret + +// Function definition at index 4 +fun test4(l0: i64, l1: i128): vector + local l2: S1 + local l3: S2 + local l4: S2 + local l5: vector + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + move_loc l2 + ld_i64 -1 + ld_i128 -2 + pack S2 + st_loc l4 + // @15 + vec_pack , 0 + st_loc l5 + mut_borrow_loc l5 + move_loc l3 + vec_push_back + // @20 + mut_borrow_loc l5 + move_loc l4 + vec_push_back + move_loc l5 + ret + +// Function definition at index 5 +fun test5(l0: i64, l1: i128): vector> + local l2: S1 + local l3: S2 + local l4: S3 + local l5: vector> + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + copy_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + move_loc l0 + move_loc l2 + move_loc l3 + pack S3 + st_loc l4 + // @15 + vec_pack >, 0 + st_loc l5 + mut_borrow_loc l5 + copy_loc l4 + vec_push_back > + // @20 + mut_borrow_loc l5 + move_loc l4 + vec_push_back > + move_loc l5 + ret + +// Function definition at index 6 +fun test6(l0: i64, l1: i128): vector> + local l2: S1 + local l3: S2 + local l4: S3 + local l5: vector> + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + copy_loc l1 + pack S2 + st_loc l3 + // @10 + move_loc l1 + move_loc l2 + move_loc l3 + pack S3 + st_loc l4 + // @15 + vec_pack >, 0 + st_loc l5 + mut_borrow_loc l5 + copy_loc l4 + vec_push_back > + // @20 + mut_borrow_loc l5 + move_loc l4 + vec_push_back > + move_loc l5 + ret + +// Function definition at index 7 +fun test7(l0: i64, l1: i128): vector + local l2: S1 + local l3: S2 + local l4: E1 + local l5: E1 + local l6: E1 + local l7: vector + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + ld_i64 -1 + copy_loc l2 + copy_loc l3 + pack S3 + move_loc l2 + // @15 + pack_variant E1, V1 + st_loc l4 + move_loc l3 + pack_variant E1, V2 + st_loc l5 + // @20 + pack_variant E1, V3 + st_loc l6 + vec_pack , 0 + st_loc l7 + mut_borrow_loc l7 + // @25 + move_loc l4 + vec_push_back + mut_borrow_loc l7 + move_loc l5 + vec_push_back + // @30 + mut_borrow_loc l7 + move_loc l6 + vec_push_back + move_loc l7 + ret + +// Function definition at index 8 +fun test8(l0: i64, l1: i128): vector + local l2: S1 + local l3: S2 + local l4: E2 + local l5: E2 + local l6: E2 + local l7: vector + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + ld_i128 -1 + copy_loc l2 + copy_loc l3 + pack S3 + move_loc l2 + // @15 + pack_variant E2, V1 + st_loc l4 + move_loc l3 + pack_variant E2, V2 + st_loc l5 + // @20 + pack_variant E2, V3 + st_loc l6 + vec_pack , 0 + st_loc l7 + mut_borrow_loc l7 + // @25 + move_loc l4 + vec_push_back + mut_borrow_loc l7 + move_loc l5 + vec_push_back + // @30 + mut_borrow_loc l7 + move_loc l6 + vec_push_back + move_loc l7 + ret + +// Function definition at index 9 +fun test9(l0: i64, l1: i128): vector> + local l2: S1 + local l3: S2 + local l4: E3 + local l5: E3 + local l6: E3 + local l7: vector> + ld_u64 1 + ld_i64 -1 + ld_i128 -2 + pack S1 + st_loc l2 + // @5 + copy_loc l2 + move_loc l0 + move_loc l1 + pack S2 + st_loc l3 + // @10 + ld_i64 -1 + copy_loc l2 + copy_loc l3 + pack S3 + move_loc l2 + // @15 + pack_variant E3, V1 + st_loc l4 + move_loc l3 + pack_variant E3, V2 + st_loc l5 + // @20 + pack_variant E3, V3 + st_loc l6 + vec_pack >, 0 + st_loc l7 + mut_borrow_loc l7 + // @25 + move_loc l4 + vec_push_back > + mut_borrow_loc l7 + move_loc l5 + vec_push_back > + // @30 + mut_borrow_loc l7 + move_loc l6 + vec_push_back > + move_loc l7 + ret + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.move b/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.move new file mode 100644 index 00000000000..14432df027c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/integers/signed/valid_vector.move @@ -0,0 +1,140 @@ +module 0x42::valid_vector { + use std::vector; + + struct S1 has copy, drop { x: u64, y: i64, z: i128 } + + struct S2 has copy, drop { x: S1, y: i64, z: i128 } + + struct S3 has copy, drop { x: T, y: S1, z: S2 } + + enum E1 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E2 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + enum E3 has copy, drop { + V1 {s: S1}, + V2 {s: S2}, + V3 {s: S3}, + } + + fun test1(a: i64): vector { + let v = vector::empty(); // vector with i64 + vector::push_back(&mut v, a); + vector::push_back(&mut v, a); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, -1); + v + } + + fun test2(a: i128): vector { // vector with i128 + let v = vector::empty(); + vector::push_back(&mut v, a); + vector::push_back(&mut v, a); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, -1); + v + } + + fun test3(a: i64, b: i128): vector { + let s1 = S1 {x: 1, y: a, z: b}; + let s11 = S1 {x: 1, y: -1, z: -2}; + let v = vector::empty(); // vector with struct involving i64 and i128 + vector::push_back(&mut v, s1); + vector::push_back(&mut v, s11); + v + } + + fun test4(a: i64, b: i128): vector { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s21 = S2 {x: s1, y: -1, z: -2}; + let v = vector::empty(); // vector with struct involving i64 and i128 and nested struct + vector::push_back(&mut v, s2); + vector::push_back(&mut v, s21); + v + } + + fun test5(a: i64, b: i128): vector> { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: a, y: s1, z: s2}; + let v = vector::empty>(); // vector with struct involving i64, i128, nested struct, and generic types + vector::push_back(&mut v, s3); + vector::push_back(&mut v, s3); + v + } + + fun test6(a: i64, b: i128): vector> { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: b, y: s1, z: s2}; + let v = vector::empty>(); // vector with struct involving i64, i128, nested struct, and generic types + vector::push_back(&mut v, s3); + vector::push_back(&mut v, s3); + v + } + + fun test7(a: i64, b: i128): vector { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e1 = E1::V1{s: s1}; + let e2 = E1::V2{s: s2}; + let e3 = E1::V3{s: s3}; + let v = vector::empty(); // vector with enums involving i64, i128, and nested struct, + vector::push_back(&mut v, e1); + vector::push_back(&mut v, e2); + vector::push_back(&mut v, e3); + v + } + + fun test8(a: i64, b: i128): vector { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e1 = E2::V1{s: s1}; + let e2 = E2::V2{s: s2}; + let e3 = E2::V3{s: s3}; + let v = vector::empty(); // vector with enums involving i64, i128, and nested struct, + vector::push_back(&mut v, e1); + vector::push_back(&mut v, e2); + vector::push_back(&mut v, e3); + v + } + + fun test9(a: i64, b: i128): vector> { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e1 = E3::V1{s: s1}; + let e2 = E3::V2{s: s2}; + let e3 = E3::V3{s: s3}; + let v = vector::empty>(); // vector with enums involving i64, i128, nested struct, and generic types + vector::push_back(&mut v, e1); + vector::push_back(&mut v, e2); + vector::push_back(&mut v, e3); + v + } + + fun test10(a: i64, b: i128): vector> { + let s1 = S1 {x: 1, y: -1, z: -2}; + let s2 = S2 {x: s1, y: a, z: b}; + let s3 = S3 {x: -1, y: s1, z: s2}; + let e1 = E3::V1{s: s1}; + let e2 = E3::V2{s: s2}; + let e3 = E3::V3{s: s3}; + let v = vector::empty>(); // vector with enums involving i64, i128, and nested struct, and generic types + vector::push_back(&mut v, e1); + vector::push_back(&mut v, e2); + vector::push_back(&mut v, e3); + v + } +} diff --git a/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda-2.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda-2.lambda.exp index fa0facbdb16..c947979392e 100644 --- a/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda-2.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda-2.lambda.exp @@ -71,6 +71,7 @@ module 0x42::m { // -- Sourcified model before first bytecode pipeline module 0x42::m { + use std::vector; struct T has copy, drop, store { issuer: vector, version: u64, @@ -91,7 +92,7 @@ module 0x42::m { let x' = 0x1::vector::length(v); let len = 0x1::vector::length(v); while (i < len) { - if (__lambda__1_inline_1_956__test(issuer, x, 0x1::vector::borrow(v, i))) { + if (lambda__1_inline_1_956__test(issuer, x, 0x1::vector::borrow(v, i))) { find = true; found_index = i; break @@ -107,7 +108,7 @@ module 0x42::m { (find, found_index) }; } - fun __lambda__1_inline_1_956__test(issuer: vector, x: u64, obj: &T): bool { + fun lambda__1_inline_1_956__test(issuer: vector, x: u64, obj: &T): bool { /* spec { assume Gt(Len($t0), 0); @@ -991,7 +992,7 @@ fun m::__lambda__1_inline_1_956__test($t0: vector, $t1: u64, $t2: &0x42::m:: # live vars: $t0, $t1, $t5 3: $t4 := ==($t5, $t0) # live vars: $t1, $t4 - 4: if ($t4) goto 5 else goto 11 + 4: if ($t4) goto 5 else goto 10 # live vars: $t1 5: label L0 # live vars: $t1 @@ -1001,114 +1002,108 @@ fun m::__lambda__1_inline_1_956__test($t0: vector, $t1: u64, $t2: &0x42::m:: # live vars: $t7, $t8 8: $t4 := >($t7, $t8) # live vars: $t4 - 9: label L2 - # live vars: $t4 - 10: return $t4 + 9: return $t4 # live vars: $t1 - 11: label L1 + 10: label L1 # live vars: - 12: $t4 := false + 11: $t4 := false # live vars: $t4 - 13: goto 9 + 12: return $t4 } ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct T has copy, drop, store { - issuer: vector, - version: u64 -} -struct J has copy, drop, store { - variant: u64 -} -struct S has copy, drop, store { - entries: vector -} +// Bytecode version v9 +module 0x42::m +struct T has copy + drop + store + issuer: vector + version: u64 + +struct J has copy + drop + store + variant: u64 + +struct S has copy + drop + store + entries: vector + +// Function definition at index 0 +fun test(l0: &mut S, l1: vector) + local l2: u64 + local l3: &vector + local l4: bool + local l5: u64 + local l6: u64 + local l7: u64 + local l8: u64 + copy_loc l0 + borrow_field S, entries + vec_len + st_loc l2 + move_loc l0 + // @5 + borrow_field S, entries + st_loc l3 + ld_false + st_loc l4 + ld_u64 0 + // @10 + st_loc l5 + ld_u64 0 + st_loc l6 + copy_loc l3 + vec_len + // @15 + st_loc l7 + copy_loc l3 + vec_len + st_loc l8 +l3: copy_loc l6 + // @20 + copy_loc l8 + lt + br_true l0 + branch l1 +l0: copy_loc l1 + // @25 + copy_loc l2 + copy_loc l3 + copy_loc l6 + vec_borrow + call __lambda__1_inline_1_956__test + // @30 + br_false l2 + ld_true + st_loc l4 + move_loc l6 + st_loc l5 + // @35 +l1: nop + move_loc l3 + pop + ret +l2: move_loc l6 + // @40 + copy_loc l7 + add + st_loc l6 + branch l3 + +// Function definition at index 1 +fun __lambda__1_inline_1_956__test(l0: vector, l1: u64, l2: &T): bool + nop + move_loc l2 + borrow_field T, issuer + read_ref + move_loc l0 + // @5 + eq + br_false l0 + move_loc l1 + ld_u64 0 + gt + // @10 + ret +l0: ld_false + ret + -test(s: &mut S, issuer: vector) /* def_idx: 0 */ { -L2: x: u64 -L3: v: &vector -L4: find: bool -L5: found_index: u64 -L6: i: u64 -L7: x': u64 -L8: len: u64 -B0: - 0: CopyLoc[0](s: &mut S) - 1: ImmBorrowField[0](S.entries: vector) - 2: VecLen(2) - 3: StLoc[2](x: u64) - 4: MoveLoc[0](s: &mut S) - 5: ImmBorrowField[0](S.entries: vector) - 6: StLoc[3](v: &vector) - 7: LdFalse - 8: StLoc[4](find: bool) - 9: LdU64(0) - 10: StLoc[5](found_index: u64) - 11: LdU64(0) - 12: StLoc[6](i: u64) - 13: CopyLoc[3](v: &vector) - 14: VecLen(2) - 15: StLoc[7](x': u64) - 16: CopyLoc[3](v: &vector) - 17: VecLen(2) - 18: StLoc[8](len: u64) -B1: - 19: CopyLoc[6](i: u64) - 20: CopyLoc[8](len: u64) - 21: Lt - 22: BrTrue(24) -B2: - 23: Branch(35) -B3: - 24: CopyLoc[1](issuer: vector) - 25: CopyLoc[2](x: u64) - 26: CopyLoc[3](v: &vector) - 27: CopyLoc[6](i: u64) - 28: VecImmBorrow(2) - 29: Call __lambda__1_inline_1_956__test(vector, u64, &T): bool - 30: BrFalse(39) -B4: - 31: LdTrue - 32: StLoc[4](find: bool) - 33: MoveLoc[6](i: u64) - 34: StLoc[5](found_index: u64) -B5: - 35: Nop - 36: MoveLoc[3](v: &vector) - 37: Pop - 38: Ret -B6: - 39: MoveLoc[6](i: u64) - 40: CopyLoc[7](x': u64) - 41: Add - 42: StLoc[6](i: u64) - 43: Branch(19) -} -__lambda__1_inline_1_956__test(issuer: vector, x: u64, obj: &T): bool /* def_idx: 1 */ { -L3: $t4: bool -B0: - 0: Nop - 1: MoveLoc[2](obj: &T) - 2: ImmBorrowField[1](T.issuer: vector) - 3: ReadRef - 4: MoveLoc[0](issuer: vector) - 5: Eq - 6: BrFalse(13) -B1: - 7: MoveLoc[1](x: u64) - 8: LdU64(0) - 9: Gt - 10: StLoc[3]($t4: bool) -B2: - 11: MoveLoc[3]($t4: bool) - 12: Ret -B3: - 13: LdFalse - 14: StLoc[3]($t4: bool) - 15: Branch(11) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda.lambda.exp b/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda.lambda.exp index 68dc4758f6e..612896b763a 100644 --- a/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda.lambda.exp +++ b/third_party/move/move-compiler-v2/tests/lambda-spec/inline-lambda.lambda.exp @@ -109,9 +109,9 @@ module 0x42::Test { let z = 3 + y; { let (x) = (y); - let y = __lambda__1_inline_1_905__call_inline(x); - let z' = __lambda__1_inline_2_916__call_inline(z, x); - let w = __lambda__1_inline_3_927__call_inline(z, x); + let y = lambda__1_inline_1_905__call_inline(x); + let z' = lambda__1_inline_2_916__call_inline(z, x); + let w = lambda__1_inline_3_927__call_inline(z, x); /* spec { assert Eq(y, Gt(x, 2)); @@ -134,7 +134,7 @@ module 0x42::Test { } */ ; - __lambda__1_inline_1_267__test_apply(v) + lambda__1_inline_1_267__test_apply(v) }; /* spec { @@ -151,7 +151,7 @@ module 0x42::Test { } */ ; - __lambda__1_inline_1_393__test_apply(a1, a2, v) + lambda__1_inline_1_393__test_apply(a1, a2, v) }; /* spec { @@ -160,22 +160,22 @@ module 0x42::Test { */ ; } - fun __lambda__1_inline_1_905__call_inline(x: u64): bool { + fun lambda__1_inline_1_905__call_inline(x: u64): bool { x > 2 } - fun __lambda__1_inline_2_916__call_inline(z: u64, x: u64): bool { + fun lambda__1_inline_2_916__call_inline(z: u64, x: u64): bool { x > z } - fun __lambda__1_inline_3_927__call_inline(z: u64, x: u64): bool { + fun lambda__1_inline_3_927__call_inline(z: u64, x: u64): bool { while (z > 0) { let _x = x + 1; }; x > 5 } - fun __lambda__1_inline_1_267__test_apply(v: u64): bool { + fun lambda__1_inline_1_267__test_apply(v: u64): bool { v >= 0 } - fun __lambda__1_inline_1_393__test_apply(a1: u64, a2: u64, v: u64): bool { + fun lambda__1_inline_1_393__test_apply(a1: u64, a2: u64, v: u64): bool { v != a1 + a2 } } @@ -1168,102 +1168,106 @@ fun Test::__lambda__1_inline_1_393__test_apply($t0: u64, $t1: u64, $t2: u64): bo ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { - - -call_inline(y: u64) /* def_idx: 0 */ { -L1: z: u64 -L2: x: u64 -L3: y: bool -L4: z': bool -L5: w: bool -B0: - 0: LdU64(3) - 1: CopyLoc[0](y: u64) - 2: Add - 3: StLoc[1](z: u64) - 4: MoveLoc[0](y: u64) - 5: StLoc[2](x: u64) - 6: CopyLoc[2](x: u64) - 7: Call __lambda__1_inline_1_905__call_inline(u64): bool - 8: StLoc[3](y: bool) - 9: CopyLoc[1](z: u64) - 10: CopyLoc[2](x: u64) - 11: Call __lambda__1_inline_2_916__call_inline(u64, u64): bool - 12: StLoc[4](z': bool) - 13: CopyLoc[1](z: u64) - 14: CopyLoc[2](x: u64) - 15: Call __lambda__1_inline_3_927__call_inline(u64, u64): bool - 16: StLoc[5](w: bool) - 17: Nop - 18: Ret -} -public test_apply(a1: u64, a2: u64) /* def_idx: 1 */ { -L2: r1: bool -L3: r2: bool -B0: - 0: Nop - 1: LdU64(0) - 2: Call __lambda__1_inline_1_267__test_apply(u64): bool - 3: StLoc[2](r1: bool) - 4: Nop - 5: Nop - 6: MoveLoc[0](a1: u64) - 7: MoveLoc[1](a2: u64) - 8: LdU64(0) - 9: Call __lambda__1_inline_1_393__test_apply(u64, u64, u64): bool - 10: StLoc[3](r2: bool) - 11: Nop - 12: Ret -} -__lambda__1_inline_1_905__call_inline(x: u64): bool /* def_idx: 2 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: LdU64(2) - 2: Gt - 3: Ret -} -__lambda__1_inline_2_916__call_inline(z: u64, x: u64): bool /* def_idx: 3 */ { -B0: - 0: MoveLoc[1](x: u64) - 1: MoveLoc[0](z: u64) - 2: Gt - 3: Ret -} -__lambda__1_inline_3_927__call_inline(z: u64, x: u64): bool /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](z: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(9) -B1: - 4: CopyLoc[1](x: u64) - 5: LdU64(1) - 6: Add - 7: Pop - 8: Branch(0) -B2: - 9: MoveLoc[1](x: u64) - 10: LdU64(5) - 11: Gt - 12: Ret -} -__lambda__1_inline_1_267__test_apply(v: u64): bool /* def_idx: 5 */ { -B0: - 0: MoveLoc[0](v: u64) - 1: LdU64(0) - 2: Ge - 3: Ret -} -__lambda__1_inline_1_393__test_apply(a1: u64, a2: u64, v: u64): bool /* def_idx: 6 */ { -B0: - 0: MoveLoc[2](v: u64) - 1: MoveLoc[0](a1: u64) - 2: MoveLoc[1](a2: u64) - 3: Add - 4: Neq - 5: Ret -} -} +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +fun call_inline(l0: u64) + local l1: u64 + local l2: u64 + local l3: bool + local l4: bool + local l5: bool + ld_u64 3 + copy_loc l0 + add + st_loc l1 + move_loc l0 + // @5 + st_loc l2 + copy_loc l2 + call __lambda__1_inline_1_905__call_inline + st_loc l3 + copy_loc l1 + // @10 + copy_loc l2 + call __lambda__1_inline_2_916__call_inline + st_loc l4 + copy_loc l1 + copy_loc l2 + // @15 + call __lambda__1_inline_3_927__call_inline + st_loc l5 + nop + ret + +// Function definition at index 1 +#[persistent] public fun test_apply(l0: u64, l1: u64) + local l2: bool + local l3: bool + nop + ld_u64 0 + call __lambda__1_inline_1_267__test_apply + st_loc l2 + nop + // @5 + nop + move_loc l0 + move_loc l1 + ld_u64 0 + call __lambda__1_inline_1_393__test_apply + // @10 + st_loc l3 + nop + ret + +// Function definition at index 2 +fun __lambda__1_inline_1_905__call_inline(l0: u64): bool + move_loc l0 + ld_u64 2 + gt + ret + +// Function definition at index 3 +fun __lambda__1_inline_2_916__call_inline(l0: u64, l1: u64): bool + move_loc l1 + move_loc l0 + gt + ret + +// Function definition at index 4 +fun __lambda__1_inline_3_927__call_inline(l0: u64, l1: u64): bool +l1: copy_loc l0 + ld_u64 0 + gt + br_false l0 + copy_loc l1 + // @5 + ld_u64 1 + add + pop + branch l1 +l0: move_loc l1 + // @10 + ld_u64 5 + gt + ret + +// Function definition at index 5 +fun __lambda__1_inline_1_267__test_apply(l0: u64): bool + move_loc l0 + ld_u64 0 + ge + ret + +// Function definition at index 6 +fun __lambda__1_inline_1_393__test_apply(l0: u64, l1: u64, l2: u64): bool + move_loc l2 + move_loc l0 + move_loc l1 + add + neq + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/live-var/bug_9717_looponly.exp b/third_party/move/move-compiler-v2/tests/live-var/bug_9717_looponly.exp index 529d4b81f55..2b4560a0a33 100644 --- a/third_party/move/move-compiler-v2/tests/live-var/bug_9717_looponly.exp +++ b/third_party/move/move-compiler-v2/tests/live-var/bug_9717_looponly.exp @@ -912,56 +912,52 @@ public fun vectors::guess_flips_break2($t0: vector): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + local l1: u64 + local l2: &vector + ld_u64 0 + st_loc l1 + borrow_loc l0 + st_loc l2 +l4: copy_loc l1 + // @5 + copy_loc l2 + vec_len + lt + br_true l0 + branch l1 + // @10 +l0: copy_loc l2 + copy_loc l1 + vec_borrow + read_ref + ld_u8 0 + // @15 + neq + br_false l2 + branch l1 +l1: move_loc l2 + vec_len + // @20 + ret +l2: move_loc l1 + ld_u64 1 + add + st_loc l1 + // @25 + copy_loc l2 + copy_loc l1 + vec_borrow + read_ref + ld_u8 5 + // @30 + eq + br_false l3 + branch l1 +l3: branch l4 -entry public guess_flips_break2(flips: vector): u64 /* def_idx: 0 */ { -L1: i: u64 -L2: flipsref5: &vector -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) - 2: ImmBorrowLoc[0](flips: vector) - 3: StLoc[2](flipsref5: &vector) -B1: - 4: CopyLoc[1](i: u64) - 5: CopyLoc[2](flipsref5: &vector) - 6: VecLen(2) - 7: Lt - 8: BrTrue(10) -B2: - 9: Branch(18) -B3: - 10: CopyLoc[2](flipsref5: &vector) - 11: CopyLoc[1](i: u64) - 12: VecImmBorrow(2) - 13: ReadRef - 14: LdU8(0) - 15: Neq - 16: BrFalse(21) -B4: - 17: Branch(18) -B5: - 18: MoveLoc[2](flipsref5: &vector) - 19: VecLen(2) - 20: Ret -B6: - 21: MoveLoc[1](i: u64) - 22: LdU64(1) - 23: Add - 24: StLoc[1](i: u64) - 25: CopyLoc[2](flipsref5: &vector) - 26: CopyLoc[1](i: u64) - 27: VecImmBorrow(2) - 28: ReadRef - 29: LdU8(5) - 30: Eq - 31: BrFalse(33) -B7: - 32: Branch(18) -B8: - 33: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/live-var/mut_inline.exp b/third_party/move/move-compiler-v2/tests/live-var/mut_inline.exp index 2081db02af9..04f2061ccf2 100644 --- a/third_party/move/move-compiler-v2/tests/live-var/mut_inline.exp +++ b/third_party/move/move-compiler-v2/tests/live-var/mut_inline.exp @@ -1647,101 +1647,101 @@ fun m::foo(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +fun foo(): u64 + local l0: vector + local l1: &mut vector + local l2: &mut vector + local l3: u64 + local l4: u64 + local l5: u64 + ld_const> [1, 2, 3] + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + st_loc l2 + ld_u64 0 + st_loc l3 + copy_loc l2 + freeze_ref + // @10 + vec_len + st_loc l4 +l7: copy_loc l3 + copy_loc l4 + lt + // @15 + br_true l0 + branch l1 +l0: copy_loc l2 + freeze_ref + copy_loc l3 + // @20 + vec_borrow + read_ref + ld_u64 1 + gt + br_true l2 + // @25 + branch l1 +l1: copy_loc l3 + st_loc l5 + move_loc l3 + ld_u64 1 + // @30 + add + st_loc l3 +l6: copy_loc l3 + copy_loc l4 + lt + // @35 + br_false l3 + copy_loc l2 + freeze_ref + copy_loc l3 + vec_borrow + // @40 + read_ref + ld_u64 1 + gt + br_true l4 + branch l5 + // @45 +l4: copy_loc l2 + copy_loc l5 + copy_loc l3 + vec_swap + move_loc l5 + // @50 + ld_u64 1 + add + st_loc l5 +l5: move_loc l3 + ld_u64 1 + // @55 + add + st_loc l3 + branch l6 +l3: move_loc l2 + pop + // @60 + move_loc l1 + freeze_ref + ld_u64 0 + vec_borrow + read_ref + // @65 + ret +l2: move_loc l3 + ld_u64 1 + add + st_loc l3 + // @70 + branch l7 -foo(): u64 /* def_idx: 0 */ { -L0: v: vector -L1: r: &mut vector -L2: v: &mut vector -L3: i: u64 -L4: len: u64 -L5: $t9: u64 -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: StLoc[0](v: vector) - 2: MutBorrowLoc[0](v: vector) - 3: StLoc[1](r: &mut vector) - 4: CopyLoc[1](r: &mut vector) - 5: StLoc[2](v: &mut vector) - 6: LdU64(0) - 7: StLoc[3](i: u64) - 8: CopyLoc[2](v: &mut vector) - 9: FreezeRef - 10: VecLen(1) - 11: StLoc[4](len: u64) -B1: - 12: CopyLoc[3](i: u64) - 13: CopyLoc[4](len: u64) - 14: Lt - 15: BrTrue(17) -B2: - 16: Branch(26) -B3: - 17: CopyLoc[2](v: &mut vector) - 18: FreezeRef - 19: CopyLoc[3](i: u64) - 20: VecImmBorrow(1) - 21: ReadRef - 22: LdU64(1) - 23: Gt - 24: BrTrue(66) -B4: - 25: Branch(26) -B5: - 26: CopyLoc[3](i: u64) - 27: StLoc[5]($t9: u64) - 28: MoveLoc[3](i: u64) - 29: LdU64(1) - 30: Add - 31: StLoc[3](i: u64) -B6: - 32: CopyLoc[3](i: u64) - 33: CopyLoc[4](len: u64) - 34: Lt - 35: BrFalse(58) -B7: - 36: CopyLoc[2](v: &mut vector) - 37: FreezeRef - 38: CopyLoc[3](i: u64) - 39: VecImmBorrow(1) - 40: ReadRef - 41: LdU64(1) - 42: Gt - 43: BrTrue(45) -B8: - 44: Branch(53) -B9: - 45: CopyLoc[2](v: &mut vector) - 46: CopyLoc[5]($t9: u64) - 47: CopyLoc[3](i: u64) - 48: VecSwap(1) - 49: MoveLoc[5]($t9: u64) - 50: LdU64(1) - 51: Add - 52: StLoc[5]($t9: u64) -B10: - 53: MoveLoc[3](i: u64) - 54: LdU64(1) - 55: Add - 56: StLoc[3](i: u64) - 57: Branch(32) -B11: - 58: MoveLoc[2](v: &mut vector) - 59: Pop - 60: MoveLoc[1](r: &mut vector) - 61: FreezeRef - 62: LdU64(0) - 63: VecImmBorrow(1) - 64: ReadRef - 65: Ret -B12: - 66: MoveLoc[3](i: u64) - 67: LdU64(1) - 68: Add - 69: StLoc[3](i: u64) - 70: Branch(12) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/live-var/mut_inline_typed.exp b/third_party/move/move-compiler-v2/tests/live-var/mut_inline_typed.exp index 2081db02af9..04f2061ccf2 100644 --- a/third_party/move/move-compiler-v2/tests/live-var/mut_inline_typed.exp +++ b/third_party/move/move-compiler-v2/tests/live-var/mut_inline_typed.exp @@ -1647,101 +1647,101 @@ fun m::foo(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +fun foo(): u64 + local l0: vector + local l1: &mut vector + local l2: &mut vector + local l3: u64 + local l4: u64 + local l5: u64 + ld_const> [1, 2, 3] + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + st_loc l2 + ld_u64 0 + st_loc l3 + copy_loc l2 + freeze_ref + // @10 + vec_len + st_loc l4 +l7: copy_loc l3 + copy_loc l4 + lt + // @15 + br_true l0 + branch l1 +l0: copy_loc l2 + freeze_ref + copy_loc l3 + // @20 + vec_borrow + read_ref + ld_u64 1 + gt + br_true l2 + // @25 + branch l1 +l1: copy_loc l3 + st_loc l5 + move_loc l3 + ld_u64 1 + // @30 + add + st_loc l3 +l6: copy_loc l3 + copy_loc l4 + lt + // @35 + br_false l3 + copy_loc l2 + freeze_ref + copy_loc l3 + vec_borrow + // @40 + read_ref + ld_u64 1 + gt + br_true l4 + branch l5 + // @45 +l4: copy_loc l2 + copy_loc l5 + copy_loc l3 + vec_swap + move_loc l5 + // @50 + ld_u64 1 + add + st_loc l5 +l5: move_loc l3 + ld_u64 1 + // @55 + add + st_loc l3 + branch l6 +l3: move_loc l2 + pop + // @60 + move_loc l1 + freeze_ref + ld_u64 0 + vec_borrow + read_ref + // @65 + ret +l2: move_loc l3 + ld_u64 1 + add + st_loc l3 + // @70 + branch l7 -foo(): u64 /* def_idx: 0 */ { -L0: v: vector -L1: r: &mut vector -L2: v: &mut vector -L3: i: u64 -L4: len: u64 -L5: $t9: u64 -B0: - 0: LdConst[0](Vector(U64): [3, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]) - 1: StLoc[0](v: vector) - 2: MutBorrowLoc[0](v: vector) - 3: StLoc[1](r: &mut vector) - 4: CopyLoc[1](r: &mut vector) - 5: StLoc[2](v: &mut vector) - 6: LdU64(0) - 7: StLoc[3](i: u64) - 8: CopyLoc[2](v: &mut vector) - 9: FreezeRef - 10: VecLen(1) - 11: StLoc[4](len: u64) -B1: - 12: CopyLoc[3](i: u64) - 13: CopyLoc[4](len: u64) - 14: Lt - 15: BrTrue(17) -B2: - 16: Branch(26) -B3: - 17: CopyLoc[2](v: &mut vector) - 18: FreezeRef - 19: CopyLoc[3](i: u64) - 20: VecImmBorrow(1) - 21: ReadRef - 22: LdU64(1) - 23: Gt - 24: BrTrue(66) -B4: - 25: Branch(26) -B5: - 26: CopyLoc[3](i: u64) - 27: StLoc[5]($t9: u64) - 28: MoveLoc[3](i: u64) - 29: LdU64(1) - 30: Add - 31: StLoc[3](i: u64) -B6: - 32: CopyLoc[3](i: u64) - 33: CopyLoc[4](len: u64) - 34: Lt - 35: BrFalse(58) -B7: - 36: CopyLoc[2](v: &mut vector) - 37: FreezeRef - 38: CopyLoc[3](i: u64) - 39: VecImmBorrow(1) - 40: ReadRef - 41: LdU64(1) - 42: Gt - 43: BrTrue(45) -B8: - 44: Branch(53) -B9: - 45: CopyLoc[2](v: &mut vector) - 46: CopyLoc[5]($t9: u64) - 47: CopyLoc[3](i: u64) - 48: VecSwap(1) - 49: MoveLoc[5]($t9: u64) - 50: LdU64(1) - 51: Add - 52: StLoc[5]($t9: u64) -B10: - 53: MoveLoc[3](i: u64) - 54: LdU64(1) - 55: Add - 56: StLoc[3](i: u64) - 57: Branch(32) -B11: - 58: MoveLoc[2](v: &mut vector) - 59: Pop - 60: MoveLoc[1](r: &mut vector) - 61: FreezeRef - 62: LdU64(0) - 63: VecImmBorrow(1) - 64: ReadRef - 65: Ret -B12: - 66: MoveLoc[3](i: u64) - 67: LdU64(1) - 68: Add - 69: StLoc[3](i: u64) - 70: Branch(12) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long.exp b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long.exp index 9fc62fbd6fd..f8c26b6ee4f 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long.exp @@ -4,10 +4,10 @@ error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long.move:3:9 │ 3 │ 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into the largest possible integer type, 'u256' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into the largest possible integer type, 'u256' error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long.move:4:9 │ 4 │ 340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into the largest possible integer type, 'u256' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into the largest possible integer type, 'u256' diff --git a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u128.exp b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u128.exp index 74b08c71d8e..13585b1c69e 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u128.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u128.exp @@ -4,10 +4,10 @@ error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u128.move:4:9 │ 4 │ 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFu128; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into 'u128' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'u128' error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u128.move:6:9 │ 6 │ 340282366920938463463374607431768211456u128; - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into 'u128' + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'u128' diff --git a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u64.exp b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u64.exp index 775cecbdcdd..48463fabc0e 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u64.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u64.exp @@ -4,10 +4,10 @@ error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u64.move:4:9 │ 4 │ 0x1FFFFFFFFFFFFFFFFu64; - │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into 'u64' + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'u64' error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u64.move:6:9 │ 6 │ 18446744073709551616u64; - │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal is too large to fit into 'u64' + │ ^^^^^^^^^^^^^^^^^^^^^^^ Invalid number literal. The given literal cannot fit into 'u64' diff --git a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u8.exp b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u8.exp index ed2b7b67bfd..8dcc7a441a4 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u8.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/expansion/number_literal_too_long_u8.exp @@ -4,10 +4,10 @@ error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u8.move:4:9 │ 4 │ 0x1FFu8; - │ ^^^^^^^ Invalid number literal. The given literal is too large to fit into 'u8' + │ ^^^^^^^ Invalid number literal. The given literal cannot fit into 'u8' error: invalid number literal ┌─ tests/more-v1/expansion/number_literal_too_long_u8.move:6:9 │ 6 │ 256u8; - │ ^^^^^ Invalid number literal. The given literal is too large to fit into 'u8' + │ ^^^^^ Invalid number literal. The given literal cannot fit into 'u8' diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/constants_blocks.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/constants_blocks.exp index b37d6382cbd..268f96f9b76 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/constants_blocks.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/constants_blocks.exp @@ -60,7 +60,7 @@ error: Invalid type for constant 14 │ │ │ x + y; 15 │ │ │ }; │ ╰─│─────^ - │ ╰──────' Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. + │ ╰──────' Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, or `vector<_>` with valid element type. error: Not a valid constant expression. ┌─ tests/more-v1/parser/constants_blocks.move:16:25 diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/expr_unary_negation.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/expr_unary_negation.exp index 7f198569788..4383b67823b 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/expr_unary_negation.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/expr_unary_negation.exp @@ -1,10 +1,7 @@ Diagnostics: -error: unexpected token - ┌─ tests/more-v1/parser/expr_unary_negation.move:5:19 +error: the function takes 2 arguments but 1 were provided + ┌─ tests/more-v1/parser/expr_unary_negation.move:5:33 │ 5 │ assert!(((1 - -2) == 3) && (-(1 - 2) == 1), 100); - │ ^ - │ │ - │ Unexpected '-' - │ Expected an expression term + │ ^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression.exp index 79eacc819f6..3e8246732c6 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression.exp @@ -6,7 +6,7 @@ error: constraint `integer` incompatible with `||_ has ..` 3 │ (if (true) 5 else 0)(); │ ^^^^^^^^^^^^^^^^^^^^^^ -error: expected function of type `|(integer, integer)|_` but found `()` +error: expected function of type `|integer, integer|_` but found `()` ┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression.move:4:9 │ 4 │ (while (false) {})(0, 1); diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression2.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression2.exp index b8fac03cbb8..2eb36c38267 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression2.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_complex_expression2.exp @@ -6,7 +6,7 @@ error: constraint `integer` incompatible with `||_ has ..` 3 │ (if (true) 5 else 0)(); │ ^^^^^^^^^^^^^^^^^^^^^^ -error: expected function of type `|(integer, integer)|_` but found `()` +error: expected function of type `|integer, integer|_` but found `()` ┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression2.move:4:9 │ 4 │ (while (false) {})(0, 1); diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value.exp index 3ebacc3184c..4861155494a 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value.exp @@ -6,7 +6,7 @@ error: constraint `integer` incompatible with `||_ has ..` 3 │ 5(); │ ^^^ -error: constraint `integer` incompatible with `|(integer, integer)|_ has ..` +error: constraint `integer` incompatible with `|integer, integer|_ has ..` ┌─ tests/more-v1/parser/invalid_call_lhs_value.move:4:9 │ 4 │ 5(0, 1); diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value2.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value2.exp index f2dc380f4e5..04010409188 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value2.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/invalid_call_lhs_value2.exp @@ -6,7 +6,7 @@ error: constraint `integer` incompatible with `||_ has ..` 3 │ 5(); │ ^^^ -error: constraint `integer` incompatible with `|(integer, integer)|_ has ..` +error: constraint `integer` incompatible with `|integer, integer|_ has ..` ┌─ tests/more-v1/parser/invalid_call_lhs_value2.move:4:9 │ 4 │ 5(0, 1); diff --git a/third_party/move/move-compiler-v2/tests/more-v1/parser/struct_public.exp b/third_party/move/move-compiler-v2/tests/more-v1/parser/struct_public.exp index 90b32906711..5b3086a3909 100644 --- a/third_party/move/move-compiler-v2/tests/more-v1/parser/struct_public.exp +++ b/third_party/move/move-compiler-v2/tests/more-v1/parser/struct_public.exp @@ -1,2 +1,13 @@ +Diagnostics: +warning: structs/enums with visibility modifier are only supported at version 2.4-unstable or later + ┌─ tests/more-v1/parser/struct_public.move:1:1 + │ +1 │ ╭ module 0x42::M { +2 │ │ // visibility modifiers on structs fail during parsing +3 │ │ public struct Foo {} +4 │ │ } + │ ╰─^ + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/op-equal/eval_order.exp b/third_party/move/move-compiler-v2/tests/op-equal/eval_order.exp index 87461dff632..5c5df43cd95 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/eval_order.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/eval_order.exp @@ -79,69 +79,69 @@ module 0xc0ffee::m { module 0xc0ffee::m { fun mod1(r: &mut u64) { { - let $t2 = 2; - let $t1 = r; - *$t1 = *$t1 + $t2 + let _t2 = 2; + let _t1 = r; + *_t1 = *_t1 + _t2 }; } fun mod2(r: &mut u64): u64 { { - let $t2 = 2; - let $t1 = r; - *$t1 = *$t1 + $t2 + let _t2 = 2; + let _t1 = r; + *_t1 = *_t1 + _t2 }; *r } public fun test0(): u64 { let v = 1; { - let $t = { + let _t = { { - let $t = { + let _t = { { - let $t = 2; - v = v + $t + let _t = 2; + v = v + _t }; v }; - v = v + $t + v = v + _t }; v }; - v = v + $t + v = v + _t }; v } public fun test1(): u64 { let v = 1; { - let $t = { + let _t = { { - let $t = 2; - v = v + $t + let _t = 2; + v = v + _t }; v }; - v = v + $t + v = v + _t }; v } public fun test2(): u64 { let v = 1; { - let $t = { + let _t = { mod1(&mut v); v }; - v = v + $t + v = v + _t }; v } public fun test3(): u64 { let v = 1; { - let $t = mod2(&mut v); - v = v + $t + let _t = mod2(&mut v); + v = v + _t }; v } @@ -1056,99 +1056,106 @@ public fun m::test3(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun mod1(l0: &mut u64) + copy_loc l0 + read_ref + ld_u64 2 + add + move_loc l0 + // @5 + write_ref + ret + +// Function definition at index 1 +fun mod2(l0: &mut u64): u64 + local l1: &mut u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + read_ref + ld_u64 2 + // @5 + add + move_loc l1 + write_ref + move_loc l0 + read_ref + // @10 + ret + +// Function definition at index 2 +#[persistent] public fun test0(): u64 + local l0: u64 + local l1: u64 + ld_u64 1 + ld_u64 2 + add + st_loc l0 + copy_loc l0 + // @5 + st_loc l1 + move_loc l0 + move_loc l1 + add + st_loc l0 + // @10 + copy_loc l0 + st_loc l1 + move_loc l0 + move_loc l1 + add + // @15 + ret + +// Function definition at index 3 +#[persistent] public fun test1(): u64 + local l0: u64 + local l1: u64 + ld_u64 1 + ld_u64 2 + add + st_loc l0 + copy_loc l0 + // @5 + st_loc l1 + move_loc l0 + move_loc l1 + add + ret + +// Function definition at index 4 +#[persistent] public fun test2(): u64 + local l0: u64 + local l1: u64 + ld_u64 1 + st_loc l0 + mut_borrow_loc l0 + call mod1 + copy_loc l0 + // @5 + st_loc l1 + move_loc l0 + move_loc l1 + add + ret + +// Function definition at index 5 +#[persistent] public fun test3(): u64 + local l0: u64 + local l1: u64 + ld_u64 1 + st_loc l0 + mut_borrow_loc l0 + call mod2 + st_loc l1 + // @5 + move_loc l0 + move_loc l1 + add + ret -mod1(r: &mut u64) /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](r: &mut u64) - 1: ReadRef - 2: LdU64(2) - 3: Add - 4: MoveLoc[0](r: &mut u64) - 5: WriteRef - 6: Ret -} -mod2(r: &mut u64): u64 /* def_idx: 1 */ { -L1: $t1: &mut u64 -B0: - 0: CopyLoc[0](r: &mut u64) - 1: StLoc[1]($t1: &mut u64) - 2: CopyLoc[1]($t1: &mut u64) - 3: ReadRef - 4: LdU64(2) - 5: Add - 6: MoveLoc[1]($t1: &mut u64) - 7: WriteRef - 8: MoveLoc[0](r: &mut u64) - 9: ReadRef - 10: Ret -} -public test0(): u64 /* def_idx: 2 */ { -L0: v: u64 -L1: $t5: u64 -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: Add - 3: StLoc[0](v: u64) - 4: CopyLoc[0](v: u64) - 5: StLoc[1]($t5: u64) - 6: MoveLoc[0](v: u64) - 7: MoveLoc[1]($t5: u64) - 8: Add - 9: StLoc[0](v: u64) - 10: CopyLoc[0](v: u64) - 11: StLoc[1]($t5: u64) - 12: MoveLoc[0](v: u64) - 13: MoveLoc[1]($t5: u64) - 14: Add - 15: Ret -} -public test1(): u64 /* def_idx: 3 */ { -L0: v: u64 -L1: $t4: u64 -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: Add - 3: StLoc[0](v: u64) - 4: CopyLoc[0](v: u64) - 5: StLoc[1]($t4: u64) - 6: MoveLoc[0](v: u64) - 7: MoveLoc[1]($t4: u64) - 8: Add - 9: Ret -} -public test2(): u64 /* def_idx: 4 */ { -L0: v: u64 -L1: $t: u64 -B0: - 0: LdU64(1) - 1: StLoc[0](v: u64) - 2: MutBorrowLoc[0](v: u64) - 3: Call mod1(&mut u64) - 4: CopyLoc[0](v: u64) - 5: StLoc[1]($t: u64) - 6: MoveLoc[0](v: u64) - 7: MoveLoc[1]($t: u64) - 8: Add - 9: Ret -} -public test3(): u64 /* def_idx: 5 */ { -L0: v: u64 -L1: $t: u64 -B0: - 0: LdU64(1) - 1: StLoc[0](v: u64) - 2: MutBorrowLoc[0](v: u64) - 3: Call mod2(&mut u64): u64 - 4: StLoc[1]($t: u64) - 5: MoveLoc[0](v: u64) - 6: MoveLoc[1]($t: u64) - 7: Add - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/op-equal/invalid1.exp b/third_party/move/move-compiler-v2/tests/op-equal/invalid1.exp index 2506add81db..6269dd71442 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/invalid1.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/invalid1.exp @@ -29,13 +29,13 @@ module 0x42::test { let x = 42; let p = &mut x; { - let $t = 1; - x = x + $t + let _t = 1; + x = x + _t }; { - let $t2 = 1; - let $t1 = p; - *$t1 = *$t1 + $t2 + let _t2 = 1; + let _t1 = p; + *_t1 = *_t1 + _t2 }; x; } diff --git a/third_party/move/move-compiler-v2/tests/op-equal/invalid6.exp b/third_party/move/move-compiler-v2/tests/op-equal/invalid6.exp index 2cfb64f5b67..62b077477f3 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/invalid6.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/invalid6.exp @@ -20,9 +20,9 @@ module 0x42::test { module 0x42::test { fun inc_new(x: &u256) { { - let $t2 = 1u256; - let $t1 = x; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = x; + *_t1 = *_t1 + _t2 }; } fun inc_old(x: &u256) { diff --git a/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp b/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp index 8c73a95ea7d..91846d30653 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/valid0.exp @@ -142,8 +142,8 @@ module 0x42::test { } fun add1_new(x: u256): u256 { { - let $t = 1u256; - x = x + $t + let _t = 1u256; + x = x + _t }; x } @@ -153,9 +153,9 @@ module 0x42::test { } fun coin_inc_new_1(self: &mut Coin) { { - let $t2 = 1u256; - let $t1 = &mut self.0; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = &mut self.0; + *_t1 = *_t1 + _t2 }; } fun coin_inc_new_2(self: &mut Coin) { @@ -174,16 +174,16 @@ module 0x42::test { { let coin = borrow_global_mut(addr); { - let $t2 = 1u256; - let $t1 = &mut coin.0; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = &mut coin.0; + *_t1 = *_t1 + _t2 }; } fun inc_new(x: &mut u256) { { - let $t2 = 1u256; - let $t1 = x; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = x; + *_t1 = *_t1 + _t2 }; } fun inc_old(x: &mut u256) { @@ -191,9 +191,9 @@ module 0x42::test { } fun inc_vec_coin_new(x: vector, index: u64) { { - let $t2 = 1u256; - let $t1 = &mut 0x1::vector::borrow_mut(&mut x, index).0; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = &mut 0x1::vector::borrow_mut(&mut x, index).0; + *_t1 = *_t1 + _t2 }; } fun inc_vec_coin_old(x: vector, index: u64) { @@ -201,9 +201,9 @@ module 0x42::test { } fun inc_vec_new(x: &mut vector, index: u64) { { - let $t2 = 1u256; - let $t1 = 0x1::vector::borrow_mut(x, index); - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = 0x1::vector::borrow_mut(x, index); + *_t1 = *_t1 + _t2 }; } fun inc_vec_old(x: vector, index: u64) { @@ -211,9 +211,9 @@ module 0x42::test { } fun inc_vec_wrapped_coin_new(x: vector>, index: u64) { { - let $t2 = 1u256; - let $t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; + *_t1 = *_t1 + _t2 }; } fun inc_vec_wrapped_coin_old(x: vector>, index: u64) { @@ -221,9 +221,9 @@ module 0x42::test { } fun inc_wrapped_coin_new(x: &mut Wrapper) { { - let $t2 = 1u256; - let $t1 = &mut x.0.0; - *$t1 = *$t1 + $t2 + let _t2 = 1u256; + let _t1 = &mut x.0.0; + *_t1 = *_t1 + _t2 }; } fun inc_wrapped_coin_old(x: &mut Wrapper) { @@ -2553,242 +2553,265 @@ fun test::inc_wrapped_coin_old($t0: &mut 0x42::test::Wrapper<0x42::test::Coin>) ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -struct Coin has drop, key { - _0: u256 -} -struct Wrapper has drop, key { - _0: T -} - -add1_new(x: u256): u256 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u256) - 1: LdU256(1) - 2: Add - 3: Ret -} -add1_old(x: u256): u256 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u256) - 1: LdU256(1) - 2: Add - 3: Ret -} -coin_inc_new_1(self: &mut Coin) /* def_idx: 2 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](self: &mut Coin) - 1: MutBorrowField[0](Coin._0: u256) - 2: StLoc[1]($t1: &mut u256) - 3: CopyLoc[1]($t1: &mut u256) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MoveLoc[1]($t1: &mut u256) - 8: WriteRef - 9: Ret -} -coin_inc_new_2(self: &mut Coin) /* def_idx: 3 */ { -L1: p: &mut u256 -B0: - 0: MoveLoc[0](self: &mut Coin) - 1: MutBorrowField[0](Coin._0: u256) - 2: StLoc[1](p: &mut u256) - 3: CopyLoc[1](p: &mut u256) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MoveLoc[1](p: &mut u256) - 8: WriteRef - 9: Ret -} -coin_inc_old_1(self: &mut Coin) /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](self: &mut Coin) - 1: ImmBorrowField[0](Coin._0: u256) - 2: ReadRef - 3: LdU256(1) - 4: Add - 5: MoveLoc[0](self: &mut Coin) - 6: MutBorrowField[0](Coin._0: u256) - 7: WriteRef - 8: Ret -} -coin_inc_old_2(self: &mut Coin) /* def_idx: 5 */ { -L1: p: &mut u256 -B0: - 0: MoveLoc[0](self: &mut Coin) - 1: MutBorrowField[0](Coin._0: u256) - 2: StLoc[1](p: &mut u256) - 3: CopyLoc[1](p: &mut u256) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MoveLoc[1](p: &mut u256) - 8: WriteRef - 9: Ret -} -inc_coin_at(addr: address) /* def_idx: 6 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](addr: address) - 1: MutBorrowGlobal[0](Coin) - 2: MutBorrowField[0](Coin._0: u256) - 3: StLoc[1]($t1: &mut u256) - 4: CopyLoc[1]($t1: &mut u256) - 5: ReadRef - 6: LdU256(1) - 7: Add - 8: MoveLoc[1]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -inc_new(x: &mut u256) /* def_idx: 7 */ { -B0: - 0: CopyLoc[0](x: &mut u256) - 1: ReadRef - 2: LdU256(1) - 3: Add - 4: MoveLoc[0](x: &mut u256) - 5: WriteRef - 6: Ret -} -inc_old(x: &mut u256) /* def_idx: 8 */ { -B0: - 0: CopyLoc[0](x: &mut u256) - 1: ReadRef - 2: LdU256(1) - 3: Add - 4: MoveLoc[0](x: &mut u256) - 5: WriteRef - 6: Ret -} -inc_vec_coin_new(x: vector, index: u64) /* def_idx: 9 */ { -L2: $t1: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(6) - 3: MutBorrowField[0](Coin._0: u256) - 4: StLoc[2]($t1: &mut u256) - 5: CopyLoc[2]($t1: &mut u256) - 6: ReadRef - 7: LdU256(1) - 8: Add - 9: MoveLoc[2]($t1: &mut u256) - 10: WriteRef - 11: Ret -} -inc_vec_coin_old(x: vector, index: u64) /* def_idx: 10 */ { -B0: - 0: ImmBorrowLoc[0](x: vector) - 1: CopyLoc[1](index: u64) - 2: VecImmBorrow(6) - 3: ImmBorrowField[0](Coin._0: u256) - 4: ReadRef - 5: LdU256(1) - 6: Add - 7: MutBorrowLoc[0](x: vector) - 8: MoveLoc[1](index: u64) - 9: VecMutBorrow(6) - 10: MutBorrowField[0](Coin._0: u256) - 11: WriteRef - 12: Ret -} -inc_vec_new(x: &mut vector, index: u64) /* def_idx: 11 */ { -L2: $t1: &mut u256 -B0: - 0: MoveLoc[0](x: &mut vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(0) - 3: StLoc[2]($t1: &mut u256) - 4: CopyLoc[2]($t1: &mut u256) - 5: ReadRef - 6: LdU256(1) - 7: Add - 8: MoveLoc[2]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -inc_vec_old(x: vector, index: u64) /* def_idx: 12 */ { -B0: - 0: ImmBorrowLoc[0](x: vector) - 1: CopyLoc[1](index: u64) - 2: VecImmBorrow(0) - 3: ReadRef - 4: LdU256(1) - 5: Add - 6: MutBorrowLoc[0](x: vector) - 7: MoveLoc[1](index: u64) - 8: VecMutBorrow(0) - 9: WriteRef - 10: Ret -} -inc_vec_wrapped_coin_new(x: vector>, index: u64) /* def_idx: 13 */ { -L2: $t1: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector>) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(10) - 3: MutBorrowFieldGeneric[0](Wrapper._0: T) - 4: MutBorrowField[0](Coin._0: u256) - 5: StLoc[2]($t1: &mut u256) - 6: CopyLoc[2]($t1: &mut u256) - 7: ReadRef - 8: LdU256(1) - 9: Add - 10: MoveLoc[2]($t1: &mut u256) - 11: WriteRef - 12: Ret -} -inc_vec_wrapped_coin_old(x: vector>, index: u64) /* def_idx: 14 */ { -B0: - 0: ImmBorrowLoc[0](x: vector>) - 1: CopyLoc[1](index: u64) - 2: VecImmBorrow(10) - 3: ImmBorrowFieldGeneric[0](Wrapper._0: T) - 4: ImmBorrowField[0](Coin._0: u256) - 5: ReadRef - 6: LdU256(1) - 7: Add - 8: MutBorrowLoc[0](x: vector>) - 9: MoveLoc[1](index: u64) - 10: VecMutBorrow(10) - 11: MutBorrowFieldGeneric[0](Wrapper._0: T) - 12: MutBorrowField[0](Coin._0: u256) - 13: WriteRef - 14: Ret -} -inc_wrapped_coin_new(x: &mut Wrapper) /* def_idx: 15 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](x: &mut Wrapper) - 1: MutBorrowFieldGeneric[0](Wrapper._0: T) - 2: MutBorrowField[0](Coin._0: u256) - 3: StLoc[1]($t1: &mut u256) - 4: CopyLoc[1]($t1: &mut u256) - 5: ReadRef - 6: LdU256(1) - 7: Add - 8: MoveLoc[1]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -inc_wrapped_coin_old(x: &mut Wrapper) /* def_idx: 16 */ { -B0: - 0: CopyLoc[0](x: &mut Wrapper) - 1: ImmBorrowFieldGeneric[0](Wrapper._0: T) - 2: ImmBorrowField[0](Coin._0: u256) - 3: ReadRef - 4: LdU256(1) - 5: Add - 6: MoveLoc[0](x: &mut Wrapper) - 7: MutBorrowFieldGeneric[0](Wrapper._0: T) - 8: MutBorrowField[0](Coin._0: u256) - 9: WriteRef - 10: Ret -} -} +// Bytecode version v9 +module 0x42::test +struct Coin has drop + key + _0: u256 + +struct Wrapper has drop + key + _0: T0 + +// Function definition at index 0 +fun add1_new(l0: u256): u256 + move_loc l0 + ld_u256 1 + add + ret + +// Function definition at index 1 +fun add1_old(l0: u256): u256 + move_loc l0 + ld_u256 1 + add + ret + +// Function definition at index 2 +fun coin_inc_new_1(l0: &mut Coin) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u256 1 + add + move_loc l1 + write_ref + ret + +// Function definition at index 3 +fun coin_inc_new_2(l0: &mut Coin) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u256 1 + add + move_loc l1 + write_ref + ret + +// Function definition at index 4 +fun coin_inc_old_1(l0: &mut Coin) + copy_loc l0 + borrow_field Coin, _0 + read_ref + ld_u256 1 + add + // @5 + move_loc l0 + mut_borrow_field Coin, _0 + write_ref + ret + +// Function definition at index 5 +fun coin_inc_old_2(l0: &mut Coin) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u256 1 + add + move_loc l1 + write_ref + ret + +// Function definition at index 6 +fun inc_coin_at(l0: address) acquires Coin + local l1: &mut u256 + move_loc l0 + mut_borrow_global Coin + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + // @5 + read_ref + ld_u256 1 + add + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 7 +fun inc_new(l0: &mut u256) + copy_loc l0 + read_ref + ld_u256 1 + add + move_loc l0 + // @5 + write_ref + ret + +// Function definition at index 8 +fun inc_old(l0: &mut u256) + copy_loc l0 + read_ref + ld_u256 1 + add + move_loc l0 + // @5 + write_ref + ret + +// Function definition at index 9 +fun inc_vec_coin_new(l0: vector, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + st_loc l2 + // @5 + copy_loc l2 + read_ref + ld_u256 1 + add + move_loc l2 + // @10 + write_ref + ret + +// Function definition at index 10 +fun inc_vec_coin_old(l0: vector, l1: u64) + borrow_loc l0 + copy_loc l1 + vec_borrow + borrow_field Coin, _0 + read_ref + // @5 + ld_u256 1 + add + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + // @10 + mut_borrow_field Coin, _0 + write_ref + ret + +// Function definition at index 11 +fun inc_vec_new(l0: &mut vector, l1: u64) + local l2: &mut u256 + move_loc l0 + move_loc l1 + vec_mut_borrow + st_loc l2 + copy_loc l2 + // @5 + read_ref + ld_u256 1 + add + move_loc l2 + write_ref + // @10 + ret + +// Function definition at index 12 +fun inc_vec_old(l0: vector, l1: u64) + borrow_loc l0 + copy_loc l1 + vec_borrow + read_ref + ld_u256 1 + // @5 + add + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + write_ref + // @10 + ret + +// Function definition at index 13 +fun inc_vec_wrapped_coin_new(l0: vector>, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow > + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + // @5 + st_loc l2 + copy_loc l2 + read_ref + ld_u256 1 + add + // @10 + move_loc l2 + write_ref + ret + +// Function definition at index 14 +fun inc_vec_wrapped_coin_old(l0: vector>, l1: u64) + borrow_loc l0 + copy_loc l1 + vec_borrow > + borrow_field Wrapper, _0 + borrow_field Coin, _0 + // @5 + read_ref + ld_u256 1 + add + mut_borrow_loc l0 + move_loc l1 + // @10 + vec_mut_borrow > + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + write_ref + ret + +// Function definition at index 15 +fun inc_wrapped_coin_new(l0: &mut Wrapper) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + // @5 + read_ref + ld_u256 1 + add + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 16 +fun inc_wrapped_coin_old(l0: &mut Wrapper) + copy_loc l0 + borrow_field Wrapper, _0 + borrow_field Coin, _0 + read_ref + ld_u256 1 + // @5 + add + move_loc l0 + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + write_ref + // @10 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp b/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp index 068abdac2a5..14cf005f34c 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/valid1.exp @@ -113,44 +113,44 @@ module 0x42::test { } fun bitand_vec_coin_new(x: vector, index: u64) { { - let $t2 = 42u256; - let $t1 = &mut 0x1::vector::borrow_mut(&mut x, index).0; - *$t1 = *$t1 & $t2 + let _t2 = 42u256; + let _t1 = &mut 0x1::vector::borrow_mut(&mut x, index).0; + *_t1 = *_t1 & _t2 }; } fun bitor_vec_new(x: &mut vector, index: u64) { { - let $t2 = 42u256; - let $t1 = 0x1::vector::borrow_mut(x, index); - *$t1 = *$t1 | $t2 + let _t2 = 42u256; + let _t1 = 0x1::vector::borrow_mut(x, index); + *_t1 = *_t1 | _t2 }; } fun coin_double(self: &mut Coin) { { - let $t2 = 2u256; - let $t1 = &mut self.0; - *$t1 = *$t1 * $t2 + let _t2 = 2u256; + let _t1 = &mut self.0; + *_t1 = *_t1 * _t2 }; } fun coin_mod_2(self: &mut Coin) { { - let $t2 = 2u256; - let $t1 = &mut self.0; - *$t1 = *$t1 % $t2 + let _t2 = 2u256; + let _t1 = &mut self.0; + *_t1 = *_t1 % _t2 }; } fun half_wrapped_coin_new(x: &mut Wrapper) { { - let $t2 = 2u256; - let $t1 = &mut x.0.0; - *$t1 = *$t1 / $t2 + let _t2 = 2u256; + let _t1 = &mut x.0.0; + *_t1 = *_t1 / _t2 }; } fun shl_vec_wrapped_coin_old(x: vector>, index: u64) { { - let $t2 = 1u8; - let $t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; - *$t1 = *$t1 << $t2 + let _t2 = 1u8; + let _t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; + *_t1 = *_t1 << _t2 }; } fun shr_coin_at(addr: address) @@ -158,23 +158,23 @@ module 0x42::test { { let coin = borrow_global_mut(addr); { - let $t2 = 1u8; - let $t1 = &mut coin.0; - *$t1 = *$t1 >> $t2 + let _t2 = 1u8; + let _t1 = &mut coin.0; + *_t1 = *_t1 >> _t2 }; } fun sub1(x: &mut u256) { { - let $t2 = 1u256; - let $t1 = x; - *$t1 = *$t1 - $t2 + let _t2 = 1u256; + let _t1 = x; + *_t1 = *_t1 - _t2 }; } fun xor_vec_wrapped_coin_new(x: vector>, index: u64) { { - let $t2 = 1u256; - let $t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; - *$t1 = *$t1 ^ $t2 + let _t2 = 1u256; + let _t1 = &mut 0x1::vector::borrow_mut>(&mut x, index).0.0; + *_t1 = *_t1 ^ _t2 }; } } @@ -1412,147 +1412,161 @@ fun test::xor_vec_wrapped_coin_new($t0: vector<0x42::test::Wrapper<0x42::test::C ============ disassembled file-format ================== -// Move bytecode v8 -module 42.test { -struct Coin has drop, key { - _0: u256 -} -struct Wrapper has drop, key { - _0: T -} +// Bytecode version v9 +module 0x42::test +struct Coin has drop + key + _0: u256 + +struct Wrapper has drop + key + _0: T0 + +// Function definition at index 0 +fun bitand_vec_coin_new(l0: vector, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow + mut_borrow_field Coin, _0 + st_loc l2 + // @5 + copy_loc l2 + read_ref + ld_u256 42 + bit_and + move_loc l2 + // @10 + write_ref + ret + +// Function definition at index 1 +fun bitor_vec_new(l0: &mut vector, l1: u64) + local l2: &mut u256 + move_loc l0 + move_loc l1 + vec_mut_borrow + st_loc l2 + copy_loc l2 + // @5 + read_ref + ld_u256 42 + bit_or + move_loc l2 + write_ref + // @10 + ret + +// Function definition at index 2 +fun coin_double(l0: &mut Coin) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u256 2 + mul + move_loc l1 + write_ref + ret + +// Function definition at index 3 +fun coin_mod_2(l0: &mut Coin) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u256 2 + mod + move_loc l1 + write_ref + ret + +// Function definition at index 4 +fun half_wrapped_coin_new(l0: &mut Wrapper) + local l1: &mut u256 + move_loc l0 + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + // @5 + read_ref + ld_u256 2 + div + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 5 +fun shl_vec_wrapped_coin_old(l0: vector>, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow > + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + // @5 + st_loc l2 + copy_loc l2 + read_ref + ld_u8 1 + shl + // @10 + move_loc l2 + write_ref + ret + +// Function definition at index 6 +fun shr_coin_at(l0: address) acquires Coin + local l1: &mut u256 + move_loc l0 + mut_borrow_global Coin + mut_borrow_field Coin, _0 + st_loc l1 + copy_loc l1 + // @5 + read_ref + ld_u8 1 + shr + move_loc l1 + write_ref + // @10 + ret + +// Function definition at index 7 +fun sub1(l0: &mut u256) + copy_loc l0 + read_ref + ld_u256 1 + sub + move_loc l0 + // @5 + write_ref + ret + +// Function definition at index 8 +fun xor_vec_wrapped_coin_new(l0: vector>, l1: u64) + local l2: &mut u256 + mut_borrow_loc l0 + move_loc l1 + vec_mut_borrow > + mut_borrow_field Wrapper, _0 + mut_borrow_field Coin, _0 + // @5 + st_loc l2 + copy_loc l2 + read_ref + ld_u256 1 + xor + // @10 + move_loc l2 + write_ref + ret + -bitand_vec_coin_new(x: vector, index: u64) /* def_idx: 0 */ { -L2: $t1: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(2) - 3: MutBorrowField[0](Coin._0: u256) - 4: StLoc[2]($t1: &mut u256) - 5: CopyLoc[2]($t1: &mut u256) - 6: ReadRef - 7: LdU256(42) - 8: BitAnd - 9: MoveLoc[2]($t1: &mut u256) - 10: WriteRef - 11: Ret -} -bitor_vec_new(x: &mut vector, index: u64) /* def_idx: 1 */ { -L2: $t1: &mut u256 -B0: - 0: MoveLoc[0](x: &mut vector) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(5) - 3: StLoc[2]($t1: &mut u256) - 4: CopyLoc[2]($t1: &mut u256) - 5: ReadRef - 6: LdU256(42) - 7: BitOr - 8: MoveLoc[2]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -coin_double(self: &mut Coin) /* def_idx: 2 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](self: &mut Coin) - 1: MutBorrowField[0](Coin._0: u256) - 2: StLoc[1]($t1: &mut u256) - 3: CopyLoc[1]($t1: &mut u256) - 4: ReadRef - 5: LdU256(2) - 6: Mul - 7: MoveLoc[1]($t1: &mut u256) - 8: WriteRef - 9: Ret -} -coin_mod_2(self: &mut Coin) /* def_idx: 3 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](self: &mut Coin) - 1: MutBorrowField[0](Coin._0: u256) - 2: StLoc[1]($t1: &mut u256) - 3: CopyLoc[1]($t1: &mut u256) - 4: ReadRef - 5: LdU256(2) - 6: Mod - 7: MoveLoc[1]($t1: &mut u256) - 8: WriteRef - 9: Ret -} -half_wrapped_coin_new(x: &mut Wrapper) /* def_idx: 4 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](x: &mut Wrapper) - 1: MutBorrowFieldGeneric[0](Wrapper._0: T) - 2: MutBorrowField[0](Coin._0: u256) - 3: StLoc[1]($t1: &mut u256) - 4: CopyLoc[1]($t1: &mut u256) - 5: ReadRef - 6: LdU256(2) - 7: Div - 8: MoveLoc[1]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -shl_vec_wrapped_coin_old(x: vector>, index: u64) /* def_idx: 5 */ { -L2: $t1: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector>) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(9) - 3: MutBorrowFieldGeneric[0](Wrapper._0: T) - 4: MutBorrowField[0](Coin._0: u256) - 5: StLoc[2]($t1: &mut u256) - 6: CopyLoc[2]($t1: &mut u256) - 7: ReadRef - 8: LdU8(1) - 9: Shl - 10: MoveLoc[2]($t1: &mut u256) - 11: WriteRef - 12: Ret -} -shr_coin_at(addr: address) /* def_idx: 6 */ { -L1: $t1: &mut u256 -B0: - 0: MoveLoc[0](addr: address) - 1: MutBorrowGlobal[0](Coin) - 2: MutBorrowField[0](Coin._0: u256) - 3: StLoc[1]($t1: &mut u256) - 4: CopyLoc[1]($t1: &mut u256) - 5: ReadRef - 6: LdU8(1) - 7: Shr - 8: MoveLoc[1]($t1: &mut u256) - 9: WriteRef - 10: Ret -} -sub1(x: &mut u256) /* def_idx: 7 */ { -B0: - 0: CopyLoc[0](x: &mut u256) - 1: ReadRef - 2: LdU256(1) - 3: Sub - 4: MoveLoc[0](x: &mut u256) - 5: WriteRef - 6: Ret -} -xor_vec_wrapped_coin_new(x: vector>, index: u64) /* def_idx: 8 */ { -L2: $t1: &mut u256 -B0: - 0: MutBorrowLoc[0](x: vector>) - 1: MoveLoc[1](index: u64) - 2: VecMutBorrow(9) - 3: MutBorrowFieldGeneric[0](Wrapper._0: T) - 4: MutBorrowField[0](Coin._0: u256) - 5: StLoc[2]($t1: &mut u256) - 6: CopyLoc[2]($t1: &mut u256) - 7: ReadRef - 8: LdU256(1) - 9: Xor - 10: MoveLoc[2]($t1: &mut u256) - 11: WriteRef - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/op-equal/valid2.exp b/third_party/move/move-compiler-v2/tests/op-equal/valid2.exp index 376437dfccf..cffbea0efe5 100644 --- a/third_party/move/move-compiler-v2/tests/op-equal/valid2.exp +++ b/third_party/move/move-compiler-v2/tests/op-equal/valid2.exp @@ -35,18 +35,18 @@ module 0xc0ffee::m { } fun foo(self: &mut S): u64 { { - let $t2 = 1; - let $t1 = &mut self.x; - *$t1 = *$t1 + $t2 + let _t2 = 1; + let _t1 = &mut self.x; + *_t1 = *_t1 + _t2 }; 1 } public fun test(): u64 { let s = S{x: 0}; { - let $t2 = foo(&mut s); - let $t1 = &mut s.x; - *$t1 = *$t1 + $t2 + let _t2 = foo(&mut s); + let _t1 = &mut s.x; + *_t1 = *_t1 + _t2 }; s.x } @@ -417,51 +417,55 @@ public fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has drop { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has drop + x: u64 + +// Function definition at index 0 +fun foo(l0: &mut S): u64 + local l1: &mut u64 + move_loc l0 + mut_borrow_field S, x + st_loc l1 + copy_loc l1 + read_ref + // @5 + ld_u64 1 + add + move_loc l1 + write_ref + ld_u64 1 + // @10 + ret + +// Function definition at index 1 +#[persistent] public fun test(): u64 + local l0: S + local l1: u64 + local l2: &mut u64 + ld_u64 0 + pack S + st_loc l0 + mut_borrow_loc l0 + call foo + // @5 + st_loc l1 + mut_borrow_loc l0 + mut_borrow_field S, x + st_loc l2 + copy_loc l2 + // @10 + read_ref + move_loc l1 + add + move_loc l2 + write_ref + // @15 + borrow_loc l0 + borrow_field S, x + read_ref + ret + -foo(self: &mut S): u64 /* def_idx: 0 */ { -L1: $t1: &mut u64 -B0: - 0: MoveLoc[0](self: &mut S) - 1: MutBorrowField[0](S.x: u64) - 2: StLoc[1]($t1: &mut u64) - 3: CopyLoc[1]($t1: &mut u64) - 4: ReadRef - 5: LdU64(1) - 6: Add - 7: MoveLoc[1]($t1: &mut u64) - 8: WriteRef - 9: LdU64(1) - 10: Ret -} -public test(): u64 /* def_idx: 1 */ { -L0: s: S -L1: $t2: u64 -L2: $t1: &mut u64 -B0: - 0: LdU64(0) - 1: Pack[0](S) - 2: StLoc[0](s: S) - 3: MutBorrowLoc[0](s: S) - 4: Call foo(&mut S): u64 - 5: StLoc[1]($t2: u64) - 6: MutBorrowLoc[0](s: S) - 7: MutBorrowField[0](S.x: u64) - 8: StLoc[2]($t1: &mut u64) - 9: CopyLoc[2]($t1: &mut u64) - 10: ReadRef - 11: MoveLoc[1]($t2: u64) - 12: Add - 13: MoveLoc[2]($t1: &mut u64) - 14: WriteRef - 15: ImmBorrowLoc[0](s: S) - 16: ImmBorrowField[0](S.x: u64) - 17: ReadRef - 18: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp new file mode 100644 index 00000000000..5478c305eb1 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.exp @@ -0,0 +1,103 @@ +// -- Model dump before first bytecode pipeline +module 0x8675309::M1 { + struct R { + x: u64, + } + public fun extract(r: &mut R,y: u64): R { + { + let x: u64 = Sub(select M1::R.x<&mut R>(r), y); + pack M1::R(x) + } + } +} // end 0x8675309::M1 +module 0x8675309::M { + use 0x8675309::M1::{R}; // resolved as: 0x8675309::M1 + use 0x8675309::M1::{extract}; // resolved as: 0x8675309::M1 + struct R1 { + x: M1::R, + } + private fun f(a: address): M1::R { + { + let r: &mut R1 = BorrowGlobal(Mutable)>(a); + M1::extract(Borrow(Mutable)(select M::R1.x<&mut R1>(r)), 3) + } + } + public fun t0(a: address): M1::R { + if false { + Tuple() + } else { + Abort(0) + }; + M::f(a) + } +} // end 0x8675309::M + +// -- Sourcified model before first bytecode pipeline +module 0x8675309::M1 { + struct R has copy, drop, store, key { + x: u64, + } + public fun extract(r: &mut R, y: u64): R { + let x = r.x - y; + R{x: x} + } +} +module 0x8675309::M { + use 0x8675309::M1; + use 0x8675309::M1; + struct R1 has key { + x: M1::R, + } + fun f(a: address): M1::R { + let r = borrow_global_mut>(a); + M1::extract(&mut r.x, 3) + } + public fun t0(a: address): M1::R { + if (false) () else abort 0; + f(a) + } +} + + +Diagnostics: +warning: If condition is always false, so then branch code eliminated as dead code + ┌─ tests/simplifier-elimination/assert_false_with_resource.move:30:17 + │ +30 │ assert!(false, 0); + │ ------ ^^^^^ + │ │ │ + │ │ condition is always false + │ then branch eliminated + +// -- Model dump before second bytecode pipeline +module 0x8675309::M1 { + struct R { + x: u64, + } + public fun extract(r: &mut R,y: u64): R { + { + let x: u64 = Sub(select M1::R.x<&mut R>(r), y); + pack M1::R(x) + } + } +} // end 0x8675309::M1 +module 0x8675309::M { + use 0x8675309::M1::{R}; // resolved as: 0x8675309::M1 + use 0x8675309::M1::{extract}; // resolved as: 0x8675309::M1 + struct R1 { + x: M1::R, + } + private fun f(a: address): M1::R { + { + let r: &mut R1 = BorrowGlobal(Mutable)>(a); + M1::extract(Borrow(Mutable)(select M::R1.x<&mut R1>(r)), 3) + } + } + public fun t0(a: address): M1::R { + Abort(0); + M::f(a) + } +} // end 0x8675309::M + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.move b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.move new file mode 100644 index 00000000000..37f125b56fc --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assert_false_with_resource.move @@ -0,0 +1,34 @@ +module 0x8675309::M1 { + + + struct R has key, store, copy, drop { + x: u64 + } + + public fun extract(r: &mut R, y: u64): R { + let x = r.x - y; + R {x} + } + +} + +module 0x8675309::M { + use 0x8675309::M1::R; + use 0x8675309::M1::extract; + + struct R1 has key { + x: R + } + + + fun f(a: address): R { + let r = borrow_global_mut>(a); + extract(&mut r.x, 3) + } + + public fun t0(a: address): R { + assert!(false, 0); + f(a) + } + +} diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assign_unpack_references.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assign_unpack_references.exp index 00720ce9a81..ecb881503fa 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/assign_unpack_references.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/assign_unpack_references.exp @@ -69,7 +69,7 @@ module 0x8675309::M { fun t0() { let f; let s2; - R{s1: S{f: f},s2: s2} = R{s1: S{f: 0},s2: S{f: 1}}; + R{s1: S{f: f}, s2: s2} = R{s1: S{f: 0}, s2: S{f: 1}}; f; s2; f = 0; @@ -80,7 +80,7 @@ module 0x8675309::M { fun t1() { let f; let s2; - R{s1: S{f: f},s2: s2} = &R{s1: S{f: 0},s2: S{f: 1}}; + R{s1: S{f: f}, s2: s2} = &R{s1: S{f: 0}, s2: S{f: 1}}; f; s2; f = &0; @@ -91,7 +91,7 @@ module 0x8675309::M { fun t2() { let f; let s2; - R{s1: S{f: f},s2: s2} = &mut R{s1: S{f: 0},s2: S{f: 1}}; + R{s1: S{f: f}, s2: s2} = &mut R{s1: S{f: 0}, s2: S{f: 1}}; f; s2; f = &mut 0; diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/constant_all_valid_types.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/constant_all_valid_types.exp index 99b0292597f..b579e9f2505 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/constant_all_valid_types.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/constant_all_valid_types.exp @@ -50,7 +50,7 @@ module 0x42::M { false } fun t5(): address { - 0x0 + @0x0 } fun t6(): vector { vector[1u8, 35u8] @@ -65,7 +65,7 @@ script { 0; 0u128; false; - 0x0; + @0x0; vector[1u8, 35u8]; vector[97u8, 98u8, 99u8, 100u8]; } diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/double_nesting.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/double_nesting.exp index b02f941cc54..0d9ecca305e 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/double_nesting.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/double_nesting.exp @@ -46,12 +46,12 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::mathtest { public inline fun fun1(a: u64, b: u64, c: u64): u64 { - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 } } module 0x42::mathtest2 { public inline fun fun2(a: u64, b: u64, c: u64): u64 { - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 } } module 0x42::test { @@ -62,20 +62,20 @@ module 0x42::test { let (a,b,c) = (2, { let (a,b,c) = (3, { let (a,b,c) = (4, 5, 6); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }, 7); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }, { let (a,b,c) = (8, 9, { let (a,b,c) = (10, { let (a,b,c) = (11, 12, 13); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }, 14); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }); - 7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128) as u64 + (7u128 * (a as u128) + 11u128 * (b as u128) + 13u128 * (c as u128)) as u64 }); - 2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128) as u64 + (2u128 * (a as u128) + 3u128 * (b as u128) + 5u128 * (c as u128)) as u64 }; if (a == 81911) () else abort 0; } diff --git a/third_party/move/move-compiler-v2/tests/simplifier-elimination/recursive_nesting.exp b/third_party/move/move-compiler-v2/tests/simplifier-elimination/recursive_nesting.exp index e73e07cb99d..2928695eb63 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier-elimination/recursive_nesting.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier-elimination/recursive_nesting.exp @@ -66,14 +66,14 @@ module 0x42::test { // -- Sourcified model before first bytecode pipeline module 0x42::mathtest { public inline fun mul_div(a: u64, b: u64, c: u64): u64 { - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::mathtest2 { use 0x42::mathtest; public inline fun mul_div2(a: u64, b: u64, c: u64): u64 { let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::mathtest3 { @@ -81,7 +81,7 @@ module 0x42::mathtest3 { public inline fun mul_div3(a: u64, b: u64, c: u64): u64 { let (a,b,c) = (b, a, c); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 } } module 0x42::test { @@ -94,16 +94,16 @@ module 0x42::test { let (a,b,c) = (1, 1, 1); let (a,b,c) = (b, a, c); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }, { let (a,b,c) = (1, 1, 1); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }, { let (a,b,c) = (1, 1, 1); let (a,b,c) = (b, a, c); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }); - (a as u128) * (b as u128) / (c as u128) as u64 + ((a as u128) * (b as u128) / (c as u128)) as u64 }; if (a == 1) () else abort 0; } diff --git a/third_party/move/move-compiler-v2/tests/simplifier/bug_11112.exp b/third_party/move/move-compiler-v2/tests/simplifier/bug_11112.exp index cad81fe0934..45c6e779930 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier/bug_11112.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier/bug_11112.exp @@ -37,6 +37,7 @@ module 0xcafe::vectors { // -- Sourcified model before first bytecode pipeline module 0xcafe::vectors { + use std::vector; fun test_for_each_mut() { let v = vector[1, 2, 3]; let s = 2; diff --git a/third_party/move/move-compiler-v2/tests/simplifier/constant_folding_addresses.exp b/third_party/move/move-compiler-v2/tests/simplifier/constant_folding_addresses.exp index 6011379df41..5209d7047cc 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier/constant_folding_addresses.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier/constant_folding_addresses.exp @@ -16,8 +16,9 @@ module 0xcafe::Addresses { // -- Sourcified model before first bytecode pipeline module 0xcafe::Addresses { + use std::vector; public fun test() { - let addresses = vector[0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234]; + let addresses = vector[@0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234, @0x1234]; if (0x1::vector::length
(&addresses) == 1845) () else abort 1; } } diff --git a/third_party/move/move-compiler-v2/tests/simplifier/match.exp b/third_party/move/move-compiler-v2/tests/simplifier/match.exp new file mode 100644 index 00000000000..87e7da1e6dc --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/simplifier/match.exp @@ -0,0 +1,61 @@ +// -- Model dump before first bytecode pipeline +module 0x66::m { + enum E { + A { + 0: u64, + } + B, + C { + 0: bool, + } + } + private fun variant_test(e: &E): bool { + match (e) { + m::E::A{ 0: _ } => { + true + } + _: &E => { + false + } + } + + } +} // end 0x66::m + +// -- Sourcified model before first bytecode pipeline +module 0x66::m { + enum E { + A { + 0: u64, + } + B, + C { + 0: bool, + } + } + fun variant_test(e: &E): bool { + match (e) { + E::A(_) => true, + _ => false, + } + } +} + +// -- Model dump before second bytecode pipeline +module 0x66::m { + enum E { + A { + 0: u64, + } + B, + C { + 0: bool, + } + } + private fun variant_test(e: &E): bool { + test_variants m::E::A(e) + } +} // end 0x66::m + + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/simplifier/match.move b/third_party/move/move-compiler-v2/tests/simplifier/match.move new file mode 100644 index 00000000000..e0ed5c3d305 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/simplifier/match.move @@ -0,0 +1,15 @@ +module 0x66::m { + + enum E { + A(u64), + B, + C(bool) + } + + fun variant_test(e: &E): bool { + match (e) { + A(_) => true, + _ => false + } + } +} diff --git a/third_party/move/move-compiler-v2/tests/simplifier/simplifier_test4.exp b/third_party/move/move-compiler-v2/tests/simplifier/simplifier_test4.exp index 3d540ae84a2..e5bd9203cd5 100644 --- a/third_party/move/move-compiler-v2/tests/simplifier/simplifier_test4.exp +++ b/third_party/move/move-compiler-v2/tests/simplifier/simplifier_test4.exp @@ -65,7 +65,7 @@ module 0x8675309::M { }; if (z == 1) { x = x + 1; - foo(/*freeze*/s, { + foo(freeze(s), { *{ x = x + 1; f diff --git a/third_party/move/move-compiler-v2/tests/testsuite.rs b/third_party/move/move-compiler-v2/tests/testsuite.rs index 5d462e71317..6d178306c34 100644 --- a/third_party/move/move-compiler-v2/tests/testsuite.rs +++ b/third_party/move/move-compiler-v2/tests/testsuite.rs @@ -214,12 +214,22 @@ const TEST_CONFIGS: Lazy> = Lazy::new(|| { // Tests for checking v2 language features only supported if 2.3 or later // is selected TestConfig { - name: "checking-lang-v2.3", - runner: |p| run_test(p, get_config_by_name("checking-lang-v2.3")), - include: vec!["/checking-lang-v2.3/"], + name: "checking-lang-v2.5", + runner: |p| run_test(p, get_config_by_name("checking-lang-v2.5")), + include: vec!["/checking-lang-v2.5/"], stop_after: StopAfter::FirstAstPipeline, dump_ast: DumpLevel::EndStage, - ..config().lang(LanguageVersion::V2_3) + ..config().lang(LanguageVersion::V2_5) + }, + TestConfig { + name: "checking-lang-v2.4", + runner: |p| run_test(p, get_config_by_name("checking-lang-v2.4")), + include: vec!["/checking-lang-v2.4/"], + stop_after: StopAfter::FileFormat, + dump_ast: DumpLevel::EndStage, + dump_bytecode: DumpLevel::EndStage, + dump_bytecode_filter: Some(vec![INITIAL_BYTECODE_STAGE, FILE_FORMAT_STAGE]), + ..config().lang(LanguageVersion::V2_4) }, TestConfig { name: "unused-assignment", @@ -251,6 +261,18 @@ const TEST_CONFIGS: Lazy> = Lazy::new(|| { dump_ast: DumpLevel::EndStage, ..config().exp(Experiment::AST_SIMPLIFY_FULL) }, + // Tests for inlining optimization + full AST simplifier + TestConfig { + name: "inlining-optimization", + runner: |p| run_test(p, get_config_by_name("inlining-optimization")), + include: vec!["/inlining-optimization/"], + dump_ast: DumpLevel::EndStage, + dump_bytecode: DumpLevel::EndStage, + dump_bytecode_filter: Some(vec![FILE_FORMAT_STAGE]), + ..config() + .exp(Experiment::INLINING_OPTIMIZATION) + .exp(Experiment::AST_SIMPLIFY_FULL) + }, // Tests for more-v1 tests TestConfig { name: "more-v1", @@ -580,6 +602,15 @@ const TEST_CONFIGS: Lazy> = Lazy::new(|| { stop_after: StopAfter::SecondAstPipeline, ..config().exp(Experiment::MESSAGE_FORMAT_JSON) }, + // Tests for integers + TestConfig { + name: "integers", + runner: |p| run_test(p, get_config_by_name("integers")), + include: vec!["integers"], + dump_ast: DumpLevel::EndStage, + dump_bytecode: DumpLevel::EndStage, + ..config().lang(LanguageVersion::V2_3) + }, ]; configs.into_iter().map(|c| (c.name, c)).collect() }); @@ -595,7 +626,7 @@ fn get_config_by_name(name: &str) -> TestConfig { /// Runs test at `path` with the given `config`. fn run_test(path: &Path, config: TestConfig) -> anyhow::Result<()> { - logging::setup_logging_for_testing(); + logging::setup_logging_for_testing(None); let path_str = path.display().to_string(); let mut options = config.options.clone(); options.warn_unused = path_str.contains("/unused/"); @@ -766,7 +797,7 @@ fn run_env_pipeline( ); if is_first_pipeline { // Print the sourcified model during the first env pipeline. - let sourcifier = Sourcifier::new(&*env); + let sourcifier = Sourcifier::new(&*env, true); for module in env.get_modules() { if module.is_primary_target() { sourcifier.print_module(module.get_id()) diff --git a/third_party/move/move-compiler-v2/tests/uninit-use-checker/assign_both_branch.exp b/third_party/move/move-compiler-v2/tests/uninit-use-checker/assign_both_branch.exp index c213a998512..03c299b894f 100644 --- a/third_party/move/move-compiler-v2/tests/uninit-use-checker/assign_both_branch.exp +++ b/third_party/move/move-compiler-v2/tests/uninit-use-checker/assign_both_branch.exp @@ -74,25 +74,21 @@ fun m::test($t0: bool): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool): u64 + local l1: u64 + move_loc l0 + br_false l0 + ld_u64 1 + st_loc l1 +l1: move_loc l1 + // @5 + ret +l0: ld_u64 2 + st_loc l1 + branch l1 -test(cond: bool): u64 /* def_idx: 0 */ { -L1: $t3: u64 -B0: - 0: MoveLoc[0](cond: bool) - 1: BrFalse(6) -B1: - 2: LdU64(1) - 3: StLoc[1]($t3: u64) -B2: - 4: MoveLoc[1]($t3: u64) - 5: Ret -B3: - 6: LdU64(2) - 7: StLoc[1]($t3: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/uninit-use-checker/no_error.exp b/third_party/move/move-compiler-v2/tests/uninit-use-checker/no_error.exp index 95e91b2ae37..d64c6dd2be6 100644 --- a/third_party/move/move-compiler-v2/tests/uninit-use-checker/no_error.exp +++ b/third_party/move/move-compiler-v2/tests/uninit-use-checker/no_error.exp @@ -85,20 +85,19 @@ fun m::foo($t0: u64, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0.m { +// Bytecode version v9 +module 0xc0::m +// Function definition at index 0 +fun foo(l0: u64, l1: u64): u64 + move_loc l0 + move_loc l1 + add + ld_u64 1 + add + // @5 + ld_u64 1 + add + ret -foo(p: u64, q: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: MoveLoc[1](q: u64) - 2: Add - 3: LdU64(1) - 4: Add - 5: LdU64(1) - 6: Add - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_only.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_only.exp index 1563acc4f11..68c0d368778 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_only.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_only.exp @@ -40,14 +40,12 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + ld_u64 0 + abort -test() /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_or_return_always.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_or_return_always.exp index 25f7083fc88..a11600a4fa8 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_or_return_always.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/abort_or_return_always.exp @@ -75,20 +75,17 @@ fun m::test($t0: bool): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool): u64 + move_loc l0 + br_false l0 + ld_u64 0 + abort +l0: ld_u64 1 + // @5 + ret -test(p: bool): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: bool) - 1: BrFalse(4) -B1: - 2: LdU64(0) - 3: Abort -B2: - 4: LdU64(1) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/always_false_branch.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/always_false_branch.exp index 1454503aea6..492cf5ece58 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/always_false_branch.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/always_false_branch.exp @@ -117,21 +117,18 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + branch l0 + ld_u64 0 + ld_u64 1 + add + ret + // @5 +l0: ld_u64 0 + ret -test(): u64 /* def_idx: 0 */ { -B0: - 0: Branch(5) -B1: - 1: LdU64(0) - 2: LdU64(1) - 3: Add - 4: Ret -B2: - 5: LdU64(0) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/break_unreachable.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/break_unreachable.exp index cac8f32bffc..784098bf67b 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/break_unreachable.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/break_unreachable.exp @@ -192,28 +192,25 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + local l0: u64 + ld_u64 0 + st_loc l0 +l1: move_loc l0 + ld_u64 1 + add + // @5 + st_loc l0 + copy_loc l0 + ld_u64 10 + eq + br_true l0 + // @10 + branch l1 +l0: ret -test() /* def_idx: 0 */ { -L0: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](i: u64) -B1: - 2: MoveLoc[0](i: u64) - 3: LdU64(1) - 4: Add - 5: StLoc[0](i: u64) - 6: CopyLoc[0](i: u64) - 7: LdU64(10) - 8: Eq - 9: BrTrue(11) -B2: - 10: Branch(2) -B3: - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/conditional_loop_unreachable.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/conditional_loop_unreachable.exp index d69d114c025..59eedb3a81c 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/conditional_loop_unreachable.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/conditional_loop_unreachable.exp @@ -111,31 +111,27 @@ fun m::test($t0: bool, $t1: bool) { var $t8: u64 [unused] var $t9: u64 [unused] # maybe - 0: if ($t0) goto 3 else goto 1 + 0: if ($t0) goto 1 else goto 9 # maybe - 1: label L9 + 1: label L2 # maybe - 2: goto 11 + 2: if ($t1) goto 3 else goto 7 # maybe - 3: label L2 + 3: label L9 # maybe - 4: if ($t1) goto 5 else goto 7 + 4: goto 5 # maybe - 5: label L10 - # maybe - 6: goto 9 - # maybe - 7: label L11 + 5: label L8 # maybe - 8: goto 11 + 6: goto 5 # maybe - 9: label L8 + 7: label L6 # maybe - 10: goto 9 + 8: return () # maybe - 11: label L1 + 9: label L3 # maybe - 12: return () + 10: return () } ============ after UnreachableCodeRemover: ================ @@ -150,44 +146,34 @@ fun m::test($t0: bool, $t1: bool) { var $t7: u64 [unused] var $t8: u64 [unused] var $t9: u64 [unused] - 0: if ($t0) goto 3 else goto 1 - 1: label L9 - 2: goto 11 - 3: label L2 - 4: if ($t1) goto 5 else goto 7 - 5: label L10 - 6: goto 9 - 7: label L11 - 8: goto 11 - 9: label L8 - 10: goto 9 - 11: label L1 - 12: return () + 0: if ($t0) goto 1 else goto 9 + 1: label L2 + 2: if ($t1) goto 3 else goto 7 + 3: label L9 + 4: goto 5 + 5: label L8 + 6: goto 5 + 7: label L6 + 8: return () + 9: label L3 + 10: return () } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool, l1: bool) + move_loc l0 + br_false l0 + move_loc l1 + br_false l1 + branch l2 + // @5 +l2: branch l2 +l1: ret +l0: ret -test(p: bool, q: bool) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: bool) - 1: BrTrue(3) -B1: - 2: Branch(8) -B2: - 3: MoveLoc[1](q: bool) - 4: BrFalse(6) -B3: - 5: Branch(7) -B4: - 6: Branch(8) -B5: - 7: Branch(7) -B6: - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/inter_procedural_abort.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/inter_procedural_abort.exp index c306849a9e7..c0ccaca79a0 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/inter_procedural_abort.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/inter_procedural_abort.exp @@ -120,22 +120,20 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun always_abort() + ld_u64 0 + abort + +// Function definition at index 1 +fun test(): u64 + call always_abort + ld_u64 0 + ld_u64 1 + add + ret -always_abort() /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -test(): u64 /* def_idx: 1 */ { -B0: - 0: Call always_abort() - 1: LdU64(0) - 2: LdU64(1) - 3: Add - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/loop_unreachable.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/loop_unreachable.exp index 6b76044364e..aeed34dfd2b 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/loop_unreachable.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/loop_unreachable.exp @@ -44,13 +44,11 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 +l0: branch l0 -test(): u64 /* def_idx: 0 */ { -B0: - 0: Branch(0) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/return_after_abort.exp b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/return_after_abort.exp index d7a1b785bdb..d5635d8c753 100644 --- a/third_party/move/move-compiler-v2/tests/unreachable-code-remover/return_after_abort.exp +++ b/third_party/move/move-compiler-v2/tests/unreachable-code-remover/return_after_abort.exp @@ -46,14 +46,12 @@ fun m::test(): u32 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u32 + ld_u64 0 + abort -test(): u32 /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/unused-assignment/bug-13880.move b/third_party/move/move-compiler-v2/tests/unused-assignment/bug-13880.move index 29ba6737506..6ed5327a7bd 100644 --- a/third_party/move/move-compiler-v2/tests/unused-assignment/bug-13880.move +++ b/third_party/move/move-compiler-v2/tests/unused-assignment/bug-13880.move @@ -73,7 +73,7 @@ module 0x42::object { inner: address, } - inline fun transfer_raw_inner(object: address, to: address, a1: bool) acquires ObjectCore { + inline fun transfer_raw_inner(object: address, to: address, a1: bool) { let object_core = borrow_global_mut(object); if (object_core.owner != to) { if (a1) { diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.exp index c0900ad546b..127c7cd4672 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.exp @@ -201,25 +201,24 @@ public fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun add(l0: u64, l1: u64): u64 + move_loc l0 + move_loc l1 + add + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: u64): u64 + copy_loc l0 + move_loc l0 + ld_u64 1 + add + call add + // @5 + ret -add(a: u64, b: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: u64) - 1: MoveLoc[1](b: u64) - 2: Add - 3: Ret -} -public test(p: u64): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](p: u64) - 1: MoveLoc[0](p: u64) - 2: LdU64(1) - 3: Add - 4: Call add(u64, u64): u64 - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.opt.exp index c0900ad546b..127c7cd4672 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/args_with_side_effects.opt.exp @@ -201,25 +201,24 @@ public fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun add(l0: u64, l1: u64): u64 + move_loc l0 + move_loc l1 + add + ret + +// Function definition at index 1 +#[persistent] public fun test(l0: u64): u64 + copy_loc l0 + move_loc l0 + ld_u64 1 + add + call add + // @5 + ret -add(a: u64, b: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](a: u64) - 1: MoveLoc[1](b: u64) - 2: Add - 3: Ret -} -public test(p: u64): u64 /* def_idx: 1 */ { -B0: - 0: CopyLoc[0](p: u64) - 1: MoveLoc[0](p: u64) - 2: LdU64(1) - 3: Add - 4: Call add(u64, u64): u64 - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.exp index 1de6f421309..fec1d75e99e 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.exp @@ -154,24 +154,23 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + local l0: u64 + local l1: &u64 + ld_u64 5 + st_loc l0 + borrow_loc l0 + pop + borrow_loc l0 + // @5 + read_ref + ld_u64 5 + eq + pop + ret -test() /* def_idx: 0 */ { -L0: x: u64 -L1: $t2: &u64 -B0: - 0: LdU64(5) - 1: StLoc[0](x: u64) - 2: ImmBorrowLoc[0](x: u64) - 3: Pop - 4: ImmBorrowLoc[0](x: u64) - 5: ReadRef - 6: LdU64(5) - 7: Eq - 8: Pop - 9: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.opt.exp index 1c3b577813f..7bc4f0bc634 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/borrowed_var.opt.exp @@ -165,27 +165,27 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + local l0: u64 + local l1: &u64 + local l2: u64 + ld_u64 5 + st_loc l0 + borrow_loc l0 + pop + ld_u64 5 + // @5 + st_loc l2 + borrow_loc l2 + read_ref + ld_u64 5 + eq + // @10 + pop + ret -test() /* def_idx: 0 */ { -L0: $t1: u64 -L1: $t2: &u64 -L2: $t4: u64 -B0: - 0: LdU64(5) - 1: StLoc[0]($t1: u64) - 2: ImmBorrowLoc[0]($t1: u64) - 3: Pop - 4: LdU64(5) - 5: StLoc[2]($t4: u64) - 6: ImmBorrowLoc[2]($t4: u64) - 7: ReadRef - 8: LdU64(5) - 9: Eq - 10: Pop - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.exp index 612a828af82..75590565379 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.exp @@ -157,24 +157,20 @@ fun m::foo($t0: bool, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: bool, l1: u64): u64 + move_loc l0 + br_true l0 + branch l1 +l0: ld_u64 0 + st_loc l1 + // @5 +l1: move_loc l1 + ld_u64 1 + add + ret -foo(b: bool, p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](b: bool) - 1: BrTrue(3) -B1: - 2: Branch(5) -B2: - 3: LdU64(0) - 4: StLoc[1](p: u64) -B3: - 5: MoveLoc[1](p: u64) - 6: LdU64(1) - 7: Add - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.opt.exp index 612a828af82..75590565379 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_1.opt.exp @@ -157,24 +157,20 @@ fun m::foo($t0: bool, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun foo(l0: bool, l1: u64): u64 + move_loc l0 + br_true l0 + branch l1 +l0: ld_u64 0 + st_loc l1 + // @5 +l1: move_loc l1 + ld_u64 1 + add + ret -foo(b: bool, p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](b: bool) - 1: BrTrue(3) -B1: - 2: Branch(5) -B2: - 3: LdU64(0) - 4: StLoc[1](p: u64) -B3: - 5: MoveLoc[1](p: u64) - 6: LdU64(1) - 7: Add - 8: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.exp index 9f5c9d1d3b6..fabf2c85def 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.exp @@ -118,25 +118,21 @@ fun m::test($t0: bool, $t1: u64, $t2: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool, l1: u64, l2: u64): u64 + local l3: u64 + move_loc l0 + br_false l0 + move_loc l1 + st_loc l3 +l1: move_loc l3 + // @5 + ret +l0: move_loc l2 + st_loc l3 + branch l1 -test(b: bool, p: u64, q: u64): u64 /* def_idx: 0 */ { -L3: a: u64 -B0: - 0: MoveLoc[0](b: bool) - 1: BrFalse(6) -B1: - 2: MoveLoc[1](p: u64) - 3: StLoc[3](a: u64) -B2: - 4: MoveLoc[3](a: u64) - 5: Ret -B3: - 6: MoveLoc[2](q: u64) - 7: StLoc[3](a: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.opt.exp index 9f5c9d1d3b6..fabf2c85def 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_2.opt.exp @@ -118,25 +118,21 @@ fun m::test($t0: bool, $t1: u64, $t2: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool, l1: u64, l2: u64): u64 + local l3: u64 + move_loc l0 + br_false l0 + move_loc l1 + st_loc l3 +l1: move_loc l3 + // @5 + ret +l0: move_loc l2 + st_loc l3 + branch l1 -test(b: bool, p: u64, q: u64): u64 /* def_idx: 0 */ { -L3: a: u64 -B0: - 0: MoveLoc[0](b: bool) - 1: BrFalse(6) -B1: - 2: MoveLoc[1](p: u64) - 3: StLoc[3](a: u64) -B2: - 4: MoveLoc[3](a: u64) - 5: Ret -B3: - 6: MoveLoc[2](q: u64) - 7: StLoc[3](a: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.exp index 32772070897..7c670ace403 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.exp @@ -117,25 +117,21 @@ fun m::test($t0: bool, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool, l1: u64): u64 + local l2: u64 + move_loc l0 + br_false l0 + move_loc l1 + st_loc l2 +l1: move_loc l2 + // @5 + ret +l0: move_loc l1 + st_loc l2 + branch l1 -test(b: bool, p: u64): u64 /* def_idx: 0 */ { -L2: a: u64 -B0: - 0: MoveLoc[0](b: bool) - 1: BrFalse(6) -B1: - 2: MoveLoc[1](p: u64) - 3: StLoc[2](a: u64) -B2: - 4: MoveLoc[2](a: u64) - 5: Ret -B3: - 6: MoveLoc[1](p: u64) - 7: StLoc[2](a: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.opt.exp index 32772070897..7c670ace403 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_3.opt.exp @@ -117,25 +117,21 @@ fun m::test($t0: bool, $t1: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool, l1: u64): u64 + local l2: u64 + move_loc l0 + br_false l0 + move_loc l1 + st_loc l2 +l1: move_loc l2 + // @5 + ret +l0: move_loc l1 + st_loc l2 + branch l1 -test(b: bool, p: u64): u64 /* def_idx: 0 */ { -L2: a: u64 -B0: - 0: MoveLoc[0](b: bool) - 1: BrFalse(6) -B1: - 2: MoveLoc[1](p: u64) - 3: StLoc[2](a: u64) -B2: - 4: MoveLoc[2](a: u64) - 5: Ret -B3: - 6: MoveLoc[1](p: u64) - 7: StLoc[2](a: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.exp index 97cf17a5e8f..7d151257f32 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.exp @@ -267,29 +267,25 @@ fun _0::main() { ============ disassembled file-format ================== -// Move bytecode v8 -script { +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 5 + st_loc l0 +l1: copy_loc l0 + ld_u64 5 + eq + // @5 + br_false l0 + ret +l0: ld_u64 42 + abort + ld_u64 0 + // @10 + st_loc l0 + branch l1 -main() /* def_idx: 0 */ { -L0: $t5: u64 -B0: - 0: LdU64(5) - 1: StLoc[0]($t5: u64) -B1: - 2: CopyLoc[0]($t5: u64) - 3: LdU64(5) - 4: Eq - 5: BrFalse(7) -B2: - 6: Ret -B3: - 7: LdU64(42) - 8: Abort -B4: - 9: LdU64(0) - 10: StLoc[0]($t5: u64) - 11: Branch(2) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.opt.exp index 97cf17a5e8f..7d151257f32 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/branch_assigns_then_moves_then_assigns.opt.exp @@ -267,29 +267,25 @@ fun _0::main() { ============ disassembled file-format ================== -// Move bytecode v8 -script { +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 5 + st_loc l0 +l1: copy_loc l0 + ld_u64 5 + eq + // @5 + br_false l0 + ret +l0: ld_u64 42 + abort + ld_u64 0 + // @10 + st_loc l0 + branch l1 -main() /* def_idx: 0 */ { -L0: $t5: u64 -B0: - 0: LdU64(5) - 1: StLoc[0]($t5: u64) -B1: - 2: CopyLoc[0]($t5: u64) - 3: LdU64(5) - 4: Eq - 5: BrFalse(7) -B2: - 6: Ret -B3: - 7: LdU64(42) - 8: Abort -B4: - 9: LdU64(0) - 10: StLoc[0]($t5: u64) - 11: Branch(2) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.exp index e1dae5dea2c..130c4d4a362 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.exp @@ -257,33 +257,28 @@ fun m::main() { ============ disassembled file-format ================== -// Move bytecode v8 -module 32.m { +// Bytecode version v9 +module 0x32::m +// Function definition at index 0 +fun main() + local l0: u64 + ld_u64 0 + st_loc l0 + branch l0 + branch l1 +l0: move_loc l0 + // @5 + ld_u64 1 + add + st_loc l0 +l1: move_loc l0 + ld_u64 1 + // @10 + eq + br_false l2 + ret +l2: ld_u64 42 + abort -main() /* def_idx: 0 */ { -L0: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](x: u64) - 2: Branch(4) -B1: - 3: Branch(8) -B2: - 4: MoveLoc[0](x: u64) - 5: LdU64(1) - 6: Add - 7: StLoc[0](x: u64) -B3: - 8: MoveLoc[0](x: u64) - 9: LdU64(1) - 10: Eq - 11: BrFalse(13) -B4: - 12: Ret -B5: - 13: LdU64(42) - 14: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.opt.exp index e1dae5dea2c..130c4d4a362 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/bug_12068.opt.exp @@ -257,33 +257,28 @@ fun m::main() { ============ disassembled file-format ================== -// Move bytecode v8 -module 32.m { +// Bytecode version v9 +module 0x32::m +// Function definition at index 0 +fun main() + local l0: u64 + ld_u64 0 + st_loc l0 + branch l0 + branch l1 +l0: move_loc l0 + // @5 + ld_u64 1 + add + st_loc l0 +l1: move_loc l0 + ld_u64 1 + // @10 + eq + br_false l2 + ret +l2: ld_u64 42 + abort -main() /* def_idx: 0 */ { -L0: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](x: u64) - 2: Branch(4) -B1: - 3: Branch(8) -B2: - 4: MoveLoc[0](x: u64) - 5: LdU64(1) - 6: Add - 7: StLoc[0](x: u64) -B3: - 8: MoveLoc[0](x: u64) - 9: LdU64(1) - 10: Eq - 11: BrFalse(13) -B4: - 12: Ret -B5: - 13: LdU64(42) - 14: Abort -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.exp index 91bc7b951f8..eb7f02694a3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.exp @@ -179,22 +179,20 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 1 +fun test(l0: u64): u64 + move_loc l0 + call id + call id + call id + ret -id(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -test(p: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Call id(u64): u64 - 2: Call id(u64): u64 - 3: Call id(u64): u64 - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.opt.exp index 91bc7b951f8..eb7f02694a3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_1.opt.exp @@ -179,22 +179,20 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 1 +fun test(l0: u64): u64 + move_loc l0 + call id + call id + call id + ret -id(x: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -test(p: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Call id(u64): u64 - 2: Call id(u64): u64 - 3: Call id(u64): u64 - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.exp index e85ac73f7e8..3a5936c41de 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.exp @@ -178,26 +178,25 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun update(l0: &mut u64) + ld_u64 0 + move_loc l0 + write_ref + ret + +// Function definition at index 1 +fun test(l0: u64): u64 + local l1: u64 + copy_loc l0 + st_loc l1 + mut_borrow_loc l1 + call update + move_loc l0 + // @5 + ret -update(p: &mut u64) /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: MoveLoc[0](p: &mut u64) - 2: WriteRef - 3: Ret -} -test(p: u64): u64 /* def_idx: 1 */ { -L1: a: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: MutBorrowLoc[1](a: u64) - 3: Call update(&mut u64) - 4: MoveLoc[0](p: u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.opt.exp index e85ac73f7e8..3a5936c41de 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/call_2.opt.exp @@ -178,26 +178,25 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun update(l0: &mut u64) + ld_u64 0 + move_loc l0 + write_ref + ret + +// Function definition at index 1 +fun test(l0: u64): u64 + local l1: u64 + copy_loc l0 + st_loc l1 + mut_borrow_loc l1 + call update + move_loc l0 + // @5 + ret -update(p: &mut u64) /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: MoveLoc[0](p: &mut u64) - 2: WriteRef - 3: Ret -} -test(p: u64): u64 /* def_idx: 1 */ { -L1: a: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: MutBorrowLoc[1](a: u64) - 3: Call update(&mut u64) - 4: MoveLoc[0](p: u64) - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.exp index 235719833c4..164a52a25a9 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.exp @@ -107,18 +107,17 @@ public fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public test(a: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: MoveLoc[0](a: u64) - 2: Add - 3: Pop - 4: LdU64(2) - 5: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64): u64 + copy_loc l0 + move_loc l0 + add + pop + ld_u64 2 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.opt.exp index 4a75e77b168..3a814682165 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_coalesce_1.opt.exp @@ -96,18 +96,17 @@ public fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public test(a: u64): u64 /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](a: u64) - 1: MoveLoc[0](a: u64) - 2: Add - 3: Pop - 4: LdU64(2) - 5: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64): u64 + copy_loc l0 + move_loc l0 + add + pop + ld_u64 2 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.exp index 9e4408948a7..d8881c7d9a7 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.exp @@ -100,17 +100,16 @@ fun m::test($t0: u64, $t1: bool) { var $t6: u64 var $t7: u64 0: $t2 := move($t0) - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 2: label L0 3: m::consume($t2) - 4: label L2 - 5: return () - 6: label L1 - 7: $t4 := move($t2) - 8: $t6 := move($t4) - 9: $t7 := 1 - 10: $t5 := +($t6, $t7) - 11: goto 4 + 4: return () + 5: label L1 + 6: $t4 := move($t2) + 7: $t6 := move($t4) + 8: $t7 := 1 + 9: $t5 := +($t6, $t7) + 10: return () } ============ after VariableCoalescingAnnotator: ================ @@ -137,31 +136,29 @@ fun m::test($t0: u64, $t1: bool) { 0: $t2 := move($t0) # live vars: $t1, $t2 # events: e:$t1 - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 # live vars: $t2 2: label L0 # live vars: $t2 3: m::consume($t2) # live vars: - 4: label L2 - # live vars: - 5: return () + 4: return () # live vars: $t2 - 6: label L1 + 5: label L1 # live vars: $t2 # events: e:$t2, b:$t4 - 7: $t4 := move($t2) + 6: $t4 := move($t2) # live vars: $t4 # events: e:$t4, b:$t6 - 8: $t6 := move($t4) + 7: $t6 := move($t4) # live vars: $t6 # events: b:$t7 - 9: $t7 := 1 + 8: $t7 := 1 # live vars: $t6, $t7 # events: e:$t5, e:$t6, e:$t7, b:$t5 - 10: $t5 := +($t6, $t7) + 9: $t5 := +($t6, $t7) # live vars: - 11: goto 4 + 10: return () } ============ after VariableCoalescingTransformer: ================ @@ -182,17 +179,16 @@ fun m::test($t0: u64, $t1: bool) { var $t6: u64 [unused] var $t7: u64 0: $t0 := move($t0) - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 2: label L0 3: m::consume($t0) - 4: label L2 - 5: return () - 6: label L1 + 4: return () + 5: label L1 + 6: $t0 := move($t0) 7: $t0 := move($t0) - 8: $t0 := move($t0) - 9: $t7 := 1 - 10: $t0 := +($t0, $t7) - 11: goto 4 + 8: $t7 := 1 + 9: $t0 := +($t0, $t7) + 10: return () } ============ after DeadStoreElimination: ================ @@ -212,43 +208,38 @@ fun m::test($t0: u64, $t1: bool) { var $t5: u64 [unused] var $t6: u64 [unused] var $t7: u64 - 0: if ($t1) goto 1 else goto 5 + 0: if ($t1) goto 1 else goto 4 1: label L0 2: m::consume($t0) - 3: label L2 - 4: return () - 5: label L1 - 6: $t0 := move($t0) - 7: $t7 := 1 - 8: $t0 := +($t0, $t7) - 9: goto 3 + 3: return () + 4: label L1 + 5: $t0 := move($t0) + 6: $t7 := 1 + 7: $t0 := +($t0, $t7) + 8: return () } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun test(l0: u64, l1: bool) + move_loc l1 + br_false l0 + move_loc l0 + call consume + ret + // @5 +l0: move_loc l0 + ld_u64 1 + add + pop + ret -consume(a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -test(a: u64, p: bool) /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](p: bool) - 1: BrFalse(5) -B1: - 2: MoveLoc[0](a: u64) - 3: Call consume(u64) -B2: - 4: Ret -B3: - 5: MoveLoc[0](a: u64) - 6: LdU64(1) - 7: Add - 8: Pop - 9: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.opt.exp index 9e4408948a7..d8881c7d9a7 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cant_copy_propagate.opt.exp @@ -100,17 +100,16 @@ fun m::test($t0: u64, $t1: bool) { var $t6: u64 var $t7: u64 0: $t2 := move($t0) - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 2: label L0 3: m::consume($t2) - 4: label L2 - 5: return () - 6: label L1 - 7: $t4 := move($t2) - 8: $t6 := move($t4) - 9: $t7 := 1 - 10: $t5 := +($t6, $t7) - 11: goto 4 + 4: return () + 5: label L1 + 6: $t4 := move($t2) + 7: $t6 := move($t4) + 8: $t7 := 1 + 9: $t5 := +($t6, $t7) + 10: return () } ============ after VariableCoalescingAnnotator: ================ @@ -137,31 +136,29 @@ fun m::test($t0: u64, $t1: bool) { 0: $t2 := move($t0) # live vars: $t1, $t2 # events: e:$t1 - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 # live vars: $t2 2: label L0 # live vars: $t2 3: m::consume($t2) # live vars: - 4: label L2 - # live vars: - 5: return () + 4: return () # live vars: $t2 - 6: label L1 + 5: label L1 # live vars: $t2 # events: e:$t2, b:$t4 - 7: $t4 := move($t2) + 6: $t4 := move($t2) # live vars: $t4 # events: e:$t4, b:$t6 - 8: $t6 := move($t4) + 7: $t6 := move($t4) # live vars: $t6 # events: b:$t7 - 9: $t7 := 1 + 8: $t7 := 1 # live vars: $t6, $t7 # events: e:$t5, e:$t6, e:$t7, b:$t5 - 10: $t5 := +($t6, $t7) + 9: $t5 := +($t6, $t7) # live vars: - 11: goto 4 + 10: return () } ============ after VariableCoalescingTransformer: ================ @@ -182,17 +179,16 @@ fun m::test($t0: u64, $t1: bool) { var $t6: u64 [unused] var $t7: u64 0: $t0 := move($t0) - 1: if ($t1) goto 2 else goto 6 + 1: if ($t1) goto 2 else goto 5 2: label L0 3: m::consume($t0) - 4: label L2 - 5: return () - 6: label L1 + 4: return () + 5: label L1 + 6: $t0 := move($t0) 7: $t0 := move($t0) - 8: $t0 := move($t0) - 9: $t7 := 1 - 10: $t0 := +($t0, $t7) - 11: goto 4 + 8: $t7 := 1 + 9: $t0 := +($t0, $t7) + 10: return () } ============ after DeadStoreElimination: ================ @@ -212,43 +208,38 @@ fun m::test($t0: u64, $t1: bool) { var $t5: u64 [unused] var $t6: u64 [unused] var $t7: u64 - 0: if ($t1) goto 1 else goto 5 + 0: if ($t1) goto 1 else goto 4 1: label L0 2: m::consume($t0) - 3: label L2 - 4: return () - 5: label L1 - 6: $t0 := move($t0) - 7: $t7 := 1 - 8: $t0 := +($t0, $t7) - 9: goto 3 + 3: return () + 4: label L1 + 5: $t0 := move($t0) + 6: $t7 := 1 + 7: $t0 := +($t0, $t7) + 8: return () } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun test(l0: u64, l1: bool) + move_loc l1 + br_false l0 + move_loc l0 + call consume + ret + // @5 +l0: move_loc l0 + ld_u64 1 + add + pop + ret -consume(a: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -test(a: u64, p: bool) /* def_idx: 1 */ { -B0: - 0: MoveLoc[1](p: bool) - 1: BrFalse(5) -B1: - 2: MoveLoc[0](a: u64) - 3: Call consume(u64) -B2: - 4: Ret -B3: - 5: MoveLoc[0](a: u64) - 6: LdU64(1) - 7: Add - 8: Pop - 9: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.exp index be0fe328f80..30b9484c09c 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.exp @@ -59,18 +59,17 @@ fun m::test($t0: bool): u64 { var $t5: u64 var $t6: u64 0: $t2 := 2 - 1: if ($t0) goto 2 else goto 7 + 1: if ($t0) goto 2 else goto 6 2: label L0 3: $t3 := 3 4: $t1 := move($t3) - 5: label L2 - 6: return $t1 - 7: label L1 - 8: $t5 := move($t2) - 9: $t6 := 1 - 10: $t4 := +($t5, $t6) - 11: $t1 := move($t4) - 12: goto 5 + 5: return $t1 + 6: label L1 + 7: $t5 := move($t2) + 8: $t6 := 1 + 9: $t4 := +($t5, $t6) + 10: $t1 := move($t4) + 11: return $t1 } ============ after VariableCoalescingAnnotator: ================ @@ -88,7 +87,7 @@ fun m::test($t0: bool): u64 { 0: $t2 := 2 # live vars: $t0, $t2 # events: e:$t0 - 1: if ($t0) goto 2 else goto 7 + 1: if ($t0) goto 2 else goto 6 # live vars: $t2 2: label L0 # live vars: @@ -98,26 +97,24 @@ fun m::test($t0: bool): u64 { # events: e:$t3, b:$t1 4: $t1 := move($t3) # live vars: $t1 - 5: label L2 - # live vars: $t1 - 6: return $t1 + 5: return $t1 # live vars: $t2 - 7: label L1 + 6: label L1 # live vars: $t2 # events: e:$t2, b:$t5 - 8: $t5 := move($t2) + 7: $t5 := move($t2) # live vars: $t5 # events: b:$t6 - 9: $t6 := 1 + 8: $t6 := 1 # live vars: $t5, $t6 # events: e:$t5, e:$t6, b:$t4 - 10: $t4 := +($t5, $t6) + 9: $t4 := +($t5, $t6) # live vars: $t4 # events: e:$t4 - 11: $t1 := move($t4) + 10: $t1 := move($t4) # live vars: $t1 # events: e:$t1 - 12: goto 5 + 11: return $t1 } ============ after VariableCoalescingTransformer: ================ @@ -131,18 +128,17 @@ fun m::test($t0: bool): u64 { var $t5: u64 [unused] var $t6: u64 0: $t2 := 2 - 1: if ($t0) goto 2 else goto 7 + 1: if ($t0) goto 2 else goto 6 2: label L0 3: $t3 := 3 4: $t3 := move($t3) - 5: label L2 - 6: return $t3 - 7: label L1 - 8: $t2 := move($t2) - 9: $t6 := 1 - 10: $t2 := +($t2, $t6) - 11: $t3 := move($t2) - 12: goto 5 + 5: return $t3 + 6: label L1 + 7: $t2 := move($t2) + 8: $t6 := 1 + 9: $t2 := +($t2, $t6) + 10: $t3 := move($t2) + 11: return $t3 } ============ after DeadStoreElimination: ================ @@ -156,45 +152,36 @@ fun m::test($t0: bool): u64 { var $t5: u64 [unused] var $t6: u64 0: $t2 := 2 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 2: label L0 3: $t3 := 3 - 4: label L2 - 5: return $t3 - 6: label L1 - 7: $t2 := move($t2) - 8: $t6 := 1 - 9: $t2 := +($t2, $t6) - 10: $t3 := move($t2) - 11: goto 4 + 4: return $t3 + 5: label L1 + 6: $t2 := move($t2) + 7: $t6 := 1 + 8: $t2 := +($t2, $t6) + 9: $t3 := move($t2) + 10: return $t3 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool): u64 + local l1: u64 + ld_u64 2 + st_loc l1 + move_loc l0 + br_false l0 + ld_u64 3 + // @5 + ret +l0: move_loc l1 + ld_u64 1 + add + ret -test(p: bool): u64 /* def_idx: 0 */ { -L1: x: u64 -L2: y: u64 -B0: - 0: LdU64(2) - 1: StLoc[1](x: u64) - 2: MoveLoc[0](p: bool) - 3: BrFalse(8) -B1: - 4: LdU64(3) - 5: StLoc[2](y: u64) -B2: - 6: MoveLoc[2](y: u64) - 7: Ret -B3: - 8: MoveLoc[1](x: u64) - 9: LdU64(1) - 10: Add - 11: StLoc[2](y: u64) - 12: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.opt.exp index 014f62917a4..f04d2aeb5f2 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/conditional.opt.exp @@ -43,14 +43,13 @@ fun m::test($t0: bool): u64 { [variant baseline] fun m::test($t0: bool): u64 { var $t1: u64 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 1: label L0 2: $t1 := 3 - 3: label L2 - 4: return $t1 - 5: label L1 - 6: $t1 := 3 - 7: goto 3 + 3: return $t1 + 4: label L1 + 5: $t1 := 3 + 6: return $t1 } ============ after VariableCoalescingAnnotator: ================ @@ -60,23 +59,21 @@ fun m::test($t0: bool): u64 { var $t1: u64 # live vars: $t0 # events: b:$t0, e:$t0 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 # live vars: 1: label L0 # live vars: # events: b:$t1 2: $t1 := 3 # live vars: $t1 - 3: label L2 - # live vars: $t1 - 4: return $t1 + 3: return $t1 # live vars: - 5: label L1 + 4: label L1 # live vars: - 6: $t1 := 3 + 5: $t1 := 3 # live vars: $t1 # events: e:$t1 - 7: goto 3 + 6: return $t1 } ============ after VariableCoalescingTransformer: ================ @@ -84,14 +81,13 @@ fun m::test($t0: bool): u64 { [variant baseline] fun m::test($t0: bool): u64 { var $t1: u64 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 1: label L0 2: $t1 := 3 - 3: label L2 - 4: return $t1 - 5: label L1 - 6: $t1 := 3 - 7: goto 3 + 3: return $t1 + 4: label L1 + 5: $t1 := 3 + 6: return $t1 } ============ after DeadStoreElimination: ================ @@ -99,37 +95,28 @@ fun m::test($t0: bool): u64 { [variant baseline] fun m::test($t0: bool): u64 { var $t1: u64 - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 1: label L0 2: $t1 := 3 - 3: label L2 - 4: return $t1 - 5: label L1 - 6: $t1 := 3 - 7: goto 3 + 3: return $t1 + 4: label L1 + 5: $t1 := 3 + 6: return $t1 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: bool): u64 + move_loc l0 + br_false l0 + ld_u64 3 + ret +l0: ld_u64 3 + // @5 + ret -test(p: bool): u64 /* def_idx: 0 */ { -L1: return: u64 -B0: - 0: MoveLoc[0](p: bool) - 1: BrFalse(6) -B1: - 2: LdU64(3) - 3: StLoc[1](return: u64) -B2: - 4: MoveLoc[1](return: u64) - 5: Ret -B3: - 6: LdU64(3) - 7: StLoc[1](return: u64) - 8: Branch(4) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.exp index fc371de67ce..1b591c99ddd 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.exp @@ -350,51 +350,50 @@ public fun m::test4($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u64 -} - -consume(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test1(x: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[0](x: u64) - 2: Call consume(u64) - 3: Call consume(u64) - 4: Ret -} -public test2(x: u64) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: Call consume(u64) - 2: MoveLoc[0](x: u64) - 3: Call consume(u64) - 4: Ret -} -public test3(x: W) /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](x: W) - 1: MoveLoc[0](x: W) - 2: Call consume_(W) - 3: Call consume_(W) - 4: Ret -} -public test4(x: W) /* def_idx: 5 */ { -B0: - 0: CopyLoc[0](x: W) - 1: Call consume_(W) - 2: MoveLoc[0](x: W) - 3: Call consume_(W) - 4: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u64 + +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + move_loc l0 + call consume + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: u64) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 4 +#[persistent] public fun test3(l0: W) + copy_loc l0 + move_loc l0 + call consume_ + call consume_ + ret + +// Function definition at index 5 +#[persistent] public fun test4(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.opt.exp index fc371de67ce..1b591c99ddd 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_1.opt.exp @@ -350,51 +350,50 @@ public fun m::test4($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u64 -} - -consume(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test1(x: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: MoveLoc[0](x: u64) - 2: Call consume(u64) - 3: Call consume(u64) - 4: Ret -} -public test2(x: u64) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: Call consume(u64) - 2: MoveLoc[0](x: u64) - 3: Call consume(u64) - 4: Ret -} -public test3(x: W) /* def_idx: 4 */ { -B0: - 0: CopyLoc[0](x: W) - 1: MoveLoc[0](x: W) - 2: Call consume_(W) - 3: Call consume_(W) - 4: Ret -} -public test4(x: W) /* def_idx: 5 */ { -B0: - 0: CopyLoc[0](x: W) - 1: Call consume_(W) - 2: MoveLoc[0](x: W) - 3: Call consume_(W) - 4: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u64 + +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + move_loc l0 + call consume + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: u64) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 4 +#[persistent] public fun test3(l0: W) + copy_loc l0 + move_loc l0 + call consume_ + call consume_ + ret + +// Function definition at index 5 +#[persistent] public fun test4(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.exp index 5e51dadc600..899160bd419 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.exp @@ -212,35 +212,34 @@ public fun m::test2($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u64 + +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test1(x: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: Call consume(u64) - 2: MoveLoc[0](x: u64) - 3: Call consume(u64) - 4: Ret -} -public test2(x: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](x: W) - 1: Call consume_(W) - 2: MoveLoc[0](x: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.opt.exp index 5e51dadc600..899160bd419 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_2.opt.exp @@ -212,35 +212,34 @@ public fun m::test2($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u64 + +// Function definition at index 0 +fun consume(l0: u64) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test1(l0: u64) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test2(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test1(x: u64) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](x: u64) - 1: Call consume(u64) - 2: MoveLoc[0](x: u64) - 3: Call consume(u64) - 4: Ret -} -public test2(x: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](x: W) - 1: Call consume_(W) - 2: MoveLoc[0](x: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.exp index ce61d72a12b..2aff232bf2d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.exp @@ -216,35 +216,34 @@ public fun m::test_($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - a: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + a: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u32) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test_(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_a: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_a: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(a: u32) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u32) - 1: Call consume(u32) - 2: MoveLoc[0](a: u32) - 3: Call consume(u32) - 4: Ret -} -public test_(a: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: W) - 1: Call consume_(W) - 2: MoveLoc[0](a: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.opt.exp index ce61d72a12b..2aff232bf2d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_3.opt.exp @@ -216,35 +216,34 @@ public fun m::test_($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - a: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + a: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u32) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test_(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_a: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_a: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(a: u32) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u32) - 1: Call consume(u32) - 2: MoveLoc[0](a: u32) - 3: Call consume(u32) - 4: Ret -} -public test_(a: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: W) - 1: Call consume_(W) - 2: MoveLoc[0](a: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.exp index 6dc2aabdf3d..cd3c226ba08 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.exp @@ -242,35 +242,34 @@ public fun m::test_struct($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - m: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + m: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u32) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test_struct(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_x: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(a: u32) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u32) - 1: Call consume(u32) - 2: MoveLoc[0](a: u32) - 3: Call consume(u32) - 4: Ret -} -public test_struct(a: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: W) - 1: Call consume_(W) - 2: MoveLoc[0](a: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.opt.exp index 6dc2aabdf3d..cd3c226ba08 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_4.opt.exp @@ -242,35 +242,34 @@ public fun m::test_struct($t0: 0xc0ffee::m::W) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - m: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + m: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: u32) + copy_loc l0 + call consume + move_loc l0 + call consume + ret + +// Function definition at index 3 +#[persistent] public fun test_struct(l0: W) + copy_loc l0 + call consume_ + move_loc l0 + call consume_ + ret + -consume(_x: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(a: u32) /* def_idx: 2 */ { -B0: - 0: CopyLoc[0](a: u32) - 1: Call consume(u32) - 2: MoveLoc[0](a: u32) - 3: Call consume(u32) - 4: Ret -} -public test_struct(a: W) /* def_idx: 3 */ { -B0: - 0: CopyLoc[0](a: W) - 1: Call consume_(W) - 2: MoveLoc[0](a: W) - 3: Call consume_(W) - 4: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.exp index 13faafd9c47..1a1e4760be1 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.exp @@ -139,22 +139,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -163,22 +162,21 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ after VariableCoalescingAnnotator: ================ @@ -207,7 +205,7 @@ public fun m::test($t0: bool, $t1: u32) { # events: b:$t0, b:$t1, b:$t2 0: $t2 := copy($t1) # live vars: $t0, $t1, $t2 - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 # live vars: $t0, $t1, $t2 2: label L0 # live vars: $t0, $t1, $t2 @@ -219,28 +217,26 @@ public fun m::test($t0: bool, $t1: u32) { 5: $t3 := !($t0) # live vars: $t1, $t2, $t3 # events: e:$t3 - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 # live vars: $t1, $t2 7: label L3 # live vars: $t1 8: m::consume($t1) # live vars: - 9: label L5 - # live vars: - 10: return () + 9: return () # live vars: $t1, $t2 - 11: label L4 + 10: label L4 # live vars: $t2 - 12: m::consume($t2) + 11: m::consume($t2) # live vars: - 13: goto 9 + 12: return () # live vars: $t0, $t1, $t2 - 14: label L1 + 13: label L1 # live vars: $t0, $t1, $t2 - 15: m::consume($t1) + 14: m::consume($t1) # live vars: $t0, $t1, $t2 # events: e:$t0, e:$t1, e:$t2 - 16: goto 4 + 15: goto 4 } @@ -252,7 +248,7 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { # events: b:$t0, b:$t1, b:$t2 0: $t2 := copy($t1) # live vars: $t0, $t1, $t2 - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 # live vars: $t0, $t1, $t2 2: label L0 # live vars: $t0, $t1, $t2 @@ -264,28 +260,26 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { 5: $t3 := !($t0) # live vars: $t1, $t2, $t3 # events: e:$t3 - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 # live vars: $t1, $t2 7: label L3 # live vars: $t1 8: m::consume_($t1) # live vars: - 9: label L5 - # live vars: - 10: return () + 9: return () # live vars: $t1, $t2 - 11: label L4 + 10: label L4 # live vars: $t2 - 12: m::consume_($t2) + 11: m::consume_($t2) # live vars: - 13: goto 9 + 12: return () # live vars: $t0, $t1, $t2 - 14: label L1 + 13: label L1 # live vars: $t0, $t1, $t2 - 15: m::consume_($t1) + 14: m::consume_($t1) # live vars: $t0, $t1, $t2 # events: e:$t0, e:$t1, e:$t2 - 16: goto 4 + 15: goto 4 } ============ after VariableCoalescingTransformer: ================ @@ -307,22 +301,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -331,22 +324,21 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ after DeadStoreElimination: ================ @@ -368,22 +360,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -392,93 +383,85 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: bool, l1: u32) + local l2: u32 + copy_loc l1 + st_loc l2 + copy_loc l0 + br_false l0 + copy_loc l2 + // @5 + call consume +l2: move_loc l0 + br_true l1 + move_loc l1 + call consume + // @10 + ret +l1: move_loc l2 + call consume + ret +l0: copy_loc l1 + // @15 + call consume + branch l2 + +// Function definition at index 3 +#[persistent] public fun test_struct(l0: bool, l1: W) + local l2: W + copy_loc l1 + st_loc l2 + copy_loc l0 + br_false l0 + copy_loc l2 + // @5 + call consume_ +l2: move_loc l0 + br_true l1 + move_loc l1 + call consume_ + // @10 + ret +l1: move_loc l2 + call consume_ + ret +l0: copy_loc l1 + // @15 + call consume_ + branch l2 + -consume(_x: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(p: bool, a: u32) /* def_idx: 2 */ { -L2: b: u32 -B0: - 0: CopyLoc[1](a: u32) - 1: StLoc[2](b: u32) - 2: CopyLoc[0](p: bool) - 3: BrFalse(14) -B1: - 4: CopyLoc[2](b: u32) - 5: Call consume(u32) -B2: - 6: MoveLoc[0](p: bool) - 7: BrTrue(11) -B3: - 8: MoveLoc[1](a: u32) - 9: Call consume(u32) -B4: - 10: Ret -B5: - 11: MoveLoc[2](b: u32) - 12: Call consume(u32) - 13: Branch(10) -B6: - 14: CopyLoc[1](a: u32) - 15: Call consume(u32) - 16: Branch(6) -} -public test_struct(p: bool, a: W) /* def_idx: 3 */ { -L2: b: W -B0: - 0: CopyLoc[1](a: W) - 1: StLoc[2](b: W) - 2: CopyLoc[0](p: bool) - 3: BrFalse(14) -B1: - 4: CopyLoc[2](b: W) - 5: Call consume_(W) -B2: - 6: MoveLoc[0](p: bool) - 7: BrTrue(11) -B3: - 8: MoveLoc[1](a: W) - 9: Call consume_(W) -B4: - 10: Ret -B5: - 11: MoveLoc[2](b: W) - 12: Call consume_(W) - 13: Branch(10) -B6: - 14: CopyLoc[1](a: W) - 15: Call consume_(W) - 16: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.opt.exp index 13faafd9c47..1a1e4760be1 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/consume_5.opt.exp @@ -139,22 +139,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -163,22 +162,21 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ after VariableCoalescingAnnotator: ================ @@ -207,7 +205,7 @@ public fun m::test($t0: bool, $t1: u32) { # events: b:$t0, b:$t1, b:$t2 0: $t2 := copy($t1) # live vars: $t0, $t1, $t2 - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 # live vars: $t0, $t1, $t2 2: label L0 # live vars: $t0, $t1, $t2 @@ -219,28 +217,26 @@ public fun m::test($t0: bool, $t1: u32) { 5: $t3 := !($t0) # live vars: $t1, $t2, $t3 # events: e:$t3 - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 # live vars: $t1, $t2 7: label L3 # live vars: $t1 8: m::consume($t1) # live vars: - 9: label L5 - # live vars: - 10: return () + 9: return () # live vars: $t1, $t2 - 11: label L4 + 10: label L4 # live vars: $t2 - 12: m::consume($t2) + 11: m::consume($t2) # live vars: - 13: goto 9 + 12: return () # live vars: $t0, $t1, $t2 - 14: label L1 + 13: label L1 # live vars: $t0, $t1, $t2 - 15: m::consume($t1) + 14: m::consume($t1) # live vars: $t0, $t1, $t2 # events: e:$t0, e:$t1, e:$t2 - 16: goto 4 + 15: goto 4 } @@ -252,7 +248,7 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { # events: b:$t0, b:$t1, b:$t2 0: $t2 := copy($t1) # live vars: $t0, $t1, $t2 - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 # live vars: $t0, $t1, $t2 2: label L0 # live vars: $t0, $t1, $t2 @@ -264,28 +260,26 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { 5: $t3 := !($t0) # live vars: $t1, $t2, $t3 # events: e:$t3 - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 # live vars: $t1, $t2 7: label L3 # live vars: $t1 8: m::consume_($t1) # live vars: - 9: label L5 - # live vars: - 10: return () + 9: return () # live vars: $t1, $t2 - 11: label L4 + 10: label L4 # live vars: $t2 - 12: m::consume_($t2) + 11: m::consume_($t2) # live vars: - 13: goto 9 + 12: return () # live vars: $t0, $t1, $t2 - 14: label L1 + 13: label L1 # live vars: $t0, $t1, $t2 - 15: m::consume_($t1) + 14: m::consume_($t1) # live vars: $t0, $t1, $t2 # events: e:$t0, e:$t1, e:$t2 - 16: goto 4 + 15: goto 4 } ============ after VariableCoalescingTransformer: ================ @@ -307,22 +301,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -331,22 +324,21 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ after DeadStoreElimination: ================ @@ -368,22 +360,21 @@ public fun m::test($t0: bool, $t1: u32) { var $t2: u32 var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume($t2) - 13: goto 9 - 14: label L1 - 15: m::consume($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume($t2) + 12: return () + 13: label L1 + 14: m::consume($t1) + 15: goto 4 } @@ -392,93 +383,85 @@ public fun m::test_struct($t0: bool, $t1: 0xc0ffee::m::W) { var $t2: 0xc0ffee::m::W var $t3: bool 0: $t2 := copy($t1) - 1: if ($t0) goto 2 else goto 14 + 1: if ($t0) goto 2 else goto 13 2: label L0 3: m::consume_($t2) 4: label L2 5: $t3 := !($t0) - 6: if ($t3) goto 7 else goto 11 + 6: if ($t3) goto 7 else goto 10 7: label L3 8: m::consume_($t1) - 9: label L5 - 10: return () - 11: label L4 - 12: m::consume_($t2) - 13: goto 9 - 14: label L1 - 15: m::consume_($t1) - 16: goto 4 + 9: return () + 10: label L4 + 11: m::consume_($t2) + 12: return () + 13: label L1 + 14: m::consume_($t1) + 15: goto 4 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct W has copy, drop { - x: u32 -} +// Bytecode version v9 +module 0xc0ffee::m +struct W has copy + drop + x: u32 + +// Function definition at index 0 +fun consume(l0: u32) + ret + +// Function definition at index 1 +fun consume_(l0: W) + ret + +// Function definition at index 2 +#[persistent] public fun test(l0: bool, l1: u32) + local l2: u32 + copy_loc l1 + st_loc l2 + copy_loc l0 + br_false l0 + copy_loc l2 + // @5 + call consume +l2: move_loc l0 + br_true l1 + move_loc l1 + call consume + // @10 + ret +l1: move_loc l2 + call consume + ret +l0: copy_loc l1 + // @15 + call consume + branch l2 + +// Function definition at index 3 +#[persistent] public fun test_struct(l0: bool, l1: W) + local l2: W + copy_loc l1 + st_loc l2 + copy_loc l0 + br_false l0 + copy_loc l2 + // @5 + call consume_ +l2: move_loc l0 + br_true l1 + move_loc l1 + call consume_ + // @10 + ret +l1: move_loc l2 + call consume_ + ret +l0: copy_loc l1 + // @15 + call consume_ + branch l2 + -consume(_x: u32) /* def_idx: 0 */ { -B0: - 0: Ret -} -consume_(_x: W) /* def_idx: 1 */ { -B0: - 0: Ret -} -public test(p: bool, a: u32) /* def_idx: 2 */ { -L2: b: u32 -B0: - 0: CopyLoc[1](a: u32) - 1: StLoc[2](b: u32) - 2: CopyLoc[0](p: bool) - 3: BrFalse(14) -B1: - 4: CopyLoc[2](b: u32) - 5: Call consume(u32) -B2: - 6: MoveLoc[0](p: bool) - 7: BrTrue(11) -B3: - 8: MoveLoc[1](a: u32) - 9: Call consume(u32) -B4: - 10: Ret -B5: - 11: MoveLoc[2](b: u32) - 12: Call consume(u32) - 13: Branch(10) -B6: - 14: CopyLoc[1](a: u32) - 15: Call consume(u32) - 16: Branch(6) -} -public test_struct(p: bool, a: W) /* def_idx: 3 */ { -L2: b: W -B0: - 0: CopyLoc[1](a: W) - 1: StLoc[2](b: W) - 2: CopyLoc[0](p: bool) - 3: BrFalse(14) -B1: - 4: CopyLoc[2](b: W) - 5: Call consume_(W) -B2: - 6: MoveLoc[0](p: bool) - 7: BrTrue(11) -B3: - 8: MoveLoc[1](a: W) - 9: Call consume_(W) -B4: - 10: Ret -B5: - 11: MoveLoc[2](b: W) - 12: Call consume_(W) - 13: Branch(10) -B6: - 14: CopyLoc[1](a: W) - 15: Call consume_(W) - 16: Branch(6) -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.exp index 59e386c4f1c..912de167e37 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.exp @@ -78,13 +78,11 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64) + ret -public test(x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.opt.exp index 59e386c4f1c..912de167e37 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignment_without_use.opt.exp @@ -78,13 +78,11 @@ public fun m::test($t0: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64) + ret -public test(x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.exp index db585fb4118..c3ec6de7bf8 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.exp @@ -92,14 +92,12 @@ fun m::cyclic($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun cyclic(l0: u64): u64 + move_loc l0 + ret -cyclic(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.opt.exp index db585fb4118..c3ec6de7bf8 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_assignments.opt.exp @@ -92,14 +92,12 @@ fun m::cyclic($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun cyclic(l0: u64): u64 + move_loc l0 + ret -cyclic(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.exp index c5481159567..446ce4001b9 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.exp @@ -379,46 +379,42 @@ public fun m::test2($t0: u64, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(l0: u64, l1: u64, l2: u64) + local l3: u64 + ld_u64 0 + st_loc l3 +l1: copy_loc l3 + copy_loc l0 + lt + // @5 + br_false l0 + move_loc l3 + ld_u64 1 + add + st_loc l3 + // @10 + branch l1 +l0: ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64, l1: u64) + ld_u64 0 + st_loc l1 +l1: copy_loc l1 + copy_loc l0 + lt + // @5 + br_false l0 + move_loc l1 + ld_u64 1 + add + st_loc l1 + // @10 + branch l1 +l0: ret -public test1(x: u64, a: u64, b: u64) /* def_idx: 0 */ { -L3: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[3](i: u64) -B1: - 2: CopyLoc[3](i: u64) - 3: CopyLoc[0](x: u64) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[3](i: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[3](i: u64) - 10: Branch(2) -B3: - 11: Ret -} -public test2(x: u64, a: u64) /* def_idx: 1 */ { -B0: - 0: LdU64(0) - 1: StLoc[1](a: u64) -B1: - 2: CopyLoc[1](a: u64) - 3: CopyLoc[0](x: u64) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[1](a: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[1](a: u64) - 10: Branch(2) -B3: - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.opt.exp index c5481159567..446ce4001b9 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/cyclic_dead_store.opt.exp @@ -379,46 +379,42 @@ public fun m::test2($t0: u64, $t1: u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(l0: u64, l1: u64, l2: u64) + local l3: u64 + ld_u64 0 + st_loc l3 +l1: copy_loc l3 + copy_loc l0 + lt + // @5 + br_false l0 + move_loc l3 + ld_u64 1 + add + st_loc l3 + // @10 + branch l1 +l0: ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64, l1: u64) + ld_u64 0 + st_loc l1 +l1: copy_loc l1 + copy_loc l0 + lt + // @5 + br_false l0 + move_loc l1 + ld_u64 1 + add + st_loc l1 + // @10 + branch l1 +l0: ret -public test1(x: u64, a: u64, b: u64) /* def_idx: 0 */ { -L3: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[3](i: u64) -B1: - 2: CopyLoc[3](i: u64) - 3: CopyLoc[0](x: u64) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[3](i: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[3](i: u64) - 10: Branch(2) -B3: - 11: Ret -} -public test2(x: u64, a: u64) /* def_idx: 1 */ { -B0: - 0: LdU64(0) - 1: StLoc[1](a: u64) -B1: - 2: CopyLoc[1](a: u64) - 3: CopyLoc[0](x: u64) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[1](a: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[1](a: u64) - 10: Branch(2) -B3: - 11: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.exp index bcc39b35499..ca13ea72518 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.exp @@ -83,14 +83,12 @@ fun m::dead($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun dead(l0: u64): u64 + move_loc l0 + ret -dead(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.opt.exp index bcc39b35499..ca13ea72518 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_1.opt.exp @@ -83,14 +83,12 @@ fun m::dead($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun dead(l0: u64): u64 + move_loc l0 + ret -dead(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.exp index 39c6a4b27b9..ca26bbacfaa 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.exp @@ -59,14 +59,12 @@ fun m::dead($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun dead(l0: u64): u64 + move_loc l0 + ret -dead(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.opt.exp index 39c6a4b27b9..ca26bbacfaa 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_2.opt.exp @@ -59,14 +59,12 @@ fun m::dead($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun dead(l0: u64): u64 + move_loc l0 + ret -dead(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.exp index c1f17adbc8c..77d22c63c4b 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.exp @@ -59,14 +59,13 @@ public fun m::test($t0: bool): u32 { var $t3: u32 0: $t2 := 1 1: $t3 := move($t2) - 2: if ($t0) goto 3 else goto 7 + 2: if ($t0) goto 3 else goto 6 3: label L0 4: $t1 := move($t3) - 5: label L2 - 6: return $t1 - 7: label L1 - 8: $t1 := 9 - 9: goto 5 + 5: return $t1 + 6: label L1 + 7: $t1 := 9 + 8: return $t1 } ============ after VariableCoalescingAnnotator: ================ @@ -84,24 +83,22 @@ public fun m::test($t0: bool): u32 { 1: $t3 := move($t2) # live vars: $t0, $t3 # events: e:$t0 - 2: if ($t0) goto 3 else goto 7 + 2: if ($t0) goto 3 else goto 6 # live vars: $t3 3: label L0 # live vars: $t3 # events: b:$t1 4: $t1 := move($t3) # live vars: $t1 - 5: label L2 - # live vars: $t1 - 6: return $t1 + 5: return $t1 # live vars: $t3 # events: e:$t3 - 7: label L1 + 6: label L1 # live vars: - 8: $t1 := 9 + 7: $t1 := 9 # live vars: $t1 # events: e:$t1 - 9: goto 5 + 8: return $t1 } ============ after VariableCoalescingTransformer: ================ @@ -113,14 +110,13 @@ public fun m::test($t0: bool): u32 { var $t3: u32 [unused] 0: $t2 := 1 1: $t2 := move($t2) - 2: if ($t0) goto 3 else goto 7 + 2: if ($t0) goto 3 else goto 6 3: label L0 4: $t1 := move($t2) - 5: label L2 - 6: return $t1 - 7: label L1 - 8: $t1 := 9 - 9: goto 5 + 5: return $t1 + 6: label L1 + 7: $t1 := 9 + 8: return $t1 } ============ after DeadStoreElimination: ================ @@ -131,40 +127,31 @@ public fun m::test($t0: bool): u32 { var $t2: u32 var $t3: u32 [unused] 0: $t2 := 1 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 2: label L0 3: $t1 := move($t2) - 4: label L2 - 5: return $t1 - 6: label L1 - 7: $t1 := 9 - 8: goto 4 + 4: return $t1 + 5: label L1 + 6: $t1 := 9 + 7: return $t1 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public test(p: bool): u32 /* def_idx: 0 */ { -L1: x: u32 -L2: return: u32 -B0: - 0: LdU32(1) - 1: StLoc[1](x: u32) - 2: MoveLoc[0](p: bool) - 3: BrFalse(8) -B1: - 4: MoveLoc[1](x: u32) - 5: StLoc[2](return: u32) -B2: - 6: MoveLoc[2](return: u32) - 7: Ret -B3: - 8: LdU32(9) - 9: StLoc[2](return: u32) - 10: Branch(6) -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: bool): u32 + local l1: u32 + ld_u32 1 + st_loc l1 + move_loc l0 + br_false l0 + move_loc l1 + // @5 + ret +l0: ld_u32 9 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.opt.exp index 75dd0280f65..6348de9c4ba 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_3.opt.exp @@ -55,14 +55,13 @@ public fun m::test($t0: bool): u32 { var $t1: u32 var $t2: u32 0: $t2 := 1 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 2: label L0 3: $t1 := move($t2) - 4: label L2 - 5: return $t1 - 6: label L1 - 7: $t1 := 9 - 8: goto 4 + 4: return $t1 + 5: label L1 + 6: $t1 := 9 + 7: return $t1 } ============ after VariableCoalescingAnnotator: ================ @@ -76,24 +75,22 @@ public fun m::test($t0: bool): u32 { 0: $t2 := 1 # live vars: $t0, $t2 # events: e:$t0 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 # live vars: $t2 2: label L0 # live vars: $t2 # events: b:$t1 3: $t1 := move($t2) # live vars: $t1 - 4: label L2 - # live vars: $t1 - 5: return $t1 + 4: return $t1 # live vars: $t2 # events: e:$t2 - 6: label L1 + 5: label L1 # live vars: - 7: $t1 := 9 + 6: $t1 := 9 # live vars: $t1 # events: e:$t1 - 8: goto 4 + 7: return $t1 } ============ after VariableCoalescingTransformer: ================ @@ -103,14 +100,13 @@ public fun m::test($t0: bool): u32 { var $t1: u32 var $t2: u32 0: $t2 := 1 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 2: label L0 3: $t1 := move($t2) - 4: label L2 - 5: return $t1 - 6: label L1 - 7: $t1 := 9 - 8: goto 4 + 4: return $t1 + 5: label L1 + 6: $t1 := 9 + 7: return $t1 } ============ after DeadStoreElimination: ================ @@ -120,40 +116,31 @@ public fun m::test($t0: bool): u32 { var $t1: u32 var $t2: u32 0: $t2 := 1 - 1: if ($t0) goto 2 else goto 6 + 1: if ($t0) goto 2 else goto 5 2: label L0 3: $t1 := move($t2) - 4: label L2 - 5: return $t1 - 6: label L1 - 7: $t1 := 9 - 8: goto 4 + 4: return $t1 + 5: label L1 + 6: $t1 := 9 + 7: return $t1 } ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public test(p: bool): u32 /* def_idx: 0 */ { -L1: y: u32 -L2: return: u32 -B0: - 0: LdU32(1) - 1: StLoc[1](y: u32) - 2: MoveLoc[0](p: bool) - 3: BrFalse(8) -B1: - 4: MoveLoc[1](y: u32) - 5: StLoc[2](return: u32) -B2: - 6: MoveLoc[2](return: u32) - 7: Ret -B3: - 8: LdU32(9) - 9: StLoc[2](return: u32) - 10: Branch(6) -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: bool): u32 + local l1: u32 + ld_u32 1 + st_loc l1 + move_loc l0 + br_false l0 + move_loc l1 + // @5 + ret +l0: ld_u32 9 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.exp index b2fbd50b0b5..63aa0502245 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.exp @@ -289,29 +289,27 @@ public fun m::test4($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(): u64 + ld_u64 3 + ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test3(l0: u64): u64 + ld_u64 8 + ret + +// Function definition at index 3 +#[persistent] public fun test4(l0: u64): u64 + ld_u64 1 + ret -public test1(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -public test2(y: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](y: u64) - 1: Ret -} -public test3(y: u64): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(8) - 1: Ret -} -public test4(y: u64): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(1) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.opt.exp index 947074f6428..6dceb278435 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/dead_assignment_4.opt.exp @@ -261,29 +261,27 @@ public fun m::test4($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(): u64 + ld_u64 3 + ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test3(l0: u64): u64 + ld_u64 8 + ret + +// Function definition at index 3 +#[persistent] public fun test4(l0: u64): u64 + ld_u64 1 + ret -public test1(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -public test2(y: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](y: u64) - 1: Ret -} -public test3(y: u64): u64 /* def_idx: 2 */ { -B0: - 0: LdU64(8) - 1: Ret -} -public test4(y: u64): u64 /* def_idx: 3 */ { -B0: - 0: LdU64(1) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.exp index d51bafd1042..f4e83e6eb28 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.exp @@ -98,15 +98,13 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + borrow_loc l0 + read_ref + ret -test(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](p: u64) - 1: ReadRef - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.opt.exp index d51bafd1042..f4e83e6eb28 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_1.opt.exp @@ -98,15 +98,13 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + borrow_loc l0 + read_ref + ret -test(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](p: u64) - 1: ReadRef - 2: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.exp index 657a06a7160..f9dc5fa4360 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.exp @@ -125,17 +125,15 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: &u64 + borrow_loc l0 + pop + move_loc l0 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: &u64 -B0: - 0: ImmBorrowLoc[0](p: u64) - 1: Pop - 2: MoveLoc[0](p: u64) - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.opt.exp index 657a06a7160..f9dc5fa4360 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/immut_refs_2.opt.exp @@ -125,17 +125,15 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: &u64 + borrow_loc l0 + pop + move_loc l0 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: &u64 -B0: - 0: ImmBorrowLoc[0](p: u64) - 1: Pop - 2: MoveLoc[0](p: u64) - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.exp index a74ec2896b7..3df3aa2e6ae 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.exp @@ -82,14 +82,12 @@ public fun Test::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 3 + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.opt.exp index 470795745ac..dd31ac5c2bb 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1.opt.exp @@ -64,14 +64,12 @@ public fun Test::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 3 + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.exp index a74ec2896b7..3df3aa2e6ae 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.exp @@ -82,14 +82,12 @@ public fun Test::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 3 + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.opt.exp index 470795745ac..dd31ac5c2bb 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/inlining1_typed.opt.exp @@ -64,14 +64,12 @@ public fun Test::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.Test { +// Bytecode version v9 +module 0x42::Test +// Function definition at index 0 +#[persistent] public fun test(): u64 + ld_u64 3 + ret -public test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.exp index 656bc227e8a..88d2f8e9600 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.exp @@ -152,23 +152,22 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(): u64 /* def_idx: 0 */ { -L0: u: u64 -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: StLoc[0](u: u64) - 3: CopyLoc[0](u: u64) - 4: Add - 5: Pop - 6: CopyLoc[0](u: u64) - 7: MoveLoc[0](u: u64) - 8: Add - 9: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + ld_u64 1 + ld_u64 2 + st_loc l0 + copy_loc l0 + add + // @5 + pop + copy_loc l0 + move_loc l0 + add + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.opt.exp index c80d87016b8..010bfa78ee1 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_1.opt.exp @@ -128,18 +128,17 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: Add - 3: Pop - 4: LdU64(4) - 5: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 1 + ld_u64 2 + add + pop + ld_u64 4 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.exp index ee7fc05fc85..887a92f0118 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.exp @@ -163,22 +163,21 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + local l1: u64 + ld_u64 1 + ld_u64 1 + add + st_loc l1 + ld_u64 2 + // @5 + move_loc l1 + add + ret -test(): u64 /* def_idx: 0 */ { -L0: u: u64 -L1: t: u64 -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: StLoc[1](t: u64) - 4: LdU64(2) - 5: MoveLoc[1](t: u64) - 6: Add - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.opt.exp index 171522297b1..57c164e1792 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_2.opt.exp @@ -140,21 +140,20 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + ld_u64 1 + ld_u64 1 + add + st_loc l0 + ld_u64 2 + // @5 + move_loc l0 + add + ret -test(): u64 /* def_idx: 0 */ { -L0: t: u64 -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: StLoc[0](t: u64) - 4: LdU64(2) - 5: MoveLoc[0](t: u64) - 6: Add - 7: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.exp index c842e2516ab..7af07b7a523 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.exp @@ -150,19 +150,18 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(): u64 /* def_idx: 0 */ { -L0: u: u64 -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + ld_u64 1 + ld_u64 1 + add + pop + ld_u64 2 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.opt.exp index 882d2c3188e..fc7f69c6273 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/intermingled_3.opt.exp @@ -128,18 +128,17 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 1 + ld_u64 1 + add + pop + ld_u64 2 + // @5 + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.exp index 1dad28cad4c..fc3368d415e 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.exp @@ -229,34 +229,32 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: u64 + ld_u64 0 + st_loc l1 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + // @5 + ld_u64 10 + lt + br_false l0 + copy_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + add + st_loc l2 + branch l1 + // @15 +l0: move_loc l1 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -L2: count: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](a: u64) - 2: LdU64(0) - 3: StLoc[2](count: u64) -B1: - 4: CopyLoc[2](count: u64) - 5: LdU64(10) - 6: Lt - 7: BrFalse(15) -B2: - 8: CopyLoc[0](p: u64) - 9: StLoc[1](a: u64) - 10: MoveLoc[2](count: u64) - 11: LdU64(1) - 12: Add - 13: StLoc[2](count: u64) - 14: Branch(4) -B3: - 15: MoveLoc[1](a: u64) - 16: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.opt.exp index 1dad28cad4c..fc3368d415e 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_1.opt.exp @@ -229,34 +229,32 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: u64 + ld_u64 0 + st_loc l1 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + // @5 + ld_u64 10 + lt + br_false l0 + copy_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + add + st_loc l2 + branch l1 + // @15 +l0: move_loc l1 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -L2: count: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](a: u64) - 2: LdU64(0) - 3: StLoc[2](count: u64) -B1: - 4: CopyLoc[2](count: u64) - 5: LdU64(10) - 6: Lt - 7: BrFalse(15) -B2: - 8: CopyLoc[0](p: u64) - 9: StLoc[1](a: u64) - 10: MoveLoc[2](count: u64) - 11: LdU64(1) - 12: Add - 13: StLoc[2](count: u64) - 14: Branch(4) -B3: - 15: MoveLoc[1](a: u64) - 16: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.exp index f3dea91d227..5554de500b7 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.exp @@ -229,34 +229,32 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + // @5 + ld_u64 10 + lt + br_false l0 + copy_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + add + st_loc l2 + branch l1 + // @15 +l0: move_loc l1 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -L2: count: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: LdU64(0) - 3: StLoc[2](count: u64) -B1: - 4: CopyLoc[2](count: u64) - 5: LdU64(10) - 6: Lt - 7: BrFalse(15) -B2: - 8: CopyLoc[0](p: u64) - 9: StLoc[1](a: u64) - 10: MoveLoc[2](count: u64) - 11: LdU64(1) - 12: Add - 13: StLoc[2](count: u64) - 14: Branch(4) -B3: - 15: MoveLoc[1](a: u64) - 16: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.opt.exp index f3dea91d227..5554de500b7 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/loop_2.opt.exp @@ -229,34 +229,32 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + ld_u64 0 + st_loc l2 +l1: copy_loc l2 + // @5 + ld_u64 10 + lt + br_false l0 + copy_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + add + st_loc l2 + branch l1 + // @15 +l0: move_loc l1 + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -L2: count: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: LdU64(0) - 3: StLoc[2](count: u64) -B1: - 4: CopyLoc[2](count: u64) - 5: LdU64(10) - 6: Lt - 7: BrFalse(15) -B2: - 8: CopyLoc[0](p: u64) - 9: StLoc[1](a: u64) - 10: MoveLoc[2](count: u64) - 11: LdU64(1) - 12: Add - 13: StLoc[2](count: u64) - 14: Branch(4) -B3: - 15: MoveLoc[1](a: u64) - 16: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.exp index 22801a3735c..64f1c8cf361 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.exp @@ -94,14 +94,12 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 2 + ret -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(2) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.opt.exp index 22801a3735c..64f1c8cf361 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/multi_assigns.opt.exp @@ -94,14 +94,12 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 2 + ret -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(2) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.exp index 8c2e9962846..640e3149358 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.exp @@ -107,21 +107,20 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: &mut u64 + copy_loc l0 + mut_borrow_loc l0 + st_loc l2 + ld_u64 1 + move_loc l2 + // @5 + write_ref + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: $t4: u64 -L2: b: &mut u64 -B0: - 0: CopyLoc[0](p: u64) - 1: MutBorrowLoc[0](p: u64) - 2: StLoc[2](b: &mut u64) - 3: LdU64(1) - 4: MoveLoc[2](b: &mut u64) - 5: WriteRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.opt.exp index 8c2e9962846..640e3149358 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_1.opt.exp @@ -107,21 +107,20 @@ fun m::test($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): u64 + local l1: u64 + local l2: &mut u64 + copy_loc l0 + mut_borrow_loc l0 + st_loc l2 + ld_u64 1 + move_loc l2 + // @5 + write_ref + ret -test(p: u64): u64 /* def_idx: 0 */ { -L1: $t4: u64 -L2: b: &mut u64 -B0: - 0: CopyLoc[0](p: u64) - 1: MutBorrowLoc[0](p: u64) - 2: StLoc[2](b: &mut u64) - 3: LdU64(1) - 4: MoveLoc[2](b: &mut u64) - 5: WriteRef - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.exp index 231865369b8..d1104e892ec 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.exp @@ -163,33 +163,34 @@ fun m::test($t0: 0xc0ffee::m::S): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has copy, drop { - a: u64, - b: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has copy + drop + a: u64 + b: u64 + +// Function definition at index 0 +fun test(l0: S): u64 + local l1: S + local l2: S + local l3: u64 + local l4: &mut u64 + move_loc l0 + st_loc l1 + copy_loc l1 + st_loc l2 + mut_borrow_loc l1 + // @5 + mut_borrow_field S, a + st_loc l4 + ld_u64 0 + move_loc l4 + write_ref + // @10 + borrow_loc l2 + borrow_field S, a + read_ref + ret + -test(s: S): u64 /* def_idx: 0 */ { -L1: p: S -L2: q: S -L3: $t6: u64 -L4: ref: &mut u64 -B0: - 0: MoveLoc[0](s: S) - 1: StLoc[1](p: S) - 2: CopyLoc[1](p: S) - 3: StLoc[2](q: S) - 4: MutBorrowLoc[1](p: S) - 5: MutBorrowField[0](S.a: u64) - 6: StLoc[4](ref: &mut u64) - 7: LdU64(0) - 8: MoveLoc[4](ref: &mut u64) - 9: WriteRef - 10: ImmBorrowLoc[2](q: S) - 11: ImmBorrowField[0](S.a: u64) - 12: ReadRef - 13: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.opt.exp index 231865369b8..d1104e892ec 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/mut_refs_2.opt.exp @@ -163,33 +163,34 @@ fun m::test($t0: 0xc0ffee::m::S): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct S has copy, drop { - a: u64, - b: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct S has copy + drop + a: u64 + b: u64 + +// Function definition at index 0 +fun test(l0: S): u64 + local l1: S + local l2: S + local l3: u64 + local l4: &mut u64 + move_loc l0 + st_loc l1 + copy_loc l1 + st_loc l2 + mut_borrow_loc l1 + // @5 + mut_borrow_field S, a + st_loc l4 + ld_u64 0 + move_loc l4 + write_ref + // @10 + borrow_loc l2 + borrow_field S, a + read_ref + ret + -test(s: S): u64 /* def_idx: 0 */ { -L1: p: S -L2: q: S -L3: $t6: u64 -L4: ref: &mut u64 -B0: - 0: MoveLoc[0](s: S) - 1: StLoc[1](p: S) - 2: CopyLoc[1](p: S) - 3: StLoc[2](q: S) - 4: MutBorrowLoc[1](p: S) - 5: MutBorrowField[0](S.a: u64) - 6: StLoc[4](ref: &mut u64) - 7: LdU64(0) - 8: MoveLoc[4](ref: &mut u64) - 9: WriteRef - 10: ImmBorrowLoc[2](q: S) - 11: ImmBorrowField[0](S.a: u64) - 12: ReadRef - 13: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.exp index 5a48abe43aa..7f3a6b4b0da 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.exp @@ -173,21 +173,20 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test() /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: LdU64(1) - 6: Add - 7: Pop - 8: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + ld_u64 1 + ld_u64 1 + add + pop + ld_u64 2 + // @5 + ld_u64 1 + add + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.opt.exp index 5a48abe43aa..7f3a6b4b0da 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars1.opt.exp @@ -173,21 +173,20 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test() /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: LdU64(1) - 6: Add - 7: Pop - 8: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + ld_u64 1 + ld_u64 1 + add + pop + ld_u64 2 + // @5 + ld_u64 1 + add + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.exp index b450ae992ad..482dc24ec3b 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.exp @@ -173,21 +173,20 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test() /* def_idx: 0 */ { -B0: - 0: LdU32(1) - 1: LdU32(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: LdU64(1) - 6: Add - 7: Pop - 8: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + ld_u32 1 + ld_u32 1 + add + pop + ld_u64 2 + // @5 + ld_u64 1 + add + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.opt.exp index b450ae992ad..482dc24ec3b 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/non_overlapping_vars_diff_type.opt.exp @@ -173,21 +173,20 @@ fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test() /* def_idx: 0 */ { -B0: - 0: LdU32(1) - 1: LdU32(1) - 2: Add - 3: Pop - 4: LdU64(2) - 5: LdU64(1) - 6: Add - 7: Pop - 8: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test() + ld_u32 1 + ld_u32 1 + add + pop + ld_u64 2 + // @5 + ld_u64 1 + add + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.exp index 56236376f0d..a6e287065cc 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.exp @@ -128,21 +128,20 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + local l1: u64 + local l2: u64 + ld_u64 1 + ld_u64 2 + add + ld_u64 3 + add + // @5 + ret -test(): u64 /* def_idx: 0 */ { -L0: z: u64 -L1: y: u64 -L2: x: u64 -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: Add - 3: LdU64(3) - 4: Add - 5: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.opt.exp index a11e992b931..dc7eb5a03c7 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/overlapping_vars.opt.exp @@ -68,14 +68,12 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 6 + ret -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(6) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.exp index 4eb01851c64..cd590ea1406 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.exp @@ -123,17 +123,15 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + local l0: u64 + ld_u64 9 + ld_u64 2 + add + ret -test(): u64 /* def_idx: 0 */ { -L0: b: u64 -B0: - 0: LdU64(9) - 1: LdU64(2) - 2: Add - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.opt.exp index a0d45a39698..36c52470b2c 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/reassigned_var.opt.exp @@ -123,16 +123,14 @@ fun m::test(): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(): u64 + ld_u64 9 + ld_u64 2 + add + ret -test(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(9) - 1: LdU64(2) - 2: Add - 3: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.exp index 25819f17a35..fd38a2d1f94 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.exp @@ -529,61 +529,57 @@ public fun m::test4($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(l0: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test3(): u64 + local l0: u64 + local l1: u64 + ld_u64 0 + st_loc l0 + ld_u64 1 + st_loc l1 +l1: copy_loc l0 + // @5 + ld_u64 42 + lt + br_false l0 + move_loc l0 + ld_u64 1 + // @10 + add + st_loc l0 + branch l1 +l0: move_loc l1 + ret + +// Function definition at index 3 +#[persistent] public fun test4(l0: u64): u64 + local l1: u64 + ld_u64 0 + st_loc l1 +l1: copy_loc l1 + ld_u64 42 + lt + // @5 + br_false l0 + move_loc l1 + ld_u64 1 + add + st_loc l1 + // @10 + branch l1 +l0: move_loc l0 + ret -public test1(x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test2(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -public test3(): u64 /* def_idx: 2 */ { -L0: i: u64 -L1: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](i: u64) - 2: LdU64(1) - 3: StLoc[1](x: u64) -B1: - 4: CopyLoc[0](i: u64) - 5: LdU64(42) - 6: Lt - 7: BrFalse(13) -B2: - 8: MoveLoc[0](i: u64) - 9: LdU64(1) - 10: Add - 11: StLoc[0](i: u64) - 12: Branch(4) -B3: - 13: MoveLoc[1](x: u64) - 14: Ret -} -public test4(x: u64): u64 /* def_idx: 3 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: LdU64(42) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[1](i: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[1](i: u64) - 10: Branch(2) -B3: - 11: MoveLoc[0](x: u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.opt.exp index 25819f17a35..fd38a2d1f94 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/self_assigns.opt.exp @@ -529,61 +529,57 @@ public fun m::test4($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test1(l0: u64) + ret + +// Function definition at index 1 +#[persistent] public fun test2(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 2 +#[persistent] public fun test3(): u64 + local l0: u64 + local l1: u64 + ld_u64 0 + st_loc l0 + ld_u64 1 + st_loc l1 +l1: copy_loc l0 + // @5 + ld_u64 42 + lt + br_false l0 + move_loc l0 + ld_u64 1 + // @10 + add + st_loc l0 + branch l1 +l0: move_loc l1 + ret + +// Function definition at index 3 +#[persistent] public fun test4(l0: u64): u64 + local l1: u64 + ld_u64 0 + st_loc l1 +l1: copy_loc l1 + ld_u64 42 + lt + // @5 + br_false l0 + move_loc l1 + ld_u64 1 + add + st_loc l1 + // @10 + branch l1 +l0: move_loc l0 + ret -public test1(x: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -public test2(x: u64): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](x: u64) - 1: Ret -} -public test3(): u64 /* def_idx: 2 */ { -L0: i: u64 -L1: x: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](i: u64) - 2: LdU64(1) - 3: StLoc[1](x: u64) -B1: - 4: CopyLoc[0](i: u64) - 5: LdU64(42) - 6: Lt - 7: BrFalse(13) -B2: - 8: MoveLoc[0](i: u64) - 9: LdU64(1) - 10: Add - 11: StLoc[0](i: u64) - 12: Branch(4) -B3: - 13: MoveLoc[1](x: u64) - 14: Ret -} -public test4(x: u64): u64 /* def_idx: 3 */ { -L1: i: u64 -B0: - 0: LdU64(0) - 1: StLoc[1](i: u64) -B1: - 2: CopyLoc[1](i: u64) - 3: LdU64(42) - 4: Lt - 5: BrFalse(11) -B2: - 6: MoveLoc[1](i: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[1](i: u64) - 10: Branch(2) -B3: - 11: MoveLoc[0](x: u64) - 12: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.exp index 5bff9f9eb8e..2230636dae4 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.exp @@ -165,26 +165,26 @@ fun m::test($t0: u64): bool { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(p: u64): bool /* def_idx: 0 */ { -L1: a: u64 -L2: b: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: StLoc[2](b: u64) - 8: MoveLoc[1](a: u64) - 9: MoveLoc[2](b: u64) - 10: Eq - 11: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): bool + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + st_loc l2 + move_loc l1 + move_loc l2 + // @10 + eq + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.opt.exp index 5bff9f9eb8e..2230636dae4 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_1.opt.exp @@ -165,26 +165,26 @@ fun m::test($t0: u64): bool { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(p: u64): bool /* def_idx: 0 */ { -L1: a: u64 -L2: b: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: StLoc[2](b: u64) - 8: MoveLoc[1](a: u64) - 9: MoveLoc[2](b: u64) - 10: Eq - 11: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): bool + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + st_loc l2 + move_loc l1 + move_loc l2 + // @10 + eq + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.exp index ccc8225199c..9eceae04e66 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.exp @@ -165,26 +165,26 @@ fun m::test($t0: u64): bool { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(p: u64): bool /* def_idx: 0 */ { -L1: a: u64 -L2: c: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: StLoc[2](c: u64) - 8: MoveLoc[1](a: u64) - 9: MoveLoc[2](c: u64) - 10: Eq - 11: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): bool + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + st_loc l2 + move_loc l1 + move_loc l2 + // @10 + eq + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.opt.exp index ccc8225199c..9eceae04e66 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/seq_kills_2.opt.exp @@ -165,26 +165,26 @@ fun m::test($t0: u64): bool { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -test(p: u64): bool /* def_idx: 0 */ { -L1: a: u64 -L2: c: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: StLoc[2](c: u64) - 8: MoveLoc[1](a: u64) - 9: MoveLoc[2](c: u64) - 10: Eq - 11: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun test(l0: u64): bool + local l1: u64 + local l2: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + st_loc l2 + move_loc l1 + move_loc l2 + // @10 + eq + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.exp index 69d8e8b7aa6..a2ec89b3c3d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.exp @@ -122,20 +122,19 @@ fun m::sequential($t0: 0xc0ffee::m::Foo): 0xc0ffee::m::Foo { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct Foo has copy { - a: u64, - b: u64, - c: u64, - d: u64, - e: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct Foo has copy + a: u64 + b: u64 + c: u64 + d: u64 + e: u64 + +// Function definition at index 0 +fun sequential(l0: Foo): Foo + move_loc l0 + ret + -sequential(p: Foo): Foo /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: Foo) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.opt.exp index 69d8e8b7aa6..a2ec89b3c3d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/sequential_assign_struct.opt.exp @@ -122,20 +122,19 @@ fun m::sequential($t0: 0xc0ffee::m::Foo): 0xc0ffee::m::Foo { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { -struct Foo has copy { - a: u64, - b: u64, - c: u64, - d: u64, - e: u64 -} +// Bytecode version v9 +module 0xc0ffee::m +struct Foo has copy + a: u64 + b: u64 + c: u64 + d: u64 + e: u64 + +// Function definition at index 0 +fun sequential(l0: Foo): Foo + move_loc l0 + ret + -sequential(p: Foo): Foo /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: Foo) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.exp index a65af63fc62..e5a0ec97d7f 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.exp @@ -122,14 +122,12 @@ fun m::sequential($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun sequential(l0: u64): u64 + move_loc l0 + ret -sequential(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.opt.exp index a65af63fc62..e5a0ec97d7f 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/simple_sequential_assign.opt.exp @@ -122,14 +122,12 @@ fun m::sequential($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun sequential(l0: u64): u64 + move_loc l0 + ret -sequential(p: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](p: u64) - 1: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.exp index aa52a516bb7..3744eba6df3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.exp @@ -152,23 +152,22 @@ fun m::copy_kill($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -copy_kill(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: MoveLoc[1](a: u64) - 8: Add - 9: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun copy_kill(l0: u64): u64 + local l1: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + move_loc l1 + add + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.opt.exp index aa52a516bb7..3744eba6df3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/straight_line_kills.opt.exp @@ -152,23 +152,22 @@ fun m::copy_kill($t0: u64): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -copy_kill(p: u64): u64 /* def_idx: 0 */ { -L1: a: u64 -B0: - 0: CopyLoc[0](p: u64) - 1: StLoc[1](a: u64) - 2: CopyLoc[1](a: u64) - 3: MoveLoc[0](p: u64) - 4: LdU64(1) - 5: Add - 6: Pop - 7: MoveLoc[1](a: u64) - 8: Add - 9: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun copy_kill(l0: u64): u64 + local l1: u64 + copy_loc l0 + st_loc l1 + copy_loc l1 + move_loc l0 + ld_u64 1 + // @5 + add + pop + move_loc l1 + add + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.exp index 6bc78b3c74b..b76376d65b3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.exp @@ -100,20 +100,19 @@ public fun m::test($t0: u64, $t1: u64): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64, l1: u64): (u64, u64) + local l2: u64 + move_loc l0 + move_loc l1 + st_loc l0 + st_loc l1 + move_loc l0 + // @5 + move_loc l1 + ret -public test(x: u64, y: u64): u64 * u64 /* def_idx: 0 */ { -L2: t: u64 -B0: - 0: MoveLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: StLoc[0](x: u64) - 3: StLoc[1](y: u64) - 4: MoveLoc[0](x: u64) - 5: MoveLoc[1](y: u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.opt.exp index 6bc78b3c74b..b76376d65b3 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap.opt.exp @@ -100,20 +100,19 @@ public fun m::test($t0: u64, $t1: u64): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64, l1: u64): (u64, u64) + local l2: u64 + move_loc l0 + move_loc l1 + st_loc l0 + st_loc l1 + move_loc l0 + // @5 + move_loc l1 + ret -public test(x: u64, y: u64): u64 * u64 /* def_idx: 0 */ { -L2: t: u64 -B0: - 0: MoveLoc[0](x: u64) - 1: MoveLoc[1](y: u64) - 2: StLoc[0](x: u64) - 3: StLoc[1](y: u64) - 4: MoveLoc[0](x: u64) - 5: MoveLoc[1](y: u64) - 6: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.exp index cf704aaad92..7af2cab5f1d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.exp @@ -251,34 +251,32 @@ public fun m::test($t0: u64, $t1: u64): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64, l1: u64): (u64, u64) + local l2: u64 + copy_loc l0 + st_loc l2 +l1: copy_loc l2 + ld_u64 0 + gt + // @5 + br_false l0 + move_loc l0 + move_loc l1 + st_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + sub + st_loc l2 + branch l1 + // @15 +l0: move_loc l0 + move_loc l1 + ret -public test(x: u64, y: u64): u64 * u64 /* def_idx: 0 */ { -L2: i: u64 -B0: - 0: CopyLoc[0](x: u64) - 1: StLoc[2](i: u64) -B1: - 2: CopyLoc[2](i: u64) - 3: LdU64(0) - 4: Gt - 5: BrFalse(15) -B2: - 6: MoveLoc[0](x: u64) - 7: MoveLoc[1](y: u64) - 8: StLoc[0](x: u64) - 9: StLoc[1](y: u64) - 10: MoveLoc[2](i: u64) - 11: LdU64(1) - 12: Sub - 13: StLoc[2](i: u64) - 14: Branch(2) -B3: - 15: MoveLoc[0](x: u64) - 16: MoveLoc[1](y: u64) - 17: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.opt.exp index cf704aaad92..7af2cab5f1d 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/swap_in_a_loop.opt.exp @@ -251,34 +251,32 @@ public fun m::test($t0: u64, $t1: u64): (u64, u64) { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test(l0: u64, l1: u64): (u64, u64) + local l2: u64 + copy_loc l0 + st_loc l2 +l1: copy_loc l2 + ld_u64 0 + gt + // @5 + br_false l0 + move_loc l0 + move_loc l1 + st_loc l0 + st_loc l1 + // @10 + move_loc l2 + ld_u64 1 + sub + st_loc l2 + branch l1 + // @15 +l0: move_loc l0 + move_loc l1 + ret -public test(x: u64, y: u64): u64 * u64 /* def_idx: 0 */ { -L2: i: u64 -B0: - 0: CopyLoc[0](x: u64) - 1: StLoc[2](i: u64) -B1: - 2: CopyLoc[2](i: u64) - 3: LdU64(0) - 4: Gt - 5: BrFalse(15) -B2: - 6: MoveLoc[0](x: u64) - 7: MoveLoc[1](y: u64) - 8: StLoc[0](x: u64) - 9: StLoc[1](y: u64) - 10: MoveLoc[2](i: u64) - 11: LdU64(1) - 12: Sub - 13: StLoc[2](i: u64) - 14: Branch(2) -B3: - 15: MoveLoc[0](x: u64) - 16: MoveLoc[1](y: u64) - 17: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.exp index c2b64f584f5..37a3f540783 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.exp @@ -107,19 +107,17 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { - - -public test() /* def_idx: 0 */ { -L0: y: u64 -L1: x: u64 -B0: - 0: LdU64(1) - 1: LdU64(2) - 2: Add - 3: Pop - 4: Ret -} -} +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test() + local l0: u64 + local l1: u64 + ld_u64 1 + ld_u64 2 + add + pop + ret + + ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.opt.exp b/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.opt.exp index 9da25367999..2827c7b9f37 100644 --- a/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.opt.exp +++ b/third_party/move/move-compiler-v2/tests/variable-coalescing/unused_add.opt.exp @@ -59,13 +59,11 @@ public fun m::test() { ============ disassembled file-format ================== -// Move bytecode v8 -module c0ffee.m { +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +#[persistent] public fun test() + ret -public test() /* def_idx: 0 */ { -B0: - 0: Ret -} -} ============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/visibility-checker/inline_with_warning_07.exp b/third_party/move/move-compiler-v2/tests/visibility-checker/inline_with_warning_07.exp index bfbb0e0bb38..488dc222573 100644 --- a/third_party/move/move-compiler-v2/tests/visibility-checker/inline_with_warning_07.exp +++ b/third_party/move/move-compiler-v2/tests/visibility-checker/inline_with_warning_07.exp @@ -133,6 +133,6 @@ module 0xc0ffee::o { f: u64, } public inline fun my_borrow(): &R { - borrow_global(0xc0ffee) + borrow_global(@0xc0ffee) } } diff --git a/third_party/move/move-compiler-v2/tests/visibility-checker/v1-typing/module_call_visibility_friend.exp b/third_party/move/move-compiler-v2/tests/visibility-checker/v1-typing/module_call_visibility_friend.exp index ce99185267e..e74f658ed36 100644 --- a/third_party/move/move-compiler-v2/tests/visibility-checker/v1-typing/module_call_visibility_friend.exp +++ b/third_party/move/move-compiler-v2/tests/visibility-checker/v1-typing/module_call_visibility_friend.exp @@ -61,8 +61,8 @@ module 0x2::X { } } module 0x2::M { - use 0x2::Y; use 0x2::X; + use 0x2::Y; friend fun f_friend() { } public fun f_public() { diff --git a/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml b/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml index 239bfa8407b..f52b5522bfe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml +++ b/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml @@ -3,7 +3,7 @@ name = "move-compiler-v2-transactional-tests" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dev-dependencies] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.exp new file mode 100644 index 00000000000..a21bb5fd207 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.exp @@ -0,0 +1,6 @@ +processed 5 tasks +task 0 lines 1-30: publish [module 0x66::m {] +task 1 lines 32-32: run 0x66::m::compile_for_testing +task 2 lines 34-34: run 0x66::m::min_max +task 3 lines 36-43: publish [module 0x66::shadow {] +task 4 lines 45-45: run 0x66::shadow::shadowed diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.move b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.move new file mode 100644 index 00000000000..ebaac2e7288 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/builtin_constants.move @@ -0,0 +1,45 @@ +//# publish +module 0x66::m { + fun compile_for_testing() { + // We are NOT compiling for testing, so expect this to be false. See independent + // compile_for_testing test. + assert!(!__COMPILE_FOR_TESTING__, 66); + } + + fun min_max() { + assert!(MAX_U8 == 255, 1); + assert!(MAX_U16 == 65535, 1); + assert!(MAX_U32 == 4294967295, 1); + assert!(MAX_U64 == 18446744073709551615, 1); + assert!(MAX_U128 == 340282366920938463463374607431768211455, 1); + assert!(MAX_U256 == 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + + assert!(MIN_I8 == -128, 1); + assert!(MAX_I8 == 127, 1); + assert!(MIN_I16 == -32768, 1); + assert!(MAX_I16 == 32767, 1); + assert!(MIN_I32 == -2147483648, 1); + assert!(MAX_I32 == 2147483647, 1); + assert!(MIN_I64 == -9223372036854775808, 1); + assert!(MAX_I64 == 9223372036854775807, 1); + assert!(MIN_I128 == -170141183460469231731687303715884105728, 1); + assert!(MAX_I128 == 170141183460469231731687303715884105727, 1); + assert!(MIN_I256 == -57896044618658097711785492504343953926634992332820282019728792003956564819968, 1); + assert!(MAX_I256 == 57896044618658097711785492504343953926634992332820282019728792003956564819967, 1); + } +} + +//# run 0x66::m::compile_for_testing + +//# run 0x66::m::min_max + +//# publish +module 0x66::shadow { + const MAX_U8: bool = false; + + fun shadowed() { + assert!(!MAX_U8, 66); + } +} + +//# run 0x66::shadow::shadowed diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/by_reference.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/by_reference.exp index 6cd67db3f64..1408ba7ee24 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/by_reference.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/by_reference.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-25: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/default_int_size.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/default_int_size.exp index 17075e0a97b..c5564df18e1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/default_int_size.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/default_int_size.exp @@ -1,6 +1,8 @@ processed 4 tasks - -task 3 'run'. lines 40-53: +task 0 lines 1-12: run [script {] +task 1 lines 14-25: run [script {] +task 2 lines 27-38: run [script {] +task 3 lines 40-53: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_tvectors.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_tvectors.exp index 5d92c423f3f..ab06f34d1b4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_tvectors.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_tvectors.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-15: publish [module 0x42::m {] +task 1 lines 17-17: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors.exp index 5d92c423f3f..a908f0a4b50 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::m {] +task 1 lines 13-13: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors2.exp index 5d92c423f3f..a908f0a4b50 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/empty_vectors2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::m {] +task 1 lines 13-13: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_boolean.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_boolean.exp index 6cd67db3f64..79ac8e4b6d5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_boolean.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_boolean.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-34: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_complex.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_complex.exp index 6cd67db3f64..da2b58c2277 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_complex.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_complex.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-103: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_equality.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_equality.exp index 6cd67db3f64..cb9b3ebe288 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_equality.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_equality.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-72: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_numeric.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_numeric.exp index 6cd67db3f64..6e5b11d32dd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_numeric.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_numeric.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-198: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_values.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_values.exp index 6cd67db3f64..624e38dacad 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_values.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_values.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-26: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector.exp index 5d92c423f3f..0e33da4e1d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0x42::M {] +task 1 lines 18-18: run 0x42::M::foo diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector_large.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector_large.exp index 6cd67db3f64..89ce0f17a0a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector_large.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/folding_vector_large.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-165: publish [module 0x42::M {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.baseline.exp index 22ff5138447..dd9f61a3008 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.baseline.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::large_vec_1 return values: 1027 - -task 2 'run'. lines 19-19: +task 2 lines 19-19: run 0xc0ffee::m::large_vec_2 return values: 1025 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp index ab002de457e..9d8fea1d094 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp @@ -1,17 +1,17 @@ processed 3 tasks - -task 0 'publish'. lines 1-15: +task 0 lines 1-15: publish [module 0xc0ffee::m {] Error: compilation errors: - bug: bytecode verification failed with unexpected status code `VALUE_STACK_OVERFLOW`. This is a compiler bug, consider reporting it. + bug: bytecode verification failed with unexpected status code `VALUE_STACK_OVERFLOW`: Error message: none ┌─ TEMPFILE:5:24 │ 5 │ let v = vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026]; │ ^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) - -task 1 'run'. lines 17-17: +task 1 lines 17-17: run 0xc0ffee::m::large_vec_1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -19,8 +19,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 19-19: +task 2 lines 19-19: run 0xc0ffee::m::large_vec_2 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.opt-extra.exp new file mode 100644 index 00000000000..dd9f61a3008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.opt-extra.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::large_vec_1 +return values: 1027 +task 2 lines 19-19: run 0xc0ffee::m::large_vec_2 +return values: 1025 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.optimize.exp index 22ff5138447..dd9f61a3008 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.optimize.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::large_vec_1 return values: 1027 - -task 2 'run'. lines 19-19: +task 2 lines 19-19: run 0xc0ffee::m::large_vec_2 return values: 1025 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/non_constant_empty_vec.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/non_constant_empty_vec.exp index 9c5bad711c4..9ee1856d8bd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/non_constant_empty_vec.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/non_constant_empty_vec.exp @@ -1,22 +1,16 @@ processed 8 tasks - -task 1 'run'. lines 33-33: +task 0 lines 1-31: publish [// These vectors should not be made constants] +task 1 lines 33-33: run 0x42::M::empty_struct_vec return values: [] - -task 2 'run'. lines 35-35: +task 2 lines 35-35: run 0x42::M::empty_struct_vec return values: [] - -task 3 'run'. lines 37-37: +task 3 lines 37-37: run 0x42::M::empty_signer_vec return values: [] - -task 4 'run'. lines 39-39: +task 4 lines 39-39: run 0x42::M::empty_generic_vec --type-args 0x42::M::S return values: [] - -task 5 'run'. lines 41-41: +task 5 lines 41-41: run 0x42::M::empty_struct_vec_vec return values: [] - -task 6 'run'. lines 43-43: +task 6 lines 43-43: run 0x42::M::empty_signer_vec_vec return values: [] - -task 7 'run'. lines 45-45: +task 7 lines 45-45: run 0x42::M::empty_generic_vec_vec --type-args 0x42::M::S return values: [] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_tvectors.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_tvectors.exp index 5d92c423f3f..779b4f1f916 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_tvectors.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_tvectors.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-15: publish [module 0x42::m {] +task 1 lines 16-16: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_vectors.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_vectors.exp index 5d92c423f3f..a908f0a4b50 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_vectors.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/nonempty_vectors.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::m {] +task 1 lines 13-13: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled new file mode 100644 index 00000000000..e91eff8706d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/builtin_constants.move` + +//# publish +module 0x66::m { + fun compile_for_testing() { + () + } + fun min_max() { + () + } +} + + +//# run 0x66::m::compile_for_testing + +//# run 0x66::m::min_max + +//# publish +module 0x66::shadow { + fun shadowed() { + () + } +} + + +//# run 0x66::shadow::shadowed \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled.baseline.exp new file mode 100644 index 00000000000..61fc61d75c5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/builtin_constants.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 5 tasks +task 0 lines 3-11: publish [module 0x66::m {] +task 1 lines 14-14: run 0x66::m::compile_for_testing +task 2 lines 16-16: run 0x66::m::min_max +task 3 lines 18-23: publish [module 0x66::shadow {] +task 4 lines 26-26: run 0x66::shadow::shadowed diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled new file mode 100644 index 00000000000..09864251aa8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/by_reference.move` + +//# run +script { + fun main() { + assert!(0 == 0, 42); + assert!(vector[104u8, 101u8, 108u8, 108u8, 111u8] == vector[104u8, 101u8, 108u8, 108u8, 111u8], 42); + let _v0 = 0; + let _v1 = &mut _v0; + *_v1 = 1; + let _v2 = vector[104u8, 101u8, 108u8, 108u8, 111u8]; + let _v3 = &mut _v2; + *_v3 = vector[98u8, 121u8, 101u8]; + assert!(*_v1 == 1, 42); + assert!(*_v3 == vector[98u8, 121u8, 101u8], 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled.baseline.exp new file mode 100644 index 00000000000..95503281748 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/by_reference.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled new file mode 100644 index 00000000000..28baa2bf5d9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled @@ -0,0 +1,52 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/default_int_size.move` + +//# run +script { + fun main() { + let _v0 = 1; + let _v1 = 1; + while (_v1 < 64) { + _v0 = 2 * _v0; + _v1 = _v1 + 1 + }; + } +} + + +//# run +script { + fun main() { + let _v0 = 256; + let _v1 = 1; + while (_v1 < 56) { + _v0 = 2 * _v0; + _v1 = _v1 + 1 + }; + } +} + + +//# run +script { + fun main() { + let _v0 = 65536; + let _v1 = 1; + while (_v1 < 48) { + _v0 = 2 * _v0; + _v1 = _v1 + 1 + }; + } +} + + +//# run +script { + fun main() { + let _v0 = 1; + let _v1 = 1; + while (_v1 < 65) { + _v0 = 2 * _v0; + _v1 = _v1 + 1 + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled.baseline.exp new file mode 100644 index 00000000000..ab319643219 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/default_int_size.decompiled.baseline.exp @@ -0,0 +1,12 @@ +processed 4 tasks +task 0 lines 3-13: run [script {] +task 1 lines 16-26: run [script {] +task 2 lines 29-39: run [script {] +task 3 lines 42-52: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled new file mode 100644 index 00000000000..24fe31ffbdf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled @@ -0,0 +1,35 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/empty_tvectors.move` + +//# publish +module 0x42::m { + use 0x1::string; + use 0x1::vector; + use 0x1::bcs; + public entry fun init() { + let _v0; + let _v1 = vector::empty(); + let _v2 = vector::empty>(); + vector::reverse>(&mut _v2); + while (!vector::is_empty>(&_v2)) { + _v0 = vector::pop_back>(&mut _v2); + let _v3 = &mut _v1; + let _v4 = string::utf8(_v0); + vector::push_back(_v3, _v4); + continue + }; + let _v5 = vector::empty>(); + let _v6 = vector::empty(); + vector::reverse(&mut _v6); + while (!vector::is_empty(&_v6)) { + let _v7 = vector::pop_back(&mut _v6); + let _v8 = &mut _v5; + let _v9 = _v7; + _v0 = bcs::to_bytes(&_v9); + vector::push_back>(_v8, _v0); + continue + }; + } +} + + +//# run 0x42::m::init \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled.baseline.exp new file mode 100644 index 00000000000..a65f36fb3c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_tvectors.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-32: publish [module 0x42::m {] +task 1 lines 35-35: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled new file mode 100644 index 00000000000..7ab057581e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled @@ -0,0 +1,34 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/empty_vectors.move` + +//# publish +module 0x42::m { + use 0x1::vector; + public entry fun init() { + let _v0; + let _v1; + let _v2 = vector::empty(); + let _v3 = vector::empty>(); + vector::reverse>(&mut _v3); + while (!vector::is_empty>(&_v3)) { + let _v4 = vector::pop_back>(&mut _v3); + _v1 = &mut _v2; + let _v5 = _v4; + _v0 = vector::length(&_v5) + 2; + vector::push_back(_v1, _v0); + continue + }; + let _v6 = vector::empty(); + let _v7 = vector::empty(); + vector::reverse(&mut _v7); + while (!vector::is_empty(&_v7)) { + let _v8 = vector::pop_back(&mut _v7); + _v1 = &mut _v6; + _v0 = _v8 + 3; + vector::push_back(_v1, _v0); + continue + }; + } +} + + +//# run 0x42::m::init \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled.baseline.exp new file mode 100644 index 00000000000..14d1804ac8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-31: publish [module 0x42::m {] +task 1 lines 34-34: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled new file mode 100644 index 00000000000..32db18c2107 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled @@ -0,0 +1,38 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/empty_vectors2.move` + +//# publish +module 0x42::m { + use 0x1::vector; + public entry fun init() { + let _v0; + let _v1; + let _v2 = vector[vector[]]; + let _v3 = *vector::borrow>>(&_v2, 0); + let _v4 = vector::empty(); + let _v5 = _v3; + vector::reverse>(&mut _v5); + while (!vector::is_empty>(&_v5)) { + let _v6 = vector::pop_back>(&mut _v5); + _v1 = &mut _v4; + let _v7 = _v6; + _v0 = vector::length(&_v7) + 2; + vector::push_back(_v1, _v0); + continue + }; + let _v8 = vector[vector[]]; + let _v9 = *vector::borrow>(&_v8, 0); + let _v10 = vector::empty(); + let _v11 = _v9; + vector::reverse(&mut _v11); + while (!vector::is_empty(&_v11)) { + let _v12 = vector::pop_back(&mut _v11); + _v1 = &mut _v10; + _v0 = _v12 + 3; + vector::push_back(_v1, _v0); + continue + }; + } +} + + +//# run 0x42::m::init \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled.baseline.exp new file mode 100644 index 00000000000..0cf117f1e1d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/empty_vectors2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-35: publish [module 0x42::m {] +task 1 lines 38-38: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled new file mode 100644 index 00000000000..abac09a44b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_boolean.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_boolean.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled new file mode 100644 index 00000000000..1db8bd9f495 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_complex.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_complex.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled new file mode 100644 index 00000000000..7b209a58e63 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_equality.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_equality.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled new file mode 100644 index 00000000000..9ccbb360c0c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_numeric.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_numeric.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled new file mode 100644 index 00000000000..b5b70e74dd9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_values.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_values.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled new file mode 100644 index 00000000000..174190249e5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_vector.move` + +//# publish +module 0x42::M { + fun foo() { + () + } +} + + +//# run 0x42::M::foo \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled.baseline.exp new file mode 100644 index 00000000000..bb7bc01a7b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::M {] +task 1 lines 11-11: run 0x42::M::foo diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled new file mode 100644 index 00000000000..28109e5abfa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled @@ -0,0 +1,5 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/folding_vector_large.move` + +//# publish +module 0x42::M { +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled.baseline.exp new file mode 100644 index 00000000000..955c39e4e47 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/folding_vector_large.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-5: publish [module 0x42::M {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled new file mode 100644 index 00000000000..4f594beaf61 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/large_vectors.move` + +//# publish +module 0xc0ffee::m { + public fun large_vec_1(): u64 { + let _v0 = vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026]; + 0x1::vector::length(&_v0) + } + public fun large_vec_2(): u64 { + let _v0 = vector[784042861, 731703328, 627427227, 480194904, 448763913, 369639437, 368990020, 339567419, 336091097, 330368286, 309883597, 306323510, 292125283, 280873590, 260288986, 244147755, 238391109, 224585968, 221686474, 220018711, 219971903, 215156936, 208999520, 198798781, 192990411, 192053779, 178545542, 177505153, 172604485, 169135513, 166658626, 158308551, 150304204, 149315443, 143583737, 139597922, 137546241, 134251623, 131763493, 127346381, 122835822, 121832197, 121267937, 118082471, 115579423, 114769586, 107825313, 107401973, 104405621, 100675375, 99743310, 99671227, 97191797, 96329877, 96074954, 95516298, 94822007, 93797146, 91785748, 90590503, 90338021, 86875188, 86498722, 84884699, 84688241, 83771041, 83483486, 83435084, 82627936, 82330314, 81706143, 81401148, 81391185, 81100890, 80871457, 80461222, 78419324, 77511249, 77114143, 76068678, 75517688, 75487275, 74013351, 73823208, 73006507, 72071711, 71890053, 71322592, 71227218, 69612396, 67820449, 67388818, 67352028, 66860045, 66306760, 65505333, 64915825, 64841579, 64636017, 64618769, 64508697, 64447073, 63669755, 62984166, 62915002, 62484906, 61358231, 61205875, 61049648, 60904764, 60732411, 60707840, 60334649, 60152838, 59888559, 59372561, 58665964, 57493630, 56658773, 56657472, 56657451, 56657448, 56657444, 56657441, 56657438, 56657429, 56657421, 56657416, 55738560, 54729978, 54612806, 54426283, 53879520, 53573532, 53224252, 53032349, 52973993, 52636280, 51926695, 51488892, 51143392, 49540937, 49470089, 48907987, 48616218, 48326460, 47431824, 47000941, 46891507, 46831952, 46688694, 46602146, 46464095, 46053089, 45736737, 45600052, 45275857, 43796324, 43593424, 43220921, 42987658, 42542852, 42479992, 41832676, 41692703, 41066748, 41066059, 41038316, 40905173, 40761881, 40728311, 40272910, 40205861, 39584988, 39127507, 38880603, 38671775, 38266189, 37907951, 37729098, 37675831, 37618689, 37584098, 37559046, 37540201, 37462105, 37454934, 37357840, 37021382, 36727720, 36565357, 36379979, 36104340, 35802721, 35542733, 35349884, 34804051, 34686075, 34628776, 34607603, 34561502, 34417788, 34214279, 33956698, 33837347, 33822166, 33664996, 33619035, 33310262, 32919369, 32813815, 32662979, 32626701, 32546606, 32528882, 32318041, 31927035, 31867719, 31682292, 31638136, 31359300, 31271856, 31085256, 31083765, 31044367, 30959328, 30939170, 30936185, 30918017, 30816019, 30787008, 30768585, 30742052, 30538172, 30506761, 30500805, 30381477, 30331081, 30292506, 30025097, 29803907, 29662272, 29509069, 29407454, 29218440, 29110141, 28887128, 28882798, 28855824, 28809126, 28749351, 28604594, 28420032, 28318040, 28173804, 28133954, 28133952, 28130402, 28015862, 28015859, 28015858, 27995405, 27880544, 27845023, 27833081, 27832621, 27756040, 27701099, 27548474, 27295377, 27265076, 27228641, 27208031, 27202592, 27134428, 27068312, 26969528, 26955643, 26899041, 26857627, 26768154, 26622287, 26585954, 26498022, 26331149, 26262784, 26219586, 26201276, 26194452, 26161084, 25944116, 25944114, 25908581, 25885183, 25885183, 25807854, 25785774, 25769038, 25724890, 25665341, 25547911, 25526667, 25500216, 25471225, 25458068, 25331051, 25246432, 25211272, 25188884, 24965263, 24949642, 24803737, 24795447, 24783637, 24605418, 24567042, 24540121, 24480428, 24411631, 24393168, 24311287, 24305853, 24227098, 24193778, 24177897, 23978923, 23960746, 23933478, 23916422, 23741352, 23704581, 23552145, 23389588, 23378970, 23342067, 23245734, 23216302, 23204333, 23157707, 23084522, 23077354, 23061567, 23036553, 23018326, 22976230, 22955875, 22929919, 22929440, 22792932, 22792220, 22712157, 22643506, 22632017, 22622605, 22609256, 22605710, 22593502, 22581447, 22451222, 22446311, 22411798, 22179705, 22096677, 22090766, 21954972, 21777081, 21772317, 21735890, 21672331, 21655823, 21640394, 21545036, 21530743, 21514017, 21504512, 21399298, 21380058, 21336479, 21317511, 21295108, 21293318, 21235444, 21139229, 21080556, 21038333, 20962589, 20919825, 20882402, 20824579, 20818046, 20811905, 20811578, 20811346, 20790242, 20762047, 20695760, 20653439, 20636452, 20611071, 20602774, 20529115, 20516582, 20483559, 20454317, 20419142, 20350817, 20304281, 20303788, 20297069, 20296285, 20290351, 20220174, 20218314, 20157426, 20125725, 20124747, 20090354, 20049432, 20044885, 20020439, 19903013, 19902624, 19884592, 19840758, 19829410, 19785850, 19785369, 19780003, 19752298, 19723970, 19680699, 19520338, 19519482, 19518114, 19482920, 19458070, 19456708, 19394877, 19393852, 19390418, 19337693, 19336465, 19304112, 19255981, 19250928, 19248791, 19205937, 19205251, 19188711, 19072145, 18984651, 18978757, 18857931, 18850605, 18780023, 18775463, 18726440, 18723600, 18717644, 18707062, 18696718, 18579335, 18562954, 18547018, 18540137, 18518462, 18469819, 18439247, 18411641, 18375390, 18293210, 18247773, 18243250, 18152756, 18131267, 18102215, 18054771, 18051621, 17988317, 17981542, 17904723, 17900930, 17864288, 17854432, 17788719, 17788718, 17788715, 17788714, 17757495, 17742251, 17698514, 17695527, 17648900, 17580056, 17531449, 17445160, 17441512, 17247032, 17237401, 17167171, 17021588, 17015295, 17015295, 17015294, 17015294, 17015293, 17015291, 17015291, 16942385, 16911335, 16846857, 16836682, 16788624, 16787224, 16771830, 16771453, 16770590, 16769186, 16767567, 16767564, 16695826, 16688123, 16671617, 16666795, 16660533, 16629364, 16599916, 16589084, 16587650, 16581198, 16570605, 16561640, 16550518, 16499928, 16495963, 16458794, 16448567, 16410846, 16380872, 16379517, 16346146, 16334022, 16329879, 16288058, 16242269, 16242258, 16241928, 16241886, 16241885, 16241885, 16241884, 16241883, 16241882, 16241882, 16241881, 16241880, 16241880, 16241879, 16241879, 16241878, 16241878, 16241877, 16241876, 16241875, 16241875, 16187422, 16172010, 16069019, 16052273, 16038890, 15980379, 15970636, 15916381, 15901539, 15898706, 15898706, 15893453, 15885719, 15837960, 15817177, 15803158, 15772988, 15762143, 15730636, 15705905, 15705905, 15694125, 15690431, 15659910, 15652065, 15652057, 15634337, 15580478, 15572910, 15548856, 15548177, 15532503, 15515803, 15487997, 15485321, 15481256, 15480102, 15471838, 15387614, 15379289, 15327584, 15310014, 15197676, 15187311, 15171591, 15151533, 15117338, 15111347, 15104658, 15065867, 15064113, 15056467, 15035569, 15019811, 14989801, 14982498, 14967959, 14936800, 14896483, 14744053, 14724229, 14723827, 14722499, 14633713, 14608024, 14565094, 14553668, 14531833, 14478880, 14462946, 14459945, 14458254, 14458253, 14458253, 14458253, 14439665, 14439659, 14408585, 14407071, 14372213, 14317896, 14283628, 14268119, 14249053, 14248115, 14203837, 14193622, 14177347, 14144858, 14136959, 14111770, 14085048, 14080687, 14080311, 14072548, 14056515, 14040059, 14033112, 14013325, 14000016, 13949829, 13881732, 13859495, 13745900, 13743134, 13743134, 13675082, 13672625, 13668418, 13657681, 13643483, 13639236, 13601096, 13601096, 13601096, 13601095, 13575998, 13573560, 13535677, 13523925, 13511580, 13511535, 13460339, 13443579, 13436915, 13412506, 13411098, 13379972, 13378799, 13361188, 13320809, 13319656, 13317324, 13314438, 13293026, 13283418, 13255300, 13250380, 13180333, 13176070, 13143077, 13130488, 13116657, 13111040, 13091998, 13041529, 13016942, 13004930, 12997658, 12940528, 12939610, 12927792, 12926644, 12926643, 12919410, 12912368, 12884508, 12880489, 12869579, 12831234, 12799661, 12642635, 12640639, 12629952, 12609683, 12602514, 12562549, 12530611, 12524085, 12508977, 12484154, 12482608, 12481557, 12468312, 12443334, 12439664, 12437867, 12432890, 12418565, 12417744, 12412586, 12389804, 12387046, 12376996, 12355432, 12349033, 12346317, 12312365, 12306615, 12281678, 12281677, 12281410, 12278445, 12258002, 12249983, 12240921, 12217040, 12199888, 12186981, 12149046, 12100885, 12087757, 12023271, 12017688, 11987863, 11958479, 11950245, 11912558, 11911256, 11909418, 11893065, 11873705, 11854972, 11774159, 11752827, 11733793, 11681587, 11664437, 11635278, 11612546, 11597862, 11556182, 11541914, 11539166, 11495370, 11489733, 11469402, 11427204, 11414069, 11406773, 11401402, 11380488, 11378960, 11374308, 11363151, 11361688, 11353063, 11342673, 11340693, 11329164, 11311865, 11301082, 11301070, 11275593, 11265868, 11246967, 11229120, 11187289, 11146875, 11141013, 11109483, 11103643, 11082644, 11060626, 11051885, 11018270, 10941046, 10907798, 10903636, 10892412, 10829815, 10817568, 10808036, 10783247, 10777311, 10764566, 10738919, 10724379, 10715542, 10714064, 10703261, 10694660, 10630595, 10630595, 10630595, 10578815, 10568836, 10557861, 10519204, 10518652, 10499415, 10479390, 10469932, 10468593, 10444544, 10417314, 10402568, 10380663, 10372114, 10359325, 10359325, 10354773, 10343968, 10335079, 10320452, 10314439, 10303811, 10280697, 10270484, 10266721, 10258215, 10257626, 10241645, 10237612, 10236114, 10230370, 10209164, 10204001, 10196734, 10164131, 10154919, 10139252, 10109635, 10097446, 10095760, 10094495, 10038170, 9990015, 9954521, 9946209, 9944393, 9942287, 9942287, 9942286, 9942286, 9942286, 9942286, 9941812, 9933013, 9916104, 9911490, 9910079, 9900653, 9893948, 9893726, 9893726, 9893724, 9893724, 9892584, 9884637, 9883945, 9833920, 9766098, 9765017, 9762144, 9759623, 9755485, 9747830, 9744318, 9719046, 9714017, 9713802, 9712072, 9703357, 9696277, 9670861, 9667944, 9623849, 9615609, 9612486, 9607468, 9606610, 9605786, 9604036, 9602950, 9602855, 9583443, 9581941, 9580397, 9573102, 9541398, 9534430, 9501914, 9494317, 9469268, 9433912, 9432697, 9399687, 9392175, 9375720, 9373993, 9354690, 9349763, 9349763, 9349763, 9339556, 9336847, 9331760, 9299940, 9287901, 9279213, 9277868, 9251524, 9244977, 9241765, 9238293, 9210725, 9182902, 9182452, 9125806, 9114067, 9105849, 9086871, 9080924, 9071321, 9068527, 9065359, 9035890, 9034701, 9017677, 8997962, 8993786, 8986187, 8976046, 8973938, 8941317, 8938938, 8934037, 8933444, 8933168, 8932255, 8931923, 8929644, 8849083, 8849083, 8848790, 8835691, 8829064, 8797919, 8786211, 8785197, 8783642, 8747637, 8742645, 8742642, 8742641, 8742640, 8742452, 8742451, 8742449, 8741642, 8713587, 8685921, 8640467, 8630805, 8619771, 8611528, 8589490, 8563866, 8556857, 8551445, 8541120, 8533418, 8524446, 8488674, 8487418, 8461807, 8444688, 8434463, 8431480]; + 0x1::vector::length(&_v0) + } +} + + +//# run 0xc0ffee::m::large_vec_1 + +//# run 0xc0ffee::m::large_vec_2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled.baseline.exp new file mode 100644 index 00000000000..a79d8af82d9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/large_vectors.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::large_vec_1 +return values: 1027 +task 2 lines 18-18: run 0xc0ffee::m::large_vec_2 +return values: 1025 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled new file mode 100644 index 00000000000..c6cd0f61579 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled @@ -0,0 +1,40 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/non_constant_empty_vec.move` + +//# publish +module 0x42::M { + struct S { + } + public fun empty_generic_vec(): vector { + 0x1::vector::empty() + } + public fun empty_generic_vec_vec(): vector> { + 0x1::vector::empty>() + } + public fun empty_signer_vec(): vector { + 0x1::vector::empty() + } + public fun empty_signer_vec_vec(): vector> { + 0x1::vector::empty>() + } + public fun empty_struct_vec(): vector { + 0x1::vector::empty() + } + public fun empty_struct_vec_vec(): vector> { + 0x1::vector::empty>() + } +} + + +//# run 0x42::M::empty_struct_vec + +//# run 0x42::M::empty_struct_vec + +//# run 0x42::M::empty_signer_vec + +//# run 0x42::M::empty_generic_vec --type-args 0x42::M::S + +//# run 0x42::M::empty_struct_vec_vec + +//# run 0x42::M::empty_signer_vec_vec + +//# run 0x42::M::empty_generic_vec_vec --type-args 0x42::M::S \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled.baseline.exp new file mode 100644 index 00000000000..dd24a61fca7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/non_constant_empty_vec.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 8 tasks +task 0 lines 3-25: publish [module 0x42::M {] +task 1 lines 28-28: run 0x42::M::empty_struct_vec +return values: [] +task 2 lines 30-30: run 0x42::M::empty_struct_vec +return values: [] +task 3 lines 32-32: run 0x42::M::empty_signer_vec +return values: [] +task 4 lines 34-34: run 0x42::M::empty_generic_vec --type-args 0x42::M::S +return values: [] +task 5 lines 36-36: run 0x42::M::empty_struct_vec_vec +return values: [] +task 6 lines 38-38: run 0x42::M::empty_signer_vec_vec +return values: [] +task 7 lines 40-40: run 0x42::M::empty_generic_vec_vec --type-args 0x42::M::S +return values: [] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled new file mode 100644 index 00000000000..519e2089e30 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled @@ -0,0 +1,35 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/nonempty_tvectors.move` + +//# publish +module 0x42::m { + use 0x1::string; + use 0x1::vector; + use 0x1::bcs; + public entry fun init() { + let _v0; + let _v1 = vector::empty(); + let _v2 = vector[vector[3u8]]; + vector::reverse>(&mut _v2); + while (!vector::is_empty>(&_v2)) { + _v0 = vector::pop_back>(&mut _v2); + let _v3 = &mut _v1; + let _v4 = string::utf8(_v0); + vector::push_back(_v3, _v4); + continue + }; + let _v5 = vector::empty>(); + let _v6 = vector[3]; + vector::reverse(&mut _v6); + while (!vector::is_empty(&_v6)) { + let _v7 = vector::pop_back(&mut _v6); + let _v8 = &mut _v5; + let _v9 = _v7; + _v0 = bcs::to_bytes(&_v9); + vector::push_back>(_v8, _v0); + continue + }; + } +} + + +//# run 0x42::m::init \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled.baseline.exp new file mode 100644 index 00000000000..a65f36fb3c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_tvectors.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-32: publish [module 0x42::m {] +task 1 lines 35-35: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled new file mode 100644 index 00000000000..cbb73549361 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled @@ -0,0 +1,34 @@ +//**** Cross-compiled for `move` syntax from `tests/constants/nonempty_vectors.move` + +//# publish +module 0x42::m { + use 0x1::vector; + public entry fun init() { + let _v0; + let _v1; + let _v2 = vector::empty(); + let _v3 = vector[vector[1u8]]; + vector::reverse>(&mut _v3); + while (!vector::is_empty>(&_v3)) { + let _v4 = vector::pop_back>(&mut _v3); + _v1 = &mut _v2; + let _v5 = _v4; + _v0 = vector::length(&_v5) + 2; + vector::push_back(_v1, _v0); + continue + }; + let _v6 = vector::empty(); + let _v7 = vector[3]; + vector::reverse(&mut _v7); + while (!vector::is_empty(&_v7)) { + let _v8 = vector::pop_back(&mut _v7); + _v1 = &mut _v6; + _v0 = _v8 + 3; + vector::push_back(_v1, _v0); + continue + }; + } +} + + +//# run 0x42::m::init \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled.baseline.exp new file mode 100644 index 00000000000..14d1804ac8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/round-trip/nonempty_vectors.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-31: publish [module 0x42::m {] +task 1 lines 34-34: run 0x42::m::init diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp index 5d92c423f3f..e0aadc2c125 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-35: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp index 6cd67db3f64..84ac8cbb69f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-16: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop.exp index 6cd67db3f64..3d1713589a2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop_nested.exp index 6cd67db3f64..d0102c77b77 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop_nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_for_loop_nested.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-28: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp index 6cd67db3f64..1872db2c866 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp index 6cd67db3f64..1872db2c866 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_empty.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_empty.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_empty.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_empty.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_counter.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_counter.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_counter.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_counter.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty.exp index 6cd67db3f64..3c0220698b7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-6: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty_range.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty_range.exp index 6cd67db3f64..0d791fbd8d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty_range.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_empty_range.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_increment_iter.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_increment_iter.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_increment_iter.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_increment_iter.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.baseline.exp index 4b45787f0f9..adae48f0e48 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.baseline.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.no-optimize.exp index 4e6f3126277..9196cb94a9e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.no-optimize.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.opt-extra.exp new file mode 100644 index 00000000000..adae48f0e48 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.opt-extra.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-14: run --gas-budget 700 [script {] +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 25)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.optimize.exp index 4b45787f0f9..adae48f0e48 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_nested_break.optimize.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.baseline.exp index ef1765eec7d..0286c54da35 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.baseline.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.move index 234651fa04b..62af38b35b9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.move @@ -1,7 +1,7 @@ //# run --gas-budget 700 script { fun main(): () { - let y = 0; + let _y = 0; // out of gas for (i in 0..10) { i = 0; diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.no-optimize.exp index aa771ff5b8c..8ca38f26a88 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.no-optimize.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.opt-extra.exp new file mode 100644 index 00000000000..0286c54da35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.opt-extra.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-11: run --gas-budget 700 [script {] +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.optimize.exp index ef1765eec7d..0286c54da35 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_non_terminating.optimize.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_upper_bound.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_upper_bound.exp index 77683c8458f..c75aba78bbb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_upper_bound.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_loop_upper_bound.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 16-16: +task 0 lines 1-14: publish [module 0x42::m {] +task 1 lines 16-16: run 0x42::m::main return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_test_v.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_test_v.exp index 77683c8458f..c75aba78bbb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_test_v.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_test_v.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 16-16: +task 0 lines 1-14: publish [module 0x42::m {] +task 1 lines 16-16: run 0x42::m::main return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_user.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_user.exp index 304777b2bb6..0ccd4adfb5f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_user.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/for_user.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::test {] +task 1 lines 13-13: run 0x42::test::for_user return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_arg_eval_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_arg_eval_order.exp index bf4e6f727b1..b3940a452d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_arg_eval_order.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_arg_eval_order.exp @@ -1,10 +1,8 @@ processed 4 tasks - -task 1 'run'. lines 38-38: +task 0 lines 1-36: publish [module 0xc0ffee::m {] +task 1 lines 38-38: run 0xc0ffee::m::test1 return values: 1 - -task 2 'run'. lines 40-40: +task 2 lines 40-40: run 0xc0ffee::m::test2 return values: 9 - -task 3 'run'. lines 42-42: +task 3 lines 42-42: run 0xc0ffee::m::main return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_mut_arg_twice.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_mut_arg_twice.exp index 61dca04cf00..e709927e094 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_mut_arg_twice.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/function_call_mut_arg_twice.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp index 5d92c423f3f..14f8a95df70 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [address 0x42 {] +task 1 lines 13-19: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp index 6cd67db3f64..6f22b29e9e7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-7: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp index 6cd67db3f64..0d791fbd8d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp index 6cd67db3f64..3c0220698b7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-6: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp index 6cd67db3f64..a3daef2be0c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-30: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_infinite.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_infinite.exp index 4d4e9c68efd..aaf950f5268 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_infinite.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_infinite.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-10: +task 0 lines 1-10: run --gas-budget 700 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp index 6cd67db3f64..3c0220698b7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-6: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_loops.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_loops.exp index 6cd67db3f64..d9dda685234 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_loops.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_loops.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-13: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_while_loops.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_while_loops.exp index 6cd67db3f64..0816e84d4c6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_while_loops.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_for_while_loops.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-21: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp index 5d92c423f3f..d4544b79f7a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::M {] +task 1 lines 13-20: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp index 6cd67db3f64..8a8cc008cc9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp index 5d92c423f3f..207639b3d76 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0x42::Test {] +task 1 lines 14-21: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp index 5d92c423f3f..9a5e957deb2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-7: publish [module 0x42::Test {] +task 1 lines 9-16: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled new file mode 100644 index 00000000000..da0a3dc4d99 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/assert_in_while.move` + +//# publish +module 0x42::Test { + struct Tester has drop { + f: u64, + } + public fun len(p0: &Tester): u64 { + *&p0.f + } + public fun modify(p0: &mut Tester): u64 { + let _v0 = *&p0.f - 1; + let _v1 = &mut p0.f; + *_v1 = _v0; + let _v2 = *&p0.f; + 9 - _v2 + } + public fun new(): Tester { + Tester{f: 10} + } +} + + +//# run +script { + use 0x42::Test; + fun main() { + let _v0 = Test::new(); + assert!(Test::len(&_v0) == 10, 70002); + let _v1 = 0; + 'l0: loop { + loop { + let _v2 = Test::len(&_v0); + if (!(_v1 < _v2)) break 'l0; + if (!(Test::modify(&mut _v0) == _v1)) break; + _v1 = _v1 + 1; + continue + }; + abort 70003 + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled.baseline.exp new file mode 100644 index 00000000000..1adebddebd7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/assert_in_while.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0x42::Test {] +task 1 lines 24-42: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled new file mode 100644 index 00000000000..03ec47ef133 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/branch_assigns_then_moves_then_assigns.move` + +//# run +script { + fun main() { + assert!(5 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/branch_assigns_then_moves_then_assigns.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled new file mode 100644 index 00000000000..92a654e2b28 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled @@ -0,0 +1,10 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_accumulator.move` + +//# run +script { + fun main() { + let _v0 = 0; + while (!(_v0 >= 5)) _v0 = _v0 + 1; + assert!(_v0 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled.baseline.exp new file mode 100644 index 00000000000..808804d8736 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_accumulator.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled new file mode 100644 index 00000000000..59ffa95bd89 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_continue_for_loop.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 10)) break; + _v0 = _v0 + 1; + if (_v0 >= 15) break; + _v0 = _v0 + 2; + if (_v1 % 2 == 0) continue; + _v0 = _v0 * 2 + }; + assert!(_v0 == 16, _v0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled.baseline.exp new file mode 100644 index 00000000000..ca388382fc0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-20: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled new file mode 100644 index 00000000000..25d01ec69a4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled @@ -0,0 +1,41 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_continue_for_loop_nested.move` + +//# run +script { + fun main() { + let _v0; + let _v1 = 0; + let _v2 = 0; + let _v3 = 0; + let _v4 = false; + 'l0: loop { + loop { + if (_v4) _v3 = _v3 + 1 else _v4 = true; + if (!(_v3 < 10)) break 'l0; + _v2 = _v2 + 1; + if (_v2 >= 15) break 'l0; + _v2 = _v2 + 2; + _v0 = 0; + let _v5 = 0; + let _v6 = false; + loop { + if (_v6) _v5 = _v5 + 1 else _v6 = true; + if (!(_v5 < 10)) break; + _v0 = _v0 + 1; + if (_v0 >= 15) break; + _v0 = _v0 + 2; + if (_v5 % 2 == 0) continue; + _v0 = _v0 * 2 + }; + if (!(_v0 == 16)) break; + _v1 = _v1 + _v0; + if (_v3 % 2 == 0) continue; + _v2 = _v2 * 2; + continue + }; + abort _v0 + }; + _v0 = 3 * _v1 + _v2; + assert!(_v0 == 160, _v0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled.baseline.exp new file mode 100644 index 00000000000..9c295cc6213 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_for_loop_nested.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-41: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled new file mode 100644 index 00000000000..7ef95be3317 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled @@ -0,0 +1,10 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_continue_simple.move` + +//# run +script { + fun main() { + let _v0 = 0; + while (!(_v0 >= 5)) _v0 = _v0 + 1; + assert!(_v0 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled.baseline.exp new file mode 100644 index 00000000000..808804d8736 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_simple.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled new file mode 100644 index 00000000000..83d8665468a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_continue_sum_of_odds.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + while (_v0 < 10) { + _v0 = _v0 + 1; + if (_v0 % 2 == 0) continue; + _v1 = _v1 + _v0 + }; + assert!(_v1 == 25, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled.baseline.exp new file mode 100644 index 00000000000..6aa1acec7bf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_continue_sum_of_odds.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-15: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled new file mode 100644 index 00000000000..b1d1b900da0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled @@ -0,0 +1,9 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_nested.move` + +//# run +script { + fun main() { + assert!(3 == 3, 42); + assert!(5 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled.baseline.exp new file mode 100644 index 00000000000..7ed27326cab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_nested.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-9: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled new file mode 100644 index 00000000000..341bb792757 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/break_simple.move` + +//# run +script { + fun main() { + assert!(0 + 1 == 1, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/break_simple.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled new file mode 100644 index 00000000000..dafd62cc127 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/deep_return_branch_doesnt_assign.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/deep_return_branch_doesnt_assign.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled new file mode 100644 index 00000000000..b8f298f8915 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_empty.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 10; + let _v2 = false; + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 4)) break; + _v0 = _v0 + 1 + }; + assert!(_v0 == 0, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled.baseline.exp new file mode 100644 index 00000000000..a132233132c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_empty.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-16: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled new file mode 100644 index 00000000000..93dcee4c783 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_counter.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 1)) break; + _v0 = _v0 + 1 + }; + assert!(_v0 == 1, 20); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled.baseline.exp new file mode 100644 index 00000000000..a132233132c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_counter.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-16: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled new file mode 100644 index 00000000000..ae9a10018b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_empty.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = false; + loop { + if (_v1) _v0 = _v0 + 1 else _v1 = true; + if (_v0 < 10) continue; + break + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled.baseline.exp new file mode 100644 index 00000000000..8a2974c5d7e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-14: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled new file mode 100644 index 00000000000..2520b0206dd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled @@ -0,0 +1,10 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_empty_range.move` + +//# run +script { + fun main() { + let _v0 = 10; + if (false) _v0 = _v0 + 1; + if (_v0 < 9) abort 42; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled.baseline.exp new file mode 100644 index 00000000000..808804d8736 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_empty_range.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled new file mode 100644 index 00000000000..1229f9bda73 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_increment_iter.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 10)) break; + _v0 = _v0 + 1; + _v1 = _v1 + 1 + }; + assert!(_v0 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled.baseline.exp new file mode 100644 index 00000000000..95503281748 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_increment_iter.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled new file mode 100644 index 00000000000..63a5b4e1655 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_nested_break.move` + +//# run --gas-budget 700 +script { + fun main() { + let _v0 = 0; + let _v1 = false; + loop { + if (_v1) _v0 = _v0 + 1 else _v1 = true; + if (!(_v0 < 10)) break; + _v0 = 0; + let _v2 = 0; + if (false) _v2 = _v2 + 1; + continue + }; + abort 42 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled.baseline.exp new file mode 100644 index 00000000000..0717344a25a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_nested_break.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-18: run --gas-budget 700 [script {] +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled new file mode 100644 index 00000000000..80036961b7d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_non_terminating.move` + +//# run --gas-budget 700 +script { + fun main() { + let _v0 = 0; + let _v1 = false; + loop { + if (_v1) _v0 = _v0 + 1 else _v1 = true; + if (!(_v0 < 10)) break; + _v0 = 0 + }; + abort 42 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled.baseline.exp new file mode 100644 index 00000000000..fbdce053db7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_non_terminating.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-15: run --gas-budget 700 [script {] +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled new file mode 100644 index 00000000000..4c6b2f65518 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_loop_upper_bound.move` + +//# publish +module 0x42::m { + fun foo(p0: &mut u64): u64 { + *p0 = *p0 + 1; + 10 + } + fun main(): u64 { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + let _v3 = foo(&mut _v0); + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (_v1 < _v3) continue; + break + }; + _v0 + } +} + + +//# run 0x42::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled.baseline.exp new file mode 100644 index 00000000000..c9ba3e70347 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_loop_upper_bound.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0x42::m {] +task 1 lines 24-24: run 0x42::m::main +return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled new file mode 100644 index 00000000000..0b9d34b85f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_test_v.move` + +//# publish +module 0x42::m { + fun foo(p0: &mut u64): u64 { + *p0 = *p0 + 1; + 10 + } + fun main(): u64 { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + let _v3 = foo(&mut _v0); + loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (_v1 < _v3) continue; + break + }; + _v0 + } +} + + +//# run 0x42::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled.baseline.exp new file mode 100644 index 00000000000..c9ba3e70347 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_test_v.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0x42::m {] +task 1 lines 24-24: run 0x42::m::main +return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled new file mode 100644 index 00000000000..80bcee7a448 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/for_user.move` + +//# publish +module 0x42::test { + fun for(p0: u32, p1: u32, p2: u32): u32 { + p0 + p1 + p2 + } + public fun for_user(): u32 { + for(3u32, 4u32, 5u32) + } +} + + +//# run 0x42::test::for_user \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled.baseline.exp new file mode 100644 index 00000000000..c008bcab856 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/for_user.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0x42::test {] +task 1 lines 14-14: run 0x42::test::for_user +return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled new file mode 100644 index 00000000000..154646a9374 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/function_call_arg_eval_order.move` + +//# publish +module 0xc0ffee::m { + fun bar(p0: &u64, p1: &u64): u64 { + let _v0 = *p1; + let _v1 = *p0; + _v0 - _v1 + } + fun foo(p0: u64, p1: u64): u64 { + p1 - p0 + } + public fun g(p0: u64): u64 { + let _v0 = p0 + 1; + test3(p0, _v0) + } + public fun test3(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun main(): u64 { + g(1) + } + public fun test1(): u64 { + let _v0 = 1; + let _v1 = _v0 + 1; + foo(_v0, _v1) + } + public fun test2(): u64 { + let _v0 = 1; + let _v1 = &_v0; + let _v2 = 10; + let _v3 = &_v2; + bar(_v1, _v3) + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled.baseline.exp new file mode 100644 index 00000000000..8cc08602868 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_arg_eval_order.decompiled.baseline.exp @@ -0,0 +1,8 @@ +processed 4 tasks +task 0 lines 3-35: publish [module 0xc0ffee::m {] +task 1 lines 38-38: run 0xc0ffee::m::test1 +return values: 1 +task 2 lines 40-40: run 0xc0ffee::m::test2 +return values: 9 +task 3 lines 42-42: run 0xc0ffee::m::main +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled new file mode 100644 index 00000000000..73d42009919 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/function_call_mut_arg_twice.move` + +//# publish +module 0xc0ffee::m { + fun update(p0: &mut u64, p1: u64, p2: u64) { + *p0 = p1 + p2; + } + fun test(): u64 { + let _v0 = 0; + let _v1 = &mut _v0; + update(_v1, 3, 4); + update(_v1, 5, 6); + _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled.baseline.exp new file mode 100644 index 00000000000..c824d090cd9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/function_call_mut_arg_twice.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test +return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled new file mode 100644 index 00000000000..f1066102a02 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_assignment.move` + +//# publish +module 0x42::ReassignCond { + public fun reassign_cond(p0: address, p1: bool): address { + if (p1) p0 = @0x2; + p0 + } +} + + +//# run +script { + use 0x42::ReassignCond; + fun main() { + assert!(ReassignCond::reassign_cond(@0x1, false) == @0x1, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled.baseline.exp new file mode 100644 index 00000000000..bb738eae176 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_assignment.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-9: publish [module 0x42::ReassignCond {] +task 1 lines 12-18: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled new file mode 100644 index 00000000000..8d4c5a70e7d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_1.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_1.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled new file mode 100644 index 00000000000..7ebf317a066 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_10.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_10.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled new file mode 100644 index 00000000000..390047d8a23 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_2.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_2.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled new file mode 100644 index 00000000000..30034f59cf6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_3.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_3.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled new file mode 100644 index 00000000000..a1449b9a669 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_4.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_4.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled new file mode 100644 index 00000000000..bec9b301550 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_5.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_5.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled new file mode 100644 index 00000000000..b0dbc56fbbc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_6.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_6.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled new file mode 100644 index 00000000000..5779bdd6c87 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_7.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_7.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled new file mode 100644 index 00000000000..8541ebfd4b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_8.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_8.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled new file mode 100644 index 00000000000..53c3423783d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_branch_diverges_9.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_branch_diverges_9.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled new file mode 100644 index 00000000000..549c2ac7bea --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_without_braces_1.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_1.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled new file mode 100644 index 00000000000..e4f41284241 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_without_braces_2.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_2.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled new file mode 100644 index 00000000000..40e26a207f5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_without_braces_3.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_3.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled new file mode 100644 index 00000000000..c7c5be696a7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/if_without_braces_4.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/if_without_braces_4.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled new file mode 100644 index 00000000000..656dcecabe7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/immediate_break.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/immediate_break.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled new file mode 100644 index 00000000000..7d83c49a339 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/local_assigned_many_times.move` + +//# run +script { + fun main() { + let _v0 = 5; + let _v1 = &_v0; + let _v2 = 2; + let _v3 = &_v2; + let _v4 = 5; + let _v5 = &_v4; + let _v6 = 2; + let _v7 = &_v6; + let _v8 = 5; + let _v9 = &_v8; + assert!(*_v7 == 2, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled.baseline.exp new file mode 100644 index 00000000000..652b56db97b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/local_assigned_many_times.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-18: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled new file mode 100644 index 00000000000..1e7ca4abbda --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/loop_infinite.move` + +//# run --gas-budget 700 +script { + fun main() { + loop continue + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled.baseline.exp new file mode 100644 index 00000000000..ed94e4e52dc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_infinite.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-8: run --gas-budget 700 [script {] +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled new file mode 100644 index 00000000000..333700a442d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/loop_nested_breaks.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_nested_breaks.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled new file mode 100644 index 00000000000..8298f7e8843 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/loop_return.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_return.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled new file mode 100644 index 00000000000..2c67af63e03 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/loop_simple.move` + +//# run +script { + fun main() { + assert!(0 + 1 == 1, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/loop_simple.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled new file mode 100644 index 00000000000..88fc7193e4f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/nested_for_loops.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + 'l0: loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 10)) break; + _v0 = _v0 + 1; + let _v3 = _v1; + let _v4 = false; + loop { + if (_v4) _v3 = _v3 + 1 else _v4 = true; + if (!(_v3 < 10)) continue 'l0; + _v0 = _v0 + 1 + }; + break + }; + assert!(_v0 == 65, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled.baseline.exp new file mode 100644 index 00000000000..c6f31d8ad44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_loops.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-24: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled new file mode 100644 index 00000000000..3b471562c6b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled @@ -0,0 +1,33 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/nested_for_while_loops.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + let _v2 = false; + 'l0: loop { + if (_v2) _v1 = _v1 + 1 else _v2 = true; + if (!(_v1 < 5)) break; + _v0 = _v0 + 1; + loop { + if (!(_v0 < 5)) continue 'l0; + _v0 = _v0 + 10 + }; + break + }; + assert!(_v0 == 15, 42); + let _v3 = 0; + 'l1: while (_v3 < 6) { + let _v4 = 0; + let _v5 = false; + loop { + if (_v5) _v4 = _v4 + 1 else _v5 = true; + if (!(_v4 < 5)) continue 'l1; + _v3 = _v3 + 1 + }; + break + }; + assert!(_v3 == 10, 43); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled.baseline.exp new file mode 100644 index 00000000000..8c32c034171 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_for_while_loops.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-33: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled new file mode 100644 index 00000000000..44849bfc6cb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/nested_loops.move` + +//# publish +module 0x42::M { + public fun foobar(p0: bool) { + loop { + if (!p0) continue; + if (!p0) continue; + break + }; + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::foobar(true); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled.baseline.exp new file mode 100644 index 00000000000..a70954e35eb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/nested_loops.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0x42::M {] +task 1 lines 15-21: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled new file mode 100644 index 00000000000..b17b678a3ee --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/return_branch_doesnt_assign.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_doesnt_assign.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled new file mode 100644 index 00000000000..fecc60705f5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/return_branch_moves.move` + +//# run +script { + fun main() { + assert!(0 == 0, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_branch_moves.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled new file mode 100644 index 00000000000..29bd3345b98 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/return_in_if_branch_taken.move` + +//# publish +module 0x42::Test { + public fun t(): u64 { + 100 + } +} + + +//# run +script { + use 0x42::Test; + fun main() { + assert!(Test::t() == 100, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled.baseline.exp new file mode 100644 index 00000000000..88fdd1685c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled new file mode 100644 index 00000000000..65062650d40 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/return_in_if_branch_taken_local.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_local.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled new file mode 100644 index 00000000000..95f77fa4142 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/return_in_if_branch_taken_no_else.move` + +//# publish +module 0x42::Test { + public fun t(): u64 { + 100 + } +} + + +//# run +script { + use 0x42::Test; + fun main() { + assert!(Test::t() == 100, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled.baseline.exp new file mode 100644 index 00000000000..88fdd1685c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/return_in_if_branch_taken_no_else.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled new file mode 100644 index 00000000000..125d7aee574 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled @@ -0,0 +1,96 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/sorter.move` + +//# publish +module 0x42::heap { + fun array_equals(p0: &vector, p1: &vector): bool { + let _v0 = 0x1::vector::length(p0); + let _v1 = 0x1::vector::length(p1); + let _v2 = _v0 != _v1; + 'l0: loop { + 'l1: loop { + if (!_v2) { + _v1 = 0; + loop { + if (!(_v1 < _v0)) break 'l0; + let _v3 = *0x1::vector::borrow(p0, _v1); + let _v4 = *0x1::vector::borrow(p1, _v1); + if (_v3 != _v4) break 'l1; + _v1 = _v1 + 1; + continue + } + }; + return false + }; + return false + }; + true + } + fun create1(): vector { + vector[3, 2, 1, 5, 8, 4] + } + fun create2(): vector { + vector[1, 2, 3, 4, 5, 8] + } + public fun main() { + let _v0 = create1(); + let _v1 = create2(); + let _v2 = vcopy(&_v0); + let _v3 = &_v0; + let _v4 = &_v2; + assert!(array_equals(_v3, _v4), 23); + let _v5 = &_v1; + let _v6 = &_v1; + assert!(array_equals(_v5, _v6), 29); + sort(&mut _v0); + let _v7 = &_v1; + let _v8 = &_v0; + assert!(array_equals(_v7, _v8), 31); + let _v9 = &_v0; + let _v10 = &_v1; + assert!(array_equals(_v9, _v10), 29); + let _v11 = &_v0; + let _v12 = &_v2; + if (array_equals(_v11, _v12)) abort 31; + } + fun vcopy(p0: &vector): vector { + let _v0 = 0x1::vector::empty(); + let _v1 = 0; + let _v2 = 0x1::vector::length(p0); + while (_v1 < _v2) { + let _v3 = &mut _v0; + let _v4 = *0x1::vector::borrow(p0, _v1); + 0x1::vector::push_back(_v3, _v4); + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sort(p0: &mut vector) { + let _v0 = 0; + loop { + let _v1 = 0x1::vector::length(freeze(p0)); + if (!(_v0 < _v1)) break; + let _v2 = _v0 + 1; + loop { + let _v3 = 0x1::vector::length(freeze(p0)); + if (!(_v2 < _v3)) break; + let _v4 = *0x1::vector::borrow(freeze(p0), _v0); + let _v5 = *0x1::vector::borrow(freeze(p0), _v2); + if (_v4 > _v5) 0x1::vector::swap(p0, _v0, _v2); + _v2 = _v2 + 1; + continue + }; + _v0 = _v0 + 1; + continue + }; + } +} + + +//# run +script { + use 0x42::heap; + fun main() { + heap::main(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled.baseline.exp new file mode 100644 index 00000000000..8366dd38cf6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/sorter.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-87: publish [module 0x42::heap {] +task 1 lines 90-96: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled new file mode 100644 index 00000000000..8d12268479c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/tuple_eval_order.move` + +//# publish +module 0xc0ffee::m { + fun foo(): (u64, u64) { + let _v0 = 1; + let _v1 = _v0 + 1; + (_v0, _v1) + } + public fun test(): u64 { + let (_v0,_v1) = foo(); + _v0 + _v1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled.baseline.exp new file mode 100644 index 00000000000..c6413494719 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/tuple_eval_order.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled new file mode 100644 index 00000000000..0c87a334bbc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/unused_signer_infinite_loop.move` + +//# run --gas-budget 700 --signers 0x1 +script { + fun main(p0: signer) { + loop continue + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled.baseline.exp new file mode 100644 index 00000000000..18a8482c768 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/unused_signer_infinite_loop.decompiled.baseline.exp @@ -0,0 +1,15 @@ +processed 1 task +task 0 lines 3-8: run --gas-budget 700 --signers 0x1 [script {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:5:14 + │ +5 │ fun main(p0: signer) { + │ ^^ + +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled new file mode 100644 index 00000000000..a67ae08a3d8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/while_false.move` + +//# run +script { + fun main() { + assert!(0 == 0, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_false.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled new file mode 100644 index 00000000000..5ffed6e56e1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/while_nested.move` + +//# run +script { + fun main() { + let _v0 = 0; + let _v1 = 0; + 'l0: while (_v0 < 3) { + _v0 = _v0 + 1; + let _v2 = 0; + loop { + if (!(_v2 < 7)) continue 'l0; + _v2 = _v2 + 1; + _v1 = _v1 + 1 + }; + break + }; + assert!(_v1 == 21, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled.baseline.exp new file mode 100644 index 00000000000..ca388382fc0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-20: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled new file mode 100644 index 00000000000..45f671a0315 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/while_nested_return.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_nested_return.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled new file mode 100644 index 00000000000..d9bffc09f72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/while_return.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_return.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled new file mode 100644 index 00000000000..125120e4acd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled @@ -0,0 +1,10 @@ +//**** Cross-compiled for `move` syntax from `tests/control_flow/while_simple.move` + +//# run +script { + fun main() { + let _v0 = 0; + while (_v0 < 5) _v0 = _v0 + 1; + assert!(_v0 == 5, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled.baseline.exp new file mode 100644 index 00000000000..808804d8736 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/round-trip/while_simple.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/sorter.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/sorter.exp index 5d92c423f3f..2ed1f9acaa2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/sorter.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/sorter.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-65: publish [module 0x42::heap {] +task 1 lines 67-73: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/tuple_eval_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/tuple_eval_order.exp index c63b3374d81..9a1ee6059ae 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/tuple_eval_order.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/tuple_eval_order.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp index d6f302c8160..0f0edadb570 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run --gas-budget 700 --signers 0x1 [script {] Error: Script execution failed with VMError: { major_status: OUT_OF_GAS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp index 6cd67db3f64..0d791fbd8d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp index 6cd67db3f64..1872db2c866 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp index 6cd67db3f64..95daba86d06 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp index 6cd67db3f64..6f22b29e9e7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-7: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp index 6cd67db3f64..0d791fbd8d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp index fc5a4436b29..07d833b217d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-7: publish [module 0x42::C {] +task 1 lines 9-15: publish [// names used to try to force an ordering of depedencies] +task 2 lines 17-29: publish [module 0x42::A {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled new file mode 100644 index 00000000000..eb1dd8e0a80 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled @@ -0,0 +1,34 @@ +//**** Cross-compiled for `move` syntax from `tests/dependencies/dependency_order.move` + +//# publish +module 0x42::C { + struct T { + } + public fun foo(): T { + T{} + } +} + + +//# publish +module 0x42::B { + use 0x42::C; + public fun foo(): C::T { + C::foo() + } +} + + +//# publish +module 0x42::A { + use 0x42::C; + use 0x42::B; + struct T { + t_b: C::T, + t_c: C::T, + } + public fun foo(): T { + let _v0 = C::foo(); + T{t_b: B::foo(), t_c: _v0} + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled.baseline.exp new file mode 100644 index 00000000000..5888d4d7475 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/dependency_order.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-10: publish [module 0x42::C {] +task 1 lines 13-19: publish [module 0x42::B {] +task 2 lines 22-34: publish [module 0x42::A {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled new file mode 100644 index 00000000000..a043242c49c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/dependencies/transitive_deps.move` + +//# publish +module 0x42::X { + struct T has drop { + } + public fun new(): T { + T{} + } +} + + +//# publish +module 0x42::Y { + use 0x42::X; + public fun foo(): X::T { + X::new() + } +} + + +//# run +script { + use 0x42::Y; + use 0x42::X; + fun main() { + let _v0 = Y::foo(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled.baseline.exp new file mode 100644 index 00000000000..780d1bf84cd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/round-trip/transitive_deps.decompiled.baseline.exp @@ -0,0 +1,11 @@ +processed 3 tasks +task 0 lines 3-10: publish [module 0x42::X {] +task 1 lines 13-19: publish [module 0x42::Y {] +task 2 lines 22-29: run [script {] +warning: unused alias + ┌─ TEMPFILE2:25:15 + │ +25 │ use 0x42::X; + │ ^ Unused 'use' of alias 'X'. Consider removing it + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp index fc5a4436b29..ea7628d7914 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-7: publish [module 0x42::X {] +task 1 lines 9-15: publish [module 0x42::Y {] +task 2 lines 18-25: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/arg_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/arg_order.exp index 5d92c423f3f..827bb094ba2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/arg_order.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/arg_order.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::test {] +task 1 lines 12-18: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.baseline.exp index c033a9e9292..ffa6bdc4703 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.baseline.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 9-15: +task 0 lines 1-7: run [script {] +task 1 lines 9-15: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,3 +8,4 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 4)], } +task 2 lines 17-23: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.no-optimize.exp index 95c5b096957..18568af5e50 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.no-optimize.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 9-15: +task 0 lines 1-7: run [script {] +task 1 lines 9-15: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,3 +8,4 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 5)], } +task 2 lines 17-23: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.opt-extra.exp new file mode 100644 index 00000000000..a364de432ab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.opt-extra.exp @@ -0,0 +1,11 @@ +processed 3 tasks +task 0 lines 1-7: run [script {] +task 1 lines 9-15: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 17-23: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.optimize.exp index c033a9e9292..ffa6bdc4703 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.optimize.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 9-15: +task 0 lines 1-7: run [script {] +task 1 lines 9-15: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,3 +8,4 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 4)], } +task 2 lines 17-23: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled new file mode 100644 index 00000000000..17225b5f25f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/arg_order.move` + +//# publish +module 0x42::test { + public fun two_args(p0: u64, p1: bool): u64 { + if (p1) return p0; + 0 + } +} + + +//# run +script { + use 0x42::test; + fun main() { + assert!(test::two_args(42, true) == 42, 1); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled.baseline.exp new file mode 100644 index 00000000000..da6a156a7ae --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/arg_order.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-9: publish [module 0x42::test {] +task 1 lines 12-18: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled new file mode 100644 index 00000000000..f356f2a5b57 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/lazy_assert.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1 / 0; + abort _v0 + } +} + + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled.baseline.exp new file mode 100644 index 00000000000..db731b527ed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/lazy_assert.decompiled.baseline.exp @@ -0,0 +1,11 @@ +processed 3 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-17: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 20-25: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled new file mode 100644 index 00000000000..3b47f75b4cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/short_circuiting.move` + +//# publish +module 0x42::X { + public fun error(): bool { + abort 42 + } +} + + +//# run +script { + use 0x42::X; + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled.baseline.exp new file mode 100644 index 00000000000..b6a254a0cfe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::X {] +task 1 lines 11-17: run [script {] +warning: unused alias + ┌─ TEMPFILE1:13:15 + │ +13 │ use 0x42::X; + │ ^ Unused 'use' of alias 'X'. Consider removing it + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled new file mode 100644 index 00000000000..66b30db2d81 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled @@ -0,0 +1,52 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/short_circuiting_invalid.move` + +//# publish +module 0x42::X { + public fun error(): bool { + abort 42 + } +} + + +//# run +script { + use 0x42::X; + fun main() { + let _v0 = X::error(); + } +} + + +//# run +script { + use 0x42::X; + fun main() { + let _v0 = X::error(); + } +} + + +//# run +script { + use 0x42::X; + fun main() { + if (X::error()) return (); + } +} + + +//# run +script { + use 0x42::X; + fun main() { + if (X::error()) return (); + } +} + + +//# run +script { + fun main() { + abort 0 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled.baseline.exp new file mode 100644 index 00000000000..8077414df92 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/short_circuiting_invalid.decompiled.baseline.exp @@ -0,0 +1,42 @@ +processed 6 tasks +task 0 lines 3-8: publish [module 0x42::X {] +task 1 lines 11-17: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 2 lines 20-26: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 3 lines 29-35: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 4 lines 38-44: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 5 lines 47-52: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled new file mode 100644 index 00000000000..05705c6c3d6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled @@ -0,0 +1,46 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/side_effecting_args.move` + +//# publish +module 0xdeadbeef::test { + fun add(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + fun test1(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = inc(&mut _v0); + let _v3 = inc(&mut _v0); + add(_v1, _v2, _v3) + } + fun test2(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0; + _v0 = _v0 + 1; + add(_v1, _v0, _v0) + } + fun test3(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0 + 1; + add(_v0, _v0, _v1) + } + fun test4(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0 + 1; + add(_v1, _v0, _v2) + } +} + + +//# run 0xdeadbeef::test::test1 + +//# run 0xdeadbeef::test::test2 + +//# run 0xdeadbeef::test::test3 + +//# run 0xdeadbeef::test::test4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled.baseline.exp new file mode 100644 index 00000000000..3a07155a597 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/side_effecting_args.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-37: publish [module 0xdeadbeef::test {] +task 1 lines 40-40: run 0xdeadbeef::test::test1 +return values: 6 +task 2 lines 42-42: run 0xdeadbeef::test::test2 +return values: 8 +task 3 lines 44-44: run 0xdeadbeef::test::test3 +return values: 7 +task 4 lines 46-46: run 0xdeadbeef::test::test4 +return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled new file mode 100644 index 00000000000..c2e15cc18b3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled @@ -0,0 +1,105 @@ +//**** Cross-compiled for `move` syntax from `tests/evaluation_order/struct_arguments.move` + +//# publish +module 0x42::M { + struct Cup has key { + a: u64, + b: R, + } + struct R has store, key { + } + struct S has drop { + a: u64, + b: u64, + } + fun fail(p0: u64): u64 { + abort p0 + } + fun mts(p0: &signer): u64 { + let _v0 = R{}; + let _v1 = Cup{a: 0, b: _v0}; + move_to(p0, _v1); + 0 + } + public fun t0() { + let _v0 = 1 / 0; + let _v1 = S{a: fail(0), b: _v0}; + } + public fun t1() { + let _v0 = 18446744073709551615 + 18446744073709551615; + let _v1 = S{a: fail(0), b: _v0}; + } + public fun t2() { + let _v0 = 0 - 1; + let _v1 = S{a: fail(0), b: _v0}; + } + public fun t3() { + let _v0 = 1 % 0; + let _v1 = S{a: fail(0), b: _v0}; + } + public fun t4() { + let _v0 = 18446744073709551615 * 18446744073709551615; + let _v1 = S{a: fail(0), b: _v0}; + } + public fun t6(p0: &signer) { + let _v0 = R{}; + let _v1 = Cup{a: 0, b: _v0}; + move_to(p0, _v1); + let _v2 = mts(p0); + let _v3 = S{a: fail(0), b: _v2}; + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::t0(); + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::t1(); + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::t2(); + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::t3(); + } +} + + +//# run +script { + use 0x42::M; + fun main() { + M::t4(); + } +} + + +//# run --signers 0x1 +script { + use 0x42::M; + fun main(p0: signer) { + M::t6(&p0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled.baseline.exp new file mode 100644 index 00000000000..b8f78ca03d9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/round-trip/struct_arguments.decompiled.baseline.exp @@ -0,0 +1,50 @@ +processed 7 tasks +task 0 lines 3-51: publish [module 0x42::M {] +task 1 lines 54-60: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 2)], +} +task 2 lines 63-69: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 2)], +} +task 3 lines 72-78: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], +} +task 4 lines 81-87: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], +} +task 5 lines 90-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], +} +task 6 lines 99-105: run --signers 0x1 [script {] +Error: Script execution failed with VMError: { + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 9)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp index 5d92c423f3f..b48cc108251 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-6: publish [module 0x42::X {] +task 1 lines 8-27: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.baseline.exp index 87b6bfd1255..7268615c49a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.baseline.exp @@ -1,6 +1,6 @@ processed 6 tasks - -task 1 'run'. lines 10-16: +task 0 lines 1-8: publish [module 0x42::X {] +task 1 lines 10-16: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 19-25: +task 2 lines 19-25: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'run'. lines 27-33: +task 3 lines 27-33: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 4 'run'. lines 35-41: +task 4 lines 35-41: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 5 'run'. lines 43-48: +task 5 lines 43-48: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.no-optimize.exp index 21cbc9bed3d..84500a5806f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.no-optimize.exp @@ -1,6 +1,6 @@ processed 6 tasks - -task 1 'run'. lines 10-16: +task 0 lines 1-8: publish [module 0x42::X {] +task 1 lines 10-16: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 19-25: +task 2 lines 19-25: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'run'. lines 27-33: +task 3 lines 27-33: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 4 'run'. lines 35-41: +task 4 lines 35-41: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 5 'run'. lines 43-48: +task 5 lines 43-48: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.opt-extra.exp new file mode 100644 index 00000000000..7268615c49a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.opt-extra.exp @@ -0,0 +1,42 @@ +processed 6 tasks +task 0 lines 1-8: publish [module 0x42::X {] +task 1 lines 10-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 2 lines 19-25: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 3 lines 27-33: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 4 lines 35-41: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.optimize.exp index 87b6bfd1255..7268615c49a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.optimize.exp @@ -1,6 +1,6 @@ processed 6 tasks - -task 1 'run'. lines 10-16: +task 0 lines 1-8: publish [module 0x42::X {] +task 1 lines 10-16: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 19-25: +task 2 lines 19-25: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'run'. lines 27-33: +task 3 lines 27-33: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 4 'run'. lines 35-41: +task 4 lines 35-41: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(42), @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 5 'run'. lines 43-48: +task 5 lines 43-48: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/side_effecting_args.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/side_effecting_args.exp index 7290b7f060e..9f299ee233c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/side_effecting_args.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/side_effecting_args.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 33-33: +task 0 lines 1-31: publish [module 0xdeadbeef::test {] +task 1 lines 33-33: run 0xdeadbeef::test::test1 return values: 6 - -task 2 'run'. lines 35-35: +task 2 lines 35-35: run 0xdeadbeef::test::test2 return values: 8 - -task 3 'run'. lines 37-37: +task 3 lines 37-37: run 0xdeadbeef::test::test3 return values: 7 - -task 4 'run'. lines 39-39: +task 4 lines 39-39: run 0xdeadbeef::test::test4 return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.baseline.exp index c36e8ed033f..e9109527cb8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.baseline.exp @@ -1,6 +1,6 @@ processed 7 tasks - -task 1 'run'. lines 57-64: +task 0 lines 3-55: publish [module 0x42::M {] +task 1 lines 57-64: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(2), 2)], } - -task 2 'run'. lines 66-73: +task 2 lines 66-73: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 2)], } - -task 3 'run'. lines 75-82: +task 3 lines 75-82: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(4), 2)], } - -task 4 'run'. lines 84-91: +task 4 lines 84-91: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 2)], } - -task 5 'run'. lines 93-110: +task 5 lines 93-110: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +40,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(6), 2)], } - -task 6 'run'. lines 112-119: +task 6 lines 112-119: run --signers 0x1 [script {] Error: Script execution failed with VMError: { major_status: RESOURCE_ALREADY_EXISTS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.no-optimize.exp index 742e80379c7..bd442ec9864 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.no-optimize.exp @@ -1,6 +1,6 @@ processed 7 tasks - -task 1 'run'. lines 57-64: +task 0 lines 3-55: publish [module 0x42::M {] +task 1 lines 57-64: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(2), 2)], } - -task 2 'run'. lines 66-73: +task 2 lines 66-73: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 2)], } - -task 3 'run'. lines 75-82: +task 3 lines 75-82: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(4), 2)], } - -task 4 'run'. lines 84-91: +task 4 lines 84-91: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 2)], } - -task 5 'run'. lines 93-110: +task 5 lines 93-110: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +40,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(6), 2)], } - -task 6 'run'. lines 112-119: +task 6 lines 112-119: run --signers 0x1 [script {] Error: Script execution failed with VMError: { major_status: RESOURCE_ALREADY_EXISTS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.opt-extra.exp new file mode 100644 index 00000000000..b9ff37d6eaa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.opt-extra.exp @@ -0,0 +1,50 @@ +processed 7 tasks +task 0 lines 3-55: publish [module 0x42::M {] +task 1 lines 57-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 2)], +} +task 2 lines 66-73: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 2)], +} +task 3 lines 75-82: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], +} +task 4 lines 84-91: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], +} +task 5 lines 93-110: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], +} +task 6 lines 112-119: run --signers 0x1 [script {] +Error: Script execution failed with VMError: { + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(7), 15)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.optimize.exp index c36e8ed033f..e9109527cb8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.optimize.exp @@ -1,6 +1,6 @@ processed 7 tasks - -task 1 'run'. lines 57-64: +task 0 lines 3-55: publish [module 0x42::M {] +task 1 lines 57-64: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(2), 2)], } - -task 2 'run'. lines 66-73: +task 2 lines 66-73: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 2)], } - -task 3 'run'. lines 75-82: +task 3 lines 75-82: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(4), 2)], } - -task 4 'run'. lines 84-91: +task 4 lines 84-91: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 2)], } - -task 5 'run'. lines 93-110: +task 5 lines 93-110: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +40,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(6), 2)], } - -task 6 'run'. lines 112-119: +task 6 lines 112-119: run --signers 0x1 [script {] Error: Script execution failed with VMError: { major_status: RESOURCE_ALREADY_EXISTS, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2_typed.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam2_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam_typed.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_noparam_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_typed.exp index 5d92c423f3f..797dc15424a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a.exp index 5d92c423f3f..a75374a9235 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::Test {] +task 1 lines 16-16: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a_typed.exp index 5d92c423f3f..a75374a9235 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991a_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::Test {] +task 1 lines 16-16: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b.exp index 5d92c423f3f..b0f070460be 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b_typed.exp index 5d92c423f3f..b0f070460be 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991b_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c.exp index 5d92c423f3f..b0f070460be 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c_typed.exp index 5d92c423f3f..b0f070460be 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_10991c_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11112.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11112.exp index 5d92c423f3f..ffbf12ab044 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11112.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11112.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0xcafe::vectors {] +task 1 lines 13-13: run 0xcafe::vectors::test_for_each_mut diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.baseline.exp index 89ed47cb9ec..5987f3e7d9d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.baseline.exp @@ -1,17 +1,14 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish --print-bytecode [module 0xcafe::vectors {] == BEGIN Bytecode == -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + borrow_loc l0 + vec_len + ret -entry public guess_flips_break2(Arg0: vector): u64 /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: vector) - 1: VecLen(2) - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.no-optimize.exp index 2eb67479209..d3a7dcec07d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.no-optimize.exp @@ -1,24 +1,22 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish --print-bytecode [module 0xcafe::vectors {] == BEGIN Bytecode == -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + local l1: &vector + borrow_loc l0 + copy_loc l0 + copy_loc l0 + pop + pop + // @5 + st_loc l1 + move_loc l1 + vec_len + ret -entry public guess_flips_break2(Arg0: vector): u64 /* def_idx: 0 */ { -L1: loc0: &vector -B0: - 0: ImmBorrowLoc[0](Arg0: vector) - 1: CopyLoc[0](Arg0: vector) - 2: CopyLoc[0](Arg0: vector) - 3: Pop - 4: Pop - 5: StLoc[1](loc0: &vector) - 6: MoveLoc[1](loc0: &vector) - 7: VecLen(2) - 8: Ret -} -} == END Bytecode == diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.opt-extra.exp new file mode 100644 index 00000000000..5987f3e7d9d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.opt-extra.exp @@ -0,0 +1,14 @@ +processed 1 task +task 0 lines 1-14: publish --print-bytecode [module 0xcafe::vectors {] + +== BEGIN Bytecode == +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + borrow_loc l0 + vec_len + ret + + +== END Bytecode == diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.optimize.exp index 89ed47cb9ec..5987f3e7d9d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_11223.optimize.exp @@ -1,17 +1,14 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish --print-bytecode [module 0xcafe::vectors {] == BEGIN Bytecode == -// Move bytecode v8 -module cafe.vectors { +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + borrow_loc l0 + vec_len + ret -entry public guess_flips_break2(Arg0: vector): u64 /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: vector) - 1: VecLen(2) - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717.exp index b134af1aea2..d197740c4f2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717.exp @@ -1 +1,6 @@ processed 5 tasks +task 0 lines 1-91: publish [module 0xcafe::vectors {] +task 1 lines 93-93: run 0xcafe::vectors::test_guess_with_inline_break +task 2 lines 95-95: run 0xcafe::vectors::test_guess_directly +task 3 lines 97-97: run 0xcafe::vectors::test_guess_with_break_no_inline +task 4 lines 99-99: run 0xcafe::vectors::test_guess_without_break diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717_looponly.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717_looponly.exp index b134af1aea2..79b5e2871c0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717_looponly.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/bug_9717_looponly.exp @@ -1 +1,6 @@ processed 5 tasks +task 0 lines 1-130: publish [module 0xcafe::vectors {] +task 1 lines 132-132: run 0xcafe::vectors::test_guess_flips_break +task 2 lines 134-134: run 0xcafe::vectors::test_guess_flips_abort +task 3 lines 136-136: run 0xcafe::vectors::test_guess_flips_nocheck +task 4 lines 138-138: run 0xcafe::vectors::test_guess_flips_continue diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/deep_exp.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/deep_exp.exp index b442b199ed7..e50b33456a9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/deep_exp.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/deep_exp.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 30-30: +task 0 lines 1-28: publish [// TODO(#12036): should pass once optimizations on by default] +task 1 lines 30-30: run 0x42::Test::test return values: 625 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param.exp index 5d92c423f3f..4fd0c4774ea 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0x42::Test {] +task 1 lines 15-15: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_some_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_some_typed.exp index 5d92c423f3f..4fd0c4774ea 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_some_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_some_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0x42::Test {] +task 1 lines 15-15: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_typed.exp index 5d92c423f3f..4fd0c4774ea 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/eval_ignored_param_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0x42::Test {] +task 1 lines 15-15: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp index 2dd983c468e..8595bd0f37d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/function_name_shadowing.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'publish'. lines 12-28: +task 0 lines 1-10: publish [module 0x42::OtherModule {] +task 1 lines 12-28: publish [module 0x42::Test {] warning: Unused parameter `f`. Consider removing or prefixing with an underscore: `_f` ┌─ TEMPFILE1:18:28 │ @@ -20,6 +20,5 @@ warning: Unused parameter `i`. Consider removing or prefixing with an underscore │ ^ - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0x42::Test::test_shadowing return values: 5280 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics.exp index 4c386977e2c..3be16328bec 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 22-22: +task 0 lines 1-20: publish [module 0x42::Test {] +task 1 lines 22-22: run 0x42::Test::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics_typed.exp index 4c386977e2c..3be16328bec 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/generics_typed.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 22-22: +task 0 lines 1-20: publish [module 0x42::Test {] +task 1 lines 22-22: run 0x42::Test::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda.exp index fc3cb918aa6..a2202bdc5a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda_typed.exp index fc3cb918aa6..a2202bdc5a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/lambda_typed.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking.exp index fd7407ee71f..330eb1174f0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::main return values: 110 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking_typed.exp index fd7407ee71f..330eb1174f0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/masking_typed.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0x42::Test {] +task 1 lines 12-12: run 0x42::Test::main return values: 110 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param.exp index 5d92c423f3f..72d168bfc9d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-29: publish [module 0x42::Test {] +task 1 lines 31-31: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param_typed.exp index 63a14da132d..91a119800f3 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/multi_param_typed.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-29: +task 0 lines 1-29: publish [module 0x42::Test {] Error: compilation errors: error: a reference is expected but `_` was provided ┌─ TEMPFILE:24:82 @@ -21,8 +20,7 @@ error: expected function type has argument of type `(&integer, &mut integer)` bu │ ^^^^^^^^^^^^^^^^^^^^^^^^ - -task 1 'run'. lines 31-31: +task 1 lines 31-31: run 0x42::Test::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/mutual_recursion.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/mutual_recursion.exp index 5d92c423f3f..fa672658ba4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/mutual_recursion.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/mutual_recursion.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-26: publish [module 0x42::Mutual {] +task 1 lines 28-28: run 0x42::Mutual::recursion_check diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda.exp index fc3cb918aa6..a2202bdc5a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module.exp index 88b423d37b4..254748d5afb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 17-17: +task 0 lines 1-6: publish [module 0x42::Test1 {] +task 1 lines 8-15: publish [module 0x42::Test {] +task 2 lines 17-17: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module_typed.exp index 88b423d37b4..254748d5afb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_module_typed.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 17-17: +task 0 lines 1-6: publish [module 0x42::Test1 {] +task 1 lines 8-15: publish [module 0x42::Test {] +task 2 lines 17-17: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_typed.exp index fc3cb918aa6..a2202bdc5a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/nested_lambda_typed.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/objects.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/objects.exp index fc5a4436b29..a2d498188d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/objects.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/objects.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-74: publish [// A module which provides the functions to manage objects.] +task 1 lines 76-101: publish [module 0x42::token {] +task 2 lines 103-115: run --signers 0x42 [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options.exp index ffa059dd286..54a324a9145 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 27-27: +task 0 lines 1-13: publish [module 0x42::map_opt {] +task 1 lines 15-25: publish [module 0x42::Test {] +task 2 lines 27-27: run 0x42::Test::test return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options_typed.exp index ffa059dd286..54a324a9145 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/options_typed.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 27-27: +task 0 lines 1-13: publish [module 0x42::map_opt {] +task 1 lines 15-25: publish [module 0x42::Test {] +task 2 lines 27-27: run 0x42::Test::test return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/phantoms.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/phantoms.exp index 5d92c423f3f..32fc03392d5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/phantoms.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/phantoms.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0x42::phantoms {] +task 1 lines 18-18: run 0x42::phantoms::test_phantoms diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/resources.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/resources.exp index 5d92c423f3f..86f52837487 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/resources.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/resources.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::M {] +task 1 lines 16-22: run --signers 0x42 [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled new file mode 100644 index 00000000000..91115eec91d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled new file mode 100644 index 00000000000..4c08dc24ee9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991_noparam.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled new file mode 100644 index 00000000000..7b1ad51dda7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991_noparam2.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled new file mode 100644 index 00000000000..a1ad314b2cd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991_noparam2_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam2_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled new file mode 100644 index 00000000000..6eec167a82a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991_noparam_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_noparam_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled new file mode 100644 index 00000000000..4436a2a70ef --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled new file mode 100644 index 00000000000..ad964a191ec --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991a.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled new file mode 100644 index 00000000000..f34051ddf47 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991a_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991a_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled new file mode 100644 index 00000000000..4fdbd96493d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991b.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled new file mode 100644 index 00000000000..3b2b37323d2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991b_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991b_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled new file mode 100644 index 00000000000..f6284ac9e15 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991c.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled new file mode 100644 index 00000000000..629daf64bf6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_10991c_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + () + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..da76be1ff35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_10991c_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled new file mode 100644 index 00000000000..c7bac2c149e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_11112.move` + +//# publish +module 0xcafe::vectors { + fun test_for_each_mut() { + let _v0 = vector[1, 2, 3]; + let _v1 = 2; + let _v2 = &mut _v0; + let _v3 = 0; + loop { + let _v4 = 0x1::vector::length(freeze(_v2)); + if (!(_v3 < _v4)) break; + let _v5 = 0x1::vector::borrow_mut(_v2, _v3); + *_v5 = _v1; + _v1 = _v1 + 1; + _v3 = _v3 + 1; + continue + }; + assert!(_v0 == vector[2, 3, 4], 0); + } +} + + +//# run 0xcafe::vectors::test_for_each_mut \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled.baseline.exp new file mode 100644 index 00000000000..f418770c83e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11112.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0xcafe::vectors {] +task 1 lines 24-24: run 0xcafe::vectors::test_for_each_mut diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled new file mode 100644 index 00000000000..95d3e85f3fb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_11223.move` + +//# publish --print-bytecode +module 0xcafe::vectors { + public entry fun guess_flips_break2(p0: vector): u64 { + 0x1::vector::length(&p0) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled.baseline.exp new file mode 100644 index 00000000000..2d42d85fc1d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_11223.decompiled.baseline.exp @@ -0,0 +1,14 @@ +processed 1 task +task 0 lines 3-8: publish --print-bytecode [module 0xcafe::vectors {] + +== BEGIN Bytecode == +// Bytecode version v9 +module 0xcafe::vectors +// Function definition at index 0 +#[persistent] entry public fun guess_flips_break2(l0: vector): u64 + borrow_loc l0 + vec_len + ret + + +== END Bytecode == diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled new file mode 100644 index 00000000000..9cefd950b28 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled @@ -0,0 +1,77 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_9717.move` + +//# publish +module 0xcafe::vectors { + public entry fun guess_flips(p0: vector) { + let _v0 = &p0; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(_v0); + if (!(_v1 < _v2)) break; + if (*0x1::vector::borrow(_v0, _v1) != 0u8) break; + _v1 = _v1 + 1; + continue + }; + } + public entry fun guess_flips_directly(p0: vector) { + let _v0 = 0; + loop { + let _v1 = 0x1::vector::length(&p0); + if (!(_v0 < _v1)) break; + if (*0x1::vector::borrow(&p0, _v0) != 0u8) break; + _v0 = _v0 + 1; + continue + }; + } + public entry fun guess_with_break_without_inline(p0: vector) { + loops_with_break_no_inline(&p0); + } + fun loops_with_break_no_inline(p0: &vector) { + let _v0 = 0; + 'l0: loop { + loop { + let _v1 = 0x1::vector::length(p0); + if (!(_v0 < _v1)) break 'l0; + if (*0x1::vector::borrow(p0, _v0) != 0u8) break; + _v0 = _v0 + 1; + continue + }; + return () + }; + } + public entry fun guess_without_break_with_inline(p0: vector) { + let _v0 = &p0; + let _v1 = 0; + 'l0: loop { + loop { + let _v2 = 0x1::vector::length(_v0); + if (!(_v1 < _v2)) break 'l0; + if (!(*0x1::vector::borrow(_v0, _v1) == 0u8)) break; + _v1 = _v1 + 1; + continue + }; + abort 3 + }; + } + fun test_guess_directly() { + guess_flips_directly(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_with_break_no_inline() { + guess_with_break_without_inline(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_with_inline_break() { + guess_flips(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_without_break() { + guess_without_break_with_inline(vector[0u8, 0u8, 0u8, 0u8]); + } +} + + +//# run 0xcafe::vectors::test_guess_with_inline_break + +//# run 0xcafe::vectors::test_guess_directly + +//# run 0xcafe::vectors::test_guess_with_break_no_inline + +//# run 0xcafe::vectors::test_guess_without_break \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled.baseline.exp new file mode 100644 index 00000000000..3f80fb29f83 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 5 tasks +task 0 lines 3-68: publish [module 0xcafe::vectors {] +task 1 lines 71-71: run 0xcafe::vectors::test_guess_with_inline_break +task 2 lines 73-73: run 0xcafe::vectors::test_guess_directly +task 3 lines 75-75: run 0xcafe::vectors::test_guess_with_break_no_inline +task 4 lines 77-77: run 0xcafe::vectors::test_guess_without_break diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled new file mode 100644 index 00000000000..6365336ece8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled @@ -0,0 +1,102 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/bug_9717_looponly.move` + +//# publish +module 0xcafe::vectors { + public entry fun entry_test_guess_flips_abort() { + guess_flips_abort(vector[0u8, 0u8, 0u8, 0u8]); + } + public entry fun guess_flips_abort(p0: vector) { + let _v0 = 0; + let _v1 = &p0; + 'l0: loop { + loop { + let _v2 = 0x1::vector::length(_v1); + if (!(_v0 < _v2)) break 'l0; + if (!(*0x1::vector::borrow(_v1, _v0) == 0u8)) break; + _v0 = _v0 + 1; + continue + }; + abort 3 + }; + } + public entry fun entry_test_guess_flips_break() { + guess_flips_break(vector[0u8, 0u8, 0u8, 0u8]); + } + public entry fun guess_flips_break(p0: vector) { + let _v0 = 0; + let _v1 = &p0; + loop { + let _v2 = 0x1::vector::length(_v1); + if (!(_v0 < _v2)) break; + if (*0x1::vector::borrow(_v1, _v0) != 0u8) break; + _v0 = _v0 + 1; + continue + }; + } + public entry fun entry_test_guess_flips_break2() { + guess_flips_break2(vector[0u8, 0u8, 0u8, 0u8]); + } + public entry fun guess_flips_break2(p0: vector) { + let _v0 = 0; + let _v1 = &p0; + loop { + let _v2 = 0x1::vector::length(_v1); + if (!(_v0 < _v2)) break; + if (*0x1::vector::borrow(_v1, _v0) != 0u8) break; + _v0 = _v0 + 1; + if (!(*0x1::vector::borrow(_v1, _v0) == 5u8)) continue; + break + }; + } + public entry fun entry_test_guess_flips_continue() { + guess_flips_continue(vector[0u8, 0u8, 0u8, 0u8]); + } + public entry fun guess_flips_continue(p0: vector) { + let _v0 = 0; + let _v1 = &p0; + loop { + let _v2 = 0x1::vector::length(_v1); + if (!(_v0 < _v2)) break; + if (*0x1::vector::borrow(_v1, _v0) != 0u8) continue; + _v0 = _v0 + 1; + continue + }; + } + public entry fun entry_test_guess_flips_nocheck() { + guess_flips_nocheck(vector[0u8, 0u8, 0u8, 0u8]); + } + public entry fun guess_flips_nocheck(p0: vector) { + let _v0 = 0; + let _v1 = &p0; + loop { + let _v2 = 0x1::vector::length(_v1); + if (!(_v0 < _v2)) break; + _v0 = _v0 + 1; + continue + }; + } + fun test_guess_flips_abort() { + guess_flips_abort(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_flips_break() { + guess_flips_break(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_flips_break2() { + guess_flips_break2(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_flips_continue() { + guess_flips_continue(vector[0u8, 0u8, 0u8, 0u8]); + } + fun test_guess_flips_nocheck() { + guess_flips_nocheck(vector[0u8, 0u8, 0u8, 0u8]); + } +} + + +//# run 0xcafe::vectors::test_guess_flips_break + +//# run 0xcafe::vectors::test_guess_flips_abort + +//# run 0xcafe::vectors::test_guess_flips_nocheck + +//# run 0xcafe::vectors::test_guess_flips_continue \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled.baseline.exp new file mode 100644 index 00000000000..f67197a034d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/bug_9717_looponly.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 5 tasks +task 0 lines 3-93: publish [module 0xcafe::vectors {] +task 1 lines 96-96: run 0xcafe::vectors::test_guess_flips_break +task 2 lines 98-98: run 0xcafe::vectors::test_guess_flips_abort +task 3 lines 100-100: run 0xcafe::vectors::test_guess_flips_nocheck +task 4 lines 102-102: run 0xcafe::vectors::test_guess_flips_continue diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled new file mode 100644 index 00000000000..73e1b83c503 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/deep_exp.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 625 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled.baseline.exp new file mode 100644 index 00000000000..920a820f1f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/deep_exp.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 625 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled new file mode 100644 index 00000000000..71e19288810 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/eval_ignored_param.move` + +//# publish +module 0x42::Test { + public fun test() { + let _v0 = 1 + 1; + let _v1 = 100 + 1; + let _v2 = 1000 + 1; + let _v3 = _v1; + let _v4 = _v0 * _v2; + _v0 = _v0 + 1; + _v3 = _v3 + 1; + _v2 = _v2 + 1; + let _v5 = _v4 + _v3; + let _v6 = 3 * _v0; + let _v7 = _v5 + _v6; + let _v8 = 5 * _v3; + let _v9 = _v7 + _v8; + let _v10 = 7 * _v2; + _v0 = _v9 + _v10; + assert!(_v0 == 9637, _v0); + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled.baseline.exp new file mode 100644 index 00000000000..8cb2a0d8334 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-23: publish [module 0x42::Test {] +task 1 lines 26-26: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled new file mode 100644 index 00000000000..4164906718d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/eval_ignored_param_some_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + let _v0 = 1 + 1; + let _v1 = 100 + 1; + let _v2 = 1000 + 1; + let _v3 = _v1; + let _v4 = _v0 * _v2; + _v0 = _v0 + 1; + _v3 = _v3 + 1; + _v2 = _v2 + 1; + let _v5 = _v4 + _v3; + let _v6 = 3 * _v0; + let _v7 = _v5 + _v6; + let _v8 = 5 * _v3; + let _v9 = _v7 + _v8; + let _v10 = 7 * _v2; + _v0 = _v9 + _v10; + assert!(_v0 == 9637, _v0); + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..8cb2a0d8334 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_some_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-23: publish [module 0x42::Test {] +task 1 lines 26-26: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled new file mode 100644 index 00000000000..5c4a783712c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/eval_ignored_param_typed.move` + +//# publish +module 0x42::Test { + public fun test() { + let _v0 = 1 + 1; + let _v1 = 100 + 1; + let _v2 = 1000 + 1; + let _v3 = _v1; + let _v4 = _v0 * _v2; + _v0 = _v0 + 1; + _v3 = _v3 + 1; + _v2 = _v2 + 1; + let _v5 = _v4 + _v3; + let _v6 = 3 * _v0; + let _v7 = _v5 + _v6; + let _v8 = 5 * _v3; + let _v9 = _v7 + _v8; + let _v10 = 7 * _v2; + _v0 = _v9 + _v10; + assert!(_v0 == 9637, _v0); + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..8cb2a0d8334 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/eval_ignored_param_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-23: publish [module 0x42::Test {] +task 1 lines 26-26: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled new file mode 100644 index 00000000000..42e068ff275 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled @@ -0,0 +1,30 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/function_name_shadowing.move` + +//# publish +module 0x42::OtherModule { + public fun g(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun h(p0: u64, p1: u64): u64 { + 2 * p0 + p1 + } +} + + +//# publish +module 0x42::Test { + use 0x42::OtherModule; + public fun f(p0: u64, p1: u64): u64 { + p0 * p1 + } + public fun test_shadowing(): u64 { + let _v0 = f(10, 2); + let _v1 = OtherModule::g(10, 2); + let _v2 = _v0 * _v1; + let _v3 = OtherModule::h(10, 2); + _v2 * _v3 + } +} + + +//# run 0x42::Test::test_shadowing \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled.baseline.exp new file mode 100644 index 00000000000..37c1ac4db0c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/function_name_shadowing.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-11: publish [module 0x42::OtherModule {] +task 1 lines 14-27: publish [module 0x42::Test {] +task 2 lines 30-30: run 0x42::Test::test_shadowing +return values: 5280 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled new file mode 100644 index 00000000000..5d82273eb20 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/generics.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + let _v0 = 0; + let _v1 = vector[1, 2, 3]; + let _v2 = &_v1; + let _v3 = 0; + loop { + let _v4 = 0x1::vector::length(_v2); + if (!(_v3 < _v4)) break; + let _v5 = *0x1::vector::borrow(_v2, _v3); + _v0 = _v0 + _v5; + _v3 = _v3 + 1; + continue + }; + _v0 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled.baseline.exp new file mode 100644 index 00000000000..14a46e23f55 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0x42::Test {] +task 1 lines 23-23: run 0x42::Test::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled new file mode 100644 index 00000000000..4c9de7c8c3b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/generics_typed.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + let _v0 = 0; + let _v1 = vector[1, 2, 3]; + let _v2 = &_v1; + let _v3 = 0; + loop { + let _v4 = 0x1::vector::length(_v2); + if (!(_v3 < _v4)) break; + let _v5 = *0x1::vector::borrow(_v2, _v3); + _v0 = _v0 + _v5; + _v3 = _v3 + 1; + continue + }; + _v0 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..14a46e23f55 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/generics_typed.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0x42::Test {] +task 1 lines 23-23: run 0x42::Test::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled new file mode 100644 index 00000000000..741c7f79d8e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/lambda.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled.baseline.exp new file mode 100644 index 00000000000..48ba06a9f8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled new file mode 100644 index 00000000000..55ae3e9ee72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/lambda_typed.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..48ba06a9f8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/lambda_typed.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled new file mode 100644 index 00000000000..402facc5cde --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/masking.move` + +//# publish +module 0x42::Test { + public fun main(): u64 { + 110 + } +} + + +//# run 0x42::Test::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled.baseline.exp new file mode 100644 index 00000000000..266a51e46da --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::main +return values: 110 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled new file mode 100644 index 00000000000..669c451a0e7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/masking_typed.move` + +//# publish +module 0x42::Test { + public fun main(): u64 { + 110 + } +} + + +//# run 0x42::Test::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..266a51e46da --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/masking_typed.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::main +return values: 110 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled new file mode 100644 index 00000000000..359ee0fee34 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled @@ -0,0 +1,35 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/multi_param.move` + +//# publish +module 0x42::Test { + struct Elem has drop { + k: T0, + v: T1, + } + public fun test() { + let _v0 = Elem{k: 1, v: 2}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = _v1; + let _v3 = &mut _v2; + let _v4 = 0; + let _v5 = 0; + loop { + let _v6 = 0x1::vector::length>(freeze(_v3)); + if (!(_v5 < _v6)) break; + let _v7 = 0x1::vector::borrow_mut>(_v3, _v5); + let _v8 = &_v7.k; + let _v9 = &mut _v7.v; + let _v10 = *_v8; + let _v11 = *_v9; + let _v12 = _v10 + _v11; + _v4 = _v4 + _v12; + _v5 = _v5 + 1; + continue + }; + assert!(_v4 == 3, 0); + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled.baseline.exp new file mode 100644 index 00000000000..2ea31ede76d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-32: publish [module 0x42::Test {] +task 1 lines 35-35: run 0x42::Test::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled new file mode 100644 index 00000000000..bbd46b17e02 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled @@ -0,0 +1,3 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/multi_param_typed.move` + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..92d1f6708cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/multi_param_typed.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-3: run 0x42::Test::test +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled new file mode 100644 index 00000000000..487083a3335 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/mutual_recursion.move` + +//# publish +module 0x42::Mutual { + fun even(p0: u64): bool { + let _v0 = p0 == 0; + loop { + if (_v0) return true else { + p0 = p0 - 1; + if (!(p0 == 0)) break + }; + return false + }; + even(p0 - 1) + } + public fun recursion_check() { + assert!(even(4), 0); + assert!(even(4), 0); + } +} + + +//# run 0x42::Mutual::recursion_check \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled.baseline.exp new file mode 100644 index 00000000000..54d5446df1b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/mutual_recursion.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0x42::Mutual {] +task 1 lines 23-23: run 0x42::Mutual::recursion_check diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled new file mode 100644 index 00000000000..af2718ead2d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/nested_lambda.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled.baseline.exp new file mode 100644 index 00000000000..48ba06a9f8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled new file mode 100644 index 00000000000..f9c56c30f8a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/nested_lambda_module.move` + +//# publish +module 0x42::Test1 { +} + + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled.baseline.exp new file mode 100644 index 00000000000..f6c01b5e070 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::Test1 {] +task 1 lines 8-13: publish [module 0x42::Test {] +task 2 lines 16-16: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled new file mode 100644 index 00000000000..353d26aed57 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/nested_lambda_module_typed.move` + +//# publish +module 0x42::Test1 { +} + + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..f6c01b5e070 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_module_typed.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::Test1 {] +task 1 lines 8-13: publish [module 0x42::Test {] +task 2 lines 16-16: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled new file mode 100644 index 00000000000..bdbe8d1e2b4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/nested_lambda_typed.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..48ba06a9f8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/nested_lambda_typed.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled new file mode 100644 index 00000000000..0fe5d870601 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled @@ -0,0 +1,86 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/objects.move` + +//# publish +module 0x42::objects { + struct OwnerRef has drop { + addr: address, + } + struct ReaderRef has drop, store { + addr: address, + } + struct WriterRef has drop, store { + addr: address, + } + public fun make_owner_ref(p0: address): OwnerRef { + OwnerRef{addr: p0} + } + public fun make_reader_ref(p0: address): ReaderRef { + ReaderRef{addr: p0} + } + public fun make_writer_ref(p0: address): WriterRef { + WriterRef{addr: p0} + } + public fun owner_addr_of(p0: &OwnerRef): address { + *&p0.addr + } + public fun reader_addr_of(p0: &ReaderRef): address { + *&p0.addr + } + public fun writer_addr_of(p0: &WriterRef): address { + *&p0.addr + } +} + + +//# publish +module 0x42::token { + use 0x42::objects; + struct Token has key { + val: u64, + } + public fun create(p0: &signer, p1: &objects::OwnerRef, p2: u64) { + let _v0 = Token{val: p2}; + move_to(p0, _v0); + } + public fun reader_ref(p0: &objects::OwnerRef): objects::ReaderRef { + let _v0 = objects::owner_addr_of(p0); + assert!(exists(_v0), 22); + objects::make_reader_ref(_v0) + } + public fun writer_ref(p0: &objects::OwnerRef): objects::WriterRef { + let _v0 = objects::owner_addr_of(p0); + assert!(exists(_v0), 23); + objects::make_writer_ref(_v0) + } + public fun get_value(p0: &objects::ReaderRef): u64 + acquires Token + { + let _v0 = objects::reader_addr_of(p0); + *&borrow_global(_v0).val + } + public fun set_value(p0: &objects::WriterRef, p1: u64) + acquires Token + { + let _v0 = objects::writer_addr_of(p0); + let _v1 = &mut borrow_global_mut(_v0).val; + *_v1 = p1; + } +} + + +//# run --signers 0x42 +script { + use 0x42::objects; + use 0x42::token; + fun main(p0: signer) { + let _v0 = objects::make_owner_ref(@0x42); + let _v1 = &p0; + let _v2 = &_v0; + token::create(_v1, _v2, 22); + let _v3 = token::reader_ref(&_v0); + let _v4 = token::writer_ref(&_v0); + assert!(token::get_value(&_v3) == 22, 0); + token::set_value(&_v4, 23); + assert!(token::get_value(&_v3) == 23, 1); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled.baseline.exp new file mode 100644 index 00000000000..330cff23f31 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/objects.decompiled.baseline.exp @@ -0,0 +1,11 @@ +processed 3 tasks +task 0 lines 3-32: publish [module 0x42::objects {] +task 1 lines 35-68: publish [module 0x42::token {] +warning: Unused value of parameter `p1`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p1`), or binding to `_` + ┌─ TEMPFILE1:41:36 + │ +41 │ public fun create(p0: &signer, p1: &objects::OwnerRef, p2: u64) { + │ ^^ + + +task 2 lines 71-86: run --signers 0x42 [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled new file mode 100644 index 00000000000..4a915d2ffc0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/options.move` + +//# publish +module 0x42::map_opt { +} + + +//# publish +module 0x42::Test { + use 0x1::option; + public fun test(): u64 { + let _v0; + let _v1 = option::some(1); + if (option::is_some(&_v1)) _v0 = option::some(option::extract(&mut _v1) + 1) else _v0 = option::none(); + option::extract(&mut _v0) + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled.baseline.exp new file mode 100644 index 00000000000..530160a1616 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::map_opt {] +task 1 lines 8-17: publish [module 0x42::Test {] +task 2 lines 20-20: run 0x42::Test::test +return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled new file mode 100644 index 00000000000..3ccf7ca32a5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/options_typed.move` + +//# publish +module 0x42::map_opt { +} + + +//# publish +module 0x42::Test { + use 0x1::option; + public fun test(): u64 { + let _v0; + let _v1 = option::some(1); + if (option::is_some(&_v1)) _v0 = option::some(option::extract(&mut _v1) + 1) else _v0 = option::none(); + option::extract(&mut _v0) + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..530160a1616 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/options_typed.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::map_opt {] +task 1 lines 8-17: publish [module 0x42::Test {] +task 2 lines 20-20: run 0x42::Test::test +return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled new file mode 100644 index 00000000000..abd015840ff --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/phantoms.move` + +//# publish +module 0x42::phantoms { + struct T { + } + struct S has drop { + addr: address, + } + public fun test_phantoms() { + let _v0 = S{addr: @0x12}; + } +} + + +//# run 0x42::phantoms::test_phantoms \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled.baseline.exp new file mode 100644 index 00000000000..2b5ace744cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/phantoms.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0x42::phantoms {] +task 1 lines 16-16: run 0x42::phantoms::test_phantoms diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled new file mode 100644 index 00000000000..b51480f3245 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/resources.move` + +//# publish +module 0x42::M { + struct R has key { + f: u64, + } + public fun test_resource(p0: &signer) + acquires R + { + let _v0 = R{f: 1}; + move_to(p0, _v0); + assert!(*&borrow_global(@0x42).f == 1, 1); + } +} + + +//# run --signers 0x42 +script { + use 0x42::M; + fun main(p0: signer) { + M::test_resource(&p0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled.baseline.exp new file mode 100644 index 00000000000..9e5bbe5fa63 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/resources.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0x42::M {] +task 1 lines 18-24: run --signers 0x42 [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled new file mode 100644 index 00000000000..2fe0465765b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing.move` + +//# publish +module 0x42::Test { + public fun test_shadowing() { + assert!(3 == 3, 0); + } +} + + +//# run 0x42::Test::test_shadowing \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled.baseline.exp new file mode 100644 index 00000000000..b056aafedf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled new file mode 100644 index 00000000000..c783c0109e7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing_renamed.move` + +//# publish +module 0x42::Test { + public fun test_shadowing() { + assert!(3 == 3, 0); + } +} + + +//# run 0x42::Test::test_shadowing \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled.baseline.exp new file mode 100644 index 00000000000..b056aafedf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled new file mode 100644 index 00000000000..2d72d1fb77c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing_renamed_param.move` + +//# publish +module 0x42::Test { + public fun test_shadowing(p0: u64) { + assert!(3 == 3, 0); + assert!(5 == 5, 0); + } + public fun test_shadowing2(p0: u64) { + assert!(3 == 3, 0); + assert!(5 == 5, 0); + } + fun test_shadowing_entry() { + test_shadowing(1); + test_shadowing2(1); + } +} + + +//# run 0x42::Test::test_shadowing_entry \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled.baseline.exp new file mode 100644 index 00000000000..99f07239318 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0x42::Test {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:5:31 + │ +5 │ public fun test_shadowing(p0: u64) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:9:32 + │ +9 │ public fun test_shadowing2(p0: u64) { + │ ^^ + + +task 1 lines 20-20: run 0x42::Test::test_shadowing_entry diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled new file mode 100644 index 00000000000..8a03f2a3542 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing_renamed_param_typed.move` + +//# publish +module 0x42::Test { + public fun test_shadowing(p0: u64) { + assert!(3 == 3, 0); + assert!(5 == 5, 0); + } + public fun test_shadowing2(p0: u64) { + assert!(3 == 3, 0); + assert!(5 == 5, 0); + } + fun test_shadowing_entry() { + test_shadowing(1); + test_shadowing2(1); + } +} + + +//# run 0x42::Test::test_shadowing_entry \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..99f07239318 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_param_typed.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0x42::Test {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:5:31 + │ +5 │ public fun test_shadowing(p0: u64) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:9:32 + │ +9 │ public fun test_shadowing2(p0: u64) { + │ ^^ + + +task 1 lines 20-20: run 0x42::Test::test_shadowing_entry diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled new file mode 100644 index 00000000000..c532912b755 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing_renamed_typed.move` + +//# publish +module 0x42::Test { + public fun test_shadowing() { + assert!(3 == 3, 0); + } +} + + +//# run 0x42::Test::test_shadowing \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..b056aafedf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_renamed_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled new file mode 100644 index 00000000000..c5c752c1670 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/shadowing_typed.move` + +//# publish +module 0x42::Test { + public fun test_shadowing() { + assert!(3 == 3, 0); + } +} + + +//# run 0x42::Test::test_shadowing \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..b056aafedf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/shadowing_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled new file mode 100644 index 00000000000..a43cd0a9884 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/simple.move` + +//# publish +module 0x42::Test { + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled.baseline.exp new file mode 100644 index 00000000000..48ba06a9f8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/simple.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x42::Test {] +task 1 lines 11-11: run 0x42::Test::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled new file mode 100644 index 00000000000..0e8f9a68fd0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/two_level_modules.move` + +//# publish +module 0x42::TwoLevelTestModule { +} + + +//# publish +module 0x42::TwoLevelTestMain { + public fun test(): u64 { + 18 + } +} + + +//# run 0x42::TwoLevelTestMain::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled.baseline.exp new file mode 100644 index 00000000000..bf6a56e80ef --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 8-13: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 16-16: run 0x42::TwoLevelTestMain::test +return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled new file mode 100644 index 00000000000..a3e9a202215 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/two_level_modules_inline.move` + +//# publish +module 0x42::TwoLevelTestModule { +} + + +//# publish +module 0x42::TwoLevelTestMain { + public fun main(): u64 { + 18 + } +} + + +//# run 0x42::TwoLevelTestMain::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled.baseline.exp new file mode 100644 index 00000000000..8b797a6b851 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_inline.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 8-13: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 16-16: run 0x42::TwoLevelTestMain::main +return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled new file mode 100644 index 00000000000..a57e6e27a11 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/two_level_modules_noinline.move` + +//# publish +module 0x42::TwoLevelTestModule { +} + + +//# publish +module 0x42::TwoLevelTestMain { + public fun main(): u64 { + test() + } + fun test(): u64 { + 18 + } +} + + +//# run 0x42::TwoLevelTestMain::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled.baseline.exp new file mode 100644 index 00000000000..1ad3dff4ef3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_noinline.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 8-16: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 19-19: run 0x42::TwoLevelTestMain::main +return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled new file mode 100644 index 00000000000..5b98e4a3f33 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/two_level_modules_pubinline.move` + +//# publish +module 0x42::TwoLevelTestModule { +} + + +//# publish +module 0x42::TwoLevelTestMain { + public fun main(): u64 { + 18 + } +} + + +//# run 0x42::TwoLevelTestMain::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled.baseline.exp new file mode 100644 index 00000000000..8b797a6b851 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubinline.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 8-13: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 16-16: run 0x42::TwoLevelTestMain::main +return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled new file mode 100644 index 00000000000..0fa3fa48d59 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/inlining/two_level_modules_pubnoinline.move` + +//# publish +module 0x42::TwoLevelTestModule { +} + + +//# publish +module 0x42::TwoLevelTestMain { + public fun main(): u64 { + test() + } + public fun test(): u64 { + 18 + } +} + + +//# run 0x42::TwoLevelTestMain::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled.baseline.exp new file mode 100644 index 00000000000..1ad3dff4ef3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/round-trip/two_level_modules_pubnoinline.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-5: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 8-16: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 19-19: run 0x42::TwoLevelTestMain::main +return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing.exp index 5d92c423f3f..d488bc66200 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-21: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed.exp index d4f1bbeb85c..04c3c2b6b59 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-19: +task 0 lines 1-19: publish [module 0x42::Test {] warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` ┌─ TEMPFILE:8:17 │ @@ -8,3 +7,4 @@ warning: This assignment/binding to the left-hand-side variable `x` is unused. C │ ^ +task 1 lines 21-21: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param.exp index a584a20f248..fa5827a370a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-46: +task 0 lines 1-46: publish [module 0x42::Test {] warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` ┌─ TEMPFILE:10:31 │ @@ -14,3 +13,4 @@ warning: This assignment/binding to the left-hand-side variable `x` is unused. C │ ^ +task 1 lines 48-48: run 0x42::Test::test_shadowing_entry diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param_typed.exp index a584a20f248..fa5827a370a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_param_typed.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-46: +task 0 lines 1-46: publish [module 0x42::Test {] warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` ┌─ TEMPFILE:10:31 │ @@ -14,3 +13,4 @@ warning: This assignment/binding to the left-hand-side variable `x` is unused. C │ ^ +task 1 lines 48-48: run 0x42::Test::test_shadowing_entry diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_typed.exp index d4f1bbeb85c..04c3c2b6b59 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_renamed_typed.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-19: +task 0 lines 1-19: publish [module 0x42::Test {] warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` ┌─ TEMPFILE:8:17 │ @@ -8,3 +7,4 @@ warning: This assignment/binding to the left-hand-side variable `x` is unused. C │ ^ +task 1 lines 21-21: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_typed.exp index 5d92c423f3f..d488bc66200 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/shadowing_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-21: run 0x42::Test::test_shadowing diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/simple.exp index fc3cb918aa6..a2202bdc5a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/simple.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0x42::Test {] +task 1 lines 13-13: run 0x42::Test::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules.exp index a47d6d614dc..b77764cb85f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 21-21: +task 0 lines 1-10: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 12-19: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 21-21: run 0x42::TwoLevelTestMain::test return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_inline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_inline.exp index a5c537ab1b0..07a8b919f65 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_inline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_inline.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 25-25: +task 0 lines 1-10: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 12-23: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 25-25: run 0x42::TwoLevelTestMain::main return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_noinline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_noinline.exp index a5c537ab1b0..07a8b919f65 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_noinline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_noinline.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 25-25: +task 0 lines 1-10: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 12-23: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 25-25: run 0x42::TwoLevelTestMain::main return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubinline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubinline.exp index a5c537ab1b0..07a8b919f65 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubinline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubinline.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 25-25: +task 0 lines 1-10: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 12-23: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 25-25: run 0x42::TwoLevelTestMain::main return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubnoinline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubnoinline.exp index a5c537ab1b0..07a8b919f65 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubnoinline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/inlining/two_level_modules_pubnoinline.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 25-25: +task 0 lines 1-10: publish [module 0x42::TwoLevelTestModule {] +task 1 lines 12-23: publish [module 0x42::TwoLevelTestMain {] +task 2 lines 25-25: run 0x42::TwoLevelTestMain::main return values: 18 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/acquires.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/acquires.exp index 6cd67db3f64..819e0011c8f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/acquires.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/acquires.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-18: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/approx_the_same.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/approx_the_same.exp index 5d92c423f3f..04f9352b861 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/approx_the_same.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/approx_the_same.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-24: publish [module 0x42::m {] +task 1 lines 26-26: run 0x42::m::exec diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_optimize_test01.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_optimize_test01.exp index 364eb984fc9..b0959c38fef 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_optimize_test01.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_optimize_test01.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 31-31: +task 0 lines 1-29: publish [module 0xc0ffee::m {] +task 1 lines 31-31: run 0xc0ffee::m::foo1 --args 10 20 true return values: 100 - -task 2 'run'. lines 33-33: +task 2 lines 33-33: run 0xc0ffee::m::foo1 --args 10 20 false return values: 50 - -task 3 'run'. lines 35-35: +task 3 lines 35-35: run 0xc0ffee::m::foo2 --args 10 20 true return values: 100 - -task 4 'run'. lines 37-37: +task 4 lines 37-37: run 0xc0ffee::m::foo2 --args 10 20 false return values: 50 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_unpack_references.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_unpack_references.exp index fc5a4436b29..42109e5ad1b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_unpack_references.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/assign_unpack_references.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-25: publish [module 0x42::m {] +task 1 lines 27-27: run 0x42::m::t1 +task 2 lines 29-29: run 0x42::m::t2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bitwise_features.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bitwise_features.exp index 5d92c423f3f..0f58bb8c99c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bitwise_features.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bitwise_features.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-56: publish [module 0x42::TestFeatures {] +task 1 lines 58-58: run 0x42::TestFeatures::test --signers 0xbeef diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/borrowed_from_one_path.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/borrowed_from_one_path.exp index 6cd67db3f64..6850bdcd19a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/borrowed_from_one_path.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/borrowed_from_one_path.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-29: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_12394_missing_freeze.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_12394_missing_freeze.exp index 3dc4647983c..302f1d62c23 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_12394_missing_freeze.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_12394_missing_freeze.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_13687_repeated_args.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_13687_repeated_args.exp index 5797351f96b..c6286c994e6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_13687_repeated_args.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_13687_repeated_args.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 24-24: +task 0 lines 1-22: publish [module 0xCAFE::Module1 {] +task 1 lines 24-24: run 0xCAFE::Module1::function6 return values: { 21859, 1399722001, 154, 1399722001, 1399722001 } diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.baseline.exp index 75b2f416361..fff205fcad8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.baseline.exp @@ -1,30 +1,29 @@ processed 1 task +task 0 lines 2-14: print-bytecode --input=module [module 0xc0ffee::m {] +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret -task 0 'print-bytecode'. lines 2-14: -// Move bytecode v8 -module c0ffee.m { +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + pop + move_loc l1 + read_ref + // @10 + pop + ret -id_mut(Arg0: &mut Ty0): &mut Ty0 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: &mut Ty0) - 1: Ret -} -t0() /* def_idx: 1 */ { -L0: loc0: u64 -L1: loc1: &mut u64 -B0: - 0: LdU64(0) - 1: StLoc[0](loc0: u64) - 2: MutBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &mut u64) - 4: CopyLoc[1](loc1: &mut u64) - 5: Call id_mut(&mut u64): &mut u64 - 6: ReadRef - 7: Pop - 8: MoveLoc[1](loc1: &mut u64) - 9: ReadRef - 10: Pop - 11: Ret -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.no-optimize.exp index 77b098fd3b0..7abef40b6d0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.no-optimize.exp @@ -1,30 +1,29 @@ processed 1 task +task 0 lines 2-14: print-bytecode --input=module [module 0xc0ffee::m {] +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret -task 0 'print-bytecode'. lines 2-14: -// Move bytecode v8 -module c0ffee.m { +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + move_loc l1 + read_ref + pop + // @10 + pop + ret -id_mut(Arg0: &mut Ty0): &mut Ty0 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: &mut Ty0) - 1: Ret -} -t0() /* def_idx: 1 */ { -L0: loc0: u64 -L1: loc1: &mut u64 -B0: - 0: LdU64(0) - 1: StLoc[0](loc0: u64) - 2: MutBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &mut u64) - 4: CopyLoc[1](loc1: &mut u64) - 5: Call id_mut(&mut u64): &mut u64 - 6: ReadRef - 7: MoveLoc[1](loc1: &mut u64) - 8: ReadRef - 9: Pop - 10: Pop - 11: Ret -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.opt-extra.exp new file mode 100644 index 00000000000..b5099a65286 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.opt-extra.exp @@ -0,0 +1,28 @@ +processed 1 task +task 0 lines 2-14: print-bytecode --input=module [module 0xc0ffee::m {] +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret + +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + read_ref + pop + move_loc l1 + read_ref + pop + // @10 + ret + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.optimize.exp index 75b2f416361..fff205fcad8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14243_stack_size.optimize.exp @@ -1,30 +1,29 @@ processed 1 task +task 0 lines 2-14: print-bytecode --input=module [module 0xc0ffee::m {] +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret -task 0 'print-bytecode'. lines 2-14: -// Move bytecode v8 -module c0ffee.m { +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + pop + move_loc l1 + read_ref + // @10 + pop + ret -id_mut(Arg0: &mut Ty0): &mut Ty0 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: &mut Ty0) - 1: Ret -} -t0() /* def_idx: 1 */ { -L0: loc0: u64 -L1: loc1: &mut u64 -B0: - 0: LdU64(0) - 1: StLoc[0](loc0: u64) - 2: MutBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &mut u64) - 4: CopyLoc[1](loc1: &mut u64) - 5: Call id_mut(&mut u64): &mut u64 - 6: ReadRef - 7: Pop - 8: MoveLoc[1](loc1: &mut u64) - 9: ReadRef - 10: Pop - 11: Ret -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.baseline.exp new file mode 100644 index 00000000000..b15bcb23a81 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.baseline.exp @@ -0,0 +1,9 @@ +processed 8 tasks +task 0 lines 1-144: publish [module 0xc0ffee::m {] +task 1 lines 146-146: run 0xc0ffee::m::main +task 2 lines 148-162: publish [module 0xCAFE::m1 {] +task 3 lines 164-164: run 0xCAFE::m1::main +task 4 lines 166-183: publish [module 0xCAFE::m2 {] +task 5 lines 185-185: run 0xCAFE::m2::main +task 6 lines 187-201: publish [module 0xc0ffee::m3 {] +task 7 lines 203-203: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.exp index f33e2b18fc0..b15bcb23a81 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.exp @@ -1 +1,9 @@ processed 8 tasks +task 0 lines 1-144: publish [module 0xc0ffee::m {] +task 1 lines 146-146: run 0xc0ffee::m::main +task 2 lines 148-162: publish [module 0xCAFE::m1 {] +task 3 lines 164-164: run 0xCAFE::m1::main +task 4 lines 166-183: publish [module 0xCAFE::m2 {] +task 5 lines 185-185: run 0xCAFE::m2::main +task 6 lines 187-201: publish [module 0xc0ffee::m3 {] +task 7 lines 203-203: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.no-optimize.exp new file mode 100644 index 00000000000..b15bcb23a81 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.no-optimize.exp @@ -0,0 +1,9 @@ +processed 8 tasks +task 0 lines 1-144: publish [module 0xc0ffee::m {] +task 1 lines 146-146: run 0xc0ffee::m::main +task 2 lines 148-162: publish [module 0xCAFE::m1 {] +task 3 lines 164-164: run 0xCAFE::m1::main +task 4 lines 166-183: publish [module 0xCAFE::m2 {] +task 5 lines 185-185: run 0xCAFE::m2::main +task 6 lines 187-201: publish [module 0xc0ffee::m3 {] +task 7 lines 203-203: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.opt-extra.exp new file mode 100644 index 00000000000..6f16612233d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.opt-extra.exp @@ -0,0 +1,27 @@ +processed 8 tasks +task 0 lines 1-144: publish [module 0xc0ffee::m {] +Error: compilation errors: + bug: bytecode verification failed with unexpected status code `BORROWFIELD_TYPE_MISMATCH_ERROR`: +Error message: none + ┌─ TEMPFILE:48:9 + │ +48 │ &mut p.q.r + │ ^^^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + + +task 1 lines 146-146: run 0xc0ffee::m::main +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 148-162: publish [module 0xCAFE::m1 {] +task 3 lines 164-164: run 0xCAFE::m1::main +task 4 lines 166-183: publish [module 0xCAFE::m2 {] +task 5 lines 185-185: run 0xCAFE::m2::main +task 6 lines 187-201: publish [module 0xc0ffee::m3 {] +task 7 lines 203-203: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.optimize.exp new file mode 100644 index 00000000000..b15bcb23a81 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_14817_extended.optimize.exp @@ -0,0 +1,9 @@ +processed 8 tasks +task 0 lines 1-144: publish [module 0xc0ffee::m {] +task 1 lines 146-146: run 0xc0ffee::m::main +task 2 lines 148-162: publish [module 0xCAFE::m1 {] +task 3 lines 164-164: run 0xCAFE::m1::main +task 4 lines 166-183: publish [module 0xCAFE::m2 {] +task 5 lines 185-185: run 0xCAFE::m2::main +task 6 lines 187-201: publish [module 0xc0ffee::m3 {] +task 7 lines 203-203: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16599.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16599.exp index 457ace9c4ac..caaadd65063 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16599.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16599.exp @@ -1 +1,5 @@ processed 4 tasks +task 0 lines 1-24: publish [module 0xCAFE::m0 {] +task 1 lines 26-26: run 0xCAFE::m0::test +task 2 lines 28-53: publish [module 0xCAFE::m1 {] +task 3 lines 55-55: run 0xCAFE::m1::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16607.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16607.exp index 6cd67db3f64..3c6681fa0fe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16607.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16607.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: publish [module 0xCAFE::Module0 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16622.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16622.exp index 8c37110a41a..591469434a3 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16622.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16622.exp @@ -1 +1,10 @@ processed 9 tasks +task 0 lines 1-25: publish [module 0xCAFE::m0 {] +task 1 lines 27-27: run 0xCAFE::m0::f0 +task 2 lines 29-67: publish [module 0xCAFE::m1 {] +task 3 lines 69-69: run 0xCAFE::m1::f0 +task 4 lines 71-71: run 0xCAFE::m1::f1 +task 5 lines 73-109: publish [module 0xCAFE::m2 {] +task 6 lines 111-111: run 0xCAFE::m2::f0 +task 7 lines 113-140: publish [module 0xCAFE::m3 {] +task 8 lines 142-142: run 0xCAFE::m3::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16625.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16625.exp index 5d92c423f3f..4fa6f1a9404 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16625.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_16625.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-17: publish [module 0xCAFE::m {] +task 1 lines 19-19: run 0xCAFE::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.exp new file mode 100644 index 00000000000..e183ec9cfb4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 1-32: publish [module 0xc0ffee::m {] +task 1 lines 34-34: run 0xc0ffee::m::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.move new file mode 100644 index 00000000000..f781c179a8f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_a.move @@ -0,0 +1,34 @@ +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + x: u64 + } + + public fun test(): u64 { + let s = make(); + s.foo() + } + + fun foo(self: &mut S): u64 { + make().bar(|| { + // inline function captures param + mod(&mut self.x); + }); + self.x + } + + fun mod(x: &mut u64) { + *x = 42; + } + + inline fun make(): S { + S { x: 0 } + } + + inline fun bar(self: &mut S, f: ||) { + self.x = 12; + f() + } +} + +//# run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.exp new file mode 100644 index 00000000000..7ce2d17cc94 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 1-33: publish [module 0xc0ffee::m {] +task 1 lines 35-35: run 0xc0ffee::m::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.move new file mode 100644 index 00000000000..23e732d868b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/bug_17283_b.move @@ -0,0 +1,35 @@ +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + x: u64 + } + + public fun test(): u64 { + let s = make(); + foo(&mut s) + } + + fun foo(s: &mut S): u64 { + bar(make(), || { + // inline function captures param + s.x = 43; + mod(&mut s.x); + }); + s.x + } + + fun mod(x: &mut u64) { + *x = 42; + } + + inline fun make(): S { + S { x: 0 } + } + + inline fun bar(s: S, f: ||) { + s.x = 12; + f() + } +} + +//# run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.baseline.exp index 0cbb8d75b5f..469da0bb6bc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.baseline.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish --print-bytecode [module 0x42::m {] warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` ┌─ TEMPFILE:3:20 │ @@ -9,27 +8,25 @@ warning: Unused value of parameter `x`. Consider removing the parameter, or pref == BEGIN Bytecode == -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +#[persistent] public fun bar() + ld_u64 3 + call foo + ld_u64 2 + eq + br_false l0 + // @5 + ret +l0: ld_u64 1 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: u64): u64 + ld_u64 2 + ret -public bar() /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Call foo(u64): u64 - 2: LdU64(2) - 3: Eq - 4: BrFalse(6) -B1: - 5: Ret -B2: - 6: LdU64(1) - 7: Abort -} -public foo(Arg0: u64): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(2) - 1: Ret -} -} == END Bytecode == +task 1 lines 12-12: run 0x42::m::bar diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.no-optimize.exp index 588c2be49ce..9b8fda032cc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.no-optimize.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish --print-bytecode [module 0x42::m {] warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` ┌─ TEMPFILE:3:20 │ @@ -9,31 +8,28 @@ warning: Unused value of parameter `x`. Consider removing the parameter, or pref == BEGIN Bytecode == -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +#[persistent] public fun bar() + ld_u64 3 + call foo + ld_u64 2 + eq + br_false l0 + // @5 + branch l1 +l0: ld_u64 1 + abort +l1: ret + +// Function definition at index 1 +#[persistent] public fun foo(l0: u64): u64 + ld_u64 1 + ld_u64 1 + add + ret -public bar() /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Call foo(u64): u64 - 2: LdU64(2) - 3: Eq - 4: BrFalse(6) -B1: - 5: Branch(8) -B2: - 6: LdU64(1) - 7: Abort -B3: - 8: Ret -} -public foo(Arg0: u64): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: LdU64(1) - 2: Add - 3: Ret -} -} == END Bytecode == +task 1 lines 12-12: run 0x42::m::bar diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.opt-extra.exp new file mode 100644 index 00000000000..056ceed9f40 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.opt-extra.exp @@ -0,0 +1,26 @@ +processed 2 tasks +task 0 lines 1-10: publish --print-bytecode [module 0x42::m {] +warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` + ┌─ TEMPFILE:3:20 + │ +3 │ public fun foo(x: u64): u64 { + │ ^ + + +== BEGIN Bytecode == +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +#[persistent] public fun bar() + ret + ld_u64 1 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: u64): u64 + ld_u64 2 + ret + + +== END Bytecode == +task 1 lines 12-12: run 0x42::m::bar diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.optimize.exp index 0cbb8d75b5f..469da0bb6bc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/build_with_warnings.optimize.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish --print-bytecode [module 0x42::m {] warning: Unused value of parameter `x`. Consider removing the parameter, or prefixing with an underscore (e.g., `_x`), or binding to `_` ┌─ TEMPFILE:3:20 │ @@ -9,27 +8,25 @@ warning: Unused value of parameter `x`. Consider removing the parameter, or pref == BEGIN Bytecode == -// Move bytecode v8 -module 42.m { +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +#[persistent] public fun bar() + ld_u64 3 + call foo + ld_u64 2 + eq + br_false l0 + // @5 + ret +l0: ld_u64 1 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: u64): u64 + ld_u64 2 + ret -public bar() /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: Call foo(u64): u64 - 2: LdU64(2) - 3: Eq - 4: BrFalse(6) -B1: - 5: Ret -B2: - 6: LdU64(1) - 7: Abort -} -public foo(Arg0: u64): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(2) - 1: Ret -} -} == END Bytecode == +task 1 lines 12-12: run 0x42::m::bar diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_1.exp index 5d92c423f3f..8ef6ea8fc69 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_2.exp index 5d92c423f3f..fa6451b2953 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_3.exp index 5d92c423f3f..3298e9d7621 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/dead_assignment_3.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-19: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/destroy_after_call.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/destroy_after_call.exp index 6cd67db3f64..2bd2d1b1327 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/destroy_after_call.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/destroy_after_call.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_after_loop.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_after_loop.exp index 5d92c423f3f..41958721575 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_after_loop.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_after_loop.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0x42::m {] +task 1 lines 15-15: run 0x42::m::drop_required diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_ref_in_branch.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_ref_in_branch.exp index 6cd67db3f64..e9d12c4eca4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_ref_in_branch.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/drop_ref_in_branch.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/fibonacci.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/fibonacci.exp index 5d92c423f3f..c466604d621 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/fibonacci.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/fibonacci.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-26: publish [module 0x42::fibonacci {] +task 1 lines 28-28: run 0x42::fibonacci::test_fib diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/flush_if_alive.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/flush_if_alive.exp index 6cd67db3f64..a2896473e2b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/flush_if_alive.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/flush_if_alive.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-36: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/foreach_mut_expanded.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/foreach_mut_expanded.exp index 5d92c423f3f..744e683d65f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/foreach_mut_expanded.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/foreach_mut_expanded.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-18: publish [module 0x42::m {] +task 1 lines 20-20: run 0x42::m::test_for_each_mut diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/freeze_mut_ref.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/freeze_mut_ref.exp index 5027f10bfe9..dc42c11539d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/freeze_mut_ref.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/freeze_mut_ref.exp @@ -1 +1,8 @@ processed 7 tasks +task 0 lines 1-94: publish [module 0x42::freeze_mut_ref {] +task 1 lines 96-96: run 0x42::freeze_mut_ref::test_1 +task 2 lines 98-98: run 0x42::freeze_mut_ref::test_2 +task 3 lines 100-100: run 0x42::freeze_mut_ref::test_3 +task 4 lines 102-102: run 0x42::freeze_mut_ref::test_5 +task 5 lines 104-104: run 0x42::freeze_mut_ref::test_6 +task 6 lines 106-106: run 0x42::freeze_mut_ref::test_7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/greatest_product.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/greatest_product.exp index 5d92c423f3f..44e3831f92b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/greatest_product.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/greatest_product.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-41: publish [module 0xc0ffee::greatest_product {] +task 1 lines 43-43: run 0xc0ffee::greatest_product::test_find_greatest_product diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/invalid_shift_in_consts.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/invalid_shift_in_consts.exp index 83596cde1fc..0d571829d34 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/invalid_shift_in_consts.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/invalid_shift_in_consts.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0xc0ffee::m {] Error: compilation errors: error: Invalid expression in `const`. Operand on the right is too large for `<<`, should be less than `8` ┌─ TEMPFILE:3:20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_11022.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_11022.exp index 5d92c423f3f..10735fcacf9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_11022.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_11022.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 2-9: publish [module 0xc0ffee::dummy1 {] +task 1 lines 11-16: publish [module 0xc0ffee::dummy2 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.exp new file mode 100644 index 00000000000..38a08f543c0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 1-25: publish [module 0xCAFE::Module0 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.move new file mode 100644 index 00000000000..41f0113ea8d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/issue_17412.move @@ -0,0 +1,25 @@ +//# publish +module 0xCAFE::Module0 { + enum Enum0 has copy, drop { + Variant0, + Variant1 { + field: bool, + }, + Variant2, + } + public fun function3( var0: bool, var1: bool) { + match (Enum0::Variant0) { + Enum0::Variant2 => { + 1 + }, + Enum0::Variant1 {..} => { + let var28 = 1; + (!var1) && var0; + var28 + }, + Enum0::Variant0 => { + 1 + } + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/largest_prime_factor.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/largest_prime_factor.exp index 5d92c423f3f..195ecc1043b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/largest_prime_factor.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/largest_prime_factor.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-39: publish [module 0xc0ffee::largest_prime_factor {] +task 1 lines 41-41: run 0xc0ffee::largest_prime_factor::test_largest_prime_factor diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/loop_invariant_code_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/loop_invariant_code_1.exp index e8649aa71c4..0567a22086d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/loop_invariant_code_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/loop_invariant_code_1.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 15-15: +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test --args 44 return values: 44 - -task 2 'run'. lines 17-17: +task 2 lines 17-17: run 0xc0ffee::m::test --args 6 return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mut_ref_compare.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mut_ref_compare.exp index e103a2d2be9..9230a10fda7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mut_ref_compare.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mut_ref_compare.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0x42::m {] +task 1 lines 12-12: run 0x42::m::test return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_if.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_if.exp index 5d92c423f3f..bdf1c9df991 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_if.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_if.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-29: publish [module 0xc0ffee::m {] +task 1 lines 31-31: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_vector.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_vector.exp index 6cd67db3f64..df534f46732 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_vector.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/mutate_vector.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-24: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/nested_mutate.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/nested_mutate.exp index 5d92c423f3f..1b1cd134ea1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/nested_mutate.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/nested_mutate.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-22: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/pack_unpack_ref.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/pack_unpack_ref.exp index 5d92c423f3f..e383b8dc031 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/pack_unpack_ref.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/pack_unpack_ref.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-32: publish [module 0x42::pack_unpack_ref {] +task 1 lines 34-34: run 0x42::pack_unpack_ref::unpack_ref_G diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/power_function.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/power_function.exp index 5d92c423f3f..6f5bdba384f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/power_function.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/power_function.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-25: publish [module 0x42::power_function {] +task 1 lines 27-27: run 0x42::power_function::test_pow diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/prime_check.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/prime_check.exp index 5d92c423f3f..e2fc61020ee 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/prime_check.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/prime_check.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-35: publish [module 0xc0ffee::prime {] +task 1 lines 37-37: run 0xc0ffee::prime::test_is_prime diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/queue.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/queue.exp index 5d92c423f3f..1d0426025fa 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/queue.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/queue.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-31: publish [module 0x42::queue {] +task 1 lines 33-33: run 0x42::queue::test_queue_operations diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled new file mode 100644 index 00000000000..26cd21776a0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/acquires.move` + +//# publish +module 0x42::m { + struct R has key { + v: u64, + } + fun read(): u64 + acquires R + { + *&borrow_global(@0x42).v + } + public fun test(): u64 + acquires R + { + read() + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled.baseline.exp new file mode 100644 index 00000000000..964dbd4e258 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/acquires.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-18: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled new file mode 100644 index 00000000000..1df9854a517 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/approx_the_same.move` + +//# publish +module 0x42::m { + fun assert_approx_the_same(p0: u256, p1: u256, p2: u128) { + if (p0 < p1) { + let _v0 = p0; + p0 = p1; + p1 = _v0 + }; + let _v1 = 1u256; + let _v2 = 10u256; + while (p2 > 0u128) { + if (p2 % 2u128 == 1u128) _v1 = _v1 * _v2; + p2 = p2 / 2u128; + _v2 = _v2 * _v2 + }; + assert!((p0 - p1) * _v1 < p0, 0); + } + fun exec() { + assert_approx_the_same(5672u256, 5672u256, 0u128); + } +} + + +//# run 0x42::m::exec \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled.baseline.exp new file mode 100644 index 00000000000..d7445b28551 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/approx_the_same.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-23: publish [module 0x42::m {] +task 1 lines 26-26: run 0x42::m::exec diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled new file mode 100644 index 00000000000..e1075c6d5a5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled @@ -0,0 +1,32 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/assign_optimize_test01.move` + +//# publish +module 0xc0ffee::m { + fun bar() { + () + } + fun foo1(p0: u64, p1: u64, p2: bool): u64 { + if (p2) p0 = p1; + let _v0 = p0 * 2; + bar(); + let _v1 = p0 * 3; + _v0 + _v1 + } + fun foo2(p0: u64, p1: u64, p2: bool): u64 { + if (p2) p0 = p1; + p1 = p0 * 2; + if (p2) bar(); + bar(); + p0 = p0 * 3; + p1 + p0 + } +} + + +//# run 0xc0ffee::m::foo1 --args 10 20 true + +//# run 0xc0ffee::m::foo1 --args 10 20 false + +//# run 0xc0ffee::m::foo2 --args 10 20 true + +//# run 0xc0ffee::m::foo2 --args 10 20 false \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled.baseline.exp new file mode 100644 index 00000000000..9e5a7f9bce8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_optimize_test01.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-23: publish [module 0xc0ffee::m {] +task 1 lines 26-26: run 0xc0ffee::m::foo1 --args 10 20 true +return values: 100 +task 2 lines 28-28: run 0xc0ffee::m::foo1 --args 10 20 false +return values: 50 +task 3 lines 30-30: run 0xc0ffee::m::foo2 --args 10 20 true +return values: 100 +task 4 lines 32-32: run 0xc0ffee::m::foo2 --args 10 20 false +return values: 50 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled new file mode 100644 index 00000000000..c8c94a53cb8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled @@ -0,0 +1,43 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/assign_unpack_references.move` + +//# publish +module 0x42::m { + struct R has drop { + s1: S, + s2: S, + } + struct S has drop { + f: u64, + } + fun t1() { + let _v0 = S{f: 0}; + let _v1 = S{f: 1}; + let _v2 = R{s1: _v0, s2: _v1}; + let _v3 = &_v2; + let _v4 = &_v3.s1; + let _v5 = &_v3.s2; + assert!(*&_v4.f == 0, 0); + assert!(*&_v5.f == 1, 1); + } + fun t2() { + let _v0 = S{f: 0}; + let _v1 = S{f: 1}; + let _v2 = R{s1: _v0, s2: _v1}; + let _v3 = &mut _v2; + let _v4 = &mut _v3.s1; + let _v5 = &mut _v3.s2; + assert!(*&mut _v4.f == 0, 0); + assert!(*&_v5.f == 1, 1); + let _v6 = 5; + let _v7 = &mut _v6; + let _v8 = S{f: 0}; + _v5 = &mut _v8; + assert!(*_v7 == 5, 0); + assert!(*&_v5.f == 0, 1); + } +} + + +//# run 0x42::m::t1 + +//# run 0x42::m::t2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled.baseline.exp new file mode 100644 index 00000000000..4bd9c796a54 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/assign_unpack_references.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-38: publish [module 0x42::m {] +task 1 lines 41-41: run 0x42::m::t1 +task 2 lines 43-43: run 0x42::m::t2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled new file mode 100644 index 00000000000..5f5d2925aa0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled @@ -0,0 +1,60 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bitwise_features.move` + +//# publish +module 0x42::TestFeatures { + struct Features has key { + features: vector, + } + fun contains(p0: &vector, p1: u64): bool { + let _v0 = p1 / 8; + let _v1 = (p1 % 8) as u8; + let _v2 = 1u8 << _v1; + let _v3 = 0x1::vector::length(p0); + if (_v0 < _v3) return *0x1::vector::borrow(p0, _v0) & _v2 != 0u8; + false + } + public fun enable_feature_flags(p0: vector) + acquires Features + { + let _v0 = &mut borrow_global_mut(@0xbeef).features; + let _v1 = 0; + let _v2 = 0x1::vector::length(&p0); + while (_v1 < _v2) { + let _v3 = *0x1::vector::borrow(&p0, _v1); + set(_v0, _v3, true); + _v1 = _v1 + 1; + continue + }; + } + fun set(p0: &mut vector, p1: u64, p2: bool) { + let _v0 = 0x1::vector::length(freeze(p0)); + let _v1 = *p0; + let _v2 = p1 / 8; + let _v3 = (p1 % 8) as u8; + let _v4 = 1u8 << _v3; + while (0x1::vector::length(freeze(p0)) <= _v2) { + 0x1::vector::push_back(p0, 0u8); + _v0 = _v0 + 1 + }; + let _v5 = 0x1::vector::borrow_mut(p0, _v2); + if (p2) { + *_v5 = *_v5 | _v4; + return () + }; + *_v5 = *_v5 & (255u8 ^ _v4); + } + public fun test(p0: signer) + acquires Features + { + let _v0 = &p0; + let _v1 = Features{features: vector[1u8, 2u8, 3u8]}; + move_to(_v0, _v1); + enable_feature_flags(vector[2]); + assert!(contains(&borrow_global(@0xbeef).features, 2), 0); + if (contains(&borrow_global(@0xbeef).features, 1)) abort 1; + if (contains(&borrow_global(@0xbeef).features, 3)) abort 2; + } +} + + +//# run 0x42::TestFeatures::test --signers 0xbeef \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled.baseline.exp new file mode 100644 index 00000000000..32a1a774370 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bitwise_features.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-57: publish [module 0x42::TestFeatures {] +task 1 lines 60-60: run 0x42::TestFeatures::test --signers 0xbeef diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled new file mode 100644 index 00000000000..965e5e150b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/borrowed_from_one_path.move` + +//# publish +module 0x42::m { + struct R has key { + data: vector, + } + fun f(p0: u8, p1: &vector): u64 + acquires R + { + let _v0; + if (p0 == 0u8) _v0 = &borrow_global(@0x1).data else _v0 = p1; + *0x1::vector::borrow(_v0, 0) + } + fun g(p0: u8, p1: &mut vector) + acquires R + { + let _v0; + if (p0 == 0u8) _v0 = &mut borrow_global_mut(@0x1).data else _v0 = p1; + let _v1 = 0x1::vector::borrow_mut(_v0, 0); + *_v1 = 1; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled.baseline.exp new file mode 100644 index 00000000000..feecab50c72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/borrowed_from_one_path.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-23: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled new file mode 100644 index 00000000000..27c1ad8127e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_12394_missing_freeze.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = freeze(&mut _v0); + let _v2 = freeze(&mut _v0); + let _v3 = *_v1; + let _v4 = *_v2; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled.baseline.exp new file mode 100644 index 00000000000..75295a9c0a8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_12394_missing_freeze.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled new file mode 100644 index 00000000000..8969c13b0ec --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_13687_repeated_args.move` + +//# publish +module 0xcafe::Module1 { + struct Struct3 has copy, drop { + var32: u16, + var33: u32, + var34: u8, + var35: u32, + var36: u32, + } + public fun function6(): Struct3 { + Struct3{var32: 21859u16, var33: 1399722001u32, var34: 154u8, var35: 1399722001u32, var36: 1399722001u32} + } +} + + +//# run 0xCAFE::Module1::function6 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled.baseline.exp new file mode 100644 index 00000000000..900b64c149c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_13687_repeated_args.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xcafe::Module1 {] +task 1 lines 18-18: run 0xCAFE::Module1::function6 +return values: { 21859, 1399722001, 154, 1399722001, 1399722001 } diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled new file mode 100644 index 00000000000..6f97a0d36a2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_14243_stack_size.move` + +//# print-bytecode --input=module +module 0xc0ffee::m { + fun id_mut(p0: &mut T0): &mut T0 { + p0 + } + fun t0() { + let _v0 = 0; + let _v1 = &mut _v0; + let _v2 = *id_mut(_v1); + let _v3 = *_v1; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled.baseline.exp new file mode 100644 index 00000000000..9d568a6c55b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14243_stack_size.decompiled.baseline.exp @@ -0,0 +1,29 @@ +processed 1 task +task 0 lines 3-14: print-bytecode --input=module [module 0xc0ffee::m {] +// Bytecode version v9 +module 0xc0ffee::m +// Function definition at index 0 +fun id_mut(l0: &mut T0): &mut T0 + move_loc l0 + ret + +// Function definition at index 1 +fun t0() + local l0: u64 + local l1: &mut u64 + ld_u64 0 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + call id_mut + read_ref + pop + move_loc l1 + read_ref + // @10 + pop + ret + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled new file mode 100644 index 00000000000..e81ad8d8cbd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled @@ -0,0 +1,186 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_14817_extended.move` + +//# publish +module 0xc0ffee::m { + struct P has copy, drop { + q: Q, + } + struct Q has copy, drop { + r: u64, + } + public fun main() { + let _v0 = test_01(new_p()); + assert!(*&(&(&_v0).q).r == 1, 0); + assert!(test_02(new_p()) == 10, 0); + let _v1 = new_p(); + test_03(&mut _v1); + assert!(*&(&(&_v1).q).r == 12, 0); + let _v2 = test_04(new_p()); + assert!(*&(&(&_v2).q).r == 14, 0); + let _v3 = test_05(new_p()); + assert!(*&(&(&_v3).q).r == 15, 0); + let _v4 = test_06(new_p()); + assert!(*&(&(&_v4).q).r == 16, 0); + let _v5 = test_07(new_p()); + assert!(*&(&(&_v5).q).r == 0, 0); + assert!(test_08(1) == 1, 0); + assert!(test_09(3), 0); + let _v6 = test_10(new_p()); + assert!(*&(&(&_v6).q).r == 20, 0); + let _v7 = test_11(new_p()); + assert!(*&(&(&_v7).q).r == 0, 0); + let _v8 = test_12(new_p()); + assert!(*&(&(&_v8).q).r == 5, 0); + let _v9 = test_13(new_p()); + assert!(*&(&(&_v9).q).r == 0, 0); + let _v10 = test_14(new_p()); + assert!(*&(&(&_v10).q).r == 24, 0); + } + fun new_p(): P { + P{q: Q{r: 0}} + } + fun test_01(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 1; + p0 + } + fun test_02(p0: P): u64 { + *&(&(&p0).q).r + 10 + } + fun test_03(p0: &mut P) { + let _v0 = &mut (&mut p0.q).r; + *_v0 = 12; + } + fun test_04(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 14; + p0 + } + fun test_05(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 15; + p0 + } + fun test_06(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 16; + p0 + } + fun test_07(p0: P): P { + let _v0 = *&(&(&p0).q).r; + let _v1 = &mut _v0; + *_v1 = 17; + p0 + } + fun test_08(p0: u64): u64 { + let _v0 = p0; + let _v1 = &mut _v0; + *_v1 = 18; + p0 + } + fun test_09(p0: u64): bool { + let _v0 = freeze(&mut p0); + let _v1 = 3; + let _v2 = freeze(&mut _v1); + _v0 == _v2 + } + fun test_10(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 20; + p0 + } + fun test_11(p0: P): P { + let _v0 = p0; + let _v1 = &mut (&mut (&mut _v0).q).r; + *_v1 = 21; + p0 + } + fun test_12(p0: P): P { + let _v0 = &mut (&mut (&mut p0).q).r; + *_v0 = 5; + let _v1 = *&(&(&p0).q).r; + let _v2 = &mut _v1; + *_v2 = 22; + p0 + } + fun test_13(p0: P): P { + let _v0 = *&(&(&p0).q).r; + let _v1 = &mut _v0; + *_v1 = 23; + p0 + } + fun test_14(p0: P): P { + let _v0 = Q{r: 24}; + let _v1 = &mut (&mut p0).q; + *_v1 = _v0; + let _v2 = *&(&(&p0).q).r; + let _v3 = &mut _v2; + *_v3 = 12; + p0 + } +} + + +//# run 0xc0ffee::m::main + +//# publish +module 0xcafe::m1 { + struct Struct0 has copy, drop { + x: bool, + } + fun f(p0: Struct0) { + let _v0 = *&(&p0).x; + let _v1 = &mut _v0; + *_v1 = true; + } + public fun main() { + f(Struct0{x: true}); + } +} + + +//# run 0xCAFE::m1::main + +//# publish +module 0xcafe::m2 { + struct S has copy, drop { + x: bool, + } + fun f(p0: S) { + let _v0 = *&(&p0).x; + let _v1 = true; + let _v2 = &mut _v1; + *_v2 = _v0; + let _v3 = 0u8; + let _v4 = &mut _v3; + *_v4 = 123u8; + } + public fun main() { + f(S{x: true}); + } +} + + +//# run 0xCAFE::m2::main + +//# publish +module 0xc0ffee::m3 { + struct S has copy, drop { + f: ||(u8) has copy + drop, + } + public fun main() { + test(S{f: || lambda__1__main()}); + } + fun lambda__1__main(): u8 { + 42u8 + } + fun test(p0: S) { + let _v0 = *&(&p0).f; + let _v1 = _v0(); + let _v2 = &mut _v1; + *_v2 = 1u8; + } +} + + +//# run 0xc0ffee::m3::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled.baseline.exp new file mode 100644 index 00000000000..6ffc7daa056 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_14817_extended.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 8 tasks +task 0 lines 3-121: publish [module 0xc0ffee::m {] +task 1 lines 124-124: run 0xc0ffee::m::main +task 2 lines 126-139: publish [module 0xcafe::m1 {] +task 3 lines 142-142: run 0xCAFE::m1::main +task 4 lines 144-161: publish [module 0xcafe::m2 {] +task 5 lines 164-164: run 0xCAFE::m2::main +task 6 lines 166-183: publish [module 0xc0ffee::m3 {] +task 7 lines 186-186: run 0xc0ffee::m3::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled new file mode 100644 index 00000000000..91a637b7b6d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled @@ -0,0 +1,54 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_16599.move` + +//# publish +module 0xcafe::m0 { + enum E has copy, drop { + E1, + } + struct S has copy, drop { + x: bool, + } + fun f(p0: S) { + let _v0 = E::E1{}; + assert!(&_v0 is E1, 14566554180833181697); + let E::E1{} = _v0; + let _v1 = *&(&p0).x; + let _v2 = true; + let _v3 = &mut _v2; + *_v3 = _v1; + let _v4 = 0u8; + let _v5 = &mut _v4; + *_v5 = 123u8; + } + fun test() { + f(S{x: true}); + } +} + + +//# run 0xCAFE::m0::test + +//# publish +module 0xcafe::m1 { + enum E has copy, drop { + E1, + } + struct S has copy, drop { + x: bool, + } + fun f(p0: S, p1: u64) { + if (p1 == 10) abort 0; + let _v0 = *&(&p0).x; + let _v1 = &mut (&mut p0).x; + *_v1 = _v0; + let _v2 = 3u8; + let _v3 = &mut _v2; + *_v3 = 123u8; + } + fun test() { + f(S{x: true}, 20); + } +} + + +//# run 0xCAFE::m1::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled.baseline.exp new file mode 100644 index 00000000000..22257f19dfd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16599.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 4 tasks +task 0 lines 3-26: publish [module 0xcafe::m0 {] +task 1 lines 29-29: run 0xCAFE::m0::test +task 2 lines 31-51: publish [module 0xcafe::m1 {] +task 3 lines 54-54: run 0xCAFE::m1::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled new file mode 100644 index 00000000000..7119e0866a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled @@ -0,0 +1,28 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_16607.move` + +//# publish +module 0xcafe::Module0 { + enum Enum0 has copy, drop { + E1 { + _0: bool, + } + } + struct S has copy, drop { + x: Enum0, + } + fun f(p0: S) { + let _v0: || has copy + drop = || lambda__1__f(); + let _v1: || has copy + drop = || lambda__2__f(); + let _v2 = *&(&p0).x; + assert!(&_v2 is E1, 14566554180833181697); + let Enum0::E1{_0: _v3} = _v2; + let _v4 = &mut _v0; + *_v4 = _v1; + } + fun lambda__1__f() { + () + } + fun lambda__2__f() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled.baseline.exp new file mode 100644 index 00000000000..6ee099e4f80 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16607.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-28: publish [module 0xcafe::Module0 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled new file mode 100644 index 00000000000..bb43e7c8517 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled @@ -0,0 +1,151 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_16622.move` + +//# publish +module 0xcafe::m0 { + enum Enum0 has copy, drop { + Variant0, + Variant1 { + field1: bool, + } + } + struct S has copy, drop { + field2: Enum0, + } + public fun f0() { + let _v0; + let _v1 = S{field2: Enum0::Variant1{field1: false}}; + let _v2 = *&(&_v1).field2; + if (&_v2 is Variant0) { + let Enum0::Variant0{} = _v2; + let _v3 = true; + _v0 = &mut _v3 + } else _v0 = &mut (&mut (&mut _v1).field2).field1; + *_v0 = true; + } +} + + +//# run 0xCAFE::m0::f0 + +//# publish +module 0xcafe::m1 { + enum Enum0 has copy, drop { + Variant0, + Variant1, + } + struct S has copy, drop { + field: Enum0, + } + public fun f0() { + let _v0; + let _v1 = S{field: Enum0::Variant1{}}; + let _v2 = *&(&_v1).field; + if (&_v2 is Variant1) { + let Enum0::Variant1{} = _v2; + let _v3 = true; + _v0 = &mut _v3 + } else { + let _v4 = _v1; + let _v5 = *&(&_v4).field; + let _v6 = true; + _v0 = &mut _v6 + }; + *_v0 = true; + } + public fun f1() { + let _v0; + let _v1 = S{field: Enum0::Variant1{}}; + let _v2 = *&(&_v1).field; + let _v3 = *&(&_v1).field; + let _v4 = &_v2; + let _v5 = &_v3; + if ((_v4 is Variant1) && (_v5 is Variant1)) { + let Enum0::Variant1{} = _v2; + let Enum0::Variant1{} = _v3; + let _v6 = true; + _v0 = &mut _v6 + } else { + let _v7 = _v1; + let _v8 = *&(&_v7).field; + let _v9 = true; + _v0 = &mut _v9 + }; + *_v0 = true; + } +} + + +//# run 0xCAFE::m1::f0 + +//# run 0xCAFE::m1::f1 + +//# publish +module 0xcafe::m2 { + enum Enum0 has copy, drop { + Variant0, + Variant1 { + field1: bool, + } + } + enum Enum1 has copy, drop { + Variant2 { + field2: Enum0, + } + } + struct Struct1 has copy, drop { + _0: bool, + } + public fun f0() { + let _v0; + let _v1 = Enum1::Variant2{field2: Enum0::Variant1{field1: false}}; + let _v2 = *&(&_v1).field2; + if (&_v2 is Variant1) { + let Enum0::Variant1{field1: _v3} = _v2; + _v0 = Struct1{_0: true} + } else { + let _v4 = _v1; + let _v5 = *&(&_v4).field2; + _v0 = Struct1{_0: true} + }; + let _v6 = Struct1{_0: *&(&(&_v1).field2).field1}; + let _v7 = &mut _v6; + *_v7 = _v0; + let _v8 = true; + let _v9 = &mut _v8; + *_v9 = true; + } +} + + +//# run 0xCAFE::m2::f0 + +//# publish +module 0xcafe::m3 { + enum Enum0 has copy, drop { + Variant0, + Variant1, + } + struct S has copy, drop { + field: Enum0, + } + fun f0(p0: S) { + let _v0; + let _v1 = *&(&p0).field; + if (&_v1 is Variant0) { + let Enum0::Variant0{} = _v1; + let _v2 = 1u8; + _v0 = &mut _v2 + } else { + let _v3 = *&(&p0).field; + let _v4 = 1u8; + _v0 = &mut _v4 + }; + *_v0 = 1u8; + } + public fun test() { + f0(S{field: Enum0::Variant1{}}); + } +} + + +//# run 0xCAFE::m3::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled.baseline.exp new file mode 100644 index 00000000000..7dd1c2acb6d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16622.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 9 tasks +task 0 lines 3-25: publish [module 0xcafe::m0 {] +task 1 lines 28-28: run 0xCAFE::m0::f0 +task 2 lines 30-75: publish [module 0xcafe::m1 {] +task 3 lines 78-78: run 0xCAFE::m1::f0 +task 4 lines 80-80: run 0xCAFE::m1::f1 +task 5 lines 82-117: publish [module 0xcafe::m2 {] +task 6 lines 120-120: run 0xCAFE::m2::f0 +task 7 lines 122-148: publish [module 0xcafe::m3 {] +task 8 lines 151-151: run 0xCAFE::m3::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled new file mode 100644 index 00000000000..09b02cc9683 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_16625.move` + +//# publish +module 0xcafe::m { + struct S has copy, drop { + f: ||(u8) has copy + drop, + } + fun foo(p0: S) { + let _v0 = *&(&p0).f; + let _v1 = _v0(); + let _v2 = &mut _v1; + *_v2 = 1u8; + } + public fun main() { + foo(S{f: || lambda__1__main()}); + } + fun lambda__1__main(): u8 { + 42u8 + } +} + + +//# run 0xCAFE::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled.baseline.exp new file mode 100644 index 00000000000..3b521ffc93c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_16625.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xcafe::m {] +task 1 lines 23-23: run 0xCAFE::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled new file mode 100644 index 00000000000..2797aeb9f19 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_17283_a.move` + +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + x: u64, + } + fun foo(p0: &mut S): u64 { + let _v0 = S{x: 0}; + let _v1 = &mut (&mut _v0).x; + *_v1 = 12; + mod(&mut p0.x); + *&p0.x + } + fun mod(p0: &mut u64) { + *p0 = 42; + } + public fun test(): u64 { + let _v0 = S{x: 0}; + foo(&mut _v0) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled.baseline.exp new file mode 100644 index 00000000000..6cdd6ed2c63 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_a.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-22: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled new file mode 100644 index 00000000000..83e352c7f42 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled @@ -0,0 +1,27 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/bug_17283_b.move` + +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + x: u64, + } + fun foo(p0: &mut S): u64 { + let _v0 = S{x: 0}; + let _v1 = &mut (&mut _v0).x; + *_v1 = 12; + let _v2 = &mut p0.x; + *_v2 = 43; + mod(&mut p0.x); + *&p0.x + } + fun mod(p0: &mut u64) { + *p0 = 42; + } + public fun test(): u64 { + let _v0 = S{x: 0}; + foo(&mut _v0) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled.baseline.exp new file mode 100644 index 00000000000..c8665663117 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/bug_17283_b.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-24: publish [module 0xc0ffee::m {] +task 1 lines 27-27: run 0xc0ffee::m::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled new file mode 100644 index 00000000000..9dc5b1d8c83 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/build_with_warnings.move` + +//# publish --print-bytecode +module 0x42::m { + public fun bar() { + assert!(foo(3) == 2, 1); + } + public fun foo(p0: u64): u64 { + 2 + } +} + + +//# run 0x42::m::bar \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled.baseline.exp new file mode 100644 index 00000000000..8f3ea3ea6d2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/build_with_warnings.decompiled.baseline.exp @@ -0,0 +1,32 @@ +processed 2 tasks +task 0 lines 3-11: publish --print-bytecode [module 0x42::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:20 + │ +8 │ public fun foo(p0: u64): u64 { + │ ^^ + + +== BEGIN Bytecode == +// Bytecode version v9 +module 0x42::m +// Function definition at index 0 +#[persistent] public fun bar() + ld_u64 3 + call foo + ld_u64 2 + eq + br_false l0 + // @5 + ret +l0: ld_u64 1 + abort + +// Function definition at index 1 +#[persistent] public fun foo(l0: u64): u64 + ld_u64 2 + ret + + +== END Bytecode == +task 1 lines 14-14: run 0x42::m::bar diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled new file mode 100644 index 00000000000..76ff92a32e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/dead_assignment_1.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: u64): u64 { + p0 + } + public fun test() { + assert!(foo(2) == 2, 42); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled.baseline.exp new file mode 100644 index 00000000000..2aaa6aa5ffd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled new file mode 100644 index 00000000000..bedfa20d0f3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/dead_assignment_2.move` + +//# publish +module 0xc0ffee::m { + fun foo(): u64 { + 2 + } + public fun test() { + assert!(foo() == 2, 45); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled.baseline.exp new file mode 100644 index 00000000000..2aaa6aa5ffd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled new file mode 100644 index 00000000000..3682f35c550 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/dead_assignment_3.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: u64): u64 { + let _v0 = 2; + let _v1 = 0; + while (_v1 < p0) { + _v1 = _v1 + 1; + _v0 = 3 + }; + _v0 + } + public fun test() { + assert!(foo(0) == 2, 55); + assert!(foo(1) == 3, 56); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled.baseline.exp new file mode 100644 index 00000000000..962eb854d5e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/dead_assignment_3.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled new file mode 100644 index 00000000000..a7c5252210d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/destroy_after_call.move` + +//# publish +module 0x42::m { + fun f(p0: &mut u64): &mut u64 { + p0 + } + fun g() { + let _v0 = 22; + let _v1 = f(&mut _v0); + let _v2 = &_v0; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled.baseline.exp new file mode 100644 index 00000000000..f97b39757b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/destroy_after_call.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-13: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled new file mode 100644 index 00000000000..00912b496e7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/drop_after_loop.move` + +//# publish +module 0x42::m { + fun drop_required() { + let _v0 = 1; + let _v1 = &mut _v0; + let _v2 = true; + while (_v2) { + *_v1 = 2; + _v2 = false + }; + assert!(_v0 == 2, 0); + } +} + + +//# run 0x42::m::drop_required \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled.baseline.exp new file mode 100644 index 00000000000..a506a7fbd0d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_after_loop.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0x42::m {] +task 1 lines 18-18: run 0x42::m::drop_required diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled new file mode 100644 index 00000000000..358b762ec72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/drop_ref_in_branch.move` + +//# publish +module 0x42::m { + struct R has key { + v: u64, + } + fun do() + acquires R + { + let _v0 = borrow_global_mut(@0x42); + let _v1 = get_vmut(_v0); + if (*_v1 > 0) { + *_v1 = 0; + return () + }; + some(_v0); + } + fun get_vmut(p0: &mut R): &mut u64 { + &mut p0.v + } + fun some(p0: &mut R) { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled.baseline.exp new file mode 100644 index 00000000000..d680bd4f564 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/drop_ref_in_branch.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-25: publish [module 0x42::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:22:14 + │ +22 │ fun some(p0: &mut R) { + │ ^^ + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled new file mode 100644 index 00000000000..e86697d1255 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled @@ -0,0 +1,28 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/fibonacci.move` + +//# publish +module 0x42::fibonacci { + public fun fib(p0: u64): u64 { + if (p0 == 0) return 0; + if (p0 == 1) return 1; + let _v0 = fib(p0 - 1); + let _v1 = fib(p0 - 2); + _v0 + _v1 + } + public fun test_fib() { + assert!(fib(0) == 0, 0); + assert!(fib(1) == 1, 1); + assert!(fib(2) == 1, 2); + assert!(fib(3) == 2, 3); + assert!(fib(4) == 3, 4); + assert!(fib(5) == 5, 5); + assert!(fib(6) == 8, 6); + assert!(fib(7) == 13, 7); + assert!(fib(8) == 21, 8); + assert!(fib(9) == 34, 9); + assert!(fib(10) == 55, 10); + } +} + + +//# run 0x42::fibonacci::test_fib \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled.baseline.exp new file mode 100644 index 00000000000..2c710be1b21 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/fibonacci.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-25: publish [module 0x42::fibonacci {] +task 1 lines 28-28: run 0x42::fibonacci::test_fib diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled new file mode 100644 index 00000000000..929a382b6c4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled @@ -0,0 +1,31 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/flush_if_alive.move` + +//# publish +module 0x42::m { + struct Cap1 has copy, store { + x: address, + } + struct Cap2 has copy, store { + x: address, + } + struct Cap3 has copy, store { + x: address, + } + struct Store has key { + c: Cap3, + } + fun init(p0: &signer): (Cap1, Cap3) { + let (_v0,_v1,_v2) = stuff(); + let _v3 = _v2; + let _v4 = Store{c: _v3}; + move_to(p0, _v4); + destroy(_v1); + (_v0, _v3) + } + fun stuff(): (Cap1, Cap2, Cap3) { + abort 0 + } + fun destroy(p0: Cap2) { + let Cap2{x: _v0} = p0; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled.baseline.exp new file mode 100644 index 00000000000..115240695f3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/flush_if_alive.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-31: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled new file mode 100644 index 00000000000..03cb765115b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/foreach_mut_expanded.move` + +//# publish +module 0x42::m { + fun test_for_each_mut() { + let _v0 = vector[1, 2, 3]; + let _v1 = 0; + let _v2 = 0x1::vector::length(&_v0); + let _v3 = &mut _v0; + while (_v1 < _v2) { + let _v4 = 0x1::vector::borrow_mut(_v3, _v1); + *_v4 = 2; + _v1 = _v1 + 1; + continue + }; + assert!(_v0 == vector[2, 2, 2], 0); + } +} + + +//# run 0x42::m::test_for_each_mut \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled.baseline.exp new file mode 100644 index 00000000000..4f4be09ebe0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/foreach_mut_expanded.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0x42::m {] +task 1 lines 21-21: run 0x42::m::test_for_each_mut diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled new file mode 100644 index 00000000000..b28ecf15854 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled @@ -0,0 +1,76 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/freeze_mut_ref.move` + +//# publish +module 0x42::freeze_mut_ref { + struct G has drop { + f: u64, + } + public fun borrow_mut(p0: &mut vector): &T0 { + freeze(0x1::vector::borrow_mut(p0, 0)) + } + public fun borrow_mut2(p0: &mut T0): &T0 { + freeze(p0) + } + fun t1(p0: &mut G): &G { + freeze(p0) + } + fun t2(p0: &mut u64, p1: &mut u64): (&mut u64, &mut u64) { + (p0, p1) + } + public fun t5(p0: &mut G): (u64, u64, u64) { + let _v0 = 0 + 1 + 1; + let _v1 = &mut p0.f; + let _v2 = 2; + let _v3 = &mut _v2; + *_v1 = 0; + let _v4 = freeze(_v3); + *_v1 = 2; + let _v5 = *_v4; + let _v6 = *_v1; + (_v5, _v6, _v0) + } + fun test_1() { + let _v0 = 0; + assert!(*freeze(&mut _v0) == 0, 0); + let _v1 = G{f: 3}; + assert!(*&t1(&mut _v1).f == 3, 1); + } + fun test_2() { + let _v0 = G{f: 50}; + let (_v1,_v2,_v3) = t5(&mut _v0); + assert!(_v1 == 2, 0); + assert!(_v2 == 2, 1); + assert!(_v3 == 2, 2); + } + fun test_3() { + let _v0 = vector[0]; + assert!(*borrow_mut(&mut _v0) == 0, 0); + } + fun test_5() { + let _v0 = 3; + assert!(*borrow_mut2(&mut _v0) == 3, 0); + } + fun test_6() { + let _v0 = G{f: 2}; + let _v1 = G{f: 3}; + assert!(*&(&_v0).f == 2, 0); + } + fun test_7() { + let _v0 = G{f: 2}; + let _v1 = G{f: 3}; + assert!(*&(&_v0).f == 2, 0); + } +} + + +//# run 0x42::freeze_mut_ref::test_1 + +//# run 0x42::freeze_mut_ref::test_2 + +//# run 0x42::freeze_mut_ref::test_3 + +//# run 0x42::freeze_mut_ref::test_5 + +//# run 0x42::freeze_mut_ref::test_6 + +//# run 0x42::freeze_mut_ref::test_7 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled.baseline.exp new file mode 100644 index 00000000000..53199ca2cb5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/freeze_mut_ref.decompiled.baseline.exp @@ -0,0 +1,8 @@ +processed 7 tasks +task 0 lines 3-63: publish [module 0x42::freeze_mut_ref {] +task 1 lines 66-66: run 0x42::freeze_mut_ref::test_1 +task 2 lines 68-68: run 0x42::freeze_mut_ref::test_2 +task 3 lines 70-70: run 0x42::freeze_mut_ref::test_3 +task 4 lines 72-72: run 0x42::freeze_mut_ref::test_5 +task 5 lines 74-74: run 0x42::freeze_mut_ref::test_6 +task 6 lines 76-76: run 0x42::freeze_mut_ref::test_7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled new file mode 100644 index 00000000000..30d8595b1f8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/greatest_product.move` + +//# publish +module 0xc0ffee::greatest_product { + public fun find_greatest_product(): u64 { + let _v0 = 0; + let _v1 = 0; + let _v2 = vector[7u8, 3u8, 1u8, 6u8, 7u8, 1u8, 7u8, 6u8, 5u8, 3u8, 1u8, 3u8, 3u8, 8u8, 7u8, 1u8, 5u8, 9u8, 9u8, 5u8, 9u8, 6u8, 9u8, 3u8, 2u8, 9u8, 8u8, 5u8, 3u8, 5u8, 7u8, 9u8, 3u8, 7u8, 2u8, 0u8, 0u8, 6u8, 3u8, 1u8, 7u8, 0u8, 1u8, 8u8, 8u8, 6u8, 7u8, 9u8, 8u8, 0u8, 8u8, 2u8, 8u8, 0u8, 8u8, 5u8, 1u8, 3u8, 2u8, 8u8, 7u8, 0u8, 3u8, 5u8, 0u8, 6u8, 6u8, 4u8, 8u8, 0u8, 7u8, 6u8, 7u8, 8u8, 8u8, 0u8, 1u8, 1u8, 6u8, 9u8, 5u8, 2u8, 3u8, 6u8, 1u8, 5u8, 6u8, 3u8, 0u8, 3u8, 8u8, 8u8, 6u8, 2u8, 3u8, 8u8, 8u8, 1u8, 7u8, 7u8, 4u8, 6u8, 2u8, 8u8, 2u8, 7u8, 9u8, 9u8, 4u8, 7u8, 5u8, 6u8, 4u8, 4u8, 7u8, 9u8, 9u8, 5u8, 8u8, 4u8, 7u8, 3u8, 4u8, 6u8, 7u8, 9u8, 9u8, 5u8, 3u8, 7u8, 1u8, 7u8, 6u8, 5u8, 2u8, 3u8, 7u8, 9u8, 1u8, 9u8, 9u8, 3u8, 5u8, 1u8, 9u8, 9u8, 7u8, 7u8, 8u8, 0u8, 0u8, 9u8, 8u8, 7u8, 6u8, 9u8, 7u8, 7u8, 7u8, 9u8, 9u8, 6u8, 7u8, 6u8, 9u8, 5u8, 5u8, 4u8, 8u8, 3u8, 7u8, 5u8, 5u8, 1u8, 5u8, 5u8, 8u8, 4u8, 4u8, 4u8]; + let _v3 = 0x1::vector::length(&_v2); + loop { + let _v4 = _v3 - 4; + if (!(_v1 <= _v4)) break; + let _v5 = vector[7u8, 3u8, 1u8, 6u8, 7u8, 1u8, 7u8, 6u8, 5u8, 3u8, 1u8, 3u8, 3u8, 8u8, 7u8, 1u8, 5u8, 9u8, 9u8, 5u8, 9u8, 6u8, 9u8, 3u8, 2u8, 9u8, 8u8, 5u8, 3u8, 5u8, 7u8, 9u8, 3u8, 7u8, 2u8, 0u8, 0u8, 6u8, 3u8, 1u8, 7u8, 0u8, 1u8, 8u8, 8u8, 6u8, 7u8, 9u8, 8u8, 0u8, 8u8, 2u8, 8u8, 0u8, 8u8, 5u8, 1u8, 3u8, 2u8, 8u8, 7u8, 0u8, 3u8, 5u8, 0u8, 6u8, 6u8, 4u8, 8u8, 0u8, 7u8, 6u8, 7u8, 8u8, 8u8, 0u8, 1u8, 1u8, 6u8, 9u8, 5u8, 2u8, 3u8, 6u8, 1u8, 5u8, 6u8, 3u8, 0u8, 3u8, 8u8, 8u8, 6u8, 2u8, 3u8, 8u8, 8u8, 1u8, 7u8, 7u8, 4u8, 6u8, 2u8, 8u8, 2u8, 7u8, 9u8, 9u8, 4u8, 7u8, 5u8, 6u8, 4u8, 4u8, 7u8, 9u8, 9u8, 5u8, 8u8, 4u8, 7u8, 3u8, 4u8, 6u8, 7u8, 9u8, 9u8, 5u8, 3u8, 7u8, 1u8, 7u8, 6u8, 5u8, 2u8, 3u8, 7u8, 9u8, 1u8, 9u8, 9u8, 3u8, 5u8, 1u8, 9u8, 9u8, 7u8, 7u8, 8u8, 0u8, 0u8, 9u8, 8u8, 7u8, 6u8, 9u8, 7u8, 7u8, 7u8, 9u8, 9u8, 6u8, 7u8, 6u8, 9u8, 5u8, 5u8, 4u8, 8u8, 3u8, 7u8, 5u8, 5u8, 1u8, 5u8, 5u8, 8u8, 4u8, 4u8, 4u8]; + let _v6 = (*0x1::vector::borrow(&_v5, _v1)) as u64; + let _v7 = vector[7u8, 3u8, 1u8, 6u8, 7u8, 1u8, 7u8, 6u8, 5u8, 3u8, 1u8, 3u8, 3u8, 8u8, 7u8, 1u8, 5u8, 9u8, 9u8, 5u8, 9u8, 6u8, 9u8, 3u8, 2u8, 9u8, 8u8, 5u8, 3u8, 5u8, 7u8, 9u8, 3u8, 7u8, 2u8, 0u8, 0u8, 6u8, 3u8, 1u8, 7u8, 0u8, 1u8, 8u8, 8u8, 6u8, 7u8, 9u8, 8u8, 0u8, 8u8, 2u8, 8u8, 0u8, 8u8, 5u8, 1u8, 3u8, 2u8, 8u8, 7u8, 0u8, 3u8, 5u8, 0u8, 6u8, 6u8, 4u8, 8u8, 0u8, 7u8, 6u8, 7u8, 8u8, 8u8, 0u8, 1u8, 1u8, 6u8, 9u8, 5u8, 2u8, 3u8, 6u8, 1u8, 5u8, 6u8, 3u8, 0u8, 3u8, 8u8, 8u8, 6u8, 2u8, 3u8, 8u8, 8u8, 1u8, 7u8, 7u8, 4u8, 6u8, 2u8, 8u8, 2u8, 7u8, 9u8, 9u8, 4u8, 7u8, 5u8, 6u8, 4u8, 4u8, 7u8, 9u8, 9u8, 5u8, 8u8, 4u8, 7u8, 3u8, 4u8, 6u8, 7u8, 9u8, 9u8, 5u8, 3u8, 7u8, 1u8, 7u8, 6u8, 5u8, 2u8, 3u8, 7u8, 9u8, 1u8, 9u8, 9u8, 3u8, 5u8, 1u8, 9u8, 9u8, 7u8, 7u8, 8u8, 0u8, 0u8, 9u8, 8u8, 7u8, 6u8, 9u8, 7u8, 7u8, 7u8, 9u8, 9u8, 6u8, 7u8, 6u8, 9u8, 5u8, 5u8, 4u8, 8u8, 3u8, 7u8, 5u8, 5u8, 1u8, 5u8, 5u8, 8u8, 4u8, 4u8, 4u8]; + let _v8 = &_v7; + let _v9 = _v1 + 1; + let _v10 = (*0x1::vector::borrow(_v8, _v9)) as u64; + let _v11 = _v6 * _v10; + let _v12 = vector[7u8, 3u8, 1u8, 6u8, 7u8, 1u8, 7u8, 6u8, 5u8, 3u8, 1u8, 3u8, 3u8, 8u8, 7u8, 1u8, 5u8, 9u8, 9u8, 5u8, 9u8, 6u8, 9u8, 3u8, 2u8, 9u8, 8u8, 5u8, 3u8, 5u8, 7u8, 9u8, 3u8, 7u8, 2u8, 0u8, 0u8, 6u8, 3u8, 1u8, 7u8, 0u8, 1u8, 8u8, 8u8, 6u8, 7u8, 9u8, 8u8, 0u8, 8u8, 2u8, 8u8, 0u8, 8u8, 5u8, 1u8, 3u8, 2u8, 8u8, 7u8, 0u8, 3u8, 5u8, 0u8, 6u8, 6u8, 4u8, 8u8, 0u8, 7u8, 6u8, 7u8, 8u8, 8u8, 0u8, 1u8, 1u8, 6u8, 9u8, 5u8, 2u8, 3u8, 6u8, 1u8, 5u8, 6u8, 3u8, 0u8, 3u8, 8u8, 8u8, 6u8, 2u8, 3u8, 8u8, 8u8, 1u8, 7u8, 7u8, 4u8, 6u8, 2u8, 8u8, 2u8, 7u8, 9u8, 9u8, 4u8, 7u8, 5u8, 6u8, 4u8, 4u8, 7u8, 9u8, 9u8, 5u8, 8u8, 4u8, 7u8, 3u8, 4u8, 6u8, 7u8, 9u8, 9u8, 5u8, 3u8, 7u8, 1u8, 7u8, 6u8, 5u8, 2u8, 3u8, 7u8, 9u8, 1u8, 9u8, 9u8, 3u8, 5u8, 1u8, 9u8, 9u8, 7u8, 7u8, 8u8, 0u8, 0u8, 9u8, 8u8, 7u8, 6u8, 9u8, 7u8, 7u8, 7u8, 9u8, 9u8, 6u8, 7u8, 6u8, 9u8, 5u8, 5u8, 4u8, 8u8, 3u8, 7u8, 5u8, 5u8, 1u8, 5u8, 5u8, 8u8, 4u8, 4u8, 4u8]; + let _v13 = &_v12; + let _v14 = _v1 + 2; + let _v15 = (*0x1::vector::borrow(_v13, _v14)) as u64; + let _v16 = _v11 * _v15; + let _v17 = vector[7u8, 3u8, 1u8, 6u8, 7u8, 1u8, 7u8, 6u8, 5u8, 3u8, 1u8, 3u8, 3u8, 8u8, 7u8, 1u8, 5u8, 9u8, 9u8, 5u8, 9u8, 6u8, 9u8, 3u8, 2u8, 9u8, 8u8, 5u8, 3u8, 5u8, 7u8, 9u8, 3u8, 7u8, 2u8, 0u8, 0u8, 6u8, 3u8, 1u8, 7u8, 0u8, 1u8, 8u8, 8u8, 6u8, 7u8, 9u8, 8u8, 0u8, 8u8, 2u8, 8u8, 0u8, 8u8, 5u8, 1u8, 3u8, 2u8, 8u8, 7u8, 0u8, 3u8, 5u8, 0u8, 6u8, 6u8, 4u8, 8u8, 0u8, 7u8, 6u8, 7u8, 8u8, 8u8, 0u8, 1u8, 1u8, 6u8, 9u8, 5u8, 2u8, 3u8, 6u8, 1u8, 5u8, 6u8, 3u8, 0u8, 3u8, 8u8, 8u8, 6u8, 2u8, 3u8, 8u8, 8u8, 1u8, 7u8, 7u8, 4u8, 6u8, 2u8, 8u8, 2u8, 7u8, 9u8, 9u8, 4u8, 7u8, 5u8, 6u8, 4u8, 4u8, 7u8, 9u8, 9u8, 5u8, 8u8, 4u8, 7u8, 3u8, 4u8, 6u8, 7u8, 9u8, 9u8, 5u8, 3u8, 7u8, 1u8, 7u8, 6u8, 5u8, 2u8, 3u8, 7u8, 9u8, 1u8, 9u8, 9u8, 3u8, 5u8, 1u8, 9u8, 9u8, 7u8, 7u8, 8u8, 0u8, 0u8, 9u8, 8u8, 7u8, 6u8, 9u8, 7u8, 7u8, 7u8, 9u8, 9u8, 6u8, 7u8, 6u8, 9u8, 5u8, 5u8, 4u8, 8u8, 3u8, 7u8, 5u8, 5u8, 1u8, 5u8, 5u8, 8u8, 4u8, 4u8, 4u8]; + let _v18 = &_v17; + let _v19 = _v1 + 3; + let _v20 = (*0x1::vector::borrow(_v18, _v19)) as u64; + let _v21 = _v16 * _v20; + if (_v21 > _v0) _v0 = _v21; + _v1 = _v1 + 1; + continue + }; + _v0 + } + public fun test_find_greatest_product() { + assert!(find_greatest_product() == 3969, 0); + } +} + + +//# run 0xc0ffee::greatest_product::test_find_greatest_product \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled.baseline.exp new file mode 100644 index 00000000000..29c7a70de1a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/greatest_product.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-39: publish [module 0xc0ffee::greatest_product {] +task 1 lines 42-42: run 0xc0ffee::greatest_product::test_find_greatest_product diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled new file mode 100644 index 00000000000..94c148126c7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/issue_11022.move` + +//# publish +module 0xc0ffee::dummy1 { +} + + +//# publish +module 0xc0ffee::dummy2 { + public fun main(): u64 { + 1 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled.baseline.exp new file mode 100644 index 00000000000..f19ae2f9cb3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_11022.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-5: publish [module 0xc0ffee::dummy1 {] +task 1 lines 8-13: publish [module 0xc0ffee::dummy2 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled new file mode 100644 index 00000000000..6a184e3b5f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled @@ -0,0 +1,33 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/issue_17412.move` + +//# publish +module 0xcafe::Module0 { + enum Enum0 has copy, drop { + Variant0, + Variant1 { + field: bool, + } + Variant2, + } + public fun function3(p0: bool, p1: bool) { + let _v0 = Enum0::Variant0{}; + let _v1 = &_v0; + 'l0: loop { + loop { + if (!(_v1 is Variant2)) { + if (_v1 is Variant1) { + let Enum0::Variant1{field: _v2} = _v0; + if (!p1) break; + break + }; + if (_v1 is Variant0) break 'l0; + abort 14566554180833181697 + }; + let Enum0::Variant2{} = _v0; + return () + }; + return () + }; + let Enum0::Variant0{} = _v0; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled.baseline.exp new file mode 100644 index 00000000000..e0ca72f195a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/issue_17412.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-33: publish [module 0xcafe::Module0 {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:12:26 + │ +12 │ public fun function3(p0: bool, p1: bool) { + │ ^^ + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled new file mode 100644 index 00000000000..57d4568d84a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled @@ -0,0 +1,45 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/largest_prime_factor.move` + +//# publish +module 0xc0ffee::largest_prime_factor { + public fun largest_prime_factor(p0: u64): u64 { + let _v0 = 1; + let _v1 = 2; + loop { + let _v2; + let _v3 = p0 / 2; + if (!(_v1 <= _v3)) break; + if (p0 % _v1 == 0) _v2 = is_prime(_v1) else _v2 = false; + if (_v2) _v0 = _v1; + _v1 = _v1 + 1; + continue + }; + if (is_prime(p0)) _v0 = p0; + _v0 + } + public fun is_prime(p0: u64): bool { + 'l0: loop { + 'l1: loop { + if (!(p0 < 2)) { + let _v0 = 2; + loop { + let _v1 = p0 / 2; + if (!(_v0 <= _v1)) break 'l0; + if (p0 % _v0 == 0) break 'l1; + _v0 = _v0 + 1; + continue + } + }; + return false + }; + return false + }; + true + } + public fun test_largest_prime_factor() { + assert!(largest_prime_factor(13195) == 29, 0); + } +} + + +//# run 0xc0ffee::largest_prime_factor::test_largest_prime_factor \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled.baseline.exp new file mode 100644 index 00000000000..ef246fb874a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/largest_prime_factor.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-42: publish [module 0xc0ffee::largest_prime_factor {] +task 1 lines 45-45: run 0xc0ffee::largest_prime_factor::test_largest_prime_factor diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled new file mode 100644 index 00000000000..c733509b2e3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/loop_invariant_code_1.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: u64): u64 { + let _v0 = p0; + let _v1 = 0; + while (_v1 < 10) { + _v0 = p0; + _v1 = _v1 + 1 + }; + _v0 + } +} + + +//# run 0xc0ffee::m::test --args 44 + +//# run 0xc0ffee::m::test --args 6 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled.baseline.exp new file mode 100644 index 00000000000..5c9989cea84 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/loop_invariant_code_1.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test --args 44 +return values: 44 +task 2 lines 19-19: run 0xc0ffee::m::test --args 6 +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled new file mode 100644 index 00000000000..659b878c55a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/mut_ref_compare.move` + +//# publish +module 0x42::m { + fun test(): bool { + let _v0 = 1; + let _v1 = 1; + let _v2 = &mut _v0; + let _v3 = &mut _v1; + let _v4 = freeze(_v2); + let _v5 = freeze(_v3); + _v4 == _v5 + } +} + + +//# run 0x42::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled.baseline.exp new file mode 100644 index 00000000000..25d604cccbc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mut_ref_compare.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0x42::m {] +task 1 lines 17-17: run 0x42::m::test +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled new file mode 100644 index 00000000000..f8e7b94ed60 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled @@ -0,0 +1,35 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/mutate_if.move` + +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + x: bool, + y: u64, + z: u64, + } + fun foo1(p0: S): S { + let _v0; + if (*&(&p0).x) _v0 = *&(&p0).y else _v0 = *&(&p0).z; + let _v1 = &mut _v0; + *_v1 = 2; + p0 + } + fun foo2(p0: S): S { + let _v0; + if (*&(&p0).x) _v0 = *&(&p0).y else _v0 = *&(&p0).z; + let _v1 = &mut _v0; + *_v1 = 2; + p0 + } + fun test() { + let _v0 = S{x: true, y: 1, z: 3}; + let _v1 = foo1(_v0); + assert!(_v0 == _v1, 0); + _v0 = S{x: false, y: 4, z: 5}; + _v1 = foo2(_v0); + assert!(_v0 == _v1, 1); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled.baseline.exp new file mode 100644 index 00000000000..e8ab38c8b98 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_if.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-32: publish [module 0xc0ffee::m {] +task 1 lines 35-35: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled new file mode 100644 index 00000000000..a51fee25f36 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/mutate_vector.move` + +//# publish +module 0x42::m { + struct Scalar has copy, drop, store { + data: vector, + } + public fun new_scalar_from_u8(p0: u8): Scalar { + let _v0 = scalar_zero(); + let _v1 = 0x1::vector::borrow_mut(&mut (&mut _v0).data, 0); + *_v1 = p0; + _v0 + } + public fun scalar_zero(): Scalar { + Scalar{data: vector[0u8]} + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled.baseline.exp new file mode 100644 index 00000000000..7a4eb52fd05 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/mutate_vector.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-17: publish [module 0x42::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled new file mode 100644 index 00000000000..8d59b5c12cc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/nested_mutate.move` + +//# publish +module 0xc0ffee::m { + struct T has copy, drop { + y: u64, + } + struct S has copy, drop { + x: T, + } + fun foo(p0: S, p1: S): S { + let _v0 = *&(&(&p1).x).y; + let _v1 = &mut (&mut (&mut p0).x).y; + *_v1 = _v0; + let _v2 = *&(&(&p0).x).y; + let _v3 = &mut _v2; + *_v3 = 1; + p0 + } + public fun test() { + let _v0 = S{x: T{y: 42}}; + let _v1 = S{x: T{y: 43}}; + let _v2 = foo(_v0, _v1); + assert!(*&(&(&_v2).x).y == 43, 0); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled.baseline.exp new file mode 100644 index 00000000000..aa39efe68a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/nested_mutate.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-26: publish [module 0xc0ffee::m {] +task 1 lines 29-29: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled new file mode 100644 index 00000000000..343af75b70f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled @@ -0,0 +1,39 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/pack_unpack_ref.move` + +//# publish +module 0x42::pack_unpack_ref { + struct G has drop { + x1: u64, + x2: u64, + s: S, + } + struct S has drop { + f: u64, + g: u64, + } + fun unpack_ref_G() { + let _v0 = S{f: 0, g: 1}; + let _v1 = G{x1: 2, x2: 3, s: _v0}; + let _v2 = &mut _v1; + let _v3 = &mut _v2.x1; + let _v4 = &mut _v2.x2; + let _v5 = &mut _v2.s; + let _v6 = &mut _v5.f; + let _v7 = &mut _v5.g; + assert!(*_v6 == 0, 0); + assert!(*_v7 == 1, 1); + assert!(*_v3 == 2, 2); + assert!(*_v4 == 3, 3); + *_v3 = *_v3 + 1; + *_v4 = *_v4 + 1; + *_v6 = *_v6 + 1; + *_v7 = *_v7 + 1; + assert!(*_v6 == 1, 0); + assert!(*_v7 == 2, 1); + assert!(*_v3 == 3, 2); + assert!(*_v4 == 4, 3); + } +} + + +//# run 0x42::pack_unpack_ref::unpack_ref_G \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled.baseline.exp new file mode 100644 index 00000000000..a67d8d73907 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/pack_unpack_ref.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-36: publish [module 0x42::pack_unpack_ref {] +task 1 lines 39-39: run 0x42::pack_unpack_ref::unpack_ref_G diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled new file mode 100644 index 00000000000..142d23670a7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled @@ -0,0 +1,32 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/power_function.move` + +//# publish +module 0x42::power_function { + public fun pow(p0: u64, p1: u64): u64 { + let _v0; + 'l0: loop { + if (!(p1 == 0)) { + _v0 = p0; + let _v1 = 1; + loop { + if (!(_v1 < p1)) break 'l0; + _v0 = _v0 * p0; + _v1 = _v1 + 1 + } + }; + return 1 + }; + _v0 + } + public fun test_pow() { + assert!(pow(2, 0) == 1, 0); + assert!(pow(2, 1) == 2, 1); + assert!(pow(2, 2) == 4, 2); + assert!(pow(2, 3) == 8, 3); + assert!(pow(3, 3) == 27, 4); + assert!(pow(5, 4) == 625, 5); + } +} + + +//# run 0x42::power_function::test_pow \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled.baseline.exp new file mode 100644 index 00000000000..6863f11a072 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/power_function.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-29: publish [module 0x42::power_function {] +task 1 lines 32-32: run 0x42::power_function::test_pow diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled new file mode 100644 index 00000000000..2bb637eca66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled @@ -0,0 +1,43 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/prime_check.move` + +//# publish +module 0xc0ffee::prime { + public fun is_prime(p0: u64): bool { + 'l0: loop { + 'l1: loop { + if (!(p0 < 2)) { + let _v0 = 2; + loop { + let _v1 = p0 / 2; + if (!(_v0 <= _v1)) break 'l0; + if (p0 % _v0 == 0) break 'l1; + _v0 = _v0 + 1; + continue + } + }; + return false + }; + return false + }; + true + } + public fun test_is_prime() { + if (is_prime(0)) abort 0; + if (is_prime(1)) abort 1; + assert!(is_prime(2), 2); + assert!(is_prime(3), 3); + if (is_prime(4)) abort 4; + assert!(is_prime(5), 5); + if (is_prime(6)) abort 6; + assert!(is_prime(7), 7); + if (is_prime(8)) abort 8; + if (is_prime(9)) abort 9; + if (is_prime(10)) abort 10; + assert!(is_prime(11), 11); + if (is_prime(12)) abort 12; + assert!(is_prime(13), 13); + } +} + + +//# run 0xc0ffee::prime::test_is_prime \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled.baseline.exp new file mode 100644 index 00000000000..096c8e30d69 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/prime_check.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-40: publish [module 0xc0ffee::prime {] +task 1 lines 43-43: run 0xc0ffee::prime::test_is_prime diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled new file mode 100644 index 00000000000..74ec846d340 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled @@ -0,0 +1,32 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/queue.move` + +//# publish +module 0x42::queue { + use 0x1::vector; + struct Queue has drop, key { + data: vector, + } + public fun create(): Queue { + Queue{data: vector::empty()} + } + public fun dequeue(p0: &mut Queue): T0 { + vector::remove(&mut p0.data, 0) + } + public fun enqueue(p0: &mut Queue, p1: T0) { + vector::push_back(&mut p0.data, p1); + } + public fun test_queue_operations() { + let _v0 = create(); + enqueue(&mut _v0, 40); + enqueue(&mut _v0, 41); + enqueue(&mut _v0, 42); + assert!(dequeue(&mut _v0) == 40, 1); + enqueue(&mut _v0, 43); + assert!(dequeue(&mut _v0) == 41, 2); + assert!(dequeue(&mut _v0) == 42, 3); + assert!(dequeue(&mut _v0) == 43, 4); + } +} + + +//# run 0x42::queue::test_queue_operations \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled.baseline.exp new file mode 100644 index 00000000000..9c0c82d44f1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/queue.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-29: publish [module 0x42::queue {] +task 1 lines 32-32: run 0x42::queue::test_queue_operations diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled new file mode 100644 index 00000000000..7901cee2fed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled @@ -0,0 +1,40 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/simple_map_keys.move` + +//# publish +module 0x42::simple_map { + struct Element has copy, drop, store { + key: T0, + value: T1, + } + struct SimpleMap has copy, drop, store { + data: vector>, + } + public fun keys(p0: &SimpleMap): vector { + let _v0 = &p0.data; + let _v1 = 0x1::vector::empty(); + let _v2 = 0; + let _v3 = 0x1::vector::length>(_v0); + while (_v2 < _v3) { + let _v4 = 0x1::vector::borrow>(_v0, _v2); + let _v5 = &mut _v1; + let _v6 = *&_v4.key; + 0x1::vector::push_back(_v5, _v6); + _v2 = _v2 + 1; + continue + }; + _v1 + } + public fun run() { + let _v0 = Element{key: 1, value: 2}; + let _v1 = 0x1::vector::empty>(); + let _v2 = &mut _v1; + 0x1::vector::push_back>(_v2, _v0); + 0x1::vector::push_back>(_v2, _v0); + 0x1::vector::push_back>(_v2, _v0); + let _v3 = SimpleMap{data: _v1}; + assert!(keys(&_v3) == vector[1, 1, 1], 33); + } +} + + +//# run 0x42::simple_map::run \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled.baseline.exp new file mode 100644 index 00000000000..6b543d0f8a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-37: publish [module 0x42::simple_map {] +task 1 lines 40-40: run 0x42::simple_map::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled new file mode 100644 index 00000000000..40e3802b1ee --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled @@ -0,0 +1,40 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/simple_map_keys_typed.move` + +//# publish +module 0x42::simple_map { + struct Element has copy, drop, store { + key: T0, + value: T1, + } + struct SimpleMap has copy, drop, store { + data: vector>, + } + public fun keys(p0: &SimpleMap): vector { + let _v0 = &p0.data; + let _v1 = 0x1::vector::empty(); + let _v2 = 0; + let _v3 = 0x1::vector::length>(_v0); + while (_v2 < _v3) { + let _v4 = 0x1::vector::borrow>(_v0, _v2); + let _v5 = &mut _v1; + let _v6 = *&_v4.key; + 0x1::vector::push_back(_v5, _v6); + _v2 = _v2 + 1; + continue + }; + _v1 + } + public fun run() { + let _v0 = Element{key: 1, value: 2}; + let _v1 = 0x1::vector::empty>(); + let _v2 = &mut _v1; + 0x1::vector::push_back>(_v2, _v0); + 0x1::vector::push_back>(_v2, _v0); + 0x1::vector::push_back>(_v2, _v0); + let _v3 = SimpleMap{data: _v1}; + assert!(keys(&_v3) == vector[1, 1, 1], 33); + } +} + + +//# run 0x42::simple_map::run \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..6b543d0f8a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/simple_map_keys_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-37: publish [module 0x42::simple_map {] +task 1 lines 40-40: run 0x42::simple_map::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled new file mode 100644 index 00000000000..579324e3cf2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled @@ -0,0 +1,31 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/smallest_multiple.move` + +//# publish +module 0xc0ffee::smallest_multiple { + public fun smallest_multiple(p0: u64): u64 { + let _v0 = 1; + let _v1 = 1; + while (_v1 <= p0) { + _v0 = lcm(_v0, _v1); + _v1 = _v1 + 1 + }; + _v0 + } + public fun lcm(p0: u64, p1: u64): u64 { + let _v0 = p0 * p1; + let _v1 = gcd(p0, p1); + _v0 / _v1 + } + public fun gcd(p0: u64, p1: u64): u64 { + if (p1 == 0) return p0; + let _v0 = p0 % p1; + gcd(p1, _v0) + } + public fun test_smallest_multiple() { + assert!(smallest_multiple(10) == 2520, 0); + assert!(smallest_multiple(20) == 232792560, 1); + } +} + + +//# run 0xc0ffee::smallest_multiple::test_smallest_multiple \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled.baseline.exp new file mode 100644 index 00000000000..a6f1efa96aa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/smallest_multiple.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-28: publish [module 0xc0ffee::smallest_multiple {] +task 1 lines 31-31: run 0xc0ffee::smallest_multiple::test_smallest_multiple diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled new file mode 100644 index 00000000000..64dc602d44e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled @@ -0,0 +1,46 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/struct_assign_swap.move` + +//# publish +module 0xc0ffee::m { + struct S { + f: u32, + g: u32, + } + fun swap1(p0: u32, p1: u32): (u32, u32) { + let S{f: _v0, g: _v1} = S{f: p1, g: p0}; + (_v0, _v1) + } + fun swap2(): (u32, u32) { + let S{f: _v0, g: _v1} = S{f: 55u32, g: 44u32}; + (55u32, 44u32) + } + fun swap3(p0: u32, p1: u32): (u32, u32) { + let S{f: _v0, g: _v1} = S{f: p0, g: p1}; + (_v1, _v0) + } + fun swap4(p0: u32, p1: u32): (u32, u32) { + let S{f: _v0, g: _v1} = S{f: p0, g: p1}; + (_v1, _v0) + } + fun test1(): (u32, u32) { + let (_v0,_v1) = swap1(1u32, 2u32); + (_v0, _v1) + } + fun test3(): (u32, u32) { + let (_v0,_v1) = swap3(1u32, 2u32); + (_v0, _v1) + } + fun test4(): (u32, u32) { + let (_v0,_v1) = swap4(1u32, 2u32); + (_v0, _v1) + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::swap2 + +//# run 0xc0ffee::m::test3 + +//# run 0xc0ffee::m::test4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled.baseline.exp new file mode 100644 index 00000000000..19aad0685c7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/struct_assign_swap.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-37: publish [module 0xc0ffee::m {] +task 1 lines 40-40: run 0xc0ffee::m::test1 +return values: 2, 1 +task 2 lines 42-42: run 0xc0ffee::m::swap2 +return values: 55, 44 +task 3 lines 44-44: run 0xc0ffee::m::test3 +return values: 2, 1 +task 4 lines 46-46: run 0xc0ffee::m::test4 +return values: 2, 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled new file mode 100644 index 00000000000..67420e3698a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/sum_multiples_euler.move` + +//# publish +module 0xc0ffee::sum_multiples { + public fun sum_multiples_3_or_5(p0: u64): u64 { + let _v0 = 0; + let _v1 = 0; + loop { + let _v2; + if (!(_v1 < p0)) break; + if (_v1 % 3 == 0) _v2 = true else _v2 = _v1 % 5 == 0; + if (_v2) _v0 = _v0 + _v1; + _v1 = _v1 + 1; + continue + }; + _v0 + } + public fun test_sum_multiples() { + assert!(sum_multiples_3_or_5(10) == 23, 0); + assert!(sum_multiples_3_or_5(1000) == 233168, 1); + } +} + + +//# run 0xc0ffee::sum_multiples::test_sum_multiples \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled.baseline.exp new file mode 100644 index 00000000000..b2c942b3142 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_multiples_euler.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-22: publish [module 0xc0ffee::sum_multiples {] +task 1 lines 25-25: run 0xc0ffee::sum_multiples::test_sum_multiples diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled new file mode 100644 index 00000000000..d0220343d92 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled @@ -0,0 +1,33 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/sum_square_difference.move` + +//# publish +module 0xc0ffee::sum_square_difference { + public fun difference(p0: u64): u64 { + let _v0 = square_of_sum(p0); + let _v1 = sum_of_squares(p0); + _v0 - _v1 + } + public fun square_of_sum(p0: u64): u64 { + let _v0 = p0 + 1; + p0 = p0 * _v0 / 2; + p0 * p0 + } + public fun sum_of_squares(p0: u64): u64 { + let _v0 = 0; + let _v1 = 1; + while (_v1 <= p0) { + let _v2 = _v1 * _v1; + _v0 = _v0 + _v2; + _v1 = _v1 + 1; + continue + }; + _v0 + } + public fun test_difference() { + assert!(difference(10) == 2640, 0); + assert!(difference(100) == 25164150, 1); + } +} + + +//# run 0xc0ffee::sum_square_difference::test_difference \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled.baseline.exp new file mode 100644 index 00000000000..a30508eb523 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/sum_square_difference.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-30: publish [module 0xc0ffee::sum_square_difference {] +task 1 lines 33-33: run 0xc0ffee::sum_square_difference::test_difference diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled new file mode 100644 index 00000000000..f4bb28c235d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/too_many_returns.move` + +//# publish +module 0xc0ffee::m { + public fun test(): (u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64) { + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled.baseline.exp new file mode 100644 index 00000000000..5d4480ece72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/too_many_returns.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-8: publish [module 0xc0ffee::m {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::m'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0xc0ffee::m, + indices: [(FunctionHandle, 0)], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled new file mode 100644 index 00000000000..680e128ad7d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled @@ -0,0 +1,118 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/tuple_swap.move` + +//# publish +module 0xc0ffee::m { + struct W { + inner: u64, + } + fun swap1(p0: u32, p1: u32): (u32, u32) { + (p1, p0) + } + fun swap10(p0: u64): (u64, u64) { + (88, p0) + } + fun swap11(): (u64, u64) { + (83, 53) + } + fun swap2(p0: u64, p1: u64, p2: u64, p3: u64): (u64, u64, u64, u64) { + (p2, p3, p1, p0) + } + fun swap3(p0: u64, p1: u64): (u64, u64) { + (p1, p0) + } + fun swap4(p0: W, p1: W): (W, W) { + (p1, p0) + } + fun swap5(): (u64, u64) { + let _v0 = W{inner: 258}; + let _v1 = W{inner: 147}; + let W{inner: _v2} = _v0; + let W{inner: _v3} = _v1; + (_v2, _v3) + } + fun swap6(p0: u64, p1: u64): (u64, u64) { + let _v0 = p1 + 1; + let _v1 = p0 + 1; + (_v0, _v1) + } + fun swap7(p0: u64, p1: u64): (u64, u64) { + let _v0 = &p0; + let _v1 = *&p1; + let _v2 = *_v0; + (_v1, _v2) + } + fun swap8(p0: u64, p1: u64, p2: u64): (u64, u64) { + let _v0 = 0; + let _v1 = false; + loop { + if (_v1) _v0 = _v0 + 1 else _v1 = true; + if (!(_v0 < p2)) break; + let _v2 = p0; + p0 = p1; + p1 = _v2; + continue + }; + (p0, p1) + } + fun swap9(): (u64, u64) { + (23, 51) + } + public fun test1(): (u32, u32) { + let (_v0,_v1) = swap1(1u32, 2u32); + (_v0, _v1) + } + public fun test10(): (u64, u64) { + let (_v0,_v1) = swap10(10); + (_v0, _v1) + } + public fun test2(): (u64, u64, u64, u64) { + let (_v0,_v1,_v2,_v3) = swap2(10, 20, 30, 40); + (_v0, _v1, _v2, _v3) + } + public fun test3(): (u64, u64) { + let (_v0,_v1) = swap3(11, 22); + (_v0, _v1) + } + public fun test4(): (W, W) { + let _v0 = W{inner: 111}; + let _v1 = W{inner: 222}; + let (_v2,_v3) = swap4(_v0, _v1); + (_v2, _v3) + } + public fun test6(): (u64, u64) { + let (_v0,_v1) = swap6(4, 40); + (_v0, _v1) + } + public fun test7(): (u64, u64) { + let (_v0,_v1) = swap7(44, 440); + (_v0, _v1) + } + public fun test8(): (u64, u64, u64, u64) { + let (_v0,_v1) = swap8(8, 80, 8); + let (_v2,_v3) = swap8(8, 80, 9); + (_v0, _v1, _v2, _v3) + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 + +//# run 0xc0ffee::m::test4 + +//# run 0xc0ffee::m::swap5 + +//# run 0xc0ffee::m::test6 + +//# run 0xc0ffee::m::test7 + +//# run 0xc0ffee::m::test8 + +//# run 0xc0ffee::m::swap9 + +//# run 0xc0ffee::m::test10 + +//# run 0xc0ffee::m::swap11 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled.baseline.exp new file mode 100644 index 00000000000..0e75c5dc631 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/tuple_swap.decompiled.baseline.exp @@ -0,0 +1,24 @@ +processed 12 tasks +task 0 lines 3-95: publish [module 0xc0ffee::m {] +task 1 lines 98-98: run 0xc0ffee::m::test1 +return values: 2, 1 +task 2 lines 100-100: run 0xc0ffee::m::test2 +return values: 30, 40, 20, 10 +task 3 lines 102-102: run 0xc0ffee::m::test3 +return values: 22, 11 +task 4 lines 104-104: run 0xc0ffee::m::test4 +return values: { 222 }, { 111 } +task 5 lines 106-106: run 0xc0ffee::m::swap5 +return values: 258, 147 +task 6 lines 108-108: run 0xc0ffee::m::test6 +return values: 41, 5 +task 7 lines 110-110: run 0xc0ffee::m::test7 +return values: 440, 44 +task 8 lines 112-112: run 0xc0ffee::m::test8 +return values: 8, 80, 80, 8 +task 9 lines 114-114: run 0xc0ffee::m::swap9 +return values: 23, 51 +task 10 lines 116-116: run 0xc0ffee::m::test10 +return values: 88, 10 +task 11 lines 118-118: run 0xc0ffee::m::swap11 +return values: 83, 53 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled new file mode 100644 index 00000000000..39e4387e2e0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/vector_depth_check.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 0x1::vector::empty>>>>(); + 0x1::vector::length>>>>(&_v0) + } +} + + +//# run 0xc0ffee::m::test + +//# publish +module 0xc0ffee::n { + public fun test(): u64 { + let _v0 = 0x1::vector::empty>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(); + 0x1::vector::length>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(&_v0) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled.baseline.exp new file mode 100644 index 00000000000..02b0ca81e31 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_depth_check.decompiled.baseline.exp @@ -0,0 +1,12 @@ +processed 3 tasks +task 0 lines 3-9: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test +return values: 0 +task 2 lines 14-20: publish [module 0xc0ffee::n {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::n'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xc0ffee::n, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled new file mode 100644 index 00000000000..3ace0518db0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled @@ -0,0 +1,44 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/vector_popback.move` + +//# publish +module 0x42::vector { + use 0x1::vector; + public fun remove(p0: &mut vector, p1: u64): T0 { + let _v0 = vector::length(freeze(p0)); + if (p1 >= _v0) abort 1; + _v0 = _v0 - 1; + while (p1 < _v0) { + let _v1 = p1; + p1 = p1 + 1; + vector::swap(p0, _v1, p1); + continue + }; + vector::pop_back(p0) + } + fun create(): vector { + vector[1, 2, 3] + } + public fun test_fold() { + let _v0 = 0; + let _v1 = vector[1]; + vector::reverse(&mut _v1); + while (!vector::is_empty(&_v1)) { + let _v2 = vector::pop_back(&mut _v1); + _v0 = 0; + continue + }; + assert!(_v0 == 0, 0); + } + public fun test_remove() { + let _v0 = create(); + assert!(remove(&mut _v0, 1) == 2, 0); + assert!(vector::length(&_v0) == 2, 0); + assert!(*vector::borrow(&_v0, 0) == 1, 0); + assert!(*vector::borrow(&_v0, 1) == 3, 0); + } +} + + +//# run 0x42::vector::test_fold + +//# run 0x42::vector::test_remove \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled.baseline.exp new file mode 100644 index 00000000000..c25a9fc76d2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/vector_popback.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-39: publish [module 0x42::vector {] +task 1 lines 42-42: run 0x42::vector::test_fold +task 2 lines 44-44: run 0x42::vector::test_remove diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled new file mode 100644 index 00000000000..ebf5370fb5b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled @@ -0,0 +1,22 @@ +//**** Cross-compiled for `move` syntax from `tests/misc/write_ref_dest.move` + +//# publish +module 0x42::m { + fun foo(p0: &vector): (vector, u64) { + (*p0, 0) + } + fun test_assign() { + assert!(vector[1] == vector[1], 0); + } + fun test_call() { + let _v0 = 0x1::vector::empty(); + let (_v1,_v2) = foo(&_v0); + let _v3 = 0x1::vector::empty(); + assert!(_v1 == _v3, 0); + } +} + + +//# run 0x42::m::test_call + +//# run 0x42::m::test_assign \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled.baseline.exp new file mode 100644 index 00000000000..7c22eebd83e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/round-trip/write_ref_dest.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-17: publish [module 0x42::m {] +task 1 lines 20-20: run 0x42::m::test_call +task 2 lines 22-22: run 0x42::m::test_assign diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys.exp index 5d92c423f3f..75a097c7538 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-48: publish [module 0x42::simple_map {] +task 1 lines 50-50: run 0x42::simple_map::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys_typed.exp index 5d92c423f3f..21f67636021 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/simple_map_keys_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-47: publish [module 0x42::simple_map {] +task 1 lines 49-49: run 0x42::simple_map::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/smallest_multiple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/smallest_multiple.exp index 5d92c423f3f..cc5b35b56cb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/smallest_multiple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/smallest_multiple.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-29: publish [module 0xc0ffee::smallest_multiple {] +task 1 lines 31-31: run 0xc0ffee::smallest_multiple::test_smallest_multiple diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/struct_assign_swap.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/struct_assign_swap.exp index 1f8394d52ce..6d19b76c493 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/struct_assign_swap.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/struct_assign_swap.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 43-43: +task 0 lines 1-41: publish [module 0xc0ffee::m {] +task 1 lines 43-43: run 0xc0ffee::m::test1 return values: 2, 1 - -task 2 'run'. lines 45-45: +task 2 lines 45-45: run 0xc0ffee::m::swap2 return values: 55, 44 - -task 3 'run'. lines 47-47: +task 3 lines 47-47: run 0xc0ffee::m::test3 return values: 2, 1 - -task 4 'run'. lines 49-49: +task 4 lines 49-49: run 0xc0ffee::m::test4 return values: 2, 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_multiples_euler.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_multiples_euler.exp index 5d92c423f3f..39c38aabe4f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_multiples_euler.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_multiples_euler.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-19: publish [module 0xc0ffee::sum_multiples {] +task 1 lines 21-21: run 0xc0ffee::sum_multiples::test_sum_multiples diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_square_difference.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_square_difference.exp index 5d92c423f3f..a508982707e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_square_difference.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/sum_square_difference.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-26: publish [module 0xc0ffee::sum_square_difference {] +task 1 lines 28-28: run 0xc0ffee::sum_square_difference::test_difference diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp new file mode 100644 index 00000000000..1f5ae804f53 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-6: publish [module 0xc0ffee::m {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::m'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0xc0ffee::m, + indices: [(FunctionHandle, 0)], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move new file mode 100644 index 00000000000..d9e9d880213 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move @@ -0,0 +1,6 @@ +//# publish +module 0xc0ffee::m { + public fun test(): (u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64) { + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/tuple_swap.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/tuple_swap.exp index fc50e5cc59f..d5df893dec6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/tuple_swap.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/tuple_swap.exp @@ -1,34 +1,24 @@ processed 12 tasks - -task 1 'run'. lines 108-108: +task 0 lines 1-106: publish [module 0xc0ffee::m {] +task 1 lines 108-108: run 0xc0ffee::m::test1 return values: 2, 1 - -task 2 'run'. lines 110-110: +task 2 lines 110-110: run 0xc0ffee::m::test2 return values: 30, 40, 20, 10 - -task 3 'run'. lines 112-112: +task 3 lines 112-112: run 0xc0ffee::m::test3 return values: 22, 11 - -task 4 'run'. lines 114-114: +task 4 lines 114-114: run 0xc0ffee::m::test4 return values: { 222 }, { 111 } - -task 5 'run'. lines 116-116: +task 5 lines 116-116: run 0xc0ffee::m::swap5 return values: 258, 147 - -task 6 'run'. lines 118-118: +task 6 lines 118-118: run 0xc0ffee::m::test6 return values: 41, 5 - -task 7 'run'. lines 120-120: +task 7 lines 120-120: run 0xc0ffee::m::test7 return values: 440, 44 - -task 8 'run'. lines 122-122: +task 8 lines 122-122: run 0xc0ffee::m::test8 return values: 8, 80, 80, 8 - -task 9 'run'. lines 124-124: +task 9 lines 124-124: run 0xc0ffee::m::swap9 return values: 23, 51 - -task 10 'run'. lines 126-126: +task 10 lines 126-126: run 0xc0ffee::m::test10 return values: 88, 10 - -task 11 'run'. lines 128-128: +task 11 lines 128-128: run 0xc0ffee::m::swap11 return values: 83, 53 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp new file mode 100644 index 00000000000..a45ccc5a1d0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp @@ -0,0 +1,12 @@ +processed 3 tasks +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test +return values: 0 +task 2 lines 11-17: publish [module 0xc0ffee::n {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::n'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xc0ffee::n, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move new file mode 100644 index 00000000000..f6d36c77246 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move @@ -0,0 +1,17 @@ +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let v: vector>>>> = vector[]; + std::vector::length(&v) + } +} + +//# run 0xc0ffee::m::test + +//# publish +module 0xc0ffee::n { + public fun test(): u64 { + let v: vector>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = vector[]; + std::vector::length(&v) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_popback.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_popback.exp index fc5a4436b29..d7b59bda9d1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_popback.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_popback.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-33: publish [module 0x42::vector {] +task 1 lines 35-35: run 0x42::vector::test_fold +task 2 lines 37-37: run 0x42::vector::test_remove diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/write_ref_dest.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/write_ref_dest.exp index fc5a4436b29..42fedbdaf84 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/write_ref_dest.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/write_ref_dest.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-21: publish [module 0x42::m {] +task 1 lines 23-23: run 0x42::m::test_call +task 2 lines 25-25: run 0x42::m::test_assign diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled new file mode 100644 index 00000000000..5a36b8ac3fa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/evaluation_order/short_circuit_boolean.move` + +//# publish +module 0x42::X { + public fun tester(p0: bool, p1: bool): u64 { + let _v0 = 1 * 2; + if (p0) _v0 = _v0 * 3; + _v0 = _v0 * 5; + if (!p1) _v0 = _v0 * 7; + _v0 + } +} + + +//# run +script { + use 0x42::X; + fun main() { + assert!(X::tester(false, false) == 70, 1); + assert!(X::tester(false, true) == 10, 2); + assert!(X::tester(true, false) == 210, 3); + assert!(X::tester(true, true) == 30, 4); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled.baseline.exp new file mode 100644 index 00000000000..2291f273c2f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/round-trip/short_circuit_boolean.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0x42::X {] +task 1 lines 15-24: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/short_circuit_boolean.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/short_circuit_boolean.exp index 5d92c423f3f..8c3909b6161 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/short_circuit_boolean.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/evaluation_order/short_circuit_boolean.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-9: publish [module 0x42::X {] +task 1 lines 11-20: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/generics/global_invalid.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/generics/global_invalid.exp index 0603cc17545..d9861c55a64 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/generics/global_invalid.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/generics/global_invalid.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish --print-bytecode [module 0x42::m {] Error: compilation errors: error: Expected a struct type. Global storage operations are restricted to struct types declared in the current module. Found: 'T' ┌─ TEMPFILE:4:17 @@ -27,8 +26,7 @@ error: Expected a struct type. Global storage operations are restricted to struc │ Invalid call to MoveFrom. - -task 1 'publish'. lines 10-22: +task 1 lines 10-22: publish --print-bytecode [module 0x41::n {] Error: compilation errors: error: no function named `invalid` found ┌─ TEMPFILE1:14:9 @@ -43,8 +41,7 @@ error: expected a struct with field `f` but found `()` │ ^^^^^^^^^^^ - -task 2 'run'. lines 24-30: +task 2 lines 24-30: run --signers 0x41 [script {] Error: compilation errors: error: unbound module ┌─ TEMPFILE2:26:9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/byte_string.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/byte_string.exp index 6cd67db3f64..ece20a4dee5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/byte_string.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/byte_string.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-9: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/control_exp_associativity.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/control_exp_associativity.exp index c1f87c04a8c..063b77b59b1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/control_exp_associativity.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/control_exp_associativity.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 24-24: +task 0 lines 1-22: publish [module 0x42::M {] +task 1 lines 24-24: run 0x42::M::t return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/expr_binary_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/expr_binary_operators.exp index 6cd67db3f64..7fab01e6e74 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/expr_binary_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/expr_binary_operators.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_address.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_address.exp index 6cd67db3f64..0d791fbd8d4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_address.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_address.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_numbers.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_numbers.exp index 6cd67db3f64..ac5c21d2999 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_numbers.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hex_and_decimal_numbers.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-87: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hexstring.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hexstring.exp index 6cd67db3f64..d9dda685234 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hexstring.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/hexstring.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-13: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/num_literal_underscore.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/num_literal_underscore.exp index 6cd67db3f64..30b2ecf96b2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/num_literal_underscore.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/num_literal_underscore.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-50: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/precedence.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/precedence.exp index 6cd67db3f64..ac548142f91 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/precedence.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/precedence.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/return_not_binary.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/return_not_binary.exp index 7b8e3b69e2e..ba7aa123df6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/return_not_binary.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/return_not_binary.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 18-18: +task 0 lines 4-16: publish [module 0x42::M {] +task 1 lines 18-18: run 0x42::M::t1 --args 0 return values: 0 - -task 2 'run'. lines 20-20: +task 2 lines 20-20: run 0x42::M::t2 --args 0 return values: 0 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled new file mode 100644 index 00000000000..4529a342d7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/byte_string.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/byte_string.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled new file mode 100644 index 00000000000..2559808e896 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/control_exp_associativity.move` + +//# publish +module 0x42::M { + fun t(): u64 { + assert!(1 + 20 == 21, 0); + assert!(true, 0); + assert!(10 == 10, 0); + assert!(0 + 1 == 1, 0); + assert!(0 == 0, 0); + 42 + } +} + + +//# run 0x42::M::t \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled.baseline.exp new file mode 100644 index 00000000000..8e6424352b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/control_exp_associativity.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0x42::M {] +task 1 lines 16-16: run 0x42::M::t +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled new file mode 100644 index 00000000000..05504c93d81 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/expr_binary_operators.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/expr_binary_operators.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled new file mode 100644 index 00000000000..9ab1d6ad5f4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/hex_and_decimal_address.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_address.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled new file mode 100644 index 00000000000..9620514f6af --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/hex_and_decimal_numbers.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hex_and_decimal_numbers.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled new file mode 100644 index 00000000000..7741fe24f6b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/hexstring.move` + +//# run +script { + use 0x1::vector; + fun main() { + let _v0 = vector[1u8, 2u8, 3u8, 4u8]; + let _v1 = 0; + while (!vector::is_empty(&_v0)) { + let _v2 = vector::pop_back(&mut _v0) as u64; + _v1 = _v1 + _v2; + continue + }; + assert!(_v1 == 10, _v1); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled.baseline.exp new file mode 100644 index 00000000000..a132233132c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/hexstring.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-16: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled new file mode 100644 index 00000000000..252dedc67e6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/num_literal_underscore.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/num_literal_underscore.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled new file mode 100644 index 00000000000..5760661737c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/precedence.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/precedence.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled new file mode 100644 index 00000000000..b9128180126 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/more-v1/parser/return_not_binary.move` + +//# publish +module 0x42::M { + struct S { + f: u64, + } + fun t1(p0: &u64): u64 { + *p0 + } + fun t2(p0: &S): &u64 { + &p0.f + } +} + + +//# run 0x42::M::t1 --args 0 + +//# run 0x42::M::t2 --args 0 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled.baseline.exp new file mode 100644 index 00000000000..6a7407fcaab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/more-v1/parser/round-trip/return_not_binary.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-14: publish [module 0x42::M {] +task 1 lines 17-17: run 0x42::M::t1 --args 0 +return values: 0 +task 2 lines 19-19: run 0x42::M::t2 --args 0 +return values: 0 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp new file mode 100644 index 00000000000..0ad395bb169 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-14: publish [module 0xc0ffee::n {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::n'. Got VMError: { + major_status: LOOKUP_FAILED, + sub_status: None, + location: 0xc0ffee::n, + indices: [(FunctionHandle, 1)], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move new file mode 100644 index 00000000000..f6289e48b14 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move @@ -0,0 +1,14 @@ +//# publish +module 0xc0ffee::m { + struct S(u64); + + fun inaccessible() {} +} + +//# publish +module 0xc0ffee::n { + public fun test() { + let f = || 0xc0ffee::m::inaccessible(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp index d19e007de6f..797037db3cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp @@ -1,8 +1,7 @@ processed 2 tasks - -task 0 'publish'. lines 1-27: +task 0 lines 1-27: publish [module 0xc0ffee::m {] Error: compilation errors: - bug: bytecode verification failed with unexpected status code `RECURSIVE_STRUCT_DEFINITION`. This is a compiler bug, consider reporting it. + bug: bytecode verification failed with unexpected status code `RECURSIVE_STRUCT_DEFINITION`: Error message: none ┌─ TEMPFILE:2:1 │ @@ -14,10 +13,11 @@ Error message: none 22 │ │ } 23 │ │ } │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) - -task 1 'run'. lines 29-29: +task 1 lines 29-29: run 0xc0ffee::m::main Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp new file mode 100644 index 00000000000..aa149df67d6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp @@ -0,0 +1,19 @@ +processed 1 task +task 0 lines 1-9: publish [module 0x8675309::M {] +Error: compilation errors: + bug: bytecode verification failed with unexpected status code `LOOP_IN_INSTANTIATION_GRAPH`: +Error message: edges with constructors: [f0#0 --StructInstantiation(StructHandleIndex(0), [TypeParameter(0)])--> f0#0], nodes: [f0#0] + ┌─ TEMPFILE:2:1 + │ +2 │ ╭ module 0x8675309::M { +3 │ │ struct S { f: T } +4 │ │ fun f() { +5 │ │ let ff = || f>(); +6 │ │ ff(); +7 │ │ } +8 │ │ } + │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move new file mode 100644 index 00000000000..80ffd3c5d2a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move @@ -0,0 +1,9 @@ +//# publish +module 0x8675309::M { + struct S { f: T } + + fun f() { + let ff = || f>(); + ff(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp new file mode 100644 index 00000000000..34dfc87a07e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp @@ -0,0 +1,19 @@ +processed 1 task +task 0 lines 1-15: publish [module 0xc0ffee::m {] +Error: compilation errors: + bug: bytecode verification failed with unexpected status code `LOOP_IN_INSTANTIATION_GRAPH`: +Error message: edges with constructors: [f1#0 --Function([Reference(TypeParameter(0))], [], )--> f0#0], nodes: [f1#0, f0#0] + ┌─ TEMPFILE:2:1 + │ + 2 │ ╭ module 0xc0ffee::m { + 3 │ │ public fun foo(): || { + 4 │ │ bar<|&T|> + 5 │ │ } + · │ +12 │ │ } +13 │ │ } + │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move new file mode 100644 index 00000000000..923ee795fcc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move @@ -0,0 +1,15 @@ +//# publish +module 0xc0ffee::m { + public fun foo(): || { + bar<|&T|> + } + + fun bar() { + (foo())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp index 45fc0b41c31..25fbdf414c4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/dynamic.exp @@ -1,12 +1,11 @@ processed 6 tasks - -task 2 'run'. lines 30-30: +task 0 lines 1-26: publish [module 0x42::test {] +task 1 lines 28-28: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 30-30: run --verbose --args @0x1 -- 0x42::test::ok1 return values: true - -task 3 'run'. lines 32-32: +task 3 lines 32-32: run --verbose --signers 0x1 -- 0x42::test::ok2 return values: true - -task 4 'run'. lines 34-34: +task 4 lines 34-34: run --verbose --args @0x1 -- 0x42::test::fail1 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x2)`, major_status: ACCESS_DENIED, @@ -16,8 +15,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(1), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 5 'run'. lines 36-36: +task 5 lines 36-36: run --verbose --signers 0x1 -- 0x42::test::fail2 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x2)`, major_status: ACCESS_DENIED, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp index 041671d6c1d..295f72e0337 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/generic.exp @@ -1,12 +1,11 @@ processed 5 tasks - -task 2 'run'. lines 25-25: +task 0 lines 1-21: publish [module 0x42::test {] +task 1 lines 23-23: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 25-25: run --verbose -- 0x42::test::ok1 return values: true - -task 3 'run'. lines 27-27: +task 3 lines 27-27: run --verbose -- 0x42::test::ok2 return values: true - -task 4 'run'. lines 29-29: +task 4 lines 29-29: run --verbose -- 0x42::test::fail1 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp index 35719677250..7344c9b77fc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/negation.exp @@ -1,12 +1,11 @@ processed 7 tasks - -task 2 'run'. lines 32-32: +task 0 lines 1-28: publish [module 0x42::test {] +task 1 lines 30-30: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 32-32: run --verbose -- 0x42::test::ok1 return values: true - -task 3 'run'. lines 34-34: +task 3 lines 34-34: run --verbose -- 0x42::test::ok2 return values: true - -task 4 'run'. lines 36-36: +task 4 lines 36-36: run --verbose -- 0x42::test::fail1 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -16,8 +15,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(1), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 5 'run'. lines 38-38: +task 5 lines 38-38: run --verbose -- 0x42::test::fail2 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -27,6 +25,5 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(2), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 6 'run'. lines 40-40: +task 6 lines 40-40: run --verbose -- 0x42::test::ok3 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp index 8cfae4bf271..6c20ae9728c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/resource.exp @@ -1,18 +1,15 @@ processed 11 tasks - -task 2 'run'. lines 57-57: +task 0 lines 1-53: publish [module 0x42::test {] +task 1 lines 55-55: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 57-57: run --verbose -- 0x42::test::ok1 return values: true - -task 3 'run'. lines 59-59: +task 3 lines 59-59: run --verbose -- 0x42::test::ok2 return values: true - -task 4 'run'. lines 61-61: +task 4 lines 61-61: run --verbose --signers 0x2 -- 0x42::test::ok3 return values: true - -task 5 'run'. lines 63-63: +task 5 lines 63-63: run --verbose -- 0x42::test::ok4 return values: true - -task 6 'run'. lines 65-65: +task 6 lines 65-65: run --verbose -- 0x42::test::fail1 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -22,8 +19,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(1), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 7 'run'. lines 67-67: +task 7 lines 67-67: run --verbose -- 0x42::test::fail2 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -33,8 +29,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(2), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 8 'run'. lines 69-69: +task 8 lines 69-69: run --verbose -- 0x42::test::fail3 Error: Function execution failed with VMError: { message: not allowed to perform `writes 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -44,8 +39,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(3), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 9 'run'. lines 71-71: +task 9 lines 71-71: run --verbose -- 0x42::test::fail4 Error: Function execution failed with VMError: { message: not allowed to perform `writes 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -55,8 +49,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(4), 2)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 10 'run'. lines 73-73: +task 10 lines 73-73: run --verbose -- 0x42::test::fail5 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled new file mode 100644 index 00000000000..ac48e90f04a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled @@ -0,0 +1,49 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/dynamic.move` + +//# publish +module 0x42::test { + use 0x1::signer; + struct R has drop, key { + value: bool, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to(p0, _v0); + } + fun fail1(p0: address): bool + acquires R + reads R(p0) + { + *&borrow_global(@0x2).value + } + fun fail2(p0: &signer): bool + acquires R + reads R(signer::address_of(p0)) + { + *&borrow_global(@0x2).value + } + fun ok1(p0: address): bool + acquires R + reads R(p0) + { + *&borrow_global(p0).value + } + fun ok2(p0: &signer): bool + acquires R + reads R(signer::address_of(p0)) + { + let _v0 = signer::address_of(p0); + *&borrow_global(_v0).value + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose --args @0x1 -- 0x42::test::ok1 + +//# run --verbose --signers 0x1 -- 0x42::test::ok2 + +//# run --verbose --args @0x1 -- 0x42::test::fail1 + +//# run --verbose --signers 0x1 -- 0x42::test::fail2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp new file mode 100644 index 00000000000..1a5f6e1e21d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/dynamic.decompiled.baseline.exp @@ -0,0 +1,40 @@ +processed 6 tasks +task 0 lines 3-38: publish [module 0x42::test {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:13:15 + │ +13 │ fun fail1(p0: address): bool + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:19:15 + │ +19 │ fun fail2(p0: &signer): bool + │ ^^ + + +task 1 lines 41-41: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 43-43: run --verbose --args @0x1 -- 0x42::test::ok1 +return values: true +task 3 lines 45-45: run --verbose --signers 0x1 -- 0x42::test::ok2 +return values: true +task 4 lines 47-47: run --verbose --args @0x1 -- 0x42::test::fail1 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x2)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 49-49: run --verbose --signers 0x1 -- 0x42::test::fail2 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x2)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled new file mode 100644 index 00000000000..002da2e21b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled @@ -0,0 +1,39 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/generic.move` + +//# publish +module 0x42::test { + struct R has drop, key { + value: T0, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to>(p0, _v0); + } + fun fail1(): bool + acquires R + reads R + { + *&borrow_global>(@0x1).value + } + fun ok1(): bool + acquires R + reads R + { + *&borrow_global>(@0x1).value + } + fun ok2(): bool + acquires R + reads R + { + *&borrow_global>(@0x1).value + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose -- 0x42::test::ok1 + +//# run --verbose -- 0x42::test::ok2 + +//# run --verbose -- 0x42::test::fail1 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp new file mode 100644 index 00000000000..3bcb3987396 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/generic.decompiled.baseline.exp @@ -0,0 +1,17 @@ +processed 5 tasks +task 0 lines 3-30: publish [module 0x42::test {] +task 1 lines 33-33: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 35-35: run --verbose -- 0x42::test::ok1 +return values: true +task 3 lines 37-37: run --verbose -- 0x42::test::ok2 +return values: true +task 4 lines 39-39: run --verbose -- 0x42::test::fail1 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled new file mode 100644 index 00000000000..9f0ceebdd50 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled @@ -0,0 +1,57 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/negation.move` + +//# publish +module 0x42::test { + struct R has drop, key { + value: bool, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to(p0, _v0); + } + fun fail1(): bool + !reads 0x42::*::* + acquires R + { + *&borrow_global(@0x1).value + } + fun fail2(): bool + !reads *(0x1) + acquires R + { + *&borrow_global(@0x1).value + } + fun ok1(): bool + !reads 0x43::*::* + acquires R + reads 0x42::*::* + { + *&borrow_global(@0x1).value + } + fun ok2(): bool + !reads 0x43::*::* + acquires R + writes * + { + *&borrow_global(@0x1).value + } + fun ok3(): bool + !reads *(0x2) + acquires R + { + *&borrow_global(@0x1).value + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose -- 0x42::test::ok1 + +//# run --verbose -- 0x42::test::ok2 + +//# run --verbose -- 0x42::test::fail1 + +//# run --verbose -- 0x42::test::fail2 + +//# run --verbose -- 0x42::test::ok3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp new file mode 100644 index 00000000000..599eb255a4c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/negation.decompiled.baseline.exp @@ -0,0 +1,29 @@ +processed 7 tasks +task 0 lines 3-44: publish [module 0x42::test {] +task 1 lines 47-47: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 49-49: run --verbose -- 0x42::test::ok1 +return values: true +task 3 lines 51-51: run --verbose -- 0x42::test::ok2 +return values: true +task 4 lines 53-53: run --verbose -- 0x42::test::fail1 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 55-55: run --verbose -- 0x42::test::fail2 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 57-57: run --verbose -- 0x42::test::ok3 +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled new file mode 100644 index 00000000000..1ca66d85205 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled @@ -0,0 +1,101 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/resource.move` + +//# publish +module 0x42::test { + struct Other has drop, key { + } + struct R has drop, key { + value: bool, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to(p0, _v0); + } + fun fail1(): bool + acquires R + reads Other + { + !*&borrow_global(@0x1).value + } + fun fail2(): bool + reads Other + { + !exists(@0x1) + } + fun fail3(): bool + acquires R + reads R + writes Other + { + let _v0 = move_from(@0x1); + !*&(&_v0).value + } + fun fail4(): bool + acquires R + reads R + writes Other + { + let _v0 = &mut borrow_global_mut(@0x1).value; + *_v0 = false; + false + } + fun fail5(): bool + acquires R + reads Other + { + fail_no_subsumes() + } + fun fail_no_subsumes(): bool + acquires R + reads R + { + *&borrow_global(@0x1).value + } + fun ok1(): bool + acquires R + reads R + { + *&borrow_global(@0x1).value + } + fun ok2(): bool + reads R + { + exists(@0x1) + } + fun ok3(p0: &signer): bool + writes R + { + let _v0 = R{value: true}; + move_to(p0, _v0); + true + } + fun ok4(): bool + acquires R + writes R + { + let _v0 = &mut borrow_global_mut(@0x1).value; + *_v0 = false; + true + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose -- 0x42::test::ok1 + +//# run --verbose -- 0x42::test::ok2 + +//# run --verbose --signers 0x2 -- 0x42::test::ok3 + +//# run --verbose -- 0x42::test::ok4 + +//# run --verbose -- 0x42::test::fail1 + +//# run --verbose -- 0x42::test::fail2 + +//# run --verbose -- 0x42::test::fail3 + +//# run --verbose -- 0x42::test::fail4 + +//# run --verbose -- 0x42::test::fail5 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp new file mode 100644 index 00000000000..1ff88eb01bc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/resource.decompiled.baseline.exp @@ -0,0 +1,61 @@ +processed 11 tasks +task 0 lines 3-80: publish [module 0x42::test {] +task 1 lines 83-83: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 85-85: run --verbose -- 0x42::test::ok1 +return values: true +task 3 lines 87-87: run --verbose -- 0x42::test::ok2 +return values: true +task 4 lines 89-89: run --verbose --signers 0x2 -- 0x42::test::ok3 +return values: true +task 5 lines 91-91: run --verbose -- 0x42::test::ok4 +return values: true +task 6 lines 93-93: run --verbose -- 0x42::test::fail1 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 95-95: run --verbose -- 0x42::test::fail2 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 97-97: run --verbose -- 0x42::test::fail3 +Error: Function execution failed with VMError: { + message: not allowed to perform `writes 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 99-99: run --verbose -- 0x42::test::fail4 +Error: Function execution failed with VMError: { + message: not allowed to perform `writes 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 101-101: run --verbose -- 0x42::test::fail5 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("test") }), FunctionDefinitionIndex(5), 0)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled new file mode 100644 index 00000000000..4ec5876fc03 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled @@ -0,0 +1,63 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/access_control/wildcard.move` + +//# publish +module 0x42::test { + struct R has drop, key { + value: bool, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to(p0, _v0); + } + fun fail1(): bool + acquires R + reads 0x43::*::* + { + *&borrow_global(@0x1).value + } + fun fail2(): bool + acquires R + reads *(0x2) + { + *&borrow_global(@0x1).value + } + fun ok1(): bool + acquires R + reads 0x42::*::* + { + *&borrow_global(@0x1).value + } + fun ok2(): bool + acquires R + reads 0x42::test::* + { + *&borrow_global(@0x1).value + } + fun ok3(): bool + acquires R + reads 0x42::test::* + { + *&borrow_global(@0x1).value + } + fun ok4(): bool + acquires R + reads *(0x1) + { + *&borrow_global(@0x1).value + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose -- 0x42::test::ok1 + +//# run --verbose -- 0x42::test::ok2 + +//# run --verbose -- 0x42::test::ok3 + +//# run --verbose -- 0x42::test::ok4 + +//# run --verbose -- 0x42::test::fail1 + +//# run --verbose -- 0x42::test::fail2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp new file mode 100644 index 00000000000..80ac63589a2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/round-trip/wildcard.decompiled.baseline.exp @@ -0,0 +1,31 @@ +processed 8 tasks +task 0 lines 3-48: publish [module 0x42::test {] +task 1 lines 51-51: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 53-53: run --verbose -- 0x42::test::ok1 +return values: true +task 3 lines 55-55: run --verbose -- 0x42::test::ok2 +return values: true +task 4 lines 57-57: run --verbose -- 0x42::test::ok3 +return values: true +task 5 lines 59-59: run --verbose -- 0x42::test::ok4 +return values: true +task 6 lines 61-61: run --verbose -- 0x42::test::fail1 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 63-63: run --verbose -- 0x42::test::fail2 +Error: Function execution failed with VMError: { + message: not allowed to perform `reads 0x42::test::R(@0x1)`, + major_status: ACCESS_DENIED, + sub_status: None, + location: 0x42::test, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp index aafc7de64f5..0043e3bf3ab 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/access_control/wildcard.exp @@ -1,18 +1,15 @@ processed 8 tasks - -task 2 'run'. lines 36-36: +task 0 lines 1-32: publish [module 0x42::test {] +task 1 lines 34-34: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 36-36: run --verbose -- 0x42::test::ok1 return values: true - -task 3 'run'. lines 38-38: +task 3 lines 38-38: run --verbose -- 0x42::test::ok2 return values: true - -task 4 'run'. lines 40-40: +task 4 lines 40-40: run --verbose -- 0x42::test::ok3 return values: true - -task 5 'run'. lines 42-42: +task 5 lines 42-42: run --verbose -- 0x42::test::ok4 return values: true - -task 6 'run'. lines 44-44: +task 6 lines 44-44: run --verbose -- 0x42::test::fail1 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, @@ -22,8 +19,7 @@ Error: Function execution failed with VMError: { offsets: [(FunctionDefinitionIndex(1), 1)], exec_state: Some(ExecutionState { stack_trace: [] }), } - -task 7 'run'. lines 46-46: +task 7 lines 46-46: run --verbose -- 0x42::test::fail2 Error: Function execution failed with VMError: { message: not allowed to perform `reads 0x42::test::R(@0x1)`, major_status: ACCESS_DENIED, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.baseline.exp index 2161a50d2b6..8e4c184c6c0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.baseline.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 21-34: +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-34: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(14566554180833181696), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.no-optimize.exp index 6b808b49a2d..6fe00216e23 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.no-optimize.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 21-34: +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-34: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(14566554180833181696), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.opt-extra.exp new file mode 100644 index 00000000000..8e4c184c6c0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.opt-extra.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-34: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(14566554180833181696), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 27)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.optimize.exp index 2161a50d2b6..8e4c184c6c0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/assert_one.optimize.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 21-34: +task 0 lines 1-19: publish [module 0x42::Test {] +task 1 lines 21-34: run [script {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(14566554180833181696), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/bug_14762.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/bug_14762.exp index 5d92c423f3f..a95aa4f875a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/bug_14762.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/bug_14762.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-77: publish [module 0x42::m {] +task 1 lines 79-79: run 0x42::m::test1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/calls_with_freeze.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/calls_with_freeze.exp index e943b63ba97..e535175a82c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/calls_with_freeze.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/calls_with_freeze.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 23-23: +task 0 lines 1-21: publish [module 0x42::m {] +task 1 lines 23-23: run 0x42::m::test return values: 16 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16198.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16198.exp index 5d92c423f3f..023287aeeb9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16198.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16198.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-31: publish [module 0xc0ffee::m {] +task 1 lines 32-32: run 0xc0ffee::m::test --args 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16199.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16199.exp index 5d92c423f3f..e55253d6d6d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16199.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16199.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335.exp index e6b9502c721..4a0b1b528b4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42::Test {] Error: compilation errors: error: cannot pass `&mut || has copy + drop` to a function which expects argument of type `&mut || has drop` ┌─ TEMPFILE:8:11 @@ -9,8 +8,7 @@ Error: compilation errors: │ ^^^^^^ - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run --verbose 0x42::Test::f2 Error: Function execution failed with VMError: { message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::Test doesn't exist, major_status: LINKER_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335_split.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335_split.exp index 5d92c423f3f..69879ce1eb7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335_split.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16335_split.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::Test {] +task 1 lines 16-16: run --verbose 0x42::Test::f3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16363.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16363.exp index 5d92c423f3f..894ae98c497 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16363.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16363.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0x42::foo {] +task 1 lines 14-20: publish [module 0x42::test {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16407.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16407.exp index 6cd67db3f64..f6f2ae998f4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16407.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16407.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: publish [module 0xc0ffee::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16408.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16408.exp index 5d92c423f3f..308d82d3b00 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16408.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16408.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-28: publish [module 0xc0ffee::m {] +task 1 lines 30-30: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp new file mode 100644 index 00000000000..86cbeee9a10 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-8: publish [module 0x66::work {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000066::work'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0x66::work, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move new file mode 100644 index 00000000000..0817077e4e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move @@ -0,0 +1,8 @@ +//# publish +module 0x66::work { + use 0x1::vector; + + public entry fun foo() { + let _: vector<|u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64| has drop> = vector::empty(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16667.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16667.exp index 5d92c423f3f..548f6bb30fe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16667.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16667.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-4: publish [module 0xAA00::M0 {] +task 1 lines 6-17: publish [module 0xAA00::M1 {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16684.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16684.exp index c7a97f1a4c2..269514c4823 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16684.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16684.exp @@ -1,43 +1,31 @@ processed 16 tasks - -task 1 'run'. lines 92-92: +task 0 lines 1-90: publish [module 0xc0ffee::m {] +task 1 lines 92-92: run 0xc0ffee::m::test1a return values: [] - -task 2 'run'. lines 94-94: +task 2 lines 94-94: run 0xc0ffee::m::test1b return values: [] - -task 3 'run'. lines 96-96: +task 3 lines 96-96: run 0xc0ffee::m::test2a return values: [] - -task 4 'run'. lines 98-98: +task 4 lines 98-98: run 0xc0ffee::m::test2b return values: [] - -task 5 'run'. lines 100-100: +task 5 lines 100-100: run 0xc0ffee::m::test3a --type-args u64 return values: [] - -task 6 'run'. lines 102-102: +task 6 lines 102-102: run 0xc0ffee::m::test3b --type-args u16 return values: [] - -task 7 'run'. lines 104-104: +task 7 lines 104-104: run 0xc0ffee::m::test4a --type-args u32 return values: [] - -task 8 'run'. lines 106-106: +task 8 lines 106-106: run 0xc0ffee::m::test4b --type-args u128 return values: [] - -task 9 'run'. lines 108-108: +task 9 lines 108-108: run 0xc0ffee::m::test5 return values: [] - -task 10 'run'. lines 110-110: +task 10 lines 110-110: run 0xc0ffee::m::test6 return values: [42] - -task 12 'run'. lines 114-114: +task 11 lines 112-112: run 0xc0ffee::m::test7 +task 12 lines 114-114: run 0xc0ffee::m::test8 return values: 3 - -task 13 'run'. lines 116-116: +task 13 lines 116-116: run 0xc0ffee::m::test9a return values: [3, 2, 1] - -task 14 'run'. lines 118-118: +task 14 lines 118-118: run 0xc0ffee::m::test9b return values: [3, 2, 1] - -task 15 'run'. lines 120-120: +task 15 lines 120-120: run 0xc0ffee::m::test10 return values: [1, 2, 3, 4] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp new file mode 100644 index 00000000000..3cef6f6445d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp @@ -0,0 +1,544 @@ +processed 1 task +task 0 lines 1-179: publish [module 0x9A2D1C77326B441F3C4D46BA03C92B5DF09D75609AFDF1C491CD4529080A0385::Module0 {] +Error: compilation errors: + warning: Unused value of parameter `var0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var0`), or binding to `_` + ┌─ TEMPFILE:30:27 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var1`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var1`), or binding to `_` + ┌─ TEMPFILE:30:45 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var2`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var2`), or binding to `_` + ┌─ TEMPFILE:30:63 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var3`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var3`), or binding to `_` + ┌─ TEMPFILE:30:81 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var15`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var15`), or binding to `_` + ┌─ TEMPFILE:32:72 + │ +32 │ public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + │ ^^^^^ + +warning: Unused value of parameter `var16`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var16`), or binding to `_` + ┌─ TEMPFILE:32:88 + │ +32 │ public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + │ ^^^^^ + +warning: Unused value of parameter `var17`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var17`), or binding to `_` + ┌─ TEMPFILE:33:43 + │ +33 │ *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + │ ^^^^^ + +warning: Unused value of parameter `var18`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var18`), or binding to `_` + ┌─ TEMPFILE:33:152 + │ +33 │ *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var19` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var19`), or renaming to `_` + ┌─ TEMPFILE:39:25 + │ +39 │ let var19 = *( &( false)); + │ ^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var24` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var24`), or renaming to `_` + ┌─ TEMPFILE:42:17 + │ +42 │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var20` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var20`), or renaming to `_` + ┌─ TEMPFILE:45:17 + │ +45 │ Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var21` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var21`), or renaming to `_` + ┌─ TEMPFILE:45:17 + │ +45 │ Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var38` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var38`), or renaming to `_` + ┌─ TEMPFILE:47:29 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var39` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var39`), or renaming to `_` + ┌─ TEMPFILE:47:29 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var42`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var42`), or binding to `_` + ┌─ TEMPFILE:47:82 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: Unused value of parameter `var43`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var43`), or binding to `_` + ┌─ TEMPFILE:47:95 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: Unused value of parameter `var44`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var44`), or binding to `_` + ┌─ TEMPFILE:47:111 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:47:80 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var36` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var36`), or renaming to `_` + ┌─ TEMPFILE:48:29 + │ +48 │ Enum1::Variant2 {field6: var36, ..} => { /* _block19 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var48`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var48`), or binding to `_` + ┌─ TEMPFILE:49:39 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: Unused value of parameter `var49`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var49`), or binding to `_` + ┌─ TEMPFILE:49:52 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: Unused value of parameter `var50`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var50`), or binding to `_` + ┌─ TEMPFILE:49:68 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:49:37 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var59`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var59`), or binding to `_` + ┌─ TEMPFILE:52:39 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: Unused value of parameter `var60`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var60`), or binding to `_` + ┌─ TEMPFILE:52:52 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: Unused value of parameter `var61`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var61`), or binding to `_` + ┌─ TEMPFILE:52:68 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:52:37 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var67` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var67`), or renaming to `_` + ┌─ TEMPFILE:56:29 + │ +56 │ Enum1::Variant4 {field11: var67, ..} => { /* _block29 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var22` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var22`), or renaming to `_` + ┌─ TEMPFILE:63:17 + │ +63 │ Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var23` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var23`), or renaming to `_` + ┌─ TEMPFILE:63:17 + │ +63 │ Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var70` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var70`), or renaming to `_` + ┌─ TEMPFILE:64:25 + │ +64 │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var69` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var69`), or renaming to `_` + ┌─ TEMPFILE:65:25 + │ +65 │ Enum1::Variant2 {field7: var69, ..} => &mut ( var14), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────' + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 67 │ │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ transfer attempted here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────' conflicting reference used here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ +67 │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ previously mutably borrowed here + │ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ +67 │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ previously mutably borrowed here + │ transfer attempted here + +warning: This assignment/binding to the left-hand-side variable `var77` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var77`), or renaming to `_` + ┌─ TEMPFILE:68:45 + │ +68 │ let var77 = Enum1::Variant2 { field6: ( 1027423549u32 - 15677u32), field7: ( 1027423549u32 - 15677u32)}; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var82` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var82`), or renaming to `_` + ┌─ TEMPFILE:74:17 + │ +74 │ Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var83` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var83`), or renaming to `_` + ┌─ TEMPFILE:74:17 + │ +74 │ Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var88` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var88`), or renaming to `_` + ┌─ TEMPFILE:75:25 + │ +75 │ Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var89` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var89`), or renaming to `_` + ┌─ TEMPFILE:75:25 + │ +75 │ Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var84` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var84`), or renaming to `_` + ┌─ TEMPFILE:78:25 + │ +78 │ Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var85` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var85`), or renaming to `_` + ┌─ TEMPFILE:78:25 + │ +78 │ Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var86` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var86`), or renaming to `_` + ┌─ TEMPFILE:79:25 + │ +79 │ Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var87` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var87`), or renaming to `_` + ┌─ TEMPFILE:79:25 + │ +79 │ Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var78` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var78`), or renaming to `_` + ┌─ TEMPFILE:81:17 + │ +81 │ Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var79` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var79`), or renaming to `_` + ┌─ TEMPFILE:81:17 + │ +81 │ Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var117` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var117`), or renaming to `_` + ┌─ TEMPFILE:82:29 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var121`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var121`), or binding to `_` + ┌─ TEMPFILE:82:87 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^ + +warning: Unused value of parameter `var122`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var122`), or binding to `_` + ┌─ TEMPFILE:82:197 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var141` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var141`), or renaming to `_` + ┌─ TEMPFILE:98:38 + │ + 98 │ let var141 = ( *( &( Struct1 {field2: 157u8, field3: Struct0 (true,true,),})) != + │ ╭──────────────────────────────────────^ + 99 │ │ Struct1 { +100 │ │ field2: ( 100u8 & 47u8), +101 │ │ field3: Struct0 ( + · │ +104 │ │ } +105 │ │ ); + │ ╰─────────────────────────^ + +warning: This assignment/binding to the left-hand-side variable `var143` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var143`), or renaming to `_` + ┌─ TEMPFILE:106:29 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var147`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var147`), or binding to `_` + ┌─ TEMPFILE:106:87 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^ + +warning: Unused value of parameter `var148`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var148`), or binding to `_` + ┌─ TEMPFILE:106:197 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var150` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var150`), or renaming to `_` + ┌─ TEMPFILE:112:41 + │ +112 │ let Struct0(var150, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var153` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var153`), or renaming to `_` + ┌─ TEMPFILE:115:41 + │ +115 │ let Struct0(var153, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var156` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var156`), or renaming to `_` + ┌─ TEMPFILE:118:41 + │ +118 │ let Struct0(var156, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var159` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var159`), or renaming to `_` + ┌─ TEMPFILE:126:41 + │ +126 │ let Struct0(var159, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var162` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var162`), or renaming to `_` + ┌─ TEMPFILE:129:41 + │ +129 │ let Struct0(var162, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var165` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var165`), or renaming to `_` + ┌─ TEMPFILE:132:41 + │ +132 │ let Struct0(var165, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var169`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var169`), or binding to `_` + ┌─ TEMPFILE:140:61 + │ +140 │ match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + │ ^^^^^^ + +warning: Unused value of parameter `var170`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var170`), or binding to `_` + ┌─ TEMPFILE:140:171 + │ +140 │ match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var172` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var172`), or renaming to `_` + ┌─ TEMPFILE:146:41 + │ +146 │ let Struct0(var172, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var175` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var175`), or renaming to `_` + ┌─ TEMPFILE:149:41 + │ +149 │ let Struct0(var175, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var178` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var178`), or renaming to `_` + ┌─ TEMPFILE:152:41 + │ +152 │ let Struct0(var178, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var80` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var80`), or renaming to `_` + ┌─ TEMPFILE:160:17 + │ +160 │ Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var81` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var81`), or renaming to `_` + ┌─ TEMPFILE:160:17 + │ +160 │ Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var181` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var181`), or renaming to `_` + ┌─ TEMPFILE:161:29 + │ +161 │ let Struct0(var181, var182) = var13; + │ ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var182` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var182`), or renaming to `_` + ┌─ TEMPFILE:161:29 + │ +161 │ let Struct0(var181, var182) = var13; + │ ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var183` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var183`), or renaming to `_` + ┌─ TEMPFILE:162:42 + │ +162 │ let var183 = *( &( Enum0::Variant0 { field4: false})); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var184` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var184`), or renaming to `_` + ┌─ TEMPFILE:163:38 + │ +163 │ let var184 = 1867244186u32; + │ ^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var187` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var187`), or renaming to `_` + ┌─ TEMPFILE:164:29 + │ +164 │ let Struct0(.., var187) = var13; + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var190` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var190`), or renaming to `_` + ┌─ TEMPFILE:167:50 + │ +167 │ let var190 = Enum1::Variant2 { field6: ( 2084683531u32 >> 19u8), field7: 2881938354u32}; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 64 │ │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 64 │ │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ │ ------------- previously mutably borrowed here + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move new file mode 100644 index 00000000000..b151c8c5cfa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move @@ -0,0 +1,179 @@ +//# publish +module 0x9A2D1C77326B441F3C4D46BA03C92B5DF09D75609AFDF1C491CD4529080A0385::Module0 { + struct Struct0(bool, bool) has copy, drop ; + struct Struct1 has copy, drop { + field2: u8, + field3: Struct0, + } + enum Enum0 has copy, drop { + Variant0 { + field4: bool, + }, + Variant1 { + field5: | (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop), (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop) | ((u16, bool) ) has copy+drop, + }, + } + enum Enum1 has copy, drop { + Variant2 { + field6: u32, + field7: u32, + }, + Variant3 { + field8: u32, + field9: u32, + }, + Variant4 { + field10: u32, + field11: u32, + }, + } + public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + } + public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + ( 41988u16, false,) + } + } + ) + ); + let var19 = *( &( false)); + let () = ( function1) ( &mut ( var14), + match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + }, + Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + let var35: | bool, Struct1, Enum0 | (u16 ) has copy+drop = match ( Enum1::Variant4 { field10: ( 1560922432u32 | 271770460u32), field11: 1499701105u32}) { + Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + Enum1::Variant2 {field6: var36, ..} => { /* _block19 */ + | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + }, + _ => { + | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + } + }; + + match ( Enum1::Variant4 { field10: 1511514864u32, field11: ( 3357996168u32 << 10u8)}) { + Enum1::Variant4 {field11: var67, ..} => { /* _block29 */ + &mut ( Enum1::Variant2 { field6: 1159191745u32, field7: 2226907110u32}) + }, + _ => &mut ( var14) + }; + &mut ( var14) + }, + Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + Enum1::Variant2 {field7: var69, ..} => &mut ( var14), + _ => { /* _block35 */ + let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + let var77 = Enum1::Variant2 { field6: ( 1027423549u32 - 15677u32), field7: ( 1027423549u32 - 15677u32)}; + &mut ( Enum1::Variant2 { field6: 2560137368u32, field7: 2560137368u32}) + } + } + }, + match ( Enum1::Variant4 { field10: ( ( 2560137368u32 * 6296u32) * 6296u32), field11: ( ( 2560137368u32 * 6296u32) * 6296u32)}) { + Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + &mut ( var14) + }, + Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + }, + Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block48 */ + Struct0 ( + true,true, + ) + }, + Enum0::Variant0 {..} => { /* _block49 */ + Struct0 ( + true,true, + ) + } + }; + let var141 = ( *( &( Struct1 {field2: 157u8, field3: Struct0 (true,true,),})) != + Struct1 { + field2: ( 100u8 & 47u8), + field3: Struct0 ( + true,true, + ), + } + ); + let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block53 */ + let Struct0(var150, ..) = Struct0 ( + true,true, + ); + let Struct0(var153, ..) = Struct0 ( + true,true, + ); + let Struct0(var156, ..) = Struct0 ( + true,true, + ); + Struct0 ( + true,true, + ) + }, + Enum0::Variant0 {..} => { /* _block54 */ + let Struct0(var159, ..) = Struct0 ( + true,true, + ); + let Struct0(var162, ..) = Struct0 ( + true,true, + ); + let Struct0(var165, ..) = Struct0 ( + true,true, + ); + Struct0 ( + true,true, + ) + } + }; + match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block58 */ + let Struct0(var172, ..) = Struct0 ( + true,true, + ); + let Struct0(var175, ..) = Struct0 ( + true,true, + ); + let Struct0(var178, ..) = Struct0 ( + true,true, + ); + &mut ( var14) + }, + Enum0::Variant0 {..} => &mut ( var14) + } + }, + Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + let Struct0(var181, var182) = var13; + let var183 = *( &( Enum0::Variant0 { field4: false})); + let var184 = 1867244186u32; + let Struct0(.., var187) = var13; + match ( *( var12)) { + Enum0::Variant1 {..} => { /* _block62 */ + let var190 = Enum1::Variant2 { field6: ( 2084683531u32 >> 19u8), field7: 2881938354u32}; + &mut ( Enum1::Variant2 { field6: 582746179u32, field7: 2065999912u32}) + }, + Enum0::Variant0 {..} => &mut ( var14) + } + } + }, + &mut ( var14) + ); + 0 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp new file mode 100644 index 00000000000..e425e1438db --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp @@ -0,0 +1,24 @@ +processed 12 tasks +task 0 lines 1-113: publish [module 0xc0ffee::m {] +task 1 lines 115-115: run 0xc0ffee::m::test1 +return values: 44 +task 2 lines 117-117: run 0xc0ffee::m::test2 +return values: 1 +task 3 lines 119-119: run 0xc0ffee::m::test3 +return values: 1 +task 4 lines 121-121: run 0xc0ffee::m::test4 --args 42 +return values: 43 +task 5 lines 123-123: run 0xc0ffee::m::test5 +return values: 10 +task 6 lines 125-125: run 0xc0ffee::m::test6 +return values: 17 +task 7 lines 127-127: run 0xc0ffee::m::test7 +return values: 9 +task 8 lines 129-129: run 0xc0ffee::m::test8 +return values: 6 +task 9 lines 131-131: run 0xc0ffee::m::test9 +return values: 4 +task 10 lines 133-133: run 0xc0ffee::m::test10 +return values: 5 +task 11 lines 135-135: run 0xc0ffee::m::test11 +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move new file mode 100644 index 00000000000..33e281801dc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move @@ -0,0 +1,135 @@ +//# publish +module 0xc0ffee::m { + public fun test1(): u8 { + let x = 1; + let f = |y: u8| { + let x = x + y; // x: 8 + let f = |y: u8| { + let x = y + x; // x: 11 + x + }; + f(3) * { + let f = |y: u8| { + let x = x - y; // x: 4 + x + }; + f(4) + } + }; + f(7) + } + + public fun test2(): u64 { + let x = 1; + let f = || || x; + f()() + } + + public fun test3(): u64 { + let x = 1; + let f = |x| { + (|x| x - 1)(x + 1) + }; + f(x) + } + + public fun test4(x: u64): u64 { + let f = || || { + let x = x + 1; + x + }; + f()() + } + + public fun test5(): u8 { + let x: u8 = 2; + let f = |x: u8| { // shadows outer `x` + let g = || { x + 1 }; // captures the *parameter* `x` + g() + }; + f(7) + x + } + + public fun test6(): u64 { + let x: u64 = 5; + let f = |y: u64| { + let x = y + 1; + let g = || { + let y = x + 1; + y + }; + g() + }; + f(10) + x + } + + public fun test7(): u8 { + let x: u8 = 3; + let f = |x: u8| { // shadows outer `x` + let x = x + 2; // shadows parameter `x` + let g = |y: u8| x + y; // captures second‑shadow `x` + g(4) // (3 + 2) + 4 + }; + f(x) + } + + public fun test8(): u64 { + let x: u64 = 1; + let f = || { + let x = 2; // shadows outermost + let g = || { + let x = 3; // shadows again + x // 3 + }; + g() + x // 3 + 2 + }; + f() + x // 5 + 1 + } + + public fun test9(): u8 { + let x: u8 = 10; + let f = |x: u8| { + let h = |x: u8| x; // yet another shadow + h(x) // returns the parameter `x` + }; + f(4) + (x - 10) // (4) + 0 + } + + public fun test10(): u8 { + let x: u8 = 2; + let f = |y: u8| y + x; // captures the first `x` + let x: u8 = 5; // new shadow of `x` + f(3) + (x - 5) // (3 + 2) + 0 + } + + fun call(f: ||u64): u64 { + f() + } + + public fun test11(): u64 { + let x = 1; + x + call(|| x + 2) + call(|| x - 1) + } +} + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 + +//# run 0xc0ffee::m::test4 --args 42 + +//# run 0xc0ffee::m::test5 + +//# run 0xc0ffee::m::test6 + +//# run 0xc0ffee::m::test7 + +//# run 0xc0ffee::m::test8 + +//# run 0xc0ffee::m::test9 + +//# run 0xc0ffee::m::test10 + +//# run 0xc0ffee::m::test11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/calculator.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/calculator.exp index fe4bf70a120..9af6e7d6bd6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/calculator.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/calculator.exp @@ -1,4 +1,10 @@ processed 8 tasks - -task 7 'run'. lines 90-90: +task 0 lines 8-76: publish [module 0x66::calculator {] +task 1 lines 78-78: run 0x66::calculator::init_module --signers 0x66 +task 2 lines 80-80: run 0x66::calculator::number --signers 0x66 --args 10 +task 3 lines 82-82: run 0x66::calculator::add --signers 0x66 +task 4 lines 84-84: run 0x66::calculator::number --signers 0x66 --args 20 +task 5 lines 86-86: run 0x66::calculator::sub --signers 0x66 +task 6 lines 88-88: run 0x66::calculator::number --signers 0x66 --args 5 +task 7 lines 90-90: run 0x66::calculator::view --signers 0x66 return values: 25 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing.exp index 1898c113db6..942c87aa821 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing.exp @@ -1,10 +1,8 @@ processed 4 tasks - -task 1 'run'. lines 27-27: +task 0 lines 1-25: publish [module 0x42::test {] +task 1 lines 27-27: run 0x42::test::one_captured --args 3 return values: 5 - -task 2 'run'. lines 29-29: +task 2 lines 29-29: run 0x42::test::two_captured --args 3 2u8 return values: 8 - -task 3 'run'. lines 31-31: +task 3 lines 31-31: run 0x42::test::struct_captured --args 3 return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing_generic.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing_generic.exp index be2cff5383d..4c1442e1545 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing_generic.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/capturing_generic.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 21-21: +task 0 lines 1-19: publish [module 0x42::test {] +task 1 lines 21-21: run 0x42::test::test_u64 --args 3 return values: false - -task 2 'run'. lines 23-23: +task 2 lines 23-23: run 0x42::test::test_S --args 2 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp new file mode 100644 index 00000000000..bb6e43ee54c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 1-20: publish [module 0xc0ffee::m {] +task 1 lines 22-22: run 0xc0ffee::m::init --signers 0xc0ffee +task 2 lines 24-31: run --signers 0xc0ffee [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move new file mode 100644 index 00000000000..745d09065c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move @@ -0,0 +1,31 @@ +//# publish +module 0xc0ffee::m { + public fun identity(t: T): T { + t + } + + struct Wrapper has copy, key, drop { + value: T, + } + + public fun init(s: &signer) { + let f: |u64|u64 has copy + store + drop = identity; + move_to(s, Wrapper { value: f }); + } + + public fun compare(other: |u64|u64 has copy + store + drop, s: &signer): bool { + let this = Wrapper<|u64|u64 has copy + store + drop>[std::signer::address_of(s)].value; + this == other + } +} + +//# run 0xc0ffee::m::init --signers 0xc0ffee + +//# run --signers 0xc0ffee +script { + fun main(s: &signer) { + // compare resolved and unresolved closure + let result = 0xc0ffee::m::compare(0xc0ffee::m::identity, s); + assert!(result); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_mask.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_mask.exp index e5496044fab..210ef73dd40 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_mask.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_mask.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 23-23: +task 0 lines 1-21: publish [module 0x42::test {] +task 1 lines 23-23: run 0x42::test::run return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closures_in_enums.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closures_in_enums.exp index b134af1aea2..beb975fc06c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closures_in_enums.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closures_in_enums.exp @@ -1 +1,6 @@ processed 5 tasks +task 0 lines 1-110: publish [module 0xc0ffee::m {] +task 1 lines 112-112: run 0xc0ffee::m::test_1 +task 2 lines 114-114: run 0xc0ffee::m::test_2 +task 3 lines 116-116: run 0xc0ffee::m::test_3 +task 4 lines 118-118: run 0xc0ffee::m::test_4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp new file mode 100644 index 00000000000..78146ab4508 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-23: publish [module 0xc0ffee::n {] +task 2 lines 25-25: run 0xc0ffee::n::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move new file mode 100644 index 00000000000..68333b91105 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move @@ -0,0 +1,25 @@ +//# publish +module 0xc0ffee::m { + struct Wrapper(u64); + + public fun apply(f: |Wrapper|u64): u64 { + let w = Wrapper(42); + f(w) + } + + public fun unwrap_maker(): |Wrapper|u64 { + |Wrapper(x)| x + } +} + +//# publish +module 0xc0ffee::n { + use 0xc0ffee::m::apply; + + public fun test(): u64 { + let unwrap = 0xc0ffee::m::unwrap_maker(); + apply(unwrap) + } +} + +//# run 0xc0ffee::n::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/extensive_capturing.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/extensive_capturing.exp index 5d92c423f3f..511a5a8cd09 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/extensive_capturing.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/extensive_capturing.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-35: publish [module 0xc0ffee::m {] +task 1 lines 37-37: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/field_access_closure.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/field_access_closure.exp index a7c109f26cf..61907a3dc67 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/field_access_closure.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/field_access_closure.exp @@ -1,10 +1,8 @@ processed 4 tasks - -task 1 'run'. lines 31-31: +task 0 lines 1-29: publish [module 0xc0ffee::m {] +task 1 lines 31-31: run 0xc0ffee::m::test1 return values: 42 - -task 2 'run'. lines 33-33: +task 2 lines 33-33: run 0xc0ffee::m::test2 return values: 87 - -task 3 'run'. lines 35-35: +task 3 lines 35-35: run 0xc0ffee::m::test3 return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/frame_cache.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/frame_cache.exp index 5753d641da1..f01aa433db6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/frame_cache.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/frame_cache.exp @@ -1,7 +1,10 @@ processed 7 tasks - -task 5 'run'. lines 47-47: +task 0 lines 1-4: publish [module 0x42::dummy {] +task 1 lines 6-19: publish [module 0x42::foo {] +task 2 lines 21-33: publish [module 0x42::bar {] +task 3 lines 35-43: publish [module 0x42::poc {] +task 4 lines 45-45: run 0x42::poc::run --signers 0x42 +task 5 lines 47-47: run 0x42::bar::dummy_bar_exists --signers 0x42 return values: true - -task 6 'run'. lines 49-49: +task 6 lines 49-49: run 0x42::foo::foo_exists --signers 0x42 --type-args 0x42::dummy::Dummy return values: false diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fun_refs.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fun_refs.exp index d8f91a2bb35..8cdd93574a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fun_refs.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fun_refs.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 29-29: +task 0 lines 1-27: publish [module 0x42::test {] +task 1 lines 29-29: run 0x42::test::ref return values: 10 - -task 2 'run'. lines 31-31: +task 2 lines 31-31: run 0x42::test::ref_mut return values: 49 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/func_ref_param.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/func_ref_param.exp index 5d92c423f3f..87c2aad2512 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/func_ref_param.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/func_ref_param.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-9: publish [module 0x77::m {] +task 1 lines 11-11: run 0x77::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp index 4cc272d947b..8c7e57eace5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp @@ -1,7 +1,17 @@ -processed 4 tasks - -task 2 'run'. lines 72-72: +processed 13 tasks +task 0 lines 1-23: publish [module 0x42::mod2 {] +task 1 lines 25-70: publish [module 0x42::mod3 {] +task 2 lines 72-91: publish [module 0x42::mod4 {] +task 3 lines 93-112: publish [module 0x42::mod5 {] +task 4 lines 114-160: publish [module 0x42::mod6 {] +task 5 lines 162-162: run 0x42::mod3::test_items --signers 0x42 --args true return values: true - -task 3 'run'. lines 74-74: +task 6 lines 164-164: run 0x42::mod3::test_items --signers 0x42 --args false return values: true +task 7 lines 166-166: run 0x42::mod4::initialize --signers 0x42 +task 8 lines 168-168: run 0x42::mod4::check_exists --signers 0x42 +task 9 lines 170-170: run 0x42::mod5::initialize --signers 0x42 +task 10 lines 172-172: run 0x42::mod5::check_exists --signers 0x42 +task 11 lines 174-174: run 0x42::mod6::initialize --signers 0x42 +task 12 lines 176-176: run 0x42::mod6::compute --signers 0x42 +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move index b44d4f20e4c..2cb93dc37e8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move @@ -69,6 +69,108 @@ module 0x42::mod3 { } } +//# publish +module 0x42::mod4 { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(ref: &u64, _mut_ref: &mut u8): &u64 { + ref + } + + fun initialize(acc: &signer) { + move_to>(acc, Wrapper { fv: 0x42::mod4::test}); + } + + fun check_exists(_acc: &signer) { + let exists = exists>(@0x42); + assert!(exists, 404); + } +} + +//# publish +module 0x42::mod5 { + struct VecWrapper has key { + fvs: vector + } + + #[persistent] + fun test(ref: &u64, _mut_ref: &mut u8): &u64 { + ref + } + + fun initialize(acc: &signer) { + move_to>(acc, VecWrapper { fvs: vector[0x42::mod5::test]}); + } + + fun check_exists(_acc: &signer) { + let exists = exists>(@0x42); + assert!(exists, 404); + } +} + +//# publish +module 0x42::mod6 { + struct VecWrapper has key { + fvs: vector + } + + #[persistent] + fun test1(x: &mut u8) { + *x = *x + 1; + } + + #[persistent] + fun test2(x: &mut u8) { + *x = *x + 2; + } + + #[persistent] + fun test3(x: &mut u8) { + *x = *x + 3; + } + + fun initialize(acc: &signer) { + let fvs = vector[ + 0x42::mod6::test1, + 0x42::mod6::test2, + 0x42::mod6::test3, + ]; + move_to>(acc, VecWrapper { fvs }); + } + + fun compute(_acc: &signer): u8 { + let do_not_exist = !exists>(@0x42) + && !exists>(@0x42); + assert!(do_not_exist, 404); + + let wrapper = &borrow_global>(@0x42).fvs; + let x = 0; + + let i = 0; + while (i < 3) { + let f = std::vector::borrow(wrapper, i); + (*f)(&mut x); + i = i + 1; + }; + x + } +} + //# run 0x42::mod3::test_items --signers 0x42 --args true //# run 0x42::mod3::test_items --signers 0x42 --args false + +//# run 0x42::mod4::initialize --signers 0x42 + +//# run 0x42::mod4::check_exists --signers 0x42 + +//# run 0x42::mod5::initialize --signers 0x42 + +//# run 0x42::mod5::check_exists --signers 0x42 + +//# run 0x42::mod6::initialize --signers 0x42 + +//# run 0x42::mod6::compute --signers 0x42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp new file mode 100644 index 00000000000..685c2227c41 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp @@ -0,0 +1,5 @@ +processed 4 tasks +task 0 lines 1-78: publish [module 0x66::fv_enum_basic {] +task 1 lines 80-80: run 0x66::fv_enum_basic::call_square --args 7 +task 2 lines 82-82: run 0x66::fv_enum_basic::test_enum_in_another_enum --signers 0x66 +task 3 lines 84-84: run 0x66::fv_enum_basic::test_fun_vec --signers 0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move new file mode 100644 index 00000000000..c235583b528 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move @@ -0,0 +1,84 @@ +//# publish +module 0x66::fv_enum_basic { + use std::signer; + enum Action has drop { + Noop, + Call(|u64|u64), + } + + fun square(x: u64): u64 { x * x } + + fun call_square(x: u64) { + let act = Action::Call(square); + let v = match (act) { + Action::Call(f) => f(x), + _ => 0 + }; + assert!(v == 49); + } + + enum Mapper has key { + Id(|T|R has copy + store), + Twice(Version), + } + + #[persistent] + fun add_k_persistent(x: u64, k: u64): u64 { x + k } + + enum Version has copy,store { + V1 { v1: |T|R has copy + store }, + } + + fun test_enum_in_another_enum(s: &signer) { + let k = 3; + let add_k: |u64|u64 has copy + store = |x: u64| add_k_persistent(x, k); + let v1 = Version::V1 { v1: add_k }; + move_to(s, Mapper::Twice(v1)); + let m = borrow_global>(signer::address_of(s)); + let v = match (m) { + Mapper::Twice(v1) => (v1.v1)((v1.v1)(10)), + Mapper::Id(f) => (*f)(10), + }; + assert!(v == 16, 99); + } + + #[persistent] + fun add_k_persistent_ref(x: &mut u64, k: u64): u64 { *x = *x + 1; *x + k } + + enum FunVec has key { + V1 { v1: vector<|&mut T|T has copy + store> }, + V2 { v0: u64, v1: vector<|&mut T|T has copy + store> }, + } + + fun test_fun_vec(s: &signer) { + use std::vector; + let k = 3; + let add_k: |&mut u64|u64 has copy + store + drop = |x: &mut u64| add_k_persistent_ref(x, k); + let v1 = FunVec::V1 { v1: vector[add_k, add_k] }; + move_to(s, v1); + let m = move_from>(signer::address_of(s)); + match (m) { + FunVec::V1 { v1 } => { + let add = vector::pop_back(&mut v1); + let v = 3; + let x = add(&mut v); + assert!(v == 4, 0); + assert!(x == 7, 1); + vector::push_back(&mut v1, add); + let m = FunVec::V2 { v0: 10, v1 }; + move_to(s, m); + } + FunVec::V2 { v0: _, v1 } => { + vector::destroy_empty(v1); + assert!(false, 2); + } + }; + } + +} + +//# run 0x66::fv_enum_basic::call_square --args 7 + +//# run 0x66::fv_enum_basic::test_enum_in_another_enum --signers 0x66 + +//# run 0x66::fv_enum_basic::test_fun_vec --signers 0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/many_arguments.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/many_arguments.exp index 3e23e3cdc97..feea74257f5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/many_arguments.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/many_arguments.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 34-34: +task 0 lines 1-33: publish [module 0xc0ffee::m {] +task 1 lines 34-34: run 0xc0ffee::m::test return values: 2145 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp index 1bdb2c78fef..005ca4e2e7b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp @@ -1,7 +1,23 @@ -processed 4 tasks - -task 1 'run'. lines 14-14: -return values: false - -task 3 'run'. lines 27-27: +processed 7 tasks +task 0 lines 1-29: publish [module 0xc0ffee::m {] +task 1 lines 31-31: run 0xc0ffee::m::test1 +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(453), + location: 0x1::bcs, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 2 lines 33-33: run 0xc0ffee::m::test2 +task 3 lines 35-35: run 0xc0ffee::m::test3 +task 4 lines 37-46: publish [module 0xc0ffee::n {] +task 5 lines 48-48: run 0xc0ffee::n::test --args 42 return values: 42 +task 6 lines 50-59: publish [module 0xc0ffee::o {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::o'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xc0ffee::o, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move index cc7985166b1..97e0b9219a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move @@ -2,22 +2,43 @@ module 0xc0ffee::m { use std::bcs; - public fun test(): bool { + public fun test1(): bool { let x = 1; let y = 2; let f: || u64 has drop = || {x + y + 1}; - let g: || u64 has drop = || {x + y + 1}; - bcs::to_bytes(&f) == bcs::to_bytes(&g) + // Serialization fails! + let _ = bcs::to_bytes(&f); + true + } + + public fun foo() {} + + #[persistent] + fun bar() {} + + public fun test2() { + let f: || has drop = foo; + let b: || has drop = bar; + assert!(bcs::to_bytes(&f) != bcs::to_bytes(&b), 1); + } + + public fun test3() { + let f: || has drop = foo; + assert!(bcs::to_bytes(&f) == bcs::to_bytes(&f), 2); } } -//# run 0xc0ffee::m::test +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 //# publish module 0xc0ffee::n { public fun test(x: u64): u64 { - let f = || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || |x| x; - let f1 = |x| f()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(x); + let f = || || || || || || || || || || |x| x; + let f1 = |x| f()()()()()()()()()()(x); let f2 = |f| f(x); let f3 = |f1, f2| f1(f2); f3(f2, f1) @@ -25,3 +46,14 @@ module 0xc0ffee::n { } //# run 0xc0ffee::n::test --args 42 + +//# publish +module 0xc0ffee::o { + public fun test(x: u64): u64 { + let f = || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || |x| x; + let f1 = |x| f()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(x); + let f2 = |f| f(x); + let f3 = |f1, f2| f1(f2); + f3(f2, f1) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/more_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/more_nested.exp index fc5a4436b29..4903df7e67b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/more_nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/more_nested.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-44: publish [module 0xc0ffee::n {] +task 1 lines 46-46: run 0xc0ffee::n::test_nested_functions +task 2 lines 48-48: run 0xc0ffee::n::test_composed_captures diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/mut_ref_downgrade.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/mut_ref_downgrade.exp index 58985a31972..b761e54db42 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/mut_ref_downgrade.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/mut_ref_downgrade.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-24: +task 0 lines 1-24: publish [module 0xc0ffee::m {] Error: compilation errors: error: cannot pass `&mut ||u64 has copy + drop` to a function which expects argument of type `&mut ||u64 has drop` ┌─ TEMPFILE:14:30 @@ -9,8 +8,7 @@ Error: compilation errors: │ ^^^^^^ - -task 1 'run'. lines 26-26: +task 1 lines 26-26: run 0xc0ffee::m::foo Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/nested.exp index a418de68c70..958cf99ca32 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/nested.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0x42::test {] +task 1 lines 17-17: run 0x42::test::nested --args 3 return values: 4 - -task 2 'run'. lines 19-19: +task 2 lines 19-19: run 0x42::test::nested_capture --args 4 return values: 5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/persistent.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/persistent.exp index fc5a4436b29..e75038ad83b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/persistent.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/persistent.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-20: publish [module 0x66::test {] +task 1 lines 22-22: run 0x66::test::store --signers 0x66 +task 2 lines 24-24: run 0x66::test::exec --signers 0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/protected_storage.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/protected_storage.exp index 5ab0ff58358..23e52e834dd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/protected_storage.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/protected_storage.exp @@ -1,10 +1,10 @@ processed 6 tasks - -task 3 'run'. lines 53-53: +task 0 lines 11-30: publish [module 0x66::protected {] +task 1 lines 32-49: publish [module 0x66::app {] +task 2 lines 51-51: run 0x66::app::init_module --signers 0x66 +task 3 lines 53-53: run 0x66::app::increment --signers 0x66 return values: 0 - -task 4 'run'. lines 55-55: +task 4 lines 55-55: run 0x66::app::increment --signers 0x66 return values: 1 - -task 5 'run'. lines 57-57: +task 5 lines 57-57: run 0x66::app::view --signers 0x66 return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.baseline.exp index 8798dc260e1..540b24248c4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.baseline.exp @@ -1,9 +1,10 @@ processed 5 tasks - -task 3 'run'. lines 45-45: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-40: publish [module 0x42::caller {] +task 2 lines 43-43: run 0x42::caller::init --signers 0x42 +task 3 lines 45-45: run 0x42::caller::callback_ok return values: true - -task 4 'run'. lines 47-47: +task 4 lines 47-47: run 0x42::caller::callback_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::caller::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.no-optimize.exp index cbe15ba7a0a..d030ed222db 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.no-optimize.exp @@ -1,9 +1,10 @@ processed 5 tasks - -task 3 'run'. lines 45-45: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-40: publish [module 0x42::caller {] +task 2 lines 43-43: run 0x42::caller::init --signers 0x42 +task 3 lines 45-45: run 0x42::caller::callback_ok return values: true - -task 4 'run'. lines 47-47: +task 4 lines 47-47: run 0x42::caller::callback_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::caller::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.opt-extra.exp new file mode 100644 index 00000000000..0c83fe53f4b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.opt-extra.exp @@ -0,0 +1,16 @@ +processed 5 tasks +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-40: publish [module 0x42::caller {] +task 2 lines 43-43: run 0x42::caller::init --signers 0x42 +task 3 lines 45-45: run 0x42::caller::callback_ok +return values: true +task 4 lines 47-47: run 0x42::caller::callback_fails --verbose +Error: Function execution failed with VMError: { + message: Resource `0x42::caller::R` cannot be accessed because of active reentrancy of defining module., + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::caller, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 3)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("caller") }), FunctionDefinitionIndex(1), 5)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.optimize.exp index 8798dc260e1..540b24248c4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy.optimize.exp @@ -1,9 +1,10 @@ processed 5 tasks - -task 3 'run'. lines 45-45: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-40: publish [module 0x42::caller {] +task 2 lines 43-43: run 0x42::caller::init --signers 0x42 +task 3 lines 45-45: run 0x42::caller::callback_ok return values: true - -task 4 'run'. lines 47-47: +task 4 lines 47-47: run 0x42::caller::callback_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::caller::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.baseline.exp index 1320ad39c85..8aacb08ff68 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.baseline.exp @@ -1,6 +1,7 @@ processed 3 tasks - -task 2 'run'. lines 20-20: +task 0 lines 1-16: publish [module 0x42::tests {] +task 1 lines 18-18: run 0x42::tests::init --signers 0x42 +task 2 lines 20-20: run 0x42::tests::local_access_via_lambda_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::tests::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.no-optimize.exp index e6f85ec88cb..d6c5737dd47 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.no-optimize.exp @@ -1,6 +1,7 @@ processed 3 tasks - -task 2 'run'. lines 20-20: +task 0 lines 1-16: publish [module 0x42::tests {] +task 1 lines 18-18: run 0x42::tests::init --signers 0x42 +task 2 lines 20-20: run 0x42::tests::local_access_via_lambda_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::tests::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.opt-extra.exp new file mode 100644 index 00000000000..8aacb08ff68 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.opt-extra.exp @@ -0,0 +1,13 @@ +processed 3 tasks +task 0 lines 1-16: publish [module 0x42::tests {] +task 1 lines 18-18: run 0x42::tests::init --signers 0x42 +task 2 lines 20-20: run 0x42::tests::local_access_via_lambda_fails --verbose +Error: Function execution failed with VMError: { + message: Resource `0x42::tests::R` cannot be accessed because of active reentrancy of defining module., + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::tests, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("tests") }), FunctionDefinitionIndex(1), 4)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.optimize.exp index 1320ad39c85..8aacb08ff68 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_local.optimize.exp @@ -1,6 +1,7 @@ processed 3 tasks - -task 2 'run'. lines 20-20: +task 0 lines 1-16: publish [module 0x42::tests {] +task 1 lines 18-18: run 0x42::tests::init --signers 0x42 +task 2 lines 20-20: run 0x42::tests::local_access_via_lambda_fails --verbose Error: Function execution failed with VMError: { message: Resource `0x42::tests::R` cannot be accessed because of active reentrancy of defining module., major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.baseline.exp index 66bcf2d0ff7..fc8dcb5ad3e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.baseline.exp @@ -1,6 +1,8 @@ processed 4 tasks - -task 3 'run'. lines 37-37: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-32: publish [module 0x42::caller {] +task 2 lines 35-35: run 0x42::caller::init --signers 0x42 +task 3 lines 37-37: run 0x42::caller::callback_not_ok --verbose Error: Function execution failed with VMError: { message: Reentrancy disallowed: reentering `0000000000000000000000000000000000000000000000000000000000000042::caller` via function `do_something` (module lock is active), major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.no-optimize.exp index 66bcf2d0ff7..fc8dcb5ad3e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.no-optimize.exp @@ -1,6 +1,8 @@ processed 4 tasks - -task 3 'run'. lines 37-37: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-32: publish [module 0x42::caller {] +task 2 lines 35-35: run 0x42::caller::init --signers 0x42 +task 3 lines 37-37: run 0x42::caller::callback_not_ok --verbose Error: Function execution failed with VMError: { message: Reentrancy disallowed: reentering `0000000000000000000000000000000000000000000000000000000000000042::caller` via function `do_something` (module lock is active), major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.opt-extra.exp new file mode 100644 index 00000000000..fc8dcb5ad3e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.opt-extra.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-32: publish [module 0x42::caller {] +task 2 lines 35-35: run 0x42::caller::init --signers 0x42 +task 3 lines 37-37: run 0x42::caller::callback_not_ok --verbose +Error: Function execution failed with VMError: { + message: Reentrancy disallowed: reentering `0000000000000000000000000000000000000000000000000000000000000042::caller` via function `do_something` (module lock is active), + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::caller, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.optimize.exp index 66bcf2d0ff7..fc8dcb5ad3e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_module_lock.optimize.exp @@ -1,6 +1,8 @@ processed 4 tasks - -task 3 'run'. lines 37-37: +task 0 lines 1-6: publish [module 0x42::callee {] +task 1 lines 8-32: publish [module 0x42::caller {] +task 2 lines 35-35: run 0x42::caller::init --signers 0x42 +task 3 lines 37-37: run 0x42::caller::callback_not_ok --verbose Error: Function execution failed with VMError: { message: Reentrancy disallowed: reentering `0000000000000000000000000000000000000000000000000000000000000042::caller` via function `do_something` (module lock is active), major_status: RUNTIME_DISPATCH_ERROR, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.baseline.exp index b475ed25a2e..e764b20e167 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.baseline.exp @@ -1,6 +1,9 @@ processed 8 tasks - -task 4 'run'. lines 74-76: +task 0 lines 1-17: publish [module 0x42::worker1 {] +task 1 lines 19-36: publish [module 0x42::worker2 {] +task 2 lines 38-69: publish [module 0x42::tests {] +task 3 lines 71-73: run 0x42::tests::init --signers 0x42 [// task 4] +task 4 lines 74-76: run 0x42::tests::direct_failure [// task 5] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -8,8 +11,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 1)], } - -task 5 'run'. lines 77-79: +task 5 lines 77-79: run 0x42::tests::worker1_failure [// task 6] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -17,8 +19,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 6 'run'. lines 80-82: +task 6 lines 80-82: run 0x42::tests::worker2_failure [// task 7] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -26,6 +27,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 7 'run'. lines 83-83: +task 7 lines 83-83: run 0x42::tests::worker2_ok return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.no-optimize.exp index c5e56af3d28..702e2937e6a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.no-optimize.exp @@ -1,6 +1,9 @@ processed 8 tasks - -task 4 'run'. lines 74-76: +task 0 lines 1-17: publish [module 0x42::worker1 {] +task 1 lines 19-36: publish [module 0x42::worker2 {] +task 2 lines 38-69: publish [module 0x42::tests {] +task 3 lines 71-73: run 0x42::tests::init --signers 0x42 [// task 4] +task 4 lines 74-76: run 0x42::tests::direct_failure [// task 5] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -8,8 +11,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 2)], } - -task 5 'run'. lines 77-79: +task 5 lines 77-79: run 0x42::tests::worker1_failure [// task 6] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -17,8 +19,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 6 'run'. lines 80-82: +task 6 lines 80-82: run 0x42::tests::worker2_failure [// task 7] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -26,6 +27,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 7 'run'. lines 83-83: +task 7 lines 83-83: run 0x42::tests::worker2_ok return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.opt-extra.exp new file mode 100644 index 00000000000..e764b20e167 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.opt-extra.exp @@ -0,0 +1,31 @@ +processed 8 tasks +task 0 lines 1-17: publish [module 0x42::worker1 {] +task 1 lines 19-36: publish [module 0x42::worker2 {] +task 2 lines 38-69: publish [module 0x42::tests {] +task 3 lines 71-73: run 0x42::tests::init --signers 0x42 [// task 4] +task 4 lines 74-76: run 0x42::tests::direct_failure [// task 5] +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::tests, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 1)], +} +task 5 lines 77-79: run 0x42::tests::worker1_failure [// task 6] +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::worker1, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} +task 6 lines 80-82: run 0x42::tests::worker2_failure [// task 7] +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::worker2, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} +task 7 lines 83-83: run 0x42::tests::worker2_ok +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.optimize.exp index b475ed25a2e..e764b20e167 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/reentrancy_nested.optimize.exp @@ -1,6 +1,9 @@ processed 8 tasks - -task 4 'run'. lines 74-76: +task 0 lines 1-17: publish [module 0x42::worker1 {] +task 1 lines 19-36: publish [module 0x42::worker2 {] +task 2 lines 38-69: publish [module 0x42::tests {] +task 3 lines 71-73: run 0x42::tests::init --signers 0x42 [// task 4] +task 4 lines 74-76: run 0x42::tests::direct_failure [// task 5] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -8,8 +11,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(5), 1)], } - -task 5 'run'. lines 77-79: +task 5 lines 77-79: run 0x42::tests::worker1_failure [// task 6] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -17,8 +19,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 6 'run'. lines 80-82: +task 6 lines 80-82: run 0x42::tests::worker2_failure [// task 7] Error: Function execution failed with VMError: { major_status: RUNTIME_DISPATCH_ERROR, sub_status: None, @@ -26,6 +27,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(1), 1)], } - -task 7 'run'. lines 83-83: +task 7 lines 83-83: run 0x42::tests::worker2_ok return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/registry.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/registry.exp index 2301000e50a..598337144c9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/registry.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/registry.exp @@ -1 +1,7 @@ processed 6 tasks +task 0 lines 1-12: publish [module 0x66::registry {] +task 1 lines 14-41: publish [module 0x66::delayed_work {] +task 2 lines 43-43: run 0x66::delayed_work::initialize --signers 0x66 +task 3 lines 45-45: run 0x66::delayed_work::add --signers 0x66 --args 5 +task 4 lines 47-47: run 0x66::delayed_work::add --signers 0x66 --args 7 +task 5 lines 49-49: run 0x66::delayed_work::eval --signers 0x66 --args 3 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/resolve_from_storage.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/resolve_from_storage.exp index fc5a4436b29..8b8eb545f05 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/resolve_from_storage.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/resolve_from_storage.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-19: publish [module 0x66::test {] +task 1 lines 21-21: run 0x66::test::init --signers 0x66 +task 2 lines 23-23: run 0x66::test::call --args @0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled new file mode 100644 index 00000000000..094ee0ff99f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled @@ -0,0 +1,101 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16198.move` + +//# publish +module 0xc0ffee::m { + struct Func has copy, drop { + _0: ||(||(u64)) has copy + drop, + } + fun forty_two(): u64 { + 42 + } + public fun test(p0: u64) { + let _v0: ||(||(u64) has drop) has copy + drop = || lambda__2__test(p0); + let _v1 = _v0(); + assert!(_v1() == 42, 14566554180833181696); + let _v2 = forty_two(); + let _v3: ||(||(u64) has drop) has copy + drop = || lambda__4__test(_v2); + let _v4 = _v3(); + assert!(_v4() == 42, 14566554180833181696); + let _v5: ||(||(||(u64) has drop)) has copy + drop = || lambda__7__test(p0); + let _v6 = _v5(); + let _v7 = _v6(); + assert!(_v7() == 42, 14566554180833181696); + let _v8: ||(||(||(||(u64) has drop))) has copy + drop = || lambda__12__test(p0, _v2); + let _v9 = _v8(); + let _v10 = _v9(); + let _v11 = _v10(); + assert!(_v11() == 84, 14566554180833181696); + let _v12: ||(||(||(||(u64) has drop))) has copy + drop = || lambda__17__test(p0, _v2); + let _v13 = _v12(); + let _v14 = _v13(); + let _v15 = _v14(); + assert!(_v15() == 84, 14566554180833181696); + let Func{_0: _v16} = Func{_0: || lambda__19__test(p0)}; + let _v17 = _v16(); + assert!(_v17() == 42, 14566554180833181696); + } + fun lambda__2__test(p0: u64): ||(u64) has drop { + || lambda__1__test(p0) + } + fun lambda__4__test(p0: u64): ||(u64) has drop { + || lambda__3__test(p0) + } + fun lambda__7__test(p0: u64): ||(||(u64) has drop) { + || lambda__6__test(p0) + } + fun lambda__12__test(p0: u64, p1: u64): ||(||(||(u64) has drop)) { + let _v0: ||u64 has copy + drop = || lambda__8__test(p0); + p0 = _v0(); + || lambda__11__test(p1, p0) + } + fun lambda__17__test(p0: u64, p1: u64): ||(||(||(u64) has drop)) { + let _v0: ||u64 has copy + drop = || lambda__13__test(p1); + p1 = _v0(); + || lambda__16__test(p0, p1) + } + fun lambda__19__test(p0: u64): ||(u64) { + || lambda__18__test(p0) + } + fun lambda__1__test(p0: u64): u64 { + p0 + } + fun lambda__3__test(p0: u64): u64 { + p0 + } + fun lambda__5__test(p0: u64): u64 { + p0 + } + fun lambda__6__test(p0: u64): ||(u64) has drop { + || lambda__5__test(p0) + } + fun lambda__8__test(p0: u64): u64 { + p0 + } + fun lambda__9__test(p0: u64, p1: u64): u64 { + p1 + p0 + } + fun lambda__10__test(p0: u64, p1: u64): ||(u64) has drop { + || lambda__9__test(p0, p1) + } + fun lambda__11__test(p0: u64, p1: u64): ||(||(u64) has drop) { + || lambda__10__test(p0, p1) + } + fun lambda__13__test(p0: u64): u64 { + p0 + } + fun lambda__14__test(p0: u64, p1: u64): u64 { + p1 + p0 + } + fun lambda__15__test(p0: u64, p1: u64): ||(u64) has drop { + || lambda__14__test(p0, p1) + } + fun lambda__16__test(p0: u64, p1: u64): ||(||(u64) has drop) { + || lambda__15__test(p0, p1) + } + fun lambda__18__test(p0: u64): u64 { + p0 + } +} + + +//# run 0xc0ffee::m::test --args 42 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled.baseline.exp new file mode 100644 index 00000000000..0ab2c645ce4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16198.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-98: publish [module 0xc0ffee::m {] +task 1 lines 101-101: run 0xc0ffee::m::test --args 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled new file mode 100644 index 00000000000..559c6e2cda2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16199.move` + +//# publish +module 0xc0ffee::m { + public fun test() { + let _v0 = |arg0| lambda__3__test(arg0); + let _v1 = _v0(1); + let _v2 = _v1(2); + assert!(_v2(3) == 6, 14566554180833181696); + } + fun lambda__3__test(p0: u64): |u64|(|u64|(u64)) { + |arg0| lambda__2__test(p0, arg0) + } + fun lambda__1__test(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + fun lambda__2__test(p0: u64, p1: u64): |u64|(u64) { + |arg0| lambda__1__test(p0, p1, arg0) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled.baseline.exp new file mode 100644 index 00000000000..5f5ae484b90 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16199.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled new file mode 100644 index 00000000000..95555a2a585 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled @@ -0,0 +1,3 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16335.move` + +//# run --verbose 0x42::Test::f2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled.baseline.exp new file mode 100644 index 00000000000..03e10e69ad4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335.decompiled.baseline.exp @@ -0,0 +1,11 @@ +processed 1 task +task 0 lines 3-3: run --verbose 0x42::Test::f2 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::Test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled new file mode 100644 index 00000000000..2dab14b829c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled @@ -0,0 +1,30 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16335_split.move` + +//# publish +module 0x42::Test { + fun f3() { + let _v0: || has copy + drop = || lambda__1__f3(); + let _v1: || has drop = || lambda__3__f3(_v0); + _v1(); + let _v2: || has copy + drop = || lambda__4__f3(); + _v2(); + } + fun lambda__1__f3() { + () + } + fun lambda__3__f3(p0: || has drop) { + let _v0: || has copy + drop = || lambda__2__f3(); + let _v1 = p0; + let _v2 = &mut _v1; + *_v2 = _v0; + } + fun lambda__4__f3() { + () + } + fun lambda__2__f3() { + () + } +} + + +//# run --verbose 0x42::Test::f3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled.baseline.exp new file mode 100644 index 00000000000..1e15e0fe91a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16335_split.decompiled.baseline.exp @@ -0,0 +1,20 @@ +processed 2 tasks +task 0 lines 3-27: publish [module 0x42::Test {] +Error: compilation errors: + error: cannot assign `&mut || has copy + drop` to left-hand side of type `&mut || has drop` + ┌─ TEMPFILE:19:10 + │ +19 │ *_v2 = _v0; + │ ^^^ + + +task 1 lines 30-30: run --verbose 0x42::Test::f3 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::Test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled new file mode 100644 index 00000000000..6a9c5f20d1b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16363.move` + +//# publish +module 0x42::foo { + use 0x1::vector; + struct Foo has drop, key { + f: |T0|(vector) has drop + store, + } + public fun make_foo(p0: &signer) { + let _v0 = Foo{f: |arg0| vector::singleton(arg0)}; + move_to>(p0, _v0); + } +} + + +//# publish +module 0x42::test { + use 0x42::foo; + fun run(p0: &signer) { + let _v0 = |arg0| foo::make_foo(arg0); + _v0(p0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled.baseline.exp new file mode 100644 index 00000000000..d4edd99c439 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16363.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0x42::foo {] +task 1 lines 16-23: publish [module 0x42::test {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled new file mode 100644 index 00000000000..64b5529c8e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16407.move` + +//# publish +module 0xc0ffee::m { + fun apply_repeatedly(p0: |u64|(u64) has copy + drop, p1: u64): |u64|(u64) has copy + drop { + |arg0| lambda__1__apply_repeatedly(p1, p0, arg0) + } + fun lambda__1__apply_repeatedly(p0: u64, p1: |u64|(u64) has copy + drop, p2: u64): u64 { + let _v0 = 0; + let _v1 = false; + loop { + if (_v1) _v0 = _v0 + 1 else _v1 = true; + if (!(_v0 < p0)) break; + p2 = p1(p2) + }; + p2 + } + public fun test(): u64 { + let _v0 = apply_repeatedly(|arg0| lambda__1__test(arg0), 10); + _v0(1) + } + fun lambda__1__test(p0: u64): u64 { + p0 + 1 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled.baseline.exp new file mode 100644 index 00000000000..afadbf6e6cd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16407.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-25: publish [module 0xc0ffee::m {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled new file mode 100644 index 00000000000..92c00f6a2fd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled @@ -0,0 +1,48 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16408.move` + +//# publish +module 0xc0ffee::m { + fun make_func_1(): |u64|(|u64|(u64)) has copy + drop { + |arg0| lambda__2__make_func_1(arg0) + } + fun lambda__2__make_func_1(p0: u64): |u64|(u64) { + |arg0| lambda__1__make_func_1(p0, arg0) + } + fun make_func_2(): |u64, u64|(||(u64)) has copy + drop { + |arg0,arg1| lambda__2__make_func_2(arg0, arg1) + } + fun lambda__2__make_func_2(p0: u64, p1: u64): ||(u64) { + || lambda__1__make_func_2(p0, p1) + } + fun make_func_3(): |u64, u64|(||(u64, u64)) has copy + drop { + |arg0,arg1| lambda__2__make_func_3(arg0, arg1) + } + fun lambda__2__make_func_3(p0: u64, p1: u64): ||(u64, u64) { + || lambda__1__make_func_3(p0, p1) + } + fun test() { + let _v0 = make_func_1(); + let _v1 = _v0(10); + assert!(_v1(20) == 30, 14566554180833181696); + let _v2 = make_func_2(); + let _v3 = _v2(10, 20); + assert!(_v3() == 200, 14566554180833181696); + let _v4 = make_func_3(); + let _v5 = _v4(10, 20); + let (_v6,_v7) = _v5(); + assert!(_v6 == 10, 14566554180833181696); + assert!(_v7 == 20, 14566554180833181696); + } + fun lambda__1__make_func_1(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__1__make_func_2(p0: u64, p1: u64): u64 { + p0 * p1 + } + fun lambda__1__make_func_3(p0: u64, p1: u64): (u64, u64) { + (p0, p1) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled.baseline.exp new file mode 100644 index 00000000000..af6c307f7d2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16408.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-45: publish [module 0xc0ffee::m {] +task 1 lines 48-48: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled new file mode 100644 index 00000000000..cc9243c8b2b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16492.move` + +//# publish +module 0x66::work { + public entry fun foo() { + let _v0 = 0x1::vector::empty<|u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64| has drop>(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled.baseline.exp new file mode 100644 index 00000000000..d8e9a099b6d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16492.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-8: publish [module 0x66::work {] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000066::work'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0x66::work, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled new file mode 100644 index 00000000000..ff47dfd0a56 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16667.move` + +//# publish +module 0xaa00::M0 { + struct S1 has drop { + } +} + + +//# publish +module 0xaa00::M1 { + use 0xaa00::M0; + public entry fun f1() { + let _v0: |M0::S1| has copy + drop = |arg0| lambda__2__f1(arg0); + let _v1: ||M0::S1| has drop| has copy + drop = |arg0: |M0::S1| has drop| lambda__1__f1(arg0); + _v1(_v0); + } + fun lambda__2__f1(p0: M0::S1) { + () + } + fun lambda__1__f1(p0: |M0::S1| has drop) { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled.baseline.exp new file mode 100644 index 00000000000..50dbfb182c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16667.decompiled.baseline.exp @@ -0,0 +1,14 @@ +processed 2 tasks +task 0 lines 3-7: publish [module 0xaa00::M0 {] +task 1 lines 10-24: publish [module 0xaa00::M1 {] +Error: compilation errors: + error: unexpected token + ┌─ TEMPFILE1:15:26 + │ +15 │ let _v1: ||M0::S1| has drop| has copy + drop = |arg0: |M0::S1| has drop| lambda__1__f1(arg0); + │ ^ + │ │ + │ Unexpected '|' + │ Expected ';' + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled new file mode 100644 index 00000000000..22aef90d029 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled @@ -0,0 +1,160 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16684.move` + +//# publish +module 0xc0ffee::m { + use 0x1::vector; + struct Resource { + _0: u64, + } + fun apply(p0: ||(vector)): vector { + p0() + } + public fun test10(): vector { + let _v0 = vector[1, 2, 3]; + let _v1 = |arg0| lambda__1__test10(4, arg0); + let _v2 = &mut _v0; + _v1(_v2); + _v0 + } + fun lambda__1__test10(p0: u64, p1: &mut vector) { + vector::push_back(p1, p0); + } + public fun test1a(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test1a(); + _v0() + } + fun lambda__1__test1a(): vector { + vector::empty() + } + public fun test1b(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test1b(); + _v0() + } + fun lambda__1__test1b(): vector { + vector::empty() + } + public fun test2a(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test2a(); + _v0() + } + fun lambda__1__test2a(): vector { + vector::empty() + } + public fun test2b(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test2b(); + _v0() + } + fun lambda__1__test2b(): vector { + vector::empty() + } + public fun test3a(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test3a(); + _v0() + } + fun lambda__1__test3a(): vector { + vector::empty() + } + public fun test3b(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test3b(); + _v0() + } + fun lambda__1__test3b(): vector { + vector::empty() + } + public fun test4a(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test4a(); + _v0() + } + fun lambda__1__test4a(): vector { + vector::empty() + } + public fun test4b(): vector { + let _v0: ||vector has copy + drop = || lambda__1__test4b(); + _v0() + } + fun lambda__1__test4b(): vector { + vector::empty() + } + public fun test5(): vector { + let _v0: ||vector has copy + drop = || lambda__2__test5(); + _v0() + } + fun lambda__2__test5(): vector { + apply(|| lambda__1__test5()) + } + public fun test6(): vector { + let _v0 = |arg0| vector::singleton(arg0); + _v0(42) + } + public fun test7() { + let _v0 = |arg0| lambda__1__test7(arg0); + let _v1 = vector::empty(); + _v0(_v1); + } + fun lambda__1__test7(p0: vector) { + vector::destroy_empty(p0); + } + public fun test8(): u64 { + let _v0 = |arg0| lambda__1__test8(arg0); + let _v1 = vector[1, 2, 3]; + let _v2 = &_v1; + _v0(_v2) + } + fun lambda__1__test8(p0: &vector): u64 { + vector::length(p0) + } + public fun test9a(): vector { + let _v0 = vector[1, 2, 3]; + let _v1 = |arg0,arg1,arg2| lambda__1__test9a(arg0, arg1, arg2); + let _v2 = &mut _v0; + _v1(_v2, 0, 2); + _v0 + } + fun lambda__1__test9a(p0: &mut vector, p1: u64, p2: u64) { + vector::swap(p0, p1, p2); + } + public fun test9b(): vector { + let _v0 = vector[1, 2, 3]; + let _v1 = |arg0,arg1,arg2| lambda__1__test9b(arg0, arg1, arg2); + let _v2 = &mut _v0; + _v1(_v2, 0, 2); + _v0 + } + fun lambda__1__test9b(p0: &mut vector, p1: u64, p2: u64) { + vector::swap(p0, p1, p2); + } + fun lambda__1__test5(): vector { + vector::empty() + } +} + + +//# run 0xc0ffee::m::test1a + +//# run 0xc0ffee::m::test1b + +//# run 0xc0ffee::m::test2a + +//# run 0xc0ffee::m::test2b + +//# run 0xc0ffee::m::test3a --type-args u64 + +//# run 0xc0ffee::m::test3b --type-args u16 + +//# run 0xc0ffee::m::test4a --type-args u32 + +//# run 0xc0ffee::m::test4b --type-args u128 + +//# run 0xc0ffee::m::test5 + +//# run 0xc0ffee::m::test6 + +//# run 0xc0ffee::m::test7 + +//# run 0xc0ffee::m::test8 + +//# run 0xc0ffee::m::test9a + +//# run 0xc0ffee::m::test9b + +//# run 0xc0ffee::m::test10 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled.baseline.exp new file mode 100644 index 00000000000..4c0dd9a5028 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16684.decompiled.baseline.exp @@ -0,0 +1,31 @@ +processed 16 tasks +task 0 lines 3-129: publish [module 0xc0ffee::m {] +task 1 lines 132-132: run 0xc0ffee::m::test1a +return values: [] +task 2 lines 134-134: run 0xc0ffee::m::test1b +return values: [] +task 3 lines 136-136: run 0xc0ffee::m::test2a +return values: [] +task 4 lines 138-138: run 0xc0ffee::m::test2b +return values: [] +task 5 lines 140-140: run 0xc0ffee::m::test3a --type-args u64 +return values: [] +task 6 lines 142-142: run 0xc0ffee::m::test3b --type-args u16 +return values: [] +task 7 lines 144-144: run 0xc0ffee::m::test4a --type-args u32 +return values: [] +task 8 lines 146-146: run 0xc0ffee::m::test4b --type-args u128 +return values: [] +task 9 lines 148-148: run 0xc0ffee::m::test5 +return values: [] +task 10 lines 150-150: run 0xc0ffee::m::test6 +return values: [42] +task 11 lines 152-152: run 0xc0ffee::m::test7 +task 12 lines 154-154: run 0xc0ffee::m::test8 +return values: 3 +task 13 lines 156-156: run 0xc0ffee::m::test9a +return values: [3, 2, 1] +task 14 lines 158-158: run 0xc0ffee::m::test9b +return values: [3, 2, 1] +task 15 lines 160-160: run 0xc0ffee::m::test10 +return values: [1, 2, 3, 4] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled new file mode 100644 index 00000000000..037e675b09d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled @@ -0,0 +1,159 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/bug_16954.move` + +//# publish +module 0xc0ffee::m { + fun call(p0: ||(u64)): u64 { + p0() + } + public fun test1(): u8 { + let _v0 = |arg0| lambda__3__test1(1u8, arg0); + _v0(7u8) + } + fun lambda__3__test1(p0: u8, p1: u8): u8 { + p0 = p0 + p1; + let _v0 = |arg0| lambda__1__test1(p0, arg0); + let _v1 = _v0(3u8); + _v0 = |arg0| lambda__2__test1(p0, arg0); + let _v2 = _v0(4u8); + _v1 * _v2 + } + public fun test10(): u8 { + let _v0 = |arg0| lambda__1__test10(2u8, arg0); + _v0(3u8) + 0u8 + } + fun lambda__1__test10(p0: u8, p1: u8): u8 { + p1 + p0 + } + public fun test11(): u64 { + let _v0 = call(|| lambda__1__test11(1)); + let _v1 = 1 + _v0; + let _v2 = call(|| lambda__2__test11(1)); + _v1 + _v2 + } + fun lambda__1__test11(p0: u64): u64 { + p0 + 2 + } + fun lambda__2__test11(p0: u64): u64 { + p0 - 1 + } + public fun test2(): u64 { + let _v0: ||(||(u64)) has copy + drop = || lambda__2__test2(1); + let _v1 = _v0(); + _v1() + } + fun lambda__2__test2(p0: u64): ||(u64) { + || lambda__1__test2(p0) + } + public fun test3(): u64 { + let _v0 = |arg0| lambda__2__test3(arg0); + _v0(1) + } + fun lambda__2__test3(p0: u64): u64 { + let _v0 = p0 + 1; + let _v1: |u64|u64 has copy + drop = |arg0| lambda__1__test3(arg0); + _v1(_v0) + } + public fun test4(p0: u64): u64 { + let _v0: ||(||(u64)) has copy + drop = || lambda__2__test4(p0); + let _v1 = _v0(); + _v1() + } + fun lambda__2__test4(p0: u64): ||(u64) { + || lambda__1__test4(p0) + } + public fun test5(): u8 { + let _v0 = |arg0| lambda__2__test5(arg0); + _v0(7u8) + 2u8 + } + fun lambda__2__test5(p0: u8): u8 { + let _v0: ||u8 has copy + drop = || lambda__1__test5(p0); + _v0() + } + public fun test6(): u64 { + let _v0 = |arg0| lambda__2__test6(arg0); + _v0(10) + 5 + } + fun lambda__2__test6(p0: u64): u64 { + let _v0 = p0 + 1; + let _v1: ||u64 has copy + drop = || lambda__1__test6(_v0); + _v1() + } + public fun test7(): u8 { + let _v0 = |arg0| lambda__2__test7(arg0); + _v0(3u8) + } + fun lambda__2__test7(p0: u8): u8 { + let _v0 = p0 + 2u8; + let _v1 = |arg0| lambda__1__test7(_v0, arg0); + _v1(4u8) + } + public fun test8(): u64 { + let _v0: ||u64 has copy + drop = || lambda__2__test8(); + _v0() + 1 + } + fun lambda__2__test8(): u64 { + let _v0: ||u64 has copy + drop = || lambda__1__test8(); + _v0() + 2 + } + public fun test9(): u8 { + let _v0 = |arg0| lambda__2__test9(arg0); + _v0(4u8) + 0u8 + } + fun lambda__2__test9(p0: u8): u8 { + let _v0 = |arg0| lambda__1__test9(arg0); + _v0(p0) + } + fun lambda__1__test1(p0: u8, p1: u8): u8 { + p1 + p0 + } + fun lambda__2__test1(p0: u8, p1: u8): u8 { + p0 - p1 + } + fun lambda__1__test2(p0: u64): u64 { + p0 + } + fun lambda__1__test3(p0: u64): u64 { + p0 - 1 + } + fun lambda__1__test4(p0: u64): u64 { + p0 + 1 + } + fun lambda__1__test5(p0: u8): u8 { + p0 + 1u8 + } + fun lambda__1__test6(p0: u64): u64 { + p0 + 1 + } + fun lambda__1__test7(p0: u8, p1: u8): u8 { + p0 + p1 + } + fun lambda__1__test8(): u64 { + 3 + } + fun lambda__1__test9(p0: u8): u8 { + p0 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 + +//# run 0xc0ffee::m::test4 --args 42 + +//# run 0xc0ffee::m::test5 + +//# run 0xc0ffee::m::test6 + +//# run 0xc0ffee::m::test7 + +//# run 0xc0ffee::m::test8 + +//# run 0xc0ffee::m::test9 + +//# run 0xc0ffee::m::test10 + +//# run 0xc0ffee::m::test11 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled.baseline.exp new file mode 100644 index 00000000000..a0a8e63f96b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/bug_16954.decompiled.baseline.exp @@ -0,0 +1,24 @@ +processed 12 tasks +task 0 lines 3-136: publish [module 0xc0ffee::m {] +task 1 lines 139-139: run 0xc0ffee::m::test1 +return values: 44 +task 2 lines 141-141: run 0xc0ffee::m::test2 +return values: 1 +task 3 lines 143-143: run 0xc0ffee::m::test3 +return values: 1 +task 4 lines 145-145: run 0xc0ffee::m::test4 --args 42 +return values: 43 +task 5 lines 147-147: run 0xc0ffee::m::test5 +return values: 10 +task 6 lines 149-149: run 0xc0ffee::m::test6 +return values: 17 +task 7 lines 151-151: run 0xc0ffee::m::test7 +return values: 9 +task 8 lines 153-153: run 0xc0ffee::m::test8 +return values: 6 +task 9 lines 155-155: run 0xc0ffee::m::test9 +return values: 4 +task 10 lines 157-157: run 0xc0ffee::m::test10 +return values: 5 +task 11 lines 159-159: run 0xc0ffee::m::test11 +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled new file mode 100644 index 00000000000..7141cd95aa7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled @@ -0,0 +1,117 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/calculator.move` + +//# publish +module 0x66::calculator { + use 0x1::signer; + enum Input { + Number { + _0: u64, + } + Add, + Sub, + } + enum State has copy, drop, key { + Empty, + Value { + _0: u64, + } + Continuation { + _0: |u64|(u64) has copy + drop + store, + } + } + entry fun add(p0: &signer) + acquires State + { + let _v0 = Input::Add{}; + process(p0, _v0); + } + fun process(p0: &signer, p1: Input) + acquires State + { + let _v0; + let _v1 = signer::address_of(p0); + let _v2 = move_from(_v1); + let _v3 = &_v2; + let _v4 = &p1; + if (!((_v3 is Empty) && (_v4 is Number))) { + if (!((_v3 is Value) && (_v4 is Number))) { + if (!((_v3 is Value) && (_v4 is Add))) { + if (!((_v3 is Value) && (_v4 is Sub))) { + assert!((_v3 is Continuation) && (_v4 is Number), 1); + let State::Continuation{_0: _v5} = _v2; + let Input::Number{_0: _v6} = p1; + _v0 = State::Value{_0: _v5(_v6)}; + move_to(p0, _v0); + return () + }; + let State::Value{_0: _v7} = _v2; + let Input::Sub{} = p1; + let _v8 = State::Continuation{_0: |arg0| storable_sub(_v7, arg0)}; + move_to(p0, _v8); + return () + }; + let State::Value{_0: _v9} = _v2; + let Input::Add{} = p1; + let _v10 = State::Continuation{_0: |arg0| storable_add(_v9, arg0)}; + move_to(p0, _v10); + return () + }; + let State::Value{_0: _v11} = _v2; + let Input::Number{_0: _v12} = p1; + let _v13 = State::Value{_0: _v12}; + move_to(p0, _v13); + return () + }; + let State::Empty{} = _v2; + let Input::Number{_0: _v14} = p1; + _v0 = State::Value{_0: _v14}; + move_to(p0, _v0); + } + fun init_module(p0: &signer) { + let _v0 = State::Empty{}; + move_to(p0, _v0); + } + entry fun number(p0: &signer, p1: u64) + acquires State + { + let _v0 = Input::Number{_0: p1}; + process(p0, _v0); + } + #[persistent] + fun storable_sub(p0: u64, p1: u64): u64 { + p0 - p1 + } + #[persistent] + fun storable_add(p0: u64, p1: u64): u64 { + p0 + p1 + } + entry fun sub(p0: &signer) + acquires State + { + let _v0 = Input::Sub{}; + process(p0, _v0); + } + fun view(p0: &signer): u64 + acquires State + { + let _v0 = signer::address_of(p0); + let _v1 = borrow_global(_v0); + assert!(_v1 is Value, 1); + *&_v1._0 + } +} + + +//# run 0x66::calculator::init_module --signers 0x66 + +//# run 0x66::calculator::number --signers 0x66 --args 10 + +//# run 0x66::calculator::add --signers 0x66 + +//# run 0x66::calculator::number --signers 0x66 --args 20 + +//# run 0x66::calculator::sub --signers 0x66 + +//# run 0x66::calculator::number --signers 0x66 --args 5 + +//# run 0x66::calculator::view --signers 0x66 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled.baseline.exp new file mode 100644 index 00000000000..8833d478417 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/calculator.decompiled.baseline.exp @@ -0,0 +1,68 @@ +processed 8 tasks +task 0 lines 3-102: publish [module 0x66::calculator {] +Error: compilation errors: + error: cannot select field `_0` since it has different types in variants of enum `State` + ┌─ TEMPFILE:100:11 + │ +100 │ *&_v1._0 + │ ^^^ + │ + = field `_0` has type `|u64|u64 has copy + drop + store` in variant `Continuation` and type `u64` in variant `Value` + + +task 1 lines 105-105: run 0x66::calculator::init_module --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 107-107: run 0x66::calculator::number --signers 0x66 --args 10 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 3 lines 109-109: run 0x66::calculator::add --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 4 lines 111-111: run 0x66::calculator::number --signers 0x66 --args 20 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 5 lines 113-113: run 0x66::calculator::sub --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 6 lines 115-115: run 0x66::calculator::number --signers 0x66 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 7 lines 117-117: run 0x66::calculator::view --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled new file mode 100644 index 00000000000..79f23774372 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled @@ -0,0 +1,40 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/capturing.move` + +//# publish +module 0x42::test { + struct S has copy, drop { + f: u64, + } + public fun one_captured(p0: u64): u64 { + let _v0 = |arg0| lambda__1__one_captured(p0, arg0); + _v0(2) + } + fun lambda__1__one_captured(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun struct_captured(p0: u64): u64 { + struct_captured_helper(S{f: p0}) + } + fun struct_captured_helper(p0: S): u64 { + let _v0 = |arg0| lambda__1__struct_captured_helper(p0, arg0); + _v0(4) + } + fun lambda__1__struct_captured_helper(p0: S, p1: u64): u64 { + *&(&p0).f + p1 + } + public fun two_captured(p0: u64, p1: u8): u64 { + let _v0 = |arg0| lambda__1__two_captured(p0, p1, arg0); + _v0(3) + } + fun lambda__1__two_captured(p0: u64, p1: u8, p2: u64): u64 { + let _v0 = p1 as u64; + p0 + _v0 + p2 + } +} + + +//# run 0x42::test::one_captured --args 3 + +//# run 0x42::test::two_captured --args 3 2u8 + +//# run 0x42::test::struct_captured --args 3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled.baseline.exp new file mode 100644 index 00000000000..2a977901226 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing.decompiled.baseline.exp @@ -0,0 +1,8 @@ +processed 4 tasks +task 0 lines 3-33: publish [module 0x42::test {] +task 1 lines 36-36: run 0x42::test::one_captured --args 3 +return values: 5 +task 2 lines 38-38: run 0x42::test::two_captured --args 3 2u8 +return values: 8 +task 3 lines 40-40: run 0x42::test::struct_captured --args 3 +return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled new file mode 100644 index 00000000000..d891787046f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled @@ -0,0 +1,28 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/capturing_generic.move` + +//# publish +module 0x42::test { + struct S has copy, drop { + f: u64, + } + fun eq_with(p0: T0): |T0|(bool) { + |arg0| lambda__1__eq_with(p0, arg0) + } + fun lambda__1__eq_with(p0: T0, p1: T0): bool { + p0 == p1 + } + public fun test_S(p0: u64): bool { + let _v0 = S{f: p0}; + let _v1 = eq_with(S{f: 2}); + _v1(_v0) + } + public fun test_u64(p0: u64): bool { + let _v0 = eq_with(2); + _v0(p0) + } +} + + +//# run 0x42::test::test_u64 --args 3 + +//# run 0x42::test::test_S --args 2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled.baseline.exp new file mode 100644 index 00000000000..e151a5c806f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/capturing_generic.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-23: publish [module 0x42::test {] +task 1 lines 26-26: run 0x42::test::test_u64 --args 3 +return values: false +task 2 lines 28-28: run 0x42::test::test_S --args 2 +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled new file mode 100644 index 00000000000..8271fd1d8b0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled @@ -0,0 +1,33 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/closure_equality.move` + +//# publish +module 0xc0ffee::m { + use 0x1::signer; + struct Wrapper has copy, drop, key { + value: T0, + } + public fun init(p0: &signer) { + let _v0 = Wrapper<|u64|(u64) has copy + drop + store>{value: |arg0| identity(arg0)}; + move_to>(p0, _v0); + } + public fun identity(p0: T0): T0 { + p0 + } + public fun compare(p0: |u64|(u64) has copy + drop + store, p1: &signer): bool + acquires Wrapper + { + let _v0 = signer::address_of(p1); + *&borrow_global>(_v0).value == p0 + } +} + + +//# run 0xc0ffee::m::init --signers 0xc0ffee + +//# run --signers 0xc0ffee +script { + use 0xc0ffee::m; + fun main(p0: &signer) { + assert!(m::compare(|arg0| m::identity(arg0), p0), 14566554180833181696); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled.baseline.exp new file mode 100644 index 00000000000..7a80ba70db2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_equality.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-22: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::init --signers 0xc0ffee +task 2 lines 27-33: run --signers 0xc0ffee [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled new file mode 100644 index 00000000000..b21ff2bc916 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/closure_mask.move` + +//# publish +module 0x42::test { + fun if_then(p0: bool, p1: u64, p2: u64): u64 { + if (p0) return p1; + p2 + } + public fun run(): bool { + let _v0 = |arg0,arg1| if_then(true, arg0, arg1); + let _v1 = |arg0,arg1| if_then(arg0, 10, arg1); + let _v2 = |arg0| if_then(false, 10, arg0); + let _v3 = |arg0,arg1| if_then(arg0, arg1, 20); + assert!(_v0(3, 4) == 3, 14566554180833181696); + assert!(_v1(true, 22222) == 10, 14566554180833181696); + assert!(_v2(43) == 43, 14566554180833181696); + assert!(_v3(false, 23333) == 20, 14566554180833181696); + true + } +} + + +//# run 0x42::test::run \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled.baseline.exp new file mode 100644 index 00000000000..25800c57c7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closure_mask.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0x42::test {] +task 1 lines 23-23: run 0x42::test::run +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled new file mode 100644 index 00000000000..1a8793855f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled @@ -0,0 +1,173 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/closures_in_enums.move` + +//# publish +module 0xc0ffee::m { + enum Function has copy, drop { + NoParam { + _0: ||(u64) has copy + drop, + } + OneParam { + _0: |u64|(u64) has copy + drop, + } + TwoParam { + _0: |u64, u64|(u64) has copy + drop, + } + } + fun get_func(p0: &Function): &||(u64) has copy { + assert!(p0 is NoParam, 42); + &p0._0 + } + fun get_func_recursive(p0: Function): ||(u64) { + let _v0 = &p0; + 'l0: loop { + loop { + if (!(_v0 is NoParam)) { + if (_v0 is OneParam) break; + if (_v0 is TwoParam) break 'l0; + abort 14566554180833181697 + }; + let Function::NoParam{_0: _v1} = p0; + return _v1 + }; + let Function::OneParam{_0: _v2} = p0; + return get_func_recursive(Function::NoParam{_0: || lambda__1__get_func_recursive(_v2)}) + }; + let Function::TwoParam{_0: _v3} = p0; + get_func_recursive(Function::OneParam{_0: |arg0| lambda__2__get_func_recursive(_v3, arg0)}) + } + fun lambda__1__get_func_recursive(p0: |u64|(u64) has copy + drop): u64 { + p0(0) + } + fun lambda__2__get_func_recursive(p0: |u64, u64|(u64) has copy + drop, p1: u64): u64 { + p0(0, p1) + } + fun runner_1(p0: Function): u64 { + let _v0 = &p0; + 'l0: loop { + loop { + if (!(_v0 is NoParam)) { + if (_v0 is OneParam) break; + if (_v0 is TwoParam) break 'l0; + abort 14566554180833181697 + }; + let Function::NoParam{_0: _v1} = p0; + return _v1() + }; + let Function::OneParam{_0: _v2} = p0; + return _v2(0) + }; + let Function::TwoParam{_0: _v3} = p0; + _v3(0, 0) + } + fun runner_2(p0: Function): u64 { + let _v0; + let _v1 = &p0; + if (_v1 is NoParam) { + let Function::NoParam{_0: _v2} = p0; + _v0 = _v2 + } else if (_v1 is OneParam) { + let Function::OneParam{_0: _v3} = p0; + _v0 = || lambda__1__runner_2(_v3) + } else if (_v1 is TwoParam) { + let Function::TwoParam{_0: _v4} = p0; + _v0 = || lambda__2__runner_2(_v4) + } else abort 14566554180833181697; + _v0() + } + fun lambda__1__runner_2(p0: |u64|(u64) has copy + drop): u64 { + p0(0) + } + fun lambda__2__runner_2(p0: |u64, u64|(u64) has copy + drop): u64 { + p0(0, 0) + } + fun runner_3(p0: &Function): u64 { + let _v0 = *get_func(p0); + _v0() + } + fun runner_4(p0: Function): u64 { + let _v0 = get_func_recursive(p0); + _v0() + } + public fun test_1() { + assert!(runner_1(Function::NoParam{_0: || lambda__1__test_1()}) == 0, 14566554180833181696); + assert!(runner_1(Function::OneParam{_0: |arg0| lambda__2__test_1(arg0)}) == 0, 14566554180833181696); + assert!(runner_1(Function::TwoParam{_0: |arg0,arg1| lambda__3__test_1(arg0, arg1)}) == 0, 14566554180833181696); + assert!(runner_1(Function::NoParam{_0: || lambda__4__test_1(1)}) == 1, 14566554180833181696); + assert!(runner_1(Function::OneParam{_0: |arg0| lambda__5__test_1(1, arg0)}) == 1, 14566554180833181696); + } + fun lambda__1__test_1(): u64 { + 0 + } + fun lambda__2__test_1(p0: u64): u64 { + p0 + } + fun lambda__3__test_1(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__4__test_1(p0: u64): u64 { + p0 + } + fun lambda__5__test_1(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test_2() { + assert!(runner_2(Function::NoParam{_0: || lambda__1__test_2()}) == 0, 14566554180833181696); + assert!(runner_2(Function::OneParam{_0: |arg0| lambda__2__test_2(arg0)}) == 0, 14566554180833181696); + assert!(runner_2(Function::TwoParam{_0: |arg0,arg1| lambda__3__test_2(arg0, arg1)}) == 0, 14566554180833181696); + assert!(runner_2(Function::NoParam{_0: || lambda__4__test_2(1)}) == 1, 14566554180833181696); + assert!(runner_2(Function::OneParam{_0: |arg0| lambda__5__test_2(1, arg0)}) == 1, 14566554180833181696); + } + fun lambda__1__test_2(): u64 { + 0 + } + fun lambda__2__test_2(p0: u64): u64 { + p0 + } + fun lambda__3__test_2(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__4__test_2(p0: u64): u64 { + p0 + } + fun lambda__5__test_2(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun test_3() { + let _v0 = Function::NoParam{_0: || lambda__1__test_3()}; + assert!(runner_3(&_v0) == 0, 14566554180833181696); + } + fun lambda__1__test_3(): u64 { + 0 + } + public fun test_4() { + assert!(runner_4(Function::NoParam{_0: || lambda__1__test_4()}) == 0, 14566554180833181696); + assert!(runner_4(Function::OneParam{_0: |arg0| lambda__2__test_4(arg0)}) == 0, 14566554180833181696); + assert!(runner_4(Function::TwoParam{_0: |arg0,arg1| lambda__3__test_4(arg0, arg1)}) == 0, 14566554180833181696); + assert!(runner_4(Function::NoParam{_0: || lambda__4__test_4(1)}) == 1, 14566554180833181696); + assert!(runner_4(Function::OneParam{_0: |arg0| lambda__5__test_4(1, arg0)}) == 1, 14566554180833181696); + } + fun lambda__1__test_4(): u64 { + 0 + } + fun lambda__2__test_4(p0: u64): u64 { + p0 + } + fun lambda__3__test_4(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__4__test_4(p0: u64): u64 { + p0 + } + fun lambda__5__test_4(p0: u64, p1: u64): u64 { + p0 + p1 + } +} + + +//# run 0xc0ffee::m::test_1 + +//# run 0xc0ffee::m::test_2 + +//# run 0xc0ffee::m::test_3 + +//# run 0xc0ffee::m::test_4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled.baseline.exp new file mode 100644 index 00000000000..8f71d517832 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/closures_in_enums.decompiled.baseline.exp @@ -0,0 +1,44 @@ +processed 5 tasks +task 0 lines 3-164: publish [module 0xc0ffee::m {] +Error: compilation errors: + error: cannot select field `_0` since it has different types in variants of enum `Function` + ┌─ TEMPFILE:18:10 + │ +18 │ &p0._0 + │ ^^ + │ + = field `_0` has type `|u64, u64|u64 has copy + drop` in variant `TwoParam` and type `||u64 has copy + drop` in variant `NoParam` and type `|u64|u64 has copy + drop` in variant `OneParam` + + +task 1 lines 167-167: run 0xc0ffee::m::test_1 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 169-169: run 0xc0ffee::m::test_2 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 3 lines 171-171: run 0xc0ffee::m::test_3 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 4 lines 173-173: run 0xc0ffee::m::test_4 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled new file mode 100644 index 00000000000..5eb0206bea4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled @@ -0,0 +1,31 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/cross_module_unwrap.move` + +//# publish +module 0xc0ffee::m { + struct Wrapper { + _0: u64, + } + public fun apply(p0: |Wrapper|(u64)): u64 { + let _v0 = Wrapper{_0: 42}; + p0(_v0) + } + public fun unwrap_maker(): |Wrapper|(u64) { + |arg0| lambda__1__unwrap_maker(arg0) + } + fun lambda__1__unwrap_maker(p0: Wrapper): u64 { + let Wrapper{_0: _v0} = p0; + _v0 + } +} + + +//# publish +module 0xc0ffee::n { + use 0xc0ffee::m; + public fun test(): u64 { + m::apply(m::unwrap_maker()) + } +} + + +//# run 0xc0ffee::n::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled.baseline.exp new file mode 100644 index 00000000000..cfe6b9b5286 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/cross_module_unwrap.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 3 tasks +task 0 lines 3-19: publish [module 0xc0ffee::m {] +task 1 lines 22-28: publish [module 0xc0ffee::n {] +task 2 lines 31-31: run 0xc0ffee::n::test +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled new file mode 100644 index 00000000000..5e942c682c4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled @@ -0,0 +1,34 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/extensive_capturing.move` + +//# publish +module 0xc0ffee::m { + fun add3(p0: u8, p1: u8, p2: u8): u8 { + p0 + p1 + p2 + } + public fun test() { + let _v0: ||u8 has copy + drop = || add3(0u8, 1u8, 2u8); + assert!(_v0() == 3u8, 14566554180833181696); + let _v1 = |arg0| add3(arg0, 0u8, 1u8); + assert!(_v1(2u8) == 3u8, 14566554180833181696); + _v1 = |arg0| add3(0u8, arg0, 1u8); + assert!(_v1(2u8) == 3u8, 14566554180833181696); + _v1 = |arg0| add3(0u8, 1u8, arg0); + assert!(_v1(2u8) == 3u8, 14566554180833181696); + let _v2 = |arg0,arg1| add3(0u8, arg0, arg1); + assert!(_v2(2u8, 1u8) == 3u8, 14566554180833181696); + _v2 = |arg0,arg1| add3(arg0, arg1, 0u8); + assert!(_v2(2u8, 1u8) == 3u8, 14566554180833181696); + _v2 = |arg0,arg1| add3(arg0, 0u8, arg1); + assert!(_v2(2u8, 1u8) == 3u8, 14566554180833181696); + let _v3 = |arg0,arg1,arg2| add3(arg0, arg1, arg2); + assert!(_v3(2u8, 0u8, 1u8) == 3u8, 14566554180833181696); + _v1 = |arg0| lambda__1__test(arg0); + assert!(_v1(2u8) == 4u8, 14566554180833181696); + } + fun lambda__1__test(p0: u8): u8 { + add3(p0, 0u8, p0) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled.baseline.exp new file mode 100644 index 00000000000..34d44280170 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/extensive_capturing.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-31: publish [module 0xc0ffee::m {] +task 1 lines 34-34: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled new file mode 100644 index 00000000000..9496fa7d38d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled @@ -0,0 +1,59 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/field_access_closure.move` + +//# publish +module 0xc0ffee::m { + struct Func1 has copy, drop { + bar: ||(u64) has copy + drop, + } + enum Func2 has copy, drop { + V1 { + bar: |u64|(u64) has copy + drop, + } + V2 { + bar: |u64|(u64) has copy + drop, + x: u64, + } + } + struct Func3 has copy, drop { + _0: ||(u64) has copy + drop, + } + fun test1(): u64 { + let _v0 = Func1{bar: || lambda__1__test1()}; + let _v1 = *&(&_v0).bar; + _v1() + } + fun lambda__1__test1(): u64 { + 42 + } + fun test2(): u64 { + let _v0 = Func2::V1{bar: |arg0| lambda__1__test2(arg0)}; + let _v1 = Func2::V2{bar: |arg0| lambda__2__test2(arg0), x: 44}; + let _v2 = *&(&_v0).bar; + let _v3 = _v2(42); + let _v4 = *&(&_v1).x; + let _v5 = *&(&_v1).bar; + let _v6 = _v5(_v4); + _v3 + _v6 + } + fun lambda__1__test2(p0: u64): u64 { + p0 + } + fun lambda__2__test2(p0: u64): u64 { + p0 + 1 + } + fun test3(): u64 { + let _v0 = Func3{_0: || lambda__1__test3()}; + let _v1 = *&(&_v0)._0; + _v1() + } + fun lambda__1__test3(): u64 { + 42 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled.baseline.exp new file mode 100644 index 00000000000..c0b5c97d214 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/field_access_closure.decompiled.baseline.exp @@ -0,0 +1,8 @@ +processed 4 tasks +task 0 lines 3-52: publish [module 0xc0ffee::m {] +task 1 lines 55-55: run 0xc0ffee::m::test1 +return values: 42 +task 2 lines 57-57: run 0xc0ffee::m::test2 +return values: 87 +task 3 lines 59-59: run 0xc0ffee::m::test3 +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled new file mode 100644 index 00000000000..036e122c6e2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled @@ -0,0 +1,62 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/frame_cache.move` + +//# publish +module 0x42::dummy { + struct Dummy has key { + } +} + + +//# publish +module 0x42::foo { + use 0x1::signer; + struct Foo has store, key { + value: u64, + } + public fun foo_exists(p0: &signer): bool { + let _v0 = signer::address_of(p0); + exists>(_v0) + } + public fun foo_roundtrip() { + let Foo{value: _v0} = Foo{value: 0}; + } +} + + +//# publish +module 0x42::bar { + use 0x1::signer; + use 0x42::dummy; + struct Bar has key { + value: u64, + } + public fun dummy_bar_exists(p0: &signer): bool { + let _v0 = signer::address_of(p0); + exists>(_v0) + } + public fun make_dummy_bar(p0: &signer) { + let _v0 = Bar{value: 10}; + move_to>(p0, _v0); + } +} + + +//# publish +module 0x42::poc { + use 0x42::dummy; + use 0x42::foo; + use 0x42::bar; + fun run(p0: &signer) { + let _v0: || has copy + drop = || foo::foo_roundtrip(); + _v0(); + let _v1 = |arg0| bar::make_dummy_bar(arg0); + _v1(p0); + } +} + + +//# run 0x42::poc::run --signers 0x42 + +//# run 0x42::bar::dummy_bar_exists --signers 0x42 + +//# run 0x42::foo::foo_exists --signers 0x42 --type-args 0x42::dummy::Dummy \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled.baseline.exp new file mode 100644 index 00000000000..9741c5d007c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/frame_cache.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 7 tasks +task 0 lines 3-7: publish [module 0x42::dummy {] +task 1 lines 10-23: publish [module 0x42::foo {] +task 2 lines 26-41: publish [module 0x42::bar {] +task 3 lines 44-55: publish [module 0x42::poc {] +task 4 lines 58-58: run 0x42::poc::run --signers 0x42 +task 5 lines 60-60: run 0x42::bar::dummy_bar_exists --signers 0x42 +return values: true +task 6 lines 62-62: run 0x42::foo::foo_exists --signers 0x42 --type-args 0x42::dummy::Dummy +return values: false diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled new file mode 100644 index 00000000000..801429e451a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled @@ -0,0 +1,37 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/fun_refs.move` + +//# publish +module 0x42::test { + public fun ref(): u64 { + let _v0: |u64|(u64) has copy + drop = |arg0| lambda__1__ref(arg0); + ref_helper(&_v0, 5) + } + fun lambda__1__ref(p0: u64): u64 { + p0 + p0 + } + fun ref_helper(p0: &|u64|(u64) has copy, p1: u64): u64 { + let _v0 = *p0; + _v0(p1) + } + public fun ref_mut(): u64 { + let _v0: |u64|(u64) has copy + drop = |arg0| lambda__1__ref_mut(arg0); + ref_mut_helper(&mut _v0, 5); + _v0(2) + } + fun lambda__1__ref_mut(p0: u64): u64 { + p0 * p0 + } + fun ref_mut_helper(p0: &mut |u64|(u64) has copy + drop, p1: u64) { + let _v0 = *p0; + *p0 = |arg0| lambda__1__ref_mut_helper(p1, _v0, arg0); + } + fun lambda__1__ref_mut_helper(p0: u64, p1: |u64|(u64) has copy + drop, p2: u64): u64 { + let _v0 = p0 + p2; + p1(_v0) + } +} + + +//# run 0x42::test::ref + +//# run 0x42::test::ref_mut \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled.baseline.exp new file mode 100644 index 00000000000..f1111fa0934 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fun_refs.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-32: publish [module 0x42::test {] +task 1 lines 35-35: run 0x42::test::ref +return values: 10 +task 2 lines 37-37: run 0x42::test::ref_mut +return values: 49 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled new file mode 100644 index 00000000000..07a579518cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/func_ref_param.move` + +//# publish +module 0x77::m { + struct Func has drop { + _0: |&u64|(bool) has drop, + } + fun test() { + let _v0 = Func{_0: |arg0| lambda__1__test(arg0)}; + let _v1 = 1; + let _v2 = &_v1; + let Func{_0: _v3} = _v0; + assert!(_v3(_v2), 14566554180833181696); + } + fun lambda__1__test(p0: &u64): bool { + *p0 > 0 + } +} + + +//# run 0x77::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled.baseline.exp new file mode 100644 index 00000000000..902e5ce80fb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/func_ref_param.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0x77::m {] +task 1 lines 21-21: run 0x77::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled new file mode 100644 index 00000000000..9666264849d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled @@ -0,0 +1,166 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/funs_as_storage_key.move` + +//# publish +module 0x42::mod2 { + struct Registry has store, key { + func: T0, + } + public fun get_item(p0: address): T0 + acquires Registry + { + *&borrow_global>(p0).func + } + public fun item_exists(p0: address): bool { + exists>(p0) + } + public fun remove_item(p0: address): T0 + acquires Registry + { + let Registry{func: _v0} = move_from>(p0); + _v0 + } + public fun save_item(p0: &signer, p1: T0) { + let _v0 = Registry{func: p1}; + move_to>(p0, _v0); + } +} + + +//# publish +module 0x42::mod3 { + use 0x42::mod2; + use 0x1::signer; + struct MyStruct1 has copy, store, key { + x: u64, + } + struct MyStruct2 has copy, store, key { + y: u8, + } + public fun test_items(p0: signer, p1: bool): bool { + let _v0: |address|(bool) has copy + drop + store = |arg0| mod2::item_exists(arg0); + let _v1: |address|(bool) has copy + drop + store = |arg0| mod2::item_exists(arg0); + let _v2 = signer::address_of(&p0); + if (!exists(_v2)) { + let _v3 = MyStruct1{x: 3}; + mod2::save_item(&p0, _v3); + let _v4 = &p0; + move_to(_v4, _v3) + }; + if (p1) mod2::save_item<|address|(bool) has copy + drop + store>(&p0, _v0) else mod2::save_item<|address|(bool) has copy + drop + store>(&p0, _v1); + assert!(mod2::item_exists<|address|(bool) has copy + drop + store>(_v2), 14566554180833181696); + let _v5 = mod2::get_item<|address|(bool) has copy + drop + store>(_v2); + let _v6 = _v5(_v2); + assert!(p1 == _v6, 14566554180833181696); + let _v7 = mod2::remove_item<|address|(bool) has copy + drop + store>(_v2); + true + } +} + + +//# publish +module 0x42::mod4 { + struct Wrapper has key { + fv: T0, + } + fun check_exists(p0: &signer) { + assert!(exists>(@0x42), 404); + } + fun initialize(p0: &signer) { + let _v0 = Wrapper<|&u64, &mut u8|(&u64) has copy + drop + store>{fv: |arg0,arg1| test(arg0, arg1)}; + move_to>(p0, _v0); + } + #[persistent] + fun test(p0: &u64, p1: &mut u8): &u64 { + p0 + } +} + + +//# publish +module 0x42::mod5 { + struct VecWrapper has key { + fvs: vector, + } + fun check_exists(p0: &signer) { + assert!(exists>(@0x42), 404); + } + fun initialize(p0: &signer) { + let _v0: |&u64, &mut u8|&u64 has copy + drop = |arg0,arg1| test(arg0, arg1); + let _v1 = 0x1::vector::empty<|&u64, &mut u8|(&u64) has copy + drop + store>(); + 0x1::vector::push_back<|&u64, &mut u8|(&u64) has copy + drop + store>(&mut _v1, _v0); + let _v2 = VecWrapper<|&u64, &mut u8|(&u64) has copy + drop + store>{fvs: _v1}; + move_to>(p0, _v2); + } + #[persistent] + fun test(p0: &u64, p1: &mut u8): &u64 { + p0 + } +} + + +//# publish +module 0x42::mod6 { + struct VecWrapper has key { + fvs: vector, + } + fun compute(p0: &signer): u8 + acquires VecWrapper + { + let _v0; + if (exists>(@0x42)) _v0 = false else _v0 = !exists>(@0x42); + assert!(_v0, 404); + let _v1 = &borrow_global>(@0x42).fvs; + let _v2 = 0u8; + let _v3 = 0; + while (_v3 < 3) { + let _v4 = 0x1::vector::borrow<|&mut u8| has copy + drop + store>(_v1, _v3); + let _v5 = &mut _v2; + let _v6 = *_v4; + _v6(_v5); + _v3 = _v3 + 1; + continue + }; + _v2 + } + fun initialize(p0: &signer) { + let _v0: |&mut u8| has copy + drop = |arg0| test1(arg0); + let _v1: |&mut u8| has copy + drop = |arg0| test2(arg0); + let _v2: |&mut u8| has copy + drop = |arg0| test3(arg0); + let _v3 = 0x1::vector::empty<|&mut u8| has copy + drop + store>(); + let _v4 = &mut _v3; + 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v0); + 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v1); + 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v2); + let _v5 = VecWrapper<|&mut u8| has copy + drop + store>{fvs: _v3}; + move_to>(p0, _v5); + } + #[persistent] + fun test1(p0: &mut u8) { + *p0 = *p0 + 1u8; + } + #[persistent] + fun test2(p0: &mut u8) { + *p0 = *p0 + 2u8; + } + #[persistent] + fun test3(p0: &mut u8) { + *p0 = *p0 + 3u8; + } +} + + +//# run 0x42::mod3::test_items --signers 0x42 --args true + +//# run 0x42::mod3::test_items --signers 0x42 --args false + +//# run 0x42::mod4::initialize --signers 0x42 + +//# run 0x42::mod4::check_exists --signers 0x42 + +//# run 0x42::mod5::initialize --signers 0x42 + +//# run 0x42::mod5::check_exists --signers 0x42 + +//# run 0x42::mod6::initialize --signers 0x42 + +//# run 0x42::mod6::compute --signers 0x42 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled.baseline.exp new file mode 100644 index 00000000000..ca2ed3efc11 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/funs_as_storage_key.decompiled.baseline.exp @@ -0,0 +1,85 @@ +processed 13 tasks +task 0 lines 3-26: publish [module 0x42::mod2 {] +task 1 lines 29-57: publish [module 0x42::mod3 {] +task 2 lines 60-76: publish [module 0x42::mod4 {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE2:65:22 + │ +65 │ fun check_exists(p0: &signer) { + │ ^^ + +warning: Unused value of parameter `p1`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p1`), or binding to `_` + ┌─ TEMPFILE2:73:24 + │ +73 │ fun test(p0: &u64, p1: &mut u8): &u64 { + │ ^^ + + +task 3 lines 79-98: publish [module 0x42::mod5 {] +Error: compilation errors: + error: type `|&u64, &mut u8|&u64 has copy + drop` is missing required ability `store` + ┌─ TEMPFILE3:90:89 + │ +90 │ 0x1::vector::push_back<|&u64, &mut u8|(&u64) has copy + drop + store>(&mut _v1, _v0); + │ ^^^ + + +task 4 lines 101-149: publish [module 0x42::mod6 {] +Error: compilation errors: + error: type `|&mut u8| has copy + drop` is missing required ability `store` + ┌─ TEMPFILE4:131:72 + │ +131 │ 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v0); + │ ^^^ + +error: type `|&mut u8| has copy + drop` is missing required ability `store` + ┌─ TEMPFILE4:132:72 + │ +132 │ 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v1); + │ ^^^ + +error: type `|&mut u8| has copy + drop` is missing required ability `store` + ┌─ TEMPFILE4:133:72 + │ +133 │ 0x1::vector::push_back<|&mut u8| has copy + drop + store>(_v4, _v2); + │ ^^^ + + +task 5 lines 152-152: run 0x42::mod3::test_items --signers 0x42 --args true +return values: true +task 6 lines 154-154: run 0x42::mod3::test_items --signers 0x42 --args false +return values: true +task 7 lines 156-156: run 0x42::mod4::initialize --signers 0x42 +task 8 lines 158-158: run 0x42::mod4::check_exists --signers 0x42 +task 9 lines 160-160: run 0x42::mod5::initialize --signers 0x42 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 10 lines 162-162: run 0x42::mod5::check_exists --signers 0x42 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 11 lines 164-164: run 0x42::mod6::initialize --signers 0x42 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 12 lines 166-166: run 0x42::mod6::compute --signers 0x42 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled new file mode 100644 index 00000000000..4fdb0ba287c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled @@ -0,0 +1,122 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/fv_enum.move` + +//# publish +module 0x66::fv_enum_basic { + use 0x1::signer; + enum Action has drop { + Noop, + Call { + _0: |u64|(u64) has drop, + } + } + enum FunVec has key { + V1 { + v1: vector<|&mut T0|(T0) has copy + store>, + } + V2 { + v0: u64, + v1: vector<|&mut T0|(T0) has copy + store>, + } + } + enum Mapper has key { + Id { + _0: |T0|(T1) has copy + store, + } + Twice { + _0: Version, + } + } + enum Version has copy, store { + V1 { + v1: |T0|(T1) has copy + store, + } + } + #[persistent] + fun add_k_persistent(p0: u64, p1: u64): u64 { + p0 + p1 + } + #[persistent] + fun add_k_persistent_ref(p0: &mut u64, p1: u64): u64 { + *p0 = *p0 + 1; + *p0 + p1 + } + fun call_square(p0: u64) { + let _v0; + let _v1 = Action::Call{_0: |arg0| square(arg0)}; + if (&_v1 is Call) { + let Action::Call{_0: _v2} = _v1; + _v0 = _v2(p0) + } else _v0 = 0; + assert!(_v0 == 49, 14566554180833181696); + } + fun square(p0: u64): u64 { + p0 * p0 + } + fun test_enum_in_another_enum(p0: &signer) + acquires Mapper + { + let _v0; + let _v1 = Mapper::Twice{_0: Version::V1{v1: |arg0| add_k_persistent(arg0, 3)}}; + move_to>(p0, _v1); + let _v2 = signer::address_of(p0); + let _v3 = borrow_global>(_v2); + if (_v3 is Twice) { + let _v4 = &_v3._0; + let _v5 = *&_v4.v1; + let _v6 = _v5(10); + let _v7 = *&_v4.v1; + _v0 = _v7(_v6) + } else if (_v3 is Id) { + let _v8 = *&_v3._0; + _v0 = _v8(10) + } else abort 14566554180833181697; + assert!(_v0 == 16, 99); + } + fun test_fun_vec(p0: &signer) + acquires FunVec + { + let _v0: |&mut u64|(u64) has copy + drop + store = |arg0| add_k_persistent_ref(arg0, 3); + let _v1 = 0x1::vector::empty<|&mut u64|(u64) has copy + store>(); + let _v2 = &mut _v1; + 0x1::vector::push_back<|&mut u64|(u64) has copy + store>(_v2, _v0); + 0x1::vector::push_back<|&mut u64|(u64) has copy + store>(_v2, _v0); + let _v3 = FunVec::V1{v1: _v1}; + move_to>(p0, _v3); + let _v4 = signer::address_of(p0); + let _v5 = move_from>(_v4); + let _v6 = &_v5; + 'l0: loop { + let _v7; + let _v8; + loop { + if (_v6 is V1) { + let FunVec::V1{v1: _v9} = _v5; + _v8 = _v9; + _v7 = 0x1::vector::pop_back<|&mut u64|(u64) has copy + store>(&mut _v8); + let _v10 = 3; + let _v11 = &mut _v10; + let _v12 = _v7(_v11); + assert!(_v10 == 4, 0); + if (_v12 == 7) break; + abort 1 + }; + assert!(_v6 is V2, 14566554180833181697); + let FunVec::V2{v0: _v13, v1: _v14} = _v5; + 0x1::vector::destroy_empty<|&mut u64|(u64) has copy + store>(_v14); + if (false) break 'l0; + abort 2 + }; + 0x1::vector::push_back<|&mut u64|(u64) has copy + store>(&mut _v8, _v7); + _v3 = FunVec::V2{v0: 10, v1: _v8}; + move_to>(p0, _v3); + return () + }; + } +} + + +//# run 0x66::fv_enum_basic::call_square --args 7 + +//# run 0x66::fv_enum_basic::test_enum_in_another_enum --signers 0x66 + +//# run 0x66::fv_enum_basic::test_fun_vec --signers 0x66 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled.baseline.exp new file mode 100644 index 00000000000..895285878c5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/fv_enum.decompiled.baseline.exp @@ -0,0 +1,44 @@ +processed 4 tasks +task 0 lines 3-115: publish [module 0x66::fv_enum_basic {] +Error: compilation errors: + error: cannot select field `_0` since it has different types in variants of enum `Mapper` + ┌─ TEMPFILE:64:24 + │ +64 │ let _v4 = &_v3._0; + │ ^^^ + │ + = field `_0` has type `Version` in variant `Twice` and type `|u64|u64 has copy + store` in variant `Id` + +error: cannot select field `_0` since it has different types in variants of enum `Mapper` + ┌─ TEMPFILE:70:25 + │ +70 │ let _v8 = *&_v3._0; + │ ^^^ + │ + = field `_0` has type `Version` in variant `Twice` and type `|u64|u64 has copy + store` in variant `Id` + + +task 1 lines 118-118: run 0x66::fv_enum_basic::call_square --args 7 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 120-120: run 0x66::fv_enum_basic::test_enum_in_another_enum --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 3 lines 122-122: run 0x66::fv_enum_basic::test_fun_vec --signers 0x66 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled new file mode 100644 index 00000000000..c7d2f083072 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/many_arguments.move` + +//# publish +module 0xc0ffee::m { + fun takes_65_args(p0: u64, p1: u64, p2: u64, p3: u64, p4: u64, p5: u64, p6: u64, p7: u64, p8: u64, p9: u64, p10: u64, p11: u64, p12: u64, p13: u64, p14: u64, p15: u64, p16: u64, p17: u64, p18: u64, p19: u64, p20: u64, p21: u64, p22: u64, p23: u64, p24: u64, p25: u64, p26: u64, p27: u64, p28: u64, p29: u64, p30: u64, p31: u64, p32: u64, p33: u64, p34: u64, p35: u64, p36: u64, p37: u64, p38: u64, p39: u64, p40: u64, p41: u64, p42: u64, p43: u64, p44: u64, p45: u64, p46: u64, p47: u64, p48: u64, p49: u64, p50: u64, p51: u64, p52: u64, p53: u64, p54: u64, p55: u64, p56: u64, p57: u64, p58: u64, p59: u64, p60: u64, p61: u64, p62: u64, p63: u64, p64: u64): u64 { + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23 + p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31 + p32 + p33 + p34 + p35 + p36 + p37 + p38 + p39 + p40 + p41 + p42 + p43 + p44 + p45 + p46 + p47 + p48 + p49 + p50 + p51 + p52 + p53 + p54 + p55 + p56 + p57 + p58 + p59 + p60 + p61 + p62 + p63 + p64 + } + public fun test(): u64 { + let _v0: ||u64 has copy + drop = || lambda__1__test(); + _v0() + } + fun lambda__1__test(): u64 { + takes_65_args(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled.baseline.exp new file mode 100644 index 00000000000..266b4134f8d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/many_arguments.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test +return values: 2145 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled new file mode 100644 index 00000000000..86041752408 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled @@ -0,0 +1,1142 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/misc_1.move` + +//# publish +module 0xc0ffee::m { + use 0x1::bcs; + #[persistent] + fun bar() { + () + } + public fun foo() { + () + } + public fun test1(): bool { + let _v0: ||(u64) has drop = || lambda__1__test1(1, 2); + let _v1 = bcs::to_bytes<||(u64) has drop>(&_v0); + true + } + fun lambda__1__test1(p0: u64, p1: u64): u64 { + p0 + p1 + 1 + } + public fun test2() { + let _v0: || has drop = || foo(); + let _v1: || has drop = || bar(); + let _v2 = bcs::to_bytes<|| has drop>(&_v0); + let _v3 = bcs::to_bytes<|| has drop>(&_v1); + assert!(_v2 != _v3, 1); + } + public fun test3() { + let _v0: || has drop = || foo(); + let _v1 = bcs::to_bytes<|| has drop>(&_v0); + let _v2 = bcs::to_bytes<|| has drop>(&_v0); + assert!(_v1 == _v2, 2); + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 + +//# publish +module 0xc0ffee::n { + public fun test(p0: u64): u64 { + let _v0: ||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))) has copy + drop = || lambda__11__test(); + let _v1 = |arg0| lambda__12__test(_v0, arg0); + let _v2: ||u64|(u64)|u64 has copy + drop = |arg0| lambda__13__test(p0, arg0); + let _v3 = |arg0,arg1| lambda__14__test(arg0, arg1); + _v3(_v2, _v1) + } + fun lambda__11__test(): ||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))) { + || lambda__10__test() + } + fun lambda__12__test(p0: ||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))), p1: u64): u64 { + let _v0 = p0(); + let _v1 = _v0(); + let _v2 = _v1(); + let _v3 = _v2(); + let _v4 = _v3(); + let _v5 = _v4(); + let _v6 = _v5(); + let _v7 = _v6(); + let _v8 = _v7(); + let _v9 = _v8(); + _v9(p1) + } + fun lambda__13__test(p0: u64, p1: |u64|(u64)): u64 { + p1(p0) + } + fun lambda__14__test(p0: ||u64|(u64)|(u64), p1: |u64|(u64)): u64 { + p0(p1) + } + fun lambda__1__test(p0: u64): u64 { + p0 + } + fun lambda__2__test(): |u64|(u64) { + |arg0| lambda__1__test(arg0) + } + fun lambda__3__test(): ||(|u64|(u64)) { + || lambda__2__test() + } + fun lambda__4__test(): ||(||(|u64|(u64))) { + || lambda__3__test() + } + fun lambda__5__test(): ||(||(||(|u64|(u64)))) { + || lambda__4__test() + } + fun lambda__6__test(): ||(||(||(||(|u64|(u64))))) { + || lambda__5__test() + } + fun lambda__7__test(): ||(||(||(||(||(|u64|(u64)))))) { + || lambda__6__test() + } + fun lambda__8__test(): ||(||(||(||(||(||(|u64|(u64))))))) { + || lambda__7__test() + } + fun lambda__9__test(): ||(||(||(||(||(||(||(|u64|(u64)))))))) { + || lambda__8__test() + } + fun lambda__10__test(): ||(||(||(||(||(||(||(||(|u64|(u64))))))))) { + || lambda__9__test() + } +} + + +//# run 0xc0ffee::n::test --args 42 + +//# publish +module 0xc0ffee::o { + public fun test(p0: u64): u64 { + let _v0: ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) has copy + drop = || lambda__254__test(); + let _v1 = |arg0| lambda__255__test(_v0, arg0); + let _v2: ||u64|(u64)|u64 has copy + drop = |arg0| lambda__256__test(p0, arg0); + let _v3 = |arg0,arg1| lambda__257__test(arg0, arg1); + _v3(_v2, _v1) + } + fun lambda__254__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__253__test() + } + fun lambda__255__test(p0: ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))), p1: u64): u64 { + let _v0 = p0(); + let _v1 = _v0(); + let _v2 = _v1(); + let _v3 = _v2(); + let _v4 = _v3(); + let _v5 = _v4(); + let _v6 = _v5(); + let _v7 = _v6(); + let _v8 = _v7(); + let _v9 = _v8(); + let _v10 = _v9(); + let _v11 = _v10(); + let _v12 = _v11(); + let _v13 = _v12(); + let _v14 = _v13(); + let _v15 = _v14(); + let _v16 = _v15(); + let _v17 = _v16(); + let _v18 = _v17(); + let _v19 = _v18(); + let _v20 = _v19(); + let _v21 = _v20(); + let _v22 = _v21(); + let _v23 = _v22(); + let _v24 = _v23(); + let _v25 = _v24(); + let _v26 = _v25(); + let _v27 = _v26(); + let _v28 = _v27(); + let _v29 = _v28(); + let _v30 = _v29(); + let _v31 = _v30(); + let _v32 = _v31(); + let _v33 = _v32(); + let _v34 = _v33(); + let _v35 = _v34(); + let _v36 = _v35(); + let _v37 = _v36(); + let _v38 = _v37(); + let _v39 = _v38(); + let _v40 = _v39(); + let _v41 = _v40(); + let _v42 = _v41(); + let _v43 = _v42(); + let _v44 = _v43(); + let _v45 = _v44(); + let _v46 = _v45(); + let _v47 = _v46(); + let _v48 = _v47(); + let _v49 = _v48(); + let _v50 = _v49(); + let _v51 = _v50(); + let _v52 = _v51(); + let _v53 = _v52(); + let _v54 = _v53(); + let _v55 = _v54(); + let _v56 = _v55(); + let _v57 = _v56(); + let _v58 = _v57(); + let _v59 = _v58(); + let _v60 = _v59(); + let _v61 = _v60(); + let _v62 = _v61(); + let _v63 = _v62(); + let _v64 = _v63(); + let _v65 = _v64(); + let _v66 = _v65(); + let _v67 = _v66(); + let _v68 = _v67(); + let _v69 = _v68(); + let _v70 = _v69(); + let _v71 = _v70(); + let _v72 = _v71(); + let _v73 = _v72(); + let _v74 = _v73(); + let _v75 = _v74(); + let _v76 = _v75(); + let _v77 = _v76(); + let _v78 = _v77(); + let _v79 = _v78(); + let _v80 = _v79(); + let _v81 = _v80(); + let _v82 = _v81(); + let _v83 = _v82(); + let _v84 = _v83(); + let _v85 = _v84(); + let _v86 = _v85(); + let _v87 = _v86(); + let _v88 = _v87(); + let _v89 = _v88(); + let _v90 = _v89(); + let _v91 = _v90(); + let _v92 = _v91(); + let _v93 = _v92(); + let _v94 = _v93(); + let _v95 = _v94(); + let _v96 = _v95(); + let _v97 = _v96(); + let _v98 = _v97(); + let _v99 = _v98(); + let _v100 = _v99(); + let _v101 = _v100(); + let _v102 = _v101(); + let _v103 = _v102(); + let _v104 = _v103(); + let _v105 = _v104(); + let _v106 = _v105(); + let _v107 = _v106(); + let _v108 = _v107(); + let _v109 = _v108(); + let _v110 = _v109(); + let _v111 = _v110(); + let _v112 = _v111(); + let _v113 = _v112(); + let _v114 = _v113(); + let _v115 = _v114(); + let _v116 = _v115(); + let _v117 = _v116(); + let _v118 = _v117(); + let _v119 = _v118(); + let _v120 = _v119(); + let _v121 = _v120(); + let _v122 = _v121(); + let _v123 = _v122(); + let _v124 = _v123(); + let _v125 = _v124(); + let _v126 = _v125(); + let _v127 = _v126(); + let _v128 = _v127(); + let _v129 = _v128(); + let _v130 = _v129(); + let _v131 = _v130(); + let _v132 = _v131(); + let _v133 = _v132(); + let _v134 = _v133(); + let _v135 = _v134(); + let _v136 = _v135(); + let _v137 = _v136(); + let _v138 = _v137(); + let _v139 = _v138(); + let _v140 = _v139(); + let _v141 = _v140(); + let _v142 = _v141(); + let _v143 = _v142(); + let _v144 = _v143(); + let _v145 = _v144(); + let _v146 = _v145(); + let _v147 = _v146(); + let _v148 = _v147(); + let _v149 = _v148(); + let _v150 = _v149(); + let _v151 = _v150(); + let _v152 = _v151(); + let _v153 = _v152(); + let _v154 = _v153(); + let _v155 = _v154(); + let _v156 = _v155(); + let _v157 = _v156(); + let _v158 = _v157(); + let _v159 = _v158(); + let _v160 = _v159(); + let _v161 = _v160(); + let _v162 = _v161(); + let _v163 = _v162(); + let _v164 = _v163(); + let _v165 = _v164(); + let _v166 = _v165(); + let _v167 = _v166(); + let _v168 = _v167(); + let _v169 = _v168(); + let _v170 = _v169(); + let _v171 = _v170(); + let _v172 = _v171(); + let _v173 = _v172(); + let _v174 = _v173(); + let _v175 = _v174(); + let _v176 = _v175(); + let _v177 = _v176(); + let _v178 = _v177(); + let _v179 = _v178(); + let _v180 = _v179(); + let _v181 = _v180(); + let _v182 = _v181(); + let _v183 = _v182(); + let _v184 = _v183(); + let _v185 = _v184(); + let _v186 = _v185(); + let _v187 = _v186(); + let _v188 = _v187(); + let _v189 = _v188(); + let _v190 = _v189(); + let _v191 = _v190(); + let _v192 = _v191(); + let _v193 = _v192(); + let _v194 = _v193(); + let _v195 = _v194(); + let _v196 = _v195(); + let _v197 = _v196(); + let _v198 = _v197(); + let _v199 = _v198(); + let _v200 = _v199(); + let _v201 = _v200(); + let _v202 = _v201(); + let _v203 = _v202(); + let _v204 = _v203(); + let _v205 = _v204(); + let _v206 = _v205(); + let _v207 = _v206(); + let _v208 = _v207(); + let _v209 = _v208(); + let _v210 = _v209(); + let _v211 = _v210(); + let _v212 = _v211(); + let _v213 = _v212(); + let _v214 = _v213(); + let _v215 = _v214(); + let _v216 = _v215(); + let _v217 = _v216(); + let _v218 = _v217(); + let _v219 = _v218(); + let _v220 = _v219(); + let _v221 = _v220(); + let _v222 = _v221(); + let _v223 = _v222(); + let _v224 = _v223(); + let _v225 = _v224(); + let _v226 = _v225(); + let _v227 = _v226(); + let _v228 = _v227(); + let _v229 = _v228(); + let _v230 = _v229(); + let _v231 = _v230(); + let _v232 = _v231(); + let _v233 = _v232(); + let _v234 = _v233(); + let _v235 = _v234(); + let _v236 = _v235(); + let _v237 = _v236(); + let _v238 = _v237(); + let _v239 = _v238(); + let _v240 = _v239(); + let _v241 = _v240(); + let _v242 = _v241(); + let _v243 = _v242(); + let _v244 = _v243(); + let _v245 = _v244(); + let _v246 = _v245(); + let _v247 = _v246(); + let _v248 = _v247(); + let _v249 = _v248(); + let _v250 = _v249(); + let _v251 = _v250(); + let _v252 = _v251(); + _v252(p1) + } + fun lambda__256__test(p0: u64, p1: |u64|(u64)): u64 { + p1(p0) + } + fun lambda__257__test(p0: ||u64|(u64)|(u64), p1: |u64|(u64)): u64 { + p0(p1) + } + fun lambda__1__test(p0: u64): u64 { + p0 + } + fun lambda__2__test(): |u64|(u64) { + |arg0| lambda__1__test(arg0) + } + fun lambda__3__test(): ||(|u64|(u64)) { + || lambda__2__test() + } + fun lambda__4__test(): ||(||(|u64|(u64))) { + || lambda__3__test() + } + fun lambda__5__test(): ||(||(||(|u64|(u64)))) { + || lambda__4__test() + } + fun lambda__6__test(): ||(||(||(||(|u64|(u64))))) { + || lambda__5__test() + } + fun lambda__7__test(): ||(||(||(||(||(|u64|(u64)))))) { + || lambda__6__test() + } + fun lambda__8__test(): ||(||(||(||(||(||(|u64|(u64))))))) { + || lambda__7__test() + } + fun lambda__9__test(): ||(||(||(||(||(||(||(|u64|(u64)))))))) { + || lambda__8__test() + } + fun lambda__10__test(): ||(||(||(||(||(||(||(||(|u64|(u64))))))))) { + || lambda__9__test() + } + fun lambda__11__test(): ||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))) { + || lambda__10__test() + } + fun lambda__12__test(): ||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))) { + || lambda__11__test() + } + fun lambda__13__test(): ||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))) { + || lambda__12__test() + } + fun lambda__14__test(): ||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))) { + || lambda__13__test() + } + fun lambda__15__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))) { + || lambda__14__test() + } + fun lambda__16__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))) { + || lambda__15__test() + } + fun lambda__17__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))) { + || lambda__16__test() + } + fun lambda__18__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))) { + || lambda__17__test() + } + fun lambda__19__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))) { + || lambda__18__test() + } + fun lambda__20__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))) { + || lambda__19__test() + } + fun lambda__21__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))) { + || lambda__20__test() + } + fun lambda__22__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))) { + || lambda__21__test() + } + fun lambda__23__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))) { + || lambda__22__test() + } + fun lambda__24__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))) { + || lambda__23__test() + } + fun lambda__25__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))) { + || lambda__24__test() + } + fun lambda__26__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))) { + || lambda__25__test() + } + fun lambda__27__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))) { + || lambda__26__test() + } + fun lambda__28__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))) { + || lambda__27__test() + } + fun lambda__29__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))) { + || lambda__28__test() + } + fun lambda__30__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))) { + || lambda__29__test() + } + fun lambda__31__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))) { + || lambda__30__test() + } + fun lambda__32__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))) { + || lambda__31__test() + } + fun lambda__33__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))) { + || lambda__32__test() + } + fun lambda__34__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))) { + || lambda__33__test() + } + fun lambda__35__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))) { + || lambda__34__test() + } + fun lambda__36__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))) { + || lambda__35__test() + } + fun lambda__37__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))) { + || lambda__36__test() + } + fun lambda__38__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))) { + || lambda__37__test() + } + fun lambda__39__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))) { + || lambda__38__test() + } + fun lambda__40__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))) { + || lambda__39__test() + } + fun lambda__41__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))) { + || lambda__40__test() + } + fun lambda__42__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))) { + || lambda__41__test() + } + fun lambda__43__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))) { + || lambda__42__test() + } + fun lambda__44__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))) { + || lambda__43__test() + } + fun lambda__45__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))) { + || lambda__44__test() + } + fun lambda__46__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__45__test() + } + fun lambda__47__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__46__test() + } + fun lambda__48__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__47__test() + } + fun lambda__49__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__48__test() + } + fun lambda__50__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__49__test() + } + fun lambda__51__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__50__test() + } + fun lambda__52__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__51__test() + } + fun lambda__53__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__52__test() + } + fun lambda__54__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__53__test() + } + fun lambda__55__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__54__test() + } + fun lambda__56__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__55__test() + } + fun lambda__57__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__56__test() + } + fun lambda__58__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__57__test() + } + fun lambda__59__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__58__test() + } + fun lambda__60__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__59__test() + } + fun lambda__61__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__60__test() + } + fun lambda__62__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__61__test() + } + fun lambda__63__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__62__test() + } + fun lambda__64__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__63__test() + } + fun lambda__65__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__64__test() + } + fun lambda__66__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__65__test() + } + fun lambda__67__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__66__test() + } + fun lambda__68__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__67__test() + } + fun lambda__69__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__68__test() + } + fun lambda__70__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__69__test() + } + fun lambda__71__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__70__test() + } + fun lambda__72__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__71__test() + } + fun lambda__73__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__72__test() + } + fun lambda__74__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__73__test() + } + fun lambda__75__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__74__test() + } + fun lambda__76__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__75__test() + } + fun lambda__77__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__76__test() + } + fun lambda__78__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__77__test() + } + fun lambda__79__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__78__test() + } + fun lambda__80__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__79__test() + } + fun lambda__81__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__80__test() + } + fun lambda__82__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__81__test() + } + fun lambda__83__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__82__test() + } + fun lambda__84__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__83__test() + } + fun lambda__85__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__84__test() + } + fun lambda__86__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__85__test() + } + fun lambda__87__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__86__test() + } + fun lambda__88__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__87__test() + } + fun lambda__89__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__88__test() + } + fun lambda__90__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__89__test() + } + fun lambda__91__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__90__test() + } + fun lambda__92__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__91__test() + } + fun lambda__93__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__92__test() + } + fun lambda__94__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__93__test() + } + fun lambda__95__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__94__test() + } + fun lambda__96__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__95__test() + } + fun lambda__97__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__96__test() + } + fun lambda__98__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__97__test() + } + fun lambda__99__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__98__test() + } + fun lambda__100__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__99__test() + } + fun lambda__101__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__100__test() + } + fun lambda__102__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__101__test() + } + fun lambda__103__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__102__test() + } + fun lambda__104__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__103__test() + } + fun lambda__105__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__104__test() + } + fun lambda__106__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__105__test() + } + fun lambda__107__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__106__test() + } + fun lambda__108__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__107__test() + } + fun lambda__109__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__108__test() + } + fun lambda__110__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__109__test() + } + fun lambda__111__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__110__test() + } + fun lambda__112__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__111__test() + } + fun lambda__113__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__112__test() + } + fun lambda__114__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__113__test() + } + fun lambda__115__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__114__test() + } + fun lambda__116__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__115__test() + } + fun lambda__117__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__116__test() + } + fun lambda__118__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__117__test() + } + fun lambda__119__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__118__test() + } + fun lambda__120__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__119__test() + } + fun lambda__121__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__120__test() + } + fun lambda__122__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__121__test() + } + fun lambda__123__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__122__test() + } + fun lambda__124__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__123__test() + } + fun lambda__125__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__124__test() + } + fun lambda__126__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__125__test() + } + fun lambda__127__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__126__test() + } + fun lambda__128__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__127__test() + } + fun lambda__129__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__128__test() + } + fun lambda__130__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__129__test() + } + fun lambda__131__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__130__test() + } + fun lambda__132__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__131__test() + } + fun lambda__133__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__132__test() + } + fun lambda__134__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__133__test() + } + fun lambda__135__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__134__test() + } + fun lambda__136__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__135__test() + } + fun lambda__137__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__136__test() + } + fun lambda__138__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__137__test() + } + fun lambda__139__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__138__test() + } + fun lambda__140__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__139__test() + } + fun lambda__141__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__140__test() + } + fun lambda__142__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__141__test() + } + fun lambda__143__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__142__test() + } + fun lambda__144__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__143__test() + } + fun lambda__145__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__144__test() + } + fun lambda__146__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__145__test() + } + fun lambda__147__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__146__test() + } + fun lambda__148__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__147__test() + } + fun lambda__149__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__148__test() + } + fun lambda__150__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__149__test() + } + fun lambda__151__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__150__test() + } + fun lambda__152__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__151__test() + } + fun lambda__153__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__152__test() + } + fun lambda__154__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__153__test() + } + fun lambda__155__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__154__test() + } + fun lambda__156__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__155__test() + } + fun lambda__157__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__156__test() + } + fun lambda__158__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__157__test() + } + fun lambda__159__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__158__test() + } + fun lambda__160__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__159__test() + } + fun lambda__161__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__160__test() + } + fun lambda__162__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__161__test() + } + fun lambda__163__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__162__test() + } + fun lambda__164__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__163__test() + } + fun lambda__165__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__164__test() + } + fun lambda__166__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__165__test() + } + fun lambda__167__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__166__test() + } + fun lambda__168__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__167__test() + } + fun lambda__169__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__168__test() + } + fun lambda__170__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__169__test() + } + fun lambda__171__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__170__test() + } + fun lambda__172__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__171__test() + } + fun lambda__173__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__172__test() + } + fun lambda__174__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__173__test() + } + fun lambda__175__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__174__test() + } + fun lambda__176__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__175__test() + } + fun lambda__177__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__176__test() + } + fun lambda__178__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__177__test() + } + fun lambda__179__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__178__test() + } + fun lambda__180__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__179__test() + } + fun lambda__181__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__180__test() + } + fun lambda__182__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__181__test() + } + fun lambda__183__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__182__test() + } + fun lambda__184__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__183__test() + } + fun lambda__185__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__184__test() + } + fun lambda__186__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__185__test() + } + fun lambda__187__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__186__test() + } + fun lambda__188__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__187__test() + } + fun lambda__189__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__188__test() + } + fun lambda__190__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__189__test() + } + fun lambda__191__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__190__test() + } + fun lambda__192__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__191__test() + } + fun lambda__193__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__192__test() + } + fun lambda__194__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__193__test() + } + fun lambda__195__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__194__test() + } + fun lambda__196__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__195__test() + } + fun lambda__197__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__196__test() + } + fun lambda__198__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__197__test() + } + fun lambda__199__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__198__test() + } + fun lambda__200__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__199__test() + } + fun lambda__201__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__200__test() + } + fun lambda__202__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__201__test() + } + fun lambda__203__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__202__test() + } + fun lambda__204__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__203__test() + } + fun lambda__205__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__204__test() + } + fun lambda__206__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__205__test() + } + fun lambda__207__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__206__test() + } + fun lambda__208__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__207__test() + } + fun lambda__209__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__208__test() + } + fun lambda__210__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__209__test() + } + fun lambda__211__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__210__test() + } + fun lambda__212__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__211__test() + } + fun lambda__213__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__212__test() + } + fun lambda__214__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__213__test() + } + fun lambda__215__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__214__test() + } + fun lambda__216__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__215__test() + } + fun lambda__217__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__216__test() + } + fun lambda__218__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__217__test() + } + fun lambda__219__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__218__test() + } + fun lambda__220__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__219__test() + } + fun lambda__221__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__220__test() + } + fun lambda__222__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__221__test() + } + fun lambda__223__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__222__test() + } + fun lambda__224__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__223__test() + } + fun lambda__225__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__224__test() + } + fun lambda__226__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__225__test() + } + fun lambda__227__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__226__test() + } + fun lambda__228__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__227__test() + } + fun lambda__229__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__228__test() + } + fun lambda__230__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__229__test() + } + fun lambda__231__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__230__test() + } + fun lambda__232__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__231__test() + } + fun lambda__233__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__232__test() + } + fun lambda__234__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__233__test() + } + fun lambda__235__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__234__test() + } + fun lambda__236__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__235__test() + } + fun lambda__237__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__236__test() + } + fun lambda__238__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__237__test() + } + fun lambda__239__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__238__test() + } + fun lambda__240__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__239__test() + } + fun lambda__241__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__240__test() + } + fun lambda__242__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__241__test() + } + fun lambda__243__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__242__test() + } + fun lambda__244__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__243__test() + } + fun lambda__245__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__244__test() + } + fun lambda__246__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__245__test() + } + fun lambda__247__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__246__test() + } + fun lambda__248__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__247__test() + } + fun lambda__249__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__248__test() + } + fun lambda__250__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__249__test() + } + fun lambda__251__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__250__test() + } + fun lambda__252__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__251__test() + } + fun lambda__253__test(): ||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(||(|u64|(u64)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { + || lambda__252__test() + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled.baseline.exp new file mode 100644 index 00000000000..0e8e4aa3872 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/misc_1.decompiled.baseline.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 3-34: publish [module 0xc0ffee::m {] +task 1 lines 37-37: run 0xc0ffee::m::test1 +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(453), + location: 0x1::bcs, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 2 lines 39-39: run 0xc0ffee::m::test2 +task 3 lines 41-41: run 0xc0ffee::m::test3 +task 4 lines 43-104: publish [module 0xc0ffee::n {] +Error: compilation errors: + error: unexpected token + ┌─ TEMPFILE1:48:23 + │ +48 │ let _v2: ||u64|(u64)|u64 has copy + drop = |arg0| lambda__13__test(p0, arg0); + │ ^ + │ │ + │ Unexpected '|' + │ Expected ';' + + +task 5 lines 107-107: run 0xc0ffee::n::test --args 42 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 6 lines 109-1142: publish [module 0xc0ffee::o {] +Error: compilation errors: + error: unexpected token + ┌─ TEMPFILE2:114:23 + │ +114 │ let _v2: ||u64|(u64)|u64 has copy + drop = |arg0| lambda__256__test(p0, arg0); + │ ^ + │ │ + │ Unexpected '|' + │ Expected ';' + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled new file mode 100644 index 00000000000..afd62de8995 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled @@ -0,0 +1,73 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/more_nested.move` + +//# publish +module 0xc0ffee::n { + fun create_adder(p0: u64): |u64|(|u64|(u64)) has copy { + |arg0| lambda__2__create_adder(p0, arg0) + } + fun lambda__2__create_adder(p0: u64, p1: u64): |u64|(u64) { + |arg0| lambda__1__create_adder(p0, p1, arg0) + } + fun create_multiplier(p0: u64): |u64|(|u64|(u64)) has copy { + |arg0| lambda__2__create_multiplier(p0, arg0) + } + fun lambda__2__create_multiplier(p0: u64, p1: u64): |u64|(u64) { + |arg0| lambda__1__create_multiplier(p0, p1, arg0) + } + fun test_composed_captures() { + let _v0: |u64|(|u64|(u64)) has copy + drop = |arg0| lambda__2__test_composed_captures(2, arg0); + let _v1: |u64|(|u64|(u64)) has copy + drop = |arg0| lambda__4__test_composed_captures(2, arg0); + let _v2 = |arg0| lambda__6__test_composed_captures(_v0, _v1, arg0); + let _v3 = _v2(3); + assert!(_v3(4) == 54, 0); + } + fun lambda__2__test_composed_captures(p0: u64, p1: u64): |u64|(u64) { + |arg0| lambda__1__test_composed_captures(p0, p1, arg0) + } + fun lambda__4__test_composed_captures(p0: u64, p1: u64): |u64|(u64) { + |arg0| lambda__3__test_composed_captures(p0, p1, arg0) + } + fun lambda__6__test_composed_captures(p0: |u64|(|u64|(u64)), p1: |u64|(|u64|(u64)), p2: u64): |u64|(u64) { + |arg0| lambda__5__test_composed_captures(p2, p0, p1, arg0) + } + fun test_nested_functions() { + let _v0 = create_adder(10); + let _v1 = _v0(5); + assert!(_v1(3) == 18, 0); + _v0 = create_multiplier(2); + _v1 = _v0(3); + assert!(_v1(4) == 24, 1); + let _v2 = |arg0| lambda__2__test_nested_functions(5, 3, arg0); + _v1 = _v2(2); + assert!(_v1(4) == 120, 2); + } + fun lambda__2__test_nested_functions(p0: u64, p1: u64, p2: u64): |u64|(u64) { + |arg0| lambda__1__test_nested_functions(p2, p0, p1, arg0) + } + fun lambda__1__create_adder(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + fun lambda__1__create_multiplier(p0: u64, p1: u64, p2: u64): u64 { + p0 * p1 * p2 + } + fun lambda__1__test_composed_captures(p0: u64, p1: u64, p2: u64): u64 { + p0 * p1 * p2 + } + fun lambda__3__test_composed_captures(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + fun lambda__5__test_composed_captures(p0: u64, p1: |u64|(|u64|(u64)), p2: |u64|(|u64|(u64)), p3: u64): u64 { + let _v0 = p2(p0); + let _v1 = _v0(p3); + let _v2 = p1(p0); + _v2(_v1) + } + fun lambda__1__test_nested_functions(p0: u64, p1: u64, p2: u64, p3: u64): u64 { + p1 * p2 * p0 * p3 + } +} + + +//# run 0xc0ffee::n::test_nested_functions + +//# run 0xc0ffee::n::test_composed_captures \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled.baseline.exp new file mode 100644 index 00000000000..8e561157d23 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/more_nested.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-68: publish [module 0xc0ffee::n {] +task 1 lines 71-71: run 0xc0ffee::n::test_nested_functions +task 2 lines 73-73: run 0xc0ffee::n::test_composed_captures diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled new file mode 100644 index 00000000000..eed5ea0c119 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled @@ -0,0 +1,3 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/mut_ref_downgrade.move` + +//# run 0xc0ffee::m::foo \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled.baseline.exp new file mode 100644 index 00000000000..422b2a7885a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/mut_ref_downgrade.decompiled.baseline.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 3-3: run 0xc0ffee::m::foo +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled new file mode 100644 index 00000000000..153748fbdb6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled @@ -0,0 +1,32 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/nested.move` + +//# publish +module 0x42::test { + public fun nested(p0: u64): u64 { + let _v0: |u64|u64 has copy + drop = |arg0| lambda__1__nested(p0, arg0); + let _v1 = |arg0,arg1| lambda__2__nested(arg0, arg1); + _v1(_v0, 1) + } + fun lambda__1__nested(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__2__nested(p0: |u64|(u64), p1: u64): u64 { + p0(p1) + } + public fun nested_capture(p0: u64): u64 { + let _v0: |u64|u64 has copy + drop = |arg0| lambda__1__nested_capture(p0, arg0); + let _v1 = |arg0| lambda__2__nested_capture(_v0, arg0); + _v1(1) + } + fun lambda__1__nested_capture(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun lambda__2__nested_capture(p0: |u64|(u64), p1: u64): u64 { + p0(p1) + } +} + + +//# run 0x42::test::nested --args 3 + +//# run 0x42::test::nested_capture --args 4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled.baseline.exp new file mode 100644 index 00000000000..0160eb51f29 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/nested.decompiled.baseline.exp @@ -0,0 +1,26 @@ +processed 3 tasks +task 0 lines 3-27: publish [module 0x42::test {] +Error: compilation errors: + error: cannot return `(|u64|u64, u64)` from a function with result type `(|u64|u64 has copy + drop, integer)` + ┌─ TEMPFILE:8:9 + │ +8 │ _v1(_v0, 1) + │ ^^^^^^^^^^^ + + +task 1 lines 30-30: run 0x42::test::nested --args 3 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 32-32: run 0x42::test::nested_capture --args 4 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled new file mode 100644 index 00000000000..517528071db --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/persistent.move` + +//# publish +module 0x66::test { + use 0x1::signer; + struct Work has store, key { + _0: ||(u64) has store, + } + entry fun exec(p0: &signer) + acquires Work + { + let _v0 = signer::address_of(p0); + let Work{_0: _v1} = move_from(_v0); + assert!(_v1() == 3, 14566554180833181696); + } + #[persistent] + fun should_be_storable(): u64 { + 3 + } + entry fun store(p0: &signer) { + let _v0 = Work{_0: || should_be_storable()}; + move_to(p0, _v0); + } +} + + +//# run 0x66::test::store --signers 0x66 + +//# run 0x66::test::exec --signers 0x66 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled.baseline.exp new file mode 100644 index 00000000000..eab47e5f55d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/persistent.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-24: publish [module 0x66::test {] +task 1 lines 27-27: run 0x66::test::store --signers 0x66 +task 2 lines 29-29: run 0x66::test::exec --signers 0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled new file mode 100644 index 00000000000..ea91a1241d8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled @@ -0,0 +1,66 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/protected_storage.move` + +//# publish +module 0x66::protected { + use 0x1::signer; + struct Entry has key { + _0: T0, + } + public fun create(p0: &signer, p1: T0) { + let _v0 = Entry{_0: p1}; + move_to>(p0, _v0); + } + public fun modify(p0: &signer, p1: |&mut T0|(T1)): T1 + acquires Entry + { + let _v0 = signer::address_of(p0); + let _v1 = &mut borrow_global_mut>(_v0)._0; + p1(_v1) + } + public fun read(p0: &signer, p1: |&T0|(T1)): T1 + acquires Entry + { + let _v0 = signer::address_of(p0); + let _v1 = &borrow_global>(_v0)._0; + p1(_v1) + } +} + + +//# publish +module 0x66::app { + use 0x66::protected; + struct Data has store { + _0: u64, + } + fun increment(p0: &signer): u64 { + let _v0: |&mut Data|u64 has copy + drop = |arg0| lambda__1__increment(arg0); + protected::modify(p0, _v0) + } + fun lambda__1__increment(p0: &mut Data): u64 { + let _v0 = *&p0._0; + let _v1 = &mut p0._0; + *_v1 = *_v1 + 1; + _v0 + } + fun init_module(p0: &signer) { + let _v0 = Data{_0: 0}; + protected::create(p0, _v0); + } + fun view(p0: &signer): u64 { + let _v0: |&Data|u64 has copy + drop = |arg0| lambda__1__view(arg0); + protected::read(p0, _v0) + } + fun lambda__1__view(p0: &Data): u64 { + *&p0._0 + } +} + + +//# run 0x66::app::init_module --signers 0x66 + +//# run 0x66::app::increment --signers 0x66 + +//# run 0x66::app::increment --signers 0x66 + +//# run 0x66::app::view --signers 0x66 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled.baseline.exp new file mode 100644 index 00000000000..f0e8d573568 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/protected_storage.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 6 tasks +task 0 lines 3-27: publish [module 0x66::protected {] +task 1 lines 30-57: publish [module 0x66::app {] +task 2 lines 60-60: run 0x66::app::init_module --signers 0x66 +task 3 lines 62-62: run 0x66::app::increment --signers 0x66 +return values: 0 +task 4 lines 64-64: run 0x66::app::increment --signers 0x66 +return values: 1 +task 5 lines 66-66: run 0x66::app::view --signers 0x66 +return values: 2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled new file mode 100644 index 00000000000..fc2b02e2157 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled @@ -0,0 +1,60 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/reentrancy.move` + +//# publish +module 0x42::callee { + public fun call_me(p0: &mut T0, p1: |&mut T0|) { + p1(p0); + } +} + + +//# publish +module 0x42::caller { + use 0x42::callee; + struct R has copy, drop, key { + count: u64, + } + fun init(p0: &signer) { + let _v0 = R{count: 0}; + move_to(p0, _v0); + } + fun callback_fails(): bool + acquires R + { + let _v0 = borrow_global_mut(@0x42); + let _v1: |&mut R| has copy + drop = |arg0| lambda__1__callback_fails(arg0); + callee::call_me(_v0, _v1); + let _v2 = &mut _v0.count; + *_v2 = *_v2 + 1; + assert!(*&_v0.count == 2, 14566554180833181696); + false + } + fun lambda__1__callback_fails(p0: &mut R) + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42).count; + *_v0 = *_v0 + 1; + } + fun callback_ok(): bool + acquires R + { + let _v0 = borrow_global_mut(@0x42); + let _v1: |&mut R| has copy + drop = |arg0| do_something(arg0); + callee::call_me(_v0, _v1); + let _v2 = &mut _v0.count; + *_v2 = *_v2 + 1; + assert!(*&_v0.count == 2, 14566554180833181696); + true + } + fun do_something(p0: &mut R) { + let _v0 = &mut p0.count; + *_v0 = *_v0 + 1; + } +} + + +//# run 0x42::caller::init --signers 0x42 + +//# run 0x42::caller::callback_ok + +//# run 0x42::caller::callback_fails --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled.baseline.exp new file mode 100644 index 00000000000..355c8fc74a5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy.decompiled.baseline.exp @@ -0,0 +1,23 @@ +processed 5 tasks +task 0 lines 3-8: publish [module 0x42::callee {] +task 1 lines 11-53: publish [module 0x42::caller {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE1:32:35 + │ +32 │ fun lambda__1__callback_fails(p0: &mut R) + │ ^^ + + +task 2 lines 56-56: run 0x42::caller::init --signers 0x42 +task 3 lines 58-58: run 0x42::caller::callback_ok +return values: true +task 4 lines 60-60: run 0x42::caller::callback_fails --verbose +Error: Function execution failed with VMError: { + message: Resource `0x42::caller::R` cannot be accessed because of active reentrancy of defining module., + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::caller, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 3)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("callee") }), FunctionDefinitionIndex(0), 2), (Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("caller") }), FunctionDefinitionIndex(1), 7)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled new file mode 100644 index 00000000000..4603e1e7ed5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled @@ -0,0 +1,33 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/reentrancy_local.move` + +//# publish +module 0x42::tests { + struct R has key { + _0: u64, + } + public fun init(p0: &signer) { + let _v0 = R{_0: 0}; + move_to(p0, _v0); + } + public fun local_access_via_lambda_fails(): bool + acquires R + { + let _v0: || has copy + drop = || lambda__1__local_access_via_lambda_fails(); + let _v1 = borrow_global_mut(@0x42); + _v0(); + let _v2 = &mut _v1._0; + *_v2 = *_v2 + 1; + false + } + fun lambda__1__local_access_via_lambda_fails() + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42)._0; + *_v0 = *_v0 + 1; + } +} + + +//# run 0x42::tests::init --signers 0x42 + +//# run 0x42::tests::local_access_via_lambda_fails --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled.baseline.exp new file mode 100644 index 00000000000..64f0988b0c9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_local.decompiled.baseline.exp @@ -0,0 +1,13 @@ +processed 3 tasks +task 0 lines 3-28: publish [module 0x42::tests {] +task 1 lines 31-31: run 0x42::tests::init --signers 0x42 +task 2 lines 33-33: run 0x42::tests::local_access_via_lambda_fails --verbose +Error: Function execution failed with VMError: { + message: Resource `0x42::tests::R` cannot be accessed because of active reentrancy of defining module., + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::tests, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000042, name: Identifier("tests") }), FunctionDefinitionIndex(2), 4)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled new file mode 100644 index 00000000000..d7cc9ea984d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/reentrancy_module_lock.move` + +//# publish +module 0x42::callee { + public fun call_me(p0: &mut T0, p1: |&mut T0|) { + p1(p0); + } +} + + +//# publish +module 0x42::caller { + use 0x42::callee; + struct R has copy, drop, key { + count: u64, + } + fun init(p0: &signer) { + let _v0 = R{count: 0}; + move_to(p0, _v0); + } + #[module_lock] + fun callback_not_ok(): bool + acquires R + { + let _v0 = borrow_global_mut(@0x42); + let _v1: |&mut R| has copy + drop = |arg0| do_something(arg0); + callee::call_me(_v0, _v1); + let _v2 = &mut _v0.count; + *_v2 = *_v2 + 1; + assert!(*&_v0.count == 2, 14566554180833181696); + true + } + fun do_something(p0: &mut R) { + let _v0 = &mut p0.count; + *_v0 = *_v0 + 1; + } +} + + +//# run 0x42::caller::init --signers 0x42 + +//# run 0x42::caller::callback_not_ok --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled.baseline.exp new file mode 100644 index 00000000000..f3d22114f7a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_module_lock.decompiled.baseline.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 3-8: publish [module 0x42::callee {] +task 1 lines 11-37: publish [module 0x42::caller {] +task 2 lines 40-40: run 0x42::caller::init --signers 0x42 +task 3 lines 42-42: run 0x42::caller::callback_not_ok --verbose +Error: Function execution failed with VMError: { + message: Reentrancy disallowed: reentering `0000000000000000000000000000000000000000000000000000000000000042::caller` via function `do_something` (module lock is active), + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::caller, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled new file mode 100644 index 00000000000..0b3a32a32d8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled @@ -0,0 +1,100 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/reentrancy_nested.move` + +//# publish +module 0x42::worker1 { + struct R has key { + _0: u64, + } + public fun init(p0: &signer) { + let _v0 = R{_0: 0}; + move_to(p0, _v0); + } + public fun set(p0: u64) + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42)._0; + *_v0 = p0; + } + public fun work(p0: ||) + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42)._0; + *_v0 = *_v0 + 1; + p0(); + } +} + + +//# publish +module 0x42::worker2 { + use 0x42::worker1; + struct R has key { + _0: u64, + } + public fun init(p0: &signer) { + let _v0 = R{_0: 0}; + move_to(p0, _v0); + } + public fun set(p0: u64) + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42)._0; + *_v0 = p0; + } + public fun work(p0: ||) + acquires R + { + let _v0 = &mut borrow_global_mut(@0x42)._0; + *_v0 = *_v0 + 1; + worker1::work(p0); + } +} + + +//# publish +module 0x42::tests { + use 0x42::worker1; + use 0x42::worker2; + struct R has key { + _0: u64, + } + fun init(p0: &signer) { + worker1::init(p0); + worker2::init(p0); + let _v0 = R{_0: 0}; + move_to(p0, _v0); + } + fun direct_failure(): bool { + worker2::work(|| lambda__1__direct_failure()); + false + } + fun lambda__1__direct_failure() + acquires R + { + let _v0 = &mut borrow_global_mut(@0x2a)._0; + *_v0 = *_v0 + 1; + } + fun worker1_failure(): bool { + worker2::work(|| worker1::set(10)); + false + } + fun worker2_failure(): bool { + worker2::work(|| worker2::set(10)); + false + } + fun worker2_ok(): bool { + worker1::work(|| worker2::set(10)); + true + } +} + + +//# run 0x42::tests::init --signers 0x42 + +//# run 0x42::tests::direct_failure + +//# run 0x42::tests::worker1_failure + +//# run 0x42::tests::worker2_failure + +//# run 0x42::tests::worker2_ok \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled.baseline.exp new file mode 100644 index 00000000000..f0e3c338fff --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/reentrancy_nested.decompiled.baseline.exp @@ -0,0 +1,31 @@ +processed 8 tasks +task 0 lines 3-25: publish [module 0x42::worker1 {] +task 1 lines 28-51: publish [module 0x42::worker2 {] +task 2 lines 54-89: publish [module 0x42::tests {] +task 3 lines 92-92: run 0x42::tests::init --signers 0x42 +task 4 lines 94-94: run 0x42::tests::direct_failure +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::tests, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], +} +task 5 lines 96-96: run 0x42::tests::worker1_failure +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::worker1, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} +task 6 lines 98-98: run 0x42::tests::worker2_failure +Error: Function execution failed with VMError: { + major_status: RUNTIME_DISPATCH_ERROR, + sub_status: None, + location: 0x42::worker2, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} +task 7 lines 100-100: run 0x42::tests::worker2_ok +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled new file mode 100644 index 00000000000..512dfe8a4dd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled @@ -0,0 +1,58 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/registry.move` + +//# publish +module 0x66::registry { + use 0x1::signer; + struct R has key { + _0: T0, + } + public fun remove(p0: &signer): T0 + acquires R + { + let _v0 = signer::address_of(p0); + let R{_0: _v1} = move_from>(_v0); + _v1 + } + public fun store(p0: &signer, p1: T0) { + let _v0 = R{_0: p1}; + move_to>(p0, _v0); + } +} + + +//# publish +module 0x66::delayed_work { + use 0x66::registry; + struct Work has store { + _0: |u64|(u64) has store, + } + entry fun add(p0: &signer, p1: u64) { + let _v0 = registry::remove(p0); + let _v1 = Work{_0: |arg0| more_work(_v0, p1, arg0)}; + registry::store(p0, _v1); + } + public fun more_work(p0: Work, p1: u64, p2: u64): u64 { + let Work{_0: _v0} = p0; + _v0(p1) + p2 + } + entry fun eval(p0: &signer, p1: u64, p2: u64) { + let Work{_0: _v0} = registry::remove(p0); + assert!(_v0(p1) == p2, 14566554180833181696); + } + public fun id_fun(p0: u64): u64 { + p0 + } + entry fun initialize(p0: &signer) { + let _v0 = Work{_0: |arg0| id_fun(arg0)}; + registry::store(p0, _v0); + } +} + + +//# run 0x66::delayed_work::initialize --signers 0x66 + +//# run 0x66::delayed_work::add --signers 0x66 --args 5 + +//# run 0x66::delayed_work::add --signers 0x66 --args 7 + +//# run 0x66::delayed_work::eval --signers 0x66 --args 3 15 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled.baseline.exp new file mode 100644 index 00000000000..76f2d2fc649 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/registry.decompiled.baseline.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 3-20: publish [module 0x66::registry {] +task 1 lines 23-49: publish [module 0x66::delayed_work {] +task 2 lines 52-52: run 0x66::delayed_work::initialize --signers 0x66 +task 3 lines 54-54: run 0x66::delayed_work::add --signers 0x66 --args 5 +task 4 lines 56-56: run 0x66::delayed_work::add --signers 0x66 --args 7 +task 5 lines 58-58: run 0x66::delayed_work::eval --signers 0x66 --args 3 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled new file mode 100644 index 00000000000..59c24d23b28 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/resolve_from_storage.move` + +//# publish +module 0x66::test { + struct Func has key { + f: ||(u64) has copy + store, + } + public fun init(p0: &signer) { + let _v0 = Func{f: || identity(23)}; + move_to(p0, _v0); + } + public fun identity(p0: T0): T0 { + p0 + } + public fun call(p0: address) + acquires Func + { + let _v0 = *&borrow_global(p0).f; + assert!(_v0() == 23, 777); + } +} + + +//# run 0x66::test::init --signers 0x66 + +//# run 0x66::test::call --args @0x66 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled.baseline.exp new file mode 100644 index 00000000000..7d801657c76 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/resolve_from_storage.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-21: publish [module 0x66::test {] +task 1 lines 24-24: run 0x66::test::init --signers 0x66 +task 2 lines 26-26: run 0x66::test::call --args @0x66 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled new file mode 100644 index 00000000000..5c4aec83ac8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled @@ -0,0 +1,38 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/scripts.move` + +//# publish +module 0xc0ffee::m { + public fun foo() { + () + } +} + + +//# run +script { + use 0xc0ffee::m; + fun main() { + let _v0: || has copy + drop = || m::foo(); + _v0(); + } +} + + +//# run +script { + use 0xc0ffee::m; + fun main() { + let _v0: || has copy + drop = || m::foo(); + _v0(); + } +} + + +//# run +script { + use 0xc0ffee::m; + fun main() { + let _v0: || has copy + drop = || m::foo(); + _v0(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled.baseline.exp new file mode 100644 index 00000000000..91d9a03dbc6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/scripts.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 4 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-18: run [script {] +task 2 lines 21-28: run [script {] +task 3 lines 31-38: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled new file mode 100644 index 00000000000..8a6ee0bee55 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/simple.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: u64, p1: u64, p2: u64, p3: u64): u64 { + p0 + p1 + p2 + p3 + } + fun one(): u64 { + 1 + } + public fun test(): u64 { + let _v0 = one(); + let _v1 = one(); + let _v2 = one(); + let _v3 = |arg0| lambda__1__test(arg0); + _v3(1) + } + fun lambda__1__test(p0: u64): u64 { + foo(1, 1, p0, p0) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled.baseline.exp new file mode 100644 index 00000000000..a5977b75133 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/simple.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::test +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled new file mode 100644 index 00000000000..16489b5b577 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/storage_examples.move` + +//# publish +module 0xc0ffee::m { + use 0x1::signer; + struct Wrapper has copy, drop, store, key { + _0: |&signer|(u64) has copy + drop + store, + } + public fun init(p0: &signer) { + let _v0 = Wrapper{_0: |arg0| foo(arg0)}; + move_to(p0, _v0); + } + #[persistent] + fun foo(p0: &signer): u64 { + 7 + } + public fun fetch_and_run(p0: &signer): u64 + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = *&borrow_global(_v0)._0; + _v1(p0) + } +} + + +//# run 0xc0ffee::m::init --signers 0xc0ffee + +//# run 0xc0ffee::m::fetch_and_run --signers 0xc0ffee \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled.baseline.exp new file mode 100644 index 00000000000..39045c6adde --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/storage_examples.decompiled.baseline.exp @@ -0,0 +1,12 @@ +processed 3 tasks +task 0 lines 3-24: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:14:13 + │ +14 │ fun foo(p0: &signer): u64 { + │ ^^ + + +task 1 lines 27-27: run 0xc0ffee::m::init --signers 0xc0ffee +task 2 lines 29-29: run 0xc0ffee::m::fetch_and_run --signers 0xc0ffee +return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled new file mode 100644 index 00000000000..8e96fc24ab5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/vectors.move` + +//# publish +module 0x42::test { + use 0x1::vector; + public fun eval(p0: u64): u64 { + let _v0 = make(); + let _v1 = 0; + let _v2 = _v0; + vector::reverse<|u64|(u64) has drop>(&mut _v2); + while (!vector::is_empty<|u64|(u64) has drop>(&_v2)) { + let _v3 = vector::pop_back<|u64|(u64) has drop>(&mut _v2); + let _v4 = _v3(p0); + _v1 = _v1 + _v4; + continue + }; + _v1 + } + fun make(): vector<|u64|(u64) has drop> { + let _v0: |u64|u64 has copy + drop = |arg0| lambda__1__make(arg0); + let _v1: |u64|u64 has copy + drop = |arg0| lambda__2__make(arg0); + let _v2: |u64|u64 has copy + drop = |arg0| lambda__3__make(arg0); + let _v3 = vector::empty<|u64|(u64) has drop>(); + let _v4 = &mut _v3; + vector::push_back<|u64|(u64) has drop>(_v4, _v0); + vector::push_back<|u64|(u64) has drop>(_v4, _v1); + vector::push_back<|u64|(u64) has drop>(_v4, _v2); + _v3 + } + fun lambda__1__make(p0: u64): u64 { + p0 + 1 + } + fun lambda__2__make(p0: u64): u64 { + p0 + 2 + } + fun lambda__3__make(p0: u64): u64 { + p0 + 3 + } +} + + +//# run 0x42::test::eval --args 2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled.baseline.exp new file mode 100644 index 00000000000..8b5a27bf715 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/vectors.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-39: publish [module 0x42::test {] +task 1 lines 42-42: run 0x42::test::eval --args 2 +return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled new file mode 100644 index 00000000000..d53a05148c8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/very_large_1.move` + +//# publish +module 0xcafe::Module0 { + public fun function32() { + let _v0: |||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| has copy + drop) has copy + drop = |arg0: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg1: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg2: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop| lambda__2__function32(arg0, arg1, arg2); + let _v1: |||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| has copy + drop) has copy + drop = |arg0: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg1: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg2: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop| lambda__4__function32(arg0, arg1, arg2); + let _v2 = &mut _v1; + *_v2 = _v0; + } + fun lambda__2__function32(p0: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, p1: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, p2: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop): ||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| has copy + drop { + |arg0: |bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop,arg1: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop,arg2: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| lambda__1__function32(arg0, arg1, arg2) + } + fun lambda__4__function32(p0: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, p1: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, p2: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop): ||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| has copy + drop { + |arg0: |bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop,arg1: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop,arg2: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| lambda__3__function32(arg0, arg1, arg2) + } + fun lambda__1__function32(p0: |bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, p1: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, p2: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop) { + () + } + fun lambda__3__function32(p0: |bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, p1: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, p2: |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop) { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled.baseline.exp new file mode 100644 index 00000000000..c9f8936054a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_1.decompiled.baseline.exp @@ -0,0 +1,13 @@ +processed 1 task +task 0 lines 3-23: publish [module 0xcafe::Module0 {] +Error: compilation errors: + error: unexpected token + ┌─ TEMPFILE:6:38 + │ +6 │ let _v0: |||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop, ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop| has copy + drop) has copy + drop = |arg0: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg1: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop,arg2: ||| has copy + drop|(||bool, bool, u8, bool, u8, u8, ||| has copy + drop, || has copy + drop, || has copy + drop|(|| has copy + drop) has copy + drop, ||| has copy + drop|(|| has copy + drop) has copy + drop|(u8) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop, |||| has copy + drop|(|| has copy + drop) has copy + drop|(||| has copy + drop|(|| has copy + drop) has copy + drop) has copy + drop|(u8) has copy + drop) has copy + drop| lambda__2__function32(arg0, arg1, arg2); + │ ^ + │ │ + │ Unexpected '|' + │ Expected ';' + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled new file mode 100644 index 00000000000..612e54c1242 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/closures/very_large_2.move` + +//# publish +module 0xcafe::Module0 { + public fun f1(p0: &||&u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8| has drop| has drop) { + () + } + public fun f2() { + let _v0: ||&u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8| has drop| has drop = |arg0: |&u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8| has drop| lambda__1__f2(arg0); + f1(&_v0); + } + fun lambda__1__f2(p0: |&u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8| has drop) { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled.baseline.exp new file mode 100644 index 00000000000..ef15e89147c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/round-trip/very_large_2.decompiled.baseline.exp @@ -0,0 +1,13 @@ +processed 1 task +task 0 lines 3-15: publish [module 0xcafe::Module0 {] +Error: compilation errors: + error: unexpected token + ┌─ TEMPFILE:5:31 + │ +5 │ public fun f1(p0: &||&u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8| has drop| has drop) { + │ ^ + │ │ + │ Unexpected '&' + │ Expected an identifier + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/scripts.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/scripts.exp index 457ace9c4ac..3aff5e8aa74 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/scripts.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/scripts.exp @@ -1 +1,5 @@ processed 4 tasks +task 0 lines 1-4: publish [module 0xc0ffee::m {] +task 1 lines 6-13: run [script {] +task 2 lines 15-21: run [script {] +task 3 lines 23-28: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/simple.exp index c2c5dc75c52..9b392313850 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/simple.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/simple.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 21-21: +task 0 lines 1-19: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/storage_examples.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/storage_examples.exp index 34aae29fea5..6ac809ce9cb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/storage_examples.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/storage_examples.exp @@ -1,4 +1,5 @@ processed 3 tasks - -task 2 'run'. lines 23-23: +task 0 lines 1-19: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::init --signers 0xc0ffee +task 2 lines 23-23: run 0xc0ffee::m::fetch_and_run --signers 0xc0ffee return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args.exp index d18ec0ff3d1..f5cf22a6614 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-104: +task 0 lines 1-104: publish [module 0xc0ffee::m {] Error: compilation errors: error: too many arguments captured in lambda (can only capture up to a maximum of `64`, but captured `66`) ┌─ TEMPFILE:90:17 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args_another.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args_another.exp index f5bb451901c..9a13c7e4d99 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args_another.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/too_many_args_another.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-21: +task 0 lines 1-21: publish [module 0x66::m {] Error: compilation errors: error: too many arguments captured in lambda (can only capture up to a maximum of `64`, but captured `65`) ┌─ TEMPFILE:12:17 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/vectors.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/vectors.exp index f228f3ab0b5..891d8e2ed87 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/vectors.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/vectors.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0x42::test {] +task 1 lines 17-17: run 0x42::test::eval --args 2 return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp new file mode 100644 index 00000000000..36f9a410f76 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-46: publish [module 0xCAFE::Module0 {] +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000cafe::Module0'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xcafe::Module0, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move new file mode 100644 index 00000000000..e8012e5bb1b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move @@ -0,0 +1,46 @@ +//# publish +module 0xCAFE::Module0 { + public fun function32() { + *( &mut ({ + let var65: | + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop), + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop), + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop) + | + ( + | + (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), + (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), + (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), + | has copy+drop + ) + has copy+drop + = | + var59: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var60: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var61: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + | + { /* _block46 */ + | + var62: | bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop, + var63: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + var64: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + | + {} + }; + var65 + })) = | + var66: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var67: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var68: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + | + { /* _block48 */ + | + var69: | bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop, + var70: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + var71: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + | + {} + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp new file mode 100644 index 00000000000..8670fd33fd0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp @@ -0,0 +1,9 @@ +processed 1 task +task 0 lines 1-21: publish [module 0xCAFE::Module0 {] +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000cafe::Module0'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xcafe::Module0, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move new file mode 100644 index 00000000000..310b9181542 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move @@ -0,0 +1,21 @@ +//# publish +module 0xCAFE::Module0 { + public fun f1( + var1: &( + | + (| + &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, + | has drop) + | has drop), + ) { } + public fun f2() { + f1(&( + | + var2: | + &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, + | has drop + | + { } + )); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/const_vec.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/const_vec.exp index 4cbd0ac0444..218a14ab6aa 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/const_vec.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/const_vec.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test1 return values: 0 - -task 2 'run'. lines 16-16: +task 2 lines 16-16: run 0xc0ffee::m::test2 return values: 0 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/nested.exp index 50ee96c4e62..c96d511295d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/nested.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/nested.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 53-53: +task 0 lines 1-51: publish [module 0x42::test {] +task 1 lines 53-53: run --verbose -- 0x42::test::test1 return values: 42 - -task 2 'run'. lines 55-55: +task 2 lines 55-55: run --verbose -- 0x42::test::test2 return values: 42 - -task 3 'run'. lines 57-57: +task 3 lines 57-57: run --verbose -- 0x42::test::test3 return values: 43 - -task 4 'run'. lines 59-59: +task 4 lines 59-59: run --verbose -- 0x42::test::test4 return values: 43 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/projection.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/projection.exp index 392560602bc..74de9e4cb9c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/projection.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/projection.exp @@ -1,19 +1,14 @@ processed 7 tasks - -task 1 'run'. lines 71-71: +task 0 lines 1-69: publish [module 0x42::test {] +task 1 lines 71-71: run --verbose -- 0x42::test::test_proj_0 return values: 42 - -task 2 'run'. lines 73-73: +task 2 lines 73-73: run --verbose -- 0x42::test::test_proj_0_ref return values: 42 - -task 3 'run'. lines 75-75: +task 3 lines 75-75: run --verbose -- 0x42::test::test_proj_2 return values: true - -task 4 'run'. lines 77-77: +task 4 lines 77-77: run --verbose -- 0x42::test::test_proj_2_ref return values: true - -task 5 'run'. lines 79-79: +task 5 lines 79-79: run --verbose -- 0x42::test::test_get_x return values: 42 - -task 6 'run'. lines 81-81: +task 6 lines 81-81: run --verbose -- 0x42::test::test_get_x_ref return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled new file mode 100644 index 00000000000..a9fb0d11d38 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled @@ -0,0 +1,72 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/dotdot/nested.move` + +//# publish +module 0x42::test { + enum E has drop { + V1 { + _0: u8, + _1: S1, + } + V2 { + x: u8, + y: S0, + } + } + struct S1 has drop { + x: T0, + y: T1, + } + struct S0 has drop { + _0: T0, + _1: T1, + } + fun extract_first_u8(p0: &E): u8 { + loop { + if (!(p0 is V1)) { + if (p0 is V2) break; + abort 14566554180833181697 + }; + return *&p0._0 + }; + *&p0.x + } + fun extract_last_u8(p0: &E): u8 { + loop { + if (!(p0 is V1)) { + if (p0 is V2) break; + abort 14566554180833181697 + }; + return *&(&p0._1).x + }; + *&(&p0.y)._0 + } + fun test1(): u8 { + let _v0 = S1{x: 43u8, y: true}; + let _v1 = E::V1{_0: 42u8, _1: _v0}; + extract_first_u8(&_v1) + } + fun test2(): u8 { + let _v0 = S0{_0: 43u8, _1: true}; + let _v1 = E::V2{x: 42u8, y: _v0}; + extract_first_u8(&_v1) + } + fun test3(): u8 { + let _v0 = S1{x: 43u8, y: true}; + let _v1 = E::V1{_0: 42u8, _1: _v0}; + extract_last_u8(&_v1) + } + fun test4(): u8 { + let _v0 = S0{_0: 43u8, _1: true}; + let _v1 = E::V2{x: 42u8, y: _v0}; + extract_last_u8(&_v1) + } +} + + +//# run --verbose -- 0x42::test::test1 + +//# run --verbose -- 0x42::test::test2 + +//# run --verbose -- 0x42::test::test3 + +//# run --verbose -- 0x42::test::test4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled.baseline.exp new file mode 100644 index 00000000000..d73cf780f5e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/nested.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-63: publish [module 0x42::test {] +task 1 lines 66-66: run --verbose -- 0x42::test::test1 +return values: 42 +task 2 lines 68-68: run --verbose -- 0x42::test::test2 +return values: 42 +task 3 lines 70-70: run --verbose -- 0x42::test::test3 +return values: 43 +task 4 lines 72-72: run --verbose -- 0x42::test::test4 +return values: 43 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled new file mode 100644 index 00000000000..6c120c4e852 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled @@ -0,0 +1,69 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/dotdot/projection.move` + +//# publish +module 0x42::test { + struct T has drop { + x: T0, + y: T1, + } + struct S has drop { + _0: T0, + _1: T1, + _2: T2, + } + fun get_x(p0: T): T0 { + let T{x: _v0, y: _v1} = p0; + _v0 + } + fun get_x_ref(p0: &T): &T0 { + &p0.x + } + fun proj_0(p0: S): T0 { + let S{_0: _v0, _1: _v1, _2: _v2} = p0; + _v0 + } + fun proj_0_ref(p0: &S): &T0 { + &p0._0 + } + fun proj_2(p0: S): T2 { + let S{_0: _v0, _1: _v1, _2: _v2} = p0; + _v2 + } + fun proj_2_ref(p0: &S): &T2 { + &p0._2 + } + fun test_get_x(): u8 { + get_x(T{x: 42u8, y: true}) + } + fun test_get_x_ref(): u8 { + let _v0 = T{x: 42u8, y: true}; + *get_x_ref(&_v0) + } + fun test_proj_0(): u8 { + proj_0(S{_0: 42u8, _1: @0x1, _2: true}) + } + fun test_proj_0_ref(): u8 { + let _v0 = S{_0: 42u8, _1: @0x1, _2: true}; + *proj_0_ref(&_v0) + } + fun test_proj_2(): bool { + proj_2(S{_0: 42, _1: @0x1, _2: true}) + } + fun test_proj_2_ref(): bool { + let _v0 = S{_0: 42, _1: @0x1, _2: true}; + *proj_2_ref(&_v0) + } +} + + +//# run --verbose -- 0x42::test::test_proj_0 + +//# run --verbose -- 0x42::test::test_proj_0_ref + +//# run --verbose -- 0x42::test::test_proj_2 + +//# run --verbose -- 0x42::test::test_proj_2_ref + +//# run --verbose -- 0x42::test::test_get_x + +//# run --verbose -- 0x42::test::test_get_x_ref \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled.baseline.exp new file mode 100644 index 00000000000..5769bc32d8e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/dotdot/round-trip/projection.decompiled.baseline.exp @@ -0,0 +1,14 @@ +processed 7 tasks +task 0 lines 3-56: publish [module 0x42::test {] +task 1 lines 59-59: run --verbose -- 0x42::test::test_proj_0 +return values: 42 +task 2 lines 61-61: run --verbose -- 0x42::test::test_proj_0_ref +return values: 42 +task 3 lines 63-63: run --verbose -- 0x42::test::test_proj_2 +return values: true +task 4 lines 65-65: run --verbose -- 0x42::test::test_proj_2_ref +return values: true +task 5 lines 67-67: run --verbose -- 0x42::test::test_get_x +return values: 42 +task 6 lines 69-69: run --verbose -- 0x42::test::test_get_x_ref +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug-14296.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug-14296.exp index 6cd67db3f64..37f054c1357 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug-14296.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug-14296.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-24: publish [module 0x42::test {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14300_update_variant_field.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14300_update_variant_field.exp index eb9aa2aa18d..1fc0a9f580a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14300_update_variant_field.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14300_update_variant_field.exp @@ -1,10 +1,8 @@ processed 4 tasks - -task 1 'run'. lines 41-41: +task 0 lines 1-39: publish [module 0x815::m {] +task 1 lines 41-41: run 0x815::m::update_common_field return values: 15 - -task 2 'run'. lines 43-43: +task 2 lines 43-43: run 0x815::m::update_non_common_field return values: 15 - -task 3 'run'. lines 45-45: +task 3 lines 45-45: run 0x815::m::update_common_field_different_offset return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14733_match_critical_edge.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14733_match_critical_edge.exp index ec874a52738..ab1d1215b10 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14733_match_critical_edge.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/bug_14733_match_critical_edge.exp @@ -1,22 +1,16 @@ processed 8 tasks - -task 1 'run'. lines 73-73: +task 0 lines 6-71: publish [module 0x815::m {] +task 1 lines 73-73: run 0x815::m::test1 return values: 22 - -task 2 'run'. lines 75-75: +task 2 lines 75-75: run 0x815::m::test2 return values: 0 - -task 3 'run'. lines 77-77: +task 3 lines 77-77: run 0x815::m::test3 return values: 10 - -task 4 'run'. lines 79-79: +task 4 lines 79-79: run 0x815::m::test4 return values: 21 - -task 5 'run'. lines 81-81: +task 5 lines 81-81: run 0x815::m::test5 return values: 43 - -task 6 'run'. lines 83-83: +task 6 lines 83-83: run 0x815::m::test6 return values: 25 - -task 7 'run'. lines 85-85: +task 7 lines 85-85: run 0x815::m::test7 return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.baseline.exp index bad82805f9b..b0973a28e60 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.baseline.exp @@ -1,12 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 37-37: +task 0 lines 1-35: publish [module 0x42::m {] +task 1 lines 37-37: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 39-39: +task 2 lines 39-39: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 41-41: +task 3 lines 41-41: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(33), @@ -14,6 +12,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 10)], } - -task 4 'run'. lines 43-43: +task 4 lines 43-43: run 0x42::m::test_get_y_v2 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.no-optimize.exp index fc020d774df..f18ff2984e9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.no-optimize.exp @@ -1,12 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 37-37: +task 0 lines 1-35: publish [module 0x42::m {] +task 1 lines 37-37: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 39-39: +task 2 lines 39-39: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 41-41: +task 3 lines 41-41: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(33), @@ -14,6 +12,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 13)], } - -task 4 'run'. lines 43-43: +task 4 lines 43-43: run 0x42::m::test_get_y_v2 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.opt-extra.exp new file mode 100644 index 00000000000..3054186cb91 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.opt-extra.exp @@ -0,0 +1,16 @@ +processed 5 tasks +task 0 lines 1-35: publish [module 0x42::m {] +task 1 lines 37-37: run 0x42::m::test_get_x_v1 +return values: 43 +task 2 lines 39-39: run 0x42::m::test_get_x_v2 +return values: 43 +task 3 lines 41-41: run 0x42::m::test_get_y_v1 +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(33), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 15)], +} +task 4 lines 43-43: run 0x42::m::test_get_y_v2 +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.optimize.exp index bad82805f9b..b0973a28e60 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select.optimize.exp @@ -1,12 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 37-37: +task 0 lines 1-35: publish [module 0x42::m {] +task 1 lines 37-37: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 39-39: +task 2 lines 39-39: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 41-41: +task 3 lines 41-41: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(33), @@ -14,6 +12,5 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 10)], } - -task 4 'run'. lines 43-43: +task 4 lines 43-43: run 0x42::m::test_get_y_v2 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.baseline.exp index 1352cb7967a..18cdacb8d6b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.baseline.exp @@ -1,15 +1,12 @@ processed 7 tasks - -task 1 'run'. lines 42-42: +task 0 lines 1-40: publish [module 0x42::m {] +task 1 lines 42-42: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 44-44: +task 2 lines 44-44: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 46-46: +task 3 lines 46-46: run 0x42::m::test_get_x_v3 return values: 43 - -task 4 'run'. lines 48-48: +task 4 lines 48-48: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, @@ -17,11 +14,9 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 4)], } - -task 5 'run'. lines 50-50: +task 5 lines 50-50: run 0x42::m::test_get_y_v2 return values: true - -task 6 'run'. lines 52-52: +task 6 lines 52-52: run 0x42::m::test_get_y_v3 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.no-optimize.exp index 69190b974ae..09b3a71b528 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.no-optimize.exp @@ -1,15 +1,12 @@ processed 7 tasks - -task 1 'run'. lines 42-42: +task 0 lines 1-40: publish [module 0x42::m {] +task 1 lines 42-42: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 44-44: +task 2 lines 44-44: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 46-46: +task 3 lines 46-46: run 0x42::m::test_get_x_v3 return values: 43 - -task 4 'run'. lines 48-48: +task 4 lines 48-48: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, @@ -17,11 +14,9 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 4)], } - -task 5 'run'. lines 50-50: +task 5 lines 50-50: run 0x42::m::test_get_y_v2 return values: true - -task 6 'run'. lines 52-52: +task 6 lines 52-52: run 0x42::m::test_get_y_v3 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.opt-extra.exp new file mode 100644 index 00000000000..18cdacb8d6b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.opt-extra.exp @@ -0,0 +1,26 @@ +processed 7 tasks +task 0 lines 1-40: publish [module 0x42::m {] +task 1 lines 42-42: run 0x42::m::test_get_x_v1 +return values: 43 +task 2 lines 44-44: run 0x42::m::test_get_x_v2 +return values: 43 +task 3 lines 46-46: run 0x42::m::test_get_x_v3 +return values: 43 +task 4 lines 48-48: run 0x42::m::test_get_y_v1 +Error: Function execution failed with VMError: { + major_status: STRUCT_VARIANT_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 4)], +} +task 5 lines 50-50: run 0x42::m::test_get_y_v2 +return values: true +task 6 lines 52-52: run 0x42::m::test_get_y_v3 +Error: Function execution failed with VMError: { + major_status: STRUCT_VARIANT_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 5)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.optimize.exp index 1352cb7967a..18cdacb8d6b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_field_select_different_offsets.optimize.exp @@ -1,15 +1,12 @@ processed 7 tasks - -task 1 'run'. lines 42-42: +task 0 lines 1-40: publish [module 0x42::m {] +task 1 lines 42-42: run 0x42::m::test_get_x_v1 return values: 43 - -task 2 'run'. lines 44-44: +task 2 lines 44-44: run 0x42::m::test_get_x_v2 return values: 43 - -task 3 'run'. lines 46-46: +task 3 lines 46-46: run 0x42::m::test_get_x_v3 return values: 43 - -task 4 'run'. lines 48-48: +task 4 lines 48-48: run 0x42::m::test_get_y_v1 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, @@ -17,11 +14,9 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(3), 4)], } - -task 5 'run'. lines 50-50: +task 5 lines 50-50: run 0x42::m::test_get_y_v2 return values: true - -task 6 'run'. lines 52-52: +task 6 lines 52-52: run 0x42::m::test_get_y_v3 Error: Function execution failed with VMError: { major_status: STRUCT_VARIANT_MISMATCH, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_matching.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_matching.exp index 3e25bc61066..5a4f3939099 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_matching.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_matching.exp @@ -1,43 +1,30 @@ processed 15 tasks - -task 1 'run'. lines 175-175: +task 0 lines 1-173: publish [module 0x42::m {] +task 1 lines 175-175: run 0x42::m::t1_is_inner1 return values: true - -task 2 'run'. lines 177-177: +task 2 lines 177-177: run 0x42::m::t2_is_inner1 return values: false - -task 3 'run'. lines 179-179: +task 3 lines 179-179: run 0x42::m::t1_inner_value return values: 7 - -task 4 'run'. lines 181-181: +task 4 lines 181-181: run 0x42::m::t1_outer_value return values: 0 - -task 5 'run'. lines 183-183: +task 5 lines 183-183: run 0x42::m::t2_outer_value return values: 3 - -task 6 'run'. lines 185-185: +task 6 lines 185-185: run 0x42::m::t3_outer_value return values: 8 - -task 7 'run'. lines 187-187: +task 7 lines 187-187: run 0x42::m::t1_outer_value_nested return values: 27 - -task 8 'run'. lines 189-189: +task 8 lines 189-189: run 0x42::m::t2_outer_value_nested return values: 12 - -task 9 'run'. lines 191-191: +task 9 lines 191-191: run 0x42::m::t1_outer_value_with_cond return values: 1 - -task 10 'run'. lines 193-193: +task 10 lines 193-193: run 0x42::m::t1_outer_value_with_cond_ref return values: true - -task 11 'run'. lines 195-195: +task 11 lines 195-195: run 0x42::m::t1_is_some return values: false - -task 12 'run'. lines 197-197: +task 12 lines 197-197: run 0x42::m::t2_is_some return values: true - -task 13 'run'. lines 199-199: +task 13 lines 199-199: run 0x42::m::t1_is_some_specialized return values: false - -task 14 'run'. lines 201-201: +task 14 lines 201-201: run 0x42::m::t2_is_some_specialized return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.baseline.exp index 3e322bc2855..5afeb8cf97a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.baseline.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-43: +task 0 lines 1-43: publish [module 0x42::m {] warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` ┌─ TEMPFILE:20:21 │ @@ -20,6 +19,5 @@ warning: This assignment/binding to the left-hand-side variable `i` is unused. C │ ^^^^^^^^^ - -task 1 'run'. lines 45-45: +task 1 lines 45-45: run 0x42::m::t1_check_scoping return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.no-optimize.exp index 3e322bc2855..5afeb8cf97a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.no-optimize.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-43: +task 0 lines 1-43: publish [module 0x42::m {] warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` ┌─ TEMPFILE:20:21 │ @@ -20,6 +19,5 @@ warning: This assignment/binding to the left-hand-side variable `i` is unused. C │ ^^^^^^^^^ - -task 1 'run'. lines 45-45: +task 1 lines 45-45: run 0x42::m::t1_check_scoping return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.opt-extra.exp new file mode 100644 index 00000000000..5afeb8cf97a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.opt-extra.exp @@ -0,0 +1,23 @@ +processed 2 tasks +task 0 lines 1-43: publish [module 0x42::m {] +warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` + ┌─ TEMPFILE:20:21 + │ +20 │ let x = 4; + │ ^ + +warning: This assignment/binding to the left-hand-side variable `b` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_b`), or renaming to `_` + ┌─ TEMPFILE:35:13 + │ +35 │ Two{i, b} => 3, + │ ^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `i` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_i`), or renaming to `_` + ┌─ TEMPFILE:35:13 + │ +35 │ Two{i, b} => 3, + │ ^^^^^^^^^ + + +task 1 lines 45-45: run 0x42::m::t1_check_scoping +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.optimize.exp index 3e322bc2855..5afeb8cf97a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_scoping.optimize.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-43: +task 0 lines 1-43: publish [module 0x42::m {] warning: This assignment/binding to the left-hand-side variable `x` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_x`), or renaming to `_` ┌─ TEMPFILE:20:21 │ @@ -20,6 +19,5 @@ warning: This assignment/binding to the left-hand-side variable `i` is unused. C │ ^^^^^^^^^ - -task 1 'run'. lines 45-45: +task 1 lines 45-45: run 0x42::m::t1_check_scoping return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_variant_test.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_variant_test.exp index a25982ced2c..89b7daca2d7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_variant_test.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/enum_variant_test.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 23-23: +task 0 lines 1-21: publish [module 0x42::m {] +task 1 lines 23-23: run 0x42::m::test_v1 return values: true - -task 2 'run'. lines 25-25: +task 2 lines 25-25: run 0x42::m::test_v1v3 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/match_cover.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/match_cover.exp index a0a6d7fe813..614f507606d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/match_cover.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/match_cover.exp @@ -1,6 +1,8 @@ processed 4 tasks - -task 3 'publish'. lines 147-197: +task 0 lines 1-62: publish [module 0xc0ffee::m {] +task 1 lines 65-94: publish [module 0xc0ffee::n {] +task 2 lines 97-145: publish [module 0xc0ffee::o {] +task 3 lines 147-197: publish [module 0xc0ffee::o_fail {] Error: compilation errors: error: unreachable pattern ┌─ TEMPFILE3:168:13 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled new file mode 100644 index 00000000000..4e9a64a85d3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled @@ -0,0 +1,31 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/bug-14296.move` + +//# publish +module 0x42::test { + enum E has drop { + V1 { + x: u8, + y: S1, + } + V2 { + x: u8, + y: S0, + } + } + struct S1 has drop { + x: T0, + y: T1, + } + struct S0 has drop { + } + fun extract_last_u8(p0: &E): u8 { + loop { + if (!(p0 is V1)) { + if (p0 is V2) break; + abort 14566554180833181697 + }; + return *&(&p0.y).x + }; + 1u8 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled.baseline.exp new file mode 100644 index 00000000000..f7cf01ac760 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug-14296.decompiled.baseline.exp @@ -0,0 +1,12 @@ +processed 1 task +task 0 lines 3-31: publish [module 0x42::test {] +Error: compilation errors: + error: cannot select field `y` since it has different types in variants of enum `E` + ┌─ TEMPFILE:27:24 + │ +27 │ return *&(&p0.y).x + │ ^^ + │ + = field `y` has type `S0` in variant `V2` and type `S1` in variant `V1` + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled new file mode 100644 index 00000000000..f65eb08451f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled @@ -0,0 +1,49 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/bug_14300_update_variant_field.move` + +//# publish +module 0x815::m { + enum CommonFields has drop { + Foo { + x: u64, + y: u8, + } + Bar { + x: u64, + y: u8, + z: u32, + } + Baz { + y: u8, + } + } + fun update_common_field(): u64 { + let _v0 = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; + let _v1 = &mut (&mut _v0).x; + *_v1 = 15; + *&(&_v0).x + } + fun update_common_field_different_offset(): u8 { + let _v0; + let _v1; + let _v2 = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; + let _v3 = &mut _v2; + if ((_v3 is Foo) || (_v3 is Bar)) _v1 = &mut _v3.y else _v1 = &mut _v3.y; + *_v1 = 15u8; + let _v4 = &_v2; + if ((_v4 is Foo) || (_v4 is Bar)) _v0 = &_v4.y else _v0 = &_v4.y; + *_v0 + } + fun update_non_common_field(): u32 { + let _v0 = CommonFields::Bar{x: 30, y: 40u8, z: 50u32}; + let _v1 = &mut (&mut _v0).z; + *_v1 = 15u32; + *&(&_v0).z + } +} + + +//# run 0x815::m::update_common_field + +//# run 0x815::m::update_non_common_field + +//# run 0x815::m::update_common_field_different_offset \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled.baseline.exp new file mode 100644 index 00000000000..cc0ce5f3a01 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14300_update_variant_field.decompiled.baseline.exp @@ -0,0 +1,8 @@ +processed 4 tasks +task 0 lines 3-42: publish [module 0x815::m {] +task 1 lines 45-45: run 0x815::m::update_common_field +return values: 15 +task 2 lines 47-47: run 0x815::m::update_non_common_field +return values: 15 +task 3 lines 49-49: run 0x815::m::update_common_field_different_offset +return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled new file mode 100644 index 00000000000..9f8e67e944f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled @@ -0,0 +1,191 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/bug_14733_match_critical_edge.move` + +//# publish +module 0x815::m { + enum Admin has drop { + Superuser, + User { + _0: u64, + } + } + enum Entity has drop { + Person { + id: u64, + } + Institution { + id: u64, + admin: Admin, + } + } + fun admin_id(p0: &Entity): u64 { + let _v0; + let _v1; + 'l5: loop { + let _v2; + 'l4: loop { + 'l3: loop { + let _v3; + 'l0: loop { + 'l1: loop { + let _v4; + 'l2: loop { + if (!((p0 is Institution) && (&p0.admin is Superuser))) { + loop { + let _v5; + if (p0 is Institution) { + _v5 = &p0.admin; + if (_v5 is User) { + _v3 = &_v5._0; + if (*_v3 > 10) break + } + }; + loop { + if (p0 is Institution) { + _v5 = &p0.admin; + if (_v5 is User) { + if (*&_v5._0 <= 10) break} + }; + _v4 = p0; + if (_v4 is Person) { + _v3 = &_v4.id; + if (*_v3 > 10) break 'l0 + }; + if (!(_v4 is Institution)) break 'l1; + break 'l2 + }; + _v4 = p0; + if (_v4 is Person) { + _v3 = &_v4.id; + if (*_v3 > 10) { + _v2 = *_v3; + break 'l3 + } + }; + if (_v4 is Institution) { + _v2 = *&_v4.id; + break 'l3 + }; + _v2 = 0; + break 'l3 + }; + _v1 = *_v3; + _v4 = p0; + if (_v4 is Person) { + _v3 = &_v4.id; + if (*_v3 > 10) { + _v2 = *_v3; + break 'l4 + } + }; + if (_v4 is Institution) { + _v2 = *&_v4.id; + break 'l4 + }; + _v2 = 0; + break 'l4 + }; + _v0 = 1; + if (p0 is Person) { + _v3 = &p0.id; + if (*_v3 > 10) { + _v1 = *_v3; + break 'l5 + } + }; + if (p0 is Institution) { + _v1 = *&p0.id; + break 'l5 + }; + _v1 = 0; + break 'l5 + }; + return *&_v4.id + }; + return 0 + }; + return *_v3 + }; + return _v2 + 5 + }; + return _v1 + _v2 + }; + _v0 + _v1 + } + fun test1(): u64 { + let _v0; + let _v1 = Entity::Person{id: 22}; + let _v2 = &_v1; + loop { + if (_v2 is Person) { + _v0 = &_v2.id; + if (*_v0 > 10) break + }; + if (_v2 is Institution) return *&_v2.id; + return 0 + }; + *_v0 + } + fun test2(): u64 { + let _v0; + let _v1 = Entity::Person{id: 10}; + let _v2 = &_v1; + loop { + if (_v2 is Person) { + _v0 = &_v2.id; + if (*_v0 > 10) break + }; + if (_v2 is Institution) return *&_v2.id; + return 0 + }; + *_v0 + } + fun test3(): u64 { + let _v0; + let _v1 = Admin::Superuser{}; + let _v2 = Entity::Institution{id: 10, admin: _v1}; + let _v3 = &_v2; + loop { + if (_v3 is Person) { + _v0 = &_v3.id; + if (*_v0 > 10) break + }; + if (_v3 is Institution) return *&_v3.id; + return 0 + }; + *_v0 + } + fun test4(): u64 { + let _v0 = Admin::Superuser{}; + let _v1 = Entity::Institution{id: 20, admin: _v0}; + admin_id(&_v1) + } + fun test5(): u64 { + let _v0 = Admin::User{_0: 23}; + let _v1 = Entity::Institution{id: 20, admin: _v0}; + admin_id(&_v1) + } + fun test6(): u64 { + let _v0 = Admin::User{_0: 8}; + let _v1 = Entity::Institution{id: 20, admin: _v0}; + admin_id(&_v1) + } + fun test7(): u64 { + let _v0 = Entity::Person{id: 15}; + admin_id(&_v0) + } +} + + +//# run 0x815::m::test1 + +//# run 0x815::m::test2 + +//# run 0x815::m::test3 + +//# run 0x815::m::test4 + +//# run 0x815::m::test5 + +//# run 0x815::m::test6 + +//# run 0x815::m::test7 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled.baseline.exp new file mode 100644 index 00000000000..e290a7c7ddb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/bug_14733_match_critical_edge.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 8 tasks +task 0 lines 3-176: publish [module 0x815::m {] +task 1 lines 179-179: run 0x815::m::test1 +return values: 22 +task 2 lines 181-181: run 0x815::m::test2 +return values: 0 +task 3 lines 183-183: run 0x815::m::test3 +return values: 10 +task 4 lines 185-185: run 0x815::m::test4 +return values: 21 +task 5 lines 187-187: run 0x815::m::test5 +return values: 43 +task 6 lines 189-189: run 0x815::m::test6 +return values: 25 +task 7 lines 191-191: run 0x815::m::test7 +return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled new file mode 100644 index 00000000000..430860da5e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled @@ -0,0 +1,43 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/enum_field_select.move` + +//# publish +module 0x42::m { + enum Data has drop { + V1 { + x: u64, + } + V2 { + x: u64, + y: bool, + } + } + fun get_y(p0: &Data): bool { + assert!(p0 is V2, 33); + *&p0.y + } + fun test_get_x_v1(): u64 { + let _v0 = Data::V1{x: 43}; + *&(&_v0).x + } + fun test_get_x_v2(): u64 { + let _v0 = Data::V2{x: 43, y: false}; + *&(&_v0).x + } + fun test_get_y_v1(): bool { + let _v0 = Data::V1{x: 43}; + get_y(&_v0) + } + fun test_get_y_v2(): bool { + let _v0 = Data::V2{x: 43, y: true}; + get_y(&_v0) + } +} + + +//# run 0x42::m::test_get_x_v1 + +//# run 0x42::m::test_get_x_v2 + +//# run 0x42::m::test_get_y_v1 + +//# run 0x42::m::test_get_y_v2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled.baseline.exp new file mode 100644 index 00000000000..7303de2cf1b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 5 tasks +task 0 lines 3-34: publish [module 0x42::m {] +task 1 lines 37-37: run 0x42::m::test_get_x_v1 +return values: 43 +task 2 lines 39-39: run 0x42::m::test_get_x_v2 +return values: 43 +task 3 lines 41-41: run 0x42::m::test_get_y_v1 +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(33), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 10)], +} +task 4 lines 43-43: run 0x42::m::test_get_y_v2 +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled new file mode 100644 index 00000000000..eed195b20a2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled @@ -0,0 +1,64 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/enum_field_select_different_offsets.move` + +//# publish +module 0x42::m { + enum Data has drop { + V1 { + x: u64, + } + V2 { + y: bool, + x: u64, + } + V3 { + z: u8, + x: u64, + } + } + fun test_get_x_v1(): u64 { + let _v0; + let _v1 = Data::V1{x: 43}; + let _v2 = &_v1; + if ((_v2 is V2) || (_v2 is V3)) _v0 = &_v2.x else _v0 = &_v2.x; + *_v0 + } + fun test_get_x_v2(): u64 { + let _v0; + let _v1 = Data::V2{y: false, x: 43}; + let _v2 = &_v1; + if ((_v2 is V2) || (_v2 is V3)) _v0 = &_v2.x else _v0 = &_v2.x; + *_v0 + } + fun test_get_x_v3(): u64 { + let _v0; + let _v1 = Data::V3{z: 1u8, x: 43}; + let _v2 = &_v1; + if ((_v2 is V2) || (_v2 is V3)) _v0 = &_v2.x else _v0 = &_v2.x; + *_v0 + } + fun test_get_y_v1(): bool { + let _v0 = Data::V1{x: 43}; + *&(&_v0).y + } + fun test_get_y_v2(): bool { + let _v0 = Data::V2{y: true, x: 43}; + *&(&_v0).y + } + fun test_get_y_v3(): bool { + let _v0 = Data::V3{z: 1u8, x: 43}; + *&(&_v0).y + } +} + + +//# run 0x42::m::test_get_x_v1 + +//# run 0x42::m::test_get_x_v2 + +//# run 0x42::m::test_get_x_v3 + +//# run 0x42::m::test_get_y_v1 + +//# run 0x42::m::test_get_y_v2 + +//# run 0x42::m::test_get_y_v3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled.baseline.exp new file mode 100644 index 00000000000..7d8b8958ae0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_field_select_different_offsets.decompiled.baseline.exp @@ -0,0 +1,26 @@ +processed 7 tasks +task 0 lines 3-51: publish [module 0x42::m {] +task 1 lines 54-54: run 0x42::m::test_get_x_v1 +return values: 43 +task 2 lines 56-56: run 0x42::m::test_get_x_v2 +return values: 43 +task 3 lines 58-58: run 0x42::m::test_get_x_v3 +return values: 43 +task 4 lines 60-60: run 0x42::m::test_get_y_v1 +Error: Function execution failed with VMError: { + major_status: STRUCT_VARIANT_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(3), 4)], +} +task 5 lines 62-62: run 0x42::m::test_get_y_v2 +return values: true +task 6 lines 64-64: run 0x42::m::test_get_y_v3 +Error: Function execution failed with VMError: { + major_status: STRUCT_VARIANT_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 5)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled new file mode 100644 index 00000000000..baac211fd09 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled @@ -0,0 +1,285 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/enum_matching.move` + +//# publish +module 0x42::m { + struct Box has drop { + x: u64, + } + enum CommonFields { + Foo { + x: u64, + y: u64, + } + Bar { + z: u64, + x: u64, + } + } + enum Inner has drop { + Inner1 { + x: u64, + } + Inner2 { + x: u64, + y: u64, + } + } + enum Option has drop { + None, + Some { + value: T0, + } + } + enum Outer has drop { + None, + One { + i: Inner, + } + Two { + i: Inner, + b: Box, + } + } + public fun inner_value(p0: Inner): u64 { + let _v0 = &p0; + loop { + if (!(_v0 is Inner1)) { + if (_v0 is Inner2) break; + abort 14566554180833181697 + }; + let Inner::Inner1{x: _v1} = p0; + return _v1 + }; + let Inner::Inner2{x: _v2, y: _v3} = p0; + _v2 + _v3 + } + public fun is_inner1(p0: &Inner): bool { + p0 is Inner1 + } + public fun is_some(p0: &Option): bool { + loop { + if (!(p0 is None)) { + if (p0 is Some) break; + abort 14566554180833181697 + }; + return false + }; + true + } + public fun is_some_dropped(p0: Option): bool { + if (&p0 is None) { + let Option::None{} = p0; + return false + }; + true + } + public fun is_some_specialized(p0: &Option>): bool { + 'l0: loop { + loop { + if (!(p0 is None)) { + if (p0 is Some) { + if (&p0.value is None) break 'l0}; + if (p0 is Some) { + if (&p0.value is Some) break}; + abort 14566554180833181697 + }; + return false + }; + return true + }; + false + } + public fun outer_value(p0: Outer): u64 { + let _v0 = &p0; + 'l0: loop { + loop { + if (!(_v0 is None)) { + if (_v0 is One) break; + if (_v0 is Two) break 'l0; + abort 14566554180833181697 + }; + let Outer::None{} = p0; + return 0 + }; + let Outer::One{i: _v1} = p0; + return inner_value(_v1) + }; + let Outer::Two{i: _v2, b: _v3} = p0; + let _v4 = _v3; + let _v5 = inner_value(_v2); + let _v6 = *&(&_v4).x; + _v5 + _v6 + } + public fun outer_value_nested(p0: Outer): u64 { + let _v0 = &p0; + 'l0: loop { + 'l1: loop { + loop { + if (!(_v0 is None)) { + if (_v0 is One) { + if (&_v0.i is Inner1) break 'l0}; + if (_v0 is One) break; + if (_v0 is Two) break 'l1; + abort 14566554180833181697 + }; + let Outer::None{} = p0; + return 0 + }; + let Outer::One{i: _v1} = p0; + return inner_value(_v1) + }; + let Outer::Two{i: _v2, b: _v3} = p0; + let _v4 = _v3; + let _v5 = inner_value(_v2); + let _v6 = *&(&_v4).x; + return _v5 + _v6 + }; + let Outer::One{i: _v7} = p0; + let Inner::Inner1{x: _v8} = _v7; + _v8 + } + public fun outer_value_with_cond(p0: Outer): u64 { + let _v0 = &p0; + 'l0: loop { + 'l1: loop { + loop { + if (!(_v0 is None)) { + if (_v0 is One) { + if (is_inner1(&_v0.i)) break 'l0}; + if (_v0 is One) break; + if (_v0 is Two) break 'l1; + abort 14566554180833181697 + }; + let Outer::None{} = p0; + return 0 + }; + let Outer::One{i: _v1} = p0; + return inner_value(_v1) + }; + let Outer::Two{i: _v2, b: _v3} = p0; + let _v4 = _v3; + let _v5 = inner_value(_v2); + let _v6 = *&(&_v4).x; + return _v5 + _v6 + }; + let Outer::One{i: _v7} = p0; + inner_value(_v7) % 2 + } + public fun outer_value_with_cond_ref(p0: &Outer): bool { + 'l0: loop { + 'l1: loop { + loop { + if (!(p0 is None)) { + if (p0 is One) { + if (is_inner1(&p0.i)) break 'l0}; + if (p0 is One) break; + if (p0 is Two) break 'l1; + abort 14566554180833181697 + }; + return false + }; + return is_inner1(&p0.i) + }; + return is_inner1(&p0.i) + }; + true + } + fun select_common_fields(p0: CommonFields): u64 { + let _v0; + let _v1; + let _v2 = &p0; + if (_v2 is Bar) _v0 = &_v2.x else _v0 = &_v2.x; + let _v3 = *_v0; + let _v4 = &p0; + if (_v4 is Foo) { + let CommonFields::Foo{x: _v5, y: _v6} = p0; + _v1 = _v6 + } else if (_v4 is Bar) { + let CommonFields::Bar{z: _v7, x: _v8} = p0; + _v1 = _v7 + } else abort 14566554180833181697; + _v3 + _v1 + } + fun t1_inner_value(): u64 { + inner_value(Inner::Inner2{x: 2, y: 5}) + } + fun t1_is_inner1(): bool { + let _v0 = Inner::Inner1{x: 2}; + is_inner1(&_v0) + } + fun t1_is_some(): bool { + let _v0 = Option::None{}; + is_some(&_v0) + } + fun t1_is_some_specialized(): bool { + let _v0 = Option::Some>{value: Option::None{}}; + is_some_specialized(&_v0) + } + fun t1_outer_value(): u64 { + outer_value(Outer::None{}) + } + fun t1_outer_value_nested(): u64 { + outer_value_nested(Outer::One{i: Inner::Inner1{x: 27}}) + } + fun t1_outer_value_with_cond(): u64 { + outer_value_with_cond(Outer::One{i: Inner::Inner1{x: 43}}) + } + fun t1_outer_value_with_cond_ref(): bool { + let _v0 = Outer::One{i: Inner::Inner1{x: 43}}; + outer_value_with_cond_ref(&_v0) + } + fun t2_is_inner1(): bool { + let _v0 = Inner::Inner2{x: 2, y: 3}; + is_inner1(&_v0) + } + fun t2_is_some(): bool { + let _v0 = Option::Some{value: 3}; + is_some(&_v0) + } + fun t2_is_some_specialized(): bool { + let _v0 = Option::Some>{value: Option::Some{value: 1}}; + is_some_specialized(&_v0) + } + fun t2_outer_value(): u64 { + outer_value(Outer::One{i: Inner::Inner2{x: 1, y: 2}}) + } + fun t2_outer_value_nested(): u64 { + let _v0 = Inner::Inner1{x: 5}; + let _v1 = Box{x: 7}; + outer_value_nested(Outer::Two{i: _v0, b: _v1}) + } + fun t3_outer_value(): u64 { + let _v0 = Inner::Inner1{x: 1}; + let _v1 = Box{x: 7}; + outer_value(Outer::Two{i: _v0, b: _v1}) + } +} + + +//# run 0x42::m::t1_is_inner1 + +//# run 0x42::m::t2_is_inner1 + +//# run 0x42::m::t1_inner_value + +//# run 0x42::m::t1_outer_value + +//# run 0x42::m::t2_outer_value + +//# run 0x42::m::t3_outer_value + +//# run 0x42::m::t1_outer_value_nested + +//# run 0x42::m::t2_outer_value_nested + +//# run 0x42::m::t1_outer_value_with_cond + +//# run 0x42::m::t1_outer_value_with_cond_ref + +//# run 0x42::m::t1_is_some + +//# run 0x42::m::t2_is_some + +//# run 0x42::m::t1_is_some_specialized + +//# run 0x42::m::t2_is_some_specialized \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled.baseline.exp new file mode 100644 index 00000000000..ef28f81d4e7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_matching.decompiled.baseline.exp @@ -0,0 +1,30 @@ +processed 15 tasks +task 0 lines 3-256: publish [module 0x42::m {] +task 1 lines 259-259: run 0x42::m::t1_is_inner1 +return values: true +task 2 lines 261-261: run 0x42::m::t2_is_inner1 +return values: false +task 3 lines 263-263: run 0x42::m::t1_inner_value +return values: 7 +task 4 lines 265-265: run 0x42::m::t1_outer_value +return values: 0 +task 5 lines 267-267: run 0x42::m::t2_outer_value +return values: 3 +task 6 lines 269-269: run 0x42::m::t3_outer_value +return values: 8 +task 7 lines 271-271: run 0x42::m::t1_outer_value_nested +return values: 27 +task 8 lines 273-273: run 0x42::m::t2_outer_value_nested +return values: 12 +task 9 lines 275-275: run 0x42::m::t1_outer_value_with_cond +return values: 1 +task 10 lines 277-277: run 0x42::m::t1_outer_value_with_cond_ref +return values: true +task 11 lines 279-279: run 0x42::m::t1_is_some +return values: false +task 12 lines 281-281: run 0x42::m::t2_is_some +return values: true +task 13 lines 283-283: run 0x42::m::t1_is_some_specialized +return values: false +task 14 lines 285-285: run 0x42::m::t2_is_some_specialized +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled new file mode 100644 index 00000000000..14e86b75cb1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled @@ -0,0 +1,53 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/enum_scoping.move` + +//# publish +module 0x42::m { + struct Box has drop { + x: u64, + } + enum Inner has drop { + Inner1 { + x: u64, + } + Inner2 { + x: u64, + y: u64, + } + } + enum Outer has drop { + None, + One { + i: Inner, + } + Two { + i: Inner, + b: Box, + } + } + public fun check_scoping(p0: &Inner): u64 { + 3 + } + fun t1_check_scoping(): u64 { + let _v0 = Outer::One{i: Inner::Inner1{x: 43}}; + let _v1 = &_v0; + 'l0: loop { + loop { + if (!(_v1 is None)) { + if (_v1 is One) break; + if (_v1 is Two) break 'l0; + abort 14566554180833181697 + }; + let Outer::None{} = _v0; + return 0 + }; + let Outer::One{i: _v2} = _v0; + let _v3 = _v2; + return check_scoping(&_v3) + }; + let Outer::Two{i: _v4, b: _v5} = _v0; + 3 + } +} + + +//# run 0x42::m::t1_check_scoping \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled.baseline.exp new file mode 100644 index 00000000000..cee698cffb7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_scoping.decompiled.baseline.exp @@ -0,0 +1,11 @@ +processed 2 tasks +task 0 lines 3-50: publish [module 0x42::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:27:30 + │ +27 │ public fun check_scoping(p0: &Inner): u64 { + │ ^^ + + +task 1 lines 53-53: run 0x42::m::t1_check_scoping +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled new file mode 100644 index 00000000000..cda2acfb302 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled @@ -0,0 +1,45 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/enum_variant_test.move` + +//# publish +module 0x42::m { + enum Data has drop { + V1 { + x: u64, + } + V2 { + x: u64, + y: bool, + } + V3, + } + fun test_v1(): bool { + let _v0 = Data::V1{x: 43}; + &_v0 is V1 + } + fun test_v1v3(): bool { + let _v0 = Data::V1{x: 43}; + let _v1 = &_v0; + let _v2 = _v1 is V1; + if (!_v2) _v2 = _v1 is V3; + let _v3 = Data::V3{}; + if (_v2) { + let _v4 = &_v3; + let _v5 = _v4 is V1; + let _v6 = _v5; + loop { + if (!_v6) { + _v5 = _v4 is V3; + if (_v5) break + }; + return _v5 + }; + return _v5 + }; + false + } +} + + +//# run 0x42::m::test_v1 + +//# run 0x42::m::test_v1v3 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled.baseline.exp new file mode 100644 index 00000000000..a17cb6a27ed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/enum_variant_test.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-40: publish [module 0x42::m {] +task 1 lines 43-43: run 0x42::m::test_v1 +return values: true +task 2 lines 45-45: run 0x42::m::test_v1v3 +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled new file mode 100644 index 00000000000..d077fc54c59 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled @@ -0,0 +1,282 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/enum/match_cover.move` + +//# publish +module 0xc0ffee::m { + enum A has drop { + V1 { + a: Q, + b: R, + } + } + enum Q has drop { + Q1, + Q2, + } + enum R has drop { + R1, + R2, + } + public fun test1(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + if (!((_v0 is V1) && (&_v0.b is R1))) { + loop { + if (_v0 is V1) { + let _v1 = &_v0.a; + let _v2 = &_v0.b; + if (_v1 is Q2) { + if (_v2 is R2) break} + }; + abort 14566554180833181697 + }; + let A::V1{a: _v3, b: _v4} = p0; + let Q::Q2{} = _v3; + let R::R2{} = _v4; + return () + }; + let A::V1{a: _v5, b: _v6} = p0; + let R::R1{} = _v6; + return () + }; + let A::V1{a: _v7, b: _v8} = p0; + let Q::Q1{} = _v7; + } + public fun test2(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + if (!((_v0 is V1) && (&_v0.b is R1))) { + assert!(_v0 is V1, 14566554180833181697); + let A::V1{a: _v1, b: _v2} = p0; + return () + }; + let A::V1{a: _v3, b: _v4} = p0; + let R::R1{} = _v4; + return () + }; + let A::V1{a: _v5, b: _v6} = p0; + let Q::Q1{} = _v5; + } + public fun test3(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + if (!((_v0 is V1) && (&_v0.b is R1))) return (); + let A::V1{a: _v1, b: _v2} = p0; + let R::R1{} = _v2; + return () + }; + let A::V1{a: _v3, b: _v4} = p0; + let Q::Q1{} = _v3; + } + public fun test4(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + assert!(_v0 is V1, 14566554180833181697); + let A::V1{a: _v1, b: _v2} = p0; + return () + }; + let A::V1{a: _v3, b: _v4} = p0; + let Q::Q1{} = _v3; + } + public fun test5(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + assert!((_v0 is V1) && (&_v0.a is Q2), 14566554180833181697); + let A::V1{a: _v1, b: _v2} = p0; + let Q::Q2{} = _v1; + return () + }; + let A::V1{a: _v3, b: _v4} = p0; + let Q::Q1{} = _v3; + } + public fun test6(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is Q1))) { + if (!((_v0 is V1) && (&_v0.a is Q2))) return (); + let A::V1{a: _v1, b: _v2} = p0; + let Q::Q2{} = _v1; + return () + }; + let A::V1{a: _v3, b: _v4} = p0; + let Q::Q1{} = _v3; + } +} + + +//# publish +module 0xc0ffee::n { + enum A has drop { + V1 { + a: P, + b: Q, + c: R, + } + } + enum P has drop { + P1, + P2, + } + enum Q has drop { + Q1, + Q2, + } + enum R has drop { + R1, + R2, + } + public fun test(p0: A) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.a is P1))) { + if (!((_v0 is V1) && (&_v0.b is Q1))) { + if (!((_v0 is V1) && (&_v0.c is R1))) { + loop { + if (_v0 is V1) { + let _v1 = &_v0.a; + let _v2 = &_v0.b; + let _v3 = &_v0.c; + if (_v1 is P2) { + if (_v2 is Q2) { + if (_v3 is R2) break}} + }; + abort 14566554180833181697 + }; + let A::V1{a: _v4, b: _v5, c: _v6} = p0; + let P::P2{} = _v4; + let Q::Q2{} = _v5; + let R::R2{} = _v6; + return () + }; + let A::V1{a: _v7, b: _v8, c: _v9} = p0; + let R::R1{} = _v9; + return () + }; + let A::V1{a: _v10, b: _v11, c: _v12} = p0; + let Q::Q1{} = _v11; + return () + }; + let A::V1{a: _v13, b: _v14, c: _v15} = p0; + let P::P1{} = _v13; + } +} + + +//# publish +module 0xc0ffee::o { + enum E has drop { + V1 { + a: F, + b: G, + } + V2 { + a: F, + b: G, + c: H, + } + } + enum F has drop { + F1, + F2 { + a: G, + } + } + enum G has drop { + G1 { + a: H, + b: H, + } + G2 { + a: H, + } + } + enum H has drop { + H1 { + a: u64, + } + H2 { + b: u64, + } + } + public fun test1(p0: E) { + let _v0 = &p0; + loop { + if (!(_v0 is V1)) { + if (_v0 is V2) break; + abort 14566554180833181697 + }; + let E::V1{a: _v1, b: _v2} = p0; + return () + }; + let E::V2{a: _v3, b: _v4, c: _v5} = p0; + } + public fun test2(p0: E) { + let _v0 = &p0; + loop { + let _v1; + if (_v0 is V1) { + _v1 = &_v0.b; + if (_v1 is G1) { + if (&_v1.a is H1) break} + }; + loop { + if (_v0 is V1) { + _v1 = &_v0.b; + if (_v1 is G1) { + if (&_v1.b is H1) break} + }; + if (!((_v0 is V1) && (&_v0.a is F1))) { + if (!((_v0 is V1) && (&_v0.a is F2))) { + assert!(_v0 is V2, 14566554180833181697); + let E::V2{a: _v2, b: _v3, c: _v4} = p0; + return () + }; + let E::V1{a: _v5, b: _v6} = p0; + let F::F2{a: _v7} = _v5; + return () + }; + let E::V1{a: _v8, b: _v9} = p0; + let F::F1{} = _v8; + return () + }; + let E::V1{a: _v10, b: _v11} = p0; + let G::G1{a: _v12, b: _v13} = _v11; + let H::H1{a: _v14} = _v13; + return () + }; + let E::V1{a: _v15, b: _v16} = p0; + let G::G1{a: _v17, b: _v18} = _v16; + let H::H1{a: _v19} = _v17; + } + public fun test3(p0: E) { + let _v0 = &p0; + if (!((_v0 is V1) && (&_v0.b is G1))) { + if (!((_v0 is V1) && (&_v0.a is F2))) { + loop { + if (_v0 is V1) { + let _v1 = &_v0.a; + let _v2 = &_v0.b; + if (_v1 is F1) { + if (_v2 is G2) { + if (&_v2.a is H2) break}} + }; + if (!((_v0 is V1) && (&_v0.a is F1))) { + assert!(_v0 is V2, 14566554180833181697); + let E::V2{a: _v3, b: _v4, c: _v5} = p0; + return () + }; + let E::V1{a: _v6, b: _v7} = p0; + let F::F1{} = _v6; + return () + }; + let E::V1{a: _v8, b: _v9} = p0; + let F::F1{} = _v8; + let G::G2{a: _v10} = _v9; + let H::H2{b: _v11} = _v10; + return () + }; + let E::V1{a: _v12, b: _v13} = p0; + let F::F2{a: _v14} = _v12; + return () + }; + let E::V1{a: _v15, b: _v16} = p0; + let G::G1{a: _v17, b: _v18} = _v16; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled.baseline.exp new file mode 100644 index 00000000000..7990a316366 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/enum/round-trip/match_cover.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-102: publish [module 0xc0ffee::m {] +task 1 lines 105-159: publish [module 0xc0ffee::n {] +task 2 lines 162-282: publish [module 0xc0ffee::o {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp new file mode 100644 index 00000000000..5711d38153c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp @@ -0,0 +1,87 @@ +processed 23 tasks +task 0 lines 2-89: publish [module 0x99::test_struct {] +task 1 lines 91-91: run --verbose --signers 0x1 -- 0x99::test_struct::init +task 2 lines 93-93: run --verbose --signers 0x1 -- 0x99::test_struct::test_exist +task 3 lines 95-95: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 +task 4 lines 97-97: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 +task 5 lines 99-101: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 [//expect to fail] +task 6 lines 102-102: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 104-106: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [//expect to fail] +task 8 lines 107-107: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 109-111: run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from [// expected to fail as the functon value has been removed above] +task 10 lines 112-115: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [/// Test cases for function values wrapped in enums as keys] +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 116-225: publish [module 0x99::test_enum {] +task 12 lines 227-229: run --verbose --signers 0x1 -- 0x99::test_enum::init [//expect to fail] +task 13 lines 230-230: run --verbose --signers 0x1 -- 0x99::test_enum::bad_init +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 232-232: run --verbose --signers 0x1 -- 0x99::test_enum::test_exist +task 15 lines 234-234: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 +task 16 lines 236-236: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 +task 17 lines 238-240: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 [//expect to fail] +task 18 lines 241-241: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 19 lines 243-245: run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from [//expect to fail] +task 20 lines 246-246: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 21 lines 248-250: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from [// expected to fail as the functon value has been removed above] +task 22 lines 251-251: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp new file mode 100644 index 00000000000..73d90c2d1d0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp @@ -0,0 +1,78 @@ +processed 23 tasks + +task 6 'run'. lines 102-102: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 8 'run'. lines 107-107: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 10 'run'. lines 112-115: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 13 'run'. lines 230-230: +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 18 'run'. lines 241-241: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 20 'run'. lines 246-246: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 22 'run'. lines 251-251: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move new file mode 100644 index 00000000000..e35e75f6e57 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move @@ -0,0 +1,251 @@ +/// Test cases for function values wrapped in structs as keys +//# publish +module 0x99::test_struct { + use std::signer; + + struct Wrapper has key, drop { + fv: |T|u64 has copy+store+drop + } + + #[persistent] + fun test(f: ||u64 has store+drop): u64 { + if (f() == 1) + 1 + else + 2 + } + + #[persistent] + fun test1(): u64 { + 1 + } + + #[persistent] + fun test2(): u64 { + 2 + } + + // store a function value of type `|T|u64` with `T = ||u64 has store+drop` + public fun init(acc: &signer){ + let f: | ||u64 has store+drop |u64 has copy+store+drop = |x| test(x); + move_to(acc, Wrapper { fv: f}); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store+drop` + // should return true + public fun test_exist(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = u64` + // should return false due to incompatible T type + public fun test_not_exist_1(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return false due to T missing `drop` + public fun test_not_exist_2(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return false due to T additionally having `copy` + public fun test_not_exist_3(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + assert!((f.fv)(test1) == 1); + assert!((f.fv)(test2) == 2); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + assert!((f.fv)(test1) == 1); + assert!((f.fv)(test2) == 2); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_move_from(acc: &signer){ + move_from>(signer::address_of(acc)); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_move_from(acc: &signer){ + move_from>(signer::address_of(acc)); + } +} + +//# run --verbose --signers 0x1 -- 0x99::test_struct::init + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from + +// expected to fail as the functon value has been removed above +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + + +/// Test cases for function values wrapped in enums as keys +//# publish +module 0x99::test_enum { + use std::signer; + + enum Wrapper has key { + V1 {fv1: |T|u64 has copy + store}, + V2 {fv1: |T|u64 has copy + drop + store} + } + + + #[persistent] + fun test(f: ||u64 has store+drop): u64 { + if (f() == 1) + 1 + else + 2 + } + + #[persistent] + fun test1(): u64 { + 1 + } + + #[persistent] + fun test2(): u64 { + 2 + } + + // store a function value of type `|T|u64` with `T = ||u64 has store+drop` + public fun init(acc: &signer){ + let f1: | ||u64 has store+drop |u64 has copy+store = |x| test(x); + let v1 = Wrapper::V1{ fv1: f1 }; + move_to(acc, v1); + } + + // failed store because resource type already exists + public fun bad_init(acc: &signer){ + let f1: | ||u64 has store+drop |u64 has copy+drop+store = |x| test(x); + let v2 = Wrapper::V2{ fv1: f1 }; + move_to(acc, v2); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store+drop` + // should return true + public fun test_exist(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = u64` + // should return true due to incompatible T type + public fun test_not_exist_1(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return true due to T missing `drop` + public fun test_not_exist_2(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return true due to T additionally having `copy` + public fun test_not_exist_3(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_borrow_from(acc: &signer){ + borrow_global>(signer::address_of(acc)); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => (*fv1)(test1), + V2{fv1} => (*fv1)(test2) + }; + assert!(res == 1, 0); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_move_from(acc: &signer){ + let f = move_from>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => fv1(test1), + V2{fv1} => fv1(test2) + }; + assert!(res == 1, 0); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_move_from(acc: &signer){ + let f = move_from>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => fv1(test1), + V2{fv1} => fv1(test2) + }; + assert!(res == 1, 0); + } + +} + +//# run --verbose --signers 0x1 -- 0x99::test_enum::init + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::bad_init + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from + +// expected to fail as the functon value has been removed above +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp new file mode 100644 index 00000000000..9bd2050f0ce --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp @@ -0,0 +1,87 @@ +processed 23 tasks +task 0 lines 2-89: publish [module 0x99::test_struct {] +task 1 lines 91-91: run --verbose --signers 0x1 -- 0x99::test_struct::init +task 2 lines 93-93: run --verbose --signers 0x1 -- 0x99::test_struct::test_exist +task 3 lines 95-95: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 +task 4 lines 97-97: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 +task 5 lines 99-101: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 [//expect to fail] +task 6 lines 102-102: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 104-106: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [//expect to fail] +task 8 lines 107-107: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 109-111: run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from [// expected to fail as the functon value has been removed above] +task 10 lines 112-115: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [/// Test cases for function values wrapped in enums as keys] +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 116-225: publish [module 0x99::test_enum {] +task 12 lines 227-229: run --verbose --signers 0x1 -- 0x99::test_enum::init [//expect to fail] +task 13 lines 230-230: run --verbose --signers 0x1 -- 0x99::test_enum::bad_init +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 7)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 232-232: run --verbose --signers 0x1 -- 0x99::test_enum::test_exist +task 15 lines 234-234: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 +task 16 lines 236-236: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 +task 17 lines 238-240: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 [//expect to fail] +task 18 lines 241-241: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 19 lines 243-245: run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from [//expect to fail] +task 20 lines 246-246: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 21 lines 248-250: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from [// expected to fail as the functon value has been removed above] +task 22 lines 251-251: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.opt-extra.exp new file mode 100644 index 00000000000..988cf73c603 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.opt-extra.exp @@ -0,0 +1,87 @@ +processed 23 tasks +task 0 lines 2-89: publish [module 0x99::test_struct {] +task 1 lines 91-91: run --verbose --signers 0x1 -- 0x99::test_struct::init +task 2 lines 93-93: run --verbose --signers 0x1 -- 0x99::test_struct::test_exist +task 3 lines 95-95: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 +task 4 lines 97-97: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 +task 5 lines 99-101: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 [//expect to fail] +task 6 lines 102-102: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 104-106: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [//expect to fail] +task 8 lines 107-107: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 109-111: run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from [// expected to fail as the functon value has been removed above] +task 10 lines 112-115: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [/// Test cases for function values wrapped in enums as keys] +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 116-225: publish [module 0x99::test_enum {] +task 12 lines 227-229: run --verbose --signers 0x1 -- 0x99::test_enum::init [//expect to fail] +task 13 lines 230-230: run --verbose --signers 0x1 -- 0x99::test_enum::bad_init +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 232-232: run --verbose --signers 0x1 -- 0x99::test_enum::test_exist +task 15 lines 234-234: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 +task 16 lines 236-236: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 +task 17 lines 238-240: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 [//expect to fail] +task 18 lines 241-241: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 19 lines 243-245: run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from [//expect to fail] +task 20 lines 246-246: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 21 lines 248-250: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from [// expected to fail as the functon value has been removed above] +task 22 lines 251-251: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 3)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp new file mode 100644 index 00000000000..5711d38153c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp @@ -0,0 +1,87 @@ +processed 23 tasks +task 0 lines 2-89: publish [module 0x99::test_struct {] +task 1 lines 91-91: run --verbose --signers 0x1 -- 0x99::test_struct::init +task 2 lines 93-93: run --verbose --signers 0x1 -- 0x99::test_struct::test_exist +task 3 lines 95-95: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 +task 4 lines 97-97: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 +task 5 lines 99-101: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 [//expect to fail] +task 6 lines 102-102: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 104-106: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [//expect to fail] +task 8 lines 107-107: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 109-111: run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from [// expected to fail as the functon value has been removed above] +task 10 lines 112-115: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from [/// Test cases for function values wrapped in enums as keys] +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 116-225: publish [module 0x99::test_enum {] +task 12 lines 227-229: run --verbose --signers 0x1 -- 0x99::test_enum::init [//expect to fail] +task 13 lines 230-230: run --verbose --signers 0x1 -- 0x99::test_enum::bad_init +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 232-232: run --verbose --signers 0x1 -- 0x99::test_enum::test_exist +task 15 lines 234-234: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 +task 16 lines 236-236: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 +task 17 lines 238-240: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 [//expect to fail] +task 18 lines 241-241: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 19 lines 243-245: run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from [//expect to fail] +task 20 lines 246-246: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 21 lines 248-250: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from [// expected to fail as the functon value has been removed above] +task 22 lines 251-251: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/index.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/index.exp index eb1ba78aa4f..bf591143194 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/index.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/index.exp @@ -1 +1,30 @@ processed 29 tasks +task 0 lines 1-364: publish [module 0x42::test {] +task 1 lines 366-366: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 368-368: run --verbose -- 0x42::test::test_resource_1 +task 3 lines 370-370: run --verbose -- 0x42::test::test_resource_2 +task 4 lines 372-372: run --verbose -- 0x42::test::test_vector +task 5 lines 374-374: run --verbose -- 0x42::test::test_two_dimension +task 6 lines 376-376: run --verbose -- 0x42::test::test_vector_borrow +task 7 lines 378-378: run --verbose -- 0x42::test::test_vector_borrow_freeze +task 8 lines 380-380: run --verbose -- 0x42::test::test_vector_borrow_mut +task 9 lines 382-382: run --verbose --signers 0x1 -- 0x42::test::init_2 +task 10 lines 384-384: run --verbose -- 0x42::test::test_resource_3 +task 11 lines 386-386: run --verbose -- 0x42::test::test_resource_freeze +task 12 lines 388-388: run --verbose -- 0x42::test::test_resource_4 +task 13 lines 390-390: run --verbose -- 0x42::test::test_resource_5 +task 14 lines 392-392: run --verbose -- 0x42::test::test_vector_const +task 15 lines 394-394: run --verbose -- 0x42::test::test_vector_in_struct +task 16 lines 396-396: run --verbose -- 0x42::test::test_vector_in_struct_2 +task 17 lines 398-398: run --verbose -- 0x42::test::test_vector_in_struct_3 +task 18 lines 400-400: run --verbose --signers 0x2 -- 0x42::test::init_3 +task 19 lines 402-402: run --verbose -- 0x42::test::test_resource_with_vector +task 20 lines 404-404: run --verbose -- 0x42::test::call_sort +task 21 lines 406-406: run --verbose -- 0x42::test::test_index_then_field_select_1 +task 22 lines 408-408: run --verbose -- 0x42::test::test_index_then_field_select_2 +task 23 lines 410-410: run --verbose -- 0x42::test::test_index_then_field_select_3 +task 24 lines 412-412: run --verbose -- 0x42::test::inc_vec_new_test +task 25 lines 414-414: run --verbose --signers 0x1 -- 0x42::test::init_receiver +task 26 lines 416-416: run --verbose -- 0x42::test::test_receiver +task 27 lines 418-418: run --verbose --signers 0x1 -- 0x42::test::init_receiver_2 +task 28 lines 420-420: run --verbose -- 0x42::test::test_receiver_2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/loop_labels.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/loop_labels.exp index 6cd67db3f64..6c9d50824c4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/loop_labels.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/loop_labels.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-18: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/eval_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/eval_order.exp index 2301000e50a..381852c3310 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/eval_order.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/eval_order.exp @@ -1 +1,7 @@ processed 6 tasks +task 0 lines 1-42: publish [module 0xc0ffee::m {] +task 1 lines 44-44: run --verbose -- 0xc0ffee::m::test0 +task 2 lines 46-46: run --verbose -- 0xc0ffee::m::test1 +task 3 lines 48-48: run --verbose -- 0xc0ffee::m::test2 +task 4 lines 50-50: run --verbose -- 0xc0ffee::m::test3 +task 5 lines 52-52: run --verbose -- 0xc0ffee::m::test4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/no_double_eval.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/no_double_eval.exp index 457ace9c4ac..7a73d6e81eb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/no_double_eval.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/no_double_eval.exp @@ -1 +1,5 @@ processed 4 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m1 {] +task 1 lines 15-26: publish [module 0xc0ffee::m2 {] +task 2 lines 28-28: run --verbose -- 0xc0ffee::m1::test +task 3 lines 30-30: run --verbose -- 0xc0ffee::m2::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled new file mode 100644 index 00000000000..14fcbcb6b2f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled @@ -0,0 +1,55 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/op_equal/eval_order.move` + +//# publish +module 0xc0ffee::m { + fun mod1(p0: &mut u64) { + *p0 = *p0 + 2; + } + fun mod2(p0: &mut u64): u64 { + let _v0 = p0; + *_v0 = *_v0 + 2; + *p0 + } + public fun test0() { + let _v0 = 1 + 2; + _v0 = _v0 + _v0; + assert!(_v0 + _v0 == 12, 14566554180833181696); + } + public fun test1() { + let _v0 = 1 + 2; + assert!(_v0 + _v0 == 6, 14566554180833181696); + } + public fun test2() { + let _v0 = 1; + mod1(&mut _v0); + assert!(_v0 + _v0 == 6, 14566554180833181696); + } + public fun test3() { + let _v0 = 1; + let _v1 = mod2(&mut _v0); + assert!(_v0 + _v1 == 6, 14566554180833181696); + } + public fun test4() { + let _v0 = vector[1, 2, 3]; + let _v1 = &_v0; + let _v2 = 0 + 1; + let _v3 = _v2; + _v3 = *0x1::vector::borrow(_v1, _v3); + let _v4 = &mut _v0; + let _v5 = _v2 + 1; + let _v6 = 0x1::vector::borrow_mut(_v4, _v5); + *_v6 = *_v6 + _v3; + assert!(_v0 == vector[1, 2, 5], 14566554180833181696); + } +} + + +//# run --verbose -- 0xc0ffee::m::test0 + +//# run --verbose -- 0xc0ffee::m::test1 + +//# run --verbose -- 0xc0ffee::m::test2 + +//# run --verbose -- 0xc0ffee::m::test3 + +//# run --verbose -- 0xc0ffee::m::test4 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled.baseline.exp new file mode 100644 index 00000000000..0c781d07bfc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/eval_order.decompiled.baseline.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 3-44: publish [module 0xc0ffee::m {] +task 1 lines 47-47: run --verbose -- 0xc0ffee::m::test0 +task 2 lines 49-49: run --verbose -- 0xc0ffee::m::test1 +task 3 lines 51-51: run --verbose -- 0xc0ffee::m::test2 +task 4 lines 53-53: run --verbose -- 0xc0ffee::m::test3 +task 5 lines 55-55: run --verbose -- 0xc0ffee::m::test4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled new file mode 100644 index 00000000000..dc11dad6cfa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled @@ -0,0 +1,37 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/op_equal/no_double_eval.move` + +//# publish +module 0xc0ffee::m1 { + fun foo(p0: &mut u64): &mut u64 { + let _v0 = p0; + *_v0 = *_v0 + 1; + p0 + } + public fun test() { + let _v0 = 1; + let _v1 = foo(&mut _v0); + *_v1 = *_v1 + 1; + assert!(_v0 == 3, 14566554180833181696); + } +} + + +//# publish +module 0xc0ffee::m2 { + fun foo(p0: &mut u64) { + *p0 = *p0 + 2; + } + public fun test() { + let _v0 = 1; + foo(&mut _v0); + foo(&mut _v0); + let _v1 = &mut _v0; + *_v1 = *_v1 + 1; + assert!(_v0 == 6, 14566554180833181696); + } +} + + +//# run --verbose -- 0xc0ffee::m1::test + +//# run --verbose -- 0xc0ffee::m2::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled.baseline.exp new file mode 100644 index 00000000000..440111423df --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/no_double_eval.decompiled.baseline.exp @@ -0,0 +1,5 @@ +processed 4 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m1 {] +task 1 lines 19-32: publish [module 0xc0ffee::m2 {] +task 2 lines 35-35: run --verbose -- 0xc0ffee::m1::test +task 3 lines 37-37: run --verbose -- 0xc0ffee::m2::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled new file mode 100644 index 00000000000..7be3818d14c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled @@ -0,0 +1,178 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/op_equal/valid.move` + +//# publish +module 0x42::test { + struct Coin has drop { + _0: u256, + } + struct Wrapper has drop { + _0: T0, + } + fun add1_new(p0: u256): u256 { + p0 + 1u256 + } + fun add1_old(p0: u256): u256 { + p0 + 1u256 + } + fun coin_inc_new_1(p0: &mut Coin) { + let _v0 = &mut p0._0; + *_v0 = *_v0 + 1u256; + } + fun coin_inc_new_2(p0: &mut Coin) { + let _v0 = &mut p0._0; + *_v0 = *_v0 + 1u256; + } + fun coin_inc_old_1(p0: &mut Coin) { + let _v0 = *&p0._0 + 1u256; + let _v1 = &mut p0._0; + *_v1 = _v0; + } + fun coin_inc_old_2(p0: &mut Coin) { + let _v0 = &mut p0._0; + *_v0 = *_v0 + 1u256; + } + fun inc_new(p0: &mut u256) { + *p0 = *p0 + 1u256; + } + fun inc_old(p0: &mut u256) { + *p0 = *p0 + 1u256; + } + fun inc_vec_coin_new(p0: vector, p1: u64): vector { + let _v0 = &mut 0x1::vector::borrow_mut(&mut p0, p1)._0; + *_v0 = *_v0 + 1u256; + p0 + } + fun inc_vec_coin_old(p0: vector, p1: u64): vector { + let _v0 = *&0x1::vector::borrow(&p0, p1)._0 + 1u256; + let _v1 = &mut 0x1::vector::borrow_mut(&mut p0, p1)._0; + *_v1 = _v0; + p0 + } + fun inc_vec_new(p0: &mut vector, p1: u64) { + let _v0 = 0x1::vector::borrow_mut(p0, p1); + *_v0 = *_v0 + 1u256; + } + fun inc_vec_old(p0: &mut vector, p1: u64) { + let _v0 = *0x1::vector::borrow(freeze(p0), p1) + 1u256; + let _v1 = 0x1::vector::borrow_mut(p0, p1); + *_v1 = _v0; + } + fun inc_vec_wrapped_coin_new(p0: vector>, p1: u64): vector> { + let _v0 = &mut (&mut 0x1::vector::borrow_mut>(&mut p0, p1)._0)._0; + *_v0 = *_v0 + 1u256; + p0 + } + fun inc_vec_wrapped_coin_old(p0: vector>, p1: u64): vector> { + let _v0 = *&(&0x1::vector::borrow>(&p0, p1)._0)._0 + 1u256; + let _v1 = &mut (&mut 0x1::vector::borrow_mut>(&mut p0, p1)._0)._0; + *_v1 = _v0; + p0 + } + fun inc_wrapped_coin_new(p0: &mut Wrapper) { + let _v0 = &mut (&mut p0._0)._0; + *_v0 = *_v0 + 1u256; + } + fun inc_wrapped_coin_old(p0: &mut Wrapper) { + let _v0 = *&(&p0._0)._0 + 1u256; + let _v1 = &mut (&mut p0._0)._0; + *_v1 = _v0; + } + fun test1() { + let _v0 = add1_old(42u256); + let _v1 = add1_new(42u256); + assert!(_v0 == _v1, 14566554180833181696); + } + fun test2() { + let _v0 = 42u256; + let _v1 = _v0; + inc_new(&mut _v0); + inc_old(&mut _v1); + assert!(_v0 == _v1, 14566554180833181696); + } + fun test3() { + let _v0 = Coin{_0: 42u256}; + let _v1 = Coin{_0: 42u256}; + let _v2 = Coin{_0: 42u256}; + let _v3 = Coin{_0: 42u256}; + coin_inc_new_1(&mut _v0); + coin_inc_new_2(&mut _v1); + coin_inc_old_1(&mut _v2); + coin_inc_old_2(&mut _v3); + let _v4 = &_v0; + let _v5 = &_v1; + assert!(_v4 == _v5, 14566554180833181696); + let _v6 = &_v0; + let _v7 = &_v2; + assert!(_v6 == _v7, 14566554180833181696); + let _v8 = &_v0; + let _v9 = &_v3; + assert!(_v8 == _v9, 14566554180833181696); + } + fun test4() { + let _v0 = Wrapper{_0: Coin{_0: 42u256}}; + let _v1 = Wrapper{_0: Coin{_0: 42u256}}; + inc_wrapped_coin_new(&mut _v0); + inc_wrapped_coin_old(&mut _v1); + assert!(_v0 == _v1, 14566554180833181696); + } + fun test5() { + let _v0 = vector[42u256]; + let _v1 = vector[42u256]; + inc_vec_new(&mut _v0, 0); + inc_vec_old(&mut _v1, 0); + assert!(_v0 == _v1, 14566554180833181696); + } + fun test6() { + let _v0 = Coin{_0: 42u256}; + let _v1 = 0x1::vector::empty(); + 0x1::vector::push_back(&mut _v1, _v0); + let _v2 = Coin{_0: 42u256}; + let _v3 = 0x1::vector::empty(); + 0x1::vector::push_back(&mut _v3, _v2); + let _v4 = inc_vec_coin_new(_v1, 0); + let _v5 = inc_vec_coin_old(_v3, 0); + assert!(_v4 == _v5, 14566554180833181696); + } + fun test7() { + let _v0 = Wrapper{_0: Coin{_0: 42u256}}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = Wrapper{_0: Coin{_0: 42u256}}; + let _v3 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v3, _v2); + let _v4 = inc_vec_wrapped_coin_new(_v1, 0); + let _v5 = inc_vec_wrapped_coin_old(_v3, 0); + assert!(_v4 == _v5, 14566554180833181696); + } + fun test8() { + let _v0 = 0; + let _v1 = vector[0u256, 1u256]; + let _v2 = &mut _v1; + let _v3 = x_plusplus(&mut _v0); + let _v4 = 0x1::vector::borrow_mut(_v2, _v3); + *_v4 = *_v4 + 1u256; + assert!(_v1 == vector[1u256, 1u256], 14566554180833181696); + } + fun x_plusplus(p0: &mut u64): u64 { + let _v0 = *p0; + *p0 = *p0 + 1; + _v0 + } +} + + +//# run --verbose -- 0x42::test::test1 + +//# run --verbose -- 0x42::test::test2 + +//# run --verbose -- 0x42::test::test3 + +//# run --verbose -- 0x42::test::test4 + +//# run --verbose -- 0x42::test::test5 + +//# run --verbose -- 0x42::test::test6 + +//# run --verbose -- 0x42::test::test7 + +//# run --verbose -- 0x42::test::test8 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled.baseline.exp new file mode 100644 index 00000000000..8efb6c2f7d8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/round-trip/valid.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 9 tasks +task 0 lines 3-161: publish [module 0x42::test {] +task 1 lines 164-164: run --verbose -- 0x42::test::test1 +task 2 lines 166-166: run --verbose -- 0x42::test::test2 +task 3 lines 168-168: run --verbose -- 0x42::test::test3 +task 4 lines 170-170: run --verbose -- 0x42::test::test4 +task 5 lines 172-172: run --verbose -- 0x42::test::test5 +task 6 lines 174-174: run --verbose -- 0x42::test::test6 +task 7 lines 176-176: run --verbose -- 0x42::test::test7 +task 8 lines 178-178: run --verbose -- 0x42::test::test8 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/valid.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/valid.exp index 8c37110a41a..efd78250666 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/valid.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/op_equal/valid.exp @@ -1 +1,10 @@ processed 9 tasks +task 0 lines 1-150: publish [module 0x42::test {] +task 1 lines 152-152: run --verbose -- 0x42::test::test1 +task 2 lines 154-154: run --verbose -- 0x42::test::test2 +task 3 lines 156-156: run --verbose -- 0x42::test::test3 +task 4 lines 158-158: run --verbose -- 0x42::test::test4 +task 5 lines 160-160: run --verbose -- 0x42::test::test5 +task 6 lines 162-162: run --verbose -- 0x42::test::test6 +task 7 lines 164-164: run --verbose -- 0x42::test::test7 +task 8 lines 166-166: run --verbose -- 0x42::test::test8 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/assign_field.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/assign_field.exp index 21bb7557901..a9cc1e822e0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/assign_field.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/assign_field.exp @@ -1,22 +1,16 @@ processed 8 tasks - -task 1 'run'. lines 122-122: +task 0 lines 1-120: publish [module 0x42::test {] +task 1 lines 122-122: run --verbose -- 0x42::test::test_simple return values: { 42, true } - -task 2 'run'. lines 124-124: +task 2 lines 124-124: run --verbose -- 0x42::test::test_simple_ref return values: { 42, true } - -task 3 'run'. lines 126-126: +task 3 lines 126-126: run --verbose -- 0x42::test::test_assign0 return values: { 0, false } - -task 4 'run'. lines 128-128: +task 4 lines 128-128: run --verbose -- 0x42::test::test_assign1 return values: 4 - -task 5 'run'. lines 130-130: +task 5 lines 130-130: run --verbose -- 0x42::test::test_assign_chained return values: { { { 0 }, 42 }, { 1 }, { { 2 }, 42 } } - -task 6 'run'. lines 132-132: +task 6 lines 132-132: run --verbose -- 0x42::test::test_assign_enum_1 return values: true - -task 7 'run'. lines 134-134: +task 7 lines 134-134: run --verbose -- 0x42::test::test_assign_enum_2 return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/common_access.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/common_access.exp index c438c0e127c..6fbe6294614 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/common_access.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/common_access.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0x42::test {] +task 1 lines 18-18: run --verbose -- 0x42::test::test_common_access return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/positional_fields.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/positional_fields.exp index 5d92c423f3f..aed4e4c4272 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/positional_fields.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/positional_fields.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0x42::test {] +task 1 lines 15-15: run --verbose -- 0x42::test::test_ok diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled new file mode 100644 index 00000000000..d6a3116708e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled @@ -0,0 +1,152 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/positional_fields/assign_field.move` + +//# publish +module 0x42::test { + enum E has drop { + V1 { + _0: u8, + _1: bool, + } + V2 { + _0: S3, + } + } + struct S3 has drop { + _0: S2, + _1: S0, + _2: S2, + } + struct S2 has copy, drop { + _0: S0, + _1: u8, + } + struct S0 has copy, drop { + x: u8, + } + struct S1 has drop { + _0: u64, + _1: bool, + } + fun assign0(p0: u64, p1: bool): S1 { + let _v0 = S1{_0: p0, _1: p1}; + while (*&(&_v0)._1) { + let _v1 = *&(&_v0)._0 - 1; + let _v2 = *&(&_v0)._0; + _v0 = S1{_0: _v1, _1: _v2 >= 2}; + continue + }; + _v0 + } + fun assign1(p0: S1): u64 { + let _v0 = 0; + loop { + let _v1; + if (!*&(&p0)._1) break; + if (*&(&p0)._0 > 0) _v1 = *&(&p0)._0 - 1 else _v1 = 0; + p0 = S1{_0: _v1, _1: _v1 >= 1}; + _v0 = _v0 + 1; + continue + }; + _v0 + } + fun assign_chained(p0: S3): S3 { + let _v0 = *&(&(&(&p0)._0)._0).x; + let _v1 = *&(&(&p0)._1).x; + let _v2 = _v0 + _v1; + let _v3 = *&(&(&(&p0)._2)._0).x; + let _v4 = _v2 + _v3; + let _v5 = &mut (&mut (&mut (&mut p0)._0)._0).x; + *_v5 = 0u8; + let _v6 = &mut (&mut (&mut p0)._1).x; + *_v6 = 1u8; + let _v7 = &mut (&mut (&mut (&mut p0)._2)._0).x; + *_v7 = 2u8; + p0 + } + fun assign_enum(p0: &mut E) { + loop { + if (!(p0 is V1)) { + if (p0 is V2) break; + abort 14566554180833181697 + }; + let _v0 = &mut p0._0; + let _v1 = &mut p0._1; + *_v0 = 42u8; + *_v1 = true; + return () + }; + let _v2 = &mut p0._0; + let _v3 = &mut (&mut (&mut _v2._0)._0).x; + *_v3 = 0u8; + let _v4 = &mut (&mut _v2._1).x; + *_v4 = 1u8; + let _v5 = &mut (&mut (&mut _v2._2)._0).x; + *_v5 = 2u8; + } + fun simple(p0: S1): S1 { + let _v0 = &mut (&mut p0)._0; + *_v0 = 42; + let _v1 = &mut (&mut p0)._1; + *_v1 = true; + p0 + } + fun simple_ref(p0: &mut S1) { + let _v0 = &mut p0._0; + *_v0 = 42; + let _v1 = &mut p0._1; + *_v1 = true; + } + fun test_assign0(): S1 { + assign0(4, true) + } + fun test_assign1(): u64 { + assign1(S1{_0: 4, _1: true}) + } + fun test_assign_chained(): S3 { + let _v0 = S0{x: 42u8}; + let _v1 = S2{_0: _v0, _1: 42u8}; + assign_chained(S3{_0: _v1, _1: _v0, _2: _v1}) + } + fun test_assign_enum_1(): bool { + let _v0 = S0{x: 43u8}; + let _v1 = S2{_0: _v0, _1: 42u8}; + let _v2 = E::V2{_0: S3{_0: _v1, _1: _v0, _2: _v1}}; + assign_enum(&mut _v2); + let _v3 = S0{x: 0u8}; + let _v4 = S0{x: 1u8}; + let _v5 = S0{x: 2u8}; + let _v6 = S2{_0: _v3, _1: 42u8}; + let _v7 = S2{_0: _v5, _1: 42u8}; + let _v8 = E::V2{_0: S3{_0: _v6, _1: _v4, _2: _v7}}; + _v2 == _v8 + } + fun test_assign_enum_2(): bool { + let _v0 = E::V1{_0: 0u8, _1: false}; + assign_enum(&mut _v0); + let _v1 = E::V1{_0: 42u8, _1: true}; + _v0 == _v1 + } + fun test_simple(): S1 { + simple(S1{_0: 0, _1: false}) + } + fun test_simple_ref(): S1 { + let _v0 = S1{_0: 0, _1: false}; + simple_ref(&mut _v0); + _v0 + } +} + + +//# run --verbose -- 0x42::test::test_simple + +//# run --verbose -- 0x42::test::test_simple_ref + +//# run --verbose -- 0x42::test::test_assign0 + +//# run --verbose -- 0x42::test::test_assign1 + +//# run --verbose -- 0x42::test::test_assign_chained + +//# run --verbose -- 0x42::test::test_assign_enum_1 + +//# run --verbose -- 0x42::test::test_assign_enum_2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled.baseline.exp new file mode 100644 index 00000000000..e0422b9711e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/assign_field.decompiled.baseline.exp @@ -0,0 +1,90 @@ +processed 8 tasks +task 0 lines 3-137: publish [module 0x42::test {] +Error: compilation errors: + error: cannot select field `_0` since it has different types in variants of enum `E` + ┌─ TEMPFILE:72:28 + │ +72 │ let _v0 = &mut p0._0; + │ ^^ + │ + = field `_0` has type `S3` in variant `V2` and type `u8` in variant `V1` + +error: cannot select field `_0` since it has different types in variants of enum `E` + ┌─ TEMPFILE:78:24 + │ +78 │ let _v2 = &mut p0._0; + │ ^^ + │ + = field `_0` has type `S3` in variant `V2` and type `u8` in variant `V1` + + +task 1 lines 140-140: run --verbose -- 0x42::test::test_simple +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 2 lines 142-142: run --verbose -- 0x42::test::test_simple_ref +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 3 lines 144-144: run --verbose -- 0x42::test::test_assign0 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 4 lines 146-146: run --verbose -- 0x42::test::test_assign1 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 148-148: run --verbose -- 0x42::test::test_assign_chained +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 6 lines 150-150: run --verbose -- 0x42::test::test_assign_enum_1 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 7 lines 152-152: run --verbose -- 0x42::test::test_assign_enum_2 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000042::test doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled new file mode 100644 index 00000000000..a8a7b0fcf35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled @@ -0,0 +1,22 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/positional_fields/common_access.move` + +//# publish +module 0x42::test { + enum Foo has drop { + A { + _0: u8, + } + B { + _0: u8, + } + } + fun common_access(p0: Foo): u8 { + *&(&p0)._0 + } + fun test_common_access(): u8 { + common_access(Foo::A{_0: 42u8}) + } +} + + +//# run --verbose -- 0x42::test::test_common_access \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled.baseline.exp new file mode 100644 index 00000000000..e97845bf8ab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/common_access.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-19: publish [module 0x42::test {] +task 1 lines 22-22: run --verbose -- 0x42::test::test_common_access +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled new file mode 100644 index 00000000000..75534facb9d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/positional_fields/positional_fields.move` + +//# publish +module 0x42::test { + struct Tup { + _0: T0, + _1: T1, + } + fun baz(p0: u64, p1: u64): u64 { + let Tup{_0: _v0, _1: _v1} = Tup{_0: p0, _1: p1}; + _v0 - _v1 + } + fun test_ok() { + assert!(baz(2, 1) == 1, 42); + } +} + + +//# run --verbose -- 0x42::test::test_ok \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled.baseline.exp new file mode 100644 index 00000000000..a43ef2d05ab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/positional_fields/round-trip/positional_fields.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0x42::test {] +task 1 lines 19-19: run --verbose -- 0x42::test::test_ok diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.baseline.exp index 5d4ffc42732..9903933dd36 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.baseline.exp @@ -1,24 +1,18 @@ processed 2 tasks +task 0 lines 1-4: print-bytecode [script {] +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret -task 0 'print-bytecode'. lines 1-4: -// Move bytecode v8 -script { +task 1 lines 6-11: print-bytecode --input=module [module 0x3::N {] +// Bytecode version v9 +module 0x3::N +// Function definition at index 0 +#[persistent] entry public fun ex(l0: signer, l1: u64) + ld_u64 0 + abort -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} -task 1 'print-bytecode'. lines 6-11: -// Move bytecode v8 -module 3.N { - - -entry public ex(Arg0: signer, Arg1: u64) /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.no-optimize.exp index ba1ffca22e1..991750b3bdf 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.no-optimize.exp @@ -1,26 +1,19 @@ processed 2 tasks +task 0 lines 1-4: print-bytecode [script {] +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret -task 0 'print-bytecode'. lines 1-4: -// Move bytecode v8 -script { +task 1 lines 6-11: print-bytecode --input=module [module 0x3::N {] +// Bytecode version v9 +module 0x3::N +// Function definition at index 0 +#[persistent] entry public fun ex(l0: signer, l1: u64) + ld_u64 0 + abort + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} -task 1 'print-bytecode'. lines 6-11: -// Move bytecode v8 -module 3.N { - - -entry public ex(Arg0: signer, Arg1: u64) /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -B1: - 2: Ret -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.opt-extra.exp new file mode 100644 index 00000000000..9903933dd36 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.opt-extra.exp @@ -0,0 +1,18 @@ +processed 2 tasks +task 0 lines 1-4: print-bytecode [script {] +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret + + +task 1 lines 6-11: print-bytecode --input=module [module 0x3::N {] +// Bytecode version v9 +module 0x3::N +// Function definition at index 0 +#[persistent] entry public fun ex(l0: signer, l1: u64) + ld_u64 0 + abort + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.optimize.exp index 5d4ffc42732..9903933dd36 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/print_bytecode.optimize.exp @@ -1,24 +1,18 @@ processed 2 tasks +task 0 lines 1-4: print-bytecode [script {] +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret -task 0 'print-bytecode'. lines 1-4: -// Move bytecode v8 -script { +task 1 lines 6-11: print-bytecode --input=module [module 0x3::N {] +// Bytecode version v9 +module 0x3::N +// Function definition at index 0 +#[persistent] entry public fun ex(l0: signer, l1: u64) + ld_u64 0 + abort -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} -task 1 'print-bytecode'. lines 6-11: -// Move bytecode v8 -module 3.N { - - -entry public ex(Arg0: signer, Arg1: u64) /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Abort -} -} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled new file mode 100644 index 00000000000..cebb480711c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled @@ -0,0 +1,44 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/assert_one.move` + +//# publish +module 0x42::Test { + struct Tester has drop { + f: u64, + } + public fun len(p0: &Tester): u64 { + *&p0.f + } + public fun modify(p0: &mut Tester): u64 { + let _v0 = *&p0.f - 1; + let _v1 = &mut p0.f; + *_v1 = _v0; + let _v2 = *&p0.f; + 9 - _v2 + } + public fun new(): Tester { + Tester{f: 10} + } +} + + +//# run +script { + use 0x42::Test; + fun main() { + let _v0 = Test::new(); + assert!(Test::len(&_v0) == 10, 70002); + let _v1 = 0; + 'l0: loop { + loop { + let _v2 = Test::len(&_v0); + if (!(_v1 < _v2)) break 'l0; + let _v3 = Test::modify(&mut _v0); + let _v4 = _v1 + 1; + if (!(_v3 == _v4)) break; + _v1 = _v1 + 1; + continue + }; + abort 14566554180833181696 + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled.baseline.exp new file mode 100644 index 00000000000..a3365af8939 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/assert_one.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0x42::Test {] +task 1 lines 24-44: run [script {] +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(14566554180833181696), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 25)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled new file mode 100644 index 00000000000..65eb4648f90 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled @@ -0,0 +1,57 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/bug_14762.move` + +//# publish +module 0x42::m { + use 0x1::option; + use 0x1::vector; + struct T has copy, drop, store { + issuer: vector, + version: u64, + } + struct J has copy, drop, store { + variant: u64, + } + struct S has copy, drop, store { + entries: vector, + } + fun test(p0: &mut S, p1: vector): option::Option { + let _v0; + let _v1 = &p0.entries; + let _v2 = false; + let _v3 = 0; + let _v4 = 0; + let _v5 = vector::length(_v1); + 'l0: loop { + loop { + if (!(_v4 < _v5)) break 'l0; + if (*&vector::borrow(_v1, _v4).issuer == p1) break; + _v4 = _v4 + 1 + }; + _v2 = true; + _v3 = _v4; + break + }; + if (_v2) _v0 = option::some(vector::remove(&mut p0.entries, _v3)) else _v0 = option::none(); + _v0 + } + fun test1() { + let _v0 = T{issuer: vector[1u8], version: 1}; + let _v1 = T{issuer: vector[2u8], version: 0}; + let _v2 = vector::empty(); + let _v3 = &mut _v2; + vector::push_back(_v3, _v0); + vector::push_back(_v3, _v1); + let _v4 = S{entries: _v2}; + let _v5 = test(&mut _v4, vector[0u8]); + assert!(option::is_none(&_v5), 0); + let _v6 = test(&mut _v4, vector[1u8]); + assert!(option::is_some(&_v6), 0); + assert!(*&option::borrow(&_v6).issuer == vector[1u8], 0); + let _v7 = test(&mut _v4, vector[2u8]); + assert!(option::is_some(&_v7), 0); + assert!(*&option::borrow(&_v7).issuer == vector[2u8], 0); + } +} + + +//# run 0x42::m::test1 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled.baseline.exp new file mode 100644 index 00000000000..54ef846c0ed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/bug_14762.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-54: publish [module 0x42::m {] +task 1 lines 57-57: run 0x42::m::test1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled new file mode 100644 index 00000000000..10170fd8ea3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled @@ -0,0 +1,34 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/calls_with_freeze.move` + +//# publish +module 0x42::m { + struct S has drop { + x: u64, + } + fun sum(p0: &S, p1: &S): u64 { + let _v0 = *&p0.x; + let _v1 = *&p1.x; + _v0 + _v1 + } + fun test(): u64 { + test_arg_freeze(S{x: 2}) + } + fun test_arg_freeze(p0: S): u64 { + let _v0 = &mut p0; + let _v1 = S{x: 4}; + let _v2 = &mut _v1; + let _v3 = freeze(_v0); + let _v4 = freeze(_v2); + let _v5 = sum(_v3, _v4); + let _v6 = freeze(_v0); + let _v7 = freeze(_v0); + let _v8 = sum(_v6, _v7); + let _v9 = &p0; + let _v10 = freeze(_v2); + let _v11 = sum(_v9, _v10); + _v5 + _v8 + _v11 + } +} + + +//# run 0x42::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled.baseline.exp new file mode 100644 index 00000000000..e05077454b9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/calls_with_freeze.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-31: publish [module 0x42::m {] +task 1 lines 34-34: run 0x42::m::test +return values: 16 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled new file mode 100644 index 00000000000..7ee6b56f55b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/const_vec.move` + +//# publish +module 0xc0ffee::m { + public fun test1(): u8 { + let _v0 = vector[0u8, 128u8]; + *0x1::vector::borrow(&_v0, 0) + } + public fun test2(): u8 { + let _v0 = vector[0u8, 128u8]; + *0x1::vector::borrow(&_v0, 0) + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled.baseline.exp new file mode 100644 index 00000000000..69cb1922d7b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/const_vec.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test1 +return values: 0 +task 2 lines 18-18: run 0xc0ffee::m::test2 +return values: 0 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled new file mode 100644 index 00000000000..5a5ef8ddfd5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled @@ -0,0 +1,233 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/fv_as_keys.move` + +//# publish +module 0x99::test_struct { + use 0x1::signer; + struct Wrapper has drop, key { + fv: |T0|(u64) has copy + drop + store, + } + public fun init(p0: &signer) { + let _v0 = Wrapper<||(u64) has drop + store>{fv: |arg0: ||(u64) has drop + store| test(arg0)}; + move_to>(p0, _v0); + } + #[persistent] + fun test(p0: ||(u64) has drop + store): u64 { + if (p0() == 1) return 1; + 2 + } + #[persistent] + fun test1(): u64 { + 1 + } + #[persistent] + fun test2(): u64 { + 2 + } + public fun test_bad_borrow_from(p0: &signer) + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = borrow_global>(_v0); + let _v2: ||u64 has copy + drop = || test1(); + let _v3 = *&_v1.fv; + assert!(_v3(_v2) == 1, 14566554180833181696); + let _v4: ||u64 has copy + drop = || test2(); + let _v5 = *&_v1.fv; + assert!(_v5(_v4) == 2, 14566554180833181696); + } + public fun test_bad_move_from(p0: &signer) + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = move_from>(_v0); + } + public fun test_borrow_from(p0: &signer) + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = borrow_global>(_v0); + let _v2: ||u64 has copy + drop = || test1(); + let _v3 = *&_v1.fv; + assert!(_v3(_v2) == 1, 14566554180833181696); + let _v4: ||u64 has copy + drop = || test2(); + let _v5 = *&_v1.fv; + assert!(_v5(_v4) == 2, 14566554180833181696); + } + public fun test_exist(p0: &signer) { + let _v0 = signer::address_of(p0); + assert!(exists>(_v0), 14566554180833181696); + } + public fun test_move_from(p0: &signer) + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = move_from>(_v0); + } + public fun test_not_exist_1(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } + public fun test_not_exist_2(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } + public fun test_not_exist_3(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } +} + + +//# run --verbose --signers 0x1 -- 0x99::test_struct::init + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + +//# publish +module 0x99::test_enum { + use 0x1::signer; + enum Wrapper has key { + V1 { + fv1: |T0|(u64) has copy + store, + } + V2 { + fv1: |T0|(u64) has copy + drop + store, + } + } + public fun init(p0: &signer) { + let _v0 = Wrapper::V1<||(u64) has drop + store>{fv1: |arg0: ||(u64) has drop + store| test(arg0)}; + move_to>(p0, _v0); + } + #[persistent] + fun test(p0: ||(u64) has drop + store): u64 { + if (p0() == 1) return 1; + 2 + } + public fun bad_init(p0: &signer) { + let _v0 = Wrapper::V2<||(u64) has drop + store>{fv1: |arg0: ||(u64) has drop + store| test(arg0)}; + move_to>(p0, _v0); + } + #[persistent] + fun test1(): u64 { + 1 + } + #[persistent] + fun test2(): u64 { + 2 + } + public fun test_bad_borrow_from(p0: &signer) + acquires Wrapper + { + let _v0 = signer::address_of(p0); + let _v1 = borrow_global>(_v0); + } + public fun test_bad_move_from(p0: &signer) + acquires Wrapper + { + let _v0; + let _v1 = signer::address_of(p0); + let _v2 = move_from>(_v1); + let _v3 = &_v2; + if (_v3 is V1) { + let Wrapper::V1<||(u64) has copy + drop + store>{fv1: _v4} = _v2; + let _v5: ||u64 has copy + drop = || test1(); + _v0 = _v4(_v5) + } else if (_v3 is V2) { + let Wrapper::V2<||(u64) has copy + drop + store>{fv1: _v6} = _v2; + let _v7: ||u64 has copy + drop = || test2(); + _v0 = _v6(_v7) + } else abort 14566554180833181697; + assert!(_v0 == 1, 0); + } + public fun test_borrow_from(p0: &signer) + acquires Wrapper + { + let _v0; + let _v1 = signer::address_of(p0); + let _v2 = borrow_global>(_v1); + if (_v2 is V1) { + let _v3 = &_v2.fv1; + let _v4: ||u64 has copy + drop = || test1(); + let _v5 = *_v3; + _v0 = _v5(_v4) + } else if (_v2 is V2) { + let _v6 = &_v2.fv1; + let _v7: ||u64 has copy + drop = || test2(); + let _v8 = *_v6; + _v0 = _v8(_v7) + } else abort 14566554180833181697; + assert!(_v0 == 1, 0); + } + public fun test_exist(p0: &signer) { + let _v0 = signer::address_of(p0); + assert!(exists>(_v0), 14566554180833181696); + } + public fun test_move_from(p0: &signer) + acquires Wrapper + { + let _v0; + let _v1 = signer::address_of(p0); + let _v2 = move_from>(_v1); + let _v3 = &_v2; + if (_v3 is V1) { + let Wrapper::V1<||(u64) has drop + store>{fv1: _v4} = _v2; + let _v5: ||u64 has copy + drop = || test1(); + _v0 = _v4(_v5) + } else if (_v3 is V2) { + let Wrapper::V2<||(u64) has drop + store>{fv1: _v6} = _v2; + let _v7: ||u64 has copy + drop = || test2(); + _v0 = _v6(_v7) + } else abort 14566554180833181697; + assert!(_v0 == 1, 0); + } + public fun test_not_exist_1(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } + public fun test_not_exist_2(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } + public fun test_not_exist_3(p0: &signer) { + let _v0 = signer::address_of(p0); + if (exists>(_v0)) abort 14566554180833181696; + } +} + + +//# run --verbose --signers 0x1 -- 0x99::test_enum::init + +//# run --verbose --signers 0x1 -- 0x99::test_enum::bad_init + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled.baseline.exp new file mode 100644 index 00000000000..45068d877fe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/fv_as_keys.decompiled.baseline.exp @@ -0,0 +1,281 @@ +processed 23 tasks +task 0 lines 3-78: publish [module 0x99::test_struct {] +Error: compilation errors: + error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has copy + drop + store` was provided + ┌─ TEMPFILE:33:17 + │ +33 │ assert!(_v3(_v2) == 1, 14566554180833181696); + │ ^^^^^^^^ + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has copy + drop + store` was provided + ┌─ TEMPFILE:36:17 + │ +36 │ assert!(_v5(_v4) == 2, 14566554180833181696); + │ ^^^^^^^^ + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has drop + store` was provided + ┌─ TEMPFILE:51:17 + │ +51 │ assert!(_v3(_v2) == 1, 14566554180833181696); + │ ^^^^^^^^ + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has drop + store` was provided + ┌─ TEMPFILE:54:17 + │ +54 │ assert!(_v5(_v4) == 2, 14566554180833181696); + │ ^^^^^^^^ + + +task 1 lines 81-81: run --verbose --signers 0x1 -- 0x99::test_struct::init +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 2 lines 83-83: run --verbose --signers 0x1 -- 0x99::test_struct::test_exist +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 3 lines 85-85: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 4 lines 87-87: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 89-89: run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 6 lines 91-91: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 7 lines 93-93: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 8 lines 95-95: run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 9 lines 97-97: run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 10 lines 99-99: run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_struct doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 11 lines 101-210: publish [module 0x99::test_enum {] +Error: compilation errors: + error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has copy + drop + store` was provided + ┌─ TEMPFILE1:149:19 + │ +149 │ _v0 = _v4(_v5) + │ ^^^^^^^^ + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has copy + drop + store` was provided + ┌─ TEMPFILE1:153:19 + │ +153 │ _v0 = _v6(_v7) + │ ^^^^^^^^ + +error: cannot select field `fv1` since it has different types in variants of enum `Wrapper<||u64 has drop + store>` + ┌─ TEMPFILE1:164:24 + │ +164 │ let _v3 = &_v2.fv1; + │ ^^^ + │ + = field `fv1` has type `|||u64 has drop + store|u64 has copy + drop + store` in variant `V2` and type `|||u64 has drop + store|u64 has copy + store` in variant `V1` + +error: cannot select field `fv1` since it has different types in variants of enum `Wrapper<||u64 has drop + store>` + ┌─ TEMPFILE1:169:24 + │ +169 │ let _v6 = &_v2.fv1; + │ ^^^ + │ + = field `fv1` has type `|||u64 has drop + store|u64 has copy + drop + store` in variant `V2` and type `|||u64 has drop + store|u64 has copy + store` in variant `V1` + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has drop + store` was provided + ┌─ TEMPFILE1:190:19 + │ +190 │ _v0 = _v4(_v5) + │ ^^^^^^^^ + +error: expected function type has argument of type `||u64 has copy + drop` but `||u64 has drop + store` was provided + ┌─ TEMPFILE1:194:19 + │ +194 │ _v0 = _v6(_v7) + │ ^^^^^^^^ + + +task 12 lines 213-213: run --verbose --signers 0x1 -- 0x99::test_enum::init +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 13 lines 215-215: run --verbose --signers 0x1 -- 0x99::test_enum::bad_init +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 14 lines 217-217: run --verbose --signers 0x1 -- 0x99::test_enum::test_exist +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 15 lines 219-219: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 16 lines 221-221: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 17 lines 223-223: run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 18 lines 225-225: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 19 lines 227-227: run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 20 lines 229-229: run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 21 lines 231-231: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 22 lines 233-233: run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000099::test_enum doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled new file mode 100644 index 00000000000..3df04868725 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled @@ -0,0 +1,404 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/index.move` + +//# publish +module 0x42::test { + struct T has copy, drop, store, key { + w: W, + } + struct W has copy, drop, store, key { + x: u64, + } + struct M has copy, drop { + vec: vector, + } + struct R has drop, key { + value: bool, + } + struct S has copy, drop, key { + t: T, + } + struct Wrapper has copy, drop, store, key { + inner: T0, + } + struct X has copy, drop, store { + value: T0, + } + struct Y has copy, drop, key { + field: T0, + } + fun init(p0: &signer) { + let _v0 = R{value: true}; + move_to(p0, _v0); + } + fun boo_1(p0: vector, p1: W): u64 { + merge(&mut (&mut 0x1::vector::borrow_mut(&mut p0, 0).t).w, p1); + *&(&(&0x1::vector::borrow(&p0, 0).t).w).x + } + fun merge(p0: &mut W, p1: W) { + let _v0 = *&(&p1).x; + let _v1 = &mut p0.x; + *_v1 = *_v1 + _v0; + } + fun boo_2(p0: vector, p1: W) { + merge(0x1::vector::borrow_mut(&mut p0, 0), p1); + assert!(*&0x1::vector::borrow(&p0, 0).x == 8, 0); + } + fun bubble_sort(p0: vector) { + let _v0 = 0x1::vector::length(&p0); + let _v1 = 0; + while (_v1 < _v0) { + let _v2 = 0; + loop { + let _v3 = _v0 - _v1 - 1; + if (!(_v2 < _v3)) break; + let _v4 = *0x1::vector::borrow(&p0, _v2); + let _v5 = &p0; + let _v6 = _v2 + 1; + let _v7 = *0x1::vector::borrow(_v5, _v6); + if (_v4 > _v7) { + let _v8 = *0x1::vector::borrow(&p0, _v2); + let _v9 = &p0; + let _v10 = _v2 + 1; + let _v11 = *0x1::vector::borrow(_v9, _v10); + let _v12 = 0x1::vector::borrow_mut(&mut p0, _v2); + *_v12 = _v11; + let _v13 = &mut p0; + let _v14 = _v2 + 1; + let _v15 = 0x1::vector::borrow_mut(_v13, _v14); + *_v15 = _v8 + }; + _v2 = _v2 + 1; + continue + }; + _v1 = _v1 + 1; + continue + }; + assert!(*0x1::vector::borrow(&p0, 0) == 1, 0); + } + fun call_sort() { + bubble_sort(vector[3, 1, 2]); + } + fun dispatch(p0: address): T0 + acquires Wrapper + { + unwrap(borrow_global>(p0)) + } + fun unwrap(p0: &Wrapper): T0 { + *&p0.inner + } + fun foo(p0: &Y>) { + assert!(*&(&p0.field).value == true, 0); + } + fun foo_1(p0: address, p1: W) + acquires S + { + merge(&mut (&mut borrow_global_mut(p0).t).w, p1); + } + fun foo_2(p0: address, p1: W) + acquires W + { + merge(borrow_global_mut(p0), p1); + } + fun greater(p0: &W, p1: W): bool { + let _v0 = *&p0.x; + let _v1 = *&(&p1).x; + _v0 > _v1 + } + fun inc_vec_new(p0: &mut vector, p1: u64) { + let _v0 = *0x1::vector::borrow(freeze(p0), p1) + 1u256; + let _v1 = 0x1::vector::borrow_mut(p0, p1); + *_v1 = _v0; + } + fun inc_vec_new_test() { + let _v0 = vector[0u256]; + let _v1 = *0x1::vector::borrow(&_v0, 0) + 1u256; + let _v2 = 0x1::vector::borrow_mut(&mut _v0, 0); + *_v2 = _v1; + assert!(*0x1::vector::borrow(&_v0, 0) == 1u256, 0); + let _v3 = &mut _v0; + inc_vec_new(_v3, 0); + assert!(*0x1::vector::borrow(freeze(_v3), 0) == 2u256, 0); + } + fun init_2(p0: &signer) { + let _v0 = Y>{field: X{value: true}}; + move_to>>(p0, _v0); + } + fun init_3(p0: &signer) { + let _v0 = Y>{field: vector[1u8, 2u8, 3u8]}; + move_to>>(p0, _v0); + } + fun init_receiver(p0: &signer) { + let _v0 = W{x: 2}; + let _v1 = S{t: T{w: _v0}}; + move_to(p0, _v0); + move_to(p0, _v1); + } + fun init_receiver_2(p0: &signer) { + let _v0 = Wrapper{inner: 2}; + move_to>(p0, _v0); + } + fun test_index_then_field_select_1() { + let _v0 = X{value: true}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = _v1; + let _v3 = &mut 0x1::vector::borrow_mut>(&mut _v2, 0).value; + *_v3 = false; + assert!(*&0x1::vector::borrow>(&_v2, 0).value == false, 0); + } + fun test_index_then_field_select_2() { + let _v0 = X{value: true}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = _v1; + let _v3 = &mut _v2; + let _v4 = &mut 0x1::vector::borrow_mut>(_v3, 0).value; + *_v4 = false; + assert!(*&0x1::vector::borrow>(freeze(_v3), 0).value == false, 0); + } + fun test_index_then_field_select_3() { + let _v0 = X{value: true}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = _v1; + assert!(*&0x1::vector::borrow>(&_v2, 0).value == true, 0); + } + fun test_receiver() + acquires S, W + { + let _v0 = W{x: 3}; + if (greater(borrow_global(@0x1), _v0)) abort 0; + foo_1(@0x1, _v0); + assert!(*&(&(&borrow_global(@0x1).t).w).x == 5, 0); + let _v1 = *borrow_global(@0x1); + let _v2 = 0x1::vector::empty(); + 0x1::vector::push_back(&mut _v2, _v1); + assert!(boo_1(_v2, _v0) == 8, 1); + foo_2(@0x1, _v0); + assert!(*&borrow_global(@0x1).x == 5, 0); + let _v3 = *borrow_global(@0x1); + let _v4 = 0x1::vector::empty(); + 0x1::vector::push_back(&mut _v4, _v3); + boo_2(_v4, _v0); + } + fun test_receiver_2() + acquires Wrapper + { + assert!(dispatch(@0x1) == 2, 0); + let _v0 = Wrapper{inner: 2}; + let _v1 = 0x1::vector::empty>(); + 0x1::vector::push_back>(&mut _v1, _v0); + let _v2 = _v1; + assert!(unwrap(0x1::vector::borrow>(&_v2, 0)) == 2, 0); + } + fun test_resource_1() + acquires R + { + assert!(*&borrow_global(@0x1).value == true, 0); + let _v0 = R{value: false}; + let _v1 = borrow_global_mut(@0x1); + *_v1 = _v0; + assert!(*&borrow_global(@0x1).value == false, 0); + } + fun test_resource_2() + acquires R + { + let _v0 = &mut borrow_global_mut(@0x1).value; + *_v0 = false; + assert!(*&borrow_global(@0x1).value == false, 1); + } + fun test_resource_3() + acquires Y + { + assert!(*&(&borrow_global>>(@0x1).field).value == true, 0); + } + fun test_resource_4() + acquires Y + { + let _v0 = &mut (&mut borrow_global_mut>>(@0x1).field).value; + *_v0 = false; + assert!(*&(&borrow_global>>(@0x1).field).value == false, 1); + } + fun test_resource_5() + acquires Y + { + let _v0 = &mut (&mut borrow_global_mut>>(@0x1).field).value; + *_v0 = false; + let _v1 = *borrow_global>>(@0x1); + assert!(*&(&(&_v1).field).value == false, 1); + } + fun test_resource_freeze() + acquires Y + { + assert!(*&(&freeze(borrow_global_mut>>(@0x1)).field).value == true, 0); + } + fun test_resource_with_vector() + acquires Y + { + assert!(*0x1::vector::borrow(&borrow_global>>(@0x2).field, 0) == 1u8, 0); + } + fun test_two_dimension() { + let _v0 = vector[vector[1, 2], vector[3, 4]]; + assert!(*0x1::vector::borrow(0x1::vector::borrow>(&_v0, 0), 0) == 1, 0); + let _v1 = 0x1::vector::borrow_mut>(&mut _v0, 0); + *_v1 = vector[2, 3, 4]; + assert!(*0x1::vector::borrow(0x1::vector::borrow>(&_v0, 0), 0) == 2, 0); + let _v2 = 0x1::vector::borrow_mut(0x1::vector::borrow_mut>(&mut _v0, 0), 1); + *_v2 = 4; + assert!(*0x1::vector::borrow(0x1::vector::borrow>(&_v0, 0), 1) == 4, 0); + let _v3 = vector[vector[1, 2], vector[3, 4]]; + let _v4 = &_v3; + let _v5 = 0 + 1; + let _v6 = 0x1::vector::borrow>(_v4, _v5); + let _v7 = _v5 - 1; + assert!(*0x1::vector::borrow(_v6, _v7) == 3, 0); + } + fun test_vector() { + let _v0 = X{value: 2}; + let _v1 = 0x1::vector::empty>(); + let _v2 = &mut _v1; + 0x1::vector::push_back>(_v2, _v0); + 0x1::vector::push_back>(_v2, _v0); + let _v3 = _v1; + assert!(*&0x1::vector::borrow>(&_v3, 0).value == 2, 0); + let _v4 = &mut 0x1::vector::borrow_mut>(&mut _v3, 0).value; + *_v4 = 3; + assert!(*&0x1::vector::borrow>(&_v3, 0).value == 3, 0); + } + fun test_vector_borrow() { + let _v0 = X{value: true}; + let _v1 = X{value: false}; + let _v2 = Y>{field: _v0}; + let _v3 = Y>{field: _v1}; + let _v4 = 0x1::vector::empty>>(); + let _v5 = &mut _v4; + 0x1::vector::push_back>>(_v5, _v2); + 0x1::vector::push_back>>(_v5, _v3); + let _v6 = _v4; + assert!(*&(&0x1::vector::borrow>>(&_v6, 0).field).value == true, 0); + assert!(*&(&0x1::vector::borrow>>(&_v6, 1).field).value == false, 0); + } + fun test_vector_borrow_freeze() { + let _v0 = X{value: true}; + let _v1 = X{value: false}; + let _v2 = Y>{field: _v0}; + let _v3 = Y>{field: _v1}; + let _v4 = 0x1::vector::empty>>(); + let _v5 = &mut _v4; + 0x1::vector::push_back>>(_v5, _v2); + 0x1::vector::push_back>>(_v5, _v3); + let _v6 = _v4; + assert!(*&(&freeze(0x1::vector::borrow_mut>>(&mut _v6, 0)).field).value == true, 0); + assert!(*&(&0x1::vector::borrow>>(&_v6, 0).field).value == true, 0); + assert!(*&(&0x1::vector::borrow>>(&_v6, 1).field).value == false, 0); + foo(freeze(0x1::vector::borrow_mut>>(&mut _v6, 0))); + } + fun test_vector_borrow_mut() { + let _v0 = X{value: true}; + let _v1 = X{value: false}; + let _v2 = Y>{field: _v0}; + let _v3 = Y>{field: _v1}; + let _v4 = 0x1::vector::empty>>(); + let _v5 = &mut _v4; + 0x1::vector::push_back>>(_v5, _v2); + 0x1::vector::push_back>>(_v5, _v3); + let _v6 = _v4; + assert!(*&(&0x1::vector::borrow>>(&_v6, 0).field).value == true, 0); + assert!(*&(&0x1::vector::borrow>>(&_v6, 1).field).value == false, 0); + let _v7 = &mut (&mut 0x1::vector::borrow_mut>>(&mut _v6, 0).field).value; + *_v7 = false; + let _v8 = &mut (&mut 0x1::vector::borrow_mut>>(&mut _v6, 1).field).value; + *_v8 = true; + assert!(*&(&0x1::vector::borrow>>(&_v6, 0).field).value == false, 0); + assert!(*&(&0x1::vector::borrow>>(&_v6, 1).field).value == true, 0); + } + fun test_vector_const() { + let _v0 = vector[1u8, 2u8, 3u8]; + assert!(*0x1::vector::borrow(&_v0, 0) == 1u8, 0); + } + fun test_vector_in_struct() { + let _v0 = M{vec: vector[1u8, 2u8, 3u8]}; + let _v1 = 0x1::vector::empty(); + let _v2 = &mut _v1; + 0x1::vector::push_back(_v2, _v0); + 0x1::vector::push_back(_v2, _v0); + let _v3 = _v1; + assert!(*&0x1::vector::borrow(&_v3, 0).vec == vector[1u8, 2u8, 3u8], 0); + } + fun test_vector_in_struct_2() { + let _v0 = M{vec: vector[1u8, 2u8, 3u8]}; + let _v1 = 0x1::vector::empty(); + let _v2 = &mut _v1; + 0x1::vector::push_back(_v2, _v0); + 0x1::vector::push_back(_v2, _v0); + let _v3 = _v1; + assert!(*0x1::vector::borrow(&0x1::vector::borrow(&_v3, 0).vec, 0) == 1u8, 0); + } + fun test_vector_in_struct_3() { + let _v0 = M{vec: vector[1u8, 2u8, 3u8]}; + let _v1 = 0x1::vector::empty(); + let _v2 = &mut _v1; + 0x1::vector::push_back(_v2, _v0); + 0x1::vector::push_back(_v2, _v0); + let _v3 = _v1; + assert!(*0x1::vector::borrow(&0x1::vector::borrow(&_v3, 0).vec, 2) == 3u8, 0); + assert!(*0x1::vector::borrow(&0x1::vector::borrow(&_v3, 1).vec, 0) == 1u8, 0); + } +} + + +//# run --verbose --signers 0x1 -- 0x42::test::init + +//# run --verbose -- 0x42::test::test_resource_1 + +//# run --verbose -- 0x42::test::test_resource_2 + +//# run --verbose -- 0x42::test::test_vector + +//# run --verbose -- 0x42::test::test_two_dimension + +//# run --verbose -- 0x42::test::test_vector_borrow + +//# run --verbose -- 0x42::test::test_vector_borrow_freeze + +//# run --verbose -- 0x42::test::test_vector_borrow_mut + +//# run --verbose --signers 0x1 -- 0x42::test::init_2 + +//# run --verbose -- 0x42::test::test_resource_3 + +//# run --verbose -- 0x42::test::test_resource_freeze + +//# run --verbose -- 0x42::test::test_resource_4 + +//# run --verbose -- 0x42::test::test_resource_5 + +//# run --verbose -- 0x42::test::test_vector_const + +//# run --verbose -- 0x42::test::test_vector_in_struct + +//# run --verbose -- 0x42::test::test_vector_in_struct_2 + +//# run --verbose -- 0x42::test::test_vector_in_struct_3 + +//# run --verbose --signers 0x2 -- 0x42::test::init_3 + +//# run --verbose -- 0x42::test::test_resource_with_vector + +//# run --verbose -- 0x42::test::call_sort + +//# run --verbose -- 0x42::test::test_index_then_field_select_1 + +//# run --verbose -- 0x42::test::test_index_then_field_select_2 + +//# run --verbose -- 0x42::test::test_index_then_field_select_3 + +//# run --verbose -- 0x42::test::inc_vec_new_test + +//# run --verbose --signers 0x1 -- 0x42::test::init_receiver + +//# run --verbose -- 0x42::test::test_receiver + +//# run --verbose --signers 0x1 -- 0x42::test::init_receiver_2 + +//# run --verbose -- 0x42::test::test_receiver_2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled.baseline.exp new file mode 100644 index 00000000000..e61351fdf35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/index.decompiled.baseline.exp @@ -0,0 +1,30 @@ +processed 29 tasks +task 0 lines 3-347: publish [module 0x42::test {] +task 1 lines 350-350: run --verbose --signers 0x1 -- 0x42::test::init +task 2 lines 352-352: run --verbose -- 0x42::test::test_resource_1 +task 3 lines 354-354: run --verbose -- 0x42::test::test_resource_2 +task 4 lines 356-356: run --verbose -- 0x42::test::test_vector +task 5 lines 358-358: run --verbose -- 0x42::test::test_two_dimension +task 6 lines 360-360: run --verbose -- 0x42::test::test_vector_borrow +task 7 lines 362-362: run --verbose -- 0x42::test::test_vector_borrow_freeze +task 8 lines 364-364: run --verbose -- 0x42::test::test_vector_borrow_mut +task 9 lines 366-366: run --verbose --signers 0x1 -- 0x42::test::init_2 +task 10 lines 368-368: run --verbose -- 0x42::test::test_resource_3 +task 11 lines 370-370: run --verbose -- 0x42::test::test_resource_freeze +task 12 lines 372-372: run --verbose -- 0x42::test::test_resource_4 +task 13 lines 374-374: run --verbose -- 0x42::test::test_resource_5 +task 14 lines 376-376: run --verbose -- 0x42::test::test_vector_const +task 15 lines 378-378: run --verbose -- 0x42::test::test_vector_in_struct +task 16 lines 380-380: run --verbose -- 0x42::test::test_vector_in_struct_2 +task 17 lines 382-382: run --verbose -- 0x42::test::test_vector_in_struct_3 +task 18 lines 384-384: run --verbose --signers 0x2 -- 0x42::test::init_3 +task 19 lines 386-386: run --verbose -- 0x42::test::test_resource_with_vector +task 20 lines 388-388: run --verbose -- 0x42::test::call_sort +task 21 lines 390-390: run --verbose -- 0x42::test::test_index_then_field_select_1 +task 22 lines 392-392: run --verbose -- 0x42::test::test_index_then_field_select_2 +task 23 lines 394-394: run --verbose -- 0x42::test::test_index_then_field_select_3 +task 24 lines 396-396: run --verbose -- 0x42::test::inc_vec_new_test +task 25 lines 398-398: run --verbose --signers 0x1 -- 0x42::test::init_receiver +task 26 lines 400-400: run --verbose -- 0x42::test::test_receiver +task 27 lines 402-402: run --verbose --signers 0x1 -- 0x42::test::init_receiver_2 +task 28 lines 404-404: run --verbose -- 0x42::test::test_receiver_2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled new file mode 100644 index 00000000000..c4b7a4e8edb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/loop_labels.move` + +//# run +script { + fun main() { + let _v0 = 0; + while (_v0 < 100) { + if (!(_v0 < 50)) { + _v0 = _v0 + 20; + continue + }; + if (_v0 < 30) { + _v0 = _v0 + 1; + continue + }; + _v0 = _v0 + 10 + }; + assert!(_v0 == 110, 14566554180833181696); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled.baseline.exp new file mode 100644 index 00000000000..ca388382fc0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/loop_labels.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-20: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled new file mode 100644 index 00000000000..7957d492950 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/no-v1-comparison/print_bytecode.move` + +//# print-bytecode +script { + fun main() { + () + } +} + + +//# print-bytecode --input=module +module 0x3::N { + public entry fun ex(p0: signer, p1: u64) { + abort 0 + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled.baseline.exp new file mode 100644 index 00000000000..0ea630b4e8e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/round-trip/print_bytecode.decompiled.baseline.exp @@ -0,0 +1,18 @@ +processed 2 tasks +task 0 lines 3-8: print-bytecode [script {] +// Bytecode version v9 +script +// Function definition at index 0 +entry public fun main() + ret + + +task 1 lines 11-16: print-bytecode --input=module [module 0x3::N {] +// Bytecode version v9 +module 0x3::N +// Function definition at index 0 +#[persistent] entry public fun ex(l0: signer, l1: u64) + ld_u64 0 + abort + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-1.exp index 435f0b7d641..69e9e2c1d1b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 10-10: +task 1 lines 10-10: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-2.exp index 3375de16595..e83811031fe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/binop_eval_order.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled new file mode 100644 index 00000000000..da0ffa4c1bb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/control_flow/binop_eval_order.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0 + 1; + _v0 + _v1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..c9cdffbd1c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/control_flow/round-trip/binop_eval_order.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-10: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test +return values: 3 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-1.exp index afbb52dc415..24d278f792c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `&&` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-2.exp index 810fe040e0d..894e9e692a3 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_01.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-1.exp index c65ab30d2e2..0c31740f775 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 31 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-2.exp index c65ab30d2e2..0c31740f775 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_02.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 31 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-1.exp index a36fe6232c6..196cfda912b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 27 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-2.exp index a36fe6232c6..196cfda912b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_03.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 27 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-1.exp index 7b3a63ae70c..6c8bb098df9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-2.exp index a36fe6232c6..196cfda912b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_04.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 27 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-1.exp index b77985cfa8d..0b22feec589 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 10-10: +task 1 lines 10-10: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-2.exp index 2e7327bcea5..f583f61f45a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_05.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 14 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-1.exp index d304dc2ef90..d72479a9d44 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 15-15: +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test return values: 37 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-2.exp index d304dc2ef90..d72479a9d44 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_06.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 15-15: +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test return values: 37 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-1.exp index 381d27874d3..0ba3d82ecbe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 14-14: +task 1 lines 14-14: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-2.exp index e9de12cfc09..38044a16afe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_07.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-1.exp index 6d71ccae99e..8799743bfca 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 14-14: +task 1 lines 14-14: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-2.exp index 14f8a2d4fe6..61af2509445 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_08.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 962 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-1.exp index 48ea04e9f17..5685b423f3a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-16: +task 0 lines 1-16: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:11:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 18-18: +task 1 lines 18-18: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-2.exp index b007961f069..a67d3a3c0e0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_09.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test return values: 890 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-1.exp index ed8eb672a0e..3b0a4529c44 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-2.exp index c1d22637df0..977b1094734 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_10.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 746 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-1.exp index 20f3e71f534..b7699ca0095 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:7:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test --args true 1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-2.exp index 27b96dbea8f..1e457fb4268 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_11.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test --args true 1 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-1.exp index 20b5da9ec87..3b5f6469242 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:7:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 12-12: +task 1 lines 12-12: run 0xc0ffee::m::test --args true Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -27,8 +25,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 14-14: +task 2 lines 14-14: run 0xc0ffee::m::test --args false Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-2.exp index c2365759ba9..9d51ef6ff7c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_12.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test --args true Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), @@ -8,8 +8,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 14-14: +task 2 lines 14-14: run 0xc0ffee::m::test --args false Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(2), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-1.exp index ba90db0306e..fd2bc94f5e7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-2.exp index a35e5625ad1..5dcaaa70e82 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_13.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-1.exp index b50b65ef099..2d09922ad52 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-26: +task 0 lines 1-26: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:16:9 @@ -63,8 +62,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 28-28: +task 1 lines 28-28: run 0xc0ffee::m::test1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -72,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-2.exp index 99b716eb7d9..e54cf2141e8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_14.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 28-28: +task 0 lines 1-26: publish [module 0xc0ffee::m {] +task 1 lines 28-28: run 0xc0ffee::m::test1 return values: 232 - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 return values: 232 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-1.exp index ef120c8cc10..8a03e523daa 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-2.exp index 27b96dbea8f..c90e8555bf1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_15.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-1.exp index bd6c7d8b9a4..d17f8bde5c6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-2.exp index 9df713f5494..bcbea34f883 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_16.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-1.exp index 15ae446143a..e1b1acc6ff4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-1.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-2.exp index 15ae446143a..e1b1acc6ff4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_17.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-1.exp index d3c38a105f3..63c0189f506 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:42 @@ -48,8 +47,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-2.exp index 79166cf94c6..22fdb0ab9e6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_18.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 29 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-1.exp index 7bf11cdd2ff..36e87a8bb19 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:4:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 8-8: +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-2.exp index 15ae446143a..e1b1acc6ff4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_19.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-1.exp index 35220377d60..ed1047c1975 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 10-10: +task 1 lines 10-10: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-2.exp index 609c1978f53..77b801d6551 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_20.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-1.exp index 7034ce05962..b066c6a8115 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:9:9 @@ -63,8 +62,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 19-19: +task 1 lines 19-19: run 0xc0ffee::m::test1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -72,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 21-21: +task 2 lines 21-21: run 0xc0ffee::m::test2 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-2.exp index 036a608d3f0..f47d279bddc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_21.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 19-19: +task 0 lines 1-17: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test1 return values: 19 - -task 2 'run'. lines 21-21: +task 2 lines 21-21: run 0xc0ffee::m::test2 return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-1.exp index 0f6970a0e1b..3842e23888a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-1.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-2.exp index 0f6970a0e1b..3842e23888a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_22.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-1.exp index 7e7ce891eba..def77e89f3b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:4:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 8-8: +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-2.exp index cdfad04a05e..3af40b0e91a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_23.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-1.exp index 7406953239f..5333160adf4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test --args 54 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-2.exp index 38788979ddf..6cecf418888 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_24.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test --args 54 return values: 168 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-1.exp index e6cb56f9822..ce72328ac43 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:42 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test --args true Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -42,8 +40,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 11-11: +task 2 lines 11-11: run 0xc0ffee::m::test --args false Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-2.exp index d11d761ac3b..ae36e64de7f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_25.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test --args true return values: 6 - -task 2 'run'. lines 11-11: +task 2 lines 11-11: run 0xc0ffee::m::test --args false return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-1.exp index 6e2852c11da..a84af1276cb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:19 @@ -93,8 +92,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-2.exp index 849f23d0492..b1af543a498 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_26.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-1.exp index a52dd3a5b32..6cbf1b441a2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `&&` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:4:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `||` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 8-8: +task 1 lines 8-8: run 0xc0ffee::m::test --args true Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -42,8 +40,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 10-10: +task 2 lines 10-10: run 0xc0ffee::m::test --args false Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-2.exp index 78a1dbf75c2..338ba58fe4f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_27.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test --args true return values: true - -task 2 'run'. lines 10-10: +task 2 lines 10-10: run 0xc0ffee::m::test --args false return values: false diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-1.exp index 3312e1da22d..3e1cb5a5abc 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `<` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-2.exp index 87fa58a2d50..6d22fb6fc3f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_28.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-1.exp index 89c906ff77c..d1abde495c2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test --args 55 return values: [55, 56, 57] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-2.exp index 89c906ff77c..d1abde495c2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_29.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test --args 55 return values: [55, 56, 57] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-1.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-2.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_30.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-1.exp index a27343fc417..e59e7a3dfee 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-26: +task 0 lines 1-26: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:13:9 @@ -63,8 +62,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 28-28: +task 1 lines 28-28: run 0xc0ffee::m::test1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -72,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-2.exp index 87b645e3088..d156bd3990c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_31.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 28-28: +task 0 lines 1-26: publish [module 0xc0ffee::m {] +task 1 lines 28-28: run 0xc0ffee::m::test1 return values: 6 - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-1.exp index eea0f7e3915..6618f06cd39 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-26: +task 0 lines 1-26: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -63,8 +62,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 28-28: +task 1 lines 28-28: run 0xc0ffee::m::test1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -72,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-2.exp index cd9a8119d7d..795ef804d2a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_32.operator-eval-lang-2.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 28-28: +task 0 lines 1-26: publish [module 0xc0ffee::m {] +task 1 lines 28-28: run 0xc0ffee::m::test1 return values: 39 - -task 2 'run'. lines 30-30: +task 2 lines 30-30: run 0xc0ffee::m::test2 return values: 99 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-1.exp index 056b438af79..9511a7d6743 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:9:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 14-14: +task 1 lines 14-14: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-2.exp index b57f0d8f1c5..a9f29f26a5f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_33.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-1.exp index 8ee94aba14b..949c33eacca 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:9:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 14-14: +task 1 lines 14-14: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-2.exp index 5d919f5557e..b55cfb1764e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_34.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-1.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-2.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_35.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-1.exp index 9ebf49ef031..9f9d75fc058 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-2.exp index 9ebf49ef031..9f9d75fc058 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_36.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-1.exp index cc213d7260d..4232b8cccbe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 25-25: +task 0 lines 1-23: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-2.exp index cc213d7260d..4232b8cccbe 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_37.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 25-25: +task 0 lines 1-23: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-1.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-2.exp index 635c7889c7e..246e4d85d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_38.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-1.exp index b30f18fbc07..6834b13cfe0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 21-21: +task 0 lines 1-19: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-2.exp index b30f18fbc07..6834b13cfe0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_39.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 21-21: +task 0 lines 1-19: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-1.exp index 9dc4fbf2445..b8be5bcf95c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 16-16: +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-2.exp index 9dc4fbf2445..b8be5bcf95c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_40.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 16-16: +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-1.exp index c151ca06520..7b9c4f66ee4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-2.exp index c151ca06520..7b9c4f66ee4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_41.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-1.exp index 3721ac7ccbf..6cc087919dd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-2.exp index 3721ac7ccbf..6cc087919dd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_42.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::test return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-1.exp index cea50312de3..4e26276026e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-2.exp index 17722043ede..a6ea7260783 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_43.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 8 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-1.exp index aa71b2ab22b..54e6dc337a4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:10 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-2.exp index aa8ddea14b0..ef70ca9df92 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_44.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-1.exp index 0eac036c98a..d7866fe60a7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-2.exp index a2985efc28a..41a9e5b7f0d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_45.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-1.exp index f44e0fc5d63..f739ee02326 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-2.exp index aa8ddea14b0..ef70ca9df92 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_46.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-1.exp index 9cd2ede1ff5..d4e5ad0b90f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-2.exp index 9cd2ede1ff5..d4e5ad0b90f 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_47.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-1.exp index 14b0414ea7d..f2f39dfc360 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-2.exp index 14b0414ea7d..f2f39dfc360 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_48.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test return values: 5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-1.exp index 8ce189d0bac..a9587fdbab6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-2.exp index 304777b2bb6..08df54bc208 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-1.exp index 51c84be14b2..a368334eff0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:8:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 13-13: +task 1 lines 13-13: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-2.exp index 304777b2bb6..08df54bc208 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_49_typed.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-1.exp index e9e713f1f4c..96404dc1bbf 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:5:9 @@ -33,8 +32,7 @@ error: A sequence within an operand of binary operation `+` can obscure program = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 9-9: +task 1 lines 9-9: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-2.exp index a35e5625ad1..5dcaaa70e82 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_50.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::test return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-1.exp index 4a6ecf66640..7e3a9174cdb 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:4:9 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 8-8: +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-2.exp index 15ae446143a..e1b1acc6ff4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_51.operator-eval-lang-2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-1.exp index e8373a19a35..d4aa3761220 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0xc0ffee::m {] Error: compilation errors: error: A sequence within an operand of binary operation `+` can obscure program logic and is not allowed by this compiler. ┌─ TEMPFILE:4:13 @@ -18,8 +17,7 @@ Error: compilation errors: = In either of these cases, please ensure to check the code does what you expect it to, because of changed semantics. - -task 1 'run'. lines 8-8: +task 1 lines 8-8: run 0xc0ffee::m::test --args 1 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-2.exp index 51ad56144aa..909612f3ecd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/op_with_side_effect_52.operator-eval-lang-2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 8-8: +task 0 lines 1-6: publish [module 0xc0ffee::m {] +task 1 lines 8-8: run 0xc0ffee::m::test --args 1 return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled new file mode 100644 index 00000000000..2b548652d99 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_01.move` + +//# publish +module 0xc0ffee::m { + fun and(p0: bool, p1: bool): bool { + if (p0) return p1; + false + } + public fun test(): bool { + let _v0 = 1 - 1; + let _v1 = _v0 == 0; + _v0 = _v0 + 3; + if (and(_v1, _v0 == 3)) return _v0 * 2 == 6; + false + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..abcc4ca6447 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_01.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled new file mode 100644 index 00000000000..11ed48b19f2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_02.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + 31 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..87f9fcd815f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_02.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test +return values: 31 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled new file mode 100644 index 00000000000..0c528417f7a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_03.move` + +//# publish +module 0xc0ffee::m { + public fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(): u64 { + let _v0 = 1 - 1; + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = add(_v1, _v2); + _v0 = _v0 * 2; + let _v4 = _v0 * 2; + let _v5 = _v0 + 1; + let _v6 = add(_v4, _v5); + add(_v3, _v6) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..91ccb3eab88 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_03.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test +return values: 27 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled new file mode 100644 index 00000000000..57598b612b2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_04.move` + +//# publish +module 0xc0ffee::m { + public fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(): u64 { + let _v0 = 1 - 1; + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = add(_v1, _v2); + _v0 = _v0 * 2; + let _v4 = _v0 * 2; + let _v5 = _v0 + 1; + let _v6 = add(_v4, _v5); + _v3 + _v6 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..91ccb3eab88 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_04.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test +return values: 27 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled new file mode 100644 index 00000000000..f961c91fc49 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_05.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0 + 2; + _v0 = _v0 + 5; + let _v2 = _v0; + _v0 = _v0 - 1; + let _v3 = _v1 + _v2; + let _v4 = _v0 * 2; + _v3 + _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..833a9aaef9a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_05.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test +return values: 14 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled new file mode 100644 index 00000000000..32ae883d895 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_06.move` + +//# publish +module 0xc0ffee::m { + fun inc(p0: &mut u64, p1: u64): u64 { + *p0 = *p0 + p1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = inc(&mut _v0, 5); + let _v2 = inc(&mut _v0, 6); + let _v3 = _v1 + _v2; + let _v4 = inc(&mut _v0, 7); + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..ca16eb79727 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_06.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test +return values: 37 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled new file mode 100644 index 00000000000..b12dd13c150 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_07.move` + +//# publish +module 0xc0ffee::m { + public fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(): u64 { + let _v0 = 1 - 1; + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = add(_v1, _v2); + let _v4 = _v0 * 2 * 2; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..88b6dd5e6d4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_07.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test +return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled new file mode 100644 index 00000000000..d3f543f9d9b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_08.move` + +//# publish +module 0xc0ffee::m { + public fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(): u64 { + let _v0 = 158 - 1; + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = _v0 * 2 * 2; + let _v4 = add(_v2, _v3); + _v1 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..f628caeb982 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_08.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test +return values: 962 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled new file mode 100644 index 00000000000..3e1ad7553ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_09.move` + +//# publish +module 0xc0ffee::m { + public fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun sub(p0: u64, p1: u64): u64 { + p0 - p1 + } + public fun test(): u64 { + let _v0 = sub(146, 1); + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = add(_v1, _v2); + let _v4 = _v0 * 2 * 2; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..45ed7ad50af --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_09.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test +return values: 890 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled new file mode 100644 index 00000000000..88637c4c535 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_10.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 122 - 1; + let _v1 = _v0 + 8; + _v0 = _v0 + 3; + let _v2 = _v0 - 3; + let _v3 = _v1 + _v2; + let _v4 = _v0 * 2 * 2; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..a5d59e3a4a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_10.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test +return values: 746 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled new file mode 100644 index 00000000000..41d1b2d50d1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_11.move` + +//# publish +module 0xc0ffee::m { + public fun aborter(p0: u64): u64 { + abort p0 + } + public fun test(p0: bool, p1: u64): u64 { + let _v0; + if (p0) _v0 = aborter(p1) else _v0 = aborter(p1 + 100); + let _v1 = aborter(p1 + 200); + _v0 + p1 + } +} + + +//# run 0xc0ffee::m::test --args true 1 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..9c9574c25dd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_11.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test --args true 1 +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled new file mode 100644 index 00000000000..69dfc5eae0b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_12.move` + +//# publish +module 0xc0ffee::m { + public fun aborter(p0: u64): u64 { + abort p0 + } + public fun test(p0: bool): u64 { + if (p0) { + let _v0 = aborter(1); + abort 3 + }; + abort 2 + } +} + + +//# run 0xc0ffee::m::test --args true + +//# run 0xc0ffee::m::test --args false \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..b200210255a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_12.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,18 @@ +processed 3 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test --args true +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 2 lines 20-20: run 0xc0ffee::m::test --args false +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(2), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 8)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled new file mode 100644 index 00000000000..b365a948595 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_13.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + 1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..c21681dc6f6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_13.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test +return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled new file mode 100644 index 00000000000..09173eb7f33 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled @@ -0,0 +1,51 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_14.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + fun inc_x(p0: &mut S, p1: u64) { + let _v0 = *&p0.x + p1; + let _v1 = &mut p0.x; + *_v1 = _v0; + } + public fun test1(): u64 { + let _v0 = S{x: 1, y: 2, z: 3}; + inc_x(&mut _v0, 6); + let _v1 = *&(&_v0).x; + inc_x(&mut _v0, 47); + let _v2 = *&(&_v0).x; + let _v3 = _v1 + _v2; + inc_x(&mut _v0, 117); + let _v4 = *&(&_v0).x; + _v3 + _v4 + } + public fun test2(): u64 { + let _v0 = S{x: 1, y: 2, z: 3}; + let _v1 = &mut _v0; + let _v2 = *&_v1.x + 6; + let _v3 = &mut _v1.x; + *_v3 = _v2; + let _v4 = *&(&_v0).x; + _v1 = &mut _v0; + let _v5 = *&_v1.x + 47; + let _v6 = &mut _v1.x; + *_v6 = _v5; + let _v7 = *&(&_v0).x; + let _v8 = _v4 + _v7; + _v1 = &mut _v0; + let _v9 = *&_v1.x + 117; + let _v10 = &mut _v1.x; + *_v10 = _v9; + let _v11 = *&(&_v0).x; + _v8 + _v11 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..5aae5c41814 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_14.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-46: publish [module 0xc0ffee::m {] +task 1 lines 49-49: run 0xc0ffee::m::test1 +return values: 232 +task 2 lines 51-51: run 0xc0ffee::m::test2 +return values: 232 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled new file mode 100644 index 00000000000..13d8474b778 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_15.move` + +//# publish +module 0xc0ffee::m { + public fun aborter(p0: u64): u64 { + abort p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = aborter(_v0); + _v0 = _v0 + 1; + let _v2 = aborter(_v0 + 100); + _v1 + _v0 + _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..4cb18b4b9b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_15.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled new file mode 100644 index 00000000000..f4d4d329a68 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_16.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + 1 + 1 + 1 + 1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..8795f14e20c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_16.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled new file mode 100644 index 00000000000..292647abec3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled @@ -0,0 +1,12 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_17.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u8 { + let _v0 = 1 - 10; + abort _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..855cec72e5d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_17.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-9: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled new file mode 100644 index 00000000000..dd786e66bd8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_18.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0; + _v0 = _v0 + 2; + let _v2 = _v0; + _v0 = _v0 + 3; + let _v3 = _v2 + _v0 + _v0; + let _v4 = _v1 + _v3; + let _v5 = _v0 + 1 + 1; + _v4 + _v5 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..f6fab640609 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_18.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test +return values: 29 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled new file mode 100644 index 00000000000..e4c2d61dd6c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled @@ -0,0 +1,12 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_19.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u8 { + let _v0 = 250u8 + 50u8; + abort 55 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..855cec72e5d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_19.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-9: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled new file mode 100644 index 00000000000..0d2a8a3cead --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_20.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1 + 1 + 1; + let _v1 = _v0; + _v0 = _v0 + 1 + 1; + let _v2 = _v1 + _v0; + let _v3 = _v0 + 1 + 1; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..266e821e6bb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_20.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 15 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled new file mode 100644 index 00000000000..bb71e21135e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled @@ -0,0 +1,41 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_21.move` + +//# publish +module 0xc0ffee::m { + fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + public fun test1(): u64 { + let _v0 = 1; + let _v1 = inc(&mut _v0); + let _v2 = inc(&mut _v0); + let _v3 = inc(&mut _v0); + let _v4 = inc(&mut _v0); + let _v5 = _v3 + _v4; + let _v6 = _v1 + _v5; + let _v7 = inc(&mut _v0); + let _v8 = inc(&mut _v0); + let _v9 = inc(&mut _v0); + _v6 + _v9 + } + public fun test2(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0; + let _v2 = inc(&mut _v1); + let _v3 = inc(&mut _v0); + let _v4 = inc(&mut _v0); + let _v5 = inc(&mut _v0); + let _v6 = _v4 + _v5; + let _v7 = _v2 + _v6; + let _v8 = inc(&mut _v0); + let _v9 = inc(&mut _v0); + let _v10 = inc(&mut _v0); + _v7 + _v10 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..1413cc9bc24 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_21.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-36: publish [module 0xc0ffee::m {] +task 1 lines 39-39: run 0xc0ffee::m::test1 +return values: 19 +task 2 lines 41-41: run 0xc0ffee::m::test2 +return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled new file mode 100644 index 00000000000..5cf08ebc824 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_22.move` + +//# publish +module 0xc0ffee::m { + fun add3(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + public fun test(): u64 { + abort 0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..239754757db --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_22.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled new file mode 100644 index 00000000000..2a6ac571e6f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_23.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + abort 0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..135a212651b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_23.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled new file mode 100644 index 00000000000..f27d4956ae2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_24.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: u64): u64 { + let _v0 = p0 + 1; + p0 = p0 + 1; + let _v1 = p0 + 1; + let _v2 = _v0 + _v1; + let _v3 = p0 + 1 + 1; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test --args 54 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..3156087306c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_24.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test --args 54 +return values: 168 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled new file mode 100644 index 00000000000..3b091e48797 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled @@ -0,0 +1,27 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_25.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: bool): u64 { + let _v0; + let _v1; + let _v2; + let _v3 = 1; + if (p0) _v2 = _v3 else { + _v3 = _v3 + 1; + _v2 = _v3 + }; + if (p0) { + _v3 = _v3 + 1; + _v1 = _v3 + } else _v1 = _v3; + if (p0) _v0 = _v3 + 1 else _v0 = _v3; + let _v4 = _v1 + _v0; + _v2 + _v4 + } +} + + +//# run 0xc0ffee::m::test --args true + +//# run 0xc0ffee::m::test --args false \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..80e011a4f5b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_25.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-22: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test --args true +return values: 6 +task 2 lines 27-27: run 0xc0ffee::m::test --args false +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled new file mode 100644 index 00000000000..b8bd97a5e40 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_26.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = _v0; + _v0 = _v0 + 1; + let _v3 = _v2 + _v0; + let _v4 = _v0 + 1; + _v0 = _v3 + _v4; + let _v5 = _v1 + _v0; + let _v6 = _v0; + _v0 = _v0 + 1; + let _v7 = _v6 + _v0; + let _v8 = _v0 + 1; + let _v9 = _v7 + _v8; + _v5 + _v9 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..fee77068843 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_26.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::test +return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled new file mode 100644 index 00000000000..76705d55102 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_27.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: bool): bool { + let _v0; + if (p0) _v0 = false else { + let _v1; + if (p0) _v1 = false else _v1 = false; + p0 = _v1; + _v0 = p0 + }; + if (_v0) return true; + !!p0 + } +} + + +//# run 0xc0ffee::m::test --args true + +//# run 0xc0ffee::m::test --args false \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..8c37fe19a35 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_27.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test --args true +return values: true +task 2 lines 21-21: run 0xc0ffee::m::test --args false +return values: false diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled new file mode 100644 index 00000000000..08653ac33bf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_28.move` + +//# publish +module 0xc0ffee::m { + public fun test(): bool { + let _v0 = 1 << 1u8; + let _v1 = _v0 << 1u8; + _v0 < _v1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..9e3e457c63c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_28.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-10: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test +return values: true diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled new file mode 100644 index 00000000000..7f68a60e3ce --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_29.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: u64): vector { + let _v0 = p0; + p0 = p0 + 1; + let _v1 = p0 + 1; + let _v2 = 0x1::vector::empty(); + let _v3 = &mut _v2; + 0x1::vector::push_back(_v3, _v0); + 0x1::vector::push_back(_v3, p0); + 0x1::vector::push_back(_v3, _v1); + _v2 + } +} + + +//# run 0xc0ffee::m::test --args 55 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..40fb61bea25 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_29.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test --args 55 +return values: [55, 56, 57] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled new file mode 100644 index 00000000000..03dfe1a8819 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_30.move` + +//# publish +module 0xc0ffee::m { + fun add2(p0: u64, p1: u64): u64 { + p0 + p1 + } + fun add3(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = add2(_v0, 1); + let _v2 = add2(_v0, 1); + add3(_v1, _v0, _v2) + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..b524c88b005 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_30.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled new file mode 100644 index 00000000000..a850428eef3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled @@ -0,0 +1,45 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_31.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + fun inc_x(p0: &mut S) { + let _v0 = *&p0.x + 1; + let _v1 = &mut p0.x; + *_v1 = _v0; + } + fun inc_xx(p0: &mut S, p1: u64) { + let _v0 = *&p0.x + p1; + let _v1 = &mut p0.x; + *_v1 = _v0; + } + public fun test1(): u64 { + let _v0 = S{x: 1, y: 2, z: 3}; + let _v1 = *&(&_v0).x; + inc_x(&mut _v0); + let _v2 = *&(&_v0).x; + let _v3 = _v1 + _v2; + inc_x(&mut _v0); + let _v4 = *&(&_v0).x; + _v3 + _v4 + } + public fun test2(): u64 { + let _v0 = S{x: 1, y: 2, z: 3}; + let _v1 = *&(&_v0).x; + inc_xx(&mut _v0, 3); + let _v2 = *&(&_v0).x; + let _v3 = _v1 + _v2; + inc_xx(&mut _v0, 11); + let _v4 = *&(&_v0).x; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..c65958f023d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_31.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-40: publish [module 0xc0ffee::m {] +task 1 lines 43-43: run 0xc0ffee::m::test1 +return values: 6 +task 2 lines 45-45: run 0xc0ffee::m::test2 +return values: 20 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled new file mode 100644 index 00000000000..c9fcd2e1e75 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled @@ -0,0 +1,61 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_32.move` + +//# publish +module 0xc0ffee::m { + fun add3(p0: u64, p1: u64, p2: u64): u64 { + p0 + p1 + p2 + } + fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + fun inc_by(p0: &mut u64, p1: u64): u64 { + *p0 = *p0 + p1; + *p0 + } + public fun test1(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = _v0; + _v0 = inc(&mut _v0); + let _v3 = _v0; + _v0 = _v0 + 1; + let _v4 = _v0; + _v0 = _v0 + 1; + let _v5 = add3(_v3, _v4, _v0); + _v0 = inc(&mut _v0) + 1; + let _v6 = _v0; + let _v7 = _v0; + _v0 = _v0 + 1; + let _v8 = add3(_v6, _v7, _v0); + let _v9 = add3(_v2, _v5, _v8); + let _v10 = _v1 + _v9; + let _v11 = inc(&mut _v0) + 1; + _v10 + _v11 + } + public fun test2(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = _v0; + _v0 = inc_by(&mut _v0, 3); + let _v3 = _v0; + _v0 = _v0 + 1; + let _v4 = _v0; + _v0 = _v0 + 1; + let _v5 = add3(_v3, _v4, _v0); + _v0 = inc(&mut _v0) + 1; + let _v6 = _v0; + let _v7 = _v0; + _v0 = _v0 + 1; + let _v8 = add3(_v6, _v7, _v0); + let _v9 = add3(_v2, _v5, _v8); + let _v10 = _v1 + _v9; + let _v11 = inc_by(&mut _v0, 47) + 1; + _v10 + _v11 + } +} + + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..4307d982719 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_32.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-56: publish [module 0xc0ffee::m {] +task 1 lines 59-59: run 0xc0ffee::m::test1 +return values: 39 +task 2 lines 61-61: run 0xc0ffee::m::test2 +return values: 99 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled new file mode 100644 index 00000000000..c1146f1db7c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_33.move` + +//# publish +module 0xc0ffee::m { + public fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + _v0 = inc(&mut _v0) + 1; + let _v1 = _v0 + _v0; + let _v2 = inc(&mut _v0) + 1; + _v1 + _v2 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..aa8e361d884 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_33.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::test +return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled new file mode 100644 index 00000000000..2935db9d5da --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_34.move` + +//# publish +module 0xc0ffee::m { + public fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = inc(&mut _v0) + 1; + let _v2 = _v1 + _v0; + let _v3 = inc(&mut _v0) + 1; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..2372fd275fe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_34.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test +return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled new file mode 100644 index 00000000000..4fda98183bf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_35.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0 + 1; + let S{x: _v3, y: _v4, z: _v5} = S{x: _v1, y: _v0, z: _v2}; + _v3 + _v4 + _v5 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..b524c88b005 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_35.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled new file mode 100644 index 00000000000..5438f4e72a1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_36.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0; + _v0 = _v0 + 1; + _v1 + _v2 + _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d65aa0bf796 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_36.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled new file mode 100644 index 00000000000..ed9a2a737ed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_37.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + fun inc(p0: &mut u64): u64 { + *p0 = *p0 + 1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = inc(&mut _v0); + let _v3 = inc(&mut _v0); + let S{x: _v4, y: _v5, z: _v6} = S{x: _v1, y: _v2, z: _v3}; + _v4 + _v5 + _v6 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d77c1d2c78b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_37.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-22: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled new file mode 100644 index 00000000000..2cf49fc37ea --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_38.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0 + 1; + let S{x: _v3, y: _v4, z: _v5} = S{x: _v1, y: _v0, z: _v2}; + _v3 + _v4 + _v5 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..b524c88b005 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_38.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled new file mode 100644 index 00000000000..49e5bf592eb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_39.move` + +//# publish +module 0xc0ffee::m { + struct S has drop { + x: u64, + y: u64, + z: u64, + } + fun inc(p0: &mut u64, p1: u64): u64 { + *p0 = *p0 + p1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = inc(&mut _v0, 7); + let _v3 = inc(&mut _v0, 11); + let S{x: _v4, y: _v5, z: _v6} = S{x: _v1, y: _v2, z: _v3}; + _v4 + _v5 + _v6 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..187f4870778 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_39.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-22: publish [module 0xc0ffee::m {] +task 1 lines 25-25: run 0xc0ffee::m::test +return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled new file mode 100644 index 00000000000..55956d3ad06 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled @@ -0,0 +1,21 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_40.move` + +//# publish +module 0xc0ffee::m { + struct S { + x: u64, + y: u64, + z: u64, + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0 + 1; + let S{x: _v3, y: _v4, z: _v5} = S{x: _v1, y: _v0, z: _v2}; + _v3 + _v4 + _v5 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..b524c88b005 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_40.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-18: publish [module 0xc0ffee::m {] +task 1 lines 21-21: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled new file mode 100644 index 00000000000..8dc1c859439 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_41.move` + +//# publish +module 0xc0ffee::m { + fun inc(p0: &mut u64, p1: u64): u64 { + *p0 = *p0 + p1; + *p0 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = inc(&mut _v0, 7); + let _v3 = _v1 + _v2; + let _v4 = inc(&mut _v0, 11); + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d6e2456d6b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_41.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test +return values: 28 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled new file mode 100644 index 00000000000..c04501e56bd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_42.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0 + 1; + _v0 = _v0 + 1; + let _v2 = _v0 + 7; + _v0 = _v0 + 1 - 3; + _v1 + _v2 + _v0 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..9cc62d7f39b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_42.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled new file mode 100644 index 00000000000..28f34404f16 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_43.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v0 - 1; + let _v3 = _v1 + _v2; + let _v4 = (_v0 + 1) * 2; + _v3 + _v4 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..9030f03ef63 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_43.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test +return values: 8 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled new file mode 100644 index 00000000000..421ffcfbbe7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_44.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v1 + _v0; + let _v3 = _v0 + 1; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d65aa0bf796 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_44.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled new file mode 100644 index 00000000000..198721efef4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_45.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1 + 1; + let _v1 = _v0 + _v0; + let _v2 = _v0 + 1; + _v1 + _v2 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..83f391e10b7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_45.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test +return values: 7 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled new file mode 100644 index 00000000000..a6c0a7432b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_46.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v1 + _v0; + let _v3 = _v0 + 1; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d65aa0bf796 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_46.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled new file mode 100644 index 00000000000..8f3c9f254be --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_47.move` + +//# publish +module 0xc0ffee::m { + fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + let _v2 = &mut _v0; + *_v2 = *_v2 + 1; + let _v3 = *_v2; + let _v4 = _v1 + _v3; + _v2 = &mut _v0; + *_v2 = *_v2 + 1; + let _v5 = *_v2; + _v4 + _v5 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..4e9969ebf9f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_47.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled new file mode 100644 index 00000000000..801e5b441a5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_48.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1 + 1; + let _v1 = 1 + _v0; + let _v2 = 1 + 1; + _v1 + _v2 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..35a52f02f22 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_48.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test +return values: 5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled new file mode 100644 index 00000000000..060cd635a66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_49.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v1 + _v0; + let _v3 = _v0 + 7; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..4b83a8a3fb1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled new file mode 100644 index 00000000000..9db94d1cc59 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_49_typed.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let _v0 = 1; + let _v1 = _v0; + _v0 = _v0 + 1; + let _v2 = _v1 + _v0; + let _v3 = _v0 + 7; + _v2 + _v3 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..4b83a8a3fb1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_49_typed.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 12 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled new file mode 100644 index 00000000000..eab5fac85e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_50.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + 1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..c21681dc6f6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_50.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test +return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled new file mode 100644 index 00000000000..042bc93d193 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled @@ -0,0 +1,12 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_51.move` + +//# publish +module 0xc0ffee::m { + public fun test(): u8 { + let _v0 = 250u8 + 50u8; + 55u8 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..855cec72e5d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_51.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-9: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test +Error: Function execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xc0ffee::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled new file mode 100644 index 00000000000..270c69ab6cb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/op_with_side_effect_52.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: u64): u64 { + let _v0 = p0 + 1; + let _v1 = p0 + _v0; + 1 + _v1 + } +} + + +//# run 0xc0ffee::m::test --args 1 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..54ac87a6689 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/op_with_side_effect_52.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-10: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test --args 1 +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled new file mode 100644 index 00000000000..2743d91f573 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled @@ -0,0 +1,25 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/underscore.move` + +//# run 0xc0ffee::m::test --args 4 + +//# run 0xc0ffee::m::test3 --args 5 + +//# run 0xc0ffee::m::test4 --args 5 + +//# run 0xc0ffee::m::test5 --args 5 + +//# run 0xc0ffee::m::test6 --args 5 + +//# run 0xc0ffee::m::test7 --args 5 + +//# run 0xc0ffee::m::test8 --args 5 + +//# run 0xc0ffee::m::test9 + +//# run 0xc0ffee::m::test10a + +//# run 0xc0ffee::m::test10b + +//# run 0xc0ffee::m::test10c + +//# run 0xc0ffee::m::test11 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..87163eec43a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,97 @@ +processed 12 tasks +task 0 lines 3-3: run 0xc0ffee::m::test --args 4 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 1 lines 5-5: run 0xc0ffee::m::test3 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 7-7: run 0xc0ffee::m::test4 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 3 lines 9-9: run 0xc0ffee::m::test5 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 4 lines 11-11: run 0xc0ffee::m::test6 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 5 lines 13-13: run 0xc0ffee::m::test7 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 6 lines 15-15: run 0xc0ffee::m::test8 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 7 lines 17-17: run 0xc0ffee::m::test9 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 8 lines 19-19: run 0xc0ffee::m::test10a +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 9 lines 21-21: run 0xc0ffee::m::test10b +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 10 lines 23-23: run 0xc0ffee::m::test10c +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 11 lines 25-25: run 0xc0ffee::m::test11 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled new file mode 100644 index 00000000000..ceb2c4672e4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled @@ -0,0 +1,13 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/underscore_v1.move` + +//# run 0xc0ffee::m::test --args 4 + +//# run 0xc0ffee::m::test3 --args 5 + +//# run 0xc0ffee::m::test4 --args 5 + +//# run 0xc0ffee::m::test5 --args 5 + +//# run 0xc0ffee::m::test6 --args 5 + +//# run 0xc0ffee::m::test11 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..1fd38676b26 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v1.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,49 @@ +processed 6 tasks +task 0 lines 3-3: run 0xc0ffee::m::test --args 4 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 1 lines 5-5: run 0xc0ffee::m::test3 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 2 lines 7-7: run 0xc0ffee::m::test4 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 3 lines 9-9: run 0xc0ffee::m::test5 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 4 lines 11-11: run 0xc0ffee::m::test6 --args 5 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} +task 5 lines 13-13: run 0xc0ffee::m::test11 +Error: Function execution failed with VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled new file mode 100644 index 00000000000..f238e886d64 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/operator_eval/underscore_v2.move` + +//# publish +module 0xc0ffee::m { + public fun test10b(): u64 { + 7 + } + public fun test10c(): u64 { + 7 + } + public fun test11(): u64 { + 1 + } + fun test2(): (u32, u64) { + (1u32, 2) + } + public fun test9(): u64 { + 7 + } +} + + +//# run 0xc0ffee::m::test9 + +//# run 0xc0ffee::m::test10b + +//# run 0xc0ffee::m::test10c + +//# run 0xc0ffee::m::test11 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled.operator-eval-lang-2.exp new file mode 100644 index 00000000000..d0e63dd6b5a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/round-trip/underscore_v2.decompiled.operator-eval-lang-2.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::test9 +return values: 7 +task 2 lines 25-25: run 0xc0ffee::m::test10b +return values: 7 +task 3 lines 27-27: run 0xc0ffee::m::test10c +return values: 7 +task 4 lines 29-29: run 0xc0ffee::m::test11 +return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-1.exp index 720220bf528..a37e7684bb2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 13 tasks - -task 0 'publish'. lines 1-77: +task 0 lines 1-77: publish [module 0xc0ffee::m {] Error: compilation errors: error: undeclared `_` ┌─ TEMPFILE:32:9 @@ -39,8 +38,7 @@ error: cannot pass `integer` to a function which expects argument of type `|u64| │ ^ - -task 1 'run'. lines 79-79: +task 1 lines 79-79: run 0xc0ffee::m::test --args 4 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -48,8 +46,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 81-81: +task 2 lines 81-81: run 0xc0ffee::m::test3 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -57,8 +54,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 3 'run'. lines 83-83: +task 3 lines 83-83: run 0xc0ffee::m::test4 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -66,8 +62,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 4 'run'. lines 85-85: +task 4 lines 85-85: run 0xc0ffee::m::test5 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -75,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 5 'run'. lines 87-87: +task 5 lines 87-87: run 0xc0ffee::m::test6 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -84,8 +78,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 6 'run'. lines 89-89: +task 6 lines 89-89: run 0xc0ffee::m::test7 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -93,8 +86,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 7 'run'. lines 91-91: +task 7 lines 91-91: run 0xc0ffee::m::test8 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -102,8 +94,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 8 'run'. lines 93-93: +task 8 lines 93-93: run 0xc0ffee::m::test9 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -111,8 +102,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 9 'run'. lines 95-95: +task 9 lines 95-95: run 0xc0ffee::m::test10a Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -120,8 +110,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 10 'run'. lines 97-97: +task 10 lines 97-97: run 0xc0ffee::m::test10b Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -129,8 +118,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 11 'run'. lines 99-99: +task 11 lines 99-99: run 0xc0ffee::m::test10c Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -138,8 +126,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 12 'run'. lines 101-101: +task 12 lines 101-101: run 0xc0ffee::m::test11 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-2.exp index 54e50a100ff..265c590650e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore.operator-eval-lang-2.exp @@ -1,6 +1,5 @@ processed 13 tasks - -task 0 'publish'. lines 1-77: +task 0 lines 1-77: publish [module 0xc0ffee::m {] Error: compilation errors: error: undeclared `_` ┌─ TEMPFILE:7:17 @@ -87,8 +86,7 @@ error: cannot pass `integer` to a function which expects argument of type `|u64| │ ^ - -task 1 'run'. lines 79-79: +task 1 lines 79-79: run 0xc0ffee::m::test --args 4 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -96,8 +94,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 81-81: +task 2 lines 81-81: run 0xc0ffee::m::test3 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -105,8 +102,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 3 'run'. lines 83-83: +task 3 lines 83-83: run 0xc0ffee::m::test4 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -114,8 +110,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 4 'run'. lines 85-85: +task 4 lines 85-85: run 0xc0ffee::m::test5 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -123,8 +118,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 5 'run'. lines 87-87: +task 5 lines 87-87: run 0xc0ffee::m::test6 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -132,8 +126,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 6 'run'. lines 89-89: +task 6 lines 89-89: run 0xc0ffee::m::test7 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -141,8 +134,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 7 'run'. lines 91-91: +task 7 lines 91-91: run 0xc0ffee::m::test8 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -150,8 +142,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 8 'run'. lines 93-93: +task 8 lines 93-93: run 0xc0ffee::m::test9 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -159,8 +150,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 9 'run'. lines 95-95: +task 9 lines 95-95: run 0xc0ffee::m::test10a Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -168,8 +158,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 10 'run'. lines 97-97: +task 10 lines 97-97: run 0xc0ffee::m::test10b Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -177,8 +166,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 11 'run'. lines 99-99: +task 11 lines 99-99: run 0xc0ffee::m::test10c Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -186,8 +174,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 12 'run'. lines 101-101: +task 12 lines 101-101: run 0xc0ffee::m::test11 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-1.exp index 22e0cf9bc39..99b593a0e34 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-1.exp @@ -1,19 +1,14 @@ processed 7 tasks - -task 1 'run'. lines 79-79: +task 0 lines 1-77: publish [module 0xc0ffee::m {] +task 1 lines 79-79: run 0xc0ffee::m::test --args 4 return values: 11 - -task 2 'run'. lines 81-81: +task 2 lines 81-81: run 0xc0ffee::m::test3 --args 5 return values: 13 - -task 3 'run'. lines 83-83: +task 3 lines 83-83: run 0xc0ffee::m::test4 --args 5 return values: 5 - -task 4 'run'. lines 85-85: +task 4 lines 85-85: run 0xc0ffee::m::test5 --args 5 return values: 5 - -task 5 'run'. lines 87-99: +task 5 lines 87-99: run 0xc0ffee::m::test6 --args 5 [// //# run 0xc0ffee::m::test7 --args 5] return values: 5 - -task 6 'run'. lines 101-101: +task 6 lines 101-101: run 0xc0ffee::m::test11 return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-2.exp index c39460deb5e..9dc3959ec2a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v1.operator-eval-lang-2.exp @@ -1,6 +1,5 @@ processed 7 tasks - -task 0 'publish'. lines 1-77: +task 0 lines 1-77: publish [module 0xc0ffee::m {] Error: compilation errors: error: undeclared `_` ┌─ TEMPFILE:7:17 @@ -63,8 +62,7 @@ error: undeclared `_` │ ^ - -task 1 'run'. lines 79-79: +task 1 lines 79-79: run 0xc0ffee::m::test --args 4 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -72,8 +70,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 81-81: +task 2 lines 81-81: run 0xc0ffee::m::test3 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -81,8 +78,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 3 'run'. lines 83-83: +task 3 lines 83-83: run 0xc0ffee::m::test4 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -90,8 +86,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 4 'run'. lines 85-85: +task 4 lines 85-85: run 0xc0ffee::m::test5 --args 5 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -99,8 +94,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 5 'run'. lines 87-99: +task 5 lines 87-99: run 0xc0ffee::m::test6 --args 5 [// //# run 0xc0ffee::m::test7 --args 5] Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -108,8 +102,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 6 'run'. lines 101-101: +task 6 lines 101-101: run 0xc0ffee::m::test11 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-1.exp index 5e6e808093c..3b8f27cc2d7 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-1.exp @@ -1,6 +1,5 @@ processed 5 tasks - -task 0 'publish'. lines 1-91: +task 0 lines 1-91: publish [module 0xc0ffee::m {] Error: compilation errors: error: duplicate declaration of `_` ┌─ TEMPFILE:38:37 @@ -19,8 +18,7 @@ error: duplicate declaration of `_` │ previous declaration of `_` - -task 1 'run'. lines 93-95: +task 1 lines 93-95: run 0xc0ffee::m::test9 [// //# run 0xc0ffee::m::test10a] Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -28,8 +26,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 97-97: +task 2 lines 97-97: run 0xc0ffee::m::test10b Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -37,8 +34,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 3 'run'. lines 99-99: +task 3 lines 99-99: run 0xc0ffee::m::test10c Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, @@ -46,8 +42,7 @@ Error: Function execution failed with VMError: { indices: [], offsets: [], } - -task 4 'run'. lines 101-101: +task 4 lines 101-101: run 0xc0ffee::m::test11 Error: Function execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-2.exp index 19c195f0b1d..a32ff89bf5e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operator_eval/underscore_v2.operator-eval-lang-2.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 93-95: +task 0 lines 1-91: publish [module 0xc0ffee::m {] +task 1 lines 93-95: run 0xc0ffee::m::test9 [// //# run 0xc0ffee::m::test10a] return values: 7 - -task 2 'run'. lines 97-97: +task 2 lines 97-97: run 0xc0ffee::m::test10b return values: 7 - -task 3 'run'. lines 99-99: +task 3 lines 99-99: run 0xc0ffee::m::test10c return values: 7 - -task 4 'run'. lines 101-101: +task 4 lines 101-101: run 0xc0ffee::m::test11 return values: 1 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp index 9e61625c3e8..04c64cff400 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 50-56: +task 3 lines 35-48: run [script {] +task 4 lines 50-56: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 58-64: +task 5 lines 58-64: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 80-86: +task 6 lines 66-78: run [script {] +task 7 lines 80-86: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 8 'run'. lines 88-94: +task 8 lines 88-94: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +50,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 113-119: +task 9 lines 98-111: run [script {] +task 10 lines 113-119: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +59,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 121-127: +task 11 lines 121-127: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +67,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 131-137: +task 12 lines 131-137: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +75,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 155-161: +task 13 lines 140-153: run [script {] +task 14 lines 155-161: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +84,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 163-169: +task 15 lines 163-169: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -98,8 +92,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 171-177: +task 16 lines 171-177: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp index 61b2ca7d4d4..28d9670c58c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 48-54: +task 3 lines 33-46: run [script {] +task 4 lines 48-54: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 56-62: +task 5 lines 56-62: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 79-85: +task 6 lines 65-77: run [script {] +task 7 lines 79-85: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 8 'run'. lines 87-93: +task 8 lines 87-93: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +50,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 112-119: +task 9 lines 97-110: run [script {] +task 10 lines 112-119: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +59,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 121-126: +task 11 lines 121-126: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +67,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 128-134: +task 12 lines 128-134: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +75,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 152-158: +task 13 lines 137-150: run [script {] +task 14 lines 152-158: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +84,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 160-166: +task 15 lines 160-166: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -98,8 +92,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 168-174: +task 16 lines 168-174: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp index 3a73a6934df..8c0fe048012 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 48-54: +task 3 lines 33-46: run [script {] +task 4 lines 48-54: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 56-62: +task 5 lines 56-62: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 79-85: +task 6 lines 65-77: run [script {] +task 7 lines 79-85: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,9 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 112-119: +task 8 lines 87-93: run [script {] +task 9 lines 97-110: run [script {] +task 10 lines 112-119: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +52,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 121-126: +task 11 lines 121-126: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +60,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 128-134: +task 12 lines 128-134: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +68,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 152-158: +task 13 lines 137-150: run [script {] +task 14 lines 152-158: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +77,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 160-166: +task 15 lines 160-166: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +85,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 168-174: +task 16 lines 168-174: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp index 3a73a6934df..8c0fe048012 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 48-54: +task 3 lines 33-46: run [script {] +task 4 lines 48-54: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 56-62: +task 5 lines 56-62: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 79-85: +task 6 lines 65-77: run [script {] +task 7 lines 79-85: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,9 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 112-119: +task 8 lines 87-93: run [script {] +task 9 lines 97-110: run [script {] +task 10 lines 112-119: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +52,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 121-126: +task 11 lines 121-126: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +60,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 128-134: +task 12 lines 128-134: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +68,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 152-158: +task 13 lines 137-150: run [script {] +task 14 lines 152-158: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +77,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 160-166: +task 15 lines 160-166: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +85,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 168-174: +task 16 lines 168-174: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp index 47054063f0b..eb2366330a9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 50-56: +task 3 lines 35-48: run [script {] +task 4 lines 50-56: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 58-64: +task 5 lines 58-64: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 81-87: +task 6 lines 67-79: run [script {] +task 7 lines 81-87: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 8 'run'. lines 89-95: +task 8 lines 89-95: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +50,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 114-121: +task 9 lines 99-112: run [script {] +task 10 lines 114-121: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +59,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 123-128: +task 11 lines 123-128: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +67,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 130-136: +task 12 lines 130-136: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +75,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 154-160: +task 13 lines 139-152: run [script {] +task 14 lines 154-160: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +84,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 162-168: +task 15 lines 162-168: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -98,8 +92,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 170-176: +task 16 lines 170-176: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp index fde7dbe2181..658f23c665e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp @@ -1,6 +1,6 @@ processed 17 tasks - -task 1 'run'. lines 17-23: +task 0 lines 1-15: run [script {] +task 1 lines 17-23: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 25-31: +task 2 lines 25-31: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +16,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 48-54: +task 3 lines 33-46: run [script {] +task 4 lines 48-54: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +25,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 56-62: +task 5 lines 56-62: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +33,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 79-85: +task 6 lines 65-77: run [script {] +task 7 lines 79-85: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +42,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 8 'run'. lines 87-93: +task 8 lines 87-93: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +50,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 111-117: +task 9 lines 96-109: run [script {] +task 10 lines 111-117: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +59,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 119-125: +task 11 lines 119-125: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +67,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'run'. lines 127-133: +task 12 lines 127-133: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +75,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'run'. lines 152-158: +task 13 lines 137-150: run [script {] +task 14 lines 152-158: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +84,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'run'. lines 160-166: +task 15 lines 160-166: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -98,8 +92,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 168-174: +task 16 lines 168-174: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp index fc5a4436b29..413e91c93f0 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-48: run [script {] +task 1 lines 51-99: run [script {] +task 2 lines 102-156: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp index 11df43aa478..e6e344742f8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp @@ -1,6 +1,11 @@ processed 35 tasks - -task 6 'run'. lines 182-188: +task 0 lines 2-31: run [script {] +task 1 lines 32-61: run [script {] +task 2 lines 62-91: run [script {] +task 3 lines 92-121: run [script {] +task 4 lines 122-151: run [script {] +task 5 lines 152-181: run [script {] +task 6 lines 182-188: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +13,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 7 'run'. lines 190-196: +task 7 lines 190-196: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,8 +21,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 8 'run'. lines 198-204: +task 8 lines 198-204: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -26,8 +29,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 9 'run'. lines 206-212: +task 9 lines 206-212: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -35,8 +37,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 10 'run'. lines 214-220: +task 10 lines 214-220: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -44,8 +45,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 11 'run'. lines 222-228: +task 11 lines 222-228: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -53,8 +53,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 12 'run'. lines 230-236: +task 12 lines 230-236: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -62,8 +61,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 13 'run'. lines 238-244: +task 13 lines 238-244: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -71,8 +69,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 14 'run'. lines 246-252: +task 14 lines 246-252: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -80,8 +77,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 15 'run'. lines 254-262: +task 15 lines 254-262: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -89,8 +85,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 16 'run'. lines 263-269: +task 16 lines 263-269: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -98,8 +93,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 17 'run'. lines 271-277: +task 17 lines 271-277: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -107,8 +101,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 18 'run'. lines 279-285: +task 18 lines 279-285: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -116,8 +109,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 19 'run'. lines 287-293: +task 19 lines 287-293: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -125,8 +117,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 20 'run'. lines 295-301: +task 20 lines 295-301: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -134,8 +125,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 21 'run'. lines 303-309: +task 21 lines 303-309: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -143,8 +133,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 22 'run'. lines 311-317: +task 22 lines 311-317: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -152,8 +141,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 23 'run'. lines 319-325: +task 23 lines 319-325: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -161,8 +149,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 24 'run'. lines 327-335: +task 24 lines 327-335: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -170,8 +157,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 25 'run'. lines 336-342: +task 25 lines 336-342: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -179,8 +165,8 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 27 'run'. lines 352-358: +task 26 lines 344-350: run [script {] +task 27 lines 352-358: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -188,8 +174,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 28 'run'. lines 360-366: +task 28 lines 360-366: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -197,8 +182,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 29 'run'. lines 368-374: +task 29 lines 368-374: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -206,8 +190,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 30 'run'. lines 376-382: +task 30 lines 376-382: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -215,8 +198,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 31 'run'. lines 384-392: +task 31 lines 384-392: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -224,8 +206,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 32 'run'. lines 393-399: +task 32 lines 393-399: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -233,8 +214,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 33 'run'. lines 401-407: +task 33 lines 401-407: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -242,8 +222,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 34 'run'. lines 409-415: +task 34 lines 409-415: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp index 2301000e50a..48478c99607 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp @@ -1 +1,7 @@ processed 6 tasks +task 0 lines 1-26: run [script {] +task 1 lines 28-55: run [script {] +task 2 lines 57-84: run [script {] +task 3 lines 86-113: run [script {] +task 4 lines 115-142: run [script {] +task 5 lines 144-171: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp index 6cd67db3f64..6429215c5c5 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled new file mode 100644 index 00000000000..cc5c75f57e1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u128.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1u128 + 340282366920938463463374607431768211455u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 264235234643575437864589745863652363451u128 + 98731747836156137656137643716471364731u128; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u128 - 1u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 54u128 - 100u128; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551616u128 * 18446744073709551616u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 170141183460469231731687303715884105728u128 * 2u128; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u128 / 0u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u128 / 0u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 / 0u128; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u128 % 0u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u128 % 0u128; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 % 0u128; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled.baseline.exp new file mode 100644 index 00000000000..dc8139c228c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u128.decompiled.baseline.exp @@ -0,0 +1,102 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled new file mode 100644 index 00000000000..055986f4e85 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u16.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1u16 + 65535u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 65135u16 + 6555u16; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u16 - 1u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 54u16 - 100u16; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 32767u16 * 32767u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 33767u16 * 2u16; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u16 / 0u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u16 / 0u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 65535u16 / 0u16; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u16 % 0u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u16 % 0u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 65535u16 % 0u16; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled.baseline.exp new file mode 100644 index 00000000000..dc8139c228c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u16.decompiled.baseline.exp @@ -0,0 +1,102 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled new file mode 100644 index 00000000000..3465bae3b93 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u256.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 105792089237316195423570985008687907853269984665640564039457584007913129639935u256 + 105792089237316195423570985008687907853269984665640564039457584007913129639935u256; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u256 - 1u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 54u256 - 100u256; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 578960446186580977117853953926634992332820282019728792003956564819967u256 * 57896044618343953926634992332820282019728792003956564819967u256; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u256 / 0u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u256 / 0u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 / 0u256; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u256 % 0u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u256 % 0u256; + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967294u256 % 0u256; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled.baseline.exp new file mode 100644 index 00000000000..64d1e9e6ce4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u256.decompiled.baseline.exp @@ -0,0 +1,95 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled new file mode 100644 index 00000000000..bd9704d3aa7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u32.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1u32 + 4294967295u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967295u32 + 4294967295u32; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u32 - 1u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 54u32 - 100u32; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1147483647u32 * 2147483647u32; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u32 / 0u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u32 / 0u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967294u32 / 0u32; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u32 % 0u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u32 % 0u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967294u32 % 0u32; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled.baseline.exp new file mode 100644 index 00000000000..64d1e9e6ce4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u32.decompiled.baseline.exp @@ -0,0 +1,95 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled new file mode 100644 index 00000000000..d9c8392990d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u64.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1 + 18446744073709551615; + } +} + + +//# run +script { + fun main() { + let _v0 = 12000000000000000000 + 10000000000000000000; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0 - 1; + } +} + + +//# run +script { + fun main() { + let _v0 = 54 - 100; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967296 * 4294967296; + } +} + + +//# run +script { + fun main() { + let _v0 = 9223372036854775808 * 2; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0 / 0; + } +} + + +//# run +script { + fun main() { + let _v0 = 1 / 0; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551615 / 0; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0 % 0; + } +} + + +//# run +script { + fun main() { + let _v0 = 1 % 0; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551615 % 0; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled.baseline.exp new file mode 100644 index 00000000000..dc8139c228c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u64.decompiled.baseline.exp @@ -0,0 +1,102 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled new file mode 100644 index 00000000000..61157622637 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled @@ -0,0 +1,136 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/arithmetic_operators_u8.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 1u8 + 255u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 215u8 + 156u8; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u8 - 1u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 54u8 - 100u8; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 16u8 * 16u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 128u8 * 2u8; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u8 / 0u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u8 / 0u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 255u8 / 0u8; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 0u8 % 0u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 1u8 % 0u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 255u8 % 0u8; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled.baseline.exp new file mode 100644 index 00000000000..dc8139c228c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/arithmetic_operators_u8.decompiled.baseline.exp @@ -0,0 +1,102 @@ +processed 17 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 5 lines 43-48: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 6 lines 51-56: run [script {] +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 8 lines 67-72: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 9 lines 75-80: run [script {] +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 13 lines 107-112: run [script {] +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled new file mode 100644 index 00000000000..ccbb69ac7bb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/bitwise_operators.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..0d77bc655db --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/bitwise_operators.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +task 2 lines 19-24: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled new file mode 100644 index 00000000000..5a0b9139c57 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/boolean_operators.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/boolean_operators.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled new file mode 100644 index 00000000000..b9d5205c57f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled @@ -0,0 +1,280 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/casting_operators.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 256 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 303 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 256u128 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 56432u128 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551615 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 2561u16 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 65532u16 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 256123u32 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 11579208923731619542357098500868790785326998466564056403945758400791312963993u256 as u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 256343532 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 3564603 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 256666765790535666u128 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 256765735666u128 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551615 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 429496729u32 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 42949629u32 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 115792089237316195423570985008687907853269984665640564039457584007913129639u256 as u16; + } +} + + +//# run +script { + fun main() { + let _v0 = 4294967295644 as u32; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + let _v0 = 256666765790535666u128 as u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 25676573566896u128 as u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551615 as u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 as u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 115792089237316195423570985008687907853269984665640564039457584007913129639u256 as u32; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551616u128 as u64; + } +} + + +//# run +script { + fun main() { + let _v0 = 18446744073709551647u128 as u64; + } +} + + +//# run +script { + fun main() { + let _v0 = 340282366920938463463374607431768211455u128 as u64; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..df4f76083dd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/casting_operators.decompiled.baseline.exp @@ -0,0 +1,232 @@ +processed 35 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +task 2 lines 19-24: run [script {] +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +task 5 lines 43-48: run [script {] +task 6 lines 51-56: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 7 lines 59-64: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 8 lines 67-72: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 9 lines 75-80: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 10 lines 83-88: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 11 lines 91-96: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 12 lines 99-104: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 13 lines 107-112: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 14 lines 115-120: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 15 lines 123-128: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 16 lines 131-136: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 17 lines 139-144: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 18 lines 147-152: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 19 lines 155-160: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 20 lines 163-168: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 21 lines 171-176: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 22 lines 179-184: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 23 lines 187-192: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 24 lines 195-200: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 25 lines 203-208: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 26 lines 211-216: run [script {] +task 27 lines 219-224: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 28 lines 227-232: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 29 lines 235-240: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 30 lines 243-248: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 31 lines 251-256: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 32 lines 259-264: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 33 lines 267-272: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} +task 34 lines 275-280: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled new file mode 100644 index 00000000000..45513923969 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled @@ -0,0 +1,48 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/comparison_operators.move` + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..907d7bf6f72 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/comparison_operators.decompiled.baseline.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 3-8: run [script {] +task 1 lines 11-16: run [script {] +task 2 lines 19-24: run [script {] +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +task 5 lines 43-48: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled new file mode 100644 index 00000000000..e5e287681a4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/precedence.move` + +//# run +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled.baseline.exp new file mode 100644 index 00000000000..8e33008573e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/precedence.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled new file mode 100644 index 00000000000..3720db1ac31 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled @@ -0,0 +1,79 @@ +//**** Cross-compiled for `move` syntax from `tests/operators/shift_operators.move` + +//# run +script { + fun main() { + let _v0 = 0u8 << 8u8; + } +} + + +//# run +script { + fun main() { + let _v0 = 0u8 >> 8u8; + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + () + } +} + + +//# run +script { + fun main() { + assert!(7u8 << 7u8 == 128u8, 5000); + assert!(7 << 62u8 == 13835058055282163712, 5001); + assert!(2u128 << 127u8 == 0u128, 5002); + assert!(7u16 << 15u8 == 32768u16, 5003); + assert!(17u32 << 30u8 == 1073741824u32, 5004); + assert!(7u256 << 254u8 == 86844066927987146567678238756515930889952488499230423029593188005934847229952u256, 5005); + } +} + + +//# run +script { + fun main() { + assert!(54u8 << 3u8 == 176u8, 6000); + assert!(124u8 << 5u8 == 128u8, 6002); + assert!(345325745376476456 << 47u8 == 2203386117691015168, 6102); + assert!(8629035907847368941279654523567912314u128 << 77u8 == 317056859699765342273530379836650946560u128, 6201); + assert!(295429678238907658936718926478967892769u128 << 83u8 == 78660438169199498567214234129963941888u128, 6203); + assert!(1234u16 << 12u8 == 8192u16, 6301); + assert!(6553u16 << 15u8 == 32768u16, 6302); + assert!(1234567u32 << 12u8 == 761819136u32, 6400); + assert!(1234567u32 << 17u8 == 2903375872u32, 6401); + assert!(12345671u32 << 27u8 == 939524096u32, 6402); + assert!(1234536789093546757803786604381691994985672142341299639418u256 << 202u8 == 33658913632735705985908889087832028406806276615240336691180752852867975479296u256, 6504); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled.baseline.exp new file mode 100644 index 00000000000..25588beaf5d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/round-trip/shift_operators.decompiled.baseline.exp @@ -0,0 +1,23 @@ +processed 8 tasks +task 0 lines 3-8: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 1 lines 11-16: run [script {] +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} +task 2 lines 19-24: run [script {] +task 3 lines 27-32: run [script {] +task 4 lines 35-40: run [script {] +task 5 lines 43-48: run [script {] +task 6 lines 51-61: run [script {] +task 7 lines 64-79: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp index 7f3f68dc1c8..6f7ddbb7e57 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp @@ -1,6 +1,5 @@ processed 8 tasks - -task 0 'run'. lines 1-8: +task 0 lines 1-8: run [// Number of bits shifted >= total number of bits in the number.] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 1 'run'. lines 10-18: +task 1 lines 10-18: run [script {] Error: Script execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, @@ -17,3 +15,9 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } +task 2 lines 19-27: run [script {] +task 3 lines 28-48: run [script {] +task 4 lines 49-70: run [script {] +task 5 lines 71-85: run [script {] +task 6 lines 86-100: run [script {] +task 7 lines 101-131: run [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/args_with_side_effects.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/args_with_side_effects.exp index 73532b7e4c8..0a0908b7226 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/args_with_side_effects.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/args_with_side_effects.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 13-13: +task 0 lines 1-11: publish [module 0xc0ffee::m {] +task 1 lines 13-13: run 0xc0ffee::m::test --args 5 return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/borrowed_var.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/borrowed_var.exp index 5d92c423f3f..e4e70a64f01 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/borrowed_var.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/borrowed_var.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_1.exp index 5d92c423f3f..3595585f8c2 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_2.exp index 5d92c423f3f..ce8babfde23 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-18: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_3.exp index 5d92c423f3f..ce8babfde23 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/branch_3.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-18: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_12068.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_12068.exp index 5d92c423f3f..e8f90539c7d 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_12068.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_12068.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x32::m {] +task 1 lines 13-13: run 0x32::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_13488_missing_copy.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_13488_missing_copy.exp index fc5a4436b29..91639b5c361 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_13488_missing_copy.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_13488_missing_copy.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-24: publish [module 0xc0ffee::m {] +task 1 lines 26-26: run 0xc0ffee::m::test +task 2 lines 28-28: run 0xc0ffee::m::test2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.baseline.exp index de563b8b65e..f3de01272ad 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.baseline.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.baseline.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xCAFE::m {] +task 1 lines 12-12: run 0xCAFE::m::f Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.no-optimize.exp index d7200f08d85..145540f7a50 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.no-optimize.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xCAFE::m {] +task 1 lines 12-12: run 0xCAFE::m::f Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.opt-extra.exp new file mode 100644 index 00000000000..f3de01272ad --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.opt-extra.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 1-10: publish [module 0xCAFE::m {] +task 1 lines 12-12: run 0xCAFE::m::f +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0xcafe::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.optimize.exp index de563b8b65e..f3de01272ad 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/bug_14223_unused_non_droppable.optimize.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 12-12: +task 0 lines 1-10: publish [module 0xCAFE::m {] +task 1 lines 12-12: run 0xCAFE::m::f Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(1), diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_1.exp index 5d92c423f3f..aadb69d5f84 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-17: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_2.exp index 5d92c423f3f..b5d7ad416cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/call_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-18: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_coalesce_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_coalesce_1.exp index 5d92c423f3f..469da439d74 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_coalesce_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_coalesce_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_copy_propagate.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_copy_propagate.exp index 5d92c423f3f..53077be26ff 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_copy_propagate.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cant_copy_propagate.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-22: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/conditional.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/conditional.exp index 5d92c423f3f..b5d7ad416cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/conditional.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/conditional.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-18: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_1.exp index 457ace9c4ac..a694bbef8d6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_1.exp @@ -1 +1,5 @@ processed 4 tasks +task 0 lines 1-41: publish [module 0xc0ffee::m {] +task 1 lines 43-43: run 0xc0ffee::m::test1 --args 42 +task 2 lines 45-45: run 0xc0ffee::m::test2 --args 42 +task 3 lines 47-47: run 0xc0ffee::m::test5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_2.exp index 5d92c423f3f..f12ecc9a343 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-27: publish [module 0xc0ffee::m {] +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_3.exp index 5d92c423f3f..f12ecc9a343 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_3.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-27: publish [module 0xc0ffee::m {] +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_4.exp index 5d92c423f3f..77d1cbbc6a3 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_4.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_4.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-29: publish [module 0xc0ffee::m {] +task 1 lines 31-31: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_5.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_5.exp index 5d92c423f3f..95a924c260b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_5.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/consume_5.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-43: publish [module 0xc0ffee::m {] +task 1 lines 45-45: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignment_without_use.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignment_without_use.exp index 5d92c423f3f..83474ba890c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignment_without_use.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignment_without_use.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-10: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test --args 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignments.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignments.exp index b6266d50187..d4b53ed3541 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignments.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_assignments.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 11-11: +task 0 lines 1-9: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::cyclic --args 42 return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_dead_store.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_dead_store.exp index c0c66a95005..9560dbb2e58 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_dead_store.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/cyclic_dead_store.exp @@ -1,13 +1,10 @@ processed 5 tasks - -task 1 'run'. lines 24-24: +task 0 lines 1-22: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::test1 --args 0 55 66 return values: 55 - -task 2 'run'. lines 26-26: +task 2 lines 26-26: run 0xc0ffee::m::test1 --args 5 55 66 return values: 66 - -task 3 'run'. lines 28-28: +task 3 lines 28-28: run 0xc0ffee::m::test2 --args 0 55 return values: 55 - -task 4 'run'. lines 30-30: +task 4 lines 30-30: run 0xc0ffee::m::test2 --args 5 55 return values: 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_1.exp index 8efb46b9417..1882234fbce 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 10-10: +task 0 lines 1-8: publish [module 0xc0ffee::m {] +task 1 lines 10-10: run 0xc0ffee::m::dead --args 55 return values: 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_2.exp index cb956307519..8bd94908c64 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 9-9: +task 0 lines 1-7: publish [module 0xc0ffee::m {] +task 1 lines 9-9: run 0xc0ffee::m::dead --args 53 return values: 53 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_3.exp index a66c937c6a8..7c48e8851dd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_3.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 17-17: +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test --args true return values: 1 - -task 2 'run'. lines 19-19: +task 2 lines 19-19: run 0xc0ffee::m::test --args false return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_4.exp index 5d92c423f3f..159202b1cd8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_4.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_assignment_4.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-31: publish [module 0xc0ffee::m {] +task 1 lines 33-33: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_loads.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_loads.exp index 5d92c423f3f..16c3b69fdc9 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_loads.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_loads.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::check diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_1.exp index 9032e4522e7..e02495556ee 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 16-16: +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test return values: 47 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_2.exp index 63d05eb655c..a0d985a342b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 18-18: +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test return values: 10 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_3.exp index a42f2598a3a..ef248315ac4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/dead_store_calls_3.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 14-14: +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test --args 42 return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_1.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_2.exp index 5d92c423f3f..c9d803a98d6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/immut_refs_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1.exp index 5d92c423f3f..b8927cb8cba 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::Test {] +task 1 lines 16-16: run 0x42::Test::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1_typed.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1_typed.exp index 5d92c423f3f..b8927cb8cba 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1_typed.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/inlining1_typed.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42::Test {] +task 1 lines 16-16: run 0x42::Test::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_1.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_2.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_3.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/intermingled_3.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_1.exp index 5d92c423f3f..e55660ee6d1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-17: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_2.exp index 5d92c423f3f..e55660ee6d1 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/loop_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-17: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/multi_assigns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/multi_assigns.exp index 5d92c423f3f..469da439d74 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/multi_assigns.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/multi_assigns.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_1.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_2.exp index 5d92c423f3f..65d7329262b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/mut_refs_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-20: publish [module 0xc0ffee::m {] +task 1 lines 22-22: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars1.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars_diff_type.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars_diff_type.exp index 5d92c423f3f..fa4a5dcd8cd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars_diff_type.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/non_overlapping_vars_diff_type.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/overlapping_vars.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/overlapping_vars.exp index 5d92c423f3f..f665ed5ca40 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/overlapping_vars.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/overlapping_vars.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/reassigned_var.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/reassigned_var.exp index 5d92c423f3f..f665ed5ca40 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/reassigned_var.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/reassigned_var.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled new file mode 100644 index 00000000000..beb5782e895 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/args_with_side_effects.move` + +//# publish +module 0xc0ffee::m { + fun add(p0: u64, p1: u64): u64 { + p0 + p1 + } + public fun test(p0: u64): u64 { + let _v0 = p0 + 1; + add(p0, _v0) + } +} + + +//# run 0xc0ffee::m::test --args 5 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled.baseline.exp new file mode 100644 index 00000000000..5f77aab9801 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/args_with_side_effects.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test --args 5 +return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled new file mode 100644 index 00000000000..bc0afef2c4a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/borrowed_var.move` + +//# publish +module 0xc0ffee::m { + fun test() { + let _v0 = 5; + let _v1 = &_v0; + let _v2 = 5; + assert!(*&_v2 == 5, 0); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled.baseline.exp new file mode 100644 index 00000000000..2aaa6aa5ffd --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/borrowed_var.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled new file mode 100644 index 00000000000..c5095eb5764 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/branch_1.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: bool, p1: u64): u64 { + if (p0) p1 = 0; + p1 + 1 + } + public fun test() { + assert!(foo(true, 15) == 1, 0); + assert!(foo(false, 5) == 6, 1); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled.baseline.exp new file mode 100644 index 00000000000..4c3ef916789 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled new file mode 100644 index 00000000000..1671992852f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/branch_2.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: bool, p1: u64, p2: u64): u64 { + let _v0; + if (p0) _v0 = p1 else _v0 = p2; + _v0 + } + public fun test() { + assert!(foo(true, 4, 5) == 4, 0); + assert!(foo(false, 4, 5) == 5, 0); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled.baseline.exp new file mode 100644 index 00000000000..8907b1c1317 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled new file mode 100644 index 00000000000..768bc8f3c8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/branch_3.move` + +//# publish +module 0xc0ffee::m { + fun foo(p0: bool, p1: u64): u64 { + let _v0; + if (p0) _v0 = p1 else _v0 = p1; + _v0 + } + public fun test() { + assert!(foo(true, 5) == 5, 0); + assert!(foo(false, 5) == 5, 2); + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled.baseline.exp new file mode 100644 index 00000000000..8907b1c1317 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/branch_3.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled new file mode 100644 index 00000000000..e45996e9e4d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/bug_12068.move` + +//# publish +module 0x32::m { + public fun main() { + assert!(0 + 1 == 1, 42); + } +} + + +//# run 0x32::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled.baseline.exp new file mode 100644 index 00000000000..f4b9b8a6769 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_12068.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0x32::m {] +task 1 lines 11-11: run 0x32::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled new file mode 100644 index 00000000000..89a89e095e3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/bug_13488_missing_copy.move` + +//# publish +module 0xc0ffee::m { + fun test() { + let _v0 = 0; + let _v1 = &_v0; + let _v2 = 0; + let _v3 = &_v2; + let _v4 = 0 + 0; + assert!(*_v1 == 0, 1); + assert!(*_v3 == 0, 1); + } + fun test2() { + let _v0 = 2; + let _v1 = &_v0; + let _v2 = 2; + let _v3 = &_v2; + assert!(2 + 2 == 4, 1); + } +} + + +//# run 0xc0ffee::m::test + +//# run 0xc0ffee::m::test2 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled.baseline.exp new file mode 100644 index 00000000000..53e51c0042c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_13488_missing_copy.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 3 tasks +task 0 lines 3-21: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::test +task 2 lines 26-26: run 0xc0ffee::m::test2 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled new file mode 100644 index 00000000000..455c24d6271 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/bug_14223_unused_non_droppable.move` + +//# publish +module 0xcafe::m { + struct S { + } + public fun f() { + let _v0 = S{}; + abort 1 + } +} + + +//# run 0xCAFE::m::f \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled.baseline.exp new file mode 100644 index 00000000000..e80b878129e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/bug_14223_unused_non_droppable.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xcafe::m {] +task 1 lines 14-14: run 0xCAFE::m::f +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0xcafe::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled new file mode 100644 index 00000000000..b75b1969eef --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/call_1.move` + +//# publish +module 0xc0ffee::m { + fun id(p0: u64): u64 { + p0 + } + public fun run() { + assert!(test(50) == 50, 0); + } + fun test(p0: u64): u64 { + id(id(id(p0))) + } +} + + +//# run 0xc0ffee::m::run \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled.baseline.exp new file mode 100644 index 00000000000..2761bd5743b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled new file mode 100644 index 00000000000..cf9df91b170 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled @@ -0,0 +1,19 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/call_2.move` + +//# publish +module 0xc0ffee::m { + fun update(p0: &mut u64) { + *p0 = 0; + } + public fun main() { + assert!(test(5) == 5, 0); + } + fun test(p0: u64): u64 { + let _v0 = p0; + update(&mut _v0); + p0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled.baseline.exp new file mode 100644 index 00000000000..a2491274c67 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/call_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-16: publish [module 0xc0ffee::m {] +task 1 lines 19-19: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled new file mode 100644 index 00000000000..470e5ee944a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/cant_coalesce_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(5) == 2, 0); + } + public fun test(p0: u64): u64 { + let _v0 = p0 + p0; + 2 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_coalesce_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled new file mode 100644 index 00000000000..b0e39e21ba2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled @@ -0,0 +1,22 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/cant_copy_propagate.move` + +//# publish +module 0xc0ffee::m { + fun consume(p0: u64) { + () + } + public fun main() { + test(42, true); + test(42, false); + } + fun test(p0: u64, p1: bool) { + if (p1) { + consume(p0); + return () + }; + let _v0 = p0 + 1; + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled.baseline.exp new file mode 100644 index 00000000000..b551cfff61a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cant_copy_propagate.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-19: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:5:17 + │ +5 │ fun consume(p0: u64) { + │ ^^ + + +task 1 lines 22-22: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled new file mode 100644 index 00000000000..b17f476a2a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/conditional.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(true) == 3, 0); + assert!(test(false) == 3, 1); + } + fun test(p0: bool): u64 { + if (p0) return 3; + 3 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled.baseline.exp new file mode 100644 index 00000000000..f97a490fc44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/conditional.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled new file mode 100644 index 00000000000..163212699e5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled @@ -0,0 +1,42 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/consume_1.move` + +//# publish +module 0xc0ffee::m { + struct W has copy, drop { + x: u64, + } + fun consume(p0: u64) { + () + } + fun consume_(p0: W) { + () + } + public fun test1(p0: u64) { + consume(p0); + consume(p0); + } + public fun test2(p0: u64) { + consume(p0); + consume(p0); + } + public fun test3(p0: W) { + consume_(p0); + consume_(p0); + } + public fun test4(p0: W) { + consume_(p0); + consume_(p0); + } + public fun test5() { + let _v0 = W{x: 42}; + test3(_v0); + test4(_v0); + } +} + + +//# run 0xc0ffee::m::test1 --args 42 + +//# run 0xc0ffee::m::test2 --args 42 + +//# run 0xc0ffee::m::test5 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled.baseline.exp new file mode 100644 index 00000000000..3736fb533f8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_1.decompiled.baseline.exp @@ -0,0 +1,18 @@ +processed 4 tasks +task 0 lines 3-35: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:17 + │ +8 │ fun consume(p0: u64) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:11:18 + │ +11 │ fun consume_(p0: W) { + │ ^^ + + +task 1 lines 38-38: run 0xc0ffee::m::test1 --args 42 +task 2 lines 40-40: run 0xc0ffee::m::test2 --args 42 +task 3 lines 42-42: run 0xc0ffee::m::test5 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled new file mode 100644 index 00000000000..6dc70ba4f25 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/consume_2.move` + +//# publish +module 0xc0ffee::m { + struct W has copy, drop { + x: u64, + } + fun consume(p0: u64) { + () + } + fun consume_(p0: W) { + () + } + public fun main() { + test1(42); + test2(W{x: 42}); + } + public fun test1(p0: u64) { + consume(p0); + consume(p0); + } + public fun test2(p0: W) { + consume_(p0); + consume_(p0); + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled.baseline.exp new file mode 100644 index 00000000000..a64cfc62b83 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_2.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-26: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:17 + │ +8 │ fun consume(p0: u64) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:11:18 + │ +11 │ fun consume_(p0: W) { + │ ^^ + + +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled new file mode 100644 index 00000000000..b0293404e2d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/consume_3.move` + +//# publish +module 0xc0ffee::m { + struct W has copy, drop { + a: u32, + } + fun consume(p0: u32) { + () + } + fun consume_(p0: W) { + () + } + public fun main() { + test(55u32); + test_(W{a: 56u32}); + } + public fun test(p0: u32) { + consume(p0); + consume(p0); + } + public fun test_(p0: W) { + consume_(p0); + consume_(p0); + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled.baseline.exp new file mode 100644 index 00000000000..55fa1493015 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_3.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-26: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:17 + │ +8 │ fun consume(p0: u32) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:11:18 + │ +11 │ fun consume_(p0: W) { + │ ^^ + + +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled new file mode 100644 index 00000000000..447a3e8198d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/consume_4.move` + +//# publish +module 0xc0ffee::m { + struct W has copy, drop { + m: u32, + } + fun consume(p0: u32) { + () + } + fun consume_(p0: W) { + () + } + public fun main() { + test(42u32); + test_struct(W{m: 45u32}); + } + public fun test(p0: u32) { + consume(p0); + consume(p0); + } + public fun test_struct(p0: W) { + consume_(p0); + consume_(p0); + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled.baseline.exp new file mode 100644 index 00000000000..55fa1493015 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_4.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-26: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:17 + │ +8 │ fun consume(p0: u32) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:11:18 + │ +11 │ fun consume_(p0: W) { + │ ^^ + + +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled new file mode 100644 index 00000000000..1725c1bbe17 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled @@ -0,0 +1,43 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/consume_5.move` + +//# publish +module 0xc0ffee::m { + struct W has copy, drop { + x: u32, + } + fun consume(p0: u32) { + () + } + fun consume_(p0: W) { + () + } + public fun main() { + test(true, 42u32); + test(false, 45u32); + let _v0 = W{x: 42u32}; + test_struct(true, _v0); + let _v1 = W{x: 45u32}; + test_struct(false, _v1); + } + public fun test(p0: bool, p1: u32) { + let _v0 = p1; + if (p0) consume(_v0) else consume(p1); + if (!p0) { + consume(p1); + return () + }; + consume(_v0); + } + public fun test_struct(p0: bool, p1: W) { + let _v0 = p1; + if (p0) consume_(_v0) else consume_(p1); + if (!p0) { + consume_(p1); + return () + }; + consume_(_v0); + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled.baseline.exp new file mode 100644 index 00000000000..f92768e910c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/consume_5.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-40: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:8:17 + │ +8 │ fun consume(p0: u32) { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:11:18 + │ +11 │ fun consume_(p0: W) { + │ ^^ + + +task 1 lines 43-43: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled new file mode 100644 index 00000000000..ec9c13282fe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/cyclic_assignment_without_use.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: u64) { + () + } +} + + +//# run 0xc0ffee::m::test --args 55 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled.baseline.exp new file mode 100644 index 00000000000..955eebff204 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignment_without_use.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:5:21 + │ +5 │ public fun test(p0: u64) { + │ ^^ + + +task 1 lines 11-11: run 0xc0ffee::m::test --args 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled new file mode 100644 index 00000000000..dc618765ae2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/cyclic_assignments.move` + +//# publish +module 0xc0ffee::m { + fun cyclic(p0: u64): u64 { + p0 + } +} + + +//# run 0xc0ffee::m::cyclic --args 42 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled.baseline.exp new file mode 100644 index 00000000000..7d060f82cc4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_assignments.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::cyclic --args 42 +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled new file mode 100644 index 00000000000..2d125d5054b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled @@ -0,0 +1,28 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/cyclic_dead_store.move` + +//# publish +module 0xc0ffee::m { + public fun test1(p0: u64, p1: u64, p2: u64): u64 { + let _v0 = 0; + while (_v0 < p0) { + p1 = p2; + p2 = p1; + _v0 = _v0 + 1 + }; + p1 + } + public fun test2(p0: u64, p1: u64): u64 { + let _v0 = 0; + while (_v0 < p0) _v0 = _v0 + 1; + p1 + } +} + + +//# run 0xc0ffee::m::test1 --args 0 55 66 + +//# run 0xc0ffee::m::test1 --args 5 55 66 + +//# run 0xc0ffee::m::test2 --args 0 55 + +//# run 0xc0ffee::m::test2 --args 5 55 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled.baseline.exp new file mode 100644 index 00000000000..37174f35d01 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/cyclic_dead_store.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 5 tasks +task 0 lines 3-19: publish [module 0xc0ffee::m {] +task 1 lines 22-22: run 0xc0ffee::m::test1 --args 0 55 66 +return values: 55 +task 2 lines 24-24: run 0xc0ffee::m::test1 --args 5 55 66 +return values: 66 +task 3 lines 26-26: run 0xc0ffee::m::test2 --args 0 55 +return values: 55 +task 4 lines 28-28: run 0xc0ffee::m::test2 --args 5 55 +return values: 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled new file mode 100644 index 00000000000..26adfee501d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_assignment_1.move` + +//# publish +module 0xc0ffee::m { + fun dead(p0: u64): u64 { + p0 + } +} + + +//# run 0xc0ffee::m::dead --args 55 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled.baseline.exp new file mode 100644 index 00000000000..df12ac125de --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_1.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::dead --args 55 +return values: 55 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled new file mode 100644 index 00000000000..4dd0de2ac4a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_assignment_2.move` + +//# publish +module 0xc0ffee::m { + fun dead(p0: u64): u64 { + p0 + } +} + + +//# run 0xc0ffee::m::dead --args 53 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled.baseline.exp new file mode 100644 index 00000000000..9058e98157c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_2.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::dead --args 53 +return values: 53 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled new file mode 100644 index 00000000000..50fe340aa7e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_assignment_3.move` + +//# publish +module 0xc0ffee::m { + public fun test(p0: bool): u32 { + if (p0) return 1u32; + 9u32 + } +} + + +//# run 0xc0ffee::m::test --args true + +//# run 0xc0ffee::m::test --args false \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled.baseline.exp new file mode 100644 index 00000000000..cf5307d38e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_3.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-9: publish [module 0xc0ffee::m {] +task 1 lines 12-12: run 0xc0ffee::m::test --args true +return values: 1 +task 2 lines 14-14: run 0xc0ffee::m::test --args false +return values: 9 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled new file mode 100644 index 00000000000..736e43ce028 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled @@ -0,0 +1,26 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_assignment_4.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test1() == 3, 0); + assert!(test2(5) == 5, 0); + assert!(test3(5) == 8, 0); + assert!(test4(45) == 1, 0); + } + public fun test1(): u64 { + 3 + } + public fun test2(p0: u64): u64 { + p0 + } + public fun test3(p0: u64): u64 { + 8 + } + public fun test4(p0: u64): u64 { + 1 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled.baseline.exp new file mode 100644 index 00000000000..e8ecb810889 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_assignment_4.decompiled.baseline.exp @@ -0,0 +1,16 @@ +processed 2 tasks +task 0 lines 3-23: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:17:22 + │ +17 │ public fun test3(p0: u64): u64 { + │ ^^ + +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:20:22 + │ +20 │ public fun test4(p0: u64): u64 { + │ ^^ + + +task 1 lines 26-26: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled new file mode 100644 index 00000000000..ea84f56c157 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_loads.move` + +//# publish +module 0xc0ffee::m { + public fun check() { + assert!(foo() == 2, 0); + } + public fun foo(): u64 { + 2 + } +} + + +//# run 0xc0ffee::m::check \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled.baseline.exp new file mode 100644 index 00000000000..6e2db2b00df --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_loads.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::check diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled new file mode 100644 index 00000000000..02411a5aaad --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_store_calls_1.move` + +//# publish +module 0xc0ffee::m { + fun id(p0: u64): u64 { + p0 + } + public fun test(): u64 { + let _v0 = id(42); + let _v1 = id(44); + id(46) + 1 + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled.baseline.exp new file mode 100644 index 00000000000..6836725ddcf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_1.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::test +return values: 47 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled new file mode 100644 index 00000000000..7f80ab76138 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled @@ -0,0 +1,18 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_store_calls_2.move` + +//# publish +module 0xc0ffee::m { + fun four(): u64 { + 4 + } + fun ten(): u64 { + 10 + } + public fun test(): u64 { + let _v0 = four(); + ten() + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled.baseline.exp new file mode 100644 index 00000000000..ba1e8a34d37 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_2.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-15: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::test +return values: 10 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled new file mode 100644 index 00000000000..140e8b1400d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/dead_store_calls_3.move` + +//# publish +module 0xc0ffee::m { + fun one(): u64 { + 1 + } + public fun test(p0: u64): u64 { + let _v0 = one(); + p0 + } +} + + +//# run 0xc0ffee::m::test --args 42 \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled.baseline.exp new file mode 100644 index 00000000000..51935117081 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/dead_store_calls_3.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::test --args 42 +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled new file mode 100644 index 00000000000..c08fa47e75c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/immut_refs_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(42) == 42, 0); + } + fun test(p0: u64): u64 { + *&p0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled.baseline.exp new file mode 100644 index 00000000000..2b921115196 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled new file mode 100644 index 00000000000..1efcfd40eaa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/immut_refs_2.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(42) == 42, 5); + } + fun test(p0: u64): u64 { + let _v0 = &p0; + p0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/immut_refs_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled new file mode 100644 index 00000000000..1e4cc864685 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/inlining1.move` + +//# publish +module 0x42::Test { + public fun main() { + assert!(test() == 3, 5); + } + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled.baseline.exp new file mode 100644 index 00000000000..30ea4a79bf2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0x42::Test {] +task 1 lines 14-14: run 0x42::Test::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled new file mode 100644 index 00000000000..167d9781345 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/inlining1_typed.move` + +//# publish +module 0x42::Test { + public fun main() { + assert!(test() == 3, 5); + } + public fun test(): u64 { + 3 + } +} + + +//# run 0x42::Test::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled.baseline.exp new file mode 100644 index 00000000000..30ea4a79bf2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/inlining1_typed.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0x42::Test {] +task 1 lines 14-14: run 0x42::Test::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled new file mode 100644 index 00000000000..2c9c090eb95 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/intermingled_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 4, 0); + } + fun test(): u64 { + let _v0 = 1 + 2; + 4 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled new file mode 100644 index 00000000000..afd7a199969 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/intermingled_2.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 4, 6); + } + fun test(): u64 { + let _v0 = 1 + 1; + 2 + _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled new file mode 100644 index 00000000000..91f88b015ee --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/intermingled_3.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 2, 6); + } + fun test(): u64 { + let _v0 = 1 + 1; + 2 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/intermingled_3.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled new file mode 100644 index 00000000000..20aeb45d957 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/loop_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(55) == 55, 0); + } + fun test(p0: u64): u64 { + let _v0 = 0; + let _v1 = 0; + while (_v1 < 10) { + _v0 = p0; + _v1 = _v1 + 1 + }; + _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled.baseline.exp new file mode 100644 index 00000000000..b040c1e3289 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled new file mode 100644 index 00000000000..fe3174a5078 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/loop_2.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(42) == 42, 5); + } + fun test(p0: u64): u64 { + let _v0 = p0; + let _v1 = 0; + while (_v1 < 10) { + _v0 = p0; + _v1 = _v1 + 1 + }; + _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled.baseline.exp new file mode 100644 index 00000000000..b040c1e3289 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/loop_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0xc0ffee::m {] +task 1 lines 20-20: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled new file mode 100644 index 00000000000..ea9c45614e1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/multi_assigns.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 2, 0); + } + fun test(): u64 { + 2 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled.baseline.exp new file mode 100644 index 00000000000..2b921115196 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/multi_assigns.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled new file mode 100644 index 00000000000..f5e5169f4cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled @@ -0,0 +1,17 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/mut_refs_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(55) == 55, 0); + } + fun test(p0: u64): u64 { + let _v0 = p0; + let _v1 = &mut p0; + *_v1 = 1; + _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled.baseline.exp new file mode 100644 index 00000000000..40b715fc321 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-14: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled new file mode 100644 index 00000000000..847a8b89c33 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled @@ -0,0 +1,22 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/mut_refs_2.move` + +//# publish +module 0xc0ffee::m { + struct S has copy, drop { + a: u64, + b: u64, + } + public fun main() { + assert!(test(S{a: 1, b: 2}) == 1, 5); + } + fun test(p0: S): u64 { + let _v0 = p0; + let _v1 = _v0; + let _v2 = &mut (&mut _v0).a; + *_v2 = 0; + *&(&_v1).a + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled.baseline.exp new file mode 100644 index 00000000000..07cc547ea8d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/mut_refs_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-19: publish [module 0xc0ffee::m {] +task 1 lines 22-22: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled new file mode 100644 index 00000000000..0226f3a4982 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/non_overlapping_vars1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 3, 0); + } + fun test(): u64 { + let _v0 = 1 + 1; + 2 + 1 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled new file mode 100644 index 00000000000..da1df62b7f1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled @@ -0,0 +1,15 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/non_overlapping_vars_diff_type.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 3, 0); + } + fun test(): u64 { + let _v0 = 1u32 + 1u32; + 2 + 1 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled.baseline.exp new file mode 100644 index 00000000000..892470300f0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/non_overlapping_vars_diff_type.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-12: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled new file mode 100644 index 00000000000..fe4c343dbad --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/overlapping_vars.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 6, 0); + } + fun test(): u64 { + 6 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled.baseline.exp new file mode 100644 index 00000000000..2b921115196 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/overlapping_vars.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled new file mode 100644 index 00000000000..c486ce1a146 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/reassigned_var.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test() == 11, 0); + } + fun test(): u64 { + 9 + 2 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled.baseline.exp new file mode 100644 index 00000000000..2b921115196 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/reassigned_var.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled new file mode 100644 index 00000000000..9c4e8f2f6f5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled @@ -0,0 +1,29 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/self_assigns.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test2(5) == 5, 0); + assert!(test3() == 1, 1); + assert!(test4(55) == 55, 2); + } + public fun test2(p0: u64): u64 { + p0 + } + public fun test3(): u64 { + let _v0 = 0; + while (_v0 < 42) _v0 = _v0 + 1; + 1 + } + public fun test4(p0: u64): u64 { + let _v0 = 0; + while (_v0 < 42) _v0 = _v0 + 1; + p0 + } + public fun test1(p0: u64) { + () + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled.baseline.exp new file mode 100644 index 00000000000..89537146337 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/self_assigns.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-26: publish [module 0xc0ffee::m {] +warning: Unused value of parameter `p0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_p0`), or binding to `_` + ┌─ TEMPFILE:23:22 + │ +23 │ public fun test1(p0: u64) { + │ ^^ + + +task 1 lines 29-29: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled new file mode 100644 index 00000000000..da79b963ca2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/seq_kills_1.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(55), 0); + } + fun test(p0: u64): bool { + let _v0 = p0; + let _v1 = p0 + 1; + _v0 == _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled.baseline.exp new file mode 100644 index 00000000000..f97a490fc44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_1.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled new file mode 100644 index 00000000000..2838a1822f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/seq_kills_2.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(test(100) == true, 0); + } + fun test(p0: u64): bool { + let _v0 = p0; + let _v1 = p0 + 1; + _v0 == _v0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled.baseline.exp new file mode 100644 index 00000000000..f97a490fc44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/seq_kills_2.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled new file mode 100644 index 00000000000..b132a341b09 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/sequential_assign_struct.move` + +//# publish +module 0xc0ffee::m { + struct Foo has copy, drop { + a: u64, + b: u64, + c: u64, + d: u64, + e: u64, + } + public fun main() { + let _v0 = sequential(Foo{a: 1, b: 2, c: 3, d: 4, e: 5}); + let _v1 = Foo{a: 1, b: 2, c: 3, d: 4, e: 5}; + assert!(_v0 == _v1, 0); + } + fun sequential(p0: Foo): Foo { + p0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled.baseline.exp new file mode 100644 index 00000000000..5fb2a7a924d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/sequential_assign_struct.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0xc0ffee::m {] +task 1 lines 23-23: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled new file mode 100644 index 00000000000..4183a4ca6f5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled @@ -0,0 +1,14 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/simple_sequential_assign.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + assert!(sequential(50) == 50, 0); + } + fun sequential(p0: u64): u64 { + p0 + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled.baseline.exp new file mode 100644 index 00000000000..2b921115196 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/simple_sequential_assign.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-11: publish [module 0xc0ffee::m {] +task 1 lines 14-14: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled new file mode 100644 index 00000000000..90e1e9cf6d4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/straight_line_kills.move` + +//# publish +module 0xc0ffee::m { + fun copy_kill(p0: u64): u64 { + let _v0 = p0; + let _v1 = p0 + 1; + _v0 + _v0 + } + public fun main() { + assert!(copy_kill(10) == 20, 0); + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled.baseline.exp new file mode 100644 index 00000000000..f97a490fc44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/straight_line_kills.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled new file mode 100644 index 00000000000..e97ead443ba --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled @@ -0,0 +1,16 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/swap.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + let (_v0,_v1) = test(55, 66); + assert!(_v0 == 66, 0); + assert!(_v1 == 55, 0); + } + public fun test(p0: u64, p1: u64): (u64, u64) { + (p1, p0) + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled.baseline.exp new file mode 100644 index 00000000000..f97a490fc44 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-13: publish [module 0xc0ffee::m {] +task 1 lines 16-16: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled new file mode 100644 index 00000000000..879c8019659 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled @@ -0,0 +1,24 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/swap_in_a_loop.move` + +//# publish +module 0xc0ffee::m { + public fun main() { + let (_v0,_v1) = test(9, 55); + assert!(_v0 == 55, 0); + assert!(_v1 == 9, 0); + } + public fun test(p0: u64, p1: u64): (u64, u64) { + let _v0 = p0; + while (_v0 > 0) { + let _v1 = p0; + p0 = p1; + p1 = _v1; + _v0 = _v0 - 1; + continue + }; + (p0, p1) + } +} + + +//# run 0xc0ffee::m::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled.baseline.exp new file mode 100644 index 00000000000..9db77afe9fb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/swap_in_a_loop.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-21: publish [module 0xc0ffee::m {] +task 1 lines 24-24: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled new file mode 100644 index 00000000000..44abc33e260 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled @@ -0,0 +1,11 @@ +//**** Cross-compiled for `move` syntax from `tests/optimization/unused_add.move` + +//# publish +module 0xc0ffee::m { + public fun test() { + () + } +} + + +//# run 0xc0ffee::m::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled.baseline.exp new file mode 100644 index 00000000000..9df6caf396f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/round-trip/unused_add.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-8: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/self_assigns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/self_assigns.exp index 5d92c423f3f..3a2f37d6801 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/self_assigns.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/self_assigns.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-37: publish [module 0xc0ffee::m {] +task 1 lines 39-39: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_1.exp index 5d92c423f3f..c9d803a98d6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_1.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_2.exp index 5d92c423f3f..93f669e0baf 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/seq_kills_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/sequential_assign_struct.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/sequential_assign_struct.exp index 5d92c423f3f..79d30e6ddbd 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/sequential_assign_struct.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/sequential_assign_struct.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-28: publish [module 0xc0ffee::m {] +task 1 lines 30-30: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/simple_sequential_assign.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/simple_sequential_assign.exp index 5d92c423f3f..c9d803a98d6 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/simple_sequential_assign.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/simple_sequential_assign.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-15: publish [module 0xc0ffee::m {] +task 1 lines 17-17: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/straight_line_kills.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/straight_line_kills.exp index 5d92c423f3f..f665ed5ca40 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/straight_line_kills.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/straight_line_kills.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-13: publish [module 0xc0ffee::m {] +task 1 lines 15-15: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap.exp index 5d92c423f3f..93f669e0baf 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0xc0ffee::m {] +task 1 lines 18-18: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap_in_a_loop.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap_in_a_loop.exp index 5d92c423f3f..65d7329262b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap_in_a_loop.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/swap_in_a_loop.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-20: publish [module 0xc0ffee::m {] +task 1 lines 22-22: run 0xc0ffee::m::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/unused_add.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/unused_add.exp index 5d92c423f3f..e16d45f1e8e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/unused_add.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/optimization/unused_add.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-9: publish [module 0xc0ffee::m {] +task 1 lines 11-11: run 0xc0ffee::m::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.baseline.exp new file mode 100644 index 00000000000..ee670fef433 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.baseline.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-35: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 37-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-71: run --verbose [script {] +task 4 lines 73-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 80-85: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 87-102: run --verbose [script {] +task 7 lines 104-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 111-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 119-124: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 126-135: run --verbose [script {] +task 11 lines 137-142: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 144-149: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 151-158: run --verbose [script {] +task 14 lines 160-165: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 167-180: publish [module 0xff::negate_i128 {] +task 16 lines 182-182: run 0xff::negate_i128::test1 --verbose +task 17 lines 184-184: run 0xff::negate_i128::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i128, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i128") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.move new file mode 100644 index 00000000000..8a673f2d38a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.move @@ -0,0 +1,184 @@ +//# run --verbose +script { + fun main() { + assert!(0i128 + 0i128 == 0i128, 1000); + assert!(0i128 + 1i128 == 1i128, 1001); + assert!(1i128 + 1i128 == 2i128, 1002); + assert!(0i128 + -1i128 == -1i128, 1003); + assert!(-1i128 + -1i128 == -2i128, 1004); + + assert!(13i128 + 67i128 == 80i128, 1100); + assert!(100i128 + 10i128 == 110i128, 1101); + assert!(-13i128 + -67i128 == -80i128, 1102); + assert!(-100i128 + -10i128 == -110i128, 1103); + + assert!(0i128 + 170141183460469231731687303715884105727i128 + == 170141183460469231731687303715884105727i128, 1200); + assert!(1i128 + 170141183460469231731687303715884105726i128 + == 170141183460469231731687303715884105727i128, 1201); + assert!(5i128 + 170141183460469231731687303715884105722i128 + == 170141183460469231731687303715884105727i128, 1202); + assert!(0i128 + -170141183460469231731687303715884105728i128 + == -170141183460469231731687303715884105728i128, 1203); + assert!(-1i128 + -170141183460469231731687303715884105727i128 + == -170141183460469231731687303715884105728i128, 1204); + assert!(-5i128 + -170141183460469231731687303715884105723i128 + == -170141183460469231731687303715884105728i128, 1205); + } +} + +//# run --verbose +script { + fun main() { + 1i128 + 170141183460469231731687303715884105727i128; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + -1i128 + (-170141183460469231731687303715884105728i128); // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i128 - 0i128 == 0i128, 2000); + assert!(1i128 - 0i128 == 1i128, 2001); + assert!(1i128 - 1i128 == 0i128, 2002); + assert!(-1i128 - -0i128 == -1i128, 2003); + assert!(-1i128 - -1i128 == 0i128, 2004); + + assert!(52i128 - 13i128 == 39i128, 2100); + assert!(100i128 - 10i128 == 90i128, 2101); + assert!(-52i128 - -13i128 == -39i128, 2102); + assert!(-100i128 - -10i128 == -90i128, 2103); + + assert!(0i128 - -170141183460469231731687303715884105727i128 + == 170141183460469231731687303715884105727i128, 2200); + assert!(1i128 - -170141183460469231731687303715884105726i128 + == 170141183460469231731687303715884105727i128, 2201); + assert!(5i128 - -170141183460469231731687303715884105722i128 + == 170141183460469231731687303715884105727i128, 2202); + assert!(-1i128 - 170141183460469231731687303715884105727i128 + == -170141183460469231731687303715884105728i128, 2203); + assert!(-5i128 - 170141183460469231731687303715884105723i128 + == -170141183460469231731687303715884105728i128, 2204); + assert!(-170141183460469231731687303715884105728i128 - 0 == + -170141183460469231731687303715884105728i128, 2205); +} +} + +//# run --verbose +script { + fun main() { + -2i128 - 170141183460469231731687303715884105727i128; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + 1i128 - -170141183460469231731687303715884105727i128; // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(6i128 * 7i128 == 42i128, 3100); + assert!(10i128 * 10i128 == 100i128, 3101); + assert!(-6i128 * 7i128 == -42i128, 3102); + assert!(-10i128 * -10i128 == 100i128, 3103); + + assert!(1i128 * 170141183460469231731687303715884105727i128 + == 170141183460469231731687303715884105727i128, 3200); + assert!(-1i128 * -170141183460469231731687303715884105727i128 + == 170141183460469231731687303715884105727i128, 3201); + assert!(1i128 * -170141183460469231731687303715884105728i128 + == -170141183460469231731687303715884105728i128, 3202); +} +} + +//# run --verbose +script { +fun main() { + 13043817825332782213i128 * 13043817825332782213i128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + 170141183460469231731687303715884105727i128 * 2i128; // expect to abort +} +} + + +//# run --verbose +script { +fun main() { + -170141183460469231731687303715884105728i128 * -1i128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(6i128 / 3i128 == 2i128, 4100); + assert!(170141183460469231731687303715884105727i128 / 7i128 + == 24305883351495604533098186245126300818i128, 4101); + assert!(-170141183460469231731687303715884105727i128 / 7i128 + == -24305883351495604533098186245126300818i128, 4102); +} +} + +//# run --verbose +script { +fun main() { + 1i128 / 0i128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -170141183460469231731687303715884105728i128 / -1i128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(8i128 % 3i128 == 2i128, 5100); + assert!(170141183460469231731687303715884105727i128 % 7i128 == 1i128, 5101); + assert!(-170141183460469231731687303715884105727i128 % 7i128 == -1i128, 5102); +} +} + +//# run --verbose +script { +fun main() { + 1i128 % 0i128; // expect to abort +} +} + +//# publish +module 0xff::negate_i128 { + fun negate(a: i128): i128 { + -a + } + public fun test1(){ + let a = 20i128; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -170141183460469231731687303715884105728i128; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i128::test1 --verbose + +//# run 0xff::negate_i128::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.no-optimize.exp new file mode 100644 index 00000000000..ee670fef433 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.no-optimize.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-35: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 37-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-71: run --verbose [script {] +task 4 lines 73-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 80-85: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 87-102: run --verbose [script {] +task 7 lines 104-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 111-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 119-124: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 126-135: run --verbose [script {] +task 11 lines 137-142: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 144-149: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 151-158: run --verbose [script {] +task 14 lines 160-165: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 167-180: publish [module 0xff::negate_i128 {] +task 16 lines 182-182: run 0xff::negate_i128::test1 --verbose +task 17 lines 184-184: run 0xff::negate_i128::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i128, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i128") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.opt-extra.exp new file mode 100644 index 00000000000..b498e9b1b30 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.opt-extra.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-35: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 37-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-71: run --verbose [script {] +task 4 lines 73-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 80-85: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 87-102: run --verbose [script {] +task 7 lines 104-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 111-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 119-124: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 126-135: run --verbose [script {] +task 11 lines 137-142: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 144-149: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 151-158: run --verbose [script {] +task 14 lines 160-165: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 167-180: publish [module 0xff::negate_i128 {] +task 16 lines 182-182: run 0xff::negate_i128::test1 --verbose +task 17 lines 184-184: run 0xff::negate_i128::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i128, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.optimize.exp new file mode 100644 index 00000000000..ee670fef433 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i128.optimize.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-35: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 37-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-71: run --verbose [script {] +task 4 lines 73-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 80-85: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 87-102: run --verbose [script {] +task 7 lines 104-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 111-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 119-124: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 126-135: run --verbose [script {] +task 11 lines 137-142: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 144-149: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 151-158: run --verbose [script {] +task 14 lines 160-165: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 167-180: publish [module 0xff::negate_i128 {] +task 16 lines 182-182: run 0xff::negate_i128::test1 --verbose +task 17 lines 184-184: run 0xff::negate_i128::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i128, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i128") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.baseline.exp new file mode 100644 index 00000000000..8324d3b9aea --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i16 {] +task 19 lines 234-234: run 0xff::negate_i16::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i16::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i16, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i16") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.move new file mode 100644 index 00000000000..4f9e18ec0c8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.move @@ -0,0 +1,236 @@ +//# run --verbose +script { + fun main() { + assert!(0i16 + 0i16 == 0i16, 1000); + assert!(0i16 + 1i16 == 1i16, 1001); + assert!(1i16 + 1i16 == 2i16, 1002); + assert!(0i16 + -1i16 == -1i16, 1003); + assert!(-1i16 + -1i16 == -2i16, 1004); + + assert!(13i16 + 67i16 == 80i16, 1100); + assert!(100i16 + 10i16 == 110i16, 1101); + assert!(-13i16 + -67i16 == -80i16, 1102); + assert!(-100i16 + -10i16 == -110i16, 1103); + + assert!(0i16 + 32767i16 == 32767i16, 1200); + assert!(1i16 + 32766i16 == 32767i16, 1201); + assert!(5i16 + 32762i16 == 32767i16, 1202); + assert!(0i16 + -32768i16 == -32768i16, 1203); + assert!(-1i16 + -32767i16 == -32768i16, 1204); + assert!(-5i16 + -32763i16 == -32768i16, 1205); + } +} + +//# run --verbose +script { + fun main() { + 1i16 + 32767i16; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + -1i16 + (-32768i16); // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i16 - 0i16 == 0i16, 2000); + assert!(1i16 - 0i16 == 1i16, 2001); + assert!(1i16 - 1i16 == 0i16, 2002); + assert!(-1i16 - -0i16 == -1i16, 2003); + assert!(-1i16 - -1i16 == 0i16, 2004); + + assert!(52i16 - 13i16 == 39i16, 2100); + assert!(100i16 - 10i16 == 90i16, 2101); + assert!(-52i16 - -13i16 == -39i16, 2102); + assert!(-100i16 - -10i16 == -90i16, 2103); + + assert!(0i16 - -32767i16 == 32767i16, 2201); + assert!(1i16 - -32766i16 == 32767i16, 2201); + assert!(5i16 - -32762i16 == 32767i16, 2201); + assert!(-1i16 - 32767i16 == -32768i16, 2201); + assert!(-5i16 - 32763i16 == -32768i16, 2201); + assert!(-32768i16 - 0 == -32768i16, 2201); +} +} + +//# run --verbose +script { + fun main() { + -2i16 - 32767i16; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + 1i16 - -32767i16; // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i16 * 0i16 == 0i16, 3000); + assert!(1i16 * 0i16 == 0i16, 3001); + assert!(1i16 * 1i16 == 1i16, 3002); + assert!(-1i16 * 0i16 == 0i16, 3003); + assert!(-1i16 * 1i16 == -1i16, 3004); + assert!(1i16 * -1i16 == -1i16, 3005); + assert!(-1i16 * -1i16 == 1i16, 3006); + + assert!(6i16 * 7i16 == 42i16, 3100); + assert!(10i16 * 10i16 == 100i16, 3101); + assert!(6i16 * -7i16 == -42i16, 3102); + assert!(10i16 * -10i16 == -100i16, 3103); + assert!(-6i16 * 7i16 == -42i16, 3104); + assert!(-10i16 * 10i16 == -100i16, 3105); + assert!(-6i16 * -7i16 == 42i16, 3106); + assert!(-10i16 * -10i16 == 100i16, 3107); + + assert!(127i16 * 256i16 == 32512i16, 3200); + assert!(-127i16 * -256i16 == 32512i16, 3201); + assert!(-127i16 * 256i16 == -32512i16, 3202); + assert!(127i16 * -256i16 == -32512i16, 3203); +} +} + +//# run --verbose +script { +fun main() { + 128i16 * 256i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -128i16 * -256i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + 129i16 * -256i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -129i16 * 256i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i16 / 1i16 == 0i16, 4000); + assert!(1i16 / 1i16 == 1i16, 4001); + assert!(1i16 / 2i16 == 0i16, 4002); + assert!(0i16 / -1i16 == 0i16, 4003); + assert!(1i16 / -1i16 == -1i16, 4004); + assert!(1i16 / -2i16 == 0i16, 4005); + assert!(-0i16 / 1i16 == 0i16, 4006); + assert!(-1i16 / 1i16 == -1i16, 4007); + assert!(-1i16 / 2i16 == 0i16, 4008); + assert!(-0i16 / -1i16 == 0i16, 4009); + assert!(-1i16 / -1i16 == 1i16, 40010); + assert!(-1i16 / -2i16 == 0i16, 40011); + + assert!(6i16 / 3i16 == 2i16, 4100); + assert!(32767i16 / 7i16 == 4681i16, 4101); + assert!(-6i16 / 3i16 == -2i16, 4102); + assert!(-32767i16 / 7i16 == -4681i16, 4103); + assert!(6i16 / -3i16 == -2i16, 4104); + assert!(32767i16 / -7i16 == -4681i16, 4105); + assert!(-6i16 / -3i16 == 2i16, 4106); + assert!(-32767i16 / -7i16 == 4681i16, 4107); +} +} + +//# run --verbose +script { +fun main() { + 1i16 / 0i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i16 / 0i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -32768i16 / -1i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i16 % 1i16 == 0i16, 5000); + assert!(1i16 % 1i16 == 0i16, 5001); + assert!(1i16 % 2i16 == 1i16, 5002); + assert!(-0i16 % 1i16 == 0i16, 5003); + assert!(-1i16 % 1i16 == 0i16, 5004); + assert!(-1i16 % 2i16 == -1i16, 5005); + assert!(0i16 % -1i16 == 0i16, 5006); + assert!(1i16 % -1i16 == 0i16, 5007); + assert!(1i16 % -2i16 == 1i16, 5008); + assert!(-0i16 % -1i16 == 0i16, 5009); + assert!(-1i16 % -1i16 == 0i16, 50010); + assert!(-1i16 % -2i16 == -1i16, 50011); + + assert!(8i16 % 3i16 == 2i16, 5100); + assert!(32765i16 % 7i16 == 5i16, 5101); + assert!(-8i16 % 3i16 == -2i16, 5102); + assert!(-32765i16 % 7i16 == -5i16, 5103); + assert!(8i16 % -3i16 == 2i16, 5104); + assert!(32765i16 % -7i16 == 5i16, 5105); + assert!(-8i16 % -3i16 == -2i16, 5106); + assert!(-32765i16 % -7i16 == -5i16, 5107); +} +} + +//# run --verbose +script { +fun main() { + 1i16 % 0i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i16 % 0i16; // expect to abort +} +} + +//# publish +module 0xff::negate_i16 { + fun negate(a: i16): i16 { + -a + } + public fun test1(){ + let a = 20i16; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -32768i16; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i16::test1 --verbose + +//# run 0xff::negate_i16::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.no-optimize.exp new file mode 100644 index 00000000000..8324d3b9aea --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.no-optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i16 {] +task 19 lines 234-234: run 0xff::negate_i16::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i16::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i16, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i16") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.opt-extra.exp new file mode 100644 index 00000000000..b0600f89b8b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.opt-extra.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i16 {] +task 19 lines 234-234: run 0xff::negate_i16::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i16::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i16, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.optimize.exp new file mode 100644 index 00000000000..8324d3b9aea --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i16.optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i16 {] +task 19 lines 234-234: run 0xff::negate_i16::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i16::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i16, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i16") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.baseline.exp new file mode 100644 index 00000000000..8af13049a66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.baseline.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-20: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 22-27: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 29-38: run --verbose [script {] +task 4 lines 40-46: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 48-54: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 56-66: run --verbose [script {] +task 7 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 76-82: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 84-93: run --verbose [script {] +task 10 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 111-118: run --verbose [script {] +task 13 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 128-134: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 136-149: publish [module 0xff::negate_i256 {] +task 16 lines 151-151: run 0xff::negate_i256::test1 --verbose +task 17 lines 153-153: run 0xff::negate_i256::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i256, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i256") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.move new file mode 100644 index 00000000000..041edc552d3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.move @@ -0,0 +1,153 @@ +//# run --verbose +script { + fun main() { + assert!(0i256 + 0i256 == 0i256, 1000); + assert!(1i256 + -1i256 == 0i256, 1001); + assert!(13i256 + 67i256 == 80i256, 1002); + + assert!(0i256 + 57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + == 57896044618658097711785492504343953926634992332820282019728792003956564819967i256, 1100); + assert!(-1i256 + -57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + == -57896044618658097711785492504343953926634992332820282019728792003956564819968i256, 1101); + } +} + +//# run --verbose +script { + fun main() { + 1i256 + 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + -1i256 + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + assert!(100i256 - 50i256 == 50i256, 2000); + assert!(0i256 - -57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + == 57896044618658097711785492504343953926634992332820282019728792003956564819967i256, 2001); + assert!(-1i256 - 57896044618658097711785492504343953926634992332820282019728792003956564819967i256 + == -57896044618658097711785492504343953926634992332820282019728792003956564819968i256, 2002); + } +} + +//# run --verbose +script { + fun main() { + // subtraction underflow + -2i256 - 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + // subtraction overflow + 1i256 - -57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + assert!(6i256 * 7i256 == 42i256, 3000); + assert!(10i256 * -10i256 == -100i256, 3001); + + // near sqrt(max) + assert!(170141183460469231731687303715884105727i256 * 170141183460469231731687303715884105727i256 + == 28948022309329048855892746252171976962977213799489202546401021394546514198529i256, 3100); + } +} + +//# run --verbose +script { + fun main() { + // min * 2 overflow + -57896044618658097711785492504343953926634992332820282019728792003956564819967i256 * 2i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + // min * -1 overflow + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 * -1i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + assert!(6i256 / 3i256 == 2i256, 4000); + assert!(57896044618658097711785492504343953926634992332820282019728792003956564819967i256 / 6i256 + == 9649340769776349618630915417390658987772498722136713669954798667326094136661i256, 4001); + assert!(-57896044618658097711785492504343953926634992332820282019728792003956564819967i256 / 6i256 + == -9649340769776349618630915417390658987772498722136713669954798667326094136661i256, 4002); + } +} + +//# run --verbose +script { + fun main() { + // division by zero + 1i256 / 0i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + // division overflow: min / -1 + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 / -1i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + assert!(8i256 % 3i256 == 2i256, 5000); + assert!(57896044618658097711785492504343953926634992332820282019728792003956564819967i256 % 6i256 == 1i256, 5001); + assert!(-57896044618658097711785492504343953926634992332820282019728792003956564819967i256 % 6i256 == -1i256, 5002); + } +} + +//# run --verbose +script { + fun main() { + // modulo by zero + 1i256 % 0i256; // expect abort + } +} + +//# run --verbose +script { + fun main() { + // modulo by zero + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 % -0i256; // expect abort + } +} + +//# publish +module 0xff::negate_i256 { + fun negate(a: i256): i256 { + -a + } + public fun test1(){ + let a = 20i256; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i256::test1 --verbose + +//# run 0xff::negate_i256::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.no-optimize.exp new file mode 100644 index 00000000000..8af13049a66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.no-optimize.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-20: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 22-27: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 29-38: run --verbose [script {] +task 4 lines 40-46: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 48-54: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 56-66: run --verbose [script {] +task 7 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 76-82: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 84-93: run --verbose [script {] +task 10 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 111-118: run --verbose [script {] +task 13 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 128-134: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 136-149: publish [module 0xff::negate_i256 {] +task 16 lines 151-151: run 0xff::negate_i256::test1 --verbose +task 17 lines 153-153: run 0xff::negate_i256::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i256, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i256") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.opt-extra.exp new file mode 100644 index 00000000000..b5b52061f41 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.opt-extra.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-20: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 22-27: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 29-38: run --verbose [script {] +task 4 lines 40-46: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 48-54: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 56-66: run --verbose [script {] +task 7 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 76-82: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 84-93: run --verbose [script {] +task 10 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 111-118: run --verbose [script {] +task 13 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 128-134: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 136-149: publish [module 0xff::negate_i256 {] +task 16 lines 151-151: run 0xff::negate_i256::test1 --verbose +task 17 lines 153-153: run 0xff::negate_i256::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i256, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.optimize.exp new file mode 100644 index 00000000000..8af13049a66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i256.optimize.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-20: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 22-27: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 29-38: run --verbose [script {] +task 4 lines 40-46: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 48-54: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 56-66: run --verbose [script {] +task 7 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 76-82: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 84-93: run --verbose [script {] +task 10 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 111-118: run --verbose [script {] +task 13 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 128-134: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 136-149: publish [module 0xff::negate_i256 {] +task 16 lines 151-151: run 0xff::negate_i256::test1 --verbose +task 17 lines 153-153: run 0xff::negate_i256::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i256, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i256") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.baseline.exp new file mode 100644 index 00000000000..9383b774976 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 215-228: publish [module 0xff::negate_i32 {] +task 19 lines 230-230: run 0xff::negate_i32::test1 --verbose +task 20 lines 232-232: run 0xff::negate_i32::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i32, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i32") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.move new file mode 100644 index 00000000000..6728adc892d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.move @@ -0,0 +1,232 @@ +//# run --verbose +script { + fun main() { + assert!(0i32 + 0i32 == 0i32, 1000); + assert!(0i32 + 1i32 == 1i32, 1001); + assert!(1i32 + 1i32 == 2i32, 1002); + assert!(0i32 + -1i32 == -1i32, 1003); + assert!(-1i32 + -1i32 == -2i32, 1004); + + assert!(13i32 + 67i32 == 80i32, 1100); + assert!(100i32 + 10i32 == 110i32, 1101); + assert!(-13i32 + -67i32 == -80i32, 1102); + assert!(-100i32 + -10i32 == -110i32, 1103); + + assert!(0i32 + 2147483647i32 == 2147483647i32, 1200); + assert!(1i32 + 2147483646i32 == 2147483647i32, 1201); + assert!(5i32 + 2147483642i32 == 2147483647i32, 1202); + assert!(0i32 + -2147483648i32 == -2147483648i32, 1203); + assert!(-1i32 + -2147483647i32 == -2147483648i32, 1204); + assert!(-5i32 + -2147483643i32 == -2147483648i32, 1205); + } +} + +//# run --verbose +script { + fun main() { + 1i32 + 2147483647i32; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + -1i32 + (-2147483648i32); // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i32 - 0i32 == 0i32, 2000); + assert!(1i32 - 0i32 == 1i32, 2001); + assert!(1i32 - 1i32 == 0i32, 2002); + assert!(-1i32 - -0i32 == -1i32, 2003); + assert!(-1i32 - -1i32 == 0i32, 2004); + + assert!(52i32 - 13i32 == 39i32, 2100); + assert!(100i32 - 10i32 == 90i32, 2101); + assert!(-52i32 - -13i32 == -39i32, 2102); + assert!(-100i32 - -10i32 == -90i32, 2103); + + assert!(0i32 - -2147483647i32 == 2147483647i32, 2200); + assert!(1i32 - -2147483646i32 == 2147483647i32, 2201); + assert!(5i32 - -2147483642i32 == 2147483647i32, 2202); + assert!(-1i32 - 2147483647i32 == -2147483648i32, 2203); + assert!(-5i32 - 2147483643i32 == -2147483648i32, 2204); + assert!(-2147483648i32 - 0 == -2147483648i32, 2205); +} +} + +//# run --verbose +script { + fun main() { + -2i32 - 2147483647i32; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + 1i32 - -2147483647i32; // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i32 * 0i32 == 0i32, 3000); + assert!(1i32 * 0i32 == 0i32, 3001); + assert!(1i32 * 1i32 == 1i32, 3002); + assert!(-1i32 * 0i32 == 0i32, 3003); + assert!(-1i32 * 1i32 == -1i32, 3004); + assert!(1i32 * -1i32 == -1i32, 3005); + assert!(-1i32 * -1i32 == 1i32, 3006); + + assert!(6i32 * 7i32 == 42i32, 3100); + assert!(10i32 * 10i32 == 100i32, 3101); + assert!(6i32 * -7i32 == -42i32, 3102); + assert!(10i32 * -10i32 == -100i32, 3103); + assert!(-6i32 * 7i32 == -42i32, 3104); + assert!(-10i32 * 10i32 == -100i32, 3105); + assert!(-6i32 * -7i32 == 42i32, 3106); + assert!(-10i32 * -10i32 == 100i32, 3107); + + assert!(46340i32 * 46340i32 == 2147395600i32, 3200); + assert!(-46340i32 * -46340i32 == 2147395600i32, 3201); + assert!(46340i32 * -46340i32 == -2147395600i32, 3202); + assert!(-46340i32 * 46340i32 == -2147395600i32, 3203); +} +} + +//# run --verbose +script { +fun main() { + 46341i32 * 46341i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -46341i32 * -46341i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + 2147483647i32 * 2i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -2147483648i32 * -1i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i32 / 1i32 == 0i32, 4000); + assert!(1i32 / 1i32 == 1i32, 4001); + assert!(1i32 / 2i32 == 0i32, 4002); + assert!(0i32 / -1i32 == 0i32, 4003); + assert!(1i32 / -1i32 == -1i32, 4004); + assert!(1i32 / -2i32 == 0i32, 4005); + assert!(-1i32 / 1i32 == -1i32, 4006); + assert!(-1i32 / 2i32 == 0i32, 4007); + assert!(-1i32 / -1i32 == 1i32, 4008); + assert!(-1i32 / -2i32 == 0i32, 4009); + + assert!(6i32 / 3i32 == 2i32, 4100); + assert!(2147483647i32 / 7i32 == 306783378i32, 4101); + assert!(-6i32 / 3i32 == -2i32, 4102); + assert!(-2147483647i32 / 7i32 == -306783378i32, 4103); + assert!(6i32 / -3i32 == -2i32, 4104); + assert!(2147483647i32 / -7i32 == -306783378i32, 4105); + assert!(-6i32 / -3i32 == 2i32, 4106); + assert!(-2147483647i32 / -7i32 == 306783378i32, 4107); +} +} + +//# run --verbose +script { +fun main() { + 1i32 / 0i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i32 / 0i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -2147483648i32 / -1i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i32 % 1i32 == 0i32, 5000); + assert!(1i32 % 1i32 == 0i32, 5001); + assert!(1i32 % 2i32 == 1i32, 5002); + assert!(-1i32 % 1i32 == 0i32, 5003); + assert!(-1i32 % 2i32 == -1i32, 5004); + assert!(1i32 % -1i32 == 0i32, 5005); + assert!(1i32 % -2i32 == 1i32, 5006); + assert!(-1i32 % -1i32 == 0i32, 5007); + assert!(-1i32 % -2i32 == -1i32, 5008); + + assert!(8i32 % 3i32 == 2i32, 5100); + assert!(2147483647i32 % 7i32 == 1i32, 5101); + assert!(-8i32 % 3i32 == -2i32, 5102); + assert!(-2147483647i32 % 7i32 == -1i32, 5103); + assert!(8i32 % -3i32 == 2i32, 5104); + assert!(2147483647i32 % -7i32 == 1i32, 5105); + assert!(-8i32 % -3i32 == -2i32, 5106); + assert!(-2147483647i32 % -7i32 == -1i32, 5107); +} +} + +//# run --verbose +script { +fun main() { + 1i32 % 0i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i32 % 0i32; // expect to abort +} +} + + +//# publish +module 0xff::negate_i32 { + fun negate(a: i32): i32 { + -a + } + public fun test1(){ + let a = 20i32; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -2147483648i32; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i32::test1 --verbose + +//# run 0xff::negate_i32::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.no-optimize.exp new file mode 100644 index 00000000000..9383b774976 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.no-optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 215-228: publish [module 0xff::negate_i32 {] +task 19 lines 230-230: run 0xff::negate_i32::test1 --verbose +task 20 lines 232-232: run 0xff::negate_i32::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i32, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i32") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.opt-extra.exp new file mode 100644 index 00000000000..7ca3897fa12 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.opt-extra.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 215-228: publish [module 0xff::negate_i32 {] +task 19 lines 230-230: run 0xff::negate_i32::test1 --verbose +task 20 lines 232-232: run 0xff::negate_i32::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i32, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.optimize.exp new file mode 100644 index 00000000000..9383b774976 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i32.optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 215-228: publish [module 0xff::negate_i32 {] +task 19 lines 230-230: run 0xff::negate_i32::test1 --verbose +task 20 lines 232-232: run 0xff::negate_i32::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i32, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i32") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.baseline.exp new file mode 100644 index 00000000000..f04c7b377c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 214-227: publish [module 0xff::negate_i64 {] +task 19 lines 229-229: run 0xff::negate_i64::test1 --verbose +task 20 lines 231-231: run 0xff::negate_i64::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i64, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i64") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.move new file mode 100644 index 00000000000..4dce9983f7e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.move @@ -0,0 +1,231 @@ +//# run --verbose +script { + fun main() { + assert!(0i64 + 0i64 == 0i64, 1000); + assert!(0i64 + 1i64 == 1i64, 1001); + assert!(1i64 + 1i64 == 2i64, 1002); + assert!(0i64 + -1i64 == -1i64, 1003); + assert!(-1i64 + -1i64 == -2i64, 1004); + + assert!(13i64 + 67i64 == 80i64, 1100); + assert!(100i64 + 10i64 == 110i64, 1101); + assert!(-13i64 + -67i64 == -80i64, 1102); + assert!(-100i64 + -10i64 == -110i64, 1103); + + assert!(0i64 + 9223372036854775807i64 == 9223372036854775807i64, 1200); + assert!(1i64 + 9223372036854775806i64 == 9223372036854775807i64, 1201); + assert!(5i64 + 9223372036854775802i64 == 9223372036854775807i64, 1202); + assert!(0i64 + -9223372036854775808i64 == -9223372036854775808i64, 1203); + assert!(-1i64 + -9223372036854775807i64 == -9223372036854775808i64, 1204); + assert!(-5i64 + -9223372036854775803i64 == -9223372036854775808i64, 1205); + } +} + +//# run --verbose +script { + fun main() { + 1i64 + 9223372036854775807i64; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + -1i64 + (-9223372036854775808i64); // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i64 - 0i64 == 0i64, 2000); + assert!(1i64 - 0i64 == 1i64, 2001); + assert!(1i64 - 1i64 == 0i64, 2002); + assert!(-1i64 - -0i64 == -1i64, 2003); + assert!(-1i64 - -1i64 == 0i64, 2004); + + assert!(52i64 - 13i64 == 39i64, 2100); + assert!(100i64 - 10i64 == 90i64, 2101); + assert!(-52i64 - -13i64 == -39i64, 2102); + assert!(-100i64 - -10i64 == -90i64, 2103); + + assert!(0i64 - -9223372036854775807i64 == 9223372036854775807i64, 2200); + assert!(1i64 - -9223372036854775806i64 == 9223372036854775807i64, 2201); + assert!(5i64 - -9223372036854775802i64 == 9223372036854775807i64, 2202); + assert!(-1i64 - 9223372036854775807i64 == -9223372036854775808i64, 2203); + assert!(-5i64 - 9223372036854775803i64 == -9223372036854775808i64, 2204); + assert!(-9223372036854775808i64 - 0 == -9223372036854775808i64, 2205); +} +} + +//# run --verbose +script { + fun main() { + -2i64 - 9223372036854775807i64; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + 1i64 - -9223372036854775807i64; // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i64 * 0i64 == 0i64, 3000); + assert!(1i64 * 0i64 == 0i64, 3001); + assert!(1i64 * 1i64 == 1i64, 3002); + assert!(-1i64 * 0i64 == 0i64, 3003); + assert!(-1i64 * 1i64 == -1i64, 3004); + assert!(1i64 * -1i64 == -1i64, 3005); + assert!(-1i64 * -1i64 == 1i64, 3006); + + assert!(6i64 * 7i64 == 42i64, 3100); + assert!(10i64 * 10i64 == 100i64, 3101); + assert!(6i64 * -7i64 == -42i64, 3102); + assert!(10i64 * -10i64 == -100i64, 3103); + assert!(-6i64 * 7i64 == -42i64, 3104); + assert!(-10i64 * 10i64 == -100i64, 3105); + assert!(-6i64 * -7i64 == 42i64, 3106); + assert!(-10i64 * -10i64 == 100i64, 3107); + + assert!(3037000499i64 * 3037000499i64 == 9223372030926249001i64, 3200); + assert!(-3037000499i64 * -3037000499i64 == 9223372030926249001i64, 3201); + assert!(3037000499i64 * -3037000499i64 == -9223372030926249001i64, 3202); + assert!(-3037000499i64 * 3037000499i64 == -9223372030926249001i64, 3203); +} +} + +//# run --verbose +script { +fun main() { + 3037000500i64 * 3037000500i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -3037000500i64 * -3037000500i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + 9223372036854775807i64 * 2i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -9223372036854775808i64 * -1i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i64 / 1i64 == 0i64, 4000); + assert!(1i64 / 1i64 == 1i64, 4001); + assert!(1i64 / 2i64 == 0i64, 4002); + assert!(0i64 / -1i64 == 0i64, 4003); + assert!(1i64 / -1i64 == -1i64, 4004); + assert!(1i64 / -2i64 == 0i64, 4005); + assert!(-1i64 / 1i64 == -1i64, 4006); + assert!(-1i64 / 2i64 == 0i64, 4007); + assert!(-1i64 / -1i64 == 1i64, 4008); + assert!(-1i64 / -2i64 == 0i64, 4009); + + assert!(6i64 / 3i64 == 2i64, 4100); + assert!(9223372036854775807i64 / 7i64 == 1317624576693539401i64, 4101); + assert!(-6i64 / 3i64 == -2i64, 4102); + assert!(-9223372036854775807i64 / 7i64 == -1317624576693539401i64, 4103); + assert!(6i64 / -3i64 == -2i64, 4104); + assert!(9223372036854775807i64 / -7i64 == -1317624576693539401i64, 4105); + assert!(-6i64 / -3i64 == 2i64, 4106); + assert!(-9223372036854775807i64 / -7i64 == 1317624576693539401i64, 4107); +} +} + +//# run --verbose +script { +fun main() { + 1i64 / 0i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i64 / 0i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -9223372036854775808i64 / -1i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i64 % 1i64 == 0i64, 5000); + assert!(1i64 % 1i64 == 0i64, 5001); + assert!(1i64 % 2i64 == 1i64, 5002); + assert!(-1i64 % 1i64 == 0i64, 5003); + assert!(-1i64 % 2i64 == -1i64, 5004); + assert!(1i64 % -1i64 == 0i64, 5005); + assert!(1i64 % -2i64 == 1i64, 5006); + assert!(-1i64 % -1i64 == 0i64, 5007); + assert!(-1i64 % -2i64 == -1i64, 5008); + + assert!(8i64 % 3i64 == 2i64, 5100); + assert!(9223372036854775806i64 % 7i64 == 6i64, 5101); + assert!(-8i64 % 3i64 == -2i64, 5102); + assert!(-9223372036854775806i64 % 7i64 == -6i64, 5103); + assert!(8i64 % -3i64 == 2i64, 5104); + assert!(9223372036854775806i64 % -7i64 == 6i64, 5105); + assert!(-8i64 % -3i64 == -2i64, 5106); + assert!(-9223372036854775806i64 % -7i64 == -6i64, 5107); +} +} + +//# run --verbose +script { +fun main() { + 1i64 % 0i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i64 % 0i64; // expect to abort +} +} + +//# publish +module 0xff::negate_i64 { + fun negate(a: i64): i64 { + -a + } + public fun test1(){ + let a = 20i64; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -9223372036854775808i64; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i64::test1 --verbose + +//# run 0xff::negate_i64::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.no-optimize.exp new file mode 100644 index 00000000000..f04c7b377c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.no-optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 214-227: publish [module 0xff::negate_i64 {] +task 19 lines 229-229: run 0xff::negate_i64::test1 --verbose +task 20 lines 231-231: run 0xff::negate_i64::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i64, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i64") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.opt-extra.exp new file mode 100644 index 00000000000..f620bd0a957 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.opt-extra.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 214-227: publish [module 0xff::negate_i64 {] +task 19 lines 229-229: run 0xff::negate_i64::test1 --verbose +task 20 lines 231-231: run 0xff::negate_i64::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i64, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.optimize.exp new file mode 100644 index 00000000000..f04c7b377c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i64.optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-153: run --verbose [script {] +task 12 lines 155-160: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 162-167: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 169-174: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 176-198: run --verbose [script {] +task 16 lines 200-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 207-212: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 214-227: publish [module 0xff::negate_i64 {] +task 19 lines 229-229: run 0xff::negate_i64::test1 --verbose +task 20 lines 231-231: run 0xff::negate_i64::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i64, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i64") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.baseline.exp new file mode 100644 index 00000000000..a33cf05ce8f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i8 {] +task 19 lines 234-234: run 0xff::negate_i8::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i8::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i8, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i8") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.move new file mode 100644 index 00000000000..9d4fab16835 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.move @@ -0,0 +1,236 @@ +//# run --verbose +script { + fun main() { + assert!(0i8 + 0i8 == 0i8, 1000); + assert!(0i8 + 1i8 == 1i8, 1001); + assert!(1i8 + 1i8 == 2i8, 1002); + assert!(0i8 + -1i8 == -1i8, 1003); + assert!(-1i8 + -1i8 == -2i8, 1004); + + assert!(13i8 + 67i8 == 80i8, 1100); + assert!(100i8 + 10i8 == 110i8, 1101); + assert!(-13i8 + -67i8 == -80i8, 1102); + assert!(-100i8 + -10i8 == -110i8, 1103); + + assert!(0i8 + 127i8 == 127i8, 1200); + assert!(1i8 + 126i8 == 127i8, 1201); + assert!(5i8 + 122i8 == 127i8, 1202); + assert!(0i8 + -128i8 == -128i8, 1203); + assert!(-1i8 + -127i8 == -128i8, 1204); + assert!(-5i8 + -123i8 == -128i8, 1205); + } +} + +//# run --verbose +script { + fun main() { + 1i8 + 127i8; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + -1i8 + (-128i8); // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i8 - 0i8 == 0i8, 2000); + assert!(1i8 - 0i8 == 1i8, 2001); + assert!(1i8 - 1i8 == 0i8, 2002); + assert!(-1i8 - -0i8 == -1i8, 2003); + assert!(-1i8 - -1i8 == 0i8, 2004); + + assert!(52i8 - 13i8 == 39i8, 2100); + assert!(100i8 - 10i8 == 90i8, 2101); + assert!(-52i8 - -13i8 == -39i8, 2102); + assert!(-100i8 - -10i8 == -90i8, 2103); + + assert!(0i8 - -127i8 == 127i8, 2201); + assert!(1i8 - -126i8 == 127i8, 2202); + assert!(5i8 - -122i8 == 127i8, 2203); + assert!(-1i8 - 127i8 == -128i8, 2204); + assert!(-5i8 - 123i8 == -128i8, 2205); + assert!(-128i8 - 0 == -128i8, 2206); +} +} + +//# run --verbose +script { + fun main() { + -2i8 - 127i8; // expect to abort + } +} + +//# run --verbose +script { + fun main() { + 1i8 - -127i8; // expect to abort + } +} + +//# run --verbose +script { +fun main() { + assert!(0i8 * 0i8 == 0i8, 3000); + assert!(1i8 * 0i8 == 0i8, 3001); + assert!(1i8 * 1i8 == 1i8, 3002); + assert!(-1i8 * 0i8 == 0i8, 3003); + assert!(-1i8 * 1i8 == -1i8, 3004); + assert!(1i8 * -1i8 == -1i8, 3005); + assert!(-1i8 * -1i8 == 1i8, 3006); + + assert!(6i8 * 7i8 == 42i8, 3100); + assert!(10i8 * 10i8 == 100i8, 3101); + assert!(6i8 * -7i8 == -42i8, 3102); + assert!(10i8 * -10i8 == -100i8, 3103); + assert!(-6i8 * 7i8 == -42i8, 3104); + assert!(-10i8 * 10i8 == -100i8, 3105); + assert!(-6i8 * -7i8 == 42i8, 3106); + assert!(-10i8 * -10i8 == 100i8, 3107); + + assert!(63i8 * 2i8 == 126i8, 3200); + assert!(-63i8 * -2i8 == 126i8, 3201); + assert!(-64i8 * 2i8 == -128i8, 3202); + assert!(64i8 * -2i8 == -128i8, 3203); +} +} + +//# run --verbose +script { +fun main() { + 8i8 * 16i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -8i8 * -16i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + 9i8 * -16i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -9i8 * 16i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i8 / 1i8 == 0i8, 4000); + assert!(1i8 / 1i8 == 1i8, 4001); + assert!(1i8 / 2i8 == 0i8, 4002); + assert!(0i8 / -1i8 == 0i8, 4003); + assert!(1i8 / -1i8 == -1i8, 4004); + assert!(1i8 / -2i8 == 0i8, 4005); + assert!(-0i8 / 1i8 == 0i8, 4006); + assert!(-1i8 / 1i8 == -1i8, 4007); + assert!(-1i8 / 2i8 == 0i8, 4008); + assert!(-0i8 / -1i8 == 0i8, 4009); + assert!(-1i8 / -1i8 == 1i8, 40010); + assert!(-1i8 / -2i8 == 0i8, 40011); + + assert!(6i8 / 3i8 == 2i8, 4100); + assert!(127i8 / 7i8 == 18i8, 4101); + assert!(-6i8 / 3i8 == -2i8, 4102); + assert!(-127i8 / 7i8 == -18i8, 4103); + assert!(6i8 / -3i8 == -2i8, 4104); + assert!(127i8 / -7i8 == -18i8, 4105); + assert!(-6i8 / -3i8 == 2i8, 4106); + assert!(-127i8 / -7i8 == 18i8, 4107); +} +} + +//# run --verbose +script { +fun main() { + 1i8 / 0i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i8 / 0i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -128i8 / -1i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + assert!(0i8 % 1i8 == 0i8, 5000); + assert!(1i8 % 1i8 == 0i8, 5001); + assert!(1i8 % 2i8 == 1i8, 5002); + assert!(-0i8 % 1i8 == 0i8, 5003); + assert!(-1i8 % 1i8 == 0i8, 5004); + assert!(-1i8 % 2i8 == -1i8, 5005); + assert!(0i8 % -1i8 == 0i8, 5006); + assert!(1i8 % -1i8 == 0i8, 5007); + assert!(1i8 % -2i8 == 1i8, 5008); + assert!(-0i8 % -1i8 == 0i8, 5009); + assert!(-1i8 % -1i8 == 0i8, 50010); + assert!(-1i8 % -2i8 == -1i8, 50011); + + assert!(8i8 % 3i8 == 2i8, 5100); + assert!(127i8 % 7i8 == 1i8, 5101); + assert!(-8i8 % 3i8 == -2i8, 5102); + assert!(-127i8 % 7i8 == -1i8, 5103); + assert!(8i8 % -3i8 == 2i8, 5104); + assert!(127i8 % -7i8 == 1i8, 5105); + assert!(-8i8 % -3i8 == -2i8, 5106); + assert!(-127i8 % -7i8 == -1i8, 5107); +} +} + +//# run --verbose +script { +fun main() { + 1i8 % 0i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + -1i8 % 0i8; // expect to abort +} +} + +//# publish +module 0xff::negate_i8 { + fun negate(a: i8): i8 { + -a + } + public fun test1(){ + let a = 20i8; + assert!(-a == negate(a)); + } + public fun test2(){ + let a = -128i8; + negate(a); // expect abort + } +} + +//# run 0xff::negate_i8::test1 --verbose + +//# run 0xff::negate_i8::test2 --verbose diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.no-optimize.exp new file mode 100644 index 00000000000..a33cf05ce8f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.no-optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i8 {] +task 19 lines 234-234: run 0xff::negate_i8::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i8::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i8, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i8") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.opt-extra.exp new file mode 100644 index 00000000000..05fc864c72a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.opt-extra.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i8 {] +task 19 lines 234-234: run 0xff::negate_i8::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i8::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i8, + indices: [], + offsets: [(FunctionDefinitionIndex(2), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.optimize.exp new file mode 100644 index 00000000000..a33cf05ce8f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/arithmetic_i8.optimize.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 1-22: run --verbose [script {] +task 1 lines 24-29: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 31-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 38-59: run --verbose [script {] +task 4 lines 61-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-73: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 75-100: run --verbose [script {] +task 7 lines 102-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 109-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 116-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 130-155: run --verbose [script {] +task 12 lines 157-162: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 164-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 171-176: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 178-203: run --verbose [script {] +task 16 lines 205-210: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 212-217: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 219-232: publish [module 0xff::negate_i8 {] +task 19 lines 234-234: run 0xff::negate_i8::test1 --verbose +task 20 lines 236-236: run 0xff::negate_i8::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i8, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i8") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.baseline.exp new file mode 100644 index 00000000000..518f30f6e7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.baseline.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-63: run --verbose [script {] +task 2 lines 65-79: run --verbose [script {] +task 3 lines 81-87: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 89-97: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 99-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 109-115: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-170141183460469231731687303715884105729) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.move new file mode 100644 index 00000000000..1c5f58a5106 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.move @@ -0,0 +1,115 @@ +//# run --verbose +script { +fun main() { + let v0: i128 = 0i128; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i8 = 0i8; + let v8: i16 = 0i16; + let v9: i32 = 0i32; + let v10: i64 = 0i64; + let v11: i128 = 0i128; + let v12: i256 = 0i256; + assert!((v1 as i128) == 0i128); + assert!((v2 as i128) == 0i128); + assert!((v3 as i128) == 0i128); + assert!((v4 as i128) == 0i128); + assert!((v5 as i128) == 0i128); + assert!((v6 as i128) == 0i128); + assert!((v7 as i128) == 0i128); + assert!((v8 as i128) == 0i128); + assert!((v9 as i128) == 0i128); + assert!((v10 as i128) == 0i128); + assert!((v11 as i128) == 0i128); + assert!((v12 as i128) == 0i128); +} +} + +//# run --verbose +script { +fun main() { + let v0: i128 = 170141183460469231731687303715884105727i128; // i128::MAX + assert!((v0 as u128) == 170141183460469231731687303715884105727u128); + assert!((v0 as u256) == 170141183460469231731687303715884105727u256); + assert!((v0 as i128) == 170141183460469231731687303715884105727i128); + assert!((v0 as i256) == 170141183460469231731687303715884105727i256); + + let v5: u128 = 170141183460469231731687303715884105727u128; + let v6: u256 = 170141183460469231731687303715884105727u256; + let v7: i128 = 170141183460469231731687303715884105727i128; + let v8: i256 = 170141183460469231731687303715884105727i256; + assert!((v5 as i128) == 170141183460469231731687303715884105727i128); + assert!((v6 as i128) == 170141183460469231731687303715884105727i128); + assert!((v7 as i128) == 170141183460469231731687303715884105727i128); + assert!((v8 as i128) == 170141183460469231731687303715884105727i128); +} +} + +//# run --verbose +script { +fun main() { + let v0: i128 = -170141183460469231731687303715884105728i128; // i128::MIN + assert!((v0 as i128) == -170141183460469231731687303715884105728i128); + assert!((v0 as i256) == -170141183460469231731687303715884105728i256); + + let v7 = -170141183460469231731687303715884105728i128; + let v8 = -170141183460469231731687303715884105728i256; + assert!((v7 as i128) == -170141183460469231731687303715884105728i128); + assert!((v8 as i128) == -170141183460469231731687303715884105728i128); +} +} + +// Unsigned → i128 (overflow when ≥ 170141183460469231731687303715884105728) + +//# run --verbose +script { +fun main() { + let v0 = 170141183460469231731687303715884105728u128; + let _v2 = v0 as i128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 170141183460469231731687303715884105728u256; + let _v2 = v0 as i128; // expect to abort +} +} + +// Signed → i128 (overflow above i128::MAX) + +//# run --verbose +script { +fun main() { + let v0 = 170141183460469231731687303715884105728i256; + let _v2 = v0 as i128; // expect to abort +} +} + +// Signed → i128 (overflow below i128::MIN) + +//# run --verbose +script { +fun main() { + let v0 = -170141183460469231731687303715884105729i256; + let _v2 = v0 as i128; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.no-optimize.exp new file mode 100644 index 00000000000..518f30f6e7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.no-optimize.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-63: run --verbose [script {] +task 2 lines 65-79: run --verbose [script {] +task 3 lines 81-87: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 89-97: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 99-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 109-115: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-170141183460469231731687303715884105729) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.opt-extra.exp new file mode 100644 index 00000000000..518f30f6e7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.opt-extra.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-63: run --verbose [script {] +task 2 lines 65-79: run --verbose [script {] +task 3 lines 81-87: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 89-97: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 99-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 109-115: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-170141183460469231731687303715884105729) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.optimize.exp new file mode 100644 index 00000000000..518f30f6e7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i128.optimize.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-63: run --verbose [script {] +task 2 lines 65-79: run --verbose [script {] +task 3 lines 81-87: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 89-97: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 99-107: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 109-115: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-170141183460469231731687303715884105729) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.baseline.exp new file mode 100644 index 00000000000..1ccc7dbc75d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.baseline.exp @@ -0,0 +1,134 @@ +processed 16 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-81: run --verbose [script {] +task 2 lines 83-106: run --verbose [script {] +task 3 lines 108-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 124-130: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 132-138: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 140-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 150-156: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 158-164: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 166-172: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 174-182: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 184-190: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 192-198: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 200-206: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 208-214: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.move new file mode 100644 index 00000000000..e9a25e4b61c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.move @@ -0,0 +1,214 @@ +//# run --verbose +script { +fun main() { + let v0: i16 = 0i16; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i8 = 0i8; + let v8: i16 = 0i16; + let v9: i32 = 0i32; + let v10: i64 = 0i64; + let v11: i128 = 0i128; + let v12: i256 = 0i256; + assert!((v1 as i16) == 0i16); + assert!((v2 as i16) == 0i16); + assert!((v3 as i16) == 0i16); + assert!((v4 as i16) == 0i16); + assert!((v5 as i16) == 0i16); + assert!((v6 as i16) == 0i16); + assert!((v7 as i16) == 0i16); + assert!((v8 as i16) == 0i16); + assert!((v9 as i16) == 0i16); + assert!((v10 as i16) == 0i16); + assert!((v11 as i16) == 0i16); + assert!((v12 as i16) == 0i16); +} +} + +//# run --verbose +script { +fun main() { + let v0: i16 = 32767i16; + assert!((v0 as u16) == 32767u16); + assert!((v0 as u32) == 32767u32); + assert!((v0 as u64) == 32767u64); + assert!((v0 as u128) == 32767u128); + assert!((v0 as u256) == 32767u256); + assert!((v0 as i16) == 32767i16); + assert!((v0 as i32) == 32767i32); + assert!((v0 as i64) == 32767i64); + assert!((v0 as i128) == 32767i128); + assert!((v0 as i256) == 32767i256); + + let v2: u16 = 32767u16; + let v3: u32 = 32767u32; + let v4: u64 = 32767u64; + let v5: u128 = 32767u128; + let v6: u256 = 32767u256; + let v7: i16 = 32767i16; + let v8: i32 = 32767i32; + let v9: i64 = 32767i64; + let v10: i128 = 32767i128; + let v11: i256 = 32767i256; + assert!((v2 as i16) == 32767i16); + assert!((v3 as i16) == 32767i16); + assert!((v4 as i16) == 32767i16); + assert!((v5 as i16) == 32767i16); + assert!((v6 as i16) == 32767i16); + assert!((v7 as i16) == 32767i16); + assert!((v8 as i16) == 32767i16); + assert!((v9 as i16) == 32767i16); + assert!((v10 as i16) == 32767i16); + assert!((v11 as i16) == 32767i16); +} +} + +//# run --verbose +script { +fun main() { + let v0: i16 = -32768i16; + assert!((v0 as i16) == -32768i16); + assert!((v0 as i32) == -32768i32); + assert!((v0 as i64) == -32768i64); + assert!((v0 as i128) == -32768i128); + assert!((v0 as i256) == -32768i256); + + let v7 = -32768i16; + let v8 = -32768i32; + let v9 = -32768i64; + let v10 = -32768i128; + let v11 = -32768i256; + assert!((v7 as i16) == -32768i16); + assert!((v8 as i16) == -32768i16); + assert!((v9 as i16) == -32768i16); + assert!((v10 as i16) == -32768i16); + assert!((v11 as i16) == -32768i16); +} +} + +// Unsigned → i16 (values ≥ 32768 overflow) + +//# run --verbose +script { +fun main() { + let v0 = 32768u16; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768u32; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768u64; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768u128; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768u256; + let _v2 = v0 as i16; // expect to abort +} +} + +// Signed → i16, overflow above 32767 + +//# run --verbose +script { +fun main() { + let v0 = 32768i32; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768i64; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768i128; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 32768i256; + let _v2 = v0 as i16; // expect to abort +} +} + +// Signed → i16, overflow below -32768 + +//# run --verbose +script { +fun main() { + let v0 = -32769i32; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -32769i64; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -32769i128; + let _v2 = v0 as i16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -32769i256; + let _v2 = v0 as i16; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.no-optimize.exp new file mode 100644 index 00000000000..1ccc7dbc75d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.no-optimize.exp @@ -0,0 +1,134 @@ +processed 16 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-81: run --verbose [script {] +task 2 lines 83-106: run --verbose [script {] +task 3 lines 108-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 124-130: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 132-138: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 140-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 150-156: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 158-164: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 166-172: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 174-182: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 184-190: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 192-198: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 200-206: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 208-214: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.opt-extra.exp new file mode 100644 index 00000000000..1ccc7dbc75d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.opt-extra.exp @@ -0,0 +1,134 @@ +processed 16 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-81: run --verbose [script {] +task 2 lines 83-106: run --verbose [script {] +task 3 lines 108-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 124-130: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 132-138: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 140-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 150-156: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 158-164: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 166-172: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 174-182: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 184-190: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 192-198: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 200-206: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 208-214: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.optimize.exp new file mode 100644 index 00000000000..1ccc7dbc75d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i16.optimize.exp @@ -0,0 +1,134 @@ +processed 16 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-81: run --verbose [script {] +task 2 lines 83-106: run --verbose [script {] +task 3 lines 108-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 124-130: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 132-138: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 140-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 150-156: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 158-164: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 166-172: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 174-182: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 184-190: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 192-198: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 200-206: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 208-214: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.baseline.exp new file mode 100644 index 00000000000..a2204a85db1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.baseline.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-54: run --verbose [script {] +task 2 lines 56-62: run --verbose [script {] +task 3 lines 64-70: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast int256::U256(57896044618658097711785492504343953926634992332820282019728792003956564819968) to int256::I256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.move new file mode 100644 index 00000000000..6d46473e03a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.move @@ -0,0 +1,70 @@ +//# run --verbose +script { +fun main() { + let v0: i256 = 0i256; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i8 = 0i8; + let v8: i16 = 0i16; + let v9: i32 = 0i32; + let v10: i64 = 0i64; + let v11: i128 = 0i128; + let v12: i256 = 0i256; + assert!((v1 as i256) == 0i256); + assert!((v2 as i256) == 0i256); + assert!((v3 as i256) == 0i256); + assert!((v4 as i256) == 0i256); + assert!((v5 as i256) == 0i256); + assert!((v6 as i256) == 0i256); + assert!((v7 as i256) == 0i256); + assert!((v8 as i256) == 0i256); + assert!((v9 as i256) == 0i256); + assert!((v10 as i256) == 0i256); + assert!((v11 as i256) == 0i256); + assert!((v12 as i256) == 0i256); +} +} + +//# run --verbose +script { +fun main() { + let v0: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + assert!((v0 as u256) == 57896044618658097711785492504343953926634992332820282019728792003956564819967u256); + + let v6: u256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967u256; + assert!((v6 as i256) == 57896044618658097711785492504343953926634992332820282019728792003956564819967i256); +} +} + +//# run --verbose +script { +fun main() { + let v0: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; + assert!((v0 as i256) == -57896044618658097711785492504343953926634992332820282019728792003956564819968i256); +} +} + +//# run --verbose +script { +fun main() { + let v0 = 57896044618658097711785492504343953926634992332820282019728792003956564819968u256; // one above i256::MAX + let _v2 = v0 as i256; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.no-optimize.exp new file mode 100644 index 00000000000..a2204a85db1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.no-optimize.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-54: run --verbose [script {] +task 2 lines 56-62: run --verbose [script {] +task 3 lines 64-70: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast int256::U256(57896044618658097711785492504343953926634992332820282019728792003956564819968) to int256::I256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.opt-extra.exp new file mode 100644 index 00000000000..a2204a85db1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.opt-extra.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-54: run --verbose [script {] +task 2 lines 56-62: run --verbose [script {] +task 3 lines 64-70: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast int256::U256(57896044618658097711785492504343953926634992332820282019728792003956564819968) to int256::I256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.optimize.exp new file mode 100644 index 00000000000..a2204a85db1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i256.optimize.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-54: run --verbose [script {] +task 2 lines 56-62: run --verbose [script {] +task 3 lines 64-70: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast int256::U256(57896044618658097711785492504343953926634992332820282019728792003956564819968) to int256::I256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.baseline.exp new file mode 100644 index 00000000000..24c780324c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.baseline.exp @@ -0,0 +1,72 @@ +processed 8 tasks +task 0 lines 1-26: run --verbose [script {] +task 1 lines 28-34: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 68-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 80-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(340282366920938463463374607431768211456) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.move new file mode 100644 index 00000000000..edf444117a2 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.move @@ -0,0 +1,86 @@ +//# run --verbose +script { +fun main() { + // ----- Success cases: 0 ----- + let v0: i8 = 0i8; + let v1: i16 = 0i16; + let v2: i32 = 0i32; + let v3: i64 = 0i64; + let v4: i128 = 0i128; + let v5: i256 = 0i256; + assert!((v0 as u128) == 0u128); + assert!((v1 as u128) == 0u128); + assert!((v2 as u128) == 0u128); + assert!((v3 as u128) == 0u128); + assert!((v4 as u128) == 0u128); + assert!((v5 as u128) == 0u128); + + // ----- Success cases: u128::MAX ----- + let w1: i256 = 340282366920938463463374607431768211455i256; + assert!((w1 as u128) == 340282366920938463463374607431768211455u128); +} +} + +// ----------------------------- +// Abort cases: negative values +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = -1i8; + let _ = v0 as u128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i16; + let _ = v0 as u128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i32; + let _ = v0 as u128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i64; + let _ = v0 as u128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i128; + let _ = v0 as u128; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i256; + let _ = v0 as u128; // expect to abort +} +} + +// ----------------------------- +// Abort cases: values above u128::MAX +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = 340282366920938463463374607431768211456i256; // one above u128::MAX + let _ = v0 as u128; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.no-optimize.exp new file mode 100644 index 00000000000..24c780324c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.no-optimize.exp @@ -0,0 +1,72 @@ +processed 8 tasks +task 0 lines 1-26: run --verbose [script {] +task 1 lines 28-34: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 68-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 80-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(340282366920938463463374607431768211456) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.opt-extra.exp new file mode 100644 index 00000000000..24c780324c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.opt-extra.exp @@ -0,0 +1,72 @@ +processed 8 tasks +task 0 lines 1-26: run --verbose [script {] +task 1 lines 28-34: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 68-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 80-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(340282366920938463463374607431768211456) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.optimize.exp new file mode 100644 index 00000000000..24c780324c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u128.optimize.exp @@ -0,0 +1,72 @@ +processed 8 tasks +task 0 lines 1-26: run --verbose [script {] +task 1 lines 28-34: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 68-78: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 80-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(340282366920938463463374607431768211456) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.baseline.exp new file mode 100644 index 00000000000..3bec3f934e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.baseline.exp @@ -0,0 +1,102 @@ +processed 11 tasks +task 0 lines 1-32: run --verbose [script {] +task 1 lines 34-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 42-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 50-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 58-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 66-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 74-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 86-92: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 94-100: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 102-108: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 110-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.move new file mode 100644 index 00000000000..f2dc5c6d04f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.move @@ -0,0 +1,116 @@ +//# run --verbose +script { +fun main() { + // ----- Success cases: 0 ----- + let v0: i8 = 0i8; + let v1: i16 = 0i16; + let v2: i32 = 0i32; + let v3: i64 = 0i64; + let v4: i128 = 0i128; + let v5: i256 = 0i256; + assert!((v0 as u16) == 0u16); + assert!((v1 as u16) == 0u16); + assert!((v2 as u16) == 0u16); + assert!((v3 as u16) == 0u16); + assert!((v4 as u16) == 0u16); + assert!((v5 as u16) == 0u16); + + // ----- Success cases: 65535 ----- + let w1: i32 = 65535i32; + let w2: i64 = 65535i64; + let w3: i128 = 65535i128; + let w4: i256 = 65535i256; + assert!((w1 as u16) == 65535u16); + assert!((w2 as u16) == 65535u16); + assert!((w3 as u16) == 65535u16); + assert!((w4 as u16) == 65535u16); +} +} + +// ----------------------------- +// Abort cases: negative values +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = -1i8; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i16; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i32; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i64; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i128; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i256; + let _ = v0 as u16; // expect to abort +} +} + +// ----------------------------- +// Abort cases: values above 65535 +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = 65536i32; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 65536i64; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 65536i128; + let _ = v0 as u16; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 65536i256; + let _ = v0 as u16; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.no-optimize.exp new file mode 100644 index 00000000000..3bec3f934e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.no-optimize.exp @@ -0,0 +1,102 @@ +processed 11 tasks +task 0 lines 1-32: run --verbose [script {] +task 1 lines 34-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 42-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 50-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 58-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 66-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 74-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 86-92: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 94-100: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 102-108: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 110-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.opt-extra.exp new file mode 100644 index 00000000000..3bec3f934e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.opt-extra.exp @@ -0,0 +1,102 @@ +processed 11 tasks +task 0 lines 1-32: run --verbose [script {] +task 1 lines 34-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 42-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 50-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 58-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 66-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 74-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 86-92: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 94-100: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 102-108: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 110-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.optimize.exp new file mode 100644 index 00000000000..3bec3f934e9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u16.optimize.exp @@ -0,0 +1,102 @@ +processed 11 tasks +task 0 lines 1-32: run --verbose [script {] +task 1 lines 34-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 42-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 50-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 58-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 66-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 74-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 86-92: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 94-100: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 102-108: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 110-116: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.baseline.exp new file mode 100644 index 00000000000..3612dce8f73 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.baseline.exp @@ -0,0 +1,62 @@ +processed 7 tasks +task 0 lines 1-36: run --verbose [script {] +task 1 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 70-76: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 78-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.move new file mode 100644 index 00000000000..6417c2feef6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.move @@ -0,0 +1,84 @@ +//# run --verbose +script { +fun main() { + // ----- Success cases: 0 ----- + let v0: i8 = 0i8; + let v1: i16 = 0i16; + let v2: i32 = 0i32; + let v3: i64 = 0i64; + let v4: i128 = 0i128; + let v5: i256 = 0i256; + assert!((v0 as u256) == 0u256); + assert!((v1 as u256) == 0u256); + assert!((v2 as u256) == 0u256); + assert!((v3 as u256) == 0u256); + assert!((v4 as u256) == 0u256); + assert!((v5 as u256) == 0u256); + + // ----- Success cases: large positive values (near signed max) ----- + let w1: i8 = 127i8; + let w2: i16 = 32767i16; + let w3: i32 = 2147483647i32; + let w4: i64 = 9223372036854775807i64; + let w5: i128 = 170141183460469231731687303715884105727i128; // i128::MAX + let w6: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; // i256::MAX + assert!((w1 as u256) == 127u256); + assert!((w2 as u256) == 32767u256); + assert!((w3 as u256) == 2147483647u256); + assert!((w4 as u256) == 9223372036854775807u256); + assert!((w5 as u256) == 170141183460469231731687303715884105727u256); + assert!((w6 as u256) == 57896044618658097711785492504343953926634992332820282019728792003956564819967u256); +} +} + +// ----------------------------- +// Abort cases: negative values +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = -1i8; + let _ = v0 as u256; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i16; + let _ = v0 as u256; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i32; + let _ = v0 as u256; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i64; + let _ = v0 as u256; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i128; + let _ = v0 as u256; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i256; + let _ = v0 as u256; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.no-optimize.exp new file mode 100644 index 00000000000..3612dce8f73 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.no-optimize.exp @@ -0,0 +1,62 @@ +processed 7 tasks +task 0 lines 1-36: run --verbose [script {] +task 1 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 70-76: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 78-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.opt-extra.exp new file mode 100644 index 00000000000..3612dce8f73 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.opt-extra.exp @@ -0,0 +1,62 @@ +processed 7 tasks +task 0 lines 1-36: run --verbose [script {] +task 1 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 70-76: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 78-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.optimize.exp new file mode 100644 index 00000000000..3612dce8f73 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u256.optimize.exp @@ -0,0 +1,62 @@ +processed 7 tasks +task 0 lines 1-36: run --verbose [script {] +task 1 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 70-76: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 78-84: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.baseline.exp new file mode 100644 index 00000000000..7a4b22f51a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.baseline.exp @@ -0,0 +1,82 @@ +processed 9 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 70-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 82-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.move new file mode 100644 index 00000000000..709fd5264fe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.move @@ -0,0 +1,96 @@ +//# run --verbose +script { +fun main() { + // ----- Success cases: 0 ----- + let v0: i8 = 0i8; + let v1: i16 = 0i16; + let v2: i32 = 0i32; + let v3: i64 = 0i64; + let v4: i128 = 0i128; + let v5: i256 = 0i256; + assert!((v0 as u64) == 0u64); + assert!((v1 as u64) == 0u64); + assert!((v2 as u64) == 0u64); + assert!((v3 as u64) == 0u64); + assert!((v4 as u64) == 0u64); + assert!((v5 as u64) == 0u64); + + // ----- Success cases: u64::MAX ----- + let w1: i128 = 18446744073709551615i128; + let w2: i256 = 18446744073709551615i256; + assert!((w1 as u64) == 18446744073709551615u64); + assert!((w2 as u64) == 18446744073709551615u64); +} +} + +// ----------------------------- +// Abort cases: negative values +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = -1i8; + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i16; + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i32; + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i64; + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i128; + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i256; + let _ = v0 as u64; // expect to abort +} +} + +// ----------------------------- +// Abort cases: values above u64::MAX +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = 18446744073709551616i128; // one above u64::MAX + let _ = v0 as u64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 18446744073709551616i256; // one above u64::MAX + let _ = v0 as u64; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.no-optimize.exp new file mode 100644 index 00000000000..7a4b22f51a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.no-optimize.exp @@ -0,0 +1,82 @@ +processed 9 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 70-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 82-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.opt-extra.exp new file mode 100644 index 00000000000..7a4b22f51a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.opt-extra.exp @@ -0,0 +1,82 @@ +processed 9 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 70-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 82-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.optimize.exp new file mode 100644 index 00000000000..7a4b22f51a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u64.optimize.exp @@ -0,0 +1,82 @@ +processed 9 tasks +task 0 lines 1-28: run --verbose [script {] +task 1 lines 30-36: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 38-44: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 46-52: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 54-60: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 62-68: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 70-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 82-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.baseline.exp new file mode 100644 index 00000000000..b594e901029 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.baseline.exp @@ -0,0 +1,112 @@ +processed 12 tasks +task 0 lines 1-34: run --verbose [script {] +task 1 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 76-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 88-94: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 96-102: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 104-110: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 112-118: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.move new file mode 100644 index 00000000000..3fa6fa15976 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.move @@ -0,0 +1,126 @@ +//# run --verbose +script { +fun main() { + // ----- Success cases: 0 ----- + let v0: i8 = 0i8; + let v1: i16 = 0i16; + let v2: i32 = 0i32; + let v3: i64 = 0i64; + let v4: i128 = 0i128; + let v5: i256 = 0i256; + assert!((v0 as u8) == 0u8); + assert!((v1 as u8) == 0u8); + assert!((v2 as u8) == 0u8); + assert!((v3 as u8) == 0u8); + assert!((v4 as u8) == 0u8); + assert!((v5 as u8) == 0u8); + + // ----- Success cases: 255 ----- + let w1: i16 = 255i16; + let w2: i32 = 255i32; + let w3: i64 = 255i64; + let w4: i128 = 255i128; + let w5: i256 = 255i256; + assert!((w1 as u8) == 255u8); + assert!((w2 as u8) == 255u8); + assert!((w3 as u8) == 255u8); + assert!((w4 as u8) == 255u8); + assert!((w5 as u8) == 255u8); +} +} + +// ----------------------------- +// Abort cases: negative values +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = -1i8; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i16; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i32; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i64; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i128; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -1i256; + let _ = v0 as u8; // expect to abort +} +} + +// ----------------------------- +// Abort cases: values above 255 +// ----------------------------- + +//# run --verbose +script { +fun main() { + let v0 = 256i16; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 256i32; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 256i64; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 256i128; + let _ = v0 as u8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 256i256; + let _ = v0 as u8; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.no-optimize.exp new file mode 100644 index 00000000000..b594e901029 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.no-optimize.exp @@ -0,0 +1,112 @@ +processed 12 tasks +task 0 lines 1-34: run --verbose [script {] +task 1 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 76-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 88-94: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 96-102: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 104-110: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 112-118: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.opt-extra.exp new file mode 100644 index 00000000000..b594e901029 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.opt-extra.exp @@ -0,0 +1,112 @@ +processed 12 tasks +task 0 lines 1-34: run --verbose [script {] +task 1 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 76-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 88-94: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 96-102: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 104-110: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 112-118: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.optimize.exp new file mode 100644 index 00000000000..b594e901029 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i2u8.optimize.exp @@ -0,0 +1,112 @@ +processed 12 tasks +task 0 lines 1-34: run --verbose [script {] +task 1 lines 36-42: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 44-50: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 52-58: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 60-66: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 68-74: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 76-86: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 88-94: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 96-102: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 104-110: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 112-118: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 120-126: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.baseline.exp new file mode 100644 index 00000000000..b8e7daf303b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.baseline.exp @@ -0,0 +1,104 @@ +processed 13 tasks +task 0 lines 1-39: run --verbose [script {] +task 1 lines 41-71: run --verbose [script {] +task 2 lines 73-93: run --verbose [script {] +task 3 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 111-117: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 119-127: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 129-135: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 137-143: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 145-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 155-161: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 163-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 171-177: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.move new file mode 100644 index 00000000000..7b86bd18819 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.move @@ -0,0 +1,177 @@ +//# run --verbose +script { +fun main() { + let v0: i32 = 0i32; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i32 = 0i32; + let v8: i64 = 0i64; + let v9: i128 = 0i128; + let v10: i256 = 0i256; + assert!((v1 as i32) == 0i32); + assert!((v2 as i32) == 0i32); + assert!((v3 as i32) == 0i32); + assert!((v4 as i32) == 0i32); + assert!((v5 as i32) == 0i32); + assert!((v6 as i32) == 0i32); + assert!((v7 as i32) == 0i32); + assert!((v8 as i32) == 0i32); + assert!((v9 as i32) == 0i32); + assert!((v10 as i32) == 0i32); +} +} + +//# run --verbose +script { +fun main() { + let v0: i32 = 2147483647i32; + assert!((v0 as u32) == 2147483647u32); + assert!((v0 as u64) == 2147483647u64); + assert!((v0 as u128) == 2147483647u128); + assert!((v0 as u256) == 2147483647u256); + assert!((v0 as i32) == 2147483647i32); + assert!((v0 as i64) == 2147483647i64); + assert!((v0 as i128) == 2147483647i128); + assert!((v0 as i256) == 2147483647i256); + + let v3: u32 = 2147483647u32; + let v4: u64 = 2147483647u64; + let v5: u128 = 2147483647u128; + let v6: u256 = 2147483647u256; + let v7: i32 = 2147483647i32; + let v8: i64 = 2147483647i64; + let v9: i128 = 2147483647i128; + let v10: i256 = 2147483647i256; + assert!((v3 as i32) == 2147483647i32); + assert!((v4 as i32) == 2147483647i32); + assert!((v5 as i32) == 2147483647i32); + assert!((v6 as i32) == 2147483647i32); + assert!((v7 as i32) == 2147483647i32); + assert!((v8 as i32) == 2147483647i32); + assert!((v9 as i32) == 2147483647i32); + assert!((v10 as i32) == 2147483647i32); +} +} + +//# run --verbose +script { +fun main() { + let v0: i32 = -2147483648i32; + assert!((v0 as i32) == -2147483648i32); + assert!((v0 as i64) == -2147483648i64); + assert!((v0 as i128) == -2147483648i128); + assert!((v0 as i256) == -2147483648i256); + + let v7 = -2147483648i32; + let v8 = -2147483648i64; + let v9 = -2147483648i128; + let v10 = -2147483648i256; + assert!((v7 as i32) == -2147483648i32); + assert!((v8 as i32) == -2147483648i32); + assert!((v9 as i32) == -2147483648i32); + assert!((v10 as i32) == -2147483648i32); +} +} + +// Unsigned → i32 (overflow when ≥ 2_147_483_648) + +//# run --verbose +script { +fun main() { + let v0 = 2147483648u32; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 2147483648u64; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 2147483648u128; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 2147483648u256; + let _v2 = v0 as i32; // expect to abort +} +} + +// Signed → i32 (overflow above 2_147_483_647) + +//# run --verbose +script { +fun main() { + let v0 = 2147483648i64; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 2147483648i128; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 2147483648i256; + let _v2 = v0 as i32; // expect to abort +} +} + +// Signed → i32 (overflow below -2_147_483_648) + +//# run --verbose +script { +fun main() { + let v0 = -2147483649i64; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -2147483649i128; + let _v2 = v0 as i32; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -2147483649i256; + let _v2 = v0 as i32; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.no-optimize.exp new file mode 100644 index 00000000000..b8e7daf303b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.no-optimize.exp @@ -0,0 +1,104 @@ +processed 13 tasks +task 0 lines 1-39: run --verbose [script {] +task 1 lines 41-71: run --verbose [script {] +task 2 lines 73-93: run --verbose [script {] +task 3 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 111-117: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 119-127: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 129-135: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 137-143: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 145-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 155-161: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 163-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 171-177: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.opt-extra.exp new file mode 100644 index 00000000000..b8e7daf303b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.opt-extra.exp @@ -0,0 +1,104 @@ +processed 13 tasks +task 0 lines 1-39: run --verbose [script {] +task 1 lines 41-71: run --verbose [script {] +task 2 lines 73-93: run --verbose [script {] +task 3 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 111-117: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 119-127: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 129-135: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 137-143: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 145-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 155-161: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 163-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 171-177: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.optimize.exp new file mode 100644 index 00000000000..b8e7daf303b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i32.optimize.exp @@ -0,0 +1,104 @@ +processed 13 tasks +task 0 lines 1-39: run --verbose [script {] +task 1 lines 41-71: run --verbose [script {] +task 2 lines 73-93: run --verbose [script {] +task 3 lines 95-101: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 103-109: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 111-117: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 119-127: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 129-135: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 137-143: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 145-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 155-161: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 163-169: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 171-177: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.baseline.exp new file mode 100644 index 00000000000..87d6003fd1f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.baseline.exp @@ -0,0 +1,74 @@ +processed 10 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-69: run --verbose [script {] +task 2 lines 71-88: run --verbose [script {] +task 3 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 98-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 106-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 124-132: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 134-140: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 142-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.move new file mode 100644 index 00000000000..76266961971 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.move @@ -0,0 +1,148 @@ +//# run --verbose +script { +fun main() { + let v0: i64 = 0i64; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i8 = 0i8; + let v8: i16 = 0i16; + let v9: i32 = 0i32; + let v10: i64 = 0i64; + let v11: i128 = 0i128; + let v12: i256 = 0i256; + assert!((v1 as i64) == 0i64); + assert!((v2 as i64) == 0i64); + assert!((v3 as i64) == 0i64); + assert!((v4 as i64) == 0i64); + assert!((v5 as i64) == 0i64); + assert!((v6 as i64) == 0i64); + assert!((v7 as i64) == 0i64); + assert!((v8 as i64) == 0i64); + assert!((v9 as i64) == 0i64); + assert!((v10 as i64) == 0i64); + assert!((v11 as i64) == 0i64); + assert!((v12 as i64) == 0i64); +} +} + +//# run --verbose +script { +fun main() { + let v0: i64 = 9223372036854775807i64; // i64::MAX + assert!((v0 as u64) == 9223372036854775807u64); + assert!((v0 as u128) == 9223372036854775807u128); + assert!((v0 as u256) == 9223372036854775807u256); + assert!((v0 as i64) == 9223372036854775807i64); + assert!((v0 as i128) == 9223372036854775807i128); + assert!((v0 as i256) == 9223372036854775807i256); + + let v4: u64 = 9223372036854775807u64; + let v5: u128 = 9223372036854775807u128; + let v6: u256 = 9223372036854775807u256; + let v7: i64 = 9223372036854775807i64; + let v8: i128 = 9223372036854775807i128; + let v9: i256 = 9223372036854775807i256; + assert!((v4 as i64) == 9223372036854775807i64); + assert!((v5 as i64) == 9223372036854775807i64); + assert!((v6 as i64) == 9223372036854775807i64); + assert!((v7 as i64) == 9223372036854775807i64); + assert!((v8 as i64) == 9223372036854775807i64); + assert!((v9 as i64) == 9223372036854775807i64); +} +} + +//# run --verbose +script { +fun main() { + let v0: i64 = -9223372036854775808i64; // i64::MIN + assert!((v0 as i64) == -9223372036854775808i64); + assert!((v0 as i128) == -9223372036854775808i128); + assert!((v0 as i256) == -9223372036854775808i256); + + let v7 = -9223372036854775808i64; + let v8 = -9223372036854775808i128; + let v9 = -9223372036854775808i256; + assert!((v7 as i64) == -9223372036854775808i64); + assert!((v8 as i64) == -9223372036854775808i64); + assert!((v9 as i64) == -9223372036854775808i64); +} +} + +// Unsigned → i64 (overflow when ≥ 9_223_372_036_854_775_808) + +//# run --verbose +script { +fun main() { + let v0 = 9223372036854775808u64; + let _v2 = v0 as i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 9223372036854775808u128; + let _v2 = v0 as i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 9223372036854775808u256; + let _v2 = v0 as i64; // expect to abort +} +} + +// Signed → i64 (overflow above i64::MAX = 9_223_372_036_854_775_807) + +//# run --verbose +script { +fun main() { + let v0 = 9223372036854775808i128; + let _v2 = v0 as i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 9223372036854775808i256; + let _v2 = v0 as i64; // expect to abort +} +} + +// Signed → i64 (overflow below i64::MIN = -9_223_372_036_854_775_808) + +//# run --verbose +script { +fun main() { + let v0 = -9223372036854775809i128; + let _v2 = v0 as i64; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -9223372036854775809i256; + let _v2 = v0 as i64; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.no-optimize.exp new file mode 100644 index 00000000000..87d6003fd1f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.no-optimize.exp @@ -0,0 +1,74 @@ +processed 10 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-69: run --verbose [script {] +task 2 lines 71-88: run --verbose [script {] +task 3 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 98-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 106-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 124-132: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 134-140: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 142-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.opt-extra.exp new file mode 100644 index 00000000000..87d6003fd1f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.opt-extra.exp @@ -0,0 +1,74 @@ +processed 10 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-69: run --verbose [script {] +task 2 lines 71-88: run --verbose [script {] +task 3 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 98-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 106-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 124-132: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 134-140: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 142-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.optimize.exp new file mode 100644 index 00000000000..87d6003fd1f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i64.optimize.exp @@ -0,0 +1,74 @@ +processed 10 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-69: run --verbose [script {] +task 2 lines 71-88: run --verbose [script {] +task 3 lines 90-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 98-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 106-114: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 116-122: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 124-132: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 134-140: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 142-148: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.baseline.exp new file mode 100644 index 00000000000..52178d81bbe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.baseline.exp @@ -0,0 +1,164 @@ +processed 19 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-87: run --verbose [script {] +task 2 lines 89-113: run --verbose [script {] +task 3 lines 115-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u8(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 123-129: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 131-137: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 139-145: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 147-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 155-163: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 165-171: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 173-179: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 181-187: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 189-195: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 197-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 207-213: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 215-221: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 16 lines 223-229: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 231-237: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 239-245: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.move new file mode 100644 index 00000000000..a02df455025 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.move @@ -0,0 +1,245 @@ +//# run --verbose +script { +fun main() { + let v0: i8 = 0i8; + assert!((v0 as u8) == 0u8); + assert!((v0 as u16) == 0u16); + assert!((v0 as u32) == 0u32); + assert!((v0 as u64) == 0u64); + assert!((v0 as u128) == 0u128); + assert!((v0 as u256) == 0u256); + assert!((v0 as i8) == 0i8); + assert!((v0 as i16) == 0i16); + assert!((v0 as i32) == 0i32); + assert!((v0 as i64) == 0i64); + assert!((v0 as i128) == 0i128); + assert!((v0 as i256) == 0i256); + + let v1: u8 = 0u8; + let v2: u16 = 0u16; + let v3: u32 = 0u32; + let v4: u64 = 0u64; + let v5: u128 = 0u128; + let v6: u256 = 0u256; + let v7: i8 = 0i8; + let v8: i16 = 0i16; + let v9: i32 = 0i32; + let v10: i64 = 0i64; + let v11: i128 = 0i128; + let v12: i256 = 0i256; + assert!((v1 as i8) == 0i8); + assert!((v2 as i8) == 0i8); + assert!((v3 as i8) == 0i8); + assert!((v4 as i8) == 0i8); + assert!((v5 as i8) == 0i8); + assert!((v6 as i8) == 0i8); + assert!((v7 as i8) == 0i8); + assert!((v8 as i8) == 0i8); + assert!((v9 as i8) == 0i8); + assert!((v10 as i8) == 0i8); + assert!((v11 as i8) == 0i8); + assert!((v12 as i8) == 0i8); +} +} + +//# run --verbose +script { +fun main() { + let v0: i8 = 127i8; + assert!((v0 as u8) == 127u8); + assert!((v0 as u16) == 127u16); + assert!((v0 as u32) == 127u32); + assert!((v0 as u64) == 127u64); + assert!((v0 as u128) == 127u128); + assert!((v0 as u256) == 127u256); + assert!((v0 as i8) == 127i8); + assert!((v0 as i16) == 127i16); + assert!((v0 as i32) == 127i32); + assert!((v0 as i64) == 127i64); + assert!((v0 as i128) == 127i128); + assert!((v0 as i256) == 127i256); + + let v1: u8 = 127u8; + let v2: u16 = 127u16; + let v3: u32 = 127u32; + let v4: u64 = 127u64; + let v5: u128 = 127u128; + let v6: u256 = 127u256; + let v7: i8 = 127i8; + let v8: i16 = 127i16; + let v9: i32 = 127i32; + let v10: i64 = 127i64; + let v11: i128 = 127i128; + let v12: i256 = 127i256; + assert!((v1 as i8) == 127i8); + assert!((v2 as i8) == 127i8); + assert!((v3 as i8) == 127i8); + assert!((v4 as i8) == 127i8); + assert!((v5 as i8) == 127i8); + assert!((v6 as i8) == 127i8); + assert!((v7 as i8) == 127i8); + assert!((v8 as i8) == 127i8); + assert!((v9 as i8) == 127i8); + assert!((v10 as i8) == 127i8); + assert!((v11 as i8) == 127i8); + assert!((v12 as i8) == 127i8); +} +} + +//# run --verbose +script { +fun main() { + let v0: i8 = -128i8; + assert!((v0 as i8) == -128i8); + assert!((v0 as i16) == -128i16); + assert!((v0 as i32) == -128i32); + assert!((v0 as i64) == -128i64); + assert!((v0 as i128) == -128i128); + assert!((v0 as i256) == -128i256); + + let v7 = -128i8; + let v8 = -128i16; + let v9 = -128i32; + let v10 = -128i64; + let v11 = -128i128; + let v12 = -128i256; + assert!((v7 as i8) == -128i8); + assert!((v8 as i8) == -128i8); + assert!((v9 as i8) == -128i8); + assert!((v10 as i8) == -128i8); + assert!((v11 as i8) == -128i8); + assert!((v12 as i8) == -128i8); +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u8; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u16; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u32; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u64; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u128; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128u256; + let _v2 = v0 as i8; // expect to abort +} +} + +// Signed types beyond i8::MAX (127) + +//# run --verbose +script { +fun main() { + let v0 = 128i16; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128i32; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128i64; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128i128; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = 128i256; + let _v2 = v0 as i8; // expect to abort +} +} + +// Signed types below i8::MIN (-128) + +//# run --verbose +script { +fun main() { + let v0 = -129i16; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -129i32; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -129i64; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -129i128; + let _v2 = v0 as i8; // expect to abort +} +} + +//# run --verbose +script { +fun main() { + let v0 = -129i256; + let _v2 = v0 as i8; // expect to abort +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.no-optimize.exp new file mode 100644 index 00000000000..52178d81bbe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.no-optimize.exp @@ -0,0 +1,164 @@ +processed 19 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-87: run --verbose [script {] +task 2 lines 89-113: run --verbose [script {] +task 3 lines 115-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u8(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 123-129: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 131-137: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 139-145: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 147-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 155-163: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 165-171: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 173-179: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 181-187: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 189-195: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 197-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 207-213: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 215-221: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 16 lines 223-229: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 231-237: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 239-245: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.opt-extra.exp new file mode 100644 index 00000000000..52178d81bbe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.opt-extra.exp @@ -0,0 +1,164 @@ +processed 19 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-87: run --verbose [script {] +task 2 lines 89-113: run --verbose [script {] +task 3 lines 115-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u8(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 123-129: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 131-137: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 139-145: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 147-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 155-163: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 165-171: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 173-179: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 181-187: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 189-195: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 197-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 207-213: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 215-221: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 16 lines 223-229: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 231-237: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 239-245: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.optimize.exp new file mode 100644 index 00000000000..52178d81bbe --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/cast_i8.optimize.exp @@ -0,0 +1,164 @@ +processed 19 tasks +task 0 lines 1-43: run --verbose [script {] +task 1 lines 45-87: run --verbose [script {] +task 2 lines 89-113: run --verbose [script {] +task 3 lines 115-121: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u8(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 123-129: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 131-137: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 139-145: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 147-153: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 155-163: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 165-171: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 173-179: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 181-187: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 189-195: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 197-205: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 207-213: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 215-221: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 16 lines 223-229: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 231-237: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 239-245: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.baseline.exp new file mode 100644 index 00000000000..4b68f4e03f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.baseline.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-27: run --verbose [script {] +task 2 lines 29-41: run --verbose [script {] +task 3 lines 43-55: run --verbose [script {] +task 4 lines 57-69: run --verbose [script {] +task 5 lines 71-83: run --verbose [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.move b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.move new file mode 100644 index 00000000000..f0cbd1bfbfb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.move @@ -0,0 +1,83 @@ +//# run --verbose +script { +fun main() { + assert!(0i8 < 1i8, 1000); + assert!(-1i8 < 0i8, 1001); + assert!(0i8 <= 1i8, 1002); + assert!(-1i8 <= 0i8, 1003); + assert!(1i8 > 0i8, 1004); + assert!(0i8 > -1i8, 1005); + assert!(1i8 >= 0i8, 1006); + assert!(0i8 >= -1i8, 1007); +} +} + +//# run --verbose +script { +fun main() { + assert!(0i16 < 1i16, 1000); + assert!(-1i16 < 0i16, 1001); + assert!(0i16 <= 1i16, 1002); + assert!(-1i16 <= 0i16, 1003); + assert!(1i16 > 0i16, 1004); + assert!(0i16 > -1i16, 1005); + assert!(1i16 >= 0i16, 1006); + assert!(0i16 >= -1i16, 1007); +} +} + +//# run --verbose +script { +fun main() { + assert!(0i32 < 1i32, 1000); + assert!(-1i32 < 0i32, 1001); + assert!(0i32 <= 1i32, 1002); + assert!(-1i32 <= 0i32, 1003); + assert!(1i32 > 0i32, 1004); + assert!(0i32 > -1i32, 1005); + assert!(1i32 >= 0i32, 1006); + assert!(0i32 >= -1i32, 1007); +} +} + +//# run --verbose +script { +fun main() { + assert!(0i64 < 1i64, 1000); + assert!(-1i64 < 0i64, 1001); + assert!(0i64 <= 1i64, 1002); + assert!(-1i64 <= 0i64, 1003); + assert!(1i64 > 0i64, 1004); + assert!(0i64 > -1i64, 1005); + assert!(1i64 >= 0i64, 1006); + assert!(0i64 >= -1i64, 1007); +} +} + +//# run --verbose +script { +fun main() { + assert!(0i128 < 1i128, 1000); + assert!(-1i128 < 0i128, 1001); + assert!(0i128 <= 1i128, 1002); + assert!(-1i128 <= 0i128, 1003); + assert!(1i128 > 0i128, 1004); + assert!(0i128 > -1i128, 1005); + assert!(1i128 >= 0i128, 1006); + assert!(0i128 >= -1i128, 1007); +} +} + +//# run --verbose +script { +fun main() { + assert!(0i256 < 1i256, 1000); + assert!(-1i256 < 0i256, 1001); + assert!(0i256 <= 1i256, 1002); + assert!(-1i256 <= 0i256, 1003); + assert!(1i256 > 0i256, 1004); + assert!(0i256 > -1i256, 1005); + assert!(1i256 >= 0i256, 1006); + assert!(0i256 >= -1i256, 1007); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.no-optimize.exp new file mode 100644 index 00000000000..4b68f4e03f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.no-optimize.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-27: run --verbose [script {] +task 2 lines 29-41: run --verbose [script {] +task 3 lines 43-55: run --verbose [script {] +task 4 lines 57-69: run --verbose [script {] +task 5 lines 71-83: run --verbose [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.opt-extra.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.opt-extra.exp new file mode 100644 index 00000000000..4b68f4e03f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.opt-extra.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-27: run --verbose [script {] +task 2 lines 29-41: run --verbose [script {] +task 3 lines 43-55: run --verbose [script {] +task 4 lines 57-69: run --verbose [script {] +task 5 lines 71-83: run --verbose [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.optimize.exp new file mode 100644 index 00000000000..4b68f4e03f9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/logic.optimize.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 1-13: run --verbose [script {] +task 1 lines 15-27: run --verbose [script {] +task 2 lines 29-41: run --verbose [script {] +task 3 lines 43-55: run --verbose [script {] +task 4 lines 57-69: run --verbose [script {] +task 5 lines 71-83: run --verbose [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled new file mode 100644 index 00000000000..78a5e1f110e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled @@ -0,0 +1,141 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i128.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i128 + 170141183460469231731687303715884105727i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 + -170141183460469231731687303715884105728i128; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i128 - 170141183460469231731687303715884105727i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i128 - -170141183460469231731687303715884105727i128; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 13043817825332782213i128 * 13043817825332782213i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 170141183460469231731687303715884105727i128 * 2i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -170141183460469231731687303715884105728i128 * -1i128; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i128 / 0i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -170141183460469231731687303715884105728i128 / -1i128; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i128 % 0i128; + } +} + + +//# publish +module 0xff::negate_i128 { + fun negate(p0: i128): i128 { + -p0 + } + public fun test1() { + let _v0 = -20i128; + let _v1 = negate(20i128); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-170141183460469231731687303715884105728i128); + } +} + + +//# run 0xff::negate_i128::test1 --verbose + +//# run 0xff::negate_i128::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled.baseline.exp new file mode 100644 index 00000000000..7902cc44025 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i128.decompiled.baseline.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-136: publish [module 0xff::negate_i128 {] +task 16 lines 139-139: run 0xff::negate_i128::test1 --verbose +task 17 lines 141-141: run 0xff::negate_i128::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i128, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i128") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled new file mode 100644 index 00000000000..d9e8a51862e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled @@ -0,0 +1,165 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i16.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i16 + 32767i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 + -32768i16; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i16 - 32767i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i16 - -32767i16; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i16 * 256i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -128i16 * -256i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 129i16 * -256i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i16 * 256i16; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i16 / 0i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 / 0i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -32768i16 / -1i16; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i16 % 0i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 % 0i16; + } +} + + +//# publish +module 0xff::negate_i16 { + fun negate(p0: i16): i16 { + -p0 + } + public fun test1() { + let _v0 = -20i16; + let _v1 = negate(20i16); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-32768i16); + } +} + + +//# run 0xff::negate_i16::test1 --verbose + +//# run 0xff::negate_i16::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled.baseline.exp new file mode 100644 index 00000000000..1c1e11cd80a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i16.decompiled.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +task 16 lines 131-136: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 139-144: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 147-160: publish [module 0xff::negate_i16 {] +task 19 lines 163-163: run 0xff::negate_i16::test1 --verbose +task 20 lines 165-165: run 0xff::negate_i16::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i16, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i16") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled new file mode 100644 index 00000000000..bda92f1453d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled @@ -0,0 +1,141 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i256.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i256 + 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 + -57896044618658097711785492504343953926634992332820282019728792003956564819968i256; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i256 - 57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i256 - -57896044618658097711785492504343953926634992332820282019728792003956564819967i256; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -57896044618658097711785492504343953926634992332820282019728792003956564819967i256 * 2i256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 * -1i256; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i256 / 0i256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 / -1i256; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i256 % 0i256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -57896044618658097711785492504343953926634992332820282019728792003956564819968i256 % 0i256; + } +} + + +//# publish +module 0xff::negate_i256 { + fun negate(p0: i256): i256 { + -p0 + } + public fun test1() { + let _v0 = -20i256; + let _v1 = negate(20i256); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-57896044618658097711785492504343953926634992332820282019728792003956564819968i256); + } +} + + +//# run 0xff::negate_i256::test1 --verbose + +//# run 0xff::negate_i256::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled.baseline.exp new file mode 100644 index 00000000000..d2a206a88b5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i256.decompiled.baseline.exp @@ -0,0 +1,118 @@ +processed 18 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 99-104: run --verbose [script {] +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-136: publish [module 0xff::negate_i256 {] +task 16 lines 139-139: run 0xff::negate_i256::test1 --verbose +task 17 lines 141-141: run 0xff::negate_i256::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i256, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i256") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled new file mode 100644 index 00000000000..3be9e5a1df1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled @@ -0,0 +1,165 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i32.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i32 + 2147483647i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 + -2147483648i32; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i32 - 2147483647i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i32 - -2147483647i32; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 46341i32 * 46341i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -46341i32 * -46341i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483647i32 * 2i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2147483648i32 * -1i32; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i32 / 0i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 / 0i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2147483648i32 / -1i32; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i32 % 0i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 % 0i32; + } +} + + +//# publish +module 0xff::negate_i32 { + fun negate(p0: i32): i32 { + -p0 + } + public fun test1() { + let _v0 = -20i32; + let _v1 = negate(20i32); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-2147483648i32); + } +} + + +//# run 0xff::negate_i32::test1 --verbose + +//# run 0xff::negate_i32::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled.baseline.exp new file mode 100644 index 00000000000..ef9bae87190 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i32.decompiled.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +task 16 lines 131-136: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 139-144: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 147-160: publish [module 0xff::negate_i32 {] +task 19 lines 163-163: run 0xff::negate_i32::test1 --verbose +task 20 lines 165-165: run 0xff::negate_i32::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i32, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i32") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled new file mode 100644 index 00000000000..84d8dc7d057 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled @@ -0,0 +1,165 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i64.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i64 + 9223372036854775807i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 + -9223372036854775808i64; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i64 - 9223372036854775807i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i64 - -9223372036854775807i64; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 3037000500i64 * 3037000500i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -3037000500i64 * -3037000500i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775807i64 * 2i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -9223372036854775808i64 * -1i64; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i64 / 0i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 / 0i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -9223372036854775808i64 / -1i64; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i64 % 0i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 % 0i64; + } +} + + +//# publish +module 0xff::negate_i64 { + fun negate(p0: i64): i64 { + -p0 + } + public fun test1() { + let _v0 = -20i64; + let _v1 = negate(20i64); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-9223372036854775808i64); + } +} + + +//# run 0xff::negate_i64::test1 --verbose + +//# run 0xff::negate_i64::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled.baseline.exp new file mode 100644 index 00000000000..9e179475c18 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i64.decompiled.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +task 16 lines 131-136: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 139-144: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 147-160: publish [module 0xff::negate_i64 {] +task 19 lines 163-163: run 0xff::negate_i64::test1 --verbose +task 20 lines 165-165: run 0xff::negate_i64::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i64, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i64") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled new file mode 100644 index 00000000000..3d45b1a69fa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled @@ -0,0 +1,165 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/arithmetic_i8.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i8 + 127i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 + -128i8; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2i8 - 127i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i8 - -127i8; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 8i8 * 16i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -8i8 * -16i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9i8 * -16i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -9i8 * 16i8; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i8 / 0i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 / 0i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -128i8 / -1i8; + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 1i8 % 0i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 % 0i8; + } +} + + +//# publish +module 0xff::negate_i8 { + fun negate(p0: i8): i8 { + -p0 + } + public fun test1() { + let _v0 = -20i8; + let _v1 = negate(20i8); + assert!(_v0 == _v1, 14566554180833181696); + } + public fun test2() { + let _v0 = negate(-128i8); + } +} + + +//# run 0xff::negate_i8::test1 --verbose + +//# run 0xff::negate_i8::test2 --verbose \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled.baseline.exp new file mode 100644 index 00000000000..9dbeba83c23 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/arithmetic_i8.decompiled.baseline.exp @@ -0,0 +1,148 @@ +processed 21 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Addition overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Subtraction overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Multiplication overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Division overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +task 16 lines 131-136: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 139-144: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Integer remainder by zero, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 147-160: publish [module 0xff::negate_i8 {] +task 19 lines 163-163: run 0xff::negate_i8::test1 --verbose +task 20 lines 165-165: run 0xff::negate_i8::test2 --verbose +Error: Function execution failed with VMError: { + message: Integer negation overflow, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xff::negate_i8, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [(Some(ModuleId { address: 00000000000000000000000000000000000000000000000000000000000000ff, name: Identifier("negate_i8") }), FunctionDefinitionIndex(2), 1)] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast.decompiled new file mode 100644 index 00000000000..ca62fb6cd15 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast.move` + +//# run --verbose +script { + fun main() { + if (!(-20i8 == -20i8)) abort 14566554180833181696; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled new file mode 100644 index 00000000000..f8dac356d84 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled @@ -0,0 +1,56 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i128.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 170141183460469231731687303715884105728u128 as i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 170141183460469231731687303715884105728u256 as i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 170141183460469231731687303715884105728i256 as i128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -170141183460469231731687303715884105729i256 as i128; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled.baseline.exp new file mode 100644 index 00000000000..7ca5da0d6d4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i128.decompiled.baseline.exp @@ -0,0 +1,44 @@ +processed 7 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(170141183460469231731687303715884105728) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-170141183460469231731687303715884105729) to i128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled new file mode 100644 index 00000000000..a4ed99b4c21 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled @@ -0,0 +1,128 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i16.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768u16 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768u32 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768u128 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768u256 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768i32 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768i64 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768i128 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 32768i256 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -32769i32 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -32769i64 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -32769i128 as i16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -32769i256 as i16; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled.baseline.exp new file mode 100644 index 00000000000..4164b663bce --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i16.decompiled.baseline.exp @@ -0,0 +1,134 @@ +processed 16 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(32768) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-32769) to i16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled new file mode 100644 index 00000000000..3838fba76cf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled @@ -0,0 +1,32 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i256.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 57896044618658097711785492504343953926634992332820282019728792003956564819968u256 as i256; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled.baseline.exp new file mode 100644 index 00000000000..6230475c2f7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i256.decompiled.baseline.exp @@ -0,0 +1,14 @@ +processed 4 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast int256::U256(57896044618658097711785492504343953926634992332820282019728792003956564819968) to int256::I256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled new file mode 100644 index 00000000000..82860e1f2c9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled @@ -0,0 +1,64 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i2u128.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 as u128; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 340282366920938463463374607431768211456i256 as u128; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled.baseline.exp new file mode 100644 index 00000000000..0800225f318 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u128.decompiled.baseline.exp @@ -0,0 +1,72 @@ +processed 8 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(340282366920938463463374607431768211456) to u128, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled new file mode 100644 index 00000000000..3631e26a67f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled @@ -0,0 +1,88 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i2u16.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 65536i32 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 65536i64 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 65536i128 as u16; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 65536i256 as u16; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled.baseline.exp new file mode 100644 index 00000000000..31553cdb3f4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u16.decompiled.baseline.exp @@ -0,0 +1,102 @@ +processed 11 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(65536) to u16, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled new file mode 100644 index 00000000000..19ee3e5f590 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled @@ -0,0 +1,56 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i2u256.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 as u256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 as u256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 as u256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 as u256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 as u256; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 as u256; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled.baseline.exp new file mode 100644 index 00000000000..ba5d18837a4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u256.decompiled.baseline.exp @@ -0,0 +1,62 @@ +processed 7 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to int256::U256, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled new file mode 100644 index 00000000000..ee559e375af --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled @@ -0,0 +1,72 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i2u64.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 18446744073709551616i128 as u64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 18446744073709551616i256 as u64; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled.baseline.exp new file mode 100644 index 00000000000..9df61ce87f4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u64.decompiled.baseline.exp @@ -0,0 +1,82 @@ +processed 9 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(18446744073709551616) to u64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled new file mode 100644 index 00000000000..83f1f74d788 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled @@ -0,0 +1,96 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i2u8.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i8 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i16 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i32 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i64 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i128 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -1i256 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 256i16 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 256i32 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 256i64 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 256i128 as u8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 256i256 as u8; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled.baseline.exp new file mode 100644 index 00000000000..1ae7e57af53 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i2u8.decompiled.baseline.exp @@ -0,0 +1,112 @@ +processed 12 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i8(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 2 lines 19-24: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-1) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(256) to u8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled new file mode 100644 index 00000000000..959d5bd6994 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled @@ -0,0 +1,104 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i32.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648u32 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648u128 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648u256 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648i64 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648i128 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 2147483648i256 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2147483649i64 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2147483649i128 as i32; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -2147483649i256 as i32; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled.baseline.exp new file mode 100644 index 00000000000..293984eb37d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i32.decompiled.baseline.exp @@ -0,0 +1,104 @@ +processed 13 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(2147483648) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-2147483649) to i32, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled new file mode 100644 index 00000000000..f2039e09587 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled @@ -0,0 +1,80 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i64.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775808 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775808u128 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775808u256 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775808i128 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 9223372036854775808i256 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -9223372036854775809i128 as i64; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -9223372036854775809i256 as i64; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled.baseline.exp new file mode 100644 index 00000000000..a7b323497b1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i64.decompiled.baseline.exp @@ -0,0 +1,74 @@ +processed 10 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(9223372036854775808) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-9223372036854775809) to i64, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled new file mode 100644 index 00000000000..642e72f1765 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled @@ -0,0 +1,152 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/cast_i8.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128u8 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128u16 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128u32 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128u128 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128u256 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i16 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i32 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i64 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i128 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = 128i256 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i16 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i32 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i64 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i128 as i8; + } +} + + +//# run --verbose +script { + fun main() { + let _v0 = -129i256 as i8; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled.baseline.exp new file mode 100644 index 00000000000..ab0373c8e9b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/cast_i8.decompiled.baseline.exp @@ -0,0 +1,164 @@ +processed 19 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u8(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 4 lines 35-40: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 5 lines 43-48: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 6 lines 51-56: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 7 lines 59-64: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast u128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 8 lines 67-72: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast U256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 9 lines 75-80: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 10 lines 83-88: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 11 lines 91-96: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 12 lines 99-104: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 13 lines 107-112: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(128) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 14 lines 115-120: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i16(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 15 lines 123-128: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i32(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 16 lines 131-136: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i64(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 17 lines 139-144: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast i128(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} +task 18 lines 147-152: run --verbose [script {] +Error: Script execution failed with VMError: { + message: Cannot cast I256(-129) to i8, + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled new file mode 100644 index 00000000000..b562db636fc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled @@ -0,0 +1,48 @@ +//**** Cross-compiled for `move` syntax from `tests/signed-int/logic.move` + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} + + +//# run --verbose +script { + fun main() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled.baseline.exp new file mode 100644 index 00000000000..d488f31c0a7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/signed-int/round-trip/logic.decompiled.baseline.exp @@ -0,0 +1,7 @@ +processed 6 tasks +task 0 lines 3-8: run --verbose [script {] +task 1 lines 11-16: run --verbose [script {] +task 2 lines 19-24: run --verbose [script {] +task 3 lines 27-32: run --verbose [script {] +task 4 lines 35-40: run --verbose [script {] +task 5 lines 43-48: run --verbose [script {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/conditional_borrow.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/conditional_borrow.exp index 6b402579ce5..4a8201e5025 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/conditional_borrow.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/conditional_borrow.exp @@ -1,7 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 54-54: +task 0 lines 1-52: publish [module 0x8675::M {] +task 1 lines 54-54: run 0x8675::M::test return values: 11 - -task 2 'run'. lines 56-56: +task 2 lines 56-56: run 0x8675::M::testb return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding.exp index 5d92c423f3f..8e377b27665 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-191: publish [module 0xcafe::MyModule {] +task 1 lines 193-193: run 0xcafe::MyModule::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_failure.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_failure.exp index 0867e291ae6..e1a947f628b 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_failure.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_failure.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 143-143: +task 0 lines 1-141: publish [module 0xcafe::ConstantFailure {] +task 1 lines 143-143: run 0xcafe::ConstantFailure::main Error: Function execution failed with VMError: { major_status: ARITHMETIC_ERROR, sub_status: None, diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_ristretto.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_ristretto.exp index 6cd67db3f64..4b91a607d20 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_ristretto.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/constant_folding_ristretto.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: publish [module 0xcafe::Ristretto {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled new file mode 100644 index 00000000000..6e6250a930a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled @@ -0,0 +1,76 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/conditional_borrow.move` + +//# publish +module 0x8675::M { + struct S has copy, drop { + f: u64, + } + public fun test(): u64 { + let _v0 = test1(7); + let _v1 = test1(2); + _v0 + _v1 + } + fun test1(p0: u64): u64 { + let _v0; + if (p0 < 4) _v0 = p0 else _v0 = 3; + let _v1 = &mut _v0; + *_v1 = 10; + let _v2 = p0; + _v1 = &mut _v2; + *_v1 = *_v1 + 1; + let _v3 = _v2; + let _v4 = _v3 + 0; + _v1 = &mut _v4; + *_v1 = *_v1 + 2; + let _v5 = _v3; + _v1 = &mut _v5; + *_v1 = *_v1 + 4; + let _v6 = _v3; + _v1 = &mut _v6; + *_v1 = *_v1 + 8; + let _v7 = _v3; + _v1 = &mut _v7; + *_v1 = *_v1 + 16; + _v3 + } + fun test1b(p0: S): u64 { + let _v0; + let _v1 = S{f: 3}; + if (*&(&p0).f < 4) _v0 = p0 else _v0 = _v1; + let _v2 = &mut _v0; + let _v3 = *_v2; + let _v4 = &mut (&mut _v3).f; + *_v4 = 10; + let _v5 = p0; + _v2 = &mut _v5; + let _v6 = *_v2; + let _v7 = *&(&_v6).f + 1; + let _v8 = *_v2; + let _v9 = &mut (&mut _v8).f; + *_v9 = _v7; + let _v10 = _v5; + let _v11 = &mut (&mut _v10).f; + *_v11 = *_v11 + 1; + let _v12 = _v10; + let _v13 = *&(&_v12).f; + _v11 = &mut _v13; + *_v11 = *_v11 + 1; + let _v14 = *&(&_v12).f; + _v11 = &mut _v14; + *_v11 = *_v11 + 8; + let _v15 = *&(&_v12).f; + _v11 = &mut _v15; + *_v11 = *_v11 + 16; + *&(&_v12).f + } + public fun testb(): u64 { + let _v0 = test1b(S{f: 7}); + let _v1 = test1b(S{f: 2}); + _v0 + _v1 + } +} + + +//# run 0x8675::M::test + +//# run 0x8675::M::testb \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled.baseline.exp new file mode 100644 index 00000000000..c0259cd253f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/conditional_borrow.decompiled.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 3-71: publish [module 0x8675::M {] +task 1 lines 74-74: run 0x8675::M::test +return values: 11 +task 2 lines 76-76: run 0x8675::M::testb +return values: 11 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled new file mode 100644 index 00000000000..b05ace58497 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled @@ -0,0 +1,75 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/constant_folding.move` + +//# publish +module 0xcafe::MyModule { + fun main() { + let _v0; + let _v1 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v2 = 0x1::vector::length(&_v1); + let _v3 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v4 = 0x1::vector::length(&_v3); + if (!(_v2 == _v4)) { + let _v5 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v6 = 0x1::vector::length(&_v5); + let _v7 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v8 = 0x1::vector::length(&_v7); + let _v9 = _v6 - _v8; + abort _v9 + }; + let _v10 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v11 = 0x1::vector::length(&_v10); + let _v12 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v13 = 0x1::vector::length(&_v12); + if (!(_v11 == _v13)) { + let _v14 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v15 = 0x1::vector::length(&_v14); + let _v16 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v17 = 0x1::vector::length(&_v16); + let _v18 = _v15 - _v17; + abort _v18 + }; + let _v19 = 0; + let _v20 = false; + let _v21 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v22 = 0x1::vector::length(&_v21); + 'l0: loop { + loop { + if (_v20) _v19 = _v19 + 1 else _v20 = true; + if (!(_v19 < _v22)) break 'l0; + let _v23 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v24 = 0x1::vector::borrow(&_v23, _v19); + let _v25 = vector[true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, false, false, false, true, true, true, false, true, false, true]; + let _v26 = 0x1::vector::borrow(&_v25, _v19); + if (_v24 == _v26) continue; + break + }; + abort _v19 + }; + let _v27 = vector[128u256, 9223372036854775808u256, 170141183460469231731687303715884105728u256, 1u256, 1u256, 1u256, 127u256, 9223372036854775807u256, 170141183460469231731687303715884105727u256, 1u256, 1u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 255u256, 18446744073709551615u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 3402823669209384u256, 340282366920938463463374607431768211455340282366920938463463374573u256, 340282366920938463463374267149401290516876818992313506695251919267u256, 340282366920938463463374267149401290518196254258471629768325169763u256, 340282366920938463463374607091485844535721254169704454104768413936u256, 0u256]; + let _v28 = 0x1::vector::length(&_v27); + let _v29 = vector[128u256, 9223372036854775808u256, 170141183460469231731687303715884105728u256, 1u256, 1u256, 1u256, 127u256, 9223372036854775807u256, 170141183460469231731687303715884105727u256, 1u256, 1u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 255u256, 18446744073709551615u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 3402823669209384u256, 340282366920938463463374607431768211455340282366920938463463374573u256, 340282366920938463463374267149401290516876818992313506695251919267u256, 340282366920938463463374267149401290518196254258471629768325169763u256, 340282366920938463463374607091485844535721254169704454104768413936u256, 0u256]; + let _v30 = 0x1::vector::length(&_v29); + if (_v28 < _v30) _v0 = 1000 + _v30 - _v28 else _v0 = 2000 + _v28 - _v30; + assert!(_v0 == 2000, _v0); + let _v31 = 0; + let _v32 = false; + let _v33 = vector[128u256, 9223372036854775808u256, 170141183460469231731687303715884105728u256, 1u256, 1u256, 1u256, 127u256, 9223372036854775807u256, 170141183460469231731687303715884105727u256, 1u256, 1u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 255u256, 18446744073709551615u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 3402823669209384u256, 340282366920938463463374607431768211455340282366920938463463374573u256, 340282366920938463463374267149401290516876818992313506695251919267u256, 340282366920938463463374267149401290518196254258471629768325169763u256, 340282366920938463463374607091485844535721254169704454104768413936u256, 0u256]; + let _v34 = 0x1::vector::length(&_v33); + 'l1: loop { + loop { + if (_v32) _v31 = _v31 + 1 else _v32 = true; + if (!(_v31 < _v34)) break 'l1; + let _v35 = vector[128u256, 9223372036854775808u256, 170141183460469231731687303715884105728u256, 1u256, 1u256, 1u256, 127u256, 9223372036854775807u256, 170141183460469231731687303715884105727u256, 1u256, 1u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 255u256, 18446744073709551615u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 3402823669209384u256, 340282366920938463463374607431768211455340282366920938463463374573u256, 340282366920938463463374267149401290516876818992313506695251919267u256, 340282366920938463463374267149401290518196254258471629768325169763u256, 340282366920938463463374607091485844535721254169704454104768413936u256, 0u256]; + let _v36 = 0x1::vector::borrow(&_v35, _v31); + let _v37 = vector[128u256, 9223372036854775808u256, 170141183460469231731687303715884105728u256, 1u256, 1u256, 1u256, 127u256, 9223372036854775807u256, 170141183460469231731687303715884105727u256, 1u256, 1u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 255u256, 18446744073709551615u256, 1u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 255u256, 18446744073709551615u256, 340282366920938463463374607431768211455u256, 0u256, 0u256, 0u256, 3402823669209384u256, 340282366920938463463374607431768211455340282366920938463463374573u256, 340282366920938463463374267149401290516876818992313506695251919267u256, 340282366920938463463374267149401290518196254258471629768325169763u256, 340282366920938463463374607091485844535721254169704454104768413936u256, 0u256]; + let _v38 = 0x1::vector::borrow(&_v37, _v31); + if (_v36 == _v38) continue; + break + }; + abort _v31 + }; + } +} + + +//# run 0xcafe::MyModule::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled.baseline.exp new file mode 100644 index 00000000000..b56e1b211bb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding.decompiled.baseline.exp @@ -0,0 +1,3 @@ +processed 2 tasks +task 0 lines 3-72: publish [module 0xcafe::MyModule {] +task 1 lines 75-75: run 0xcafe::MyModule::main diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled new file mode 100644 index 00000000000..981d4d81285 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled @@ -0,0 +1,246 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/constant_folding_failure.move` + +//# publish +module 0xcafe::ConstantFailure { + fun main() { + let _v0 = 1u8 << 8u8; + let _v1 = 0u8 >> 8u8; + let _v2 = 1u8 / 0u8; + let _v3 = 1u8 % 0u8; + let _v4 = 255u8 + 255u8; + let _v5 = 0u8 - 1u8; + let _v6 = 256 as u8; + let _v7 = 0x1::vector::empty(); + let _v8 = &mut _v7; + 0x1::vector::push_back(_v8, _v0); + 0x1::vector::push_back(_v8, _v1); + 0x1::vector::push_back(_v8, _v2); + 0x1::vector::push_back(_v8, _v3); + 0x1::vector::push_back(_v8, _v4); + 0x1::vector::push_back(_v8, _v5); + 0x1::vector::push_back(_v8, _v6); + let _v9 = _v7; + let _v10 = 1u16 << 16u8; + let _v11 = 0u16 >> 16u8; + let _v12 = 1u16 / 0u16; + let _v13 = 1u16 % 0u16; + let _v14 = 65535u16 + 65535u16; + let _v15 = 0u16 - 1u16; + let _v16 = 65536 as u16; + let _v17 = 0x1::vector::empty(); + let _v18 = &mut _v17; + 0x1::vector::push_back(_v18, _v10); + 0x1::vector::push_back(_v18, _v11); + 0x1::vector::push_back(_v18, _v12); + 0x1::vector::push_back(_v18, _v13); + 0x1::vector::push_back(_v18, _v14); + 0x1::vector::push_back(_v18, _v15); + 0x1::vector::push_back(_v18, _v16); + let _v19 = _v17; + let _v20 = 1u32 << 32u8; + let _v21 = (1u8 << 8u8) as u32; + let _v22 = (1u16 << 16u8) as u32; + let _v23 = 0u32 >> 32u8; + let _v24 = (0u8 >> 8u8) as u32; + let _v25 = (0u16 >> 16u8) as u32; + let _v26 = 1u32 / 0u32; + let _v27 = 1u32 % 0u32; + let _v28 = 4294967295u32 + 4294967295u32; + let _v29 = (65535u16 + 65535u16) as u32; + let _v30 = (65535u16 + 65535u16) as u32; + let _v31 = (65535u16 + 65535u16) as u32; + let _v32 = 0u32 - 1u32; + let _v33 = 4294967296u128 as u32; + let _v34 = 0x1::vector::empty(); + let _v35 = &mut _v34; + 0x1::vector::push_back(_v35, _v20); + 0x1::vector::push_back(_v35, _v21); + 0x1::vector::push_back(_v35, _v22); + 0x1::vector::push_back(_v35, _v23); + 0x1::vector::push_back(_v35, _v24); + 0x1::vector::push_back(_v35, _v25); + 0x1::vector::push_back(_v35, _v26); + 0x1::vector::push_back(_v35, _v27); + 0x1::vector::push_back(_v35, _v28); + 0x1::vector::push_back(_v35, _v29); + 0x1::vector::push_back(_v35, _v30); + 0x1::vector::push_back(_v35, _v31); + 0x1::vector::push_back(_v35, _v32); + 0x1::vector::push_back(_v35, _v33); + let _v36 = _v34; + let _v37 = 1 << 64u8; + let _v38 = (1u32 << 32u8) as u64; + let _v39 = 0 >> 64u8; + let _v40 = (0u32 >> 32u8) as u64; + let _v41 = 1 / 0; + let _v42 = 1 % 0; + let _v43 = 18446744073709551615 + 18446744073709551615; + let _v44 = (255u8 + 255u8) as u64; + let _v45 = (255u8 + 255u8) as u64; + let _v46 = (255u8 + 255u8) as u64; + let _v47 = (4294967295u32 + 4294967295u32) as u64; + let _v48 = (4294967295u32 + 4294967295u32) as u64; + let _v49 = (4294967295u32 + 4294967295u32) as u64; + let _v50 = 0 - 1; + let _v51 = 340282366920938463463374607431768211450u128 as u64; + let _v52 = 0x1::vector::empty(); + let _v53 = &mut _v52; + 0x1::vector::push_back(_v53, _v37); + 0x1::vector::push_back(_v53, _v38); + 0x1::vector::push_back(_v53, _v39); + 0x1::vector::push_back(_v53, _v40); + 0x1::vector::push_back(_v53, _v41); + 0x1::vector::push_back(_v53, _v42); + 0x1::vector::push_back(_v53, _v43); + 0x1::vector::push_back(_v53, _v44); + 0x1::vector::push_back(_v53, _v45); + 0x1::vector::push_back(_v53, _v46); + 0x1::vector::push_back(_v53, _v47); + 0x1::vector::push_back(_v53, _v48); + 0x1::vector::push_back(_v53, _v49); + 0x1::vector::push_back(_v53, _v50); + 0x1::vector::push_back(_v53, _v51); + let _v54 = _v52; + let _v55 = 1u128 << 128u8; + let _v56 = (1 << 64u8) as u128; + let _v57 = 0u128 >> 128u8; + let _v58 = (0 >> 64u8) as u128; + let _v59 = 1u128 / 0u128; + let _v60 = 1u128 % 0u128; + let _v61 = 340282366920938463463374607431768211450u128 + 340282366920938463463374607431768211450u128; + let _v62 = (18446744073709551615 + 18446744073709551615) as u128; + let _v63 = (18446744073709551615 + 18446744073709551615) as u128; + let _v64 = (18446744073709551615 + 18446744073709551615) as u128; + let _v65 = 0u128 - 1u128; + let _v66 = 340282366920938463463374607431768211456u256 as u128; + let _v67 = 0x1::vector::empty(); + let _v68 = &mut _v67; + 0x1::vector::push_back(_v68, _v55); + 0x1::vector::push_back(_v68, _v56); + 0x1::vector::push_back(_v68, _v57); + 0x1::vector::push_back(_v68, _v58); + 0x1::vector::push_back(_v68, _v59); + 0x1::vector::push_back(_v68, _v60); + 0x1::vector::push_back(_v68, _v61); + 0x1::vector::push_back(_v68, _v62); + 0x1::vector::push_back(_v68, _v63); + 0x1::vector::push_back(_v68, _v64); + 0x1::vector::push_back(_v68, _v65); + 0x1::vector::push_back(_v68, _v66); + let _v69 = _v67; + let _v70 = (1u128 << 128u8) as u256; + let _v71 = (0u128 >> 128u8) as u256; + let _v72 = 1u256 / 0u256; + let _v73 = 1u256 % 0u256; + let _v74 = 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; + let _v75 = (340282366920938463463374607431768211450u128 + 340282366920938463463374607431768211450u128) as u256; + let _v76 = (340282366920938463463374607431768211450u128 + 340282366920938463463374607431768211450u128) as u256; + let _v77 = (340282366920938463463374607431768211450u128 + 340282366920938463463374607431768211450u128) as u256; + let _v78 = 0u256 - 1u256; + let _v79 = 0x1::vector::empty(); + let _v80 = &mut _v79; + 0x1::vector::push_back(_v80, _v70); + 0x1::vector::push_back(_v80, _v71); + 0x1::vector::push_back(_v80, _v72); + 0x1::vector::push_back(_v80, _v73); + 0x1::vector::push_back(_v80, _v74); + 0x1::vector::push_back(_v80, _v75); + 0x1::vector::push_back(_v80, _v76); + 0x1::vector::push_back(_v80, _v77); + 0x1::vector::push_back(_v80, _v78); + let _v81 = _v79; + let _v82 = sum_u8(&_v9); + let _v83 = sum_u16(&_v19); + let _v84 = sum_u32(&_v36); + let _v85 = sum_u64(&_v54); + let _v86 = sum_u128(&_v69); + let _v87 = sum_u256(&_v81); + assert!(_v82 != 0u8, 1); + assert!(_v83 != 0u16, 1); + assert!(_v84 != 0u32, 1); + assert!(_v85 != 0, 1); + assert!(_v86 != 0u128, 1); + assert!(_v87 != 0u256, 1); + } + fun sum_u8(p0: &vector): u8 { + let _v0 = 0u8; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sum_u16(p0: &vector): u16 { + let _v0 = 0u16; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sum_u32(p0: &vector): u32 { + let _v0 = 0u32; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sum_u64(p0: &vector): u64 { + let _v0 = 0; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sum_u128(p0: &vector): u128 { + let _v0 = 0u128; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } + fun sum_u256(p0: &vector): u256 { + let _v0 = 0u256; + let _v1 = 0; + loop { + let _v2 = 0x1::vector::length(p0); + if (!(_v1 < _v2)) break; + let _v3 = *0x1::vector::borrow(p0, _v1); + _v0 = _v0 + _v3; + _v1 = _v1 + 1; + continue + }; + _v0 + } +} + + +//# run 0xcafe::ConstantFailure::main \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled.baseline.exp new file mode 100644 index 00000000000..8b54ae6f524 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_failure.decompiled.baseline.exp @@ -0,0 +1,10 @@ +processed 2 tasks +task 0 lines 3-243: publish [module 0xcafe::ConstantFailure {] +task 1 lines 246-246: run 0xcafe::ConstantFailure::main +Error: Function execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: 0xcafe::ConstantFailure, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled new file mode 100644 index 00000000000..922f3b77aaf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled @@ -0,0 +1,8 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/constant_folding_ristretto.move` + +//# publish +module 0xcafe::Ristretto { + public fun test() { + () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled.baseline.exp new file mode 100644 index 00000000000..6fbb48e2a7f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/constant_folding_ristretto.decompiled.baseline.exp @@ -0,0 +1,2 @@ +processed 1 task +task 0 lines 3-8: publish [module 0xcafe::Ristretto {] diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled new file mode 100644 index 00000000000..0df320ab3a0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled @@ -0,0 +1,22 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/simplifier_test1.move` + +//# publish +module 0x8675::M { + public fun test(): u64 { + test1(10) + } + fun test1(p0: u64): u64 { + let _v0 = p0; + let _v1 = 0; + while (p0 > 0) { + let _v2 = p0; + p0 = p0 - 1; + _v1 = _v1 + _v2; + continue + }; + p0 + _v0 + _v1 + } +} + + +//# run 0x8675::M::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled.baseline.exp new file mode 100644 index 00000000000..701ffc769c4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test1.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-19: publish [module 0x8675::M {] +task 1 lines 22-22: run 0x8675::M::test +return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled new file mode 100644 index 00000000000..8ab174e8eb7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled @@ -0,0 +1,20 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/simplifier_test2.move` + +//# publish +module 0x8675::M { + public fun test(): u64 { + let _v0 = 10; + let _v1 = _v0; + let _v2 = 0; + while (_v0 > 0) { + let _v3 = _v0; + _v0 = _v0 - 1; + _v2 = _v2 + _v3; + continue + }; + _v0 + _v1 + _v2 + } +} + + +//# run 0x8675::M::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled.baseline.exp new file mode 100644 index 00000000000..fb59abceae8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test2.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-17: publish [module 0x8675::M {] +task 1 lines 20-20: run 0x8675::M::test +return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled new file mode 100644 index 00000000000..88db74a0cf3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled @@ -0,0 +1,23 @@ +//**** Cross-compiled for `move` syntax from `tests/simplifier/simplifier_test3.move` + +//# publish +module 0x8675::M { + public fun test(): u64 { + test1(10) + } + fun test1(p0: u64): u64 { + let _v0 = p0; + let _v1 = 0; + loop { + let _v2 = p0; + p0 = p0 - 1; + _v1 = _v1 + _v2; + if (p0 > 0) continue; + break + }; + p0 + _v0 + _v1 + } +} + + +//# run 0x8675::M::test \ No newline at end of file diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled.baseline.exp new file mode 100644 index 00000000000..7080554feb3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/round-trip/simplifier_test3.decompiled.baseline.exp @@ -0,0 +1,4 @@ +processed 2 tasks +task 0 lines 3-20: publish [module 0x8675::M {] +task 1 lines 23-23: run 0x8675::M::test +return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test1.exp index bb00c1ccf72..d01f8abce54 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test1.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 19-19: +task 0 lines 1-17: publish [module 0x8675::M {] +task 1 lines 19-19: run 0x8675::M::test return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test2.exp index bb00c1ccf72..d01f8abce54 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test2.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test2.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 19-19: +task 0 lines 1-17: publish [module 0x8675::M {] +task 1 lines 19-19: run 0x8675::M::test return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test3.exp index bb00c1ccf72..d01f8abce54 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test3.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/simplifier/simplifier_test3.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 19-19: +task 0 lines 1-17: publish [module 0x8675::M {] +task 1 lines 19-19: run 0x8675::M::test return values: 65 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.move b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.move new file mode 100644 index 00000000000..81ef05543eb --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.move @@ -0,0 +1,8 @@ +//# publish --print-bytecode +module 0x66::m { + fun run() { + if (__COMPILE_FOR_TESTING__) abort 1 else abort 2 + } +} + +//#run 0x66::m::run diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-false.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-false.exp new file mode 100644 index 00000000000..f06f777d61e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-false.exp @@ -0,0 +1,24 @@ +processed 2 tasks +task 0 lines 1-6: publish --print-bytecode [module 0x66::m {] + +== BEGIN Bytecode == +// Bytecode version v9 +module 0x66::m +// Function definition at index 0 +fun run() + branch l0 + ld_u64 1 + abort +l0: ld_u64 2 + abort + + +== END Bytecode == +task 1 lines 8-8: run 0x66::m::run +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(2), + location: 0x66::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-true.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-true.exp new file mode 100644 index 00000000000..b31dde99ee8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/testing-constant/compile_for_testing.testing-constant-true.exp @@ -0,0 +1,23 @@ +processed 2 tasks +task 0 lines 1-6: publish --print-bytecode [module 0x66::m {] + +== BEGIN Bytecode == +// Bytecode version v9 +module 0x66::m +// Function definition at index 0 +fun run() + ld_u64 1 + abort + ld_u64 2 + abort + + +== END Bytecode == +task 1 lines 8-8: run 0x66::m::run +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(1), + location: 0x66::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs index 7916c1501db..b3a0c226aa4 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -8,7 +8,9 @@ use itertools::Itertools; use libtest_mimic::{Arguments, Trial}; use move_compiler_v2::{logging, Experiment}; use move_model::metadata::LanguageVersion; -use move_transactional_test_runner::{vm_test_harness, vm_test_harness::TestRunConfig}; +use move_transactional_test_runner::{ + tasks::SyntaxChoice, vm_test_harness, vm_test_harness::TestRunConfig, +}; use std::{ path::{Path, PathBuf}, string::ToString, @@ -27,8 +29,19 @@ struct TestConfig { /// Path substrings for tests to exclude (applied after the include filter). /// If empty, no additional tests are excluded. exclude: &'static [&'static str], + /// Cross compile or not + cross_compile: bool, } +/// Set of exclusions that apply when using `include: &[]` in TestConfig. +const COMMON_EXCLUSIONS: &[&str] = &[ + "/operator_eval/", + "/no-recursive-check/", + "/no-access-check/", + "/no-recursive-type-check/", + "/testing-constant/", +]; + /// Note that any config which has different output for a test directory /// *must* be added to the `SEPARATE_BASELINE` array below, so that a /// special output file `test.foo.exp` will be generated for the output @@ -40,8 +53,9 @@ const TEST_CONFIGS: &[TestConfig] = &[ runner: |p| run(p, get_config_by_name("baseline")), experiments: &[], language_version: LanguageVersion::latest(), - include: &[], - exclude: &["/operator_eval/", "/no-recursive-check/"], + include: &[], // all tests except those excluded below + exclude: COMMON_EXCLUSIONS, + cross_compile: true, }, // Test optimize/no-optimize/etc., except for `/access_control/` TestConfig { @@ -53,7 +67,8 @@ const TEST_CONFIGS: &[TestConfig] = &[ ], language_version: LanguageVersion::latest(), include: &[], // all tests except those excluded below - exclude: &["/operator_eval/", "/no-recursive-check/"], + exclude: COMMON_EXCLUSIONS, + cross_compile: false, }, TestConfig { name: "no-optimize", @@ -61,7 +76,23 @@ const TEST_CONFIGS: &[TestConfig] = &[ experiments: &[(Experiment::OPTIMIZE, false)], language_version: LanguageVersion::latest(), include: &[], // all tests except those excluded below - exclude: &["/operator_eval/", "/no-recursive-check/"], + exclude: COMMON_EXCLUSIONS, + cross_compile: false, + }, + // Test enabling inlining optimization, across package inlining, and extra optimizations. + TestConfig { + name: "opt-extra", + runner: |p| run(p, get_config_by_name("opt-extra")), + experiments: &[ + (Experiment::INLINING_OPTIMIZATION, true), + (Experiment::ACROSS_PACKAGE_INLINING, true), + (Experiment::OPTIMIZE, true), + (Experiment::OPTIMIZE_EXTRA, true), + ], + language_version: LanguageVersion::latest(), + include: &[], // all tests except those excluded below + exclude: COMMON_EXCLUSIONS, + cross_compile: false, }, // Test `/operator_eval/` with language version 1 and 2 TestConfig { @@ -71,6 +102,7 @@ const TEST_CONFIGS: &[TestConfig] = &[ language_version: LanguageVersion::V1, include: &["/operator_eval/"], exclude: &[], + cross_compile: false, }, TestConfig { name: "operator-eval-lang-2", @@ -79,6 +111,7 @@ const TEST_CONFIGS: &[TestConfig] = &[ language_version: LanguageVersion::latest(), include: &["/operator_eval/"], exclude: &[], + cross_compile: true, }, TestConfig { name: "no-recursive-check", @@ -87,6 +120,43 @@ const TEST_CONFIGS: &[TestConfig] = &[ language_version: LanguageVersion::latest(), include: &["/no-recursive-check/"], exclude: &[], + cross_compile: false, + }, + TestConfig { + name: "no-access-check", + runner: |p| run(p, get_config_by_name("no-access-check")), + experiments: &[(Experiment::ACCESS_CHECK, false)], + language_version: LanguageVersion::latest(), + include: &["/no-access-check/"], + exclude: &[], + cross_compile: false, + }, + TestConfig { + name: "no-recursive-type-check", + runner: |p| run(p, get_config_by_name("no-recursive-type-check")), + experiments: &[(Experiment::RECURSIVE_TYPE_CHECK, false)], + language_version: LanguageVersion::latest(), + include: &["/no-recursive-type-check/"], + exclude: &[], + cross_compile: false, + }, + TestConfig { + name: "testing-constant-true", + runner: |p| run(p, get_config_by_name("testing-constant-true")), + experiments: &[(Experiment::COMPILE_FOR_TESTING, true)], + language_version: LanguageVersion::latest(), + include: &["/testing-constant/"], + exclude: &[], + cross_compile: false, + }, + TestConfig { + name: "testing-constant-false", + runner: |p| run(p, get_config_by_name("testing-constant-false")), + experiments: &[(Experiment::COMPILE_FOR_TESTING, false)], + language_version: LanguageVersion::latest(), + include: &["/testing-constant/"], + exclude: &[], + cross_compile: false, }, ]; @@ -121,6 +191,14 @@ const SEPARATE_BASELINE: &[&str] = &[ "optimization/bug_14223_unused_non_droppable.move", // Flaky redundant unused assignment error "no-v1-comparison/enum/enum_scoping.move", + // Different error messages depending on optimizations or not + "no-v1-comparison/fv_as_keys.move", + // needed until bug #17615 is fixed + "misc/bug_14817_extended.move", + // run in verbose mode to unveil the exact error messages + "/signed-int/", + // different expected result + "/testing-constant/", ]; fn get_config_by_name(name: &str) -> TestConfig { @@ -132,7 +210,7 @@ fn get_config_by_name(name: &str) -> TestConfig { } fn run(path: &Path, config: TestConfig) -> datatest_stable::Result<()> { - logging::setup_logging_for_testing(); + logging::setup_logging_for_testing(None); let p = path.to_str().unwrap_or_default(); let exp_suffix = if SEPARATE_BASELINE.iter().any(|s| p.contains(s)) { Some(format!("{}.exp", config.name)) @@ -145,7 +223,19 @@ fn run(path: &Path, config: TestConfig) -> datatest_stable::Result<()> { .map(|(s, v)| (s.to_string(), *v)) .collect_vec(); let language_version = config.language_version; - let vm_test_config = TestRunConfig::compiler_v2(language_version, experiments); + let mut vm_test_config = + TestRunConfig::new(language_version, experiments).with_runtime_ref_checks(); + // For cross compilation, we need to always append the config name as a part of the + // outcome file suffix, as optimizations affect the generated code. + if config.cross_compile { + vm_test_config = vm_test_config.cross_compile_into( + SyntaxChoice::Source, + true, + exp_suffix + .clone() + .or_else(|| Some(format!("{}.exp", config.name))), + ); + } vm_test_harness::run_test_with_config_and_exp_suffix(vm_test_config, path, &exp_suffix) } diff --git a/third_party/move/move-core/types/Cargo.toml b/third_party/move/move-core/types/Cargo.toml index da9c7b9f5f3..175044f1d6d 100644 --- a/third_party/move/move-core/types/Cargo.toml +++ b/third_party/move/move-core/types/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = ["crates-io"] -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } @@ -15,12 +15,11 @@ arbitrary = { workspace = true, features = ["derive_arbitrary"], optional = true bcs = { workspace = true } bytes = { workspace = true } dearbitrary = { workspace = true, optional = true, features = ["derive"] } -ethnum = { workspace = true } +ethnum = { workspace = true, features = ["serde"] } hashbrown = { workspace = true } hex = { workspace = true } num = { workspace = true } once_cell = { workspace = true } -primitive-types = { workspace = true, features = ["impl-serde"] } proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } # Cannot use workspace version as aptos-core currently cannot be upgraded @@ -30,7 +29,6 @@ ref-cast = { workspace = true } serde = { workspace = true } serde_bytes = { workspace = true } thiserror = { workspace = true } -uint = { workspace = true } [dev-dependencies] arbitrary = { workspace = true, features = ["derive_arbitrary"] } diff --git a/third_party/move/move-core/types/src/ability.rs b/third_party/move/move-core/types/src/ability.rs index 1b62ee17e21..7d48aa46cd6 100644 --- a/third_party/move/move-core/types/src/ability.rs +++ b/third_party/move/move-core/types/src/ability.rs @@ -222,13 +222,6 @@ impl AbilitySet { if declared_phantom_parameters.len() != type_arguments.len() { bail!("the length of `declared_phantom_parameters` doesn't match the length of `type_arguments`") - /* - return Err( - PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION).with_message( - "the length of `declared_phantom_parameters` doesn't match the length of `type_arguments`".to_string(), - ), - ); - */ } // Conceptually this is performing the following operation: diff --git a/third_party/move/move-core/types/src/account_address.rs b/third_party/move/move-core/types/src/account_address.rs index 40336f1dcfa..6d06781dc95 100644 --- a/third_party/move/move-core/types/src/account_address.rs +++ b/third_party/move/move-core/types/src/account_address.rs @@ -79,7 +79,7 @@ impl AccountAddress { pub fn random() -> Self { let mut rng = OsRng; - let buf: [u8; Self::LENGTH] = rng.gen(); + let buf: [u8; Self::LENGTH] = rng.r#gen(); Self(buf) } @@ -116,6 +116,7 @@ impl AccountAddress { /// /// For more details see the v1 address standard defined as part of AIP-40: /// + #[inline(always)] pub fn is_special(&self) -> bool { self.0[..Self::LENGTH - 1].iter().all(|x| *x == 0) && self.0[Self::LENGTH - 1] < 0b10000 } diff --git a/third_party/move/move-core/types/src/function.rs b/third_party/move/move-core/types/src/function.rs index fd01ef4ec66..432e37c4bd4 100644 --- a/third_party/move/move-core/types/src/function.rs +++ b/third_party/move/move-core/types/src/function.rs @@ -51,12 +51,12 @@ impl ClosureMask { Self(mask) } - pub fn new_for_leading(n: usize) -> Self { + pub fn new_for_leading(n: usize) -> Result { let mut mask = Self::new(0); for i in 0..n { - mask.set_captured(i) + mask.set_captured(i)?; } - mask + Ok(mask) } pub fn bits(&self) -> u64 { @@ -65,14 +65,22 @@ impl ClosureMask { /// Returns true if the i'th argument is captured. If `i` is out of range, false will /// be returned. + #[inline(always)] pub fn is_captured(&self, i: usize) -> bool { i < Self::MAX_ARGS && self.0 & (1 << i) != 0 } /// Sets the ith argument to be captured - pub fn set_captured(&mut self, i: usize) { - assert!(i < Self::MAX_ARGS); - self.0 |= 1 << i + pub fn set_captured(&mut self, i: usize) -> Result<(), String> { + if i >= Self::MAX_ARGS { + return Err(format!( + "Captured argument index {} exceeds maximum allowed captured arguments {}", + i, + Self::MAX_ARGS + )); + } + self.0 |= 1 << i; + Ok(()) } /// Apply a closure mask to a list of elements, returning only those diff --git a/third_party/move/move-core/types/src/gas_algebra.rs b/third_party/move/move-core/types/src/gas_algebra.rs index 5a2cb0cc890..01192325a99 100644 --- a/third_party/move/move-core/types/src/gas_algebra.rs +++ b/third_party/move/move-core/types/src/gas_algebra.rs @@ -270,7 +270,7 @@ fn apply_ratio_round_up(val: u64, nominator: u64, denominator: u64) -> u64 { let n = val as u128 * nominator as u128; let d = denominator as u128; - let res = n / d + if n % d == 0 { 0 } else { 1 }; + let res = n / d + if n.is_multiple_of(d) { 0 } else { 1 }; if res > u64::MAX as u128 { u64::MAX } else { diff --git a/third_party/move/move-core/types/src/identifier.rs b/third_party/move/move-core/types/src/identifier.rs index 3fdf0ed944a..a05add2447c 100644 --- a/third_party/move/move-core/types/src/identifier.rs +++ b/third_party/move/move-core/types/src/identifier.rs @@ -6,10 +6,13 @@ //! //! A valid identifier consists of an ASCII string which satisfies any of the conditions: //! -//! * The first character is a letter and the remaining characters are letters, digits or -//! underscores. -//! * The first character is an underscore, and there is at least one further letter, digit or -//! underscore. +//! * The first character is a letter and the remaining characters are letters, digits, +//! underscores, or dollar. +//! * The first character is an underscore or dollar, and there is at least one further letter, +//! digit, underscore, or dollar. +//! +//! Notice that dollar (`$`) is reserved for compiler or runtime intrinsic identifiers +//! and cannot be reached from the Move language. //! //! The spec for allowed identifiers is similar to Rust's spec //! ([as of version 1.38](https://doc.rust-lang.org/1.38.0/reference/identifiers.html)). @@ -40,7 +43,7 @@ use std::{borrow::Borrow, fmt, ops::Deref, str::FromStr}; /// identifier--only alphabetic characters are allowed here. #[inline] pub const fn is_valid_identifier_char(c: char) -> bool { - matches!(c, '_' | 'a'..='z' | 'A'..='Z' | '0'..='9') + matches!(c, '_' | '$' | 'a'..='z' | 'A'..='Z' | '0'..='9') } /// Returns `true` if all bytes in `b` after the offset `start_offset` are valid @@ -85,7 +88,7 @@ pub const fn is_valid(s: &str) -> bool { b"" => true, [b'<', b'S', b'E', b'L', b'F', b'>', b'_', ..] if b.len() > 7 => all_bytes_numeric(b, 7), [b'a'..=b'z', ..] | [b'A'..=b'Z', ..] => all_bytes_valid(b, 1), - [b'_', ..] if b.len() > 1 => all_bytes_valid(b, 1), + [b'_', ..] | [b'$', ..] if b.len() > 1 => all_bytes_valid(b, 1), _ => false, } } @@ -96,10 +99,10 @@ pub const fn is_valid(s: &str) -> bool { #[cfg(any(test, feature = "fuzzing"))] #[allow(dead_code)] pub(crate) static ALLOWED_IDENTIFIERS: &str = - r"(?:[a-zA-Z][a-zA-Z0-9_]*)|(?:_[a-zA-Z0-9_]+)|(?:)|(?:_[0-9]+)"; + r"(?:[a-zA-Z][a-zA-Z0-9_$]*)|(?:_[a-zA-Z0-9_$]+)|(?:)|(?:_[0-9]+)"; #[cfg(any(test, feature = "fuzzing"))] pub(crate) static ALLOWED_NO_SELF_IDENTIFIERS: &str = - r"(?:[a-zA-Z][a-zA-Z0-9_]*)|(?:_[a-zA-Z0-9_]+)"; + r"(?:[a-zA-Z][a-zA-Z0-9_$]*)|(?:_[a-zA-Z0-9_$]+)"; /// An owned identifier. /// @@ -123,6 +126,14 @@ impl Identifier { } } + /// Creates an unchecked `Identifier` instance, allowing characters which + /// are invalid. This is, for example, used by move-asm + /// to create invalid identifiers which are expected to be caught by + /// validation. + pub fn new_unchecked(s: impl Into>) -> Self { + Self(s.into()) + } + /// Returns true if this string is a valid identifier. pub fn is_valid(s: impl AsRef) -> bool { is_valid(s.as_ref()) diff --git a/third_party/move/move-core/types/src/int256.rs b/third_party/move/move-core/types/src/int256.rs new file mode 100644 index 00000000000..9d2f222fe38 --- /dev/null +++ b/third_party/move/move-core/types/src/int256.rs @@ -0,0 +1,444 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Implemented of unsigned and signed 256 bit integers. +//! +//! This uses the `ethnum` crate for the underlying representation. This is one of the +//! most downloaded 256 bit implementation for Rust, and has full integration of both +//! signed and unsigned integers with the standard Rust int types. This module is +//! merely a wrapper around the provided types. + +use num::{bigint::Sign, BigInt}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + ops::{BitAnd, BitOr, BitXor, Neg, Shl, Shr}, + str::FromStr, +}; + +// ---- U256 Representation + +#[derive(Clone, Copy, Default, Hash, PartialOrd, PartialEq, Ord, Eq)] +pub struct U256 { + repr: ethnum::U256, +} + +impl U256 { + pub const MAX: U256 = U256 { + repr: ethnum::U256::MAX, + }; + pub const MIN: U256 = U256 { + repr: ethnum::U256::MIN, + }; + pub const ONE: U256 = U256 { + repr: ethnum::U256::ONE, + }; + pub const ZERO: U256 = U256 { + repr: ethnum::U256::ZERO, + }; + + #[inline(always)] + pub fn repr(self) -> ethnum::U256 { + self.repr + } + + #[inline(always)] + pub fn from_le_bytes(bytes: [u8; 32]) -> Self { + Self { + repr: ethnum::U256::from_le_bytes(bytes), + } + } + + #[inline(always)] + pub fn to_le_bytes(self) -> [u8; 32] { + self.repr.to_le_bytes() + } +} + +impl From for U256 { + #[inline(always)] + fn from(repr: ethnum::U256) -> Self { + Self { repr } + } +} + +impl From for ethnum::U256 { + #[inline(always)] + fn from(value: U256) -> Self { + value.repr + } +} + +impl From for BigInt { + fn from(value: U256) -> Self { + BigInt::from_bytes_le(Sign::Plus, &value.to_le_bytes()) + } +} + +impl std::fmt::Debug for U256 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "U256({})", self.repr) + } +} + +// ---- I256 Representation + +#[derive(Clone, Copy, Default, Hash, PartialOrd, PartialEq, Ord, Eq)] +pub struct I256 { + repr: ethnum::I256, +} + +impl I256 { + pub const MAX: I256 = I256 { + repr: ethnum::I256::MAX, + }; + pub const MIN: I256 = I256 { + repr: ethnum::I256::MIN, + }; + pub const ONE: I256 = I256 { + repr: ethnum::I256::ONE, + }; + pub const ZERO: I256 = I256 { + repr: ethnum::I256::ZERO, + }; + + #[inline(always)] + pub fn repr(self) -> ethnum::I256 { + self.repr + } + + #[inline(always)] + pub fn from_le_bytes(bytes: [u8; 32]) -> Self { + Self { + repr: ethnum::I256::from_le_bytes(bytes), + } + } + + #[inline(always)] + pub fn to_le_bytes(self) -> [u8; 32] { + self.repr.to_le_bytes() + } +} + +impl From for I256 { + #[inline(always)] + fn from(repr: ethnum::I256) -> Self { + Self { repr } + } +} + +impl From for ethnum::I256 { + #[inline(always)] + fn from(value: I256) -> Self { + value.repr + } +} + +impl From for BigInt { + fn from(value: I256) -> Self { + BigInt::from_signed_bytes_le(&value.to_le_bytes()) + } +} + +impl std::fmt::Debug for I256 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "I256({})", self.repr) + } +} + +// ---- Serialization + +macro_rules! serde_serializer { + ($wrapper:ty) => { + impl Serialize for $wrapper { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.to_le_bytes().serialize(serializer) + } + } + + impl<'de> Deserialize<'de> for $wrapper { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + Ok(<$wrapper>::from_le_bytes( + (<[u8; 32]>::deserialize(deserializer)?), + )) + } + } + }; +} + +serde_serializer!(U256); +serde_serializer!(I256); + +// ---- Fuzzing + +#[cfg(any(test, feature = "fuzzing"))] +mod arbitrary_impl { + use super::*; + use arbitrary::{Arbitrary, Result as AResult, Unstructured}; + use dearbitrary::{Dearbitrary, Dearbitrator}; + + impl<'a> Arbitrary<'a> for U256 { + fn arbitrary(u: &mut Unstructured<'a>) -> AResult { + let bytes: [u8; 32] = <[u8; 32]>::arbitrary(u)?; + Ok(U256::from_le_bytes(bytes)) + } + } + + impl<'a> Arbitrary<'a> for I256 { + fn arbitrary(u: &mut Unstructured<'a>) -> AResult { + let bytes: [u8; 32] = <[u8; 32]>::arbitrary(u)?; + Ok(I256::from_le_bytes(bytes)) + } + } + + impl Dearbitrary for U256 { + fn dearbitrary(&self, dearbitrator: &mut Dearbitrator) { + dearbitrator.push_bytes(&self.to_le_bytes()); + } + } + + impl Dearbitrary for I256 { + fn dearbitrary(&self, dearbitrator: &mut Dearbitrator) { + dearbitrator.push_bytes(&self.to_le_bytes()); + } + } +} + +// ---- Proptest + +#[cfg(any(test, feature = "fuzzing"))] +mod proptest_impl { + use super::*; + use proptest::prelude::*; + impl Arbitrary for U256 { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + any::<[u8; 32]>().prop_map(U256::from_le_bytes).boxed() + } + } + + impl Arbitrary for I256 { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + any::<[u8; 32]>().prop_map(I256::from_le_bytes).boxed() + } + } +} + +// ---- String Representation + +macro_rules! string_repr { + ($wrapper:ty, $repr:ty) => { + impl $wrapper { + pub fn from_str_radix(s: &str, radix: u32) -> anyhow::Result { + Ok(<$repr>::from_str_radix(s, radix)?.into()) + } + } + + impl std::fmt::Display for $wrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.repr) + } + } + + impl FromStr for $wrapper { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Self::from_str_radix(s, 10) + } + } + }; +} + +string_repr!(U256, ethnum::U256); +string_repr!(I256, ethnum::I256); + +// ---- Arithmetics + +macro_rules! arithmetics { + ($wrapper:ty, $repr:ty) => { + impl $wrapper { + pub fn checked_add(l: $wrapper, r: $wrapper) -> Option<$wrapper> { + <$repr>::checked_add(l.repr, r.repr).map(|r| r.into()) + } + + pub fn checked_sub(l: $wrapper, r: $wrapper) -> Option<$wrapper> { + <$repr>::checked_sub(l.repr, r.repr).map(|r| r.into()) + } + + pub fn checked_mul(l: $wrapper, r: $wrapper) -> Option<$wrapper> { + <$repr>::checked_mul(l.repr, r.repr).map(|r| r.into()) + } + + pub fn checked_div(l: $wrapper, r: $wrapper) -> Option<$wrapper> { + <$repr>::checked_div(l.repr, r.repr).map(|r| r.into()) + } + + pub fn checked_rem(l: $wrapper, r: $wrapper) -> Option<$wrapper> { + <$repr>::checked_rem(l.repr, r.repr).map(|r| r.into()) + } + } + }; +} + +macro_rules! bitops { + ($wrapper:ty, $repr:ty) => { + impl BitAnd for $wrapper { + type Output = $wrapper; + + fn bitand(self, rhs: Self) -> Self::Output { + (self.repr & rhs.repr).into() + } + } + + impl BitOr for $wrapper { + type Output = $wrapper; + + fn bitor(self, rhs: Self) -> Self::Output { + (self.repr | rhs.repr).into() + } + } + + impl BitXor for $wrapper { + type Output = $wrapper; + + fn bitxor(self, rhs: Self) -> Self::Output { + (self.repr ^ rhs.repr).into() + } + } + + impl Shl for $wrapper { + type Output = $wrapper; + + fn shl(self, rhs: Self) -> Self::Output { + (self.repr << rhs.repr).into() + } + } + + impl Shr for $wrapper { + type Output = $wrapper; + + fn shr(self, rhs: Self) -> Self::Output { + (self.repr >> rhs.repr).into() + } + } + }; +} + +arithmetics!(U256, ethnum::U256); +bitops!(U256, ethnum::U256); +arithmetics!(I256, ethnum::I256); + +impl Neg for I256 { + type Output = I256; + + fn neg(self) -> Self::Output { + I256 { repr: -self.repr } + } +} + +impl I256 { + pub fn checked_neg(self) -> Option { + self.repr.checked_neg().map(|x| x.into()) + } +} + +// ---- Conversions +// Semantics: conversions are fallible if the target type cannot represent the full range of the source type. + +// Conversions between wrapper types and primitive types where both directions are fallible. +macro_rules! conversions { + ($wrapper:ty, $repr:ty, $target:ty) => { + impl TryFrom<$wrapper> for $target { + type Error = anyhow::Error; + + #[inline(always)] + fn try_from(value: $wrapper) -> Result { + Ok(value.repr.try_into()?) + } + } + + impl TryFrom<$target> for $wrapper { + type Error = anyhow::Error; + + #[inline(always)] + fn try_from(value: $target) -> Result { + let result: $repr = value.try_into()?; + Ok(result.into()) + } + } + }; +} + +// Conversions where wrapper to primitive is fallible, but primitive to wrapper is infallible. +macro_rules! conversions_infallible { + ($wrapper:ty, $repr:ty, $target:ty) => { + impl TryFrom<$wrapper> for $target { + type Error = anyhow::Error; + + #[inline(always)] + fn try_from(value: $wrapper) -> Result { + Ok(value.repr.try_into()?) + } + } + + impl From<$target> for $wrapper { + fn from(value: $target) -> Self { + let result: $repr = value.try_into().expect("conversion succeeds"); + result.into() + } + } + }; +} + +conversions_infallible!(U256, ethnum::U256, u8); +conversions_infallible!(U256, ethnum::U256, u16); +conversions_infallible!(U256, ethnum::U256, u32); +conversions_infallible!(U256, ethnum::U256, u64); +conversions_infallible!(U256, ethnum::U256, u128); +conversions!(U256, ethnum::U256, i8); +conversions!(U256, ethnum::U256, i16); +conversions!(U256, ethnum::U256, i32); +conversions!(U256, ethnum::U256, i64); +conversions!(U256, ethnum::U256, i128); + +conversions_infallible!(I256, ethnum::I256, u8); +conversions_infallible!(I256, ethnum::I256, u16); +conversions_infallible!(I256, ethnum::I256, u32); +conversions_infallible!(I256, ethnum::I256, u64); +conversions_infallible!(I256, ethnum::I256, u128); +conversions_infallible!(I256, ethnum::I256, i8); +conversions_infallible!(I256, ethnum::I256, i16); +conversions_infallible!(I256, ethnum::I256, i32); +conversions_infallible!(I256, ethnum::I256, i64); +conversions_infallible!(I256, ethnum::I256, i128); + +// Conversion between those types is not the same as back and forth between primitives, +// therefore explicit trait impls. +impl TryFrom for U256 { + type Error = anyhow::Error; + + fn try_from(value: I256) -> Result { + let repr: ethnum::U256 = value.repr.try_into()?; + Ok(U256 { repr }) + } +} + +impl TryFrom for I256 { + type Error = anyhow::Error; + + fn try_from(value: U256) -> Result { + let repr: ethnum::I256 = value.repr.try_into()?; + Ok(I256 { repr }) + } +} diff --git a/third_party/move/move-core/types/src/language_storage.rs b/third_party/move/move-core/types/src/language_storage.rs index 6abdb24bc1c..95029c85258 100644 --- a/third_party/move/move-core/types/src/language_storage.rs +++ b/third_party/move/move-core/types/src/language_storage.rs @@ -5,7 +5,9 @@ use crate::{ ability::AbilitySet, account_address::AccountAddress, + ident_str, identifier::{IdentStr, Identifier}, + language_storage::FunctionParamOrReturnTag::{MutableReference, Reference, Value}, parser::{parse_module_id, parse_struct_tag, parse_type_tag}, safe_serialize, }; @@ -26,6 +28,29 @@ pub const RESOURCE_TAG: u8 = 1; pub const CORE_CODE_ADDRESS: AccountAddress = AccountAddress::ONE; pub const TOKEN_ADDRESS: AccountAddress = AccountAddress::THREE; pub const TOKEN_OBJECTS_ADDRESS: AccountAddress = AccountAddress::FOUR; +pub const EXPERIMENTAL_CODE_ADDRESS: AccountAddress = AccountAddress::SEVEN; + +pub const OPTION_NONE_TAG: u16 = 0; +pub const OPTION_SOME_TAG: u16 = 1; +// field "vec" of the old representation of option +pub const LEGACY_OPTION_VEC: &str = "vec"; +pub const OPTION_MODULE_NAME_STR: &str = "option"; +pub const OPTION_STRUCT_NAME_STR: &str = "Option"; + +pub static OPTION_MODULE_ID: Lazy = Lazy::new(|| { + ModuleId::new( + AccountAddress::ONE, + Identifier::from(ident_str!(OPTION_MODULE_NAME_STR)), + ) +}); +pub static OPTION_STRUCT_NAME: Lazy = + Lazy::new(|| Identifier::from(ident_str!(OPTION_STRUCT_NAME_STR))); +pub static MEM_MODULE_ID: Lazy = + Lazy::new(|| ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("mem")))); +pub static TABLE_MODULE_ID: Lazy = + Lazy::new(|| ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("table")))); +pub static TABLE_STRUCT_NAME: Lazy = + Lazy::new(|| Identifier::from(ident_str!("Table"))); #[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] #[cfg_attr( @@ -79,6 +104,20 @@ pub enum TypeTag { )] Box, ), + + // NOTED: added in bytecode version v9 + #[serde(rename = "i8", alias = "I8")] + I8, + #[serde(rename = "i16", alias = "I16")] + I16, + #[serde(rename = "i32", alias = "I32")] + I32, + #[serde(rename = "i64", alias = "I64")] + I64, + #[serde(rename = "i128", alias = "I128")] + I128, + #[serde(rename = "i256", alias = "I256")] + I256, } impl TypeTag { @@ -96,6 +135,12 @@ impl TypeTag { U64 => "u64".to_owned(), U128 => "u128".to_owned(), U256 => "u256".to_owned(), + I8 => "i8".to_owned(), + I16 => "i16".to_owned(), + I32 => "i32".to_owned(), + I64 => "i64".to_owned(), + I128 => "i128".to_owned(), + I256 => "i256".to_owned(), Address => "address".to_owned(), Signer => "signer".to_owned(), Vector(t) => format!("vector<{}>", t.to_canonical_string()), @@ -108,8 +153,8 @@ impl TypeTag { use TypeTag::*; match self { Struct(struct_tag) => Some(struct_tag.as_ref()), - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer | Vector(_) - | Function(_) => None, + Bool | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Address | Signer | Vector(_) | Function(_) => None, } } @@ -131,13 +176,19 @@ impl<'a> Iterator for TypeTagPreorderTraversalIter<'a> { match self.stack.pop() { Some(ty) => { match ty { - Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 => (), + Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 + | I32 | I64 | I128 | I256 => (), Vector(ty) => self.stack.push(ty), Struct(struct_tag) => self.stack.extend(struct_tag.type_args.iter().rev()), Function(fun_tag) => { let FunctionTag { args, results, .. } = fun_tag.as_ref(); - self.stack - .extend(results.iter().rev().chain(args.iter().rev())) + self.stack.extend( + results + .iter() + .map(|t| t.inner_tag()) + .rev() + .chain(args.iter().map(|t| t.inner_tag()).rev()), + ) }, } Some(ty) @@ -198,8 +249,8 @@ impl StructTag { /// standard library at address `move_std_addr`. pub fn is_std_option(&self, move_std_addr: &AccountAddress) -> bool { self.address == *move_std_addr - && self.module.as_str().eq("option") - && self.name.as_str().eq("Option") + && self.module.as_str().eq(OPTION_MODULE_NAME_STR) + && self.name.as_str().eq(OPTION_STRUCT_NAME_STR) } pub fn module_id(&self) -> ModuleId { @@ -238,6 +289,12 @@ impl StructTag { generics ) } + + /// Returns true if this is a `StructTag` for an `Option` struct defined in the + /// standard library at address `0x1`. + pub fn is_option(&self) -> bool { + self.is_std_option(OPTION_MODULE_ID.address()) + } } impl FromStr for StructTag { @@ -256,8 +313,8 @@ impl FromStr for StructTag { #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] #[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] pub struct FunctionTag { - pub args: Vec, - pub results: Vec, + pub args: Vec, + pub results: Vec, pub abilities: AbilitySet, } @@ -266,7 +323,7 @@ impl FunctionTag { /// /// INVARIANT: If two function tags are different, they must have different canonical strings. pub fn to_canonical_string(&self) -> String { - let fmt_list = |l: &[TypeTag]| -> String { + let fmt_list = |l: &[FunctionParamOrReturnTag]| -> String { l.iter() .map(|t| t.to_canonical_string()) .collect::>() @@ -289,6 +346,42 @@ impl FunctionTag { } } +/// Represents an argument or return tag for [FunctionTag]. This is needed because function tags +/// carry information about return and argument types which can be references. So direct return +/// or paramter tags can be references, but not the inner tags. +#[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +#[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] +pub enum FunctionParamOrReturnTag { + Reference(TypeTag), + MutableReference(TypeTag), + Value(TypeTag), +} + +impl FunctionParamOrReturnTag { + /// Returns a canonical string representation of function tag's argument or return tag. If any + /// two tags are different, their canonical representation must be also different. + pub fn to_canonical_string(&self) -> String { + use FunctionParamOrReturnTag::*; + match self { + Reference(tag) => format!("&{}", tag.to_canonical_string()), + MutableReference(tag) => format!("&mut {}", tag.to_canonical_string()), + Value(tag) => tag.to_canonical_string(), + } + } + + /// Returns the inner tag for this argument or return tag. + pub fn inner_tag(&self) -> &TypeTag { + match self { + Reference(tag) | MutableReference(tag) | Value(tag) => tag, + } + } +} + /// Represents the initial key into global storage where we first index by the address, and then /// the struct tag. The struct fields are public to support pattern matching. #[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] @@ -310,11 +403,16 @@ impl From for (AccountAddress, Identifier) { } static SCRIPT_MODULE_ID: Lazy = Lazy::new(|| ModuleId { + // [TODO #17369]: Replace `AccountAddress::MAX_ADDRESS` with the value below for `address` + // Currently, this is blocked by performance benchmarking in CI + /* address: AccountAddress::from_str_strict( - // This is generated using sha256sum on 10k of bytes from /dev/urandom - "0x8bd18359a7ebb84407b6defa7bc5da9aca34a3d1ce764ddfb4d0adcc663430b4", + // This is generated using sha256sum on 10k of bytes from /dev/urandom + "0x8bd18359a7ebb84407b6defa7bc5da9aca34a3d1ce764ddfb4d0adcc663430b4", ) .expect("parsing of script address constant"), + */ + address: AccountAddress::MAX_ADDRESS, name: Identifier::new("__script__").expect("valid identifier for script"), }); @@ -354,6 +452,11 @@ impl ModuleId { pub fn as_refs(&self) -> (&AccountAddress, &IdentStr) { (&self.address, self.name.as_ident_str()) } + + pub fn is_option(&self) -> bool { + self.address == *OPTION_MODULE_ID.address() + && self.name.as_ident_str() == OPTION_MODULE_ID.name() + } } impl<'a> hashbrown::Equivalent<(&'a AccountAddress, &'a IdentStr)> for ModuleId { @@ -422,8 +525,8 @@ mod tests { } fn make_function_tag( - args: Vec, - results: Vec, + args: Vec, + results: Vec, abilities: AbilitySet, ) -> TypeTag { TypeTag::Function(Box::new(FunctionTag { @@ -435,6 +538,7 @@ mod tests { #[test] fn test_to_canonical_string() { + use FunctionParamOrReturnTag::*; use TypeTag::*; let data = [ @@ -466,25 +570,33 @@ mod tests { ), (make_function_tag(vec![], vec![], AbilitySet::EMPTY), "||()"), ( - make_function_tag(vec![], vec![U8, U64], AbilitySet::EMPTY), - "||(u8, u64)", + make_function_tag( + vec![], + vec![MutableReference(U8), Value(U64)], + AbilitySet::EMPTY, + ), + "||(&mut u8, u64)", ), ( - make_function_tag(vec![U8, U64], vec![], AbilitySet::EMPTY), - "|u8, u64|()", + make_function_tag(vec![Reference(U8), Value(U64)], vec![], AbilitySet::EMPTY), + "|&u8, u64|()", ), ( make_struct_tag(AccountAddress::ONE, "a", "A", vec![make_function_tag( - vec![make_function_tag( - vec![make_function_tag( + vec![Value(make_function_tag( + vec![Value(make_function_tag( vec![], vec![], AbilitySet::singleton(Ability::Copy), - )], + ))], vec![], AbilitySet::EMPTY, - )], - vec![make_function_tag(vec![], vec![], AbilitySet::ALL)], + ))], + vec![FunctionParamOrReturnTag::Value(make_function_tag( + vec![], + vec![], + AbilitySet::ALL, + ))], AbilitySet::EMPTY, )]), "0x1::a::A<||||() has copy|()|(||() has copy + drop + store + key)>", diff --git a/third_party/move/move-core/types/src/lib.rs b/third_party/move/move-core/types/src/lib.rs index c6cad8c3772..8cac3e02ad0 100644 --- a/third_party/move/move-core/types/src/lib.rs +++ b/third_party/move/move-core/types/src/lib.rs @@ -12,6 +12,7 @@ pub mod errmap; pub mod function; pub mod gas_algebra; pub mod identifier; +pub mod int256; pub mod language_storage; pub mod metadata; pub mod move_resource; @@ -21,7 +22,6 @@ pub mod proptest_types; mod safe_serialize; pub mod state; pub mod transaction_argument; -pub mod u256; #[cfg(test)] mod unit_tests; pub mod value; diff --git a/third_party/move/move-core/types/src/parser.rs b/third_party/move/move-core/types/src/parser.rs index 5a66e4a62e4..5c9ffff3979 100644 --- a/third_party/move/move-core/types/src/parser.rs +++ b/third_party/move/move-core/types/src/parser.rs @@ -422,9 +422,9 @@ pub fn parse_struct_tag(s: &str) -> Result { mod tests { use crate::{ account_address::AccountAddress, + int256, parser::{parse_struct_tag, parse_transaction_argument, parse_type_tag}, transaction_argument::TransactionArgument, - u256, }; use std::str::FromStr; @@ -462,22 +462,22 @@ mod tests { ("01239498u32", T::U32(1239498)), ("35366u32", T::U32(35366)), ("4294967295u32", T::U32(4294967295)), - ("0u256", T::U256(u256::U256::from(0u8))), + ("0u256", T::U256(int256::U256::ZERO)), ("1_0u16", T::U16(1_0)), ("10_u16", T::U16(10)), ("10___u16", T::U16(10)), ("1_000u32", T::U32(1_000)), ("1_0_00u32", T::U32(1_000)), ("1_0_0_0u32", T::U32(1_000)), - ("1_000_000u256", T::U256(u256::U256::from(1_000_000u64))), + ("1_000_000u256", T::U256(int256::U256::from(1_000_000u64))), ( "1_000_000_000u256", - T::U256(u256::U256::from(1_000_000_000u128)), + T::U256(int256::U256::from(1_000_000_000u128)), ), ( "3402823669209384634633746074317682114551234u256", T::U256( - u256::U256::from_str("3402823669209384634633746074317682114551234").unwrap(), + int256::U256::from_str("3402823669209384634633746074317682114551234").unwrap(), ), ), ("true", T::Bool(true)), diff --git a/third_party/move/move-core/types/src/transaction_argument.rs b/third_party/move/move-core/types/src/transaction_argument.rs index da85bc7ccab..5c98d333044 100644 --- a/third_party/move/move-core/types/src/transaction_argument.rs +++ b/third_party/move/move-core/types/src/transaction_argument.rs @@ -2,7 +2,7 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{account_address::AccountAddress, u256, value::MoveValue}; +use crate::{account_address::AccountAddress, int256, value::MoveValue}; use anyhow::{anyhow, Error, Result}; use serde::{Deserialize, Serialize}; use std::{convert::TryFrom, fmt}; @@ -18,9 +18,16 @@ pub enum TransactionArgument { // NOTE: Added in bytecode version v6, do not reorder! U16(u16), U32(u32), - U256(u256::U256), + U256(int256::U256), // Note: Gated by feature flag ALLOW_SERIALIZED_SCRIPT_ARGS Serialized(#[serde(with = "serde_bytes")] Vec), + // NOTE: Added in bytecode version v9, do not reorder! + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + I256(int256::I256), } impl fmt::Debug for TransactionArgument { @@ -40,6 +47,12 @@ impl fmt::Debug for TransactionArgument { TransactionArgument::Serialized(value) => { write!(f, "{{RAW_BYTES: {}}}", hex::encode(value)) }, + TransactionArgument::I8(value) => write!(f, "{{I8: {}}}", value), + TransactionArgument::I16(value) => write!(f, "{{I16: {}}}", value), + TransactionArgument::I32(value) => write!(f, "{{I32: {}}}", value), + TransactionArgument::I64(value) => write!(f, "{{I64: {}}}", value), + TransactionArgument::I128(value) => write!(f, "{{I128: {}}}", value), + TransactionArgument::I256(value) => write!(f, "{{I256: {}}}", value), } } } @@ -57,6 +70,12 @@ impl From for MoveValue { TransactionArgument::U32(i) => MoveValue::U32(i), TransactionArgument::U256(i) => MoveValue::U256(i), TransactionArgument::Serialized(value) => MoveValue::vector_u8(value), + TransactionArgument::I8(i) => MoveValue::I8(i), + TransactionArgument::I16(i) => MoveValue::I16(i), + TransactionArgument::I32(i) => MoveValue::I32(i), + TransactionArgument::I64(i) => MoveValue::I64(i), + TransactionArgument::I128(i) => MoveValue::I128(i), + TransactionArgument::I256(i) => MoveValue::I256(i), } } } @@ -88,6 +107,12 @@ impl TryFrom for TransactionArgument { MoveValue::U16(i) => TransactionArgument::U16(i), MoveValue::U32(i) => TransactionArgument::U32(i), MoveValue::U256(i) => TransactionArgument::U256(i), + MoveValue::I8(i) => TransactionArgument::I8(i), + MoveValue::I16(i) => TransactionArgument::I16(i), + MoveValue::I32(i) => TransactionArgument::I32(i), + MoveValue::I64(i) => TransactionArgument::I64(i), + MoveValue::I128(i) => TransactionArgument::I128(i), + MoveValue::I256(i) => TransactionArgument::I256(i), }) } } @@ -132,7 +157,9 @@ impl VecBytes { #[cfg(test)] mod tests { use crate::{ - account_address::AccountAddress, transaction_argument::TransactionArgument, u256::U256, + account_address::AccountAddress, + int256::{I256, U256}, + transaction_argument::TransactionArgument, value::MoveValue, }; use std::convert::{From, TryInto}; @@ -145,7 +172,13 @@ mod tests { TransactionArgument::U32(u32::MAX), TransactionArgument::U64(u64::MAX), TransactionArgument::U128(u128::MAX), - TransactionArgument::U256(U256::max_value()), + TransactionArgument::U256(U256::MAX), + TransactionArgument::I8(-1), + TransactionArgument::I16(i16::MIN), + TransactionArgument::I32(i32::MIN), + TransactionArgument::I64(i64::MIN), + TransactionArgument::I128(i128::MIN), + TransactionArgument::I256(I256::MIN), TransactionArgument::Bool(true), TransactionArgument::Address(AccountAddress::from_hex_literal("0x1").unwrap()), TransactionArgument::U8Vector(vec![1, 2, 3, 4]), diff --git a/third_party/move/move-core/types/src/u256.rs b/third_party/move/move-core/types/src/u256.rs deleted file mode 100644 index 763a59f9e30..00000000000 --- a/third_party/move/move-core/types/src/u256.rs +++ /dev/null @@ -1,730 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -#![allow(unexpected_cfgs)] - -use ethnum::U256 as EthnumU256; -use num::{bigint::Sign, BigInt}; -// This U256 impl was chosen for now but we are open to changing it as needed -use primitive_types::U256 as PrimitiveU256; -#[cfg(any(test, feature = "fuzzing"))] -use proptest::strategy::BoxedStrategy; -use rand::{ - distributions::{ - uniform::{SampleUniform, UniformSampler}, - Distribution, Standard, - }, - Rng, -}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::{ - fmt, - mem::size_of, - ops::{ - Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitXor, Div, DivAssign, Mul, MulAssign, Rem, - RemAssign, Shl, Shr, Sub, SubAssign, - }, -}; -use uint::FromStrRadixErr; - -const NUM_BITS_PER_BYTE: usize = 8; -const U256_NUM_BITS: usize = 256; -pub const U256_NUM_BYTES: usize = U256_NUM_BITS / NUM_BITS_PER_BYTE; - -#[derive(Debug)] -pub struct U256FromStrError(FromStrRadixErr); - -/// A list of error categories encountered when parsing numbers. -#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] -pub enum U256CastErrorKind { - /// Value too large to fit in U8. - TooLargeForU8, - - /// Value too large to fit in U16. - TooLargeForU16, - - /// Value too large to fit in U32. - TooLargeForU32, - - /// Value too large to fit in U64. - TooLargeForU64, - - /// Value too large to fit in U128. - TooLargeForU128, -} - -#[derive(Debug)] -pub struct U256CastError { - kind: U256CastErrorKind, - val: U256, -} - -impl U256CastError { - pub fn new>(val: T, kind: U256CastErrorKind) -> Self { - Self { - kind, - val: val.into(), - } - } -} - -impl std::error::Error for U256CastError {} - -impl fmt::Display for U256CastError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_str = match self.kind { - U256CastErrorKind::TooLargeForU8 => "u8", - U256CastErrorKind::TooLargeForU16 => "u16", - U256CastErrorKind::TooLargeForU32 => "u32", - U256CastErrorKind::TooLargeForU64 => "u64", - U256CastErrorKind::TooLargeForU128 => "u128", - }; - let err_str = format!("Cast failed. {} too large for {}.", self.val, type_str); - write!(f, "{err_str}") - } -} - -impl std::error::Error for U256FromStrError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.0.source() - } -} - -impl fmt::Display for U256FromStrError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Default)] -pub struct U256(PrimitiveU256); - -impl fmt::Display for U256 { - fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl fmt::UpperHex for U256 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::UpperHex::fmt(&self.0, f) - } -} - -impl fmt::LowerHex for U256 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::LowerHex::fmt(&self.0, f) - } -} - -impl std::str::FromStr for U256 { - type Err = U256FromStrError; - - fn from_str(s: &str) -> Result { - Self::from_str_radix(s, 10) - } -} - -impl<'de> Deserialize<'de> for U256 { - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - Ok(U256::from_le_bytes( - &(<[u8; U256_NUM_BYTES]>::deserialize(deserializer)?), - )) - } -} - -impl Serialize for U256 { - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - self.to_le_bytes().serialize(serializer) - } -} - -impl Shl for U256 { - type Output = Self; - - fn shl(self, rhs: u32) -> Self::Output { - let Self(lhs) = self; - Self(lhs << rhs) - } -} - -impl Shl for U256 { - type Output = Self; - - fn shl(self, rhs: u8) -> Self::Output { - let Self(lhs) = self; - Self(lhs << rhs) - } -} - -impl Shr for U256 { - type Output = Self; - - fn shr(self, rhs: u8) -> Self::Output { - let Self(lhs) = self; - Self(lhs >> rhs) - } -} - -impl BitOr for U256 { - type Output = Self; - - fn bitor(self, rhs: U256) -> Self::Output { - let Self(lhs) = self; - let Self(rhs) = rhs; - Self(lhs | rhs) - } -} - -impl BitAnd for U256 { - type Output = Self; - - fn bitand(self, rhs: U256) -> Self::Output { - let Self(lhs) = self; - let Self(rhs) = rhs; - Self(lhs & rhs) - } -} - -impl BitXor for U256 { - type Output = Self; - - fn bitxor(self, rhs: U256) -> Self::Output { - let Self(lhs) = self; - let Self(rhs) = rhs; - Self(lhs ^ rhs) - } -} - -impl BitAndAssign for U256 { - fn bitand_assign(&mut self, rhs: U256) { - *self = *self & rhs; - } -} - -// Ignores overflows -impl Add for U256 { - type Output = Self; - - fn add(self, rhs: U256) -> Self::Output { - self.wrapping_add(rhs) - } -} - -impl AddAssign for U256 { - fn add_assign(&mut self, rhs: U256) { - *self = *self + rhs; - } -} - -// Ignores underflows -impl Sub for U256 { - type Output = Self; - - fn sub(self, rhs: U256) -> Self::Output { - self.wrapping_sub(rhs) - } -} - -impl SubAssign for U256 { - fn sub_assign(&mut self, rhs: U256) { - *self = *self - rhs; - } -} - -// Ignores overflows -impl Mul for U256 { - type Output = Self; - - fn mul(self, rhs: U256) -> Self::Output { - self.wrapping_mul(rhs) - } -} - -impl MulAssign for U256 { - fn mul_assign(&mut self, rhs: U256) { - *self = *self * rhs; - } -} - -impl Div for U256 { - type Output = Self; - - fn div(self, rhs: U256) -> Self::Output { - Self(self.0 / rhs.0) - } -} - -impl DivAssign for U256 { - fn div_assign(&mut self, rhs: U256) { - *self = *self / rhs; - } -} - -impl Rem for U256 { - type Output = Self; - - fn rem(self, rhs: U256) -> Self::Output { - Self(self.0 % rhs.0) - } -} - -impl RemAssign for U256 { - fn rem_assign(&mut self, rhs: U256) { - *self = Self(self.0 % rhs.0); - } -} - -impl U256 { - /// Zero value as U256 - pub const fn zero() -> Self { - Self(PrimitiveU256::zero()) - } - - /// One value as U256 - pub const fn one() -> Self { - Self(PrimitiveU256::one()) - } - - /// Max value of U256: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - pub const fn max_value() -> Self { - Self(PrimitiveU256::max_value()) - } - - /// U256 from string with radix 10 or 16 - pub fn from_str_radix(src: &str, radix: u32) -> Result { - PrimitiveU256::from_str_radix(src.trim_start_matches('0'), radix) - .map(Self) - .map_err(U256FromStrError) - } - - /// U256 from 32 little endian bytes - pub fn from_le_bytes(slice: &[u8; U256_NUM_BYTES]) -> Self { - Self(PrimitiveU256::from_little_endian(slice)) - } - - /// U256 to 32 little endian bytes - pub fn to_le_bytes(self) -> [u8; U256_NUM_BYTES] { - let mut bytes = [0u8; U256_NUM_BYTES]; - self.0.to_little_endian(&mut bytes); - bytes - } - - /// Leading zeros of the number - pub fn leading_zeros(&self) -> u32 { - self.0.leading_zeros() - } - - // Unchecked downcasting. Values as truncated if larger than target max - pub fn unchecked_as_u8(&self) -> u8 { - self.0.low_u128() as u8 - } - - pub fn unchecked_as_u16(&self) -> u16 { - self.0.low_u128() as u16 - } - - pub fn unchecked_as_u32(&self) -> u32 { - self.0.low_u128() as u32 - } - - pub fn unchecked_as_u64(&self) -> u64 { - self.0.low_u128() as u64 - } - - pub fn unchecked_as_u128(&self) -> u128 { - self.0.low_u128() - } - - // Check arithmetic - /// Checked integer addition. Computes self + rhs, returning None if overflow occurred. - pub fn checked_add(self, rhs: Self) -> Option { - self.0.checked_add(rhs.0).map(Self) - } - - /// Checked integer subtraction. Computes self - rhs, returning None if overflow occurred. - pub fn checked_sub(self, rhs: Self) -> Option { - self.0.checked_sub(rhs.0).map(Self) - } - - /// Checked integer multiplication. Computes self * rhs, returning None if overflow occurred. - pub fn checked_mul(self, rhs: Self) -> Option { - self.0.checked_mul(rhs.0).map(Self) - } - - /// Checked integer division. Computes self / rhs, returning None if rhs == 0. - pub fn checked_div(self, rhs: Self) -> Option { - self.0.checked_div(rhs.0).map(Self) - } - - /// Checked integer remainder. Computes self % rhs, returning None if rhs == 0. - pub fn checked_rem(self, rhs: Self) -> Option { - self.0.checked_rem(rhs.0).map(Self) - } - - /// Checked integer remainder. Computes self % rhs, returning None if rhs == 0. - pub fn checked_shl(self, rhs: u32) -> Option { - if rhs >= U256_NUM_BITS as u32 { - return None; - } - Some(Self(self.0.shl(rhs))) - } - - /// Checked shift right. Computes self >> rhs, returning None if rhs is larger than or equal to the number of bits in self. - pub fn checked_shr(self, rhs: u32) -> Option { - if rhs >= U256_NUM_BITS as u32 { - return None; - } - Some(Self(self.0.shr(rhs))) - } - - /// Downcast to a an unsigned value of type T - /// T must be at most u128 - pub fn down_cast_lossy>(self) -> T { - // Size of this type - let type_size = size_of::(); - // Maximum value for this type - let max_val: u128 = if type_size < 16 { - (1u128 << (NUM_BITS_PER_BYTE * type_size)) - 1u128 - } else { - u128::MAX - }; - // This should never fail - match T::try_from(self.0.low_u128() & max_val) { - Ok(w) => w, - Err(_) => panic!("Fatal! Downcast failed"), - } - } - - /// Wrapping integer addition. Computes self + rhs, wrapping around at the boundary of the type. - /// By definition in std::instrinsics, a.wrapping_add(b) = (a + b) % (2^N), where N is bit width - pub fn wrapping_add(self, rhs: Self) -> Self { - Self(self.0.overflowing_add(rhs.0).0) - } - - /// Wrapping integer subtraction. Computes self - rhs, wrapping around at the boundary of the type. - /// By definition in std::instrinsics, a.wrapping_add(b) = (a - b) % (2^N), where N is bit width - pub fn wrapping_sub(self, rhs: Self) -> Self { - Self(self.0.overflowing_sub(rhs.0).0) - } - - /// Wrapping integer multiplication. Computes self * rhs, wrapping around at the boundary of the type. - /// By definition in std::instrinsics, a.wrapping_mul(b) = (a * b) % (2^N), where N is bit width - pub fn wrapping_mul(self, rhs: Self) -> Self { - Self(self.0.overflowing_mul(rhs.0).0) - } - - /// Implementation of widenining multiply - /// https://github.com/rust-random/rand/blob/master/src/distributions/utils.rs - #[inline(always)] - fn wmul(self, b: Self) -> (Self, Self) { - let half = 128; - #[allow(non_snake_case)] - let LOWER_MASK: U256 = Self::max_value() >> half; - - let mut low = (self & LOWER_MASK).wrapping_mul(b & LOWER_MASK); - let mut t = low >> half; - low &= LOWER_MASK; - t += (self >> half).wrapping_mul(b & LOWER_MASK); - low += (t & LOWER_MASK) << half; - let mut high = t >> half; - t = low >> half; - low &= LOWER_MASK; - t += (b >> half).wrapping_mul(self & LOWER_MASK); - low += (t & LOWER_MASK) << half; - high += t >> half; - high += (self >> half).wrapping_mul(b >> half); - - (high, low) - } -} - -impl From for U256 { - fn from(n: u8) -> Self { - U256(PrimitiveU256::from(n)) - } -} - -impl From for U256 { - fn from(n: u16) -> Self { - U256(PrimitiveU256::from(n)) - } -} - -impl From for U256 { - fn from(n: u32) -> Self { - U256(PrimitiveU256::from(n)) - } -} - -impl From for U256 { - fn from(n: u64) -> Self { - U256(PrimitiveU256::from(n)) - } -} - -impl From for U256 { - fn from(n: u128) -> Self { - U256(PrimitiveU256::from(n)) - } -} - -/// TODO (ade): Remove conversions and migrate Prover & Move Model code from BigInt -impl From<&U256> for BigInt { - fn from(n: &U256) -> Self { - BigInt::from_bytes_le(Sign::Plus, &n.to_le_bytes()) - } -} - -/// TODO (ade): Remove conversions and migrate Prover & Move Model code from EthnumU256 -impl From<&U256> for EthnumU256 { - fn from(n: &U256) -> EthnumU256 { - // TODO (ade): use better solution for conversion - // Currently using str because EthnumU256 can be little or big endian - let num_str = format!("{:X}", n.0); - // TODO (ade): remove expect() - EthnumU256::from_str_radix(&num_str, 16).expect("Cannot convert to U256") - } -} - -impl TryFrom for u8 { - type Error = U256CastError; - - fn try_from(n: U256) -> Result { - let n = n.0.low_u64(); - if n > u8::MAX as u64 { - Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU8)) - } else { - Ok(n as u8) - } - } -} - -impl TryFrom for u16 { - type Error = U256CastError; - - fn try_from(n: U256) -> Result { - let n = n.0.low_u64(); - if n > u16::MAX as u64 { - Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU16)) - } else { - Ok(n as u16) - } - } -} - -impl TryFrom for u32 { - type Error = U256CastError; - - fn try_from(n: U256) -> Result { - let n = n.0.low_u64(); - if n > u32::MAX as u64 { - Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU32)) - } else { - Ok(n as u32) - } - } -} - -impl TryFrom for u64 { - type Error = U256CastError; - - fn try_from(n: U256) -> Result { - let n = n.0.low_u128(); - if n > u64::MAX as u128 { - Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU64)) - } else { - Ok(n as u64) - } - } -} - -impl TryFrom for u128 { - type Error = U256CastError; - - fn try_from(n: U256) -> Result { - if n > U256::from(u128::MAX) { - Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU128)) - } else { - Ok(n.0.low_u128()) - } - } -} - -impl Distribution for Standard { - #[inline] - fn sample(&self, rng: &mut R) -> U256 { - let mut dest = [0; U256_NUM_BYTES]; - rng.fill_bytes(&mut dest); - U256::from_le_bytes(&dest) - } -} - -// Rand impl below are inspired by u128 impl found in https://rust-random.github.io/rand/src/rand/distributions/uniform.rs.html - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] -pub struct UniformU256 { - low: U256, - range: U256, - z: U256, -} - -impl SampleUniform for U256 { - type Sampler = UniformU256; -} - -impl UniformSampler for UniformU256 { - type X = U256; - - fn new(low: B1, high: B2) -> Self - where - B1: rand::distributions::uniform::SampleBorrow + Sized, - B2: rand::distributions::uniform::SampleBorrow + Sized, - { - let low = *low.borrow(); - let high = *high.borrow(); - assert!(low < high, "Uniform::new called with `low >= high`"); - UniformSampler::new_inclusive(low, high - U256::one()) - } - - fn new_inclusive(low: B1, high: B2) -> Self - where - B1: rand::distributions::uniform::SampleBorrow + Sized, - B2: rand::distributions::uniform::SampleBorrow + Sized, - { - let low = *low.borrow(); - let high = *high.borrow(); - assert!( - low <= high, - "Uniform::new_inclusive called with `low > high`" - ); - let unsigned_max = U256::max_value(); - - let range = high.wrapping_sub(low).wrapping_add(U256::one()); - - let ints_to_reject = if range > U256::zero() { - (unsigned_max - range) + U256::one() % range - } else { - U256::zero() - }; - - UniformU256 { - low, - range, - z: ints_to_reject, - } - } - - fn sample(&self, rng: &mut R) -> Self::X { - let range = self.range; - if range > U256::zero() { - let unsigned_max = U256::max_value(); - let zone = unsigned_max - self.z; - loop { - let v: U256 = rng.gen(); - let (hi, lo) = v.wmul(range); - if lo <= zone { - return self.low.wrapping_add(hi); - } - } - } else { - // Sample from the entire integer range. - rng.gen() - } - } - - fn sample_single(low: B1, high: B2, rng: &mut R) -> Self::X - where - B1: rand::distributions::uniform::SampleBorrow + Sized, - B2: rand::distributions::uniform::SampleBorrow + Sized, - { - let low = *low.borrow(); - let high = *high.borrow(); - assert!(low < high, "UniformSampler::sample_single: low >= high"); - Self::sample_single_inclusive(low, high - U256::one(), rng) - } - - fn sample_single_inclusive( - low: B1, - high: B2, - rng: &mut R, - ) -> Self::X - where - B1: rand::distributions::uniform::SampleBorrow + Sized, - B2: rand::distributions::uniform::SampleBorrow + Sized, - { - let low = *low.borrow(); - let high = *high.borrow(); - assert!( - low <= high, - "UniformSampler::sample_single_inclusive: low > high" - ); - let range = high.wrapping_sub(low).wrapping_add(U256::one()); - // If the above resulted in wrap-around to 0, the range is U256::MIN..=U256::MAX, - // and any integer will do. - if range == U256::zero() { - return rng.gen(); - } - // conservative but fast approximation. `- 1` is necessary to allow the - // same comparison without bias. - let zone = (range << range.leading_zeros()).wrapping_sub(U256::one()); - - loop { - let v: U256 = rng.gen(); - let (hi, lo) = v.wmul(range); - if lo <= zone { - return low.wrapping_add(hi); - } - } - } -} - -#[cfg(any(test, feature = "fuzzing"))] -impl proptest::prelude::Arbitrary for U256 { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with(_params: Self::Parameters) -> Self::Strategy { - use proptest::strategy::Strategy as _; - proptest::arbitrary::any::<[u8; U256_NUM_BYTES]>() - .prop_map(|q| U256::from_le_bytes(&q)) - .boxed() - } -} - -#[cfg(any(test, feature = "fuzzing"))] -impl<'a> arbitrary::Arbitrary<'a> for U256 { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let bytes = <[u8; U256_NUM_BYTES]>::arbitrary(u)?; - Ok(U256::from_le_bytes(&bytes)) - } -} - -#[cfg(any(test, feature = "fuzzing"))] -impl dearbitrary::Dearbitrary for U256 { - fn dearbitrary(&self, dearbitrator: &mut dearbitrary::Dearbitrator) { - dearbitrator.push_bytes(U256::to_le_bytes(self.to_owned()).as_ref()); - } -} - -#[test] -fn wrapping_add() { - // a + b overflows U256::MAX by 100 - // By definition in std::instrinsics, a.wrapping_add(b) = (a + b) % (2^N), where N is bit width - - let a = U256::from(1234u32); - let b = U256::from_str_radix( - "115792089237316195423570985008687907853269984665640564039457584007913129638801", - 10, - ) - .unwrap(); - - assert!(a.wrapping_add(b) == U256::from(99u8)); -} diff --git a/third_party/move/move-core/types/src/value.rs b/third_party/move/move-core/types/src/value.rs index 607670a64b9..79978cfa2d9 100644 --- a/third_party/move/move-core/types/src/value.rs +++ b/third_party/move/move-core/types/src/value.rs @@ -12,8 +12,8 @@ use crate::{ function::{ClosureVisitor, MoveClosure}, ident_str, identifier::Identifier, + int256, language_storage::{ModuleId, StructTag, TypeTag}, - u256, }; use anyhow::{anyhow, bail, Result as AResult}; use once_cell::sync::Lazy; @@ -133,9 +133,16 @@ pub enum MoveValue { // NOTE: Added in bytecode version v6, do not reorder! U16(u16), U32(u32), - U256(u256::U256), + U256(int256::U256), // Added in bytecode version v8 Closure(Box), + // Added in bytecode version v9 + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + I256(int256::I256), } /// A layout associated with a named field @@ -268,28 +275,19 @@ pub enum MoveTypeLayout { // Added in bytecode version v8 #[serde(rename(serialize = "fun", deserialize = "fun"))] Function, -} - -impl MoveTypeLayout { - /// Determines whether the layout is serialization compatible with the other layout - /// (that is, any value serialized with this layout can be deserialized by the other). - pub fn is_compatible_with(&self, other: &Self) -> bool { - use MoveTypeLayout::*; - match (self, other) { - (Vector(t1), Vector(t2)) => t1.is_compatible_with(t2), - (Struct(s1), Struct(s2)) => s1.is_compatible_with(s2), - // For all other cases, equality is used - (t1, t2) => t1 == t2, - } - } - - pub fn is_compatible_with_slice(this: &[Self], other: &[Self]) -> bool { - this.len() == other.len() - && this - .iter() - .zip(other) - .all(|(t1, t2)| t1.is_compatible_with(t2)) - } + // Added in bytecode version v9 + #[serde(rename(serialize = "i8", deserialize = "i8"))] + I8, + #[serde(rename(serialize = "i16", deserialize = "i16"))] + I16, + #[serde(rename(serialize = "i32", deserialize = "i32"))] + I32, + #[serde(rename(serialize = "i64", deserialize = "i64"))] + I64, + #[serde(rename(serialize = "i128", deserialize = "i128"))] + I128, + #[serde(rename(serialize = "i256", deserialize = "i256"))] + I256, } impl MoveValue { @@ -510,31 +508,6 @@ impl MoveStructLayout { Self::WithVariants(variants) } - /// Determines whether the layout is serialization compatible with the other layout - /// (that is, any value serialized with this layout can be deserialized by the other). - /// This only will consider runtime variants, decorated variants are only compatible - /// if equal. - pub fn is_compatible_with(&self, other: &Self) -> bool { - use MoveStructLayout::*; - match (self, other) { - (RuntimeVariants(variants1), RuntimeVariants(variants2)) => { - variants1.len() <= variants2.len() - && variants1.iter().zip(variants2).all(|(fields1, fields2)| { - MoveTypeLayout::is_compatible_with_slice(fields1, fields2) - }) - }, - (Runtime(fields1), Runtime(fields2)) => { - fields1.len() == fields2.len() - && fields1 - .iter() - .zip(fields2) - .all(|(t1, t2)| t1.is_compatible_with(t2)) - }, - // All other cases require equality - (s1, s2) => s1 == s2, - } - } - pub fn fields(&self, variant: Option) -> &[MoveTypeLayout] { match self { Self::Runtime(vals) => vals, @@ -606,7 +579,13 @@ impl<'d> serde::de::DeserializeSeed<'d> for &MoveTypeLayout { MoveTypeLayout::U32 => u32::deserialize(deserializer).map(MoveValue::U32), MoveTypeLayout::U64 => u64::deserialize(deserializer).map(MoveValue::U64), MoveTypeLayout::U128 => u128::deserialize(deserializer).map(MoveValue::U128), - MoveTypeLayout::U256 => u256::U256::deserialize(deserializer).map(MoveValue::U256), + MoveTypeLayout::U256 => int256::U256::deserialize(deserializer).map(MoveValue::U256), + MoveTypeLayout::I8 => i8::deserialize(deserializer).map(MoveValue::I8), + MoveTypeLayout::I16 => i16::deserialize(deserializer).map(MoveValue::I16), + MoveTypeLayout::I32 => i32::deserialize(deserializer).map(MoveValue::I32), + MoveTypeLayout::I64 => i64::deserialize(deserializer).map(MoveValue::I64), + MoveTypeLayout::I128 => i128::deserialize(deserializer).map(MoveValue::I128), + MoveTypeLayout::I256 => int256::I256::deserialize(deserializer).map(MoveValue::I256), MoveTypeLayout::Address => { AccountAddress::deserialize(deserializer).map(MoveValue::Address) }, @@ -819,6 +798,12 @@ impl serde::Serialize for MoveValue { MoveValue::U64(i) => serializer.serialize_u64(*i), MoveValue::U128(i) => serializer.serialize_u128(*i), MoveValue::U256(i) => i.serialize(serializer), + MoveValue::I8(i) => serializer.serialize_i8(*i), + MoveValue::I16(i) => serializer.serialize_i16(*i), + MoveValue::I32(i) => serializer.serialize_i32(*i), + MoveValue::I64(i) => serializer.serialize_i64(*i), + MoveValue::I128(i) => serializer.serialize_i128(*i), + MoveValue::I256(i) => i.serialize(serializer), MoveValue::Address(a) => a.serialize(serializer), MoveValue::Signer(a) => { // Runtime representation of signer looks following: @@ -938,6 +923,12 @@ impl fmt::Display for MoveTypeLayout { U64 => write!(f, "u64"), U128 => write!(f, "u128"), U256 => write!(f, "u256"), + I8 => write!(f, "i8"), + I16 => write!(f, "i16"), + I32 => write!(f, "i32"), + I64 => write!(f, "i64"), + I128 => write!(f, "i128"), + I256 => write!(f, "i256"), Address => write!(f, "address"), Vector(typ) => write!(f, "vector<{}>", typ), Struct(s) => fmt::Display::fmt(s, f), @@ -1006,6 +997,12 @@ impl TryInto for &MoveTypeLayout { MoveTypeLayout::U64 => TypeTag::U64, MoveTypeLayout::U128 => TypeTag::U128, MoveTypeLayout::U256 => TypeTag::U256, + MoveTypeLayout::I8 => TypeTag::I8, + MoveTypeLayout::I16 => TypeTag::I16, + MoveTypeLayout::I32 => TypeTag::I32, + MoveTypeLayout::I64 => TypeTag::I64, + MoveTypeLayout::I128 => TypeTag::I128, + MoveTypeLayout::I256 => TypeTag::I256, MoveTypeLayout::Signer => TypeTag::Signer, MoveTypeLayout::Vector(v) => TypeTag::Vector(Box::new(v.as_ref().try_into()?)), MoveTypeLayout::Struct(v) => TypeTag::Struct(Box::new(v.try_into()?)), diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 37e3c0eca77..87edc4c450f 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -192,7 +192,11 @@ impl VMStatus { /// Returns `Ok` with a recorded status if it should be kept, `Err` of the error code if it /// should be discarded - pub fn keep_or_discard(self) -> Result { + pub fn keep_or_discard( + self, + function_values_enabled: bool, + memory_limit_exceeded_as_miscellaneous_error: bool, + ) -> Result { match self { VMStatus::Executed => Ok(KeptVMStatus::Executed), VMStatus::MoveAbort(location, code) => Ok(KeptVMStatus::MoveAbort(location, code)), @@ -205,13 +209,36 @@ impl VMStatus { .. } => Ok(KeptVMStatus::OutOfGas), + // Note: this is feature gated because the status was not propagated out before and was + // mapped to execution error at function ... at offset ..., etc. + VMStatus::ExecutionFailure { + status_code: StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + .. + } + | VMStatus::Error { + status_code: StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + .. + } if function_values_enabled => Ok(KeptVMStatus::MiscellaneousError), + VMStatus::ExecutionFailure { + status_code: StatusCode::MEMORY_LIMIT_EXCEEDED, + .. + } if memory_limit_exceeded_as_miscellaneous_error => { + Ok(KeptVMStatus::MiscellaneousError) + }, + VMStatus::Error { + status_code: StatusCode::MEMORY_LIMIT_EXCEEDED, + .. + } if memory_limit_exceeded_as_miscellaneous_error => { + Ok(KeptVMStatus::MiscellaneousError) + }, VMStatus::ExecutionFailure { status_code: StatusCode::EXECUTION_LIMIT_REACHED | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::VM_MAX_VALUE_DEPTH_REACHED + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } | VMStatus::Error { @@ -220,7 +247,8 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::VM_MAX_VALUE_DEPTH_REACHED + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } => Ok(KeptVMStatus::MiscellaneousError), @@ -760,12 +788,15 @@ pub enum StatusCode { CLOSURE_CALL_REQUIRES_FUNCTION = 1133, // Returned if init_module function is not valid during code publishing. INVALID_INIT_MODULE = 1134, + // When publishing a module bundle, all friends declared there must be in this bundle. If it is + // not the case, an error with this status code is returned. + FRIEND_NOT_FOUND_IN_MODULE_BUNDLE = 1135, // Reserved error code for future use - RESERVED_VERIFICATION_ERROR_1 = 1135, - RESERVED_VERIFICATION_ERROR_2 = 1136, - RESERVED_VERIFICATION_ERROR_3 = 1137, - RESERVED_VERIFICATION_ERROR_4 = 1138, + RESERVED_VERIFICATION_ERROR_1 = 1136, + RESERVED_VERIFICATION_ERROR_2 = 1137, + RESERVED_VERIFICATION_ERROR_3 = 1138, + RESERVED_VERIFICATION_ERROR_4 = 1139, // These are errors that the VM might raise if a violation of internal // invariants takes place. @@ -838,12 +869,16 @@ pub enum StatusCode { VALUE_DESERIALIZATION_ERROR = 3023, CODE_DESERIALIZATION_ERROR = 3024, INVALID_FLAG_BITS = 3025, + // Returned when a function value is trying to capture an option. This is not allowed + // until the feature flag ENABLE_CAPTURE_OPTION is on. + UNABLE_TO_CAPTURE_OPTION_TYPE = 3026, + // Reserved error code for future use - RESERVED_DESERIALIZAION_ERROR_1 = 3026, - RESERVED_DESERIALIZAION_ERROR_2 = 3027, - RESERVED_DESERIALIZAION_ERROR_3 = 3028, - RESERVED_DESERIALIZAION_ERROR_4 = 3029, - RESERVED_DESERIALIZAION_ERROR_5 = 3030, + RESERVED_DESERIALIZAION_ERROR_1 = 3027, + RESERVED_DESERIALIZAION_ERROR_2 = 3028, + RESERVED_DESERIALIZAION_ERROR_3 = 3029, + RESERVED_DESERIALIZAION_ERROR_4 = 3030, + RESERVED_DESERIALIZAION_ERROR_5 = 3031, // Errors that can arise at runtime // Runtime Errors: 4000-4999 @@ -886,12 +921,17 @@ pub enum StatusCode { STRUCT_VARIANT_MISMATCH = 4038, // An unimplemented functionality in the VM. UNIMPLEMENTED_FUNCTIONALITY = 4039, + // Modules are cyclic (module A uses module B which uses module A). Detected at runtime in case + // module loading is performed lazily. + RUNTIME_CYCLIC_MODULE_DEPENDENCY = 4040, + // Returned when a function value is trying to capture a delayed field. This is not allowed + // because layouts for values with delayed fields are not serializable. + UNABLE_TO_CAPTURE_DELAYED_FIELDS = 4041, // Reserved error code for future use. Always keep this buffer of well-defined new codes. - RESERVED_RUNTIME_ERROR_1 = 4040, - RESERVED_RUNTIME_ERROR_2 = 4041, - RESERVED_RUNTIME_ERROR_3 = 4042, - RESERVED_RUNTIME_ERROR_4 = 4043, + RESERVED_RUNTIME_ERROR_1 = 4042, + RESERVED_RUNTIME_ERROR_2 = 4043, + RESERVED_RUNTIME_ERROR_3 = 4044, // A reserved status to represent an unknown vm status. // this is u64::MAX, but we can't pattern match on that, so put the hardcoded value in @@ -1034,21 +1074,24 @@ fn test_status_codes() { } pub mod sub_status { - // Native Function Error sub-codes + /// Native Function Error sub-codes pub const NFE_VECTOR_ERROR_BASE: u64 = 0; - // Failure in BCS deserialization + /// Failure in BCS deserialization pub const NFE_BCS_SERIALIZATION_FAILURE: u64 = 0x1C5; pub mod unknown_invariant_violation { - // Paranoid Type checking returns an error + /// Paranoid Type checking returns an error pub const EPARANOID_FAILURE: u64 = 0x1; - // Reference safety checks failure + /// Reference counting checks failure pub const EREFERENCE_COUNTING_FAILURE: u64 = 0x2; + + /// Dynamic reference safety checks failure + pub const EREFERENCE_SAFETY_FAILURE: u64 = 0x3; } pub mod type_resolution_failure { - // User provided typetag failed to load. + /// User provided typetag failed to load. pub const EUSER_TYPE_LOADING_FAILURE: u64 = 0x1; } } diff --git a/third_party/move/move-examples/Cargo.toml b/third_party/move/move-examples/Cargo.toml index 0df69fbb215..043977449fa 100644 --- a/third_party/move/move-examples/Cargo.toml +++ b/third_party/move/move-examples/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "move-examples" version = "0.1.1" -edition = "2021" +edition = { workspace = true } authors = ["Diem Association "] description = "Move examples" license = "Apache-2.0" diff --git a/third_party/move/move-examples/diem-framework/crates/cli/Cargo.toml b/third_party/move/move-examples/diem-framework/crates/cli/Cargo.toml index a8dfc0cced2..9b625eda1e1 100644 --- a/third_party/move/move-examples/diem-framework/crates/cli/Cargo.toml +++ b/third_party/move/move-examples/diem-framework/crates/cli/Cargo.toml @@ -5,7 +5,7 @@ description = "CLI frontend for the Move compiler and VM (with Diem Framework)" authors = ["Diem Association "] license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-examples/diem-framework/crates/crypto-derive/Cargo.toml b/third_party/move/move-examples/diem-framework/crates/crypto-derive/Cargo.toml index 3018a363149..45d4bbbdda4 100644 --- a/third_party/move/move-examples/diem-framework/crates/crypto-derive/Cargo.toml +++ b/third_party/move/move-examples/diem-framework/crates/crypto-derive/Cargo.toml @@ -3,7 +3,7 @@ name = "diem-crypto-derive" version = "0.0.3" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [lib] diff --git a/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml b/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml index bbca086b375..6bded4eb041 100644 --- a/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml +++ b/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml @@ -3,7 +3,7 @@ name = "diem-crypto" version = "0.0.3" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-examples/diem-framework/crates/natives/Cargo.toml b/third_party/move/move-examples/diem-framework/crates/natives/Cargo.toml index 86171b086b8..4e02267d031 100644 --- a/third_party/move/move-examples/diem-framework/crates/natives/Cargo.toml +++ b/third_party/move/move-examples/diem-framework/crates/natives/Cargo.toml @@ -3,7 +3,7 @@ name = "diem-framework-natives" version = "0.0.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs b/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs index 026bb9ff4bb..eae9d0baef6 100644 --- a/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs +++ b/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs @@ -13,7 +13,7 @@ use std::collections::VecDeque; pub fn native_create_signer( _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); @@ -29,7 +29,7 @@ pub fn native_create_signer( /// remain for replaying old transactions pub fn native_destroy_signer( _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); diff --git a/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs b/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs index cab54afaacb..f16e030f1af 100644 --- a/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs +++ b/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs @@ -13,7 +13,7 @@ use std::{collections::VecDeque, convert::TryFrom}; pub fn native_ed25519_publickey_validation( _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); @@ -30,7 +30,7 @@ pub fn native_ed25519_publickey_validation( pub fn native_ed25519_signature_verification( _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-ir-compiler/Cargo.toml b/third_party/move/move-ir-compiler/Cargo.toml index 0b3752139fa..a9e8dbaebfd 100644 --- a/third_party/move/move-ir-compiler/Cargo.toml +++ b/third_party/move/move-ir-compiler/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-ir-compiler/move-bytecode-source-map/Cargo.toml b/third_party/move/move-ir-compiler/move-bytecode-source-map/Cargo.toml index b7428bba989..20f03dd68df 100644 --- a/third_party/move/move-ir-compiler/move-bytecode-source-map/Cargo.toml +++ b/third_party/move/move-ir-compiler/move-bytecode-source-map/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Diem Association "] license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/Cargo.toml b/third_party/move/move-ir-compiler/move-ir-to-bytecode/Cargo.toml index 27d17fbbefb..16c72746b15 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/Cargo.toml +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs index 85730682e3d..e89088eaeea 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs @@ -711,7 +711,7 @@ impl<'a> Context<'a> { // Dependency Resolution //********************************************************************************************** - fn dependency(&self, m: &ModuleIdent) -> Result<&CompiledDependencyView> { + fn dependency(&self, m: &ModuleIdent) -> Result<&CompiledDependencyView<'_>> { let dep = self .dependencies .get(m) @@ -773,6 +773,14 @@ impl<'a> Context<'a> { SignatureToken::Function(..) => { unimplemented!("function types not supported by MoveIR") }, + SignatureToken::I8 + | SignatureToken::I16 + | SignatureToken::I32 + | SignatureToken::I64 + | SignatureToken::I128 + | SignatureToken::I256 => { + unimplemented!("signed integer types not supported by MoveIR") + }, SignatureToken::Reference(inner) => { let correct_inner = self.reindex_signature_token(dep, *inner)?; SignatureToken::Reference(Box::new(correct_inner)) diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/Cargo.toml b/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/Cargo.toml index 438ecddaef1..1120145f226 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/Cargo.toml +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/src/syntax.rs b/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/src/syntax.rs index e4d7b6009b2..bd7dd94b339 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/src/syntax.rs +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/syntax/src/syntax.rs @@ -5,11 +5,10 @@ use crate::lexer::*; use anyhow::{anyhow, Context}; use move_command_line_common::files::FileHash; -use move_core_types::{account_address::AccountAddress, u256}; +use move_core_types::{account_address::AccountAddress, int256}; use move_ir_types::{ast::*, location::*, spec_language_ast::*}; use move_symbol_pool::Symbol; use std::{collections::BTreeSet, fmt, str::FromStr}; - // FIXME: The following simplified version of ParseError copied from // lalrpop-util should be replaced. @@ -319,7 +318,7 @@ fn parse_copyable_val(tokens: &mut Lexer) -> Result ! { } fn do_verify_module(module: &CompiledModule, dependencies: &[CompiledModule]) { - verify_module(module).unwrap_or_else(|err| print_error_and_exit(&err)); - if let Err(err) = dependencies::verify_module(module, dependencies) { + let config = VerifierConfig::default(); + verify_module_with_config(&config, module).unwrap_or_else(|err| print_error_and_exit(&err)); + if let Err(err) = dependencies::verify_module(&config, module, dependencies) { print_error_and_exit(&err); } } fn do_verify_script(script: &CompiledScript, dependencies: &[CompiledModule]) { - verify_script(script).unwrap_or_else(|err| print_error_and_exit(&err)); - if let Err(err) = dependencies::verify_script(script, dependencies) { + let config = VerifierConfig::default(); + verify_script_with_config(&config, script).unwrap_or_else(|err| print_error_and_exit(&err)); + if let Err(err) = dependencies::verify_script(&config, script, dependencies) { print_error_and_exit(&err); } } diff --git a/third_party/move/move-ir-compiler/transactional-tests/Cargo.toml b/third_party/move/move-ir-compiler/transactional-tests/Cargo.toml index cdbe4757857..922a35d96ef 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/Cargo.toml +++ b/third_party/move/move-ir-compiler/transactional-tests/Cargo.toml @@ -3,7 +3,7 @@ name = "move-ir-compiler-transactional-tests" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dev-dependencies] diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/function.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/function.exp index 37648b5a63d..0dfa0768965 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/function.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/function.exp @@ -1,67 +1,67 @@ processed 2 tasks +task 0 lines 1-31: print-bytecode --input=module [// This module defines several public functions with complex bodies.] +// Bytecode version v8 +module 0x3d10::Example +struct Coin + value: u64 -task 0 'print-bytecode'. lines 1-31: -// Move bytecode v7 -module 3d10.Example { -struct Coin { - value: u64 -} +// Function definition at index 0 +public fun value(l0: &Coin): u64 + local l1: &u64 + move_loc l0 + borrow_field Coin, value + st_loc l1 + move_loc l1 + read_ref + // @5 + ret -public value(Arg0: &Coin): u64 /* def_idx: 0 */ { -L1: loc0: &u64 -B0: - 0: MoveLoc[0](Arg0: &Coin) - 1: ImmBorrowField[0](Coin.value: u64) - 2: StLoc[1](loc0: &u64) - 3: MoveLoc[1](loc0: &u64) - 4: ReadRef - 5: Ret -} -public deposit(Arg0: &mut Coin, Arg1: Coin) /* def_idx: 1 */ { -L2: loc0: &mut u64 -L3: loc1: u64 -L4: loc2: &Coin -L5: loc3: u64 -L6: loc4: u64 -L7: loc5: u64 -B0: - 0: MoveLoc[0](Arg0: &mut Coin) - 1: MutBorrowField[0](Coin.value: u64) - 2: StLoc[2](loc0: &mut u64) - 3: CopyLoc[2](loc0: &mut u64) - 4: ReadRef - 5: StLoc[3](loc1: u64) - 6: ImmBorrowLoc[1](Arg1: Coin) - 7: StLoc[4](loc2: &Coin) - 8: MoveLoc[4](loc2: &Coin) - 9: Call value(&Coin): u64 - 10: StLoc[5](loc3: u64) - 11: CopyLoc[3](loc1: u64) - 12: CopyLoc[5](loc3: u64) - 13: Add - 14: StLoc[6](loc4: u64) - 15: MoveLoc[6](loc4: u64) - 16: MoveLoc[2](loc0: &mut u64) - 17: WriteRef - 18: MoveLoc[1](Arg1: Coin) - 19: Unpack[0](Coin) - 20: StLoc[7](loc5: u64) - 21: Ret -} -} +// Function definition at index 1 +public fun deposit(l0: &mut Coin, l1: Coin) + local l2: &mut u64 + local l3: u64 + local l4: &Coin + local l5: u64 + local l6: u64 + local l7: u64 + move_loc l0 + mut_borrow_field Coin, value + st_loc l2 + copy_loc l2 + read_ref + // @5 + st_loc l3 + borrow_loc l1 + st_loc l4 + move_loc l4 + call value + // @10 + st_loc l5 + copy_loc l3 + copy_loc l5 + add + st_loc l6 + // @15 + move_loc l6 + move_loc l2 + write_ref + move_loc l1 + unpack Coin + // @20 + st_loc l7 + ret -task 1 'print-bytecode'. lines 33-46: -// Move bytecode v7 -module 4d10.M { + +task 1 lines 33-46: print-bytecode --input=module [// Functions may be declared with entry modifier] +// Bytecode version v8 +module 0x4d10::M +// Function definition at index 0 +entry public fun f() + ret + +// Function definition at index 1 +entry public fun g() + call f + ret -entry public f() /* def_idx: 0 */ { -B0: - 0: Ret -} -entry public g() /* def_idx: 1 */ { -B0: - 0: Call f() - 1: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/let.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/let.exp index 14367531fae..7631d2d2b92 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/let.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/declarations/let.exp @@ -1,16 +1,12 @@ processed 2 tasks +task 0 lines 1-7: print-bytecode [// `let` generates a local with the given type.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ret -task 0 'print-bytecode'. lines 1-7: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: Ret -} -} - -task 1 'print-bytecode'. lines 9-16: +task 1 lines 9-16: print-bytecode [// Two `let` cannot use the same name for a local.] Error: variable redefinition x diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/binary_add.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/binary_add.exp index 726fb5e92f1..13d246330dc 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/binary_add.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/binary_add.exp @@ -1,23 +1,21 @@ processed 1 task +task 0 lines 1-13: print-bytecode --input=module [module 0xE.Expressions {] +// Bytecode version v8 +module 0xe::Expressions +// Function definition at index 0 +fun binary_add() + local l0: u64 + local l1: u64 + local l2: u64 + ld_u64 3 + st_loc l0 + ld_u64 5 + st_loc l1 + move_loc l0 + // @5 + move_loc l1 + add + st_loc l2 + ret -task 0 'print-bytecode'. lines 1-13: -// Move bytecode v7 -module e.Expressions { - -binary_add() /* def_idx: 0 */ { -L0: loc0: u64 -L1: loc1: u64 -L2: loc2: u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: LdU64(5) - 3: StLoc[1](loc1: u64) - 4: MoveLoc[0](loc0: u64) - 5: MoveLoc[1](loc1: u64) - 6: Add - 7: StLoc[2](loc2: u64) - 8: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow.exp index 7e6f5ed38e8..14cd078e3ae 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow.exp @@ -1,120 +1,114 @@ processed 9 tasks +task 0 lines 1-11: print-bytecode [// Borrowing a local produces a reference type.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + local l1: &u64 + ld_u64 3 + st_loc l0 + borrow_loc l0 + st_loc l1 + move_loc l1 + // @5 + pop + ret -task 0 'print-bytecode'. lines 1-11: -// Move bytecode v7 -script { +task 1 lines 13-24: print-bytecode [// Borrowing a local reference produces a reference type.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + local l1: &u64 + local l2: &u64 + ld_u64 3 + st_loc l0 + borrow_loc l0 + st_loc l1 + borrow_loc l1 + // @5 + st_loc l2 + ret -main() /* def_idx: 0 */ { -L0: loc0: u64 -L1: loc1: &u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: ImmBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &u64) - 4: MoveLoc[1](loc1: &u64) - 5: Pop - 6: Ret -} -} -task 1 'print-bytecode'. lines 13-24: -// Move bytecode v7 -script { +task 2 lines 26-59: print-bytecode --input=module [module 0x1d4.M {] +// Bytecode version v8 +module 0x1d4::M +struct T + u: u64 +// Function definition at index 0 +fun f(l0: &T) + local l1: &u64 + move_loc l0 + borrow_field T, u + st_loc l1 + move_loc l1 + pop + // @5 + ret -main() /* def_idx: 0 */ { -L0: loc0: u64 -L1: loc1: &u64 -L2: loc2: &u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: ImmBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &u64) - 4: ImmBorrowLoc[1](loc1: &u64) - 5: StLoc[2](loc2: &u64) - 6: Ret -} -} +// Function definition at index 1 +fun g(l0: &mut T) + local l1: &u64 + move_loc l0 + borrow_field T, u + st_loc l1 + move_loc l1 + pop + // @5 + ret -task 2 'print-bytecode'. lines 26-59: -// Move bytecode v7 -module 1d4.M { -struct T { - u: u64 -} +// Function definition at index 2 +public fun h(l0: &mut T) + local l1: &mut u64 + move_loc l0 + mut_borrow_field T, u + st_loc l1 + move_loc l1 + pop + // @5 + ret -f(Arg0: &T) /* def_idx: 0 */ { -L1: loc0: &u64 -B0: - 0: MoveLoc[0](Arg0: &T) - 1: ImmBorrowField[0](T.u: u64) - 2: StLoc[1](loc0: &u64) - 3: MoveLoc[1](loc0: &u64) - 4: Pop - 5: Ret -} -g(Arg0: &mut T) /* def_idx: 1 */ { -L1: loc0: &u64 -B0: - 0: MoveLoc[0](Arg0: &mut T) - 1: ImmBorrowField[0](T.u: u64) - 2: StLoc[1](loc0: &u64) - 3: MoveLoc[1](loc0: &u64) - 4: Pop - 5: Ret -} -public h(Arg0: &mut T) /* def_idx: 2 */ { -L1: loc0: &mut u64 -B0: - 0: MoveLoc[0](Arg0: &mut T) - 1: MutBorrowField[0](T.u: u64) - 2: StLoc[1](loc0: &mut u64) - 3: MoveLoc[1](loc0: &mut u64) - 4: Pop - 5: Ret -} -} -task 3 'print-bytecode'. lines 61-80: -// Move bytecode v7 -module 2d4.M { -struct T { - u: Ty0 -} +task 3 lines 61-80: print-bytecode --input=module [module 0x2d4.M {] +// Bytecode version v8 +module 0x2d4::M +struct T + u: T0 -f(Arg0: &T) /* def_idx: 0 */ { -L1: loc0: &u64 -B0: - 0: MoveLoc[0](Arg0: &T) - 1: ImmBorrowFieldGeneric[0](T.u: Ty0) - 2: StLoc[1](loc0: &u64) - 3: MoveLoc[1](loc0: &u64) - 4: Pop - 5: Ret -} -g(Arg0: &mut T) /* def_idx: 1 */ { -L1: loc0: &u128 -B0: - 0: MoveLoc[0](Arg0: &mut T) - 1: ImmBorrowFieldGeneric[1](T.u: Ty0) - 2: StLoc[1](loc0: &u128) - 3: MoveLoc[1](loc0: &u128) - 4: Pop - 5: Ret -} -} +// Function definition at index 0 +fun f(l0: &T) + local l1: &u64 + move_loc l0 + borrow_field T, u + st_loc l1 + move_loc l1 + pop + // @5 + ret -task 5 'print-bytecode'. lines 93-108: -Error: Unbound struct Self.T +// Function definition at index 1 +fun g(l0: &mut T) + local l1: &u128 + move_loc l0 + borrow_field T, u + st_loc l1 + move_loc l1 + pop + // @5 + ret -task 6 'print-bytecode'. lines 110-119: -Error: Unbound struct Self.T -task 7 'print-bytecode'. lines 121-136: +task 4 lines 82-90: publish [module 0x3d4.M {] +task 5 lines 93-108: print-bytecode --input=module [// Attempting an immutable borrow of the field of a struct type defined in a] Error: Unbound struct Self.T - -task 8 'print-bytecode'. lines 138-146: +task 6 lines 110-119: print-bytecode [import 0x3d4.M;] +Error: Unbound struct Self.T +task 7 lines 121-136: print-bytecode --input=module [// Attempting a mutable borrow of the field of a struct type defined in a] +Error: Unbound struct Self.T +task 8 lines 138-146: print-bytecode [main(account: signer) {] Error: Unbound module alias M diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp index b1117ab2292..8208eeada8a 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/borrow_mut.exp @@ -1,59 +1,55 @@ processed 3 tasks +task 0 lines 1-10: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + local l1: &mut u64 + ld_u64 3 + st_loc l0 + mut_borrow_loc l0 + st_loc l1 + ld_u64 42 + // @5 + move_loc l1 + write_ref + ret + + +task 1 lines 12-23: print-bytecode --input=module [module 0x3d.Foobar {] +// Bytecode version v8 +module 0x3d::Foobar +struct FooCoin + value: u64 + +// Function definition at index 0 +public fun borrow_mut_field(l0: &mut FooCoin) + local l1: &mut u64 + move_loc l0 + mut_borrow_field FooCoin, value + st_loc l1 + move_loc l1 + pop + // @5 + ret + + +task 2 lines 25-36: print-bytecode --input=module [module 0x4d.Foobar {] +// Bytecode version v8 +module 0x4d::Foobar +struct FooCoin + value: u64 + +// Function definition at index 0 +public fun borrow_mut_field(l0: &mut FooCoin
) + local l1: &mut u64 + move_loc l0 + mut_borrow_field FooCoin
, value + st_loc l1 + move_loc l1 + pop + // @5 + ret + -task 0 'print-bytecode'. lines 1-10: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -L0: loc0: u64 -L1: loc1: &mut u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: MutBorrowLoc[0](loc0: u64) - 3: StLoc[1](loc1: &mut u64) - 4: LdU64(42) - 5: MoveLoc[1](loc1: &mut u64) - 6: WriteRef - 7: Ret -} -} - -task 1 'print-bytecode'. lines 12-23: -// Move bytecode v7 -module 3d.Foobar { -struct FooCoin { - value: u64 -} - -public borrow_mut_field(Arg0: &mut FooCoin) /* def_idx: 0 */ { -L1: loc0: &mut u64 -B0: - 0: MoveLoc[0](Arg0: &mut FooCoin) - 1: MutBorrowField[0](FooCoin.value: u64) - 2: StLoc[1](loc0: &mut u64) - 3: MoveLoc[1](loc0: &mut u64) - 4: Pop - 5: Ret -} -} - -task 2 'print-bytecode'. lines 25-36: -// Move bytecode v7 -module 4d.Foobar { -struct FooCoin { - value: u64 -} - -public borrow_mut_field(Arg0: &mut FooCoin
) /* def_idx: 0 */ { -L1: loc0: &mut u64 -B0: - 0: MoveLoc[0](Arg0: &mut FooCoin
) - 1: MutBorrowFieldGeneric[0](FooCoin.value: u64) - 2: StLoc[1](loc0: &mut u64) - 3: MoveLoc[1](loc0: &mut u64) - 4: Pop - 5: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp index 7a93d926589..b3b072916b2 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global.exp @@ -1,28 +1,23 @@ processed 4 tasks +task 0 lines 1-14: print-bytecode --input=module [// Borrowing a global of a type defined as part of the same module is valid.] +// Bytecode version v8 +module 0x1d6::M +use 0x1::signer +struct T has key + b: bool -task 0 'print-bytecode'. lines 1-14: -// Move bytecode v7 -module 1d6.M { -use 0000000000000000000000000000000000000000000000000000000000000001::signer; +// Function definition at index 0 +fun f(l0: signer) + local l1: &T + borrow_loc l0 + call signer::address_of + borrow_global T + st_loc l1 + ret -struct T has key { - b: bool -} - -f(Arg0: signer) /* def_idx: 0 */ { -L1: loc0: &T -B0: - 0: ImmBorrowLoc[0](Arg0: signer) - 1: Call signer::address_of(&signer): address - 2: ImmBorrowGlobal[0](T) - 3: StLoc[1](loc0: &T) - 4: Ret -} -} - -task 2 'print-bytecode'. lines 21-33: +task 1 lines 16-19: publish [module 0x2d6.M {] +task 2 lines 21-33: print-bytecode --input=module [// Borrowing a global of a type defined in a different module is invalid.] Error: Missing struct definition for T - -task 3 'print-bytecode'. lines 35-46: +task 3 lines 35-46: print-bytecode [// Borrowing a global of a struct type within a script (which cannot define its own struct types)] Error: Missing struct definition for T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp index 2d4a266ad6f..5bd5c1882c6 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/borrow_global_mut.exp @@ -1,28 +1,23 @@ processed 4 tasks +task 0 lines 1-14: print-bytecode --input=module [// Borrowing a global of a type defined as part of the same module is valid.] +// Bytecode version v8 +module 0x1d6::M +use 0x1::signer +struct T has key + b: bool -task 0 'print-bytecode'. lines 1-14: -// Move bytecode v7 -module 1d6.M { -use 0000000000000000000000000000000000000000000000000000000000000001::signer; +// Function definition at index 0 +fun f(l0: signer) + local l1: &mut T + borrow_loc l0 + call signer::address_of + mut_borrow_global T + st_loc l1 + ret -struct T has key { - b: bool -} - -f(Arg0: signer) /* def_idx: 0 */ { -L1: loc0: &mut T -B0: - 0: ImmBorrowLoc[0](Arg0: signer) - 1: Call signer::address_of(&signer): address - 2: MutBorrowGlobal[0](T) - 3: StLoc[1](loc0: &mut T) - 4: Ret -} -} - -task 2 'print-bytecode'. lines 21-33: +task 1 lines 16-19: publish [module 0x2d6.M {] +task 2 lines 21-33: print-bytecode --input=module [// Borrowing a global of a type defined in a different module is invalid.] Error: Missing struct definition for T - -task 3 'print-bytecode'. lines 35-46: +task 3 lines 35-46: print-bytecode [// Borrowing a global of a struct type within a script (which cannot define its own struct types)] Error: Missing struct definition for T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp index cc06f16a70e..3e9f834f462 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/exists.exp @@ -1,24 +1,21 @@ processed 4 tasks +task 0 lines 1-11: print-bytecode --input=module [module 0x5d5.M {] +// Bytecode version v8 +module 0x5d5::M +struct T has key + b: bool -task 0 'print-bytecode'. lines 1-11: -// Move bytecode v7 -module 5d5.M { -struct T has key { - b: bool -} +// Function definition at index 0 +fun f() + local l0: bool + ld_u64 4 + exists T + st_loc l0 + ret -f() /* def_idx: 0 */ { -L0: loc0: bool -B0: - 0: LdU64(4) - 1: Exists[0](T) - 2: StLoc[0](loc0: bool) - 3: Ret -} -} -task 2 'print-bytecode'. lines 18-27: +task 1 lines 13-16: publish [module 0x6d5.M {] +task 2 lines 18-27: print-bytecode --input=module [// Checking the existence of a struct type defined in a different module is invalid.] Error: Missing struct definition for T - -task 3 'print-bytecode'. lines 29-37: +task 3 lines 29-37: print-bytecode [// Checking the existence of a struct type within a script (which cannot define its own] Error: Missing struct definition for T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp index 1d0a02e062b..dabb53a8522 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/move_to.exp @@ -1,29 +1,26 @@ processed 4 tasks +task 0 lines 1-16: print-bytecode --input=module [// Moving a type defined as part of the same module is valid.] +// Bytecode version v8 +module 0x2d6::M +struct T has key + b: bool -task 0 'print-bytecode'. lines 1-16: -// Move bytecode v7 -module 2d6.M { -struct T has key { - b: bool -} +// Function definition at index 0 +public fun new(): T + ld_true + pack T + ret -public new(): T /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: Pack[0](T) - 2: Ret -} -f(Arg0: signer) /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: signer) - 1: Call new(): T - 2: MoveTo[0](T) - 3: Ret -} -} +// Function definition at index 1 +fun f(l0: signer) + borrow_loc l0 + call new + move_to T + ret -task 2 'print-bytecode'. lines 29-39: -Error: Missing struct definition for T -task 3 'print-bytecode'. lines 41-49: +task 1 lines 18-26: publish [module 0x3d6.M {] +task 2 lines 29-39: print-bytecode --input=module [// Moving a type defined in a different module is invalid.] +Error: Missing struct definition for T +task 3 lines 41-49: print-bytecode [// Moving a struct type within a script (which cannot define its own struct types) is invalid.] Error: Missing struct definition for T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp index 2b64f4f351c..9b7830ae89f 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/builtins/vector.exp @@ -1,61 +1,66 @@ processed 1 task +task 0 lines 1-31: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: vector + local l1: &vector + local l2: &mut vector + local l3: u64 + local l4: &u64 + local l5: &mut u64 + vec_pack , 0 + st_loc l0 + borrow_loc l0 + st_loc l1 + copy_loc l1 + // @5 + vec_len + st_loc l3 + move_loc l1 + pop + mut_borrow_loc l0 + // @10 + st_loc l2 + copy_loc l2 + ld_u64 0 + vec_push_back + copy_loc l2 + // @15 + ld_u64 1 + vec_push_back + copy_loc l2 + ld_u64 0 + vec_borrow + // @20 + st_loc l4 + move_loc l4 + pop + copy_loc l2 + ld_u64 1 + // @25 + vec_mut_borrow + st_loc l5 + move_loc l5 + pop + copy_loc l2 + // @30 + ld_u64 0 + ld_u64 1 + vec_swap + copy_loc l2 + vec_pop_back + // @35 + pop + copy_loc l2 + vec_pop_back + pop + move_loc l2 + // @40 + pop + move_loc l0 + vec_unpack , 0 + ret -task 0 'print-bytecode'. lines 1-31: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: vector -L1: loc1: &vector -L2: loc2: &mut vector -L3: loc3: u64 -L4: loc4: &u64 -L5: loc5: &mut u64 -B0: - 0: VecPack(2, 0) - 1: StLoc[0](loc0: vector) - 2: ImmBorrowLoc[0](loc0: vector) - 3: StLoc[1](loc1: &vector) - 4: CopyLoc[1](loc1: &vector) - 5: VecLen(2) - 6: StLoc[3](loc3: u64) - 7: MoveLoc[1](loc1: &vector) - 8: Pop - 9: MutBorrowLoc[0](loc0: vector) - 10: StLoc[2](loc2: &mut vector) - 11: CopyLoc[2](loc2: &mut vector) - 12: LdU64(0) - 13: VecPushBack(2) - 14: CopyLoc[2](loc2: &mut vector) - 15: LdU64(1) - 16: VecPushBack(2) - 17: CopyLoc[2](loc2: &mut vector) - 18: LdU64(0) - 19: VecImmBorrow(2) - 20: StLoc[4](loc4: &u64) - 21: MoveLoc[4](loc4: &u64) - 22: Pop - 23: CopyLoc[2](loc2: &mut vector) - 24: LdU64(1) - 25: VecMutBorrow(2) - 26: StLoc[5](loc5: &mut u64) - 27: MoveLoc[5](loc5: &mut u64) - 28: Pop - 29: CopyLoc[2](loc2: &mut vector) - 30: LdU64(0) - 31: LdU64(1) - 32: VecSwap(2) - 33: CopyLoc[2](loc2: &mut vector) - 34: VecPopBack(2) - 35: Pop - 36: CopyLoc[2](loc2: &mut vector) - 37: VecPopBack(2) - 38: Pop - 39: MoveLoc[2](loc2: &mut vector) - 40: Pop - 41: MoveLoc[0](loc0: vector) - 42: VecUnpack(2, 0) - 43: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/combined.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/combined.exp index 343d5404e5f..2413567c92b 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/combined.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/combined.exp @@ -1,27 +1,26 @@ processed 1 task +task 0 lines 1-11: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + local l1: u64 + local l2: u64 + ld_u64 3 + st_loc l0 + ld_u64 5 + st_loc l1 + move_loc l0 + // @5 + copy_loc l1 + ld_u64 5 + mul + add + copy_loc l1 + // @10 + sub + st_loc l2 + ret -task 0 'print-bytecode'. lines 1-11: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: u64 -L1: loc1: u64 -L2: loc2: u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: LdU64(5) - 3: StLoc[1](loc1: u64) - 4: MoveLoc[0](loc0: u64) - 5: CopyLoc[1](loc1: u64) - 6: LdU64(5) - 7: Mul - 8: Add - 9: CopyLoc[1](loc1: u64) - 10: Sub - 11: StLoc[2](loc2: u64) - 12: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/pack.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/pack.exp index e7392842b7c..5da16925230 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/pack.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/pack.exp @@ -1,22 +1,18 @@ processed 3 tasks +task 0 lines 1-9: print-bytecode --input=module [module 0x2d20.M {] +// Bytecode version v8 +module 0x2d20::M +struct T + u: u64 -task 0 'print-bytecode'. lines 1-9: -// Move bytecode v7 -module 2d20.M { -struct T { - u: u64 -} +// Function definition at index 0 +fun f(): T + ld_u64 0 + pack T + ret -f(): T /* def_idx: 0 */ { -B0: - 0: LdU64(0) - 1: Pack[0](T) - 2: Ret -} -} -task 1 'print-bytecode'. lines 11-20: +task 1 lines 11-20: print-bytecode --input=module [module 0x3d20.M {] Error: Unbound field x - -task 2 'print-bytecode'. lines 22-31: +task 2 lines 22-31: print-bytecode --input=module [module 0x4d20.M {] Error: Field y defined out of order for struct T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/unpack.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/unpack.exp index 7ccc23f50db..806a425c4c2 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/unpack.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/expressions/unpack.exp @@ -1,30 +1,29 @@ processed 3 tasks +task 0 lines 1-18: print-bytecode --input=module [module 0x1d12.M {] +// Bytecode version v8 +module 0x1d12::M +struct T + b: bool -task 0 'print-bytecode'. lines 1-18: -// Move bytecode v7 -module 1d12.M { -struct T { - b: bool -} +// Function definition at index 0 +fun new(): T + ld_true + pack T + ret -new(): T /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: Pack[0](T) - 2: Ret -} -f() /* def_idx: 1 */ { -L0: loc0: T -L1: loc1: bool -B0: - 0: Call new(): T - 1: StLoc[0](loc0: T) - 2: MoveLoc[0](loc0: T) - 3: Unpack[0](T) - 4: StLoc[1](loc1: bool) - 5: Ret -} -} +// Function definition at index 1 +fun f() + local l0: T + local l1: bool + call new + st_loc l0 + move_loc l0 + unpack T + st_loc l1 + // @5 + ret -task 2 'print-bytecode'. lines 31-44: + +task 1 lines 20-28: publish [module 0x2d12.M {] +task 2 lines 31-44: print-bytecode --input=module [// An unpack expression cannot reference a struct type defined in a separate module.] Error: Missing struct definition for T diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assert.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assert.exp index 0366257f0d1..9392d3e2ed4 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assert.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assert.exp @@ -1,24 +1,20 @@ processed 1 task +task 0 lines 1-8: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 3 + st_loc l0 + copy_loc l0 + ld_u64 2 + gt + // @5 + not + br_false l0 + ld_u64 42 + abort +l0: ret -task 0 'print-bytecode'. lines 1-8: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(3) - 1: StLoc[0](loc0: u64) - 2: CopyLoc[0](loc0: u64) - 3: LdU64(2) - 4: Gt - 5: Not - 6: BrFalse(9) -B1: - 7: LdU64(42) - 8: Abort -B2: - 9: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assign.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assign.exp index 1842feb066e..b66b6de1cb1 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assign.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/assign.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'print-bytecode'. lines 1-7: +task 0 lines 1-7: print-bytecode [// Un-declared locals cannot be assigned to.] Error: variable x undefined diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump.exp index 379200d251a..1b39caa6279 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump.exp @@ -1,28 +1,20 @@ processed 3 tasks +task 0 lines 1-6: print-bytecode [// An endless loop is valid Move IR.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() +l0: branch l0 -task 0 'print-bytecode'. lines 1-6: -// Move bytecode v7 -script { +task 1 lines 8-15: print-bytecode [// Jumping to a label that is declared after the jump statement itself is valid.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() +l1: branch l0 +l0: branch l1 -main() /* def_idx: 0 */ { -B0: - 0: Branch(0) -} -} -task 1 'print-bytecode'. lines 8-15: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -B0: - 0: Branch(1) -B1: - 1: Branch(0) -} -} - -task 2 'print-bytecode'. lines 17-28: +task 2 lines 17-28: print-bytecode --input=module [// Jumping to a label that isn't declared in the same function is invalid.] Error: Invalid block labels, labels were used without being declared (bar) diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if.exp index 06ec31e3147..029538a7918 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if.exp @@ -1,110 +1,91 @@ processed 4 tasks +task 0 lines 1-22: print-bytecode [// This is roughly equivalent to the following Move program:] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 42 + ld_u64 0 + gt + br_true l0 + branch l1 + // @5 +l0: ld_u64 1 + st_loc l0 + branch l2 +l1: ld_u64 2 + st_loc l0 + // @10 + branch l2 +l2: ret -task 0 'print-bytecode'. lines 1-22: -// Move bytecode v7 -script { +task 1 lines 24-41: print-bytecode [// This is roughly equivalent to the following Move program:] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 42 + ld_u64 0 + gt + br_true l0 + ld_u64 2 + // @5 + st_loc l0 + branch l1 +l0: ld_u64 1 + st_loc l0 +l1: ret -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(42) - 1: LdU64(0) - 2: Gt - 3: BrTrue(5) -B1: - 4: Branch(8) -B2: - 5: LdU64(1) - 6: StLoc[0](loc0: u64) - 7: Branch(11) -B3: - 8: LdU64(2) - 9: StLoc[0](loc0: u64) - 10: Branch(11) -B4: - 11: Ret -} -} -task 1 'print-bytecode'. lines 24-41: -// Move bytecode v7 -script { +task 2 lines 43-59: print-bytecode [// `jump_if` statements can be sequenced, akin to "nested" `if` statements in Move.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 0 + ld_u64 1 + lt + br_true l0 + ld_u64 0 + // @5 + st_loc l0 + branch l1 +l0: ld_u64 2 + ld_u64 1 + gt + // @10 + br_true l2 + ld_u64 1 + st_loc l0 + branch l1 +l2: ld_u64 2 + // @15 + st_loc l0 +l1: ret -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(42) - 1: LdU64(0) - 2: Gt - 3: BrTrue(7) -B1: - 4: LdU64(2) - 5: StLoc[0](loc0: u64) - 6: Branch(9) -B2: - 7: LdU64(1) - 8: StLoc[0](loc0: u64) -B3: - 9: Ret -} -} +task 3 lines 61-74: print-bytecode [// `return` statements can appear anywhere, including within a jump destination's block.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 0 + ld_u64 1 + neq + br_true l0 + ld_u64 1 + // @5 + st_loc l0 + branch l1 +l0: ld_u64 2 + st_loc l0 + ret + // @10 +l1: ret -task 2 'print-bytecode'. lines 43-59: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(0) - 1: LdU64(1) - 2: Lt - 3: BrTrue(7) -B1: - 4: LdU64(0) - 5: StLoc[0](loc0: u64) - 6: Branch(16) -B2: - 7: LdU64(2) - 8: LdU64(1) - 9: Gt - 10: BrTrue(14) -B3: - 11: LdU64(1) - 12: StLoc[0](loc0: u64) - 13: Branch(16) -B4: - 14: LdU64(2) - 15: StLoc[0](loc0: u64) -B5: - 16: Ret -} -} - -task 3 'print-bytecode'. lines 61-74: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(0) - 1: LdU64(1) - 2: Neq - 3: BrTrue(7) -B1: - 4: LdU64(1) - 5: StLoc[0](loc0: u64) - 6: Branch(10) -B2: - 7: LdU64(2) - 8: StLoc[0](loc0: u64) - 9: Ret -B3: - 10: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp index e34f5c89367..0822c076b1c 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/jump_if_false.exp @@ -1,84 +1,62 @@ processed 4 tasks +task 0 lines 1-18: print-bytecode [// This is roughly equivalent to the following Move program:] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 0 + st_loc l0 +l1: copy_loc l0 + ld_u64 5 + lt + // @5 + br_false l0 + copy_loc l0 + ld_u64 1 + add + st_loc l0 + // @10 + branch l1 +l0: ret + + +task 1 lines 20-32: print-bytecode [// `return` statements can appear anywhere, even within a loop.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + local l0: u64 + ld_u64 0 + st_loc l0 +l1: ld_true + br_false l0 + ret + // @5 + branch l1 +l0: ret + + +task 2 lines 34-42: print-bytecode [// This is roughly equivalent to the following Move code: `while (true) { break; }`.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ld_true + br_false l0 + branch l0 +l0: ret + + +task 3 lines 44-55: print-bytecode [// This is roughly equivalent to the following Move code: `loop { loop { break; } break; }`.] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() +l1: branch l0 + branch l1 +l0: branch l2 + branch l1 +l2: ret -task 0 'print-bytecode'. lines 1-18: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](loc0: u64) -B1: - 2: CopyLoc[0](loc0: u64) - 3: LdU64(5) - 4: Lt - 5: BrFalse(11) -B2: - 6: CopyLoc[0](loc0: u64) - 7: LdU64(1) - 8: Add - 9: StLoc[0](loc0: u64) - 10: Branch(2) -B3: - 11: Ret -} -} - -task 1 'print-bytecode'. lines 20-32: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -L0: loc0: u64 -B0: - 0: LdU64(0) - 1: StLoc[0](loc0: u64) -B1: - 2: LdTrue - 3: BrFalse(6) -B2: - 4: Ret -B3: - 5: Branch(2) -B4: - 6: Ret -} -} - -task 2 'print-bytecode'. lines 34-42: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -B0: - 0: LdTrue - 1: BrFalse(3) -B1: - 2: Branch(3) -B2: - 3: Ret -} -} - -task 3 'print-bytecode'. lines 44-55: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -B0: - 0: Branch(2) -B1: - 1: Branch(0) -B2: - 2: Branch(4) -B3: - 3: Branch(0) -B4: - 4: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/nop.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/nop.exp index ea5c19403dd..942c04baf4e 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/nop.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/statements/nop.exp @@ -1,19 +1,16 @@ processed 1 task +task 0 lines 1-14: print-bytecode --input=module [module 0xcafe.Nop {] +// Bytecode version v8 +module 0xcafe::Nop +// Function definition at index 0 +fun nop_valid() + nop + ret -task 0 'print-bytecode'. lines 1-14: -// Move bytecode v7 -module cafe.Nop { +// Function definition at index 1 +fun nop_invalid() + nop + pop + ret -nop_valid() /* def_idx: 0 */ { -B0: - 0: Nop - 1: Ret -} -nop_invalid() /* def_idx: 1 */ { -B0: - 0: Nop - 1: Pop - 2: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/types/struct.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/types/struct.exp index 9b676c8f151..17f702befb9 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/types/struct.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/bytecode-generation/types/struct.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'print-bytecode'. lines 1-8: +task 0 lines 1-8: print-bytecode --input=module [// Module names cannot be used as types.] Error: Unbound struct Self.M diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/comments.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/comments.exp index d39d20db11c..2258f071c79 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/comments.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/comments.exp @@ -1,59 +1,43 @@ processed 6 tasks +task 0 lines 1-6: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -task 0 'print-bytecode'. lines 1-6: -// Move bytecode v7 -script { +task 1 lines 8-14: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} -task 1 'print-bytecode'. lines 8-14: -// Move bytecode v7 -script { +task 2 lines 16-20: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} +task 3 lines 22-27: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -task 2 'print-bytecode'. lines 16-20: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} - -task 3 'print-bytecode'. lines 22-27: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} - -task 4 'print-bytecode'. lines 29-36: +task 4 lines 29-36: print-bytecode [// In Move, /* */ are block comment delimiters. Not so in Move IR, so the `/*` below] Error: ParserError: Invalid Token: invalid token kind for statement Slash - -task 5 'print-bytecode'. lines 38-46: -// Move bytecode v7 -script { +task 5 lines 38-46: print-bytecode [// Since /* */ are not block comment delimiters, they do not behave in any unique way when] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/crlf.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/crlf.exp index d39d20db11c..2258f071c79 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/crlf.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/crlf.exp @@ -1,59 +1,43 @@ processed 6 tasks +task 0 lines 1-6: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -task 0 'print-bytecode'. lines 1-6: -// Move bytecode v7 -script { +task 1 lines 8-14: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} -task 1 'print-bytecode'. lines 8-14: -// Move bytecode v7 -script { +task 2 lines 16-20: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} +task 3 lines 22-27: print-bytecode [main() {] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -task 2 'print-bytecode'. lines 16-20: -// Move bytecode v7 -script { - -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} - -task 3 'print-bytecode'. lines 22-27: -// Move bytecode v7 -script { - - -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} - -task 4 'print-bytecode'. lines 29-36: +task 4 lines 29-36: print-bytecode [// In Move, /* */ are block comment delimiters. Not so in Move IR, so the `/*` below] Error: ParserError: Invalid Token: invalid token kind for statement Slash - -task 5 'print-bytecode'. lines 38-46: -// Move bytecode v7 -script { +task 5 lines 38-46: print-bytecode [// Since /* */ are not block comment delimiters, they do not behave in any unique way when] +// Bytecode version v8 +script +// Function definition at index 0 +entry public fun main() + ret -main() /* def_idx: 0 */ { -B0: - 0: Ret -} -} diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/keywords.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/keywords.exp index 356f8e6040c..06a281c737b 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/keywords.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/keywords.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'print-bytecode'. lines 1-6: +task 0 lines 1-6: print-bytecode [// `label` is a keyword so it cannot be used as a parameter name.] Error: ParserError: Invalid Token: expected Tok::NameValue diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/structs.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/structs.exp index 4702e5335b9..1a711e5d0f6 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/structs.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/structs.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'print-bytecode'. lines 1-13: +task 0 lines 1-13: print-bytecode --input=module [// A struct declaration cannot contain function declarations (like the syntax for declaring] Error: ParserError: Invalid Token: expected Colon, not LParen diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/types.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/types.exp index 918a06670c7..54b83fb9421 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/types.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/parsing/types.exp @@ -1,19 +1,13 @@ processed 6 tasks - -task 0 'print-bytecode'. lines 1-7: +task 0 lines 1-7: print-bytecode [// The `borrow_global` builtin is followed by a list of type actuals, and these cannot be qualified] Error: ParserError: Invalid Token: expected Tok::NameValue - -task 1 'print-bytecode'. lines 9-14: +task 1 lines 9-14: print-bytecode [// `borrow_global_mut` types must not be qualified.] Error: ParserError: Invalid Token: expected Tok::NameValue - -task 2 'print-bytecode'. lines 16-21: +task 2 lines 16-21: print-bytecode [// `move_to` types must not be qualified.] Error: ParserError: Invalid Token: expected Tok::NameValue - -task 3 'print-bytecode'. lines 23-28: +task 3 lines 23-28: print-bytecode [// `exists` types must not be qualified.] Error: ParserError: Invalid Token: expected Tok::NameValue - -task 4 'print-bytecode'. lines 30-35: +task 4 lines 30-35: print-bytecode [// Struct field specifiers in immutable borrows must not be qualified.] Error: ParserError: Invalid Token: expected Tok::NameValue - -task 5 'print-bytecode'. lines 37-42: +task 5 lines 37-42: print-bytecode [// Struct field specifiers in mutable borrows must not be qualified.] Error: ParserError: Invalid Token: expected Tok::NameValue diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/specification/conditions.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/specification/conditions.exp index b134af1aea2..d1d771a70e8 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/specification/conditions.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/specification/conditions.exp @@ -1 +1,5 @@ processed 5 tasks +task 1 lines 9-88: publish [module 0x1.TestConditions {] +task 2 lines 89-165: publish [module 0x1.TestSpecExp {] +task 3 lines 166-210: publish [module 0x1.TestEnsuresAccessPath {] +task 4 lines 212-265: publish [module 0x1.TestBinaryOps {] diff --git a/third_party/move/move-ir-compiler/transactional-tests/tests/specification/invariants.exp b/third_party/move/move-ir-compiler/transactional-tests/tests/specification/invariants.exp index 5d92c423f3f..a1b9d8cd9a8 100644 --- a/third_party/move/move-ir-compiler/transactional-tests/tests/specification/invariants.exp +++ b/third_party/move/move-ir-compiler/transactional-tests/tests/specification/invariants.exp @@ -1 +1,2 @@ processed 2 tasks +task 1 lines 5-28: publish [module 0x1.TestInvariants {] diff --git a/third_party/move/move-ir/types/Cargo.toml b/third_party/move/move-ir/types/Cargo.toml index 9b040edc45b..eb4f446f93a 100644 --- a/third_party/move/move-ir/types/Cargo.toml +++ b/third_party/move/move-ir/types/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/third_party/move/move-ir/types/src/ast.rs b/third_party/move/move-ir/types/src/ast.rs index 4718cf90841..5f3f85cb927 100644 --- a/third_party/move/move-ir/types/src/ast.rs +++ b/third_party/move/move-ir/types/src/ast.rs @@ -7,7 +7,7 @@ use crate::{ spec_language_ast::{Condition, Invariant, SyntheticDefinition}, }; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId, + account_address::AccountAddress, identifier::Identifier, int256, language_storage::ModuleId, value::MoveValue, }; use move_symbol_pool::Symbol; @@ -17,7 +17,6 @@ use std::{ collections::{BTreeSet, HashSet, VecDeque}, fmt, }; - //************************************************************************************************** // Program //************************************************************************************************** @@ -535,7 +534,7 @@ pub enum CopyableVal_ { /// An unsigned 128-bit integer U128(u128), /// An unsigned 256-bit integer - U256(move_core_types::u256::U256), + U256(int256::U256), /// true or false Bool(bool), /// `b""` @@ -671,7 +670,7 @@ pub enum Bytecode_ { LdU32(u32), LdU64(u64), LdU128(u128), - LdU256(move_core_types::u256::U256), + LdU256(int256::U256), CastU8, CastU16, CastU32, @@ -1358,10 +1357,7 @@ impl fmt::Display for ConstantName { impl fmt::Display for FunctionBody { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - FunctionBody::Move { - ref locals, - ref code, - } => { + FunctionBody::Move { locals, code } => { for (local, ty) in locals { write!(f, "let {}: {};", local, ty)?; } @@ -1813,5 +1809,11 @@ fn format_move_value(v: &MoveValue) -> String { MoveValue::U16(u) => format!("{}u16", u), MoveValue::U32(u) => format!("{}u32", u), MoveValue::U256(u) => format!("{}u256", u), + MoveValue::I8(u) => format!("{}i8", u), + MoveValue::I16(u) => format!("{}i16", u), + MoveValue::I32(u) => format!("{}i32", u), + MoveValue::I64(u) => format!("{}i64", u), + MoveValue::I128(u) => format!("{}i128", u), + MoveValue::I256(u) => format!("{}i256", u), } } diff --git a/third_party/move/move-model/Cargo.toml b/third_party/move/move-model/Cargo.toml index d4170ff84d9..b847d5e1818 100644 --- a/third_party/move/move-model/Cargo.toml +++ b/third_party/move/move-model/Cargo.toml @@ -3,7 +3,7 @@ name = "move-model" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] @@ -15,11 +15,11 @@ internment = { workspace = true, features = ["arc"] } itertools = { workspace = true } legacy-move-compiler = { workspace = true } log = { workspace = true } +move-asm = { workspace = true } move-binary-format = { workspace = true } move-bytecode-source-map = { workspace = true } move-command-line-common = { workspace = true } move-core-types = { workspace = true } -move-disassembler = { workspace = true } move-ir-types = { workspace = true } move-symbol-pool = { workspace = true } num = { workspace = true } diff --git a/third_party/move/move-model/bytecode-test-utils/Cargo.toml b/third_party/move/move-model/bytecode-test-utils/Cargo.toml index b6c1335a536..f305da67c83 100644 --- a/third_party/move/move-model/bytecode-test-utils/Cargo.toml +++ b/third_party/move/move-model/bytecode-test-utils/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-model/bytecode/Cargo.toml b/third_party/move/move-model/bytecode/Cargo.toml index 8770e6f4b98..d4e30b62693 100644 --- a/third_party/move/move-model/bytecode/Cargo.toml +++ b/third_party/move/move-model/bytecode/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] abstract-domain-derive = { path = "./abstract_domain_derive" } diff --git a/third_party/move/move-model/bytecode/abstract_domain_derive/Cargo.toml b/third_party/move/move-model/bytecode/abstract_domain_derive/Cargo.toml index 2c183c63884..4bbb0e35fd7 100644 --- a/third_party/move/move-model/bytecode/abstract_domain_derive/Cargo.toml +++ b/third_party/move/move-model/bytecode/abstract_domain_derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "abstract-domain-derive" version = "0.1.0" -edition = "2021" +edition = { workspace = true } license = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/Cargo.toml b/third_party/move/move-model/bytecode/ast-generator-tests/Cargo.toml index 984877d3123..b1c6b23cc52 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/Cargo.toml +++ b/third_party/move/move-model/bytecode/ast-generator-tests/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "move-ast-generator-tests" version = "0.1.0" -edition = "2021" +edition = { workspace = true } license = { workspace = true } [dev-dependencies] diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp index bd030fe1556..106a6367222 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp @@ -83,15 +83,18 @@ loop { _t8: u64 = 0; _t1: u64 = _t8; loop { - _t9: u64 = _t1; - _t10: u64 = length; - _t11: bool = Lt(_t9, _t10); - if (Not(_t11)) break; - _t12: u64 = _t1; - _t13: u64 = 1; - _t14: u64 = Add(_t12, _t13); - _t1: u64 = _t14; - continue + loop { + _t9: u64 = _t1; + _t10: u64 = length; + _t11: bool = Lt(_t9, _t10); + if (Not(_t11)) break[1]; + _t12: u64 = _t1; + _t13: u64 = 1; + _t14: u64 = Add(_t12, _t13); + _t1: u64 = _t14; + continue + }; + break }; _t15: u64 = _t1; return _t15 @@ -107,9 +110,12 @@ loop { }; _t1: u64 = 0; loop { - if (Not(Lt(_t1, length))) break; - _t1: u64 = Add(_t1, 1); - continue + loop { + if (Not(Lt(_t1, length))) break[1]; + _t1: u64 = Add(_t1, 1); + continue + }; + break }; return _t1 @@ -125,11 +131,10 @@ loop { return _t1 --- Var-Bound Generated AST +if (Not(Gt(length, 0))) Abort(1); +if (Not(Lt(length, 100))) Abort(2); { - let _t1: u64; - if (Not(Gt(length, 0))) Abort(1); - if (Not(Lt(length, 100))) Abort(2); - _t1: u64 = 0; + let _t1: u64 = 0; loop { if (Not(Lt(_t1, length))) break; _t1: u64 = Add(_t1, 1); @@ -141,11 +146,10 @@ return _t1 === Sourcified Output ============================================ module 0x815::m { public fun f(length: u64): u64 { - let _t1; - if (!(length > 0)) abort 1; - if (!(length < 100)) abort 2; - _t1 = 0; - while (_t1 < length) _t1 = _t1 + 1; - _t1 + assert!(length > 0, 1); + assert!(length < 100, 2); + let _v0 = 0; + while (_v0 < length) _v0 = _v0 + 1; + _v0 } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp index 381f6d03f0c..9505bdc9b06 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp @@ -60,19 +60,29 @@ _t11: bool = Deref(_t10); return _t11 --- Assign-Transformed Generated AST +_t5: u64 = vector::length(select m::BitVector.bit_field(self)); loop { - if (Lt(bit_index, vector::length(select m::BitVector.bit_field(self)))) break; + if (Lt(bit_index, _t5)) break; Abort(131072) }; -return Deref(vector::borrow(select m::BitVector.bit_field(self), bit_index)) +_t8: &vector = select m::BitVector.bit_field(self); +return Deref(vector::borrow(_t8, bit_index)) --- If-Transformed Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -return Deref(vector::borrow(select m::BitVector.bit_field(self), bit_index)) +_t5: u64 = vector::length(select m::BitVector.bit_field(self)); +if (Not(Lt(bit_index, _t5))) Abort(131072); +_t8: &vector = select m::BitVector.bit_field(self); +return Deref(vector::borrow(_t8, bit_index)) --- Var-Bound Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -return Deref(vector::borrow(select m::BitVector.bit_field(self), bit_index)) +{ + let _t5: u64 = vector::length(select m::BitVector.bit_field(self)); + if (Not(Lt(bit_index, _t5))) Abort(131072); + { + let _t8: &vector = select m::BitVector.bit_field(self); + return Deref(vector::borrow(_t8, bit_index)) + } +} === Processing m::set ===================================================== @@ -146,22 +156,37 @@ _t14 = _t13; return Tuple() --- Assign-Transformed Generated AST +_t7: u64 = vector::length(select m::BitVector.bit_field(self)); loop { - if (Lt(bit_index, vector::length(select m::BitVector.bit_field(self)))) break; + if (Lt(bit_index, _t7)) break; Abort(131072) }; -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = true; +_t10: &mut vector = select m::BitVector.bit_field(self); +_t3: &mut bool = vector::borrow_mut(_t10, bit_index); +_t3 = true; return Tuple() --- If-Transformed Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = true; +_t7: u64 = vector::length(select m::BitVector.bit_field(self)); +if (Not(Lt(bit_index, _t7))) Abort(131072); +_t10: &mut vector = select m::BitVector.bit_field(self); +_t3: &mut bool = vector::borrow_mut(_t10, bit_index); +_t3 = true; return Tuple() --- Var-Bound Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = true; -return Tuple() +{ + let _t7: u64 = vector::length(select m::BitVector.bit_field(self)); + if (Not(Lt(bit_index, _t7))) Abort(131072); + { + let _t10: &mut vector = select m::BitVector.bit_field(self); + { + let _t3: &mut bool = vector::borrow_mut(_t10, bit_index); + _t3 = true; + return Tuple() + } + } +} === Processing m::shift_left ===================================================== @@ -259,7 +284,7 @@ public fun m::shift_left($t0|self: &mut 0x1::m::BitVector, $t1|amount: u64) { 2: $t8 := borrow_field<0x1::m::BitVector>.length($t7) 3: $t9 := read_ref($t8) 4: $t10 := >=($t6, $t9) - 5: if ($t10) goto 6 else goto 39 + 5: if ($t10) goto 6 else goto 37 6: label L1 7: $t11 := move($t0) 8: $t12 := borrow_field<0x1::m::BitVector>.bit_field($t11) @@ -290,74 +315,72 @@ public fun m::shift_left($t0|self: &mut 0x1::m::BitVector, $t1|amount: u64) { 33: label L2 34: $t27 := move($t2) 35: drop($t27) - 36: goto 37 - 37: label L14 - 38: return () - 39: label L0 - 40: $t28 := copy($t1) - 41: $t3 := $t28 - 42: goto 43 - 43: label L9 - 44: $t29 := copy($t3) - 45: $t30 := copy($t0) - 46: $t31 := borrow_field<0x1::m::BitVector>.length($t30) - 47: $t32 := read_ref($t31) - 48: $t33 := <($t29, $t32) - 49: if ($t33) goto 50 else goto 76 - 50: label L6 - 51: $t34 := copy($t0) - 52: $t35 := freeze_ref($t34) - 53: $t36 := copy($t3) - 54: $t37 := m::is_index_set($t35, $t36) - 55: if ($t37) goto 56 else goto 69 - 56: label L8 - 57: $t38 := copy($t0) - 58: $t39 := copy($t3) - 59: $t40 := copy($t1) - 60: $t41 := -($t39, $t40) - 61: m::set($t38, $t41) - 62: goto 63 - 63: label L10 - 64: $t42 := move($t3) - 65: $t43 := 1 - 66: $t44 := +($t42, $t43) - 67: $t3 := $t44 - 68: goto 43 - 69: label L7 - 70: $t45 := copy($t0) - 71: $t46 := copy($t3) - 72: $t47 := copy($t1) - 73: $t48 := -($t46, $t47) - 74: m::unset($t45, $t48) - 75: goto 63 - 76: label L5 - 77: $t49 := copy($t0) - 78: $t50 := borrow_field<0x1::m::BitVector>.length($t49) - 79: $t51 := read_ref($t50) - 80: $t52 := move($t1) - 81: $t53 := -($t51, $t52) - 82: $t3 := $t53 - 83: goto 84 - 84: label L13 - 85: $t54 := copy($t3) - 86: $t55 := copy($t0) - 87: $t56 := borrow_field<0x1::m::BitVector>.length($t55) - 88: $t57 := read_ref($t56) - 89: $t58 := <($t54, $t57) - 90: if ($t58) goto 91 else goto 100 - 91: label L12 - 92: $t59 := copy($t0) - 93: $t60 := copy($t3) - 94: m::unset($t59, $t60) - 95: $t61 := move($t3) - 96: $t62 := 1 - 97: $t63 := +($t61, $t62) - 98: $t3 := $t63 - 99: goto 84 -100: label L11 -101: $t64 := move($t0) -102: drop($t64) -103: goto 37 + 36: return () + 37: label L0 + 38: $t28 := copy($t1) + 39: $t3 := $t28 + 40: goto 41 + 41: label L9 + 42: $t29 := copy($t3) + 43: $t30 := copy($t0) + 44: $t31 := borrow_field<0x1::m::BitVector>.length($t30) + 45: $t32 := read_ref($t31) + 46: $t33 := <($t29, $t32) + 47: if ($t33) goto 48 else goto 74 + 48: label L6 + 49: $t34 := copy($t0) + 50: $t35 := freeze_ref($t34) + 51: $t36 := copy($t3) + 52: $t37 := m::is_index_set($t35, $t36) + 53: if ($t37) goto 54 else goto 67 + 54: label L8 + 55: $t38 := copy($t0) + 56: $t39 := copy($t3) + 57: $t40 := copy($t1) + 58: $t41 := -($t39, $t40) + 59: m::set($t38, $t41) + 60: goto 61 + 61: label L10 + 62: $t42 := move($t3) + 63: $t43 := 1 + 64: $t44 := +($t42, $t43) + 65: $t3 := $t44 + 66: goto 41 + 67: label L7 + 68: $t45 := copy($t0) + 69: $t46 := copy($t3) + 70: $t47 := copy($t1) + 71: $t48 := -($t46, $t47) + 72: m::unset($t45, $t48) + 73: goto 61 + 74: label L5 + 75: $t49 := copy($t0) + 76: $t50 := borrow_field<0x1::m::BitVector>.length($t49) + 77: $t51 := read_ref($t50) + 78: $t52 := move($t1) + 79: $t53 := -($t51, $t52) + 80: $t3 := $t53 + 81: goto 82 + 82: label L13 + 83: $t54 := copy($t3) + 84: $t55 := copy($t0) + 85: $t56 := borrow_field<0x1::m::BitVector>.length($t55) + 86: $t57 := read_ref($t56) + 87: $t58 := <($t54, $t57) + 88: if ($t58) goto 89 else goto 98 + 89: label L12 + 90: $t59 := copy($t0) + 91: $t60 := copy($t3) + 92: m::unset($t59, $t60) + 93: $t61 := move($t3) + 94: $t62 := 1 + 95: $t63 := +($t61, $t62) + 96: $t3 := $t63 + 97: goto 82 + 98: label L11 + 99: $t64 := move($t0) +100: drop($t64) +101: return () } --- Raw Generated AST @@ -370,230 +393,289 @@ loop { loop { loop { loop { - if (Not(_t10)) break; - _t11: &mut BitVector = self; - _t12: &mut vector = select m::BitVector.bit_field(_t11); - _t2: &mut vector = _t12; - _t13: u64 = 0; - _t3: u64 = _t13; + loop { + if (Not(_t10)) break; + _t11: &mut BitVector = self; + _t12: &mut vector = select m::BitVector.bit_field(_t11); + _t2: &mut vector = _t12; + _t13: u64 = 0; + _t3: u64 = _t13; + break[1] + }; + _t28: u64 = amount; + _t3: u64 = _t28; break[1] }; - _t28: u64 = amount; - _t3: u64 = _t28; - break[1] - }; - loop { - _t14: u64 = _t3; - _t15: &mut vector = _t2; - _t16: &vector = Freeze(true)(_t15); - _t17: u64 = vector::length(_t16); - _t18: bool = Lt(_t14, _t17); - if (Not(_t18)) break; - _t19: &mut vector = _t2; - _t20: u64 = _t3; - _t21: &mut bool = vector::borrow_mut(_t19, _t20); - _t5: &mut bool = _t21; - _t22: bool = false; - _t23: &mut bool = _t5; - _t23 = _t22; - _t24: u64 = _t3; - _t25: u64 = 1; - _t26: u64 = Add(_t24, _t25); - _t3: u64 = _t26; - continue + loop { + _t14: u64 = _t3; + _t15: &mut vector = _t2; + _t16: &vector = Freeze(true)(_t15); + _t17: u64 = vector::length(_t16); + _t18: bool = Lt(_t14, _t17); + if (Not(_t18)) break[2]; + _t19: &mut vector = _t2; + _t20: u64 = _t3; + _t21: &mut bool = vector::borrow_mut(_t19, _t20); + _t5: &mut bool = _t21; + _t22: bool = false; + _t23: &mut bool = _t5; + _t23 = _t22; + _t24: u64 = _t3; + _t25: u64 = 1; + _t26: u64 = Add(_t24, _t25); + _t3: u64 = _t26; + continue + }; + break }; - _t27: &mut vector = _t2; - break[1] - }; - loop { - _t29: u64 = _t3; - _t30: &mut BitVector = self; - _t31: &u64 = select m::BitVector.length(_t30); - _t32: u64 = Deref(_t31); - _t33: bool = Lt(_t29, _t32); - if (Not(_t33)) break; - _t34: &mut BitVector = self; - _t35: &BitVector = Freeze(true)(_t34); - _t36: u64 = _t3; - _t37: bool = m::is_index_set(_t35, _t36); loop { loop { - if (Not(_t37)) break; - _t38: &mut BitVector = self; - _t39: u64 = _t3; - _t40: u64 = amount; - _t41: u64 = Sub(_t39, _t40); - m::set(_t38, _t41); - break[1] + _t29: u64 = _t3; + _t30: &mut BitVector = self; + _t31: &u64 = select m::BitVector.length(_t30); + _t32: u64 = Deref(_t31); + _t33: bool = Lt(_t29, _t32); + if (Not(_t33)) break[1]; + _t34: &mut BitVector = self; + _t35: &BitVector = Freeze(true)(_t34); + _t36: u64 = _t3; + _t37: bool = m::is_index_set(_t35, _t36); + loop { + loop { + if (Not(_t37)) break; + _t38: &mut BitVector = self; + _t39: u64 = _t3; + _t40: u64 = amount; + _t41: u64 = Sub(_t39, _t40); + m::set(_t38, _t41); + break[1] + }; + _t45: &mut BitVector = self; + _t46: u64 = _t3; + _t47: u64 = amount; + _t48: u64 = Sub(_t46, _t47); + m::unset(_t45, _t48); + break + }; + _t42: u64 = _t3; + _t43: u64 = 1; + _t44: u64 = Add(_t42, _t43); + _t3: u64 = _t44; + continue }; - _t45: &mut BitVector = self; - _t46: u64 = _t3; - _t47: u64 = amount; - _t48: u64 = Sub(_t46, _t47); - m::unset(_t45, _t48); break }; - _t42: u64 = _t3; - _t43: u64 = 1; - _t44: u64 = Add(_t42, _t43); - _t3: u64 = _t44; - continue - }; - _t49: &mut BitVector = self; - _t50: &u64 = select m::BitVector.length(_t49); - _t51: u64 = Deref(_t50); - _t52: u64 = amount; - _t53: u64 = Sub(_t51, _t52); - _t3: u64 = _t53; - loop { - _t54: u64 = _t3; - _t55: &mut BitVector = self; - _t56: &u64 = select m::BitVector.length(_t55); - _t57: u64 = Deref(_t56); - _t58: bool = Lt(_t54, _t57); - if (Not(_t58)) break; - _t59: &mut BitVector = self; - _t60: u64 = _t3; - m::unset(_t59, _t60); - _t61: u64 = _t3; - _t62: u64 = 1; - _t63: u64 = Add(_t61, _t62); - _t3: u64 = _t63; - continue + _t49: &mut BitVector = self; + _t50: &u64 = select m::BitVector.length(_t49); + _t51: u64 = Deref(_t50); + _t52: u64 = amount; + _t53: u64 = Sub(_t51, _t52); + _t3: u64 = _t53; + loop { + _t54: u64 = _t3; + _t55: &mut BitVector = self; + _t56: &u64 = select m::BitVector.length(_t55); + _t57: u64 = Deref(_t56); + _t58: bool = Lt(_t54, _t57); + if (Not(_t58)) break[2]; + _t59: &mut BitVector = self; + _t60: u64 = _t3; + m::unset(_t59, _t60); + _t61: u64 = _t3; + _t62: u64 = 1; + _t63: u64 = Add(_t61, _t62); + _t3: u64 = _t63; + continue + }; + break }; - _t64: &mut BitVector = self; - break + _t27: &mut vector = _t2; + return Tuple() }; +_t64: &mut BitVector = self; return Tuple() --- Assign-Transformed Generated AST +_t9: u64 = Deref(select m::BitVector.length(self)); loop { loop { loop { loop { - if (Not(Ge(amount, Deref(select m::BitVector.length(self))))) break; - _t2: &mut vector = select m::BitVector.bit_field(self); - _t3: u64 = 0; + loop { + if (Not(Ge(amount, _t9))) break; + _t2: &mut vector = select m::BitVector.bit_field(self); + _t3: u64 = 0; + break[1] + }; + _t3: u64 = amount; break[1] }; - _t3: u64 = amount; - break[1] - }; - loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; - _t3: u64 = Add(_t3, 1); - continue + loop { + _t17: u64 = vector::length(Freeze(true)(_t2)); + if (Not(Lt(_t3, _t17))) break[2]; + _t5: &mut bool = vector::borrow_mut(_t2, _t3); + _t5 = false; + _t3: u64 = Add(_t3, 1); + continue + }; + break }; - break[1] - }; - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; loop { loop { - if (Not(m::is_index_set(Freeze(true)(self), _t3))) break; - m::set(self, Sub(_t3, amount)); - break[1] + _t32: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t32))) break[1]; + _t35: &BitVector = Freeze(true)(self); + _t37: bool = m::is_index_set(_t35, _t3); + loop { + loop { + if (Not(_t37)) break; + _t41: u64 = Sub(_t3, amount); + m::set(self, _t41); + break[1] + }; + _t48: u64 = Sub(_t3, amount); + m::unset(self, _t48); + break + }; + _t3: u64 = Add(_t3, 1); + continue }; - m::unset(self, Sub(_t3, amount)); break }; - _t3: u64 = Add(_t3, 1); - continue - }; - _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue + _t51: u64 = Deref(select m::BitVector.length(self)); + _t3: u64 = Sub(_t51, amount); + loop { + _t57: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t57))) break[2]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue + }; + break }; - break + return Tuple() }; return Tuple() --- If-Transformed Generated AST +_t9: u64 = Deref(select m::BitVector.length(self)); loop { loop { - if Ge(amount, Deref(select m::BitVector.length(self))) { + if Ge(amount, _t9) { _t2: &mut vector = select m::BitVector.bit_field(self); - _t3: u64 = 0 + _t3: u64 = 0; + loop { + _t17: u64 = vector::length(Freeze(true)(_t2)); + if (Not(Lt(_t3, _t17))) break[1]; + _t5: &mut bool = vector::borrow_mut(_t2, _t3); + _t5 = false; + _t3: u64 = Add(_t3, 1); + continue + } } else { - _t3: u64 = amount; - break + _t3: u64 = amount }; loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; + _t32: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t32))) break; + _t35: &BitVector = Freeze(true)(self); + _t37: bool = m::is_index_set(_t35, _t3); + if _t37 { + _t41: u64 = Sub(_t3, amount); + m::set(self, _t41) + } else { + _t48: u64 = Sub(_t3, amount); + m::unset(self, _t48) + }; _t3: u64 = Add(_t3, 1); continue }; - break[1] - }; - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - if m::is_index_set(Freeze(true)(self), _t3) { - m::set(self, Sub(_t3, amount)) - } else { - m::unset(self, Sub(_t3, amount)) + _t51: u64 = Deref(select m::BitVector.length(self)); + _t3: u64 = Sub(_t51, amount); + loop { + _t57: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t57))) break[2]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue }; - _t3: u64 = Add(_t3, 1); - continue - }; - _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue + break }; - break + return Tuple() }; return Tuple() --- Var-Bound Generated AST { - let _t3: u64; - { - let _t2: &mut vector; + let _t9: u64 = Deref(select m::BitVector.length(self)); + loop { loop { - loop { - if Ge(amount, Deref(select m::BitVector.length(self))) { - _t2: &mut vector = select m::BitVector.bit_field(self); - _t3: u64 = 0 + { + let _t3: u64; + if Ge(amount, _t9) { + { + let _t2: &mut vector = select m::BitVector.bit_field(self); + _t3: u64 = 0; + loop { + { + let _t17: u64 = vector::length(Freeze(true)(_t2)); + if (Not(Lt(_t3, _t17))) break[1]; + { + let _t5: &mut bool = vector::borrow_mut(_t2, _t3); + _t5 = false; + _t3: u64 = Add(_t3, 1); + continue + } + } + } + } } else { - _t3: u64 = amount; - break + _t3: u64 = amount }; loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; - _t3: u64 = Add(_t3, 1); - continue - }; - break[1] - }; - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - if m::is_index_set(Freeze(true)(self), _t3) { - m::set(self, Sub(_t3, amount)) - } else { - m::unset(self, Sub(_t3, amount)) + { + let _t32: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t32))) break; + { + let _t35: &BitVector = Freeze(true)(self); + { + let _t37: bool = m::is_index_set(_t35, _t3); + if _t37 { + { + let _t41: u64 = Sub(_t3, amount); + m::set(self, _t41) + } + } else { + { + let _t48: u64 = Sub(_t3, amount); + m::unset(self, _t48) + } + }; + _t3: u64 = Add(_t3, 1); + continue + } + } + } }; - _t3: u64 = Add(_t3, 1); - continue - }; - _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); - loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue - }; - break + { + let _t51: u64 = Deref(select m::BitVector.length(self)); + _t3: u64 = Sub(_t51, amount); + loop { + { + let _t57: u64 = Deref(select m::BitVector.length(self)); + if (Not(Lt(_t3, _t57))) break[2]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue + } + }; + break + } + } }; return Tuple() - } + }; + return Tuple() } @@ -668,22 +750,37 @@ _t14 = _t13; return Tuple() --- Assign-Transformed Generated AST +_t7: u64 = vector::length(select m::BitVector.bit_field(self)); loop { - if (Lt(bit_index, vector::length(select m::BitVector.bit_field(self)))) break; + if (Lt(bit_index, _t7)) break; Abort(131072) }; -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = false; +_t10: &mut vector = select m::BitVector.bit_field(self); +_t3: &mut bool = vector::borrow_mut(_t10, bit_index); +_t3 = false; return Tuple() --- If-Transformed Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = false; +_t7: u64 = vector::length(select m::BitVector.bit_field(self)); +if (Not(Lt(bit_index, _t7))) Abort(131072); +_t10: &mut vector = select m::BitVector.bit_field(self); +_t3: &mut bool = vector::borrow_mut(_t10, bit_index); +_t3 = false; return Tuple() --- Var-Bound Generated AST -if (Not(Lt(bit_index, vector::length(select m::BitVector.bit_field(self))))) Abort(131072); -vector::borrow_mut(select m::BitVector.bit_field(self), bit_index) = false; -return Tuple() +{ + let _t7: u64 = vector::length(select m::BitVector.bit_field(self)); + if (Not(Lt(bit_index, _t7))) Abort(131072); + { + let _t10: &mut vector = select m::BitVector.bit_field(self); + { + let _t3: &mut bool = vector::borrow_mut(_t10, bit_index); + _t3 = false; + return Tuple() + } + } +} === Sourcified Output ============================================ module 0x1::m { @@ -692,45 +789,69 @@ module 0x1::m { bit_field: vector, } public fun is_index_set(self: &BitVector, bit_index: u64): bool { - if (!(bit_index < 0x1::vector::length(&self.bit_field))) abort 131072; - *0x1::vector::borrow(&self.bit_field, bit_index) + let _v0 = 0x1::vector::length(&self.bit_field); + assert!(bit_index < _v0, 131072); + let _v1 = &self.bit_field; + *0x1::vector::borrow(_v1, bit_index) } public fun set(self: &mut BitVector, bit_index: u64) { - if (!(bit_index < 0x1::vector::length(&self.bit_field))) abort 131072; - *0x1::vector::borrow_mut(&mut self.bit_field, bit_index) = true; + let _v0 = 0x1::vector::length(&self.bit_field); + assert!(bit_index < _v0, 131072); + let _v1 = &mut self.bit_field; + let _v2 = 0x1::vector::borrow_mut(_v1, bit_index); + *_v2 = true; } public fun shift_left(self: &mut BitVector, amount: u64) { - let _t3; - let _t2; - 'l0: loop { - loop { - if (amount >= *&self.length) { - _t2 = &mut self.bit_field; - _t3 = 0 - } else { - _t3 = amount; - break + let _v0 = *&self.length; + 'l1: loop { + 'l0: loop { + let _v1; + if (amount >= _v0) { + let _v2 = &mut self.bit_field; + _v1 = 0; + loop { + let _v3 = 0x1::vector::length(freeze(_v2)); + if (!(_v1 < _v3)) break 'l0; + let _v4 = 0x1::vector::borrow_mut(_v2, _v1); + *_v4 = false; + _v1 = _v1 + 1; + continue + } + } else _v1 = amount; + loop { + let _v5 = *&self.length; + if (!(_v1 < _v5)) break; + let _v6 = freeze(self); + let _v7 = is_index_set(_v6, _v1); + if (_v7) { + let _v8 = _v1 - amount; + set(self, _v8) + } else { + let _v9 = _v1 - amount; + unset(self, _v9) + }; + _v1 = _v1 + 1; + continue }; - while (_t3 < 0x1::vector::length(/*freeze*/_t2)) { - *0x1::vector::borrow_mut(_t2, _t3) = false; - _t3 = _t3 + 1 + let _v10 = *&self.length; + _v1 = _v10 - amount; + loop { + let _v11 = *&self.length; + if (!(_v1 < _v11)) break 'l1; + unset(self, _v1); + _v1 = _v1 + 1; + continue }; - break 'l0 - }; - while (_t3 < *&self.length) { - if (is_index_set(/*freeze*/self, _t3)) set(self, _t3 - amount) else unset(self, _t3 - amount); - _t3 = _t3 + 1 - }; - _t3 = *&self.length - amount; - while (_t3 < *&self.length) { - unset(self, _t3); - _t3 = _t3 + 1 + break }; - break + return () }; } public fun unset(self: &mut BitVector, bit_index: u64) { - if (!(bit_index < 0x1::vector::length(&self.bit_field))) abort 131072; - *0x1::vector::borrow_mut(&mut self.bit_field, bit_index) = false; + let _v0 = 0x1::vector::length(&self.bit_field); + assert!(bit_index < _v0, 131072); + let _v1 = &mut self.bit_field; + let _v2 = 0x1::vector::borrow_mut(_v1, bit_index); + *_v2 = false; } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp index e094abccf41..5159bfb59c8 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp @@ -58,8 +58,7 @@ return _t1 --- Var-Bound Generated AST { - let _t1: u8; - _t1: u8 = 0; + let _t1: u8 = 0; if (c) _t1: u8 = 1; return _t1 } @@ -73,72 +72,43 @@ fun if_else_1(c: bool): u8 { --- Stackless Bytecode fun m::if_else_1($t0|c: bool): u8 { - var $t1|return: u8 - var $t2: bool + var $t1: bool + var $t2: u8 var $t3: u8 - var $t4: u8 - var $t5: u8 - 0: $t2 := move($t0) - 1: if ($t2) goto 2 else goto 9 + 0: $t1 := move($t0) + 1: if ($t1) goto 2 else goto 5 2: label L1 - 3: $t3 := 1 - 4: $t1 := $t3 - 5: goto 6 - 6: label L2 - 7: $t4 := move($t1) - 8: return $t4 - 9: label L0 - 10: $t5 := 2 - 11: $t1 := $t5 - 12: goto 6 + 3: $t2 := 1 + 4: return $t2 + 5: label L0 + 6: $t3 := 2 + 7: return $t3 } --- Raw Generated AST -_t2: bool = c; +_t1: bool = c; loop { - loop { - if (Not(_t2)) break; - _t3: u8 = 1; - _t1: u8 = _t3; - break[1] - }; - _t5: u8 = 2; - _t1: u8 = _t5; - break + if (Not(_t1)) break; + _t2: u8 = 1; + return _t2 }; -_t4: u8 = _t1; -return _t4 +_t3: u8 = 2; +return _t3 --- Assign-Transformed Generated AST loop { - loop { - if (Not(c)) break; - _t1: u8 = 1; - break[1] - }; - _t1: u8 = 2; - break + if (Not(c)) break; + return 1 }; -return _t1 +return 2 --- If-Transformed Generated AST -if c { - _t1: u8 = 1 -} else { - _t1: u8 = 2 -}; -return _t1 +if (c) return 1; +return 2 --- Var-Bound Generated AST -{ - let _t1: u8; - if c { - _t1: u8 = 1 - } else { - _t1: u8 = 2 - }; - return _t1 -} +if (c) return 1; +return 2 === Processing m::if_else_2 ===================================================== @@ -157,101 +127,67 @@ fun if_else_2(c: bool, d: bool): u8 { --- Stackless Bytecode fun m::if_else_2($t0|c: bool, $t1|d: bool): u8 { - var $t2|return: u8 + var $t2: bool var $t3: bool - var $t4: bool + var $t4: u8 var $t5: u8 var $t6: u8 - var $t7: u8 - var $t8: u8 - 0: $t3 := move($t0) - 1: if ($t3) goto 2 else goto 16 + 0: $t2 := move($t0) + 1: if ($t2) goto 2 else goto 11 2: label L1 - 3: $t4 := move($t1) - 4: if ($t4) goto 5 else goto 12 + 3: $t3 := move($t1) + 4: if ($t3) goto 5 else goto 8 5: label L3 - 6: $t5 := 1 - 7: $t2 := $t5 - 8: goto 9 - 9: label L4 - 10: $t6 := move($t2) - 11: return $t6 - 12: label L2 - 13: $t7 := 2 - 14: $t2 := $t7 - 15: goto 9 - 16: label L0 - 17: $t8 := 3 - 18: $t2 := $t8 - 19: goto 9 + 6: $t4 := 1 + 7: return $t4 + 8: label L2 + 9: $t5 := 2 + 10: return $t5 + 11: label L0 + 12: $t6 := 3 + 13: return $t6 } --- Raw Generated AST -_t3: bool = c; +_t2: bool = c; loop { + if (Not(_t2)) break; + _t3: bool = d; loop { - if (_t3) break; - _t8: u8 = 3; - _t2: u8 = _t8; - break[1] - }; - _t4: bool = d; - loop { - if (Not(_t4)) break; - _t5: u8 = 1; - _t2: u8 = _t5; - break[1] + if (Not(_t3)) break; + _t4: u8 = 1; + return _t4 }; - _t7: u8 = 2; - _t2: u8 = _t7; - break + _t5: u8 = 2; + return _t5 }; -_t6: u8 = _t2; +_t6: u8 = 3; return _t6 --- Assign-Transformed Generated AST loop { - loop { - if (c) break; - _t2: u8 = 3; - break[1] - }; + if (Not(c)) break; loop { if (Not(d)) break; - _t2: u8 = 1; - break[1] + return 1 }; - _t2: u8 = 2; - break + return 2 }; -return _t2 +return 3 --- If-Transformed Generated AST if c { - if d { - _t2: u8 = 1 - } else { - _t2: u8 = 2 - } -} else { - _t2: u8 = 3 + if (d) return 1; + return 2 }; -return _t2 +return 3 --- Var-Bound Generated AST -{ - let _t2: u8; - if c { - if d { - _t2: u8 = 1 - } else { - _t2: u8 = 2 - } - } else { - _t2: u8 = 3 - }; - return _t2 -} +if c { + if (d) return 1; + return 2 +}; +return 3 === Processing m::if_else_3 ===================================================== @@ -353,46 +289,44 @@ fun m::if_else_if($t0|c: bool, $t1|d: bool): u8 { var $t7: u8 var $t8: u8 0: $t3 := move($t0) - 1: if ($t3) goto 2 else goto 9 + 1: if ($t3) goto 2 else goto 8 2: label L1 3: $t4 := 1 - 4: $t2 := $t4 - 5: goto 6 - 6: label L4 - 7: $t5 := move($t2) - 8: return $t5 - 9: label L0 - 10: $t6 := move($t1) - 11: if ($t6) goto 12 else goto 16 - 12: label L3 - 13: $t7 := 2 - 14: $t2 := $t7 - 15: goto 6 - 16: label L2 - 17: $t8 := 3 - 18: $t2 := $t8 - 19: goto 6 + 4: return $t4 + 5: label L4 + 6: $t5 := move($t2) + 7: return $t5 + 8: label L0 + 9: $t6 := move($t1) + 10: if ($t6) goto 11 else goto 15 + 11: label L3 + 12: $t7 := 2 + 13: $t2 := $t7 + 14: goto 5 + 15: label L2 + 16: $t8 := 3 + 17: $t2 := $t8 + 18: goto 5 } --- Raw Generated AST _t3: bool = c; loop { loop { - if (Not(_t3)) break; - _t4: u8 = 1; - _t2: u8 = _t4; - break[1] - }; - _t6: bool = d; - loop { - if (Not(_t6)) break; - _t7: u8 = 2; - _t2: u8 = _t7; + if (_t3) break; + _t6: bool = d; + loop { + if (Not(_t6)) break; + _t7: u8 = 2; + _t2: u8 = _t7; + break[2] + }; + _t8: u8 = 3; + _t2: u8 = _t8; break[1] }; - _t8: u8 = 3; - _t2: u8 = _t8; - break + _t4: u8 = 1; + return _t4 }; _t5: u8 = _t2; return _t5 @@ -400,43 +334,46 @@ return _t5 --- Assign-Transformed Generated AST loop { loop { - if (Not(c)) break; - _t2: u8 = 1; - break[1] - }; - loop { - if (Not(d)) break; - _t2: u8 = 2; + if (c) break; + loop { + if (Not(d)) break; + _t2: u8 = 2; + break[2] + }; + _t2: u8 = 3; break[1] }; - _t2: u8 = 3; - break + return 1 }; return _t2 --- If-Transformed Generated AST -if c { - _t2: u8 = 1 -} else { - if d { - _t2: u8 = 2 - } else { - _t2: u8 = 3 - } +loop { + if Not(c) { + if d { + _t2: u8 = 2; + break + }; + _t2: u8 = 3; + break + }; + return 1 }; return _t2 --- Var-Bound Generated AST { let _t2: u8; - if c { - _t2: u8 = 1 - } else { - if d { - _t2: u8 = 2 - } else { - _t2: u8 = 3 - } + loop { + if Not(c) { + if d { + _t2: u8 = 2; + break + }; + _t2: u8 = 3; + break + }; + return 1 }; return _t2 } @@ -452,7 +389,7 @@ fun if_else_with_shared_exp(x: u64): u64 { --- Stackless Bytecode fun m::if_else_with_shared_exp($t0|x: u64): u64 { - var $t1|$t3: u64 + var $t1: u64 var $t2: u64 var $t3: u64 var $t4: u64 @@ -460,144 +397,124 @@ fun m::if_else_with_shared_exp($t0|x: u64): u64 { var $t6: u64 var $t7: u64 var $t8: u64 - var $t9: u64 - var $t10: bool + var $t9: bool + var $t10: u64 var $t11: u64 var $t12: u64 var $t13: u64 var $t14: u64 var $t15: u64 - var $t16: u64 - var $t17: u64 - 0: $t2 := copy($t0) - 1: $t3 := move($t0) - 2: $t4 := +($t2, $t3) - 3: $t0 := $t4 - 4: $t5 := copy($t0) - 5: $t6 := move($t0) - 6: $t7 := *($t5, $t6) - 7: $t0 := $t7 - 8: $t8 := copy($t0) - 9: $t9 := 0 - 10: $t10 := >($t8, $t9) - 11: if ($t10) goto 12 else goto 21 + 0: $t1 := copy($t0) + 1: $t2 := move($t0) + 2: $t3 := +($t1, $t2) + 3: $t0 := $t3 + 4: $t4 := copy($t0) + 5: $t5 := move($t0) + 6: $t6 := *($t4, $t5) + 7: $t0 := $t6 + 8: $t7 := copy($t0) + 9: $t8 := 0 + 10: $t9 := >($t7, $t8) + 11: if ($t9) goto 12 else goto 17 12: label L1 - 13: $t11 := move($t0) - 14: $t12 := 1 - 15: $t13 := +($t11, $t12) - 16: $t1 := $t13 - 17: goto 18 - 18: label L2 - 19: $t14 := move($t1) - 20: return $t14 - 21: label L0 - 22: $t15 := move($t0) - 23: $t16 := 1 - 24: $t17 := -($t15, $t16) - 25: $t1 := $t17 - 26: goto 18 + 13: $t10 := move($t0) + 14: $t11 := 1 + 15: $t12 := +($t10, $t11) + 16: return $t12 + 17: label L0 + 18: $t13 := move($t0) + 19: $t14 := 1 + 20: $t15 := -($t13, $t14) + 21: return $t15 } --- Raw Generated AST +_t1: u64 = x; _t2: u64 = x; -_t3: u64 = x; -_t4: u64 = Add(_t2, _t3); -x: u64 = _t4; +_t3: u64 = Add(_t1, _t2); +x: u64 = _t3; +_t4: u64 = x; _t5: u64 = x; -_t6: u64 = x; -_t7: u64 = Mul(_t5, _t6); -x: u64 = _t7; -_t8: u64 = x; -_t9: u64 = 0; -_t10: bool = Gt(_t8, _t9); +_t6: u64 = Mul(_t4, _t5); +x: u64 = _t6; +_t7: u64 = x; +_t8: u64 = 0; +_t9: bool = Gt(_t7, _t8); loop { - loop { - if (Not(_t10)) break; - _t11: u64 = x; - _t12: u64 = 1; - _t13: u64 = Add(_t11, _t12); - _t1: u64 = _t13; - break[1] - }; - _t15: u64 = x; - _t16: u64 = 1; - _t17: u64 = Sub(_t15, _t16); - _t1: u64 = _t17; - break + if (Not(_t9)) break; + _t10: u64 = x; + _t11: u64 = 1; + _t12: u64 = Add(_t10, _t11); + return _t12 }; -_t14: u64 = _t1; -return _t14 +_t13: u64 = x; +_t14: u64 = 1; +_t15: u64 = Sub(_t13, _t14); +return _t15 --- Assign-Transformed Generated AST x: u64 = Add(x, x); x: u64 = Mul(x, x); loop { - loop { - if (Not(Gt(x, 0))) break; - _t1: u64 = Add(x, 1); - break[1] - }; - _t1: u64 = Sub(x, 1); - break + if (Not(Gt(x, 0))) break; + return Add(x, 1) }; -return _t1 +return Sub(x, 1) --- If-Transformed Generated AST x: u64 = Add(x, x); x: u64 = Mul(x, x); -if Gt(x, 0) { - _t1: u64 = Add(x, 1) -} else { - _t1: u64 = Sub(x, 1) -}; -return _t1 +if (Gt(x, 0)) return Add(x, 1); +return Sub(x, 1) --- Var-Bound Generated AST -{ - let _t1: u64; - x: u64 = Add(x, x); - x: u64 = Mul(x, x); - if Gt(x, 0) { - _t1: u64 = Add(x, 1) - } else { - _t1: u64 = Sub(x, 1) - }; - return _t1 -} +x: u64 = Add(x, x); +x: u64 = Mul(x, x); +if (Gt(x, 0)) return Add(x, 1); +return Sub(x, 1) === Sourcified Output ============================================ module 0x815::m { fun if_1(c: bool): u8 { - let _t1; - _t1 = 0u8; - if (c) _t1 = 1u8; - _t1 + let _v0 = 0u8; + if (c) _v0 = 1u8; + _v0 } fun if_else_1(c: bool): u8 { - let _t1; - if (c) _t1 = 1u8 else _t1 = 2u8; - _t1 + if (c) return 1u8; + 2u8 } fun if_else_2(c: bool, d: bool): u8 { - let _t2; - if (c) if (d) _t2 = 1u8 else _t2 = 2u8 else _t2 = 3u8; - _t2 + if (c) { + if (d) return 1u8; + return 2u8 + }; + 3u8 } fun if_else_3(c: bool): u64 { - let _t1; - if (c) _t1 = 1 else _t1 = 2; - _t1 + let _v0; + if (c) _v0 = 1 else _v0 = 2; + _v0 } fun if_else_if(c: bool, d: bool): u8 { - let _t2; - if (c) _t2 = 1u8 else if (d) _t2 = 2u8 else _t2 = 3u8; - _t2 + let _v0; + loop { + if (!c) { + if (d) { + _v0 = 2u8; + break + }; + _v0 = 3u8; + break + }; + return 1u8 + }; + _v0 } fun if_else_with_shared_exp(x: u64): u64 { - let _t1; x = x + x; x = x * x; - if (x > 0) _t1 = x + 1 else _t1 = x - 1; - _t1 + if (x > 0) return x + 1; + x - 1 } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp index ef55daa883f..77e7e7be049 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp @@ -89,9 +89,11 @@ return _t17 --- Assign-Transformed Generated AST loop { c: u64 = Add(c, 1); - if (Eq(Mod(c, 2), 0)) continue; + _t6: u64 = Mod(c, 2); + if (Eq(_t6, 0)) continue; c: u64 = Add(c, 3); - if (Not(Eq(Mod(c, 2), 1))) continue; + _t14: u64 = Mod(c, 2); + if (Not(Eq(_t14, 1))) continue; break }; return c @@ -99,9 +101,11 @@ return c --- If-Transformed Generated AST loop { c: u64 = Add(c, 1); - if (Eq(Mod(c, 2), 0)) continue; + _t6: u64 = Mod(c, 2); + if (Eq(_t6, 0)) continue; c: u64 = Add(c, 3); - if (Not(Eq(Mod(c, 2), 1))) continue; + _t14: u64 = Mod(c, 2); + if (Not(Eq(_t14, 1))) continue; break }; return c @@ -109,10 +113,16 @@ return c --- Var-Bound Generated AST loop { c: u64 = Add(c, 1); - if (Eq(Mod(c, 2), 0)) continue; - c: u64 = Add(c, 3); - if (Not(Eq(Mod(c, 2), 1))) continue; - break + { + let _t6: u64 = Mod(c, 2); + if (Eq(_t6, 0)) continue; + c: u64 = Add(c, 3); + { + let _t14: u64 = Mod(c, 2); + if (Not(Eq(_t14, 1))) continue; + break + } + } }; return c @@ -175,47 +185,55 @@ fun m::nested_loop($t0|x: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = x; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = x; - _t5: u64 = 10; - _t6: bool = Gt(_t4, _t5); loop { - if (Not(_t6)) break; - _t7: u64 = x; - _t8: u64 = 1; - _t9: u64 = Sub(_t7, _t8); - x: u64 = _t9; - break + _t1: u64 = x; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = x; + _t5: u64 = 10; + _t6: bool = Gt(_t4, _t5); + loop { + if (Not(_t6)) break; + _t7: u64 = x; + _t8: u64 = 1; + _t9: u64 = Sub(_t7, _t8); + x: u64 = _t9; + break + }; + _t10: u64 = x; + _t11: u64 = 1; + _t12: u64 = Sub(_t10, _t11); + x: u64 = _t12; + continue }; - _t10: u64 = x; - _t11: u64 = 1; - _t12: u64 = Sub(_t10, _t11); - x: u64 = _t12; - continue + break }; _t13: u64 = x; return _t13 --- Assign-Transformed Generated AST loop { - if (Not(Gt(x, 0))) break; loop { - if (Not(Gt(x, 10))) break; + if (Not(Gt(x, 0))) break[1]; + _t6: bool = Gt(x, 10); + loop { + if (Not(_t6)) break; + x: u64 = Sub(x, 1); + break + }; x: u64 = Sub(x, 1); - break + continue }; - x: u64 = Sub(x, 1); - continue + break }; return x --- If-Transformed Generated AST loop { if (Not(Gt(x, 0))) break; - if (Gt(x, 10)) x: u64 = Sub(x, 1); + _t6: bool = Gt(x, 10); + if (_t6) x: u64 = Sub(x, 1); x: u64 = Sub(x, 1); continue }; @@ -224,9 +242,12 @@ return x --- Var-Bound Generated AST loop { if (Not(Gt(x, 0))) break; - if (Gt(x, 10)) x: u64 = Sub(x, 1); - x: u64 = Sub(x, 1); - continue + { + let _t6: bool = Gt(x, 10); + if (_t6) x: u64 = Sub(x, 1); + x: u64 = Sub(x, 1); + continue + } }; return x @@ -262,23 +283,29 @@ fun m::while_1($t0|c: u64) { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = c; - _t5: u64 = 1; - _t6: u64 = Sub(_t4, _t5); - c: u64 = _t6; - continue + loop { + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = c; + _t5: u64 = 1; + _t6: u64 = Sub(_t4, _t5); + c: u64 = _t6; + continue + }; + break }; return Tuple() --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - c: u64 = Sub(c, 1); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + c: u64 = Sub(c, 1); + continue + }; + break }; return Tuple() @@ -350,19 +377,22 @@ fun m::while_2($t0|c: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = c; - _t5: u64 = 10; - _t6: bool = Ge(_t4, _t5); - if (Not(_t6)) continue; - _t7: u64 = c; - _t8: u64 = 10; - _t9: u64 = Sub(_t7, _t8); - c: u64 = _t9; - continue + loop { + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = c; + _t5: u64 = 10; + _t6: bool = Ge(_t4, _t5); + if (Not(_t6)) continue; + _t7: u64 = c; + _t8: u64 = 10; + _t9: u64 = Sub(_t7, _t8); + c: u64 = _t9; + continue + }; + break }; _t10: u64 = c; _t11: u64 = 1; @@ -371,10 +401,13 @@ return _t12 --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - if (Not(Ge(c, 10))) continue; - c: u64 = Sub(c, 10); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + if (Not(Ge(c, 10))) continue; + c: u64 = Sub(c, 10); + continue + }; + break }; return Add(c, 1) @@ -453,40 +486,52 @@ fun m::while_3($t0|c: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; loop { - _t4: u64 = c; - _t5: u64 = 10; - _t6: bool = Gt(_t4, _t5); - if (Not(_t6)) break; - _t7: u64 = c; - _t8: u64 = 10; - _t9: u64 = Sub(_t7, _t8); - c: u64 = _t9; + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + loop { + loop { + _t4: u64 = c; + _t5: u64 = 10; + _t6: bool = Gt(_t4, _t5); + if (Not(_t6)) break[1]; + _t7: u64 = c; + _t8: u64 = 10; + _t9: u64 = Sub(_t7, _t8); + c: u64 = _t9; + continue + }; + break + }; + _t10: u64 = c; + _t11: u64 = 1; + _t12: u64 = Sub(_t10, _t11); + c: u64 = _t12; continue }; - _t10: u64 = c; - _t11: u64 = 1; - _t12: u64 = Sub(_t10, _t11); - c: u64 = _t12; - continue + break }; _t13: u64 = c; return _t13 --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; loop { - if (Not(Gt(c, 10))) break; - c: u64 = Sub(c, 10); + if (Not(Gt(c, 0))) break[1]; + loop { + loop { + if (Not(Gt(c, 10))) break[1]; + c: u64 = Sub(c, 10); + continue + }; + break + }; + c: u64 = Sub(c, 1); continue }; - c: u64 = Sub(c, 1); - continue + break }; return c @@ -521,17 +566,21 @@ module 0x815::m { fun loop_1(c: u64): u64 { loop { c = c + 1; - if (c % 2 == 0) continue; + let _v0 = c % 2; + if (_v0 == 0) continue; c = c + 3; - if (!(c % 2 == 1)) continue; + let _v1 = c % 2; + if (!(_v1 == 1)) continue; break }; c } fun nested_loop(x: u64): u64 { while (x > 0) { - if (x > 10) x = x - 1; - x = x - 1 + let _v0 = x > 10; + if (_v0) x = x - 1; + x = x - 1; + continue }; x } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp index 0b545627c8e..d3146327a3f 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp @@ -10,114 +10,95 @@ fun id(self: &Entity): u64 { --- Stackless Bytecode fun m::id($t0|self: &0x815::m::Entity): u64 { - var $t1|return: u64 - var $t2: &0x815::m::Entity - var $t3: bool - var $t4: &0x815::m::Entity - var $t5: &u64 - var $t6: u64 - var $t7: u64 + var $t1: &0x815::m::Entity + var $t2: bool + var $t3: &0x815::m::Entity + var $t4: &u64 + var $t5: u64 + var $t6: &0x815::m::Entity + var $t7: bool var $t8: &0x815::m::Entity - var $t9: bool - var $t10: &0x815::m::Entity - var $t11: &u64 + var $t9: &u64 + var $t10: u64 + var $t11: &0x815::m::Entity var $t12: u64 - var $t13: &0x815::m::Entity - var $t14: u64 - 0: $t2 := copy($t0) - 1: $t3 := test_variant 0x815::m::Entity::Person($t2) - 2: if ($t3) goto 3 else goto 12 + 0: $t1 := copy($t0) + 1: $t2 := test_variant 0x815::m::Entity::Person($t1) + 2: if ($t2) goto 3 else goto 8 3: label L1 - 4: $t4 := move($t0) - 5: $t5 := borrow_variant_field<0x815::m::Entity::Person>.id($t4) - 6: $t6 := read_ref($t5) - 7: $t1 := $t6 - 8: goto 9 - 9: label L4 - 10: $t7 := move($t1) - 11: return $t7 - 12: label L0 - 13: $t8 := copy($t0) - 14: $t9 := test_variant 0x815::m::Entity::Institution($t8) - 15: if ($t9) goto 16 else goto 22 - 16: label L3 - 17: $t10 := move($t0) - 18: $t11 := borrow_variant_field<0x815::m::Entity::Institution>.id($t10) - 19: $t12 := read_ref($t11) - 20: $t1 := $t12 - 21: goto 9 - 22: label L2 - 23: $t13 := move($t0) - 24: drop($t13) - 25: $t14 := 14566554180833181697 - 26: abort($t14) + 4: $t3 := move($t0) + 5: $t4 := borrow_variant_field<0x815::m::Entity::Person>.id($t3) + 6: $t5 := read_ref($t4) + 7: return $t5 + 8: label L0 + 9: $t6 := copy($t0) + 10: $t7 := test_variant 0x815::m::Entity::Institution($t6) + 11: if ($t7) goto 12 else goto 17 + 12: label L3 + 13: $t8 := move($t0) + 14: $t9 := borrow_variant_field<0x815::m::Entity::Institution>.id($t8) + 15: $t10 := read_ref($t9) + 16: return $t10 + 17: label L2 + 18: $t11 := move($t0) + 19: drop($t11) + 20: $t12 := 14566554180833181697 + 21: abort($t12) } --- Raw Generated AST -_t2: &Entity = self; -_t3: bool = test_variants m::Entity::Person(_t2); +_t1: &Entity = self; +_t2: bool = test_variants m::Entity::Person(_t1); loop { loop { - if (Not(_t3)) break; - _t4: &Entity = self; - _t5: &u64 = select_variants m::Entity.Person.id(_t4); - _t6: u64 = Deref(_t5); - _t1: u64 = _t6; - break[1] - }; - _t8: &Entity = self; - _t9: bool = test_variants m::Entity::Institution(_t8); - loop { - if (_t9) break; - _t13: &Entity = self; - _t14: u64 = 14566554180833181697; - Abort(_t14) + if (_t2) break; + _t6: &Entity = self; + _t7: bool = test_variants m::Entity::Institution(_t6); + if (_t7) break[1]; + _t11: &Entity = self; + _t12: u64 = 14566554180833181697; + Abort(_t12) }; - _t10: &Entity = self; - _t11: &u64 = select_variants m::Entity.Institution.id(_t10); - _t12: u64 = Deref(_t11); - _t1: u64 = _t12; - break + _t3: &Entity = self; + _t4: &u64 = select_variants m::Entity.Person.id(_t3); + _t5: u64 = Deref(_t4); + return _t5 }; -_t7: u64 = _t1; -return _t7 +_t8: &Entity = self; +_t9: &u64 = select_variants m::Entity.Institution.id(_t8); +_t10: u64 = Deref(_t9); +return _t10 --- Assign-Transformed Generated AST loop { loop { - if (Not(test_variants m::Entity::Person(self))) break; - _t1: u64 = Deref(select_variants m::Entity.Person.id(self)); - break[1] - }; - loop { - if (test_variants m::Entity::Institution(self)) break; + if (test_variants m::Entity::Person(self)) break; + if (test_variants m::Entity::Institution(self)) break[1]; Abort(14566554180833181697) }; - _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)); - break + return Deref(select_variants m::Entity.Person.id(self)) }; -return _t1 +return Deref(select_variants m::Entity.Institution.id(self)) --- If-Transformed Generated AST -if test_variants m::Entity::Person(self) { - _t1: u64 = Deref(select_variants m::Entity.Person.id(self)) -} else { - if (Not(test_variants m::Entity::Institution(self))) Abort(14566554180833181697); - _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)) +loop { + if Not(test_variants m::Entity::Person(self)) { + if (test_variants m::Entity::Institution(self)) break; + Abort(14566554180833181697) + }; + return Deref(select_variants m::Entity.Person.id(self)) }; -return _t1 +return Deref(select_variants m::Entity.Institution.id(self)) --- Var-Bound Generated AST -{ - let _t1: u64; - if test_variants m::Entity::Person(self) { - _t1: u64 = Deref(select_variants m::Entity.Person.id(self)) - } else { - if (Not(test_variants m::Entity::Institution(self))) Abort(14566554180833181697); - _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)) +loop { + if Not(test_variants m::Entity::Person(self)) { + if (test_variants m::Entity::Institution(self)) break; + Abort(14566554180833181697) }; - return _t1 -} + return Deref(select_variants m::Entity.Person.id(self)) +}; +return Deref(select_variants m::Entity.Institution.id(self)) === Processing m::id2 ===================================================== @@ -133,162 +114,139 @@ fun id2(self: Entity): u64 { --- Stackless Bytecode fun m::id2($t0|self: 0x815::m::Entity): u64 { var $t1|$t2: &0x815::m::Entity - var $t2|id: u64 + var $t2: &0x815::m::Entity var $t3: &0x815::m::Entity - var $t4: &0x815::m::Entity - var $t5: bool - var $t6: &0x815::m::Entity - var $t7: bool - var $t8: 0x815::m::Entity + var $t4: bool + var $t5: &0x815::m::Entity + var $t6: bool + var $t7: 0x815::m::Entity + var $t8: u64 var $t9: u64 var $t10: u64 - var $t11: u64 - var $t12: u64 - var $t13: &0x815::m::Entity - var $t14: &u64 - var $t15: u64 - var $t16: u64 - var $t17: bool - var $t18: &0x815::m::Entity - var $t19: 0x815::m::Entity - var $t20: u64 - 0: $t3 := borrow_local($t0) - 1: $t1 := $t3 - 2: $t4 := copy($t1) - 3: $t5 := test_variant 0x815::m::Entity::Person($t4) - 4: if ($t5) goto 22 else goto 5 + var $t11: &0x815::m::Entity + var $t12: &u64 + var $t13: u64 + var $t14: u64 + var $t15: bool + var $t16: &0x815::m::Entity + var $t17: 0x815::m::Entity + var $t18: u64 + 0: $t2 := borrow_local($t0) + 1: $t1 := $t2 + 2: $t3 := copy($t1) + 3: $t4 := test_variant 0x815::m::Entity::Person($t3) + 4: if ($t4) goto 17 else goto 5 5: label L2 - 6: $t6 := move($t1) - 7: $t7 := test_variant 0x815::m::Entity::Institution($t6) - 8: if ($t7) goto 9 else goto 18 + 6: $t5 := move($t1) + 7: $t6 := test_variant 0x815::m::Entity::Institution($t5) + 8: if ($t6) goto 9 else goto 14 9: label L4 - 10: $t8 := move($t0) - 11: ($t9, $t10) := unpack_variant 0x815::m::Entity::Institution($t8) - 12: drop($t10) - 13: $t2 := $t9 - 14: goto 15 - 15: label L5 - 16: $t11 := move($t2) - 17: return $t11 - 18: label L3 - 19: $t12 := 0 - 20: $t2 := $t12 - 21: goto 15 - 22: label L0 - 23: $t13 := copy($t1) - 24: $t14 := borrow_variant_field<0x815::m::Entity::Person>.id($t13) - 25: $t15 := read_ref($t14) - 26: $t16 := 0 - 27: $t17 := >($t15, $t16) - 28: if ($t17) goto 29 else goto 5 - 29: label L6 - 30: $t18 := move($t1) - 31: drop($t18) - 32: $t19 := move($t0) - 33: $t20 := unpack_variant 0x815::m::Entity::Person($t19) - 34: $t2 := $t20 - 35: goto 15 + 10: $t7 := move($t0) + 11: ($t8, $t9) := unpack_variant 0x815::m::Entity::Institution($t7) + 12: drop($t9) + 13: return $t8 + 14: label L3 + 15: $t10 := 0 + 16: return $t10 + 17: label L0 + 18: $t11 := copy($t1) + 19: $t12 := borrow_variant_field<0x815::m::Entity::Person>.id($t11) + 20: $t13 := read_ref($t12) + 21: $t14 := 0 + 22: $t15 := >($t13, $t14) + 23: if ($t15) goto 24 else goto 5 + 24: label L5 + 25: $t16 := move($t1) + 26: drop($t16) + 27: $t17 := move($t0) + 28: $t18 := unpack_variant 0x815::m::Entity::Person($t17) + 29: return $t18 } --- Raw Generated AST -_t3: &Entity = Borrow(Immutable)(self); -_t1: &Entity = _t3; -_t4: &Entity = _t1; -_t5: bool = test_variants m::Entity::Person(_t4); +_t2: &Entity = Borrow(Immutable)(self); +_t1: &Entity = _t2; +_t3: &Entity = _t1; +_t4: bool = test_variants m::Entity::Person(_t3); loop { loop { - if (Not(_t5)) break; - _t13: &Entity = _t1; - _t14: &u64 = select_variants m::Entity.Person.id(_t13); - _t15: u64 = Deref(_t14); - _t16: u64 = 0; - _t17: bool = Gt(_t15, _t16); - if (Not(_t17)) break; - _t18: &Entity = _t1; - _t19: Entity = self; - m::Entity::Person{ id: _t20 } = _t19; - _t2: u64 = _t20; + if (Not(_t4)) break; + _t11: &Entity = _t1; + _t12: &u64 = select_variants m::Entity.Person.id(_t11); + _t13: u64 = Deref(_t12); + _t14: u64 = 0; + _t15: bool = Gt(_t13, _t14); + if (Not(_t15)) break; break[1] }; - _t6: &Entity = _t1; - _t7: bool = test_variants m::Entity::Institution(_t6); + _t5: &Entity = _t1; + _t6: bool = test_variants m::Entity::Institution(_t5); loop { - if (Not(_t7)) break; - _t8: Entity = self; - m::Entity::Institution{ id: _t9, admin: _t10 } = _t8; - _t2: u64 = _t9; - break[1] + if (Not(_t6)) break; + _t7: Entity = self; + m::Entity::Institution{ id: _t8, admin: _t9 } = _t7; + return _t8 }; - _t12: u64 = 0; - _t2: u64 = _t12; - break + _t10: u64 = 0; + return _t10 }; -_t11: u64 = _t2; -return _t11 +_t16: &Entity = _t1; +_t17: Entity = self; +m::Entity::Person{ id: _t18 } = _t17; +return _t18 --- Assign-Transformed Generated AST _t1: &Entity = Borrow(Immutable)(self); loop { loop { if (Not(test_variants m::Entity::Person(_t1))) break; - if (Not(Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0))) break; - m::Entity::Person{ id: _t20 } = self; - _t2: u64 = _t20; + _t13: u64 = Deref(select_variants m::Entity.Person.id(_t1)); + if (Not(Gt(_t13, 0))) break; break[1] }; loop { if (Not(test_variants m::Entity::Institution(_t1))) break; - m::Entity::Institution{ id: _t9, admin: _t10 } = self; - _t2: u64 = _t9; - break[1] + m::Entity::Institution{ id: _t8, admin: _t9 } = self; + return _t8 }; - _t2: u64 = 0; - break + return 0 }; -return _t2 +m::Entity::Person{ id: _t18 } = self; +return _t18 --- If-Transformed Generated AST _t1: &Entity = Borrow(Immutable)(self); -if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { - m::Entity::Person{ id: _t20 } = self; - _t2: u64 = _t20 -} else { +loop { + if test_variants m::Entity::Person(_t1) { + _t13: u64 = Deref(select_variants m::Entity.Person.id(_t1)); + if (Gt(_t13, 0)) break + }; if test_variants m::Entity::Institution(_t1) { - m::Entity::Institution{ id: _t9, admin: _t10 } = self; - _t2: u64 = _t9 - } else { - _t2: u64 = 0 - } + m::Entity::Institution{ id: _t8, admin: _t9 } = self; + return _t8 + }; + return 0 }; -return _t2 +m::Entity::Person{ id: _t18 } = self; +return _t18 --- Var-Bound Generated AST { - let _t10: u64; + let _t1: &Entity = Borrow(Immutable)(self); + loop { + if (test_variants m::Entity::Person(_t1)) { + let _t13: u64 = Deref(select_variants m::Entity.Person.id(_t1)); + if (Gt(_t13, 0)) break + }; + if (test_variants m::Entity::Institution(_t1)) { + let m::Entity::Institution{ id: _t8, admin: _t9 } = self; + return _t8 + }; + return 0 + }; { - let _t9: u64; - { - let _t2: u64; - { - let _t20: u64; - { - let _t1: &Entity; - _t1: &Entity = Borrow(Immutable)(self); - if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { - m::Entity::Person{ id: _t20 } = self; - _t2: u64 = _t20 - } else { - if test_variants m::Entity::Institution(_t1) { - m::Entity::Institution{ id: _t9, admin: _t10 } = self; - _t2: u64 = _t9 - } else { - _t2: u64 = 0 - } - }; - return _t2 - } - } - } + let m::Entity::Person{ id: _t18 } = self; + return _t18 } } @@ -304,27 +262,29 @@ module 0x815::m { } } fun id(self: &Entity): u64 { - let _t1; - if (self is Person) _t1 = *&self.id else { - if (!(self is Institution)) abort 14566554180833181697; - _t1 = *&self.id + loop { + if (!(self is Person)) { + if (self is Institution) break; + abort 14566554180833181697 + }; + return *&self.id }; - _t1 + *&self.id } fun id2(self: Entity): u64 { - let _t10; - let _t9; - let _t2; - let _t20; - let _t1; - _t1 = &self; - if ((_t1 is Person) && *&_t1.id > 0) { - Entity::Person{id: _t20} = self; - _t2 = _t20 - } else if (_t1 is Institution) { - Entity::Institution{id: _t9,admin: _t10} = self; - _t2 = _t9 - } else _t2 = 0; - _t2 + let _v0 = &self; + loop { + if (_v0 is Person) { + let _v1 = *&_v0.id; + if (_v1 > 0) break + }; + if (_v0 is Institution) { + let Entity::Institution{id: _v2, admin: _v3} = self; + return _v2 + }; + return 0 + }; + let Entity::Person{id: _v4} = self; + _v4 } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/testsuite.rs b/third_party/move/move-model/bytecode/ast-generator-tests/tests/testsuite.rs index dcd03c9ca3e..097e07caf2f 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/testsuite.rs +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/testsuite.rs @@ -22,7 +22,7 @@ pub const EXP_EXT: &str = "exp"; datatest_stable::harness!(test_runner, "tests", r".*\.move$"); fn test_runner(path: &Path) -> datatest_stable::Result<()> { - logging::setup_logging_for_testing(); + logging::setup_logging_for_testing(None); let path_str = path.display().to_string(); let mut options = Options { sources_deps: extract_test_directives(path, "// dep:")?, @@ -59,7 +59,7 @@ fn test_runner(path: &Path) -> datatest_stable::Result<()> { env.set_function_def(fun_id, def); } } - let sourcifier = Sourcifier::new(&env); + let sourcifier = Sourcifier::new(&env, true); for mid in modules { sourcifier.print_module(mid) } diff --git a/third_party/move/move-model/bytecode/src/astifier.rs b/third_party/move/move-model/bytecode/src/astifier.rs index 4293e836c9a..4d0fe4b1d41 100644 --- a/third_party/move/move-model/bytecode/src/astifier.rs +++ b/third_party/move/move-model/bytecode/src/astifier.rs @@ -94,6 +94,7 @@ use move_model::{ use std::{ cmp::Ordering, collections::{BTreeMap, BTreeSet}, + vec, }; use topological_sort::TopologicalSort; use try_match::match_ok; @@ -153,14 +154,14 @@ pub fn generate_ast_raw(target: &FunctionTarget) -> Option { ctx.compute_loop_info(&fat_loop_info); // Create the generator and run it. - let mut gen = Generator { + let mut r#gen = Generator { block_stack: vec![], unreached_labels, used_labels: BTreeSet::new(), current_attr: None, block_order: BTreeMap::new(), }; - Some(gen.gen(&ctx)) + Some(r#gen.r#gen(&ctx)) } // ------------------------------------------------------------------------------------------- @@ -247,6 +248,9 @@ impl<'a> Context<'a> { /// here to simplify the viewpoint on the resulting CFG. /// 3. There must not be stub blocks which just forward a jump, as in /// `label L1; goto L2`. In this case, we substitute `L1` by `L2`. + /// Given a dead loop like `loop continue`, the substitutions will + /// form a cycle like L1->L2->L3--->L1. In this case, all labels will be + /// substituted with the last one, L3. fn clean_bytecode(self) -> Vec { // Compute # of incoming edges for each block. let mut incoming_count = BTreeMap::::new(); @@ -257,22 +261,28 @@ impl<'a> Context<'a> { } // Build a label substitution for stubs. let mut label_subst = BTreeMap::new(); + for blk_id in self.forward_cfg.blocks() { let block_code = self.code_for_block(blk_id); if block_code.len() == 2 { if let (Bytecode::Label(_, label1), Bytecode::Jump(_, label2)) = (&block_code[0], &block_code[1]) { - label_subst.insert(*label1, *label2); + // When only a substitution does not create a cycle, we add it. + if !Self::cyclic_label_subst_detected(*label1, *label2, &label_subst) { + label_subst.insert(*label1, *label2); + } } } } let substitute_label = |mut label: Label| { let mut visited = BTreeSet::new(); while let Some(s) = label_subst.get(&label) { + // This assert should always hold as we have prevented cycles + // when building the label_subst map. assert!( visited.insert(label), - "unexpected cyclic label substitution" + "label_subst is acyclic by construction" ); label = *s; } @@ -346,6 +356,27 @@ impl<'a> Context<'a> { result } + /// Helper function to detect if a label substitution creates a cycle. + fn cyclic_label_subst_detected( + label1: Label, + label2: Label, + label_subst: &BTreeMap, + ) -> bool { + if label1 == label2 { + return true; + } + // starting from `label2`, recursively replace the label and see if we go back to `label1`. + // why no endless iteration: label_subst has no cycles! + let mut target = label2; + while let Some(s) = label_subst.get(&target) { + if *s == label1 { + return true; + } + target = *s; + } + false + } + /// Helper to compute information about loops. fn compute_loop_info(&mut self, loop_info: &FatLoopFunctionInfo) { let backward_cfg = StacklessControlFlowGraph::new_backward(self.code(), true); @@ -471,7 +502,7 @@ impl<'a> Context<'a> { impl Generator { /// Run the generator. - fn gen(&mut self, ctx: &Context) -> Exp { + fn r#gen(&mut self, ctx: &Context) -> Exp { let mut blocks = ctx.forward_cfg.blocks(); // Sort blocks topologically. self.sort_blocks(ctx, &mut blocks); @@ -526,10 +557,21 @@ impl Generator { for header in &ctx.loop_headers { for after_loop_label in &ctx.after_loop_labels[header] { for loop_block_label in &ctx.loop_labels[header] { - top_sort.add_dependency( - ctx.block_of_label(*loop_block_label), - ctx.block_of_label(*after_loop_label), - ) + // Only when the new virtual edge does not bring a loop back (without considering the back edges), + // we add it! + let source_block = ctx.block_of_label(*loop_block_label); + let dest_block = ctx.block_of_label(*after_loop_label); + let edge_filter = |from: BlockId, to: BlockId| !ctx.is_back_edge(from, to); + if !ctx + .forward_cfg + .reachable_blocks(dest_block, edge_filter) + .contains(&source_block) + { + top_sort.add_dependency( + ctx.block_of_label(*loop_block_label), + ctx.block_of_label(*after_loop_label), + ) + } } } } @@ -609,7 +651,7 @@ impl Generator { top_sort.add_dependency(min, other) } } - debug_assert_eq!(min, top_sort.pop().expect("expected order consistent")); + assert_eq!(min, top_sort.pop().expect("expected order consistent")); blocks.push(min); } assert!(top_sort.is_empty(), "unexpected cycle in forward jumps"); @@ -757,11 +799,15 @@ impl Generator { }, if_false, ); + // We need to break out from all the inner loops! + let nest = self + .find_break_nest(ctx, if_false) + .expect("the newly added block must exist"); self.used_labels.insert(if_false); - self.add_stm( - ctx.builder - .if_(negated_cond, ctx.builder.break_(&self.current_loc(ctx), 0)), - ); + self.add_stm(ctx.builder.if_( + negated_cond, + ctx.builder.break_(&self.current_loc(ctx), nest), + )); self.gen_jump(ctx, next_block_label, if_true) } } @@ -818,7 +864,10 @@ impl Generator { }) { // Insert nested in the other block. self.block_stack - .insert(self.block_stack.len() - idx, block_info) + .insert(self.block_stack.len() - idx, block_info); + // This block can become a new loop between an inner `LoopCont` and its target `Loop`. + // We need to increase the `LoopCont`'s nest depth to account for the new loop. + self.adjust_loop_nest_depth(idx) } else { // Insert at top-level, beneath the virtual root block self.block_stack.insert(1, block_info) @@ -832,6 +881,58 @@ impl Generator { > self.block_order[&ctx.block_of_label(other_label)] } + /// Adjust the nest depth of `LoopCont` statements that are affected by a newly inserted block (which is expected to be a loop) + /// Given the following pattern + /// ```Move + /// Loop_n { + /// ... + /// Loop_1 { + /// Loop_0 { + /// LoopCont[x] + /// } + /// } + /// } + /// and assuming we insert a new block `Loop_t` + /// - 0 <= `t` <= n, and is represented by the function argument `idx` below. + /// - If `t` <= `x`, we rewrite ` LoopCont[x]` to `LoopCont[x + 1]`. + /// - Why: the pattern above means the new block is inserted between the `LoopCont` and its target loop, + /// so we must increase the loop nest depth of `LoopCont` to make sure it refers to the right loop. + /// + fn adjust_loop_nest_depth(&mut self, idx: usize) { + for (i, inner) in self.block_stack.iter_mut().rev().enumerate() { + // We only need to worry about the `LoopCont` statements nested inside the newly added block. + if i < idx { + // Iterate over all statements in an inner loop + for val in inner.stms.iter_mut() { + // A customized loop nest rewrite function where + // - `nest - loop_depth` represents `x` in the pattern above + // - `delta` represents `t` in the pattern above + let rewrite = |exp: Exp, + loop_depth: usize, + nest: usize, + cont: bool, + delta: isize| + -> Exp { + let x = (nest - loop_depth) as isize; + let increase = x - delta; + + if increase >= 0 { + ExpData::LoopCont(exp.node_id(), nest + 1, cont).into_exp() + } else { + exp.clone() + } + }; + + // Rewrite a statement where `idx - i` tells the distance between the target `LoopCont` and the newly added block, + // representing `delta`. + *val = val + .clone() + .customizable_rewrite_loop_nest((idx - i) as isize, rewrite) + } + } + } + } + fn find_continue_nest(&self, _ctx: &Context, label: Label) -> Option { for (nest, info) in self.block_stack.iter().rev().enumerate() { if info.continue_label.map(|l| l == label).unwrap_or(false) { @@ -953,10 +1054,14 @@ impl Generator { Operation::MoveFunction(*mid, *fid), srcs, ), - Closure(..) | Invoke => { - // TODO(#15664): implement closure opcodes for astifier - panic!("closure operations not supported: {:?}", oper) - }, + Closure(mid, fid, inst, closure_mask) => self.gen_call_stm( + ctx, + Some(inst), + dests, + Operation::Closure(*mid, *fid, *closure_mask), + srcs, + ), + Invoke => self.gen_invoke(ctx, dests, srcs), Pack(mid, sid, inst) => { self.gen_call_stm( ctx, @@ -971,14 +1076,17 @@ impl Generator { let rhs = self.make_temp(ctx, srcs[0]); self.gen_match(ctx, dests, qsid, None, rhs); }, - MoveTo(_, _, inst) => { - self.gen_call_stm(ctx, Some(inst), dests, Operation::MoveTo, srcs); + MoveTo(mid, sid, inst) => { + let ty = Type::Struct(*mid, *sid, inst.to_vec()); + self.gen_call_stm(ctx, Some(&vec![ty]), dests, Operation::MoveTo, srcs); }, - MoveFrom(_, _, inst) => { - self.gen_call_stm(ctx, Some(inst), dests, Operation::MoveFrom, srcs); + MoveFrom(mid, sid, inst) => { + let ty = Type::Struct(*mid, *sid, inst.to_vec()); + self.gen_call_stm(ctx, Some(&vec![ty]), dests, Operation::MoveFrom, srcs); }, - Exists(_, _, inst) => { - self.gen_call_stm(ctx, Some(inst), dests, Operation::Exists(None), srcs); + Exists(mid, sid, inst) => { + let ty = Type::Struct(*mid, *sid, inst.to_vec()); + self.gen_call_stm(ctx, Some(&vec![ty]), dests, Operation::Exists(None), srcs); }, TestVariant(mid, sid, variant, inst) => { self.gen_call_stm( @@ -1003,13 +1111,16 @@ impl Generator { let rhs = self.make_temp(ctx, srcs[0]); self.gen_match(ctx, dests, qsid, Some(*variant), rhs); }, - BorrowGlobal(_, _, inst) => self.gen_call_stm( - ctx, - Some(inst), - dests, - Operation::BorrowGlobal(ctx.ref_kind(dests[0])), - srcs, - ), + BorrowGlobal(mid, sid, inst) => { + let ty = Type::Struct(*mid, *sid, inst.to_vec()); + self.gen_call_stm( + ctx, + Some(&vec![ty]), + dests, + Operation::BorrowGlobal(ctx.ref_kind(dests[0])), + srcs, + ); + }, BorrowLoc => self.gen_call_stm( ctx, None, @@ -1062,7 +1173,8 @@ impl Generator { self.gen_call_stm(ctx, None, dests, Operation::Freeze(*explicit), srcs) }, Vector => self.gen_call_stm(ctx, None, dests, Operation::Vector, srcs), - CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 => { + CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 | CastI8 | CastI16 + | CastI32 | CastI64 | CastI128 | CastI256 => { self.gen_call_stm(ctx, None, dests, Operation::Cast, srcs) }, Not => self.gen_call_stm(ctx, None, dests, Operation::Not, srcs), @@ -1084,6 +1196,7 @@ impl Generator { And => self.gen_call_stm(ctx, None, dests, Operation::And, srcs), Eq => self.gen_call_stm(ctx, None, dests, Operation::Eq, srcs), Neq => self.gen_call_stm(ctx, None, dests, Operation::Neq, srcs), + Negate => self.gen_call_stm(ctx, None, dests, Operation::Negate, srcs), OpaqueCallBegin(_, _, _) | OpaqueCallEnd(_, _, _) @@ -1137,6 +1250,24 @@ impl Generator { } } + fn gen_invoke(&mut self, ctx: &Context, dests: &[TempIndex], srcs: &[TempIndex]) { + let ty = Type::tuple( + dests + .iter() + .map(|d| ctx.target.get_local_type(*d).clone()) + .collect(), + ); + let invoke_id = self.new_node_id(ctx, ty); + let mut temps = self.make_temps(ctx, srcs.iter().copied()); + let closure = temps.pop().expect("closure must be present for invoke"); + let invoke = ExpData::Invoke(invoke_id, closure, temps); + if !dests.is_empty() { + self.gen_assign(ctx, dests, invoke) + } else { + self.add_stm(invoke) + } + } + fn gen_match( &mut self, ctx: &Context, @@ -1362,122 +1493,549 @@ struct IfElseTransformer<'a> { impl ExpRewriterFunctions for IfElseTransformer<'_> { fn rewrite_exp(&mut self, exp: Exp) -> Exp { - if let Some(result) = self.try_make_if_else(exp.clone()) { - self.rewrite_exp_descent(result) - } else if let Some(result) = self.try_make_if(exp.clone()) { - self.rewrite_exp_descent(result) - } else { - self.rewrite_exp_descent(exp) + // Please maintain the order of the transformers as their results clear hurdles for the next one. + let transformers: [fn(&Self, Exp) -> Option; 4] = [ + Self::try_remove_redundant_loop, + Self::try_make_if, + Self::try_make_if_else, + Self::try_remove_redundant_exp, + ]; + let mut old_exp = exp; + // Recursively apply the transformers until a fixed point is reached. + // Each iteration, if any transformer is applied, will eliminate one or more loops or remove some expressions + // - this guarantees the fixed point to be reached + // - new transformers should follow the same principle + loop { + let mut new_exp = None; + for transformer in transformers { + if let Some(result) = transformer(self, old_exp.clone()) { + new_exp = Some(self.rewrite_exp_descent(result)); + break; + } + } + let new_exp = new_exp.unwrap_or_else(|| self.rewrite_exp_descent(old_exp.clone())); + if new_exp == old_exp { + return old_exp; + } + old_exp = new_exp; } } } impl IfElseTransformer<'_> { - /// Attempts to create an if-then-else from the given expression. - /// This recognizes the pattern below, as produced by the AST - /// generator. Here, with 'does not branch out of a loop' we mean - /// that an expressions does not contain any unbound break or - /// continue statements which point outside the given loop: + /// Attempts to remove redundant loops introduced during control flow structuring and optimization /// + /// It identifies and transforms the following patterns (Pattern 1): /// ```move - /// loop { /// loop { // no loop header - /// ( if (c_i) break; )+ - /// // no reference to inner loop - /// break[1] + /// stms // no reference to current loop (via `break` or `continue`) + /// break[*]|abort|return|continue[>0] /// } - /// - /// } - /// ==> - /// if (c1 || .. || cn) { - /// loop { - /// + /// ``` + /// ===> + /// ```move + /// stms where loop_nest -= 1 + /// break[*]|abort|return|continue[>0] where loop_nest -= 1 (in case of break[0], remove it) /// } - /// else { + /// ``` + /// Why the transformation is valid: + /// - The loop can iterate at most once, so it is equivalent to the body of the loop. + /// - If the loop body exits to an outer loop, the `loop_nest -= 1` will maintain the exit to the outer loop. + /// + /// + /// If the above pattern does not match, it also checks for and transforms the following pattern (Pattern 2): + /// ```move + /// 'outer loop { // no loop header + /// loop { + /// stms // no `continue[1]` (i.e., does not continue to the 'outer loop) + /// } + /// break[0] + /// } + /// ``` + /// ===> + /// ```move /// loop { - /// where loop_nest -= 1 + /// stms where loop_nest -= 1 /// } - /// } /// ``` - fn try_make_if_else(&self, exp: Exp) -> Option { - let node_id = exp.node_id(); - let default_loc = self.builder.env().get_node_loc(node_id); + /// why the transformation is valid: similar to Pattern 1 + /// + fn try_remove_redundant_loop(&self, exp: Exp) -> Option { + let (loop_id, body) = match_ok!(exp.as_ref(), ExpData::Loop(_0, _1))?; + // Make sure this loop does not continue itself + // Otherwise, it is a loop in the original code and we should not remove it. + self.check_no_loop_header(*loop_id)?; + let default_loc = self.builder.env().get_node_loc(*loop_id); - // Match the pattern as described above - let outer_body = match_ok!(exp.as_ref(), ExpData::Loop(_, _0))?; - let (outer_first, then_branch) = self.builder.extract_first(outer_body.clone()); - let (inner_id, inner_body) = match_ok!(outer_first.as_ref(), ExpData::Loop(_0, _1))?; - let (cond, inner_rest) = self.builder.match_if_break_list(inner_body.clone())?; - // When getting the else branch, do not match exits as there are better treated with - // if without else. - let else_branch = self.builder.extract_terminated_prefix( + // Make sure this loop terminates (always exits) + // and extract the terminating prefix + let terminated_body = self.builder.extract_terminated_prefix( &default_loc, - inner_rest, - 1, - /*allow_exit*/ false, + body.clone(), + 0, + /*allow_exit*/ true, )?; - // Check whether the inner 'loop' is not a loop header - self.check_no_loop_header(*inner_id)?; + // match Pattern 1 (see doc above) + let branch_cond_1 = |loop_nest: usize, nest: usize, _: bool| nest == loop_nest; + if !terminated_body.customizable_branches_to(branch_cond_1) { + return Some(terminated_body.rewrite_loop_nest(-1)); + } - // Check whether else-branch is not referencing the inner loop - if else_branch.branches_to(0..1) { - return None; + // match Pattern 2 (see doc above) + let branch_cond_2 = |loop_nest: usize, nest: usize, cont: bool| cont && nest == loop_nest; + if matches!(terminated_body.as_ref(), ExpData::Loop(_, _)) + && !terminated_body.customizable_branches_to(branch_cond_2) + { + return Some(terminated_body.rewrite_loop_nest(-1)); } - // Create result - let else_branch = else_branch.rewrite_loop_nest(-1); - let then_branch = self.builder.seq(&default_loc, then_branch); - Some(self.builder.if_else( - cond.clone(), - self.builder.push_loop_block_into(then_branch), - self.builder.push_loop_block_into(else_branch), - )) + None } - /// Attempts to create an if-then (without else) from the given expression. - /// This recognizes the pattern below, as produced by the AST - /// generator: + /// Attempts to create `if-then` from the given expression. + /// This transforms the pattern below /// /// ```move /// loop { // no loop header - /// ( if (c_i) break; )+ - /// // does not reference loop - /// break|abort|return|continue - /// } - /// + /// // no reference to current loop + /// [ if (c_i) { + /// break[*]|abort|return|continue[>0]; + /// } + /// // no reference to current loop ]+ + /// // no reference to current loop + /// break[*]|abort|return|continue[>0]; + /// } // end of loop /// ==> - /// - /// if (!(c1 || .. || cn)) { - /// where loop_nest -= 1 + /// + /// if (!c_1) { + /// where loop_nest -= 1 + /// if (!c_2){ + /// where loop_nest -= 1 + /// ... + /// if (!c_n) { + /// where loop_nest -= 1 + /// } + /// } /// } /// ``` + /// Why the transformation is valid: + /// - The loop can iterate once at most, so it is equivalent to the body of the loop. + /// - `then_branch_i` is only reached when `c_i` is false, so the `if-break-then` is equivalent to `if(!c_i) { }` + /// - If the loop body exits to an outer loop, the `loop_nest -= 1` operation will maintain the exit to the outer loop. + /// fn try_make_if(&self, exp: Exp) -> Option { - let node_id = exp.node_id(); - let default_loc = self.builder.env().get_node_loc(node_id); - - // Match the pattern as described above let (loop_id, body) = match_ok!(exp.as_ref(), ExpData::Loop(_0, _1))?; - let (cond, rest) = self.builder.match_if_break_list(body.clone())?; - let then_branch = self.builder.extract_terminated_prefix( + self.check_no_loop_header(*loop_id)?; + let default_loc = self.builder.env().get_node_loc(*loop_id); + + // Transform `if-else` where applicable (see doc of the function) + let body = self.try_unify_if_else(body.clone()); + + // Find the transformable pattern (see doc above) + // `if_cond_then_list` ALWAYS follows the format of [, c_1, , c_2, , ..., c_n, ], + let mut if_cond_then_list = self.builder.match_if_break_else_list(body.clone(), 0)?; + let end_branch = if_cond_then_list + .pop() + .expect("end branch should always be present"); + + // Make sure the always exits the loop + let end_branch = self.builder.extract_terminated_prefix( &default_loc, - rest, + end_branch.clone(), 0, /*allow_exit*/ true, )?; + // Make sure the does not refer to the current loop + let branch_cond = |loop_nest: usize, nest: usize, _: bool| loop_nest == nest; + if end_branch.customizable_branches_to(branch_cond) { + return None; + } + + // Recursively assemble a nested-if expression + // - start from the + // - put the as the true branch of `if(!c_n)`, forming `if(!c_n) { }` + // - put the new `if` expression as the `new_body` + // - continue with an upper-level branch, say `branch[n-1]` + // - put the `branch[n-1]` together with the previous `new_body` as the true branch of `if(!c[n-1])`, forming `if(!c[n-1]) { ; new_body }` + // - put the new `if` expression as the `new_body` + // - repeat until we reach the + let mut cur_branch = end_branch.rewrite_loop_nest(-1); + let mut new_body = self.builder.nop(&default_loc); + while if_cond_then_list.len() > 1 { + let cond = if_cond_then_list.pop().expect("condition is expected"); + new_body = self.builder.if_else( + self.builder.not(cond), + self.builder.seq(&default_loc, vec![cur_branch, new_body]), + self.builder.nop(&default_loc), + ); + cur_branch = if_cond_then_list + .pop() + .expect("branch before if is expected"); + + // get the terminated prefix of `cur_branch` or fallback to the original + cur_branch = self + .builder + .extract_terminated_prefix( + &default_loc, + cur_branch.clone(), + 0, + /*allow_exit*/ true, + ) + .unwrap_or(cur_branch); - // Check conditions + // Make sure the `cur-branch` does not refer to the current loop + if cur_branch.customizable_branches_to(branch_cond) { + return None; + } + cur_branch = cur_branch.rewrite_loop_nest(-1); + } + // Add the `begin_stmts` before the nested `if` expression + Some(self.builder.seq(&default_loc, vec![cur_branch, new_body])) + } + + /// Attempts to create `if-then-else` from the given expression. + /// This transforms the pattern below + /// + /// ```move + /// loop { // no loop header + /// // no reference to current loop + /// [ if (c_i) { + /// then_branch_i // no reference to current loop + /// break[*]|abort|return|continue[>0]; + /// } + /// else_branch_i // no reference to current loop ]+ + /// break|abort|return|continue + /// ==> + /// + /// if (c_1) { + /// where abort|return maintained and loop_nest -= 1 + /// } else { + /// where abort|return maintained and loop_nest -= 1 + /// if (c_2) { + /// where abort|return maintained and loop_nest -= 1 + /// } else { + /// where abort|return maintained and loop_nest -= 1 + /// ... + /// if (c_n) { + /// then_branch_n where abort|return maintained and loop_nest -= 1 + /// } else { + /// where abort|return maintained and loop_nest -= 1 + /// } + /// } + /// } + /// ``` + /// Why the transformation is valid: similar to `try_make_if` + /// + fn try_make_if_else(&self, exp: Exp) -> Option { + let (loop_id, body) = match_ok!(exp.as_ref(), ExpData::Loop(_0, _1))?; self.check_no_loop_header(*loop_id)?; - if then_branch.branches_to(0..1) { + let default_loc = self.builder.env().get_node_loc(*loop_id); + + // Transform `if-else` where applicable (see doc of the function) + let body = self.try_unify_if_else(body.clone()); + + // Find the transformable pattern (see doc above) + // `if_else_list` ALWAYS follows the format of + // <[seq(begin_stmts), c_1, seq(then_branch_1), seq(else_branch_1), c_2, seq(then_branch_2), seq(else_branch_2), ... c_n, seq(then_branch_n), seq(else_branch_n)]> + let mut if_else_list = self + .builder + .match_if_branch_break_branch_list(body.clone())?; + let end_branch = if_else_list + .pop() + .expect("end branch should always be present"); + + // Make sure the always exits the loop + let end_branch = self.builder.extract_terminated_prefix( + &default_loc, + end_branch.clone(), + 0, + /*allow_exit*/ true, + )?; + // Make sure the does not refer to the current loop + let branch_cond = |loop_nest: usize, nest: usize, _: bool| nest == loop_nest; + if end_branch.customizable_branches_to(branch_cond) { return None; } - // Construct result - let then_branch = then_branch.rewrite_loop_nest(-1); - Some(self.builder.if_else( - self.builder.not(cond), - then_branch, - self.builder.nop(&default_loc), - )) + // recursively assemble a nested `if-else` expression + // - start from the + // - put the as the false branch of `if(c_n)` and as the true branch, + // forming `if(c_n) { } else { }` + // - put the new `if-else` expression as the `new_body` + // - continue with an upper-level branch, say and + // - put the as the true branch of `if(c_n-1)` + // and together with `new_body` as the false branch, + // forming `if(c_n-1) { } else { ; new_body }` + // - put the new `if-else` expression as the `new_body` + // - repeat until we reach the + let mut else_branch = end_branch.rewrite_loop_nest(-1); + let mut new_body = self.builder.nop(&default_loc); + + while if_else_list.len() > 2 { + let mut then_branch = if_else_list.pop().expect("then branch is expected"); + // Make sure the always exits the loop + then_branch = self + .builder + .extract_terminated_prefix( + &default_loc, + then_branch.clone(), + 0, + /*allow_exit*/ true, + ) + .expect("then_branch must be terminated"); + + // Make sure the does not refer to the current loop + if then_branch.customizable_branches_to(branch_cond) { + return None; + } + then_branch = then_branch.rewrite_loop_nest(-1); + let cond = if_else_list.pop().expect("condition is expected"); + new_body = self.builder.if_else( + cond, + then_branch, + self.builder.seq(&default_loc, vec![else_branch, new_body]), + ); + + else_branch = if_else_list.pop()?; + // get the terminated prefix of or fallback to the original + else_branch = self + .builder + .extract_terminated_prefix( + &default_loc, + else_branch.clone(), + 0, + /*allow_exit*/ true, + ) + .unwrap_or(else_branch); + + // make sure the does not refer to the current loop + if else_branch.customizable_branches_to(branch_cond) { + return None; + } + // in case the branches to an outer loop + else_branch = else_branch.rewrite_loop_nest(-1); + } + + // Add the to the top of the expression + Some(self.builder.seq(&default_loc, vec![else_branch, new_body])) + } + + /// Attempts to remove redundant expressions generated during control flow transformations. + fn try_remove_redundant_exp(&self, mut exp: Exp) -> Option { + let removers: [fn(&Self, Exp) -> Option; 2] = [ + Self::try_flatten_sequence, + Self::try_remove_unreachable_code, + ]; + + let mut changed = false; + for remover in removers { + if let Some(new_exp) = remover(self, exp.clone()) { + exp = new_exp; + changed = true; + } + } + + if changed { + Some(exp) + } else { + None + } + } + + /// Attempts to remove dangling `seq` expressions produced by control flow transformations. + /// + /// It converts the following pattern + /// ```move + /// seq { + /// stmt1 + /// stmt2 + /// seq_1 { + /// stmt3 + /// stmt4 + /// } + /// seq_2 { + /// stmt5 + /// stmt6 + /// } + /// ... + /// } + /// ==> + /// seq { + /// stmt1 + /// stmt2 + /// stmt3 + /// stmt4 + /// stmt5 + /// stmt6 + /// ... + /// } + /// ``` + fn try_flatten_sequence(&self, exp: Exp) -> Option { + let mut new_stms = vec![]; + let mut changed = false; + let (seq_id, stmts) = match_ok!(exp.as_ref(), ExpData::Sequence(_0, _1))?; + stmts.iter().for_each(|stmt| { + if let Some(inner_stmts) = match_ok!(stmt.as_ref(), ExpData::Sequence(_, _0)) { + new_stms.extend(inner_stmts.clone()); + changed = true; + } else { + new_stms.push(stmt.clone()); + } + }); + + if changed { + let default_loc = self.builder.env().get_node_loc(*seq_id); + Some(self.builder.seq(&default_loc, new_stms)) + } else { + None + } + } + + /// Attempts to remove redundant code produced by control flow transformations. + /// + /// It converts the following pattern + /// ```move + /// seq { + /// stmt1 + /// stmt2 + /// break|continue|return|abort + /// ... + /// } + /// ==> + /// seq { + /// stmt1 + /// stmt2 + /// break|continue|return|abort + /// } + /// ``` + fn try_remove_unreachable_code(&self, exp: Exp) -> Option { + let (seq_id, stmts) = match_ok!(exp.as_ref(), ExpData::Sequence(_0, _1))?; + + let terminating_prefix_idx = stmts + .iter() + .position(|stmt| { + matches!( + stmt.as_ref(), + ExpData::LoopCont(..) + | ExpData::Return(..) + | ExpData::Call(_, Operation::Abort, _) + ) + }) + .unwrap_or(stmts.len()); + + // We only return the prefix when the seq terminates early + if terminating_prefix_idx + 1 < stmts.len() { + let default_loc = self.builder.env().get_node_loc(*seq_id); + Some( + self.builder + .seq(&default_loc, stmts[..=terminating_prefix_idx].to_vec()), + ) + } else { + None + } + } + + /// Attempts to unify 3 patterns of an `if-else` Exp or `if-else`s embedded in a Sequence Exp. + /// The goal is to uniform the code for matching `try_make_if` and `try_make_if_else`. Otherwise, we will have to enumerate too many variants of them. + /// If `try_make_if` and `try_make_if_else` are not matched eventually, the unification here will be discarded. + /// + /// Pattern 1 + /// ```move + /// if(c) { + /// + /// } else { + /// + /// break + /// } + /// ``` + /// ==> + /// ```move + /// if(!c) { + /// + /// break + /// } + /// + /// ``` + /// + /// Pattern 2 + /// ```move + /// if(c) { + /// + /// break + /// } else { + /// + /// } + /// ``` + /// ==> + /// ```move + /// if(c) { + /// + /// break + /// } + /// + /// ``` + /// + /// Pattern 3 + /// ```move + /// if(c_1) { + /// if (c_2) { + /// ... + /// if (c_n) { + /// stmts + /// break + /// } + /// } + /// } + /// ``` + /// ==> + /// ```move + /// if(c_1 && c_2 && ... && c_n) { + /// stmts + /// break + /// } + /// ``` + fn try_unify_if_else(&self, mut exp: Exp) -> Exp { + let node_id = exp.node_id(); + let default_loc = self.builder.env().get_node_loc(node_id); + + let mut new_exp = vec![]; + loop { + let (first, rest) = self.builder.extract_first(exp.clone()); + if let Some((c, if_true, if_false)) = self.builder.match_if_else_break(first.clone()) { + // Pattern 1 + let new_if = self.builder.if_else( + self.builder.not(c), + if_false, + self.builder.nop(&default_loc), + ); + new_exp.push(new_if); + new_exp.push(if_true); + } else if let Some((c, if_true, if_false)) = + self.builder.match_if_break_else(first.clone()) + { + // Pattern 2 + let new_if = self + .builder + .if_else(c, if_true, self.builder.nop(&default_loc)); + new_exp.push(new_if); + new_exp.push(if_false); + } else if let Some((c, if_true)) = self.builder.match_nested_if_break(first.clone()) { + // Pattern 3 + let new_if = self + .builder + .if_else(c, if_true, self.builder.nop(&default_loc)); + new_exp.push(new_if); + } else { + // Not an if-branch, so we add it to the current sequence + new_exp.push(first); + }; + // No more exps to process + if rest.is_empty() { + break; + } + exp = self.builder.seq(&default_loc, rest); + } + self.builder.seq(&default_loc, new_exp) } fn check_no_loop_header(&self, node_id: NodeId) -> Option<()> { @@ -1498,18 +2056,29 @@ impl IfElseTransformer<'_> { /// A rewriter which eliminates single and unused assignments. pub fn transform_assigns(target: &FunctionTarget, exp: Exp) -> Exp { - let usage = analyze_usage(target, exp.as_ref()); + let post_usage = analyze_post_usage(target, exp.as_ref()); let builder = ExpBuilder::new(target.global_env()); - AssignTransformer { usage, builder }.rewrite_exp(exp) + AssignTransformer { + usage: post_usage, + builder, + } + .rewrite_exp(exp) } /// A rewriter which binds free variables. pub fn bind_free_vars(target: &FunctionTarget, exp: Exp) -> Exp { - let usage = analyze_usage(target, exp.as_ref()); + let usage = analyze_global_usage(exp.as_ref()); + if usage.is_empty() { + // If there are no free variables, we can return the expression as is. + return exp; + } + // Let's make sure the input expression is a sequence + assert!(matches!(exp.as_ref(), ExpData::Sequence(_, _))); let builder = ExpBuilder::new(target.global_env()); FreeVariableBinder { usage, builder, + bound: BTreeSet::new(), // Parameters set to be bound bound_vars: vec![target .get_parameters() @@ -1526,21 +2095,25 @@ struct AssignTransformer<'a> { builder: ExpBuilder<'a>, } -#[allow(unused)] -struct FreeVariableBinder<'a> { - /// Usage information about variables in the expression - usage: BTreeMap, - /// The expression builder. - builder: ExpBuilder<'a>, - /// Variables which are bound in outer scopes - bound_vars: Vec>, +impl AssignTransformer<'_> { + /// Check if an expression is safe to eliminate, assuming its result is never used. + /// The current rules are insanely conservative to ensure safety + fn safe_to_eliminate(exp: &Exp) -> bool { + match exp.as_ref() { + ExpData::LocalVar(..) | ExpData::Value(..) | ExpData::Temporary(..) => true, + ExpData::Call(_, ops, args) => { + ops.is_ok_to_remove_from_code() && args.iter().all(Self::safe_to_eliminate) + }, + _ => false, + } + } } impl ExpRewriterFunctions for AssignTransformer<'_> { fn rewrite_exp(&mut self, exp: Exp) -> Exp { if let ExpData::Sequence(id, stms) = exp.as_ref() { // If this is a sequence, simplify. - ExpData::Sequence(*id, self.simplify_seq(*id, stms)).into_exp() + ExpData::Sequence(*id, self.simplify_seq(stms)).into_exp() } else { self.rewrite_exp_descent(exp) } @@ -1548,159 +2121,514 @@ impl ExpRewriterFunctions for AssignTransformer<'_> { } impl AssignTransformer<'_> { - fn simplify_seq(&mut self, seq_id: NodeId, stms: &[Exp]) -> Vec { - let Some(last) = stms.last() else { + fn simplify_seq(&mut self, stms: &[Exp]) -> Vec { + if stms.is_empty() { return vec![]; - }; - let mut after_block_usage = self.usage[&last.node_id()].clone(); - if matches!(last.as_ref(), ExpData::LoopCont(..)) && stms.len() > 1 { - // TODO: it seems to be weird to need to go back after terminator, but the usage - // after the terminator is cleared (because the code there is never used). Lets try - // to consolidate this in a better way - let before_last = &stms[stms.len() - 2]; - if let Some(u) = self.usage.get(&before_last.node_id()) { - after_block_usage.join(u); - } } - let mut blocks = vec![]; let mut new_stms = vec![]; let mut substitution: BTreeMap = BTreeMap::new(); - for stm in stms { + for (idx, stm) in stms.iter().enumerate() { let stm_usage = self.usage[&stm.node_id()].clone(); match stm.as_ref() { - // Check whether an assignment can be eliminated because it is used only once. - // This is often the case with stackless bytecode generated - // from stack code. - ExpData::Assign(id, Pattern::Var(_, var), rhs) + // Check whether an assignment can be eliminated by replacing the use of the LHS directly with the RHS + ExpData::Assign(_, Pattern::Var(var_id, var), rhs) if - // Cannot be read outside this block - after_block_usage.read_count(*var) == 0 && - // Must be read zero or once inside the block - stm_usage.read_count(*var) <= 1 && - // If it's been written to after, only via this exact statement (this - // happens if we are in a loop). - stm_usage.is_single_assignment(*var, id) && - // Must not be borrowed after this statement - !stm_usage.is_borrowed(*var) - => - { - substitution.insert( - *var, - self.rewrite_exp(self.builder.unfold(&substitution, rhs.clone()))); + // If it's been written to, must be only via this exact statement + stm_usage.is_single_assignment(*var, var_id) && + // Must not be borrowed after this statement + !stm_usage.is_borrowed(*var) && + // Must be read zero times or once + stm_usage.read_count(*var) <= 1 && + // The read can only be done by statements after the current statement in this sequence + stm_usage.only_read_in_range(var, &stms[idx + 1..]) + => { + // If the result is not used and the RHS is safe to eliminate, we can discard the assignment + let read_cnt = stm_usage.read_count(*var); + let rhs_unfolded = self.builder.unfold(&substitution, rhs.clone()); + if read_cnt == 0 && Self::safe_to_eliminate(&rhs_unfolded) { + continue; + } + // If the RHS is safe to simplify and the result is used once, we can substitute the var with RHS + if read_cnt == 1 && self.safe_to_simplify(var, rhs, stms.get(idx + 1..).unwrap_or(&[]), &substitution) { + assert!(substitution.insert(*var, self.rewrite_exp(rhs_unfolded)).is_none()); + continue; + } + // Otherwise, let's keep the assignment as it is + new_stms.push(self.rewrite_exp(self.builder.unfold(&substitution, stm.clone()))); }, - // Check whether an assignment can be transformed into a let - // TODO: refine to the correct implementation, the below doesn't work - // if variable is already assigned (need reaching definitions). - /* - ExpData::Assign(_, pat, rhs) - // None of the variables in the pattern is used after the block - if pat.vars().into_iter().all(|(_, var)| after_block_usage.read_count(var) == 0) => { - // Save building the block for later when we have the rest of the sequence - blocks.push((new_stms, pat.clone(), - self.rewrite_exp( - self.builder.unfold(&substitution, rhs.clone())))); - new_stms = vec![]; - } - */ _ => { new_stms.push(self.rewrite_exp( self.builder.unfold(&substitution, stm.clone()))) }, } } - let default_loc = self.builder.env().get_node_loc(seq_id); - // Process all blocks which have been saved for later - while let Some((prev_stms, pat, def)) = blocks.pop() { - let block = - self.builder - .block(pat, Some(def), self.builder.seq(&default_loc, new_stms)); - new_stms = prev_stms; - new_stms.push(block) - } new_stms } + + /// Analyze if the following pattern + /// ```move + /// let _t = rhs; // _t is only used once and never written to again + /// stmt1 + /// stmt2 + /// ... + /// stmtN + /// use(_t) + /// ``` + /// can be safely simplified to + /// ```move + /// stmt1 + /// stmt2 + /// ... + /// stmtN + /// use(rhs) + /// ``` + /// + fn safe_to_simplify( + &self, + target_var: &Symbol, + rhs: &Exp, + stmts: &[Exp], + substitution: &BTreeMap, + ) -> bool { + // If there are no statements after the assignment, or + // if the target var is used immediately after its assignment, we can safely simplify it. + // While this seems to be hacky, it is very effective in reducing compiler-introduced temp vars. + if stmts.first().is_none_or(|first_exp| { + Self::used_immediately( + target_var, + &self.builder.unfold(substitution, first_exp.clone()), + Self::safe_to_eliminate(rhs), + ) + }) { + return true; + } + + // Make sure RHS has no side effects + if !Self::safe_to_eliminate(&self.builder.unfold(substitution, rhs.clone())) { + return false; + } + + // Check if moving the RHS to a later location might incur different results + // Algorithm: + // - Gather all the variables used by the RHS and their types + // - Check every statement in the sequence before usage of the target variable: + // - If any of the RHS free var is redefined or mutably borrowed, we cannot move the RHS around + // + // Step 1: gather all free vars used by the RHS + let rhs = self.builder.unfold(substitution, rhs.clone()); + let rhs_free_vars = rhs.free_vars(); + + // Analyze all the follow-up statements + for stmt in stmts { + // Step 2: Get all the free vars usage by a statement + let stmt = self.builder.unfold(substitution, stmt.clone()); + let mut stmt_usage = UsageInfo::default(); + fetch_usage(&mut stmt_usage, &stmt); + + // Step 3: Give up if any of the free vars used by the RHS is written to/mutably borrowed in the statement + if rhs_free_vars + .iter() + .any(|var| stmt_usage.writes.contains_key(var)) + { + return false; + } + + // Step 4: If the target var is reached, we are good to go! + let stmt_free_vars = stmt.free_vars(); + if stmt_free_vars.contains(target_var) { + return true; + } + } + true + } + + /// Check if the target variable is the first variable accessed during execution of the expression. + /// `rhs_safe` indicates whether the RHS assigned to the target variable has no side effects. + fn used_immediately(target_var: &Symbol, exp: &Exp, rhs_safe: bool) -> bool { + match exp.as_ref() { + ExpData::LocalVar(_, var) => *var == *target_var, + ExpData::IfElse(_, cond, _, _) => Self::used_immediately(target_var, cond, rhs_safe), + ExpData::Assign(_, _, rhs) => Self::used_immediately(target_var, rhs, rhs_safe), + ExpData::Sequence(_, stmts) => stmts + .first() + .is_some_and(|e| Self::used_immediately(target_var, e, rhs_safe)), + ExpData::Block(_, _, bind, body) => { + if let Some(bind) = bind { + // If there is a binding, we check the bind + Self::used_immediately(target_var, bind, rhs_safe) + } else { + // Otherwise, we check the body + Self::used_immediately(target_var, body, rhs_safe) + } + }, + ExpData::Match(_, target, _) => Self::used_immediately(target_var, target, rhs_safe), + ExpData::Return(_, ret) => Self::used_immediately(target_var, ret, rhs_safe), + ExpData::Mutate(_, _, rhs) => Self::used_immediately(target_var, rhs, rhs_safe), + ExpData::Call(_, op, args) => match op { + // Operations with exactly one argument + Operation::Freeze(_) + | Operation::Borrow(_) + | Operation::Deref + | Operation::Not + | Operation::Negate + | Operation::Cast + | Operation::Select(_, _, _) + | Operation::SelectVariants(_, _, _) + | Operation::TestVariants(_, _, _) => args + .first() + .is_some_and(|e| Self::used_immediately(target_var, e, rhs_safe)), + // Operations with two arguments + Operation::Add + | Operation::Copy + | Operation::Move + | Operation::Sub + | Operation::Mul + | Operation::Mod + | Operation::Div + | Operation::BitOr + | Operation::BitAnd + | Operation::Xor + | Operation::Shl + | Operation::Shr + | Operation::And + | Operation::Or + | Operation::Eq + | Operation::Neq + | Operation::Lt + | Operation::Gt + | Operation::Le + | Operation::Ge => args.first().zip(args.get(1)).is_some_and(|(op1, op2)| { + // Safe to assume immediate reuse if: + // - the target variable is used in the first argument, OR + // - the target variable is used in the second argument, but both the first argument and the RHS have no side effects. + Self::used_immediately(target_var, op1, rhs_safe) + || (Self::safe_to_eliminate(op1) + && rhs_safe + && Self::used_immediately(target_var, op2, rhs_safe)) + }), + // Operations with or without arguments + Operation::MoveFunction(_, _) | Operation::Pack(_, _, _) | Operation::Tuple => { + for (idx, arg) in args.iter().enumerate() { + // Safe to assume immediate reuse if: + // - the target variable is immediately used in the first argument + if idx == 0 && Self::used_immediately(target_var, arg, rhs_safe) { + return true; + } + // OR + // - the target variable is immediately used in a follow-up argument, but all the arguments before it and the RHS have no side effects + if idx != 0 && rhs_safe && Self::used_immediately(target_var, arg, rhs_safe) + { + return true; + } + if !rhs_safe || !Self::safe_to_eliminate(arg) { + return false; + } + } + false + }, + // [TODO] handle global resource operators after issue #17010 is fixed + Operation::Abort + | Operation::Closure(..) + | Operation::Vector + | Operation::Exists(..) + | Operation::BorrowGlobal(..) + | Operation::MoveFrom + | Operation::MoveTo + | Operation::SpecFunction(..) + | Operation::UpdateField(..) + | Operation::Result(..) + | Operation::Index + | Operation::Slice + | Operation::Range + | Operation::Implies + | Operation::Iff + | Operation::Identical + | Operation::Len + | Operation::TypeDomain + | Operation::TypeValue + | Operation::ResourceDomain + | Operation::Global(..) + | Operation::CanModify + | Operation::Old + | Operation::Trace(..) + | Operation::EmptyVec + | Operation::SingleVec + | Operation::UpdateVec + | Operation::ConcatVec + | Operation::IndexOfVec + | Operation::InRangeRange + | Operation::InRangeVec + | Operation::ContainsVec + | Operation::RangeVec + | Operation::MaxU256 + | Operation::MaxU128 + | Operation::MaxU64 + | Operation::MaxU32 + | Operation::MaxU16 + | Operation::MaxU8 + | Operation::Bv2Int + | Operation::Int2Bv + | Operation::AbortFlag + | Operation::AbortCode + | Operation::WellFormed + | Operation::BoxValue + | Operation::UnboxValue + | Operation::EmptyEventStore + | Operation::EventStoreIncludedIn + | Operation::EventStoreIncludes + | Operation::ExtendEventStore + | Operation::NoOp => false, + }, + ExpData::Value(..) + | ExpData::Temporary(..) + | ExpData::Lambda(..) + | ExpData::Quant(..) + | ExpData::Loop(..) + | ExpData::LoopCont(..) + | ExpData::SpecBlock(..) + | ExpData::Invoke(..) + | ExpData::Invalid(..) => false, + } + } +} + +#[allow(unused)] +struct FreeVariableBinder<'a> { + /// Usage information about variables in the expression + usage: BTreeMap>, + /// The expression builder. + builder: ExpBuilder<'a>, + /// Variables which have been bound inside a given expression + bound: BTreeSet, + /// Variables which are bound in outer scopes + bound_vars: Vec>, } impl ExpRewriterFunctions for FreeVariableBinder<'_> { - fn rewrite_exp(&mut self, mut exp: Exp) -> Exp { - // TODO: this currently just adds lets on outermost level. - // Refine this to push lets down to leafs. - let mut bound = BTreeSet::new(); - exp.clone().visit_free_local_vars(|node_id, var| { - if bound.insert(var) && !self.bound_vars.iter().any(|b| b.contains(&var)) { - exp = self.builder.block( - Pattern::Var(self.builder.clone_node_id(node_id), var), - None, - exp.clone(), - ); + fn rewrite_exp(&mut self, exp: Exp) -> Exp { + // Try to bind free vars in deeper expressions first + let mut exp = self.rewrite_exp_descent(exp); + + // We only bind free variables in sequences + let ExpData::Sequence(_, stmts) = exp.as_ref() else { + return exp; + }; + + // Collect the free variables used in this sequence. + let mut free_vars = BTreeMap::new(); + exp.visit_free_local_vars(|node_id, var| { + if !self.bound_vars.iter().any(|b| b.contains(&var)) { + free_vars + .entry(var) + .or_insert_with(BTreeSet::new) + .insert(node_id); } }); + + // Try to collect free vars that should be bound in this sequence, using two conditions: + // 1. the var is only used in this sequence + // 2. the var has not been bound in its sub-sequences + free_vars.retain(|var, node_ids| { + self.all_usage_contained(*var, node_ids) && self.bound.insert(*var) + }); + + // Let's bind the free variables who first usage is a definition + let default_loc = self.builder.env().get_node_loc(exp.node_id()); + exp = self.builder.seq( + &default_loc, + self.bind_defined_vars(stmts, &mut free_vars, &default_loc), + ); + + // Let's bind the remaining free variables at the beginning of the sequence + for (var, node_ids) in &free_vars { + exp = self.builder.block( + Pattern::Var( + self.builder.clone_node_id( + *node_ids + .iter() + .next() + .expect("a free var must be used at least once"), + ), + *var, + ), + None, + exp.clone(), + ); + } exp } } +impl<'a> FreeVariableBinder<'a> { + /// Check if all usages of `target_var` are contained in `exp`. + fn all_usage_contained(&self, target_var: Symbol, local_var_usage: &BTreeSet) -> bool { + self.usage + .get(&target_var) + .is_none_or(|global_usage| *global_usage == *local_var_usage) + } + + /// Given a sequence of statements and a list of free vars that can be safely bound to the sequence, + /// this function binds a free var with its definition IF the definition is the var's FIRST usage in the sequence. + /// Any un-bound free vars needs to be processed later by the caller function. + fn bind_defined_vars( + &self, + stmts: &Vec, + free_vars: &mut BTreeMap>, + loc: &Loc, + ) -> Vec { + let mut blocks = vec![]; + // Indicate which variables have been visited + let mut visited = BTreeSet::new(); + let mut new_stmts = vec![]; + for stmt in stmts { + match stmt.as_ref() { + ExpData::Assign(_, pat, rhs) => { + // Mark all the vars that are used in the RHS + rhs.visit_free_local_vars(|_, var| { + visited.insert(var); + }); + // If all vars in the pattern can be bound in this sequence, and they are first used in this assignment, + // we can bind them with this assignment (definition). + if pat.vars().into_iter().all(|(_, var)| { + free_vars.iter().any(|(free_var, _)| *free_var == var) + && !visited.contains(&var) + }) { + // save the statements processed so far and record that a new block needs to be created + blocks.push((new_stmts, pat.clone(), rhs.clone())); + for var in pat.vars() { + // mark the var has been bound and visited + free_vars.remove(&var.1); + visited.insert(var.1); + } + // reset the statement tracker for next block + new_stmts = vec![]; + } else { + // For all non-boundable vars, mark them as used + for var in pat.vars() { + visited.insert(var.1); + } + new_stmts.push(stmt.clone()); + } + }, + _ => { + // For all non-assignment exps, mark the involved vars as used + stmt.visit_free_local_vars(|_, var| { + visited.insert(var); + }); + new_stmts.push(stmt.clone()); + }, + } + } + + // Now let's assemble a new list of statements with block expressions + while let Some((prev_stmts, pat, def)) = blocks.pop() { + let block = self + .builder + .block(pat, Some(def), self.builder.seq(loc, new_stmts)); + new_stmts = prev_stmts; + new_stmts.push(block) + } + new_stmts + } +} + // =================================================================================== -/// Usage information about variables in an expression. +/// Usage information about variables #[derive(Default, Clone, AbstractDomain)] struct UsageInfo { - /// Variables which are read by and after this expression. + /// Mapping variables to the set of node IDs where they are read. reads: MapDomain>, - /// Variables which are written by or after this expression. + /// Mapping variables to the set of node IDs where they are written. writes: MapDomain>, - /// Variables which are borrowed by or after this expression, immutable or mutable. + /// Mapping variables to the set of node IDs where they are borrowed, immutable or mutable. borrows: MapDomain>, } -/// Analyze the expression for variable usage and returns a map from node id -/// to the info. -fn analyze_usage(_target: &FunctionTarget, exp: &ExpData) -> BTreeMap { - let mut step_fun = |state: &mut UsageInfo, e: &ExpData| { +/// Analyze an expression for variable usage. +/// It returns a map showing the usage info by code after each descendant expression on the control flow. +fn analyze_post_usage(target: &FunctionTarget, exp: &ExpData) -> BTreeMap { + let mut step_fun = |state: &mut UsageInfo, e: &ExpData| fetch_usage(state, e); + let mut analyzer = FixpointAnalyser::new(false, &mut step_fun); + analyzer.run_until_fixpoint(exp); + let mut post_state = BTreeMap::new(); + analyzer.compute_post_state(&mut post_state, exp, UsageInfo::default()); + if DEBUG { + debug!( + "post exp usage for function {}:\n {}\n", + target.get_name().display(target.global_env().symbol_pool()), + exp.display_with_annotator(target.global_env(), &|id| { + if let Some(u) = post_state.get(&id) { + u.debug_print(target.global_env()) + } else { + "".to_string() + } + }) + ); + } + post_state +} + +/// Analyze an expression and its descendants to build a map from variable symbols to the set of node IDs where they are used. +/// Only bottom most node IDs (i.e., `LocalVar` nodes) are considered. +fn analyze_global_usage(exp: &ExpData) -> BTreeMap> { + let mut var_usage = BTreeMap::new(); + exp.visit_free_local_vars(|node_id, var| { + var_usage + .entry(var) + .or_insert_with(BTreeSet::new) + .insert(node_id); + }); + var_usage +} + +/// Helper function to gather variable usage +fn fetch_usage(state: &mut UsageInfo, e: &ExpData) { + let mut borrows = BTreeSet::new(); + let mut writes = BTreeSet::new(); + + // Recursively gather writes and borrows info first + let mut visitor = |e: &ExpData| { use ExpData::*; match e { - Assign(id, pat, rhs) => { - for (_, var) in pat.vars() { - state.add_write(var, *id) + Assign(_, pat, _) => { + for (var_id, var) in pat.vars() { + writes.insert((var, var_id)); } - rhs.visit_free_local_vars(|id, var| state.add_read(var, id)) }, - Block(id, pat, binding, body) => { - if let Some(b) = binding { - b.visit_free_local_vars(|id, var| state.add_read(var, id)) + Block(_, pat, _, _) => { + for (var_id, var) in pat.vars() { + writes.insert((var, var_id)); } - for (_, var) in pat.vars() { - state.add_write(var, *id) - } - body.visit_free_local_vars(|id, var| state.add_read(var, id)) }, Call(_, Operation::Borrow(kind), args) => args[0].visit_free_local_vars(|id, var| { // Args supposed to be only a single variable, and marking everything in // this exp as borrowed is safe. if *kind == ReferenceKind::Mutable { - state.add_write(var, id) + writes.insert((var, id)); } - state.add_borrow(var, id); + borrows.insert((var, id)); }), - _ => e.visit_free_local_vars(|id, var| state.add_read(var, id)), + _ => {}, } + true }; - let mut analyzer = FixpointAnalyser::new(false, &mut step_fun); - analyzer.run_until_fixpoint(exp); - let mut post_state = BTreeMap::new(); - analyzer.compute_post_state(&mut post_state, exp, UsageInfo::default()); - if DEBUG { - debug!( - "usage: {}", - exp.display_with_annotator(_target.global_env(), &|id| { - if let Some(u) = post_state.get(&id) { - u.debug_print(_target.global_env()) - } else { - "".to_string() - } - }) - ); + e.visit_pre_order(&mut visitor); + + // Why not directly add writes and borrows in the loop above: writes removes borrows! + + for (var, id) in writes.iter() { + state.add_write(*var, *id); } - post_state + for (var, id) in borrows.iter() { + state.add_borrow(*var, *id); + } + // Why not collects reads together with writes and borrows in the loop above: too many cases and easy to miss! + e.visit_free_local_vars(|id, var| { + if !writes.contains(&(var, id)) && !borrows.contains(&(var, id)) { + state.add_read(var, id) + } + }); } impl UsageInfo { @@ -1744,6 +2672,16 @@ impl UsageInfo { .unwrap_or(false) } + /// Check if a var is read in the given range of expressions + fn only_read_in_range(&self, var: &Symbol, range: &[Exp]) -> bool { + self.reads.get(var).is_none_or(|read_set| { + read_set.iter().all(|reader| { + // Check if every read of the variable is by some expression in the range + range.iter().any(|exp| exp.node_ids().contains(reader)) + }) + }) + } + #[allow(unused)] fn debug_print(&self, env: &GlobalEnv) -> String { let disp = |s: &str, d: &MapDomain>| { @@ -1831,9 +2769,10 @@ where match exp { ExpData::Sequence(_, stms) if !stms.is_empty() => { for stm in stms.iter().rev() { - if let ExpData::LoopCont(cont_id, _, true) = stm.as_ref() { - let header = self.cont_to_loop[cont_id]; - post_state = post_state_map[&header].clone(); + // Let's jump over loop continues as they have been handled + if let ExpData::LoopCont(_, _, _) = stm.as_ref() { + post_state = self.state(&stm.node_id()).cloned().unwrap_or_default(); + continue; } self.compute_post_state(post_state_map, stm.as_ref(), post_state); post_state = self.state(&stm.node_id()).cloned().unwrap_or_default(); @@ -1841,8 +2780,14 @@ where }, ExpData::Loop(id, body) => { for (cont_id, is_cont) in &self.loop_to_cont[id] { + let header = self.cont_to_loop[cont_id]; if *is_cont { - post_state_map.insert(*cont_id, post_state.clone()); + // Var usage after a `continue` should include usage both inside and after the target loop + post_state_map + .insert(*cont_id, self.state(&header).cloned().unwrap_or_default()); + } else { + // Var usage after a `break` should include usage after the target loop + post_state_map.insert(*cont_id, post_state_map[&header].clone()); } } self.compute_post_state(post_state_map, body, post_state) diff --git a/third_party/move/move-model/bytecode/src/borrow_analysis.rs b/third_party/move/move-model/bytecode/src/borrow_analysis.rs index 29b02333675..ce8d9dd3c2c 100644 --- a/third_party/move/move-model/bytecode/src/borrow_analysis.rs +++ b/third_party/move/move-model/bytecode/src/borrow_analysis.rs @@ -792,6 +792,34 @@ impl TransferFunctions for BorrowAnalysis<'_> { dests, ); }, + Invoke => { + // For Invoke, we have no function summaries and do not know the + // borrow relation. Directly draw the `Invoke` edges. We only need to + // look at mutable references since others are eliminated. + for dest in dests { + if self + .func_target + .get_local_type(*dest) + .is_mutable_reference() + { + let dest_node = BorrowNode::Reference(*dest); + state.add_node(dest_node.clone()); + // Moves overapproximation: draw a borrow edge from each + // input ref to the output ref + for src in srcs { + if self.func_target.get_local_type(*src).is_mutable_reference() + { + let src_node = BorrowNode::Reference(*src); + state.add_edge( + src_node, + dest_node.clone(), + BorrowEdge::Invoke, + ); + } + } + } + } + }, OpaqueCallBegin(_, _, _) | OpaqueCallEnd(_, _, _) => { // just skip }, diff --git a/third_party/move/move-model/bytecode/src/fat_loop.rs b/third_party/move/move-model/bytecode/src/fat_loop.rs index 0aee1dcc786..e141ae76901 100644 --- a/third_party/move/move-model/bytecode/src/fat_loop.rs +++ b/third_party/move/move-model/bytecode/src/fat_loop.rs @@ -475,13 +475,12 @@ impl FatLoopBuilder { // because the fatloop algorithm doesn't support fallthrough if cfg.successors(*block_id).len() == 1 && !block[block.len() - 1].is_branching() { let successor_id = cfg.successors(*block_id).first().unwrap(); - let successor_label_opt = id_label_map.get(successor_id); - if successor_label_opt.is_some() + let successor_label_opt = id_label_map.get(successor_id).copied(); + if let Some(successor_label) = successor_label_opt && i != blocks.len() - 1 && !blocks.get(i + 1).unwrap().1.is_empty() { if let Some(lbl) = blocks.get(i + 1).unwrap().1[0].get_label_inner_opt() { - let successor_label = *successor_label_opt.unwrap(); if lbl != successor_label { let mut new_block = block.clone(); // Inserted bc is used for jumping to its successor so diff --git a/third_party/move/move-model/bytecode/src/function_target.rs b/third_party/move/move-model/bytecode/src/function_target.rs index 3e46793bd32..3949064bd66 100644 --- a/third_party/move/move-model/bytecode/src/function_target.rs +++ b/third_party/move/move-model/bytecode/src/function_target.rs @@ -124,7 +124,7 @@ impl<'env> FunctionTarget<'env> { } /// Shortcut for accessing the module env of this function. - pub fn module_env(&self) -> &ModuleEnv { + pub fn module_env(&self) -> &ModuleEnv<'_> { &self.func_env.module_env } @@ -465,14 +465,6 @@ impl<'env> FunctionTarget<'env> { texts.push(format!(" # {}", comment)); } - // add location - if verbose { - texts.push(format!( - " # {}", - self.get_bytecode_loc(attr_id).display(self.global_env()) - )); - } - // add annotations let annotations = self .annotation_formatters @@ -500,13 +492,24 @@ impl<'env> FunctionTarget<'env> { )); } + // location string if verbose + let verbose_str = if verbose { + format!( + "# {}", + self.get_bytecode_loc(attr_id).display(self.global_env()) + ) + } else { + "".to_string() + }; + // add the instruction itself with offset - texts.push(format!( - "{:>3}: {}", + let instr = format!( + "{:>3}: {:<40} {}", offset, - code.display(self, label_offsets) - )); - + code.display(self, label_offsets).to_string(), + verbose_str + ); + texts.push(instr); texts.join("\n") } } diff --git a/third_party/move/move-model/bytecode/src/function_target_pipeline.rs b/third_party/move/move-model/bytecode/src/function_target_pipeline.rs index 632dff79b5a..f4210f30f0a 100644 --- a/third_party/move/move-model/bytecode/src/function_target_pipeline.rs +++ b/third_party/move/move-model/bytecode/src/function_target_pipeline.rs @@ -10,8 +10,8 @@ use crate::{ }; use core::fmt; use itertools::{Either, Itertools}; -use log::{debug, info}; -use move_model::model::{FunId, FunctionEnv, GlobalEnv, QualifiedId}; +use log::debug; +use move_model::model::{FunId, FunctionEnv, FunctionSize, GlobalEnv, QualifiedId}; use petgraph::graph::DiGraph; use std::{ collections::{BTreeMap, BTreeSet}, @@ -295,6 +295,23 @@ impl FunctionTargetsHolder { } } } + + /// Computes the estimated sizes of functions using their stackless bytecode. + pub fn compute_function_size_estimates(&self) -> BTreeMap, FunctionSize> { + self.targets + .iter() + .filter_map(|(fid, variants)| { + let baseline_function = variants.get(&FunctionVariant::Baseline)?; + Some(( + *fid, + FunctionSize::new( + baseline_function.code.len(), + baseline_function.local_types.len(), + ), + )) + }) + .collect() + } } impl FunctionTargetPipeline { @@ -424,7 +441,7 @@ impl FunctionTargetPipeline { AfterEach: Fn(usize, &dyn FunctionTargetProcessor, &FunctionTargetsHolder) -> bool, { let rev_topo_order = Self::sort_in_reverse_topological_order(env, targets); - info!("transforming bytecode"); + debug!("transforming bytecode"); hook_before_pipeline(targets); for (step_count, processor) in self.processors.iter().enumerate() { if processor.is_single_run() { @@ -573,7 +590,7 @@ impl FunctionTargetPipeline { } fn debug_dump(base_name: &str, step_count: usize, suffix: &str, content: &str) { - let name = format!("bytecode of {}_{}_{}", base_name, step_count, suffix); + let name = format!("bytecode of {}#step{}_{}", base_name, step_count, suffix); debug!("{}:\n{}\n", name, content.trim()) } diff --git a/third_party/move/move-model/bytecode/src/stackless_bytecode.rs b/third_party/move/move-model/bytecode/src/stackless_bytecode.rs index f92f8164419..0da21e5d9a3 100644 --- a/third_party/move/move-model/bytecode/src/stackless_bytecode.rs +++ b/third_party/move/move-model/bytecode/src/stackless_bytecode.rs @@ -3,10 +3,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::function_target::FunctionTarget; -use ethnum::U256; +use ethnum::{I256, U256}; use itertools::Itertools; use move_binary_format::file_format::CodeOffset; -use move_core_types::{function::ClosureMask, u256, value::MoveValue}; +use move_core_types::{function::ClosureMask, value::MoveValue}; use move_model::{ ast, ast::{Address, Exp, ExpData, MemoryLabel, Spec, TempIndex, TraceKind, Value}, @@ -112,12 +112,12 @@ pub enum Constant { U16(u16), U32(u32), U256(U256), -} - -impl From<&u256::U256> for Constant { - fn from(n: &u256::U256) -> Constant { - Constant::U256(U256::from(n)) - } + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + I256(I256), } impl Constant { @@ -131,9 +131,17 @@ impl Constant { Constant::U32(x) => MoveValue::U32(*x), Constant::U64(x) => MoveValue::U64(*x), Constant::U128(x) => MoveValue::U128(*x), - Constant::U256(x) => { - MoveValue::U256(move_core_types::u256::U256::from_le_bytes(&x.to_le_bytes())) - }, + Constant::U256(x) => MoveValue::U256(move_core_types::int256::U256::from_le_bytes( + x.to_le_bytes(), + )), + Constant::I8(x) => MoveValue::I8(*x), + Constant::I16(x) => MoveValue::I16(*x), + Constant::I32(x) => MoveValue::I32(*x), + Constant::I64(x) => MoveValue::I64(*x), + Constant::I128(x) => MoveValue::I128(*x), + Constant::I256(x) => MoveValue::I256(move_core_types::int256::I256::from_le_bytes( + x.to_le_bytes(), + )), Constant::Address(a) => MoveValue::Address(a.expect_numerical()), Constant::ByteArray(v) => { MoveValue::Vector(v.iter().map(|x| MoveValue::U8(*x)).collect()) @@ -155,9 +163,13 @@ impl Constant { Constant::U32(x) => Value::Number((*x).into()), Constant::U64(x) => Value::Number((*x).into()), Constant::U128(x) => Value::Number((*x).into()), - Constant::U256(x) => { - Value::Number(BigInt::from_bytes_le(Sign::NoSign, &x.to_le_bytes())) - }, + Constant::U256(x) => Value::Number(BigInt::from_bytes_le(Sign::Plus, &x.to_le_bytes())), + Constant::I8(x) => Value::Number((*x).into()), + Constant::I16(x) => Value::Number((*x).into()), + Constant::I32(x) => Value::Number((*x).into()), + Constant::I64(x) => Value::Number((*x).into()), + Constant::I128(x) => Value::Number((*x).into()), + Constant::I256(x) => Value::Number(BigInt::from_signed_bytes_le(&x.to_le_bytes())), Constant::Address(a) => Value::Address(a.clone()), Constant::Vector(v) => Value::Vector(v.iter().map(|x| x.to_model_value()).collect()), Constant::ByteArray(v) => { @@ -233,7 +245,15 @@ pub enum Operation { CastU32, CastU64, CastU128, + CastU256, + CastI8, + CastI16, + CastI32, + CastI64, + CastI128, + CastI256, Not, + Negate, // Binary Add, @@ -254,7 +274,6 @@ pub enum Operation { And, Eq, Neq, - CastU256, // ============================================================== // Extended Bytecodes (part of the verification IL) @@ -341,7 +360,14 @@ impl Operation { Operation::CastU64 => true, Operation::CastU128 => true, Operation::CastU256 => true, + Operation::CastI8 => true, + Operation::CastI16 => true, + Operation::CastI32 => true, + Operation::CastI64 => true, + Operation::CastI128 => true, + Operation::CastI256 => true, Operation::Not => false, + Operation::Negate => true, Operation::Add => true, Operation::Sub => true, Operation::Mul => true, @@ -419,6 +445,8 @@ pub enum BorrowEdge { Field(QualifiedInstId, Option>, usize), /// Vector borrow with dynamic index. Index(IndexEdgeKind), + /// Borrow via a function value, unknown structure + Invoke, /// Composed sequence of edges. Hyper(Vec), } @@ -1380,7 +1408,14 @@ impl fmt::Display for OperationDisplay<'_> { CastU64 => write!(f, "(u64)")?, CastU128 => write!(f, "(u128)")?, CastU256 => write!(f, "(u256)")?, + CastI8 => write!(f, "(i8)")?, + CastI16 => write!(f, "(i16)")?, + CastI32 => write!(f, "(i32)")?, + CastI64 => write!(f, "(i64)")?, + CastI128 => write!(f, "(i128)")?, + CastI256 => write!(f, "(i256)")?, Not => write!(f, "!")?, + Negate => write!(f, "-")?, // Binary Add => write!(f, "+")?, @@ -1462,6 +1497,12 @@ impl fmt::Display for Constant { U64(x) => write!(f, "{}", x)?, U128(x) => write!(f, "{}", x)?, U256(x) => write!(f, "{}", x)?, + I8(x) => write!(f, "{}", x)?, + I16(x) => write!(f, "{}", x)?, + I32(x) => write!(f, "{}", x)?, + I64(x) => write!(f, "{}", x)?, + I128(x) => write!(f, "{}", x)?, + I256(x) => write!(f, "{}", x)?, Address(x) => write!(f, "{}", address_to_string(x))?, ByteArray(x) => write!(f, "{:?}", x)?, AddressArray(x) => write!(f, "{:?}", x.iter().map(address_to_string).collect_vec())?, @@ -1557,6 +1598,7 @@ impl std::fmt::Display for BorrowEdgeDisplay<'_> { }, Index(_) => write!(f, "[]"), Direct => write!(f, "@"), + Invoke => write!(f, ">"), Hyper(es) => { write!( f, diff --git a/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs b/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs index 88e28f5a468..0747c31960f 100644 --- a/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs +++ b/third_party/move/move-model/bytecode/src/stackless_bytecode_generator.rs @@ -110,10 +110,10 @@ impl<'a> StacklessBytecodeGenerator<'a> { | MoveBytecode::Branch(code_offset) = bytecode { let offs = *code_offset as CodeOffset; - if !label_map.contains_key(&offs) { - let label = Label::new(label_map.len()); - label_map.insert(offs, label); - } + let label_cnt = label_map.len(); + let label = label_map.entry(offs).or_insert(Label::new(label_cnt)); + // remove the label from the fallthrough set if exists + self.fallthrough_labels.remove(label); } if let MoveBytecode::BrTrue(_) | MoveBytecode::BrFalse(_) = bytecode { let next_offs = (pos + 1) as CodeOffset; @@ -544,8 +544,11 @@ impl<'a> StacklessBytecodeGenerator<'a> { let temp_index = self.temp_count; self.temp_stack.push(temp_index); self.local_types.push(Type::Primitive(PrimitiveType::U256)); - self.code - .push(Bytecode::Load(attr_id, temp_index, Constant::from(number))); + self.code.push(Bytecode::Load( + attr_id, + temp_index, + Constant::U256(number.repr()), + )); self.temp_count += 1; }, @@ -618,6 +621,123 @@ impl<'a> StacklessBytecodeGenerator<'a> { self.temp_count += 1; }, + MoveBytecode::LdI8(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I8)); + self.code + .push(Bytecode::Load(attr_id, temp_index, Constant::I8(*number))); + self.temp_count += 1; + }, + + MoveBytecode::LdI16(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I16)); + self.code + .push(Bytecode::Load(attr_id, temp_index, Constant::I16(*number))); + self.temp_count += 1; + }, + + MoveBytecode::LdI32(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I32)); + self.code + .push(Bytecode::Load(attr_id, temp_index, Constant::I32(*number))); + self.temp_count += 1; + }, + + MoveBytecode::LdI64(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I64)); + self.code + .push(Bytecode::Load(attr_id, temp_index, Constant::I64(*number))); + self.temp_count += 1; + }, + + MoveBytecode::LdI128(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I128)); + self.code + .push(Bytecode::Load(attr_id, temp_index, Constant::I128(*number))); + self.temp_count += 1; + }, + + MoveBytecode::LdI256(number) => { + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I256)); + self.code.push(Bytecode::Load( + attr_id, + temp_index, + Constant::I256(number.repr()), + )); + self.temp_count += 1; + }, + + MoveBytecode::CastI8 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I8)); + self.code + .push(mk_unary(Operation::CastI8, temp_index, operand_index)); + self.temp_count += 1; + }, + + MoveBytecode::CastI16 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I16)); + self.code + .push(mk_unary(Operation::CastI16, temp_index, operand_index)); + self.temp_count += 1; + }, + + MoveBytecode::CastI32 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I32)); + self.code + .push(mk_unary(Operation::CastI32, temp_index, operand_index)); + self.temp_count += 1; + }, + + MoveBytecode::CastI64 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I64)); + self.code + .push(mk_unary(Operation::CastI64, temp_index, operand_index)); + self.temp_count += 1; + }, + + MoveBytecode::CastI128 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I128)); + self.code + .push(mk_unary(Operation::CastI128, temp_index, operand_index)); + self.temp_count += 1; + }, + + MoveBytecode::CastI256 => { + let operand_index = self.temp_stack.pop().unwrap(); + let temp_index = self.temp_count; + self.temp_stack.push(temp_index); + self.local_types.push(Type::Primitive(PrimitiveType::I256)); + self.code + .push(mk_unary(Operation::CastI256, temp_index, operand_index)); + self.temp_count += 1; + }, + MoveBytecode::LdConst(idx) => { let temp_index = self.temp_count; self.temp_stack.push(temp_index); @@ -1211,6 +1331,18 @@ impl<'a> StacklessBytecodeGenerator<'a> { _ => {}, } }, + + MoveBytecode::Negate => { + let operand_index = self.temp_stack.pop().unwrap(); + let operand_type = self.local_types[operand_index].clone(); + let temp_index = self.temp_count; + self.local_types.push(operand_type); + self.temp_count += 1; + self.temp_stack.push(temp_index); + self.code + .push(mk_unary(Operation::Negate, temp_index, operand_index)); + }, + MoveBytecode::Or => { let operand2_index = self.temp_stack.pop().unwrap(); let operand1_index = self.temp_stack.pop().unwrap(); @@ -1803,7 +1935,13 @@ impl<'a> StacklessBytecodeGenerator<'a> { (Type::Primitive(PrimitiveType::U32), MoveValue::U32(b)) => Constant::U32(*b), (Type::Primitive(PrimitiveType::U64), MoveValue::U64(b)) => Constant::U64(*b), (Type::Primitive(PrimitiveType::U128), MoveValue::U128(b)) => Constant::U128(*b), - (Type::Primitive(PrimitiveType::U256), MoveValue::U256(b)) => Constant::U256(b.into()), + (Type::Primitive(PrimitiveType::U256), MoveValue::U256(b)) => Constant::U256(b.repr()), + (Type::Primitive(PrimitiveType::I8), MoveValue::I8(b)) => Constant::I8(*b), + (Type::Primitive(PrimitiveType::I16), MoveValue::I16(b)) => Constant::I16(*b), + (Type::Primitive(PrimitiveType::I32), MoveValue::I32(b)) => Constant::I32(*b), + (Type::Primitive(PrimitiveType::I64), MoveValue::I64(b)) => Constant::I64(*b), + (Type::Primitive(PrimitiveType::I128), MoveValue::I128(b)) => Constant::I128(*b), + (Type::Primitive(PrimitiveType::I256), MoveValue::I256(b)) => Constant::I256(b.repr()), (Type::Primitive(PrimitiveType::Address), MoveValue::Address(a)) => { Constant::Address(Address::Numerical(*a)) }, diff --git a/third_party/move/move-model/bytecode/src/stackless_control_flow_graph.rs b/third_party/move/move-model/bytecode/src/stackless_control_flow_graph.rs index e4f2a877439..239fb97f2a8 100644 --- a/third_party/move/move-model/bytecode/src/stackless_control_flow_graph.rs +++ b/third_party/move/move-model/bytecode/src/stackless_control_flow_graph.rs @@ -347,7 +347,7 @@ impl<'a> DFSLeft<'a> { } else if let Some(unvisited_blocks) = &mut self.unvisited { unvisited_blocks.pop_first() } else { - return None; + None } } diff --git a/third_party/move/move-model/bytecode/tests/borrow/basic_test.exp b/third_party/move/move-model/bytecode/tests/borrow/basic_test.exp index 42e5dc2e467..739a74f0b8f 100644 --- a/third_party/move/move-model/bytecode/tests/borrow/basic_test.exp +++ b/third_party/move/move-model/bytecode/tests/borrow/basic_test.exp @@ -210,23 +210,21 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: 36: goto 27 37: label L0 38: $t25 := move($t0) - 39: if ($t25) goto 40 else goto 49 + 39: if ($t25) goto 40 else goto 47 40: label L7 41: $t26 := move($t5) 42: drop($t26) 43: $t27 := move($t2) 44: $t28 := 0 45: TestBorrow::test3($t27, $t28) - 46: goto 47 - 47: label L8 - 48: return () - 49: label L6 - 50: $t29 := move($t2) - 51: drop($t29) - 52: $t30 := move($t5) - 53: $t31 := 0 - 54: TestBorrow::test3($t30, $t31) - 55: goto 47 + 46: return () + 47: label L6 + 48: $t29 := move($t2) + 49: drop($t29) + 50: $t30 := move($t5) + 51: $t31 := 0 + 52: TestBorrow::test3($t30, $t31) + 53: return () } ============ after pipeline `borrow` ================ @@ -592,7 +590,7 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 31: if ($t0) goto 32 else goto 39 + 31: if ($t0) goto 32 else goto 37 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} @@ -612,35 +610,27 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: # live_nodes: LocalRoot($t0), LocalRoot($t1) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 36: goto 37 - # live_nodes: LocalRoot($t0), LocalRoot($t1) - # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} - # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 37: label L8 - # live_nodes: LocalRoot($t0), LocalRoot($t1) - # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} - # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 38: return () + 36: return () # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 39: label L6 + 37: label L6 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 40: drop($t2) + 38: drop($t2) # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 41: $t19 := 0 + 39: $t19 := 0 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 42: TestBorrow::test3($t5, $t19) + 40: TestBorrow::test3($t5, $t19) # live_nodes: LocalRoot($t0), LocalRoot($t1) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t15))}, LocalRoot($t4) -> {(@, Reference($t8)), (@, Reference($t17))}, Reference($t8) -> {(@, Reference($t5))}, Reference($t15) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t8)), (@, Reference($t15)), (@, Reference($t17))}, Reference($t8) -> {(@, LocalRoot($t4))}, Reference($t15) -> {(@, LocalRoot($t3))}, Reference($t17) -> {(@, LocalRoot($t4))} - 43: goto 37 + 41: return () } diff --git a/third_party/move/move-model/bytecode/tests/borrow_strong/basic_test.exp b/third_party/move/move-model/bytecode/tests/borrow_strong/basic_test.exp index 6864edaea6d..4179c6afc87 100644 --- a/third_party/move/move-model/bytecode/tests/borrow_strong/basic_test.exp +++ b/third_party/move/move-model/bytecode/tests/borrow_strong/basic_test.exp @@ -276,23 +276,21 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: 38: goto 29 39: label L0 40: $t27 := move($t0) - 41: if ($t27) goto 42 else goto 51 + 41: if ($t27) goto 42 else goto 49 42: label L7 43: $t28 := move($t5) 44: drop($t28) 45: $t29 := move($t2) 46: $t30 := 0 47: TestBorrow::test3($t29, $t30) - 48: goto 49 - 49: label L8 - 50: return () - 51: label L6 - 52: $t31 := move($t2) - 53: drop($t31) - 54: $t32 := move($t5) - 55: $t33 := 0 - 56: TestBorrow::test3($t32, $t33) - 57: goto 49 + 48: return () + 49: label L6 + 50: $t31 := move($t2) + 51: drop($t31) + 52: $t32 := move($t5) + 53: $t33 := 0 + 54: TestBorrow::test3($t32, $t33) + 55: return () } @@ -820,7 +818,7 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 33: if ($t0) goto 34 else goto 41 + 33: if ($t0) goto 34 else goto 39 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} @@ -840,35 +838,27 @@ fun TestBorrow::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestBorrow: # live_nodes: LocalRoot($t0), LocalRoot($t1) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 38: goto 39 - # live_nodes: LocalRoot($t0), LocalRoot($t1) - # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} - # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 39: label L8 - # live_nodes: LocalRoot($t0), LocalRoot($t1) - # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} - # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 40: return () + 38: return () # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 41: label L6 + 39: label L6 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t2), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 42: drop($t2) + 40: drop($t2) # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 43: $t21 := 0 + 41: $t21 := 0 # live_nodes: LocalRoot($t0), LocalRoot($t1), Reference($t5) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 44: TestBorrow::test3($t5, $t21) + 42: TestBorrow::test3($t5, $t21) # live_nodes: LocalRoot($t0), LocalRoot($t1) # borrowed_by: LocalRoot($t3) -> {(@, Reference($t17))}, LocalRoot($t4) -> {(@, Reference($t10)), (@, Reference($t19))}, Reference($t10) -> {(@, Reference($t5))}, Reference($t17) -> {(@, Reference($t5))}, Reference($t19) -> {(@, Reference($t5))} # borrows_from: Reference($t5) -> {(@, Reference($t10)), (@, Reference($t17)), (@, Reference($t19))}, Reference($t10) -> {(@, LocalRoot($t4))}, Reference($t17) -> {(@, LocalRoot($t3))}, Reference($t19) -> {(@, LocalRoot($t4))} - 45: goto 39 + 43: return () } diff --git a/third_party/move/move-model/bytecode/tests/borrow_strong/mut_ref.exp b/third_party/move/move-model/bytecode/tests/borrow_strong/mut_ref.exp index a4ae761eb3d..d420f6f615a 100644 --- a/third_party/move/move-model/bytecode/tests/borrow_strong/mut_ref.exp +++ b/third_party/move/move-model/bytecode/tests/borrow_strong/mut_ref.exp @@ -321,135 +321,107 @@ fun TestMutRef::call_return_ref_different_root($t0|b: bool): (0x1::TestMutRef::T [variant baseline] fun TestMutRef::return_ref_different_path($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::N): &mut u64 { - var $t2|return: &mut u64 - var $t3: bool - var $t4: &mut 0x1::TestMutRef::N - var $t5: &mut u64 - var $t6: &mut u64 - var $t7: &mut 0x1::TestMutRef::N - var $t8: &mut 0x1::TestMutRef::T - var $t9: &mut u64 - 0: $t3 := move($t0) - 1: if ($t3) goto 2 else goto 10 + var $t2: bool + var $t3: &mut 0x1::TestMutRef::N + var $t4: &mut u64 + var $t5: &mut 0x1::TestMutRef::N + var $t6: &mut 0x1::TestMutRef::T + var $t7: &mut u64 + 0: $t2 := move($t0) + 1: if ($t2) goto 2 else goto 6 2: label L1 - 3: $t4 := move($t1) - 4: $t5 := borrow_field<0x1::TestMutRef::N>.value($t4) - 5: $t2 := $t5 - 6: goto 7 - 7: label L2 - 8: $t6 := move($t2) - 9: return $t6 - 10: label L0 - 11: $t7 := move($t1) - 12: $t8 := borrow_field<0x1::TestMutRef::N>.t($t7) - 13: $t9 := borrow_field<0x1::TestMutRef::T>.value($t8) - 14: $t2 := $t9 - 15: goto 7 + 3: $t3 := move($t1) + 4: $t4 := borrow_field<0x1::TestMutRef::N>.value($t3) + 5: return $t4 + 6: label L0 + 7: $t5 := move($t1) + 8: $t6 := borrow_field<0x1::TestMutRef::N>.t($t5) + 9: $t7 := borrow_field<0x1::TestMutRef::T>.value($t6) + 10: return $t7 } [variant baseline] fun TestMutRef::return_ref_different_path_vec($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::V): &mut u64 { - var $t2|return: &mut u64 - var $t3: bool - var $t4: &mut 0x1::TestMutRef::V - var $t5: &mut vector - var $t6: u64 - var $t7: &mut u64 - var $t8: &mut u64 - var $t9: &mut 0x1::TestMutRef::V - var $t10: &mut vector - var $t11: u64 - var $t12: &mut u64 - 0: $t3 := move($t0) - 1: if ($t3) goto 2 else goto 12 + var $t2: bool + var $t3: &mut 0x1::TestMutRef::V + var $t4: &mut vector + var $t5: u64 + var $t6: &mut u64 + var $t7: &mut 0x1::TestMutRef::V + var $t8: &mut vector + var $t9: u64 + var $t10: &mut u64 + 0: $t2 := move($t0) + 1: if ($t2) goto 2 else goto 8 2: label L1 - 3: $t4 := move($t1) - 4: $t5 := borrow_field<0x1::TestMutRef::V>.is($t4) - 5: $t6 := 1 - 6: $t7 := vector::borrow_mut($t5, $t6) - 7: $t2 := $t7 - 8: goto 9 - 9: label L2 - 10: $t8 := move($t2) - 11: return $t8 - 12: label L0 - 13: $t9 := move($t1) - 14: $t10 := borrow_field<0x1::TestMutRef::V>.is($t9) - 15: $t11 := 0 - 16: $t12 := vector::borrow_mut($t10, $t11) - 17: $t2 := $t12 - 18: goto 9 + 3: $t3 := move($t1) + 4: $t4 := borrow_field<0x1::TestMutRef::V>.is($t3) + 5: $t5 := 1 + 6: $t6 := vector::borrow_mut($t4, $t5) + 7: return $t6 + 8: label L0 + 9: $t7 := move($t1) + 10: $t8 := borrow_field<0x1::TestMutRef::V>.is($t7) + 11: $t9 := 0 + 12: $t10 := vector::borrow_mut($t8, $t9) + 13: return $t10 } [variant baseline] fun TestMutRef::return_ref_different_path_vec2($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::V): &mut u64 { - var $t2|return: &mut u64 - var $t3: bool - var $t4: &mut 0x1::TestMutRef::V - var $t5: &mut vector - var $t6: u64 - var $t7: &mut u64 - var $t8: &mut u64 - var $t9: &mut 0x1::TestMutRef::V - var $t10: &mut vector<0x1::TestMutRef::T> - var $t11: u64 - var $t12: &mut 0x1::TestMutRef::T - var $t13: &mut u64 - 0: $t3 := move($t0) - 1: if ($t3) goto 2 else goto 12 + var $t2: bool + var $t3: &mut 0x1::TestMutRef::V + var $t4: &mut vector + var $t5: u64 + var $t6: &mut u64 + var $t7: &mut 0x1::TestMutRef::V + var $t8: &mut vector<0x1::TestMutRef::T> + var $t9: u64 + var $t10: &mut 0x1::TestMutRef::T + var $t11: &mut u64 + 0: $t2 := move($t0) + 1: if ($t2) goto 2 else goto 8 2: label L1 - 3: $t4 := move($t1) - 4: $t5 := borrow_field<0x1::TestMutRef::V>.is($t4) - 5: $t6 := 1 - 6: $t7 := vector::borrow_mut($t5, $t6) - 7: $t2 := $t7 - 8: goto 9 - 9: label L2 - 10: $t8 := move($t2) - 11: return $t8 - 12: label L0 - 13: $t9 := move($t1) - 14: $t10 := borrow_field<0x1::TestMutRef::V>.ts($t9) - 15: $t11 := 0 - 16: $t12 := vector::borrow_mut<0x1::TestMutRef::T>($t10, $t11) - 17: $t13 := borrow_field<0x1::TestMutRef::T>.value($t12) - 18: $t2 := $t13 - 19: goto 9 + 3: $t3 := move($t1) + 4: $t4 := borrow_field<0x1::TestMutRef::V>.is($t3) + 5: $t5 := 1 + 6: $t6 := vector::borrow_mut($t4, $t5) + 7: return $t6 + 8: label L0 + 9: $t7 := move($t1) + 10: $t8 := borrow_field<0x1::TestMutRef::V>.ts($t7) + 11: $t9 := 0 + 12: $t10 := vector::borrow_mut<0x1::TestMutRef::T>($t8, $t9) + 13: $t11 := borrow_field<0x1::TestMutRef::T>.value($t10) + 14: return $t11 } [variant baseline] fun TestMutRef::return_ref_different_root($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::T, $t2|y: &mut 0x1::TestMutRef::R): &mut u64 { - var $t3|return: &mut u64 - var $t4: bool - var $t5: &mut 0x1::TestMutRef::R - var $t6: &mut 0x1::TestMutRef::T - var $t7: &mut u64 - var $t8: &mut u64 - var $t9: &mut 0x1::TestMutRef::T - var $t10: &mut 0x1::TestMutRef::R - var $t11: &mut u64 - 0: $t4 := move($t0) - 1: if ($t4) goto 2 else goto 12 + var $t3: bool + var $t4: &mut 0x1::TestMutRef::R + var $t5: &mut 0x1::TestMutRef::T + var $t6: &mut u64 + var $t7: &mut 0x1::TestMutRef::T + var $t8: &mut 0x1::TestMutRef::R + var $t9: &mut u64 + 0: $t3 := move($t0) + 1: if ($t3) goto 2 else goto 8 2: label L1 - 3: $t5 := move($t2) - 4: drop($t5) - 5: $t6 := move($t1) - 6: $t7 := borrow_field<0x1::TestMutRef::T>.value($t6) - 7: $t3 := $t7 - 8: goto 9 - 9: label L2 - 10: $t8 := move($t3) - 11: return $t8 - 12: label L0 - 13: $t9 := move($t1) - 14: drop($t9) - 15: $t10 := move($t2) - 16: $t11 := borrow_field<0x1::TestMutRef::R>.value($t10) - 17: $t3 := $t11 - 18: goto 9 + 3: $t4 := move($t2) + 4: drop($t4) + 5: $t5 := move($t1) + 6: $t6 := borrow_field<0x1::TestMutRef::T>.value($t5) + 7: return $t6 + 8: label L0 + 9: $t7 := move($t1) + 10: drop($t7) + 11: $t8 := move($t2) + 12: $t9 := borrow_field<0x1::TestMutRef::R>.value($t8) + 13: return $t9 } ============ after pipeline `borrow_strong` ================ @@ -958,10 +930,11 @@ fun TestMutRef::call_return_ref_different_root($t0|b: bool): (0x1::TestMutRef::T [variant baseline] fun TestMutRef::return_ref_different_path($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::N): &mut u64 { - var $t2|return: &mut u64 + var $t2: &mut u64 var $t3: &mut 0x1::TestMutRef::T + var $t4: &mut u64 # live_nodes: LocalRoot($t0), Reference($t1) - 0: if ($t0) goto 1 else goto 6 + 0: if ($t0) goto 1 else goto 4 # live_nodes: LocalRoot($t0), Reference($t1) 1: label L1 # live_nodes: LocalRoot($t0), Reference($t1) @@ -969,144 +942,123 @@ fun TestMutRef::return_ref_different_path($t0|b: bool, $t1|x: &mut 0x1::TestMutR # live_nodes: LocalRoot($t0), Reference($t2) # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t2))} # borrows_from: Reference($t2) -> {(.value (u64), Reference($t1))} - 3: goto 4 - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t2)), (.t (0x1::TestMutRef::T), Reference($t3))}, Reference($t3) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {(.value (u64), Reference($t1)), (.value (u64), Reference($t3))}, Reference($t3) -> {(.t (0x1::TestMutRef::T), Reference($t1))} - 4: label L2 - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t2)), (.t (0x1::TestMutRef::T), Reference($t3))}, Reference($t3) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {(.value (u64), Reference($t1)), (.value (u64), Reference($t3))}, Reference($t3) -> {(.t (0x1::TestMutRef::T), Reference($t1))} - 5: return $t2 + 3: return $t2 # live_nodes: LocalRoot($t0), Reference($t1) - 6: label L0 + 4: label L0 # live_nodes: LocalRoot($t0), Reference($t1) - 7: $t3 := borrow_field<0x1::TestMutRef::N>.t($t1) + 5: $t3 := borrow_field<0x1::TestMutRef::N>.t($t1) # live_nodes: LocalRoot($t0), Reference($t3) # borrowed_by: Reference($t1) -> {(.t (0x1::TestMutRef::T), Reference($t3))} # borrows_from: Reference($t3) -> {(.t (0x1::TestMutRef::T), Reference($t1))} - 8: $t2 := borrow_field<0x1::TestMutRef::T>.value($t3) - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.t (0x1::TestMutRef::T), Reference($t3))}, Reference($t3) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {(.value (u64), Reference($t3))}, Reference($t3) -> {(.t (0x1::TestMutRef::T), Reference($t1))} - 9: goto 4 + 6: $t4 := borrow_field<0x1::TestMutRef::T>.value($t3) + # live_nodes: LocalRoot($t0), Reference($t4) + # borrowed_by: Reference($t1) -> {(.t (0x1::TestMutRef::T), Reference($t3))}, Reference($t3) -> {(.value (u64), Reference($t4))} + # borrows_from: Reference($t3) -> {(.t (0x1::TestMutRef::T), Reference($t1))}, Reference($t4) -> {(.value (u64), Reference($t3))} + 7: return $t4 } [variant baseline] fun TestMutRef::return_ref_different_path_vec($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::V): &mut u64 { - var $t2|return: &mut u64 - var $t3: &mut vector - var $t4: u64 + var $t2: &mut vector + var $t3: u64 + var $t4: &mut u64 var $t5: &mut vector var $t6: u64 + var $t7: &mut u64 # live_nodes: LocalRoot($t0), Reference($t1) - 0: if ($t0) goto 1 else goto 8 + 0: if ($t0) goto 1 else goto 6 # live_nodes: LocalRoot($t0), Reference($t1) 1: label L1 # live_nodes: LocalRoot($t0), Reference($t1) - 2: $t3 := borrow_field<0x1::TestMutRef::V>.is($t1) - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))} - # borrows_from: Reference($t3) -> {(.is (vector), Reference($t1))} - 3: $t4 := 1 - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))} - # borrows_from: Reference($t3) -> {(.is (vector), Reference($t1))} - 4: $t2 := vector::borrow_mut($t3, $t4) - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))}, Reference($t3) -> {([], Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3))}, Reference($t3) -> {(.is (vector), Reference($t1))} - 5: goto 6 + 2: $t2 := borrow_field<0x1::TestMutRef::V>.is($t1) # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3)), (.is (vector), Reference($t5))}, Reference($t3) -> {([], Reference($t2))}, Reference($t5) -> {([], Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3)), ([], Reference($t5))}, Reference($t3) -> {(.is (vector), Reference($t1))}, Reference($t5) -> {(.is (vector), Reference($t1))} - 6: label L2 + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))} + 3: $t3 := 1 # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3)), (.is (vector), Reference($t5))}, Reference($t3) -> {([], Reference($t2))}, Reference($t5) -> {([], Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3)), ([], Reference($t5))}, Reference($t3) -> {(.is (vector), Reference($t1))}, Reference($t5) -> {(.is (vector), Reference($t1))} - 7: return $t2 + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))} + 4: $t4 := vector::borrow_mut($t2, $t3) + # live_nodes: LocalRoot($t0), Reference($t4) + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))}, Reference($t2) -> {([], Reference($t4))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))}, Reference($t4) -> {([], Reference($t2))} + 5: return $t4 # live_nodes: LocalRoot($t0), Reference($t1) - 8: label L0 + 6: label L0 # live_nodes: LocalRoot($t0), Reference($t1) - 9: $t5 := borrow_field<0x1::TestMutRef::V>.is($t1) + 7: $t5 := borrow_field<0x1::TestMutRef::V>.is($t1) # live_nodes: LocalRoot($t0), Reference($t5) # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t5))} # borrows_from: Reference($t5) -> {(.is (vector), Reference($t1))} - 10: $t6 := 0 + 8: $t6 := 0 # live_nodes: LocalRoot($t0), Reference($t5) # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t5))} # borrows_from: Reference($t5) -> {(.is (vector), Reference($t1))} - 11: $t2 := vector::borrow_mut($t5, $t6) - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t5))}, Reference($t5) -> {([], Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t5))}, Reference($t5) -> {(.is (vector), Reference($t1))} - 12: goto 6 + 9: $t7 := vector::borrow_mut($t5, $t6) + # live_nodes: LocalRoot($t0), Reference($t7) + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t5))}, Reference($t5) -> {([], Reference($t7))} + # borrows_from: Reference($t5) -> {(.is (vector), Reference($t1))}, Reference($t7) -> {([], Reference($t5))} + 10: return $t7 } [variant baseline] fun TestMutRef::return_ref_different_path_vec2($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::V): &mut u64 { - var $t2|return: &mut u64 - var $t3: &mut vector - var $t4: u64 + var $t2: &mut vector + var $t3: u64 + var $t4: &mut u64 var $t5: &mut vector<0x1::TestMutRef::T> var $t6: u64 var $t7: &mut 0x1::TestMutRef::T + var $t8: &mut u64 # live_nodes: LocalRoot($t0), Reference($t1) - 0: if ($t0) goto 1 else goto 8 + 0: if ($t0) goto 1 else goto 6 # live_nodes: LocalRoot($t0), Reference($t1) 1: label L1 # live_nodes: LocalRoot($t0), Reference($t1) - 2: $t3 := borrow_field<0x1::TestMutRef::V>.is($t1) - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))} - # borrows_from: Reference($t3) -> {(.is (vector), Reference($t1))} - 3: $t4 := 1 - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))} - # borrows_from: Reference($t3) -> {(.is (vector), Reference($t1))} - 4: $t2 := vector::borrow_mut($t3, $t4) + 2: $t2 := borrow_field<0x1::TestMutRef::V>.is($t1) # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3))}, Reference($t3) -> {([], Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3))}, Reference($t3) -> {(.is (vector), Reference($t1))} - 5: goto 6 + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))} + 3: $t3 := 1 # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3)), (.ts (vector<0x1::TestMutRef::T>), Reference($t5))}, Reference($t3) -> {([], Reference($t2))}, Reference($t5) -> {([], Reference($t7))}, Reference($t7) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3)), (.value (u64), Reference($t7))}, Reference($t3) -> {(.is (vector), Reference($t1))}, Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))}, Reference($t7) -> {([], Reference($t5))} - 6: label L2 - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t3)), (.ts (vector<0x1::TestMutRef::T>), Reference($t5))}, Reference($t3) -> {([], Reference($t2))}, Reference($t5) -> {([], Reference($t7))}, Reference($t7) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {([], Reference($t3)), (.value (u64), Reference($t7))}, Reference($t3) -> {(.is (vector), Reference($t1))}, Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))}, Reference($t7) -> {([], Reference($t5))} - 7: return $t2 + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))} + 4: $t4 := vector::borrow_mut($t2, $t3) + # live_nodes: LocalRoot($t0), Reference($t4) + # borrowed_by: Reference($t1) -> {(.is (vector), Reference($t2))}, Reference($t2) -> {([], Reference($t4))} + # borrows_from: Reference($t2) -> {(.is (vector), Reference($t1))}, Reference($t4) -> {([], Reference($t2))} + 5: return $t4 # live_nodes: LocalRoot($t0), Reference($t1) - 8: label L0 + 6: label L0 # live_nodes: LocalRoot($t0), Reference($t1) - 9: $t5 := borrow_field<0x1::TestMutRef::V>.ts($t1) + 7: $t5 := borrow_field<0x1::TestMutRef::V>.ts($t1) # live_nodes: LocalRoot($t0), Reference($t5) # borrowed_by: Reference($t1) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t5))} # borrows_from: Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))} - 10: $t6 := 0 + 8: $t6 := 0 # live_nodes: LocalRoot($t0), Reference($t5) # borrowed_by: Reference($t1) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t5))} # borrows_from: Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))} - 11: $t7 := vector::borrow_mut<0x1::TestMutRef::T>($t5, $t6) + 9: $t7 := vector::borrow_mut<0x1::TestMutRef::T>($t5, $t6) # live_nodes: LocalRoot($t0), Reference($t7) # borrowed_by: Reference($t1) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t5))}, Reference($t5) -> {([], Reference($t7))} # borrows_from: Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))}, Reference($t7) -> {([], Reference($t5))} - 12: $t2 := borrow_field<0x1::TestMutRef::T>.value($t7) - # live_nodes: LocalRoot($t0), Reference($t2) - # borrowed_by: Reference($t1) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t5))}, Reference($t5) -> {([], Reference($t7))}, Reference($t7) -> {(.value (u64), Reference($t2))} - # borrows_from: Reference($t2) -> {(.value (u64), Reference($t7))}, Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))}, Reference($t7) -> {([], Reference($t5))} - 13: goto 6 + 10: $t8 := borrow_field<0x1::TestMutRef::T>.value($t7) + # live_nodes: LocalRoot($t0), Reference($t8) + # borrowed_by: Reference($t1) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t5))}, Reference($t5) -> {([], Reference($t7))}, Reference($t7) -> {(.value (u64), Reference($t8))} + # borrows_from: Reference($t5) -> {(.ts (vector<0x1::TestMutRef::T>), Reference($t1))}, Reference($t7) -> {([], Reference($t5))}, Reference($t8) -> {(.value (u64), Reference($t7))} + 11: return $t8 } [variant baseline] fun TestMutRef::return_ref_different_root($t0|b: bool, $t1|x: &mut 0x1::TestMutRef::T, $t2|y: &mut 0x1::TestMutRef::R): &mut u64 { - var $t3|return: &mut u64 + var $t3: &mut u64 + var $t4: &mut u64 # live_nodes: LocalRoot($t0), Reference($t1), Reference($t2) - 0: if ($t0) goto 1 else goto 7 + 0: if ($t0) goto 1 else goto 5 # live_nodes: LocalRoot($t0), Reference($t1), Reference($t2) 1: label L1 # live_nodes: LocalRoot($t0), Reference($t1), Reference($t2) @@ -1116,25 +1068,17 @@ fun TestMutRef::return_ref_different_root($t0|b: bool, $t1|x: &mut 0x1::TestMutR # live_nodes: LocalRoot($t0), Reference($t3) # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t3))} # borrows_from: Reference($t3) -> {(.value (u64), Reference($t1))} - 4: goto 5 - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t3))}, Reference($t2) -> {(.value (u64), Reference($t3))} - # borrows_from: Reference($t3) -> {(.value (u64), Reference($t1)), (.value (u64), Reference($t2))} - 5: label L2 - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t1) -> {(.value (u64), Reference($t3))}, Reference($t2) -> {(.value (u64), Reference($t3))} - # borrows_from: Reference($t3) -> {(.value (u64), Reference($t1)), (.value (u64), Reference($t2))} - 6: return $t3 + 4: return $t3 # live_nodes: LocalRoot($t0), Reference($t1), Reference($t2) - 7: label L0 + 5: label L0 # live_nodes: LocalRoot($t0), Reference($t1), Reference($t2) - 8: drop($t1) + 6: drop($t1) # live_nodes: LocalRoot($t0), Reference($t2) - 9: $t3 := borrow_field<0x1::TestMutRef::R>.value($t2) - # live_nodes: LocalRoot($t0), Reference($t3) - # borrowed_by: Reference($t2) -> {(.value (u64), Reference($t3))} - # borrows_from: Reference($t3) -> {(.value (u64), Reference($t2))} - 10: goto 5 + 7: $t4 := borrow_field<0x1::TestMutRef::R>.value($t2) + # live_nodes: LocalRoot($t0), Reference($t4) + # borrowed_by: Reference($t2) -> {(.value (u64), Reference($t4))} + # borrows_from: Reference($t4) -> {(.value (u64), Reference($t2))} + 8: return $t4 } diff --git a/third_party/move/move-model/src/ast.rs b/third_party/move/move-model/src/ast.rs index 462901dbf53..91c38baedf5 100644 --- a/third_party/move/move-model/src/ast.rs +++ b/third_party/move/move-model/src/ast.rs @@ -18,7 +18,10 @@ use either::Either; use internment::LocalIntern; use itertools::{EitherOrBoth, Itertools}; use move_binary_format::file_format::{CodeOffset, Visibility}; -use move_core_types::{account_address::AccountAddress, function::ClosureMask}; +use move_core_types::{ + account_address::AccountAddress, function::ClosureMask, + language_storage::pseudo_script_module_id, +}; use num::BigInt; use std::{ borrow::Borrow, @@ -168,12 +171,7 @@ impl ConditionKind { } pub fn allowed_on_lambda_spec(&self) -> bool { - // TODO(#16256): support all conditions allowed in `allowed_on_fun_decl` - use ConditionKind::*; - matches!( - self, - Requires | AbortsIf | Ensures | FunctionInvariant | LetPre(..) - ) + self.allowed_on_fun_decl(Visibility::Public) } /// Returns true if this condition is allowed on a struct. @@ -1221,12 +1219,54 @@ impl ExpData { called } + /// Returns the Move functions called by this expression, along with call sites and their + /// loop depth. + pub fn called_funs_with_callsites_and_loop_depth( + &self, + ) -> BTreeMap, BTreeSet<(NodeId, usize)>> { + let mut called: BTreeMap<_, BTreeSet<_>> = BTreeMap::new(); + let mut loop_depth = 0; + let mut visitor = |post: bool, e: &ExpData| { + match e { + ExpData::Loop(..) => { + if post { + loop_depth -= 1 + } else { + loop_depth += 1 + } + }, + ExpData::Call(node_id, Operation::MoveFunction(mid, fid), _) if !post => { + called + .entry(mid.qualified(*fid)) + .or_default() + .insert((*node_id, loop_depth)); + }, + _ => {}, + } + true // keep going + }; + self.visit_pre_post(&mut visitor); + called + } + /// Returns true if the given expression contains a `continue` or /// `break` which refers to a loop in the given `nest_range`. /// For example, `branches_to(loop { break }, 1..10)` will return false, /// but `branches_to(loop { break }, 0..10)` will return true. /// count as exit. pub fn branches_to(&self, nest_range: Range) -> bool { + let branch_cond = |loop_nest: usize, nest: usize, _: bool| { + nest >= loop_nest && nest_range.contains(&(nest - loop_nest)) + }; + self.customizable_branches_to(branch_cond) + } + + /// A customizable version of `branches_to`, allowing to + /// specify how a `continue` or `break` refers to which loop(s). + pub fn customizable_branches_to(&self, condition: F) -> bool + where + F: Fn(usize, usize, bool) -> bool, + { let mut loop_nest = 0; let mut branches = false; let mut visitor = |post: bool, e: &ExpData| { @@ -1238,9 +1278,7 @@ impl ExpData { loop_nest += 1 } }, - ExpData::LoopCont(_, nest, _) - if *nest >= loop_nest && nest_range.contains(&(*nest - loop_nest)) => - { + ExpData::LoopCont(_, nest, cond) if condition(loop_nest, *nest, *cond) => { branches = true; return false; // found a reference, exit visit early }, @@ -1306,9 +1344,34 @@ impl ExpData { /// /// If this is needed elsewhere we can move it out, currently it's a local helper. pub fn rewrite_loop_nest(&self, delta: isize) -> Exp { + self.customizable_rewrite_loop_nest(delta, Self::default_nest_rewrite) + } + + /// A commonly used rewriter for adjusting nesting level of `LoopCont` + /// - `exp`: the target `LoopCont` expression to rewrite + /// - `nest`: the current nesting level of the loop + /// - `cont`: whether this is a `continue` or `break` + /// - `delta`: the delta to add to the nesting level; cound be negative + fn default_nest_rewrite(exp: Exp, _: usize, nest: usize, cont: bool, delta: isize) -> Exp { + let new_nest = (nest as isize) + delta; + assert!( + new_nest >= 0, + "loop removed which has break/continue references?" + ); + ExpData::LoopCont(exp.node_id(), new_nest as usize, cont).into_exp() + } + + /// A customizable version of `rewrite_loop_nest`, allowing to specify how + /// the rewriting is done. + pub fn customizable_rewrite_loop_nest( + &self, + delta: isize, + rewrite: fn(Exp, usize, usize, bool, isize) -> Exp, + ) -> Exp { LoopNestRewriter { loop_depth: 0, delta, + rewrite, } .rewrite_exp(self.clone().into_exp()) } @@ -1755,17 +1818,60 @@ impl ExpData { None } - /// Collect struct-related operations - pub fn struct_usage(&self, usage: &mut BTreeSet>) { + fn collect_struct_pattern(pat: &Pattern, usage: &mut BTreeSet>) { + if let Pattern::Struct(_, qid, _, pats) = pat { + usage.insert(qid.to_qualified_id()); + for p in pats { + Self::collect_struct_pattern(p, usage); + } + } + } + + /// Collect struct-related operations including unpacking + pub fn struct_usage(&self, env: &GlobalEnv, usage: &mut BTreeSet>) { self.visit_post_order(&mut |e| { if let ExpData::Call(_, oper, _) = e { use Operation::*; match oper { - Select(mid, sid, ..) | UpdateField(mid, sid, ..) | Pack(mid, sid, _) => { + SelectVariants(mid, sid, ..) + | TestVariants(mid, sid, ..) + | Select(mid, sid, ..) + | UpdateField(mid, sid, ..) + | Pack(mid, sid, _) => { usage.insert(mid.qualified(*sid)); }, _ => {}, } + } else { + match e { + ExpData::Assign(_, pat, _) | ExpData::Block(_, pat, _, _) => { + Self::collect_struct_pattern(pat, usage); + }, + ExpData::Lambda(id, pat, _, _, _) => { + let fun_ty = env.get_node_type(*id); + if let Some((wrapper_struct, _)) = fun_ty.get_struct(env) { + usage.insert(wrapper_struct.get_qualified_id()); + } + Self::collect_struct_pattern(pat, usage); + }, + ExpData::Quant(_, _, pattern_tuple, _, _, _) => { + for (pat, _) in pattern_tuple { + Self::collect_struct_pattern(pat, usage); + } + }, + ExpData::Match(_, _, arms) => { + for arm in arms.iter() { + Self::collect_struct_pattern(&arm.pattern, usage); + } + }, + ExpData::Invoke(_, exp, _) => { + let fun_ty = env.get_node_type(exp.node_id()); + if let Some((wrapper_struct, _)) = fun_ty.get_struct(env) { + usage.insert(wrapper_struct.get_qualified_id()); + } + }, + _ => {}, + } } true // keep going. }); @@ -1843,18 +1949,15 @@ impl ExpRewriterFunctions for ExpRewriter<'_> { struct LoopNestRewriter { loop_depth: usize, delta: isize, + /// Args: target `LoopCont` expression, current depth of loop, nest level of `LoopCont`, continue or not, delta to add to nest level + rewrite: fn(Exp, usize, usize, bool, isize) -> Exp, } impl ExpRewriterFunctions for LoopNestRewriter { fn rewrite_exp(&mut self, exp: Exp) -> Exp { match exp.as_ref() { - ExpData::LoopCont(id, nest, cont) if *nest >= self.loop_depth => { - let new_nest = (*nest as isize) + self.delta; - assert!( - new_nest >= 0, - "loop removed which has break/continue references?" - ); - ExpData::LoopCont(*id, new_nest as usize, *cont).into_exp() + ExpData::LoopCont(_, nest, cont) if *nest >= self.loop_depth => { + (self.rewrite)(exp.clone(), self.loop_depth, *nest, *cont, self.delta) }, ExpData::Loop(_, _) => { self.loop_depth += 1; @@ -1919,6 +2022,7 @@ pub enum Operation { // Unary operators Not, Cast, + Negate, // Builtin functions (impl and spec) Exists(Option), @@ -2392,7 +2496,7 @@ impl PatDisplay<'_> { Self { show_type, ..self } } - fn type_ctx(&self) -> TypeDisplayContext { + fn type_ctx(&self) -> TypeDisplayContext<'_> { if let Some(fe) = &self.fun_env { fe.get_type_display_ctx() } else { @@ -2739,7 +2843,8 @@ impl Operation { // Unary operators Not => true, - Cast => false, // can overflow + Cast => false, // can overflow + Negate => false, // can overflow // Builtin functions (impl and spec) Exists(..) => false, // Spec @@ -3003,6 +3108,14 @@ impl ModuleName { ModuleName(addr, name) } + /// Returns builtin module name. + pub fn builtin_module(env: &GlobalEnv) -> Self { + Self::new( + Address::Numerical(AccountAddress::ZERO), + env.symbol_pool().make("$$"), + ) + } + pub fn from_address_bytes_and_name( addr: legacy_move_compiler::shared::NumericalAddress, name: Symbol, @@ -3032,15 +3145,18 @@ impl ModuleName { } /// Return the pseudo module name used for scripts, incorporating the `index`. - /// Our compiler infrastructure uses `MAX_ADDRESS` for pseudo modules created from scripts. + /// Our compiler infrastructure uses `SCRIPT_MODULE_ID` for pseudo modules created from scripts. pub fn pseudo_script_name(pool: &SymbolPool, index: usize) -> ModuleName { let name = pool.make(Self::pseudo_script_name_builder(SCRIPT_MODULE_NAME, index).as_str()); - ModuleName(Address::Numerical(AccountAddress::MAX_ADDRESS), name) + ModuleName( + Address::Numerical(*pseudo_script_module_id().address()), + name, + ) } /// Determine whether this is a script. pub fn is_script(&self) -> bool { - self.0 == Address::Numerical(AccountAddress::MAX_ADDRESS) + self.0 == Address::Numerical(*pseudo_script_module_id().address()) } } @@ -3465,7 +3581,7 @@ fn indent(fmt: impl fmt::Display) -> String { } impl ExpDisplay<'_> { - fn type_ctx(&self) -> TypeDisplayContext { + fn type_ctx(&self) -> TypeDisplayContext<'_> { if let Some(fe) = &self.fun_env { fe.get_type_display_ctx() } else { diff --git a/third_party/move/move-model/src/builder/binary_module_loader.rs b/third_party/move/move-model/src/builder/binary_module_loader.rs index c55eb8288b5..607f3319a8b 100644 --- a/third_party/move/move-model/src/builder/binary_module_loader.rs +++ b/third_party/move/move-model/src/builder/binary_module_loader.rs @@ -6,7 +6,11 @@ //! scripts (`CompiledScript`) to the global env. use crate::{ - ast::{Address, ModuleName}, + ast::{ + AccessSpecifier as ASTAccessSpecifier, AccessSpecifierKind as ASTAccessSpecifierKind, + Address, AddressSpecifier as ASTAddressSpecifier, Attribute, ModuleName, + ResourceSpecifier as ASTResourceSpecifier, + }, model::{ FieldData, FieldId, FunId, FunctionData, FunctionKind, GlobalEnv, Loc, ModuleData, ModuleId, MoveIrLoc, Parameter, StructData, StructId, StructVariant, TypeParameter, @@ -14,12 +18,16 @@ use crate::{ }, symbol::{Symbol, SymbolPool}, ty::{PrimitiveType, ReferenceKind, Type}, + well_known, }; use itertools::Itertools; use move_binary_format::{ + access::ModuleAccess, file_format::{ - FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, SignatureToken, - StructDefinitionIndex, StructHandleIndex, TableIndex, VariantIndex, Visibility, + AccessKind as FFAccessKind, AddressSpecifier as FFAddressSpecifier, FunctionAttribute, + FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, + ResourceSpecifier as FFResourceSpecifier, SignatureToken, StructDefinitionIndex, + StructHandleIndex, TableIndex, VariantIndex, Visibility, }, internals::ModuleIndex, views::{ @@ -32,6 +40,19 @@ use move_bytecode_source_map::source_map::{SourceMap, SourceName}; use move_core_types::{ability::AbilitySet, account_address::AccountAddress, language_storage}; use std::collections::BTreeMap; +/// Macro to abort the execution if `with_dep_closure` is specified while dependencies are missing. +macro_rules! abort_if_missing { + ($with_dep_closure:expr) => { + if $with_dep_closure { + panic!("Malformed bytecode or module loader bug. Please report this."); + } else { + // This should not be reached since no existing code sets `with_dep_closure` to `false`. + // Adding an alert in case things change in the future. + unimplemented!("[TODO #17414]"); + } + }; +} + impl GlobalEnv { /// Loads the compiled module into the environment. If the module already exists, /// information about it will be refined according to the provided `module` @@ -65,6 +86,7 @@ impl GlobalEnv { loader.load(); let BinaryModuleLoader { module_id, .. } = loader; self.attach_compiled_module(module_id, module, source_map); + self.update_loaded_modules(); module_id } } @@ -401,8 +423,24 @@ impl<'a> BinaryModuleLoader<'a> { let result_type = Type::tuple(handle_view.return_().0.iter().map(|s| self.ty(s)).collect()); - // TODO: access specifiers - let access_specifiers = None; + // Convert access specifiers from file format to AST format + let rw_specifiers = self.rw_specifiers(&handle_view, ¶ms); + let acquire_specifiers = if let Some((_, def_view)) = def_view.clone() { + self.acquire_specifiers(&def_view) + } else { + None + }; + // Combine read/write and acquire specifiers. + let access_specifiers = rw_specifiers + .clone() + .zip(acquire_specifiers.clone()) + .map(|(mut rw, acquire)| { + rw.extend(acquire); + rw + }) + .or(rw_specifiers) + .or(acquire_specifiers); + let (visibility, is_native, kind) = if let Some((_, def_view)) = def_view { ( def_view.visibility(), @@ -418,6 +456,32 @@ impl<'a> BinaryModuleLoader<'a> { // defaults (Visibility::Public, false, FunctionKind::Regular) }; + + // add attributes to the function + let mut attributes = vec![]; + for attr in handle_view.attributes() { + match attr { + FunctionAttribute::Persistent => { + if !visibility.is_public() { + let node_id = self.env.new_node(Loc::default(), Type::Tuple(vec![])); + let sym = self + .env + .symbol_pool() + .make(well_known::PERSISTENT_ATTRIBUTE); + attributes.push(Attribute::Apply(node_id, sym, vec![])); + } + }, + FunctionAttribute::ModuleLock => { + let node_id = self.env.new_node(Loc::default(), Type::Tuple(vec![])); + let sym = self + .env + .symbol_pool() + .make(well_known::MODULE_LOCK_ATTRIBUTE); + attributes.push(Attribute::Apply(node_id, sym, vec![])); + }, + } + } + let mut new = false; let fun_data = self.env.module_data[module_id.to_usize()] .function_data @@ -428,6 +492,7 @@ impl<'a> BinaryModuleLoader<'a> { visibility, is_native, kind, + attributes, ..FunctionData::new(fun_id.symbol(), loc) } }); @@ -457,6 +522,182 @@ impl<'a> BinaryModuleLoader<'a> { } } + fn rw_specifiers( + &self, + handle_view: &FunctionHandleView, + params: &[Parameter], + ) -> Option> { + let ff_access_specifiers = handle_view.access_specifiers()?; + let mut access_specifiers = Vec::new(); + let ff_module = handle_view.module(); + + // Helper function mapping a file format `ModuleId` to a `ModuleEnv` in move model + let ff_mid_to_module_env = |ff_mid: language_storage::ModuleId| { + let mname = self.env.to_module_name(&ff_mid); + self.env + .find_module(&mname) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)) + }; + + for ff_acc_spec in ff_access_specifiers { + let spec_kind = match ff_acc_spec.kind { + FFAccessKind::Reads => ASTAccessSpecifierKind::Reads, + FFAccessKind::Writes => ASTAccessSpecifierKind::Writes, + }; + let spec_negated = ff_acc_spec.negated; + let resource_spec = match ff_acc_spec.resource { + FFResourceSpecifier::Any => ASTResourceSpecifier::Any, + FFResourceSpecifier::DeclaredAtAddress(addr_idx) => { + let acct_addr = ff_module.address_identifier_at(addr_idx); + ASTResourceSpecifier::DeclaredAtAddress(Address::Numerical(*acct_addr)) + }, + FFResourceSpecifier::DeclaredInModule(mhid) => { + // ModuleHandleIndex -> ModuleHandle -> File format ModuleId + let ff_mhandle = ff_module.module_handle_at(mhid); + let ff_mid = ff_module.module_id_for_handle(ff_mhandle); + // File format ModuleId -> ModuleEnv in move model + let module_env = ff_mid_to_module_env(ff_mid); + ASTResourceSpecifier::DeclaredInModule(module_env.get_id()) + }, + FFResourceSpecifier::Resource(shid) => { + // StructHandleIndex -> StructHandle -> ModuleHandle -> File format ModuleId + let ff_shandle = ff_module.struct_handle_at(shid); + let ff_mhandle = ff_module.module_handle_at(ff_shandle.module); + let ff_mid = ff_module.module_id_for_handle(ff_mhandle); + // StructHandle -> struct name -> StructId in move model + let sname = ff_module.identifier_at(ff_shandle.name); + let struct_id = StructId::new(self.sym(sname.as_str())); + // File format ModuleId -> ModuleEnv in move model -> StructEnv in move model + let module_env = ff_mid_to_module_env(ff_mid); + let struct_env = self + .env + .get_struct_opt(module_env.get_id().qualified(struct_id)) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); + ASTResourceSpecifier::Resource( + module_env + .get_id() + .qualified_inst(struct_env.get_id(), vec![]), + ) + }, + FFResourceSpecifier::ResourceInstantiation(shid, sig_idx) => { + // Process similar to `FFResourceSpecifier::Resource` + let ff_shandle = ff_module.struct_handle_at(shid); + let ff_mhandle = ff_module.module_handle_at(ff_shandle.module); + let ff_mid = ff_module.module_id_for_handle(ff_mhandle); + let sname = ff_module.identifier_at(ff_shandle.name); + let sig = ff_module.signature_at(sig_idx); + let type_args: Vec<_> = sig.0.iter().map(|arg| self.ty(arg)).collect(); + let struct_id = StructId::new(self.sym(sname.as_str())); + let module_env = ff_mid_to_module_env(ff_mid); + let struct_env = self + .env + .get_struct_opt(module_env.get_id().qualified(struct_id)) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); + ASTResourceSpecifier::Resource( + module_env + .get_id() + .qualified_inst(struct_env.get_id(), type_args), + ) + }, + }; + let addr_spec = match ff_acc_spec.address { + FFAddressSpecifier::Any => ASTAddressSpecifier::Any, + FFAddressSpecifier::Literal(addr_idx) => { + let addr = Address::Numerical(*ff_module.address_identifier_at(addr_idx)); + ASTAddressSpecifier::Address(addr) + }, + FFAddressSpecifier::Parameter(param_idx, func_inst_inx) => { + if let Some(func_inst_idx) = func_inst_inx { + // FunctionInstantiationIndex -> FunctionInstantiation -> FunctionHandle -> ModuleHandle -> File format ModuleId + let ff_func_inst = ff_module.function_instantiation_at(func_inst_idx); + let ff_func_handle = ff_module.function_handle_at(ff_func_inst.handle); + let ff_mhandle = ff_module.module_handle_at(ff_func_handle.module); + let ff_mid = ff_module.module_id_for_handle(ff_mhandle); + // FunctionHandle -> function name -> FunId in move model + let fname = ff_module.identifier_at(ff_func_handle.name); + let fun_id = FunId::new(self.sym(fname.as_str())); + // File format ModuleId -> ModuleEnv in move model -> FunctionEnv in move model + let module_env = ff_mid_to_module_env(ff_mid); + let fun_env = self + .env + .get_function_opt(module_env.get_id().qualified(fun_id)) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); + ASTAddressSpecifier::Call( + module_env + .get_id() + .qualified_inst(fun_env.get_id(), fun_env.get_parameter_types()), + params[param_idx as usize].0, + ) + } else { + ASTAddressSpecifier::Parameter(params[param_idx as usize].0) + } + }, + }; + let loc = Loc::default(); + let ast_access_specifier: ASTAccessSpecifier = ASTAccessSpecifier { + kind: spec_kind, + negated: spec_negated, + resource: (loc.clone(), resource_spec), + address: (loc.clone(), addr_spec), + loc, + }; + access_specifiers.push(ast_access_specifier); + } + Some(access_specifiers) + } + + fn acquire_specifiers( + &self, + def_view: &FunctionDefinitionView, + ) -> Option> { + let mut access_specifiers = Vec::new(); + let ff_module = def_view.module(); + let ff_acquires = def_view.acquired_resources(); + if ff_acquires.is_empty() { + return None; + } + for sdef_idx in def_view.acquired_resources() { + let spec_kind = ASTAccessSpecifierKind::LegacyAcquires; + let spec_negated = false; + let resource_spec = { + // StructDefinitionIndex -> StructHandleIndex -> StructHandle -> ModuleHandle -> File format ModuleId + let struct_hidx = ff_module.struct_def_at(*sdef_idx).struct_handle; + let struct_handle = ff_module.struct_handle_at(struct_hidx); + let mhandle = ff_module.module_handle_at(struct_handle.module); + let ff_mid = ff_module.module_id_for_handle(mhandle); + // StructHandle -> struct name -> StructId in move model + let sname = ff_module.identifier_at(struct_handle.name); + let struct_id = StructId::new(self.sym(sname.as_str())); + // File format ModuleId -> ModuleEnv in move model -> StructEnv in move model + let mname = self.env.to_module_name(&ff_mid); + let module_env = self + .env + .find_module(&mname) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); + let struct_env = self + .env + .get_struct_opt(module_env.get_id().qualified(struct_id)) + .unwrap_or_else(|| abort_if_missing!(self.with_dep_closure)); + ASTResourceSpecifier::Resource( + module_env + .get_id() + .qualified_inst(struct_env.get_id(), vec![]), + ) + }; + let addr_spec = ASTAddressSpecifier::Any; + let loc = Loc::default(); + let ast_acquire_specifier: ASTAccessSpecifier = ASTAccessSpecifier { + kind: spec_kind, + negated: spec_negated, + resource: (loc.clone(), resource_spec), + address: (loc.clone(), addr_spec), + loc, + }; + access_specifiers.push(ast_acquire_specifier); + } + Some(access_specifiers) + } + fn ty(&self, sign: &SignatureToken) -> Type { let resolver = |module_name, struct_sym| { let struct_id = StructId::new(struct_sym); diff --git a/third_party/move/move-model/src/builder/builtins.rs b/third_party/move/move-model/src/builder/builtins.rs index e189c9a3db3..e300c428c55 100644 --- a/third_party/move/move-model/src/builder/builtins.rs +++ b/third_party/move/move-model/src/builder/builtins.rs @@ -7,13 +7,18 @@ use crate::{ ast::{Operation, TraceKind, Value}, builder::model_builder::{ConstEntry, EntryVisibility, ModelBuilder, SpecOrBuiltinFunEntry}, + metadata::{ + lang_feature_versions::{COMPILE_FOR_TESTING_VALUE, SINT_LANGUAGE_VERSION_VALUE}, + LanguageVersion, + }, model::{Parameter, TypeParameter, TypeParameterKind}, + options::ModelBuilderOptions, ty::{Constraint, PrimitiveType, ReferenceKind, Type}, }; use legacy_move_compiler::parser::ast as PA; use move_core_types::{ ability::{Ability, AbilitySet}, - u256::U256, + int256::{I256, U256}, }; use num::BigInt; use std::collections::BTreeMap; @@ -21,6 +26,7 @@ use std::collections::BTreeMap; /// Adds builtin functions. pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { let loc = trans.env.internal_loc(); + let prim_ty = |p| Type::new_prim(p); let bool_t = &Type::new_prim(PrimitiveType::Bool); let num_t = &Type::new_prim(PrimitiveType::Num); let range_t = &Type::new_prim(PrimitiveType::Range); @@ -34,43 +40,205 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { ) }; + let options = trans + .env + .get_extension::() + .unwrap_or_default(); + let param_t = &Type::TypeParameter(0); let param_t_decl = TypeParameter::new_named(&trans.env.symbol_pool().make("T"), &loc); - let mk_num_const = |value: BigInt, visibility: EntryVisibility| ConstEntry { + let mk_int_const = |value: BigInt, ty: &Type, visibility: EntryVisibility| ConstEntry { loc: loc.clone(), - ty: num_t.clone(), + ty: ty.clone(), value: Value::Number(value), visibility, }; + let mk_num_const = + |value: BigInt, visibility: EntryVisibility| mk_int_const(value, num_t, visibility); + + let mk_bool_const = |value: bool, visibility: EntryVisibility| ConstEntry { + loc: loc.clone(), + ty: bool_t.clone(), + value: Value::Bool(value), + visibility, + }; + + { + if options + .language_version + .is_at_least(COMPILE_FOR_TESTING_VALUE) + { + use EntryVisibility::SpecAndImpl; + // Compiler builtin constants. + trans.define_const( + trans.builtin_qualified_symbol("__COMPILE_FOR_TESTING__"), + mk_bool_const(options.compile_for_testing, SpecAndImpl), + ); + } + } + { + use EntryVisibility::{Spec, SpecAndImpl}; + + let range_visibility = if options.language_version.is_at_least(LanguageVersion::V2_3) { + SpecAndImpl + } else { + Spec + }; + // Builtin Constants (for specifications) - use EntryVisibility::Spec; + + // Unsigned integers trans.define_const( trans.builtin_qualified_symbol("MAX_U8"), - mk_num_const(BigInt::from(u8::MAX), Spec), + mk_int_const( + BigInt::from(u8::MAX), + &prim_ty(PrimitiveType::U8), + range_visibility, + ), ); trans.define_const( trans.builtin_qualified_symbol("MAX_U16"), - mk_num_const(BigInt::from(u16::MAX), Spec), + mk_int_const( + BigInt::from(u16::MAX), + &prim_ty(PrimitiveType::U16), + range_visibility, + ), ); trans.define_const( trans.builtin_qualified_symbol("MAX_U32"), - mk_num_const(BigInt::from(u32::MAX), Spec), + mk_int_const( + BigInt::from(u32::MAX), + &prim_ty(PrimitiveType::U32), + range_visibility, + ), ); trans.define_const( trans.builtin_qualified_symbol("MAX_U64"), - mk_num_const(BigInt::from(u64::MAX), Spec), + mk_int_const( + BigInt::from(u64::MAX), + &prim_ty(PrimitiveType::U64), + range_visibility, + ), ); trans.define_const( trans.builtin_qualified_symbol("MAX_U128"), - mk_num_const(BigInt::from(u128::MAX), Spec), + mk_int_const( + BigInt::from(u128::MAX), + &prim_ty(PrimitiveType::U128), + range_visibility, + ), ); trans.define_const( trans.builtin_qualified_symbol("MAX_U256"), - mk_num_const(BigInt::from(&U256::max_value()), Spec), + mk_int_const( + BigInt::from(U256::MAX), + &prim_ty(PrimitiveType::U256), + range_visibility, + ), + ); + + // Signed integers + trans.define_const( + trans.builtin_qualified_symbol("MAX_I8"), + mk_int_const( + BigInt::from(i8::MAX), + &prim_ty(PrimitiveType::I8), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MAX_I16"), + mk_int_const( + BigInt::from(i16::MAX), + &prim_ty(PrimitiveType::I16), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MAX_I32"), + mk_int_const( + BigInt::from(i32::MAX), + &prim_ty(PrimitiveType::I32), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MAX_I64"), + mk_int_const( + BigInt::from(i64::MAX), + &prim_ty(PrimitiveType::I64), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MAX_I128"), + mk_int_const( + BigInt::from(i128::MAX), + &prim_ty(PrimitiveType::I128), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MAX_I256"), + mk_int_const( + BigInt::from(I256::MAX), + &prim_ty(PrimitiveType::I256), + range_visibility, + ), + ); + + trans.define_const( + trans.builtin_qualified_symbol("MIN_I8"), + mk_int_const( + BigInt::from(i8::MIN), + &prim_ty(PrimitiveType::I8), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MIN_I16"), + mk_int_const( + BigInt::from(i16::MIN), + &prim_ty(PrimitiveType::I16), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MIN_I32"), + mk_int_const( + BigInt::from(i32::MIN), + &prim_ty(PrimitiveType::I32), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MIN_I64"), + mk_int_const( + BigInt::from(i64::MIN), + &prim_ty(PrimitiveType::I64), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MIN_I128"), + mk_int_const( + BigInt::from(i128::MIN), + &prim_ty(PrimitiveType::I128), + range_visibility, + ), + ); + trans.define_const( + trans.builtin_qualified_symbol("MIN_I256"), + mk_int_const( + BigInt::from(I256::MIN), + &prim_ty(PrimitiveType::I256), + range_visibility, + ), ); + trans.define_const( trans.builtin_qualified_symbol("EXECUTION_FAILURE"), mk_num_const(BigInt::from(-1), Spec), @@ -124,13 +292,41 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { ) }; - let u8_ty = Type::Primitive(PrimitiveType::U8); + // Builtin function for arithmetic operations + // op_vec: operations to declare + // type_params: type parameters for the operations + // type_constraints: constraints on the type parameters + // ty1, ty2: types of the two parameters + // result_ty: result type + // visibility: impl or spec let declare_arithm_ops = |trans: &mut ModelBuilder, + op_vec: &[(PA::BinOp_, Operation)], type_params: &[TypeParameter], type_constraints: &BTreeMap, - ty: Type, + ty1: Type, + ty2: Type, + result_ty: Type, visibility: EntryVisibility| { - for (op, oper) in [ + for (op, oper) in op_vec { + declare_bin_gen( + trans, + *op, + oper.clone(), + type_params, + type_constraints, + &ty1, + &ty2, + &result_ty, + visibility, + ); + } + }; + + // Declare the SPEC arithm ops for `Add`, `Sub`, `Mul`, `Mod`, `Div`, `BitOr`, `BitAnd`, `Xor` + // Both operands and the result are of Num type. + declare_arithm_ops( + trans, + &[ (Add, Operation::Add), (Sub, Operation::Sub), (Mul, Operation::Mul), @@ -139,32 +335,109 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { (BitOr, Operation::BitOr), (BitAnd, Operation::BitAnd), (Xor, Operation::Xor), - ] { - declare_bin_gen( - trans, - op, - oper, - type_params, - type_constraints, - &ty, - &ty, - &ty, - visibility, - ); - } - for (op, oper) in [(Shl, Operation::Shl), (Shr, Operation::Shr)] { - declare_bin_gen( - trans, - op, - oper, - type_params, - type_constraints, - &ty, - &u8_ty, - &ty, - visibility, - ); - } + ], + &[], + &BTreeMap::new(), + Type::new_prim(PrimitiveType::Num), + Type::new_prim(PrimitiveType::Num), + Type::new_prim(PrimitiveType::Num), + Spec, // visible only in the spec language + ); + + // Declare the SPEC arithm ops for `Shl`, `Shr` + // First operand and the result are of Num type, second operand is of u8 type. + declare_arithm_ops( + trans, + &[(Shl, Operation::Shl), (Shr, Operation::Shr)], + &[], + &BTreeMap::new(), + Type::new_prim(PrimitiveType::Num), + Type::Primitive(PrimitiveType::U8), + Type::new_prim(PrimitiveType::Num), + Spec, // visible only in the spec language + ); + + // Declare the IMPL arithm ops for `Add`, `Sub`, `Mul`, `Mod`, `Div` + // We use a generic function with a constraint accepting all integer types, + // conceptually: `fun _+_(x: A, y: A): A where A: u8|u16|..|u256|i8|i16|..|i256`. + declare_arithm_ops( + trans, + &[ + (Add, Operation::Add), + (Sub, Operation::Sub), + (Mul, Operation::Mul), + (Mod, Operation::Mod), + (Div, Operation::Div), + ], + std::slice::from_ref(¶m_t_decl), + &[( + 0, + Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), + )] + .into_iter() + .collect(), + param_t.clone(), + param_t.clone(), + param_t.clone(), + Impl, + ); + + // Declare the IMPL arithm ops for `BitOr`, `BitAnd`, `Xor` + // We use a generic function with a constraint accepting only unsigned int types, + // conceptually: `fun _^_(x: A, y: A): A where A: u8|u16|..|u256`. + declare_arithm_ops( + trans, + &[ + (BitOr, Operation::BitOr), + (BitAnd, Operation::BitAnd), + (Xor, Operation::Xor), + ], + std::slice::from_ref(¶m_t_decl), + &[( + 0, + Constraint::SomeNumber( + PrimitiveType::all_unsigned_int_types() + .into_iter() + .collect(), + ), + )] + .into_iter() + .collect(), + param_t.clone(), + param_t.clone(), + param_t.clone(), + Impl, + ); + + // Declare the IMPL arithm ops for `Shl`, `Shr` + // We use a generic function with a constraint accepting only unsigned int types as first arg and `u8` as second arg, + // conceptually: `fun _>>_(x: A, y: u8): A where A: u8|u16|..|u256`. + declare_arithm_ops( + trans, + &[(Shl, Operation::Shl), (Shr, Operation::Shr)], + std::slice::from_ref(¶m_t_decl), + &[( + 0, + Constraint::SomeNumber( + PrimitiveType::all_unsigned_int_types() + .into_iter() + .collect(), + ), + )] + .into_iter() + .collect(), + param_t.clone(), + Type::Primitive(PrimitiveType::U8), + param_t.clone(), + Impl, + ); + + // Builtin function for comparison operations + let declare_cmp_ops = |trans: &mut ModelBuilder, + type_params: &[TypeParameter], + type_constraints: &BTreeMap, + ty: Type, + visibility: EntryVisibility| { for (op, oper) in [ (Lt, Operation::Lt), (Le, Operation::Le), @@ -185,28 +458,53 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { } }; - // Declare the specification arithm ops, based on Num type. - declare_arithm_ops( + // Declare the specification cmp ops. + // Only Num type is supported for cmp ops in spec. + declare_cmp_ops( trans, &[], &BTreeMap::new(), Type::new_prim(PrimitiveType::Num), Spec, // visible only in the spec language ); - // For the implementation arithm ops, we use a generic function with a constraint, - // conceptually: `fun _+_(x: A, y: A): A where A: u8|u16|..|u256`. - declare_arithm_ops( - trans, - &[param_t_decl.clone()], - &[( - 0, - Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), - )] - .into_iter() - .collect(), - param_t.clone(), - Impl, // visible only in the impl language - ); + // Declare the implementation cmp ops + if trans + .env + .language_version() + .is_at_least(LanguageVersion::V2_2) + { + // For LanguageVersion::V2_2 and later, we support comparison on all types. + // - integer types supported by the VM natively + // - other types supported by the `compare` native function + // - implicitly through compiler rewrite at the AST level + let ref_param_t = Type::Reference(ReferenceKind::Immutable, Box::new(param_t.clone())); + // Allow cmp over both generic types and reference types + for pt in [ref_param_t.clone(), param_t.clone()] { + declare_cmp_ops( + trans, + std::slice::from_ref(¶m_t_decl), + &BTreeMap::default(), + pt, + Impl, // visible only in the impl language + ); + } + } else { + // For LanguageVersion::V2_1 and earlier, we support only integer types. + // We use a generic function with a constraint, conceptually: + // `fun _cmp_(x: A, y: A): bool where A: u8|u16|..|u256`. + declare_cmp_ops( + trans, + std::slice::from_ref(¶m_t_decl), + &[( + 0, + Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), + )] + .into_iter() + .collect(), + param_t.clone(), + Impl, // visible only in the impl language + ); + } declare_bin(trans, Range, Operation::Range, num_t, num_t, range_t, Spec); @@ -290,6 +588,30 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { visibility: SpecAndImpl, }, ); + if options + .language_version + .is_at_least(SINT_LANGUAGE_VERSION_VALUE) + { + trans.define_spec_or_builtin_fun( + trans.unary_op_symbol(&PA::UnaryOp_::Negate), + SpecOrBuiltinFunEntry { + loc: loc.clone(), + oper: Operation::Negate, + type_params: vec![param_t_decl.clone()], + type_param_constraints: [( + 0, + Constraint::SomeNumber( + PrimitiveType::all_signed_int_types().into_iter().collect(), + ), + )] + .into_iter() + .collect(), + params: vec![mk_param(trans, 1, param_t.clone())], + result_type: param_t.clone(), + visibility: SpecAndImpl, + }, + ); + } } { diff --git a/third_party/move/move-model/src/builder/exp_builder.rs b/third_party/move/move-model/src/builder/exp_builder.rs index 0b440bbc778..cac030872b8 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -14,7 +14,10 @@ use crate::{ }, module_builder::{ModuleBuilder, SpecBlockContext}, }, - metadata::LanguageVersion, + metadata::{ + lang_feature_versions::{LANGUAGE_VERSION_FOR_RAC, SINT_LANGUAGE_VERSION_VALUE}, + LanguageVersion, + }, model::{ FieldData, FieldId, FunctionKind, GlobalEnv, Loc, ModuleId, NodeId, Parameter, QualifiedId, QualifiedInstId, SpecFunId, StructId, TypeParameter, TypeParameterKind, @@ -580,7 +583,6 @@ impl<'env, 'translator, 'module_translator> ExpTranslator<'env, 'translator, 'mo "previously declared here".to_string(), )], ); - return; } self.type_params.push((name, ty, kind, loc.clone())); } else if report_errors { @@ -882,7 +884,7 @@ impl UnificationContext for ExpTranslator<'_, '_, '_> { } } - fn type_display_context(&self) -> TypeDisplayContext { + fn type_display_context(&self) -> TypeDisplayContext<'_> { self.type_display_context() } } @@ -926,7 +928,7 @@ impl ExpTranslator<'_, '_, '_> { match &ty.value { Apply(access, args) => { if let EA::ModuleAccess_::Name(n) = &access.value { - let check_zero_args = |et: &mut Self, ty: Type| { + let check_zero_args = |et: &Self, ty: Type| { if args.is_empty() { ty } else { @@ -941,6 +943,21 @@ impl ExpTranslator<'_, '_, '_> { Type::Error } }; + let sint_gated_check_zero_args = |et: &Self, ty: Type| { + if !self + .env() + .language_version + .is_at_least(SINT_LANGUAGE_VERSION_VALUE) + { + et.error( + loc, + &format!("signed integer types not supported prior to language version {}", SINT_LANGUAGE_VERSION_VALUE.to_str()), + ); + Type::Error + } else { + check_zero_args(et, ty) + } + }; // Attempt to resolve as builtin type. match n.value.as_str() { "bool" => { @@ -956,6 +973,42 @@ impl ExpTranslator<'_, '_, '_> { "u256" => { return check_zero_args(self, Type::new_prim(PrimitiveType::U256)); }, + "i8" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I8), + ) + }, + "i16" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I16), + ) + }, + "i32" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I32), + ) + }, + "i64" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I64), + ) + }, + "i128" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I128), + ) + }, + "i256" => { + return sint_gated_check_zero_args( + self, + Type::new_prim(PrimitiveType::I256), + ) + }, "num" => return check_zero_args(self, Type::new_prim(PrimitiveType::Num)), "range" => { return check_zero_args(self, Type::new_prim(PrimitiveType::Range)); @@ -1069,11 +1122,11 @@ impl ExpTranslator<'_, '_, '_> { vec![self.translate_function_param_or_return_type(result)] }, }; - Type::function( - Type::tuple(arg_tys), - Type::tuple(result_tys), - self.parent.translate_abilities(abilities), - ) + let ability_set = self.parent.translate_abilities(abilities); + if ability_set.has_key() { + self.error(loc, "function types cannot have `key` ability"); + } + Type::function(Type::tuple(arg_tys), Type::tuple(result_tys), ability_set) }, Unit => Type::Tuple(vec![]), Multiple(vst) => { @@ -1191,7 +1244,7 @@ impl ExpTranslator<'_, '_, '_> { self.check_language_version( &loc, "read/write access specifiers.", - LanguageVersion::V2_3, + LANGUAGE_VERSION_FOR_RAC, )?; }, } @@ -1754,9 +1807,9 @@ impl ExpTranslator<'_, '_, '_> { ); } // Insert freeze for each expression in the exp list - let target_exp = if self.insert_freeze && expected_tys_opt.is_some() { - let expected_tys = - expected_tys_opt.expect("expected types should not be None"); + let target_exp = if self.insert_freeze + && let Some(expected_tys) = expected_tys_opt + { let expected_ty_opt = expected_tys.get(i); if let Some(expected_ty) = expected_ty_opt { self.try_freeze(expected_ty, &ty, exp.into()) @@ -3057,50 +3110,95 @@ impl ExpTranslator<'_, '_, '_> { ); Some((value, ty)) }, - EA::Value_::U8(x) => Some(self.translate_number( + EA::Value_::U8(x) => self.translate_number( &loc, BigInt::from_u8(*x).unwrap(), Some(PrimitiveType::U8), expected_type, context, - )), - EA::Value_::U16(x) => Some(self.translate_number( + ), + EA::Value_::U16(x) => self.translate_number( &loc, BigInt::from_u16(*x).unwrap(), Some(PrimitiveType::U16), expected_type, context, - )), - EA::Value_::U32(x) => Some(self.translate_number( + ), + EA::Value_::U32(x) => self.translate_number( &loc, BigInt::from_u32(*x).unwrap(), Some(PrimitiveType::U32), expected_type, context, - )), - EA::Value_::U64(x) => Some(self.translate_number( + ), + EA::Value_::U64(x) => self.translate_number( &loc, BigInt::from_u64(*x).unwrap(), Some(PrimitiveType::U64), expected_type, context, - )), - EA::Value_::U128(x) => Some(self.translate_number( + ), + EA::Value_::U128(x) => self.translate_number( &loc, BigInt::from_u128(*x).unwrap(), Some(PrimitiveType::U128), expected_type, context, - )), - EA::Value_::U256(x) => Some(self.translate_number( + ), + EA::Value_::U256(x) => self.translate_number( &loc, - BigInt::from(x), + BigInt::from(*x), Some(PrimitiveType::U256), expected_type, context, - )), + ), + EA::Value_::I8(x) => self.translate_number( + &loc, + BigInt::from_i8(*x).unwrap(), + Some(PrimitiveType::I8), + expected_type, + context, + ), + EA::Value_::I16(x) => self.translate_number( + &loc, + BigInt::from_i16(*x).unwrap(), + Some(PrimitiveType::I16), + expected_type, + context, + ), + EA::Value_::I32(x) => self.translate_number( + &loc, + BigInt::from_i32(*x).unwrap(), + Some(PrimitiveType::I32), + expected_type, + context, + ), + EA::Value_::I64(x) => self.translate_number( + &loc, + BigInt::from_i64(*x).unwrap(), + Some(PrimitiveType::I64), + expected_type, + context, + ), + EA::Value_::I128(x) => self.translate_number( + &loc, + BigInt::from_i128(*x).unwrap(), + Some(PrimitiveType::I128), + expected_type, + context, + ), + EA::Value_::I256(x) => self.translate_number( + &loc, + BigInt::from(*x), + Some(PrimitiveType::I256), + expected_type, + context, + ), + EA::Value_::InferredNegNum(x) => { + self.translate_number(&loc, BigInt::from(*x), None, expected_type, context) + }, EA::Value_::InferredNum(x) => { - Some(self.translate_number(&loc, BigInt::from(x), None, expected_type, context)) + self.translate_number(&loc, BigInt::from(*x), None, expected_type, context) }, EA::Value_::Bool(x) => Some((Value::Bool(*x), Type::new_prim(PrimitiveType::Bool))), EA::Value_::Bytearray(x) => { @@ -3118,7 +3216,7 @@ impl ExpTranslator<'_, '_, '_> { requested_type: Option, expected_type: &Type, context: &ErrorMessageContext, - ) -> (Value, Type) { + ) -> Option<(Value, Type)> { // First determine the type of the number. let mut possible_types = if let Some(requested) = requested_type { // The type of the constant is explicit (e.g. `0u64`) @@ -3131,8 +3229,12 @@ impl ExpTranslator<'_, '_, '_> { _ => unreachable!("not primitive"), } } else if self.is_spec_mode() { - // In specification mode, use U256. - vec![PrimitiveType::U256] + // In specification mode, use I256 or U256. + if value < BigInt::zero() { + vec![PrimitiveType::I256] + } else { + vec![PrimitiveType::U256] + } } else { // Infer the possible types from the value PrimitiveType::possible_int_types(value.clone()) @@ -3152,13 +3254,28 @@ impl ExpTranslator<'_, '_, '_> { ) }; let ty = self.check_type(loc, &ty, expected_type, context); - (Value::Number(value), ty) + + if ty.is_signed_int() + && !self + .env() + .language_version() + .is_at_least(LanguageVersion::V2_3) + { + self.error( + loc, + "signed integer types are not supported in language versions prior to 2.3", + ); + None + } else { + Some((Value::Number(value), ty)) + } } /// Check whether value fits into primitive type, report error if not. fn check_range(&mut self, loc: &Loc, ty: PrimitiveType, value: BigInt) { let max = ty.get_max_value().unwrap_or(value.clone()); - if value < BigInt::zero() || value > max { + let min = ty.get_min_value().unwrap_or(value.clone()); + if value < min || value > max { let tcx = self.type_display_context(); self.error( loc, @@ -3749,7 +3866,7 @@ impl ExpTranslator<'_, '_, '_> { return ExpData::Call( id, - Operation::Closure(module_id, fun_id, ClosureMask::new_for_leading(0)), + Operation::Closure(module_id, fun_id, ClosureMask::empty()), vec![], ); } @@ -3818,8 +3935,11 @@ impl ExpTranslator<'_, '_, '_> { context: &ErrorMessageContext, sym: &QualifiedSymbol, ) -> ExpData { - // Constants are always visible in specs. - if self.mode != ExpTranslationMode::Spec && sym.module_name != self.parent.module_name { + // Constants are always visible in specs. Builtin constants are visible everywhere. + if self.mode != ExpTranslationMode::Spec + && sym.module_name != self.parent.module_name + && sym.module_name != ModuleName::builtin_module(self.env()) + { self.error( loc, &format!( @@ -4738,7 +4858,7 @@ impl ExpTranslator<'_, '_, '_> { args: Vec, ) -> Vec { let params = entry.get_signature().1; - let new_args = params + params .iter() .map(|Parameter(_, ty, _)| ty.instantiate(instantiation)) .zip(args) @@ -4746,8 +4866,7 @@ impl ExpTranslator<'_, '_, '_> { let exp_ty = self.env().get_node_type(exp.node_id()); self.try_freeze(¶m_ty, &exp_ty, exp) }) - .collect_vec(); - new_args + .collect_vec() } /// Inserts the freeze operation when `expected_ty` is immutable ref and ty is mutable ref diff --git a/third_party/move/move-model/src/builder/model_builder.rs b/third_party/move/move-model/src/builder/model_builder.rs index 3639cdc836d..2a509d5389d 100644 --- a/third_party/move/move-model/src/builder/model_builder.rs +++ b/third_party/move/move-model/src/builder/model_builder.rs @@ -8,7 +8,7 @@ //! system, as well as type checking it and translating it to the spec language ast. use crate::{ - ast::{Address, Attribute, FriendDecl, ModuleName, Operation, QualifiedSymbol, Spec, Value}, + ast::{Attribute, FriendDecl, ModuleName, Operation, QualifiedSymbol, Spec, Value}, builder::builtins, intrinsics::IntrinsicDecl, model::{ @@ -23,7 +23,7 @@ use codespan_reporting::diagnostic::Severity; use itertools::Itertools; use legacy_move_compiler::{expansion::ast as EA, parser::ast as PA, shared::NumericalAddress}; use move_binary_format::file_format::Visibility; -use move_core_types::{ability::AbilitySet, account_address::AccountAddress}; +use move_core_types::ability::{Ability, AbilitySet}; use std::collections::{BTreeMap, BTreeSet}; /// A builder is used to enter a sequence of modules in acyclic dependency order into the model. The @@ -129,6 +129,7 @@ pub(crate) struct StructEntry { /// always false when it is enum pub is_empty_struct: bool, pub is_native: bool, + pub visibility: Visibility, } #[derive(Debug, Clone)] @@ -271,6 +272,7 @@ impl<'env> ModelBuilder<'env> { display_type_vars: false, used_modules: BTreeSet::new(), use_module_qualification: false, + display_module_addr: false, recursive_vars: None, } } @@ -363,7 +365,20 @@ impl<'env> ModelBuilder<'env> { type_params: Vec, layout: StructLayout, is_native: bool, + visibility: Visibility, ) { + if self + .env + .language_version() + .language_version_for_public_struct() + && visibility.is_public_or_friend() + && abilities.has_ability(Ability::Key) + { + self.env.error( + &loc, + "structs/enums with key ability cannot have public, package or friend visibility", + ); + } let entry = StructEntry { loc, attributes, @@ -375,6 +390,7 @@ impl<'env> ModelBuilder<'env> { receiver_functions: BTreeMap::new(), is_empty_struct: false, is_native, + visibility, }; self.struct_table.insert(name.clone(), entry); self.reverse_struct_table @@ -692,10 +708,7 @@ impl<'env> ModelBuilder<'env> { /// Returns the name for the pseudo builtin module. pub fn builtin_module(&self) -> ModuleName { - ModuleName::new( - Address::Numerical(AccountAddress::ZERO), - self.env.symbol_pool().make("$$"), - ) + ModuleName::builtin_module(self.env) } /// Adds a spec function to used_spec_funs set. diff --git a/third_party/move/move-model/src/builder/module_builder.rs b/third_party/move/move-model/src/builder/module_builder.rs index 3006c3ae714..c18b865040a 100644 --- a/third_party/move/move-model/src/builder/module_builder.rs +++ b/third_party/move/move-model/src/builder/module_builder.rs @@ -19,6 +19,7 @@ use crate::{ constant_folder::ConstantFolder, exp_rewriter::{ExpRewriter, ExpRewriterFunctions, RewriteTarget}, intrinsics::process_intrinsic_declaration, + metadata::lang_feature_versions::LANGUAGE_VERSION_FOR_PUBLIC_STRUCT, model::{ self, EqIgnoringLoc, FieldData, FieldId, FunId, FunctionData, FunctionKind, FunctionLoc, Loc, ModuleId, MoveIrLoc, NamedConstantData, NamedConstantId, NodeId, Parameter, SchemaId, @@ -35,7 +36,8 @@ use crate::{ Constraint, ConstraintContext, ErrorMessageContext, PrimitiveType, Type, Variance, BOOL_TYPE, }, - well_known, LanguageVersion, + well_known::{self}, + LanguageVersion, }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; @@ -66,12 +68,14 @@ pub(crate) struct ModuleBuilder<'env, 'translator> { pub use_decls: Vec, /// Translated friend declarations. pub friend_decls: Vec, - /// Location of a friend visibility modifier in the current module - pub friend_fun_loc: Option, + /// Location of a friend/package visibility modifier in the current module + pub friend_visibility_loc: Option, /// Location of a package visibility modifier in the current module pub package_fun_loc: Option, /// Set of functions with package visibility in the current module pub package_funs: BTreeSet, + /// Set of structs with package visibility in the current module + pub package_structs: BTreeSet, /// Translated specification functions. pub spec_funs: Vec, /// During the definition analysis, the index into `spec_funs` we are currently @@ -116,10 +120,7 @@ pub enum SpecBlockContext { impl SpecBlockContext { pub fn allow_old(&self) -> bool { use SpecBlockContext::*; - match self { - FunctionCodeV2(_, _, _) => false, // TODO(#16256): add support of old(..) to spec of lambda expression - _ => true, - } + !matches!(self, FunctionCodeV2(_, _, None)) } pub fn name(&self) -> Option<&QualifiedSymbol> { @@ -158,9 +159,10 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { module_id, module_name, use_decls: vec![], - friend_fun_loc: None, + friend_visibility_loc: None, package_fun_loc: None, package_funs: BTreeSet::new(), + package_structs: BTreeSet::new(), friend_decls: vec![], spec_funs: vec![], inline_spec_builder: Spec::default(), @@ -522,6 +524,23 @@ impl ModuleBuilder<'_, '_> { let struct_id = StructId::new(qsym.symbol); let attrs = self.translate_attributes(&def.attributes); let abilities = self.translate_abilities(&def.abilities); + let visibility = match def.visibility { + EA::Visibility::Public(_) => Visibility::Public, + EA::Visibility::Friend(loc) => { + if self.friend_visibility_loc.is_none() { + self.friend_visibility_loc = Some(loc); + } + Visibility::Friend + }, + EA::Visibility::Internal => Visibility::Private, + EA::Visibility::Package(loc) => { + if self.package_fun_loc.is_none() { + self.package_fun_loc = Some(loc); + } + self.package_structs.insert(struct_id); + Visibility::Friend + }, + }; let mut et = ExpTranslator::new(self); et.set_translate_move_fun(); let type_params = et.analyze_and_add_type_params( @@ -539,6 +558,7 @@ impl ModuleBuilder<'_, '_> { type_params, StructLayout::None, // will be filled in during definition analysis, matches!(def.layout, EA::StructLayout::Native(_)), + visibility, ); } @@ -554,8 +574,8 @@ impl ModuleBuilder<'_, '_> { let visibility = match def.visibility { EA::Visibility::Public(_) => Visibility::Public, EA::Visibility::Friend(loc) => { - if self.friend_fun_loc.is_none() { - self.friend_fun_loc = Some(loc); + if self.friend_visibility_loc.is_none() { + self.friend_visibility_loc = Some(loc); } Visibility::Friend }, @@ -1185,6 +1205,11 @@ impl ModuleBuilder<'_, '_> { EA::SpecBlockMember_::Update { lhs, rhs } => { self.def_ana_global_var_update(loc, &context, lhs, rhs) }, + EA::SpecBlockMember_::Pragma { properties } + if matches!(context, SpecBlockContext::FunctionCodeV2(.., Some(..))) => + { + self.def_ana_pragma(loc, &context, properties); + }, _ => { self.parent.error(loc, "item not allowed"); }, @@ -1941,7 +1966,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { fn check_visibility_compatibility(&self) { if let Some(package_vis_loc) = &self.package_fun_loc { let package_vis_loc = self.parent.to_loc(package_vis_loc); - let friend_vis_loc = if let Some(friend_vis_loc) = &self.friend_fun_loc { + let friend_vis_loc = if let Some(friend_vis_loc) = &self.friend_visibility_loc { Some(self.parent.to_loc(friend_vis_loc)) } else { self.friend_decls @@ -2743,7 +2768,8 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> { fn iter_schema_includes<'a>( &self, members: &'a [EA::SpecBlockMember], - ) -> impl Iterator, &'a EA::Exp)> { + ) -> impl Iterator, &'a EA::Exp)> + use<'a> + { members.iter().filter_map(|m| { if let EA::SpecBlockMember_::Include { properties, exp } = &m.value { Some((&m.loc, properties, exp)) @@ -3590,8 +3616,23 @@ impl ModuleBuilder<'_, '_> { variants: if is_enum { Some(variants) } else { None }, spec: RefCell::new(spec), is_native: entry.is_native, + visibility: entry.visibility, + has_package_visibility: self.package_structs.contains(&entry.struct_id), }; struct_data.insert(StructId::new(name.symbol), data); + if entry.visibility != Visibility::Private + && !self + .parent + .env + .language_version() + .language_version_for_public_struct() + { + self.parent.env.warning( + &loc, + &format!("structs/enums with visibility modifier are only supported at version {} or later", + LANGUAGE_VERSION_FOR_PUBLIC_STRUCT) + ); + } } let mut function_data: BTreeMap = Default::default(); for (name, entry) in &self.parent.fun_table { @@ -3640,6 +3681,7 @@ impl ModuleBuilder<'_, '_> { using_funs: RefCell::default(), transitive_closure_of_used_funs: RefCell::default(), used_functions_with_transitive_inline: RefCell::default(), + used_structs: RefCell::default(), }; function_data.insert(fun_id, data); } diff --git a/third_party/move/move-model/src/constant_folder.rs b/third_party/move/move-model/src/constant_folder.rs index e51cce7aeeb..2e5cba02629 100644 --- a/third_party/move/move-model/src/constant_folder.rs +++ b/third_party/move/move-model/src/constant_folder.rs @@ -351,13 +351,11 @@ impl<'env> ConstantFolder<'env> { O::Or => Some(V(id, Bool(*val0 || *val1)).into_exp()), O::Eq => Some(V(id, Bool(*val0 == *val1)).into_exp()), O::Neq => Some(V(id, Bool(*val0 != *val1)).into_exp()), - _ => { - return self.constant_folding_error(id, |_| { - "Binary expression with boolean parameters and result \ + _ => self.constant_folding_error(id, |_| { + "Binary expression with boolean parameters and result \ not foldable to constant" - .to_owned() - }) - }, + .to_owned() + }), } } else { match oper { diff --git a/third_party/move/move-model/src/exp_builder.rs b/third_party/move/move-model/src/exp_builder.rs index f5e5952a616..16bb41019e8 100644 --- a/third_party/move/move-model/src/exp_builder.rs +++ b/third_party/move/move-model/src/exp_builder.rs @@ -11,7 +11,7 @@ use crate::{ ty::Type, }; use itertools::Itertools; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, vec}; /// Represents an expression builder. pub struct ExpBuilder<'a> { @@ -50,6 +50,20 @@ impl<'a> ExpBuilder<'a> { } } + pub fn and(&self, exp1: Exp, exp2: Exp) -> Exp { + use ExpData::*; + // Pull Not to the outside so it can be eliminated with if-else + let id = self.clone_node_id(exp1.node_id()); + if let (Some(arg1), Some(arg2)) = ( + self.extract_not(exp1.clone()), + self.extract_not(exp2.clone()), + ) { + self.not(Call(id, Operation::Or, vec![arg1, arg2]).into_exp()) + } else { + Call(id, Operation::And, vec![exp1, exp2]).into_exp() + } + } + pub fn if_else(&self, cond: Exp, if_true: Exp, if_false: Exp) -> Exp { if if_false.is_unit_exp() { self.if_(cond, if_true) @@ -114,9 +128,14 @@ impl<'a> ExpBuilder<'a> { /// Constructs a loop, simplifying redundant loop. pub fn loop_(&self, body: Exp) -> Exp { let loc = self.env().get_node_loc(body.node_id()); + // We can skip creating a loop if the loop body + // - always terminates + // - does not `continue` itself + // - without considering the terminating expression, does not `break` itself + let branch_cond = |loop_nest: usize, nest: usize, _: bool| nest == loop_nest; if let Some(body_prefix) = self .extract_terminated_prefix(&loc, body.clone(), 0, true) - .filter(|prefix| !prefix.branches_to(0..1)) + .filter(|prefix| !prefix.customizable_branches_to(branch_cond)) { body_prefix.rewrite_loop_nest(-1) } else { @@ -156,28 +175,6 @@ impl<'a> ExpBuilder<'a> { } } - /// Pushes a loop block close to the point where it matters, i.e. where there is - /// another loop or a break/continue. - pub fn push_loop_block_into(&self, exp: Exp) -> Exp { - match exp.as_ref() { - ExpData::Loop(..) | ExpData::LoopCont(..) => self.loop_(exp), - ExpData::Sequence(id, elems) => { - if let Some(i) = elems - .iter() - .position(|e| matches!(e.as_ref(), ExpData::Loop(..) | ExpData::LoopCont(..))) - { - let mut new_elems = elems[0..i].to_vec(); - let default_loc = self.env().get_node_loc(*id); - new_elems.push(self.loop_(self.seq(&default_loc, elems[i..].to_vec()))); - self.seq(&default_loc, new_elems) - } else { - exp - } - }, - _ => exp, - } - } - pub fn unfold(&self, substitution: &BTreeMap, exp: Exp) -> Exp { ExpData::rewrite(exp, &mut |e: Exp| { if let ExpData::LocalVar(_, name) = e.as_ref() { @@ -239,6 +236,90 @@ impl<'a> ExpBuilder<'a> { } } + /// Attempts to extract an `if-then` expression where the then branch terminates a loop + /// via `break[*]|continue[>0]|return|abort`. + pub fn match_if_then_break(&self, exp: Exp) -> Option<(Exp, Exp)> { + let node_id = exp.node_id(); + let default_loc = self.env().get_node_loc(node_id); + match exp.as_ref() { + ExpData::IfElse(_, cond, if_true, if_false) + if if_false.is_unit_exp() + && self + .extract_terminated_prefix(&default_loc, if_true.clone(), 0, true) + .is_some() => + { + Some((cond.clone(), if_true.clone())) + }, + _ => None, + } + } + + /// Attempts to extract an `if-then-else` expression where the else branch terminates a loop + /// via `break[*]|continue[>0]|return|abort`, but the then branch does not. + pub fn match_if_else_break(&self, exp: Exp) -> Option<(Exp, Exp, Exp)> { + let node_id = exp.node_id(); + let default_loc = self.env().get_node_loc(node_id); + match exp.as_ref() { + ExpData::IfElse(_, cond, if_true, if_false) + if self.extract_terminated_prefix(&default_loc, if_true.clone(), 0, true).is_none() // true branch does not break + && self.extract_terminated_prefix(&default_loc, if_false.clone(), 0, true).is_some() // false branch breaks + => { + Some((cond.clone(), if_true.clone(), if_false.clone())) + }, + _ => None, + } + } + + /// Attempts to extract an `if-then-else` expression where the then branch terminates a loop + /// via `break[*]|continue[>0]|return|abort`, but the else branch does not. + pub fn match_if_break_else(&self, exp: Exp) -> Option<(Exp, Exp, Exp)> { + let node_id = exp.node_id(); + let default_loc = self.env().get_node_loc(node_id); + match exp.as_ref() { + ExpData::IfElse(_, cond, if_true, if_false) + if self.extract_terminated_prefix(&default_loc, if_true.clone(), 0, true).is_some() // true branch does not break + && self.extract_terminated_prefix(&default_loc, if_false.clone(), 0, true).is_none() // false branch breaks + => { + Some((cond.clone(), if_true.clone(), if_false.clone())) + }, + _ => None, + } + } + + /// Attempts to match a nested if-break structure: + /// + /// ```move + /// if (c_1) { + /// if (c_2) { + /// ... + /// if (c_n) { + /// which break[*]|continue[>0]|return|abort + /// } + /// } + /// } + /// ``` + /// + /// This will merge conditions as `c_1 && c_2 && ..` and return the as an expression. + pub fn match_nested_if_break(&self, mut exp: Exp) -> Option<(Exp, Exp)> { + let node_id = exp.node_id(); + let default_loc = self.env().get_node_loc(node_id); + let mut cond = None; + loop { + let (c, if_true) = self.match_if(exp)?; + match cond { + None => cond = Some(c), + Some(old) => cond = Some(self.and(old, c)), + } + if self + .extract_terminated_prefix(&default_loc, if_true.clone(), 0, true) + .is_some() + { + return Some((cond.expect("condition must be present"), if_true)); + } + exp = if_true; + } + } + pub fn match_if_loop_cont(&self, exp: Exp, nest: usize, is_continue: bool) -> Option { let (cond, if_true) = self.match_if(exp)?; if if_true.is_loop_cont(Some(nest), is_continue) { @@ -275,6 +356,104 @@ impl<'a> ExpBuilder<'a> { cond.map(|c| (c, exp)) } + /// Attempts to extract a sequence of if-break-else-branch + /// + /// ```move + /// + /// if (c_1) break; + /// + /// if (c_2) break; + /// + /// if (c_n) break; + /// + /// ``` + /// This will return the results as a vector <[seq(begin_stmts), c_1, seq(else_branch_1), c_2, seq(else_branch_2), ...]> + pub fn match_if_break_else_list(&self, mut exp: Exp, nest: usize) -> Option> { + let default_loc = self.env.get_node_loc(exp.node_id()); + // Global vector to track the `if-break-then` list + let mut if_branch_list = vec![]; + // Local vector to track the current sequence of expressions that represent the before an if-break + let mut cur_branch = vec![]; + + loop { + let (first, rest) = self.extract_first(exp.clone()); + // Found a `if-break` + if let Some(c) = self.match_if_loop_cont(first.clone(), nest, false) { + // save the before the if-break + let seq = self.seq(&default_loc, std::mem::take(&mut cur_branch)); + if_branch_list.push(seq); + // save the condition + if_branch_list.push(c); + } else { + cur_branch.push(first); + }; + // No more exps to process + if rest.is_empty() { + break; + } + exp = self.seq(&default_loc, rest) + } + + // Do not forget to add + let seq = self.seq(&default_loc, cur_branch.clone()); + if_branch_list.push(seq); + Some(if_branch_list) + } + + /// Attempts to extract a sequence of if-then-break-else-branch + /// + /// ```move + /// + /// if (c_1) { + /// which break[*]|continue[>0]|return|abort + /// } + /// + /// if (c_2) { + /// which break[*]|continue[>0]|return|abort + /// } + /// + /// if (c_n) { + /// which break[*]|continue[>0]|return|abort + /// } + /// + /// ``` + /// + /// This will return the results as a vector <[seq(begin_stmts), c_1, seq(then_branch_1), seq(else_branch_1), c_2, seq(then_branch_2), seq(else_branch_2), ...]> + pub fn match_if_branch_break_branch_list(&self, mut exp: Exp) -> Option> { + let default_loc = self.env.get_node_loc(exp.node_id()); + // Vector to track the global `if-then-else` list + let mut if_else_list = vec![]; + // Vector to track the current sequence of expressions that represent the before an `if-then` + let mut cur_branch = vec![]; + + loop { + let (first, rest) = self.extract_first(exp.clone()); + // Found a `if-then-break` + if let Some((c, if_true)) = self.match_if_then_break(first.clone()) { + // Save the previous (meanwhile clean up `cur_branch`) + let seq = self.seq(&default_loc, std::mem::take(&mut cur_branch)); + if_else_list.push(seq); + // Save the condition + if_else_list.push(c); + // Save the + if_else_list.push(if_true); + } else { + // Not an `if-then-break`, so we add it to the current sequence + cur_branch.push(first); + }; + // No more exps to process + if rest.is_empty() { + break; + } + exp = self.seq(&default_loc, rest) + } + + // Do not forget to add + let seq = self.seq(&default_loc, cur_branch.clone()); + if_else_list.push(seq); + Some(if_else_list) + } + pub fn new_node_id(&self, loc: Loc, ty: Type) -> NodeId { self.env.new_node(loc, ty) } diff --git a/third_party/move/move-model/src/exp_generator.rs b/third_party/move/move-model/src/exp_generator.rs index e602276a21b..0072c4a1a8b 100644 --- a/third_party/move/move-model/src/exp_generator.rs +++ b/third_party/move/move-model/src/exp_generator.rs @@ -6,7 +6,7 @@ use crate::{ ast::{Address, Exp, ExpData, Operation, Pattern, QuantKind, TempIndex, Value}, model::{ FieldEnv, FunctionEnv, GlobalEnv, Loc, NodeId, QualifiedId, QualifiedInstId, SpecFunId, - StructId, + StructEnv, StructId, }, symbol::Symbol, ty::{PrimitiveType, Type, BOOL_TYPE, NUM_TYPE}, @@ -377,6 +377,19 @@ pub trait ExpGenerator<'env> { .into_exp() } + /// Makes an expression which tests a variant. + fn mk_variant_test(&self, struct_env: &StructEnv, variant: Symbol, exp: Exp) -> Exp { + let node_id = self.new_node(Type::Primitive(PrimitiveType::Bool), None); + ExpData::Call( + node_id, + Operation::TestVariants(struct_env.module_env.get_id(), struct_env.get_id(), vec![ + variant, + ]), + vec![exp], + ) + .into_exp() + } + /// Makes an expression for a temporary. fn mk_temporary(&self, temp: TempIndex) -> Exp { let ty = self.get_local_type(temp); diff --git a/third_party/move/move-model/src/exp_rewriter.rs b/third_party/move/move-model/src/exp_rewriter.rs index 32d57a6de8d..91e31224bc2 100644 --- a/third_party/move/move-model/src/exp_rewriter.rs +++ b/third_party/move/move-model/src/exp_rewriter.rs @@ -246,6 +246,9 @@ pub trait ExpRewriterFunctions { ) -> Option { None } + fn rewrite_match(&mut self, id: NodeId, disc: &Exp, arms: &[MatchArm]) -> Option { + None + } // Optionally rewrite a pattern, which may be in `Let`, `Lambda`, or `Assign` expression. // // Parameter`creating_scope` is `true` for `Let` and `Lambda` operations, which create a new @@ -509,8 +512,10 @@ pub trait ExpRewriterFunctions { arms_changed = arms_changed || arm_changed || pat_changed || cond_changed || body_changed; } - if id_changed || disc_changed || arms_changed { - Match(*id, new_disc, new_arms).into_exp() + if let Some(new_exp) = self.rewrite_match(new_id, &new_disc, &new_arms) { + new_exp + } else if id_changed || disc_changed || arms_changed { + Match(new_id, new_disc, new_arms).into_exp() } else { exp } diff --git a/third_party/move/move-model/src/lib.rs b/third_party/move/move-model/src/lib.rs index 5e75c98db19..e7c0fe016e2 100644 --- a/third_party/move/move-model/src/lib.rs +++ b/third_party/move/move-model/src/lib.rs @@ -25,15 +25,7 @@ use legacy_move_compiler::{ }, Compiler, Flags, PASS_EXPANSION, PASS_PARSER, }; -use move_binary_format::{ - check_bounds::BoundsChecker, - file_format::{ - AddressIdentifierIndex, CompiledModule, CompiledScript, FunctionDefinition, FunctionHandle, - FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, - SignatureIndex, Visibility, - }, -}; -use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use move_core_types::account_address::AccountAddress; use move_symbol_pool::Symbol as MoveSymbol; use std::{ collections::{BTreeMap, BTreeSet}, @@ -62,7 +54,6 @@ pub mod ty_invariant_analysis; pub mod well_known; pub use builder::binary_module_loader; -use move_binary_format::access::ScriptAccess; /// Represents information about a package: the sources it contains and the package private /// address mapping. @@ -105,6 +96,7 @@ pub fn run_model_builder_in_compiler_mode( deps.into_iter().map(to_package_paths).collect(), ModelBuilderOptions { language_version, + compile_for_testing: compile_test_code, ..ModelBuilderOptions::default() }, Flags::model_compilation() @@ -269,7 +261,10 @@ pub fn run_model_builder_with_options_and_compilation_flags< let mut visited_modules = BTreeSet::new(); // Extract the module dependency closure for the vector module let mut vector_and_its_dependencies = BTreeSet::new(); + // Extract the module dependency closure for the std::cmp module + let mut cmp_and_its_dependencies = BTreeSet::new(); let mut seen_vector = false; + let mut seen_cmp = false; for (_, mident, mdef) in &expansion_ast.modules { let src_file_hash = mdef.loc.file_hash(); if !dep_files.contains(&src_file_hash) { @@ -284,6 +279,15 @@ pub fn run_model_builder_with_options_and_compilation_flags< &mut vector_and_its_dependencies, ); } + if !seen_cmp && is_cmp(*mident) { + seen_cmp = true; + // Collect the cmp module and its dependencies. + collect_related_modules_recursive( + mident, + &expansion_ast.modules, + &mut cmp_and_its_dependencies, + ); + } } for sdef in expansion_ast.scripts.values() { let src_file_hash = sdef.loc.file_hash(); @@ -307,6 +311,9 @@ pub fn run_model_builder_with_options_and_compilation_flags< // E.g., index operation on a vector results in a call to `vector::borrow`. // TODO(#15483): consider refactoring code to avoid this special case. (vector_and_its_dependencies.contains(&mident.value) + // We also need to always include the `cmp` module and its dependencies, + // so that we can use interfaces offered by `cmp` to support comparison, Lt/Le/Gt/Ge, over non-integer types. + || cmp_and_its_dependencies.contains(&mident.value) || visited_modules.contains(&mident.value)) .then(|| { mdef.is_source_module = true; @@ -327,6 +334,12 @@ fn is_vector(module_ident: ModuleIdent_) -> bool { && module_ident.module.0.value.as_str() == "vector" } +/// Is `module_ident` the `0x1::cmp` module? +fn is_cmp(module_ident: ModuleIdent_) -> bool { + module_ident.address.into_addr_bytes().into_inner() == AccountAddress::ONE + && module_ident.module.0.value.as_str() == well_known::CMP_MODULE +} + fn run_move_checker(env: &mut GlobalEnv, program: E::Program) { let mut builder = ModelBuilder::new(env); for (module_count, (module_id, module_def)) in program @@ -492,139 +505,6 @@ pub fn add_move_lang_diagnostics(env: &mut GlobalEnv, diags: Diagnostics) { } } -/// Converts the given compiled script into an equivalent compiled module. This assigns -/// a unique name to the module based on the script function's name and the passed index. -/// The index must be unique w.r.t. the context of where the result shall be used -/// since the function name alone can be used by multiple scripts in the context. -pub fn convert_script_to_module(script: CompiledScript, index: usize) -> CompiledModule { - let fhd = script - .function_handles - .first() - .expect("malformed script without function"); - let name = script.identifier_at(fhd.name); - let unique_name = format!("{}_{}", name, index); - script_into_module(script, &unique_name) -} - -#[allow(deprecated)] -pub fn script_into_module(compiled_script: CompiledScript, name: &str) -> CompiledModule { - let mut script = compiled_script; - - // Add the "" identifier if it isn't present. - // - // Note: When adding an element to the table, in theory it is possible for the index - // to overflow. This will not be a problem if we get rid of the script/module conversion. - let self_ident_idx = match script - .identifiers - .iter() - .position(|ident| ident.as_ident_str().as_str() == name) - { - Some(idx) => IdentifierIndex::new(idx as u16), - None => { - let idx = IdentifierIndex::new(script.identifiers.len() as u16); - script - .identifiers - .push(Identifier::new(name.to_string()).unwrap()); - idx - }, - }; - - // Add a dummy address if none exists. - let dummy_addr = AccountAddress::MAX_ADDRESS; - let dummy_addr_idx = match script - .address_identifiers - .iter() - .position(|addr| addr == &dummy_addr) - { - Some(idx) => AddressIdentifierIndex::new(idx as u16), - None => { - let idx = AddressIdentifierIndex::new(script.address_identifiers.len() as u16); - script.address_identifiers.push(dummy_addr); - idx - }, - }; - - // Add a self module handle. - let self_module_handle_idx = match script - .module_handles - .iter() - .position(|handle| handle.address == dummy_addr_idx && handle.name == self_ident_idx) - { - Some(idx) => ModuleHandleIndex::new(idx as u16), - None => { - let idx = ModuleHandleIndex::new(script.module_handles.len() as u16); - script.module_handles.push(ModuleHandle { - address: dummy_addr_idx, - name: self_ident_idx, - }); - idx - }, - }; - - // Find the index to the empty signature []. - // Create one if it doesn't exist. - let return_sig_idx = match script.signatures.iter().position(|sig| sig.0.is_empty()) { - Some(idx) => SignatureIndex::new(idx as u16), - None => { - let idx = SignatureIndex::new(script.signatures.len() as u16); - script.signatures.push(Signature(vec![])); - idx - }, - }; - - // Create a function handle for the main function. - let main_handle_idx = FunctionHandleIndex::new(script.function_handles.len() as u16); - script.function_handles.push(FunctionHandle { - module: self_module_handle_idx, - name: self_ident_idx, - parameters: script.parameters, - return_: return_sig_idx, - type_parameters: script.type_parameters, - access_specifiers: None, // TODO: access specifiers for script functions - attributes: vec![], - }); - - // Create a function definition for the main function. - let main_def = FunctionDefinition { - function: main_handle_idx, - visibility: Visibility::Public, - is_entry: true, - acquires_global_resources: vec![], - code: Some(script.code), - }; - - let module = CompiledModule { - version: script.version, - module_handles: script.module_handles, - self_module_handle_idx, - struct_handles: script.struct_handles, - function_handles: script.function_handles, - field_handles: vec![], - friend_decls: vec![], - - struct_def_instantiations: vec![], - function_instantiations: script.function_instantiations, - field_instantiations: vec![], - - signatures: script.signatures, - - identifiers: script.identifiers, - address_identifiers: script.address_identifiers, - constant_pool: script.constant_pool, - metadata: script.metadata, - - struct_defs: vec![], - function_defs: vec![main_def], - - struct_variant_handles: vec![], - struct_variant_instantiations: vec![], - variant_field_handles: vec![], - variant_field_instantiations: vec![], - }; - BoundsChecker::verify_module(&module).expect("invalid bounds in module"); - module -} - // ================================================================================================= // Helpers diff --git a/third_party/move/move-model/src/metadata.rs b/third_party/move/move-model/src/metadata.rs index b9cc6985e92..29a846fc4b0 100644 --- a/third_party/move/move-model/src/metadata.rs +++ b/third_party/move/move-model/src/metadata.rs @@ -3,7 +3,9 @@ use anyhow::bail; use legacy_move_compiler::shared::LanguageVersion as CompilerLanguageVersion; -use move_binary_format::file_format_common::{VERSION_8, VERSION_DEFAULT, VERSION_DEFAULT_LANG_V2}; +use move_binary_format::file_format_common::{ + VERSION_DEFAULT, VERSION_DEFAULT_LANG_V2, VERSION_DEFAULT_LANG_V2_3, +}; use move_command_line_common::env; use serde::{Deserialize, Serialize}; use std::{ @@ -13,13 +15,24 @@ use std::{ }; const UNSTABLE_MARKER: &str = "-unstable"; -pub const LATEST_STABLE_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_1; +// 2.2, even though stable, produces several warnings in the frameworks which we first need to fix +// before we can make it the default +pub const LATEST_STABLE_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_2; pub const LATEST_STABLE_COMPILER_VERSION_VALUE: CompilerVersion = CompilerVersion::V2_0; pub const LATEST_STABLE_LANGUAGE_VERSION: &str = LATEST_STABLE_LANGUAGE_VERSION_VALUE.to_str(); pub const LATEST_STABLE_COMPILER_VERSION: &str = LATEST_STABLE_COMPILER_VERSION_VALUE.to_str(); pub static COMPILATION_METADATA_KEY: &[u8] = "compilation_metadata".as_bytes(); +// Language versions enabling specific features +pub mod lang_feature_versions { + use crate::LanguageVersion; + pub const COMPILE_FOR_TESTING_VALUE: LanguageVersion = LanguageVersion::V2_2; + pub const SINT_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_3; + pub const LANGUAGE_VERSION_FOR_PUBLIC_STRUCT: LanguageVersion = LanguageVersion::V2_4; + pub const LANGUAGE_VERSION_FOR_RAC: LanguageVersion = LanguageVersion::V2_5; +} + // ================================================================================' // Metadata for compilation result (WORK IN PROGRESS) @@ -190,10 +203,14 @@ pub enum LanguageVersion { V2_0, /// The 2.1 version of Move, V2_1, - /// The currently unstable 2.2 version of Move + /// The 2.2 version of Move V2_2, /// The currently unstable 2.3 version of Move V2_3, + /// The currently unstable 2.4 version of Move + V2_4, + /// The currently unstable 2.5 version of Move + V2_5, } impl Default for LanguageVersion { @@ -236,8 +253,10 @@ impl FromStr for LanguageVersion { "2" | "2.1" => Ok(Self::V2_1), "2.2" => Ok(Self::V2_2), "2.3" => Ok(Self::V2_3), + "2.4" => Ok(Self::V2_4), + "2.5" => Ok(Self::V2_5), _ => bail!( - "unrecognized language version \"{}\" (supported versions: \"1\", \"2\", \"2.0-2.3\")", + "unrecognized language version \"{}\" (supported versions: \"1\", \"2\", \"2.0-2.5\")", s ), } @@ -252,6 +271,8 @@ impl From for CompilerLanguageVersion { LanguageVersion::V2_1 => CompilerLanguageVersion::V2_1, LanguageVersion::V2_2 => CompilerLanguageVersion::V2_2, LanguageVersion::V2_3 => CompilerLanguageVersion::V2_3, + LanguageVersion::V2_4 => CompilerLanguageVersion::V2_4, + LanguageVersion::V2_5 => CompilerLanguageVersion::V2_5, } } } @@ -262,14 +283,14 @@ impl LanguageVersion { pub const fn unstable(self) -> bool { use LanguageVersion::*; match self { - V1 | V2_0 | V2_1 => false, - V2_2 | V2_3 => true, + V1 | V2_0 | V2_1 | V2_2 => false, + V2_3 | V2_4 | V2_5 => true, } } /// The latest language version. pub const fn latest() -> Self { - LanguageVersion::V2_3 + LanguageVersion::V2_5 } /// The latest stable language version. @@ -282,14 +303,21 @@ impl LanguageVersion { *self >= ver } + pub fn language_version_for_public_struct(&self) -> bool { + self.is_at_least(lang_feature_versions::LANGUAGE_VERSION_FOR_PUBLIC_STRUCT) + } + /// If the bytecode version is not specified, infer it from the language version. For /// debugging purposes, respects the MOVE_BYTECODE_VERSION env var as an override. pub fn infer_bytecode_version(&self, version: Option) -> u32 { env::get_bytecode_version_from_env(version).unwrap_or(match self { LanguageVersion::V1 => VERSION_DEFAULT, - LanguageVersion::V2_0 => VERSION_DEFAULT_LANG_V2, - LanguageVersion::V2_1 => VERSION_DEFAULT_LANG_V2, - LanguageVersion::V2_2 | LanguageVersion::V2_3 => VERSION_8, + LanguageVersion::V2_0 | LanguageVersion::V2_1 | LanguageVersion::V2_2 => { + VERSION_DEFAULT_LANG_V2 + }, + LanguageVersion::V2_3 | LanguageVersion::V2_4 | LanguageVersion::V2_5 => { + VERSION_DEFAULT_LANG_V2_3 + }, }) } @@ -300,6 +328,8 @@ impl LanguageVersion { LanguageVersion::V2_1 => "2.1", LanguageVersion::V2_2 => "2.2", LanguageVersion::V2_3 => "2.3", + LanguageVersion::V2_4 => "2.4", + LanguageVersion::V2_5 => "2.5", } } } @@ -315,6 +345,8 @@ impl Display for LanguageVersion { LanguageVersion::V2_1 => "2.1", LanguageVersion::V2_2 => "2.2", LanguageVersion::V2_3 => "2.3", + LanguageVersion::V2_4 => "2.4", + LanguageVersion::V2_5 => "2.5", }, if self.unstable() { UNSTABLE_MARKER } else { "" } ) diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 7e7903c951e..28b889af37a 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -48,11 +48,8 @@ use legacy_move_compiler::command_line as cli; #[allow(unused_imports)] use log::{debug, info, warn}; pub use move_binary_format::file_format::Visibility; -#[allow(deprecated)] -use move_binary_format::normalized::Type as MType; use move_binary_format::{ access::ModuleAccess, - binary_views::BinaryIndexedView, file_format::{ Bytecode, CodeOffset, Constant as VMConstant, ConstantPoolIndex, FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, SignatureIndex, SignatureToken, StructDefinitionIndex, @@ -61,7 +58,7 @@ use move_binary_format::{ views::{FunctionDefinitionView, FunctionHandleView, StructHandleView}, CompiledModule, }; -use move_bytecode_source_map::{mapping::SourceMapping, source_map::SourceMap}; +use move_bytecode_source_map::source_map::SourceMap; use move_command_line_common::{ address::NumericalAddress, env::read_bool_env_var, files::FileHash, }; @@ -72,7 +69,6 @@ use move_core_types::{ language_storage, value::MoveValue, }; -use move_disassembler::disassembler::{Disassembler, DisassemblerOptions}; use num::ToPrimitive; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; @@ -607,6 +603,10 @@ pub struct GlobalEnv { /// Whether the v2 compiler has generated this model. /// TODO: replace with a proper version number once we have this in file format pub(crate) generated_by_v2: bool, + /// A set of types that are instantiated in cmp module. + pub cmp_types: RefCell>, + /// An estimate of each target Move function's size. + pub function_size_estimate: RefCell, FunctionSize>>, } /// A helper type for implementing fmt::Display depending on GlobalEnv @@ -668,6 +668,8 @@ impl GlobalEnv { address_alias_map: Default::default(), everything_is_target: Default::default(), generated_by_v2: false, + cmp_types: RefCell::new(Default::default()), + function_size_estimate: RefCell::new(Default::default()), } } @@ -882,7 +884,7 @@ impl GlobalEnv { } /// Find all target modules and return in a vector - pub fn get_target_modules(&self) -> Vec { + pub fn get_target_modules(&self) -> Vec> { let mut target_modules: Vec = vec![]; for module_env in self.get_modules() { if module_env.is_target() { @@ -893,7 +895,7 @@ impl GlobalEnv { } /// Find all target modules and their transitive closures and return in a vector - pub fn get_target_modules_transitive_closure(&self) -> Vec { + pub fn get_target_modules_transitive_closure(&self) -> Vec> { let mut target_and_transitive_modules: BTreeSet = BTreeSet::new(); let mut todo_modules: BTreeSet = BTreeSet::new(); for module_env in self.get_modules() { @@ -924,7 +926,7 @@ impl GlobalEnv { } /// Find all primary target modules and return in a vector - pub fn get_primary_target_modules(&self) -> Vec { + pub fn get_primary_target_modules(&self) -> Vec> { let mut target_modules: Vec = vec![]; for module_env in self.get_modules() { if module_env.is_primary_target() { @@ -1249,6 +1251,15 @@ impl GlobalEnv { .any(|(d, _)| d.severity >= Severity::Warning) } + pub fn has_diag_in_primary_targets(&self, min_severity: Severity) -> bool { + self.diags.borrow().iter().any(|(d, _)| { + d.severity >= min_severity + && d.labels + .iter() + .any(|label| self.file_id_is_primary_target.contains(&label.file_id)) + }) + } + /// Writes accumulated diagnostics of given or higher severity. pub fn report_diag(&self, writer: &mut W, severity: Severity) { self.report_diag_with_filter( @@ -1281,25 +1292,18 @@ impl GlobalEnv { // Comparison of Diagnostic values that tries to match program ordering so we // can display them to the user in a more natural order. fn cmp_diagnostic(diag1: &Diagnostic, diag2: &Diagnostic) -> Ordering { - let labels_ordering = GlobalEnv::cmp_labels(&diag1.labels, &diag2.labels); - if Ordering::Equal == labels_ordering { - let sev_ordering = diag1 + GlobalEnv::cmp_labels(&diag1.labels, &diag2.labels).then_with(|| { + diag1 .severity .partial_cmp(&diag2.severity) - .expect("Severity provides a total ordering for valid severity enum values"); - if Ordering::Equal == sev_ordering { - let message_ordering = diag1.message.cmp(&diag2.message); - if Ordering::Equal == message_ordering { - diag1.code.cmp(&diag2.code) - } else { - message_ordering - } - } else { - sev_ordering - } - } else { - labels_ordering - } + .expect("Severity provides a total ordering for valid severity enum values") + .then_with(|| { + diag1 + .message + .cmp(&diag2.message) + .then_with(|| diag1.code.cmp(&diag2.code)) + }) + }) } // Label comparison that tries to match program ordering. `FileId` is already set in visitation @@ -1307,25 +1311,13 @@ impl GlobalEnv { // marking nested regions, we want the innermost region, so we order first by end of labelled // code region, then in reverse by start of region. fn cmp_label(label1: &Label, label2: &Label) -> Ordering { - let file_ordering = label1.file_id.cmp(&label2.file_id); - if Ordering::Equal == file_ordering { - // First order by end of region. - let end1 = label1.range.end; - let end2 = label2.range.end; - let end_ordering = end1.cmp(&end2); - if Ordering::Equal == end_ordering { - let start1 = label1.range.start; - let start2 = label2.range.start; - - // For nested regions with same end, show inner-most region first. - // Swap 1 and 2 in comparing starts. - start2.cmp(&start1) - } else { - end_ordering - } - } else { - file_ordering - } + label1.file_id.cmp(&label2.file_id).then_with(|| { + label1 + .range + .end + .cmp(&label2.range.end) + .then_with(|| label2.range.start.cmp(&label1.range.start)) + }) } // Label comparison within a list of labels for a given diagnostic, which orders by priority @@ -1346,12 +1338,14 @@ impl GlobalEnv { fn cmp_labels(labels1: &[Label], labels2: &[Label]) -> Ordering { let mut sorted_labels1 = labels1.iter().collect_vec(); sorted_labels1.sort_by(|l1, l2| GlobalEnv::cmp_label_priority(l1, l2)); + let sorted_labels1_len = sorted_labels1.len(); let mut sorted_labels2 = labels2.iter().collect_vec(); sorted_labels2.sort_by(|l1, l2| GlobalEnv::cmp_label_priority(l1, l2)); + let sorted_labels2_len = sorted_labels2.len(); std::iter::zip(sorted_labels1, sorted_labels2) .map(|(l1, l2)| GlobalEnv::cmp_label(l1, l2)) - .find(|r| Ordering::Equal != *r) - .unwrap_or(Ordering::Equal) + .fold(Ordering::Equal, Ordering::then) + .then_with(|| sorted_labels1_len.cmp(&sorted_labels2_len)) } /// Writes accumulated diagnostics that pass through `filter` @@ -1362,12 +1356,8 @@ impl GlobalEnv { { let mut shown = BTreeSet::new(); self.diags.borrow_mut().sort_by(|a, b| { - let reported_ordering = a.1.cmp(&b.1); - if Ordering::Equal == reported_ordering { - GlobalEnv::cmp_diagnostic(&a.0, &b.0) - } else { - reported_ordering - } + a.1.cmp(&b.1) + .then_with(|| GlobalEnv::cmp_diagnostic(&a.0, &b.0)) }); for (diag, reported) in self.diags.borrow_mut().iter_mut().filter(|(d, reported)| { !reported @@ -1728,13 +1718,106 @@ impl GlobalEnv { } let used_modules = self.get_used_modules_from_bytecode(&module); let friend_modules = self.get_friend_modules_from_bytecode(&module); + + // If use decls decls are empty, let's propagage them from the CompiledModule with aliases assigned + let use_decls = if self.module_data[module_id.0 as usize].use_decls.is_empty() { + // Map to keep track of aliases for used modules + // key: module name (without address) + // value: [module address -> module alias] + let mut aliases = BTreeMap::new(); + let mut make_alias = |address: Address, module_name: Symbol| { + // module name does not exist: alias not needed but keep track of it + let addr_alias_map = aliases.entry(module_name).or_insert_with(|| { + let mut inner_map = BTreeMap::new(); + inner_map.insert(address.clone(), module_name); + inner_map + }); + // The module name exists and the address has not been recorded, we need to make an alias for this module name at this address + if addr_alias_map.get(&address).is_none() { + let module_alias = format!( + "{}_{}", + module_name.display(&self.symbol_pool), + addr_alias_map.len() + ); + let alias = self.symbol_pool.make(&module_alias); + addr_alias_map.insert(address, alias); + return Some(alias); + } + None + }; + used_modules + .iter() + .map(|mid| { + let module_env = self.get_module(*mid); + let name = module_env.get_name(); + UseDecl { + loc: Loc::default(), + module_name: name.clone(), + module_id: Some(*mid), + alias: make_alias(name.addr().clone(), name.name()), + members: vec![], + } + }) + .collect() + } else { + vec![] + }; + // If friend decls are empty, let's propagage them from the CompiledModule + // Different from use decls, we allow friend modules that have not been added to the GlobalEnv + // - why: use decls are ensured to be added when `with_dep_closure` is set, which is not the case for friend decls + let friend_decls = if self.module_data[module_id.0 as usize] + .friend_decls + .is_empty() + { + module + .immediate_friends_iter() + .map(|(ff_addr, ff_name)| { + let addr = Address::Numerical(*ff_addr); + let name = self.symbol_pool.make(ff_name.as_str()); + let module_name = ModuleName::new(addr, name); + let module_id = self + .find_module(&module_name) + .map(|module_env| module_env.get_id()); + FriendDecl { + loc: Loc::default(), + module_name, + module_id, + } + }) + .collect() + } else { + vec![] + }; + let mod_data = &mut self.module_data[module_id.0 as usize]; mod_data.used_modules = used_modules; + mod_data.use_decls = use_decls; mod_data.friend_modules = friend_modules; + mod_data.friend_decls = friend_decls; mod_data.compiled_module = Some(module); mod_data.source_map = Some(source_map); } + /// Updates modules previously loaded into the environment + pub fn update_loaded_modules(&mut self) { + // update friend modules that are not ready when loading a module + let friend_modules_vec: Vec>> = + self.module_data + .iter() + .map(|mod_data| { + mod_data.compiled_module.as_ref().map(|compiled_module| { + self.get_friend_modules_from_bytecode(compiled_module) + }) + }) + .collect(); + + for (mod_data, friend_modules_opt) in self.module_data.iter_mut().zip(friend_modules_vec) { + if let Some(friend_modules) = friend_modules_opt { + mod_data.friend_modules = friend_modules; + } + } + } + fn get_used_funs_from_bytecode( &self, module: &CompiledModule, @@ -1863,6 +1946,8 @@ impl GlobalEnv { variants: None, spec: RefCell::new(Spec::default()), is_native: false, + visibility: Visibility::Private, + has_package_visibility: false, } } @@ -1984,8 +2069,16 @@ impl GlobalEnv { .function_data .get_mut(&fun.id) .unwrap(); - data.used_funs = Some(def.used_funs()); + // Recompute called and used functions. data.called_funs = Some(def.called_funs()); + data.used_funs = Some(def.used_funs()); + // Reset various caches because the AST has changed. + *data.calling_funs.borrow_mut() = None; + *data.transitive_closure_of_called_funs.borrow_mut() = None; + *data.using_funs.borrow_mut() = None; + *data.transitive_closure_of_used_funs.borrow_mut() = None; + *data.used_functions_with_transitive_inline.borrow_mut() = None; + // Set the new function definition. data.def = Some(def); } @@ -2045,6 +2138,7 @@ impl GlobalEnv { using_funs: RefCell::new(None), transitive_closure_of_used_funs: RefCell::new(None), used_functions_with_transitive_inline: RefCell::new(None), + used_structs: RefCell::new(None), }; assert!(self .module_data @@ -2111,6 +2205,7 @@ impl GlobalEnv { using_funs: RefCell::new(None), transitive_closure_of_used_funs: RefCell::new(None), used_functions_with_transitive_inline: RefCell::new(None), + used_structs: RefCell::new(None), } } @@ -2152,7 +2247,7 @@ impl GlobalEnv { /// Gets the spec block associated with the spec block target. Only /// module, struct, and function specs are supported. - pub fn get_spec_block(&self, target: &SpecBlockTarget) -> Ref { + pub fn get_spec_block(&self, target: &SpecBlockTarget) -> Ref<'_, Spec> { use SpecBlockTarget::*; match target { Module(mid) => self.module_data[mid.to_usize()].module_spec.borrow(), @@ -2179,7 +2274,7 @@ impl GlobalEnv { /// Gets the spec block associated with the spec block target. Only /// module, struct, and function specs are supported. - pub fn get_spec_block_mut(&self, target: &SpecBlockTarget) -> RefMut { + pub fn get_spec_block_mut(&self, target: &SpecBlockTarget) -> RefMut<'_, Spec> { use SpecBlockTarget::*; match target { Module(mid) => self.module_data[mid.to_usize()].module_spec.borrow_mut(), @@ -2205,10 +2300,20 @@ impl GlobalEnv { } /// Return the `StructEnv` for `str` - pub fn get_struct(&self, str: QualifiedId) -> StructEnv { + pub fn get_struct(&self, str: QualifiedId) -> StructEnv<'_> { self.get_module(str.module_id).into_struct(str.id) } + /// Return the `Option` for `str` + pub fn get_struct_opt(&self, str: QualifiedId) -> Option> { + self.get_module_opt(str.module_id).and_then(|module| { + module.data.struct_data.get(&str.id).map(|data| StructEnv { + module_env: module, + data, + }) + }) + } + // Gets the number of modules in this environment. pub fn get_module_count(&self) -> usize { self.module_data.len() @@ -2311,36 +2416,6 @@ impl GlobalEnv { None } - /// Attempt to compute a struct tag for (`mid`, `sid`, `ts`). Returns `Some` if all types in - /// `ts` are closed, `None` otherwise - pub fn get_struct_tag( - &self, - mid: ModuleId, - sid: StructId, - ts: &[Type], - ) -> Option { - self.get_struct_type(mid, sid, ts)?.into_struct_tag() - } - - /// Attempt to compute a struct type for (`mid`, `sid`, `ts`). - #[allow(deprecated)] - pub fn get_struct_type(&self, mid: ModuleId, sid: StructId, ts: &[Type]) -> Option { - let menv = self.get_module(mid); - Some(MType::Struct { - address: (if let Address::Numerical(addr) = *menv.self_address() { - Some(addr) - } else { - None - })?, - module: menv.get_identifier()?, - name: menv.get_struct(sid).get_identifier()?, - type_arguments: ts - .iter() - .map(|t| t.clone().into_normalized_type(self).unwrap()) - .collect(), - }) - } - /// Gets the location of the given node. pub fn get_node_loc(&self, node_id: NodeId) -> Loc { self.exp_info @@ -2534,7 +2609,7 @@ impl GlobalEnv { } /// Produce a TypeDisplayContext to print types within the scope of this env - pub fn get_type_display_ctx(&self) -> TypeDisplayContext { + pub fn get_type_display_ctx(&self) -> TypeDisplayContext<'_> { TypeDisplayContext::new(self) } @@ -2577,6 +2652,42 @@ impl GlobalEnv { }); } } + + /// Update the friend declarations in all target modules, when the + /// callees could have changed due to AST-level optimizations. + pub fn update_friend_decls_in_targets(&mut self) { + let mut friend_decls_to_add = BTreeMap::new(); + for module in self.get_target_modules() { + let module_name = module.get_name(); + let needed = module.need_to_be_friended_by(); + for need_to_be_friended_by in needed { + let need_to_be_friend_with = self.get_module(need_to_be_friended_by); + let already_friended = need_to_be_friend_with + .get_friend_decls() + .iter() + .any(|friend_decl| &friend_decl.module_name == module_name); + if !already_friended { + let loc = need_to_be_friend_with.get_loc(); + let friend_decl = FriendDecl { + loc, + module_name: module_name.clone(), + module_id: Some(module.get_id()), + }; + friend_decls_to_add + .entry(need_to_be_friended_by) + .or_insert_with(Vec::new) + .push(friend_decl); + } + } + } + for (module_id, friend_decls) in friend_decls_to_add { + let module_data = self.get_module_data_mut(module_id); + module_data + .friend_modules + .extend(friend_decls.iter().flat_map(|d| d.module_id)); + module_data.friend_decls.extend(friend_decls); + } + } } impl Default for GlobalEnv { @@ -2851,6 +2962,10 @@ impl GlobalEnv { }; format!("{}({}){}", type_params_str, params_str, result_str) } + + pub fn set_function_size_estimates(&self, sizes: BTreeMap, FunctionSize>) { + *self.function_size_estimate.borrow_mut() = sizes; + } } // ================================================================================================= @@ -3148,6 +3263,26 @@ impl<'env> ModuleEnv<'env> { deps.insert(used_mod_id); } } + // Obtain used structs and enums for package visibility of structs/enums + if self + .env + .language_version() + .language_version_for_public_struct() + { + for used_struct in fun_env.get_used_structs_with_transitive_inline() { + let used_mod_id = used_struct.module_id; + if self.get_id() == used_struct.module_id { + continue; + } + let used_mod_env = self.env.get_module(used_mod_id); + let used_struct_env = used_mod_env.get_struct(used_struct.id); + if used_struct_env.has_package_visibility() + && self.can_call_package_fun_in(&used_mod_env) + { + deps.insert(used_mod_id); + } + } + } } deps } @@ -3194,7 +3329,7 @@ impl<'env> ModuleEnv<'env> { } /// Returns a context to display types for this module. - pub fn get_type_display_ctx(&self) -> TypeDisplayContext { + pub fn get_type_display_ctx(&self) -> TypeDisplayContext<'_> { TypeDisplayContext { module_name: Some(self.get_name().clone()), used_modules: self.get_used_modules(false), @@ -3510,7 +3645,7 @@ impl<'env> ModuleEnv<'env> { } /// Gets module specification. - pub fn get_spec(&self) -> Ref { + pub fn get_spec(&self) -> Ref<'_, Spec> { self.data.module_spec.borrow() } @@ -3525,7 +3660,7 @@ impl<'env> ModuleEnv<'env> { pub fn get_spec_funs_of_name( &self, name: Symbol, - ) -> impl Iterator { + ) -> impl Iterator + use<'env> { self.data .spec_funs .iter() @@ -3534,20 +3669,10 @@ impl<'env> ModuleEnv<'env> { /// Disassemble the module bytecode, if it is available. pub fn disassemble(&self) -> Option { - let view = BinaryIndexedView::Module(self.get_verified_module()?); - let smap = self.data.source_map.as_ref().expect("source map").clone(); - let disas = Disassembler::new(SourceMapping::new(smap, view), DisassemblerOptions { - only_externally_visible: false, - print_code: true, - print_basic_blocks: true, - print_locals: true, - print_bytecode_stats: false, - }); + let module = self.get_verified_module()?; Some( - disas - .disassemble() - // Failure here is fatal and should not happen - .expect("Failed to disassemble a verified module"), + move_asm::disassembler::disassemble_module(String::new(), module, false) + .expect("disassemble succeeds"), ) } @@ -3606,6 +3731,14 @@ impl<'env> ModuleEnv<'env> { || self.is_module_in_ext("table") || self.is_module_in_ext("table_with_length") } + + pub fn is_cmp(&self) -> bool { + self.is_module_in_std("cmp") + } + + pub fn is_option(&self) -> bool { + self.is_module_in_std("option") + } } // ================================================================================================= @@ -3648,6 +3781,13 @@ pub struct StructData { /// Whether this struct is native pub is_native: bool, + + /// Visibility of this struct + pub visibility: Visibility, + + /// Whether this struct has package visibility before the transformation. + /// Invariant: when true, visibility is always friend. + pub(crate) has_package_visibility: bool, } impl StructData { @@ -3664,6 +3804,8 @@ impl StructData { variants: None, spec: RefCell::new(Default::default()), is_native: false, + visibility: Visibility::Private, + has_package_visibility: false, } } } @@ -3834,7 +3976,7 @@ impl<'env> StructEnv<'env> { /// Returns an iteration of the variant names in the struct, in the order they /// are declared. - pub fn get_variants(&self) -> impl Iterator + 'env { + pub fn get_variants(&self) -> impl Iterator + 'env + use<'env> { self.data .variants .as_ref() @@ -3973,7 +4115,7 @@ impl<'env> StructEnv<'env> { } /// Returns the data invariants associated with this struct. - pub fn get_spec(&self) -> Ref { + pub fn get_spec(&self) -> Ref<'_, Spec> { self.data.spec.borrow() } @@ -3992,7 +4134,7 @@ impl<'env> StructEnv<'env> { } /// Produce a TypeDisplayContext to print types within the scope of this env - pub fn get_type_display_ctx(&self) -> TypeDisplayContext { + pub fn get_type_display_ctx(&self) -> TypeDisplayContext<'_> { let type_param_names = self .get_type_parameters() .iter() @@ -4016,6 +4158,19 @@ impl<'env> StructEnv<'env> { } None } + + /// Whether the current struct/enum is Option + pub fn is_option_type(&self) -> bool { + self.module_env.is_option() && self.get_full_name_str() == "option::Option" + } + + pub fn get_visibility(&self) -> Visibility { + self.data.visibility + } + + pub fn has_package_visibility(&self) -> bool { + self.data.has_package_visibility + } } // ================================================================================================= @@ -4185,7 +4340,7 @@ impl NamedConstantEnv<'_> { } /// Returns a context to display types for this module. - pub fn get_type_display_ctx(&self) -> TypeDisplayContext { + pub fn get_type_display_ctx(&self) -> TypeDisplayContext<'_> { TypeDisplayContext { module_name: Some(self.module_env.get_name().clone()), used_modules: self.module_env.get_used_modules(false), @@ -4400,6 +4555,9 @@ pub struct FunctionData { /// A cache for used functions including ones obtained by transitively traversing used inline functions. pub(crate) used_functions_with_transitive_inline: RefCell>>>, + + /// A cache for used structs. + pub(crate) used_structs: RefCell>>>, } impl FunctionData { @@ -4428,6 +4586,7 @@ impl FunctionData { using_funs: RefCell::new(None), transitive_closure_of_used_funs: RefCell::new(None), used_functions_with_transitive_inline: RefCell::new(None), + used_structs: RefCell::new(None), } } } @@ -5133,6 +5292,31 @@ impl<'env> FunctionEnv<'env> { set } + /// Get used structs/enums including ones obtained by transitively traversing used inline functions + pub fn get_used_structs_with_transitive_inline(&self) -> BTreeSet> { + if let Some(used_structs) = &*self.data.used_structs.borrow() { + return used_structs.clone(); + } + + let mut set = BTreeSet::new(); + let mut reachable_funcs = VecDeque::new(); + reachable_funcs.push_back(self.clone()); + + while let Some(fnc) = reachable_funcs.pop_front() { + if let Some(def) = fnc.get_def() { + def.struct_usage(self.module_env.env, &mut set); + } + for callee in fnc.get_used_functions().expect("call info available") { + let f = self.module_env.env.get_function(*callee); + if f.is_inline() { + reachable_funcs.push_back(f.clone()); + } + } + } + *self.data.used_structs.borrow_mut() = Some(set.clone()); + set + } + /// Get the functions that call this one, if available. pub fn get_calling_functions(&self) -> Option>> { if let Some(calling) = &*self.data.calling_funs.borrow() { @@ -5247,7 +5431,7 @@ impl<'env> FunctionEnv<'env> { } /// Produce a TypeDisplayContext to print types within the scope of this env - pub fn get_type_display_ctx(&self) -> TypeDisplayContext { + pub fn get_type_display_ctx(&self) -> TypeDisplayContext<'_> { let type_param_names = self .get_type_parameters() .iter() @@ -5438,3 +5622,20 @@ impl fmt::Display for EnvDisplay<'_, Parameter> { ) } } + +#[derive(Clone, Copy, Debug, Default)] +pub struct FunctionSize { + /// Number of instructions in the function body + pub code_size: usize, + /// Number of local variables in the function + pub num_locals: usize, +} + +impl FunctionSize { + pub fn new(code_size: usize, num_locals: usize) -> Self { + Self { + code_size, + num_locals, + } + } +} diff --git a/third_party/move/move-model/src/options.rs b/third_party/move/move-model/src/options.rs index ab5b217ecb9..bfafff58e38 100644 --- a/third_party/move/move-model/src/options.rs +++ b/third_party/move/move-model/src/options.rs @@ -19,4 +19,8 @@ pub struct ModelBuilderOptions { /// Ignore the "opaque" pragma on all function specs when possible. The opaque can be ignored /// as long as the function spec has no property marked as `[concrete]` or `[abstract]`. pub ignore_pragma_opaque_when_possible: bool, + + /// Whether to compiler for testing. This will be reflected in the builtin constant + /// `__COMPILE_FOR_TESTING__`. + pub compile_for_testing: bool, } diff --git a/third_party/move/move-model/src/pragmas.rs b/third_party/move/move-model/src/pragmas.rs index 267346156a0..32226cb1d91 100644 --- a/third_party/move/move-model/src/pragmas.rs +++ b/third_party/move/move-model/src/pragmas.rs @@ -213,7 +213,7 @@ pub fn is_pragma_valid_for_block( | INTRINSIC_PRAGMA | UNROLL_PRAGMA ), - Function(..) => matches!( + Function(..) | FunctionCodeV2(.., Some(..)) => matches!( pragma, VERIFY_PRAGMA | TIMEOUT_PRAGMA diff --git a/third_party/move/move-model/src/sourcifier.rs b/third_party/move/move-model/src/sourcifier.rs index 01b358499a8..f88750f2614 100644 --- a/third_party/move/move-model/src/sourcifier.rs +++ b/third_party/move/move-model/src/sourcifier.rs @@ -19,7 +19,10 @@ use crate::{ }; use itertools::Itertools; use move_core_types::ability::AbilitySet; -use std::collections::{BTreeMap, BTreeSet}; +use std::{ + cell::RefCell, + collections::{BTreeMap, BTreeSet}, +}; // // ======================================================================================== // @@ -29,15 +32,21 @@ use std::collections::{BTreeMap, BTreeSet}; pub struct Sourcifier<'a> { builder: ExpBuilder<'a>, writer: CodeWriter, + // A mapping from symbols to their aliased string representation, if any. + sym_alias_map: RefCell>, + // whether to amend the displayed results to be recompilable (e.g., remove `__` from lambda names) and more readable (e.g., local var names starting from `_v0`) + amend: bool, } impl<'a> Sourcifier<'a> { /// Creates a new sourcifier. - pub fn new(env: &'a GlobalEnv) -> Self { + pub fn new(env: &'a GlobalEnv, amend: bool) -> Self { Self { builder: ExpBuilder::new(env), // Location not used, but required by the constructor writer: CodeWriter::new(env.unknown_loc()), + amend, + sym_alias_map: RefCell::new(BTreeMap::new()), } } @@ -63,23 +72,28 @@ impl<'a> Sourcifier<'a> { emitln!(self.writer, "module {} {{", module_env.get_full_name_str()); } self.writer.indent(); - for use_ in module_env.get_used_modules(false) { + + for use_ in module_env.get_use_decls() { emitln!( self.writer, - "use {};", - self.env().get_module(use_).get_full_name_str() + "use {}{};", + use_.module_name.display_full(self.env()).to_string(), + use_.alias + .map(|alias| format!(" as {}", alias.display(self.env().symbol_pool()))) + .unwrap_or_default() ) } - for friend in module_env.get_friend_modules() { + for friend_ in module_env.get_friend_decls() { emitln!( self.writer, "friend {};", - self.env().get_module(friend).get_full_name_str() + friend_.module_name.display_full(self.env()).to_string() ) } + if module_env.get_struct_count() > 0 { for struct_env in module_env.get_structs() { - self.print_struct(struct_env.get_qualified_id()) + self.print_struct(struct_env.get_qualified_id()); } } if module_env.get_function_count() > 0 { @@ -95,28 +109,38 @@ impl<'a> Sourcifier<'a> { /// as a parameter. pub fn print_fun(&self, fun_id: QualifiedId, def: Option<&Exp>) { let fun_env = self.env().get_function(fun_id); - match fun_env.visibility() { - Visibility::Private => {}, - Visibility::Public => { - emit!(self.writer, "public ") - }, - Visibility::Friend => { - emit!(self.writer, "friend ") - }, - } - if fun_env.is_entry() { - emit!(self.writer, "entry ") - } - if fun_env.is_native() { - emit!(self.writer, "native ") - } - if fun_env.is_inline() { - emit!(self.writer, "inline ") + if !fun_env.module_env.is_script_module() { + // Print attributes, visibility, and other modifiers + if !fun_env.get_attributes().is_empty() { + self.print_list("", "\n", "", fun_env.get_attributes().iter(), |attr| { + emit!(self.writer, "#[{}]", self.sym(attr.name())); + }); + emitln!(self.writer); + } + match fun_env.visibility() { + Visibility::Private => {}, + Visibility::Public => { + emit!(self.writer, "public ") + }, + Visibility::Friend => { + emit!(self.writer, "friend ") + }, + } + if fun_env.is_entry() { + emit!(self.writer, "entry ") + } + if fun_env.is_native() { + emit!(self.writer, "native ") + } + if fun_env.is_inline() { + emit!(self.writer, "inline ") + } } + emit!( self.writer, "fun {}{}", - self.sym(fun_env.get_name()), + Self::amend_fun_name(self.env(), self.sym(fun_env.get_name()), self.amend), self.type_params(fun_env.get_type_parameters_ref()) ); let tctx = fun_env.get_type_display_ctx(); @@ -140,9 +164,11 @@ impl<'a> Sourcifier<'a> { self.print_access_specifiers(&tctx, &fun_env); } if let Some(def) = def { + // Set up aliases for all temporary variables in the function body + self.set_temp_var_alias(def); // A sequence or block is already automatically printed in braces with indent let requires_braces = !Self::is_braced(def); - let exp_sourcifier = ExpSourcifier::for_fun(self, &fun_env, def); + let exp_sourcifier = ExpSourcifier::for_fun(self, &fun_env, tctx, def, self.amend); if requires_braces { self.print_block(|| { if !def.is_unit_exp() { @@ -154,11 +180,29 @@ impl<'a> Sourcifier<'a> { exp_sourcifier.print_exp(Prio::General, true, def) } emitln!(self.writer); + // Clear all temporary variable aliases after printing the function body + self.clear_temp_var_alias(); } else { emitln!(self.writer, ";"); } } + /// Amend function name to be recompilable + fn amend_fun_name(env: &GlobalEnv, mut fun: String, amend: bool) -> String { + // amend lambda function names + if amend { + if fun.starts_with("__lambda") { + fun = fun.replacen("__", "", 1); + fun = Self::new_global_unique_name(env, &fun); + } + // amend script entry function name + if fun.starts_with("_") { + fun = fun.replacen("_", "main_", 1); + } + } + fun + } + fn is_braced(exp: &Exp) -> bool { match exp.as_ref() { ExpData::Sequence(_, exps) => exps.len() != 1 || Self::is_braced(&exps[0]), @@ -168,76 +212,95 @@ impl<'a> Sourcifier<'a> { } fn print_access_specifiers(&self, tctx: &TypeDisplayContext, fun: &FunctionEnv) { - if let Some(specs) = fun.get_access_specifiers() { - self.writer.indent(); - for spec in specs { + let Some(specs) = fun.get_access_specifiers() else { + return; + }; + self.writer.indent(); + let mut acc_spec_map = BTreeMap::new(); + + // gather resources together under each spec kind + for spec_kind in [ + "!reads", + "!writes", + "!acquires", + "reads", + "writes", + "acquires", + ] { + acc_spec_map.insert(spec_kind.to_string(), BTreeSet::new()); + } + + for spec in specs { + let resource = match &spec.resource.1 { + ResourceSpecifier::Any => "*".to_string(), + ResourceSpecifier::DeclaredAtAddress(addr) => { + format!("0x{}::*::*", addr.expect_numerical().short_str_lossless()) + }, + ResourceSpecifier::DeclaredInModule(mid) => { + format!("{}::*", self.env().get_module(*mid).get_full_name_str()) + }, + ResourceSpecifier::Resource(sid) => { + format!("{}", sid.to_type().display(tctx)) + }, + }; + + let address = match &spec.address.1 { + AddressSpecifier::Any => "".to_string(), + AddressSpecifier::Address(addr) => { + format!("(0x{})", addr.expect_numerical().short_str_lossless()) + }, + AddressSpecifier::Parameter(sym) => { + format!("({})", self.sym(*sym)) + }, + AddressSpecifier::Call(fun, sym) => { + let func_env = self.env().get_function(fun.to_qualified_id()); + format!( + "({}{}({}))", + self.module_qualifier(tctx, func_env.module_env.get_id()), + func_env.get_name_str(), + self.sym(*sym) + ) + }, + }; + + let spec_kind = match spec.kind { + AccessSpecifierKind::Reads => "reads", + AccessSpecifierKind::Writes => "writes", + AccessSpecifierKind::LegacyAcquires => "acquires", + }; + + let spec_key = if spec.negated { + format!("!{}", spec_kind) + } else { + spec_kind.to_string() + }; + + acc_spec_map + .get_mut(&spec_key) + .expect("spec kind key expected") + .insert(format!("{}{}", resource, address)); + } + + // print the spec kind and associated resources one by one + for (spec_kind, resources) in &acc_spec_map { + if !resources.is_empty() { emitln!(self.writer); - if spec.negated { - emit!(self.writer, "!") - } - match &spec.kind { - AccessSpecifierKind::Reads => emit!(self.writer, "reads "), - AccessSpecifierKind::Writes => emit!(self.writer, "writes "), - AccessSpecifierKind::LegacyAcquires => emit!(self.writer, "acquires "), - } - match &spec.resource.1 { - ResourceSpecifier::Any => emit!(self.writer, "*"), - ResourceSpecifier::DeclaredAtAddress(addr) => { - emit!( - self.writer, - "0x{}::*", - addr.expect_numerical().short_str_lossless() - ) - }, - ResourceSpecifier::DeclaredInModule(mid) => { - emit!( - self.writer, - "{}::*", - self.env().get_module(*mid).get_full_name_str() - ) - }, - ResourceSpecifier::Resource(sid) => { - emit!(self.writer, "{}", sid.to_type().display(tctx)) - }, - } - if !matches!(spec.address.1, AddressSpecifier::Any) { - emit!(self.writer, "("); - match &spec.address.1 { - AddressSpecifier::Any => { - // should be also valid, but not reached: - // emit!(self.writer, "*") - unreachable!() - }, - AddressSpecifier::Address(addr) => { - emit!( - self.writer, - "0x{}", - addr.expect_numerical().short_str_lossless() - ) - }, - AddressSpecifier::Parameter(sym) => { - emit!(self.writer, "{}", self.sym(*sym)) - }, - AddressSpecifier::Call(fun, sym) => emit!( - self.writer, - "{}({})", - self.env() - .get_function(fun.to_qualified_id()) - .get_full_name_str(), - self.sym(*sym) - ), - } - emit!(self.writer, ")") - } + self.print_list( + &format!("{} ", spec_kind), + ", ", + "", + resources.iter(), + |resource| emit!(self.writer, "{}", resource), + ); } - self.writer.unindent(); - emitln!(self.writer) } + self.writer.unindent(); + emitln!(self.writer) } pub fn print_value(&self, value: &Value, ty: Option<&Type>) { match value { - Value::Address(address) => emit!(self.writer, "{}", self.env().display(address)), + Value::Address(address) => emit!(self.writer, "@{}", self.env().display(address)), Value::Number(int) => { emit!(self.writer, "{}", int); if let Some(Type::Primitive(prim)) = ty { @@ -248,6 +311,12 @@ impl<'a> Sourcifier<'a> { PrimitiveType::U64 => "", PrimitiveType::U128 => "u128", PrimitiveType::U256 => "u256", + PrimitiveType::I8 => "i8", + PrimitiveType::I16 => "i16", + PrimitiveType::I32 => "i32", + PrimitiveType::I64 => "i64", + PrimitiveType::I128 => "i128", + PrimitiveType::I256 => "i256", _ => "", }) } @@ -282,7 +351,7 @@ impl<'a> Sourcifier<'a> { }, Value::AddressArray(addresses) => { self.print_list("vector[", ", ", "]", addresses.iter(), |address| { - emit!(self.writer, "{}", self.env().display(address)) + emit!(self.writer, "@{}", self.env().display(address)) }) }, } @@ -356,10 +425,55 @@ impl<'a> Sourcifier<'a> { } fn field(&self, tctx: &TypeDisplayContext, field: &FieldEnv) -> String { + let mut tctx = tctx.clone(); + // If the field is a struct defined in a different module with name identical to any struct in the current module, e.g., + // ```Move + // use 0x2::X; + // struct X { + // f: X::S, + // } + // ``` + // + // and + // + // ```Move + // use 0x2::X; + // struct Y { + // f: X::S, + // } + // enum X { + // S, + // } + // ``` + // we will force to print out the module address (i.e., `f: X::S` -> `f: 0x2::X::S`). + if let Type::Struct(field_mid, _, _) = field.get_type() { + let sym_pool = self.env().symbol_pool(); + // Get the module containing the parent struct of the field + let parent_module = &field.struct_env.module_env; + let parent_mid = parent_module.get_id(); + // Field type is defined in a different module + if parent_mid != field_mid { + // Get the module name defining the field struct + let field_mname = self + .env() + .get_module(field_mid) + .get_name() + .display(self.env()) + .to_string(); + + // If the parent module has any structure with the same name as `field_mname` + if parent_module + .get_structs() + .any(|s| s.get_name().display(sym_pool).to_string() == field_mname) + { + tctx.display_module_addr = true; + } + } + } format!( "{}: {}", self.sym(field.get_name()), - field.get_type().display(tctx) + field.get_type().display(&tctx) ) } @@ -392,7 +506,18 @@ impl<'a> Sourcifier<'a> { } fn sym(&self, sym: Symbol) -> String { - sym.display(self.env().symbol_pool()).to_string() + let sym_str = if let Some(alias) = self.sym_alias_map.borrow().get(&sym) { + alias.clone() + } else { + sym.display(self.env().symbol_pool()).to_string() + }; + + // Replace the `invalid` characters so that the generated code is recompilable. + if self.amend { + sym_str.replace('$', "_") + } else { + sym_str + } } fn print_block(&self, content_printer: impl Fn()) { @@ -423,6 +548,108 @@ impl<'a> Sourcifier<'a> { } emit!(self.writer, end) } + + fn module_qualifier(&self, tctx: &TypeDisplayContext, mid: ModuleId) -> String { + let module_env = self.env().get_module(mid); + let module_name = module_env.get_name(); + if tctx.is_current_module(module_name) { + // Current module, no qualification needed + "".to_string() + } else { + format!( + "{}::", + tctx.get_alias(module_name) + .map(|sym| self.sym(sym)) + .unwrap_or_else(|| { + if tctx.used_modules.contains(&mid) { + self.sym(module_env.get_name().name()) + } else { + module_env.get_full_name_str() + } + }) + ) + } + } + + /// Creates a new name which has no clashes with symbols in the global environment. + fn new_global_unique_name(env: &GlobalEnv, base_name: &str) -> String { + let spool = env.symbol_pool(); + // Name is available + if !spool.name_already_taken(base_name) { + return base_name.to_string(); + } + // Name is taken, try to append a postfix + for i in 0..256 { + let new_name = &format!("{}_{}", base_name, i); + if !spool.name_already_taken(new_name) { + return new_name.to_string(); + } + } + // Give up after too many attempts + panic!("too many fruitless attempts to generate unique name") + } + + fn is_temp_var(s: &str) -> bool { + if let Some(rest) = s.strip_prefix("_t") { + rest.chars().all(|c| c.is_ascii_digit()) + } else { + false + } + } + + /// our assignment optimization at the AST level removes many dummy temp vars. As such, their names no longer start from `_t0` + /// this function amends names of temp vars in the function body to start from `_v0` + fn set_temp_var_alias(&self, def: &ExpData) { + if self.amend { + // Collect all used local variables in the function body + // Why use vec instead of set: we need to keep the order of the symbols as they appear in the function body + let mut used_vars = Vec::new(); + let mut visitor = |exp: &ExpData| { + match exp { + ExpData::Block(_, pat, _, _) => { + for (_, sym) in pat.vars().iter() { + if !used_vars.contains(sym) { + used_vars.push(*sym); + } + } + }, + ExpData::LocalVar(_, sym) => { + if !used_vars.contains(sym) { + used_vars.push(*sym); + } + }, + ExpData::Assign(_, pat, _) => { + for (_, sym) in pat.vars().iter() { + if !used_vars.contains(sym) { + used_vars.push(*sym); + } + } + }, + _ => {}, + } + true + }; + def.visit_pre_order(&mut visitor); + + // set up alias for each temp var + for used_var in used_vars { + let var_name = used_var.display(self.env().symbol_pool()).to_string(); + if Self::is_temp_var(&var_name) { + let new_name = Self::new_global_unique_name( + self.env(), + format!("_v{}", self.sym_alias_map.borrow().len()).as_str(), + ); + self.sym_alias_map + .borrow_mut() + .insert(used_var, new_name.clone()); + } + } + } + } + + fn clear_temp_var_alias(&self) { + self.sym_alias_map.borrow_mut().clear(); + } } // @@ -438,6 +665,7 @@ pub struct ExpSourcifier<'a> { loop_labels: BTreeMap, // A mapping from node-id if `break` or `continue` to associated label, if one is needed. cont_labels: BTreeMap, + amend: bool, } /// Helper type to split blocks and sequences into vector of items @@ -475,12 +703,17 @@ mod Prio { impl<'a> ExpSourcifier<'a> { /// Creates a sourcifier for the given expression in the context of the function - pub fn for_fun(parent: &'a Sourcifier<'a>, fun_env: &'a FunctionEnv, exp: &Exp) -> Self { - let type_display_context = fun_env.get_type_display_ctx(); + pub fn for_fun( + parent: &'a Sourcifier<'a>, + fun_env: &'a FunctionEnv, + tctx: TypeDisplayContext<'a>, + exp: &Exp, + amend: bool, + ) -> Self { let temp_names = (0..fun_env.get_parameter_count()) .map(|i| (i, fun_env.get_local_name(i))) .collect(); - Self::new(parent, type_display_context, temp_names, exp) + Self::new(parent, tctx, temp_names, exp, amend) } fn new( @@ -488,6 +721,7 @@ impl<'a> ExpSourcifier<'a> { type_display_context: TypeDisplayContext<'a>, temp_names: BTreeMap, for_exp: &Exp, + amend: bool, ) -> Self { let (_, cont_to_loop) = for_exp.compute_loop_bindings(); let mut loop_labels = BTreeMap::new(); @@ -518,6 +752,7 @@ impl<'a> ExpSourcifier<'a> { temp_names, loop_labels, cont_labels, + amend, } } @@ -547,7 +782,7 @@ impl<'a> ExpSourcifier<'a> { emit!(self.wr(), "{} ", capture_kind); }; emit!(self.wr(), "|"); - self.print_pat(pat); + self.print_pat(pat, true, false); emit!(self.wr(), "| "); self.print_exp(Prio::General, true, body); if let Some(spec) = spec_opt { @@ -592,12 +827,15 @@ impl<'a> ExpSourcifier<'a> { } LetOrStm::Let(pat, binding) => { emit!(self.wr(), "let "); - self.print_pat(pat); + self.print_pat(pat, false, !binding.as_ref().is_some_and(|exp| matches!(exp.as_ref(), ExpData::Call(_, Operation::Closure(..), _)))); if let Some(exp) = binding { emit!(self.wr(), " = "); - self.print_exp(Prio::General, is_result, exp); + self.print_exp(Prio::General, matches!(exp.as_ref(), Block(..) | Sequence(..)), exp); } if last { + if !is_result { + emit!(self.wr(), ";") + } emitln!(self.wr()) } } @@ -608,6 +846,10 @@ impl<'a> ExpSourcifier<'a> { } }, IfElse(_, cond, if_exp, else_exp) => { + // Special case: the if-else can be printed as an `assert!` + if self.print_assert(context_prio, cond, if_exp, else_exp) { + return; + } self.parenthesize(context_prio, Prio::General, || { emit!(self.wr(), "if ("); self.print_exp(Prio::General, false, cond); @@ -635,7 +877,7 @@ impl<'a> ExpSourcifier<'a> { emitln!(self.wr(), ") {"); self.wr().indent(); for arm in arms { - self.print_pat(&arm.pattern); + self.print_pat(&arm.pattern, false, true); if let Some(exp) = &arm.condition { emit!(self.wr(), " if "); self.print_exp(Prio::General, false, exp); @@ -747,16 +989,23 @@ impl<'a> ExpSourcifier<'a> { self.print_exp(Prio::General, false, val) }), Assign(_, pat, val) => self.parenthesize(context_prio, Prio::General, || { - self.print_pat(pat); + self.print_pat(pat, false, true); emit!(self.wr(), " = "); - self.print_exp(Prio::General, false, val) + self.print_exp( + Prio::General, + matches!(exp.as_ref(), Block(..) | Sequence(..)), + val, + ); }), Mutate(_, lhs, rhs) => self.parenthesize(context_prio, Prio::General, || { - if matches!( - lhs.as_ref(), - Call(_, Operation::Select(..) | Operation::SelectVariants(..), _) - ) { - // No deref required + if let Call(inner_id, Operation::Select(..) | Operation::SelectVariants(..), _) = + lhs.as_ref() + { + let result_ty = self.env().get_node_type(*inner_id); + // While this looks weird, it is a must due to how `WriteRef` is translated into AST + if result_ty.is_mutable_reference() { + emit!(self.wr(), "*"); + } self.print_exp(Prio::General, false, lhs); emit!(self.wr(), " = "); self.print_exp(Prio::General, false, rhs) @@ -785,6 +1034,13 @@ impl<'a> ExpSourcifier<'a> { }) } + fn print_rev_exp_list(&self, open: &str, close: &str, exps: &[Exp]) { + self.parent + .print_list(open, ", ", close, exps.iter().rev(), |e| { + self.print_exp(Prio::General, false, e) + }) + } + fn print_call(&self, context_prio: Priority, id: NodeId, oper: &Operation, args: &[Exp]) { match oper { Operation::MoveFunction(mid, fid) => { @@ -793,11 +1049,16 @@ impl<'a> ExpSourcifier<'a> { emit!( self.wr(), "{}{}", - self.module_qualifier(*mid), - self.sym(fun_env.get_name()) + self.parent + .module_qualifier(&self.type_display_context, *mid), + Sourcifier::amend_fun_name( + self.env(), + self.sym(fun_env.get_name()), + self.amend + ) ); self.print_node_inst(id); - self.print_exp_list("(", ")", args) + self.print_exp_list("(", ")", args); }) }, Operation::Closure(mid, fid, mask) => { @@ -826,12 +1087,14 @@ impl<'a> ExpSourcifier<'a> { emit!(self.wr(), "<>"); return; }; - let call_exp = ExpData::Call( - self.env().new_node(loc.clone(), res_ty.as_ref().clone()), - Operation::MoveFunction(*mid, *fid), - all_args, - ) - .into_exp(); + let new_node_id = self.env().new_node(loc.clone(), res_ty.as_ref().clone()); + let call_exp = + ExpData::Call(new_node_id, Operation::MoveFunction(*mid, *fid), all_args) + .into_exp(); + // Need to migrate the type instantiations to move function call. + if let Some(inst) = self.env().get_node_instantiation_opt(id) { + self.env().set_node_instantiation(new_node_id, inst); + } let lambda_pat = if lambda_params.len() != 1 { Pattern::Tuple( self.env() @@ -865,31 +1128,42 @@ impl<'a> ExpSourcifier<'a> { }, Operation::Tuple => self.print_exp_list("(", ")", args), Operation::Select(mid, sid, fid) => { - self.parenthesize(context_prio, Prio::Postfix, || { - let struct_env = self.env().get_module(*mid).into_struct(*sid); - let field_env = struct_env.get_field(*fid); - let result_ty = self.env().get_node_type(id); + let struct_env = self.env().get_module(*mid).into_struct(*sid); + let field_env = struct_env.get_field(*fid); + let result_ty = self.env().get_node_type(id); + // This is to accommodate nested `&` and `&mut` + let given_prio = if result_ty.is_reference() { + Prio::Prefix + } else { + Prio::Postfix + }; + self.parenthesize(context_prio, given_prio, || { if result_ty.is_immutable_reference() { - emit!(self.wr(), "&") + emit!(self.wr(), "&"); } else if result_ty.is_mutable_reference() { - emit!(self.wr(), "&mut ") + emit!(self.wr(), "&mut "); } self.print_exp(Prio::Postfix, false, &args[0]); emit!(self.wr(), ".{}", self.sym(field_env.get_name())) }) }, Operation::SelectVariants(mid, sid, fids) => { - self.parenthesize(context_prio, Prio::Postfix, || { - let struct_env = self.env().get_module(*mid).into_struct(*sid); - // All field names are the same, so we can choose one representative - // on source level. - let fid = fids[0]; - let field_env = struct_env.get_field(fid); - let result_ty = self.env().get_node_type(id); + let struct_env = self.env().get_module(*mid).into_struct(*sid); + // All field names are the same, so we can choose one representative + // on source level. + let fid = fids[0]; + let field_env = struct_env.get_field(fid); + let result_ty = self.env().get_node_type(id); + let given_prio = if result_ty.is_reference() { + Prio::Prefix + } else { + Prio::Postfix + }; + self.parenthesize(context_prio, given_prio, || { if result_ty.is_immutable_reference() { - emit!(self.wr(), "&") + emit!(self.wr(), "&"); } else if result_ty.is_mutable_reference() { - emit!(self.wr(), "&mut ") + emit!(self.wr(), "&mut "); } self.print_exp(Prio::Postfix, false, &args[0]); emit!(self.wr(), ".{}", self.sym(field_env.get_name())) @@ -934,16 +1208,25 @@ impl<'a> ExpSourcifier<'a> { emit!(self.wr(), "abort "); self.print_exp(Prio::General, false, &args[0]) }), - Operation::Freeze(_) => { - emit!(self.wr(), "/*freeze*/"); - self.print_exp(context_prio, false, &args[0]) + Operation::Freeze(explicit) => { + if *explicit { + self.print_exp_list("freeze(", ")", &args[0..1]); + } else { + emit!(self.wr(), "/*freeze*/"); + self.print_exp(context_prio, false, &args[0]); + } }, Operation::Not => self.parenthesize(context_prio, Prio::Prefix, || { emit!(self.wr(), "!"); self.print_exp(Prio::Prefix, false, &args[0]) }), + Operation::Negate => self.parenthesize(context_prio, Prio::Prefix, || { + emit!(self.wr(), "-"); + self.print_exp(Prio::Prefix, false, &args[0]) + }), Operation::Cast => self.parenthesize(context_prio, Prio::General, || { - self.print_exp(Prio::General, false, &args[0]); + // We take `as` as a postfix operator, to enforce a parenthesis around LHS as needed + self.print_exp(Prio::Postfix, false, &args[0]); let ty = self.env().get_node_type(id); emit!(self.wr(), " as {}", self.ty(&ty)) }), @@ -964,7 +1247,7 @@ impl<'a> ExpSourcifier<'a> { Operation::MoveTo => self.parenthesize(context_prio, Prio::Postfix, || { emit!(self.wr(), "move_to"); self.print_node_inst(id); - self.print_exp_list("(", ")", args) + self.print_rev_exp_list("(", ")", args) }), Operation::MoveFrom => self.parenthesize(context_prio, Prio::Postfix, || { emit!(self.wr(), "move_from"); @@ -977,7 +1260,13 @@ impl<'a> ExpSourcifier<'a> { } else { emit!(self.wr(), "&") } - self.print_exp(Prio::Prefix, false, &args[0]) + let inner_ty = self.env().get_node_type(args[0].node_id()); + let context_prio = if inner_ty.is_reference() { + Prio::Postfix + } else { + Prio::Prefix + }; + self.print_exp(context_prio, false, &args[0]) }), Operation::Deref => self.parenthesize(context_prio, Prio::Prefix, || { emit!(self.wr(), "*"); @@ -1038,6 +1327,31 @@ impl<'a> ExpSourcifier<'a> { } } + fn print_assert(&self, context_prio: Priority, cond_: &Exp, then_: &Exp, else_: &Exp) -> bool { + // Match the pattern `if (!cond) abort(code) else ()` + let inner_cond = match cond_.as_ref() { + ExpData::Call(_, Operation::Not, args) if args.len() == 1 => args[0].clone(), + _ => return false, + }; + let abort_code = match then_.as_ref() { + ExpData::Call(_, Operation::Abort, args) if args.len() == 1 => args[0].clone(), + _ => return false, + }; + if !else_.is_unit_exp() { + return false; + } + + // All matched, print as `assert!(cond, code)` + self.parenthesize(context_prio, Prio::General, || { + emit!(self.wr(), "assert!("); + self.print_exp(Prio::General, false, &inner_cond); + emit!(self.wr(), ", "); + self.print_exp(Prio::General, false, &abort_code); + emit!(self.wr(), ")"); + }); + true + } + fn print_constructor( &self, qid: &QualifiedInstId, @@ -1049,7 +1363,8 @@ impl<'a> ExpSourcifier<'a> { emit!( self.wr(), "{}{}", - self.module_qualifier(struct_env.module_env.get_id()), + self.parent + .module_qualifier(&self.type_display_context, struct_env.module_env.get_id()), self.sym(struct_env.get_name()) ); if let Some(v) = variant { @@ -1066,7 +1381,7 @@ impl<'a> ExpSourcifier<'a> { }; self.parent.print_list( open, - ",", + ", ", close, struct_env .get_fields_optional_variant(*variant) @@ -1120,15 +1435,33 @@ impl<'a> ExpSourcifier<'a> { } } - fn print_pat(&self, pat: &Pattern) { + fn print_pat(&self, pat: &Pattern, no_parenthesize: bool, no_type: bool) { match pat { - Pattern::Var(_, name) => emit!(self.wr(), "{}", self.sym(*name)), + Pattern::Var(node_id, name) => { + emit!(self.wr(), "{}", self.sym(*name)); + let ty = self.env().get_node_type(*node_id); + if let Type::Fun(_, _, ability) = ty { + if !ability.is_empty() && !no_type { + emit!(self.wr(), ": {}", self.ty(&ty)); + } + } + }, Pattern::Wildcard(_) => emit!(self.wr(), "_"), - Pattern::Tuple(_, elems) => self - .parent - .print_list("(", ",", ")", elems.iter(), |p| self.print_pat(p)), + Pattern::Tuple(_, elems) => { + let (start, end) = if !no_parenthesize { + ("(", ")") + } else { + // When printing the args of a function value, we cannot parenthesize the tuple + ("", "") + }; + self.parent.print_list(start, ",", end, elems.iter(), |p| { + self.print_pat(p, no_parenthesize, no_type) + }) + }, Pattern::Struct(_, qid, variant, elems) => { - self.print_constructor(qid, variant, elems.iter(), |p| self.print_pat(p)) + self.print_constructor(qid, variant, elems.iter(), |p| { + self.print_pat(p, no_parenthesize, no_type) + }) }, Pattern::Error(_) => emit!(self.wr(), "*error*"), } @@ -1153,23 +1486,6 @@ impl<'a> ExpSourcifier<'a> { } } - fn module_qualifier(&self, mid: ModuleId) -> String { - let module_env = self.env().get_module(mid); - if self.type_display_context.module_name.as_ref() == Some(module_env.get_name()) { - // Current module, no qualification needed - "".to_string() - } else { - format!( - "{}::", - if self.type_display_context.used_modules.contains(&mid) { - self.sym(module_env.get_name().name()) - } else { - module_env.get_full_name_str() - } - ) - } - } - fn ty(&self, ty: &Type) -> String { ty.display(&self.type_display_context).to_string() } diff --git a/third_party/move/move-model/src/spec_translator.rs b/third_party/move/move-model/src/spec_translator.rs index 43c119d07b0..f83a21fd711 100644 --- a/third_party/move/move-model/src/spec_translator.rs +++ b/third_party/move/move-model/src/spec_translator.rs @@ -131,7 +131,7 @@ impl TranslatedSpec { pub fn pre_conditions<'a, T: ExpGenerator<'a>>( &self, _builder: &T, - ) -> impl Iterator + '_ { + ) -> impl Iterator + '_ + use<'_, T> { self.pre.iter().cloned() } diff --git a/third_party/move/move-model/src/symbol.rs b/third_party/move/move-model/src/symbol.rs index e99885b6f9f..cd62df29810 100644 --- a/third_party/move/move-model/src/symbol.rs +++ b/third_party/move/move-model/src/symbol.rs @@ -66,6 +66,12 @@ impl SymbolPool { } } + /// Check if a name has been taken by a symbol in this pool. + pub fn name_already_taken(&self, s: &str) -> bool { + let pool = self.inner.borrow(); + pool.lookup.contains_key(&Rc::new(s.to_string())) + } + /// Looks up a symbol by its string representation. If a symbol with this representation /// already exists, it will be returned, otherwise a new one will be created in the /// pool. The implementation uses internally a RefCell for storing symbols, so the pool diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index eba11991548..86a10ea3abd 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -5,7 +5,7 @@ //! Contains types and related functions. use crate::{ - ast::{ModuleName, QualifiedSymbol}, + ast::{Address, ModuleName, QualifiedSymbol}, builder::{ith_str, pluralize}, model::{ FunId, GlobalEnv, Loc, ModuleId, QualifiedId, QualifiedInstId, StructEnv, StructId, @@ -14,24 +14,21 @@ use crate::{ symbol::Symbol, }; use itertools::Itertools; -#[allow(deprecated)] -use move_binary_format::normalized::Type as MType; use move_binary_format::{ access::ModuleAccess, file_format::SignatureToken, views::StructHandleView, CompiledModule, }; use move_core_types::{ ability::{Ability, AbilitySet}, - language_storage::{FunctionTag, StructTag, TypeTag}, - u256::U256, + int256::{I256, U256}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, TypeTag}, }; use num::BigInt; use num_traits::identities::Zero; use std::{ cmp::Ordering, collections::{btree_map::Entry, BTreeMap, BTreeSet}, - fmt, - fmt::{Debug, Formatter}, - iter, + fmt::{self, Debug, Formatter}, + iter, str, }; /// Represents a type. @@ -99,6 +96,12 @@ pub enum PrimitiveType { U64, U128, U256, + I8, + I16, + I32, + I64, + I128, + I256, Address, Signer, // Types only appearing in specifications @@ -823,39 +826,31 @@ impl PrimitiveType { pub fn is_spec(&self) -> bool { use PrimitiveType::*; match self { - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer => false, + Bool | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Address | Signer => false, Num | Range | EventStore => true, } } - /// Attempt to convert this type into a normalized::Type - #[allow(deprecated)] - pub fn into_normalized_type(self) -> Option { - use PrimitiveType::*; - Some(match self { - Bool => MType::Bool, - U8 => MType::U8, - U16 => MType::U16, - U32 => MType::U32, - U64 => MType::U64, - U128 => MType::U128, - U256 => MType::U256, - Address => MType::Address, - Signer => MType::Signer, - Num | Range | EventStore => return None, - }) - } - /// Infer a type from a value. Returns the set of int types which can fit the /// value. pub fn possible_int_types(value: BigInt) -> Vec { Self::all_int_types() .into_iter() - .filter(|t| value <= Self::get_max_value(t).expect("type has max")) + .filter(|t| { + value <= Self::get_max_value(t).expect("type has max") + && value >= Self::get_min_value(t).expect("type has min") + }) .collect() } pub fn all_int_types() -> Vec { + let mut types = Self::all_signed_int_types(); + types.extend(Self::all_unsigned_int_types()); + types + } + + pub fn all_unsigned_int_types() -> Vec { vec![ PrimitiveType::U8, PrimitiveType::U16, @@ -866,6 +861,17 @@ impl PrimitiveType { ] } + pub fn all_signed_int_types() -> Vec { + vec![ + PrimitiveType::I8, + PrimitiveType::I16, + PrimitiveType::I32, + PrimitiveType::I64, + PrimitiveType::I128, + PrimitiveType::I256, + ] + } + /// Gets the maximal value allowed for a numeric type, or none if it is unbounded. pub fn get_max_value(self: &PrimitiveType) -> Option { match self { @@ -874,7 +880,13 @@ impl PrimitiveType { PrimitiveType::U32 => Some(BigInt::from(u32::MAX)), PrimitiveType::U64 => Some(BigInt::from(u64::MAX)), PrimitiveType::U128 => Some(BigInt::from(u128::MAX)), - PrimitiveType::U256 => Some(BigInt::from(&U256::max_value())), + PrimitiveType::U256 => Some(BigInt::from(U256::MAX)), + PrimitiveType::I8 => Some(BigInt::from(i8::MAX)), + PrimitiveType::I16 => Some(BigInt::from(i16::MAX)), + PrimitiveType::I32 => Some(BigInt::from(i32::MAX)), + PrimitiveType::I64 => Some(BigInt::from(i64::MAX)), + PrimitiveType::I128 => Some(BigInt::from(i128::MAX)), + PrimitiveType::I256 => Some(BigInt::from(I256::MAX)), PrimitiveType::Num => None, _ => unreachable!("no num type"), } @@ -889,6 +901,12 @@ impl PrimitiveType { PrimitiveType::U64 => Some(BigInt::zero()), PrimitiveType::U128 => Some(BigInt::zero()), PrimitiveType::U256 => Some(BigInt::zero()), + PrimitiveType::I8 => Some(BigInt::from(i8::MIN)), + PrimitiveType::I16 => Some(BigInt::from(i16::MIN)), + PrimitiveType::I32 => Some(BigInt::from(i32::MIN)), + PrimitiveType::I64 => Some(BigInt::from(i64::MIN)), + PrimitiveType::I128 => Some(BigInt::from(i128::MIN)), + PrimitiveType::I256 => Some(BigInt::from(I256::MIN)), PrimitiveType::Num => None, _ => unreachable!("no num type"), } @@ -903,8 +921,18 @@ impl PrimitiveType { PrimitiveType::U64 => Some(64), PrimitiveType::U128 => Some(128), PrimitiveType::U256 => Some(256), + PrimitiveType::I8 => Some(8), + PrimitiveType::I16 => Some(16), + PrimitiveType::I32 => Some(32), + PrimitiveType::I64 => Some(64), + PrimitiveType::I128 => Some(128), + PrimitiveType::I256 => Some(256), PrimitiveType::Num => None, - _ => unreachable!("no num type"), + PrimitiveType::Bool + | PrimitiveType::Address + | PrimitiveType::Signer + | PrimitiveType::Range + | PrimitiveType::EventStore => unreachable!("no num type"), } } } @@ -1046,14 +1074,29 @@ impl Type { use PrimitiveType::*; use Type::*; match self { - Primitive(p) => matches!(p, U8 | U16 | U32 | U64 | U128 | U256 | Bool | Address), + Primitive(p) => matches!( + p, + U8 | U16 + | U32 + | U64 + | U128 + | U256 + | I8 + | I16 + | I32 + | I64 + | I128 + | I256 + | Bool + | Address + ), Vector(ety) => ety.is_valid_for_constant(), _ => false, } } pub fn describe_valid_for_constant() -> &'static str { - "Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, \ + "Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, `bool`, `address`, \ or `vector<_>` with valid element type." } @@ -1086,6 +1129,89 @@ impl Type { matches!(self, Type::Var(_)) } + /// Returns all internal types contained in this type (including itself), skipping reference types. + pub fn get_all_contained_types_with_skip_reference(&self, env: &GlobalEnv) -> Vec { + match self { + Type::Primitive(_) => vec![self.clone()], + Type::Tuple(ts) => ts + .iter() + .flat_map(|t| t.get_all_contained_types_with_skip_reference(env)) + .collect(), + Type::Vector(et) => { + let mut types = et.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::Struct(_, _, ts) => { + let struct_env = self.get_struct(env).unwrap().0; + let mut new_types = ts + .iter() + .zip(struct_env.data.type_params.iter()) + .filter(|(_, param)| !param.1.is_phantom) + .flat_map(|(t, _)| t.get_all_contained_types_with_skip_reference(env)) + .collect_vec(); + new_types.push(self.clone()); + if struct_env.has_variants() { + for variant in struct_env.get_variants() { + for field in struct_env.get_fields_of_variant(variant) { + new_types.extend( + field + .get_type() + .instantiate(ts) + .get_all_contained_types_with_skip_reference(env), + ); + } + } + } else { + for field in struct_env.get_fields() { + new_types.extend( + field + .get_type() + .instantiate(ts) + .get_all_contained_types_with_skip_reference(env), + ); + } + } + new_types + }, + Type::Fun(arg, result, _) => { + let mut types = arg.get_all_contained_types_with_skip_reference(env); + types.extend(result.get_all_contained_types_with_skip_reference(env)); + types + }, + Type::Reference(_, bt) => { + let mut types = bt.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::TypeDomain(bt) => { + let mut types = bt.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::ResourceDomain(_, _, Some(bt)) => { + let mut types = bt + .iter() + .flat_map(|t| t.get_all_contained_types_with_skip_reference(env)) + .collect_vec(); + types.push(self.clone()); + types + }, + Type::ResourceDomain(_, _, None) => { + vec![self.clone()] + }, + Type::Var(..) => { + vec![self.clone()] + }, + Type::Error => { + vec![self.clone()] + }, + Type::TypeParameter(..) => { + vec![self.clone()] + }, + } + } + /// Returns true if this is any number type. pub fn is_number(&self) -> bool { if let Type::Primitive(p) = self { @@ -1095,6 +1221,12 @@ impl Type { | PrimitiveType::U64 | PrimitiveType::U128 | PrimitiveType::U256 + | PrimitiveType::I8 + | PrimitiveType::I16 + | PrimitiveType::I32 + | PrimitiveType::I64 + | PrimitiveType::I128 + | PrimitiveType::I256 | PrimitiveType::Num = p { return true; @@ -1103,6 +1235,36 @@ impl Type { false } + /// Returns true if this is signed int type. + pub fn is_signed_int(&self) -> bool { + matches!( + self, + Type::Primitive( + PrimitiveType::I8 + | PrimitiveType::I16 + | PrimitiveType::I32 + | PrimitiveType::I64 + | PrimitiveType::I128 + | PrimitiveType::I256 + ) + ) + } + + /// Returns true if this is unsigned int type. + pub fn is_unsigned_int(&self) -> bool { + matches!( + self, + Type::Primitive( + PrimitiveType::U8 + | PrimitiveType::U16 + | PrimitiveType::U32 + | PrimitiveType::U64 + | PrimitiveType::U128 + | PrimitiveType::U256 + ) + ) + } + /// Returns compatible number type if `self` and `ty` are compatible number types. pub fn is_compatible_num_type(&self, ty: &Type) -> Option { let skip_reference_self = self.skip_reference(); @@ -1418,64 +1580,23 @@ impl Type { } } - /// Attempt to convert this type into a normalized::Type - #[allow(deprecated)] - pub fn into_struct_type(self, env: &GlobalEnv) -> Option { - use Type::*; - match self { - Struct(mid, sid, ts) => env.get_struct_type(mid, sid, &ts), - _ => None, - } - } - - /// Attempt to convert this type into a normalized::Type - #[allow(deprecated)] - pub fn into_normalized_type(self, env: &GlobalEnv) -> Option { - use Type::*; - match self { - Primitive(p) => Some(p.into_normalized_type().expect("Invariant violation: unexpected spec primitive")), - Struct(mid, sid, ts) => - env.get_struct_type(mid, sid, &ts), - Vector(et) => Some(MType::Vector( - Box::new(et.into_normalized_type(env) - .expect("Invariant violation: vector type argument contains incomplete, tuple, or spec type")) - )), - Reference(r, t) => - match r { - ReferenceKind::Mutable => { - Some(MType::MutableReference(Box::new(t.into_normalized_type(env).expect("Invariant violation: reference type contains incomplete, tuple, or spec type")))) - } - ReferenceKind::Immutable => { - Some(MType::Reference(Box::new(t.into_normalized_type(env).expect("Invariant violation: reference type contains incomplete, tuple, or spec type")))) - } - }, - TypeParameter(idx) => Some(MType::TypeParameter(idx)), - Tuple(..) | Error | Fun(..) | TypeDomain(..) | ResourceDomain(..) | Var(..) => - None - } - } - - /// Attempt to convert this type into a language_storage::StructTag - pub fn into_struct_tag(self, env: &GlobalEnv) -> Option { - self.into_struct_type(env)?.into_struct_tag() - } - - /// Attempt to convert this type into a language_storage::TypeTag - pub fn into_type_tag(self, env: &GlobalEnv) -> Option { - self.into_normalized_type(env)?.into_type_tag() - } - /// Create a `Type` from `t` pub fn from_type_tag(t: &TypeTag, env: &GlobalEnv) -> Self { use Type::*; match t { TypeTag::Bool => Primitive(PrimitiveType::Bool), TypeTag::U8 => Primitive(PrimitiveType::U8), - TypeTag::U16 => Primitive(PrimitiveType::U8), - TypeTag::U32 => Primitive(PrimitiveType::U8), + TypeTag::U16 => Primitive(PrimitiveType::U16), + TypeTag::U32 => Primitive(PrimitiveType::U32), TypeTag::U64 => Primitive(PrimitiveType::U64), TypeTag::U128 => Primitive(PrimitiveType::U128), - TypeTag::U256 => Primitive(PrimitiveType::U8), + TypeTag::U256 => Primitive(PrimitiveType::U256), + TypeTag::I8 => Primitive(PrimitiveType::I8), + TypeTag::I16 => Primitive(PrimitiveType::I16), + TypeTag::I32 => Primitive(PrimitiveType::I32), + TypeTag::I64 => Primitive(PrimitiveType::I64), + TypeTag::I128 => Primitive(PrimitiveType::I128), + TypeTag::I256 => Primitive(PrimitiveType::I256), TypeTag::Address => Primitive(PrimitiveType::Address), TypeTag::Signer => Primitive(PrimitiveType::Signer), TypeTag::Struct(s) => { @@ -1496,8 +1617,22 @@ impl Type { results, abilities, } = fun.as_ref(); - let from_vec = |ts: &[TypeTag]| { - Type::tuple(ts.iter().map(|t| Type::from_type_tag(t, env)).collect_vec()) + let from_vec = |ts: &[FunctionParamOrReturnTag]| { + Type::tuple( + ts.iter() + .map(|t| match t { + FunctionParamOrReturnTag::Reference(t) => Reference( + ReferenceKind::Immutable, + Box::new(Type::from_type_tag(t, env)), + ), + FunctionParamOrReturnTag::MutableReference(t) => Reference( + ReferenceKind::Mutable, + Box::new(Type::from_type_tag(t, env)), + ), + FunctionParamOrReturnTag::Value(t) => Type::from_type_tag(t, env), + }) + .collect_vec(), + ) }; Fun( Box::new(from_vec(args)), @@ -1531,6 +1666,12 @@ impl Type { SignatureToken::U64 => Type::Primitive(PrimitiveType::U64), SignatureToken::U128 => Type::Primitive(PrimitiveType::U128), SignatureToken::U256 => Type::Primitive(PrimitiveType::U256), + SignatureToken::I8 => Type::Primitive(PrimitiveType::I8), + SignatureToken::I16 => Type::Primitive(PrimitiveType::I16), + SignatureToken::I32 => Type::Primitive(PrimitiveType::I32), + SignatureToken::I64 => Type::Primitive(PrimitiveType::I64), + SignatureToken::I128 => Type::Primitive(PrimitiveType::I128), + SignatureToken::I256 => Type::Primitive(PrimitiveType::I256), SignatureToken::Address => Type::Primitive(PrimitiveType::Address), SignatureToken::Signer => Type::Primitive(PrimitiveType::Signer), SignatureToken::Reference(t) => Type::Reference( @@ -1810,7 +1951,7 @@ pub trait UnificationContext: AbilityContext { ) -> Option; /// Returns a type display context. - fn type_display_context(&self) -> TypeDisplayContext; + fn type_display_context(&self) -> TypeDisplayContext<'_>; } /// Information returned about an instantiated function @@ -1867,7 +2008,7 @@ impl UnificationContext for NoUnificationContext { None } - fn type_display_context(&self) -> TypeDisplayContext { + fn type_display_context(&self) -> TypeDisplayContext<'_> { unimplemented!("NoUnificationContext does not support type display") } } @@ -3455,6 +3596,8 @@ pub struct TypeDisplayContext<'a> { pub used_modules: BTreeSet, /// Whether to use `m::T` for representing types, for stable output in docgen pub use_module_qualification: bool, + /// Whether to display module addresses in types, to accommodate special cases + pub display_module_addr: bool, /// Var types that are recursive and should appear as `..` in display pub recursive_vars: Option>, } @@ -3470,6 +3613,7 @@ impl<'a> TypeDisplayContext<'a> { display_type_vars: false, used_modules: BTreeSet::new(), use_module_qualification: false, + display_module_addr: false, recursive_vars: None, } } @@ -3494,6 +3638,7 @@ impl<'a> TypeDisplayContext<'a> { display_type_vars: false, used_modules: BTreeSet::new(), use_module_qualification: false, + display_module_addr: false, recursive_vars: None, } } @@ -3517,6 +3662,66 @@ impl<'a> TypeDisplayContext<'a> { ..self.clone() } } + + /// Check if the given module has the same address as the current module + pub fn is_current_addr(&self, module_address: &Address) -> bool { + self.module_name + .as_ref() + .is_some_and(|ctx_module| ctx_module.addr() == module_address) + } + + /// Check if the given module has the same string identifier as the current module + pub fn is_current_name(&self, module_name: &str) -> bool { + self.module_name.as_ref().is_some_and(|ctx_module| { + ctx_module + .name() + .display(self.env.symbol_pool()) + .to_string() + == *module_name + }) + } + + /// Check if the given module is the current module + pub fn is_current_module(&self, module_name: &ModuleName) -> bool { + self.module_name.as_ref() == Some(module_name) + } + + /// Check if the given module is used by the current module + pub fn is_imported_module(&self, module_id: &ModuleId) -> bool { + self.used_modules.contains(module_id) || { + // `used_modules` may not have been propagated yet, so let's check `use_decls` as a backup. + let imported_module_env = self.env.get_module(*module_id); + self.module_name.as_ref().is_some_and(|ctx_module| { + self.env.find_module(ctx_module).is_some_and(|m| { + m.get_use_decls() + .iter() + .any(|use_| use_.module_name == *imported_module_env.get_name()) + }) + }) + } + } + + /// Check if the given name clashes with a type parameter + pub fn clash_with_ty_params(&self, name: Symbol) -> bool { + self.type_param_names + .as_ref() + .map(|tparams| tparams.contains(&name)) + .unwrap_or(false) + } + + /// Get an optional alias for the given module + pub fn get_alias(&self, module_name: &ModuleName) -> Option { + self.module_name + .as_ref() + .and_then(|ctx_module| self.env.find_module(ctx_module)) + .and_then(|module| { + module + .get_use_decls() + .iter() + .find(|use_| use_.module_name == *module_name) + .and_then(|use_| use_.alias) + }) + } } /// Helper for type displays. @@ -3570,7 +3775,14 @@ impl fmt::Display for TypeDisplay<'_> { Fun(a, t, abilities) => { f.write_str("|")?; if !a.is_unit() { - write!(f, "{}", a.display(self.context))?; + let mut arg_str = a.display(self.context).to_string(); + // Function value args cannot be displayed as a tuple + arg_str = arg_str + .strip_prefix('(') + .and_then(|s| s.strip_suffix(')')) + .unwrap_or(&arg_str) + .to_string(); + write!(f, "{}", arg_str)?; } f.write_str("|")?; if !t.is_unit() { @@ -3659,42 +3871,69 @@ impl TypeDisplay<'_> { #[allow(clippy::assigning_clones)] fn struct_str(&self, mid: ModuleId, sid: StructId) -> String { let env = self.context.env; - let mut str = if let Some(builder_table) = self.context.builder_struct_table { - let qsym = builder_table.get(&(mid, sid)).expect("type known"); - qsym.display(self.context.env).to_string() - } else { - let struct_env = env.get_module(mid).into_struct(sid); - let module_name = struct_env.module_env.get_name(); - let module_str = if self.context.use_module_qualification - || self.context.used_modules.contains(&mid) - || Some(module_name) == self.context.module_name.as_ref() - { - module_name.display(env).to_string() + // Get the struct ModuleName and struct name + let (ty_available, struct_module_name, struct_symbol) = + if let Some(builder_table) = self.context.builder_struct_table { + let qsym = builder_table.get(&(mid, sid)).expect("type known"); + (false, qsym.module_name.clone(), qsym.symbol) } else { - module_name.display_full(env).to_string() + let module_env = env.get_module(mid); + ( + true, + module_env.get_name().clone(), + module_env.into_struct(sid).get_name(), + ) }; - format!( - "{}::{}", - module_str, - struct_env.get_name().display(env.symbol_pool()) - ) - }; - if !self.context.use_module_qualification { - if let Some(mname) = &self.context.module_name { - let s = format!("{}::", mname.name().display(self.context.env.symbol_pool())); - if let Some(shortcut) = str.strip_prefix(&s) { - if let Some(tparams) = &self.context.type_param_names { - // Avoid name clash with type parameter - if !tparams.contains(&self.context.env.symbol_pool().make(shortcut)) { - str = shortcut.to_owned() - } - } else { - str = shortcut.to_owned(); - } - } + + let struct_module_addr = struct_module_name.addr().expect_numerical(); + let struct_module_idstr = struct_module_name + .name() + .display(env.symbol_pool()) + .to_string(); + let struct_name = struct_symbol.display(env.symbol_pool()).to_string(); + + // If we are not able to get the type info, OR + // the type is not inside or the host module is not imported into the current module, + // let's do pattern matching! + if !ty_available + || (!self.context.is_current_module(&struct_module_name) + && !self.context.is_imported_module(&mid)) + { + let mut result = String::new(); + let show_addr = !self.context.is_current_addr(struct_module_name.addr()); + let show_mod = show_addr + || !self.context.is_current_name(&struct_module_idstr) + || self.context.clash_with_ty_params(struct_symbol) + || self.context.use_module_qualification; + + if show_addr { + result.push_str(&format!("0x{}::", struct_module_addr.short_str_lossless())); + } + if show_mod { + result.push_str(&format!("{}::", struct_module_idstr)); } + result.push_str(&struct_name); + return result; + } + + // If there's a module alias, use it + if let Some(alias) = self.context.get_alias(&struct_module_name) { + return format!("{}::{}", alias.display(env.symbol_pool()), struct_name); + } + + // No alias, but the struct is inside or imported into the current module + let mut result = String::new(); + if self.context.display_module_addr { + result.push_str(&format!("0x{}::", struct_module_addr.short_str_lossless())); + } + if self.context.use_module_qualification + || !self.context.is_current_module(&struct_module_name) + || self.context.clash_with_ty_params(struct_symbol) + { + result.push_str(&format!("{}::", struct_module_idstr)); } - str + result.push_str(&struct_name); + result } } @@ -3709,6 +3948,12 @@ impl fmt::Display for PrimitiveType { U64 => f.write_str("u64"), U128 => f.write_str("u128"), U256 => f.write_str("u256"), + I8 => f.write_str("i8"), + I16 => f.write_str("i16"), + I32 => f.write_str("i32"), + I64 => f.write_str("i64"), + I128 => f.write_str("i128"), + I256 => f.write_str("i256"), Address => f.write_str("address"), Signer => f.write_str("signer"), Range => f.write_str("range"), @@ -3723,7 +3968,7 @@ pub trait AbilityInference: AbilityContext { /// Infers the abilities of the type. The returned boolean indicates whether /// the type is a phantom type parameter, fn infer_abilities(&self, ty: &Type) -> (bool, AbilitySet) { - let res = match ty { + match ty { Type::Primitive(p) => match p { PrimitiveType::Bool | PrimitiveType::U8 @@ -3732,6 +3977,12 @@ pub trait AbilityInference: AbilityContext { | PrimitiveType::U64 | PrimitiveType::U128 | PrimitiveType::U256 + | PrimitiveType::I8 + | PrimitiveType::I16 + | PrimitiveType::I32 + | PrimitiveType::I64 + | PrimitiveType::I128 + | PrimitiveType::I256 | PrimitiveType::Num | PrimitiveType::Range | PrimitiveType::EventStore @@ -3763,8 +4014,7 @@ pub trait AbilityInference: AbilityContext { Type::TypeDomain(_) | Type::ResourceDomain(_, _, _) | Type::Error => { (false, AbilitySet::EMPTY) }, - }; - res + } } fn infer_struct_abilities(&self, qid: QualifiedId, ty_args: &[Type]) -> AbilitySet { diff --git a/third_party/move/move-model/src/well_known.rs b/third_party/move/move-model/src/well_known.rs index 68c67c087dc..c9cc893ee4d 100644 --- a/third_party/move/move-model/src/well_known.rs +++ b/third_party/move/move-model/src/well_known.rs @@ -42,6 +42,8 @@ pub const VECTOR_FUNCS_WITH_BYTECODE_INSTRS: &[&str] = &[ "swap", ]; +pub const CMP_MODULE: &str = "cmp"; + pub const TYPE_NAME_MOVE: &str = "type_info::type_name"; pub const TYPE_NAME_SPEC: &str = "type_info::$type_name"; pub const TYPE_INFO_MOVE: &str = "type_info::type_of"; diff --git a/third_party/move/move-model/tests/testsuite.rs b/third_party/move/move-model/tests/testsuite.rs index 2e087c28808..f009e0cede2 100644 --- a/third_party/move/move-model/tests/testsuite.rs +++ b/third_party/move/move-model/tests/testsuite.rs @@ -41,9 +41,7 @@ fn test_runner(path: &Path, options: ModelBuilderOptions) -> datatest_stable::Re } fn runner(path: &Path) -> datatest_stable::Result<()> { - test_runner(path, ModelBuilderOptions { - ..Default::default() - }) + test_runner(path, ModelBuilderOptions::default()) } datatest_stable::harness!(runner, "tests/sources", r".*\.move$"); diff --git a/third_party/move/move-prover/Cargo.toml b/third_party/move/move-prover/Cargo.toml index 78fab6ba8d6..7f57150a486 100644 --- a/third_party/move/move-prover/Cargo.toml +++ b/third_party/move/move-prover/Cargo.toml @@ -3,7 +3,7 @@ name = "move-prover" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] @@ -25,7 +25,6 @@ move-prover-bytecode-pipeline = { workspace = true } move-stackless-bytecode = { workspace = true } once_cell = { workspace = true } serde = { workspace = true, features = ["derive"] } -simplelog = { workspace = true } toml = { workspace = true } [dev-dependencies] diff --git a/third_party/move/move-prover/boogie-backend/Cargo.toml b/third_party/move/move-prover/boogie-backend/Cargo.toml index 0a309286316..a5a9f530c79 100644 --- a/third_party/move/move-prover/boogie-backend/Cargo.toml +++ b/third_party/move/move-prover/boogie-backend/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Diem Association "] description = "Move prover Boogie backend" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs b/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs index 595229e4366..e118568d531 100644 --- a/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs +++ b/third_party/move/move-prover/boogie-backend/src/boogie_helpers.rs @@ -9,27 +9,32 @@ use crate::{options::BoogieOptions, COMPILED_MODULE_AVAILABLE}; use itertools::Itertools; use move_binary_format::file_format::TypeParameterIndex; -use move_core_types::account_address::AccountAddress; +use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, function::ClosureMask, +}; use move_model::{ ast::{Address, MemoryLabel, TempIndex, Value}, model::{ - FieldEnv, FieldId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, QualifiedInstId, SpecFunId, - StructEnv, StructId, SCRIPT_MODULE_NAME, + FieldEnv, FieldId, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, QualifiedInstId, + SpecFunId, StructEnv, StructId, SCRIPT_MODULE_NAME, }, pragmas::INTRINSIC_TYPE_MAP, symbol::Symbol, - ty::{PrimitiveType, Type}, + ty::{PrimitiveType, ReferenceKind, Type}, }; use move_prover_bytecode_pipeline::number_operation::{ GlobalNumberOperationState, NumOperation::Bitwise, }; use move_stackless_bytecode::{function_target::FunctionTarget, stackless_bytecode::Constant}; use num::BigUint; +use once_cell::sync::Lazy; +use regex::Regex; pub const MAX_MAKE_VEC_ARGS: usize = 4; pub const TABLE_NATIVE_SPEC_ERROR: &str = "Native functions defined in Table cannot be used as specification functions"; const NUM_TYPE_BASE_ERROR: &str = "cannot infer concrete integer type from `num`, consider using a concrete integer type or explicit type cast"; +const BV_TYPE_NOT_ENABLED_ERROR: &str = "signed integer cannot be turned into bit vector"; /// Return boogie name of given module. pub fn boogie_module_name(env: &ModuleEnv<'_>) -> String { @@ -184,6 +189,24 @@ pub fn boogie_function_name(fun_env: &FunctionEnv<'_>, inst: &[Type]) -> String ) } +/// Reverse map mangled function name to source level function name. +pub fn boogie_reverse_function_name(_env: &GlobalEnv, s: &str) -> Option { + // TODO: in order to make this actually reversible, we can't use ${}_{}{} above + // but must use something like ${}${}{}. This requires also changes in the prelude. + static REX: Lazy = + Lazy::new(|| Regex::new(r"^\$([0-9,a-f,A-F]+)_(\w+)_(\w+)").expect("regex compiles")); + let cap = REX.captures(s)?; + let addr = cap.get(1)?; + let module_name = cap.get(2)?; + let fun_name = cap.get(3)?; + Some(format!( + "0x{}::{}::{}", + addr.as_str(), + module_name.as_str(), + fun_name.as_str() + )) +} + /// Return boogie name of given function /// Currently bv_flag is used when generating vector functions pub fn boogie_function_bv_name( @@ -316,7 +339,8 @@ pub fn boogie_type(env: &GlobalEnv, ty: &Type) -> String { use Type::*; match ty { Primitive(p) => match p { - U8 | U16 | U32 | U64 | U128 | U256 | Num | Address => "int".to_string(), + U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 | Num + | Address => "int".to_string(), Signer => "$signer".to_string(), Bool => "bool".to_string(), Range | EventStore => panic!("unexpected type"), @@ -325,12 +349,31 @@ pub fn boogie_type(env: &GlobalEnv, ty: &Type) -> String { Struct(mid, sid, inst) => boogie_struct_name(&env.get_module(*mid).into_struct(*sid), inst), Reference(_, bt) => format!("$Mutation ({})", boogie_type(env, bt)), TypeParameter(idx) => boogie_type_param(env, *idx), - Fun(..) | Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) => { + Fun(param, result, abilities) => fun_type(env, param, result, *abilities), + Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) => { format!("<>", ty) }, } } +fn fun_type(env: &GlobalEnv, params: &Type, results: &Type, _abilities: AbilitySet) -> String { + // Abilities are abstracted out in the prover, but for completeness and future changes, + // we pass them into this function. + let params = params + .clone() + .flatten() + .iter() + .map(|t| boogie_type_suffix(env, t)) + .join("_"); + let results = results + .clone() + .flatten() + .iter() + .map(|t| boogie_type_suffix(env, t)) + .join("_"); + format!("$fun_{}_{}", params, results) +} + /// Return boogie type for a local with given signature token. /// TODO(tengzhang): combine with boogie_type later pub fn boogie_bv_type(env: &GlobalEnv, ty: &Type) -> String { @@ -344,13 +387,16 @@ pub fn boogie_bv_type(env: &GlobalEnv, ty: &Type) -> String { U64 => "bv64".to_string(), U128 => "bv128".to_string(), U256 => "bv256".to_string(), + I8 | I16 | I32 | I64 | I128 | I256 => { + unimplemented!("{}", BV_TYPE_NOT_ENABLED_ERROR) + }, Address => "int".to_string(), Signer => "$signer".to_string(), Bool => "bool".to_string(), Range | EventStore => panic!("unexpected type"), Num => { //TODO(tengzhang): add error message with accurate location info - "<>".to_string() + "<>".to_string() }, }, Vector(et) => format!("Vec ({})", boogie_bv_type(env, et)), @@ -359,7 +405,8 @@ pub fn boogie_bv_type(env: &GlobalEnv, ty: &Type) -> String { }, Reference(_, bt) => format!("$Mutation ({})", boogie_bv_type(env, bt)), TypeParameter(idx) => boogie_type_param(env, *idx), - Fun(..) | Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) => { + Fun(param, result, abilities) => fun_type(env, param, result, *abilities), + Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) => { format!("<>", ty) }, } @@ -374,9 +421,18 @@ pub fn boogie_num_type_base_bv(env: &GlobalEnv, loc: Option, ty: &Type) -> Type::Primitive(PrimitiveType::U64) => "Bv64", Type::Primitive(PrimitiveType::U128) => "Bv128", Type::Primitive(PrimitiveType::U256) => "Bv256", + Type::Primitive(PrimitiveType::I8) + | Type::Primitive(PrimitiveType::I16) + | Type::Primitive(PrimitiveType::I32) + | Type::Primitive(PrimitiveType::I64) + | Type::Primitive(PrimitiveType::I128) + | Type::Primitive(PrimitiveType::I256) => { + env.error(&loc.unwrap_or_default(), BV_TYPE_NOT_ENABLED_ERROR); + "<>" + }, Type::Primitive(PrimitiveType::Num) => { env.error(&loc.unwrap_or_default(), NUM_TYPE_BASE_ERROR); - "<>" + "<>" }, _ => unreachable!(), }; @@ -404,13 +460,13 @@ pub fn boogie_num_literal(num: &String, base: usize, bv_flag: bool) -> String { } } -pub fn boogie_num_type_string(num: &str, bv_flag: bool) -> String { - let pre = if bv_flag { "bv" } else { "u" }; +pub fn boogie_num_type_string(kind: &str, num: &str, bv_flag: bool) -> String { + let pre = if bv_flag { "bv" } else { kind }; [pre, num].join("") } -pub fn boogie_num_type_string_capital(num: &str, bv_flag: bool) -> String { - let pre = if bv_flag { "Bv" } else { "U" }; +pub fn boogie_num_type_string_capital(kind: &str, num: &str, bv_flag: bool) -> String { + let pre = if bv_flag { "Bv" } else { kind }; [pre, num].join("") } @@ -425,9 +481,13 @@ pub fn boogie_num_type_base(env: &GlobalEnv, loc: Option, ty: &Type) -> Str U64 => "64".to_string(), U128 => "128".to_string(), U256 => "256".to_string(), + I8 | I16 | I32 | I64 | I128 | I256 => { + env.error(&loc.unwrap_or_default(), BV_TYPE_NOT_ENABLED_ERROR); + "<>".to_string() + }, Num => { env.error(&loc.unwrap_or_default(), NUM_TYPE_BASE_ERROR); - "<>".to_string() + "<>".to_string() }, _ => format!("<>", ty), }, @@ -442,16 +502,22 @@ pub fn boogie_type_suffix_bv(env: &GlobalEnv, ty: &Type, bv_flag: bool) -> Strin match ty { Primitive(p) => match p { - U8 => boogie_num_type_string("8", bv_flag), - U16 => boogie_num_type_string("16", bv_flag), - U32 => boogie_num_type_string("32", bv_flag), - U64 => boogie_num_type_string("64", bv_flag), - U128 => boogie_num_type_string("128", bv_flag), - U256 => boogie_num_type_string("256", bv_flag), + U8 => boogie_num_type_string("u", "8", bv_flag), + U16 => boogie_num_type_string("u", "16", bv_flag), + U32 => boogie_num_type_string("u", "32", bv_flag), + U64 => boogie_num_type_string("u", "64", bv_flag), + U128 => boogie_num_type_string("u", "128", bv_flag), + U256 => boogie_num_type_string("u", "256", bv_flag), + I8 => boogie_num_type_string("i", "8", bv_flag), + I16 => boogie_num_type_string("i", "16", bv_flag), + I32 => boogie_num_type_string("i", "32", bv_flag), + I64 => boogie_num_type_string("i", "64", bv_flag), + I128 => boogie_num_type_string("i", "128", bv_flag), + I256 => boogie_num_type_string("i", "256", bv_flag), Num => { if bv_flag { //TODO(tengzhang): add error message with accurate location info - "<>".to_string() + "<>".to_string() } else { "num".to_string() } @@ -470,8 +536,16 @@ pub fn boogie_type_suffix_bv(env: &GlobalEnv, ty: &Type, bv_flag: bool) -> Strin boogie_type_suffix_for_struct(&env.get_module(*mid).into_struct(*sid), inst, bv_flag) }, TypeParameter(idx) => boogie_type_param(env, *idx), - Fun(..) | Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) - | Reference(..) => format!("<>", ty), + Fun(params, results, abilities) => fun_type(env, params, results, *abilities), + Reference(ReferenceKind::Immutable, ty) => { + format!("$ref'{}'", boogie_type_suffix_bv(env, ty, bv_flag)) + }, + Reference(ReferenceKind::Mutable, ty) => { + format!("$mut'{}'", boogie_type_suffix_bv(env, ty, bv_flag)) + }, + Tuple(..) | TypeDomain(..) | ResourceDomain(..) | Error | Var(..) => { + format!("<>", ty) + }, } } @@ -648,9 +722,17 @@ pub fn boogie_constant(env: &GlobalEnv, _options: &BoogieOptions, val: &Constant Constant::Bool(true) => "true".to_string(), Constant::Bool(false) => "false".to_string(), Constant::U8(num) => num.to_string(), + Constant::U16(num) => num.to_string(), + Constant::U32(num) => num.to_string(), Constant::U64(num) => num.to_string(), Constant::U128(num) => num.to_string(), Constant::U256(num) => num.to_string(), + Constant::I8(num) => num.to_string(), + Constant::I16(num) => num.to_string(), + Constant::I32(num) => num.to_string(), + Constant::I64(num) => num.to_string(), + Constant::I128(num) => num.to_string(), + Constant::I256(num) => num.to_string(), Constant::Address(v) => boogie_address(env, v), Constant::ByteArray(v) => boogie_byte_blob(_options, v, false), Constant::AddressArray(v) => boogie_address_blob(env, _options, v), @@ -659,8 +741,6 @@ pub fn boogie_constant(env: &GlobalEnv, _options: &BoogieOptions, val: &Constant .map(|v| boogie_constant(env, _options, v)) .collect_vec(), ), - Constant::U16(num) => num.to_string(), - Constant::U32(num) => num.to_string(), } } @@ -902,6 +982,12 @@ fn type_name_to_ident_tokens( Type::Primitive(PrimitiveType::U64) => TypeIdentToken::make("u64"), Type::Primitive(PrimitiveType::U128) => TypeIdentToken::make("u128"), Type::Primitive(PrimitiveType::U256) => TypeIdentToken::make("u256"), + Type::Primitive(PrimitiveType::I8) => TypeIdentToken::make("i8"), + Type::Primitive(PrimitiveType::I16) => TypeIdentToken::make("i16"), + Type::Primitive(PrimitiveType::I32) => TypeIdentToken::make("i32"), + Type::Primitive(PrimitiveType::I64) => TypeIdentToken::make("i64"), + Type::Primitive(PrimitiveType::I128) => TypeIdentToken::make("i128"), + Type::Primitive(PrimitiveType::I256) => TypeIdentToken::make("i256"), Type::Primitive(PrimitiveType::Address) => TypeIdentToken::make("address"), Type::Primitive(PrimitiveType::Signer) => TypeIdentToken::make("signer"), Type::Vector(element) => { @@ -1029,6 +1115,12 @@ fn type_name_to_info_pack(env: &GlobalEnv, ty: &Type) -> Option { | Type::Primitive(PrimitiveType::U64) | Type::Primitive(PrimitiveType::U128) | Type::Primitive(PrimitiveType::U256) + | Type::Primitive(PrimitiveType::I8) + | Type::Primitive(PrimitiveType::I16) + | Type::Primitive(PrimitiveType::I32) + | Type::Primitive(PrimitiveType::I64) + | Type::Primitive(PrimitiveType::I128) + | Type::Primitive(PrimitiveType::I256) | Type::Primitive(PrimitiveType::Address) | Type::Primitive(PrimitiveType::Signer) | Type::Vector(_) => None, @@ -1111,3 +1203,19 @@ pub fn boogie_reflection_type_is_struct(env: &GlobalEnv, ty: &Type) -> String { Some(TypeInfoPack::Symbolic(idx)) => format!("(#{}_info is $TypeParamStruct)", idx), } } + +/// Return name of generated function for applying a function value. +pub fn boogie_fun_apply_name(env: &GlobalEnv, ty: &Type) -> String { + format!("$apply'{}'", boogie_type_suffix(env, ty)) +} + +/// Return name of generated function for constructing a closure based on given function and mask. +pub fn boogie_closure_pack_name( + env: &GlobalEnv, + fun: &QualifiedInstId, + mask: ClosureMask, +) -> String { + let fun_env = env.get_function(fun.to_qualified_id()); + let fun_name = boogie_function_name(&fun_env, &fun.inst); + format!("$closure'{}'_{}", fun_name, mask) +} diff --git a/third_party/move/move-prover/boogie-backend/src/boogie_wrapper.rs b/third_party/move/move-prover/boogie-backend/src/boogie_wrapper.rs index 26d7ee522bd..1e988dcb107 100644 --- a/third_party/move/move-prover/boogie-backend/src/boogie_wrapper.rs +++ b/third_party/move/move-prover/boogie-backend/src/boogie_wrapper.rs @@ -7,7 +7,8 @@ // DEBUG // use backtrace::Backtrace; use crate::{ - boogie_helpers::{boogie_inst_suffix, boogie_struct_name}, + boogie_helpers, + boogie_helpers::{boogie_inst_suffix, boogie_reverse_function_name, boogie_struct_name}, options::{BoogieOptions, VectorTheory}, prover_task_runner::{ProverTaskRunner, RunBoogieWithSeeds}, }; @@ -1315,6 +1316,20 @@ impl ModelValue { None } + /// Extract the arguments of a list of the form `(... element...)`, also returning + /// the ctor string for further analysis. + fn extract_ctor_and_list(&self, ctor_prefix: &str) -> Option<(String, &[ModelValue])> { + if let ModelValue::List(elems) = self { + if !elems.is_empty() { + let literal = elems[0].extract_literal()?; + if let Some(stripped) = literal.strip_prefix(ctor_prefix) { + return Some((stripped.to_string(), &elems[1..])); + } + } + } + None + } + /// Extract a $Value box value. fn extract_box(&self) -> &ModelValue { if let ModelValue::List(elems) = self { @@ -1327,11 +1342,7 @@ impl ModelValue { /// Extract a number from a literal. fn extract_number(&self) -> Option { - if let Ok(n) = self.extract_literal()?.parse::() { - Some(n) - } else { - None - } + self.extract_literal()?.parse::().ok() } /// Extract a i128 from a literal. @@ -1344,10 +1355,8 @@ impl ModelValue { } }) { Some(value) - } else if let Ok(n) = self.extract_literal()?.parse::() { - Some(n) } else { - None + self.extract_literal()?.parse::().ok() } } @@ -1434,9 +1443,31 @@ impl ModelValue { // effect the verification outcome, we may not have much need for seeing it. Some(PrettyDoc::text("")) }, + Type::Fun(..) => { + let repr = if let Some((ctor_rest, args)) = self.extract_ctor_and_list("|$closure'") + { + let end = ctor_rest.rfind("'")?; + let fun_name_mangled = &ctor_rest[..end]; + let fun_name = boogie_reverse_function_name(wrapper.env, fun_name_mangled) + .unwrap_or_else(|| fun_name_mangled.to_string()); + format!("{}(captured={:?})", fun_name, args) + } else if let Some((_, args)) = self.extract_ctor_and_list("|$unknown_function'") { + format!( + "(captured={:?})", + ty.display(&wrapper.env.get_type_display_ctx()), + args + ) + } else { + format!( + "(captured={:?})", + ty.display(&wrapper.env.get_type_display_ctx()), + self + ) + }; + Some(PrettyDoc::text(repr)) + }, Type::Tuple(_) | Type::Primitive(_) - | Type::Fun(..) | Type::TypeDomain(_) | Type::ResourceDomain(_, _, _) | Type::Error @@ -1507,6 +1538,11 @@ impl ModelValue { struct_env: &StructEnv, inst: &[Type], ) -> Option { + let struct_name = &boogie_struct_name(struct_env, inst); + let mut ctor_name = struct_env + .get_name() + .display(struct_env.symbol_pool()) + .to_string(); let entries = if struct_env.is_intrinsic() { let mut rep = self.extract_literal()?.to_string(); if rep.starts_with("T@") { @@ -1516,14 +1552,33 @@ impl ModelValue { } vec![PrettyDoc::text(rep)] } else { - let struct_name = &boogie_struct_name(struct_env, inst); - let values = self - .extract_list(struct_name) - // It appears sometimes keys are represented witout, sometimes with enclosing - // bars? - .or_else(|| self.extract_list(&format!("|{}|", struct_name)))?; + let mut variant = None; + let mut values: &[ModelValue] = &[]; + if struct_env.has_variants() { + // Probe which of the variants we are looking at + for vari in struct_env.get_variants() { + let variant_name = + boogie_helpers::boogie_struct_variant_name(struct_env, inst, vari); + if let Some(vals) = self + .extract_list(&variant_name) + // It appears sometimes keys are represented without, sometimes with enclosing + // bars? + .or_else(|| self.extract_list(&format!("|{}|", variant_name))) + { + variant = Some(vari); + values = vals; + ctor_name = + format!("{}::{}", ctor_name, vari.display(struct_env.symbol_pool())); + break; + } + } + } else { + values = self + .extract_list(struct_name) + .or_else(|| self.extract_list(&format!("|{}|", struct_name)))?; + } struct_env - .get_fields() + .get_fields_optional_variant(variant) .enumerate() .map(|(i, f)| { let ty = f.get_type().instantiate(inst); @@ -1543,13 +1598,13 @@ impl ModelValue { }; Some( PrettyDoc::text(format!( - "{}.{}", + "{}::{}", struct_env .module_env .get_name() .name() .display(struct_env.symbol_pool()), - struct_env.get_name().display(struct_env.symbol_pool()) + ctor_name )) .append(Self::pretty_vec_or_struct_body(entries)), ) @@ -1567,7 +1622,7 @@ impl ModelValue { // function table of $EncodeKey and turns into a map from int to encoded ModelValue. let encoding_key = format!( "$EncodeKey{}", - boogie_inst_suffix(wrapper.env, &[key_ty.clone()]) + boogie_inst_suffix(wrapper.env, std::slice::from_ref(key_ty)) ); let encoding_map = model .vars diff --git a/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs b/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs index 23d8f831b64..f127a3c9b31 100644 --- a/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs @@ -7,14 +7,15 @@ use crate::{ boogie_helpers::{ boogie_address, boogie_address_blob, boogie_bv_type, boogie_byte_blob, - boogie_constant_blob, boogie_debug_track_abort, boogie_debug_track_local, - boogie_debug_track_return, boogie_equality_for_type, boogie_field_sel, boogie_field_update, - boogie_function_bv_name, boogie_function_name, boogie_make_vec_from_strings, - boogie_modifies_memory_name, boogie_num_literal, boogie_num_type_base, - boogie_num_type_string_capital, boogie_reflection_type_info, boogie_reflection_type_name, - boogie_resource_memory_name, boogie_struct_name, boogie_struct_variant_name, boogie_temp, - boogie_temp_from_suffix, boogie_type, boogie_type_for_struct_field, boogie_type_param, - boogie_type_suffix, boogie_type_suffix_bv, boogie_type_suffix_for_struct, + boogie_closure_pack_name, boogie_constant_blob, boogie_debug_track_abort, + boogie_debug_track_local, boogie_debug_track_return, boogie_equality_for_type, + boogie_field_sel, boogie_field_update, boogie_fun_apply_name, boogie_function_bv_name, + boogie_function_name, boogie_make_vec_from_strings, boogie_modifies_memory_name, + boogie_num_literal, boogie_num_type_base, boogie_num_type_string_capital, + boogie_reflection_type_info, boogie_reflection_type_name, boogie_resource_memory_name, + boogie_struct_name, boogie_struct_variant_name, boogie_temp, boogie_temp_from_suffix, + boogie_type, boogie_type_for_struct_field, boogie_type_param, boogie_type_suffix, + boogie_type_suffix_bv, boogie_type_suffix_for_struct, boogie_type_suffix_for_struct_variant, boogie_variant_field_update, boogie_well_formed_check, boogie_well_formed_expr_bv, field_bv_flag_global_state, TypeIdentToken, @@ -43,6 +44,7 @@ use move_model::{ }; use move_prover_bytecode_pipeline::{ mono_analysis, + mono_analysis::ClosureInfo, number_operation::{ FuncOperationMap, GlobalNumberOperationState, NumOperation, NumOperation::{Bitwise, Bottom}, @@ -62,6 +64,19 @@ use std::{ hash::{DefaultHasher, Hash, Hasher}, }; +macro_rules! bv_op_not_enabled_error { + ($bytecode:expr, $fun_target:expr, $env:expr, $loc:expr) => { + unimplemented!( + "bit vector not supported in operation: `{}` {}", + $bytecode + .display($fun_target, &::std::collections::BTreeMap::default()) + .to_string() + .replace('\n', "\n// "), + $loc.display($env) + ) + }; +} + pub struct BoogieTranslator<'env> { env: &'env GlobalEnv, options: &'env BoogieOptions, @@ -150,6 +165,51 @@ impl<'env> BoogieTranslator<'env> { } } + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_function(&self, writer: &CodeWriter, signature: &str, body_fn: impl Fn()) { + self.emit_function_with_attr(writer, "{:inline} ", signature, body_fn) + } + + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_procedure(&self, writer: &CodeWriter, signature: &str, body_fn: impl Fn()) { + self.emit_procedure_with_attr(writer, "{:inline 1} ", signature, body_fn) + } + + fn emit_with_attr( + &self, + writer: &CodeWriter, + sig: &str, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + emitln!(writer, "{} {}{} {{", sig, attr, signature); + writer.indent(); + body_fn(); + writer.unindent(); + emitln!(writer, "}"); + } + + fn emit_function_with_attr( + &self, + writer: &CodeWriter, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + self.emit_with_attr(writer, "function", attr, signature, body_fn) + } + + fn emit_procedure_with_attr( + &self, + writer: &CodeWriter, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + self.emit_with_attr(writer, "procedure", attr, signature, body_fn) + } + #[allow(clippy::literal_string_with_formatting_args)] pub fn translate(&mut self) { let writer = self.writer; @@ -170,7 +230,8 @@ impl<'env> BoogieTranslator<'env> { // type name <-> type info: primitives for name in [ - "Bool", "U8", "U16", "U32", "U64", "U128", "U256", "Address", "Signer", + "Bool", "U8", "U16", "U32", "U64", "U128", "U256", "I8", "I16", "I32", "I64", + "I128", "I256", "Address", "Signer", ] .into_iter() { @@ -257,6 +318,39 @@ impl<'env> BoogieTranslator<'env> { // declare the memory variable for this type emitln!(writer, "var {}_$memory: $Memory {};", suffix, param_type); + + // If cmp module is included, emit cmp functions for generic types + if env + .get_modules() + .any(|m| m.get_full_name_str() == "0x1::cmp") + { + self.emit_function( + writer, + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, param_type, param_type + ), + || { + emitln!( + writer, + "if $IsEqual'{}'(v1, v2) then $1_cmp_Ordering_Equal()", + suffix + ); + emitln!(writer, "else $Arbitrary_value_of'$1_cmp_Ordering'()"); + }, + ); + + self.emit_procedure( + writer, + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, param_type, param_type + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } } emitln!(writer); @@ -264,6 +358,7 @@ impl<'env> BoogieTranslator<'env> { .translate_axioms(env, mono_info.as_ref()); let mut translated_types = BTreeSet::new(); + let mut translated_memory = vec![]; let mut translated_funs = BTreeSet::new(); let mut verified_functions_count = 0; info!("generating verification conditions"); @@ -286,6 +381,13 @@ impl<'env> BoogieTranslator<'env> { if !translated_types.insert(struct_name) { continue; } + if struct_env.has_memory() { + translated_memory.push(boogie_resource_memory_name( + env, + &struct_env.get_qualified_id().instantiate(type_inst.clone()), + &None, + )) + } StructTranslator { parent: self, struct_env, @@ -383,6 +485,12 @@ impl<'env> BoogieTranslator<'env> { } } } + + // Emit function types and closures + for (fun_type, closure_infos) in &mono_info.fun_infos { + self.translate_fun_type(fun_type, closure_infos, &translated_memory) + } + // Emit any finalization items required by spec translation. self.spec_translator.finalize(); let shard_info = if let Some(shard) = self.for_shard { @@ -395,6 +503,155 @@ impl<'env> BoogieTranslator<'env> { verified_functions_count, shard_info ); } + + fn translate_fun_type( + &self, + fun_type: &Type, + closure_infos: &BTreeSet, + memory: &[String], + ) { + emitln!( + self.writer, + "// Function type `{}`", + fun_type.display(&self.env.get_type_display_ctx()) + ); + + // Create data type for the function type. + let fun_ty_boogie_name = boogie_type(self.env, fun_type); + emitln!(self.writer, "datatype {} {{", fun_ty_boogie_name); + self.writer.indent(); + for info in closure_infos { + emitln!( + self.writer, + "// Closure from function `{}`, capture mask 0b{}", + self.env.display(&info.fun), + info.mask + ); + emit!( + self.writer, + "{}(", + boogie_closure_pack_name(self.env, &info.fun, info.mask) + ); + let fun_env = self.env.get_function(info.fun.to_qualified_id()); + let param_tys = Type::instantiate_vec(fun_env.get_parameter_types(), &info.fun.inst); + for (pos, captured_ty) in info.mask.extract(¶m_tys, true).iter().enumerate() { + if pos > 0 { + emit!(self.writer, ", ") + } + emit!( + self.writer, + "p{}: {}", + pos, + boogie_type(self.env, captured_ty) + ) + } + emitln!(self.writer, "),") + } + // Last variant for unknown value. + emitln!( + self.writer, + "// Value to represent some arbitrary unknown function" + ); + emitln!( + self.writer, + "$unknown_function'{}'(id: int)", + boogie_type_suffix(self.env, fun_type), + ); + self.writer.unindent(); + emitln!(self.writer, "}"); + emitln!( + self.writer, + "function $IsValid'{}'(x: {}): bool {{ true }}", + boogie_type_suffix(self.env, fun_type), + fun_ty_boogie_name + ); + + // Create an apply procedure. + emit!( + self.writer, + "procedure {{:inline 1}} {}(", + boogie_fun_apply_name(self.env, fun_type), + ); + let Type::Fun(params, results, _abilities) = fun_type else { + panic!("expected function type") + }; + let params = params.clone().flatten(); + for (pos, mut ty) in params.iter().enumerate() { + if pos > 0 { + emit!(self.writer, ", ") + } + if ty.is_immutable_reference() { + // Immutable references are eliminated in the compilation scheme, so skip + ty = ty.skip_reference(); + } + emit!(self.writer, "p{}: {}", pos, boogie_type(self.env, ty)) + } + if !params.is_empty() { + emit!(self.writer, ", ") + } + emit!(self.writer, "fun: {}", fun_ty_boogie_name); + emit!(self.writer, ") returns ("); + let mut result_locals = vec![]; + for (pos, mut ty) in results + .clone() + .flatten() + .iter() + // Mutable input parameters become output, so append them + .chain(params.iter().filter(|p| p.is_mutable_reference())) + .enumerate() + { + if pos > 0 { + emit!(self.writer, ",") + } + let local_name = format!("r{}", pos); + if ty.is_immutable_reference() { + // Immutable references are eliminated in the compilation scheme, so skip + ty = ty.skip_reference(); + } + emit!(self.writer, "{}: {}", local_name, boogie_type(self.env, ty)); + result_locals.push(local_name) + } + emitln!(self.writer, ") {"); + self.writer.indent(); + let result_str = result_locals.iter().cloned().join(", "); + for info in closure_infos { + let ctor_name = boogie_closure_pack_name(self.env, &info.fun, info.mask); + emitln!(self.writer, "if (fun is {}) {{", ctor_name); + self.writer.indent(); + let fun_env = &self.env.get_function(info.fun.to_qualified_id()); + let fun_name = boogie_function_name(fun_env, &info.fun.inst); + let args = (0..info.mask.captured_count()) + .map(|pos| format!("fun->p{}", pos)) + .chain((0..params.len()).map(|pos| format!("p{}", pos))) + .join(", "); + let call_prefix = if result_str.is_empty() { + String::new() + } else { + format!("{result_str} := ") + }; + emitln!(self.writer, "call {}{}({});", call_prefix, fun_name, args); + self.writer.unindent(); + emitln!(self.writer, "} else "); + } + if !closure_infos.is_empty() { + emitln!(self.writer, "{"); + self.writer.indent(); + } + emitln!( + self.writer, + "// Havoc memory and abort_flag since the unknown function could modify anything." + ); + emitln!(self.writer, "havoc $abort_flag;"); + for mem in memory { + emitln!(self.writer, "havoc {};", mem) + } + if !closure_infos.is_empty() { + self.writer.unindent(); + emitln!(self.writer, "}"); + } + self.writer.unindent(); + emitln!(self.writer, "}"); + } } // ================================================================================================= @@ -511,7 +768,8 @@ impl StructTranslator<'_> { } // Emit $IsValid function for `variant`. - self.emit_function_with_attr( + self.parent.emit_function_with_attr( + writer, "", // not inlined! &format!("$IsValid'{}'(s: {}): bool", suffix_variant, struct_name), || { @@ -538,7 +796,8 @@ impl StructTranslator<'_> { // Emit $IsValid function for struct. fn emit_is_valid_struct(&self, struct_env: &StructEnv, struct_name: &str, emit_fn: impl Fn()) { let writer = self.parent.writer; - self.emit_function_with_attr( + self.parent.emit_function_with_attr( + writer, "", // not inlined! &format!("$IsValid'{}'(s: {}): bool", struct_name, struct_name), || { @@ -642,6 +901,121 @@ impl StructTranslator<'_> { emitln!(writer, "else false"); } + /// Emit the function cmp::compare for enum + fn emit_cmp_for_enum(&self, struct_env: &StructEnv, struct_name: &str) { + let writer = self.parent.writer; + let suffix: String = boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, struct_name, struct_name + ), + || { + let mut else_symbol = ""; + for (pos_1, v1) in struct_env.get_variants().collect_vec().iter().enumerate() { + for (pos_2, v2) in struct_env.get_variants().collect_vec().iter().enumerate() { + if pos_2 <= pos_1 { + continue; + } + let struct_variant_name_1 = + boogie_struct_variant_name(struct_env, self.type_inst, *v1); + let struct_variant_name_2 = + boogie_struct_variant_name(struct_env, self.type_inst, *v2); + let cmp_order_less = format!( + "{} if v1 is {} && v2 is {} then $1_cmp_Ordering_Less()", + else_symbol, struct_variant_name_1, struct_variant_name_2 + ); + let cmp_order_greater = format!( + "else if v1 is {} && v2 is {} then $1_cmp_Ordering_Greater()", + struct_variant_name_2, struct_variant_name_1 + ); + if else_symbol.is_empty() { + else_symbol = "else"; + } + emitln!(writer, "{}", cmp_order_less); + emitln!(writer, "{}", cmp_order_greater); + } + } + for variant in struct_env.get_variants().collect_vec().iter() { + let struct_variant_name_1 = + boogie_struct_variant_name(struct_env, self.type_inst, *variant); + let suffix_variant = + boogie_type_suffix_for_struct_variant(struct_env, self.type_inst, variant); + let cmp_order = format!( + "{} if v1 is {} && v2 is {} then $1_cmp_$compare'{}'(v1, v2)", + else_symbol, struct_variant_name_1, struct_variant_name_1, suffix_variant + ); + emitln!(writer, "{}", cmp_order); + } + emitln!(writer, "else $Arbitrary_value_of'$1_cmp_Ordering'()"); + }, + ); + for variant in struct_env.get_variants().collect_vec().iter() { + self.emit_cmp_for_enum_variant(struct_env, *variant, struct_name); + } + } + + /// Emit the function cmp::compare for each enum variant + fn emit_cmp_for_enum_variant( + &self, + struct_env: &StructEnv, + variant: Symbol, + struct_name: &str, + ) { + let writer = self.parent.writer; + let suffix_variant = + boogie_type_suffix_for_struct_variant(struct_env, self.type_inst, &variant); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix_variant, struct_name, struct_name + ), + || { + if struct_env + .get_fields_of_variant(variant) + .collect_vec() + .is_empty() + { + emitln!(writer, "$1_cmp_Ordering_Equal()"); + } else { + for (pos, field) in struct_env.get_fields_of_variant(variant).enumerate() { + let bv_flag = self.field_bv_flag(&field); + let field_type_name = boogie_type_suffix_bv( + self.parent.env, + &self.inst(&field.get_type()), + bv_flag, + ); + let cmp_field_call = format!( + "$1_cmp_$compare'{}'(v1->{}, v2->{})", + field_type_name, + boogie_field_sel(&field), + boogie_field_sel(&field) + ); + let cmp_field_call_less = + format!("{} == $1_cmp_Ordering_Less()", cmp_field_call); + let cmp_field_call_greater = + format!("{} == $1_cmp_Ordering_Greater()", cmp_field_call); + emitln!(writer, "if {}", cmp_field_call_less); + emitln!(writer, "then $1_cmp_Ordering_Less()"); + emitln!(writer, "else if {}", cmp_field_call_greater); + emitln!(writer, "then $1_cmp_Ordering_Greater()"); + if pos + < struct_env + .get_fields_of_variant(variant) + .collect_vec() + .len() + - 1 + { + emitln!(writer, "else"); + } else { + emitln!(writer, "else $1_cmp_Ordering_Equal()"); + } + } + } + }, + ); + } + /// Return whether a field involves bitwise operations pub fn field_bv_flag(&self, field_env: &FieldEnv) -> bool { let global_state = &self @@ -805,21 +1179,90 @@ impl StructTranslator<'_> { emitln!(writer, "var {}: $Memory {};", memory_name, struct_name); } + // Emit compare function and procedure + let cmp_struct_types = self.parent.env.cmp_types.borrow(); + for cmp_struct_type in cmp_struct_types.iter() { + if let Some((cur_struct, inst)) = cmp_struct_type.get_struct(env) { + if cur_struct.get_id() == struct_env.get_id() && inst == self.type_inst { + if !struct_env.has_variants() { + let suffix = + boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, struct_name, struct_name + ), + || { + for (pos, field) in struct_env.get_fields().enumerate() { + let bv_flag = self.field_bv_flag(&field); + let suffix_ty = boogie_type_suffix_bv( + self.parent.env, + &self.inst(&field.get_type()), + bv_flag, + ); + let cmp_field_call = format!( + "$1_cmp_$compare'{}'(v1->{}, v2->{})", + suffix_ty, + boogie_field_sel(&field), + boogie_field_sel(&field) + ); + let cmp_field_call_less = + format!("{} == $1_cmp_Ordering_Less()", cmp_field_call); + let cmp_field_call_greater = + format!("{} == $1_cmp_Ordering_Greater()", cmp_field_call); + emitln!(writer, "if {}", cmp_field_call_less); + emitln!(writer, "then $1_cmp_Ordering_Less()"); + emitln!(writer, "else if {}", cmp_field_call_greater); + emitln!(writer, "then $1_cmp_Ordering_Greater()"); + if pos < struct_env.get_field_count() - 1 { + emitln!(writer, "else"); + } else { + emitln!(writer, "else $1_cmp_Ordering_Equal()"); + } + } + }, + ); + self.emit_procedure( + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, struct_name, struct_name + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } else { + self.emit_cmp_for_enum(struct_env, &struct_name); + let suffix: String = + boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_procedure( + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, struct_name, struct_name + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } + break; + } + } + } + emitln!(writer); } #[allow(clippy::literal_string_with_formatting_args)] fn emit_function(&self, signature: &str, body_fn: impl Fn()) { - self.emit_function_with_attr("{:inline} ", signature, body_fn) + self.parent + .emit_function(self.parent.writer, signature, body_fn); } - fn emit_function_with_attr(&self, attr: &str, signature: &str, body_fn: impl Fn()) { - let writer = self.parent.writer; - emitln!(writer, "function {}{} {{", attr, signature); - writer.indent(); - body_fn(); - writer.unindent(); - emitln!(writer, "}"); + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_procedure(&self, signature: &str, body_fn: impl Fn()) { + self.parent + .emit_procedure(self.parent.writer, signature, body_fn); } } @@ -1381,15 +1824,21 @@ impl FunctionTranslator<'_> { Constant::Bool(true) => "true".to_string(), Constant::Bool(false) => "false".to_string(), Constant::U8(num) => boogie_num_literal(&num.to_string(), 8, bv_flag), + Constant::U16(num) => boogie_num_literal(&num.to_string(), 16, bv_flag), + Constant::U32(num) => boogie_num_literal(&num.to_string(), 32, bv_flag), Constant::U64(num) => boogie_num_literal(&num.to_string(), 64, bv_flag), Constant::U128(num) => boogie_num_literal(&num.to_string(), 128, bv_flag), Constant::U256(num) => boogie_num_literal(&num.to_string(), 256, bv_flag), + Constant::I8(num) => boogie_num_literal(&num.to_string(), 8, bv_flag), + Constant::I16(num) => boogie_num_literal(&num.to_string(), 16, bv_flag), + Constant::I32(num) => boogie_num_literal(&num.to_string(), 32, bv_flag), + Constant::I64(num) => boogie_num_literal(&num.to_string(), 64, bv_flag), + Constant::I128(num) => boogie_num_literal(&num.to_string(), 128, bv_flag), + Constant::I256(num) => boogie_num_literal(&num.to_string(), 256, bv_flag), Constant::Address(val) => boogie_address(env, val), Constant::ByteArray(val) => boogie_byte_blob(options, val, bv_flag), Constant::AddressArray(val) => boogie_address_blob(env, options, val), Constant::Vector(val) => boogie_constant_blob(env, options, val), - Constant::U16(num) => boogie_num_literal(&num.to_string(), 16, bv_flag), - Constant::U32(num) => boogie_num_literal(&num.to_string(), 32, bv_flag), }; let dest_str = str_local(*dest); emitln!(writer, "{} := {};", dest_str, value); @@ -1403,10 +1852,6 @@ impl FunctionTranslator<'_> { Call(_, dests, oper, srcs, aa) => { use Operation::*; match oper { - Closure(..) | Invoke => { - // TODO(#15664): implement closures for prover - panic!("closures not yet supported") - }, TestVariant(mid, sid, variant, inst) => { let inst = &self.inst_slice(inst); let src_type = self.get_local_type(srcs[0]); @@ -1514,7 +1959,7 @@ impl FunctionTranslator<'_> { str_local(value), ); }, - Function(mid, fid, inst) => { + Function(mid, fid, inst) | Closure(mid, fid, inst, _) => { let inst = &self.inst_slice(inst); let module_env = env.get_module(*mid); let callee_env = module_env.get_function(*fid); @@ -1536,6 +1981,20 @@ impl FunctionTranslator<'_> { if self.try_reflection_call(writer, env, inst, &callee_env, &dest_str) { // Special case of reflection call, code is generated + } else if let Closure(_, _, _, mask) = oper { + // Special case of closure construction + let closure_ctor_name = boogie_closure_pack_name( + env, + &mid.qualified_inst(*fid, inst.clone()), + *mask, + ); + emitln!( + writer, + "{} := {}({});", + dest_str, + closure_ctor_name, + args_str + ) } else { // regular path let targeted = self.fun_target.module_env().is_target(); @@ -1622,6 +2081,11 @@ impl FunctionTranslator<'_> { } else { let dest_bv_flag = !dests.is_empty() && compute_flag(dests[0]); let bv_flag = !srcs.is_empty() && compute_flag(srcs[0]); + if module_env.is_cmp() { + fun_name = boogie_function_bv_name(&callee_env, inst, &[ + bv_flag || dest_bv_flag, + ]); + } // Handle the case where the return value of length is assigned to a bv int because // length always returns a non-bv result if module_env.is_std_vector() { @@ -1701,6 +2165,31 @@ impl FunctionTranslator<'_> { // location tracks before it returns. *last_tracked_loc = None; }, + Invoke => { + // Function is last argument + let fun_type = self.inst(fun_target.get_local_type(*srcs.last().unwrap())); + let args_str = srcs.iter().cloned().map(str_local).join(", "); + let dest_str = dests + .iter() + .cloned() + .map(str_local) + // Add implict dest returns for &mut srcs: + // f(x) --> x := f(x) if type(x) = &mut_ + .chain( + srcs.iter() + .filter(|idx| self.get_local_type(**idx).is_mutable_reference()) + .cloned() + .map(str_local), + ) + .join(","); + let apply_fun = boogie_fun_apply_name(env, &fun_type); + let call_prefix = if dest_str.is_empty() { + String::new() + } else { + format!("{dest_str} := ") + }; + emitln!(writer, "call {}{}({});", call_prefix, apply_fun, args_str); + }, Pack(mid, sid, inst) => { let inst = &self.inst_slice(inst); let struct_env = env.get_module(*mid).into_struct(*sid); @@ -1998,46 +2487,88 @@ impl FunctionTranslator<'_> { CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 => { let src = srcs[0]; let dest = dests[0]; - let make_cast = |target_base: &str, src: TempIndex, dest: TempIndex| { - let num_oper = global_state - .get_temp_index_oper(mid, fid, src, baseline_flag) - .unwrap(); - let bv_flag = self.bv_flag(num_oper); - if bv_flag { - let src_type = self.get_local_type(src); - let base = boogie_num_type_base( - self.parent.env, - Some(self.fun_target.get_bytecode_loc(attr_id)), - &src_type, - ); - emitln!( - writer, - "call {} := $CastBv{}to{}({});", - str_local(dest), - base, - target_base, - str_local(src) - ); - } else { - emitln!( - writer, - "call {} := $CastU{}({});", - str_local(dest), - target_base, - str_local(src) - ); - } + let (target_kind, target_base) = match oper { + CastU8 => ("U", "8"), + CastU16 => ("U", "16"), + CastU32 => ("U", "32"), + CastU64 => ("U", "64"), + CastU128 => ("U", "128"), + CastU256 => ("U", "256"), + _ => unreachable!(), }; - let target_base = match oper { - CastU8 => "8", - CastU16 => "16", - CastU32 => "32", - CastU64 => "64", - CastU128 => "128", - CastU256 => "256", + + let num_oper = global_state + .get_temp_index_oper(mid, fid, src, baseline_flag) + .unwrap(); + + if self.bv_flag(num_oper) { + let src_type = self.get_local_type(src); + let src_base = boogie_num_type_base( + self.parent.env, + Some(self.fun_target.get_bytecode_loc(attr_id)), + &src_type, + ); + emitln!( + writer, + "call {} := $CastBv{}to{}({});", + str_local(dest), + src_base, + target_base, + str_local(src) + ); + } else { + emitln!( + writer, + "call {} := $Cast{}{}({});", + str_local(dest), + target_kind, + target_base, + str_local(src) + ); + } + }, + CastI8 | CastI16 | CastI32 | CastI64 | CastI128 | CastI256 => { + let src = srcs[0]; + let dest = dests[0]; + let (target_kind, target_base) = match oper { + CastI8 => ("I", "8"), + CastI16 => ("I", "16"), + CastI32 => ("I", "32"), + CastI64 => ("I", "64"), + CastI128 => ("I", "128"), + CastI256 => ("I", "256"), _ => unreachable!(), }; - make_cast(target_base, src, dest); + let num_oper = global_state + .get_temp_index_oper(mid, fid, src, baseline_flag) + .unwrap(); + if self.bv_flag(num_oper) { + // src is a bitvector: convert it to int and then do cast + let src_type = self.get_local_type(src); + let src_base = boogie_num_type_base( + self.parent.env, + Some(self.fun_target.get_bytecode_loc(attr_id)), + &src_type, + ); + emitln!( + writer, + "call {} := $Cast{}{}($bv2int.{}({}));", + str_local(dest), + target_kind, + target_base, + src_base, + str_local(src) + ); + } else { + emitln!( + writer, + "call {} := $Cast{}{}({});", + str_local(dest), + target_kind, + target_base, + str_local(src) + ); + } }, Not => { let src = srcs[0]; @@ -2067,31 +2598,61 @@ impl FunctionTranslator<'_> { let add_type = match &self.get_local_type(dest) { Type::Primitive(PrimitiveType::U8) => { - boogie_num_type_string_capital("8", bv_flag) + boogie_num_type_string_capital("U", "8", bv_flag) }, Type::Primitive(PrimitiveType::U16) => format!( "{}{}", - boogie_num_type_string_capital("16", bv_flag), + boogie_num_type_string_capital("U", "16", bv_flag), unchecked ), Type::Primitive(PrimitiveType::U32) => format!( "{}{}", - boogie_num_type_string_capital("32", bv_flag), + boogie_num_type_string_capital("U", "32", bv_flag), unchecked ), Type::Primitive(PrimitiveType::U64) => format!( "{}{}", - boogie_num_type_string_capital("64", bv_flag), + boogie_num_type_string_capital("U", "64", bv_flag), unchecked ), Type::Primitive(PrimitiveType::U128) => format!( "{}{}", - boogie_num_type_string_capital("128", bv_flag), + boogie_num_type_string_capital("U", "128", bv_flag), unchecked ), Type::Primitive(PrimitiveType::U256) => format!( "{}{}", - boogie_num_type_string_capital("256", bv_flag), + boogie_num_type_string_capital("U", "256", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I8) => format!( + "{}{}", + boogie_num_type_string_capital("I", "8", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I16) => format!( + "{}{}", + boogie_num_type_string_capital("I", "16", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I32) => format!( + "{}{}", + boogie_num_type_string_capital("I", "32", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I64) => format!( + "{}{}", + boogie_num_type_string_capital("I", "64", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I128) => format!( + "{}{}", + boogie_num_type_string_capital("I", "128", bv_flag), + unchecked + ), + Type::Primitive(PrimitiveType::I256) => format!( + "{}{}", + boogie_num_type_string_capital("I", "256", bv_flag), unchecked ), Type::Primitive(_) @@ -2123,43 +2684,63 @@ impl FunctionTranslator<'_> { .get_temp_index_oper(mid, fid, dest, baseline_flag) .unwrap(); let bv_flag = self.bv_flag(num_oper); - if bv_flag { - let sub_type = match &self.get_local_type(dest) { - Type::Primitive(PrimitiveType::U8) => "Bv8".to_string(), - Type::Primitive(PrimitiveType::U16) => "Bv16".to_string(), - Type::Primitive(PrimitiveType::U32) => "Bv32".to_string(), - Type::Primitive(PrimitiveType::U64) => "Bv64".to_string(), - Type::Primitive(PrimitiveType::U128) => "Bv128".to_string(), - Type::Primitive(PrimitiveType::U256) => "Bv256".to_string(), - Type::Primitive(_) - | Type::Tuple(_) - | Type::Vector(_) - | Type::Struct(_, _, _) - | Type::TypeParameter(_) - | Type::Reference(_, _) - | Type::Fun(..) - | Type::TypeDomain(_) - | Type::ResourceDomain(_, _, _) - | Type::Error - | Type::Var(_) => unreachable!(), - }; - emitln!( - writer, - "call {} := $Sub{}({}, {});", - str_local(dest), - sub_type, - str_local(op1), - str_local(op2) - ); - } else { - emitln!( - writer, - "call {} := $Sub({}, {});", - str_local(dest), - str_local(op1), - str_local(op2) - ); - } + let sub_type = match &self.get_local_type(dest) { + Type::Primitive(PrimitiveType::U8) => { + boogie_num_type_string_capital("U", "8", bv_flag) + }, + Type::Primitive(PrimitiveType::U16) => { + boogie_num_type_string_capital("U", "16", bv_flag) + }, + Type::Primitive(PrimitiveType::U32) => { + boogie_num_type_string_capital("U", "32", bv_flag) + }, + Type::Primitive(PrimitiveType::U64) => { + boogie_num_type_string_capital("U", "64", bv_flag) + }, + Type::Primitive(PrimitiveType::U128) => { + boogie_num_type_string_capital("U", "128", bv_flag) + }, + Type::Primitive(PrimitiveType::U256) => { + boogie_num_type_string_capital("U", "256", bv_flag) + }, + Type::Primitive(PrimitiveType::I8) => { + boogie_num_type_string_capital("I", "8", bv_flag) + }, + Type::Primitive(PrimitiveType::I16) => { + boogie_num_type_string_capital("I", "16", bv_flag) + }, + Type::Primitive(PrimitiveType::I32) => { + boogie_num_type_string_capital("I", "32", bv_flag) + }, + Type::Primitive(PrimitiveType::I64) => { + boogie_num_type_string_capital("I", "64", bv_flag) + }, + Type::Primitive(PrimitiveType::I128) => { + boogie_num_type_string_capital("I", "128", bv_flag) + }, + Type::Primitive(PrimitiveType::I256) => { + boogie_num_type_string_capital("I", "256", bv_flag) + }, + Type::Primitive(_) + | Type::Tuple(_) + | Type::Vector(_) + | Type::Struct(_, _, _) + | Type::TypeParameter(_) + | Type::Reference(_, _) + | Type::Fun(..) + | Type::TypeDomain(_) + | Type::ResourceDomain(_, _, _) + | Type::Error + | Type::Var(_) => unreachable!(), + }; + emitln!( + writer, + "call {} := $Sub{}({}, {});", + str_local(dest), + sub_type, + str_local(op1), + str_local(op2) + ); }, Mul => { let dest = dests[0]; @@ -2171,22 +2752,40 @@ impl FunctionTranslator<'_> { let bv_flag = self.bv_flag(num_oper); let mul_type = match &self.get_local_type(dest) { Type::Primitive(PrimitiveType::U8) => { - boogie_num_type_string_capital("8", bv_flag) + boogie_num_type_string_capital("U", "8", bv_flag) }, Type::Primitive(PrimitiveType::U16) => { - boogie_num_type_string_capital("16", bv_flag) + boogie_num_type_string_capital("U", "16", bv_flag) }, Type::Primitive(PrimitiveType::U32) => { - boogie_num_type_string_capital("32", bv_flag) + boogie_num_type_string_capital("U", "32", bv_flag) }, Type::Primitive(PrimitiveType::U64) => { - boogie_num_type_string_capital("64", bv_flag) + boogie_num_type_string_capital("U", "64", bv_flag) }, Type::Primitive(PrimitiveType::U128) => { - boogie_num_type_string_capital("128", bv_flag) + boogie_num_type_string_capital("U", "128", bv_flag) }, Type::Primitive(PrimitiveType::U256) => { - boogie_num_type_string_capital("256", bv_flag) + boogie_num_type_string_capital("U", "256", bv_flag) + }, + Type::Primitive(PrimitiveType::I8) => { + boogie_num_type_string_capital("I", "8", bv_flag) + }, + Type::Primitive(PrimitiveType::I16) => { + boogie_num_type_string_capital("I", "16", bv_flag) + }, + Type::Primitive(PrimitiveType::I32) => { + boogie_num_type_string_capital("I", "32", bv_flag) + }, + Type::Primitive(PrimitiveType::I64) => { + boogie_num_type_string_capital("I", "64", bv_flag) + }, + Type::Primitive(PrimitiveType::I128) => { + boogie_num_type_string_capital("I", "128", bv_flag) + }, + Type::Primitive(PrimitiveType::I256) => { + boogie_num_type_string_capital("I", "256", bv_flag) }, Type::Primitive(_) | Type::Tuple(_) @@ -2289,6 +2888,42 @@ impl FunctionTranslator<'_> { str_local(op2) ); }, + Negate => { + let dest = dests[0]; + let op = srcs[0]; + let num_oper = global_state + .get_temp_index_oper(mid, fid, dest, baseline_flag) + .unwrap(); + if self.bv_flag(num_oper) { + bv_op_not_enabled_error!(bytecode, fun_target, env, loc); + } + let neg_type = match &self.get_local_type(dest) { + Type::Primitive(PrimitiveType::I8) => "I8", + Type::Primitive(PrimitiveType::I16) => "I16", + Type::Primitive(PrimitiveType::I32) => "I32", + Type::Primitive(PrimitiveType::I64) => "I64", + Type::Primitive(PrimitiveType::I128) => "I128", + Type::Primitive(PrimitiveType::I256) => "I256", + Type::Primitive(_) + | Type::Tuple(_) + | Type::Vector(_) + | Type::Struct(_, _, _) + | Type::TypeParameter(_) + | Type::Reference(_, _) + | Type::Fun(..) + | Type::TypeDomain(_) + | Type::ResourceDomain(_, _, _) + | Type::Error + | Type::Var(_) => unreachable!(), + }; + emitln!( + writer, + "call {} := $Negate{}({});", + str_local(dest), + neg_type, + str_local(op), + ); + }, Shl | Shr => { let dest = dests[0]; let op1 = srcs[0]; @@ -2762,30 +3397,34 @@ impl FunctionTranslator<'_> { format!("ReadVec({}->p, LenVec($t{}->p) + {})", src_str, idx, offset) } }; - let update = if let BorrowEdge::Hyper(edges) = edge { - self.translate_write_back_update( - &mut || dst_value.clone(), - &get_path_index, - src_value, - edges, - 0, - ) + if matches!(edge, BorrowEdge::Invoke) { + emitln!(writer, "call $t{} := $HavocMutation($t{});", idx, idx); } else { - self.translate_write_back_update( - &mut || dst_value.clone(), - &get_path_index, - src_value, - &[edge.to_owned()], - 0, - ) - }; - emitln!( - writer, - "$t{} := $UpdateMutation($t{}, {});", - idx, - idx, - update - ); + let update = if let BorrowEdge::Hyper(edges) = edge { + self.translate_write_back_update( + &mut || dst_value.clone(), + &get_path_index, + src_value, + edges, + 0, + ) + } else { + self.translate_write_back_update( + &mut || dst_value.clone(), + &get_path_index, + src_value, + &[edge.to_owned()], + 0, + ) + }; + emitln!( + writer, + "$t{} := $UpdateMutation($t{}, {});", + idx, + idx, + update + ); + } }, } } @@ -2936,7 +3575,7 @@ impl FunctionTranslator<'_> { ) } }, - BorrowEdge::Hyper(_) => unreachable!("unexpected borrow edge"), + BorrowEdge::Hyper(_) | BorrowEdge::Invoke => unreachable!("unexpected borrow edge"), } } } diff --git a/third_party/move/move-prover/boogie-backend/src/lib.rs b/third_party/move/move-prover/boogie-backend/src/lib.rs index 906bc6f7b6a..2a1444e3733 100644 --- a/third_party/move/move-prover/boogie-backend/src/lib.rs +++ b/third_party/move/move-prover/boogie-backend/src/lib.rs @@ -54,7 +54,9 @@ const TABLE_ARRAY_THEORY: &[u8] = include_bytes!("prelude/table-array-theory.bpl // TODO use named addresses const BCS_MODULE: &str = "0x1::bcs"; +const FROM_BCS_MODULE: &str = "0x1::from_bcs"; const EVENT_MODULE: &str = "0x1::event"; +const CMP_MODULE: &str = "0x1::cmp"; mod boogie_helpers; pub mod boogie_wrapper; @@ -201,20 +203,19 @@ pub fn add_prelude( let mut bv_all_types = mono_info .all_types .iter() - .filter(|ty| ty.can_be_type_argument()) + .filter(|ty| ty.can_be_type_argument() && !ty.is_signed_int()) .map(|ty| TypeInfo::new(env, options, ty, true)) .filter(|ty_info| !all_types.contains(ty_info)) .collect::>() .into_iter() .collect_vec(); all_types.append(&mut bv_all_types); - context.insert("uninterpreted_instances", &all_types); // obtain bv number types appearing in the program, which is currently used to generate cast functions for bv types - let number_types = mono_info + let bv_number_types = mono_info .all_types .iter() - .filter(|ty| ty.is_number() && !matches!(ty, Type::Primitive(PrimitiveType::Num))) + .filter(|ty| ty.is_unsigned_int()) .map(|ty| { boogie_num_type_base(env, None, ty) .parse::() @@ -223,7 +224,7 @@ pub fn add_prelude( .collect_vec(); let bv_in_all_types = bv_instances .iter() - .filter(|bv_info| number_types.contains(&bv_info.base)) + .filter(|bv_info| bv_number_types.contains(&bv_info.base)) .map(|bv_info| bv_info.base) .collect_vec(); @@ -318,9 +319,73 @@ pub fn add_prelude( let bcs_instances = filter_native_ensure_one_inst(BCS_MODULE); context.insert("bcs_instances", &bcs_instances); + let from_bcs_instances = filter_native_ensure_one_inst(FROM_BCS_MODULE); + context.insert("from_bcs_instances", &from_bcs_instances); let event_instances = filter_native_ensure_one_inst(EVENT_MODULE); context.insert("event_instances", &event_instances); + // handle cmp module + let filter_native_with_contained_types_with_bv_flag = |module: &str, bv_flag: bool| { + mono_info + .native_inst + .iter() + .filter(|(id, _)| env.get_module(**id).get_full_name_str() == module) + .flat_map(|(_, insts)| { + insts.iter().map(|inst| { + inst.iter() + .flat_map(|i| i.get_all_contained_types_with_skip_reference(env)) + .map(|i| (i.clone(), TypeInfo::new(env, options, &i, bv_flag))) + .collect::>() + }) + }) + .sorted() + .collect_vec() + }; + let filter_native_with_contained_types = |module: &str| { + let mut filtered = filter_native_with_contained_types_with_bv_flag(module, false); + let mut filtered_bv = filter_native_with_contained_types_with_bv_flag(module, true); + filtered.append(&mut filtered_bv); + filtered.into_iter().flatten().collect_vec() + }; + let mut cmp_instances = filter_native_with_contained_types(CMP_MODULE); + cmp_instances.sort(); + cmp_instances.dedup(); + let mut cmp_struct_types = vec![]; + let mut cmp_int_types = all_types + .clone() + .into_iter() + .filter(|ty| ty.name == "int") + .collect_vec(); + for (ty, ty_info) in &cmp_instances { + if ty.is_struct() { + cmp_struct_types.push(ty.clone()); + } + if ty.is_number() && !ty_info.suffix.contains("bv") && !cmp_int_types.contains(ty_info) { + cmp_int_types.push(ty_info.clone()); + } + } + cmp_int_types.sort(); + cmp_int_types.dedup(); + cmp_struct_types.sort(); + cmp_struct_types.dedup(); + context.insert("cmp_int_instances", &cmp_int_types); + env.cmp_types.borrow_mut().extend(cmp_struct_types); + + let filter_cmp_instances_with_name_prefix = |name_prefix: &str| { + cmp_instances + .clone() + .into_iter() + .filter(|ty| ty.1.name.starts_with(name_prefix)) + .map(|ty| ty.1) + .collect_vec() + }; + let cmp_vector_instances = filter_cmp_instances_with_name_prefix("Vec"); + context.insert("cmp_vector_instances", &cmp_vector_instances); + let cmp_table_instances = filter_cmp_instances_with_name_prefix("Table"); + context.insert("cmp_table_instances", &cmp_table_instances); + + context.insert("uninterpreted_instances", &all_types); + // TODO: we have defined {{std}} for adaptable resolution of stdlib addresses but // not used it yet in the templates. let std_addr = format!("${}", env.get_stdlib_address().expect_numerical()); diff --git a/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl b/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl index 506707ddf8e..1a1fa15f13d 100644 --- a/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl +++ b/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl @@ -616,6 +616,23 @@ axiom (forall v: int :: {$1_bcs_serialize'address'(v)} {% endmacro hash_module %} +{# FROM_BCS + ==== +#} + +{% macro from_bcs_module(instance) %} +{%- set S = "'" ~ instance.suffix ~ "'" -%} +{%- set T = instance.name -%} + +procedure $1_from_bcs_from_bytes{{S}}(v: Vec int) returns (res: {{T}}); + +function $1_from_bcs_$from_bytes{{S}}(v: Vec int): {{T}}; +axiom (forall v: Vec int :: {$1_from_bcs_deserialize{{S}}(v)} + ( var r := $1_from_bcs_$from_bytes{{S}}(v); r == $1_from_bcs_deserialize{{S}}(v) )); + +{% endmacro from_bcs_module %} + + {# Event Module ============ #} diff --git a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl index 7b279ac9887..4cb32662cd1 100644 --- a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl +++ b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl @@ -3,7 +3,7 @@ Copyright (c) The Diem Core Contributors SPDX-License-Identifier: Apache-2.0 This files contains a Tera Rust template for the prover's Boogie prelude. -(See https://tera.netlify.app/docs). +(See https://docs.rs/tera/latest/tera/). The following variables and filters are bound in the template context: @@ -32,26 +32,235 @@ options provided to the prover. {%- set S = "'" ~ instance.suffix ~ "'" -%} {%- set T = instance.name -%} +{%-if S != "'$1_cmp_Ordering'" %} function $Arbitrary_value_of{{S}}(): {{T}}; +{% endif %} {% endfor %} // ============================================================================================ -// Primitive Types - -const $MAX_U8: int; -axiom $MAX_U8 == 255; -const $MAX_U16: int; -axiom $MAX_U16 == 65535; -const $MAX_U32: int; -axiom $MAX_U32 == 4294967295; -const $MAX_U64: int; -axiom $MAX_U64 == 18446744073709551615; -const $MAX_U128: int; -axiom $MAX_U128 == 340282366920938463463374607431768211455; -const $MAX_U256: int; -axiom $MAX_U256 == 115792089237316195423570985008687907853269984665640564039457584007913129639935; +// Integer Types + +// Constants, Instructions, and Procedures needed by both unsigned and signed integers, but defined separately. +{% macro integer_type(name, typename, min, max) %} +const $MIN_{{name}}: int; +const $MAX_{{name}}: int; +axiom $MIN_{{name}} == {{min}}; +axiom $MAX_{{name}} == {{max}}; + +function $IsValid'{{typename}}'(v: int): bool { + v >= $MIN_{{name}} && v <= $MAX_{{name}} +} + +function {:inline} $IsEqual'{{typename}}'(x: int, y: int): bool { + x == y +} + +procedure {:inline 1} $Cast{{name}}(src: int) returns (dst: int) +{ + if (src < $MIN_{{name}} || src > $MAX_{{name}}) { + call $ExecFailureAbort(); + return; + } + dst := src; +} + +procedure {:inline 1} $Add{{name}}(src1: int, src2: int) returns (dst: int) +{ + if (src1 + src2 > $MAX_{{name}} || src1 + src2 < $MIN_{{name}}) { + call $ExecFailureAbort(); + return; + } + dst := src1 + src2; +} + +procedure {:inline 1} $Add{{name}}_unchecked(src1: int, src2: int) returns (dst: int) +{ + dst := src1 + src2; +} + +procedure {:inline 1} $Sub{{name}}(src1: int, src2: int) returns (dst: int) +{ + if (src1 - src2 > $MAX_{{name}} || src1 - src2 < $MIN_{{name}}) { + call $ExecFailureAbort(); + return; + } + dst := src1 - src2; +} + +procedure {:inline 1} $Mul{{name}}(src1: int, src2: int) returns (dst: int) +{ + if (src1 * src2 > $MAX_{{name}} || src1 * src2 < $MIN_{{name}}) { + call $ExecFailureAbort(); + return; + } + dst := src1 * src2; +} +{% endmacro %} + +{{ self::integer_type(name="U8", typename="u8", min=0, max=255) }} +{{ self::integer_type(name="U16", typename="u16", min=0, max=65535) }} +{{ self::integer_type(name="U32", typename="u32", min=0, max=4294967295) }} +{{ self::integer_type(name="U64", typename="u64", min=0, max="18446744073709551615") }} +{{ self::integer_type(name="U128", typename="u128", min=0, max="340282366920938463463374607431768211455") }} +{{ self::integer_type(name="U256", typename="u256", min=0, max="115792089237316195423570985008687907853269984665640564039457584007913129639935") }} +{{ self::integer_type(name="I8", typename="i8", min=-128, max=127) }} +{{ self::integer_type(name="I16", typename="i16", min=-32768, max=32767) }} +{{ self::integer_type(name="I32", typename="i32", min=-2147483648, max=2147483647) }} +{{ self::integer_type(name="I64", typename="i64", min="-9223372036854775808", max="9223372036854775807") }} +{{ self::integer_type(name="I128", typename="i128", min="-170141183460469231731687303715884105728", max="170141183460469231731687303715884105727") }} +{{ self::integer_type(name="I256", typename="i256", min="-57896044618658097711785492504343953926634992332820282019728792003956564819968", max="57896044618658097711785492504343953926634992332820282019728792003956564819967") }} + +// Instructions and Procedures shared by unsigned and signed integers + +// uninterpreted function to return an undefined value. +function $undefined_int(): int; + +procedure {:inline 1} $Div(src1: int, src2: int) returns (dst: int) +{ + if (src2 == 0) { + call $ExecFailureAbort(); + return; + } + dst := src1 div src2; +} + +procedure {:inline 1} $Mod(src1: int, src2: int) returns (dst: int) +{ + if (src2 == 0) { + call $ExecFailureAbort(); + return; + } + dst := src1 mod src2; +} + +// Unimplemented binary arithmetic operations; return the dst +procedure {:inline 1} $ArithBinaryUnimplemented(src1: int, src2: int) returns (dst: int); + +// Instructions and Procedures unique to unsigned integers + +// Recursive exponentiation function +// Undefined unless e >=0. $pow(0,0) is also undefined. +function $pow(n: int, e: int): int { + if n != 0 && e == 0 then 1 + else if e > 0 then n * $pow(n, e - 1) + else $undefined_int() +} + +function $shl(src1: int, p: int): int { + src1 * $pow(2, p) +} + +function $shr(src1: int, p: int): int { + src1 div $pow(2, p) +} + +procedure {:inline 1} $Shr(src1: int, src2: int) returns (dst: int) +{ + var res: int; + // src2 is a u8 + assume src2 >= 0 && src2 < 256; + dst := $shr(src1, src2); +} + +{% macro shift_funs_and_procs(name, bits) %} +function $shl{{name}}(src1: int, p: int): int { + (src1 * $pow(2, p)) mod ($MAX_{{name}} + 1) +} + +procedure {:inline 1} $Shl{{name}}(src1: int, src2: int) returns (dst: int) +{ + // src2 is a u8 + assume src2 >= 0 && src2 < 256; + {% if bits > 0 %} + if (src2 >= {{bits}}) { + call $ExecFailureAbort(); + return; + } + {% endif %} + dst := $shl{{name}}(src1, src2); +} + +procedure {:inline 1} $Shr{{name}}(src1: int, src2: int) returns (dst: int) +{ + // src2 is a u8 + assume src2 >= 0 && src2 < 256; + {% if bits > 0 %} + if (src2 >= {{bits}}) { + call $ExecFailureAbort(); + return; + } + {% endif %} + dst := $shr(src1, src2); +} +{% endmacro %} + +{{ self::shift_funs_and_procs(name="U8", bits=8) }} +{{ self::shift_funs_and_procs(name="U16", bits=16) }} +{{ self::shift_funs_and_procs(name="U32", bits=32) }} +{{ self::shift_funs_and_procs(name="U64", bits=64) }} +{{ self::shift_funs_and_procs(name="U128", bits=128) }} +{{ self::shift_funs_and_procs(name="U256", bits=0) }} + +// Instructions and Procedures unique to signed integers + +{% macro negate_proc(name) %} +procedure {:inline 1} $Negate{{name}}(src: int) returns (dst: int) +{ + if (src <= $MIN_{{name}}) { + call $ExecFailureAbort(); + return; + } + dst := -src; +} +{% endmacro %} + +{{ self::negate_proc(name="I8") }} +{{ self::negate_proc(name="I16") }} +{{ self::negate_proc(name="I32") }} +{{ self::negate_proc(name="I64") }} +{{ self::negate_proc(name="I128") }} +{{ self::negate_proc(name="I256") }} + +// ============================================================================================ +// Logical Procedures + +procedure {:inline 1} $Lt(src1: int, src2: int) returns (dst: bool) +{ + dst := src1 < src2; +} + +procedure {:inline 1} $Gt(src1: int, src2: int) returns (dst: bool) +{ + dst := src1 > src2; +} + +procedure {:inline 1} $Le(src1: int, src2: int) returns (dst: bool) +{ + dst := src1 <= src2; +} + +procedure {:inline 1} $Ge(src1: int, src2: int) returns (dst: bool) +{ + dst := src1 >= src2; +} + +procedure {:inline 1} $And(src1: bool, src2: bool) returns (dst: bool) +{ + dst := src1 && src2; +} +procedure {:inline 1} $Or(src1: bool, src2: bool) returns (dst: bool) +{ + dst := src1 || src2; +} + +procedure {:inline 1} $Not(src: bool) returns (dst: bool) +{ + dst := !src; +} + +// ============================================================================================ // Templates for bitvector operations {%- for impl in bv_instances %} @@ -191,30 +400,6 @@ function {:inline} $IsValid'bool'(v: bool): bool { true } -function $IsValid'u8'(v: int): bool { - v >= 0 && v <= $MAX_U8 -} - -function $IsValid'u16'(v: int): bool { - v >= 0 && v <= $MAX_U16 -} - -function $IsValid'u32'(v: int): bool { - v >= 0 && v <= $MAX_U32 -} - -function $IsValid'u64'(v: int): bool { - v >= 0 && v <= $MAX_U64 -} - -function $IsValid'u128'(v: int): bool { - v >= 0 && v <= $MAX_U128 -} - -function $IsValid'u256'(v: int): bool { - v >= 0 && v <= $MAX_U256 -} - function $IsValid'num'(v: int): bool { true } @@ -233,31 +418,6 @@ function $InRange(r: $Range, i: int): bool { r->lb <= i && i < r->ub } - -function {:inline} $IsEqual'u8'(x: int, y: int): bool { - x == y -} - -function {:inline} $IsEqual'u16'(x: int, y: int): bool { - x == y -} - -function {:inline} $IsEqual'u32'(x: int, y: int): bool { - x == y -} - -function {:inline} $IsEqual'u64'(x: int, y: int): bool { - x == y -} - -function {:inline} $IsEqual'u128'(x: int, y: int): bool { - x == y -} - -function {:inline} $IsEqual'u256'(x: int, y: int): bool { - x == y -} - function {:inline} $IsEqual'num'(x: int, y: int): bool { x == y } @@ -316,6 +476,13 @@ function {:inline} $UpdateMutation(m: $Mutation T, v: T): $Mutation T { $Mutation(m->l, m->p, v) } +// Havoc the content of the mutation, preserving location and path. +procedure {:inline 1} $HavocMutation(m: $Mutation T) returns (r: $Mutation T) { + r->l := m->l; + r->p := m->p; + // r->v stays uninitialized, thus havoced +} + function {:inline} $ChildMutation(m: $Mutation T1, offset: int, v: T2): $Mutation T2 { $Mutation(m->l, ExtendVec(m->p, offset), v) } @@ -404,8 +571,6 @@ function {:inline} $ResourceCopy(m: $Memory T, s: $Memory T, a: int): $Memory m->contents[a := s->contents[a]]) } - - // ============================================================================================ // Abort Handling @@ -448,278 +613,79 @@ procedure {:inline 1} $InitVerification() { // Instructions -procedure {:inline 1} $CastU8(src: int) returns (dst: int) +// Template for cast and shift operations of bitvector types + +{%- for impl in bv_instances %} +{%- for instance in sh_instances %} +{%- set base_diff = impl.base - instance %} + +procedure {:inline 1} $CastBv{{instance}}to{{impl.base}}(src: bv{{instance}}) returns (dst: bv{{impl.base}}) { - if (src > $MAX_U8) { - call $ExecFailureAbort(); - return; + {%- if base_diff < 0 %} + if ($Gt'Bv{{instance}}'(src, {{impl.max}}bv{{instance}})) { + call $ExecFailureAbort(); + return; } + {%- endif %} + {%- if base_diff < 0 %} + dst := src[{{impl.base}}:0]; + {%- elif base_diff == 0 %} dst := src; + {%- else %} + dst := 0bv{{base_diff}} ++ src; + {%- endif %} } -procedure {:inline 1} $CastU16(src: int) returns (dst: int) +{% if impl.base in bv_in_all_types and instance in bv_in_all_types %} +function $castBv{{instance}}to{{impl.base}}(src: bv{{instance}}) returns (bv{{impl.base}}) { - if (src > $MAX_U16) { - call $ExecFailureAbort(); - return; - } - dst := src; + {%- if base_diff < 0 %} + if ($Gt'Bv{{instance}}'(src, {{impl.max}}bv{{instance}})) then + $Arbitrary_value_of'bv{{impl.base}}'() + {%- endif %} + {%- if base_diff < 0 %} + else + src[{{impl.base}}:0] + {%- elif base_diff == 0 %} + src + {%- else %} + 0bv{{base_diff}} ++ src + {%- endif %} } +{% endif %} -procedure {:inline 1} $CastU32(src: int) returns (dst: int) +function $shlBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (bv{{impl.base}}) { - if (src > $MAX_U32) { - call $ExecFailureAbort(); - return; - } - dst := src; + {%- if base_diff > 0 %} + $Shl'Bv{{impl.base}}'(src1, 0bv{{base_diff}} ++ src2) + {%- elif base_diff == 0 %} + $Shl'Bv{{impl.base}}'(src1, src2) + {%- else %} + $Shl'Bv{{impl.base}}'(src1, src2[{{impl.base}}:0]) + {%- endif %} } -procedure {:inline 1} $CastU64(src: int) returns (dst: int) +procedure {:inline 1} $ShlBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (dst: bv{{impl.base}}) { - if (src > $MAX_U64) { + {%- if impl.base != 256 or instance != 8 %} + if ($Ge'Bv{{instance}}'(src2, {{impl.base}}bv{{instance}})) { call $ExecFailureAbort(); return; } - dst := src; + {% else %} + assume $bv2int.{{instance}}(src2) >= 0 && $bv2int.{{instance}}(src2) < 256; + {%- endif %} + + {%- if base_diff > 0 %} + dst := $Shl'Bv{{impl.base}}'(src1, 0bv{{base_diff}} ++ src2); + {%- elif base_diff == 0 %} + dst := $Shl'Bv{{impl.base}}'(src1, src2); + {%- else %} + dst := $Shl'Bv{{impl.base}}'(src1, src2[{{impl.base}}:0]); + {%- endif %} } -procedure {:inline 1} $CastU128(src: int) returns (dst: int) -{ - if (src > $MAX_U128) { - call $ExecFailureAbort(); - return; - } - dst := src; -} - -procedure {:inline 1} $CastU256(src: int) returns (dst: int) -{ - if (src > $MAX_U256) { - call $ExecFailureAbort(); - return; - } - dst := src; -} - -procedure {:inline 1} $AddU8(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U8) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU16(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U16) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU16_unchecked(src1: int, src2: int) returns (dst: int) -{ - dst := src1 + src2; -} - -procedure {:inline 1} $AddU32(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U32) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU32_unchecked(src1: int, src2: int) returns (dst: int) -{ - dst := src1 + src2; -} - -procedure {:inline 1} $AddU64(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U64) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU64_unchecked(src1: int, src2: int) returns (dst: int) -{ - dst := src1 + src2; -} - -procedure {:inline 1} $AddU128(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U128) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU128_unchecked(src1: int, src2: int) returns (dst: int) -{ - dst := src1 + src2; -} - -procedure {:inline 1} $AddU256(src1: int, src2: int) returns (dst: int) -{ - if (src1 + src2 > $MAX_U256) { - call $ExecFailureAbort(); - return; - } - dst := src1 + src2; -} - -procedure {:inline 1} $AddU256_unchecked(src1: int, src2: int) returns (dst: int) -{ - dst := src1 + src2; -} - -procedure {:inline 1} $Sub(src1: int, src2: int) returns (dst: int) -{ - if (src1 < src2) { - call $ExecFailureAbort(); - return; - } - dst := src1 - src2; -} - -// uninterpreted function to return an undefined value. -function $undefined_int(): int; - -// Recursive exponentiation function -// Undefined unless e >=0. $pow(0,0) is also undefined. -function $pow(n: int, e: int): int { - if n != 0 && e == 0 then 1 - else if e > 0 then n * $pow(n, e - 1) - else $undefined_int() -} - -function $shl(src1: int, p: int): int { - src1 * $pow(2, p) -} - -function $shlU8(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 256 -} - -function $shlU16(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 65536 -} - -function $shlU32(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 4294967296 -} - -function $shlU64(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 18446744073709551616 -} - -function $shlU128(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 340282366920938463463374607431768211456 -} - -function $shlU256(src1: int, p: int): int { - (src1 * $pow(2, p)) mod 115792089237316195423570985008687907853269984665640564039457584007913129639936 -} - -function $shr(src1: int, p: int): int { - src1 div $pow(2, p) -} - -// We need to know the size of the destination in order to drop bits -// that have been shifted left more than that, so we have $ShlU8/16/32/64/128/256 -procedure {:inline 1} $ShlU8(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 8) { - call $ExecFailureAbort(); - return; - } - dst := $shlU8(src1, src2); -} - -// Template for cast and shift operations of bitvector types - -{%- for impl in bv_instances %} -{%- for instance in sh_instances %} -{%- set base_diff = impl.base - instance %} - -procedure {:inline 1} $CastBv{{instance}}to{{impl.base}}(src: bv{{instance}}) returns (dst: bv{{impl.base}}) -{ - {%- if base_diff < 0 %} - if ($Gt'Bv{{instance}}'(src, {{impl.max}}bv{{instance}})) { - call $ExecFailureAbort(); - return; - } - {%- endif %} - {%- if base_diff < 0 %} - dst := src[{{impl.base}}:0]; - {%- elif base_diff == 0 %} - dst := src; - {%- else %} - dst := 0bv{{base_diff}} ++ src; - {%- endif %} -} - -{% if impl.base in bv_in_all_types and instance in bv_in_all_types %} -function $castBv{{instance}}to{{impl.base}}(src: bv{{instance}}) returns (bv{{impl.base}}) -{ - {%- if base_diff < 0 %} - if ($Gt'Bv{{instance}}'(src, {{impl.max}}bv{{instance}})) then - $Arbitrary_value_of'bv{{impl.base}}'() - {%- endif %} - {%- if base_diff < 0 %} - else - src[{{impl.base}}:0] - {%- elif base_diff == 0 %} - src - {%- else %} - 0bv{{base_diff}} ++ src - {%- endif %} -} -{% endif %} - -function $shlBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (bv{{impl.base}}) -{ - {%- if base_diff > 0 %} - $Shl'Bv{{impl.base}}'(src1, 0bv{{base_diff}} ++ src2) - {%- elif base_diff == 0 %} - $Shl'Bv{{impl.base}}'(src1, src2) - {%- else %} - $Shl'Bv{{impl.base}}'(src1, src2[{{impl.base}}:0]) - {%- endif %} -} - -procedure {:inline 1} $ShlBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (dst: bv{{impl.base}}) -{ - {%- if impl.base != 256 or instance != 8 %} - if ($Ge'Bv{{instance}}'(src2, {{impl.base}}bv{{instance}})) { - call $ExecFailureAbort(); - return; - } - {% else %} - assume $bv2int.{{instance}}(src2) >= 0 && $bv2int.{{instance}}(src2) < 256; - {%- endif %} - - {%- if base_diff > 0 %} - dst := $Shl'Bv{{impl.base}}'(src1, 0bv{{base_diff}} ++ src2); - {%- elif base_diff == 0 %} - dst := $Shl'Bv{{impl.base}}'(src1, src2); - {%- else %} - dst := $Shl'Bv{{impl.base}}'(src1, src2[{{impl.base}}:0]); - {%- endif %} -} - -function $shrBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (bv{{impl.base}}) +function $shrBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, src2: bv{{instance}}) returns (bv{{impl.base}}) { {%- if base_diff > 0 %} $Shr'Bv{{impl.base}}'(src1, 0bv{{base_diff}} ++ src2) @@ -753,247 +719,6 @@ procedure {:inline 1} $ShrBv{{impl.base}}From{{instance}}(src1: bv{{impl.base}}, {%- endfor %} {%- endfor %} -procedure {:inline 1} $ShlU16(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 16) { - call $ExecFailureAbort(); - return; - } - dst := $shlU16(src1, src2); -} - -procedure {:inline 1} $ShlU32(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 32) { - call $ExecFailureAbort(); - return; - } - dst := $shlU32(src1, src2); -} - -procedure {:inline 1} $ShlU64(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 64) { - call $ExecFailureAbort(); - return; - } - dst := $shlU64(src1, src2); -} - -procedure {:inline 1} $ShlU128(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 128) { - call $ExecFailureAbort(); - return; - } - dst := $shlU128(src1, src2); -} - -procedure {:inline 1} $ShlU256(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - dst := $shlU256(src1, src2); -} - -procedure {:inline 1} $Shr(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU8(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 8) { - call $ExecFailureAbort(); - return; - } - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU16(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 16) { - call $ExecFailureAbort(); - return; - } - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU32(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 32) { - call $ExecFailureAbort(); - return; - } - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU64(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 64) { - call $ExecFailureAbort(); - return; - } - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU128(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - if (src2 >= 128) { - call $ExecFailureAbort(); - return; - } - dst := $shr(src1, src2); -} - -procedure {:inline 1} $ShrU256(src1: int, src2: int) returns (dst: int) -{ - var res: int; - // src2 is a u8 - assume src2 >= 0 && src2 < 256; - dst := $shr(src1, src2); -} - -procedure {:inline 1} $MulU8(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U8) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $MulU16(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U16) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $MulU32(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U32) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $MulU64(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U64) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $MulU128(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U128) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $MulU256(src1: int, src2: int) returns (dst: int) -{ - if (src1 * src2 > $MAX_U256) { - call $ExecFailureAbort(); - return; - } - dst := src1 * src2; -} - -procedure {:inline 1} $Div(src1: int, src2: int) returns (dst: int) -{ - if (src2 == 0) { - call $ExecFailureAbort(); - return; - } - dst := src1 div src2; -} - -procedure {:inline 1} $Mod(src1: int, src2: int) returns (dst: int) -{ - if (src2 == 0) { - call $ExecFailureAbort(); - return; - } - dst := src1 mod src2; -} - -procedure {:inline 1} $ArithBinaryUnimplemented(src1: int, src2: int) returns (dst: int); - -procedure {:inline 1} $Lt(src1: int, src2: int) returns (dst: bool) -{ - dst := src1 < src2; -} - -procedure {:inline 1} $Gt(src1: int, src2: int) returns (dst: bool) -{ - dst := src1 > src2; -} - -procedure {:inline 1} $Le(src1: int, src2: int) returns (dst: bool) -{ - dst := src1 <= src2; -} - -procedure {:inline 1} $Ge(src1: int, src2: int) returns (dst: bool) -{ - dst := src1 >= src2; -} - -procedure {:inline 1} $And(src1: bool, src2: bool) returns (dst: bool) -{ - dst := src1 && src2; -} - -procedure {:inline 1} $Or(src1: bool, src2: bool) returns (dst: bool) -{ - dst := src1 || src2; -} - -procedure {:inline 1} $Not(src: bool) returns (dst: bool) -{ - dst := !src; -} - // Pack and Unpack are auto-generated for each type T @@ -1206,6 +931,18 @@ procedure {:inline 1} $1_Signature_ed25519_verify( {%- endfor %} +// ================================================================================== +// Native from_bcs::from_bytes + +{%- for instance in from_bcs_instances %} + +// ---------------------------------------------------------------------------------- +// Native FROM_BCS implementation for element type `{{instance.suffix}}` + +{{ native::from_bcs_module(instance=instance) -}} +{%- endfor %} + + // ================================================================================== // Native Event module @@ -1298,6 +1035,12 @@ datatype $TypeParamInfo { $TypeParamU64(), $TypeParamU128(), $TypeParamU256(), + $TypeParamI8(), + $TypeParamI16(), + $TypeParamI32(), + $TypeParamI64(), + $TypeParamI128(), + $TypeParamI256(), $TypeParamAddress(), $TypeParamSigner(), $TypeParamVector(e: $TypeParamInfo), diff --git a/third_party/move/move-prover/boogie-backend/src/prover_task_runner.rs b/third_party/move/move-prover/boogie-backend/src/prover_task_runner.rs index 461add08f31..0cb3fdd548e 100644 --- a/third_party/move/move-prover/boogie-backend/src/prover_task_runner.rs +++ b/third_party/move/move-prover/boogie-backend/src/prover_task_runner.rs @@ -180,7 +180,7 @@ impl ProverTask for RunBoogieWithSeeds { let mut rng = rand::thread_rng(); // Otherwise generate a list of random numbers to use as seeds. (0..num_instances) - .map(|_| rng.gen::() as usize) + .map(|_| rng.r#gen::() as usize) .collect() } @@ -188,7 +188,7 @@ impl ProverTask for RunBoogieWithSeeds { let _guard = sem.acquire().await; let args = self .get_boogie_command(task_id) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?; + .map_err(std::io::Error::other)?; debug!("running Boogie command with seed {}", task_id); Command::new(&args[0]) .args(&args[1..]) diff --git a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs index 6ca78128163..e5f629e6d20 100644 --- a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs @@ -576,6 +576,13 @@ impl SpecTranslator<'_> { ..self.clone() }; + let skip_immutable_reference = |ty: &Type| { + if !ty.is_mutable_reference() { + ty.skip_reference().clone() + } else { + ty.clone() + } + }; // Pairs of context parameter names and boogie types let param_decls = info .free_vars @@ -583,14 +590,15 @@ impl SpecTranslator<'_> { .map(|(s, ty)| { ( s.display(env.symbol_pool()).to_string(), - boogie_type(env, ty.skip_reference()), + boogie_type(env, &skip_immutable_reference(ty)), ) }) - .chain( - info.used_temps - .iter() - .map(|(t, ty)| (format!("$t{}", t), boogie_type(env, ty.skip_reference()))), - ) + .chain(info.used_temps.iter().map(|(t, ty)| { + ( + format!("$t{}", t), + boogie_type(env, &skip_immutable_reference(ty)), + ) + })) .chain(info.used_memory.iter().map(|(m, l)| { let struct_env = &env.get_struct(m.to_qualified_id()); ( @@ -607,6 +615,11 @@ impl SpecTranslator<'_> { let mk_arg = |(n, _): &(String, String)| n.to_owned(); let emit_valid = |n: &str, ty: &Type| { let suffix = boogie_type_suffix(env, ty.skip_reference()); + let n = if ty.is_mutable_reference() { + format!("$Dereference({})", n) + } else { + n.to_owned() + }; emit!(new_spec_trans.writer, "$IsValid'{}'({})", suffix, n); }; let mk_temp = |t: TempIndex| format!("$t{}", t); @@ -801,8 +814,11 @@ impl SpecTranslator<'_> { self.translate_call(*node_id, oper, args); }, ExpData::Invoke(node_id, ..) => { - self.error(&self.env.get_node_loc(*node_id), "Invoke not yet supported"); - // TODO(LAMBDA) + self.error( + &self.env.get_node_loc(*node_id), + "current restriction: a function \ + value cannot be used in a specification expression.", + ); }, ExpData::Lambda(node_id, ..) => self.error( &self.env.get_node_loc(*node_id), @@ -982,7 +998,7 @@ impl SpecTranslator<'_> { self.translate_select_variant(node_id, *module_id, *struct_id, field_ids, args); }, Operation::TestVariants(module_id, struct_id, variants) => { - self.translate_test_variants(node_id, *module_id, *struct_id, variants, args); + self.translate_test_variants(*module_id, *struct_id, variants, args); }, Operation::UpdateField(module_id, struct_id, field_id) => { self.translate_update_field(node_id, *module_id, *struct_id, *field_id, args) @@ -1006,7 +1022,7 @@ impl SpecTranslator<'_> { Operation::BitOr => self.translate_bit_op("$Or", args), Operation::BitAnd => self.translate_bit_op("$And", args), Operation::Xor => self.translate_bit_op("$Xor", args), - Operation::Shl => self.translate_primitive_call_shl("$shl", args), + Operation::Shl => self.translate_primitive_call_shl("$shl", args, &loc), Operation::Shr => self.translate_primitive_call_shr("$shr", args), Operation::Implies => self.translate_logical_op("==>", args), Operation::Iff => self.translate_logical_op("<==>", args), @@ -1021,6 +1037,7 @@ impl SpecTranslator<'_> { Operation::Neq => self.translate_eq_neq("!$IsEqual", args), // Unary operators + Operation::Negate => self.translate_arithmetic_unary_op("-", args), Operation::Not => self.translate_logical_unary_op("!", args), Operation::Cast => self.translate_cast(node_id, args), Operation::Int2Bv => { @@ -1115,7 +1132,7 @@ impl SpecTranslator<'_> { let mut count = 0; for arg in &args[0..args.len() - 1] { emit!(self.writer, "ConcatVec("); - self.translate_call(node_id, oper, &[arg.clone()]); + self.translate_call(node_id, oper, std::slice::from_ref(arg)); emit!(self.writer, ","); count += 1; } @@ -1251,8 +1268,9 @@ impl SpecTranslator<'_> { .env .get_extension::() .expect("global number operation state"); - let is_vector_table_module = module_env.is_std_vector() || module_env.is_table(); - let bv_flag = if is_vector_table_module && !args.is_empty() { + let is_vector_table_cmp_module = + module_env.is_std_vector() || module_env.is_table() || module_env.is_cmp(); + let bv_flag = if is_vector_table_cmp_module && !args.is_empty() { global_state.get_node_num_oper(args[0].node_id()) == Bitwise } else { global_state.get_node_num_oper(node_id) == Bitwise @@ -1434,23 +1452,14 @@ impl SpecTranslator<'_> { fn translate_test_variants( &self, - node_id: NodeId, module_id: ModuleId, struct_id: StructId, variants: &[Symbol], args: &[Exp], ) { let struct_env = self.env.get_module(module_id).into_struct(struct_id); - if struct_env.is_intrinsic() { - self.env.error( - &self.env.get_node_loc(node_id), - "cannot test variants of intrinsic struct", - ); - } let struct_type = &self.get_node_type(args[0].node_id()); - let (_, _, _) = struct_type.skip_reference().require_struct(); - let inst = self.env.get_node_instantiation(node_id); - let inst = &self.inst_slice(&inst); + let (_, _, inst) = struct_type.skip_reference().require_struct(); let test_var_result = self.fresh_var_name("test_variant_var"); emit!(self.writer, "(var {} := ", test_var_result); self.translate_exp(&args[0]); @@ -2026,6 +2035,20 @@ impl SpecTranslator<'_> { emit!(self.writer, ")"); } + fn translate_arithmetic_unary_op(&self, boogie_op: &str, args: &[Exp]) { + let global_state = &self + .env + .get_extension::() + .expect("global number operation state"); + let num_oper_e = global_state.get_node_num_oper(args[0].node_id()); + assert!( + num_oper_e != Bitwise, + "no bitwise unary arithmetic ops supported" + ); + emit!(self.writer, "{}", boogie_op); + self.translate_exp(&args[0]); + } + fn translate_logical_unary_op(&self, boogie_op: &str, args: &[Exp]) { emit!(self.writer, "{}", boogie_op); self.translate_exp(&args[0]); @@ -2045,8 +2068,7 @@ impl SpecTranslator<'_> { .get_node_type(arg.node_id()) .skip_reference() .clone(); - let check_cast = - |ty: &Type| ty.is_number() && !matches!(ty, Type::Primitive(PrimitiveType::Num)); + let check_cast = |ty: &Type| ty.is_unsigned_int(); if cast_oper == Bitwise && check_cast(&target_type) && check_cast(&source_type) { let target_base = boogie_num_type_base(self.env, Some(self.env.get_node_loc(node_id)), &target_type); @@ -2094,13 +2116,28 @@ impl SpecTranslator<'_> { oper_right_base ); } else { + let ty = self.get_node_type(args[0].node_id()); + if matches!( + ty, + Type::Primitive(PrimitiveType::I8) + | Type::Primitive(PrimitiveType::I16) + | Type::Primitive(PrimitiveType::I32) + | Type::Primitive(PrimitiveType::I64) + | Type::Primitive(PrimitiveType::I128) + | Type::Primitive(PrimitiveType::I256) + ) { + self.error( + &self.env.get_node_loc(args[0].node_id()), + &format!("signed integer types not supported in operation {}", fun), + ); + } emit!(self.writer, "{}(", fun); } self.translate_seq(args.iter(), ", ", |e| self.translate_exp(e)); emit!(self.writer, ")"); } - fn translate_primitive_call_shl(&self, fun: &str, args: &[Exp]) { + fn translate_primitive_call_shl(&self, fun: &str, args: &[Exp], loc: &Loc) { let global_state = &self .env .get_extension::() @@ -2133,6 +2170,18 @@ impl SpecTranslator<'_> { Type::Primitive(PrimitiveType::U64) => "U64", Type::Primitive(PrimitiveType::U128) => "U128", Type::Primitive(PrimitiveType::U256) => "U256", + Type::Primitive(PrimitiveType::I8) + | Type::Primitive(PrimitiveType::I16) + | Type::Primitive(PrimitiveType::I32) + | Type::Primitive(PrimitiveType::I64) + | Type::Primitive(PrimitiveType::I128) + | Type::Primitive(PrimitiveType::I256) => { + self.error( + loc, + &format!("signed integer types not supported in operation {}", fun), + ); + "<>" + }, Type::Primitive(PrimitiveType::Num) => "", _ => unreachable!(), }; diff --git a/third_party/move/move-prover/bytecode-pipeline/Cargo.toml b/third_party/move/move-prover/bytecode-pipeline/Cargo.toml index 2d41dd22fa8..bc10362875a 100644 --- a/third_party/move/move-prover/bytecode-pipeline/Cargo.toml +++ b/third_party/move/move-prover/bytecode-pipeline/Cargo.toml @@ -3,11 +3,10 @@ name = "move-prover-bytecode-pipeline" version = "0.1.0" authors = ["Aptos Labs "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] -abstract-domain-derive = { path = "../../move-model/bytecode/abstract_domain_derive" } anyhow = { workspace = true } codespan-reporting = { workspace = true } itertools = { workspace = true } diff --git a/third_party/move/move-prover/bytecode-pipeline/src/clean_and_optimize.rs b/third_party/move/move-prover/bytecode-pipeline/src/clean_and_optimize.rs index 7339ac047cd..d4eaca3028f 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/clean_and_optimize.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/clean_and_optimize.rs @@ -131,6 +131,14 @@ impl TransferFunctions for Optimizer<'_> { } } }, + Invoke => { + // Need to assume effect + for src in srcs { + if self.target.get_local_type(*src).is_mutable_reference() { + state.unwritten.insert(Reference(*src)); + } + } + }, _ => {}, } } @@ -235,6 +243,13 @@ impl Optimizer<'_> { Call(_, _, WriteBack(..), srcs, _) if !is_unwritten(code_offset as CodeOffset, &Reference(srcs[0])) => { + // When current write-back is redundant, we can also remove the previous PackRefDeep + // because no need to check data invariant + if let Some(Call(_, _, PackRefDeep, srcs_pack, _)) = new_instrs.last() { + if srcs[0] == srcs_pack[0] { + new_instrs.pop(); + } + } continue; }, _ => {}, diff --git a/third_party/move/move-prover/bytecode-pipeline/src/data_invariant_instrumentation.rs b/third_party/move/move-prover/bytecode-pipeline/src/data_invariant_instrumentation.rs index 061b703bce0..4cb4002d0b4 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/data_invariant_instrumentation.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/data_invariant_instrumentation.rs @@ -300,16 +300,37 @@ impl<'a> Instrumenter<'a> { result.push((cond.loc.clone(), exp)); } - // If this is deep, recurse over all fields. + // If this is deep, recurse over all fields. For enum variants, need to guard the + // field invariants with an appropriate test. if deep { - for field_env in struct_env.get_fields() { - let field_exp = self - .builder - .mk_field_select(&field_env, targs, value.clone()); - result.extend(self.translate_invariant(deep, field_exp)); + if struct_env.has_variants() { + for variant in struct_env.get_variants() { + let is_variant = + self.builder + .mk_variant_test(&struct_env, variant, value.clone()); + for field_env in struct_env.get_fields_of_variant(variant) { + let field_exp = + self.builder + .mk_field_select(&field_env, targs, value.clone()); + result.extend(self.translate_invariant(deep, field_exp).iter().map( + |inv| { + ( + inv.0.clone(), + self.builder.mk_implies(is_variant.clone(), inv.1.clone()), + ) + }, + )); + } + } + } else { + for field_env in struct_env.get_fields() { + let field_exp = self + .builder + .mk_field_select(&field_env, targs, value.clone()); + result.extend(self.translate_invariant(deep, field_exp)); + } } } - result } } diff --git a/third_party/move/move-prover/bytecode-pipeline/src/lib.rs b/third_party/move/move-prover/bytecode-pipeline/src/lib.rs index 30dccd06635..cba4e34d082 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/lib.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/lib.rs @@ -14,7 +14,6 @@ pub mod mut_ref_instrumentation; pub mod number_operation; pub mod number_operation_analysis; pub mod options; -pub mod packed_types_analysis; pub mod pipeline_factory; pub mod spec_instrumentation; pub mod verification_analysis; diff --git a/third_party/move/move-prover/bytecode-pipeline/src/memory_instrumentation.rs b/third_party/move/move-prover/bytecode-pipeline/src/memory_instrumentation.rs index 97490c7d681..e6bc4fd3982 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/memory_instrumentation.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/memory_instrumentation.rs @@ -249,8 +249,8 @@ impl<'a> Instrumenter<'a> { // derive all the borrow edges that uniquely differentiate this chain let base = &tree[index]; - let diffs = tree - .iter() + // return the indices of the actions that differentiate this borrow chain + tree.iter() .enumerate() .filter_map(|(i, chain)| { if i == index { @@ -259,10 +259,7 @@ impl<'a> Instrumenter<'a> { Some(index_of_first_different_action(base, chain)) } }) - .collect(); - - // return the indices of the actions that differentiate this borrow chain - diffs + .collect() } fn write_back_chain( diff --git a/third_party/move/move-prover/bytecode-pipeline/src/mono_analysis.rs b/third_party/move/move-prover/bytecode-pipeline/src/mono_analysis.rs index 2f77f767ff4..f5d39cd1d94 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/mono_analysis.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/mono_analysis.rs @@ -6,6 +6,7 @@ //! computes the distinct type instantiations in the model for structs and inlined functions. use itertools::Itertools; +use move_core_types::{ability::AbilitySet, function::ClosureMask}; use move_model::{ ast, ast::{Condition, ConditionKind, ExpData}, @@ -46,6 +47,17 @@ pub struct MonoInfo { pub native_inst: BTreeMap>>, pub all_types: BTreeSet, pub axioms: Vec<(Condition, Vec>)>, + /// A map from function types used in the program to the closures appearing in + /// code constructing values of this function type. + pub fun_infos: BTreeMap>, +} + +#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq)] +pub struct ClosureInfo { + /// The function used to construct the closure. + pub fun: QualifiedInstId, + /// Closure mask used by the function. + pub mask: ClosureMask, } /// Get the information computed by this analysis. @@ -361,14 +373,15 @@ impl Analyzer<'_> { } } - fn analyze_bytecode(&mut self, _target: &FunctionTarget<'_>, bc: &Bytecode) { + fn analyze_bytecode(&mut self, target: &FunctionTarget<'_>, bc: &Bytecode) { use Bytecode::*; use Operation::*; - // We only need to analyze function calls, not `pack` or other instructions - // because the types those are using are reflected in locals which are analyzed + // For monomorphization, we only need to analyze function calls, not `pack` or other + // instructions because the types those are using are reflected in locals which are analyzed // elsewhere. match bc { - Call(_, _, Function(mid, fid, targs), ..) => { + Call(_, _, Function(mid, fid, targs), ..) + | Call(_, _, Closure(mid, fid, targs, ..), ..) => { let module_env = &self.env.get_module(*mid); let callee_env = module_env.get_function(*fid); let actuals = self.instantiate_vec(targs); @@ -412,6 +425,19 @@ impl Analyzer<'_> { self.todo_funs.push(entry); } } + + // Record closure construction under the type of the constructed closure. + // Notice we strip abilities here as the prover does not consider them. + if let Call(_, dests, Closure(_mid, _fid, _targs, mask), ..) = bc { + let fun_type = + self.normalize_fun_ty(self.instantiate(target.get_local_type(dests[0]))); + let fun = mid.qualified_inst(*fid, self.instantiate_vec(targs)); + self.info + .fun_infos + .entry(fun_type) + .or_default() + .insert(ClosureInfo { fun, mask: *mask }); + } }, Call(_, _, WriteBack(_, edge), ..) => { // In very rare occasions, not all types used in the function can appear in @@ -432,6 +458,28 @@ impl Analyzer<'_> { } } + /// Normalize a function type. This remove abilities which are abstracted by the prover, + /// as well as ensures that singleton tuples aren't present. The resulting type + /// can be used to index function types. + fn normalize_fun_ty(&self, ty: Type) -> Type { + let Type::Fun(params, results, _) = ty else { + panic!("expected fun type") + }; + Type::Fun( + Box::new(Type::tuple(params.flatten())), + Box::new(Type::tuple(results.flatten())), + AbilitySet::EMPTY, + ) + } + + fn instantiate(&self, ty: &Type) -> Type { + if let Some(inst) = &self.inst_opt { + ty.instantiate(inst) + } else { + ty.clone() + } + } + fn instantiate_vec(&self, targs: &[Type]) -> Vec { if let Some(inst) = &self.inst_opt { Type::instantiate_slice(targs, inst) @@ -536,6 +584,12 @@ impl Analyzer<'_> { return; } ty.visit(&mut |t| match t { + Type::Fun(..) => { + self.info + .fun_infos + .entry(self.normalize_fun_ty(t.clone())) + .or_default(); + }, Type::Vector(et) => { self.info.vec_inst.insert(et.as_ref().clone()); }, @@ -587,7 +641,7 @@ impl Analyzer<'_> { fn add_types_in_borrow_edge(&mut self, edge: &BorrowEdge) { match edge { - BorrowEdge::Direct | BorrowEdge::Index(_) => (), + BorrowEdge::Direct | BorrowEdge::Invoke | BorrowEdge::Index(_) => (), BorrowEdge::Field(qid, _, _) => { self.add_type_root(&qid.to_type()); }, diff --git a/third_party/move/move-prover/bytecode-pipeline/src/number_operation_analysis.rs b/third_party/move/move-prover/bytecode-pipeline/src/number_operation_analysis.rs index dabdee5284d..7f24d8793f6 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/number_operation_analysis.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/number_operation_analysis.rs @@ -842,6 +842,7 @@ impl TransferFunctions for NumberOperationAnalysis<'_> { baseline_flag, ); }, + BitOr | BitAnd | Xor => self.check_and_update_oper_dest( state, dests, @@ -1174,7 +1175,8 @@ impl TransferFunctions for NumberOperationAnalysis<'_> { } // empty, do nothing } }, - // TODO(#14349): add support for enum type related operation + // TODO(#14349): add support for enum type related operation and + // function values. _ => {}, } }, diff --git a/third_party/move/move-prover/bytecode-pipeline/src/packed_types_analysis.rs b/third_party/move/move-prover/bytecode-pipeline/src/packed_types_analysis.rs deleted file mode 100644 index d11774652bc..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/src/packed_types_analysis.rs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use abstract_domain_derive::AbstractDomain; -use move_binary_format::file_format::CodeOffset; -use move_core_types::language_storage::{StructTag, TypeTag}; -use move_model::{ - model::{FunctionEnv, GlobalEnv}, - ty::Type, -}; -use move_stackless_bytecode::{ - compositional_analysis::{CompositionalAnalysis, SummaryCache}, - dataflow_analysis::{DataflowAnalysis, TransferFunctions}, - dataflow_domains::{AbstractDomain, JoinResult, SetDomain}, - function_target::{FunctionData, FunctionTarget}, - function_target_pipeline::{FunctionTargetProcessor, FunctionTargetsHolder, FunctionVariant}, - stackless_bytecode::{Bytecode, Operation}, - COMPILED_MODULE_AVAILABLE, -}; -use std::collections::BTreeSet; - -/// Get all closed types that may be packed by (1) genesis and (2) all transaction scripts. -/// This makes some simplifying assumptions that are not correct in general, but hold for the -/// current Diem Framework: -/// - Transaction scripts have at most 1 type argument -/// - The only values that can be bound to a transaction script type argument are XUS and -/// XDX. Passing any other values will lead to an aborted transaction. -/// The first assumption is checked and will trigger an assert failure if violated. The second -/// is unchecked, but would be a nice property for the prover. -pub fn get_packed_types( - env: &GlobalEnv, - targets: &FunctionTargetsHolder, - coin_types: Vec, -) -> BTreeSet { - let mut packed_types = BTreeSet::new(); - for module_env in env.get_modules() { - let module_name = module_env - .get_identifier() - .expect(COMPILED_MODULE_AVAILABLE) - .to_string(); - let is_script = module_env.is_script_module(); - if is_script || module_name == "Genesis" { - for func_env in module_env.get_functions() { - let fun_target = targets.get_target(&func_env, &FunctionVariant::Baseline); - let annotation = fun_target - .get_annotations() - .get::() - .expect( - "Invariant violation: usage analysis should be run before calling this", - ); - - packed_types.extend(annotation.closed_types.clone()); - // instantiate the tx script open types with XUS, XDX - if is_script { - let num_type_parameters = func_env.get_type_parameters().len(); - assert!(num_type_parameters <= 1, "Assuming that transaction scripts have <= 1 type parameters for simplicity. If there can be >1 type parameter, the code here must account for all permutations of type params"); - - if num_type_parameters == 1 { - for open_ty in annotation.open_types.iter() { - for coin_ty in &coin_types { - match open_ty.instantiate(vec![coin_ty.clone()].as_slice()).into_type_tag(env) { - Some(TypeTag::Struct(s)) => { - packed_types.insert(*s); - } - _ => panic!("Invariant violation: failed to specialize tx script open type {:?} into struct", open_ty), - } - } - } - } - } - } - } - } - packed_types -} - -#[derive(AbstractDomain, Debug, Clone, Default, Eq, PartialOrd, PartialEq)] -struct PackedTypesState { - // Closed types (i.e., with no free type variables) that may be directly or transitively packed by this function. - closed_types: SetDomain, - // Open types (i.e., with free type variables) that may be directly or transitively packed by this function. - open_types: SetDomain, -} - -struct PackedTypesAnalysis<'a> { - cache: SummaryCache<'a>, -} - -impl TransferFunctions for PackedTypesAnalysis<'_> { - type State = PackedTypesState; - - const BACKWARD: bool = false; - - fn execute(&self, state: &mut Self::State, instr: &Bytecode, _offset: CodeOffset) { - use Bytecode::*; - use Operation::*; - - if let Call(_, _, oper, ..) = instr { - match oper { - Pack(mid, sid, types) => { - let env = self.cache.global_env(); - match env.get_struct_tag(*mid, *sid, types) { - Some(tag) => { - // type is closed - state.closed_types.insert(tag); - }, - None => { - // type is open - state - .open_types - .insert(Type::Struct(*mid, *sid, types.clone())); - }, - } - }, - Function(mid, fid, types) => { - if let Some(summary) = self - .cache - .get::(mid.qualified(*fid), &FunctionVariant::Baseline) - { - // add closed types - for ty in summary.closed_types.iter() { - state.closed_types.insert(ty.clone()); - } - // instantiate open types with the type parameters at this call site - for open_ty in summary.open_types.iter() { - let specialized_ty = open_ty.instantiate(types); - if specialized_ty.is_open() { - state.open_types.insert(specialized_ty); - } else if let Some(TypeTag::Struct(s)) = - specialized_ty.into_type_tag(self.cache.global_env()) - { - state.closed_types.insert(*s); - } else { - panic!("Invariant violation: struct type {:?} became non-struct type after substitution", open_ty) - } - } - } - // TODO(mengxu, sam): fix the recursive function case - }, - OpaqueCallBegin(_, _, _) | OpaqueCallEnd(_, _, _) => { - // skip - }, - _ => (), - } - } - } -} - -impl DataflowAnalysis for PackedTypesAnalysis<'_> {} -impl CompositionalAnalysis for PackedTypesAnalysis<'_> { - fn to_summary( - &self, - state: PackedTypesState, - _fun_target: &FunctionTarget, - ) -> PackedTypesState { - state - } -} - -pub struct PackedTypesProcessor(); -impl PackedTypesProcessor { - pub fn new() -> Box { - Box::new(PackedTypesProcessor()) - } -} - -impl FunctionTargetProcessor for PackedTypesProcessor { - fn process( - &self, - targets: &mut FunctionTargetsHolder, - func_env: &FunctionEnv, - mut data: FunctionData, - _scc_opt: Option<&[FunctionEnv]>, - ) -> FunctionData { - let initial_state = PackedTypesState::default(); - let fun_target = FunctionTarget::new(func_env, &data); - let cache = SummaryCache::new(targets, func_env.module_env.env); - let analysis = PackedTypesAnalysis { cache }; - let summary = analysis.summarize(&fun_target, initial_state); - // TODO(mengxu, sam): recursion seems to have an impact on how this analysis are conducted, - // resolve the TODO item above in the code and update the fixedpoint calculation logic here. - data.annotations.set(summary, true); - data - } - - fn name(&self) -> String { - "packed_types_analysis".to_string() - } -} diff --git a/third_party/move/move-prover/bytecode-pipeline/src/verification_analysis.rs b/third_party/move/move-prover/bytecode-pipeline/src/verification_analysis.rs index 1dbede38b2e..0efcb6dd1ea 100644 --- a/third_party/move/move-prover/bytecode-pipeline/src/verification_analysis.rs +++ b/third_party/move/move-prover/bytecode-pipeline/src/verification_analysis.rs @@ -423,7 +423,7 @@ impl VerificationAnalysisProcessor { /// `mark_inlined` function above. fn mark_callees_inlined(fun_env: &FunctionEnv, targets: &mut FunctionTargetsHolder) { for callee in fun_env - .get_called_functions() + .get_used_functions() .expect(COMPILED_MODULE_AVAILABLE) { let callee_env = fun_env.module_env.env.get_function(*callee); @@ -469,16 +469,16 @@ impl VerificationAnalysisProcessor { } } // Downward closure of the non_inv_fun_set - while let Some(called_fun_id) = worklist.pop() { - let called_funs = env - .get_function(called_fun_id) - .get_called_functions() + while let Some(used_fun_id) = worklist.pop() { + let used_funs = env + .get_function(used_fun_id) + .get_used_functions() .cloned() .expect(COMPILED_MODULE_AVAILABLE); - for called_fun_id in called_funs { - if non_inv_fun_set.insert(called_fun_id) { + for fun_id in used_funs { + if non_inv_fun_set.insert(fun_id) { // Add to work_list only if fun_id is not in fun_set - worklist.push(called_fun_id); + worklist.push(fun_id); } } } @@ -670,10 +670,7 @@ impl VerificationAnalysisProcessor { for (fun_id, mut relevance) in pruned.into_iter() { if !fun_set_with_no_inv_check.contains(&fun_id) { let fenv = env.get_function(fun_id); - for callee in fenv - .get_called_functions() - .expect(COMPILED_MODULE_AVAILABLE) - { + for callee in fenv.get_used_functions().expect(COMPILED_MODULE_AVAILABLE) { if fun_set_with_no_inv_check.contains(callee) { // all invariants in the callee side will now be deferred to this function let suspended = deferred.get(callee).unwrap(); diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/borrow.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/borrow.v2_exp deleted file mode 100644 index 01f5a92eabc..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/borrow.v2_exp +++ /dev/null @@ -1,197 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::test_borrow_imm<#0>(): u64 { - var $t0: address - var $t1: &0x42::Test::R<#0> - var $t2: &u64 - var $t3: u64 - 0: $t0 := 0x1 - 1: $t1 := borrow_global<0x42::Test::R<#0>>($t0) - 2: $t2 := borrow_field<0x42::Test::R<#0>>.x($t1) - 3: $t3 := read_ref($t2) - 4: return $t3 -} - - -[variant baseline] -public fun Test::test_borrow_mut<#0>(): u64 { - var $t0|r: &mut 0x42::Test::R<#0> - var $t1: address - var $t2: &mut 0x42::Test::R<#0> - var $t3: u64 - var $t4: &mut 0x42::Test::R<#0> - var $t5: &mut 0x42::Test::S - var $t6: &mut u64 - var $t7: u64 - var $t8: &mut 0x42::Test::R<#0> - var $t9: &mut u64 - var $t10: &mut 0x42::Test::R<#0> - var $t11: &u64 - var $t12: u64 - 0: $t1 := 0x1 - 1: $t2 := borrow_global<0x42::Test::R<#0>>($t1) - 2: $t0 := $t2 - 3: $t3 := 2 - 4: $t4 := copy($t0) - 5: $t5 := borrow_field<0x42::Test::R<#0>>.s($t4) - 6: $t6 := borrow_field<0x42::Test::S>.y($t5) - 7: write_ref($t6, $t3) - 8: $t7 := 3 - 9: $t8 := copy($t0) - 10: $t9 := borrow_field<0x42::Test::R<#0>>.x($t8) - 11: write_ref($t9, $t7) - 12: $t10 := move($t0) - 13: $t11 := borrow_field<0x42::Test::R<#0>>.x($t10) - 14: $t12 := read_ref($t11) - 15: return $t12 -} - - -[variant baseline] -public fun Test::test_borrow_mut_local(): 0x42::Test::R { - var $t0|d: 0x42::Test::R - var $t1|r: &mut 0x42::Test::R - var $t2: u64 - var $t3: u64 - var $t4: 0x42::Test::S - var $t5: u64 - var $t6: 0x42::Test::R - var $t7: &mut 0x42::Test::R - var $t8: u64 - var $t9: &mut 0x42::Test::R - var $t10: &mut 0x42::Test::S - var $t11: &mut u64 - var $t12: u64 - var $t13: &mut 0x42::Test::R - var $t14: &mut u64 - var $t15: 0x42::Test::R - 0: $t2 := 2 - 1: $t3 := 1 - 2: $t4 := pack 0x42::Test::S($t3) - 3: $t5 := 0 - 4: $t6 := pack 0x42::Test::R($t2, $t4, $t5) - 5: $t0 := $t6 - 6: $t7 := borrow_local($t0) - 7: $t1 := $t7 - 8: $t8 := 2 - 9: $t9 := copy($t1) - 10: $t10 := borrow_field<0x42::Test::R>.s($t9) - 11: $t11 := borrow_field<0x42::Test::S>.y($t10) - 12: write_ref($t11, $t8) - 13: $t12 := 3 - 14: $t13 := move($t1) - 15: $t14 := borrow_field<0x42::Test::R>.x($t13) - 16: write_ref($t14, $t12) - 17: $t15 := move($t0) - 18: return $t15 -} - -============ after pipeline `data_invariant_instrumentation` ================ - -[variant verification] -public fun Test::test_borrow_imm<#0>(): u64 { - var $t0: address - var $t1: 0x42::Test::R<#0> - var $t2: num - var $t3: u64 - 0: assume forall $rsc: 0x42::Test::R<#0>: ResourceDomain<0x42::Test::R<#0>>(): And(WellFormed($rsc), And(Gt(select Test::R.x($rsc), select Test::S.y<0x42::Test::S>(select Test::R.s($rsc))), Gt(select Test::S.y(select Test::R.s($rsc)), 0))) - 1: $t0 := 0x1 - 2: $t1 := get_global<0x42::Test::R<#0>>($t0) on_abort goto 6 with $t2 - 3: $t3 := get_field<0x42::Test::R<#0>>.x($t1) - 4: label L1 - 5: return $t3 - 6: label L2 - 7: abort($t2) -} - - -[variant verification] -public fun Test::test_borrow_mut<#0>(): u64 { - var $t0|r: &mut 0x42::Test::R<#0> - var $t1: address - var $t2: &mut 0x42::Test::R<#0> - var $t3: num - var $t4: u64 - var $t5: &mut 0x42::Test::S - var $t6: &mut u64 - var $t7: u64 - var $t8: &mut u64 - var $t9: u64 - 0: assume forall $rsc: 0x42::Test::R<#0>: ResourceDomain<0x42::Test::R<#0>>(): And(WellFormed($rsc), And(Gt(select Test::R.x($rsc), select Test::S.y<0x42::Test::S>(select Test::R.s($rsc))), Gt(select Test::S.y(select Test::R.s($rsc)), 0))) - 1: $t1 := 0x1 - 2: $t2 := borrow_global<0x42::Test::R<#0>>($t1) on_abort goto 19 with $t3 - 3: $t4 := 2 - 4: $t5 := borrow_field<0x42::Test::R<#0>>.s($t2) - 5: $t6 := borrow_field<0x42::Test::S>.y($t5) - 6: write_ref($t6, $t4) - 7: write_back[Reference($t5).y (u64)]($t6) - 8: write_back[Reference($t2).s (0x42::Test::S)]($t5) - 9: $t7 := 3 - 10: $t8 := borrow_field<0x42::Test::R<#0>>.x($t2) - 11: write_ref($t8, $t7) - 12: write_back[Reference($t2).x (u64)]($t8) - 13: $t9 := get_field<0x42::Test::R<#0>>.x($t2) - # data invariant at tests/data_invariant_instrumentation/borrow.move:13:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:13:9+18 - 14: assert Gt(select Test::R.x($t2), select Test::S.y<0x42::Test::S>(select Test::R.s($t2))) - # data invariant at tests/data_invariant_instrumentation/borrow.move:17:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:17:9+16 - 15: assert Gt(select Test::S.y(select Test::R.s($t2)), 0) - 16: write_back[0x42::Test::R<#0>@]($t2) - 17: label L1 - 18: return $t9 - 19: label L2 - 20: abort($t3) -} - - -[variant verification] -public fun Test::test_borrow_mut_local(): 0x42::Test::R { - var $t0|d: 0x42::Test::R - var $t1|r: &mut 0x42::Test::R - var $t2: u64 - var $t3: u64 - var $t4: 0x42::Test::S - var $t5: u64 - var $t6: &mut 0x42::Test::R - var $t7: u64 - var $t8: &mut 0x42::Test::S - var $t9: &mut u64 - var $t10: u64 - var $t11: &mut u64 - var $t12: 0x42::Test::R - 0: $t2 := 2 - 1: $t3 := 1 - 2: $t4 := pack 0x42::Test::S($t3) - # data invariant at tests/data_invariant_instrumentation/borrow.move:17:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:17:9+16 - 3: assert Gt(select Test::S.y($t4), 0) - 4: $t5 := 0 - 5: $t0 := pack 0x42::Test::R($t2, $t4, $t5) - # data invariant at tests/data_invariant_instrumentation/borrow.move:13:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:13:9+18 - 6: assert Gt(select Test::R.x($t0), select Test::S.y<0x42::Test::S>(select Test::R.s($t0))) - 7: $t6 := borrow_local($t0) - 8: $t7 := 2 - 9: $t8 := borrow_field<0x42::Test::R>.s($t6) - 10: $t9 := borrow_field<0x42::Test::S>.y($t8) - 11: write_ref($t9, $t7) - 12: write_back[Reference($t8).y (u64)]($t9) - 13: write_back[Reference($t6).s (0x42::Test::S)]($t8) - 14: $t10 := 3 - 15: $t11 := borrow_field<0x42::Test::R>.x($t6) - 16: write_ref($t11, $t10) - 17: write_back[Reference($t6).x (u64)]($t11) - # data invariant at tests/data_invariant_instrumentation/borrow.move:13:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:13:9+18 - 18: assert Gt(select Test::R.x($t6), select Test::S.y<0x42::Test::S>(select Test::R.s($t6))) - # data invariant at tests/data_invariant_instrumentation/borrow.move:17:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/borrow.move:17:9+16 - 19: assert Gt(select Test::S.y(select Test::R.s($t6)), 0) - 20: write_back[LocalRoot($t0)@]($t6) - 21: trace_local[d]($t0) - 22: $t12 := move($t0) - 23: label L1 - 24: return $t12 -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/pack.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/pack.v2_exp deleted file mode 100644 index 61ccf20a63d..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/pack.v2_exp +++ /dev/null @@ -1,36 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::test_pack(): 0x42::Test::R { - var $t0: u64 - var $t1: u64 - var $t2: 0x42::Test::S - var $t3: 0x42::Test::R - 0: $t0 := 3 - 1: $t1 := 1 - 2: $t2 := pack 0x42::Test::S($t1) - 3: $t3 := pack 0x42::Test::R($t0, $t2) - 4: return $t3 -} - -============ after pipeline `data_invariant_instrumentation` ================ - -[variant verification] -public fun Test::test_pack(): 0x42::Test::R { - var $t0: u64 - var $t1: u64 - var $t2: 0x42::Test::S - var $t3: 0x42::Test::R - 0: $t0 := 3 - 1: $t1 := 1 - 2: $t2 := pack 0x42::Test::S($t1) - # data invariant at tests/data_invariant_instrumentation/pack.move:16:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/pack.move:16:9+16 - 3: assert Gt(select Test::S.y($t2), 0) - 4: $t3 := pack 0x42::Test::R($t0, $t2) - # data invariant at tests/data_invariant_instrumentation/pack.move:12:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/pack.move:12:9+18 - 5: assert Gt(select Test::R.x($t3), select Test::S.y<0x42::Test::S>(select Test::R.s($t3))) - 6: label L1 - 7: return $t3 -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/params.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/params.v2_exp deleted file mode 100644 index 6082ece7d2a..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/params.v2_exp +++ /dev/null @@ -1,25 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::test_param($t0|_simple_R: 0x42::Test::R, $t1|_ref_R: &0x42::Test::R, $t2|_simple_S: 0x42::Test::S, $t3|_mut_R: &mut 0x42::Test::R) { - 0: return () -} - -============ after pipeline `data_invariant_instrumentation` ================ - -[variant verification] -public fun Test::test_param($t0|_simple_R: 0x42::Test::R, $t1|_ref_R: 0x42::Test::R, $t2|_simple_S: 0x42::Test::S, $t3|_mut_R: &mut 0x42::Test::R) { - 0: assume And(WellFormed($t0), And(Gt(select Test::R.x($t0), select Test::S.y<0x42::Test::S>(select Test::R.s($t0))), Gt(select Test::S.y(select Test::R.s($t0)), 0))) - 1: assume And(WellFormed($t1), And(Gt(select Test::R.x($t1), select Test::S.y<0x42::Test::S>(select Test::R.s($t1))), Gt(select Test::S.y(select Test::R.s($t1)), 0))) - 2: assume And(WellFormed($t2), Gt(select Test::S.y($t2), 0)) - 3: assume And(WellFormed($t3), And(Gt(select Test::R.x($t3), select Test::S.y<0x42::Test::S>(select Test::R.s($t3))), Gt(select Test::S.y(select Test::R.s($t3)), 0))) - 4: trace_local[_mut_R]($t3) - # data invariant at tests/data_invariant_instrumentation/params.move:12:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/params.move:12:9+18 - 5: assert Gt(select Test::R.x($t3), select Test::S.y<0x42::Test::S>(select Test::R.s($t3))) - # data invariant at tests/data_invariant_instrumentation/params.move:16:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/params.move:16:9+16 - 6: assert Gt(select Test::S.y(select Test::R.s($t3)), 0) - 7: label L1 - 8: return () -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/vector.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/vector.v2_exp deleted file mode 100644 index ea035bed6ae..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/data_invariant_instrumentation/vector.v2_exp +++ /dev/null @@ -1,15 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::test($t0|_r: 0x42::Test::R) { - 0: return () -} - -============ after pipeline `data_invariant_instrumentation` ================ - -[variant verification] -public fun Test::test($t0|_r: 0x42::Test::R) { - 0: assume And(WellFormed($t0), forall $elem: vector<0x42::Test::S>: select Test::R.s($t0): forall $elem: 0x42::Test::S: $elem: Gt(select Test::S.y($elem), 0)) - 1: label L1 - 2: return () -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/eliminate_imm_refs/basic_test.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/eliminate_imm_refs/basic_test.v2_exp deleted file mode 100644 index 65f119cf04a..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/eliminate_imm_refs/basic_test.v2_exp +++ /dev/null @@ -1,176 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun TestEliminateImmRefs::test1(): 0x42::TestEliminateImmRefs::R { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1|x_ref: &mut u64 - var $t2: u64 - var $t3: 0x42::TestEliminateImmRefs::R - var $t4: &mut 0x42::TestEliminateImmRefs::R - var $t5: &mut u64 - var $t6: u64 - var $t7: &mut u64 - var $t8: 0x42::TestEliminateImmRefs::R - 0: $t2 := 3 - 1: $t3 := pack 0x42::TestEliminateImmRefs::R($t2) - 2: $t0 := $t3 - 3: $t4 := borrow_local($t0) - 4: $t5 := borrow_field<0x42::TestEliminateImmRefs::R>.x($t4) - 5: $t1 := $t5 - 6: $t6 := 0 - 7: $t7 := move($t1) - 8: write_ref($t7, $t6) - 9: $t8 := move($t0) - 10: return $t8 -} - - -[variant baseline] -fun TestEliminateImmRefs::test2(): u64 { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: &0x42::TestEliminateImmRefs::R - var $t4: &u64 - var $t5: u64 - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := borrow_field<0x42::TestEliminateImmRefs::R>.x($t3) - 5: $t5 := read_ref($t4) - 6: return $t5 -} - - -[variant baseline] -fun TestEliminateImmRefs::test3($t0|r_ref: &0x42::TestEliminateImmRefs::R): u64 { - var $t1: &0x42::TestEliminateImmRefs::R - var $t2: &u64 - var $t3: u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_field<0x42::TestEliminateImmRefs::R>.x($t1) - 2: $t3 := read_ref($t2) - 3: return $t3 -} - - -[variant baseline] -fun TestEliminateImmRefs::test4(): u64 { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: &0x42::TestEliminateImmRefs::R - var $t4: u64 - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := TestEliminateImmRefs::test3($t3) - 5: return $t4 -} - - -[variant baseline] -fun TestEliminateImmRefs::test5(): 0x42::TestEliminateImmRefs::R { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: &0x42::TestEliminateImmRefs::R - var $t4: 0x42::TestEliminateImmRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: drop($t3) - 5: $t4 := move($t0) - 6: return $t4 -} - -============ after pipeline `eliminate_imm_refs` ================ - -[variant baseline] -fun TestEliminateImmRefs::test1(): 0x42::TestEliminateImmRefs::R { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1|x_ref: &mut u64 - var $t2: u64 - var $t3: 0x42::TestEliminateImmRefs::R - var $t4: &mut 0x42::TestEliminateImmRefs::R - var $t5: &mut u64 - var $t6: u64 - var $t7: &mut u64 - var $t8: 0x42::TestEliminateImmRefs::R - 0: $t2 := 3 - 1: $t3 := pack 0x42::TestEliminateImmRefs::R($t2) - 2: $t0 := $t3 - 3: $t4 := borrow_local($t0) - 4: $t5 := borrow_field<0x42::TestEliminateImmRefs::R>.x($t4) - 5: $t1 := $t5 - 6: $t6 := 0 - 7: $t7 := move($t1) - 8: write_ref($t7, $t6) - 9: $t8 := move($t0) - 10: return $t8 -} - - -[variant baseline] -fun TestEliminateImmRefs::test2(): u64 { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: 0x42::TestEliminateImmRefs::R - var $t4: u64 - var $t5: u64 - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := copy($t0) - 4: $t4 := get_field<0x42::TestEliminateImmRefs::R>.x($t3) - 5: $t5 := move($t4) - 6: return $t5 -} - - -[variant baseline] -fun TestEliminateImmRefs::test3($t0|r_ref: 0x42::TestEliminateImmRefs::R): u64 { - var $t1: 0x42::TestEliminateImmRefs::R - var $t2: u64 - var $t3: u64 - 0: $t1 := move($t0) - 1: $t2 := get_field<0x42::TestEliminateImmRefs::R>.x($t1) - 2: $t3 := move($t2) - 3: return $t3 -} - - -[variant baseline] -fun TestEliminateImmRefs::test4(): u64 { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: 0x42::TestEliminateImmRefs::R - var $t4: u64 - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := copy($t0) - 4: $t4 := TestEliminateImmRefs::test3($t3) - 5: return $t4 -} - - -[variant baseline] -fun TestEliminateImmRefs::test5(): 0x42::TestEliminateImmRefs::R { - var $t0|r: 0x42::TestEliminateImmRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateImmRefs::R - var $t3: 0x42::TestEliminateImmRefs::R - var $t4: 0x42::TestEliminateImmRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateImmRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := copy($t0) - 4: $t4 := move($t0) - 5: return $t4 -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/disable_in_body.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/disable_in_body.v2_exp deleted file mode 100644 index 4f91e8b19bc..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/disable_in_body.v2_exp +++ /dev/null @@ -1,54 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun DisableInv::foo($t0|s: &signer) { - var $t1: &signer - var $t2: bool - var $t3: 0x1::DisableInv::R2 - 0: $t1 := move($t0) - 1: $t2 := false - 2: $t3 := pack 0x1::DisableInv::R2($t2) - 3: move_to<0x1::DisableInv::R2>($t3, $t1) - 4: return () -} - -============ after pipeline `global_invariant_analysis` ================ - -[variant verification] -fun DisableInv::foo($t0|s: signer) { - var $t1: bool - var $t2: 0x1::DisableInv::R2 - var $t3: num - 0: $t1 := false - 1: $t2 := pack 0x1::DisableInv::R2($t1) - 2: move_to<0x1::DisableInv::R2>($t2, $t0) on_abort goto 5 with $t3 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t3) -} - - -********* Result of global invariant instrumentation ********* - -DisableInv::foo: [ - entrypoint { - assume @0 = [ - <> -> [ - <> - ] - ] - } - 2: move_to<0x1::DisableInv::R2>($t2, $t0) on_abort goto L2 with $t3 {} - exitpoint { - assert @0 = [ - <> -> [ - <> - ] - ] - } -] - -********* Global invariants by ID ********* - -@0 => invariant [suspendable] forall a: address where exists(a): exists(a); diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/mutual_inst.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/mutual_inst.v2_exp deleted file mode 100644 index 0dfc46750bb..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/mutual_inst.v2_exp +++ /dev/null @@ -1,418 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun S::publish_u64_bool($t0|account: signer, $t1|x: u64, $t2|y: bool) { - var $t3: &signer - var $t4: u64 - var $t5: bool - var $t6: u8 - var $t7: 0x2::S::Storage - 0: $t3 := borrow_local($t0) - 1: $t4 := move($t1) - 2: $t5 := move($t2) - 3: $t6 := 0 - 4: $t7 := pack 0x2::S::Storage($t4, $t5, $t6) - 5: move_to<0x2::S::Storage>($t7, $t3) - 6: return () -} - - -[variant baseline] -public fun S::publish_u64_y<#0>($t0|account: signer, $t1|x: u64, $t2|y: #0) { - var $t3: &signer - var $t4: u64 - var $t5: #0 - var $t6: u8 - var $t7: 0x2::S::Storage - 0: $t3 := borrow_local($t0) - 1: $t4 := move($t1) - 2: $t5 := move($t2) - 3: $t6 := 1 - 4: $t7 := pack 0x2::S::Storage($t4, $t5, $t6) - 5: move_to<0x2::S::Storage>($t7, $t3) - 6: return () -} - - -[variant baseline] -public fun S::publish_x_bool<#0>($t0|account: signer, $t1|x: #0, $t2|y: bool) { - var $t3: &signer - var $t4: #0 - var $t5: bool - var $t6: u8 - var $t7: 0x2::S::Storage<#0, bool> - 0: $t3 := borrow_local($t0) - 1: $t4 := move($t1) - 2: $t5 := move($t2) - 3: $t6 := 2 - 4: $t7 := pack 0x2::S::Storage<#0, bool>($t4, $t5, $t6) - 5: move_to<0x2::S::Storage<#0, bool>>($t7, $t3) - 6: return () -} - - -[variant baseline] -public fun S::publish_x_y<#0, #1>($t0|account: signer, $t1|x: #0, $t2|y: #1) { - var $t3: &signer - var $t4: #0 - var $t5: #1 - var $t6: u8 - var $t7: 0x2::S::Storage<#0, #1> - 0: $t3 := borrow_local($t0) - 1: $t4 := move($t1) - 2: $t5 := move($t2) - 3: $t6 := 3 - 4: $t7 := pack 0x2::S::Storage<#0, #1>($t4, $t5, $t6) - 5: move_to<0x2::S::Storage<#0, #1>>($t7, $t3) - 6: return () -} - - -[variant baseline] -public fun A::good($t0|account1: signer, $t1|account2: signer) { - var $t2: signer - var $t3: u64 - var $t4: bool - var $t5: signer - var $t6: u64 - var $t7: bool - 0: $t2 := move($t0) - 1: $t3 := 1 - 2: $t4 := true - 3: S::publish_x_y($t2, $t3, $t4) - 4: $t5 := move($t1) - 5: $t6 := 1 - 6: $t7 := true - 7: S::publish_x_y($t5, $t6, $t7) - 8: return () -} - -============ after pipeline `global_invariant_analysis` ================ - -[variant verification] -public fun S::publish_u64_bool($t0|account: signer, $t1|x: u64, $t2|y: bool) { - var $t3: u8 - var $t4: 0x2::S::Storage - var $t5: num - 0: $t3 := 0 - 1: $t4 := pack 0x2::S::Storage($t1, $t2, $t3) - 2: move_to<0x2::S::Storage>($t4, $t0) on_abort goto 5 with $t5 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t5) -} - - -[variant verification] -public fun S::publish_u64_y<#0>($t0|account: signer, $t1|x: u64, $t2|y: #0) { - var $t3: u8 - var $t4: 0x2::S::Storage - var $t5: num - 0: $t3 := 1 - 1: $t4 := pack 0x2::S::Storage($t1, $t2, $t3) - 2: move_to<0x2::S::Storage>($t4, $t0) on_abort goto 5 with $t5 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t5) -} - - -[variant verification] -public fun S::publish_x_bool<#0>($t0|account: signer, $t1|x: #0, $t2|y: bool) { - var $t3: u8 - var $t4: 0x2::S::Storage<#0, bool> - var $t5: num - 0: $t3 := 2 - 1: $t4 := pack 0x2::S::Storage<#0, bool>($t1, $t2, $t3) - 2: move_to<0x2::S::Storage<#0, bool>>($t4, $t0) on_abort goto 5 with $t5 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t5) -} - - -[variant baseline] -public fun S::publish_x_y<#0, #1>($t0|account: signer, $t1|x: #0, $t2|y: #1) { - var $t3: u8 - var $t4: 0x2::S::Storage<#0, #1> - var $t5: num - 0: $t3 := 3 - 1: $t4 := pack 0x2::S::Storage<#0, #1>($t1, $t2, $t3) - 2: move_to<0x2::S::Storage<#0, #1>>($t4, $t0) on_abort goto 5 with $t5 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t5) -} - - -[variant verification] -public fun S::publish_x_y<#0, #1>($t0|account: signer, $t1|x: #0, $t2|y: #1) { - var $t3: u8 - var $t4: 0x2::S::Storage<#0, #1> - var $t5: num - 0: $t3 := 3 - 1: $t4 := pack 0x2::S::Storage<#0, #1>($t1, $t2, $t3) - 2: move_to<0x2::S::Storage<#0, #1>>($t4, $t0) on_abort goto 5 with $t5 - 3: label L1 - 4: return () - 5: label L2 - 6: abort($t5) -} - - -[variant verification] -public fun A::good($t0|account1: signer, $t1|account2: signer) { - var $t2: u64 - var $t3: bool - var $t4: num - var $t5: u64 - var $t6: bool - 0: $t2 := 1 - 1: $t3 := true - 2: S::publish_x_y($t0, $t2, $t3) on_abort goto 8 with $t4 - 3: $t5 := 1 - 4: $t6 := true - 5: S::publish_x_y($t1, $t5, $t6) on_abort goto 8 with $t4 - 6: label L1 - 7: return () - 8: label L2 - 9: abort($t4) -} - - -********* Result of global invariant instrumentation ********* - -S::publish_u64_bool: [ - entrypoint { - assume @0 = [ - <> -> [ - <> - ] - ] - assume @1 = [ - <> -> [ - - ] - ] - assume @2 = [ - <> -> [ - - ] - ] - assume @3 = [ - <> -> [ - - ] - ] - } - 2: move_to<0x2::S::Storage>($t4, $t0) on_abort goto L2 with $t5 { - assert @0 = [ - <> -> [ - <> - ] - ] - assert @1 = [ - <> -> [ - - ] - ] - assert @2 = [ - <> -> [ - - ] - ] - assert @3 = [ - <> -> [ - - ] - ] - } - exitpoint {} -] -S::publish_u64_y: [ - entrypoint { - assume @0 = [ - -> [ - <> - ] - ] - assume @1 = [ - <#0> -> [ - <#0> - ] - ] - assume @2 = [ - -> [ - - ] - ] - assume @3 = [ - <#0> -> [ - - ] - ] - } - 2: move_to<0x2::S::Storage>($t4, $t0) on_abort goto L2 with $t5 { - assert @0 = [ - -> [ - <> - ] - ] - assert @1 = [ - <#0> -> [ - <#0> - ] - ] - assert @2 = [ - -> [ - - ] - ] - assert @3 = [ - <#0> -> [ - - ] - ] - } - exitpoint {} -] -S::publish_x_bool: [ - entrypoint { - assume @0 = [ - -> [ - <> - ] - ] - assume @1 = [ - -> [ - - ] - ] - assume @2 = [ - <#0> -> [ - <#0> - ] - ] - assume @3 = [ - <#0> -> [ - <#0, bool> - ] - ] - } - 2: move_to<0x2::S::Storage<#0, bool>>($t4, $t0) on_abort goto L2 with $t5 { - assert @0 = [ - -> [ - <> - ] - ] - assert @1 = [ - -> [ - - ] - ] - assert @2 = [ - <#0> -> [ - <#0> - ] - ] - assert @3 = [ - <#0> -> [ - <#0, bool> - ] - ] - } - exitpoint {} -] -S::publish_x_y: [ - entrypoint { - assume @0 = [ - -> [ - <> - ] - ] - assume @1 = [ - -> [ - <#1> - ] - ] - assume @2 = [ - <#0, bool> -> [ - <#0> - ] - ] - assume @3 = [ - <#0, #1> -> [ - <#0, #1> - ] - ] - } - 2: move_to<0x2::S::Storage<#0, #1>>($t4, $t0) on_abort goto L2 with $t5 { - assert @0 = [ - -> [ - <> - ] - ] - assert @1 = [ - -> [ - <#1> - ] - ] - assert @2 = [ - <#0, bool> -> [ - <#0> - ] - ] - assert @3 = [ - <#0, #1> -> [ - <#0, #1> - ] - ] - } - exitpoint {} -] -A::good: [ - entrypoint { - assume @0 = [ - <> -> [ - <> - ] - ] - assume @1 = [ - <> -> [ - - ] - ] - assume @2 = [ - <> -> [ - - ] - ] - assume @3 = [ - <> -> [ - - ] - ] - } - 2: S::publish_x_y($t0, $t2, $t3) on_abort goto L2 with $t4 {} - 5: S::publish_x_y($t1, $t5, $t6) on_abort goto L2 with $t4 {} - exitpoint {} -] - -********* Global invariants by ID ********* - -@0 => invariant - exists>(@0x22) - ==> global>(@0x22).x == 1; -@1 => invariant - exists>(@0x23) - ==> global>(@0x23).x > 0; -@2 => invariant - exists>(@0x24) - ==> global>(@0x24).y; -@3 => invariant - (exists>(@0x25) && exists>(@0x26)) - ==> global>(@0x25) == global>(@0x26); diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.exp index ba4a290369a..882bd488f00 100644 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.exp +++ b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.exp @@ -28,14 +28,14 @@ fun Demo::f1($t0|addr: address) { 11: $t7 := copy($t0) 12: $t8 := exists<0x42::Demo::S1>($t7) 13: if ($t8) goto 14 else goto 21 - 14: label L3 + 14: label L4 15: $t9 := 0 16: $t10 := move($t0) 17: $t11 := borrow_global<0x42::Demo::S1>($t10) 18: $t12 := borrow_field<0x42::Demo::S1>.v($t11) 19: write_ref($t12, $t9) - 20: goto 21 - 21: label L5 + 20: return () + 21: label L3 22: return () } @@ -56,26 +56,27 @@ fun Demo::f1($t0|addr: address) { 1: if ($t1) goto 2 else goto 9 2: label L0 3: $t2 := 0 - 4: $t3 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 22 with $t4 + 4: $t3 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 23 with $t4 5: $t5 := borrow_field<0x42::Demo::S1>.v($t3) 6: write_ref($t5, $t2) 7: write_back[Reference($t3).v (u8)]($t5) 8: write_back[0x42::Demo::S1@]($t3) 9: label L2 10: $t6 := exists<0x42::Demo::S1>($t0) - 11: if ($t6) goto 12 else goto 19 - 12: label L3 + 11: if ($t6) goto 12 else goto 20 + 12: label L4 13: $t7 := 0 - 14: $t8 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 22 with $t4 + 14: $t8 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 23 with $t4 15: $t9 := borrow_field<0x42::Demo::S1>.v($t8) 16: write_ref($t9, $t7) 17: write_back[Reference($t8).v (u8)]($t9) 18: write_back[0x42::Demo::S1@]($t8) - 19: label L5 - 20: label L6 - 21: return () - 22: label L7 - 23: abort($t4) + 19: goto 21 + 20: label L3 + 21: label L5 + 22: return () + 23: label L6 + 24: abort($t4) } diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.v2_exp deleted file mode 100644 index 51b2dcd360f..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_analysis/uninst_type_param_in_inv.v2_exp +++ /dev/null @@ -1,116 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun Demo::f1($t0|addr: address) { - var $t1: address - var $t2: bool - var $t3: u8 - var $t4: address - var $t5: &mut 0x42::Demo::S1 - var $t6: &mut u8 - var $t7: address - var $t8: bool - var $t9: u8 - var $t10: address - var $t11: &mut 0x42::Demo::S1 - var $t12: &mut u8 - 0: $t1 := copy($t0) - 1: $t2 := exists<0x42::Demo::S1>($t1) - 2: if ($t2) goto 3 else goto 10 - 3: label L1 - 4: $t3 := 0 - 5: $t4 := copy($t0) - 6: $t5 := borrow_global<0x42::Demo::S1>($t4) - 7: $t6 := borrow_field<0x42::Demo::S1>.v($t5) - 8: write_ref($t6, $t3) - 9: goto 10 - 10: label L0 - 11: $t7 := copy($t0) - 12: $t8 := exists<0x42::Demo::S1>($t7) - 13: if ($t8) goto 14 else goto 21 - 14: label L3 - 15: $t9 := 0 - 16: $t10 := move($t0) - 17: $t11 := borrow_global<0x42::Demo::S1>($t10) - 18: $t12 := borrow_field<0x42::Demo::S1>.v($t11) - 19: write_ref($t12, $t9) - 20: goto 21 - 21: label L2 - 22: return () -} - -============ after pipeline `global_invariant_analysis` ================ - -[variant verification] -fun Demo::f1($t0|addr: address) { - var $t1: bool - var $t2: u8 - var $t3: &mut 0x42::Demo::S1 - var $t4: num - var $t5: &mut u8 - var $t6: bool - var $t7: u8 - var $t8: &mut 0x42::Demo::S1 - var $t9: &mut u8 - 0: $t1 := exists<0x42::Demo::S1>($t0) - 1: if ($t1) goto 2 else goto 9 - 2: label L1 - 3: $t2 := 0 - 4: $t3 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 22 with $t4 - 5: $t5 := borrow_field<0x42::Demo::S1>.v($t3) - 6: write_ref($t5, $t2) - 7: write_back[Reference($t3).v (u8)]($t5) - 8: write_back[0x42::Demo::S1@]($t3) - 9: label L0 - 10: $t6 := exists<0x42::Demo::S1>($t0) - 11: if ($t6) goto 12 else goto 19 - 12: label L3 - 13: $t7 := 0 - 14: $t8 := borrow_global<0x42::Demo::S1>($t0) on_abort goto 22 with $t4 - 15: $t9 := borrow_field<0x42::Demo::S1>.v($t8) - 16: write_ref($t9, $t7) - 17: write_back[Reference($t8).v (u8)]($t9) - 18: write_back[0x42::Demo::S1@]($t8) - 19: label L2 - 20: label L4 - 21: return () - 22: label L5 - 23: abort($t4) -} - - -********* Result of global invariant instrumentation ********* - -Demo::f1: [ - entrypoint { - assume @0 = [ - <> -> [ - - - ] - ] - } - 0: $t1 := exists<0x42::Demo::S1>($t0) {} - 8: write_back[0x42::Demo::S1@]($t3) { - assert @0 = [ - <> -> [ - - ] - ] - } - 10: $t6 := exists<0x42::Demo::S1>($t0) {} - 18: write_back[0x42::Demo::S1@]($t8) { - assert @0 = [ - <> -> [ - - ] - ] - } - exitpoint {} -] - -********* Global invariants by ID ********* - -@0 => invariant - (exists>(@0x2) && exists>(@0x2)) - ==> global>(@0x2).v == 0; diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/borrow.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/borrow.v2_exp deleted file mode 100644 index c387eb5048f..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/borrow.v2_exp +++ /dev/null @@ -1,57 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::borrow($t0|a: address) { - var $t1|r: &mut 0x42::Test::R - var $t2: address - var $t3: &mut 0x42::Test::R - var $t4: &mut 0x42::Test::R - var $t5: &u64 - var $t6: u64 - var $t7: u64 - var $t8: u64 - var $t9: &mut 0x42::Test::R - var $t10: &mut u64 - 0: $t2 := move($t0) - 1: $t3 := borrow_global<0x42::Test::R>($t2) - 2: $t1 := $t3 - 3: $t4 := copy($t1) - 4: $t5 := borrow_field<0x42::Test::R>.x($t4) - 5: $t6 := read_ref($t5) - 6: $t7 := 1 - 7: $t8 := +($t6, $t7) - 8: $t9 := move($t1) - 9: $t10 := borrow_field<0x42::Test::R>.x($t9) - 10: write_ref($t10, $t8) - 11: return () -} - -============ after pipeline `global_invariant_instrumentation` ================ - -[variant verification] -public fun Test::borrow($t0|a: address) { - var $t1|r: &mut 0x42::Test::R - var $t2: &mut 0x42::Test::R - var $t3: num - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: &mut u64 - # global invariant at tests/global_invariant_instrumentation/borrow.move:7:9+57 - 0: assume forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 1: $t2 := borrow_global<0x42::Test::R>($t0) on_abort goto 12 with $t3 - 2: $t4 := get_field<0x42::Test::R>.x($t2) - 3: $t5 := 1 - 4: $t6 := +($t4, $t5) on_abort goto 12 with $t3 - 5: $t7 := borrow_field<0x42::Test::R>.x($t2) - 6: write_ref($t7, $t6) - 7: write_back[Reference($t2).x (u64)]($t7) - 8: write_back[0x42::Test::R@]($t2) - # global invariant at tests/global_invariant_instrumentation/borrow.move:7:9+57 - # VC: global memory invariant does not hold at tests/global_invariant_instrumentation/borrow.move:7:9+57 - 9: assert forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 10: label L1 - 11: return () - 12: label L2 - 13: abort($t3) -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/move.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/move.v2_exp deleted file mode 100644 index b2b8db8a0f5..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/move.v2_exp +++ /dev/null @@ -1,61 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::publish($t0|s: &signer) { - var $t1: &signer - var $t2: u64 - var $t3: 0x42::Test::R - 0: $t1 := move($t0) - 1: $t2 := 1 - 2: $t3 := pack 0x42::Test::R($t2) - 3: move_to<0x42::Test::R>($t3, $t1) - 4: return () -} - - -[variant baseline] -public fun Test::remove($t0|a: address): 0x42::Test::R { - var $t1: address - var $t2: 0x42::Test::R - 0: $t1 := move($t0) - 1: $t2 := move_from<0x42::Test::R>($t1) - 2: return $t2 -} - -============ after pipeline `global_invariant_instrumentation` ================ - -[variant verification] -public fun Test::publish($t0|s: signer) { - var $t1: u64 - var $t2: 0x42::Test::R - var $t3: num - # global invariant at tests/global_invariant_instrumentation/move.move:7:9+57 - 0: assume forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 1: $t1 := 1 - 2: $t2 := pack 0x42::Test::R($t1) - 3: move_to<0x42::Test::R>($t2, $t0) on_abort goto 7 with $t3 - # global invariant at tests/global_invariant_instrumentation/move.move:7:9+57 - # VC: global memory invariant does not hold at tests/global_invariant_instrumentation/move.move:7:9+57 - 4: assert forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 5: label L1 - 6: return () - 7: label L2 - 8: abort($t3) -} - - -[variant verification] -public fun Test::remove($t0|a: address): 0x42::Test::R { - var $t1: 0x42::Test::R - var $t2: num - # global invariant at tests/global_invariant_instrumentation/move.move:7:9+57 - 0: assume forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 1: $t1 := move_from<0x42::Test::R>($t0) on_abort goto 5 with $t2 - # global invariant at tests/global_invariant_instrumentation/move.move:7:9+57 - # VC: global memory invariant does not hold at tests/global_invariant_instrumentation/move.move:7:9+57 - 2: assert forall a: address: TypeDomain
(): Gt(select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a)), 0) - 3: label L1 - 4: return $t1 - 5: label L2 - 6: abort($t2) -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/update.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/update.v2_exp deleted file mode 100644 index 6ffdeb41527..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/global_invariant_instrumentation/update.v2_exp +++ /dev/null @@ -1,57 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::incr($t0|a: address) { - var $t1|r: &mut 0x42::Test::R - var $t2: address - var $t3: &mut 0x42::Test::R - var $t4: &mut 0x42::Test::R - var $t5: &u64 - var $t6: u64 - var $t7: u64 - var $t8: u64 - var $t9: &mut 0x42::Test::R - var $t10: &mut u64 - 0: $t2 := move($t0) - 1: $t3 := borrow_global<0x42::Test::R>($t2) - 2: $t1 := $t3 - 3: $t4 := copy($t1) - 4: $t5 := borrow_field<0x42::Test::R>.x($t4) - 5: $t6 := read_ref($t5) - 6: $t7 := 1 - 7: $t8 := +($t6, $t7) - 8: $t9 := move($t1) - 9: $t10 := borrow_field<0x42::Test::R>.x($t9) - 10: write_ref($t10, $t8) - 11: return () -} - -============ after pipeline `global_invariant_instrumentation` ================ - -[variant verification] -public fun Test::incr($t0|a: address) { - var $t1|r: &mut 0x42::Test::R - var $t2: &mut 0x42::Test::R - var $t3: num - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: &mut u64 - 0: $t2 := borrow_global<0x42::Test::R>($t0) on_abort goto 12 with $t3 - 1: $t4 := get_field<0x42::Test::R>.x($t2) - 2: $t5 := 1 - 3: $t6 := +($t4, $t5) on_abort goto 12 with $t3 - 4: $t7 := borrow_field<0x42::Test::R>.x($t2) - 5: write_ref($t7, $t6) - 6: write_back[Reference($t2).x (u64)]($t7) - # state save for global update invariants - 7: @1 := save_mem(Test::R) - 8: write_back[0x42::Test::R@]($t2) - # global invariant at tests/global_invariant_instrumentation/update.move:7:9+82 - # VC: global memory invariant does not hold at tests/global_invariant_instrumentation/update.move:7:9+82 - 9: assert forall a: address: TypeDomain
(): Lt(select Test::R.x<0x42::Test::R>(global[@1]<0x42::Test::R>(a)), select Test::R.x<0x42::Test::R>(global<0x42::Test::R>(a))) - 10: label L1 - 11: return () - 12: label L2 - 13: abort($t3) -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.exp b/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.exp index e8d6ab8cc9e..d1a5b30e650 100644 --- a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.exp +++ b/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.exp @@ -210,23 +210,21 @@ fun TestPackref::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestPackre 36: goto 27 37: label L0 38: $t25 := move($t0) - 39: if ($t25) goto 40 else goto 49 + 39: if ($t25) goto 40 else goto 47 40: label L7 41: $t26 := move($t5) 42: drop($t26) 43: $t27 := move($t2) 44: $t28 := 0 45: TestPackref::test3($t27, $t28) - 46: goto 47 - 47: label L8 - 48: return () - 49: label L6 - 50: $t29 := move($t2) - 51: drop($t29) - 52: $t30 := move($t5) - 53: $t31 := 0 - 54: TestPackref::test3($t30, $t31) - 55: goto 47 + 46: return () + 47: label L6 + 48: $t29 := move($t2) + 49: drop($t29) + 50: $t30 := move($t5) + 51: $t31 := 0 + 52: TestPackref::test3($t30, $t31) + 53: return () } ============ after pipeline `memory_instr` ================ @@ -422,25 +420,25 @@ fun TestPackref::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestPackre 10: label L1 11: $t20 := is_parent[Reference($t8)@]($t5) 12: if ($t20) goto 13 else goto 17 - 13: label L9 + 13: label L8 14: write_back[Reference($t8)@]($t5) 15: write_back[LocalRoot($t4)@]($t8) 16: trace_local[r2]($t4) - 17: label L10 + 17: label L9 18: $t21 := is_parent[Reference($t15)@]($t5) 19: if ($t21) goto 20 else goto 24 - 20: label L11 + 20: label L10 21: write_back[Reference($t15)@]($t5) 22: write_back[LocalRoot($t3)@]($t15) 23: trace_local[r1]($t3) - 24: label L12 + 24: label L11 25: $t22 := is_parent[Reference($t17)@]($t5) 26: if ($t22) goto 27 else goto 31 - 27: label L13 + 27: label L12 28: write_back[Reference($t17)@]($t5) 29: write_back[LocalRoot($t4)@]($t17) 30: trace_local[r2]($t4) - 31: label L14 + 31: label L13 32: drop($t5) 33: $t11 := 2 34: $t12 := /($t1, $t11) @@ -459,59 +457,59 @@ fun TestPackref::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestPackre 47: $t5 := $t17 48: goto 41 49: label L0 - 50: if ($t0) goto 51 else goto 79 + 50: if ($t0) goto 51 else goto 78 51: label L7 52: $t23 := is_parent[Reference($t8)@]($t5) 53: if ($t23) goto 54 else goto 58 - 54: label L15 + 54: label L14 55: write_back[Reference($t8)@]($t5) 56: write_back[LocalRoot($t4)@]($t8) 57: trace_local[r2]($t4) - 58: label L16 + 58: label L15 59: $t24 := is_parent[Reference($t15)@]($t5) 60: if ($t24) goto 61 else goto 65 - 61: label L17 + 61: label L16 62: write_back[Reference($t15)@]($t5) 63: write_back[LocalRoot($t3)@]($t15) 64: trace_local[r1]($t3) - 65: label L18 + 65: label L17 66: $t25 := is_parent[Reference($t17)@]($t5) 67: if ($t25) goto 68 else goto 72 - 68: label L19 + 68: label L18 69: write_back[Reference($t17)@]($t5) 70: write_back[LocalRoot($t4)@]($t17) 71: trace_local[r2]($t4) - 72: label L20 + 72: label L19 73: drop($t5) 74: $t18 := 0 75: TestPackref::test3($t2, $t18) - 76: label L8 - 77: trace_local[r_ref]($t2) - 78: return () - 79: label L6 - 80: drop($t2) - 81: $t19 := 0 - 82: TestPackref::test3($t5, $t19) - 83: $t26 := is_parent[Reference($t8)@]($t5) - 84: if ($t26) goto 85 else goto 89 - 85: label L21 - 86: write_back[Reference($t8)@]($t5) - 87: write_back[LocalRoot($t4)@]($t8) - 88: trace_local[r2]($t4) - 89: label L22 - 90: $t27 := is_parent[Reference($t15)@]($t5) - 91: if ($t27) goto 92 else goto 96 - 92: label L23 - 93: write_back[Reference($t15)@]($t5) - 94: write_back[LocalRoot($t3)@]($t15) - 95: trace_local[r1]($t3) - 96: label L24 - 97: $t28 := is_parent[Reference($t17)@]($t5) - 98: if ($t28) goto 99 else goto 103 - 99: label L25 -100: write_back[Reference($t17)@]($t5) -101: write_back[LocalRoot($t4)@]($t17) -102: trace_local[r2]($t4) -103: label L26 -104: goto 76 + 76: trace_local[r_ref]($t2) + 77: return () + 78: label L6 + 79: drop($t2) + 80: $t19 := 0 + 81: TestPackref::test3($t5, $t19) + 82: $t26 := is_parent[Reference($t8)@]($t5) + 83: if ($t26) goto 84 else goto 88 + 84: label L20 + 85: write_back[Reference($t8)@]($t5) + 86: write_back[LocalRoot($t4)@]($t8) + 87: trace_local[r2]($t4) + 88: label L21 + 89: $t27 := is_parent[Reference($t15)@]($t5) + 90: if ($t27) goto 91 else goto 95 + 91: label L22 + 92: write_back[Reference($t15)@]($t5) + 93: write_back[LocalRoot($t3)@]($t15) + 94: trace_local[r1]($t3) + 95: label L23 + 96: $t28 := is_parent[Reference($t17)@]($t5) + 97: if ($t28) goto 98 else goto 102 + 98: label L24 + 99: write_back[Reference($t17)@]($t5) +100: write_back[LocalRoot($t4)@]($t17) +101: trace_local[r2]($t4) +102: label L25 +103: trace_local[r_ref]($t2) +104: return () } diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.v2_exp deleted file mode 100644 index 9e079b1d849..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/basic_test.v2_exp +++ /dev/null @@ -1,516 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun TestPackref::test1(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1|x_ref: &mut u64 - var $t2: u64 - var $t3: 0x42::TestPackref::R - var $t4: &mut 0x42::TestPackref::R - var $t5: &mut u64 - var $t6: u64 - var $t7: &mut u64 - var $t8: 0x42::TestPackref::R - 0: $t2 := 3 - 1: $t3 := pack 0x42::TestPackref::R($t2) - 2: $t0 := $t3 - 3: $t4 := borrow_local($t0) - 4: $t5 := borrow_field<0x42::TestPackref::R>.x($t4) - 5: $t1 := $t5 - 6: $t6 := 0 - 7: $t7 := move($t1) - 8: write_ref($t7, $t6) - 9: $t8 := move($t0) - 10: return $t8 -} - - -[variant baseline] -fun TestPackref::test2($t0|x_ref: &mut u64, $t1|v: u64) { - var $t2: u64 - var $t3: &mut u64 - 0: $t2 := move($t1) - 1: $t3 := move($t0) - 2: write_ref($t3, $t2) - 3: return () -} - - -[variant baseline] -public fun TestPackref::test3($t0|r_ref: &mut 0x42::TestPackref::R, $t1|v: u64) { - var $t2: &mut 0x42::TestPackref::R - var $t3: &mut u64 - var $t4: u64 - 0: $t2 := move($t0) - 1: $t3 := borrow_field<0x42::TestPackref::R>.x($t2) - 2: $t4 := move($t1) - 3: TestPackref::test2($t3, $t4) - 4: return () -} - - -[variant baseline] -fun TestPackref::test4(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1: u64 - var $t2: 0x42::TestPackref::R - var $t3: &mut 0x42::TestPackref::R - var $t4: u64 - var $t5: 0x42::TestPackref::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestPackref::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := 0 - 5: TestPackref::test3($t3, $t4) - 6: $t5 := move($t0) - 7: return $t5 -} - - -[variant baseline] -public fun TestPackref::test5($t0|r_ref: &mut 0x42::TestPackref::R): &mut u64 { - var $t1: &mut 0x42::TestPackref::R - var $t2: &mut u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_field<0x42::TestPackref::R>.x($t1) - 2: return $t2 -} - - -[variant baseline] -fun TestPackref::test6(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1: u64 - var $t2: 0x42::TestPackref::R - var $t3: &mut 0x42::TestPackref::R - var $t4: &mut u64 - var $t5: u64 - var $t6: 0x42::TestPackref::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestPackref::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := TestPackref::test5($t3) - 5: $t5 := 0 - 6: TestPackref::test2($t4, $t5) - 7: $t6 := move($t0) - 8: return $t6 -} - - -[variant baseline] -fun TestPackref::test7($t0|b: bool) { - var $t1|r1: 0x42::TestPackref::R - var $t2|r2: 0x42::TestPackref::R - var $t3|r_ref: &mut 0x42::TestPackref::R - var $t4: u64 - var $t5: 0x42::TestPackref::R - var $t6: u64 - var $t7: 0x42::TestPackref::R - var $t8: &mut 0x42::TestPackref::R - var $t9: bool - var $t10: &mut 0x42::TestPackref::R - var $t11: &mut 0x42::TestPackref::R - var $t12: &mut 0x42::TestPackref::R - var $t13: u64 - 0: $t4 := 3 - 1: $t5 := pack 0x42::TestPackref::R($t4) - 2: $t1 := $t5 - 3: $t6 := 4 - 4: $t7 := pack 0x42::TestPackref::R($t6) - 5: $t2 := $t7 - 6: $t8 := borrow_local($t1) - 7: $t3 := $t8 - 8: $t9 := move($t0) - 9: if ($t9) goto 10 else goto 16 - 10: label L1 - 11: $t10 := move($t3) - 12: drop($t10) - 13: $t11 := borrow_local($t2) - 14: $t3 := $t11 - 15: goto 16 - 16: label L0 - 17: $t12 := move($t3) - 18: $t13 := 0 - 19: TestPackref::test3($t12, $t13) - 20: return () -} - - -[variant baseline] -fun TestPackref::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestPackref::R) { - var $t3|r1: 0x42::TestPackref::R - var $t4|r2: 0x42::TestPackref::R - var $t5|t_ref: &mut 0x42::TestPackref::R - var $t6: u64 - var $t7: 0x42::TestPackref::R - var $t8: u64 - var $t9: 0x42::TestPackref::R - var $t10: &mut 0x42::TestPackref::R - var $t11: u64 - var $t12: u64 - var $t13: bool - var $t14: &mut 0x42::TestPackref::R - var $t15: u64 - var $t16: u64 - var $t17: u64 - var $t18: u64 - var $t19: bool - var $t20: &mut 0x42::TestPackref::R - var $t21: &mut 0x42::TestPackref::R - var $t22: u64 - var $t23: u64 - var $t24: u64 - var $t25: bool - var $t26: &mut 0x42::TestPackref::R - var $t27: &mut 0x42::TestPackref::R - var $t28: u64 - var $t29: &mut 0x42::TestPackref::R - var $t30: &mut 0x42::TestPackref::R - var $t31: u64 - 0: $t6 := 3 - 1: $t7 := pack 0x42::TestPackref::R($t6) - 2: $t3 := $t7 - 3: $t8 := 4 - 4: $t9 := pack 0x42::TestPackref::R($t8) - 5: $t4 := $t9 - 6: $t10 := borrow_local($t4) - 7: $t5 := $t10 - 8: goto 9 - 9: label L6 - 10: $t11 := 0 - 11: $t12 := copy($t1) - 12: $t13 := <($t11, $t12) - 13: if ($t13) goto 14 else goto 39 - 14: label L1 - 15: goto 16 - 16: label L2 - 17: $t14 := move($t5) - 18: drop($t14) - 19: $t15 := copy($t1) - 20: $t16 := 2 - 21: $t17 := /($t15, $t16) - 22: $t18 := 0 - 23: $t19 := ==($t17, $t18) - 24: if ($t19) goto 25 else goto 29 - 25: label L4 - 26: $t20 := borrow_local($t3) - 27: $t5 := $t20 - 28: goto 33 - 29: label L3 - 30: $t21 := borrow_local($t4) - 31: $t5 := $t21 - 32: goto 33 - 33: label L5 - 34: $t22 := move($t1) - 35: $t23 := 1 - 36: $t24 := -($t22, $t23) - 37: $t1 := $t24 - 38: goto 9 - 39: label L0 - 40: $t25 := move($t0) - 41: if ($t25) goto 42 else goto 49 - 42: label L8 - 43: $t26 := move($t5) - 44: drop($t26) - 45: $t27 := move($t2) - 46: $t28 := 0 - 47: TestPackref::test3($t27, $t28) - 48: goto 56 - 49: label L7 - 50: $t29 := move($t2) - 51: drop($t29) - 52: $t30 := move($t5) - 53: $t31 := 0 - 54: TestPackref::test3($t30, $t31) - 55: goto 56 - 56: label L9 - 57: return () -} - -============ after pipeline `memory_instr` ================ - -[variant baseline] -fun TestPackref::test1(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1|x_ref: &mut u64 [unused] - var $t2: u64 - var $t3: &mut 0x42::TestPackref::R - var $t4: &mut u64 - var $t5: u64 - var $t6: 0x42::TestPackref::R - 0: $t2 := 3 - 1: $t0 := pack 0x42::TestPackref::R($t2) - 2: $t3 := borrow_local($t0) - 3: $t4 := borrow_field<0x42::TestPackref::R>.x($t3) - 4: $t5 := 0 - 5: write_ref($t4, $t5) - 6: write_back[Reference($t3).x (u64)]($t4) - 7: write_back[LocalRoot($t0)@]($t3) - 8: trace_local[r]($t0) - 9: $t6 := move($t0) - 10: return $t6 -} - - -[variant baseline] -fun TestPackref::test2($t0|x_ref: &mut u64, $t1|v: u64) { - 0: write_ref($t0, $t1) - 1: trace_local[x_ref]($t0) - 2: return () -} - - -[variant baseline] -public fun TestPackref::test3($t0|r_ref: &mut 0x42::TestPackref::R, $t1|v: u64) { - var $t2: &mut u64 - 0: $t2 := borrow_field<0x42::TestPackref::R>.x($t0) - 1: TestPackref::test2($t2, $t1) - 2: write_back[Reference($t0).x (u64)]($t2) - 3: trace_local[r_ref]($t0) - 4: trace_local[r_ref]($t0) - 5: return () -} - - -[variant baseline] -fun TestPackref::test4(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1: u64 - var $t2: &mut 0x42::TestPackref::R - var $t3: u64 - var $t4: 0x42::TestPackref::R - 0: $t1 := 3 - 1: $t0 := pack 0x42::TestPackref::R($t1) - 2: $t2 := borrow_local($t0) - 3: $t3 := 0 - 4: TestPackref::test3($t2, $t3) - 5: write_back[LocalRoot($t0)@]($t2) - 6: trace_local[r]($t0) - 7: $t4 := move($t0) - 8: return $t4 -} - - -[variant baseline] -public fun TestPackref::test5($t0|r_ref: &mut 0x42::TestPackref::R): &mut u64 { - var $t1: &mut u64 - 0: $t1 := borrow_field<0x42::TestPackref::R>.x($t0) - 1: trace_local[r_ref]($t0) - 2: write_back[Reference($t0).x (u64)]($t1) - 3: trace_local[r_ref]($t0) - 4: return $t1 -} - - -[variant baseline] -fun TestPackref::test6(): 0x42::TestPackref::R { - var $t0|r: 0x42::TestPackref::R - var $t1: u64 - var $t2: &mut 0x42::TestPackref::R - var $t3: &mut u64 - var $t4: u64 - var $t5: 0x42::TestPackref::R - 0: $t1 := 3 - 1: $t0 := pack 0x42::TestPackref::R($t1) - 2: $t2 := borrow_local($t0) - 3: $t3 := TestPackref::test5($t2) - 4: $t4 := 0 - 5: TestPackref::test2($t3, $t4) - 6: write_back[Reference($t2).x (u64)]($t3) - 7: write_back[LocalRoot($t0)@]($t2) - 8: trace_local[r]($t0) - 9: $t5 := move($t0) - 10: return $t5 -} - - -[variant baseline] -fun TestPackref::test7($t0|b: bool) { - var $t1|r1: 0x42::TestPackref::R - var $t2|r2: 0x42::TestPackref::R - var $t3|r_ref: &mut 0x42::TestPackref::R - var $t4: u64 - var $t5: u64 - var $t6: &mut 0x42::TestPackref::R - var $t7: &mut 0x42::TestPackref::R - var $t8: u64 - var $t9: bool - var $t10: bool - 0: $t4 := 3 - 1: $t1 := pack 0x42::TestPackref::R($t4) - 2: $t5 := 4 - 3: $t2 := pack 0x42::TestPackref::R($t5) - 4: $t6 := borrow_local($t1) - 5: $t3 := $t6 - 6: if ($t0) goto 31 else goto 35 - 7: label L1 - 8: write_back[LocalRoot($t1)@]($t6) - 9: trace_local[r1]($t1) - 10: drop($t6) - 11: $t7 := borrow_local($t2) - 12: $t3 := $t7 - 13: label L0 - 14: $t8 := 0 - 15: TestPackref::test3($t3, $t8) - 16: $t9 := is_parent[Reference($t6)@]($t3) - 17: if ($t9) goto 18 else goto 22 - 18: label L4 - 19: write_back[Reference($t6)@]($t3) - 20: write_back[LocalRoot($t1)@]($t6) - 21: trace_local[r1]($t1) - 22: label L5 - 23: $t10 := is_parent[Reference($t7)@]($t3) - 24: if ($t10) goto 25 else goto 29 - 25: label L6 - 26: write_back[Reference($t7)@]($t3) - 27: write_back[LocalRoot($t2)@]($t7) - 28: trace_local[r2]($t2) - 29: label L7 - 30: return () - 31: label L2 - 32: write_back[Reference($t6)@]($t3) - 33: drop($t3) - 34: goto 7 - 35: label L3 - 36: drop($t6) - 37: goto 13 -} - - -[variant baseline] -fun TestPackref::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestPackref::R) { - var $t3|r1: 0x42::TestPackref::R - var $t4|r2: 0x42::TestPackref::R - var $t5|t_ref: &mut 0x42::TestPackref::R - var $t6: u64 - var $t7: u64 - var $t8: &mut 0x42::TestPackref::R - var $t9: u64 - var $t10: bool - var $t11: u64 - var $t12: u64 - var $t13: u64 - var $t14: bool - var $t15: &mut 0x42::TestPackref::R - var $t16: &mut 0x42::TestPackref::R - var $t17: u64 - var $t18: u64 - var $t19: u64 - var $t20: bool - var $t21: bool - var $t22: bool - var $t23: bool - var $t24: bool - var $t25: bool - var $t26: bool - var $t27: bool - var $t28: bool - 0: $t6 := 3 - 1: $t3 := pack 0x42::TestPackref::R($t6) - 2: $t7 := 4 - 3: $t4 := pack 0x42::TestPackref::R($t7) - 4: $t8 := borrow_local($t4) - 5: $t5 := $t8 - 6: label L6 - 7: $t9 := 0 - 8: $t10 := <($t9, $t1) - 9: if ($t10) goto 10 else goto 50 - 10: label L1 - 11: label L2 - 12: $t20 := is_parent[Reference($t8)@]($t5) - 13: if ($t20) goto 14 else goto 18 - 14: label L10 - 15: write_back[Reference($t8)@]($t5) - 16: write_back[LocalRoot($t4)@]($t8) - 17: trace_local[r2]($t4) - 18: label L11 - 19: $t21 := is_parent[Reference($t15)@]($t5) - 20: if ($t21) goto 21 else goto 25 - 21: label L12 - 22: write_back[Reference($t15)@]($t5) - 23: write_back[LocalRoot($t3)@]($t15) - 24: trace_local[r1]($t3) - 25: label L13 - 26: $t22 := is_parent[Reference($t16)@]($t5) - 27: if ($t22) goto 28 else goto 32 - 28: label L14 - 29: write_back[Reference($t16)@]($t5) - 30: write_back[LocalRoot($t4)@]($t16) - 31: trace_local[r2]($t4) - 32: label L15 - 33: drop($t5) - 34: $t11 := 2 - 35: $t12 := /($t1, $t11) - 36: $t13 := 0 - 37: $t14 := ==($t12, $t13) - 38: if ($t14) goto 39 else goto 43 - 39: label L4 - 40: $t15 := borrow_local($t3) - 41: $t5 := $t15 - 42: goto 46 - 43: label L3 - 44: $t16 := borrow_local($t4) - 45: $t5 := $t16 - 46: label L5 - 47: $t17 := 1 - 48: $t1 := -($t1, $t17) - 49: goto 6 - 50: label L0 - 51: if ($t0) goto 52 else goto 78 - 52: label L8 - 53: $t23 := is_parent[Reference($t8)@]($t5) - 54: if ($t23) goto 55 else goto 59 - 55: label L16 - 56: write_back[Reference($t8)@]($t5) - 57: write_back[LocalRoot($t4)@]($t8) - 58: trace_local[r2]($t4) - 59: label L17 - 60: $t24 := is_parent[Reference($t15)@]($t5) - 61: if ($t24) goto 62 else goto 66 - 62: label L18 - 63: write_back[Reference($t15)@]($t5) - 64: write_back[LocalRoot($t3)@]($t15) - 65: trace_local[r1]($t3) - 66: label L19 - 67: $t25 := is_parent[Reference($t16)@]($t5) - 68: if ($t25) goto 69 else goto 73 - 69: label L20 - 70: write_back[Reference($t16)@]($t5) - 71: write_back[LocalRoot($t4)@]($t16) - 72: trace_local[r2]($t4) - 73: label L21 - 74: drop($t5) - 75: $t18 := 0 - 76: TestPackref::test3($t2, $t18) - 77: goto 103 - 78: label L7 - 79: drop($t2) - 80: $t19 := 0 - 81: TestPackref::test3($t5, $t19) - 82: $t26 := is_parent[Reference($t8)@]($t5) - 83: if ($t26) goto 84 else goto 88 - 84: label L22 - 85: write_back[Reference($t8)@]($t5) - 86: write_back[LocalRoot($t4)@]($t8) - 87: trace_local[r2]($t4) - 88: label L23 - 89: $t27 := is_parent[Reference($t15)@]($t5) - 90: if ($t27) goto 91 else goto 95 - 91: label L24 - 92: write_back[Reference($t15)@]($t5) - 93: write_back[LocalRoot($t3)@]($t15) - 94: trace_local[r1]($t3) - 95: label L25 - 96: $t28 := is_parent[Reference($t16)@]($t5) - 97: if ($t28) goto 98 else goto 102 - 98: label L26 - 99: write_back[Reference($t16)@]($t5) -100: write_back[LocalRoot($t4)@]($t16) -101: trace_local[r2]($t4) -102: label L27 -103: label L9 -104: trace_local[r_ref]($t2) -105: return () -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/mut_ref.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/mut_ref.v2_exp deleted file mode 100644 index 1381a02e33a..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/memory_instr/mut_ref.v2_exp +++ /dev/null @@ -1,495 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun TestMutRefs::data_invariant($t0|_x: &mut 0x1::TestMutRefs::T) { - 0: return () -} - - -[variant baseline] -public fun TestMutRefs::decrement_invalid($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum - var $t2: &mut 0x1::TestMutRefs::T - var $t3: &u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: &mut 0x1::TestMutRefs::T - var $t8: &mut u64 - var $t9: address - var $t10: &mut 0x1::TestMutRefs::TSum - var $t11: &mut 0x1::TestMutRefs::TSum - var $t12: &u64 - var $t13: u64 - var $t14: u64 - var $t15: u64 - var $t16: &mut 0x1::TestMutRefs::TSum - var $t17: &mut u64 - 0: $t2 := copy($t0) - 1: $t3 := borrow_field<0x1::TestMutRefs::T>.value($t2) - 2: $t4 := read_ref($t3) - 3: $t5 := 1 - 4: $t6 := -($t4, $t5) - 5: $t7 := move($t0) - 6: $t8 := borrow_field<0x1::TestMutRefs::T>.value($t7) - 7: write_ref($t8, $t6) - 8: $t9 := 0x0 - 9: $t10 := borrow_global<0x1::TestMutRefs::TSum>($t9) - 10: $t1 := $t10 - 11: $t11 := copy($t1) - 12: $t12 := borrow_field<0x1::TestMutRefs::TSum>.sum($t11) - 13: $t13 := read_ref($t12) - 14: $t14 := 1 - 15: $t15 := -($t13, $t14) - 16: $t16 := move($t1) - 17: $t17 := borrow_field<0x1::TestMutRefs::TSum>.sum($t16) - 18: write_ref($t17, $t15) - 19: return () -} - - -[variant baseline] -public fun TestMutRefs::delete($t0|x: 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum - var $t2|v: u64 - var $t3: address - var $t4: &mut 0x1::TestMutRefs::TSum - var $t5: 0x1::TestMutRefs::T - var $t6: u64 - var $t7: &mut 0x1::TestMutRefs::TSum - var $t8: &u64 - var $t9: u64 - var $t10: u64 - var $t11: u64 - var $t12: &mut 0x1::TestMutRefs::TSum - var $t13: &mut u64 - 0: $t3 := 0x0 - 1: $t4 := borrow_global<0x1::TestMutRefs::TSum>($t3) - 2: $t1 := $t4 - 3: $t5 := move($t0) - 4: $t6 := unpack 0x1::TestMutRefs::T($t5) - 5: $t2 := $t6 - 6: $t7 := copy($t1) - 7: $t8 := borrow_field<0x1::TestMutRefs::TSum>.sum($t7) - 8: $t9 := read_ref($t8) - 9: $t10 := move($t2) - 10: $t11 := -($t9, $t10) - 11: $t12 := move($t1) - 12: $t13 := borrow_field<0x1::TestMutRefs::TSum>.sum($t12) - 13: write_ref($t13, $t11) - 14: return () -} - - -[variant baseline] -public fun TestMutRefs::increment($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum - var $t2: &mut 0x1::TestMutRefs::T - var $t3: &u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: &mut 0x1::TestMutRefs::T - var $t8: &mut u64 - var $t9: address - var $t10: &mut 0x1::TestMutRefs::TSum - var $t11: &mut 0x1::TestMutRefs::TSum - var $t12: &u64 - var $t13: u64 - var $t14: u64 - var $t15: u64 - var $t16: &mut 0x1::TestMutRefs::TSum - var $t17: &mut u64 - 0: $t2 := copy($t0) - 1: $t3 := borrow_field<0x1::TestMutRefs::T>.value($t2) - 2: $t4 := read_ref($t3) - 3: $t5 := 1 - 4: $t6 := +($t4, $t5) - 5: $t7 := move($t0) - 6: $t8 := borrow_field<0x1::TestMutRefs::T>.value($t7) - 7: write_ref($t8, $t6) - 8: $t9 := 0x0 - 9: $t10 := borrow_global<0x1::TestMutRefs::TSum>($t9) - 10: $t1 := $t10 - 11: $t11 := copy($t1) - 12: $t12 := borrow_field<0x1::TestMutRefs::TSum>.sum($t11) - 13: $t13 := read_ref($t12) - 14: $t14 := 1 - 15: $t15 := +($t13, $t14) - 16: $t16 := move($t1) - 17: $t17 := borrow_field<0x1::TestMutRefs::TSum>.sum($t16) - 18: write_ref($t17, $t15) - 19: return () -} - - -[variant baseline] -public fun TestMutRefs::increment_invalid($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1: &mut 0x1::TestMutRefs::T - var $t2: &u64 - var $t3: u64 - var $t4: u64 - var $t5: u64 - var $t6: &mut 0x1::TestMutRefs::T - var $t7: &mut u64 - 0: $t1 := copy($t0) - 1: $t2 := borrow_field<0x1::TestMutRefs::T>.value($t1) - 2: $t3 := read_ref($t2) - 3: $t4 := 1 - 4: $t5 := +($t3, $t4) - 5: $t6 := move($t0) - 6: $t7 := borrow_field<0x1::TestMutRefs::T>.value($t6) - 7: write_ref($t7, $t5) - 8: return () -} - - -[variant baseline] -public fun TestMutRefs::new($t0|x: u64): 0x1::TestMutRefs::T { - var $t1|r: &mut 0x1::TestMutRefs::TSum - var $t2: address - var $t3: &mut 0x1::TestMutRefs::TSum - var $t4: &mut 0x1::TestMutRefs::TSum - var $t5: &u64 - var $t6: u64 - var $t7: u64 - var $t8: u64 - var $t9: &mut 0x1::TestMutRefs::TSum - var $t10: &mut u64 - var $t11: u64 - var $t12: 0x1::TestMutRefs::T - 0: $t2 := 0x0 - 1: $t3 := borrow_global<0x1::TestMutRefs::TSum>($t2) - 2: $t1 := $t3 - 3: $t4 := copy($t1) - 4: $t5 := borrow_field<0x1::TestMutRefs::TSum>.sum($t4) - 5: $t6 := read_ref($t5) - 6: $t7 := copy($t0) - 7: $t8 := +($t6, $t7) - 8: $t9 := move($t1) - 9: $t10 := borrow_field<0x1::TestMutRefs::TSum>.sum($t9) - 10: write_ref($t10, $t8) - 11: $t11 := move($t0) - 12: $t12 := pack 0x1::TestMutRefs::T($t11) - 13: return $t12 -} - - -[variant baseline] -fun TestMutRefs::private_data_invariant_invalid($t0|_x: &mut 0x1::TestMutRefs::T) { - 0: return () -} - - -[variant baseline] -fun TestMutRefs::private_decrement($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum - var $t2: &mut 0x1::TestMutRefs::T - var $t3: &u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: &mut 0x1::TestMutRefs::T - var $t8: &mut u64 - var $t9: address - var $t10: &mut 0x1::TestMutRefs::TSum - var $t11: &mut 0x1::TestMutRefs::TSum - var $t12: &u64 - var $t13: u64 - var $t14: u64 - var $t15: u64 - var $t16: &mut 0x1::TestMutRefs::TSum - var $t17: &mut u64 - 0: $t2 := copy($t0) - 1: $t3 := borrow_field<0x1::TestMutRefs::T>.value($t2) - 2: $t4 := read_ref($t3) - 3: $t5 := 1 - 4: $t6 := -($t4, $t5) - 5: $t7 := move($t0) - 6: $t8 := borrow_field<0x1::TestMutRefs::T>.value($t7) - 7: write_ref($t8, $t6) - 8: $t9 := 0x0 - 9: $t10 := borrow_global<0x1::TestMutRefs::TSum>($t9) - 10: $t1 := $t10 - 11: $t11 := copy($t1) - 12: $t12 := borrow_field<0x1::TestMutRefs::TSum>.sum($t11) - 13: $t13 := read_ref($t12) - 14: $t14 := 1 - 15: $t15 := -($t13, $t14) - 16: $t16 := move($t1) - 17: $t17 := borrow_field<0x1::TestMutRefs::TSum>.sum($t16) - 18: write_ref($t17, $t15) - 19: return () -} - - -[variant baseline] -fun TestMutRefs::private_to_public_caller($t0|r: &mut 0x1::TestMutRefs::T) { - var $t1: &mut 0x1::TestMutRefs::T - 0: $t1 := move($t0) - 1: TestMutRefs::increment($t1) - 2: return () -} - - -[variant baseline] -fun TestMutRefs::private_to_public_caller_invalid_data_invariant() { - var $t0|r: &mut 0x1::TestMutRefs::T - var $t1|x: 0x1::TestMutRefs::T - var $t2: u64 - var $t3: 0x1::TestMutRefs::T - var $t4: &mut 0x1::TestMutRefs::T - var $t5: &mut 0x1::TestMutRefs::T - var $t6: &mut 0x1::TestMutRefs::T - 0: $t2 := 1 - 1: $t3 := TestMutRefs::new($t2) - 2: $t1 := $t3 - 3: $t4 := borrow_local($t1) - 4: $t0 := $t4 - 5: $t5 := copy($t0) - 6: TestMutRefs::private_decrement($t5) - 7: $t6 := move($t0) - 8: TestMutRefs::increment($t6) - 9: return () -} - - -[variant baseline] -public fun TestMutRefsUser::valid() { - var $t0|x: 0x1::TestMutRefs::T - var $t1: u64 - var $t2: 0x1::TestMutRefs::T - var $t3: &mut 0x1::TestMutRefs::T - var $t4: 0x1::TestMutRefs::T - 0: $t1 := 4 - 1: $t2 := TestMutRefs::new($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: TestMutRefs::increment($t3) - 5: $t4 := move($t0) - 6: TestMutRefs::delete($t4) - 7: return () -} - -============ after pipeline `memory_instr` ================ - -[variant baseline] -public fun TestMutRefs::data_invariant($t0|_x: &mut 0x1::TestMutRefs::T) { - 0: trace_local[_x]($t0) - 1: return () -} - - -[variant baseline] -public fun TestMutRefs::decrement_invalid($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum [unused] - var $t2: u64 - var $t3: u64 - var $t4: u64 - var $t5: &mut u64 - var $t6: address - var $t7: &mut 0x1::TestMutRefs::TSum - var $t8: u64 - var $t9: u64 - var $t10: u64 - var $t11: &mut u64 - 0: $t2 := get_field<0x1::TestMutRefs::T>.value($t0) - 1: $t3 := 1 - 2: $t4 := -($t2, $t3) - 3: $t5 := borrow_field<0x1::TestMutRefs::T>.value($t0) - 4: write_ref($t5, $t4) - 5: write_back[Reference($t0).value (u64)]($t5) - 6: trace_local[x]($t0) - 7: $t6 := 0x0 - 8: $t7 := borrow_global<0x1::TestMutRefs::TSum>($t6) - 9: $t8 := get_field<0x1::TestMutRefs::TSum>.sum($t7) - 10: $t9 := 1 - 11: $t10 := -($t8, $t9) - 12: $t11 := borrow_field<0x1::TestMutRefs::TSum>.sum($t7) - 13: write_ref($t11, $t10) - 14: write_back[Reference($t7).sum (u64)]($t11) - 15: write_back[0x1::TestMutRefs::TSum@]($t7) - 16: trace_local[x]($t0) - 17: return () -} - - -[variant baseline] -public fun TestMutRefs::delete($t0|x: 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum [unused] - var $t2|v: u64 [unused] - var $t3: address - var $t4: &mut 0x1::TestMutRefs::TSum - var $t5: u64 - var $t6: u64 - var $t7: u64 - var $t8: &mut u64 - 0: $t3 := 0x0 - 1: $t4 := borrow_global<0x1::TestMutRefs::TSum>($t3) - 2: $t5 := unpack 0x1::TestMutRefs::T($t0) - 3: $t6 := get_field<0x1::TestMutRefs::TSum>.sum($t4) - 4: $t7 := -($t6, $t5) - 5: $t8 := borrow_field<0x1::TestMutRefs::TSum>.sum($t4) - 6: write_ref($t8, $t7) - 7: write_back[Reference($t4).sum (u64)]($t8) - 8: write_back[0x1::TestMutRefs::TSum@]($t4) - 9: return () -} - - -[variant baseline] -public fun TestMutRefs::increment($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum [unused] - var $t2: u64 - var $t3: u64 - var $t4: u64 - var $t5: &mut u64 - var $t6: address - var $t7: &mut 0x1::TestMutRefs::TSum - var $t8: u64 - var $t9: u64 - var $t10: u64 - var $t11: &mut u64 - 0: $t2 := get_field<0x1::TestMutRefs::T>.value($t0) - 1: $t3 := 1 - 2: $t4 := +($t2, $t3) - 3: $t5 := borrow_field<0x1::TestMutRefs::T>.value($t0) - 4: write_ref($t5, $t4) - 5: write_back[Reference($t0).value (u64)]($t5) - 6: trace_local[x]($t0) - 7: $t6 := 0x0 - 8: $t7 := borrow_global<0x1::TestMutRefs::TSum>($t6) - 9: $t8 := get_field<0x1::TestMutRefs::TSum>.sum($t7) - 10: $t9 := 1 - 11: $t10 := +($t8, $t9) - 12: $t11 := borrow_field<0x1::TestMutRefs::TSum>.sum($t7) - 13: write_ref($t11, $t10) - 14: write_back[Reference($t7).sum (u64)]($t11) - 15: write_back[0x1::TestMutRefs::TSum@]($t7) - 16: trace_local[x]($t0) - 17: return () -} - - -[variant baseline] -public fun TestMutRefs::increment_invalid($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1: u64 - var $t2: u64 - var $t3: u64 - var $t4: &mut u64 - 0: $t1 := get_field<0x1::TestMutRefs::T>.value($t0) - 1: $t2 := 1 - 2: $t3 := +($t1, $t2) - 3: $t4 := borrow_field<0x1::TestMutRefs::T>.value($t0) - 4: write_ref($t4, $t3) - 5: write_back[Reference($t0).value (u64)]($t4) - 6: trace_local[x]($t0) - 7: trace_local[x]($t0) - 8: return () -} - - -[variant baseline] -public fun TestMutRefs::new($t0|x: u64): 0x1::TestMutRefs::T { - var $t1|r: &mut 0x1::TestMutRefs::TSum [unused] - var $t2: address - var $t3: &mut 0x1::TestMutRefs::TSum - var $t4: u64 - var $t5: u64 - var $t6: &mut u64 - var $t7: 0x1::TestMutRefs::T - 0: $t2 := 0x0 - 1: $t3 := borrow_global<0x1::TestMutRefs::TSum>($t2) - 2: $t4 := get_field<0x1::TestMutRefs::TSum>.sum($t3) - 3: $t5 := +($t4, $t0) - 4: $t6 := borrow_field<0x1::TestMutRefs::TSum>.sum($t3) - 5: write_ref($t6, $t5) - 6: write_back[Reference($t3).sum (u64)]($t6) - 7: write_back[0x1::TestMutRefs::TSum@]($t3) - 8: $t7 := pack 0x1::TestMutRefs::T($t0) - 9: return $t7 -} - - -[variant baseline] -fun TestMutRefs::private_data_invariant_invalid($t0|_x: &mut 0x1::TestMutRefs::T) { - 0: trace_local[_x]($t0) - 1: return () -} - - -[variant baseline] -fun TestMutRefs::private_decrement($t0|x: &mut 0x1::TestMutRefs::T) { - var $t1|r: &mut 0x1::TestMutRefs::TSum [unused] - var $t2: u64 - var $t3: u64 - var $t4: u64 - var $t5: &mut u64 - var $t6: address - var $t7: &mut 0x1::TestMutRefs::TSum - var $t8: u64 - var $t9: u64 - var $t10: u64 - var $t11: &mut u64 - 0: $t2 := get_field<0x1::TestMutRefs::T>.value($t0) - 1: $t3 := 1 - 2: $t4 := -($t2, $t3) - 3: $t5 := borrow_field<0x1::TestMutRefs::T>.value($t0) - 4: write_ref($t5, $t4) - 5: write_back[Reference($t0).value (u64)]($t5) - 6: trace_local[x]($t0) - 7: $t6 := 0x0 - 8: $t7 := borrow_global<0x1::TestMutRefs::TSum>($t6) - 9: $t8 := get_field<0x1::TestMutRefs::TSum>.sum($t7) - 10: $t9 := 1 - 11: $t10 := -($t8, $t9) - 12: $t11 := borrow_field<0x1::TestMutRefs::TSum>.sum($t7) - 13: write_ref($t11, $t10) - 14: write_back[Reference($t7).sum (u64)]($t11) - 15: write_back[0x1::TestMutRefs::TSum@]($t7) - 16: trace_local[x]($t0) - 17: return () -} - - -[variant baseline] -fun TestMutRefs::private_to_public_caller($t0|r: &mut 0x1::TestMutRefs::T) { - 0: TestMutRefs::increment($t0) - 1: trace_local[r]($t0) - 2: return () -} - - -[variant baseline] -fun TestMutRefs::private_to_public_caller_invalid_data_invariant() { - var $t0|r: &mut 0x1::TestMutRefs::T [unused] - var $t1|x: 0x1::TestMutRefs::T - var $t2: u64 - var $t3: &mut 0x1::TestMutRefs::T - 0: $t2 := 1 - 1: $t1 := TestMutRefs::new($t2) - 2: $t3 := borrow_local($t1) - 3: TestMutRefs::private_decrement($t3) - 4: TestMutRefs::increment($t3) - 5: write_back[LocalRoot($t1)@]($t3) - 6: trace_local[x]($t1) - 7: return () -} - - -[variant baseline] -public fun TestMutRefsUser::valid() { - var $t0|x: 0x1::TestMutRefs::T - var $t1: u64 - var $t2: &mut 0x1::TestMutRefs::T - var $t3: 0x1::TestMutRefs::T - 0: $t1 := 4 - 1: $t0 := TestMutRefs::new($t1) - 2: $t2 := borrow_local($t0) - 3: TestMutRefs::increment($t2) - 4: write_back[LocalRoot($t0)@]($t2) - 5: trace_local[x]($t0) - 6: $t3 := move($t0) - 7: TestMutRefs::delete($t3) - 8: return () -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/mono_analysis/test.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/mono_analysis/test.v2_exp deleted file mode 100644 index 80f164e8b3d..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/mono_analysis/test.v2_exp +++ /dev/null @@ -1,79 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::f1<#0>($t0|x1: #0): 0x123::Test::A<#0, u64> { - var $t1: #0 - var $t2: u64 - var $t3: 0x123::Test::A<#0, u64> - 0: $t1 := move($t0) - 1: $t2 := 10 - 2: $t3 := pack 0x123::Test::A<#0, u64>($t1, $t2) - 3: return $t3 -} - - -[variant baseline] -public fun Test::f2($t0|x: u8): 0x123::Test::B { - var $t1: u8 - var $t2: 0x123::Test::A - var $t3: 0x123::Test::B - 0: $t1 := move($t0) - 1: $t2 := Test::f1($t1) - 2: $t3 := pack 0x123::Test::B($t2) - 3: return $t3 -} - - -[variant baseline] -public fun Test::f3<#0>($t0|x1: #0): 0x123::Test::A<#0, u64> { - var $t1: #0 - var $t2: u64 - var $t3: 0x123::Test::A<#0, u64> - 0: $t1 := move($t0) - 1: $t2 := 1 - 2: $t3 := pack 0x123::Test::A<#0, u64>($t1, $t2) - 3: return $t3 -} - - -[variant baseline] -public fun Test::f4<#0>($t0|x1: #0): 0x123::Test::B<#0> { - var $t1: #0 - var $t2: 0x123::Test::A<#0, u64> - var $t3: 0x123::Test::B<#0> - 0: $t1 := move($t0) - 1: $t2 := Test::f3<#0>($t1) - 2: $t3 := pack 0x123::Test::B<#0>($t2) - 3: return $t3 -} - - -[variant baseline] -public fun Test::f5(): 0x123::Test::B { - var $t0: u128 - var $t1: 0x123::Test::B - 0: $t0 := 1 - 1: $t1 := Test::f4($t0) - 2: return $t1 -} - - - -==== mono-analysis result ==== - -struct Test::A = { - - - <#0, u64> -} -struct Test::B = { - - - <#0> -} -fun Test::f1 [baseline] = { - -} -fun Test::f4 [baseline] = { - -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.exp b/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.exp index 483d09d2d4a..4d4f2573f2c 100644 --- a/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.exp +++ b/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.exp @@ -210,23 +210,21 @@ fun TestEliminateMutRefs::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::T 36: goto 27 37: label L0 38: $t25 := move($t0) - 39: if ($t25) goto 40 else goto 49 + 39: if ($t25) goto 40 else goto 47 40: label L7 41: $t26 := move($t5) 42: drop($t26) 43: $t27 := move($t2) 44: $t28 := 0 45: TestEliminateMutRefs::test3($t27, $t28) - 46: goto 47 - 47: label L8 - 48: return () - 49: label L6 - 50: $t29 := move($t2) - 51: drop($t29) - 52: $t30 := move($t5) - 53: $t31 := 0 - 54: TestEliminateMutRefs::test3($t30, $t31) - 55: goto 47 + 46: return () + 47: label L6 + 48: $t29 := move($t2) + 49: drop($t29) + 50: $t30 := move($t5) + 51: $t31 := 0 + 52: TestEliminateMutRefs::test3($t30, $t31) + 53: return () } ============ after pipeline `mut_ref_instrumentation` ================ @@ -441,21 +439,21 @@ fun TestEliminateMutRefs::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::T 34: goto 25 35: label L0 36: $t25 := move($t0) - 37: if ($t25) goto 38 else goto 47 + 37: if ($t25) goto 38 else goto 46 38: label L7 39: $t26 := move($t5) 40: drop($t26) 41: $t27 := copy($t2) 42: $t28 := 0 43: TestEliminateMutRefs::test3($t27, $t28) - 44: label L8 - 45: trace_local[r_ref]($t2) - 46: return () - 47: label L6 - 48: $t29 := copy($t2) - 49: drop($t29) - 50: $t30 := move($t5) - 51: $t31 := 0 - 52: TestEliminateMutRefs::test3($t30, $t31) - 53: goto 44 + 44: trace_local[r_ref]($t2) + 45: return () + 46: label L6 + 47: $t29 := copy($t2) + 48: drop($t29) + 49: $t30 := move($t5) + 50: $t31 := 0 + 51: TestEliminateMutRefs::test3($t30, $t31) + 52: trace_local[r_ref]($t2) + 53: return () } diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.v2_exp deleted file mode 100644 index c94dd4a0879..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/mut_ref_instrumentation/basic_test.v2_exp +++ /dev/null @@ -1,460 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun TestEliminateMutRefs::test1(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1|x_ref: &mut u64 - var $t2: u64 - var $t3: 0x42::TestEliminateMutRefs::R - var $t4: &mut 0x42::TestEliminateMutRefs::R - var $t5: &mut u64 - var $t6: u64 - var $t7: &mut u64 - var $t8: 0x42::TestEliminateMutRefs::R - 0: $t2 := 3 - 1: $t3 := pack 0x42::TestEliminateMutRefs::R($t2) - 2: $t0 := $t3 - 3: $t4 := borrow_local($t0) - 4: $t5 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t4) - 5: $t1 := $t5 - 6: $t6 := 0 - 7: $t7 := move($t1) - 8: write_ref($t7, $t6) - 9: $t8 := move($t0) - 10: return $t8 -} - - -[variant baseline] -fun TestEliminateMutRefs::test2($t0|x_ref: &mut u64, $t1|v: u64) { - var $t2: u64 - var $t3: &mut u64 - 0: $t2 := move($t1) - 1: $t3 := move($t0) - 2: write_ref($t3, $t2) - 3: return () -} - - -[variant baseline] -public fun TestEliminateMutRefs::test3($t0|r_ref: &mut 0x42::TestEliminateMutRefs::R, $t1|v: u64) { - var $t2: &mut 0x42::TestEliminateMutRefs::R - var $t3: &mut u64 - var $t4: u64 - 0: $t2 := move($t0) - 1: $t3 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t2) - 2: $t4 := move($t1) - 3: TestEliminateMutRefs::test2($t3, $t4) - 4: return () -} - - -[variant baseline] -fun TestEliminateMutRefs::test4(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateMutRefs::R - var $t3: &mut 0x42::TestEliminateMutRefs::R - var $t4: u64 - var $t5: 0x42::TestEliminateMutRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateMutRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := 0 - 5: TestEliminateMutRefs::test3($t3, $t4) - 6: $t5 := move($t0) - 7: return $t5 -} - - -[variant baseline] -public fun TestEliminateMutRefs::test5($t0|r_ref: &mut 0x42::TestEliminateMutRefs::R): &mut u64 { - var $t1: &mut 0x42::TestEliminateMutRefs::R - var $t2: &mut u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t1) - 2: return $t2 -} - - -[variant baseline] -fun TestEliminateMutRefs::test6(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateMutRefs::R - var $t3: &mut 0x42::TestEliminateMutRefs::R - var $t4: &mut u64 - var $t5: u64 - var $t6: 0x42::TestEliminateMutRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateMutRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := TestEliminateMutRefs::test5($t3) - 5: $t5 := 0 - 6: TestEliminateMutRefs::test2($t4, $t5) - 7: $t6 := move($t0) - 8: return $t6 -} - - -[variant baseline] -fun TestEliminateMutRefs::test7($t0|b: bool) { - var $t1|r1: 0x42::TestEliminateMutRefs::R - var $t2|r2: 0x42::TestEliminateMutRefs::R - var $t3|r_ref: &mut 0x42::TestEliminateMutRefs::R - var $t4: u64 - var $t5: 0x42::TestEliminateMutRefs::R - var $t6: u64 - var $t7: 0x42::TestEliminateMutRefs::R - var $t8: &mut 0x42::TestEliminateMutRefs::R - var $t9: bool - var $t10: &mut 0x42::TestEliminateMutRefs::R - var $t11: &mut 0x42::TestEliminateMutRefs::R - var $t12: &mut 0x42::TestEliminateMutRefs::R - var $t13: u64 - 0: $t4 := 3 - 1: $t5 := pack 0x42::TestEliminateMutRefs::R($t4) - 2: $t1 := $t5 - 3: $t6 := 4 - 4: $t7 := pack 0x42::TestEliminateMutRefs::R($t6) - 5: $t2 := $t7 - 6: $t8 := borrow_local($t1) - 7: $t3 := $t8 - 8: $t9 := move($t0) - 9: if ($t9) goto 10 else goto 16 - 10: label L1 - 11: $t10 := move($t3) - 12: drop($t10) - 13: $t11 := borrow_local($t2) - 14: $t3 := $t11 - 15: goto 16 - 16: label L0 - 17: $t12 := move($t3) - 18: $t13 := 0 - 19: TestEliminateMutRefs::test3($t12, $t13) - 20: return () -} - - -[variant baseline] -fun TestEliminateMutRefs::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestEliminateMutRefs::R) { - var $t3|r1: 0x42::TestEliminateMutRefs::R - var $t4|r2: 0x42::TestEliminateMutRefs::R - var $t5|t_ref: &mut 0x42::TestEliminateMutRefs::R - var $t6: u64 - var $t7: 0x42::TestEliminateMutRefs::R - var $t8: u64 - var $t9: 0x42::TestEliminateMutRefs::R - var $t10: &mut 0x42::TestEliminateMutRefs::R - var $t11: u64 - var $t12: u64 - var $t13: bool - var $t14: &mut 0x42::TestEliminateMutRefs::R - var $t15: u64 - var $t16: u64 - var $t17: u64 - var $t18: u64 - var $t19: bool - var $t20: &mut 0x42::TestEliminateMutRefs::R - var $t21: &mut 0x42::TestEliminateMutRefs::R - var $t22: u64 - var $t23: u64 - var $t24: u64 - var $t25: bool - var $t26: &mut 0x42::TestEliminateMutRefs::R - var $t27: &mut 0x42::TestEliminateMutRefs::R - var $t28: u64 - var $t29: &mut 0x42::TestEliminateMutRefs::R - var $t30: &mut 0x42::TestEliminateMutRefs::R - var $t31: u64 - 0: $t6 := 3 - 1: $t7 := pack 0x42::TestEliminateMutRefs::R($t6) - 2: $t3 := $t7 - 3: $t8 := 4 - 4: $t9 := pack 0x42::TestEliminateMutRefs::R($t8) - 5: $t4 := $t9 - 6: $t10 := borrow_local($t4) - 7: $t5 := $t10 - 8: goto 9 - 9: label L6 - 10: $t11 := 0 - 11: $t12 := copy($t1) - 12: $t13 := <($t11, $t12) - 13: if ($t13) goto 14 else goto 39 - 14: label L1 - 15: goto 16 - 16: label L2 - 17: $t14 := move($t5) - 18: drop($t14) - 19: $t15 := copy($t1) - 20: $t16 := 2 - 21: $t17 := /($t15, $t16) - 22: $t18 := 0 - 23: $t19 := ==($t17, $t18) - 24: if ($t19) goto 25 else goto 29 - 25: label L4 - 26: $t20 := borrow_local($t3) - 27: $t5 := $t20 - 28: goto 33 - 29: label L3 - 30: $t21 := borrow_local($t4) - 31: $t5 := $t21 - 32: goto 33 - 33: label L5 - 34: $t22 := move($t1) - 35: $t23 := 1 - 36: $t24 := -($t22, $t23) - 37: $t1 := $t24 - 38: goto 9 - 39: label L0 - 40: $t25 := move($t0) - 41: if ($t25) goto 42 else goto 49 - 42: label L8 - 43: $t26 := move($t5) - 44: drop($t26) - 45: $t27 := move($t2) - 46: $t28 := 0 - 47: TestEliminateMutRefs::test3($t27, $t28) - 48: goto 56 - 49: label L7 - 50: $t29 := move($t2) - 51: drop($t29) - 52: $t30 := move($t5) - 53: $t31 := 0 - 54: TestEliminateMutRefs::test3($t30, $t31) - 55: goto 56 - 56: label L9 - 57: return () -} - -============ after pipeline `mut_ref_instrumentation` ================ - -[variant baseline] -fun TestEliminateMutRefs::test1(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1|x_ref: &mut u64 - var $t2: u64 - var $t3: 0x42::TestEliminateMutRefs::R - var $t4: &mut 0x42::TestEliminateMutRefs::R - var $t5: &mut u64 - var $t6: u64 - var $t7: &mut u64 - var $t8: 0x42::TestEliminateMutRefs::R - 0: $t2 := 3 - 1: $t3 := pack 0x42::TestEliminateMutRefs::R($t2) - 2: $t0 := $t3 - 3: $t4 := borrow_local($t0) - 4: $t5 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t4) - 5: $t1 := $t5 - 6: $t6 := 0 - 7: $t7 := move($t1) - 8: write_ref($t7, $t6) - 9: $t8 := move($t0) - 10: return $t8 -} - - -[variant baseline] -fun TestEliminateMutRefs::test2($t0|x_ref: &mut u64, $t1|v: u64) { - var $t2: u64 - var $t3: &mut u64 - 0: $t2 := move($t1) - 1: $t3 := copy($t0) - 2: write_ref($t3, $t2) - 3: trace_local[x_ref]($t0) - 4: return () -} - - -[variant baseline] -public fun TestEliminateMutRefs::test3($t0|r_ref: &mut 0x42::TestEliminateMutRefs::R, $t1|v: u64) { - var $t2: &mut 0x42::TestEliminateMutRefs::R - var $t3: &mut u64 - var $t4: u64 - 0: $t2 := copy($t0) - 1: $t3 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t2) - 2: $t4 := move($t1) - 3: TestEliminateMutRefs::test2($t3, $t4) - 4: trace_local[r_ref]($t0) - 5: return () -} - - -[variant baseline] -fun TestEliminateMutRefs::test4(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateMutRefs::R - var $t3: &mut 0x42::TestEliminateMutRefs::R - var $t4: u64 - var $t5: 0x42::TestEliminateMutRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateMutRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := 0 - 5: TestEliminateMutRefs::test3($t3, $t4) - 6: $t5 := move($t0) - 7: return $t5 -} - - -[variant baseline] -public fun TestEliminateMutRefs::test5($t0|r_ref: &mut 0x42::TestEliminateMutRefs::R): &mut u64 { - var $t1: &mut 0x42::TestEliminateMutRefs::R - var $t2: &mut u64 - 0: $t1 := copy($t0) - 1: $t2 := borrow_field<0x42::TestEliminateMutRefs::R>.x($t1) - 2: trace_local[r_ref]($t0) - 3: return $t2 -} - - -[variant baseline] -fun TestEliminateMutRefs::test6(): 0x42::TestEliminateMutRefs::R { - var $t0|r: 0x42::TestEliminateMutRefs::R - var $t1: u64 - var $t2: 0x42::TestEliminateMutRefs::R - var $t3: &mut 0x42::TestEliminateMutRefs::R - var $t4: &mut u64 - var $t5: u64 - var $t6: 0x42::TestEliminateMutRefs::R - 0: $t1 := 3 - 1: $t2 := pack 0x42::TestEliminateMutRefs::R($t1) - 2: $t0 := $t2 - 3: $t3 := borrow_local($t0) - 4: $t4 := TestEliminateMutRefs::test5($t3) - 5: $t5 := 0 - 6: TestEliminateMutRefs::test2($t4, $t5) - 7: $t6 := move($t0) - 8: return $t6 -} - - -[variant baseline] -fun TestEliminateMutRefs::test7($t0|b: bool) { - var $t1|r1: 0x42::TestEliminateMutRefs::R - var $t2|r2: 0x42::TestEliminateMutRefs::R - var $t3|r_ref: &mut 0x42::TestEliminateMutRefs::R - var $t4: u64 - var $t5: 0x42::TestEliminateMutRefs::R - var $t6: u64 - var $t7: 0x42::TestEliminateMutRefs::R - var $t8: &mut 0x42::TestEliminateMutRefs::R - var $t9: bool - var $t10: &mut 0x42::TestEliminateMutRefs::R - var $t11: &mut 0x42::TestEliminateMutRefs::R - var $t12: &mut 0x42::TestEliminateMutRefs::R - var $t13: u64 - 0: $t4 := 3 - 1: $t5 := pack 0x42::TestEliminateMutRefs::R($t4) - 2: $t1 := $t5 - 3: $t6 := 4 - 4: $t7 := pack 0x42::TestEliminateMutRefs::R($t6) - 5: $t2 := $t7 - 6: $t8 := borrow_local($t1) - 7: $t3 := $t8 - 8: $t9 := move($t0) - 9: if ($t9) goto 10 else goto 15 - 10: label L1 - 11: $t10 := move($t3) - 12: drop($t10) - 13: $t11 := borrow_local($t2) - 14: $t3 := $t11 - 15: label L0 - 16: $t12 := move($t3) - 17: $t13 := 0 - 18: TestEliminateMutRefs::test3($t12, $t13) - 19: return () -} - - -[variant baseline] -fun TestEliminateMutRefs::test8($t0|b: bool, $t1|n: u64, $t2|r_ref: &mut 0x42::TestEliminateMutRefs::R) { - var $t3|r1: 0x42::TestEliminateMutRefs::R - var $t4|r2: 0x42::TestEliminateMutRefs::R - var $t5|t_ref: &mut 0x42::TestEliminateMutRefs::R - var $t6: u64 - var $t7: 0x42::TestEliminateMutRefs::R - var $t8: u64 - var $t9: 0x42::TestEliminateMutRefs::R - var $t10: &mut 0x42::TestEliminateMutRefs::R - var $t11: u64 - var $t12: u64 - var $t13: bool - var $t14: &mut 0x42::TestEliminateMutRefs::R - var $t15: u64 - var $t16: u64 - var $t17: u64 - var $t18: u64 - var $t19: bool - var $t20: &mut 0x42::TestEliminateMutRefs::R - var $t21: &mut 0x42::TestEliminateMutRefs::R - var $t22: u64 - var $t23: u64 - var $t24: u64 - var $t25: bool - var $t26: &mut 0x42::TestEliminateMutRefs::R - var $t27: &mut 0x42::TestEliminateMutRefs::R - var $t28: u64 - var $t29: &mut 0x42::TestEliminateMutRefs::R - var $t30: &mut 0x42::TestEliminateMutRefs::R - var $t31: u64 - 0: $t6 := 3 - 1: $t7 := pack 0x42::TestEliminateMutRefs::R($t6) - 2: $t3 := $t7 - 3: $t8 := 4 - 4: $t9 := pack 0x42::TestEliminateMutRefs::R($t8) - 5: $t4 := $t9 - 6: $t10 := borrow_local($t4) - 7: $t5 := $t10 - 8: label L6 - 9: $t11 := 0 - 10: $t12 := copy($t1) - 11: $t13 := <($t11, $t12) - 12: if ($t13) goto 13 else goto 36 - 13: label L1 - 14: label L2 - 15: $t14 := move($t5) - 16: drop($t14) - 17: $t15 := copy($t1) - 18: $t16 := 2 - 19: $t17 := /($t15, $t16) - 20: $t18 := 0 - 21: $t19 := ==($t17, $t18) - 22: if ($t19) goto 23 else goto 27 - 23: label L4 - 24: $t20 := borrow_local($t3) - 25: $t5 := $t20 - 26: goto 30 - 27: label L3 - 28: $t21 := borrow_local($t4) - 29: $t5 := $t21 - 30: label L5 - 31: $t22 := move($t1) - 32: $t23 := 1 - 33: $t24 := -($t22, $t23) - 34: $t1 := $t24 - 35: goto 8 - 36: label L0 - 37: $t25 := move($t0) - 38: if ($t25) goto 39 else goto 46 - 39: label L8 - 40: $t26 := move($t5) - 41: drop($t26) - 42: $t27 := copy($t2) - 43: $t28 := 0 - 44: TestEliminateMutRefs::test3($t27, $t28) - 45: goto 52 - 46: label L7 - 47: $t29 := copy($t2) - 48: drop($t29) - 49: $t30 := move($t5) - 50: $t31 := 0 - 51: TestEliminateMutRefs::test3($t30, $t31) - 52: label L9 - 53: trace_local[r_ref]($t2) - 54: return () -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.exp b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.exp index 88539672d8c..24465082b5b 100644 --- a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.exp +++ b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.exp @@ -2,32 +2,25 @@ [variant baseline] fun Test::branching_result($t0|is_div: bool, $t1|a: u64, $t2|b: u64): u64 { - var $t3|$t4: u64 - var $t4: bool + var $t3: bool + var $t4: u64 var $t5: u64 var $t6: u64 var $t7: u64 var $t8: u64 var $t9: u64 - var $t10: u64 - var $t11: u64 - 0: $t4 := move($t0) - 1: if ($t4) goto 2 else goto 11 + 0: $t3 := move($t0) + 1: if ($t3) goto 2 else goto 7 2: label L1 - 3: $t5 := move($t1) - 4: $t6 := move($t2) - 5: $t7 := /($t5, $t6) - 6: $t3 := $t7 - 7: goto 8 - 8: label L2 - 9: $t8 := move($t3) - 10: return $t8 - 11: label L0 - 12: $t9 := move($t1) - 13: $t10 := move($t2) - 14: $t11 := *($t9, $t10) - 15: $t3 := $t11 - 16: goto 8 + 3: $t4 := move($t1) + 4: $t5 := move($t2) + 5: $t6 := /($t4, $t5) + 6: return $t6 + 7: label L0 + 8: $t7 := move($t1) + 9: $t8 := move($t2) + 10: $t9 := *($t7, $t8) + 11: return $t9 } @@ -162,30 +155,28 @@ fun Test::resource_with_old($t0|val: u64) { [variant verification] fun Test::branching_result($t0|is_div: bool, $t1|a: u64, $t2|b: u64): u64 { - var $t3|$t4: u64 + var $t3: u64 var $t4: num - 0: if ($t0) goto 1 else goto 5 + 0: if ($t0) goto 1 else goto 4 1: label L1 - 2: $t3 := /($t1, $t2) on_abort goto 13 with $t4 - 3: label L2 - 4: goto 8 - 5: label L0 - 6: $t3 := *($t1, $t2) on_abort goto 13 with $t4 - 7: goto 3 - 8: label L3 + 2: $t3 := /($t1, $t2) on_abort goto 11 with $t4 + 3: goto 6 + 4: label L0 + 5: $t3 := *($t1, $t2) on_abort goto 11 with $t4 + 6: label L2 # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:27:6+50 - 9: assert Not(And($t0, Eq($t2, 0))) + 7: assert Not(And($t0, Eq($t2, 0))) # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:28:6+35 - 10: assert Implies($t0, Eq($t3, Div($t1, $t2))) + 8: assert Implies($t0, Eq($t3, Div($t1, $t2))) # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:29:6+36 - 11: assert Implies(Not($t0), Eq($t3, Mul($t1, $t2))) - 12: return $t3 - 13: label L4 + 9: assert Implies(Not($t0), Eq($t3, Mul($t1, $t2))) + 10: return $t3 + 11: label L3 # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:26:2+165 - 14: assert And($t0, Eq($t2, 0)) + 12: assert And($t0, Eq($t2, 0)) # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:26:2+165 - 15: assert And(And($t0, Eq($t2, 0)), Eq(-1, $t4)) - 16: abort($t4) + 13: assert And(And($t0, Eq($t2, 0)), Eq(-1, $t4)) + 14: abort($t4) } diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.v2_exp deleted file mode 100644 index a7ad4677671..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/fun_spec.v2_exp +++ /dev/null @@ -1,460 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun Test::branching_result($t0|is_div: bool, $t1|a: u64, $t2|b: u64): u64 { - var $t3|tmp#$3: u64 - var $t4: bool - var $t5: u64 - var $t6: u64 - var $t7: u64 - var $t8: u64 - var $t9: u64 - var $t10: u64 - var $t11: u64 - 0: $t4 := move($t0) - 1: if ($t4) goto 2 else goto 8 - 2: label L1 - 3: $t5 := move($t1) - 4: $t6 := move($t2) - 5: $t7 := /($t5, $t6) - 6: $t3 := $t7 - 7: goto 14 - 8: label L0 - 9: $t8 := move($t1) - 10: $t9 := move($t2) - 11: $t10 := *($t8, $t9) - 12: $t3 := $t10 - 13: goto 14 - 14: label L2 - 15: $t11 := move($t3) - 16: return $t11 -} - - -[variant baseline] -fun Test::implicit_and_explicit_abort($t0|a: u64, $t1|b: u64): u64 { - var $t2: u64 - var $t3: u64 - var $t4: bool - var $t5: u64 - var $t6: u64 - var $t7: u64 - var $t8: u64 - 0: $t2 := copy($t1) - 1: $t3 := 0 - 2: $t4 := !=($t2, $t3) - 3: if ($t4) goto 4 else goto 7 - 4: label L1 - 5: $t5 := 22 - 6: abort($t5) - 7: label L0 - 8: $t6 := move($t0) - 9: $t7 := move($t1) - 10: $t8 := /($t6, $t7) - 11: return $t8 -} - - -[variant baseline] -fun Test::multiple_results($t0|a: u64, $t1|b: u64): (u64, u64) { - var $t2: u64 - var $t3: u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: u64 - 0: $t2 := copy($t0) - 1: $t3 := copy($t1) - 2: $t4 := /($t2, $t3) - 3: $t5 := move($t0) - 4: $t6 := move($t1) - 5: $t7 := %($t5, $t6) - 6: return ($t4, $t7) -} - - -[variant baseline] -fun Test::mut_ref_param($t0|r: &mut 0x42::Test::R): u64 { - var $t1|x: u64 - var $t2: &mut 0x42::Test::R - var $t3: &u64 - var $t4: u64 - var $t5: &mut 0x42::Test::R - var $t6: &u64 - var $t7: u64 - var $t8: u64 - var $t9: u64 - var $t10: &mut 0x42::Test::R - var $t11: &mut u64 - var $t12: u64 - 0: $t2 := copy($t0) - 1: $t3 := borrow_field<0x42::Test::R>.v($t2) - 2: $t4 := read_ref($t3) - 3: $t1 := $t4 - 4: $t5 := copy($t0) - 5: $t6 := borrow_field<0x42::Test::R>.v($t5) - 6: $t7 := read_ref($t6) - 7: $t8 := 1 - 8: $t9 := -($t7, $t8) - 9: $t10 := move($t0) - 10: $t11 := borrow_field<0x42::Test::R>.v($t10) - 11: write_ref($t11, $t9) - 12: $t12 := move($t1) - 13: return $t12 -} - - -[variant baseline] -fun Test::ref_param($t0|r: &0x42::Test::R): u64 { - var $t1: &0x42::Test::R - var $t2: &u64 - var $t3: u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_field<0x42::Test::R>.v($t1) - 2: $t3 := read_ref($t2) - 3: return $t3 -} - - -[variant baseline] -fun Test::ref_param_return_ref($t0|r: &0x42::Test::R): &u64 { - var $t1: &0x42::Test::R - var $t2: &u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_field<0x42::Test::R>.v($t1) - 2: return $t2 -} - - -[variant baseline] -fun Test::resource_with_old($t0|val: u64) { - var $t1|r: &mut 0x42::Test::R - var $t2: address - var $t3: bool - var $t4: bool - var $t5: u64 - var $t6: address - var $t7: &mut 0x42::Test::R - var $t8: &mut 0x42::Test::R - var $t9: &u64 - var $t10: u64 - var $t11: u64 - var $t12: u64 - var $t13: &mut 0x42::Test::R - var $t14: &mut u64 - 0: $t2 := 0x0 - 1: $t3 := exists<0x42::Test::R>($t2) - 2: $t4 := !($t3) - 3: if ($t4) goto 4 else goto 7 - 4: label L1 - 5: $t5 := 33 - 6: abort($t5) - 7: label L0 - 8: $t6 := 0x0 - 9: $t7 := borrow_global<0x42::Test::R>($t6) - 10: $t1 := $t7 - 11: $t8 := copy($t1) - 12: $t9 := borrow_field<0x42::Test::R>.v($t8) - 13: $t10 := read_ref($t9) - 14: $t11 := move($t0) - 15: $t12 := +($t10, $t11) - 16: $t13 := move($t1) - 17: $t14 := borrow_field<0x42::Test::R>.v($t13) - 18: write_ref($t14, $t12) - 19: return () -} - -============ after pipeline `spec_instrumentation` ================ - -[variant verification] -fun Test::branching_result($t0|is_div: bool, $t1|a: u64, $t2|b: u64): u64 { - var $t3|tmp#$3: u64 - var $t4: num - 0: if ($t0) goto 1 else goto 4 - 1: label L1 - 2: $t3 := /($t1, $t2) on_abort goto 12 with $t4 - 3: goto 6 - 4: label L0 - 5: $t3 := *($t1, $t2) on_abort goto 12 with $t4 - 6: label L2 - 7: label L3 - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:27:6+50 - 8: assert Not(And($t0, Eq($t2, 0))) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:28:6+35 - 9: assert Implies($t0, Eq($t3, Div($t1, $t2))) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:29:6+36 - 10: assert Implies(Not($t0), Eq($t3, Mul($t1, $t2))) - 11: return $t3 - 12: label L4 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:26:2+165 - 13: assert And($t0, Eq($t2, 0)) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:26:2+165 - 14: assert And(And($t0, Eq($t2, 0)), Eq(-1, $t4)) - 15: abort($t4) -} - - -[variant verification] -fun Test::implicit_and_explicit_abort($t0|a: u64, $t1|b: u64): u64 { - var $t2: u64 - var $t3: bool - var $t4: u64 - var $t5: num - var $t6: u64 - 0: $t2 := 0 - 1: $t3 := !=($t1, $t2) - 2: if ($t3) goto 3 else goto 7 - 3: label L1 - 4: $t4 := 22 - 5: $t5 := move($t4) - 6: goto 14 - 7: label L0 - 8: $t6 := /($t0, $t1) on_abort goto 14 with $t5 - 9: label L2 - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:9:6+25 - 10: assert Not(Eq($t1, 0)) - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:10:6+17 - 11: assert Not(Eq($t0, 0)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:11:6+24 - 12: assert Eq($t6, Div($t0, $t1)) - 13: return $t6 - 14: label L3 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:8:2+121 - 15: assert Or(Eq($t1, 0), Eq($t0, 0)) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:8:2+121 - 16: assert Or(And(Eq($t1, 0), Eq(22, $t5)), Eq($t0, 0)) - 17: abort($t5) -} - - -[variant verification] -fun Test::multiple_results($t0|a: u64, $t1|b: u64): (u64, u64) { - var $t2: u64 - var $t3: num - var $t4: u64 - 0: $t2 := /($t0, $t1) on_abort goto 7 with $t3 - 1: $t4 := %($t0, $t1) on_abort goto 7 with $t3 - 2: label L1 - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:18:6+40 - 3: assert Not(Eq($t1, 0)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:19:6+26 - 4: assert Eq($t2, Div($t0, $t1)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:20:6+26 - 5: assert Eq($t4, Mod($t0, $t1)) - 6: return ($t2, $t4) - 7: label L2 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:17:2+136 - 8: assert Eq($t1, 0) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:17:2+136 - 9: assert And(Eq($t1, 0), Eq(-1, $t3)) - 10: abort($t3) -} - - -[variant verification] -fun Test::mut_ref_param($t0|r: &mut 0x42::Test::R): u64 { - var $t1|x: u64 - var $t2: 0x42::Test::R - var $t3: u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - var $t7: num - var $t8: &mut u64 - 0: $t2 := read_ref($t0) - 1: $t3 := get_field<0x42::Test::R>.v($t0) - 2: $t4 := get_field<0x42::Test::R>.v($t0) - 3: $t5 := 1 - 4: $t6 := -($t4, $t5) on_abort goto 15 with $t7 - 5: $t8 := borrow_field<0x42::Test::R>.v($t0) - 6: write_ref($t8, $t6) - 7: write_back[Reference($t0).v (u64)]($t8) - 8: trace_local[r]($t0) - 9: trace_local[r]($t0) - 10: label L1 - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:67:6+42 - 11: assert Not(Eq(select Test::R.v<0x42::Test::R>($t2), 0)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:68:6+27 - 12: assert Eq($t3, select Test::R.v<0x42::Test::R>($t2)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:69:6+28 - 13: assert Eq(select Test::R.v<0x42::Test::R>($t0), Add(select Test::R.v<0x42::Test::R>($t2), 1)) - 14: return $t3 - 15: label L2 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:66:2+138 - 16: assert Eq(select Test::R.v<0x42::Test::R>($t2), 0) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:66:2+138 - 17: assert And(Eq(select Test::R.v<0x42::Test::R>($t2), 0), Eq(-1, $t7)) - 18: abort($t7) -} - - -[variant verification] -fun Test::ref_param($t0|r: 0x42::Test::R): u64 { - var $t1: u64 - 0: $t1 := get_field<0x42::Test::R>.v($t0) - 1: label L1 - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:51:6+22 - 2: assert Eq($t1, select Test::R.v<0x42::Test::R>($t0)) - 3: return $t1 -} - - -[variant verification] -fun Test::ref_param_return_ref($t0|r: 0x42::Test::R): u64 { - var $t1: u64 - 0: $t1 := get_field<0x42::Test::R>.v($t0) - 1: label L1 - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:58:6+22 - 2: assert Eq($t1, select Test::R.v<0x42::Test::R>($t0)) - 3: return $t1 -} - - -[variant verification] -fun Test::resource_with_old($t0|val: u64) { - var $t1|r: &mut 0x42::Test::R - var $t2: address - var $t3: bool - var $t4: bool - var $t5: u64 - var $t6: num - var $t7: address - var $t8: &mut 0x42::Test::R - var $t9: u64 - var $t10: u64 - var $t11: &mut u64 - 0: assume Gt($t0, 0) - 1: assume CanModify<0x42::Test::R>(0x0) - 2: @0 := save_mem(Test::R) - 3: $t2 := 0x0 - 4: $t3 := exists<0x42::Test::R>($t2) - 5: $t4 := !($t3) - 6: if ($t4) goto 7 else goto 11 - 7: label L1 - 8: $t5 := 33 - 9: $t6 := move($t5) - 10: goto 26 - 11: label L0 - 12: $t7 := 0x0 - # VC: caller does not have permission to modify `Test::R` at given address at tests/spec_instrumentation/fun_spec.move:36:14+17 - 13: assert CanModify<0x42::Test::R>($t7) - 14: $t8 := borrow_global<0x42::Test::R>($t7) on_abort goto 26 with $t6 - 15: $t9 := get_field<0x42::Test::R>.v($t8) - 16: $t10 := +($t9, $t0) on_abort goto 26 with $t6 - 17: $t11 := borrow_field<0x42::Test::R>.v($t8) - 18: write_ref($t11, $t10) - 19: write_back[Reference($t8).v (u64)]($t11) - 20: write_back[0x42::Test::R@]($t8) - 21: label L2 - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:41:6+35 - 22: assert Not(Not(exists[@0]<0x42::Test::R>(0x0))) - # VC: function does not abort under this condition at tests/spec_instrumentation/fun_spec.move:42:6+58 - 23: assert Not(Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>(0x0)), $t0), 18446744073709551615)) - # VC: post-condition does not hold at tests/spec_instrumentation/fun_spec.move:43:6+58 - 24: assert Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x0)), Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>(0x0)), $t0)) - 25: return () - 26: label L3 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/fun_spec.move:39:2+250 - 27: assert Or(Not(exists[@0]<0x42::Test::R>(0x0)), Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>(0x0)), $t0), 18446744073709551615)) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/fun_spec.move:39:2+250 - 28: assert Or(And(Not(exists[@0]<0x42::Test::R>(0x0)), Eq(33, $t6)), Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>(0x0)), $t0), 18446744073709551615)) - 29: abort($t6) -} - - - -==== spec-instrumenter input specs ==== - -fun Test::branching_result[baseline] -spec { - aborts_if And($t0, Eq($t2, 0)); - ensures Implies($t0, Eq(result0(), Div($t1, $t2))); - ensures Implies(Not($t0), Eq(result0(), Mul($t1, $t2))); -} - -fun Test::branching_result[verification] -spec { - aborts_if And($t0, Eq($t2, 0)); - ensures Implies($t0, Eq(result0(), Div($t1, $t2))); - ensures Implies(Not($t0), Eq(result0(), Mul($t1, $t2))); -} - -fun Test::implicit_and_explicit_abort[baseline] -spec { - aborts_if Eq($t1, 0); - aborts_if Eq($t0, 0); - ensures Eq(result0(), Div($t0, $t1)); -} - -fun Test::implicit_and_explicit_abort[verification] -spec { - aborts_if Eq($t1, 0); - aborts_if Eq($t0, 0); - ensures Eq(result0(), Div($t0, $t1)); -} - -fun Test::multiple_results[baseline] -spec { - aborts_if Eq($t1, 0); - ensures Eq(result0(), Div($t0, $t1)); - ensures Eq(result1(), Mod($t0, $t1)); -} - -fun Test::multiple_results[verification] -spec { - aborts_if Eq($t1, 0); - ensures Eq(result0(), Div($t0, $t1)); - ensures Eq(result1(), Mod($t0, $t1)); -} - -fun Test::mut_ref_param[baseline] -spec { - aborts_if Eq(select Test::R.v<0x42::Test::R>($t0), 0); - ensures Eq(result0(), Old(select Test::R.v<0x42::Test::R>($t0))); - ensures Eq(select Test::R.v<0x42::Test::R>($t0), Add(Old(select Test::R.v<0x42::Test::R>($t0)), 1)); -} - -fun Test::mut_ref_param[verification] -spec { - aborts_if Eq(select Test::R.v<0x42::Test::R>($t0), 0); - ensures Eq(result0(), Old(select Test::R.v<0x42::Test::R>($t0))); - ensures Eq(select Test::R.v<0x42::Test::R>($t0), Add(Old(select Test::R.v<0x42::Test::R>($t0)), 1)); -} - -fun Test::ref_param[baseline] -spec { - ensures Eq(result0(), select Test::R.v<0x42::Test::R>($t0)); -} - -fun Test::ref_param[verification] -spec { - ensures Eq(result0(), select Test::R.v<0x42::Test::R>($t0)); -} - -fun Test::ref_param_return_ref[baseline] -spec { - ensures Eq(result0(), select Test::R.v<0x42::Test::R>($t0)); -} - -fun Test::ref_param_return_ref[verification] -spec { - ensures Eq(result0(), select Test::R.v<0x42::Test::R>($t0)); -} - -fun Test::resource_with_old[baseline] -spec { - requires Gt($t0, 0); - aborts_if Not(exists<0x42::Test::R>(0x0)); - aborts_if Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x0)), $t0), 18446744073709551615); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x0)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>(0x0))), $t0)); - modifies global<0x42::Test::R>(0x0); -} - -fun Test::resource_with_old[verification] -spec { - requires Gt($t0, 0); - aborts_if Not(exists<0x42::Test::R>(0x0)); - aborts_if Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x0)), $t0), 18446744073709551615); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x0)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>(0x0))), $t0)); - modifies global<0x42::Test::R>(0x0); -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/generics.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/generics.v2_exp deleted file mode 100644 index 20d3c90eb52..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/generics.v2_exp +++ /dev/null @@ -1,94 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun Generics::remove<#0>($t0|a: address): 0x42::Generics::R<#0> { - var $t1: address - var $t2: 0x42::Generics::R<#0> - 0: $t1 := move($t0) - 1: $t2 := move_from<0x42::Generics::R<#0>>($t1) - 2: return $t2 -} - - -[variant baseline] -fun Generics::remove_u64($t0|a: address): 0x42::Generics::R { - var $t1: address - var $t2: 0x42::Generics::R - 0: $t1 := move($t0) - 1: $t2 := Generics::remove($t1) - 2: return $t2 -} - -============ after pipeline `spec_instrumentation` ================ - -[variant verification] -fun Generics::remove<#0>($t0|a: address): 0x42::Generics::R<#0> { - var $t1: 0x42::Generics::R<#0> - var $t2: num - 0: assume CanModify<0x42::Generics::R<#0>>($t0) - # VC: caller does not have permission to modify `Generics::R<#0>` at given address at tests/spec_instrumentation/generics.move:11:9+9 - 1: assert CanModify<0x42::Generics::R<#0>>($t0) - 2: $t1 := move_from<0x42::Generics::R<#0>>($t0) on_abort goto 6 with $t2 - 3: label L1 - # VC: post-condition does not hold at tests/spec_instrumentation/generics.move:20:9+25 - 4: assert Not(exists<0x42::Generics::R<#0>>($t0)) - 5: return $t1 - 6: label L2 - 7: abort($t2) -} - - -[variant verification] -fun Generics::remove_u64($t0|a: address): 0x42::Generics::R { - var $t1: 0x42::Generics::R - var $t2: bool - var $t3: num - 0: assume CanModify<0x42::Generics::R>($t0) - # VC: caller does not have permission to modify `Generics::R` at given address at tests/spec_instrumentation/generics.move:24:9+14 - 1: assert CanModify<0x42::Generics::R>($t0) - 2: $t1 := opaque begin: Generics::remove($t0) - 3: $t2 := havoc[val]() - 4: if ($t2) goto 5 else goto 8 - 5: label L4 - 6: trace_abort($t3) - 7: goto 16 - 8: label L3 - 9: modifies global<0x42::Generics::R>($t0) - 10: assume WellFormed($t1) - 11: assume Not(exists<0x42::Generics::R>($t0)) - 12: $t1 := opaque end: Generics::remove($t0) - 13: label L1 - # VC: post-condition does not hold at tests/spec_instrumentation/generics.move:20:9+25 - 14: assert Not(exists<0x42::Generics::R>($t0)) - 15: return $t1 - 16: label L2 - 17: abort($t3) -} - - - -==== spec-instrumenter input specs ==== - -fun Generics::remove[baseline] -spec { - modifies global<0x42::Generics::R<#0>>($t0); - ensures Not(exists<0x42::Generics::R<#0>>($t0)); -} - -fun Generics::remove[verification] -spec { - modifies global<0x42::Generics::R<#0>>($t0); - ensures Not(exists<0x42::Generics::R<#0>>($t0)); -} - -fun Generics::remove_u64[baseline] -spec { - modifies global<0x42::Generics::R>($t0); - ensures Not(exists<0x42::Generics::R>($t0)); -} - -fun Generics::remove_u64[verification] -spec { - modifies global<0x42::Generics::R>($t0); - ensures Not(exists<0x42::Generics::R>($t0)); -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/modifies.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/modifies.v2_exp deleted file mode 100644 index f080a521771..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/modifies.v2_exp +++ /dev/null @@ -1,576 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun A::mutate_at($t0|addr: address) { - var $t1|s: &mut 0x0::A::S - var $t2: address - var $t3: &mut 0x0::A::S - var $t4: u64 - var $t5: &mut 0x0::A::S - var $t6: &mut u64 - 0: $t2 := move($t0) - 1: $t3 := borrow_global<0x0::A::S>($t2) - 2: $t1 := $t3 - 3: $t4 := 2 - 4: $t5 := move($t1) - 5: $t6 := borrow_field<0x0::A::S>.x($t5) - 6: write_ref($t6, $t4) - 7: return () -} - - -[variant baseline] -public fun A::read_at($t0|addr: address): u64 { - var $t1: address - var $t2: &0x0::A::S - var $t3: &u64 - var $t4: u64 - 0: $t1 := move($t0) - 1: $t2 := borrow_global<0x0::A::S>($t1) - 2: $t3 := borrow_field<0x0::A::S>.x($t2) - 3: $t4 := read_ref($t3) - 4: return $t4 -} - - -[variant baseline] -public fun B::move_from_test_incorrect($t0|addr1: address, $t1|addr2: address): 0x0::B::T { - var $t2|v: 0x0::B::T - var $t3|x0: u64 - var $t4|x1: u64 - var $t5: address - var $t6: u64 - var $t7: address - var $t8: 0x0::B::T - var $t9: address - var $t10: u64 - var $t11: 0x0::B::T - 0: $t5 := copy($t1) - 1: $t6 := A::read_at($t5) - 2: $t3 := $t6 - 3: $t7 := move($t0) - 4: $t8 := move_from<0x0::B::T>($t7) - 5: $t2 := $t8 - 6: $t9 := move($t1) - 7: $t10 := A::read_at($t9) - 8: $t4 := $t10 - 9: assert Eq($t3, $t4) - 10: $t11 := move($t2) - 11: return $t11 -} - - -[variant baseline] -public fun B::move_to_test_incorrect($t0|account: &signer, $t1|addr2: address) { - var $t2|x0: u64 - var $t3|x1: u64 - var $t4: address - var $t5: u64 - var $t6: &signer - var $t7: u64 - var $t8: 0x0::B::T - var $t9: address - var $t10: u64 - 0: $t4 := copy($t1) - 1: $t5 := A::read_at($t4) - 2: $t2 := $t5 - 3: $t6 := move($t0) - 4: $t7 := 2 - 5: $t8 := pack 0x0::B::T($t7) - 6: move_to<0x0::B::T>($t8, $t6) - 7: $t9 := move($t1) - 8: $t10 := A::read_at($t9) - 9: $t3 := $t10 - 10: assert Eq($t2, $t3) - 11: return () -} - - -[variant baseline] -public fun B::mutate_S_test1_incorrect($t0|addr1: address, $t1|addr2: address) { - var $t2|x0: u64 - var $t3|x1: u64 - var $t4: address - var $t5: u64 - var $t6: address - var $t7: address - var $t8: u64 - 0: $t4 := copy($t1) - 1: $t5 := A::read_at($t4) - 2: $t2 := $t5 - 3: $t6 := move($t0) - 4: A::mutate_at($t6) - 5: $t7 := move($t1) - 6: $t8 := A::read_at($t7) - 7: $t3 := $t8 - 8: assert Eq($t2, $t3) - 9: return () -} - - -[variant baseline] -public fun B::mutate_S_test2_incorrect($t0|addr: address) { - var $t1|x0: u64 - var $t2|x1: u64 - var $t3: address - var $t4: u64 - var $t5: address - var $t6: address - var $t7: u64 - 0: $t3 := copy($t0) - 1: $t4 := A::read_at($t3) - 2: $t1 := $t4 - 3: $t5 := copy($t0) - 4: A::mutate_at($t5) - 5: $t6 := move($t0) - 6: $t7 := A::read_at($t6) - 7: $t2 := $t7 - 8: assert Eq($t1, $t2) - 9: return () -} - - -[variant baseline] -public fun B::mutate_at_test_incorrect($t0|addr1: address, $t1|addr2: address) { - var $t2|t: &mut 0x0::B::T - var $t3|x0: u64 - var $t4|x1: u64 - var $t5: address - var $t6: u64 - var $t7: address - var $t8: &mut 0x0::B::T - var $t9: u64 - var $t10: &mut 0x0::B::T - var $t11: &mut u64 - var $t12: address - var $t13: u64 - 0: $t5 := copy($t1) - 1: $t6 := A::read_at($t5) - 2: $t3 := $t6 - 3: $t7 := move($t0) - 4: $t8 := borrow_global<0x0::B::T>($t7) - 5: $t2 := $t8 - 6: $t9 := 2 - 7: $t10 := move($t2) - 8: $t11 := borrow_field<0x0::B::T>.x($t10) - 9: write_ref($t11, $t9) - 10: $t12 := move($t1) - 11: $t13 := A::read_at($t12) - 12: $t4 := $t13 - 13: assert Eq($t3, $t4) - 14: return () -} - -============ after pipeline `spec_instrumentation` ================ - -[variant verification] -public fun A::mutate_at($t0|addr: address) { - var $t1|s: &mut 0x0::A::S - var $t2: &mut 0x0::A::S - var $t3: num - var $t4: u64 - var $t5: &mut u64 - 0: assume CanModify<0x0::A::S>($t0) - 1: @0 := save_mem(A::S) - # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:18:17+17 - 2: assert CanModify<0x0::A::S>($t0) - 3: $t2 := borrow_global<0x0::A::S>($t0) on_abort goto 13 with $t3 - 4: $t4 := 2 - 5: $t5 := borrow_field<0x0::A::S>.x($t2) - 6: write_ref($t5, $t4) - 7: write_back[Reference($t2).x (u64)]($t5) - 8: write_back[0x0::A::S@]($t2) - 9: label L1 - # VC: function does not abort under this condition at tests/spec_instrumentation/modifies.move:24:9+27 - 10: assert Not(Not(exists[@0]<0x0::A::S>($t0))) - # VC: post-condition does not hold at tests/spec_instrumentation/modifies.move:23:9+31 - 11: assert Eq(select A::S.x<0x0::A::S>(global<0x0::A::S>($t0)), 2) - 12: return () - 13: label L2 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/modifies.move:21:5+162 - 14: assert Not(exists[@0]<0x0::A::S>($t0)) - 15: abort($t3) -} - - -[variant verification] -public fun A::read_at($t0|addr: address): u64 { - var $t1: 0x0::A::S - var $t2: num - var $t3: u64 - 0: @1 := save_mem(A::S) - 1: $t1 := get_global<0x0::A::S>($t0) on_abort goto 7 with $t2 - 2: $t3 := get_field<0x0::A::S>.x($t1) - 3: label L1 - # VC: function does not abort under this condition at tests/spec_instrumentation/modifies.move:13:9+27 - 4: assert Not(Not(exists[@1]<0x0::A::S>($t0))) - # VC: post-condition does not hold at tests/spec_instrumentation/modifies.move:14:9+36 - 5: assert Eq($t3, select A::S.x<0x0::A::S>(global<0x0::A::S>($t0))) - 6: return $t3 - 7: label L2 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/modifies.move:11:5+131 - 8: assert Not(exists[@1]<0x0::A::S>($t0)) - 9: abort($t2) -} - - -[variant verification] -public fun B::move_from_test_incorrect($t0|addr1: address, $t1|addr2: address): 0x0::B::T { - var $t2|v: 0x0::B::T - var $t3|x0: u64 - var $t4|x1: u64 - var $t5: u64 - var $t6: bool - var $t7: num - var $t8: 0x0::B::T - var $t9: u64 - var $t10: bool - 0: assume CanModify<0x0::B::T>($t1) - 1: $t5 := opaque begin: A::read_at($t1) - 2: assume Identical($t6, Not(exists<0x0::A::S>($t1))) - 3: if ($t6) goto 4 else goto 7 - 4: label L4 - 5: trace_abort($t7) - 6: goto 26 - 7: label L3 - 8: assume WellFormed($t5) - 9: assume Eq($t5, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 10: $t5 := opaque end: A::read_at($t1) - # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:65:17+9 - 11: assert CanModify<0x0::B::T>($t0) - 12: $t8 := move_from<0x0::B::T>($t0) on_abort goto 26 with $t7 - 13: $t9 := opaque begin: A::read_at($t1) - 14: assume Identical($t10, Not(exists<0x0::A::S>($t1))) - 15: if ($t10) goto 16 else goto 19 - 16: label L6 - 17: trace_abort($t7) - 18: goto 26 - 19: label L5 - 20: assume WellFormed($t9) - 21: assume Eq($t9, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 22: $t9 := opaque end: A::read_at($t1) - 23: assert Eq($t5, $t9) - 24: label L1 - 25: return $t8 - 26: label L2 - 27: abort($t7) -} - - -[variant verification] -public fun B::move_to_test_incorrect($t0|account: signer, $t1|addr2: address) { - var $t2|x0: u64 - var $t3|x1: u64 - var $t4: u64 - var $t5: bool - var $t6: num - var $t7: u64 - var $t8: 0x0::B::T - var $t9: u64 - var $t10: bool - 0: assume CanModify<0x0::B::T>($t1) - 1: $t4 := opaque begin: A::read_at($t1) - 2: assume Identical($t5, Not(exists<0x0::A::S>($t1))) - 3: if ($t5) goto 4 else goto 7 - 4: label L4 - 5: trace_abort($t6) - 6: goto 28 - 7: label L3 - 8: assume WellFormed($t4) - 9: assume Eq($t4, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 10: $t4 := opaque end: A::read_at($t1) - 11: $t7 := 2 - 12: $t8 := pack 0x0::B::T($t7) - # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:52:9+7 - 13: assert CanModify<0x0::B::T>($t0) - 14: move_to<0x0::B::T>($t8, $t0) on_abort goto 28 with $t6 - 15: $t9 := opaque begin: A::read_at($t1) - 16: assume Identical($t10, Not(exists<0x0::A::S>($t1))) - 17: if ($t10) goto 18 else goto 21 - 18: label L6 - 19: trace_abort($t6) - 20: goto 28 - 21: label L5 - 22: assume WellFormed($t9) - 23: assume Eq($t9, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 24: $t9 := opaque end: A::read_at($t1) - 25: assert Eq($t4, $t9) - 26: label L1 - 27: return () - 28: label L2 - 29: abort($t6) -} - - -[variant verification] -public fun B::mutate_S_test1_incorrect($t0|addr1: address, $t1|addr2: address) { - var $t2|x0: u64 - var $t3|x1: u64 - var $t4: u64 - var $t5: bool - var $t6: num - var $t7: bool - var $t8: u64 - var $t9: bool - 0: assume Neq
($t0, $t1) - 1: assume CanModify<0x0::A::S>($t1) - 2: $t4 := opaque begin: A::read_at($t1) - 3: assume Identical($t5, Not(exists<0x0::A::S>($t1))) - 4: if ($t5) goto 5 else goto 8 - 5: label L4 - 6: trace_abort($t6) - 7: goto 36 - 8: label L3 - 9: assume WellFormed($t4) - 10: assume Eq($t4, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 11: $t4 := opaque end: A::read_at($t1) - # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:79:9+19 - 12: assert CanModify<0x0::A::S>($t0) - 13: opaque begin: A::mutate_at($t0) - 14: assume Identical($t7, Not(exists<0x0::A::S>($t0))) - 15: if ($t7) goto 16 else goto 19 - 16: label L6 - 17: trace_abort($t6) - 18: goto 36 - 19: label L5 - 20: modifies global<0x0::A::S>($t0) - 21: assume Eq(select A::S.x<0x0::A::S>(global<0x0::A::S>($t0)), 2) - 22: opaque end: A::mutate_at($t0) - 23: $t8 := opaque begin: A::read_at($t1) - 24: assume Identical($t9, Not(exists<0x0::A::S>($t1))) - 25: if ($t9) goto 26 else goto 29 - 26: label L8 - 27: trace_abort($t6) - 28: goto 36 - 29: label L7 - 30: assume WellFormed($t8) - 31: assume Eq($t8, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 32: $t8 := opaque end: A::read_at($t1) - 33: assert Eq($t4, $t8) - 34: label L1 - 35: return () - 36: label L2 - 37: abort($t6) -} - - -[variant verification] -public fun B::mutate_S_test2_incorrect($t0|addr: address) { - var $t1|x0: u64 - var $t2|x1: u64 - var $t3: u64 - var $t4: bool - var $t5: num - var $t6: bool - var $t7: u64 - var $t8: bool - 0: assume CanModify<0x0::A::S>($t0) - 1: $t3 := opaque begin: A::read_at($t0) - 2: assume Identical($t4, Not(exists<0x0::A::S>($t0))) - 3: if ($t4) goto 4 else goto 7 - 4: label L4 - 5: trace_abort($t5) - 6: goto 35 - 7: label L3 - 8: assume WellFormed($t3) - 9: assume Eq($t3, select A::S.x<0x0::A::S>(global<0x0::A::S>($t0))) - 10: $t3 := opaque end: A::read_at($t0) - # VC: caller does not have permission to modify `A::S` at given address at tests/spec_instrumentation/modifies.move:92:9+18 - 11: assert CanModify<0x0::A::S>($t0) - 12: opaque begin: A::mutate_at($t0) - 13: assume Identical($t6, Not(exists<0x0::A::S>($t0))) - 14: if ($t6) goto 15 else goto 18 - 15: label L6 - 16: trace_abort($t5) - 17: goto 35 - 18: label L5 - 19: modifies global<0x0::A::S>($t0) - 20: assume Eq(select A::S.x<0x0::A::S>(global<0x0::A::S>($t0)), 2) - 21: opaque end: A::mutate_at($t0) - 22: $t7 := opaque begin: A::read_at($t0) - 23: assume Identical($t8, Not(exists<0x0::A::S>($t0))) - 24: if ($t8) goto 25 else goto 28 - 25: label L8 - 26: trace_abort($t5) - 27: goto 35 - 28: label L7 - 29: assume WellFormed($t7) - 30: assume Eq($t7, select A::S.x<0x0::A::S>(global<0x0::A::S>($t0))) - 31: $t7 := opaque end: A::read_at($t0) - 32: assert Eq($t3, $t7) - 33: label L1 - 34: return () - 35: label L2 - 36: abort($t5) -} - - -[variant verification] -public fun B::mutate_at_test_incorrect($t0|addr1: address, $t1|addr2: address) { - var $t2|t: &mut 0x0::B::T - var $t3|x0: u64 - var $t4|x1: u64 - var $t5: u64 - var $t6: bool - var $t7: num - var $t8: &mut 0x0::B::T - var $t9: u64 - var $t10: &mut u64 - var $t11: u64 - var $t12: bool - 0: assume CanModify<0x0::B::T>($t1) - 1: $t5 := opaque begin: A::read_at($t1) - 2: assume Identical($t6, Not(exists<0x0::A::S>($t1))) - 3: if ($t6) goto 4 else goto 7 - 4: label L4 - 5: trace_abort($t7) - 6: goto 31 - 7: label L3 - 8: assume WellFormed($t5) - 9: assume Eq($t5, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 10: $t5 := opaque end: A::read_at($t1) - # VC: caller does not have permission to modify `B::T` at given address at tests/spec_instrumentation/modifies.move:38:17+17 - 11: assert CanModify<0x0::B::T>($t0) - 12: $t8 := borrow_global<0x0::B::T>($t0) on_abort goto 31 with $t7 - 13: $t9 := 2 - 14: $t10 := borrow_field<0x0::B::T>.x($t8) - 15: write_ref($t10, $t9) - 16: write_back[Reference($t8).x (u64)]($t10) - 17: write_back[0x0::B::T@]($t8) - 18: $t11 := opaque begin: A::read_at($t1) - 19: assume Identical($t12, Not(exists<0x0::A::S>($t1))) - 20: if ($t12) goto 21 else goto 24 - 21: label L6 - 22: trace_abort($t7) - 23: goto 31 - 24: label L5 - 25: assume WellFormed($t11) - 26: assume Eq($t11, select A::S.x<0x0::A::S>(global<0x0::A::S>($t1))) - 27: $t11 := opaque end: A::read_at($t1) - 28: assert Eq($t5, $t11) - 29: label L1 - 30: return () - 31: label L2 - 32: abort($t7) -} - - - -==== spec-instrumenter input specs ==== - -fun A::mutate_at[baseline] -spec { - ensures Eq(select A::S.x<0x0::A::S>(global<0x0::A::S>($t0)), 2); - aborts_if Not(exists<0x0::A::S>($t0)); - modifies global<0x0::A::S>($t0); -} - -fun A::mutate_at[verification] -spec { - ensures Eq(select A::S.x<0x0::A::S>(global<0x0::A::S>($t0)), 2); - aborts_if Not(exists<0x0::A::S>($t0)); - modifies global<0x0::A::S>($t0); -} - -fun A::read_at[baseline] -spec { - aborts_if Not(exists<0x0::A::S>($t0)); - ensures Eq(result0(), select A::S.x<0x0::A::S>(global<0x0::A::S>($t0))); -} - -fun A::read_at[verification] -spec { - aborts_if Not(exists<0x0::A::S>($t0)); - ensures Eq(result0(), select A::S.x<0x0::A::S>(global<0x0::A::S>($t0))); -} - -fun B::move_from_test_incorrect[baseline] -spec { - modifies global<0x0::B::T>($t1); -} -9 -> spec { - assert Eq($t3, $t4); -} - - -fun B::move_from_test_incorrect[verification] -spec { - modifies global<0x0::B::T>($t1); -} -9 -> spec { - assert Eq($t3, $t4); -} - - -fun B::move_to_test_incorrect[baseline] -spec { - modifies global<0x0::B::T>($t1); -} -10 -> spec { - assert Eq($t2, $t3); -} - - -fun B::move_to_test_incorrect[verification] -spec { - modifies global<0x0::B::T>($t1); -} -10 -> spec { - assert Eq($t2, $t3); -} - - -fun B::mutate_S_test1_incorrect[baseline] -spec { - requires Neq
($t0, $t1); - modifies global<0x0::A::S>($t1); -} -8 -> spec { - assert Eq($t2, $t3); -} - - -fun B::mutate_S_test1_incorrect[verification] -spec { - requires Neq
($t0, $t1); - modifies global<0x0::A::S>($t1); -} -8 -> spec { - assert Eq($t2, $t3); -} - - -fun B::mutate_S_test2_incorrect[baseline] -spec { - modifies global<0x0::A::S>($t0); -} -8 -> spec { - assert Eq($t1, $t2); -} - - -fun B::mutate_S_test2_incorrect[verification] -spec { - modifies global<0x0::A::S>($t0); -} -8 -> spec { - assert Eq($t1, $t2); -} - - -fun B::mutate_at_test_incorrect[baseline] -spec { - modifies global<0x0::B::T>($t1); -} -13 -> spec { - assert Eq($t3, $t4); -} - - -fun B::mutate_at_test_incorrect[verification] -spec { - modifies global<0x0::B::T>($t1); -} -13 -> spec { - assert Eq($t3, $t4); -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/opaque_call.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/opaque_call.v2_exp deleted file mode 100644 index 1ad51d37ed3..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/spec_instrumentation/opaque_call.v2_exp +++ /dev/null @@ -1,218 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun Test::get_and_incr($t0|addr: address): u64 { - var $t1|r: &mut 0x42::Test::R - var $t2|v: u64 - var $t3: address - var $t4: bool - var $t5: bool - var $t6: u64 - var $t7: address - var $t8: &mut 0x42::Test::R - var $t9: &mut 0x42::Test::R - var $t10: &u64 - var $t11: u64 - var $t12: &mut 0x42::Test::R - var $t13: &u64 - var $t14: u64 - var $t15: u64 - var $t16: u64 - var $t17: &mut 0x42::Test::R - var $t18: &mut u64 - var $t19: u64 - 0: $t3 := copy($t0) - 1: $t4 := exists<0x42::Test::R>($t3) - 2: $t5 := !($t4) - 3: if ($t5) goto 4 else goto 7 - 4: label L1 - 5: $t6 := 33 - 6: abort($t6) - 7: label L0 - 8: $t7 := move($t0) - 9: $t8 := borrow_global<0x42::Test::R>($t7) - 10: $t1 := $t8 - 11: $t9 := copy($t1) - 12: $t10 := borrow_field<0x42::Test::R>.v($t9) - 13: $t11 := read_ref($t10) - 14: $t2 := $t11 - 15: $t12 := copy($t1) - 16: $t13 := borrow_field<0x42::Test::R>.v($t12) - 17: $t14 := read_ref($t13) - 18: $t15 := 1 - 19: $t16 := +($t14, $t15) - 20: $t17 := move($t1) - 21: $t18 := borrow_field<0x42::Test::R>.v($t17) - 22: write_ref($t18, $t16) - 23: $t19 := move($t2) - 24: return $t19 -} - - -[variant baseline] -fun Test::incr_twice() { - var $t0: address - var $t1: u64 - var $t2: address - var $t3: u64 - 0: $t0 := 0x1 - 1: $t1 := Test::get_and_incr($t0) - 2: drop($t1) - 3: $t2 := 0x1 - 4: $t3 := Test::get_and_incr($t2) - 5: drop($t3) - 6: return () -} - -============ after pipeline `spec_instrumentation` ================ - -[variant verification] -fun Test::get_and_incr($t0|addr: address): u64 { - var $t1|r: &mut 0x42::Test::R - var $t2|v: u64 - var $t3: bool - var $t4: bool - var $t5: u64 - var $t6: num - var $t7: &mut 0x42::Test::R - var $t8: u64 - var $t9: u64 - var $t10: u64 - var $t11: u64 - var $t12: &mut u64 - 0: assume Neq
($t0, 0x0) - 1: assume CanModify<0x42::Test::R>($t0) - 2: @0 := save_mem(Test::R) - 3: $t3 := exists<0x42::Test::R>($t0) - 4: $t4 := !($t3) - 5: if ($t4) goto 6 else goto 10 - 6: label L1 - 7: $t5 := 33 - 8: $t6 := move($t5) - 9: goto 27 - 10: label L0 - # VC: caller does not have permission to modify `Test::R` at given address at tests/spec_instrumentation/opaque_call.move:8:14+17 - 11: assert CanModify<0x42::Test::R>($t0) - 12: $t7 := borrow_global<0x42::Test::R>($t0) on_abort goto 27 with $t6 - 13: $t8 := get_field<0x42::Test::R>.v($t7) - 14: $t9 := get_field<0x42::Test::R>.v($t7) - 15: $t10 := 1 - 16: $t11 := +($t9, $t10) on_abort goto 27 with $t6 - 17: $t12 := borrow_field<0x42::Test::R>.v($t7) - 18: write_ref($t12, $t11) - 19: write_back[Reference($t7).v (u64)]($t12) - 20: write_back[0x42::Test::R@]($t7) - 21: label L2 - # VC: function does not abort under this condition at tests/spec_instrumentation/opaque_call.move:16:6+35 - 22: assert Not(Not(exists[@0]<0x42::Test::R>($t0))) - # VC: function does not abort under this condition at tests/spec_instrumentation/opaque_call.move:17:6+56 - 23: assert Not(Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>($t0)), 1), 18446744073709551615)) - # VC: post-condition does not hold at tests/spec_instrumentation/opaque_call.move:19:6+56 - 24: assert Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>($t0)), 1)) - # VC: post-condition does not hold at tests/spec_instrumentation/opaque_call.move:20:6+36 - 25: assert Eq($t8, select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0))) - 26: return $t8 - 27: label L3 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/opaque_call.move:13:2+308 - 28: assert Or(Not(exists[@0]<0x42::Test::R>($t0)), Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>($t0)), 1), 18446744073709551615)) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/opaque_call.move:13:2+308 - 29: assert Or(And(Not(exists[@0]<0x42::Test::R>($t0)), Eq(33, $t6)), Ge(Add(select Test::R.v<0x42::Test::R>(global[@0]<0x42::Test::R>($t0)), 1), 18446744073709551615)) - 30: abort($t6) -} - - -[variant verification] -fun Test::incr_twice() { - var $t0: address - var $t1: u64 - var $t2: bool - var $t3: num - var $t4: address - var $t5: u64 - var $t6: bool - 0: @1 := save_mem(Test::R) - 1: $t0 := 0x1 - # VC: precondition does not hold at this call at tests/spec_instrumentation/opaque_call.move:15:6+22 - 2: assert Neq
($t0, 0x0) - 3: $t1 := opaque begin: Test::get_and_incr($t0) - 4: assume Identical($t2, Or(Not(exists<0x42::Test::R>($t0)), Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), 1), 18446744073709551615))) - 5: if ($t2) goto 6 else goto 10 - 6: label L4 - 7: assume Or(And(Not(exists<0x42::Test::R>($t0)), Eq(33, $t3)), Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), 1), 18446744073709551615)) - 8: trace_abort($t3) - 9: goto 39 - 10: label L3 - 11: @2 := save_mem(Test::R) - 12: modifies global<0x42::Test::R>($t0) - 13: assume WellFormed($t1) - 14: assume Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), Add(select Test::R.v<0x42::Test::R>(global[@2]<0x42::Test::R>($t0)), 1)) - 15: assume Eq($t1, select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0))) - 16: $t1 := opaque end: Test::get_and_incr($t0) - 17: drop($t1) - 18: $t4 := 0x1 - # VC: precondition does not hold at this call at tests/spec_instrumentation/opaque_call.move:15:6+22 - 19: assert Neq
($t4, 0x0) - 20: $t5 := opaque begin: Test::get_and_incr($t4) - 21: assume Identical($t6, Or(Not(exists<0x42::Test::R>($t4)), Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t4)), 1), 18446744073709551615))) - 22: if ($t6) goto 23 else goto 27 - 23: label L6 - 24: assume Or(And(Not(exists<0x42::Test::R>($t4)), Eq(33, $t3)), Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t4)), 1), 18446744073709551615)) - 25: trace_abort($t3) - 26: goto 39 - 27: label L5 - 28: @3 := save_mem(Test::R) - 29: modifies global<0x42::Test::R>($t4) - 30: assume WellFormed($t5) - 31: assume Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t4)), Add(select Test::R.v<0x42::Test::R>(global[@3]<0x42::Test::R>($t4)), 1)) - 32: assume Eq($t5, select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t4))) - 33: $t5 := opaque end: Test::get_and_incr($t4) - 34: drop($t5) - 35: label L1 - # VC: function does not abort under this condition at tests/spec_instrumentation/opaque_call.move:28:6+35 - 36: assert Not(Not(exists[@1]<0x42::Test::R>(0x1))) - # VC: post-condition does not hold at tests/spec_instrumentation/opaque_call.move:29:6+56 - 37: assert Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x1)), Add(select Test::R.v<0x42::Test::R>(global[@1]<0x42::Test::R>(0x1)), 2)) - 38: return () - 39: label L2 - # VC: abort not covered by any of the `aborts_if` clauses at tests/spec_instrumentation/opaque_call.move:27:2+123 - 40: assert Not(exists[@1]<0x42::Test::R>(0x1)) - # VC: abort code not covered by any of the `aborts_if` or `aborts_with` clauses at tests/spec_instrumentation/opaque_call.move:27:2+123 - 41: assert And(Not(exists[@1]<0x42::Test::R>(0x1)), Eq(33, $t3)) - 42: abort($t3) -} - - - -==== spec-instrumenter input specs ==== - -fun Test::get_and_incr[baseline] -spec { - requires Neq
($t0, 0x0); - aborts_if Not(exists<0x42::Test::R>($t0)); - aborts_if Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), 1), 18446744073709551615); - modifies global<0x42::Test::R>($t0); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>($t0))), 1)); - ensures Eq(result0(), select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0))); -} - -fun Test::get_and_incr[verification] -spec { - requires Neq
($t0, 0x0); - aborts_if Not(exists<0x42::Test::R>($t0)); - aborts_if Ge(Add(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), 1), 18446744073709551615); - modifies global<0x42::Test::R>($t0); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>($t0))), 1)); - ensures Eq(result0(), select Test::R.v<0x42::Test::R>(global<0x42::Test::R>($t0))); -} - -fun Test::incr_twice[baseline] -spec { - aborts_if Not(exists<0x42::Test::R>(0x1)); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x1)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>(0x1))), 2)); -} - -fun Test::incr_twice[verification] -spec { - aborts_if Not(exists<0x42::Test::R>(0x1)); - ensures Eq(select Test::R.v<0x42::Test::R>(global<0x42::Test::R>(0x1)), Add(select Test::R.v<0x42::Test::R>(Old<0x42::Test::R>(global<0x42::Test::R>(0x1))), 2)); -} diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_relevance.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_relevance.v2_exp deleted file mode 100644 index f197986ab70..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_relevance.v2_exp +++ /dev/null @@ -1,120 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun InvRelevance::inner<#0>($t0|s: &signer, $t1|t: #0) { - var $t2: &signer - var $t3: #0 - var $t4: 0x2::InvRelevance::R<#0> - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: $t4 := pack 0x2::InvRelevance::R<#0>($t3) - 3: move_to<0x2::InvRelevance::R<#0>>($t4, $t2) - 4: return () -} - - -[variant baseline] -public fun InvRelevance::outer_T<#0>($t0|s: &signer, $t1|t: #0) { - var $t2: &signer - var $t3: #0 - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner<#0>($t2, $t3) - 3: return () -} - - -[variant baseline] -public fun InvRelevance::outer_bool($t0|s: &signer, $t1|t: bool) { - var $t2: &signer - var $t3: bool - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner($t2, $t3) - 3: return () -} - - -[variant baseline] -public fun InvRelevance::outer_u64($t0|s: &signer, $t1|t: u64) { - var $t2: &signer - var $t3: u64 - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner($t2, $t3) - 3: return () -} - -============ after pipeline `verification_analysis` ================ - -[variant baseline] -fun InvRelevance::inner<#0>($t0|s: signer, $t1|t: #0) { - var $t2: 0x2::InvRelevance::R<#0> - 0: $t2 := pack 0x2::InvRelevance::R<#0>($t1) - 1: move_to<0x2::InvRelevance::R<#0>>($t2, $t0) - 2: return () -} - - -[variant baseline] -public fun InvRelevance::outer_T<#0>($t0|s: signer, $t1|t: #0) { - 0: InvRelevance::inner<#0>($t0, $t1) - 1: return () -} - - -[variant baseline] -public fun InvRelevance::outer_bool($t0|s: signer, $t1|t: bool) { - 0: InvRelevance::inner($t0, $t1) - 1: return () -} - - -[variant baseline] -public fun InvRelevance::outer_u64($t0|s: signer, $t1|t: u64) { - 0: InvRelevance::inner($t0, $t1) - 1: return () -} - - -********* Result of verification analysis ********* - -functions that defer invariant checking at return: [ -] - -functions that delegate invariants to its callers: [ -] - -invariant applicability: [ - InvRelevance::inner: { - accessed: [@0*] - modified: [@0*] - directly accessed: [@0*] - directly modified: [@0*] - } - InvRelevance::outer_T: { - accessed: [@0*] - modified: [@0*] - directly accessed: [] - directly modified: [] - } - InvRelevance::outer_bool: { - accessed: [@0*] - modified: [@0*] - directly accessed: [] - directly modified: [] - } - InvRelevance::outer_u64: { - accessed: [] - modified: [] - directly accessed: [] - directly modified: [] - } -] - -verification analysis: [ - InvRelevance::inner: verified + inlined - InvRelevance::outer_T: verified - InvRelevance::outer_bool: verified - InvRelevance::outer_u64: verified -] diff --git a/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_suspension.v2_exp b/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_suspension.v2_exp deleted file mode 100644 index cdca820b4cb..00000000000 --- a/third_party/move/move-prover/bytecode-pipeline/tests/verification_analysis/inv_suspension.v2_exp +++ /dev/null @@ -1,121 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -fun InvRelevance::inner<#0>($t0|s: &signer, $t1|t: #0) { - var $t2: &signer - var $t3: #0 - var $t4: 0x2::InvRelevance::R<#0> - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: $t4 := pack 0x2::InvRelevance::R<#0>($t3) - 3: move_to<0x2::InvRelevance::R<#0>>($t4, $t2) - 4: return () -} - - -[variant baseline] -public fun InvRelevance::outer_T<#0>($t0|s: &signer, $t1|t: #0) { - var $t2: &signer - var $t3: #0 - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner<#0>($t2, $t3) - 3: return () -} - - -[variant baseline] -public fun InvRelevance::outer_bool($t0|s: &signer, $t1|t: bool) { - var $t2: &signer - var $t3: bool - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner($t2, $t3) - 3: return () -} - - -[variant baseline] -public fun InvRelevance::outer_u64($t0|s: &signer, $t1|t: u64) { - var $t2: &signer - var $t3: u64 - 0: $t2 := move($t0) - 1: $t3 := move($t1) - 2: InvRelevance::inner($t2, $t3) - 3: return () -} - -============ after pipeline `verification_analysis` ================ - -[variant baseline] -fun InvRelevance::inner<#0>($t0|s: signer, $t1|t: #0) { - var $t2: 0x2::InvRelevance::R<#0> - 0: $t2 := pack 0x2::InvRelevance::R<#0>($t1) - 1: move_to<0x2::InvRelevance::R<#0>>($t2, $t0) - 2: return () -} - - -[variant baseline] -public fun InvRelevance::outer_T<#0>($t0|s: signer, $t1|t: #0) { - 0: InvRelevance::inner<#0>($t0, $t1) - 1: return () -} - - -[variant baseline] -public fun InvRelevance::outer_bool($t0|s: signer, $t1|t: bool) { - 0: InvRelevance::inner($t0, $t1) - 1: return () -} - - -[variant baseline] -public fun InvRelevance::outer_u64($t0|s: signer, $t1|t: u64) { - 0: InvRelevance::inner($t0, $t1) - 1: return () -} - - -********* Result of verification analysis ********* - -functions that defer invariant checking at return: [ -] - -functions that delegate invariants to its callers: [ - InvRelevance::inner -] - -invariant applicability: [ - InvRelevance::inner: { - accessed: [@0*] - modified: [@0*] - directly accessed: [@0*] - directly modified: [@0*] - } - InvRelevance::outer_T: { - accessed: [@0*, @1*] - modified: [@0*, @1*] - directly accessed: [@1*] - directly modified: [@1*] - } - InvRelevance::outer_bool: { - accessed: [@0*] - modified: [@0*] - directly accessed: [] - directly modified: [] - } - InvRelevance::outer_u64: { - accessed: [@1*] - modified: [@1*] - directly accessed: [@1*] - directly modified: [@1*] - } -] - -verification analysis: [ - InvRelevance::inner: verified + inlined - InvRelevance::outer_T: verified - InvRelevance::outer_bool: verified - InvRelevance::outer_u64: verified -] diff --git a/third_party/move/move-prover/lab/Cargo.toml b/third_party/move/move-prover/lab/Cargo.toml index dc90304f53b..15311da8209 100644 --- a/third_party/move/move-prover/lab/Cargo.toml +++ b/third_party/move/move-prover/lab/Cargo.toml @@ -3,7 +3,7 @@ name = "move-prover-lab" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-prover/move-abigen/Cargo.toml b/third_party/move/move-prover/move-abigen/Cargo.toml index d9da5ad60f5..872a52b5235 100644 --- a/third_party/move/move-prover/move-abigen/Cargo.toml +++ b/third_party/move/move-prover/move-abigen/Cargo.toml @@ -3,7 +3,7 @@ name = "move-abigen" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-prover/move-abigen/src/abigen.rs b/third_party/move/move-prover/move-abigen/src/abigen.rs index 33d3ce46ded..e532dab1d64 100644 --- a/third_party/move/move-prover/move-abigen/src/abigen.rs +++ b/third_party/move/move-prover/move-abigen/src/abigen.rs @@ -79,7 +79,7 @@ impl<'env> Abigen<'env> { } /// Generates ABIs for all script modules in the environment (excluding the dependency set). - pub fn gen(&mut self) { + pub fn r#gen(&mut self) { for module in self.env.get_modules() { if module.is_primary_target() { let mut path = PathBuf::from(&self.options.output_directory); @@ -275,6 +275,12 @@ impl<'env> Abigen<'env> { U64 => TypeTag::U64, U128 => TypeTag::U128, U256 => TypeTag::U256, + I8 => TypeTag::I8, + I16 => TypeTag::I16, + I32 => TypeTag::I32, + I64 => TypeTag::I64, + I128 => TypeTag::I128, + I256 => TypeTag::I256, Address => TypeTag::Address, Signer => TypeTag::Signer, Num | Range | EventStore => { diff --git a/third_party/move/move-prover/move-docgen/Cargo.toml b/third_party/move/move-prover/move-docgen/Cargo.toml index 8d6f3c380f4..9a9ab26a9cc 100644 --- a/third_party/move/move-prover/move-docgen/Cargo.toml +++ b/third_party/move/move-prover/move-docgen/Cargo.toml @@ -3,7 +3,7 @@ name = "move-docgen" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-prover/move-docgen/src/docgen.rs b/third_party/move/move-prover/move-docgen/src/docgen.rs index dd5a75e2bee..c4c053b5354 100644 --- a/third_party/move/move-prover/move-docgen/src/docgen.rs +++ b/third_party/move/move-prover/move-docgen/src/docgen.rs @@ -237,7 +237,7 @@ impl<'env> Docgen<'env> { } /// Generate document contents, returning pairs of output file names and generated contents. - pub fn gen(mut self) -> Vec<(String, String)> { + pub fn r#gen(mut self) -> Vec<(String, String)> { // Compute missing information about schemas. self.compute_declared_schemas(); @@ -588,7 +588,7 @@ impl<'env> Docgen<'env> { let symbol2_name = self.name_string(*symbol2).to_string(); let module_prefix = match module_name_option { None => "".to_string(), - Some(ref module_name) => { + Some(module_name) => { format!("{}::", module_name.display_full(self.env)) }, }; diff --git a/third_party/move/move-prover/move-errmapgen/Cargo.toml b/third_party/move/move-prover/move-errmapgen/Cargo.toml index 9e448d8bd17..af43ca6d35b 100644 --- a/third_party/move/move-prover/move-errmapgen/Cargo.toml +++ b/third_party/move/move-prover/move-errmapgen/Cargo.toml @@ -3,7 +3,7 @@ name = "move-errmapgen" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-prover/move-errmapgen/src/errmapgen.rs b/third_party/move/move-prover/move-errmapgen/src/errmapgen.rs index 14153c1185b..c57b9919b25 100644 --- a/third_party/move/move-prover/move-errmapgen/src/errmapgen.rs +++ b/third_party/move/move-prover/move-errmapgen/src/errmapgen.rs @@ -58,7 +58,7 @@ impl<'env> ErrmapGen<'env> { self.output.to_file(&self.options.output_file); } - pub fn gen(&mut self) { + pub fn r#gen(&mut self) { for module in self.env.get_modules() { if !module.is_script_module() { self.build_error_map(&module).unwrap() diff --git a/third_party/move/move-prover/src/cli.rs b/third_party/move/move-prover/src/cli.rs index 3e0641350e9..0ca5182f5da 100644 --- a/third_party/move/move-prover/src/cli.rs +++ b/third_party/move/move-prover/src/cli.rs @@ -24,19 +24,7 @@ use move_prover_boogie_backend::{ use move_prover_bytecode_pipeline::options::{AutoTraceLevel, ProverOptions}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; -use simplelog::{ - CombinedLogger, Config, ConfigBuilder, LevelPadding, SimpleLogger, TermLogger, TerminalMode, -}; -use std::{ - collections::BTreeMap, - sync::atomic::{AtomicBool, Ordering}, -}; - -/// Atomic used to prevent re-initialization of logging. -static LOGGER_CONFIGURED: AtomicBool = AtomicBool::new(false); - -/// Atomic used to detect whether we are running in test mode. -static TEST_MODE: AtomicBool = AtomicBool::new(false); +use std::collections::BTreeMap; /// Represents options provided to the tool. Most of those options are configured via a toml /// source; some over the command line flags. @@ -759,38 +747,11 @@ impl Options { /// Sets up logging based on provided options. This should be called as early as possible /// and before any use of info!, warn! etc. pub fn setup_logging(&self) { - if LOGGER_CONFIGURED - .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) - .is_err() - { - return; - } - let config = ConfigBuilder::new() - .set_time_level(LevelFilter::Debug) - .set_level_padding(LevelPadding::Off) - .build(); - // Ignore error if logger is already setup - let _logger = if atty::is(atty::Stream::Stderr) && atty::is(atty::Stream::Stdout) { - CombinedLogger::init(vec![TermLogger::new( - self.verbosity_level, - config, - TerminalMode::Mixed, - )]) - } else { - CombinedLogger::init(vec![SimpleLogger::new(self.verbosity_level, config)]) - }; + move_compiler_v2::logging::setup_logging(Some(self.verbosity_level)) } pub fn setup_logging_for_test(&self) { - if LOGGER_CONFIGURED - .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) - .is_err() - { - return; - } - TEST_MODE.store(true, Ordering::Relaxed); - // Ignore error if logger is already setup - let _ = SimpleLogger::init(self.verbosity_level, Config::default()); + move_compiler_v2::logging::setup_logging_for_testing(Some(self.verbosity_level)) } /// Convenience function to enable debugging (like high verbosity) on this instance. diff --git a/third_party/move/move-prover/src/lib.rs b/third_party/move/move-prover/src/lib.rs index 535b8dd291b..1fb2fd1efe0 100644 --- a/third_party/move/move-prover/src/lib.rs +++ b/third_party/move/move-prover/src/lib.rs @@ -10,6 +10,7 @@ use codespan_reporting::term::termcolor::{ColorChoice, StandardStream, WriteColo use itertools::Itertools; #[allow(unused_imports)] use log::{debug, info, warn}; +use log::{log_enabled, Level}; use move_abigen::Abigen; use move_docgen::Docgen; use move_errmapgen::ErrmapGen; @@ -74,6 +75,7 @@ pub fn create_move_prover_v2_model( compile_test_code: false, compile_verify_code: true, external_checks: vec![], + print_errors: true, }; move_compiler_v2::run_move_compiler_for_analysis(error_writer, compiler_options) @@ -273,8 +275,7 @@ pub fn create_and_process_bytecode(options: &Options, env: &GlobalEnv) -> Functi } if options.prover.dump_bytecode { if let Some(out) = module_env.disassemble() { - let dump_file = output_dir.join(format!("{}.mv.disas", output_prefix)); - fs::write(dump_file, out).expect("dumping disassembled module"); + debug!("disassembled bytecode:\n{}", out); } } for func_env in module_env.get_functions() { @@ -289,7 +290,7 @@ pub fn create_and_process_bytecode(options: &Options, env: &GlobalEnv) -> Functi pipeline_factory::default_pipeline_with_options(&options.prover) }; - if options.prover.dump_bytecode { + if log_enabled!(Level::Debug) && options.prover.dump_bytecode { let dump_file_base = output_dir .join(output_prefix) .into_os_string() @@ -300,7 +301,7 @@ pub fn create_and_process_bytecode(options: &Options, env: &GlobalEnv) -> Functi &mut targets, &dump_file_base, options.prover.dump_cfg, - &|_| {}, + &|target| target.register_annotation_formatters_for_test(), || true, ) } else { @@ -325,7 +326,7 @@ fn run_docgen( let generator = Docgen::new(env, &options.docgen); let checking_elapsed = now.elapsed(); info!("generating documentation"); - for (file, content) in generator.gen() { + for (file, content) in generator.r#gen() { let path = PathBuf::from(&file); fs::create_dir_all(path.parent().unwrap())?; fs::write(path.as_path(), content)?; @@ -348,7 +349,7 @@ fn run_abigen(env: &GlobalEnv, options: &Options, now: Instant) -> anyhow::Resul let mut generator = Abigen::new(env, &options.abigen); let checking_elapsed = now.elapsed(); info!("generating ABI files"); - generator.gen(); + generator.r#gen(); for (file, content) in generator.into_result() { let path = PathBuf::from(&file); fs::create_dir_all(path.parent().unwrap())?; @@ -367,7 +368,7 @@ fn run_errmapgen(env: &GlobalEnv, options: &Options, now: Instant) { let mut generator = ErrmapGen::new(env, &options.errmapgen); let checking_elapsed = now.elapsed(); info!("generating error map"); - generator.gen(); + generator.r#gen(); generator.save_result(); let generating_elapsed = now.elapsed(); info!( diff --git a/third_party/move/move-prover/test-utils/Cargo.toml b/third_party/move/move-prover/test-utils/Cargo.toml index d18e3baec45..e7d9da0d4da 100644 --- a/third_party/move/move-prover/test-utils/Cargo.toml +++ b/third_party/move/move-prover/test-utils/Cargo.toml @@ -2,7 +2,7 @@ name = "move-prover-test-utils" version = "0.1.0" authors = ["Diem Association "] -edition = "2021" +edition = { workspace = true } publish = false license = "Apache-2.0" diff --git a/third_party/move/move-prover/tests/README.md b/third_party/move/move-prover/tests/README.md index b3b4acbea5b..64531d9a216 100644 --- a/third_party/move/move-prover/tests/README.md +++ b/third_party/move/move-prover/tests/README.md @@ -14,7 +14,7 @@ prover's integration into the Move CLI and configured outside this tree. > `.exp`. To update those files, use `UPBL=1 cargo test`. To update or test a single file, you can > also provide a fragment of the Move source path. -## Running the Prover on Sources in this Tree +## Running the Prover for Debugging on Sources in this Tree > NOTE: in contrast to older versions, the prover does not longer automatically pick a configuration file via the MOVE_PROVER_CONFIG variable. @@ -28,14 +28,24 @@ alias mvp=cargo run -p move-prover -- --config= The file at the path to `` should contain (at least) the following content: ```toml +language_version = "2.2" # Or any other options move_deps = [ - "/diem/language/move-stdlib/sources" + "/Users//aptos-core/third_party/move/move-stdlib/sources" ] move_named_address_values = [ - "Std=0x1", + "std=0x1", + "extensions=0x2", ] ``` +The prover dumps debug information to the `debug!` channel of the `log` crate. It shares the logging configuration with the Move compiler as described [here](../../move-compiler-v2/src/logging.rs). One uses the MVC_LOG environment variable to configure the logging. E.g., `MVC_LOG=debug` sends active debug prints to stderr, and `MVC_LOG=debug@my.log` to the given file. While the env var controls the level of logging, `mvp` (above alias) still need to be told to create `debug!` via the verbose flag. The below command line shows how to let `mvp` dump stackless bytecode of all prover phases except compiler; this is useful for targeted debugging of the prover: + +```shell +MVC_LOG="move_compiler_v2=info,debug@prover.log" \ + mvp --verbose debug --dump-bytecode enum_invariants.move +``` + + ## Running Tests: Quick Guide - In order to regenerate baseline files, use `UPBL=1 cargo test ` diff --git a/third_party/move/move-prover/tests/sources/functional/bitwise_features.move b/third_party/move/move-prover/tests/sources/functional/bitwise_features.move index 96486010cce..79c7f3b5f6c 100644 --- a/third_party/move/move-prover/tests/sources/functional/bitwise_features.move +++ b/third_party/move/move-prover/tests/sources/functional/bitwise_features.move @@ -171,6 +171,7 @@ module TestFeatures { } spec enable_feature_flags { + pragma verify = false; // timeout frequent, makes testsuite too slow pragma opaque; pragma timeout = 120; modifies global(@std); diff --git a/third_party/move/move-prover/tests/sources/functional/bug-17117.move b/third_party/move/move-prover/tests/sources/functional/bug-17117.move new file mode 100644 index 00000000000..95e0fe3be7e --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/bug-17117.move @@ -0,0 +1,85 @@ +module 0x42::M { + use std::option; + use std::vector; + + spec S { + invariant x > 20; + } + + struct IsolatedPosition has key { + position: S + } + + struct CrossedPosition has key { + positions: vector + } + + struct S has store { + x: u64 + } + + struct Foo has key { + x: u64 + } + + public(package) fun bar(x: u64): option::Option { + if (x > 20) { + option::some(Foo { x: x }) + } else { + option::none() + } + } + + inline fun must_find_position_mut( + address: address, x: u64 + ): &mut S { + if (exists(address)) { + &mut borrow_global_mut(address).position + } else { + let positions = &mut CrossedPosition[address].positions; + let (is_found, index) = vector::find(positions, |position| &position.x == &x); + if (is_found) { + vector::borrow_mut(positions, index) + } else { + abort 1 + } + } + } + + inline fun must_find_position( + address: address, x: u64 + ): &S { + if (exists(address)) { + &borrow_global(address).position + } else { + let positions = &mut CrossedPosition[address].positions; + let (is_found, index) = vector::find(positions, |position| &position.x == &x); + if (is_found) { + vector::borrow(positions, index) + } else { + abort 1 + } + } + } + + fun get_s_error( + address: address, x: u64 + ): option::Option acquires IsolatedPosition, CrossedPosition { + let s = must_find_position_mut(address, x); + bar(s.x) + } + + fun get_s_no_error( + address: address, x: u64 + ): option::Option acquires IsolatedPosition, CrossedPosition { + let s = must_find_position(address, x); + bar(s.x) + } + + fun test_input_param_as_mut_ref(r: &mut S) { + let y = &mut r.x; + spec { + assert r.x == y; + }; + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/cast.exp b/third_party/move/move-prover/tests/sources/functional/cast.exp index 7f6ea2f6f8b..0f8d953589b 100644 --- a/third_party/move/move-prover/tests/sources/functional/cast.exp +++ b/third_party/move/move-prover/tests/sources/functional/cast.exp @@ -47,18 +47,34 @@ error: abort not covered by any of the `aborts_if` clauses = at tests/sources/functional/cast.move:79: aborting_u32_cast_incorrect = ABORTED +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/cast.move:95:5 + │ +93 │ (x as u64) + │ ---------- abort happened here with execution failure +94 │ } +95 │ ╭ spec aborting_u64_cast_incorrect { +96 │ │ aborts_if false; +97 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/cast.move:92: aborting_u64_cast_incorrect + = x = + = at tests/sources/functional/cast.move:93: aborting_u64_cast_incorrect + = ABORTED + error: abort not covered by any of the `aborts_if` clauses ┌─ tests/sources/functional/cast.move:109:5 │ - 93 │ (x as u64) - │ ---------- abort happened here with execution failure - · -109 │ ╭ spec aborting_u64_cast_incorrect { +107 │ (x as u128) + │ ----------- abort happened here with execution failure +108 │ } +109 │ ╭ spec aborting_u128_cast_incorrect { 110 │ │ aborts_if false; 111 │ │ } │ ╰─────^ │ - = at tests/sources/functional/cast.move:92: aborting_u64_cast_incorrect + = at tests/sources/functional/cast.move:106: aborting_u128_cast_incorrect = x = - = at tests/sources/functional/cast.move:93: aborting_u64_cast_incorrect + = at tests/sources/functional/cast.move:107: aborting_u128_cast_incorrect = ABORTED diff --git a/third_party/move/move-prover/tests/sources/functional/cast.move b/third_party/move/move-prover/tests/sources/functional/cast.move index 076e4ab542e..28877180234 100644 --- a/third_party/move/move-prover/tests/sources/functional/cast.move +++ b/third_party/move/move-prover/tests/sources/functional/cast.move @@ -8,38 +8,38 @@ module 0x42::TestCast { // Type promotion // -------------- - fun u8_cast_incorrect(x: u8): u64 { + fun u8_cast(x: u8): u64 { (x as u64) } - spec u8_cast_incorrect { + spec u8_cast { aborts_if false; } - fun u16_cast_incorrect(x: u16): u64 { + fun u16_cast(x: u16): u64 { (x as u64) } - spec u16_cast_incorrect { + spec u16_cast { aborts_if false; } - fun u32_cast_incorrect(x: u32): u64 { + fun u32_cast(x: u32): u64 { (x as u64) } - spec u8_cast_incorrect { + spec u32_cast { aborts_if false; } fun u64_cast(x: u64): u128 { (x as u128) } - spec aborting_u64_cast { + spec u64_cast { aborts_if false; } fun u128_cast(x: u128): u256 { (x as u256) } - spec aborting_u128_cast { + spec u128_cast { aborts_if false; } @@ -85,7 +85,7 @@ module 0x42::TestCast { fun aborting_u32_cast(x: u64): u32 { (x as u32) } - spec aborting_u16_cast { + spec aborting_u32_cast { aborts_if x > 4294967295; } @@ -106,7 +106,7 @@ module 0x42::TestCast { fun aborting_u128_cast_incorrect(x: u256): u128 { (x as u128) } - spec aborting_u64_cast_incorrect { + spec aborting_u128_cast_incorrect { aborts_if false; } diff --git a/third_party/move/move-prover/tests/sources/functional/choice.exp b/third_party/move/move-prover/tests/sources/functional/choice.exp index 12365e40fda..d9ea49a8f4d 100644 --- a/third_party/move/move-prover/tests/sources/functional/choice.exp +++ b/third_party/move/move-prover/tests/sources/functional/choice.exp @@ -8,9 +8,8 @@ error: post-condition does not hold = at tests/sources/functional/choice.move:16: simple_incorrect = b = = at tests/sources/functional/choice.move:17: simple_incorrect - = return = - = at tests/sources/functional/choice.move:17: simple_incorrect = result = + = at tests/sources/functional/choice.move:18: simple_incorrect = at tests/sources/functional/choice.move:22: simple_incorrect (spec) = `TRACE(choose x: u64 where x >= 4 && x <= 5)` = diff --git a/third_party/move/move-prover/tests/sources/functional/choice.move b/third_party/move/move-prover/tests/sources/functional/choice.move index b47faa814aa..d97620c468c 100644 --- a/third_party/move/move-prover/tests/sources/functional/choice.move +++ b/third_party/move/move-prover/tests/sources/functional/choice.move @@ -303,4 +303,13 @@ module 0x42::TestSome { <= 0); } + public fun get_ballots(ballots: &mut Ballots): &mut Ballot { + &mut ballots.ballots[0] + } + + spec get_ballots { + let index = choose min i in range (ballots.ballots) where ballots.ballots[i].ballot_id.counter == 0; + ensures true; + } + } diff --git a/third_party/move/move-prover/tests/sources/functional/closure.exp b/third_party/move/move-prover/tests/sources/functional/closure.exp deleted file mode 100644 index c735d979506..00000000000 --- a/third_party/move/move-prover/tests/sources/functional/closure.exp +++ /dev/null @@ -1,17 +0,0 @@ -Move prover returns: exiting with verification errors -error: post-condition does not hold - ┌─ tests/sources/functional/closure.move:17:9 - │ -17 │ ensures result == x + 2; // This does not verify - │ ^^^^^^^^^^^^^^^^^^^^^^^^ - │ - = at tests/sources/functional/closure.move:13: test_closure_2 - = x = - = at tests/sources/functional/closure.move:14: test_closure_2 - = x = - = y = - = result = - = at tests/sources/functional/closure.move:14: test_closure_2 - = result = - = at tests/sources/functional/closure.move:15: test_closure_2 - = at tests/sources/functional/closure.move:17: test_closure_2 (spec) diff --git a/third_party/move/move-prover/tests/sources/functional/closure.move b/third_party/move/move-prover/tests/sources/functional/closure.move deleted file mode 100644 index e59564af79c..00000000000 --- a/third_party/move/move-prover/tests/sources/functional/closure.move +++ /dev/null @@ -1,49 +0,0 @@ -module 0x42::Test { - - fun add(x: u64, y: u64): u64 { - x + y - } - fun test_closure_1(x: u64): u64 { - (add)(x, 1) - } - spec test_closure_1 { - ensures result == x + 1; - } - - fun test_closure_2(x: u64): u64 { - (|y| y + x)(1) - } - spec test_closure_2 { - ensures result == x + 2; // This does not verify - } - - fun test_closure_3(x: u64): u64 { - (|y| y + x)(1) - } - spec test_closure_3 { - ensures result == (add)(1 as u64, x); - } - - fun and(a: bool, b: bool): bool { - a && b - } - - fun test_closure_4(x: bool): bool { - and(x, false) - } - spec test_closure_4 { - ensures and(x, false) == (|y| y && x)(false); - } - - struct S has copy, drop { - f: T - } - - fun test_closure_5(x: S): bool { - and(x.f, false) - } - spec test_closure_5 { - ensures and(x.f, false) == (|s: S| s.f && x.f )(S { f: false }); - } - -} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_empty_result.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_empty_result.move new file mode 100644 index 00000000000..4aa8f3fb936 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_empty_result.move @@ -0,0 +1,11 @@ +module 0x42::test { + //This exercises the `invoke` arm of `translate_bytecode` with no return vars + public fun test_unit_closure(f: |u64| ()) { + f(0); + } + + //This exercises the `translate_fun` function with no return vars + public fun wrapper() { + test_unit_closure(|_x| ()) + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.exp b/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.exp new file mode 100644 index 00000000000..e7cc7d452ed --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.exp @@ -0,0 +1,6 @@ +Move prover returns: exiting with condition generation errors +error: [boogie translator] current restriction: a function value cannot be used in a specification expression. + ┌─ tests/sources/functional/closures/closure_in_spec_expr.move:6:27 + │ +6 │ ensures result == p(v[0]); + │ ^^^^^^^ diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.move new file mode 100644 index 00000000000..12ce0af7aad --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_in_spec_expr.move @@ -0,0 +1,16 @@ +module 0x42::test { + fun contains(v: &vector, p: |u64|bool): bool { + p(v[0]) + } + spec contains { + ensures result == p(v[0]); + } + + fun using(): bool { + let v = vector[1]; + contains(&v, |x| x == 1) + } + spec using { + ensures result; + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.exp b/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.exp new file mode 100644 index 00000000000..90d9fbd8800 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.exp @@ -0,0 +1,36 @@ +Move prover returns: exiting with verification errors +error: post-condition does not hold + ┌─ tests/sources/functional/closures/closure_non_provable.move:13:9 + │ +13 │ ensures old(S[@0x2]) == S[@0x2]; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ + = at tests/sources/functional/closures/closure_non_provable.move:5: exec + = f = + = x = + = at tests/sources/functional/closures/closure_non_provable.move:6: exec + = result = + = at tests/sources/functional/closures/closure_non_provable.move:7: exec + = at tests/sources/functional/closures/closure_non_provable.move:10: exec (spec) + = at tests/sources/functional/closures/closure_non_provable.move:13: exec (spec) + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/closures/closure_non_provable.move:8:5 + │ + 6 │ f(x) + │ ---- abort happened here with code 0x0 + 7 │ } + 8 │ ╭ spec exec { + 9 │ │ // We cannot prove this because `f` can abort +10 │ │ aborts_if false; +11 │ │ +12 │ │ // We can also not prove this because `S` can be modified by `f` +13 │ │ ensures old(S[@0x2]) == S[@0x2]; +14 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/closures/closure_non_provable.move:5: exec + = f = + = x = + = at tests/sources/functional/closures/closure_non_provable.move:6: exec + = ABORTED diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.move new file mode 100644 index 00000000000..eee6f583e41 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_non_provable.move @@ -0,0 +1,15 @@ +module 0x42::test { + + struct S(u64) has key; + + fun exec(f: |u64|u64, x: u64): u64 { + f(x) + } + spec exec { + // We cannot prove this because `f` can abort + aborts_if false; + + // We can also not prove this because `S` can be modified by `f` + ensures old(S[@0x2]) == S[@0x2]; + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.exp b/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.exp new file mode 100644 index 00000000000..f638baa0028 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.exp @@ -0,0 +1,17 @@ +Move prover returns: exiting with verification errors +error: post-condition does not hold + ┌─ tests/sources/functional/closures/closure_optimized_away.move:17:9 + │ +17 │ ensures result == x + 2; // This does not verify + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ + = at tests/sources/functional/closures/closure_optimized_away.move:13: test_closure_2 + = x = + = at tests/sources/functional/closures/closure_optimized_away.move:14: test_closure_2 + = x = + = y = + = result = + = at tests/sources/functional/closures/closure_optimized_away.move:14: test_closure_2 + = result = + = at tests/sources/functional/closures/closure_optimized_away.move:15: test_closure_2 + = at tests/sources/functional/closures/closure_optimized_away.move:17: test_closure_2 (spec) diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.move new file mode 100644 index 00000000000..12b1640dc7d --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_optimized_away.move @@ -0,0 +1,49 @@ +module 0x42::test { + + fun add(x: u64, y: u64): u64 { + x + y + } + fun test_closure_1(x: u64): u64 { + (add)(x, 1) + } + spec test_closure_1 { + ensures result == x + 1; + } + + fun test_closure_2(x: u64): u64 { + (|y| y + x)(1) + } + spec test_closure_2 { + ensures result == x + 2; // This does not verify + } + + fun test_closure_3(x: u64): u64 { + (|y| y + x)(1) + } + spec test_closure_3 { + ensures result == (add)(1 as u64, x); + } + + fun and(a: bool, b: bool): bool { + a && b + } + + fun test_closure_4(x: bool): bool { + and(x, false) + } + spec test_closure_4 { + ensures and(x, false) == (|y| y && x)(false); + } + + struct S has copy, drop { + f: T + } + + fun test_closure_5(x: S): bool { + and(x.f, false) + } + spec test_closure_5 { + ensures and(x.f, false) == (|s: S| s.f && x.f )(S { f: false }); + } + +} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.exp b/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.exp new file mode 100644 index 00000000000..40d65e4241f --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.exp @@ -0,0 +1,23 @@ +Move prover returns: exiting with verification errors +error: post-condition does not hold + ┌─ tests/sources/functional/closures/closure_provable.move:30:9 + │ +30 │ ensures result == x + 1; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + │ + = at tests/sources/functional/closures/closure_provable.move:25: call_exec3_fail + = x = + = at tests/sources/functional/closures/closure_provable.move:26: call_exec3_fail + = at tests/sources/functional/closures/closure_provable.move:4: exec + = f = + = x = + = at tests/sources/functional/closures/closure_provable.move:5: exec + = at tests/sources/functional/closures/closure_provable.move:26: call_exec3_fail + = y = + = result = + = at tests/sources/functional/closures/closure_provable.move:26: call_exec3_fail + = result = + = at tests/sources/functional/closures/closure_provable.move:6: exec + = result = + = at tests/sources/functional/closures/closure_provable.move:27: call_exec3_fail + = at tests/sources/functional/closures/closure_provable.move:30: call_exec3_fail (spec) diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.move new file mode 100644 index 00000000000..7a9bfe8775b --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_provable.move @@ -0,0 +1,41 @@ +module 0x42::test { + + + fun exec(f: |u64|u64, x: u64): u64 { + f(x) + } + + // We can prove the functions below because `exec` is inlined in Boogie and + // the function value is known in the inlining context. + + fun call_exec1_ok(x: u64): u64 { + exec(|y| x + y, 3) + } + spec call_exec1_ok { + ensures result == x + 3; + } + + fun call_exec2_ok(x: u64): u64 { + exec(|y| y + 1, x) + } + spec call_exec2_ok { + ensures result == x + 1; + } + + fun call_exec3_fail(x: u64): u64 { + exec(|y| y + 2, x) + } + spec call_exec3_fail { + // Expected to fail since result == x + 2 + ensures result == x + 1; + } + + fun call_exec4_ok(x: u64): u64 { + // Let doesn't matter + let f = |y| y + 1; + exec(f, x) + } + spec call_exec4_ok { + ensures result == x + 1; + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.exp b/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.exp new file mode 100644 index 00000000000..277468f81fc --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.exp @@ -0,0 +1,30 @@ +Move prover returns: exiting with verification errors +error: post-condition does not hold + ┌─ tests/sources/functional/closures/closure_refs.move:56:9 + │ +56 │ ensures result == 33; // expected to fail + │ ^^^^^^^^^^^^^^^^^^^^^ + │ + = at tests/sources/functional/closures/closure_refs.move:47: update_a + = s = + = at tests/sources/functional/closures/closure_refs.move:48: update_a + = at tests/sources/functional/closures/closure_refs.move:42: update_indirect + = s = + = borrow = + = new_value = + = at tests/sources/functional/closures/closure_refs.move:43: update_indirect + = at tests/sources/functional/closures/closure_refs.move:34: borrow_a + = s = + = at tests/sources/functional/closures/closure_refs.move:35: borrow_a + = result = + = s = + = at tests/sources/functional/closures/closure_refs.move:36: borrow_a + = = + = s = + = at tests/sources/functional/closures/closure_refs.move:44: update_indirect + = s = + = at tests/sources/functional/closures/closure_refs.move:49: update_a + = at tests/sources/functional/closures/closure_refs.move:46: update_a + = result = + = at tests/sources/functional/closures/closure_refs.move:50: update_a + = at tests/sources/functional/closures/closure_refs.move:56: update_a (spec) diff --git a/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.move b/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.move new file mode 100644 index 00000000000..1d0e86e4a25 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/closures/closure_refs.move @@ -0,0 +1,58 @@ +module 0x42::test { + + // Immut refs + + fun exec_ref(f: |&u64|u64, x: u64): u64 { + f(&x) + } + + fun call_exec_ref(x: u64): u64 { + exec_ref(|y| x + *y, 3) + } + spec call_exec_ref { + ensures result == x + 3; + } + + // Mut refs + + fun exec_mut_ref(f: |&mut u64|, x: u64): u64 { + f(&mut x); + x + } + + fun call_exec_mut_ref(x: u64): u64 { + exec_mut_ref(|y| *y = *y + 2, x) + } + spec call_exec_mut_ref { + ensures result == x + 2; + } + + // Mut ref derivation (expected to fail) + + struct S has drop { a: u64, b: u64 } + + fun borrow_a(s: &mut S): &mut u64 { + &mut s.a + } + + fun borrow_b(s: &mut S): &mut u64 { + &mut s.b + } + + fun update_indirect(s: &mut S, borrow: |&mut S|&mut u64, new_value: u64) { + *borrow(s) = new_value + } + + fun update_a(): u64 { + let s = S{a: 0, b: 0}; + update_indirect(&mut s, borrow_a, 33); + s.a + } + spec update_a { + // Currently we cannot verify code where borrow paths are derived via function values. + // This is since the reference elimination approach. + // TODO(#17904): there are potential ways to improve this, but ultimately, this does not fit with + // our reference elimination approach, which requires a statically known borrow path. + ensures result == 33; // expected to fail + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/emits.exp b/third_party/move/move-prover/tests/sources/functional/emits.exp index f68f38a31db..b0289030da4 100644 --- a/third_party/move/move-prover/tests/sources/functional/emits.exp +++ b/third_party/move/move-prover/tests/sources/functional/emits.exp @@ -72,6 +72,7 @@ error: function does not emit the expected event = handle = = at tests/sources/functional/emits.move:106: conditional_wrong_condition_incorrect = handle = + = at tests/sources/functional/emits.move:109: conditional_wrong_condition_incorrect = at tests/sources/functional/emits.move:111: conditional_wrong_condition_incorrect (spec) error: function does not emit the expected event @@ -85,6 +86,7 @@ error: function does not emit the expected event = handle = = at tests/sources/functional/emits.move:115: conditional_missing_condition_incorrect = handle = + = at tests/sources/functional/emits.move:118: conditional_missing_condition_incorrect = at tests/sources/functional/emits.move:120: conditional_missing_condition_incorrect (spec) error: function does not emit the expected event @@ -101,6 +103,7 @@ error: function does not emit the expected event = at tests/sources/functional/emits.move:152: conditional_multiple_incorrect = at tests/sources/functional/emits.move:149: conditional_multiple_incorrect = handle = + = at tests/sources/functional/emits.move:155: conditional_multiple_incorrect = at tests/sources/functional/emits.move:157: conditional_multiple_incorrect (spec) = at tests/sources/functional/emits.move:158: conditional_multiple_incorrect (spec) = at tests/sources/functional/emits.move:159: conditional_multiple_incorrect (spec) @@ -119,6 +122,7 @@ error: function does not emit the expected event = at tests/sources/functional/emits.move:182: conditional_multiple_same_incorrect = at tests/sources/functional/emits.move:179: conditional_multiple_same_incorrect = handle = + = at tests/sources/functional/emits.move:185: conditional_multiple_same_incorrect = at tests/sources/functional/emits.move:187: conditional_multiple_same_incorrect (spec) = at tests/sources/functional/emits.move:188: conditional_multiple_same_incorrect (spec) = at tests/sources/functional/emits.move:189: conditional_multiple_same_incorrect (spec) diff --git a/third_party/move/move-prover/tests/sources/functional/enum_invariants.exp b/third_party/move/move-prover/tests/sources/functional/enum_invariants.exp new file mode 100644 index 00000000000..83496628652 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/enum_invariants.exp @@ -0,0 +1,16 @@ +Move prover returns: exiting with verification errors +error: data invariant does not hold + ┌─ tests/sources/functional/enum_invariants.move:12:9 + │ +12 │ invariant self.bar > 0; + │ ^^^^^^^^^^^^^^^^^^^^^^^ + │ + = at tests/sources/functional/enum_invariants.move:31: sub_one_if_second_fail + = self = + = at tests/sources/functional/enum_invariants.move:33: sub_one_if_second_fail + = at tests/sources/functional/enum_invariants.move:34: sub_one_if_second_fail + = bar = + = self = + = at tests/sources/functional/enum_invariants.move:32: sub_one_if_second_fail + = self = + = at tests/sources/functional/enum_invariants.move:12 diff --git a/third_party/move/move-prover/tests/sources/functional/enum_invariants.move b/third_party/move/move-prover/tests/sources/functional/enum_invariants.move new file mode 100644 index 00000000000..a906342fc05 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/enum_invariants.move @@ -0,0 +1,37 @@ +module 0x42::m { + + struct Foo { + foo: u64, + } + + struct Bar { + bar: u64, + } + + spec Bar{ + invariant self.bar > 0; + } + + enum Foobar { + First { + foo: Foo, + }, + Second { + bar: Bar, + } + } + + fun add_one_if_first_ok(self: &mut Foobar) { + match(self) { + Foobar::First { foo } => foo.foo = foo.foo + 1, + Foobar::Second { bar } => bar.bar = bar.bar + 1, + } + } + + fun sub_one_if_second_fail(self: &mut Foobar) { + match(self) { + Foobar::First { foo } => foo.foo = foo.foo + 1, + Foobar::Second { bar } => bar.bar = bar.bar - 1, + } + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.exp b/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.exp new file mode 100644 index 00000000000..e49f03b539d --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.exp @@ -0,0 +1,21 @@ +Move prover returns: exiting with bytecode transformation errors +error: function `A::__lambda__1_inline_1_744__call_mutate_inline_no_modifies` is opaque but its specification does not have a modifies clause for `A::S` + ┌─ tests/sources/functional/inline-lambda-modifies.move:34:11 + │ +34 │ } spec { + │ ╭───────────^ +35 │ │ pragma opaque; +36 │ │ aborts_if !exists(addr); +37 │ │ ensures global(addr).x == 2; +38 │ │ }) + │ ╰─────────^ + +error: function `A::call_mutate_inline_caller_no_modifies` is opaque but its specification does not have a modifies clause for `A::S` + ┌─ tests/sources/functional/inline-lambda-modifies.move:52:5 + │ +52 │ ╭ spec call_mutate_inline_caller_no_modifies { +53 │ │ pragma opaque; +54 │ │ aborts_if !exists(addr); +55 │ │ ensures global(addr).x == 2; +56 │ │ } + │ ╰─────^ diff --git a/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.move b/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.move new file mode 100644 index 00000000000..a6e97abb4a3 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/inline-lambda-modifies.move @@ -0,0 +1,59 @@ +address 0x0 { +module A { + + struct S has key { + x: u64 + } + inline fun mutate_at(addr: address, f: |address|) { + f(addr) + } + + + fun call_mutate_at(addr: address) acquires S { + mutate_at(addr, |addr| { + let s = borrow_global_mut(addr); + s.x = 2; + } spec { + modifies global(addr); + pragma opaque; + aborts_if !exists(addr); + ensures global(addr).x == 2; + }) + } + spec call_mutate_at { + pragma opaque; + modifies global(addr); + aborts_if !exists(addr); + ensures global(addr).x == 2; + } + + fun call_mutate_inline_no_modifies(addr: address) acquires S { + mutate_at(addr, |addr| { + let s = borrow_global_mut(addr); + s.x = 2; + } spec { + pragma opaque; + aborts_if !exists(addr); + ensures global(addr).x == 2; + }) + } + + fun call_mutate_inline_caller_no_modifies(addr: address) acquires S { + mutate_at(addr, |addr| { + let s = borrow_global_mut(addr); + s.x = 2; + } spec { + pragma opaque; + modifies global(addr); + aborts_if !exists(addr); + ensures global(addr).x == 2; + }) + } + spec call_mutate_inline_caller_no_modifies { + pragma opaque; + aborts_if !exists(addr); + ensures global(addr).x == 2; + } + +} +} diff --git a/third_party/move/move-prover/tests/sources/functional/inline-lambda.exp b/third_party/move/move-prover/tests/sources/functional/inline-lambda.exp index 8b84018f424..d27a975a1ae 100644 --- a/third_party/move/move-prover/tests/sources/functional/inline-lambda.exp +++ b/third_party/move/move-prover/tests/sources/functional/inline-lambda.exp @@ -56,35 +56,35 @@ error: unknown assertion failed 32 │ assert w == e(x); // e is translated into an uninterpreted spec fun │ ^^^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:75: call_inline_fail_1 - = y = = at tests/sources/functional/inline-lambda.move:76: call_inline_fail_1 + = y = + = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 = z = = at tests/sources/functional/inline-lambda.move:24: inline_1 = x = = at tests/sources/functional/inline-lambda.move:25: inline_1 - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = x = = result = - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 - = y = + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 + = y' = = at tests/sources/functional/inline-lambda.move:26: inline_1 - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = z = = x = = result = - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = z' = = at tests/sources/functional/inline-lambda.move:27: inline_1 - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = y = = z = = x = - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = enter loop - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = result = - = at tests/sources/functional/inline-lambda.move:81: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:82: call_inline_fail_1 = w = = at tests/sources/functional/inline-lambda.move:29: inline_1 = at tests/sources/functional/inline-lambda.move:30: inline_1 @@ -97,41 +97,41 @@ error: unknown assertion failed 32 │ assert w == e(x); // e is translated into an uninterpreted spec fun │ ^^^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:84: call_inline_fail_2 - = y = = at tests/sources/functional/inline-lambda.move:85: call_inline_fail_2 + = y = + = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 = z = = at tests/sources/functional/inline-lambda.move:24: inline_1 = x = = at tests/sources/functional/inline-lambda.move:25: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 - = y = + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 + = y' = = at tests/sources/functional/inline-lambda.move:26: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z = = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z' = - = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:90: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:91: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:92: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:27: inline_1 - = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:90: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:91: call_inline_fail_2 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:92: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = y = = z = = x = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = enter loop - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = result = - = at tests/sources/functional/inline-lambda.move:94: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:95: call_inline_fail_2 = w = = at tests/sources/functional/inline-lambda.move:29: inline_1 = at tests/sources/functional/inline-lambda.move:30: inline_1 @@ -139,94 +139,94 @@ error: unknown assertion failed = at tests/sources/functional/inline-lambda.move:32: inline_1 error: function does not abort under this condition - ┌─ tests/sources/functional/inline-lambda.move:78:13 + ┌─ tests/sources/functional/inline-lambda.move:79:13 │ -78 │ aborts_if x > 0; // This does not verify +79 │ aborts_if x > 0; // This does not verify │ ^^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = y = = z = = x = - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 + = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 = enter loop - = at tests/sources/functional/inline-lambda.move:77: call_inline_fail_1 - = result = = at tests/sources/functional/inline-lambda.move:78: call_inline_fail_1 + = result = + = at tests/sources/functional/inline-lambda.move:79: call_inline_fail_1 error: precondition does not hold at this call - ┌─ tests/sources/functional/inline-lambda.move:89:13 + ┌─ tests/sources/functional/inline-lambda.move:90:13 │ -89 │ requires x > 0; // This does not verify at the call site +90 │ requires x > 0; // This does not verify at the call site │ ^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:84: call_inline_fail_2 - = y = = at tests/sources/functional/inline-lambda.move:85: call_inline_fail_2 + = y = + = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 = z = = at tests/sources/functional/inline-lambda.move:24: inline_1 = x = = at tests/sources/functional/inline-lambda.move:25: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 - = y = + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 + = y' = = at tests/sources/functional/inline-lambda.move:26: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z = = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z' = - = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:90: call_inline_fail_2 error: precondition does not hold at this call - ┌─ tests/sources/functional/inline-lambda.move:90:13 + ┌─ tests/sources/functional/inline-lambda.move:91:13 │ -90 │ requires z > 5; // This does not verify at the call site +91 │ requires z > 5; // This does not verify at the call site │ ^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:84: call_inline_fail_2 - = y = = at tests/sources/functional/inline-lambda.move:85: call_inline_fail_2 + = y = + = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 = z = = at tests/sources/functional/inline-lambda.move:24: inline_1 = x = = at tests/sources/functional/inline-lambda.move:25: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 - = y = + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 + = y' = = at tests/sources/functional/inline-lambda.move:26: inline_1 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z = = x = = result = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = z' = - = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:90: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:91: call_inline_fail_2 error: post-condition does not hold - ┌─ tests/sources/functional/inline-lambda.move:92:13 + ┌─ tests/sources/functional/inline-lambda.move:93:13 │ -92 │ ensures result == (x == 5); // This does not verify +93 │ ensures result == (x == 5); // This does not verify │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 - = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:90: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:91: call_inline_fail_2 - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:92: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = y = = z = = x = - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = enter loop - = at tests/sources/functional/inline-lambda.move:86: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:87: call_inline_fail_2 = result = - = at tests/sources/functional/inline-lambda.move:88: call_inline_fail_2 - = at tests/sources/functional/inline-lambda.move:91: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:89: call_inline_fail_2 = at tests/sources/functional/inline-lambda.move:92: call_inline_fail_2 + = at tests/sources/functional/inline-lambda.move:93: call_inline_fail_2 diff --git a/third_party/move/move-prover/tests/sources/functional/inline-lambda.move b/third_party/move/move-prover/tests/sources/functional/inline-lambda.move index 4cadfd9367c..19019c6667d 100644 --- a/third_party/move/move-prover/tests/sources/functional/inline-lambda.move +++ b/third_party/move/move-prover/tests/sources/functional/inline-lambda.move @@ -58,6 +58,7 @@ module 0x42::Test { fun call_inline_2(y: u64) { let z = 3 + y; inline_2(y, |x| { while(z < y) {let _x = x;}; x > 5 } spec { + pragma opaque; requires x > 0; ensures result == (x > 5); ensures result != !(x > 5); @@ -121,4 +122,20 @@ module 0x42::Test { let s = vector[1, 2, 3]; let (_a, _b) = find(&s, |x| *x > 1); } + + inline fun inline_3(x: &mut u64, f: |&mut u64|) { + f(x); + } + + fun call_inline_3(x: &mut u64) { + inline_3(x, |y| *y = *y + 1 spec { + ensures y == old(y) + 1; + }); + } + + spec call_inline_3 { + ensures x == old(x) + 1; + } + + } diff --git a/third_party/move/move-prover/tests/sources/functional/invariants.exp b/third_party/move/move-prover/tests/sources/functional/invariants.exp index 01a2cd1aa10..ec9803cb932 100644 --- a/third_party/move/move-prover/tests/sources/functional/invariants.exp +++ b/third_party/move/move-prover/tests/sources/functional/invariants.exp @@ -45,8 +45,6 @@ error: data invariant does not hold = at tests/sources/functional/invariants.move:157: lifetime_invalid_S_branching = b_ref = = at tests/sources/functional/invariants.move:158: lifetime_invalid_S_branching - = at tests/sources/functional/invariants.move:143 - = at tests/sources/functional/invariants.move:158: lifetime_invalid_S_branching = a = = x_ref = = at tests/sources/functional/invariants.move:160: lifetime_invalid_S_branching diff --git a/third_party/move/move-prover/tests/sources/functional/loops_with_memory_ops.exp b/third_party/move/move-prover/tests/sources/functional/loops_with_memory_ops.exp index 1cd7f8e1ae5..e7b1ba0abd1 100644 --- a/third_party/move/move-prover/tests/sources/functional/loops_with_memory_ops.exp +++ b/third_party/move/move-prover/tests/sources/functional/loops_with_memory_ops.exp @@ -43,7 +43,10 @@ error: induction case of the loop invariant does not hold = y = = at tests/sources/functional/loops_with_memory_ops.move:80: nested_loop2 = at tests/sources/functional/loops_with_memory_ops.move:81: nested_loop2 + = a = + = at tests/sources/functional/loops_with_memory_ops.move:81: nested_loop2 = b = + = at tests/sources/functional/loops_with_memory_ops.move:81: nested_loop2 = at tests/sources/functional/loops_with_memory_ops.move:85: nested_loop2 = i = = at tests/sources/functional/loops_with_memory_ops.move:86: nested_loop2 @@ -105,6 +108,8 @@ error: unknown assertion failed = y = = at tests/sources/functional/loops_with_memory_ops.move:80: nested_loop2 = at tests/sources/functional/loops_with_memory_ops.move:81: nested_loop2 + = a = + = b = = at tests/sources/functional/loops_with_memory_ops.move:85: nested_loop2 = i = = at tests/sources/functional/loops_with_memory_ops.move:86: nested_loop2 diff --git a/third_party/move/move-prover/tests/sources/functional/mut_ref.exp b/third_party/move/move-prover/tests/sources/functional/mut_ref.exp index 75804ab3c40..c88a152bc33 100644 --- a/third_party/move/move-prover/tests/sources/functional/mut_ref.exp +++ b/third_party/move/move-prover/tests/sources/functional/mut_ref.exp @@ -34,8 +34,6 @@ error: data invariant does not hold = b = = x = = at tests/sources/functional/mut_ref.move:91: return_ref_different_path_vec2 - = return = - = at tests/sources/functional/mut_ref.move:91: return_ref_different_path_vec2 = result = = x = = at tests/sources/functional/mut_ref.move:92: return_ref_different_path_vec2 diff --git a/third_party/move/move-prover/tests/sources/functional/restrictions.exp b/third_party/move/move-prover/tests/sources/functional/restrictions.exp index af2b26bff64..1fa085fcc42 100644 --- a/third_party/move/move-prover/tests/sources/functional/restrictions.exp +++ b/third_party/move/move-prover/tests/sources/functional/restrictions.exp @@ -11,7 +11,7 @@ error: [boogie translator] function result type not yet supported 12 │ fun f2(): | |num { | | 1 } │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: [boogie translator] Invoke not yet supported +error: [boogie translator] current restriction: a function value cannot be used in a specification expression. ┌─ tests/sources/functional/restrictions.move:16:13 │ 16 │ f(1u64) diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.exp b/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.exp new file mode 100644 index 00000000000..fc3406838b7 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.exp @@ -0,0 +1,221 @@ +Move prover returns: exiting with verification errors +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:128:5 + │ +126 │ x / y + │ ----- abort happened here with execution failure +127 │ } +128 │ ╭ spec div_by_zero_i64_incorrect { +129 │ │ aborts_if false; +130 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:125: div_by_zero_i64_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:126: div_by_zero_i64_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:148:5 + │ +146 │ x + y + │ ----- abort happened here with execution failure +147 │ } +148 │ ╭ spec overflow_i8_add_incorrect { +149 │ │ aborts_if false; +150 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:145: overflow_i8_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:146: overflow_i8_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:164:5 + │ +162 │ x + y + │ ----- abort happened here with execution failure +163 │ } +164 │ ╭ spec overflow_i16_add_incorrect { +165 │ │ aborts_if false; +166 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:161: overflow_i16_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:162: overflow_i16_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:180:5 + │ +178 │ x + y + │ ----- abort happened here with execution failure +179 │ } +180 │ ╭ spec overflow_i32_add_incorrect { +181 │ │ aborts_if false; +182 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:177: overflow_i32_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:178: overflow_i32_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:196:5 + │ +194 │ x + y + │ ----- abort happened here with execution failure +195 │ } +196 │ ╭ spec overflow_i64_add_incorrect { +197 │ │ aborts_if false; +198 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:193: overflow_i64_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:194: overflow_i64_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:212:5 + │ +210 │ x + y + │ ----- abort happened here with execution failure +211 │ } +212 │ ╭ spec overflow_i128_add_incorrect { +213 │ │ aborts_if false; +214 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:209: overflow_i128_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:210: overflow_i128_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:228:5 + │ +226 │ x + y + │ ----- abort happened here with execution failure +227 │ } +228 │ ╭ spec overflow_i256_add_incorrect { +229 │ │ aborts_if false; +230 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:225: overflow_i256_add_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:226: overflow_i256_add_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:249:5 + │ +247 │ x * y + │ ----- abort happened here with execution failure +248 │ } +249 │ ╭ spec overflow_i8_mul_incorrect { +250 │ │ aborts_if false; +251 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:246: overflow_i8_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:247: overflow_i8_mul_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:265:5 + │ +263 │ x * y + │ ----- abort happened here with execution failure +264 │ } +265 │ ╭ spec overflow_i16_mul_incorrect { +266 │ │ aborts_if false; +267 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:262: overflow_i16_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:263: overflow_i16_mul_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:281:5 + │ +279 │ x * y + │ ----- abort happened here with execution failure +280 │ } +281 │ ╭ spec overflow_i32_mul_incorrect { +282 │ │ aborts_if false; +283 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:278: overflow_i32_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:279: overflow_i32_mul_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:297:5 + │ +295 │ x * y + │ ----- abort happened here with execution failure +296 │ } +297 │ ╭ spec overflow_i64_mul_incorrect { +298 │ │ aborts_if false; +299 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:294: overflow_i64_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:295: overflow_i64_mul_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:312:5 + │ +310 │ x * y + │ ----- abort happened here with execution failure +311 │ } +312 │ ╭ spec overflow_i128_mul_incorrect { +313 │ │ aborts_if false; +314 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:309: overflow_i128_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:310: overflow_i128_mul_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/artithmetic.move:327:5 + │ +325 │ x * y + │ ----- abort happened here with execution failure +326 │ } +327 │ ╭ spec overflow_i256_mul_incorrect { +328 │ │ aborts_if false; +329 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/artithmetic.move:324: overflow_i256_mul_incorrect + = x = + = y = + = at tests/sources/functional/signed_int/artithmetic.move:325: overflow_i256_mul_incorrect + = ABORTED diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.move b/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.move new file mode 100644 index 00000000000..d71ef9c74db --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/artithmetic.move @@ -0,0 +1,338 @@ +module 0x42::TestSintArithmetic { + + spec module { + pragma verify = true; + } + + // -------------------------- + // Basic arithmetic operation + // -------------------------- + + // Most of the tests here just ensure that what the bytecode operation does + // is the same as the spec expressions. + + // succeeds. + fun add_two_number(x: i64, y: i64): (i64, i64) { + let res: i64 = x + y; + let z: i64 = 3; + (z, res) + } + spec add_two_number { + aborts_if x + y > MAX_I64 || x + y < MIN_I64; + ensures result_1 == 3; + ensures result_2 == x + y; + } + + fun div(x: i64, y: i64): (i64, i64) { + (x / y, x % y) + } + spec div { + aborts_if y == 0; + ensures result_1 == x / y; + ensures result_2 == x % y; + } + + // succeeds. + fun multiple_ops(x: i64, y: i64, z: i64): i64 { + x + y * z + } + spec multiple_ops { + ensures result == x + y * z; + } + + // succeeds. + fun bool_ops(a: i64, b: i64): (bool, bool) { + let c: bool; + let d: bool; + c = a > b && a >= b; + d = a < b || a <= b; + if (!(c != d)) abort 42; + (c, d) + } + spec bool_ops { + ensures result_1 <==> (a > b && a >= b); + ensures result_2 <==> (a < b || a <= b); + } + + // succeeds. + fun arithmetic_ops(a: i64): (i64, i64) { + let c: i64; + c = (6 + 4 - 1) * 2 / 3 % 4; + if (c != 2) abort 42; + (c, a) + } + spec arithmetic_ops { + ensures result_1 == (6 + 4 - 1) * 2 / 3 % 4; + ensures result_2 == a; + } + + fun f(x: i64) : i64 { + x+1 + } + spec f { + aborts_if x+1 > MAX_I64; + ensures result == x+1; + } + + fun g(x: i64) : i64 { + x+2 + } + spec g { + aborts_if x+2 > MAX_I64; + ensures result == x+2; + } + + fun h(b: bool): i64 { + let x: i64 = 3; + let y: i64; + if (b) y=f(x) else y=g(x); + if (b && y != 4) abort 4; + if (!b && y != 5) abort 5; + y + } + spec h { + aborts_if false; + } + + + // --------- + // Underflow + // --------- + + // succeeds. + fun underflow(): i64 { + let x = -9223372036854775808; + x - 1 + } + spec underflow { + aborts_if true; + } + + + // ---------------- + // Division by zero + // ---------------- + + // succeeds. + fun div_by_zero(): i64 { + let x = 0; + 1 / x + } + spec div_by_zero { + aborts_if true; + } + + fun div_by_zero_i64_incorrect(x: i64, y: i64): i64 { + x / y + } + spec div_by_zero_i64_incorrect { + aborts_if false; + } + + fun div_by_zero_i64(x: i64, y: i64): i64 { + x / y + } + spec div_by_zero_i64 { + aborts_if y == 0; + } + + + // -------------------- + // Overflow by addition + // -------------------- + + // fails. + fun overflow_i8_add_incorrect(x: i8, y: i8): i8 { + x + y + } + spec overflow_i8_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i8_add(x: i8, y: i8): i8 { + x + y + } + spec overflow_i8_add { + aborts_if x + y > MAX_I8 || x + y < MIN_I8; + } + + // fails. + fun overflow_i16_add_incorrect(x: i16, y: i16): i16 { + x + y + } + spec overflow_i16_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i16_add(x: i16, y: i16): i16 { + x + y + } + spec overflow_i16_add { + aborts_if x + y > MAX_I16 || x + y < MIN_I16; + } + + // fails. + fun overflow_i32_add_incorrect(x: i32, y: i32): i32 { + x + y + } + spec overflow_i32_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i32_add(x: i32, y: i32): i32 { + x + y + } + spec overflow_i32_add { + aborts_if x + y > MAX_I32 || x + y < MIN_I32; + } + + // fails. + fun overflow_i64_add_incorrect(x: i64, y: i64): i64 { + x + y + } + spec overflow_i64_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i64_add(x: i64, y: i64): i64 { + x + y + } + spec overflow_i64_add { + aborts_if x + y > MAX_I64 || x + y < MIN_I64; + } + + // fails. + fun overflow_i128_add_incorrect(x: i128, y: i128): i128 { + x + y + } + spec overflow_i128_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i128_add(x: i128, y: i128): i128 { + x + y + } + spec overflow_i128_add { + aborts_if x + y > MAX_I128 || x + y < MIN_I128; + } + + // fails. + fun overflow_i256_add_incorrect(x: i256, y: i256): i256 { + x + y + } + spec overflow_i256_add_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i256_add(x: i256, y: i256): i256 { + x + y + } + spec overflow_i256_add { + aborts_if x + y > MAX_I256 || x + y < MIN_I256; + } + + + // -------------------------- + // Overflow by multiplication + // -------------------------- + + // fails. + fun overflow_i8_mul_incorrect(x: i8, y: i8): i8 { + x * y + } + spec overflow_i8_mul_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i8_mul(x: i8, y: i8): i8 { + x * y + } + spec overflow_i8_mul { + aborts_if x * y > MAX_I8 || x * y < MIN_I8; + } + + // fails. + fun overflow_i16_mul_incorrect(x: i16, y: i16): i16 { + x * y + } + spec overflow_i16_mul_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i16_mul(x: i16, y: i16): i16 { + x * y + } + spec overflow_i16_mul { + aborts_if x * y > MAX_I16 || x * y < MIN_I16; + } + + // fails. + fun overflow_i32_mul_incorrect(x: i32, y: i32): i32 { + x * y + } + spec overflow_i32_mul_incorrect { + aborts_if false; + } + + // succeeds. + fun overflow_i32_mul(x: i32, y: i32): i32 { + x * y + } + spec overflow_i32_mul { + aborts_if x * y > MAX_I32 || x * y < MIN_I32; + } + + // fails. + fun overflow_i64_mul_incorrect(x: i64, y: i64): i64 { + x * y + } + spec overflow_i64_mul_incorrect { + aborts_if false; + } + + fun overflow_i64_mul(x: i64, y: i64): i64 { + x * y + } + spec overflow_i64_mul { + aborts_if x * y > MAX_I64 || x * y < MIN_I64; + } + + // fails. + fun overflow_i128_mul_incorrect(x: i128, y: i128): i128 { + x * y + } + spec overflow_i128_mul_incorrect { + aborts_if false; + } + + fun overflow_i128_mul(x: i128, y: i128): i128 { + x * y + } + spec overflow_i128_mul { + aborts_if x * y > MAX_I128 || x * y < MIN_I128; + } + + // fails. + fun overflow_i256_mul_incorrect(x: i256, y: i256): i256 { + x * y + } + spec overflow_i256_mul_incorrect { + aborts_if false; + } + + fun overflow_i256_mul(x: i256, y: i256): i256 { + x * y + } + spec overflow_i256_mul { + aborts_if x * y > MAX_I256 || x * y < MIN_I256; + } + +} diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/cast.exp b/third_party/move/move-prover/tests/sources/functional/signed_int/cast.exp new file mode 100644 index 00000000000..5a0bf8d8288 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/cast.exp @@ -0,0 +1,80 @@ +Move prover returns: exiting with verification errors +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/cast.move:53:5 + │ +51 │ (x as i8) + │ --------- abort happened here with execution failure +52 │ } +53 │ ╭ spec aborting_i8_cast_incorrect { +54 │ │ aborts_if false; +55 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/cast.move:50: aborting_i8_cast_incorrect + = x = + = at tests/sources/functional/signed_int/cast.move:51: aborting_i8_cast_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/cast.move:67:5 + │ +65 │ (x as i16) + │ ---------- abort happened here with execution failure +66 │ } +67 │ ╭ spec aborting_i16_cast_incorrect { +68 │ │ aborts_if false; +69 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/cast.move:64: aborting_i16_cast_incorrect + = x = + = at tests/sources/functional/signed_int/cast.move:65: aborting_i16_cast_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/cast.move:81:5 + │ +79 │ (x as i32) + │ ---------- abort happened here with execution failure +80 │ } +81 │ ╭ spec aborting_i32_cast_incorrect { +82 │ │ aborts_if false; +83 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/cast.move:78: aborting_i32_cast_incorrect + = x = + = at tests/sources/functional/signed_int/cast.move:79: aborting_i32_cast_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/cast.move:95:5 + │ +93 │ (x as i64) + │ ---------- abort happened here with execution failure +94 │ } +95 │ ╭ spec aborting_i64_cast_incorrect { +96 │ │ aborts_if false; +97 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/cast.move:92: aborting_i64_cast_incorrect + = x = + = at tests/sources/functional/signed_int/cast.move:93: aborting_i64_cast_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/cast.move:109:5 + │ +107 │ (x as i128) + │ ----------- abort happened here with execution failure +108 │ } +109 │ ╭ spec aborting_i128_cast_incorrect { +110 │ │ aborts_if false; +111 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/cast.move:106: aborting_i128_cast_incorrect + = x = + = at tests/sources/functional/signed_int/cast.move:107: aborting_i128_cast_incorrect + = ABORTED diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/cast.move b/third_party/move/move-prover/tests/sources/functional/signed_int/cast.move new file mode 100644 index 00000000000..6caf02eaebe --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/cast.move @@ -0,0 +1,127 @@ +module 0x42::TestCast { + + spec module { + pragma verify = true; + } + + // -------------- + // Type promotion + // -------------- + + fun i8_cast(x: i8): i64 { + (x as i64) + } + spec i8_cast { + aborts_if false; + } + + fun i16_cast(x: i16): i64 { + (x as i64) + } + spec i16_cast { + aborts_if false; + } + + fun i32_cast(x: i32): i64 { + (x as i64) + } + spec i32_cast { + aborts_if false; + } + + fun i64_cast(x: i64): i128 { + (x as i128) + } + spec i64_cast { + aborts_if false; + } + + fun i128_cast(x: i128): i256 { + (x as i256) + } + spec i128_cast { + aborts_if false; + } + + // ------------- + // Type demotion + // ------------- + + fun aborting_i8_cast_incorrect(x: i64): i8 { + (x as i8) + } + spec aborting_i8_cast_incorrect { + aborts_if false; + } + + fun aborting_i8_cast(x: i64): i8 { + (x as i8) + } + spec aborting_i8_cast { + aborts_if x > 127 || x < -128; + } + + fun aborting_i16_cast_incorrect(x: i64): i16 { + (x as i16) + } + spec aborting_i16_cast_incorrect { + aborts_if false; + } + + fun aborting_i16_cast(x: i64): i16 { + (x as i16) + } + spec aborting_i16_cast { + aborts_if x > 32767 || x < -32768; + } + + fun aborting_i32_cast_incorrect(x: i64): i32 { + (x as i32) + } + spec aborting_i32_cast_incorrect { + aborts_if false; + } + + fun aborting_i32_cast(x: i64): i32 { + (x as i32) + } + spec aborting_i32_cast { + aborts_if x > 2147483647 || x < -2147483648; + } + + fun aborting_i64_cast_incorrect(x: i128): i64 { + (x as i64) + } + spec aborting_i64_cast_incorrect { + aborts_if false; + } + + fun aborting_i64_cast(x: i128): i64 { + (x as i64) + } + spec aborting_i64_cast { + aborts_if x > 9223372036854775807 || x < -9223372036854775808; + } + + fun aborting_i128_cast_incorrect(x: i256): i128 { + (x as i128) + } + spec aborting_i128_cast_incorrect { + aborts_if false; + } + + fun aborting_i128_cast(x: i256): i128 { + (x as i128) + } + spec aborting_i128_cast { + aborts_if x > 170141183460469231731687303715884105727 || x < -170141183460469231731687303715884105728; + } + + fun cast_bv_to_sint(x: u64): i64 { + (x & 0x1u64) as i64 + } + + spec cast_bv_to_sint { + aborts_if false; + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/error.exp b/third_party/move/move-prover/tests/sources/functional/signed_int/error.exp new file mode 100644 index 00000000000..c2fdc787f47 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/error.exp @@ -0,0 +1,30 @@ +Move prover returns: exiting with condition generation errors +error: signed integer cannot be turned into bit vector + ┌─ tests/sources/functional/signed_int/error.move:11:25 + │ +11 │ invariant x >= (x ^ (1 as i64)); + │ ^ + +error: signed integer cannot be turned into bit vector + ┌─ tests/sources/functional/signed_int/error.move:12:25 + │ +12 │ invariant x >= (x | (1 as i64)); + │ ^ + +error: signed integer cannot be turned into bit vector + ┌─ tests/sources/functional/signed_int/error.move:13:25 + │ +13 │ invariant x >= (x & (1 as i64)); + │ ^ + +error: [boogie translator] signed integer types not supported in operation $shl + ┌─ tests/sources/functional/signed_int/error.move:14:24 + │ +14 │ invariant x >= (x << (1 as i64)); + │ ^^^^^^^^^^^^^^^^^ + +error: [boogie translator] signed integer types not supported in operation $shr + ┌─ tests/sources/functional/signed_int/error.move:15:25 + │ +15 │ invariant x >= (x >> (1 as i64)); + │ ^ diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/error.move b/third_party/move/move-prover/tests/sources/functional/signed_int/error.move new file mode 100644 index 00000000000..f53bfb4cf50 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/error.move @@ -0,0 +1,17 @@ +module 0x42::InvalidOr { + struct Int_test { + x : i64, + } + + fun test(foo: &mut Int_test) { + foo.x = foo.x + 1; + } + + spec Int_test { + invariant x >= (x ^ (1 as i64)); + invariant x >= (x | (1 as i64)); + invariant x >= (x & (1 as i64)); + invariant x >= (x << (1 as i64)); + invariant x >= (x >> (1 as i64)); + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/negate.exp b/third_party/move/move-prover/tests/sources/functional/signed_int/negate.exp new file mode 100644 index 00000000000..3ed8457d6d6 --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/negate.exp @@ -0,0 +1,96 @@ +Move prover returns: exiting with verification errors +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:11:5 + │ + 9 │ -x + │ -- abort happened here with execution failure +10 │ } +11 │ ╭ spec negate_i8_incorrect { +12 │ │ aborts_if false; +13 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:8: negate_i8_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:9: negate_i8_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:26:5 + │ +24 │ -x + │ -- abort happened here with execution failure +25 │ } +26 │ ╭ spec negate_i16_incorrect { +27 │ │ aborts_if false; +28 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:23: negate_i16_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:24: negate_i16_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:42:5 + │ +40 │ -x + │ -- abort happened here with execution failure +41 │ } +42 │ ╭ spec negate_i32_incorrect { +43 │ │ aborts_if false; +44 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:39: negate_i32_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:40: negate_i32_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:58:5 + │ +56 │ -x + │ -- abort happened here with execution failure +57 │ } +58 │ ╭ spec negate_i64_incorrect { +59 │ │ aborts_if false; +60 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:55: negate_i64_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:56: negate_i64_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:74:5 + │ +72 │ -x + │ -- abort happened here with execution failure +73 │ } +74 │ ╭ spec negate_i128_incorrect { +75 │ │ aborts_if false; +76 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:71: negate_i128_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:72: negate_i128_incorrect + = ABORTED + +error: abort not covered by any of the `aborts_if` clauses + ┌─ tests/sources/functional/signed_int/negate.move:90:5 + │ +88 │ -x + │ -- abort happened here with execution failure +89 │ } +90 │ ╭ spec negate_i256_incorrect { +91 │ │ aborts_if false; +92 │ │ } + │ ╰─────^ + │ + = at tests/sources/functional/signed_int/negate.move:87: negate_i256_incorrect + = x = + = at tests/sources/functional/signed_int/negate.move:88: negate_i256_incorrect + = ABORTED diff --git a/third_party/move/move-prover/tests/sources/functional/signed_int/negate.move b/third_party/move/move-prover/tests/sources/functional/signed_int/negate.move new file mode 100644 index 00000000000..ead09f550af --- /dev/null +++ b/third_party/move/move-prover/tests/sources/functional/signed_int/negate.move @@ -0,0 +1,100 @@ +module 0x42::TestCast { + + spec module { + pragma verify = true; + } + + // i8 + fun negate_i8_incorrect(x: i8): i8 { + -x + } + spec negate_i8_incorrect { + aborts_if false; + } + + fun negate_i8(x: i8): i8 { + -x + } + spec negate_i8 { + aborts_if x == -128; // -(2^7) + } + + // i16 + fun negate_i16_incorrect(x: i16): i16 { + -x + } + spec negate_i16_incorrect { + aborts_if false; + } + + fun negate_i16(x: i16): i16 { + -x + } + spec negate_i16 { + aborts_if x == -32768; // -(2^15) + } + + + // i32 + fun negate_i32_incorrect(x: i32): i32 { + -x + } + spec negate_i32_incorrect { + aborts_if false; + } + + fun negate_i32(x: i32): i32 { + -x + } + spec negate_i32 { + aborts_if x == -2147483648; // -(2^31) + } + + + // i64 + fun negate_i64_incorrect(x: i64): i64 { + -x + } + spec negate_i64_incorrect { + aborts_if false; + } + + fun negate_i64(x: i64): i64 { + -x + } + spec negate_i64 { + aborts_if x == -9223372036854775808; // -(2^63) + } + + + // i128 + fun negate_i128_incorrect(x: i128): i128 { + -x + } + spec negate_i128_incorrect { + aborts_if false; + } + + fun negate_i128(x: i128): i128 { + -x + } + spec negate_i128 { + aborts_if x == -170141183460469231731687303715884105728; // -(2^127) + } + + + // i256 + fun negate_i256_incorrect(x: i256): i256 { + -x + } + spec negate_i256_incorrect { + aborts_if false; + } + + fun negate_i256(x: i256): i256 { + -x + } + spec negate_i256 { + aborts_if x == -57896044618658097711785492504343953926634992332820282019728792003956564819968; // -(2^255) + } +} diff --git a/third_party/move/move-prover/tests/sources/functional/type_reflection.move b/third_party/move/move-prover/tests/sources/functional/type_reflection.move index 0f5ae8e30ed..b8b4a1f98d6 100644 --- a/third_party/move/move-prover/tests/sources/functional/type_reflection.move +++ b/third_party/move/move-prover/tests/sources/functional/type_reflection.move @@ -143,6 +143,48 @@ module 0x43::test { ensures result.bytes == b"bool"; } + fun test_type_name_concrete_i8(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i8 { + ensures result.bytes == b"i8"; + } + + fun test_type_name_concrete_i16(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i16 { + ensures result.bytes == b"i16"; + } + + fun test_type_name_concrete_i32(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i32 { + ensures result.bytes == b"i32"; + } + + fun test_type_name_concrete_i64(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i64 { + ensures result.bytes == b"i64"; + } + + fun test_type_name_concrete_i128(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i128 { + ensures result.bytes == b"i128"; + } + + fun test_type_name_concrete_i256(): ascii::String { + type_name::into_string(type_name::get()) + } + spec test_type_name_concrete_i256 { + ensures result.bytes == b"i256"; + } + fun test_type_name_concrete_vector(): ascii::String { type_name::into_string(type_name::get>>()) } diff --git a/third_party/move/move-stdlib/Cargo.toml b/third_party/move/move-stdlib/Cargo.toml index 4b02d534248..7080acca9f7 100644 --- a/third_party/move/move-stdlib/Cargo.toml +++ b/third_party/move/move-stdlib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "move-stdlib" version = "0.1.1" -edition = "2021" +edition = { workspace = true } authors = ["Diem Association "] description = "Diem stdlib" repository = "https://github.com/diem/diem" @@ -37,4 +37,4 @@ move-unit-test = { workspace = true } tempfile = { workspace = true } [features] -testing = [] +testing = ["move-vm-types/testing"] diff --git a/third_party/move/move-stdlib/docs/option.md b/third_party/move/move-stdlib/docs/option.md index 698df505bcc..8ed106412c3 100644 --- a/third_party/move/move-stdlib/docs/option.md +++ b/third_party/move/move-stdlib/docs/option.md @@ -943,7 +943,7 @@ Apply the function to the optional element reference. Folds the function over the optional element. -
public fun fold<Accumulator, Element>(o: option::Option<Element>, init: Accumulator, f: |(Accumulator, Element)|Accumulator): Accumulator
+
public fun fold<Accumulator, Element>(o: option::Option<Element>, init: Accumulator, f: |Accumulator, Element|Accumulator): Accumulator
 
diff --git a/third_party/move/move-stdlib/docs/vector.md b/third_party/move/move-stdlib/docs/vector.md index c50a8c59f3a..2de4b0d99b5 100644 --- a/third_party/move/move-stdlib/docs/vector.md +++ b/third_party/move/move-stdlib/docs/vector.md @@ -26,6 +26,7 @@ the return on investment didn't seem worth it for these simple functions. - [Function `swap`](#0x1_vector_swap) - [Function `singleton`](#0x1_vector_singleton) - [Function `reverse`](#0x1_vector_reverse) +- [Function `find`](#0x1_vector_find) - [Function `append`](#0x1_vector_append) - [Function `is_empty`](#0x1_vector_is_empty) - [Function `contains`](#0x1_vector_contains) @@ -342,6 +343,53 @@ Reverses the order of the elements in the vector v in place. + + + + +## Function `find` + + + +
public fun find<Element>(v: &vector<Element>, f: |&Element|bool): (bool, u64)
+
+ + + +
+Implementation + + +
public inline fun find<Element>(v: &vector<Element>, f: |&Element|bool): (bool, u64) {
+    let find = false;
+    let found_index = 0;
+    let i = 0;
+    let len = length(v);
+    while ({
+        spec {
+            invariant i <= len;
+            invariant forall j: num where j >= 0 && j < i: !f(borrow(v, j));
+            invariant find ==> i < len && f(borrow(v, i));
+        };
+        i < len
+        }) {
+        // Cannot call return in an inline function so we need to resort to break here.
+        if (f(borrow(v, i))) {
+            find = true;
+            found_index = i;
+            break
+        };
+        i = i + 1;
+    };
+    spec {
+        assert !find <==> (forall j: num where j >= 0 && j < len: !f(v[j]));
+    };
+    (find, found_index)
+}
+
+ + +
@@ -690,7 +738,7 @@ Fold the function over the elements. For example, fold<Accumulator, Element>(v: vector<Element>, init: Accumulator, f: |(Accumulator, Element)|Accumulator): Accumulator +
public fun fold<Accumulator, Element>(v: vector<Element>, init: Accumulator, f: |Accumulator, Element|Accumulator): Accumulator
 
diff --git a/third_party/move/move-stdlib/sources/vector.move b/third_party/move/move-stdlib/sources/vector.move index 82c3387e474..68dc17970a7 100644 --- a/third_party/move/move-stdlib/sources/vector.move +++ b/third_party/move/move-stdlib/sources/vector.move @@ -78,6 +78,32 @@ module std::vector { pragma intrinsic = true; } + public inline fun find(v: &vector, f: |&Element|bool): (bool, u64) { + let find = false; + let found_index = 0; + let i = 0; + let len = length(v); + while ({ + spec { + invariant i <= len; + invariant forall j: num where j >= 0 && j < i: !f(borrow(v, j)); + invariant find ==> i < len && f(borrow(v, i)); + }; + i < len + }) { + // Cannot call return in an inline function so we need to resort to break here. + if (f(borrow(v, i))) { + find = true; + found_index = i; + break + }; + i = i + 1; + }; + spec { + assert !find <==> (forall j: num where j >= 0 && j < len: !f(v[j])); + }; + (find, found_index) + } /// Pushes all of the elements of the `other` vector into the `lhs` vector. public fun append(lhs: &mut vector, other: vector) { diff --git a/third_party/move/move-stdlib/src/natives/bcs.rs b/third_party/move/move-stdlib/src/natives/bcs.rs index 1904d06de6c..90238c16223 100644 --- a/third_party/move/move-stdlib/src/natives/bcs.rs +++ b/third_party/move/move-stdlib/src/natives/bcs.rs @@ -41,7 +41,7 @@ pub struct ToBytesGasParameters { fn native_to_bytes( gas_params: &ToBytesGasParameters, context: &mut NativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.len() == 1); @@ -51,10 +51,10 @@ fn native_to_bytes( // pop type and value let ref_to_val = pop_arg!(args, Reference); - let arg_type = ty_args.pop().unwrap(); + let arg_type = &ty_args[0]; // get type layout - let layout = match context.type_to_type_layout(&arg_type) { + let layout = match context.type_to_type_layout(arg_type) { Ok(layout) => layout, Err(_) => { cost += gas_params.failure; diff --git a/third_party/move/move-stdlib/src/natives/debug.rs b/third_party/move/move-stdlib/src/natives/debug.rs index 43461fadab9..b6dac55ed2e 100644 --- a/third_party/move/move-stdlib/src/natives/debug.rs +++ b/third_party/move/move-stdlib/src/natives/debug.rs @@ -30,7 +30,7 @@ pub struct PrintGasParameters { fn native_print( gas_params: &PrintGasParameters, _context: &mut NativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, _move_std_addr: AccountAddress, ) -> PartialVMResult { @@ -38,7 +38,7 @@ fn native_print( debug_assert!(args.len() == 1); let _val = args.pop_back().unwrap(); - let _ty = ty_args.pop().unwrap(); + let _ty = &ty_args[0]; // No-op if the feature flag is not present. #[cfg(feature = "testing")] @@ -93,7 +93,7 @@ pub struct PrintStackTraceGasParameters { fn native_print_stack_trace( gas_params: &PrintStackTraceGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); @@ -175,18 +175,22 @@ mod testing { } fn get_annotated_struct_layout( - context: &NativeContext, + context: &mut NativeContext, ty: &Type, ) -> PartialVMResult { let annotated_type_layout = context.type_to_fully_annotated_layout(ty)?; - match annotated_type_layout { - MoveTypeLayout::Struct(annotated_struct_layout) => Ok(annotated_struct_layout), - _ => Err( + if let Some(MoveTypeLayout::Struct(annotated_struct_layout)) = + annotated_type_layout.as_ref().map(|l| l.as_ref()) + { + // Note: this stdlib is not used in production, so cloning here is acceptable. + Ok(annotated_struct_layout.clone()) + } else { + Err( PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR).with_message( "Could not convert Type to fully-annotated MoveTypeLayout via NativeContext" .to_string(), ), - ), + ) } } @@ -248,26 +252,30 @@ mod testing { /// Prints any `Value` in a user-friendly manner. pub(crate) fn print_value( - context: &NativeContext, + context: &mut NativeContext, out: &mut String, val: Value, - ty: Type, + ty: &Type, move_std_addr: &AccountAddress, depth: usize, canonicalize: bool, single_line: bool, include_int_types: bool, ) -> PartialVMResult<()> { - // get type layout in VM format - let ty_layout = context.type_to_type_layout(&ty)?; + // Get type layout in VM format. We do not expect to see any delayed fields here because + // this debug implementation is + // 1. Not used in production, instead debug implementation from 0x1::string_utils is used. + // 2. Not called in block-execution context where delayed fields are relevant. + let ty_layout = context.type_to_type_layout_check_no_delayed_fields(ty)?; - match &ty_layout { + match ty_layout.as_ref() { MoveTypeLayout::Vector(_) => { - // get the inner type T of a vector - let inner_ty = get_vector_inner_type(&ty)?; - let inner_tyl = context.type_to_type_layout(inner_ty)?; + // Get the inner type T of a vector. Again, we should not see any delayed fields + // in the debug context. + let inner_ty = get_vector_inner_type(ty)?; + let inner_tyl = context.type_to_type_layout_check_no_delayed_fields(inner_ty)?; - match inner_tyl { + match inner_tyl.as_ref() { // We cannot simply convert a `Value` (of type vector) to a `MoveValue` because // there might be a struct in the vector that needs to be "decorated" using the // logic in this function. Instead, we recursively "unpack" the vector until we @@ -290,7 +298,7 @@ mod testing { context, out, val, - inner_ty.clone(), + inner_ty, move_std_addr, depth, canonicalize, @@ -337,7 +345,7 @@ mod testing { }, }; - let annotated_struct_layout = get_annotated_struct_layout(context, &ty)?; + let annotated_struct_layout = get_annotated_struct_layout(context, ty)?; let decorated_struct = move_struct.decorate(&annotated_struct_layout); print_move_value( @@ -415,6 +423,42 @@ mod testing { write!(out, "u256").map_err(fmt_error_to_partial_vm_error)?; } }, + MoveValue::I8(i8) => { + write!(out, "{}", i8).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i8").map_err(fmt_error_to_partial_vm_error)?; + } + }, + MoveValue::I16(i16) => { + write!(out, "{}", i16).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i16").map_err(fmt_error_to_partial_vm_error)?; + } + }, + MoveValue::I32(i32) => { + write!(out, "{}", i32).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i32").map_err(fmt_error_to_partial_vm_error)?; + } + }, + MoveValue::I64(i64) => { + write!(out, "{}", i64).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i64").map_err(fmt_error_to_partial_vm_error)?; + } + }, + MoveValue::I128(i128) => { + write!(out, "{}", i128).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i128").map_err(fmt_error_to_partial_vm_error)?; + } + }, + MoveValue::I256(i256) => { + write!(out, "{}", i256).map_err(fmt_error_to_partial_vm_error)?; + if include_int_types { + write!(out, "i256").map_err(fmt_error_to_partial_vm_error)?; + } + }, MoveValue::Bool(b) => { // Note that when `include_int_types` is enabled, the boolean `true` and `false` // values unambiguously encode their type, since they are different than any integer @@ -590,7 +634,7 @@ mod testing { single_line: bool, include_int_types: bool, vec: Vec, - print_inner_value: impl Fn( + mut print_inner_value: impl FnMut( &mut String, ValType, &AccountAddress, diff --git a/third_party/move/move-stdlib/src/natives/event.rs b/third_party/move/move-stdlib/src/natives/event.rs index 5ab61c203f8..716b7b52cc6 100644 --- a/third_party/move/move-stdlib/src/natives/event.rs +++ b/third_party/move/move-stdlib/src/natives/event.rs @@ -28,7 +28,7 @@ pub struct WriteToEventStoreGasParameters { fn native_write_to_event_store( gas_params: &WriteToEventStoreGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.len() == 1); diff --git a/third_party/move/move-stdlib/src/natives/hash.rs b/third_party/move/move-stdlib/src/natives/hash.rs index f915fa77cd9..516f6e0eab0 100644 --- a/third_party/move/move-stdlib/src/natives/hash.rs +++ b/third_party/move/move-stdlib/src/natives/hash.rs @@ -31,7 +31,7 @@ pub struct Sha2_256GasParameters { fn native_sha2_256( gas_params: &Sha2_256GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); @@ -77,7 +77,7 @@ pub struct Sha3_256GasParameters { fn native_sha3_256( gas_params: &Sha3_256GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-stdlib/src/natives/signer.rs b/third_party/move/move-stdlib/src/natives/signer.rs index 90c8ccac06b..2f4f513ab14 100644 --- a/third_party/move/move-stdlib/src/natives/signer.rs +++ b/third_party/move/move-stdlib/src/natives/signer.rs @@ -30,7 +30,7 @@ pub struct BorrowAddressGasParameters { fn native_borrow_address( gas_params: &BorrowAddressGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-stdlib/src/natives/string.rs b/third_party/move/move-stdlib/src/natives/string.rs index 24b1074dc07..daea83ce60f 100644 --- a/third_party/move/move-stdlib/src/natives/string.rs +++ b/third_party/move/move-stdlib/src/natives/string.rs @@ -39,7 +39,7 @@ pub struct CheckUtf8GasParameters { fn native_check_utf8( gas_params: &CheckUtf8GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 1); @@ -75,7 +75,7 @@ pub struct IsCharBoundaryGasParameters { fn native_is_char_boundary( gas_params: &IsCharBoundaryGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 2); @@ -112,7 +112,7 @@ pub struct SubStringGasParameters { fn native_sub_string( gas_params: &SubStringGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 3); @@ -160,7 +160,7 @@ pub struct IndexOfGasParameters { fn native_index_of( gas_params: &IndexOfGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 2); diff --git a/third_party/move/move-stdlib/src/natives/type_name.rs b/third_party/move/move-stdlib/src/natives/type_name.rs index 897ea168602..788d9f8215e 100644 --- a/third_party/move/move-stdlib/src/natives/type_name.rs +++ b/third_party/move/move-stdlib/src/natives/type_name.rs @@ -21,7 +21,7 @@ pub struct GetGasParameters { fn native_get( gas_params: &GetGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> PartialVMResult { debug_assert_eq!(ty_args.len(), 1); diff --git a/third_party/move/move-stdlib/src/natives/unit_test.rs b/third_party/move/move-stdlib/src/natives/unit_test.rs index 2408e300193..6b4592edf09 100644 --- a/third_party/move/move-stdlib/src/natives/unit_test.rs +++ b/third_party/move/move-stdlib/src/natives/unit_test.rs @@ -37,16 +37,16 @@ pub struct CreateSignersForTestingGasParameters { fn native_create_signers_for_testing( gas_params: &CreateSignersForTestingGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); debug_assert!(args.len() == 1); let num_signers = pop_arg!(args, u64); - let signers = Value::vector_for_testing_only( + let signers = Value::vector_unchecked( (0..num_signers).map(|i| Value::master_signer(AccountAddress::new(to_le_bytes(i)))), - ); + )?; let cost = gas_params.base_cost + gas_params.unit_cost * NumArgs::new(num_signers); diff --git a/third_party/move/move-stdlib/src/tests.rs b/third_party/move/move-stdlib/src/tests.rs index c89e6392e6d..3bf1ef5534c 100644 --- a/third_party/move/move-stdlib/src/tests.rs +++ b/third_party/move/move-stdlib/src/tests.rs @@ -7,6 +7,17 @@ use std::{cmp::Ordering, path::Path}; use tempfile::tempdir; use walkdir::{DirEntry, WalkDir}; +pub const UB: &str = "UB"; + +fn read_env_var(v: &str) -> String { + std::env::var(v).unwrap_or_else(|_| String::new()) +} + +fn read_bool_env_var(v: &str) -> bool { + let val = read_env_var(v).to_lowercase(); + val.parse::() == Ok(true) || val.parse::() == Ok(1) +} + #[test] fn check_that_docs_are_updated() { let temp_dir = tempdir().unwrap(); @@ -14,11 +25,14 @@ fn check_that_docs_are_updated() { crate::build_stdlib_doc(&temp_dir.path().to_string_lossy()); let res = check_dirs_not_diff(&temp_dir, crate::move_stdlib_docs_full_path()); - assert!( - res.is_ok(), - "Generated docs differ from the ones checked in. {}", - res.unwrap_err() - ) + + if res.is_err() { + assert!( + !read_bool_env_var(UB), + "Generated docs differ from the ones checked in {}. Call this test with env variable UB=1 to regenerate or remove old baseline files.", + res.unwrap_err() + ); + } } #[test] @@ -69,7 +83,11 @@ fn check_dirs_not_diff, B: AsRef>( ) } if a.file_type().is_file() && std::fs::read(a.path())? != std::fs::read(b.path())? { - bail!("{} needs to be updated", display_dir_entry(a)) + if read_bool_env_var(UB) { + std::fs::write(b.path(), std::fs::read(a.path())?).unwrap(); + } else { + bail!("{}", display_dir_entry(b)) + } } } diff --git a/third_party/move/move-stdlib/tests/move_unit_test.rs b/third_party/move/move-stdlib/tests/move_unit_test.rs index 90cb4c985d3..e50e7f1e9df 100644 --- a/third_party/move/move-stdlib/tests/move_unit_test.rs +++ b/third_party/move/move-stdlib/tests/move_unit_test.rs @@ -39,6 +39,7 @@ fn run_tests_for_pkg(path_to_pkg: impl Into, include_nursery_natives: bo /* cost_table */ None, /* compute_coverage */ false, &mut std::io::stdout(), + false, ); if result.is_err() || result.is_ok_and(|r| r == UnitTestResult::Failure) { panic!("aborting because of Move unit test failures") diff --git a/third_party/move/move-symbol-pool/Cargo.toml b/third_party/move/move-symbol-pool/Cargo.toml index 9096856fb24..f21c5666a18 100644 --- a/third_party/move/move-symbol-pool/Cargo.toml +++ b/third_party/move/move-symbol-pool/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] once_cell = { workspace = true } diff --git a/third_party/move/move-vm/integration-tests/Cargo.toml b/third_party/move/move-vm/integration-tests/Cargo.toml index 7f7ab6f0141..2aea1afd7fc 100644 --- a/third_party/move/move-vm/integration-tests/Cargo.toml +++ b/third_party/move/move-vm/integration-tests/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -23,11 +23,12 @@ move-compiler-v2 = { workspace = true } move-core-types = { workspace = true } move-model = { workspace = true } move-stdlib = { path = "../../move-stdlib" } -move-vm-runtime = { workspace = true, features = ["testing"] } +move-vm-runtime = { workspace = true, features = ["disable_verifier_cache", "testing"] } move-vm-test-utils = { workspace = true } move-vm-types = { workspace = true, features = ["testing"] } smallvec = { workspace = true } tempfile = { workspace = true } +test-case = { workspace = true } [features] default = [] diff --git a/third_party/move/move-vm/integration-tests/src/tests/bad_storage_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/bad_storage_tests.rs index 79132966ccb..a7ff4528825 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/bad_storage_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/bad_storage_tests.rs @@ -200,7 +200,7 @@ fn test_malformed_module() { vec![], ) .unwrap_err(); - assert_eq!(err.status_type(), StatusType::InvariantViolation); + assert_eq!(err.major_status(), StatusCode::CODE_DESERIALIZATION_ERROR); } } @@ -319,7 +319,7 @@ fn test_missing_module_dependency() { vec![], ) .unwrap_err(); - assert_eq!(err.status_type(), StatusType::InvariantViolation); + assert_eq!(err.major_status(), StatusCode::LINKER_ERROR); } } @@ -385,7 +385,7 @@ fn test_malformed_module_dependency() { vec![], ) .unwrap_err(); - assert_eq!(err.status_type(), StatusType::InvariantViolation); + assert_eq!(err.major_status(), StatusCode::CODE_DESERIALIZATION_ERROR); } } @@ -452,7 +452,7 @@ fn test_unverifiable_module_dependency() { vec![], ) .unwrap_err(); - assert_eq!(err.status_type(), StatusType::InvariantViolation); + assert_eq!(err.major_status(), StatusCode::UNEXPECTED_VERIFIER_ERROR); } } @@ -537,23 +537,7 @@ fn test_storage_returns_bogus_error_when_loading_module() { vec![], ) .unwrap_err(); - - // TODO(loader_v2): - // Loader V2 remaps all deserialization and verification errors. Loader V1 does not - // remap them when module resolver is accessed, and only on verification steps. - // Strictly speaking, the storage would never return such an error so V2 behaviour is - // ok. Moreover, the fact that V1 still returns UNKNOWN_BINARY_ERROR and does not - // remap it is weird. - if *error_code == StatusCode::UNKNOWN_VERIFICATION_ERROR { - assert_eq!(err.major_status(), StatusCode::UNEXPECTED_VERIFIER_ERROR); - } else if *error_code == StatusCode::UNKNOWN_BINARY_ERROR { - assert_eq!( - err.major_status(), - StatusCode::UNEXPECTED_DESERIALIZATION_ERROR - ); - } else { - assert_eq!(err.major_status(), *error_code); - } + assert_eq!(err.major_status(), *error_code); } } diff --git a/third_party/move/move-vm/integration-tests/src/tests/exec_func_effects_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/exec_func_effects_tests.rs index 546ac382226..b8d9d0a9e86 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/exec_func_effects_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/exec_func_effects_tests.rs @@ -10,8 +10,8 @@ use move_binary_format::errors::VMResult; use move_core_types::{ account_address::AccountAddress, identifier::Identifier, + int256::U256, language_storage::ModuleId, - u256::U256, value::{serialize_values, MoveValue}, vm_status::StatusCode, }; diff --git a/third_party/move/move-vm/integration-tests/src/tests/function_arg_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/function_arg_tests.rs index bc31c38dd6b..87e4b4db365 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/function_arg_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/function_arg_tests.rs @@ -10,8 +10,8 @@ use move_binary_format::errors::VMResult; use move_core_types::{ account_address::AccountAddress, identifier::Identifier, + int256::U256, language_storage::TypeTag, - u256::U256, value::{MoveStruct, MoveValue}, vm_status::StatusCode, }; @@ -220,8 +220,8 @@ fn expected_A_B__A_u32_vector_B_got_u16_u256__u16_u32_vector_u256() { MoveValue::U16(0), MoveValue::U32(0), MoveValue::Vector(vec![ - MoveValue::U256(U256::from(0u8)), - MoveValue::U256(U256::from(0u8)), + MoveValue::U256(U256::ZERO), + MoveValue::U256(U256::ZERO), ]), ], ) diff --git a/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs index 2953ae2cfbd..e9ab30e6505 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs @@ -16,9 +16,14 @@ use move_core_types::{ vm_status::StatusCode, }; use move_vm_runtime::{ - config::VMConfig, AsUnsyncCodeStorage, ModuleStorage, RuntimeEnvironment, StagingModuleStorage, + config::VMConfig, + dispatch_loader, + module_traversal::{TraversalContext, TraversalStorage}, + AsUnsyncCodeStorage, InstantiatedFunctionLoader, LegacyLoaderConfig, ModuleStorage, + RuntimeEnvironment, StagingModuleStorage, }; use move_vm_test_utils::InMemoryStorage; +use move_vm_types::gas::UnmeteredGasMeter; #[test] fn instantiation_err() { @@ -141,7 +146,17 @@ fn instantiation_err() { } fn load_function(module_storage: &impl ModuleStorage, module_id: &ModuleId, ty_args: &[TypeTag]) { - let res = module_storage.load_function(module_id, ident_str!("f"), ty_args); + let traversal_storage = TraversalStorage::new(); + let res = dispatch_loader!(module_storage, loader, { + loader.load_instantiated_function( + &LegacyLoaderConfig::unmetered(), + &mut UnmeteredGasMeter, + &mut TraversalContext::new(&traversal_storage), + module_id, + ident_str!("f"), + ty_args, + ) + }); assert!( res.is_err(), "Instantiation must fail at load time when converting from type tag to type " diff --git a/third_party/move/move-vm/integration-tests/src/tests/invariant_violation_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/invariant_violation_tests.rs deleted file mode 100644 index 4d1d317c4b9..00000000000 --- a/third_party/move/move-vm/integration-tests/src/tests/invariant_violation_tests.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::tests::execute_script_for_test; -use move_binary_format::file_format::{ - Bytecode::*, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, Signature, SignatureIndex, - SignatureToken::*, -}; -use move_core_types::vm_status::StatusCode; -use move_vm_test_utils::InMemoryStorage; - -#[test] -fn merge_borrow_states_infinite_loop() { - let cs = CompiledScript { - version: 6, - module_handles: vec![], - struct_handles: vec![], - function_handles: vec![], - function_instantiations: vec![], - signatures: vec![ - Signature(vec![]), - Signature(vec![ - U64, - Vector(Box::new(U8)), - U64, - Vector(Box::new(U8)), - MutableReference(Box::new(Vector(Box::new(U8)))), - MutableReference(Box::new(U64)), - ]), - ], - identifiers: vec![], - address_identifiers: vec![], - constant_pool: vec![Constant { - type_: Vector(Box::new(U8)), - data: vec![0], - }], - metadata: vec![], - // The bytecode verifier should reject this code but it doesn't. - code: CodeUnit { - locals: SignatureIndex(1), - code: vec![ - LdU64(0), - StLoc(0), // { 0 => 0 } - LdConst(ConstantPoolIndex(0)), - StLoc(1), // { 0 => 0, 1 => [] } - LdU64(0), - StLoc(2), // { 0 => 0, 1 => [], 2 => 0 } - MutBorrowLoc(2), - StLoc(5), // { 0 => 0, 1 => [], 2 => 0, 5 => &2 } - LdU64(1), - CopyLoc(5), - WriteRef, // { 0 => 0, 1 => [], 2 => 1, 5 => &2 } - LdConst(ConstantPoolIndex(0)), - StLoc(3), // { 0 => 0, 1 => [], 2 => 1, 3 => [], 5 => &2 } - MutBorrowLoc(3), - StLoc(4), // { 0 => 0, 1 => [], 2 => 1, 3 => [], 4 => &3, 5 => &2 } - LdConst(ConstantPoolIndex(0)), - CopyLoc(4), - WriteRef, - CopyLoc(5), - ReadRef, - LdU64(1), - Eq, - BrTrue(11), - Ret, - ], - }, - type_parameters: vec![], - parameters: SignatureIndex(0), - access_specifiers: None, - }; - - move_bytecode_verifier::verify_script(&cs).expect("verify failed"); - - let mut script_bytes = vec![]; - cs.serialize(&mut script_bytes).unwrap(); - - let storage = InMemoryStorage::new(); - let status = execute_script_for_test(&storage, &script_bytes, &[], vec![]) - .unwrap_err() - .major_status(); - assert_eq!(status, StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR); -} diff --git a/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs index 99b809dde10..4bbc9630edd 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs @@ -15,8 +15,14 @@ use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, ident_str, identifier::Identifier, language_storage::ModuleId, }; -use move_vm_runtime::{AsUnsyncModuleStorage, ModuleStorage, StagingModuleStorage}; +use move_vm_runtime::{ + dispatch_loader, + module_traversal::{TraversalContext, TraversalStorage}, + AsUnsyncModuleStorage, InstantiatedFunctionLoader, LegacyLoaderConfig, ModuleStorage, + StagingModuleStorage, +}; use move_vm_test_utils::InMemoryStorage; +use move_vm_types::gas::UnmeteredGasMeter; use std::path::PathBuf; const WORKING_ACCOUNT: AccountAddress = AccountAddress::TWO; @@ -151,9 +157,19 @@ fn load_phantom_module() { let module_storage = InMemoryStorage::new().into_unsync_module_storage(); let new_module_storage = adapter.publish_modules_using_loader_v2(&module_storage, modules); - let _ = new_module_storage - .load_function(&module_id, ident_str!("foo"), &[]) - .unwrap(); + let traversal_storage = TraversalStorage::new(); + dispatch_loader!(&new_module_storage, loader, { + loader + .load_instantiated_function( + &LegacyLoaderConfig::unmetered(), + &mut UnmeteredGasMeter, + &mut TraversalContext::new(&traversal_storage), + &module_id, + ident_str!("foo"), + &[], + ) + .unwrap(); + }); } #[test] @@ -211,9 +227,19 @@ fn load_with_extra_ability() { let module_storage = InMemoryStorage::new().into_unsync_module_storage(); let new_module_storage = adapter.publish_modules_using_loader_v2(&module_storage, modules); - let _ = new_module_storage - .load_function(&module_id, ident_str!("foo"), &[]) - .unwrap(); + let traversal_storage = TraversalStorage::new(); + dispatch_loader!(&new_module_storage, loader, { + loader + .load_instantiated_function( + &LegacyLoaderConfig::unmetered(), + &mut UnmeteredGasMeter, + &mut TraversalContext::new(&traversal_storage), + &module_id, + ident_str!("foo"), + &[], + ) + .unwrap(); + }); } #[test] diff --git a/third_party/move/move-vm/integration-tests/src/tests/mod.rs b/third_party/move/move-vm/integration-tests/src/tests/mod.rs index 0887d9bb861..a313bff884a 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/mod.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/mod.rs @@ -2,6 +2,7 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 +use crate::compiler::{as_module, compile_units}; use move_binary_format::errors::{Location, VMResult}; use move_core_types::{ effects::ChangeSet, @@ -9,11 +10,13 @@ use move_core_types::{ language_storage::{ModuleId, TypeTag}, }; use move_vm_runtime::{ - data_cache::TransactionDataCache, + data_cache::{MoveVmDataCacheAdapter, TransactionDataCache}, + dispatch_loader, module_traversal::{TraversalContext, TraversalStorage}, move_vm::{MoveVM, SerializedReturnValues}, native_extensions::NativeContextExtensions, - AsUnsyncCodeStorage, AsUnsyncModuleStorage, CodeStorage, ModuleStorage, + AsUnsyncCodeStorage, AsUnsyncModuleStorage, InstantiatedFunctionLoader, LegacyLoaderConfig, + ModuleStorage, ScriptLoader, }; use move_vm_test_utils::InMemoryStorage; use move_vm_types::{gas::UnmeteredGasMeter, resolver::ResourceResolver}; @@ -24,7 +27,6 @@ mod binary_format_version; mod exec_func_effects_tests; mod function_arg_tests; mod instantiation_tests; -mod invariant_violation_tests; mod leak_tests; mod loader_tests; mod module_storage_tests; @@ -35,6 +37,15 @@ mod return_value_tests; mod runtime_reentrancy_check_tests; mod vm_arguments_tests; +/// Given code string, compiles it, serializes and adds to storage. +fn compile_and_publish(storage: &mut InMemoryStorage, code: String) { + let mut units = compile_units(&code).unwrap(); + let m = as_module(units.pop().unwrap()); + let mut blob = vec![]; + m.serialize(&mut blob).unwrap(); + storage.add_module_bytes(m.self_addr(), m.self_name(), blob.into()); +} + /// Executes a Move script on top of the provided storage state, with the given arguments and type /// arguments. fn execute_script_for_test( @@ -88,19 +99,31 @@ fn execute_function_for_test( ty_args: &[TypeTag], args: Vec>, ) -> VMResult { + let mut data_cache = TransactionDataCache::empty(); + + let mut gas_meter = UnmeteredGasMeter; let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); - let func = module_storage.load_function(module_id, function_name, ty_args)?; - MoveVM::execute_loaded_function( - func, - args, - &mut TransactionDataCache::empty(), - &mut UnmeteredGasMeter, - &mut TraversalContext::new(&traversal_storage), - &mut NativeContextExtensions::default(), - module_storage, - data_storage, - ) + dispatch_loader!(module_storage, loader, { + let func = loader.load_instantiated_function( + &LegacyLoaderConfig::unmetered(), + &mut gas_meter, + &mut traversal_context, + module_id, + function_name, + ty_args, + )?; + MoveVM::execute_loaded_function( + func, + args, + &mut MoveVmDataCacheAdapter::new(&mut data_cache, data_storage, &loader), + &mut gas_meter, + &mut traversal_context, + &mut NativeContextExtensions::default(), + &loader, + ) + }) } fn execute_script_impl( @@ -110,21 +133,32 @@ fn execute_script_impl( args: Vec>, ) -> VMResult { let code_storage = storage.as_unsync_code_storage(); + + let mut gas_meter = UnmeteredGasMeter; let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); - let function = code_storage.load_script(script, ty_args)?; let mut data_cache = TransactionDataCache::empty(); - MoveVM::execute_loaded_function( - function, - args, - &mut data_cache, - &mut UnmeteredGasMeter, - &mut TraversalContext::new(&traversal_storage), - &mut NativeContextExtensions::default(), - &code_storage, - storage, - )?; + dispatch_loader!(&code_storage, loader, { + let function = loader.load_script( + &LegacyLoaderConfig::unmetered(), + &mut gas_meter, + &mut traversal_context, + script, + ty_args, + )?; + MoveVM::execute_loaded_function( + function, + args, + &mut MoveVmDataCacheAdapter::new(&mut data_cache, storage, &loader), + &mut gas_meter, + &mut traversal_context, + &mut NativeContextExtensions::default(), + &loader, + ) + })?; + let change_set = data_cache .into_effects(&code_storage) .map_err(|err| err.finish(Location::Undefined))?; diff --git a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs index 00424243732..0b72bb43699 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs @@ -12,9 +12,26 @@ use move_core_types::{ account_address::AccountAddress, ident_str, identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode, }; -use move_vm_runtime::{AsUnsyncCodeStorage, AsUnsyncModuleStorage, CodeStorage, ModuleStorage}; +use move_vm_runtime::{ + config::VMConfig, + dispatch_loader, + module_traversal::{TraversalContext, TraversalStorage}, + AsUnsyncCodeStorage, AsUnsyncModuleStorage, LegacyLoaderConfig, ModuleStorage, + RuntimeEnvironment, ScriptLoader, StructDefinitionLoader, +}; use move_vm_test_utils::InMemoryStorage; -use move_vm_types::sha3_256; +use move_vm_types::{gas::UnmeteredGasMeter, sha3_256}; +use test_case::test_case; + +fn in_memory_storage(enable_lazy_loading: bool) -> InMemoryStorage { + InMemoryStorage::new_with_runtime_environment(RuntimeEnvironment::new_with_config( + vec![], + VMConfig { + enable_lazy_loading, + ..VMConfig::default() + }, + )) +} fn make_module<'a>( module_name: &'a str, @@ -53,19 +70,19 @@ fn add_module_bytes<'a>( fn test_module_does_not_exist() { let module_storage = InMemoryStorage::new().into_unsync_module_storage(); - let result = module_storage.check_module_exists(&AccountAddress::ZERO, ident_str!("a")); + let result = + module_storage.unmetered_check_module_exists(&AccountAddress::ZERO, ident_str!("a")); assert!(!assert_ok!(result)); - let result = module_storage.fetch_module_size_in_bytes(&AccountAddress::ZERO, ident_str!("a")); + let result = module_storage.unmetered_get_module_size(&AccountAddress::ZERO, ident_str!("a")); assert_none!(assert_ok!(result)); - let result = module_storage.fetch_module_metadata(&AccountAddress::ZERO, ident_str!("a")); + let result = + module_storage.unmetered_get_deserialized_module(&AccountAddress::ZERO, ident_str!("a")); assert_none!(assert_ok!(result)); - let result = module_storage.fetch_deserialized_module(&AccountAddress::ZERO, ident_str!("a")); - assert_none!(assert_ok!(result)); - - let result = module_storage.fetch_verified_module(&AccountAddress::ZERO, ident_str!("a")); + let result = module_storage + .unmetered_get_eagerly_verified_module(&AccountAddress::ZERO, ident_str!("a")); assert_none!(assert_ok!(result)); } @@ -78,7 +95,7 @@ fn test_module_exists() { let module_storage = module_bytes_storage.into_unsync_module_storage(); assert!(assert_ok!( - module_storage.check_module_exists(id.address(), id.name()) + module_storage.unmetered_check_module_exists(id.address(), id.name()) )); module_storage.assert_cached_state(vec![&id], vec![]); } @@ -98,20 +115,21 @@ fn test_deserialized_caching() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - let result = module_storage.fetch_module_metadata(a_id.address(), a_id.name()); - let expected = make_module("a", vec!["b", "c"], vec![]).0.metadata; - assert_eq!(assert_some!(assert_ok!(result)), expected); + let result = module_storage.unmetered_get_deserialized_module(a_id.address(), a_id.name()); + let expected = make_module("a", vec!["b", "c"], vec![]).0; + assert_eq!(assert_some!(assert_ok!(result)).as_ref(), &expected); module_storage.assert_cached_state(vec![&a_id], vec![]); - let result = module_storage.fetch_deserialized_module(c_id.address(), c_id.name()); + let result = module_storage.unmetered_get_deserialized_module(c_id.address(), c_id.name()); let expected = make_module("c", vec!["d", "e"], vec![]).0; assert_eq!(assert_some!(assert_ok!(result)).as_ref(), &expected); module_storage.assert_cached_state(vec![&a_id, &c_id], vec![]); } -#[test] -fn test_dependency_tree_traversal() { - let mut module_bytes_storage = InMemoryStorage::new(); +#[test_case(true)] +#[test_case(false)] +fn test_dependency_tree_traversal(enable_lazy_loading: bool) { + let mut module_bytes_storage = in_memory_storage(enable_lazy_loading); let a_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("a").unwrap()); let b_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("b").unwrap()); @@ -127,18 +145,29 @@ fn test_dependency_tree_traversal() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - assert_ok!(module_storage.fetch_verified_module(c_id.address(), c_id.name())); - module_storage.assert_cached_state(vec![], vec![&c_id, &d_id, &e_id]); - - assert_ok!(module_storage.fetch_verified_module(a_id.address(), a_id.name())); - module_storage.assert_cached_state(vec![], vec![&a_id, &b_id, &c_id, &d_id, &e_id]); - - assert_ok!(module_storage.fetch_verified_module(a_id.address(), a_id.name())); + if enable_lazy_loading { + assert_ok!(module_storage.unmetered_get_lazily_verified_module(&c_id)); + module_storage.assert_cached_state(vec![], vec![&c_id]); + + assert_ok!(module_storage.unmetered_get_lazily_verified_module(&a_id)); + module_storage.assert_cached_state(vec![], vec![&a_id, &c_id]); + } else { + assert_ok!( + module_storage.unmetered_get_eagerly_verified_module(c_id.address(), c_id.name()) + ); + module_storage.assert_cached_state(vec![], vec![&c_id, &d_id, &e_id]); + + assert_ok!( + module_storage.unmetered_get_eagerly_verified_module(a_id.address(), a_id.name()) + ); + module_storage.assert_cached_state(vec![], vec![&a_id, &b_id, &c_id, &d_id, &e_id]); + } } -#[test] -fn test_dependency_dag_traversal() { - let mut module_bytes_storage = InMemoryStorage::new(); +#[test_case(true)] +#[test_case(false)] +fn test_dependency_dag_traversal(enable_lazy_loading: bool) { + let mut module_bytes_storage = in_memory_storage(enable_lazy_loading); let a_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("a").unwrap()); let b_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("b").unwrap()); @@ -158,22 +187,35 @@ fn test_dependency_dag_traversal() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - assert_ok!(module_storage.fetch_deserialized_module(a_id.address(), a_id.name())); - assert_ok!(module_storage.fetch_deserialized_module(c_id.address(), c_id.name())); + assert_ok!(module_storage.unmetered_get_deserialized_module(a_id.address(), a_id.name())); + assert_ok!(module_storage.unmetered_get_deserialized_module(c_id.address(), c_id.name())); module_storage.assert_cached_state(vec![&a_id, &c_id], vec![]); - assert_ok!(module_storage.fetch_verified_module(d_id.address(), d_id.name())); - module_storage.assert_cached_state(vec![&a_id, &c_id], vec![&d_id, &e_id, &f_id, &g_id]); - - assert_ok!(module_storage.fetch_verified_module(a_id.address(), a_id.name())); - module_storage.assert_cached_state(vec![], vec![ - &a_id, &b_id, &c_id, &d_id, &e_id, &f_id, &g_id, - ]); + if enable_lazy_loading { + assert_ok!(module_storage.unmetered_get_lazily_verified_module(&d_id)); + module_storage.assert_cached_state(vec![&a_id, &c_id], vec![&d_id]); + + assert_ok!(module_storage.unmetered_get_lazily_verified_module(&a_id)); + module_storage.assert_cached_state(vec![&c_id], vec![&a_id, &d_id]); + } else { + assert_ok!( + module_storage.unmetered_get_eagerly_verified_module(d_id.address(), d_id.name()) + ); + module_storage.assert_cached_state(vec![&a_id, &c_id], vec![&d_id, &e_id, &f_id, &g_id]); + + assert_ok!( + module_storage.unmetered_get_eagerly_verified_module(a_id.address(), a_id.name()) + ); + module_storage.assert_cached_state(vec![], vec![ + &a_id, &b_id, &c_id, &d_id, &e_id, &f_id, &g_id, + ]); + } } -#[test] -fn test_cyclic_dependencies_traversal_fails() { - let mut module_bytes_storage = InMemoryStorage::new(); +#[test_case(true)] +#[test_case(false)] +fn test_cyclic_dependencies(enable_lazy_loading: bool) { + let mut module_bytes_storage = in_memory_storage(enable_lazy_loading); let c_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("c").unwrap()); @@ -183,11 +225,18 @@ fn test_cyclic_dependencies_traversal_fails() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - let result = module_storage.fetch_verified_module(c_id.address(), c_id.name()); - assert_eq!( - assert_err!(result).major_status(), - StatusCode::CYCLIC_MODULE_DEPENDENCY - ); + if enable_lazy_loading { + // With lazy loading, cyclic dependencies are allowed to be published (but not called). + assert_ok!(module_storage.unmetered_get_lazily_verified_module(&c_id)); + module_storage.assert_cached_state(vec![], vec![&c_id]); + } else { + let result = + module_storage.unmetered_get_eagerly_verified_module(c_id.address(), c_id.name()); + assert_eq!( + assert_err!(result).major_status(), + StatusCode::CYCLIC_MODULE_DEPENDENCY + ); + } } #[test] @@ -202,7 +251,7 @@ fn test_cyclic_friends_are_allowed() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - let result = module_storage.fetch_verified_module(c_id.address(), c_id.name()); + let result = module_storage.unmetered_get_eagerly_verified_module(c_id.address(), c_id.name()); assert_ok!(result); // Since `c` has no dependencies, only it gets deserialized and verified. @@ -224,59 +273,51 @@ fn test_transitive_friends_are_allowed_to_be_transitive_dependencies() { let module_storage = module_bytes_storage.into_unsync_module_storage(); - assert_ok!(module_storage.fetch_verified_module(a_id.address(), a_id.name())); + assert_ok!(module_storage.unmetered_get_eagerly_verified_module(a_id.address(), a_id.name())); module_storage.assert_cached_state(vec![], vec![&a_id, &b_id, &c_id]); } -#[test] -fn test_deserialized_script_caching() { - let mut module_bytes_storage = InMemoryStorage::new(); - add_module_bytes(&mut module_bytes_storage, "a", vec!["b", "c"], vec![]); - add_module_bytes(&mut module_bytes_storage, "b", vec![], vec![]); - add_module_bytes(&mut module_bytes_storage, "c", vec![], vec![]); - - let code_storage = module_bytes_storage.into_unsync_code_storage(); - - let serialized_script = make_script(vec!["a"]); - let hash_1 = sha3_256(&serialized_script); - assert_ok!(code_storage.deserialize_and_cache_script(&serialized_script)); - - let serialized_script = make_script(vec!["b"]); - let hash_2 = sha3_256(&serialized_script); - assert_ok!(code_storage.deserialize_and_cache_script(&serialized_script)); - - code_storage.assert_cached_state(vec![&hash_1, &hash_2], vec![]); -} - -#[test] -fn test_verified_script_caching() { - let mut module_bytes_storage = InMemoryStorage::new(); +#[test_case(true)] +#[test_case(false)] +fn test_load_script(enable_lazy_loading: bool) { + let mut module_bytes_storage = in_memory_storage(enable_lazy_loading); let a_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("a").unwrap()); let b_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("b").unwrap()); let c_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("c").unwrap()); + let d_id = ModuleId::new(AccountAddress::ZERO, Identifier::new("d").unwrap()); add_module_bytes(&mut module_bytes_storage, "a", vec!["b", "c"], vec![]); add_module_bytes(&mut module_bytes_storage, "b", vec![], vec![]); - add_module_bytes(&mut module_bytes_storage, "c", vec![], vec![]); + add_module_bytes(&mut module_bytes_storage, "c", vec!["d"], vec![]); + add_module_bytes(&mut module_bytes_storage, "d", vec![], vec![]); let code_storage = module_bytes_storage.into_unsync_code_storage(); let serialized_script = make_script(vec!["a"]); let hash = sha3_256(&serialized_script); - assert_ok!(code_storage.deserialize_and_cache_script(&serialized_script)); - - // Nothing gets loaded into module cache. - code_storage - .module_storage() - .assert_cached_state(vec![], vec![]); - code_storage.assert_cached_state(vec![&hash], vec![]); - - assert_ok!(code_storage.verify_and_cache_script(&serialized_script)); - // Script is verified, so its dependencies are loaded into cache. - code_storage - .module_storage() - .assert_cached_state(vec![], vec![&a_id, &b_id, &c_id]); - code_storage.assert_cached_state(vec![], vec![&hash]); + dispatch_loader!(&code_storage, loader, { + let traversal_storage = TraversalStorage::new(); + assert_ok!(loader.load_script( + &LegacyLoaderConfig::unmetered(), + &mut UnmeteredGasMeter, + &mut TraversalContext::new(&traversal_storage), + &serialized_script, + &[], + )); + + code_storage.assert_cached_state(vec![], vec![&hash]); + if loader.is_lazy_loading_enabled() { + // For lazy loading, we load only immediate dependencies. + code_storage + .module_storage() + .assert_cached_state(vec![], vec![&a_id]); + } else { + // Without lazy loading, we load the whole transitive closure of dependencies. + code_storage + .module_storage() + .assert_cached_state(vec![], vec![&a_id, &b_id, &c_id, &d_id]); + } + }); } diff --git a/third_party/move/move-vm/integration-tests/src/tests/native_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/native_tests.rs index 11371161dfd..bb7e299ff7a 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/native_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/native_tests.rs @@ -1,20 +1,23 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ - compiler::{as_module, compile_units}, - tests::execute_function_for_test, +use crate::tests::{compile_and_publish, execute_function_for_test}; +use claims::assert_ok; +use move_binary_format::{ + errors::PartialVMResult, file_format::empty_module_with_dependencies_and_friends_at_addr, + CompiledModule, }; -use move_binary_format::errors::PartialVMResult; use move_core_types::{ account_address::AccountAddress, gas_algebra::InternalGas, ident_str, identifier::Identifier, + language_storage::ModuleId, }; use move_vm_runtime::{ - native_functions::NativeFunction, AsUnsyncCodeStorage, RuntimeEnvironment, StagingModuleStorage, + config::VMConfig, native_functions::NativeFunction, AsUnsyncCodeStorage, RuntimeEnvironment, }; use move_vm_test_utils::InMemoryStorage; use move_vm_types::natives::function::NativeResult; use std::sync::Arc; +use test_case::test_case; const TEST_ADDR: AccountAddress = AccountAddress::new([42; AccountAddress::LENGTH]); @@ -29,65 +32,127 @@ fn make_failed_native() -> NativeFunction { #[test] fn test_failed_native() { - let code = r#" - module {{ADDR}}::M { - fun foo() { - Self::bar(); - } + let module_id = ModuleId::new(TEST_ADDR, Identifier::new("M").unwrap()); + let natives = vec![( + TEST_ADDR, + Identifier::new("M").unwrap(), + Identifier::new("bar").unwrap(), + make_failed_native(), + )]; - fun foo2() { - Self::foo1(); - } + let runtime_environment = RuntimeEnvironment::new(natives); + let mut storage = InMemoryStorage::new_with_runtime_environment(runtime_environment); - fun foo1() { - Self::bar(); - } + let code = format!( + r#" + module 0x{0}::M {{ + fun foo() {{ Self::bar(); }} + fun foo1() {{ Self::bar(); }} + fun foo2() {{ Self::foo1(); }} native fun bar(); - } - "#; - let code = code.replace("{{ADDR}}", &format!("0x{}", TEST_ADDR.to_hex())); - let mut units = compile_units(&code).unwrap(); - - let m = as_module(units.pop().unwrap()); - let mut m_blob = vec![]; - m.serialize(&mut m_blob).unwrap(); - - { - let natives = vec![( - TEST_ADDR, - Identifier::new("M").unwrap(), - Identifier::new("bar").unwrap(), - make_failed_native(), - )]; - let runtime_environment = RuntimeEnvironment::new(natives); - let storage = InMemoryStorage::new_with_runtime_environment(runtime_environment); - - let module_storage = storage.as_unsync_code_storage(); - let new_module_storage = - StagingModuleStorage::create(&TEST_ADDR, &module_storage, vec![m_blob.clone().into()]) - .expect("Module should be publishable"); - - let err = execute_function_for_test( - &storage, - &new_module_storage, - &m.self_id(), - ident_str!("foo"), - &[], - vec![], - ) - .unwrap_err(); - assert!(err.exec_state().unwrap().stack_trace().is_empty()); - - let err = execute_function_for_test( - &storage, - &new_module_storage, - &m.self_id(), - ident_str!("foo2"), - &[], - vec![], - ) - .unwrap_err(); - assert_eq!(err.exec_state().unwrap().stack_trace().len(), 1); + }} + "#, + TEST_ADDR.to_hex(), + ); + compile_and_publish(&mut storage, code); + let module_storage = storage.as_unsync_code_storage(); + + let err = execute_function_for_test( + &storage, + &module_storage, + &module_id, + ident_str!("foo"), + &[], + vec![], + ) + .unwrap_err(); + assert!(err.exec_state().unwrap().stack_trace().is_empty()); + + let err = execute_function_for_test( + &storage, + &module_storage, + &module_id, + ident_str!("foo2"), + &[], + vec![], + ) + .unwrap_err(); + assert_eq!(err.exec_state().unwrap().stack_trace().len(), 1); +} + +fn make_load_module_b() -> NativeFunction { + Arc::new(move |_, _, _| -> PartialVMResult { + Ok(NativeResult::LoadModule { + module_name: ModuleId::new(TEST_ADDR, ident_str!("b").to_owned()), + }) + }) +} + +#[test_case(true)] +#[test_case(false)] +fn test_load_module_native_result(enable_lazy_loading: bool) { + let a_id = ModuleId::new(TEST_ADDR, ident_str!("a").to_owned()); + let natives = vec![( + TEST_ADDR, + ident_str!("a").to_owned(), + ident_str!("load_module_b").to_owned(), + make_load_module_b(), + )]; + let runtime_environment = RuntimeEnvironment::new_with_config(natives, VMConfig { + enable_lazy_loading, + ..VMConfig::default() + }); + let mut storage = InMemoryStorage::new_with_runtime_environment(runtime_environment); + + let code_a = format!( + r#" + module 0x{0}::a {{ + fun foo() {{ load_module_b(); }} + native fun load_module_b(); + }} + "#, + TEST_ADDR.to_hex(), + ); + compile_and_publish(&mut storage, code_a); + + let mut add_module = |m: CompiledModule| { + let mut blob = vec![]; + m.serialize(&mut blob).unwrap(); + storage.add_module_bytes(m.self_addr(), m.self_name(), blob.into()); + m.self_id() + }; + + let b = empty_module_with_dependencies_and_friends_at_addr(TEST_ADDR, "b", vec!["c"], vec![]); + let c = empty_module_with_dependencies_and_friends_at_addr(TEST_ADDR, "c", vec!["d"], vec![]); + let d = empty_module_with_dependencies_and_friends_at_addr(TEST_ADDR, "d", vec![], vec![]); + + let b_id = add_module(b); + let c_id = add_module(c); + let d_id = add_module(d); + + let code_storage = storage.as_unsync_code_storage(); + assert_ok!(execute_function_for_test( + &storage, + &code_storage, + &a_id, + ident_str!("foo"), + &[], + vec![], + )); + + // Here we assert that the state of the cache contains specified modules. For lazy loading, + // only loaded modules is deserialized for charging and cached. For eager loading, the + // transitive closure is deserialized and cached for charging. The modules are not verified + // because verification happens when other natives is called to load a function from the module + // (here, "b"). + if enable_lazy_loading { + code_storage + .module_storage() + .assert_cached_state(vec![&b_id], vec![&a_id]); + } else { + code_storage + .module_storage() + .assert_cached_state(vec![&b_id, &c_id, &d_id], vec![&a_id]); } } diff --git a/third_party/move/move-vm/integration-tests/src/tests/regression_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/regression_tests.rs index d19b87b07b9..bffbff9287d 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/regression_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/regression_tests.rs @@ -26,7 +26,7 @@ fn get_nested_struct_type( ) -> TypeTag { let mut ret = TypeTag::Bool; for _ in 0..depth { - let type_args = std::iter::repeat(ret).take(num_type_args).collect(); + let type_args = std::iter::repeat_n(ret, num_type_args).collect(); ret = TypeTag::Struct(Box::new(StructTag { address: module_address, module: module_identifier.clone(), diff --git a/third_party/move/move-vm/integration-tests/src/tests/runtime_reentrancy_check_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/runtime_reentrancy_check_tests.rs index b36190d3261..efc5512deab 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/runtime_reentrancy_check_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/runtime_reentrancy_check_tests.rs @@ -2,10 +2,7 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ - compiler::{as_module, compile_units}, - tests::execute_function_with_single_storage_for_test, -}; +use crate::tests::{compile_and_publish, execute_function_with_single_storage_for_test}; use claims::assert_ok; use move_binary_format::errors::PartialVMResult; use move_core_types::{ @@ -64,14 +61,6 @@ fn make_dispatch_d_native() -> NativeFunction { }) } -fn compile_and_publish(storage: &mut InMemoryStorage, code: String) { - let mut units = compile_units(&code).unwrap(); - let m = as_module(units.pop().unwrap()); - let mut blob = vec![]; - m.serialize(&mut blob).unwrap(); - storage.add_module_bytes(m.self_addr(), m.self_name(), blob.into()); -} - #[test] fn runtime_reentrancy_check() { let natives = vec![ @@ -197,5 +186,5 @@ fn runtime_reentrancy_check() { ) .unwrap_err() .major_status(); - assert_eq!(status, StatusCode::FUNCTION_RESOLUTION_FAILURE); + assert_eq!(status, StatusCode::LINKER_ERROR); } diff --git a/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs index ac177eb79b8..19dfac8bc27 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs @@ -18,8 +18,8 @@ use move_core_types::{ account_address::AccountAddress, ident_str, identifier::Identifier, + int256, language_storage::TypeTag, - u256::U256, value::{serialize_values, MoveValue}, vm_status::{StatusCode, StatusType}, }; @@ -368,7 +368,7 @@ fn good_signatures_and_arguments() -> Vec<(Signature, Vec)> { )]), // U256 arg (Signature(vec![SignatureToken::U256]), vec![ - MoveValue::U256(U256::zero()), + MoveValue::U256(int256::U256::ZERO), ]), // All constants ( diff --git a/third_party/move/move-vm/metrics/src/lib.rs b/third_party/move/move-vm/metrics/src/lib.rs index bc9c62ad29d..8e0b1b7492d 100644 --- a/third_party/move/move-vm/metrics/src/lib.rs +++ b/third_party/move/move-vm/metrics/src/lib.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use once_cell::sync::Lazy; -use prometheus::{register_histogram_vec, HistogramTimer, HistogramVec}; +use prometheus::{ + register_histogram_vec, register_int_gauge, HistogramTimer, HistogramVec, IntGauge, +}; /// Helper trait to encapsulate [HistogramVec] functionality. Users can use this trait to time /// different VM parts collecting metrics for different labels. Use wisely as timers do introduce @@ -13,6 +15,7 @@ pub trait Timer { } impl Timer for HistogramVec { + #[inline] fn timer_with_label(&self, label: &str) -> HistogramTimer { self.with_label_values(&[label]).start_timer() } @@ -44,3 +47,11 @@ pub static VM_TIMER: Lazy = Lazy::new(|| { ) .expect("Registering the histogram should always succeed") }); + +pub static VERIFIED_MODULE_CACHE_SIZE: Lazy = Lazy::new(|| { + register_int_gauge!( + "verified_module_cache_size", + "Number of modules stored in verified module cache" + ) + .expect("Registering the counter should always succeed") +}); diff --git a/third_party/move/move-vm/profiler/Cargo.toml b/third_party/move/move-vm/profiler/Cargo.toml new file mode 100644 index 00000000000..c19263d2b1d --- /dev/null +++ b/third_party/move/move-vm/profiler/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "move-vm-profiler" +version = "0.1.0" + +# Workspace inherited keys +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +move-vm-types = { workspace = true } +once_cell = { workspace = true } +usdt = { workspace = true, optional = true } + +[features] +default = [] +probe-profiler = ["dep:usdt"] diff --git a/third_party/move/move-vm/profiler/README.md b/third_party/move/move-vm/profiler/README.md new file mode 100644 index 00000000000..d7e8276e2da --- /dev/null +++ b/third_party/move/move-vm/profiler/README.md @@ -0,0 +1,24 @@ +# VM Profiler + +This is a lightweight Rust profiling utility for instrumenting function and instruction execution inside the Move VM. +It provides per-function and per-instruction timing via RAII guards +and the [usdt](https://docs.rs/usdt) crate. + +--- + +## Usage + +To use this profiler, build a binary with the `probe-profiler` feature enabled, and attach an external tracing tool +(e.g. `dtrace` on macOS or `bpftrace` on Linux). + +Example using **DTrace**: + +```bash +sudo dtrace -s -c +``` + +To generate a flamegraph, use the provided script with an appropriate binary: +```bash +./profile.sh +``` +Note that this requires that you have `flamegraph.pl` installed locally, and depends on the `fold.awk` and `trace.d` scripts, which must be kept in the same directory. \ No newline at end of file diff --git a/third_party/move/move-vm/profiler/flame.svg b/third_party/move/move-vm/profiler/flame.svg new file mode 100644 index 00000000000..797a29989c4 --- /dev/null +++ b/third_party/move/move-vm/profiler/flame.svg @@ -0,0 +1,3558 @@ + + + + + + + + + + + + + + +Flame Graph + +Reset Zoom +Search + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::fungible_asset_example::init_module (5,385,835 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::check_code_publishing_permission (24,057,635 samples, 0.04%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::liquidity_pool::init_module (6,298,041 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_numbered_ambassador_token_by_user (907,196,128 samples, 1.64%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::fungible_asset_example::init_module (4,708,464 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_sanity_check (27,319,727 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (9,206,719 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,141,547 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_capacity_above (8,563,283 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,908,031 samples, 0.03%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::create_pool (70,968,046 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (7,947,048 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::add (746,678,581 samples, 1.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::destroy_permissioned_handle (154,545,866 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::create_collection_address (27,461,935 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::generate_mutator_ref (10,264,400 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::replace_key_inplace (124,548,699 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (10,303,780 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (4,867,164 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,529,956 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::transfer (199,161,568 samples, 0.36%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (16,975,650 samples, 0.03%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::fungible_asset_example::init_module (4,952,036 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (2,240,651,019 samples, 4.05%) +0x00.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (295,507,034 samples, 0.53%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::new (5,147,555 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (125,028,282 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::mint_internal (8,357,635 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (32,147,886 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (24,922,018 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_borrow (13,902,462 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (22,773,484 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::register (64,283,169 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,980,796 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (582,813,685 samples, 1.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow (242,673,256 samples, 0.44%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (113,652,043 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::create_signer::create_signer (14,358,876 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,757,500 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (47,474,626 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_dynamic_size_and_init_max_degrees (7,743,297 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validators_with_commission (53,324,084 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (61,410,627 samples, 0.11%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::fungible_asset_example::init_module (5,251,337 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (32,963,659 samples, 0.06%) + + + +0x8753bfb0c0ce026233b9645f580351e44ca7672d5296143cebbd2f4f7746490b::coin_example::init_module (16,347,164 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (154,794,275 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_with_parallelizable_supply (17,625,417 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,825,167 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,242,868 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::mint_token (430,546,122 samples, 0.78%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (1,297,754,260 samples, 2.34%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,273,661 samples, 0.01%) + + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::fungible_asset_example::init_module (4,988,998 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (7,260,059 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (30,454,021 samples, 0.06%) + + + +0x59751998dc73e3ce112b95b971392fb5d8d52f2ddedb0e5c974f76d6841c8690::maps_example::test_add_remove_ordered_map (1,557,490,535 samples, 2.81%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,174,709 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::split_one_bucket (24,641,476 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::find (384,748,198 samples, 0.70%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (6,584,502 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,583,248 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (24,212,052 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::utf8 (10,255,908 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::assert_collection_exists (17,949,170 samples, 0.03%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::resource_groups_example::set (18,116,699 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (45,378,993 samples, 0.08%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::coin_example::init_module (16,309,460 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::symbol (6,200,957 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,580,087 samples, 0.01%) + + + +0xe7de0ac63e1bdaadb9400daa013a754bbdd16faa7de47cfca3f2ef6bb5d893fe::permissioned_transfer::transfer_permissioned (1,368,156,379 samples, 2.47%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::increment_sequence_number (7,546,584 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (10,153,208 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (13,408,495 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,395,713 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (7,803,405 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (9,124,170 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_link (19,623,309 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (4,706,375 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (22,049,959 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,680,793 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_sanity_check (14,028,749 samples, 0.03%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::coin_example::init_module (18,251,709 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (5,154,125 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (24,594,530 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize_validator (8,466,253 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (40,535,663 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (7,928,241 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,172,349 samples, 0.01%) + + + +0x8753bfb0c0ce026233b9645f580351e44ca7672d5296143cebbd2f4f7746490b::objects::create_objects (688,256,458 samples, 1.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,717,332 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::store_exists (5,860,581 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (44,167,456 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::mint (14,751,966 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (4,710,834 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (17,694,496 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (11,673,692 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::is_empty (7,897,351 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (41,452,333 samples, 0.07%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::coin_example::init_module (17,443,625 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (94,323,676 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (191,606,450 samples, 0.35%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::coin_example::init_module (16,375,210 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (18,627,162 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (217,481,612 samples, 0.39%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::add_stake (4,923,754 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (33,842,035 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::signer_from_permissioned_handle (9,708,787 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::mint (1,354,289,168 samples, 2.45%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (19,318,914 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (36,210,624 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::store_signer_cap (5,256,122 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::burn_internal (14,255,508 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (5,288,990 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (5,729,749 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (348,329,738 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_with_ref (20,554,155 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validator (42,656,961 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_account (12,517,125 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,078,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (120,076,387 samples, 0.22%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (117,386,645 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (299,847,042 samples, 0.54%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (149,397,099 samples, 0.27%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (8,922,878 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::upsert (2,685,655,880 samples, 4.85%) +0x0000.. + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::coin_example::init_module (16,514,668 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::is_empty (9,687,292 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::prologue_common (94,448,934 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (8,881,536 samples, 0.02%) + + + +0x3257ababdfa165c9b16f8f2a2d2dec58c83dcdea9bdf550c7c60f4b6b5b06feb::liquidity_pool::init_module (5,828,585 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (8,728,836 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (15,141,100 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::grant_permission_by_address (254,886,896 samples, 0.46%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (12,344,698 samples, 0.02%) + + + +0x63ca834489731b89c8f75e63a4fc65cfea775d20c69d0ec65fa105329715121b::vector_picture::update (9,804,504 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (69,434,615 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::add_fungibility (50,713,550 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (11,116,461 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (401,691,995 samples, 0.73%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (304,323,054 samples, 0.55%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_owner (5,040,747 samples, 0.01%) + + + +0x59751998dc73e3ce112b95b971392fb5d8d52f2ddedb0e5c974f76d6841c8690::coin_example::init_module (15,891,289 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::balance (75,791,035 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,454,287 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_named_object (46,229,840 samples, 0.08%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::coin_example::init_module (16,401,293 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (309,479,419 samples, 0.56%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,701,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,236,967 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::vector_example::generate_vec (186,205,249 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,539,710 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validators (62,533,917 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (68,629,514 samples, 0.12%) + + + +0xab7f7aaaaa5edf4a7a8f19fe268ff5d3d0ad81293c22372582d48dc52ceea209::resource_groups_example::set (9,208,509 samples, 0.02%) + + + +0xceea15bd81a80dae592da4fca2a5576de8e685b2a8d3571f77c13857a5415d64::simple::loop_arithmetic (567,709,124 samples, 1.03%) + + + +0xbd3ad01b3983ac748103d27139071721edd713d9bed75a79bd8b8872bd87648c::counter_with_milestone::increment_milestone (29,144,469 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (142,328,131 samples, 0.26%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (143,307,875 samples, 0.26%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::maps_example::test_add_remove_simple_map (1,735,074,990 samples, 3.13%) +0xe.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,904,253 samples, 0.02%) + + + +0xab7f7aaaaa5edf4a7a8f19fe268ff5d3d0ad81293c22372582d48dc52ceea209::coin_example::init_module (16,410,794 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (28,294,034 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::is_empty (7,647,940 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (127,817,788 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_with_event_internal (48,974,665 samples, 0.09%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::get_amount_out (134,854,876 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,372,623 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_transfer_ref (6,431,327 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (8,209,784 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (62,427,589 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (279,599,130 samples, 0.51%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (61,080,821 samples, 0.11%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::init_module (5,787,834 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (50,430,244 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (10,008,091 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_end (6,908,620 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (6,240,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::mint (5,307,419 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (39,046,097 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_sanity_check (25,566,404 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::copyable_any::pack (4,987,452 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,679,708 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (17,638,109 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::update_key (405,724,222 samples, 0.73%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::create (33,350,835 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,687,501 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (19,331,973 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::fungible_transfer_only (118,278,779 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,422,874 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (7,920,794 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (622,861,316 samples, 1.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (274,657,221 samples, 0.50%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (4,891,996 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::create (29,783,130 samples, 0.05%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::coin_example::init_module (17,507,625 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (10,706,792 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::unified_prologue_v2 (133,584,015 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,078,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::create_numbered_token (202,575,395 samples, 0.37%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add (18,457,919 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,727,377 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (71,249,788 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (5,367,992 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (1,742,372,809 samples, 3.15%) +0x0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::coin_to_fungible_asset (519,379,428 samples, 0.94%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (11,065,331 samples, 0.02%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::get_signer (12,449,415 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,260,507 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (12,319,343 samples, 0.02%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::smart_table_picture::create (10,994,330 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (11,639,136 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (67,484,890 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (8,135,965 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::operations_default_to_fa_apt_store_enabled (4,856,757 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::concurrent_fungible_assets_enabled (5,333,793 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::exists_at (6,563,746 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (8,086,451 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,128,304 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add_box (7,150,214 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_mint_ref (6,586,338 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,619,294 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::upsert (1,556,371,504 samples, 2.81%) +0x.. + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::vector_example::test_remove_insert (873,394,417 samples, 1.58%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::destroy_empty (8,813,582 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (84,781,225 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_token (76,402,724 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (20,155,242 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::store_exists (5,816,334 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_ambassador_token_impl (514,747,674 samples, 0.93%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,448,790 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::coin_example::init_module (16,087,039 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::operations_default_to_fa_apt_store_enabled (5,092,665 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (11,684,692 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,338,625 samples, 0.02%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::fungible_asset_example::init_module (5,038,580 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::create_unlimited_collection (4,852,290 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (26,120,495 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (14,397,697 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_framework_reserved_account (8,925,952 samples, 0.02%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::create_fungible_asset (4,824,128 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (18,538,918 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,167,621 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::extract (19,864,993 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::length (4,751,615 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (6,423,412 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::transfer (454,515,287 samples, 0.82%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::permissioned_transfer::transfer (262,608,104 samples, 0.47%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (44,441,887 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (46,628,219 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,776,794 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (31,291,332 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (61,988,500 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,303,842 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,887,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,874,582 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (12,514,893 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::guid::create (4,845,835 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_mint_and_transfer_nft_sequential (1,683,731,881 samples, 3.04%) +0xe.. + + +0x0000000000000000000000000000000000000000000000000000000000000007::confidential_asset::init_module (46,522,457 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,551,377 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (5,025,552 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (36,091,694 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (6,805,309 samples, 0.01%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::vector_example::test_trim_append (799,331,547 samples, 1.44%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (8,263,760 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (227,974,463 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (13,428,826 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::destroy_empty_node (6,645,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,731,160 samples, 0.01%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::vector_picture::create (88,647,500 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,630,498 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_transfer (449,820,258 samples, 0.81%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (10,344,249 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (22,024,831 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (31,525,595 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (748,510,448 samples, 1.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_with_event_internal (49,664,552 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check_by_address (23,769,113 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check_by_address (215,796,348 samples, 0.39%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::maps_example::test_add_remove_big_ordered_map (3,090,752,373 samples, 5.58%) +0x6fc74.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (33,462,207 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (8,984,032 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store_enabled_fungible_asset (90,834,255 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account_abstraction::register_derivable_authentication_function (11,255,741 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::write_to_event_store (92,097,050 samples, 0.17%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::vector_example::generate_vec (88,360,339 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (22,212,871 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (19,798,412 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (6,800,090 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::mint (447,523,437 samples, 0.81%) + + + +0x11043a7dcbc2d15b7d37cb307cda8c82dde4664d521e99fc7ddd3b7f5d029179::objects::create_objects (366,372,780 samples, 0.66%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::address_burn_from_for_gas (31,863,853 samples, 0.06%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::smart_table_picture::create (11,793,960 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,921,752 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (14,669,962 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,309,874 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::contains (427,093,719 samples, 0.77%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (19,212,683 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (25,878,537 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (285,717,684 samples, 0.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (24,946,802 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,757,415 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_token (75,632,078 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (16,764,409 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (16,103,040 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::initialize_partial_voting (9,249,416 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (14,817,408 samples, 0.03%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::vector_example::test_middle_move_range (841,318,071 samples, 1.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,486,166 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (1,226,800,607 samples, 2.22%) +0.. + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::fungible_asset_example::init_module (5,031,374 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::prepare_input (9,446,748 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (8,334,791 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (5,208,163 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (30,542,076 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (37,800,216 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::initialize (28,486,871 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (4,720,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (3,530,193,691 samples, 6.38%) +0x000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_lower_bound (19,371,829 samples, 0.04%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::swap (514,755,106 samples, 0.93%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::check_dependencies (505,214,447 samples, 0.91%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::is_account_registered (22,773,454 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check (26,598,363 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (16,460,880 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,786,534 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (9,645,497 samples, 0.02%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::mint_p (575,562,120 samples, 1.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (9,763,831 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::replace_root (4,713,662 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (136,233,571 samples, 0.25%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (5,271,085 samples, 0.01%) + + + +0x11043a7dcbc2d15b7d37cb307cda8c82dde4664d521e99fc7ddd3b7f5d029179::coin_example::init_module (16,126,876 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (131,662,696 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::remove (9,366,563 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (7,907,125 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::initialize_liquid_pair (116,293,664 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (9,110,568 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add (5,278,838 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::contains (36,306,694 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit (57,657,282 samples, 0.10%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::vector_picture::update (124,099,417 samples, 0.22%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,553,914 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (8,047,661 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::generate_burn_ref (6,465,114 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (10,526,038 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (9,046,468 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,106,040 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (5,834,783 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (33,429,542 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,154,125 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::unified_epilogue_v2 (139,108,517 samples, 0.25%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::mem::replace (7,102,295 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (381,598,150 samples, 0.69%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,717,791 samples, 0.01%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::smart_table_picture::update (3,972,636,764 samples, 7.18%) +0x581b3e8.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (20,606,559 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::mint_token (457,328,853 samples, 0.83%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::liquidity_pool::init_module (6,357,625 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::swap (484,727,077 samples, 0.88%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (1,869,550,150 samples, 3.38%) +0x0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,597,758 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_borrow (7,719,511 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::init_module (5,128,201 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (1,560,303,744 samples, 2.82%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (42,939,838 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (31,498,580 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (29,675,160 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,533,919 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (9,210,249 samples, 0.02%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::create_ambassador_collection (7,009,291 samples, 0.01%) + + + +0x5cb9b3017d5a8b166c06d23575bba9498b86db361a599af889d5f833778c2ee9::objects::create_objects (289,916,335 samples, 0.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (42,802,155 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (30,676,569 samples, 0.06%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_create_token_data (26,158,460 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove_at (942,714,646 samples, 1.70%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::init_module (6,593,293 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box_mut (5,517,912 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (108,878,469 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_stake_owner (13,120,000 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::get_collection_supply (37,256,242 samples, 0.07%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::fungible_asset_example::init_module (4,845,168 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,228,123 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (338,338,125 samples, 0.61%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,472,416 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (8,202,968 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit_event (565,830,735 samples, 1.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000007::confidential_asset::init_module_for_genesis (91,181,499 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (46,956,116 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (51,124,216 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (12,199,240 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (7,882,952 samples, 0.01%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::coin_example::init_module (16,588,791 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,605,543 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (16,590,332 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,791,208 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (19,868,942 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (70,304,319 samples, 0.13%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::fungible_asset_example::init_module (4,962,537 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,918,828 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (5,359,837 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove_at (17,178,116 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (19,019,966 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::load_factor (9,345,592 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (64,202,030 samples, 0.12%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::swap (1,252,000,252 samples, 2.26%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::empty (5,060,446 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (5,080,879 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,409,250 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::generate_signer (12,160,026 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (12,669,386 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (8,557,952 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (55,500,189 samples, 0.10%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::mint (13,650,826 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (6,528,255 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (16,049,919 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (20,321,188 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_sanity_check (14,946,633 samples, 0.03%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::get_metadata (58,658,712 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (7,883,663 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::reserve_slot (18,492,603 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_exists (51,111,166 samples, 0.09%) + + + +0x5cb9b3017d5a8b166c06d23575bba9498b86db361a599af889d5f833778c2ee9::coin_example::init_module (16,215,624 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (5,910,326 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (7,594,085 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::extract (5,204,373 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::is_fungible_balance_at_least (19,370,834 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (13,684,191 samples, 0.02%) + + + +all (55,346,729,665 samples, 100%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::grant_apt_permission (345,086,930 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,965,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::destroy_empty (30,975,007 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::publish_package (1,059,047,085 samples, 1.91%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_capacity_above (13,415,012 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (9,436,793 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,103,158 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (19,333,669 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (24,278,838 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::new_event_handle (10,609,491 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append_utf8 (12,110,077 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (21,118,886 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,674,500 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (12,677,310 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (48,013,171 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,734,950 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::remove (337,409,385 samples, 0.61%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (108,203,443 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,218,578 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (4,693,774 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::is_empty (9,669,835 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_internal (4,805,542 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (15,794,833 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (8,421,831 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (171,966,413 samples, 0.31%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize_core_resources_and_aptos_coin (156,802,884 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,192,375 samples, 0.01%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::coin_example::init_module (16,830,336 samples, 0.03%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_mint_and_transfer_ft (1,150,613,726 samples, 2.08%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (6,307,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::trim (9,045,474 samples, 0.02%) + + + +0xe7de0ac63e1bdaadb9400daa013a754bbdd16faa7de47cfca3f2ef6bb5d893fe::coin_example::init_module (16,771,582 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_guid (4,697,158 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,722,831 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::fungible_asset_example::init_module (4,932,707 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (194,326,076 samples, 0.35%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::vector_example::generate_vec (184,636,958 samples, 0.33%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::reconfiguration::initialize (33,146,455 samples, 0.06%) + + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::vector_example::generate_vec (186,464,835 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (4,589,393,082 samples, 8.29%) +0x000000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (33,900,397 samples, 0.06%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::get_signer (12,366,245 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (63,541,048 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::aggregator_v2_is_at_least_api_enabled (7,668,344 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,042,249 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_and_reserve (31,629,774 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (21,502,123 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,508,668 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,704,757 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (13,752,811 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (15,428,407 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (9,689,450 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (46,951,305 samples, 0.08%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::mint_nft_sequential (905,870,822 samples, 1.64%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::next_slot_index (7,054,962 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::owns (8,201,837 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,515,377 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::decimals (6,158,504 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (341,860,114 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (13,639,742 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::find (133,255,892 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw (96,997,925 samples, 0.18%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::vector_example::generate_vec (9,363,750 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (25,950,502 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (175,471,851 samples, 0.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::is_coin_initialized (12,585,412 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw (90,525,296 samples, 0.16%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::coin_example::init_module (16,290,251 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (6,692,048 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::mint (14,982,042 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (6,478,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::empty (5,279,219 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,747,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (8,567,009 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (83,741,082 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,950,748 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::create_permissioned_handle (114,719,846 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (4,762,161 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (13,067,006 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (25,611,035 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_fee::burn_fee (64,762,402 samples, 0.12%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::maps_example::test_add_remove_big_ordered_map (8,555,122,898 samples, 15.46%) +0x504281e16926b35e2e0b2.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (11,132,663 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,921,042 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (4,819,750 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (49,142,634 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::find_leaf_path (662,382,985 samples, 1.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_static_size_and_init_max_degrees (7,816,396 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (51,143,688 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::burn_internal (8,210,463 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (208,965,219 samples, 0.38%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (159,486,278 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (28,153,742 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,265,709 samples, 0.01%) + + + +0x3257ababdfa165c9b16f8f2a2d2dec58c83dcdea9bdf550c7c60f4b6b5b06feb::vector_picture::create (83,779,366 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (9,232,873 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (56,836,669 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::transfer_with_ref (22,053,851 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::find_leaf_path (1,181,338,731 samples, 2.13%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (9,220,166 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,207,702 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_exists (18,396,471 samples, 0.03%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::coin_example::init_module (16,513,042 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (9,041,126 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::new (4,963,420 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (6,177,950 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (159,663,055 samples, 0.29%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::vector_example::generate_vec (118,852,748 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,950,724 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::ensure_paired_metadata (350,519,725 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store_enabled_fungible_asset (15,526,331 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::load_factor (5,983,931 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_numbered_ambassador_token (708,783,593 samples, 1.28%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::coin_example::init_module (17,717,916 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,165,823 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (61,357,007 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,512,292 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::borrow (8,532,015 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::publish_package_txn (1,595,342,084 samples, 2.88%) +0x.. + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::coin_example::init_module (16,150,585 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (22,926,797 samples, 0.04%) + + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::coin_example::mint_p (1,731,472,453 samples, 3.13%) +0x5.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_link (5,359,836 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (47,650,615 samples, 0.09%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::vector_example::generate_vec (189,177,417 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,881,290 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check (24,900,964 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (110,750,182 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (21,958,884 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,001,254 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::burn_from_fungible_store_for_gas (49,355,730 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::destroy_none (7,400,981 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append (5,297,665 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::check_for_replay_protection_regular_txn (14,447,913 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (17,828,457 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (110,921,803 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,808,791 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_exists (55,461,247 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (228,073,104 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (15,488,043 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (12,846,873 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_internal (9,134,208 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (162,191,948 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (16,472,277 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (185,456,332 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (147,198,737 samples, 0.27%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_transfer (456,909,641 samples, 0.83%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (11,738,712 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (43,778,045 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (6,901,503 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (51,873,119 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (8,664,162 samples, 0.02%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::create_pool (63,712,378 samples, 0.12%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::vector_picture::create (88,295,167 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,431,627 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (20,546,996 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_pending_transaction_fee (36,511,624 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (30,738,502 samples, 0.06%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::vector_example::test_trim_append (178,992,255 samples, 0.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (7,935,621 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (17,548,586 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (19,417,084 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (8,778,100 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::is_fungible_balance_at_least (15,037,165 samples, 0.03%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_create_token_data (26,047,210 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,330,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (11,688,037 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (5,239,675 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_burn_ref (6,419,036 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::swap (1,247,714,755 samples, 2.25%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (19,375,456 samples, 0.04%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::coin_example::init_module (16,300,252 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (213,344,873 samples, 0.39%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,364,456 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,087,671 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::add (9,972,376 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (15,425,007 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,178,461 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (20,965,474 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (13,911,945 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::timestamp::now_seconds (4,935,294 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,121,623 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,606,534 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,734,052 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (18,870,780 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,467,547 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::add (794,092,857 samples, 1.43%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (156,966,298 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (669,594,044 samples, 1.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (17,439,185 samples, 0.03%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::smart_table_picture::update (2,303,191,819 samples, 4.16%) +0xbc.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::borrow (4,722,580 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::balance_of (9,524,714 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append (5,147,750 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,116,247 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::build_token_name (30,704,695 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (191,137,561 samples, 0.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,717,002 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (174,013,515 samples, 0.31%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (8,561,037 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_new_begin_iter (20,815,591 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (329,533,242 samples, 0.60%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,820,412 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::vector_example::test_remove_insert (1,430,756,024 samples, 2.59%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,220,041 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::pop_front (57,633,238 samples, 0.10%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::coin_example::init_module (16,627,956 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::add (34,742,826 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::balance (69,850,749 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (67,087,119 samples, 0.12%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_initialize_collection (59,675,881 samples, 0.11%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::maps_example::test_add_remove_ordered_map (5,716,835,651 samples, 10.33%) +0x19dea829a8427.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (101,878,592 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::initialize (36,720,457 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_and_reserve (8,617,169 samples, 0.02%) + + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::coin_example::init_module (17,218,208 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,708,084 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,836,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (46,750,133 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (16,387,553 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::guid::create (43,287,749 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (11,700,173 samples, 0.02%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::coin_example::init_module (16,832,209 samples, 0.03%) + + + +0x594e3921c57b1380975ada61d3a574551a5f7df189876dbbd87dff82cda4f982::liquidity_pool::init_module (5,828,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit (61,585,954 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (14,795,766 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::burn (22,560,722 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (15,722,535 samples, 0.03%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::fungible_asset_example::init_module (6,187,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (7,969,422 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (4,833,791 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,245,706 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::aggregator_v2_is_at_least_api_enabled (12,643,738 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aggregator_v2::is_at_least (15,767,346 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::deposit (7,170,837 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::initialize_liquid_pair (129,691,259 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,750,626 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,718,417 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (5,399,508 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::name (6,266,363 samples, 0.01%) + + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::vector_example::generate_vec (18,813,830 samples, 0.03%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::get_amount_out (97,757,227 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (12,170,599 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (6,454,452 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize (227,504,870 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,519,749 samples, 0.02%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::vector_picture::check (123,190,291 samples, 0.22%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::vector_example::test_trim_append (371,482,374 samples, 0.67%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (100,172,878 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (10,246,289 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (108,530,261 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_dynamic_size_and_init_max_degrees (9,902,548 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (18,168,582 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::contains (35,162,999 samples, 0.06%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::vector_example::test_trim_append (1,111,354,625 samples, 2.01%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (37,624,807 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (4,817,753 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (20,764,828 samples, 0.04%) + + + +0x594e3921c57b1380975ada61d3a574551a5f7df189876dbbd87dff82cda4f982::vector_picture::create (601,775,667 samples, 1.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (56,370,441 samples, 0.10%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_create_token_data (167,016,707 samples, 0.30%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::new (9,883,258 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (6,657,007 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (3,442,740,360 samples, 6.22%) +0x000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,768,379 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (7,624,564 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::deposit (1,085,484,621 samples, 1.96%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,605,585 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (7,552,045 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::coin_example::init_module (17,524,499 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,413,293 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::new_event_handle (23,091,560 samples, 0.04%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::add_liquidity (20,089,376 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (353,457,655 samples, 0.64%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::fungible_asset_example::init_module (5,181,335 samples, 0.01%) + + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::coin_example::init_module (17,745,459 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_lower_bound (22,345,414 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,038,834 samples, 0.01%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::liquidity_pool::init_module (6,634,000 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (19,268,592 samples, 0.03%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::vector_example::test_trim_append (730,259,441 samples, 1.32%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::resource_groups_example::set_3 (35,615,989 samples, 0.06%) + + + +0x374c567d86c4bfbe7b22224a6a9efe2311b93d7115b349f68596e15bbde1f7cf::counter_with_milestone::increment_milestone (51,413,955 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,284,209 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::create_pairing (52,516,710 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::increment_supply (20,529,967 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::stored_to_index (7,319,445 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,736,792 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (311,816,327 samples, 0.56%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,464,333 samples, 0.02%) + + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::objects::create_objects (2,870,535,384 samples, 5.19%) +0x9948.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (85,752,543 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (5,070,029 samples, 0.01%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::vector_example::generate_vec (238,084,206 samples, 0.43%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (10,659,120 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::owns (7,676,743 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::decrease_supply (7,158,171 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (7,474,875 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (28,489,145 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,797,542 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,241,053 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (8,603,968 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (35,180,929 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,790,209 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,349,584 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::register (91,495,457 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (18,067,318 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (16,200,400 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow (134,493,995 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (210,798,431 samples, 0.38%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,647,877 samples, 0.02%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_initialize_collection (59,602,002 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,220,541 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (8,167,946 samples, 0.01%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::liquidity_pool::init_module (6,445,501 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (20,427,429 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,997,999 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (5,163,206 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (7,326,215 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::add_typed (46,862,222 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::init (5,432,788 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::balance_of (9,787,812 samples, 0.02%) + + + +0xcc06ae22a4425ea36680d3df96c0ccc98f3e5c9c43771ddeda0506656fda5eb7::simple::emit_events (1,066,172,614 samples, 1.93%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (5,562,745 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (7,476,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::configure_accounts_for_test (10,440,090 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (68,824,876 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,887,709 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::utf8 (5,586,498 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (10,602,629 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (14,454,537 samples, 0.03%) + + + +0xe1367aab40e405230929737f522f7c13a9c4d85667aef12054ed1f89584d87aa::liquidity_pool::init_module (6,811,666 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (112,828,915 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,980,249 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (6,885,251 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,048,167 samples, 0.01%) + + + +0x4e2ca9154fea8f1bf409b19a7df42313447c3c232245e4efb030b8f668c26f70::simple::loop_nop (948,994,668 samples, 1.71%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::add (432,148,324 samples, 0.78%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (107,891,239 samples, 0.19%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::init_module (9,129,083 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,423,583 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (326,222,604 samples, 0.59%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (37,427,648 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (90,807,209 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,735,846 samples, 0.01%) + + + +0x63ca834489731b89c8f75e63a4fc65cfea775d20c69d0ec65fa105329715121b::liquidity_pool::init_module (5,788,376 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (11,352,312 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::contains (732,646,955 samples, 1.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::fungible_transfer_only (344,527,713 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (36,220,615 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::split_one_bucket (51,435,746 samples, 0.09%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::add_liquidity (18,331,243 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (4,747,413 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (30,369,520 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::assert_master_signer (14,625,585 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::authorize_increase (191,420,521 samples, 0.35%) + + + +0xe1367aab40e405230929737f522f7c13a9c4d85667aef12054ed1f89584d87aa::vector_picture::check (8,497,083 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (105,625,738 samples, 0.19%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (49,685,000 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::add (7,966,529 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (162,571,811 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (158,698,179 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,894,204 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (21,497,452 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (14,932,184 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aggregator_v2::is_at_least (25,519,455 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::swap_remove (9,347,241 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (13,215,549 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (23,740,641 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (48,386,422 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (22,601,661 samples, 0.04%) + + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::vector_example::test_middle_move_range (350,396,776 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (20,914,813 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::is_empty (11,888,300 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,308,749 samples, 0.01%) + + + diff --git a/third_party/move/move-vm/profiler/fold.awk b/third_party/move/move-vm/profiler/fold.awk new file mode 100644 index 00000000000..91a355f2761 --- /dev/null +++ b/third_party/move/move-vm/profiler/fold.awk @@ -0,0 +1,20 @@ +BEGIN { + depth = 0 +} + +$1 == "BEGIN" { + stack[depth] = $2 + depth++ +} + +$1 == "END" { + # print current stack + out = stack[0] + for (i = 1; i < depth; i++) { + out = out ";" stack[i] + } + print out, $2 + + # pop + depth-- +} diff --git a/third_party/move/move-vm/profiler/profile.sh b/third_party/move/move-vm/profiler/profile.sh new file mode 100755 index 00000000000..aa7031d611e --- /dev/null +++ b/third_party/move/move-vm/profiler/profile.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +############################################# +# CONFIG +############################################# + +SCRIPT_DIR="$(dirname $0)" + +BIN_PATH=$1 +TRACE_SCRIPT="$SCRIPT_DIR/trace.d" +FOLD_SCRIPT="$SCRIPT_DIR/fold.awk" + +OUT_RAW=$(mktemp /tmp/dtrace-raw.XXXXXX) +OUT_FOLDED=$(mktemp /tmp/dtrace-folded.XXXXXX) +OUT_SVG="flame.svg" + +############################################# +# LOGGING +############################################# + +red() { printf '\033[31m%s\033[0m\n' "$*" >&2; } +green() { printf '\033[32m%s\033[0m\n' "$*" >&2; } +yellow() { printf '\033[33m%s\033[0m\n' "$*" >&2; } +blue() { printf '\033[34m%s\033[0m\n' "$*" >&2; } + +log() { blue "==> $*"; } + +############################################# +# TOOL CHECKING +############################################# + +require() { + if ! command -v "$1" >/dev/null 2>&1; then + red "Error: '$1' not found in PATH" + exit 1 + fi +} + +require awk +require flamegraph.pl + +############################################# +# CLEANUP +############################################# + +TARGET_PID="" + +cleanup() { + # Kill the benchmark program if it's still alive + if [[ -n "${TARGET_PID:-}" ]] && kill -0 "$TARGET_PID" 2>/dev/null; then + yellow "Stopping benchmark (PID $TARGET_PID)…" + kill "$TARGET_PID" 2>/dev/null || true + wait "$TARGET_PID" 2>/dev/null || true + fi + + # Remove temporary files + [[ -f "${OUT_RAW:-}" ]] && rm -f "$OUT_RAW" + [[ -f "${OUT_FOLDED:-}" ]] && rm -f "$OUT_FOLDED" +} +trap cleanup EXIT + +############################################# +# MAIN WORKFLOW +############################################# + +log "Starting benchmark with tracing…" +sudo dtrace -q -s "$TRACE_SCRIPT" -c "$BIN_PATH" > "$OUT_RAW" + +log "Folding stack output…" +awk -f "$FOLD_SCRIPT" "$OUT_RAW" > "$OUT_FOLDED" + +log "Generating flamegraph…" +flamegraph.pl "$OUT_FOLDED" > "$OUT_SVG" + +green "Done!" +green "Flamegraph written to: $OUT_SVG" diff --git a/third_party/move/move-vm/profiler/src/lib.rs b/third_party/move/move-vm/profiler/src/lib.rs new file mode 100644 index 00000000000..369346e208c --- /dev/null +++ b/third_party/move/move-vm/profiler/src/lib.rs @@ -0,0 +1,110 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use move_vm_types::instr::Instruction; +use once_cell::sync::Lazy; +#[cfg(feature = "probe-profiler")] +use probe::ProbeProfiler; + +#[cfg(feature = "probe-profiler")] +pub mod probe; + +#[cfg(feature = "probe-profiler")] +pub type ActiveProfiler = ProbeProfiler; + +#[cfg(not(feature = "probe-profiler"))] +pub type ActiveProfiler = NoopProfiler; + +pub type FnGuard = ::FnGuard; + +pub static VM_PROFILER: Lazy = Lazy::new(ActiveProfiler::default); + +/// A function that can be profiled. +pub trait ProfilerFunction { + fn name(&self) -> String; +} + +/// An instruction that can be profiled. +pub trait ProfilerInstruction { + fn name(&self) -> String; +} + +impl ProfilerInstruction for Instruction { + fn name(&self) -> String { + self.name().to_string() + } +} + +/// A profiler for Move VM execution. +pub trait Profiler { + type FnGuard; + type InstrGuard; + + /// Start profiling a function and return a guard. + /// The guard ends profiling when dropped, so it should be held for the duration of the function execution. + fn function_start(&self, function: &F) -> Self::FnGuard + where + F: ProfilerFunction; + + /// Start profiling an instruction and return a guard. + /// The guard ends profiling when dropped, so it should be held for the duration of the instruction execution. + fn instruction_start(&self, instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction; +} + +pub struct NoopFnGuard; +pub struct NoopInstrGuard; + +/// A no-op profiler that does nothing. +#[derive(Default)] +pub struct NoopProfiler; + +impl Profiler for NoopProfiler { + type FnGuard = NoopFnGuard; + type InstrGuard = NoopInstrGuard; + + fn function_start(&self, _function: &F) -> Self::FnGuard + where + F: ProfilerFunction, + { + NoopFnGuard + } + + fn instruction_start(&self, _instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction, + { + NoopInstrGuard + } +} + +#[cfg(test)] +mod tests { + use crate::{Profiler, ProfilerFunction, VM_PROFILER}; + use move_vm_types::instr::Instruction; + use std::{thread::sleep, time::Duration}; + + struct DummyFunction<'a>(&'a str); + + impl ProfilerFunction for DummyFunction<'_> { + fn name(&self) -> String { + self.0.to_string() + } + } + + #[test] + fn test_profiler() { + let _fg = VM_PROFILER.function_start(&DummyFunction("foo")); + sleep(Duration::from_millis(100)); + execute_instruction(&Instruction::And); + execute_instruction(&Instruction::Or); + execute_instruction(&Instruction::Not); + sleep(Duration::from_millis(100)); + } + + fn execute_instruction(instr: &Instruction) { + let _ig = VM_PROFILER.instruction_start(instr); + sleep(Duration::from_millis(100)); + } +} diff --git a/third_party/move/move-vm/profiler/src/probe.rs b/third_party/move/move-vm/profiler/src/probe.rs new file mode 100644 index 00000000000..9d2ce123f80 --- /dev/null +++ b/third_party/move/move-vm/profiler/src/probe.rs @@ -0,0 +1,107 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{Profiler, ProfilerFunction, ProfilerInstruction}; +use std::time::Instant; + +#[usdt::provider] +mod vm_profiler { + fn function_entry(function_name: String) {} + fn function_exit(nanos: u64) {} + + fn instruction_entry(instruction_name: String) {} + fn instruction_exit(nanos: u64) {} +} + +/// A profiler that emits USDT (Userland Statically Defined Tracing) probes. +/// See [usdt](https://crates.io/crates/usdt) for more details. +/// +/// It emits the following probes for function and instruction entry/exit: +/// - `function_entry(function_name: String)` +/// - `function_exit(nanos: u64)` +/// - `instruction_entry(instruction_name: String)` +/// - `instruction_exit(nanos: u64)` +/// Note that the exit probes include the elapsed time in nanoseconds. +pub struct ProbeProfiler; + +impl Default for ProbeProfiler { + fn default() -> Self { + usdt::register_probes().expect("Failed to register probes"); + Self + } +} + +impl Profiler for ProbeProfiler { + type FnGuard = ProbeFnGuard; + type InstrGuard = ProbeInstrGuard; + + #[inline] + fn function_start(&self, function: &F) -> Self::FnGuard + where + F: ProfilerFunction, + { + ProbeFnGuard::new(function) + } + + #[inline] + fn instruction_start(&self, instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction, + { + ProbeInstrGuard::new(instruction) + } +} + +pub struct ProbeFnGuard { + start: Instant, +} + +impl ProbeFnGuard { + #[must_use] + fn new(function: &F) -> Self + where + F: ProfilerFunction, + { + vm_profiler::function_entry!(|| function.name()); + + Self { + start: Instant::now(), + } + } +} + +impl Drop for ProbeFnGuard { + fn drop(&mut self) { + vm_profiler::function_exit!(|| { + let dt = self.start.elapsed(); + dt.as_nanos() as u64 + }); + } +} + +pub struct ProbeInstrGuard { + start: Instant, +} + +impl ProbeInstrGuard { + #[must_use] + fn new(instruction: &I) -> Self + where + I: ProfilerInstruction, + { + vm_profiler::instruction_entry!(|| instruction.name()); + + Self { + start: Instant::now(), + } + } +} + +impl Drop for ProbeInstrGuard { + fn drop(&mut self) { + vm_profiler::instruction_exit!(|| { + let dt = self.start.elapsed(); + dt.as_nanos() as u64 + }); + } +} diff --git a/third_party/move/move-vm/profiler/trace.d b/third_party/move/move-vm/profiler/trace.d new file mode 100644 index 00000000000..f69a5db0864 --- /dev/null +++ b/third_party/move/move-vm/profiler/trace.d @@ -0,0 +1,13 @@ +#pragma D + +/* Function probes */ + +vm_profiler*:::function_entry +{ + printf("BEGIN %s\n", copyinstr(arg0)); +} + +vm_profiler*:::function_exit +{ + printf("END %llu\n", (unsigned long long)arg0); +} diff --git a/third_party/move/move-vm/runtime/Cargo.toml b/third_party/move/move-vm/runtime/Cargo.toml index ff9aef33d7b..0e166f99af0 100644 --- a/third_party/move/move-vm/runtime/Cargo.toml +++ b/third_party/move/move-vm/runtime/Cargo.toml @@ -7,23 +7,28 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] ambassador = { workspace = true } bcs = { workspace = true } better_any = { workspace = true } +bitvec = { workspace = true } bytes = { workspace = true } +cfg-if = { workspace = true } claims = { workspace = true } fail = { workspace = true } +fxhash = { workspace = true } hashbrown = { workspace = true } +itertools = { workspace = true } lazy_static = { workspace = true } lru = { workspace = true } move-binary-format = { workspace = true } move-bytecode-verifier = { workspace = true } move-core-types = { workspace = true } move-vm-metrics = { workspace = true } +move-vm-profiler = { workspace = true } move-vm-types = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } @@ -38,19 +43,27 @@ hex = { workspace = true } legacy-move-compiler = { workspace = true } move-binary-format = { workspace = true, features = ["fuzzing"] } move-ir-compiler = { workspace = true } -move-vm-test-utils ={ workspace = true } +move-vm-test-utils = { workspace = true } move-vm-types = { workspace = true, features = ["testing"] } proptest = { workspace = true } smallbitvec = { workspace = true } +test-case = { workspace = true } [features] -default = [] +default = [ + "inline-callstack", +] +profiling = ["move-vm-profiler/probe-profiler"] +testing = [] fuzzing = ["move-vm-types/fuzzing"] failpoints = ["fail/failpoints"] # Enable tracing and debugging also for release builds. By default, it is only enabled for debug builds. debugging = [] -testing = [] stacktrace = [] +# Enable this features for tests that check bytecode verification. +disable_verifier_cache = [] +force-inline = [] +inline-callstack = [] [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] } diff --git a/third_party/move/move-vm/runtime/src/access_control.rs b/third_party/move/move-vm/runtime/src/access_control.rs index 94e3b703609..4c8b330d763 100644 --- a/third_party/move/move-vm/runtime/src/access_control.rs +++ b/third_party/move/move-vm/runtime/src/access_control.rs @@ -20,6 +20,9 @@ pub struct AccessControlState { impl AccessControlState { /// Enters a function, applying its access specifier to the state. + // note(inline): do not inline, they are called once per function, and increase `execute_main` + // quite a bit, we want to avoid those compile times + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn enter_function( &mut self, env: &impl AccessSpecifierEnv, @@ -46,6 +49,9 @@ impl AccessControlState { } /// Exit function, restoring access state before entering. + // note(inline): do not inline, they are called once per function, and increase `execute_main` + // quite a bit, we want to avoid those compile times + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn exit_function(&mut self, fun: &LoadedFunction) -> PartialVMResult<()> { if !matches!(fun.access_specifier(), AccessSpecifier::Any) { if self.specifier_stack.is_empty() { diff --git a/third_party/move/move-vm/runtime/src/config.rs b/third_party/move/move-vm/runtime/src/config.rs index 98be2e5f490..1787f2124c8 100644 --- a/third_party/move/move-vm/runtime/src/config.rs +++ b/third_party/move/move-vm/runtime/src/config.rs @@ -8,15 +8,20 @@ use move_vm_types::{ }; use serde::Serialize; -/// Dynamic config options for the Move VM. +/// Dynamic config options for the Move VM. Always add new fields to the end, as we rely on the +/// hash or serialized bytes of config to detect if it has changed (e.g., new feature flag was +/// enabled). Also, do not delete existing fields, or change the type of existing field. #[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct VMConfig { pub verifier_config: VerifierConfig, pub deserializer_config: DeserializerConfig, /// When this flag is set to true, MoveVM will perform type checks at every instruction - /// execution to ensure that type safety cannot be violated at runtime. + /// execution to ensure that type safety cannot be violated at runtime. Note: these + /// are more than type checks, for example, stack balancing, visibility, but the name + /// is kept for historical reasons. pub paranoid_type_checks: bool, - pub check_invariant_in_swap_loc: bool, + /// Always set to false, no longer used, kept for compatibility. + pub legacy_check_invariant_in_swap_loc: bool, /// Maximum value nest depth for structs. pub max_value_nest_depth: Option, /// Maximum allowed number of nodes in a type layout. This includes the types of fields for @@ -29,9 +34,23 @@ pub struct VMConfig { pub type_byte_cost: u64, pub delayed_field_optimization_enabled: bool, pub ty_builder: TypeBuilder, - pub use_call_tree_and_instruction_cache: bool, + pub enable_function_caches: bool, pub enable_lazy_loading: bool, pub enable_depth_checks: bool, + /// Whether trusted code should be optimized, for example, excluding it from expensive + /// paranoid checks. Checks may still not be done in place, and instead delayed to later time. + /// Instead, a trace can be recorded which is sufficient for type checking. + pub optimize_trusted_code: bool, + /// When this flag is set to true, Move VM will perform additional checks to ensure that + /// reference safety is maintained during execution. Note that the checks might be delayed and + /// instead execution trace can be recorded (so that checks are done based on the trace later). + pub paranoid_ref_checks: bool, + pub enable_capture_option: bool, + pub enable_enum_option: bool, + /// If true, Move VM will try to fetch layout from remote cache. + pub enable_layout_caches: bool, + pub propagate_dependency_limit_error: bool, + pub enable_framework_for_option: bool, } impl Default for VMConfig { @@ -40,18 +59,35 @@ impl Default for VMConfig { verifier_config: VerifierConfig::default(), deserializer_config: DeserializerConfig::default(), paranoid_type_checks: false, - check_invariant_in_swap_loc: true, + legacy_check_invariant_in_swap_loc: false, max_value_nest_depth: Some(DEFAULT_MAX_VM_VALUE_NESTED_DEPTH), - layout_max_size: 256, + layout_max_size: 512, layout_max_depth: 128, type_max_cost: 0, type_base_cost: 0, type_byte_cost: 0, delayed_field_optimization_enabled: false, ty_builder: TypeBuilder::with_limits(128, 20), - use_call_tree_and_instruction_cache: true, - enable_lazy_loading: false, + enable_function_caches: true, + enable_lazy_loading: true, enable_depth_checks: true, + optimize_trusted_code: false, + paranoid_ref_checks: false, + enable_capture_option: true, + enable_enum_option: true, + enable_layout_caches: true, + propagate_dependency_limit_error: true, + enable_framework_for_option: true, + } + } +} + +impl VMConfig { + /// Set the paranoid reference checks flag. + pub fn set_paranoid_ref_checks(self, enable: bool) -> Self { + Self { + paranoid_ref_checks: enable, + ..self } } } diff --git a/third_party/move/move-vm/runtime/src/data_cache.rs b/third_party/move/move-vm/runtime/src/data_cache.rs index 9dd342b4744..24e4c1b870d 100644 --- a/third_party/move/move-vm/runtime/src/data_cache.rs +++ b/third_party/move/move-vm/runtime/src/data_cache.rs @@ -3,11 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + module_traversal::TraversalContext, + native_functions::DependencyGasMeterWrapper, storage::{ + loader::traits::{ModuleMetadataLoader, StructDefinitionLoader}, module_storage::FunctionValueExtensionAdapter, - ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, + ty_layout_converter::LayoutConverter, }, - ModuleStorage, + Loader, ModuleStorage, }; use bytes::Bytes; use move_binary_format::errors::*; @@ -20,29 +23,144 @@ use move_core_types::{ vm_status::StatusCode, }; use move_vm_types::{ + gas::DependencyGasMeter, loaded_data::runtime_types::Type, resolver::ResourceResolver, value_serde::{FunctionValueExtension, ValueSerDeContext}, values::{GlobalValue, Value}, }; use std::collections::btree_map::{BTreeMap, Entry}; +use triomphe::Arc as TriompheArc; + +/// A hack to be able to use [MoveVmDataCache] in native context where there is no access to +/// static gas meter. +pub trait NativeContextMoveVmDataCache { + /// Used by native context only! Returns true if resource exists in global storage, and false + /// otherwise. Also, returns the number of bytes loaded (if any, otherwise [None]). + fn native_check_resource_exists( + &mut self, + gas_meter: &mut dyn DependencyGasMeter, + traversal_context: &mut TraversalContext, + addr: &AccountAddress, + ty: &Type, + ) -> PartialVMResult<(bool, Option)>; +} + +/// Provides access to global storage for Move VM. +pub trait MoveVmDataCache: NativeContextMoveVmDataCache { + /// Loads resource from global storage. Returns the immutable reference to it, along with the + /// number of bytes loaded (if any, otherwise [None]). + /// + /// Note: default implementation loads the resource for mutation, casting the mutable reference + /// to immutable. + fn load_resource( + &mut self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + addr: &AccountAddress, + ty: &Type, + ) -> PartialVMResult<(&GlobalValue, Option)> { + let (gv, bytes_loaded) = self.load_resource_mut(gas_meter, traversal_context, addr, ty)?; + Ok((gv, bytes_loaded)) + } + + /// Loads resource from global storage. Returns the mutable reference to it, along with the + /// number of bytes loaded (if any, otherwise [None]). + fn load_resource_mut( + &mut self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + addr: &AccountAddress, + ty: &Type, + ) -> PartialVMResult<(&mut GlobalValue, Option)>; +} + +/// Adapter for data cache that also stores references to code and data global storages. In case +/// resource is not yet in data cache, global storage is used to add it there. +pub struct MoveVmDataCacheAdapter<'a, LoaderImpl> { + data_cache: &'a mut TransactionDataCache, + resource_resolver: &'a dyn ResourceResolver, + loader: &'a LoaderImpl, +} + +impl<'a, LoaderImpl> NativeContextMoveVmDataCache for MoveVmDataCacheAdapter<'a, LoaderImpl> +where + LoaderImpl: Loader, +{ + fn native_check_resource_exists( + &mut self, + gas_meter: &mut dyn DependencyGasMeter, + traversal_context: &mut TraversalContext, + addr: &AccountAddress, + ty: &Type, + ) -> PartialVMResult<(bool, Option)> { + let mut gas_meter = DependencyGasMeterWrapper::new(gas_meter); + let (gv, bytes_loaded) = self.load_resource(&mut gas_meter, traversal_context, addr, ty)?; + let exists = gv.exists(); + Ok((exists, bytes_loaded)) + } +} + +impl<'a, LoaderImpl> MoveVmDataCacheAdapter<'a, LoaderImpl> +where + LoaderImpl: Loader, +{ + pub fn new( + data_cache: &'a mut TransactionDataCache, + resource_resolver: &'a dyn ResourceResolver, + loader: &'a LoaderImpl, + ) -> Self { + Self { + data_cache, + resource_resolver, + loader, + } + } +} + +impl<'a, LoaderImpl> MoveVmDataCache for MoveVmDataCacheAdapter<'a, LoaderImpl> +where + LoaderImpl: Loader, +{ + fn load_resource_mut( + &mut self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + addr: &AccountAddress, + ty: &Type, + ) -> PartialVMResult<(&mut GlobalValue, Option)> { + let bytes_loaded = if !self.data_cache.contains_resource(addr, ty) { + let (entry, bytes_loaded) = TransactionDataCache::create_data_cache_entry( + self.loader, + &LayoutConverter::new(self.loader), + gas_meter, + traversal_context, + self.loader.unmetered_module_storage(), + self.resource_resolver, + addr, + ty, + )?; + self.data_cache.insert_resource(*addr, ty.clone(), entry)?; + Some(bytes_loaded) + } else { + None + }; + + let gv = self.data_cache.get_resource_mut(addr, ty)?; + Ok((gv, bytes_loaded)) + } +} /// An entry in the data cache, containing resource's [GlobalValue] as well as additional cached /// information such as tag, layout, and a flag whether there are any delayed fields inside the /// resource. -pub(crate) struct DataCacheEntry { +struct DataCacheEntry { struct_tag: StructTag, - layout: MoveTypeLayout, + layout: TriompheArc, contains_delayed_fields: bool, value: GlobalValue, } -impl DataCacheEntry { - pub(crate) fn value(&self) -> &GlobalValue { - &self.value - } -} - /// Transaction data cache. Keep updates within a transaction so they can all be published at /// once when the transaction succeeds. /// @@ -74,19 +192,21 @@ impl TransactionDataCache { /// /// Gives all proper guarantees on lifetime of global data as well. pub fn into_effects(self, module_storage: &dyn ModuleStorage) -> PartialVMResult { - let resource_converter = - |value: Value, layout: MoveTypeLayout, _: bool| -> PartialVMResult { - let function_value_extension = FunctionValueExtensionAdapter { module_storage }; - let max_value_nest_depth = function_value_extension.max_value_nest_depth(); - ValueSerDeContext::new(max_value_nest_depth) - .with_func_args_deserialization(&function_value_extension) - .serialize(&value, &layout)? - .map(Into::into) - .ok_or_else(|| { - PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR) - .with_message(format!("Error when serializing resource {}.", value)) - }) - }; + let resource_converter = |value: Value, + layout: TriompheArc, + _: bool| + -> PartialVMResult { + let function_value_extension = FunctionValueExtensionAdapter { module_storage }; + let max_value_nest_depth = function_value_extension.max_value_nest_depth(); + ValueSerDeContext::new(max_value_nest_depth) + .with_func_args_deserialization(&function_value_extension) + .serialize(&value, &layout)? + .map(Into::into) + .ok_or_else(|| { + PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR) + .with_message(format!("Error when serializing resource {}.", value)) + }) + }; self.into_custom_effects(&resource_converter) } @@ -94,7 +214,11 @@ impl TransactionDataCache { /// produced effects for resources. pub fn into_custom_effects( self, - resource_converter: &dyn Fn(Value, MoveTypeLayout, bool) -> PartialVMResult, + resource_converter: &dyn Fn( + Value, + TriompheArc, + bool, + ) -> PartialVMResult, ) -> PartialVMResult> { let mut change_set = Changes::::new(); for (addr, account_data_cache) in self.account_map.into_iter() { @@ -128,7 +252,11 @@ impl TransactionDataCache { /// Retrieves data from the remote on-chain storage and converts it into a [DataCacheEntry]. /// Also returns the size of the loaded resource in bytes. This method does not add the entry /// to the cache - it is the caller's responsibility to add it there. - pub(crate) fn create_data_cache_entry( + fn create_data_cache_entry( + metadata_loader: &impl ModuleMetadataLoader, + layout_converter: &LayoutConverter, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, module_storage: &dyn ModuleStorage, resource_resolver: &dyn ResourceResolver, addr: &AccountAddress, @@ -142,33 +270,32 @@ impl TransactionDataCache { }, }; - // TODO(Gas): Shall we charge for this? - let (layout, contains_delayed_fields) = StorageLayoutConverter::new(module_storage) - .type_to_type_layout_with_identifier_mappings(ty)?; + let layout_with_delayed_fields = layout_converter.type_to_type_layout_with_delayed_fields( + gas_meter, + traversal_context, + ty, + false, + )?; let (data, bytes_loaded) = { - let metadata = module_storage - .fetch_existing_module_metadata( - &struct_tag.address, - struct_tag.module.as_ident_str(), - ) - .map_err(|err| err.to_partial())?; + let module = metadata_loader.load_module_for_metadata( + gas_meter, + traversal_context, + &struct_tag.module_id(), + )?; // If we need to process delayed fields, we pass type layout to remote storage. Remote // storage, in turn ensures that all delayed field values are pre-processed. resource_resolver.get_resource_bytes_with_metadata_and_layout( addr, &struct_tag, - &metadata, - if contains_delayed_fields { - Some(&layout) - } else { - None - }, + &module.metadata, + layout_with_delayed_fields.layout_when_contains_delayed_fields(), )? }; let function_value_extension = FunctionValueExtensionAdapter { module_storage }; + let (layout, contains_delayed_fields) = layout_with_delayed_fields.unpack(); let value = match data { Some(blob) => { let max_value_nest_depth = function_value_extension.max_value_nest_depth(); @@ -201,7 +328,7 @@ impl TransactionDataCache { /// Returns true if resource has been inserted into the cache. Otherwise, returns false. The /// state of the cache does not chang when calling this function. - pub(crate) fn contains_resource(&self, addr: &AccountAddress, ty: &Type) -> bool { + fn contains_resource(&self, addr: &AccountAddress, ty: &Type) -> bool { self.account_map .get(addr) .is_some_and(|account_cache| account_cache.contains_key(ty)) @@ -209,7 +336,7 @@ impl TransactionDataCache { /// Stores a new entry for loaded resource into the data cache. Returns an error if there is an /// entry already for the specified address-type pair. - pub(crate) fn insert_resource( + fn insert_resource( &mut self, addr: AccountAddress, ty: Type, @@ -229,7 +356,7 @@ impl TransactionDataCache { /// Returns the resource from the data cache. If resource has not been inserted (i.e., it does /// not exist in cache), an error is returned. - pub(crate) fn get_resource_mut( + fn get_resource_mut( &mut self, addr: &AccountAddress, ty: &Type, diff --git a/third_party/move/move-vm/runtime/src/debug.rs b/third_party/move/move-vm/runtime/src/debug.rs index 102daf934d6..068d81766eb 100644 --- a/third_party/move/move-vm/runtime/src/debug.rs +++ b/third_party/move/move-vm/runtime/src/debug.rs @@ -3,8 +3,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{interpreter::InterpreterDebugInterface, LoadedFunction, RuntimeEnvironment}; -use move_binary_format::file_format::Bytecode; -use move_vm_types::values::{self, Locals}; +use move_vm_types::{ + instr::Instruction, + values::{self, Locals}, +}; use std::{ collections::BTreeSet, io::{self, Write}, @@ -12,9 +14,12 @@ use std::{ }; #[derive(Debug)] +#[allow(unused)] enum DebugCommand { PrintStack, - Step, + Step(usize), + StepOver(usize), + StepOut, Continue, Breakpoint(String), DeleteBreakpoint(String), @@ -25,7 +30,9 @@ impl DebugCommand { pub fn debug_string(&self) -> &str { match self { Self::PrintStack => "stack", - Self::Step => "step", + Self::Step(_) => "step", + Self::StepOver(_) => "step_over", + Self::StepOut => "step_out", Self::Continue => "continue", Self::Breakpoint(_) => "breakpoint ", Self::DeleteBreakpoint(_) => "delete ", @@ -36,7 +43,9 @@ impl DebugCommand { pub fn commands() -> Vec { vec![ Self::PrintStack, - Self::Step, + Self::Step(0), + Self::StepOver(0), + Self::StepOut, Self::Continue, Self::Breakpoint("".to_string()), Self::DeleteBreakpoint("".to_string()), @@ -45,6 +54,17 @@ impl DebugCommand { } } +fn parse_number(s: &str) -> Result { + if s.trim_start().is_empty() { + return Ok(1); + } + let n = s.trim_start().parse::(); + if n.is_err() { + return Err("Step count must be a number".to_string()); + } + Ok(n.unwrap()) +} + impl FromStr for DebugCommand { type Err = String; @@ -54,9 +74,19 @@ impl FromStr for DebugCommand { if s.starts_with(PrintStack.debug_string()) { return Ok(PrintStack); } - if s.starts_with(Step.debug_string()) { - return Ok(Step); + + if s.starts_with(StepOut.debug_string()) { + return Ok(StepOut); } + + if let Some(n) = s.strip_prefix(StepOver(0).debug_string()) { + return Ok(StepOver(parse_number(n)?)); + } + + if let Some(n) = s.strip_prefix(Step(0).debug_string()) { + return Ok(Step(parse_number(n)?)); + } + if s.starts_with(Continue.debug_string()) { return Ok(Continue); } @@ -82,45 +112,99 @@ impl FromStr for DebugCommand { } #[derive(Debug)] +#[allow(unused)] pub(crate) struct DebugContext { breakpoints: BTreeSet, - should_take_input: bool, + input_checker: InputChecker, +} + +#[derive(Debug)] +#[allow(unused)] +enum InputChecker { + StepRemaining(usize), + StepOverRemaining { + stack_depth: usize, + remaining: usize, + }, + StepOut { + target_stack_depth: usize, + }, + Continue, } impl DebugContext { + #[allow(unused)] pub(crate) fn new() -> Self { Self { breakpoints: BTreeSet::new(), - should_take_input: true, + input_checker: InputChecker::StepRemaining(1), } } + #[allow(unused)] pub(crate) fn debug_loop( &mut self, function: &LoadedFunction, locals: &Locals, pc: u16, - instr: &Bytecode, + instr: &Instruction, runtime_environment: &RuntimeEnvironment, interpreter: &dyn InterpreterDebugInterface, ) { let instr_string = format!("{:?}", instr); - let function_string = function.name_as_pretty_string(); - let breakpoint_hit = self.breakpoints.contains(&function_string) - || self - .breakpoints - .iter() - .any(|bp| instr_string[..].starts_with(bp.as_str())); + let function_string = format!("{}::{}", function.name_as_pretty_string(), pc); + let breakpoint_hit = self + .breakpoints + .iter() + .any(|bp| instr_string[..].starts_with(bp.as_str()) || function_string.contains(bp)); + + let should_take_input = match &mut self.input_checker { + InputChecker::StepRemaining(n) => { + if *n == 1 { + self.input_checker = InputChecker::Continue; + true + } else { + *n -= 1; + false + } + }, + InputChecker::StepOverRemaining { + stack_depth, + remaining, + } => { + if *stack_depth >= interpreter.get_stack_frames(usize::MAX).stack_trace().len() { + if *remaining == 1 { + self.input_checker = InputChecker::Continue; + true + } else { + *remaining -= 1; + false + } + } else { + false + } + }, + InputChecker::StepOut { target_stack_depth } => { + if *target_stack_depth + == interpreter.get_stack_frames(usize::MAX).stack_trace().len() + { + self.input_checker = InputChecker::Continue; + true + } else { + false + } + }, + InputChecker::Continue => false, + }; - if self.should_take_input || breakpoint_hit { - self.should_take_input = true; + if should_take_input || breakpoint_hit { if breakpoint_hit { let bp_match = self .breakpoints .iter() .find(|bp| instr_string.starts_with(bp.as_str())) - .unwrap() - .clone(); + .cloned() + .unwrap_or(function_string.clone()); println!( "Breakpoint {} hit with instruction {}", bp_match, instr_string @@ -138,12 +222,22 @@ impl DebugContext { Ok(_) => match input.parse::() { Err(err) => println!("{}", err), Ok(command) => match command { - DebugCommand::Step => { - self.should_take_input = true; + DebugCommand::Step(n) => { + self.input_checker = InputChecker::StepRemaining(n); + break; + }, + DebugCommand::StepOver(n) => { + self.input_checker = InputChecker::StepOverRemaining { + stack_depth: interpreter + .get_stack_frames(usize::MAX) + .stack_trace() + .len(), + remaining: n, + }; break; }, DebugCommand::Continue => { - self.should_take_input = false; + self.input_checker = InputChecker::Continue; break; }, DebugCommand::Breakpoint(breakpoint) => { @@ -152,6 +246,18 @@ impl DebugContext { DebugCommand::DeleteBreakpoint(breakpoint) => { self.breakpoints.remove(&breakpoint); }, + DebugCommand::StepOut => { + let stack_depth = + interpreter.get_stack_frames(usize::MAX).stack_trace().len(); + if stack_depth == 0 { + println!("No stack frames to step out of"); + } else { + self.input_checker = InputChecker::StepOut { + target_stack_depth: stack_depth - 1, + }; + break; + } + }, DebugCommand::PrintBreakpoints => self .breakpoints .iter() @@ -176,7 +282,7 @@ impl DebugContext { println!(" Locals:"); if !function.local_tys().is_empty() { let mut s = String::new(); - values::debug::print_locals(&mut s, locals).unwrap(); + values::debug::print_locals(&mut s, locals, false).unwrap(); println!("{}", s); } else { println!(" (none)"); diff --git a/third_party/move/move-vm/runtime/src/execution_tracing/mod.rs b/third_party/move/move-vm/runtime/src/execution_tracing/mod.rs new file mode 100644 index 00000000000..f92702bd72e --- /dev/null +++ b/third_party/move/move-vm/runtime/src/execution_tracing/mod.rs @@ -0,0 +1,11 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Defines trace types and ability to replay traces after execution. + +mod recorders; +pub use recorders::{FullTraceRecorder, NoOpTraceRecorder, TraceRecorder}; + +mod trace; +pub use trace::Trace; +pub(crate) use trace::TraceCursor; diff --git a/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs b/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs new file mode 100644 index 00000000000..8c4c061d742 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs @@ -0,0 +1,199 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Interfaces and implementations for [Trace] collection. + +use crate::{ + execution_tracing::{trace::DynamicCall, Trace}, + LoadedFunction, +}; +use bitvec::vec::BitVec; +use fxhash::FxHasher64; +use move_core_types::function::ClosureMask; +use move_vm_types::instr::Instruction; +use std::hash::{Hash, Hasher}; + +/// Interface for recording the trace at runtime. It is sufficient to record branch decisions as +/// well as dynamic function calls originating from closures. +pub trait TraceRecorder { + /// Returns true if the trace is being collected. + fn is_enabled(&self) -> bool; + + /// Called in the end of execution to produce a final trace, suitable for replay. + fn finish(self) -> Trace; + + /// Called after successful execution of a bytecode instruction. It is crucial that the trace + /// records only successful instructions. + fn record_successful_instruction(&mut self, instr: &Instruction); + + /// Called for every successfully executed conditional branch. + fn record_branch_outcome(&mut self, taken: bool); + + /// Called for every successful set-up of the entrypoint (entry function or script). That is, + /// setting up frame, stack, and other structures before actually executing the bytecode. + fn record_entrypoint(&mut self, function: &LoadedFunction); + + /// Called for every successful set-up of the closure call (i.e., immediately before the first + /// instruction of the callee is executed). + fn record_call_closure(&mut self, function: &LoadedFunction, mask: ClosureMask); +} + +/// Records the fingerprint of executed bytecode instructions to check trace replay integrity. +#[derive(Default)] +pub(crate) struct BytecodeFingerprintRecorder { + // Use fast hasher as we do not care about collisions but mostly about performance. + hasher: FxHasher64, +} + +impl BytecodeFingerprintRecorder { + pub(crate) fn record(&mut self, instr: &Instruction) { + instr.hash(&mut self.hasher); + } + + pub(crate) fn finish(&self) -> u64 { + self.hasher.finish() + } +} + +/// Recorder that collects the full trace of execution. Records the number of successfully executed +/// instructions, branch outcomes and closure calls. +pub struct FullTraceRecorder { + /// Number of successfully executed instructions. + ticks: u64, + /// Records the fingerprint of the trace, for extra security. + fingerprint_recorder: BytecodeFingerprintRecorder, + /// Branch outcomes (taken or not taken), stored as a bit-vector. + branch_outcomes: BitVec, + /// Dynamic call outcomes. + calls: Vec, +} + +impl FullTraceRecorder { + /// Returns a new empty recorder ready for trace collection. + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + Self { + ticks: 0, + fingerprint_recorder: BytecodeFingerprintRecorder::default(), + branch_outcomes: BitVec::with_capacity(64), + calls: vec![], + } + } +} + +impl TraceRecorder for FullTraceRecorder { + #[inline(always)] + fn is_enabled(&self) -> bool { + true + } + + fn finish(self) -> Trace { + Trace::from_recorder( + self.ticks, + self.fingerprint_recorder.finish(), + self.branch_outcomes, + self.calls, + ) + } + + #[inline(always)] + fn record_successful_instruction(&mut self, instr: &Instruction) { + self.ticks += 1; + self.fingerprint_recorder.record(instr); + } + + #[inline(always)] + fn record_branch_outcome(&mut self, taken: bool) { + self.branch_outcomes.push(taken); + } + + #[inline(always)] + fn record_entrypoint(&mut self, function: &LoadedFunction) { + self.calls.push(DynamicCall::Entrypoint(function.clone())); + } + + #[inline(always)] + fn record_call_closure(&mut self, function: &LoadedFunction, mask: ClosureMask) { + self.calls + .push(DynamicCall::Closure(function.clone(), mask)); + } +} + +/// No-op instance of recorder in case there is no need to collect execution trace at runtime. +pub struct NoOpTraceRecorder; + +impl TraceRecorder for NoOpTraceRecorder { + #[inline(always)] + fn is_enabled(&self) -> bool { + false + } + + fn finish(self) -> Trace { + Trace::empty() + } + + #[inline(always)] + fn record_successful_instruction(&mut self, _instr: &Instruction) {} + + #[inline(always)] + fn record_branch_outcome(&mut self, _taken: bool) {} + + #[inline(always)] + fn record_entrypoint(&mut self, _function: &LoadedFunction) {} + + #[inline(always)] + fn record_call_closure(&mut self, _function: &LoadedFunction, _mask: ClosureMask) {} +} + +#[cfg(test)] +mod testing { + use super::*; + use crate::execution_tracing::TraceCursor; + use claims::assert_ok_eq; + + #[test] + fn test_full_recorder_is_enabled() { + let recorder = FullTraceRecorder::new(); + assert!(recorder.is_enabled()); + + let recorder = NoOpTraceRecorder; + assert!(!recorder.is_enabled()); + } + + #[test] + fn test_ticks_recorded() { + let mut recorder = FullTraceRecorder::new(); + assert_eq!(recorder.ticks, 0); + + recorder.record_successful_instruction(&Instruction::Nop); + assert_eq!(recorder.ticks, 1); + + for _ in 0..10 { + recorder.record_successful_instruction(&Instruction::Nop); + } + assert_eq!(recorder.ticks, 11); + } + + #[test] + fn test_branches_recorded() { + let mut recorder = FullTraceRecorder::new(); + + let expected = [ + true, true, false, true, false, false, false, true, false, false, true, true, true, + ]; + for taken in expected { + recorder.record_branch_outcome(taken); + } + + let trace = recorder.finish(); + assert!(!trace.is_empty()); + + let mut cursor = TraceCursor::new(&trace); + for taken in expected { + let recorded = cursor.consume_branch(); + assert_ok_eq!(recorded, taken); + } + assert!(cursor.consume_branch().is_err()); + assert!(cursor.is_done()); + } +} diff --git a/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs b/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs new file mode 100644 index 00000000000..d309cf42557 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs @@ -0,0 +1,246 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Defines the trace data structure which is sufficient to replay Move program execution without +//! requiring any data accesses (only access to code loader is needed). + +use crate::{execution_tracing::recorders::BytecodeFingerprintRecorder, LoadedFunction}; +use bitvec::vec::BitVec; +use move_binary_format::errors::{PartialVMError, PartialVMResult}; +use move_core_types::function::ClosureMask; +use move_vm_types::instr::Instruction; + +/// A non-static call record in the trace. Used for entry-points and closures. +#[derive(Clone)] +pub(crate) enum DynamicCall { + Entrypoint(LoadedFunction), + Closure(LoadedFunction, ClosureMask), +} + +/// Trace of execution of a program that records information sufficient to replay executed +/// instructions: +/// 1. Number of successfully executed instructions (ticks). +/// 2. Outcomes of every executed conditional branch. +/// 3. A vector of functions called via closures. +#[derive(Clone)] +pub struct Trace { + /// Number of successfully executed instructions. + ticks: u64, + /// Fingerprint of all successfully executed instructions. + fingerprint: u64, + /// Record of all outcomes of conditional branches (taken and not taken). + branch_outcomes: BitVec, + /// Record of all functions called via closures. Note that the static calls are not recorded to + /// keep the trace smaller (while giving up the ability to resolve calls without data context + /// when replaying the trace). + calls: Vec, +} + +impl Default for Trace { + fn default() -> Self { + Self::empty() + } +} + +impl Trace { + /// Returns an empty trace. + pub fn empty() -> Self { + Self { + ticks: 0, + fingerprint: 0, + branch_outcomes: BitVec::new(), + calls: vec![], + } + } + + /// Returns a trace from recorded data. + pub(crate) fn from_recorder( + ticks: u64, + fingerprint: u64, + branch_outcomes: BitVec, + calls: Vec, + ) -> Self { + Self { + ticks, + fingerprint, + branch_outcomes, + calls, + } + } + + /// Returns true if the trace has no recorded instructions and no branches / calls recorded. + pub fn is_empty(&self) -> bool { + self.ticks == 0 && self.branch_outcomes.len() == 0 && self.calls.len() == 0 + } + + /// Returns the number of recorded instructions. + pub fn num_recorded_instructions(&self) -> u64 { + self.ticks + } + + /// Returns the number of recorded conditional branch outcomes. + pub fn num_recorded_branch_outcomes(&self) -> usize { + self.branch_outcomes.len() + } + + /// Returns the number of recorded dynamic calls. + pub fn num_recorded_calls(&self) -> usize { + self.calls.len() + } + + /// For testing purposes only, displays the collected trace. + #[cfg(any(test, feature = "testing"))] + pub fn to_string_for_tests(&self) -> String { + use std::fmt::Write; + + let mut result = String::new(); + + writeln!(result, "instructions: {}", self.ticks).unwrap(); + writeln!(result, "fingerprint: {}", self.fingerprint).unwrap(); + write!(result, "branch_outcomes: ").unwrap(); + for bit in self.branch_outcomes.iter() { + result.push(if *bit { '1' } else { '0' }); + } + result.push('\n'); + + let ty_args_str = |f: &LoadedFunction| { + if f.ty_args().is_empty() { + "".to_string() + } else { + // We have only runtime types available, so keep as is. + "<..>".to_string() + } + }; + + writeln!(result, "calls:").unwrap(); + for call in &self.calls { + match call { + DynamicCall::Entrypoint(func) => { + writeln!( + result, + " entrypoint {}{}", + func.name_as_pretty_string(), + ty_args_str(func) + ) + .unwrap(); + }, + DynamicCall::Closure(func, mask) => { + writeln!( + result, + " closure {}{} {}", + func.name_as_pretty_string(), + ty_args_str(func), + mask + ) + .unwrap(); + }, + } + } + + result + } +} + +/// Replays the trace keeping track of executed branches and dynamic calls so far. +pub struct TraceCursor<'a> { + /// Trace to replay. + trace: &'a Trace, + /// Number of instructions still left to replay. + instructions_remaining: u64, + /// Fingerprint of the replayed trace. + fingerprint_recorder: BytecodeFingerprintRecorder, + /// Index into next branch target to consume, initially 0. + branch_cursor: usize, + /// Index into next call target to consume, initially 0. + call_cursor: usize, +} + +impl<'a> TraceCursor<'a> { + /// Returns a new cursor for replaying the provided trace. + pub fn new(trace: &'a Trace) -> Self { + Self { + trace, + instructions_remaining: trace.ticks, + fingerprint_recorder: BytecodeFingerprintRecorder::default(), + branch_cursor: 0, + call_cursor: 0, + } + } + + /// Returns true if there are no instructions remaining to replay. The caller is responsible to + /// ensure the invariant that all branch targets and all closure call targets are consumed + /// holds. This is a cheap check and should be used in replay interpreter loop instead of + /// [Self::is_done]. + #[inline(always)] + pub(crate) fn no_instructions_remaining(&self) -> bool { + self.instructions_remaining == 0 + } + + /// Returns true if the trace is fully replayed - no instructions remaining, no more branches + /// to consume, no more dynamic calls to consume. Do not use in the hot interpreter loop and + /// prefer [Self::no_instructions_remaining] for a faster check. + pub(crate) fn is_done(&self) -> bool { + self.no_instructions_remaining() + && self.fingerprint_recorder.finish() == self.trace.fingerprint + && self.branch_cursor == self.trace.branch_outcomes.len() + && self.call_cursor == self.trace.calls.len() + } + + /// Decrements a tick (equivalent to replay of an instruction). The caller must ensure it does + /// not underflow. + #[inline(always)] + pub(crate) fn consume_instruction_unchecked(&mut self, instr: &Instruction) { + self.instructions_remaining -= 1; + self.fingerprint_recorder.record(instr); + } + + /// Processes a conditional branch. Returns [None] if branch was not recorded. + #[inline(always)] + pub(crate) fn consume_branch(&mut self) -> PartialVMResult { + let i = self.branch_cursor; + if i < self.trace.branch_outcomes.len() { + self.branch_cursor = i + 1; + Ok(self.trace.branch_outcomes[i]) + } else { + Err(PartialVMError::new_invariant_violation( + "All conditional branches must be recorded", + )) + } + } + + /// Processes an entrypoint. Returns [None] if entrypoint call was not recorded. + #[inline(always)] + pub(crate) fn consume_entrypoint(&mut self) -> PartialVMResult<&LoadedFunction> { + let target = self + .trace + .calls + .get(self.call_cursor) + .ok_or_else(|| PartialVMError::new_invariant_violation("Entrypoint not found"))?; + self.call_cursor += 1; + match target { + DynamicCall::Entrypoint(target) => Ok(target), + DynamicCall::Closure(_, _) => Err(PartialVMError::new_invariant_violation( + "Expected to consume an entrypoint, but found a closure", + )), + } + } + + /// Processes a closure. Returns [None] if closure call was not recorded. + #[inline(always)] + pub(crate) fn consume_closure_call( + &mut self, + ) -> PartialVMResult<(&LoadedFunction, ClosureMask)> { + let target = self + .trace + .calls + .get(self.call_cursor) + .ok_or_else(|| PartialVMError::new_invariant_violation("Closure not found"))?; + self.call_cursor += 1; + match target { + DynamicCall::Closure(target, mask) => Ok((target, *mask)), + DynamicCall::Entrypoint(_) => Err(PartialVMError::new_invariant_violation( + "Expected to consume a closure, but found an entrypoint", + )), + } + } +} diff --git a/third_party/move/move-vm/runtime/src/frame.rs b/third_party/move/move-vm/runtime/src/frame.rs index 3523383a331..499f59badcf 100644 --- a/third_party/move/move-vm/runtime/src/frame.rs +++ b/third_party/move/move-vm/runtime/src/frame.rs @@ -4,10 +4,13 @@ use crate::{ config::VMConfig, frame_type_cache::FrameTypeCache, + interpreter::Stack, loader::{FunctionHandle, LoadedFunctionOwner, StructVariantInfo, VariantFieldInfo}, + module_traversal::TraversalContext, reentrancy_checker::CallType, runtime_type_checks::RuntimeTypeCheck, - LoadedFunction, ModuleStorage, + storage::loader::traits::FunctionDefinitionLoader, + LoadedFunction, }; use move_binary_format::{ access::{ModuleAccess, ScriptAccess}, @@ -24,31 +27,53 @@ use move_core_types::{ ability::Ability, account_address::AccountAddress, gas_algebra::NumTypeNodes, identifier::IdentStr, language_storage::ModuleId, vm_status::StatusCode, }; +use move_vm_profiler::FnGuard; use move_vm_types::{ gas::GasMeter, loaded_data::{ runtime_access_specifier::{AccessSpecifierEnv, AddressSpecifierFunction}, runtime_types::{AbilityInfo, StructType, Type, TypeBuilder}, }, + ty_interner::{InternedTypePool, TypeVecId}, values::Locals, }; use std::{cell::RefCell, rc::Rc, sync::Arc}; +/// Represents types of locals of a Move function. Actual types are only need for runtime checks, +/// and for non-generic functions can be borrowed directly from the function definition. For +/// generic functions, type instantiations are cached by interpreter. +pub(crate) enum LocalTys { + /// Used when runtime type checks are not enabled. + None, + /// Used for non-generic functions to avoid type clones around locals. + BorrowFromFunction, + /// Used for generic functions, where types are cached per-instantiation. + BorrowFromFunctionGeneric(Rc<[Type]>), +} + /// Represents the execution context for a function. When calls are made, frames are /// pushed and then popped to/from the call stack. pub(crate) struct Frame { pub(crate) pc: u16, - ty_builder: TypeBuilder, + pub(crate) ty_builder: TypeBuilder, // Currently being executed function. pub(crate) function: Rc, + // Guard used to profile the execution of this function. + // Note that this is only stored to keep it alive for the lifetime of the frame. + // It is an option so we can pass `None` during the runtime type checks. + pub(crate) _guard: Option, // How this frame was established. - call_type: CallType, + pub(crate) call_type: CallType, // Locals for this execution context and their instantiated types. pub(crate) locals: Locals, - local_tys: Vec, + pub(crate) local_tys: LocalTys, // Cache of types accessed in this frame, to improve performance when accessing // and constructing types. pub(crate) frame_cache: Rc>, + // Saved value stack size of the caller that created this frame. + pub(crate) caller_value_stack_size: u32, + // Saved type stack size of the caller that created this frame. + pub(crate) caller_type_stack_size: u32, } impl AccessSpecifierEnv for Frame { @@ -65,9 +90,12 @@ macro_rules! build_loaded_function { ($function_name:ident, $idx_ty:ty, $get_function_handle:ident) => { pub(crate) fn $function_name( &self, - module_storage: &impl ModuleStorage, + loader: &impl FunctionDefinitionLoader, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, idx: $idx_ty, verified_ty_args: Vec, + ty_args_id: TypeVecId, ) -> PartialVMResult { match self.function.owner() { LoadedFunctionOwner::Module(module) => { @@ -77,15 +105,19 @@ macro_rules! build_loaded_function { (Ok(LoadedFunction { owner: LoadedFunctionOwner::Module(module.clone()), ty_args: verified_ty_args, + ty_args_id, function: function.clone(), })) }, FunctionHandle::Remote { module, name } => self .build_loaded_function_from_name_and_ty_args( - module_storage, + loader, + gas_meter, + traversal_context, module, name, verified_ty_args, + ty_args_id, ), } }, @@ -98,10 +130,13 @@ macro_rules! build_loaded_function { .with_message("Scripts never have local functions".to_string())), FunctionHandle::Remote { module, name } => self .build_loaded_function_from_name_and_ty_args( - module_storage, + loader, + gas_meter, + traversal_context, module, name, verified_ty_args, + ty_args_id, ), } }, @@ -123,33 +158,66 @@ impl Frame { function_instantiation_handle_at ); + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn make_new_frame( gas_meter: &mut impl GasMeter, call_type: CallType, vm_config: &VMConfig, function: Rc, + guard: Option, locals: Locals, frame_cache: Rc>, + stack: &Stack, ) -> PartialVMResult { let ty_args = function.ty_args(); - for ty in function.local_tys() { - gas_meter - .charge_create_ty(NumTypeNodes::new(ty.num_nodes_in_subst(ty_args)? as u64))?; - } let ty_builder = vm_config.ty_builder.clone(); - let local_tys = if RTTCheck::should_perform_checks() { - if ty_args.is_empty() { - function.local_tys().to_vec() + let local_tys = if ty_args.is_empty() { + // Function is not generic - avoid cloning types. + for ty in function.local_tys() { + gas_meter.charge_create_ty(NumTypeNodes::new(ty.num_nodes() as u64))?; + } + + if RTTCheck::should_perform_checks(&function.function) { + LocalTys::BorrowFromFunction } else { - function - .local_tys() - .iter() - .map(|ty| ty_builder.create_ty_with_subst(ty, ty_args)) - .collect::>>()? + LocalTys::None } } else { - vec![] + // Try cached instantiated locals in frame cache. This way we instantiate only once per + // usage of the function. + let mut cache_borrow = frame_cache.borrow_mut(); + if let Some(local_ty_counts) = cache_borrow.instantiated_local_ty_counts.as_ref() { + for cnt in local_ty_counts.iter() { + gas_meter.charge_create_ty(*cnt)?; + } + } else { + let local_tys = function.local_tys(); + let mut local_ty_counts = Vec::with_capacity(local_tys.len()); + for ty in local_tys { + let cnt = NumTypeNodes::new(ty.num_nodes_in_subst(ty_args)? as u64); + gas_meter.charge_create_ty(cnt)?; + local_ty_counts.push(cnt); + } + cache_borrow.instantiated_local_ty_counts = Some(Rc::from(local_ty_counts)); + } + + if RTTCheck::should_perform_checks(&function.function) { + if let Some(local_tys) = cache_borrow.instantiated_local_tys.as_ref().cloned() { + LocalTys::BorrowFromFunctionGeneric(local_tys) + } else { + let local_tys: Rc<[Type]> = function + .local_tys() + .iter() + .map(|ty| ty_builder.create_ty_with_subst(ty, ty_args)) + .collect::>>() + .map(Rc::from)?; + cache_borrow.instantiated_local_tys = Some(local_tys.clone()); + LocalTys::BorrowFromFunctionGeneric(local_tys) + } + } else { + LocalTys::None + } }; Ok(Frame { @@ -157,9 +225,12 @@ impl Frame { ty_builder, locals, function, + _guard: guard, call_type, local_tys, frame_cache, + caller_value_stack_size: stack.value.len() as u32, + caller_type_stack_size: stack.types.len() as u32, }) } @@ -171,12 +242,27 @@ impl Frame { self.call_type } + /// Returns a local type at specified index. Used for runtime type checks only, and if called + /// in non-type checking context will panic! + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn local_ty_at(&self, idx: usize) -> &Type { - &self.local_tys[idx] + match &self.local_tys { + LocalTys::None => { + unreachable!("Local types are not used when there are no runtime type checks") + }, + LocalTys::BorrowFromFunction => &self.function.local_tys()[idx], + LocalTys::BorrowFromFunctionGeneric(tys) => &tys[idx], + } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn check_local_tys_have_drop_ability(&self) -> PartialVMResult<()> { - for (idx, ty) in self.local_tys.iter().enumerate() { + let local_tys = match &self.local_tys { + LocalTys::None => return Ok(()), + LocalTys::BorrowFromFunction => self.function.local_tys(), + LocalTys::BorrowFromFunctionGeneric(tys) => tys, + }; + for (idx, ty) in local_tys.iter().enumerate() { if !self.locals.is_invalid(idx)? { ty.paranoid_check_has_ability(Ability::Drop)?; } @@ -184,6 +270,12 @@ impl Frame { Ok(()) } + #[cfg_attr(feature = "force-inline", inline(always))] + pub(crate) fn untrusted_code(&self) -> bool { + !self.function.function.is_trusted + } + + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn constant_at(&self, idx: ConstantPoolIndex) -> &Constant { use LoadedFunctionOwner::*; match self.function.owner() { @@ -192,6 +284,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn get_struct_ty(&self, idx: StructDefinitionIndex) -> Type { use LoadedFunctionOwner::*; let struct_ty = match self.function.owner() { @@ -241,6 +334,7 @@ impl Frame { ) } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn get_field_ty(&self, idx: FieldHandleIndex) -> PartialVMResult<&Type> { use LoadedFunctionOwner::*; match self.function.owner() { @@ -252,6 +346,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn get_generic_field_ty( &self, idx: FieldInstantiationIndex, @@ -299,6 +394,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn get_struct(&self, idx: StructDefinitionIndex) -> &Arc { use LoadedFunctionOwner::*; match self.function.owner() { @@ -396,6 +492,7 @@ impl Frame { ) } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_offset(&self, idx: FieldHandleIndex) -> usize { use LoadedFunctionOwner::*; match self.function.owner() { @@ -404,6 +501,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_instantiation_offset(&self, idx: FieldInstantiationIndex) -> usize { use LoadedFunctionOwner::*; match self.function.owner() { @@ -412,6 +510,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_count(&self, idx: StructDefinitionIndex) -> u16 { use LoadedFunctionOwner::*; match self.function.owner() { @@ -420,6 +519,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_instantiation_count(&self, idx: StructDefInstantiationIndex) -> u16 { use LoadedFunctionOwner::*; match self.function.owner() { @@ -428,6 +528,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_handle_to_struct(&self, idx: FieldHandleIndex) -> Type { use LoadedFunctionOwner::*; match self.function.owner() { @@ -439,6 +540,7 @@ impl Frame { } } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_instantiation_to_struct( &self, idx: FieldInstantiationIndex, @@ -458,11 +560,12 @@ impl Frame { pub(crate) fn instantiate_generic_function( &self, + ty_pool: &InternedTypePool, gas_meter: Option<&mut impl GasMeter>, idx: FunctionInstantiationIndex, - ) -> PartialVMResult> { + ) -> PartialVMResult<(Vec, TypeVecId)> { use LoadedFunctionOwner::*; - let instantiation = match self.function.owner() { + let (instantiation, ty_args_id) = match self.function.owner() { Module(module) => module.function_instantiation_at(idx.0), Script(script) => script.function_instantiation_at(idx.0), }; @@ -479,30 +582,32 @@ impl Frame { .iter() .map(|ty| self.ty_builder.create_ty_with_subst(ty, ty_args)) .collect::>>()?; - Ok(instantiation) + let ty_args_id = match ty_args_id { + Some(ty_args_id) => ty_args_id, + // We can hit this case where original type args were only a partial instantiation. + None => ty_pool.intern_ty_args(&instantiation), + }; + + Ok((instantiation, ty_args_id)) } pub(crate) fn build_loaded_function_from_name_and_ty_args( &self, - module_storage: &impl ModuleStorage, + loader: &impl FunctionDefinitionLoader, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, module_id: &ModuleId, function_name: &IdentStr, verified_ty_args: Vec, + ty_args_id: TypeVecId, ) -> PartialVMResult { - let (module, function) = module_storage - .fetch_function_definition(module_id.address(), module_id.name(), function_name) - .map_err(|_| { - // Note: legacy loader implementation used this error, so we need to remap. - PartialVMError::new(StatusCode::FUNCTION_RESOLUTION_FAILURE).with_message(format!( - "Module or function do not exist for {}::{}::{}", - module_id.address(), - module_id.name(), - function_name - )) - })?; + let (module, function) = loader + .load_function_definition(gas_meter, traversal_context, module_id, function_name) + .map_err(|err| err.to_partial())?; Ok(LoadedFunction { owner: LoadedFunctionOwner::Module(module), ty_args: verified_ty_args, + ty_args_id, function, }) } diff --git a/third_party/move/move-vm/runtime/src/frame_type_cache.rs b/third_party/move/move-vm/runtime/src/frame_type_cache.rs index f60de5209ef..3bad54cd7c1 100644 --- a/third_party/move/move-vm/runtime/src/frame_type_cache.rs +++ b/third_party/move/move-vm/runtime/src/frame_type_cache.rs @@ -14,34 +14,15 @@ use move_core_types::gas_algebra::NumTypeNodes; use move_vm_types::loaded_data::runtime_types::Type; use std::{cell::RefCell, collections::BTreeMap, rc::Rc}; -#[allow(dead_code)] -pub(crate) trait RuntimeCacheTraits { - fn caches_enabled() -> bool; -} - -pub(crate) struct NoRuntimeCaches; -pub(crate) struct AllRuntimeCaches; - -impl RuntimeCacheTraits for NoRuntimeCaches { - fn caches_enabled() -> bool { - false - } -} - -impl RuntimeCacheTraits for AllRuntimeCaches { - fn caches_enabled() -> bool { - true - } -} - /// Variants for each individual instruction cache. Should make sure /// that the memory footprint of each variant is small. This is an /// enum that is expected to grow in the future. #[derive(Clone)] -#[allow(dead_code)] pub(crate) enum PerInstructionCache { Nothing, + #[allow(dead_code)] Pack(u16), + #[allow(dead_code)] PackGeneric(u16), Call(Rc, Rc>), CallGeneric(Rc, Rc>), @@ -65,15 +46,6 @@ pub(crate) struct FrameTypeCache { variant_field_instantiation: BTreeMap, single_sig_token_type: BTreeMap, - /// Recursive frame cache for a function that is called from the - /// current frame. It is indexed by FunctionInstantiationindex or - /// FunctionHandleIndex for non-generic functions. Note that - /// whenever a function with the same `index` is called, the - /// structures stored in that function's frame cache do not change. - pub(crate) generic_sub_frame_cache: - BTreeMap, Rc>)>, - pub(crate) sub_frame_cache: - BTreeMap, Rc>)>, /// Stores a variant for each individual instruction in the /// function's bytecode. We keep the size of the variant to be /// small. The caches are indexed by the index of the given @@ -85,51 +57,56 @@ pub(crate) struct FrameTypeCache { /// guaranteed that everything will be exactly the same as when we /// did the insertion. pub(crate) per_instruction_cache: Vec, + + pub(crate) function_cache: + BTreeMap, Rc>)>, + pub(crate) generic_function_cache: + BTreeMap, Rc>)>, + + /// Cached instantiated local types for generic functions. + pub(crate) instantiated_local_tys: Option>, + /// Cached number of type nodes per instantiated local type for gas charging re-use. + pub(crate) instantiated_local_ty_counts: Option>, } -impl FrameTypeCache { - #[inline(always)] - fn get_or( - map: &mut BTreeMap, - idx: K, - ty_func: F, - ) -> PartialVMResult<&V> - where - F: FnOnce(K) -> PartialVMResult, - { - match map.entry(idx) { - std::collections::btree_map::Entry::Occupied(entry) => Ok(entry.into_mut()), +macro_rules! get_or_insert { + ($map:expr, $idx:expr, $ty_func:tt) => { + match $map.entry($idx) { + std::collections::btree_map::Entry::Occupied(entry) => entry.into_mut(), std::collections::btree_map::Entry::Vacant(entry) => { - let v = ty_func(idx)?; - Ok(entry.insert(v)) + let v = { $ty_func }; + entry.insert(v) }, } - } + }; +} - #[inline(always)] +impl FrameTypeCache { + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_field_type_and_struct_type( &mut self, idx: FieldInstantiationIndex, frame: &Frame, ) -> PartialVMResult<((&Type, NumTypeNodes), (&Type, NumTypeNodes))> { let ((field_ty, field_ty_count), (struct_ty, struct_ty_count)) = - Self::get_or(&mut self.field_instantiation, idx, |idx| { + get_or_insert!(&mut self.field_instantiation, idx, { let struct_type = frame.field_instantiation_to_struct(idx)?; let struct_ty_count = NumTypeNodes::new(struct_type.num_nodes() as u64); let field_ty = frame.get_generic_field_ty(idx)?; let field_ty_count = NumTypeNodes::new(field_ty.num_nodes() as u64); - Ok(((field_ty, field_ty_count), (struct_type, struct_ty_count))) - })?; + ((field_ty, field_ty_count), (struct_type, struct_ty_count)) + }); Ok(((field_ty, *field_ty_count), (struct_ty, *struct_ty_count))) } + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_variant_field_type_and_struct_type( &mut self, idx: VariantFieldInstantiationIndex, frame: &Frame, ) -> PartialVMResult<((&Type, NumTypeNodes), (&Type, NumTypeNodes))> { let ((field_ty, field_ty_count), (struct_ty, struct_ty_count)) = - Self::get_or(&mut self.variant_field_instantiation, idx, |idx| { + get_or_insert!(&mut self.variant_field_instantiation, idx, { let info = frame.variant_field_instantiation_info_at(idx); let struct_type = frame.create_struct_instantiation_ty( &info.definition_struct_type, @@ -139,99 +116,98 @@ impl FrameTypeCache { let field_ty = frame.instantiate_ty(&info.uninstantiated_field_ty, &info.instantiation)?; let field_ty_count = NumTypeNodes::new(field_ty.num_nodes() as u64); - Ok(((field_ty, field_ty_count), (struct_type, struct_ty_count))) - })?; + ((field_ty, field_ty_count), (struct_type, struct_ty_count)) + }); Ok(((field_ty, *field_ty_count), (struct_ty, *struct_ty_count))) } - #[inline(always)] + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_struct_type( &mut self, idx: StructDefInstantiationIndex, frame: &Frame, ) -> PartialVMResult<(&Type, NumTypeNodes)> { - let (ty, ty_count) = Self::get_or(&mut self.struct_def_instantiation_type, idx, |idx| { + let (ty, ty_count) = get_or_insert!(&mut self.struct_def_instantiation_type, idx, { let ty = frame.get_generic_struct_ty(idx)?; let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); - Ok((ty, ty_count)) - })?; + (ty, ty_count) + }); Ok((ty, *ty_count)) } - #[inline(always)] + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_struct_variant_type( &mut self, idx: StructVariantInstantiationIndex, frame: &Frame, ) -> PartialVMResult<(&Type, NumTypeNodes)> { - let (ty, ty_count) = - Self::get_or(&mut self.struct_variant_instantiation_type, idx, |idx| { - let info = frame.get_struct_variant_instantiation_at(idx); - let ty = frame.create_struct_instantiation_ty( - &info.definition_struct_type, - &info.instantiation, - )?; - let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); - Ok((ty, ty_count)) - })?; + let (ty, ty_count) = get_or_insert!(&mut self.struct_variant_instantiation_type, idx, { + let info = frame.get_struct_variant_instantiation_at(idx); + let ty = frame.create_struct_instantiation_ty( + &info.definition_struct_type, + &info.instantiation, + )?; + let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); + (ty, ty_count) + }); Ok((ty, *ty_count)) } - #[inline(always)] + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_struct_fields_types( &mut self, idx: StructDefInstantiationIndex, frame: &Frame, ) -> PartialVMResult<&[(Type, NumTypeNodes)]> { - Ok(Self::get_or( + Ok(get_or_insert!( &mut self.struct_field_type_instantiation, idx, - |idx| { - Ok(frame + { + frame .instantiate_generic_struct_fields(idx)? .into_iter() .map(|ty| { let num_nodes = NumTypeNodes::new(ty.num_nodes() as u64); (ty, num_nodes) }) - .collect::>()) - }, - )?) + .collect::>() + } + )) } - #[inline(always)] + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_struct_variant_fields_types( &mut self, idx: StructVariantInstantiationIndex, frame: &Frame, ) -> PartialVMResult<&[(Type, NumTypeNodes)]> { - Ok(Self::get_or( + Ok(get_or_insert!( &mut self.struct_variant_field_type_instantiation, idx, - |idx| { - Ok(frame + { + frame .instantiate_generic_struct_variant_fields(idx)? .into_iter() .map(|ty| { let num_nodes = NumTypeNodes::new(ty.num_nodes() as u64); (ty, num_nodes) }) - .collect::>()) - }, - )?) + .collect::>() + } + )) } - #[inline(always)] + // note(inline): do not inline, increases size a lot, might even decrease the performance pub(crate) fn get_signature_index_type( &mut self, idx: SignatureIndex, frame: &Frame, ) -> PartialVMResult<(&Type, NumTypeNodes)> { - let (ty, ty_count) = Self::get_or(&mut self.single_sig_token_type, idx, |idx| { + let (ty, ty_count) = get_or_insert!(&mut self.single_sig_token_type, idx, { let ty = frame.instantiate_single_type(idx)?; let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); - Ok((ty, ty_count)) - })?; + (ty, ty_count) + }); Ok((ty, *ty_count)) } diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index b6af52e4f22..1f8fc468c8a 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -4,62 +4,112 @@ use crate::{ access_control::AccessControlState, - check_type_tag_dependencies_and_charge_gas, config::VMConfig, - data_cache::{DataCacheEntry, TransactionDataCache}, + data_cache::MoveVmDataCache, + execution_tracing::TraceRecorder, frame::Frame, - frame_type_cache::{ - AllRuntimeCaches, FrameTypeCache, NoRuntimeCaches, PerInstructionCache, RuntimeCacheTraits, - }, + frame_type_cache::{FrameTypeCache, PerInstructionCache}, + interpreter_caches::InterpreterFunctionCaches, loader::LazyLoadedFunction, module_traversal::TraversalContext, native_extensions::NativeContextExtensions, native_functions::NativeContext, reentrancy_checker::{CallType, ReentrancyChecker}, + runtime_ref_checks::{FullRuntimeRefCheck, NoRuntimeRefCheck, RefCheckState, RuntimeRefCheck}, runtime_type_checks::{ verify_pack_closure, FullRuntimeTypeCheck, NoRuntimeTypeCheck, RuntimeTypeCheck, + UntrustedOnlyRuntimeTypeCheck, }, storage::{ - dependencies_gas_charging::check_dependencies_and_charge_gas, - depth_formula_calculator::DepthFormulaCalculator, + loader::traits::Loader, ty_depth_checker::TypeDepthChecker, + ty_layout_converter::LayoutConverter, }, - trace, LoadedFunction, ModuleStorage, RuntimeEnvironment, + trace, LoadedFunction, RuntimeEnvironment, }; use fail::fail_point; +use itertools::Itertools; use move_binary_format::{ + errors, errors::*, - file_format::{ - AccessKind, Bytecode, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, - }, + file_format::{AccessKind, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex}, }; use move_core_types::{ account_address::AccountAddress, function::ClosureMask, gas_algebra::{NumArgs, NumBytes, NumTypeNodes}, language_storage::TypeTag, - vm_status::{StatusCode, StatusType}, + vm_status::{ + sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode, StatusType, + }, }; -use move_vm_metrics::{Timer, VM_TIMER}; +use move_vm_profiler::{FnGuard, Profiler, VM_PROFILER}; use move_vm_types::{ debug_write, debug_writeln, gas::{GasMeter, SimpleInstruction}, + instr::Instruction, loaded_data::{runtime_access_specifier::AccessInstance, runtime_types::Type}, natives::function::NativeResult, - resolver::ResourceResolver, + ty_interner::InternedTypePool, values::{ - self, AbstractFunction, Closure, GlobalValue, IntegerValue, Locals, Reference, SignerRef, - Struct, StructRef, VMValueCast, Value, Vector, VectorRef, + self, AbstractFunction, Closure, GlobalValue, Locals, Reference, SignerRef, Struct, + StructRef, VMValueCast, Value, Vector, VectorRef, }, views::TypeView, }; +use once_cell::sync::Lazy; use std::{ cell::RefCell, cmp::min, - collections::{btree_map, VecDeque}, - fmt::Write, + collections::{btree_map::Entry, BTreeSet, VecDeque}, + fmt::{Debug, Write}, rc::Rc, + str::FromStr, }; +/// A category of information which can be traced by the interpreter. +#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] +pub(crate) enum TraceCategory { + /// Unknown category name. An unknown category name can be used for local debugging. + Unknown(String), + /// Trace VM Error. + VMError, + /// Trace abort of given code. + Abort(u64), +} + +/// A set of categories to be traced as defined by environment variable, for example +/// `MOVE_TRACE_EXEC=abort(22),abort(33)`. +static MOVE_TRACE_EXEC: Lazy>> = Lazy::new(|| { + std::env::var("MOVE_TRACE_EXEC").ok().map(|str| { + str.split(',') + .map(|part| { + if part == "vm_error" { + return TraceCategory::VMError; + } + if let Some(mut s) = part.strip_prefix("abort(") { + s = s.strip_suffix(")").unwrap_or(s); + if let Ok(c) = u64::from_str(s) { + return TraceCategory::Abort(c); + } + } + TraceCategory::Unknown(part.to_string()) + }) + .collect() + }) +}); + +/// Macro for checking whether a certain trace category is active. +macro_rules! is_tracing_for { + ($category:expr) => {{ + if let Some(categories) = &*MOVE_TRACE_EXEC { + // Only evaluate $category when tracing is on. + categories.contains(&$category) + } else { + false + } + }}; +} + macro_rules! set_err_info { ($frame:ident, $e:expr) => {{ $e.at_code_offset($frame.function.index(), $frame.pc) @@ -86,17 +136,28 @@ pub(crate) trait InterpreterDebugInterface { /// /// An `Interpreter` instance is a stand alone execution context for a function. /// It mimics execution on a single thread, with an call stack and an operand stack. -pub(crate) struct InterpreterImpl<'ctx> { +pub(crate) struct InterpreterImpl<'ctx, LoaderImpl> { /// Operand stack, where Move `Value`s are stored for stack operations. pub(crate) operand_stack: Stack, /// The stack of active functions. call_stack: CallStack, /// VM configuration used by the interpreter. vm_config: &'ctx VMConfig, + /// Pool of interned types. + ty_pool: &'ctx InternedTypePool, /// The access control state. access_control: AccessControlState, /// Reentrancy checker. reentrancy_checker: ReentrancyChecker, + /// Loader to resolve functions and modules from remote storage. Ensures all module accesses + /// are metered. + loader: &'ctx LoaderImpl, + /// Checks depth of types of values. Used to bound packing too deep structs or vectors. + ty_depth_checker: &'ctx TypeDepthChecker<'ctx, LoaderImpl>, + /// Converts runtime types ([Type]) to layouts for (de)serialization. + layout_converter: &'ctx LayoutConverter<'ctx, LoaderImpl>, + /// State maintained for dynamic reference checks. + ref_state: RefCheckState, } struct TypeWithRuntimeEnvironment<'a, 'b> { @@ -113,150 +174,157 @@ impl TypeView for TypeWithRuntimeEnvironment<'_, '_> { impl Interpreter { /// Entrypoint into the interpreter. All external calls need to be routed through this /// function. - pub(crate) fn entrypoint( + pub(crate) fn entrypoint( function: LoadedFunction, args: Vec, - data_cache: &mut TransactionDataCache, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, + data_cache: &mut impl MoveVmDataCache, + function_caches: &mut InterpreterFunctionCaches, + loader: &LoaderImpl, + ty_depth_checker: &TypeDepthChecker, + layout_converter: &LayoutConverter, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, - ) -> VMResult> { + trace_logeer: &mut impl TraceRecorder, + ) -> VMResult> + where + LoaderImpl: Loader, + { InterpreterImpl::entrypoint( function, args, data_cache, - module_storage, - resource_resolver, + function_caches, + loader, + ty_depth_checker, + layout_converter, gas_meter, traversal_context, extensions, + trace_logeer, ) } } -impl InterpreterImpl<'_> { +impl InterpreterImpl<'_, LoaderImpl> +where + LoaderImpl: Loader, +{ /// Entrypoint into the interpreter. All external calls need to be routed through this /// function. pub(crate) fn entrypoint( function: LoadedFunction, args: Vec, - data_cache: &mut TransactionDataCache, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, + data_cache: &mut impl MoveVmDataCache, + function_caches: &mut InterpreterFunctionCaches, + loader: &LoaderImpl, + ty_depth_checker: &TypeDepthChecker, + layout_converter: &LayoutConverter, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, + trace_recorder: &mut impl TraceRecorder, ) -> VMResult> { let interpreter = InterpreterImpl { operand_stack: Stack::new(), call_stack: CallStack::new(), - vm_config: module_storage.runtime_environment().vm_config(), + vm_config: loader.runtime_environment().vm_config(), + ty_pool: loader.runtime_environment().ty_pool(), access_control: AccessControlState::default(), reentrancy_checker: ReentrancyChecker::default(), + loader, + ty_depth_checker, + layout_converter, + ref_state: RefCheckState::new(), }; + // Tracing and runtime checks (full or partial) are mutually exclusive because if we record + // the trace, the checks are done after execution via abstract interpretation during trace + // replay. + let paranoid_type_checks = + !trace_recorder.is_enabled() && interpreter.vm_config.paranoid_type_checks; + let optimize_trusted_code = + !trace_recorder.is_enabled() && interpreter.vm_config.optimize_trusted_code; + let paranoid_ref_checks = interpreter.vm_config.paranoid_ref_checks; + let function = Rc::new(function); - // TODO: remove Self::paranoid_type_checks fully to be replaced - // with the static RuntimeTypeCheck trait - if interpreter.vm_config.paranoid_type_checks { - interpreter.dispatch_execute_main::( - data_cache, - resource_resolver, - module_storage, - gas_meter, - traversal_context, - extensions, - function, - args, - ) - } else { - interpreter.dispatch_execute_main::( - data_cache, - resource_resolver, - module_storage, - gas_meter, - traversal_context, - extensions, - function, - args, - ) + macro_rules! execute_main { + ($type_check:ty, $ref_check:ty) => { + interpreter.execute_main::<$type_check, $ref_check>( + data_cache, + function_caches, + gas_meter, + traversal_context, + extensions, + trace_recorder, + function, + args, + ) + }; + } + + // Note: we have organized the code below from most-likely config to least-likely config. + match ( + paranoid_type_checks, + optimize_trusted_code, + paranoid_ref_checks, + ) { + (true, true, false) => execute_main!(UntrustedOnlyRuntimeTypeCheck, NoRuntimeRefCheck), + (true, false, false) => execute_main!(FullRuntimeTypeCheck, NoRuntimeRefCheck), + (true, true, true) => execute_main!(UntrustedOnlyRuntimeTypeCheck, FullRuntimeRefCheck), + (true, false, true) => execute_main!(FullRuntimeTypeCheck, FullRuntimeRefCheck), + (false, _, false) => execute_main!(NoRuntimeTypeCheck, NoRuntimeRefCheck), + (false, _, true) => execute_main!(NoRuntimeTypeCheck, FullRuntimeRefCheck), } } - fn load_generic_function( + /// Loads a generic function with instantiated type arguments. Does not perform any checks if + /// the function is callable (i.e., visible to the caller). The visibility check should be done + /// at the call-site. + fn load_generic_function_no_visibility_checks( &mut self, - module_storage: &impl ModuleStorage, - current_frame: &Frame, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, + current_frame: &Frame, idx: FunctionInstantiationIndex, ) -> VMResult { - let ty_args = current_frame - .instantiate_generic_function(Some(gas_meter), idx) + let (ty_args, ty_args_id) = current_frame + .instantiate_generic_function(self.ty_pool, Some(gas_meter), idx) .map_err(|e| set_err_info!(current_frame, e))?; let function = current_frame - .build_loaded_function_from_instantiation_and_ty_args(module_storage, idx, ty_args) + .build_loaded_function_from_instantiation_and_ty_args( + self.loader, + gas_meter, + traversal_context, + idx, + ty_args, + ty_args_id, + ) .map_err(|e| self.set_location(e))?; - - if self.vm_config.paranoid_type_checks { - self.check_friend_or_private_call(¤t_frame.function, &function)?; - } - Ok(function) } - fn load_function( + /// Loads a non-generic function. Does not perform any checks if the function is callable + /// (i.e., visible to the caller). The visibility check should be done at the call-site. + fn load_function_no_visibility_checks( &mut self, - module_storage: &impl ModuleStorage, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, current_frame: &Frame, fh_idx: FunctionHandleIndex, ) -> VMResult { + let ty_args_id = self.ty_pool.intern_ty_args(&[]); let function = current_frame - .build_loaded_function_from_handle_and_ty_args(module_storage, fh_idx, vec![]) - .map_err(|e| self.set_location(e))?; - - if self.vm_config.paranoid_type_checks { - self.check_friend_or_private_call(¤t_frame.function, &function)?; - } - - Ok(function) - } - - fn dispatch_execute_main( - self, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - extensions: &mut NativeContextExtensions, - function: Rc, - args: Vec, - ) -> VMResult> { - if self.vm_config.use_call_tree_and_instruction_cache { - self.execute_main::( - data_cache, - resource_resolver, - module_storage, - gas_meter, - traversal_context, - extensions, - function, - args, - ) - } else { - self.execute_main::( - data_cache, - resource_resolver, - module_storage, + .build_loaded_function_from_handle_and_ty_args( + self.loader, gas_meter, traversal_context, - extensions, - function, - args, + fh_idx, + vec![], + ty_args_id, ) - } + .map_err(|e| self.set_location(e))?; + Ok(function) } /// Main loop for the execution of a function. @@ -265,21 +333,24 @@ impl InterpreterImpl<'_> { /// function represented by the frame. Control comes back to this function on return or /// on call. When that happens the frame is changes to a new one (call) or to the one /// at the top of the stack (return). If the call stack is empty execution is completed. - fn execute_main( + fn execute_main( mut self, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, + function_caches: &mut InterpreterFunctionCaches, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, + trace_recorder: &mut impl TraceRecorder, function: Rc, args: Vec, ) -> VMResult> { - let mut locals = Locals::new(function.local_tys().len()); + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + + let num_locals = function.local_tys().len(); + let mut locals = Locals::new(num_locals); for (i, value) in args.into_iter().enumerate() { locals - .store_loc(i, value, self.vm_config.check_invariant_in_swap_loc) + .store_loc(i, value) .map_err(|e| self.set_location(e))?; } @@ -287,19 +358,23 @@ impl InterpreterImpl<'_> { .enter_function(None, &function, CallType::Regular) .map_err(|e| self.set_location(e))?; - let frame_cache = if RTCaches::caches_enabled() { - FrameTypeCache::make_rc_for_function(&function) + RTRCheck::init_entry(&function, &mut self.ref_state) + .map_err(|err| self.set_location(err))?; + + let frame_cache = if self.vm_config.enable_function_caches { + function_caches.get_or_create_frame_cache(&function) } else { FrameTypeCache::make_rc() }; - let mut current_frame = Frame::make_new_frame::( gas_meter, CallType::Regular, self.vm_config, function, + Some(fn_guard), locals, frame_cache, + &self.operand_stack, ) .map_err(|err| self.set_location(err))?; @@ -308,33 +383,41 @@ impl InterpreterImpl<'_> { .enter_function(¤t_frame, ¤t_frame.function) .map_err(|e| self.set_location(e))?; + trace_recorder.record_entrypoint(current_frame.function.as_ref()); loop { let exit_code = current_frame - .execute_code::( + .execute_code::( &mut self, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, + trace_recorder, ) .map_err(|err| self.attach_state_if_invariant_violation(err, ¤t_frame))?; match exit_code { ExitCode::Return => { - let non_ref_vals = current_frame - .locals - .drop_all_values() - .map(|(_idx, val)| val) - .collect::>(); + let non_ref_vals = current_frame.locals.drop_all_values(); - // TODO: Check if the error location is set correctly. gas_meter .charge_drop_frame(non_ref_vals.iter()) - .map_err(|e| self.set_location(e))?; + .map_err(|e| set_err_info!(current_frame, e))?; + + let actual_stack_size = self.operand_stack.value.len(); + let expected_stack_size = current_frame.function.return_tys().len() + + current_frame.caller_value_stack_size as usize; + if actual_stack_size != expected_stack_size { + let err = current_frame + .stack_size_mismatch_error(expected_stack_size, actual_stack_size); + return Err(set_err_info!(current_frame, err)); + } + self.call_stack + .type_check_return::(&mut self.operand_stack, &mut current_frame) + .map_err(|e| set_err_info!(current_frame, e))?; self.access_control .exit_function(¤t_frame.function) - .map_err(|e| self.set_location(e))?; + .map_err(|e| set_err_info!(current_frame, e))?; if let Some(frame) = self.call_stack.pop() { self.reentrancy_checker @@ -343,16 +426,18 @@ impl InterpreterImpl<'_> { ¤t_frame.function, current_frame.call_type(), ) - .map_err(|e| self.set_location(e))?; + .map_err(|e| set_err_info!(current_frame, e))?; // Note: the caller will find the callee's return values at the top of the shared operand stack current_frame = frame; current_frame.pc += 1; // advance past the Call instruction in the caller + trace_recorder.record_successful_instruction(&Instruction::Ret); } else { + trace_recorder.record_successful_instruction(&Instruction::Ret); return Ok(self.operand_stack.value); } }, ExitCode::Call(fh_idx) => { - let (function, frame_cache) = if RTCaches::caches_enabled() { + let (function, frame_cache) = if self.vm_config.enable_function_caches { let current_frame_cache = &mut *current_frame.frame_cache.borrow_mut(); if let PerInstructionCache::Call(ref function, ref frame_cache) = @@ -360,40 +445,35 @@ impl InterpreterImpl<'_> { { (Rc::clone(function), Rc::clone(frame_cache)) } else { - match current_frame_cache.sub_frame_cache.entry(fh_idx) { - btree_map::Entry::Occupied(entry) => { - let entry = entry.get(); - current_frame_cache.per_instruction_cache - [current_frame.pc as usize] = PerInstructionCache::Call( - Rc::clone(&entry.0), - Rc::clone(&entry.1), - ); - - (Rc::clone(&entry.0), Rc::clone(&entry.1)) - }, - btree_map::Entry::Vacant(entry) => { - let function = Rc::new(self.load_function( - module_storage, - ¤t_frame, - fh_idx, - )?); - let frame_cache = - FrameTypeCache::make_rc_for_function(&function); - - entry.insert((Rc::clone(&function), Rc::clone(&frame_cache))); - current_frame_cache.per_instruction_cache - [current_frame.pc as usize] = PerInstructionCache::Call( - Rc::clone(&function), - Rc::clone(&frame_cache), - ); - - (function, frame_cache) - }, - } + let (function, frame_cache) = + match current_frame_cache.function_cache.entry(fh_idx) { + Entry::Vacant(e) => { + let function = self + .load_function_no_visibility_checks( + gas_meter, + traversal_context, + ¤t_frame, + fh_idx, + ) + .map(Rc::new)?; + let frame_cache = function_caches + .get_or_create_frame_cache_non_generic(&function); + e.insert((function.clone(), frame_cache.clone())); + (function, frame_cache) + }, + Entry::Occupied(e) => e.into_mut().clone(), + }; + current_frame_cache.per_instruction_cache[current_frame.pc as usize] = + PerInstructionCache::Call( + Rc::clone(&function), + Rc::clone(&frame_cache), + ); + (function, frame_cache) } } else { - let function = Rc::::new(self.load_function( - module_storage, + let function = Rc::new(self.load_function_no_visibility_checks( + gas_meter, + traversal_context, ¤t_frame, fh_idx, )?); @@ -401,16 +481,19 @@ impl InterpreterImpl<'_> { (function, frame_cache) }; + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + + RTTCheck::check_call_visibility( + ¤t_frame.function, + &function, + CallType::Regular, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas - let module_id = function.module_id().ok_or_else(|| { - let err = PartialVMError::new_invariant_violation( - "Failed to get native function module id", - ); - set_err_info!(current_frame, err) - })?; gas_meter .charge_call( - module_id, + function.owner_as_module()?.self_id(), function.name(), self.operand_stack .last_n(function.param_tys().len()) @@ -420,11 +503,10 @@ impl InterpreterImpl<'_> { .map_err(|e| set_err_info!(current_frame, e))?; if function.is_native() { - self.call_native::( + let dispatched = self.call_native::( &mut current_frame, data_cache, - resource_resolver, - module_storage, + function_caches, gas_meter, traversal_context, extensions, @@ -432,21 +514,27 @@ impl InterpreterImpl<'_> { ClosureMask::empty(), vec![], )?; + trace_recorder.record_successful_instruction(&Instruction::Call(fh_idx)); + if dispatched { + trace_recorder.record_entrypoint(¤t_frame.function) + } continue; } - self.set_new_call_frame::( + self.set_new_call_frame::( &mut current_frame, gas_meter, function, + fn_guard, CallType::Regular, frame_cache, ClosureMask::empty(), vec![], )?; + trace_recorder.record_successful_instruction(&Instruction::Call(fh_idx)); }, ExitCode::CallGeneric(idx) => { - let (function, frame_cache) = if RTCaches::caches_enabled() { + let (function, frame_cache) = if self.vm_config.enable_function_caches { let current_frame_cache = &mut *current_frame.frame_cache.borrow_mut(); if let PerInstructionCache::CallGeneric(ref function, ref frame_cache) = @@ -454,70 +542,62 @@ impl InterpreterImpl<'_> { { (Rc::clone(function), Rc::clone(frame_cache)) } else { - match current_frame_cache.generic_sub_frame_cache.entry(idx) { - btree_map::Entry::Occupied(entry) => { - let entry = entry.get(); - current_frame_cache.per_instruction_cache - [current_frame.pc as usize] = - PerInstructionCache::CallGeneric( - Rc::clone(&entry.0), - Rc::clone(&entry.1), + let (function, frame_cache) = + match current_frame_cache.generic_function_cache.entry(idx) { + Entry::Vacant(e) => { + let function = Rc::new( + self.load_generic_function_no_visibility_checks( + gas_meter, + traversal_context, + ¤t_frame, + idx, + )?, ); - - (Rc::clone(&entry.0), Rc::clone(&entry.1)) - }, - btree_map::Entry::Vacant(entry) => { - let function = - Rc::::new(self.load_generic_function( - module_storage, - ¤t_frame, - gas_meter, - idx, - )?); - let frame_cache = - FrameTypeCache::make_rc_for_function(&function); - - entry.insert((Rc::clone(&function), Rc::clone(&frame_cache))); - current_frame_cache.per_instruction_cache - [current_frame.pc as usize] = - PerInstructionCache::CallGeneric( - Rc::clone(&function), - Rc::clone(&frame_cache), - ); - (function, frame_cache) - }, - } + let frame_cache = function_caches + .get_or_create_frame_cache_generic(&function); + e.insert((function.clone(), frame_cache.clone())); + (function, frame_cache) + }, + Entry::Occupied(e) => e.into_mut().clone(), + }; + current_frame_cache.per_instruction_cache[current_frame.pc as usize] = + PerInstructionCache::CallGeneric( + Rc::clone(&function), + Rc::clone(&frame_cache), + ); + (function, frame_cache) } } else { - let function = Rc::::new(self.load_generic_function( - module_storage, - ¤t_frame, + let function = Rc::new(self.load_generic_function_no_visibility_checks( gas_meter, + traversal_context, + ¤t_frame, idx, )?); let frame_cache = FrameTypeCache::make_rc(); (function, frame_cache) }; - let module_id = function - .module_id() - .ok_or_else(|| { - PartialVMError::new_invariant_violation( - "Failed to get native function module id", - ) - }) - .map_err(|e| set_err_info!(current_frame, e))?; + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + + RTTCheck::check_call_visibility( + ¤t_frame.function, + &function, + CallType::Regular, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas gas_meter .charge_call_generic( - module_id, + function.owner_as_module()?.self_id(), function.name(), function .ty_args() .iter() .map(|ty| TypeWithRuntimeEnvironment { ty, - runtime_environment: module_storage.runtime_environment(), + runtime_environment: self.loader.runtime_environment(), }), self.operand_stack .last_n(function.param_tys().len()) @@ -527,11 +607,10 @@ impl InterpreterImpl<'_> { .map_err(|e| set_err_info!(current_frame, e))?; if function.is_native() { - self.call_native::( + let dispatched = self.call_native::( &mut current_frame, data_cache, - resource_resolver, - module_storage, + function_caches, gas_meter, traversal_context, extensions, @@ -539,73 +618,69 @@ impl InterpreterImpl<'_> { ClosureMask::empty(), vec![], )?; + trace_recorder + .record_successful_instruction(&Instruction::CallGeneric(idx)); + if dispatched { + trace_recorder.record_entrypoint(¤t_frame.function) + } continue; } - self.set_new_call_frame::( + self.set_new_call_frame::( &mut current_frame, gas_meter, function, + fn_guard, CallType::Regular, frame_cache, ClosureMask::empty(), vec![], )?; + trace_recorder.record_successful_instruction(&Instruction::CallGeneric(idx)); }, - ExitCode::CallClosure(_sig_idx) => { + ExitCode::CallClosure(sig_idx) => { // Notice the closure is type-checked in runtime_type_checker let (fun, captured) = self .operand_stack .pop_as::() .map_err(|e| set_err_info!(current_frame, e))? .unpack(); + let lazy_function = LazyLoadedFunction::expect_this_impl(fun.as_ref()) .map_err(|e| set_err_info!(current_frame, e))?; let mask = lazy_function.closure_mask(); - // Before trying to resolve the function, charge gas for associated - // module loading. - let module_id = lazy_function.with_name_and_ty_args( - |module_opt, _func_name, ty_arg_tags| { - let Some(module_id) = module_opt else { - // TODO(#15664): currently we need the module id for gas charging - // of calls, so we can't proceed here without one. But we want - // to be able to let scripts use closures. - let err = PartialVMError::new_invariant_violation(format!( - "module id required to charge gas for function `{}`", - lazy_function.to_canonical_string() - )); - return Err(set_err_info!(current_frame, err)); - }; - - // Charge gas for function code loading. - let arena_id = traversal_context - .referenced_module_ids - .alloc(module_id.clone()); - check_dependencies_and_charge_gas( - module_storage, - gas_meter, - traversal_context, - [(arena_id.address(), arena_id.name())], - )?; - - // Charge gas for code loading of modules used by type arguments. - check_type_tag_dependencies_and_charge_gas( - module_storage, - gas_meter, - traversal_context, - ty_arg_tags, - )?; - Ok(module_id.clone()) - }, - )?; + let module_id = lazy_function.with_name_and_ty_args(|module_id, _, _| { + module_id.cloned().ok_or_else(|| { + // Note: + // Module ID of a function should always exist because functions + // are defined in modules. The only way to have `None` here is + // when function is a script entrypoint. Note that in this case, + // entrypoint function cannot be packed as a closure, nor there + // can be any lambda-lifting in the script. + let err = PartialVMError::new_invariant_violation(format!( + "module id required to charge gas for function `{}`", + lazy_function.to_canonical_string() + )); + set_err_info!(current_frame, err) + }) + })?; // Resolve the function. This may lead to loading the code related // to this function. let callee = lazy_function - .with_resolved_function(module_storage, |f| Ok(f.clone())) + .as_resolved(self.loader, gas_meter, traversal_context) .map_err(|e| set_err_info!(current_frame, e))?; + let fn_guard = VM_PROFILER.function_start(callee.as_ref()); + + RTTCheck::check_call_visibility( + ¤t_frame.function, + &callee, + CallType::ClosureDynamicDispatch, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas for call and for the parameters. The current APIs // require an ExactSizeIterator to be passed for charge_call, so // some acrobatics is needed (sigh). @@ -627,51 +702,156 @@ impl InterpreterImpl<'_> { ) .map_err(|e| set_err_info!(current_frame, e))?; - // In difference to regular calls, we skip visibility check. - // It is possible to call a private function of another module via - // a closure. - // Call function if callee.is_native() { - self.call_native::( + let dispatched = self.call_native::( &mut current_frame, data_cache, - resource_resolver, - module_storage, + function_caches, gas_meter, traversal_context, extensions, &callee, mask, captured_vec, - )? + )?; + // If we call a dispatchable native, we need to record first the closure + // call, and then the target where it redirects to (which at this point + // has to be set as the current frame's function). + trace_recorder + .record_successful_instruction(&Instruction::CallClosure(sig_idx)); + trace_recorder.record_call_closure(&callee, mask); + if dispatched { + trace_recorder.record_entrypoint(¤t_frame.function) + } } else { - let frame_cache = if RTCaches::caches_enabled() { - FrameTypeCache::make_rc_for_function(&callee) + let frame_cache = if self.vm_config.enable_function_caches { + function_caches.get_or_create_frame_cache(&callee) } else { FrameTypeCache::make_rc() }; - self.set_new_call_frame::( + self.set_new_call_frame::( &mut current_frame, gas_meter, callee, + fn_guard, CallType::ClosureDynamicDispatch, // Make sure the frame cache is empty for the new call. frame_cache, mask, captured_vec, - )? + )?; + trace_recorder + .record_successful_instruction(&Instruction::CallClosure(sig_idx)); + trace_recorder.record_call_closure(current_frame.function.as_ref(), mask); } }, } } } +} + +impl CallStack { + pub(crate) fn type_check_return( + &self, + operand_stack: &mut Stack, + current_frame: &mut Frame, + ) -> PartialVMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + // If the returning function has runtime checks on, the return types + // will be on the caller stack. + let caller_has_rt_checks = self + .0 + .last() + .map(|f| RTTCheck::should_perform_checks(&f.function.function)) + .unwrap_or(false); + let callee_has_rt_checks = + RTTCheck::should_perform_checks(¤t_frame.function.function); + if callee_has_rt_checks { + let num_return_tys = current_frame.function.return_tys().len(); + let actual_type_stack_size = operand_stack.types.len(); + let expected_type_stack_size = + num_return_tys + current_frame.caller_type_stack_size as usize; + if actual_type_stack_size != expected_type_stack_size { + return Err(current_frame + .stack_size_mismatch_error(expected_type_stack_size, actual_type_stack_size)); + } + self.check_return_tys::(operand_stack, current_frame)?; + if !caller_has_rt_checks { + // The callee has pushed return types, but they aren't used by + // the caller, so need to be removed. + operand_stack.remove_tys(num_return_tys)?; + } + } else if caller_has_rt_checks { + // We are not runtime checking this function, but in the caller, so we must push the + // return types of the function onto the type stack, following the runtime type + // checking protocol. Also, we should check that the type stack is balanced: if callee + // has no runtime checks, type stack should be at the same state. + let actual_type_stack_size = operand_stack.types.len(); + let expected_type_stack_size = current_frame.caller_type_stack_size as usize; + if actual_type_stack_size != expected_type_stack_size { + return Err(current_frame + .stack_size_mismatch_error(expected_type_stack_size, actual_type_stack_size)); + } + + let ty_args = current_frame.function.ty_args(); + if ty_args.is_empty() { + for ret_ty in current_frame.function.return_tys() { + operand_stack.push_ty(ret_ty.clone())? + } + } else { + for ret_ty in current_frame.function.return_tys() { + let ret_ty = current_frame + .ty_builder() + .create_ty_with_subst(ret_ty, ty_args)?; + operand_stack.push_ty(ret_ty)? + } + } + } + Ok(()) + } + + // Check whether the values on the operand stack have the expected return types. + #[cfg_attr(feature = "force-inline", inline(always))] + fn check_return_tys( + &self, + operand_stack: &mut Stack, + current_frame: &mut Frame, + ) -> PartialVMResult<()> { + let expected_ret_tys = current_frame.function.return_tys(); + if expected_ret_tys.is_empty() { + return Ok(()); + } + let given_ret_tys = operand_stack.last_n_tys(expected_ret_tys.len())?; + for (expected, given) in expected_ret_tys.iter().zip(given_ret_tys) { + let ty_args = current_frame.function.ty_args(); + if ty_args.is_empty() { + given.paranoid_check_assignable(expected)?; + } else { + let expected_inst = current_frame + .ty_builder + .create_ty_with_subst(expected, ty_args)?; + given.paranoid_check_assignable(&expected_inst)?; + } + } + + Ok(()) + } +} - fn set_new_call_frame( +impl InterpreterImpl<'_, LoaderImpl> +where + LoaderImpl: Loader, +{ + #[cfg_attr(feature = "force-inline", inline(always))] + fn set_new_call_frame( &mut self, current_frame: &mut Frame, gas_meter: &mut impl GasMeter, function: Rc, + fn_guard: FnGuard, call_type: CallType, frame_cache: Rc>, mask: ClosureMask, @@ -686,9 +866,11 @@ impl InterpreterImpl<'_> { .map_err(|e| self.set_location(e))?; let mut frame = self - .make_call_frame::( + .make_call_frame::( + current_frame, gas_meter, function, + fn_guard, call_type, frame_cache, mask, @@ -717,17 +899,24 @@ impl InterpreterImpl<'_> { /// /// Native functions do not push a frame at the moment and as such errors from a native /// function are incorrectly attributed to the caller. - fn make_call_frame( + // note(inline): single usage + #[inline(always)] + fn make_call_frame( &mut self, + current_frame: &Frame, gas_meter: &mut impl GasMeter, function: Rc, + fn_guard: FnGuard, call_type: CallType, frame_cache: Rc>, mask: ClosureMask, mut captured: Vec, ) -> PartialVMResult { - let mut locals = Locals::new(function.local_tys().len()); + let num_locals = function.local_tys().len(); + let mut locals = Locals::new(num_locals); let num_param_tys = function.param_tys().len(); + // Whether the function making this frame performs checks. + let should_check = RTTCheck::should_perform_checks(¤t_frame.function.function); for i in (0..num_param_tys).rev() { let is_captured = mask.is_captured(i); let value = if is_captured { @@ -738,12 +927,12 @@ impl InterpreterImpl<'_> { } else { self.operand_stack.pop()? }; - locals.store_loc(i, value, self.vm_config.check_invariant_in_swap_loc)?; + locals.store_loc(i, value)?; - let ty_args = function.ty_args(); - if RTTCheck::should_perform_checks() && !is_captured { + if should_check && !is_captured { // Only perform paranoid type check for actual operands on the stack. // Captured arguments are already verified against function signature. + let ty_args = function.ty_args(); let ty = self.operand_stack.pop_ty()?; let expected_ty = &function.local_tys()[i]; if !ty_args.is_empty() { @@ -759,36 +948,38 @@ impl InterpreterImpl<'_> { } } } + RTRCheck::core_call_transition(num_param_tys, num_locals, mask, &mut self.ref_state)?; Frame::make_new_frame::( gas_meter, call_type, self.vm_config, function, + Some(fn_guard), locals, frame_cache, + &self.operand_stack, ) } - /// Call a native functions. - fn call_native( + /// Call a native functions. If native function is a dispatchable native (i.e., it dynamically + /// dispatches to ome target via reflection), returns true. Otherwise, returns false. For + /// tracing, it is responsibility of the caller to ensure the outcome is logged in the trace. + fn call_native( &mut self, current_frame: &mut Frame, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, + function_caches: &mut InterpreterFunctionCaches, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, function: &LoadedFunction, mask: ClosureMask, captured: Vec, - ) -> VMResult<()> { - // Note: refactor if native functions push a frame on the stack - self.call_native_impl::( + ) -> VMResult { + self.call_native_impl::( current_frame, data_cache, - resource_resolver, - module_storage, + function_caches, gas_meter, traversal_context, extensions, @@ -814,19 +1005,18 @@ impl InterpreterImpl<'_> { }) } - fn call_native_impl( + fn call_native_impl( &mut self, current_frame: &mut Frame, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, + function_caches: &mut InterpreterFunctionCaches, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, function: &LoadedFunction, mask: ClosureMask, mut captured: Vec, - ) -> PartialVMResult<()> { + ) -> PartialVMResult { let ty_builder = &self.vm_config.ty_builder; let num_param_tys = function.param_tys().len(); @@ -844,7 +1034,7 @@ impl InterpreterImpl<'_> { let mut arg_tys = VecDeque::new(); let ty_args = function.ty_args(); - if RTTCheck::should_perform_checks() { + if RTTCheck::should_perform_checks(¤t_frame.function.function) { for i in (0..num_param_tys).rev() { let expected_ty = &function.param_tys()[i]; if !mask.is_captured(i) { @@ -868,7 +1058,7 @@ impl InterpreterImpl<'_> { gas_meter.charge_native_function_before_execution( ty_args.iter().map(|ty| TypeWithRuntimeEnvironment { ty, - runtime_environment: module_storage.runtime_environment(), + runtime_environment: self.loader.runtime_environment(), }), args.iter(), )?; @@ -876,13 +1066,12 @@ impl InterpreterImpl<'_> { let mut native_context = NativeContext::new( self, data_cache, - resource_resolver, - module_storage, + self.loader.unmetered_module_storage(), extensions, gas_meter, traversal_context, ); - let result = native_function(&mut native_context, ty_args.to_vec(), args)?; + let result = native_function(&mut native_context, ty_args, args)?; // Note(Gas): The order by which gas is charged / error gets returned MUST NOT be modified // here or otherwise it becomes an incompatible change!!! @@ -906,15 +1095,23 @@ impl InterpreterImpl<'_> { self.operand_stack.push(value)?; } - if RTTCheck::should_perform_checks() { - for ty in function.return_tys() { - let ty = ty_builder.create_ty_with_subst(ty, ty_args)?; - self.operand_stack.push_ty(ty)?; + // If the caller requires checks, push return types of native function to + // satisfy runtime check protocol. + if RTTCheck::should_perform_checks(¤t_frame.function.function) { + if function.ty_args().is_empty() { + for ty in function.return_tys() { + self.operand_stack.push_ty(ty.clone())?; + } + } else { + for ty in function.return_tys() { + let ty = ty_builder.create_ty_with_subst(ty, ty_args)?; + self.operand_stack.push_ty(ty)?; + } } } current_frame.pc += 1; // advance past the Call instruction in the caller - Ok(()) + Ok(false) }, NativeResult::Abort { cost, abort_code } => { gas_meter.charge_native_function(cost, Option::>::None)?; @@ -943,26 +1140,25 @@ impl InterpreterImpl<'_> { } => { gas_meter.charge_native_function(cost, Option::>::None)?; + let ty_args_id = self.ty_pool.intern_ty_args(&ty_args); let target_func = current_frame.build_loaded_function_from_name_and_ty_args( - module_storage, + self.loader, + gas_meter, + traversal_context, &module_name, &func_name, ty_args, + ty_args_id, )?; - if target_func.is_friend_or_private() - || target_func.module_id() == function.module_id() - { - return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) - .with_message( - "Invoking private or friend function during dispatch".to_string(), - )); - } + // Note: the profiler begins measuring at this point, so it captures only execution time, not loading time. + let fn_guard = VM_PROFILER.function_start(&target_func); - if target_func.is_native() { - return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) - .with_message("Invoking native function during dispatch".to_string())); - } + RTTCheck::check_call_visibility( + function, + &target_func, + CallType::NativeDynamicDispatch, + )?; // Checking type of the dispatch target function // @@ -977,179 +1173,144 @@ impl InterpreterImpl<'_> { != target_func.param_tys() { return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) - .with_message( - "Invoking private or friend function during dispatch".to_string(), - )); + .with_message("Invoking function with incompatible type".to_string())); } for value in args { self.operand_stack.push(value)?; } - // Maintaining the type stack for the paranoid mode using calling convention mentioned above. - if RTTCheck::should_perform_checks() { + // If the current function requires runtime checks, setup the type stack with the + // argument types + if RTTCheck::should_perform_checks(¤t_frame.function.function) { arg_tys.pop_back(); for ty in arg_tys { self.operand_stack.push_ty(ty)?; } } - let frame_cache = if RTCaches::caches_enabled() { - FrameTypeCache::make_rc_for_function(&target_func) - } else { - FrameTypeCache::make_rc() - }; - - self.set_new_call_frame::( + let frame_cache = function_caches.get_or_create_frame_cache(&target_func); + self.set_new_call_frame::( current_frame, gas_meter, Rc::new(target_func), + fn_guard, CallType::NativeDynamicDispatch, frame_cache, ClosureMask::empty(), vec![], ) - .map_err(|err| err.to_partial()) + .map_err(|err| err.to_partial())?; + Ok(true) }, NativeResult::LoadModule { module_name } => { - let arena_id = traversal_context - .referenced_module_ids - .alloc(module_name.clone()); - check_dependencies_and_charge_gas( - module_storage, - gas_meter, - traversal_context, - [(arena_id.address(), arena_id.name())], - ) - .map_err(|err| err - .to_partial() - .append_message_with_separator('.', - format!("Failed to charge transitive dependency for {}. Does this module exists?", module_name) - ))?; + self.loader.charge_native_result_load_module( + gas_meter, + traversal_context, + &module_name, + )?; current_frame.pc += 1; // advance past the Call instruction in the caller - Ok(()) + Ok(false) }, } } - /// Make sure only private/friend function can only be invoked by modules under the same address. - fn check_friend_or_private_call( - &self, - caller: &LoadedFunction, - callee: &LoadedFunction, - ) -> VMResult<()> { - if callee.is_friend_or_private() { - match (caller.module_id(), callee.module_id()) { - (Some(caller_id), Some(callee_id)) => { - if caller_id.address() == callee_id.address() { - Ok(()) - } else { - Err(self.set_location(PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message( - format!("Private/Friend function invokation error, caller: {:?}::{:?}, callee: {:?}::{:?}", caller_id, caller.name(), callee_id, callee.name()), - ))) - } - }, - _ => Err(self.set_location( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message(format!( - "Private/Friend function invokation error caller: {:?}, callee {:?}", - caller.name(), - callee.name() - )), - )), - } - } else { - Ok(()) - } - } - /// Perform a binary operation to two values at the top of the stack. - fn binop(&mut self, f: F) -> PartialVMResult<()> + #[inline(always)] + fn binop(&mut self, f: F) -> PartialVMResult<()> where - Value: VMValueCast, - F: FnOnce(T, T) -> PartialVMResult, + F: FnOnce(Value, Value) -> PartialVMResult, { - let rhs = self.operand_stack.pop_as::()?; - let lhs = self.operand_stack.pop_as::()?; + let rhs = self.operand_stack.pop()?; + let lhs = self.operand_stack.pop()?; let result = f(lhs, rhs)?; self.operand_stack.push(result) } - /// Perform a binary operation for integer values. - fn binop_int(&mut self, f: F) -> PartialVMResult<()> + #[inline(always)] + fn binop_bool(&mut self, f: F) -> PartialVMResult<()> where - F: FnOnce(IntegerValue, IntegerValue) -> PartialVMResult, + F: FnOnce(bool, bool) -> PartialVMResult, { - self.binop(|lhs, rhs| { - Ok(match f(lhs, rhs)? { - IntegerValue::U8(x) => Value::u8(x), - IntegerValue::U16(x) => Value::u16(x), - IntegerValue::U32(x) => Value::u32(x), - IntegerValue::U64(x) => Value::u64(x), - IntegerValue::U128(x) => Value::u128(x), - IntegerValue::U256(x) => Value::u256(x), - }) - }) + let rhs = self.operand_stack.pop_as::()?; + let lhs = self.operand_stack.pop_as::()?; + let result = f(lhs, rhs)?; + self.operand_stack.push(Value::bool(result)) } - /// Perform a binary operation for boolean values. - fn binop_bool(&mut self, f: F) -> PartialVMResult<()> + #[inline(always)] + fn binop_rel(&mut self, f: F) -> PartialVMResult<()> where - Value: VMValueCast, - F: FnOnce(T, T) -> PartialVMResult, + F: FnOnce(Value, Value) -> PartialVMResult, { - self.binop(|lhs, rhs| Ok(Value::bool(f(lhs, rhs)?))) + let rhs = self.operand_stack.pop()?; + let lhs = self.operand_stack.pop()?; + let result = f(lhs, rhs)?; + self.operand_stack.push(Value::bool(result)) + } + + /// Perform a unary operation to one value at the top of the stack. + #[inline(always)] + fn unop(&mut self, f: F) -> PartialVMResult<()> + where + F: FnOnce(Value) -> PartialVMResult, + { + let arg = self.operand_stack.pop()?; + let result = f(arg)?; + self.operand_stack.push(result) } - /// Creates a data cache entry for the specified address-type pair. Charges gas for the number - /// of bytes loaded. - fn create_and_charge_data_cache_entry( - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + /// Loads a resource from the on-chain storage and returns mutable reference to it. + fn load_resource_mut<'cache>( + &self, + data_cache: &'cache mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, - ) -> PartialVMResult { - let (entry, bytes_loaded) = TransactionDataCache::create_data_cache_entry( - module_storage, - resource_resolver, - &addr, - ty, - )?; - gas_meter.charge_load_resource( - addr, - TypeWithRuntimeEnvironment { - ty, - runtime_environment: module_storage.runtime_environment(), - }, - entry.value().view(), - bytes_loaded, - )?; - Ok(entry) + ) -> PartialVMResult<&'cache mut GlobalValue> { + let (gv, bytes_loaded) = + data_cache.load_resource_mut(gas_meter, traversal_context, &addr, ty)?; + if let Some(bytes_loaded) = bytes_loaded { + gas_meter.charge_load_resource( + addr, + TypeWithRuntimeEnvironment { + ty, + runtime_environment: self.loader.runtime_environment(), + }, + gv.view(), + bytes_loaded, + )?; + } + + Ok(gv) } - /// Loads a resource from the data store and return the number of bytes read from the storage. - fn load_resource<'c>( - data_cache: &'c mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + /// Loads a resource from the on-chain storage and returns immutable reference to it. + fn load_resource<'cache>( + &self, + data_cache: &'cache mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, - ) -> PartialVMResult<&'c mut GlobalValue> { - if !data_cache.contains_resource(&addr, ty) { - let entry = Self::create_and_charge_data_cache_entry( - resource_resolver, - module_storage, - gas_meter, + ) -> PartialVMResult<&'cache GlobalValue> { + let (gv, bytes_loaded) = + data_cache.load_resource(gas_meter, traversal_context, &addr, ty)?; + if let Some(bytes_loaded) = bytes_loaded { + gas_meter.charge_load_resource( addr, - ty, + TypeWithRuntimeEnvironment { + ty, + runtime_environment: self.loader.runtime_environment(), + }, + gv.view(), + bytes_loaded, )?; - data_cache.insert_resource(addr, ty.clone(), entry)?; } - data_cache.get_resource_mut(&addr, ty) + + Ok(gv) } /// BorrowGlobal (mutable and not) opcode. @@ -1157,23 +1318,20 @@ impl InterpreterImpl<'_> { &mut self, is_mut: bool, is_generic: bool, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { - let runtime_environment = module_storage.runtime_environment(); - let res = Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )? - .borrow_global(); + let runtime_environment = self.loader.runtime_environment(); + let gv = if is_mut { + self.load_resource_mut(data_cache, gas_meter, traversal_context, addr, ty)? + } else { + self.load_resource(data_cache, gas_meter, traversal_context, addr, ty)? + }; + + let res = gv.borrow_global(); gas_meter.charge_borrow_global( is_mut, is_generic, @@ -1235,23 +1393,15 @@ impl InterpreterImpl<'_> { fn exists( &mut self, is_generic: bool, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { - let runtime_environment = module_storage.runtime_environment(); - let gv = Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )?; - let exists = gv.exists()?; + let runtime_environment = self.loader.runtime_environment(); + let gv = self.load_resource(data_cache, gas_meter, traversal_context, addr, ty)?; + let exists = gv.exists(); gas_meter.charge_exists( is_generic, TypeWithRuntimeEnvironment { @@ -1269,23 +1419,16 @@ impl InterpreterImpl<'_> { fn move_from( &mut self, is_generic: bool, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { - let runtime_environment = module_storage.runtime_environment(); - let resource = match Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )? - .move_from() + let runtime_environment = self.loader.runtime_environment(); + let resource = match self + .load_resource_mut(data_cache, gas_meter, traversal_context, addr, ty)? + .move_from() { Ok(resource) => { gas_meter.charge_move_from( @@ -1320,23 +1463,15 @@ impl InterpreterImpl<'_> { fn move_to( &mut self, is_generic: bool, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, resource: Value, ) -> PartialVMResult<()> { - let runtime_environment = module_storage.runtime_environment(); - let gv = Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )?; + let runtime_environment = self.loader.runtime_environment(); + let gv = self.load_resource_mut(data_cache, gas_meter, traversal_context, addr, ty)?; // NOTE(Gas): To maintain backward compatibility, we need to charge gas after attempting // the move_to operation. match gv.move_to(resource) { @@ -1373,6 +1508,7 @@ impl InterpreterImpl<'_> { // /// If the error is invariant violation, attaches the state of the current frame. + #[cold] fn attach_state_if_invariant_violation( &self, mut err: VMError, @@ -1385,12 +1521,18 @@ impl InterpreterImpl<'_> { // These errors mean that the code breaks some invariant, so we need to // remap the error. if err.status_type() == StatusType::Verification { - err.set_major_status(StatusCode::VERIFICATION_ERROR); + // Make sure we propagate dependency limit errors. + if !self.vm_config.propagate_dependency_limit_error + || err.major_status() != StatusCode::DEPENDENCY_LIMIT_REACHED + { + err.set_major_status(StatusCode::VERIFICATION_ERROR); + } } // We do not consider speculative invariant violations. if err.status_type() == StatusType::InvariantViolation && err.major_status() != StatusCode::SPECULATIVE_EXECUTION_ABORT_ERROR + && !errors::is_stable_test_display() { let location = err.location().clone(); let state = self.internal_state_str(current_frame); @@ -1445,7 +1587,7 @@ impl InterpreterImpl<'_> { debug_writeln!(buf, " Code:")?; let pc = frame.pc as usize; let code = function.code(); - let before = if pc > 3 { pc - 3 } else { 0 }; + let before = pc.saturating_sub(3); let after = min(code.len(), pc + 4); for (idx, instr) in code.iter().enumerate().take(pc).skip(before) { debug_writeln!(buf, " [{}] {:?}", idx, instr)?; @@ -1459,7 +1601,7 @@ impl InterpreterImpl<'_> { debug_writeln!(buf)?; debug_writeln!(buf, " Locals:")?; if !function.local_tys().is_empty() { - values::debug::print_locals(buf, &frame.locals)?; + values::debug::print_locals(buf, &frame.locals, true)?; debug_writeln!(buf)?; } else { debug_writeln!(buf, " (none)")?; @@ -1515,17 +1657,23 @@ impl InterpreterImpl<'_> { internal_state } + #[cold] fn set_location(&self, err: PartialVMError) -> VMError { err.finish(self.call_stack.current_location()) } + #[cold] fn get_internal_state(&self) -> ExecutionState { self.get_stack_frames(usize::MAX) } } -impl InterpreterDebugInterface for InterpreterImpl<'_> { +impl InterpreterDebugInterface for InterpreterImpl<'_, LoaderImpl> +where + LoaderImpl: Loader, +{ #[allow(dead_code)] + #[cold] fn debug_print_stack_trace( &self, buf: &mut String, @@ -1576,13 +1724,24 @@ pub(crate) const ACCESS_STACK_SIZE_LIMIT: usize = 256; /// The operand and runtime-type stacks. pub(crate) struct Stack { - value: Vec, - types: Vec, + pub(crate) value: Vec, + pub(crate) types: Vec, +} + +impl Debug for Stack { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!( + f, + "values = \n {}\n types = \n {}\n", + self.value.iter().map(|v| format!("{:?}", v)).join(", "), + self.types.iter().map(|v| format!("{:?}", v)).join(", "), + ) + } } impl Stack { /// Create a new empty operand stack. - fn new() -> Self { + pub(crate) fn new() -> Self { Stack { value: vec![], types: vec![], @@ -1591,6 +1750,7 @@ impl Stack { /// Push a `Value` on the stack if the max stack size has not been reached. Abort execution /// otherwise. + // note(inline): increases function size 25%, DOES NOT improve performance, do not inline. fn push(&mut self, value: Value) -> PartialVMResult<()> { if self.value.len() < OPERAND_STACK_SIZE_LIMIT { self.value.push(value); @@ -1601,6 +1761,7 @@ impl Stack { } /// Pop a `Value` off the stack or abort execution if the stack is empty. + #[inline] fn pop(&mut self) -> PartialVMResult { self.value .pop() @@ -1609,6 +1770,8 @@ impl Stack { /// Pop a `Value` of a given type off the stack. Abort if the value is not of the given /// type or if the stack is empty. + // note(inline): do not inline this, it bloats interpreter loop 20% and does not adds enough perf to justify, + // instead we're inlining `value_as()` and all VM casts. fn pop_as(&mut self) -> PartialVMResult where Value: VMValueCast, @@ -1629,14 +1792,19 @@ impl Stack { fn last_n(&self, n: usize) -> PartialVMResult + Clone> { if self.value.len() < n { - return Err(PartialVMError::new(StatusCode::EMPTY_VALUE_STACK) - .with_message("Failed to get last n arguments on the argument stack".to_string())); + return Err( + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK).with_message(format!( + "Failed to get last {} arguments on the argument stack", + n + )), + ); } Ok(self.value[(self.value.len() - n)..].iter()) } /// Push a type on the stack if the max stack size has not been reached. Abort execution /// otherwise. + // note(inline): bloats runtime_type_checks pub(crate) fn push_ty(&mut self, ty: Type) -> PartialVMResult<()> { if self.types.len() < OPERAND_STACK_SIZE_LIMIT { self.types.push(ty); @@ -1647,53 +1815,69 @@ impl Stack { } /// Pop a type off the stack or abort execution if the stack is empty. + // note(inline): bloats runtime_type_checks pub(crate) fn pop_ty(&mut self) -> PartialVMResult { - self.types - .pop() - .ok_or_else(|| PartialVMError::new(StatusCode::EMPTY_VALUE_STACK)) + self.types.pop().ok_or_else(|| { + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK) + .with_message("runtime type stack empty") + }) } + // note(inline): bloats runtime_type_checks pub(crate) fn top_ty(&mut self) -> PartialVMResult<&Type> { - self.types - .last() - .ok_or_else(|| PartialVMError::new(StatusCode::EMPTY_VALUE_STACK)) + self.types.last().ok_or_else(|| { + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK) + .with_message("runtime type stack empty") + }) } /// Pop n types off the stack. + // note(inline): bloats runtime_type_checks pub(crate) fn popn_tys(&mut self, n: usize) -> PartialVMResult> { - let remaining_stack_size = self - .types - .len() - .checked_sub(n) - .ok_or_else(|| PartialVMError::new(StatusCode::EMPTY_VALUE_STACK))?; + let remaining_stack_size = self.types.len().checked_sub(n).ok_or_else(|| { + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK) + .with_message("runtime type stack empty") + })?; let args = self.types.split_off(remaining_stack_size); Ok(args) } - pub(crate) fn check_balance(&self) -> PartialVMResult<()> { - if self.types.len() != self.value.len() { + /// Remove n types from the stack. + pub(crate) fn remove_tys(&mut self, n: usize) -> PartialVMResult<()> { + let remaining_stack_size = self.types.len().checked_sub(n).ok_or_else(|| { + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK) + .with_message("runtime type stack empty") + })?; + self.types.truncate(remaining_stack_size); + Ok(()) + } + + pub(crate) fn last_n_tys(&self, n: usize) -> PartialVMResult<&[Type]> { + if self.types.len() < n { return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message( - "Paranoid Mode: Type and value stack need to be balanced".to_string(), - ), + PartialVMError::new(StatusCode::EMPTY_VALUE_STACK).with_message(format!( + "Failed to get last {} arguments on the runtime type stack", + n + )), ); } - Ok(()) + let len = self.types.len(); + Ok(&self.types[(len - n)..]) } } /// A call stack. -// #[derive(Debug)] -struct CallStack(Vec); +pub(crate) struct CallStack(Vec); impl CallStack { /// Create a new empty call stack. - fn new() -> Self { + pub(crate) fn new() -> Self { CallStack(vec![]) } /// Push a `Frame` on the call stack. - fn push(&mut self, frame: Frame) -> Result<(), Frame> { + #[cfg_attr(feature = "inline-callstack", inline(always))] + pub(crate) fn push(&mut self, frame: Frame) -> Result<(), Frame> { if self.0.len() < CALL_STACK_SIZE_LIMIT { self.0.push(frame); Ok(()) @@ -1703,110 +1887,17 @@ impl CallStack { } /// Pop a `Frame` off the call stack. - fn pop(&mut self) -> Option { + #[cfg_attr(feature = "inline-callstack", inline(always))] + pub(crate) fn pop(&mut self) -> Option { self.0.pop() } - fn current_location(&self) -> Location { + pub(crate) fn current_location(&self) -> Location { let location_opt = self.0.last().map(|frame| frame.location()); location_opt.unwrap_or(Location::Undefined) } } -fn check_depth_of_type(module_storage: &impl ModuleStorage, ty: &Type) -> PartialVMResult<()> { - let _timer = VM_TIMER.timer_with_label("Interpreter::check_depth_of_type"); - - // Start at 1 since we always call this right before we add a new node to the value's depth. - let max_depth = match module_storage - .runtime_environment() - .vm_config() - .max_value_nest_depth - { - Some(max_depth) => max_depth, - None => return Ok(()), - }; - check_depth_of_type_impl(module_storage, ty, max_depth, 1)?; - Ok(()) -} - -fn check_depth_of_type_impl( - module_storage: &impl ModuleStorage, - ty: &Type, - max_depth: u64, - depth: u64, -) -> PartialVMResult { - macro_rules! check_depth { - ($additional_depth:expr) => {{ - let new_depth = depth.saturating_add($additional_depth); - if new_depth > max_depth { - return Err(PartialVMError::new(StatusCode::VM_MAX_VALUE_DEPTH_REACHED)); - } else { - new_depth - } - }}; - } - - // Calculate depth of the type itself - let ty_depth = match ty { - Type::Bool - | Type::U8 - | Type::U16 - | Type::U32 - | Type::U64 - | Type::U128 - | Type::U256 - | Type::Address - | Type::Signer => check_depth!(0), - // Even though this is recursive this is OK since the depth of this recursion is - // bounded by the depth of the type arguments, which we have already checked. - Type::Reference(ty) | Type::MutableReference(ty) => { - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(1))? - }, - Type::Vector(ty) => { - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(1))? - }, - Type::Struct { idx, .. } => { - let formula = - DepthFormulaCalculator::new(module_storage).calculate_depth_of_struct(idx)?; - check_depth!(formula.solve(&[])?) - }, - // NB: substitution must be performed before calling this function - Type::StructInstantiation { idx, ty_args, .. } => { - // Calculate depth of all type arguments, and make sure they themselves are not too deep. - let ty_arg_depths = ty_args - .iter() - .map(|ty| { - // Ty args should be fully resolved and not need any type arguments - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(0)) - }) - .collect::>>()?; - let formula = - DepthFormulaCalculator::new(module_storage).calculate_depth_of_struct(idx)?; - check_depth!(formula.solve(&ty_arg_depths)?) - }, - Type::Function { args, results, .. } => { - let mut ty_max_depth = depth; - for ty in args.iter().chain(results) { - ty_max_depth = ty_max_depth.max(check_depth_of_type_impl( - module_storage, - ty, - max_depth, - check_depth!(1), - )?); - } - ty_max_depth - }, - Type::TyParam(_) => { - return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message("Type parameter should be fully resolved".to_string()), - ) - }, - }; - - Ok(ty_depth) -} - /// An `ExitCode` from `execute_code_unit`. #[derive(Debug)] enum ExitCode { @@ -1818,20 +1909,20 @@ enum ExitCode { impl Frame { /// Execute a Move function until a return or a call opcode is found. - fn execute_code( + fn execute_code( &mut self, - interpreter: &mut InterpreterImpl, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + interpreter: &mut InterpreterImpl, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, + trace_recorder: &mut impl TraceRecorder, ) -> VMResult { - self.execute_code_impl::( + self.execute_code_impl::( interpreter, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, + trace_recorder, ) .map_err(|e| { let e = if cfg!(feature = "testing") || cfg!(feature = "stacktrace") { @@ -1839,29 +1930,29 @@ impl Frame { } else { e }; + if is_tracing_for!(TraceCategory::VMError) { + let mut str = String::new(); + if let Err(print_err) = interpreter + .debug_print_stack_trace(&mut str, interpreter.loader.runtime_environment()) + { + str = format!(": {}", print_err); + } + eprintln!("trace vm_error {}:\n{}", e, str) + } set_err_info!(self, e) }) } - fn execute_code_impl( + fn execute_code_impl( &mut self, - interpreter: &mut InterpreterImpl, - data_cache: &mut TransactionDataCache, - resource_resolver: &impl ResourceResolver, - module_storage: &impl ModuleStorage, + interpreter: &mut InterpreterImpl, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, + trace_recorder: &mut impl TraceRecorder, ) -> PartialVMResult { use SimpleInstruction as S; - macro_rules! make_ty { - ($ty:expr) => { - TypeWithRuntimeEnvironment { - ty: $ty, - runtime_environment: module_storage.runtime_environment(), - } - }; - } - let frame_cache = &mut *self.frame_cache.borrow_mut(); let code = self.function.code(); @@ -1872,7 +1963,7 @@ impl Frame { &self.locals, self.pc, instruction, - module_storage.runtime_environment(), + interpreter.loader.runtime_environment(), interpreter ); @@ -1884,6 +1975,8 @@ impl Frame { ) }); + let _guard = VM_PROFILER.instruction_start(instruction); + // Paranoid Mode: Perform the type stack transition check to make sure all type safety requirements has been met. // // We will run the checks for only the control flow instructions and StLoc here. The majority of checks will be @@ -1892,77 +1985,111 @@ impl Frame { // The reason for this design is we charge gas during instruction execution and we want to perform checks only after // proper gas has been charged for each instruction. - RTTCheck::check_operand_stack_balance(&interpreter.operand_stack)?; RTTCheck::pre_execution_type_stack_transition( self, &mut interpreter.operand_stack, instruction, frame_cache, )?; + RTRCheck::pre_execution_transition(self, instruction, &mut interpreter.ref_state)?; match instruction { - Bytecode::Pop => { + Instruction::Pop => { let popped_val = interpreter.operand_stack.pop()?; gas_meter.charge_pop(popped_val)?; }, - Bytecode::Ret => { + Instruction::Ret => { gas_meter.charge_simple_instr(S::Ret)?; + // Frame will process return instruction outside the main dispatch loop, so + // the instruction is recorded then. return Ok(ExitCode::Return); }, - Bytecode::BrTrue(offset) => { + Instruction::BrTrue(offset) => { if interpreter.operand_stack.pop_as::()? { gas_meter.charge_br_true(Some(*offset))?; self.pc = *offset; + trace_recorder.record_branch_outcome(true); + trace_recorder.record_successful_instruction(instruction); break; } else { gas_meter.charge_br_true(None)?; + trace_recorder.record_branch_outcome(false); + // Success of instruction is recorded when we exit the dispatch. } }, - Bytecode::BrFalse(offset) => { + Instruction::BrFalse(offset) => { if !interpreter.operand_stack.pop_as::()? { gas_meter.charge_br_false(Some(*offset))?; self.pc = *offset; + trace_recorder.record_branch_outcome(true); + trace_recorder.record_successful_instruction(instruction); break; } else { gas_meter.charge_br_false(None)?; + trace_recorder.record_branch_outcome(false); + // Success of instruction is recorded when we exit the dispatch. } }, - Bytecode::Branch(offset) => { + Instruction::Branch(offset) => { gas_meter.charge_branch(*offset)?; self.pc = *offset; + trace_recorder.record_successful_instruction(instruction); break; }, - Bytecode::LdU8(int_const) => { + Instruction::LdU8(int_const) => { gas_meter.charge_simple_instr(S::LdU8)?; interpreter.operand_stack.push(Value::u8(*int_const))?; }, - Bytecode::LdU16(int_const) => { + Instruction::LdU16(int_const) => { gas_meter.charge_simple_instr(S::LdU16)?; interpreter.operand_stack.push(Value::u16(*int_const))?; }, - Bytecode::LdU32(int_const) => { + Instruction::LdU32(int_const) => { gas_meter.charge_simple_instr(S::LdU32)?; interpreter.operand_stack.push(Value::u32(*int_const))?; }, - Bytecode::LdU64(int_const) => { + Instruction::LdU64(int_const) => { gas_meter.charge_simple_instr(S::LdU64)?; interpreter.operand_stack.push(Value::u64(*int_const))?; }, - Bytecode::LdU128(int_const) => { + Instruction::LdU128(int_const) => { gas_meter.charge_simple_instr(S::LdU128)?; - interpreter.operand_stack.push(Value::u128(*int_const))?; + interpreter.operand_stack.push(Value::u128(**int_const))?; }, - Bytecode::LdU256(int_const) => { + Instruction::LdU256(int_const) => { gas_meter.charge_simple_instr(S::LdU256)?; - interpreter.operand_stack.push(Value::u256(*int_const))?; + interpreter.operand_stack.push(Value::u256(**int_const))?; + }, + Instruction::LdI8(int_const) => { + gas_meter.charge_simple_instr(S::LdI8)?; + interpreter.operand_stack.push(Value::i8(*int_const))?; + }, + Instruction::LdI16(int_const) => { + gas_meter.charge_simple_instr(S::LdI16)?; + interpreter.operand_stack.push(Value::i16(*int_const))?; + }, + Instruction::LdI32(int_const) => { + gas_meter.charge_simple_instr(S::LdI32)?; + interpreter.operand_stack.push(Value::i32(*int_const))?; + }, + Instruction::LdI64(int_const) => { + gas_meter.charge_simple_instr(S::LdI64)?; + interpreter.operand_stack.push(Value::i64(*int_const))?; }, - Bytecode::LdConst(idx) => { + Instruction::LdI128(int_const) => { + gas_meter.charge_simple_instr(S::LdI128)?; + interpreter.operand_stack.push(Value::i128(**int_const))?; + }, + Instruction::LdI256(int_const) => { + gas_meter.charge_simple_instr(S::LdI256)?; + interpreter.operand_stack.push(Value::i256(**int_const))?; + }, + Instruction::LdConst(idx) => { let constant = self.constant_at(*idx); gas_meter.charge_create_ty(NumTypeNodes::new( constant.type_.num_nodes() as u64, ))?; - gas_meter.charge_ld_const(NumBytes::new(constant.data.len() as u64))?; let val = Value::deserialize_constant(constant).ok_or_else(|| { @@ -1974,51 +2101,50 @@ impl Frame { })?; gas_meter.charge_ld_const_after_deserialization(&val)?; - interpreter.operand_stack.push(val)?; }, - Bytecode::LdTrue => { + Instruction::LdTrue => { gas_meter.charge_simple_instr(S::LdTrue)?; interpreter.operand_stack.push(Value::bool(true))?; }, - Bytecode::LdFalse => { + Instruction::LdFalse => { gas_meter.charge_simple_instr(S::LdFalse)?; interpreter.operand_stack.push(Value::bool(false))?; }, - Bytecode::CopyLoc(idx) => { + Instruction::CopyLoc(idx) => { // TODO(Gas): We should charge gas before copying the value. let local = self.locals.copy_loc(*idx as usize)?; gas_meter.charge_copy_loc(&local)?; interpreter.operand_stack.push(local)?; }, - Bytecode::MoveLoc(idx) => { - let local = self.locals.move_loc( - *idx as usize, - interpreter.vm_config.check_invariant_in_swap_loc, - )?; + Instruction::MoveLoc(idx) => { + let local = self.locals.move_loc(*idx as usize)?; gas_meter.charge_move_loc(&local)?; - interpreter.operand_stack.push(local)?; }, - Bytecode::StLoc(idx) => { + Instruction::StLoc(idx) => { let value_to_store = interpreter.operand_stack.pop()?; gas_meter.charge_store_loc(&value_to_store)?; - self.locals.store_loc( - *idx as usize, - value_to_store, - interpreter.vm_config.check_invariant_in_swap_loc, - )?; + self.locals.store_loc(*idx as usize, value_to_store)?; }, - Bytecode::Call(idx) => { + Instruction::Call(idx) => { + // Frame will process call instruction outside the main dispatch loop, so + // the instruction is recorded then. return Ok(ExitCode::Call(*idx)); }, - Bytecode::CallGeneric(idx) => { + Instruction::CallGeneric(idx) => { + // Frame will process generic call instruction outside the main dispatch + // loop, so the instruction is recorded then. return Ok(ExitCode::CallGeneric(*idx)); }, - Bytecode::CallClosure(idx) => return Ok(ExitCode::CallClosure(*idx)), - Bytecode::MutBorrowLoc(idx) | Bytecode::ImmBorrowLoc(idx) => { + Instruction::CallClosure(idx) => { + // Frame will process closure call instruction outside the main dispatch + // loop, so the instruction is recorded then. + return Ok(ExitCode::CallClosure(*idx)); + }, + Instruction::MutBorrowLoc(idx) | Instruction::ImmBorrowLoc(idx) => { let instr = match instruction { - Bytecode::MutBorrowLoc(_) => S::MutBorrowLoc, + Instruction::MutBorrowLoc(_) => S::MutBorrowLoc, _ => S::ImmBorrowLoc, }; gas_meter.charge_simple_instr(instr)?; @@ -2026,9 +2152,9 @@ impl Frame { .operand_stack .push(self.locals.borrow_loc(*idx as usize)?)?; }, - Bytecode::ImmBorrowField(fh_idx) | Bytecode::MutBorrowField(fh_idx) => { + Instruction::ImmBorrowField(fh_idx) | Instruction::MutBorrowField(fh_idx) => { let instr = match instruction { - Bytecode::MutBorrowField(_) => S::MutBorrowField, + Instruction::MutBorrowField(_) => S::MutBorrowField, _ => S::ImmBorrowField, }; gas_meter.charge_simple_instr(instr)?; @@ -2039,8 +2165,8 @@ impl Frame { let field_ref = reference.borrow_field(offset)?; interpreter.operand_stack.push(field_ref)?; }, - Bytecode::ImmBorrowFieldGeneric(fi_idx) - | Bytecode::MutBorrowFieldGeneric(fi_idx) => { + Instruction::ImmBorrowFieldGeneric(fi_idx) + | Instruction::MutBorrowFieldGeneric(fi_idx) => { // TODO: Even though the types are not needed for execution, we still // instantiate them for gas metering. // @@ -2051,7 +2177,8 @@ impl Frame { gas_meter.charge_create_ty(struct_ty_count)?; gas_meter.charge_create_ty(field_ty_count)?; - let instr = if matches!(instruction, Bytecode::MutBorrowFieldGeneric(_)) { + let instr = if matches!(instruction, Instruction::MutBorrowFieldGeneric(_)) + { S::MutBorrowFieldGeneric } else { S::ImmBorrowFieldGeneric @@ -2064,8 +2191,10 @@ impl Frame { let field_ref = reference.borrow_field(offset)?; interpreter.operand_stack.push(field_ref)?; }, - Bytecode::ImmBorrowVariantField(idx) | Bytecode::MutBorrowVariantField(idx) => { - let instr = if matches!(instruction, Bytecode::MutBorrowVariantField(_)) { + Instruction::ImmBorrowVariantField(idx) + | Instruction::MutBorrowVariantField(idx) => { + let instr = if matches!(instruction, Instruction::MutBorrowVariantField(_)) + { S::MutBorrowVariantField } else { S::ImmBorrowVariantField @@ -2085,8 +2214,8 @@ impl Frame { )?; interpreter.operand_stack.push(field_ref)?; }, - Bytecode::ImmBorrowVariantFieldGeneric(fi_idx) - | Bytecode::MutBorrowVariantFieldGeneric(fi_idx) => { + Instruction::ImmBorrowVariantFieldGeneric(fi_idx) + | Instruction::MutBorrowVariantFieldGeneric(fi_idx) => { // TODO: Even though the types are not needed for execution, we still // instantiate them for gas metering. // @@ -2098,7 +2227,7 @@ impl Frame { gas_meter.charge_create_ty(field_ty_count)?; let instr = match instruction { - Bytecode::MutBorrowVariantFieldGeneric(_) => { + Instruction::MutBorrowVariantFieldGeneric(_) => { S::MutBorrowVariantFieldGeneric }, _ => S::ImmBorrowVariantFieldGeneric, @@ -2118,29 +2247,14 @@ impl Frame { )?; interpreter.operand_stack.push(field_ref)?; }, - Bytecode::Pack(sd_idx) => { - let get_field_count_charge_gas_and_check_depth = - || -> PartialVMResult { - let field_count = self.field_count(*sd_idx); - let struct_type = self.get_struct_ty(*sd_idx); - check_depth_of_type(module_storage, &struct_type)?; - Ok(field_count) - }; - - let field_count = if RTCaches::caches_enabled() { - let cached_field_count = - &frame_cache.per_instruction_cache[self.pc as usize]; - if let PerInstructionCache::Pack(ref field_count) = cached_field_count { - *field_count - } else { - let field_count = get_field_count_charge_gas_and_check_depth()?; - frame_cache.per_instruction_cache[self.pc as usize] = - PerInstructionCache::Pack(field_count); - field_count - } - } else { - get_field_count_charge_gas_and_check_depth()? - }; + Instruction::Pack(sd_idx) => { + let field_count = self.field_count(*sd_idx); + let struct_type = self.get_struct_ty(*sd_idx); + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + &struct_type, + )?; gas_meter.charge_pack( false, @@ -2151,10 +2265,14 @@ impl Frame { .operand_stack .push(Value::struct_(Struct::pack(args)))?; }, - Bytecode::PackVariant(idx) => { + Instruction::PackVariant(idx) => { let info = self.get_struct_variant_at(*idx); let struct_type = self.create_struct_ty(&info.definition_struct_type); - check_depth_of_type(module_storage, &struct_type)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + &struct_type, + )?; gas_meter.charge_pack_variant( false, interpreter @@ -2166,46 +2284,25 @@ impl Frame { .operand_stack .push(Value::struct_(Struct::pack_variant(info.variant, args)))?; }, - Bytecode::PackGeneric(si_idx) => { + Instruction::PackGeneric(si_idx) => { // TODO: Even though the types are not needed for execution, we still // instantiate them for gas metering. // // This is a bit wasteful since the newly created types are // dropped immediately. + let field_tys = frame_cache.get_struct_fields_types(*si_idx, self)?; + for (_, ty_count) in field_tys { + gas_meter.charge_create_ty(*ty_count)?; + } - let mut get_field_count_charge_gas_and_check_depth = - |frame_cache: &mut FrameTypeCache| -> PartialVMResult { - let field_tys = - frame_cache.get_struct_fields_types(*si_idx, self)?; - - for (_, ty_count) in field_tys { - gas_meter.charge_create_ty(*ty_count)?; - } - - let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; - gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; - Ok(self.field_instantiation_count(*si_idx)) - }; - - let field_count = if RTCaches::caches_enabled() { - let cached_field_count = - &frame_cache.per_instruction_cache[self.pc as usize]; - - if let PerInstructionCache::PackGeneric(ref field_count) = - cached_field_count - { - *field_count - } else { - let field_count = - get_field_count_charge_gas_and_check_depth(frame_cache)?; - frame_cache.per_instruction_cache[self.pc as usize] = - PerInstructionCache::PackGeneric(field_count); - field_count - } - } else { - get_field_count_charge_gas_and_check_depth(frame_cache)? - }; + let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; + gas_meter.charge_create_ty(ty_count)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; + let field_count = self.field_instantiation_count(*si_idx); gas_meter.charge_pack( true, @@ -2216,7 +2313,7 @@ impl Frame { .operand_stack .push(Value::struct_(Struct::pack(args)))?; }, - Bytecode::PackVariantGeneric(si_idx) => { + Instruction::PackVariantGeneric(si_idx) => { let field_tys = frame_cache.get_struct_variant_fields_types(*si_idx, self)?; @@ -2226,7 +2323,11 @@ impl Frame { let (ty, ty_count) = frame_cache.get_struct_variant_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; let info = self.get_struct_variant_instantiation_at(*si_idx); gas_meter.charge_pack_variant( @@ -2240,16 +2341,14 @@ impl Frame { .operand_stack .push(Value::struct_(Struct::pack_variant(info.variant, args)))?; }, - Bytecode::Unpack(_sd_idx) => { + Instruction::Unpack(_sd_idx) => { let struct_value = interpreter.operand_stack.pop_as::()?; - gas_meter.charge_unpack(false, struct_value.field_views())?; - for value in struct_value.unpack()? { interpreter.operand_stack.push(value)?; } }, - Bytecode::UnpackVariant(sd_idx) => { + Instruction::UnpackVariant(sd_idx) => { let struct_value = interpreter.operand_stack.pop_as::()?; gas_meter.charge_unpack_variant(false, struct_value.field_views())?; @@ -2261,7 +2360,7 @@ impl Frame { interpreter.operand_stack.push(value)?; } }, - Bytecode::UnpackGeneric(si_idx) => { + Instruction::UnpackGeneric(si_idx) => { // TODO: Even though the types are not needed for execution, we still // instantiate them for gas metering. // @@ -2273,36 +2372,26 @@ impl Frame { gas_meter.charge_create_ty(*ty_count)?; } - let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; + let (_, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; - let struct_ = interpreter.operand_stack.pop_as::()?; - gas_meter.charge_unpack(true, struct_.field_views())?; - - // TODO: Whether or not we want this gas metering in the loop is - // questionable. However, if we don't have it in the loop we could wind up - // doing a fair bit of work before charging for it. for value in struct_.unpack()? { interpreter.operand_stack.push(value)?; } }, - Bytecode::UnpackVariantGeneric(si_idx) => { + Instruction::UnpackVariantGeneric(si_idx) => { let ty_and_field_counts = frame_cache.get_struct_variant_fields_types(*si_idx, self)?; for (_, ty_count) in ty_and_field_counts { gas_meter.charge_create_ty(*ty_count)?; } - let (ty, ty_count) = frame_cache.get_struct_variant_type(*si_idx, self)?; + let (_, ty_count) = frame_cache.get_struct_variant_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; - let struct_ = interpreter.operand_stack.pop_as::()?; - gas_meter.charge_unpack_variant(true, struct_.field_views())?; let info = self.get_struct_variant_instantiation_at(*si_idx); @@ -2312,7 +2401,7 @@ impl Frame { interpreter.operand_stack.push(value)?; } }, - Bytecode::TestVariant(sd_idx) => { + Instruction::TestVariant(sd_idx) => { let reference = interpreter.operand_stack.pop_as::()?; gas_meter.charge_simple_instr(S::TestVariant)?; let info = self.get_struct_variant_at(*sd_idx); @@ -2320,7 +2409,7 @@ impl Frame { .operand_stack .push(reference.test_variant(info.variant)?)?; }, - Bytecode::TestVariantGeneric(sd_idx) => { + Instruction::TestVariantGeneric(sd_idx) => { // TODO: Even though the types are not needed for execution, we still // instantiate them for gas metering. // @@ -2337,44 +2426,71 @@ impl Frame { .operand_stack .push(reference.test_variant(info.variant)?)?; }, - Bytecode::PackClosure(fh_idx, mask) => { + Instruction::PackClosure(fh_idx, mask) => { + gas_meter.charge_pack_closure( + false, + interpreter + .operand_stack + .last_n(mask.captured_count() as usize)?, + )?; + + let ty_args_id = interpreter.ty_pool.intern_ty_args(&[]); let function = self .build_loaded_function_from_handle_and_ty_args( - module_storage, + interpreter.loader, + gas_meter, + traversal_context, *fh_idx, vec![], + ty_args_id, ) .map(Rc::new)?; + RTTCheck::check_pack_closure_visibility(&self.function, &function)?; + if RTTCheck::should_perform_checks(&self.function.function) { + verify_pack_closure( + self.ty_builder(), + &mut interpreter.operand_stack, + &function, + *mask, + )?; + } let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( - module_storage.runtime_environment(), + interpreter.layout_converter, + gas_meter, + traversal_context, function.clone(), *mask, )?; interpreter .operand_stack .push(Value::closure(Box::new(lazy_function), captured))?; - - if RTTCheck::should_perform_checks() { - verify_pack_closure( - self.ty_builder(), - &mut interpreter.operand_stack, - &function, - *mask, - )?; - } }, - Bytecode::PackClosureGeneric(fi_idx, mask) => { - let ty_args = - self.instantiate_generic_function(Some(gas_meter), *fi_idx)?; + Instruction::PackClosureGeneric(fi_idx, mask) => { + gas_meter.charge_pack_closure( + true, + interpreter + .operand_stack + .last_n(mask.captured_count() as usize)?, + )?; + + let (ty_args, ty_args_id) = self.instantiate_generic_function( + interpreter.ty_pool, + Some(gas_meter), + *fi_idx, + )?; let function = self .build_loaded_function_from_instantiation_and_ty_args( - module_storage, + interpreter.loader, + gas_meter, + traversal_context, *fi_idx, ty_args, + ty_args_id, ) .map(Rc::new)?; - if RTTCheck::should_perform_checks() { + RTTCheck::check_pack_closure_visibility(&self.function, &function)?; + if RTTCheck::should_perform_checks(&self.function.function) { verify_pack_closure( self.ty_builder(), &mut interpreter.operand_stack, @@ -2384,7 +2500,9 @@ impl Frame { } let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( - module_storage.runtime_environment(), + interpreter.layout_converter, + gas_meter, + traversal_context, function.clone(), *mask, )?; @@ -2392,136 +2510,187 @@ impl Frame { .operand_stack .push(Value::closure(Box::new(lazy_function), captured))?; }, - Bytecode::ReadRef => { + Instruction::ReadRef => { let reference = interpreter.operand_stack.pop_as::()?; gas_meter.charge_read_ref(reference.value_view())?; let value = reference.read_ref()?; interpreter.operand_stack.push(value)?; }, - Bytecode::WriteRef => { + Instruction::WriteRef => { let reference = interpreter.operand_stack.pop_as::()?; let value = interpreter.operand_stack.pop()?; gas_meter.charge_write_ref(&value, reference.value_view())?; reference.write_ref(value)?; }, - Bytecode::CastU8 => { + Instruction::CastU8 => { gas_meter.charge_simple_instr(S::CastU8)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u8(integer_value.cast_u8()?))?; }, - Bytecode::CastU16 => { + Instruction::CastU16 => { gas_meter.charge_simple_instr(S::CastU16)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u16(integer_value.cast_u16()?))?; }, - Bytecode::CastU32 => { + Instruction::CastU32 => { gas_meter.charge_simple_instr(S::CastU32)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u32(integer_value.cast_u32()?))?; }, - Bytecode::CastU64 => { + Instruction::CastU64 => { gas_meter.charge_simple_instr(S::CastU64)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u64(integer_value.cast_u64()?))?; }, - Bytecode::CastU128 => { + Instruction::CastU128 => { gas_meter.charge_simple_instr(S::CastU128)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u128(integer_value.cast_u128()?))?; }, - Bytecode::CastU256 => { + Instruction::CastU256 => { gas_meter.charge_simple_instr(S::CastU256)?; - let integer_value = interpreter.operand_stack.pop_as::()?; + let integer_value = interpreter.operand_stack.pop()?; interpreter .operand_stack .push(Value::u256(integer_value.cast_u256()?))?; }, + Instruction::CastI8 => { + gas_meter.charge_simple_instr(S::CastI8)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i8(integer_value.cast_i8()?))?; + }, + Instruction::CastI16 => { + gas_meter.charge_simple_instr(S::CastI16)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i16(integer_value.cast_i16()?))?; + }, + Instruction::CastI32 => { + gas_meter.charge_simple_instr(S::CastI32)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i32(integer_value.cast_i32()?))?; + }, + Instruction::CastI64 => { + gas_meter.charge_simple_instr(S::CastI64)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i64(integer_value.cast_i64()?))?; + }, + Instruction::CastI128 => { + gas_meter.charge_simple_instr(S::CastI128)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i128(integer_value.cast_i128()?))?; + }, + Instruction::CastI256 => { + gas_meter.charge_simple_instr(S::CastI256)?; + let integer_value = interpreter.operand_stack.pop()?; + interpreter + .operand_stack + .push(Value::i256(integer_value.cast_i256()?))?; + }, + // Arithmetic Operations - Bytecode::Add => { + Instruction::Add => { gas_meter.charge_simple_instr(S::Add)?; - interpreter.binop_int(IntegerValue::add_checked)? + interpreter.binop(Value::add_checked)?; }, - Bytecode::Sub => { + Instruction::Sub => { gas_meter.charge_simple_instr(S::Sub)?; - interpreter.binop_int(IntegerValue::sub_checked)? + interpreter.binop(Value::sub_checked)?; }, - Bytecode::Mul => { + Instruction::Mul => { gas_meter.charge_simple_instr(S::Mul)?; - interpreter.binop_int(IntegerValue::mul_checked)? + interpreter.binop(Value::mul_checked)?; }, - Bytecode::Mod => { + Instruction::Mod => { gas_meter.charge_simple_instr(S::Mod)?; - interpreter.binop_int(IntegerValue::rem_checked)? + interpreter.binop(Value::rem_checked)?; }, - Bytecode::Div => { + Instruction::Div => { gas_meter.charge_simple_instr(S::Div)?; - interpreter.binop_int(IntegerValue::div_checked)? + interpreter.binop(Value::div_checked)?; + }, + Instruction::Negate => { + gas_meter.charge_simple_instr(S::Negate)?; + interpreter.unop(Value::negate_checked)?; }, - Bytecode::BitOr => { + Instruction::BitOr => { gas_meter.charge_simple_instr(S::BitOr)?; - interpreter.binop_int(IntegerValue::bit_or)? + interpreter.binop(Value::bit_or)?; }, - Bytecode::BitAnd => { + Instruction::BitAnd => { gas_meter.charge_simple_instr(S::BitAnd)?; - interpreter.binop_int(IntegerValue::bit_and)? + interpreter.binop(Value::bit_and)?; }, - Bytecode::Xor => { + Instruction::Xor => { gas_meter.charge_simple_instr(S::Xor)?; - interpreter.binop_int(IntegerValue::bit_xor)? + interpreter.binop(Value::bit_xor)?; }, - Bytecode::Shl => { + Instruction::Shl => { gas_meter.charge_simple_instr(S::Shl)?; let rhs = interpreter.operand_stack.pop_as::()?; - let lhs = interpreter.operand_stack.pop_as::()?; - interpreter - .operand_stack - .push(lhs.shl_checked(rhs)?.into_value())?; + let lhs = interpreter.operand_stack.pop()?; + interpreter.operand_stack.push(lhs.shl_checked(rhs)?)?; }, - Bytecode::Shr => { + Instruction::Shr => { gas_meter.charge_simple_instr(S::Shr)?; let rhs = interpreter.operand_stack.pop_as::()?; - let lhs = interpreter.operand_stack.pop_as::()?; - interpreter - .operand_stack - .push(lhs.shr_checked(rhs)?.into_value())?; + let lhs = interpreter.operand_stack.pop()?; + interpreter.operand_stack.push(lhs.shr_checked(rhs)?)?; }, - Bytecode::Or => { + Instruction::Or => { gas_meter.charge_simple_instr(S::Or)?; - interpreter.binop_bool(|l, r| Ok(l || r))? + interpreter.binop_bool(|l, r| Ok(l || r))?; }, - Bytecode::And => { + Instruction::And => { gas_meter.charge_simple_instr(S::And)?; - interpreter.binop_bool(|l, r| Ok(l && r))? + interpreter.binop_bool(|l, r| Ok(l && r))?; }, - Bytecode::Lt => { + Instruction::Lt => { gas_meter.charge_simple_instr(S::Lt)?; - interpreter.binop_bool(IntegerValue::lt)? + interpreter.binop_rel(Value::lt)?; }, - Bytecode::Gt => { + Instruction::Gt => { gas_meter.charge_simple_instr(S::Gt)?; - interpreter.binop_bool(IntegerValue::gt)? + interpreter.binop_rel(Value::gt)?; }, - Bytecode::Le => { + Instruction::Le => { gas_meter.charge_simple_instr(S::Le)?; - interpreter.binop_bool(IntegerValue::le)? + interpreter.binop_rel(Value::le)?; }, - Bytecode::Ge => { + Instruction::Ge => { gas_meter.charge_simple_instr(S::Ge)?; - interpreter.binop_bool(IntegerValue::ge)? + interpreter.binop_rel(Value::ge)?; }, - Bytecode::Abort => { + Instruction::Abort => { gas_meter.charge_simple_instr(S::Abort)?; let error_code = interpreter.operand_stack.pop_as::()?; + if is_tracing_for!(TraceCategory::Abort(error_code)) { + let mut str = String::new(); + interpreter.debug_print_stack_trace( + &mut str, + interpreter.loader.runtime_environment(), + )?; + eprintln!("trace abort({}): {}", error_code, str); + } let error = PartialVMError::new(StatusCode::ABORTED) .with_sub_status(error_code) .with_message(format!( @@ -2529,9 +2698,13 @@ impl Frame { self.function.name_as_pretty_string(), self.pc, )); + + // Before returning an abort error, ensure the instruction is recorded in + // the trace, so the trace is full. + trace_recorder.record_successful_instruction(instruction); return Err(error); }, - Bytecode::Eq => { + Instruction::Eq => { let lhs = interpreter.operand_stack.pop()?; let rhs = interpreter.operand_stack.pop()?; gas_meter.charge_eq(&lhs, &rhs)?; @@ -2539,7 +2712,7 @@ impl Frame { .operand_stack .push(Value::bool(lhs.equals(&rhs)?))?; }, - Bytecode::Neq => { + Instruction::Neq => { let lhs = interpreter.operand_stack.pop()?; let rhs = interpreter.operand_stack.pop()?; gas_meter.charge_neq(&lhs, &rhs)?; @@ -2547,24 +2720,23 @@ impl Frame { .operand_stack .push(Value::bool(!lhs.equals(&rhs)?))?; }, - Bytecode::MutBorrowGlobal(sd_idx) | Bytecode::ImmBorrowGlobal(sd_idx) => { - let is_mut = matches!(instruction, Bytecode::MutBorrowGlobal(_)); + Instruction::MutBorrowGlobal(sd_idx) | Instruction::ImmBorrowGlobal(sd_idx) => { + let is_mut = matches!(instruction, Instruction::MutBorrowGlobal(_)); let addr = interpreter.operand_stack.pop_as::()?; let ty = self.get_struct_ty(*sd_idx); interpreter.borrow_global( is_mut, false, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, &ty, )?; }, - Bytecode::MutBorrowGlobalGeneric(si_idx) - | Bytecode::ImmBorrowGlobalGeneric(si_idx) => { - let is_mut = matches!(instruction, Bytecode::MutBorrowGlobalGeneric(_)); + Instruction::MutBorrowGlobalGeneric(si_idx) + | Instruction::ImmBorrowGlobalGeneric(si_idx) => { + let is_mut = matches!(instruction, Instruction::MutBorrowGlobalGeneric(_)); let addr = interpreter.operand_stack.pop_as::()?; let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; @@ -2572,68 +2744,63 @@ impl Frame { is_mut, true, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, ty, )?; }, - Bytecode::Exists(sd_idx) => { + Instruction::Exists(sd_idx) => { let addr = interpreter.operand_stack.pop_as::()?; let ty = self.get_struct_ty(*sd_idx); interpreter.exists( false, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, &ty, )?; }, - Bytecode::ExistsGeneric(si_idx) => { + Instruction::ExistsGeneric(si_idx) => { let addr = interpreter.operand_stack.pop_as::()?; let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; interpreter.exists( true, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, ty, )?; }, - Bytecode::MoveFrom(sd_idx) => { + Instruction::MoveFrom(sd_idx) => { let addr = interpreter.operand_stack.pop_as::()?; let ty = self.get_struct_ty(*sd_idx); interpreter.move_from( false, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, &ty, )?; }, - Bytecode::MoveFromGeneric(si_idx) => { + Instruction::MoveFromGeneric(si_idx) => { let addr = interpreter.operand_stack.pop_as::()?; let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; interpreter.move_from( true, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, ty, )?; }, - Bytecode::MoveTo(sd_idx) => { + Instruction::MoveTo(sd_idx) => { let resource = interpreter.operand_stack.pop()?; let signer_reference = interpreter.operand_stack.pop_as::()?; let addr = signer_reference @@ -2645,15 +2812,14 @@ impl Frame { interpreter.move_to( false, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, &ty, resource, )?; }, - Bytecode::MoveToGeneric(si_idx) => { + Instruction::MoveToGeneric(si_idx) => { let resource = interpreter.operand_stack.pop()?; let signer_reference = interpreter.operand_stack.pop_as::()?; let addr = signer_reference @@ -2666,105 +2832,103 @@ impl Frame { interpreter.move_to( true, data_cache, - resource_resolver, - module_storage, gas_meter, + traversal_context, addr, ty, resource, )?; }, - Bytecode::FreezeRef => { - gas_meter.charge_simple_instr(S::FreezeRef)?; + Instruction::FreezeRef => { // FreezeRef should just be a null op as we don't distinguish between mut // and immut ref at runtime. + gas_meter.charge_simple_instr(S::FreezeRef)?; }, - Bytecode::Not => { + Instruction::Not => { gas_meter.charge_simple_instr(S::Not)?; let value = !interpreter.operand_stack.pop_as::()?; interpreter.operand_stack.push(Value::bool(value))?; }, - Bytecode::Nop => { + Instruction::Nop => { gas_meter.charge_simple_instr(S::Nop)?; }, - Bytecode::VecPack(si, num) => { + Instruction::VecPack(si, num) => { let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; - gas_meter.charge_vec_pack( - make_ty!(ty), - interpreter.operand_stack.last_n(*num as usize)?, + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, )?; + gas_meter + .charge_vec_pack(interpreter.operand_stack.last_n(*num as usize)?)?; let elements = interpreter.operand_stack.popn(*num as u16)?; let value = Vector::pack(ty, elements)?; interpreter.operand_stack.push(value)?; }, - Bytecode::VecLen(si) => { + Instruction::VecLen(si) => { let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - gas_meter.charge_vec_len(make_ty!(ty))?; - let value = vec_ref.len(ty)?; + gas_meter.charge_vec_len()?; + let value = vec_ref.len()?; interpreter.operand_stack.push(value)?; }, - Bytecode::VecImmBorrow(si) => { + Instruction::VecImmBorrow(si) => { let idx = interpreter.operand_stack.pop_as::()? as usize; let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - let res = vec_ref.borrow_elem(idx, ty); - gas_meter.charge_vec_borrow(false, make_ty!(ty), res.is_ok())?; - interpreter.operand_stack.push(res?)?; + gas_meter.charge_vec_borrow(false)?; + let elem = vec_ref.borrow_elem(idx)?; + interpreter.operand_stack.push(elem)?; }, - Bytecode::VecMutBorrow(si) => { + Instruction::VecMutBorrow(si) => { let idx = interpreter.operand_stack.pop_as::()? as usize; let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - let res = vec_ref.borrow_elem(idx, ty); - gas_meter.charge_vec_borrow(true, make_ty!(ty), res.is_ok())?; - interpreter.operand_stack.push(res?)?; + gas_meter.charge_vec_borrow(true)?; + let elem = vec_ref.borrow_elem(idx)?; + interpreter.operand_stack.push(elem)?; }, - Bytecode::VecPushBack(si) => { + Instruction::VecPushBack(si) => { let elem = interpreter.operand_stack.pop()?; let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - gas_meter.charge_vec_push_back(make_ty!(ty), &elem)?; - vec_ref.push_back(elem, ty)?; + gas_meter.charge_vec_push_back(&elem)?; + vec_ref.push_back(elem)?; }, - Bytecode::VecPopBack(si) => { + Instruction::VecPopBack(si) => { let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - let res = vec_ref.pop(ty); - gas_meter.charge_vec_pop_back(make_ty!(ty), res.as_ref().ok())?; + let res = vec_ref.pop(); + gas_meter.charge_vec_pop_back(res.as_ref().ok())?; interpreter.operand_stack.push(res?)?; }, - Bytecode::VecUnpack(si, num) => { + Instruction::VecUnpack(si, num) => { let vec_val = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - gas_meter.charge_vec_unpack( - make_ty!(ty), - NumArgs::new(*num), - vec_val.elem_views(), - )?; - let elements = vec_val.unpack(ty, *num)?; + gas_meter.charge_vec_unpack(NumArgs::new(*num), vec_val.elem_views())?; + let elements = vec_val.unpack(*num)?; for value in elements { interpreter.operand_stack.push(value)?; } }, - Bytecode::VecSwap(si) => { + Instruction::VecSwap(si) => { let idx2 = interpreter.operand_stack.pop_as::()? as usize; let idx1 = interpreter.operand_stack.pop_as::()? as usize; let vec_ref = interpreter.operand_stack.pop_as::()?; - let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; + let (_, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - gas_meter.charge_vec_swap(make_ty!(ty))?; - vec_ref.swap(idx1, idx2, ty)?; + gas_meter.charge_vec_swap()?; + vec_ref.swap(idx1, idx2)?; }, } + trace_recorder.record_successful_instruction(instruction); RTTCheck::post_execution_type_stack_transition( self, @@ -2772,31 +2936,38 @@ impl Frame { instruction, frame_cache, )?; - RTTCheck::check_operand_stack_balance(&interpreter.operand_stack)?; - + RTRCheck::post_execution_transition( + self, + instruction, + &mut interpreter.ref_state, + frame_cache, + )?; // invariant: advance to pc +1 is iff instruction at pc executed without aborting self.pc += 1; } - // ok we are out, it's a branch, check the pc for good luck - // TODO: re-work the logic here. Tests should have a more - // natural way to plug in + + // If out of the loop - it was a branch. if self.pc as usize >= code.len() { - if cfg!(test) { - // In order to test the behavior of an instruction stream, hitting end of the - // code should report no error so that we can check the - // locals. - return Ok(ExitCode::Return); - } else { - return Err(PartialVMError::new(StatusCode::PC_OVERFLOW)); - } + return Err(PartialVMError::new(StatusCode::PC_OVERFLOW)); } } } - fn location(&self) -> Location { + pub(crate) fn location(&self) -> Location { match self.function.module_id() { None => Location::Script, Some(id) => Location::Module(id.clone()), } } + + #[cold] + fn stack_size_mismatch_error(&self, expected: usize, actual: usize) -> PartialVMError { + let err = PartialVMError::new_invariant_violation(format!( + "Stack size mismatch when returning from {}: expected: {}, got: {}", + self.function.name_as_pretty_string(), + expected, + actual + )); + err.with_sub_status(EPARANOID_FAILURE) + } } diff --git a/third_party/move/move-vm/runtime/src/interpreter_caches.rs b/third_party/move/move-vm/runtime/src/interpreter_caches.rs new file mode 100644 index 00000000000..2ce457a6b98 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/interpreter_caches.rs @@ -0,0 +1,68 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Interpreter caches keep a record of cached data for each function call observed during +//! execution (e.g., caching [FrameTypeCache]). As a result, when calling function `foo` +//! at multiple call-sites, cached information from `foo` is re-used and only computed once +//! on the first call. + +use crate::{ + frame_type_cache::FrameTypeCache, + loader::{FunctionPtr, GenericFunctionPtr}, + LoadedFunction, +}; +use std::{cell::RefCell, collections::HashMap, rc::Rc}; + +/// Interpreter-level caches for function data (single-threaded) +pub struct InterpreterFunctionCaches { + function_instruction_caches: HashMap>>, + generic_function_instruction_caches: HashMap>>, +} + +impl InterpreterFunctionCaches { + pub fn new() -> Self { + Self { + function_instruction_caches: HashMap::new(), + generic_function_instruction_caches: HashMap::new(), + } + } + + pub(crate) fn get_or_create_frame_cache( + &mut self, + function: &LoadedFunction, + ) -> Rc> { + if function.ty_args.is_empty() { + self.get_or_create_frame_cache_non_generic(function) + } else { + self.get_or_create_frame_cache_generic(function) + } + } + + /// Returns existing cache, or creates a new one for a non-generic function. + pub(crate) fn get_or_create_frame_cache_non_generic( + &mut self, + function: &LoadedFunction, + ) -> Rc> { + debug_assert!(function.ty_args().is_empty()); + + let ptr = FunctionPtr::from_loaded_function(function); + self.function_instruction_caches + .entry(ptr) + .or_insert_with(|| FrameTypeCache::make_rc_for_function(function)) + .clone() + } + + /// Returns existing cache, or creates a new one for a generic function. + pub(crate) fn get_or_create_frame_cache_generic( + &mut self, + function: &LoadedFunction, + ) -> Rc> { + debug_assert!(!function.ty_args().is_empty()); + + let ptr = GenericFunctionPtr::from_loaded_function(function); + self.generic_function_instruction_caches + .entry(ptr) + .or_insert_with(|| FrameTypeCache::make_rc_for_function(function)) + .clone() + } +} diff --git a/third_party/move/move-vm/runtime/src/lib.rs b/third_party/move/move-vm/runtime/src/lib.rs index 47a517b585b..019fb9827cf 100644 --- a/third_party/move/move-vm/runtime/src/lib.rs +++ b/third_party/move/move-vm/runtime/src/lib.rs @@ -8,7 +8,9 @@ //! The core Move VM logic. pub mod data_cache; +pub mod execution_tracing; mod interpreter; +mod interpreter_caches; mod loader; pub mod logging; pub mod move_vm; @@ -27,16 +29,16 @@ mod access_control; mod frame; mod frame_type_cache; mod reentrancy_checker; +mod runtime_ref_checks; mod runtime_type_checks; +mod runtime_type_checks_async; +pub use runtime_type_checks_async::TypeChecker; mod storage; pub use loader::{Function, LoadedFunction, LoadedFunctionOwner, Module, Script}; pub use storage::{ - code_storage::{ambassador_impl_CodeStorage, CodeStorage}, - dependencies_gas_charging::{ - check_dependencies_and_charge_gas, check_script_dependencies_and_check_gas, - check_type_tag_dependencies_and_charge_gas, - }, + code_storage::CodeStorage, + dependencies_gas_charging::check_dependencies_and_charge_gas, environment::{ ambassador_impl_WithRuntimeEnvironment, RuntimeEnvironment, WithRuntimeEnvironment, }, @@ -44,6 +46,36 @@ pub use storage::{ unsync_code_storage::{AsUnsyncCodeStorage, UnsyncCodeStorage}, unsync_module_storage::{AsUnsyncModuleStorage, BorrowedOrOwned, UnsyncModuleStorage}, }, - module_storage::{ambassador_impl_ModuleStorage, AsFunctionValueExtension, ModuleStorage}, + layout_cache::{LayoutCache, LayoutCacheEntry, NoOpLayoutCache, StructKey}, + loader::{ + eager::EagerLoader, + lazy::LazyLoader, + traits::{ + FunctionDefinitionLoader, InstantiatedFunctionLoader, LegacyLoaderConfig, Loader, + ScriptLoader, StructDefinitionLoader, + }, + }, + module_storage::{ + ambassador_impl_ModuleStorage, AsFunctionValueExtension, FunctionValueExtensionAdapter, + ModuleStorage, + }, publishing::{StagingModuleStorage, VerifiedModuleBundle}, + ty_layout_converter::LayoutWithDelayedFields, }; + +// TODO(lazy-loading): revisit this macro in favour of a callback or an enum. +#[macro_export] +macro_rules! dispatch_loader { + ($module_storage:expr, $loader:ident, $dispatch:stmt) => { + if $crate::WithRuntimeEnvironment::runtime_environment($module_storage) + .vm_config() + .enable_lazy_loading + { + let $loader = $crate::LazyLoader::new($module_storage); + $dispatch + } else { + let $loader = $crate::EagerLoader::new($module_storage); + $dispatch + } + }; +} diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index 7e3952f508c..5d437df499c 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -4,18 +4,17 @@ use crate::{ loader::{access_specifier_loader::load_access_specifier, Module, Script}, + module_traversal::TraversalContext, native_functions::{NativeFunction, NativeFunctions, UnboxedNativeFunction}, - storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, - ModuleStorage, RuntimeEnvironment, + storage::{loader::traits::Loader, ty_layout_converter::LayoutConverter}, }; use better_any::{Tid, TidAble, TidExt}; +use lazy_static::lazy_static; use move_binary_format::{ access::ModuleAccess, binary_views::BinaryIndexedView, errors::{Location, PartialVMError, PartialVMResult, VMResult}, - file_format::{ - Bytecode, CompiledModule, FunctionAttribute, FunctionDefinitionIndex, Visibility, - }, + file_format::{CompiledModule, FunctionAttribute, FunctionDefinitionIndex, Visibility}, }; use move_core_types::{ ability::AbilitySet, @@ -26,34 +25,69 @@ use move_core_types::{ value::MoveTypeLayout, vm_status::StatusCode, }; +use move_vm_profiler::ProfilerFunction; use move_vm_types::{ + gas::DependencyGasMeter, + instr::Instruction, loaded_data::{ runtime_access_specifier::AccessSpecifier, runtime_types::{StructIdentifier, Type}, }, + module_id_interner::InternedModuleId, + ty_interner::TypeVecId, values::{AbstractFunction, SerializedFunctionData}, }; -use std::{cell::RefCell, cmp::Ordering, fmt::Debug, rc::Rc, sync::Arc}; +use std::{ + cell::RefCell, + cmp::Ordering, + collections::BTreeSet, + fmt::{Debug, Formatter}, + hash::{Hash, Hasher}, + mem, + rc::Rc, + sync::Arc, +}; + +lazy_static! { + /// List of native functions that perform a dynamic dispatch via reflection. This was a hack + /// and with function values enabled should be replaced. Keeping the set to make sure one can + /// statically determine if a native call has dispatched or not. + static ref DISPATCHABLE_NATIVES: BTreeSet<&'static str> = BTreeSet::from([ + "dispatchable_withdraw", + "dispatchable_deposit", + "dispatchable_derived_balance", + "dispatchable_derived_supply", + "dispatchable_authenticate", + ]); +} /// A runtime function definition representation. pub struct Function { #[allow(unused)] pub(crate) file_format_version: u32, pub(crate) index: FunctionDefinitionIndex, - pub(crate) code: Vec, + pub(crate) code: Vec, pub(crate) ty_param_abilities: Vec, // TODO: Make `native` and `def_is_native` become an enum. pub(crate) native: Option, pub(crate) is_native: bool, + /// If true, this is a native function which does native dynamic dispatch (main use cases are + /// fungible asset and account abstraction). + pub(crate) is_dispatchable_native: bool, pub(crate) visibility: Visibility, pub(crate) is_entry: bool, pub(crate) name: Identifier, pub(crate) return_tys: Vec, + // For non-native functions: parameter types first and then local types, if any. + // For native functions, an empty vector (there are no locals). This is very important because + // gas is charged based on number of locals which should be 0 for native calls (to be backwards + // compatible). pub(crate) local_tys: Vec, pub(crate) param_tys: Vec, pub(crate) access_specifier: AccessSpecifier, pub(crate) is_persistent: bool, pub(crate) has_module_reentrancy_lock: bool, + pub(crate) is_trusted: bool, } /// For loaded function representation, specifies the owner: a script or a module. @@ -63,6 +97,40 @@ pub enum LoadedFunctionOwner { Module(Arc), } +impl Debug for LoadedFunctionOwner { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + LoadedFunctionOwner::Script(_) => f.write_str("script"), + LoadedFunctionOwner::Module(m) => { + write!( + f, + "{}::{}", + m.module.address().to_hex_literal(), + m.module.name() + ) + }, + } + } +} + +impl LoadedFunctionOwner { + #[cfg_attr(feature = "force-inline", inline(always))] + pub fn module_or_script_id(&self) -> &ModuleId { + match self { + LoadedFunctionOwner::Module(m) => Module::self_id(m), + LoadedFunctionOwner::Script(_) => language_storage::pseudo_script_module_id(), + } + } + + #[cfg_attr(feature = "force-inline", inline(always))] + pub fn interned_module_or_script_id(&self) -> InternedModuleId { + match self { + LoadedFunctionOwner::Module(m) => m.interned_id, + LoadedFunctionOwner::Script(s) => s.interned_id, + } + } +} + /// A loaded runtime function representation along with type arguments used to instantiate it. #[derive(Clone)] pub struct LoadedFunction { @@ -70,10 +138,19 @@ pub struct LoadedFunction { // A set of verified type arguments provided for this definition. If // function is not generic, an empty vector. pub ty_args: Vec, + // Unique identifier for type arguments. + pub ty_args_id: TypeVecId, // Definition of the loaded function. pub function: Arc, } +impl ProfilerFunction for LoadedFunction { + #[inline] + fn name(&self) -> String { + self.name_as_pretty_string() + } +} + impl LoadedFunction { pub(crate) fn owner(&self) -> &LoadedFunctionOwner { &self.owner @@ -96,6 +173,7 @@ impl LoadedFunction { /// Returns a reference to parent [Module] owning the function. Returns an invariant violation /// error if the function comes from a script. + #[cfg_attr(feature = "force-inline", inline(always))] pub fn owner_as_module(&self) -> VMResult<&Module> { match &self.owner { LoadedFunctionOwner::Module(module) => Ok(module.as_ref()), @@ -110,16 +188,51 @@ impl LoadedFunction { } } +/// Stable pointer identity for a non-generic [Function] within a single interpreter invocation. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub(crate) struct FunctionPtr(*const Function); + +impl FunctionPtr { + pub(crate) fn from_loaded_function(function: &LoadedFunction) -> Self { + // Pointer identity can be used since the loader guarantees that any loaded function has + // exactly one `Arc`. + Self(Arc::as_ptr(&function.function)) + } +} + +impl Hash for FunctionPtr { + fn hash(&self, state: &mut H) { + state.write_usize(self.0 as usize); + } +} + +/// Stable pointer identity for a generic [Function] within a single interpreter invocation. +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub(crate) struct GenericFunctionPtr(FunctionPtr, TypeVecId); + +impl GenericFunctionPtr { + pub(crate) fn from_loaded_function(function: &LoadedFunction) -> Self { + Self( + FunctionPtr::from_loaded_function(function), + function.ty_args_id, + ) + } +} + /// A lazy loaded function, which can either be unresolved (as resulting /// from deserialization) or resolved, and then forwarding to a /// `LoadedFunction`. This is wrapped into a Rc so one can clone the /// function while sharing the loading state. #[derive(Clone, Tid)] -pub(crate) struct LazyLoadedFunction(pub(crate) Rc>); +pub(crate) struct LazyLoadedFunction { + pub(crate) state: Rc>, +} #[derive(Clone)] pub(crate) enum LazyLoadedFunctionState { Unresolved { + // Note: this contains layouts from storage, which may be out-dated (e.g., storing only old + // enum variant layouts even when enum has been upgraded to contain more variants). data: SerializedFunctionData, }, Resolved { @@ -131,29 +244,111 @@ pub(crate) enum LazyLoadedFunctionState { // unresolved case, the type argument tags are stored with the serialized data. ty_args: Vec, mask: ClosureMask, + // Layouts for captured arguments. The invariant is that these are always set for storable + // closures at construction time. Non-storable closures just have None as they will not be + // serialized anyway. + captured_layouts: Option>, }, } impl LazyLoadedFunction { pub(crate) fn new_unresolved(data: SerializedFunctionData) -> Self { - Self(Rc::new(RefCell::new(LazyLoadedFunctionState::Unresolved { - data, - }))) + Self { + state: Rc::new(RefCell::new(LazyLoadedFunctionState::Unresolved { data })), + } } pub(crate) fn new_resolved( - runtime_environment: &RuntimeEnvironment, + layout_converter: &LayoutConverter, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, fun: Rc, mask: ClosureMask, ) -> PartialVMResult { + let runtime_environment = layout_converter.runtime_environment(); let ty_args = fun .ty_args .iter() .map(|t| runtime_environment.ty_to_ty_tag(t)) .collect::>>()?; - Ok(Self(Rc::new(RefCell::new( - LazyLoadedFunctionState::Resolved { fun, ty_args, mask }, - )))) + + // When building a closure, if it captures arguments, and it is persistent (i.e., it may + // be stored to storage), pre-compute layouts which will be stored alongside the captured + // arguments. This way layouts always exist for storable closures and there is no need to + // construct them at serialization time. This makes loading and metering logic much simpler + // while adding layout construction overhead only for storable closures. + let captured_layouts = fun + .function + .is_persistent() + .then(|| { + // In case there are delayed fields when constructing captured layouts, we need to + // fail early to not allow their capturing altogether. + Self::construct_captured_layouts( + layout_converter, + gas_meter, + traversal_context, + &fun, + mask, + )? + .ok_or_else(|| { + PartialVMError::new(StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS) + .with_message("Function values cannot capture delayed fields".to_string()) + }) + }) + .transpose()?; + + Ok(Self { + state: Rc::new(RefCell::new(LazyLoadedFunctionState::Resolved { + fun, + ty_args, + mask, + captured_layouts, + })), + }) + } + + /// For a given function and a mask, constructs a vector of layouts for the captured arguments. + /// Returns [None] if there are any captured delayed fields in the layouts (i.e., the captured + /// values are not serializable not "displayable"). For all other failures, an error is + /// returned. + pub(crate) fn construct_captured_layouts( + layout_converter: &LayoutConverter, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + fun: &LoadedFunction, + mask: ClosureMask, + ) -> PartialVMResult>> { + let ty_builder = &layout_converter + .runtime_environment() + .vm_config() + .ty_builder; + mask.extract(fun.param_tys(), true) + .into_iter() + .map(|ty| { + let layout = if fun.ty_args.is_empty() { + layout_converter.type_to_type_layout_with_delayed_fields( + gas_meter, + traversal_context, + ty, + true, + )? + } else { + let ty = ty_builder.create_ty_with_subst(ty, &fun.ty_args)?; + layout_converter.type_to_type_layout_with_delayed_fields( + gas_meter, + traversal_context, + &ty, + true, + )? + }; + + // Do not allow delayed fields to be serialized. + // TODO(layouts): consider not cloning layouts for captured arguments. + Ok(layout + .into_layout_when_has_no_delayed_fields() + .map(|l| l.as_ref().clone())) + }) + .collect::>>>() } pub(crate) fn expect_this_impl( @@ -173,7 +368,7 @@ impl LazyLoadedFunction { &self, action: impl FnOnce(Option<&ModuleId>, &IdentStr, &[TypeTag]) -> T, ) -> T { - match &*self.0.borrow() { + match &*self.state.borrow() { LazyLoadedFunctionState::Unresolved { data: SerializedFunctionData { @@ -190,17 +385,17 @@ impl LazyLoadedFunction { } } - /// Executed an action with the resolved loaded function. If the function hasn't been - /// loaded yet, it will be loaded now. - #[allow(unused)] - pub(crate) fn with_resolved_function( + /// If the function hasn't been resolved (loaded) yet, loads it. The gas is also charged for + /// function loading and any other module accesses. + pub(crate) fn as_resolved( &self, - storage: &dyn ModuleStorage, - action: impl FnOnce(Rc) -> PartialVMResult, - ) -> PartialVMResult { - let mut state = self.0.borrow_mut(); - match &mut *state { - LazyLoadedFunctionState::Resolved { fun, .. } => action(fun.clone()), + loader: &impl Loader, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + ) -> PartialVMResult> { + let mut state = self.state.borrow_mut(); + Ok(match &mut *state { + LazyLoadedFunctionState::Resolved { fun, .. } => fun.clone(), LazyLoadedFunctionState::Unresolved { data: SerializedFunctionData { @@ -212,85 +407,28 @@ impl LazyLoadedFunction { captured_layouts, }, } => { - let fun = - Self::resolve(storage, module_id, fun_id, ty_args, *mask, captured_layouts)?; - let result = action(fun.clone()); + let fun = loader.load_closure( + gas_meter, + traversal_context, + module_id, + fun_id, + ty_args, + )?; *state = LazyLoadedFunctionState::Resolved { - fun, - ty_args: ty_args.clone(), + fun: fun.clone(), + ty_args: mem::take(ty_args), mask: *mask, + captured_layouts: Some(mem::take(captured_layouts)), }; - result + fun }, - } - } - - /// Resolves a function into a loaded function. This verifies existence of the named - /// function as well as whether it has the type used for deserializing the captured values. - fn resolve( - module_storage: &dyn ModuleStorage, - module_id: &ModuleId, - fun_id: &IdentStr, - ty_args: &[TypeTag], - mask: ClosureMask, - captured_layouts: &[MoveTypeLayout], - ) -> PartialVMResult> { - let function = module_storage - .load_function(module_id, fun_id, ty_args) - .map_err(|err| err.to_partial())?; - - // Verify that the function argument types match the layouts used for deserialization. - // This is only done in paranoid mode. Since integrity of storage - // and guarantee of public function, this should not able to fail. - if module_storage - .runtime_environment() - .vm_config() - .paranoid_type_checks - { - // TODO(#15664): Determine whether we need to charge gas here. - let captured_arg_types = mask.extract(function.param_tys(), true); - let converter = StorageLayoutConverter::new(module_storage); - if captured_arg_types.len() != captured_layouts.len() { - return Err(PartialVMError::new(StatusCode::FUNCTION_RESOLUTION_FAILURE) - .with_message( - "captured argument count does not match declared parameters".to_string(), - )); - } - - let ty_builder = &module_storage.runtime_environment().vm_config().ty_builder; - for (actual_arg_ty, serialized_layout) in - captured_arg_types.into_iter().zip(captured_layouts) - { - // We do not allow function values to capture any delayed fields, for now. Note - // that this is enforced at serialization time. Here we cannot enforce it because - // function value could have stored an old version of an enum without an aggregator - // but the new layout has the new variant with the aggregator. In any case, the - // serializer will fail on this resolved closure if there is an attempt to put it - // back into storage. - let actual_arg_layout = if function.ty_args().is_empty() { - converter.type_to_type_layout(actual_arg_ty)? - } else { - let actual_arg_ty = - ty_builder.create_ty_with_subst(actual_arg_ty, function.ty_args())?; - converter.type_to_type_layout(&actual_arg_ty)? - }; - - if !serialized_layout.is_compatible_with(&actual_arg_layout) { - return Err(PartialVMError::new(StatusCode::FUNCTION_RESOLUTION_FAILURE) - .with_message( - "stored captured argument layout does not match declared parameters" - .to_string(), - )); - } - } - } - Ok(Rc::new(function)) + }) } } impl AbstractFunction for LazyLoadedFunction { fn closure_mask(&self) -> ClosureMask { - let state = self.0.borrow(); + let state = self.state.borrow(); match &*state { LazyLoadedFunctionState::Resolved { mask, .. } => *mask, LazyLoadedFunctionState::Unresolved { @@ -319,7 +457,7 @@ impl AbstractFunction for LazyLoadedFunction { fn to_canonical_string(&self) -> String { self.with_name_and_ty_args(|module_id, fun_id, ty_args| { let prefix = if let Some(m) = module_id { - format!("0x{}::{}::", m.address(), m.name()) + format!("{}::{}", m.address(), m.name()) } else { "".to_string() }; @@ -355,11 +493,9 @@ impl LoadedFunction { } /// Returns the module id or, if it is a script, the pseudo module id for scripts. + #[cfg_attr(feature = "force-inline", inline(always))] pub fn module_or_script_id(&self) -> &ModuleId { - match &self.owner { - LoadedFunctionOwner::Module(m) => Module::self_id(m), - LoadedFunctionOwner::Script(_) => language_storage::pseudo_script_module_id(), - } + self.owner.module_or_script_id() } /// Returns the name of this function. @@ -374,7 +510,7 @@ impl LoadedFunction { /// Returns true if the loaded function has friend or private visibility. pub fn is_friend_or_private(&self) -> bool { - self.function.is_friend() || self.function.is_private() + self.is_friend() || self.is_private() } /// Returns true if the loaded function has public visibility. @@ -382,6 +518,16 @@ impl LoadedFunction { self.function.is_public() } + /// Returns true if the loaded function has friend visibility. + pub fn is_friend(&self) -> bool { + self.function.is_friend() + } + + /// Returns true if the loaded function has private visibility. + pub fn is_private(&self) -> bool { + self.function.is_private() + } + /// Returns an error if the loaded function is **NOT** an entry function. pub fn is_entry_or_err(&self) -> VMResult<()> { if !self.function.is_entry() { @@ -420,6 +566,7 @@ impl LoadedFunction { self.function.is_native() } + #[cfg_attr(feature = "force-inline", inline(always))] pub fn get_native(&self) -> PartialVMResult<&UnboxedNativeFunction> { self.function.get_native() } @@ -428,7 +575,7 @@ impl LoadedFunction { self.function.index } - pub(crate) fn code(&self) -> &[Bytecode] { + pub(crate) fn code(&self) -> &[Instruction] { &self.function.code } @@ -474,6 +621,9 @@ impl Function { let name = module.identifier_at(handle.name).to_owned(); let module_id = module.self_id(); + // For now, just framework code considered trusted, but this could be expanded. + let is_trusted = module.address().is_special(); + let (native, is_native) = if def.is_native() { let native = natives.resolve( module_id.address(), @@ -484,16 +634,20 @@ impl Function { } else { (None, false) }; + let is_dispatchable_native = + is_native && native.is_some() && DISPATCHABLE_NATIVES.contains(name.as_str()); + // Native functions do not have a code unit let code = match &def.code { - Some(code) => code.code.clone(), + Some(code) => code.code.iter().map(|b| b.clone().into()).collect(), None => vec![], }; let ty_param_abilities = handle.type_parameters.clone(); + let return_tys = signature_table[handle.return_.0 as usize].clone(); let local_tys = if let Some(code) = &def.code { let mut local_tys = signature_table[handle.parameters.0 as usize].clone(); - local_tys.append(&mut signature_table[code.locals.0 as usize].clone()); + local_tys.extend(signature_table[code.locals.0 as usize].clone()); local_tys } else { vec![] @@ -514,6 +668,7 @@ impl Function { ty_param_abilities, native, is_native, + is_dispatchable_native, visibility: def.visibility, is_entry: def.is_entry, name, @@ -523,6 +678,7 @@ impl Function { access_specifier, is_persistent: handle.attributes.contains(&FunctionAttribute::Persistent), has_module_reentrancy_lock: handle.attributes.contains(&FunctionAttribute::ModuleLock), + is_trusted, }) } @@ -552,6 +708,7 @@ impl Function { self.ty_param_abilities.len() } + /// Returns local types, including parameters and local variables. pub(crate) fn local_tys(&self) -> &[Type] { &self.local_tys } @@ -603,9 +760,11 @@ impl Function { // A function instantiation. #[derive(Clone, Debug)] pub(crate) struct FunctionInstantiation { - // index to `ModuleCache::functions` global table pub(crate) handle: FunctionHandle, pub(crate) instantiation: Vec, + // Unique ID for type arg instantiation. If type arguments are non-generic, is set. For generic + // type arguments kept not set. + pub(crate) ty_args_id: Option, } #[derive(Clone, Debug)] diff --git a/third_party/move/move-vm/runtime/src/loader/mod.rs b/third_party/move/move-vm/runtime/src/loader/mod.rs index 58b174b374b..bcbbdee4cfa 100644 --- a/third_party/move/move-vm/runtime/src/loader/mod.rs +++ b/third_party/move/move-vm/runtime/src/loader/mod.rs @@ -7,7 +7,8 @@ mod access_specifier_loader; mod function; pub use function::{Function, LoadedFunction, LoadedFunctionOwner}; pub(crate) use function::{ - FunctionHandle, FunctionInstantiation, LazyLoadedFunction, LazyLoadedFunctionState, + FunctionHandle, FunctionInstantiation, FunctionPtr, GenericFunctionPtr, LazyLoadedFunction, + LazyLoadedFunctionState, }; mod modules; @@ -20,4 +21,4 @@ pub use script::Script; mod single_signature_loader; mod type_loader; -use type_loader::intern_type; +use type_loader::convert_tok_to_type; diff --git a/third_party/move/move-vm/runtime/src/loader/modules.rs b/third_party/move/move-vm/runtime/src/loader/modules.rs index 0597fafb5e1..27cb76dc666 100644 --- a/third_party/move/move-vm/runtime/src/loader/modules.rs +++ b/third_party/move/move-vm/runtime/src/loader/modules.rs @@ -6,7 +6,7 @@ use crate::{ loader::{ function::{Function, FunctionHandle, FunctionInstantiation}, single_signature_loader::load_single_signatures_for_module, - type_loader::intern_type, + type_loader::{convert_tok_to_type, convert_toks_to_types}, }, native_functions::NativeFunctions, }; @@ -27,12 +27,16 @@ use move_core_types::{ vm_status::StatusCode, }; use move_vm_metrics::{Timer, VM_TIMER}; -use move_vm_types::loaded_data::{ - runtime_types::{StructIdentifier, StructLayout, StructType, Type}, - struct_name_indexing::{StructNameIndex, StructNameIndexMap}, +use move_vm_types::{ + loaded_data::{ + runtime_types::{StructIdentifier, StructLayout, StructType, Type}, + struct_name_indexing::{StructNameIndex, StructNameIndexMap}, + }, + module_id_interner::{InternedModuleId, InternedModuleIdPool}, + ty_interner::{InternedTypePool, TypeVecId}, }; use std::{ - collections::{BTreeMap, HashMap}, + collections::{BTreeMap, BTreeSet, HashMap}, fmt::Debug, ops::Deref, sync::Arc, @@ -46,6 +50,8 @@ use std::{ pub struct Module { id: ModuleId, + pub(crate) interned_id: InternedModuleId, + // size in bytes #[allow(dead_code)] pub(crate) size: usize, @@ -93,6 +99,10 @@ pub struct Module { // `VecMutBorrow(SignatureIndex)`, the `SignatureIndex` maps to a single `SignatureToken`, and // hence, a single type. pub(crate) single_signature_token_map: BTreeMap, + + // Friends of this module. Needed for re-entrancy visibility checks if lazy loading is enabled. + // Particularly, if a callee has friend visibility, the caller's module must be in this set. + pub(crate) friends: BTreeSet, } #[derive(Clone, Debug)] @@ -149,10 +159,18 @@ impl Module { size: usize, module: Arc, struct_name_index_map: &StructNameIndexMap, + ty_pool: &InternedTypePool, + module_id_pool: &InternedModuleIdPool, ) -> PartialVMResult { let _timer = VM_TIMER.timer_with_label("Module::new"); let id = module.self_id(); + let interned_id = module_id_pool.intern_by_ref(&id); + + let friends = module + .immediate_friends_iter() + .map(|(addr, name)| ModuleId::new(*addr, name.to_owned())) + .collect::>(); let mut structs = vec![]; let mut struct_instantiations = vec![]; @@ -168,6 +186,7 @@ impl Module { let mut function_map = HashMap::new(); let mut struct_map = HashMap::new(); let mut signature_table = vec![]; + let mut is_fully_instantiated_signature = vec![]; let mut struct_idxs = vec![]; let mut struct_names = vec![]; @@ -177,24 +196,21 @@ impl Module { let struct_name = module.identifier_at(struct_handle.name); let module_handle = module.module_handle_at(struct_handle.module); let module_id = module.module_id_for_handle(module_handle); - - let struct_name = StructIdentifier { - module: module_id, - name: struct_name.to_owned(), - }; + let struct_name = + StructIdentifier::new(module_id_pool, module_id, struct_name.to_owned()); struct_idxs.push(struct_name_index_map.struct_name_to_idx(&struct_name)?); struct_names.push(struct_name) } // Build signature table for signatures in module.signatures() { - signature_table.push( - signatures - .0 - .iter() - .map(|sig| intern_type(BinaryIndexedView::Module(&module), sig, &struct_idxs)) - .collect::>>()?, - ) + let (tys, is_fully_instantiated) = convert_toks_to_types( + BinaryIndexedView::Module(&module), + &signatures.0, + &struct_idxs, + )?; + signature_table.push(tys); + is_fully_instantiated_signature.push(is_fully_instantiated); } for (idx, struct_def) in module.struct_defs().iter().enumerate() { @@ -281,9 +297,17 @@ impl Module { for func_inst in module.function_instantiations() { let handle = function_refs[func_inst.handle.0 as usize].clone(); + let idx = func_inst.type_parameters.0 as usize; + let instantiation = signature_table[idx].clone(); + let ty_args_id = if is_fully_instantiated_signature[idx] { + Some(ty_pool.intern_ty_args(&instantiation)) + } else { + None + }; function_instantiations.push(FunctionInstantiation { handle, - instantiation: signature_table[func_inst.type_parameters.0 as usize].clone(), + instantiation, + ty_args_id, }); } @@ -357,6 +381,7 @@ impl Module { Ok(Self { id, + interned_id, size, module, structs, @@ -373,9 +398,49 @@ impl Module { function_map, struct_map, single_signature_token_map, + friends, }) } + /// Creates a new Module instance for testing purposes. + /// This method creates a minimal Module with empty contents. + #[cfg(any(test, feature = "testing"))] + pub fn new_for_test(module_id_pool: &InternedModuleIdPool, module_id: ModuleId) -> Self { + use move_binary_format::file_format::empty_module; + + // Start with an empty module + let mut empty_module = empty_module(); + + // Update the module ID + empty_module.identifiers[0] = module_id.name().to_owned(); + empty_module.address_identifiers[0] = *module_id.address(); + + // Create necessary empty collections + let module_arc = Arc::new(empty_module); + + Self { + id: module_id.clone(), + interned_id: module_id_pool.intern(module_id), + size: 0, + module: module_arc, + structs: vec![], + struct_instantiations: vec![], + struct_variant_infos: vec![], + struct_variant_instantiation_infos: vec![], + function_refs: vec![], + function_defs: vec![], + function_instantiations: vec![], + field_handles: vec![], + field_instantiations: vec![], + variant_field_infos: vec![], + variant_field_instantiation_infos: vec![], + function_map: HashMap::new(), + struct_map: HashMap::new(), + single_signature_token_map: BTreeMap::new(), + friends: BTreeSet::new(), + } + } + fn make_struct_type( module: &CompiledModule, struct_def: &StructDefinition, @@ -428,7 +493,7 @@ impl Module { field: &FieldDefinition, struct_name_table: &[StructNameIndex], ) -> PartialVMResult<(Identifier, Type)> { - let ty = intern_type( + let ty = convert_tok_to_type( BinaryIndexedView::Module(module), &field.signature.0, struct_name_table, @@ -440,18 +505,22 @@ impl Module { &self.id } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn struct_at(&self, idx: StructDefinitionIndex) -> &Arc { &self.structs[idx.0 as usize].definition_struct_type } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn struct_instantiation_at(&self, idx: u16) -> &StructInstantiation { &self.struct_instantiations[idx as usize] } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn struct_variant_at(&self, idx: StructVariantHandleIndex) -> &StructVariantInfo { &self.struct_variant_infos[idx.0 as usize] } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn struct_variant_instantiation_at( &self, idx: StructVariantInstantiationIndex, @@ -459,38 +528,48 @@ impl Module { &self.struct_variant_instantiation_infos[idx.0 as usize] } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn function_at(&self, idx: u16) -> &FunctionHandle { &self.function_refs[idx as usize] } - pub(crate) fn function_instantiation_at(&self, idx: u16) -> &[Type] { - &self.function_instantiations[idx as usize].instantiation + #[cfg_attr(feature = "force-inline", inline(always))] + pub(crate) fn function_instantiation_at(&self, idx: u16) -> (&[Type], Option) { + let instantiation = &self.function_instantiations[idx as usize]; + (&instantiation.instantiation, instantiation.ty_args_id) } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn function_instantiation_handle_at(&self, idx: u16) -> &FunctionHandle { &self.function_instantiations[idx as usize].handle } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_count(&self, idx: u16) -> u16 { self.structs[idx as usize].field_count } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_instantiation_count(&self, idx: u16) -> u16 { self.struct_instantiations[idx as usize].field_count } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_offset(&self, idx: FieldHandleIndex) -> usize { self.field_handles[idx.0 as usize].offset } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn field_instantiation_offset(&self, idx: FieldInstantiationIndex) -> usize { self.field_instantiations[idx.0 as usize].offset } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn variant_field_info_at(&self, idx: VariantFieldHandleIndex) -> &VariantFieldInfo { &self.variant_field_infos[idx.0 as usize] } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn variant_field_instantiation_info_at( &self, idx: VariantFieldInstantiationIndex, @@ -498,6 +577,7 @@ impl Module { &self.variant_field_instantiation_infos[idx.0 as usize] } + #[cfg_attr(feature = "force-inline", inline(always))] pub(crate) fn single_type_at(&self, idx: SignatureIndex) -> &Type { self.single_signature_token_map.get(&idx).unwrap() } diff --git a/third_party/move/move-vm/runtime/src/loader/script.rs b/third_party/move/move-vm/runtime/src/loader/script.rs index 30cb8560b85..b8bc2e16213 100644 --- a/third_party/move/move-vm/runtime/src/loader/script.rs +++ b/third_party/move/move-vm/runtime/src/loader/script.rs @@ -2,20 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 use super::{ - intern_type, single_signature_loader::load_single_signatures_for_script, Function, + convert_tok_to_type, single_signature_loader::load_single_signatures_for_script, Function, FunctionHandle, FunctionInstantiation, }; +use crate::loader::type_loader::convert_toks_to_types; use move_binary_format::{ access::ScriptAccess, binary_views::BinaryIndexedView, errors::PartialVMResult, - file_format::{CompiledScript, FunctionDefinitionIndex, Signature, SignatureIndex, Visibility}, + file_format::{CompiledScript, FunctionDefinitionIndex, SignatureIndex, Visibility}, }; -use move_core_types::{ident_str, language_storage::ModuleId}; -use move_vm_types::loaded_data::{ - runtime_access_specifier::AccessSpecifier, - runtime_types::{StructIdentifier, Type}, - struct_name_indexing::StructNameIndexMap, +use move_core_types::{ + ident_str, + language_storage::{pseudo_script_module_id, ModuleId}, +}; +use move_vm_types::{ + loaded_data::{ + runtime_access_specifier::AccessSpecifier, + runtime_types::{StructIdentifier, Type}, + struct_name_indexing::StructNameIndexMap, + }, + module_id_interner::{InternedModuleId, InternedModuleIdPool}, + ty_interner::{InternedTypePool, TypeVecId}, }; use std::{collections::BTreeMap, ops::Deref, sync::Arc}; @@ -25,6 +33,8 @@ use std::{collections::BTreeMap, ops::Deref, sync::Arc}; // (rather than "compiled") to make available data needed for execution. #[derive(Clone, Debug)] pub struct Script { + pub(crate) interned_id: InternedModuleId, + // primitive pools pub(crate) script: Arc, @@ -44,16 +54,18 @@ impl Script { pub(crate) fn new( script: Arc, struct_name_index_map: &StructNameIndexMap, + ty_pool: &InternedTypePool, + module_id_pool: &InternedModuleIdPool, ) -> PartialVMResult { + let interned_id = module_id_pool.intern_by_ref(pseudo_script_module_id()); + let mut struct_names = vec![]; for struct_handle in script.struct_handles() { let struct_name = script.identifier_at(struct_handle.name); let module_handle = script.module_handle_at(struct_handle.module); let module_id = script.module_id_for_handle(module_handle); - let struct_name = StructIdentifier { - module: module_id, - name: struct_name.to_owned(), - }; + let struct_name = + StructIdentifier::new(module_id_pool, module_id, struct_name.to_owned()); struct_names.push(struct_name_index_map.struct_name_to_idx(&struct_name)?); } @@ -74,40 +86,36 @@ impl Script { let mut function_instantiations = vec![]; for func_inst in script.function_instantiations() { let handle = function_refs[func_inst.handle.0 as usize].clone(); - let mut instantiation = vec![]; - for ty in &script.signature_at(func_inst.type_parameters).0 { - instantiation.push(intern_type( - BinaryIndexedView::Script(&script), - ty, - &struct_names, - )?); - } + let (instantiation, is_fully_instantiated) = convert_toks_to_types( + BinaryIndexedView::Script(&script), + &script.signature_at(func_inst.type_parameters).0, + &struct_names, + )?; + let ty_args_id = if is_fully_instantiated { + Some(ty_pool.intern_ty_args(&instantiation)) + } else { + None + }; function_instantiations.push(FunctionInstantiation { handle, instantiation, + ty_args_id, }); } - let code = script.code.code.clone(); + let code = script.code.code.iter().map(|b| b.clone().into()).collect(); let parameters = script.signature_at(script.parameters).clone(); let param_tys = parameters .0 .iter() - .map(|tok| intern_type(BinaryIndexedView::Script(&script), tok, &struct_names)) + .map(|tok| convert_tok_to_type(BinaryIndexedView::Script(&script), tok, &struct_names)) .collect::>>()?; - let locals = Signature( - parameters - .0 - .iter() - .chain(script.signature_at(script.code.locals).0.iter()) - .cloned() - .collect(), - ); - let local_tys = locals + let local_tys = parameters .0 .iter() - .map(|tok| intern_type(BinaryIndexedView::Script(&script), tok, &struct_names)) + .chain(script.signature_at(script.code.locals).0.iter()) + .map(|tok| convert_tok_to_type(BinaryIndexedView::Script(&script), tok, &struct_names)) .collect::>>()?; let ty_param_abilities = script.type_parameters.clone(); @@ -118,6 +126,7 @@ impl Script { ty_param_abilities, native: None, is_native: false, + is_dispatchable_native: false, visibility: Visibility::Private, is_entry: false, // TODO: main does not have a name. Revisit. @@ -129,11 +138,13 @@ impl Script { access_specifier: AccessSpecifier::Any, is_persistent: false, has_module_reentrancy_lock: false, + is_trusted: false, }); let single_signature_token_map = load_single_signatures_for_script(&script, &struct_names)?; Ok(Self { + interned_id, script, function_refs, function_instantiations, @@ -154,8 +165,9 @@ impl Script { &self.function_instantiations[idx as usize].handle } - pub(crate) fn function_instantiation_at(&self, idx: u16) -> &[Type] { - &self.function_instantiations[idx as usize].instantiation + pub(crate) fn function_instantiation_at(&self, idx: u16) -> (&[Type], Option) { + let instantiation = &self.function_instantiations[idx as usize]; + (&instantiation.instantiation, instantiation.ty_args_id) } pub(crate) fn single_type_at(&self, idx: SignatureIndex) -> &Type { diff --git a/third_party/move/move-vm/runtime/src/loader/single_signature_loader.rs b/third_party/move/move-vm/runtime/src/loader/single_signature_loader.rs index 2cc511d5adc..22b5aceb09a 100644 --- a/third_party/move/move-vm/runtime/src/loader/single_signature_loader.rs +++ b/third_party/move/move-vm/runtime/src/loader/single_signature_loader.rs @@ -1,7 +1,7 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use super::type_loader::intern_type; +use super::type_loader::convert_tok_to_type; use move_binary_format::{ access::ModuleAccess, binary_views::BinaryIndexedView, @@ -99,7 +99,7 @@ impl<'a> SingleSignatureMap<'a> { ); } - let ty = intern_type(self.view, &sig_toks[0], self.struct_idxs)?; + let ty = convert_tok_to_type(self.view, &sig_toks[0], self.struct_idxs)?; self.index_to_type.insert(idx, ty); Ok(()) } diff --git a/third_party/move/move-vm/runtime/src/loader/type_loader.rs b/third_party/move/move-vm/runtime/src/loader/type_loader.rs index 0feedeaf454..17751e2c33e 100644 --- a/third_party/move/move-vm/runtime/src/loader/type_loader.rs +++ b/third_party/move/move-vm/runtime/src/loader/type_loader.rs @@ -11,55 +11,108 @@ use move_vm_types::loaded_data::{ use triomphe::Arc as TriompheArc; /// Converts a signature token into the in memory type representation used by the MoveVM. -pub fn intern_type( +pub fn convert_tok_to_type( module: BinaryIndexedView, tok: &SignatureToken, struct_name_table: &[StructNameIndex], ) -> PartialVMResult { - let list = |toks: &[SignatureToken]| { - toks.iter() - .map(|tok| intern_type(module, tok, struct_name_table)) - .collect::>>() - }; + Ok(convert_tok_to_type_impl(module, tok, struct_name_table)?.0) +} + +/// Converts a stream of signature tokens into the in memory type representation used by the +/// MoveVM. Also returns true if all tokens are non-generic (contain 0 type parameters). +pub fn convert_toks_to_types( + module: BinaryIndexedView, + toks: &[SignatureToken], + struct_name_table: &[StructNameIndex], +) -> PartialVMResult<(Vec, bool)> { + convert_toks_to_types_impl(module, toks, struct_name_table) +} + +fn convert_toks_to_types_impl( + module: BinaryIndexedView, + toks: &[SignatureToken], + struct_name_table: &[StructNameIndex], +) -> PartialVMResult<(Vec, bool)> { + let mut tys = Vec::with_capacity(toks.len()); + let mut all_fully_instantiated = true; + for tok in toks { + let (ty, is_fully_instantiated) = convert_tok_to_type_impl(module, tok, struct_name_table)?; + tys.push(ty); + all_fully_instantiated &= is_fully_instantiated; + } + Ok((tys, all_fully_instantiated)) +} + +/// Returns the type, and true if this type is fully instantiated, and false otherwise. +fn convert_tok_to_type_impl( + module: BinaryIndexedView, + tok: &SignatureToken, + struct_name_table: &[StructNameIndex], +) -> PartialVMResult<(Type, bool)> { let res = match tok { - SignatureToken::Bool => Type::Bool, - SignatureToken::U8 => Type::U8, - SignatureToken::U16 => Type::U16, - SignatureToken::U32 => Type::U32, - SignatureToken::U64 => Type::U64, - SignatureToken::U128 => Type::U128, - SignatureToken::U256 => Type::U256, - SignatureToken::Address => Type::Address, - SignatureToken::Signer => Type::Signer, - SignatureToken::TypeParameter(idx) => Type::TyParam(*idx), + SignatureToken::Bool => (Type::Bool, true), + SignatureToken::U8 => (Type::U8, true), + SignatureToken::U16 => (Type::U16, true), + SignatureToken::U32 => (Type::U32, true), + SignatureToken::U64 => (Type::U64, true), + SignatureToken::U128 => (Type::U128, true), + SignatureToken::U256 => (Type::U256, true), + SignatureToken::I8 => (Type::I8, true), + SignatureToken::I16 => (Type::I16, true), + SignatureToken::I32 => (Type::I32, true), + SignatureToken::I64 => (Type::I64, true), + SignatureToken::I128 => (Type::I128, true), + SignatureToken::I256 => (Type::I256, true), + SignatureToken::Address => (Type::Address, true), + SignatureToken::Signer => (Type::Signer, true), + SignatureToken::TypeParameter(idx) => (Type::TyParam(*idx), false), SignatureToken::Vector(inner_tok) => { - let inner_type = intern_type(module, inner_tok, struct_name_table)?; - Type::Vector(TriompheArc::new(inner_type)) + let (inner_type, is_fully_instantiated) = + convert_tok_to_type_impl(module, inner_tok, struct_name_table)?; + ( + Type::Vector(TriompheArc::new(inner_type)), + is_fully_instantiated, + ) }, - SignatureToken::Function(args, results, abilities) => Type::Function { - args: list(args)?, - results: list(results)?, - abilities: *abilities, + SignatureToken::Function(args, results, abilities) => { + let (args, args_fully_instantiated) = + convert_toks_to_types_impl(module, args, struct_name_table)?; + let (results, results_fully_instantiated) = + convert_toks_to_types_impl(module, results, struct_name_table)?; + let ty = Type::Function { + args, + results, + abilities: *abilities, + }; + (ty, args_fully_instantiated && results_fully_instantiated) }, SignatureToken::Reference(inner_tok) => { - let inner_type = intern_type(module, inner_tok, struct_name_table)?; - Type::Reference(Box::new(inner_type)) + let (inner_type, is_fully_instantiated) = + convert_tok_to_type_impl(module, inner_tok, struct_name_table)?; + (Type::Reference(Box::new(inner_type)), is_fully_instantiated) }, SignatureToken::MutableReference(inner_tok) => { - let inner_type = intern_type(module, inner_tok, struct_name_table)?; - Type::MutableReference(Box::new(inner_type)) + let (inner_type, is_fully_instantiated) = + convert_tok_to_type_impl(module, inner_tok, struct_name_table)?; + ( + Type::MutableReference(Box::new(inner_type)), + is_fully_instantiated, + ) }, SignatureToken::Struct(sh_idx) => { let struct_handle = module.struct_handle_at(*sh_idx); - Type::Struct { + let ty = Type::Struct { idx: struct_name_table[sh_idx.0 as usize], ability: AbilityInfo::struct_(struct_handle.abilities), - } + }; + (ty, true) }, SignatureToken::StructInstantiation(sh_idx, tys) => { - let type_args: Vec<_> = list(tys)?; + let (type_args, type_args_fully_instantiated) = + convert_toks_to_types_impl(module, tys, struct_name_table)?; let struct_handle = module.struct_handle_at(*sh_idx); - Type::StructInstantiation { + let ty = Type::StructInstantiation { idx: struct_name_table[sh_idx.0 as usize], ty_args: TriompheArc::new(type_args), ability: AbilityInfo::generic_struct( @@ -70,7 +123,8 @@ pub fn intern_type( .map(|ty| ty.is_phantom) .collect(), ), - } + }; + (ty, type_args_fully_instantiated) }, }; Ok(res) diff --git a/third_party/move/move-vm/runtime/src/module_traversal.rs b/third_party/move/move-vm/runtime/src/module_traversal.rs index e16758dd9eb..dc2c78d35ed 100644 --- a/third_party/move/move-vm/runtime/src/module_traversal.rs +++ b/third_party/move/move-vm/runtime/src/module_traversal.rs @@ -64,6 +64,26 @@ impl<'a> TraversalContext<'a> { !addr.is_special() && self.visited.insert((addr, name), ()).is_none() } + /// If the address of the specified module id is not special, adds the address-name pair to the + /// visited set and returns true. If the address is special, or if the set already contains the + /// pair, returns false. + pub fn visit_if_not_special_module_id(&mut self, module_id: &ModuleId) -> bool { + let addr = module_id.address(); + if addr.is_special() { + return false; + } + + let name = module_id.name(); + if self.visited.contains_key(&(addr, name)) { + false + } else { + let module_id = self.referenced_module_ids.alloc(module_id.clone()); + self.visited + .insert((module_id.address(), module_id.name()), ()); + true + } + } + /// No-op if address is visited, otherwise returns an invariant violation error. fn check_visited_impl(&self, addr: &AccountAddress, name: &IdentStr) -> PartialVMResult<()> { if self.visited.contains_key(&(addr, name)) { @@ -128,8 +148,9 @@ mod test { let mut traversal_context = TraversalContext::new(&traversal_storage); let special = AccountAddress::ONE; - let non_special = AccountAddress::from_hex_literal("0x123").unwrap(); - assert!(special.is_special() && !non_special.is_special()); + let non_special_1 = AccountAddress::from_hex_literal("0x123").unwrap(); + let non_special_2 = AccountAddress::from_hex_literal("0x234").unwrap(); + assert!(special.is_special() && !non_special_1.is_special() && !non_special_2.is_special()); let allocated_module_id = |addr| { let module_id = ModuleId::new(addr, ident_str!("foo").to_owned()); @@ -145,25 +166,35 @@ mod test { .expect_err("0x1 is special address and should not be visited"); assert!(!traversal_context.visit_if_not_special_address(special.address(), special.name())); + assert!(!traversal_context.visit_if_not_special_module_id(special)); assert!(traversal_context.visited.is_empty()); traversal_context .legacy_check_visited(special.address(), special.name()) .expect_err("0x1 is special address but we don't allow them to be non-visited"); - let non_special = allocated_module_id(non_special); + let non_special_1 = allocated_module_id(non_special_1); + let non_special_2 = ModuleId::new(non_special_2, ident_str!("foo").to_owned()); traversal_context - .check_is_special_or_visited(non_special.address(), non_special.name()) + .check_is_special_or_visited(non_special_1.address(), non_special_1.name()) .expect_err("0x123 is non-special address and have not been visited"); + traversal_context + .check_is_special_or_visited(non_special_2.address(), non_special_2.name()) + .expect_err("0x234 is non-special address and have not been visited"); assert!(traversal_context - .visit_if_not_special_address(non_special.address(), non_special.name())); - assert_eq!(traversal_context.visited.len(), 1); + .visit_if_not_special_address(non_special_1.address(), non_special_1.name())); + assert!(traversal_context.visit_if_not_special_module_id(&non_special_2)); + assert_eq!(traversal_context.visited.len(), 2); traversal_context - .check_is_special_or_visited(non_special.address(), non_special.name()) + .check_is_special_or_visited(non_special_1.address(), non_special_1.name()) .expect("0x123 is non-special address but have been visited"); + traversal_context + .check_is_special_or_visited(non_special_2.address(), non_special_2.name()) + .expect("0x234 is non-special address but have been visited"); // Double insertion: should not be visiting anymore. assert!(!traversal_context - .visit_if_not_special_address(non_special.address(), non_special.name())); + .visit_if_not_special_address(non_special_1.address(), non_special_1.name())); + assert!(!traversal_context.visit_if_not_special_module_id(&non_special_2)); } } diff --git a/third_party/move/move-vm/runtime/src/move_vm.rs b/third_party/move/move-vm/runtime/src/move_vm.rs index a261a3676cc..e8d54eed209 100644 --- a/third_party/move/move-vm/runtime/src/move_vm.rs +++ b/third_party/move/move-vm/runtime/src/move_vm.rs @@ -3,12 +3,17 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - data_cache::TransactionDataCache, + data_cache::MoveVmDataCache, + execution_tracing::{NoOpTraceRecorder, TraceRecorder}, interpreter::Interpreter, + interpreter_caches::InterpreterFunctionCaches, module_traversal::TraversalContext, native_extensions::NativeContextExtensions, - storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, - AsFunctionValueExtension, LoadedFunction, ModuleStorage, + storage::{ + loader::traits::Loader, module_storage::FunctionValueExtensionAdapter, + ty_depth_checker::TypeDepthChecker, ty_layout_converter::LayoutConverter, + }, + LoadedFunction, }; use move_binary_format::{ errors::{Location, PartialVMError, PartialVMResult, VMResult}, @@ -19,7 +24,6 @@ use move_vm_metrics::{Timer, VM_TIMER}; use move_vm_types::{ gas::GasMeter, loaded_data::runtime_types::Type, - resolver::ResourceResolver, value_serde::{FunctionValueExtension, ValueSerDeContext}, values::{Locals, Reference, VMValueCast, Value}, }; @@ -40,6 +44,27 @@ pub struct SerializedReturnValues { pub struct MoveVM; impl MoveVM { + pub fn execute_loaded_function( + function: LoadedFunction, + serialized_args: Vec>, + data_cache: &mut impl MoveVmDataCache, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, + extensions: &mut NativeContextExtensions, + loader: &impl Loader, + ) -> VMResult { + Self::execute_loaded_function_with_tracing( + function, + serialized_args, + data_cache, + gas_meter, + traversal_context, + extensions, + loader, + &mut NoOpTraceRecorder, + ) + } + /// Executes provided function with the specified arguments. The arguments are serialized, and /// are not checked by the VM. It is the responsibility of the caller of this function to /// verify that they are well-formed. @@ -51,20 +76,26 @@ impl MoveVM { /// /// When execution finishes, the return values of the function are returned. Additionally, if /// there are any mutable references passed as arguments, these values are also returned. - pub fn execute_loaded_function( + pub fn execute_loaded_function_with_tracing( function: LoadedFunction, serialized_args: Vec>, - data_cache: &mut TransactionDataCache, + data_cache: &mut impl MoveVmDataCache, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, extensions: &mut NativeContextExtensions, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, + loader: &impl Loader, + trace_recorder: &mut impl TraceRecorder, ) -> VMResult { - let vm_config = module_storage.runtime_environment().vm_config(); - let ty_builder = &vm_config.ty_builder; + let vm_config = loader.runtime_environment().vm_config(); + + let function_value_extension = FunctionValueExtensionAdapter { + module_storage: loader.unmetered_module_storage(), + }; + let layout_converter = LayoutConverter::new(loader); + let ty_depth_checker = TypeDepthChecker::new(loader); let create_ty_with_subst = |tys: &[Type]| -> VMResult> { + let ty_builder = &vm_config.ty_builder; tys.iter() .map(|ty| ty_builder.create_ty_with_subst(ty, function.ty_args())) .collect::>>() @@ -72,28 +103,46 @@ impl MoveVM { }; let param_tys = create_ty_with_subst(function.param_tys())?; - let (mut dummy_locals, deserialized_args) = - deserialize_args(module_storage, ¶m_tys, serialized_args) - .map_err(|e| e.finish(Location::Undefined))?; + let (mut dummy_locals, deserialized_args) = deserialize_args( + &function_value_extension, + &layout_converter, + gas_meter, + traversal_context, + ¶m_tys, + serialized_args, + ) + .map_err(|err| err.finish(Location::Undefined))?; let return_tys = create_ty_with_subst(function.return_tys())?; let return_values = { let _timer = VM_TIMER.timer_with_label("Interpreter::entrypoint"); + Interpreter::entrypoint( function, deserialized_args, data_cache, - module_storage, - resource_resolver, + // TODO(caches): async drop + &mut InterpreterFunctionCaches::new(), + loader, + &ty_depth_checker, + &layout_converter, gas_meter, traversal_context, extensions, + trace_recorder, )? }; - let return_values = serialize_return_values(module_storage, &return_tys, return_values) - .map_err(|e| e.finish(Location::Undefined))?; + let return_values = serialize_return_values( + &function_value_extension, + &layout_converter, + gas_meter, + traversal_context, + &return_tys, + return_values, + ) + .map_err(|e| e.finish(Location::Undefined))?; let mutable_reference_outputs = param_tys .iter() .enumerate() @@ -103,9 +152,15 @@ impl MoveVM { }) .map(|(idx, ty)| { // serialize return values first in the case that a value points into this local - let local_val = - dummy_locals.move_loc(idx, vm_config.check_invariant_in_swap_loc)?; - let (bytes, layout) = serialize_return_value(module_storage, ty, local_val)?; + let local_val = dummy_locals.move_loc(idx)?; + let (bytes, layout) = serialize_return_value( + &function_value_extension, + &layout_converter, + gas_meter, + traversal_context, + ty, + local_val, + )?; Ok((idx as LocalIndex, bytes, layout)) }) .collect::>() @@ -122,39 +177,49 @@ impl MoveVM { } fn deserialize_arg( - module_storage: &impl ModuleStorage, + function_value_extension: &impl FunctionValueExtension, + layout_converter: &LayoutConverter, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, ty: &Type, arg: impl Borrow<[u8]>, ) -> PartialVMResult { - let (layout, has_identifier_mappings) = StorageLayoutConverter::new(module_storage) - .type_to_type_layout_with_identifier_mappings(ty) - .map_err(|_| { - PartialVMError::new(StatusCode::INVALID_PARAM_TYPE_FOR_DESERIALIZATION) - .with_message("[VM] failed to get layout from type".to_string()) - })?; - let deserialization_error = || -> PartialVMError { PartialVMError::new(StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT) .with_message("[VM] failed to deserialize argument".to_string()) }; - // Make sure we do not construct values which might have identifiers - // inside. This should be guaranteed by transaction argument validation - // but because it does not use layouts we double-check here. - if has_identifier_mappings { - return Err(deserialization_error()); - } + // Make sure we do not construct values which might have delayed fields inside. This should be + // guaranteed by transaction argument validation but because it does not use layouts we better + // double-check here. + let layout = layout_converter + .type_to_type_layout_with_delayed_fields(gas_meter, traversal_context, ty, false) + .map_err(|err| { + if layout_converter.is_lazy_loading_enabled() { + err + } else { + // Note: for backwards compatibility, the error code is remapped to this error. We + // no longer should do it because layout construction may return useful errors such + // as layout being too large, running out of gas, etc. + PartialVMError::new(StatusCode::INVALID_PARAM_TYPE_FOR_DESERIALIZATION) + .with_message("[VM] failed to get layout from type".to_string()) + } + })? + .into_layout_when_has_no_delayed_fields() + .ok_or_else(deserialization_error)?; - let function_value_extension = module_storage.as_function_value_extension(); let max_value_nest_depth = function_value_extension.max_value_nest_depth(); ValueSerDeContext::new(max_value_nest_depth) - .with_func_args_deserialization(&function_value_extension) + .with_func_args_deserialization(function_value_extension) .deserialize(arg.borrow(), &layout) .ok_or_else(deserialization_error) } fn deserialize_args( - module_storage: &impl ModuleStorage, + function_value_extension: &impl FunctionValueExtension, + layout_converter: &LayoutConverter, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, param_tys: &[Type], serialized_args: Vec>, ) -> PartialVMResult<(Locals, Vec)> { @@ -173,7 +238,6 @@ fn deserialize_args( let mut dummy_locals = Locals::new(param_tys.len()); // Arguments for the invoked function. These can be owned values or references - let vm_config = module_storage.runtime_environment().vm_config(); let deserialized_args = param_tys .iter() .zip(serialized_args) @@ -182,19 +246,35 @@ fn deserialize_args( Some(inner_ty) => { dummy_locals.store_loc( idx, - deserialize_arg(module_storage, inner_ty, arg_bytes)?, - vm_config.check_invariant_in_swap_loc, + deserialize_arg( + function_value_extension, + layout_converter, + gas_meter, + traversal_context, + inner_ty, + arg_bytes, + )?, )?; dummy_locals.borrow_loc(idx) }, - None => deserialize_arg(module_storage, ty, arg_bytes), + None => deserialize_arg( + function_value_extension, + layout_converter, + gas_meter, + traversal_context, + ty, + arg_bytes, + ), }) .collect::>>()?; Ok((dummy_locals, deserialized_args)) } fn serialize_return_value( - module_storage: &impl ModuleStorage, + function_value_extension: &impl FunctionValueExtension, + layout_converter: &LayoutConverter, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, ty: &Type, value: Value, ) -> PartialVMResult<(Vec, MoveTypeLayout)> { @@ -207,36 +287,43 @@ fn serialize_return_value( None => (ty, value), }; - let (layout, has_identifier_mappings) = StorageLayoutConverter::new(module_storage) - .type_to_type_layout_with_identifier_mappings(ty) - .map_err(|_err| { - // TODO: Should we use `err` instead of mapping? - PartialVMError::new(StatusCode::VERIFICATION_ERROR).with_message( - "entry point functions cannot have non-serializable return types".to_string(), - ) - })?; - let serialization_error = || -> PartialVMError { PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) .with_message("failed to serialize return values".to_string()) }; - // Disallow native values to escape through return values of a function. - if has_identifier_mappings { - return Err(serialization_error()); - } + // Disallow delayed fields to escape through return values of a function. + let layout = layout_converter + .type_to_type_layout_with_delayed_fields(gas_meter, traversal_context, ty, false) + .map_err(|err| { + if layout_converter.is_lazy_loading_enabled() { + err + } else { + // Note: for backwards compatibility, the error code is remapped to verification + // error. We should no longer do it because layout construction may return useful + // errors, like running out of gas, exceeding certain limits, etc. + PartialVMError::new(StatusCode::VERIFICATION_ERROR).with_message( + "entry point functions cannot have non-serializable return types".to_string(), + ) + } + })? + .into_layout_when_has_no_delayed_fields() + .ok_or_else(serialization_error)?; - let function_value_extension = module_storage.as_function_value_extension(); let max_value_nest_depth = function_value_extension.max_value_nest_depth(); let bytes = ValueSerDeContext::new(max_value_nest_depth) - .with_func_args_deserialization(&function_value_extension) + .with_func_args_deserialization(function_value_extension) .serialize(&value, &layout)? .ok_or_else(serialization_error)?; - Ok((bytes, layout)) + // TODO(layouts): consider not cloning returned layouts? + Ok((bytes, layout.as_ref().clone())) } fn serialize_return_values( - module_storage: &impl ModuleStorage, + function_value_extension: &impl FunctionValueExtension, + layout_converter: &LayoutConverter, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, return_tys: &[Type], return_values: Vec, ) -> PartialVMResult, MoveTypeLayout)>> { @@ -255,6 +342,15 @@ fn serialize_return_values( return_tys .iter() .zip(return_values) - .map(|(ty, value)| serialize_return_value(module_storage, ty, value)) + .map(|(ty, value)| { + serialize_return_value( + function_value_extension, + layout_converter, + gas_meter, + traversal_context, + ty, + value, + ) + }) .collect() } diff --git a/third_party/move/move-vm/runtime/src/native_extensions.rs b/third_party/move/move-vm/runtime/src/native_extensions.rs index e75c50c8d50..eb2f1d7301d 100644 --- a/third_party/move/move-vm/runtime/src/native_extensions.rs +++ b/third_party/move/move-vm/runtime/src/native_extensions.rs @@ -5,6 +5,54 @@ use better_any::{Tid, TidAble, TidExt}; use std::{any::TypeId, collections::HashMap}; +/// Controls how VM session interacts with native extensions. For every session, we consider three +/// kinds of operations: +/// 1. `start`: marks the start to some session in state S1. +/// 2. `finish`: marks the end of the current session state. The changes made by S are saved, and +/// the session is ready to transition to new state S2 (via calling `start`). +/// 3. `abort`: called when the session aborts and needs to roll back to old state (e.g., if +/// currently at state S2, will move back to state S1), discarding all changes made by S2. +pub trait SessionListener { + /// Must be called on every session start to transition to a new state. + fn start(&mut self, session_hash: &[u8; 32], script_hash: &[u8], session_counter: u8); + + /// Called on session finish, to save the data modified by the current extension. Called before + /// a transition to the new session via `start`. + fn finish(&mut self); + + /// Called when session is aborted, to roll back the state to the previous session's state, + /// just before a new session needs to start. If there is no session before, a no-op. + fn abort(&mut self); +} + +/// Any native extension should implement its interaction with the [SessionListener]. This way when +/// a new extension gets added there is a compile-time error when one tries to add it to the native +/// context. +pub trait NativeSessionListener<'a>: SessionListener + Tid<'a> {} + +impl<'a, T> NativeSessionListener<'a> for T where T: SessionListener + Tid<'a> {} + +/// Marker for extensions that do not use session model and so there is no need to implement any +/// session operations. +pub trait UnreachableSessionListener {} + +impl SessionListener for T +where + T: UnreachableSessionListener, +{ + fn start(&mut self, _session_hash: &[u8; 32], _script_hash: &[u8], _session_counter: u8) { + unreachable!("Irrelevant for extension") + } + + fn finish(&mut self) { + unreachable!("Irrelevant for extension") + } + + fn abort(&mut self) { + unreachable!("Irrelevant for extension") + } +} + /// A data type to represent a heterogeneous collection of extensions which are available to /// native functions. A value to this is passed into the session function execution. /// @@ -15,18 +63,18 @@ use std::{any::TypeId, collections::HashMap}; /// tests at the end of this module.) #[derive(Default)] pub struct NativeContextExtensions<'a> { - map: HashMap>>, + map: HashMap>>, } impl<'a> NativeContextExtensions<'a> { - pub fn add>(&mut self, ext: T) { + pub fn add>(&mut self, ext: T) { assert!( self.map.insert(T::id(), Box::new(ext)).is_none(), "multiple extensions of the same type not allowed" ) } - pub fn get>(&self) -> &T { + pub fn get>(&self) -> &T { self.map .get(&T::id()) .expect("extension unknown") @@ -35,7 +83,7 @@ impl<'a> NativeContextExtensions<'a> { .unwrap() } - pub fn get_mut>(&mut self) -> &mut T { + pub fn get_mut>(&mut self) -> &mut T { self.map .get_mut(&T::id()) .expect("extension unknown") @@ -44,7 +92,7 @@ impl<'a> NativeContextExtensions<'a> { .unwrap() } - pub fn remove>(&mut self) -> T { + pub fn remove>(&mut self) -> T { // can't use expect below because it requires `T: Debug`. match self .map @@ -56,12 +104,22 @@ impl<'a> NativeContextExtensions<'a> { Err(_) => panic!("downcast error"), } } + + pub fn for_each_mut(&mut self, f: F) + where + F: Fn(&mut dyn SessionListener), + { + for extension in self.map.values_mut() { + f(extension.as_mut()); + } + } } #[cfg(test)] mod tests { - use crate::native_extensions::NativeContextExtensions; - use better_any::{Tid, TidAble}; + use super::*; + + impl<'a> UnreachableSessionListener for Ext<'a> {} #[derive(Tid)] struct Ext<'a> { diff --git a/third_party/move/move-vm/runtime/src/native_functions.rs b/third_party/move/move-vm/runtime/src/native_functions.rs index ed7f60aa00c..acbf566cf23 100644 --- a/third_party/move/move-vm/runtime/src/native_functions.rs +++ b/third_party/move/move-vm/runtime/src/native_functions.rs @@ -3,36 +3,49 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - check_dependencies_and_charge_gas, - data_cache::TransactionDataCache, + ambassador_impl_ModuleStorage, ambassador_impl_WithRuntimeEnvironment, + data_cache::NativeContextMoveVmDataCache, + dispatch_loader, interpreter::InterpreterDebugInterface, + loader::{LazyLoadedFunction, LazyLoadedFunctionState}, module_traversal::TraversalContext, native_extensions::NativeContextExtensions, storage::{ + layout_cache::StructKey, + loader::traits::NativeModuleLoader, module_storage::FunctionValueExtensionAdapter, - ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, + ty_layout_converter::{LayoutConverter, LayoutWithDelayedFields}, }, - ModuleStorage, + LayoutCache, LayoutCacheEntry, Module, ModuleStorage, RuntimeEnvironment, + WithRuntimeEnvironment, +}; +use ambassador::delegate_to_methods; +use bytes::Bytes; +use move_binary_format::{ + errors::{ExecutionState, PartialVMError, PartialVMResult, VMResult}, + CompiledModule, }; -use move_binary_format::errors::{ExecutionState, PartialVMError, PartialVMResult, VMResult}; use move_core_types::{ account_address::AccountAddress, gas_algebra::{InternalGas, NumBytes}, - identifier::Identifier, + identifier::{IdentStr, Identifier}, language_storage::{ModuleId, TypeTag}, value::MoveTypeLayout, vm_status::StatusCode, }; use move_vm_types::{ - gas::NativeGasMeter, loaded_data::runtime_types::Type, natives::function::NativeResult, - resolver::ResourceResolver, values::Value, + gas::{ambassador_impl_DependencyGasMeter, DependencyGasMeter, DependencyKind, NativeGasMeter}, + loaded_data::runtime_types::Type, + natives::function::NativeResult, + values::{AbstractFunction, Value}, }; use std::{ collections::{HashMap, VecDeque}, sync::Arc, }; +use triomphe::Arc as TriompheArc; -pub type UnboxedNativeFunction = dyn Fn(&mut NativeContext, Vec, VecDeque) -> PartialVMResult +pub type UnboxedNativeFunction = dyn for<'a> Fn(&mut NativeContext, &'a [Type], VecDeque) -> PartialVMResult + Send + Sync + 'static; @@ -101,8 +114,7 @@ impl NativeFunctions { pub struct NativeContext<'a, 'b, 'c> { interpreter: &'a dyn InterpreterDebugInterface, - data_store: &'a mut TransactionDataCache, - resource_resolver: &'a dyn ResourceResolver, + data_cache: &'a mut dyn NativeContextMoveVmDataCache, module_storage: &'a dyn ModuleStorage, extensions: &'a mut NativeContextExtensions<'b>, gas_meter: &'a mut dyn NativeGasMeter, @@ -112,8 +124,7 @@ pub struct NativeContext<'a, 'b, 'c> { impl<'a, 'b, 'c> NativeContext<'a, 'b, 'c> { pub(crate) fn new( interpreter: &'a dyn InterpreterDebugInterface, - data_store: &'a mut TransactionDataCache, - resource_resolver: &'a dyn ResourceResolver, + data_cache: &'a mut dyn NativeContextMoveVmDataCache, module_storage: &'a dyn ModuleStorage, extensions: &'a mut NativeContextExtensions<'b>, gas_meter: &'a mut dyn NativeGasMeter, @@ -121,8 +132,7 @@ impl<'a, 'b, 'c> NativeContext<'a, 'b, 'c> { ) -> Self { Self { interpreter, - data_store, - resource_resolver, + data_cache, module_storage, extensions, gas_meter, @@ -142,45 +152,67 @@ impl<'b, 'c> NativeContext<'_, 'b, 'c> { address: AccountAddress, ty: &Type, ) -> PartialVMResult<(bool, Option)> { - // TODO(#16516): - // Propagate exists call all the way to resolver, because we can implement the check more - // efficiently, without the need to actually load bytes, deserialize the value and cache - // it in the data cache. - Ok(if !self.data_store.contains_resource(&address, ty) { - let (entry, bytes_loaded) = TransactionDataCache::create_data_cache_entry( - self.module_storage, - self.resource_resolver, - &address, - ty, - )?; - let exists = entry.value().exists()?; - self.data_store - .insert_resource(address, ty.clone(), entry)?; - (exists, Some(bytes_loaded)) - } else { - let exists = self.data_store.get_resource_mut(&address, ty)?.exists()?; - (exists, None) - }) + self.data_cache.native_check_resource_exists( + self.gas_meter, + self.traversal_context, + &address, + ty, + ) } pub fn type_to_type_tag(&self, ty: &Type) -> PartialVMResult { self.module_storage.runtime_environment().ty_to_ty_tag(ty) } - pub fn type_to_type_layout(&self, ty: &Type) -> PartialVMResult { - StorageLayoutConverter::new(self.module_storage).type_to_type_layout(ty) + /// Returns the runtime layout of a type that can be used to (de)serialize the value. + /// + /// NOTE: use with caution as this ignores the flag if layout contains delayed fields or not. + pub fn type_to_type_layout( + &mut self, + ty: &Type, + ) -> PartialVMResult> { + let layout = self + .loader_context() + .type_to_type_layout_with_delayed_fields(ty)? + .unpack() + .0; + Ok(layout) } - pub fn type_to_type_layout_with_identifier_mappings( - &self, + /// Returns the runtime layout of a type that can be used to (de)serialize the value. Also, + /// information whether there are any delayed fields in layouts is returned. + pub fn type_to_type_layout_with_delayed_fields( + &mut self, ty: &Type, - ) -> PartialVMResult<(MoveTypeLayout, bool)> { - StorageLayoutConverter::new(self.module_storage) - .type_to_type_layout_with_identifier_mappings(ty) + ) -> PartialVMResult { + self.loader_context() + .type_to_type_layout_with_delayed_fields(ty) } - pub fn type_to_fully_annotated_layout(&self, ty: &Type) -> PartialVMResult { - StorageLayoutConverter::new(self.module_storage).type_to_fully_annotated_layout(ty) + /// Returns the runtime layout of a type that can be used to (de)serialize the value. The + /// layout does not contain delayed fields (otherwise, invariant violation is returned). + pub fn type_to_type_layout_check_no_delayed_fields( + &mut self, + ty: &Type, + ) -> PartialVMResult> { + let layout = self + .loader_context() + .type_to_type_layout_with_delayed_fields(ty)?; + layout + .into_layout_when_has_no_delayed_fields() + .ok_or_else(|| { + PartialVMError::new_invariant_violation("Layout should not contain delayed fields") + }) + } + + /// Returns the annotated layout of a type. If type contains delayed fields, returns [None]. + /// An error is returned when a layout cannot be constructed (e.g., some limits on number of + /// nodes are reached, or an internal invariant violation is raised). + pub fn type_to_fully_annotated_layout( + &mut self, + ty: &Type, + ) -> PartialVMResult>> { + self.loader_context().type_to_fully_annotated_layout(ty) } pub fn module_storage(&self) -> &dyn ModuleStorage { @@ -191,6 +223,18 @@ impl<'b, 'c> NativeContext<'_, 'b, 'c> { self.extensions } + /// Returns native extensions and loader context (storing mutable gas meter and traversal + /// context). Native functions can use this method to query extensions while holding mutable + /// reference to loader's context. + pub fn extensions_with_loader_context( + &mut self, + ) -> (&NativeContextExtensions<'b>, LoaderContext<'_, 'c>) { + ( + self.extensions, + LoaderContext::new(self.module_storage, self.gas_meter, self.traversal_context), + ) + } + pub fn extensions_mut(&mut self) -> &mut NativeContextExtensions<'b> { self.extensions } @@ -211,26 +255,167 @@ impl<'b, 'c> NativeContext<'_, 'b, 'c> { self.gas_meter } - pub fn charge_gas_for_dependencies(&mut self, module_id: ModuleId) -> VMResult<()> { - let arena_id = self - .traversal_context - .referenced_module_ids - .alloc(module_id); - check_dependencies_and_charge_gas( - self.module_storage, - self.gas_meter, - self.traversal_context, - [(arena_id.address(), arena_id.name())], - ) + /// Returns the loader context used by the natives. + pub fn loader_context(&mut self) -> LoaderContext<'_, 'c> { + LoaderContext::new(self.module_storage, self.gas_meter, self.traversal_context) } pub fn traversal_context(&self) -> &TraversalContext<'c> { self.traversal_context } - pub fn function_value_extension(&self) -> FunctionValueExtensionAdapter { + pub fn function_value_extension(&self) -> FunctionValueExtensionAdapter<'_> { FunctionValueExtensionAdapter { module_storage: self.module_storage, } } } + +/// Helper struct that can be returned together with extensions so that layouts can be constructed +/// while there is a live mutable reference to context extensions. +pub struct LoaderContext<'a, 'b> { + module_storage: ModuleStorageWrapper<'a>, + gas_meter: DependencyGasMeterWrapper<'a>, + traversal_context: &'a mut TraversalContext<'b>, +} + +impl<'a, 'b> LoaderContext<'a, 'b> { + /// Returns a vector of layouts for captured arguments. Used to format captured arguments as + /// strings. Returns [Ok(None)] in case layouts contain delayed fields (i.e., the values cannot + /// be formatted as strings). + pub fn get_captured_layouts_for_string_utils( + &mut self, + fun: &dyn AbstractFunction, + ) -> PartialVMResult>> { + Ok( + match &*LazyLoadedFunction::expect_this_impl(fun)?.state.borrow() { + LazyLoadedFunctionState::Unresolved { data, .. } => { + Some(data.captured_layouts.clone()) + }, + LazyLoadedFunctionState::Resolved { + fun, + mask, + captured_layouts, + .. + } => match captured_layouts.as_ref() { + Some(captured_layouts) => Some(captured_layouts.clone()), + None => dispatch_loader!(&self.module_storage, loader, { + LazyLoadedFunction::construct_captured_layouts( + &LayoutConverter::new(&loader), + &mut self.gas_meter, + self.traversal_context, + fun, + *mask, + ) + })?, + }, + }, + ) + } + + /// Charges gas for module dependencies for native dynamic dispatch. + pub fn charge_gas_for_dependencies(&mut self, module_id: ModuleId) -> PartialVMResult<()> { + dispatch_loader!(&self.module_storage, loader, { + loader.charge_native_result_load_module( + &mut self.gas_meter, + self.traversal_context, + &module_id, + ) + }) + } + + /// Returns function value extension that can be used for (de)serializing function values. + pub fn function_value_extension(&self) -> FunctionValueExtensionAdapter<'_> { + FunctionValueExtensionAdapter { + module_storage: self.module_storage.module_storage, + } + } + + /// Converts a runtime type into layout for (de)serialization. + pub fn type_to_type_layout_with_delayed_fields( + &mut self, + ty: &Type, + ) -> PartialVMResult { + dispatch_loader!(&self.module_storage, loader, { + LayoutConverter::new(&loader).type_to_type_layout_with_delayed_fields( + &mut self.gas_meter, + self.traversal_context, + ty, + false, + ) + }) + } +} + +// Private interfaces. +impl<'a, 'b> LoaderContext<'a, 'b> { + /// Creates a new loader context. + fn new( + module_storage: &'a dyn ModuleStorage, + gas_meter: &'a mut dyn DependencyGasMeter, + traversal_context: &'a mut TraversalContext<'b>, + ) -> Self { + Self { + module_storage: ModuleStorageWrapper { module_storage }, + gas_meter: DependencyGasMeterWrapper { gas_meter }, + traversal_context, + } + } + + /// Converts a runtime type into decorated layout for pretty-printing. + fn type_to_fully_annotated_layout( + &mut self, + ty: &Type, + ) -> PartialVMResult>> { + let layout = dispatch_loader!(&self.module_storage, loader, { + LayoutConverter::new(&loader).type_to_annotated_type_layout_with_delayed_fields( + &mut self.gas_meter, + self.traversal_context, + ty, + ) + })?; + Ok(layout.into_layout_when_has_no_delayed_fields()) + } +} + +// Wrappers to use trait objects where static dispatch is expected. +struct ModuleStorageWrapper<'a> { + module_storage: &'a dyn ModuleStorage, +} + +impl<'a> LayoutCache for ModuleStorageWrapper<'a> { + fn get_struct_layout(&self, key: &StructKey) -> Option { + self.module_storage.get_struct_layout(key) + } + + fn store_struct_layout(&self, key: &StructKey, entry: LayoutCacheEntry) -> PartialVMResult<()> { + self.module_storage.store_struct_layout(key, entry) + } +} + +#[delegate_to_methods] +#[delegate(WithRuntimeEnvironment, target_ref = "inner")] +#[delegate(ModuleStorage, target_ref = "inner")] +impl<'a> ModuleStorageWrapper<'a> { + fn inner(&self) -> &dyn ModuleStorage { + self.module_storage + } +} + +pub(crate) struct DependencyGasMeterWrapper<'a> { + gas_meter: &'a mut dyn DependencyGasMeter, +} + +impl<'a> DependencyGasMeterWrapper<'a> { + pub(crate) fn new(gas_meter: &'a mut dyn DependencyGasMeter) -> Self { + Self { gas_meter } + } +} + +#[delegate_to_methods] +#[delegate(DependencyGasMeter, target_mut = "inner_mut")] +impl<'a> DependencyGasMeterWrapper<'a> { + fn inner_mut(&mut self) -> &mut dyn DependencyGasMeter { + self.gas_meter + } +} diff --git a/third_party/move/move-vm/runtime/src/reentrancy_checker.rs b/third_party/move/move-vm/runtime/src/reentrancy_checker.rs index de9670f19b2..3957acb7281 100644 --- a/third_party/move/move-vm/runtime/src/reentrancy_checker.rs +++ b/third_party/move/move-vm/runtime/src/reentrancy_checker.rs @@ -21,17 +21,20 @@ use crate::LoadedFunction; use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{language_storage::ModuleId, vm_status::StatusCode}; -use move_vm_types::loaded_data::runtime_types::StructIdentifier; -use std::collections::{btree_map::Entry, BTreeMap}; +use move_vm_types::{ + loaded_data::runtime_types::StructIdentifier, module_id_interner::InternedModuleId, +}; +use std::collections::hash_map::Entry; /// The reentrancy checker's state #[derive(Default)] pub(crate) struct ReentrancyChecker { /// A multiset (bag) of active modules. This is not a set because the same /// module can be entered multiple times on closure dispatch. - active_modules: BTreeMap, - /// Whether we are in module lock mode. This happens if we enter a function via - /// `NativeDynamicDispatch`. + active_modules: fxhash::FxHashMap, + /// Whether we are in module lock mode. This happens if we enter a function which is locking: + /// - call via [CallType::NativeDynamicDispatch], + /// - function has `#[module_lock]` attribute. module_lock_count: usize, } @@ -46,26 +49,40 @@ pub(crate) enum CallType { ClosureDynamicDispatch, } +impl CallType { + /// Returns true of the call to callee needs to lock the module. This is the case if: + /// 1. we are dispatching via native, + /// 2. the callee has `#[module_lock]` attribute. + fn is_locking(&self, callee: &LoadedFunction) -> bool { + match self { + Self::NativeDynamicDispatch => true, + Self::Regular | Self::ClosureDynamicDispatch => callee.function.has_module_lock(), + } + } +} + impl ReentrancyChecker { + // note(inline): as `call_type` is sometimes a fixed value, this inline is very valuable + #[inline(always)] pub fn enter_function( &mut self, caller_module: Option<&ModuleId>, callee: &LoadedFunction, call_type: CallType, ) -> PartialVMResult<()> { - if call_type == CallType::NativeDynamicDispatch - || callee.function.has_module_reentrancy_lock - { - // If we enter a native dispatch function, or a function which has marked for locking, - // also enter module locking mode - self.enter_module_lock() + if call_type.is_locking(callee) { + self.enter_module_lock(); } + let callee_module = callee.module_or_script_id(); if Some(callee_module) != caller_module { // Cross module call. // When module lock is active, and we have already called into this module, this // reentry is disallowed - match self.active_modules.entry(callee_module.clone()) { + match self + .active_modules + .entry(callee.owner.interned_module_or_script_id()) + { Entry::Occupied(mut e) => { if self.module_lock_count > 0 { return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) @@ -91,12 +108,13 @@ impl ReentrancyChecker { // which already has a check in place preventing a dispatch into the same module. *self .active_modules - .entry(callee_module.clone()) + .entry(callee.owner.interned_module_or_script_id()) .or_default() += 1; } Ok(()) } + // note(inline): bloats code, not a hot path pub fn exit_function( &mut self, caller_module: &ModuleId, @@ -107,7 +125,10 @@ impl ReentrancyChecker { if caller_module != callee_module || call_type == CallType::ClosureDynamicDispatch { // If this is an exit from cross-module call, or exit from closure dispatch, // decrement counter. - match self.active_modules.entry(callee_module.clone()) { + match self + .active_modules + .entry(callee.owner.interned_module_or_script_id()) + { Entry::Occupied(mut e) => { let val = e.get_mut(); if *val == 1 { @@ -123,9 +144,9 @@ impl ReentrancyChecker { }, } } - if call_type == CallType::NativeDynamicDispatch || callee.function.has_module_lock() { - // If this is native dispatch, exit module lock. - self.exit_module_lock()? + + if call_type.is_locking(callee) { + self.exit_module_lock()?; } Ok(()) } @@ -148,7 +169,7 @@ impl ReentrancyChecker { pub fn check_resource_access(&self, struct_id: &StructIdentifier) -> PartialVMResult<()> { if self .active_modules - .get(&struct_id.module) + .get(&struct_id.interned_module_id()) .copied() .unwrap_or_default() > 1 diff --git a/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs b/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs new file mode 100644 index 00000000000..bb4732e8ebf --- /dev/null +++ b/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs @@ -0,0 +1,1877 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module implements the runtime reference checks for Move bytecode. +//! +//! Move bytecode has a bytecode verifier pass for enforcing reference safety rules: +//! the runtime checks implemented here are the relaxed dynamic semantics of that pass. +//! If the bytecode verifier pass succeeds, then the runtime checks should also succeed +//! for any execution path. +//! However, there may be Move bytecode that the bytecode verifier pass rejects, but +//! the runtime checks may still succeed, as long as reference-safety rules are not +//! violated (i.e., relaxed semantics). +//! +//! This checker maintains shadow state as the execution proceeds: the shadow state +//! contains information needed about the references in order to check for reference safety. +//! Note that simpler techniques such as reference counting are insufficient to +//! implement the dynamic relaxed semantics of the bytecode verifier pass. +//! +//! The shadow state contains: +//! - A shadow stack of values. Values which can either be non-references (we don't +//! keep track of their type or actual value) or references (represented by a +//! unique-per-caller-frame identifier). The shadow stack is shared across all +//! active frames in the call stack. +//! - A shadow frame stack of per-function data structures (described below). +//! The shadow frame stack grows and shrinks with the call stack. +//! +//! An access path tree, which is built out lazily as needed (for performance +//! reasons), represents a non-reference value. A reference always points to a node +//! in some access path tree. +//! +//! Consider, for example, a value of type `A`: +//! ```move +//! struct A { +//! x: B +//! } +//! +//! struct B { +//! y: vector +//! z: u64 +//! } +//! ``` +//! An access path tree for a value of type `A` would look like this: +//! ```tree +//! root +//! └──0── .x +//! ├──0── .y +//! │ └──0── all elements of the vector +//! └──1── .z +//! ``` +//! The edges are ordered by labels, given by field offsets for structs and variants. +//! For vectors, we use `0` to abstract all elements, instead of tracking +//! each element of the vector separately. This is done for performance reasons. +//! +//! The per-function frame data structure contains: +//! - A shadow list of values for all locals. +//! - An access path tree for: +//! - each local that is not a reference +//! - each resource type globally borrowed by the function +//! - each value behind reference parameters passed to the function +//! - A map from reference identifiers to the following info: +//! - whether the reference is mutable or immutable +//! - whether the reference is poisoned or not +//! - the access path tree node corresponding to the reference +//! - A map from each reference parameter index to the corresponding access path tree +//! node in the caller's frame (if it exists) +//! +//! The informal idea is that we allow borrowing of references (mutable or immutable), +//! but poison references when the underlying value is moved, or when a destructive +//! update is performed via a mutable reference. Later, any use of a poisoned reference +//! will result in an invariant violation error. +//! +//! When a call is made with reference parameters, the corresponding access path tree +//! node subtree is locked (with exclusive lock for mutable references, and shared +//! lock for immutable references). This is to make sure that values behind mutable +//! references are unique at function call boundaries. +//! +//! When we return references on the shadow stack, we ensure that they are derived from +//! one of the reference parameters. They are also transformed to point to the +//! corresponding access path tree node in the caller's frame (if it exists). + +use crate::{frame::Frame, frame_type_cache::FrameTypeCache, LoadedFunction}; +use fxhash::FxBuildHasher; +use hashbrown::HashMap; +use move_binary_format::{ + errors::{PartialVMError, PartialVMResult}, + safe_assert, safe_unwrap, safe_unwrap_err, +}; +use move_core_types::{ + function::ClosureMask, + vm_status::{sub_status::unknown_invariant_violation::EREFERENCE_SAFETY_FAILURE, StatusCode}, +}; +use move_vm_types::{instr::Instruction, loaded_data::runtime_types::Type}; +use std::{collections::BTreeSet, slice}; + +/// A deterministic hash map (used in the Rust compiler), expected to perform well. +/// Not resistant to hash collision attacks, nor is it cryptographically secure. +/// Should not be used for iterating over keys without sorting first. +type UnorderedMap = HashMap; + +/// `ref_check_failure!(msg)` will return a `PartialVMError` with the given message +/// and a sub-status code indicating a reference safety failure. +macro_rules! ref_check_failure { + ($msg:ident) => { + Err( + PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) + .with_message($msg) + .with_sub_status(EREFERENCE_SAFETY_FAILURE), + ) + }; +} + +/// Represents a value in the shadow stack or shadow locals list. +#[derive(Clone, Copy)] +enum Value { + /// A non-reference value + NonRef, + /// A reference value + Ref(RefID), +} + +/// Unique (within a frame) identifier for a reference. +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +struct RefID(usize); + +/// Access Path Tree, representing the access paths corresponding +/// to a value (local, global, or value behind a reference parameter) in a frame. +/// It is built up lazily as needed. +struct AccessPathTree { + nodes: Vec, +} + +/// Node ID in a given access path tree, acts an index into the access path tree's +/// node list. +type NodeID = usize; +/// Edge label for an edge between two nodes in a given access path tree. +type EdgeLabel = usize; + +/// A node in the access path tree. +struct AccessPathTreeNode { + /// Parent node id and edge label (`None` for root nodes) + parent: Option<(NodeID, EdgeLabel)>, + /// Child nodes, edge label is the index in this vector + children: Vec>, + /// References to this node + refs: BTreeSet, + /// Current lock on this node + lock: Option, +} + +/// Represents the type of lock on an access path tree node. +#[derive(Copy, Clone, PartialEq, Eq)] +enum Lock { + /// Shared lock - multiple shared locks on the same node are allowed + Shared, + /// Exclusive lock - conflicts with any other lock + Exclusive, +} + +/// Different kinds of root nodes in a frame. +#[derive(Clone)] +enum AccessPathTreeRoot { + /// Root representing a local (non-ref) value + Local { index: usize }, + /// Root representing a global type + Global { type_: Type }, + /// Special node representing the value behind a reference parameter + ReferenceParameter { param_index: usize }, +} + +/// Collection of access path tree roots information for a frame. +struct AccessPathTreeRootsInfo { + /// Mapping from local index to the corresponding access path tree + locals: UnorderedMap, + /// Mapping from global type to the corresponding access path tree + globals: UnorderedMap, + /// Mapping from reference parameter index to the corresponding access path tree + reference_params: UnorderedMap, +} + +/// The root of the access path tree and the node ID within that tree. +#[derive(Clone)] +struct QualifiedNodeID { + root: AccessPathTreeRoot, + node_id: NodeID, +} + +/// Per frame reference checking state. +struct FrameRefState { + /// Shadow list of local values. + locals: Vec, + /// Roots of the Access Path Tree for this frame. + access_path_tree_roots: AccessPathTreeRootsInfo, + /// Mapping from references to their information. + /// Reference ID is unique within the frame. + ref_table: UnorderedMap, + /// Next available reference ID. + next_ref_id: usize, + /// Map the reference parameter's index to the access path tree node + /// (in the caller's `FrameRefState`) corresponding to the reference parameter. + caller_ref_param_map: UnorderedMap, +} + +/// Filter for references when applying actions such as poisoning. +enum ReferenceFilter { + /// Apply action to mutable references only + MutOnly, + /// Apply action to immutable references only + ImmutOnly, + /// Apply action to all references + All, +} + +enum VisitKind { + /// Visit the node itself + SelfOnly, + /// Visit strict descendants of the node + StrictDescendants, + /// Visit strict ancestors of the node + StrictAncestors, +} + +/// Various information about a reference. +struct ReferenceInfo { + /// Whether this reference is mutable + is_mutable: bool, + /// Whether this reference is poisoned + poisoned: bool, + /// The access path tree node this reference points to + access_path_tree_node: QualifiedNodeID, +} + +/// State associated with the reference checker. +/// This state is transitioned and checked as the bytecode is executed. +pub(crate) struct RefCheckState { + /// Shadow stack of ref/non-ref values. + /// This is shared between all the frames in the call stack. + shadow_stack: Vec, + + /// Stack of per-frame reference states. + frame_stack: Vec, +} + +/// A trait for determining the behavior of the runtime reference checks. +pub(crate) trait RuntimeRefCheck { + /// Transitions the reference check state before executing a bytecode instruction. + fn pre_execution_transition( + frame: &Frame, + instruction: &Instruction, + ref_state: &mut RefCheckState, + ) -> PartialVMResult<()>; + + /// Transitions the reference check state after executing a bytecode instruction. + fn post_execution_transition( + frame: &Frame, + instruction: &Instruction, + ref_state: &mut RefCheckState, + ty_cache: &mut FrameTypeCache, + ) -> PartialVMResult<()>; + + /// Transitions the reference check state during various forms of function calls. + fn core_call_transition( + num_params: usize, + num_locals: usize, + mask: ClosureMask, + ref_state: &mut RefCheckState, + ) -> PartialVMResult<()>; + + /// Initializes the reference check state on the entrypoint function. + fn init_entry(function: &LoadedFunction, ref_state: &mut RefCheckState) -> PartialVMResult<()>; +} + +/// A no-op implementation of the `RuntimeRefCheck` trait, which does not perform +/// any runtime reference checks. +pub(crate) struct NoRuntimeRefCheck; + +/// An implementation of the `RuntimeRefCheck` trait that performs the reference checks +/// as described in the module documentation. +pub(crate) struct FullRuntimeRefCheck; + +impl RuntimeRefCheck for NoRuntimeRefCheck { + fn pre_execution_transition( + _frame: &Frame, + _instruction: &Instruction, + _ref_state: &mut RefCheckState, + ) -> PartialVMResult<()> { + Ok(()) + } + + fn post_execution_transition( + _frame: &Frame, + _instruction: &Instruction, + _ref_state: &mut RefCheckState, + _ty_cache: &mut FrameTypeCache, + ) -> PartialVMResult<()> { + Ok(()) + } + + fn core_call_transition( + _num_params: usize, + _num_locals: usize, + _mask: ClosureMask, + _ref_state: &mut RefCheckState, + ) -> PartialVMResult<()> { + Ok(()) + } + + fn init_entry( + _function: &LoadedFunction, + _ref_state: &mut RefCheckState, + ) -> PartialVMResult<()> { + Ok(()) + } +} + +impl RuntimeRefCheck for FullRuntimeRefCheck { + /// It may be preferred to have as many transitions in the `post_execution_transition`, because + /// gas is charged during execution, but we may want to validate this preference. + fn pre_execution_transition( + frame: &Frame, + instruction: &Instruction, + ref_state: &mut RefCheckState, + ) -> PartialVMResult<()> { + use Instruction::*; + match instruction { + Call(_) | CallGeneric(_) | Branch(_) => { + // `Call` and `CallGeneric` are handled by calling `core_call_transition` elsewhere + }, + BrFalse(_) | BrTrue(_) | CallClosure(_) | Abort => { + // remove the top value from the shadow stack + let _ = ref_state.pop_from_shadow_stack()?; + }, + Ret => { + ref_state.return_(frame.function.return_tys().len())?; + }, + ReadRef => { + ref_state.pop_ref_push_non_ref()?; + }, + StLoc(_) + | Pop + | LdU8(_) + | LdU16(_) + | LdU32(_) + | LdU64(_) + | LdU128(_) + | LdU256(_) + | LdI8(_) + | LdI16(_) + | LdI32(_) + | LdI64(_) + | LdI128(_) + | LdI256(_) + | LdTrue + | LdFalse + | LdConst(_) + | CopyLoc(_) + | MoveLoc(_) + | MutBorrowLoc(_) + | ImmBorrowLoc(_) + | ImmBorrowField(_) + | MutBorrowField(_) + | ImmBorrowFieldGeneric(_) + | MutBorrowFieldGeneric(_) + | PackClosure(..) + | PackClosureGeneric(..) + | Pack(_) + | PackGeneric(_) + | Unpack(_) + | UnpackGeneric(_) + | WriteRef + | CastU8 + | CastU16 + | CastU32 + | CastU64 + | CastU128 + | CastU256 + | CastI8 + | CastI16 + | CastI32 + | CastI64 + | CastI128 + | CastI256 + | Add + | Sub + | Mul + | Mod + | Div + | Negate + | BitOr + | BitAnd + | Xor + | Or + | And + | Shl + | Shr + | Lt + | Le + | Gt + | Ge + | Eq + | Neq + | MutBorrowGlobal(_) + | ImmBorrowGlobal(_) + | MutBorrowGlobalGeneric(_) + | ImmBorrowGlobalGeneric(_) + | Exists(_) + | ExistsGeneric(_) + | MoveTo(_) + | MoveToGeneric(_) + | MoveFrom(_) + | MoveFromGeneric(_) + | FreezeRef + | Nop + | Not + | VecPack(_, _) + | VecLen(_) + | VecImmBorrow(_) + | VecMutBorrow(_) + | VecPushBack(_) + | VecPopBack(_) + | VecUnpack(_, _) + | VecSwap(_) + | PackVariant(_) + | PackVariantGeneric(_) + | UnpackVariant(_) + | UnpackVariantGeneric(_) + | TestVariant(_) + | TestVariantGeneric(_) + | MutBorrowVariantField(_) + | MutBorrowVariantFieldGeneric(_) + | ImmBorrowVariantField(_) + | ImmBorrowVariantFieldGeneric(_) => { + // handled in `post_execution_transition` + }, + }; + Ok(()) + } + + fn post_execution_transition( + frame: &Frame, + instruction: &Instruction, + ref_state: &mut RefCheckState, + ty_cache: &mut FrameTypeCache, + ) -> PartialVMResult<()> { + use Instruction::*; + match instruction { + Pop => { + let top = ref_state.pop_from_shadow_stack()?; + if let Value::Ref(ref_id) = top { + ref_state.purge_reference(ref_id)?; + } + }, + Ret | BrTrue(_) | BrFalse(_) | Branch(_) => { + // not reachable here, transition is handled in `pre_execution_transition` + }, + CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 | CastI8 | CastI16 + | CastI32 | CastI64 | CastI128 | CastI256 | Not | Nop | Exists(_) + | ExistsGeneric(_) => { + // no-op + }, + LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU128(_) | LdU256(_) | LdI8(_) + | LdI16(_) | LdI32(_) | LdI64(_) | LdI128(_) | LdI256(_) | LdConst(_) | LdTrue + | LdFalse => { + ref_state.push_non_refs_to_shadow_stack(1); + }, + CopyLoc(index) => { + ref_state.copy_loc(*index)?; + }, + MoveLoc(index) => { + ref_state.move_loc(*index)?; + }, + StLoc(index) => { + ref_state.st_loc(*index)?; + }, + Call(_) | CallGeneric(_) | CallClosure(_) => { + // not reachable here, transition handled in `core_call_transition` + }, + Pack(index) => { + let num_fields = frame.field_count(*index).into(); + ref_state.pop_many_from_shadow_stack(num_fields)?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + PackGeneric(index) => { + let num_fields = frame.field_instantiation_count(*index).into(); + ref_state.pop_many_from_shadow_stack(num_fields)?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + PackVariant(index) => { + let struct_variant_info = frame.get_struct_variant_at(*index); + let num_fields = struct_variant_info.field_count.into(); + ref_state.pop_many_from_shadow_stack(num_fields)?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + PackVariantGeneric(index) => { + let struct_variant_info = frame.get_struct_variant_instantiation_at(*index); + let num_fields = struct_variant_info.field_count.into(); + ref_state.pop_many_from_shadow_stack(num_fields)?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + Unpack(index) => { + ref_state.pop_from_shadow_stack()?; + let num_fields = frame.field_count(*index).into(); + ref_state.push_non_refs_to_shadow_stack(num_fields); + }, + UnpackGeneric(index) => { + ref_state.pop_from_shadow_stack()?; + let num_fields = frame.field_instantiation_count(*index).into(); + ref_state.push_non_refs_to_shadow_stack(num_fields); + }, + UnpackVariant(index) => { + ref_state.pop_from_shadow_stack()?; + let struct_variant_info = frame.get_struct_variant_at(*index); + let num_fields = struct_variant_info.field_count.into(); + ref_state.push_non_refs_to_shadow_stack(num_fields); + }, + UnpackVariantGeneric(index) => { + ref_state.pop_from_shadow_stack()?; + let struct_variant_info = frame.get_struct_variant_instantiation_at(*index); + let num_fields = struct_variant_info.field_count.into(); + ref_state.push_non_refs_to_shadow_stack(num_fields); + }, + TestVariant(_) => { + ref_state.pop_ref_push_non_ref()?; + }, + TestVariantGeneric(_) => { + ref_state.pop_ref_push_non_ref()?; + }, + ReadRef => { + // Transition handled in `pre_execution_transition` + }, + WriteRef => { + ref_state.write_ref()?; + }, + FreezeRef => { + ref_state.freeze_ref()?; + }, + MutBorrowLoc(index) => { + ref_state.borrow_loc(*index, true)?; + }, + ImmBorrowLoc(index) => { + ref_state.borrow_loc(*index, false)?; + }, + MutBorrowField(index) => { + let label = frame.field_offset(*index); + ref_state.borrow_child_with_label::(label)?; + }, + MutBorrowVariantField(index) => { + let field_info = frame.variant_field_info_at(*index); + let label = field_info.offset; + ref_state.borrow_child_with_label::(label)?; + }, + MutBorrowFieldGeneric(index) => { + let label = frame.field_instantiation_offset(*index); + ref_state.borrow_child_with_label::(label)?; + }, + MutBorrowVariantFieldGeneric(index) => { + let field_info = frame.variant_field_instantiation_info_at(*index); + let label = field_info.offset; + ref_state.borrow_child_with_label::(label)?; + }, + ImmBorrowField(index) => { + let label = frame.field_offset(*index); + ref_state.borrow_child_with_label::(label)?; + }, + ImmBorrowVariantField(index) => { + let field_info = frame.variant_field_info_at(*index); + let label = field_info.offset; + ref_state.borrow_child_with_label::(label)?; + }, + ImmBorrowFieldGeneric(index) => { + let label = frame.field_instantiation_offset(*index); + ref_state.borrow_child_with_label::(label)?; + }, + ImmBorrowVariantFieldGeneric(index) => { + let field_info = frame.variant_field_instantiation_info_at(*index); + let label = field_info.offset; + ref_state.borrow_child_with_label::(label)?; + }, + MutBorrowGlobal(index) => { + let struct_ty = frame.get_struct_ty(*index); + ref_state.borrow_global::(struct_ty)?; + }, + MutBorrowGlobalGeneric(index) => { + let struct_ty = ty_cache.get_struct_type(*index, frame)?.0; + ref_state.borrow_global::(struct_ty.clone())?; + }, + ImmBorrowGlobal(index) => { + let struct_ty = frame.get_struct_ty(*index); + ref_state.borrow_global::(struct_ty)?; + }, + ImmBorrowGlobalGeneric(index) => { + let struct_ty = ty_cache.get_struct_type(*index, frame)?.0; + ref_state.borrow_global::(struct_ty.clone())?; + }, + Add | Sub | Mul | Mod | Div | BitOr | BitAnd | Xor | Or | And | Lt | Gt | Le | Ge + | Shl | Shr => { + // pop two non-ref values from the shadow stack, push a new non-ref value + let _ = ref_state.pop_from_shadow_stack()?; + }, + Negate => { + // leaves shadow stack at same value + }, + Eq | Neq => { + // pop two values from the shadow stack (which can be ref or non-ref values) + let top_1 = ref_state.pop_from_shadow_stack()?; + let top_2 = ref_state.pop_from_shadow_stack()?; + if let (Value::Ref(ref_1), Value::Ref(ref_2)) = (top_1, top_2) { + ref_state.purge_reference(ref_1)?; + ref_state.purge_reference(ref_2)?; + } + // push a non-ref value onto the shadow stack + ref_state.push_non_refs_to_shadow_stack(1); + }, + Abort => { + // not reachable here, transition handled in `pre_execution_transition` + }, + MoveFrom(index) => { + let struct_ty = frame.get_struct_ty(*index); + ref_state.move_from(struct_ty)?; + }, + MoveFromGeneric(index) => { + let struct_ty = ty_cache.get_struct_type(*index, frame)?.0; + ref_state.move_from(struct_ty.clone())?; + }, + MoveTo(_) => { + ref_state.move_to()?; + }, + MoveToGeneric(_) => { + ref_state.move_to()?; + }, + VecPack(_, n) => { + ref_state.pop_many_from_shadow_stack(safe_unwrap_err!((*n).try_into()))?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + VecLen(_) => { + ref_state.vec_len()?; + }, + VecImmBorrow(_) => { + ref_state.vec_borrow::()?; + }, + VecMutBorrow(_) => { + ref_state.vec_borrow::()?; + }, + VecPushBack(_) => { + ref_state.vec_push_back()?; + }, + VecPopBack(_) => { + ref_state.vec_pop_back()?; + }, + VecUnpack(_, n) => { + let _ = ref_state.pop_from_shadow_stack()?; + ref_state.push_non_refs_to_shadow_stack(safe_unwrap_err!((*n).try_into())); + }, + VecSwap(_) => { + ref_state.vec_swap()?; + }, + PackClosure(_, mask) => { + let captured = mask.captured_count(); + // note: we are not checking that values captured are non-ref values, as this belongs + // to type checks. + ref_state.pop_many_from_shadow_stack(captured.into())?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + PackClosureGeneric(_, mask) => { + let captured = mask.captured_count(); + ref_state.pop_many_from_shadow_stack(captured.into())?; + ref_state.push_non_refs_to_shadow_stack(1); + }, + }; + Ok(()) + } + + fn core_call_transition( + num_params: usize, + num_locals: usize, + mask: ClosureMask, + ref_state: &mut RefCheckState, + ) -> PartialVMResult<()> { + ref_state.core_call(num_params, num_locals, mask) + } + + fn init_entry(function: &LoadedFunction, ref_state: &mut RefCheckState) -> PartialVMResult<()> { + let num_locals = function.local_tys().len(); + let mut mut_ref_indexes = vec![]; + let mut immut_ref_indexes = vec![]; + for (i, ty) in function.param_tys().iter().enumerate() { + match ty { + Type::Reference(_) => immut_ref_indexes.push(i), + Type::MutableReference(_) => mut_ref_indexes.push(i), + _ => continue, + } + } + // Empty map, references are not transformed when returning from the entrypoint function. + let caller_ref_param_map = UnorderedMap::with_hasher(FxBuildHasher::default()); + ref_state.push_new_frame( + num_locals, + mut_ref_indexes, + immut_ref_indexes, + caller_ref_param_map, + )?; + + Ok(()) + } +} + +impl AccessPathTree { + /// Create a new Access Path Tree with a fresh root node. + fn new() -> Self { + Self { + nodes: vec![AccessPathTreeNode::fresh_root()], + } + } + + /// Make a new child node in the access path tree, given the parent node ID + /// and the label for the edge. + fn make_new_node(&mut self, parent_id: NodeID, label: EdgeLabel) -> NodeID { + let new_node = AccessPathTreeNode::fresh_node(parent_id, label); + self.nodes.push(new_node); + self.nodes.len() - 1 + } + + /// Get a reference to the node at `node_id`. + fn get_node(&self, node_id: NodeID) -> PartialVMResult<&AccessPathTreeNode> { + Ok(safe_unwrap!(self.nodes.get(node_id))) + } + + /// Get a mutable reference to the node at `node_id`. + fn get_node_mut(&mut self, node_id: NodeID) -> PartialVMResult<&mut AccessPathTreeNode> { + Ok(safe_unwrap!(self.nodes.get_mut(node_id))) + } + + /// Given the parent node ID and the label, get the existing child node or create a new one. + fn get_or_create_child_node( + &mut self, + parent_id: NodeID, + label: EdgeLabel, + ) -> PartialVMResult { + let parent_node = self.get_node_mut(parent_id)?; + let child_id = parent_node.children.get(label); + // Should we resize the children vector? + let resize = match child_id { + // child slot exists and is occupied, return its ID + Some(Some(child_id)) => return Ok(*child_id), + // child slot exists but is unoccupied, no need to resize, just occupy it + Some(None) => false, + // child slot does not exist, we need to resize and then occupy it + None => true, + }; + + if resize { + parent_node + .children + .resize(safe_unwrap!(label.checked_add(1)), None); + } + + // Create a new child node, and update the parent's children slot. + let new_child_id = self.make_new_node(parent_id, label); + // Re-borrow to satisfy Rust's borrow checker. + let parent_node = self.get_node_mut(parent_id)?; + *safe_unwrap!(parent_node.children.get_mut(label)) = Some(new_child_id); + Ok(new_child_id) + } + + /// Visit the strict descendants (i.e., exclude self) of the node and apply `f` to each. + fn visit_strict_descendants(&mut self, node_id: NodeID, mut f: F) -> PartialVMResult<()> + where + F: FnMut(&mut AccessPathTreeNode) -> PartialVMResult<()>, + { + // We need to collect the descendants first, because we are mutating nodes while visiting. + for descendant in self + .get_descendants_iter(node_id) + .skip(1) + .collect::>() + { + let node = self.get_node_mut(descendant)?; + f(node)?; + } + Ok(()) + } + + /// Visit the node itself and apply `f` to it. + fn visit_self(&mut self, node_id: NodeID, mut f: F) -> PartialVMResult<()> + where + F: FnMut(&mut AccessPathTreeNode) -> PartialVMResult<()>, + { + let node = self.get_node_mut(node_id)?; + f(node)?; + Ok(()) + } + + /// Visit the strict ancestors of the node (i.e., excluding self) and apply `f` to each. + fn visit_strict_ancestors(&mut self, node_id: NodeID, mut f: F) -> PartialVMResult<()> + where + F: FnMut(&mut AccessPathTreeNode) -> PartialVMResult<()>, + { + let mut current_node_id = node_id; + while let Some((parent_id, _label)) = self.get_node(current_node_id)?.parent { + let parent_node = self.get_node_mut(parent_id)?; + f(parent_node)?; + current_node_id = parent_id; + } + Ok(()) + } + + /// Get the list of edge labels that can be used to get from the root node to the given node. + fn get_access_path_from_root(&self, node_id: NodeID) -> PartialVMResult> { + let mut current_node_id = node_id; + let mut path = Vec::new(); + while let Some((parent_id, label)) = self.get_node(current_node_id)?.parent { + current_node_id = parent_id; + path.push(label); + } + path.reverse(); + Ok(path) + } + + /// Get an iterator over the descendants (including self) of the given node. + fn get_descendants_iter<'a>(&'a self, node_id: NodeID) -> DescendantsTraversalIter<'a> { + DescendantsTraversalIter { + stack: vec![node_id], + access_path_tree: self, + } + } +} + +/// An iterator for traversing the descendants of an access path tree node. +struct DescendantsTraversalIter<'a> { + stack: Vec, + access_path_tree: &'a AccessPathTree, +} + +impl<'a> Iterator for DescendantsTraversalIter<'a> { + type Item = NodeID; + + fn next(&mut self) -> Option { + let node_id = self.stack.pop()?; + // When processing a node, its children are added to the stack in reverse order. + if let Some(node) = self.access_path_tree.nodes.get(node_id) { + self.stack.extend(node.children.iter().rev().flatten()); + } // else should be unreachable, as we should not have invalid node IDs + Some(node_id) + } +} + +impl AccessPathTreeNode { + /// Create a fresh root node for the access path tree. + fn fresh_root() -> Self { + Self { + parent: None, + children: Vec::new(), + refs: BTreeSet::new(), + lock: None, + } + } + + /// Create a fresh child node with the given parent and edge label. + fn fresh_node(parent_id: NodeID, label: EdgeLabel) -> Self { + Self { + parent: Some((parent_id, label)), + children: Vec::new(), + refs: BTreeSet::new(), + lock: None, + } + } +} + +impl AccessPathTreeRootsInfo { + /// Get a reference to the access path tree for the given root. + /// Should be called when the root is guaranteed to exist. + fn get_access_path_tree(&self, root: &AccessPathTreeRoot) -> PartialVMResult<&AccessPathTree> { + match root { + AccessPathTreeRoot::Local { index } => Ok(safe_unwrap!(self.locals.get(index))), + AccessPathTreeRoot::Global { type_ } => Ok(safe_unwrap!(self.globals.get(type_))), + AccessPathTreeRoot::ReferenceParameter { param_index } => { + Ok(safe_unwrap!(self.reference_params.get(param_index))) + }, + } + } + + /// Get a mutable reference to the access path tree for the given root. + /// Should be called when the root is guaranteed to exist. + fn get_mut_access_path_tree( + &mut self, + root: &AccessPathTreeRoot, + ) -> PartialVMResult<&mut AccessPathTree> { + Ok(safe_unwrap!(self.maybe_get_mut_access_path_tree(root))) + } + + /// Get a mutable reference to the access path tree for the given root, if it exists. + fn maybe_get_mut_access_path_tree( + &mut self, + root: &AccessPathTreeRoot, + ) -> Option<&mut AccessPathTree> { + match root { + AccessPathTreeRoot::Local { index } => self.locals.get_mut(index), + AccessPathTreeRoot::Global { type_ } => self.globals.get_mut(type_), + AccessPathTreeRoot::ReferenceParameter { param_index } => { + self.reference_params.get_mut(param_index) + }, + } + } + + /// Get a mutable reference to the given node in the access path tree. + fn get_mut_access_path_tree_node( + &mut self, + node: &QualifiedNodeID, + ) -> PartialVMResult<&mut AccessPathTreeNode> { + let access_path_tree = self.get_mut_access_path_tree(&node.root)?; + Ok(safe_unwrap!(access_path_tree.nodes.get_mut(node.node_id))) + } +} + +impl QualifiedNodeID { + /// A root node corresponding to a local with the given index. + fn local_root(index: usize) -> Self { + Self { + root: AccessPathTreeRoot::Local { index }, + node_id: 0, // root is always at 0 + } + } + + /// A root node corresponding to a global type. + fn global_root(type_: Type) -> Self { + Self { + root: AccessPathTreeRoot::Global { type_ }, + node_id: 0, // root is always at 0 + } + } + + /// A root node corresponding to a reference parameter with the given index. + fn reference_param_root(param_index: usize) -> Self { + Self { + root: AccessPathTreeRoot::ReferenceParameter { param_index }, + node_id: 0, // root is always at 0 + } + } +} + +impl FrameRefState { + /// Create a new `FrameRefState`. + /// - `num_locals` is the number of locals in the frame. + /// - `mut_ref_indexes` are the indexes of mutable reference parameters. + /// - `immut_ref_indexes` are the indexes of immutable reference parameters. + /// - `caller_ref_param_map` maps the reference parameter's index to the access path tree + /// node corresponding to the reference parameter in the caller's `FrameRefState`. + fn new( + num_locals: usize, + mut_ref_indexes: Vec, + immut_ref_indexes: Vec, + caller_ref_param_map: UnorderedMap, + ) -> PartialVMResult { + debug_assert!( + num_locals >= mut_ref_indexes.len() + immut_ref_indexes.len(), + "locals should be enough for all reference parameters" + ); + debug_assert!( + caller_ref_param_map + .keys() + .all(|index| mut_ref_indexes.contains(index) || immut_ref_indexes.contains(index)), + "consistency check for caller_ref_param_map" + ); + let mut this = Self { + // initially, all locals are non-ref values + locals: vec![Value::NonRef; num_locals], + access_path_tree_roots: AccessPathTreeRootsInfo { + locals: UnorderedMap::with_hasher(FxBuildHasher::default()), + globals: UnorderedMap::with_hasher(FxBuildHasher::default()), + reference_params: UnorderedMap::with_hasher(FxBuildHasher::default()), + }, + ref_table: UnorderedMap::with_hasher(FxBuildHasher::default()), + next_ref_id: 0, + caller_ref_param_map, + }; + // Locals corresponding to reference parameters are handled below. + for index in mut_ref_indexes { + let node_id = QualifiedNodeID::reference_param_root(index); + this.ensure_reference_param_root_exists(index); + let new_ref_id = this.make_new_ref_to_existing_node(node_id, true)?; + *safe_unwrap!(this.locals.get_mut(index)) = Value::Ref(new_ref_id); + } + for index in immut_ref_indexes { + let node_id = QualifiedNodeID::reference_param_root(index); + this.ensure_reference_param_root_exists(index); + let new_ref_id = this.make_new_ref_to_existing_node(node_id, false)?; + *safe_unwrap!(this.locals.get_mut(index)) = Value::Ref(new_ref_id); + } + Ok(this) + } + + /// Check if the reference has been poisoned. + fn poison_check(&self, ref_id: RefID) -> PartialVMResult<()> { + let poisoned = safe_unwrap!(self.ref_table.get(&ref_id)).poisoned; + if poisoned { + let msg = "Poisoned reference accessed".to_string(); + return ref_check_failure!(msg); + } + Ok(()) + } + + /// Get the reference information for the given `ref_id`. + fn get_ref_info(&self, ref_id: &RefID) -> PartialVMResult<&ReferenceInfo> { + Ok(safe_unwrap!(self.ref_table.get(ref_id))) + } + + /// Poison the references related to the given `node`. + /// Specify which references to poison using `visit_kind` and `filter`. + fn poison_refs_of_node( + &mut self, + node: &QualifiedNodeID, + visit_kind: VisitKind, + filter: ReferenceFilter, + ) -> PartialVMResult<()> { + let Some(tree) = self + .access_path_tree_roots + .maybe_get_mut_access_path_tree(&node.root) + else { + // If the tree is not present, there are no references to poison. + return Ok(()); + }; + let action = |node: &mut AccessPathTreeNode| { + for ref_ in node.refs.iter() { + let info = safe_unwrap!(self.ref_table.get_mut(ref_)); + match filter { + ReferenceFilter::All => { + info.poisoned = true; + }, + ReferenceFilter::MutOnly if info.is_mutable => { + info.poisoned = true; + }, + ReferenceFilter::ImmutOnly if !info.is_mutable => { + info.poisoned = true; + }, + _ => {}, + } + } + Ok(()) + }; + match visit_kind { + VisitKind::SelfOnly => tree.visit_self(node.node_id, action)?, + VisitKind::StrictDescendants => tree.visit_strict_descendants(node.node_id, action)?, + VisitKind::StrictAncestors => tree.visit_strict_ancestors(node.node_id, action)?, + } + Ok(()) + } + + /// Perform a destructive write via a mutable reference to the given `node`. + fn destructive_write_via_mut_ref(&mut self, node: &QualifiedNodeID) -> PartialVMResult<()> { + // Poison all immutable references of the node, its descendants, and ancestors. + self.poison_refs_of_node(node, VisitKind::SelfOnly, ReferenceFilter::ImmutOnly)?; + self.poison_refs_of_node( + node, + VisitKind::StrictDescendants, + ReferenceFilter::ImmutOnly, + )?; + self.poison_refs_of_node(node, VisitKind::StrictAncestors, ReferenceFilter::ImmutOnly)?; + + // Poison all mutable references of the node's strict descendants. + // Note that mutable references of the node itself are not poisoned, which is needed + // to keep consistent with the static bytecode verifier reference rules. + self.poison_refs_of_node(node, VisitKind::StrictDescendants, ReferenceFilter::MutOnly)?; + + Ok(()) + } + + /// Lock the entire subtree rooted at the given `node` with the specified `lock`. + /// If any node in the subtree is already exclusively locked, it returns an invariant error. + fn lock_node_subtree(&mut self, node: &QualifiedNodeID, lock: Lock) -> PartialVMResult<()> { + let tree = self + .access_path_tree_roots + .get_mut_access_path_tree(&node.root)?; + let action = |node: &mut AccessPathTreeNode| { + if let Some(node_lock) = node.lock { + if lock == Lock::Exclusive || node_lock == Lock::Exclusive { + let msg = "Exclusive lock conflict".to_string(); + return ref_check_failure!(msg); + } + } + node.lock = Some(lock); + Ok(()) + }; + tree.visit_self(node.node_id, action)?; + tree.visit_strict_descendants(node.node_id, action)?; + Ok(()) + } + + /// Release all locks on the entire subtree rooted at the given `node`. + fn release_lock_node_subtree(&mut self, node: &QualifiedNodeID) -> PartialVMResult<()> { + let tree = self + .access_path_tree_roots + .get_mut_access_path_tree(&node.root)?; + let action = |node: &mut AccessPathTreeNode| { + node.lock = None; + Ok(()) + }; + tree.visit_self(node.node_id, action)?; + tree.visit_strict_descendants(node.node_id, action)?; + Ok(()) + } + + /// Consume the reference with the given `ref_id`. + /// This will get rid of `ref_id` from various data structures. + fn purge_reference(&mut self, ref_id: RefID) -> PartialVMResult<()> { + let info = safe_unwrap!(self.ref_table.remove(&ref_id)); + let node = self.get_mut_access_path_tree_node(&info.access_path_tree_node)?; + node.refs.remove(&ref_id); + Ok(()) + } + + /// Make a new reference to an existing node in the access path tree. + fn make_new_ref_to_existing_node( + &mut self, + qualified_node_id: QualifiedNodeID, + is_mutable: bool, + ) -> PartialVMResult { + let new_ref_id = RefID(self.next_ref_id); + self.next_ref_id = safe_unwrap!(self.next_ref_id.checked_add(1)); + + let access_path_tree_node = self.get_mut_access_path_tree_node(&qualified_node_id)?; + // Connect the `access_path_tree_node` to the new reference. + // We just made this `new_ref_id`, so it must not already exist in the `access_path_tree_node`'s refs. + safe_assert!(access_path_tree_node.refs.insert(new_ref_id)); + + // Connect the new reference to the `access_path_tree_node`. + self.ref_table.insert(new_ref_id, ReferenceInfo { + is_mutable, + poisoned: false, + access_path_tree_node: qualified_node_id, + }); + + Ok(new_ref_id) + } + + /// Ensure that the local root exists for the given index. + fn ensure_local_root_exists(&mut self, index: usize) { + self.access_path_tree_roots + .locals + .entry(index) + .or_insert_with(AccessPathTree::new); + } + + /// Ensure that the global root exists for the given type. + fn ensure_global_root_exists(&mut self, type_: Type) { + self.access_path_tree_roots + .globals + .entry(type_) + .or_insert_with(AccessPathTree::new); + } + + /// Ensure that the reference parameter root exists for the given parameter index. + fn ensure_reference_param_root_exists(&mut self, param_index: usize) { + self.access_path_tree_roots + .reference_params + .entry(param_index) + .or_insert_with(AccessPathTree::new); + } + + /// Get or create a new descendant node in the access_path_tree_node, given the parent node ID and the access path. + /// Will also create any intermediate nodes if needed. + fn get_or_create_descendant_node( + &mut self, + parent_id: &QualifiedNodeID, + access_path: &[EdgeLabel], + ) -> PartialVMResult { + let access_path_tree = self + .access_path_tree_roots + .get_mut_access_path_tree(&parent_id.root)?; + let mut node_id = parent_id.node_id; + for label in access_path { + node_id = access_path_tree.get_or_create_child_node(node_id, *label)?; + } + Ok(QualifiedNodeID { + root: parent_id.root.clone(), + node_id, + }) + } + + /// Does the subtree rooted at `node` have any references that match the given `filter`? + fn subtree_has_references( + &self, + node: &QualifiedNodeID, + filter: ReferenceFilter, + ) -> PartialVMResult { + let access_path_tree = self + .access_path_tree_roots + .get_access_path_tree(&node.root)?; + // Note that the node itself is included in the descendants. + for descendant in access_path_tree.get_descendants_iter(node.node_id) { + let access_path_tree_node = safe_unwrap!(access_path_tree.nodes.get(descendant)); + for ref_ in access_path_tree_node.refs.iter() { + match filter { + ReferenceFilter::All => return Ok(true), + ReferenceFilter::MutOnly + if safe_unwrap!(self.ref_table.get(ref_)).is_mutable => + { + return Ok(true) + }, + ReferenceFilter::ImmutOnly + if !safe_unwrap!(self.ref_table.get(ref_)).is_mutable => + { + return Ok(true) + }, + _ => {}, + }; + } + } + Ok(false) + } + + /// Get a mutable reference to the access path tree node. + fn get_mut_access_path_tree_node( + &mut self, + node: &QualifiedNodeID, + ) -> PartialVMResult<&mut AccessPathTreeNode> { + self.access_path_tree_roots + .get_mut_access_path_tree_node(node) + } + + /// Get the reference param index and the access path (list of edge labels) from it to the + /// access path tree node. `None` if node is derived from a reference parameter. + fn get_access_path_from_ref_param( + &self, + qualified_node_id: &QualifiedNodeID, + ) -> PartialVMResult)>> { + let AccessPathTreeRoot::ReferenceParameter { param_index } = qualified_node_id.root else { + return Ok(None); + }; + let access_path_tree = self + .access_path_tree_roots + .get_access_path_tree(&qualified_node_id.root)?; + let path = access_path_tree.get_access_path_from_root(qualified_node_id.node_id)?; + Ok(Some((param_index, path))) + } +} + +impl ReferenceInfo { + /// Check if this reference is poisoned. + /// Invariant violation if it is. + fn poison_check(&self) -> PartialVMResult<()> { + if self.poisoned { + let msg = "Poisoned reference accessed".to_string(); + return ref_check_failure!(msg); + } + Ok(()) + } +} + +impl RefCheckState { + /// Create a new `RefCheckState` with empty stacks. + pub fn new() -> Self { + Self { + shadow_stack: Vec::new(), + frame_stack: Vec::new(), + } + } + + /// Push `num` non-reference values onto the shadow stack. + fn push_non_refs_to_shadow_stack(&mut self, num: usize) { + self.shadow_stack + .extend(std::iter::repeat_n(Value::NonRef, num)); + } + + /// Push the given `ref_id` onto the shadow stack as a reference value. + fn push_ref_to_shadow_stack(&mut self, ref_id: RefID) { + self.shadow_stack.push(Value::Ref(ref_id)); + } + + /// Push the given `value` onto the shadow stack. + fn push_to_shadow_stack(&mut self, value: Value) { + self.shadow_stack.push(value); + } + + /// Pop and get the value on top of the shadow stack. + fn pop_from_shadow_stack(&mut self) -> PartialVMResult { + Ok(safe_unwrap!(self.shadow_stack.pop())) + } + + /// Pop `num` values from the shadow stack. + fn pop_many_from_shadow_stack(&mut self, num: usize) -> PartialVMResult<()> { + self.shadow_stack + .truncate(safe_unwrap!(self.shadow_stack.len().checked_sub(num))); + Ok(()) + } + + /// Get a reference to the latest frame state. + fn get_latest_frame_state(&self) -> PartialVMResult<&FrameRefState> { + Ok(safe_unwrap!(self.frame_stack.last())) + } + + /// Get a mutable reference to the latest frame state. + fn get_mut_latest_frame_state(&mut self) -> PartialVMResult<&mut FrameRefState> { + Ok(safe_unwrap!(self.frame_stack.last_mut())) + } + + /// Is there a function that called the current function? + fn has_caller(&self) -> bool { + self.frame_stack.len() >= 2 + } + + /// Assumes that there is a caller frame, invariant violation if not. + fn get_mut_callers_frame_state(&mut self) -> PartialVMResult<&mut FrameRefState> { + let caller_index = safe_unwrap!(self.frame_stack.len().checked_sub(2)); + Ok(safe_unwrap!(self.frame_stack.get_mut(caller_index))) + } + + /// Check if `ref_id` is poisoned in the latest frame state. + fn poison_check(&self, ref_id: RefID) -> PartialVMResult<()> { + self.get_latest_frame_state()?.poison_check(ref_id) + } + + /// Remove tracking of `ref_id` from the latest frame state. + fn purge_reference(&mut self, ref_id: RefID) -> PartialVMResult<()> { + self.get_mut_latest_frame_state()?.purge_reference(ref_id) + } + + /// Transition for `CopyLoc` instruction. + fn copy_loc(&mut self, index: u8) -> PartialVMResult<()> { + let index = index.into(); + let frame_state_immut = self.get_latest_frame_state()?; + let value = safe_unwrap!(frame_state_immut.locals.get(index)); + match value { + Value::NonRef => { + self.push_non_refs_to_shadow_stack(1); + let node = QualifiedNodeID::local_root(index); + let frame_state_mut = self.get_mut_latest_frame_state()?; + // Poison all mutable references to the location rooted at `index`. + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::SelfOnly, + ReferenceFilter::MutOnly, + )?; + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::StrictDescendants, + ReferenceFilter::MutOnly, + )?; + }, + Value::Ref(ref_id) => { + self.poison_check(*ref_id)?; + let ref_info = frame_state_immut.get_ref_info(ref_id)?; + let access_path_tree_node = ref_info.access_path_tree_node.clone(); + let is_mutable = ref_info.is_mutable; + let frame_state_mut = self.get_mut_latest_frame_state()?; + // Create a new reference to the existing referenced node. + let new_ref_id = frame_state_mut + .make_new_ref_to_existing_node(access_path_tree_node, is_mutable)?; + self.push_ref_to_shadow_stack(new_ref_id); + }, + } + Ok(()) + } + + /// Transition for `MoveLoc` instruction. + fn move_loc(&mut self, index: u8) -> PartialVMResult<()> { + let index = index.into(); + let frame_state = self.get_mut_latest_frame_state()?; + let mut value = Value::NonRef; + // Replace the shadow local at `index` with a non-ref value. + std::mem::swap(safe_unwrap!(frame_state.locals.get_mut(index)), &mut value); + + match value { + Value::NonRef => { + let node = QualifiedNodeID::local_root(index); + let frame_state_mut = self.get_mut_latest_frame_state()?; + // Poison all references to the location rooted at `index`. + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::SelfOnly, + ReferenceFilter::All, + )?; + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::StrictDescendants, + ReferenceFilter::All, + )?; + }, + Value::Ref(_) => { + // Reference is being moved from a local to the stack + // No poison checks here, because we do not consider this a reference access. + // This will allow a poisoned reference to be moved to the stack and popped. + }, + } + + self.push_to_shadow_stack(value); + Ok(()) + } + + /// Transition for `StLoc` instruction. + fn st_loc(&mut self, index: u8) -> PartialVMResult<()> { + let index = index.into(); + let mut value_1 = self.pop_from_shadow_stack()?; + let frame_state = self.get_mut_latest_frame_state()?; + let value_2 = safe_unwrap!(frame_state.locals.get_mut(index)); + + // Store the value from the shadow stack into the local at `index`. + // `value_1` will then have the value that was previously in the local. + std::mem::swap(value_2, &mut value_1); + + match value_1 { + Value::NonRef => { + let node = QualifiedNodeID::local_root(index); + let frame_state_mut = self.get_mut_latest_frame_state()?; + // The value stored at `index` is being overwritten. + // Poison all references to the location rooted at `index`. + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::SelfOnly, + ReferenceFilter::All, + )?; + frame_state_mut.poison_refs_of_node( + &node, + VisitKind::StrictDescendants, + ReferenceFilter::All, + )?; + }, + Value::Ref(ref_id) => { + let frame_state_mut = self.get_mut_latest_frame_state()?; + frame_state_mut.purge_reference(ref_id)?; + // Note: we do not check if the reference overwritten was poisoned. + }, + } + + Ok(()) + } + + /// Pop a reference from the shadow stack, check if it is poisoned, purge it, + /// and push a non-reference value onto the shadow stack. + fn pop_ref_push_non_ref(&mut self) -> PartialVMResult<()> { + let top = self.pop_from_shadow_stack()?; + let Value::Ref(ref_id) = top else { + let msg = "Expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(ref_id)?; + self.purge_reference(ref_id)?; + + self.push_non_refs_to_shadow_stack(1); + + Ok(()) + } + + /// Transition for `WriteRef` instruction. + fn write_ref(&mut self) -> PartialVMResult<()> { + let ref_to_write = self.pop_from_shadow_stack()?; + let _ = self.pop_from_shadow_stack()?; + + let Value::Ref(ref_id) = ref_to_write else { + let msg = "WriteRef expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&ref_id)?; + safe_assert!(ref_info.is_mutable); + let node = ref_info.access_path_tree_node.clone(); + frame_state.destructive_write_via_mut_ref(&node)?; + + frame_state.purge_reference(ref_id)?; + + Ok(()) + } + + /// Transition for `FreezeRef` instruction. + fn freeze_ref(&mut self) -> PartialVMResult<()> { + let ref_to_freeze = self.pop_from_shadow_stack()?; + let Value::Ref(ref_id) = ref_to_freeze else { + let msg = "FreezeRef expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&ref_id)?; + safe_assert!(ref_info.is_mutable); + let node = ref_info.access_path_tree_node.clone(); + // Note: freeze_ref does not poison any references, as it is the same as purging the mut-ref + // and creating a new immutable ref to the same node. + frame_state.purge_reference(ref_id)?; + let new_ref_id = frame_state.make_new_ref_to_existing_node(node, false)?; + self.push_ref_to_shadow_stack(new_ref_id); + + Ok(()) + } + + /// Borrow a local value at the given `index`. + /// The mutability of the reference given by `is_mutable`. + fn borrow_loc(&mut self, index: u8, is_mutable: bool) -> PartialVMResult<()> { + let index = index.into(); + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.ensure_local_root_exists(index); + let node_id = QualifiedNodeID::local_root(index); + let new_ref_id = frame_state.make_new_ref_to_existing_node(node_id, is_mutable)?; + self.push_ref_to_shadow_stack(new_ref_id); + + Ok(()) + } + + /// Derive a child reference with `label` from the parent reference on the top of the shadow stack. + /// The mutability of the reference is given by `MUTABLE`. + /// Transition for family of instructions borrowing fields of structs and variants. + fn borrow_child_with_label( + &mut self, + label: EdgeLabel, + ) -> PartialVMResult<()> { + let ref_to_borrow_from = self.pop_from_shadow_stack()?; + let Value::Ref(parent_ref_id) = ref_to_borrow_from else { + let msg = "Expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + // We perform poison check right away, although it could be delayed until reference is used. + // If we delay, we would need to ensure poisoning is transferred to children. + self.poison_check(parent_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&parent_ref_id)?; + // If we are borrowing a mutable reference, the parent reference must also be mutable. + safe_assert!(!MUTABLE || ref_info.is_mutable); + + let parent_node_id = ref_info.access_path_tree_node.clone(); + let child_node_id = + frame_state.get_or_create_descendant_node(&parent_node_id, slice::from_ref(&label))?; + + frame_state.purge_reference(parent_ref_id)?; + + let new_ref_id = frame_state.make_new_ref_to_existing_node(child_node_id, MUTABLE)?; + self.push_ref_to_shadow_stack(new_ref_id); + + Ok(()) + } + + /// Transition for borrow global family of instructions. + /// We currently abstract over all addresses and only use types. + fn borrow_global(&mut self, type_: Type) -> PartialVMResult<()> { + let _ = self.pop_from_shadow_stack()?; + + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.ensure_global_root_exists(type_.clone()); + + let node_id = QualifiedNodeID::global_root(type_); + // Unlike references to locals (where borrowing itself does not lead to violations, but use of + // poisoned refs does), we perform a stricter check here (similar to bytecode verifier). + if MUTABLE && frame_state.subtree_has_references(&node_id, ReferenceFilter::All)? { + let msg = "Cannot borrow_global_mut while there are existing references".to_string(); + return ref_check_failure!(msg); + } else if !MUTABLE + && frame_state.subtree_has_references(&node_id, ReferenceFilter::MutOnly)? + { + let msg = "Cannot borrow_global while there are mutable references".to_string(); + return ref_check_failure!(msg); + } + + let new_ref_id = frame_state.make_new_ref_to_existing_node(node_id, MUTABLE)?; + self.push_ref_to_shadow_stack(new_ref_id); + + Ok(()) + } + + /// Transition for `MoveFrom` and `MoveFromGeneric` instruction. + fn move_from(&mut self, type_: Type) -> PartialVMResult<()> { + let _ = self.pop_from_shadow_stack()?; + + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.ensure_global_root_exists(type_.clone()); + + let node_id = QualifiedNodeID::global_root(type_); + // Poison all references to the global type's subtree. + frame_state.poison_refs_of_node(&node_id, VisitKind::SelfOnly, ReferenceFilter::All)?; + frame_state.poison_refs_of_node( + &node_id, + VisitKind::StrictDescendants, + ReferenceFilter::All, + )?; + + self.push_non_refs_to_shadow_stack(1); + + Ok(()) + } + + /// Transition for `MoveTo` and `MoveToGeneric` instructions. + fn move_to(&mut self) -> PartialVMResult<()> { + let _ = self.pop_from_shadow_stack()?; + let signer_ref = self.pop_from_shadow_stack()?; + + let Value::Ref(signer_ref_id) = signer_ref else { + let msg = "Expected a reference to a signer on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(signer_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.purge_reference(signer_ref_id)?; + // Note: `MoveTo` only succeeds if global value is not already present, so we do not + // need to poison references to the global type's subtree. + + Ok(()) + } + + /// Transition for `VecLen` instruction. + fn vec_len(&mut self) -> PartialVMResult<()> { + let vec_ref = self.pop_from_shadow_stack()?; + let Value::Ref(vec_ref_id) = vec_ref else { + let msg = "vec_len expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(vec_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.purge_reference(vec_ref_id)?; + + self.push_non_refs_to_shadow_stack(1); + + Ok(()) + } + + /// Transition for vector borrow family of instructions. + fn vec_borrow(&mut self) -> PartialVMResult<()> { + let _ = self.pop_from_shadow_stack()?; + let vec_ref = self.pop_from_shadow_stack()?; + let Value::Ref(parent_ref_id) = vec_ref else { + let msg = "vec_borrow expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(parent_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&parent_ref_id)?; + // If we are borrowing a mutable reference, the parent reference must also be mutable. + safe_assert!(!MUTABLE || ref_info.is_mutable); + + let parent_node_id = ref_info.access_path_tree_node.clone(); + // Note that we abstract over all indices and use `0` to represent the label. + // This is stricter than necessary, but it is cheaper than maintaining a per-index access path tree node. + let abstracted_label = 0; + let child_node_id = frame_state + .get_or_create_descendant_node(&parent_node_id, slice::from_ref(&abstracted_label))?; + + frame_state.purge_reference(parent_ref_id)?; + + let new_ref_id = frame_state.make_new_ref_to_existing_node(child_node_id, MUTABLE)?; + self.push_ref_to_shadow_stack(new_ref_id); + + Ok(()) + } + + /// Transition for `VecPushBack` instruction. + fn vec_push_back(&mut self) -> PartialVMResult<()> { + let _ = self.pop_from_shadow_stack()?; + let vec_ref = self.pop_from_shadow_stack()?; + let Value::Ref(vec_ref_id) = vec_ref else { + let msg = "vec_push_back expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(vec_ref_id)?; + + // Note: we are not checking if the reference is mutable here, as such type checks + // are not part of reference checking. + let frame_state = self.get_mut_latest_frame_state()?; + frame_state.purge_reference(vec_ref_id)?; + + // Note: we do not consider this to be a destructive update to the vector, + // and references to other elements in the vector would still be un-poisoned. + Ok(()) + } + + /// Transition for `VecPopBack` instruction. + fn vec_pop_back(&mut self) -> PartialVMResult<()> { + let vec_ref = self.pop_from_shadow_stack()?; + let Value::Ref(vec_ref_id) = vec_ref else { + let msg = "vec_pop_back expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(vec_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&vec_ref_id)?; + safe_assert!(ref_info.is_mutable); + + let node = ref_info.access_path_tree_node.clone(); + frame_state.destructive_write_via_mut_ref(&node)?; + + frame_state.purge_reference(vec_ref_id)?; + + self.push_non_refs_to_shadow_stack(1); + + Ok(()) + } + + /// Transition for `VecSwap` instruction. + fn vec_swap(&mut self) -> PartialVMResult<()> { + self.pop_many_from_shadow_stack(2)?; + let vec_ref = self.pop_from_shadow_stack()?; + let Value::Ref(vec_ref_id) = vec_ref else { + let msg = "vec_swap expected a reference on the stack".to_string(); + return ref_check_failure!(msg); + }; + self.poison_check(vec_ref_id)?; + + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&vec_ref_id)?; + safe_assert!(ref_info.is_mutable); + + let node = ref_info.access_path_tree_node.clone(); + frame_state.destructive_write_via_mut_ref(&node)?; + + frame_state.purge_reference(vec_ref_id)?; + + Ok(()) + } + + /// Transition for a function call (`Call`, `CallGeneric`, `CallClosure`). + fn core_call( + &mut self, + num_params: usize, + num_locals: usize, + mask: ClosureMask, + ) -> PartialVMResult<()> { + // Keep track of all reference argument's IDs. + let mut ref_arg_ids = Vec::new(); + // Keep track of mutable reference param indexes. + let mut mut_ref_indexes = Vec::new(); + // Keep track of immutable reference param indexes. + let mut immut_ref_indexes = Vec::new(); + // Map from parameter index to the access path tree node of a reference parameter. + let mut ref_param_map = UnorderedMap::with_hasher(FxBuildHasher::default()); + for i in (0..num_params).rev() { + let is_captured = mask.is_captured(i); + if !is_captured { + let Value::Ref(ref_id) = self.pop_from_shadow_stack()? else { + continue; + }; + + // We have a reference argument to deal with. + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&ref_id)?; + ref_info.poison_check()?; + let access_path_tree_node = ref_info.access_path_tree_node.clone(); + // Make sure that there are no overlaps with a mutable reference. + if ref_info.is_mutable { + frame_state.lock_node_subtree(&access_path_tree_node, Lock::Exclusive)?; + // Having a mutable reference argument is the same as performing a destructive write. + frame_state.destructive_write_via_mut_ref(&access_path_tree_node)?; + mut_ref_indexes.push(i); + } else { + frame_state.lock_node_subtree(&access_path_tree_node, Lock::Shared)?; + immut_ref_indexes.push(i); + } + ref_arg_ids.push(ref_id); + ref_param_map.insert(i, access_path_tree_node); + } + } + for ref_id in ref_arg_ids { + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&ref_id)?; + let access_path_tree_node = ref_info.access_path_tree_node.clone(); + // Release locks so that they don't interfere with the next call. + frame_state.release_lock_node_subtree(&access_path_tree_node)?; + frame_state.purge_reference(ref_id)?; + } + + self.push_new_frame( + num_locals, + mut_ref_indexes, + immut_ref_indexes, + ref_param_map, + )?; + + Ok(()) + } + + /// Push a new frame onto the frame stack. + /// `mut_ref_indexes` and `immut_ref_indexes` are the indexes of mutable and immutable + /// reference parameters, respectively. + /// `ref_param_map` maps parameter indexes to the access path tree nodes of reference parameters. + fn push_new_frame( + &mut self, + num_locals: usize, + mut_ref_indexes: Vec, + immut_ref_indexes: Vec, + ref_param_map: UnorderedMap, + ) -> PartialVMResult<()> { + let frame = FrameRefState::new( + num_locals, + mut_ref_indexes, + immut_ref_indexes, + ref_param_map, + )?; + self.frame_stack.push(frame); + Ok(()) + } + + /// Check that any returned references must be derived from reference parameters. + /// Returned references must also be exclusive (no overlap with any mut refs). + /// Use the access path of returned references to transform them to the caller's frame. + /// Current frame will be popped from the stack. + fn return_(&mut self, num_return_values: usize) -> PartialVMResult<()> { + if !self + .shadow_stack + .iter() + .rev() + .take(num_return_values) + .all(|v| matches!(v, Value::NonRef)) + { + // There is at least one reference value being returned. + // We perform some checks and transform the references to the caller's frame. + let has_caller = self.has_caller(); + let mut transformed_values = Vec::new(); + let stack_values = self + .shadow_stack + .iter() + .rev() + .take(num_return_values) + .cloned() + .collect::>(); + for value in stack_values { + if let Value::Ref(ref_id) = value { + let frame_state = self.get_mut_latest_frame_state()?; + let ref_info = frame_state.get_ref_info(&ref_id)?; + let is_mutable = ref_info.is_mutable; + ref_info.poison_check()?; + + let access_path_tree_node = ref_info.access_path_tree_node.clone(); + // Check if each reference being returned is derived from a reference parameter. + let Some((param_index, access_path)) = + frame_state.get_access_path_from_ref_param(&access_path_tree_node)? + else { + let msg = + "Returning a reference that is not derived from a reference parameter" + .to_string(); + return ref_check_failure!(msg); + }; + // Check that mutable references are returned "exclusively". + if is_mutable { + frame_state.lock_node_subtree(&access_path_tree_node, Lock::Exclusive)?; + } else { + frame_state.lock_node_subtree(&access_path_tree_node, Lock::Shared)?; + } + // This frame will be thrown away, so no need to unlock the nodes. + // Compute the transformation of the reference to one on the caller's frame, + // if there is a caller. + if !has_caller { + continue; + } + let caller_access_path_tree_node = + safe_unwrap!(frame_state.caller_ref_param_map.get(¶m_index)).clone(); + let callers_frame = self.get_mut_callers_frame_state()?; + let transformed_node = callers_frame.get_or_create_descendant_node( + &caller_access_path_tree_node, + &access_path, + )?; + let transformed_ref_id = callers_frame + .make_new_ref_to_existing_node(transformed_node, is_mutable)?; + transformed_values.push(Some(transformed_ref_id)); + } else if has_caller { + // The returned value is not a reference and there is a caller. + transformed_values.push(None); + } + } + if has_caller { + // Transform the shadow stack reference values to the caller's frame. + for (value, transformed_value) in self + .shadow_stack + .iter_mut() + .rev() + .take(num_return_values) + .zip(transformed_values.iter()) + { + if let Some(transformed_ref) = transformed_value { + debug_assert!(matches!(value, Value::Ref(_))); + *value = Value::Ref(*transformed_ref); + } + } + } + } + + self.frame_stack.pop(); + Ok(()) + } +} diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index a43c604a582..1c5d2e069ff 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -1,21 +1,27 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{frame::Frame, frame_type_cache::FrameTypeCache, interpreter::Stack, LoadedFunction}; -use move_binary_format::{errors::*, file_format::Bytecode}; +use crate::{ + frame::Frame, frame_type_cache::FrameTypeCache, interpreter::Stack, + reentrancy_checker::CallType, Function, LoadedFunction, +}; +use move_binary_format::errors::*; use move_core_types::{ ability::{Ability, AbilitySet}, function::ClosureMask, - vm_status::StatusCode, + vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, +}; +use move_vm_types::{ + instr::Instruction, + loaded_data::runtime_types::{Type, TypeBuilder}, }; -use move_vm_types::loaded_data::runtime_types::{Type, TypeBuilder}; pub(crate) trait RuntimeTypeCheck { /// Paranoid type checks to perform before instruction execution. fn pre_execution_type_stack_transition( frame: &Frame, operand_stack: &mut Stack, - instruction: &Bytecode, + instruction: &Instruction, ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()>; @@ -23,17 +29,80 @@ pub(crate) trait RuntimeTypeCheck { fn post_execution_type_stack_transition( frame: &Frame, operand_stack: &mut Stack, - instruction: &Bytecode, + instruction: &Instruction, ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()>; - /// Paranoid check that operand and type stacks have the same size - fn check_operand_stack_balance(operand_stack: &Stack) -> PartialVMResult<()>; - /// For any other checks are performed externally - fn should_perform_checks() -> bool; + fn should_perform_checks(for_fun: &Function) -> bool; + + /// Performs a runtime check of the caller is allowed to call the callee for any type of call, + /// including native dynamic dispatch or calling a closure. + #[cfg_attr(feature = "force-inline", inline(always))] + fn check_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + call_type: CallType, + ) -> PartialVMResult<()> { + match call_type { + CallType::Regular => { + // We only need to check cross-contract calls. + if caller.module_id() == callee.module_id() { + return Ok(()); + } + Self::check_cross_module_regular_call_visibility(caller, callee) + }, + CallType::ClosureDynamicDispatch => { + // In difference to regular calls, we skip visibility check. It is possible to call + // a private function of another module via a closure. + Ok(()) + }, + CallType::NativeDynamicDispatch => { + // Dynamic dispatch may fail at runtime and this is ok. Hence, these errors are not + // invariant violations as they cannot be checked at compile- or load-time. + // + // Note: native dispatch cannot call into the same module, otherwise the reentrancy + // check is broken. For more details, see AIP-73: + // https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-73.md + if callee.is_friend_or_private() || callee.module_id() == caller.module_id() { + return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) + .with_message( + "Invoking private or friend function during dispatch".to_string(), + )); + } + + if callee.is_native() { + return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) + .with_message("Invoking native function during dispatch".to_string())); + } + Ok(()) + }, + } + } + + /// Checks if the caller can pack a function as a closure. + fn check_pack_closure_visibility( + caller: &LoadedFunction, + function: &LoadedFunction, + ) -> PartialVMResult<()> { + if caller.module_id() == function.module_id() { + return Ok(()); + } + // Same visibility rules as for regular cross-contract calls should apply. + Self::check_cross_module_regular_call_visibility(caller, function) + } + + /// Performs a runtime check of the caller is allowed to call a cross-module callee. Applies + /// only on regular static calls (no dynamic dispatch!), with caller and callee being coming + /// from different modules. + fn check_cross_module_regular_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + ) -> PartialVMResult<()>; } +// note(inline): improves perf a little bit, but increases `post_execution_type_stack_transition` by 20% +#[cfg_attr(feature = "force-inline", inline(always))] fn verify_pack<'a>( operand_stack: &mut Stack, field_count: usize, @@ -83,7 +152,7 @@ pub fn verify_pack_closure( AbilitySet::PRIVATE_FUNCTIONS }; // Verify that captured arguments are assignable against types in the function - // signature. + // signature, and that they are no references. let expected_capture_tys = mask.extract(func.param_tys(), true); let given_capture_tys = operand_stack.popn_tys(expected_capture_tys.len())?; @@ -91,6 +160,7 @@ pub fn verify_pack_closure( .into_iter() .zip(given_capture_tys.into_iter()) { + expected.paranoid_check_is_no_ref("Captured argument type")?; with_instantiation(ty_builder, func, expected, |expected| { // Intersect the captured type with the accumulated abilities abilities = abilities.intersect(given.abilities()?); @@ -145,52 +215,61 @@ fn with_owned_instantiation( pub(crate) struct NoRuntimeTypeCheck; pub(crate) struct FullRuntimeTypeCheck; +pub(crate) struct UntrustedOnlyRuntimeTypeCheck; impl RuntimeTypeCheck for NoRuntimeTypeCheck { + #[cfg_attr(feature = "force-inline", inline(always))] fn pre_execution_type_stack_transition( _frame: &Frame, _operand_stack: &mut Stack, - _instruction: &Bytecode, + _instruction: &Instruction, _ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()> { Ok(()) } + #[cfg_attr(feature = "force-inline", inline(always))] fn post_execution_type_stack_transition( _frame: &Frame, _operand_stack: &mut Stack, - _instruction: &Bytecode, + _instruction: &Instruction, _ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()> { Ok(()) } - fn check_operand_stack_balance(_operand_stack: &Stack) -> PartialVMResult<()> { - Ok(()) + #[cfg_attr(feature = "force-inline", inline(always))] + fn should_perform_checks(_for_fun: &Function) -> bool { + false } - #[inline(always)] - fn should_perform_checks() -> bool { - false + #[cfg_attr(feature = "force-inline", inline(always))] + fn check_cross_module_regular_call_visibility( + _caller: &LoadedFunction, + _callee: &LoadedFunction, + ) -> PartialVMResult<()> { + Ok(()) } } impl RuntimeTypeCheck for FullRuntimeTypeCheck { /// Note that most of the checks should happen after instruction execution, because gas charging will happen during /// instruction execution and we want to avoid running code without charging proper gas as much as possible. + // note(inline): it should not be inlined, function calling overhead + // is not big enough to justify the increase in function size fn pre_execution_type_stack_transition( frame: &Frame, operand_stack: &mut Stack, - instruction: &Bytecode, + instruction: &Instruction, ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()> { match instruction { // Call instruction will be checked at execute_main. - Bytecode::Call(_) | Bytecode::CallGeneric(_) => (), - Bytecode::BrFalse(_) | Bytecode::BrTrue(_) => { + Instruction::Call(_) | Instruction::CallGeneric(_) => (), + Instruction::BrFalse(_) | Instruction::BrTrue(_) => { operand_stack.pop_ty()?; }, - Bytecode::CallClosure(sig_idx) => { + Instruction::CallClosure(sig_idx) => { // For closure, we need to check the type of the closure on // top of the stack. The argument types are checked when the frame // is constructed in the interpreter, using the same code as for regular @@ -199,15 +278,15 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let given_ty = operand_stack.pop_ty()?; given_ty.paranoid_check_assignable(expected_ty)?; }, - Bytecode::Branch(_) => (), - Bytecode::Ret => { + Instruction::Branch(_) => (), + Instruction::Ret => { frame.check_local_tys_have_drop_ability()?; }, - Bytecode::Abort => { + Instruction::Abort => { operand_stack.pop_ty()?; }, // StLoc needs to check before execution as we need to check the drop ability of values. - Bytecode::StLoc(idx) => { + Instruction::StLoc(idx) => { let expected_ty = frame.local_ty_at(*idx as usize); let val_ty = operand_stack.pop_ty()?; // For store, use assignability @@ -217,89 +296,102 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { } }, // We will check the rest of the instructions after execution phase. - Bytecode::Pop - | Bytecode::LdU8(_) - | Bytecode::LdU16(_) - | Bytecode::LdU32(_) - | Bytecode::LdU64(_) - | Bytecode::LdU128(_) - | Bytecode::LdU256(_) - | Bytecode::LdTrue - | Bytecode::LdFalse - | Bytecode::LdConst(_) - | Bytecode::CopyLoc(_) - | Bytecode::MoveLoc(_) - | Bytecode::MutBorrowLoc(_) - | Bytecode::ImmBorrowLoc(_) - | Bytecode::ImmBorrowField(_) - | Bytecode::MutBorrowField(_) - | Bytecode::ImmBorrowFieldGeneric(_) - | Bytecode::MutBorrowFieldGeneric(_) - | Bytecode::PackClosure(..) - | Bytecode::PackClosureGeneric(..) - | Bytecode::Pack(_) - | Bytecode::PackGeneric(_) - | Bytecode::Unpack(_) - | Bytecode::UnpackGeneric(_) - | Bytecode::ReadRef - | Bytecode::WriteRef - | Bytecode::CastU8 - | Bytecode::CastU16 - | Bytecode::CastU32 - | Bytecode::CastU64 - | Bytecode::CastU128 - | Bytecode::CastU256 - | Bytecode::Add - | Bytecode::Sub - | Bytecode::Mul - | Bytecode::Mod - | Bytecode::Div - | Bytecode::BitOr - | Bytecode::BitAnd - | Bytecode::Xor - | Bytecode::Or - | Bytecode::And - | Bytecode::Shl - | Bytecode::Shr - | Bytecode::Lt - | Bytecode::Le - | Bytecode::Gt - | Bytecode::Ge - | Bytecode::Eq - | Bytecode::Neq - | Bytecode::MutBorrowGlobal(_) - | Bytecode::ImmBorrowGlobal(_) - | Bytecode::MutBorrowGlobalGeneric(_) - | Bytecode::ImmBorrowGlobalGeneric(_) - | Bytecode::Exists(_) - | Bytecode::ExistsGeneric(_) - | Bytecode::MoveTo(_) - | Bytecode::MoveToGeneric(_) - | Bytecode::MoveFrom(_) - | Bytecode::MoveFromGeneric(_) - | Bytecode::FreezeRef - | Bytecode::Nop - | Bytecode::Not - | Bytecode::VecPack(_, _) - | Bytecode::VecLen(_) - | Bytecode::VecImmBorrow(_) - | Bytecode::VecMutBorrow(_) - | Bytecode::VecPushBack(_) - | Bytecode::VecPopBack(_) - | Bytecode::VecUnpack(_, _) - | Bytecode::VecSwap(_) => (), + Instruction::Pop + | Instruction::LdU8(_) + | Instruction::LdU16(_) + | Instruction::LdU32(_) + | Instruction::LdU64(_) + | Instruction::LdU128(_) + | Instruction::LdU256(_) + | Instruction::LdI8(_) + | Instruction::LdI16(_) + | Instruction::LdI32(_) + | Instruction::LdI64(_) + | Instruction::LdI128(_) + | Instruction::LdI256(_) + | Instruction::LdTrue + | Instruction::LdFalse + | Instruction::LdConst(_) + | Instruction::CopyLoc(_) + | Instruction::MoveLoc(_) + | Instruction::MutBorrowLoc(_) + | Instruction::ImmBorrowLoc(_) + | Instruction::ImmBorrowField(_) + | Instruction::MutBorrowField(_) + | Instruction::ImmBorrowFieldGeneric(_) + | Instruction::MutBorrowFieldGeneric(_) + | Instruction::PackClosure(..) + | Instruction::PackClosureGeneric(..) + | Instruction::Pack(_) + | Instruction::PackGeneric(_) + | Instruction::Unpack(_) + | Instruction::UnpackGeneric(_) + | Instruction::ReadRef + | Instruction::WriteRef + | Instruction::CastU8 + | Instruction::CastU16 + | Instruction::CastU32 + | Instruction::CastU64 + | Instruction::CastU128 + | Instruction::CastU256 + | Instruction::CastI8 + | Instruction::CastI16 + | Instruction::CastI32 + | Instruction::CastI64 + | Instruction::CastI128 + | Instruction::CastI256 + | Instruction::Add + | Instruction::Sub + | Instruction::Mul + | Instruction::Mod + | Instruction::Div + | Instruction::Negate + | Instruction::BitOr + | Instruction::BitAnd + | Instruction::Xor + | Instruction::Or + | Instruction::And + | Instruction::Shl + | Instruction::Shr + | Instruction::Lt + | Instruction::Le + | Instruction::Gt + | Instruction::Ge + | Instruction::Eq + | Instruction::Neq + | Instruction::MutBorrowGlobal(_) + | Instruction::ImmBorrowGlobal(_) + | Instruction::MutBorrowGlobalGeneric(_) + | Instruction::ImmBorrowGlobalGeneric(_) + | Instruction::Exists(_) + | Instruction::ExistsGeneric(_) + | Instruction::MoveTo(_) + | Instruction::MoveToGeneric(_) + | Instruction::MoveFrom(_) + | Instruction::MoveFromGeneric(_) + | Instruction::FreezeRef + | Instruction::Nop + | Instruction::Not + | Instruction::VecPack(_, _) + | Instruction::VecLen(_) + | Instruction::VecImmBorrow(_) + | Instruction::VecMutBorrow(_) + | Instruction::VecPushBack(_) + | Instruction::VecPopBack(_) + | Instruction::VecUnpack(_, _) + | Instruction::VecSwap(_) => (), // Since bytecode version 7 - Bytecode::PackVariant(_) - | Bytecode::PackVariantGeneric(_) - | Bytecode::UnpackVariant(_) - | Bytecode::UnpackVariantGeneric(_) - | Bytecode::TestVariant(_) - | Bytecode::TestVariantGeneric(_) - | Bytecode::MutBorrowVariantField(_) - | Bytecode::MutBorrowVariantFieldGeneric(_) - | Bytecode::ImmBorrowVariantField(_) - | Bytecode::ImmBorrowVariantFieldGeneric(_) => (), + Instruction::PackVariant(_) + | Instruction::PackVariantGeneric(_) + | Instruction::UnpackVariant(_) + | Instruction::UnpackVariantGeneric(_) + | Instruction::TestVariant(_) + | Instruction::TestVariantGeneric(_) + | Instruction::MutBorrowVariantField(_) + | Instruction::MutBorrowVariantFieldGeneric(_) + | Instruction::ImmBorrowVariantField(_) + | Instruction::ImmBorrowVariantFieldGeneric(_) => (), }; Ok(()) } @@ -309,85 +401,110 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { /// This function and `pre_execution_type_stack_transition` should /// constitute the full type stack transition for the paranoid /// mode. + // note(inline): it should not be inlined, function calling overhead + // is not big enough to justify the increase in function size fn post_execution_type_stack_transition( frame: &Frame, operand_stack: &mut Stack, - instruction: &Bytecode, + instruction: &Instruction, ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()> { let ty_builder = frame.ty_builder(); - match instruction { - Bytecode::BrTrue(_) | Bytecode::BrFalse(_) => (), - Bytecode::Branch(_) - | Bytecode::Ret - | Bytecode::Call(_) - | Bytecode::CallGeneric(_) - | Bytecode::CallClosure(_) - | Bytecode::Abort => { + Instruction::BrTrue(_) | Instruction::BrFalse(_) => (), + Instruction::Branch(_) + | Instruction::Ret + | Instruction::Call(_) + | Instruction::CallGeneric(_) + | Instruction::CallClosure(_) + | Instruction::Abort => { // Invariants hold because all of the instructions // above will force VM to break from the interpreter // loop and thus not hit this code path. unreachable!("control flow instruction encountered during type check") }, - Bytecode::Pop => { + Instruction::Pop => { let ty = operand_stack.pop_ty()?; ty.paranoid_check_has_ability(Ability::Drop)?; }, - Bytecode::LdU8(_) => { + Instruction::LdU8(_) => { let u8_ty = ty_builder.create_u8_ty(); operand_stack.push_ty(u8_ty)? }, - Bytecode::LdU16(_) => { + Instruction::LdU16(_) => { let u16_ty = ty_builder.create_u16_ty(); operand_stack.push_ty(u16_ty)? }, - Bytecode::LdU32(_) => { + Instruction::LdU32(_) => { let u32_ty = ty_builder.create_u32_ty(); operand_stack.push_ty(u32_ty)? }, - Bytecode::LdU64(_) => { + Instruction::LdU64(_) => { let u64_ty = ty_builder.create_u64_ty(); operand_stack.push_ty(u64_ty)? }, - Bytecode::LdU128(_) => { + Instruction::LdU128(_) => { let u128_ty = ty_builder.create_u128_ty(); operand_stack.push_ty(u128_ty)? }, - Bytecode::LdU256(_) => { + Instruction::LdU256(_) => { let u256_ty = ty_builder.create_u256_ty(); operand_stack.push_ty(u256_ty)? }, - Bytecode::LdTrue | Bytecode::LdFalse => { + Instruction::LdI8(_) => { + let i8_ty = ty_builder.create_i8_ty(); + operand_stack.push_ty(i8_ty)? + }, + Instruction::LdI16(_) => { + let i16_ty = ty_builder.create_i16_ty(); + operand_stack.push_ty(i16_ty)? + }, + Instruction::LdI32(_) => { + let i32_ty = ty_builder.create_i32_ty(); + operand_stack.push_ty(i32_ty)? + }, + Instruction::LdI64(_) => { + let i64_ty = ty_builder.create_i64_ty(); + operand_stack.push_ty(i64_ty)? + }, + Instruction::LdI128(_) => { + let i128_ty = ty_builder.create_i128_ty(); + operand_stack.push_ty(i128_ty)? + }, + Instruction::LdI256(_) => { + let i256_ty = ty_builder.create_i256_ty(); + operand_stack.push_ty(i256_ty)? + }, + Instruction::LdTrue | Instruction::LdFalse => { let bool_ty = ty_builder.create_bool_ty(); operand_stack.push_ty(bool_ty)? }, - Bytecode::LdConst(i) => { + Instruction::LdConst(i) => { let constant = frame.constant_at(*i); let ty = ty_builder.create_constant_ty(&constant.type_)?; operand_stack.push_ty(ty)?; }, - Bytecode::CopyLoc(idx) => { + Instruction::CopyLoc(idx) => { let ty = frame.local_ty_at(*idx as usize).clone(); ty.paranoid_check_has_ability(Ability::Copy)?; operand_stack.push_ty(ty)?; }, - Bytecode::MoveLoc(idx) => { + Instruction::MoveLoc(idx) => { let ty = frame.local_ty_at(*idx as usize).clone(); operand_stack.push_ty(ty)?; }, - Bytecode::StLoc(_) => (), - Bytecode::MutBorrowLoc(idx) => { + Instruction::StLoc(_) => (), + Instruction::MutBorrowLoc(idx) => { let ty = frame.local_ty_at(*idx as usize); let mut_ref_ty = ty_builder.create_ref_ty(ty, true)?; operand_stack.push_ty(mut_ref_ty)?; }, - Bytecode::ImmBorrowLoc(idx) => { + Instruction::ImmBorrowLoc(idx) => { let ty = frame.local_ty_at(*idx as usize); let ref_ty = ty_builder.create_ref_ty(ty, false)?; operand_stack.push_ty(ref_ty)?; }, - Bytecode::ImmBorrowField(fh_idx) => { + Instruction::ImmBorrowField(fh_idx) => { let ty = operand_stack.pop_ty()?; let expected_ty = frame.field_handle_to_struct(*fh_idx); ty.paranoid_check_ref_eq(&expected_ty, false)?; @@ -396,7 +513,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_ref_ty = ty_builder.create_ref_ty(field_ty, false)?; operand_stack.push_ty(field_ref_ty)?; }, - Bytecode::MutBorrowField(fh_idx) => { + Instruction::MutBorrowField(fh_idx) => { let ref_ty = operand_stack.pop_ty()?; let expected_inner_ty = frame.field_handle_to_struct(*fh_idx); ref_ty.paranoid_check_ref_eq(&expected_inner_ty, true)?; @@ -405,7 +522,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_mut_ref_ty = ty_builder.create_ref_ty(field_ty, true)?; operand_stack.push_ty(field_mut_ref_ty)?; }, - Bytecode::ImmBorrowFieldGeneric(idx) => { + Instruction::ImmBorrowFieldGeneric(idx) => { let struct_ty = operand_stack.pop_ty()?; let ((field_ty, _), (expected_struct_ty, _)) = ty_cache.get_field_type_and_struct_type(*idx, frame)?; @@ -414,7 +531,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_ref_ty = ty_builder.create_ref_ty(field_ty, false)?; operand_stack.push_ty(field_ref_ty)?; }, - Bytecode::MutBorrowFieldGeneric(idx) => { + Instruction::MutBorrowFieldGeneric(idx) => { let struct_ty = operand_stack.pop_ty()?; let ((field_ty, _), (expected_struct_ty, _)) = ty_cache.get_field_type_and_struct_type(*idx, frame)?; @@ -423,8 +540,9 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_mut_ref_ty = ty_builder.create_ref_ty(field_ty, true)?; operand_stack.push_ty(field_mut_ref_ty)?; }, - Bytecode::ImmBorrowVariantField(fh_idx) | Bytecode::MutBorrowVariantField(fh_idx) => { - let is_mut = matches!(instruction, Bytecode::MutBorrowVariantField(..)); + Instruction::ImmBorrowVariantField(fh_idx) + | Instruction::MutBorrowVariantField(fh_idx) => { + let is_mut = matches!(instruction, Instruction::MutBorrowVariantField(..)); let field_info = frame.variant_field_info_at(*fh_idx); let ty = operand_stack.pop_ty()?; let expected_ty = frame.create_struct_ty(&field_info.definition_struct_type); @@ -433,9 +551,9 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_ref_ty = ty_builder.create_ref_ty(field_ty, is_mut)?; operand_stack.push_ty(field_ref_ty)?; }, - Bytecode::ImmBorrowVariantFieldGeneric(idx) - | Bytecode::MutBorrowVariantFieldGeneric(idx) => { - let is_mut = matches!(instruction, Bytecode::MutBorrowVariantFieldGeneric(..)); + Instruction::ImmBorrowVariantFieldGeneric(idx) + | Instruction::MutBorrowVariantFieldGeneric(idx) => { + let is_mut = matches!(instruction, Instruction::MutBorrowVariantFieldGeneric(..)); let struct_ty = operand_stack.pop_ty()?; let ((field_ty, _), (expected_struct_ty, _)) = ty_cache.get_variant_field_type_and_struct_type(*idx, frame)?; @@ -443,18 +561,18 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let field_ref_ty = ty_builder.create_ref_ty(field_ty, is_mut)?; operand_stack.push_ty(field_ref_ty)?; }, - Bytecode::PackClosure(..) | Bytecode::PackClosureGeneric(..) => { + Instruction::PackClosure(..) | Instruction::PackClosureGeneric(..) => { // Skip: runtime checks are implemented in interpreter loop! }, - Bytecode::Pack(idx) => { + Instruction::Pack(idx) => { let field_count = frame.field_count(*idx); let args_ty = frame.get_struct(*idx); let field_tys = args_ty.fields(None)?.iter().map(|(_, ty)| ty); let output_ty = frame.get_struct_ty(*idx); verify_pack(operand_stack, field_count.into(), field_tys, output_ty)?; }, - Bytecode::PackGeneric(idx) => { + Instruction::PackGeneric(idx) => { let field_count = frame.field_instantiation_count(*idx); let output_ty = ty_cache.get_struct_type(*idx, frame)?.0.clone(); let args_ty = ty_cache.get_struct_fields_types(*idx, frame)?; @@ -477,7 +595,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { output_ty, )?; }, - Bytecode::Unpack(idx) => { + Instruction::Unpack(idx) => { let struct_ty = operand_stack.pop_ty()?; struct_ty.paranoid_check_eq(&frame.get_struct_ty(*idx))?; let struct_decl = frame.get_struct(*idx); @@ -485,7 +603,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(ty.clone())?; } }, - Bytecode::UnpackGeneric(idx) => { + Instruction::UnpackGeneric(idx) => { let struct_ty = operand_stack.pop_ty()?; struct_ty.paranoid_check_eq(ty_cache.get_struct_type(*idx, frame)?.0)?; @@ -495,7 +613,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(ty.clone())?; } }, - Bytecode::PackVariant(idx) => { + Instruction::PackVariant(idx) => { let info = frame.get_struct_variant_at(*idx); let field_tys = info .definition_struct_type @@ -505,7 +623,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let output_ty = frame.create_struct_ty(&info.definition_struct_type); verify_pack(operand_stack, info.field_count.into(), field_tys, output_ty)?; }, - Bytecode::PackVariantGeneric(idx) => { + Instruction::PackVariantGeneric(idx) => { let info = frame.get_struct_variant_instantiation_at(*idx); let output_ty = ty_cache.get_struct_variant_type(*idx, frame)?.0.clone(); let args_ty = ty_cache.get_struct_variant_fields_types(*idx, frame)?; @@ -516,7 +634,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { output_ty, )?; }, - Bytecode::UnpackVariant(idx) => { + Instruction::UnpackVariant(idx) => { let info = frame.get_struct_variant_at(*idx); let expected_struct_ty = frame.create_struct_ty(&info.definition_struct_type); let actual_struct_ty = operand_stack.pop_ty()?; @@ -529,7 +647,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(ty.clone())?; } }, - Bytecode::UnpackVariantGeneric(idx) => { + Instruction::UnpackVariantGeneric(idx) => { let expected_struct_type = ty_cache.get_struct_variant_type(*idx, frame)?.0; let actual_struct_type = operand_stack.pop_ty()?; actual_struct_type.paranoid_check_eq(expected_struct_type)?; @@ -538,82 +656,116 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(ty.clone())?; } }, - Bytecode::TestVariant(idx) => { + Instruction::TestVariant(idx) => { let info = frame.get_struct_variant_at(*idx); let expected_struct_ty = frame.create_struct_ty(&info.definition_struct_type); let actual_struct_ty = operand_stack.pop_ty()?; actual_struct_ty.paranoid_check_ref_eq(&expected_struct_ty, false)?; operand_stack.push_ty(ty_builder.create_bool_ty())?; }, - Bytecode::TestVariantGeneric(idx) => { + Instruction::TestVariantGeneric(idx) => { let expected_struct_ty = ty_cache.get_struct_variant_type(*idx, frame)?.0; let actual_struct_ty = operand_stack.pop_ty()?; actual_struct_ty.paranoid_check_ref_eq(expected_struct_ty, false)?; operand_stack.push_ty(ty_builder.create_bool_ty())?; }, - Bytecode::ReadRef => { + Instruction::ReadRef => { let ref_ty = operand_stack.pop_ty()?; let inner_ty = ref_ty.paranoid_read_ref()?; operand_stack.push_ty(inner_ty)?; }, - Bytecode::WriteRef => { + Instruction::WriteRef => { let mut_ref_ty = operand_stack.pop_ty()?; let val_ty = operand_stack.pop_ty()?; mut_ref_ty.paranoid_write_ref(&val_ty)?; }, - Bytecode::CastU8 => { + Instruction::CastU8 => { operand_stack.pop_ty()?; let u8_ty = ty_builder.create_u8_ty(); operand_stack.push_ty(u8_ty)?; }, - Bytecode::CastU16 => { + Instruction::CastU16 => { operand_stack.pop_ty()?; let u16_ty = ty_builder.create_u16_ty(); operand_stack.push_ty(u16_ty)?; }, - Bytecode::CastU32 => { + Instruction::CastU32 => { operand_stack.pop_ty()?; let u32_ty = ty_builder.create_u32_ty(); operand_stack.push_ty(u32_ty)?; }, - Bytecode::CastU64 => { + Instruction::CastU64 => { operand_stack.pop_ty()?; let u64_ty = ty_builder.create_u64_ty(); operand_stack.push_ty(u64_ty)?; }, - Bytecode::CastU128 => { + Instruction::CastU128 => { operand_stack.pop_ty()?; let u128_ty = ty_builder.create_u128_ty(); operand_stack.push_ty(u128_ty)?; }, - Bytecode::CastU256 => { + Instruction::CastU256 => { operand_stack.pop_ty()?; let u256_ty = ty_builder.create_u256_ty(); operand_stack.push_ty(u256_ty)?; }, - Bytecode::Add - | Bytecode::Sub - | Bytecode::Mul - | Bytecode::Mod - | Bytecode::Div - | Bytecode::BitOr - | Bytecode::BitAnd - | Bytecode::Xor - | Bytecode::Or - | Bytecode::And => { + Instruction::CastI8 => { + operand_stack.pop_ty()?; + let i8_ty = ty_builder.create_i8_ty(); + operand_stack.push_ty(i8_ty)?; + }, + Instruction::CastI16 => { + operand_stack.pop_ty()?; + let i16_ty = ty_builder.create_i16_ty(); + operand_stack.push_ty(i16_ty)?; + }, + Instruction::CastI32 => { + operand_stack.pop_ty()?; + let i32_ty = ty_builder.create_i32_ty(); + operand_stack.push_ty(i32_ty)?; + }, + Instruction::CastI64 => { + operand_stack.pop_ty()?; + let i64_ty = ty_builder.create_i64_ty(); + operand_stack.push_ty(i64_ty)?; + }, + Instruction::CastI128 => { + operand_stack.pop_ty()?; + let i128_ty = ty_builder.create_i128_ty(); + operand_stack.push_ty(i128_ty)?; + }, + Instruction::CastI256 => { + operand_stack.pop_ty()?; + let i256_ty = ty_builder.create_i256_ty(); + operand_stack.push_ty(i256_ty)?; + }, + Instruction::Add + | Instruction::Sub + | Instruction::Mul + | Instruction::Mod + | Instruction::Div + | Instruction::BitOr + | Instruction::BitAnd + | Instruction::Xor + | Instruction::Or + | Instruction::And => { let rhs_ty = operand_stack.pop_ty()?; rhs_ty.paranoid_check_eq(operand_stack.top_ty()?)?; // NO-OP, same as the two lines below when the types are indeed the same: // let lhs_ty = operand_stack.pop_ty()?; // operand_stack.push_ty(rhs_ty)?; }, - Bytecode::Shl | Bytecode::Shr => { + Instruction::Negate => { + operand_stack.top_ty()?.paranoid_check_is_sint_ty()?; + // NO-OP, leave stack as is + }, + Instruction::Shl | Instruction::Shr => { let _rhs = operand_stack.pop_ty()?; // NO-OP, same as the two lines below: // let lhs = operand_stack.pop_ty()?; // operand_stack.push_ty(lhs)?; }, - Bytecode::Lt | Bytecode::Le | Bytecode::Gt | Bytecode::Ge => { + Instruction::Lt | Instruction::Le | Instruction::Gt | Instruction::Ge => { let rhs_ty = operand_stack.pop_ty()?; let lhs_ty = operand_stack.pop_ty()?; rhs_ty.paranoid_check_eq(&lhs_ty)?; @@ -621,7 +773,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let bool_ty = ty_builder.create_bool_ty(); operand_stack.push_ty(bool_ty)?; }, - Bytecode::Eq | Bytecode::Neq => { + Instruction::Eq | Instruction::Neq => { let rhs_ty = operand_stack.pop_ty()?; let lhs_ty = operand_stack.pop_ty()?; rhs_ty.paranoid_check_eq(&lhs_ty)?; @@ -630,7 +782,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let bool_ty = ty_builder.create_bool_ty(); operand_stack.push_ty(bool_ty)?; }, - Bytecode::MutBorrowGlobal(idx) => { + Instruction::MutBorrowGlobal(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let struct_ty = frame.get_struct_ty(*idx); struct_ty.paranoid_check_has_ability(Ability::Key)?; @@ -638,7 +790,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let struct_mut_ref_ty = ty_builder.create_ref_ty(&struct_ty, true)?; operand_stack.push_ty(struct_mut_ref_ty)?; }, - Bytecode::ImmBorrowGlobal(idx) => { + Instruction::ImmBorrowGlobal(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let struct_ty = frame.get_struct_ty(*idx); struct_ty.paranoid_check_has_ability(Ability::Key)?; @@ -646,7 +798,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let struct_ref_ty = ty_builder.create_ref_ty(&struct_ty, false)?; operand_stack.push_ty(struct_ref_ty)?; }, - Bytecode::MutBorrowGlobalGeneric(idx) => { + Instruction::MutBorrowGlobalGeneric(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let struct_ty = ty_cache.get_struct_type(*idx, frame)?.0; struct_ty.paranoid_check_has_ability(Ability::Key)?; @@ -654,7 +806,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let struct_mut_ref_ty = ty_builder.create_ref_ty(struct_ty, true)?; operand_stack.push_ty(struct_mut_ref_ty)?; }, - Bytecode::ImmBorrowGlobalGeneric(idx) => { + Instruction::ImmBorrowGlobalGeneric(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let struct_ty = ty_cache.get_struct_type(*idx, frame)?.0; struct_ty.paranoid_check_has_ability(Ability::Key)?; @@ -662,49 +814,49 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let struct_ref_ty = ty_builder.create_ref_ty(struct_ty, false)?; operand_stack.push_ty(struct_ref_ty)?; }, - Bytecode::Exists(_) | Bytecode::ExistsGeneric(_) => { + Instruction::Exists(_) | Instruction::ExistsGeneric(_) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let bool_ty = ty_builder.create_bool_ty(); operand_stack.push_ty(bool_ty)?; }, - Bytecode::MoveTo(idx) => { + Instruction::MoveTo(idx) => { let ty = operand_stack.pop_ty()?; operand_stack.pop_ty()?.paranoid_check_is_signer_ref_ty()?; ty.paranoid_check_eq(&frame.get_struct_ty(*idx))?; ty.paranoid_check_has_ability(Ability::Key)?; }, - Bytecode::MoveToGeneric(idx) => { + Instruction::MoveToGeneric(idx) => { let ty = operand_stack.pop_ty()?; operand_stack.pop_ty()?.paranoid_check_is_signer_ref_ty()?; ty.paranoid_check_eq(ty_cache.get_struct_type(*idx, frame)?.0)?; ty.paranoid_check_has_ability(Ability::Key)?; }, - Bytecode::MoveFrom(idx) => { + Instruction::MoveFrom(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let ty = frame.get_struct_ty(*idx); ty.paranoid_check_has_ability(Ability::Key)?; operand_stack.push_ty(ty)?; }, - Bytecode::MoveFromGeneric(idx) => { + Instruction::MoveFromGeneric(idx) => { operand_stack.pop_ty()?.paranoid_check_is_address_ty()?; let ty = ty_cache.get_struct_type(*idx, frame)?.0.clone(); ty.paranoid_check_has_ability(Ability::Key)?; operand_stack.push_ty(ty)?; }, - Bytecode::FreezeRef => { + Instruction::FreezeRef => { let mut_ref_ty = operand_stack.pop_ty()?; let ref_ty = mut_ref_ty.paranoid_freeze_ref_ty()?; operand_stack.push_ty(ref_ty)?; }, - Bytecode::Nop => (), - Bytecode::Not => { + Instruction::Nop => (), + Instruction::Not => { operand_stack.top_ty()?.paranoid_check_is_bool_ty()?; // NO-OP, same as the two lines below: // let bool_ty = ty_builder.create_bool_ty(); // operand_stack.push_ty(bool_ty)?; }, - Bytecode::VecPack(si, num) => { + Instruction::VecPack(si, num) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; let num: u16 = (*num).try_into().map_err(|_| { PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) @@ -718,7 +870,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let vec_ty = ty_builder.create_vec_ty(ty)?; operand_stack.push_ty(vec_ty)?; }, - Bytecode::VecLen(si) => { + Instruction::VecLen(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; operand_stack .pop_ty()? @@ -727,7 +879,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { let u64_ty = ty_builder.create_u64_ty(); operand_stack.push_ty(u64_ty)?; }, - Bytecode::VecImmBorrow(si) => { + Instruction::VecImmBorrow(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; operand_stack.pop_ty()?.paranoid_check_is_u64_ty()?; let elem_ref_ty = operand_stack @@ -736,7 +888,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(elem_ref_ty)?; }, - Bytecode::VecMutBorrow(si) => { + Instruction::VecMutBorrow(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; operand_stack.pop_ty()?.paranoid_check_is_u64_ty()?; let elem_ref_ty = operand_stack @@ -744,7 +896,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { .paranoid_check_and_get_vec_elem_ref_ty::(ty)?; operand_stack.push_ty(elem_ref_ty)?; }, - Bytecode::VecPushBack(si) => { + Instruction::VecPushBack(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; // For pushing an element to a vector, use assignability operand_stack.pop_ty()?.paranoid_check_assignable(ty)?; @@ -752,14 +904,14 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { .pop_ty()? .paranoid_check_is_vec_ref_ty::(ty)?; }, - Bytecode::VecPopBack(si) => { + Instruction::VecPopBack(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; let elem_ty = operand_stack .pop_ty()? .paranoid_check_and_get_vec_elem_ty::(ty)?; operand_stack.push_ty(elem_ty)?; }, - Bytecode::VecUnpack(si, num) => { + Instruction::VecUnpack(si, num) => { let (expected_elem_ty, _) = ty_cache.get_signature_index_type(*si, frame)?; let vec_ty = operand_stack.pop_ty()?; vec_ty.paranoid_check_is_vec_ty(expected_elem_ty)?; @@ -767,7 +919,7 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { operand_stack.push_ty(expected_elem_ty.clone())?; } }, - Bytecode::VecSwap(si) => { + Instruction::VecSwap(si) => { let (ty, _) = ty_cache.get_signature_index_type(*si, frame)?; operand_stack.pop_ty()?.paranoid_check_is_u64_ty()?; operand_stack.pop_ty()?.paranoid_check_is_u64_ty()?; @@ -779,12 +931,103 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { Ok(()) } - fn check_operand_stack_balance(operand_stack: &Stack) -> PartialVMResult<()> { - operand_stack.check_balance() + #[cfg_attr(feature = "force-inline", inline(always))] + fn should_perform_checks(_for_fun: &Function) -> bool { + true } - #[inline(always)] - fn should_perform_checks() -> bool { - true + #[cfg_attr(feature = "force-inline", inline(always))] + fn check_cross_module_regular_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + ) -> PartialVMResult<()> { + if callee.is_private() { + let msg = format!( + "Function {}::{} cannot be called because it is private", + callee.module_or_script_id(), + callee.name() + ); + return Err( + PartialVMError::new_invariant_violation(msg).with_sub_status(EPARANOID_FAILURE) + ); + } + + if callee.is_friend() { + let callee_module = callee.owner_as_module().map_err(|err| err.to_partial())?; + if !caller + .module_id() + .is_some_and(|id| callee_module.friends.contains(id)) + { + let msg = format!( + "Function {}::{} cannot be called because it has friend visibility, but {} \ + is not {}'s friend", + callee.module_or_script_id(), + callee.name(), + caller.module_or_script_id(), + callee.module_or_script_id() + ); + return Err( + PartialVMError::new_invariant_violation(msg).with_sub_status(EPARANOID_FAILURE) + ); + } + } + + Ok(()) + } +} + +impl RuntimeTypeCheck for UntrustedOnlyRuntimeTypeCheck { + #[cfg_attr(feature = "force-inline", inline(always))] + fn pre_execution_type_stack_transition( + frame: &Frame, + operand_stack: &mut Stack, + instruction: &Instruction, + ty_cache: &mut FrameTypeCache, + ) -> PartialVMResult<()> { + if frame.untrusted_code() { + FullRuntimeTypeCheck::pre_execution_type_stack_transition( + frame, + operand_stack, + instruction, + ty_cache, + ) + } else { + Ok(()) + } + } + + #[cfg_attr(feature = "force-inline", inline(always))] + fn post_execution_type_stack_transition( + frame: &Frame, + operand_stack: &mut Stack, + instruction: &Instruction, + ty_cache: &mut FrameTypeCache, + ) -> PartialVMResult<()> { + if frame.untrusted_code() { + FullRuntimeTypeCheck::post_execution_type_stack_transition( + frame, + operand_stack, + instruction, + ty_cache, + ) + } else { + Ok(()) + } + } + + fn should_perform_checks(for_fun: &Function) -> bool { + !for_fun.is_trusted + } + + #[cfg_attr(feature = "force-inline", inline(always))] + fn check_cross_module_regular_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + ) -> PartialVMResult<()> { + if !caller.function.is_trusted { + FullRuntimeTypeCheck::check_cross_module_regular_call_visibility(caller, callee) + } else { + Ok(()) + } } } diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs new file mode 100644 index 00000000000..4ddb33df8af --- /dev/null +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs @@ -0,0 +1,796 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Defines async type checker that abstractly interprets Move bytecode to perform type checks +//! based on the execution trace. +//! +//! The type checker should only be used (as opposed to just performing the checks synchronously) +//! if it can provide performance improvements. For example, to avoid redundant type checking +//! during speculative parallel execution of transactions that are aborted (and instead performing +//! the checks async once, and still in parallel). +//! +//! The type checker can safely use [UnmeteredGasMeter], or other unmetered APIs (e.g., for module +//! loading) because trace records only successful execution of instructions, and so the gas must +//! have been charged during execution. +//! +//! The type checker is also not expected to fail. Any type check violations must be caught by the +//! bytecode verifier, so the runtime checks are an additional safety net. Also, because checks are +//! done over fully-substituted types, it is important that type substitution cannot fail here and +//! this has to be enforced at execution time. Otherwise, user-defined code can fail checks because +//! of running into limits that were not done at regular execution time. + +use crate::{ + config::VMConfig, + execution_tracing::{Trace, TraceCursor}, + frame::Frame, + frame_type_cache::{FrameTypeCache, PerInstructionCache}, + interpreter::{CallStack, Stack}, + interpreter_caches::InterpreterFunctionCaches, + loader::FunctionHandle, + reentrancy_checker::CallType, + runtime_type_checks::{ + verify_pack_closure, FullRuntimeTypeCheck, RuntimeTypeCheck, UntrustedOnlyRuntimeTypeCheck, + }, + LoadedFunction, LoadedFunctionOwner, ModuleStorage, +}; +use move_binary_format::{ + errors::{Location, PartialVMError, PartialVMResult, VMResult}, + file_format::{FunctionHandleIndex, FunctionInstantiationIndex}, +}; +use move_core_types::function::ClosureMask; +use move_vm_types::{ + gas::UnmeteredGasMeter, + instr::Instruction, + loaded_data::runtime_types::{Type, TypeBuilder}, + ty_interner::{InternedTypePool, TypeVecId}, + values::{Locals, Value}, +}; +use std::{ + cell::RefCell, + collections::{btree_map::Entry, VecDeque}, + iter, + rc::Rc, +}; + +/// This ensures error location is set in the same way as in the interpreter. +macro_rules! set_err_info { + ($frame:ident, $e:expr) => {{ + $e.at_code_offset($frame.function.index(), $frame.pc) + .finish($frame.location()) + }}; +} + +/// Exit codes returned when type frame reaches a control-flow instructions like calls, etc. +enum ExitCode { + /// Replay is done. No more instructions need to be replayed. + Done, + /// Function returns the control to the caller. + Return, + /// Function statically calls into a non-generic function. + Call(FunctionHandleIndex), + /// Function statically calls into a generic function. + CallGeneric(FunctionInstantiationIndex), + /// Function dynamically calls a closure (must be recorded in the trace). + CallClosure, +} + +/// Runtime type checker based on tracing. +pub struct TypeChecker<'a, T> { + /// Stores type information for type checks. + type_stack: Stack, + /// Stores function frames of callers. + call_stack: CallStack, + /// Stores frame caches for functions used during replay. + function_caches: InterpreterFunctionCaches, + /// Code state on top of which the replay runs. + module_storage: &'a T, + /// Cached pool of interned type IDs. + ty_pool: &'a InternedTypePool, + /// Cached VM configuration and feature flags. + vm_config: &'a VMConfig, + /// Cached type builder. + ty_builder: &'a TypeBuilder, +} + +impl<'a, T> TypeChecker<'a, T> +where + T: ModuleStorage, +{ + /// Creates a new type checker that can replay traces over the provided code state. + pub fn new(module_storage: &'a T) -> Self { + let runtime_environment = module_storage.runtime_environment(); + let ty_pool = runtime_environment.ty_pool(); + let vm_config = runtime_environment.vm_config(); + let ty_builder = &vm_config.ty_builder; + + Self { + type_stack: Stack::new(), + call_stack: CallStack::new(), + function_caches: InterpreterFunctionCaches::new(), + module_storage, + ty_pool, + vm_config, + ty_builder, + } + } + + /// Replays the trace performing type checks. If any checks fail, an error is returned. + pub fn replay(mut self, trace: &Trace) -> VMResult<()> { + // If there is no type checks ar all: no need to replay the trace. + if !self.vm_config.paranoid_type_checks { + debug_assert!(!self.vm_config.optimize_trusted_code); + return Ok(()); + } + + // If trace is empty - there is nothing to check. + if trace.is_empty() { + return Ok(()); + } + + // Otherwise, the trace is replayed with full type checks or type checks only for untrusted + // code. + let mut cursor = TraceCursor::new(trace); + if self.vm_config.optimize_trusted_code { + self.replay_impl::(&mut cursor)?; + } else { + self.replay_impl::(&mut cursor)?; + } + + if !cursor.is_done() { + return Err(PartialVMError::new_invariant_violation("Trace replay finished but there are still some branches/dynamic calls not yet processed").finish(Location::Undefined)); + } + Ok(()) + } +} + +impl<'a, T> TypeChecker<'a, T> +where + T: ModuleStorage, +{ + /// Internal implementation of trace replay, with configurable type checker. + fn replay_impl(&mut self, cursor: &mut TraceCursor) -> VMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + let mut current_frame = self + .set_entrypoint_frame::(cursor) + .map_err(|err| err.finish(Location::Undefined))?; + loop { + let exit = self + .execute_instructions::(cursor, &mut current_frame) + .map_err(|err| set_err_info!(current_frame, err))?; + match exit { + ExitCode::Done => return Ok(()), + ExitCode::Return => { + self.call_stack + .type_check_return::(&mut self.type_stack, &mut current_frame) + .map_err(|err| set_err_info!(current_frame, err))?; + if let Some(frame) = self.call_stack.pop() { + // Return control to the caller, advance PC past the call instruction. + current_frame = frame; + current_frame.pc += 1; + } else { + return Ok(()); + } + }, + ExitCode::Call(idx) => { + let (callee, callee_frame_cache) = self + .load_function(&mut current_frame, idx) + .map_err(|err| set_err_info!(current_frame, err))?; + self.execute_regular_call::( + cursor, + &mut current_frame, + callee, + callee_frame_cache, + )?; + }, + ExitCode::CallGeneric(idx) => { + let (callee, callee_frame_cache) = self + .load_function_generic(&mut current_frame, idx) + .map_err(|err| set_err_info!(current_frame, err))?; + self.execute_regular_call::( + cursor, + &mut current_frame, + callee, + callee_frame_cache, + )?; + }, + ExitCode::CallClosure => { + let (callee, mask) = cursor + .consume_closure_call() + .map_err(|err| err.finish(Location::Undefined)) + .map(|(f, mask)| (Rc::new(f.clone()), mask))?; + let callee_frame_cache = FrameTypeCache::make_rc_for_function(&callee); + self.execute_closure_call::( + cursor, + &mut current_frame, + callee, + callee_frame_cache, + mask, + )?; + }, + } + } + } + + /// Replays a sequence of instructions in a function frame, performing type checks. Returns an + /// error if checks during execution fail, or there is an internal invariant violation. + fn execute_instructions( + &mut self, + cursor: &mut TraceCursor, + frame: &mut Frame, + ) -> PartialVMResult + where + RTTCheck: RuntimeTypeCheck, + { + loop { + let pc = frame.pc as usize; + if pc >= frame.function.function.code.len() { + return Err(PartialVMError::new_invariant_violation( + "PC cannot overflow when replaying the trace", + )); + } + let instr = &frame.function.function.code[pc]; + + // Check if we need to execute this instruction, if so, decrement the number of + // remaining instructions to replay. + if cursor.no_instructions_remaining() { + return Ok(ExitCode::Done); + } + cursor.consume_instruction_unchecked(instr); + + let mut frame_cache = frame.frame_cache.borrow_mut(); + RTTCheck::pre_execution_type_stack_transition( + frame, + &mut self.type_stack, + instr, + &mut frame_cache, + )?; + + // After pre-execution transition, we need to check for control flow instructions to + // make sure replay goes as expected. For non-control flow instructions, there is + // nothing to do (*). + // + // (*) Note that for some instructions there are additional steps: + // For example, closure pack is checked in interpreter loop, not in post-execution + // type checks. Another example is local handling: we need to invalidate locals, + // which is done via dummy values. + match instr { + Instruction::Ret => { + return Ok(ExitCode::Return); + }, + Instruction::Abort => { + return Ok(ExitCode::Done); + }, + Instruction::Call(idx) => { + return Ok(ExitCode::Call(*idx)); + }, + Instruction::CallGeneric(idx) => { + return Ok(ExitCode::CallGeneric(*idx)); + }, + Instruction::CallClosure(_) => { + return Ok(ExitCode::CallClosure); + }, + Instruction::Branch(target) => { + frame.pc = *target; + continue; + }, + Instruction::BrTrue(target) | Instruction::BrFalse(target) => { + let taken = cursor.consume_branch()?; + if taken { + frame.pc = *target; + } else { + frame.pc += 1; + } + continue; + }, + Instruction::StLoc(idx) => { + // Store dummy value - these are not needed for type checks, as we only need to + // know if the value is valid or not. + frame.locals.store_loc(*idx as usize, dummy_local())?; + }, + Instruction::MoveLoc(idx) => { + frame.locals.move_loc(*idx as usize)?; + }, + // Pack closure is not checked in pre- or post-execution type transition. + Instruction::PackClosure(idx, mask) => { + let function = self.idx_to_loaded_function(frame, *idx)?; + RTTCheck::check_pack_closure_visibility(&frame.function, &function)?; + if RTTCheck::should_perform_checks(&frame.function.function) { + verify_pack_closure( + self.ty_builder, + &mut self.type_stack, + &function, + *mask, + )?; + } + }, + // Pack closure generic is not checked in pre- or post-execution type transition. + Instruction::PackClosureGeneric(idx, mask) => { + let function = self.instantiation_idx_to_loaded_function(frame, *idx)?; + RTTCheck::check_pack_closure_visibility(&frame.function, &function)?; + if RTTCheck::should_perform_checks(&frame.function.function) { + verify_pack_closure( + self.ty_builder, + &mut self.type_stack, + &function, + *mask, + )?; + } + }, + Instruction::Pop + | Instruction::LdU8(_) + | Instruction::LdU64(_) + | Instruction::LdU128(_) + | Instruction::CastU8 + | Instruction::CastU64 + | Instruction::CastU128 + | Instruction::LdConst(_) + | Instruction::LdTrue + | Instruction::LdFalse + | Instruction::CopyLoc(_) + | Instruction::Pack(_) + | Instruction::PackGeneric(_) + | Instruction::PackVariant(_) + | Instruction::PackVariantGeneric(_) + | Instruction::Unpack(_) + | Instruction::UnpackGeneric(_) + | Instruction::UnpackVariant(_) + | Instruction::UnpackVariantGeneric(_) + | Instruction::TestVariant(_) + | Instruction::TestVariantGeneric(_) + | Instruction::ReadRef + | Instruction::WriteRef + | Instruction::FreezeRef + | Instruction::MutBorrowLoc(_) + | Instruction::ImmBorrowLoc(_) + | Instruction::MutBorrowField(_) + | Instruction::MutBorrowVariantField(_) + | Instruction::MutBorrowFieldGeneric(_) + | Instruction::MutBorrowVariantFieldGeneric(_) + | Instruction::ImmBorrowField(_) + | Instruction::ImmBorrowVariantField(_) + | Instruction::ImmBorrowFieldGeneric(_) + | Instruction::ImmBorrowVariantFieldGeneric(_) + | Instruction::MutBorrowGlobal(_) + | Instruction::MutBorrowGlobalGeneric(_) + | Instruction::ImmBorrowGlobal(_) + | Instruction::ImmBorrowGlobalGeneric(_) + | Instruction::Add + | Instruction::Sub + | Instruction::Mul + | Instruction::Mod + | Instruction::Div + | Instruction::BitOr + | Instruction::BitAnd + | Instruction::Xor + | Instruction::Or + | Instruction::And + | Instruction::Not + | Instruction::Eq + | Instruction::Neq + | Instruction::Lt + | Instruction::Gt + | Instruction::Le + | Instruction::Ge + | Instruction::Nop + | Instruction::Exists(_) + | Instruction::ExistsGeneric(_) + | Instruction::MoveFrom(_) + | Instruction::MoveFromGeneric(_) + | Instruction::MoveTo(_) + | Instruction::MoveToGeneric(_) + | Instruction::Shl + | Instruction::Shr + | Instruction::VecPack(_, _) + | Instruction::VecLen(_) + | Instruction::VecImmBorrow(_) + | Instruction::VecMutBorrow(_) + | Instruction::VecPushBack(_) + | Instruction::VecPopBack(_) + | Instruction::VecUnpack(_, _) + | Instruction::VecSwap(_) + | Instruction::LdU16(_) + | Instruction::LdU32(_) + | Instruction::LdU256(_) + | Instruction::LdI8(_) + | Instruction::LdI16(_) + | Instruction::LdI32(_) + | Instruction::LdI64(_) + | Instruction::LdI128(_) + | Instruction::LdI256(_) + | Instruction::CastI8 + | Instruction::CastI16 + | Instruction::CastI32 + | Instruction::CastI64 + | Instruction::CastI128 + | Instruction::CastI256 + | Instruction::Negate + | Instruction::CastU16 + | Instruction::CastU32 + | Instruction::CastU256 => (), + } + + RTTCheck::post_execution_type_stack_transition( + frame, + &mut self.type_stack, + instr, + &mut frame_cache, + )?; + frame.pc += 1; + } + } + + /// Called when encountering instruction that makes a static call. + fn execute_regular_call( + &mut self, + cursor: &mut TraceCursor, + current_frame: &mut Frame, + callee: Rc, + callee_frame_cache: Rc>, + ) -> VMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + self.execute_call::( + cursor, + current_frame, + callee, + callee_frame_cache, + CallType::Regular, + ClosureMask::empty(), + ) + } + + /// Called when encountering instruction that makes a call via closure dynamic dispatch. + fn execute_closure_call( + &mut self, + cursor: &mut TraceCursor, + current_frame: &mut Frame, + callee: Rc, + callee_frame_cache: Rc>, + mask: ClosureMask, + ) -> VMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + self.execute_call::( + cursor, + current_frame, + callee, + callee_frame_cache, + CallType::ClosureDynamicDispatch, + mask, + ) + } + + /// Called when encountering instruction that statically or dynamically calls a function. + #[inline(always)] + fn execute_call( + &mut self, + cursor: &mut TraceCursor, + current_frame: &mut Frame, + callee: Rc, + callee_frame_cache: Rc>, + call_type: CallType, + mask: ClosureMask, + ) -> VMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + RTTCheck::check_call_visibility(¤t_frame.function, &callee, call_type) + .map_err(|err| set_err_info!(current_frame, err))?; + + if callee.is_native() { + self.execute_native_call::(cursor, current_frame, &callee, mask) + .map_err(|err| { + // Preserving same behavior as interpreter. + err.at_code_offset(callee.index(), 0) + .finish(Location::Module(callee.module_or_script_id().clone())) + })?; + return Ok(()); + } + + self.set_new_frame::(current_frame, callee, callee_frame_cache, call_type, mask) + .map_err(|err| { + // Preserving same behavior as interpreter. + err.finish(self.call_stack.current_location()) + })?; + Ok(()) + } + + /// Replays execution of a native function, type checking both parameter and return types. + fn execute_native_call( + &mut self, + cursor: &mut TraceCursor, + current_frame: &mut Frame, + native: &LoadedFunction, + mask: ClosureMask, + ) -> PartialVMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + let ty_args = native.ty_args(); + let mut arg_tys = VecDeque::new(); + if RTTCheck::should_perform_checks(¤t_frame.function.function) { + let num_params = native.param_tys().len(); + for i in (0..num_params).rev() { + let expected_ty = &native.param_tys()[i]; + if !mask.is_captured(i) { + let ty = self.type_stack.pop_ty()?; + if ty_args.is_empty() { + ty.paranoid_check_assignable(expected_ty)?; + } else { + let expected_ty = + self.ty_builder.create_ty_with_subst(expected_ty, ty_args)?; + ty.paranoid_check_assignable(&expected_ty)?; + } + arg_tys.push_front(ty); + } else { + #[allow(clippy::collapsible_else_if)] + if ty_args.is_empty() { + arg_tys.push_front(expected_ty.clone()) + } else { + let expected_ty = + self.ty_builder.create_ty_with_subst(expected_ty, ty_args)?; + arg_tys.push_front(expected_ty) + } + } + } + } + + if native.function.is_dispatchable_native { + let target_func = cursor.consume_entrypoint().map(|f| Rc::new(f.clone()))?; + let frame_cache = self.function_caches.get_or_create_frame_cache(&target_func); + RTTCheck::check_call_visibility(native, &target_func, CallType::NativeDynamicDispatch)?; + + if RTTCheck::should_perform_checks(¤t_frame.function.function) { + arg_tys.pop_back(); + for ty in arg_tys { + self.type_stack.push_ty(ty)?; + } + } + self.set_new_frame::( + current_frame, + target_func, + frame_cache, + CallType::NativeDynamicDispatch, + ClosureMask::empty(), + )?; + } else { + if RTTCheck::should_perform_checks(¤t_frame.function.function) { + if ty_args.is_empty() { + for ty in native.return_tys() { + self.type_stack.push_ty(ty.clone())?; + } + } else { + for ty in native.return_tys() { + let ty = self.ty_builder.create_ty_with_subst(ty, ty_args)?; + self.type_stack.push_ty(ty)?; + } + } + } + current_frame.pc += 1; + } + + Ok(()) + } + + /// Returns the entry-point frame when replay starts. + fn set_entrypoint_frame(&mut self, cursor: &mut TraceCursor) -> PartialVMResult + where + RTTCheck: RuntimeTypeCheck, + { + let function = cursor.consume_entrypoint().map(|f| Rc::new(f.clone()))?; + let frame_cache = self.function_caches.get_or_create_frame_cache(&function); + + let num_params = function.param_tys().len(); + let num_locals = function.local_tys().len(); + + let args = iter::repeat_with(dummy_local).take(num_params).collect(); + let locals = Locals::new_from(args, num_locals)?; + Frame::make_new_frame::( + &mut UnmeteredGasMeter, + CallType::Regular, + self.vm_config, + function, + None, + locals, + frame_cache, + &self.type_stack, + ) + } + + /// Creates a new frame for a function call, and assigns it to the current frame. Additionally, + /// type checks types on the stack against the expected local types. + fn set_new_frame( + &mut self, + current_frame: &mut Frame, + callee: Rc, + callee_frame_cache: Rc>, + call_type: CallType, + mask: ClosureMask, + ) -> PartialVMResult<()> + where + RTTCheck: RuntimeTypeCheck, + { + let num_params = callee.param_tys().len(); + let num_locals = callee.local_tys().len(); + let mut locals = Locals::new(num_locals); + + let ty_args = callee.ty_args(); + let should_check = RTTCheck::should_perform_checks(¤t_frame.function.function); + + for i in (0..num_params).rev() { + locals.store_loc(i, dummy_local())?; + + if should_check && !mask.is_captured(i) { + let ty = self.type_stack.pop_ty()?; + let expected_ty = &callee.local_tys()[i]; + + if ty_args.is_empty() { + ty.paranoid_check_assignable(expected_ty)?; + } else { + let expected_ty = self.ty_builder.create_ty_with_subst(expected_ty, ty_args)?; + ty.paranoid_check_assignable(&expected_ty)?; + } + } + } + + let mut frame = Frame::make_new_frame::( + &mut UnmeteredGasMeter, + call_type, + self.vm_config, + callee, + None, + locals, + callee_frame_cache, + &self.type_stack, + )?; + std::mem::swap(current_frame, &mut frame); + self.call_stack.push(frame).map_err(|_| { + PartialVMError::new_invariant_violation("Call-stack cannot overflow during replay") + })?; + + Ok(()) + } + + /// For a given function index, loads it and its frame cache. + fn load_function( + &mut self, + current_frame: &mut Frame, + idx: FunctionHandleIndex, + ) -> PartialVMResult<(Rc, Rc>)> { + use PerInstructionCache::*; + + let pc = current_frame.pc as usize; + let current_frame_cache = &mut *current_frame.frame_cache.borrow_mut(); + + let function_and_cache = + if let Call(function, frame_cache) = ¤t_frame_cache.per_instruction_cache[pc] { + (Rc::clone(function), Rc::clone(frame_cache)) + } else { + let (function, frame_cache) = match current_frame_cache.function_cache.entry(idx) { + Entry::Vacant(e) => { + let function = self.idx_to_loaded_function(current_frame, idx)?; + let frame_cache = self + .function_caches + .get_or_create_frame_cache_non_generic(&function); + e.insert((function.clone(), frame_cache.clone())); + (function, frame_cache) + }, + Entry::Occupied(e) => e.into_mut().clone(), + }; + + current_frame_cache.per_instruction_cache[pc] = + Call(Rc::clone(&function), Rc::clone(&frame_cache)); + (function, frame_cache) + }; + Ok(function_and_cache) + } + + /// For a given function instantiation index, loads it instantiation, and its frame cache. + fn load_function_generic( + &mut self, + current_frame: &mut Frame, + idx: FunctionInstantiationIndex, + ) -> PartialVMResult<(Rc, Rc>)> { + let pc = current_frame.pc as usize; + let current_frame_cache = &mut *current_frame.frame_cache.borrow_mut(); + + let function_and_cache = if let PerInstructionCache::CallGeneric(function, frame_cache) = + ¤t_frame_cache.per_instruction_cache[pc] + { + (Rc::clone(function), Rc::clone(frame_cache)) + } else { + let (function, frame_cache) = + match current_frame_cache.generic_function_cache.entry(idx) { + Entry::Vacant(e) => { + let function = + self.instantiation_idx_to_loaded_function(current_frame, idx)?; + let frame_cache = self + .function_caches + .get_or_create_frame_cache_generic(&function); + e.insert((function.clone(), frame_cache.clone())); + (function, frame_cache) + }, + Entry::Occupied(e) => e.into_mut().clone(), + }; + + current_frame_cache.per_instruction_cache[pc] = + PerInstructionCache::CallGeneric(Rc::clone(&function), Rc::clone(&frame_cache)); + (function, frame_cache) + }; + Ok(function_and_cache) + } + + /// Converts handle to a non-generic function into a [LoadedFunction]. + fn idx_to_loaded_function( + &self, + frame: &Frame, + idx: FunctionHandleIndex, + ) -> PartialVMResult> { + let handle = match frame.function.owner() { + LoadedFunctionOwner::Script(script) => script.function_at(idx.0), + LoadedFunctionOwner::Module(module) => module.function_at(idx.0), + }; + let no_ty_args_id = self.ty_pool.intern_ty_args(&[]); + self.handle_to_loaded_function(frame, handle, vec![], no_ty_args_id) + } + + /// Converts handle to an instantiation of a generic function into a [LoadedFunction]. + fn instantiation_idx_to_loaded_function( + &self, + frame: &Frame, + idx: FunctionInstantiationIndex, + ) -> PartialVMResult> { + let handle = match frame.function.owner() { + LoadedFunctionOwner::Script(script) => script.function_instantiation_handle_at(idx.0), + LoadedFunctionOwner::Module(module) => module.function_instantiation_handle_at(idx.0), + }; + let (ty_args, ty_args_id) = frame.instantiate_generic_function( + self.ty_pool, + None::<&mut UnmeteredGasMeter>, + idx, + )?; + self.handle_to_loaded_function(frame, handle, ty_args, ty_args_id) + } + + /// Converts handle to a function into a [LoadedFunction], fetching it from code storage if + /// needed. + #[inline(always)] + fn handle_to_loaded_function( + &self, + frame: &Frame, + handle: &FunctionHandle, + ty_args: Vec, + ty_args_id: TypeVecId, + ) -> PartialVMResult> { + let (owner, function) = match handle { + FunctionHandle::Local(f) => (frame.function.owner().clone(), f.clone()), + FunctionHandle::Remote { module, name } => { + // There is no need to meter gas here: it has been charged during execution. + let module = self + .module_storage + .unmetered_get_existing_lazily_verified_module(module) + .map_err(|err| err.to_partial())?; + let function = module.get_function(name).map_err(|err| err.to_partial())?; + (LoadedFunctionOwner::Module(module), function) + }, + }; + Ok(Rc::new(LoadedFunction { + owner, + ty_args, + ty_args_id, + function, + })) + } +} + +/// Locals can be non-invalid, in which case type checks need to verify that such a local has drop +/// ability (based on the local type). To simulate invalidation of locals, a simple dummy value (an +/// integer) is sufficient. +#[inline(always)] +fn dummy_local() -> Value { + Value::u8(0) +} diff --git a/third_party/move/move-vm/runtime/src/session.rs b/third_party/move/move-vm/runtime/src/session.rs deleted file mode 100644 index 92485e608ce..00000000000 --- a/third_party/move/move-vm/runtime/src/session.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - data_cache::TransactionDataCache, loader::LoadedFunction, module_traversal::TraversalContext, - move_vm::MoveVM, native_extensions::NativeContextExtensions, - storage::module_storage::ModuleStorage, CodeStorage, -}; -use move_binary_format::{errors::*, file_format::LocalIndex}; -use move_core_types::{ - effects::{ChangeSet, Changes}, - identifier::IdentStr, - language_storage::{ModuleId, TypeTag}, - value::MoveTypeLayout, - vm_status::StatusCode, -}; -use move_vm_types::{gas::GasMeter, resolver::ResourceResolver, values::Value}; -use std::borrow::Borrow; - -pub struct Session<'r> { - pub(crate) data_cache: TransactionDataCache, - pub(crate) native_extensions: NativeContextExtensions<'r>, -} - -/// Serialized return values from function/script execution -/// Simple struct is designed just to convey meaning behind serialized values -#[derive(Debug)] -pub struct SerializedReturnValues { - /// The value of any arguments that were mutably borrowed. - /// Non-mut borrowed values are not included - pub mutable_reference_outputs: Vec<(LocalIndex, Vec, MoveTypeLayout)>, - /// The return values from the function - pub return_values: Vec<(Vec, MoveTypeLayout)>, -} - -impl<'r> Session<'r> { - /// Execute a Move entry function. - /// - /// NOTE: There are NO checks on the `args` except that they can deserialize - /// into the provided types. The ability to deserialize `args` into arbitrary - /// types is *very* powerful, e.g., it can be used to manufacture `signer`s - /// or `Coin`s from raw bytes. It is the responsibility of the caller to ensure - /// that this power is used responsibly/securely for its use-case. - pub fn execute_entry_function( - &mut self, - func: LoadedFunction, - args: Vec>, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, - ) -> VMResult<()> { - if !func.is_entry() { - let module_id = func - .module_id() - .cloned() - .expect("Entry function always has module id"); - return Err(PartialVMError::new( - StatusCode::EXECUTE_ENTRY_FUNCTION_CALLED_ON_NON_ENTRY_FUNCTION, - ) - .finish(Location::Module(module_id))); - } - - MoveVM::execute_loaded_function( - func, - args, - &mut self.data_cache, - gas_meter, - traversal_context, - &mut self.native_extensions, - module_storage, - resource_resolver, - )?; - Ok(()) - } - - /// Execute a Move function ignoring its visibility and whether it is entry or not. - pub fn execute_function_bypass_visibility( - &mut self, - module_id: &ModuleId, - function_name: &IdentStr, - ty_args: Vec, - args: Vec>, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, - ) -> VMResult { - let func = module_storage.load_function(module_id, function_name, &ty_args)?; - MoveVM::execute_loaded_function( - func, - args, - &mut self.data_cache, - gas_meter, - traversal_context, - &mut self.native_extensions, - module_storage, - resource_resolver, - ) - } - - pub fn execute_loaded_function( - &mut self, - func: LoadedFunction, - args: Vec>, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - module_storage: &impl ModuleStorage, - resource_resolver: &impl ResourceResolver, - ) -> VMResult { - MoveVM::execute_loaded_function( - func, - args, - &mut self.data_cache, - gas_meter, - traversal_context, - &mut self.native_extensions, - module_storage, - resource_resolver, - ) - } - - /// Execute a transaction script. - /// - /// The Move VM MUST return a user error (in other words, an error that's not an invariant - /// violation) if - /// - The script fails to deserialize or verify. Not all expressible signatures are valid. - /// See `move_bytecode_verifier::script_signature` for the rules. - /// - Type arguments refer to a non-existent type. - /// - Arguments (senders included) fail to deserialize or fail to match the signature of the - /// script function. - /// - /// If any other error occurs during execution, the Move VM MUST propagate that error back to - /// the caller. - /// Besides, no user input should cause the Move VM to return an invariant violation. - /// - /// In case an invariant violation occurs, the whole Session should be considered corrupted and - /// one shall not proceed with effect generation. - pub fn load_and_execute_script( - &mut self, - script: impl Borrow<[u8]>, - ty_args: Vec, - args: Vec>, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - code_storage: &impl CodeStorage, - resource_resolver: &impl ResourceResolver, - ) -> VMResult<()> { - let main = code_storage.load_script(script.borrow(), &ty_args)?; - MoveVM::execute_loaded_function( - main, - args, - &mut self.data_cache, - gas_meter, - traversal_context, - &mut self.native_extensions, - code_storage, - resource_resolver, - )?; - Ok(()) - } - - /// Finish up the session and produce the side effects. - /// - /// This function should always succeed with no user errors returned, barring invariant violations. - /// - /// This MUST NOT be called if there is a previous invocation that failed with an invariant violation. - pub fn finish(self, module_storage: &impl ModuleStorage) -> VMResult { - self.data_cache - .into_effects(module_storage) - .map_err(|e| e.finish(Location::Undefined)) - } - - pub fn finish_with_custom_effects( - self, - resource_converter: &dyn Fn(Value, MoveTypeLayout, bool) -> PartialVMResult, - module_storage: &impl ModuleStorage, - ) -> VMResult> { - self.data_cache - .into_custom_effects(resource_converter, module_storage) - .map_err(|e| e.finish(Location::Undefined)) - } - - /// Same like `finish`, but also extracts the native context extensions from the session. - pub fn finish_with_extensions( - self, - module_storage: &impl ModuleStorage, - ) -> VMResult<(ChangeSet, NativeContextExtensions<'r>)> { - let Session { - data_cache, - native_extensions, - .. - } = self; - let change_set = data_cache - .into_effects(module_storage) - .map_err(|e| e.finish(Location::Undefined))?; - Ok((change_set, native_extensions)) - } - - pub fn finish_with_extensions_with_custom_effects( - self, - resource_converter: &dyn Fn(Value, MoveTypeLayout, bool) -> PartialVMResult, - module_storage: &impl ModuleStorage, - ) -> VMResult<(Changes, NativeContextExtensions<'r>)> { - let Session { - data_cache, - native_extensions, - .. - } = self; - let change_set = data_cache - .into_custom_effects(resource_converter, module_storage) - .map_err(|e| e.finish(Location::Undefined))?; - Ok((change_set, native_extensions)) - } - - /// Gets the underlying native extensions. - pub fn get_native_extensions(&mut self) -> &mut NativeContextExtensions<'r> { - &mut self.native_extensions - } -} diff --git a/third_party/move/move-vm/runtime/src/storage/code_storage.rs b/third_party/move/move-vm/runtime/src/storage/code_storage.rs index aecef2d6ae9..63df008a8d6 100644 --- a/third_party/move/move-vm/runtime/src/storage/code_storage.rs +++ b/third_party/move/move-vm/runtime/src/storage/code_storage.rs @@ -1,125 +1,18 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ - loader::{LoadedFunctionOwner, Script}, - LoadedFunction, ModuleStorage, -}; -use ambassador::delegatable_trait; -use move_binary_format::{ - errors::{Location, PartialVMResult, VMResult}, - file_format::CompiledScript, -}; -use move_core_types::language_storage::TypeTag; -use move_vm_types::{ - code::{Code, ScriptCache}, - loaded_data::runtime_types::Type, - sha3_256, -}; -use std::sync::Arc; +use crate::{loader::Script, ModuleStorage}; +use move_binary_format::file_format::CompiledScript; +use move_vm_types::code::ScriptCache; -/// Represents storage which in addition to modules, also caches scripts. The clients can implement -/// this trait to ensure that even script dependency is upgraded, the correct script is still -/// returned. Scripts are cached based on their hash. -#[delegatable_trait] -pub trait CodeStorage: ModuleStorage { - /// Returns a deserialized script, either by directly deserializing it from the provided bytes - /// (and caching it), or fetching it from the cache. Note that there are no guarantees that the - /// returned script is verified. An error is returned if the deserialization fails. - fn deserialize_and_cache_script( - &self, - serialized_script: &[u8], - ) -> VMResult>; - - /// Returns a verified script. If not yet cached, verified from scratch and cached. An error is - /// returned if script fails to deserialize or verify. - fn verify_and_cache_script(&self, serialized_script: &[u8]) -> VMResult>; - - /// Loads the script: - /// 1. Fetches it from the cache (or deserializes and verifies it if it is not cached). - /// 2. Verifies type arguments (modules that define the type arguments are also loaded). - /// If both steps are successful, returns a [LoadedFunction] corresponding to the script's - /// entrypoint. - fn load_script( - &self, - serialized_script: &[u8], - ty_tag_args: &[TypeTag], - ) -> VMResult { - // Step 1: Load script. During the loading process, if script has not been previously - // cached, it will be verified. - let script = self.verify_and_cache_script(serialized_script)?; - - // Step 2: Load & verify types used as type arguments passed to this script. Note that - // arguments for scripts are verified on the client side. - let ty_args = ty_tag_args - .iter() - .map(|ty_tag| self.fetch_ty(ty_tag)) - .collect::>>() - .map_err(|err| err.finish(Location::Script))?; - - let main = script.entry_point(); - Type::verify_ty_arg_abilities(main.ty_param_abilities(), &ty_args) - .map_err(|err| err.finish(Location::Script))?; - - Ok(LoadedFunction { - owner: LoadedFunctionOwner::Script(script), - ty_args, - function: main, - }) - } +/// Represents storage which in addition to modules, also caches scripts. +pub trait CodeStorage: + ModuleStorage + ScriptCache +{ } -impl CodeStorage for T -where +impl CodeStorage for T where T: ModuleStorage - + ScriptCache, + + ScriptCache { - fn deserialize_and_cache_script( - &self, - serialized_script: &[u8], - ) -> VMResult> { - let hash = sha3_256(serialized_script); - Ok(match self.get_script(&hash) { - Some(script) => script.deserialized().clone(), - None => { - let deserialized_script = self - .runtime_environment() - .deserialize_into_script(serialized_script)?; - self.insert_deserialized_script(hash, deserialized_script) - }, - }) - } - - fn verify_and_cache_script(&self, serialized_script: &[u8]) -> VMResult> { - use Code::*; - - let hash = sha3_256(serialized_script); - let deserialized_script = match self.get_script(&hash) { - Some(Verified(script)) => return Ok(script), - Some(Deserialized(deserialized_script)) => deserialized_script, - None => self - .runtime_environment() - .deserialize_into_script(serialized_script) - .map(Arc::new)?, - }; - - // Locally verify the script. - let locally_verified_script = self - .runtime_environment() - .build_locally_verified_script(deserialized_script)?; - - // Verify the script is correct w.r.t. its dependencies. - let immediate_dependencies = locally_verified_script - .immediate_dependencies_iter() - .map(|(addr, name)| { - // Since module is stored on-chain, we should not see any verification errors here. - self.fetch_existing_verified_module(addr, name) - }) - .collect::>>()?; - let verified_script = self - .runtime_environment() - .build_verified_script(locally_verified_script, &immediate_dependencies)?; - - Ok(self.insert_verified_script(hash, verified_script)) - } } diff --git a/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs b/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs index c00eb46cb2d..a4dd7e34190 100644 --- a/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs +++ b/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs @@ -1,9 +1,9 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{module_traversal::TraversalContext, CodeStorage, ModuleStorage}; +use crate::{module_traversal::TraversalContext, ModuleStorage}; use move_binary_format::{ - access::{ModuleAccess, ScriptAccess}, + access::ModuleAccess, errors::{Location, VMResult}, }; use move_core_types::{ @@ -13,35 +13,12 @@ use move_core_types::{ language_storage::{ModuleId, TypeTag}, }; use move_vm_metrics::{Timer, VM_TIMER}; -use move_vm_types::{ - gas::{DependencyGasMeter, GasMeter}, - module_linker_error, -}; +use move_vm_types::gas::{DependencyGasMeter, DependencyKind}; use std::collections::BTreeSet; -pub fn check_script_dependencies_and_check_gas( - code_storage: &impl CodeStorage, - gas_meter: &mut impl GasMeter, - traversal_context: &mut TraversalContext, - serialized_script: &[u8], -) -> VMResult<()> { - let compiled_script = code_storage.deserialize_and_cache_script(serialized_script)?; - let compiled_script = traversal_context.referenced_scripts.alloc(compiled_script); - - // TODO(Gas): Should we charge dependency gas for the script itself? - check_dependencies_and_charge_gas( - code_storage, - gas_meter, - traversal_context, - compiled_script.immediate_dependencies_iter(), - )?; - - Ok(()) -} - pub fn check_type_tag_dependencies_and_charge_gas( module_storage: &impl ModuleStorage, - gas_meter: &mut impl GasMeter, + gas_meter: &mut impl DependencyGasMeter, traversal_context: &mut TraversalContext, ty_tags: &[TypeTag], ) -> VMResult<()> { @@ -83,8 +60,8 @@ pub fn check_type_tag_dependencies_and_charge_gas( /// `ModuleId`, a.k.a. heap allocations, as much as possible, which is critical for /// performance. pub fn check_dependencies_and_charge_gas<'a, I>( - module_storage: &dyn ModuleStorage, - gas_meter: &mut dyn DependencyGasMeter, + module_storage: &impl ModuleStorage, + gas_meter: &mut impl DependencyGasMeter, traversal_context: &mut TraversalContext<'a>, ids: I, ) -> VMResult<()> @@ -101,11 +78,14 @@ where traversal_context.push_next_ids_to_visit(&mut stack, ids); while let Some((addr, name)) = stack.pop() { - let size = module_storage - .fetch_module_size_in_bytes(addr, name)? - .ok_or_else(|| module_linker_error!(addr, name))?; + let size = module_storage.unmetered_get_existing_module_size(addr, name)?; gas_meter - .charge_dependency(false, addr, name, NumBytes::new(size as u64)) + .charge_dependency( + DependencyKind::Existing, + addr, + name, + NumBytes::new(size as u64), + ) .map_err(|err| err.finish(Location::Module(ModuleId::new(*addr, name.to_owned()))))?; // Extend the lifetime of the module to the remainder of the function body @@ -113,9 +93,8 @@ where // // This is needed because we need to store references derived from it in the // work list. - let compiled_module = module_storage - .fetch_deserialized_module(addr, name)? - .ok_or_else(|| module_linker_error!(addr, name))?; + let compiled_module = + module_storage.unmetered_get_existing_deserialized_module(addr, name)?; let compiled_module = traversal_context.referenced_modules.alloc(compiled_module); // Explore all dependencies and friends that have been visited yet. diff --git a/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs b/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs deleted file mode 100644 index d11d90d4241..00000000000 --- a/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::ModuleStorage; -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::TypeParameterIndex, -}; -use move_core_types::vm_status::StatusCode; -use move_vm_types::loaded_data::{ - runtime_types::{DepthFormula, StructLayout, Type}, - struct_name_indexing::StructNameIndex, -}; -use std::collections::{BTreeMap, HashMap}; - -/// Calculates [DepthFormula] for struct types. Stores a cache of visited formulas. -pub(crate) struct DepthFormulaCalculator<'a, M> { - module_storage: &'a M, - visited_formulas: HashMap, -} - -impl<'a, M> DepthFormulaCalculator<'a, M> -where - M: ModuleStorage, -{ - pub(crate) fn new(module_storage: &'a M) -> Self { - Self { - module_storage, - visited_formulas: HashMap::new(), - } - } - - pub(crate) fn calculate_depth_of_struct( - &mut self, - struct_name_idx: &StructNameIndex, - ) -> PartialVMResult { - if let Some(depth_formula) = self.visited_formulas.get(struct_name_idx) { - return Ok(depth_formula.clone()); - } - - let struct_type = self - .module_storage - .fetch_struct_ty_by_idx(struct_name_idx)?; - let formulas = match &struct_type.layout { - StructLayout::Single(fields) => fields - .iter() - .map(|(_, field_ty)| self.calculate_depth_of_type(field_ty)) - .collect::>>()?, - StructLayout::Variants(variants) => variants - .iter() - .flat_map(|variant| variant.1.iter().map(|(_, ty)| ty)) - .map(|field_ty| self.calculate_depth_of_type(field_ty)) - .collect::>>()?, - }; - - let formula = DepthFormula::normalize(formulas); - if self - .visited_formulas - .insert(*struct_name_idx, formula.clone()) - .is_some() - { - // Same thread has put this entry previously, which means there is a recursion. - let struct_name = self - .module_storage - .runtime_environment() - .struct_name_index_map() - .idx_to_struct_name_ref(*struct_name_idx)?; - return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message( - format!( - "Depth formula for struct '{}' is already cached by the same thread", - struct_name.as_ref(), - ), - ), - ); - } - Ok(formula) - } - - fn calculate_depth_of_type(&mut self, ty: &Type) -> PartialVMResult { - Ok(match ty { - Type::Bool - | Type::U8 - | Type::U64 - | Type::U128 - | Type::Address - | Type::Signer - | Type::U16 - | Type::U32 - | Type::U256 => DepthFormula::constant(1), - Type::Vector(ty) => { - let mut inner = self.calculate_depth_of_type(ty)?; - inner.scale(1); - inner - }, - Type::Reference(ty) | Type::MutableReference(ty) => { - let mut inner = self.calculate_depth_of_type(ty)?; - inner.scale(1); - inner - }, - Type::TyParam(ty_idx) => DepthFormula::type_parameter(*ty_idx), - Type::Struct { idx, .. } => { - let mut struct_formula = self.calculate_depth_of_struct(idx)?; - debug_assert!(struct_formula.terms.is_empty()); - struct_formula.scale(1); - struct_formula - }, - Type::StructInstantiation { idx, ty_args, .. } => { - let ty_arg_map = ty_args - .iter() - .enumerate() - .map(|(idx, ty)| { - let var = idx as TypeParameterIndex; - Ok((var, self.calculate_depth_of_type(ty)?)) - }) - .collect::>>()?; - let struct_formula = self.calculate_depth_of_struct(idx)?; - let mut subst_struct_formula = struct_formula.subst(ty_arg_map)?; - subst_struct_formula.scale(1); - subst_struct_formula - }, - Type::Function { - args, - results, - abilities: _, - } => { - let mut inner = DepthFormula::normalize( - args.iter() - .chain(results) - .map(|arg_ty| self.calculate_depth_of_type(arg_ty)) - .collect::>>()?, - ); - inner.scale(1); - inner - }, - }) - } -} diff --git a/third_party/move/move-vm/runtime/src/storage/environment.rs b/third_party/move/move-vm/runtime/src/storage/environment.rs index 8846e77b633..3d1e73325d7 100644 --- a/third_party/move/move-vm/runtime/src/storage/environment.rs +++ b/third_party/move/move-vm/runtime/src/storage/environment.rs @@ -6,7 +6,7 @@ use crate::{ native_functions::{NativeFunction, NativeFunctions}, storage::{ ty_tag_converter::{TypeTagCache, TypeTagConverter}, - verified_module_cache::VERIFIED_MODULES_V2, + verified_module_cache::VERIFIED_MODULES_CACHE, }, Module, Script, }; @@ -22,18 +22,25 @@ use move_bytecode_verifier::dependencies; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, - language_storage::{ModuleId, TypeTag}, + language_storage::{ModuleId, TypeTag, MEM_MODULE_ID, OPTION_MODULE_ID}, vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, }; -use move_vm_metrics::{Timer, VM_TIMER}; +use move_vm_metrics::{Timer, VERIFIED_MODULE_CACHE_SIZE, VM_TIMER}; #[cfg(any(test, feature = "testing"))] use move_vm_types::loaded_data::{ runtime_types::StructIdentifier, struct_name_indexing::StructNameIndex, }; -use move_vm_types::loaded_data::{runtime_types::Type, struct_name_indexing::StructNameIndexMap}; +use move_vm_types::{ + loaded_data::{runtime_types::Type, struct_name_indexing::StructNameIndexMap}, + module_id_interner::InternedModuleIdPool, + ty_interner::InternedTypePool, +}; use sha3::{Digest, Sha3_256}; use std::sync::Arc; +const OPTION_MODULE_BYTES: &[u8] = include_bytes!("option.mv"); +const MEM_MODULE_BYTES: &[u8] = include_bytes!("mem.mv"); + /// [MoveVM] runtime environment encapsulating different configurations. Shared between the VM and /// the code cache, possibly across multiple threads. pub struct RuntimeEnvironment { @@ -62,7 +69,7 @@ pub struct RuntimeEnvironment { /// SHA3-256 digest of the BCS-serialized [VerifierConfig] from `vm_config`. Precomputed at /// construction time so it can be combined with the module hash to form the - /// [VERIFIED_MODULES_V2] cache key without re-hashing the config on every lookup. + /// [VERIFIED_MODULES_CACHE] cache key without re-hashing the config on every lookup. /// /// Why this exists: the verified-module cache is a process-global LRU shared across all /// runtime environments. Without a per-config component in the key, two threads using @@ -73,6 +80,12 @@ pub struct RuntimeEnvironment { /// Invariant: must stay in line with `vm_config.verifier_config`. Any mutation of `vm_config.verifier_config` must /// recompute this digest. verifier_config_digest: [u8; 32], + + /// Pool of interned type representations. Same lifetime as struct index map. + interned_ty_pool: Arc, + + /// Pool of interned module ids. + interned_module_id_pool: Arc, } impl RuntimeEnvironment { @@ -80,10 +93,21 @@ impl RuntimeEnvironment { /// there are duplicated natives, panics. pub fn new( natives: impl IntoIterator, + ) -> Self { + Self::new_for_move_third_party_tests(natives, true, true) + } + + /// API to control the enum option feature flag depending on whether the caller is from aptos or not + pub fn new_for_move_third_party_tests( + natives: impl IntoIterator, + enable_enum_option: bool, + enable_framework_for_option: bool, ) -> Self { let vm_config = VMConfig { // Keep the paranoid mode on as we most likely want this for tests. paranoid_type_checks: true, + enable_enum_option, + enable_framework_for_option, ..VMConfig::default() }; Self::new_with_config(natives, vm_config) @@ -104,6 +128,8 @@ impl RuntimeEnvironment { struct_name_index_map: Arc::new(StructNameIndexMap::empty()), ty_tag_cache: Arc::new(TypeTagCache::empty()), verifier_config_digest, + interned_ty_pool: Arc::new(InternedTypePool::new()), + interned_module_id_pool: Arc::new(InternedModuleIdPool::new()), } } @@ -112,6 +138,15 @@ impl RuntimeEnvironment { &self.vm_config } + /// Returns the type pool for interning that is currently used by this runtime environment. + pub fn ty_pool(&self) -> &InternedTypePool { + &self.interned_ty_pool + } + + pub fn module_id_pool(&self) -> &InternedModuleIdPool { + &self.interned_module_id_pool + } + /// Enables delayed field optimization for this environment. /// /// Note: this does not change the verifier config, so [Self::verifier_config_digest] is @@ -142,13 +177,19 @@ impl RuntimeEnvironment { immediate_dependencies: &[Arc], ) -> VMResult

{ .verifier .get_public_key(&self.my_addr) .ok_or_else(|| anyhow!("my pk not found in validator set"))?; - let dealer_sk = self.key_storage.consensus_sk_by_pk(my_pk).map_err(|e| { - anyhow!("dkg new epoch handling failed with consensus sk lookup err: {e}") - })?; + let dealer_sk = self + .key_storage + .consensus_sk_by_pk(my_pk.clone()) + .map_err(|e| { + anyhow!("dkg new epoch handling failed with consensus sk lookup err: {e}") + })?; let dkg_manager = DKGManager::::new( Arc::new(dealer_sk), + Arc::new(my_pk), my_index, self.my_addr, epoch_state, diff --git a/dkg/src/transcript_aggregation/tests.rs b/dkg/src/transcript_aggregation/tests.rs index 4270a83e201..a06337d727b 100644 --- a/dkg/src/transcript_aggregation/tests.rs +++ b/dkg/src/transcript_aggregation/tests.rs @@ -56,8 +56,13 @@ fn test_transcript_aggregation_state() { epoch_state, )); - let good_trx_0 = - RealDKG::sample_secret_and_generate_transcript(&mut rng, &pub_params, 0, &private_keys[0]); + let good_trx_0 = RealDKG::sample_secret_and_generate_transcript( + &mut rng, + &pub_params, + 0, + &private_keys[0], + &public_keys[0], + ); let good_trx_0_bytes = bcs::to_bytes(&good_trx_0).unwrap(); // Node with incorrect epoch should be rejected. @@ -118,6 +123,7 @@ fn test_transcript_aggregation_state() { &pub_params, 2, &private_keys[2], + &public_keys[2], ); let result = trx_agg_state.add(addrs[2], DKGTranscript { metadata: DKGTranscriptMetadata { @@ -129,8 +135,13 @@ fn test_transcript_aggregation_state() { assert!(result.is_err()); // Good node should be accepted. - let good_trx_3 = - RealDKG::sample_secret_and_generate_transcript(&mut rng, &pub_params, 3, &private_keys[3]); + let good_trx_3 = RealDKG::sample_secret_and_generate_transcript( + &mut rng, + &pub_params, + 3, + &private_keys[3], + &public_keys[3], + ); let result = trx_agg_state.add(addrs[3], DKGTranscript { metadata: DKGTranscriptMetadata { epoch: 999, @@ -142,8 +153,13 @@ fn test_transcript_aggregation_state() { assert!(matches!(result, Ok(None))); // Repeated contribution should be ignored. - let good_trx_3_another = - RealDKG::sample_secret_and_generate_transcript(&mut rng, &pub_params, 3, &private_keys[3]); + let good_trx_3_another = RealDKG::sample_secret_and_generate_transcript( + &mut rng, + &pub_params, + 3, + &private_keys[3], + &public_keys[3], + ); let result = trx_agg_state.add(addrs[3], DKGTranscript { metadata: DKGTranscriptMetadata { epoch: 999, @@ -154,8 +170,13 @@ fn test_transcript_aggregation_state() { assert!(matches!(result, Ok(None))); // Aggregated trx should be returned if after adding a node, the threshold is exceeded. - let good_trx_4 = - RealDKG::sample_secret_and_generate_transcript(&mut rng, &pub_params, 4, &private_keys[4]); + let good_trx_4 = RealDKG::sample_secret_and_generate_transcript( + &mut rng, + &pub_params, + 4, + &private_keys[4], + &public_keys[4], + ); let result = trx_agg_state.add(addrs[4], DKGTranscript { metadata: DKGTranscriptMetadata { epoch: 999, diff --git a/docker/aptos-debugger/README.md b/docker/aptos-debugger/README.md index 06af3fdfcf8..7758bb119df 100644 --- a/docker/aptos-debugger/README.md +++ b/docker/aptos-debugger/README.md @@ -24,7 +24,7 @@ From the repository root: just container-build aptos-debugger latest release # Verify -docker run --rm ghcr.io/movementlabsxyz/aptos-debugger:latest --version +docker run --rm ghcr.io/movement-network/aptos-debugger:latest --version ``` ## Pushing to GHCR @@ -34,14 +34,14 @@ docker run --rm ghcr.io/movementlabsxyz/aptos-debugger:latest --version docker login ghcr.io -u # Push -docker push ghcr.io/movementlabsxyz/aptos-debugger:latest +docker push ghcr.io/movement-network/aptos-debugger:latest ``` ## CI The `build-versions.yaml` workflow automatically builds and pushes this image on every push to the default branch. The image is tagged with the short git SHA -(e.g., `ghcr.io/movementlabsxyz/aptos-debugger:f24a5bc`). +(e.g., `ghcr.io/movement-network/aptos-debugger:f24a5bc`). ## Runtime Dependencies diff --git a/docker/builder/README.md b/docker/builder/README.md index 4873049e1d5..0263c49c197 100644 --- a/docker/builder/README.md +++ b/docker/builder/README.md @@ -21,10 +21,9 @@ The builder can produce the following Docker images. To build a particular image 2. `validator` : Image containing the `aptos-node` and `aptos-debugger` binaries. This image is usually used for distribution. 3. `tools`: Image containing all the aptos tools binaries including `aptos-debugger`, `aptos`, `aptos-transaction-emitter`, `aptos-openapi-spec-generator` and `aptos-fn-check-client`. Also, includes the Aptos Move framework for use with genesis generation. 4. `forge`: Image containing the `forge` binary that orchestrates and runs Forge tests. -5. `node-checker`: Image containing the `node-checker` binary that checks the health of a node. -6. `faucet`: Image containing the `faucet` binary that provides a faucet service for minting coins. -7. `indexer-grpc`: Image containing the `indexer-grpc` binary that indexes the blockchain and provides a gRPC service for querying. -8. `telemetry-service`: Image containing the `telemetry-service` binary that collects telemetry from blockchain nodes. +5. `faucet`: Image containing the `faucet` binary that provides a faucet service for minting coins. +6. `indexer-grpc`: Image containing the `indexer-grpc` binary that indexes the blockchain and provides a gRPC service for querying. +7. `telemetry-service`: Image containing the `telemetry-service` binary that collects telemetry from blockchain nodes. ## How the builder works diff --git a/docker/builder/build-indexer.sh b/docker/builder/build-indexer.sh index 9b86b7c1cc8..1d781a19370 100755 --- a/docker/builder/build-indexer.sh +++ b/docker/builder/build-indexer.sh @@ -19,6 +19,7 @@ cargo build --locked --profile=$PROFILE \ -p aptos-indexer-grpc-file-checker \ -p aptos-indexer-grpc-data-service-v2 \ -p aptos-indexer-grpc-manager \ + -p aptos-indexer-grpc-gateway \ "$@" # After building, copy the binaries we need to `dist` since the `target` directory is used as docker cache mount and only available during the RUN step @@ -30,6 +31,7 @@ BINS=( aptos-indexer-grpc-file-checker aptos-indexer-grpc-data-service-v2 aptos-indexer-grpc-manager + aptos-indexer-grpc-gateway ) mkdir dist diff --git a/docker/builder/build-tools.sh b/docker/builder/build-tools.sh index 4353994aec6..bb47cce33d8 100755 --- a/docker/builder/build-tools.sh +++ b/docker/builder/build-tools.sh @@ -3,7 +3,11 @@ # SPDX-License-Identifier: Apache-2.0 set -e -PROFILE=cli +# We usually just need to build with `cli` profile, but building `aptos-debugger` +# with `performance` profile helps speed up replay-verify. +if [[ "${PROFILE}" != "performance" ]]; then + PROFILE=cli +fi echo "Building tools and services docker images" echo "PROFILE: $PROFILE" @@ -14,28 +18,24 @@ cargo build --locked --profile=$PROFILE \ -p aptos \ -p aptos-backup-cli \ -p aptos-faucet-service \ - -p aptos-fn-check-client \ - -p aptos-node-checker \ -p aptos-openapi-spec-generator \ -p aptos-telemetry-service \ -p aptos-keyless-pepper-service \ -p aptos-debugger \ -p aptos-transaction-emitter \ - -p aptos-api-tester \ + -p aptos-release-builder \ "$@" # After building, copy the binaries we need to `dist` since the `target` directory is used as docker cache mount and only available during the RUN step BINS=( aptos aptos-faucet-service - aptos-node-checker aptos-openapi-spec-generator aptos-telemetry-service aptos-keyless-pepper-service - aptos-fn-check-client aptos-debugger aptos-transaction-emitter - aptos-api-tester + aptos-release-builder ) mkdir dist diff --git a/docker/builder/builder.Dockerfile b/docker/builder/builder.Dockerfile index c639bf2dc6a..fb617405918 100644 --- a/docker/builder/builder.Dockerfile +++ b/docker/builder/builder.Dockerfile @@ -5,21 +5,30 @@ WORKDIR /aptos RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +ARG CLANG_VERSION=20 RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ - sed -i 's|http://deb.debian.org/debian|http://cloudfront.debian.net/debian|g' /etc/apt/sources.list && \ - apt update && apt-get --no-install-recommends install -y \ + sed -i 's|http://deb.debian.org/debian|http://cloudfront.debian.net/debian|g' /etc/apt/sources.list \ + && apt update \ + && apt-get --no-install-recommends install -y \ binutils \ - clang \ cmake \ curl \ git \ + gnupg \ libdw-dev \ libpq-dev \ libssl-dev \ libudev-dev \ lld \ - pkg-config + lsb-release \ + pkg-config \ + software-properties-common \ + wget \ + && bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" llvm.sh ${CLANG_VERSION} \ + && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${CLANG_VERSION} 100 \ + && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANG_VERSION} 100 + ### Build Rust code ### FROM rust-base as builder-base diff --git a/docker/builder/docker-bake-rust-all.hcl b/docker/builder/docker-bake-rust-all.hcl index b42eeb32c18..fc9af2bf736 100644 --- a/docker/builder/docker-bake-rust-all.hcl +++ b/docker/builder/docker-bake-rust-all.hcl @@ -49,7 +49,6 @@ variable "CARGO_TARGET_DIR" { group "all" { targets = flatten([ "validator", - "node-checker", "tools", "faucet", "forge", @@ -69,7 +68,7 @@ target "debian-base" { dockerfile = "docker/builder/debian-base.Dockerfile" contexts = { # Run `docker buildx imagetools inspect debian:bullseye` to find the latest multi-platform hash - debian = "docker-image://debian:bullseye@sha256:cf48c31af360e1c0a0aedd33aae4d928b68c2cdf093f1612650eb1ff434d1c34" + debian = "docker-image://debian:bullseye@sha256:25c0cab214b810db1b3c8adef5a12a92596979abddf86bb364e8d9c9d111df9f" } } @@ -182,14 +181,6 @@ target "tools" { target = "tools" tags = generate_tags("tools") } - -target "node-checker" { - inherits = ["_common"] - dockerfile = "docker/builder/node-checker.Dockerfile" - target = "node-checker" - tags = generate_tags("node-checker") -} - target "faucet" { inherits = ["_common"] dockerfile = "docker/builder/faucet.Dockerfile" diff --git a/docker/builder/indexer-grpc.Dockerfile b/docker/builder/indexer-grpc.Dockerfile index 93ac77eb991..609b92f2349 100644 --- a/docker/builder/indexer-grpc.Dockerfile +++ b/docker/builder/indexer-grpc.Dockerfile @@ -8,6 +8,7 @@ COPY --link --from=indexer-builder /aptos/dist/aptos-indexer-grpc-data-service / COPY --link --from=indexer-builder /aptos/dist/aptos-indexer-grpc-file-checker /usr/local/bin/aptos-indexer-grpc-file-checker COPY --link --from=indexer-builder /aptos/dist/aptos-indexer-grpc-data-service-v2 /usr/local/bin/aptos-indexer-grpc-data-service-v2 COPY --link --from=indexer-builder /aptos/dist/aptos-indexer-grpc-manager /usr/local/bin/aptos-indexer-grpc-manager +COPY --link --from=indexer-builder /aptos/dist/aptos-indexer-grpc-gateway /usr/local/bin/aptos-indexer-grpc-gateway # The health check port EXPOSE 8080 diff --git a/docker/builder/node-checker.Dockerfile b/docker/builder/node-checker.Dockerfile deleted file mode 100644 index 29941eac85c..00000000000 --- a/docker/builder/node-checker.Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -### Node Checker Image ### - -FROM debian-base AS node-checker - -COPY --link --from=tools-builder /aptos/dist/aptos-node-checker /usr/local/bin/aptos-node-checker - -ENV RUST_LOG_FORMAT=json - -# add build info -ARG BUILD_DATE -ENV BUILD_DATE ${BUILD_DATE} -ARG GIT_TAG -ENV GIT_TAG ${GIT_TAG} -ARG GIT_BRANCH -ENV GIT_BRANCH ${GIT_BRANCH} -ARG GIT_SHA -ENV GIT_SHA ${GIT_SHA} diff --git a/docker/builder/tools.Dockerfile b/docker/builder/tools.Dockerfile index 16f2c1a3f74..f8b44041527 100644 --- a/docker/builder/tools.Dockerfile +++ b/docker/builder/tools.Dockerfile @@ -30,9 +30,12 @@ RUN cd /usr/local/bin && wget "https://storage.googleapis.com/kubernetes-release COPY --link --from=tools-builder /aptos/dist/aptos-debugger /usr/local/bin/aptos-debugger COPY --link --from=tools-builder /aptos/dist/aptos /usr/local/bin/aptos COPY --link --from=tools-builder /aptos/dist/aptos-openapi-spec-generator /usr/local/bin/aptos-openapi-spec-generator -COPY --link --from=tools-builder /aptos/dist/aptos-fn-check-client /usr/local/bin/aptos-fn-check-client COPY --link --from=tools-builder /aptos/dist/aptos-transaction-emitter /usr/local/bin/aptos-transaction-emitter -COPY --link --from=tools-builder /aptos/dist/aptos-api-tester /usr/local/bin/aptos-api-tester +COPY --link --from=tools-builder /aptos/dist/aptos-release-builder /usr/local/bin/aptos-release-builder + +# For the release builder +COPY --link --from=tools-builder /aptos/aptos-move/framework/ /aptos/aptos-move/framework/ +COPY --link --from=tools-builder /aptos/aptos-move/aptos-release-builder/ /aptos/aptos-move/aptos-release-builder/ # Copy the example module to publish for api-tester COPY --link --from=tools-builder /aptos/aptos-move/framework/aptos-framework /aptos-move/framework/aptos-framework diff --git a/docker/image-helpers.js b/docker/image-helpers.js index ed9b589cc23..e4005d9d5ed 100644 --- a/docker/image-helpers.js +++ b/docker/image-helpers.js @@ -122,8 +122,36 @@ export const CargoBuildProfiles = { Performance: "performance", } +export function getImagesToWaitFor(args) { + const perfImages = ["validator", "validator-testing"]; + const images = ["forge", "tools", "indexer-grpc"]; + const imagesToWaitFor = {}; + for (const image of [...perfImages, ...images]) { + const imageConfig = {}; + + if (args.PROFILE_RELEASE) { + imageConfig[CargoBuildProfiles.Release] = [CargoBuildFeatures.Default]; + } + + if (perfImages.includes(image)) { + if (args.PROFILE_PERF) { + imageConfig[CargoBuildProfiles.Performance] = [CargoBuildFeatures.Default]; + } + + if (args.FEATURE_FAILPOINTS) { + if (imageConfig[CargoBuildProfiles.Release] !== undefined) { + imageConfig[CargoBuildProfiles.Release].push(CargoBuildFeatures.Failpoints); + } else { + imageConfig[CargoBuildProfiles.Release] = [CargoBuildFeatures.Failpoints]; + } + } + } + imagesToWaitFor[image] = imageConfig; + } + return imagesToWaitFor; +} -export function parseArgsFromFlagOrEnv(requiredArgs, optionalArgs) { +export function parseArgsFromFlagOrEnv(requiredArgs, optionalArgs, booleanArgs) { const parsedArgs = {}; for (const arg of requiredArgs) { @@ -140,6 +168,12 @@ export function parseArgsFromFlagOrEnv(requiredArgs, optionalArgs) { parsedArgs[arg] = argValue; } + for (const arg of booleanArgs) { + const argExists = (argv[arg.toLowerCase().replaceAll("_", "-")] !== undefined) || + (process.env[arg] === "true"); + parsedArgs[arg] = argExists; + } + return parsedArgs; } diff --git a/docker/release-images.mjs b/docker/release-images.mjs index 4e2f3afe814..1286a04b886 100755 --- a/docker/release-images.mjs +++ b/docker/release-images.mjs @@ -37,8 +37,6 @@ import { assertExecutingInRepoRoot, CargoBuildFeatures, CargoBuildProfiles, - Environment, - getEnvironment, installCrane, lazyImports, parseArgsFromFlagOrEnv, @@ -50,84 +48,50 @@ import { // When we release aptos-node, we also want to release related images for tooling, testing, etc. Similarly, other images have other related images // that we can release together, ie in a release group. const IMAGES_TO_RELEASE_BY_RELEASE_GROUP = { - "aptos-node": [ - "validator", - "validator-testing", - "faucet", - "tools", - ], - "aptos-indexer-grpc": [ - "indexer-grpc", - ], -} + "aptos-node": ["validator", "validator-testing", "faucet", "tools"], + "aptos-indexer-grpc": ["indexer-grpc"], +}; const IMAGE_NAMES_TO_RELEASE_ONLY_INTERNAL = ["validator-testing"]; const IMAGES_TO_RELEASE = { validator: { - [CargoBuildProfiles.Performance]: [ - CargoBuildFeatures.Default, - ], - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], + [CargoBuildProfiles.Performance]: [CargoBuildFeatures.Default], + [CargoBuildProfiles.Release]: [CargoBuildFeatures.Default], }, "validator-testing": { - [CargoBuildProfiles.Performance]: [ - CargoBuildFeatures.Default, - ], - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], + [CargoBuildProfiles.Performance]: [CargoBuildFeatures.Default], + [CargoBuildProfiles.Release]: [CargoBuildFeatures.Default], }, faucet: { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], - }, - forge: { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], + [CargoBuildProfiles.Release]: [CargoBuildFeatures.Default], }, tools: { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], - }, - "node-checker": { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], + [CargoBuildProfiles.Release]: [CargoBuildFeatures.Default], }, "indexer-grpc": { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], + [CargoBuildProfiles.Release]: [CargoBuildFeatures.Default], }, }; - async function main() { const REQUIRED_ARGS = ["GIT_SHA", "GCP_DOCKER_ARTIFACT_REPO", "AWS_ACCOUNT_ID", "IMAGE_TAG_PREFIX"]; const OPTIONAL_ARGS = ["WAIT_FOR_IMAGE_SECONDS", "DRY_RUN"]; + const BOOLEAN_ARGS = ["PROFILE_RELEASE"]; - const parsedArgs = parseArgsFromFlagOrEnv(REQUIRED_ARGS, OPTIONAL_ARGS); + const parsedArgs = parseArgsFromFlagOrEnv(REQUIRED_ARGS, OPTIONAL_ARGS, BOOLEAN_ARGS); await assertExecutingInRepoRoot(); const crane = await installCrane(); const craneVersion = await $`${crane} version`; console.log(`INFO: crane version: ${craneVersion}`); - + const AWS_ECR = `${parsedArgs.AWS_ACCOUNT_ID}.dkr.ecr.us-west-2.amazonaws.com/aptos`; const GCP_ARTIFACT_REPO = parsedArgs.GCP_DOCKER_ARTIFACT_REPO; const DOCKERHUB = "docker.io/aptoslabs"; const INTERNAL_TARGET_REGISTRIES = [GCP_ARTIFACT_REPO, AWS_ECR]; - const ALL_TARGET_REGISTRIES = [ - ...INTERNAL_TARGET_REGISTRIES, - DOCKERHUB, - ]; + const ALL_TARGET_REGISTRIES = [...INTERNAL_TARGET_REGISTRIES, DOCKERHUB]; // default 10 seconds parsedArgs.WAIT_FOR_IMAGE_SECONDS = parseInt(parsedArgs.WAIT_FOR_IMAGE_SECONDS ?? 10, 10); @@ -154,7 +118,9 @@ async function main() { const profilePrefix = profile === "release" ? "" : profile; for (const feature of features) { const featureSuffix = feature === CargoBuildFeatures.Default ? "" : feature; - const targetRegistries = IMAGE_NAMES_TO_RELEASE_ONLY_INTERNAL.includes(image) ? INTERNAL_TARGET_REGISTRIES : ALL_TARGET_REGISTRIES; + const targetRegistries = IMAGE_NAMES_TO_RELEASE_ONLY_INTERNAL.includes(image) + ? INTERNAL_TARGET_REGISTRIES + : ALL_TARGET_REGISTRIES; for (const targetRegistry of targetRegistries) { const imageSource = `${parsedArgs.GCP_DOCKER_ARTIFACT_REPO}/${image}:${joinTagSegments( @@ -162,7 +128,11 @@ async function main() { featureSuffix, parsedArgs.GIT_SHA, )}`; - const imageTarget = `${targetRegistry}/${image}:${joinTagSegments(parsedArgs.IMAGE_TAG_PREFIX, profilePrefix, featureSuffix)}`; + const imageTarget = `${targetRegistry}/${image}:${joinTagSegments( + parsedArgs.IMAGE_TAG_PREFIX, + profilePrefix, + featureSuffix, + )}`; await waitForImageToBecomeAvailable(imageSource, parsedArgs.WAIT_FOR_IMAGE_SECONDS); if (parsedArgs.DRY_RUN) { console.info(chalk.yellow(`INFO: skipping copy of ${imageSource} to ${imageTarget} due to dry run`)); @@ -193,12 +163,11 @@ export function getImageReleaseGroupByImageTagPrefix(prefix) { return "aptos-node"; } - // This prevents tests from executing main if (import.meta.jest === undefined) { pnpmInstall(); await lazyImports(); - await main() + await main(); } else { // Because we do this weird import in order to test we also have to resolve imports // However we force the caller to actually install pnpm first here diff --git a/docker/wait-images-ci.mjs b/docker/wait-images-ci.mjs index 4cc8a73de6b..27d552b4317 100755 --- a/docker/wait-images-ci.mjs +++ b/docker/wait-images-ci.mjs @@ -15,61 +15,31 @@ import { pnpmInstall, waitForImageToBecomeAvailable, joinTagSegments, + getImagesToWaitFor, } from "./image-helpers.js"; -const IMAGES_TO_WAIT_FOR = { - validator: { - [CargoBuildProfiles.Performance]: [ - CargoBuildFeatures.Default, - ], - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - CargoBuildFeatures.Failpoints, - ], - }, - "validator-testing": { - [CargoBuildProfiles.Performance]: [ - CargoBuildFeatures.Default, - ], - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - CargoBuildFeatures.Failpoints, - ], - }, - forge: { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], - }, - tools: { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], - }, - "indexer-grpc": { - [CargoBuildProfiles.Release]: [ - CargoBuildFeatures.Default, - ], - }, -}; - - async function main() { const REQUIRED_ARGS = ["GIT_SHA", "GCP_DOCKER_ARTIFACT_REPO"]; const OPTIONAL_ARGS = ["WAIT_FOR_IMAGE_SECONDS"]; + const BOOLEAN_ARGS = ["PROFILE_RELEASE", "PROFILE_PERF", "FEATURE_FAILPOINTS"]; - const parsedArgs = parseArgsFromFlagOrEnv(REQUIRED_ARGS, OPTIONAL_ARGS); + const parsedArgs = parseArgsFromFlagOrEnv(REQUIRED_ARGS, OPTIONAL_ARGS, BOOLEAN_ARGS); + + // if none are set, check all images + if (!parsedArgs.PROFILE_RELEASE && !parsedArgs.PROFILE_PERF && !parsedArgs.FEATURE_FAILPOINTS) { + parsedArgs.PROFILE_RELEASE = parsedArgs.PROFILE_PERF = parsedArgs.FEATURE_FAILPOINTS = true; + } await assertExecutingInRepoRoot(); await installCrane(); - const GCP_ARTIFACT_REPO = parsedArgs.GCP_DOCKER_ARTIFACT_REPO; - + const imagesToWaitFor = getImagesToWaitFor(parsedArgs); + // default 10 seconds parsedArgs.WAIT_FOR_IMAGE_SECONDS = parseInt(parsedArgs.WAIT_FOR_IMAGE_SECONDS ?? 10, 10); // iterate over all images to wait for - for (const [image, imageConfig] of Object.entries(IMAGES_TO_WAIT_FOR)) { + for (const [image, imageConfig] of Object.entries(imagesToWaitFor)) { for (const [profile, features] of Object.entries(imageConfig)) { // build profiles that are not the default "release" will have a separate prefix const profilePrefix = profile === CargoBuildProfiles.Release ? "" : profile; diff --git a/ecosystem/indexer-grpc/indexer-grpc-cache-worker/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-cache-worker/Cargo.toml index 26dff4e0200..8ba54bdd1fa 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-cache-worker/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-cache-worker/Cargo.toml @@ -33,10 +33,7 @@ tracing = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [dev-dependencies] aptos-config = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-cache-worker/src/worker.rs b/ecosystem/indexer-grpc/indexer-grpc-cache-worker/src/worker.rs index a29fc31353a..3b7260e6a79 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-cache-worker/src/worker.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-cache-worker/src/worker.rs @@ -418,7 +418,7 @@ async fn process_streaming_response( let result = join_all(tasks_to_run).await; if result .iter() - .any(|r| (r.is_err() || r.as_ref().unwrap().is_err())) + .any(|r| r.is_err() || r.as_ref().unwrap().is_err()) { error!( start_version = start_version, diff --git a/ecosystem/indexer-grpc/indexer-grpc-data-service-v2/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-data-service-v2/Cargo.toml index a9d2ad54ec9..ac78f58546e 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-data-service-v2/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-data-service-v2/Cargo.toml @@ -38,7 +38,4 @@ uuid = { workspace = true } warp = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-data-service/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-data-service/Cargo.toml index d9f83b2a440..2e8ee41f6f2 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-data-service/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-data-service/Cargo.toml @@ -37,7 +37,4 @@ tracing = { workspace = true } uuid = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-data-service/src/service.rs b/ecosystem/indexer-grpc/indexer-grpc-data-service/src/service.rs index 9b229dd1137..dbfd0a7421e 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-data-service/src/service.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-data-service/src/service.rs @@ -181,7 +181,7 @@ impl RawData for RawDataServerWrapper { SERVICE_TYPE, IndexerGrpcStep::DataServiceNewRequestReceived, Some(current_version as i64), - transactions_count.map(|v| (v as i64 + current_version as i64 - 1)), + transactions_count.map(|v| v as i64 + current_version as i64 - 1), None, None, None, @@ -612,8 +612,7 @@ fn ensure_sequential_transactions(mut batches: Vec>) -> Vec= end_version { diff --git a/ecosystem/indexer-grpc/indexer-grpc-file-checker/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-file-checker/Cargo.toml index 7b2f5b92c74..078984e2739 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-file-checker/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-file-checker/Cargo.toml @@ -27,7 +27,4 @@ tokio = { workspace = true } tracing = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller/Cargo.toml index 8047b1fe846..399ddb7c3f0 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-file-store-backfiller/Cargo.toml @@ -28,7 +28,4 @@ tracing = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-file-store/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-file-store/Cargo.toml index 60ccd1cdcf5..57d4eed5e86 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-file-store/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-file-store/Cargo.toml @@ -28,7 +28,4 @@ tokio = { workspace = true } tracing = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs index c1e37220f88..6c3141d4655 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs @@ -60,6 +60,7 @@ pub fn convert_move_struct(move_struct: &MoveStruct) -> transaction::MoveStruct name: move_struct.name.0.to_string(), is_native: move_struct.is_native, is_event: move_struct.is_event, + is_enum: move_struct.is_enum, abilities: move_struct .abilities .iter() @@ -271,6 +272,15 @@ pub fn convert_move_type(move_type: &MoveType) -> transaction::MoveType { MoveType::Reference { .. } => transaction::MoveTypes::Reference, MoveType::Function { .. } => transaction::MoveTypes::Unparsable, MoveType::Unparsable(_) => transaction::MoveTypes::Unparsable, + MoveType::I8 + | MoveType::I16 + | MoveType::I32 + | MoveType::I64 + | MoveType::I128 + | MoveType::I256 => { + //TODO(#17645): support signed integers + transaction::MoveTypes::Unparsable + }, }; let content = match move_type { MoveType::Bool => None, @@ -303,6 +313,15 @@ pub fn convert_move_type(move_type: &MoveType) -> transaction::MoveType { MoveType::Unparsable(string) => { Some(transaction::move_type::Content::Unparsable(string.clone())) }, + MoveType::I8 + | MoveType::I16 + | MoveType::I32 + | MoveType::I64 + | MoveType::I128 + | MoveType::I256 => { + //TODO(#17645): make sure `None` is enough here + None + }, }; transaction::MoveType { r#type: r#type as i32, @@ -708,10 +727,10 @@ pub fn convert_account_signature( "[Indexer Fullnode] Indexer should never see transactions with NoAccountSignature" ) }, - AccountSignature::AbstractionSignature(s) => ( + AccountSignature::AbstractSignature(s) => ( transaction::account_signature::Type::Abstraction, transaction::account_signature::Signature::Abstraction( - transaction::AbstractionSignature { + transaction::AbstractSignature { function_info: s.function_info.to_owned(), signature: s.auth_data.inner().to_owned(), }, diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/fullnode_data_service.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/fullnode_data_service.rs index 567c5b69e53..d4535463ee8 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/fullnode_data_service.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/fullnode_data_service.rs @@ -23,6 +23,10 @@ use aptos_protos::{ use futures::Stream; use std::{ pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, time::{Duration, SystemTime, UNIX_EPOCH}, }; use tokio::sync::mpsc; @@ -31,6 +35,13 @@ use tonic::{Request, Response, Status}; pub struct FullnodeDataService { pub service_context: ServiceContext, + pub abort_handle: Arc, +} + +impl Drop for FullnodeDataService { + fn drop(&mut self) { + println!("**** Dropping FullnodeDataService. ****"); + } } type FullnodeResponseStream = @@ -60,7 +71,10 @@ impl FullnodeData for FullnodeDataService { ) -> Result, Status> { // Gets configs for the stream, partly from the request and partly from the node config let r = req.into_inner(); - let starting_version = r.starting_version.expect("Starting version must be set"); + let starting_version = match r.starting_version { + Some(version) => version, + None => return Err(Status::invalid_argument("Starting version must be set")), + }; let processor_task_count = self.service_context.processor_task_count; let processor_batch_size = self.service_context.processor_batch_size; let output_batch_size = self.service_context.output_batch_size; @@ -80,6 +94,7 @@ impl FullnodeData for FullnodeDataService { // Creates a moving average to track tps let mut ma = MovingAverage::new(10_000); + let abort_handle = self.abort_handle.clone(); // This is the main thread handling pushing to the stream tokio::spawn(async move { // Initialize the coordinator that tracks starting version and processes transactions @@ -91,6 +106,7 @@ impl FullnodeData for FullnodeDataService { processor_batch_size, output_batch_size, tx.clone(), + Some(abort_handle.clone()), ); // Sends init message (one time per request) to the client in the with chain id and starting version. Basically a handshake let init_status = get_status(StatusType::Init, starting_version, None, ledger_chain_id); @@ -113,6 +129,10 @@ impl FullnodeData for FullnodeDataService { let start_time = std::time::Instant::now(); // Processes and sends batch of transactions to client let results = coordinator.process_next_batch().await; + if abort_handle.load(Ordering::SeqCst) { + info!("FullnodeDataService is aborted."); + break; + } if results.is_empty() { info!( start_version = starting_version, diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/localnet_data_service.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/localnet_data_service.rs index c1f0a1c576f..d01dc43baf9 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/localnet_data_service.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/localnet_data_service.rs @@ -39,7 +39,10 @@ impl RawData for LocalnetDataService { // Some node metadata let context = self.service_context.context.clone(); let r = req.into_inner(); - let starting_version = r.starting_version.expect("Starting version must be set"); + let starting_version = match r.starting_version { + Some(version) => version, + None => return Err(Status::invalid_argument("Starting version must be set")), + }; let ending_version = if let Some(count) = r.transactions_count { starting_version.saturating_add(count) } else { @@ -65,6 +68,7 @@ impl RawData for LocalnetDataService { processor_batch_size, output_batch_size, tx.clone(), + None, ); while coordinator.current_version < coordinator.end_version { // Processes and sends batch of transactions to client diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/runtime.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/runtime.rs index 43e850efee1..78dd1d4fd44 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/runtime.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/runtime.rs @@ -20,7 +20,7 @@ use aptos_protos::{ use aptos_storage_interface::DbReader; use aptos_types::{chain_id::ChainId, indexer::indexer_db_reader::IndexerReader}; use futures::channel::oneshot; -use std::sync::Arc; +use std::sync::{atomic::AtomicBool, Arc}; use tokio::{net::TcpListener, runtime::Runtime}; use tonic::{ codec::CompressionEncoding, @@ -72,6 +72,7 @@ pub fn bootstrap( // If we are here, we know indexer grpc is enabled. let server = FullnodeDataService { service_context: service_context.clone(), + abort_handle: Arc::new(AtomicBool::new(false)), }; let localnet_data_server = LocalnetDataService { service_context }; diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/stream_coordinator.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/stream_coordinator.rs index 2e9021f4fcc..62352cbc9e0 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/stream_coordinator.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/stream_coordinator.rs @@ -25,7 +25,13 @@ use aptos_protos::{ }; use itertools::Itertools; use serde::Serialize; -use std::{sync::Arc, time::Duration}; +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, +}; use tokio::sync::mpsc; use tonic::Status; @@ -44,6 +50,7 @@ pub struct IndexerStreamCoordinator { pub highest_known_version: u64, pub context: Arc, pub transactions_sender: mpsc::Sender>, + abort_handle: Option>, } // Single batch of transactions to fetch, convert, and stream @@ -64,6 +71,7 @@ impl IndexerStreamCoordinator { processor_batch_size: u16, output_batch_size: u16, transactions_sender: mpsc::Sender>, + abort_handle: Option>, ) -> Self { Self { current_version: request_start_version, @@ -74,6 +82,7 @@ impl IndexerStreamCoordinator { highest_known_version: 0, context, transactions_sender, + abort_handle, } } @@ -90,6 +99,9 @@ impl IndexerStreamCoordinator { // Stage 1: fetch transactions from storage. let sorted_transactions_from_storage_with_size = self.fetch_transactions_from_storage().await; + if sorted_transactions_from_storage_with_size.is_empty() { + return vec![]; + } let first_version = sorted_transactions_from_storage_with_size .first() .map(|(txn, _)| txn.version) @@ -264,7 +276,9 @@ impl IndexerStreamCoordinator { /// This will create batches based on the configuration of the request async fn get_batches(&mut self) -> Vec { - self.ensure_highest_known_version().await; + if !self.ensure_highest_known_version().await { + return vec![]; + } let mut starting_version = self.current_version; let mut num_fetches = 0; @@ -518,9 +532,14 @@ impl IndexerStreamCoordinator { /// Will keep looping and checking the latest ledger info to see if there are new transactions /// If there are, it will set the highest known version - async fn ensure_highest_known_version(&mut self) { + async fn ensure_highest_known_version(&mut self) -> bool { let mut empty_loops = 0; while self.highest_known_version == 0 || self.current_version > self.highest_known_version { + if let Some(abort_handle) = self.abort_handle.as_ref() { + if abort_handle.load(Ordering::SeqCst) { + return false; + } + } if empty_loops > 0 { tokio::time::sleep(Duration::from_millis(RETRY_TIME_MILLIS)).await; } @@ -541,5 +560,6 @@ impl IndexerStreamCoordinator { ); } } + true } } diff --git a/ecosystem/indexer-grpc/indexer-grpc-gateway/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-gateway/Cargo.toml new file mode 100644 index 00000000000..562c17d4943 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-gateway/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "aptos-indexer-grpc-gateway" +description = "Aptos Indexer gRPC Gateway" +version = "1.0.0" + +# Workspace inherited keys +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +anyhow = { workspace = true } +aptos-indexer-grpc-server-framework = { workspace = true } +aptos-protos = { workspace = true } +async-trait = { workspace = true } +axum = { workspace = true } +clap = { workspace = true } +futures = { workspace = true } +http-body-util = { workspace = true } +hyper-util = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true } +tonic = { workspace = true } +tracing = { workspace = true } +url = { workspace = true } + +[target.'cfg(unix)'.dependencies] +jemallocator = { version = "0.5.0", features = [ + "profiling", + "unprefixed_malloc_on_supported_platforms", +] } diff --git a/ecosystem/indexer-grpc/indexer-grpc-gateway/src/config.rs b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/config.rs new file mode 100644 index 00000000000..0975eee990a --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/config.rs @@ -0,0 +1,38 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::gateway::GrpcGateway; +use aptos_indexer_grpc_server_framework::RunnableConfig; +use serde::{Deserialize, Serialize}; +use tokio::sync::OnceCell; + +pub(crate) static GRPC_GATEWAY: OnceCell = OnceCell::const_new(); + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct IndexerGrpcGatewayConfig { + #[serde(default = "IndexerGrpcGatewayConfig::default_port")] + pub(crate) port: u16, + pub(crate) grpc_manager_address: String, +} + +impl IndexerGrpcGatewayConfig { + const fn default_port() -> u16 { + 8080 + } +} + +#[async_trait::async_trait] +impl RunnableConfig for IndexerGrpcGatewayConfig { + async fn run(&self) -> anyhow::Result<()> { + GRPC_GATEWAY + .get_or_init(|| async { GrpcGateway::new(self.clone()) }) + .await + .start() + .await + } + + fn get_server_name(&self) -> String { + "grpc_gateway".to_string() + } +} diff --git a/ecosystem/indexer-grpc/indexer-grpc-gateway/src/gateway.rs b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/gateway.rs new file mode 100644 index 00000000000..2aa1d1e635e --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/gateway.rs @@ -0,0 +1,176 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::IndexerGrpcGatewayConfig; +use anyhow::Context; +use aptos_protos::indexer::v1::{ + grpc_manager_client::GrpcManagerClient, GetDataServiceForRequestRequest, + GetDataServiceForRequestResponse, GetTransactionsRequest, +}; +use axum::{ + extract::{Request, State}, + http::{StatusCode, Uri}, + middleware::{from_fn_with_state, Next}, + response::Response, + routing::any, + Extension, Router, +}; +use futures::TryStreamExt; +use http_body_util::{BodyExt, Full}; +use hyper_util::{client::legacy::Client, rt::TokioExecutor}; +use std::{str::FromStr, sync::Arc}; +use tonic::{ + codec::{Codec, CompressionEncoding, ProstCodec}, + Streaming, +}; +use tracing::info; +use url::Url; + +const LISTEN_ADDRESS: &str = "0.0.0.0"; +const ENCODING_HEADER: &str = "grpc-encoding"; + +pub(crate) struct GrpcGateway { + config: Arc, +} + +impl GrpcGateway { + pub(crate) fn new(config: IndexerGrpcGatewayConfig) -> Self { + Self { + config: Arc::new(config), + } + } + + pub(crate) async fn start(&self) -> anyhow::Result<()> { + let app = Router::new() + .route("/*path", any(proxy).with_state(self.config.clone())) + .layer(from_fn_with_state( + self.config.clone(), + get_data_service_url, + )); + + info!( + "gRPC Gateway listening on {}:{}", + LISTEN_ADDRESS, self.config.port + ); + let listener = tokio::net::TcpListener::bind((LISTEN_ADDRESS, self.config.port)) + .await + .expect("Failed to bind TCP listener"); + + axum::serve(listener, app) + .await + .context("Failed to serve gRPC Gateway") + } +} + +fn override_uri_with_upstream_url( + original_uri: &Uri, + upstream_url: &Url, +) -> Result { + let requested_path_and_query = original_uri.path_and_query().unwrap().to_string(); + + let new_url = upstream_url + .join(requested_path_and_query.as_str()) + .map_err(|_| { + ( + StatusCode::BAD_REQUEST, + format!("Requested URL is not supported: {}", original_uri), + ) + })?; + + if new_url.origin() != upstream_url.origin() { + return Err(( + StatusCode::BAD_REQUEST, + format!("Requested URL is not supported: {}", original_uri), + )); + } + + let uri = Uri::try_from(new_url.as_str()).unwrap(); + + Ok(uri) +} + +async fn get_data_service_url( + State(config): State>, + req: Request, + next: Next, +) -> Result { + let request_compression_encoding: Option = req + .headers() + .get(ENCODING_HEADER) + .and_then(|encoding_header| { + encoding_header + .to_str() + .ok() + .map(|encoding_str| match encoding_str { + "gzip" => Some(CompressionEncoding::Gzip), + "zstd" => Some(CompressionEncoding::Zstd), + _ => None, + }) + }) + .flatten(); + + let (head, mut body) = req.into_parts(); + + let mut user_request = None; + if head.uri.path() == "/aptos.indexer.v1.RawData/GetTransactions" { + let body_bytes = body + .collect() + .await + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? + .to_bytes(); + body = body_bytes.clone().into(); + let stream = Streaming::::new_request( + as Codec>::decoder( + &mut tonic::codec::ProstCodec::::default(), + ), + Full::new(body_bytes), + request_compression_encoding, + None, + ); + + tokio::pin!(stream); + + if let Ok(Some(request)) = stream.try_next().await { + user_request = Some(request); + } + } + + let mut client = GrpcManagerClient::connect(config.grpc_manager_address.to_string()) + .await + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + let grpc_manager_request = + tonic::Request::new(GetDataServiceForRequestRequest { user_request }); + let response: GetDataServiceForRequestResponse = client + .get_data_service_for_request(grpc_manager_request) + .await + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? + .into_inner(); + + let url = Url::from_str(&response.data_service_address).unwrap(); + let mut req = Request::from_parts(head, body); + req.extensions_mut().insert(url); + Ok(next.run(req).await) +} + +async fn proxy( + data_service_url: Extension, + mut request: Request, +) -> Result { + info!( + data_service_url = data_service_url.as_str(), + "Proxying request to data service: {}", + data_service_url.as_str() + ); + *request.uri_mut() = override_uri_with_upstream_url(request.uri(), &data_service_url)?; + + Client::builder(TokioExecutor::new()) + .http2_only(true) + .build_http() + .request(request) + .await + .map(|res| { + let (parts, body) = res.into_parts(); + Response::from_parts(parts, axum::body::Body::new(body)) + }) + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) +} diff --git a/ecosystem/indexer-grpc/indexer-grpc-gateway/src/lib.rs b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/lib.rs new file mode 100644 index 00000000000..49de76ff2f1 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/lib.rs @@ -0,0 +1,5 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod config; +mod gateway; diff --git a/ecosystem/indexer-grpc/indexer-grpc-gateway/src/main.rs b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/main.rs new file mode 100644 index 00000000000..48f84f6bce7 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-gateway/src/main.rs @@ -0,0 +1,17 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use aptos_indexer_grpc_gateway::config::IndexerGrpcGatewayConfig; +use aptos_indexer_grpc_server_framework::ServerArgs; +use clap::Parser; + +#[cfg(unix)] +#[global_allocator] +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; + +#[tokio::main] +async fn main() -> Result<()> { + let args = ServerArgs::parse(); + args.run::().await +} diff --git a/ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark/Cargo.toml index fa682ebba18..c40527464dc 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-in-memory-cache-benchmark/Cargo.toml @@ -23,7 +23,4 @@ redis-test = { workspace = true } tokio = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml index 96955568087..f51420d9700 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml @@ -39,7 +39,4 @@ aptos-config = { workspace = true } serde_json = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs index 26ebbd1b7b3..f201e534d78 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs @@ -38,6 +38,7 @@ pub struct IndexerGrpcManagerConfig { pub(crate) grpc_manager_addresses: Vec, pub(crate) fullnode_addresses: Vec, pub(crate) is_master: bool, + pub(crate) allow_fn_fallback: bool, } const fn default_cache_config() -> CacheConfig { diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/data_manager.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/data_manager.rs index b99d5028f19..6ef9c93deac 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/data_manager.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/data_manager.rs @@ -125,12 +125,14 @@ impl Cache { } } if update_file_store_version { - let old_version = self - .file_store_version - .fetch_add(transactions.len() as u64, Ordering::SeqCst); - let new_version = old_version + transactions.len() as u64; - FILE_STORE_VERSION_IN_CACHE.set(new_version as i64); - info!("Updated file_store_version in cache to {new_version}."); + if !transactions.is_empty() { + let old_version = self + .file_store_version + .fetch_add(transactions.len() as u64, Ordering::SeqCst); + let new_version = old_version + transactions.len() as u64; + FILE_STORE_VERSION_IN_CACHE.set(new_version as i64); + info!("Updated file_store_version in cache to {new_version}."); + } } else { trace!( "Returned {} transactions from Cache, total {size_bytes} bytes.", @@ -147,6 +149,7 @@ pub(crate) struct DataManager { cache: RwLock, file_store_reader: FileStoreReader, metadata_manager: Arc, + allow_fn_fallback: bool, } impl DataManager { @@ -155,6 +158,7 @@ impl DataManager { file_store_config: IndexerGrpcFileStoreConfig, cache_config: CacheConfig, metadata_manager: Arc, + allow_fn_fallback: bool, ) -> Self { let file_store = file_store_config.create_filestore().await; let file_store_reader = FileStoreReader::new(chain_id, file_store).await; @@ -163,6 +167,7 @@ impl DataManager { cache: RwLock::new(Cache::new(cache_config, file_store_version)), file_store_reader, metadata_manager, + allow_fn_fallback, } } @@ -211,6 +216,7 @@ impl DataManager { ); let (address, mut fullnode_client) = self.metadata_manager.get_fullnode_for_request(&request); + trace!("Fullnode ({address}) is picked for request."); let response = fullnode_client.get_transactions_from_node(request).await; if response.is_err() { warn!( @@ -219,13 +225,18 @@ impl DataManager { ); tokio::time::sleep(Duration::from_millis(100)).await; continue; + } else { + trace!("Got success response from fullnode."); } let mut response = response.unwrap().into_inner(); while let Some(response_item) = response.next().await { + trace!("Processing 1 response item."); loop { + trace!("Maybe running GC."); if self.cache.write().await.maybe_gc() { IS_FILE_STORE_LAGGING.set(0); + trace!("GC is done, file store is not lagging."); break; } IS_FILE_STORE_LAGGING.set(1); @@ -248,6 +259,10 @@ impl DataManager { if let Some(response) = r.response { match response { Response::Data(data) => { + trace!( + "Putting data into cache, {} transaction(s).", + data.transactions.len() + ); self.cache.write().await.put_transactions(data.transactions); }, Response::Status(_) => continue, @@ -284,7 +299,7 @@ impl DataManager { if start_version >= cache_start_version { if start_version >= cache_next_version { // If lagging, try to fetch the data from FN. - if self.lagging(cache_next_version) { + if self.lagging(cache_next_version) && self.allow_fn_fallback { debug!("GrpcManager is lagging, getting data from FN, requested_version: {start_version}, cache_next_version: {cache_next_version}."); let request = GetTransactionsFromNodeRequest { starting_version: Some(start_version), @@ -307,6 +322,8 @@ impl DataManager { } } + tokio::time::sleep(Duration::from_millis(200)).await; + // Let client side to retry. return Ok(vec![]); } diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/file_store_uploader.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/file_store_uploader.rs index 4459b8533b6..c6bb300e98c 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/file_store_uploader.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/file_store_uploader.rs @@ -171,7 +171,7 @@ impl FileStoreUploader { } if len == 0 { info!("No transaction was returned from cache, requested version: {next_version}."); - tokio::time::sleep(Duration::from_millis(100)).await; + tokio::time::sleep(Duration::from_millis(200)).await; } } }); diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs index ef5da5c19ca..5e4601d8fac 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs @@ -71,6 +71,7 @@ impl GrpcManager { config.file_store_config.clone(), config.cache_config.clone(), metadata_manager.clone(), + config.allow_fn_fallback, ) .await, ); diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/metadata_manager.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/metadata_manager.rs index 2688aba1024..7c6349deaba 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/metadata_manager.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/metadata_manager.rs @@ -187,13 +187,15 @@ impl MetadataManager { s.spawn(async move { if let Err(e) = self.heartbeat(client).await { warn!("Failed to send heartbeat to other grpc manager ({address}): {e:?}."); + } else { + trace!("Successfully sent heartbeat to other grpc manager ({address})."); } }); } for kv in &self.fullnodes { let (address, fullnode) = kv.pair(); - let need_ping = fullnode.recent_states.back().map_or(true, |s| { + let need_ping = fullnode.recent_states.back().is_none_or(|s| { Self::is_stale_timestamp( s.timestamp.unwrap_or_default(), Duration::from_secs(1), @@ -205,6 +207,8 @@ impl MetadataManager { s.spawn(async move { if let Err(e) = self.ping_fullnode(address.clone(), client).await { warn!("Failed to ping FN ({address}): {e:?}."); + } else { + trace!("Successfully pinged FN ({address})."); } }); } @@ -222,7 +226,7 @@ impl MetadataManager { unreachable_live_data_services.push(address.clone()); continue; } - let need_ping = live_data_service.recent_states.back().map_or(true, |s| { + let need_ping = live_data_service.recent_states.back().is_none_or(|s| { Self::is_stale_timestamp( s.timestamp.unwrap_or_default(), Duration::from_secs(5), @@ -236,6 +240,8 @@ impl MetadataManager { self.ping_live_data_service(address.clone(), client).await { warn!("Failed to ping live data service ({address}): {e:?}."); + } else { + trace!("Successfully pinged live data service ({address})."); } }); } @@ -257,16 +263,15 @@ impl MetadataManager { unreachable_historical_data_services.push(address.clone()); continue; } - let need_ping = - historical_data_service - .recent_states - .back() - .map_or(true, |s| { - Self::is_stale_timestamp( - s.timestamp.unwrap_or_default(), - Duration::from_secs(5), - ) - }); + let need_ping = historical_data_service + .recent_states + .back() + .is_none_or(|s| { + Self::is_stale_timestamp( + s.timestamp.unwrap_or_default(), + Duration::from_secs(5), + ) + }); if need_ping { let address = address.clone(); let client = historical_data_service.client.clone(); @@ -276,6 +281,8 @@ impl MetadataManager { .await { warn!("Failed to ping historical data service ({address}): {e:?}."); + } else { + trace!("Successfully pinged historical data service ({address})."); } }); } diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs index 90f28e46cf5..10af1f25d72 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs @@ -40,6 +40,7 @@ async fn test_run() { grpc_manager_addresses: vec![self_address], fullnode_addresses: vec![], is_master: true, + allow_fn_fallback: false, }; let task = tokio::spawn(async move { diff --git a/ecosystem/indexer-grpc/indexer-grpc-table-info/src/runtime.rs b/ecosystem/indexer-grpc/indexer-grpc-table-info/src/runtime.rs index de5fdd47252..e0c8b16ac26 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-table-info/src/runtime.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-table-info/src/runtime.rs @@ -72,8 +72,8 @@ pub fn bootstrap( .default_root_path() .join(INDEX_ASYNC_V2_DB_NAME); let rocksdb_config = node_config.storage.rocksdb_configs.index_db_config; - let db = - open_db(db_path, &rocksdb_config).expect("Failed to open up indexer async v2 db initially"); + let db = open_db(db_path, &rocksdb_config, /*readonly=*/ false) + .expect("Failed to open up indexer async v2 db initially"); let indexer_async_v2 = Arc::new(IndexerAsyncV2::new(db).expect("Failed to initialize indexer async v2")); @@ -97,7 +97,7 @@ pub fn bootstrap( _ => None, }; - let mut parser = TableInfoService::new( + let parser = TableInfoService::new( context, indexer_async_v2_clone.next_version(), node_config.indexer_table_info.parser_task_count, diff --git a/ecosystem/indexer-grpc/indexer-grpc-table-info/src/table_info_service.rs b/ecosystem/indexer-grpc/indexer-grpc-table-info/src/table_info_service.rs index 034c54cf1cb..4f8ea237a3d 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-table-info/src/table_info_service.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-table-info/src/table_info_service.rs @@ -4,7 +4,7 @@ use crate::{ backup_restore::gcs::GcsBackupRestoreOperator, snapshot_folder_name, snapshot_folder_prefix, }; -use anyhow::{Context, Error}; +use anyhow::{anyhow, Context, Error}; use aptos_api::context::Context as ApiContext; use aptos_api_types::TransactionOnChainData; use aptos_db_indexer::db_v2::IndexerAsyncV2; @@ -13,9 +13,15 @@ use aptos_indexer_grpc_fullnode::stream_coordinator::{ }; use aptos_indexer_grpc_utils::counters::{log_grpc_step, IndexerGrpcStep}; use aptos_logger::{debug, error, info, sample, sample::SampleRate}; -use aptos_types::write_set::WriteSet; use itertools::Itertools; -use std::{cmp::Ordering, sync::Arc, time::Duration}; +use std::{ + cmp::Ordering as CmpOrdering, + sync::{ + atomic::{AtomicBool, AtomicU64, Ordering}, + Arc, + }, + time::Duration, +}; type EndVersion = u64; const LEDGER_VERSION_RETRY_TIME_MILLIS: u64 = 10; @@ -25,7 +31,6 @@ const SERVICE_TYPE: &str = "table_info_service"; /// TableInfoService is responsible for parsing table info from transactions and writing them to rocksdb. /// Not thread safe. pub struct TableInfoService { - pub current_version: u64, pub parser_task_count: u16, pub parser_batch_size: u16, pub context: Arc, @@ -33,6 +38,15 @@ pub struct TableInfoService { // Backup and restore service. If not enabled, this will be None. pub backup_restore_operator: Option>, + + current_version: AtomicU64, + aborted: AtomicBool, +} + +impl Drop for TableInfoService { + fn drop(&mut self) { + println!("**** Dropping TableInfoService ****"); + } } impl TableInfoService { @@ -45,21 +59,26 @@ impl TableInfoService { indexer_async_v2: Arc, ) -> Self { Self { - current_version: request_start_version, + current_version: AtomicU64::new(request_start_version), parser_task_count, parser_batch_size, context, backup_restore_operator, indexer_async_v2, + aborted: AtomicBool::new(false), } } + pub fn abort(&self) { + self.aborted.store(true, Ordering::SeqCst); + } + /// Start table info service and backup service is optional. /// It contains two main loops: /// 1. Table info parsing loop: fetching raw txns from db, processing, and writing to rocksdb. /// If backup service is enabled, it will also snapshot the rocksdb at the end of each epoch. /// 2. Optional backup service loop: it monitors if new snapshots are available to backup and uploads them to GCS. - pub async fn run(&mut self) { + pub async fn run(&self) { // TODO: fix the restore logic. let backup_is_enabled = match self.backup_restore_operator.clone() { Some(backup_restore_operator) => { @@ -87,6 +106,10 @@ impl TableInfoService { loop { let start_time = std::time::Instant::now(); let ledger_version = self.get_highest_known_version().await.unwrap_or_default(); + if self.aborted.load(Ordering::SeqCst) { + info!("table info service aborted"); + break; + } let batches = self.get_batches(ledger_version).await; let transactions = self.fetch_batches(batches, ledger_version).await.unwrap(); let num_transactions = transactions.len(); @@ -149,7 +172,7 @@ impl TableInfoService { .await; let versions_processed = num_transactions as i64; - let start_version = self.current_version; + let start_version = self.current_version.load(Ordering::SeqCst); log_grpc_step( SERVICE_TYPE, IndexerGrpcStep::TableInfoProcessed, @@ -163,11 +186,16 @@ impl TableInfoService { None, ); - self.current_version = last_version + 1; + self.current_version + .store(last_version + 1, Ordering::SeqCst); current_epoch = Some(epoch); } } + pub fn next_version(&self) -> u64 { + self.current_version.load(Ordering::SeqCst) + } + async fn fetch_batches( &self, batches: Vec, @@ -226,18 +254,22 @@ impl TableInfoService { .map(|txn| txn.version) .unwrap_or_default(); - // We copy the transactions here in case we need to retry the parsing. - let batches: Vec> = transactions + let transactions = Arc::new(transactions); + for (chunk_idx, batch_size) in transactions .chunks(self.parser_batch_size as usize) - .map(|chunk| chunk.to_vec()) - .collect(); - - for batch in batches { - let task = tokio::spawn(Self::process_transactions( - context.clone(), - indexer_async_v2.clone(), - batch, - )); + .enumerate() + .map(|(idx, chunk)| (idx, chunk.len())) + { + let start = chunk_idx * self.parser_batch_size as usize; + let end = start + batch_size; + + let transactions = transactions.clone(); + let context = context.clone(); + let indexer_async_v2 = indexer_async_v2.clone(); + let task = tokio::spawn(async move { + Self::process_transactions(context, indexer_async_v2, &transactions[start..end]) + .await + }); tasks.push(task); } @@ -256,7 +288,7 @@ impl TableInfoService { Self::process_transactions( context.clone(), indexer_async_v2.clone(), - transactions, + &transactions, ) .await; } @@ -284,19 +316,27 @@ impl TableInfoService { /// It's used in the first loop to process batches in parallel, /// and it's used in the second loop to process transactions sequentially /// if pending on items are not empty - /// TODO: better error handling with retry. async fn process_transactions( context: Arc, indexer_async_v2: Arc, - raw_txns: Vec, + raw_txns: &[TransactionOnChainData], ) -> EndVersion { let start_time = std::time::Instant::now(); let start_version = raw_txns[0].version; let end_version = raw_txns.last().unwrap().version; let num_transactions = raw_txns.len(); - Self::parse_table_info(context.clone(), raw_txns.clone(), indexer_async_v2) - .expect("[Table Info] Failed to parse table info"); + loop { + // NOTE: The retry is unlikely to be helpful. Put a loop here just to avoid panic and + // allow the rest of FN functionality continue to work. + match Self::parse_table_info(context.clone(), raw_txns, indexer_async_v2.clone()) { + Ok(_) => break, + Err(e) => { + error!(error = ?e, "Error during parse_table_info."); + tokio::time::sleep(Duration::from_secs(5)).await; + }, + } + } log_grpc_step( SERVICE_TYPE, @@ -317,16 +357,16 @@ impl TableInfoService { /// Retrieves transaction batches based on the provided ledger version. /// The function prepares to fetch transactions by determining the start version, /// the number of fetches, and the size of each batch. - async fn get_batches(&mut self, ledger_version: u64) -> Vec { + async fn get_batches(&self, ledger_version: u64) -> Vec { + let mut start_version = self.current_version.load(Ordering::SeqCst); info!( - current_version = self.current_version, + current_version = start_version, highest_known_version = ledger_version, parser_batch_size = self.parser_batch_size, parser_task_count = self.parser_task_count, "[Table Info] Preparing to fetch transactions" ); - let mut start_version = self.current_version; let mut num_fetches = 0; let mut batches = vec![]; @@ -352,7 +392,7 @@ impl TableInfoService { /// Parse table info from write sets, fn parse_table_info( context: Arc, - raw_txns: Vec, + raw_txns: &[TransactionOnChainData], indexer_async_v2: Arc, ) -> Result<(), Error> { if raw_txns.is_empty() { @@ -361,13 +401,10 @@ impl TableInfoService { let start_time = std::time::Instant::now(); let first_version = raw_txns.first().map(|txn| txn.version).unwrap(); - let write_sets: Vec = raw_txns.iter().map(|txn| txn.changes.clone()).collect(); - let write_sets_slice: Vec<&WriteSet> = write_sets.iter().collect(); + let write_sets = raw_txns.iter().map(|txn| &txn.changes).collect::>(); indexer_async_v2 - .index_table_info(context.db.clone(), first_version, &write_sets_slice) - .expect( - "[Table Info] Failed to process write sets and index to the table info rocksdb", - ); + .index_table_info(context.db.clone(), first_version, &write_sets) + .map_err(|err| anyhow!("[Table Info] Failed to process write sets and index to the table info rocksdb: {}", err))?; info!( table_info_first_version = first_version, @@ -459,7 +496,10 @@ impl TableInfoService { let mut ledger_version = info.unwrap().ledger_version.0; let mut empty_loops = 0; - while ledger_version == 0 || self.current_version > ledger_version { + while ledger_version == 0 || self.current_version.load(Ordering::SeqCst) > ledger_version { + if self.aborted.load(Ordering::SeqCst) { + break; + } if empty_loops > 0 { tokio::time::sleep(Duration::from_millis(LEDGER_VERSION_RETRY_TIME_MILLIS)).await; } @@ -603,12 +643,12 @@ fn transactions_in_epochs( let current_epoch = current_epoch.unwrap(); let split_off_index = match current_epoch.cmp(&block_epoch.epoch()) { - Ordering::Equal => { + CmpOrdering::Equal => { // All transactions are in the this epoch. // Previous epoch is empty, i.e., [0, 0), and this epoch is [first_version, last_version]. 0 }, - Ordering::Less => { + CmpOrdering::Less => { // Try the best to split the transactions into two epochs. epoch_first_version - first_version }, diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/counters.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/counters.rs index b3746eee88f..00777e3f7c2 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/counters.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/counters.rs @@ -259,7 +259,7 @@ pub fn log_grpc_step( let start_txn_timestamp_iso = start_version_timestamp.map(timestamp_to_iso); let end_txn_timestamp_iso = end_version_timestamp.map(timestamp_to_iso); - if request_metadata.is_none() { + if let Some(request_metadata) = request_metadata { tracing::info!( start_version, end_version, @@ -268,13 +268,19 @@ pub fn log_grpc_step( num_transactions, duration_in_secs, size_in_bytes, + // Request metadata variables + processor_name = &request_metadata.processor_name, + request_identifier_type = &request_metadata.request_identifier_type, + request_identifier = &request_metadata.request_identifier, + request_email = &request_metadata.request_email, + request_application_name = &request_metadata.request_application_name, + connection_id = &request_metadata.request_connection_id, service_type, step = step.get_step(), "{}", step.get_label(), ); } else { - let request_metadata = request_metadata.unwrap(); tracing::info!( start_version, end_version, @@ -283,13 +289,6 @@ pub fn log_grpc_step( num_transactions, duration_in_secs, size_in_bytes, - // Request metadata variables - processor_name = &request_metadata.processor_name, - request_identifier_type = &request_metadata.request_identifier_type, - request_identifier = &request_metadata.request_identifier, - request_email = &request_metadata.request_email, - request_application_name = &request_metadata.request_application_name, - connection_id = &request_metadata.request_connection_id, service_type, step = step.get_step(), "{}", diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator/gcs.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator/gcs.rs index 2b6361f8bde..ed606ec974e 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator/gcs.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator/gcs.rs @@ -32,7 +32,10 @@ impl GcsFileStoreOperator { service_account_path: String, enable_compression: bool, ) -> Self { - env::set_var(SERVICE_ACCOUNT_ENV_VAR, service_account_path); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + env::set_var(SERVICE_ACCOUNT_ENV_VAR, service_account_path); + } let storage_format = if enable_compression { StorageFormat::Lz4CompressedProto } else { diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator_v2/gcs.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator_v2/gcs.rs index 3722b07cd2d..72d80621646 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator_v2/gcs.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/file_store_operator_v2/gcs.rs @@ -24,7 +24,10 @@ impl GcsFileStore { bucket_sub_dir: Option, service_account_path: String, ) -> Self { - env::set_var(SERVICE_ACCOUNT_ENV_VAR, service_account_path); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + env::set_var(SERVICE_ACCOUNT_ENV_VAR, service_account_path); + } info!( bucket_name = bucket_name, diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/lib.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/lib.rs index d6d45b38e1b..dc39523e1df 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/lib.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/lib.rs @@ -80,7 +80,9 @@ pub async fn create_data_service_grpc_client( address = address.to_string(), "[Indexer Cache] Connected to indexer data service gRPC server." ); - Ok(client) + Ok(client + .max_decoding_message_size(usize::MAX) + .max_encoding_message_size(usize::MAX)) }, Err(e) => { tracing::error!( diff --git a/ecosystem/indexer-grpc/indexer-grpc-v2-file-store-backfiller/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-v2-file-store-backfiller/Cargo.toml index eeb18380079..14caa3c6fdb 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-v2-file-store-backfiller/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-v2-file-store-backfiller/Cargo.toml @@ -29,7 +29,4 @@ tracing = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs index cc60396f201..525b41b7b64 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs @@ -3,11 +3,15 @@ #![allow(dead_code)] #![allow(unused_variables)] +pub const IMPORTED_MAINNET_TXNS_2386021136_TRADEPORT_V2_FILL_COLLECTION_OFFER: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2386021136_tradeport_v2_fill_collection_offer.json")); + pub const IMPORTED_MAINNET_TXNS_121508544_STAKE_DISTRIBUTE: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json" )); +pub const IMPORTED_MAINNET_TXNS_2819452713_TOKEN_V1_CANCEL_OFFER_MODULE_EVENT: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2819452713_token_v1_cancel_offer_module_event.json")); + pub const IMPORTED_MAINNET_TXNS_590098441_USER_TXN_SINGLE_SENDER_ED25519: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json")); pub const IMPORTED_MAINNET_TXNS_145959468_ACCOUNT_TRANSACTION: &[u8] = include_bytes!(concat!( @@ -32,6 +36,12 @@ pub const IMPORTED_MAINNET_TXNS_1831971037_STAKE_DELEGATION_POOL: &[u8] = includ "/src/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json" )); +pub const IMPORTED_MAINNET_TXNS_2386133936_TRADEPORT_V2_PLACE_OFFER: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2386133936_tradeport_v2_place_offer.json" + )); + pub const IMPORTED_MAINNET_TXNS_527013476_USER_TXN_SINGLE_SENDER_SECP256K1_ECDSA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json")); pub const IMPORTED_MAINNET_TXNS_118489_PROPOSAL_VOTE: &[u8] = include_bytes!(concat!( @@ -47,11 +57,38 @@ pub const IMPORTED_MAINNET_TXNS_1845035942_DEFAULT_CURRENT_TABLE_ITEMS: &[u8] = "/src/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json" )); +pub const IMPORTED_MAINNET_TXNS_2382373978_WAPAL_CANCEL_COLLECTION_OFFER: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2382373978_wapal_cancel_collection_offer.json")); + +pub const IMPORTED_MAINNET_TXNS_2386455218_TRADEPORT_V2_FILL_LISTING: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2386455218_tradeport_v2_fill_listing.json" + )); + +pub const IMPORTED_MAINNET_TXNS_2382221134_WAPAL_FILL_LISTING: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2382221134_wapal_fill_listing.json" +)); + +pub const IMPORTED_MAINNET_TXNS_3020266695_TOKEN_V1_OFFER_MODULE_EVENT: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/3020266695_token_v1_offer_module_event.json" + )); + +pub const IMPORTED_MAINNET_TXNS_2386889884_TRADEPORT_V2_CANCEL_COLLECTION_OFFER: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2386889884_tradeport_v2_cancel_collection_offer.json")); + pub const IMPORTED_MAINNET_TXNS_125600867_STAKE_DELEGATION_POOL: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json" )); +pub const IMPORTED_MAINNET_TXNS_2382219668_WAPAL_FILL_COLLECTION_OFFER: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2382219668_wapal_fill_collection_offer.json" + )); + pub const IMPORTED_MAINNET_TXNS_513424821_DEFAULT_BLOCK_METADATA_TRANSACTIONS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json")); pub const IMPORTED_MAINNET_TXNS_103958588_MULTI_AGENTS: &[u8] = include_bytes!(concat!( @@ -83,11 +120,22 @@ pub const IMPORTED_MAINNET_TXNS_2212040150_TRANSACTION_WITHOUT_EVENTS: &[u8] = "/src/json_transactions/imported_mainnet_txns/2212040150_transaction_without_events.json" )); +pub const IMPORTED_MAINNET_TXNS_2386809975_TRADEPORT_V2_PLACE_LISTING: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2386809975_tradeport_v2_place_listing.json" + )); + pub const IMPORTED_MAINNET_TXNS_550582915_MULTIPLE_TRANSFER_EVENT: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/550582915_multiple_transfer_event.json" )); +pub const IMPORTED_MAINNET_TXNS_2313248448_WAPAL_FILL_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2313248448_wapal_fill_offer.json" +)); + pub const IMPORTED_MAINNET_TXNS_464961735_USER_TXN_SINGLE_KEY_ED25519: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -110,6 +158,8 @@ pub const IMPORTED_MAINNET_TXNS_2308282694_ASSET_TYPE_V1_NULL: &[u8] = include_b "/src/json_transactions/imported_mainnet_txns/2308282694_asset_type_v1_null.json" )); +pub const IMPORTED_MAINNET_TXNS_2296149225_TRADEPORT_V2_ACCEPT_TOKEN_DELIST: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2296149225_tradeport_v2_accept_token_delist.json")); + pub const IMPORTED_MAINNET_TXNS_999930475_TOKEN_V2_CONCURRENT_MINT: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -118,6 +168,11 @@ pub const IMPORTED_MAINNET_TXNS_999930475_TOKEN_V2_CONCURRENT_MINT: &[u8] = pub const IMPORTED_MAINNET_TXNS_554229017_EVENTS_WITH_NO_EVENT_SIZE_INFO: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/554229017_events_with_no_event_size_info.json")); +pub const IMPORTED_MAINNET_TXNS_84023785_TOKEN_V1_CLAIM_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/84023785_token_v1_claim_offer.json" +)); + pub const IMPORTED_MAINNET_TXNS_2448304257_COINSTORE_DELETION_EVENT: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -129,14 +184,18 @@ pub const IMPORTED_MAINNET_TXNS_124094774_DELEGATED_POOL_BALANCE: &[u8] = includ "/src/json_transactions/imported_mainnet_txns/124094774_delegated_pool_balance.json" )); +pub const IMPORTED_MAINNET_TXNS_2277018899_TRADEPORT_V2_ACCEPT_TOKEN_DELIST_SAME_TOKEN_DATA_ID: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2277018899_tradeport_v2_accept_token_delist_same_token_data_id.json")); + pub const IMPORTED_MAINNET_TXNS_144201980_MULTIPLE_TRANSFER_EVENT: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/144201980_multiple_transfer_event.json" )); -pub const IMPORTED_MAINNET_TXNS_97963136_TOKEN_V2_CANCEL_OFFER: &[u8] = include_bytes!(concat!( +pub const IMPORTED_MAINNET_TXNS_2424873868_FA_SECONDARY_STORE_EXISTS_OBJECT_CORE_DELETED: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2424873868_fa_secondary_store_exists_object_core_deleted.json")); + +pub const IMPORTED_MAINNET_TXNS_2382313982_WAPAL_PLACE_OFFER: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), - "/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json" + "/src/json_transactions/imported_mainnet_txns/2382313982_wapal_place_offer.json" )); pub const IMPORTED_MAINNET_TXNS_152449628_COIN_INFO_WRITE: &[u8] = include_bytes!(concat!( @@ -150,6 +209,19 @@ pub const IMPORTED_MAINNET_TXNS_602320562_TOKEN_V2_APTOS_TOKEN_MINT: &[u8] = "/src/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json" )); +pub const IMPORTED_MAINNET_TXNS_2386716658_TRADEPORT_V2_CANCEL_LISTING: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2386716658_tradeport_v2_cancel_listing.json" + )); + +pub const IMPORTED_MAINNET_TXNS_2386891051_TRADEPORT_V2_PLACE_COLLECTION_OFFER: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2386891051_tradeport_v2_place_collection_offer.json")); + +pub const IMPORTED_MAINNET_TXNS_2381742315_WAPAL_CANCEL_LISTING: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2381742315_wapal_cancel_listing.json" +)); + pub const IMPORTED_MAINNET_TXNS_1830706009_STAKER_GOVERNANCE_RECORD: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -169,6 +241,8 @@ pub const IMPORTED_MAINNET_TXNS_303690531_ANS_LOOKUP_V2: &[u8] = include_bytes!( pub const IMPORTED_MAINNET_TXNS_2200077800_ACCOUNT_RESTORATION_ROTATED_TO_MULTI_KEY: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2200077800_account_restoration_rotated_to_multi_key.json")); +pub const IMPORTED_MAINNET_TXNS_2975888978_FA_SECONDARY_STORE_BURNT_OBJECT_STILL_EXISTS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2975888978_fa_secondary_store_burnt_object_still_exists.json")); + pub const IMPORTED_MAINNET_TXNS_1803170308_USER_TXN_MULTI_KEY_KEYLESS: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -199,16 +273,22 @@ pub const IMPORTED_MAINNET_TXNS_255894550_STORAGE_REFUND: &[u8] = include_bytes! pub const IMPORTED_MAINNET_TXNS_551057865_USER_TXN_SINGLE_SENDER_WEBAUTH: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json")); -pub const IMPORTED_MAINNET_TXNS_84023785_TOKEN_V2_CLAIM_OFFER: &[u8] = include_bytes!(concat!( +pub const IMPORTED_MAINNET_TXNS_141135867_TOKEN_V1_OFFER: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), - "/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json" + "/src/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json" )); -pub const IMPORTED_MAINNET_TXNS_141135867_TOKEN_V1_OFFER: &[u8] = include_bytes!(concat!( +pub const IMPORTED_MAINNET_TXNS_2382251863_WAPAL_PLACE_LISTING: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), - "/src/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json" + "/src/json_transactions/imported_mainnet_txns/2382251863_wapal_place_listing.json" )); +pub const IMPORTED_MAINNET_TXNS_2386142672_TRADEPORT_V2_CANCEL_OFFER: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2386142672_tradeport_v2_cancel_offer.json" + )); + pub const IMPORTED_MAINNET_TXNS_1957950162_FA_MIGRATION_V2_STORE_ONLY: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -228,6 +308,12 @@ pub const IMPORTED_MAINNET_TXNS_2080538_ANS_LOOKUP_V1: &[u8] = include_bytes!(co "/src/json_transactions/imported_mainnet_txns/2080538_ans_lookup_v1.json" )); +pub const IMPORTED_MAINNET_TXNS_2382373209_WAPAL_PLACE_COLLECTION_OFFER: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2382373209_wapal_place_collection_offer.json" + )); + pub const IMPORTED_MAINNET_TXNS_139449359_STAKE_REACTIVATE: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json" @@ -256,6 +342,17 @@ pub const IMPORTED_MAINNET_TXNS_1080786089_TOKEN_V2_BURN_EVENT_V1: &[u8] = inclu "/src/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json" )); +pub const IMPORTED_MAINNET_TXNS_97963136_TOKEN_V1_CANCEL_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/97963136_token_v1_cancel_offer.json" +)); + +pub const IMPORTED_MAINNET_TXNS_2298838662_TRADEPORT_V2_FILL_OFFER: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2298838662_tradeport_v2_fill_offer.json" + )); + pub const IMPORTED_MAINNET_TXNS_445585423_TOKEN_MINT_AND_BURN_EVENT: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -277,11 +374,18 @@ pub const IMPORTED_MAINNET_TXNS_537250181_TOKEN_V2_FIXED_SUPPLY_MINT: &[u8] = pub const IMPORTED_MAINNET_TXNS_2200077673_ACCOUNT_RESTORATION_UNVERIFIED_KEY_ROTATION_TO_MULTI_KEY_TXN: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2200077673_account_restoration_unverified_key_rotation_to_multi_key_txn.json")); +pub const IMPORTED_MAINNET_TXNS_2296098846_TRADEPORT_V2_ACCEPT_TOKEN_DELIST2: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2296098846_tradeport_v2_accept_token_delist2.json")); + pub const IMPORTED_MAINNET_TXNS_4827964_STAKE_INITIALIZE: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json" )); +pub const IMPORTED_MAINNET_TXNS_2381810159_WAPAL_CANCEL_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2381810159_wapal_cancel_offer.json" +)); + pub const IMPORTED_MAINNET_TXNS_155112189_DEFAULT_TABLE_ITEMS: &[u8] = include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/155112189_default_table_items.json" @@ -297,18 +401,27 @@ pub const IMPORTED_MAINNET_TXNS_685_USER_TXN_ED25519: &[u8] = include_bytes!(con "/src/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json" )); pub const ALL_IMPORTED_MAINNET_TXNS: &[&[u8]] = &[ + IMPORTED_MAINNET_TXNS_2386021136_TRADEPORT_V2_FILL_COLLECTION_OFFER, IMPORTED_MAINNET_TXNS_121508544_STAKE_DISTRIBUTE, + IMPORTED_MAINNET_TXNS_2819452713_TOKEN_V1_CANCEL_OFFER_MODULE_EVENT, IMPORTED_MAINNET_TXNS_590098441_USER_TXN_SINGLE_SENDER_ED25519, IMPORTED_MAINNET_TXNS_145959468_ACCOUNT_TRANSACTION, IMPORTED_MAINNET_TXNS_2175935_USER_TXN_MULTI_ED25519, IMPORTED_MAINNET_TXNS_2308283617_ASSET_TYPE_V1_NULL_2, IMPORTED_MAINNET_TXNS_2200077877_ACCOUNT_RESTORATION_ROTATED_TO_SINGLE_SECP256K1, IMPORTED_MAINNET_TXNS_1831971037_STAKE_DELEGATION_POOL, + IMPORTED_MAINNET_TXNS_2386133936_TRADEPORT_V2_PLACE_OFFER, IMPORTED_MAINNET_TXNS_527013476_USER_TXN_SINGLE_SENDER_SECP256K1_ECDSA, IMPORTED_MAINNET_TXNS_118489_PROPOSAL_VOTE, IMPORTED_MAINNET_TXNS_1058723093_TOKEN_V1_MINT_WITHDRAW_DEPOSIT_EVENTS, IMPORTED_MAINNET_TXNS_1845035942_DEFAULT_CURRENT_TABLE_ITEMS, + IMPORTED_MAINNET_TXNS_2382373978_WAPAL_CANCEL_COLLECTION_OFFER, + IMPORTED_MAINNET_TXNS_2386455218_TRADEPORT_V2_FILL_LISTING, + IMPORTED_MAINNET_TXNS_2382221134_WAPAL_FILL_LISTING, + IMPORTED_MAINNET_TXNS_3020266695_TOKEN_V1_OFFER_MODULE_EVENT, + IMPORTED_MAINNET_TXNS_2386889884_TRADEPORT_V2_CANCEL_COLLECTION_OFFER, IMPORTED_MAINNET_TXNS_125600867_STAKE_DELEGATION_POOL, + IMPORTED_MAINNET_TXNS_2382219668_WAPAL_FILL_COLLECTION_OFFER, IMPORTED_MAINNET_TXNS_513424821_DEFAULT_BLOCK_METADATA_TRANSACTIONS, IMPORTED_MAINNET_TXNS_103958588_MULTI_AGENTS, IMPORTED_MAINNET_TXNS_999929475_COIN_AND_FA_TRANSFERS, @@ -318,23 +431,33 @@ pub const ALL_IMPORTED_MAINNET_TXNS: &[&[u8]] = &[ IMPORTED_MAINNET_TXNS_1056780409_ANS_CURRENT_ANS_PRIMARY_NAME_V2, IMPORTED_MAINNET_TXNS_2200077591_ACCOUNT_RESTORATION_SINGLE_ED25519, IMPORTED_MAINNET_TXNS_2212040150_TRANSACTION_WITHOUT_EVENTS, + IMPORTED_MAINNET_TXNS_2386809975_TRADEPORT_V2_PLACE_LISTING, IMPORTED_MAINNET_TXNS_550582915_MULTIPLE_TRANSFER_EVENT, + IMPORTED_MAINNET_TXNS_2313248448_WAPAL_FILL_OFFER, IMPORTED_MAINNET_TXNS_464961735_USER_TXN_SINGLE_KEY_ED25519, IMPORTED_MAINNET_TXNS_438536688_ANS_CURRENT_ANS_LOOKUP_V2, IMPORTED_MAINNET_TXNS_578318306_OBJECTS_WRITE_RESOURCE, IMPORTED_MAINNET_TXNS_2308282694_ASSET_TYPE_V1_NULL, + IMPORTED_MAINNET_TXNS_2296149225_TRADEPORT_V2_ACCEPT_TOKEN_DELIST, IMPORTED_MAINNET_TXNS_999930475_TOKEN_V2_CONCURRENT_MINT, IMPORTED_MAINNET_TXNS_554229017_EVENTS_WITH_NO_EVENT_SIZE_INFO, + IMPORTED_MAINNET_TXNS_84023785_TOKEN_V1_CLAIM_OFFER, IMPORTED_MAINNET_TXNS_2448304257_COINSTORE_DELETION_EVENT, IMPORTED_MAINNET_TXNS_124094774_DELEGATED_POOL_BALANCE, + IMPORTED_MAINNET_TXNS_2277018899_TRADEPORT_V2_ACCEPT_TOKEN_DELIST_SAME_TOKEN_DATA_ID, IMPORTED_MAINNET_TXNS_144201980_MULTIPLE_TRANSFER_EVENT, - IMPORTED_MAINNET_TXNS_97963136_TOKEN_V2_CANCEL_OFFER, + IMPORTED_MAINNET_TXNS_2424873868_FA_SECONDARY_STORE_EXISTS_OBJECT_CORE_DELETED, + IMPORTED_MAINNET_TXNS_2382313982_WAPAL_PLACE_OFFER, IMPORTED_MAINNET_TXNS_152449628_COIN_INFO_WRITE, IMPORTED_MAINNET_TXNS_602320562_TOKEN_V2_APTOS_TOKEN_MINT, + IMPORTED_MAINNET_TXNS_2386716658_TRADEPORT_V2_CANCEL_LISTING, + IMPORTED_MAINNET_TXNS_2386891051_TRADEPORT_V2_PLACE_COLLECTION_OFFER, + IMPORTED_MAINNET_TXNS_2381742315_WAPAL_CANCEL_LISTING, IMPORTED_MAINNET_TXNS_1830706009_STAKER_GOVERNANCE_RECORD, IMPORTED_MAINNET_TXNS_423176063_ACCOUNT_TRANSACTION_DELETE, IMPORTED_MAINNET_TXNS_303690531_ANS_LOOKUP_V2, IMPORTED_MAINNET_TXNS_2200077800_ACCOUNT_RESTORATION_ROTATED_TO_MULTI_KEY, + IMPORTED_MAINNET_TXNS_2975888978_FA_SECONDARY_STORE_BURNT_OBJECT_STILL_EXISTS, IMPORTED_MAINNET_TXNS_1803170308_USER_TXN_MULTI_KEY_KEYLESS, IMPORTED_MAINNET_TXNS_508365567_FA_V1_EVENTS, IMPORTED_MAINNET_TXNS_1806220919_OBJECT_UNTRANSFERABLE, @@ -342,24 +465,30 @@ pub const ALL_IMPORTED_MAINNET_TXNS: &[&[u8]] = &[ IMPORTED_MAINNET_TXNS_325355235_TOKEN_V2_UNLIMITED_SUPPLY_MINT, IMPORTED_MAINNET_TXNS_255894550_STORAGE_REFUND, IMPORTED_MAINNET_TXNS_551057865_USER_TXN_SINGLE_SENDER_WEBAUTH, - IMPORTED_MAINNET_TXNS_84023785_TOKEN_V2_CLAIM_OFFER, IMPORTED_MAINNET_TXNS_141135867_TOKEN_V1_OFFER, + IMPORTED_MAINNET_TXNS_2382251863_WAPAL_PLACE_LISTING, + IMPORTED_MAINNET_TXNS_2386142672_TRADEPORT_V2_CANCEL_OFFER, IMPORTED_MAINNET_TXNS_1957950162_FA_MIGRATION_V2_STORE_ONLY, IMPORTED_MAINNET_TXNS_976087151_USER_TXN_SINGLE_SENDER_KEYLESS, IMPORTED_MAINNET_TXNS_1737056775_COIN_TRANSFER_BURN_EVENT, IMPORTED_MAINNET_TXNS_2080538_ANS_LOOKUP_V1, + IMPORTED_MAINNET_TXNS_2382373209_WAPAL_PLACE_COLLECTION_OFFER, IMPORTED_MAINNET_TXNS_139449359_STAKE_REACTIVATE, IMPORTED_MAINNET_TXNS_308783012_FA_TRANSFER, IMPORTED_MAINNET_TXNS_2186504987_COIN_STORE_DELETION_NO_EVENT, IMPORTED_MAINNET_TXNS_1680592683_FA_MIGRATION_COIN_INFO, IMPORTED_MAINNET_TXNS_453498957_TOKEN_V2_MINT_AND_TRANSFER_EVENT_V1, IMPORTED_MAINNET_TXNS_1080786089_TOKEN_V2_BURN_EVENT_V1, + IMPORTED_MAINNET_TXNS_97963136_TOKEN_V1_CANCEL_OFFER, + IMPORTED_MAINNET_TXNS_2298838662_TRADEPORT_V2_FILL_OFFER, IMPORTED_MAINNET_TXNS_445585423_TOKEN_MINT_AND_BURN_EVENT, IMPORTED_MAINNET_TXNS_967255533_TOKEN_V2_MUTATION_EVENT, IMPORTED_MAINNET_TXNS_407418623_USER_TXN_SINGLE_KEY_SECP256K1_ECDSA, IMPORTED_MAINNET_TXNS_537250181_TOKEN_V2_FIXED_SUPPLY_MINT, IMPORTED_MAINNET_TXNS_2200077673_ACCOUNT_RESTORATION_UNVERIFIED_KEY_ROTATION_TO_MULTI_KEY_TXN, + IMPORTED_MAINNET_TXNS_2296098846_TRADEPORT_V2_ACCEPT_TOKEN_DELIST2, IMPORTED_MAINNET_TXNS_4827964_STAKE_INITIALIZE, + IMPORTED_MAINNET_TXNS_2381810159_WAPAL_CANCEL_OFFER, IMPORTED_MAINNET_TXNS_155112189_DEFAULT_TABLE_ITEMS, IMPORTED_MAINNET_TXNS_178179220_TOKEN_V1_MUTATE_EVENT, IMPORTED_MAINNET_TXNS_685_USER_TXN_ED25519, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2277018899_tradeport_v2_accept_token_delist_same_token_data_id.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2277018899_tradeport_v2_accept_token_delist_same_token_data_id.json new file mode 100644 index 00000000000..214e2e7ffb1 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2277018899_tradeport_v2_accept_token_delist_same_token_data_id.json @@ -0,0 +1,535 @@ +{ + "timestamp": { + "seconds": "1738092852", + "nanos": 915658000 + }, + "version": "2277018899", + "info": { + "hash": "E74a1FC4GkGO65Ig4xmaJbM5hWFhnTR0daMRnjLnHkE=", + "stateChangeHash": "04LpT5qp05FA8E5FAwJlmYfD02vS4X3j57SgtKP758o=", + "eventRootHash": "n83wdnCkv4fRVrfCzDHsy4PglL9A0aVRZPsUbnDZnhI=", + "gasUsed": "20", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "C06HYwg6sJXRiNRkKLBPhss+u5+IOE4+k4yxuSryzOk=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xe89fe77893a9bbbfb89d747005e621d4cc9e30b6a5c5f9b419c7f784a3307a5", + "stateKeyHash": "r8ki1cCzdPpvNc7TBfbbgEg2gzLB8r+QTZ9QF6qGSi8=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60", + "stateKeyHash": "hizPXgf4k6Y4LlVYvl0lQ5OM7doVSYeH0BcWJbk2oKg=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"27433732\"},\"deposit_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"9\",\"guid\":{\"id\":{\"addr\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60", + "stateKeyHash": "yVpnC8QMW+FdlLhFx+CuV2VCs1+9aabr1fvIb2pR98A=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"coin_register_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"11\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"14\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"9867565519\"},\"deposit_events\":{\"counter\":\"149203\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"23\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"transfer_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"elemental\",\"value\":{\"type\":9,\"value\":\"0x0446495245\"}},{\"key\":\"category\",\"value\":{\"type\":9,\"value\":\"0x096170746f6d696e676f\"}},{\"key\":\"grade\",\"value\":{\"type\":9,\"value\":\"0x06436f6d6d6f6e\"}},{\"key\":\"@probability_set\",\"value\":{\"type\":9,\"value\":\"0x0c67616d653a3a6578706f7274\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "royalty", + "name": "Royalty" + }, + "typeStr": "0x4::royalty::Royalty", + "data": "{\"denominator\":\"100\",\"numerator\":\"5\",\"payee_address\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"description\":\"I am a Sidekick, always standing by my Villain. When the bond between a Villain and me deepens, something special could happen!\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://public.vir.supervlabs.io/virweb/nft/sidekicks/mingo.png\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"291160\"},\"name\":{\"padding\":\"0x0000000000000000\",\"value\":\"Mingo #12541\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "sidekick", + "name": "Sidekick" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::sidekick::Sidekick", + "data": "{\"salt\":\"0\",\"updated_at\":\"1738028896\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmObject" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmObject", + "data": "{\"class\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"creator\":{\"inner\":\"0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6\"},\"delete_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"extend_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"transfer_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmToken" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"property_mutator_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"royalty_mutator_ref\":{\"vec\":[{\"inner\":{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}]}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x6ecdec1173f2e79aeab37fc2e2bdd43f36d7c169a153a1bf6e05246b21457e90", + "stateKeyHash": "bGTRvQOhc1OgXKdmecFvmpviy9mzSfjdEY3jJYDmKNI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7", + "stateKeyHash": "e3BUygmgtbbu9RwYj5qaEWzxrbT3Ynu8up05xX4yDTY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12354643426\"},\"deposit_events\":{\"counter\":\"26196\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30309\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"612\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"40543\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3848\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"113420\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11631\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"60883\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"45529\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"132734\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113796454671434417\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10123", + "blockHeight": "283151355", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 306, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 66, + "totalBytes": 258 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1276 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60", + "sequenceNumber": "13", + "maxGasAmount": "40", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1738092942" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "unlist_and_accept_token_bid" + }, + "arguments": [ + "{\"inner\":\"0x6ecdec1173f2e79aeab37fc2e2bdd43f36d7c169a153a1bf6e05246b21457e90\"}", + "{\"inner\":\"0xe89fe77893a9bbbfb89d747005e621d4cc9e30b6a5c5f9b419c7f784a3307a5\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::unlist_and_accept_token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "Oho059tQpX98PEOyKmD3H8tSrW20r6GzrfPObEwuyxA=", + "signature": "vVDRxEUVdUFd4E3fx9BwO6OTwDDrkjPTwtQvrVk5gUMzW+Xz9RRqThkv0G7dkLTMmRJqUu4UtjjXTAXYytjeDw==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0" + }, + "sequenceNumber": "8", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x6ecdec1173f2e79aeab37fc2e2bdd43f36d7c169a153a1bf6e05246b21457e90\",\"object\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"to\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "45528", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "DeleteListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::DeleteListingEvent", + "data": "{\"listing\":{\"inner\":\"0x6ecdec1173f2e79aeab37fc2e2bdd43f36d7c169a153a1bf6e05246b21457e90\"},\"price\":\"6000000\",\"seller\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"timestamp\":\"1738092852915658\",\"token\":{\"inner\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7" + }, + "sequenceNumber": "26195", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"150000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "149202", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"75000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2775000\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0" + }, + "sequenceNumber": "9", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"object\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"to\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\"}" + }, + { + "key": { + "creationNumber": "20", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "611", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "AcceptTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::AcceptTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0xe89fe77893a9bbbfb89d747005e621d4cc9e30b6a5c5f9b419c7f784a3307a5\"},\"bid_buyer\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"bid_seller\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"price\":\"3000000\",\"timestamp\":\"1738092852915658\",\"token\":{\"inner\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"13\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"112160\",\"total_charge_gas_units\":\"20\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296098846_tradeport_v2_accept_token_delist2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296098846_tradeport_v2_accept_token_delist2.json new file mode 100644 index 00000000000..a14e859b170 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296098846_tradeport_v2_accept_token_delist2.json @@ -0,0 +1,535 @@ +{ + "timestamp": { + "seconds": "1738220719", + "nanos": 436414000 + }, + "version": "2296098846", + "info": { + "hash": "XYdEw2WNv2x9ySEALaSioNwidRn55KvGaWaKTzumyrQ=", + "stateChangeHash": "Aq1CW+vgW70zrlP0p8b0gBTP6zUDJauZpdD7hZwPz2o=", + "eventRootHash": "nW9G3nf6QHoHyddChDPvuomAWvnc9xDSdFpe9EQMGwQ=", + "gasUsed": "20", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "VF+NDhTFTYMsj1gOqjTZq/A2XRdlKFYzzif7wZpzfR4=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x601d63ebac2606de806f319e03eebbc1d72e97d3636e565f6136fa3474e9dc06", + "stateKeyHash": "dBuhSGd4DZmV9cnzMysTbPalpiBZW9poQgAkRsyGk1I=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab", + "stateKeyHash": "1Fj8JHwzqA6z6TBA3RpdeSdjaF2YBUW9il+NLLzEIwM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"24268001\"},\"deposit_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7\",\"guid\":{\"id\":{\"addr\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab", + "stateKeyHash": "sekr1Wz4gFwqIvBIIEI+fklEo7ZEmzIrsGe9cMsSkOY=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"coin_register_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"11\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"13\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"10862744439\"},\"deposit_events\":{\"counter\":\"149331\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"23\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0xd8cc665d62192ecea331471956c854a15a6db7a13ba94b6aa5d75be430af0458\",\"transfer_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"elemental\",\"value\":{\"type\":9,\"value\":\"0x0446495245\"}},{\"key\":\"category\",\"value\":{\"type\":9,\"value\":\"0x096170746f6d696e676f\"}},{\"key\":\"grade\",\"value\":{\"type\":9,\"value\":\"0x06436f6d6d6f6e\"}},{\"key\":\"@probability_set\",\"value\":{\"type\":9,\"value\":\"0x0c67616d653a3a6578706f7274\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "royalty", + "name": "Royalty" + }, + "typeStr": "0x4::royalty::Royalty", + "data": "{\"denominator\":\"100\",\"numerator\":\"5\",\"payee_address\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"description\":\"I am a Sidekick, always standing by my Villain. When the bond between a Villain and me deepens, something special could happen!\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://public.vir.supervlabs.io/virweb/nft/sidekicks/mingo.png\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"291160\"},\"name\":{\"padding\":\"0x0000000000000000\",\"value\":\"Mingo #12541\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "sidekick", + "name": "Sidekick" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::sidekick::Sidekick", + "data": "{\"salt\":\"0\",\"updated_at\":\"1738028896\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmObject" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmObject", + "data": "{\"class\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"creator\":{\"inner\":\"0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6\"},\"delete_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"extend_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"transfer_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0", + "stateKeyHash": "HCdN5ItTehT8qEKwjDoHoenlf/7CyjpOBc/oU7is2ak=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmToken" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"property_mutator_ref\":{\"vec\":[{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}]},\"royalty_mutator_ref\":{\"vec\":[{\"inner\":{\"self\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7", + "stateKeyHash": "e3BUygmgtbbu9RwYj5qaEWzxrbT3Ynu8up05xX4yDTY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12367295121\"},\"deposit_events\":{\"counter\":\"26234\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xa4877fd357bbb3c4464765537ecd0936403d202002ae0c70f9808f94ecf5200c", + "stateKeyHash": "bfeY5/I80k/GA01HWAY8joxArU7SucTeaZ9A/gl2Nwk=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30363\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"624\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"40618\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3852\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"113573\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11661\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"60918\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"45629\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"133182\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113819635731724186\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10140", + "blockHeight": "283771098", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 306, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 66, + "totalBytes": 258 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1276 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab", + "sequenceNumber": "12", + "maxGasAmount": "40", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1738220808" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "unlist_and_accept_token_bid" + }, + "arguments": [ + "{\"inner\":\"0x601d63ebac2606de806f319e03eebbc1d72e97d3636e565f6136fa3474e9dc06\"}", + "{\"inner\":\"0xa4877fd357bbb3c4464765537ecd0936403d202002ae0c70f9808f94ecf5200c\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::unlist_and_accept_token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "mrCFAMGwEE717ZUin2MaY1c6M89i+nOZVtW6OSEOglg=", + "signature": "YhDHyryOBrQKQd+8kgd1EUQghcNKIWi6yDNL0EE00iEO1En6HGmVLlOs6G+m1dI+QzFza52JfcDWOag7An+MAA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0" + }, + "sequenceNumber": "11", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x601d63ebac2606de806f319e03eebbc1d72e97d3636e565f6136fa3474e9dc06\",\"object\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"to\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "45628", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "DeleteListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::DeleteListingEvent", + "data": "{\"listing\":{\"inner\":\"0x601d63ebac2606de806f319e03eebbc1d72e97d3636e565f6136fa3474e9dc06\"},\"price\":\"20000000\",\"seller\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"timestamp\":\"1738220719436414\",\"token\":{\"inner\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7" + }, + "sequenceNumber": "26233", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"100000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "149330", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"50000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"1850000\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0" + }, + "sequenceNumber": "12", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"object\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\",\"to\":\"0xd8cc665d62192ecea331471956c854a15a6db7a13ba94b6aa5d75be430af0458\"}" + }, + { + "key": { + "creationNumber": "20", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "623", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "AcceptTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::AcceptTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0xa4877fd357bbb3c4464765537ecd0936403d202002ae0c70f9808f94ecf5200c\"},\"bid_buyer\":\"0xd8cc665d62192ecea331471956c854a15a6db7a13ba94b6aa5d75be430af0458\",\"bid_seller\":\"0x65d8eb0656a9f3c6479671b37e6243cd322a5a4f042ce9e43ac968c2a84197ab\",\"price\":\"2000000\",\"timestamp\":\"1738220719436414\",\"token\":{\"inner\":\"0x6bc9d89f72ecc22dbca30025a10bc888cb1c90d6d6ee0d90f2739e6043557bf0\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"13\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"112160\",\"total_charge_gas_units\":\"20\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296149225_tradeport_v2_accept_token_delist.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296149225_tradeport_v2_accept_token_delist.json new file mode 100644 index 00000000000..16f78150fdc --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2296149225_tradeport_v2_accept_token_delist.json @@ -0,0 +1,563 @@ +{ + "timestamp": { + "seconds": "1738221494", + "nanos": 554632000 + }, + "version": "2296149225", + "info": { + "hash": "OJ6ZgbLo54vRkSXu/HW9TSPcEJcv2J3No/QXJ61yAqc=", + "stateChangeHash": "m2TbtUaYHUeNIOVPEbwMyNl4Oaot5Plg0ByCeGWXd2k=", + "eventRootHash": "1/GgkNvnRhzWMm4Zlix9gCwymUWyvkfmjJZGKOwiKZY=", + "gasUsed": "20", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "FuRYWYl0VFKM06JIyTxT7kvYYKsvdt7PmlAcOqCU9FU=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x23eac30752bcdfdc610896e50abc56237234634802b8b7b8b7ba21dfe5390e6", + "stateKeyHash": "ffy8nV+QK9NSrAwf9ZJH0IfI1dwSfi1QKNmSxDW3HEw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x142d4aaf554ebbebb41d6fab20964a6a64b5d9396f6bdacd2533479e589c4963", + "stateKeyHash": "fzQAjY06qXuGkbnQDXZ+5g/JWscXSTpFn85NenANg+s=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e", + "stateKeyHash": "dOhExhE4nIEDqCFvENbEAIdihmjZWeY5MadZ5Jo/wug=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"80374668\"},\"deposit_events\":{\"counter\":\"5\",\"guid\":{\"id\":{\"addr\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7\",\"guid\":{\"id\":{\"addr\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e", + "stateKeyHash": "sozZnJkSai2ZVg5q+PwY61kth8RVENG9+8at9WjitQo=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"coin_register_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"11\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"13\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"10863232439\"},\"deposit_events\":{\"counter\":\"149335\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"23\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7", + "stateKeyHash": "e3BUygmgtbbu9RwYj5qaEWzxrbT3Ynu8up05xX4yDTY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12368271121\"},\"deposit_events\":{\"counter\":\"26238\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"transfer_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"elemental\",\"value\":{\"type\":9,\"value\":\"0x0446495245\"}},{\"key\":\"category\",\"value\":{\"type\":9,\"value\":\"0x03646f67\"}},{\"key\":\"grade\",\"value\":{\"type\":9,\"value\":\"0x06436f6d6d6f6e\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x4", + "module": "royalty", + "name": "Royalty" + }, + "typeStr": "0x4::royalty::Royalty", + "data": "{\"denominator\":\"100\",\"numerator\":\"5\",\"payee_address\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"description\":\"I am a Sidekick, always standing by my Villain. When the bond between a Villain and me deepens, something special could happen!\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://public.vir.supervlabs.io/virweb/nft/sidekicks/shiba.png\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"157156\"},\"name\":{\"padding\":\"0x000000000000000000\",\"value\":\"Shiba #7141\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "gacha_rounds", + "name": "GachaRoundLog" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::gacha_rounds::GachaRoundLog", + "data": "{\"current_round\":\"117\",\"selected_round\":\"0\",\"updated_at\":\"1718721391549743\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "random", + "name": "RandOutputLog" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::random::RandOutputLog", + "data": "{\"list\":[{\"max\":\"100000000\",\"min\":\"0\",\"result\":\"41967892\"},{\"max\":\"13\",\"min\":\"1\",\"result\":\"1\"}]}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "sidekick", + "name": "Sidekick" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::sidekick::Sidekick", + "data": "{\"salt\":\"9588\",\"updated_at\":\"1718721391\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmObject" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmObject", + "data": "{\"class\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"creator\":{\"inner\":\"0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6\"},\"delete_ref\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]},\"extend_ref\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]},\"transfer_ref\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d", + "stateKeyHash": "ONRyFv1LAFKMA5VH4tL7lV3lruUBZ/3Catz0W/6ZysM=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmToken" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]},\"property_mutator_ref\":{\"vec\":[{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}]},\"royalty_mutator_ref\":{\"vec\":[{\"inner\":{\"self\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30363\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"627\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"40618\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3852\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"113573\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11661\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"60919\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"45632\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"133182\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113819573377132500\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10140", + "blockHeight": "283774916", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 306, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 66, + "totalBytes": 258 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1427 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e", + "sequenceNumber": "12", + "maxGasAmount": "40", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1738221583" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "unlist_and_accept_token_bid" + }, + "arguments": [ + "{\"inner\":\"0x23eac30752bcdfdc610896e50abc56237234634802b8b7b8b7ba21dfe5390e6\"}", + "{\"inner\":\"0x142d4aaf554ebbebb41d6fab20964a6a64b5d9396f6bdacd2533479e589c4963\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::unlist_and_accept_token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "wT6+JAv+YgeoKCF1m7bIRaOXGxfZ1koNm8GRbNTrwEE=", + "signature": "cC2td9GtpSUZKQW6z7LHzOPGzNrh4OHheFAaK1oz/tD8mSeoxZhfumwmSP1duLYd+iDk40QgK6KHNcbaIMfWDw==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d" + }, + "sequenceNumber": "8", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x23eac30752bcdfdc610896e50abc56237234634802b8b7b8b7ba21dfe5390e6\",\"object\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\",\"to\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "45631", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "DeleteListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::DeleteListingEvent", + "data": "{\"listing\":{\"inner\":\"0x23eac30752bcdfdc610896e50abc56237234634802b8b7b8b7ba21dfe5390e6\"},\"price\":\"9000000\",\"seller\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"timestamp\":\"1738221494554632\",\"token\":{\"inner\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7" + }, + "sequenceNumber": "26237", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"150000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "149334", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"75000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2775000\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d" + }, + "sequenceNumber": "9", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"object\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\",\"to\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\"}" + }, + { + "key": { + "creationNumber": "20", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "626", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "AcceptTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::AcceptTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0x142d4aaf554ebbebb41d6fab20964a6a64b5d9396f6bdacd2533479e589c4963\"},\"bid_buyer\":\"0x36f08a98302079f5bd60d811c0187171a7edaa352ae9907ae21a7014ff2dbc60\",\"bid_seller\":\"0x43d8f99000e4be09b1145832e9b1a98725fc7b4f63fd1ba3726b6266365fc39e\",\"price\":\"3000000\",\"timestamp\":\"1738221494554632\",\"token\":{\"inner\":\"0xdb3751353dd2d7edda6a3443a71a2656c2c477caebb3bce0ae50941741fcf12d\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"13\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"112160\",\"total_charge_gas_units\":\"20\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2298838662_tradeport_v2_fill_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2298838662_tradeport_v2_fill_offer.json new file mode 100644 index 00000000000..24dcc62d5e2 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2298838662_tradeport_v2_fill_offer.json @@ -0,0 +1,563 @@ +{ + "timestamp": { + "seconds": "1738263799", + "nanos": 318155000 + }, + "version": "2298838662", + "info": { + "hash": "VgSAZQzJPcRT5ZEEPfpPrqZN/ZlbhezhBBg4tzxpTaI=", + "stateChangeHash": "Z54NcLdBrFvWcXJG/o50EbOyEjtHmYUchRGyMLD7Gfw=", + "eventRootHash": "pMh9oGidH5bQQ5IWOx0xRqlktyQERko8GUhUJPKJSoM=", + "gasUsed": "20", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "Y06dhpAMg+F9XZX0r8XRGgYVW9bDS/lqOZCPLg38m6Q=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x1b4a34336112158ef3d58708f1d54da931c1ed9786c4b1f074498e2c19be4719", + "stateKeyHash": "FqthjBXFLLP/TmZC+mT60i5uzYGPhWPrun/rD5Ttwb0=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x4d575e42589f77401881170b9038fa0332fc8a40dd77bf260bf10023591ae891\",\"transfer_events\":{\"counter\":\"7\",\"guid\":{\"id\":{\"addr\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"elemental\",\"value\":{\"type\":9,\"value\":\"0x04574f4f44\"}},{\"key\":\"category\",\"value\":{\"type\":9,\"value\":\"0x056661697279\"}},{\"key\":\"grade\",\"value\":{\"type\":9,\"value\":\"0x06436f6d6d6f6e\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x4", + "module": "royalty", + "name": "Royalty" + }, + "typeStr": "0x4::royalty::Royalty", + "data": "{\"denominator\":\"100\",\"numerator\":\"5\",\"payee_address\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"description\":\"I am a Sidekick, always standing by my Villain. When the bond between a Villain and me deepens, something special could happen!\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://public.vir.supervlabs.io/virweb/nft/sidekicks/greeny.png\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"66118\"},\"name\":{\"padding\":\"0x0000000000000000\",\"value\":\"Greeny #3578\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "gacha_rounds", + "name": "GachaRoundLog" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::gacha_rounds::GachaRoundLog", + "data": "{\"current_round\":\"68\",\"selected_round\":\"0\",\"updated_at\":\"1713254600311352\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "random", + "name": "RandLog" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::random::RandLog", + "data": "{\"list\":[{\"i1\":\"0xad68439dd08605fd29881911f64c9ac4ed7ad02f005875bbe9eeb1bf90648be7\",\"i2\":\"1713254600311352\",\"i3\":\"100\",\"i4\":\"0x554d6cde3dc8f2c994af260a7a2085f81291f10d569ca732476d5a16260c4824\",\"max\":\"100000000\",\"min\":\"0\"},{\"i1\":\"0xad68439dd08605fd29881911f64c9ac4ed7ad02f005875bbe9eeb1bf90648be7\",\"i2\":\"1713254600311352\",\"i3\":\"877\",\"i4\":\"0x554d6cde3dc8f2c994af260a7a2085f81291f10d569ca732476d5a16260c4824\",\"max\":\"13\",\"min\":\"1\"}]}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6", + "module": "sidekick", + "name": "Sidekick" + }, + "typeStr": "0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6::sidekick::Sidekick", + "data": "{\"salt\":\"100\",\"updated_at\":\"1713254600\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmObject" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmObject", + "data": "{\"class\":{\"inner\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\"},\"creator\":{\"inner\":\"0x9d518b9b84f327eafc5f6632200ea224a818a935ffd6be5d78ada250bbc44a6\"},\"delete_ref\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]},\"extend_ref\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]},\"transfer_ref\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f", + "stateKeyHash": "WDhAmkHG4vQjye5WlpB57hIJCbf76nKLzej0pIMBPOE=", + "type": { + "address": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3", + "module": "orm_object", + "name": "OrmToken" + }, + "typeStr": "0xfacedd48d64a2ee04cbdf5c17608bd7a5ea9144fa1fe65320c588fffea131de3::orm_object::OrmToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]},\"property_mutator_ref\":{\"vec\":[{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}]},\"royalty_mutator_ref\":{\"vec\":[{\"inner\":{\"self\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72", + "stateKeyHash": "zK7ddVtDKFmYjpVmV/5JZ0Mz9FkHcsXtM1ln5JEZkhc=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"208065570\"},\"deposit_events\":{\"counter\":\"388\",\"guid\":{\"id\":{\"addr\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2203\",\"guid\":{\"id\":{\"addr\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72", + "stateKeyHash": "Jyr6V4gr+I2XpvcJql/GdzPetJjxe8uBY3IQaSdXG9M=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"coin_register_events\":{\"counter\":\"33\",\"guid\":{\"id\":{\"addr\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"1286\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1270\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"11011043110\"},\"deposit_events\":{\"counter\":\"149389\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"23\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7", + "stateKeyHash": "e3BUygmgtbbu9RwYj5qaEWzxrbT3Ynu8up05xX4yDTY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12374967220\"},\"deposit_events\":{\"counter\":\"26255\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xdb7392368c123f65922ba55c82cafab598aeea93ba83f8d217ef3a0093be54bf", + "stateKeyHash": "I1hG4NGDNmAcB5RDSmYjlBFA37Ws2z+9KIB6TV5f/CA=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30379\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"40624\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3852\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"113581\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11665\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"60946\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"45650\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"133250\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113810766359769605\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10146", + "blockHeight": "283990492", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 306, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 66, + "totalBytes": 258 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 1571 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72", + "sequenceNumber": "1269", + "maxGasAmount": "40", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1738263888" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "unlist_and_accept_token_bid" + }, + "arguments": [ + "{\"inner\":\"0x1b4a34336112158ef3d58708f1d54da931c1ed9786c4b1f074498e2c19be4719\"}", + "{\"inner\":\"0xdb7392368c123f65922ba55c82cafab598aeea93ba83f8d217ef3a0093be54bf\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::unlist_and_accept_token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "SoRAJvPZNYM+urrYSi/D1rmbVEqoO+FSQ5E8s8TAuPI=", + "signature": "TEi5O+2IRwQndW8O8elebO4gHHMMjm0UBSpazyu2tJAGyqCRG0fFRLCnViofPvyvgRHJaRaF+TEgC1pUFsDyBA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x1b4a34336112158ef3d58708f1d54da931c1ed9786c4b1f074498e2c19be4719\",\"object\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\",\"to\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "45649", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "DeleteListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::DeleteListingEvent", + "data": "{\"listing\":{\"inner\":\"0x1b4a34336112158ef3d58708f1d54da931c1ed9786c4b1f074498e2c19be4719\"},\"price\":\"50000000\",\"seller\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"timestamp\":\"1738263799318155\",\"token\":{\"inner\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x9d9ae026d65ad917bffcc6984370468e751ec3e9cd7a69f114c8a58c34d408b7" + }, + "sequenceNumber": "26254", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"500000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "149388", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"250000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72" + }, + "sequenceNumber": "387", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"9250000\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f" + }, + "sequenceNumber": "6", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"object\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\",\"to\":\"0x4d575e42589f77401881170b9038fa0332fc8a40dd77bf260bf10023591ae891\"}" + }, + { + "key": { + "creationNumber": "20", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "629", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "AcceptTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::AcceptTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0xdb7392368c123f65922ba55c82cafab598aeea93ba83f8d217ef3a0093be54bf\"},\"bid_buyer\":\"0x4d575e42589f77401881170b9038fa0332fc8a40dd77bf260bf10023591ae891\",\"bid_seller\":\"0x5c85d808ce379ba504a346508c878f72080ded0aa8b0df48b8eb2966d47a0a72\",\"price\":\"10000000\",\"timestamp\":\"1738263799318155\",\"token\":{\"inner\":\"0x496627a8924237cbcf4ac7efd743eee5e6004ab35bbad6c64a9280fa6ebea26f\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"13\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"112160\",\"total_charge_gas_units\":\"20\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2313248448_wapal_fill_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2313248448_wapal_fill_offer.json new file mode 100644 index 00000000000..c537fdf6dbd --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2313248448_wapal_fill_offer.json @@ -0,0 +1,545 @@ +{ + "timestamp": { + "seconds": "1738517570", + "nanos": 466815000 + }, + "version": "2313248448", + "info": { + "hash": "QwW/k6+7Wey4WQvPX4X024mevfiuf2h7HuSOqfZVzlg=", + "stateChangeHash": "9r33rTcrOLhks60eG5skep8lxn6LVJw6PBQbZqugGh8=", + "eventRootHash": "9ctX1/kHT4Tjh2riLd6VBT5UfhIRmCUL9zeLur8qrSk=", + "gasUsed": "30", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "nSK4Xn8kHl5nGB3QmNd4935jl2x8GOcMm1c/Xm0PzGg=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562", + "stateKeyHash": "fvjBO5IEqzNiVObviU8o0AcxtAqfZK4sUvsLkp1CzS0=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"999640005\"},\"deposit_events\":{\"counter\":\"30\",\"guid\":{\"id\":{\"addr\":\"0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"51\",\"guid\":{\"id\":{\"addr\":\"0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6", + "stateKeyHash": "EMqTMQksaw5v/er1udU4S/BFYuz2Ov0YBKb63F/2uGY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"28859565319\"},\"deposit_events\":{\"counter\":\"3639\",\"guid\":{\"id\":{\"addr\":\"0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"61\",\"guid\":{\"id\":{\"addr\":\"0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "stateKeyHash": "CnIoX/rU8s/MEWBmiMymIKAzkKuqzEhHPNEaXeZekPM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"42813802003\"},\"deposit_events\":{\"counter\":\"2495573\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"25\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"27576\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"77512\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"153879\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"73460\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"691082\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1770085\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9047\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77808\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x9d14c489b6f56ac55e8707022400c23bb83bd0b0cd486c862defccf6241a219e", + "stateKeyHash": "/DTBy6biPnGSeHv/rQkM0XX26vmAgUHqPjvMnfc0OMU=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14", + "stateKeyHash": "ptGzC3WgeGpmQ+ufD2RK21sdAc+zXBgEJvJigOXurzM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"3216164648\"},\"deposit_events\":{\"counter\":\"17\",\"guid\":{\"id\":{\"addr\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"20\",\"guid\":{\"id\":{\"addr\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14", + "stateKeyHash": "5tYuOAAcvEMS78Vt6pXOsj8sT1fWVHQvPIqVgrZtRP4=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"coin_register_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"22\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"74\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126", + "stateKeyHash": "9RqY26JbTo63xdxhhbTWbO5NYwQMyvUgsJj79715VoA=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562\",\"transfer_events\":{\"counter\":\"28\",\"guid\":{\"id\":{\"addr\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126", + "stateKeyHash": "9RqY26JbTo63xdxhhbTWbO5NYwQMyvUgsJj79715VoA=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\"}]},\"property_mutator_ref\":{\"self\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126", + "stateKeyHash": "9RqY26JbTo63xdxhhbTWbO5NYwQMyvUgsJj79715VoA=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126", + "stateKeyHash": "9RqY26JbTo63xdxhhbTWbO5NYwQMyvUgsJj79715VoA=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"description\":\"The Loonies is a collection of 5000 human PFPs. It's the official NFT collection by Wapal, the leading community-based NFT marketplace and launchpad on Aptos.\\n\\nDITCH LIMITS ⚡️\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://arweave.net/p_hpKSyXV3YXXhdDPOXQGsAYuI5YKcKitOm9DO9xAuI/399.json\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126", + "stateKeyHash": "9RqY26JbTo63xdxhhbTWbO5NYwQMyvUgsJj79715VoA=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"1891\"},\"name\":{\"padding\":\"0x00000000\",\"value\":\"The Loonies #399\"}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113842588164654499\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10182", + "blockHeight": "285278421", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 313, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 359 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 870 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14", + "sequenceNumber": "73", + "maxGasAmount": "60", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1738517660" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "token_offer" + }, + "name": "sell_tokenv2" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0x9d14c489b6f56ac55e8707022400c23bb83bd0b0cd486c862defccf6241a219e\"}" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::sell_tokenv2" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "uK9WDzFH5bPIaObVg+RiA4pDXiMzeB0maYco7fcDees=", + "signature": "tqwhIyCdDcZTNVAP+w7h3xyOLEQvyov3haKGlccqkmnCrtPHk9zMZqqUARr+83WP1BvdKW5xvyGPotH0UO0lCQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126" + }, + "sequenceNumber": "27", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"object\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\",\"to\":\"0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6" + }, + "sequenceNumber": "3638", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"142800000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9" + }, + "sequenceNumber": "2495572", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"51000000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14" + }, + "sequenceNumber": "16", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"3206200000\"}" + }, + { + "key": { + "creationNumber": "1125899906842635", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "599", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "TokenOfferFilledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::TokenOfferFilledEvent", + "data": "{\"commission\":\"51000000\",\"price\":\"3400000000\",\"purchaser\":\"0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562\",\"royalties\":\"142800000\",\"seller\":\"0xc60f124dc24f4ea97232bc5ead5f37252b7cbee47f48ef05932998050c414d14\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"}]},\"collection_name\":\"The Loonies\",\"creator_address\":\"0xf54f8f7ffc2b779d81b721b3d42fe9a53f96e1d3459a8001934307783d493725\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0xc821b5c1712fca97553c85830b91dc212cd2fcdd2a2490b65f945ed901d9f126\"}]},\"token_name\":\"The Loonies #399\"},\"token_offer\":\"0x9d14c489b6f56ac55e8707022400c23bb83bd0b0cd486c862defccf6241a219e\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x22113f16f9b7c6761ef14df757c016b8736a9023e8881cd5e11579b0b98ef562" + }, + "sequenceNumber": "29", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"0\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"23\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"63160\",\"total_charge_gas_units\":\"30\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381742315_wapal_cancel_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381742315_wapal_cancel_listing.json new file mode 100644 index 00000000000..9de637714a0 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381742315_wapal_cancel_listing.json @@ -0,0 +1,377 @@ +{ + "timestamp": { + "seconds": "1739898952", + "nanos": 960045000 + }, + "version": "2381742315", + "info": { + "hash": "2UQ2DoppaZkgYq3srOjz+PI3GFV8d5HZ675y9n1UrXE=", + "stateChangeHash": "BUzJXtEm8TXDSMgt11iDoGX6CSaN7qtCR0IaohZ6cuA=", + "eventRootHash": "Mjz4qFSGWKrk5eokDDA9E6yJCKdqGSnpmad1J4QJ7ms=", + "gasUsed": "14", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "bWvP4BN3OPoB0UfzBmuwZmmKr4noLnWccG6NozLkgcc=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293", + "stateKeyHash": "hDtQiei/k4yNgRlJmtYF3cpxy4EtQoquj19vhTTf0fI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"transfer_events\":{\"counter\":\"11\",\"guid\":{\"id\":{\"addr\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293", + "stateKeyHash": "hDtQiei/k4yNgRlJmtYF3cpxy4EtQoquj19vhTTf0fI=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\"}]},\"property_mutator_ref\":{\"self\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293", + "stateKeyHash": "hDtQiei/k4yNgRlJmtYF3cpxy4EtQoquj19vhTTf0fI=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293", + "stateKeyHash": "hDtQiei/k4yNgRlJmtYF3cpxy4EtQoquj19vhTTf0fI=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"description\":\"The Loonies is a collection of 5000 human PFPs. It's the official NFT collection by Wapal, the leading community-based NFT marketplace and launchpad on Aptos.\\n\\nDITCH LIMITS ⚡️\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://arweave.net/p_hpKSyXV3YXXhdDPOXQGsAYuI5YKcKitOm9DO9xAuI/3210.json\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293", + "stateKeyHash": "hDtQiei/k4yNgRlJmtYF3cpxy4EtQoquj19vhTTf0fI=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"1351\"},\"name\":{\"padding\":\"0x000000\",\"value\":\"The Loonies #3210\"}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x560197dcdc27af1cadc1cc75b51d9f0e3a0f40d7a761397c13bfdb4097924c1f", + "stateKeyHash": "OVL21jmU2HHxcnUxCQtaRFQH9Co9kMiZl0SOEkQvfPQ=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28184\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78048\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154728\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692261\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773300\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9075\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77859\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e", + "stateKeyHash": "ogHDIkWjeyR9OvNcu0982yW6p1O2r/U4Joileq2fiyg=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"17784903\"},\"deposit_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"5\",\"guid\":{\"id\":{\"addr\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e", + "stateKeyHash": "v9CRc6lWl+PSrmuF/JoB6YJ2Jjd0KQpWmBZjenGYSq8=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"coin_register_events\":{\"counter\":\"5\",\"guid\":{\"id\":{\"addr\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"15\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"194\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114060193964301574\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10374", + "blockHeight": "292395841", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 317, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 62, + "totalBytes": 323 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 871 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e", + "sequenceNumber": "193", + "maxGasAmount": "28", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739899042" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "coin_listing" + }, + "name": "end_fixed_price" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0x560197dcdc27af1cadc1cc75b51d9f0e3a0f40d7a761397c13bfdb4097924c1f\"}" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::coin_listing::end_fixed_price" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "MVUQCW2GGstiVSBD99QdWIqTpnwtkQLFI+HCerNpAs0=", + "signature": "VclecH5C6jq7VCx5oHjrvQoxJZXl9BkW8WZsAtTufEKxMFbioAFr56a/Z9NB7HajbgnKHgzYZw9JZ4NAiQqWBA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x00a8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293" + }, + "sequenceNumber": "10", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x560197dcdc27af1cadc1cc75b51d9f0e3a0f40d7a761397c13bfdb4097924c1f\",\"object\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\",\"to\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\"}" + }, + { + "key": { + "creationNumber": "1125899906842628", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "74310", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "ListingCanceledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::ListingCanceledEvent", + "data": "{\"listing\":\"0x560197dcdc27af1cadc1cc75b51d9f0e3a0f40d7a761397c13bfdb4097924c1f\",\"price\":\"3200000000\",\"seller\":\"0xecd896bfa7eae31fb5085dca8e2f3c88ea3577bd54fafeaeb4ad6ede1e13e81e\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"}]},\"collection_name\":\"The Loonies\",\"creator_address\":\"0xf54f8f7ffc2b779d81b721b3d42fe9a53f96e1d3459a8001934307783d493725\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0xa8b76ee68f7574dafb6f19988880c16571ccd10ac159a8684067a9fc0df293\"}]},\"token_name\":\"The Loonies #3210\"},\"type\":\"fixed price\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"8\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"62640\",\"total_charge_gas_units\":\"14\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381810159_wapal_cancel_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381810159_wapal_cancel_offer.json new file mode 100644 index 00000000000..94988e8b104 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2381810159_wapal_cancel_offer.json @@ -0,0 +1,303 @@ +{ + "timestamp": { + "seconds": "1739900115", + "nanos": 692708000 + }, + "version": "2381810159", + "info": { + "hash": "MG+F8DhmoVBjgt8PfnSyDr7vADgJlYl6cxh9JyEmcjo=", + "stateChangeHash": "1Z8OxWFz2tATl+HGaQpJvvNCALsAcwnY8x98QlWZUv8=", + "eventRootHash": "EuB5AwnM/hLmcwSHaRxTcfbvBfsPNI/p/EdsdXci88Q=", + "gasUsed": "16", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "Sukr33AJB9dKqGQetU/br84wRLHVSwYaptw/C4UQi5c=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x6132638f6078196e0a2c554cf195f08f73b56e672134c429cdda7f04272c3b13", + "stateKeyHash": "zwqNfbxj51JIyaK3jZ1MRoRgu8a3Qk0IVzBZhcXaA94=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a", + "stateKeyHash": "d+XtQCwiMzFkcm6d61f74jrLW7JkcBH1/qUZYMp6HBM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"30097930219\"},\"deposit_events\":{\"counter\":\"2189\",\"guid\":{\"id\":{\"addr\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2319\",\"guid\":{\"id\":{\"addr\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a", + "stateKeyHash": "+U88S6d+WvvLdwXhIE/tizv1Q8COIfN9raV8YUtilPM=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"coin_register_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"1085\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"5797\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28184\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78048\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154728\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692261\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773300\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77859\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114059809480760161\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10374", + "blockHeight": "292401684", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 307, + "eventSizeInfo": [ + { + "typeTagBytes": 65, + "totalBytes": 314 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a", + "sequenceNumber": "5796", + "maxGasAmount": "20", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739900203" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "token_offer" + }, + "name": "cancel" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0x6132638f6078196e0a2c554cf195f08f73b56e672134c429cdda7f04272c3b13\"}" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::cancel" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "3ljDucX/Hr+Fkwogem+SamNccf64m4DVjhhSCstUiCg=", + "signature": "ue4qM65zil8dd+P2OKTWRJZ0rVXEevt0TBdV/rc1xdFGsr1NTy2I+19t+JD1KVX+D0NoZs2p3L3Be17oZcHUDw==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842634", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "9077", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "TokenOfferCanceledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::TokenOfferCanceledEvent", + "data": "{\"price\":\"2800000000\",\"purchaser\":\"0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"}]},\"collection_name\":\"The Loonies\",\"creator_address\":\"0xf54f8f7ffc2b779d81b721b3d42fe9a53f96e1d3459a8001934307783d493725\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0x5eebc18e7f35cc5db4abd90631f35d0454cf0181fbd0042c023e858372b2e2a8\"}]},\"token_name\":\"The Loonies #1768\"},\"token_offer\":\"0x6132638f6078196e0a2c554cf195f08f73b56e672134c429cdda7f04272c3b13\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6ce9d41971de334c94541fcdd8f4cd2a69456057d444192e1257dacfc528ca0a" + }, + "sequenceNumber": "2188", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2800000000\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"10\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"63160\",\"total_charge_gas_units\":\"16\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382219668_wapal_fill_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382219668_wapal_fill_collection_offer.json new file mode 100644 index 00000000000..ca08fb35ca4 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382219668_wapal_fill_collection_offer.json @@ -0,0 +1,546 @@ +{ + "timestamp": { + "seconds": "1739908306", + "nanos": 707377000 + }, + "version": "2382219668", + "info": { + "hash": "+MKB6Qj8OiS19jwtMhGw5m9r47+9gNAZYsTBr8TrmDE=", + "stateChangeHash": "I8VT3jh9YPG34kGuWf1HD+b7+YAbsC0vhnm5IZy62to=", + "eventRootHash": "buSvd8Je9CaTvm4W5h5VHnKjlG3761NOEyEyk0GIbCQ=", + "gasUsed": "28", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "yTp/aFGBASzPT5rfYRqmdhZQQXGc+ajAJwa9DsH6MAI=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6", + "stateKeyHash": "EMqTMQksaw5v/er1udU4S/BFYuz2Ov0YBKb63F/2uGY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"17040483549\"},\"deposit_events\":{\"counter\":\"3747\",\"guid\":{\"id\":{\"addr\":\"0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"64\",\"guid\":{\"id\":{\"addr\":\"0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "stateKeyHash": "CnIoX/rU8s/MEWBmiMymIKAzkKuqzEhHPNEaXeZekPM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"43281703969\"},\"deposit_events\":{\"counter\":\"2500623\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"26\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2", + "stateKeyHash": "itoiDuFCtmfSP99PbS3l4EdeiQsxFiLiy64mY29NGr8=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"2453838459\"},\"deposit_events\":{\"counter\":\"209\",\"guid\":{\"id\":{\"addr\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"495\",\"guid\":{\"id\":{\"addr\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2", + "stateKeyHash": "oZeuTwgXWy+0nfNAJ8jTCLJo7xd35ZEISCLeLgWdPGY=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"coin_register_events\":{\"counter\":\"38\",\"guid\":{\"id\":{\"addr\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"159\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1254\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28185\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154729\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692269\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773310\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77859\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x8eb23351a1e2a9ed5d5516d6a592ec8fe8e3beeaedd7a7de9cdfc1cc8d9a0d73", + "stateKeyHash": "t0yeYU2yLxg3Vo5NTssJbigV2Umsbf5AIDdSg6Vg6l8=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22", + "stateKeyHash": "lsMQkeGa+zqCLJ+m0TGLUNxxvWPi3OPTWBOhKXKwtqo=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"5172029151\"},\"deposit_events\":{\"counter\":\"3931\",\"guid\":{\"id\":{\"addr\":\"0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"3424\",\"guid\":{\"id\":{\"addr\":\"0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229", + "stateKeyHash": "7SwsaRZxhJCswnE26sxDg3YTLXwctifP/Fj3a6uPIMs=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22\",\"transfer_events\":{\"counter\":\"22\",\"guid\":{\"id\":{\"addr\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229", + "stateKeyHash": "7SwsaRZxhJCswnE26sxDg3YTLXwctifP/Fj3a6uPIMs=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}]},\"property_mutator_ref\":{\"self\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229", + "stateKeyHash": "7SwsaRZxhJCswnE26sxDg3YTLXwctifP/Fj3a6uPIMs=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229", + "stateKeyHash": "7SwsaRZxhJCswnE26sxDg3YTLXwctifP/Fj3a6uPIMs=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"description\":\"The Loonies is a collection of 5000 human PFPs. It's the official NFT collection by Wapal, the leading community-based NFT marketplace and launchpad on Aptos.\\n\\nDITCH LIMITS ⚡️\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://arweave.net/p_hpKSyXV3YXXhdDPOXQGsAYuI5YKcKitOm9DO9xAuI/1339.json\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229", + "stateKeyHash": "7SwsaRZxhJCswnE26sxDg3YTLXwctifP/Fj3a6uPIMs=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"1487\"},\"name\":{\"padding\":\"0x000000\",\"value\":\"The Loonies #1339\"}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062601547091801\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292443982", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 351, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 68, + "totalBytes": 365 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 871 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2", + "sequenceNumber": "1253", + "maxGasAmount": "56", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739908397" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "collection_offer" + }, + "name": "sell_tokenv2" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0x8eb23351a1e2a9ed5d5516d6a592ec8fe8e3beeaedd7a7de9cdfc1cc8d9a0d73\"}", + "{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::sell_tokenv2" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "Qs7FhKPbf/RNzbM1bNjiazhvB3PjEtSJ20y4dHOq0vg=", + "signature": "3GbharcvKQrsnxC8oaAgNHHAGcD0ZsqZ9Er2TOVEP0NikfGtK0/M3ExiGCGyZIPIQHDbXFp9mWVWpV00r6HQBw==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229" + }, + "sequenceNumber": "21", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"object\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\",\"to\":\"0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6" + }, + "sequenceNumber": "3746", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"107121420\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9" + }, + "sequenceNumber": "2500622", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"38257650\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2" + }, + "sequenceNumber": "208", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2405130930\"}" + }, + { + "key": { + "creationNumber": "1125899906842632", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "78048", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "CollectionOfferFilledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::CollectionOfferFilledEvent", + "data": "{\"collection_offer\":\"0x8eb23351a1e2a9ed5d5516d6a592ec8fe8e3beeaedd7a7de9cdfc1cc8d9a0d73\",\"commission\":\"38257650\",\"price\":\"2550510000\",\"purchaser\":\"0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22\",\"royalties\":\"107121420\",\"seller\":\"0x67d1d1e79787a57df644b192f67959be26bb0330a5b8d782f13a324d86ee91b2\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"}]},\"collection_name\":\"The Loonies\",\"creator_address\":\"0xf54f8f7ffc2b779d81b721b3d42fe9a53f96e1d3459a8001934307783d493725\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}]},\"token_name\":\"The Loonies #1339\"}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xd098ed4c8a4fecfd082149216a1029ff1ed3d4dffd628348b018ed00036eec22" + }, + "sequenceNumber": "3930", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"0\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"8\",\"io_gas_units\":\"21\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"64480\",\"total_charge_gas_units\":\"28\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382221134_wapal_fill_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382221134_wapal_fill_listing.json new file mode 100644 index 00000000000..27133c45ab0 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382221134_wapal_fill_listing.json @@ -0,0 +1,1068 @@ +{ + "timestamp": { + "seconds": "1739908340", + "nanos": 290288000 + }, + "version": "2382221134", + "info": { + "hash": "o00Rn5rOAba9n5bT1228VC2fG45E6g/UhVywONacfY8=", + "stateChangeHash": "bB6knofg8ZJ+X8/STy7IVG1I1LlzJ1RxuPog7MfbeOw=", + "eventRootHash": "/ox3zDtxc7GJZHTyDNGcsP9UG+xILHdbC1+arg6E6yA=", + "gasUsed": "1493", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "sExdM9XKpPF0stElF06s2QPiqQz8Vh2+1EJYjSpst9E=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "kSJiqPFCska3SlG2fNyd46mssC9QXZVqf1lwRkrXuCM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"36521137143\"},\"deposit_events\":{\"counter\":\"7157\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7235\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "stateKeyHash": "CnIoX/rU8s/MEWBmiMymIKAzkKuqzEhHPNEaXeZekPM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"43287672469\"},\"deposit_events\":{\"counter\":\"2500624\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"26\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650", + "stateKeyHash": "jrLGIAldjKLN0xPzrpNQXv1b0WzZqLZ1ZONOMlpgat0=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"13725967085\"},\"deposit_events\":{\"counter\":\"14406\",\"guid\":{\"id\":{\"addr\":\"0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"24\",\"guid\":{\"id\":{\"addr\":\"0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"11614494730\"},\"deposit_events\":{\"counter\":\"150764\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"24\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28185\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154729\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692270\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773310\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77859\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726", + "stateKeyHash": "ht3PjI67UKgO0puYF4UkTR7CD79lMale6wrkehknQUw=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"919936045\"},\"deposit_events\":{\"counter\":\"525\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"835\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726", + "stateKeyHash": "Nn23UmPeaegsjXCSgXInfZQyAs9hE8t1NzHNfVCdAoE=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"coin_register_events\":{\"counter\":\"92\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"233\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"971\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726", + "stateKeyHash": "qdvdLgJUTcYsaIjKEb/cDXw3T88Q/PUAgYRAm0CTE4A=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"132\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"4\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0xaadb0671fadd64716243e40ca76a42e2147827be09ea16a9e99d795b37b463d1\"},\"withdraw_events\":{\"counter\":\"129\",\"guid\":{\"id\":{\"addr\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x7d618afb24770a0491e128c2d4db80598471795d76ed7a5bc0b88067b5f28d0d", + "stateKeyHash": "Z4B/6tZXvmuKL9X3KXJ0no3vWC1DQqH3uGkGuo8C0bI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "stateKeyHash": "5b0VaahYzzDgHb/FFnkMnUEShP6MG5h2KtgHmd1TO7s=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"1234594428\"},\"deposit_events\":{\"counter\":\"973\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1065\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "yqjAt6XexkjhclahvRVH6qR4Q/72t7jBQVorKxeECtI=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"20669\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"7\"}}},\"delete_listing_events\":{\"counter\":\"40260\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"6\"}}},\"insert_listing_events\":{\"counter\":\"72981\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"4\"}}},\"listings\":{\"handle\":\"0xefdd9245f9b45b09ca9cc0fa7dbe5214cb44b7dbac49d9eafeacedc9b5fec21e\"},\"update_listing_events\":{\"counter\":\"1136\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010", + "stateKeyHash": "zKuNaYlml9QP9p1H23M3PI1vCE1sp6mY4WNMnC7uhBs=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"855878250\"},\"deposit_events\":{\"counter\":\"1757\",\"guid\":{\"id\":{\"addr\":\"0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2209\",\"guid\":{\"id\":{\"addr\":\"0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xf244211ddd471bd7151410e4b4ecd8d22bb70eb3fee2736fdd3fdfe77bc6c4fd", + "stateKeyHash": "TR997ODfknzVuDOYGDUpuHUc6MxfuOouwJThxBC+PrE=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062610335615490\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "sYYoTPTUcPVsm11JZH4I7PSvFZYNKXrwljb1Dk14I5M=", + "handle": "0xaadb0671fadd64716243e40ca76a42e2147827be09ea16a9e99d795b37b463d1", + "key": "0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef20a427275682042656172730f4272756820426561722023333432380100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3428\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3428\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"level\",\"value\":{\"type\":\"u64\",\"value\":\"0xd201000000000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "akdpyEl/CHmID5XuEK+pQL//vVNrm9Bq7sE8znqMRg4=", + "handle": "0xaadb0671fadd64716243e40ca76a42e2147827be09ea16a9e99d795b37b463d1", + "key": "0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef20a427275682042656172730f4272756820426561722023333737300100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3770\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3770\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"level\",\"value\":{\"type\":\"u64\",\"value\":\"0x4800000000000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "Ox1dOHO+BJeab6+IMjlAutgjKiFBi1bgpOUAGfBHjWw=", + "handle": "0xaadb0671fadd64716243e40ca76a42e2147827be09ea16a9e99d795b37b463d1", + "key": "0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef20a427275682042656172730f4272756820426561722023343038340100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #4084\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #4084\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"level\",\"value\":{\"type\":\"u64\",\"value\":\"0x7402000000000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "UC+KzK4XJpqSZO4uuxvyqGRpz/u0p37Mr6HiL6hmnts=", + "handle": "0xefdd9245f9b45b09ca9cc0fa7dbe5214cb44b7dbac49d9eafeacedc9b5fec21e", + "key": "0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef20a427275682042656172730f4272756820426561722023333432380100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3428\"}}", + "keyType": "0x3::token::TokenId" + } + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "DtpEl4VIE/GMpuCrS3yRq00mgCysYfcbsU9nUyC7j2s=", + "handle": "0xefdd9245f9b45b09ca9cc0fa7dbe5214cb44b7dbac49d9eafeacedc9b5fec21e", + "key": "0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef20a427275682042656172730f4272756820426561722023333737300100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3770\"}}", + "keyType": "0x3::token::TokenId" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292444152", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 760, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 176 + }, + { + "typeTagBytes": 52, + "totalBytes": 247 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 53, + "totalBytes": 176 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 60, + "totalBytes": 310 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 176 + }, + { + "typeTagBytes": 52, + "totalBytes": 247 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 90, + "valueBytes": 224 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 101, + "valueBytes": 95 + }, + { + "keyBytes": 101, + "valueBytes": 95 + }, + { + "keyBytes": 101, + "valueBytes": 95 + }, + { + "keyBytes": 101 + }, + { + "keyBytes": 101 + } + ] + }, + "user": { + "request": { + "sender": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726", + "sequenceNumber": "970", + "maxGasAmount": "2986", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739908430" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "markets_v2" + }, + "name": "buy_tokens_v2" + }, + "arguments": [ + "[\"1\",\"1\",\"1\"]", + "[\"TradePort\",\"Wapal\",\"TradePort\"]", + "[\"0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010\",\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\"]", + "[\"398000000\",\"397900000\",\"398000000\"]", + "[\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\"]", + "[\"Bruh Bears\",\"Bruh Bears\",\"Bruh Bears\"]", + "[\"Bruh Bear #3428\",\"Bruh Bear #4084\",\"Bruh Bear #3770\"]", + "[\"1\",\"1\",\"1\"]", + "[\"0\",\"0\",\"0\"]", + "[\"0x0\",\"0x7d618afb24770a0491e128c2d4db80598471795d76ed7a5bc0b88067b5f28d0d\",\"0x0\"]" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::markets_v2::buy_tokens_v2" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "gQPVGQ+FdanHp4wNkHWdFD66oCkhdV699h4aXkIfwrs=", + "signature": "skqZkrqXeQJPqj72OAPxi+VWBdwaB4KhnDnQLl2edYB6MnqbQxrl1Zh/eNPBy6/M/VHN5FwVjUHsGHRr/Ur1Bg==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "827", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"21890000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650" + }, + "sequenceNumber": "14403", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"21890000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "828", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"9950000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150761", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"9950000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "829", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"366160000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010" + }, + "sequenceNumber": "1756", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"366160000\"}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "129", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3428\"}}}" + }, + { + "key": { + "creationNumber": "7", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "20667", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings::BuyEvent", + "data": "{\"buyer\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"owner\":\"0xed4f5679c427845c8695a6a3ef7b31af448cf90c0d1b3e35653d8acf2fffd010\",\"price\":\"398000000\",\"timestamp\":\"1739908340290288\",\"token_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3428\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "830", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"397900000\"}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "130", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #4084\"}}}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650" + }, + "sequenceNumber": "14404", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"21884500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9" + }, + "sequenceNumber": "2500623", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"5968500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b" + }, + "sequenceNumber": "972", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"370047000\"}" + }, + { + "key": { + "creationNumber": "1125899906842629", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "692269", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "ListingFilledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::ListingFilledEvent", + "data": "{\"commission\":\"5968500\",\"listing\":\"0x7d618afb24770a0491e128c2d4db80598471795d76ed7a5bc0b88067b5f28d0d\",\"price\":\"397900000\",\"purchaser\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"royalties\":\"21884500\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token_metadata\":{\"collection\":{\"vec\":[]},\"collection_name\":\"Bruh Bears\",\"creator_address\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"property_version\":{\"vec\":[\"1\"]},\"token\":{\"vec\":[]},\"token_name\":\"Bruh Bear #4084\"},\"type\":\"fixed price\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "831", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"21890000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x5aa4efe9703ffba6082906721756da68b9f7e8d256ed719cf49c40cab3938650" + }, + "sequenceNumber": "14405", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"21890000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "832", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"9950000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150762", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"9950000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "833", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"366160000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4" + }, + "sequenceNumber": "7156", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"366160000\"}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "131", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3770\"}}}" + }, + { + "key": { + "creationNumber": "7", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "20668", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings::BuyEvent", + "data": "{\"buyer\":\"0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726\",\"owner\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"price\":\"398000000\",\"timestamp\":\"1739908340290288\",\"token_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Bruh Bears\",\"creator\":\"0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2\",\"name\":\"Bruh Bear #3770\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x735507953f702ddad6dbf5a98de6fd3f57f50b89da9c68672414d8431f103726" + }, + "sequenceNumber": "834", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"4000000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150763", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"4000000\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"32\",\"io_gas_units\":\"29\",\"storage_fee_octas\":\"143280\",\"storage_fee_refund_octas\":\"219200\",\"total_charge_gas_units\":\"1493\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382251863_wapal_place_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382251863_wapal_place_listing.json new file mode 100644 index 00000000000..6b206856d82 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382251863_wapal_place_listing.json @@ -0,0 +1,400 @@ +{ + "timestamp": { + "seconds": "1739909050", + "nanos": 543248000 + }, + "version": "2382251863", + "info": { + "hash": "JcHXGOiJXFo9AAaA9A8n0mT5Uph8XJNpPlHDQ14rq30=", + "stateChangeHash": "CajDBNRT8l38Zt+ZTcd8ApSr8rfgUlSUnMzpnj4+IBo=", + "eventRootHash": "/BnkRhbfb9h7XHEzL2j9sU7zHdtE0Svzzhjze4v7qGs=", + "gasUsed": "19", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "q5Zjd5QX1+dBGkFxJ5uo4UVc5a9qIMdDpU4XpLcZdQI=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28188\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154731\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692270\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773321\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77859\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502", + "stateKeyHash": "Kp8OqvsQgmrFHTKNWLRhmpMheWF8Qd5ZlvGv27SQbic=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502", + "stateKeyHash": "Kp8OqvsQgmrFHTKNWLRhmpMheWF8Qd5ZlvGv27SQbic=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "coin_listing", + "name": "FixedPriceListing", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::coin_listing::FixedPriceListing<0x1::aptos_coin::AptosCoin>", + "data": "{\"price\":\"459900000\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502", + "stateKeyHash": "Kp8OqvsQgmrFHTKNWLRhmpMheWF8Qd5ZlvGv27SQbic=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "listing", + "name": "Listing" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::listing::Listing", + "data": "{\"delete_ref\":{\"self\":\"0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502\"},\"extend_ref\":{\"self\":\"0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502\"},\"fee_schedule\":{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"object\":{\"inner\":\"0xd88b304033e2b615d5fae295a9986313d3ea713f3a625d06ae686c26181dcc7e\"},\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505", + "stateKeyHash": "t9jRzZsZI/pIMB5ho5/yNKGdltNrLY06mUKM/K6PKcg=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505", + "stateKeyHash": "t9jRzZsZI/pIMB5ho5/yNKGdltNrLY06mUKM/K6PKcg=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "coin_listing", + "name": "FixedPriceListing", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::coin_listing::FixedPriceListing<0x1::aptos_coin::AptosCoin>", + "data": "{\"price\":\"459900000\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505", + "stateKeyHash": "t9jRzZsZI/pIMB5ho5/yNKGdltNrLY06mUKM/K6PKcg=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "listing", + "name": "Listing" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::listing::Listing", + "data": "{\"delete_ref\":{\"self\":\"0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505\"},\"extend_ref\":{\"self\":\"0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505\"},\"fee_schedule\":{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"object\":{\"inner\":\"0xbc600af43ac14abe414c209456a995baefadccf78cc1241b2119b6a8ebe98b06\"},\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "stateKeyHash": "5b0VaahYzzDgHb/FFnkMnUEShP6MG5h2KtgHmd1TO7s=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"1234460328\"},\"deposit_events\":{\"counter\":\"973\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1065\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "stateKeyHash": "/OOIo15/S8NhwWU8pHHCbdtrTv5XnSvbwSv3IlygeJE=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"coin_register_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"1342\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2407\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062610299697248\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292447858", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 383, + "eventSizeInfo": [ + { + "typeTagBytes": 60, + "totalBytes": 320 + }, + { + "typeTagBytes": 60, + "totalBytes": 319 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 87, + "valueBytes": 481 + }, + { + "keyBytes": 87, + "valueBytes": 481 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "sequenceNumber": "2406", + "maxGasAmount": "38", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739909141" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "marketplace_scripts" + }, + "name": "update_fixed_price_many" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "[\"0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505\",\"0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502\"]", + "[\"459900000\",\"459900000\"]" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::marketplace_scripts::update_fixed_price_many" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "fGvkKHnGZkyumjtIC85RbEostHPoXoKtf1R9WQZ1soE=", + "signature": "sRNmWhPFrkSgVlT/V8GEi8wLMhQ8f3yZ+KO2DrBziqRvhO36AiOy8Qwze8F63D7OqnChFp6VZNtOWTsw/AGMBw==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842627", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "1773319", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "ListingPlacedEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::ListingPlacedEvent", + "data": "{\"listing\":\"0xa67bf73aee5f50029a94fcfadc751b4818b42dd9123721e9c6872bdd3fd0b505\",\"price\":\"459900000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0x53858a7a4b6faf7cb2d198efe80351abc658d9cefcd2e95587f3d473cc90a041\"}]},\"collection_name\":\"Sloth balls\",\"creator_address\":\"0x7bc33fea1f7f5e7dc023c5cb041d0aadd664c8f738f619829095c19a9cc34e0\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0xbc600af43ac14abe414c209456a995baefadccf78cc1241b2119b6a8ebe98b06\"}]},\"token_name\":\"Sloth Ball #1938\"},\"type\":\"fixed price\"}" + }, + { + "key": { + "creationNumber": "1125899906842627", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "1773320", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "ListingPlacedEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::ListingPlacedEvent", + "data": "{\"listing\":\"0x7d3092ed4eab5a0ebffb73868748f06d15cae1b3d82d6bbaeebd33f5acd36502\",\"price\":\"459900000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0x53858a7a4b6faf7cb2d198efe80351abc658d9cefcd2e95587f3d473cc90a041\"}]},\"collection_name\":\"Sloth balls\",\"creator_address\":\"0x7bc33fea1f7f5e7dc023c5cb041d0aadd664c8f738f619829095c19a9cc34e0\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0xd88b304033e2b615d5fae295a9986313d3ea713f3a625d06ae686c26181dcc7e\"}]},\"token_name\":\"Sloth Ball #109\"},\"type\":\"fixed price\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"7\",\"io_gas_units\":\"12\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"19\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382313982_wapal_place_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382313982_wapal_place_offer.json new file mode 100644 index 00000000000..d0f25bc84c6 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382313982_wapal_place_offer.json @@ -0,0 +1,468 @@ +{ + "timestamp": { + "seconds": "1739910634", + "nanos": 289382000 + }, + "version": "2382313982", + "info": { + "hash": "vdW1lCRfMO7VSSqO+OVzgCoW0B+AUSuFxbK9lQEHV3w=", + "stateChangeHash": "sACKl4LOdku0IprpfquIJXSkYIIOn4rfsFPOY9t4FRk=", + "eventRootHash": "J9w/Fx+lxC5gU+DHLLW1DdsUNgcVWso7qITolyLjsHY=", + "gasUsed": "1278", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "6JbmIPw5IOxtztzh0kEKUtrtvdNOJMqygG/HKkQVTzk=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e", + "stateKeyHash": "cpNLbASMsACy94Kkrj1vHP1HjAvK3rfGQaloXHLTD6Q=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e", + "stateKeyHash": "cpNLbASMsACy94Kkrj1vHP1HjAvK3rfGQaloXHLTD6Q=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "token_offer", + "name": "CoinOffer", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::CoinOffer<0x1::aptos_coin::AptosCoin>", + "data": "{\"coins\":{\"value\":\"25000000\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e", + "stateKeyHash": "cpNLbASMsACy94Kkrj1vHP1HjAvK3rfGQaloXHLTD6Q=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "token_offer", + "name": "TokenOffer" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::TokenOffer", + "data": "{\"delete_ref\":{\"self\":\"0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e\"},\"expiration_time\":\"1739923200\",\"fee_schedule\":{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"item_price\":\"25000000\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e", + "stateKeyHash": "cpNLbASMsACy94Kkrj1vHP1HjAvK3rfGQaloXHLTD6Q=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "token_offer", + "name": "TokenOfferTokenV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::TokenOfferTokenV1", + "data": "{\"collection_name\":\"Aptos Dogs\",\"creator_address\":\"0xee814d743d2c3b4b1b8b30f3e0c84c7017df3154bda84c31958785f1d5b70e61\",\"property_version\":\"0\",\"token_name\":\"AptosDogs #1596\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "stateKeyHash": "CnIoX/rU8s/MEWBmiMymIKAzkKuqzEhHPNEaXeZekPM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"43287672469\"},\"deposit_events\":{\"counter\":\"2500630\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"26\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370", + "stateKeyHash": "IyRYVbJUBMkMuQaFggZjn111qLTWbH/eXoWTSRLZxVU=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"785074663\"},\"deposit_events\":{\"counter\":\"130\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"198\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370", + "stateKeyHash": "kpXwtHWZmkJREq5YDLqGVbaPLJ8ud7xjUhSL55k+sJE=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"coin_register_events\":{\"counter\":\"44\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"122\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"396\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370", + "stateKeyHash": "6jrw+W8XldFnMNc9FfPoUsIyLs0OR6vP+JKFQCsXQbE=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"14\"}}},\"deposit_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"12\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"15\"}}},\"tokens\":{\"handle\":\"0xd14836610466b216bb9ca3eb09fbf3fec6d3219b038b515ff2915d539192beda\"},\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"13\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370", + "stateKeyHash": "QHBVUTmMZACoSRvtLhOTg1vXmhatuv6WMLU3RqenNM4=", + "type": { + "address": "0x3", + "module": "token_event_store", + "name": "TokenEventStoreV1" + }, + "typeStr": "0x3::token_event_store::TokenEventStoreV1", + "data": "{\"collection_description_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"115\"}}},\"collection_maximum_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"114\"}}},\"collection_uri_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"113\"}}},\"default_property_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"118\"}}},\"description_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"119\"}}},\"extension\":{\"vec\":[]},\"maximum_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"121\"}}},\"opt_in_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"116\"}}},\"royalty_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"120\"}}},\"uri_mutate_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"creation_num\":\"117\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28188\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154731\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692270\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773321\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77860\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062714855835894\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292455993", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 412, + "eventSizeInfo": [ + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 71, + "totalBytes": 120 + }, + { + "typeTagBytes": 63, + "totalBytes": 253 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 529 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 104, + "valueBytes": 433 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370", + "sequenceNumber": "395", + "maxGasAmount": "2556", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739910724" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "token_offer" + }, + "name": "init_for_tokenv1_entry" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "\"0xee814d743d2c3b4b1b8b30f3e0c84c7017df3154bda84c31958785f1d5b70e61\"", + "\"Aptos Dogs\"", + "\"AptosDogs #1596\"", + "\"0\"", + "{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"}", + "\"25000000\"", + "\"1739923200\"" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::token_offer::init_for_tokenv1_entry" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "acCkjysfpSQy+nIQYG5FS906GeTnUafhxvZmFWNtlpk=", + "signature": "ex3BRinrrf+T5Dbo+DLaq8xy1jfdEsV1z31ktzU89KbaWUDNfbjQMKTzoz73SSfLjobBgFvkQMPpg1hnQFqSDg==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "2", + "accountAddress": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9" + }, + "sequenceNumber": "2500629", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"0\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370" + }, + "sequenceNumber": "197", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"25000000\"}" + }, + { + "key": { + "creationNumber": "116", + "accountAddress": "0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token_event_store", + "name": "OptInTransferEvent" + } + }, + "typeStr": "0x3::token_event_store::OptInTransferEvent", + "data": "{\"opt_in\":true}" + }, + { + "key": { + "creationNumber": "1125899906842633", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "77859", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "TokenOfferPlacedEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::TokenOfferPlacedEvent", + "data": "{\"price\":\"25000000\",\"purchaser\":\"0x62928b3712d452190346090807d5cfb40dabb54740cf1d2acfc5b4d3d9e0b370\",\"token_metadata\":{\"collection\":{\"vec\":[]},\"collection_name\":\"Aptos Dogs\",\"creator_address\":\"0xee814d743d2c3b4b1b8b30f3e0c84c7017df3154bda84c31958785f1d5b70e61\",\"property_version\":{\"vec\":[\"0\"]},\"token\":{\"vec\":[]},\"token_name\":\"AptosDogs #1596\"},\"token_offer\":\"0xdd69203952afa9962f3277f2be027fad3d21d57b986a61d674279d5e395323e\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"7\",\"io_gas_units\":\"12\",\"storage_fee_octas\":\"125960\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"1278\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373209_wapal_place_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373209_wapal_place_collection_offer.json new file mode 100644 index 00000000000..ffdc58daecf --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373209_wapal_place_collection_offer.json @@ -0,0 +1,410 @@ +{ + "timestamp": { + "seconds": "1739912240", + "nanos": 932749000 + }, + "version": "2382373209", + "info": { + "hash": "+2O2t8eCytS4YpEySEPyxRl56vzjJzhgfVmZ46y3sek=", + "stateChangeHash": "CsZvmLuuX9CcLjTmQncWIox78lRJ9o0DzkQCw4SAE0I=", + "eventRootHash": "5OJluPga8kSuxjHYE1vjf637j9I0JJSVGceadUgsl+s=", + "gasUsed": "661", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "o7E7OyXpLAeo4F8FKnZSnsV0Lm+AMPClKTx9BfpMHX0=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "stateKeyHash": "CnIoX/rU8s/MEWBmiMymIKAzkKuqzEhHPNEaXeZekPM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"43287672469\"},\"deposit_events\":{\"counter\":\"2500632\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"26\",\"guid\":{\"id\":{\"addr\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28189\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154733\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692270\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773321\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77860\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "stateKeyHash": "KsqT1JN2+xPyls4Z6XQ0VQ5qGiPo7TPIVShXAPtTPOk=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"186342221\"},\"deposit_events\":{\"counter\":\"502\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"861\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "stateKeyHash": "TSgc7JUH/xPSo1Mjho2il59yJ6Rdy2zwGV0fB8LIxKo=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"coin_register_events\":{\"counter\":\"27\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"721\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1253\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9", + "stateKeyHash": "4L8IVIqmTSuPIgcdhGHN3i0ZOfBNcHc46s/GyJMOGGI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9", + "stateKeyHash": "4L8IVIqmTSuPIgcdhGHN3i0ZOfBNcHc46s/GyJMOGGI=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "collection_offer", + "name": "CoinOffer", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::CoinOffer<0x1::aptos_coin::AptosCoin>", + "data": "{\"coins\":{\"value\":\"97600000\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9", + "stateKeyHash": "4L8IVIqmTSuPIgcdhGHN3i0ZOfBNcHc46s/GyJMOGGI=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "collection_offer", + "name": "CollectionOffer" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::CollectionOffer", + "data": "{\"delete_ref\":{\"self\":\"0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9\"},\"expiration_time\":\"1740700800\",\"fee_schedule\":{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"item_price\":\"24400000\",\"remaining\":\"4\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9", + "stateKeyHash": "4L8IVIqmTSuPIgcdhGHN3i0ZOfBNcHc46s/GyJMOGGI=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "collection_offer", + "name": "CollectionOfferTokenV2" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::CollectionOfferTokenV2", + "data": "{\"collection\":{\"inner\":\"0xd82f5841196bf66232316dc61188947583f418346b72758c0f45827cc5838617\"}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062480303824399\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292464304", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 388, + "eventSizeInfo": [ + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 68, + "totalBytes": 273 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 527 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "sequenceNumber": "1252", + "maxGasAmount": "1322", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739912331" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "collection_offer" + }, + "name": "init_for_tokenv2_entry" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0xd82f5841196bf66232316dc61188947583f418346b72758c0f45827cc5838617\"}", + "{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"}", + "\"24400000\"", + "\"4\"", + "\"1740700800\"" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::init_for_tokenv2_entry" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "jzTNxSbl1tG2PYddDaytN3LlJtYxugmmeV8TRRHmqh0=", + "signature": "TN8LiCIkTpf6Tq1iPdsIGD0QH153vnqgTBB+1wBLR9FWa5Y73wb7MlpmPLspukLmVQlXfgjwEVXntqph7V3zCQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "2", + "accountAddress": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9" + }, + "sequenceNumber": "2500631", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"0\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c" + }, + "sequenceNumber": "860", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"97600000\"}" + }, + { + "key": { + "creationNumber": "1125899906842630", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "154732", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "CollectionOfferPlacedEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::CollectionOfferPlacedEvent", + "data": "{\"collection_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xd82f5841196bf66232316dc61188947583f418346b72758c0f45827cc5838617\"}]},\"collection_name\":\"Cool Sloths\",\"creator_address\":\"0x7bc33fea1f7f5e7dc023c5cb041d0aadd664c8f738f619829095c19a9cc34e0\"},\"collection_offer\":\"0xff2ba0969dfe349d37cbabc28f922201b25ecd8102cb2960d62f9a4b64756de9\",\"price\":\"24400000\",\"purchaser\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"token_amount\":\"4\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"7\",\"io_gas_units\":\"10\",\"storage_fee_octas\":\"64480\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"661\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373978_wapal_cancel_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373978_wapal_cancel_collection_offer.json new file mode 100644 index 00000000000..ae6bd289b13 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2382373978_wapal_cancel_collection_offer.json @@ -0,0 +1,303 @@ +{ + "timestamp": { + "seconds": "1739912259", + "nanos": 38045000 + }, + "version": "2382373978", + "info": { + "hash": "dAtgKnR+kjQXAVxrJbgxBclzHjlySJevgg2RVC2cHbE=", + "stateChangeHash": "x3u7psiaoQTqD24rOh5bp2sLqXpxrNOpg6+2eEPuBnA=", + "eventRootHash": "VrJ2PzYWXE52klyDeAhjZCu38iU5TbzVW+3r/24bb/o=", + "gasUsed": "14", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "XIEfsIt/OdIBe9Dw16ivNb1krRpaAvx0+GzM+F5G21Y=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28190\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78049\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154733\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74311\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692270\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773321\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77860\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "stateKeyHash": "KsqT1JN2+xPyls4Z6XQ0VQ5qGiPo7TPIVShXAPtTPOk=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"283205301\"},\"deposit_events\":{\"counter\":\"503\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"861\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "stateKeyHash": "TSgc7JUH/xPSo1Mjho2il59yJ6Rdy2zwGV0fB8LIxKo=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"coin_register_events\":{\"counter\":\"27\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"721\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1254\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xeece745b73ee7615fc6634f2851eb84f07aa16f6a59f9343f395ca7ffafec899", + "stateKeyHash": "Mmj67e/Cp3NzgCZXa1dRIyZvVj5SU27I+t7nztLaVo4=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114062480294585364\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10375", + "blockHeight": "292464403", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 312, + "eventSizeInfo": [ + { + "typeTagBytes": 70, + "totalBytes": 275 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c", + "sequenceNumber": "1253", + "maxGasAmount": "28", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739912349" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "name": "collection_offer" + }, + "name": "cancel" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "{\"inner\":\"0xeece745b73ee7615fc6634f2851eb84f07aa16f6a59f9343f395ca7ffafec899\"}" + ], + "entryFunctionIdStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::collection_offer::cancel" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "jzTNxSbl1tG2PYddDaytN3LlJtYxugmmeV8TRRHmqh0=", + "signature": "hCLjxPrdmO5jfbsZA4kUoT+bJBMVLQAgylH5oAj1hKu2bRQF11oCkycYdu23DC3BnNh6sv6k5ALvSlRfwaygBA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842631", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "28189", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "CollectionOfferCanceledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::CollectionOfferCanceledEvent", + "data": "{\"collection_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0xd82f5841196bf66232316dc61188947583f418346b72758c0f45827cc5838617\"}]},\"collection_name\":\"Cool Sloths\",\"creator_address\":\"0x7bc33fea1f7f5e7dc023c5cb041d0aadd664c8f738f619829095c19a9cc34e0\"},\"collection_offer\":\"0xeece745b73ee7615fc6634f2851eb84f07aa16f6a59f9343f395ca7ffafec899\",\"price\":\"24200000\",\"purchaser\":\"0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c\",\"remaining_token_amount\":\"4\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xc8a05b0e489a00c2137a7b78de208fa678d87d4664dccf5b2848ad8a4425152c" + }, + "sequenceNumber": "502", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"96800000\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"9\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"64480\",\"total_charge_gas_units\":\"14\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386021136_tradeport_v2_fill_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386021136_tradeport_v2_fill_collection_offer.json new file mode 100644 index 00000000000..0c5482ef55c --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386021136_tradeport_v2_fill_collection_offer.json @@ -0,0 +1,434 @@ +{ + "timestamp": { + "seconds": "1739967219", + "nanos": 744142000 + }, + "version": "2386021136", + "info": { + "hash": "Ghrvk7yoDX2i96oBcavk+TtTSyybz5K2eVk+fqdAOn4=", + "stateChangeHash": "HJk3/5F0h/zislhrbjh+SZq2lf4nshpChG1Yf+tUFTg=", + "eventRootHash": "XNwLfssTF3QHCRoVjz1PJGoY3xkiB+Q0eS6MSSkBNKI=", + "gasUsed": "33", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "0EScfN5k1JT1q3rlYEjre0785E1k4vVJAFG50yJGIn0=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xe3c39dbed236c7ddcf847f9734baf8168911babd8384f17538102b17ab156bd", + "stateKeyHash": "17SYqUbyEjho5Gj3NVQWzLPGr/dpUOrVgCiSth5enwg=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d", + "stateKeyHash": "gJqWi0CJ+MuK3VXAnlp0S29arFczqUUedtYC8860U94=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"transfer_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d", + "stateKeyHash": "gJqWi0CJ+MuK3VXAnlp0S29arFczqUUedtYC8860U94=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"}]},\"property_mutator_ref\":{\"self\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d", + "stateKeyHash": "gJqWi0CJ+MuK3VXAnlp0S29arFczqUUedtYC8860U94=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"Eyes\",\"value\":{\"type\":9,\"value\":\"0x054861707079\"}},{\"key\":\"Headwear\",\"value\":{\"type\":9,\"value\":\"0x07427261696e6579\"}},{\"key\":\"Outfits\",\"value\":{\"type\":9,\"value\":\"0x05476f726564\"}},{\"key\":\"Skins\",\"value\":{\"type\":9,\"value\":\"0x0354616e\"}},{\"key\":\"Items\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Backgrounds\",\"value\":{\"type\":9,\"value\":\"0x05437265616d\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d", + "stateKeyHash": "gJqWi0CJ+MuK3VXAnlp0S29arFczqUUedtYC8860U94=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xae91e12aadaaa2d0e45a2f3dea52befe42002977e038edf53d15dbc298d64d89\"},\"description\":\"10,000 BITs, A key to the future of Eon Labs. Collect, Create, Vibe.\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"ipfs://QmV6ZywNPnNXtkQZQF82ND3Az3FzpuTBd9614BxKKtJNjV\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d", + "stateKeyHash": "gJqWi0CJ+MuK3VXAnlp0S29arFczqUUedtYC8860U94=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"1059\"},\"name\":{\"padding\":\"0x0000000000000000000000\",\"value\":\"BIT #3524\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"11973951477\"},\"deposit_events\":{\"counter\":\"150819\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"24\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90", + "stateKeyHash": "Tmognmf+Q297fd/j+zVu31WGUdSpfwPCdeqhXBej9RQ=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"48116540\"},\"deposit_events\":{\"counter\":\"291\",\"guid\":{\"id\":{\"addr\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"738\",\"guid\":{\"id\":{\"addr\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90", + "stateKeyHash": "bwvp098DFe4UeA6PX+tVBOy+qXPdOe3zcs+oVeUFRKM=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"coin_register_events\":{\"counter\":\"25\",\"guid\":{\"id\":{\"addr\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"426\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1389\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd456a5938d68b004c5b6341dbfb7f8e258ab3f0df08a978d785ee421b6ec9fa2", + "stateKeyHash": "usVY0WzXU52BSarHRVpsa0yE3FgmlhHFfdjkJFA2lZU=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12030463\"},\"deposit_events\":{\"counter\":\"1065\",\"guid\":{\"id\":{\"addr\":\"0xd456a5938d68b004c5b6341dbfb7f8e258ab3f0df08a978d785ee421b6ec9fa2\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"32\",\"guid\":{\"id\":{\"addr\":\"0xd456a5938d68b004c5b6341dbfb7f8e258ab3f0df08a978d785ee421b6ec9fa2\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30950\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"41264\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3873\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"114639\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11692\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114084854019894234\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10385", + "blockHeight": "292748902", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 438, + "eventSizeInfo": [ + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 71, + "totalBytes": 263 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 832 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90", + "sequenceNumber": "1388", + "maxGasAmount": "66", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739967310" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x7ccf0e6e871977c354c331aa0fccdffb562d9fceb27e3d7f61f8e12e470358e9", + "name": "aggregator" + }, + "name": "instant_sell" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "[\"0xe3c39dbed236c7ddcf847f9734baf8168911babd8384f17538102b17ab156bd\"]", + "[\"mercato\"]", + "[\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"]", + "[\"Bits\"]", + "[\"BIT #3524\"]", + "\"1\"", + "[\"0\"]", + "{\"inner\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"}", + "[\"1\"]" + ], + "entryFunctionIdStr": "0x7ccf0e6e871977c354c331aa0fccdffb562d9fceb27e3d7f61f8e12e470358e9::aggregator::instant_sell" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "OczGUbSkenxKAd/z4U2l2C7A059nfnUSrf3nJR7irXo=", + "signature": "WeVdoSAoPRoX3daPxP6ZVDHH896gJ/GKuywi+7CvJ4wBQCdSO0jT1QvFSnSG3qlkzA04SwP3/By1fI+Ye4UmDA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "2", + "accountAddress": "0xd456a5938d68b004c5b6341dbfb7f8e258ab3f0df08a978d785ee421b6ec9fa2" + }, + "sequenceNumber": "1064", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"1031500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150818", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"515750\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90" + }, + "sequenceNumber": "290", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"19082750\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"object\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\",\"to\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\"}" + }, + { + "key": { + "creationNumber": "23", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "30949", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "AcceptCollectionBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::AcceptCollectionBidEvent", + "data": "{\"bid\":{\"inner\":\"0xe3c39dbed236c7ddcf847f9734baf8168911babd8384f17538102b17ab156bd\"},\"bid_buyer\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"bid_seller\":\"0x756e65ad425f2baf916afb562c21a259ad3bf65f7bee439a562e03251859cf90\",\"price\":\"20630000\",\"timestamp\":\"1739967219744142\",\"token\":{\"inner\":\"0x1cad42fedce28de2e45b1de11e26abe0d540edae729341135388cdbec4b8262d\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"20\",\"io_gas_units\":\"14\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"55640\",\"total_charge_gas_units\":\"33\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386133936_tradeport_v2_place_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386133936_tradeport_v2_place_offer.json new file mode 100644 index 00000000000..1cf3b4c4bc2 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386133936_tradeport_v2_place_offer.json @@ -0,0 +1,240 @@ +{ + "timestamp": { + "seconds": "1739969888", + "nanos": 265903000 + }, + "version": "2386133936", + "info": { + "hash": "mNsFYqf1mOd2FQtrbtT1ZtpLZoUFpN93VARA3UyBSfA=", + "stateChangeHash": "bLkjtION2RdAaGrLWMgeWzUH3Y7YnfdKeh5TGXJQEtM=", + "eventRootHash": "Yu642k8pDy/xQjHZq4W7OQqHU2o7fpMwjRzw+tQ7koo=", + "gasUsed": "568", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "C7im/ed+QVKMa7FL3d+1UhHQihSSO/G4qSqmweivBfk=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172", + "stateKeyHash": "2CRij/kdJGtiu99L7xYmREtUtkxQQLMPMi0/laaasSs=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172", + "stateKeyHash": "2CRij/kdJGtiu99L7xYmREtUtkxQQLMPMi0/laaasSs=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "TokenBid" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::TokenBid", + "data": "{\"bid_buyer\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"coins\":{\"value\":\"3000000000\"},\"delete_ref\":{\"self\":\"0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172\"},\"token\":{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30950\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"41265\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3873\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"114737\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11693\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "stateKeyHash": "ng9+mevGUfoc5AR3vftd7PqgkTKm2V/50+aYfbQZf2c=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"260780793\"},\"deposit_events\":{\"counter\":\"89\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"135\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "stateKeyHash": "6bxz90Ogj9/Y37uaza8hgFOVDXjI3C/OTi459ELPWgo=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"coin_register_events\":{\"counter\":\"33\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"90\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"300\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114085190601556105\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10385", + "blockHeight": "292762673", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 264, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 66, + "totalBytes": 226 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 301 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "sequenceNumber": "299", + "maxGasAmount": "1136", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739969976" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "token_bid" + }, + "arguments": [ + "{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}", + "\"3000000000\"" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "4V6RdMWQI1vJnHxZUqGIrK5p5miGZpn3vFZGoeUiHPg=", + "signature": "Dx8vWxWm2aXihaCgnGceyva6+wWRfN2dHbj4i87IA+aWcq7yFNDrBwmEVaRNCX20BeyGyjQ0DbfK/viPyWtuBg==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "3", + "accountAddress": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202" + }, + "sequenceNumber": "134", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"3000000000\"}" + }, + { + "key": { + "creationNumber": "18", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "11692", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "InsertTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::InsertTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172\"},\"bid_buyer\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"price\":\"3000000000\",\"timestamp\":\"1739969888265903\",\"token\":{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"7\",\"io_gas_units\":\"7\",\"storage_fee_octas\":\"55440\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"568\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386142672_tradeport_v2_cancel_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386142672_tradeport_v2_cancel_offer.json new file mode 100644 index 00000000000..cca324ec71c --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386142672_tradeport_v2_cancel_offer.json @@ -0,0 +1,223 @@ +{ + "timestamp": { + "seconds": "1739970113", + "nanos": 672146000 + }, + "version": "2386142672", + "info": { + "hash": "kiwhMc/v8l8o5DmBexSVCT5935XIEly+As03na/ptNA=", + "stateChangeHash": "qf1cm9iNTlNhcwH3vwAxM6cne5zwcWn5Jrsr78QrYmA=", + "eventRootHash": "qSJCWS2ebZOTaD1S3xELbRxSPB1yN5RpWN19936mUuY=", + "gasUsed": "10", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "nU0FhJKYBPYpdNVbMV4cpSkoVxUyu7asu0M51uzEVFw=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172", + "stateKeyHash": "2CRij/kdJGtiu99L7xYmREtUtkxQQLMPMi0/laaasSs=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30950\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"41265\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3874\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"114738\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11693\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "stateKeyHash": "ng9+mevGUfoc5AR3vftd7PqgkTKm2V/50+aYfbQZf2c=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"3260835233\"},\"deposit_events\":{\"counter\":\"90\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"135\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "stateKeyHash": "6bxz90Ogj9/Y37uaza8hgFOVDXjI3C/OTi459ELPWgo=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"coin_register_events\":{\"counter\":\"33\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"90\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"301\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114085195631212555\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10385", + "blockHeight": "292763848", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 262, + "eventSizeInfo": [ + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 66, + "totalBytes": 226 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202", + "sequenceNumber": "300", + "maxGasAmount": "20", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739970201" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "cancel_token_bid" + }, + "arguments": [ + "{\"inner\":\"0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::cancel_token_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "4V6RdMWQI1vJnHxZUqGIrK5p5miGZpn3vFZGoeUiHPg=", + "signature": "SYbOHKaBVkj+uBKIdhdxxpq4PLyLCqChgmp7Abjoum6R+/gIG7eUjpDSbBhvTjVQpb0slr7Jz7LOQnf7Dh9FBA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "2", + "accountAddress": "0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202" + }, + "sequenceNumber": "89", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"3000000000\"}" + }, + { + "key": { + "creationNumber": "19", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "3873", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "DeleteTokenBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::DeleteTokenBidEvent", + "data": "{\"bid\":{\"inner\":\"0x892b542fbc8724a065e3c1138b637712ab063ab8db92680ef2533121b8fba172\"},\"bid_buyer\":\"0xf05f4dbe6ad3dfe4b626751b2bd7e5b9da81fe8b4dc63e56adb03d329559a202\",\"price\":\"3000000000\",\"timestamp\":\"1739970113672146\",\"token\":{\"inner\":\"0xfa0f4628e8737fe9149070e0aa5801a4c0c872f519fa622c363c7f397cf38229\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"55440\",\"total_charge_gas_units\":\"10\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386455218_tradeport_v2_fill_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386455218_tradeport_v2_fill_listing.json new file mode 100644 index 00000000000..d380e45471e --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386455218_tradeport_v2_fill_listing.json @@ -0,0 +1,1298 @@ +{ + "timestamp": { + "seconds": "1739978001", + "nanos": 822811000 + }, + "version": "2386455218", + "info": { + "hash": "01VnT77scqp+82AT6PwZrB2O5RbYAJUAV+HwYUU2ITU=", + "stateChangeHash": "FdKOx8uDjKvb1BbHbNrCLCRb3p+DaTT899iByYY+o7A=", + "eventRootHash": "tTg7N+4LfW+gotTe83vWE8fHepTgi2GB8iLH/h395ew=", + "gasUsed": "65", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "zyWGO88waYcV9Ek3lfL2necoscf7e1UlHRV+9oziYEE=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "kSJiqPFCska3SlG2fNyd46mssC9QXZVqf1lwRkrXuCM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"56421315284\"},\"deposit_events\":{\"counter\":\"7194\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7260\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3", + "stateKeyHash": "CpR9agEo6WJOyRGiXtQooOeImZhoDwLMDCKz3/QN9SM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"2030623591\"},\"deposit_events\":{\"counter\":\"3698\",\"guid\":{\"id\":{\"addr\":\"0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"19\",\"guid\":{\"id\":{\"addr\":\"0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x266aec1520a09e07ca8b831bbe6da9d419e259e8cc84e79e3d44c2051403c8cb", + "stateKeyHash": "4iwGYUW6bnSme6+Nie3LWIUNJMWB4sU+VSelnPoRPUI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374", + "stateKeyHash": "mYXpq0onTfLDNxYuJjxD6xUxeSPtSTi6KgUyT/lMTvU=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"117976684\"},\"deposit_events\":{\"counter\":\"810\",\"guid\":{\"id\":{\"addr\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2326\",\"guid\":{\"id\":{\"addr\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374", + "stateKeyHash": "Js4o4egqpmrW14o4GAz1FOCvB4jmYJqbNNQg4ADzX/Y=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"coin_register_events\":{\"counter\":\"55\",\"guid\":{\"id\":{\"addr\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"605\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2572\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5", + "stateKeyHash": "Nx/tbjMtJhjeIwDE9rrFQczUki+Pi4d2GL3jtlxSqtA=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"transfer_events\":{\"counter\":\"14\",\"guid\":{\"id\":{\"addr\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5", + "stateKeyHash": "Nx/tbjMtJhjeIwDE9rrFQczUki+Pi4d2GL3jtlxSqtA=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\"}]},\"property_mutator_ref\":{\"self\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5", + "stateKeyHash": "Nx/tbjMtJhjeIwDE9rrFQczUki+Pi4d2GL3jtlxSqtA=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"Background\",\"value\":{\"type\":9,\"value\":\"0x0441757261\"}},{\"key\":\"Effect BEHIND\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect FRONT\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Wings\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Mask\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Horn\",\"value\":{\"type\":9,\"value\":\"0x085265696e64656572\"}},{\"key\":\"Earrings\",\"value\":{\"type\":9,\"value\":\"0x045365616c\"}},{\"key\":\"Headwear\",\"value\":{\"type\":9,\"value\":\"0x09576869746562656172\"}},{\"key\":\"Mouth\",\"value\":{\"type\":9,\"value\":\"0x04436f6f6c\"}},{\"key\":\"Glasses\",\"value\":{\"type\":9,\"value\":\"0x0e4d617463686120476c6173736573\"}},{\"key\":\"Eyes\",\"value\":{\"type\":9,\"value\":\"0x044861696c\"}},{\"key\":\"Clothes\",\"value\":{\"type\":9,\"value\":\"0x08436172646967616e\"}},{\"key\":\"Base\",\"value\":{\"type\":9,\"value\":\"0x054e61697665\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5", + "stateKeyHash": "Nx/tbjMtJhjeIwDE9rrFQczUki+Pi4d2GL3jtlxSqtA=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xdf7175d95f236ac3f9fb581645498857bc42f90ff030527bcefe30c1558a6eac\"},\"description\":\"Ice Blue is a hidden resort for people to heal and find relaxation and peace after a difficult period.\",\"index\":\"697\",\"mutation_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"Ice Blue #1397\",\"uri\":\"ipfs://QmaNKKTo8CAyLC2YrdK1jvmfjxJE6Y5SpgRU5nL7kfnRXw\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4", + "stateKeyHash": "ia5CJAqvJ4lnS7nWhVMNNxhYGforZgoP0qtHcM/2+OM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"12793006216\"},\"deposit_events\":{\"counter\":\"150846\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"24\",\"guid\":{\"id\":{\"addr\":\"0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885", + "stateKeyHash": "RGVGiGAgJJAM1fbTg7d4qvejhdVakutf4M+u32WxpFY=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"transfer_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885", + "stateKeyHash": "RGVGiGAgJJAM1fbTg7d4qvejhdVakutf4M+u32WxpFY=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\"}]},\"property_mutator_ref\":{\"self\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885", + "stateKeyHash": "RGVGiGAgJJAM1fbTg7d4qvejhdVakutf4M+u32WxpFY=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"Mouth\",\"value\":{\"type\":9,\"value\":\"0x0a536865657220636f6c64\"}},{\"key\":\"Headwear\",\"value\":{\"type\":9,\"value\":\"0x09576869746562656172\"}},{\"key\":\"Earrings\",\"value\":{\"type\":9,\"value\":\"0x045365616c\"}},{\"key\":\"Effect BEHIND\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect FRONT\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Mask\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Glasses\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Wings\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Horn\",\"value\":{\"type\":9,\"value\":\"0x085265696e64656572\"}},{\"key\":\"Background\",\"value\":{\"type\":9,\"value\":\"0x0453616e64\"}},{\"key\":\"Base\",\"value\":{\"type\":9,\"value\":\"0x054e61697665\"}},{\"key\":\"Clothes\",\"value\":{\"type\":9,\"value\":\"0x08436172646967616e\"}},{\"key\":\"Eyes\",\"value\":{\"type\":9,\"value\":\"0x044861696c\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885", + "stateKeyHash": "RGVGiGAgJJAM1fbTg7d4qvejhdVakutf4M+u32WxpFY=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xdf7175d95f236ac3f9fb581645498857bc42f90ff030527bcefe30c1558a6eac\"},\"description\":\"Ice Blue is a hidden resort for people to heal and find relaxation and peace after a difficult period.\",\"index\":\"1311\",\"mutation_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"Ice Blue #1890\",\"uri\":\"ipfs://Qmf64CGfCejXvybCQZRVhQrkhjrvWVv2WZr7zRyr5P1AFS\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xb4576a3ec891f0508aedf9b907391e8aa2e467704f321a615cae8c8c730db76f", + "stateKeyHash": "3ZbMhWRlkhW59j52NY024K1iy5MrEAozJ52pCM/mZgo=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"1214445864\"},\"deposit_events\":{\"counter\":\"1646\",\"guid\":{\"id\":{\"addr\":\"0xb4576a3ec891f0508aedf9b907391e8aa2e467704f321a615cae8c8c730db76f\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2085\",\"guid\":{\"id\":{\"addr\":\"0xb4576a3ec891f0508aedf9b907391e8aa2e467704f321a615cae8c8c730db76f\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35", + "stateKeyHash": "oSinGY+QHFV+wDApq7q162uzO4zdHdeFmxx4zKjnwXM=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"transfer_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35", + "stateKeyHash": "oSinGY+QHFV+wDApq7q162uzO4zdHdeFmxx4zKjnwXM=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\"}]},\"property_mutator_ref\":{\"self\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35", + "stateKeyHash": "oSinGY+QHFV+wDApq7q162uzO4zdHdeFmxx4zKjnwXM=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"Mouth\",\"value\":{\"type\":9,\"value\":\"0x05416d757365\"}},{\"key\":\"Background\",\"value\":{\"type\":9,\"value\":\"0x044a616465\"}},{\"key\":\"Base\",\"value\":{\"type\":9,\"value\":\"0x054e61697665\"}},{\"key\":\"Clothes\",\"value\":{\"type\":9,\"value\":\"0x05477265656e\"}},{\"key\":\"Eyes\",\"value\":{\"type\":9,\"value\":\"0x044861696c\"}},{\"key\":\"Glasses\",\"value\":{\"type\":9,\"value\":\"0x0d536b696920676c617373657320\"}},{\"key\":\"Headwear\",\"value\":{\"type\":9,\"value\":\"0x09576869746562656172\"}},{\"key\":\"Earrings\",\"value\":{\"type\":9,\"value\":\"0x045365616c\"}},{\"key\":\"Horn\",\"value\":{\"type\":9,\"value\":\"0x0646726f737479\"}},{\"key\":\"Mask\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Wings\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect FRONT\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect BEHIND\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35", + "stateKeyHash": "oSinGY+QHFV+wDApq7q162uzO4zdHdeFmxx4zKjnwXM=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xdf7175d95f236ac3f9fb581645498857bc42f90ff030527bcefe30c1558a6eac\"},\"description\":\"Ice Blue is a hidden resort for people to heal and find relaxation and peace after a difficult period.\",\"index\":\"2275\",\"mutation_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"Ice Blue #2577\",\"uri\":\"ipfs://QmXm8X5paXaC72RoZCYcnE1xFZkMXy6er9vjgotDJarFNv\"}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xd14be2c5e5a6f5b0c1181c4d2f28b84511a1abed28eb49c88a7c67b248bd2d9d", + "stateKeyHash": "kdNKZEpYYw+h5DFoiyDVTAHFMwDunL4DshXTDxhoDuk=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59", + "stateKeyHash": "Q9PbX53c7nWDm1eXzv309w6JbzA+9B8RJHCxN6xq/fA=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"transfer_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59", + "stateKeyHash": "Q9PbX53c7nWDm1eXzv309w6JbzA+9B8RJHCxN6xq/fA=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\"}]},\"property_mutator_ref\":{\"self\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59", + "stateKeyHash": "Q9PbX53c7nWDm1eXzv309w6JbzA+9B8RJHCxN6xq/fA=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[{\"key\":\"Horn\",\"value\":{\"type\":9,\"value\":\"0x064d6f6f727365\"}},{\"key\":\"Mask\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Wings\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Mouth\",\"value\":{\"type\":9,\"value\":\"0x05416d757365\"}},{\"key\":\"Eyes\",\"value\":{\"type\":9,\"value\":\"0x044861696c\"}},{\"key\":\"Clothes\",\"value\":{\"type\":9,\"value\":\"0x08536e6f7720667572\"}},{\"key\":\"Base\",\"value\":{\"type\":9,\"value\":\"0x054e61697665\"}},{\"key\":\"Background\",\"value\":{\"type\":9,\"value\":\"0x0553756e6e79\"}},{\"key\":\"Glasses\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect BEHIND\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Headwear\",\"value\":{\"type\":9,\"value\":\"0x09537472696e67686174\"}},{\"key\":\"Earrings\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}},{\"key\":\"Effect FRONT\",\"value\":{\"type\":9,\"value\":\"0x044e6f6e65\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59", + "stateKeyHash": "Q9PbX53c7nWDm1eXzv309w6JbzA+9B8RJHCxN6xq/fA=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0xdf7175d95f236ac3f9fb581645498857bc42f90ff030527bcefe30c1558a6eac\"},\"description\":\"Ice Blue is a hidden resort for people to heal and find relaxation and peace after a difficult period.\",\"index\":\"22\",\"mutation_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"Ice Blue #1388\",\"uri\":\"ipfs://QmP5rRPGW3zy4qBa7vG83R2MGynwp5tyQ6Bjbq4NCsaRVK\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"61372\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"46143\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"135597\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xeea7e965045cd02bed0649694c2c7e1e60a68ffc600c55a8af7df5f27157c0e7", + "stateKeyHash": "uBySsGcAUVoBmrzgTqQvbtp7/zgfnptbTfObVm9oMtM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"726963530\"},\"deposit_events\":{\"counter\":\"8587\",\"guid\":{\"id\":{\"addr\":\"0xeea7e965045cd02bed0649694c2c7e1e60a68ffc600c55a8af7df5f27157c0e7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"12128\",\"guid\":{\"id\":{\"addr\":\"0xeea7e965045cd02bed0649694c2c7e1e60a68ffc600c55a8af7df5f27157c0e7\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xf0d4384157e8c7caac07e0866c4c65fa9df8151c329edf58b825ff7e9b72baf8", + "stateKeyHash": "XViv45qWMchsvksXVNEmiTgJcsUZ/DJr6d0YoWClErU=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xf0d4a40c5c2e9806e464b45e5c0d04545a52f44459568cbc163bec1211aaf7df", + "stateKeyHash": "PzJr43NuiFQBWhXL0RMj6h+mcUZZ83oeNBLBWgl9rfo=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114085797854695479\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10386", + "blockHeight": "292804244", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 627, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 55, + "totalBytes": 247 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 55, + "totalBytes": 247 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 55, + "totalBytes": 247 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 55, + "totalBytes": 247 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 920 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 916 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 915 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 910 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374", + "sequenceNumber": "2571", + "maxGasAmount": "130", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739978091" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x7ccf0e6e871977c354c331aa0fccdffb562d9fceb27e3d7f61f8e12e470358e9", + "name": "aggregator" + }, + "name": "purchase_many" + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ], + "arguments": [ + "[\"0xf0d4a40c5c2e9806e464b45e5c0d04545a52f44459568cbc163bec1211aaf7df\",\"0x266aec1520a09e07ca8b831bbe6da9d419e259e8cc84e79e3d44c2051403c8cb\",\"0xf0d4384157e8c7caac07e0866c4c65fa9df8151c329edf58b825ff7e9b72baf8\",\"0xd14be2c5e5a6f5b0c1181c4d2f28b84511a1abed28eb49c88a7c67b248bd2d9d\"]", + "[\"mercato\",\"mercato\",\"mercato\",\"mercato\"]", + "\"0x791991536b698ef3bc3270624748bbfc79a17793ec5472fbeb864d2df63cfebc\"", + "\"Ice Blue\"", + "[\"Ice Blue #1397\",\"Ice Blue #2577\",\"Ice Blue #1890\",\"Ice Blue #1388\"]", + "[\"0\",\"0\",\"0\",\"0\"]", + "[\"164860000\",\"164900000\",\"165000000\",\"166240000\"]", + "\"1\"" + ], + "entryFunctionIdStr": "0x7ccf0e6e871977c354c331aa0fccdffb562d9fceb27e3d7f61f8e12e470358e9::aggregator::purchase_many" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "DjXLB6aMmOL84UA7t1zMRhTEftK0qs4nb8PqiFT36+w=", + "signature": "FP/Xym1/fdo93vzejZ5WjVh4+aOqKWCkmHEYgs2sHv53OzOKkuekijSGA4LbzVYQRZPoqvyR5gq4GDJp3f6+DA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2314", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"13188800\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3" + }, + "sequenceNumber": "3694", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"13188800\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2315", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"4121500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150842", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"4121500\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2316", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"147549700\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xb4576a3ec891f0508aedf9b907391e8aa2e467704f321a615cae8c8c730db76f" + }, + "sequenceNumber": "1645", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"147549700\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5" + }, + "sequenceNumber": "13", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xf0d4a40c5c2e9806e464b45e5c0d04545a52f44459568cbc163bec1211aaf7df\",\"object\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\",\"to\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\"}" + }, + { + "key": { + "creationNumber": "17", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "61368", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::BuyEvent", + "data": "{\"buyer\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"listing\":{\"inner\":\"0xf0d4a40c5c2e9806e464b45e5c0d04545a52f44459568cbc163bec1211aaf7df\"},\"price\":\"164860000\",\"seller\":\"0xb4576a3ec891f0508aedf9b907391e8aa2e467704f321a615cae8c8c730db76f\",\"timestamp\":\"1739978001822811\",\"token\":{\"inner\":\"0x2d3df7ab1e81459bf92e65cace8b8986da3c91be8d10029d1cd156edfb2317d5\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2317", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"13192000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3" + }, + "sequenceNumber": "3695", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"13192000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2318", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"4122500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150843", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"4122500\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2319", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"147585500\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xeea7e965045cd02bed0649694c2c7e1e60a68ffc600c55a8af7df5f27157c0e7" + }, + "sequenceNumber": "8586", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"147585500\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35" + }, + "sequenceNumber": "11", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x266aec1520a09e07ca8b831bbe6da9d419e259e8cc84e79e3d44c2051403c8cb\",\"object\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\",\"to\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\"}" + }, + { + "key": { + "creationNumber": "17", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "61369", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::BuyEvent", + "data": "{\"buyer\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"listing\":{\"inner\":\"0x266aec1520a09e07ca8b831bbe6da9d419e259e8cc84e79e3d44c2051403c8cb\"},\"price\":\"164900000\",\"seller\":\"0xeea7e965045cd02bed0649694c2c7e1e60a68ffc600c55a8af7df5f27157c0e7\",\"timestamp\":\"1739978001822811\",\"token\":{\"inner\":\"0xc473007e12bdeec420c383127a77e83236731aa22174f2af94a1476183644f35\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2320", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"13200000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3" + }, + "sequenceNumber": "3696", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"13200000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2321", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"4125000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150844", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"4125000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2322", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"147675000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4" + }, + "sequenceNumber": "7192", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"147675000\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885" + }, + "sequenceNumber": "11", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xf0d4384157e8c7caac07e0866c4c65fa9df8151c329edf58b825ff7e9b72baf8\",\"object\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\",\"to\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\"}" + }, + { + "key": { + "creationNumber": "17", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "61370", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::BuyEvent", + "data": "{\"buyer\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"listing\":{\"inner\":\"0xf0d4384157e8c7caac07e0866c4c65fa9df8151c329edf58b825ff7e9b72baf8\"},\"price\":\"165000000\",\"seller\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"timestamp\":\"1739978001822811\",\"token\":{\"inner\":\"0x9e5d1a8c276e1153bacfc46a94b417b9d2effb62baca30000d5e419ad7e53885\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2323", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"13299200\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x189365d87b89fece2ba6b9411ce750a05cb1d3e4715107836117137da2d24fe3" + }, + "sequenceNumber": "3697", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"13299200\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2324", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"4156000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x6a03eb973cd9385d62fc2842d02a4dd6b70e52f5da77a0689e57e48d93fae1b4" + }, + "sequenceNumber": "150845", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"4156000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374" + }, + "sequenceNumber": "2325", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"148784800\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4" + }, + "sequenceNumber": "7193", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"148784800\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59" + }, + "sequenceNumber": "9", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xd14be2c5e5a6f5b0c1181c4d2f28b84511a1abed28eb49c88a7c67b248bd2d9d\",\"object\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\",\"to\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\"}" + }, + { + "key": { + "creationNumber": "17", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "61371", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "BuyEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::BuyEvent", + "data": "{\"buyer\":\"0x27e8e9a9ebadb462322bca29352c3a0d24f5b80caa03a529cb71a69b6a09c374\",\"listing\":{\"inner\":\"0xd14be2c5e5a6f5b0c1181c4d2f28b84511a1abed28eb49c88a7c67b248bd2d9d\"},\"price\":\"166240000\",\"seller\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"timestamp\":\"1739978001822811\",\"token\":{\"inner\":\"0xe0ad60b5be1a160e19257812c19a0a347d443500bdf8ec442cfe5f820169de59\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"35\",\"io_gas_units\":\"30\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"226880\",\"total_charge_gas_units\":\"65\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386716658_tradeport_v2_cancel_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386716658_tradeport_v2_cancel_listing.json new file mode 100644 index 00000000000..4f8a7c048bd --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386716658_tradeport_v2_cancel_listing.json @@ -0,0 +1,325 @@ +{ + "timestamp": { + "seconds": "1739985031", + "nanos": 402031000 + }, + "version": "2386716658", + "info": { + "hash": "NlOlWkMfv3AdxUvg0076Br5hhSzShzpYoAuJaNnset8=", + "stateChangeHash": "fhYJWYIXFie3x9LFhaIwyfpqApfdgxyFfsNKYuzSXpk=", + "eventRootHash": "pScJskK8i51LmErG6GOWcDleQj44bGrdqSkl7IVARiM=", + "gasUsed": "10", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "q7pjuv2nTcwavOTALw6ydrUtvuymgyWLtSmBvjiYu68=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce", + "stateKeyHash": "K+lQ4IfGoax6BsDXyU0WDzQ/ELh/LPIo+97Q1pKGOKE=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"1307595\"},\"deposit_events\":{\"counter\":\"19604\",\"guid\":{\"id\":{\"addr\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"22052\",\"guid\":{\"id\":{\"addr\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce", + "stateKeyHash": "dbnVjRIZ5dnLDP1GnUgYBv0NbJTew0ELQhZBqJiJQn4=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"coin_register_events\":{\"counter\":\"25\",\"guid\":{\"id\":{\"addr\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"5039\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"52946\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"61372\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"46146\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"135603\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0xe2e50b7366c7a5e5f7b6ec024465b4444f02bd0b3eed5c9d4fdfe98236f85555", + "stateKeyHash": "yzS9G1EDglfNCleiambCXBJgQ1NzVoGsDoisDNpS9B8=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"122377704693\",\"frozen\":true,\"metadata\":{\"inner\":\"0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"transfer_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\"},\"description\":\"NFT representing voting power in Cellana corresponding to $CELL locked up\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://api.cellana.finance/api/v1/ve-nft/uri/@0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"383712\"},\"name\":{\"padding\":\"0x0000000000000000000000000000\",\"value\":\"veCELL\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "module": "voting_escrow", + "name": "VeCellanaDeleteRef" + }, + "typeStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::VeCellanaDeleteRef", + "data": "{\"delete_ref\":{\"self\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "module": "voting_escrow", + "name": "VeCellanaToken" + }, + "typeStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::VeCellanaToken", + "data": "{\"end_epoch\":\"2980\",\"locked_amount\":\"122377704693\",\"next_rebase_epoch\":\"2876\",\"snapshots\":{\"big_vec\":{\"vec\":[]},\"bucket_size\":{\"vec\":[]},\"inline_capacity\":{\"vec\":[]},\"inline_vec\":[{\"end_epoch\":\"2980\",\"epoch\":\"2876\",\"locked_amount\":\"122377704693\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218", + "stateKeyHash": "2nWy3jH1lfZtVtDENX6yYOVI5iKA5S4ui77jKecH7nc=", + "type": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "module": "voting_escrow", + "name": "VeCellanaTokenRefs" + }, + "typeStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::VeCellanaTokenRefs", + "data": "{\"burn_ref\":{\"inner\":{\"vec\":[{\"self\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\"}]},\"self\":{\"vec\":[]}},\"transfer_ref\":{\"self\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\"}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114087966002510937\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10387", + "blockHeight": "292840561", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 258, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 1004 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce", + "sequenceNumber": "52945", + "maxGasAmount": "12", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739985107" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "listings_v2" + }, + "name": "unlist_token" + }, + "arguments": [ + "{\"inner\":\"0xe2e50b7366c7a5e5f7b6ec024465b4444f02bd0b3eed5c9d4fdfe98236f85555\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::unlist_token" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "noZyne/i0eyr3+hoixjrQpCa5O5SzQUqNWE+OiViO4Q=", + "signature": "yFMy0yTknkCijL8PQ3kdavpC184erHe68sRgWdI46BstS289DzfPgrPY9m9k//y/WC+l0VAL+KL/ZHEqDFYSBA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xe2e50b7366c7a5e5f7b6ec024465b4444f02bd0b3eed5c9d4fdfe98236f85555\",\"object\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\",\"to\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "46145", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "DeleteListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::DeleteListingEvent", + "data": "{\"listing\":{\"inner\":\"0xe2e50b7366c7a5e5f7b6ec024465b4444f02bd0b3eed5c9d4fdfe98236f85555\"},\"price\":\"300000000\",\"seller\":\"0x7650b060223321d2a7a409abaca386b7e104910878bb5c463f0cbd727561f1ce\",\"timestamp\":\"1739985031402031\",\"token\":{\"inner\":\"0xf8ad2d07e1df7dfb81a63784c102996c391b040a62b8bb6e181fd649ef688218\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"56720\",\"total_charge_gas_units\":\"10\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386809975_tradeport_v2_place_listing.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386809975_tradeport_v2_place_listing.json new file mode 100644 index 00000000000..3cac5aa1f0b --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386809975_tradeport_v2_place_listing.json @@ -0,0 +1,616 @@ +{ + "timestamp": { + "seconds": "1739988091", + "nanos": 944133000 + }, + "version": "2386809975", + "info": { + "hash": "YhkN3JCbGTBcjf1SfGHBux/Ybl/yz4Cxn8kSFEpL8LA=", + "stateChangeHash": "kshVTtgrHuRm3Cz/0mVrLz0iIjBlHibWAJQwISN4+fs=", + "eventRootHash": "VW4peTuNKUKy6Ga4ViUU+gXqZDHx8jRH3nTgVIdyetI=", + "gasUsed": "1168", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "On8e62sOuOxxsz5cDTf/UPqeDd3/4sW8YFl6Kh40v58=", + "changes": [ + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x254d2eccf3a4736a62f4e9eb8685fa54bb4c98a450c7c71fd4da1c6cb203855f", + "stateKeyHash": "wcpCKl8yR83C0FXuuEulbmFkfA8TrS3xWbQxIeYWSsU=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb", + "stateKeyHash": "hOAQsoouQp7V/58t2Y7VkhYNiwwek5ghGodWSQo9qVs=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb", + "stateKeyHash": "hOAQsoouQp7V/58t2Y7VkhYNiwwek5ghGodWSQo9qVs=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "Listing" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::Listing", + "data": "{\"delete_ref\":{\"self\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\"},\"extend_ref\":{\"self\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\"},\"price\":\"119000000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token\":{\"inner\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c", + "stateKeyHash": "UsaAk/CETGvo7nwt82uDRtM123aprkkOwJejlsJ32mw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c", + "stateKeyHash": "UsaAk/CETGvo7nwt82uDRtM123aprkkOwJejlsJ32mw=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "Listing" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::Listing", + "data": "{\"delete_ref\":{\"self\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\"},\"extend_ref\":{\"self\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\"},\"price\":\"119000000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token\":{\"inner\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842636\",\"owner\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "EventsV1" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::EventsV1", + "data": "{\"auction_bid_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842626\"}}},\"collection_offer_canceled_events\":{\"counter\":\"28213\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842631\"}}},\"collection_offer_filled_events\":{\"counter\":\"78064\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842632\"}}},\"collection_offer_placed_events\":{\"counter\":\"154760\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842630\"}}},\"listing_canceled_events\":{\"counter\":\"74388\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842628\"}}},\"listing_filled_events\":{\"counter\":\"692349\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842629\"}}},\"listing_placed_events\":{\"counter\":\"1773587\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842627\"}}},\"token_offer_canceled_events\":{\"counter\":\"9078\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842634\"}}},\"token_offer_filled_events\":{\"counter\":\"600\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842635\"}}},\"token_offer_placed_events\":{\"counter\":\"77862\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842633\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FeeSchedule" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FeeSchedule", + "data": "{\"extend_ref\":{\"self\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\"},\"fee_address\":\"0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08\",\"creation_num\":\"1125899906842625\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateBiddingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateBiddingFee", + "data": "{\"bidding_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "FixedRateListingFee" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::FixedRateListingFee", + "data": "{\"listing_fee\":\"0\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08", + "stateKeyHash": "auABzXqPl+Vs2d6YJuBQ5tt+4LBOBje/7ssPbckNThw=", + "type": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "fee_schedule", + "name": "PercentageRateCommission" + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::fee_schedule::PercentageRateCommission", + "data": "{\"denominator\":\"1000\",\"numerator\":\"15\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf", + "stateKeyHash": "6WA49u1ciQXkmqpQ30B39Lsk1M4RBAcNdtE0O36L3W0=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\",\"transfer_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf", + "stateKeyHash": "6WA49u1ciQXkmqpQ30B39Lsk1M4RBAcNdtE0O36L3W0=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}]},\"property_mutator_ref\":{\"self\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf", + "stateKeyHash": "6WA49u1ciQXkmqpQ30B39Lsk1M4RBAcNdtE0O36L3W0=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf", + "stateKeyHash": "6WA49u1ciQXkmqpQ30B39Lsk1M4RBAcNdtE0O36L3W0=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x7b4cd01cc85280139fbf2a11dd929a073febeba767d74904d0c691d68b74f321\"},\"description\":\"The Baptmen created by Baptman and Gawthim Labz.\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://arweave.net/ExSxSo31Ht7qfET0CWCSpx6nvo8ueDERTjVpBI7nwkk/1745.json\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf", + "stateKeyHash": "6WA49u1ciQXkmqpQ30B39Lsk1M4RBAcNdtE0O36L3W0=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"1302\"},\"name\":{\"padding\":\"0x000000\",\"value\":\"The Baptmen #1745\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7", + "stateKeyHash": "oQiMzNFyb/vCe0ljzi23hxzkgNpOSeyE1MWtcjlPlBk=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\",\"transfer_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7", + "stateKeyHash": "oQiMzNFyb/vCe0ljzi23hxzkgNpOSeyE1MWtcjlPlBk=", + "type": { + "address": "0x4", + "module": "aptos_token", + "name": "AptosToken" + }, + "typeStr": "0x4::aptos_token::AptosToken", + "data": "{\"burn_ref\":{\"vec\":[{\"inner\":{\"vec\":[{\"self\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"}]},\"self\":{\"vec\":[]}}]},\"mutator_ref\":{\"vec\":[{\"self\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"}]},\"property_mutator_ref\":{\"self\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"},\"transfer_ref\":{\"vec\":[{\"self\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7", + "stateKeyHash": "oQiMzNFyb/vCe0ljzi23hxzkgNpOSeyE1MWtcjlPlBk=", + "type": { + "address": "0x4", + "module": "property_map", + "name": "PropertyMap" + }, + "typeStr": "0x4::property_map::PropertyMap", + "data": "{\"inner\":{\"data\":[]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7", + "stateKeyHash": "oQiMzNFyb/vCe0ljzi23hxzkgNpOSeyE1MWtcjlPlBk=", + "type": { + "address": "0x4", + "module": "token", + "name": "Token" + }, + "typeStr": "0x4::token::Token", + "data": "{\"collection\":{\"inner\":\"0x7b4cd01cc85280139fbf2a11dd929a073febeba767d74904d0c691d68b74f321\"},\"description\":\"The Baptmen created by Baptman and Gawthim Labz.\",\"index\":\"0\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"\",\"uri\":\"https://arweave.net/ExSxSo31Ht7qfET0CWCSpx6nvo8ueDERTjVpBI7nwkk/1385.json\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7", + "stateKeyHash": "oQiMzNFyb/vCe0ljzi23hxzkgNpOSeyE1MWtcjlPlBk=", + "type": { + "address": "0x4", + "module": "token", + "name": "TokenIdentifiers" + }, + "typeStr": "0x4::token::TokenIdentifiers", + "data": "{\"index\":{\"value\":\"348\"},\"name\":{\"padding\":\"0x000000\",\"value\":\"The Baptmen #1385\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "stateKeyHash": "5b0VaahYzzDgHb/FFnkMnUEShP6MG5h2KtgHmd1TO7s=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"2241957998\"},\"deposit_events\":{\"counter\":\"980\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1072\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "stateKeyHash": "/OOIo15/S8NhwWU8pHHCbdtrTv5XnSvbwSv3IlygeJE=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"coin_register_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"1347\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2421\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "GziPDIxPViVKmcTdIO/LNrfAEGOLVL1z45HHLE9Rf8g=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "ListingStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::ListingStore", + "data": "{\"buy_events\":{\"counter\":\"61372\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"17\"}}},\"delete_listing_events\":{\"counter\":\"46146\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"16\"}}},\"insert_listing_events\":{\"counter\":\"135605\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"15\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114089276232385059\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10388", + "blockHeight": "292856727", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 684, + "eventSizeInfo": [ + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 62, + "totalBytes": 323 + }, + { + "typeTagBytes": 55, + "totalBytes": 199 + }, + { + "typeTagBytes": 65, + "totalBytes": 225 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87 + }, + { + "keyBytes": 87, + "valueBytes": 333 + }, + { + "keyBytes": 87, + "valueBytes": 333 + }, + { + "keyBytes": 87, + "valueBytes": 1082 + }, + { + "keyBytes": 87, + "valueBytes": 739 + }, + { + "keyBytes": 87, + "valueBytes": 739 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 93, + "valueBytes": 144 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b", + "sequenceNumber": "2420", + "maxGasAmount": "2336", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739988182" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "markets_v2" + }, + "name": "list_tokens_v2" + }, + "arguments": [ + "[\"2\",\"2\"]", + "[\"\",\"Wapal\"]", + "[\"0x7b4cd01cc85280139fbf2a11dd929a073febeba767d74904d0c691d68b74f321\",\"0x7b4cd01cc85280139fbf2a11dd929a073febeba767d74904d0c691d68b74f321\"]", + "[\"The Baptmen\",\"The Baptmen\"]", + "[\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\",\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"]", + "[\"0\",\"0\"]", + "[\"119000000\",\"119000000\"]", + "[\"0\",\"0\"]", + "[\"0x0\",\"0x254d2eccf3a4736a62f4e9eb8685fa54bb4c98a450c7c71fd4da1c6cb203855f\"]", + "[\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\",\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"]" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::markets_v2::list_tokens_v2" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "fGvkKHnGZkyumjtIC85RbEostHPoXoKtf1R9WQZ1soE=", + "signature": "Bxtc/IT9I1nIpVFiZ5qGxY+8o8PL9WoidB7bJkGBsNrSNSmoc4MC4M1WROxIRZ5aeWkavxrbiRsvCCtGk2DUDQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"object\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\",\"to\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\"}" + }, + { + "key": { + "creationNumber": "15", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "135603", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "InsertListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::InsertListingEvent", + "data": "{\"listing\":{\"inner\":\"0x3929540e32fb063ddf7fecb764c914493d2844978621767b9f013326093258eb\"},\"price\":\"119000000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"timestamp\":\"1739988091944133\",\"token\":{\"inner\":\"0x826cb695c5748ae84e9ed87902e9b214058d7b7589b32bcc48c30bdfe89f03e7\"}}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf" + }, + "sequenceNumber": "6", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0x254d2eccf3a4736a62f4e9eb8685fa54bb4c98a450c7c71fd4da1c6cb203855f\",\"object\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\",\"to\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\"}" + }, + { + "key": { + "creationNumber": "1125899906842628", + "accountAddress": "0x71f7c94805c33d32a7f9560c95f02e9d3b5bc49884a883916f03abe6da11ac08" + }, + "sequenceNumber": "74387", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9", + "module": "events", + "name": "ListingCanceledEvent" + } + }, + "typeStr": "0x584b50b999c78ade62f8359c91b5165ff390338d45f8e55969a04e65d76258c9::events::ListingCanceledEvent", + "data": "{\"listing\":\"0x254d2eccf3a4736a62f4e9eb8685fa54bb4c98a450c7c71fd4da1c6cb203855f\",\"price\":\"154500000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"token_metadata\":{\"collection\":{\"vec\":[{\"inner\":\"0x7b4cd01cc85280139fbf2a11dd929a073febeba767d74904d0c691d68b74f321\"}]},\"collection_name\":\"The Baptmen\",\"creator_address\":\"0x777368fcbcc8d6c4de5dd13278436b519d7d8917646151dbc56c9d3a58bf51b6\",\"property_version\":{\"vec\":[]},\"token\":{\"vec\":[{\"inner\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}]},\"token_name\":\"The Baptmen #1745\"},\"type\":\"fixed price\"}" + }, + { + "key": { + "creationNumber": "1125899906842624", + "accountAddress": "0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf" + }, + "sequenceNumber": "7", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "object", + "name": "TransferEvent" + } + }, + "typeStr": "0x1::object::TransferEvent", + "data": "{\"from\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"object\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\",\"to\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\"}" + }, + { + "key": { + "creationNumber": "15", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "135604", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "listings_v2", + "name": "InsertListingEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::listings_v2::InsertListingEvent", + "data": "{\"listing\":{\"inner\":\"0x6db18abc2ba8fb386af8bc9e6d35ef88256a25fcc9cbbfffb0d785be1f64fa8c\"},\"price\":\"119000000\",\"seller\":\"0xc24b9ea285e953bbf7470309b879bc60d5a68e71e2f2c17be047c3f74664e82b\",\"timestamp\":\"1739988091944133\",\"token\":{\"inner\":\"0x78d80871a136e75a0cde6b3ff0f45bc8e4c78f29e990b58947e49a1eecaaf6bf\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"19\",\"io_gas_units\":\"15\",\"storage_fee_octas\":\"113440\",\"storage_fee_refund_octas\":\"62640\",\"total_charge_gas_units\":\"1168\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386889884_tradeport_v2_cancel_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386889884_tradeport_v2_cancel_collection_offer.json new file mode 100644 index 00000000000..82c40bc7484 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386889884_tradeport_v2_cancel_collection_offer.json @@ -0,0 +1,223 @@ +{ + "timestamp": { + "seconds": "1739990687", + "nanos": 880613000 + }, + "version": "2386889884", + "info": { + "hash": "9iheHnWuyBq0BrLKJTcpwzRBffvtzmrONiR2pn3VtbQ=", + "stateChangeHash": "PLNL7KrmOeReA8EwxjaJ+snl8+ZKfiQ00iw2xLZY1Cc=", + "eventRootHash": "qjH7uoVTF1FcKuWsiu5XfnESnToLGgZl8DjDAQxV5TU=", + "gasUsed": "10", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "o0ExwQXGOdZtJhIvEXx8c0WqaJYyUE6y9S5amguxg94=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "kSJiqPFCska3SlG2fNyd46mssC9QXZVqf1lwRkrXuCM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"58786128904\"},\"deposit_events\":{\"counter\":\"7198\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7264\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "sGxUIhBizy+RgNIG5xaVsDlZM1aKr/4wnYoa1MAFoQQ=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"coin_register_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"6063\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"42466\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_DELETE_RESOURCE", + "deleteResource": { + "address": "0x2b040f0a6dcf7a2dc0bf2c0e0cfe962983038ab3df4211daba31d5f8d7a005d7", + "stateKeyHash": "F7ZKvQ53/VFAbtkHmNzUedWGwUFC+O/JrFCw2W8cgVI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectGroup" + }, + "typeStr": "0x1::object::ObjectGroup" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30950\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"41275\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3874\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"114748\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11693\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114089042018835901\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10388", + "blockHeight": "292870330", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 267, + "eventSizeInfo": [ + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 71, + "totalBytes": 231 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "sequenceNumber": "42465", + "maxGasAmount": "100000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739991287" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "cancel_collection_bid" + }, + "arguments": [ + "{\"inner\":\"0x2b040f0a6dcf7a2dc0bf2c0e0cfe962983038ab3df4211daba31d5f8d7a005d7\"}" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::cancel_collection_bid" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "EKGqbmjxRW+jOGpkqaNnq+z8syHRlO+/jAx3Zhrcpec=", + "signature": "G38gFofPQt9g7gVSmTmP6sm8Nchs/MtOFTzw7x+HSoRLFeh7IMdunZkRFtGXVQYzEqnRdEkniWzOnwFvAQ27CQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "2", + "accountAddress": "0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4" + }, + "sequenceNumber": "7197", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2726630000\"}" + }, + { + "key": { + "creationNumber": "22", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "41274", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "DeleteCollectionBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::DeleteCollectionBidEvent", + "data": "{\"bid\":{\"inner\":\"0x2b040f0a6dcf7a2dc0bf2c0e0cfe962983038ab3df4211daba31d5f8d7a005d7\"},\"bid_buyer\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"price\":\"2726630000\",\"timestamp\":\"1739990687880613\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"55640\",\"total_charge_gas_units\":\"10\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386891051_tradeport_v2_place_collection_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386891051_tradeport_v2_place_collection_offer.json new file mode 100644 index 00000000000..e58aa382eb4 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2386891051_tradeport_v2_place_collection_offer.json @@ -0,0 +1,241 @@ +{ + "timestamp": { + "seconds": "1739990720", + "nanos": 621178000 + }, + "version": "2386891051", + "info": { + "hash": "Jvce9khSZR0dmFxyRrgZSJmjTAT/6cTajh8har+Y8No=", + "stateChangeHash": "/vpugO6ZsAAuwoJSR2ILpKUC+CRRPLCm4HLRMUIeasI=", + "eventRootHash": "uyHUcc78fzF1yp5Mo9L2lSPEqg5lTOeX7scV41TfCaE=", + "gasUsed": "570", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "zKGNbHn2/d9nsbrIe+jVIbUFml9tBeIdM56kQ5/lnPc=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "kSJiqPFCska3SlG2fNyd46mssC9QXZVqf1lwRkrXuCM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"56026081904\"},\"deposit_events\":{\"counter\":\"7198\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7265\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "stateKeyHash": "sGxUIhBizy+RgNIG5xaVsDlZM1aKr/4wnYoa1MAFoQQ=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"coin_register_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"6064\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"42467\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe06d17630ff3fd295fcc1b83dc023187de07bb79118998ea17d0873a34150f84", + "stateKeyHash": "Hz/oHbg8iya9KaPUZfPrCqebdcX0OwFGtCyRt9kUj80=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe06d17630ff3fd295fcc1b83dc023187de07bb79118998ea17d0873a34150f84\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe06d17630ff3fd295fcc1b83dc023187de07bb79118998ea17d0873a34150f84", + "stateKeyHash": "Hz/oHbg8iya9KaPUZfPrCqebdcX0OwFGtCyRt9kUj80=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "CollectionBid" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::CollectionBid", + "data": "{\"bid_buyer\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"coins\":{\"value\":\"2759990000\"},\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"delete_ref\":{\"self\":\"0xe06d17630ff3fd295fcc1b83dc023187de07bb79118998ea17d0873a34150f84\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "stateKeyHash": "YyxEM2ISNprB8ZNNbepmRFb5Yl7G+bHX/jJlJ/MnbD8=", + "type": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "BidStore" + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::BidStore", + "data": "{\"accept_collection_bid_events\":{\"counter\":\"30950\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"23\"}}},\"accept_token_bid_events\":{\"counter\":\"630\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"20\"}}},\"delete_collection_bid_events\":{\"counter\":\"41275\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"22\"}}},\"delete_token_bid_events\":{\"counter\":\"3874\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"19\"}}},\"insert_collection_bid_events\":{\"counter\":\"114749\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"21\"}}},\"insert_token_bid_events\":{\"counter\":\"11693\",\"guid\":{\"id\":{\"addr\":\"0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26\",\"creation_num\":\"18\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114088996445803003\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10388", + "blockHeight": "292870507", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 279, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 71, + "totalBytes": 231 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 306 + }, + { + "keyBytes": 89, + "valueBytes": 288 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4", + "sequenceNumber": "42466", + "maxGasAmount": "100000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1739991320" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "name": "biddings_v2" + }, + "name": "collection_bids" + }, + "arguments": [ + "{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"}", + "\"2759990000\"", + "\"1\"" + ], + "entryFunctionIdStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::collection_bids" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "EKGqbmjxRW+jOGpkqaNnq+z8syHRlO+/jAx3Zhrcpec=", + "signature": "IAfJy5F72RzRb896WO3DxY11VrEICX2HoSHqKLxd436+aYvY4VXGFIG9Uq+g7hqEXDITyYpf+w7Mecv9ry1qBQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "3", + "accountAddress": "0x08c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4" + }, + "sequenceNumber": "7264", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"2759990000\"}" + }, + { + "key": { + "creationNumber": "21", + "accountAddress": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26" + }, + "sequenceNumber": "114748", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26", + "module": "biddings_v2", + "name": "InsertCollectionBidEvent" + } + }, + "typeStr": "0xe11c12ec495f3989c35e1c6a0af414451223305b579291fc8f3d9d0575a23c26::biddings_v2::InsertCollectionBidEvent", + "data": "{\"bid\":{\"inner\":\"0xe06d17630ff3fd295fcc1b83dc023187de07bb79118998ea17d0873a34150f84\"},\"bid_buyer\":\"0x8c557bb0a12d47c1eda90dd4883b44674111b915fa39ff862e6a0a39140dcd4\",\"collection\":{\"inner\":\"0xa2485c3b392d211770ed161e73a1097d21016c7dd41f53592434380b2aa14cba\"},\"price\":\"2759990000\",\"timestamp\":\"1739990720621178\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"7\",\"io_gas_units\":\"7\",\"storage_fee_octas\":\"55640\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"570\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2424873868_fa_secondary_store_exists_object_core_deleted.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2424873868_fa_secondary_store_exists_object_core_deleted.json new file mode 100644 index 00000000000..8c9b8dbff01 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2424873868_fa_secondary_store_exists_object_core_deleted.json @@ -0,0 +1,419 @@ +{ + "timestamp": { + "seconds": "1740864389", + "nanos": 112325000 + }, + "version": "2424873868", + "info": { + "hash": "+LmSYWG50Xf7NklmG36cEtZm9ppKR2uDFttjx64VD38=", + "stateChangeHash": "+1Dzgz2aapIS2BemXZVjDxHQ/i5SL8O8+tjVPczx3pU=", + "eventRootHash": "LwGJZ5fAybP38+rojPk5g275UbYJLfNpLibonXcB7IQ=", + "gasUsed": "40", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "qwpI5/d4edp57CFCd223ErCZQdYznIyK1UppdBzAt/M=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleAssetEvents" + }, + "typeStr": "0x1::fungible_asset::FungibleAssetEvents", + "data": "{\"deposit_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842628\"}}},\"frozen_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842630\"}}},\"withdraw_events\":{\"counter\":\"33091\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842629\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"130171350273901\",\"frozen\":false,\"metadata\":{\"inner\":\"0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842631\",\"owner\":\"0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x4", + "module": "collection", + "name": "Collection" + }, + "typeStr": "0x4::collection::Collection", + "data": "{\"creator\":\"0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1\",\"description\":\"Cellana Voting Tokens\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842627\"}}},\"name\":\"Cellana Voting Tokens\",\"uri\":\"https://api.cellana.finance/api/v1/ve-nft/uri/\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x4", + "module": "collection", + "name": "UnlimitedSupply" + }, + "typeStr": "0x4::collection::UnlimitedSupply", + "data": "{\"burn_events\":{\"counter\":\"24321\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842625\"}}},\"current_supply\":\"359860\",\"mint_events\":{\"counter\":\"384181\",\"guid\":{\"id\":{\"addr\":\"0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65\",\"creation_num\":\"1125899906842626\"}}},\"total_minted\":\"384181\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65", + "stateKeyHash": "DxFxZz0uboErSy8PXxT6AmpHFiQPACQPRW0digfqGeg=", + "type": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "module": "voting_escrow", + "name": "VeCellanaCollection" + }, + "typeStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::VeCellanaCollection", + "data": "{\"rebases\":{\"buckets\":{\"inner\":{\"handle\":\"0xa92a82faa53d835a2e386e53d0fef43079f0c53084cf463718e99bc5420ca172\"},\"length\":\"2\"},\"level\":1,\"num_buckets\":\"2\",\"size\":\"53\",\"split_load_threshold\":75,\"target_bucket_size\":\"42\"},\"unscaled_total_voting_power_per_epoch\":{\"buckets\":{\"inner\":{\"handle\":\"0x635198ef8a973c8da529ca94a6b564706137eb6c95976ba9be1144408fe300dd\"},\"length\":\"7\"},\"level\":2,\"num_buckets\":\"7\",\"size\":\"157\",\"split_load_threshold\":75,\"target_bucket_size\":\"32\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x3656f551dbdddb61a5e0956b8f64fd9f9d20c48c9f8f2a07551072fd15a3cddb", + "stateKeyHash": "uBsE4QMXU/xTfc166wJnP+L8V3hDdchVNe2DZeDnIbw=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"94957937980\"},\"deposit_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0x3656f551dbdddb61a5e0956b8f64fd9f9d20c48c9f8f2a07551072fd15a3cddb\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x3656f551dbdddb61a5e0956b8f64fd9f9d20c48c9f8f2a07551072fd15a3cddb\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2", + "stateKeyHash": "n5fgNJKfXnlDWNYNwOBQ1WhgPkVyQvimCFNiQewg4jI=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleAssetEvents" + }, + "typeStr": "0x1::fungible_asset::FungibleAssetEvents", + "data": "{\"deposit_events\":{\"counter\":\"14\",\"guid\":{\"id\":{\"addr\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\",\"creation_num\":\"1125899906842626\"}}},\"frozen_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\",\"creation_num\":\"1125899906842628\"}}},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\",\"creation_num\":\"1125899906842627\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2", + "stateKeyHash": "n5fgNJKfXnlDWNYNwOBQ1WhgPkVyQvimCFNiQewg4jI=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"0\",\"frozen\":true,\"metadata\":{\"inner\":\"0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b", + "stateKeyHash": "qkxg575t339eek99AwskJJzzEL80hg+CsJCTkbIxMvs=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b\",\"coin_register_events\":{\"counter\":\"14\",\"guid\":{\"id\":{\"addr\":\"0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"30\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"413\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470", + "stateKeyHash": "wzAJ66VgFkUTh135InxGjioAK3jsGIsOrpUrbsIJlSE=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleAssetEvents" + }, + "typeStr": "0x1::fungible_asset::FungibleAssetEvents", + "data": "{\"deposit_events\":{\"counter\":\"69\",\"guid\":{\"id\":{\"addr\":\"0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470\",\"creation_num\":\"1125899906842625\"}}},\"frozen_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470\",\"creation_num\":\"1125899906842627\"}}},\"withdraw_events\":{\"counter\":\"21\",\"guid\":{\"id\":{\"addr\":\"0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470\",\"creation_num\":\"1125899906842626\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470", + "stateKeyHash": "wzAJ66VgFkUTh135InxGjioAK3jsGIsOrpUrbsIJlSE=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"20303622000289\",\"frozen\":false,\"metadata\":{\"inner\":\"0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470", + "stateKeyHash": "wzAJ66VgFkUTh135InxGjioAK3jsGIsOrpUrbsIJlSE=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842628\",\"owner\":\"0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"114247313958170178\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "fpt1Uyx6G9OWwM7D15maYAYez47igOWzbiHyPCHgRT4=", + "handle": "0x999821e9b7cef12d14a8dd20d976c9cb698219048f84295667235061eaf9aee4", + "key": "0x0000000000000000", + "data": { + "key": "\"0\"", + "keyType": "u64" + } + } + } + ] + }, + "epoch": "10509", + "blockHeight": "297490277", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 396, + "eventSizeInfo": [ + { + "typeTagBytes": 58, + "totalBytes": 98 + }, + { + "typeTagBytes": 55, + "totalBytes": 143 + }, + { + "typeTagBytes": 62, + "totalBytes": 134 + }, + { + "typeTagBytes": 57, + "totalBytes": 97 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 1062 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 87, + "valueBytes": 319 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 87, + "valueBytes": 460 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 42 + } + ] + }, + "user": { + "request": { + "sender": "0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b", + "sequenceNumber": "412", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1740864744" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "name": "voting_escrow" + }, + "name": "withdraw_entry" + }, + "arguments": [ + "{\"inner\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\"}" + ], + "entryFunctionIdStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::withdraw_entry" + } + }, + "signature": { + "type": "TYPE_FEE_PAYER", + "feePayer": { + "sender": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "qJbg4AQXVaA9ggSeLUtw2z0wQKu4nmiogFOfUNu8uNw=", + "signature": "Po1iRzV4AqIihMbn6ReIS50NYMskYM6QaKwTuQNwu+vahNWia2fQlgFtvyiFpyFS+ilBur5RdFWez5R/4eAwBQ==" + } + }, + "feePayerAddress": "0x3656f551dbdddb61a5e0956b8f64fd9f9d20c48c9f8f2a07551072fd15a3cddb", + "feePayerSigner": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "vKKx7JYsJ3aycGdtX2tiONLC9ger9e6Gk2xjuCN311Y=", + "signature": "CBjsRoXXSW+FNzSLBFp8Nco7x0cp2BclGypMPxr2DxBKBAofrSu0CZJsp4pN7bvVQntPb/rV9kBoooWfNUYDBg==" + } + } + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "fungible_asset", + "name": "Withdraw" + } + }, + "typeStr": "0x1::fungible_asset::Withdraw", + "data": "{\"amount\":\"20303622000289\",\"store\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\"}" + }, + { + "key": { + "creationNumber": "1125899906842625", + "accountAddress": "0x30e2f18b1f9c447e7dadd7a05966e721ab6512b81ee977cb053edb86cc1b1d65" + }, + "sequenceNumber": "24320", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x4", + "module": "collection", + "name": "BurnEvent" + } + }, + "typeStr": "0x4::collection::BurnEvent", + "data": "{\"index\":\"16610\",\"token\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1", + "module": "voting_escrow", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::voting_escrow::WithdrawEvent", + "data": "{\"amount\":\"20303622000289\",\"owner\":\"0xca77d95fd530d6ca7fe811454e0d96b70e8a9f66e0f069ba815e854c2a9e135b\",\"ve_token\":{\"inner\":\"0xc62f9a29e3c871d3c3d9e729e95eb947aec69851e98f2649cf594b2197945ef2\"}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "fungible_asset", + "name": "Deposit" + } + }, + "typeStr": "0x1::fungible_asset::Deposit", + "data": "{\"amount\":\"20303622000289\",\"store\":\"0xd42a65844c773b0bb31b5ba848e60031f6ba7cc90e64fcbfc61e30e4c1a61470\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"27\",\"io_gas_units\":\"13\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"89360\",\"total_charge_gas_units\":\"40\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2819452713_token_v1_cancel_offer_module_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2819452713_token_v1_cancel_offer_module_event.json new file mode 100644 index 00000000000..51c0e2e1bf5 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2819452713_token_v1_cancel_offer_module_event.json @@ -0,0 +1,222 @@ +{ + "timestamp": { + "seconds": "1748992846", + "nanos": 418432000 + }, + "version": "2819452713", + "info": { + "hash": "rJ9u5QkHEL9hHcFbi93fcFbF1CsJ9EXOW166yzlvRCM=", + "stateChangeHash": "RuDFnUKanMXLzf2d56bGY6TpBGGj3WXmFnnl7Bouqb4=", + "eventRootHash": "iWsmEsktDxZ1wx+u2awocJx316V8NAQb+fncrtQOEv4=", + "gasUsed": "472", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "jAO4hPMf/pLD2MH0nMtJDLPTKpgaLkqu5YK+gw9p8IE=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f", + "stateKeyHash": "1tONs7J7whCxkzKFNzY498SSuwCDJzbXAA6Y0ygnrEA=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"689143974\"},\"deposit_events\":{\"counter\":\"81\",\"guid\":{\"id\":{\"addr\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"102\",\"guid\":{\"id\":{\"addr\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f", + "stateKeyHash": "C+NIUeN68ycofYbeYhmx3qiE46vAz/FOty83ZwXZCIM=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"coin_register_events\":{\"counter\":\"17\",\"guid\":{\"id\":{\"addr\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"43\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"214\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"115043290219362953\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "0Q6GdDeq1bXia1FANKqCuGoO1B90GLraYDzeNrcYneA=", + "handle": "0x5459a6e0aae6906091deae5325a75b46b08d146dfa95c5b7e628f9bbef34b2db", + "key": "0x04a3cfe8c86599474cc9e0307db78211101e32875164dcd6dc05965b32d6760ff3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916064d415652494b0b4d415652494b20233934310000000000000000", + "data": { + "key": "{\"to_addr\":\"0x4a3cfe8c86599474cc9e0307db78211101e32875164dcd6dc05965b32d6760f\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"MAVRIK\",\"creator\":\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\",\"name\":\"MAVRIK #941\"}}}", + "keyType": "0x3::token_transfers::TokenOfferId" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bUGcVtKqbemHVgSvvQZiCCX+9mnpQou7Ih5LJxVrnVM=", + "handle": "0x9ccf0cb7fe70e9b75633ce047dc1fba808431724f36219f9fe95585882f6ff05", + "key": "0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916064d415652494b0b4d415652494b20233934310000000000000000", + "data": { + "key": "{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"MAVRIK\",\"creator\":\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\",\"name\":\"MAVRIK #941\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"MAVRIK\",\"creator\":\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\",\"name\":\"MAVRIK #941\"}},\"token_properties\":{\"map\":{\"data\":[]}}}", + "valueType": "0x3::token::Token" + } + } + } + ] + }, + "epoch": "11639", + "blockHeight": "355922000", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 332, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 152 + }, + { + "typeTagBytes": 62, + "totalBytes": 193 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 125 + }, + { + "keyBytes": 93, + "valueBytes": 68 + } + ] + }, + "user": { + "request": { + "sender": "0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f", + "sequenceNumber": "213", + "maxGasAmount": "944", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1748992941" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x3", + "name": "token_transfers" + }, + "name": "cancel_offer_script" + }, + "arguments": [ + "\"0x4a3cfe8c86599474cc9e0307db78211101e32875164dcd6dc05965b32d6760f\"", + "\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\"", + "\"MAVRIK\"", + "\"MAVRIK #941\"", + "\"0\"" + ], + "entryFunctionIdStr": "0x3::token_transfers::cancel_offer_script" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "nTWo9Td/EHpy+5zDYtqtCIGCROXwkr5cLXP6hZPZUco=", + "signature": "rwmIPjdlg2SBmA1Whe4DA1mL87o2l017JazTkDsGh5zYsKTQyl5DjKFBL74KG7xx6NatXHQCauaGtXzeRJTsBQ==" + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "TokenDeposit" + } + }, + "typeStr": "0x3::token::TokenDeposit", + "data": "{\"account\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"MAVRIK\",\"creator\":\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\",\"name\":\"MAVRIK #941\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token_transfers", + "name": "CancelOffer" + } + }, + "typeStr": "0x3::token_transfers::CancelOffer", + "data": "{\"account\":\"0xbf0a07a9eb77fc7a2ec8f48356e2968fb489494da37673ded619b94cb323f42f\",\"amount\":\"1\",\"to_address\":\"0x4a3cfe8c86599474cc9e0307db78211101e32875164dcd6dc05965b32d6760f\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"MAVRIK\",\"creator\":\"0xf3778cf4d8b6d61ab3d79c804797ef7417e258449d2735b0f405e604b81f7916\",\"name\":\"MAVRIK #941\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"4\",\"storage_fee_octas\":\"46360\",\"storage_fee_refund_octas\":\"47640\",\"total_charge_gas_units\":\"472\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2975888978_fa_secondary_store_burnt_object_still_exists.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2975888978_fa_secondary_store_burnt_object_still_exists.json new file mode 100644 index 00000000000..e5902d4c147 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2975888978_fa_secondary_store_burnt_object_still_exists.json @@ -0,0 +1,426 @@ +{ + "timestamp": { + "seconds": "1751259825", + "nanos": 422808000 + }, + "version": "2975888978", + "info": { + "hash": "XygceXJ4OPYAW53Gb8aRKBrFbUt6EwMe/cadngw2PI8=", + "stateChangeHash": "t2en7rzYgMbjPViH34GA1RiJlun8Calzxj+r/s+y5o8=", + "eventRootHash": "T1PqKKxbfTE2d1osX0ZoNoIZlCpjxtW3ViMBEd1awTk=", + "gasUsed": "31", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "BAT1RprJTLulVwOEGQnNDAtK5Y2jHhFDETwazbcNNyk=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "PairedCoinType" + }, + "typeStr": "0x1::coin::PairedCoinType", + "data": "{\"type\":{\"account_address\":\"0x1\",\"module_name\":\"0x6170746f735f636f696e\",\"struct_name\":\"0x4170746f73436f696e\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "coin", + "name": "PairedFungibleAssetRefs" + }, + "typeStr": "0x1::coin::PairedFungibleAssetRefs", + "data": "{\"burn_ref_opt\":{\"vec\":[{\"metadata\":{\"inner\":\"0xa\"}}]},\"mint_ref_opt\":{\"vec\":[{\"metadata\":{\"inner\":\"0xa\"}}]},\"transfer_ref_opt\":{\"vec\":[{\"metadata\":{\"inner\":\"0xa\"}}]}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "ConcurrentSupply" + }, + "typeStr": "0x1::fungible_asset::ConcurrentSupply", + "data": "{\"current\":{\"max_value\":\"340282366920938463463374607431768211455\",\"value\":\"1041352936553427\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "Metadata" + }, + "typeStr": "0x1::fungible_asset::Metadata", + "data": "{\"decimals\":8,\"icon_uri\":\"\",\"name\":\"Aptos Coin\",\"project_uri\":\"\",\"symbol\":\"APT\"}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0x1\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xa", + "stateKeyHash": "HbVEHY+kIpxYRPc/1m2krYF2y4eT2LOn9sqFhyIDAEM=", + "type": { + "address": "0x1", + "module": "primary_fungible_store", + "name": "DeriveRefPod" + }, + "typeStr": "0x1::primary_fungible_store::DeriveRefPod", + "data": "{\"metadata_derive_ref\":{\"self\":\"0xa\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1198c59f6c6f84f0a52f1a8524fbaac60946c7e2ac74a87bf7632fa50e23f34d", + "stateKeyHash": "AfUzalCYgH8VwN4yO0xeeQE6IzrlY8btYu63mCSm884=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0x4ea3c7d6fd8ee6e752ca70420d4aac1fda379db4475520249faf8e04ad31c5a4\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1198c59f6c6f84f0a52f1a8524fbaac60946c7e2ac74a87bf7632fa50e23f34d\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1198c59f6c6f84f0a52f1a8524fbaac60946c7e2ac74a87bf7632fa50e23f34d", + "stateKeyHash": "AfUzalCYgH8VwN4yO0xeeQE6IzrlY8btYu63mCSm884=", + "type": { + "address": "0x1", + "module": "object", + "name": "Untransferable" + }, + "typeStr": "0x1::object::Untransferable", + "data": "{\"dummy_field\":false}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x39c5e9646e47ecbd490adc5070fac264337d6c7ffe8785a11a22d041b5b8ed1f", + "stateKeyHash": "YAlE6z7FpON3oLYkMIXTVWdEDsJOhFeyCtiuVva9vhI=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"463374913\",\"frozen\":false,\"metadata\":{\"inner\":\"0xa\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x39c5e9646e47ecbd490adc5070fac264337d6c7ffe8785a11a22d041b5b8ed1f", + "stateKeyHash": "YAlE6z7FpON3oLYkMIXTVWdEDsJOhFeyCtiuVva9vhI=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x39c5e9646e47ecbd490adc5070fac264337d6c7ffe8785a11a22d041b5b8ed1f\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2379bc13b5a41345e0e16be571170fa774ab0cdf4bcafecf5e3c4a9a8cb965d", + "stateKeyHash": "Y7TvvOTnpI/bpgo5CMELVUa1SoW2GUC9f0W3ixJsR/o=", + "type": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStore" + }, + "typeStr": "0x1::fungible_asset::FungibleStore", + "data": "{\"balance\":\"1967366248021\",\"frozen\":false,\"metadata\":{\"inner\":\"0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2379bc13b5a41345e0e16be571170fa774ab0cdf4bcafecf5e3c4a9a8cb965d", + "stateKeyHash": "Y7TvvOTnpI/bpgo5CMELVUa1SoW2GUC9f0W3ixJsR/o=", + "type": { + "address": "0x1", + "module": "object", + "name": "ObjectCore" + }, + "typeStr": "0x1::object::ObjectCore", + "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842625\",\"owner\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2379bc13b5a41345e0e16be571170fa774ab0cdf4bcafecf5e3c4a9a8cb965d\",\"creation_num\":\"1125899906842624\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2379bc13b5a41345e0e16be571170fa774ab0cdf4bcafecf5e3c4a9a8cb965d", + "stateKeyHash": "Y7TvvOTnpI/bpgo5CMELVUa1SoW2GUC9f0W3ixJsR/o=", + "type": { + "address": "0x1", + "module": "object", + "name": "Untransferable" + }, + "typeStr": "0x1::object::Untransferable", + "data": "{\"dummy_field\":false}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def", + "stateKeyHash": "NdiofNNijBDbRuivqj/8oCNlw3e3Sv4xYuFrLA6L84U=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"8\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"58\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def", + "stateKeyHash": "mLX6Xt+Hly0bhExm2cD97ernWtCBWNcIAt4wRWPLO30=", + "type": { + "address": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c", + "module": "fridge", + "name": "Fridge" + }, + "typeStr": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c::fridge::Fridge", + "data": "{\"boxes\":{\"buckets\":{\"inner\":{\"handle\":\"0x253784c601b2d5bba82ea9ea74bb336ac25eb4f30dda54da0f71f4f88bd9476c\"},\"length\":\"2\"},\"level\":1,\"num_buckets\":\"2\",\"size\":\"0\",\"split_load_threshold\":75,\"target_bucket_size\":\"4\"}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "mARYT6GK3REj8zybFb6i1hGhCr1fNA1Opf3pR3t+SXU=", + "handle": "0x253784c601b2d5bba82ea9ea74bb336ac25eb4f30dda54da0f71f4f88bd9476c", + "key": "0x0000000000000000", + "data": { + "key": "\"0\"", + "keyType": "u64", + "value": "[]", + "valueType": "vector<0x1::smart_table::Entry>" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "/HxilANqRRZqzZCf4skxq9qEd6gu5HrxP67IFqcGWtI=", + "handle": "0x6b18af0908f82daa19d91044c67282c92425280024402bee2a3debe193d27aa7", + "key": "0x0000000000000000", + "data": { + "key": "\"0\"", + "keyType": "u64", + "value": "[{\"hash\":\"17865349363605900100\",\"key\":\"0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b\",\"value\":\"0\"}]", + "valueType": "vector<0x1::smart_table::Entry>" + } + } + } + ] + }, + "epoch": "11954", + "blockHeight": "374069028", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 230, + "eventSizeInfo": [ + { + "typeTagBytes": 58, + "totalBytes": 98 + }, + { + "typeTagBytes": 57, + "totalBytes": 97 + }, + { + "typeTagBytes": 71, + "totalBytes": 167 + }, + { + "typeTagBytes": 57, + "totalBytes": 265 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 87, + "valueBytes": 687 + }, + { + "keyBytes": 87, + "valueBytes": 199 + }, + { + "keyBytes": 87, + "valueBytes": 246 + }, + { + "keyBytes": 87, + "valueBytes": 303 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 82, + "valueBytes": 66 + }, + { + "keyBytes": 42, + "valueBytes": 1 + }, + { + "keyBytes": 42, + "valueBytes": 49 + } + ] + }, + "user": { + "request": { + "sender": "0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def", + "sequenceNumber": "57", + "maxGasAmount": "62", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1751263422" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c", + "name": "fridge" + }, + "name": "claim_box_all_released" + }, + "entryFunctionIdStr": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c::fridge::claim_box_all_released" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "Fd2EMnMqtbRa5luEVhvvinJ/uYWMABgkGb/RAZElxuo=", + "signature": "jTa7c1PGMCer70Kk51Me7zwdMglgPu3AwQQQW4ZEX99LEQ1drbJWznaiFJtAMWxn3/qg51RWERXrOmtg3bzcCA==" + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "fungible_asset", + "name": "Withdraw" + } + }, + "typeStr": "0x1::fungible_asset::Withdraw", + "data": "{\"amount\":\"1967223709853\",\"store\":\"0x1198c59f6c6f84f0a52f1a8524fbaac60946c7e2ac74a87bf7632fa50e23f34d\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "fungible_asset", + "name": "Deposit" + } + }, + "typeStr": "0x1::fungible_asset::Deposit", + "data": "{\"amount\":\"1967223709853\",\"store\":\"0xe2379bc13b5a41345e0e16be571170fa774ab0cdf4bcafecf5e3c4a9a8cb965d\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "fungible_asset", + "name": "FungibleStoreDeletion" + } + }, + "typeStr": "0x1::fungible_asset::FungibleStoreDeletion", + "data": "{\"metadata\":\"0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b\",\"owner\":\"0x4ea3c7d6fd8ee6e752ca70420d4aac1fda379db4475520249faf8e04ad31c5a4\",\"store\":\"0x1198c59f6c6f84f0a52f1a8524fbaac60946c7e2ac74a87bf7632fa50e23f34d\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c", + "module": "fridge", + "name": "BoxClaimedEvent" + } + }, + "typeStr": "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c::fridge::BoxClaimedEvent", + "data": "{\"box_id\":\"0x6acf794d9be232eade19f0012dfaea8d27f709cc355c3f851bd327bb9d893ae7\",\"pool_id\":\"0xd3894aca06d5f42b27c89e6f448114b3ed6a1ba07f992a58b2126c71dd83c127\",\"position_id\":\"0xe7c8dd1614075f13ee744ccd6bfeb24fd9b2150687346cbe6e60f6baf7b4a240\",\"token_a_amount\":\"1967223709853\",\"token_a_metadata\":{\"inner\":\"0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b\"},\"token_b_amount\":\"0\",\"token_b_metadata\":{\"inner\":\"0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b\"},\"user\":\"0xfad988a7cc7872ac290984c5a12b587c1f8c1afb9c329893909e5a14d1312def\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"18\",\"io_gas_units\":\"14\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"31\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/3020266695_token_v1_offer_module_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/3020266695_token_v1_offer_module_event.json new file mode 100644 index 00000000000..ae0ebf51158 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/3020266695_token_v1_offer_module_event.json @@ -0,0 +1,223 @@ +{ + "timestamp": { + "seconds": "1751901312", + "nanos": 159328000 + }, + "version": "3020266695", + "info": { + "hash": "PBeHyWrjVmIHm0YOoAc8KZVpsD2c3M+oMxvuFwC3Mq8=", + "stateChangeHash": "z0tI8+VYkZMCH1CHtuGrpqer0+phHe0s9tpvr2yUlns=", + "eventRootHash": "MzZQTf/kyDRKHV47btr2HoxpL6pMBEGtvOxQAIeuxHc=", + "gasUsed": "513", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "tO65fd1UpY0BW6YjMZE8fjz7iJERIqCEYl7BmiBXOqY=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f", + "stateKeyHash": "fzTxcmaMgX6rNBprqcGWtppa0y3oKnHvKvkb4cdH/PE=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"35700\"},\"deposit_events\":{\"counter\":\"2395\",\"guid\":{\"id\":{\"addr\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"3981\",\"guid\":{\"id\":{\"addr\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f", + "stateKeyHash": "kheUwHu+SwkApzRLPBbkwundMnXhRizJyMGZcnTLE80=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"coin_register_events\":{\"counter\":\"136\",\"guid\":{\"id\":{\"addr\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"324\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"67435\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "iZK01eF88zp9mPXtlLNUEWByTBJMVG52WXyfpctBa5Y=", + "handle": "0x03cb17a570f807158c816f0eb51f2e32daa9216722633f90689c30b4868384e2", + "key": "0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7225061696e7465642050616e64617a20476f6c642048656172747a2045646974696f6e135061696e7465642050616e64617a20233737350000000000000000", + "data": { + "key": "{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Painted Pandaz Gold Heartz Edition\",\"creator\":\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\",\"name\":\"Painted Pandaz #775\"}}", + "keyType": "0x3::token::TokenId" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"115262386861063695\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "y2o4ONuUWcps4teemw6/GJCnQrRIYb3cOijndCB2lf0=", + "handle": "0x5bb377b66e8033a4bbd18d6bec86106bda3e2e35eff3d7c6636b6b7376e95bdc", + "key": "0x3751f06509c1c3149eb74acb24395aa24e7aaa76c6cf8386cf478ec3893753cd2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7225061696e7465642050616e64617a20476f6c642048656172747a2045646974696f6e135061696e7465642050616e64617a20233737350000000000000000", + "data": { + "key": "{\"to_addr\":\"0x3751f06509c1c3149eb74acb24395aa24e7aaa76c6cf8386cf478ec3893753cd\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Painted Pandaz Gold Heartz Edition\",\"creator\":\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\",\"name\":\"Painted Pandaz #775\"}}}", + "keyType": "0x3::token_transfers::TokenOfferId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Painted Pandaz Gold Heartz Edition\",\"creator\":\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\",\"name\":\"Painted Pandaz #775\"}},\"token_properties\":{\"map\":{\"data\":[]}}}", + "valueType": "0x3::token::Token" + } + } + } + ] + }, + "epoch": "12045", + "blockHeight": "379241357", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 370, + "eventSizeInfo": [ + { + "typeTagBytes": 54, + "totalBytes": 189 + }, + { + "typeTagBytes": 56, + "totalBytes": 223 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 129 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 161, + "valueBytes": 104 + } + ] + }, + "user": { + "request": { + "sender": "0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f", + "sequenceNumber": "67434", + "maxGasAmount": "1026", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1751901401" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x3", + "name": "token_transfers" + }, + "name": "offer_script" + }, + "arguments": [ + "\"0x3751f06509c1c3149eb74acb24395aa24e7aaa76c6cf8386cf478ec3893753cd\"", + "\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\"", + "\"Painted Pandaz Gold Heartz Edition\"", + "\"Painted Pandaz #775\"", + "\"0\"", + "\"1\"" + ], + "entryFunctionIdStr": "0x3::token_transfers::offer_script" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "DsDAmoEuXuJjUG4AFc6iVuKkRinQv+Ile+zdGkYvT78=", + "signature": "3u4Zf6Dqn7USt5ZgHRZSW6eRzxWR2h2WVQDyp0zjgtkkKkqSmK00+PxcWx2wHJat5t4pNyRXjIS/nEAQ3Ro3DA==" + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "TokenWithdraw" + } + }, + "typeStr": "0x3::token::TokenWithdraw", + "data": "{\"account\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Painted Pandaz Gold Heartz Edition\",\"creator\":\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\",\"name\":\"Painted Pandaz #775\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token_transfers", + "name": "Offer" + } + }, + "typeStr": "0x3::token_transfers::Offer", + "data": "{\"account\":\"0xc02399a3dadb83d363802e3fc990eceade0e9b2a9a6dc180a092a60b0c17566f\",\"amount\":\"1\",\"to_address\":\"0x3751f06509c1c3149eb74acb24395aa24e7aaa76c6cf8386cf478ec3893753cd\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Painted Pandaz Gold Heartz Edition\",\"creator\":\"0x2c3a145f6bd45ad84784f8fc8ea75a2b6171a8f23da84dcbdb1b1bd00fdcc1f7\",\"name\":\"Painted Pandaz #775\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"4\",\"storage_fee_octas\":\"50520\",\"storage_fee_refund_octas\":\"49240\",\"total_charge_gas_units\":\"513\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v1_claim_offer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v1_claim_offer.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v1_cancel_offer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v1_cancel_offer.json diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml index 1e64e7879aa..d3aaa1ed9cb 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml @@ -45,14 +45,18 @@ mainnet: 2308282694: 2308282694_asset_type_v1_null 2308283617: 2308283617_asset_type_v1_null_2 2662373625: 2662373625_fa_secondary_store_burnt_with_deletion_event + 2975888978: 2975888978_fa_secondary_store_burnt_object_still_exists + 2424873868: 2424873868_fa_secondary_store_exists_object_core_deleted # token v2 processor 1058723093: 1058723093_token_v1_mint_withdraw_deposit_events 11648867: 11648867_token_v1_burn_event 178179220: 178179220_token_v1_mutate_event 141135867: 141135867_token_v1_offer - 97963136: 97963136_token_v2_cancel_offer - 84023785: 84023785_token_v2_claim_offer + 3020266695: 3020266695_token_v1_offer_module_event + 97963136: 97963136_token_v1_cancel_offer + 2819452713: 2819452713_token_v1_cancel_offer_module_event + 84023785: 84023785_token_v1_claim_offer 999930475: 999930475_token_v2_concurrent_mint 537250181: 537250181_token_v2_fixed_supply_mint 325355235: 325355235_token_v2_unlimited_supply_mint @@ -119,3 +123,31 @@ mainnet: # Fungible asset migration 1680592683: 1680592683_fa_migration_coin_info 1957950162: 1957950162_fa_migration_v2_store_only + + # Nft Aggregator tradeport + 2386133936: 2386133936_tradeport_v2_place_offer + 2298838662: 2298838662_tradeport_v2_fill_offer + 2386142672: 2386142672_tradeport_v2_cancel_offer + 2386889884: 2386889884_tradeport_v2_cancel_collection_offer + 2386021136: 2386021136_tradeport_v2_fill_collection_offer + 2386891051: 2386891051_tradeport_v2_place_collection_offer + 2386716658: 2386716658_tradeport_v2_cancel_listing + 2386809975: 2386809975_tradeport_v2_place_listing + 2386455218: 2386455218_tradeport_v2_fill_listing + + 2296149225: 2296149225_tradeport_v2_accept_token_delist + 2296098846: 2296098846_tradeport_v2_accept_token_delist2 + 2277018899: 2277018899_tradeport_v2_accept_token_delist_same_token_data_id + + # wapal + 2381810159: 2381810159_wapal_cancel_offer + 2313248448: 2313248448_wapal_fill_offer + 2382313982: 2382313982_wapal_place_offer + 2382373209: 2382373209_wapal_place_collection_offer + 2382373978: 2382373978_wapal_cancel_collection_offer + 2382219668: 2382219668_wapal_fill_collection_offer + 2382221134: 2382221134_wapal_fill_listing + 2381742315: 2381742315_wapal_cancel_listing + 2382251863: 2382251863_wapal_place_listing + + # diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/src/config_template.yaml b/ecosystem/indexer-grpc/indexer-transaction-generator/src/config_template.yaml index bb5780d4538..62a515622d1 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/src/config_template.yaml +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/src/config_template.yaml @@ -1,6 +1,6 @@ import_config: testnet: - # Transaction Stream endpoint addresss. + # Transaction Stream endpoint address. transaction_stream_endpoint: https://grpc.testnet.aptoslabs.com:443 # (Optional) The key to use with developers.aptoslabs.com api_key: YOUR_KEY_HERE @@ -8,21 +8,21 @@ import_config: versions_to_import: 123: testnet_v1.json # mainnet: - # # Transaction Stream endpoint addresss. + # # Transaction Stream endpoint address. # transaction_stream_endpoint: https://grpc.mainnet.aptoslabs.com:443 # # (Optional) The key to use with developers.aptoslabs.com # api_key: YOUR_KEY_HERE # versions_to_import: # 123: mainnetnet_v1.json # devnet: - # # Transaction Stream endpoint addresss. + # # Transaction Stream endpoint address. # transaction_stream_endpoint: https://grpc.devnet.aptoslabs.com:443 # # (Optional) The key to use with developers.aptoslabs.com # api_key: YOUR_KEY_HERE # versions_to_import: # 123: devnet_v1.json # custom: - # # Transaction Stream endpoint addresss. + # # Transaction Stream endpoint address. # transaction_stream_endpoint: YOUR_CUSTOM_ENDPOINT # versions_to_import: - # 123: custom_v1.json \ No newline at end of file + # 123: custom_v1.json diff --git a/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs b/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs index 1406f607009..6f4973cf847 100644 --- a/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs +++ b/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs @@ -275,7 +275,7 @@ impl Filterable for UserTransactionPayloadFilter { fn get_entry_function_payload_from_transaction_payload( payload: &TransactionPayload, ) -> Option<&EntryFunctionPayload> { - let z = if let Some(payload) = &payload.payload { + if let Some(payload) = &payload.payload { match payload { transaction_payload::Payload::EntryFunctionPayload(ef_payload) => Some(ef_payload), transaction_payload::Payload::MultisigPayload(ms_payload) => ms_payload @@ -291,6 +291,5 @@ fn get_entry_function_payload_from_transaction_payload( } } else { None - }; - z + } } diff --git a/ecosystem/nft-metadata-crawler/src/asset_uploader/worker/mod.rs b/ecosystem/nft-metadata-crawler/src/asset_uploader/worker/mod.rs index 708da221fcd..e47aeae15f5 100644 --- a/ecosystem/nft-metadata-crawler/src/asset_uploader/worker/mod.rs +++ b/ecosystem/nft-metadata-crawler/src/asset_uploader/worker/mod.rs @@ -66,7 +66,7 @@ impl AssetUploaderWorkerContext { } /// Uploads an asset to Cloudflare and returns the response - async fn upload_asset(&self, url: &Url) -> anyhow::Result { + async fn upload_asset(&self, url: &Url) -> anyhow::Result> { let hashed_url = sha256::digest(url.to_string()); let client = Client::builder() .timeout(Duration::from_secs(MAX_ASSET_UPLOAD_RETRY_SECONDS)) diff --git a/ecosystem/nft-metadata-crawler/src/parser/mod.rs b/ecosystem/nft-metadata-crawler/src/parser/mod.rs index 56830330f00..ba44f9dc50d 100644 --- a/ecosystem/nft-metadata-crawler/src/parser/mod.rs +++ b/ecosystem/nft-metadata-crawler/src/parser/mod.rs @@ -44,10 +44,13 @@ impl ParserContext { info!( "[NFT Metadata Crawler] Google Application Credentials path found, setting env var" ); - std::env::set_var( - "GOOGLE_APPLICATION_CREDENTIALS", - google_application_credentials, - ); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { + std::env::set_var( + "GOOGLE_APPLICATION_CREDENTIALS", + google_application_credentials, + ); + } } // Establish GCS client diff --git a/ecosystem/nft-metadata-crawler/src/parser/worker.rs b/ecosystem/nft-metadata-crawler/src/parser/worker.rs index dce2f642f48..a20059f4d9d 100644 --- a/ecosystem/nft-metadata-crawler/src/parser/worker.rs +++ b/ecosystem/nft-metadata-crawler/src/parser/worker.rs @@ -176,7 +176,7 @@ impl Worker { } else if self.model.get_cdn_image_uri().is_some() { false } else { - self.model.get_raw_image_uri().map_or(true, |uri| { + self.model.get_raw_image_uri().is_none_or(|uri| { match ParsedAssetUrisQuery::get_by_raw_image_uri( &mut self.conn, &self.asset_uri, diff --git a/execution/block-partitioner/Cargo.toml b/execution/block-partitioner/Cargo.toml index 422f2b0a07f..e4ba06cbfcd 100644 --- a/execution/block-partitioner/Cargo.toml +++ b/execution/block-partitioner/Cargo.toml @@ -32,10 +32,7 @@ serde = { workspace = true } criterion = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [features] default = [] diff --git a/execution/block-partitioner/src/v2/build_edge.rs b/execution/block-partitioner/src/v2/build_edge.rs index 7b8c82874a4..93589304cb6 100644 --- a/execution/block-partitioner/src/v2/build_edge.rs +++ b/execution/block-partitioner/src/v2/build_edge.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::v2::{counters::MISC_TIMERS_SECONDS, state::PartitionState, PartitionerV2}; +use aptos_metrics_core::TimerHelper; use aptos_types::{ block_executor::partitioner::{ PartitionedTransactions, SubBlock, SubBlocksForShard, TransactionWithDependencies, @@ -16,9 +17,7 @@ use std::sync::Mutex; impl PartitionerV2 { pub(crate) fn add_edges(state: &mut PartitionState) -> PartitionedTransactions { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["add_edges"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["add_edges"]); state.sub_block_matrix = state.thread_pool.install(|| { (0..state.num_rounds()) diff --git a/execution/block-partitioner/src/v2/init.rs b/execution/block-partitioner/src/v2/init.rs index f58eeb2fc1f..dbd6140934e 100644 --- a/execution/block-partitioner/src/v2/init.rs +++ b/execution/block-partitioner/src/v2/init.rs @@ -8,14 +8,13 @@ use crate::{ state::PartitionState, types::OriginalTxnIdx, PartitionerV2, }, }; +use aptos_metrics_core::TimerHelper; use rayon::{iter::ParallelIterator, prelude::IntoParallelIterator}; use std::sync::RwLock; impl PartitionerV2 { pub(crate) fn init(state: &mut PartitionState) { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["init"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["init"]); state.thread_pool.install(|| { (0..state.num_txns()) diff --git a/execution/block-partitioner/src/v2/partition_to_matrix.rs b/execution/block-partitioner/src/v2/partition_to_matrix.rs index a58879c6bf5..d5e2264c197 100644 --- a/execution/block-partitioner/src/v2/partition_to_matrix.rs +++ b/execution/block-partitioner/src/v2/partition_to_matrix.rs @@ -9,6 +9,7 @@ use crate::v2::{ PartitionerV2, }; use aptos_logger::trace; +use aptos_metrics_core::TimerHelper; use aptos_types::block_executor::partitioner::{RoundId, TxnIndex}; use dashmap::DashMap; use rayon::{ @@ -27,9 +28,7 @@ impl PartitionerV2 { /// Populate `state.finalized_txn_matrix` with txns flattened into a matrix (num_rounds by num_shards), /// in a way that avoid in-round cross-shard conflicts. pub(crate) fn remove_cross_shard_dependencies(state: &mut PartitionState) { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["remove_cross_shard_dependencies"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["remove_cross_shard_dependencies"]); let mut remaining_txns = mem::take(&mut state.pre_partitioned); assert_eq!(state.num_executor_shards, remaining_txns.len()); @@ -48,9 +47,7 @@ impl PartitionerV2 { } } - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["last_round"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["last_round"]); if !state.partition_last_round { trace!("Merging txns after discarding stopped."); @@ -83,9 +80,7 @@ impl PartitionerV2 { Vec>, Vec>, ) { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&[format!("round_{round_id}").as_str()]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&[format!("round_{round_id}").as_str()]); let num_shards = remaining_txns.len(); @@ -182,9 +177,7 @@ impl PartitionerV2 { } pub(crate) fn build_index_from_txn_matrix(state: &mut PartitionState) { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["build_index_from_txn_matrix"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["build_index_from_txn_matrix"]); let num_rounds = state.finalized_txn_matrix.len(); state.start_index_matrix = vec![vec![0; state.num_executor_shards]; num_rounds]; diff --git a/execution/block-partitioner/src/v2/state.rs b/execution/block-partitioner/src/v2/state.rs index 65171c1775a..03d0efae728 100644 --- a/execution/block-partitioner/src/v2/state.rs +++ b/execution/block-partitioner/src/v2/state.rs @@ -14,6 +14,7 @@ use crate::{ }, Sender, }; +use aptos_metrics_core::TimerHelper; use aptos_types::{ block_executor::partitioner::{ CrossShardDependencies, RoundId, ShardId, ShardedTxnIndex, SubBlock, @@ -116,9 +117,7 @@ impl PartitionState { cross_shard_dep_avoid_threshold: f32, partition_last_round: bool, ) -> Self { - let _timer = MISC_TIMERS_SECONDS - .with_label_values(&["new"]) - .start_timer(); + let _timer = MISC_TIMERS_SECONDS.timer_with(&["new"]); let num_txns = txns.len(); let sender_counter = AtomicUsize::new(0); let key_counter = AtomicUsize::new(0); @@ -246,12 +245,11 @@ impl PartitionState { let tracker = tracker_ref.read().unwrap(); let start = ShardedTxnIndexV2::new(sub_block.round_id, sub_block.shard_id, 0); let end = ShardedTxnIndexV2::new(sub_block.round_id, sub_block.shard_id + 1, 0); - let ret = tracker + tracker .finalized_writes .range(start..end) .last() - .map(|t| t.pre_partitioned_txn_idx); - ret + .map(|t| t.pre_partitioned_txn_idx) } /// Get the 1st txn after `since` that writes a given key. diff --git a/execution/executor-benchmark/Cargo.toml b/execution/executor-benchmark/Cargo.toml index 54d9e02b121..63da35b9011 100644 --- a/execution/executor-benchmark/Cargo.toml +++ b/execution/executor-benchmark/Cargo.toml @@ -15,23 +15,28 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } aptos-aggregator = { workspace = true } +aptos-api = { workspace = true } aptos-block-executor = { workspace = true } aptos-block-partitioner = { workspace = true } aptos-config = { workspace = true } aptos-crypto = { workspace = true } aptos-db = { workspace = true } +aptos-db-indexer = { workspace = true } aptos-executor = { workspace = true } aptos-executor-service = { workspace = true } aptos-executor-types = { workspace = true } aptos-experimental-ptx-executor = { workspace = true } aptos-experimental-runtimes = { workspace = true } aptos-genesis = { workspace = true, features = ["testing"] } +aptos-indexer-grpc-fullnode = { workspace = true } +aptos-indexer-grpc-table-info = { workspace = true } aptos-infallible = { workspace = true } aptos-jellyfish-merkle = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-mvhashmap = { workspace = true } aptos-node-resource-metrics = { workspace = true } +aptos-protos = { workspace = true } aptos-push-metrics = { workspace = true } aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } @@ -49,6 +54,7 @@ chrono = { workspace = true } clap = { workspace = true } dashmap = { workspace = true } derivative = { workspace = true } +futures = { workspace = true } indicatif = { workspace = true } itertools = { workspace = true } move-core-types = { workspace = true } @@ -58,16 +64,15 @@ once_cell = { workspace = true } rand = { workspace = true } rayon = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } thread_local = { workspace = true } tokio = { workspace = true } toml = { workspace = true } +tonic = { workspace = true } [target.'cfg(unix)'.dependencies] aptos-profiler = { workspace = true } -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [dev-dependencies] aptos-temppath = { workspace = true } diff --git a/execution/executor-benchmark/src/block_preparation.rs b/execution/executor-benchmark/src/block_preparation.rs index c58e428214b..9750d4dddad 100644 --- a/execution/executor-benchmark/src/block_preparation.rs +++ b/execution/executor-benchmark/src/block_preparation.rs @@ -9,9 +9,13 @@ use aptos_block_partitioner::{BlockPartitioner, PartitionerConfig}; use aptos_crypto::HashValue; use aptos_experimental_runtimes::thread_manager::optimal_min_len; use aptos_logger::info; +use aptos_metrics_core::{IntCounterVecHelper, TimerHelper}; use aptos_types::{ block_executor::partitioner::{ExecutableBlock, ExecutableTransactions}, - transaction::{signature_verified_transaction::SignatureVerifiedTransaction, Transaction}, + transaction::{ + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, + AuxiliaryInfoTrait, Transaction, + }, }; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use std::time::Instant; @@ -68,14 +72,13 @@ impl BlockPreparationStage { txns.len() ); let block_id = HashValue::random(); + let sig_verified_txns: Vec = self.sig_verify_pool.install(|| { - let _timer = TIMER.with_label_values(&["sig_verify"]).start_timer(); + let _timer = TIMER.timer_with(&["sig_verify"]); let num_txns = txns.len(); - NUM_TXNS - .with_label_values(&["sig_verify"]) - .inc_by(num_txns as u64); + NUM_TXNS.inc_with_by(&["sig_verify"], num_txns as u64); txns.into_par_iter() .with_min_len(optimal_min_len(num_txns, SIG_VERIFY_RAYON_MIN_THRESHOLD)) @@ -83,18 +86,28 @@ impl BlockPreparationStage { .collect::>() }); let block: ExecutableBlock = match &self.maybe_partitioner { - None => (block_id, sig_verified_txns).into(), + None => { + // Create proper AuxiliaryInfo with correct transaction indices + let auxiliary_info: Vec = sig_verified_txns + .iter() + .enumerate() + .map(|(idx, _)| AuxiliaryInfo::auxiliary_info_at_txn_index(idx as u32)) + .collect(); + (block_id, sig_verified_txns, auxiliary_info).into() + }, Some(partitioner) => { - NUM_TXNS - .with_label_values(&["partition"]) - .inc_by(sig_verified_txns.len() as u64); + NUM_TXNS.inc_with_by(&["partition"], sig_verified_txns.len() as u64); let analyzed_transactions = sig_verified_txns.into_iter().map(|t| t.into()).collect(); - let timer = TIMER.with_label_values(&["partition"]).start_timer(); + let timer = TIMER.timer_with(&["partition"]); let partitioned_txns = partitioner.partition(analyzed_transactions, self.num_executor_shards); timer.stop_and_record(); - ExecutableBlock::new(block_id, ExecutableTransactions::Sharded(partitioned_txns)) + ExecutableBlock::new( + block_id, + ExecutableTransactions::Sharded(partitioned_txns), + vec![], + ) }, }; self.num_blocks_processed += 1; diff --git a/execution/executor-benchmark/src/db_generator.rs b/execution/executor-benchmark/src/db_generator.rs index 90f9f43f9fb..6968c446ab7 100644 --- a/execution/executor-benchmark/src/db_generator.rs +++ b/execution/executor-benchmark/src/db_generator.rs @@ -2,10 +2,10 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{add_accounts_impl, PipelineConfig}; +use crate::{add_accounts_impl, PipelineConfig, StorageTestConfig}; use aptos_config::{ config::{ - PrunerConfig, RocksdbConfigs, StorageDirPaths, BUFFERED_STATE_TARGET_ITEMS, + RocksdbConfigs, StorageDirPaths, BUFFERED_STATE_TARGET_ITEMS, DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, NO_OP_STORAGE_PRUNER_CONFIG, }, utils::get_genesis_txn, @@ -30,9 +30,8 @@ pub fn create_db_with_accounts( init_account_balance: u64, block_size: usize, db_dir: impl AsRef, - storage_pruner_config: PrunerConfig, + storage_test_config: StorageTestConfig, verify_sequence_numbers: bool, - enable_storage_sharding: bool, pipeline_config: PipelineConfig, init_features: Features, is_keyless: bool, @@ -51,7 +50,11 @@ pub fn create_db_with_accounts( // create if not exists fs::create_dir_all(db_dir.as_ref()).unwrap(); - bootstrap_with_genesis(&db_dir, enable_storage_sharding, init_features.clone()); + bootstrap_with_genesis( + &db_dir, + storage_test_config.enable_storage_sharding, + init_features.clone(), + ); println!( "Finished empty DB creation, DB dir: {}. Creating accounts now...", @@ -64,9 +67,8 @@ pub fn create_db_with_accounts( block_size, &db_dir, &db_dir, - storage_pruner_config, + storage_test_config, verify_sequence_numbers, - enable_storage_sharding, pipeline_config, init_features, is_keyless, diff --git a/execution/executor-benchmark/src/db_reliable_submitter.rs b/execution/executor-benchmark/src/db_reliable_submitter.rs index e2c74fc330f..c1f15104545 100644 --- a/execution/executor-benchmark/src/db_reliable_submitter.rs +++ b/execution/executor-benchmark/src/db_reliable_submitter.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::db_access::DbAccessUtil; +use crate::{db_access::DbAccessUtil, transaction_generator::create_block_metadata_transaction}; use anyhow::Result; use aptos_storage_interface::{ state_store::state_view::db_state_view::LatestDbStateCheckpointView, DbReaderWriter, @@ -18,7 +18,7 @@ use async_trait::async_trait; use std::{ collections::HashMap, sync::{atomic::AtomicUsize, mpsc}, - time::Duration, + time::{Duration, Instant}, }; pub struct DbReliableTransactionSubmitter { @@ -50,16 +50,41 @@ impl ReliableTransactionSubmitter for DbReliableTransactionSubmitter { txns: &[SignedTransaction], _state: &CounterState, ) -> Result<()> { - self.block_sender.send( + let mut block = Vec::new(); + block.push(create_block_metadata_transaction(1, &self.db)); + block.extend( txns.iter() .map(|t| Transaction::UserTransaction(t.clone())) - .collect(), - )?; + .collect::>(), + ); + self.block_sender.send(block)?; + + let start = Instant::now(); for txn in txns { - // Pipeline commit makes sure all initialization transactions - // get committed succesfully on-chain - while txn.sequence_number() >= self.query_sequence_number(txn.sender()).await? { + loop { + if let Some(txn_output) = self + .db + .reader + .get_transaction_by_hash( + txn.committed_hash(), + self.db.reader.get_latest_ledger_info_version().unwrap(), + false, + ) + .unwrap() + { + if txn_output.proof.transaction_info().status().is_success() { + break; + } else { + panic!( + "Transaction failed: {:?}", + txn_output.proof.transaction_info() + ); + } + } + if start.elapsed().as_secs() > 30 { + panic!("Transaction timed out"); + } tokio::time::sleep(Duration::from_millis(10)).await; } } diff --git a/execution/executor-benchmark/src/indexer_grpc_waiter.rs b/execution/executor-benchmark/src/indexer_grpc_waiter.rs new file mode 100644 index 00000000000..42c1d87cd7c --- /dev/null +++ b/execution/executor-benchmark/src/indexer_grpc_waiter.rs @@ -0,0 +1,76 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_indexer_grpc_table_info::table_info_service::TableInfoService; +use aptos_logger::info; +use aptos_types::transaction::Version; +use std::{ + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, + time::{Duration, Instant}, +}; + +const INDEXER_GRPC_POLL_INTERVAL_MS: u64 = 50; +const STATUS_LOG_INTERVAL_SECS: u64 = 1; + +pub struct IndexerGrpcWaiter { + table_info_service: Arc, + stream_version: Arc, +} + +impl Drop for IndexerGrpcWaiter { + fn drop(&mut self) { + println!("**** Dropping IndexerGrpcWaiter. ****"); + } +} + +impl IndexerGrpcWaiter { + pub fn new(table_info_service: Arc, stream_version: Arc) -> Self { + Self { + table_info_service, + stream_version, + } + } + + pub async fn wait_for_version(&self, target_version: Version, abort_on_finish: bool) { + info!( + "Waiting for indexer_grpc to reach target version: {}", + target_version + ); + + let start_time = Instant::now(); + let mut last_log_time = Instant::now(); + + loop { + let table_info_version = self.table_info_service.next_version().saturating_sub(1); + let stream_version = self.stream_version.load(Ordering::SeqCst); + if stream_version >= target_version { + info!( + "Indexer stream reached target version. Current: {}, Target: {}, elapsed: {:.2}s", + stream_version, + target_version, + start_time.elapsed().as_secs_f64() + ); + if abort_on_finish { + self.table_info_service.abort(); + } + break; + } + + // Log status every 1 second + if last_log_time.elapsed().as_secs() >= STATUS_LOG_INTERVAL_SECS { + let versions_behind = target_version.saturating_sub(stream_version); + let elapsed_secs = start_time.elapsed().as_secs_f64(); + info!( + "Indexer_grpc progress: target={}, table_info_current={}, stream_version={}, behind={}, elapsed={:.2}s", + target_version, table_info_version, stream_version, versions_behind, elapsed_secs + ); + last_log_time = Instant::now(); + } + + tokio::time::sleep(Duration::from_millis(INDEXER_GRPC_POLL_INTERVAL_MS)).await; + } + } +} diff --git a/execution/executor-benchmark/src/ledger_update_stage.rs b/execution/executor-benchmark/src/ledger_update_stage.rs index 05f646eb661..3394ef3e1ad 100644 --- a/execution/executor-benchmark/src/ledger_update_stage.rs +++ b/execution/executor-benchmark/src/ledger_update_stage.rs @@ -73,8 +73,13 @@ where self.allow_discards, self.allow_retries, ); - if !self.allow_retries && num_input_txns != 0 { - assert_eq!(output.num_transactions_to_commit(), num_input_txns + 1); + + if !self.allow_retries { + if output.epoch_state().is_none() { + assert_eq!(output.num_transactions_to_commit(), num_input_txns + 1); + } else { + assert_eq!(output.num_transactions_to_commit(), num_input_txns); + } } let mut event_summary = self.event_summary.lock(); diff --git a/execution/executor-benchmark/src/lib.rs b/execution/executor-benchmark/src/lib.rs index 01476eb7ae7..d56586394a9 100644 --- a/execution/executor-benchmark/src/lib.rs +++ b/execution/executor-benchmark/src/lib.rs @@ -7,6 +7,7 @@ pub mod block_preparation; pub mod db_access; pub mod db_generator; mod db_reliable_submitter; +mod indexer_grpc_waiter; mod ledger_update_stage; pub mod measurements; mod metrics; @@ -17,16 +18,27 @@ pub mod transaction_executor; pub mod transaction_generator; use crate::{ - db_access::DbAccessUtil, pipeline::Pipeline, transaction_committer::TransactionCommitter, - transaction_executor::TransactionExecutor, transaction_generator::TransactionGenerator, + db_access::DbAccessUtil, + pipeline::Pipeline, + transaction_committer::TransactionCommitter, + transaction_executor::TransactionExecutor, + transaction_generator::{create_block_metadata_transaction, TransactionGenerator}, }; +use aptos_api::context::Context; use aptos_config::config::{NodeConfig, PrunerConfig, NO_OP_STORAGE_PRUNER_CONFIG}; use aptos_db::AptosDB; +use aptos_db_indexer::{db_ops::open_db, db_v2::IndexerAsyncV2, indexer_reader::IndexerReaders}; use aptos_executor::block_executor::BlockExecutor; +use aptos_indexer_grpc_fullnode::{fullnode_data_service::FullnodeDataService, ServiceContext}; +use aptos_indexer_grpc_table_info::table_info_service::TableInfoService; use aptos_jellyfish_merkle::metrics::{ APTOS_JELLYFISH_INTERNAL_ENCODED_BYTES, APTOS_JELLYFISH_LEAF_ENCODED_BYTES, }; use aptos_logger::{info, warn}; +use aptos_protos::internal::fullnode::v1::{ + fullnode_data_server::FullnodeData, transactions_from_node_response::Response, + GetTransactionsFromNodeRequest, +}; use aptos_sdk::types::LocalAccount; use aptos_storage_interface::{ state_store::state_view::db_state_view::LatestDbStateCheckpointView, DbReader, DbReaderWriter, @@ -37,17 +49,49 @@ use aptos_transaction_generator_lib::{ }; use aptos_types::on_chain_config::{FeatureFlag, Features}; use aptos_vm::{aptos_vm::AptosVMBlockExecutor, AptosVM, VMBlockExecutor}; +use aptos_vm_environment::prod_configs::{ + set_async_runtime_checks, set_layout_caches, set_paranoid_type_checks, +}; use db_generator::create_db_with_accounts; use db_reliable_submitter::DbReliableTransactionSubmitter; +use futures::StreamExt; use measurements::{EventMeasurements, OverallMeasurement, OverallMeasuring}; use pipeline::PipelineConfig; use std::{ fs, path::Path, - sync::{atomic::AtomicUsize, Arc}, + sync::{ + atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}, + Arc, + }, time::Instant, }; use tokio::runtime::Runtime; +use tonic::IntoRequest; + +const TABLE_INFO_DB_NAME: &str = "index_async_v2_db"; + +#[derive(Clone, Copy, Debug)] +pub struct StorageTestConfig { + pub pruner_config: PrunerConfig, + pub enable_storage_sharding: bool, + pub enable_indexer_grpc: bool, +} + +impl StorageTestConfig { + pub fn init_storage_config(&self, node_config: &mut NodeConfig) { + node_config.storage.storage_pruner_config = self.pruner_config; + node_config.storage.rocksdb_configs.enable_storage_sharding = self.enable_storage_sharding; + if self.enable_indexer_grpc { + node_config.indexer_grpc.enabled = true; + node_config.indexer_table_info.table_info_service_mode = + aptos_config::config::TableInfoServiceMode::IndexingOnly; + + node_config.indexer_table_info.parser_task_count = 10; + node_config.indexer_table_info.parser_batch_size = 100; + } + } +} pub struct SingleRunResults { pub measurements: OverallMeasurement, @@ -56,7 +100,9 @@ pub struct SingleRunResults { } pub fn default_benchmark_features() -> Features { - Features::default() + let mut features = Features::default(); + features.disable(FeatureFlag::CALCULATE_TRANSACTION_FEE_FOR_DISTRIBUTION); + features } pub fn init_db(config: &NodeConfig) -> DbReaderWriter { @@ -75,19 +121,131 @@ pub fn init_db(config: &NodeConfig) -> DbReaderWriter { ) } +fn init_indexer_wrapper( + config: &NodeConfig, + db: &DbReaderWriter, + storage_test_config: &StorageTestConfig, + start_version: u64, +) -> Option<(Arc, Arc, Arc)> { + if !storage_test_config.enable_indexer_grpc { + return None; + } + + let db_path = config + .storage + .get_dir_paths() + .default_root_path() + .join(TABLE_INFO_DB_NAME); + let rocksdb_config = config.storage.rocksdb_configs.index_db_config; + let indexer_db = open_db(db_path, &rocksdb_config, /*readonly=*/ false) + .expect("Failed to open indexer async v2 db"); + let indexer_async_v2 = + Arc::new(IndexerAsyncV2::new(indexer_db).expect("Failed to initialize indexer async v2")); + + // Create API context for table_info_service + let (mp_sender, _mp_receiver) = futures::channel::mpsc::channel(1); + // Use ChainId::test() for benchmark + let chain_id = aptos_types::chain_id::ChainId::test(); + let context = Arc::new(Context::new( + chain_id, + db.reader.clone(), + mp_sender, + config.clone(), + Some(Arc::new( + IndexerReaders::new(Some(indexer_async_v2.clone()), None).unwrap(), + )), + )); + let service_context = ServiceContext { + context: context.clone(), + processor_task_count: config.indexer_grpc.processor_task_count, + processor_batch_size: config.indexer_grpc.processor_batch_size, + output_batch_size: config.indexer_grpc.output_batch_size, + }; + + // Spawn table_info_service in tokio runtime + let indexer_async_v2_clone = indexer_async_v2.clone(); + let config_clone = config.clone(); + let indexer_runtime = tokio::runtime::Runtime::new().unwrap(); + let table_info_service = Arc::new(TableInfoService::new( + context, + indexer_async_v2_clone.next_version(), + config_clone.indexer_table_info.parser_task_count, + config_clone.indexer_table_info.parser_batch_size, + None, // No backup/restore for benchmark + indexer_async_v2_clone, + )); + let table_info_service_clone = table_info_service.clone(); + indexer_runtime.spawn(async move { + println!( + "**** Starting table_info_service at version {}.", + table_info_service_clone.next_version() + ); + table_info_service_clone.run().await; + }); + let grpc_version = Arc::new(AtomicU64::new(0)); + let grpc_version_clone = grpc_version.clone(); + let abort_handle = Arc::new(AtomicBool::new(false)); + let abort_handle_clone = abort_handle.clone(); + indexer_runtime.spawn(async move { + let grpc_service = FullnodeDataService { + service_context, + abort_handle, + }; + println!("Starting grpc stream at version {start_version}."); + let request = GetTransactionsFromNodeRequest { + starting_version: Some(start_version), + transactions_count: None, + }; + let mut response = grpc_service + .get_transactions_from_node(request.into_request()) + .await + .unwrap() + .into_inner(); + while let Some(item) = response.next().await { + if let Ok(r) = item { + if let Some(response) = r.response { + if let Response::Data(data) = response { + if let Some(txn) = data.transactions.last().as_ref() { + grpc_version_clone.store(txn.version, Ordering::SeqCst); + } + } + } + } + } + }); + + // Keep runtime alive - it will be dropped when the function scope ends + std::mem::forget(indexer_runtime); + + Some((table_info_service, grpc_version, abort_handle_clone)) +} + fn create_checkpoint( source_dir: impl AsRef, checkpoint_dir: impl AsRef, enable_storage_sharding: bool, + enable_indexer_grpc: bool, ) { + println!("Creating checkpoint for DBs."); // Create rocksdb checkpoint. if checkpoint_dir.as_ref().exists() { fs::remove_dir_all(checkpoint_dir.as_ref()).unwrap_or(()); } std::fs::create_dir_all(checkpoint_dir.as_ref()).unwrap(); + if enable_indexer_grpc { + let db_path = source_dir.as_ref().join(TABLE_INFO_DB_NAME); + let indexer_db = open_db(db_path, &Default::default(), /*readonly=*/ false) + .expect("Failed to open table info db."); + indexer_db + .create_checkpoint(checkpoint_dir.as_ref().join(TABLE_INFO_DB_NAME)) + .expect("Table info db checkpoint creation fails."); + } + AptosDB::create_checkpoint(source_dir, checkpoint_dir, enable_storage_sharding) .expect("db checkpoint creation fails."); + + println!("Checkpoint for DBs is done."); } pub enum BenchmarkWorkload { @@ -124,8 +282,7 @@ pub fn run_benchmark( source_dir: impl AsRef, checkpoint_dir: impl AsRef, verify_sequence_numbers: bool, - pruner_config: PrunerConfig, - enable_storage_sharding: bool, + storage_test_config: StorageTestConfig, pipeline_config: PipelineConfig, init_features: Features, is_keyless: bool, @@ -136,13 +293,13 @@ where create_checkpoint( source_dir.as_ref(), checkpoint_dir.as_ref(), - enable_storage_sharding, + storage_test_config.enable_storage_sharding, + storage_test_config.enable_indexer_grpc, ); let (mut config, genesis_key) = aptos_genesis::test_utils::test_config_with_custom_features(init_features); config.storage.dir = checkpoint_dir.as_ref().to_path_buf(); - config.storage.storage_pruner_config = pruner_config; - config.storage.rocksdb_configs.enable_storage_sharding = enable_storage_sharding; + storage_test_config.init_storage_config(&mut config); let db = init_db(&config); let root_account = TransactionGenerator::read_root_account(genesis_key, &db); let root_account = Arc::new(root_account); @@ -230,9 +387,18 @@ where }; let start_version = db.reader.expect_synced_version(); + + // Initialize table_info_service and grpc stream if indexer_grpc is enabled + let indexer_wrapper = init_indexer_wrapper(&config, &db, &storage_test_config, start_version); + let executor = BlockExecutor::::new(db.clone()); - let (pipeline, block_sender) = - Pipeline::new(executor, start_version, &pipeline_config, Some(num_blocks)); + let (pipeline, block_sender) = Pipeline::new( + executor, + start_version, + &pipeline_config, + Some(num_blocks), + indexer_wrapper, + ); let root_account = Arc::into_inner(root_account).unwrap(); let mut generator = TransactionGenerator::new_with_existing_db( @@ -335,6 +501,7 @@ where start_version, pipeline_config, None, + None, // No indexer for init workload ); let runtime = Runtime::new().unwrap(); @@ -376,9 +543,8 @@ pub fn add_accounts( block_size: usize, source_dir: impl AsRef, checkpoint_dir: impl AsRef, - pruner_config: PrunerConfig, + storage_test_config: StorageTestConfig, verify_sequence_numbers: bool, - enable_storage_sharding: bool, pipeline_config: PipelineConfig, init_features: Features, is_keyless: bool, @@ -389,7 +555,8 @@ pub fn add_accounts( create_checkpoint( source_dir.as_ref(), checkpoint_dir.as_ref(), - enable_storage_sharding, + storage_test_config.enable_storage_sharding, + storage_test_config.enable_indexer_grpc, ); add_accounts_impl::( num_new_accounts, @@ -397,9 +564,8 @@ pub fn add_accounts( block_size, source_dir, checkpoint_dir, - pruner_config, + storage_test_config, verify_sequence_numbers, - enable_storage_sharding, pipeline_config, init_features, is_keyless, @@ -412,9 +578,8 @@ fn add_accounts_impl( block_size: usize, source_dir: impl AsRef, output_dir: impl AsRef, - pruner_config: PrunerConfig, + storage_test_config: StorageTestConfig, verify_sequence_numbers: bool, - enable_storage_sharding: bool, pipeline_config: PipelineConfig, init_features: Features, is_keyless: bool, @@ -424,18 +589,45 @@ fn add_accounts_impl( let (mut config, genesis_key) = aptos_genesis::test_utils::test_config_with_custom_features(init_features); config.storage.dir = output_dir.as_ref().to_path_buf(); - config.storage.storage_pruner_config = pruner_config; - config.storage.rocksdb_configs.enable_storage_sharding = enable_storage_sharding; + storage_test_config.init_storage_config(&mut config); let db = init_db(&config); - let executor = BlockExecutor::::new(db.clone()); let start_version = db.reader.get_latest_ledger_info_version().unwrap(); + // Initialize indexer if enabled + let indexer_wrapper = init_indexer_wrapper(&config, &db, &storage_test_config, start_version); + + let executor = BlockExecutor::::new(db.clone()); + + // First BlockMetadata transaction (epoch=0 to trigger epoch change) + let executor1 = BlockExecutor::::new(db.clone()); + let (pipeline1, block_sender1) = Pipeline::new( + executor1, + start_version, + &pipeline_config, + Some(1), // Only 1 block + None, + ); + + info!("Sending the first block metadata transaction to start a new epoch"); + block_sender1 + .send(vec![create_block_metadata_transaction(0, &db)]) + .unwrap(); + drop(block_sender1); // Close the sender to indicate no more transactions + + pipeline1.start_pipeline_processing(); + let _ = pipeline1.join(); + + info!("Sent the first block metadata transaction to start a new epoch"); + + // Now create the main pipeline for account creation + let current_version = db.reader.get_latest_ledger_info_version().unwrap(); let (pipeline, block_sender) = Pipeline::new( executor, - start_version, + current_version, &pipeline_config, - Some(1 + num_new_accounts / block_size * 101 / 100), + Some(num_new_accounts / block_size * 101 / 100), + indexer_wrapper, ); let mut generator = TransactionGenerator::new_with_existing_db( @@ -514,19 +706,60 @@ pub enum SingleRunMode { /// If your workflow has an end (generats no transactions after some point), /// you can set a large number, and test will stop by itself. run_for_blocks: Option, + additional_configs: Option, }, + EXACT { + print_transactions: bool, + allow_debug_build: bool, + benchmark_block_size: usize, + num_blocks: usize, + num_init_accounts: usize, + }, +} + +/// Optional more detailed configuration. +pub struct SingleRunAdditionalConfigs { + /// If num_generator_workers=1 then order in which transactions are generated + /// is kept in the block, otherwise transactions from different workers are + /// stitched together in arbitrary order + pub num_generator_workers: usize, + pub split_stages: bool, + pub enable_indexer_grpc: bool, } pub fn run_single_with_default_params( transaction_type: TransactionType, test_folder: impl AsRef, concurrency_level: usize, + use_blockstm_v2: bool, mode: SingleRunMode, ) -> SingleRunResults { aptos_logger::Logger::new().init(); + match mode { + SingleRunMode::TEST + | SingleRunMode::EXACT { + allow_debug_build: true, + .. + } => {}, + SingleRunMode::BENCHMARK { .. } + | SingleRunMode::EXACT { + allow_debug_build: false, + .. + } => { + debug_assert!( + false, + "Benchmark shouldn't be run in debug mode, use --release instead." + ); + }, + } + + set_layout_caches(true); + set_paranoid_type_checks(true); + set_async_runtime_checks(true); AptosVM::set_num_shards_once(1); AptosVM::set_concurrency_level_once(concurrency_level); + AptosVM::set_blockstm_v2_enabled_once(use_blockstm_v2); AptosVM::set_processed_transactions_detailed_counters(); rayon::ThreadPoolBuilder::new() @@ -539,10 +772,16 @@ pub fn run_single_with_default_params( let print_transactions = match mode { SingleRunMode::TEST => true, SingleRunMode::BENCHMARK { .. } => false, + SingleRunMode::EXACT { + print_transactions, .. + } => print_transactions, }; let num_accounts = match mode { SingleRunMode::TEST => 100, SingleRunMode::BENCHMARK { .. } => 100000, + SingleRunMode::EXACT { + num_init_accounts, .. + } => num_init_accounts, }; let num_blocks = match mode { SingleRunMode::TEST @@ -554,16 +793,59 @@ pub fn run_single_with_default_params( run_for_blocks: Some(num_blocks), .. } => num_blocks, + SingleRunMode::EXACT { num_blocks, .. } => num_blocks, }; let benchmark_block_size = match mode { SingleRunMode::TEST => 10, - SingleRunMode::BENCHMARK { approx_tps, .. } => { - debug_assert!( - false, - "Benchmark shouldn't be run in debug mode, use --release instead." - ); - (approx_tps / 4).clamp(10, 10000) - }, + SingleRunMode::BENCHMARK { approx_tps, .. } => (approx_tps / 4).clamp(10, 10000), + SingleRunMode::EXACT { + benchmark_block_size, + .. + } => benchmark_block_size, + }; + let num_generator_workers = match mode { + SingleRunMode::TEST => 1, + SingleRunMode::BENCHMARK { + additional_configs: None, + .. + } + | SingleRunMode::EXACT { .. } => 4, + SingleRunMode::BENCHMARK { + additional_configs: + Some(SingleRunAdditionalConfigs { + num_generator_workers, + .. + }), + .. + } => num_generator_workers, + }; + let split_stages = match mode { + SingleRunMode::TEST + | SingleRunMode::BENCHMARK { + additional_configs: None, + .. + } + | SingleRunMode::EXACT { .. } => false, + SingleRunMode::BENCHMARK { + additional_configs: Some(SingleRunAdditionalConfigs { split_stages, .. }), + .. + } => split_stages, + }; + let enable_indexer_grpc = match mode { + SingleRunMode::TEST + | SingleRunMode::EXACT { .. } + | SingleRunMode::BENCHMARK { + additional_configs: None, + .. + } => false, + SingleRunMode::BENCHMARK { + additional_configs: + Some(SingleRunAdditionalConfigs { + enable_indexer_grpc, + .. + }), + .. + } => enable_indexer_grpc, }; let num_main_signer_accounts = num_accounts / 5; @@ -581,17 +863,23 @@ pub fn run_single_with_default_params( let init_pipeline_config = PipelineConfig { num_sig_verify_threads: std::cmp::max(1, num_cpus::get() / 3), print_transactions, + wait_for_indexer_grpc: enable_indexer_grpc, ..Default::default() }; + let storage_test_config = StorageTestConfig { + pruner_config: NO_OP_STORAGE_PRUNER_CONFIG, /* prune_window */ + enable_storage_sharding: true, + enable_indexer_grpc, + }; + create_db_with_accounts::( num_accounts, /* num_accounts */ 100000 * 100000000, /* init_account_balance */ 10000, /* block_size */ &storage_dir, - NO_OP_STORAGE_PRUNER_CONFIG, /* prune_window */ + storage_test_config, verify_sequence_numbers, - true, init_pipeline_config, features.clone(), is_keyless, @@ -603,6 +891,9 @@ pub fn run_single_with_default_params( generate_then_execute: true, num_sig_verify_threads: std::cmp::max(1, num_cpus::get() / 3), print_transactions, + num_generator_workers, + split_stages, + wait_for_indexer_grpc: enable_indexer_grpc, ..Default::default() }; @@ -616,8 +907,7 @@ pub fn run_single_with_default_params( &storage_dir, checkpoint_dir, verify_sequence_numbers, - NO_OP_STORAGE_PRUNER_CONFIG, - true, + storage_test_config, execute_pipeline_config, features, is_keyless, @@ -639,9 +929,10 @@ mod tests { }, }, pipeline::PipelineConfig, + run_single_with_default_params, transaction_executor::BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, transaction_generator::TransactionGenerator, - BenchmarkWorkload, + BenchmarkWorkload, StorageTestConfig, }; use aptos_config::config::NO_OP_STORAGE_PRUNER_CONFIG; use aptos_crypto::HashValue; @@ -656,7 +947,10 @@ mod tests { account_address::AccountAddress, on_chain_config::{FeatureFlag, Features}, state_store::state_key::inner::StateKeyInner, - transaction::{Transaction, TransactionPayload}, + transaction::{ + signature_verified_transaction::into_signature_verified_block, Transaction, + TransactionOutput, TransactionPayload, + }, }; use aptos_vm::{aptos_vm::AptosVMBlockExecutor, AptosVM, VMBlockExecutor}; use itertools::Itertools; @@ -691,27 +985,7 @@ mod tests { } fn test_compare_prod_and_another_all_types(values_match: bool) { - let mut non_fa_features = default_benchmark_features(); - non_fa_features.disable(FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_APT_STORE); - non_fa_features.disable(FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE); - non_fa_features.disable(FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_STORE); - // non_fa_features.disable(FeatureFlag::MODULE_EVENT_MIGRATION); - // non_fa_features.disable(FeatureFlag::COIN_TO_FUNGIBLE_ASSET_MIGRATION); - - test_compare_prod_and_another::(values_match, non_fa_features.clone(), |address| { - aptos_stdlib::aptos_account_transfer(address, 1000) - }); - - test_compare_prod_and_another::( - values_match, - non_fa_features, - aptos_stdlib::aptos_account_create_account, - ); - let mut fa_features = default_benchmark_features(); - fa_features.enable(FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_APT_STORE); - fa_features.enable(FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE); - fa_features.enable(FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_STORE); fa_features.disable(FeatureFlag::CONCURRENT_FUNGIBLE_BALANCE); test_compare_prod_and_another::(values_match, fa_features.clone(), |address| { @@ -747,6 +1021,7 @@ mod tests { config.storage.dir = db_dir.as_ref().to_path_buf(); config.storage.storage_pruner_config = NO_OP_STORAGE_PRUNER_CONFIG; config.storage.rocksdb_configs.enable_storage_sharding = false; + config.indexer_grpc.enabled = false; // Disable indexer for tests let (txn, vm_result) = { let vm_db = init_db(&config); @@ -764,7 +1039,7 @@ mod tests { let block_id = HashValue::random(); vm_executor .execute_and_update_state( - (block_id, vec![txn.clone()]).into(), + (block_id, into_signature_verified_block(vec![txn.clone()])).into(), parent_block_id, BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, ) @@ -785,7 +1060,7 @@ mod tests { let block_id = HashValue::random(); other_executor .execute_and_update_state( - (block_id, vec![txn]).into(), + (block_id, into_signature_verified_block(vec![txn])).into(), parent_block_id, BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, ) @@ -807,7 +1082,7 @@ mod tests { let other_txn_output = &other_to_commit.transaction_outputs[0]; let other_cp_txn_output = &other_to_commit.transaction_outputs[1]; - assert_eq!(vm_cp_txn_output, other_cp_txn_output); + assert_equal_transaction_outputs(vm_cp_txn_output, other_cp_txn_output); let vm_event_types = vm_txn_output .events() @@ -882,6 +1157,16 @@ mod tests { } } + // TODO(HotState): hotness computation not implemented in all VMs, so their hotness part of the + // write set might be different. + fn assert_equal_transaction_outputs(output1: &TransactionOutput, output2: &TransactionOutput) { + assert_eq!(output1.write_set().as_v0(), output2.write_set().as_v0()); + assert_eq!(output1.events(), output2.events()); + assert_eq!(output1.gas_used(), output2.gas_used()); + assert_eq!(output1.status(), output2.status()); + assert_eq!(output1.auxiliary_data(), output2.auxiliary_data()); + } + fn test_generic_benchmark( transaction_type: Option, verify_sequence_numbers: bool, @@ -899,16 +1184,24 @@ mod tests { features.enable(FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_APT_STORE); features.enable(FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE); + let storage_test_config = StorageTestConfig { + pruner_config: NO_OP_STORAGE_PRUNER_CONFIG, + enable_storage_sharding: false, + enable_indexer_grpc: true, + }; + crate::db_generator::create_db_with_accounts::( 100, /* num_accounts */ // TODO(Gas): double check if this is correct 100_000_000_000, /* init_account_balance */ 5, /* block_size */ storage_dir.as_ref(), - NO_OP_STORAGE_PRUNER_CONFIG, /* prune_window */ + storage_test_config, verify_sequence_numbers, - false, - PipelineConfig::default(), + PipelineConfig { + wait_for_indexer_grpc: true, + ..Default::default() + }, features.clone(), false, ); @@ -937,9 +1230,11 @@ mod tests { storage_dir.as_ref(), checkpoint_dir, verify_sequence_numbers, - NO_OP_STORAGE_PRUNER_CONFIG, - false, - PipelineConfig::default(), + storage_test_config, + PipelineConfig { + wait_for_indexer_grpc: true, + ..Default::default() + }, features, false, ); @@ -973,6 +1268,18 @@ mod tests { ); } + #[test] + fn test_benchmark_orderless_transaction() { + AptosVM::set_num_shards_once(4); + AptosVM::set_concurrency_level_once(4); + AptosVM::set_processed_transactions_detailed_counters(); + NativeConfig::set_concurrency_level_once(4); + test_generic_benchmark::( + Some(TransactionTypeArg::NoOpOrderless), + true, + ); + } + #[test] fn test_native_vm_benchmark_transaction() { test_generic_benchmark::( @@ -1004,4 +1311,55 @@ mod tests { NativeParallelUncoordinatedBlockExecutor, >(Some(TransactionTypeArg::NoOp), false); } + + #[test] + fn test_fibonacci_recursive() { + test_generic_benchmark::( + Some(TransactionTypeArg::FibonacciRecursive20), + true, + ); + } + + #[test] + fn test_fibonacci_tail_recursive() { + test_generic_benchmark::( + Some(TransactionTypeArg::FibonacciTailRecursive20), + true, + ); + } + + #[test] + fn test_fibonacci_iterative() { + test_generic_benchmark::( + Some(TransactionTypeArg::FibonacciIterative20), + true, + ); + } + + #[test] + fn test_external_lib_bench_test() { + run_single_with_default_params( + TransactionTypeArg::AptFaTransfer.materialize_default(), + TempPath::new(), + 4, + true, + crate::SingleRunMode::TEST, + ); + } + #[test] + fn test_external_lib_bench_larger() { + run_single_with_default_params( + TransactionTypeArg::AptFaTransfer.materialize_default(), + TempPath::new(), + 4, + true, + crate::SingleRunMode::EXACT { + print_transactions: false, + allow_debug_build: true, + benchmark_block_size: 3, + num_blocks: 50, + num_init_accounts: 200, + }, + ); + } } diff --git a/execution/executor-benchmark/src/main.rs b/execution/executor-benchmark/src/main.rs index d325acabd79..87a995362b3 100644 --- a/execution/executor-benchmark/src/main.rs +++ b/execution/executor-benchmark/src/main.rs @@ -25,7 +25,7 @@ use aptos_executor_benchmark::{ }, }, pipeline::PipelineConfig, - BenchmarkWorkload, + BenchmarkWorkload, StorageTestConfig, }; use aptos_executor_service::remote_executor_client; use aptos_experimental_ptx_executor::PtxBlockExecutor; @@ -38,7 +38,9 @@ use aptos_transaction_generator_lib::WorkflowProgress; use aptos_transaction_workloads_lib::args::TransactionTypeArg; use aptos_types::on_chain_config::{FeatureFlag, Features}; use aptos_vm::{aptos_vm::AptosVMBlockExecutor, AptosVM, VMBlockExecutor}; -use aptos_vm_environment::prod_configs::set_paranoid_type_checks; +use aptos_vm_environment::prod_configs::{ + set_async_runtime_checks, set_layout_caches, set_paranoid_type_checks, +}; use clap::{Parser, Subcommand, ValueEnum}; use once_cell::sync::Lazy; use std::{ @@ -109,6 +111,28 @@ impl PrunerOpt { } } +#[derive(Debug, Parser)] +struct StorageOpt { + #[clap(flatten)] + pruner_opt: PrunerOpt, + + #[clap(long)] + enable_storage_sharding: bool, + + #[clap(long)] + enable_indexer_grpc: bool, +} + +impl StorageOpt { + fn storage_test_config(&self) -> StorageTestConfig { + StorageTestConfig { + pruner_config: self.pruner_opt.pruner_config(), + enable_storage_sharding: self.enable_storage_sharding, + enable_indexer_grpc: self.enable_indexer_grpc, + } + } +} + #[derive(Debug, Parser)] pub struct PipelineOpt { /// First generate all transactions for all blocks (and keep them in memory), @@ -153,7 +177,7 @@ pub struct PipelineOpt { } impl PipelineOpt { - fn pipeline_config(&self) -> PipelineConfig { + fn pipeline_config(&self, enable_indexer_grpc: bool) -> PipelineConfig { PipelineConfig { generate_then_execute: self.generate_then_execute, split_stages: self.split_stages, @@ -166,6 +190,7 @@ impl PipelineOpt { partitioner_config: self.sharding_opt.partitioner_config(), num_sig_verify_threads: self.num_sig_verify_threads, print_transactions: false, + wait_for_indexer_grpc: enable_indexer_grpc, } } } @@ -300,10 +325,7 @@ struct Opt { execution_threads: Option, #[clap(flatten)] - pruner_opt: PrunerOpt, - - #[clap(long)] - enable_storage_sharding: bool, + storage_opt: StorageOpt, #[clap(flatten)] pipeline_opt: PipelineOpt, @@ -323,6 +345,9 @@ struct Opt { #[clap(long)] skip_paranoid_checks: bool, + + #[clap(long)] + use_blockstm_v2: bool, } impl Opt { @@ -470,10 +495,10 @@ where init_account_balance, opt.block_size, data_dir, - opt.pruner_opt.pruner_config(), + opt.storage_opt.storage_test_config(), opt.verify_sequence_numbers, - opt.enable_storage_sharding, - opt.pipeline_opt.pipeline_config(), + opt.pipeline_opt + .pipeline_config(opt.storage_opt.enable_indexer_grpc), get_init_features(enable_feature, disable_feature), opt.use_keyless_accounts, ); @@ -533,9 +558,9 @@ where data_dir, checkpoint_dir, opt.verify_sequence_numbers, - opt.pruner_opt.pruner_config(), - opt.enable_storage_sharding, - opt.pipeline_opt.pipeline_config(), + opt.storage_opt.storage_test_config(), + opt.pipeline_opt + .pipeline_config(opt.storage_opt.enable_indexer_grpc), get_init_features(enable_feature, disable_feature), opt.use_keyless_accounts, ); @@ -552,10 +577,10 @@ where opt.block_size, data_dir, checkpoint_dir, - opt.pruner_opt.pruner_config(), + opt.storage_opt.storage_test_config(), opt.verify_sequence_numbers, - opt.enable_storage_sharding, - opt.pipeline_opt.pipeline_config(), + opt.pipeline_opt + .pipeline_config(opt.storage_opt.enable_indexer_grpc), Features::default(), opt.use_keyless_accounts, ); @@ -621,13 +646,19 @@ fn main() { execution_threads_per_shard = execution_threads; } + set_layout_caches(true); if opt.skip_paranoid_checks { set_paranoid_type_checks(false); + } else { + // If we do paranoid checks, then they are allowed to run async in post-commit hook. + set_paranoid_type_checks(true); + set_async_runtime_checks(true); } AptosVM::set_num_shards_once(execution_shards); AptosVM::set_concurrency_level_once(execution_threads_per_shard); NativeConfig::set_concurrency_level_once(execution_threads_per_shard); AptosVM::set_processed_transactions_detailed_counters(); + AptosVM::set_blockstm_v2_enabled_once(opt.use_blockstm_v2); let config = ProfilerConfig::new_with_defaults(); let handler = ProfilerHandler::new(config); diff --git a/execution/executor-benchmark/src/measurements.rs b/execution/executor-benchmark/src/measurements.rs index 6d638389bf2..4a993718b4a 100644 --- a/execution/executor-benchmark/src/measurements.rs +++ b/execution/executor-benchmark/src/measurements.rs @@ -14,6 +14,7 @@ use aptos_metrics_core::Histogram; use move_core_types::language_storage::StructTag; use std::{ collections::{BTreeMap, HashMap}, + fmt::Write, time::Instant, }; @@ -120,6 +121,7 @@ static OTHER_LABELS: &[(&str, bool, &str)] = &[ #[derive(Debug, Clone)] struct ExecutionTimeMeasurement { output_size: f64, + output_count: u64, sig_verify_total_time: f64, partitioning_total_time: f64, @@ -136,6 +138,9 @@ impl ExecutionTimeMeasurement { let output_size = PROCESSED_TXNS_OUTPUT_SIZE .with_label_values(&["execution"]) .get_sample_sum(); + let output_count = PROCESSED_TXNS_OUTPUT_SIZE + .with_label_values(&["execution"]) + .get_sample_count(); let sig_verify_total = TIMER.with_label_values(&["sig_verify"]).get_sample_sum(); let partitioning_total = TIMER.with_label_values(&["partition"]).get_sample_sum(); @@ -159,6 +164,7 @@ impl ExecutionTimeMeasurement { Self { output_size, + output_count, sig_verify_total_time: sig_verify_total, partitioning_total_time: partitioning_total, execution_total_time: execution_total, @@ -175,6 +181,7 @@ impl ExecutionTimeMeasurement { Self { output_size: end.output_size - self.output_size, + output_count: end.output_count - self.output_count, sig_verify_total_time: end.sig_verify_total_time - self.sig_verify_total_time, partitioning_total_time: end.partitioning_total_time - self.partitioning_total_time, execution_total_time: end.execution_total_time - self.execution_total_time, @@ -236,6 +243,62 @@ pub struct OverallMeasurement { } impl OverallMeasurement { + pub fn get_tps(&self) -> f64 { + self.num_txns as f64 / self.elapsed + } + + pub fn get_gps(&self) -> f64 { + self.delta_gas.gas / self.elapsed + } + + pub fn get_effective_gps(&self) -> f64 { + self.delta_gas.effective_block_gas / self.elapsed + } + + pub fn get_effective_conflict_multiplier(&self) -> f64 { + self.delta_gas.effective_block_gas / self.delta_gas.gas + } + + pub fn get_speculative_abort_rate(&self) -> f64 { + self.delta_gas.speculative_abort_count as f64 / self.num_txns as f64 + } + + pub fn get_io_gps(&self) -> f64 { + self.delta_gas.io_gas / self.elapsed + } + + pub fn get_execution_gps(&self) -> f64 { + self.delta_gas.execution_gas / self.elapsed + } + + pub fn get_gpt(&self) -> f64 { + self.delta_gas.gas / (self.delta_gas.gas_count as f64).max(1.0) + } + + pub fn get_io_gpt(&self) -> f64 { + self.delta_gas.io_gas / (self.delta_gas.gas_count as f64).max(1.0) + } + + pub fn get_execution_gpt(&self) -> f64 { + self.delta_gas.execution_gas / (self.delta_gas.gas_count as f64).max(1.0) + } + + pub fn get_storage_fee_per_txn(&self) -> f64 { + self.delta_gas.storage_fee / (self.delta_gas.gas_count as f64).max(1.0) + } + + pub fn get_approx_output_per_s(&self) -> f64 { + self.delta_gas.approx_block_output / self.elapsed + } + + pub fn get_output_per_s(&self) -> f64 { + self.delta_execution.output_size / self.elapsed + } + + pub fn get_output_per_txn(&self) -> f64 { + self.delta_execution.output_size / self.delta_execution.output_count as f64 + } + pub fn print_end(&self) { let num_txns = self.num_txns as f64; @@ -244,63 +307,56 @@ impl OverallMeasurement { info!( "{} TPS: {} txn/s (over {} txns, in {} s)", self.prefix, - num_txns / self.elapsed, + self.get_tps(), num_txns, self.elapsed ); - info!( - "{} GPS: {} gas/s", - self.prefix, - self.delta_gas.gas / self.elapsed - ); + info!("{} GPS: {} gas/s", self.prefix, self.get_gps()); info!( "{} effectiveGPS: {} gas/s ({} effective block gas, in {} s)", self.prefix, - self.delta_gas.effective_block_gas / self.elapsed, + self.get_effective_gps(), self.delta_gas.effective_block_gas, self.elapsed ); info!( "{} effective conflict multiplier: {}", self.prefix, - self.delta_gas.effective_block_gas / self.delta_gas.gas + self.get_effective_conflict_multiplier() ); info!( "{} speculative aborts: {} aborts/txn ({} aborts over {} txns)", self.prefix, - self.delta_gas.speculative_abort_count as f64 / num_txns, + self.get_speculative_abort_rate(), self.delta_gas.speculative_abort_count, self.num_txns ); - info!( - "{} ioGPS: {} gas/s", - self.prefix, - self.delta_gas.io_gas / self.elapsed - ); + info!("{} ioGPS: {} gas/s", self.prefix, self.get_io_gps()); info!( "{} executionGPS: {} gas/s", self.prefix, - self.delta_gas.execution_gas / self.elapsed - ); - info!( - "{} GPT: {} gas/txn", - self.prefix, - self.delta_gas.gas / (self.delta_gas.gas_count as f64).max(1.0) + self.get_execution_gps() ); + info!("{} GPT: {} gas/txn", self.prefix, self.get_gpt()); info!( "{} Storage fee: {} octas/txn", self.prefix, - self.delta_gas.storage_fee / (self.delta_gas.gas_count as f64).max(1.0) + self.get_storage_fee_per_txn() ); info!( "{} approx_output: {} bytes/s", self.prefix, - self.delta_gas.approx_block_output / self.elapsed + self.get_approx_output_per_s() ); info!( "{} output: {} bytes/s", self.prefix, - self.delta_execution.output_size / self.elapsed + self.get_output_per_s() + ); + info!( + "{} output: {} bytes/txn", + self.prefix, + self.get_output_per_txn() ); info!( @@ -363,17 +419,17 @@ impl OverallMeasurement { ); } - pub fn print_end_table(stages: &[Self], overall: &Self) { - for v in stages.iter().chain(std::iter::once(overall)) { - println!("{} {}", v.prefix, v.metadata); - } + pub fn format_end_table(stages: &[Self], overall: &Self) -> String { + let mut result = "".to_string(); fn print_one( + result: &mut String, stages: &[OverallMeasurement], overall: &OverallMeasurement, name: &str, fun: impl Fn(&OverallMeasurement) -> String, ) { - println!( + writeln!( + result, "{: <12}{}", name, stages @@ -381,39 +437,60 @@ impl OverallMeasurement { .chain(std::iter::once(overall)) .map(fun) .collect::() - ); + ) + .unwrap(); } - print_one(stages, overall, "", |v| { + print_one(&mut result, stages, overall, "", |v| { format!("{: >12}", v.prefix.replace("Staged execution: ", "")) }); - print_one(stages, overall, "TPS", |v| { - format!("{: >12.2}", v.num_txns as f64 / v.elapsed) + print_one(&mut result, stages, overall, "txn/s", |v| { + format!("{: >12.2}", v.get_tps()) }); - print_one(stages, overall, "GPS", |v| { - format!("{: >12.2}", v.delta_gas.gas / v.elapsed) + print_one(&mut result, stages, overall, "gas/s", |v| { + format!("{: >12.2}", v.get_gps()) }); - print_one(stages, overall, "effGPS", |v| { - format!("{: >12.2}", v.delta_gas.effective_block_gas / v.elapsed) + print_one(&mut result, stages, overall, "eff_gas/s", |v| { + format!("{: >12.2}", v.get_effective_gps()) }); - print_one(stages, overall, "GPT", |v| { - format!( - "{: >12.2}", - v.delta_gas.gas / (v.delta_gas.gas_count as f64).max(1.0) - ) + print_one(&mut result, stages, overall, "conf_mul", |v| { + format!("{: >12.2}", v.get_effective_conflict_multiplier()) }); - print_one(stages, overall, "ioGPT", |v| { - format!( - "{: >12.2}", - v.delta_gas.io_gas / (v.delta_gas.gas_count as f64).max(1.0) - ) + print_one(&mut result, stages, overall, "gas/txn", |v| { + format!("{: >12.2}", v.get_gpt()) }); - print_one(stages, overall, "exeGPT", |v| { - format!( - "{: >12.2}", - v.delta_gas.execution_gas / (v.delta_gas.gas_count as f64).max(1.0) - ) + print_one(&mut result, stages, overall, "io gas/txn", |v| { + format!("{: >12.2}", v.get_io_gpt()) + }); + print_one(&mut result, stages, overall, "exe gas/txn", |v| { + format!("{: >12.2}", v.get_execution_gpt()) }); + print_one(&mut result, stages, overall, "output/txn", |v| { + format!("{: >12.2}", v.get_output_per_txn()) + }); + result + } + + pub fn print_end_table(stages: &[Self], overall: &Self) { + for v in stages.iter().chain(std::iter::once(overall)) { + println!("{} {}", v.prefix, v.metadata); + } + println!("{}", Self::format_end_table(stages, overall)); + } + + pub fn json_end_table(&self) -> serde_json::Value { + serde_json::json!({ + "stage": self.prefix.replace("Staged execution: ", ""), + "metadata": self.metadata, + "txns/s": format!("{:.2}", self.get_tps()), + "gas/s": format!("{:.2}", self.get_gps()), + "eff_gas/s": format!("{:.2}", self.get_effective_gps()), + "conf_mul": format!("{:.2}", self.get_effective_conflict_multiplier()), + "gas/txn": format!("{:.2}", self.get_gpt()), + "io gas/txn": format!("{:.2}", self.get_io_gpt()), + "exe gas/txn": format!("{:.2}", self.get_execution_gpt()), + "output/txn": format!("{:.2}", self.get_output_per_txn()), + }) } } diff --git a/execution/executor-benchmark/src/native/aptos_vm_uncoordinated.rs b/execution/executor-benchmark/src/native/aptos_vm_uncoordinated.rs index 56ebb80fa6c..42a937232b4 100644 --- a/execution/executor-benchmark/src/native/aptos_vm_uncoordinated.rs +++ b/execution/executor-benchmark/src/native/aptos_vm_uncoordinated.rs @@ -13,7 +13,7 @@ use aptos_types::{ state_store::StateView, transaction::{ block_epilogue::BlockEndInfo, signature_verified_transaction::SignatureVerifiedTransaction, - BlockOutput, Transaction, TransactionOutput, + AuxiliaryInfo, BlockOutput, Transaction, TransactionOutput, }, vm_status::VMStatus, }; @@ -32,11 +32,11 @@ impl VMBlockExecutor for AptosVMParallelUncoordinatedBlockExecutor { fn execute_block( &self, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &(impl StateView + Sync), _onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { + ) -> Result, VMStatus> { let _timer = BLOCK_EXECUTOR_INNER_EXECUTE_BLOCK.start_timer(); // let features = Features::fetch_config(&state_view).unwrap_or_default(); @@ -44,10 +44,18 @@ impl VMBlockExecutor for AptosVMParallelUncoordinatedBlockExecutor { let env = AptosEnvironment::new(state_view); let vm = AptosVM::new(&env, state_view); + let block_epilogue_txn = Transaction::block_epilogue_v0( + transaction_slice_metadata + .append_state_checkpoint_to_block() + .unwrap(), + BlockEndInfo::new_empty(), + ); + let transaction_outputs = NATIVE_EXECUTOR_POOL.install(|| { txn_provider .get_txns() .par_iter() + .chain(vec![block_epilogue_txn.clone().into()].par_iter()) .enumerate() .map(|(txn_idx, txn)| { let log_context = AdapterLogSchema::new(state_view.id(), txn_idx); @@ -58,6 +66,7 @@ impl VMBlockExecutor for AptosVMParallelUncoordinatedBlockExecutor { &vm.as_move_resolver(state_view), &code_storage, &log_context, + &AuxiliaryInfo::default(), ) .map(|(_vm_status, vm_output)| { vm_output @@ -68,16 +77,9 @@ impl VMBlockExecutor for AptosVMParallelUncoordinatedBlockExecutor { .collect::, _>>() })?; - let block_epilogue_txn = Transaction::block_epilogue( - transaction_slice_metadata - .append_state_checkpoint_to_block() - .unwrap(), - BlockEndInfo::new_empty(), - ); - Ok(BlockOutput::new( transaction_outputs, - Some(block_epilogue_txn), + Some(block_epilogue_txn.into()), )) } } diff --git a/execution/executor-benchmark/src/native/native_transaction.rs b/execution/executor-benchmark/src/native/native_transaction.rs index 8c1ccbd9b89..ffa4dab345d 100644 --- a/execution/executor-benchmark/src/native/native_transaction.rs +++ b/execution/executor-benchmark/src/native/native_transaction.rs @@ -35,14 +35,19 @@ pub enum NativeTransaction { fail_on_recipient_account_existing: bool, fail_on_recipient_account_missing: bool, }, + BlockEpilogue, + BlockMetadata, } impl NativeTransaction { pub fn parse(txn: &SignatureVerifiedTransaction) -> Self { match &txn.expect_valid() { aptos_types::transaction::Transaction::UserTransaction(user_txn) => { - match user_txn.payload() { - aptos_types::transaction::TransactionPayload::EntryFunction(f) => { + // Use executable_ref() to handle both EntryFunction and Payload variants uniformly + match user_txn.payload().executable_ref() { + Ok(aptos_types::transaction::TransactionExecutableRef::EntryFunction(f)) + if !user_txn.payload().is_multisig() => + { match ( *f.module().address(), f.module().name().as_str(), @@ -112,10 +117,12 @@ impl NativeTransaction { ), } }, - _ => unimplemented!(), + _ => unimplemented!("user transaction {:?}", user_txn.payload()), } }, - _ => unimplemented!(), + aptos_types::transaction::Transaction::BlockEpilogue(_) => Self::BlockEpilogue, + aptos_types::transaction::Transaction::BlockMetadata(_) => Self::BlockMetadata, + _ => unimplemented!("non-user transaction {:?}", txn), } } } diff --git a/execution/executor-benchmark/src/native/native_vm.rs b/execution/executor-benchmark/src/native/native_vm.rs index 6e8d7036468..db01a954dc0 100644 --- a/execution/executor-benchmark/src/native/native_vm.rs +++ b/execution/executor-benchmark/src/native/native_vm.rs @@ -40,8 +40,8 @@ use aptos_types::{ on_chain_config::FeatureFlag, state_store::{state_key::StateKey, state_value::StateValueMetadata, StateView}, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, Transaction, - TransactionOutput, TransactionStatus, WriteSetPayload, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, BlockOutput, + Transaction, TransactionOutput, TransactionStatus, WriteSetPayload, }, write_set::WriteOp, AptosCoinType, @@ -86,14 +86,14 @@ impl VMBlockExecutor for NativeVMBlockExecutor { /// transaction output. fn execute_block( &self, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &(impl StateView + Sync), onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { + ) -> Result, VMStatus> { AptosBlockExecutorWrapper::::execute_block_on_thread_pool::< _, - NoOpTransactionCommitHook, + NoOpTransactionCommitHook, _, >( Arc::clone(&NATIVE_EXECUTOR_POOL), @@ -118,11 +118,16 @@ pub(crate) struct NativeVMExecutorTask { } impl ExecutorTask for NativeVMExecutorTask { + type AuxiliaryInfo = AuxiliaryInfo; type Error = VMStatus; type Output = AptosTransactionOutput; type Txn = SignatureVerifiedTransaction; - fn init(env: &AptosEnvironment, _state_view: &impl StateView) -> Self { + fn init( + env: &AptosEnvironment, + _state_view: &impl StateView, + _async_runtime_checks_enabled: bool, + ) -> Self { let fa_migration_complete = env .features() .is_enabled(FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE); @@ -147,22 +152,22 @@ impl ExecutorTask for NativeVMExecutorTask { &self, executor_with_group_view: &(impl ExecutorView + ResourceGroupView), txn: &SignatureVerifiedTransaction, + _auxiliary_info: &AuxiliaryInfo, _txn_idx: TxnIndex, ) -> ExecutionStatus { - let gas_units = 4; - match self.execute_transaction_impl( executor_with_group_view, txn, - gas_units, self.fa_migration_complete, ) { - Ok(change_set) => ExecutionStatus::Success(AptosTransactionOutput::new(VMOutput::new( - change_set, - ModuleWriteSet::empty(), - FeeStatement::new(gas_units, gas_units, 0, 0, 0), - TransactionStatus::Keep(aptos_types::transaction::ExecutionStatus::Success), - ))), + Ok((change_set, gas_units)) => { + ExecutionStatus::Success(AptosTransactionOutput::new(VMOutput::new( + change_set, + ModuleWriteSet::empty(), + FeeStatement::new(gas_units, gas_units, 0, 0, 0), + TransactionStatus::Keep(aptos_types::transaction::ExecutionStatus::Success), + ))) + }, Err(_) => ExecutionStatus::SpeculativeExecutionAbortError("something".to_string()), } } @@ -185,9 +190,9 @@ impl NativeVMExecutorTask { &self, view: &(impl ExecutorView + ResourceGroupView), txn: &SignatureVerifiedTransaction, - gas_units: u64, fa_migration_complete: bool, - ) -> Result { + ) -> Result<(VMChangeSet, u64), ()> { + let gas_units = 4; let gas = gas_units * 100; let mut resource_write_set = BTreeMap::new(); @@ -352,6 +357,8 @@ impl NativeVMExecutorTask { } } }, + NativeTransaction::BlockEpilogue => return Ok((VMChangeSet::empty(), 0)), + NativeTransaction::BlockMetadata => return Ok((VMChangeSet::empty(), 0)), }; events.push(( @@ -361,12 +368,15 @@ impl NativeVMExecutorTask { None, )); - Ok(VMChangeSet::new( - resource_write_set, - events, - delayed_field_change_set, - aggregator_v1_write_set, - aggregator_v1_delta_set, + Ok(( + VMChangeSet::new( + resource_write_set, + events, + delayed_field_change_set, + aggregator_v1_write_set, + aggregator_v1_delta_set, + ), + gas_units, )) } diff --git a/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs b/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs index 1966dbc9ac7..f68050dfba6 100644 --- a/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs +++ b/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs @@ -11,6 +11,7 @@ use anyhow::{bail, Result}; use aptos_block_executor::{ counters::BLOCK_EXECUTOR_INNER_EXECUTE_BLOCK, txn_provider::default::DefaultTxnProvider, }; +use aptos_metrics_core::TimerHelper; use aptos_types::{ account_address::AccountAddress, account_config::{ @@ -29,8 +30,8 @@ use aptos_types::{ state_store::{state_key::StateKey, StateView}, transaction::{ block_epilogue::BlockEndInfo, signature_verified_transaction::SignatureVerifiedTransaction, - BlockOutput, ExecutionStatus, Transaction, TransactionAuxiliaryData, TransactionOutput, - TransactionStatus, + AuxiliaryInfo, BlockOutput, ExecutionStatus, Transaction, TransactionAuxiliaryData, + TransactionOutput, TransactionStatus, }, vm_status::{StatusCode, VMStatus}, write_set::{WriteOp, WriteSetMut}, @@ -46,7 +47,6 @@ use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterato use std::{ cell::Cell, collections::BTreeMap, - hash::RandomState, sync::atomic::{AtomicU64, Ordering}, }; use thread_local::ThreadLocal; @@ -81,18 +81,26 @@ impl VMBlockExecutor fn execute_block( &self, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &(impl StateView + Sync), _onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { - let native_transactions = NATIVE_EXECUTOR_POOL.install(|| { + ) -> Result, VMStatus> { + let block_epilogue_txn = Transaction::block_epilogue_v0( + transaction_slice_metadata + .append_state_checkpoint_to_block() + .unwrap(), + BlockEndInfo::new_empty(), + ); + + let mut native_transactions = NATIVE_EXECUTOR_POOL.install(|| { txn_provider .get_txns() .par_iter() .map(NativeTransaction::parse) .collect::>() }); + native_transactions.push(NativeTransaction::parse(&block_epilogue_txn.clone().into())); let _timer = BLOCK_EXECUTOR_INNER_EXECUTE_BLOCK.start_timer(); @@ -112,16 +120,9 @@ impl VMBlockExecutor ) })?; - let block_epilogue_txn = Transaction::block_epilogue( - transaction_slice_metadata - .append_state_checkpoint_to_block() - .unwrap(), - BlockEndInfo::new_empty(), - ); - Ok(BlockOutput::new( transaction_outputs, - Some(block_epilogue_txn), + Some(block_epilogue_txn.into()), )) } } @@ -140,11 +141,13 @@ impl IncrementalOutput { } fn into_success_output(mut self, gas: u64) -> Result { - self.events.push( - FeeStatement::new(gas, gas, 0, 0, 0) - .create_event_v2() - .expect("Creating FeeStatement should always succeed"), - ); + if gas != 0 { + self.events.push( + FeeStatement::new(gas, gas, 0, 0, 0) + .create_event_v2() + .expect("Creating FeeStatement should always succeed"), + ); + } Ok(TransactionOutput::new( WriteSetMut::new(self.write_set).freeze()?, @@ -425,6 +428,8 @@ impl RawTransactionExecutor for T { } } }, + NativeTransaction::BlockEpilogue => return output.into_success_output(0), + NativeTransaction::BlockMetadata => return output.into_success_output(0), }; self.reduce_apt_supply(fa_migration_complete, gas, state_view, &mut output)?; @@ -534,9 +539,7 @@ impl CommonNativeRawTransactionExecutor for NativeRawTransactionExecutor { .db_util .new_state_key_object_resource_group(&sender_store_address); let mut sender_fa_store_object = { - let _timer = TIMER - .with_label_values(&["read_sender_fa_store"]) - .start_timer(); + let _timer = TIMER.timer_with(&["read_sender_fa_store"]); match DbAccessUtil::get_resource_group(&sender_fa_store_object_key, state_view)? { Some(sender_fa_store_object) => sender_fa_store_object, None => bail!("sender fa store missing"), @@ -586,9 +589,7 @@ impl CommonNativeRawTransactionExecutor for NativeRawTransactionExecutor { ) -> Result<()> { let sender_coin_store_key = self.db_util.new_state_key_aptos_coin(&sender_address); let sender_coin_store_opt = { - let _timer = TIMER - .with_label_values(&["read_sender_coin_store"]) - .start_timer(); + let _timer = TIMER.timer_with(&["read_sender_coin_store"]); DbAccessUtil::get_apt_coin_store(&sender_coin_store_key, state_view)? }; let mut sender_coin_store = match sender_coin_store_opt { @@ -923,11 +924,10 @@ impl CommonNativeRawTransactionExecutor for NativeValueCacheRawTransactionExecut ) }); - let total_supply_state_key = match entry.value() { + match entry.value() { CachedResource::AptCoinInfo(coin_info) => coin_info.supply_aggregator_state_key(), _ => panic!("wrong type"), - }; - total_supply_state_key + } }); if USE_THREAD_LOCAL_SUPPLY { @@ -1023,7 +1023,7 @@ impl NativeValueCacheRawTransactionExecutor { &'a self, key: &StateKey, init_value: impl FnOnce(&StateKey) -> CachedResource, - ) -> Ref<'a, StateKey, CachedResource, RandomState> { + ) -> Ref<'a, StateKey, CachedResource> { // Data in cache is going to be the hot path, so short-circuit here to avoid cloning the key. if let Some(ref_mut) = self.cache.get(key) { return ref_mut; @@ -1039,7 +1039,7 @@ impl NativeValueCacheRawTransactionExecutor { &'a self, key: &StateKey, init_value: impl FnOnce(&StateKey) -> CachedResource, - ) -> RefMut<'a, StateKey, CachedResource, RandomState> { + ) -> RefMut<'a, StateKey, CachedResource> { // Data in cache is going to be the hot path, so short-circuit here to avoid cloning the key. if let Some(ref_mut) = self.cache.get_mut(key) { return ref_mut; @@ -1241,6 +1241,8 @@ impl RawTransactionExecutor for NativeNoStorageRawTransactionExecutor { } (sender, sequence_number) }, + NativeTransaction::BlockEpilogue => return output.into_success_output(0), + NativeTransaction::BlockMetadata => return output.into_success_output(0), }; self.seq_nums.insert(sender, sequence_number); diff --git a/execution/executor-benchmark/src/pipeline.rs b/execution/executor-benchmark/src/pipeline.rs index 482f1c1a1a8..398be8d7079 100644 --- a/execution/executor-benchmark/src/pipeline.rs +++ b/execution/executor-benchmark/src/pipeline.rs @@ -3,6 +3,7 @@ use crate::{ block_preparation::BlockPreparationStage, + indexer_grpc_waiter::IndexerGrpcWaiter, ledger_update_stage::{CommitProcessing, LedgerUpdateStage}, measurements::{EventMeasurements, OverallMeasuring}, metrics::NUM_TXNS, @@ -12,8 +13,10 @@ use aptos_block_partitioner::v2::config::PartitionerV2Config; use aptos_crypto::HashValue; use aptos_executor::block_executor::BlockExecutor; use aptos_executor_types::{state_compute_result::StateComputeResult, BlockExecutorTrait}; +use aptos_indexer_grpc_table_info::table_info_service::TableInfoService; use aptos_infallible::Mutex; use aptos_logger::info; +use aptos_metrics_core::IntCounterVecHelper; use aptos_types::{ block_executor::partitioner::ExecutableBlock, transaction::{Transaction, TransactionPayload, Version}, @@ -25,6 +28,7 @@ use std::{ collections::{BTreeMap, HashMap}, marker::PhantomData, sync::{ + atomic::{AtomicBool, AtomicU64, Ordering}, mpsc::{self, SyncSender}, Arc, }, @@ -50,6 +54,7 @@ pub struct PipelineConfig { pub num_sig_verify_threads: usize, pub print_transactions: bool, + pub wait_for_indexer_grpc: bool, } pub struct Pipeline { @@ -70,6 +75,7 @@ where config: &PipelineConfig, // Need to specify num blocks, to size queues correctly, when delay_execution_start, split_stages or skip_commit are used num_blocks: Option, + indexer_wrapper: Option<(Arc, Arc, Arc)>, ) -> (Self, SyncSender>) { let parent_block_id = executor.committed_block_id(); let executor_1 = Arc::new(executor); @@ -116,6 +122,8 @@ where let (start_ledger_update_tx, start_ledger_update_rx) = create_start_tx_rx(config.split_stages); let (start_commit_tx, start_commit_rx) = create_start_tx_rx(config.split_stages); + let (start_indexer_grpc_wait_tx, start_indexer_grpc_wait_rx) = + create_start_tx_rx(config.wait_for_indexer_grpc); let mut join_handles = vec![]; @@ -207,9 +215,7 @@ where } } - NUM_TXNS - .with_label_values(&["execution"]) - .inc_by(block_size); + NUM_TXNS.inc_with_by(&["execution"], block_size); info!("Received block of size {:?} to execute", block_size); executed += block_size; stage_executed += block_size; @@ -274,8 +280,7 @@ where while let Ok(ledger_update_msg) = ledger_update_receiver.recv() { NUM_TXNS - .with_label_values(&["ledger_update"]) - .inc_by(ledger_update_msg.num_input_txns as u64); + .inc_with_by(&["ledger_update"], ledger_update_msg.num_input_txns as u64); ledger_update_stage.ledger_update(ledger_update_msg); } start_commit_tx.map(|tx| tx.send(())); @@ -285,6 +290,9 @@ where .expect("Failed to spawn ledger update thread."); join_handles.push(ledger_update_thread); + let target_version = Arc::new(Mutex::new(None)); + let target_version_clone = target_version.clone(); + if !config.skip_commit { let commit_thread = std::thread::Builder::new() .name("txn_committer".to_string()) @@ -293,7 +301,11 @@ where info!("Starting commit thread"); let mut committer = TransactionCommitter::new(executor_3, start_version, commit_receiver); - committer.run(); + let final_version = committer.run(); + + // Store the final version for indexer_grpc waiter + *target_version_clone.lock() = Some(final_version); + start_indexer_grpc_wait_tx.map(|tx| tx.send(())); 0 }) @@ -301,6 +313,41 @@ where join_handles.push(commit_thread); } + // Add indexer_grpc waiter stage + if config.wait_for_indexer_grpc && !config.skip_commit { + if let Some(indexer_wrapper) = indexer_wrapper { + let waiter = IndexerGrpcWaiter::new(indexer_wrapper.0, indexer_wrapper.1); + let target_version_for_waiter = target_version.clone(); + let waiter_thread = std::thread::Builder::new() + .name("indexer_grpc_waiter".to_string()) + .spawn(move || { + start_indexer_grpc_wait_rx.map(|rx| rx.recv()); + info!("Starting indexer_grpc waiter thread"); + + // Wait for target version to be set by commit thread + let target_ver = loop { + if let Some(ver) = *target_version_for_waiter.lock() { + break ver; + } + std::thread::sleep(std::time::Duration::from_millis(10)); + }; + + // Create a tokio runtime for async wait + let runtime = tokio::runtime::Runtime::new().unwrap(); + runtime.block_on( + waiter.wait_for_version(target_ver - 1, /*abort_on_finish=*/ true), + ); + indexer_wrapper.2.store(true, Ordering::SeqCst); + info!("Indexer_grpc waiter finished"); + // This is a HACK. Just sleep here to wait the DB lock to drop. + std::thread::sleep(std::time::Duration::from_secs(2)); + 0 + }) + .expect("Failed to spawn indexer_grpc waiter thread."); + join_handles.push(waiter_thread); + } + } + ( Self { join_handles, diff --git a/execution/executor-benchmark/src/transaction_committer.rs b/execution/executor-benchmark/src/transaction_committer.rs index d0311e27a45..b203ca3a4cd 100644 --- a/execution/executor-benchmark/src/transaction_committer.rs +++ b/execution/executor-benchmark/src/transaction_committer.rs @@ -13,6 +13,7 @@ use aptos_executor::{ }; use aptos_executor_types::BlockExecutorTrait; use aptos_logger::prelude::*; +use aptos_metrics_core::IntCounterVecHelper; use aptos_types::{ aggregate_signature::AggregateSignature, block_info::BlockInfo, @@ -69,8 +70,9 @@ where } } - pub fn run(&mut self) { + pub fn run(&mut self) -> Version { info!("Start with version: {}", self.start_version); + let mut last_version = self.start_version; while let Ok(msg) = self.block_receiver.recv() { let CommitBlockMessage { @@ -86,11 +88,10 @@ where .transaction_accumulator .root_hash(); let num_input_txns = output.num_input_transactions(); - NUM_TXNS - .with_label_values(&["commit"]) - .inc_by(num_input_txns as u64); + NUM_TXNS.inc_with_by(&["commit"], num_input_txns as u64); let version = output.expect_last_version(); + last_version = version; let commit_start = Instant::now(); let ledger_info_with_sigs = gen_li_with_sigs(block_id, root_hash, version); self.executor.pre_commit_block(block_id).unwrap(); @@ -107,6 +108,7 @@ where num_input_txns, ); } + last_version } } diff --git a/execution/executor-benchmark/src/transaction_executor.rs b/execution/executor-benchmark/src/transaction_executor.rs index 8ffa221a561..d8a7cd3f28d 100644 --- a/execution/executor-benchmark/src/transaction_executor.rs +++ b/execution/executor-benchmark/src/transaction_executor.rs @@ -7,6 +7,7 @@ use aptos_crypto::hash::HashValue; use aptos_executor::block_executor::BlockExecutor; use aptos_executor_types::BlockExecutorTrait; use aptos_logger::info; +use aptos_metrics_core::TimerHelper; use aptos_types::block_executor::{ config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock, }; @@ -62,8 +63,9 @@ where self.num_blocks_processed, block_id ); let num_input_txns = executable_block.transactions.num_transactions(); + assert!(num_input_txns > 0); { - let _timer = TIMER.with_label_values(&["execute"]).start_timer(); + let _timer = TIMER.timer_with(&["execute"]); self.executor .execute_and_update_state( executable_block, diff --git a/execution/executor-benchmark/src/transaction_generator.rs b/execution/executor-benchmark/src/transaction_generator.rs index 99a669db1b8..a53370ac0dd 100644 --- a/execution/executor-benchmark/src/transaction_generator.rs +++ b/execution/executor-benchmark/src/transaction_generator.rs @@ -6,8 +6,9 @@ use crate::{ account_generator::{AccountCache, AccountGenerator}, metrics::{NUM_TXNS, TIMER}, }; -use aptos_crypto::ed25519::Ed25519PrivateKey; +use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue, PrivateKey, Uniform}; use aptos_logger::info; +use aptos_metrics_core::{IntCounterVecHelper, TimerHelper}; use aptos_sdk::{ transaction_builder::{aptos_stdlib, TransactionFactory}, types::LocalAccount, @@ -18,17 +19,18 @@ use aptos_storage_interface::{ use aptos_types::{ account_address::AccountAddress, account_config::{aptos_test_root_address, AccountResource}, + block_metadata::BlockMetadata, chain_id::ChainId, state_store::MoveResourceExt, - transaction::{EntryFunction, Transaction, TransactionPayload}, + transaction::{ + authenticator::AuthenticationKey, EntryFunction, Transaction, TransactionPayload, + }, }; use chrono::Local; use indicatif::{ProgressBar, ProgressStyle}; use itertools::Itertools; use move_core_types::{ident_str, language_storage::ModuleId}; -#[cfg(test)] -use rand::SeedableRng; -use rand::{rngs::StdRng, seq::SliceRandom, thread_rng, Rng}; +use rand::{rngs::StdRng, seq::SliceRandom, thread_rng, Rng, SeedableRng}; use rayon::{ iter::{IntoParallelRefIterator, ParallelIterator}, ThreadPool, ThreadPoolBuilder, @@ -52,6 +54,101 @@ use thread_local::ThreadLocal; const META_FILENAME: &str = "metadata.toml"; pub const MAX_ACCOUNTS_INVOLVED_IN_P2P: usize = 1_000_000; +fn validator_address() -> AccountAddress { + // Replicate the exact same logic as genesis creation in test_config_with_custom_onchain + // 1. Create StdRng with the same seed used in test_utils.rs + let mut genesis_rng = StdRng::from_seed([0; 32]); + // 2. Generate seed for validator index 0 (same as in builder.rs generate_validator_config) + let validator_seed: [u8; 32] = genesis_rng.r#gen(); + // 3. Create another StdRng with that seed (same as KeyGen::from_seed) + let mut validator_rng = StdRng::from_seed(validator_seed); + // 4. Generate Ed25519 private key directly (same as KeyGen::generate_ed25519_private_key) + let private_key = Ed25519PrivateKey::generate(&mut validator_rng); + // 5. Get public key and derive account address (same as in keys.rs generate_key_objects line 44) + let public_key = private_key.public_key(); + let address = AuthenticationKey::ed25519(&public_key).account_address(); + eprintln!("DEBUG: Generated validator address: {:x}", address); + address +} + +fn get_genesis_validator_address(db: &DbReaderWriter) -> AccountAddress { + // Read the actual validator address from the genesis validator set + // This ensures we use the same validator that was registered during genesis + use aptos_types::{ + on_chain_config::ValidatorSet, + state_store::{state_key::StateKey, TStateView}, + }; + + let state_view = db.reader.latest_state_checkpoint_view().unwrap(); + + // Try to get the ValidatorSet resource from @aptos_framework + if let Ok(Some(validator_set_bytes)) = + state_view.get_state_value(&StateKey::on_chain_config::().unwrap()) + { + if let Ok(validator_set) = bcs::from_bytes::(validator_set_bytes.bytes()) { + if !validator_set.active_validators.is_empty() { + let validator_addr = validator_set.active_validators[0].account_address; + eprintln!( + "DEBUG: Using genesis validator address: {:x}", + validator_addr + ); + return validator_addr; + } + } + } + + // Fallback to generated address if we can't read the validator set + eprintln!("DEBUG: Could not read genesis validator set, falling back to generated address"); + validator_address() +} + +pub(crate) fn create_block_metadata_transaction(epoch: u64, db: &DbReaderWriter) -> Transaction { + // Use incremental timestamps to avoid triggering epoch reconfigurations + // Large real timestamps cause immediate epoch changes since last_reconfiguration_time is small + use std::sync::atomic::{AtomicU64, Ordering}; + static ROUND_COUNTER: AtomicU64 = AtomicU64::new(0); + static LAST_TIMESTAMP: AtomicU64 = AtomicU64::new(0); + static LAST_EPOCH: AtomicU64 = AtomicU64::new(0); + + // Check if epoch has changed and reset round counter if needed + let last_epoch = LAST_EPOCH.load(Ordering::SeqCst); + if last_epoch != epoch { + ROUND_COUNTER.store(0, Ordering::SeqCst); + LAST_EPOCH.store(epoch, Ordering::SeqCst); + } + + let round = ROUND_COUNTER.fetch_add(1, Ordering::SeqCst); + + // Get current real time to keep blockchain time close to real time for orderless transactions + let current_time_usecs = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_micros() as u64; + + // Ensure strictly increasing timestamps by comparing with last used timestamp + let last_timestamp = LAST_TIMESTAMP.load(Ordering::SeqCst); + let timestamp_usecs = if current_time_usecs > last_timestamp { + current_time_usecs + } else { + // If current time is not greater, increment by 1 microsecond to maintain strict ordering + last_timestamp + 1 + }; + + // Update the last timestamp atomically + LAST_TIMESTAMP.store(timestamp_usecs, Ordering::SeqCst); + info!("block metadata timestamp: {}", timestamp_usecs); + + Transaction::BlockMetadata(BlockMetadata::new( + HashValue::random(), + epoch, // use provided epoch + round, // proper incrementing round number (resets on epoch change) + get_genesis_validator_address(db), // use actual validator from genesis + vec![], + vec![], + timestamp_usecs, // real time with strict ordering guarantee + )) +} + pub(crate) fn get_progress_bar(num_accounts: usize) -> ProgressBar { let bar = ProgressBar::new(num_accounts as u64); bar.set_style(ProgressStyle::default_bar().template( @@ -115,6 +212,9 @@ pub struct TransactionGenerator { // TODO(grao): Use a different pool, and pin threads to dedicate cores to avoid affecting the // rest parts of benchmark. worker_pool: ThreadPool, + + /// Database reader-writer for accessing validator information + db: DbReaderWriter, } impl TransactionGenerator { @@ -216,12 +316,15 @@ impl TransactionGenerator { .num_threads(num_workers) .build() .unwrap(), + db, } } pub fn create_transaction_factory() -> TransactionFactory { TransactionFactory::new(ChainId::test()) - .with_transaction_expiration_time(300) + // Use relative expiration: current time + 60 seconds + // This ensures transactions have reasonable expiration window regardless of blockchain time + .with_transaction_expiration_time(60) .with_gas_unit_price(100) } @@ -371,7 +474,7 @@ impl TransactionGenerator { // and re-mint seed accounts here. let num_seed_accounts = (num_new_accounts / 1000).clamp(1, 100000); let seed_accounts_cache = - Self::gen_seed_account_cache(reader, num_seed_accounts, is_keyless); + Self::gen_seed_account_cache(reader.clone(), num_seed_accounts, is_keyless); println!( "[{}] Generating {} seed account creation txns, with {} coins.", @@ -387,6 +490,11 @@ impl TransactionGenerator { .collect::>() .chunks(block_size) { + // Refresh root account sequence number once per block from database + // This ensures we stay in sync even if BlockMetadata or other transactions affected the account + let current_seq_num = get_sequence_number(self.root_account.address(), reader.clone()); + self.root_account.set_sequence_number(current_seq_num); + let transactions: Vec<_> = chunk .iter() .map(|new_account| { @@ -401,7 +509,10 @@ impl TransactionGenerator { .collect(); bar.inc(transactions.len() as u64 - 1); if let Some(sender) = &self.block_sender { - sender.send(transactions).unwrap(); + // Add BlockMetadata transaction at the beginning of the block + let mut block_transactions = vec![create_block_metadata_transaction(1, &self.db)]; + block_transactions.extend(transactions); + sender.send(block_transactions).unwrap(); } } bar.finish(); @@ -602,7 +713,7 @@ impl TransactionGenerator { let conflicting_indices: Vec<_> = (0..num_txns_per_grp) .map(|_| { let index2 = accounts_pool[rng.gen_range(0, accounts_pool.len())]; - if rng.gen::() { + if rng.r#gen::() { (index1, index2) } else { (index2, index1) @@ -681,7 +792,7 @@ impl TransactionGenerator { F: Fn(T, &AccountCache) -> Option + Send + Sync, S: Fn(&T) -> usize, { - let _timer = TIMER.with_label_values(&["generate_block"]).start_timer(); + let _timer = TIMER.timer_with(&["generate_block"]); let block_size = inputs.len(); let mut jobs = Vec::new(); jobs.resize_with(self.num_workers, BTreeMap::new); @@ -709,13 +820,16 @@ impl TransactionGenerator { } let mut transactions = Vec::new(); + transactions.push(create_block_metadata_transaction(1, &self.db)); + + let init_size = transactions.len(); for i in 0..block_size { if let Some(txn) = transactions_by_index.get(&i) { transactions.push(txn.clone()); } } - if transactions.is_empty() { + if transactions.len() == init_size { let val = phase.fetch_add(1, Ordering::Relaxed); let last_generated_at = last_non_empty_phase.load(Ordering::Relaxed); if val > last_generated_at + 2 { @@ -739,9 +853,7 @@ impl TransactionGenerator { ); } - NUM_TXNS - .with_label_values(&["generation_done"]) - .inc_by(transactions.len() as u64); + NUM_TXNS.inc_with_by(&["generation_done"], transactions.len() as u64); if let Some(sender) = &self.block_sender { sender.send(transactions).unwrap(); diff --git a/execution/executor-service/Cargo.toml b/execution/executor-service/Cargo.toml index 01486b49c47..34be3b8d30c 100644 --- a/execution/executor-service/Cargo.toml +++ b/execution/executor-service/Cargo.toml @@ -18,14 +18,12 @@ aptos-block-partitioner = { workspace = true } aptos-config = { workspace = true } aptos-infallible = { workspace = true } aptos-keygen = { workspace = true } -aptos-language-e2e-tests = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-node-resource-metrics = { workspace = true } aptos-push-metrics = { workspace = true } aptos-secure-net = { workspace = true } aptos-storage-interface = { workspace = true } -aptos-transaction-simulation = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } bcs = { workspace = true } @@ -42,4 +40,5 @@ thiserror = { workspace = true } [dev-dependencies] aptos-language-e2e-tests = { workspace = true } +aptos-transaction-simulation = { workspace = true } aptos-vm = { workspace = true } diff --git a/execution/executor-service/src/lib.rs b/execution/executor-service/src/lib.rs index 25d14115975..aeff680a534 100644 --- a/execution/executor-service/src/lib.rs +++ b/execution/executor-service/src/lib.rs @@ -11,6 +11,7 @@ use aptos_types::{ }; use serde::{Deserialize, Serialize}; +#[allow(dead_code)] // TODO: remove. mod error; pub mod local_executor_helper; mod metrics; diff --git a/execution/executor-service/src/test_utils.rs b/execution/executor-service/src/test_utils.rs index 3934e676b4e..7f28cc27462 100644 --- a/execution/executor-service/src/test_utils.rs +++ b/execution/executor-service/src/test_utils.rs @@ -148,7 +148,7 @@ pub fn test_sharded_block_executor_no_conflict>( BlockExecutor, Waypoint, ) { - let (db, dbrw) = force_sharding - .then(|| { - DbReaderWriter::wrap(AptosDB::new_for_test_with_sharding( - &path, - DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, - )) - }) - .unwrap_or_else(|| DbReaderWriter::wrap(AptosDB::new_for_test(&path))); + let (db, dbrw) = DbReaderWriter::wrap( + if force_sharding { + AptosDB::new_for_test_with_sharding(&path, DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD) + } else { + AptosDB::new_for_test(&path) + }, + ); let waypoint = bootstrap_genesis::(&dbrw, genesis).unwrap(); let executor = BlockExecutor::new(dbrw.clone()); @@ -425,10 +440,12 @@ where } pub fn verify_transactions( - txn_list_with_proof: &TransactionListWithProof, + txn_list_with_proof: &TransactionListWithProofV2, expected_txns: &[Transaction], ) -> Result<()> { - let txns = &txn_list_with_proof.transactions; + let txns = &txn_list_with_proof + .get_transaction_list_with_proof() + .transactions; ensure!( *txns == expected_txns, "expected txns {:?} doesn't equal to returned txns {:?}", @@ -458,3 +475,20 @@ pub fn verify_committed_txn_status( Ok(()) } + +fn gen_auxiliary_info_for_block(block: &[SignatureVerifiedTransaction]) -> Vec { + block + .iter() + .map(|txn| { + txn.borrow_into_inner().try_as_signed_user_txn().map_or( + AuxiliaryInfo::new_empty(), + |_| { + AuxiliaryInfo::new( + PersistedAuxiliaryInfo::None, + Some(EphemeralAuxiliaryInfo { proposer_index: 0 }), + ) + }, + ) + }) + .collect() +} diff --git a/execution/executor-types/Cargo.toml b/execution/executor-types/Cargo.toml index 4fc2f997536..885c1e9502c 100644 --- a/execution/executor-types/Cargo.toml +++ b/execution/executor-types/Cargo.toml @@ -33,7 +33,7 @@ serde = { workspace = true } thiserror = { workspace = true } [dev-dependencies] -aptos-types = { workspace = true, features = ["fuzzing"] } +aptos-types = { workspace = true, features = ["fuzzing", "testing"] } [features] default = [] diff --git a/execution/executor-types/src/execution_output.rs b/execution/executor-types/src/execution_output.rs index b500dfe5a81..540d89ed483 100644 --- a/execution/executor-types/src/execution_output.rs +++ b/execution/executor-types/src/execution_output.rs @@ -15,6 +15,7 @@ use aptos_storage_interface::state_store::{ use aptos_types::{ contract_event::ContractEvent, epoch_state::EpochState, + state_store::hot_state::HotStateConfig, transaction::{ block_epilogue::BlockEndInfo, ExecutionStatus, Transaction, TransactionStatus, Version, }, @@ -94,7 +95,7 @@ impl ExecutionOutput { to_commit: TransactionsToKeep::new_dummy_success(txns), to_discard: TransactionsWithOutput::new_empty(), to_retry: TransactionsWithOutput::new_empty(), - result_state: LedgerState::new_empty(), + result_state: LedgerState::new_empty(HotStateConfig::default()), state_reads: ShardedStateCache::new_empty(None), block_end_info: None, next_epoch_state: None, @@ -178,12 +179,12 @@ impl Inner { let aborts = self .to_commit .iter() - .flat_map(|(txn, output)| match output.status().status() { + .flat_map(|(txn, output, aux_info)| match output.status().status() { Ok(execution_status) => { if execution_status.is_success() { None } else { - Some(format!("{:?}: {:?}", txn, output.status())) + Some(format!("{txn:?}: {:?} {aux_info:?}", output.status())) } }, Err(_) => None, @@ -194,13 +195,13 @@ impl Inner { .to_discard .iter() .take(3) - .map(|(txn, output)| format!("{:?}: {:?}", txn, output.status())) + .map(|(txn, output, aux_info)| format!("{txn:?}: {:?} {aux_info:?}", output.status())) .collect::>(); let retries_3 = self .to_retry .iter() .take(3) - .map(|(txn, output)| format!("{:?}: {:?}", txn, output.status())) + .map(|(txn, output, aux_info)| format!("{txn:?}: {:?} {aux_info:?}", output.status())) .collect::>(); if !aborts.is_empty() || !discards_3.is_empty() || !retries_3.is_empty() { diff --git a/execution/executor-types/src/lib.rs b/execution/executor-types/src/lib.rs index e39c7a43533..d631b906280 100644 --- a/execution/executor-types/src/lib.rs +++ b/execution/executor-types/src/lib.rs @@ -6,8 +6,12 @@ use anyhow::Result; use aptos_crypto::HashValue; use aptos_scratchpad::SparseMerkleTree; +use aptos_storage_interface::state_store::state_view::cached_state_view::CachedStateView; use aptos_types::{ - account_config::{NEW_EPOCH_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG}, + account_config::{ + randomness_event::RANDOMNESS_GENERATED_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_MOVE_TYPE_TAG, + NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG, + }, block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, contract_event::ContractEvent, dkg::DKG_START_EVENT_MOVE_TYPE_TAG, @@ -15,8 +19,8 @@ use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::state_key::StateKey, transaction::{ - Transaction, TransactionInfo, TransactionListWithProof, TransactionOutputListWithProof, - Version, + PersistedAuxiliaryInfo, Transaction, TransactionInfo, TransactionListWithProofV2, + TransactionOutputListWithProofV2, Version, }, write_set::WriteSet, }; @@ -47,7 +51,7 @@ pub trait ChunkExecutorTrait: Send + Sync { #[cfg(any(test, feature = "fuzzing"))] fn execute_chunk( &self, - txn_list_with_proof: TransactionListWithProof, + txn_list_with_proof: TransactionListWithProofV2, // Target LI that has been verified independently: the proofs are relative to this version. verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, @@ -62,7 +66,7 @@ pub trait ChunkExecutorTrait: Send + Sync { #[cfg(any(test, feature = "fuzzing"))] fn apply_chunk( &self, - txn_output_list_with_proof: TransactionOutputListWithProof, + txn_output_list_with_proof: TransactionOutputListWithProofV2, // Target LI that has been verified independently: the proofs are relative to this version. verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, @@ -82,7 +86,7 @@ pub trait ChunkExecutorTrait: Send + Sync { /// transaction accumulator. fn enqueue_chunk_by_execution( &self, - txn_list_with_proof: TransactionListWithProof, + txn_list_with_proof: TransactionListWithProofV2, // Target LI that has been verified independently: the proofs are relative to this version. verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, @@ -92,7 +96,7 @@ pub trait ChunkExecutorTrait: Send + Sync { /// transaction outputs directly to get the executed result. fn enqueue_chunk_by_transaction_outputs( &self, - txn_output_list_with_proof: TransactionOutputListWithProof, + txn_output_list_with_proof: TransactionOutputListWithProofV2, // Target LI that has been verified independently: the proofs are relative to this version. verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, @@ -179,6 +183,8 @@ pub trait BlockExecutorTrait: Send + Sync { /// Finishes the block executor by releasing memory held by inner data structures(SMT). fn finish(&self); + + fn state_view(&self, block_id: HashValue) -> ExecutorResult; } #[derive(Clone)] @@ -257,6 +263,7 @@ pub trait TransactionReplayer: Send { fn enqueue_chunks( &self, transactions: Vec, + persisted_info: Vec, transaction_infos: Vec, write_sets: Vec, event_vecs: Vec>, @@ -281,6 +288,7 @@ pub fn should_forward_to_subscription_service(event: &ContractEvent) -> bool { || type_tag == DKG_START_EVENT_MOVE_TYPE_TAG.deref() || type_tag == NEW_EPOCH_EVENT_MOVE_TYPE_TAG.deref() || type_tag == NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG.deref() + || type_tag == RANDOMNESS_GENERATED_EVENT_MOVE_TYPE_TAG.deref() } #[cfg(feature = "bench")] diff --git a/execution/executor-types/src/state_compute_result.rs b/execution/executor-types/src/state_compute_result.rs index ec370fd5ecf..1d57ebe37b7 100644 --- a/execution/executor-types/src/state_compute_result.rs +++ b/execution/executor-types/src/state_compute_result.rs @@ -155,10 +155,11 @@ impl StateComputeResult { } } - pub fn as_chunk_to_commit(&self) -> ChunkToCommit { + pub fn as_chunk_to_commit(&self) -> ChunkToCommit<'_> { ChunkToCommit { first_version: self.ledger_update_output.first_version(), transactions: &self.execution_output.to_commit.transactions, + persisted_auxiliary_infos: &self.execution_output.to_commit.persisted_auxiliary_infos, transaction_outputs: &self.execution_output.to_commit.transaction_outputs, transaction_infos: &self.ledger_update_output.transaction_infos, state: &self.execution_output.result_state, diff --git a/execution/executor-types/src/transactions_with_output.rs b/execution/executor-types/src/transactions_with_output.rs index 051c8f21b64..1dbc983e636 100644 --- a/execution/executor-types/src/transactions_with_output.rs +++ b/execution/executor-types/src/transactions_with_output.rs @@ -5,8 +5,8 @@ use crate::metrics::TIMER; use anyhow::{ensure, Result}; use aptos_metrics_core::TimerHelper; use aptos_storage_interface::state_store::state_update_refs::StateUpdateRefs; -use aptos_types::transaction::{Transaction, TransactionOutput, Version}; -use itertools::izip; +use aptos_types::transaction::{PersistedAuxiliaryInfo, Transaction, TransactionOutput, Version}; +use itertools::{izip, Itertools}; use std::{ fmt::{Debug, Formatter}, ops::Deref, @@ -16,17 +16,21 @@ use std::{ pub struct TransactionsWithOutput { pub transactions: Vec, pub transaction_outputs: Vec, + pub persisted_auxiliary_infos: Vec, } impl TransactionsWithOutput { pub fn new( transactions: Vec, transaction_outputs: Vec, + persisted_auxiliary_infos: Vec, ) -> Self { assert_eq!(transactions.len(), transaction_outputs.len()); + assert_eq!(transactions.len(), persisted_auxiliary_infos.len()); Self { transactions, transaction_outputs, + persisted_auxiliary_infos, } } @@ -34,9 +38,16 @@ impl TransactionsWithOutput { Self::default() } - pub fn push(&mut self, transaction: Transaction, transaction_output: TransactionOutput) { + pub fn push( + &mut self, + transaction: Transaction, + transaction_output: TransactionOutput, + persisted_auxiliary_info: PersistedAuxiliaryInfo, + ) { self.transactions.push(transaction); self.transaction_outputs.push(transaction_output); + self.persisted_auxiliary_infos + .push(persisted_auxiliary_info); } pub fn len(&self) -> usize { @@ -47,8 +58,26 @@ impl TransactionsWithOutput { self.transactions.is_empty() } - pub fn iter(&self) -> impl Iterator { - izip!(self.transactions.iter(), self.transaction_outputs.iter(),) + pub fn iter( + &self, + ) -> impl Iterator { + izip!( + self.transactions.iter(), + self.transaction_outputs.iter(), + self.persisted_auxiliary_infos.iter() + ) + } + + pub fn last(&self) -> Option<(&Transaction, &TransactionOutput, &PersistedAuxiliaryInfo)> { + self.transactions.last().map(|txn| { + ( + txn, + self.transaction_outputs.last().expect("Must be non-empty"), + self.persisted_auxiliary_infos + .last() + .expect("Must be non-empty"), + ) + }) } } @@ -62,13 +91,18 @@ pub struct TransactionsToKeep { } impl TransactionsToKeep { + /// `must_be_block` is a hint to tell the implementation that the last transaction is the only + /// checkpoint and there is no need to look further to find other checkpoints. pub fn index( first_version: Version, transactions_with_output: TransactionsWithOutput, - is_reconfig: bool, + must_be_block: bool, ) -> Self { let _timer = TIMER.timer_with(&["transactions_to_keep__index"]); + let (all_checkpoint_indices, is_reconfig) = + Self::get_all_checkpoint_indices(&transactions_with_output, must_be_block); + TransactionsToKeepBuilder { transactions_with_output, is_reconfig, @@ -77,15 +111,11 @@ impl TransactionsToKeep { .transaction_outputs .iter() .map(TransactionOutput::write_set); - let last_checkpoint_index = Self::get_last_checkpoint_index( - is_reconfig, - &transactions_with_output.transactions, - ); StateUpdateRefs::index_write_sets( first_version, write_sets, transactions_with_output.len(), - last_checkpoint_index, + all_checkpoint_indices, ) }, } @@ -96,26 +126,36 @@ impl TransactionsToKeep { first_version: Version, transactions: Vec, transaction_outputs: Vec, - is_reconfig: bool, + persisted_auxiliary_infos: Vec, ) -> Self { - let txns_with_output = TransactionsWithOutput::new(transactions, transaction_outputs); - Self::index(first_version, txns_with_output, is_reconfig) + let txns_with_output = TransactionsWithOutput::new( + transactions, + transaction_outputs, + persisted_auxiliary_infos, + ); + Self::index(first_version, txns_with_output, false) } pub fn new_empty() -> Self { - Self::make(0, vec![], vec![], false) + Self::make(0, vec![], vec![], vec![]) } pub fn new_dummy_success(txns: Vec) -> Self { let txn_outputs = vec![TransactionOutput::new_empty_success(); txns.len()]; - Self::make(0, txns, txn_outputs, false) + let persisted_auxiliary_infos = (0..txns.len()) + .map(|i| PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }) + .collect(); + Self::make(0, txns, txn_outputs, persisted_auxiliary_infos) } + /// Whether the last txn of this block/chunk is reconfig. pub fn is_reconfig(&self) -> bool { *self.borrow_is_reconfig() } - pub fn state_update_refs(&self) -> &StateUpdateRefs { + pub fn state_update_refs(&self) -> &StateUpdateRefs<'_> { self.borrow_state_update_refs() } @@ -135,16 +175,32 @@ impl TransactionsToKeep { } } - fn get_last_checkpoint_index(is_reconfig: bool, transactions: &[Transaction]) -> Option { - let _timer = TIMER.timer_with(&["get_last_checkpoint_index"]); + fn get_all_checkpoint_indices( + transactions_with_output: &TransactionsWithOutput, + must_be_block: bool, + ) -> (Vec, bool) { + let _timer = TIMER.timer_with(&["get_all_checkpoint_indices"]); + + let (last_txn, last_output) = match transactions_with_output.last() { + Some((txn, output, _)) => (txn, output), + None => return (Vec::new(), false), + }; + let is_reconfig = last_output.has_new_epoch_event(); - if is_reconfig { - return Some(transactions.len() - 1); + if must_be_block { + assert!(last_txn.is_non_reconfig_block_ending() || is_reconfig); + return (vec![transactions_with_output.len() - 1], is_reconfig); } - transactions - .iter() - .rposition(Transaction::is_non_reconfig_block_ending) + ( + transactions_with_output + .iter() + .positions(|(txn, output, _)| { + txn.is_non_reconfig_block_ending() || output.has_new_epoch_event() + }) + .collect(), + is_reconfig, + ) } pub fn ensure_at_most_one_checkpoint(&self) -> Result<()> { @@ -190,3 +246,214 @@ impl Debug for TransactionsToKeep { .finish() } } + +#[cfg(test)] +mod tests { + use super::{TransactionsToKeep, TransactionsWithOutput}; + use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue, PrivateKey, Uniform}; + use aptos_types::{ + account_address::AccountAddress, + contract_event::ContractEvent, + test_helpers::transaction_test_helpers::get_test_signed_txn, + transaction::{ + ExecutionStatus, PersistedAuxiliaryInfo, Transaction, TransactionAuxiliaryData, + TransactionOutput, TransactionStatus, + }, + write_set::WriteSet, + }; + + fn dummy_txn() -> Transaction { + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = private_key.public_key(); + let sender = AccountAddress::ZERO; + Transaction::UserTransaction(get_test_signed_txn( + sender, + 0, + &private_key, + public_key, + None, + )) + } + + fn ckpt_txn() -> Transaction { + Transaction::StateCheckpoint(HashValue::zero()) + } + + fn default_output() -> TransactionOutput { + TransactionOutput::new( + WriteSet::default(), + vec![], + 0, + TransactionStatus::Keep(ExecutionStatus::Success), + TransactionAuxiliaryData::default(), + ) + } + + fn output_with_reconfig() -> TransactionOutput { + let reconfig_event = ContractEvent::new_v2_with_type_tag_str( + "0x1::reconfiguration::NewEpochEvent", + b"".to_vec(), + ); + TransactionOutput::new( + WriteSet::default(), + vec![reconfig_event], + 0, + TransactionStatus::Keep(ExecutionStatus::Success), + TransactionAuxiliaryData::default(), + ) + } + + fn default_aux_info() -> PersistedAuxiliaryInfo { + PersistedAuxiliaryInfo::None + } + + #[test] + fn test_regular_block_without_reconfig() { + let txns = vec![dummy_txn(), dummy_txn(), ckpt_txn()]; + let outputs = vec![default_output(), default_output(), default_output()]; + let aux_infos = vec![default_aux_info(), default_aux_info(), default_aux_info()]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + { + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, true); + assert_eq!(all_ckpt_indices, vec![2]); + assert!(!is_reconfig); + } + + { + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert_eq!(all_ckpt_indices, vec![2]); + assert!(!is_reconfig); + } + } + + #[test] + fn test_regular_block_with_reconfig() { + let txns = vec![dummy_txn(), dummy_txn(), dummy_txn()]; + let outputs = vec![default_output(), default_output(), output_with_reconfig()]; + let aux_infos = vec![default_aux_info(), default_aux_info(), default_aux_info()]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + { + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, true); + assert_eq!(all_ckpt_indices, vec![2]); + assert!(is_reconfig); + } + + { + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert_eq!(all_ckpt_indices, vec![2]); + assert!(is_reconfig); + } + } + + #[test] + fn test_chunk_with_no_ckpt() { + let txns = vec![dummy_txn(), dummy_txn(), dummy_txn()]; + let outputs = vec![default_output(), default_output(), default_output()]; + let aux_infos = vec![default_aux_info(), default_aux_info(), default_aux_info()]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert!(all_ckpt_indices.is_empty()); + assert!(!is_reconfig); + } + + #[test] + fn test_chunk_with_ckpts_no_reconfig() { + let txns = vec![ + dummy_txn(), + ckpt_txn(), + dummy_txn(), + ckpt_txn(), + dummy_txn(), + ]; + let outputs = vec![ + default_output(), + default_output(), + default_output(), + default_output(), + default_output(), + ]; + let aux_infos = vec![ + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + ]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert_eq!(all_ckpt_indices, vec![1, 3]); + assert!(!is_reconfig); + } + + #[test] + fn test_chunk_with_ckpts_with_reconfig_in_the_middle() { + let txns = vec![ + dummy_txn(), + ckpt_txn(), + dummy_txn(), + dummy_txn(), + dummy_txn(), + ]; + let outputs = vec![ + default_output(), + default_output(), + default_output(), + output_with_reconfig(), + default_output(), + ]; + let aux_infos = vec![ + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + ]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert_eq!(all_ckpt_indices, vec![1, 3]); + assert!(!is_reconfig); + } + + #[test] + fn test_chunk_with_ckpts_with_reconfig_at_end() { + let txns = vec![ + dummy_txn(), + ckpt_txn(), + dummy_txn(), + dummy_txn(), + dummy_txn(), + ]; + let outputs = vec![ + default_output(), + default_output(), + default_output(), + default_output(), + output_with_reconfig(), + ]; + let aux_infos = vec![ + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + default_aux_info(), + ]; + let txn_with_outputs = TransactionsWithOutput::new(txns, outputs, aux_infos); + + let (all_ckpt_indices, is_reconfig) = + TransactionsToKeep::get_all_checkpoint_indices(&txn_with_outputs, false); + assert_eq!(all_ckpt_indices, vec![1, 4]); + assert!(is_reconfig); + } +} diff --git a/execution/executor/Cargo.toml b/execution/executor/Cargo.toml index d77ed487281..1d9e7d49bc9 100644 --- a/execution/executor/Cargo.toml +++ b/execution/executor/Cargo.toml @@ -21,11 +21,9 @@ aptos-drop-helper = { workspace = true } aptos-executor-service = { workspace = true } aptos-executor-types = { workspace = true } aptos-experimental-runtimes = { workspace = true } -aptos-indexer-grpc-table-info = { workspace = true } aptos-infallible = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } -aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } @@ -44,6 +42,8 @@ aptos-config = { workspace = true } aptos-db = { workspace = true } aptos-db-indexer = { workspace = true, features = ["fuzzing"] } aptos-executor-test-helpers = { workspace = true } +aptos-indexer-grpc-table-info = { workspace = true } +aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-temppath = { workspace = true } aptos-transaction-simulation = { workspace = true } diff --git a/execution/executor/benches/data_collection.rs b/execution/executor/benches/data_collection.rs index 5b27433297b..397281d31bf 100644 --- a/execution/executor/benches/data_collection.rs +++ b/execution/executor/benches/data_collection.rs @@ -1,12 +1,11 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_storage_interface::state_store::NUM_STATE_SHARDS; use aptos_types::{ account_address::AccountAddress, account_config::AccountResource, event::{EventHandle, EventKey}, - state_store::{state_key::StateKey, state_value::StateValue}, + state_store::{state_key::StateKey, state_value::StateValue, NUM_STATE_SHARDS}, transaction::Version, write_set::{WriteOp, WriteSet}, }; @@ -154,7 +153,7 @@ fn collect_per_version_sharded_state_values(c: &mut Criterion, write_sets: &[Wri .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].push((k, v)); + ret[k.get_shard_id()].push((k, v)); } ret }) @@ -170,7 +169,7 @@ fn collect_per_version_sharded_state_values(c: &mut Criterion, write_sets: &[Wri .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].push((k, v)); + ret[k.get_shard_id()].push((k, v)); } ret }) @@ -185,7 +184,7 @@ fn collect_per_version_sharded_state_values(c: &mut Criterion, write_sets: &[Wri .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_updates_cloned() { - ret[k.get_shard_id() as usize].push((k, v)); + ret[k.get_shard_id()].push((k, v)); } ret }) @@ -201,7 +200,7 @@ fn collect_per_version_sharded_state_values(c: &mut Criterion, write_sets: &[Wri .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].insert(k, v); + ret[k.get_shard_id()].insert(k, v); } ret }) @@ -217,7 +216,7 @@ fn collect_per_version_sharded_state_values(c: &mut Criterion, write_sets: &[Wri .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].insert(k, v); + ret[k.get_shard_id()].insert(k, v); } ret }) @@ -236,7 +235,7 @@ fn collect_sharded_per_version_state_value_refs(c: &mut Criterion, write_sets: & write_sets.iter().enumerate().for_each(|(idx, write_set)| { for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize][idx].push((k, v)); + ret[k.get_shard_id()][idx].push((k, v)); } }); ret @@ -254,7 +253,7 @@ fn collect_sharded_per_version_state_value_refs(c: &mut Criterion, write_sets: & .for_each(|(shard_id, shard)| { write_sets.iter().enumerate().for_each(|(idx, write_set)| { for (k, v) in write_set.state_update_refs() { - if k.get_shard_id() == shard_id as u8 { + if k.get_shard_id() == shard_id { shard[idx].push((k, v)); } } @@ -271,7 +270,7 @@ fn collect_sharded_per_version_state_value_refs(c: &mut Criterion, write_sets: & write_sets.iter().enumerate().for_each(|(idx, write_set)| { for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize][idx].insert(k, v); + ret[k.get_shard_id()][idx].insert(k, v); } }); ret @@ -289,7 +288,7 @@ fn collect_sharded_state_updates_with_version(c: &mut Criterion, write_sets: &[W arr![Vec::with_capacity(write_sets.len()); 16]; write_sets.iter().enumerate().for_each(|(idx, write_set)| { for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].push((first_version + idx as Version, k, v)); + ret[k.get_shard_id()].push((first_version + idx as Version, k, v)); } }); @@ -420,7 +419,7 @@ fn collect_state_update_maps(c: &mut Criterion, write_sets: &[WriteSet]) { .map(|write_set| { let mut ret = empty_shards::>(); for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].push((k, v)); + ret[k.get_shard_id()].push((k, v)); } ret }) @@ -467,7 +466,7 @@ fn collect_state_update_maps(c: &mut Criterion, write_sets: &[WriteSet]) { let mut ret = arr![Vec::with_capacity(write_sets.len()); 16]; write_sets.iter().enumerate().for_each(|(idx, write_set)| { for (k, v) in write_set.state_update_refs() { - ret[k.get_shard_id() as usize].push((first_version + idx as Version, k, v)); + ret[k.get_shard_id()].push((first_version + idx as Version, k, v)); } }); ret diff --git a/execution/executor/src/block_executor/block_tree/test.rs b/execution/executor/src/block_executor/block_tree/test.rs index 0411533f677..2786e02b550 100644 --- a/execution/executor/src/block_executor/block_tree/test.rs +++ b/execution/executor/src/block_executor/block_tree/test.rs @@ -9,7 +9,10 @@ use crate::{ use aptos_crypto::{hash::PRE_GENESIS_BLOCK_ID, HashValue}; use aptos_infallible::Mutex; use aptos_storage_interface::LedgerSummary; -use aptos_types::{block_info::BlockInfo, epoch_state::EpochState, ledger_info::LedgerInfo}; +use aptos_types::{ + block_info::BlockInfo, epoch_state::EpochState, ledger_info::LedgerInfo, + state_store::hot_state::HotStateConfig, +}; use std::sync::Arc; impl BlockTree { @@ -39,7 +42,7 @@ fn id(index: u64) -> HashValue { } fn empty_block() -> PartialStateComputeResult { - PartialStateComputeResult::new_empty(LedgerSummary::new_empty()) + PartialStateComputeResult::new_empty(LedgerSummary::new_empty(HotStateConfig::default())) } fn gen_ledger_info(block_id: HashValue, reconfig: bool) -> LedgerInfo { diff --git a/execution/executor/src/block_executor/mod.rs b/execution/executor/src/block_executor/mod.rs index 7cb9c398ceb..41f35d8c340 100644 --- a/execution/executor/src/block_executor/mod.rs +++ b/execution/executor/src/block_executor/mod.rs @@ -23,9 +23,9 @@ use aptos_executor_types::{ state_compute_result::StateComputeResult, BlockExecutorTrait, ExecutorError, ExecutorResult, }; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; -use aptos_infallible::RwLock; +use aptos_infallible::{Mutex, RwLock}; use aptos_logger::prelude::*; -use aptos_metrics_core::{IntGaugeHelper, TimerHelper}; +use aptos_metrics_core::{IntGaugeVecHelper, TimerHelper}; use aptos_storage_interface::{ state_store::{ state_summary::ProvableStateSummary, state_view::cached_state_view::CachedStateView, @@ -50,6 +50,7 @@ pub mod block_tree; pub struct BlockExecutor { pub db: DbReaderWriter, inner: RwLock>>, + execution_lock: Mutex<()>, } impl BlockExecutor @@ -60,6 +61,7 @@ where Self { db, inner: RwLock::new(None), + execution_lock: Mutex::new(()), } } @@ -115,6 +117,8 @@ where let _guard = CONCURRENCY_GAUGE.concurrency_with(&["block", "execute_and_state_checkpoint"]); self.maybe_initialize()?; + // guarantee only one block being executed at a time + let _guard = self.execution_lock.lock(); self.inner .read() .as_ref() @@ -131,7 +135,6 @@ where ) -> ExecutorResult { let _guard = CONCURRENCY_GAUGE.concurrency_with(&["block", "ledger_update"]); - self.maybe_initialize()?; self.inner .read() .as_ref() @@ -170,6 +173,11 @@ where *self.inner.write() = None; } + + fn state_view(&self, block_id: HashValue) -> ExecutorResult { + self.maybe_initialize()?; + self.inner.read().as_ref().unwrap().state_view(block_id) + } } struct BlockExecutorInner { @@ -217,6 +225,7 @@ where let ExecutableBlock { block_id, transactions, + auxiliary_info, } = block; let mut block_vec = self .block_tree @@ -260,6 +269,7 @@ where DoGetExecutionOutput::by_transaction_execution( &self.block_executor, transactions, + auxiliary_info, parent_output.result_state(), state_view, onchain_config.clone(), @@ -295,7 +305,11 @@ where // At this point of time two things must happen // 1. The block tree must also have the current block id with or without the ledger update output. // 2. We must have the ledger update output of the parent block. - let block = block_vec.pop().expect("Must exist").unwrap(); + // Above is not ture if the block is on a forked branch. + let block = block_vec + .pop() + .expect("Must exist") + .ok_or(ExecutorError::BlockNotFound(parent_block_id))?; parent_block.ensure_has_child(block_id)?; let output = &block.output; let parent_out = &parent_block.output; @@ -406,4 +420,17 @@ where Ok(()) } + + fn state_view(&self, block_id: HashValue) -> ExecutorResult { + let mut block_vec = self.block_tree.get_blocks_opt(&[block_id])?; + let block = block_vec + .pop() + .expect("Must exist.") + .ok_or(ExecutorError::BlockNotFound(block_id))?; + Ok(CachedStateView::new( + StateViewId::BlockExecution { block_id }, + Arc::clone(&self.db.reader), + block.output.result_state().latest().clone(), + )?) + } } diff --git a/execution/executor/src/chunk_executor/mod.rs b/execution/executor/src/chunk_executor/mod.rs index b0ca02943ed..cb890bf1f35 100644 --- a/execution/executor/src/chunk_executor/mod.rs +++ b/execution/executor/src/chunk_executor/mod.rs @@ -22,7 +22,7 @@ use aptos_executor_types::{ use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_infallible::{Mutex, RwLock}; use aptos_logger::prelude::*; -use aptos_metrics_core::{IntGaugeHelper, TimerHelper}; +use aptos_metrics_core::{IntGaugeVecHelper, TimerHelper}; use aptos_storage_interface::{ state_store::{ state::State, state_summary::ProvableStateSummary, @@ -39,9 +39,11 @@ use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::StateViewId, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, Transaction, - TransactionAuxiliaryData, TransactionInfo, TransactionListWithProof, TransactionOutput, - TransactionOutputListWithProof, TransactionStatus, Version, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, + PersistedAuxiliaryInfo, Transaction, TransactionAuxiliaryData, TransactionInfo, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithProof, TransactionOutputListWithProofV2, TransactionStatus, + Version, }, write_set::WriteSet, }; @@ -112,7 +114,7 @@ impl ChunkExecutor { impl ChunkExecutorTrait for ChunkExecutor { fn enqueue_chunk_by_execution( &self, - txn_list_with_proof: TransactionListWithProof, + txn_list_with_proof: TransactionListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, ) -> Result<()> { @@ -126,10 +128,11 @@ impl ChunkExecutorTrait for ChunkExecutor { if !cfg!(feature = "consensus-only-perf-test") { txn_list_with_proof.verify( verified_target_li.ledger_info(), - txn_list_with_proof.first_transaction_version, + txn_list_with_proof.get_first_transaction_version(), )?; } + let (txn_list_with_proof, persisted_aux_info) = txn_list_with_proof.into_parts(); // Compose enqueue_chunk parameters. let TransactionListWithProof { transactions, @@ -140,6 +143,7 @@ impl ChunkExecutorTrait for ChunkExecutor { let chunk = ChunkToExecute { transactions, + persisted_aux_info, first_version: v.ok_or_else(|| anyhow!("first version is None"))?, }; let chunk_verifier = Arc::new(StateSyncChunkVerifier { @@ -154,7 +158,7 @@ impl ChunkExecutorTrait for ChunkExecutor { fn enqueue_chunk_by_transaction_outputs( &self, - txn_output_list_with_proof: TransactionOutputListWithProof, + txn_output_list_with_proof: TransactionOutputListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&LedgerInfoWithSignatures>, ) -> Result<()> { @@ -166,21 +170,24 @@ impl ChunkExecutorTrait for ChunkExecutor { let _timer = CHUNK_OTHER_TIMERS.timer_with(&["apply_chunk__verify"]); txn_output_list_with_proof.verify( verified_target_li.ledger_info(), - txn_output_list_with_proof.first_transaction_output_version, + txn_output_list_with_proof.get_first_output_version(), ) })?; + let (txn_output_list_with_proof, persisted_aux_info) = + txn_output_list_with_proof.into_parts(); // Compose enqueue_chunk parameters. let TransactionOutputListWithProof { transactions_and_outputs, first_transaction_output_version: v, proof: txn_infos_with_proof, } = txn_output_list_with_proof; - let (transactions, transaction_outputs) = transactions_and_outputs.into_iter().unzip(); - + let (transactions, transaction_outputs): (Vec<_>, Vec<_>) = + transactions_and_outputs.into_iter().unzip(); let chunk = ChunkToApply { transactions, transaction_outputs, + persisted_aux_info, first_version: v.ok_or_else(|| anyhow!("first version is None"))?, }; let chunk_verifier = Arc::new(StateSyncChunkVerifier { @@ -407,6 +414,7 @@ impl TransactionReplayer for ChunkExecutor { fn enqueue_chunks( &self, transactions: Vec, + persisted_aux_info: Vec, transaction_infos: Vec, write_sets: Vec, event_vecs: Vec>, @@ -421,6 +429,7 @@ impl TransactionReplayer for ChunkExecutor { .expect("not reset") .enqueue_chunks( transactions, + persisted_aux_info, transaction_infos, write_sets, event_vecs, @@ -439,6 +448,7 @@ impl ChunkExecutorInner { fn enqueue_chunks( &self, mut transactions: Vec, + mut persisted_aux_info: Vec, mut transaction_infos: Vec, mut write_sets: Vec, mut event_vecs: Vec>, @@ -468,6 +478,7 @@ impl ChunkExecutorInner { for (begin, end) in epochs { chunks_enqueued += self.remove_and_replay_epoch( &mut transactions, + &mut persisted_aux_info, &mut transaction_infos, &mut write_sets, &mut event_vecs, @@ -508,6 +519,7 @@ impl ChunkExecutorInner { fn remove_and_replay_epoch( &self, transactions: &mut Vec, + persisted_aux_info: &mut Vec, transaction_infos: &mut Vec, write_sets: &mut Vec, event_vecs: &mut Vec>, @@ -530,6 +542,7 @@ impl ChunkExecutorInner { // batch_end is a known broken version that won't pass execution verification self.remove_and_apply( transactions, + persisted_aux_info, transaction_infos, write_sets, event_vecs, @@ -550,6 +563,7 @@ impl ChunkExecutorInner { let next_begin = if verify_execution_mode.should_verify() { self.verify_execution( transactions, + persisted_aux_info, transaction_infos, write_sets, event_vecs, @@ -562,6 +576,7 @@ impl ChunkExecutorInner { }; self.remove_and_apply( transactions, + persisted_aux_info, transaction_infos, write_sets, event_vecs, @@ -578,6 +593,7 @@ impl ChunkExecutorInner { fn verify_execution( &self, transactions: &[Transaction], + persisted_aux_info: &[PersistedAuxiliaryInfo], transaction_infos: &[TransactionInfo], write_sets: &[WriteSet], event_vecs: &[Vec], @@ -595,10 +611,16 @@ impl ChunkExecutorInner { .map(|t| t.into()) .collect::>(); + let auxiliary_info = persisted_aux_info + .iter() + .take((end_version - begin_version) as usize) + .map(|persisted_aux_info| AuxiliaryInfo::new(*persisted_aux_info, None)) + .collect::>(); // State sync executor shouldn't have block gas limit. let execution_output = DoGetExecutionOutput::by_transaction_execution::( &V::new(), txns.into(), + auxiliary_info, &parent_state, state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), @@ -635,6 +657,7 @@ impl ChunkExecutorInner { fn remove_and_apply( &self, transactions: &mut Vec, + persisted_aux_info: &mut Vec, transaction_infos: &mut Vec, write_sets: &mut Vec, event_vecs: &mut Vec>, @@ -643,15 +666,17 @@ impl ChunkExecutorInner { ) -> Result<()> { let num_txns = (end_version - begin_version) as usize; let txn_infos: Vec<_> = transaction_infos.drain(..num_txns).collect(); - let (transactions, transaction_outputs) = multizip(( + let (transactions, persisted_aux_info, transaction_outputs) = multizip(( transactions.drain(..num_txns), + persisted_aux_info.drain(..num_txns), txn_infos.iter(), write_sets.drain(..num_txns), event_vecs.drain(..num_txns), )) - .map(|(txn, txn_info, write_set, events)| { + .map(|(txn, persisted_aux_info, txn_info, write_set, events)| { ( txn, + persisted_aux_info, TransactionOutput::new( write_set, events, @@ -661,11 +686,12 @@ impl ChunkExecutorInner { ), ) }) - .unzip(); + .multiunzip(); let chunk = ChunkToApply { transactions, transaction_outputs, + persisted_aux_info, first_version: begin_version, }; let chunk_verifier = Arc::new(ReplayChunkVerifier { diff --git a/execution/executor/src/chunk_executor/transaction_chunk.rs b/execution/executor/src/chunk_executor/transaction_chunk.rs index eb749734dd9..b767743f29b 100644 --- a/execution/executor/src/chunk_executor/transaction_chunk.rs +++ b/execution/executor/src/chunk_executor/transaction_chunk.rs @@ -17,7 +17,7 @@ use aptos_types::{ config::BlockExecutorConfigFromOnchain, transaction_slice_metadata::TransactionSliceMetadata, }, - transaction::{Transaction, TransactionOutput, Version}, + transaction::{AuxiliaryInfo, PersistedAuxiliaryInfo, Transaction, TransactionOutput, Version}, }; use aptos_vm::VMBlockExecutor; use once_cell::sync::Lazy; @@ -52,6 +52,7 @@ pub trait TransactionChunk { pub struct ChunkToExecute { pub transactions: Vec, + pub persisted_aux_info: Vec, pub first_version: Version, } @@ -71,9 +72,16 @@ impl TransactionChunk for ChunkToExecute { ) -> Result { let ChunkToExecute { transactions, + persisted_aux_info, first_version: _, } = self; + assert_eq!( + transactions.len(), + persisted_aux_info.len(), + "transactions and persisted_aux_info must have the same length" + ); + // TODO(skedia) In the chunk executor path, we ideally don't need to verify the signature // as only transactions with verified signatures are committed to the storage. let sig_verified_txns = { @@ -93,6 +101,10 @@ impl TransactionChunk for ChunkToExecute { DoGetExecutionOutput::by_transaction_execution::( &V::new(), sig_verified_txns.into(), + persisted_aux_info + .into_iter() + .map(|info| AuxiliaryInfo::new(info, None)) + .collect(), parent_state, state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), @@ -104,6 +116,7 @@ impl TransactionChunk for ChunkToExecute { pub struct ChunkToApply { pub transactions: Vec, pub transaction_outputs: Vec, + pub persisted_aux_info: Vec, pub first_version: Version, } @@ -124,12 +137,17 @@ impl TransactionChunk for ChunkToApply { let Self { transactions, transaction_outputs, + persisted_aux_info, first_version: _, } = self; DoGetExecutionOutput::by_transaction_output( transactions, transaction_outputs, + persisted_aux_info + .into_iter() + .map(|info| AuxiliaryInfo::new(info, None)) + .collect(), parent_state, state_view, ) diff --git a/execution/executor/src/db_bootstrapper/mod.rs b/execution/executor/src/db_bootstrapper/mod.rs index 260d2399433..42ffbae763b 100644 --- a/execution/executor/src/db_bootstrapper/mod.rs +++ b/execution/executor/src/db_bootstrapper/mod.rs @@ -27,7 +27,7 @@ use aptos_types::{ on_chain_config::ConfigurationResource, state_store::{state_key::StateKey, StateViewId, TStateView}, timestamp::TimestampResource, - transaction::Transaction, + transaction::{AuxiliaryInfo, AuxiliaryInfoTrait, Transaction}, waypoint::Waypoint, }; use aptos_vm::VMBlockExecutor; @@ -137,6 +137,9 @@ pub fn calculate_genesis( let execution_output = DoGetExecutionOutput::by_transaction_execution::( &V::new(), vec![genesis_txn.clone().into()].into(), + // TODO(grao): Do we need any auxiliary info for hard fork? Not now, but maybe one day we + // will need it. + vec![AuxiliaryInfo::new_empty()], &ledger_summary.state, base_state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), diff --git a/execution/executor/src/fuzzing.rs b/execution/executor/src/fuzzing.rs index e820753c921..94897528c7d 100644 --- a/execution/executor/src/fuzzing.rs +++ b/execution/executor/src/fuzzing.rs @@ -20,7 +20,7 @@ use aptos_types::{ signature_verified_transaction::{ into_signature_verified_block, SignatureVerifiedTransaction, }, - BlockOutput, Transaction, TransactionOutput, Version, + AuxiliaryInfo, BlockOutput, Transaction, TransactionOutput, Version, }, vm_status::VMStatus, }; @@ -78,11 +78,11 @@ impl VMBlockExecutor for FakeVM { fn execute_block( &self, - _txn_provider: &DefaultTxnProvider, + _txn_provider: &DefaultTxnProvider, _state_view: &impl StateView, _onchain_config: BlockExecutorConfigFromOnchain, _transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { + ) -> Result, VMStatus> { Ok(BlockOutput::new(vec![], None)) } } diff --git a/execution/executor/src/metrics.rs b/execution/executor/src/metrics.rs index e1462f38c28..1feee7a0551 100644 --- a/execution/executor/src/metrics.rs +++ b/execution/executor/src/metrics.rs @@ -6,7 +6,7 @@ use aptos_logger::{prelude::*, sample, warn}; use aptos_metrics_core::{ exponential_buckets, register_histogram, register_histogram_vec, register_int_counter, register_int_counter_vec, register_int_gauge_vec, Histogram, HistogramVec, IntCounter, - IntCounterVec, IntGaugeVec, + IntCounterVec, IntGaugeVec, TimerHelper, }; use aptos_types::{ contract_event::ContractEvent, @@ -281,9 +281,7 @@ pub fn update_counters_for_processed_chunk( for (txn, output) in transactions.iter().zip(transaction_outputs.iter()) { if detailed_counters { if let Ok(size) = bcs::serialized_size(output) { - PROCESSED_TXNS_OUTPUT_SIZE - .with_label_values(&[process_type]) - .observe(size as f64); + PROCESSED_TXNS_OUTPUT_SIZE.observe_with(&[process_type], size as f64); } } @@ -420,7 +418,7 @@ pub fn update_counters_for_processed_chunk( .with_label_values(&[process_type, "NoAccountAuthenticator"]) .inc(); }, - AccountAuthenticator::Abstraction { .. } => { + AccountAuthenticator::Abstract { .. } => { PROCESSED_TXNS_AUTHENTICATOR .with_label_values(&[process_type, "AbstractionAuthenticator"]) .inc(); @@ -429,8 +427,7 @@ pub fn update_counters_for_processed_chunk( } PROCESSED_TXNS_NUM_AUTHENTICATORS - .with_label_values(&[process_type]) - .observe(signature_count as f64); + .observe_with(&[process_type], signature_count as f64); } let payload_type = if user_txn.payload().is_multisig() { diff --git a/execution/executor/src/tests/chunk_executor_tests.rs b/execution/executor/src/tests/chunk_executor_tests.rs index 854a3d7ff0f..ffaada38138 100644 --- a/execution/executor/src/tests/chunk_executor_tests.rs +++ b/execution/executor/src/tests/chunk_executor_tests.rs @@ -20,7 +20,7 @@ use aptos_storage_interface::DbReaderWriter; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, test_helpers::transaction_test_helpers::{block, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG}, - transaction::{TransactionListWithProof, Version}, + transaction::{TransactionListWithProofV2, Version}, }; use rand::Rng; @@ -49,7 +49,7 @@ impl TestExecutor { } fn execute_and_commit_chunks( - chunks: [TransactionListWithProof; 3], + chunks: [TransactionListWithProofV2; 3], ledger_info: LedgerInfoWithSignatures, db: &DbReaderWriter, executor: &ChunkExecutor, @@ -99,7 +99,7 @@ fn test_executor_execute_or_apply_and_commit_chunk() { third_batch_start..=third_batch_start + third_batch_size - 1, ]) }; - // First test with transactions only and reset chunks to be `Vec`. + // First test with transactions only and reset chunks to be `Vec`. let chunks = { let TestExecutor { _path, @@ -236,7 +236,7 @@ fn test_executor_execute_and_commit_chunk_local_result_mismatch() { let mut rng = rand::thread_rng(); let txns = (0..5) - .map(|_| encode_mint_transaction(tests::gen_address(rng.gen::()), 100)) + .map(|_| encode_mint_transaction(tests::gen_address(rng.r#gen::()), 100)) .collect::>(); let output = executor .execute_block( @@ -289,7 +289,7 @@ fn test_executor_execute_and_commit_chunk_without_verify() { let mut rng = rand::thread_rng(); let txns = (0..5) - .map(|_| encode_mint_transaction(tests::gen_address(rng.gen::()), 100)) + .map(|_| encode_mint_transaction(tests::gen_address(rng.r#gen::()), 100)) .collect::>(); let output = executor .execute_block( @@ -316,7 +316,7 @@ const PRE_COMMIT_TESTS_LATEST_VERSION: Version = 10; /// commits txn 1-3, pre-commits txn 4-7, returns txn 8-10 and ledger infos at 7 and 10 fn commit_1_pre_commit_2_return_3() -> ( DbReaderWriter, - TransactionListWithProof, + TransactionListWithProofV2, LedgerInfoWithSignatures, LedgerInfoWithSignatures, ) { @@ -333,11 +333,11 @@ fn commit_1_pre_commit_2_return_3() -> ( let block_executor = BlockExecutor::::new(db.clone()); let mut parent_block_id = block_executor.committed_block_id(); // execute and pre-commit block 1 & 2 - for (txns, ledger_info) in &blocks[0..=1] { + for (txns, aux_info, ledger_info) in &blocks[0..=1] { let block_id = ledger_info.commit_info().id(); let output = block_executor .execute_block( - (block_id, block(txns.clone())).into(), + (block_id, block(txns.clone()), aux_info.clone()).into(), parent_block_id, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG, ) @@ -350,9 +350,9 @@ fn commit_1_pre_commit_2_return_3() -> ( parent_block_id = block_id; } // commit till block 1 - let ledger_info1 = blocks[0].1.clone(); - let ledger_info2 = blocks[1].1.clone(); - let ledger_info3 = blocks[2].1.clone(); + let ledger_info1 = blocks[0].2.clone(); + let ledger_info2 = blocks[1].2.clone(); + let ledger_info3 = blocks[2].2.clone(); block_executor.commit_ledger(ledger_info1).unwrap(); assert_eq!( ledger_info3.ledger_info().version(), diff --git a/execution/executor/src/tests/mock_vm/mock_vm_test.rs b/execution/executor/src/tests/mock_vm/mock_vm_test.rs index 86a68f1254a..bda60fc1c88 100644 --- a/execution/executor/src/tests/mock_vm/mock_vm_test.rs +++ b/execution/executor/src/tests/mock_vm/mock_vm_test.rs @@ -26,7 +26,8 @@ fn test_mock_vm_different_senders() { txns.push(encode_mint_transaction(gen_address(i), amount)); } - let txn_provider = DefaultTxnProvider::new(into_signature_verified_block(txns.clone())); + let txn_provider = + DefaultTxnProvider::new_without_info(into_signature_verified_block(txns.clone())); let outputs = MockVM::new() .execute_block_no_limit(&txn_provider, &MockStateView::empty()) .expect("MockVM should not fail to start"); @@ -64,7 +65,7 @@ fn test_mock_vm_same_sender() { txns.push(encode_mint_transaction(sender, amount)); } - let txn_provider = DefaultTxnProvider::new(into_signature_verified_block(txns)); + let txn_provider = DefaultTxnProvider::new_without_info(into_signature_verified_block(txns)); let outputs = MockVM::new() .execute_block_no_limit(&txn_provider, &MockStateView::empty()) .expect("MockVM should not fail to start"); @@ -100,7 +101,7 @@ fn test_mock_vm_payment() { encode_transfer_transaction(gen_address(0), gen_address(1), 50), ]; - let txn_provider = DefaultTxnProvider::new(into_signature_verified_block(txns)); + let txn_provider = DefaultTxnProvider::new_without_info(into_signature_verified_block(txns)); let output = MockVM::new() .execute_block_no_limit(&txn_provider, &MockStateView::empty()) .expect("MockVM should not fail to start"); diff --git a/execution/executor/src/tests/mock_vm/mod.rs b/execution/executor/src/tests/mock_vm/mod.rs index 32729310754..a7fbfbc8ce1 100644 --- a/execution/executor/src/tests/mock_vm/mod.rs +++ b/execution/executor/src/tests/mock_vm/mod.rs @@ -22,10 +22,10 @@ use aptos_types::{ on_chain_config::{ConfigurationResource, ValidatorSet}, state_store::{state_key::StateKey, StateView}, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockEndInfo, BlockOutput, - ChangeSet, ExecutionStatus, RawTransaction, Script, SignedTransaction, Transaction, - TransactionArgument, TransactionAuxiliaryData, TransactionExecutableRef, TransactionOutput, - TransactionStatus, WriteSetPayload, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, BlockEndInfo, + BlockOutput, ChangeSet, ExecutionStatus, RawTransaction, Script, SignedTransaction, + Transaction, TransactionArgument, TransactionAuxiliaryData, TransactionExecutableRef, + TransactionOutput, TransactionStatus, WriteSetPayload, }, vm_status::{StatusCode, VMStatus}, write_set::{WriteOp, WriteSet, WriteSetMut}, @@ -68,11 +68,11 @@ impl VMBlockExecutor for MockVM { fn execute_block( &self, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &impl StateView, _onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { + ) -> Result, VMStatus> { // output_cache is used to store the output of transactions so they are visible to later // transactions. let mut output_cache = HashMap::new(); @@ -201,14 +201,18 @@ impl VMBlockExecutor for MockVM { let mut block_epilogue_txn = None; if !skip_rest { if let Some(block_id) = transaction_slice_metadata.append_state_checkpoint_to_block() { - block_epilogue_txn = Some(Transaction::block_epilogue( + block_epilogue_txn = Some(Transaction::block_epilogue_v0( block_id, BlockEndInfo::new_empty(), )); + outputs.push(TransactionOutput::new_empty_success()); } } - Ok(BlockOutput::new(outputs, block_epilogue_txn)) + Ok(BlockOutput::new( + outputs, + block_epilogue_txn.map(Into::into), + )) } fn execute_block_sharded>( diff --git a/execution/executor/src/tests/mod.rs b/execution/executor/src/tests/mod.rs index 7b718c997cc..39587ee02e1 100644 --- a/execution/executor/src/tests/mod.rs +++ b/execution/executor/src/tests/mod.rs @@ -19,10 +19,6 @@ use aptos_storage_interface::{ use aptos_types::{ account_address::AccountAddress, aggregate_signature::AggregateSignature, - block_executor::{ - config::BlockExecutorConfigFromOnchain, - transaction_slice_metadata::TransactionSliceMetadata, - }, block_info::BlockInfo, bytes::NumToBytes, chain_id::ChainId, @@ -30,14 +26,15 @@ use aptos_types::{ state_store::{state_key::StateKey, state_value::StateValue, StateViewId}, test_helpers::transaction_test_helpers::{block, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG}, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockEndInfo, - ExecutionStatus, RawTransaction, Script, SignedTransaction, Transaction, - TransactionAuxiliaryData, TransactionListWithProof, TransactionOutput, TransactionPayload, - TransactionStatus, Version, + signature_verified_transaction::{ + into_signature_verified_block, SignatureVerifiedTransaction, + }, + AuxiliaryInfo, ExecutionStatus, PersistedAuxiliaryInfo, RawTransaction, Script, + SignedTransaction, Transaction, TransactionAuxiliaryData, TransactionListWithProofV2, + TransactionOutput, TransactionPayload, TransactionStatus, Version, }, write_set::{WriteOp, WriteSet, WriteSetMut}, }; -use aptos_vm::VMBlockExecutor; use itertools::Itertools; use mock_vm::{ encode_mint_transaction, encode_reconfiguration_transaction, encode_transfer_transaction, @@ -339,8 +336,12 @@ fn create_blocks_and_chunks( block_ranges: Vec>, chunk_ranges: Vec>, ) -> ( - Vec<(Vec, LedgerInfoWithSignatures)>, - Vec, + Vec<( + Vec, + Vec, + LedgerInfoWithSignatures, + )>, + Vec, ) { assert_eq!(*block_ranges.first().unwrap().start(), 1); assert_eq!(*chunk_ranges.first().unwrap().start(), 1); @@ -385,9 +386,24 @@ fn create_blocks_and_chunks( .map(|v| encode_mint_transaction(gen_address(v), 10)) .collect(); let block_id = gen_block_id(version); + let aux_info: Vec<_> = (0..num_txns) + .map(|i| { + AuxiliaryInfo::new( + PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }, + None, + ) + }) + .collect(); let output = block_executor .execute_block( - (block_id, txns.clone()).into(), + ( + block_id, + into_signature_verified_block(txns.clone()), + aux_info.clone(), + ) + .into(), parent_block_id, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG, ) @@ -395,10 +411,10 @@ fn create_blocks_and_chunks( assert_eq!(output.expect_last_version(), version); block_executor.pre_commit_block(block_id).unwrap(); let ledger_info = gen_ledger_info(version, output.root_hash(), block_id, version); - out_blocks.push((txns, ledger_info)); + out_blocks.push((txns, aux_info, ledger_info)); parent_block_id = block_id; } - let ledger_info = out_blocks.last().unwrap().1.clone(); + let ledger_info = out_blocks.last().unwrap().2.clone(); let ledger_version = ledger_info.ledger_info().version(); block_executor.commit_ledger(ledger_info).unwrap(); @@ -421,13 +437,13 @@ fn create_blocks_and_chunks( fn create_transaction_chunks( chunks: Vec>, -) -> (Vec, LedgerInfoWithSignatures) { +) -> (Vec, LedgerInfoWithSignatures) { let num_txns = *chunks.last().unwrap().end(); // last txn is a block epilogue let all_txns = 1..=num_txns; let (mut blocks, chunks) = create_blocks_and_chunks(vec![all_txns], chunks); - (chunks, blocks.pop().unwrap().1) + (chunks, blocks.pop().unwrap().2) } fn create_test_transaction(sequence_number: u64) -> Transaction { @@ -460,7 +476,7 @@ fn apply_transaction_by_writeset( ) { let ledger_summary: LedgerSummary = db.reader.get_pre_committed_ledger_summary().unwrap(); - let (txns, txn_outs) = transactions_and_writesets + let (txns, txn_outs): (Vec<_>, Vec<_>) = transactions_and_writesets .iter() .map(|(txn, write_set)| { ( @@ -492,9 +508,22 @@ fn apply_transaction_by_writeset( ledger_summary.state.latest().clone(), ) .unwrap(); + let aux_info = txns + .iter() + .enumerate() + .map(|(i, _)| { + AuxiliaryInfo::new( + PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }, + None, + ) + }) + .collect(); let chunk_output = DoGetExecutionOutput::by_transaction_output( txns, txn_outs, + aux_info, &ledger_summary.state, state_view, ) @@ -676,48 +705,6 @@ impl TestBlock { } } -// Executes a list of transactions by executing and immediately committing one at a time. Returns -// the root hash after all transactions are committed. -fn run_transactions_naive( - transactions: Vec, - block_executor_onchain_config: BlockExecutorConfigFromOnchain, -) -> HashValue { - let executor = TestExecutor::new(); - let db = &executor.db; - - for txn in transactions { - let ledger_summary = db.reader.get_pre_committed_ledger_summary().unwrap(); - let state_view = CachedStateView::new( - StateViewId::Miscellaneous, - db.reader.clone(), - ledger_summary.state.latest().clone(), - ) - .unwrap(); - let out = DoGetExecutionOutput::by_transaction_execution( - &MockVM::new(), - vec![txn].into(), - &ledger_summary.state, - state_view, - block_executor_onchain_config.clone(), - TransactionSliceMetadata::unknown(), - ) - .unwrap(); - let output = ApplyExecutionOutput::run(out, ledger_summary, db.reader.as_ref()).unwrap(); - db.writer - .save_transactions( - output.expect_complete_result().as_chunk_to_commit(), - None, - true, /* sync_commit */ - ) - .unwrap(); - } - db.reader - .get_pre_committed_ledger_summary() - .unwrap() - .transaction_accumulator - .root_hash() -} - proptest! { #![proptest_config(ProptestConfig::with_cases(5))] @@ -785,12 +772,12 @@ proptest! { // get txn_infos from db let db = executor.db.reader.clone(); prop_assert_eq!(db.expect_synced_version(), ledger_version); - let txn_list = db.get_transactions( + let (txn_list, persisted_aux_info)= db.get_transactions( 1, /* start version */ ledger_version, /* version */ ledger_version, /* ledger version */ false /* fetch events */ - ).unwrap(); + ).unwrap().into_parts(); prop_assert_eq!(&block.inner_txns(), &txn_list.transactions[..num_input_txns]); let txn_infos = txn_list.proof.transaction_infos; let write_sets = db.get_write_set_iterator(1, ledger_version).unwrap().collect::>().unwrap(); @@ -801,6 +788,7 @@ proptest! { let replayer = chunk_executor_tests::TestExecutor::new(); let chunks_enqueued = replayer.executor.enqueue_chunks( txn_list.transactions, + persisted_aux_info, txn_infos, write_sets, event_vecs, @@ -842,6 +830,7 @@ proptest! { (block_a.id, block_a.txns.clone()).into(), parent_block_id, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG ).unwrap(); root_hash = output_a.root_hash(); + // Add one transaction for the state checkpoint. let ledger_info = gen_ledger_info(block_a.txns.len() as u64 + 1, root_hash, block_a.id, 1); executor.commit_blocks(vec![block_a.id], ledger_info).unwrap(); @@ -854,6 +843,7 @@ proptest! { let executor = BlockExecutor::::new(db); let output_b = executor.execute_block((block_b.id, block_b.txns.clone()).into(), parent_block_id, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG).unwrap(); root_hash = output_b.root_hash(); + let ledger_info = gen_ledger_info( // add two transactions for the state checkpoints (block_a.txns.len() + block_b.txns.len() + 2) as u64, @@ -864,14 +854,40 @@ proptest! { executor.commit_blocks(vec![block_b.id], ledger_info).unwrap(); }; - let expected_root_hash = run_transactions_naive({ - let mut txns = vec![]; - txns.extend(block_a.txns.iter().cloned()); - txns.push(SignatureVerifiedTransaction::Valid(Transaction::block_epilogue(block_a.id, BlockEndInfo::new_empty()))); - txns.extend(block_b.txns.iter().cloned()); - txns.push(SignatureVerifiedTransaction::Valid(Transaction::block_epilogue(block_b.id, BlockEndInfo::new_empty()))); - txns - }, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG); + // Execute blocks separately using BlockExecutor to match the real execution pattern + let expected_root_hash = { + let executor_naive = TestExecutor::new(); + let db_naive = &executor_naive.db; + + // Execute block A using BlockExecutor + let parent_block_id_a = executor_naive.committed_block_id(); + let output_a_naive = executor_naive.execute_block( + (block_a.id, block_a.txns.clone()).into(), + parent_block_id_a, + TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG + ).unwrap(); + let root_hash_a = output_a_naive.root_hash(); + let ledger_info_a = gen_ledger_info(block_a.txns.len() as u64 + 1, root_hash_a, block_a.id, 1); + executor_naive.commit_blocks(vec![block_a.id], ledger_info_a).unwrap(); + + // Create new executor for block B (simulating restart) + let executor_b_naive = BlockExecutor::::new(db_naive.clone()); + let output_b_naive = executor_b_naive.execute_block( + (block_b.id, block_b.txns.clone()).into(), + block_a.id, + TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG + ).unwrap(); + let root_hash_b = output_b_naive.root_hash(); + let ledger_info_b = gen_ledger_info( + (block_a.txns.len() + block_b.txns.len() + 2) as u64, + root_hash_b, + block_b.id, + 2 + ); + executor_b_naive.commit_blocks(vec![block_b.id], ledger_info_b).unwrap(); + + root_hash_b + }; prop_assert_eq!(root_hash, expected_root_hash); } diff --git a/execution/executor/src/workflow/do_get_execution_output.rs b/execution/executor/src/workflow/do_get_execution_output.rs index 7a9a26770f7..c900edd83a6 100644 --- a/execution/executor/src/workflow/do_get_execution_output.rs +++ b/execution/executor/src/workflow/do_get_execution_output.rs @@ -24,7 +24,8 @@ use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::*; use aptos_metrics_core::TimerHelper; use aptos_storage_interface::state_store::{ - state::LedgerState, state_view::cached_state_view::CachedStateView, + state::LedgerState, + state_view::cached_state_view::{CachedStateView, PrimingPolicy}, }; #[cfg(feature = "consensus-only-perf-test")] use aptos_types::transaction::ExecutionStatus; @@ -42,10 +43,11 @@ use aptos_types::{ TStateView, }, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, Transaction, - TransactionOutput, TransactionStatus, Version, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, + AuxiliaryInfoTrait, BlockOutput, PersistedAuxiliaryInfo, Transaction, TransactionOutput, + TransactionStatus, Version, }, - write_set::{TransactionWrite, WriteSet}, + write_set::{HotStateOp, TransactionWrite, WriteSet}, }; use aptos_vm::VMBlockExecutor; use itertools::Itertools; @@ -57,6 +59,7 @@ impl DoGetExecutionOutput { pub fn by_transaction_execution( executor: &V, transactions: ExecutableTransactions, + auxiliary_infos: Vec, parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, @@ -67,14 +70,17 @@ impl DoGetExecutionOutput { Self::by_transaction_execution_unsharded::( executor, txns, + auxiliary_infos, parent_state, state_view, onchain_config, transaction_slice_metadata, )? }, + // TODO: Execution with auxiliary info is yet to be supported properly here for sharded transactions ExecutableTransactions::Sharded(txns) => Self::by_transaction_execution_sharded::( txns, + auxiliary_infos, parent_state, state_view, onchain_config, @@ -100,12 +106,13 @@ impl DoGetExecutionOutput { fn by_transaction_execution_unsharded( executor: &V, transactions: Vec, + auxiliary_infos: Vec, parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, ) -> Result { - let txn_provider = DefaultTxnProvider::new(transactions); + let txn_provider = DefaultTxnProvider::new(transactions, auxiliary_infos.clone()); let block_output = Self::execute_block::( executor, &txn_provider, @@ -114,29 +121,61 @@ impl DoGetExecutionOutput { transaction_slice_metadata, )?; let (mut transaction_outputs, block_epilogue_txn) = block_output.into_inner(); - let mut transactions: Vec<_> = txn_provider - .txns + let (transactions, mut auxiliary_infos) = txn_provider.into_inner(); + let mut transactions = transactions .into_iter() .map(|t| t.into_inner()) - .collect(); + .collect_vec(); if let Some(block_epilogue_txn) = block_epilogue_txn { - transactions.push(block_epilogue_txn); - // TODO(HotState): there are three possible paths where the block epilogue - // output is passed to the DB: - // 1. a block from consensus is executed: the VM outputs the block end info - // and the block epilogue transaction and output are generated here. - // 2. a chunk re-executed: The VM will see the block epilogue transaction and - // should output the transaction output by looking at the block end info - // embedded in the epilogue transaction (and maybe the state view). - // 3. a chunk replayed by transaction output: we get the transaction output - // directly. - transaction_outputs.push(TransactionOutput::new_empty_success()); + transactions.push(block_epilogue_txn.into_inner()); + + // Check if all existing auxiliary infos are None to maintain consistency + let all_auxiliary_infos_are_none = auxiliary_infos + .iter() + .all(|info| matches!(info.persisted_info(), PersistedAuxiliaryInfo::None)); + + let block_epilogue_aux_info = if all_auxiliary_infos_are_none { + // If all other auxiliary infos are None, use None for consistency (version 0 behavior) + AuxiliaryInfo::new(PersistedAuxiliaryInfo::None, None) + } else { + // Otherwise, use the standard function (version 1 behavior) + AuxiliaryInfo::auxiliary_info_at_txn_index(transactions.len() as u32 - 1) + }; + + auxiliary_infos.push(block_epilogue_aux_info); + } + + // Manually create hotness write sets for block epilogue transaction(s), based on the block + // end info saved. Note that even if we are re-executing transactions during a state sync, + // the block end info is not re-computed and has to come from the previous execution. + // + // If the input transactions are from a normal block, the last one should be the epilogue. + // If they are from a chunk (i.e. we are re-executing transactions during state sync), then + // there could be zero or more block epilogue transactions, and we need to handle all of + // them. + // + // TODO(HotState): it might be better to do this in AptosVM::execute_single_transaction, + // but we need to figure out how to properly construct `VMOutput` from block end info. + for (transaction, output) in transactions.iter().zip_eq(transaction_outputs.iter_mut()) { + if let Transaction::BlockEpilogue(payload) = transaction { + assert!(output.status().is_kept(), "Block epilogue must be kept"); + output.add_hotness( + payload + .try_get_keys_to_make_hot() + .cloned() + .unwrap_or_default() + .into_iter() + .map(|key| (key, HotStateOp::make_hot())) + .collect(), + ); + } } Parser::parse( state_view.next_version(), transactions, transaction_outputs, + auxiliary_infos, parent_state, state_view, false, // prime_state_cache @@ -148,6 +187,7 @@ impl DoGetExecutionOutput { pub fn by_transaction_execution_sharded( transactions: PartitionedTransactions, + auxiliary_infos: Vec, parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, @@ -160,6 +200,8 @@ impl DoGetExecutionOutput { onchain_config, )?; + // TODO(Manu): Handle state checkpoint here. + // TODO(skedia) add logic to emit counters per shard instead of doing it globally. // Unwrapping here is safe because the execution has finished and it is guaranteed that @@ -172,6 +214,7 @@ impl DoGetExecutionOutput { .map(|t| t.into_txn().into_inner()) .collect(), transaction_outputs, + auxiliary_infos, parent_state, state_view, false, // prime_state_cache @@ -182,6 +225,7 @@ impl DoGetExecutionOutput { pub fn by_transaction_output( transactions: Vec, transaction_outputs: Vec, + auxiliary_infos: Vec, parent_state: &LedgerState, state_view: CachedStateView, ) -> Result { @@ -189,6 +233,7 @@ impl DoGetExecutionOutput { state_view.next_version(), transactions, transaction_outputs, + auxiliary_infos, parent_state, state_view, true, // prime state cache @@ -235,11 +280,11 @@ impl DoGetExecutionOutput { #[cfg(not(feature = "consensus-only-perf-test"))] fn execute_block( executor: &V, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result> { + ) -> Result> { let _timer = OTHER_TIMERS.timer_with(&["vm_execute_block"]); Ok(executor.execute_block( txn_provider, @@ -301,6 +346,7 @@ impl Parser { first_version: Version, mut transactions: Vec, mut transaction_outputs: Vec, + auxiliary_infos: Vec, parent_state: &LedgerState, base_state_view: CachedStateView, prime_state_cache: bool, @@ -318,35 +364,61 @@ impl Parser { .collect_vec() }; + let mut persisted_auxiliary_infos = auxiliary_infos + .into_iter() + .map(|info| info.into_persisted_info()) + .collect(); + // Isolate retries and discards. - let (to_retry, to_discard, has_reconfig) = - Self::extract_retries_and_discards(&mut transactions, &mut transaction_outputs); + let (to_retry, to_discard) = Self::extract_retries_and_discards( + &mut transactions, + &mut transaction_outputs, + &mut persisted_auxiliary_infos, + ); let mut block_end_info = None; - if is_block && !has_reconfig { + if is_block { if let Some(Transaction::BlockEpilogue(payload)) = transactions.last() { block_end_info = payload.try_as_block_end_info().cloned(); ensure!(statuses_for_input_txns.pop().is_some()); } } + // The rest is to be committed, attach block epilogue as needed and optionally get next EpochState. let to_commit = { let _timer = OTHER_TIMERS.timer_with(&["parse_raw_output__to_commit"]); - let to_commit = TransactionsWithOutput::new(transactions, transaction_outputs); - TransactionsToKeep::index(first_version, to_commit, has_reconfig) + let to_commit = TransactionsWithOutput::new( + transactions, + transaction_outputs, + persisted_auxiliary_infos, + ); + TransactionsToKeep::index(first_version, to_commit, is_block) }; let next_epoch_state = { let _timer = OTHER_TIMERS.timer_with(&["parse_raw_output__next_epoch_state"]); - has_reconfig + to_commit + .is_reconfig() .then(|| Self::ensure_next_epoch_state(&to_commit)) .transpose()? }; - if prime_state_cache { - base_state_view.prime_cache(to_commit.state_update_refs())?; - } + base_state_view.prime_cache( + to_commit.state_update_refs(), + if prime_state_cache { + PrimingPolicy::All + } else { + // Most of the transaction reads should already be in the cache, but some module + // reads in the transactions might be done via the global module cache instead of + // cached state view, so they are not present in the cache. + // Therfore, we must prime the cache for the keys that we are going to promote into + // hot state, regardless of `prime_state_cache`, because the write sets have only + // the keys, not the values. + PrimingPolicy::MakeHotOnly + }, + )?; let result_state = parent_state.update_with_memorized_reads( + base_state_view.persisted_hot_state(), base_state_view.persisted_state(), to_commit.state_update_refs(), base_state_view.memorized_reads(), @@ -387,18 +459,10 @@ impl Parser { fn extract_retries_and_discards( transactions: &mut Vec, transaction_outputs: &mut Vec, - ) -> (TransactionsWithOutput, TransactionsWithOutput, bool) { + persisted_auxiliary_infos: &mut Vec, + ) -> (TransactionsWithOutput, TransactionsWithOutput) { let _timer = OTHER_TIMERS.timer_with(&["parse_raw_output__retries_and_discards"]); - let last_non_retry = transaction_outputs - .iter() - .rposition(|t| !t.status().is_retry()); - let is_reconfig = if let Some(idx) = last_non_retry { - transaction_outputs[idx].has_new_epoch_event() - } else { - false - }; - let mut to_discard = TransactionsWithOutput::new_empty(); let mut to_retry = TransactionsWithOutput::new_empty(); @@ -410,23 +474,29 @@ impl Parser { if num_keep_txns != idx { transactions[num_keep_txns] = transactions[idx].clone(); transaction_outputs[num_keep_txns] = transaction_outputs[idx].clone(); + persisted_auxiliary_infos[num_keep_txns] = persisted_auxiliary_infos[idx]; } num_keep_txns += 1; }, - TransactionStatus::Retry => { - to_retry.push(transactions[idx].clone(), transaction_outputs[idx].clone()) - }, - TransactionStatus::Discard(_) => { - to_discard.push(transactions[idx].clone(), transaction_outputs[idx].clone()) - }, + TransactionStatus::Retry => to_retry.push( + transactions[idx].clone(), + transaction_outputs[idx].clone(), + persisted_auxiliary_infos[idx], + ), + TransactionStatus::Discard(_) => to_discard.push( + transactions[idx].clone(), + transaction_outputs[idx].clone(), + persisted_auxiliary_infos[idx], + ), } } transactions.truncate(num_keep_txns); transaction_outputs.truncate(num_keep_txns); + persisted_auxiliary_infos.truncate(num_keep_txns); // Sanity check transactions with the Discard status: - to_discard.iter().for_each(|(t, o)| { + to_discard.iter().for_each(|(t, o, _)| { // In case a new status other than Retry, Keep and Discard is added: if !matches!(o.status(), TransactionStatus::Discard(_)) { error!("Status other than Retry, Keep or Discard; Transaction discarded."); @@ -443,7 +513,7 @@ impl Parser { } }); - (to_retry, to_discard, is_reconfig) + (to_retry, to_discard) } fn ensure_next_epoch_state(to_commit: &TransactionsWithOutput) -> Result { @@ -490,6 +560,7 @@ impl TStateView for WriteSetStateView<'_> { unreachable!("Not supposed to be called on WriteSetStateView.") } } + #[cfg(test)] mod tests { use super::Parser; @@ -498,9 +569,10 @@ mod tests { }; use aptos_types::{ contract_event::ContractEvent, + state_store::hot_state::HotStateConfig, transaction::{ - ExecutionStatus, Transaction, TransactionAuxiliaryData, TransactionOutput, - TransactionStatus, + AuxiliaryInfo, ExecutionStatus, PersistedAuxiliaryInfo, Transaction, + TransactionAuxiliaryData, TransactionOutput, TransactionStatus, }, vm_status::StatusCode, write_set::WriteSet, @@ -534,11 +606,26 @@ mod tests { TransactionAuxiliaryData::default(), ), ]; - let state = LedgerState::new_empty(); + let auxiliary_infos = vec![ + AuxiliaryInfo::new( + PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }, + None, + ), + AuxiliaryInfo::new( + PersistedAuxiliaryInfo::V1 { + transaction_index: 1, + }, + None, + ), + ]; + let state = LedgerState::new_empty(HotStateConfig::default()); let execution_output = Parser::parse( 0, txns, txn_outs, + auxiliary_infos, &state, CachedStateView::new_dummy(&state), false, @@ -589,21 +676,43 @@ mod tests { TransactionAuxiliaryData::default(), ), ]; - let (to_retry, to_discard, is_reconfig) = - Parser::extract_retries_and_discards(&mut txns, &mut txn_outs); - assert!(!is_reconfig); + let mut auxiliary_infos = vec![ + PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }, + PersistedAuxiliaryInfo::V1 { + transaction_index: 1, + }, + PersistedAuxiliaryInfo::V1 { + transaction_index: 2, + }, + PersistedAuxiliaryInfo::V1 { + transaction_index: 3, + }, + ]; + let (to_retry, to_discard) = + Parser::extract_retries_and_discards(&mut txns, &mut txn_outs, &mut auxiliary_infos); assert_eq!(to_retry.len(), 1); assert_eq!(to_discard.len(), 1); assert_eq!(txns.len(), 2); assert_eq!(txn_outs.len(), 2); + assert_eq!(auxiliary_infos.len(), 2); + assert_eq!( + PersistedAuxiliaryInfo::V1 { + transaction_index: 0 + }, + auxiliary_infos[0] + ); + assert_eq!( + PersistedAuxiliaryInfo::V1 { + transaction_index: 3 + }, + auxiliary_infos[1] + ); } #[test] fn test_extract_retry_and_discard_reconfig() { - let reconfig_event = ContractEvent::new_v2_with_type_tag_str( - "0x1::reconfiguration::NewEpochEvent", - b"".to_vec(), - ); let mut txns = vec![ Transaction::dummy(), Transaction::dummy(), @@ -612,7 +721,7 @@ mod tests { let mut txn_outs = vec![ TransactionOutput::new( WriteSet::default(), - vec![reconfig_event], + vec![], 0, TransactionStatus::Keep(ExecutionStatus::Success), TransactionAuxiliaryData::default(), @@ -632,12 +741,23 @@ mod tests { TransactionAuxiliaryData::default(), ), ]; - let (to_retry, to_discard, is_reconfig) = - Parser::extract_retries_and_discards(&mut txns, &mut txn_outs); - assert!(is_reconfig); + let mut auxiliary_infos = vec![ + PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }, + PersistedAuxiliaryInfo::V1 { + transaction_index: 1, + }, + PersistedAuxiliaryInfo::V1 { + transaction_index: 2, + }, + ]; + let (to_retry, to_discard) = + Parser::extract_retries_and_discards(&mut txns, &mut txn_outs, &mut auxiliary_infos); assert_eq!(to_retry.len(), 2); assert_eq!(to_discard.len(), 0); assert_eq!(txns.len(), 1); assert_eq!(txn_outs.len(), 1); + assert_eq!(auxiliary_infos.len(), 1); } } diff --git a/execution/executor/src/workflow/do_ledger_update.rs b/execution/executor/src/workflow/do_ledger_update.rs index f4b7b0247c8..8733949ea4d 100644 --- a/execution/executor/src/workflow/do_ledger_update.rs +++ b/execution/executor/src/workflow/do_ledger_update.rs @@ -12,9 +12,8 @@ use aptos_experimental_runtimes::thread_manager::optimal_min_len; use aptos_metrics_core::TimerHelper; use aptos_types::{ proof::accumulator::{InMemoryEventAccumulator, InMemoryTransactionAccumulator}, - transaction::{TransactionInfo, TransactionOutput}, + transaction::{PersistedAuxiliaryInfo, TransactionInfo}, }; -use itertools::{izip, Itertools}; use rayon::prelude::*; use std::sync::Arc; @@ -28,21 +27,13 @@ impl DoLedgerUpdate { ) -> Result { let _timer = OTHER_TIMERS.timer_with(&["do_ledger_update"]); - // Calculate hashes - let txn_outs = &execution_output.to_commit.transaction_outputs; - - let (event_hashes, writeset_hashes) = Self::calculate_events_and_writeset_hashes(txn_outs); - // Assemble `TransactionInfo`s - let transaction_infos = Self::assemble_transaction_infos( + let (transaction_infos, transaction_info_hashes) = Self::assemble_transaction_infos( &execution_output.to_commit, state_checkpoint_output.state_checkpoint_hashes.clone(), - event_hashes, - writeset_hashes, ); // Calculate root hash - let transaction_info_hashes = transaction_infos.iter().map(CryptoHash::hash).collect_vec(); let transaction_accumulator = Arc::new(parent_accumulator.append(&transaction_info_hashes)); Ok(LedgerUpdateOutput::new( @@ -53,56 +44,50 @@ impl DoLedgerUpdate { )) } - fn calculate_events_and_writeset_hashes( - to_commit: &[TransactionOutput], - ) -> (Vec, Vec) { - let _timer = OTHER_TIMERS.timer_with(&["calculate_events_and_writeset_hashes"]); + fn assemble_transaction_infos( + to_commit: &TransactionsWithOutput, + state_checkpoint_hashes: Vec>, + ) -> (Vec, Vec) { + let _timer = OTHER_TIMERS.timer_with(&["assemble_transaction_infos"]); - let num_txns = to_commit.len(); - to_commit - .par_iter() - .with_min_len(optimal_min_len(num_txns, 64)) - .map(|txn_output| { + (0..to_commit.len()) + .into_par_iter() + .with_min_len(optimal_min_len(to_commit.len(), 64)) + .map(|i| { + let txn = &to_commit.transactions[i]; + let txn_output = &to_commit.transaction_outputs[i]; + let persisted_auxiliary_info = &to_commit.persisted_auxiliary_infos[i]; + // Use the auxiliary info hash directly from the persisted info + let auxiliary_info_hash = match persisted_auxiliary_info { + PersistedAuxiliaryInfo::None => None, + PersistedAuxiliaryInfo::V1 { .. } => { + Some(CryptoHash::hash(persisted_auxiliary_info)) + }, + }; + let state_checkpoint_hash = state_checkpoint_hashes[i]; let event_hashes = txn_output .events() .iter() .map(CryptoHash::hash) .collect::>(); - - ( - InMemoryEventAccumulator::from_leaves(&event_hashes).root_hash(), - CryptoHash::hash(txn_output.write_set()), - ) - }) - .unzip() - } - - fn assemble_transaction_infos( - to_commit: &TransactionsWithOutput, - state_checkpoint_hashes: Vec>, - event_hashes: Vec, - writeset_hashes: Vec, - ) -> Vec { - let _timer = OTHER_TIMERS.timer_with(&["assemble_transaction_infos"]); - - izip!( - to_commit.iter(), - state_checkpoint_hashes, - event_hashes, - writeset_hashes - ) - .map( - |((txn, txn_out), state_checkpoint_hash, event_root_hash, write_set_hash)| { - TransactionInfo::new( + let event_root_hash = + InMemoryEventAccumulator::from_leaves(&event_hashes).root_hash(); + let write_set_hash = CryptoHash::hash(txn_output.write_set()); + let txn_info = TransactionInfo::new( txn.hash(), write_set_hash, event_root_hash, state_checkpoint_hash, - txn_out.gas_used(), - txn_out.status().as_kept_status().expect("Already sorted."), - ) - }, - ) - .collect() + txn_output.gas_used(), + txn_output + .status() + .as_kept_status() + .expect("Already sorted."), + auxiliary_info_hash, + ); + let txn_info_hash = txn_info.hash(); + (txn_info, txn_info_hash) + }) + .unzip() } } diff --git a/execution/executor/tests/db_bootstrapper_test.rs b/execution/executor/tests/db_bootstrapper_test.rs index 829399dbdb7..0c6510ce47d 100644 --- a/execution/executor/tests/db_bootstrapper_test.rs +++ b/execution/executor/tests/db_bootstrapper_test.rs @@ -95,7 +95,7 @@ fn execute_and_commit(txns: Vec, db: &DbReaderWriter, signer: &Vali .unwrap(); assert_eq!(output.next_version(), target_version + 1); let ledger_info_with_sigs = - gen_ledger_info_with_sigs(epoch, &output, block_id, &[signer.clone()]); + gen_ledger_info_with_sigs(epoch, &output, block_id, std::slice::from_ref(signer)); executor .commit_blocks(vec![block_id], ledger_info_with_sigs) .unwrap(); diff --git a/execution/executor/tests/internal_indexer_test.rs b/execution/executor/tests/internal_indexer_test.rs index 1a11a6e2b9d..ea3013e1c26 100644 --- a/execution/executor/tests/internal_indexer_test.rs +++ b/execution/executor/tests/internal_indexer_test.rs @@ -127,7 +127,7 @@ pub fn create_test_db() -> (Arc, LocalAccount) { TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG, ) .unwrap(); - let li1 = gen_ledger_info_with_sigs(1, &output1, block1_id, &[signer.clone()]); + let li1 = gen_ledger_info_with_sigs(1, &output1, block1_id, std::slice::from_ref(&signer)); executor.commit_blocks(vec![block1_id], li1).unwrap(); (aptos_db, core_resources_account) } @@ -316,6 +316,7 @@ fn test_db_indexer_data() { ident_str!("ristretto255_elgamal"), ident_str!("reconfiguration_state"), ident_str!("ristretto255_pedersen"), + ident_str!("sui_derivable_account"), ident_str!("object_code_deployment"), ident_str!("primary_fungible_store"), ident_str!("transaction_validation"), @@ -361,6 +362,7 @@ fn test_db_indexer_data() { (false, "0x1::gas_schedule::GasScheduleV2"), (false, "0x1::jwks::SupportedOIDCProviders"), (false, "0x1::stake::AptosCoinCapabilities"), + (false, "0x1::stake::PendingTransactionFee"), (false, "0x1::reconfiguration_state::State"), (false, "0x1::version::SetVersionCapability"), (false, "0x1::storage_gas::StorageGasConfig"), diff --git a/experimental/execution/ptx-executor/src/lib.rs b/experimental/execution/ptx-executor/src/lib.rs index 3f6bbd5bea8..667ca3ef3b1 100644 --- a/experimental/execution/ptx-executor/src/lib.rs +++ b/experimental/execution/ptx-executor/src/lib.rs @@ -32,7 +32,7 @@ use aptos_types::{ }, state_store::StateView, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, BlockOutput, TransactionOutput, }, }; @@ -52,11 +52,11 @@ impl VMBlockExecutor for PtxBlockExecutor { fn execute_block( &self, - txn_provider: &DefaultTxnProvider, + txn_provider: &DefaultTxnProvider, state_view: &(impl StateView + Sync), _onchain_config: BlockExecutorConfigFromOnchain, _transaction_slice_metadata: TransactionSliceMetadata, - ) -> Result, VMStatus> { + ) -> Result, VMStatus> { let _timer = TIMER.timer_with(&["block_total"]); let concurrency_level = AptosVM::get_concurrency_level(); diff --git a/experimental/execution/ptx-executor/src/runner.rs b/experimental/execution/ptx-executor/src/runner.rs index 9ccfadeae9b..478e6e5e0e0 100644 --- a/experimental/execution/ptx-executor/src/runner.rs +++ b/experimental/execution/ptx-executor/src/runner.rs @@ -16,7 +16,7 @@ use aptos_logger::trace; use aptos_metrics_core::TimerHelper; use aptos_types::{ state_store::{state_key::StateKey, state_value::StateValue, StateView}, - transaction::signature_verified_transaction::SignatureVerifiedTransaction, + transaction::{signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo}, write_set::TransactionWrite, }; use aptos_vm::AptosVM; @@ -271,6 +271,7 @@ impl<'scope, 'view: 'scope, BaseView: StateView + Sync> Worker<'view, BaseView> &vm.as_move_resolver(&state_view), &code_storage, &log_context, + &AuxiliaryInfo::default(), ) }; let _post = PER_WORKER_TIMER.timer_with(&[&idx, "run_txn_post_vm"]); diff --git a/experimental/storage/hexy/Cargo.toml b/experimental/storage/hexy/Cargo.toml index 8e213d9f76d..7d17e1bed6c 100644 --- a/experimental/storage/hexy/Cargo.toml +++ b/experimental/storage/hexy/Cargo.toml @@ -28,10 +28,7 @@ proptest = { workspace = true } rand = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [[bench]] name = "sort_dedup" diff --git a/experimental/storage/hexy/src/in_mem/base.rs b/experimental/storage/hexy/src/in_mem/base.rs index c4a1de1a722..af8be79363d 100644 --- a/experimental/storage/hexy/src/in_mem/base.rs +++ b/experimental/storage/hexy/src/in_mem/base.rs @@ -53,14 +53,14 @@ where // Another thread is possibly modifying the cell, explicit synchronization is needed through, // e.g. atomic::fence pub unsafe fn unsafe_expect(&self, index: usize) -> &T { - &*self.expect_raw(index) + unsafe { &*self.expect_raw(index) } } // The caller must guarantee the cell pointed by the index is not accessed while // it's mutated. #[allow(clippy::mut_from_ref)] pub unsafe fn unsafe_expect_mut(&self, index: usize) -> &mut T { - &mut *self.expect_raw(index) + unsafe { &mut *self.expect_raw(index) } } } @@ -114,7 +114,7 @@ impl HexyBase { let level = self.expect_level(position); if position.index_in_level < level.len() as u32 { - Ok(*level.unsafe_expect(position.index_in_level as usize)) + Ok(unsafe { *level.unsafe_expect(position.index_in_level as usize) }) } else { let parent_position = position.parent(); ensure!( @@ -136,6 +136,7 @@ impl HexyBase { } } + #[allow(clippy::mut_from_ref)] unsafe fn unsafe_get_hash_mut(&self, position: NodePosition) -> Result<&mut HashValue> { let num_leaves = self.num_leaves(); ensure!( @@ -152,7 +153,7 @@ impl HexyBase { position, ); - Ok(level.unsafe_expect_mut(position.index_in_level as usize)) + Ok(unsafe { level.unsafe_expect_mut(position.index_in_level as usize) }) } fn expect_level(&self, position: NodePosition) -> &BigVector { @@ -160,7 +161,7 @@ impl HexyBase { } pub(crate) unsafe fn unsafe_expect_hash(&self, position: NodePosition) -> HashValue { - self.unsafe_get_hash(position).expect("Failed to get hash.") + unsafe { self.unsafe_get_hash(position).expect("Failed to get hash.") } } pub fn root_position(&self) -> NodePosition { diff --git a/experimental/storage/hexy/src/in_mem/view.rs b/experimental/storage/hexy/src/in_mem/view.rs index 18942212ffc..3dd9d7c6b8a 100644 --- a/experimental/storage/hexy/src/in_mem/view.rs +++ b/experimental/storage/hexy/src/in_mem/view.rs @@ -67,7 +67,11 @@ impl HexyView { for (updated_child_position, updated_child_hash) in updated_children.into_iter() { let updated_child = updated_child_position.index_in_siblings(); for child in next_child..updated_child { - hasher.add_child(&self.unsafe_expect_hash(parent_position.child(child)))?; + unsafe { + hasher.add_child( + &self.unsafe_expect_hash(parent_position.child(child)), + )?; + } } // n.b. There's the rule of "16 placeholders hash to the placeholder", and // it seems a waste to detect that. @@ -76,7 +80,9 @@ impl HexyView { next_child = updated_child + 1; } for child in next_child..ARITY { - hasher.add_child(&self.unsafe_expect_hash(parent_position.child(child)))?; + unsafe { + hasher.add_child(&self.unsafe_expect_hash(parent_position.child(child)))?; + } } this_level_updates.push((parent_position, hasher.finish()?)) } // end for children per parent @@ -134,7 +140,7 @@ impl HexyView { unsafe fn unsafe_expect_hash(&self, position: NodePosition) -> HashValue { match self.overlay.get(&position) { Some(hash) => hash, - None => self.base.unsafe_expect_hash(position), + None => unsafe { self.base.unsafe_expect_hash(position) }, } } } diff --git a/experimental/storage/layered-map/Cargo.toml b/experimental/storage/layered-map/Cargo.toml index dc60a7da9fb..98fc4bd1d45 100644 --- a/experimental/storage/layered-map/Cargo.toml +++ b/experimental/storage/layered-map/Cargo.toml @@ -32,11 +32,8 @@ proptest = { workspace = true } rand = { workspace = true } rocksdb = { workspace = true } -[target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +[target.'cfg(unix)'.dev-dependencies] +jemallocator = { workspace = true } [lib] bench = false diff --git a/experimental/storage/layered-map/src/flatten_perfect_tree.rs b/experimental/storage/layered-map/src/flatten_perfect_tree.rs index 49bba86f57a..02a5fbc0437 100644 --- a/experimental/storage/layered-map/src/flatten_perfect_tree.rs +++ b/experimental/storage/layered-map/src/flatten_perfect_tree.rs @@ -23,13 +23,13 @@ impl FlattenPerfectTree { } } - pub fn get_ref(&self) -> FptRef { + pub fn get_ref(&self) -> FptRef<'_, K, V> { FptRef { leaves: &self.leaves, } } - pub fn get_mut(&mut self) -> FptRefMut { + pub fn get_mut(&mut self) -> FptRefMut<'_, K, V> { FptRefMut { leaves: &mut self.leaves, } diff --git a/experimental/storage/layered-map/src/layer.rs b/experimental/storage/layered-map/src/layer.rs index b41b7ae049a..2262b23ff19 100644 --- a/experimental/storage/layered-map/src/layer.rs +++ b/experimental/storage/layered-map/src/layer.rs @@ -10,7 +10,7 @@ use crate::{ use aptos_crypto::HashValue; use aptos_drop_helper::ArcAsyncDrop; use aptos_infallible::Mutex; -use aptos_metrics_core::IntGaugeHelper; +use aptos_metrics_core::IntGaugeVecHelper; use std::{marker::PhantomData, sync::Arc}; #[derive(Debug)] @@ -151,7 +151,7 @@ impl MapLayer { Self::new(self.inner.spawn(child_peak, base_layer)) } - pub(crate) fn peak(&self) -> FptRef { + pub(crate) fn peak(&self) -> FptRef<'_, K, V> { self.inner.peak.get_ref() } } diff --git a/flake.lock b/flake.lock index 7243e698a30..92547e71042 100644 --- a/flake.lock +++ b/flake.lock @@ -62,11 +62,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1755916474, - "narHash": "sha256-r0WnHKwA8DQNSHDmN3LNaqu41GbWDYqLS7IQAGR+6Wg=", + "lastModified": 1788419040, + "narHash": "sha256-Itdv4WV5z+U0VpseZ/f4uvYmULVPxsV3Hc2l9HrCyY4=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "897ecf2b25be05e6ccb7661703f9f2fdec155f42", + "rev": "1af4dd0db58d4adde06f0840ce28da90f9c66c50", "type": "github" }, "original": { diff --git a/keyless/pepper/README.md b/keyless/pepper/README.md new file mode 100644 index 00000000000..6b48b0a1944 --- /dev/null +++ b/keyless/pepper/README.md @@ -0,0 +1,115 @@ +# Pepper Service Developer Guide + +## Overview + +This directory contains the **Pepper Service**, and a Rust-based **Pepper Client** example. + +Note: if you are a frontend developer, you can use the Pepper Client example as a reference to +understand how to interact with the Pepper Service API. + +## Local Development +The simplest way to run the Pepper Service and Pepper Client locally are to use the example scripts +in this repository. Follow the steps below to get started. + +### Start the Pepper Service + +First, start the Pepper Service using the commands below: + +```bash +cd keyless/pepper/scripts +./start-pepper-service.sh +``` + +This will start the Pepper Service on port `8000`, in local development mode, meaning that it +will use a temporary file-based database and connect to the Aptos **devnet** to fetch on-chain +resources. + +Note: the Pepper Service will run in the foreground, so you will need to keep this terminal window +open while you interact with the Pepper Service. + +### Start the Pepper Client + +Next, you can run the Pepper Client example to interact with the Pepper Service: + +```bash +cd keyless/pepper/scripts +./start-pepper-client.sh +``` + +This will start the Pepper Client, which makes several API calls to the Pepper Service to +demonstrate example user flows. + +Note: the Pepper Client is an interactive console program, so you will need to follow the +instructions to manually complete a session with the Pepper Service. + +## Local Development with Firestore Emulator + +If you wish to test the Pepper Service with a Firestore database, you can do so by running +a Firestore emulator locally. The steps below will guide you through the process. + +### Prerequisites + +To run the Pepper Service with a Firestore database, this requires: +1. **GCP Project**: You must have a GCP project already set up. +2. **Service Account**: You need to create a service account with Firestore access and download the credential file + in JSON format. + +Both of these steps can be done via the GCP console. Once you have completed these steps, you can proceed. + +### Start the Firestore Emulator + +First, you will need to start the Firestore emulator locally. This can be done by running: + +```bash +cd keyless/pepper/scripts +./start-firestore-emulator.sh 8081 +``` + +The script arguments are: +- ``: The port where the Firestore emulator will run. + +The command above will start the Firestore emulator on port `8081`. The emulator will run in the foreground, so you +will need to keep this terminal window open while you work with the Pepper Service. + +### Stop the Emulator + +If you ever need to stop the Firestore emulator, you can do so by running: +```bash +cd keyless/pepper/scripts +./stop-firestore-emulator.sh 8081 +``` + +The script arguments are: +- ``: The port where the existing Firestore emulator is already running. + +When stopping the Firestore emulator, be sure to enter the correct port number. + +### Start the Pepper Service with Firestore + +Next, you can start the Pepper Service with Firestore by running: + +```bash +cd keyless/pepper/scripts +./start-pepper-service-with-firestore.sh +``` + +The script arguments are: +- ``: The host and port of the Firestore emulator, e.g., `http://localhost:8081`. +- ``: The path to your service account credential file (in JSON format). +- ``: The ID of your GCP project. + +### Start the Pepper Client with Firestore + +To run the example client, execute the following commands: + +```bash +cd keyless/pepper/scripts +./start-pepper-client-with-firestore.sh " +``` + +The script arguments are: +- ``: The host and port of the Firestore emulator, e.g., `http://localhost:8081`. +- ``: The path to your service account credential file (in JSON format). +- ``: The host and port of the Pepper Service, e.g., `http://localhost:8000`. +- ``: The ID of your GCP project. +- ``: The ID of your Firestore database. diff --git a/keyless/pepper/common/Cargo.toml b/keyless/pepper/common/Cargo.toml index 5466ceda380..c7824891f3d 100644 --- a/keyless/pepper/common/Cargo.toml +++ b/keyless/pepper/common/Cargo.toml @@ -16,17 +16,12 @@ rust-version = { workspace = true } anyhow = { workspace = true } aptos-crypto = { workspace = true } aptos-crypto-derive = { workspace = true } -aptos-dkg = { workspace = true } aptos-types = { workspace = true } -ark-bls12-381 = { workspace = true } -ark-ec = { workspace = true } -ark-ff = { workspace = true } -ark-serialize = { workspace = true } -ark-std = { workspace = true } -bcs = { workspace = true } +bcs = { workspace = true } # needed for BCSCryptoHash blstrs = { workspace = true } derivation-path = { workspace = true } ed25519-dalek = { workspace = true } +group = "0.13" hex = { workspace = true } hmac = { workspace = true } jsonwebtoken = { workspace = true } diff --git a/keyless/pepper/common/src/lib.rs b/keyless/pepper/common/src/lib.rs index 29e884a1403..8f927145362 100644 --- a/keyless/pepper/common/src/lib.rs +++ b/keyless/pepper/common/src/lib.rs @@ -70,6 +70,30 @@ pub struct BadPepperRequestError { pub message: String, } +/// A pepper request V2, which extends the original pepper request with additional +/// information. Note: this is an enum, to allow for future modifications and +/// extensibility, without needing to change the pepper service API. +#[derive(Debug, Deserialize, Serialize)] +pub enum PepperRequestV2 { + RequestWithAudOverride(PepperRequestWithAudOverride), +} + +impl PepperRequestV2 { + pub fn get_request_with_aud_override(self) -> PepperRequestWithAudOverride { + match self { + PepperRequestV2::RequestWithAudOverride(pepper_request_with_aud_override) => { + pepper_request_with_aud_override + }, + } + } +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct PepperRequestWithAudOverride { + pub aud_override: String, + pub pepper_request: PepperRequest, +} + /// A pepper scheme where: /// - The pepper input contains `JWT, epk, blinder, expiry_time, uid_key`, wrapped in type `PepperRequest`. /// - The pepper output is the `BLS12381_G1_BLS` VUF output of the input, wrapped in type `PepperResponse`. @@ -193,7 +217,13 @@ pub struct PepperV0VufPubKey { pub public_key: Vec, } -#[derive(Debug, Deserialize, Serialize)] +impl PepperV0VufPubKey { + pub fn new(public_key: Vec) -> Self { + Self { public_key } + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct PepperInput { pub iss: String, pub aud: String, diff --git a/keyless/pepper/common/src/vuf/bls12381_g1_bls.rs b/keyless/pepper/common/src/vuf/bls12381_g1_bls.rs index 32e339fdcd3..3366f4d3012 100644 --- a/keyless/pepper/common/src/vuf/bls12381_g1_bls.rs +++ b/keyless/pepper/common/src/vuf/bls12381_g1_bls.rs @@ -2,24 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 use crate::vuf::VUF; -use anyhow::{anyhow, ensure}; -use aptos_crypto::hash::CryptoHash; +use anyhow::ensure; +use aptos_crypto::{ + blstrs::{g1_proj_from_bytes, multi_pairing, random_scalar}, + hash::CryptoHash, +}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; -use aptos_dkg::utils::multi_pairing; use aptos_types::keyless::Pepper; -use ark_bls12_381::{Bls12_381, Fq12, Fr, G1Affine, G2Affine, G2Projective}; -use ark_ec::{ - hashing::HashToCurve, pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, - Group, -}; -use ark_ff::Field; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::{ - rand::{CryptoRng, RngCore}, - UniformRand, -}; -use blstrs::{self, Compress}; +use blstrs::{self, Compress, G1Affine, G1Projective, G2Affine, G2Projective, Gt, Scalar}; +use group::{prime::PrimeCurveAffine, Group}; use once_cell::sync::Lazy; +use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use serde_big_array::BigArray; use std::ops::Mul; @@ -32,8 +25,8 @@ pub static PINKAS_DST: &[u8] = b"APTOS_PINKAS_PEPPER_DST"; pub static PINKAS_SECRET_KEY_BASE_SEED: &[u8] = b"APTOS_PINKAS_PEPPER_SECRET_KEY_BASE_SEED"; -pub static PINKAS_SECRET_KEY_BASE_G2: Lazy = - Lazy::new(|| blstrs::G2Projective::hash_to_curve(PINKAS_SECRET_KEY_BASE_SEED, PINKAS_DST, b"")); +pub static PINKAS_SECRET_KEY_BASE_G2: Lazy = + Lazy::new(|| G2Projective::hash_to_curve(PINKAS_SECRET_KEY_BASE_SEED, PINKAS_DST, b"")); #[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] pub struct PinkasPepper { @@ -43,7 +36,7 @@ pub struct PinkasPepper { impl PinkasPepper { pub fn from_affine_bytes(input: &[u8]) -> anyhow::Result { - let g1 = blstrs::G1Projective::from_compressed(&input[0..48].try_into()?).unwrap(); + let g1 = G1Projective::from_compressed(&input[0..48].try_into()?).unwrap(); let g2 = *PINKAS_SECRET_KEY_BASE_G2; let pairing = multi_pairing([g1].iter(), [g2].iter()); let mut output: Vec = vec![]; @@ -61,20 +54,14 @@ impl PinkasPepper { impl Bls12381G1Bls { fn hash_to_g1(input: &[u8]) -> G1Affine { - let mapper = ark_ec::hashing::map_to_curve_hasher::MapToCurveBasedHasher::< - Projective, - ark_ff::fields::field_hashers::DefaultFieldHasher, - ark_ec::hashing::curve_maps::wb::WBMap, - >::new(DST) - .unwrap(); - mapper.hash(input).unwrap() + G1Projective::hash_to_curve(input, DST, b"").into() } } pub const SCHEME_NAME: &str = "BLS12381_G1_BLS"; impl VUF for Bls12381G1Bls { - type PrivateKey = Fr; + type PrivateKey = Scalar; type PublicKey = G2Projective; fn scheme_name() -> String { @@ -82,24 +69,20 @@ impl VUF for Bls12381G1Bls { } fn setup(rng: &mut R) -> (Self::PrivateKey, Self::PublicKey) { - let sk = Fr::rand(rng); + let sk = random_scalar(rng); let pk = G2Affine::generator() * sk; (sk, pk) } - fn pk_from_sk(sk: &Fr) -> anyhow::Result { + fn pk_from_sk(sk: &Scalar) -> anyhow::Result { Ok(G2Projective::generator() * sk) } - fn eval(sk: &Fr, input: &[u8]) -> anyhow::Result<(Vec, Vec)> { + /// WARNING: This function must remain constant-time w.r.t. to `sk` and `input`. + fn eval(sk: &Scalar, input: &[u8]) -> anyhow::Result<(Vec, Vec)> { let input_g1 = Self::hash_to_g1(input); - let output_g1 = input_g1.mul(sk).into_affine(); - let mut output_bytes = vec![]; - output_g1 - .serialize_compressed(&mut output_bytes) - .map_err(|e| { - anyhow!("Bls12381G1Bls::eval failed with output serialization error: {e}") - })?; + let output_g1 = input_g1.mul(sk); + let output_bytes = output_g1.to_compressed().to_vec(); Ok((output_bytes, vec![])) } @@ -114,16 +97,13 @@ impl VUF for Bls12381G1Bls { "Bls12381G1Bls::verify failed with proof deserialization error" ); let input_g1 = Self::hash_to_g1(input); - let output_g1 = G1Affine::deserialize_compressed(output).map_err(|e| { - anyhow!("Bls12381G1Bls::verify failed with output deserialization error: {e}") - })?; + let output_g1 = g1_proj_from_bytes(output)?; + ensure!( - Fq12::ONE - == Bls12_381::multi_pairing([-output_g1, input_g1], [ - G2Affine::generator(), - (*pk_g2).into_affine() - ]) - .0, + multi_pairing( + vec![-output_g1, input_g1.into()].iter(), + vec![G2Projective::generator(), *pk_g2].iter() + ) == Gt::identity(), "Bls12381G1Bls::verify failed with final check failure" ); Ok(()) @@ -135,8 +115,8 @@ mod tests { use crate::vuf::{bls12381_g1_bls::Bls12381G1Bls, VUF}; #[test] - fn gen_eval_verify() { - let mut rng = ark_std::rand::thread_rng(); + fn test_eval_verify() { + let mut rng = rand::thread_rng(); let (sk, pk) = Bls12381G1Bls::setup(&mut rng); let pk_another = Bls12381G1Bls::pk_from_sk(&sk).unwrap(); assert_eq!(pk_another, pk); diff --git a/keyless/pepper/common/src/vuf/mod.rs b/keyless/pepper/common/src/vuf/mod.rs index d23aa5a85be..5809c5e840a 100644 --- a/keyless/pepper/common/src/vuf/mod.rs +++ b/keyless/pepper/common/src/vuf/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use anyhow::Result; -use ark_std::rand::{CryptoRng, RngCore}; +use rand::{CryptoRng, RngCore}; /// Implement this to define a VUF (verifiable unpredictable function). pub trait VUF { @@ -15,6 +15,7 @@ pub trait VUF { fn pk_from_sk(sk: &Self::PrivateKey) -> Result; + /// WARNING: Implementations of this MUST be constant-time w.r.t. to any `sk` and `input`. /// Return `(output, proof)`. fn eval(sk: &Self::PrivateKey, input: &[u8]) -> Result<(Vec, Vec)>; diff --git a/keyless/pepper/common/src/vuf/slip_10.rs b/keyless/pepper/common/src/vuf/slip_10.rs index 65def266187..75b23e6ac75 100644 --- a/keyless/pepper/common/src/vuf/slip_10.rs +++ b/keyless/pepper/common/src/vuf/slip_10.rs @@ -59,9 +59,7 @@ type HmacSha512 = Hmac; pub fn get_aptos_derivation_path(s: &str) -> Result { let re = Regex::new(r"^m\/44'\/637'\/[0-9]+'\/[0-9]+'\/[0-9]+'?$").unwrap(); - if re.is_match(s) { - println!("Valid path"); - } else { + if !re.is_match(s) { bail!(format!("Invalid derivation path: {}", s)) } Ok(DerivationPath::from_str(s)?) diff --git a/keyless/pepper/example-client-rust/Cargo.toml b/keyless/pepper/example-client-rust/Cargo.toml index 3311ef0e924..da8c05e4750 100644 --- a/keyless/pepper/example-client-rust/Cargo.toml +++ b/keyless/pepper/example-client-rust/Cargo.toml @@ -17,11 +17,13 @@ aptos-crypto = { workspace = true } aptos-infallible = { workspace = true } aptos-keyless-pepper-common = { workspace = true } aptos-types = { workspace = true } -ark-bls12-381 = { workspace = true } -ark-serialize = { workspace = true } bcs = { workspace = true } +blstrs = { workspace = true } +clap = { workspace = true } firestore = { workspace = true } hex = { workspace = true } +rand = { workspace = true } reqwest = { workspace = true } +serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } diff --git a/keyless/pepper/example-client-rust/src/lib.rs b/keyless/pepper/example-client-rust/src/lib.rs new file mode 100644 index 00000000000..fedb49d6072 --- /dev/null +++ b/keyless/pepper/example-client-rust/src/lib.rs @@ -0,0 +1,491 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_crypto::{blstrs::g2_proj_from_bytes, ed25519::Ed25519PrivateKey, PrivateKey, Uniform}; +use aptos_infallible::duration_since_epoch; +use aptos_keyless_pepper_common::{ + account_recovery_db::AccountRecoveryDbEntry, + jwt, + vuf::{self, VUF}, + PepperInput, PepperRequest, PepperResponse, PepperV0VufPubKey, SignatureResponse, +}; +use aptos_types::{keyless::OpenIdSig, transaction::authenticator::EphemeralPublicKey}; +use blstrs::G2Projective; +use firestore::{path, paths, FirestoreDb, FirestoreDbOptions}; +use rand::RngCore; +use reqwest::{Client, StatusCode}; + +mod utils; + +// Default values +const DEFAULT_CLIENT_TIMEOUT_SECS: u64 = 10; +const DEFAULT_FIRESTORE_COLLECTION: &str = "accounts"; +const DEFAULT_JWT: &str = + "eyJhbGciOiJSUzI1NiIsImtpZCI6ImUxYjkzYzY0MDE0NGI4NGJkMDViZjI5NmQ2NzI2MmI2\ + YmM2MWE0ODciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZ\ + S5jb20iLCJhenAiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iL\ + CJhdWQiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiO\ + iIxMTE2Mjc3NzI0NjA3NTIzNDIzMTIiLCJhdF9oYXNoIjoiaG5OWHFJVTZ3dWFPYlVqR05lR\ + VhGQSIsIm5vbmNlIjoiNzQyMDQxODMxNDYwMDk1MDM0MTU3NzQ0MzEzMzY0MTU4OTk0NzYwN\ + TExMjc1MDEwNDIyNjY5MDY3NTc3OTY3NTIyNDAwNjA0OTI0NCIsIm5hbWUiOiJPbGl2ZXIgS\ + GUiLCJnaXZlbl9uYW1lIjoiT2xpdmVyIiwiZmFtaWx5X25hbWUiOiJIZSIsImlhdCI6MTcxN\ + DQ0MTc4MywiZXhwIjoxNzE0NDQ1MzgzfQ.iNeVzp4BTQj2I_WH6UaUOfUBV4Q_wUriV7jWkh\ + 1fUqTPSs30jMMSjEDZml8lQ_NUIpivnGvfEHt_rF9rlrsuRur9pTVKRRKhJUNf5avrAujvLz\ + rz-bwdgKXtTY_nmYisNNNQwmFIVP004ICois4DHD7EmO8PI88CzSzdDbl9qAIoxOP3JRKRwU\ + 05wK5qkGz6FpYzTYiG50lQCybSzzUN5Lws49ANCAOZiROG5lmszOW41mAbFSd6MUX469uvyM\ + A2ZZ5av9ArKricHJPutGtLoOSWpzKQ_mlCzofVs5tHoMhGgcOFKuhnEVdY4J7TdcV6pZv9Ih\ + 5F8MX3-Wz9Iz9O4w"; +const DEFAULT_UID_KEY: &str = "sub"; + +// The Google Playground URL for generating JWTs +const GOOGLE_PLAYGROUND_URL: &str = + "https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?\ + redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground\ + &prompt=consent\ + &response_type=code\ + &client_id=407408718192.apps.googleusercontent.com\ + &scope=profile\ + &access_type=offline\ + &service=lso\ + &o2v=2\ + &theme=glif\ + &flowName=GeneralOAuthFlow\ + &nonce="; + +// Endpoints for the pepper service +const PEPPER_SERVICE_FETCH_URL: &str = "/v0/fetch"; +const PEPPER_SERVICE_SIG_URL: &str = "/v0/signature"; +const PEPPER_SERVICE_VUF_PUB_KEY_URL: &str = "/v0/vuf-pub-key"; + +// Useful type annotations +type Blinder = [u8; 31]; + +/// Runs the example client that interacts with the pepper service +pub async fn run_client_example( + pepper_service_url: String, + firestore_google_project_id: Option, + firestore_database_id: Option, +) { + utils::print( + "Starting the example client that interacts with the Aptos OIDB Pepper Service.", + true, + ); + + // Step 1: Fetch the verification key from the pepper service + let mut request_client = utils::create_request_client(); + let verification_public_key = + fetch_verification_public_key(&mut request_client, &pepper_service_url).await; + + // Step 2: Create the blinder, ephemeral key and ephemeral key expiry time + let (blinder, ephemeral_public_key, ephemeral_key_expiry_secs) = + generate_blinder_and_ephemeral_key(); + + // Step 3: Generate an OAuth nonce using the blinder, ephemeral public key and expiry time + let nonce_str = generate_oauth_nonce(blinder, ephemeral_key_expiry_secs, &ephemeral_public_key); + + // Step 4: Fetch a JWT with the given nonce + let jwt = fetch_jwt_with_nonce(nonce_str); + + // Step 5: Request a pepper from the pepper service + let pepper_request = request_pepper_from_service( + &mut request_client, + &pepper_service_url, + blinder, + ephemeral_public_key, + ephemeral_key_expiry_secs, + &jwt, + ) + .await; + + // Step 6: Request a signature from the pepper service for the pepper request + let signature = + request_signature_from_service(&mut request_client, &pepper_service_url, &pepper_request) + .await; + + // (Optional) Step 7: Verify the pepper signature using the verification key, JWT and signature + let pepper_input = verify_pepper_signature(&verification_public_key, jwt, &signature); + + // (Optional) Step 8: Verify the firestore entry for the pepper input + verify_firestore_pepper_entry( + pepper_input, + firestore_google_project_id, + firestore_database_id, + ) + .await; +} + +/// Step 1: Fetch the verification key from the pepper service +async fn fetch_verification_public_key( + request_client: &mut Client, + pepper_service_url: &str, +) -> G2Projective { + let verification_key_url = format!("{}{}", pepper_service_url, PEPPER_SERVICE_VUF_PUB_KEY_URL); + utils::print( + &format!("Step 1: Fetching the verification key from the pepper service ({}) with a GET request to {}.", pepper_service_url, verification_key_url), + true, + ); + + // Send the GET request + let response = request_client + .get(verification_key_url) + .send() + .await + .unwrap(); + + // Parse the verification key from the response + let verification_key = response.json::().await.unwrap(); + utils::print( + &format!( + "Received the verification key: {}", + utils::to_string_pretty(&verification_key) + ), + false, + ); + + // Deserialize the verification key + g2_proj_from_bytes(verification_key.public_key.as_slice()).unwrap() +} + +/// Step 2: Generate a blinder, an ephemeral key pair, and an expiry time for the ephemeral key +fn generate_blinder_and_ephemeral_key() -> (Blinder, EphemeralPublicKey, u64) { + utils::print( + "Step 2: Generating a blinder, ephemeral keypair and keypair expiration time.", + true, + ); + + // Generate a random blinder + let mut blinder = Blinder::default(); + rand::thread_rng().fill_bytes(&mut blinder); + utils::print( + &format!("Generated blinder (hex): {}", hex::encode(blinder)), + false, + ); + + // Generate a new ephemeral key pair + let private_key = Ed25519PrivateKey::generate(&mut rand::thread_rng()); + let ephemeral_public_key = EphemeralPublicKey::ed25519(private_key.public_key()); + utils::print( + &format!( + "Generated ephemeral public key (hex): {} and private key (hex): {}", + hex::encode(ephemeral_public_key.to_bytes()), + hex::encode(private_key.to_bytes()) + ), + false, + ); + + // Generate a UNIX expiry time for the keypair (e.g., 1 hour from now) + let expiry_time_secs = duration_since_epoch().as_secs() + 3600; + utils::print( + &format!( + "Generated UNIX expiry time (1 hour from now): {}", + expiry_time_secs + ), + false, + ); + + (blinder, ephemeral_public_key, expiry_time_secs) +} + +/// Step 3: Generate the OAuth nonce using the given blinder, expiry time, and ephemeral public key +fn generate_oauth_nonce( + blinder: Blinder, + epk_expiry_time_secs: u64, + ephemeral_public_key: &EphemeralPublicKey, +) -> String { + utils::print( + "Step 3: Generating the OAuth nonce using the blinder, expiry time, and ephemeral public key.", + true, + ); + + // Generate the nonce + let oauth_nonce = OpenIdSig::reconstruct_oauth_nonce( + blinder.as_slice(), + epk_expiry_time_secs, + ephemeral_public_key, + &utils::get_keyless_configuration(), + ) + .unwrap(); + utils::print(&format!("Generated OAuth nonce: {}", oauth_nonce), false); + + oauth_nonce +} + +/// Step 4: Fetch a JWT with the given nonce +fn fetch_jwt_with_nonce(nonce_str: String) -> String { + utils::print( + &format!("Step 4: Fetch a JWT with the given nonce: {}", nonce_str), + true, + ); + + // Print instructions for the user to follow + utils::print("To fetch a JWT with the nonce, we will use an example from the Google OAuth 2.0 Playground.", false); + utils::print("First, open the following URL in your web browser:", false); + utils::print(&format!("{}{}", GOOGLE_PLAYGROUND_URL, nonce_str), false); + utils::print("Then, sign in as requested by the web UI.", false); + utils::print( + "Once you are signed in to 'OAuth 2.0 Playground' click the blue button called \ + 'Exchange authorization code for tokens'.", + false, + ); + utils::print( + "You should see a response. In the response, take the value of the field 'id_token' \ + (exclude the double-quotes) and save it to a file. This is your JWT.", + false, + ); + + // Get the JWT from the user + utils::get_jwt() +} + +/// Step 5: Request a pepper from the pepper service for the given parameters +async fn request_pepper_from_service( + request_client: &mut Client, + pepper_service_url: &str, + blinder: Blinder, + ephemeral_public_key: EphemeralPublicKey, + ephemeral_key_expiry_secs: u64, + jwt: &str, +) -> PepperRequest { + let pepper_fetch_url = format!("{}{}", pepper_service_url, PEPPER_SERVICE_FETCH_URL); + utils::print( + &format!( + "Step 5: Requesting a pepper from the pepper service with a POST request to {}.", + pepper_fetch_url + ), + true, + ); + + // Create the pepper request + let pepper_request = PepperRequest { + jwt: jwt.into(), + epk: ephemeral_public_key, + exp_date_secs: ephemeral_key_expiry_secs, + uid_key: None, + epk_blinder: blinder.to_vec(), + derivation_path: None, + }; + + // Send the request to fetch the pepper + utils::print( + &format!( + "Sending the request to fetch the pepper. Request body: {}", + utils::to_string_pretty(&pepper_request) + ), + false, + ); + let response = request_client + .post(pepper_fetch_url) + .json(&pepper_request) + .send() + .await + .unwrap(); + + // Parse the response + let pepper_response = match response.status() { + StatusCode::OK => response.json::().await.unwrap(), + status => { + panic!( + "Failed to fetch the pepper from the service. Response status: {}", + status + ); + }, + }; + utils::print( + &format!( + "Received the pepper response from the service: {}", + utils::to_string_pretty(&pepper_response) + ), + false, + ); + + pepper_request +} + +/// Step 6: Request a signature from the pepper service for the given pepper request +async fn request_signature_from_service( + request_client: &mut Client, + pepper_service_url: &str, + pepper_request: &PepperRequest, +) -> Vec { + let pepper_sig_url = format!("{}{}", pepper_service_url, PEPPER_SERVICE_SIG_URL); + utils::print( + &format!( + "Step 6: Requesting a signature from the pepper service with a POST request to {}.", + pepper_sig_url + ), + true, + ); + + // Send the request to fetch the signature + utils::print( + &format!( + "Sending the request to fetch the signature. Request body: {}", + utils::to_string_pretty(&pepper_request) + ), + false, + ); + let response = request_client + .post(pepper_sig_url) + .json(&pepper_request) + .send() + .await + .unwrap(); + + // Parse the response + let signature_response = match response.status() { + StatusCode::OK => response.json::().await.unwrap(), + status => { + panic!( + "Failed to fetch the signature from the service. Response status: {}", + status + ); + }, + }; + utils::print( + &format!( + "Received the signature response from the service: {}", + utils::to_string_pretty(&signature_response) + ), + false, + ); + + // Return the signature + let SignatureResponse { signature } = signature_response; + signature +} + +/// (Optional) Step 7: Verify the pepper signature using the verification public key, JWT and signature +fn verify_pepper_signature( + verification_public_key: &G2Projective, + jwt: String, + signature: &[u8], +) -> PepperInput { + utils::print( + "(Optional) Step 7: Verifying the pepper signature using the verification public key, JWT and signature.", + true, + ); + + // Parse the claims from the JWT + let claims = jwt::parse(&jwt).unwrap(); + let iss = claims.claims.iss.clone(); + let uid_key = DEFAULT_UID_KEY.to_string(); + let uid_val = claims.claims.sub.clone(); + let aud = claims.claims.aud.clone(); + + // Construct the pepper input and serialize it + let pepper_input = PepperInput { + iss, + uid_key, + uid_val, + aud, + }; + utils::print( + &format!( + "Constructed the pepper input to verify the signature: {}", + utils::to_string_pretty(&pepper_input) + ), + false, + ); + let pepper_input_bytes = bcs::to_bytes(&pepper_input).unwrap(); + + // Verify the pepper service signature over the pepper input + vuf::bls12381_g1_bls::Bls12381G1Bls::verify( + verification_public_key, + &pepper_input_bytes, + signature, + &[], + ) + .unwrap(); + utils::print( + "The signature over the pepper input was verified successfully!", + false, + ); + + pepper_input +} + +/// (Optional) Step 8: Verify that a firestore entry exists for the given pepper input +async fn verify_firestore_pepper_entry( + pepper_input: PepperInput, + google_project_id: Option, + database_id: Option, +) { + // Check if the Google project ID and database ID are provided + let (google_project_id, database_id) = match (google_project_id, database_id) { + (Some(google_project_id), Some(database_id)) => { + utils::print( + &format!("(Optional) Step 8: Verifying that a firestore entry exists for the given pepper input. Project ID: {}, Database: {}", google_project_id, database_id), + true, + ); + (google_project_id, database_id) + }, + _ => { + utils::print( + "Skipping the verification of the firestore entry since the Google project ID and database ID are not provided!", + true, + ); + return; + }, + }; + + // Create the firestore DB client + let firestore_db_options = FirestoreDbOptions { + google_project_id, + database_id, + max_retries: 1, + firebase_api_url: None, + }; + let firestore_db = FirestoreDb::with_options(firestore_db_options) + .await + .unwrap(); + + // Wait for a short duration to ensure the firestore entry is available. + // This is required because firestore writes may be asynchronous. + utils::print( + "Waiting for 2 seconds to ensure the firestore entry is available...", + false, + ); + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + + // Query the firestore DB for the pepper input entry + let docs: Vec = firestore_db + .fluent() + .select() + .fields(paths!(AccountRecoveryDbEntry::{iss, aud, uid_key, uid_val, last_request_unix_ms, first_request_unix_ms_minus_1q, num_requests})) + .from(DEFAULT_FIRESTORE_COLLECTION) + .filter(|q| { + q.for_all([ + q.field(path!(AccountRecoveryDbEntry::iss)) + .eq(pepper_input.iss.clone()), + q.field(path!(AccountRecoveryDbEntry::aud)) + .eq(pepper_input.aud.clone()), + q.field(path!(AccountRecoveryDbEntry::uid_key)) + .eq(pepper_input.uid_key.clone()), + q.field(path!(AccountRecoveryDbEntry::uid_val)) + .eq(pepper_input.uid_val.clone()), + ]) + }) + .obj() + .query() + .await + .unwrap(); + + // Verify that exactly one entry was found + match docs.len() { + 0 => panic!( + "No firestore entry found for the given pepper input: {}", + utils::to_string_pretty(&pepper_input) + ), + 1 => utils::print( + &format!( + "Successfully found exactly one firestore entry for the given pepper input: {:?}", + docs + ), + false, + ), + n => panic!( + "Multiple ({}) firestore entries found for the given pepper input!", + n + ), + } +} diff --git a/keyless/pepper/example-client-rust/src/main.rs b/keyless/pepper/example-client-rust/src/main.rs index d9bd0820964..270ca873da1 100644 --- a/keyless/pepper/example-client-rust/src/main.rs +++ b/keyless/pepper/example-client-rust/src/main.rs @@ -1,239 +1,37 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_crypto::ed25519::{Ed25519PrivateKey, Ed25519PublicKey}; -use aptos_infallible::duration_since_epoch; -use aptos_keyless_pepper_common::{ - account_recovery_db::AccountRecoveryDbEntry, - jwt, - vuf::{self, VUF}, - PepperInput, PepperRequest, PepperResponse, PepperV0VufPubKey, SignatureResponse, -}; -use aptos_types::{ - keyless::{Configuration, OpenIdSig}, - transaction::authenticator::EphemeralPublicKey, -}; -use ark_serialize::CanonicalDeserialize; -use firestore::{path, paths, FirestoreDb, FirestoreDbOptions}; -use reqwest::StatusCode; -use std::{fs, io::stdin}; - -const TEST_JWT: &str = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImUxYjkzYzY0MDE0NGI4NGJkMDViZjI5NmQ2NzI2MmI2YmM2MWE0ODciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTE2Mjc3NzI0NjA3NTIzNDIzMTIiLCJhdF9oYXNoIjoiaG5OWHFJVTZ3dWFPYlVqR05lRVhGQSIsIm5vbmNlIjoiNzQyMDQxODMxNDYwMDk1MDM0MTU3NzQ0MzEzMzY0MTU4OTk0NzYwNTExMjc1MDEwNDIyNjY5MDY3NTc3OTY3NTIyNDAwNjA0OTI0NCIsIm5hbWUiOiJPbGl2ZXIgSGUiLCJnaXZlbl9uYW1lIjoiT2xpdmVyIiwiZmFtaWx5X25hbWUiOiJIZSIsImlhdCI6MTcxNDQ0MTc4MywiZXhwIjoxNzE0NDQ1MzgzfQ.iNeVzp4BTQj2I_WH6UaUOfUBV4Q_wUriV7jWkh1fUqTPSs30jMMSjEDZml8lQ_NUIpivnGvfEHt_rF9rlrsuRur9pTVKRRKhJUNf5avrAujvLzrz-bwdgKXtTY_nmYisNNNQwmFIVP004ICois4DHD7EmO8PI88CzSzdDbl9qAIoxOP3JRKRwU05wK5qkGz6FpYzTYiG50lQCybSzzUN5Lws49ANCAOZiROG5lmszOW41mAbFSd6MUX469uvyMA2ZZ5av9ArKricHJPutGtLoOSWpzKQ_mlCzofVs5tHoMhGgcOFKuhnEVdY4J7TdcV6pZv9Ih5F8MX3-Wz9Iz9O4w"; - -fn read_line_from_stdin() -> String { - let mut line = String::new(); - stdin().read_line(&mut line).unwrap(); - line -} - -fn get_pepper_service_url() -> String { - match std::env::var("OIDB_PEPPER_TEST_CLIENT__SERVICE_URL") { - Ok(val) => { - println!(); - println!( - "Pepper service url found from envvar OIDB_PEPPER_TEST_CLIENT__SERVICE_URL: {}", - val - ); - val - }, - Err(_) => { - println!(); - println!("Pepper service url not found from envvar OIDB_PEPPER_SERVICE_URL."); - println!("Enter the URL of the targeted pepper service deployment (default: http://localhost:8000):"); - let raw = read_line_from_stdin().trim().to_string(); - if raw.is_empty() { - "http://localhost:8000".to_string() - } else { - raw - } - }, - } -} - -fn get_jwt_or_path() -> String { - println!(); - println!( - "Enter the JWT token (defaults to test token), or a text file path that contains the JWT:" - ); - let user_input = read_line_from_stdin().trim().to_string(); - if !user_input.is_empty() { - user_input - } else { - println!("Using the test JWT token"); - TEST_JWT.to_string() - } +use aptos_keyless_pepper_example_client_rust::run_client_example; +use clap::Parser; + +#[derive(Parser, Debug)] +#[command(author, version, about)] +struct Args { + /// The URL of the Pepper Service + #[arg(long, default_value = "http://localhost:8000")] + pepper_service_url: String, + + /// The Google project ID used by Firestore. If not provided, the client example + /// will not verify that the account recovery DB was updated. + #[arg(long, requires = "firestore_database_id")] + firestore_google_project_id: Option, + + /// The database ID used by Firestore. If not provided, the client example + /// will not verify that the account recovery DB was updated. + #[arg(long, requires = "firestore_google_project_id")] + firestore_database_id: Option, } #[tokio::main] async fn main() { - // if let Ok(x) = std::env::var("V0_VERIFY") { - // test_v0_verify(); - // } - println!(); - println!("Starting an interaction with aptos-oidb-pepper-service."); - let url = get_pepper_service_url(); - println!(); - let vuf_pub_key_url = format!("{url}/v0/vuf-pub-key"); - let fetch_url = format!("{url}/v0/fetch"); - let sig_url = format!("{url}/v0/signature"); - println!(); - println!( - "Action 1: fetch its verification key with a GET request to {}", - vuf_pub_key_url - ); - let client = reqwest::Client::new(); - let response = client - .get(vuf_pub_key_url) - .send() - .await - .unwrap() - .json::() - .await - .unwrap(); - println!(); - println!( - "response_json={}", - serde_json::to_string_pretty(&response).unwrap() - ); - let PepperV0VufPubKey { public_key: vuf_pk } = response; - let vuf_pk: ark_bls12_381::G2Projective = - ark_bls12_381::G2Affine::deserialize_compressed(vuf_pk.as_slice()) - .unwrap() - .into(); - - println!(); - println!("Action 3: generate some random bytes as a blinder."); - let blinder: [u8; 31] = [0u8; 31]; - println!("blinder_hexlified={}", hex::encode(blinder)); - - println!(); - println!("Action 4: decide an expiry unix time."); - let epk_expiry_time_secs = duration_since_epoch().as_secs() + 3600; - println!("expiry_time_sec={}", epk_expiry_time_secs); - - let esk_bytes = - hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap(); - let serialized: &[u8] = esk_bytes.as_slice(); - let esk = Ed25519PrivateKey::try_from(serialized).unwrap(); - let epk = EphemeralPublicKey::ed25519(Ed25519PublicKey::from(&esk)); - println!("esk_hexlified={}", hex::encode(esk.to_bytes())); - println!("epk_hexlified={}", hex::encode(epk.to_bytes())); - - println!(); - println!("Action 5: compute nonce."); - let nonce_str = OpenIdSig::reconstruct_oauth_nonce( - blinder.as_slice(), - epk_expiry_time_secs, - &epk, - &Configuration::new_for_devnet(), + // Fetch the command line arguments + let args = Args::parse(); + + // Run the client example + run_client_example( + args.pepper_service_url, + args.firestore_google_project_id, + args.firestore_database_id, ) - .unwrap(); - println!("nonce_string={}", nonce_str); - println!(); - println!("Action 6: request a JWT with this nonce. Below are generated example that uses Google OAuth 2.0 Playground:"); - println!("6.1: Go to https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=profile&access_type=offline&service=lso&o2v=2&theme=glif&flowName=GeneralOAuthFlow&nonce={nonce_str}"); - println!("6.2: Sign in as requested by the web UI"); - println!("6.3: Once you are signed in to 'OAuth 2.0 Playground' and see a blue button called 'Exchange authorization code for tokens', click it"); - println!("6.4: You should see some response showing up. Take the value of the field 'id_token' (exclude the double-quotes) and save it to a file"); - let jwt_or_path = get_jwt_or_path(); - let jwt = match fs::read_to_string(jwt_or_path.clone()) { - Ok(raw_str) => raw_str.trim().to_string(), - Err(_) => jwt_or_path, - }; - - let pepper_request = PepperRequest { - jwt: jwt.clone(), - epk, - exp_date_secs: epk_expiry_time_secs, - uid_key: None, - epk_blinder: blinder.to_vec(), - derivation_path: None, - }; - println!(); - println!( - "Request pepper with a POST to {} and the body being {}", - fetch_url, - serde_json::to_string_pretty(&pepper_request).unwrap() - ); - let pepper_raw_response = client - .post(fetch_url) - .json(&pepper_request) - .send() - .await - .unwrap(); - assert_eq!(StatusCode::OK, pepper_raw_response.status()); - let pepper_response = pepper_raw_response.json::().await.unwrap(); - println!(); - println!( - "pepper_service_response={}", - serde_json::to_string_pretty(&pepper_response).unwrap() - ); - let PepperResponse { pepper, address } = pepper_response; - - let signature_raw_response = client - .post(sig_url) - .json(&pepper_request) - .send() - .await - .unwrap(); - assert_eq!(StatusCode::OK, signature_raw_response.status()); - let signature_response = signature_raw_response - .json::() - .await - .unwrap(); - println!( - "signature_response={}", - serde_json::to_string_pretty(&signature_response).unwrap() - ); - let SignatureResponse { signature } = signature_response; - println!("signature={:?}", hex::encode(signature.clone())); - println!("pepper={:?}", hex::encode(pepper.clone())); - println!("address={:?}", hex::encode(address.clone())); - let claims = jwt::parse(jwt.as_str()).unwrap(); - println!(); - println!("Verify the pepper against the server's verification key, part of the JWT, and the actual aud."); - let pepper_input = PepperInput { - iss: claims.claims.iss.clone(), - uid_key: "sub".to_string(), - uid_val: claims.claims.sub.clone(), - aud: claims.claims.aud.clone(), - }; - let pepper_input_bytes = bcs::to_bytes(&pepper_input).unwrap(); - vuf::bls12381_g1_bls::Bls12381G1Bls::verify(&vuf_pk, &pepper_input_bytes, &signature, &[]) - .unwrap(); - println!("Pepper verification succeeded!"); - - println!("Checking firestore records."); - let google_project_id = std::env::var("PROJECT_ID").unwrap(); - let database_id = std::env::var("DATABASE_ID").unwrap(); - let options = FirestoreDbOptions { - google_project_id, - database_id, - max_retries: 1, - firebase_api_url: None, - }; - let db = FirestoreDb::with_options(options).await.unwrap(); - let docs: Vec = db - .fluent() - .select() - .fields(paths!(AccountRecoveryDbEntry::{iss, aud, uid_key, uid_val, last_request_unix_ms, first_request_unix_ms_minus_1q, num_requests})) - .from("accounts") - .filter(|q| { - q.for_all([ - q.field(path!(AccountRecoveryDbEntry::iss)) - .eq(pepper_input.iss.clone()), - q.field(path!(AccountRecoveryDbEntry::aud)) - .eq(pepper_input.aud.clone()), - q.field(path!(AccountRecoveryDbEntry::uid_key)) - .eq(pepper_input.uid_key.clone()), - q.field(path!(AccountRecoveryDbEntry::uid_val)) - .eq(pepper_input.uid_val.clone()), - ]) - }) - .obj() - .query() - .await - .unwrap(); - println!("docs={docs:?}"); - assert_eq!(1, docs.len()); + .await; } diff --git a/keyless/pepper/example-client-rust/src/utils.rs b/keyless/pepper/example-client-rust/src/utils.rs new file mode 100644 index 00000000000..e76f3e4d29b --- /dev/null +++ b/keyless/pepper/example-client-rust/src/utils.rs @@ -0,0 +1,69 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{DEFAULT_CLIENT_TIMEOUT_SECS, DEFAULT_JWT}; +use aptos_types::keyless::Configuration; +use reqwest::Client; +use serde::Serialize; +use std::{fs, io::stdin, time::Duration}; + +/// Creates and returns a new reqwest client +pub fn create_request_client() -> Client { + Client::builder() + .timeout(Duration::from_secs(DEFAULT_CLIENT_TIMEOUT_SECS)) + .build() + .unwrap() +} + +/// Fetches the JWT from the user, or uses a test token if no input is provided +pub fn get_jwt() -> String { + // Prompt the user for the token or file path + print( + "Enter the JWT, or a text file path that contains the JWT. If nothing is entered, \ + a test token will be used.", + true, + ); + let user_input = read_input_from_stdin().trim().to_string(); + + // Fetch the JWT or use the test token + if !user_input.is_empty() { + match fs::read_to_string(user_input.clone()) { + Ok(jwt) => { + print("Read the JWT from the file!", false); + jwt.trim().to_string() + }, + Err(_) => { + print("Using the input as the JWT itself!", false); + user_input + }, + } + } else { + print("Using the test JWT token!", false); + DEFAULT_JWT.to_string() + } +} + +/// Returns a test keyless configuration +pub fn get_keyless_configuration() -> Configuration { + Configuration::new_for_devnet() +} + +/// Prints the given string. If `newline_header` is true, adds an empty line before the string. +pub fn print(string: &str, newline_header: bool) { + if newline_header { + println!(); + } + println!("{}", string); +} + +/// Reads a line from stdin and returns it as string +pub fn read_input_from_stdin() -> String { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + line.trim().to_string() +} + +/// Serializes a value to a pretty JSON string +pub fn to_string_pretty(value: &T) -> String { + serde_json::to_string_pretty(value).unwrap() +} diff --git a/keyless/pepper/readme.md b/keyless/pepper/readme.md deleted file mode 100644 index 85386414148..00000000000 --- a/keyless/pepper/readme.md +++ /dev/null @@ -1,89 +0,0 @@ -## Dev guide - -### Prepare dependency: a firestore instance. - -Pepper service now depends on an account recovery DB, which is deployed as a firestore on GCP. -You must have a GCP project in order to run firestore emulator locally. -You also need to create a service account, grant firestore access to it, and download its credential file. - -In terminal 0, start a local firestore emulator. -```bash -gcloud emulators firestore start --host-port=localhost:8081 -``` - -In terminal 1, set up the environment variables and start the pepper service. -```bash -# If specified, firestore library connects to the local emulator instead of the real GCP API. -export FIRESTORE_EMULATOR_HOST=localhost:8081 - -export GOOGLE_APPLICATION_CREDENTIALS="" - -# Specify the account recovery DB location. -export PROJECT_ID=$(gcloud config get-value project) -export DATABASE_ID='(default)' # the default name of a local firestore emulator - -# Specify an account manager. -export ACCOUNT_MANAGER_0_ISSUER=https://accounts.google.com -export ACCOUNT_MANAGER_0_AUD=407408718192.apps.googleusercontent.com -# To specify more, do the following: -# export ACCOUNT_MANAGER_1_ISSUER=https://www.facebook.com -# export ACCOUNT_MANAGER_1_AUD=999999999.apps.fbusercontent.com -# export ACCOUNT_MANAGER_2_ISSUER=https://appleid.apple.com -# export ACCOUNT_MANAGER_2_AUD=88888888.apps.appleusercontent.com - -# Specify the VUF private key. -export VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -# Start the pepper service. -cargo run -p aptos-keyless-pepper-service -``` - -Run the example client in terminal 2. -```bash -# In addition to sending a pepper request and verify the response, -# the example client also connects to the account recovery DB and verifies that it was correctly updated by the pepper service. -# So here it relies on the same firestore-related parameters as `aptos-keyless-pepper-service` does. -export FIRESTORE_EMULATOR_HOST=localhost:8081 -export GOOGLE_APPLICATION_CREDENTIALS="" -export PROJECT_ID=$(gcloud config get-value project) -export DATABASE_ID='(default)' # the default name of a local firestore emulator - -# Start the example client. -cargo run -p aptos-keyless-pepper-example-client-rust -``` -This is an interactive console program. -Follow the instruction to manually complete a session with the pepper service. - -## NOTE for frontend developers -Sorry for the missing examples in other programming languages. -For now please read through `example-client-rust/src/main.rs` implementation and output: -that is what your frontend needs to do. - -## Extra: manual testing for endpoint `v0/verify`. -NOTE: API `v0/verify` now depends on on-chain resources -`0x1::keyless_account::Groth16VerificationKey` and `0x1::keyless_account::Configuration`, -which need to be fetched via HTTP requests. - -In terminal 0, run the pepper service. -```bash -export VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -export ONCHAIN_GROTH16_VK_URL=http://localhost:4444/groth16_vk.json -export ONCHAIN_KEYLESS_CONFIG_URL=http://localhost:4444/keyless_config.json -cargo run -p aptos-keyless-pepper-service -``` - -In terminal 1, peek the cached resources, they should currently give 404. -``` -curl -v http://localhost:8000/cached/groth16-vk -curl -v http://localhost:8000/cached/keyless-config -``` - -In terminal 2, mock the full node with a naive HTTP server. -```bash -cd keyless/pepper/service/resources -python3 -m http.server 4444 -``` - -Wait for 10 secs then go back to terminal 1 to retry the curl cmds. The cached data should be available. - -TODO: how to generate sample request and interact with `v0/verify` endpoint? diff --git a/keyless/pepper/scripts/install-deps.sh b/keyless/pepper/scripts/install-deps.sh deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/keyless/pepper/scripts/start-firestore-emulator.sh b/keyless/pepper/scripts/start-firestore-emulator.sh new file mode 100755 index 00000000000..4d966b6c9af --- /dev/null +++ b/keyless/pepper/scripts/start-firestore-emulator.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the required arguments are provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Port for Firestore emulator (the first argument to the script) +FIRESTORE_PORT=$1 + +# Start the Firestore emulator +gcloud emulators firestore start --host-port=localhost:${FIRESTORE_PORT} diff --git a/keyless/pepper/scripts/start-pepper-client-with-firestore.sh b/keyless/pepper/scripts/start-pepper-client-with-firestore.sh new file mode 100755 index 00000000000..e3676968b44 --- /dev/null +++ b/keyless/pepper/scripts/start-pepper-client-with-firestore.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the correct arguments are provided +if [ "$#" -ne 5 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Export the Firestore emulator host and port (passed as the first argument to the script) +export FIRESTORE_EMULATOR_HOST=$1 + +# Export the Google application credentials (passed as the second argument to the script). +# Note: this should point to the service account credential JSON file. +export GOOGLE_APPLICATION_CREDENTIALS=$2 + +# Fetch the Google Project ID, Firestore Database ID and Pepper Service URL from the script arguments +PEPPER_SERVICE_URL=$3 +GOOGLE_PROJECT_ID=$4 +FIRESTORE_DATABASE_ID=$5 + +# Start the pepper client example +echo "Starting the pepper client example with a Firestore emulator!" +cargo run -p aptos-keyless-pepper-example-client-rust -- --pepper-service-url=${PEPPER_SERVICE_URL} --firestore-google-project-id=${GOOGLE_PROJECT_ID} --firestore-database-id=${FIRESTORE_DATABASE_ID} diff --git a/keyless/pepper/scripts/start-pepper-client.sh b/keyless/pepper/scripts/start-pepper-client.sh new file mode 100755 index 00000000000..2d500c02b30 --- /dev/null +++ b/keyless/pepper/scripts/start-pepper-client.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the correct arguments are provided +if [ "$#" -ne 0 ]; then + echo "Usage: $0" + exit 1 +fi + +# Start the pepper client example +echo "Starting the pepper client example connecting to a local pepper service at http://localhost:8000!" +cargo run -p aptos-keyless-pepper-example-client-rust -- --pepper-service-url="http://localhost:8000" diff --git a/keyless/pepper/scripts/start-pepper-service-with-firestore.sh b/keyless/pepper/scripts/start-pepper-service-with-firestore.sh new file mode 100755 index 00000000000..6d89031e276 --- /dev/null +++ b/keyless/pepper/scripts/start-pepper-service-with-firestore.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the correct arguments are provided +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Export the Firestore emulator host and port (passed as the first argument to the script) +export FIRESTORE_EMULATOR_HOST=$1 + +# Export the Google application credentials (passed as the second argument to the script). +# Note: this should point to the service account credential JSON file. +export GOOGLE_APPLICATION_CREDENTIALS=$2 + +# Specify the account recovery DB location (passed as the third argument to the script). +GOOGLE_PROJECT_ID=$3 +FIRESTORE_DATABASE_ID='(default)' # the default name of a local firestore emulator + +# Specify an account manager (e.g., Google, Facebook, Apple). The example below is for Google. +export ACCOUNT_MANAGER_0_ISSUER=https://accounts.google.com +export ACCOUNT_MANAGER_0_AUD=407408718192.apps.googleusercontent.com + +# To specify more account managers, do the following: +# export ACCOUNT_MANAGER_1_ISSUER=https://www.facebook.com +# export ACCOUNT_MANAGER_1_AUD=999999999.apps.fbusercontent.com +# export ACCOUNT_MANAGER_2_ISSUER=https://appleid.apple.com +# export ACCOUNT_MANAGER_2_AUD=88888888.apps.appleusercontent.com + +# The VUF private key in hex format. This is a dummy key for testing purposes. +VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +# The expected VUF public key and derived pepper on startup. These are derived from the private key above. +EXPECTED_VUF_PUBKEY_ON_STARTUP=b601ec185c62da8f5c0402d4d4f987b63b06972c11f6f6f9d68464bda32fa502a5eac0adeda29917b6f8fa9bbe0f498209dcdb48d6a066c1f599c0502c5b4c24d4b057c758549e3e8a89ad861a82a789886d69876e6c6341f115c9ecc381eefd +EXPECTED_DERIVED_PEPPER_ON_STARTUP=72c147eb3457ec5ff32cc540e09ebe739a189b0b194fe269f18d29556dcc2f + +# The URLs for the on-chain keyless configuration and groth16 verification key (for local development, we use devnet) +ON_CHAIN_GROTH16_VK_URL=https://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey +ON_CHAIN_KEYLESS_CONFIG_URL=https://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Configuration + +# Start the pepper service +echo "Starting the pepper service with a Firestore emulator, connecting to Aptos devnet for on-chain data!" +cargo run -p aptos-keyless-pepper-service -- \ +--expected-derived-pepper-on-startup=${EXPECTED_DERIVED_PEPPER_ON_STARTUP} \ +--expected-vuf-pubkey-on-startup=${EXPECTED_VUF_PUBKEY_ON_STARTUP} \ +--google-project-id=${GOOGLE_PROJECT_ID} \ +--firestore-database-id=${FIRESTORE_DATABASE_ID} \ +--on-chain-groth16-vk-url=${ON_CHAIN_GROTH16_VK_URL} \ +--on-chain-keyless-config-url=${ON_CHAIN_KEYLESS_CONFIG_URL} \ +--vuf-private-key-seed-hex=${VUF_KEY_SEED_HEX} diff --git a/keyless/pepper/scripts/start-pepper-service.sh b/keyless/pepper/scripts/start-pepper-service.sh new file mode 100755 index 00000000000..d402002a48a --- /dev/null +++ b/keyless/pepper/scripts/start-pepper-service.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the correct arguments are provided +if [ "$#" -ne 0 ]; then + echo "Usage: $0" + exit 1 +fi + +# The VUF private key in hex format. This is a dummy key for testing purposes. +VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +# The expected VUF public key and derived pepper on startup. These are derived from the private key above. +EXPECTED_VUF_PUBKEY_ON_STARTUP=b601ec185c62da8f5c0402d4d4f987b63b06972c11f6f6f9d68464bda32fa502a5eac0adeda29917b6f8fa9bbe0f498209dcdb48d6a066c1f599c0502c5b4c24d4b057c758549e3e8a89ad861a82a789886d69876e6c6341f115c9ecc381eefd +EXPECTED_DERIVED_PEPPER_ON_STARTUP=72c147eb3457ec5ff32cc540e09ebe739a189b0b194fe269f18d29556dcc2f + +# The URLs for the on-chain keyless configuration and groth16 verification key (for local development, we use devnet) +ON_CHAIN_GROTH16_VK_URL=https://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey +ON_CHAIN_KEYLESS_CONFIG_URL=https://fullnode.devnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Configuration + +# Start the pepper service +echo "Starting the pepper service in local development mode, connecting to Aptos devnet for on-chain data!" +cargo run -p aptos-keyless-pepper-service -- \ +--local-development-mode \ +--expected-derived-pepper-on-startup=${EXPECTED_DERIVED_PEPPER_ON_STARTUP} \ +--expected-vuf-pubkey-on-startup=${EXPECTED_VUF_PUBKEY_ON_STARTUP} \ +--on-chain-groth16-vk-url=${ON_CHAIN_GROTH16_VK_URL} \ +--on-chain-keyless-config-url=${ON_CHAIN_KEYLESS_CONFIG_URL} \ +--vuf-private-key-seed-hex=${VUF_KEY_SEED_HEX} diff --git a/keyless/pepper/scripts/stop-firestore-emulator.sh b/keyless/pepper/scripts/stop-firestore-emulator.sh new file mode 100755 index 00000000000..319d04f2822 --- /dev/null +++ b/keyless/pepper/scripts/stop-firestore-emulator.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Exit immediately if a command fails +set -e + +# Check if the required arguments are provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Port for Firestore emulator (the first argument to the script) +FIRESTORE_PORT=$1 + +# Stop the Firestore emulator (by killing the process using the port) +lsof -t -i:${FIRESTORE_PORT} | xargs kill -9 diff --git a/keyless/pepper/service/Cargo.toml b/keyless/pepper/service/Cargo.toml index a5a321d5faa..af8058c2643 100644 --- a/keyless/pepper/service/Cargo.toml +++ b/keyless/pepper/service/Cargo.toml @@ -13,28 +13,31 @@ repository = { workspace = true } rust-version = { workspace = true } [dependencies] -aes-gcm = { workspace = true } anyhow = { workspace = true } +aptos-build-info = { workspace = true } aptos-crypto = { workspace = true } aptos-infallible = { workspace = true } aptos-inspection-service = { workspace = true } aptos-keyless-pepper-common = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } +aptos-time-service = { workspace = true } aptos-types = { workspace = true } -ark-bls12-381 = { workspace = true } ark-bn254 = { workspace = true } -ark-ec = { workspace = true } -ark-ff = { workspace = true } ark-groth16 = { workspace = true } ark-serialize = { workspace = true } +async-trait = { workspace = true } bcs = { workspace = true } -dashmap = { workspace = true } +blstrs = { workspace = true } +clap = { workspace = true } +dudect-bencher = { workspace = true } firestore = { workspace = true } hex = { workspace = true } hyper = { workspace = true } jsonwebtoken = { workspace = true } jwt = { workspace = true } +more-asserts = { workspace = true } +num-traits = { workspace = true } once_cell = { workspace = true } rand = { workspace = true } regex = { workspace = true } @@ -42,5 +45,9 @@ reqwest = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } sha3 = { workspace = true } +tempfile = { workspace = true } +thiserror = { workspace = true } tokio = { workspace = true } -uuid = { workspace = true } + +[dev-dependencies] +aptos-time-service = { workspace = true, features = ["testing"] } diff --git a/keyless/pepper/service/resources/groth16_vk.json b/keyless/pepper/service/resources/groth16_vk.json deleted file mode 100644 index 705f734f753..00000000000 --- a/keyless/pepper/service/resources/groth16_vk.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "0x1::keyless_account::Groth16VerificationKey", - "data": { - "alpha_g1": "0xe2f26dbea299f5223b646cb1fb33eadb059d9407559d7441dfd902e3a79a4d2d", - "beta_g2": "0xabb73dc17fbc13021e2471e0c08bd67d8401f52b73d6d07483794cad4778180e0c06f33bbc4c79a9cadef253a68084d382f17788f885c9afd176f7cb2f036789", - "delta_g2": "0xb106619932d0ef372c46909a2492e246d5de739aa140e27f2c71c0470662f125219049cfe15e4d140d7e4bb911284aad1cad19880efb86f2d9dd4b1bb344ef8f", - "gamma_abc_g1": [ - "0x6123b6fea40de2a7e3595f9c35210da8a45a7e8c2f7da9eb4548e9210cfea81a", - "0x32a9b8347c512483812ee922dc75952842f8f3083edb6fe8d5c3c07e1340b683" - ], - "gamma_g2": "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19" - } -} \ No newline at end of file diff --git a/keyless/pepper/service/resources/keyless_config.json b/keyless/pepper/service/resources/keyless_config.json deleted file mode 100644 index da097c690ef..00000000000 --- a/keyless/pepper/service/resources/keyless_config.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "0x1::keyless_account::Configuration", - "data": { - "max_commited_epk_bytes": 93, - "max_exp_horizon_secs": "10000000", - "max_extra_field_bytes": 350, - "max_iss_val_bytes": 120, - "max_jwt_header_b64_bytes": 300, - "max_signatures_per_txn": 3, - "override_aud_vals": [], - "training_wheels_pubkey": { - "vec": [ - "0x5cd926a700e3997a3b319bfd003127ec7278eff14973c8cdcfbea54f3ea3669f" - ] - } - } -} diff --git a/keyless/pepper/service/src/about.rs b/keyless/pepper/service/src/about.rs deleted file mode 100644 index 8baa091b3e7..00000000000 --- a/keyless/pepper/service/src/about.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use once_cell::sync::Lazy; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize)] -struct AboutInfo { - git_commit: String, -} - -pub static ABOUT_JSON: Lazy = Lazy::new(|| { - let obj = AboutInfo { - git_commit: std::env::var("GIT_COMMIT").unwrap_or_default(), - }; - serde_json::to_string_pretty(&obj).unwrap() -}); diff --git a/keyless/pepper/service/src/account_db.rs b/keyless/pepper/service/src/account_db.rs deleted file mode 100644 index d9dd3500702..00000000000 --- a/keyless/pepper/service/src/account_db.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_logger::warn; -use firestore::{FirestoreDb, FirestoreDbOptions, FirestoreResult}; -use once_cell::sync::Lazy; -use tokio::sync::OnceCell; - -/// A GCP firestore that holds all account address pre-images -pub static ACCOUNT_RECOVERY_DB: Lazy>> = - Lazy::new(OnceCell::new); - -pub async fn init_account_db() -> FirestoreResult { - let google_project_id = match std::env::var("PROJECT_ID") { - Ok(id) => id, - Err(e) => { - warn!("Could not load envvar `PROJECT_ID`: {e}"); - "unknown_project".to_string() - }, - }; - - let database_id = match std::env::var("DATABASE_ID") { - Ok(id) => id, - Err(e) => { - warn!("Could not load envvar `DATABASE_ID`: {e}"); - "unknown_database".to_string() - }, - }; - - let option = FirestoreDbOptions { - google_project_id, - database_id, - max_retries: 1, - firebase_api_url: None, - }; - FirestoreDb::with_options(option).await -} diff --git a/keyless/pepper/service/src/account_managers.rs b/keyless/pepper/service/src/account_managers.rs deleted file mode 100644 index 58844e1aba2..00000000000 --- a/keyless/pepper/service/src/account_managers.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_logger::info; -use once_cell::sync::Lazy; -use regex::Regex; -use std::{ - collections::{HashMap, HashSet}, - env, -}; - -/// If a pepper request v1 comes with a JWT from one of the priviliged auds, -/// aud overriding is allowed. -/// -/// ## How to use -/// For an account manager identified by issuer `` and client ID ``, -/// give it a unique short name `` and put the following as the environment variables. -/// `ACCOUNT_MANAGER__ISSUER= -/// `ACCOUNT_MANAGER__AUD= -/// -/// Multiple account managers can be specified, as long as their each have a unique short name. -/// -/// Here is an example command. -/// ```bash -/// ACCOUNT_MANAGER_1A_ISSUER=https://accounts.google.com \ -/// ACCOUNT_MANAGER_1A_AUD=1234567890 \ -/// ACCOUNT_MANAGER_2B_ISSUER=https://accounts.facebook.com \ -/// ACCOUNT_MANAGER_2B_AUD=9876543210 \ -/// VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \ -/// cargo run -p aptos-keyless-pepper-service -/// ``` -pub static ACCOUNT_MANAGERS: Lazy> = Lazy::new(|| { - let re_issuer = Regex::new(r"ACCOUNT_MANAGER_(\w+)_ISSUER").unwrap(); - let re_aud = Regex::new(r"ACCOUNT_MANAGER_(\w+)_AUD").unwrap(); - let mut working_set: HashMap = HashMap::new(); - - env::vars().for_each(|(key, val)| { - if let Some(caps) = re_issuer.captures(key.as_str()) { - let uid = caps.get(1).unwrap().as_str().to_string(); - working_set.entry(uid).or_default().set_issuer(val); - } else if let Some(caps) = re_aud.captures(key.as_str()) { - let uid = caps.get(1).unwrap().as_str().to_string(); - working_set.entry(uid).or_default().set_aud(val); - } - }); - - let ret: HashSet<(String, String)> = working_set - .values() - .cloned() - .filter_map(|collector| { - let Collector { issuer, aud } = collector; - if let (Some(issuer), Some(aud)) = (issuer, aud) { - Some((issuer, aud)) - } else { - None - } - }) - .collect(); - info!("ACCOUNT_MANAGERS={:?}", ret); - ret -}); - -#[derive(Clone, Default)] -struct Collector { - pub issuer: Option, - pub aud: Option, -} - -impl Collector { - fn set_issuer(&mut self, issuer: String) { - self.issuer = Some(issuer); - } - - fn set_aud(&mut self, aud: String) { - self.aud = Some(aud); - } -} diff --git a/keyless/pepper/service/src/accounts/account_managers.rs b/keyless/pepper/service/src/accounts/account_managers.rs new file mode 100644 index 00000000000..a4232614a43 --- /dev/null +++ b/keyless/pepper/service/src/accounts/account_managers.rs @@ -0,0 +1,107 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::PepperServiceError; +use aptos_logger::info; +use std::{collections::HashSet, env, str::FromStr}; + +/// A struct that holds all account recovery managers +pub struct AccountRecoveryManagers { + account_recovery_managers: HashSet, +} + +impl AccountRecoveryManagers { + pub fn new(account_recovery_managers: Vec) -> Self { + let mut account_recovery_managers_set = HashSet::new(); + + // Collect all account recovery managers + for account_recovery_manager in account_recovery_managers { + info!( + "Adding account recovery manager: issuer={}, aud={}.", + account_recovery_manager.issuer(), + account_recovery_manager.aud() + ); + account_recovery_managers_set.insert(account_recovery_manager); + } + + Self { + account_recovery_managers: account_recovery_managers_set, + } + } + + /// Creates an empty set of account recovery managers (used for testing) + #[cfg(test)] + pub fn new_empty() -> Self { + Self { + account_recovery_managers: HashSet::new(), + } + } + + /// Check if the given issuer and aud are in the set of account recovery managers + pub fn contains(&self, issuer: &str, aud: &str) -> bool { + // If there are no account recovery managers, return false + if self.account_recovery_managers.is_empty() { + return false; + } + + // Otherwise, check if the given issuer and aud are in the set + let account_recovery_manager = AccountRecoveryManager::new(issuer.into(), aud.into()); + self.account_recovery_managers + .contains(&account_recovery_manager) + } +} + +/// A struct that represents an account recovery manager +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct AccountRecoveryManager { + issuer: String, + aud: String, +} + +impl AccountRecoveryManager { + pub fn new(issuer: String, aud: String) -> Self { + Self { issuer, aud } + } + + /// Get the issuer of the account manager + pub fn issuer(&self) -> String { + self.issuer.clone() + } + + /// Get the aud of the account manager + pub fn aud(&self) -> String { + self.aud.clone() + } +} + +impl FromStr for AccountRecoveryManager { + type Err = PepperServiceError; + + // Note: this is used to parse each account recovery manager from + // the command line. The expected format is: " ". + fn from_str(string: &str) -> Result { + // Split the string by whitespace + let mut iterator = string.split_whitespace(); + + // Parse the substrings as issuer and aud + let issuer = iterator.next().ok_or(PepperServiceError::UnexpectedError( + "Failed to parse issuer for account recovery manager!".into(), + ))?; + let aud = iterator.next().ok_or(PepperServiceError::UnexpectedError( + "Failed to parse aud for account recovery manager!".into(), + ))?; + + // Verify that there are exactly 2 substrings + if iterator.next().is_some() { + return Err(PepperServiceError::UnexpectedError( + "Too many arguments found for account recovery manager!".into(), + )); + } + + // Create the override + let account_manager_override = + AccountRecoveryManager::new(issuer.to_string(), aud.to_string()); + + Ok(account_manager_override) + } +} diff --git a/keyless/pepper/service/src/accounts/account_recovery_db.rs b/keyless/pepper/service/src/accounts/account_recovery_db.rs new file mode 100644 index 00000000000..b4007b7ca99 --- /dev/null +++ b/keyless/pepper/service/src/accounts/account_recovery_db.rs @@ -0,0 +1,247 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{error::PepperServiceError, metrics}; +use aptos_infallible::duration_since_epoch; +use aptos_keyless_pepper_common::{account_recovery_db::AccountRecoveryDbEntry, PepperInput}; +use aptos_logger::{error, info}; +use firestore::{path, paths, FirestoreDb, FirestoreDbOptions}; +use std::{io::Write, time::Instant}; +use tempfile::NamedTempFile; + +// Firestore DB transaction constants +const FIRESTORE_DB_COLLECTION_ID: &str = "accounts"; + +/// A generic interface for the account recovery database +#[async_trait::async_trait] +pub trait AccountRecoveryDBInterface { + /// Updates the account recovery database with the given pepper input + async fn update_db_with_pepper_input( + &self, + pepper_input: &PepperInput, + ) -> Result<(), PepperServiceError>; +} + +/// A GCP firestore that holds all account recovery data +pub struct FirestoreAccountRecoveryDB { + /// Whether to disable async DB updates (e.g., for testing purposes) + disable_async_db_updates: bool, + + /// The Firestore DB instance + firestore_db: FirestoreDb, +} + +impl FirestoreAccountRecoveryDB { + pub async fn new( + google_project_id: String, + firestore_database_id: String, + disable_async_db_updates: bool, + ) -> Self { + // Create the FirestoreDB options + let firestore_db_options = FirestoreDbOptions { + google_project_id, + database_id: firestore_database_id, + max_retries: 1, + firebase_api_url: None, + }; + + // Create the FirestoreDB instance + match FirestoreDb::with_options(firestore_db_options).await { + Ok(firestore_db) => Self { + disable_async_db_updates, + firestore_db, + }, + Err(error) => { + panic!( + "Failed to create Firestore account recovery database! Error: {}", + error + ); + }, + } + } +} + +#[async_trait::async_trait] +impl AccountRecoveryDBInterface for FirestoreAccountRecoveryDB { + async fn update_db_with_pepper_input( + &self, + pepper_input: &PepperInput, + ) -> Result<(), PepperServiceError> { + let firestore_db = self.firestore_db.clone(); + let pepper_input = pepper_input.clone(); + + // Create the DB update task + let db_update_task = async move { + // Start the db update timer + let db_update_timer = Instant::now(); + + // Update the firestore DB + let update_result = + update_firestore_with_pepper_input(firestore_db, pepper_input.clone()).await; + if let Err(error) = &update_result { + error!( + "Failed to update the firestore database for pepper input: {:?}! Error: {:?}", + pepper_input, error + ); + } + + // Update the write metrics + metrics::update_account_recovery_db_metrics(update_result.is_ok(), db_update_timer); + + update_result + }; + + // Run the DB update task + if self.disable_async_db_updates { + db_update_task.await // Run the task and wait for the result + } else { + tokio::spawn(db_update_task); // Run the task asynchronously + Ok(()) + } + } +} + +/// A test implementation of the account recovery database. Internally, the +/// DB is represented as a temporary file, with each line being a single JSON entry. +pub struct TestAccountRecoveryDB { + temp_file: NamedTempFile, +} + +impl TestAccountRecoveryDB { + pub fn new() -> Self { + // Open the temporary file + let temp_file = match NamedTempFile::new() { + Ok(file) => file, + Err(error) => panic!("Failed to create temp file! Error: {}", error), + }; + + // Print the temporary file path + let temp_file_path = temp_file.path().to_str().unwrap().to_string(); + info!( + "Created temporary account recovery DB at {}", + temp_file_path + ); + + Self { temp_file } + } +} + +#[async_trait::async_trait] +impl AccountRecoveryDBInterface for TestAccountRecoveryDB { + async fn update_db_with_pepper_input( + &self, + pepper_input: &PepperInput, + ) -> Result<(), PepperServiceError> { + // Format the pepper input as a JSON line + let json_line = match serde_json::to_string(pepper_input) { + Ok(json) => json, + Err(error) => { + return Err(PepperServiceError::InternalError(format!( + "Failed to serialize pepper input {:?} to JSON! Error: {}", + pepper_input, error + ))); + }, + }; + + // Write the JSON line to the temporary file + writeln!(&self.temp_file, "{}", json_line).map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to write pepper input {:?} to temp file! Error: {}", + pepper_input, error + )) + }) + } +} + +impl Default for TestAccountRecoveryDB { + fn default() -> Self { + Self::new() + } +} + +/// Updates the firestore DB with the given pepper input +async fn update_firestore_with_pepper_input( + firestore_db: FirestoreDb, + pepper_input: PepperInput, +) -> Result<(), PepperServiceError> { + // Create the database entry and get the document ID + let entry = AccountRecoveryDbEntry { + iss: pepper_input.iss.clone(), + aud: pepper_input.aud.clone(), + uid_key: pepper_input.uid_key.clone(), + uid_val: pepper_input.uid_val.clone(), + first_request_unix_ms_minus_1q: None, + last_request_unix_ms: None, + num_requests: None, + }; + let document_id = entry.document_id(); + + // Get the time now + let now_unix_ms = duration_since_epoch().as_millis() as i64; + + // To update the DB, we use the following strategy: + // 1. If the document doesn't exist, create the document for the user identifier `(iss, aud, uid_key, uid_val)`, + // but leave counter/time fields unspecified. + // 2. `num_requests += 1`, assuming the default value is 0. + // 3. `last_request_unix_ms = max(last_request_unix_ms, now)`, assuming the default value is 0. + // 4. `first_request_unix_ms = min(first_request_unix_ms, now)`, assuming the default value is +inf. + // + // This strategy is preferred because all the operations can be done on the server-side, + // which means the transaction should require only 1 RTT (this is better than using + // the read-compute-write pattern that requires 2 RTTs). + // + // Note: this strategy requires some modifications: + // - In firestore, the default value of a number field is 0, and we do not have a way to customize it for step 4. + // - The workaround here is to apply an offset so 0 becomes a legitimate default value. + // - So we work with `first_request_unix_ms_minus_1q` instead, which is defined as + // `first_request_unix_ms - 1_000_000_000_000_000`, where 1_000_000_000_000_000 milliseconds is roughly 31710 years. + + // Create the firestore DB transaction + let mut firestore_transaction = firestore_db.begin_transaction().await.map_err(|error| { + PepperServiceError::InternalError(format!( + "Firestore DB begin_transaction() error: {}", + error + )) + })?; + firestore_db + .fluent() + .update() + .fields(paths!(AccountRecoveryDbEntry::{iss, aud, uid_key, uid_val})) + .in_col(FIRESTORE_DB_COLLECTION_ID) + .document_id(&document_id) + .object(&entry) // Step 1 + .transforms(|builder| { + builder.fields([ + builder + .field(path!(AccountRecoveryDbEntry::num_requests)) + .increment(1), // Step 2 + builder + .field(path!(AccountRecoveryDbEntry::last_request_unix_ms)) + .maximum(now_unix_ms), // Step 3 + builder + .field(path!( + AccountRecoveryDbEntry::first_request_unix_ms_minus_1q + )) + .minimum(now_unix_ms - 1_000_000_000_000_000), // Step 4 + ]) + }) + .add_to_transaction(&mut firestore_transaction) + .map_err(|error| { + PepperServiceError::InternalError(format!( + "Firestore DB add_to_transaction() error: {}", + error + )) + })?; + + // Commit the DB transaction + match firestore_transaction.commit().await { + Ok(_) => Ok(()), + Err(error) => { + let error_message = format!( + "Failed to commit Firestore DB transaction for pepper input {:?}! Document ID {}, Error: {}", + pepper_input, document_id, error + ); + Err(PepperServiceError::InternalError(error_message)) + }, + } +} diff --git a/keyless/pepper/service/src/accounts/mod.rs b/keyless/pepper/service/src/accounts/mod.rs new file mode 100644 index 00000000000..f808f76e634 --- /dev/null +++ b/keyless/pepper/service/src/accounts/mod.rs @@ -0,0 +1,5 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod account_managers; +pub mod account_recovery_db; diff --git a/keyless/pepper/service/src/dedicated_handlers/handlers.rs b/keyless/pepper/service/src/dedicated_handlers/handlers.rs new file mode 100644 index 00000000000..4a19cade2e7 --- /dev/null +++ b/keyless/pepper/service/src/dedicated_handlers/handlers.rs @@ -0,0 +1,478 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + accounts::{ + account_managers::AccountRecoveryManagers, account_recovery_db::AccountRecoveryDBInterface, + }, + dedicated_handlers::pepper_request::handle_pepper_request, + error::PepperServiceError, + external_resources::{jwk_fetcher, jwk_fetcher::JWKCache, resource_fetcher::CachedResources}, + vuf_keypair::VUFKeypair, +}; +use aptos_crypto::ed25519::Ed25519PublicKey; +use aptos_keyless_pepper_common::{ + PepperRequest, PepperRequestV2, PepperRequestWithAudOverride, PepperResponse, + SignatureResponse, VerifyRequest, VerifyResponse, +}; +use aptos_types::{ + jwks::rsa::RSA_JWK, + keyless::{ + get_public_inputs_hash, Configuration, EphemeralCertificate, Groth16ProofAndStatement, + KeylessPublicKey, KeylessSignature, ZeroKnowledgeSig, ZKP, + }, + transaction::authenticator::{AnyPublicKey, AnySignature, EphemeralPublicKey}, +}; +use ark_bn254::Fr; +use firestore::async_trait; +use std::{ + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, +}; + +/// A generic handler trait for processing requests and producing responses +#[async_trait] +pub trait HandlerTrait: Send + Sync { + /// Returns the name of the handler (e.g., the type name). This is useful for logging. + fn get_handler_name(&self) -> &'static str { + std::any::type_name::() + } + + // TODO: is there a way we can remove the vuf_private_key param here? + async fn handle_request( + &self, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request: TRequest, + account_recovery_managers: Arc, + account_recovery_db: Arc, + ) -> Result; +} + +/// A handler for processing pepper fetch requests +pub struct V0DelegatedFetchHandler; + +#[async_trait] +impl HandlerTrait for V0DelegatedFetchHandler { + async fn handle_request( + &self, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request: PepperRequestV2, + account_recovery_managers: Arc, + account_recovery_db: Arc, + ) -> Result { + // Parse the request + let PepperRequestWithAudOverride { + aud_override, + pepper_request, + } = request.get_request_with_aud_override(); + let PepperRequest { + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + } = pepper_request; + + // Fetch the pepper + let (_pepper_base, pepper, address) = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + account_recovery_managers, + Some(aud_override), + account_recovery_db, + ) + .await?; + + // Return the pepper response + Ok(PepperResponse { + pepper, + address: address.to_vec(), + }) + } +} + +/// A handler for processing pepper fetch requests +pub struct V0FetchHandler; + +#[async_trait] +impl HandlerTrait for V0FetchHandler { + async fn handle_request( + &self, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request: PepperRequest, + account_recovery_managers: Arc, + account_recovery_db: Arc, + ) -> Result { + // Parse the request + let PepperRequest { + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + } = request; + + // Fetch the pepper + let (_pepper_base, pepper, address) = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + account_recovery_managers, + None, + account_recovery_db, + ) + .await?; + + // Return the pepper response + Ok(PepperResponse { + pepper, + address: address.to_vec(), + }) + } +} + +/// A handler for processing signature requests +pub struct V0SignatureHandler; + +#[async_trait] +impl HandlerTrait for V0SignatureHandler { + async fn handle_request( + &self, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request: PepperRequest, + account_recovery_managers: Arc, + account_recovery_db: Arc, + ) -> Result { + // Parse the request + let PepperRequest { + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + } = request; + + // Fetch the pepper base (i.e., VUF signature) + let (pepper_base, _pepper, _address) = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + epk, + exp_date_secs, + epk_blinder, + uid_key, + derivation_path, + account_recovery_managers, + None, + account_recovery_db, + ) + .await?; + + // Return the signature response + Ok(SignatureResponse { + signature: pepper_base, + }) + } +} + +/// A handler for processing signature verification requests. +// TODO: see if we should remove this endpoint. +pub struct V0VerifyHandler; + +#[async_trait] +impl HandlerTrait for V0VerifyHandler { + async fn handle_request( + &self, + _: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request: VerifyRequest, + _account_recovery_managers: Arc, + _account_recovery_db: Arc, + ) -> Result { + // Parse the request + let VerifyRequest { + public_key, + signature, + message, + address: _, // TODO: what should we do with the address field? + } = request; + + // Fetch the keyless public key and signature from the request + let (keyless_public_key, keyless_signature) = match (&public_key, &signature) { + (AnyPublicKey::Keyless { public_key }, AnySignature::Keyless { signature }) => { + (public_key, signature) + }, + (any_public_key, any_signature) => { + return Err(PepperServiceError::BadRequest(format!( + "Unsupported public key or signature types for keyless verify request: {:?}, {:?}", + any_public_key, any_signature + ))); + }, + }; + + // Verify the expiry time of the keyless signature + verify_signature_expiry(keyless_signature)?; + + // Verify the signature over the message + verify_message_signature(&message, keyless_signature)?; + + // Get the keyless configuration and training wheels public key + let (keyless_config, training_wheels_pubkey) = + get_keyless_config_and_training_wheels_pubkey(&cached_resources)?; + + // Get the zero knowledge signature from the certificate + let zero_knowledge_signature = get_zero_knowledge_signature(keyless_signature)?; + + // Verify the expiration horizon + if zero_knowledge_signature.exp_horizon_secs > keyless_config.max_exp_horizon_secs { + return Err(PepperServiceError::BadRequest(format!( + "The expiration horizon is too long: {} seconds (max allowed: {} seconds)", + zero_knowledge_signature.exp_horizon_secs, keyless_config.max_exp_horizon_secs + ))); + } + + // Verify the override aud value + if let Some(override_aud_val) = &zero_knowledge_signature.override_aud_val { + keyless_config + .is_allowed_override_aud(override_aud_val) + .map_err(|error| { + PepperServiceError::BadRequest(format!( + "The given override aud value is not allowed: {}. Error: {}", + override_aud_val, error + )) + })?; + } + + // Verify the training wheels signature + let public_inputs_hash = verify_training_wheels_signature( + &jwk_cache, + keyless_public_key, + keyless_signature, + &zero_knowledge_signature, + &keyless_config, + training_wheels_pubkey, + )?; + + // Verify the groth16 proof in the zero knowledge signature + verify_groth16_proof( + cached_resources, + zero_knowledge_signature, + public_inputs_hash, + )?; + + // All verifications passed + Ok(VerifyResponse { success: true }) + } +} + +/// Retrieves the keyless configuration and training wheels public key +fn get_keyless_config_and_training_wheels_pubkey( + cached_resources: &CachedResources, +) -> Result<(Configuration, Option), PepperServiceError> { + // Get the keyless configuration + let on_chain_keyless_config = cached_resources + .read_on_chain_keyless_configuration() + .ok_or_else(|| { + PepperServiceError::InternalError( + "On-chain keyless config not cached locally.".to_string(), + ) + })?; + let configuration = on_chain_keyless_config + .get_keyless_configuration() + .map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to parse on-chain keyless config: {}", + error + )) + })?; + + // Extract the training wheels public key + let training_wheels_pubkey = match &configuration.training_wheels_pubkey { + // This takes ~4.4 microseconds, so we are not too concerned about speed here. + // (Run `cargo bench -- ed25519/pk_deserialize` in `crates/aptos-crypto`.) + Some(public_key_bytes) => Some(EphemeralPublicKey::ed25519( + Ed25519PublicKey::try_from(public_key_bytes.as_slice()).map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to parse on-chain training wheels public key: {}", + error + )) + })?, + )), + None => None, + }; + + Ok((configuration, training_wheels_pubkey)) +} + +/// Fetches the RSA JWK for the given keyless public key and signature +fn get_rsa_jwk( + keyless_public_key: &KeylessPublicKey, + keyless_signature: &KeylessSignature, + jwk_cache: JWKCache, +) -> Result, PepperServiceError> { + let KeylessPublicKey { idc: _, iss_val } = keyless_public_key; + let jwt_header = keyless_signature.parse_jwt_header().map_err(|error| { + PepperServiceError::BadRequest(format!( + "Failed to decode JWT header from signature: {}", + error + )) + })?; + jwk_fetcher::get_cached_jwk_as_rsa(iss_val, &jwt_header.kid, jwk_cache).map_err(|error| { + PepperServiceError::BadRequest(format!("Failed to get RSA JWK from cache: {}", error)) + }) +} + +/// Extracts the zero knowledge signature from the keyless signature +fn get_zero_knowledge_signature( + keyless_signature: &KeylessSignature, +) -> Result { + let KeylessSignature { cert, .. } = keyless_signature; + match cert { + EphemeralCertificate::ZeroKnowledgeSig(zero_knowledge_sig) => { + Ok(zero_knowledge_sig.clone()) + }, + certificate => Err(PepperServiceError::BadRequest(format!( + "Unsupported certificate type for keyless verify request: {:?}", + certificate + ))), + } +} + +/// Verifies the groth16 proof in the zero knowledge signature +fn verify_groth16_proof( + cached_resources: CachedResources, + zero_knowledge_sig: ZeroKnowledgeSig, + public_inputs_hash: Fr, +) -> Result<(), PepperServiceError> { + // Get the groth16 verification key from cached resources + let onchain_groth16_vk = cached_resources.read_on_chain_groth16_vk().ok_or_else(|| { + PepperServiceError::InternalError("Failed to read groth16 VK from cached resources.".into()) + })?; + let ark_groth16_pvk = onchain_groth16_vk + .to_ark_prepared_verifying_key() + .map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to convert on-chain groth16 VK to Ark format: {}", + error + )) + })?; + + // Verify the groth16 proof + zero_knowledge_sig + .verify_groth16_proof(public_inputs_hash, &ark_groth16_pvk) + .map_err(|error| { + PepperServiceError::BadRequest(format!("Groth16 proof verification failed: {}", error)) + })?; + Ok(()) +} + +/// Verifies the signature over the provided message using the ephemeral public key and signature +fn verify_message_signature( + message: &[u8], + keyless_signature: &KeylessSignature, +) -> Result<(), PepperServiceError> { + let KeylessSignature { + cert: _, + jwt_header_json: _, + exp_date_secs: _, + ephemeral_pubkey, + ephemeral_signature, + } = keyless_signature; + + ephemeral_signature + .verify_arbitrary_msg(message, ephemeral_pubkey) + .map_err(|error| { + PepperServiceError::BadRequest(format!( + "Message signature verification failed: {}", + error + )) + }) +} + +/// Verifies that the keyless signature has not expired +fn verify_signature_expiry(signature: &KeylessSignature) -> Result<(), PepperServiceError> { + let current_time_microseconds = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_micros() as u64; + + signature + .verify_expiry(current_time_microseconds) + .map_err(|error| { + PepperServiceError::BadRequest(format!( + "Signature expiry verification failed: {}", + error + )) + }) +} + +/// Verifies the training wheels signature (if applicable) and returns the public inputs hash +fn verify_training_wheels_signature( + jwk_cache: &JWKCache, + keyless_public_key: &KeylessPublicKey, + keyless_signature: &KeylessSignature, + zero_knowledge_sig: &ZeroKnowledgeSig, + keyless_config: &Configuration, + training_wheels_pubkey: Option, +) -> Result { + // Get the public inputs hash + let rsa_jwk = get_rsa_jwk(keyless_public_key, keyless_signature, jwk_cache.clone())?; + let public_inputs_hash = get_public_inputs_hash( + keyless_signature, + keyless_public_key, + &rsa_jwk, + keyless_config, + ) + .map_err(|error| { + PepperServiceError::BadRequest(format!("Failed to compute public inputs hash: {}", error)) + })?; + + // Verify the training wheels signature + if let Some(training_wheels_pubkey) = &training_wheels_pubkey { + if let Some(training_wheels_signature) = &zero_knowledge_sig.training_wheels_signature { + let ZKP::Groth16(groth16proof) = &zero_knowledge_sig.proof; + let groth16_proof_and_statement = + Groth16ProofAndStatement::new(*groth16proof, public_inputs_hash); + training_wheels_signature + .verify(&groth16_proof_and_statement, training_wheels_pubkey) + .map_err(|error| { + PepperServiceError::BadRequest(format!( + "Could not verify training wheels signature: {}", + error, + )) + })?; + } else { + return Err(PepperServiceError::BadRequest( + "Training wheels signature expected but it is missing".into(), + )); + } + } + + Ok(public_inputs_hash) +} diff --git a/keyless/pepper/service/src/dedicated_handlers/mod.rs b/keyless/pepper/service/src/dedicated_handlers/mod.rs new file mode 100644 index 00000000000..8f132e5256e --- /dev/null +++ b/keyless/pepper/service/src/dedicated_handlers/mod.rs @@ -0,0 +1,5 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod handlers; +pub mod pepper_request; diff --git a/keyless/pepper/service/src/dedicated_handlers/pepper_request.rs b/keyless/pepper/service/src/dedicated_handlers/pepper_request.rs new file mode 100644 index 00000000000..780cc579d3e --- /dev/null +++ b/keyless/pepper/service/src/dedicated_handlers/pepper_request.rs @@ -0,0 +1,759 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + accounts::{ + account_managers::AccountRecoveryManagers, account_recovery_db::AccountRecoveryDBInterface, + }, + error::PepperServiceError, + external_resources::{jwk_fetcher, jwk_fetcher::JWKCache, resource_fetcher::CachedResources}, + metrics, + vuf_keypair::VUFKeypair, +}; +use aptos_keyless_pepper_common::{ + jwt::Claims, + vuf::{ + self, + bls12381_g1_bls::PinkasPepper, + slip_10, + slip_10::{DerivationPath, ExtendedPepper}, + VUF, + }, + PepperInput, +}; +use aptos_logger::info; +use aptos_types::{ + account_address::AccountAddress, + keyless::{Configuration, IdCommitment, KeylessPublicKey, OpenIdSig, Pepper}, + transaction::authenticator::{AnyPublicKey, AuthenticationKey, EphemeralPublicKey}, +}; +use jsonwebtoken::{Algorithm::RS256, DecodingKey, TokenData, Validation}; +use std::{ + sync::Arc, + time::{Instant, SystemTime, UNIX_EPOCH}, +}; + +// The default derivation path (if none is provided) +const DEFAULT_DERIVATION_PATH: &str = "m/44'/637'/0'/0'/0'"; + +// The default uid key (if none is provided) +const DEFAULT_UID_KEY: &str = "sub"; + +// The sub uid key string +const SUB_UID_KEY: &str = "sub"; + +// The email uid key string +const EMAIL_UID_KEY: &str = "email"; + +/// Handles the given pepper request, returning the pepper base, pepper and account address +pub async fn handle_pepper_request( + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + jwt: String, + ephemeral_public_key: EphemeralPublicKey, + exp_date_secs: u64, + epk_blinder: Vec, + uid_key: Option, + derivation_path: Option, + account_recovery_managers: Arc, + aud_override: Option, + account_recovery_db: Arc, +) -> Result<(Vec, Vec, AccountAddress), PepperServiceError> { + // Get the on-chain keyless configuration + let keyless_configuration = get_on_chain_keyless_configuration(cached_resources)?; + + // Parse the JWT (without signature verification) + let claims = aptos_keyless_pepper_common::jwt::parse(jwt.as_str()) + .map_err(|e| PepperServiceError::BadRequest(format!("JWT decoding error: {e}")))?; + + // Verify the public key expiry date + verify_public_key_expiry_date_secs(exp_date_secs, &claims, &keyless_configuration)?; + + // Verify the oauth nonce + verify_oath_nonce( + &ephemeral_public_key, + exp_date_secs, + epk_blinder, + &claims, + &keyless_configuration, + )?; + + // Verify the JWT signature + verify_jwt_signature(jwk_cache, &jwt, &claims).await?; + + // Get the uid key and value + let (uid_key, uid_val) = get_uid_key_and_value(uid_key, &claims)?; + + // Create the pepper input + let pepper_input = create_pepper_input( + &claims, + uid_key, + uid_val, + account_recovery_managers, + aud_override, + account_recovery_db, + ) + .await?; + + // Derive the pepper base, pepper bytes and account address. + // Note: we do this using spawn_blocking() to avoid blocking the async runtime. + let (pepper_base, derived_pepper_bytes, address) = tokio::task::spawn_blocking(move || { + // Start the derivation timer + let derivation_start_time = Instant::now(); + + // Derive the pepper and account address + let derivation_result = + derive_pepper_and_account_address(vuf_keypair, derivation_path, &pepper_input); + + // Update the derivation metrics + metrics::update_pepper_derivation_metrics(derivation_result.is_ok(), derivation_start_time); + + derivation_result + }) + .await??; + + // Return the pepper base, derived pepper and address + Ok((pepper_base, derived_pepper_bytes, address)) +} + +/// Creates the account address using the pepper input and the derived pepper +fn create_account_address( + pepper_input: &PepperInput, + derived_pepper: &Pepper, +) -> Result { + let id_commitment = IdCommitment::new_from_preimage( + derived_pepper, + &pepper_input.aud, + &pepper_input.uid_key, + &pepper_input.uid_val, + ) + .map_err(|error| { + PepperServiceError::InternalError(format!("Failed to create id commitment: {}", error)) + })?; + let public_key = KeylessPublicKey { + iss_val: pepper_input.iss.clone(), + idc: id_commitment, + }; + let address = AuthenticationKey::any_key(AnyPublicKey::keyless(public_key)).account_address(); + + Ok(address) +} + +/// Creates the pepper base using the VUF private key and the pepper input +fn create_pepper_base( + vuf_keypair: Arc, + pepper_input: &PepperInput, +) -> Result, PepperServiceError> { + // Serialize the pepper input using BCS + let input_bytes = bcs::to_bytes(&pepper_input).map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to serialize pepper input! Error: {:?}", + error + )) + })?; + + // Generate the pepper base and proof using the VUF + let (pepper_base, vuf_proof) = + vuf::bls12381_g1_bls::Bls12381G1Bls::eval(vuf_keypair.vuf_private_key(), &input_bytes) + .map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to evaluate bls12381_g1_bls VUF: {}", + error + )) + })?; + + // Verify that the proof is empty + if !vuf_proof.is_empty() { + return Err(PepperServiceError::InternalError( + "The VUF proof is not empty! This shouldn't happen.".to_string(), + )); + } + + // Verify the pepper base output (this ensures we only ever return valid outputs, + // and protects against various security issues, e.g., fault based side channels). + vuf::bls12381_g1_bls::Bls12381G1Bls::verify( + vuf_keypair.vuf_public_key(), + &input_bytes, + &pepper_base, + &vuf_proof, + ) + .map_err(|error| { + PepperServiceError::InternalError(format!("VUF verification failed: {}", error)) + })?; + + Ok(pepper_base) +} + +/// Creates the pepper input, and updates the account recovery DB +async fn create_pepper_input( + claims: &TokenData, + uid_key: String, + uid_val: String, + account_recovery_managers: Arc, + aud_override: Option, + account_recovery_db: Arc, +) -> Result { + let iss = claims.claims.iss.clone(); + let claims_aud = claims.claims.aud.clone(); + + // Get the aud for the pepper input. Note: if the request is from an account + // recovery manager, we will override the aud and generate the pepper input + // with the overridden aud. This is useful for pepper recovery. + let aud = if account_recovery_managers.contains(&iss, &claims_aud) { + match aud_override { + Some(aud_override) => aud_override, // Use the overridden aud + None => { + return Err(PepperServiceError::UnexpectedError(format!( + "The issuer {} and aud {} correspond to an account recovery manager, but no aud override was provided!", + &iss, &claims_aud + ))); + }, + } + } else if let Some(aud_override) = aud_override { + return Err(PepperServiceError::UnexpectedError(format!( + "The issuer {} and aud {} do not correspond to an account recovery manager, but an aud override was provided: {}!", + &iss, &claims_aud, &aud_override + ))); + } else { + claims_aud // Use the aud directly from the claims + }; + + // Create the pepper input + let pepper_input = PepperInput { + iss, + uid_key, + uid_val, + aud, + }; + info!("Successfully created PepperInput: {:?}", &pepper_input); + + // Update the account recovery DB + account_recovery_db + .update_db_with_pepper_input(&pepper_input) + .await?; + + Ok(pepper_input) +} + +/// Derives the pepper using the verified derivation path and the pepper base +fn derive_pepper( + verified_derivation_path: &DerivationPath, + pepper_base: &[u8], +) -> Result { + let pinkas_pepper = PinkasPepper::from_affine_bytes(pepper_base).map_err(|error| { + PepperServiceError::InternalError(format!("Failed to create pinkas pepper: {}", error)) + })?; + let derived_pepper = ExtendedPepper::from_seed(pinkas_pepper.to_master_pepper().to_bytes()) + .map_err(|error| PepperServiceError::InternalError(error.to_string()))? + .derive(&verified_derivation_path) + .map_err(|error| PepperServiceError::InternalError(error.to_string()))? + .get_pepper(); + + Ok(derived_pepper) +} + +/// Derives the pepper base, pepper bytes and account address +pub fn derive_pepper_and_account_address( + vuf_keypair: Arc, + derivation_path: Option, + pepper_input: &PepperInput, +) -> Result<(Vec, Vec, AccountAddress), PepperServiceError> { + // Create the pepper base using the vuf private key and the pepper input + let pepper_base = create_pepper_base(vuf_keypair, pepper_input)?; + + // Derive the pepper using the verified derivation path and the pepper base + let verified_derivation_path = get_verified_derivation_path(derivation_path)?; + let derived_pepper = derive_pepper(&verified_derivation_path, &pepper_base)?; + let derived_pepper_bytes = derived_pepper.to_bytes().to_vec(); + + // Create the account address + let address = create_account_address(pepper_input, &derived_pepper)?; + + Ok((pepper_base, derived_pepper_bytes, address)) +} + +/// Returns the on-chain keyless configuration from the cached resources +fn get_on_chain_keyless_configuration( + cached_resources: CachedResources, +) -> Result { + let on_chain_keyless_configuration = cached_resources + .read_on_chain_keyless_configuration() + .ok_or_else(|| { + PepperServiceError::InternalError( + "Failed to read on-chain keyless configuration".to_string(), + ) + })?; + on_chain_keyless_configuration + .get_keyless_configuration() + .map_err(|error| { + PepperServiceError::InternalError(format!( + "Failed to get keyless configuration: {error}" + )) + }) +} + +/// Returns the uid key and value from the claims +fn get_uid_key_and_value( + uid_key: Option, + claims: &TokenData, +) -> Result<(String, String), PepperServiceError> { + // If `uid_key` is missing, use `sub` as the default + let uid_key = match uid_key { + Some(uid_key) => uid_key, + None => { + return Ok((DEFAULT_UID_KEY.into(), claims.claims.sub.clone())); + }, + }; + + // If the uid_key is "sub", return the sub claim value + if uid_key == SUB_UID_KEY { + return Ok((uid_key, claims.claims.sub.clone())); + } + + // Otherwise, check if the uid_key is an email + if uid_key == EMAIL_UID_KEY { + let uid_value = claims.claims.email.clone().ok_or_else(|| { + PepperServiceError::BadRequest(format!( + "The {} uid_key was specified, but the email claim was not found in the JWT", + EMAIL_UID_KEY + )) + })?; + return Ok((uid_key, uid_value)); + } + + // Otherwise, an unsupported uid_key was specified + Err(PepperServiceError::BadRequest(format!( + "Unsupported uid key provided: {}", + uid_key + ))) +} + +/// Returns the verified derivation path +fn get_verified_derivation_path( + derivation_path: Option, +) -> Result { + // Get the derivation path or use the default + let derivation_path = derivation_path.unwrap_or(DEFAULT_DERIVATION_PATH.into()); + + // Verify the derivation path + slip_10::get_aptos_derivation_path(&derivation_path).map_err(|error| { + PepperServiceError::BadRequest(format!("Invalid derivation path: {}", error)) + }) +} + +/// Verifies the JWT signature using the cached JWKs, or fetches the federated JWK if not found in cache +async fn verify_jwt_signature( + jwk_cache: JWKCache, + jwt: &str, + claims: &TokenData, +) -> Result<(), PepperServiceError> { + // Get the key ID from the JWT header + let key_id = claims + .header + .kid + .clone() + .ok_or_else(|| PepperServiceError::BadRequest("Missing kid in JWT".to_string()))?; + + // Get the JWK from the cache, or fetch the federated JWK if not found + let rsa_jwk = match jwk_fetcher::get_cached_jwk_as_rsa(&claims.claims.iss, &key_id, jwk_cache) { + Ok(rsa_jwk) => rsa_jwk, + Err(error) => { + info!("Failed to get cached JWK for issuer {} and key ID {}: {}. Attempting to fetch federated JWK.", &claims.claims.iss, &key_id, error); + jwk_fetcher::get_federated_jwk(jwt).await.map_err(|error| { + PepperServiceError::BadRequest(format!( + "Failed to fetch federated JWK: {}. JWT: {}", + error, jwt + )) + })? + }, + }; + let jwk_decoding_key = + DecodingKey::from_rsa_components(&rsa_jwk.n, &rsa_jwk.e).map_err(|error| { + PepperServiceError::BadRequest(format!( + "Failed to create decoding key from JWK: {}", + error + )) + })?; + + // Validate the JWT signature. + // TODO: can we avoid decoding the JWT twice? + let mut validation_with_sig_verification = Validation::new(RS256); + validation_with_sig_verification.validate_exp = false; // Don't validate the exp time + jsonwebtoken::decode::(jwt, &jwk_decoding_key, &validation_with_sig_verification) // Signature verification happens here + .map_err(|e| { + PepperServiceError::BadRequest(format!("JWT signature verification failed: {e}")) + })?; + + Ok(()) +} + +/// Verifies that the oauth nonce in the claims matches the recalculated nonce +fn verify_oath_nonce( + ephemeral_public_key: &EphemeralPublicKey, + exp_date_secs: u64, + epk_blinder: Vec, + claims: &TokenData, + keyless_configuration: &Configuration, +) -> Result<(), PepperServiceError> { + let recalculated_nonce = OpenIdSig::reconstruct_oauth_nonce( + epk_blinder.as_slice(), + exp_date_secs, + ephemeral_public_key, + keyless_configuration, + ) + .map_err(|error| { + PepperServiceError::BadRequest(format!("Failed to reconstruct oauth nonce: {}", error)) + })?; + + if claims.claims.nonce != recalculated_nonce { + Err(PepperServiceError::BadRequest(format!( + "The oauth nonce in the JWT does not match the recalculated nonce: jwt_nonce = {}, \ + recalculated_nonce = {}", + claims.claims.nonce, recalculated_nonce + ))) + } else { + Ok(()) + } +} + +/// Verifies that the given public key expiry date is in the future, and that it +/// is within the allowed horizon from the issued-at time in the claims. +fn verify_public_key_expiry_date_secs( + exp_date_secs: u64, + claims: &TokenData, + keyless_configuration: &Configuration, +) -> Result<(), PepperServiceError> { + // Get the current time + let time_now_secs = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(); + + // Verify that the expiry date is in the future + if exp_date_secs <= time_now_secs { + return Err(PepperServiceError::BadRequest(format!( + "The ephemeral public key expiry date has passed: exp_date_secs = {}, time_now_secs = {}", + exp_date_secs, time_now_secs + ))); + } + + // Get the maximum allowed expiry date + let (max_exp_date_secs, overflowed) = claims + .claims + .iat + .overflowing_add(keyless_configuration.max_exp_horizon_secs); + if overflowed { + return Err(PepperServiceError::BadRequest( + "The maximum allowed expiry date overflowed".to_string(), + )); + } + + // Verify that the expiry date is within the allowed horizon + if exp_date_secs >= max_exp_date_secs { + Err(PepperServiceError::BadRequest( + "The ephemeral public key expiry date is too far in the future (and beyond the max allowed horizon)".into() + )) + } else { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{accounts::account_managers::AccountRecoveryManager, tests::utils}; + + // Test token data constants + const TEST_TOKEN_ISSUER: &str = "token_issuer"; + const TEST_TOKEN_SUB: &str = "token_sub"; + const TEST_TOKEN_AUD: &str = "token_aud"; + const TEST_TOKEN_AUD_OVERRIDE: &str = "token_aud_override"; + const TEST_TOKEN_EMAIL: &str = "token_email"; + const TEST_TOKEN_NONCE: &str = "token_nonce"; + + // Hard-coded test pepper constants. These are used to sanity check the + // generation logic for the pepper base, derived pepper and account address. + // Note: + // - These were generated using the tests in this file, and verified across + // several releases (to ensure backward compatibility). + // - The "sub" variants are for when the "sub" uid key is used. + // - The "email" variants are for when the "email" uid key is used. + // - The "sub_override" variants are for when the "sub" uid key is used with an + // account manager that has an aud override. + const TEST_EMAIL_ACCOUNT_ADDRESS: &str = + "0x526bcbdbdb4641f1b2f7bbc865c8eb41e976285a9849844b4f543ea17cff3dd3"; + const TEST_EMAIL_DERIVED_PEPPER_HEX: &str = + "9c76d2f26e8717ffbd499caad7ef5d85fdf24ce493ed111c8313f34429d10d"; + const TEST_EMAIL_PEPPER_BASE_HEX: &str = "96ef6f0fa8534a24b917dd773f14fa75a934e3bd21480391b49699c6b14735915de0adbdacc2670be61f06cb7215a57c"; + const TEST_EMAIL_VUF_PRIVATE_KEY_SEED: [u8; 32] = [1; 32]; + + const TEST_SUB_ACCOUNT_ADDRESS: &str = + "0xafdfc88e30c9858d34b2b5f63854cb4c2740c03a16cbc4df3f4adbe7b2e6c63f"; + const TEST_SUB_DERIVED_PEPPER_HEX: &str = + "42803a2ec0739390232b81a20a78651210e6e185d70edc4fa5bddbc2416b24"; + const TEST_SUB_PEPPER_BASE_HEX: &str = "b6d25395110bad7fda25f36bd44ee8220f37e952718bbb0e92cfae1061b6bb982bf34779d936f1b3cc412b832cf76d83"; + const TEST_SUB_VUF_PRIVATE_KEY_SEED: [u8; 32] = [2; 32]; + + const TEST_SUB_OVERRIDE_ACCOUNT_ADDRESS: &str = + "0xf357a030bf7da7f4c28a55dfda8bc1725339576acb2623b526e8d3eb2f366b79"; + const TEST_SUB_OVERRIDE_DERIVED_PEPPER_HEX: &str = + "21a8d5768336a41a5872351c806d56cca994b0acbe7f054afeed22bee06ef2"; + const TEST_SUB_OVERRIDE_PEPPER_BASE_HEX: &str = "b14111748bc9bde79f0a7edea91b06432800107c448dbe9cc89b47a49ec5094e2fe8976790f6574c7eb9abdc7c5b1df5"; + + #[test] + fn test_create_pepper_base() { + // Create a test pepper input + let pepper_input = PepperInput { + iss: TEST_TOKEN_ISSUER.into(), + uid_key: SUB_UID_KEY.into(), + uid_val: TEST_TOKEN_SUB.into(), + aud: TEST_TOKEN_AUD.into(), + }; + + // Create a test VUF keypair + let vuf_keypair = utils::create_vuf_keypair(Some(TEST_SUB_VUF_PRIVATE_KEY_SEED)); + + // Create the pepper base + let pepper_base = create_pepper_base(vuf_keypair.clone(), &pepper_input).unwrap(); + + // Verify the pepper base matches the expected value + assert_eq!( + hex::encode(pepper_base), + TEST_SUB_PEPPER_BASE_HEX.to_string() + ); + + // Create an invalid keypair where the public and private keys do not match + let invalid_private_key = *utils::create_vuf_keypair(None).vuf_private_key(); + let invalid_vuf_keypair = VUFKeypair::new( + invalid_private_key, + *vuf_keypair.vuf_public_key(), + vuf_keypair.vuf_public_key_json().clone(), + ); + + // Create the pepper base using the invalid keypair. This should fail with + // a verification error, because the public and private keys don't match. + let pepper_service_error = + create_pepper_base(Arc::new(invalid_vuf_keypair), &pepper_input).unwrap_err(); + assert!(pepper_service_error + .to_string() + .contains("VUF verification failed")); + } + + #[test] + fn test_get_uid_key_and_value() { + // Create test token data + let claims = create_test_token_data(); + + // Test with no uid_key (should use the default) + let (uid_key, uid_val) = get_uid_key_and_value(None, &claims).unwrap(); + assert_eq!(uid_key, SUB_UID_KEY); + assert_eq!(uid_val, TEST_TOKEN_SUB); + + // Test with sub uid_key + let (uid_key, uid_val) = get_uid_key_and_value(Some(SUB_UID_KEY.into()), &claims).unwrap(); + assert_eq!(uid_key, SUB_UID_KEY); + assert_eq!(uid_val, TEST_TOKEN_SUB); + + // Test with email uid_key + let (uid_key, uid_val) = + get_uid_key_and_value(Some(EMAIL_UID_KEY.into()), &claims).unwrap(); + assert_eq!(uid_key, EMAIL_UID_KEY); + assert_eq!(uid_val, TEST_TOKEN_EMAIL); + + // Test with an unsupported uid_key + let result = get_uid_key_and_value(Some("unsupported".to_string()), &claims); + assert!(result.is_err()); + } + + #[test] + fn test_invalid_derivation_path() { + let invalid_path = Some("m/44'/637'/0'/0/0'".to_string()); // Invalid because one index is not hardened + let result = get_verified_derivation_path(invalid_path); + assert!(result.is_err()); + } + + #[tokio::test] + async fn test_pepper_and_address_derivation_default() { + // Create test token data + let claims = create_test_token_data(); + + // Get the default uid key and value (which should be "sub") + let (uid_key, uid_val) = get_uid_key_and_value(None, &claims).unwrap(); + + // Create the pepper input + let accounts_managers_and_overrides = utils::get_empty_account_recovery_managers(); + let account_recovery_db = utils::get_mock_account_recovery_db(); + let pepper_input = create_pepper_input( + &claims, + uid_key, + uid_val, + accounts_managers_and_overrides, + None, + account_recovery_db, + ) + .await + .unwrap(); + + // Get the VUF keypair + let vuf_keypair = utils::create_vuf_keypair(Some(TEST_SUB_VUF_PRIVATE_KEY_SEED)); + + // Verify the pepper base, derived pepper and account address + verify_base_pepper_and_address_generation( + vuf_keypair, + &pepper_input, + TEST_SUB_PEPPER_BASE_HEX, + TEST_SUB_DERIVED_PEPPER_HEX, + TEST_SUB_ACCOUNT_ADDRESS, + ); + } + + #[tokio::test] + async fn test_pepper_and_address_derivation_email() { + // Create test token data + let claims = create_test_token_data(); + + // Get the email uid key and value + let (uid_key, uid_val) = + get_uid_key_and_value(Some(EMAIL_UID_KEY.into()), &claims).unwrap(); + + // Create the pepper input + let accounts_managers_and_overrides = utils::get_empty_account_recovery_managers(); + let account_recovery_db = utils::get_mock_account_recovery_db(); + let pepper_input = create_pepper_input( + &claims, + uid_key, + uid_val, + accounts_managers_and_overrides, + None, + account_recovery_db, + ) + .await + .unwrap(); + + // Get the VUF keypair + let vuf_keypair = utils::create_vuf_keypair(Some(TEST_EMAIL_VUF_PRIVATE_KEY_SEED)); + + // Verify the pepper base, derived pepper and account address + verify_base_pepper_and_address_generation( + vuf_keypair, + &pepper_input, + TEST_EMAIL_PEPPER_BASE_HEX, + TEST_EMAIL_DERIVED_PEPPER_HEX, + TEST_EMAIL_ACCOUNT_ADDRESS, + ); + } + + #[tokio::test] + async fn test_pepper_and_address_derivation_sub() { + // Create test token data + let claims = create_test_token_data(); + + // Get the sub uid key and value + let (uid_key, uid_val) = get_uid_key_and_value(Some(SUB_UID_KEY.into()), &claims).unwrap(); + + // Create the pepper input + let accounts_managers_and_overrides = utils::get_empty_account_recovery_managers(); + let account_recovery_db = utils::get_mock_account_recovery_db(); + let pepper_input = create_pepper_input( + &claims, + uid_key, + uid_val, + accounts_managers_and_overrides, + None, + account_recovery_db, + ) + .await + .unwrap(); + + // Get the VUF keypair + let vuf_keypair = utils::create_vuf_keypair(Some(TEST_SUB_VUF_PRIVATE_KEY_SEED)); + + // Verify the pepper base, derived pepper and account address + verify_base_pepper_and_address_generation( + vuf_keypair, + &pepper_input, + TEST_SUB_PEPPER_BASE_HEX, + TEST_SUB_DERIVED_PEPPER_HEX, + TEST_SUB_ACCOUNT_ADDRESS, + ); + } + + #[tokio::test] + async fn test_pepper_and_address_derivation_sub_aud_override() { + // Create test token data + let claims = create_test_token_data(); + + // Get the sub uid key and value + let (uid_key, uid_val) = get_uid_key_and_value(Some(SUB_UID_KEY.into()), &claims).unwrap(); + + // Create the account recovery managers + let account_recovery_manager = + AccountRecoveryManager::new(claims.claims.iss.clone(), claims.claims.aud.clone()); + let account_recovery_managers = + Arc::new(AccountRecoveryManagers::new(vec![account_recovery_manager])); + + // Create the pepper input with an aud override + let account_recovery_db = utils::get_mock_account_recovery_db(); + let pepper_input = create_pepper_input( + &claims, + uid_key, + uid_val, + account_recovery_managers, + Some(TEST_TOKEN_AUD_OVERRIDE.into()), + account_recovery_db, + ) + .await + .unwrap(); + + // Get the VUF keypair + let vuf_keypair = utils::create_vuf_keypair(Some(TEST_SUB_VUF_PRIVATE_KEY_SEED)); + + // Verify the pepper base, derived pepper and account address + verify_base_pepper_and_address_generation( + vuf_keypair, + &pepper_input, + TEST_SUB_OVERRIDE_PEPPER_BASE_HEX, + TEST_SUB_OVERRIDE_DERIVED_PEPPER_HEX, + TEST_SUB_OVERRIDE_ACCOUNT_ADDRESS, + ); + } + + /// Creates test token data with predefined claims + fn create_test_token_data() -> TokenData { + TokenData { + claims: Claims { + iss: TEST_TOKEN_ISSUER.into(), + sub: TEST_TOKEN_SUB.into(), + aud: TEST_TOKEN_AUD.into(), + exp: 0, + iat: 0, + nonce: TEST_TOKEN_NONCE.into(), + email: Some(TEST_TOKEN_EMAIL.into()), + azp: None, + }, + header: Default::default(), + } + } + + /// Verifies the generated pepper base, derived pepper and account address against the expected values + fn verify_base_pepper_and_address_generation( + vuf_keypair: Arc, + pepper_input: &PepperInput, + expected_pepper_base_hex: &str, + expected_derived_pepper_hex: &str, + expected_account_address: &str, + ) { + // Derive the pepper base, pepper and account address + let (pepper_base, derived_pepper_bytes, address) = + derive_pepper_and_account_address(vuf_keypair, None, pepper_input).unwrap(); + + // Verify the pepper base, derived pepper and account address + assert_eq!(hex::encode(pepper_base), expected_pepper_base_hex); + assert_eq!( + hex::encode(derived_pepper_bytes), + expected_derived_pepper_hex + ); + assert_eq!(address.to_standard_string(), expected_account_address); + } +} diff --git a/keyless/pepper/service/src/deployment_information.rs b/keyless/pepper/service/src/deployment_information.rs new file mode 100644 index 00000000000..99f2a300b51 --- /dev/null +++ b/keyless/pepper/service/src/deployment_information.rs @@ -0,0 +1,40 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_build_info::build_information; +use aptos_infallible::Mutex; +use std::{collections::BTreeMap, sync::Arc}; + +/// A simple struct to hold deployment information as key-value pairs +#[derive(Clone, Debug)] +pub struct DeploymentInformation { + deployment_information_map: Arc>>, +} + +impl DeploymentInformation { + pub fn new() -> Self { + // Collect the build information and initialize the map + let build_information = build_information!(); + let deployment_information_map = Arc::new(Mutex::new(build_information)); + + Self { + deployment_information_map, + } + } + + /// Adds a new key-value pair to the deployment information map + pub fn extend_deployment_information(&mut self, key: String, value: String) { + self.deployment_information_map.lock().insert(key, value); + } + + /// Returns a copy of the deployment information map + pub fn get_deployment_information(&self) -> BTreeMap { + self.deployment_information_map.lock().clone() + } +} + +impl Default for DeploymentInformation { + fn default() -> Self { + Self::new() + } +} diff --git a/keyless/pepper/service/src/error.rs b/keyless/pepper/service/src/error.rs new file mode 100644 index 00000000000..755701b8dfa --- /dev/null +++ b/keyless/pepper/service/src/error.rs @@ -0,0 +1,22 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +/// A pepper service error (e.g., for bad API requests, internal errors, etc.) +#[derive(Clone, Debug, Deserialize, Error, PartialEq, Eq, Serialize)] +pub enum PepperServiceError { + #[error("Bad request error: {0}")] + BadRequest(String), + #[error("Internal service error: {0}")] + InternalError(String), + #[error("Unexpected error: {0}")] + UnexpectedError(String), +} + +impl From for PepperServiceError { + fn from(error: tokio::task::JoinError) -> PepperServiceError { + PepperServiceError::UnexpectedError(format!("JoinError: {:?}", error)) + } +} diff --git a/keyless/pepper/service/src/external_resources/groth16_vk.rs b/keyless/pepper/service/src/external_resources/groth16_vk.rs new file mode 100644 index 00000000000..76061ca6def --- /dev/null +++ b/keyless/pepper/service/src/external_resources/groth16_vk.rs @@ -0,0 +1,155 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils; +use anyhow::{anyhow, Result}; +use ark_bn254::Bn254; +use ark_groth16::{PreparedVerifyingKey, VerifyingKey}; +use ark_serialize::CanonicalDeserialize; +use serde::{Deserialize, Serialize}; + +/// This struct is a representation of a Groth16VerificationKey resource as found on-chain. +/// See, for example: +/// https://fullnode.testnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey +/// +/// Example JSON: +/// { +/// "type": "0x1::keyless_account::Groth16VerificationKey", +/// "data": { +/// "alpha_g1": "0xe2f26dbea299f5223b646cb1fb33eadb059d9407559d7441dfd902e3a79a4d2d", +/// "beta_g2": "0xabb73dc17fbc13021e2471e0c08bd67d8401f52b73d6d07483794cad4778180e0c06f33bbc4c79a9cadef253a68084d382f17788f885c9afd176f7cb2f036789", +/// "delta_g2": "0xb106619932d0ef372c46909a2492e246d5de739aa140e27f2c71c0470662f125219049cfe15e4d140d7e4bb911284aad1cad19880efb86f2d9dd4b1bb344ef8f", +/// "gamma_abc_g1": [ +/// "0x6123b6fea40de2a7e3595f9c35210da8a45a7e8c2f7da9eb4548e9210cfea81a", +/// "0x32a9b8347c512483812ee922dc75952842f8f3083edb6fe8d5c3c07e1340b683" +/// ], +/// "gamma_g2": "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19" +/// } +/// } +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct OnChainGroth16VerificationKey { + pub r#type: String, // Note: "type" is a reserved keyword, so we use raw identifier syntax + pub data: Groth16VerificationKeyData, +} + +impl OnChainGroth16VerificationKey { + #[cfg(test)] + /// Creates a new OnChainGroth16VerificationKey for testing. + /// Note: internally, the fields will contain default values. + pub fn new_for_testing() -> Self { + OnChainGroth16VerificationKey { + r#type: "0x1::keyless_account::Groth16VerificationKey".to_string(), + data: Groth16VerificationKeyData::default(), + } + } + + /// Converts the on-chain verification key to a prepared verifying key + pub fn to_ark_prepared_verifying_key(&self) -> Result> { + // Collect and parse the gamma_abc_g1 elements + let verification_key_data = &self.data; + let mut gamma_abc_g1 = Vec::with_capacity(verification_key_data.gamma_abc_g1.len()); + for (index, onchain_ele) in verification_key_data.gamma_abc_g1.iter().enumerate() { + let ark_ele = parse_type_from_hex(onchain_ele).map_err(|error| { + anyhow!( + "Failed to parse gamma_abc_g1[{index}] from hex! Error: {}", + error + ) + })?; + gamma_abc_g1.push(ark_ele); + } + + // Parse the other elements + let alpha_g1 = parse_type_from_hex(&verification_key_data.alpha_g1) + .map_err(|error| anyhow!("Failed to parse alpha_g1 from hex! Error: {}", error))?; + let beta_g2 = parse_type_from_hex(&verification_key_data.beta_g2) + .map_err(|error| anyhow!("Failed to parse beta_g2 from hex! Error: {}", error))?; + let gamma_g2 = parse_type_from_hex(&verification_key_data.gamma_g2) + .map_err(|error| anyhow!("Failed to parse gamma_g2 from hex! Error: {}", error))?; + let delta_g2 = parse_type_from_hex(&verification_key_data.delta_g2) + .map_err(|error| anyhow!("Failed to parse delta_g2 from hex! Error: {}", error))?; + + // Construct the VerifyingKey + let ark_vk = VerifyingKey { + alpha_g1, + beta_g2, + gamma_g2, + delta_g2, + gamma_abc_g1, + }; + + Ok(PreparedVerifyingKey::from(ark_vk)) + } +} + +/// The data fields of the Groth16VerificationKey resource +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct Groth16VerificationKeyData { + pub alpha_g1: String, + pub beta_g2: String, + pub delta_g2: String, + pub gamma_abc_g1: Vec, + pub gamma_g2: String, +} + +/// Parses a type that implements canonical deserialization from a hex string +fn parse_type_from_hex(hex_string: &str) -> Result { + // Get the raw bytes from the hex string + let raw_bytes = utils::unhexlify_api_bytes(hex_string) + .map_err(|error| anyhow!("Failed to unhexlify input hex string! Error: {}", error))?; + + // Deserialize the bytes into the desired type + T::deserialize_compressed(raw_bytes.as_slice()) + .map_err(|e| anyhow!("Failed to deserialize compressed bytes! Error: {}", e)) +} + +#[cfg(test)] +mod tests { + use crate::external_resources::groth16_vk::{ + Groth16VerificationKeyData, OnChainGroth16VerificationKey, + }; + use ark_bn254::{Bn254, Fr, G1Affine, G2Affine}; + use ark_groth16::Groth16; + use ark_serialize::CanonicalDeserialize; + + #[test] + fn test_to_ark_pvk() { + // Create a Groth16 verification key + let groth16_verification_key = OnChainGroth16VerificationKey { + r#type: "0x1::keyless_account::Groth16VerificationKey".into(), + data: Groth16VerificationKeyData { + alpha_g1: "0xe39cb24154872dbdbbdbc8056c6eb3e6cab3ad82f80ded72ed4c9301c5b3da15".into(), + beta_g2: "0x9a732e38644f89ad2c7bd629b84d6b81f2e83ca4b3cddfd99c0254e49332861e2fcec4f74545abdd42c8857ff8df6d3f6b3670f930d1d5ba961655ea38ded315".into(), + delta_g2: "0x04c7b3a2734731369a281424c2bd7af229b92496527fd0a01bfe4a5c01e0a92f256921817b6d6cf040ccd483d81738ac88571b57009f182946e8a88cced03a01".into(), + gamma_abc_g1: vec![ + "0x2f4f4bc4acbea0c3bae9e676fb59537e2e46994d5896e286e6fcccc7e14b1b2d".into(), + "0x979308443fbac05f6d22a16525c26246e965a9be68e163154f44b20d6b2ddf18".into(), + ], + gamma_g2: "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19".into(), + }, + }; + + // Convert the key to a prepared verifying key + let prepared_verifying_key = groth16_verification_key + .to_ark_prepared_verifying_key() + .unwrap(); + + // Construct a proof and public inputs that can be verified with this key + let proof = ark_groth16::Proof { + a: G1Affine::deserialize_compressed(hex::decode("fd6ae6c19f7eb7362e420e3e359f3d85c0030b779a815627b805276e45018817").unwrap().as_slice()).unwrap(), + b: G2Affine::deserialize_compressed(hex::decode("c4af5f1e793653d80009c19637b326f78a46d9d031e9e36a6f87e296ba04e31322af2d8d5c3d4129b6b2f3d222f741ce17145ab62f1b238f3f9e8c88831da297").unwrap().as_slice()).unwrap(), + c: G1Affine::deserialize_compressed(hex::decode("a856a923cde90ecb6f8955c9627ede579e67b7082431b965d011fca578892096").unwrap().as_slice()).unwrap(), + }; + let public_input_bytes = + hex::decode("08aba90163b227d54013b7d1a892b20edf149a23acf810acf78e8baf8e770d11") + .unwrap(); + let public_inputs = + vec![Fr::deserialize_compressed(public_input_bytes.as_slice()).unwrap()]; + + // Verify the proof using the prepared verifying key and public inputs + let result = + Groth16::::verify_proof(&prepared_verifying_key, &proof, &public_inputs); + + // Ensure the verification was successful + assert_eq!(result, Ok(true)); + } +} diff --git a/keyless/pepper/service/src/external_resources/jwk_fetcher.rs b/keyless/pepper/service/src/external_resources/jwk_fetcher.rs new file mode 100644 index 00000000000..db6d550b9fc --- /dev/null +++ b/keyless/pepper/service/src/external_resources/jwk_fetcher.rs @@ -0,0 +1,339 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{error::PepperServiceError, metrics, utils}; +use anyhow::{anyhow, Result}; +use aptos_infallible::Mutex; +use aptos_keyless_pepper_common::jwt::parse; +use aptos_logger::{info, warn}; +use aptos_time_service::{TimeService, TimeServiceTrait}; +use aptos_types::{jwks::rsa::RSA_JWK, keyless::test_utils::get_sample_iss}; +use once_cell::sync::Lazy; +use regex::Regex; +use serde_json::Value; +use std::{collections::HashMap, str::FromStr, sync::Arc, time::Duration}; +use tokio::time::Instant; +// TODO: at some point, we should try to merge the JWK and resource fetcher code + +// Issuer and JWK URL constants for Apple +const ISSUER_APPLE: &str = "https://appleid.apple.com"; +const JWK_URL_APPLE: &str = "https://appleid.apple.com/auth/keys"; + +// Issuer and JWK URL constants for Google +const ISSUER_GOOGLE: &str = "https://accounts.google.com"; +const JWK_URL_GOOGLE: &str = "https://www.googleapis.com/oauth2/v3/certs"; + +// The interval (in seconds) at which to refresh the JWKs +pub const JWK_REFRESH_INTERVAL_SECS: u64 = 10; + +// The frequency at which to log the JWK refresh status (per loop iteration) +const JWK_REFRESH_LOOP_LOG_FREQUENCY: u64 = 6; // e.g., 6 * 10s (per loop) = 60s per log + +// Useful type declarations +pub type Issuer = String; +pub type KeyID = String; +pub type JWKCache = Arc>>>>; + +/// A lazy static regex to match auth0 URLs +static AUTH_0_REGEX: Lazy = + Lazy::new(|| Regex::new(r"^https://[a-zA-Z0-9-]+\.us\.auth0\.com/$").unwrap()); + +/// A lazy static regex to match cognito URLs +static COGNITO_REGEX: Lazy = Lazy::new(|| { + Regex::new(r"^https://cognito-idp\.[a-zA-Z0-9-_]+\.amazonaws\.com/[a-zA-Z0-9-_]+$").unwrap() +}); + +/// A common interface offered by JWK issuers (this is especially useful for logging and testing) +#[async_trait::async_trait] +pub trait JWKIssuerInterface { + /// Returns the name of the issuer + fn issuer_name(&self) -> String; + + /// Returns the JWK URL of the issuer + fn issuer_jwk_url(&self) -> String; + + /// Fetches the JWKs from the issuer's JWK URL + async fn fetch_jwks(&self) -> Result>>; +} + +/// A simple JWK issuer struct +#[derive(Clone, Debug)] +pub struct JWKIssuer { + issuer_name: String, + issuer_jwk_url: String, +} + +impl JWKIssuer { + pub fn new(issuer_name: String, issuer_jwk_url: String) -> JWKIssuer { + JWKIssuer { + issuer_name, + issuer_jwk_url, + } + } +} + +#[async_trait::async_trait] +impl JWKIssuerInterface for JWKIssuer { + fn issuer_name(&self) -> String { + self.issuer_name.clone() + } + + fn issuer_jwk_url(&self) -> String { + self.issuer_jwk_url.clone() + } + + async fn fetch_jwks(&self) -> Result>> { + fetch_jwks(&self.issuer_jwk_url).await + } +} + +impl FromStr for JWKIssuer { + type Err = PepperServiceError; + + /// This is used to parse each jwk issuer from the command line. + /// The expected format is: " ". + /// NOTE: we assume there is no whitespace character in either `iss` or `jwk_url`. + fn from_str(string: &str) -> std::result::Result { + // Split the string by whitespace + let mut iterator = string.split_whitespace(); + + // Parse the substrings as issuer and aud + let issuer_name = iterator.next().ok_or(PepperServiceError::UnexpectedError( + "Failed to parse JWK issuer name!".into(), + ))?; + let issuer_jwk_url = iterator.next().ok_or(PepperServiceError::UnexpectedError( + "Failed to parse JWK issuer URL!".into(), + ))?; + + // Verify that there are exactly 2 substrings + if iterator.next().is_some() { + return Err(PepperServiceError::UnexpectedError( + "Too many arguments found for JWK issuer!".into(), + )); + } + + // Create the override + let jwk_issuer = JWKIssuer::new(issuer_name.to_string(), issuer_jwk_url.to_string()); + Ok(jwk_issuer) + } +} + +/// Fetches the JWKs from the given URL +async fn fetch_jwks(jwk_url: &str) -> Result>> { + // Create the request client + let client = utils::create_request_client(); + + // Fetch the JWKs from the URL + let response = client + .get(jwk_url) + .send() + .await + .map_err(|error| anyhow!("Failed to fetch JWKs from {}! Error: {}", jwk_url, error))?; + + // Extract the response text + let response_text = response.text().await.map_err(|error| { + anyhow!( + "Failed to extract response text from {}! Error: {}", + jwk_url, + error + ) + })?; + + // Parse the JWKs from the response text + parse_jwks(&response_text) +} + +/// Returns a cached RSA JWK for the given issuer and key ID +pub fn get_cached_jwk_as_rsa( + issuer: &String, + key_id: &String, + jwk_cache: JWKCache, +) -> Result> { + // Get the key set for the issuer + let jwk_cache = jwk_cache.lock(); + let key_set = jwk_cache + .get(issuer) + .ok_or_else(|| anyhow!("Failed to get cached RSA JWK! Unknown issuer: {}", issuer))?; + + // Get the key for the given key ID + let key = key_set + .get(key_id) + .ok_or_else(|| anyhow!("Failed to get cached RSA JWK! Unknown key ID: {}", key_id))?; + + Ok(key.clone()) +} + +/// Fetches the federated JWK for the given JWT +pub async fn get_federated_jwk(jwt: &str) -> Result> { + // Parse the JWT to extract the issuer and key ID + let payload = parse(jwt)?; + let jwt_issuer = payload.claims.iss; + let jwt_key_id: String = match payload.header.kid { + Some(kid) => kid, + None => return Err(anyhow!("No key ID (kid) found on JWT header!")), + }; + + // Fetch the keys for the issuer + let keys = if jwt_issuer.eq("test.federated.oidc.provider") { + let test_jwk = include_str!("../../../../../types/src/jwks/rsa/secure_test_jwk.json"); + parse_jwks(test_jwk).expect("The test JWK should parse successfully!") + } else if AUTH_0_REGEX.is_match(&jwt_issuer) { + let jwk_url = format!("{}.well-known/jwks.json", &jwt_issuer); + fetch_jwks(&jwk_url).await? + } else if COGNITO_REGEX.is_match(&jwt_issuer) { + let jwk_url = format!("{}/.well-known/jwks.json", &jwt_issuer); + fetch_jwks(&jwk_url).await? + } else { + return Err(anyhow!("Unsupported federated issuer: {}", jwt_issuer)); + }; + + // Fetch the key for the given key ID + let key = keys + .get(&jwt_key_id) + .ok_or_else(|| anyhow!("unknown kid: {}", jwt_key_id))?; + Ok(key.clone()) +} + +/// Inserts the test JWK into the JWT cache +pub fn insert_test_jwk(jwk_cache: JWKCache) { + let test_jwk = include_str!("../../../../../types/src/jwks/rsa/secure_test_jwk.json"); + let parsed_jwk = parse_jwks(test_jwk).expect("The test JWK should parse successfully!"); + jwk_cache.lock().insert(get_sample_iss(), parsed_jwk); +} + +/// Parses the JWKs from the given response text +fn parse_jwks(response_text: &str) -> Result>> { + // Parse the response text into a JSON value + let response_json_value = serde_json::from_str::(response_text) + .map_err(|error| anyhow!("Failed to parse response json! Error: {}", error))?; + + // Extract the "keys" array from the JSON value + let keys: &Vec = response_json_value + .get("keys") + .ok_or_else(|| anyhow!("Failed to parse JWK json: \"keys\" entry not found!"))? + .as_array() + .ok_or_else(|| anyhow!("Failed to parse JWK json: \"keys\" entry not an array!"))?; + + // Parse each key, and filter out unsupported keys + let key_map: HashMap> = keys + .iter() + .filter_map(|jwk_val| match RSA_JWK::try_from(jwk_val) { + Ok(rsa_jwk) => { + if rsa_jwk.e == "AQAB" { + Some((rsa_jwk.kid.clone(), Arc::new(rsa_jwk))) + } else { + warn!("Unsupported RSA modulus for jwk: {}", jwk_val); + None + } + }, + Err(error) => { + warn!("Error while parsing JWK: {}! {}", jwk_val, error); + None + }, + }) + .collect(); + + Ok(key_map) +} + +/// Starts the JWK refresh loops for known issuers. Note: we currently +/// hardcode the known issuers here, instead of fetching them from on-chain +/// configs. This is a security measure to ensure the pepper service only +/// trusts a small set of known issuers, with deterministic and immutable +/// JWK URLs. Otherwise, if these values were fetched from on-chain configs, +/// an attacker who compromises governance could change these values to +/// point to a malicious issuer (or JWK URL). +pub fn start_jwk_fetchers(jwk_issuers_override: Vec) -> JWKCache { + // Create the JWK cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + + // Insert the test JWK. This is required for the automated end-to-end + // integration tests that run as a part of testing pipeline. + insert_test_jwk(jwk_cache.clone()); + + // Create the time service + let time_service = TimeService::real(); + + // Create the known issuers for Google and Apple + let default_issuers = vec![ + JWKIssuer::new(ISSUER_GOOGLE.into(), JWK_URL_GOOGLE.into()), + JWKIssuer::new(ISSUER_APPLE.into(), JWK_URL_APPLE.into()), + ]; + let jwk_issuer_map: HashMap> = default_issuers + .into_iter() + .chain(jwk_issuers_override) + .map(|issuer| (issuer.issuer_name.clone(), Arc::new(issuer))) + .collect(); + + // Start the JWK refresh loops for known issuers + for (_, jwk_issuer) in jwk_issuer_map { + start_jwk_refresh_loop(jwk_issuer, jwk_cache.clone(), time_service.clone()); + } + + // Return the JWK cache + jwk_cache +} + +/// Starts a background task that periodically fetches and caches the JWKs from the given issuer +pub fn start_jwk_refresh_loop( + jwk_issuer: Arc, + jwk_cache: JWKCache, + time_service: TimeService, +) { + // Log the start of the task for the issuer + let issuer_name = jwk_issuer.issuer_name(); + let issuer_jwk_url = jwk_issuer.issuer_jwk_url(); + info!( + "Starting the JWK refresh loop for {}, URL: {}!", + issuer_name, issuer_jwk_url + ); + + // Start the task + tokio::spawn(async move { + let mut loop_iteration_counter: u64 = 0; + + loop { + // Fetch the JWKs from the URL + let time_now = Instant::now(); + let fetch_result = jwk_issuer.fetch_jwks().await; + let fetch_time = time_now.elapsed(); + + // Process the fetch result + match &fetch_result { + Ok(key_set) => { + // Log the successful fetch + if loop_iteration_counter % JWK_REFRESH_LOOP_LOG_FREQUENCY == 0 { + info!( + "Successfully fetched the JWK in {:?}! Issuer: {}, URL: {}, Key set: {:?}", + fetch_time, + issuer_jwk_url, + issuer_name, + key_set + ) + } + + // Update the cache + jwk_cache + .lock() + .insert(issuer_name.clone(), key_set.clone()); + }, + Err(error) => { + warn!( + "Failed to fetch the JWK in {:?}! Issuer: {}, URL: {}, Error: {}", + fetch_time, issuer_jwk_url, issuer_name, error + ); + }, + } + + // Update the fetch metrics + metrics::update_jwk_fetch_metrics(&issuer_name, fetch_result.is_ok(), fetch_time); + + // Increment the loop iteration counter + loop_iteration_counter = loop_iteration_counter.wrapping_add(1); + + // Sleep until the next refresh interval + let refresh_interval = Duration::from_secs(JWK_REFRESH_INTERVAL_SECS); + time_service.sleep(refresh_interval).await; + } + }); +} diff --git a/keyless/pepper/service/src/external_resources/keyless_config.rs b/keyless/pepper/service/src/external_resources/keyless_config.rs new file mode 100644 index 00000000000..c26e73ea3d3 --- /dev/null +++ b/keyless/pepper/service/src/external_resources/keyless_config.rs @@ -0,0 +1,125 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils; +use anyhow::{anyhow, Result}; +use aptos_types::keyless::Configuration; +use serde::{Deserialize, Serialize}; + +/// This struct is a representation of an OnChainKeylessConfiguration resource as found on-chain. +/// See, for example: +/// https://fullnode.testnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Configuration +/// +/// Example JSON: +/// { +/// "type": "0x1::keyless_account::Configuration", +/// "data": { +/// "max_commited_epk_bytes": 93, +/// "max_exp_horizon_secs": "10000000", +/// "max_extra_field_bytes": 350, +/// "max_iss_val_bytes": 120, +/// "max_jwt_header_b64_bytes": 300, +/// "max_signatures_per_txn": 3, +/// "override_aud_vals": [], +/// "training_wheels_pubkey": { +/// "vec": [ +/// "0x1388de358cf4701696bd58ed4b96e9d670cbbb914b888be1ceda6374a3098ed4" +/// ] +/// } +/// } +/// } +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct OnChainKeylessConfiguration { + pub r#type: String, // Note: "type" is a reserved keyword, so we use raw identifier syntax + pub data: KeylessConfigurationData, +} + +impl OnChainKeylessConfiguration { + #[cfg(test)] + /// Creates a new OnChainKeylessConfiguration for testing + pub fn new_for_testing() -> Self { + // Create a test configuration + let configuration = Configuration::new_for_testing(); + + // Get the training wheels public key + let training_wheels_pubkey = match configuration.training_wheels_pubkey { + Some(public_key) => { + let public_key_hex = hex::encode(&public_key); + let public_key_string = format!("0x{}", public_key_hex); + TrainingWheelsPubKey { + vec: vec![public_key_string], + } + }, + None => TrainingWheelsPubKey { vec: vec![] }, + }; + + // Get the corresponding on-chain configuration data + let data = KeylessConfigurationData { + max_commited_epk_bytes: configuration.max_commited_epk_bytes, + max_exp_horizon_secs: configuration.max_exp_horizon_secs.to_string(), + max_extra_field_bytes: configuration.max_extra_field_bytes, + max_iss_val_bytes: configuration.max_iss_val_bytes, + max_jwt_header_b64_bytes: configuration.max_jwt_header_b64_bytes, + max_signatures_per_txn: configuration.max_signatures_per_txn, + override_aud_vals: configuration.override_aud_vals, + training_wheels_pubkey, + }; + + // Return the on-chain keyless configuration + OnChainKeylessConfiguration { + r#type: "0x1::keyless_account::Configuration".to_string(), + data, + } + } + + /// Converts the on-chain keyless configuration to the internal representation + pub fn get_keyless_configuration(&self) -> Result { + // Extract the training wheels public key + let configuration_data = &self.data; + let training_wheels_pubkey = configuration_data + .training_wheels_pubkey + .vec + .first() + .map(|v| utils::unhexlify_api_bytes(v.as_str())) + .transpose() + .map_err(|error| anyhow!("Failed to unhexlify training_wheels_pubkey: {}", error))?; + + // Get the max_exp_horizon_secs as u64 + let max_exp_horizon_secs = configuration_data + .max_exp_horizon_secs + .parse() + .map_err(|error| anyhow!("Failed to parse max_exp_horizon_secs as u64: {}", error))?; + + // Return the configuration + let configuration = Configuration { + override_aud_vals: configuration_data.override_aud_vals.clone(), + max_signatures_per_txn: configuration_data.max_signatures_per_txn, + max_exp_horizon_secs, + training_wheels_pubkey, + max_commited_epk_bytes: configuration_data.max_commited_epk_bytes, + max_iss_val_bytes: configuration_data.max_iss_val_bytes, + max_extra_field_bytes: configuration_data.max_extra_field_bytes, + max_jwt_header_b64_bytes: configuration_data.max_jwt_header_b64_bytes, + }; + Ok(configuration) + } +} + +/// The data fields of the OnChainKeylessConfiguration resource +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct KeylessConfigurationData { + pub max_commited_epk_bytes: u16, + pub max_exp_horizon_secs: String, + pub max_extra_field_bytes: u16, + pub max_iss_val_bytes: u16, + pub max_jwt_header_b64_bytes: u32, + pub max_signatures_per_txn: u16, + pub override_aud_vals: Vec, + pub training_wheels_pubkey: TrainingWheelsPubKey, +} + +/// The training wheels public key of the OnChainKeylessConfiguration resource +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct TrainingWheelsPubKey { + vec: Vec, +} diff --git a/keyless/pepper/service/src/external_resources/mod.rs b/keyless/pepper/service/src/external_resources/mod.rs new file mode 100644 index 00000000000..23194b5622e --- /dev/null +++ b/keyless/pepper/service/src/external_resources/mod.rs @@ -0,0 +1,7 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod groth16_vk; +pub mod jwk_fetcher; +pub mod keyless_config; +pub mod resource_fetcher; diff --git a/keyless/pepper/service/src/external_resources/resource_fetcher.rs b/keyless/pepper/service/src/external_resources/resource_fetcher.rs new file mode 100644 index 00000000000..dd64fcb229b --- /dev/null +++ b/keyless/pepper/service/src/external_resources/resource_fetcher.rs @@ -0,0 +1,275 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + error::PepperServiceError, + external_resources::{ + groth16_vk::OnChainGroth16VerificationKey, keyless_config::OnChainKeylessConfiguration, + }, + metrics, utils, +}; +use aptos_infallible::RwLock; +use aptos_logger::{info, warn}; +use aptos_time_service::{TimeService, TimeServiceTrait}; +use serde::de::DeserializeOwned; +use std::{sync::Arc, time::Duration}; +use tokio::time::Instant; + +// TODO: at some point, we should try to merge the JWK and resource fetcher code + +// Resource names for metrics and logging +const ON_CHAIN_KEYLESS_CONFIG_RESOURCE_NAME: &str = "on_chain_keyless_configuration"; +const ON_CHAIN_GROTH16_VK_RESOURCE_NAME: &str = "on_chain_groth16_verification_key"; + +// The interval (in seconds) at which to refresh the resources +pub const RESOURCE_FETCH_INTERVAL_SECS: u64 = 10; + +// The frequency at which to log the resource fetch status (per loop iteration) +const RESOURCE_REFRESH_LOOP_LOG_FREQUENCY: u64 = 6; // e.g., 6 * 10s (per loop) = 60s per log + +/// A common interface for fetching external resources (this is especially useful for logging and testing) +#[async_trait::async_trait] +pub trait ExternalResourceInterface { + /// Returns the name of the resource + fn resource_name(&self) -> String; + + /// Returns the URL of the resource + fn resource_url(&self) -> String; + + /// Fetches the resource from the URL and parses it into the expected type + async fn fetch_resource(&self) -> Result; +} + +/// An external resource (e.g., on-chain keyless config or Groth16 VK) +struct ExternalResource { + name: String, + url: String, +} + +impl ExternalResource { + pub fn new(name: String, url: String) -> ExternalResource { + ExternalResource { name, url } + } +} + +#[async_trait::async_trait] +impl ExternalResourceInterface + for ExternalResource +{ + fn resource_name(&self) -> String { + self.name.clone() + } + + fn resource_url(&self) -> String { + self.url.clone() + } + + async fn fetch_resource(&self) -> Result { + // Fetch the resource from the URL + let url = self.url.clone(); + let client = utils::create_request_client(); + let fetch_result = client.get(url.clone()).send().await; + + // Parse the response into the expected resource type + let resource_name = self.name.clone(); + match fetch_result { + Ok(response) => match response.json::().await { + Ok(resource) => Ok(resource), + Err(error) => Err(PepperServiceError::InternalError(format!( + "Failed to parse resource: {}, from {}! Error: {}", + resource_name, url, error + ))), + }, + Err(error) => Err(PepperServiceError::InternalError(format!( + "Failed to fetch resource: {}, from {}! Error: {}", + resource_name, url, error + ))), + } + } +} + +/// A struct that holds the cached resources and their refresh logic +#[derive(Clone, Debug)] +pub struct CachedResources { + on_chain_keyless_configuration: Arc>>, + groth16_vk: Arc>>, + time_service: TimeService, +} + +impl CachedResources { + pub fn new(time_service: TimeService) -> Self { + Self { + on_chain_keyless_configuration: Arc::new(RwLock::new(None)), + groth16_vk: Arc::new(RwLock::new(None)), + time_service, + } + } + + /// Creates a new CachedResources instance with a mock time service (for testing) + #[cfg(test)] + pub fn new_for_testing() -> Self { + Self::new(TimeService::mock()) + } + + /// Starts the refresh loops for the cached resources at the given URLs. + /// If a URL is None, the corresponding fetcher is not started. + pub fn start_resource_fetcher( + &self, + on_chain_groth16_vk_url: Option, + on_chain_keyless_config_url: Option, + ) { + // Start the Groth16 VK fetcher + match on_chain_groth16_vk_url { + Some(url) => { + let external_resource = Arc::new(ExternalResource::new( + ON_CHAIN_GROTH16_VK_RESOURCE_NAME.into(), + url.clone(), + )); + start_external_resource_refresh_loop( + external_resource, + self.groth16_vk.clone(), + self.time_service.clone(), + ); + }, + None => { + warn!("The on-chain Groth16 VK URL is not set, skipping on-chain Groth16 VK fetching!"); + }, + } + + // Start the keyless config fetcher + match on_chain_keyless_config_url { + Some(url) => { + let external_resource = Arc::new(ExternalResource::new( + ON_CHAIN_KEYLESS_CONFIG_RESOURCE_NAME.into(), + url.clone(), + )); + start_external_resource_refresh_loop( + external_resource, + self.on_chain_keyless_configuration.clone(), + self.time_service.clone(), + ); + }, + None => { + warn!("The on-chain keyless config URL is not set, skipping on-chain keyless config fetching!"); + }, + } + } + + /// Returns the Groth16 verification key cache entry (for testing purposes) + #[cfg(test)] + pub fn get_groth16_vk_cache_entry(&self) -> Arc>> { + self.groth16_vk.clone() + } + + /// Returns the keyless configuration cache entry (for testing purposes) + #[cfg(test)] + pub fn get_keyless_configuration_cache_entry( + &self, + ) -> Arc>> { + self.on_chain_keyless_configuration.clone() + } + + /// Reads the cached on-chain Groth16 verification key + pub fn read_on_chain_groth16_vk(&self) -> Option { + self.groth16_vk.read().as_ref().cloned() + } + + /// Reads the cached on-chain keyless configuration + pub fn read_on_chain_keyless_configuration(&self) -> Option { + self.on_chain_keyless_configuration.read().as_ref().cloned() + } + + /// Sets the cached on-chain Groth16 verification key (for testing purposes) + #[cfg(test)] + pub fn set_on_chain_groth16_vk(&self, on_chain_groth16_vk: OnChainGroth16VerificationKey) { + let mut cache = self.groth16_vk.write(); + *cache = Some(on_chain_groth16_vk); + } + + /// Sets the cached on-chain keyless configuration (for testing purposes) + #[cfg(test)] + pub fn set_on_chain_keyless_configuration( + &self, + on_chain_keyless_configuration: OnChainKeylessConfiguration, + ) { + let mut cache = self.on_chain_keyless_configuration.write(); + *cache = Some(on_chain_keyless_configuration); + } +} + +/// Starts a background task that periodically fetches and caches the resource from the given URL +pub fn start_external_resource_refresh_loop( + external_resource: Arc + Send + Sync>, + local_cache: Arc>>, + time_service: TimeService, +) { + // Log the start of the task for the resource fetcher + let resource_name = external_resource.resource_name(); + let resource_url = external_resource.resource_url(); + info!( + "Starting the cached resource refresh loop for {} at {}!", + resource_name, resource_url + ); + + // Start the resource fetcher loop + tokio::spawn(async move { + let mut loop_iteration_counter: u64 = 0; + + loop { + // Sleep until the next refresh + let refresh_interval = Duration::from_secs(RESOURCE_FETCH_INTERVAL_SECS); + time_service.sleep(refresh_interval).await; + + // Increment the loop iteration counter + loop_iteration_counter = loop_iteration_counter.wrapping_add(1); + + // Fetch the resource from the URL + let time_now = Instant::now(); + let fetch_result: Result = + external_resource.fetch_resource().await; + let fetch_time = time_now.elapsed(); + + // Update the fetch metrics + metrics::update_external_resource_fetch_metrics( + &resource_name, + fetch_result.is_ok(), + fetch_time, + ); + + // Process the fetch result + match fetch_result { + Ok(resource) => { + // Log the successful fetch + if loop_iteration_counter % RESOURCE_REFRESH_LOOP_LOG_FREQUENCY == 0 { + info!( + "Successfully fetched resource {} from {} in {:?}", + resource_name, resource_url, fetch_time + ) + } + + // Update the cache + let mut cache = local_cache.write(); + *cache = Some(resource); + }, + Err(error) => { + warn!( + "Failed to fetch resource from {} in {:?}! Error: {}", + resource_url, fetch_time, error + ); + continue; // Retry in the next loop + }, + }; + } + }); +} + +/// Creates and starts the cached resource fetcher, and +/// returns a handle to the cached resources. +pub fn start_cached_resource_fetcher( + on_chain_groth16_vk_url: Option, + on_chain_keyless_config_url: Option, +) -> CachedResources { + let cached_resources = CachedResources::new(TimeService::real()); + cached_resources.start_resource_fetcher(on_chain_groth16_vk_url, on_chain_keyless_config_url); + cached_resources +} diff --git a/keyless/pepper/service/src/groth16_vk.rs b/keyless/pepper/service/src/groth16_vk.rs deleted file mode 100644 index d0be02a16c5..00000000000 --- a/keyless/pepper/service/src/groth16_vk.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::watcher::{unhexlify_api_bytes, ExternalResource}; -use anyhow::{anyhow, Result}; -use aptos_infallible::RwLock; -use ark_bn254::{Bn254, G1Affine, G2Affine}; -use ark_groth16::{PreparedVerifyingKey, VerifyingKey}; -use ark_serialize::CanonicalDeserialize; -use once_cell::sync::Lazy; -use serde::{Deserialize, Serialize}; -use std::sync::Arc; - -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] -pub struct VKeyData { - pub alpha_g1: String, - pub beta_g2: String, - pub delta_g2: String, - pub gamma_abc_g1: Vec, - pub gamma_g2: String, -} - -/// On-chain representation of a VK. -/// -/// https://fullnode.testnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] -pub struct OnChainGroth16VerificationKey { - /// Some type info returned by node API. - pub r#type: String, - pub data: VKeyData, -} - -impl OnChainGroth16VerificationKey { - pub fn to_ark_pvk(&self) -> Result> { - let mut gamma_abc_g1 = Vec::with_capacity(self.data.gamma_abc_g1.len()); - for (idx, onchain_ele) in self.data.gamma_abc_g1.iter().enumerate() { - let ark_ele = g1_from_api_repr(onchain_ele).map_err(|e| { - anyhow!("to_ark_pvk() failed with gamma_abc_g1[{idx}] convert err: {e}") - })?; - gamma_abc_g1.push(ark_ele); - } - let ark_vk = VerifyingKey { - alpha_g1: g1_from_api_repr(&self.data.alpha_g1) - .map_err(|e| anyhow!("to_ark_pvk() failed with alpha_g1 convert err: {e}"))?, - beta_g2: g2_from_api_repr(&self.data.beta_g2) - .map_err(|e| anyhow!("to_ark_pvk() failed with beta_g2 convert err: {e}"))?, - gamma_g2: g2_from_api_repr(&self.data.gamma_g2) - .map_err(|e| anyhow!("to_ark_pvk() failed with gamma_g2 convert err: {e}"))?, - delta_g2: g2_from_api_repr(&self.data.delta_g2) - .map_err(|e| anyhow!("to_ark_pvk() failed with delta_g2 convert err: {e}"))?, - gamma_abc_g1, - }; - Ok(PreparedVerifyingKey::from(ark_vk)) - } -} - -/// This variable holds the cached on-chain VK. A refresh loop exists to update it periodically. -pub static ONCHAIN_GROTH16_VK: Lazy>>> = - Lazy::new(|| Arc::new(RwLock::new(None))); - -fn g1_from_api_repr(api_repr: &str) -> Result { - let bytes = unhexlify_api_bytes(api_repr) - .map_err(|e| anyhow!("g1_from_api_repr() failed with unhex err: {e}"))?; - let ret = G1Affine::deserialize_compressed(bytes.as_slice()) - .map_err(|e| anyhow!("g1_from_api_repr() failed with g1 deser err: {e}"))?; - Ok(ret) -} - -fn g2_from_api_repr(api_repr: &str) -> Result { - let bytes = unhexlify_api_bytes(api_repr) - .map_err(|e| anyhow!("g2_from_api_repr() failed with unhex err: {e}"))?; - let ret = G2Affine::deserialize_compressed(bytes.as_slice()) - .map_err(|e| anyhow!("g2_from_api_repr() failed with g2 deser err: {e}"))?; - Ok(ret) -} - -impl ExternalResource for OnChainGroth16VerificationKey { - fn resource_name() -> String { - "OnChainGroth16VerificationKey".to_string() - } -} - -#[cfg(test)] -mod tests { - use crate::groth16_vk::{OnChainGroth16VerificationKey, VKeyData}; - use ark_bn254::{Bn254, Fr, G1Affine, G2Affine}; - use ark_groth16::Groth16; - use ark_serialize::CanonicalDeserialize; - - #[test] - fn test_to_ark_pvk() { - let api_repr = OnChainGroth16VerificationKey { - r#type: "0x1::keyless_account::Groth16VerificationKey".to_string(), - data: VKeyData { - alpha_g1: "0xe39cb24154872dbdbbdbc8056c6eb3e6cab3ad82f80ded72ed4c9301c5b3da15".to_string(), - beta_g2: "0x9a732e38644f89ad2c7bd629b84d6b81f2e83ca4b3cddfd99c0254e49332861e2fcec4f74545abdd42c8857ff8df6d3f6b3670f930d1d5ba961655ea38ded315".to_string(), - delta_g2: "0x04c7b3a2734731369a281424c2bd7af229b92496527fd0a01bfe4a5c01e0a92f256921817b6d6cf040ccd483d81738ac88571b57009f182946e8a88cced03a01".to_string(), - gamma_abc_g1: vec![ - "0x2f4f4bc4acbea0c3bae9e676fb59537e2e46994d5896e286e6fcccc7e14b1b2d".to_string(), - "0x979308443fbac05f6d22a16525c26246e965a9be68e163154f44b20d6b2ddf18".to_string(), - ], - gamma_g2: "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19".to_string(), - }, - }; - - let ark_pvk = api_repr.to_ark_pvk().unwrap(); - let proof = ark_groth16::Proof { - a: G1Affine::deserialize_compressed(hex::decode("fd6ae6c19f7eb7362e420e3e359f3d85c0030b779a815627b805276e45018817").unwrap().as_slice()).unwrap(), - b: G2Affine::deserialize_compressed(hex::decode("c4af5f1e793653d80009c19637b326f78a46d9d031e9e36a6f87e296ba04e31322af2d8d5c3d4129b6b2f3d222f741ce17145ab62f1b238f3f9e8c88831da297").unwrap().as_slice()).unwrap(), - c: G1Affine::deserialize_compressed(hex::decode("a856a923cde90ecb6f8955c9627ede579e67b7082431b965d011fca578892096").unwrap().as_slice()).unwrap(), - }; - let public_inputs = vec![Fr::deserialize_compressed( - hex::decode("08aba90163b227d54013b7d1a892b20edf149a23acf810acf78e8baf8e770d11") - .unwrap() - .as_slice(), - ) - .unwrap()]; - assert!(Groth16::::verify_proof(&ark_pvk, &proof, &public_inputs).unwrap()); - } -} diff --git a/keyless/pepper/service/src/jwk.rs b/keyless/pepper/service/src/jwk.rs deleted file mode 100644 index 54617bdaaf2..00000000000 --- a/keyless/pepper/service/src/jwk.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{metrics::JWK_FETCH_SECONDS, Issuer, KeyID}; -use anyhow::{anyhow, Result}; -use aptos_keyless_pepper_common::jwt::parse; -use aptos_logger::warn; -use aptos_types::jwks::rsa::RSA_JWK; -use dashmap::DashMap; -use jsonwebtoken::DecodingKey; -use once_cell::sync::Lazy; -use regex::Regex; -use serde_json::Value; -use std::{sync::Arc, time::Duration}; -use tokio::time::Instant; - -static AUTH_0_REGEX: Lazy = - Lazy::new(|| Regex::new(r"^https://[a-zA-Z0-9-]+\.us\.auth0\.com/$").unwrap()); - -static COGNITO_REGEX: Lazy = Lazy::new(|| { - Regex::new(r"^https://cognito-idp\.[a-zA-Z0-9-_]+\.amazonaws\.com/[a-zA-Z0-9-_]+$").unwrap() -}); - -/// The JWK in-mem cache. -pub static DECODING_KEY_CACHE: Lazy>>> = - Lazy::new(DashMap::new); - -pub async fn get_federated_jwk(jwt: &str) -> Result> { - let payload = parse(jwt)?; - - let jwt_kid: String = match payload.header.kid { - Some(kid) => kid, - None => return Err(anyhow!("no kid found on jwt header")), - }; - - // Check if it is a test iss - let keys = if payload.claims.iss.eq("test.federated.oidc.provider") { - let test_jwk = include_str!("../../../../types/src/jwks/rsa/secure_test_jwk.json"); - parse_jwks(test_jwk).expect("test jwk should parse") - } else if AUTH_0_REGEX.is_match(&payload.claims.iss) { - let jwk_url = format!("{}.well-known/jwks.json", &payload.claims.iss); - fetch_jwks(&jwk_url).await? - } else if COGNITO_REGEX.is_match(&payload.claims.iss) { - let jwk_url = format!("{}/.well-known/jwks.json", &payload.claims.iss); - fetch_jwks(&jwk_url).await? - } else { - return Err(anyhow!("not a federated iss")); - }; - - let key = keys - .get(&jwt_kid) - .ok_or_else(|| anyhow!("unknown kid: {}", jwt_kid))?; - Ok(key.clone()) -} - -/// Send a request to a JWK endpoint and return its JWK map. -pub async fn fetch_jwks(jwk_url: &str) -> Result>> { - let response = reqwest::get(jwk_url) - .await - .map_err(|e| anyhow!("jwk fetch error: {}", e))?; - let text = response - .text() - .await - .map_err(|e| anyhow!("error while getting response as text: {}", e))?; - parse_jwks(&text) -} - -pub fn parse_jwks(text: &str) -> Result>> { - let endpoint_response_val = serde_json::from_str::(text) - .map_err(|e| anyhow!("error while parsing json: {}", e))?; - - let keys: &Vec = endpoint_response_val - .get("keys") - .ok_or_else(|| anyhow!("Error while parsing jwk json: \"keys\" not found"))? - .as_array() - .ok_or_else(|| anyhow!("Error while parsing jwk json: \"keys\" not array"))?; - let key_map: DashMap> = keys - .iter() - .filter_map(|jwk_val| match RSA_JWK::try_from(jwk_val) { - Ok(jwk) => { - if jwk.e == "AQAB" { - Some((jwk.kid.clone(), Arc::new(jwk))) - } else { - warn!("Unsupported RSA modulus for jwk: {}", jwk_val); - None - } - }, - Err(e) => { - warn!("error while parsing jwk {}: {e}", jwk_val); - None - }, - }) - .collect(); - Ok(key_map) -} - -pub fn start_jwk_refresh_loop(issuer: &str, jwk_url: &str, refresh_interval: Duration) { - let issuer = issuer.to_string(); - let jwk_url = jwk_url.to_string(); - let _handle = tokio::spawn(async move { - loop { - let timer = Instant::now(); - let fetch_result = fetch_jwks(jwk_url.as_str()).await; - let fetch_time = timer.elapsed(); - let succeeded = fetch_result.is_ok(); - JWK_FETCH_SECONDS - .with_label_values(&[issuer.as_str(), succeeded.to_string().as_str()]) - .observe(fetch_time.as_secs_f64()); - match fetch_result { - Ok(key_set) => { - DECODING_KEY_CACHE.insert(issuer.clone(), key_set.clone()); - }, - Err(msg) => { - warn!( - issuer = issuer, - jwk_url = jwk_url, - "error fetching JWK: {}", - msg - ); - }, - } - tokio::time::sleep(refresh_interval).await; - } - }); -} - -pub fn cached_decoding_key_as_rsa(issuer: &String, kid: &String) -> Result> { - let key_set = DECODING_KEY_CACHE - .get(issuer) - .ok_or_else(|| anyhow!("unknown issuer: {}", issuer))?; - let key = key_set - .get(kid) - .ok_or_else(|| anyhow!("unknown kid: {}", kid))?; - Ok(key.clone()) -} - -pub fn cached_decoding_key(issuer: &String, kid: &String) -> Result { - let key = cached_decoding_key_as_rsa(issuer, kid)?; - let decoding_key = DecodingKey::from_rsa_components(&key.n, &key.e)?; - Ok(decoding_key) -} diff --git a/keyless/pepper/service/src/keyless_config.rs b/keyless/pepper/service/src/keyless_config.rs deleted file mode 100644 index a70b6762dee..00000000000 --- a/keyless/pepper/service/src/keyless_config.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::watcher::{unhexlify_api_bytes, ExternalResource}; -use anyhow::{anyhow, Result}; -use aptos_infallible::RwLock; -use aptos_types::keyless::Configuration; -use once_cell::sync::Lazy; -use serde::{Deserialize, Serialize}; -use std::sync::Arc; - -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] -pub struct TrainingWheelsPubKey { - vec: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] -pub struct OnChainKeylessConfiguration { - /// Some type info returned by node API. - pub r#type: String, - pub data: ConfigData, -} - -impl OnChainKeylessConfiguration { - pub fn to_rust_repr(&self) -> Result { - let training_wheels_pubkey = self - .data - .training_wheels_pubkey - .vec - .first() - .map(|v| unhexlify_api_bytes(v.as_str())) - .transpose() - .map_err(|e| anyhow!("to_rust_repr() failed with unhexlify err: {e}"))?; - let ret = Configuration { - override_aud_vals: self.data.override_aud_vals.clone(), - max_signatures_per_txn: self.data.max_signatures_per_txn, - max_exp_horizon_secs: self.data.max_exp_horizon_secs.parse().map_err(|e| { - anyhow!("to_rust_repr() failed at max_exp_horizon_secs convert: {e}") - })?, - training_wheels_pubkey, - max_commited_epk_bytes: self.data.max_commited_epk_bytes, - max_iss_val_bytes: self.data.max_iss_val_bytes, - max_extra_field_bytes: self.data.max_extra_field_bytes, - max_jwt_header_b64_bytes: self.data.max_jwt_header_b64_bytes, - }; - Ok(ret) - } -} - -impl ExternalResource for OnChainKeylessConfiguration { - fn resource_name() -> String { - "OnChainKeylessConfiguration".to_string() - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] -pub struct ConfigData { - pub max_commited_epk_bytes: u16, - pub max_exp_horizon_secs: String, - pub max_extra_field_bytes: u16, - pub max_iss_val_bytes: u16, - pub max_jwt_header_b64_bytes: u32, - pub max_signatures_per_txn: u16, - pub override_aud_vals: Vec, - pub training_wheels_pubkey: TrainingWheelsPubKey, -} - -pub static ONCHAIN_KEYLESS_CONFIG: Lazy>>> = - Lazy::new(|| Arc::new(RwLock::new(None))); diff --git a/keyless/pepper/service/src/lib.rs b/keyless/pepper/service/src/lib.rs index 3c6fe36e779..6d8f6f134b5 100644 --- a/keyless/pepper/service/src/lib.rs +++ b/keyless/pepper/service/src/lib.rs @@ -1,568 +1,15 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - account_db::{init_account_db, ACCOUNT_RECOVERY_DB}, - account_managers::ACCOUNT_MANAGERS, - groth16_vk::ONCHAIN_GROTH16_VK, - keyless_config::ONCHAIN_KEYLESS_CONFIG, - vuf_keys::VUF_SK, - ProcessingFailure::{BadRequest, InternalError}, -}; -use aptos_crypto::{ - asymmetric_encryption::{ - elgamal_curve25519_aes256_gcm::ElGamalCurve25519Aes256Gcm, AsymmetricEncryption, - }, - ed25519::Ed25519PublicKey, -}; -use aptos_infallible::duration_since_epoch; -use aptos_keyless_pepper_common::{ - account_recovery_db::AccountRecoveryDbEntry, - jwt::Claims, - vuf::{ - self, - bls12381_g1_bls::PinkasPepper, - slip_10::{get_aptos_derivation_path, ExtendedPepper}, - VUF, - }, - PepperInput, PepperRequest, PepperResponse, SignatureResponse, VerifyRequest, VerifyResponse, -}; -use aptos_logger::{info, warn}; -use aptos_types::{ - account_address::AccountAddress, - keyless::{ - get_public_inputs_hash, Configuration, EphemeralCertificate, Groth16ProofAndStatement, - IdCommitment, KeylessPublicKey, KeylessSignature, OpenIdSig, ZKP, - }, - transaction::authenticator::{ - AnyPublicKey, AnySignature, AuthenticationKey, EphemeralPublicKey, - }, -}; -use firestore::{async_trait, paths, struct_path::path}; -use jsonwebtoken::{Algorithm::RS256, DecodingKey, Validation}; -use jwk::get_federated_jwk; -use rand::thread_rng; -use serde::{Deserialize, Serialize}; -use std::time::{SystemTime, UNIX_EPOCH}; -use uuid::Uuid; - -pub mod about; -pub mod account_db; -pub mod account_managers; -pub mod groth16_vk; -pub mod jwk; -pub mod keyless_config; +pub mod accounts; +pub mod dedicated_handlers; +pub mod deployment_information; +pub mod error; +pub mod external_resources; pub mod metrics; -pub mod vuf_keys; -pub mod watcher; - -pub type Issuer = String; -pub type KeyID = String; - -#[derive(Debug, Deserialize, Serialize)] -pub enum ProcessingFailure { - BadRequest(String), - InternalError(String), -} - -pub const DEFAULT_DERIVATION_PATH: &str = "m/44'/637'/0'/0'/0'"; - -#[async_trait] -pub trait HandlerTrait: Send + Sync { - async fn handle(&self, request: REQ) -> Result; -} - -pub struct V0FetchHandler; - -#[async_trait] -impl HandlerTrait for V0FetchHandler { - async fn handle(&self, request: PepperRequest) -> Result { - let session_id = Uuid::new_v4(); - let PepperRequest { - jwt, - epk, - exp_date_secs, - epk_blinder, - uid_key, - derivation_path, - } = request; - - let (_pepper_base, pepper, address) = process_common( - &session_id, - jwt, - epk, - exp_date_secs, - epk_blinder, - uid_key, - derivation_path, - false, - None, - true, - ) - .await?; - - Ok(PepperResponse { - pepper, - address: address.to_vec(), - }) - } -} - -pub struct V0SignatureHandler; - -#[async_trait] -impl HandlerTrait for V0SignatureHandler { - async fn handle(&self, request: PepperRequest) -> Result { - let session_id = Uuid::new_v4(); - let PepperRequest { - jwt, - epk, - exp_date_secs, - epk_blinder, - uid_key, - derivation_path, - } = request; - - let (pepper_base, _pepper, _address) = process_common( - &session_id, - jwt, - epk, - exp_date_secs, - epk_blinder, - uid_key, - derivation_path, - false, - None, - false, - ) - .await?; - - Ok(SignatureResponse { - signature: pepper_base, - }) - } -} - -#[macro_export] -macro_rules! invalid_signature { - ($message:expr) => { - BadRequest($message.to_owned()) - }; -} - -pub struct V0VerifyHandler; - -#[async_trait] -impl HandlerTrait for V0VerifyHandler { - async fn handle(&self, request: VerifyRequest) -> Result { - let VerifyRequest { - public_key, - signature, - message, - address: _, - } = request; - if let (AnyPublicKey::Keyless { public_key }, AnySignature::Keyless { signature }) = - (&public_key, &signature) - { - let KeylessPublicKey { idc: _, iss_val } = public_key; - let KeylessSignature { - cert, - jwt_header_json: _, - exp_date_secs: _, - ephemeral_pubkey, - ephemeral_signature, - } = signature; - let current_time_microseconds = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_micros() as u64; - signature - .verify_expiry(current_time_microseconds) - .map_err(|_| invalid_signature!("The ephemeral keypair has expired"))?; - ephemeral_signature - .verify_arbitrary_msg(&message, ephemeral_pubkey) - .map_err(|e| BadRequest(format!("Ephemeral sig check failed: {e}")))?; - let jwt_header = signature - .parse_jwt_header() - .map_err(|e| BadRequest(format!("JWT header decoding error: {e}")))?; - let jwk = jwk::cached_decoding_key_as_rsa(iss_val, &jwt_header.kid) - .map_err(|e| BadRequest(format!("JWK not found: {e}")))?; - let config_api_repr = - { ONCHAIN_KEYLESS_CONFIG.read().as_ref().cloned() }.ok_or_else(|| { - InternalError("API keyless config not cached locally.".to_string()) - })?; - let config = config_api_repr - .to_rust_repr() - .map_err(|e| InternalError(format!("Could not parse API keyless config: {e}")))?; - let training_wheels_pk = match &config.training_wheels_pubkey { - None => None, - // This takes ~4.4 microseconds, so we are not too concerned about speed here. - // (Run `cargo bench -- ed25519/pk_deserialize` in `crates/aptos-crypto`.) - Some(bytes) => Some(EphemeralPublicKey::ed25519( - Ed25519PublicKey::try_from(bytes.as_slice()).map_err(|_| { - // println!("[aptos-vm][groth16] On chain TW PK is invalid"); - invalid_signature!("The training wheels PK set on chain is not a valid PK") - })?, - )), - }; - match cert { - EphemeralCertificate::ZeroKnowledgeSig(zksig) => { - if zksig.exp_horizon_secs > config.max_exp_horizon_secs { - // println!("[aptos-vm][groth16] Expiration horizon is too long"); - return Err(invalid_signature!("The expiration horizon is too long")); - } - if zksig.override_aud_val.is_some() { - config - .is_allowed_override_aud(zksig.override_aud_val.as_ref().unwrap()) - .map_err(|_| { - // println!("[aptos-vm][groth16] PIH computation failed"); - invalid_signature!("Could not compute public inputs hash") - })?; - } - match &zksig.proof { - ZKP::Groth16(groth16proof) => { - // let start = std::time::Instant::now(); - let public_inputs_hash = - get_public_inputs_hash(signature, public_key, &jwk, &config) - .map_err(|_| { - // println!("[aptos-vm][groth16] PIH computation failed"); - invalid_signature!("Could not compute public inputs hash") - })?; - // println!("Public inputs hash time: {:?}", start.elapsed()); - - let groth16_and_stmt = - Groth16ProofAndStatement::new(*groth16proof, public_inputs_hash); - - // The training wheels signature is only checked if a training wheels PK is set on chain - if training_wheels_pk.is_some() { - match &zksig.training_wheels_signature { - Some(training_wheels_sig) => { - training_wheels_sig - .verify( - &groth16_and_stmt, - training_wheels_pk.as_ref().unwrap(), - ) - .map_err(|_| { - // println!("[aptos-vm][groth16] TW sig verification failed"); - invalid_signature!( - "Could not verify training wheels signature" - ) - })?; - }, - None => { - // println!("[aptos-vm][groth16] Expected TW sig to be set"); - return Err(invalid_signature!( - "Training wheels signature expected but it is missing" - )); - }, - } - } - - let onchain_groth16_vk = - { ONCHAIN_GROTH16_VK.read().as_ref().cloned() }.ok_or_else( - || InternalError("No Groth16 VK cached locally.".to_string()), - )?; - let ark_groth16_pvk = onchain_groth16_vk.to_ark_pvk().map_err(|e| { - InternalError(format!("Onchain-to-ark convertion err: {e}")) - })?; - let result = - zksig.verify_groth16_proof(public_inputs_hash, &ark_groth16_pvk); - result.map_err(|_| { - // println!("[aptos-vm][groth16] ZKP verification failed"); - // println!("[aptos-vm][groth16] PIH: {}", public_inputs_hash); - // match zksig.proof { - // ZKP::Groth16(proof) => { - // println!("[aptos-vm][groth16] ZKP: {}", proof.hash()); - // }, - // } - // println!( - // "[aptos-vm][groth16] PVK: {}", - // Groth16VerificationKey::from(pvk).hash() - // ); - invalid_signature!("Proof verification failed") - })?; - }, - } - }, - EphemeralCertificate::OpenIdSig(_) => { - return Err(invalid_signature!( - "Could not verify training wheels signature" - )) - }, - } - return Ok(VerifyResponse { success: true }); - } - Err(invalid_signature!("Not a keyless signature")) - } -} - -async fn process_common( - session_id: &Uuid, - jwt: String, - epk: EphemeralPublicKey, - exp_date_secs: u64, - epk_blinder: Vec, - uid_key: Option, - derivation_path: Option, - encrypts_pepper: bool, - aud: Option, - should_update_account_recovery_db: bool, -) -> Result<(Vec, Vec, AccountAddress), ProcessingFailure> { - let config = Configuration::new_for_devnet(); - - let derivation_path = if let Some(path) = derivation_path { - path - } else { - DEFAULT_DERIVATION_PATH.to_owned() - }; - let checked_derivation_path = - get_aptos_derivation_path(&derivation_path).map_err(|e| BadRequest(e.to_string()))?; - - let curve25519_pk_point = match &epk { - EphemeralPublicKey::Ed25519 { public_key } => public_key - .to_compressed_edwards_y() - .decompress() - .ok_or_else(|| BadRequest("the pk point is off-curve".to_string()))?, - _ => { - return Err(BadRequest("Only Ed25519 epk is supported".to_string())); - }, - }; - - let claims = aptos_keyless_pepper_common::jwt::parse(jwt.as_str()) - .map_err(|e| BadRequest(format!("JWT decoding error: {e}")))?; - let now_secs = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs(); - if exp_date_secs <= now_secs { - return Err(BadRequest("epk expired".to_string())); - } - - let (max_exp_data_secs, overflowed) = claims - .claims - .iat - .overflowing_add(config.max_exp_horizon_secs); - if overflowed { - return Err(BadRequest("max_exp_data_secs overflowed".to_string())); - } - if exp_date_secs >= max_exp_data_secs { - return Err(BadRequest("epk expiry date too far".to_string())); - } - - let actual_uid_key = if let Some(uid_key) = uid_key.as_ref() { - uid_key - } else { - "sub" - }; - - let uid_val = if actual_uid_key == "email" { - claims - .claims - .email - .clone() - .ok_or_else(|| BadRequest("`email` required but not found in jwt".to_string()))? - } else if actual_uid_key == "sub" { - claims.claims.sub.clone() - } else { - return Err(BadRequest(format!( - "unsupported uid key: {}", - actual_uid_key - ))); - }; - - let recalculated_nonce = - OpenIdSig::reconstruct_oauth_nonce(epk_blinder.as_slice(), exp_date_secs, &epk, &config) - .map_err(|e| BadRequest(format!("nonce reconstruction error: {e}")))?; - - if claims.claims.nonce != recalculated_nonce { - return Err(BadRequest("with nonce mismatch".to_string())); - } - - let key_id = claims - .header - .kid - .ok_or_else(|| BadRequest("missing kid in JWT".to_string()))?; - - let cached_key = jwk::cached_decoding_key_as_rsa(&claims.claims.iss, &key_id); - - let jwk = match cached_key { - Ok(key) => key, - Err(_) => get_federated_jwk(&jwt) - .await - .map_err(|e| BadRequest(format!("JWK not found: {e}")))?, - }; - let jwk_decoding_key = DecodingKey::from_rsa_components(&jwk.n, &jwk.e) - .map_err(|e| BadRequest(format!("JWK not found: {e}")))?; - - let mut validation_with_sig_verification = Validation::new(RS256); - validation_with_sig_verification.validate_exp = false; // Don't validate the exp time - let _claims = jsonwebtoken::decode::( - jwt.as_str(), - &jwk_decoding_key, - &validation_with_sig_verification, - ) // Signature verification happens here. - .map_err(|e| BadRequest(format!("JWT signature verification failed: {e}")))?; - - // If the pepper request is is from an account manager, and has a target aud specified, compute the pepper for the target aud. - let mut aud_overridden = false; - let mut final_aud = claims.claims.aud.clone(); - if ACCOUNT_MANAGERS.contains(&(claims.claims.iss.clone(), claims.claims.aud.clone())) { - if let Some(aud) = aud { - final_aud = aud; - aud_overridden = true; - } - }; - - let input = PepperInput { - iss: claims.claims.iss.clone(), - uid_key: actual_uid_key.to_string(), - uid_val, - aud: final_aud, - }; - - if !aud_overridden { - info!( - session_id = session_id, - iss = input.iss.clone(), - aud = input.aud.clone(), - uid_val = input.uid_val.clone(), - uid_key = input.uid_key.clone(), - "PepperInput is available." - ); - if should_update_account_recovery_db { - update_account_recovery_db(&input).await?; - } - } - - let input_bytes = bcs::to_bytes(&input).unwrap(); - let (pepper_base, vuf_proof) = vuf::bls12381_g1_bls::Bls12381G1Bls::eval(&VUF_SK, &input_bytes) - .map_err(|e| InternalError(format!("bls12381_g1_bls eval error: {e}")))?; - if !vuf_proof.is_empty() { - return Err(InternalError("proof size should be 0".to_string())); - } - - let pinkas_pepper = PinkasPepper::from_affine_bytes(&pepper_base) - .map_err(|_| InternalError("Failed to derive pinkas pepper".to_string()))?; - let master_pepper = pinkas_pepper.to_master_pepper(); - let derived_pepper = ExtendedPepper::from_seed(master_pepper.to_bytes()) - .map_err(|e| InternalError(e.to_string()))? - .derive(&checked_derivation_path) - .map_err(|e| InternalError(e.to_string()))? - .get_pepper(); - - let idc = IdCommitment::new_from_preimage( - &derived_pepper, - &input.aud, - &input.uid_key, - &input.uid_val, - ) - .map_err(|e| InternalError(e.to_string()))?; - let public_key = KeylessPublicKey { - iss_val: input.iss, - idc, - }; - let address = - AuthenticationKey::any_key(AnyPublicKey::keyless(public_key.clone())).account_address(); - - if encrypts_pepper { - let mut main_rng: rand::prelude::ThreadRng = thread_rng(); - let mut aead_rng = aes_gcm::aead::OsRng; - let pepper_base_encrypted = ElGamalCurve25519Aes256Gcm::enc( - &mut main_rng, - &mut aead_rng, - &curve25519_pk_point, - &pepper_base, - ) - .map_err(|e| InternalError(format!("ElGamalCurve25519Aes256Gcm enc error: {e}")))?; - let pepper_encrypted = ElGamalCurve25519Aes256Gcm::enc( - &mut main_rng, - &mut aead_rng, - &curve25519_pk_point, - derived_pepper.to_bytes(), - ) - .map_err(|e| InternalError(format!("ElGamalCurve25519Aes256Gcm enc error: {e}")))?; - Ok((pepper_base_encrypted, pepper_encrypted, address)) - } else { - Ok((pepper_base, derived_pepper.to_bytes().to_vec(), address)) - } -} - -/// Save a pepper request into the account recovery DB. -/// -/// TODO: once the account recovery DB flow is verified working e2e, DB error should not be ignored. -async fn update_account_recovery_db(input: &PepperInput) -> Result<(), ProcessingFailure> { - match ACCOUNT_RECOVERY_DB.get_or_init(init_account_db).await { - Ok(db) => { - let entry = AccountRecoveryDbEntry { - iss: input.iss.clone(), - aud: input.aud.clone(), - uid_key: input.uid_key.clone(), - uid_val: input.uid_val.clone(), - first_request_unix_ms_minus_1q: None, - last_request_unix_ms: None, - num_requests: None, - }; - let doc_id = entry.document_id(); - let now_unix_ms = duration_since_epoch().as_millis() as i64; - - // The update transactions use the following strategy. - // 1. If not exists, create the document for the user identifier `(iss, aud, uid_key, uid_val)`. - // but leave counter/time fields unspecified. - // 2. `num_requests += 1`, assuming the default value is 0. - // 3. `last_request_unix_ms = max(last_request_unix_ms, now)`, assuming the default value is 0. - // 4. `first_request_unix_ms = min(first_request_unix_ms, now)`, assuming the default value is +inf. - // - // This strategy is preferred because all the operations can be made server-side, - // which means the txn should require only 1 RTT, - // better than using read-compute-write pattern that requires 2 RTTs. - // - // This strategy does not work directly: - // in firestore, the default value of a number field is 0, and we do not know a way to customize it for op 4. - // The workaround here is apply an offset so 0 becomes a legitimate default value. - // So we work with `first_request_unix_ms_minus_1q` instead, - // which is defined as `first_request_unix_ms - 1_000_000_000_000_000`, - // where 1_000_000_000_000_000 milliseconds is roughly 31710 years. - - let mut txn = db - .begin_transaction() - .await - .map_err(|e| InternalError(format!("begin_transaction error: {e}")))?; - db.fluent() - .update() - .fields(paths!(AccountRecoveryDbEntry::{iss, aud, uid_key, uid_val})) - .in_col("accounts") - .document_id(&doc_id) - .object(&entry) // op 1 - .transforms(|builder| { - builder.fields([ - builder - .field(path!(AccountRecoveryDbEntry::num_requests)) - .increment(1), // op 2 - builder - .field(path!(AccountRecoveryDbEntry::last_request_unix_ms)) - .maximum(now_unix_ms), // op 3 - builder - .field(path!( - AccountRecoveryDbEntry::first_request_unix_ms_minus_1q - )) - .minimum(now_unix_ms - 1_000_000_000_000_000), // op 4 - ]) - }) - .add_to_transaction(&mut txn) - .map_err(|e| InternalError(format!("add_to_transaction error: {e}")))?; - let txn_result = txn.commit().await; - - if let Err(e) = txn_result { - warn!("ACCOUNT_RECOVERY_DB operation failed: {e}"); - } - Ok(()) - }, - Err(e) => { - warn!("ACCOUNT_RECOVERY_DB client failed to init: {e}"); - Ok(()) - }, - } -} +pub mod request_handler; +pub mod utils; +pub mod vuf_keypair; #[cfg(test)] mod tests; diff --git a/keyless/pepper/service/src/main.rs b/keyless/pepper/service/src/main.rs index 6a722b3fa95..02ac0ff0e1c 100644 --- a/keyless/pepper/service/src/main.rs +++ b/keyless/pepper/service/src/main.rs @@ -1,212 +1,487 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_keyless_pepper_common::BadPepperRequestError; +use aptos_crypto::constant_time; +use aptos_keyless_pepper_common::PepperInput; use aptos_keyless_pepper_service::{ - about::ABOUT_JSON, - account_db::{init_account_db, ACCOUNT_RECOVERY_DB}, - account_managers::ACCOUNT_MANAGERS, - groth16_vk::ONCHAIN_GROTH16_VK, - jwk::{self, parse_jwks, DECODING_KEY_CACHE}, - keyless_config::ONCHAIN_KEYLESS_CONFIG, - metrics::start_metric_server, - vuf_keys::{PEPPER_VUF_VERIFICATION_KEY_JSON, VUF_SK}, - watcher::start_external_resource_refresh_loop, - HandlerTrait, - ProcessingFailure::{BadRequest, InternalError}, - V0FetchHandler, V0SignatureHandler, V0VerifyHandler, + accounts::{ + account_managers::{AccountRecoveryManager, AccountRecoveryManagers}, + account_recovery_db::{ + AccountRecoveryDBInterface, FirestoreAccountRecoveryDB, TestAccountRecoveryDB, + }, + }, + dedicated_handlers::pepper_request, + deployment_information::DeploymentInformation, + external_resources::{ + jwk_fetcher, + jwk_fetcher::{JWKCache, JWKIssuer}, + resource_fetcher, + resource_fetcher::CachedResources, + }, + metrics, + metrics::DEFAULT_METRICS_SERVER_PORT, + request_handler, + request_handler::DEFAULT_PEPPER_SERVICE_PORT, + utils, vuf_keypair, + vuf_keypair::VUFKeypair, }; -use aptos_logger::{error, info}; -use aptos_types::keyless::test_utils::get_sample_iss; +use aptos_logger::{error, info, warn}; +use clap::Parser; +use dudect_bencher::{ctbench, ctbench::BenchName}; use hyper::{ - header::{ - ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, - ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE, - }, service::{make_service_fn, service_fn}, - Body, Method, Request, Response, Server, StatusCode, + Server, }; -use serde::{de::DeserializeOwned, Serialize}; -use std::{convert::Infallible, fmt::Debug, net::SocketAddr, ops::Deref, time::Duration}; - -async fn handle_request(req: Request) -> Result, Infallible> { - let origin = req - .headers() - .get("origin") - .and_then(|v| v.to_str().ok()) - .unwrap_or("") - .to_owned(); - let response = match (req.method(), req.uri().path()) { - (&Method::GET, "/about") => { - build_response(origin, StatusCode::OK, ABOUT_JSON.deref().clone()) - }, - (&Method::GET, "/cached/keyless-config") => build_response_for_optional_resource( - origin, - ONCHAIN_KEYLESS_CONFIG.read().as_ref().cloned(), - ), - (&Method::GET, "/cached/groth16-vk") => build_response_for_optional_resource( - origin, - ONCHAIN_GROTH16_VK.read().as_ref().cloned(), - ), - (&Method::GET, "/v0/vuf-pub-key") => build_response( - origin, - StatusCode::OK, - PEPPER_VUF_VERIFICATION_KEY_JSON.deref().clone(), - ), - (&Method::POST, "/v0/signature") => { - generate_response(origin, req, &V0SignatureHandler).await - }, - (&Method::POST, "/v0/verify") => generate_response(origin, req, &V0VerifyHandler).await, - (&Method::POST, "/v0/fetch") => generate_response(origin, req, &V0FetchHandler).await, - (&Method::OPTIONS, _) => hyper::Response::builder() - .status(StatusCode::OK) - .header(ACCESS_CONTROL_ALLOW_ORIGIN, origin) - .header(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true") - .header(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS") - .header(ACCESS_CONTROL_ALLOW_HEADERS, "*") - .body(Body::empty()) - .expect("Response should build"), - _ => { - let mut response = hyper::Response::new(Body::empty()); - *response.status_mut() = StatusCode::NOT_FOUND; - response - }, - }; - Ok(response) +use more_asserts::assert_le; +use num_traits::ToPrimitive; +use std::{convert::Infallible, net::SocketAddr, sync::Arc, time::Instant}; + +// The key used to store the derived pepper in the deployment information +const DERIVED_PEPPER_ON_STARTUP_KEY: &str = "derived_pepper_on_startup"; + +// Constants for deriving the fixed pepper on startup. These are +// hardcoded to ensure that the pepper derivation logic remains +// consistent and backwards compatible across deployments. +const FIXED_PEPPER_INPUT_ISS: &str = "fixed_issuer"; +const FIXED_PEPPER_INPUT_UID_KEY: &str = "fixed_sub"; +const FIXED_PEPPER_INPUT_UID_VAL: &str = "fixed_user_id"; +const FIXED_PEPPER_INPUT_AUD: &str = "fixed_audience"; + +// The field name in the VUF JSON that contains the public key +const PUBLIC_KEY_FIELD_NAME: &str = "public_key"; + +#[derive(Parser, Debug)] +#[command(author, version, about)] +struct Args { + /// A list of account recovery managers that are allowed to override the + /// aud claim in the JWTs they issue when handling pepper requests. + /// + /// For example: + /// --account-recovery-managers="https://accounts.google.com 1234567890" + /// --account-recovery-managers="https://accounts.facebook.com 9876543210" + #[arg(long)] + account_recovery_managers: Vec, + + /// Disable asynchronous updates to the account recovery database. + /// By default, async updates are enabled to avoid blocking request handlers. + #[arg(long)] + disable_async_db_updates: bool, // Defaults to false if not provided + + /// If provided, the pepper service will compute a locally derived pepper + /// and compare it against this expected (hex encoded) value. This helps to + /// ensure that the pepper derivation logic is consistent and backwards + /// compatible. If no value is provided, no verification will be done. + #[arg(long)] + expected_derived_pepper_on_startup: Option, + + /// If provided, the pepper service will verify that the VUF public key + /// matches this expected (hex encoded) value on startup. This helps to + /// ensure that the correct VUF keypair is being used by the service. If + /// no value is provided, no verification will be done. + #[arg(long)] + expected_vuf_pubkey_on_startup: Option, + + /// The Firestore database ID (required to connect to Firestore). + /// Only required if not running in local development mode. + #[arg( + long, + requires = "google_project_id", + required_unless_present = "local_development_mode", + conflicts_with = "local_development_mode" + )] + firestore_database_id: Option, + + /// The Google Cloud Project ID (required to connect to Firestore). + /// Only required if not running in local development mode. + #[arg( + long, + requires = "firestore_database_id", + required_unless_present = "local_development_mode", + conflicts_with = "local_development_mode" + )] + google_project_id: Option, + + /// Run the service in local development mode (uses a test account recovery database). + /// If this flag is not provided, the service will use the Firestore account recovery database. + #[arg( + long, + conflicts_with_all = ["firestore_database_id", "google_project_id"] + )] + local_development_mode: bool, // Defaults to false if not provided + + /// The URL to fetch the on-chain keyless account configuration resource (if not provided, no fetching will be done) + #[arg(long)] + on_chain_groth16_vk_url: Option, + + /// The URL to fetch the on-chain keyless account configuration resource (if not provided, no fetching will be done) + #[arg(long)] + on_chain_keyless_config_url: Option, + + /// The port for the Pepper service to listen on + #[arg(long, default_value_t = DEFAULT_PEPPER_SERVICE_PORT)] + pepper_service_port: u16, + + /// The hex-encoded VUF private key (used directly if provided, otherwise derived from the seed) + #[arg( + long, + required_unless_present = "vuf_private_key_seed_hex", + conflicts_with = "vuf_private_key_seed_hex" + )] + vuf_private_key_hex: Option, + + /// The hex-encoded VUF private key seed (used to derive the private key if the key is not provided directly) + #[arg( + long, + required_unless_present = "vuf_private_key_hex", + conflicts_with = "vuf_private_key_hex" + )] + vuf_private_key_seed_hex: Option, + + /// A list of JWK URLs the pepper service should monitor in addition to the default issuers. + /// This can also be used to override the JWK URL of default issuers. + /// + /// For example: + /// --jwk-issuers-override="https://accounts.google.com https://www.googleapis.com/oauth2/v999/certs" + /// --jwk-issuers-override="https://www.facebook.com https://www.facebook.com/.well-known/oauth/openid/jwks" + #[arg(long)] + jwk_issuers_override: Vec, } +/// The DudeCT statistical test must output a `max_t` value whose absolute value is <= to this. +/// +/// Docs here: https://docs.rs/dudect-bencher/latest/dudect_bencher/ +/// Original paper here: https://eprint.iacr.org/2016/1123.pdf +const ABS_MAX_T: i64 = 5; + #[tokio::main] async fn main() { - // Trigger private key loading. - let _ = VUF_SK.deref(); - let _ = ACCOUNT_MANAGERS.deref(); - { - let _db = ACCOUNT_RECOVERY_DB.get_or_init(init_account_db).await; - } + // Fetch the command line arguments + let args = Args::parse(); + + // Start the logger aptos_logger::Logger::new().init(); - start_metric_server(); - if let Ok(url) = std::env::var("ONCHAIN_GROTH16_VK_URL") { - start_external_resource_refresh_loop( - &url, - Duration::from_secs(10), - ONCHAIN_GROTH16_VK.clone(), - ); - } - if let Ok(url) = std::env::var("ONCHAIN_KEYLESS_CONFIG_URL") { - start_external_resource_refresh_loop( - &url, - Duration::from_secs(10), - ONCHAIN_KEYLESS_CONFIG.clone(), - ); - } + info!("Starting the Pepper service..."); + + // Start the metrics server + start_metrics_server(); + + // Get the deployment information + let deployment_information = DeploymentInformation::new(); - // TODO: JWKs should be from on-chain states? - jwk::start_jwk_refresh_loop( - "https://accounts.google.com", - "https://www.googleapis.com/oauth2/v3/certs", - Duration::from_secs(10), + // Fetch the VUF public and private keypair (this will load the private key into memory) + info!("Fetching the VUF public and private keypair for the pepper service..."); + let vuf_keypair = Arc::new(vuf_keypair::get_pepper_service_vuf_keypair( + args.vuf_private_key_hex.clone(), + args.vuf_private_key_seed_hex.clone(), + )); + info!( + "Retrieved the VUF public key: {:?}", + vuf_keypair.vuf_public_key_json() ); - jwk::start_jwk_refresh_loop( - "https://appleid.apple.com", - "https://appleid.apple.com/auth/keys", - Duration::from_secs(10), + + // Verify the critical service invariants + info!("Verifying critical service invariants..."); + verify_critical_service_invariants(&args, vuf_keypair.clone(), deployment_information.clone()); + + // Collect the account recovery managers + info!("Collecting the account recovery managers..."); + let account_recovery_managers = + Arc::new(AccountRecoveryManagers::new(args.account_recovery_managers)); + + // Start the cached resource fetcher + let cached_resources = resource_fetcher::start_cached_resource_fetcher( + args.on_chain_groth16_vk_url, + args.on_chain_keyless_config_url, ); - let test_jwk = include_str!("../../../../types/src/jwks/rsa/secure_test_jwk.json"); - DECODING_KEY_CACHE.insert( - get_sample_iss(), - parse_jwks(test_jwk).expect("test jwk should parse"), + // Create the account recovery database + let account_recovery_db: Arc = + if args.local_development_mode { + warn!("Running in local development mode! Using a test account recovery database!"); + Arc::new(TestAccountRecoveryDB::new()) + } else { + let google_project_id = args.google_project_id.expect( + "Google Project ID must be provided when not running in local development mode!", + ); + let firestore_database_id = args.firestore_database_id.expect( + "Firestore Database ID must be provided when not running in local development mode!", + ); + Arc::new( + FirestoreAccountRecoveryDB::new( + google_project_id, + firestore_database_id, + args.disable_async_db_updates, + ) + .await, + ) + }; + + // Start the JWK fetchers + let jwk_cache = jwk_fetcher::start_jwk_fetchers(args.jwk_issuers_override.clone()); + + // Start the pepper service + start_pepper_service( + args.pepper_service_port, + vuf_keypair, + jwk_cache, + cached_resources, + account_recovery_managers, + account_recovery_db, + deployment_information, + ) + .await; +} + +// Starts a simple metrics server +fn start_metrics_server() { + let _handle = tokio::spawn(async move { + info!("Starting metrics server request handler..."); + + // Create a service function that handles the metrics requests + let make_service = make_service_fn(|_conn| async { + Ok::<_, Infallible>(service_fn(metrics::handle_metrics_request)) + }); + + // Bind the socket address, and start the server + let socket_addr = SocketAddr::from(([0, 0, 0, 0], DEFAULT_METRICS_SERVER_PORT)); + let server = Server::bind(&socket_addr).serve(make_service); + if let Err(error) = server.await { + panic!("Metrics server error! Error: {}", error); + } + }); +} + +// Starts the pepper service +async fn start_pepper_service( + pepper_service_port: u16, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + account_recovery_managers: Arc, + account_recovery_db: Arc, + deployment_information: DeploymentInformation, +) { + info!( + "Starting the Pepper service request handler on port {}...", + pepper_service_port ); - let addr = SocketAddr::from(([0, 0, 0, 0], 8000)); + // Create the service function that handles the endpoint requests + let make_service = make_service_fn(move |_conn| { + // Clone the required Arcs for the service function + let vuf_keypair = vuf_keypair.clone(); + let jwk_cache = jwk_cache.clone(); + let cached_resources = cached_resources.clone(); + let account_recovery_managers = account_recovery_managers.clone(); + let account_recovery_db = account_recovery_db.clone(); + let deployment_information = deployment_information.clone(); + + async move { + Ok::<_, Infallible>(service_fn(move |request| { + // Start the request timer + let request_start_time = Instant::now(); + + // Get the request origin, method and request path + let request_origin = utils::get_request_origin(&request); + let request_method = request.method().clone(); + let request_path = request.uri().path().to_owned(); + + // Clone the required Arcs for the request handler + let vuf_keypair = vuf_keypair.clone(); + let jwk_cache = jwk_cache.clone(); + let cached_resources = cached_resources.clone(); + let account_recovery_managers = account_recovery_managers.clone(); + let account_recovery_db = account_recovery_db.clone(); + let deployment_information = deployment_information.clone(); - let make_svc = - make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle_request)) }); + // Handle the request + async move { + // Call the request handler + let result = request_handler::handle_request( + request, + vuf_keypair.clone(), + jwk_cache.clone(), + cached_resources.clone(), + account_recovery_managers.clone(), + account_recovery_db.clone(), + deployment_information.clone(), + ) + .await; + + // Update the request handling metrics and logs + match &result { + Ok(response) => { + // Update the request handling metrics + metrics::update_request_handling_metrics( + &request_path, + request_method.clone(), + response.status(), + request_start_time, + ); + + // If the response was not successful, log the request details + if !response.status().is_success() { + warn!( + "Handled request with non-successful response! Request origin: {:?}, \ + request path: {:?}, request method: {:?}, response status: {:?}", + request_origin, + request_path, + request_method, + response.status() + ); + } + }, + Err(error) => { + error!( + "Error occurred when handling request! Request origin: {:?}, \ + request path: {:?}, request method: {:?}, Error: {:?}", + request_origin, request_path, request_method, error + ); + }, + } - let server = Server::bind(&addr).serve(make_svc); + result + } + })) + } + }); - if let Err(e) = server.await { - eprintln!("server error: {}", e); + // Bind the socket address, and start the server + let socket_addr = SocketAddr::from(([0, 0, 0, 0], pepper_service_port)); + let server = Server::bind(&socket_addr).serve(make_service); + if let Err(error) = server.await { + panic!("Pepper service error! Error: {}", error); } } -/// Feed a request into a handler and wrap the output as an HTTP response. -async fn generate_response( - origin: String, - req: Request, - handler: &HDLR, -) -> Response -where - PREQ: Debug + Serialize + DeserializeOwned, - PRES: Debug + Serialize, - HDLR: HandlerTrait + Send + Sync, -{ - let body = req.into_body(); - let body_bytes = hyper::body::to_bytes(body).await.unwrap_or_default(); - let pepper_request = serde_json::from_slice::(&body_bytes); - let (status_code, body_json) = match pepper_request { - Ok(request) => { - let pepper_response = handler.handle(request).await; - match pepper_response { - Ok(pepper_response) => { - info!("Request processed normally."); - ( - StatusCode::OK, - serde_json::to_string_pretty(&pepper_response).unwrap(), - ) - }, - Err(BadRequest(err)) => { - info!("Processing failed with bad request: {err}"); - ( - StatusCode::BAD_REQUEST, - serde_json::to_string_pretty(&BadPepperRequestError { - message: err.to_string(), - }) - .unwrap(), - ) - }, - Err(InternalError(e)) => { - error!("Processing failed with internal error: {e}"); - (StatusCode::INTERNAL_SERVER_ERROR, String::new()) - }, - } - }, - Err(err) => { - error!("Processing did not start due to bad request: {err}"); - ( - StatusCode::BAD_REQUEST, - serde_json::to_string_pretty(&BadPepperRequestError { - message: err.to_string(), - }) - .unwrap(), - ) - }, - }; +/// Verifies that scalar multiplication is constant time +fn verify_constant_time_scalar_multiplication() { + // Run the constant time benchmarks for random bases + let abs_max_t = ctbench::run_bench( + &BenchName("blstrs_scalar_mul/random_bases"), + constant_time::blstrs_scalar_mul::run_bench_with_random_bases, + None, + ) + .1 + .max_t + .abs() + .ceil() + .to_i64() + .expect("Floating point arithmetic went awry."); + assert_le!(abs_max_t, ABS_MAX_T); - build_response(origin, status_code, body_json) + // Run the constant time benchmarks for fixed bases + let abs_max_t = ctbench::run_bench( + &BenchName("blstrs_scalar_mul/fixed_bases"), + constant_time::blstrs_scalar_mul::run_bench_with_fixed_bases, + None, + ) + .1 + .max_t + .abs() + .ceil() + .to_i64() + .expect("Floating point arithmetic went awry."); + assert_le!(abs_max_t, ABS_MAX_T); } -fn build_response(origin: String, status_code: StatusCode, body_str: String) -> Response { - hyper::Response::builder() - .status(status_code) - .header(ACCESS_CONTROL_ALLOW_ORIGIN, origin) - .header(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true") - .header(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS") - .header(ACCESS_CONTROL_ALLOW_HEADERS, "*") - .header(CONTENT_TYPE, "application/json") - .body(Body::from(body_str)) - .expect("Response should build") +/// Verifies critical service invariants. If any of the invariants fail, +/// this function will panic. This helps to ensure that no critical properties +/// are violated during development, or after deployment. +fn verify_critical_service_invariants( + args: &Args, + vuf_keypair: Arc, + deployment_information: DeploymentInformation, +) { + // Verify constant-time scalar multiplication if in production. + if args.local_development_mode { + info!( + "Constant-time scalar multiplication verification skipped in local development mode." + ); + } else { + info!("Verifying constant-time scalar multiplication..."); + verify_constant_time_scalar_multiplication(); + } + + // Verify the VUF public key + if let Some(expected_vuf_pubkey) = args.expected_vuf_pubkey_on_startup.as_ref() { + info!("Verifying expected VUF public key..."); + verify_expected_vuf_public_key(vuf_keypair.clone(), expected_vuf_pubkey); + } else { + warn!("No expected VUF public key provided for startup verification!"); + } + + // Verify the expected derived pepper + if let Some(expected_derived_pepper) = args.expected_derived_pepper_on_startup.as_ref() { + info!("Verifying expected derived pepper..."); + verify_expected_derived_pepper( + vuf_keypair, + expected_derived_pepper, + deployment_information, + ); + } else { + warn!("No expected derived pepper provided for startup verification!"); + } } -fn build_response_for_optional_resource( - origin: String, - res: Option, -) -> Response { - match res { - None => build_response(origin, StatusCode::NOT_FOUND, "".to_string()), - Some(val) => match serde_json::to_string(&val) { - Ok(s) => build_response(origin, StatusCode::OK, s), - Err(e) => build_response(origin, StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), - }, +/// Verifies that the locally derived pepper matches the expected +/// value, and if so, inserts it into the deployment information. +/// This is useful for observability and debugging purposes. +fn verify_expected_derived_pepper( + vuf_keypair: Arc, + expected_derived_pepper: &str, + mut deployment_information: DeploymentInformation, +) { + // Create the pepper input + let pepper_input = PepperInput { + iss: FIXED_PEPPER_INPUT_ISS.into(), + uid_key: FIXED_PEPPER_INPUT_UID_KEY.into(), + uid_val: FIXED_PEPPER_INPUT_UID_VAL.into(), + aud: FIXED_PEPPER_INPUT_AUD.into(), + }; + + // Derive the pepper locally and hex encode it + let (_, derived_pepper_bytes, _) = + pepper_request::derive_pepper_and_account_address(vuf_keypair, None, &pepper_input) + .unwrap(); + let derived_pepper = hex::encode(derived_pepper_bytes); + + // Verify the derived pepper matches the expected value + if derived_pepper != expected_derived_pepper { + panic!( + "The derived pepper does not match the expected value! Derived: {:?}, Expected: {:?}", + derived_pepper, expected_derived_pepper + ); + } + + // Insert the derived pepper into the deployment information + deployment_information + .extend_deployment_information(DERIVED_PEPPER_ON_STARTUP_KEY.into(), derived_pepper); +} + +/// Verifies that the local public key matches the expected value +fn verify_expected_vuf_public_key(vuf_keypair: Arc, expected_vuf_public_key: &str) { + // Get the public key as a JSON value + let vuf_public_key_json = vuf_keypair.vuf_public_key_json(); + let vuf_public_key_value = serde_json::from_str::(vuf_public_key_json) + .expect("Failed to parse VUF public key as JSON!"); + + // Extract the public key from the JSON value + let vuf_public_key = vuf_public_key_value + .get(PUBLIC_KEY_FIELD_NAME) + .and_then(|value| value.as_str()) + .unwrap_or_else(|| { + panic!( + "VUF public key JSON does not contain the {} field!", + PUBLIC_KEY_FIELD_NAME + ) + }); + + // Verify the public key matches the expected value + if vuf_public_key != expected_vuf_public_key { + panic!( + "The VUF public key does not match the expected value! Actual: {:?}, Expected: {:?}", + vuf_public_key, expected_vuf_public_key + ); } } diff --git a/keyless/pepper/service/src/metrics.rs b/keyless/pepper/service/src/metrics.rs index 995726de66f..872b7a6139d 100644 --- a/keyless/pepper/service/src/metrics.rs +++ b/keyless/pepper/service/src/metrics.rs @@ -1,53 +1,90 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use crate::request_handler::is_known_path; use aptos_inspection_service::utils::get_encoded_metrics; use aptos_metrics_core::{exponential_buckets, register_histogram_vec, HistogramVec, TextEncoder}; -use hyper::{ - header::CONTENT_TYPE, - service::{make_service_fn, service_fn}, - Body, Method, Server, StatusCode, -}; +use hyper::{header::CONTENT_TYPE, Body, Method, StatusCode}; use once_cell::sync::Lazy; -use std::{convert::Infallible, net::SocketAddr}; +use std::{ + convert::Infallible, + time::{Duration, Instant}, +}; -pub static JWK_FETCH_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - "keyless_pepper_service_jwk_fetch_seconds", - "Seconds taken to process pepper requests by scheme and result.", - &["issuer", "succeeded"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 24).unwrap() +// Default port for the metrics service +pub const DEFAULT_METRICS_SERVER_PORT: u16 = 8080; + +// Invalid request path label +const INVALID_PATH: &str = "invalid-path"; + +// Buckets for tracking latencies +static LATENCY_BUCKETS: Lazy> = Lazy::new(|| { + exponential_buckets( + /*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 24, ) .unwrap() }); -pub static REQUEST_HANDLING_SECONDS: Lazy = Lazy::new(|| { +// Histogram for tracking time taken to write to the account recovery database +static ACCOUNT_RECOVERY_DB_WRITE_SECONDS: Lazy = Lazy::new(|| { register_histogram_vec!( - "keyless_pepper_request_handling_seconds", - "Seconds taken to process pepper requests by scheme and result.", - &["pepper_scheme", "is_ok"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 24).unwrap() + "keyless_pepper_service_account_recovery_db_write_seconds", + "Time taken to write to the account recovery database", + &["succeeded"], + LATENCY_BUCKETS.clone() ) .unwrap() }); -pub fn start_metric_server() { - let _handle = tokio::spawn(async move { - let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); +// Histogram for tracking time taken to fetch external resources +static EXTERNAL_RESOURCE_FETCH_SECONDS: Lazy = Lazy::new(|| { + register_histogram_vec!( + "keyless_pepper_service_external_resource_fetch_seconds", + "Time taken to fetch external resources", + &["resource", "succeeded"], + LATENCY_BUCKETS.clone() + ) + .unwrap() +}); - let make_svc = - make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle_request)) }); +// Histogram for tracking time taken to fetch JWKs by issuer and result +static JWK_FETCH_SECONDS: Lazy = Lazy::new(|| { + register_histogram_vec!( + "keyless_pepper_service_jwk_fetch_seconds", + "Time taken to fetch keyless pepper service jwks", + &["issuer", "succeeded"], + LATENCY_BUCKETS.clone() + ) + .unwrap() +}); - let server = Server::bind(&addr).serve(make_svc); +// Histogram for tracking time taken to derive peppers +static PEPPER_DERIVATION_SECONDS: Lazy = Lazy::new(|| { + register_histogram_vec!( + "keyless_pepper_service_pepper_derivation_seconds", + "Time taken to derive peppers", + &["succeeded"], + LATENCY_BUCKETS.clone() + ) + .unwrap() +}); - if let Err(e) = server.await { - eprintln!("server error: {}", e); - } - }); -} +// Histogram for tracking time taken to handle pepper service requests +static REQUEST_HANDLING_SECONDS: Lazy = Lazy::new(|| { + register_histogram_vec!( + "keyless_pepper_service_request_handling_seconds", + "Seconds taken to process pepper requests by scheme and result.", + &["request_endpoint", "request_method", "response_code"], + LATENCY_BUCKETS.clone() + ) + .unwrap() +}); -async fn handle_request(req: hyper::Request) -> Result, Infallible> { - let response = match (req.method(), req.uri().path()) { +/// Handles incoming HTTP requests for the metrics server +pub async fn handle_metrics_request( + request: hyper::Request, +) -> Result, Infallible> { + let response = match (request.method(), request.uri().path()) { (&Method::GET, "/metrics") => { let buffer = get_encoded_metrics(TextEncoder::new()); hyper::Response::builder() @@ -64,3 +101,71 @@ async fn handle_request(req: hyper::Request) -> Result( + origin: String, + request: Request, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + request_handler: &TRequestHandler, + account_recovery_managers: Arc, + account_recovery_db: Arc, +) -> Result, Infallible> +where + TRequest: Debug + Serialize + DeserializeOwned, + TResponse: Debug + Serialize, + TRequestHandler: HandlerTrait + Send + Sync, +{ + // Get the request body bytes + let request_body = request.into_body(); + let request_bytes = match hyper::body::to_bytes(request_body).await { + Ok(request_bytes) => request_bytes, + Err(error) => { + error!("Failed to get request body bytes: {}", error); + return generate_internal_server_error_response(origin); + }, + }; + + // Extract the pepper request from the request bytes + let pepper_request: TRequest = match serde_json::from_slice(&request_bytes) { + Ok(pepper_request) => pepper_request, + Err(error) => { + let error_string = format!("Failed to deserialize request body JSON: {}", error); + warn!("{}", error_string); + return generate_bad_request_response(origin, error_string); + }, + }; + + // Invoke the handler and generate the response + match request_handler + .handle_request( + vuf_keypair, + jwk_cache, + cached_resources, + pepper_request, + account_recovery_managers, + account_recovery_db, + ) + .await + { + Ok(pepper_response) => { + info!( + "Pepper request processed successfully! Origin: {}, handler: {}", + origin, + request_handler.get_handler_name() + ); + let response_body = match serde_json::to_string_pretty(&pepper_response) { + Ok(response_body) => response_body, + Err(error) => { + error!("Failed to serialize response to pretty JSON: {}", error); + return generate_internal_server_error_response(origin); + }, + }; + generate_json_response(origin, StatusCode::OK, response_body) + }, + Err(PepperServiceError::BadRequest(error)) => { + let error_string = format!( + "Pepper request processing failed with bad request: {}", + error + ); + warn!("{}", error_string); + + let bad_pepper_request_error = BadPepperRequestError { + message: error_string, + }; + let error_message = match serde_json::to_string_pretty(&bad_pepper_request_error) { + Ok(error_message) => error_message, + Err(error) => { + error!("Failed to serialize response to pretty JSON: {}", error); + return generate_internal_server_error_response(origin); + }, + }; + generate_bad_request_response(origin, error_message) + }, + Err(PepperServiceError::InternalError(error)) => { + error!( + "Pepper request processing failed with internal error: {}", + error + ); + generate_internal_server_error_response(origin) + }, + Err(PepperServiceError::UnexpectedError(error)) => { + error!( + "Pepper request processing failed with unexpected error: {}", + error + ); + generate_internal_server_error_response(origin) + }, + } +} + +/// Returns a response builder prepopulated with common headers +fn create_response_builder(origin: String, status_code: StatusCode) -> response::Builder { + hyper::Response::builder() + .status(status_code) + .header(ACCESS_CONTROL_ALLOW_ORIGIN, origin) + .header(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true") +} + +/// Generates a response for the about endpoint +fn generate_about_response( + origin: String, + deployment_information: DeploymentInformation, +) -> Result, Infallible> { + // Serialize the deployment information + let deployment_info_json = + match serde_json::to_string_pretty(&deployment_information.get_deployment_information()) { + Ok(json) => json, + Err(error) => { + error!( + "Failed to serialize deployment information to JSON: {}", + error + ); + return generate_internal_server_error_response(origin); + }, + }; + + // Generate the response + generate_json_response(origin, StatusCode::OK, deployment_info_json) +} + +/// Generates a 400 response for bad requests +fn generate_bad_request_response( + origin: String, + json_error_string: String, +) -> Result, Infallible> { + generate_json_response(origin, StatusCode::BAD_REQUEST, json_error_string) +} + +/// Generates a response for cached resources +fn generate_cached_resource_response( + origin: String, + request_method: &Method, + request_path: &str, + cached_resource: Option, +) -> Result, Infallible> { + if let Some(cached_resource) = cached_resource { + match serde_json::to_string(&cached_resource) { + Ok(response_body) => generate_json_response(origin, StatusCode::OK, response_body), + Err(error) => { + // Failed to serialize the cached resource, return a server error + error!("Failed to serialize to JSON response: {}", error); + generate_internal_server_error_response(origin) + }, + } + } else { + // The cached resource was not found, return a missing resource error + generate_not_found_response(origin, request_method, request_path) + } +} + +/// Generates a 500 response for unexpected internal server errors +fn generate_internal_server_error_response(origin: String) -> Result, Infallible> { + generate_text_response( + origin, + StatusCode::INTERNAL_SERVER_ERROR, + UNEXPECTED_ERROR_MESSAGE.into(), + ) +} + +/// Generates a JSON response with the given status code and body string +fn generate_json_response( + origin: String, + status_code: StatusCode, + body_str: String, +) -> Result, Infallible> { + let response = create_response_builder(origin, status_code) + .header(CONTENT_TYPE, CONTENT_TYPE_JSON) + .body(Body::from(body_str)) + .expect("Failed to build JSON response!"); + Ok(response) +} + +/// Generates a response with the cached JWKs as JSON +fn generate_jwt_cache_response( + origin: String, + jwk_cache: JWKCache, +) -> Result, Infallible> { + let jwk_cache = jwk_cache.lock().deref().clone(); + match serde_json::to_string_pretty(&jwk_cache) { + Ok(response_body) => generate_json_response(origin, StatusCode::OK, response_body), + Err(error) => { + // Failed to serialize the JWK cache, return a server error + error!("Failed to serialize to JSON response: {}", error); + generate_internal_server_error_response(origin.clone()) + }, + } +} + +/// Generates a 405 response for invalid methods on known paths +fn generate_method_not_allowed_response(origin: String) -> Result, Infallible> { + generate_text_response( + origin, + StatusCode::METHOD_NOT_ALLOWED, + METHOD_NOT_ALLOWED_MESSAGE.into(), + ) +} + +/// Generates a 404 response for invalid paths +fn generate_not_found_response( + origin: String, + request_method: &Method, + request_path: &str, +) -> Result, Infallible> { + let response_message = format!( + "The request for '{}' with method '{}' was not found!", + request_path, request_method + ); + generate_text_response(origin, StatusCode::NOT_FOUND, response_message) +} + +/// Generates a response for options requests +fn generate_options_response(origin: String) -> Result, Infallible> { + let response = create_response_builder(origin, StatusCode::OK) + .header(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS") + .header(ACCESS_CONTROL_ALLOW_HEADERS, "*") + .body(Body::empty()) + .expect("Failed to build options response!"); + Ok(response) +} + +/// Generates a text response with the given status code and body string +fn generate_text_response( + origin: String, + status_code: StatusCode, + body_str: String, +) -> Result, Infallible> { + let response = create_response_builder(origin, status_code) + .header(CONTENT_TYPE, CONTENT_TYPE_TEXT) + .body(Body::from(body_str)) + .expect("Failed to build text response!"); + Ok(response) +} + +/// Handles the given request and returns a response +pub async fn handle_request( + request: Request, + vuf_keypair: Arc, + jwk_cache: JWKCache, + cached_resources: CachedResources, + account_recovery_managers: Arc, + account_recovery_db: Arc, + deployment_information: DeploymentInformation, +) -> Result, Infallible> { + // Get the request origin + let origin = utils::get_request_origin(&request); + + // Handle any OPTIONS requests + let request_method = request.method(); + if request_method == Method::OPTIONS { + return generate_options_response(origin); + } + + // Handle any GET requests + let request_path = request.uri().path(); + if request_method == Method::GET { + match request_path { + ABOUT_PATH => return generate_about_response(origin, deployment_information.clone()), + GROTH16_VK_PATH => { + let groth16_vk = cached_resources.read_on_chain_groth16_vk(); + return generate_cached_resource_response( + origin, + request_method, + GROTH16_VK_PATH, + groth16_vk, + ); + }, + JWK_PATH => { + return generate_jwt_cache_response(origin, jwk_cache); + }, + KEYLESS_CONFIG_PATH => { + let keyless_config = cached_resources.read_on_chain_keyless_configuration(); + return generate_cached_resource_response( + origin, + request_method, + KEYLESS_CONFIG_PATH, + keyless_config, + ); + }, + VUF_PUB_KEY_PATH => { + return generate_json_response( + origin, + StatusCode::OK, + vuf_keypair.vuf_public_key_json().clone(), + ); + }, + _ => { /* Continue below */ }, + }; + } + + // Handle any POST requests + if request_method == Method::POST { + match request_path { + DELEGATED_FETCH_PATH => { + return call_dedicated_request_handler( + origin, + request, + vuf_keypair.clone(), + jwk_cache, + cached_resources, + &V0DelegatedFetchHandler, + account_recovery_managers, + account_recovery_db, + ) + .await + }, + FETCH_PATH => { + return call_dedicated_request_handler( + origin, + request, + vuf_keypair.clone(), + jwk_cache, + cached_resources, + &V0FetchHandler, + account_recovery_managers, + account_recovery_db, + ) + .await + }, + SIGNATURE_PATH => { + return call_dedicated_request_handler( + origin, + request, + vuf_keypair.clone(), + jwk_cache, + cached_resources, + &V0SignatureHandler, + account_recovery_managers, + account_recovery_db, + ) + .await + }, + VERIFY_PATH => { + return call_dedicated_request_handler( + origin, + request, + vuf_keypair.clone(), + jwk_cache, + cached_resources, + &V0VerifyHandler, + account_recovery_managers, + account_recovery_db, + ) + .await + }, + _ => { /* Continue below */ }, + }; + } + + // If the request is to a known path but with an invalid method, return a method not allowed response + if is_known_path(request_path) { + return generate_method_not_allowed_response(origin); + } + + // Otherwise, no matching route was found + generate_not_found_response(origin, request_method, request_path) +} + +/// Returns true if the given URI path is a known path/endpoint +pub fn is_known_path(uri_path: &str) -> bool { + ALL_PATHS.contains(&uri_path) +} diff --git a/keyless/pepper/service/src/tests.rs b/keyless/pepper/service/src/tests.rs deleted file mode 100644 index 58b09c0bb79..00000000000 --- a/keyless/pepper/service/src/tests.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{process_common, ProcessingFailure}; -use aptos_crypto::ed25519::Ed25519PublicKey; -use aptos_types::{ - keyless::{ - circuit_testcases::{ - sample_jwt_payload_json_overrides, SAMPLE_EXP_DATE, SAMPLE_JWT_EXTRA_FIELD, - SAMPLE_NONCE, SAMPLE_TEST_ISS_VALUE, SAMPLE_UID_VAL, - }, - test_utils::{get_sample_epk_blinder, get_sample_esk, get_sample_jwt_token_from_payload}, - }, - transaction::authenticator::EphemeralPublicKey, -}; -use uuid::Uuid; - -#[tokio::test] -async fn process_common_should_fail_if_max_exp_data_secs_overflowed() { - let session_id = Uuid::new_v4(); - let sk = get_sample_esk(); - let pk = Ed25519PublicKey::from(&sk); - - let jwt_payload = sample_jwt_payload_json_overrides( - SAMPLE_TEST_ISS_VALUE, - SAMPLE_UID_VAL, - SAMPLE_JWT_EXTRA_FIELD.as_str(), - u64::MAX - 1, // unusual iat - SAMPLE_NONCE.as_str(), - ); - - let jwt = get_sample_jwt_token_from_payload(&jwt_payload); - - let process_result = process_common( - &session_id, - jwt, - EphemeralPublicKey::ed25519(pk), - SAMPLE_EXP_DATE, - get_sample_epk_blinder(), - None, - None, - false, - None, - false, - ) - .await; - assert!( - matches!(process_result, Err(ProcessingFailure::BadRequest(e)) if e.as_str() == "max_exp_data_secs overflowed") - ); -} diff --git a/keyless/pepper/service/src/tests/jwk_fetcher.rs b/keyless/pepper/service/src/tests/jwk_fetcher.rs new file mode 100644 index 00000000000..22cf7eac368 --- /dev/null +++ b/keyless/pepper/service/src/tests/jwk_fetcher.rs @@ -0,0 +1,214 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + error::PepperServiceError, + external_resources::{ + jwk_fetcher, + jwk_fetcher::{JWKCache, JWKIssuerInterface, KeyID, JWK_REFRESH_INTERVAL_SECS}, + }, + tests::utils, +}; +use aptos_infallible::Mutex; +use aptos_time_service::TimeService; +use aptos_types::{jwks, jwks::rsa::RSA_JWK}; +use std::{collections::HashMap, sync::Arc, time::Duration}; +use tokio::{task::JoinHandle, time::timeout}; + +// Test issuer names for Apple and Google +const ISSUER_APPLE: &str = "issuer_apple"; +const ISSUER_GOOGLE: &str = "issuer_google"; + +// Maximum wait time (secs) for each test to complete +const MAX_TEST_WAIT_SECS: u64 = 10; + +/// A mock JWK issuer (for testing JWK fetching and caching) +struct MockJWKIssuer { + issuer_name: String, + jwk_key_set: HashMap>, + num_fetch_failures: Arc>, // The number of fetch failures to simulate +} + +impl MockJWKIssuer { + pub fn new( + issuer_name: String, + jwk_key_set: HashMap>, + num_fetch_failures: u64, + ) -> Self { + Self { + issuer_name, + jwk_key_set, + num_fetch_failures: Arc::new(Mutex::new(num_fetch_failures)), + } + } +} + +#[async_trait::async_trait] +impl JWKIssuerInterface for MockJWKIssuer { + fn issuer_name(&self) -> String { + self.issuer_name.clone() + } + + fn issuer_jwk_url(&self) -> String { + "".into() // The URL is not used in the mock implementation + } + + async fn fetch_jwks(&self) -> anyhow::Result>> { + // If there are failures to simulate, decrement the counter and + // return an error, otherwise, return the JWK key set. + let mut num_fetch_failures = self.num_fetch_failures.lock(); + if *num_fetch_failures > 0 { + *num_fetch_failures -= 1; + Err(anyhow::anyhow!( + "Simulated fetch failure for issuer {}! Failures remaining: {}", + self.issuer_name, + *num_fetch_failures + )) + } else { + Ok(self.jwk_key_set.clone()) + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn jwk_cache_updates_after_interval() { + // Create test JWK key sets + let apple_jwk_key_set = create_test_jwk_key_set(ISSUER_APPLE.into()); + let google_jwk_key_set = create_test_jwk_key_set(ISSUER_GOOGLE.into()); + + // Create mock JWK issuers for Apple and Google + let apple_jwk_issuer = Arc::new(MockJWKIssuer::new( + ISSUER_APPLE.into(), + apple_jwk_key_set.clone(), + 0, + )); + let google_jwk_issuer = Arc::new(MockJWKIssuer::new( + ISSUER_GOOGLE.into(), + google_jwk_key_set.clone(), + 0, + )); + + // Verify that the JWK cache is updated correctly + verify_jwk_cache_updates( + apple_jwk_key_set, + google_jwk_key_set, + apple_jwk_issuer, + google_jwk_issuer, + ) + .await; +} + +#[tokio::test(flavor = "multi_thread")] +async fn jwk_cache_updates_after_failures() { + // Create test JWK key sets + let apple_jwk_key_set = create_test_jwk_key_set(ISSUER_APPLE.into()); + let google_jwk_key_set = create_test_jwk_key_set(ISSUER_GOOGLE.into()); + + // Create mock JWK issuers that fail a few times before succeeding + let num_fetch_failures = 3; + let apple_jwk_issuer = Arc::new(MockJWKIssuer::new( + ISSUER_APPLE.into(), + apple_jwk_key_set.clone(), + num_fetch_failures, + )); + let google_jwk_issuer = Arc::new(MockJWKIssuer::new( + ISSUER_GOOGLE.into(), + google_jwk_key_set.clone(), + num_fetch_failures, + )); + + // Verify that the JWK cache is updated correctly + verify_jwk_cache_updates( + apple_jwk_key_set, + google_jwk_key_set, + apple_jwk_issuer, + google_jwk_issuer, + ) + .await; +} + +/// Creates a JWK cache and starts the refresh loops for known issuers +fn create_and_start_jwk_cache( + apple_jwk_issuer: Arc, + google_jwk_issuer: Arc, + time_service: TimeService, +) -> JWKCache { + // Create the JWK cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + + // Start the JWK refresh loops for Apple and Google + jwk_fetcher::start_jwk_refresh_loop(apple_jwk_issuer, jwk_cache.clone(), time_service.clone()); + jwk_fetcher::start_jwk_refresh_loop(google_jwk_issuer, jwk_cache.clone(), time_service.clone()); + + jwk_cache +} + +/// Creates a test JWK key set with a single RSA key +fn create_test_jwk_key_set(issuer_name: String) -> HashMap> { + // Create several keys with different IDs + let mut key_set = HashMap::new(); + for i in 0..5 { + let key_id = format!("{}_key_{}", issuer_name, i); + key_set.insert(key_id, Arc::new(jwks::insecure_test_rsa_jwk())); + } + + key_set +} + +/// Verifies that the cached resources are eventually updated +/// correctly after the resource fetcher is started. +async fn verify_jwk_cache_updates( + apple_jwk_key_set: HashMap>, + google_jwk_key_set: HashMap>, + apple_jwk_issuer: Arc, + google_jwk_issuer: Arc, +) { + // Create the JWK cache and start the refresh loops + let time_service = TimeService::mock(); + let jwk_cache = + create_and_start_jwk_cache(apple_jwk_issuer, google_jwk_issuer, time_service.clone()); + + // Verify that initially the cache is empty + assert!(jwk_cache.lock().get(ISSUER_APPLE).is_none()); + assert!(jwk_cache.lock().get(ISSUER_GOOGLE).is_none()); + + // Spawn a task that advances time and verifies the cache is eventually updated + let cache_verification_task: JoinHandle> = tokio::spawn({ + let time_service = time_service.clone(); + let jwk_cache = jwk_cache.clone(); + + async move { + loop { + // Advance time by the refresh interval + utils::advance_time_secs(time_service.clone(), JWK_REFRESH_INTERVAL_SECS + 1).await; + + // Grab the cached key sets + let cached_apple_jwk_set = jwk_cache.lock().get(ISSUER_APPLE).cloned(); + let cached_google_jwk_set = jwk_cache.lock().get(ISSUER_GOOGLE).cloned(); + + // Check if the cache has been updated correctly + match (cached_apple_jwk_set, cached_google_jwk_set) { + (Some(cached_apple_jwk_set), Some(cached_google_jwk_set)) => { + assert_eq!(cached_apple_jwk_set, apple_jwk_key_set); + assert_eq!(cached_google_jwk_set, google_jwk_key_set); + return Ok(()); + }, + _ => { + // Yield to allow other tasks to run + tokio::task::yield_now().await; + }, + } + } + } + }); + + // Verify that the JWK cache is eventually updated + if let Err(error) = timeout( + Duration::from_secs(MAX_TEST_WAIT_SECS), + cache_verification_task, + ) + .await + { + panic!("Failed waiting for JWK cache to be updated: {}", error); + } +} diff --git a/keyless/pepper/service/src/tests/mod.rs b/keyless/pepper/service/src/tests/mod.rs new file mode 100644 index 00000000000..4cd8d5d7a86 --- /dev/null +++ b/keyless/pepper/service/src/tests/mod.rs @@ -0,0 +1,8 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +mod jwk_fetcher; +mod pepper_request; +mod request_handler; +mod resource_fetcher; +pub mod utils; diff --git a/keyless/pepper/service/src/tests/pepper_request.rs b/keyless/pepper/service/src/tests/pepper_request.rs new file mode 100644 index 00000000000..5fcf4ae0599 --- /dev/null +++ b/keyless/pepper/service/src/tests/pepper_request.rs @@ -0,0 +1,335 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + dedicated_handlers::pepper_request::handle_pepper_request, + error::PepperServiceError, + external_resources::{ + jwk_fetcher, keyless_config::OnChainKeylessConfiguration, resource_fetcher::CachedResources, + }, + tests::utils, +}; +use aptos_crypto::ed25519::Ed25519PublicKey; +use aptos_infallible::Mutex; +use aptos_types::{ + account_address::AccountAddress, + keyless::{ + circuit_testcases::{ + sample_jwt_payload_json_overrides, SAMPLE_EXP_DATE, SAMPLE_JWT_EXTRA_FIELD, + SAMPLE_NONCE, SAMPLE_TEST_ISS_VALUE, SAMPLE_UID_VAL, + }, + test_utils::{get_sample_epk_blinder, get_sample_esk, get_sample_jwt_token_from_payload}, + OpenIdSig, + }, + transaction::authenticator::EphemeralPublicKey, +}; +use std::{ + collections::HashMap, + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, +}; + +#[tokio::test] +async fn request_ephemeral_public_key_expired() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Create a test JWT + let jwt_payload = sample_jwt_payload_json_overrides( + SAMPLE_TEST_ISS_VALUE, + SAMPLE_UID_VAL, + &SAMPLE_JWT_EXTRA_FIELD, + get_current_time_secs(), + &SAMPLE_NONCE, + ); + let jwt = get_sample_jwt_token_from_payload(&jwt_payload); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + generate_ephemeral_public_key(), + get_current_time_secs() - 10, // Expiry time in the past + get_sample_epk_blinder(), + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string( + pepper_result, + "The ephemeral public key expiry date has passed", + ); +} + +#[tokio::test] +async fn request_ephemeral_public_key_expiry_too_large() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Create a test JWT + let jwt_payload = sample_jwt_payload_json_overrides( + SAMPLE_TEST_ISS_VALUE, + SAMPLE_UID_VAL, + &SAMPLE_JWT_EXTRA_FIELD, + get_current_time_secs(), + &SAMPLE_NONCE, + ); + let jwt = get_sample_jwt_token_from_payload(&jwt_payload); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + generate_ephemeral_public_key(), + u64::MAX / 2, // Large expiry time + get_sample_epk_blinder(), + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string( + pepper_result, + "The ephemeral public key expiry date is too far in the future", + ); +} + +#[tokio::test] +async fn request_invalid_oath_nonce() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Create a test JWT + let jwt_payload = sample_jwt_payload_json_overrides( + SAMPLE_TEST_ISS_VALUE, + SAMPLE_UID_VAL, + &SAMPLE_JWT_EXTRA_FIELD, + get_current_time_secs(), + &SAMPLE_NONCE, + ); + let jwt = get_sample_jwt_token_from_payload(&jwt_payload); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + generate_ephemeral_public_key(), + get_current_time_secs() + 10, + get_sample_epk_blinder(), + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string( + pepper_result, + "The oauth nonce in the JWT does not match the recalculated nonce", + ); +} + +#[tokio::test] +async fn request_invalid_jwt() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + "invalid jwt string".into(), + generate_ephemeral_public_key(), + SAMPLE_EXP_DATE, + get_sample_epk_blinder(), + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string(pepper_result, "JWT decoding error"); +} + +#[tokio::test] +async fn request_invalid_jwt_signature() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the JWK cache + jwk_fetcher::insert_test_jwk(jwk_cache.clone()); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Create an oauth nonce + let ephemeral_public_key = generate_ephemeral_public_key(); + let exp_date_secs = get_current_time_secs() + 10; + let epk_blinder = get_sample_epk_blinder(); + let keyless_configuration = OnChainKeylessConfiguration::new_for_testing() + .get_keyless_configuration() + .unwrap(); + let oauth_nonce = OpenIdSig::reconstruct_oauth_nonce( + &epk_blinder, + exp_date_secs, + &ephemeral_public_key, + &keyless_configuration, + ) + .unwrap(); + + // Create a test JWT + let jwt_payload = sample_jwt_payload_json_overrides( + SAMPLE_TEST_ISS_VALUE, + SAMPLE_UID_VAL, + &SAMPLE_JWT_EXTRA_FIELD, + get_current_time_secs(), + &oauth_nonce, + ); + let jwt = get_sample_jwt_token_from_payload(&jwt_payload); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + ephemeral_public_key, + exp_date_secs, + epk_blinder, + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string(pepper_result, "JWT signature verification failed"); +} + +#[tokio::test] +async fn request_max_exp_data_secs_overflowed() { + // Generate a VUF keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Create a JWK cache and resource cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + set_on_chain_keyless_configuration(&cached_resources); + + // Create a test JWT + let jwt_payload = sample_jwt_payload_json_overrides( + SAMPLE_TEST_ISS_VALUE, + SAMPLE_UID_VAL, + &SAMPLE_JWT_EXTRA_FIELD, + u64::MAX - 1, // Large issue time to cause overflow + &SAMPLE_NONCE, + ); + let jwt = get_sample_jwt_token_from_payload(&jwt_payload); + + // Handle the pepper request + let pepper_result = handle_pepper_request( + vuf_keypair, + jwk_cache, + cached_resources, + jwt, + generate_ephemeral_public_key(), + SAMPLE_EXP_DATE, + get_sample_epk_blinder(), + None, + None, + utils::get_empty_account_recovery_managers(), + None, + utils::get_mock_account_recovery_db(), + ) + .await; + + // Expect an error + verify_error_string(pepper_result, "The maximum allowed expiry date overflowed"); +} + +/// Generates an ephemeral public key for testing +fn generate_ephemeral_public_key() -> EphemeralPublicKey { + let sk = get_sample_esk(); + let pk = Ed25519PublicKey::from(&sk); + EphemeralPublicKey::ed25519(pk) +} + +/// Gets the current time in seconds since the UNIX epoch +fn get_current_time_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() +} + +/// Sets a test on-chain keyless configuration in the cached resources +fn set_on_chain_keyless_configuration(cached_resources: &CachedResources) { + let on_chain_keyless_configuration = OnChainKeylessConfiguration::new_for_testing(); + cached_resources.set_on_chain_keyless_configuration(on_chain_keyless_configuration); +} + +/// Verifies that the error from a pepper request contains the expected message substring +fn verify_error_string( + pepper_result: Result<(Vec, Vec, AccountAddress), PepperServiceError>, + expected_message: &str, +) { + let pepper_service_error = pepper_result.unwrap_err(); + assert!(pepper_service_error.to_string().contains(expected_message)); +} diff --git a/keyless/pepper/service/src/tests/request_handler.rs b/keyless/pepper/service/src/tests/request_handler.rs new file mode 100644 index 00000000000..659863b4770 --- /dev/null +++ b/keyless/pepper/service/src/tests/request_handler.rs @@ -0,0 +1,625 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + deployment_information::DeploymentInformation, + external_resources::{ + groth16_vk::OnChainGroth16VerificationKey, jwk_fetcher::JWKCache, + keyless_config::OnChainKeylessConfiguration, resource_fetcher::CachedResources, + }, + request_handler::{ + handle_request, ABOUT_PATH, DEFAULT_PEPPER_SERVICE_PORT, DELEGATED_FETCH_PATH, FETCH_PATH, + GROTH16_VK_PATH, JWK_PATH, KEYLESS_CONFIG_PATH, SIGNATURE_PATH, VERIFY_PATH, + VUF_PUB_KEY_PATH, + }, + tests::utils, + vuf_keypair::VUFKeypair, +}; +use aptos_crypto::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, + Uniform, +}; +use aptos_infallible::Mutex; +use aptos_keyless_pepper_common::{PepperRequest, PepperRequestV2, PepperRequestWithAudOverride}; +use aptos_types::{jwks::rsa::SECURE_TEST_RSA_JWK, transaction::authenticator::EphemeralPublicKey}; +use hyper::{ + header::{ + ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, + }, + Body, Method, Request, Response, StatusCode, +}; +use reqwest::header::ACCESS_CONTROL_ALLOW_CREDENTIALS; +use std::{collections::HashMap, ops::Deref, sync::Arc}; + +#[tokio::test] +async fn test_options_request() { + // Send an options request to the root path + let response = + send_request_to_path(Method::OPTIONS, "/", Body::empty(), None, None, None, None).await; + + // Assert that the response status is OK + assert_eq!(response.status(), StatusCode::OK); + + // Verify the response headers + let headers = response.headers(); + assert_eq!(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN).unwrap(), ""); + assert_eq!( + headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS).unwrap(), + "true" + ); + assert_eq!(headers.get(ACCESS_CONTROL_ALLOW_HEADERS).unwrap(), "*"); + assert_eq!( + headers.get(ACCESS_CONTROL_ALLOW_METHODS).unwrap(), + "GET, POST, OPTIONS" + ); +} + +#[tokio::test] +async fn test_get_about_request() { + // Create a new deployment information object + let mut deployment_information = DeploymentInformation::new(); + + // Insert a test entry into the deployment information + let test_key = "test_key".to_string(); + let test_value = "test_value".to_string(); + deployment_information.extend_deployment_information(test_key.clone(), test_value.clone()); + + // Send a GET request to the about endpoint + let response = send_request_to_path( + Method::GET, + ABOUT_PATH, + Body::empty(), + None, + None, + None, + Some(deployment_information), + ) + .await; + + // Assert that the response status is OK + assert_eq!(response.status(), StatusCode::OK); + + // Parse the response body as a JSON map + let body_string = get_response_body_string(response).await; + let json_value: serde_json::Value = serde_json::from_str(&body_string).unwrap(); + let json_map = json_value.as_object().unwrap(); + + // Verify the response body contains relevant build information + assert!(json_map.contains_key("build_cargo_version")); + assert!(json_map.contains_key("build_commit_hash")); + assert!(json_map.contains_key("build_is_release_build")); + + // Verify the test entry is present in the response body + assert_eq!(json_map.get(&test_key).unwrap(), test_value.as_str()); +} + +#[tokio::test] +async fn test_get_groth16_vk_request() { + // Create a cached resources object with no cached resources + let cached_resources = CachedResources::new_for_testing(); + + // Send a GET request to the groth16 vk endpoint + let response = send_request_to_path( + Method::GET, + GROTH16_VK_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 404 (the resource has not been cached yet) + assert_eq!(response.status(), StatusCode::NOT_FOUND); + + // Update the groth16 vk cached resource + let mut on_chain_groth16_vk = OnChainGroth16VerificationKey::default(); + cached_resources.set_on_chain_groth16_vk(on_chain_groth16_vk.clone()); + + // Send a GET request to the groth16 vk endpoint + let response = send_request_to_path( + Method::GET, + GROTH16_VK_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 200 (the resource has been cached) + assert_eq!(response.status(), StatusCode::OK); + + // Verify the groth16 vk from the response body JSON + let body_string = get_response_body_string(response).await; + let response_groth16_vk: OnChainGroth16VerificationKey = + serde_json::from_str(&body_string).unwrap(); + assert_eq!(response_groth16_vk, on_chain_groth16_vk); + + // Update the groth16 vk cached resource with a new + on_chain_groth16_vk.data.beta_g2 = "Some new value".into(); + cached_resources.set_on_chain_groth16_vk(on_chain_groth16_vk.clone()); + + // Send a GET request to the groth16 vk endpoint + let response = send_request_to_path( + Method::GET, + GROTH16_VK_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 200 (the new resource has been cached) + assert_eq!(response.status(), StatusCode::OK); + + // Verify the new groth16 vk from the response body + let body_string = get_response_body_string(response).await; + let response_groth16_vk: OnChainGroth16VerificationKey = + serde_json::from_str(&body_string).unwrap(); + assert_eq!(response_groth16_vk, on_chain_groth16_vk); +} + +#[tokio::test] +async fn test_get_jwk_request() { + // Create a JWK cache + let jwk_cache = Arc::new(Mutex::new(HashMap::new())); + + // Send a GET request to the JWK endpoint + let response = send_request_to_path( + Method::GET, + JWK_PATH, + Body::empty(), + None, + Some(jwk_cache.clone()), + None, + None, + ) + .await; + + // Assert that the response status is OK + assert_eq!(response.status(), StatusCode::OK); + + // Parse the response body string and verify that it is an empty JSON map + let body_string = get_response_body_string(response).await; + let json_value: serde_json::Value = serde_json::from_str(&body_string).unwrap(); + let json_map = json_value.as_object().unwrap(); + assert!(json_map.is_empty()); + + // Insert several test JWKs into the cache + for i in 0..3 { + // Create the test issuer and key ID + let test_issuer = format!("test.issuer.{}", i); + let test_key_id = format!("test.key.id.{}", i); + + // Insert the test JWK into the cache + let mut jwk_cache = jwk_cache.lock(); + let issuer_entry = jwk_cache.entry(test_issuer.clone()).or_default(); + issuer_entry.insert( + test_key_id.clone(), + Arc::new(SECURE_TEST_RSA_JWK.deref().clone()), + ); + } + + // Send a GET request to the JWK endpoint + let response = send_request_to_path( + Method::GET, + JWK_PATH, + Body::empty(), + None, + Some(jwk_cache.clone()), + None, + None, + ) + .await; + + // Assert that the response status is OK + assert_eq!(response.status(), StatusCode::OK); + + // Parse the response body as a JSON map, and verify the number of entries + let body_string = get_response_body_string(response).await; + let json_value: serde_json::Value = serde_json::from_str(&body_string).unwrap(); + let json_map = json_value.as_object().unwrap(); + assert_eq!(json_map.len(), 3); + + // Verify that the map contains the expected JWKs + for i in 0..3 { + // Create the test issuer and key ID + let test_issuer = format!("test.issuer.{}", i); + let test_key_id = format!("test.key.id.{}", i); + + // Verify that the map contains the issuer and key ID + let issuer_entry = json_map.get(&test_issuer).unwrap().as_object().unwrap(); + assert_eq!(issuer_entry.len(), 1); + assert!(issuer_entry.contains_key(&test_key_id)); + } +} + +#[tokio::test] +async fn test_get_keyless_config_request() { + // Create a cached resources object with no cached resources + let cached_resources = CachedResources::new_for_testing(); + + // Send a GET request to the keyless config endpoint + let response = send_request_to_path( + Method::GET, + KEYLESS_CONFIG_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 404 (the resource has not been cached yet) + assert_eq!(response.status(), StatusCode::NOT_FOUND); + + // Update the keyless config cached resource + let mut on_chain_keyless_configuration = OnChainKeylessConfiguration::default(); + cached_resources.set_on_chain_keyless_configuration(on_chain_keyless_configuration.clone()); + + // Send a GET request to the keyless config endpoint + let response = send_request_to_path( + Method::GET, + KEYLESS_CONFIG_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 200 (the resource has been cached) + assert_eq!(response.status(), StatusCode::OK); + + // Verify the keyless config from the response body JSON + let body_string = get_response_body_string(response).await; + let response_keyless_config: OnChainKeylessConfiguration = + serde_json::from_str(&body_string).unwrap(); + assert_eq!(response_keyless_config, on_chain_keyless_configuration); + + // Update the keyless config cached resource with a new config + on_chain_keyless_configuration.data.max_exp_horizon_secs = "Some new value".into(); + cached_resources.set_on_chain_keyless_configuration(on_chain_keyless_configuration.clone()); + + // Send a GET request to the keyless config endpoint + let response = send_request_to_path( + Method::GET, + KEYLESS_CONFIG_PATH, + Body::empty(), + None, + None, + Some(cached_resources.clone()), + None, + ) + .await; + + // Assert that the response is a 200 (the new resource has been cached) + assert_eq!(response.status(), StatusCode::OK); + + // Verify the new keyless config from the response body + let body_string = get_response_body_string(response).await; + let response_keyless_config: OnChainKeylessConfiguration = + serde_json::from_str(&body_string).unwrap(); + assert_eq!(response_keyless_config, on_chain_keyless_configuration); +} + +#[tokio::test] +async fn test_get_vuf_pub_key_request() { + // Generate a test VUF public private keypair + let vuf_keypair = utils::create_vuf_keypair(None); + + // Send a GET request to the vuf public key endpoint + let response = send_request_to_path( + Method::GET, + VUF_PUB_KEY_PATH, + Body::empty(), + Some(vuf_keypair.clone()), + None, + None, + None, + ) + .await; + + // Assert that the response is a 200 (OK) + assert_eq!(response.status(), StatusCode::OK); + + // Get the public key from the response body + let body_string = get_response_body_string(response).await; + let response_vuf_public_key = get_public_key_from_json(&body_string); + + // Get the expected public key from the keypair + let vuf_public_key = get_public_key_from_json(vuf_keypair.vuf_public_key_json()); + + // Verify the public key is correct + assert_eq!(response_vuf_public_key, vuf_public_key); +} + +#[tokio::test] +async fn test_get_invalid_path_or_method_request() { + // Send a GET request to an unknown endpoint and verify that it returns 404 + let response = send_request_to_path( + Method::GET, + "/invalid_path", + Body::empty(), + None, + None, + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::NOT_FOUND); + + // Send a GET request to an endpoint that only supports POST requests, and verify that it returns 405 + let response = send_request_to_path( + Method::GET, + VERIFY_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::METHOD_NOT_ALLOWED); + + // Send a POST request to an endpoint that only supports GET requests, and verify that it returns 405 + let response = send_request_to_path( + Method::POST, + ABOUT_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::METHOD_NOT_ALLOWED); +} + +#[tokio::test] +async fn test_post_delegated_fetch_request_bad_request() { + // Send a POST request to the delegated fetch endpoint + let response = send_request_to_path( + Method::POST, + DELEGATED_FETCH_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + + // Assert that the response is a 400 (bad request, since no body was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +#[tokio::test] +async fn test_post_delegated_fetch_request_invalid_jwt() { + // Create a cached resources object + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + let mut on_chain_keyless_configuration = OnChainKeylessConfiguration::default(); + on_chain_keyless_configuration.data.max_exp_horizon_secs = "0".into(); + cached_resources.set_on_chain_keyless_configuration(on_chain_keyless_configuration.clone()); + + // Create a pepper request with an invalid JWT + let pepper_request = PepperRequest { + jwt: "invalid_jwt".into(), + epk: create_ephemeral_public_key(), + exp_date_secs: 0, + epk_blinder: vec![0u8; 32], + uid_key: None, + derivation_path: None, + }; + let pepper_request_v2 = PepperRequestV2::RequestWithAudOverride(PepperRequestWithAudOverride { + aud_override: "0".into(), + pepper_request, + }); + + // Serialize the pepper request to JSON + let request_body = serde_json::to_vec(&pepper_request_v2).unwrap(); + + // Send a POST request to the delegated fetch endpoint + let body = Body::from(request_body); + let response = send_request_to_path( + Method::POST, + DELEGATED_FETCH_PATH, + body, + None, + None, + Some(cached_resources), + None, + ) + .await; + + // Assert that the response is a 500 (bad request, since an invalid JWT was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + + // Assert that the response body contains an error message + let body_string = get_response_body_string(response).await; + assert!(body_string.contains("JWT decoding error")); +} + +#[tokio::test] +async fn test_post_fetch_request_bad_request() { + // Send a POST request to the fetch endpoint + let response = send_request_to_path( + Method::POST, + FETCH_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + + // Assert that the response is a 400 (bad request, since no body was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +#[tokio::test] +async fn test_post_fetch_request_invalid_jwt() { + // Create a cached resources object + let cached_resources = CachedResources::new_for_testing(); + + // Update the keyless config cached resource + let mut on_chain_keyless_configuration = OnChainKeylessConfiguration::default(); + on_chain_keyless_configuration.data.max_exp_horizon_secs = "0".into(); + cached_resources.set_on_chain_keyless_configuration(on_chain_keyless_configuration.clone()); + + // Create a pepper request with an invalid JWT + let pepper_request = PepperRequest { + jwt: "invalid_jwt".into(), + epk: create_ephemeral_public_key(), + exp_date_secs: 0, + epk_blinder: vec![0u8; 32], + uid_key: None, + derivation_path: None, + }; + + // Serialize the pepper request to JSON + let request_body = serde_json::to_vec(&pepper_request).unwrap(); + + // Send a POST request to the fetch endpoint + let body = Body::from(request_body); + let response = send_request_to_path( + Method::POST, + FETCH_PATH, + body, + None, + None, + Some(cached_resources), + None, + ) + .await; + + // Assert that the response is a 500 (bad request, since an invalid JWT was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + + // Assert that the response body contains an error message + let body_string = get_response_body_string(response).await; + assert!(body_string.contains("JWT decoding error")); +} + +#[tokio::test] +async fn test_post_signature_request_bad_request() { + // Send a POST request to the signature endpoint + let response = send_request_to_path( + Method::POST, + SIGNATURE_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + + // Assert that the response is a 400 (bad request, since no body was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +#[tokio::test] +async fn test_post_verify_request_bad_request() { + // Send a POST request to the verify endpoint + let response = send_request_to_path( + Method::POST, + VERIFY_PATH, + Body::empty(), + None, + None, + None, + None, + ) + .await; + + // Assert that the response is a 400 (bad request, since no body was provided) + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +/// Creates and returns an ephemeral public key for testing purposes +fn create_ephemeral_public_key() -> EphemeralPublicKey { + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = Ed25519PublicKey::from(&private_key); + + EphemeralPublicKey::Ed25519 { public_key } +} + +/// Gets the public key from a JSON string map +fn get_public_key_from_json(json_string_map: &str) -> String { + let json_value: serde_json::Value = serde_json::from_str(json_string_map).unwrap(); + let json_map = json_value.as_object().unwrap(); + let json_entry = json_map.get("public_key").unwrap(); + json_entry.as_str().unwrap().to_string() +} + +/// Gets the response body as a string +async fn get_response_body_string(response: Response) -> String { + let body_bytes = hyper::body::to_bytes(response.into_body()).await.unwrap(); + String::from_utf8(body_bytes.to_vec()).unwrap() +} + +// Calls the request handler with the given method, endpoint, and body +async fn send_request_to_path( + method: Method, + endpoint: &str, + body: Body, + vuf_keypair: Option>, + jwk_cache: Option, + cached_resources: Option, + deployment_information: Option, +) -> Response { + // Build the URI + let uri = format!( + "http://127.0.0.1:{}{}", + DEFAULT_PEPPER_SERVICE_PORT, endpoint + ); + + // Build the request + let request = Request::builder() + .uri(uri) + .method(method) + .body(body) + .unwrap(); + + // Get or create a VUF public private keypair + let vuf_keypair = vuf_keypair.unwrap_or_else(|| utils::create_vuf_keypair(None)); + + // Get or create a JWK cache + let jwk_cache = jwk_cache.unwrap_or_else(|| Arc::new(Mutex::new(HashMap::new()))); + + // Get or create cached resources + let cached_resources = cached_resources.unwrap_or(CachedResources::new_for_testing()); + + // Create the account recovery managers + let account_recovery_managers = utils::get_empty_account_recovery_managers(); + + // Create the mock account recovery DB + let account_recovery_db = utils::get_mock_account_recovery_db(); + + // Get or create deployment information + let deployment_information = deployment_information.unwrap_or_default(); + + // Serve the request + handle_request( + request, + vuf_keypair, + jwk_cache, + cached_resources, + account_recovery_managers, + account_recovery_db, + deployment_information, + ) + .await + .unwrap() +} diff --git a/keyless/pepper/service/src/tests/resource_fetcher.rs b/keyless/pepper/service/src/tests/resource_fetcher.rs new file mode 100644 index 00000000000..7e711784067 --- /dev/null +++ b/keyless/pepper/service/src/tests/resource_fetcher.rs @@ -0,0 +1,206 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + error::PepperServiceError, + external_resources::{ + groth16_vk::OnChainGroth16VerificationKey, + keyless_config::OnChainKeylessConfiguration, + resource_fetcher, + resource_fetcher::{ + CachedResources, ExternalResourceInterface, RESOURCE_FETCH_INTERVAL_SECS, + }, + }, + tests::utils, +}; +use aptos_infallible::Mutex; +use aptos_time_service::TimeService; +use serde::de::DeserializeOwned; +use std::{sync::Arc, time::Duration}; +use tokio::{task::JoinHandle, time::timeout}; + +// Maximum wait time (secs) for each test to complete +const MAX_TEST_WAIT_SECS: u64 = 10; + +/// A mock external resource (for testing resource fetching and caching) +struct MockExternalResource { + resource_name: String, + resource: T, + num_fetch_failures: Arc>, // The number of fetch failures to simulate +} + +impl MockExternalResource { + pub fn new(resource_name: String, resource: T, num_fetch_failures: u64) -> Self { + Self { + resource_name, + resource, + num_fetch_failures: Arc::new(Mutex::new(num_fetch_failures)), + } + } +} + +#[async_trait::async_trait] +impl ExternalResourceInterface + for MockExternalResource +{ + fn resource_name(&self) -> String { + self.resource_name.clone() + } + + fn resource_url(&self) -> String { + "".into() // The URL is not used in the mock implementation + } + + async fn fetch_resource(&self) -> Result { + // If there are failures to simulate, decrement the counter and + // return an error, otherwise, return the resource. + let mut num_fetch_failures = self.num_fetch_failures.lock(); + if *num_fetch_failures > 0 { + *num_fetch_failures -= 1; + Err(PepperServiceError::InternalError(format!( + "Simulated fetch failure for resource: {}! Failures remaining: {}", + self.resource_name, *num_fetch_failures + ))) + } else { + Ok(self.resource.clone()) + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn cached_resources_updates_after_interval() { + // Create test external resources + let on_chain_keyless_configuration = OnChainKeylessConfiguration::new_for_testing(); + let on_chain_groth16_vk = OnChainGroth16VerificationKey::new_for_testing(); + + // Create mock external resources + let keyless_resource = Arc::new(MockExternalResource::new( + "OnChainKeylessConfiguration".into(), + on_chain_keyless_configuration.clone(), + 0, + )); + let groth16_vk_resource = Arc::new(MockExternalResource::new( + "OnChainGroth16VerificationKey".into(), + on_chain_groth16_vk.clone(), + 0, + )); + + // Verify that the cached resources are updated correctly + verify_cached_resource_updates( + on_chain_keyless_configuration, + on_chain_groth16_vk, + keyless_resource, + groth16_vk_resource, + ) + .await; +} + +#[tokio::test(flavor = "multi_thread")] +async fn cached_resources_updates_after_failures() { + // Create test external resources + let on_chain_keyless_configuration = OnChainKeylessConfiguration::new_for_testing(); + let on_chain_groth16_vk = OnChainGroth16VerificationKey::new_for_testing(); + + // Create mock external resources that fail a few times before succeeding + let num_fetch_failures = 4; + let keyless_resource = Arc::new(MockExternalResource::new( + "OnChainKeylessConfiguration".into(), + on_chain_keyless_configuration.clone(), + num_fetch_failures, + )); + let groth16_vk_resource = Arc::new(MockExternalResource::new( + "OnChainGroth16VerificationKey".into(), + on_chain_groth16_vk.clone(), + num_fetch_failures, + )); + + // Verify that the cached resources are updated correctly + verify_cached_resource_updates( + on_chain_keyless_configuration, + on_chain_groth16_vk, + keyless_resource, + groth16_vk_resource, + ) + .await; +} + +/// Verifies that the cached resources are eventually updated +/// correctly after the resource fetcher is started. +async fn verify_cached_resource_updates( + on_chain_keyless_configuration: OnChainKeylessConfiguration, + on_chain_groth16_vk: OnChainGroth16VerificationKey, + keyless_resource: Arc + Send + Sync>, + groth16_vk_resource: Arc< + dyn ExternalResourceInterface + Send + Sync, + >, +) { + // Create the cached resources instance with a mock time service + let time_service = TimeService::mock(); + let cached_resources = CachedResources::new(time_service.clone()); + + // Start the external resource fetchers + resource_fetcher::start_external_resource_refresh_loop( + keyless_resource, + cached_resources.get_keyless_configuration_cache_entry(), + time_service.clone(), + ); + resource_fetcher::start_external_resource_refresh_loop( + groth16_vk_resource, + cached_resources.get_groth16_vk_cache_entry(), + time_service.clone(), + ); + + // Verify that initially the cache is empty + assert!(cached_resources + .read_on_chain_keyless_configuration() + .is_none()); + assert!(cached_resources.read_on_chain_groth16_vk().is_none()); + + // Spawn a task that advances time and verifies the cache is eventually updated + let cache_verification_task: JoinHandle> = tokio::spawn({ + let time_service = time_service.clone(); + let cached_resources = cached_resources.clone(); + + async move { + loop { + // Advance time by the fetch interval + utils::advance_time_secs(time_service.clone(), RESOURCE_FETCH_INTERVAL_SECS + 1) + .await; + + // Grab the cached resources + let fetched_keyless_configuration = + cached_resources.read_on_chain_keyless_configuration(); + let fetched_groth16_vk = cached_resources.read_on_chain_groth16_vk(); + + // Check if the cache has been updated correctly + match (fetched_keyless_configuration, fetched_groth16_vk) { + (Some(fetched_keyless_configuration), Some(fetched_groth16_vk)) => { + assert_eq!( + fetched_keyless_configuration, + on_chain_keyless_configuration + ); + assert_eq!(fetched_groth16_vk, on_chain_groth16_vk); + return Ok(()); + }, + _ => { + // Yield to allow other tasks to run + tokio::task::yield_now().await; + }, + } + } + } + }); + + // Verify that the cached resources are eventually updated + if let Err(error) = timeout( + Duration::from_secs(MAX_TEST_WAIT_SECS), + cache_verification_task, + ) + .await + { + panic!( + "Failed waiting for cached resources to be updated: {}", + error + ); + } +} diff --git a/keyless/pepper/service/src/tests/utils.rs b/keyless/pepper/service/src/tests/utils.rs new file mode 100644 index 00000000000..10653eeafc1 --- /dev/null +++ b/keyless/pepper/service/src/tests/utils.rs @@ -0,0 +1,64 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + accounts::{ + account_managers::AccountRecoveryManagers, account_recovery_db::AccountRecoveryDBInterface, + }, + error::PepperServiceError, + vuf_keypair::{get_pepper_service_vuf_public_key_and_json, VUFKeypair}, +}; +use aptos_crypto::blstrs::scalar_from_uniform_be_bytes; +use aptos_keyless_pepper_common::{vuf::slip_10::ed25519_dalek::Digest, PepperInput}; +use aptos_time_service::TimeService; +use std::{sync::Arc, time::Duration}; + +/// A mock implementation of the account recovery DB that does nothing +struct MockAccountRecoveryDB; + +#[async_trait::async_trait] +impl AccountRecoveryDBInterface for MockAccountRecoveryDB { + async fn update_db_with_pepper_input( + &self, + _pepper_input: &PepperInput, + ) -> Result<(), PepperServiceError> { + Ok(()) // Do nothing + } +} + +/// Advances the mock time service by the given number of seconds +pub async fn advance_time_secs(time_service: TimeService, seconds: u64) { + let mock_time_service = time_service.into_mock(); + mock_time_service + .advance_async(Duration::from_secs(seconds)) + .await; +} + +/// Generates a random VUF keypair for testing purposes +pub fn create_vuf_keypair(private_key_seed: Option<[u8; 32]>) -> Arc { + // Get or generate a seed for the private key + let private_key_seed = private_key_seed.unwrap_or(rand::random::<[u8; 32]>()); + + // Derive the VUF private key from the seed + let mut sha3_hasher = sha3::Sha3_512::new(); + sha3_hasher.update(private_key_seed); + let vuf_private_key = scalar_from_uniform_be_bytes(sha3_hasher.finalize().as_slice()); + + // Get the VUF public key and its JSON representation + let (vuf_public_key, vuf_public_key_json) = + get_pepper_service_vuf_public_key_and_json(&vuf_private_key); + + // Return the VUF keypair + let vuf_keypair = VUFKeypair::new(vuf_private_key, vuf_public_key, vuf_public_key_json); + Arc::new(vuf_keypair) +} + +/// Returns an empty account managers and overrides instance +pub fn get_empty_account_recovery_managers() -> Arc { + Arc::new(AccountRecoveryManagers::new_empty()) +} + +/// Returns a mock account recovery DB instance +pub fn get_mock_account_recovery_db() -> Arc { + Arc::new(MockAccountRecoveryDB) +} diff --git a/keyless/pepper/service/src/utils.rs b/keyless/pepper/service/src/utils.rs new file mode 100644 index 00000000000..e44ead54b7e --- /dev/null +++ b/keyless/pepper/service/src/utils.rs @@ -0,0 +1,75 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::{anyhow, ensure}; +use hyper::{Body, Request}; +use reqwest::Client; +use std::time::Duration; + +// Timeout for client requests +const CLIENT_REQUEST_TIMEOUT_SECS: u64 = 15; + +// Origin header constants +const MISSING_ORIGIN_STRING: &str = ""; // Default to empty string if origin header is missing +const ORIGIN_HEADER: &str = "origin"; + +/// Creates and returns a reqwest HTTP client with a timeout +pub fn create_request_client() -> Client { + Client::builder() + .timeout(Duration::from_secs(CLIENT_REQUEST_TIMEOUT_SECS)) + .build() + .expect("Failed to build the request client!") +} + +/// Extracts the origin header from the request +pub fn get_request_origin(request: &Request) -> String { + request + .headers() + .get(ORIGIN_HEADER) + .and_then(|header_value| header_value.to_str().ok()) + .unwrap_or(MISSING_ORIGIN_STRING) + .to_owned() +} + +/// Converts a hex-encoded string (with "0x" prefix) to a byte vector +pub fn unhexlify_api_bytes(api_output: &str) -> anyhow::Result> { + // Verify the input format + ensure!(api_output.len() >= 2); + let lower = api_output.to_lowercase(); + ensure!(&lower[0..2] == "0x"); + + // Decode the hex string + hex::decode(&lower[2..]).map_err(|error| { + anyhow!( + "unhexlify_api_bytes() failed to decode intput {}! Error: {}", + lower, + error + ) + }) +} + +#[cfg(test)] +mod tests { + use crate::utils::unhexlify_api_bytes; + + #[test] + fn test_unhexlify_api_bytes() { + // Test valid input + assert!(unhexlify_api_bytes("0x").unwrap().is_empty()); + assert_eq!( + vec![0x00_u8, 0x01, 0xFF], + unhexlify_api_bytes("0x0001ff").unwrap() + ); + assert_eq!( + vec![0xDE_u8, 0xAD, 0xBE, 0xEF], + unhexlify_api_bytes("0xdeadbeef").unwrap() + ); + + // Test invalid inputs + assert!(unhexlify_api_bytes("0001ff").is_err()); + assert!(unhexlify_api_bytes("0x0001fg").is_err()); + assert!(unhexlify_api_bytes("000").is_err()); + assert!(unhexlify_api_bytes("0").is_err()); + assert!(unhexlify_api_bytes("").is_err()); + } +} diff --git a/keyless/pepper/service/src/vuf_keypair.rs b/keyless/pepper/service/src/vuf_keypair.rs new file mode 100644 index 00000000000..f17e480d7e0 --- /dev/null +++ b/keyless/pepper/service/src/vuf_keypair.rs @@ -0,0 +1,245 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::PepperServiceError; +use aptos_crypto::blstrs::scalar_from_uniform_be_bytes; +use aptos_keyless_pepper_common::{ + vuf::{bls12381_g1_bls::Bls12381G1Bls, VUF}, + PepperV0VufPubKey, +}; +use aptos_logger::{info, warn}; +use blstrs::{G2Projective, Scalar}; +use sha3::Digest; + +/// A simple struct that holds a VUF public and private keypair, +/// including the VUF public key in JSON format. +pub struct VUFKeypair { + vuf_private_key: Scalar, + vuf_public_key: G2Projective, + vuf_public_key_json: String, +} + +impl VUFKeypair { + pub fn new( + vuf_private_key: Scalar, + vuf_public_key: G2Projective, + vuf_public_key_json: String, + ) -> Self { + Self { + vuf_private_key, + vuf_public_key, + vuf_public_key_json, + } + } + + /// Returns a reference to the VUF private key + pub fn vuf_private_key(&self) -> &Scalar { + &self.vuf_private_key + } + + /// Returns a reference to the VUF public key + pub fn vuf_public_key(&self) -> &G2Projective { + &self.vuf_public_key + } + + /// Returns a reference to the VUF public key in JSON format + pub fn vuf_public_key_json(&self) -> &String { + &self.vuf_public_key_json + } +} + +/// Derive the VUF private key from the given hex-encoded seed +fn derive_vuf_private_key_from_seed( + vuf_private_key_seed_hex: String, +) -> Result { + // Decode the hex-encoded seed + let vuf_private_key_seed = hex::decode(vuf_private_key_seed_hex).map_err(|error| { + PepperServiceError::UnexpectedError(format!( + "Failed to decode VUF private key seed hex! Error: {}", + error + )) + })?; + + // Ensure the seed has sufficient entropy (at least 32 bytes) + let vuf_private_key_seed_length = vuf_private_key_seed.len(); + if vuf_private_key_seed_length < 32 { + return Err(PepperServiceError::UnexpectedError(format!( + "VUF private key seed must be at least 32 bytes long! Found length: {}", + vuf_private_key_seed_length + ))); + } + + // Hash the seed to derive the private key + let mut sha3_hasher = sha3::Sha3_512::new(); + sha3_hasher.update(vuf_private_key_seed); + let vuf_private_key = scalar_from_uniform_be_bytes(sha3_hasher.finalize().as_slice()); + + Ok(vuf_private_key) +} + +/// Deserialize the VUF private key directly from the given hex-encoded string +fn deserialize_vuf_private_key(vuf_private_key_hex: String) -> Result { + // Decode the hex-encoded private key + let vuf_private_key_bytes = hex::decode(vuf_private_key_hex).map_err(|e| { + PepperServiceError::UnexpectedError(format!( + "Failed to decode VUF private key hex! Error: {}", + e + )) + })?; + + // Deserialize the private key bytes + let vuf_private_key_opt = + Scalar::from_bytes_le(<&[u8; 32]>::try_from(vuf_private_key_bytes.as_slice()).unwrap()); + + if vuf_private_key_opt.is_none().unwrap_u8() == 1 { + return Err(PepperServiceError::UnexpectedError( + "Failed to deserialize VUF private key!".to_string(), + )); + } + + Ok(vuf_private_key_opt.unwrap()) +} + +/// Fetches the VUF private key for the pepper service. Note: this function +/// will panic if no valid private key can be derived or deserialized. +fn get_pepper_service_vuf_private_key( + vuf_private_key_hex: Option, + vuf_private_key_seed_hex: Option, +) -> Scalar { + info!("Loading the VUF private key for the pepper service..."); + + // Attempt to derive the private key from the seed + if let Some(vuf_private_key_seed_hex) = vuf_private_key_seed_hex { + match derive_vuf_private_key_from_seed(vuf_private_key_seed_hex) { + Ok(private_key) => { + info!("Successfully derived the VUF private key from the seed!"); + return private_key; + }, + Err(error) => { + warn!( + "Failed to derive the VUF private key from a seed! Error: {}", + error + ); + }, + } + } + + // Seed derivation failed, fall back to direct deserialization + warn!("Falling back to direct VUF private key deserialization!"); + + // Attempt to deserialize the private key directly + if let Some(vuf_private_key_hex) = vuf_private_key_hex { + match deserialize_vuf_private_key(vuf_private_key_hex) { + Ok(private_key) => { + info!("Successfully deserialized the VUF private key directly!"); + return private_key; + }, + Err(error) => { + warn!( + "Failed to derive VUF private key from direct deserialization! Error: {}", + error + ); + }, + } + } + + // Panic, as there is no valid private key + panic!("No valid VUF private key could be derived or deserialized!"); +} + +/// Returns the VUF public key of the pepper service (both the G2Projective and JSON) +pub fn get_pepper_service_vuf_public_key_and_json( + vuf_private_key: &Scalar, +) -> (G2Projective, String) { + info!("Deriving the VUF public key for the pepper service..."); + + // Calculate the corresponding public key + let vuf_public_key = match Bls12381G1Bls::pk_from_sk(vuf_private_key) { + Ok(public_key) => public_key, + Err(error) => panic!( + "Failed to derive the VUF public key from the private key! Error: {}", + error + ), + }; + + // Create the public key object + let public_key_buf = vuf_public_key.to_compressed().to_vec(); + let pepper_vuf_public_key = PepperV0VufPubKey::new(public_key_buf); + info!( + "Successfully derived the VUF public key for the pepper service: {:?}", + pepper_vuf_public_key + ); + + // Transform the public key to a pretty JSON string + let vuf_public_key_json = serde_json::to_string_pretty(&pepper_vuf_public_key) + .expect("Fail to format the VUF public key using pretty JSON!"); + + (vuf_public_key, vuf_public_key_json) +} + +/// Returns the VUF keypair for the pepper service +pub fn get_pepper_service_vuf_keypair( + vuf_private_key_hex: Option, + vuf_private_key_seed_hex: Option, +) -> VUFKeypair { + // Fetch the VUF private key + let vuf_private_key = + get_pepper_service_vuf_private_key(vuf_private_key_hex, vuf_private_key_seed_hex); + + // Get the VUF public key and its JSON representation + let (vuf_public_key, vuf_public_key_json) = + get_pepper_service_vuf_public_key_and_json(&vuf_private_key); + + // Create a new VUFKeypair + VUFKeypair::new(vuf_private_key, vuf_public_key, vuf_public_key_json) +} + +#[cfg(test)] +mod tests { + use crate::vuf_keypair; + + // Useful test constants + const TEST_VUF_KEY_SEED: &str = + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + const TEST_VUF_KEY_HEX: &str = + "0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9"; + + #[test] + #[should_panic(expected = "No valid VUF private key could be derived or deserialized!")] + fn test_get_pepper_service_vuf_keypair() { + // Get the pepper service VUF keypair given both seed and hex + let vuf_keypair = vuf_keypair::get_pepper_service_vuf_keypair( + Some(TEST_VUF_KEY_HEX.into()), + Some(TEST_VUF_KEY_SEED.into()), + ); + + // Verify the private key is derived from the seed + let derived_private_key = + vuf_keypair::derive_vuf_private_key_from_seed(TEST_VUF_KEY_SEED.into()).unwrap(); + assert_eq!(vuf_keypair.vuf_private_key(), &derived_private_key); + + // Verify the public keys are correctly derived + let (expected_public_key, expected_public_key_json) = + vuf_keypair::get_pepper_service_vuf_public_key_and_json(vuf_keypair.vuf_private_key()); + assert_eq!(vuf_keypair.vuf_public_key(), &expected_public_key); + assert_eq!(vuf_keypair.vuf_public_key_json(), &expected_public_key_json); + + // Get the pepper service VUF keypair again (with only the hex) + let vuf_keypair = + vuf_keypair::get_pepper_service_vuf_keypair(Some(TEST_VUF_KEY_HEX.into()), None); + + // Verify the private key is derived from the fallback hex + let deserialized_private_key = + vuf_keypair::deserialize_vuf_private_key(TEST_VUF_KEY_HEX.to_string()).unwrap(); + assert_eq!(vuf_keypair.vuf_private_key(), &deserialized_private_key); + + // Verify the public keys are correctly derived + let (expected_public_key, expected_public_key_json) = + vuf_keypair::get_pepper_service_vuf_public_key_and_json(vuf_keypair.vuf_private_key()); + assert_eq!(vuf_keypair.vuf_public_key(), &expected_public_key); + assert_eq!(vuf_keypair.vuf_public_key_json(), &expected_public_key_json); + + // Get the pepper service VUF keypair again, with neither seed nor hex (this should panic) + let _ = vuf_keypair::get_pepper_service_vuf_keypair(None, None); + } +} diff --git a/keyless/pepper/service/src/vuf_keys.rs b/keyless/pepper/service/src/vuf_keys.rs deleted file mode 100644 index 2bc136baf87..00000000000 --- a/keyless/pepper/service/src/vuf_keys.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{anyhow, ensure}; -use aptos_keyless_pepper_common::{ - vuf::{bls12381_g1_bls::Bls12381G1Bls, VUF}, - PepperV0VufPubKey, -}; -use aptos_logger::warn; -use ark_ec::CurveGroup; -use ark_ff::PrimeField; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use once_cell::sync::Lazy; -use sha3::Digest; - -/// Derive the VUF private key from a seed given in the environment. -fn derive_sk_from_env_seed() -> anyhow::Result { - let seed_hexlified = std::env::var("VUF_KEY_SEED_HEX") - .map_err(|e| anyhow!("error while reading envvar `VUF_KEY_SEED_HEX`: {e}"))?; - let seed = - hex::decode(seed_hexlified).map_err(|e| anyhow!("seed unhexlification error: {e}"))?; - ensure!(seed.len() >= 32, "seed entropy should be at least 32 bytes"); - let mut hasher = sha3::Sha3_512::new(); - hasher.update(seed); - let sk = ark_bls12_381::Fr::from_be_bytes_mod_order(hasher.finalize().as_slice()); - Ok(sk) -} - -/// A backward-compatible path to load a sk (serialized and hexlified) from envvar. -/// TODO: once secret seed is stable, remove this. -fn deserialize_sk_from_env() -> anyhow::Result { - let vuf_key_hex = std::env::var("VUF_KEY_HEX") - .map_err(|e| anyhow!("error while reading envvar `VUF_KEY_HEX`: {e}"))?; - let mut sk_bytes = - hex::decode(vuf_key_hex).map_err(|e| anyhow!("sk unhexlification error: {e}"))?; - sk_bytes.reverse(); - let sk = ark_bls12_381::Fr::deserialize_compressed(sk_bytes.as_slice()) - .map_err(|e| anyhow!("Fr deserialization error: {e}"))?; - Ok(sk) -} - -pub static VUF_SK: Lazy = Lazy::new(|| { - match derive_sk_from_env_seed() { - Ok(sk) => { - return sk; - }, - Err(e) => { - warn!("`derive_sk_from_env_seed`failed: {e}"); - warn!("falling back to `deserialize_sk_from_env`"); - //TODO: once secret seed is stable, remove the fallback path. - }, - } - - deserialize_sk_from_env().expect("fallback sk also failed") -}); - -pub static PEPPER_VUF_VERIFICATION_KEY_JSON: Lazy = Lazy::new(|| { - let pk = Bls12381G1Bls::pk_from_sk(&VUF_SK).expect("bad sk"); - let mut buf = vec![]; - pk.into_affine().serialize_compressed(&mut buf).unwrap(); - let obj = PepperV0VufPubKey { public_key: buf }; - serde_json::to_string_pretty(&obj).unwrap() -}); diff --git a/keyless/pepper/service/src/watcher.rs b/keyless/pepper/service/src/watcher.rs deleted file mode 100644 index 72738e602c3..00000000000 --- a/keyless/pepper/service/src/watcher.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{anyhow, ensure, Result}; -use aptos_infallible::RwLock; -use aptos_logger::{debug, info, warn}; -use serde::de::DeserializeOwned; -use std::{sync::Arc, time::Duration}; - -pub async fn fetch_and_cache_resource( - resource_url: &str, - resource_holder: &RwLock>, -) -> Result<()> { - let resource = reqwest::get(resource_url).await?.json::().await?; - *resource_holder.write() = Some(resource); - Ok(()) -} - -pub fn start_external_resource_refresh_loop< - T: DeserializeOwned + ExternalResource + Send + Sync + 'static, ->( - url: &str, - refresh_interval: Duration, - local_cache: Arc>>, -) { - info!( - "Starting external resource refresh loop for {}", - T::resource_name() - ); - let url = url.to_string(); - let _handle = tokio::spawn(async move { - loop { - let result = fetch_and_cache_resource(&url, local_cache.as_ref()).await; - match result { - Ok(_vk) => { - debug!("fetch_and_cache_resource {} succeeded.", T::resource_name()); - }, - Err(e) => { - warn!( - "fetch_and_cache_resource {} failed: {}", - T::resource_name(), - e - ); - }, - } - - tokio::time::sleep(refresh_interval).await; - } - }); -} - -pub trait ExternalResource { - fn resource_name() -> String; -} - -pub fn unhexlify_api_bytes(api_output: &str) -> Result> { - ensure!(api_output.len() >= 2); - let lower = api_output.to_lowercase(); - ensure!(&lower[0..2] == "0x"); - let bytes = hex::decode(&lower[2..]) - .map_err(|e| anyhow!("unhexlify_api_bytes() failed at decoding: {e}"))?; - Ok(bytes) -} - -#[test] -fn test_unhexlify_api_bytes() { - assert_eq!( - vec![0x00_u8, 0x01, 0xFF], - unhexlify_api_bytes("0x0001ff").unwrap() - ); - assert!(unhexlify_api_bytes("0x").unwrap().is_empty()); - assert!(unhexlify_api_bytes("0001ff").is_err()); - assert!(unhexlify_api_bytes("0x0001fg").is_err()); - assert!(unhexlify_api_bytes("000").is_err()); - assert!(unhexlify_api_bytes("0").is_err()); - assert!(unhexlify_api_bytes("").is_err()); -} diff --git a/mempool/Cargo.toml b/mempool/Cargo.toml index dede31a8319..43c5894badf 100644 --- a/mempool/Cargo.toml +++ b/mempool/Cargo.toml @@ -31,6 +31,7 @@ aptos-runtimes = { workspace = true } aptos-short-hex-str = { workspace = true } aptos-storage-interface = { workspace = true } aptos-time-service = { workspace = true } +aptos-transaction-filters = { workspace = true } aptos-types = { workspace = true } aptos-vm-validator = { workspace = true } bcs = { workspace = true } @@ -55,6 +56,7 @@ aptos-id-generator = { workspace = true } aptos-network = { workspace = true, features = ["fuzzing"] } aptos-storage-interface = { workspace = true, features = ["fuzzing"] } aptos-time-service = { workspace = true, features = ["testing"] } +aptos-transaction-filters = { workspace = true, features = ["fuzzing"] } enum_dispatch = { workspace = true } proptest = { workspace = true } diff --git a/mempool/src/core_mempool/index.rs b/mempool/src/core_mempool/index.rs index cff946c3129..950b86881a2 100644 --- a/mempool/src/core_mempool/index.rs +++ b/mempool/src/core_mempool/index.rs @@ -165,7 +165,7 @@ impl PriorityIndex { } } - pub(crate) fn iter(&self) -> PriorityQueueIter { + pub(crate) fn iter(&self) -> PriorityQueueIter<'_> { self.data.iter().rev() } @@ -269,7 +269,7 @@ impl TTLIndex { } } - pub(crate) fn iter(&self) -> Iter { + pub(crate) fn iter(&self) -> Iter<'_, TTLOrderingKey> { self.data.iter() } diff --git a/mempool/src/core_mempool/transaction_store.rs b/mempool/src/core_mempool/transaction_store.rs index d2e36ae9c1b..8e0277cf010 100644 --- a/mempool/src/core_mempool/transaction_store.rs +++ b/mempool/src/core_mempool/transaction_store.rs @@ -1008,7 +1008,7 @@ impl TransactionStore { self.track_indices(); } - pub(crate) fn iter_queue(&self) -> PriorityQueueIter { + pub(crate) fn iter_queue(&self) -> PriorityQueueIter<'_> { self.priority_index.iter() } diff --git a/mempool/src/counters.rs b/mempool/src/counters.rs index 838506efd7f..76165042528 100644 --- a/mempool/src/counters.rs +++ b/mempool/src/counters.rs @@ -58,6 +58,7 @@ pub const REQUEST_SUCCESS_LABEL: &str = "success"; // Process txn breakdown type labels pub const FETCH_SEQ_NUM_LABEL: &str = "storage_fetch"; +pub const FILTER_TRANSACTIONS_LABEL: &str = "filter_transactions"; pub const VM_VALIDATION_LABEL: &str = "vm_validation"; // Txn process result labels @@ -100,6 +101,10 @@ pub const SUBMITTED_BY_CLIENT_LABEL: &str = "client"; pub const SUBMITTED_BY_DOWNSTREAM_LABEL: &str = "downstream"; pub const SUBMITTED_BY_PEER_VALIDATOR_LABEL: &str = "peer_validator"; +// Broadcast event labels +pub const DROP_BROADCAST_LABEL: &str = "drop_broadcast"; +pub const RUNNING_LABEL: &str = "running"; + // Histogram buckets with a large range of 0-500s and some constant sized buckets between: // 0-1.5s (every 25ms), 1.5-2s (every 100ms), 2-5s (250ms), 5-10s (1s), and 10-25s (2.5s). const MEMPOOL_LATENCY_BUCKETS: &[f64] = &[ @@ -556,6 +561,22 @@ pub fn shared_mempool_broadcast_size(network_id: NetworkId, num_txns: usize) { .observe(num_txns as f64); } +/// Counter for the number and type of broadcast events that shared mempool executes +static SHARED_MEMPOOL_BROADCAST_EVENTS: Lazy = Lazy::new(|| { + register_int_counter_vec!( + "aptos_shared_mempool_broadcast_events", + "Broadcast events (at runtime) for shared mempool", + &["event", "network_id"] + ) + .unwrap() +}); + +pub fn shared_mempool_broadcast_event_inc(event_label: &str, network_id: NetworkId) { + SHARED_MEMPOOL_BROADCAST_EVENTS + .with_label_values(&[event_label, network_id.as_str()]) + .inc(); +} + static SHARED_MEMPOOL_BROADCAST_TYPE_COUNT: Lazy = Lazy::new(|| { register_int_counter_vec!( "aptos_shared_mempool_rebroadcast_count", diff --git a/mempool/src/logging.rs b/mempool/src/logging.rs index 342a3ec5a10..a2e5fbdac67 100644 --- a/mempool/src/logging.rs +++ b/mempool/src/logging.rs @@ -129,6 +129,7 @@ pub struct LogSchema<'a> { message_id: Option<&'a MempoolMessageId>, backpressure: Option, num_txns: Option, + message: Option<&'a str>, } impl LogSchema<'_> { @@ -156,6 +157,7 @@ impl LogSchema<'_> { message_id: None, backpressure: None, num_txns: None, + message: None, } } } @@ -187,6 +189,7 @@ pub enum LogEntry { DBError, UnexpectedNetworkMsg, MempoolSnapshot, + TransactionFilter, } #[derive(Clone, Copy, Serialize)] @@ -209,5 +212,8 @@ pub enum LogEvent { SystemTTLExpiration, ClientExpiration, + // Transaction filter events + TransactionRejected, + Success, } diff --git a/mempool/src/shared_mempool/network.rs b/mempool/src/shared_mempool/network.rs index eb57f9bad09..c59835d1446 100644 --- a/mempool/src/shared_mempool/network.rs +++ b/mempool/src/shared_mempool/network.rs @@ -90,6 +90,20 @@ pub enum BroadcastError { TooManyPendingBroadcasts(PeerNetworkId), } +impl BroadcastError { + /// Returns a summary label for the error + pub fn get_label(&self) -> &'static str { + match self { + Self::NetworkError(_, _) => "network_error", + Self::NoTransactions(_) => "no_transactions", + Self::PeerNotFound(_) => "peer_not_found", + Self::PeerNotPrioritized(_, _) => "peer_not_prioritized", + Self::PeerNotScheduled(_) => "peer_not_scheduled", + Self::TooManyPendingBroadcasts(_) => "too_many_pending_broadcasts", + } + } +} + #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] pub enum BroadcastPeerPriority { Primary, @@ -253,6 +267,7 @@ impl> MempoolNetworkInterf self.num_committed_txns_received_since_peers_updated .load(Ordering::Relaxed), ); + // Resetting the counter self.num_mempool_txns_received_since_peers_updated = 0; self.num_committed_txns_received_since_peers_updated diff --git a/mempool/src/shared_mempool/priority.rs b/mempool/src/shared_mempool/priority.rs index 537b73d1ea8..dc30da4d6fb 100644 --- a/mempool/src/shared_mempool/priority.rs +++ b/mempool/src/shared_mempool/priority.rs @@ -20,16 +20,28 @@ use std::{ time::Instant, }; +/// The number of microseconds in one second +const MICROS_PER_SECOND: u64 = 1000 * 1000; // 1 million + /// A simple struct that offers comparisons and ordering for peer prioritization #[derive(Clone, Debug)] struct PrioritizedPeersComparator { + // The current mempool configuration + mempool_config: MempoolConfig, + + // The random state used to hash peer IDs random_state: RandomState, + + // The time service used to calculate timestamps + time_service: TimeService, } impl PrioritizedPeersComparator { - fn new() -> Self { + fn new(mempool_config: MempoolConfig, time_service: TimeService) -> Self { Self { + mempool_config, random_state: RandomState::new(), + time_service, } } @@ -68,7 +80,18 @@ impl PrioritizedPeersComparator { let (peer_network_id_a, monitoring_metadata_a) = peer_a; let (peer_network_id_b, monitoring_metadata_b) = peer_b; - // First, compare by network ID (i.e., Validator > VFN > Public) + // First, compare the peers by health (e.g., sync lag) + let unhealthy_ordering = compare_peer_health( + &self.mempool_config, + &self.time_service, + monitoring_metadata_a, + monitoring_metadata_b, + ); + if !unhealthy_ordering.is_eq() { + return unhealthy_ordering; // Only return if it's not equal + } + + // Next, compare by network ID (i.e., Validator > VFN > Public) let network_ordering = compare_network_id( &peer_network_id_a.network_id(), &peer_network_id_b.network_id(), @@ -153,10 +176,14 @@ impl PrioritizedPeersState { node_type: NodeType, time_service: TimeService, ) -> Self { + let prioritized_peers = Arc::new(RwLock::new(Vec::new())); + let peer_comparator = + PrioritizedPeersComparator::new(mempool_config.clone(), time_service.clone()); + Self { mempool_config, - prioritized_peers: Arc::new(RwLock::new(Vec::new())), - peer_comparator: PrioritizedPeersComparator::new(), + prioritized_peers, + peer_comparator, observed_all_ping_latencies: false, last_peer_priority_update: None, time_service, @@ -440,7 +467,7 @@ impl PrioritizedPeersState { // Set the last peer priority update time self.last_peer_priority_update = Some(self.time_service.now()); info!( - "Updated prioritized peers. Peer count: {:?}, Latencies: {:?},\n Prioritized peers: {:?},\n Sender bucket assignment: {:?}", + "Updated prioritized peers. Peer count: {:?}, Latencies: {:?}, Prioritized peers: {:?}, Sender bucket assignment: {:?}", peers_and_metadata.len(), peers_and_metadata .iter() @@ -529,6 +556,60 @@ fn compare_ping_latency( } } +/// Returns true iff the given peer monitoring metadata is healthy. A peer is +/// considered healthy if its latest ledger timestamp is within the max acceptable +/// sync lag. If the monitoring metadata is missing, the peer is considered unhealthy. +fn check_peer_metadata_health( + mempool_config: &MempoolConfig, + time_service: &TimeService, + monitoring_metadata: &Option<&PeerMonitoringMetadata>, +) -> bool { + monitoring_metadata + .and_then(|metadata| { + metadata + .latest_node_info_response + .as_ref() + .map(|node_information_response| { + // Get the peer's ledger timestamp and the current timestamp + let peer_ledger_timestamp_usecs = + node_information_response.ledger_timestamp_usecs; + let current_timestamp_usecs = get_timestamp_now_usecs(time_service); + + // Calculate the max sync lag before the peer is considered unhealthy (in microseconds) + let max_sync_lag_secs = + mempool_config.max_sync_lag_before_unhealthy_secs as u64; + let max_sync_lag_usecs = max_sync_lag_secs * MICROS_PER_SECOND; + + // Determine if the peer is healthy + current_timestamp_usecs.saturating_sub(peer_ledger_timestamp_usecs) + < max_sync_lag_usecs + }) + }) + .unwrap_or(false) // If metadata is missing, consider the peer unhealthy +} + +/// Compares the health of the given peer monitoring metadata. Healthy +/// peers are prioritized over unhealthy peers, or peers missing metadata. +fn compare_peer_health( + mempool_config: &MempoolConfig, + time_service: &TimeService, + monitoring_metadata_a: &Option<&PeerMonitoringMetadata>, + monitoring_metadata_b: &Option<&PeerMonitoringMetadata>, +) -> Ordering { + // Check the health of the peer monitoring metadata + let is_healthy_a = + check_peer_metadata_health(mempool_config, time_service, monitoring_metadata_a); + let is_healthy_b = + check_peer_metadata_health(mempool_config, time_service, monitoring_metadata_b); + + // Compare the health statuses + match (is_healthy_a, is_healthy_b) { + (true, false) => Ordering::Greater, // A is healthy, B is unhealthy + (false, true) => Ordering::Less, // A is unhealthy, B is healthy + _ => Ordering::Equal, // Both are healthy or unhealthy + } +} + /// Compares the validator distance for the given pair of monitoring metadata. /// The peer with the lowest validator distance is prioritized. fn compare_validator_distance( @@ -557,6 +638,11 @@ fn compare_validator_distance( } } +/// Returns the current timestamp (in microseconds) since the Unix epoch +fn get_timestamp_now_usecs(time_service: &TimeService) -> u64 { + time_service.now_unix_time().as_micros() as u64 +} + #[cfg(test)] mod test { use super::*; @@ -565,7 +651,8 @@ mod test { network_id::{NetworkId, PeerNetworkId}, }; use aptos_peer_monitoring_service_types::{ - response::NetworkInformationResponse, PeerMonitoringMetadata, + response::{NetworkInformationResponse, NodeInformationResponse}, + PeerMonitoringMetadata, }; use aptos_types::PeerId; use core::cmp::Ordering; @@ -597,6 +684,136 @@ mod test { ); } + #[test] + fn test_check_peer_metadata_health() { + // Create a mempool config with a max sync lag of 10 seconds + let mempool_config = MempoolConfig { + max_sync_lag_before_unhealthy_secs: 10, + ..MempoolConfig::default() + }; + + // Create a mock time service for testing + let time_service = TimeService::mock(); + + // Create monitoring metadata with no sync lag (healthy) + let monitoring_metadata = create_metadata_with_sync_lag(&time_service, 0); + + // Verify the peer is healthy + let is_peer_healthy = + check_peer_metadata_health(&mempool_config, &time_service, &Some(&monitoring_metadata)); + assert!(is_peer_healthy); + + // Elapse some time, but not enough to make the peer unhealthy + time_service.clone().into_mock().advance_secs(5); + + // Verify the peer is still healthy + let is_peer_healthy = + check_peer_metadata_health(&mempool_config, &time_service, &Some(&monitoring_metadata)); + assert!(is_peer_healthy); + + // Elapse some more time, but not enough to make the peer unhealthy + time_service.clone().into_mock().advance_secs(4); + + // Verify the peer is still healthy + let is_peer_healthy = + check_peer_metadata_health(&mempool_config, &time_service, &Some(&monitoring_metadata)); + assert!(is_peer_healthy); + + // Elapse some more time to make the peer unhealthy + time_service.clone().into_mock().advance_secs(1); + + // Verify the peer is now unhealthy + let is_peer_healthy = + check_peer_metadata_health(&mempool_config, &time_service, &Some(&monitoring_metadata)); + assert!(!is_peer_healthy); + } + + #[test] + fn test_compare_peer_health_ordering() { + // Create a mempool config with a max sync lag of 10 seconds + let mempool_config = MempoolConfig { + max_sync_lag_before_unhealthy_secs: 10, + ..MempoolConfig::default() + }; + + // Create a mock time service for testing and elapse some time + let time_service = TimeService::mock(); + time_service.clone().into_mock().advance_secs(100); + + // Create monitoring metadata for healthy peer 1 + let healthy_metadata_1 = create_metadata_with_sync_lag(&time_service, 9); + + // Create monitoring metadata for healthy peer 2 + let healthy_metadata_2 = create_metadata_with_sync_lag(&time_service, 5); + + // Create monitoring metadata for unhealthy peer 1 + let unhealthy_metadata_1 = create_metadata_with_sync_lag(&time_service, 11); + + // Create monitoring metadata for unhealthy peer 2 + let unhealthy_metadata_2 = create_metadata_with_sync_lag(&time_service, 20); + + // Verify health metadata against others + for (metadata_1, metadata_2, expected_ordering) in [ + ( + Some(&healthy_metadata_1), + Some(&healthy_metadata_2), + Ordering::Equal, // Both healthy + ), + ( + Some(&healthy_metadata_1), + Some(&unhealthy_metadata_1), + Ordering::Greater, // Prioritize healthy + ), + (Some(&healthy_metadata_1), None, Ordering::Greater), // Prioritize healthy + ] { + verify_metadata_health_ordering( + &mempool_config, + &time_service, + &metadata_1, + &metadata_2, + expected_ordering, + ) + } + + // Verify unhealthy metadata against others + for (metadata_1, metadata_2, expected_ordering) in [ + ( + Some(&unhealthy_metadata_1), + Some(&unhealthy_metadata_2), + Ordering::Equal, // Both unhealthy + ), + ( + Some(&unhealthy_metadata_1), + Some(&healthy_metadata_1), + Ordering::Less, // Prioritize healthy + ), + (Some(&unhealthy_metadata_1), None, Ordering::Equal), // Unhealthy and missing are equal + ] { + verify_metadata_health_ordering( + &mempool_config, + &time_service, + &metadata_1, + &metadata_2, + expected_ordering, + ) + } + + // Verify missing metadata against others + for (metadata_1, metadata_2, expected_ordering) in [ + (None, None, Ordering::Equal), // Both missing + (None, Some(&healthy_metadata_1), Ordering::Less), // Prioritize healthy + (None, Some(&unhealthy_metadata_1), Ordering::Equal), // Missing and unhealthy are equal + ] { + verify_metadata_health_ordering( + &mempool_config, + &time_service, + &metadata_1, + &metadata_2, + expected_ordering, + ) + } + } + #[test] fn test_compare_validator_distance() { // Create monitoring metadata with the same distance @@ -1276,6 +1493,23 @@ mod test { PeerMonitoringMetadata::new(average_ping_latency_secs, None, None, None, None) } + /// Creates peer monitoring metadata with the given sync lag (in seconds) + fn create_metadata_with_sync_lag( + time_service: &TimeService, + sync_lag_secs: usize, + ) -> PeerMonitoringMetadata { + let ledger_timestamp_usecs = get_timestamp_in_past_usecs(time_service, sync_lag_secs); + + let healthy_node_info_response = NodeInformationResponse { + ledger_timestamp_usecs, + ..Default::default() + }; + PeerMonitoringMetadata { + latest_node_info_response: Some(healthy_node_info_response), + ..Default::default() + } + } + /// Creates a validator peer with a random peer ID fn create_validator_peer() -> PeerNetworkId { PeerNetworkId::new(NetworkId::Validator, PeerId::random()) @@ -1290,4 +1524,22 @@ mod test { fn create_public_peer() -> PeerNetworkId { PeerNetworkId::new(NetworkId::Public, PeerId::random()) } + + /// Returns a timestamp in the past (in microseconds) + fn get_timestamp_in_past_usecs(time_service: &TimeService, secs_in_past: usize) -> u64 { + let now_usecs = get_timestamp_now_usecs(time_service); + now_usecs - ((secs_in_past as u64) * MICROS_PER_SECOND) + } + + /// Verifies that the ordering of peer monitoring metadata is as expected + fn verify_metadata_health_ordering( + mempool_config: &MempoolConfig, + time_service: &TimeService, + metadata_1: &Option<&PeerMonitoringMetadata>, + metadata_2: &Option<&PeerMonitoringMetadata>, + expected_ordering: Ordering, + ) { + let ordering = compare_peer_health(mempool_config, time_service, metadata_1, metadata_2); + assert_eq!(ordering, expected_ordering); + } } diff --git a/mempool/src/shared_mempool/runtime.rs b/mempool/src/shared_mempool/runtime.rs index 7fedbb050d6..9253260f109 100644 --- a/mempool/src/shared_mempool/runtime.rs +++ b/mempool/src/shared_mempool/runtime.rs @@ -51,10 +51,12 @@ pub(crate) fn start_shared_mempool( ConfigProvider: OnChainConfigProvider, { let node_type = NodeType::extract_from_config(config); + let transaction_filter_config = config.transaction_filters.mempool_filter.clone(); let smp: SharedMempool, TransactionValidator> = SharedMempool::new( mempool.clone(), config.mempool.clone(), + transaction_filter_config, network_client, db, validator, diff --git a/mempool/src/shared_mempool/tasks.rs b/mempool/src/shared_mempool/tasks.rs index 60476c70e74..38a54946ab9 100644 --- a/mempool/src/shared_mempool/tasks.rs +++ b/mempool/src/shared_mempool/tasks.rs @@ -20,7 +20,7 @@ use crate::{ QuorumStoreRequest, QuorumStoreResponse, SubmissionStatus, }; use anyhow::Result; -use aptos_config::network_id::PeerNetworkId; +use aptos_config::{config::TransactionFilterConfig, network_id::PeerNetworkId}; use aptos_consensus_types::common::RejectedTransactionSummary; use aptos_crypto::HashValue; use aptos_infallible::{Mutex, RwLock}; @@ -49,6 +49,10 @@ use tokio::runtime::Handle; // broadcast_coordinator tasks // // ============================== // +// The sample rate for broadcast events and errors +const BROADCAST_ERROR_LOG_SAMPLE_SECS: u64 = 1; +const BROADCAST_EVENT_LOG_SAMPLE_SECS: u64 = 5; + /// Attempts broadcast to `peer` and schedules the next broadcast. pub(crate) async fn execute_broadcast( peer: PeerNetworkId, @@ -61,35 +65,45 @@ pub(crate) async fn execute_broadcast( TransactionValidator: TransactionValidation, { let network_interface = &smp.network_interface.clone(); + counters::shared_mempool_broadcast_event_inc(counters::RUNNING_LABEL, peer.network_id()); + // If there's no connection, don't bother to broadcast if network_interface.sync_states_exists(&peer) { if let Err(err) = network_interface .execute_broadcast(peer, backoff, smp) .await { + counters::shared_mempool_broadcast_event_inc(err.get_label(), peer.network_id()); match err { - BroadcastError::NetworkError(peer, error) => warn!(LogSchema::event_log( - LogEntry::BroadcastTransaction, - LogEvent::NetworkSendFail - ) - .peer(&peer) - .error(&error)), - BroadcastError::NoTransactions(_) | BroadcastError::PeerNotPrioritized(_, _) => { + BroadcastError::NoTransactions(_) => { + sample!( + SampleRate::Duration(Duration::from_secs(BROADCAST_EVENT_LOG_SAMPLE_SECS)), + debug!("No transactions to broadcast: {:?}", err) + ); + }, + BroadcastError::PeerNotPrioritized(_, _) => { sample!( - SampleRate::Duration(Duration::from_secs(60)), - trace!("{:?}", err) + SampleRate::Duration(Duration::from_secs(BROADCAST_EVENT_LOG_SAMPLE_SECS)), + debug!( + "Peer {} not prioritized. Skipping broadcast: {:?}", + peer, err + ) ); }, _ => { sample!( - SampleRate::Duration(Duration::from_secs(60)), - debug!("{:?}", err) + SampleRate::Duration(Duration::from_secs(BROADCAST_ERROR_LOG_SAMPLE_SECS)), + warn!("Execute broadcast for peer {} failed: {:?}", peer, err) ); }, } } } else { // Drop the scheduled broadcast, we're not connected anymore + counters::shared_mempool_broadcast_event_inc( + counters::DROP_BROADCAST_LABEL, + peer.network_id(), + ); return; } let schedule_backoff = network_interface.is_backoff_mode(&peer); @@ -302,7 +316,15 @@ where NetworkClient: NetworkClientInterface, TransactionValidator: TransactionValidation, { + // Filter out any disallowed transactions let mut statuses = vec![]; + let transactions = + filter_transactions(&smp.transaction_filter_config, transactions, &mut statuses); + + // If there are no transactions left after filtering, return early + if transactions.is_empty() { + return statuses; + } let start_storage_read = Instant::now(); let state_view = smp @@ -382,6 +404,68 @@ where statuses } +/// Filters transactions based on the transaction filter configuration. Any +/// transactions that are filtered out will have their statuses marked accordingly. +fn filter_transactions( + transaction_filter_config: &TransactionFilterConfig, + transactions: Vec<( + SignedTransaction, + Option, + Option, + )>, + statuses: &mut Vec<(SignedTransaction, (MempoolStatus, Option))>, +) -> Vec<( + SignedTransaction, + Option, + Option, +)> { + // If the filter is not enabled, return early + if !transaction_filter_config.is_enabled() { + return transactions; + } + + // Start the filter processing timer + let transaction_filter_timer = counters::PROCESS_TXN_BREAKDOWN_LATENCY + .with_label_values(&[counters::FILTER_TRANSACTIONS_LABEL]) + .start_timer(); + + // Filter the transactions and update the statuses accordingly + let transactions = transactions + .into_iter() + .filter_map(|(transaction, account_sequence_number, priority)| { + if transaction_filter_config + .transaction_filter() + .allows_transaction(&transaction) + { + Some((transaction, account_sequence_number, priority)) + } else { + info!(LogSchema::event_log( + LogEntry::TransactionFilter, + LogEvent::TransactionRejected + ) + .message(&format!( + "Transaction {} rejected by filter", + transaction.committed_hash() + ))); + + statuses.push(( + transaction.clone(), + ( + MempoolStatus::new(MempoolStatusCode::RejectedByFilter), + None, + ), + )); + None + } + }) + .collect(); + + // Update the filter processing latency metrics + transaction_filter_timer.stop_and_record(); + + transactions +} + /// Perfoms VM validation on the transactions and inserts those that passes /// validation into the mempool. #[cfg(not(feature = "consensus-only-perf-test"))] @@ -709,3 +793,140 @@ pub(crate) async fn process_config_update( }, } } + +#[cfg(test)] +mod test { + use super::*; + use aptos_crypto::{ed25519::Ed25519PrivateKey, PrivateKey, SigningKey, Uniform}; + use aptos_transaction_filters::transaction_filter::TransactionFilter; + use aptos_types::{ + chain_id::ChainId, + transaction::{RawTransaction, Script, TransactionPayload}, + }; + + #[test] + fn test_filter_transactions() { + // Create test transactions + let mut transactions = vec![]; + for _ in 0..10 { + let transaction = create_signed_transaction(); + transactions.push((transaction, None, Some(BroadcastPeerPriority::Primary))); + } + + // Create a config with filtering enabled (the first and last transactions will be rejected) + let transaction_filter = TransactionFilter::empty() + .add_sender_filter(false, transactions[0].0.sender()) + .add_sender_filter(false, transactions[9].0.sender()); + let transaction_filter_config = TransactionFilterConfig::new(true, transaction_filter); + + // Filter the transactions + let mut statuses = vec![]; + let filtered_transactions = filter_transactions( + &transaction_filter_config, + transactions.clone(), + &mut statuses, + ); + + // Verify that the first and last transactions are filtered out + assert_eq!(filtered_transactions.len(), 8); + assert!(!filtered_transactions.contains(&transactions[0])); + assert!(!filtered_transactions.contains(&transactions[9])); + + // Verify the filtered transaction statuses + assert_eq!(statuses.len(), 2); + verify_rejected_status(statuses[0].clone(), transactions[0].0.clone()); + verify_rejected_status(statuses[1].clone(), transactions[9].0.clone()); + } + + #[test] + fn test_filter_transactions_disabled() { + // Create test transactions + let num_transactions = 10; + let mut transactions = vec![]; + for _ in 0..num_transactions { + let transaction = create_signed_transaction(); + transactions.push((transaction, None, Some(BroadcastPeerPriority::Primary))); + } + + // Create a config with filtering disabled + let transaction_filter = TransactionFilter::empty().add_all_filter(false); // Reject all transactions + let transaction_filter_config = TransactionFilterConfig::new(false, transaction_filter); + + // Filter the transactions + let mut statuses = vec![]; + let filtered_transactions = filter_transactions( + &transaction_filter_config, + transactions.clone(), + &mut statuses, + ); + + // Verify that all transactions are retained + assert_eq!(filtered_transactions.len(), num_transactions); + assert!(statuses.is_empty()); + for transaction in transactions { + assert!(filtered_transactions.contains(&transaction)); + } + } + + #[test] + fn test_filter_transactions_empty() { + // Create test transactions + let num_transactions = 10; + let mut transactions = vec![]; + for _ in 0..num_transactions { + let transaction = create_signed_transaction(); + transactions.push((transaction, None, Some(BroadcastPeerPriority::Primary))); + } + + // Create a config with filtering enabled (the filter is empty, so no transactions will be rejected) + let transaction_filter = TransactionFilter::empty(); // Allow all transactions + let transaction_filter_config = TransactionFilterConfig::new(true, transaction_filter); + + // Filter the transactions + let mut statuses = vec![]; + let filtered_transactions = filter_transactions( + &transaction_filter_config, + transactions.clone(), + &mut statuses, + ); + + // Verify that all transactions are retained + assert_eq!(filtered_transactions.len(), num_transactions); + assert!(statuses.is_empty()); + for transaction in transactions { + assert!(filtered_transactions.contains(&transaction)); + } + } + + fn create_raw_transaction() -> RawTransaction { + RawTransaction::new( + AccountAddress::random(), + 0, + TransactionPayload::Script(Script::new(vec![], vec![], vec![])), + 0, + 0, + 0, + ChainId::new(10), + ) + } + + fn create_signed_transaction() -> SignedTransaction { + let raw_transaction = create_raw_transaction(); + let private_key_1 = Ed25519PrivateKey::generate_for_testing(); + let signature = private_key_1.sign(&raw_transaction).unwrap(); + + SignedTransaction::new( + raw_transaction.clone(), + private_key_1.public_key(), + signature.clone(), + ) + } + + fn verify_rejected_status( + status: (SignedTransaction, (MempoolStatus, Option)), + transaction: SignedTransaction, + ) { + let rejected_status = MempoolStatus::new(MempoolStatusCode::RejectedByFilter); + assert_eq!(status, (transaction, (rejected_status, None))); + } +} diff --git a/mempool/src/shared_mempool/types.rs b/mempool/src/shared_mempool/types.rs index 5885ade4caa..d526f4473bb 100644 --- a/mempool/src/shared_mempool/types.rs +++ b/mempool/src/shared_mempool/types.rs @@ -10,7 +10,7 @@ use crate::{ }; use anyhow::Result; use aptos_config::{ - config::{MempoolConfig, NodeType}, + config::{MempoolConfig, NodeType, TransactionFilterConfig}, network_id::PeerNetworkId, }; use aptos_consensus_types::common::{ @@ -56,6 +56,7 @@ pub(crate) struct SharedMempool { pub subscribers: Vec>, pub broadcast_within_validator_network: Arc>, pub use_case_history: Arc>, + pub transaction_filter_config: TransactionFilterConfig, } impl< @@ -66,6 +67,7 @@ impl< pub fn new( mempool: Arc>, config: MempoolConfig, + transaction_filter_config: TransactionFilterConfig, network_client: NetworkClient, db: Arc, validator: Arc>, @@ -87,6 +89,7 @@ impl< subscribers, broadcast_within_validator_network: Arc::new(RwLock::new(true)), use_case_history: Arc::new(Mutex::new(use_case_history)), + transaction_filter_config, } } @@ -283,24 +286,6 @@ impl PeerSyncState { } } -/// Identifier for a broadcasted batch of txns. -/// For BatchId(`start_id`, `end_id`), (`start_id`, `end_id`) is the range of timeline IDs read from -/// the core mempool timeline index that produced the txns in this batch. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -struct BatchId(pub u64, pub u64); - -impl PartialOrd for BatchId { - fn partial_cmp(&self, other: &BatchId) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for BatchId { - fn cmp(&self, other: &BatchId) -> std::cmp::Ordering { - (other.0, other.1).cmp(&(self.0, self.1)) - } -} - #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct MultiBucketTimelineIndexIds { pub id_per_bucket: Vec, diff --git a/mempool/src/tests/fuzzing.rs b/mempool/src/tests/fuzzing.rs index d978ecaf6c4..838037d78fc 100644 --- a/mempool/src/tests/fuzzing.rs +++ b/mempool/src/tests/fuzzing.rs @@ -82,9 +82,11 @@ pub fn test_mempool_process_incoming_transactions_impl( HashMap::new(), PeersAndMetadata::new(&[NetworkId::Validator]), ); + let transaction_filter_config = config.transaction_filters.mempool_filter.clone(); let smp: SharedMempool, MockVMValidator> = SharedMempool::new( Arc::new(Mutex::new(CoreMempool::new(&config))), config.mempool.clone(), + transaction_filter_config, network_client, Arc::new(mock_db), vm_validator, diff --git a/mempool/src/tests/node.rs b/mempool/src/tests/node.rs index 33a4ee4e109..b83f07263b5 100644 --- a/mempool/src/tests/node.rs +++ b/mempool/src/tests/node.rs @@ -10,7 +10,7 @@ use crate::{ }; use aptos_channels::{aptos_channel, message_queues::QueueStyle}; use aptos_config::{ - config::{Identity, NodeConfig, PeerRole, RoleType}, + config::{Identity, NodeConfig, PeerRole}, network_id::{NetworkId, PeerNetworkId}, }; use aptos_crypto::{x25519::PrivateKey, Uniform}; @@ -125,9 +125,6 @@ pub trait NodeInfoTrait { PeerNetworkId::new(network_id, self.peer_id(network_id)) } - /// `RoleType` of the `Node` - fn role(&self) -> RoleType; - /// `PeerRole` for use in the upstream / downstream peers fn peer_role(&self) -> PeerRole; } @@ -160,10 +157,6 @@ impl NodeInfoTrait for ValidatorNodeInfo { } } - fn role(&self) -> RoleType { - RoleType::Validator - } - fn peer_role(&self) -> PeerRole { PeerRole::Validator } @@ -197,10 +190,6 @@ impl NodeInfoTrait for ValidatorFullNodeInfo { } } - fn role(&self) -> RoleType { - RoleType::FullNode - } - fn peer_role(&self) -> PeerRole { PeerRole::ValidatorFullNode } @@ -231,10 +220,6 @@ impl NodeInfoTrait for FullNodeInfo { } } - fn role(&self) -> RoleType { - RoleType::FullNode - } - fn peer_role(&self) -> PeerRole { self.peer_role } @@ -336,10 +321,6 @@ impl NodeInfoTrait for Node { self.node_info.peer_id(network_id) } - fn role(&self) -> RoleType { - self.node_info.role() - } - fn peer_role(&self) -> PeerRole { self.node_info.peer_role() } @@ -368,7 +349,7 @@ impl Node { } /// Retrieves a `CoreMempool` - pub fn mempool(&self) -> MutexGuard { + pub fn mempool(&self) -> MutexGuard<'_, CoreMempool> { self.mempool.lock() } diff --git a/movement-migration/framework-upgrades/Move.toml b/movement-migration/framework-upgrades/Move.toml index 3e007b91810..e30ffbc16dd 100644 --- a/movement-migration/framework-upgrades/Move.toml +++ b/movement-migration/framework-upgrades/Move.toml @@ -6,6 +6,6 @@ version = "0.0.0" admin = "0x1" [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "movement" subdir = "aptos-move/framework/aptos-framework" diff --git a/movement-migration/post-migration/Move.toml b/movement-migration/post-migration/Move.toml index 0ee9d14849f..e0705fd5da0 100644 --- a/movement-migration/post-migration/Move.toml +++ b/movement-migration/post-migration/Move.toml @@ -6,6 +6,6 @@ version = "0.0.0" admin = "0x1" [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "l1-migration" subdir = "aptos-move/framework/aptos-framework" \ No newline at end of file diff --git a/movement-migration/post-move2-upgrade/Move.toml b/movement-migration/post-move2-upgrade/Move.toml index 4949273cd64..b3bcf2583c0 100644 --- a/movement-migration/post-move2-upgrade/Move.toml +++ b/movement-migration/post-move2-upgrade/Move.toml @@ -6,6 +6,6 @@ version = "0.0.0" admin = "0x1" [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "l1-migration" subdir = "aptos-move/framework/aptos-framework" diff --git a/movement-migration/test-proposal/Move.toml b/movement-migration/test-proposal/Move.toml index 291b48d2816..d30db1b4624 100644 --- a/movement-migration/test-proposal/Move.toml +++ b/movement-migration/test-proposal/Move.toml @@ -6,6 +6,6 @@ version = "0.0.0" admin = "0x1" [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "l1-migration" subdir = "aptos-move/framework/aptos-framework" diff --git a/movement-migration/update_reconfiguration/Move.toml b/movement-migration/update_reconfiguration/Move.toml index c09a65205d4..ee03c6618d2 100644 --- a/movement-migration/update_reconfiguration/Move.toml +++ b/movement-migration/update_reconfiguration/Move.toml @@ -3,6 +3,6 @@ name = "UpdateReconfiguration" version = "0.0.0" [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "movement" subdir = "aptos-move/framework/aptos-framework" \ No newline at end of file diff --git a/movement-migration/update_recurring_lockup_duration/Move.toml b/movement-migration/update_recurring_lockup_duration/Move.toml index 894c2fb337f..79835169b92 100644 --- a/movement-migration/update_recurring_lockup_duration/Move.toml +++ b/movement-migration/update_recurring_lockup_duration/Move.toml @@ -8,7 +8,7 @@ authors = [] [dev-addresses] [dependencies.AptosFramework] -git = "https://github.com/movementlabsxyz/aptos-core.git" +git = "https://github.com/movement-network/aptos-core.git" rev = "l1-migration" subdir = "aptos-move/framework/aptos-framework" diff --git a/movement-migration/validation-tool/src/types/storage.rs b/movement-migration/validation-tool/src/types/storage.rs index d8a8fe615f2..1df2c436fdf 100644 --- a/movement-migration/validation-tool/src/types/storage.rs +++ b/movement-migration/validation-tool/src/types/storage.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use anyhow::Context; -use aptos_config::config::{StorageConfig, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG}; +use aptos_config::config::{ + RocksdbConfigs, StorageConfig, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG, +}; use aptos_db::AptosDB; use aptos_storage_interface::{ state_store::state_view::db_state_view::{DbStateView, DbStateViewAtVersion}, @@ -21,7 +23,13 @@ impl Storage { StorageDirPaths::from_path(path), true, NO_OP_STORAGE_PRUNER_CONFIG, - Default::default(), + RocksdbConfigs { + // Movement node databases use the unsharded (monolithic) + // ledger_db layout. Upstream defaults this to sharded, so pin + // it explicitly rather than relying on Default. + enable_storage_sharding: false, + ..Default::default() + }, false, config.buffered_state_target_items, config.max_num_nodes_per_lru_cache_shard, @@ -122,7 +130,7 @@ impl GlobalStateKeyIterable { Ok(write_set) => { // It should be okay to collect because there should not be that many state keys in a write set. let items: Vec<_> = write_set - .expect_v0() + .as_v0() .iter() .map(|(key, _)| Ok(key.clone())) .collect(); diff --git a/network/benchmark/src/lib.rs b/network/benchmark/src/lib.rs index a7fc992955f..00b6906143d 100644 --- a/network/benchmark/src/lib.rs +++ b/network/benchmark/src/lib.rs @@ -358,10 +358,10 @@ pub async fn direct_sender( // random payload filler for _ in 0..data_size { - blob.push(rng.gen()); + blob.push(rng.r#gen()); } - let mut counter: u64 = rng.gen(); + let mut counter: u64 = rng.r#gen(); loop { ticker.next().await; @@ -424,10 +424,10 @@ pub async fn rpc_sender( let mut blob = Vec::::with_capacity(data_size); let mut rng = OsRng; for _ in 0..data_size { - blob.push(rng.gen()); + blob.push(rng.r#gen()); } - let mut counter: u64 = rng.gen(); + let mut counter: u64 = rng.r#gen(); let mut open_rpcs = FuturesUnordered::new(); diff --git a/network/framework/src/noise/fuzzing.rs b/network/framework/src/noise/fuzzing.rs index fed9ee70d4f..88c4283e511 100644 --- a/network/framework/src/noise/fuzzing.rs +++ b/network/framework/src/noise/fuzzing.rs @@ -113,11 +113,11 @@ fn generate_first_two_messages() -> (Vec, Vec) { (init_msg, resp_msg) } -pub fn generate_corpus(gen: &mut aptos_proptest_helpers::ValueGenerator) -> Vec { +pub fn generate_corpus(r#gen: &mut aptos_proptest_helpers::ValueGenerator) -> Vec { let (init_msg, resp_msg) = generate_first_two_messages(); // choose a random one let strategy = proptest::arbitrary::any::(); - if gen.generate(strategy) { + if r#gen.generate(strategy) { init_msg } else { resp_msg diff --git a/network/framework/src/peer/fuzzing.rs b/network/framework/src/peer/fuzzing.rs index 9ab4b85bd2e..e6d0ce296b0 100644 --- a/network/framework/src/peer/fuzzing.rs +++ b/network/framework/src/peer/fuzzing.rs @@ -25,8 +25,8 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; /// Generate a sequence of `MultiplexMessage`, bcs serialize them, and write them /// out to a buffer using our length-prefixed message codec. -pub fn generate_corpus(gen: &mut ValueGenerator) -> Vec { - let network_msgs = gen.generate(vec(any::(), 1..20)); +pub fn generate_corpus(r#gen: &mut ValueGenerator) -> Vec { + let network_msgs = r#gen.generate(vec(any::(), 1..20)); let (write_socket, mut read_socket) = MemorySocket::new_pair(); let mut writer = MultiplexMessageSink::new(write_socket, constants::MAX_FRAME_SIZE); diff --git a/network/framework/src/peer_manager/mod.rs b/network/framework/src/peer_manager/mod.rs index d1cb58956f2..98711b5593a 100644 --- a/network/framework/src/peer_manager/mod.rs +++ b/network/framework/src/peer_manager/mod.rs @@ -363,7 +363,7 @@ where metadata.origin == ConnectionOrigin::Inbound && trusted_peers .get(peer_id) - .map_or(true, |peer| peer.role == PeerRole::Unknown) + .is_none_or(|peer| peer.role == PeerRole::Unknown) }) .count(); diff --git a/network/framework/src/peer_manager/tests.rs b/network/framework/src/peer_manager/tests.rs index 61f8ea51411..998dd927fdf 100644 --- a/network/framework/src/peer_manager/tests.rs +++ b/network/framework/src/peer_manager/tests.rs @@ -158,7 +158,7 @@ async fn assert_peer_disconnected_event( ) { let connection_event = peer_manager.transport_notifs_rx.select_next_some().await; match &connection_event { - TransportNotification::Disconnected(ref actual_metadata, ref actual_reason) => { + TransportNotification::Disconnected(actual_metadata, actual_reason) => { assert_eq!(actual_metadata.remote_peer_id, peer_id); assert_eq!(*actual_reason, reason); assert_eq!(actual_metadata.origin, origin); diff --git a/network/framework/src/protocols/health_checker/mod.rs b/network/framework/src/protocols/health_checker/mod.rs index 0287bb32ebf..0e24c38a6af 100644 --- a/network/framework/src/protocols/health_checker/mod.rs +++ b/network/framework/src/protocols/health_checker/mod.rs @@ -242,7 +242,7 @@ impl + Unpin> HealthChec } for peer_id in connected { - let nonce = self.rng.gen::(); + let nonce = self.rng.r#gen::(); trace!( NetworkSchema::new(&self.network_context), round = self.round, diff --git a/network/framework/src/transport/mod.rs b/network/framework/src/transport/mod.rs index a541103e912..65e0eb724fc 100644 --- a/network/framework/src/transport/mod.rs +++ b/network/framework/src/transport/mod.rs @@ -289,7 +289,7 @@ async fn upgrade_inbound( ) ); } - let err = io::Error::new(io::ErrorKind::Other, err); + let err = io::Error::other(err); add_pp_addr(proxy_protocol_enabled, err, &addr) })?; let remote_pubkey = socket.get_remote_static(); @@ -314,11 +314,7 @@ async fn upgrade_inbound( remote_peer_id.short_str(), err ); - add_pp_addr( - proxy_protocol_enabled, - io::Error::new(io::ErrorKind::Other, err), - &addr, - ) + add_pp_addr(proxy_protocol_enabled, io::Error::other(err), &addr) })?; // return successful connection @@ -371,7 +367,7 @@ pub async fn upgrade_outbound( ) ); } - io::Error::new(io::ErrorKind::Other, err) + io::Error::other(err) })?; // sanity check: Noise IK should always guarantee this is true @@ -393,7 +389,7 @@ pub async fn upgrade_outbound( "handshake negotiation with peer {} failed: {}", remote_peer_id, e ); - io::Error::new(io::ErrorKind::Other, e) + io::Error::other(e) })?; // return successful connection @@ -544,7 +540,10 @@ where peer_id: PeerId, addr: NetworkAddress, ) -> io::Result< - impl Future>>> + Send + 'static, + impl Future>>> + + Send + + 'static + + use, > { // parse aptosnet protocols // TODO(philiphayes): `Transport` trait should include parsing in `dial`? @@ -593,11 +592,14 @@ where Item = io::Result<( impl Future>>> + Send - + 'static, + + 'static + + use, NetworkAddress, )>, - > + Send - + 'static, + > + + Send + + 'static + + use, NetworkAddress, )> { // listen on base transport. for example, this could be a tcp socket or diff --git a/network/memsocket/src/lib.rs b/network/memsocket/src/lib.rs index 82c4128ef6f..a3cc670ee2b 100644 --- a/network/memsocket/src/lib.rs +++ b/network/memsocket/src/lib.rs @@ -209,7 +209,7 @@ impl MemoryListener { match Pin::new(&mut self.incoming).poll_next(context) { Poll::Ready(Some(socket)) => Poll::Ready(Ok(socket)), Poll::Ready(None) => { - let err = Error::new(ErrorKind::Other, "MemoryListener unknown error"); + let err = Error::other("MemoryListener unknown error"); Poll::Ready(Err(err)) }, Poll::Pending => Poll::Pending, diff --git a/network/netcore/src/framing.rs b/network/netcore/src/framing.rs index 82737670fc0..3cf49095b5b 100644 --- a/network/netcore/src/framing.rs +++ b/network/netcore/src/framing.rs @@ -49,7 +49,7 @@ where let len = buf .len() .try_into() - .map_err(|_e| std::io::Error::new(std::io::ErrorKind::Other, "Too big"))?; + .map_err(|_e| std::io::Error::other("Too big"))?; write_u16frame_len(&mut stream, len).await?; stream.write_all(buf).await?; diff --git a/network/netcore/src/transport/tcp.rs b/network/netcore/src/transport/tcp.rs index 196e40340db..cf5f1e1f2cc 100644 --- a/network/netcore/src/transport/tcp.rs +++ b/network/netcore/src/transport/tcp.rs @@ -277,26 +277,20 @@ async fn connect_via_proxy(proxy_addr: String, addr: NetworkAddress) -> io::Resu let msg = &buffer[..read]; if len == 0 { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "HTTP proxy CONNECT failed. Len == 0. Message: {}", - String::from_utf8_lossy(msg) - ), - )); + return Err(io::Error::other(format!( + "HTTP proxy CONNECT failed. Len == 0. Message: {}", + String::from_utf8_lossy(msg) + ))); } else if msg.len() >= 16 { if (msg.starts_with(b"HTTP/1.1 200") || msg.starts_with(b"HTTP/1.0 200")) && msg.ends_with(b"\r\n\r\n") { return Ok(stream); } else { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "HTTP proxy CONNECT failed! Unexpected message: {}", - String::from_utf8_lossy(msg) - ), - )); + return Err(io::Error::other(format!( + "HTTP proxy CONNECT failed! Unexpected message: {}", + String::from_utf8_lossy(msg) + ))); } } else { // Keep reading until we get at least 16 bytes diff --git a/peer-monitoring-service/client/src/peer_states/latency_info.rs b/peer-monitoring-service/client/src/peer_states/latency_info.rs index fac6a4c26c2..d20c34060b8 100644 --- a/peer-monitoring-service/client/src/peer_states/latency_info.rs +++ b/peer-monitoring-service/client/src/peer_states/latency_info.rs @@ -362,7 +362,7 @@ mod test { /// Returns a random U64 fn get_random_u64() -> u64 { let mut rng = OsRng; - rng.gen() + rng.r#gen() } /// Handles a monitoring service response from a peer diff --git a/peer-monitoring-service/client/src/tests/utils.rs b/peer-monitoring-service/client/src/tests/utils.rs index 13a1358d0bc..a7c096746a1 100644 --- a/peer-monitoring-service/client/src/tests/utils.rs +++ b/peer-monitoring-service/client/src/tests/utils.rs @@ -227,7 +227,7 @@ pub fn get_distance_from_validators(peer_network_id: &PeerNetworkId) -> u64 { /// Returns a random u64 for test purposes fn get_random_u64() -> u64 { - OsRng.gen() + OsRng.r#gen() } /// Handle several latency ping requests and responses for the given peer diff --git a/peer-monitoring-service/server/src/tests.rs b/peer-monitoring-service/server/src/tests.rs index 7b783364522..c5cd05ba90f 100644 --- a/peer-monitoring-service/server/src/tests.rs +++ b/peer-monitoring-service/server/src/tests.rs @@ -55,8 +55,8 @@ use aptos_types::{ state_value::{StateValue, StateValueChunkWithProof}, }, transaction::{ - AccountOrderedTransactionsWithProof, TransactionListWithProof, - TransactionOutputListWithProof, TransactionWithProof, Version, + AccountOrderedTransactionsWithProof, TransactionListWithProofV2, + TransactionOutputListWithProofV2, TransactionWithProof, Version, }, PeerId, }; @@ -597,7 +597,7 @@ pub fn initialize_logger() { /// Returns a random network ID fn get_random_network_id() -> NetworkId { let mut rng = OsRng; - let random_number: u8 = rng.gen(); + let random_number: u8 = rng.r#gen(); match random_number % 3 { 0 => NetworkId::Validator, 1 => NetworkId::Vfn, @@ -633,7 +633,7 @@ mod database_mock { batch_size: u64, ledger_version: Version, fetch_events: bool, - ) -> Result; + ) -> Result; fn get_transaction_by_hash( &self, @@ -658,7 +658,7 @@ mod database_mock { start_version: Version, limit: u64, ledger_version: Version, - ) -> Result; + ) -> Result; fn get_events( &self, diff --git a/peer-monitoring-service/types/src/response.rs b/peer-monitoring-service/types/src/response.rs index 6925f2f4ced..f0a823e9e50 100644 --- a/peer-monitoring-service/types/src/response.rs +++ b/peer-monitoring-service/types/src/response.rs @@ -91,7 +91,7 @@ pub struct ServerProtocolVersionResponse { } /// A response for the node information request -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct NodeInformationResponse { pub build_information: BTreeMap, // The build information of the node pub highest_synced_epoch: u64, // The highest synced epoch of the node diff --git a/proposals/2026-04-08-disable-feature-67/metadata/disable_concurrent_fungible_balance.json b/proposals/2026-04-08-disable-feature-67/metadata/disable_concurrent_fungible_balance.json index 58a0a5c3e61..a34226adcd9 100644 --- a/proposals/2026-04-08-disable-feature-67/metadata/disable_concurrent_fungible_balance.json +++ b/proposals/2026-04-08-disable-feature-67/metadata/disable_concurrent_fungible_balance.json @@ -1,6 +1,6 @@ { "title": "Disable concurrent fungible balance", "description": "This is for disabling concurrent fungible balance", - "source_code_url": "https://github.com/movementlabsxyz/aptos-core", - "discussion_url": "https://github.com/movementlabsxyz/aptos-core" -} \ No newline at end of file + "source_code_url": "https://github.com/movement-network/aptos-core", + "discussion_url": "https://github.com/movement-network/aptos-core" +} diff --git a/protos/README.md b/protos/README.md index ad6318a6e6e..bb720ecdc9d 100644 --- a/protos/README.md +++ b/protos/README.md @@ -17,3 +17,195 @@ If you haven't installed deps yet, run this script from this directory: ```bash ./scripts/install_deps.sh ``` + +# Transactions + +## Signatures + +Converted signatures part of transactions proto to uml (below) + +signatures_plantuml + +```uml +@startuml SignatureStructure + +' Root Signature message +class Signature { + +Type type + .. oneof signature .. + +Ed25519Signature ed25519 + +MultiEd25519Signature multi_ed25519 + +MultiAgentSignature multi_agent + +FeePayerSignature fee_payer + +SingleSender single_sender +} + +enum Signature::Type { + TYPE_UNSPECIFIED = 0 + TYPE_ED25519 = 1 + TYPE_MULTI_ED25519 = 2 + TYPE_MULTI_AGENT = 3 + TYPE_FEE_PAYER = 4 + TYPE_SINGLE_SENDER = 6 +} + +' Ed25519Signature +class Ed25519Signature { + +bytes public_key + +bytes signature +} + +' MultiEd25519Signature +class MultiEd25519Signature { + +repeated bytes public_keys + +repeated bytes signatures + +uint32 threshold + +repeated uint32 public_key_indices +} + +' MultiAgentSignature +class MultiAgentSignature { + +AccountSignature sender + +repeated string secondary_signer_addresses + +repeated AccountSignature secondary_signers +} + +' FeePayerSignature +class FeePayerSignature { + +AccountSignature sender + +repeated string secondary_signer_addresses + +repeated AccountSignature secondary_signers + +string fee_payer_address + +AccountSignature fee_payer_signer +} + +' SingleSender +class SingleSender { + +AccountSignature sender +} + +' AccountSignature +class AccountSignature { + +Type type + .. oneof signature .. + +Ed25519Signature ed25519 + +MultiEd25519Signature multi_ed25519 + +SingleKeySignature single_key_signature + +MultiKeySignature multi_key_signature + +AbstractionSignature abstraction +} + +enum AccountSignature::Type { + TYPE_UNSPECIFIED = 0 + TYPE_ED25519 = 1 + TYPE_MULTI_ED25519 = 2 + TYPE_SINGLE_KEY = 4 + TYPE_MULTI_KEY = 5 + TYPE_ABSTRACTION = 6 +} + +' SingleKeySignature +class SingleKeySignature { + +AnyPublicKey public_key + +AnySignature signature +} + +' MultiKeySignature +class MultiKeySignature { + +repeated AnyPublicKey public_keys + +repeated IndexedSignature signatures + +uint32 signatures_required +} + +' AbstractionSignature +class AbstractionSignature { + +string function_info + +bytes signature +} + +' IndexedSignature +class IndexedSignature { + +uint32 index + +AnySignature signature +} + +' AnyPublicKey +class AnyPublicKey { + +Type type + +bytes public_key +} + +enum AnyPublicKey::Type { + TYPE_UNSPECIFIED = 0 + TYPE_ED25519 = 1 + TYPE_SECP256K1_ECDSA = 2 + TYPE_SECP256R1_ECDSA = 3 + TYPE_KEYLESS = 4 + TYPE_FEDERATED_KEYLESS = 5 +} + +' AnySignature +class AnySignature { + +Type type + +bytes signature (deprecated) + .. oneof signature_variant .. + +Ed25519 ed25519 + +Secp256k1Ecdsa secp256k1_ecdsa + +WebAuthn webauthn + +Keyless keyless +} + +enum AnySignature::Type { + TYPE_UNSPECIFIED = 0 + TYPE_ED25519 = 1 + TYPE_SECP256K1_ECDSA = 2 + TYPE_WEBAUTHN = 3 + TYPE_KEYLESS = 4 +} + +class Ed25519 { + +bytes signature +} + +class Secp256k1Ecdsa { + +bytes signature +} + +class WebAuthn { + +bytes signature +} + +class Keyless { + +bytes signature +} + +' Associations +Signature --> Ed25519Signature +Signature --> MultiEd25519Signature +Signature --> MultiAgentSignature +Signature --> FeePayerSignature +Signature --> SingleSender + +MultiAgentSignature --> AccountSignature +FeePayerSignature --> AccountSignature +SingleSender --> AccountSignature + +AccountSignature --> Ed25519Signature +AccountSignature --> MultiEd25519Signature +AccountSignature --> SingleKeySignature +AccountSignature --> MultiKeySignature +AccountSignature --> AbstractionSignature + +SingleKeySignature --> AnyPublicKey +SingleKeySignature --> AnySignature +MultiKeySignature --> AnyPublicKey +MultiKeySignature --> IndexedSignature +IndexedSignature --> AnySignature + +AnySignature --> Ed25519 +AnySignature --> Secp256k1Ecdsa +AnySignature --> WebAuthn +AnySignature --> Keyless + +@enduml +``` diff --git a/protos/proto/aptos/transaction/v1/transaction.proto b/protos/proto/aptos/transaction/v1/transaction.proto index 1f026df6592..85ea6a437ae 100644 --- a/protos/proto/aptos/transaction/v1/transaction.proto +++ b/protos/proto/aptos/transaction/v1/transaction.proto @@ -392,6 +392,7 @@ message MoveStruct { string name = 1; bool is_native = 2; bool is_event = 6; + bool is_enum = 7; repeated MoveAbility abilities = 3; repeated MoveStructGenericTypeParam generic_type_params = 4; repeated MoveStructField fields = 5; @@ -592,7 +593,7 @@ message MultiKeySignature { uint32 signatures_required = 3; } -message AbstractionSignature { +message AbstractSignature { string function_info = 1; bytes signature = 2; } @@ -620,7 +621,7 @@ message AccountSignature { // 4 is reserved. SingleKeySignature single_key_signature = 5; MultiKeySignature multi_key_signature = 6; - AbstractionSignature abstraction = 7; + AbstractSignature abstraction = 7; } } diff --git a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py index c3d965c0acd..afc7782fb84 100644 --- a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py +++ b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py @@ -17,7 +17,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n&aptos/transaction/v1/transaction.proto\x12\x14\x61ptos.transaction.v1\x1a$aptos/util/timestamp/timestamp.proto"\x9a\x01\n\x05\x42lock\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x12\n\x06height\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x37\n\x0ctransactions\x18\x03 \x03(\x0b\x32!.aptos.transaction.v1.Transaction\x12\x10\n\x08\x63hain_id\x18\x04 \x01(\r"\xda\x07\n\x0bTransaction\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x13\n\x07version\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x33\n\x04info\x18\x03 \x01(\x0b\x32%.aptos.transaction.v1.TransactionInfo\x12\x11\n\x05\x65poch\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x18\n\x0c\x62lock_height\x18\x05 \x01(\x04\x42\x02\x30\x01\x12?\n\x04type\x18\x06 \x01(\x0e\x32\x31.aptos.transaction.v1.Transaction.TransactionType\x12H\n\x0e\x62lock_metadata\x18\x07 \x01(\x0b\x32..aptos.transaction.v1.BlockMetadataTransactionH\x00\x12;\n\x07genesis\x18\x08 \x01(\x0b\x32(.aptos.transaction.v1.GenesisTransactionH\x00\x12L\n\x10state_checkpoint\x18\t \x01(\x0b\x32\x30.aptos.transaction.v1.StateCheckpointTransactionH\x00\x12\x35\n\x04user\x18\n \x01(\x0b\x32%.aptos.transaction.v1.UserTransactionH\x00\x12?\n\tvalidator\x18\x15 \x01(\x0b\x32*.aptos.transaction.v1.ValidatorTransactionH\x00\x12H\n\x0e\x62lock_epilogue\x18\x17 \x01(\x0b\x32..aptos.transaction.v1.BlockEpilogueTransactionH\x00\x12<\n\tsize_info\x18\x16 \x01(\x0b\x32).aptos.transaction.v1.TransactionSizeInfo"\xfd\x01\n\x0fTransactionType\x12 \n\x1cTRANSACTION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18TRANSACTION_TYPE_GENESIS\x10\x01\x12#\n\x1fTRANSACTION_TYPE_BLOCK_METADATA\x10\x02\x12%\n!TRANSACTION_TYPE_STATE_CHECKPOINT\x10\x03\x12\x19\n\x15TRANSACTION_TYPE_USER\x10\x04\x12\x1e\n\x1aTRANSACTION_TYPE_VALIDATOR\x10\x14\x12#\n\x1fTRANSACTION_TYPE_BLOCK_EPILOGUE\x10\x15\x42\n\n\x08txn_data"\xbe\x01\n\x18\x42lockMetadataTransaction\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x05round\x18\x02 \x01(\x04\x42\x02\x30\x01\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x12#\n\x1bprevious_block_votes_bitvec\x18\x04 \x01(\x0c\x12\x10\n\x08proposer\x18\x05 \x01(\t\x12\x1f\n\x17\x66\x61iled_proposer_indices\x18\x06 \x03(\r"r\n\x12GenesisTransaction\x12/\n\x07payload\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x1c\n\x1aStateCheckpointTransaction"\xfa\n\n\x14ValidatorTransaction\x12[\n\x13observed_jwk_update\x18\x01 \x01(\x0b\x32<.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdateH\x00\x12J\n\ndkg_update\x18\x02 \x01(\x0b\x32\x34.aptos.transaction.v1.ValidatorTransaction.DkgUpdateH\x00\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x1a\xc4\x07\n\x11ObservedJwkUpdate\x12s\n\x17quorum_certified_update\x18\x01 \x01(\x0b\x32R.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.QuorumCertifiedUpdate\x1a\x8d\x04\n\x14\x45xportedProviderJWKs\x12\x0e\n\x06issuer\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x04\x12\x63\n\x04jwks\x18\x03 \x03(\x0b\x32U.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK\x1a\xee\x02\n\x03JWK\x12\x7f\n\x0funsupported_jwk\x18\x01 \x01(\x0b\x32\x64.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.UnsupportedJWKH\x00\x12h\n\x03rsa\x18\x02 \x01(\x0b\x32Y.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.RSAH\x00\x1a\x42\n\x03RSA\x12\x0b\n\x03kid\x18\x01 \x01(\t\x12\x0b\n\x03kty\x18\x02 \x01(\t\x12\x0b\n\x03\x61lg\x18\x03 \x01(\t\x12\t\n\x01\x65\x18\x04 \x01(\t\x12\t\n\x01n\x18\x05 \x01(\t\x1a-\n\x0eUnsupportedJWK\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x42\t\n\x07JwkType\x1a\x41\n\x1a\x45xportedAggregateSignature\x12\x16\n\x0esigner_indices\x18\x01 \x03(\x04\x12\x0b\n\x03sig\x18\x02 \x01(\x0c\x1a\xe6\x01\n\x15QuorumCertifiedUpdate\x12\x61\n\x06update\x18\x01 \x01(\x0b\x32Q.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs\x12j\n\tmulti_sig\x18\x02 \x01(\x0b\x32W.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedAggregateSignature\x1a\xa8\x01\n\tDkgUpdate\x12Z\n\x0e\x64kg_transcript\x18\x01 \x01(\x0b\x32\x42.aptos.transaction.v1.ValidatorTransaction.DkgUpdate.DkgTranscript\x1a?\n\rDkgTranscript\x12\r\n\x05\x65poch\x18\x01 \x01(\x04\x12\x0e\n\x06\x61uthor\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x42\x1a\n\x18ValidatorTransactionType"n\n\x18\x42lockEpilogueTransaction\x12?\n\x0e\x62lock_end_info\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.BlockEndInfoH\x00\x88\x01\x01\x42\x11\n\x0f_block_end_info"\x9e\x01\n\x0c\x42lockEndInfo\x12\x1f\n\x17\x62lock_gas_limit_reached\x18\x01 \x01(\x08\x12"\n\x1a\x62lock_output_limit_reached\x18\x02 \x01(\x08\x12\'\n\x1f\x62lock_effective_block_gas_units\x18\x03 \x01(\x04\x12 \n\x18\x62lock_approx_output_size\x18\x04 \x01(\x04"}\n\x0fUserTransaction\x12=\n\x07request\x18\x01 \x01(\x0b\x32,.aptos.transaction.v1.UserTransactionRequest\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x9f\x01\n\x05\x45vent\x12+\n\x03key\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.EventKey\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12,\n\x04type\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x10\n\x08type_str\x18\x05 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t"\xa1\x02\n\x0fTransactionInfo\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x19\n\x11state_change_hash\x18\x02 \x01(\x0c\x12\x17\n\x0f\x65vent_root_hash\x18\x03 \x01(\x0c\x12"\n\x15state_checkpoint_hash\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x08gas_used\x18\x05 \x01(\x04\x42\x02\x30\x01\x12\x0f\n\x07success\x18\x06 \x01(\x08\x12\x11\n\tvm_status\x18\x07 \x01(\t\x12\x1d\n\x15\x61\x63\x63umulator_root_hash\x18\x08 \x01(\x0c\x12\x35\n\x07\x63hanges\x18\t \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChangeB\x18\n\x16_state_checkpoint_hash"@\n\x08\x45ventKey\x12\x1b\n\x0f\x63reation_number\x18\x01 \x01(\x04\x42\x02\x30\x01\x12\x17\n\x0f\x61\x63\x63ount_address\x18\x02 \x01(\t"\xb0\x02\n\x16UserTransactionRequest\x12\x0e\n\x06sender\x18\x01 \x01(\t\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0emax_gas_amount\x18\x03 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0egas_unit_price\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x42\n\x19\x65xpiration_timestamp_secs\x18\x05 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x39\n\x07payload\x18\x06 \x01(\x0b\x32(.aptos.transaction.v1.TransactionPayload\x12\x32\n\tsignature\x18\x07 \x01(\x0b\x32\x1f.aptos.transaction.v1.Signature"\xda\x02\n\x08WriteSet\x12\x43\n\x0ewrite_set_type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.WriteSet.WriteSetType\x12@\n\x10script_write_set\x18\x02 \x01(\x0b\x32$.aptos.transaction.v1.ScriptWriteSetH\x00\x12@\n\x10\x64irect_write_set\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DirectWriteSetH\x00"x\n\x0cWriteSetType\x12\x1e\n\x1aWRITE_SET_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1fWRITE_SET_TYPE_SCRIPT_WRITE_SET\x10\x01\x12#\n\x1fWRITE_SET_TYPE_DIRECT_WRITE_SET\x10\x02\x42\x0b\n\twrite_set"Y\n\x0eScriptWriteSet\x12\x12\n\nexecute_as\x18\x01 \x01(\t\x12\x33\n\x06script\x18\x02 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayload"}\n\x0e\x44irectWriteSet\x12>\n\x10write_set_change\x18\x01 \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChange\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x89\x05\n\x0eWriteSetChange\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).aptos.transaction.v1.WriteSetChange.Type\x12;\n\rdelete_module\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.DeleteModuleH\x00\x12?\n\x0f\x64\x65lete_resource\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DeleteResourceH\x00\x12\x42\n\x11\x64\x65lete_table_item\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableItemH\x00\x12\x39\n\x0cwrite_module\x18\x05 \x01(\x0b\x32!.aptos.transaction.v1.WriteModuleH\x00\x12=\n\x0ewrite_resource\x18\x06 \x01(\x0b\x32#.aptos.transaction.v1.WriteResourceH\x00\x12@\n\x10write_table_item\x18\x07 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableItemH\x00"\xb5\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12TYPE_DELETE_MODULE\x10\x01\x12\x18\n\x14TYPE_DELETE_RESOURCE\x10\x02\x12\x1a\n\x16TYPE_DELETE_TABLE_ITEM\x10\x03\x12\x15\n\x11TYPE_WRITE_MODULE\x10\x04\x12\x17\n\x13TYPE_WRITE_RESOURCE\x10\x05\x12\x19\n\x15TYPE_WRITE_TABLE_ITEM\x10\x06\x42\x08\n\x06\x63hange"k\n\x0c\x44\x65leteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x32\n\x06module\x18\x03 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId"~\n\x0e\x44\x65leteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t"{\n\x0f\x44\x65leteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x33\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableData"0\n\x0f\x44\x65leteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t"n\n\x0bWriteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x36\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32(.aptos.transaction.v1.MoveModuleBytecode"\x8b\x01\n\rWriteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\t"R\n\x0eWriteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\x12\x12\n\nvalue_type\x18\x04 \x01(\t"y\n\x0eWriteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x32\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableData"\xdc\x04\n\x12TransactionPayload\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.aptos.transaction.v1.TransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00\x12=\n\x0escript_payload\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayloadH\x00\x12\x42\n\x11write_set_payload\x18\x05 \x01(\x0b\x32%.aptos.transaction.v1.WriteSetPayloadH\x00\x12\x41\n\x10multisig_payload\x18\x06 \x01(\x0b\x32%.aptos.transaction.v1.MultisigPayloadH\x00\x12>\n\x0f\x65xtra_config_v1\x18\x07 \x01(\x0b\x32#.aptos.transaction.v1.ExtraConfigV1H\x01"\x93\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x12\x17\n\x13TYPE_SCRIPT_PAYLOAD\x10\x02\x12\x1a\n\x16TYPE_WRITE_SET_PAYLOAD\x10\x04\x12\x19\n\x15TYPE_MULTISIG_PAYLOAD\x10\x05"\x04\x08\x03\x10\x03\x42\t\n\x07payloadB\x0e\n\x0c\x65xtra_configJ\x04\x08\x04\x10\x05"\x85\x01\n\rExtraConfigV1\x12\x1d\n\x10multisig_address\x18\x01 \x01(\tH\x00\x88\x01\x01\x12$\n\x17replay_protection_nonce\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x13\n\x11_multisig_addressB\x1a\n\x18_replay_protection_nonce"\xb9\x01\n\x14\x45ntryFunctionPayload\x12\x37\n\x08\x66unction\x18\x01 \x01(\x0b\x32%.aptos.transaction.v1.EntryFunctionId\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t\x12\x1d\n\x15\x65ntry_function_id_str\x18\x04 \x01(\t"W\n\x12MoveScriptBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12/\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.MoveFunction"\x92\x01\n\rScriptPayload\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0b\x32(.aptos.transaction.v1.MoveScriptBytecode\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t"\x97\x01\n\x0fMultisigPayload\x12\x18\n\x10multisig_address\x18\x01 \x01(\t\x12R\n\x13transaction_payload\x18\x02 \x01(\x0b\x32\x30.aptos.transaction.v1.MultisigTransactionPayloadH\x00\x88\x01\x01\x42\x16\n\x14_transaction_payload"\xf9\x01\n\x1aMultisigTransactionPayload\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.aptos.transaction.v1.MultisigTransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00"=\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x42\t\n\x07payload"U\n\x12MoveModuleBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12-\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32 .aptos.transaction.v1.MoveModule"\xd2\x01\n\nMoveModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x33\n\x07\x66riends\x18\x03 \x03(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12=\n\x11\x65xposed_functions\x18\x04 \x03(\x0b\x32".aptos.transaction.v1.MoveFunction\x12\x31\n\x07structs\x18\x05 \x03(\x0b\x32 .aptos.transaction.v1.MoveStruct"\x92\x03\n\x0cMoveFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x41\n\nvisibility\x18\x02 \x01(\x0e\x32-.aptos.transaction.v1.MoveFunction.Visibility\x12\x10\n\x08is_entry\x18\x03 \x01(\x08\x12O\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x32.aptos.transaction.v1.MoveFunctionGenericTypeParam\x12.\n\x06params\x18\x05 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12.\n\x06return\x18\x06 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"n\n\nVisibility\x12\x1a\n\x16VISIBILITY_UNSPECIFIED\x10\x00\x12\x16\n\x12VISIBILITY_PRIVATE\x10\x01\x12\x15\n\x11VISIBILITY_PUBLIC\x10\x02\x12\x15\n\x11VISIBILITY_FRIEND\x10\x03"\xfb\x01\n\nMoveStruct\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tis_native\x18\x02 \x01(\x08\x12\x10\n\x08is_event\x18\x06 \x01(\x08\x12\x34\n\tabilities\x18\x03 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12M\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x30.aptos.transaction.v1.MoveStructGenericTypeParam\x12\x35\n\x06\x66ields\x18\x05 \x03(\x0b\x32%.aptos.transaction.v1.MoveStructField"h\n\x1aMoveStructGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12\x12\n\nis_phantom\x18\x02 \x01(\x08"M\n\x0fMoveStructField\x12\x0c\n\x04name\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType"V\n\x1cMoveFunctionGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility"\xf8\x02\n\x08MoveType\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.aptos.transaction.v1.MoveTypes\x12\x30\n\x06vector\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeH\x00\x12\x35\n\x06struct\x18\x04 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTagH\x00\x12"\n\x18generic_type_param_index\x18\x05 \x01(\rH\x00\x12\x41\n\treference\x18\x06 \x01(\x0b\x32,.aptos.transaction.v1.MoveType.ReferenceTypeH\x00\x12\x14\n\nunparsable\x18\x07 \x01(\tH\x00\x1aL\n\rReferenceType\x12\x0f\n\x07mutable\x18\x01 \x01(\x08\x12*\n\x02to\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeB\t\n\x07\x63ontent"D\n\x0fWriteSetPayload\x12\x31\n\twrite_set\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet"S\n\x0f\x45ntryFunctionId\x12\x32\n\x06module\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12\x0c\n\x04name\x18\x02 \x01(\t"-\n\x0cMoveModuleId\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"{\n\rMoveStructTag\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12;\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"\x9b\x04\n\tSignature\x12\x32\n\x04type\x18\x01 \x01(\x0e\x32$.aptos.transaction.v1.Signature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12@\n\x0bmulti_agent\x18\x04 \x01(\x0b\x32).aptos.transaction.v1.MultiAgentSignatureH\x00\x12<\n\tfee_payer\x18\x05 \x01(\x0b\x32\'.aptos.transaction.v1.FeePayerSignatureH\x00\x12;\n\rsingle_sender\x18\x07 \x01(\x0b\x32".aptos.transaction.v1.SingleSenderH\x00"\x8e\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x14\n\x10TYPE_MULTI_AGENT\x10\x03\x12\x12\n\x0eTYPE_FEE_PAYER\x10\x04\x12\x16\n\x12TYPE_SINGLE_SENDER\x10\x06"\x04\x08\x05\x10\x05\x42\x0b\n\tsignature"9\n\x10\x45\x64\x32\x35\x35\x31\x39Signature\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c"o\n\x15MultiEd25519Signature\x12\x13\n\x0bpublic_keys\x18\x01 \x03(\x0c\x12\x12\n\nsignatures\x18\x02 \x03(\x0c\x12\x11\n\tthreshold\x18\x03 \x01(\r\x12\x1a\n\x12public_key_indices\x18\x04 \x03(\r"\xb4\x01\n\x13MultiAgentSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature"\x8f\x02\n\x11\x46\x65\x65PayerSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12\x19\n\x11\x66\x65\x65_payer_address\x18\x04 \x01(\t\x12@\n\x10\x66\x65\x65_payer_signer\x18\x05 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xec\x01\n\x0c\x41nyPublicKey\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnyPublicKey.Type\x12\x12\n\npublic_key\x18\x02 \x01(\x0c"\x90\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x18\n\x14TYPE_SECP256R1_ECDSA\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x12\x1a\n\x16TYPE_FEDERATED_KEYLESS\x10\x05"\xb9\x03\n\x0c\x41nySignature\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnySignature.Type\x12\x15\n\tsignature\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x30\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x03 \x01(\x0b\x32\x1d.aptos.transaction.v1.Ed25519H\x00\x12?\n\x0fsecp256k1_ecdsa\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.Secp256k1EcdsaH\x00\x12\x32\n\x08webauthn\x18\x05 \x01(\x0b\x32\x1e.aptos.transaction.v1.WebAuthnH\x00\x12\x30\n\x07keyless\x18\x06 \x01(\x0b\x32\x1d.aptos.transaction.v1.KeylessH\x00"m\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x11\n\rTYPE_WEBAUTHN\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x42\x13\n\x11signature_variant"\x1c\n\x07\x45\x64\x32\x35\x35\x31\x39\x12\x11\n\tsignature\x18\x01 \x01(\x0c"#\n\x0eSecp256k1Ecdsa\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1d\n\x08WebAuthn\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1c\n\x07Keyless\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x83\x01\n\x12SingleKeySignature\x12\x36\n\npublic_key\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"X\n\x10IndexedSignature\x12\r\n\x05index\x18\x01 \x01(\r\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"\xa5\x01\n\x11MultiKeySignature\x12\x37\n\x0bpublic_keys\x18\x01 \x03(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12:\n\nsignatures\x18\x02 \x03(\x0b\x32&.aptos.transaction.v1.IndexedSignature\x12\x1b\n\x13signatures_required\x18\x03 \x01(\r"@\n\x14\x41\x62stractionSignature\x12\x15\n\rfunction_info\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c"F\n\x0cSingleSender\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xbe\x04\n\x10\x41\x63\x63ountSignature\x12\x39\n\x04type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.AccountSignature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12H\n\x14single_key_signature\x18\x05 \x01(\x0b\x32(.aptos.transaction.v1.SingleKeySignatureH\x00\x12\x46\n\x13multi_key_signature\x18\x06 \x01(\x0b\x32\'.aptos.transaction.v1.MultiKeySignatureH\x00\x12\x41\n\x0b\x61\x62straction\x18\x07 \x01(\x0b\x32*.aptos.transaction.v1.AbstractionSignatureH\x00"\x8b\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x13\n\x0fTYPE_SINGLE_KEY\x10\x04\x12\x12\n\x0eTYPE_MULTI_KEY\x10\x05\x12\x14\n\x10TYPE_ABSTRACTION\x10\x06"\x04\x08\x03\x10\x03\x42\x0b\n\tsignature"\xb1\x01\n\x13TransactionSizeInfo\x12\x19\n\x11transaction_bytes\x18\x01 \x01(\r\x12<\n\x0f\x65vent_size_info\x18\x02 \x03(\x0b\x32#.aptos.transaction.v1.EventSizeInfo\x12\x41\n\x12write_op_size_info\x18\x03 \x03(\x0b\x32%.aptos.transaction.v1.WriteOpSizeInfo"<\n\rEventSizeInfo\x12\x16\n\x0etype_tag_bytes\x18\x01 \x01(\r\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\r"9\n\x0fWriteOpSizeInfo\x12\x11\n\tkey_bytes\x18\x01 \x01(\r\x12\x13\n\x0bvalue_bytes\x18\x02 \x01(\r*\xea\x02\n\tMoveTypes\x12\x1a\n\x16MOVE_TYPES_UNSPECIFIED\x10\x00\x12\x13\n\x0fMOVE_TYPES_BOOL\x10\x01\x12\x11\n\rMOVE_TYPES_U8\x10\x02\x12\x12\n\x0eMOVE_TYPES_U16\x10\x0c\x12\x12\n\x0eMOVE_TYPES_U32\x10\r\x12\x12\n\x0eMOVE_TYPES_U64\x10\x03\x12\x13\n\x0fMOVE_TYPES_U128\x10\x04\x12\x13\n\x0fMOVE_TYPES_U256\x10\x0e\x12\x16\n\x12MOVE_TYPES_ADDRESS\x10\x05\x12\x15\n\x11MOVE_TYPES_SIGNER\x10\x06\x12\x15\n\x11MOVE_TYPES_VECTOR\x10\x07\x12\x15\n\x11MOVE_TYPES_STRUCT\x10\x08\x12!\n\x1dMOVE_TYPES_GENERIC_TYPE_PARAM\x10\t\x12\x18\n\x14MOVE_TYPES_REFERENCE\x10\n\x12\x19\n\x15MOVE_TYPES_UNPARSABLE\x10\x0b*\x87\x01\n\x0bMoveAbility\x12\x1c\n\x18MOVE_ABILITY_UNSPECIFIED\x10\x00\x12\x15\n\x11MOVE_ABILITY_COPY\x10\x01\x12\x15\n\x11MOVE_ABILITY_DROP\x10\x02\x12\x16\n\x12MOVE_ABILITY_STORE\x10\x03\x12\x14\n\x10MOVE_ABILITY_KEY\x10\x04\x62\x06proto3' + b'\n&aptos/transaction/v1/transaction.proto\x12\x14\x61ptos.transaction.v1\x1a$aptos/util/timestamp/timestamp.proto"\x9a\x01\n\x05\x42lock\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x12\n\x06height\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x37\n\x0ctransactions\x18\x03 \x03(\x0b\x32!.aptos.transaction.v1.Transaction\x12\x10\n\x08\x63hain_id\x18\x04 \x01(\r"\xda\x07\n\x0bTransaction\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x13\n\x07version\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x33\n\x04info\x18\x03 \x01(\x0b\x32%.aptos.transaction.v1.TransactionInfo\x12\x11\n\x05\x65poch\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x18\n\x0c\x62lock_height\x18\x05 \x01(\x04\x42\x02\x30\x01\x12?\n\x04type\x18\x06 \x01(\x0e\x32\x31.aptos.transaction.v1.Transaction.TransactionType\x12H\n\x0e\x62lock_metadata\x18\x07 \x01(\x0b\x32..aptos.transaction.v1.BlockMetadataTransactionH\x00\x12;\n\x07genesis\x18\x08 \x01(\x0b\x32(.aptos.transaction.v1.GenesisTransactionH\x00\x12L\n\x10state_checkpoint\x18\t \x01(\x0b\x32\x30.aptos.transaction.v1.StateCheckpointTransactionH\x00\x12\x35\n\x04user\x18\n \x01(\x0b\x32%.aptos.transaction.v1.UserTransactionH\x00\x12?\n\tvalidator\x18\x15 \x01(\x0b\x32*.aptos.transaction.v1.ValidatorTransactionH\x00\x12H\n\x0e\x62lock_epilogue\x18\x17 \x01(\x0b\x32..aptos.transaction.v1.BlockEpilogueTransactionH\x00\x12<\n\tsize_info\x18\x16 \x01(\x0b\x32).aptos.transaction.v1.TransactionSizeInfo"\xfd\x01\n\x0fTransactionType\x12 \n\x1cTRANSACTION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18TRANSACTION_TYPE_GENESIS\x10\x01\x12#\n\x1fTRANSACTION_TYPE_BLOCK_METADATA\x10\x02\x12%\n!TRANSACTION_TYPE_STATE_CHECKPOINT\x10\x03\x12\x19\n\x15TRANSACTION_TYPE_USER\x10\x04\x12\x1e\n\x1aTRANSACTION_TYPE_VALIDATOR\x10\x14\x12#\n\x1fTRANSACTION_TYPE_BLOCK_EPILOGUE\x10\x15\x42\n\n\x08txn_data"\xbe\x01\n\x18\x42lockMetadataTransaction\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x05round\x18\x02 \x01(\x04\x42\x02\x30\x01\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x12#\n\x1bprevious_block_votes_bitvec\x18\x04 \x01(\x0c\x12\x10\n\x08proposer\x18\x05 \x01(\t\x12\x1f\n\x17\x66\x61iled_proposer_indices\x18\x06 \x03(\r"r\n\x12GenesisTransaction\x12/\n\x07payload\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x1c\n\x1aStateCheckpointTransaction"\xfa\n\n\x14ValidatorTransaction\x12[\n\x13observed_jwk_update\x18\x01 \x01(\x0b\x32<.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdateH\x00\x12J\n\ndkg_update\x18\x02 \x01(\x0b\x32\x34.aptos.transaction.v1.ValidatorTransaction.DkgUpdateH\x00\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x1a\xc4\x07\n\x11ObservedJwkUpdate\x12s\n\x17quorum_certified_update\x18\x01 \x01(\x0b\x32R.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.QuorumCertifiedUpdate\x1a\x8d\x04\n\x14\x45xportedProviderJWKs\x12\x0e\n\x06issuer\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x04\x12\x63\n\x04jwks\x18\x03 \x03(\x0b\x32U.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK\x1a\xee\x02\n\x03JWK\x12\x7f\n\x0funsupported_jwk\x18\x01 \x01(\x0b\x32\x64.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.UnsupportedJWKH\x00\x12h\n\x03rsa\x18\x02 \x01(\x0b\x32Y.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.RSAH\x00\x1a\x42\n\x03RSA\x12\x0b\n\x03kid\x18\x01 \x01(\t\x12\x0b\n\x03kty\x18\x02 \x01(\t\x12\x0b\n\x03\x61lg\x18\x03 \x01(\t\x12\t\n\x01\x65\x18\x04 \x01(\t\x12\t\n\x01n\x18\x05 \x01(\t\x1a-\n\x0eUnsupportedJWK\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x42\t\n\x07JwkType\x1a\x41\n\x1a\x45xportedAggregateSignature\x12\x16\n\x0esigner_indices\x18\x01 \x03(\x04\x12\x0b\n\x03sig\x18\x02 \x01(\x0c\x1a\xe6\x01\n\x15QuorumCertifiedUpdate\x12\x61\n\x06update\x18\x01 \x01(\x0b\x32Q.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs\x12j\n\tmulti_sig\x18\x02 \x01(\x0b\x32W.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedAggregateSignature\x1a\xa8\x01\n\tDkgUpdate\x12Z\n\x0e\x64kg_transcript\x18\x01 \x01(\x0b\x32\x42.aptos.transaction.v1.ValidatorTransaction.DkgUpdate.DkgTranscript\x1a?\n\rDkgTranscript\x12\r\n\x05\x65poch\x18\x01 \x01(\x04\x12\x0e\n\x06\x61uthor\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x42\x1a\n\x18ValidatorTransactionType"n\n\x18\x42lockEpilogueTransaction\x12?\n\x0e\x62lock_end_info\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.BlockEndInfoH\x00\x88\x01\x01\x42\x11\n\x0f_block_end_info"\x9e\x01\n\x0c\x42lockEndInfo\x12\x1f\n\x17\x62lock_gas_limit_reached\x18\x01 \x01(\x08\x12"\n\x1a\x62lock_output_limit_reached\x18\x02 \x01(\x08\x12\'\n\x1f\x62lock_effective_block_gas_units\x18\x03 \x01(\x04\x12 \n\x18\x62lock_approx_output_size\x18\x04 \x01(\x04"}\n\x0fUserTransaction\x12=\n\x07request\x18\x01 \x01(\x0b\x32,.aptos.transaction.v1.UserTransactionRequest\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x9f\x01\n\x05\x45vent\x12+\n\x03key\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.EventKey\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12,\n\x04type\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x10\n\x08type_str\x18\x05 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t"\xa1\x02\n\x0fTransactionInfo\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x19\n\x11state_change_hash\x18\x02 \x01(\x0c\x12\x17\n\x0f\x65vent_root_hash\x18\x03 \x01(\x0c\x12"\n\x15state_checkpoint_hash\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x08gas_used\x18\x05 \x01(\x04\x42\x02\x30\x01\x12\x0f\n\x07success\x18\x06 \x01(\x08\x12\x11\n\tvm_status\x18\x07 \x01(\t\x12\x1d\n\x15\x61\x63\x63umulator_root_hash\x18\x08 \x01(\x0c\x12\x35\n\x07\x63hanges\x18\t \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChangeB\x18\n\x16_state_checkpoint_hash"@\n\x08\x45ventKey\x12\x1b\n\x0f\x63reation_number\x18\x01 \x01(\x04\x42\x02\x30\x01\x12\x17\n\x0f\x61\x63\x63ount_address\x18\x02 \x01(\t"\xb0\x02\n\x16UserTransactionRequest\x12\x0e\n\x06sender\x18\x01 \x01(\t\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0emax_gas_amount\x18\x03 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0egas_unit_price\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x42\n\x19\x65xpiration_timestamp_secs\x18\x05 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x39\n\x07payload\x18\x06 \x01(\x0b\x32(.aptos.transaction.v1.TransactionPayload\x12\x32\n\tsignature\x18\x07 \x01(\x0b\x32\x1f.aptos.transaction.v1.Signature"\xda\x02\n\x08WriteSet\x12\x43\n\x0ewrite_set_type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.WriteSet.WriteSetType\x12@\n\x10script_write_set\x18\x02 \x01(\x0b\x32$.aptos.transaction.v1.ScriptWriteSetH\x00\x12@\n\x10\x64irect_write_set\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DirectWriteSetH\x00"x\n\x0cWriteSetType\x12\x1e\n\x1aWRITE_SET_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1fWRITE_SET_TYPE_SCRIPT_WRITE_SET\x10\x01\x12#\n\x1fWRITE_SET_TYPE_DIRECT_WRITE_SET\x10\x02\x42\x0b\n\twrite_set"Y\n\x0eScriptWriteSet\x12\x12\n\nexecute_as\x18\x01 \x01(\t\x12\x33\n\x06script\x18\x02 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayload"}\n\x0e\x44irectWriteSet\x12>\n\x10write_set_change\x18\x01 \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChange\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x89\x05\n\x0eWriteSetChange\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).aptos.transaction.v1.WriteSetChange.Type\x12;\n\rdelete_module\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.DeleteModuleH\x00\x12?\n\x0f\x64\x65lete_resource\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DeleteResourceH\x00\x12\x42\n\x11\x64\x65lete_table_item\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableItemH\x00\x12\x39\n\x0cwrite_module\x18\x05 \x01(\x0b\x32!.aptos.transaction.v1.WriteModuleH\x00\x12=\n\x0ewrite_resource\x18\x06 \x01(\x0b\x32#.aptos.transaction.v1.WriteResourceH\x00\x12@\n\x10write_table_item\x18\x07 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableItemH\x00"\xb5\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12TYPE_DELETE_MODULE\x10\x01\x12\x18\n\x14TYPE_DELETE_RESOURCE\x10\x02\x12\x1a\n\x16TYPE_DELETE_TABLE_ITEM\x10\x03\x12\x15\n\x11TYPE_WRITE_MODULE\x10\x04\x12\x17\n\x13TYPE_WRITE_RESOURCE\x10\x05\x12\x19\n\x15TYPE_WRITE_TABLE_ITEM\x10\x06\x42\x08\n\x06\x63hange"k\n\x0c\x44\x65leteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x32\n\x06module\x18\x03 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId"~\n\x0e\x44\x65leteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t"{\n\x0f\x44\x65leteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x33\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableData"0\n\x0f\x44\x65leteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t"n\n\x0bWriteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x36\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32(.aptos.transaction.v1.MoveModuleBytecode"\x8b\x01\n\rWriteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\t"R\n\x0eWriteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\x12\x12\n\nvalue_type\x18\x04 \x01(\t"y\n\x0eWriteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x32\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableData"\xdc\x04\n\x12TransactionPayload\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.aptos.transaction.v1.TransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00\x12=\n\x0escript_payload\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayloadH\x00\x12\x42\n\x11write_set_payload\x18\x05 \x01(\x0b\x32%.aptos.transaction.v1.WriteSetPayloadH\x00\x12\x41\n\x10multisig_payload\x18\x06 \x01(\x0b\x32%.aptos.transaction.v1.MultisigPayloadH\x00\x12>\n\x0f\x65xtra_config_v1\x18\x07 \x01(\x0b\x32#.aptos.transaction.v1.ExtraConfigV1H\x01"\x93\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x12\x17\n\x13TYPE_SCRIPT_PAYLOAD\x10\x02\x12\x1a\n\x16TYPE_WRITE_SET_PAYLOAD\x10\x04\x12\x19\n\x15TYPE_MULTISIG_PAYLOAD\x10\x05"\x04\x08\x03\x10\x03\x42\t\n\x07payloadB\x0e\n\x0c\x65xtra_configJ\x04\x08\x04\x10\x05"\x85\x01\n\rExtraConfigV1\x12\x1d\n\x10multisig_address\x18\x01 \x01(\tH\x00\x88\x01\x01\x12$\n\x17replay_protection_nonce\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x13\n\x11_multisig_addressB\x1a\n\x18_replay_protection_nonce"\xb9\x01\n\x14\x45ntryFunctionPayload\x12\x37\n\x08\x66unction\x18\x01 \x01(\x0b\x32%.aptos.transaction.v1.EntryFunctionId\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t\x12\x1d\n\x15\x65ntry_function_id_str\x18\x04 \x01(\t"W\n\x12MoveScriptBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12/\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.MoveFunction"\x92\x01\n\rScriptPayload\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0b\x32(.aptos.transaction.v1.MoveScriptBytecode\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t"\x97\x01\n\x0fMultisigPayload\x12\x18\n\x10multisig_address\x18\x01 \x01(\t\x12R\n\x13transaction_payload\x18\x02 \x01(\x0b\x32\x30.aptos.transaction.v1.MultisigTransactionPayloadH\x00\x88\x01\x01\x42\x16\n\x14_transaction_payload"\xf9\x01\n\x1aMultisigTransactionPayload\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.aptos.transaction.v1.MultisigTransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00"=\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x42\t\n\x07payload"U\n\x12MoveModuleBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12-\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32 .aptos.transaction.v1.MoveModule"\xd2\x01\n\nMoveModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x33\n\x07\x66riends\x18\x03 \x03(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12=\n\x11\x65xposed_functions\x18\x04 \x03(\x0b\x32".aptos.transaction.v1.MoveFunction\x12\x31\n\x07structs\x18\x05 \x03(\x0b\x32 .aptos.transaction.v1.MoveStruct"\x92\x03\n\x0cMoveFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x41\n\nvisibility\x18\x02 \x01(\x0e\x32-.aptos.transaction.v1.MoveFunction.Visibility\x12\x10\n\x08is_entry\x18\x03 \x01(\x08\x12O\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x32.aptos.transaction.v1.MoveFunctionGenericTypeParam\x12.\n\x06params\x18\x05 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12.\n\x06return\x18\x06 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"n\n\nVisibility\x12\x1a\n\x16VISIBILITY_UNSPECIFIED\x10\x00\x12\x16\n\x12VISIBILITY_PRIVATE\x10\x01\x12\x15\n\x11VISIBILITY_PUBLIC\x10\x02\x12\x15\n\x11VISIBILITY_FRIEND\x10\x03"\x8c\x02\n\nMoveStruct\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tis_native\x18\x02 \x01(\x08\x12\x10\n\x08is_event\x18\x06 \x01(\x08\x12\x0f\n\x07is_enum\x18\x07 \x01(\x08\x12\x34\n\tabilities\x18\x03 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12M\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x30.aptos.transaction.v1.MoveStructGenericTypeParam\x12\x35\n\x06\x66ields\x18\x05 \x03(\x0b\x32%.aptos.transaction.v1.MoveStructField"h\n\x1aMoveStructGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12\x12\n\nis_phantom\x18\x02 \x01(\x08"M\n\x0fMoveStructField\x12\x0c\n\x04name\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType"V\n\x1cMoveFunctionGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility"\xf8\x02\n\x08MoveType\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.aptos.transaction.v1.MoveTypes\x12\x30\n\x06vector\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeH\x00\x12\x35\n\x06struct\x18\x04 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTagH\x00\x12"\n\x18generic_type_param_index\x18\x05 \x01(\rH\x00\x12\x41\n\treference\x18\x06 \x01(\x0b\x32,.aptos.transaction.v1.MoveType.ReferenceTypeH\x00\x12\x14\n\nunparsable\x18\x07 \x01(\tH\x00\x1aL\n\rReferenceType\x12\x0f\n\x07mutable\x18\x01 \x01(\x08\x12*\n\x02to\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeB\t\n\x07\x63ontent"D\n\x0fWriteSetPayload\x12\x31\n\twrite_set\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet"S\n\x0f\x45ntryFunctionId\x12\x32\n\x06module\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12\x0c\n\x04name\x18\x02 \x01(\t"-\n\x0cMoveModuleId\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"{\n\rMoveStructTag\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12;\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"\x9b\x04\n\tSignature\x12\x32\n\x04type\x18\x01 \x01(\x0e\x32$.aptos.transaction.v1.Signature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12@\n\x0bmulti_agent\x18\x04 \x01(\x0b\x32).aptos.transaction.v1.MultiAgentSignatureH\x00\x12<\n\tfee_payer\x18\x05 \x01(\x0b\x32\'.aptos.transaction.v1.FeePayerSignatureH\x00\x12;\n\rsingle_sender\x18\x07 \x01(\x0b\x32".aptos.transaction.v1.SingleSenderH\x00"\x8e\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x14\n\x10TYPE_MULTI_AGENT\x10\x03\x12\x12\n\x0eTYPE_FEE_PAYER\x10\x04\x12\x16\n\x12TYPE_SINGLE_SENDER\x10\x06"\x04\x08\x05\x10\x05\x42\x0b\n\tsignature"9\n\x10\x45\x64\x32\x35\x35\x31\x39Signature\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c"o\n\x15MultiEd25519Signature\x12\x13\n\x0bpublic_keys\x18\x01 \x03(\x0c\x12\x12\n\nsignatures\x18\x02 \x03(\x0c\x12\x11\n\tthreshold\x18\x03 \x01(\r\x12\x1a\n\x12public_key_indices\x18\x04 \x03(\r"\xb4\x01\n\x13MultiAgentSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature"\x8f\x02\n\x11\x46\x65\x65PayerSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12\x19\n\x11\x66\x65\x65_payer_address\x18\x04 \x01(\t\x12@\n\x10\x66\x65\x65_payer_signer\x18\x05 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xec\x01\n\x0c\x41nyPublicKey\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnyPublicKey.Type\x12\x12\n\npublic_key\x18\x02 \x01(\x0c"\x90\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x18\n\x14TYPE_SECP256R1_ECDSA\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x12\x1a\n\x16TYPE_FEDERATED_KEYLESS\x10\x05"\xb9\x03\n\x0c\x41nySignature\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnySignature.Type\x12\x15\n\tsignature\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x30\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x03 \x01(\x0b\x32\x1d.aptos.transaction.v1.Ed25519H\x00\x12?\n\x0fsecp256k1_ecdsa\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.Secp256k1EcdsaH\x00\x12\x32\n\x08webauthn\x18\x05 \x01(\x0b\x32\x1e.aptos.transaction.v1.WebAuthnH\x00\x12\x30\n\x07keyless\x18\x06 \x01(\x0b\x32\x1d.aptos.transaction.v1.KeylessH\x00"m\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x11\n\rTYPE_WEBAUTHN\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x42\x13\n\x11signature_variant"\x1c\n\x07\x45\x64\x32\x35\x35\x31\x39\x12\x11\n\tsignature\x18\x01 \x01(\x0c"#\n\x0eSecp256k1Ecdsa\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1d\n\x08WebAuthn\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1c\n\x07Keyless\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x83\x01\n\x12SingleKeySignature\x12\x36\n\npublic_key\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"X\n\x10IndexedSignature\x12\r\n\x05index\x18\x01 \x01(\r\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"\xa5\x01\n\x11MultiKeySignature\x12\x37\n\x0bpublic_keys\x18\x01 \x03(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12:\n\nsignatures\x18\x02 \x03(\x0b\x32&.aptos.transaction.v1.IndexedSignature\x12\x1b\n\x13signatures_required\x18\x03 \x01(\r"=\n\x11\x41\x62stractSignature\x12\x15\n\rfunction_info\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c"F\n\x0cSingleSender\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xbb\x04\n\x10\x41\x63\x63ountSignature\x12\x39\n\x04type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.AccountSignature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12H\n\x14single_key_signature\x18\x05 \x01(\x0b\x32(.aptos.transaction.v1.SingleKeySignatureH\x00\x12\x46\n\x13multi_key_signature\x18\x06 \x01(\x0b\x32\'.aptos.transaction.v1.MultiKeySignatureH\x00\x12>\n\x0b\x61\x62straction\x18\x07 \x01(\x0b\x32\'.aptos.transaction.v1.AbstractSignatureH\x00"\x8b\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x13\n\x0fTYPE_SINGLE_KEY\x10\x04\x12\x12\n\x0eTYPE_MULTI_KEY\x10\x05\x12\x14\n\x10TYPE_ABSTRACTION\x10\x06"\x04\x08\x03\x10\x03\x42\x0b\n\tsignature"\xb1\x01\n\x13TransactionSizeInfo\x12\x19\n\x11transaction_bytes\x18\x01 \x01(\r\x12<\n\x0f\x65vent_size_info\x18\x02 \x03(\x0b\x32#.aptos.transaction.v1.EventSizeInfo\x12\x41\n\x12write_op_size_info\x18\x03 \x03(\x0b\x32%.aptos.transaction.v1.WriteOpSizeInfo"<\n\rEventSizeInfo\x12\x16\n\x0etype_tag_bytes\x18\x01 \x01(\r\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\r"9\n\x0fWriteOpSizeInfo\x12\x11\n\tkey_bytes\x18\x01 \x01(\r\x12\x13\n\x0bvalue_bytes\x18\x02 \x01(\r*\xea\x02\n\tMoveTypes\x12\x1a\n\x16MOVE_TYPES_UNSPECIFIED\x10\x00\x12\x13\n\x0fMOVE_TYPES_BOOL\x10\x01\x12\x11\n\rMOVE_TYPES_U8\x10\x02\x12\x12\n\x0eMOVE_TYPES_U16\x10\x0c\x12\x12\n\x0eMOVE_TYPES_U32\x10\r\x12\x12\n\x0eMOVE_TYPES_U64\x10\x03\x12\x13\n\x0fMOVE_TYPES_U128\x10\x04\x12\x13\n\x0fMOVE_TYPES_U256\x10\x0e\x12\x16\n\x12MOVE_TYPES_ADDRESS\x10\x05\x12\x15\n\x11MOVE_TYPES_SIGNER\x10\x06\x12\x15\n\x11MOVE_TYPES_VECTOR\x10\x07\x12\x15\n\x11MOVE_TYPES_STRUCT\x10\x08\x12!\n\x1dMOVE_TYPES_GENERIC_TYPE_PARAM\x10\t\x12\x18\n\x14MOVE_TYPES_REFERENCE\x10\n\x12\x19\n\x15MOVE_TYPES_UNPARSABLE\x10\x0b*\x87\x01\n\x0bMoveAbility\x12\x1c\n\x18MOVE_ABILITY_UNSPECIFIED\x10\x00\x12\x15\n\x11MOVE_ABILITY_COPY\x10\x01\x12\x15\n\x11MOVE_ABILITY_DROP\x10\x02\x12\x16\n\x12MOVE_ABILITY_STORE\x10\x03\x12\x14\n\x10MOVE_ABILITY_KEY\x10\x04\x62\x06proto3' ) _globals = globals() @@ -57,10 +57,10 @@ ]._serialized_options = b"0\001" _ANYSIGNATURE.fields_by_name["signature"]._options = None _ANYSIGNATURE.fields_by_name["signature"]._serialized_options = b"\030\001" - _globals["_MOVETYPES"]._serialized_start = 13215 - _globals["_MOVETYPES"]._serialized_end = 13577 - _globals["_MOVEABILITY"]._serialized_start = 13580 - _globals["_MOVEABILITY"]._serialized_end = 13715 + _globals["_MOVETYPES"]._serialized_start = 13226 + _globals["_MOVETYPES"]._serialized_end = 13588 + _globals["_MOVEABILITY"]._serialized_start = 13591 + _globals["_MOVEABILITY"]._serialized_end = 13726 _globals["_BLOCK"]._serialized_start = 103 _globals["_BLOCK"]._serialized_end = 257 _globals["_TRANSACTION"]._serialized_start = 260 @@ -186,71 +186,71 @@ _globals["_MOVEFUNCTION_VISIBILITY"]._serialized_start = 8479 _globals["_MOVEFUNCTION_VISIBILITY"]._serialized_end = 8589 _globals["_MOVESTRUCT"]._serialized_start = 8592 - _globals["_MOVESTRUCT"]._serialized_end = 8843 - _globals["_MOVESTRUCTGENERICTYPEPARAM"]._serialized_start = 8845 - _globals["_MOVESTRUCTGENERICTYPEPARAM"]._serialized_end = 8949 - _globals["_MOVESTRUCTFIELD"]._serialized_start = 8951 - _globals["_MOVESTRUCTFIELD"]._serialized_end = 9028 - _globals["_MOVEFUNCTIONGENERICTYPEPARAM"]._serialized_start = 9030 - _globals["_MOVEFUNCTIONGENERICTYPEPARAM"]._serialized_end = 9116 - _globals["_MOVETYPE"]._serialized_start = 9119 - _globals["_MOVETYPE"]._serialized_end = 9495 - _globals["_MOVETYPE_REFERENCETYPE"]._serialized_start = 9408 - _globals["_MOVETYPE_REFERENCETYPE"]._serialized_end = 9484 - _globals["_WRITESETPAYLOAD"]._serialized_start = 9497 - _globals["_WRITESETPAYLOAD"]._serialized_end = 9565 - _globals["_ENTRYFUNCTIONID"]._serialized_start = 9567 - _globals["_ENTRYFUNCTIONID"]._serialized_end = 9650 - _globals["_MOVEMODULEID"]._serialized_start = 9652 - _globals["_MOVEMODULEID"]._serialized_end = 9697 - _globals["_MOVESTRUCTTAG"]._serialized_start = 9699 - _globals["_MOVESTRUCTTAG"]._serialized_end = 9822 - _globals["_SIGNATURE"]._serialized_start = 9825 - _globals["_SIGNATURE"]._serialized_end = 10364 - _globals["_SIGNATURE_TYPE"]._serialized_start = 10209 - _globals["_SIGNATURE_TYPE"]._serialized_end = 10351 - _globals["_ED25519SIGNATURE"]._serialized_start = 10366 - _globals["_ED25519SIGNATURE"]._serialized_end = 10423 - _globals["_MULTIED25519SIGNATURE"]._serialized_start = 10425 - _globals["_MULTIED25519SIGNATURE"]._serialized_end = 10536 - _globals["_MULTIAGENTSIGNATURE"]._serialized_start = 10539 - _globals["_MULTIAGENTSIGNATURE"]._serialized_end = 10719 - _globals["_FEEPAYERSIGNATURE"]._serialized_start = 10722 - _globals["_FEEPAYERSIGNATURE"]._serialized_end = 10993 - _globals["_ANYPUBLICKEY"]._serialized_start = 10996 - _globals["_ANYPUBLICKEY"]._serialized_end = 11232 - _globals["_ANYPUBLICKEY_TYPE"]._serialized_start = 11088 - _globals["_ANYPUBLICKEY_TYPE"]._serialized_end = 11232 - _globals["_ANYSIGNATURE"]._serialized_start = 11235 - _globals["_ANYSIGNATURE"]._serialized_end = 11676 - _globals["_ANYSIGNATURE_TYPE"]._serialized_start = 11546 - _globals["_ANYSIGNATURE_TYPE"]._serialized_end = 11655 - _globals["_ED25519"]._serialized_start = 11678 - _globals["_ED25519"]._serialized_end = 11706 - _globals["_SECP256K1ECDSA"]._serialized_start = 11708 - _globals["_SECP256K1ECDSA"]._serialized_end = 11743 - _globals["_WEBAUTHN"]._serialized_start = 11745 - _globals["_WEBAUTHN"]._serialized_end = 11774 - _globals["_KEYLESS"]._serialized_start = 11776 - _globals["_KEYLESS"]._serialized_end = 11804 - _globals["_SINGLEKEYSIGNATURE"]._serialized_start = 11807 - _globals["_SINGLEKEYSIGNATURE"]._serialized_end = 11938 - _globals["_INDEXEDSIGNATURE"]._serialized_start = 11940 - _globals["_INDEXEDSIGNATURE"]._serialized_end = 12028 - _globals["_MULTIKEYSIGNATURE"]._serialized_start = 12031 - _globals["_MULTIKEYSIGNATURE"]._serialized_end = 12196 - _globals["_ABSTRACTIONSIGNATURE"]._serialized_start = 12198 - _globals["_ABSTRACTIONSIGNATURE"]._serialized_end = 12262 - _globals["_SINGLESENDER"]._serialized_start = 12264 - _globals["_SINGLESENDER"]._serialized_end = 12334 - _globals["_ACCOUNTSIGNATURE"]._serialized_start = 12337 - _globals["_ACCOUNTSIGNATURE"]._serialized_end = 12911 - _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_start = 12759 - _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_end = 12898 - _globals["_TRANSACTIONSIZEINFO"]._serialized_start = 12914 - _globals["_TRANSACTIONSIZEINFO"]._serialized_end = 13091 - _globals["_EVENTSIZEINFO"]._serialized_start = 13093 - _globals["_EVENTSIZEINFO"]._serialized_end = 13153 - _globals["_WRITEOPSIZEINFO"]._serialized_start = 13155 - _globals["_WRITEOPSIZEINFO"]._serialized_end = 13212 + _globals["_MOVESTRUCT"]._serialized_end = 8860 + _globals["_MOVESTRUCTGENERICTYPEPARAM"]._serialized_start = 8862 + _globals["_MOVESTRUCTGENERICTYPEPARAM"]._serialized_end = 8966 + _globals["_MOVESTRUCTFIELD"]._serialized_start = 8968 + _globals["_MOVESTRUCTFIELD"]._serialized_end = 9045 + _globals["_MOVEFUNCTIONGENERICTYPEPARAM"]._serialized_start = 9047 + _globals["_MOVEFUNCTIONGENERICTYPEPARAM"]._serialized_end = 9133 + _globals["_MOVETYPE"]._serialized_start = 9136 + _globals["_MOVETYPE"]._serialized_end = 9512 + _globals["_MOVETYPE_REFERENCETYPE"]._serialized_start = 9425 + _globals["_MOVETYPE_REFERENCETYPE"]._serialized_end = 9501 + _globals["_WRITESETPAYLOAD"]._serialized_start = 9514 + _globals["_WRITESETPAYLOAD"]._serialized_end = 9582 + _globals["_ENTRYFUNCTIONID"]._serialized_start = 9584 + _globals["_ENTRYFUNCTIONID"]._serialized_end = 9667 + _globals["_MOVEMODULEID"]._serialized_start = 9669 + _globals["_MOVEMODULEID"]._serialized_end = 9714 + _globals["_MOVESTRUCTTAG"]._serialized_start = 9716 + _globals["_MOVESTRUCTTAG"]._serialized_end = 9839 + _globals["_SIGNATURE"]._serialized_start = 9842 + _globals["_SIGNATURE"]._serialized_end = 10381 + _globals["_SIGNATURE_TYPE"]._serialized_start = 10226 + _globals["_SIGNATURE_TYPE"]._serialized_end = 10368 + _globals["_ED25519SIGNATURE"]._serialized_start = 10383 + _globals["_ED25519SIGNATURE"]._serialized_end = 10440 + _globals["_MULTIED25519SIGNATURE"]._serialized_start = 10442 + _globals["_MULTIED25519SIGNATURE"]._serialized_end = 10553 + _globals["_MULTIAGENTSIGNATURE"]._serialized_start = 10556 + _globals["_MULTIAGENTSIGNATURE"]._serialized_end = 10736 + _globals["_FEEPAYERSIGNATURE"]._serialized_start = 10739 + _globals["_FEEPAYERSIGNATURE"]._serialized_end = 11010 + _globals["_ANYPUBLICKEY"]._serialized_start = 11013 + _globals["_ANYPUBLICKEY"]._serialized_end = 11249 + _globals["_ANYPUBLICKEY_TYPE"]._serialized_start = 11105 + _globals["_ANYPUBLICKEY_TYPE"]._serialized_end = 11249 + _globals["_ANYSIGNATURE"]._serialized_start = 11252 + _globals["_ANYSIGNATURE"]._serialized_end = 11693 + _globals["_ANYSIGNATURE_TYPE"]._serialized_start = 11563 + _globals["_ANYSIGNATURE_TYPE"]._serialized_end = 11672 + _globals["_ED25519"]._serialized_start = 11695 + _globals["_ED25519"]._serialized_end = 11723 + _globals["_SECP256K1ECDSA"]._serialized_start = 11725 + _globals["_SECP256K1ECDSA"]._serialized_end = 11760 + _globals["_WEBAUTHN"]._serialized_start = 11762 + _globals["_WEBAUTHN"]._serialized_end = 11791 + _globals["_KEYLESS"]._serialized_start = 11793 + _globals["_KEYLESS"]._serialized_end = 11821 + _globals["_SINGLEKEYSIGNATURE"]._serialized_start = 11824 + _globals["_SINGLEKEYSIGNATURE"]._serialized_end = 11955 + _globals["_INDEXEDSIGNATURE"]._serialized_start = 11957 + _globals["_INDEXEDSIGNATURE"]._serialized_end = 12045 + _globals["_MULTIKEYSIGNATURE"]._serialized_start = 12048 + _globals["_MULTIKEYSIGNATURE"]._serialized_end = 12213 + _globals["_ABSTRACTSIGNATURE"]._serialized_start = 12215 + _globals["_ABSTRACTSIGNATURE"]._serialized_end = 12276 + _globals["_SINGLESENDER"]._serialized_start = 12278 + _globals["_SINGLESENDER"]._serialized_end = 12348 + _globals["_ACCOUNTSIGNATURE"]._serialized_start = 12351 + _globals["_ACCOUNTSIGNATURE"]._serialized_end = 12922 + _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_start = 12770 + _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_end = 12909 + _globals["_TRANSACTIONSIZEINFO"]._serialized_start = 12925 + _globals["_TRANSACTIONSIZEINFO"]._serialized_end = 13102 + _globals["_EVENTSIZEINFO"]._serialized_start = 13104 + _globals["_EVENTSIZEINFO"]._serialized_end = 13164 + _globals["_WRITEOPSIZEINFO"]._serialized_start = 13166 + _globals["_WRITEOPSIZEINFO"]._serialized_end = 13223 # @@protoc_insertion_point(module_scope) diff --git a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi index 987641e7953..688a01541b0 100644 --- a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi +++ b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi @@ -969,6 +969,7 @@ class MoveStruct(_message.Message): "name", "is_native", "is_event", + "is_enum", "abilities", "generic_type_params", "fields", @@ -976,12 +977,14 @@ class MoveStruct(_message.Message): NAME_FIELD_NUMBER: _ClassVar[int] IS_NATIVE_FIELD_NUMBER: _ClassVar[int] IS_EVENT_FIELD_NUMBER: _ClassVar[int] + IS_ENUM_FIELD_NUMBER: _ClassVar[int] ABILITIES_FIELD_NUMBER: _ClassVar[int] GENERIC_TYPE_PARAMS_FIELD_NUMBER: _ClassVar[int] FIELDS_FIELD_NUMBER: _ClassVar[int] name: str is_native: bool is_event: bool + is_enum: bool abilities: _containers.RepeatedScalarFieldContainer[MoveAbility] generic_type_params: _containers.RepeatedCompositeFieldContainer[ MoveStructGenericTypeParam @@ -992,6 +995,7 @@ class MoveStruct(_message.Message): name: _Optional[str] = ..., is_native: bool = ..., is_event: bool = ..., + is_enum: bool = ..., abilities: _Optional[_Iterable[_Union[MoveAbility, str]]] = ..., generic_type_params: _Optional[ _Iterable[_Union[MoveStructGenericTypeParam, _Mapping]] @@ -1374,7 +1378,7 @@ class MultiKeySignature(_message.Message): signatures_required: _Optional[int] = ..., ) -> None: ... -class AbstractionSignature(_message.Message): +class AbstractSignature(_message.Message): __slots__ = ["function_info", "signature"] FUNCTION_INFO_FIELD_NUMBER: _ClassVar[int] SIGNATURE_FIELD_NUMBER: _ClassVar[int] @@ -1427,7 +1431,7 @@ class AccountSignature(_message.Message): multi_ed25519: MultiEd25519Signature single_key_signature: SingleKeySignature multi_key_signature: MultiKeySignature - abstraction: AbstractionSignature + abstraction: AbstractSignature def __init__( self, type: _Optional[_Union[AccountSignature.Type, str]] = ..., @@ -1435,7 +1439,7 @@ class AccountSignature(_message.Message): multi_ed25519: _Optional[_Union[MultiEd25519Signature, _Mapping]] = ..., single_key_signature: _Optional[_Union[SingleKeySignature, _Mapping]] = ..., multi_key_signature: _Optional[_Union[MultiKeySignature, _Mapping]] = ..., - abstraction: _Optional[_Union[AbstractionSignature, _Mapping]] = ..., + abstraction: _Optional[_Union[AbstractSignature, _Mapping]] = ..., ) -> None: ... class TransactionSizeInfo(_message.Message): diff --git a/protos/python/poetry.lock b/protos/python/poetry.lock index 46468939085..fc5c3f0ebfe 100644 --- a/protos/python/poetry.lock +++ b/protos/python/poetry.lock @@ -1,12 +1,12 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "black" version = "23.10.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "black-23.10.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"}, {file = "black-23.10.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd"}, @@ -47,9 +47,9 @@ uvloop = ["uvloop (>=0.15.2)"] name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -62,9 +62,10 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "platform_system == \"Windows\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -74,9 +75,9 @@ files = [ name = "grpcio" version = "1.59.0" description = "HTTP/2-based RPC framework" -category = "main" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "grpcio-1.59.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:225e5fa61c35eeaebb4e7491cd2d768cd8eb6ed00f2664fa83a58f29418b39fd"}, {file = "grpcio-1.59.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b95ec8ecc4f703f5caaa8d96e93e40c7f589bad299a2617bdb8becbcce525539"}, @@ -141,9 +142,9 @@ protobuf = ["grpcio-tools (>=1.59.0)"] name = "grpcio-tools" version = "1.59.0" description = "Protobuf code generator for gRPC" -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "grpcio-tools-1.59.0.tar.gz", hash = "sha256:aa4018f2d8662ac4d9830445d3d253a11b3e096e8afe20865547137aa1160e93"}, {file = "grpcio_tools-1.59.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:882b809b42b5464bee55288f4e60837297f9618e53e69ae3eea6d61b05ce48fa"}, @@ -210,9 +211,9 @@ setuptools = "*" name = "grpclib" version = "0.4.6" description = "Pure-Python gRPC implementation for asyncio" -category = "main" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "grpclib-0.4.6.tar.gz", hash = "sha256:595d05236ca8b8f8e433f5bf6095e6354c1d8777d003ddaf5288efa9611e3fd6"}, ] @@ -228,9 +229,9 @@ protobuf = ["protobuf (>=3.20.0)"] name = "h2" version = "4.1.0" description = "HTTP/2 State-Machine based protocol implementation" -category = "main" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, @@ -244,9 +245,9 @@ hyperframe = ">=6.0,<7" name = "hpack" version = "4.0.0" description = "Pure-Python HPACK header compression" -category = "main" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, @@ -256,9 +257,9 @@ files = [ name = "hyperframe" version = "6.0.1" description = "HTTP/2 framing layer for Python" -category = "main" optional = false python-versions = ">=3.6.1" +groups = ["main"] files = [ {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, @@ -268,9 +269,9 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, @@ -286,9 +287,9 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "multidict" version = "6.0.4" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, @@ -370,9 +371,9 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -382,9 +383,9 @@ files = [ name = "packaging" version = "23.2" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, @@ -394,9 +395,9 @@ files = [ name = "pastel" version = "0.2.1" description = "Bring colors to your terminal." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["dev"] files = [ {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, @@ -406,9 +407,9 @@ files = [ name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, @@ -418,9 +419,9 @@ files = [ name = "platformdirs" version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, @@ -434,9 +435,9 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "poethepoet" version = "0.22.1" description = "A task runner that works well with poetry." -category = "dev" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "poethepoet-0.22.1-py3-none-any.whl", hash = "sha256:1da4cd00d3b2c44b811c91616a744cf71094a26a299ea9956025162d34eef1a5"}, {file = "poethepoet-0.22.1.tar.gz", hash = "sha256:e758bcac731fa9ac0b812389589541e32b825c4a1894e16fa90aeb1946ba2823"}, @@ -453,9 +454,9 @@ poetry-plugin = ["poetry (>=1.0,<2.0)"] name = "protobuf" version = "4.24.4" description = "" -category = "main" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "protobuf-4.24.4-cp310-abi3-win32.whl", hash = "sha256:ec9912d5cb6714a5710e28e592ee1093d68c5ebfeda61983b3f40331da0b1ebb"}, {file = "protobuf-4.24.4-cp310-abi3-win_amd64.whl", hash = "sha256:1badab72aa8a3a2b812eacfede5020472e16c6b2212d737cefd685884c191085"}, @@ -476,9 +477,9 @@ files = [ name = "setuptools" version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, @@ -486,16 +487,16 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov ; platform_python_implementation != \"PyPy\"", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-ruff ; sys_platform != \"cygwin\"", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -505,15 +506,16 @@ files = [ name = "typing-extensions" version = "4.8.0" description = "Backported and Experimental Type Hints for Python 3.8+" -category = "dev" optional = false python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [metadata] -lock-version = "2.0" -python-versions = "^3.9" -content-hash = "5d6ccbd9b0e9c3c971f06b3893e77d61d8f97665d7e9b10d6e39c828c237e952" +lock-version = "2.1" +python-versions = ">=3.9,<3.12" +content-hash = "2c08443bb28a2402ed1978c27dd0b64eeb160377fb627cdbac8e425b76739283" diff --git a/protos/python/pyproject.toml b/protos/python/pyproject.toml index 2faea9a7c7b..399077b8ced 100644 --- a/protos/python/pyproject.toml +++ b/protos/python/pyproject.toml @@ -14,7 +14,7 @@ packages = [{include = "aptos_protos"}] generate = "./generate.sh" [tool.poetry.dependencies] -python = "^3.9" +python = ">=3.9,<3.12" grpcio = "^1.57.0" protobuf = "^4.24.2" grpclib = "^0.4.5" diff --git a/protos/rust/Cargo.toml b/protos/rust/Cargo.toml index 3c261271bac..2f25603ddf6 100644 --- a/protos/rust/Cargo.toml +++ b/protos/rust/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/aptos-labs/aptos-core" homepage = "https://aptoslabs.com" license = "Apache-2.0" publish = true -edition = "2021" +edition = { workspace = true } [dependencies] pbjson = { workspace = true } diff --git a/protos/rust/src/pb/aptos.indexer.v1.tonic.rs b/protos/rust/src/pb/aptos.indexer.v1.tonic.rs index 4e0c6ea8040..7c1140ba61e 100644 --- a/protos/rust/src/pb/aptos.indexer.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.indexer.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod raw_data_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod raw_data_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod raw_data_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { RawDataClient::new(InterceptedService::new(inner, interceptor)) } @@ -107,7 +101,8 @@ pub mod raw_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -124,22 +119,16 @@ pub mod raw_data_client { } /// Generated server implementations. pub mod raw_data_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with RawDataServer. #[async_trait] - pub trait RawData: std::marker::Send + std::marker::Sync + 'static { + pub trait RawData: Send + Sync + 'static { /// Server streaming response type for the GetTransactions method. type GetTransactionsStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result, > - + std::marker::Send + + Send + 'static; /** Get transactions batch without any filtering from starting version and end if transaction count is present. */ @@ -153,14 +142,14 @@ pub mod raw_data_server { } /// #[derive(Debug)] - pub struct RawDataServer { + pub struct RawDataServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl RawDataServer { + impl RawDataServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -214,8 +203,8 @@ pub mod raw_data_server { impl tonic::codegen::Service> for RawDataServer where T: RawData, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -277,25 +266,23 @@ pub mod raw_data_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for RawDataServer { + impl Clone for RawDataServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -307,21 +294,13 @@ pub mod raw_data_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.RawData"; - impl tonic::server::NamedService for RawDataServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for RawDataServer { + const NAME: &'static str = "aptos.indexer.v1.RawData"; } } /// Generated client implementations. pub mod grpc_manager_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -344,8 +323,8 @@ pub mod grpc_manager_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -370,7 +349,7 @@ pub mod grpc_manager_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { GrpcManagerClient::new(InterceptedService::new(inner, interceptor)) } @@ -417,7 +396,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -442,7 +422,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -469,7 +450,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -491,17 +473,11 @@ pub mod grpc_manager_client { } /// Generated server implementations. pub mod grpc_manager_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with GrpcManagerServer. #[async_trait] - pub trait GrpcManager: std::marker::Send + std::marker::Sync + 'static { + pub trait GrpcManager: Send + Sync + 'static { /// async fn heartbeat( &self, @@ -529,14 +505,14 @@ pub mod grpc_manager_server { } /// #[derive(Debug)] - pub struct GrpcManagerServer { + pub struct GrpcManagerServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl GrpcManagerServer { + impl GrpcManagerServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -590,8 +566,8 @@ pub mod grpc_manager_server { impl tonic::codegen::Service> for GrpcManagerServer where T: GrpcManager, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -747,25 +723,23 @@ pub mod grpc_manager_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for GrpcManagerServer { + impl Clone for GrpcManagerServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -777,21 +751,13 @@ pub mod grpc_manager_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.GrpcManager"; - impl tonic::server::NamedService for GrpcManagerServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for GrpcManagerServer { + const NAME: &'static str = "aptos.indexer.v1.GrpcManager"; } } /// Generated client implementations. pub mod data_service_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -814,8 +780,8 @@ pub mod data_service_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -840,7 +806,7 @@ pub mod data_service_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { DataServiceClient::new(InterceptedService::new(inner, interceptor)) } @@ -887,7 +853,8 @@ pub mod data_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -912,7 +879,8 @@ pub mod data_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -931,17 +899,11 @@ pub mod data_service_client { } /// Generated server implementations. pub mod data_service_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with DataServiceServer. #[async_trait] - pub trait DataService: std::marker::Send + std::marker::Sync + 'static { + pub trait DataService: Send + Sync + 'static { /// async fn ping( &self, @@ -954,7 +916,7 @@ pub mod data_service_server { type GetTransactionsStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result, > - + std::marker::Send + + Send + 'static; /// async fn get_transactions( @@ -967,14 +929,14 @@ pub mod data_service_server { } /// #[derive(Debug)] - pub struct DataServiceServer { + pub struct DataServiceServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl DataServiceServer { + impl DataServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -1028,8 +990,8 @@ pub mod data_service_server { impl tonic::codegen::Service> for DataServiceServer where T: DataService, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -1136,25 +1098,23 @@ pub mod data_service_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for DataServiceServer { + impl Clone for DataServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -1166,9 +1126,7 @@ pub mod data_service_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.DataService"; - impl tonic::server::NamedService for DataServiceServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for DataServiceServer { + const NAME: &'static str = "aptos.indexer.v1.DataService"; } } diff --git a/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs b/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs index f8cf73cd62e..3879fd94dce 100644 --- a/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod fullnode_data_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod fullnode_data_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod fullnode_data_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { FullnodeDataClient::new(InterceptedService::new(inner, interceptor)) } @@ -106,7 +100,8 @@ pub mod fullnode_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -135,7 +130,8 @@ pub mod fullnode_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -157,17 +153,11 @@ pub mod fullnode_data_client { } /// Generated server implementations. pub mod fullnode_data_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with FullnodeDataServer. #[async_trait] - pub trait FullnodeData: std::marker::Send + std::marker::Sync + 'static { + pub trait FullnodeData: Send + Sync + 'static { /// async fn ping( &self, @@ -183,7 +173,7 @@ pub mod fullnode_data_server { tonic::Status, >, > - + std::marker::Send + + Send + 'static; /// async fn get_transactions_from_node( @@ -196,14 +186,14 @@ pub mod fullnode_data_server { } /// #[derive(Debug)] - pub struct FullnodeDataServer { + pub struct FullnodeDataServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl FullnodeDataServer { + impl FullnodeDataServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -257,8 +247,8 @@ pub mod fullnode_data_server { impl tonic::codegen::Service> for FullnodeDataServer where T: FullnodeData, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -371,25 +361,23 @@ pub mod fullnode_data_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for FullnodeDataServer { + impl Clone for FullnodeDataServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -401,9 +389,7 @@ pub mod fullnode_data_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.internal.fullnode.v1.FullnodeData"; - impl tonic::server::NamedService for FullnodeDataServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for FullnodeDataServer { + const NAME: &'static str = "aptos.internal.fullnode.v1.FullnodeData"; } } diff --git a/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs b/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs index 85f08bf9e8c..bab5b94b15a 100644 --- a/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod network_message_service_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod network_message_service_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod network_message_service_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { NetworkMessageServiceClient::new(InterceptedService::new(inner, interceptor)) } @@ -103,7 +97,8 @@ pub mod network_message_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -125,17 +120,11 @@ pub mod network_message_service_client { } /// Generated server implementations. pub mod network_message_service_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with NetworkMessageServiceServer. #[async_trait] - pub trait NetworkMessageService: std::marker::Send + std::marker::Sync + 'static { + pub trait NetworkMessageService: Send + Sync + 'static { /// async fn simple_msg_exchange( &self, @@ -144,14 +133,14 @@ pub mod network_message_service_server { } /// #[derive(Debug)] - pub struct NetworkMessageServiceServer { + pub struct NetworkMessageServiceServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl NetworkMessageServiceServer { + impl NetworkMessageServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -206,8 +195,8 @@ pub mod network_message_service_server { for NetworkMessageServiceServer where T: NetworkMessageService, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -271,25 +260,23 @@ pub mod network_message_service_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for NetworkMessageServiceServer { + impl Clone for NetworkMessageServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -301,9 +288,8 @@ pub mod network_message_service_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.remote_executor.v1.NetworkMessageService"; - impl tonic::server::NamedService for NetworkMessageServiceServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService + for NetworkMessageServiceServer { + const NAME: &'static str = "aptos.remote_executor.v1.NetworkMessageService"; } } diff --git a/protos/rust/src/pb/aptos.transaction.v1.rs b/protos/rust/src/pb/aptos.transaction.v1.rs index 42cf6289910..0276b061e44 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.rs @@ -812,6 +812,8 @@ pub struct MoveStruct { pub is_native: bool, #[prost(bool, tag="6")] pub is_event: bool, + #[prost(bool, tag="7")] + pub is_enum: bool, #[prost(enumeration="MoveAbility", repeated, tag="3")] pub abilities: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag="4")] @@ -1182,7 +1184,7 @@ pub struct MultiKeySignature { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct AbstractionSignature { +pub struct AbstractSignature { #[prost(string, tag="1")] pub function_info: ::prost::alloc::string::String, #[prost(bytes="vec", tag="2")] @@ -1255,7 +1257,7 @@ pub mod account_signature { #[prost(message, tag="6")] MultiKeySignature(super::MultiKeySignature), #[prost(message, tag="7")] - Abstraction(super::AbstractionSignature), + Abstraction(super::AbstractSignature), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -1391,7 +1393,7 @@ impl MoveAbility { } /// Encoded file descriptor set for the `aptos.transaction.v1` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xcb, 0xc1, 0x02, 0x0a, 0x26, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, + 0x0a, 0x99, 0xc2, 0x02, 0x0a, 0x26, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, @@ -2039,170 +2041,157 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x59, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, - 0x5f, 0x46, 0x52, 0x49, 0x45, 0x4e, 0x44, 0x10, 0x03, 0x22, 0xba, 0x02, 0x0a, 0x0a, 0x4d, 0x6f, + 0x5f, 0x46, 0x52, 0x49, 0x45, 0x4e, 0x44, 0x10, 0x03, 0x22, 0xd3, 0x02, 0x0a, 0x0a, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x09, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x09, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x60, 0x0a, 0x13, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x52, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, - 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x3f, 0x0a, + 0x09, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, + 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x52, 0x09, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x60, + 0x0a, 0x13, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x70, + 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x11, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, + 0x80, 0x01, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x43, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x41, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x70, 0x68, 0x61, 0x6e, 0x74, 0x6f, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x50, 0x68, 0x61, 0x6e, 0x74, + 0x6f, 0x6d, 0x22, 0x59, 0x0a, 0x0f, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x80, 0x01, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x43, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, - 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, - 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, - 0x5f, 0x70, 0x68, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x69, 0x73, 0x50, 0x68, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x22, 0x59, 0x0a, 0x0f, 0x4d, 0x6f, 0x76, - 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, - 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x63, 0x0a, 0x1c, 0x4d, 0x6f, 0x76, 0x65, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x12, 0x43, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, - 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, 0x6f, - 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x22, 0xc9, 0x03, 0x0a, 0x08, 0x4d, 0x6f, - 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x63, 0x0a, + 0x1c, 0x4d, 0x6f, 0x76, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x43, 0x0a, + 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, + 0x74, 0x73, 0x22, 0xc9, 0x03, 0x0a, 0x08, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x33, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, + 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x76, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, - 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x06, 0x76, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, - 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x61, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x12, 0x39, 0x0a, 0x18, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, - 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x4c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, - 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x72, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x72, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x1a, - 0x59, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x02, 0x74, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, - 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x4e, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, - 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, - 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x53, 0x65, 0x74, 0x22, 0x61, 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x46, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, - 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x6f, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x52, 0x06, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x0c, 0x4d, 0x6f, 0x76, 0x65, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x76, 0x65, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4e, - 0x0a, 0x13, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, + 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x3d, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x54, 0x61, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x39, 0x0a, + 0x18, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, + 0x00, 0x52, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x11, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xdc, - 0x04, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x74, + 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x72, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x6e, + 0x70, 0x61, 0x72, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x1a, 0x59, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x75, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x75, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x02, 0x74, 0x6f, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x4e, + 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x22, 0x61, + 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x49, 0x64, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x3c, 0x0a, 0x0c, 0x4d, 0x6f, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x49, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0xa5, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x61, + 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xdc, 0x04, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x42, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x12, 0x52, 0x0a, 0x0d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, + 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, - 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, - 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x52, 0x0a, 0x0d, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, - 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, - 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x4c, - 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, - 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x09, - 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x08, 0x66, 0x65, 0x65, 0x50, - 0x61, 0x79, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x73, - 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, - 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x48, - 0x00, 0x52, 0x0c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, - 0x8e, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, - 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, - 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x12, - 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x45, 0x52, - 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x47, 0x4c, - 0x45, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x10, 0x06, 0x22, 0x04, 0x08, 0x05, 0x10, 0x05, - 0x42, 0x0b, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x4f, 0x0a, - 0x10, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa4, - 0x01, 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, - 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x68, - 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0d, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x6e, - 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, 0xe8, 0x01, 0x0a, 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3e, 0x0a, - 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x3c, 0x0a, - 0x1a, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x18, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x11, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x10, - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, - 0x22, 0xe4, 0x02, 0x0a, 0x11, 0x46, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x53, 0x69, 0x67, + 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x4c, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, + 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x09, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, + 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x46, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x48, 0x00, 0x52, 0x08, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x12, 0x49, 0x0a, + 0x0d, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, 0x8e, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, + 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, + 0x41, 0x47, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x45, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, + 0x52, 0x10, 0x06, 0x22, 0x04, 0x08, 0x05, 0x10, 0x05, 0x42, 0x0b, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x4f, 0x0a, 0x10, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, + 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, + 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x10, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, 0xe8, + 0x01, 0x0a, 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, @@ -2216,1754 +2205,1772 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x10, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, - 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x65, 0x65, - 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x50, 0x0a, 0x10, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x22, 0xe4, 0x02, 0x0a, 0x11, 0x46, 0x65, + 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, + 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, - 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x41, 0x6e, 0x79, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, - 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x22, 0x90, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, + 0x3c, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x18, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x53, 0x69, + 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x53, 0x0a, + 0x11, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x10, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, + 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x50, + 0x0a, 0x10, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x0e, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x41, 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x90, 0x01, + 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x18, + 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x4b, 0x31, + 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, + 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x4c, 0x45, + 0x53, 0x53, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x44, + 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x05, + 0x22, 0xf6, 0x03, 0x0a, 0x0c, 0x41, 0x6e, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, + 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x39, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, + 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x4f, 0x0a, 0x0f, 0x73, + 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x5f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x70, + 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, 0x63, 0x64, 0x73, 0x61, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, + 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, 0x63, 0x64, 0x73, 0x61, 0x12, 0x3c, 0x0a, 0x08, + 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x6e, 0x48, 0x00, + 0x52, 0x08, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x12, 0x39, 0x0a, 0x07, 0x6b, 0x65, + 0x79, 0x6c, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, + 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x6c, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x65, + 0x79, 0x6c, 0x65, 0x73, 0x73, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x4b, 0x31, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x10, 0x02, 0x12, - 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, - 0x31, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4b, 0x45, - 0x59, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x05, 0x22, 0xf6, 0x03, 0x0a, 0x0c, 0x41, 0x6e, 0x79, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, - 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, - 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, - 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, - 0x31, 0x39, 0x12, 0x4f, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x5f, - 0x65, 0x63, 0x64, 0x73, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, - 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, 0x63, 0x64, 0x73, - 0x61, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, 0x63, - 0x64, 0x73, 0x61, 0x12, 0x3c, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x62, - 0x41, 0x75, 0x74, 0x68, 0x6e, 0x48, 0x00, 0x52, 0x08, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, - 0x6e, 0x12, 0x39, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x6c, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x6c, 0x65, 0x73, - 0x73, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x6c, 0x65, 0x73, 0x73, 0x22, 0x6d, 0x0a, 0x04, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x4b, 0x31, 0x5f, 0x45, - 0x43, 0x44, 0x53, 0x41, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, - 0x45, 0x42, 0x41, 0x55, 0x54, 0x48, 0x4e, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x04, 0x42, 0x13, 0x0a, 0x11, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, - 0x22, 0x27, 0x0a, 0x07, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x2e, 0x0a, 0x0e, 0x53, 0x65, 0x63, - 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, 0x63, 0x64, 0x73, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x28, 0x0a, 0x08, 0x57, 0x65, 0x62, - 0x41, 0x75, 0x74, 0x68, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x22, 0x27, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x1c, + 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x45, 0x42, 0x41, 0x55, 0x54, 0x48, 0x4e, + 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x4c, 0x45, + 0x53, 0x53, 0x10, 0x04, 0x42, 0x13, 0x0a, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x27, 0x0a, 0x07, 0x45, 0x64, 0x32, + 0x35, 0x35, 0x31, 0x39, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x22, 0x2e, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x45, + 0x63, 0x64, 0x73, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x22, 0x28, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x99, 0x01, 0x0a, - 0x12, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x40, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, + 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x27, 0x0a, 0x07, + 0x4b, 0x65, 0x79, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x99, 0x01, 0x0a, 0x12, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, + 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x41, 0x0a, 0x0a, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, + 0x40, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x22, 0x6a, 0x0a, 0x10, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x40, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xd1, 0x01, + 0x0a, 0x11, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x43, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x46, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, + 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x5f, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x22, 0x56, 0x0a, 0x11, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x6e, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x6a, 0x0a, 0x10, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x12, 0x40, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x11, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, - 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x43, 0x0a, 0x0b, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, - 0x46, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x59, 0x0a, 0x14, 0x41, 0x62, 0x73, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x73, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x22, 0x8f, 0x05, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x65, 0x64, 0x32, - 0x35, 0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, - 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x52, 0x0a, - 0x0d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, - 0x39, 0x12, 0x5c, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x12, 0x73, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, - 0x59, 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, 0x8c, 0x05, 0x0a, 0x10, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3f, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, - 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x62, - 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, - 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8b, 0x01, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, - 0x39, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x47, - 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x54, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x06, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x0b, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, 0x0a, - 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, - 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x12, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x5f, 0x6f, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, - 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, 0x0a, 0x0d, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x0a, 0x0e, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x54, 0x61, 0x67, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x70, 0x53, 0x69, - 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x79, 0x74, 0x65, 0x73, 0x2a, 0xea, 0x02, 0x0a, 0x09, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x42, 0x4f, 0x4f, - 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x53, 0x5f, 0x55, 0x38, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x31, 0x36, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, - 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x12, - 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x36, 0x34, - 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, - 0x5f, 0x55, 0x31, 0x32, 0x38, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x12, 0x16, 0x0a, 0x12, - 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, - 0x53, 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x53, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x4d, - 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, - 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, - 0x5f, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x08, 0x12, 0x21, 0x0a, 0x1d, 0x4d, 0x4f, 0x56, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, - 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, - 0x45, 0x4e, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x50, 0x41, 0x52, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x10, - 0x0b, 0x2a, 0x87, 0x01, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x79, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, - 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, - 0x43, 0x4f, 0x50, 0x59, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, - 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x02, 0x12, 0x16, 0x0a, - 0x12, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x53, 0x54, - 0x4f, 0x52, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, - 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x42, 0x9e, 0x01, 0x0a, 0x18, - 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0xa2, 0x02, 0x03, 0x41, - 0x54, 0x58, 0xaa, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, - 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x4a, 0xc7, 0xbf, 0x01, - 0x0a, 0x07, 0x12, 0x05, 0x03, 0x00, 0x80, 0x05, 0x01, 0x0a, 0x4e, 0x0a, 0x01, 0x0c, 0x12, 0x03, - 0x03, 0x00, 0x12, 0x32, 0x44, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, - 0xc2, 0xa9, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, - 0x65, 0x2d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, - 0x05, 0x00, 0x1d, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x07, 0x00, 0x2e, 0x0a, 0xa3, - 0x05, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x12, 0x00, 0x20, 0x01, 0x1a, 0x96, 0x05, 0x20, 0x41, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, - 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, - 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x28, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, - 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x29, 0x0a, 0x20, - 0x41, 0x6c, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, - 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x64, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6c, 0x79, 0x20, - 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, - 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2c, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, - 0x72, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, - 0x20, 0x61, 0x20, 0x67, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, - 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6c, - 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x60, 0x2e, 0x0a, 0x0a, - 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x30, 0x29, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, - 0x73, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, - 0x68, 0x61, 0x73, 0x20, 0x61, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6f, 0x66, 0x20, - 0x60, 0x30, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x12, 0x08, 0x0d, - 0x0a, 0xde, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x15, 0x02, 0x2f, 0x1a, 0xd0, - 0x01, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x72, 0x65, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x60, 0x47, 0x65, 0x6e, 0x65, - 0x73, 0x69, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, - 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, - 0x79, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x60, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x60, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x15, 0x02, 0x20, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x15, 0x21, 0x2a, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x15, 0x2d, 0x2e, 0x0a, 0x88, 0x01, 0x0a, 0x04, - 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x18, 0x02, 0x29, 0x1a, 0x7b, 0x20, 0x48, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x69, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, - 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, - 0x03, 0x18, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x18, - 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x18, 0x12, 0x13, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, 0x03, 0x18, 0x14, 0x28, 0x0a, 0x0d, - 0x0a, 0x06, 0x04, 0x00, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x18, 0x15, 0x27, 0x0a, 0x87, 0x02, - 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x1c, 0x02, 0x28, 0x1a, 0xf9, 0x01, 0x20, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x6f, 0x6c, 0x64, - 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, - 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, - 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, - 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x29, - 0x0a, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2c, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, 0x20, 0x74, - 0x6f, 0x20, 0x28, 0x62, 0x75, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x42, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x12, 0x52, 0x0a, 0x0d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, + 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, + 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x5c, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, + 0x00, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x59, 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, + 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x4b, 0x0a, 0x0b, 0x61, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x62, 0x73, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, + 0x52, 0x0b, 0x61, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8b, 0x01, + 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x16, + 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, 0x44, 0x32, + 0x35, 0x35, 0x31, 0x39, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x05, 0x12, + 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x54, 0x52, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x0b, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4b, 0x0a, + 0x0f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x12, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, + 0x0a, 0x0d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x24, 0x0a, 0x0e, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x54, 0x61, 0x67, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, + 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0xea, 0x02, 0x0a, 0x09, 0x4d, 0x6f, 0x76, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, + 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x38, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x31, 0x36, 0x10, 0x0c, 0x12, 0x12, 0x0a, + 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x33, 0x32, 0x10, + 0x0d, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, + 0x55, 0x36, 0x34, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x53, 0x5f, 0x55, 0x31, 0x32, 0x38, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, + 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x12, + 0x16, 0x0a, 0x12, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x41, 0x44, + 0x44, 0x52, 0x45, 0x53, 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x15, + 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x56, 0x45, 0x43, + 0x54, 0x4f, 0x52, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x08, 0x12, 0x21, 0x0a, 0x1d, + 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, + 0x49, 0x43, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x10, 0x09, 0x12, + 0x18, 0x0a, 0x14, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x52, 0x45, + 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x4f, 0x56, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x50, 0x41, 0x52, 0x53, 0x41, 0x42, + 0x4c, 0x45, 0x10, 0x0b, 0x2a, 0x87, 0x01, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, + 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, + 0x54, 0x59, 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, + 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x02, + 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, + 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x56, 0x45, + 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x42, 0x9e, + 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0xa2, + 0x02, 0x03, 0x41, 0x54, 0x58, 0xaa, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, + 0x70, 0x74, 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x3a, 0x3a, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x4a, + 0x82, 0xc0, 0x01, 0x0a, 0x07, 0x12, 0x05, 0x03, 0x00, 0x81, 0x05, 0x01, 0x0a, 0x4e, 0x0a, 0x01, + 0x0c, 0x12, 0x03, 0x03, 0x00, 0x12, 0x32, 0x44, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0xc2, 0xa9, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, 0x46, 0x6f, 0x75, 0x6e, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, + 0x65, 0x6e, 0x73, 0x65, 0x2d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, + 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x0a, 0x0a, 0x08, 0x0a, 0x01, + 0x02, 0x12, 0x03, 0x05, 0x00, 0x1d, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x07, 0x00, + 0x2e, 0x0a, 0xa3, 0x05, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x12, 0x00, 0x20, 0x01, 0x1a, 0x96, + 0x05, 0x20, 0x41, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x41, 0x70, 0x74, + 0x6f, 0x73, 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, + 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x28, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, + 0x20, 0x60, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x29, 0x0a, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x04, - 0x12, 0x03, 0x1c, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, - 0x1c, 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x1c, 0x17, - 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1c, 0x26, 0x27, 0x0a, - 0x99, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1f, 0x02, 0x16, 0x1a, 0x8b, 0x01, - 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x49, 0x44, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x73, 0x20, 0x75, 0x73, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, - 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x73, - 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x6d, 0x69, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, - 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x1f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, - 0x03, 0x01, 0x12, 0x03, 0x1f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, - 0x12, 0x03, 0x1f, 0x14, 0x15, 0x0a, 0x94, 0x04, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x27, 0x00, - 0x47, 0x01, 0x1a, 0x87, 0x04, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, - 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x34, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x3a, 0x0a, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x0a, 0x20, - 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x22, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x22, 0x0a, 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x45, 0x70, 0x69, 0x6c, - 0x6f, 0x67, 0x75, 0x65, 0x20, 0x2f, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x64, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x0a, 0x20, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, - 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x62, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, - 0x04, 0x01, 0x01, 0x12, 0x03, 0x27, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, - 0x12, 0x03, 0x28, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, - 0x28, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x21, - 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x2d, 0x2e, 0x0a, - 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x29, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x01, 0x01, 0x12, 0x03, 0x29, 0x09, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, - 0x03, 0x12, 0x03, 0x29, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x08, 0x12, - 0x03, 0x29, 0x15, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, - 0x29, 0x16, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x2a, 0x02, 0x1b, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x2a, 0x02, 0x11, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x2a, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x2a, 0x19, 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, - 0x02, 0x03, 0x12, 0x03, 0x2b, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x05, - 0x12, 0x03, 0x2b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, - 0x2b, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x2b, 0x11, - 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, 0x03, 0x2b, 0x13, 0x27, 0x0a, - 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x03, 0x08, 0x06, 0x12, 0x03, 0x2b, 0x14, 0x26, 0x0a, 0x0b, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x2c, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x04, 0x05, 0x12, 0x03, 0x2c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x04, 0x01, 0x12, 0x03, 0x2c, 0x09, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x03, - 0x12, 0x03, 0x2c, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x08, 0x12, 0x03, - 0x2c, 0x1a, 0x2e, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x04, 0x08, 0x06, 0x12, 0x03, 0x2c, - 0x1b, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x04, 0x00, 0x12, 0x04, 0x2e, 0x02, 0x37, 0x03, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x16, 0x0a, 0x0d, - 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2f, 0x04, 0x25, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x04, 0x20, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x2f, 0x23, 0x24, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x30, 0x04, 0x21, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x30, 0x1f, 0x20, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x31, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x31, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x32, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x32, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x32, 0x28, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x33, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x33, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x33, 0x1c, 0x1d, 0x0a, 0x32, 0x0a, 0x06, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x05, 0x12, 0x03, 0x35, 0x04, 0x24, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x20, 0x35, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x35, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x35, 0x21, 0x23, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x12, 0x03, 0x36, 0x04, 0x29, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, 0x36, 0x04, 0x23, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x36, 0x26, 0x28, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x01, 0x02, 0x05, 0x12, 0x03, 0x39, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x05, 0x06, 0x12, 0x03, 0x39, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, 0x01, - 0x12, 0x03, 0x39, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, 0x03, 0x12, 0x03, - 0x39, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x3b, 0x02, 0x44, - 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x3b, 0x08, 0x10, 0x0a, - 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x30, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x06, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x06, 0x01, 0x12, 0x03, 0x3c, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x06, - 0x03, 0x12, 0x03, 0x3c, 0x2e, 0x2f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x07, 0x12, 0x03, - 0x3d, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x06, 0x12, 0x03, 0x3d, 0x04, - 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x01, 0x12, 0x03, 0x3d, 0x17, 0x1e, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x03, 0x12, 0x03, 0x3d, 0x21, 0x22, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x01, 0x02, 0x08, 0x12, 0x03, 0x3e, 0x04, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x08, 0x06, 0x12, 0x03, 0x3e, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x08, - 0x01, 0x12, 0x03, 0x3e, 0x1f, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x08, 0x03, 0x12, - 0x03, 0x3e, 0x32, 0x33, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x09, 0x12, 0x03, 0x3f, 0x04, - 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x06, 0x12, 0x03, 0x3f, 0x04, 0x13, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x01, 0x12, 0x03, 0x3f, 0x14, 0x18, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x09, 0x03, 0x12, 0x03, 0x3f, 0x1b, 0x1d, 0x0a, 0x30, 0x0a, 0x04, 0x04, - 0x01, 0x02, 0x0a, 0x12, 0x03, 0x41, 0x04, 0x28, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x20, 0x31, 0x31, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x0a, 0x06, 0x12, 0x03, 0x41, 0x04, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x0a, 0x01, 0x12, 0x03, 0x41, 0x19, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x0a, 0x03, 0x12, 0x03, 0x41, 0x25, 0x27, 0x0a, 0x6e, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0b, 0x12, - 0x03, 0x43, 0x04, 0x31, 0x1a, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x32, 0x32, 0x20, - 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x75, 0x70, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, - 0x20, 0x28, 0x61, 0x6c, 0x6c, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x6f, - 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x67, 0x6f, 0x69, 0x6e, 0x67, - 0x20, 0x74, 0x6f, 0x20, 0x32, 0x33, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x06, - 0x12, 0x03, 0x43, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x01, 0x12, 0x03, - 0x43, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x03, 0x12, 0x03, 0x43, 0x2e, - 0x30, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x03, 0x46, 0x02, 0x25, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0c, 0x06, 0x12, 0x03, 0x46, 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x0c, 0x01, 0x12, 0x03, 0x46, 0x16, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x0c, 0x03, 0x12, 0x03, 0x46, 0x22, 0x24, 0x0a, 0x20, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, - 0x4a, 0x00, 0x51, 0x01, 0x1a, 0x14, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, - 0x01, 0x12, 0x03, 0x4a, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, - 0x4b, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x4b, 0x02, - 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4b, 0x09, 0x0b, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4b, 0x0e, 0x0f, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4c, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, - 0x02, 0x01, 0x05, 0x12, 0x03, 0x4c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, - 0x01, 0x12, 0x03, 0x4c, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, 0x12, - 0x03, 0x4c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x08, 0x12, 0x03, 0x4c, - 0x13, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x4c, 0x14, - 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03, 0x4d, 0x02, 0x1c, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4d, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x02, 0x02, 0x02, 0x06, 0x12, 0x03, 0x4d, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, - 0x02, 0x02, 0x01, 0x12, 0x03, 0x4d, 0x11, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, - 0x03, 0x12, 0x03, 0x4d, 0x1a, 0x1b, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x03, 0x12, 0x03, - 0x4e, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, 0x03, 0x4e, 0x02, - 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x01, 0x12, 0x03, 0x4e, 0x08, 0x23, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x03, 0x12, 0x03, 0x4e, 0x26, 0x27, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4f, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, - 0x02, 0x04, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x04, - 0x01, 0x12, 0x03, 0x4f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x04, 0x03, 0x12, - 0x03, 0x4f, 0x14, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x05, 0x12, 0x03, 0x50, 0x02, - 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x04, 0x12, 0x03, 0x50, 0x02, 0x0a, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x05, 0x12, 0x03, 0x50, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x02, 0x02, 0x05, 0x01, 0x12, 0x03, 0x50, 0x12, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x02, 0x02, 0x05, 0x03, 0x12, 0x03, 0x50, 0x2c, 0x2d, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, - 0x04, 0x53, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x53, 0x08, - 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x54, 0x02, 0x17, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x54, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x54, 0x0b, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, - 0x02, 0x00, 0x03, 0x12, 0x03, 0x54, 0x15, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x12, 0x03, 0x55, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x04, 0x12, 0x03, - 0x55, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x55, 0x0b, - 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x55, 0x11, 0x17, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x55, 0x1a, 0x1b, 0x0a, 0x09, 0x0a, - 0x02, 0x04, 0x04, 0x12, 0x03, 0x58, 0x00, 0x25, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, - 0x03, 0x58, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x05, 0x5a, 0x00, 0x8e, 0x01, - 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x5a, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, 0x5b, 0x02, 0x5e, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x5b, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, - 0x00, 0x12, 0x03, 0x5c, 0x04, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, 0x12, - 0x03, 0x5c, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x5c, - 0x16, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x5c, 0x2c, 0x2d, - 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x5d, 0x04, 0x1d, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x05, 0x02, 0x01, 0x06, 0x12, 0x03, 0x5d, 0x04, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x5d, 0x0e, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, - 0x01, 0x03, 0x12, 0x03, 0x5d, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x00, 0x12, - 0x05, 0x60, 0x02, 0x82, 0x01, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x00, 0x01, 0x12, - 0x03, 0x60, 0x0a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, - 0x61, 0x04, 0x77, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, - 0x03, 0x61, 0x0c, 0x20, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x12, 0x03, 0x62, 0x06, 0x18, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, - 0x00, 0x05, 0x12, 0x03, 0x62, 0x06, 0x0c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x62, 0x0d, 0x13, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x62, 0x16, 0x17, 0x0a, 0x0f, 0x0a, 0x08, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x63, 0x06, 0x19, 0x0a, 0x10, 0x0a, 0x09, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x63, 0x06, 0x0c, 0x0a, 0x10, - 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x63, 0x0d, 0x14, - 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x63, - 0x17, 0x18, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, - 0x64, 0x06, 0x74, 0x07, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x01, 0x12, 0x03, 0x64, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, 0x65, 0x08, 0x6b, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x65, 0x10, 0x13, 0x0a, 0x13, - 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, - 0x66, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x66, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x66, 0x11, 0x14, 0x0a, - 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, - 0x12, 0x03, 0x66, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x67, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x67, 0x0a, 0x10, - 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, - 0x01, 0x12, 0x03, 0x67, 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x67, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x68, 0x0a, - 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, - 0x02, 0x05, 0x12, 0x03, 0x68, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x68, 0x11, 0x14, 0x0a, 0x14, 0x0a, - 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, - 0x68, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x03, 0x12, 0x03, 0x69, 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x69, 0x0a, 0x10, 0x0a, 0x14, - 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x01, 0x12, - 0x03, 0x69, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x69, 0x15, 0x16, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x12, 0x03, 0x6a, 0x0a, 0x17, 0x0a, - 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x05, - 0x12, 0x03, 0x6a, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x6a, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x6a, 0x15, - 0x16, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x12, - 0x04, 0x6c, 0x08, 0x6f, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x01, 0x01, 0x12, 0x03, 0x6c, 0x10, 0x1e, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x6d, 0x0a, 0x17, 0x0a, 0x14, - 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, - 0x03, 0x6d, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x6d, 0x10, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x6d, 0x15, 0x16, - 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, - 0x12, 0x03, 0x6e, 0x0a, 0x1c, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x6e, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x6e, 0x10, + 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, + 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, + 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, + 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x64, 0x65, 0x6e, 0x6f, 0x74, + 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, + 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x60, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, + 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2c, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, + 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x67, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, + 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, 0x74, 0x77, + 0x6f, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x60, + 0x2e, 0x0a, 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x30, 0x29, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, 0x68, 0x69, + 0x63, 0x68, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x60, 0x30, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, + 0x12, 0x08, 0x0d, 0x0a, 0xde, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x15, 0x02, + 0x2f, 0x1a, 0xd0, 0x01, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x72, + 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x60, 0x47, + 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x60, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, + 0x76, 0x65, 0x72, 0x79, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x60, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x60, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x15, + 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x15, 0x21, 0x2a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x15, 0x2d, 0x2e, 0x0a, 0x88, + 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x18, 0x02, 0x29, 0x1a, 0x7b, 0x20, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, + 0x2c, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x01, 0x05, 0x12, 0x03, 0x18, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, + 0x12, 0x03, 0x18, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, + 0x18, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, 0x03, 0x18, 0x14, + 0x28, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x18, 0x15, 0x27, + 0x0a, 0x87, 0x02, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x1c, 0x02, 0x28, 0x1a, 0xf9, + 0x01, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, + 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, + 0x6e, 0x67, 0x29, 0x0a, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, + 0x70, 0x20, 0x74, 0x6f, 0x20, 0x28, 0x62, 0x75, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x69, 0x6e, 0x67, 0x29, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x02, 0x04, 0x12, 0x03, 0x1c, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, + 0x06, 0x12, 0x03, 0x1c, 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, + 0x03, 0x1c, 0x17, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1c, + 0x26, 0x27, 0x0a, 0x99, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1f, 0x02, 0x16, + 0x1a, 0x8b, 0x01, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x49, 0x44, 0x20, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x75, 0x73, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, + 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x27, 0x72, + 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x69, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x1f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x03, 0x03, 0x12, 0x03, 0x1f, 0x14, 0x15, 0x0a, 0x94, 0x04, 0x0a, 0x02, 0x04, 0x01, 0x12, + 0x04, 0x27, 0x00, 0x47, 0x01, 0x1a, 0x87, 0x04, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x34, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x3a, 0x0a, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, + 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x0a, 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x6f, + 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x22, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x0a, 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x45, + 0x70, 0x69, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x20, 0x2f, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x0a, 0x20, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, + 0x73, 0x69, 0x73, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x63, 0x6f, + 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x27, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x00, 0x12, 0x03, 0x28, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x28, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x28, 0x21, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, + 0x2d, 0x2e, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02, 0x2a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x29, 0x02, 0x08, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x29, 0x09, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x29, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x01, 0x08, 0x12, 0x03, 0x29, 0x15, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x01, 0x08, + 0x06, 0x12, 0x03, 0x29, 0x16, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, + 0x2a, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x2a, 0x02, + 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x2a, 0x12, 0x16, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x2a, 0x19, 0x1a, 0x0a, 0x0b, 0x0a, + 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x2b, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x03, 0x05, 0x12, 0x03, 0x2b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, + 0x01, 0x12, 0x03, 0x2b, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, + 0x03, 0x2b, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, 0x03, 0x2b, + 0x13, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x03, 0x08, 0x06, 0x12, 0x03, 0x2b, 0x14, + 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x2c, 0x02, 0x2f, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x05, 0x12, 0x03, 0x2c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x04, 0x01, 0x12, 0x03, 0x2c, 0x09, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x04, 0x03, 0x12, 0x03, 0x2c, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, + 0x08, 0x12, 0x03, 0x2c, 0x1a, 0x2e, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x04, 0x08, 0x06, + 0x12, 0x03, 0x2c, 0x1b, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x04, 0x00, 0x12, 0x04, 0x2e, + 0x02, 0x37, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, + 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2f, 0x04, 0x25, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x04, 0x20, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x2f, 0x23, 0x24, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x30, 0x04, 0x21, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x04, 0x1c, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x30, 0x1f, 0x20, 0x0a, + 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x31, 0x04, 0x28, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x23, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x31, 0x26, 0x27, 0x0a, 0x0d, + 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x32, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x32, 0x04, 0x25, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x32, 0x28, 0x29, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x33, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x33, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x33, 0x1c, 0x1d, 0x0a, 0x32, 0x0a, 0x06, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x12, 0x03, 0x35, 0x04, 0x24, 0x1a, 0x23, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x20, 0x35, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, + 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x35, 0x04, 0x1e, + 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x35, 0x21, 0x23, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x12, 0x03, 0x36, 0x04, 0x29, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, 0x36, 0x04, 0x23, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x36, 0x26, 0x28, 0x0a, + 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x05, 0x12, 0x03, 0x39, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x05, 0x06, 0x12, 0x03, 0x39, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x05, 0x01, 0x12, 0x03, 0x39, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, + 0x03, 0x12, 0x03, 0x39, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, + 0x3b, 0x02, 0x44, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x3b, + 0x08, 0x10, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x30, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x06, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x06, 0x01, 0x12, 0x03, 0x3c, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x06, 0x03, 0x12, 0x03, 0x3c, 0x2e, 0x2f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, + 0x07, 0x12, 0x03, 0x3d, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x06, 0x12, + 0x03, 0x3d, 0x04, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x01, 0x12, 0x03, 0x3d, + 0x17, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x03, 0x12, 0x03, 0x3d, 0x21, 0x22, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x08, 0x12, 0x03, 0x3e, 0x04, 0x34, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x08, 0x06, 0x12, 0x03, 0x3e, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x08, 0x01, 0x12, 0x03, 0x3e, 0x1f, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x08, 0x03, 0x12, 0x03, 0x3e, 0x32, 0x33, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x09, 0x12, + 0x03, 0x3f, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x06, 0x12, 0x03, 0x3f, + 0x04, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x01, 0x12, 0x03, 0x3f, 0x14, 0x18, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x03, 0x12, 0x03, 0x3f, 0x1b, 0x1d, 0x0a, 0x30, + 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0a, 0x12, 0x03, 0x41, 0x04, 0x28, 0x1a, 0x23, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x31, 0x31, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, + 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0a, 0x06, 0x12, 0x03, 0x41, 0x04, 0x18, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0a, 0x01, 0x12, 0x03, 0x41, 0x19, 0x22, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x0a, 0x03, 0x12, 0x03, 0x41, 0x25, 0x27, 0x0a, 0x6e, 0x0a, 0x04, 0x04, 0x01, + 0x02, 0x0b, 0x12, 0x03, 0x43, 0x04, 0x31, 0x1a, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, + 0x32, 0x32, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x75, 0x70, 0x20, 0x62, 0x65, + 0x6c, 0x6f, 0x77, 0x20, 0x28, 0x61, 0x6c, 0x6c, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x67, 0x6f, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x32, 0x33, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x0b, 0x06, 0x12, 0x03, 0x43, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, + 0x01, 0x12, 0x03, 0x43, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x03, 0x12, + 0x03, 0x43, 0x2e, 0x30, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x03, 0x46, 0x02, + 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0c, 0x06, 0x12, 0x03, 0x46, 0x02, 0x15, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0c, 0x01, 0x12, 0x03, 0x46, 0x16, 0x1f, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x0c, 0x03, 0x12, 0x03, 0x46, 0x22, 0x24, 0x0a, 0x20, 0x0a, 0x02, 0x04, + 0x02, 0x12, 0x04, 0x4a, 0x00, 0x51, 0x01, 0x1a, 0x14, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x4a, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, + 0x00, 0x12, 0x03, 0x4b, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, + 0x03, 0x4b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4b, + 0x09, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4b, 0x0e, 0x0f, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4c, 0x02, 0x28, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x01, 0x05, 0x12, 0x03, 0x4c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x4c, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x4c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x08, + 0x12, 0x03, 0x4c, 0x13, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x02, 0x01, 0x08, 0x06, 0x12, + 0x03, 0x4c, 0x14, 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03, 0x4d, 0x02, + 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4d, 0x02, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x06, 0x12, 0x03, 0x4d, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4d, 0x11, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x4d, 0x1a, 0x1b, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, + 0x03, 0x12, 0x03, 0x4e, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, + 0x03, 0x4e, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x01, 0x12, 0x03, 0x4e, + 0x08, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x03, 0x12, 0x03, 0x4e, 0x26, 0x27, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4f, 0x02, 0x16, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x04, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x04, 0x01, 0x12, 0x03, 0x4f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x04, 0x03, 0x12, 0x03, 0x4f, 0x14, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x05, 0x12, + 0x03, 0x50, 0x02, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x04, 0x12, 0x03, 0x50, + 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x05, 0x12, 0x03, 0x50, 0x0b, 0x11, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x01, 0x12, 0x03, 0x50, 0x12, 0x29, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x03, 0x12, 0x03, 0x50, 0x2c, 0x2d, 0x0a, 0x0a, 0x0a, 0x02, + 0x04, 0x03, 0x12, 0x04, 0x53, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, + 0x03, 0x53, 0x08, 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x54, 0x02, + 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x54, 0x02, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x54, 0x0b, 0x12, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x54, 0x15, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x03, 0x02, 0x01, 0x12, 0x03, 0x55, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, + 0x04, 0x12, 0x03, 0x55, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, + 0x03, 0x55, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x55, + 0x11, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x55, 0x1a, 0x1b, + 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x03, 0x58, 0x00, 0x25, 0x0a, 0x0a, 0x0a, 0x03, 0x04, + 0x04, 0x01, 0x12, 0x03, 0x58, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x05, 0x5a, + 0x00, 0x8e, 0x01, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x5a, 0x08, 0x1c, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, 0x5b, 0x02, 0x5e, 0x03, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x5b, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, + 0x04, 0x05, 0x02, 0x00, 0x12, 0x03, 0x5c, 0x04, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, + 0x00, 0x06, 0x12, 0x03, 0x5c, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x5c, 0x16, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x5c, 0x2c, 0x2d, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x5d, 0x04, 0x1d, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x06, 0x12, 0x03, 0x5d, 0x04, 0x0d, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x5d, 0x0e, 0x18, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x05, 0x02, 0x01, 0x03, 0x12, 0x03, 0x5d, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x04, 0x04, 0x05, + 0x03, 0x00, 0x12, 0x05, 0x60, 0x02, 0x82, 0x01, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, + 0x00, 0x01, 0x12, 0x03, 0x60, 0x0a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x12, 0x04, 0x61, 0x04, 0x77, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x01, 0x12, 0x03, 0x61, 0x0c, 0x20, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x02, 0x00, 0x12, 0x03, 0x62, 0x06, 0x18, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x62, 0x06, 0x0c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x62, 0x0d, 0x13, 0x0a, 0x10, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x62, 0x16, 0x17, 0x0a, 0x0f, + 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x63, 0x06, 0x19, 0x0a, + 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x63, 0x06, + 0x0c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x63, 0x0d, 0x14, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, + 0x12, 0x03, 0x63, 0x17, 0x18, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x12, 0x04, 0x64, 0x06, 0x74, 0x07, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x64, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, 0x65, 0x08, 0x6b, 0x09, 0x0a, 0x12, 0x0a, + 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x65, 0x10, + 0x13, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x00, 0x12, 0x03, 0x66, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x66, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x66, + 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x03, 0x12, 0x03, 0x66, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x67, 0x0a, 0x19, 0x0a, 0x14, 0x0a, + 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, + 0x67, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x67, 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x67, 0x17, 0x18, 0x0a, + 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, + 0x03, 0x68, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x68, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x68, 0x11, 0x14, + 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, + 0x03, 0x12, 0x03, 0x68, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x12, 0x03, 0x69, 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x69, 0x0a, + 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x03, 0x69, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x69, 0x15, 0x16, 0x0a, 0x13, 0x0a, + 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x12, 0x03, 0x6a, + 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x04, 0x05, 0x12, 0x03, 0x6a, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x6a, 0x11, 0x12, 0x0a, 0x14, + 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x12, + 0x03, 0x6a, 0x15, 0x16, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x01, 0x12, 0x04, 0x6c, 0x08, 0x6f, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x01, 0x12, 0x03, 0x6c, 0x10, 0x1e, 0x0a, 0x13, 0x0a, 0x0c, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x6d, 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, - 0x01, 0x03, 0x12, 0x03, 0x6e, 0x1a, 0x1b, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x08, 0x00, 0x12, 0x04, 0x70, 0x08, 0x73, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x70, 0x0e, 0x15, 0x0a, - 0x11, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x71, - 0x0a, 0x2d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x71, 0x0a, 0x18, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x71, 0x19, 0x28, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x71, 0x2b, 0x2c, 0x0a, 0x11, - 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x72, 0x0a, - 0x16, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x06, - 0x12, 0x03, 0x72, 0x0a, 0x0d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x72, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x72, 0x14, 0x15, 0x0a, 0x0f, 0x0a, - 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x76, 0x06, 0x1c, 0x0a, 0x10, - 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x04, 0x12, 0x03, 0x76, 0x06, 0x0e, - 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x76, - 0x0f, 0x12, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, - 0x03, 0x76, 0x13, 0x17, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, - 0x03, 0x12, 0x03, 0x76, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, - 0x12, 0x04, 0x78, 0x04, 0x7c, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, - 0x01, 0x12, 0x03, 0x78, 0x0c, 0x26, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, - 0x02, 0x00, 0x12, 0x03, 0x79, 0x06, 0x29, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x79, 0x06, 0x0e, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x79, 0x0f, 0x15, 0x0a, 0x10, 0x0a, 0x09, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x79, 0x16, 0x24, 0x0a, 0x10, 0x0a, - 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79, 0x27, 0x28, 0x0a, - 0x1e, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x12, 0x03, 0x7b, 0x06, 0x14, - 0x1a, 0x0d, 0x20, 0x48, 0x65, 0x78, 0x54, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, - 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x7b, 0x06, - 0x0b, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, - 0x7b, 0x0c, 0x0f, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x03, - 0x12, 0x03, 0x7b, 0x12, 0x13, 0x0a, 0x0f, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x12, - 0x05, 0x7d, 0x04, 0x80, 0x01, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, - 0x01, 0x12, 0x03, 0x7d, 0x0c, 0x21, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, - 0x02, 0x00, 0x12, 0x03, 0x7e, 0x06, 0x26, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x7e, 0x06, 0x1a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x7e, 0x1b, 0x21, 0x0a, 0x10, 0x0a, 0x09, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x7e, 0x24, 0x25, 0x0a, 0x0f, 0x0a, - 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7f, 0x06, 0x2f, 0x0a, 0x10, - 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x7f, 0x06, 0x20, - 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x7f, - 0x21, 0x2a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x03, 0x12, - 0x03, 0x7f, 0x2d, 0x2e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, - 0x81, 0x01, 0x04, 0x36, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, - 0x04, 0x81, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x12, 0x04, 0x81, 0x01, 0x1a, 0x31, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, - 0x03, 0x12, 0x04, 0x81, 0x01, 0x34, 0x35, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x01, 0x12, - 0x06, 0x84, 0x01, 0x02, 0x8b, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x01, 0x01, - 0x12, 0x04, 0x84, 0x01, 0x0a, 0x13, 0x0a, 0x10, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, - 0x12, 0x06, 0x85, 0x01, 0x04, 0x89, 0x01, 0x05, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x01, - 0x03, 0x00, 0x01, 0x12, 0x04, 0x85, 0x01, 0x0c, 0x19, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, - 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0x86, 0x01, 0x06, 0x17, 0x0a, 0x11, 0x0a, 0x09, 0x04, - 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x04, 0x86, 0x01, 0x06, 0x0c, 0x0a, 0x11, - 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x86, 0x01, 0x0d, - 0x12, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x04, - 0x86, 0x01, 0x15, 0x16, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, - 0x12, 0x04, 0x87, 0x01, 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, - 0x02, 0x01, 0x05, 0x12, 0x04, 0x87, 0x01, 0x06, 0x0c, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, - 0x01, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x87, 0x01, 0x0d, 0x13, 0x0a, 0x11, 0x0a, 0x09, - 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0x87, 0x01, 0x16, 0x17, 0x0a, - 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x12, 0x04, 0x88, 0x01, 0x06, - 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x05, 0x12, 0x04, - 0x88, 0x01, 0x06, 0x0b, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, - 0x01, 0x12, 0x04, 0x88, 0x01, 0x0c, 0x13, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, - 0x00, 0x02, 0x02, 0x03, 0x12, 0x04, 0x88, 0x01, 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, - 0x03, 0x01, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x25, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, - 0x03, 0x01, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x05, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x12, 0x20, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x05, 0x02, 0x02, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x05, 0x02, 0x02, 0x04, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, - 0x02, 0x02, 0x06, 0x12, 0x04, 0x8d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, - 0x02, 0x01, 0x12, 0x04, 0x8d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, - 0x03, 0x12, 0x04, 0x8d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x06, 0x12, 0x06, 0x90, - 0x01, 0x00, 0x92, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x04, 0x90, 0x01, - 0x08, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, 0x91, 0x01, 0x02, 0x2b, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x04, 0x12, 0x04, 0x91, 0x01, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x04, 0x91, 0x01, 0x0b, 0x17, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x01, 0x18, 0x26, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x04, 0x91, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x02, - 0x04, 0x07, 0x12, 0x06, 0x94, 0x01, 0x00, 0x99, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x07, - 0x01, 0x12, 0x04, 0x94, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x00, 0x12, - 0x04, 0x95, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x05, 0x12, 0x04, - 0x95, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12, 0x04, 0x95, - 0x01, 0x07, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x04, 0x95, 0x01, - 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x04, 0x96, 0x01, 0x02, 0x26, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x04, 0x96, 0x01, 0x02, 0x06, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x04, 0x96, 0x01, 0x07, 0x21, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x03, 0x12, 0x04, 0x96, 0x01, 0x24, 0x25, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x07, 0x02, 0x02, 0x12, 0x04, 0x97, 0x01, 0x02, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x07, 0x02, 0x02, 0x05, 0x12, 0x04, 0x97, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, - 0x02, 0x02, 0x01, 0x12, 0x04, 0x97, 0x01, 0x09, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, - 0x02, 0x03, 0x12, 0x04, 0x97, 0x01, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x03, - 0x12, 0x04, 0x98, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x05, 0x12, - 0x04, 0x98, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x01, 0x12, 0x04, - 0x98, 0x01, 0x09, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x03, 0x12, 0x04, 0x98, - 0x01, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x06, 0x9b, 0x01, 0x00, 0x9e, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x01, 0x08, 0x17, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x25, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x08, 0x02, 0x00, 0x06, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x08, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x01, 0x19, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, - 0x02, 0x00, 0x03, 0x12, 0x04, 0x9c, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x08, 0x02, - 0x01, 0x12, 0x04, 0x9d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x04, - 0x12, 0x04, 0x9d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x06, 0x12, - 0x04, 0x9d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x01, 0x12, 0x04, - 0x9d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, 0x12, 0x04, 0x9d, - 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x06, 0xa0, 0x01, 0x00, 0xa6, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x09, 0x01, 0x12, 0x04, 0xa0, 0x01, 0x08, 0x0d, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x09, 0x02, 0x00, 0x06, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x09, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x01, 0x0b, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, - 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x01, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, - 0x01, 0x12, 0x04, 0xa2, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x05, - 0x12, 0x04, 0xa2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x01, 0x12, - 0x04, 0xa2, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x03, 0x12, 0x04, - 0xa2, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x08, 0x12, 0x04, 0xa2, - 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x09, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xa2, - 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x02, 0x12, 0x04, 0xa3, 0x01, 0x02, - 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x06, 0x12, 0x04, 0xa3, 0x01, 0x02, 0x0a, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x01, 0x12, 0x04, 0xa3, 0x01, 0x0b, 0x0f, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, 0x01, 0x12, 0x13, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x09, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x09, 0x02, 0x03, 0x05, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x09, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, - 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, - 0x04, 0x12, 0x04, 0xa5, 0x01, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x05, - 0x12, 0x04, 0xa5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x01, 0x12, - 0x04, 0xa5, 0x01, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x03, 0x12, 0x04, - 0xa5, 0x01, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x06, 0xa8, 0x01, 0x00, 0xb2, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x04, 0xa8, 0x01, 0x08, 0x17, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x11, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x01, 0x08, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa9, 0x01, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, - 0x02, 0x01, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, - 0x05, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x01, - 0x12, 0x04, 0xaa, 0x01, 0x08, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x03, 0x12, - 0x04, 0xaa, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x02, 0x12, 0x04, 0xab, - 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xab, 0x01, - 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01, 0x12, 0x04, 0xab, 0x01, 0x08, - 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xab, 0x01, 0x1a, 0x1b, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x03, 0x12, 0x04, 0xac, 0x01, 0x02, 0x2b, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x04, 0x12, 0x04, 0xac, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0a, 0x02, 0x03, 0x05, 0x12, 0x04, 0xac, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x01, 0x11, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xac, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, - 0x02, 0x04, 0x12, 0x04, 0xad, 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, - 0x05, 0x12, 0x04, 0xad, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x01, - 0x12, 0x04, 0xad, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x03, 0x12, - 0x04, 0xad, 0x01, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x04, - 0xad, 0x01, 0x16, 0x2a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x06, 0x12, 0x04, - 0xad, 0x01, 0x17, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x05, 0x12, 0x04, 0xae, 0x01, - 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x05, 0x12, 0x04, 0xae, 0x01, 0x02, - 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x01, 0x12, 0x04, 0xae, 0x01, 0x07, 0x0e, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x03, 0x12, 0x04, 0xae, 0x01, 0x11, 0x12, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x06, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x17, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0a, 0x02, 0x06, 0x05, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0xaf, 0x01, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x06, 0x03, 0x12, 0x04, 0xaf, 0x01, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, - 0x02, 0x07, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, - 0x05, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x01, - 0x12, 0x04, 0xb0, 0x01, 0x08, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x03, 0x12, - 0x04, 0xb0, 0x01, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x08, 0x12, 0x04, 0xb1, - 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x04, 0x12, 0x04, 0xb1, 0x01, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x06, 0x12, 0x04, 0xb1, 0x01, 0x0b, - 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x01, 0x12, 0x04, 0xb1, 0x01, 0x1a, 0x21, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x12, 0x04, 0xb1, 0x01, 0x24, 0x25, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x06, 0xb4, 0x01, 0x00, 0xb7, 0x01, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x0b, 0x01, 0x12, 0x04, 0xb4, 0x01, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, - 0x02, 0x00, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, - 0x05, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xb5, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xb5, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x12, 0x04, - 0xb5, 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x06, 0x12, 0x04, - 0xb5, 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x01, 0x12, 0x04, 0xb6, 0x01, - 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x05, 0x12, 0x04, 0xb6, 0x01, 0x02, - 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x01, 0x09, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x01, 0x1b, 0x1c, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x0c, 0x12, 0x06, 0xb9, 0x01, 0x00, 0xc1, 0x01, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x0c, 0x01, 0x12, 0x04, 0xb9, 0x01, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, - 0x02, 0x00, 0x12, 0x04, 0xba, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, - 0x05, 0x12, 0x04, 0xba, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xba, 0x01, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xba, 0x01, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x01, 0x12, 0x04, 0xbb, - 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xbb, 0x01, - 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbb, 0x01, 0x09, - 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbb, 0x01, 0x1b, 0x1c, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x04, 0xbb, 0x01, 0x1d, 0x31, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xbb, 0x01, 0x1e, 0x30, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x02, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0c, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0c, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbc, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0c, 0x02, 0x02, 0x03, 0x12, 0x04, 0xbc, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, - 0x02, 0x02, 0x08, 0x12, 0x04, 0xbc, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, - 0x02, 0x08, 0x06, 0x12, 0x04, 0xbc, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, - 0x03, 0x12, 0x04, 0xbd, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x05, - 0x12, 0x04, 0xbd, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x01, 0x12, - 0x04, 0xbd, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x03, 0x12, 0x04, - 0xbd, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x12, 0x04, 0xbd, - 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x06, 0x12, 0x04, 0xbd, - 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x04, 0x12, 0x04, 0xbe, 0x01, 0x02, - 0x3f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xbe, 0x01, 0x02, 0x20, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xbe, 0x01, 0x21, 0x3a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xbe, 0x01, 0x3d, 0x3e, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xbf, 0x01, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, - 0x02, 0x05, 0x03, 0x12, 0x04, 0xbf, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, - 0x06, 0x12, 0x04, 0xc0, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x06, - 0x12, 0x04, 0xc0, 0x01, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x01, 0x12, - 0x04, 0xc0, 0x01, 0x0c, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x03, 0x12, 0x04, - 0xc0, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x06, 0xc3, 0x01, 0x00, 0xcf, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0d, 0x01, 0x12, 0x04, 0xc3, 0x01, 0x08, 0x10, 0x0a, - 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x04, 0x00, 0x12, 0x06, 0xc4, 0x01, 0x02, 0xc8, 0x01, 0x03, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x04, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x01, 0x07, 0x13, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x23, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x1e, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc5, 0x01, 0x21, 0x22, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xc6, 0x01, 0x04, 0x28, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc6, 0x01, 0x04, - 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xc6, 0x01, - 0x26, 0x27, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xc7, 0x01, - 0x04, 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xc7, - 0x01, 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, - 0xc7, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12, 0x04, 0xca, 0x01, - 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x06, 0x12, 0x04, 0xca, 0x01, 0x02, - 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xca, 0x01, 0x0f, 0x1d, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xca, 0x01, 0x20, 0x21, 0x0a, - 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x08, 0x00, 0x12, 0x06, 0xcb, 0x01, 0x02, 0xce, 0x01, 0x03, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x08, 0x00, 0x01, 0x12, 0x04, 0xcb, 0x01, 0x08, 0x11, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xcc, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, - 0x02, 0x12, 0x04, 0xcd, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x06, - 0x12, 0x04, 0xcd, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x01, 0x12, - 0x04, 0xcd, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x03, 0x12, 0x04, - 0xcd, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0e, 0x12, 0x06, 0xd1, 0x01, 0x00, 0xd4, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0e, 0x01, 0x12, 0x04, 0xd1, 0x01, 0x08, 0x16, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x18, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x01, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd2, 0x01, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0e, - 0x02, 0x01, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, - 0x06, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x01, - 0x12, 0x04, 0xd3, 0x01, 0x10, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x03, 0x12, - 0x04, 0xd3, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06, 0xd6, 0x01, 0x00, - 0xd9, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0xd6, 0x01, 0x08, 0x16, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x2f, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x04, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd7, 0x01, 0x0b, 0x19, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x01, 0x1a, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd7, 0x01, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, - 0x02, 0x01, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, - 0x04, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x06, - 0x12, 0x04, 0xd8, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x01, 0x12, - 0x04, 0xd8, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x03, 0x12, 0x04, - 0xd8, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x10, 0x12, 0x06, 0xdb, 0x01, 0x00, 0xf0, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x10, 0x01, 0x12, 0x04, 0xdb, 0x01, 0x08, 0x16, 0x0a, - 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x04, 0x00, 0x12, 0x06, 0xdc, 0x01, 0x02, 0xe4, 0x01, 0x03, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdc, 0x01, 0x07, 0x0b, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x19, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x14, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdd, 0x01, 0x17, 0x18, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xde, 0x01, 0x04, 0x1b, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x01, 0x04, - 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xde, 0x01, - 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x01, - 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xdf, - 0x01, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, - 0xdf, 0x01, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, - 0xe0, 0x01, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, - 0x04, 0xe0, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x02, - 0x12, 0x04, 0xe0, 0x01, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x04, - 0x12, 0x04, 0xe1, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x04, - 0x01, 0x12, 0x04, 0xe1, 0x01, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, - 0x04, 0x02, 0x12, 0x04, 0xe1, 0x01, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, - 0x02, 0x05, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, - 0x02, 0x05, 0x01, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, - 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0xe2, 0x01, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, - 0x04, 0x00, 0x02, 0x06, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, - 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x10, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x04, 0xe3, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x10, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, - 0x02, 0x00, 0x06, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x00, 0x01, 0x12, 0x04, 0xe6, 0x01, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, - 0x03, 0x12, 0x04, 0xe6, 0x01, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x08, 0x00, 0x12, - 0x06, 0xe8, 0x01, 0x02, 0xef, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x08, 0x00, 0x01, - 0x12, 0x04, 0xe8, 0x01, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x01, 0x12, 0x04, - 0xe9, 0x01, 0x04, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe9, - 0x01, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x01, - 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x01, 0x21, - 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x02, 0x12, 0x04, 0xea, 0x01, 0x04, 0x27, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x01, 0x04, 0x12, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x01, 0x12, 0x04, 0xea, 0x01, 0x13, 0x22, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x10, 0x02, 0x02, 0x03, 0x12, 0x04, 0xea, 0x01, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x10, 0x02, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, - 0x02, 0x03, 0x06, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x03, 0x01, 0x12, 0x04, 0xeb, 0x01, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, - 0x03, 0x12, 0x04, 0xeb, 0x01, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x04, 0x12, - 0x04, 0xec, 0x01, 0x04, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x06, 0x12, 0x04, - 0xec, 0x01, 0x04, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x01, 0x12, 0x04, 0xec, - 0x01, 0x10, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x03, 0x12, 0x04, 0xec, 0x01, - 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x05, 0x12, 0x04, 0xed, 0x01, 0x04, 0x25, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x06, 0x12, 0x04, 0xed, 0x01, 0x04, 0x11, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x01, 0x12, 0x04, 0xed, 0x01, 0x12, 0x20, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x03, 0x12, 0x04, 0xed, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x10, 0x02, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x10, 0x02, 0x06, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, - 0x02, 0x06, 0x01, 0x12, 0x04, 0xee, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x06, 0x03, 0x12, 0x04, 0xee, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x11, 0x12, 0x06, - 0xf2, 0x01, 0x00, 0xf6, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x11, 0x01, 0x12, 0x04, 0xf2, - 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x00, 0x12, 0x04, 0xf3, 0x01, 0x02, - 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, 0x01, 0x02, 0x08, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x01, 0x09, 0x10, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x01, 0x13, 0x14, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x11, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x11, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x11, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, - 0x02, 0x12, 0x04, 0xf5, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x06, - 0x12, 0x04, 0xf5, 0x01, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x01, 0x12, - 0x04, 0xf5, 0x01, 0x0f, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x03, 0x12, 0x04, - 0xf5, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x12, 0x12, 0x06, 0xf8, 0x01, 0x00, 0xfd, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x12, 0x01, 0x12, 0x04, 0xf8, 0x01, 0x08, 0x16, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x15, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x12, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x01, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x12, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x01, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, - 0x02, 0x01, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, - 0x05, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x01, - 0x12, 0x04, 0xfa, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x03, 0x12, - 0x04, 0xfa, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x02, 0x12, 0x04, 0xfb, - 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x06, 0x12, 0x04, 0xfb, 0x01, - 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x01, 0x12, 0x04, 0xfb, 0x01, 0x10, - 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfb, 0x01, 0x17, 0x18, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x12, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x12, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x13, 0x12, 0x06, 0xff, 0x01, 0x00, 0x84, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x13, 0x01, - 0x12, 0x04, 0xff, 0x01, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x00, 0x12, 0x04, - 0x80, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x05, 0x12, 0x04, 0x80, - 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x01, 0x12, 0x04, 0x80, 0x02, - 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x03, 0x12, 0x04, 0x80, 0x02, 0x19, - 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x01, 0x12, 0x04, 0x81, 0x02, 0x02, 0x14, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x05, 0x12, 0x04, 0x81, 0x02, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x01, 0x12, 0x04, 0x81, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x13, 0x02, 0x01, 0x03, 0x12, 0x04, 0x81, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x13, 0x02, 0x02, 0x12, 0x04, 0x82, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, - 0x02, 0x02, 0x05, 0x12, 0x04, 0x82, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, - 0x02, 0x01, 0x12, 0x04, 0x82, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x02, - 0x03, 0x12, 0x04, 0x82, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x03, 0x12, - 0x04, 0x83, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x06, 0x12, 0x04, - 0x83, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x01, 0x12, 0x04, 0x83, - 0x02, 0x12, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x03, 0x12, 0x04, 0x83, 0x02, - 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x14, 0x12, 0x06, 0x86, 0x02, 0x00, 0x89, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x14, 0x01, 0x12, 0x04, 0x86, 0x02, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x14, 0x02, 0x00, 0x12, 0x04, 0x87, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x14, 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, - 0x02, 0x00, 0x01, 0x12, 0x04, 0x87, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, - 0x00, 0x03, 0x12, 0x04, 0x87, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x01, - 0x12, 0x04, 0x88, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x05, 0x12, - 0x04, 0x88, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x01, 0x12, 0x04, - 0x88, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x03, 0x12, 0x04, 0x88, - 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x15, 0x12, 0x06, 0x8b, 0x02, 0x00, 0x8f, 0x02, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x15, 0x01, 0x12, 0x04, 0x8b, 0x02, 0x08, 0x13, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x15, 0x02, 0x00, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x15, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x15, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8c, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, - 0x02, 0x00, 0x03, 0x12, 0x04, 0x8c, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, - 0x01, 0x12, 0x04, 0x8d, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x05, - 0x12, 0x04, 0x8d, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x01, 0x12, - 0x04, 0x8d, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x03, 0x12, 0x04, - 0x8d, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x02, 0x12, 0x04, 0x8e, 0x02, - 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x06, 0x12, 0x04, 0x8e, 0x02, 0x02, - 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x01, 0x12, 0x04, 0x8e, 0x02, 0x15, 0x19, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8e, 0x02, 0x1c, 0x1d, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x16, 0x12, 0x06, 0x91, 0x02, 0x00, 0x97, 0x02, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x16, 0x01, 0x12, 0x04, 0x91, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, - 0x02, 0x00, 0x12, 0x04, 0x92, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, - 0x05, 0x12, 0x04, 0x92, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x01, - 0x12, 0x04, 0x92, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x03, 0x12, - 0x04, 0x92, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x01, 0x12, 0x04, 0x93, - 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x05, 0x12, 0x04, 0x93, 0x02, - 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x01, 0x12, 0x04, 0x93, 0x02, 0x08, - 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x03, 0x12, 0x04, 0x93, 0x02, 0x19, 0x1a, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x02, 0x12, 0x04, 0x94, 0x02, 0x02, 0x19, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x06, 0x12, 0x04, 0x94, 0x02, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x16, 0x02, 0x02, 0x01, 0x12, 0x04, 0x94, 0x02, 0x10, 0x14, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x16, 0x02, 0x02, 0x03, 0x12, 0x04, 0x94, 0x02, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x16, 0x02, 0x03, 0x12, 0x04, 0x95, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, - 0x03, 0x05, 0x12, 0x04, 0x95, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, - 0x01, 0x12, 0x04, 0x95, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, 0x03, - 0x12, 0x04, 0x95, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x04, 0x12, 0x04, - 0x96, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x05, 0x12, 0x04, 0x96, - 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x01, 0x12, 0x04, 0x96, 0x02, - 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x03, 0x12, 0x04, 0x96, 0x02, 0x10, - 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x17, 0x12, 0x06, 0x99, 0x02, 0x00, 0x9e, 0x02, 0x01, 0x0a, - 0x0b, 0x0a, 0x03, 0x04, 0x17, 0x01, 0x12, 0x04, 0x99, 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x17, 0x02, 0x00, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, - 0x02, 0x00, 0x05, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, - 0x00, 0x01, 0x12, 0x04, 0x9a, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x00, - 0x03, 0x12, 0x04, 0x9a, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x01, 0x12, - 0x04, 0x9b, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x05, 0x12, 0x04, - 0x9b, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9b, - 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x03, 0x12, 0x04, 0x9b, 0x02, - 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x02, 0x12, 0x04, 0x9c, 0x02, 0x02, 0x13, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x05, 0x12, 0x04, 0x9c, 0x02, 0x02, 0x08, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x01, 0x12, 0x04, 0x9c, 0x02, 0x09, 0x0e, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x03, 0x12, 0x04, 0x9c, 0x02, 0x11, 0x12, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x17, 0x02, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x17, 0x02, 0x03, 0x05, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, - 0x02, 0x03, 0x01, 0x12, 0x04, 0x9d, 0x02, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, - 0x03, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x18, 0x12, 0x06, - 0xa0, 0x02, 0x00, 0xa5, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x18, 0x01, 0x12, 0x04, 0xa0, - 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x02, 0x02, - 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa1, 0x02, 0x02, 0x07, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x02, 0x08, 0x16, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x02, 0x19, 0x1a, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x18, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x18, 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x18, 0x02, 0x01, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xa2, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, - 0x02, 0x12, 0x04, 0xa3, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x05, - 0x12, 0x04, 0xa3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x01, 0x12, - 0x04, 0xa3, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x03, 0x12, 0x04, - 0xa3, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x02, - 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x06, 0x12, 0x04, 0xa4, 0x02, 0x02, - 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x02, 0x11, 0x15, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x02, 0x18, 0x19, 0x0a, - 0xa1, 0x01, 0x0a, 0x02, 0x04, 0x19, 0x12, 0x06, 0xa9, 0x02, 0x00, 0xc0, 0x02, 0x01, 0x1a, 0x92, - 0x01, 0x20, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4e, 0x6f, 0x74, 0x20, - 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x77, 0x61, 0x79, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x20, - 0x68, 0x65, 0x72, 0x65, 0x2e, 0x20, 0x0a, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x72, 0x65, - 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x2e, 0x20, 0x50, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x2e, 0x0a, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x19, 0x01, 0x12, 0x04, 0xa9, 0x02, 0x08, 0x1a, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x04, 0x00, 0x12, 0x06, 0xaa, 0x02, 0x02, 0xb1, 0x02, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, 0x00, 0x01, 0x12, 0x04, 0xaa, 0x02, 0x07, 0x0b, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xab, 0x02, 0x04, 0x19, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xab, 0x02, 0x04, 0x14, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xab, 0x02, 0x17, - 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xac, 0x02, 0x04, - 0x24, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xac, 0x02, - 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xac, - 0x02, 0x22, 0x23, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xad, - 0x02, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xad, 0x02, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0xad, 0x02, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x12, - 0x04, 0xae, 0x02, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xae, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, - 0x02, 0x12, 0x04, 0xae, 0x02, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, - 0x04, 0x12, 0x04, 0xaf, 0x02, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, - 0x04, 0x01, 0x12, 0x04, 0xaf, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, - 0x02, 0x04, 0x02, 0x12, 0x04, 0xaf, 0x02, 0x1c, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, - 0x00, 0x04, 0x12, 0x04, 0xb0, 0x02, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, - 0x04, 0x00, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, - 0x04, 0x00, 0x01, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, - 0x00, 0x04, 0x00, 0x02, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, - 0x02, 0x00, 0x12, 0x04, 0xb3, 0x02, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xb3, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xb3, 0x02, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xb3, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x08, 0x00, 0x12, 0x06, 0xb5, - 0x02, 0x02, 0xba, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x08, 0x00, 0x01, 0x12, 0x04, - 0xb5, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x01, 0x12, 0x04, 0xb6, 0x02, - 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb6, 0x02, 0x04, - 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x02, 0x19, 0x2f, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x02, 0x32, 0x33, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x25, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x19, 0x02, 0x02, 0x06, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x19, 0x02, 0x02, 0x01, 0x12, 0x04, 0xb7, 0x02, 0x12, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x19, 0x02, 0x02, 0x03, 0x12, 0x04, 0xb7, 0x02, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, - 0x02, 0x03, 0x12, 0x04, 0xb8, 0x02, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, - 0x06, 0x12, 0x04, 0xb8, 0x02, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xb8, 0x02, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x03, 0x12, - 0x04, 0xb8, 0x02, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x04, 0x12, 0x04, 0xb9, - 0x02, 0x04, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x06, 0x12, 0x04, 0xb9, 0x02, - 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x01, 0x12, 0x04, 0xb9, 0x02, 0x14, - 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x03, 0x12, 0x04, 0xb9, 0x02, 0x27, 0x28, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x19, 0x09, 0x12, 0x04, 0xbb, 0x02, 0x02, 0x0d, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x19, 0x09, 0x00, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x19, 0x09, 0x00, 0x01, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, - 0x09, 0x00, 0x02, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x08, - 0x01, 0x12, 0x06, 0xbd, 0x02, 0x02, 0xbf, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x08, - 0x01, 0x01, 0x12, 0x04, 0xbd, 0x02, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x05, - 0x12, 0x04, 0xbe, 0x02, 0x04, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x05, 0x06, 0x12, - 0x04, 0xbe, 0x02, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x05, 0x01, 0x12, 0x04, - 0xbe, 0x02, 0x12, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x05, 0x03, 0x12, 0x04, 0xbe, - 0x02, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1a, 0x12, 0x06, 0xc2, 0x02, 0x00, 0xc5, 0x02, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1a, 0x01, 0x12, 0x04, 0xc2, 0x02, 0x08, 0x15, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x00, 0x12, 0x04, 0xc3, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1a, 0x02, 0x00, 0x04, 0x12, 0x04, 0xc3, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc3, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xc3, 0x02, 0x12, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xc3, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x01, - 0x12, 0x04, 0xc4, 0x02, 0x02, 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x04, 0x12, - 0x04, 0xc4, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x05, 0x12, 0x04, - 0xc4, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc4, - 0x02, 0x12, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc4, 0x02, - 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1b, 0x12, 0x06, 0xc7, 0x02, 0x00, 0xcc, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1b, 0x01, 0x12, 0x04, 0xc7, 0x02, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1b, 0x02, 0x00, 0x12, 0x04, 0xc8, 0x02, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1b, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc8, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xc8, 0x02, 0x12, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xc8, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x01, - 0x12, 0x04, 0xc9, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x04, 0x12, - 0x04, 0xc9, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x06, 0x12, 0x04, - 0xc9, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc9, - 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc9, 0x02, - 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x02, 0x12, 0x04, 0xca, 0x02, 0x02, 0x20, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x04, 0x12, 0x04, 0xca, 0x02, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x05, 0x12, 0x04, 0xca, 0x02, 0x0b, 0x11, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x01, 0x12, 0x04, 0xca, 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1b, 0x02, 0x02, 0x03, 0x12, 0x04, 0xca, 0x02, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x1b, 0x02, 0x03, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, - 0x02, 0x03, 0x05, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, - 0x03, 0x01, 0x12, 0x04, 0xcb, 0x02, 0x09, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x03, - 0x03, 0x12, 0x04, 0xcb, 0x02, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1c, 0x12, 0x06, 0xce, - 0x02, 0x00, 0xd1, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1c, 0x01, 0x12, 0x04, 0xce, 0x02, - 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x00, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x15, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x05, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x07, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcf, 0x02, 0x08, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcf, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1c, 0x02, 0x01, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xd0, 0x02, 0x0f, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xd0, 0x02, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1d, 0x12, 0x06, - 0xd3, 0x02, 0x00, 0xd7, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1d, 0x01, 0x12, 0x04, 0xd3, - 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x00, 0x12, 0x04, 0xd4, 0x02, 0x02, - 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd4, 0x02, 0x02, 0x14, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd4, 0x02, 0x15, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd4, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xd5, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd5, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xd5, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x02, - 0x12, 0x04, 0xd6, 0x02, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x04, 0x12, - 0x04, 0xd6, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x05, 0x12, 0x04, - 0xd6, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x01, 0x12, 0x04, 0xd6, - 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x03, 0x12, 0x04, 0xd6, 0x02, - 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1e, 0x12, 0x06, 0xd9, 0x02, 0x00, 0xdc, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1e, 0x01, 0x12, 0x04, 0xd9, 0x02, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1e, 0x02, 0x00, 0x12, 0x04, 0xda, 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xda, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xda, 0x02, 0x09, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xda, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1e, 0x02, 0x01, - 0x12, 0x04, 0xdb, 0x02, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x04, 0x12, - 0x04, 0xdb, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x06, 0x12, 0x04, - 0xdb, 0x02, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x01, 0x12, 0x04, 0xdb, - 0x02, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x03, 0x12, 0x04, 0xdb, 0x02, - 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1f, 0x12, 0x06, 0xde, 0x02, 0x00, 0xe9, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1f, 0x01, 0x12, 0x04, 0xde, 0x02, 0x08, 0x22, 0x0a, 0x0e, 0x0a, - 0x04, 0x04, 0x1f, 0x04, 0x00, 0x12, 0x06, 0xdf, 0x02, 0x02, 0xe2, 0x02, 0x03, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1f, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdf, 0x02, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xe0, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe0, 0x02, 0x04, 0x14, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xe0, 0x02, 0x17, 0x18, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xe1, 0x02, 0x04, 0x24, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe1, 0x02, 0x04, 0x1f, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xe1, 0x02, 0x22, 0x23, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1f, 0x02, 0x00, 0x12, 0x04, 0xe4, 0x02, 0x02, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe4, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe4, 0x02, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe4, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, - 0x1f, 0x08, 0x00, 0x12, 0x06, 0xe6, 0x02, 0x02, 0xe8, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1f, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1f, - 0x02, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x01, - 0x06, 0x12, 0x04, 0xe7, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x01, 0x01, - 0x12, 0x04, 0xe7, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x01, 0x03, 0x12, - 0x04, 0xe7, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x20, 0x12, 0x06, 0xeb, 0x02, 0x00, - 0xee, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x20, 0x01, 0x12, 0x04, 0xeb, 0x02, 0x08, 0x1a, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x00, 0x12, 0x04, 0xec, 0x02, 0x02, 0x15, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x05, 0x12, 0x04, 0xec, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x20, 0x02, 0x00, 0x01, 0x12, 0x04, 0xec, 0x02, 0x08, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x20, 0x02, 0x00, 0x03, 0x12, 0x04, 0xec, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x20, 0x02, 0x01, 0x12, 0x04, 0xed, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, - 0x01, 0x06, 0x12, 0x04, 0xed, 0x02, 0x02, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x01, - 0x01, 0x12, 0x04, 0xed, 0x02, 0x0d, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x01, 0x03, - 0x12, 0x04, 0xed, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x21, 0x12, 0x06, 0xf0, 0x02, - 0x00, 0xf6, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x21, 0x01, 0x12, 0x04, 0xf0, 0x02, 0x08, - 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x00, 0x12, 0x04, 0xf1, 0x02, 0x02, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf1, 0x02, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf1, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x21, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf1, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x21, 0x02, 0x01, 0x12, 0x04, 0xf2, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, - 0x02, 0x01, 0x05, 0x12, 0x04, 0xf2, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, - 0x01, 0x01, 0x12, 0x04, 0xf2, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, - 0x03, 0x12, 0x04, 0xf2, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x02, 0x12, - 0x04, 0xf3, 0x02, 0x02, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x04, 0x12, 0x04, - 0xf3, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x06, 0x12, 0x04, 0xf3, - 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x01, 0x12, 0x04, 0xf3, 0x02, - 0x18, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x03, 0x12, 0x04, 0xf3, 0x02, 0x22, - 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x03, 0x12, 0x04, 0xf4, 0x02, 0x02, 0x2e, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x04, 0x12, 0x04, 0xf4, 0x02, 0x02, 0x0a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x06, 0x12, 0x04, 0xf4, 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x21, 0x02, 0x03, 0x01, 0x12, 0x04, 0xf4, 0x02, 0x18, 0x29, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x21, 0x02, 0x03, 0x03, 0x12, 0x04, 0xf4, 0x02, 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x21, 0x02, 0x04, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, - 0x04, 0x04, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, - 0x06, 0x12, 0x04, 0xf5, 0x02, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x01, - 0x12, 0x04, 0xf5, 0x02, 0x16, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x03, 0x12, - 0x04, 0xf5, 0x02, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x22, 0x12, 0x06, 0xf7, 0x02, 0x00, - 0x84, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x22, 0x01, 0x12, 0x04, 0xf7, 0x02, 0x08, 0x14, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x22, 0x04, 0x00, 0x12, 0x06, 0xf8, 0x02, 0x02, 0xfd, 0x02, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x04, 0x00, 0x01, 0x12, 0x04, 0xf8, 0x02, 0x07, 0x11, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x02, 0x04, 0x1f, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x02, 0x04, 0x1a, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xf9, 0x02, 0x1d, - 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xfa, 0x02, 0x04, - 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xfa, 0x02, - 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xfa, - 0x02, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xfb, - 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xfb, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0xfb, 0x02, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x03, 0x12, - 0x04, 0xfc, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xfc, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x03, - 0x02, 0x12, 0x04, 0xfc, 0x02, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x00, 0x12, - 0x04, 0xfe, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x05, 0x12, 0x04, - 0xfe, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfe, - 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfe, 0x02, - 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x01, 0x12, 0x04, 0xff, 0x02, 0x02, 0x29, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x06, 0x12, 0x04, 0xff, 0x02, 0x02, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x01, 0x12, 0x04, 0xff, 0x02, 0x1a, 0x24, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x03, 0x12, 0x04, 0xff, 0x02, 0x27, 0x28, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x22, 0x02, 0x02, 0x12, 0x04, 0x80, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x22, 0x02, 0x02, 0x05, 0x12, 0x04, 0x80, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, - 0x02, 0x02, 0x01, 0x12, 0x04, 0x80, 0x03, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, - 0x02, 0x03, 0x12, 0x04, 0x80, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x03, - 0x12, 0x04, 0x81, 0x03, 0x02, 0x40, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x04, 0x12, - 0x04, 0x81, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x06, 0x12, 0x04, - 0x81, 0x03, 0x0b, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x01, 0x12, 0x04, 0x81, - 0x03, 0x28, 0x3b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x03, 0x12, 0x04, 0x81, 0x03, - 0x3e, 0x3f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x04, 0x12, 0x04, 0x82, 0x03, 0x02, 0x1f, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x04, 0x12, 0x04, 0x82, 0x03, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x06, 0x12, 0x04, 0x82, 0x03, 0x0b, 0x13, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x01, 0x12, 0x04, 0x82, 0x03, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x22, 0x02, 0x04, 0x03, 0x12, 0x04, 0x82, 0x03, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x22, 0x02, 0x05, 0x12, 0x04, 0x83, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, - 0x02, 0x05, 0x04, 0x12, 0x04, 0x83, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, - 0x05, 0x06, 0x12, 0x04, 0x83, 0x03, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, - 0x01, 0x12, 0x04, 0x83, 0x03, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x03, - 0x12, 0x04, 0x83, 0x03, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x23, 0x12, 0x06, 0x86, 0x03, - 0x00, 0x8d, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x23, 0x01, 0x12, 0x04, 0x86, 0x03, 0x08, - 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x00, 0x12, 0x04, 0x87, 0x03, 0x02, 0x12, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x03, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x01, 0x12, 0x04, 0x87, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x23, 0x02, 0x00, 0x03, 0x12, 0x04, 0x87, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x23, 0x02, 0x01, 0x12, 0x04, 0x88, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, - 0x02, 0x01, 0x05, 0x12, 0x04, 0x88, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, - 0x01, 0x01, 0x12, 0x04, 0x88, 0x03, 0x07, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, - 0x03, 0x12, 0x04, 0x88, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x02, 0x12, - 0x04, 0x89, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, 0x05, 0x12, 0x04, - 0x89, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, 0x01, 0x12, 0x04, 0x89, - 0x03, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, 0x03, 0x12, 0x04, 0x89, 0x03, - 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x03, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x25, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x04, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x06, 0x12, 0x04, 0x8a, 0x03, 0x0b, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x01, 0x12, 0x04, 0x8a, 0x03, 0x17, 0x20, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x23, 0x02, 0x03, 0x03, 0x12, 0x04, 0x8a, 0x03, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x23, 0x02, 0x04, 0x12, 0x04, 0x8b, 0x03, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, - 0x02, 0x04, 0x04, 0x12, 0x04, 0x8b, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, - 0x04, 0x06, 0x12, 0x04, 0x8b, 0x03, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x04, - 0x01, 0x12, 0x04, 0x8b, 0x03, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x04, 0x03, - 0x12, 0x04, 0x8b, 0x03, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x05, 0x12, 0x04, - 0x8c, 0x03, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x04, 0x12, 0x04, 0x8c, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x06, 0x12, 0x04, 0x8c, 0x03, - 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x01, 0x12, 0x04, 0x8c, 0x03, 0x1b, - 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x03, 0x12, 0x04, 0x8c, 0x03, 0x24, 0x25, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x24, 0x12, 0x06, 0x8f, 0x03, 0x00, 0x92, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x24, 0x01, 0x12, 0x04, 0x8f, 0x03, 0x08, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x24, 0x02, 0x00, 0x12, 0x04, 0x90, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, - 0x00, 0x04, 0x12, 0x04, 0x90, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, - 0x06, 0x12, 0x04, 0x90, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x01, - 0x12, 0x04, 0x90, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x03, 0x12, - 0x04, 0x90, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x24, 0x02, 0x01, 0x12, 0x04, 0x91, - 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x05, 0x12, 0x04, 0x91, 0x03, - 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x01, 0x12, 0x04, 0x91, 0x03, 0x07, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x03, 0x12, 0x04, 0x91, 0x03, 0x14, 0x15, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x25, 0x12, 0x06, 0x94, 0x03, 0x00, 0x97, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x25, 0x01, 0x12, 0x04, 0x94, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x25, 0x02, 0x00, 0x12, 0x04, 0x95, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, - 0x00, 0x05, 0x12, 0x04, 0x95, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, - 0x01, 0x12, 0x04, 0x95, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x95, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x25, 0x02, 0x01, 0x12, 0x04, - 0x96, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x06, 0x12, 0x04, 0x96, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x01, 0x12, 0x04, 0x96, 0x03, - 0x0b, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x03, 0x12, 0x04, 0x96, 0x03, 0x12, - 0x13, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x26, 0x12, 0x06, 0x99, 0x03, 0x00, 0x9b, 0x03, 0x01, 0x0a, - 0x0b, 0x0a, 0x03, 0x04, 0x26, 0x01, 0x12, 0x04, 0x99, 0x03, 0x08, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x26, 0x02, 0x00, 0x12, 0x04, 0x9a, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, - 0x02, 0x00, 0x04, 0x12, 0x04, 0x9a, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, - 0x00, 0x06, 0x12, 0x04, 0x9a, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, - 0x01, 0x12, 0x04, 0x9a, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x9a, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x06, 0x9d, 0x03, - 0x00, 0xad, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x04, 0x9d, 0x03, 0x05, - 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x04, 0x9e, 0x03, 0x02, 0x1d, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9e, 0x03, 0x02, 0x18, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x9e, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x01, 0x02, 0x12, 0x04, 0x9f, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x02, 0x12, 0x04, 0xa0, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xa0, 0x03, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0xa0, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x03, 0x12, 0x04, 0xa1, - 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa1, 0x03, - 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xa1, 0x03, 0x13, - 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x04, 0x12, 0x04, 0xa2, 0x03, 0x02, 0x16, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xa2, 0x03, 0x02, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xa2, 0x03, 0x13, 0x15, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x05, 0x12, 0x04, 0xa3, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0xa3, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x05, 0x02, 0x12, 0x04, 0xa3, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x06, 0x12, 0x04, 0xa4, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x01, - 0x12, 0x04, 0xa4, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x02, 0x12, - 0x04, 0xa4, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x07, 0x12, 0x04, 0xa5, - 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x01, 0x12, 0x04, 0xa5, 0x03, - 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x02, 0x12, 0x04, 0xa5, 0x03, 0x14, - 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x08, 0x12, 0x04, 0xa6, 0x03, 0x02, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x01, 0x12, 0x04, 0xa6, 0x03, 0x02, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x02, 0x12, 0x04, 0xa6, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x09, 0x12, 0x04, 0xa7, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x09, 0x01, 0x12, 0x04, 0xa7, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x09, 0x02, 0x12, 0x04, 0xa7, 0x03, 0x16, 0x17, 0x0a, 0x2b, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x0a, 0x12, 0x04, 0xa8, 0x03, 0x02, 0x18, 0x22, 0x1d, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x3a, 0x20, 0x42, 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x3e, 0x20, 0x7d, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x01, 0x12, - 0x04, 0xa8, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x02, 0x12, 0x04, - 0xa8, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0b, 0x12, 0x04, 0xa9, 0x03, - 0x02, 0x18, 0x22, 0x14, 0x20, 0x60, 0x28, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x54, 0x61, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, - 0x01, 0x12, 0x04, 0xa9, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, 0x02, - 0x12, 0x04, 0xa9, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0c, 0x12, 0x04, - 0xaa, 0x03, 0x02, 0x24, 0x22, 0x14, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, - 0x20, 0x75, 0x31, 0x36, 0x20, 0x7d, 0x60, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x0c, 0x01, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, - 0x0c, 0x02, 0x12, 0x04, 0xaa, 0x03, 0x22, 0x23, 0x0a, 0x37, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0d, - 0x12, 0x04, 0xab, 0x03, 0x02, 0x1c, 0x22, 0x29, 0x20, 0x60, 0x7b, 0x20, 0x6d, 0x75, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x74, 0x6f, 0x3a, 0x20, 0x42, - 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3e, 0x20, 0x7d, 0x60, 0x2c, - 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x01, 0x12, 0x04, 0xab, 0x03, 0x02, 0x16, - 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x02, 0x12, 0x04, 0xab, 0x03, 0x19, 0x1b, 0x0a, - 0x1b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0e, 0x12, 0x04, 0xac, 0x03, 0x02, 0x1d, 0x22, 0x0d, 0x20, - 0x60, 0x28, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x05, 0x00, 0x02, 0x0e, 0x01, 0x12, 0x04, 0xac, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x0e, 0x02, 0x12, 0x04, 0xac, 0x03, 0x1a, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x27, - 0x12, 0x06, 0xaf, 0x03, 0x00, 0xbd, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x27, 0x01, 0x12, - 0x04, 0xaf, 0x03, 0x08, 0x10, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x27, 0x03, 0x00, 0x12, 0x06, 0xb0, - 0x03, 0x02, 0xb3, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x03, 0x00, 0x01, 0x12, 0x04, - 0xb0, 0x03, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, - 0xb1, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, - 0x04, 0xb1, 0x03, 0x04, 0x08, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xb1, 0x03, 0x09, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, - 0x03, 0x12, 0x04, 0xb1, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x27, 0x03, 0x00, 0x02, - 0x01, 0x12, 0x04, 0xb2, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, - 0x01, 0x06, 0x12, 0x04, 0xb2, 0x03, 0x04, 0x0c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xb2, 0x03, 0x0d, 0x0f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, - 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb2, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, - 0x02, 0x00, 0x12, 0x04, 0xb5, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xb5, 0x03, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xb5, 0x03, 0x0c, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xb5, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x27, 0x08, 0x00, 0x12, 0x06, 0xb6, - 0x03, 0x02, 0xbc, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x08, 0x00, 0x01, 0x12, 0x04, - 0xb6, 0x03, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x01, 0x12, 0x04, 0xb7, 0x03, - 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb7, 0x03, 0x04, - 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb7, 0x03, 0x0d, 0x13, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb7, 0x03, 0x16, 0x17, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x02, 0x12, 0x04, 0xb8, 0x03, 0x04, 0x1d, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x27, 0x02, 0x02, 0x06, 0x12, 0x04, 0xb8, 0x03, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x27, 0x02, 0x02, 0x01, 0x12, 0x04, 0xb8, 0x03, 0x12, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x27, 0x02, 0x02, 0x03, 0x12, 0x04, 0xb8, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, - 0x02, 0x03, 0x12, 0x04, 0xb9, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, - 0x05, 0x12, 0x04, 0xb9, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xb9, 0x03, 0x0b, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, 0x03, 0x12, - 0x04, 0xb9, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x04, 0x12, 0x04, 0xba, - 0x03, 0x04, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x06, 0x12, 0x04, 0xba, 0x03, - 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x01, 0x12, 0x04, 0xba, 0x03, 0x12, - 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x03, 0x12, 0x04, 0xba, 0x03, 0x1e, 0x1f, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x05, 0x12, 0x04, 0xbb, 0x03, 0x04, 0x1a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x27, 0x02, 0x05, 0x05, 0x12, 0x04, 0xbb, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x27, 0x02, 0x05, 0x01, 0x12, 0x04, 0xbb, 0x03, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x27, 0x02, 0x05, 0x03, 0x12, 0x04, 0xbb, 0x03, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x05, - 0x01, 0x12, 0x06, 0xbf, 0x03, 0x00, 0xc5, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x01, 0x01, - 0x12, 0x04, 0xbf, 0x03, 0x05, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x00, 0x12, 0x04, - 0xc0, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc0, - 0x03, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc0, 0x03, - 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x01, 0x12, 0x04, 0xc1, 0x03, 0x02, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc1, 0x03, 0x02, 0x13, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x02, 0x12, 0x04, 0xc1, 0x03, 0x16, 0x17, 0x0a, 0x0c, - 0x0a, 0x04, 0x05, 0x01, 0x02, 0x02, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, - 0x05, 0x01, 0x02, 0x02, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x01, 0x02, 0x02, 0x02, 0x12, 0x04, 0xc2, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, - 0x02, 0x03, 0x12, 0x04, 0xc3, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, - 0x01, 0x12, 0x04, 0xc3, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, 0x02, - 0x12, 0x04, 0xc3, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x04, 0x12, 0x04, - 0xc4, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x01, 0x12, 0x04, 0xc4, - 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x02, 0x12, 0x04, 0xc4, 0x03, - 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x28, 0x12, 0x06, 0xc7, 0x03, 0x00, 0xc9, 0x03, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x28, 0x01, 0x12, 0x04, 0xc7, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x28, 0x02, 0x00, 0x12, 0x04, 0xc8, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x28, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc8, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xc8, 0x03, 0x0b, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xc8, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x29, 0x12, 0x06, - 0xcb, 0x03, 0x00, 0xce, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x29, 0x01, 0x12, 0x04, 0xcb, - 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x00, 0x12, 0x04, 0xcc, 0x03, 0x02, - 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x06, 0x12, 0x04, 0xcc, 0x03, 0x02, 0x0e, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x0f, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcc, 0x03, 0x18, 0x19, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x29, 0x02, 0x01, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x29, 0x02, 0x01, 0x05, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x29, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcd, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xcd, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2a, 0x12, - 0x06, 0xd0, 0x03, 0x00, 0xd3, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2a, 0x01, 0x12, 0x04, - 0xd0, 0x03, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x00, 0x12, 0x04, 0xd1, 0x03, - 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd1, 0x03, 0x02, - 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd1, 0x03, 0x09, 0x10, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd1, 0x03, 0x13, 0x14, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x01, 0x12, 0x04, 0xd2, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd2, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd2, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd2, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2b, - 0x12, 0x06, 0xd5, 0x03, 0x00, 0xda, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2b, 0x01, 0x12, - 0x04, 0xd5, 0x03, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x00, 0x12, 0x04, 0xd6, - 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd6, 0x03, - 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd6, 0x03, 0x09, - 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd6, 0x03, 0x13, 0x14, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x01, 0x12, 0x04, 0xd7, 0x03, 0x02, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd7, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd7, 0x03, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd7, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x2b, 0x02, 0x02, 0x12, 0x04, 0xd8, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, - 0x02, 0x05, 0x12, 0x04, 0xd8, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, - 0x01, 0x12, 0x04, 0xd8, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, 0x03, - 0x12, 0x04, 0xd8, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x03, 0x12, 0x04, - 0xd9, 0x03, 0x02, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x04, 0x12, 0x04, 0xd9, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x06, 0x12, 0x04, 0xd9, 0x03, - 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x01, 0x12, 0x04, 0xd9, 0x03, 0x14, - 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x03, 0x12, 0x04, 0xd9, 0x03, 0x2a, 0x2b, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2c, 0x12, 0x06, 0xdc, 0x03, 0x00, 0xf0, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x2c, 0x01, 0x12, 0x04, 0xdc, 0x03, 0x08, 0x11, 0x0a, 0x0e, 0x0a, 0x04, 0x04, - 0x2c, 0x04, 0x00, 0x12, 0x06, 0xdd, 0x03, 0x02, 0xe5, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2c, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x03, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, - 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xde, 0x03, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, - 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xde, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x2c, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xde, 0x03, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x2c, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x2c, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x10, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xdf, 0x03, 0x13, 0x14, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xe0, 0x03, 0x04, 0x1b, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xe0, 0x03, 0x04, 0x16, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xe0, 0x03, 0x19, 0x1a, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xe1, 0x03, 0x04, 0x19, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe1, 0x03, 0x04, - 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xe1, 0x03, - 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xe2, 0x03, - 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe2, - 0x03, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, - 0xe2, 0x03, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, - 0xe3, 0x03, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, - 0x04, 0xe3, 0x03, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x02, - 0x12, 0x04, 0xe3, 0x03, 0x19, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x12, - 0x04, 0xe4, 0x03, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, 0x12, - 0x04, 0xe4, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, 0x01, - 0x12, 0x04, 0xe4, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, - 0x02, 0x12, 0x04, 0xe4, 0x03, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x00, 0x12, - 0x04, 0xe7, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x06, 0x12, 0x04, - 0xe7, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe7, - 0x03, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe7, 0x03, - 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x2c, 0x08, 0x00, 0x12, 0x06, 0xe8, 0x03, 0x02, 0xef, - 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x03, 0x08, - 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x04, 0x21, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe9, 0x03, 0x04, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x03, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x2c, 0x02, 0x02, 0x12, 0x04, 0xea, 0x03, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, - 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x03, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, - 0x02, 0x01, 0x12, 0x04, 0xea, 0x03, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x02, - 0x03, 0x12, 0x04, 0xea, 0x03, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x03, 0x12, - 0x04, 0xeb, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x06, 0x12, 0x04, - 0xeb, 0x03, 0x04, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x01, 0x12, 0x04, 0xeb, - 0x03, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x03, 0x12, 0x04, 0xeb, 0x03, - 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x04, 0x12, 0x04, 0xec, 0x03, 0x04, 0x24, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xec, 0x03, 0x04, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xec, 0x03, 0x16, 0x1f, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xec, 0x03, 0x22, 0x23, 0x0a, 0x1e, 0x0a, - 0x04, 0x04, 0x2c, 0x02, 0x05, 0x12, 0x04, 0xee, 0x03, 0x04, 0x23, 0x1a, 0x10, 0x20, 0x36, 0x20, - 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xee, 0x03, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xee, 0x03, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2c, 0x02, 0x05, 0x03, 0x12, 0x04, 0xee, 0x03, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2d, - 0x12, 0x06, 0xf2, 0x03, 0x00, 0xf5, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2d, 0x01, 0x12, - 0x04, 0xf2, 0x03, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x00, 0x12, 0x04, 0xf3, - 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, 0x03, - 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x03, 0x08, - 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x03, 0x15, 0x16, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x07, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x03, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x2e, 0x12, 0x06, 0xf7, 0x03, 0x00, 0xfc, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2e, 0x01, - 0x12, 0x04, 0xf7, 0x03, 0x08, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x00, 0x12, 0x04, - 0xf8, 0x03, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x04, 0x12, 0x04, 0xf8, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf8, 0x03, - 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf8, 0x03, 0x11, - 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf8, 0x03, 0x1f, 0x20, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x01, 0x12, 0x04, 0xf9, 0x03, 0x02, 0x20, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x04, 0x12, 0x04, 0xf9, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2e, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf9, 0x03, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2e, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf9, 0x03, 0x11, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2e, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf9, 0x03, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, - 0x02, 0x02, 0x12, 0x04, 0xfa, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, - 0x05, 0x12, 0x04, 0xfa, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xfa, 0x03, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xfa, 0x03, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x03, 0x12, 0x04, 0xfb, - 0x03, 0x02, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x04, 0x12, 0x04, 0xfb, 0x03, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfb, 0x03, 0x0b, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfb, 0x03, 0x12, 0x24, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfb, 0x03, 0x27, 0x28, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x2f, 0x12, 0x06, 0xfe, 0x03, 0x00, 0x82, 0x04, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x2f, 0x01, 0x12, 0x04, 0xfe, 0x03, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, - 0x02, 0x00, 0x12, 0x04, 0xff, 0x03, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xff, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xff, 0x03, 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xff, 0x03, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x01, 0x12, 0x04, 0x80, - 0x04, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x04, 0x12, 0x04, 0x80, 0x04, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x05, 0x12, 0x04, 0x80, 0x04, 0x0b, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x01, 0x12, 0x04, 0x80, 0x04, 0x12, 0x2c, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x03, 0x12, 0x04, 0x80, 0x04, 0x2f, 0x30, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x02, 0x12, 0x04, 0x81, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2f, 0x02, 0x02, 0x04, 0x12, 0x04, 0x81, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2f, 0x02, 0x02, 0x06, 0x12, 0x04, 0x81, 0x04, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2f, 0x02, 0x02, 0x01, 0x12, 0x04, 0x81, 0x04, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, - 0x02, 0x02, 0x03, 0x12, 0x04, 0x81, 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x30, 0x12, - 0x06, 0x84, 0x04, 0x00, 0x8a, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x30, 0x01, 0x12, 0x04, - 0x84, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x00, 0x12, 0x04, 0x85, 0x04, - 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x06, 0x12, 0x04, 0x85, 0x04, 0x02, - 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x01, 0x12, 0x04, 0x85, 0x04, 0x13, 0x19, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x03, 0x12, 0x04, 0x85, 0x04, 0x1c, 0x1d, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x01, 0x12, 0x04, 0x86, 0x04, 0x02, 0x31, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x30, 0x02, 0x01, 0x04, 0x12, 0x04, 0x86, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x30, 0x02, 0x01, 0x05, 0x12, 0x04, 0x86, 0x04, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x30, 0x02, 0x01, 0x01, 0x12, 0x04, 0x86, 0x04, 0x12, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, - 0x02, 0x01, 0x03, 0x12, 0x04, 0x86, 0x04, 0x2f, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, - 0x02, 0x12, 0x04, 0x87, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x04, - 0x12, 0x04, 0x87, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x06, 0x12, - 0x04, 0x87, 0x04, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x01, 0x12, 0x04, - 0x87, 0x04, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x03, 0x12, 0x04, 0x87, - 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x03, 0x12, 0x04, 0x88, 0x04, 0x02, - 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x03, 0x05, 0x12, 0x04, 0x88, 0x04, 0x02, 0x08, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x03, 0x01, 0x12, 0x04, 0x88, 0x04, 0x09, 0x1a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x03, 0x03, 0x12, 0x04, 0x88, 0x04, 0x1d, 0x1e, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x30, 0x02, 0x04, 0x12, 0x04, 0x89, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x30, 0x02, 0x04, 0x06, 0x12, 0x04, 0x89, 0x04, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x30, 0x02, 0x04, 0x01, 0x12, 0x04, 0x89, 0x04, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, - 0x02, 0x04, 0x03, 0x12, 0x04, 0x89, 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x31, 0x12, - 0x06, 0x8c, 0x04, 0x00, 0x98, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x31, 0x01, 0x12, 0x04, - 0x8c, 0x04, 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x31, 0x04, 0x00, 0x12, 0x06, 0x8d, 0x04, - 0x02, 0x94, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x04, 0x00, 0x01, 0x12, 0x04, 0x8d, - 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x8e, - 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, - 0x8e, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, - 0x04, 0x8e, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x12, - 0x04, 0x8f, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x01, - 0x12, 0x04, 0x8f, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, - 0x02, 0x12, 0x04, 0x8f, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, - 0x02, 0x12, 0x04, 0x90, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, - 0x02, 0x01, 0x12, 0x04, 0x90, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, - 0x02, 0x02, 0x02, 0x12, 0x04, 0x90, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, - 0x00, 0x02, 0x03, 0x12, 0x04, 0x91, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, - 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0x91, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, - 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0x91, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, - 0x31, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0x92, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x31, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x92, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x31, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x92, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, - 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0x93, 0x04, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x93, 0x04, 0x04, 0x1a, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0x93, 0x04, 0x1d, 0x1e, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x00, 0x12, 0x04, 0x96, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x31, 0x02, 0x00, 0x06, 0x12, 0x04, 0x96, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x31, 0x02, 0x00, 0x01, 0x12, 0x04, 0x96, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x31, 0x02, 0x00, 0x03, 0x12, 0x04, 0x96, 0x04, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, - 0x02, 0x01, 0x12, 0x04, 0x97, 0x04, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, - 0x05, 0x12, 0x04, 0x97, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x01, - 0x12, 0x04, 0x97, 0x04, 0x08, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x03, 0x12, - 0x04, 0x97, 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x32, 0x12, 0x06, 0x9a, 0x04, 0x00, - 0xb0, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x32, 0x01, 0x12, 0x04, 0x9a, 0x04, 0x08, 0x14, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x32, 0x04, 0x00, 0x12, 0x06, 0x9b, 0x04, 0x02, 0xa1, 0x04, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x04, 0x00, 0x01, 0x12, 0x04, 0x9b, 0x04, 0x07, 0x0b, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x9c, 0x04, 0x04, 0x19, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x04, 0x04, 0x14, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x9c, 0x04, 0x17, - 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x9d, 0x04, 0x04, - 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9d, 0x04, - 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0x9d, - 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0x9e, - 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, - 0x9e, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0x9e, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, 0x12, - 0x04, 0x9f, 0x04, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, 0x01, - 0x12, 0x04, 0x9f, 0x04, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, - 0x02, 0x12, 0x04, 0x9f, 0x04, 0x14, 0x15, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, - 0x04, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, - 0x04, 0x01, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, - 0x02, 0x04, 0x02, 0x12, 0x04, 0xa0, 0x04, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, - 0x00, 0x12, 0x04, 0xa3, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x06, - 0x12, 0x04, 0xa3, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x01, 0x12, - 0x04, 0xa3, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x03, 0x12, 0x04, - 0xa3, 0x04, 0x0e, 0x0f, 0x0a, 0x64, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x01, 0x12, 0x04, 0xa7, 0x04, - 0x02, 0x2a, 0x1a, 0x56, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x3a, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0x0a, - 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, - 0x02, 0x01, 0x05, 0x12, 0x04, 0xa7, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, - 0x01, 0x01, 0x12, 0x04, 0xa7, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, - 0x03, 0x12, 0x04, 0xa7, 0x04, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, 0x08, - 0x12, 0x04, 0xa7, 0x04, 0x16, 0x29, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x02, 0x01, 0x08, 0x03, - 0x12, 0x04, 0xa7, 0x04, 0x17, 0x28, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x32, 0x08, 0x00, 0x12, 0x06, - 0xaa, 0x04, 0x02, 0xaf, 0x04, 0x03, 0x1a, 0x13, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x32, 0x08, 0x00, 0x01, 0x12, 0x04, 0xaa, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, - 0x02, 0x02, 0x12, 0x04, 0xab, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, - 0x06, 0x12, 0x04, 0xab, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xab, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xab, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x03, 0x12, 0x04, 0xac, - 0x04, 0x04, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x06, 0x12, 0x04, 0xac, 0x04, - 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x04, 0x13, - 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x03, 0x12, 0x04, 0xac, 0x04, 0x25, 0x26, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x04, 0x12, 0x04, 0xad, 0x04, 0x04, 0x1a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x32, 0x02, 0x04, 0x06, 0x12, 0x04, 0xad, 0x04, 0x04, 0x0c, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x32, 0x02, 0x04, 0x01, 0x12, 0x04, 0xad, 0x04, 0x0d, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x32, 0x02, 0x04, 0x03, 0x12, 0x04, 0xad, 0x04, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x32, 0x02, 0x05, 0x12, 0x04, 0xae, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, - 0x05, 0x06, 0x12, 0x04, 0xae, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x05, - 0x01, 0x12, 0x04, 0xae, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x05, 0x03, - 0x12, 0x04, 0xae, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x33, 0x12, 0x06, 0xb2, 0x04, - 0x00, 0xb4, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x33, 0x01, 0x12, 0x04, 0xb2, 0x04, 0x08, - 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x33, 0x02, 0x00, 0x12, 0x04, 0xb3, 0x04, 0x02, 0x16, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb3, 0x04, 0x02, 0x07, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb3, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x33, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb3, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, - 0x04, 0x34, 0x12, 0x06, 0xb6, 0x04, 0x00, 0xb8, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x34, - 0x01, 0x12, 0x04, 0xb6, 0x04, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x34, 0x02, 0x00, 0x12, - 0x04, 0xb7, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x05, 0x12, 0x04, - 0xb7, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb7, - 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb7, 0x04, - 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x35, 0x12, 0x06, 0xba, 0x04, 0x00, 0xbc, 0x04, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x35, 0x01, 0x12, 0x04, 0xba, 0x04, 0x08, 0x10, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x35, 0x02, 0x00, 0x12, 0x04, 0xbb, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x35, 0x02, 0x00, 0x05, 0x12, 0x04, 0xbb, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xbb, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xbb, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x36, 0x12, 0x06, - 0xbe, 0x04, 0x00, 0xc0, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x36, 0x01, 0x12, 0x04, 0xbe, - 0x04, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x36, 0x02, 0x00, 0x12, 0x04, 0xbf, 0x04, 0x02, - 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x05, 0x12, 0x04, 0xbf, 0x04, 0x02, 0x07, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x01, 0x12, 0x04, 0xbf, 0x04, 0x08, 0x11, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x03, 0x12, 0x04, 0xbf, 0x04, 0x14, 0x15, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x37, 0x12, 0x06, 0xc2, 0x04, 0x00, 0xc5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x37, 0x01, 0x12, 0x04, 0xc2, 0x04, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, - 0x00, 0x12, 0x04, 0xc3, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x06, - 0x12, 0x04, 0xc3, 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x01, 0x12, - 0x04, 0xc3, 0x04, 0x0f, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x03, 0x12, 0x04, - 0xc3, 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, 0x01, 0x12, 0x04, 0xc4, 0x04, - 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc4, 0x04, 0x02, - 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc4, 0x04, 0x0f, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc4, 0x04, 0x1b, 0x1c, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x38, 0x12, 0x06, 0xc7, 0x04, 0x00, 0xca, 0x04, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x38, 0x01, 0x12, 0x04, 0xc7, 0x04, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, - 0x02, 0x00, 0x12, 0x04, 0xc8, 0x04, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, - 0x05, 0x12, 0x04, 0xc8, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xc8, 0x04, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xc8, 0x04, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x01, 0x12, 0x04, 0xc9, - 0x04, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc9, 0x04, - 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc9, 0x04, 0x0f, - 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc9, 0x04, 0x1b, 0x1c, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x39, 0x12, 0x06, 0xcc, 0x04, 0x00, 0xd0, 0x04, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x39, 0x01, 0x12, 0x04, 0xcc, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x39, 0x02, 0x00, 0x12, 0x04, 0xcd, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, - 0x00, 0x04, 0x12, 0x04, 0xcd, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xcd, 0x04, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xcd, 0x04, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xcd, 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x01, 0x12, 0x04, 0xce, - 0x04, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x04, 0x12, 0x04, 0xce, 0x04, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x06, 0x12, 0x04, 0xce, 0x04, 0x0b, - 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x01, 0x12, 0x04, 0xce, 0x04, 0x1c, 0x26, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x03, 0x12, 0x04, 0xce, 0x04, 0x29, 0x2a, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x02, 0x12, 0x04, 0xcf, 0x04, 0x02, 0x21, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x39, 0x02, 0x02, 0x05, 0x12, 0x04, 0xcf, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x39, 0x02, 0x02, 0x01, 0x12, 0x04, 0xcf, 0x04, 0x09, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x39, 0x02, 0x02, 0x03, 0x12, 0x04, 0xcf, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3a, - 0x12, 0x06, 0xd2, 0x04, 0x00, 0xd5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3a, 0x01, 0x12, - 0x04, 0xd2, 0x04, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x00, 0x12, 0x04, 0xd3, - 0x04, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd3, 0x04, - 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd3, 0x04, 0x09, - 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd3, 0x04, 0x19, 0x1a, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x01, 0x12, 0x04, 0xd4, 0x04, 0x02, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd4, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd4, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd4, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x3b, 0x12, 0x06, 0xd7, 0x04, 0x00, 0xd9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3b, 0x01, - 0x12, 0x04, 0xd7, 0x04, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x00, 0x12, 0x04, - 0xd8, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd8, - 0x04, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd8, 0x04, - 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd8, 0x04, 0x1c, - 0x1d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3c, 0x12, 0x06, 0xdb, 0x04, 0x00, 0xf0, 0x04, 0x01, 0x0a, - 0x0b, 0x0a, 0x03, 0x04, 0x3c, 0x01, 0x12, 0x04, 0xdb, 0x04, 0x08, 0x18, 0x0a, 0x0e, 0x0a, 0x04, - 0x04, 0x3c, 0x04, 0x00, 0x12, 0x06, 0xdc, 0x04, 0x02, 0xe5, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3c, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdc, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, - 0x3c, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xdd, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x3c, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x3c, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdd, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, - 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xde, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x04, 0x04, 0x10, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xde, 0x04, 0x13, 0x14, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x1b, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x16, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x04, 0x19, - 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xe0, 0x04, 0x04, - 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe0, 0x04, - 0x04, 0x13, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xe0, - 0x04, 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xe1, - 0x04, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, - 0xe1, 0x04, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, - 0x04, 0xe1, 0x04, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, 0x12, - 0x04, 0xe2, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, 0x01, - 0x12, 0x04, 0xe2, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, - 0x02, 0x12, 0x04, 0xe2, 0x04, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x04, 0x00, 0x04, - 0x12, 0x04, 0xe4, 0x04, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x00, - 0x12, 0x04, 0xe4, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x00, - 0x01, 0x12, 0x04, 0xe4, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x04, - 0x00, 0x02, 0x12, 0x04, 0xe4, 0x04, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x00, - 0x12, 0x04, 0xe7, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x06, 0x12, - 0x04, 0xe7, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x01, 0x12, 0x04, - 0xe7, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe7, - 0x04, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x3c, 0x08, 0x00, 0x12, 0x06, 0xe8, 0x04, 0x02, - 0xef, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x04, - 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x01, 0x12, 0x04, 0xe9, 0x04, 0x04, 0x21, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe9, 0x04, 0x04, 0x14, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x04, 0x15, 0x1c, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x3c, 0x02, 0x02, 0x12, 0x04, 0xea, 0x04, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3c, 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x04, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, - 0x02, 0x02, 0x01, 0x12, 0x04, 0xea, 0x04, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, - 0x02, 0x03, 0x12, 0x04, 0xea, 0x04, 0x2a, 0x2b, 0x0a, 0x1e, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x03, - 0x12, 0x04, 0xec, 0x04, 0x04, 0x30, 0x1a, 0x10, 0x20, 0x34, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, - 0x06, 0x12, 0x04, 0xec, 0x04, 0x04, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xec, 0x04, 0x17, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, 0x03, 0x12, - 0x04, 0xec, 0x04, 0x2e, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x04, 0x12, 0x04, 0xed, - 0x04, 0x04, 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xed, 0x04, - 0x04, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xed, 0x04, 0x16, - 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xed, 0x04, 0x2c, 0x2d, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x05, 0x12, 0x04, 0xee, 0x04, 0x04, 0x29, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xee, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xee, 0x04, 0x19, 0x24, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3c, 0x02, 0x05, 0x03, 0x12, 0x04, 0xee, 0x04, 0x27, 0x28, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x3d, 0x12, 0x06, 0xf2, 0x04, 0x00, 0xf6, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3d, 0x01, - 0x12, 0x04, 0xf2, 0x04, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x00, 0x12, 0x04, - 0xf3, 0x04, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, - 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x04, - 0x09, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x04, 0x1d, - 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x04, 0x02, 0x2d, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xf4, 0x04, 0x02, 0x0a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xf4, 0x04, 0x0b, 0x18, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x04, 0x19, 0x28, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x04, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x3d, 0x02, 0x02, 0x12, 0x04, 0xf5, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, - 0x02, 0x04, 0x12, 0x04, 0xf5, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, - 0x06, 0x12, 0x04, 0xf5, 0x04, 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xf5, 0x04, 0x1b, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xf5, 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3e, 0x12, 0x06, 0xf8, 0x04, 0x00, - 0xfb, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3e, 0x01, 0x12, 0x04, 0xf8, 0x04, 0x08, 0x15, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3e, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x04, 0x02, 0x1c, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x04, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x04, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x3e, 0x02, 0x01, 0x12, 0x04, 0xfa, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, - 0x01, 0x05, 0x12, 0x04, 0xfa, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x01, - 0x01, 0x12, 0x04, 0xfa, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x01, 0x03, - 0x12, 0x04, 0xfa, 0x04, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3f, 0x12, 0x06, 0xfd, 0x04, - 0x00, 0x80, 0x05, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3f, 0x01, 0x12, 0x04, 0xfd, 0x04, 0x08, - 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3f, 0x02, 0x00, 0x12, 0x04, 0xfe, 0x04, 0x02, 0x17, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x00, 0x05, 0x12, 0x04, 0xfe, 0x04, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfe, 0x04, 0x09, 0x12, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfe, 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x3f, 0x02, 0x01, 0x12, 0x04, 0xff, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, - 0x02, 0x01, 0x05, 0x12, 0x04, 0xff, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, - 0x01, 0x01, 0x12, 0x04, 0xff, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x01, - 0x03, 0x12, 0x04, 0xff, 0x04, 0x17, 0x18, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x00, 0x05, 0x12, 0x03, 0x6d, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x6d, 0x10, 0x12, 0x0a, 0x14, 0x0a, + 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x6d, 0x15, 0x16, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x01, 0x02, 0x01, 0x12, 0x03, 0x6e, 0x0a, 0x1c, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x6e, 0x0a, 0x0f, 0x0a, 0x14, + 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x6e, 0x10, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x6e, 0x1a, 0x1b, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x12, 0x04, 0x70, 0x08, 0x73, 0x09, 0x0a, 0x12, + 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x70, + 0x0e, 0x15, 0x0a, 0x11, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x12, 0x03, 0x71, 0x0a, 0x2d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x71, 0x0a, 0x18, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x71, 0x19, 0x28, 0x0a, 0x12, 0x0a, + 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x71, 0x2b, + 0x2c, 0x0a, 0x11, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, + 0x03, 0x72, 0x0a, 0x16, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x01, 0x06, 0x12, 0x03, 0x72, 0x0a, 0x0d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x72, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0b, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x72, 0x14, 0x15, + 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x76, 0x06, + 0x1c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x04, 0x12, 0x03, + 0x76, 0x06, 0x0e, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x06, + 0x12, 0x03, 0x76, 0x0f, 0x12, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x02, 0x01, 0x12, 0x03, 0x76, 0x13, 0x17, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x76, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x01, 0x12, 0x04, 0x78, 0x04, 0x7c, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x01, 0x01, 0x12, 0x03, 0x78, 0x0c, 0x26, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x79, 0x06, 0x29, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x79, 0x06, 0x0e, 0x0a, 0x10, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x79, 0x0f, 0x15, 0x0a, 0x10, + 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x79, 0x16, 0x24, + 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79, + 0x27, 0x28, 0x0a, 0x1e, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x12, 0x03, + 0x7b, 0x06, 0x14, 0x1a, 0x0d, 0x20, 0x48, 0x65, 0x78, 0x54, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x2e, 0x0a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, + 0x03, 0x7b, 0x06, 0x0b, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, + 0x01, 0x12, 0x03, 0x7b, 0x0c, 0x0f, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x7b, 0x12, 0x13, 0x0a, 0x0f, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x02, 0x12, 0x05, 0x7d, 0x04, 0x80, 0x01, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x02, 0x01, 0x12, 0x03, 0x7d, 0x0c, 0x21, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x02, 0x02, 0x00, 0x12, 0x03, 0x7e, 0x06, 0x26, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x7e, 0x06, 0x1a, 0x0a, 0x10, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x7e, 0x1b, 0x21, 0x0a, 0x10, + 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x7e, 0x24, 0x25, + 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7f, 0x06, + 0x2f, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, + 0x7f, 0x06, 0x20, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x01, + 0x12, 0x03, 0x7f, 0x21, 0x2a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x7f, 0x2d, 0x2e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, + 0x00, 0x12, 0x04, 0x81, 0x01, 0x04, 0x36, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, + 0x00, 0x06, 0x12, 0x04, 0x81, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x81, 0x01, 0x1a, 0x31, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, + 0x00, 0x02, 0x00, 0x03, 0x12, 0x04, 0x81, 0x01, 0x34, 0x35, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x05, + 0x03, 0x01, 0x12, 0x06, 0x84, 0x01, 0x02, 0x8b, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, + 0x03, 0x01, 0x01, 0x12, 0x04, 0x84, 0x01, 0x0a, 0x13, 0x0a, 0x10, 0x0a, 0x06, 0x04, 0x05, 0x03, + 0x01, 0x03, 0x00, 0x12, 0x06, 0x85, 0x01, 0x04, 0x89, 0x01, 0x05, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x05, 0x03, 0x01, 0x03, 0x00, 0x01, 0x12, 0x04, 0x85, 0x01, 0x0c, 0x19, 0x0a, 0x10, 0x0a, 0x08, + 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0x86, 0x01, 0x06, 0x17, 0x0a, 0x11, + 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x04, 0x86, 0x01, 0x06, + 0x0c, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, + 0x86, 0x01, 0x0d, 0x12, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, + 0x03, 0x12, 0x04, 0x86, 0x01, 0x15, 0x16, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, + 0x00, 0x02, 0x01, 0x12, 0x04, 0x87, 0x01, 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, + 0x01, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x04, 0x87, 0x01, 0x06, 0x0c, 0x0a, 0x11, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x87, 0x01, 0x0d, 0x13, 0x0a, + 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0x87, 0x01, + 0x16, 0x17, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x12, 0x04, + 0x88, 0x01, 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, + 0x05, 0x12, 0x04, 0x88, 0x01, 0x06, 0x0b, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, + 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0x88, 0x01, 0x0c, 0x13, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x03, 0x12, 0x04, 0x88, 0x01, 0x16, 0x17, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x25, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x11, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x12, 0x20, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x23, 0x24, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x02, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x04, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x05, 0x02, 0x02, 0x06, 0x12, 0x04, 0x8d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x05, 0x02, 0x02, 0x01, 0x12, 0x04, 0x8d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x05, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x06, + 0x12, 0x06, 0x90, 0x01, 0x00, 0x92, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, + 0x04, 0x90, 0x01, 0x08, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, 0x91, + 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x04, 0x12, 0x04, 0x91, 0x01, + 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x04, 0x91, 0x01, 0x0b, + 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x01, 0x18, 0x26, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x04, 0x91, 0x01, 0x29, 0x2a, 0x0a, + 0x0c, 0x0a, 0x02, 0x04, 0x07, 0x12, 0x06, 0x94, 0x01, 0x00, 0x99, 0x01, 0x01, 0x0a, 0x0b, 0x0a, + 0x03, 0x04, 0x07, 0x01, 0x12, 0x04, 0x94, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, + 0x02, 0x00, 0x12, 0x04, 0x95, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, + 0x05, 0x12, 0x04, 0x95, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, + 0x12, 0x04, 0x95, 0x01, 0x07, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, + 0x04, 0x95, 0x01, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x04, 0x96, + 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x04, 0x96, 0x01, + 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x04, 0x96, 0x01, 0x07, + 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x03, 0x12, 0x04, 0x96, 0x01, 0x24, 0x25, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x02, 0x12, 0x04, 0x97, 0x01, 0x02, 0x2d, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, 0x05, 0x12, 0x04, 0x97, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x07, 0x02, 0x02, 0x01, 0x12, 0x04, 0x97, 0x01, 0x09, 0x28, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x07, 0x02, 0x02, 0x03, 0x12, 0x04, 0x97, 0x01, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x07, 0x02, 0x03, 0x12, 0x04, 0x98, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, + 0x03, 0x05, 0x12, 0x04, 0x98, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, + 0x01, 0x12, 0x04, 0x98, 0x01, 0x09, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x03, + 0x12, 0x04, 0x98, 0x01, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x06, 0x9b, 0x01, + 0x00, 0x9e, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x01, 0x08, + 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x25, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x06, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x01, 0x19, 0x20, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x08, 0x02, 0x00, 0x03, 0x12, 0x04, 0x9c, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x08, 0x02, 0x01, 0x12, 0x04, 0x9d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, + 0x02, 0x01, 0x04, 0x12, 0x04, 0x9d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, + 0x01, 0x06, 0x12, 0x04, 0x9d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, + 0x01, 0x12, 0x04, 0x9d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, + 0x12, 0x04, 0x9d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x06, 0xa0, 0x01, + 0x00, 0xa6, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x09, 0x01, 0x12, 0x04, 0xa0, 0x01, 0x08, + 0x0d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x13, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x06, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x01, 0x0b, 0x0e, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x09, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x01, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x09, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, + 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, + 0x01, 0x01, 0x12, 0x04, 0xa2, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, + 0x03, 0x12, 0x04, 0xa2, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x08, + 0x12, 0x04, 0xa2, 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x09, 0x02, 0x01, 0x08, 0x06, + 0x12, 0x04, 0xa2, 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x02, 0x12, 0x04, + 0xa3, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x06, 0x12, 0x04, 0xa3, + 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x01, 0x12, 0x04, 0xa3, 0x01, + 0x0b, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, 0x01, 0x12, + 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x16, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x03, 0x05, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x09, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x09, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x09, 0x02, 0x04, 0x12, 0x04, 0xa5, 0x01, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, + 0x02, 0x04, 0x05, 0x12, 0x04, 0xa5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, + 0x04, 0x01, 0x12, 0x04, 0xa5, 0x01, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, + 0x03, 0x12, 0x04, 0xa5, 0x01, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x06, 0xa8, + 0x01, 0x00, 0xb2, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x04, 0xa8, 0x01, + 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x11, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x07, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x01, 0x08, 0x0c, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa9, 0x01, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0a, 0x02, 0x01, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xaa, 0x01, 0x08, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xaa, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x02, + 0x12, 0x04, 0xab, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x05, 0x12, + 0x04, 0xab, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xab, 0x01, 0x08, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xab, + 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x03, 0x12, 0x04, 0xac, 0x01, 0x02, + 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x04, 0x12, 0x04, 0xac, 0x01, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x05, 0x12, 0x04, 0xac, 0x01, 0x0b, 0x10, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x01, 0x11, 0x26, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xac, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0a, 0x02, 0x04, 0x12, 0x04, 0xad, 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, 0xad, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, + 0x02, 0x04, 0x01, 0x12, 0x04, 0xad, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x04, 0x03, 0x12, 0x04, 0xad, 0x01, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, + 0x08, 0x12, 0x04, 0xad, 0x01, 0x16, 0x2a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0a, 0x02, 0x04, 0x08, + 0x06, 0x12, 0x04, 0xad, 0x01, 0x17, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x05, 0x12, + 0x04, 0xae, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x05, 0x12, 0x04, + 0xae, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x01, 0x12, 0x04, 0xae, + 0x01, 0x07, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x03, 0x12, 0x04, 0xae, 0x01, + 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x06, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x17, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x06, 0x05, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0xaf, 0x01, 0x09, 0x12, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x06, 0x03, 0x12, 0x04, 0xaf, 0x01, 0x15, 0x16, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0a, 0x02, 0x07, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0a, 0x02, 0x07, 0x05, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, + 0x02, 0x07, 0x01, 0x12, 0x04, 0xb0, 0x01, 0x08, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x07, 0x03, 0x12, 0x04, 0xb0, 0x01, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x08, + 0x12, 0x04, 0xb1, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x04, 0x12, + 0x04, 0xb1, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x06, 0x12, 0x04, + 0xb1, 0x01, 0x0b, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x01, 0x12, 0x04, 0xb1, + 0x01, 0x1a, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x12, 0x04, 0xb1, 0x01, + 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x06, 0xb4, 0x01, 0x00, 0xb7, 0x01, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0b, 0x01, 0x12, 0x04, 0xb4, 0x01, 0x08, 0x10, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0b, 0x02, 0x00, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0b, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, + 0x02, 0x00, 0x01, 0x12, 0x04, 0xb5, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, + 0x00, 0x03, 0x12, 0x04, 0xb5, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, + 0x08, 0x12, 0x04, 0xb5, 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0b, 0x02, 0x00, 0x08, + 0x06, 0x12, 0x04, 0xb5, 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x01, 0x12, + 0x04, 0xb6, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x05, 0x12, 0x04, + 0xb6, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, + 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x01, + 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0c, 0x12, 0x06, 0xb9, 0x01, 0x00, 0xc1, 0x01, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x04, 0xb9, 0x01, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0c, 0x02, 0x00, 0x12, 0x04, 0xba, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0c, 0x02, 0x00, 0x05, 0x12, 0x04, 0xba, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, + 0x02, 0x00, 0x01, 0x12, 0x04, 0xba, 0x01, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, + 0x00, 0x03, 0x12, 0x04, 0xba, 0x01, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x01, + 0x12, 0x04, 0xbb, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x05, 0x12, + 0x04, 0xbb, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, 0x04, + 0xbb, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbb, + 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x04, 0xbb, 0x01, + 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xbb, 0x01, + 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x02, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x31, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbc, 0x01, 0x09, 0x17, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x02, 0x03, 0x12, 0x04, 0xbc, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0c, 0x02, 0x02, 0x08, 0x12, 0x04, 0xbc, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, + 0x04, 0x0c, 0x02, 0x02, 0x08, 0x06, 0x12, 0x04, 0xbc, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x0c, 0x02, 0x03, 0x12, 0x04, 0xbd, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, + 0x02, 0x03, 0x05, 0x12, 0x04, 0xbd, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, + 0x03, 0x01, 0x12, 0x04, 0xbd, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, + 0x03, 0x12, 0x04, 0xbd, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x08, + 0x12, 0x04, 0xbd, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x06, + 0x12, 0x04, 0xbd, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x04, 0x12, 0x04, + 0xbe, 0x01, 0x02, 0x3f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xbe, + 0x01, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xbe, 0x01, + 0x21, 0x3a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xbe, 0x01, 0x3d, + 0x3e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x21, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x14, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xbf, 0x01, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0c, 0x02, 0x05, 0x03, 0x12, 0x04, 0xbf, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x0c, 0x02, 0x06, 0x12, 0x04, 0xc0, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, + 0x02, 0x06, 0x06, 0x12, 0x04, 0xc0, 0x01, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, + 0x06, 0x01, 0x12, 0x04, 0xc0, 0x01, 0x0c, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, + 0x03, 0x12, 0x04, 0xc0, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x06, 0xc3, + 0x01, 0x00, 0xcf, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0d, 0x01, 0x12, 0x04, 0xc3, 0x01, + 0x08, 0x10, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x04, 0x00, 0x12, 0x06, 0xc4, 0x01, 0x02, 0xc8, + 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x04, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x01, 0x07, + 0x13, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xc5, 0x01, 0x04, + 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc5, 0x01, + 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc5, + 0x01, 0x21, 0x22, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xc6, + 0x01, 0x04, 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, + 0xc6, 0x01, 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x04, 0xc6, 0x01, 0x26, 0x27, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x04, 0xc7, 0x01, 0x04, 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xc7, 0x01, 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0xc7, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12, + 0x04, 0xca, 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x06, 0x12, 0x04, + 0xca, 0x01, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xca, + 0x01, 0x0f, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xca, 0x01, + 0x20, 0x21, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x08, 0x00, 0x12, 0x06, 0xcb, 0x01, 0x02, 0xce, + 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x08, 0x00, 0x01, 0x12, 0x04, 0xcb, 0x01, 0x08, + 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x28, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x12, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xcc, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x0d, 0x02, 0x02, 0x12, 0x04, 0xcd, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, + 0x02, 0x02, 0x06, 0x12, 0x04, 0xcd, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xcd, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xcd, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0e, 0x12, 0x06, 0xd1, + 0x01, 0x00, 0xd4, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0e, 0x01, 0x12, 0x04, 0xd1, 0x01, + 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x18, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x01, 0x09, 0x13, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd2, 0x01, 0x16, 0x17, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0e, 0x02, 0x01, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0e, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xd3, 0x01, 0x10, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xd3, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06, + 0xd6, 0x01, 0x00, 0xd9, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0xd6, + 0x01, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0xd7, 0x01, 0x02, + 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x04, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd7, 0x01, 0x0b, 0x19, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x01, 0x1a, 0x2a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd7, 0x01, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x0f, 0x02, 0x01, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0f, 0x02, 0x01, 0x04, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, + 0x02, 0x01, 0x06, 0x12, 0x04, 0xd8, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, + 0x01, 0x01, 0x12, 0x04, 0xd8, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, + 0x03, 0x12, 0x04, 0xd8, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x10, 0x12, 0x06, 0xdb, + 0x01, 0x00, 0xf0, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x10, 0x01, 0x12, 0x04, 0xdb, 0x01, + 0x08, 0x16, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x04, 0x00, 0x12, 0x06, 0xdc, 0x01, 0x02, 0xe4, + 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdc, 0x01, 0x07, + 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xdd, 0x01, 0x04, + 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x01, + 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdd, + 0x01, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xde, + 0x01, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, + 0xde, 0x01, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x04, 0xde, 0x01, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x04, 0xdf, 0x01, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xdf, 0x01, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0xdf, 0x01, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, + 0x03, 0x12, 0x04, 0xe0, 0x01, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x04, 0xe0, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, + 0x02, 0x03, 0x02, 0x12, 0x04, 0xe0, 0x01, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, + 0x00, 0x02, 0x04, 0x12, 0x04, 0xe1, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, + 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe1, 0x01, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, + 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xe1, 0x01, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x10, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x10, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x10, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0xe2, 0x01, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x06, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x19, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x04, 0xe3, 0x01, 0x1c, 0x1d, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x10, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x10, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x10, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x01, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x10, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe6, 0x01, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, + 0x08, 0x00, 0x12, 0x06, 0xe8, 0x01, 0x02, 0xef, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, + 0x08, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x01, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, + 0x01, 0x12, 0x04, 0xe9, 0x01, 0x04, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x06, + 0x12, 0x04, 0xe9, 0x01, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xe9, 0x01, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x03, 0x12, 0x04, + 0xe9, 0x01, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x02, 0x12, 0x04, 0xea, 0x01, + 0x04, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x01, 0x04, + 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x01, 0x12, 0x04, 0xea, 0x01, 0x13, 0x22, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x03, 0x12, 0x04, 0xea, 0x01, 0x25, 0x26, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x10, 0x02, 0x03, 0x06, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x10, 0x02, 0x03, 0x01, 0x12, 0x04, 0xeb, 0x01, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x10, 0x02, 0x03, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, + 0x02, 0x04, 0x12, 0x04, 0xec, 0x01, 0x04, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, + 0x06, 0x12, 0x04, 0xec, 0x01, 0x04, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x01, + 0x12, 0x04, 0xec, 0x01, 0x10, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x03, 0x12, + 0x04, 0xec, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x05, 0x12, 0x04, 0xed, + 0x01, 0x04, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x06, 0x12, 0x04, 0xed, 0x01, + 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x01, 0x12, 0x04, 0xed, 0x01, 0x12, + 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x03, 0x12, 0x04, 0xed, 0x01, 0x23, 0x24, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x28, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x10, 0x02, 0x06, 0x01, 0x12, 0x04, 0xee, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x10, 0x02, 0x06, 0x03, 0x12, 0x04, 0xee, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x11, 0x12, 0x06, 0xf2, 0x01, 0x00, 0xf6, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x11, 0x01, + 0x12, 0x04, 0xf2, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x00, 0x12, 0x04, + 0xf3, 0x01, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, + 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x01, + 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x01, 0x13, + 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x1b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x07, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x11, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x11, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x11, 0x02, 0x02, 0x12, 0x04, 0xf5, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, + 0x02, 0x02, 0x06, 0x12, 0x04, 0xf5, 0x01, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xf5, 0x01, 0x0f, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xf5, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x12, 0x12, 0x06, 0xf8, + 0x01, 0x00, 0xfd, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x12, 0x01, 0x12, 0x04, 0xf8, 0x01, + 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x15, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x01, 0x09, 0x10, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x12, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x01, 0x13, 0x14, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x12, 0x02, 0x01, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x12, 0x02, 0x01, 0x05, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xfa, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xfa, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x02, + 0x12, 0x04, 0xfb, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x06, 0x12, + 0x04, 0xfb, 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xfb, 0x01, 0x10, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfb, + 0x01, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x02, + 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x01, 0x09, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x14, 0x15, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x13, 0x12, 0x06, 0xff, 0x01, 0x00, 0x84, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x13, 0x01, 0x12, 0x04, 0xff, 0x01, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, + 0x00, 0x12, 0x04, 0x80, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x05, + 0x12, 0x04, 0x80, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x01, 0x12, + 0x04, 0x80, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x03, 0x12, 0x04, + 0x80, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x01, 0x12, 0x04, 0x81, 0x02, + 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x05, 0x12, 0x04, 0x81, 0x02, 0x02, + 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x01, 0x12, 0x04, 0x81, 0x02, 0x09, 0x0f, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x03, 0x12, 0x04, 0x81, 0x02, 0x12, 0x13, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x02, 0x12, 0x04, 0x82, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x13, 0x02, 0x02, 0x05, 0x12, 0x04, 0x82, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x13, 0x02, 0x02, 0x01, 0x12, 0x04, 0x82, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x13, 0x02, 0x02, 0x03, 0x12, 0x04, 0x82, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, + 0x02, 0x03, 0x12, 0x04, 0x83, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, + 0x06, 0x12, 0x04, 0x83, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x01, + 0x12, 0x04, 0x83, 0x02, 0x12, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x03, 0x12, + 0x04, 0x83, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x14, 0x12, 0x06, 0x86, 0x02, 0x00, + 0x89, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x14, 0x01, 0x12, 0x04, 0x86, 0x02, 0x08, 0x17, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x00, 0x12, 0x04, 0x87, 0x02, 0x02, 0x11, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x14, 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x14, 0x02, 0x00, 0x01, 0x12, 0x04, 0x87, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x14, 0x02, 0x00, 0x03, 0x12, 0x04, 0x87, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x14, 0x02, 0x01, 0x12, 0x04, 0x88, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, + 0x01, 0x05, 0x12, 0x04, 0x88, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, + 0x01, 0x12, 0x04, 0x88, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x03, + 0x12, 0x04, 0x88, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x15, 0x12, 0x06, 0x8b, 0x02, + 0x00, 0x8f, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x15, 0x01, 0x12, 0x04, 0x8b, 0x02, 0x08, + 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x00, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x15, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x15, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8c, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x15, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8c, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x15, 0x02, 0x01, 0x12, 0x04, 0x8d, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, + 0x02, 0x01, 0x05, 0x12, 0x04, 0x8d, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, + 0x01, 0x01, 0x12, 0x04, 0x8d, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, + 0x03, 0x12, 0x04, 0x8d, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x02, 0x12, + 0x04, 0x8e, 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x06, 0x12, 0x04, + 0x8e, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x01, 0x12, 0x04, 0x8e, + 0x02, 0x15, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8e, 0x02, + 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x16, 0x12, 0x06, 0x91, 0x02, 0x00, 0x97, 0x02, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x16, 0x01, 0x12, 0x04, 0x91, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x16, 0x02, 0x00, 0x12, 0x04, 0x92, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x16, 0x02, 0x00, 0x05, 0x12, 0x04, 0x92, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x92, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x92, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x01, + 0x12, 0x04, 0x93, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x05, 0x12, + 0x04, 0x93, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x93, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x03, 0x12, 0x04, 0x93, + 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x02, 0x12, 0x04, 0x94, 0x02, 0x02, + 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x06, 0x12, 0x04, 0x94, 0x02, 0x02, 0x0f, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x01, 0x12, 0x04, 0x94, 0x02, 0x10, 0x14, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x03, 0x12, 0x04, 0x94, 0x02, 0x17, 0x18, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x16, 0x02, 0x03, 0x12, 0x04, 0x95, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x16, 0x02, 0x03, 0x05, 0x12, 0x04, 0x95, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x16, 0x02, 0x03, 0x01, 0x12, 0x04, 0x95, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, + 0x02, 0x03, 0x03, 0x12, 0x04, 0x95, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, + 0x04, 0x12, 0x04, 0x96, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x05, + 0x12, 0x04, 0x96, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x01, 0x12, + 0x04, 0x96, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x03, 0x12, 0x04, + 0x96, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x17, 0x12, 0x06, 0x99, 0x02, 0x00, 0x9e, + 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x17, 0x01, 0x12, 0x04, 0x99, 0x02, 0x08, 0x16, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x00, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x17, 0x02, 0x00, 0x05, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x17, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9a, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x17, 0x02, 0x00, 0x03, 0x12, 0x04, 0x9a, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, + 0x02, 0x01, 0x12, 0x04, 0x9b, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, + 0x05, 0x12, 0x04, 0x9b, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x01, + 0x12, 0x04, 0x9b, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x03, 0x12, + 0x04, 0x9b, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x02, 0x12, 0x04, 0x9c, + 0x02, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x05, 0x12, 0x04, 0x9c, 0x02, + 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x01, 0x12, 0x04, 0x9c, 0x02, 0x09, + 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x03, 0x12, 0x04, 0x9c, 0x02, 0x11, 0x12, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x17, 0x02, 0x03, 0x05, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x17, 0x02, 0x03, 0x01, 0x12, 0x04, 0x9d, 0x02, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x17, 0x02, 0x03, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x18, 0x12, 0x06, 0xa0, 0x02, 0x00, 0xa5, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x18, 0x01, + 0x12, 0x04, 0xa0, 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x00, 0x12, 0x04, + 0xa1, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa1, + 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x02, + 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x02, 0x19, + 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x14, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x18, 0x02, 0x01, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x18, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa2, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x18, 0x02, 0x02, 0x12, 0x04, 0xa3, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, + 0x02, 0x02, 0x05, 0x12, 0x04, 0xa3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xa3, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xa3, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x03, 0x12, + 0x04, 0xa4, 0x02, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x06, 0x12, 0x04, + 0xa4, 0x02, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, + 0x02, 0x11, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x02, + 0x18, 0x19, 0x0a, 0xa1, 0x01, 0x0a, 0x02, 0x04, 0x19, 0x12, 0x06, 0xa9, 0x02, 0x00, 0xc0, 0x02, + 0x01, 0x1a, 0x92, 0x01, 0x20, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4e, + 0x6f, 0x74, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x77, + 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x20, 0x0a, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x73, + 0x75, 0x72, 0x65, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x2e, + 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x0a, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x19, 0x01, 0x12, 0x04, 0xa9, + 0x02, 0x08, 0x1a, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x04, 0x00, 0x12, 0x06, 0xaa, 0x02, 0x02, + 0xb1, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, 0x00, 0x01, 0x12, 0x04, 0xaa, 0x02, + 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xab, 0x02, + 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xab, + 0x02, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, + 0xab, 0x02, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, + 0xac, 0x02, 0x04, 0x24, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xac, 0x02, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x02, + 0x12, 0x04, 0xac, 0x02, 0x22, 0x23, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, + 0x12, 0x04, 0xad, 0x02, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, + 0x01, 0x12, 0x04, 0xad, 0x02, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, + 0x02, 0x02, 0x12, 0x04, 0xad, 0x02, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, + 0x02, 0x03, 0x12, 0x04, 0xae, 0x02, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, + 0x02, 0x03, 0x01, 0x12, 0x04, 0xae, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, + 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xae, 0x02, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, + 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xaf, 0x02, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, + 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xaf, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x19, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xaf, 0x02, 0x1c, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x19, 0x04, 0x00, 0x04, 0x12, 0x04, 0xb0, 0x02, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x19, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x19, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x02, 0x12, 0x04, 0xb0, 0x02, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x19, 0x02, 0x00, 0x12, 0x04, 0xb3, 0x02, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x19, 0x02, 0x00, 0x06, 0x12, 0x04, 0xb3, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, + 0x02, 0x00, 0x01, 0x12, 0x04, 0xb3, 0x02, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, + 0x00, 0x03, 0x12, 0x04, 0xb3, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x08, 0x00, + 0x12, 0x06, 0xb5, 0x02, 0x02, 0xba, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x08, 0x00, + 0x01, 0x12, 0x04, 0xb5, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x01, 0x12, + 0x04, 0xb6, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x06, 0x12, 0x04, + 0xb6, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, + 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x02, + 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x25, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x06, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x01, 0x12, 0x04, 0xb7, 0x02, 0x12, 0x20, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x03, 0x12, 0x04, 0xb7, 0x02, 0x23, 0x24, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x19, 0x02, 0x03, 0x12, 0x04, 0xb8, 0x02, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x19, 0x02, 0x03, 0x06, 0x12, 0x04, 0xb8, 0x02, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, + 0x02, 0x03, 0x01, 0x12, 0x04, 0xb8, 0x02, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, + 0x03, 0x03, 0x12, 0x04, 0xb8, 0x02, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x04, + 0x12, 0x04, 0xb9, 0x02, 0x04, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x06, 0x12, + 0x04, 0xb9, 0x02, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x01, 0x12, 0x04, + 0xb9, 0x02, 0x14, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x03, 0x12, 0x04, 0xb9, + 0x02, 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x19, 0x09, 0x12, 0x04, 0xbb, 0x02, 0x02, 0x0d, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x09, 0x00, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x19, 0x09, 0x00, 0x01, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x19, 0x09, 0x00, 0x02, 0x12, 0x04, 0xbb, 0x02, 0x0b, 0x0c, 0x0a, 0x0e, 0x0a, 0x04, + 0x04, 0x19, 0x08, 0x01, 0x12, 0x06, 0xbd, 0x02, 0x02, 0xbf, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x19, 0x08, 0x01, 0x01, 0x12, 0x04, 0xbd, 0x02, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x19, 0x02, 0x05, 0x12, 0x04, 0xbe, 0x02, 0x04, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, + 0x05, 0x06, 0x12, 0x04, 0xbe, 0x02, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x05, + 0x01, 0x12, 0x04, 0xbe, 0x02, 0x12, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x05, 0x03, + 0x12, 0x04, 0xbe, 0x02, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1a, 0x12, 0x06, 0xc2, 0x02, + 0x00, 0xc5, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1a, 0x01, 0x12, 0x04, 0xc2, 0x02, 0x08, + 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x00, 0x12, 0x04, 0xc3, 0x02, 0x02, 0x27, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x00, 0x04, 0x12, 0x04, 0xc3, 0x02, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc3, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc3, 0x02, 0x12, 0x22, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc3, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x1a, 0x02, 0x01, 0x12, 0x04, 0xc4, 0x02, 0x02, 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, + 0x01, 0x04, 0x12, 0x04, 0xc4, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, + 0x05, 0x12, 0x04, 0xc4, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xc4, 0x02, 0x12, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xc4, 0x02, 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1b, 0x12, 0x06, 0xc7, 0x02, 0x00, + 0xcc, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1b, 0x01, 0x12, 0x04, 0xc7, 0x02, 0x08, 0x1c, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x00, 0x12, 0x04, 0xc8, 0x02, 0x02, 0x1f, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc8, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc8, 0x02, 0x12, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc8, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x1b, 0x02, 0x01, 0x12, 0x04, 0xc9, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, + 0x01, 0x04, 0x12, 0x04, 0xc9, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, + 0x06, 0x12, 0x04, 0xc9, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xc9, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xc9, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x02, 0x12, 0x04, 0xca, + 0x02, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x04, 0x12, 0x04, 0xca, 0x02, + 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x05, 0x12, 0x04, 0xca, 0x02, 0x0b, + 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x01, 0x12, 0x04, 0xca, 0x02, 0x12, 0x1b, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x02, 0x03, 0x12, 0x04, 0xca, 0x02, 0x1e, 0x1f, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x03, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x23, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1b, 0x02, 0x03, 0x05, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1b, 0x02, 0x03, 0x01, 0x12, 0x04, 0xcb, 0x02, 0x09, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1b, 0x02, 0x03, 0x03, 0x12, 0x04, 0xcb, 0x02, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1c, + 0x12, 0x06, 0xce, 0x02, 0x00, 0xd1, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1c, 0x01, 0x12, + 0x04, 0xce, 0x02, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x00, 0x12, 0x04, 0xcf, + 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x05, 0x12, 0x04, 0xcf, 0x02, + 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcf, 0x02, 0x08, + 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcf, 0x02, 0x13, 0x14, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x01, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x17, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd0, 0x02, 0x0f, 0x12, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd0, 0x02, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x1d, 0x12, 0x06, 0xd3, 0x02, 0x00, 0xd7, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1d, 0x01, + 0x12, 0x04, 0xd3, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x00, 0x12, 0x04, + 0xd4, 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd4, + 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd4, 0x02, + 0x15, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd4, 0x02, 0x1c, + 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x02, 0x27, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xd5, 0x02, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd5, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd5, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x1d, 0x02, 0x02, 0x12, 0x04, 0xd6, 0x02, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, + 0x02, 0x04, 0x12, 0x04, 0xd6, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, + 0x05, 0x12, 0x04, 0xd6, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xd6, 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xd6, 0x02, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1e, 0x12, 0x06, 0xd9, 0x02, 0x00, + 0xdc, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1e, 0x01, 0x12, 0x04, 0xd9, 0x02, 0x08, 0x17, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1e, 0x02, 0x00, 0x12, 0x04, 0xda, 0x02, 0x02, 0x1e, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xda, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xda, 0x02, 0x09, 0x19, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xda, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x1e, 0x02, 0x01, 0x12, 0x04, 0xdb, 0x02, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, + 0x01, 0x04, 0x12, 0x04, 0xdb, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, + 0x06, 0x12, 0x04, 0xdb, 0x02, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xdb, 0x02, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xdb, 0x02, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1f, 0x12, 0x06, 0xde, 0x02, 0x00, + 0xe9, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1f, 0x01, 0x12, 0x04, 0xde, 0x02, 0x08, 0x22, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x1f, 0x04, 0x00, 0x12, 0x06, 0xdf, 0x02, 0x02, 0xe2, 0x02, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdf, 0x02, 0x07, 0x0b, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xe0, 0x02, 0x04, 0x19, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe0, 0x02, 0x04, 0x14, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xe0, 0x02, 0x17, + 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xe1, 0x02, 0x04, + 0x24, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe1, 0x02, + 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x1f, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xe1, + 0x02, 0x22, 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1f, 0x02, 0x00, 0x12, 0x04, 0xe4, 0x02, 0x02, + 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe4, 0x02, 0x02, 0x06, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe4, 0x02, 0x07, 0x0b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe4, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, + 0x0a, 0x04, 0x04, 0x1f, 0x08, 0x00, 0x12, 0x06, 0xe6, 0x02, 0x02, 0xe8, 0x02, 0x03, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1f, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x1f, 0x02, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1f, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe7, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xe7, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x20, 0x12, 0x06, + 0xeb, 0x02, 0x00, 0xee, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x20, 0x01, 0x12, 0x04, 0xeb, + 0x02, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x00, 0x12, 0x04, 0xec, 0x02, 0x02, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x05, 0x12, 0x04, 0xec, 0x02, 0x02, 0x07, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x01, 0x12, 0x04, 0xec, 0x02, 0x08, 0x10, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x03, 0x12, 0x04, 0xec, 0x02, 0x13, 0x14, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x20, 0x02, 0x01, 0x12, 0x04, 0xed, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x20, 0x02, 0x01, 0x06, 0x12, 0x04, 0xed, 0x02, 0x02, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x20, 0x02, 0x01, 0x01, 0x12, 0x04, 0xed, 0x02, 0x0d, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xed, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x21, 0x12, + 0x06, 0xf0, 0x02, 0x00, 0xf6, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x21, 0x01, 0x12, 0x04, + 0xf0, 0x02, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x00, 0x12, 0x04, 0xf1, 0x02, + 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf1, 0x02, 0x02, + 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf1, 0x02, 0x09, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf1, 0x02, 0x13, 0x14, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x01, 0x12, 0x04, 0xf2, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x21, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf2, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x21, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf2, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x21, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf2, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, + 0x02, 0x02, 0x12, 0x04, 0xf3, 0x02, 0x02, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, + 0x04, 0x12, 0x04, 0xf3, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x06, + 0x12, 0x04, 0xf3, 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x01, 0x12, + 0x04, 0xf3, 0x02, 0x18, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x02, 0x03, 0x12, 0x04, + 0xf3, 0x02, 0x22, 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x03, 0x12, 0x04, 0xf4, 0x02, + 0x02, 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x04, 0x12, 0x04, 0xf4, 0x02, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x06, 0x12, 0x04, 0xf4, 0x02, 0x0b, 0x17, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x01, 0x12, 0x04, 0xf4, 0x02, 0x18, 0x29, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x03, 0x12, 0x04, 0xf4, 0x02, 0x2c, 0x2d, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x21, 0x02, 0x04, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x21, 0x02, 0x04, 0x04, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x21, 0x02, 0x04, 0x06, 0x12, 0x04, 0xf5, 0x02, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, + 0x02, 0x04, 0x01, 0x12, 0x04, 0xf5, 0x02, 0x16, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, + 0x04, 0x03, 0x12, 0x04, 0xf5, 0x02, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x22, 0x12, 0x06, + 0xf7, 0x02, 0x00, 0x84, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x22, 0x01, 0x12, 0x04, 0xf7, + 0x02, 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x22, 0x04, 0x00, 0x12, 0x06, 0xf8, 0x02, 0x02, + 0xfd, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x04, 0x00, 0x01, 0x12, 0x04, 0xf8, 0x02, + 0x07, 0x11, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x02, + 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, + 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, + 0xf9, 0x02, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, + 0xfa, 0x02, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xfa, 0x02, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x01, 0x02, + 0x12, 0x04, 0xfa, 0x02, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, 0x02, 0x02, + 0x12, 0x04, 0xfb, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, 0x02, + 0x01, 0x12, 0x04, 0xfb, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, 0x02, + 0x02, 0x02, 0x12, 0x04, 0xfb, 0x02, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x22, 0x04, 0x00, + 0x02, 0x03, 0x12, 0x04, 0xfc, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, 0x00, + 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x22, 0x04, + 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xfc, 0x02, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, + 0x02, 0x00, 0x12, 0x04, 0xfe, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, + 0x05, 0x12, 0x04, 0xfe, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x01, + 0x12, 0x04, 0xfe, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x03, 0x12, + 0x04, 0xfe, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x01, 0x12, 0x04, 0xff, + 0x02, 0x02, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x06, 0x12, 0x04, 0xff, 0x02, + 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x01, 0x12, 0x04, 0xff, 0x02, 0x1a, + 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, 0x03, 0x12, 0x04, 0xff, 0x02, 0x27, 0x28, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x02, 0x12, 0x04, 0x80, 0x03, 0x02, 0x14, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x05, 0x12, 0x04, 0x80, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x22, 0x02, 0x02, 0x01, 0x12, 0x04, 0x80, 0x03, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x22, 0x02, 0x02, 0x03, 0x12, 0x04, 0x80, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x22, 0x02, 0x03, 0x12, 0x04, 0x81, 0x03, 0x02, 0x40, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, + 0x03, 0x04, 0x12, 0x04, 0x81, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, + 0x06, 0x12, 0x04, 0x81, 0x03, 0x0b, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x01, + 0x12, 0x04, 0x81, 0x03, 0x28, 0x3b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x03, 0x12, + 0x04, 0x81, 0x03, 0x3e, 0x3f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x04, 0x12, 0x04, 0x82, + 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x04, 0x12, 0x04, 0x82, 0x03, + 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x06, 0x12, 0x04, 0x82, 0x03, 0x0b, + 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x01, 0x12, 0x04, 0x82, 0x03, 0x14, 0x1a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x03, 0x12, 0x04, 0x82, 0x03, 0x1d, 0x1e, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x05, 0x12, 0x04, 0x83, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x22, 0x02, 0x05, 0x04, 0x12, 0x04, 0x83, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x22, 0x02, 0x05, 0x06, 0x12, 0x04, 0x83, 0x03, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x22, 0x02, 0x05, 0x01, 0x12, 0x04, 0x83, 0x03, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, + 0x02, 0x05, 0x03, 0x12, 0x04, 0x83, 0x03, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x23, 0x12, + 0x06, 0x86, 0x03, 0x00, 0x8e, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x23, 0x01, 0x12, 0x04, + 0x86, 0x03, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x00, 0x12, 0x04, 0x87, 0x03, + 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x03, 0x02, + 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x01, 0x12, 0x04, 0x87, 0x03, 0x09, 0x0d, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x03, 0x12, 0x04, 0x87, 0x03, 0x10, 0x11, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x01, 0x12, 0x04, 0x88, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x23, 0x02, 0x01, 0x05, 0x12, 0x04, 0x88, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x23, 0x02, 0x01, 0x01, 0x12, 0x04, 0x88, 0x03, 0x07, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x23, 0x02, 0x01, 0x03, 0x12, 0x04, 0x88, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, + 0x02, 0x02, 0x12, 0x04, 0x89, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, + 0x05, 0x12, 0x04, 0x89, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, 0x01, + 0x12, 0x04, 0x89, 0x03, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x02, 0x03, 0x12, + 0x04, 0x89, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x03, 0x12, 0x04, 0x8a, + 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x05, 0x12, 0x04, 0x8a, 0x03, + 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x01, 0x12, 0x04, 0x8a, 0x03, 0x07, + 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x03, 0x03, 0x12, 0x04, 0x8a, 0x03, 0x11, 0x12, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x04, 0x12, 0x04, 0x8b, 0x03, 0x02, 0x25, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x23, 0x02, 0x04, 0x04, 0x12, 0x04, 0x8b, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x23, 0x02, 0x04, 0x06, 0x12, 0x04, 0x8b, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x23, 0x02, 0x04, 0x01, 0x12, 0x04, 0x8b, 0x03, 0x17, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x23, 0x02, 0x04, 0x03, 0x12, 0x04, 0x8b, 0x03, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, + 0x02, 0x05, 0x12, 0x04, 0x8c, 0x03, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, + 0x04, 0x12, 0x04, 0x8c, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x06, + 0x12, 0x04, 0x8c, 0x03, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x01, 0x12, + 0x04, 0x8c, 0x03, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x05, 0x03, 0x12, 0x04, + 0x8c, 0x03, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x06, 0x12, 0x04, 0x8d, 0x03, + 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x06, 0x04, 0x12, 0x04, 0x8d, 0x03, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x06, 0x06, 0x12, 0x04, 0x8d, 0x03, 0x0b, 0x1a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x06, 0x01, 0x12, 0x04, 0x8d, 0x03, 0x1b, 0x21, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x06, 0x03, 0x12, 0x04, 0x8d, 0x03, 0x24, 0x25, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x24, 0x12, 0x06, 0x90, 0x03, 0x00, 0x93, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x24, 0x01, 0x12, 0x04, 0x90, 0x03, 0x08, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x24, 0x02, + 0x00, 0x12, 0x04, 0x91, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x04, + 0x12, 0x04, 0x91, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x06, 0x12, + 0x04, 0x91, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x01, 0x12, 0x04, + 0x91, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x03, 0x12, 0x04, 0x91, + 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x24, 0x02, 0x01, 0x12, 0x04, 0x92, 0x03, 0x02, + 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x05, 0x12, 0x04, 0x92, 0x03, 0x02, 0x06, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x01, 0x12, 0x04, 0x92, 0x03, 0x07, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x03, 0x12, 0x04, 0x92, 0x03, 0x14, 0x15, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x25, 0x12, 0x06, 0x95, 0x03, 0x00, 0x98, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x25, 0x01, 0x12, 0x04, 0x95, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x25, 0x02, + 0x00, 0x12, 0x04, 0x96, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, 0x05, + 0x12, 0x04, 0x96, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, 0x01, 0x12, + 0x04, 0x96, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, 0x03, 0x12, 0x04, + 0x96, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x25, 0x02, 0x01, 0x12, 0x04, 0x97, 0x03, + 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x06, 0x12, 0x04, 0x97, 0x03, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x01, 0x12, 0x04, 0x97, 0x03, 0x0b, 0x0f, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x01, 0x03, 0x12, 0x04, 0x97, 0x03, 0x12, 0x13, 0x0a, + 0x0c, 0x0a, 0x02, 0x04, 0x26, 0x12, 0x06, 0x9a, 0x03, 0x00, 0x9c, 0x03, 0x01, 0x0a, 0x0b, 0x0a, + 0x03, 0x04, 0x26, 0x01, 0x12, 0x04, 0x9a, 0x03, 0x08, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, + 0x02, 0x00, 0x12, 0x04, 0x9b, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, + 0x04, 0x12, 0x04, 0x9b, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x06, + 0x12, 0x04, 0x9b, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x01, 0x12, + 0x04, 0x9b, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x03, 0x12, 0x04, + 0x9b, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x06, 0x9e, 0x03, 0x00, 0xae, + 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x04, 0x9e, 0x03, 0x05, 0x0e, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x9f, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x01, 0x12, 0x04, 0xa0, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x01, 0x01, 0x12, 0x04, 0xa0, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, + 0x02, 0x12, 0x04, 0xa0, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x02, 0x12, + 0x04, 0xa1, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xa1, 0x03, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xa1, + 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x03, 0x12, 0x04, 0xa2, 0x03, 0x02, + 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa2, 0x03, 0x02, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xa2, 0x03, 0x13, 0x15, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x04, 0x12, 0x04, 0xa3, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xa3, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xa3, 0x03, 0x13, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x05, 0x12, 0x04, 0xa4, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x05, 0x01, 0x12, 0x04, 0xa4, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x05, + 0x02, 0x12, 0x04, 0xa4, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x06, 0x12, + 0x04, 0xa5, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x01, 0x12, 0x04, + 0xa5, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x02, 0x12, 0x04, 0xa5, + 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x07, 0x12, 0x04, 0xa6, 0x03, 0x02, + 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x01, 0x12, 0x04, 0xa6, 0x03, 0x02, 0x11, + 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x02, 0x12, 0x04, 0xa6, 0x03, 0x14, 0x16, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x08, 0x12, 0x04, 0xa7, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x08, 0x01, 0x12, 0x04, 0xa7, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x08, 0x02, 0x12, 0x04, 0xa7, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x09, 0x12, 0x04, 0xa8, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x09, 0x01, 0x12, 0x04, 0xa8, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x09, + 0x02, 0x12, 0x04, 0xa8, 0x03, 0x16, 0x17, 0x0a, 0x2b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0a, 0x12, + 0x04, 0xa9, 0x03, 0x02, 0x18, 0x22, 0x1d, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x3a, 0x20, 0x42, 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3e, 0x20, + 0x7d, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x01, 0x12, 0x04, 0xa9, + 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x02, 0x12, 0x04, 0xa9, 0x03, + 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0b, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x18, + 0x22, 0x14, 0x20, 0x60, 0x28, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, + 0x61, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, 0x01, 0x12, + 0x04, 0xaa, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, 0x02, 0x12, 0x04, + 0xaa, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0c, 0x12, 0x04, 0xab, 0x03, + 0x02, 0x24, 0x22, 0x14, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, + 0x31, 0x36, 0x20, 0x7d, 0x60, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0c, + 0x01, 0x12, 0x04, 0xab, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0c, 0x02, + 0x12, 0x04, 0xab, 0x03, 0x22, 0x23, 0x0a, 0x37, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0d, 0x12, 0x04, + 0xac, 0x03, 0x02, 0x1c, 0x22, 0x29, 0x20, 0x60, 0x7b, 0x20, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x74, 0x6f, 0x3a, 0x20, 0x42, 0x6f, 0x78, + 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3e, 0x20, 0x7d, 0x60, 0x2c, 0x0a, 0x0a, + 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x01, 0x12, 0x04, 0xac, 0x03, 0x02, 0x16, 0x0a, 0x0d, + 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x02, 0x12, 0x04, 0xac, 0x03, 0x19, 0x1b, 0x0a, 0x1b, 0x0a, + 0x04, 0x05, 0x00, 0x02, 0x0e, 0x12, 0x04, 0xad, 0x03, 0x02, 0x1d, 0x22, 0x0d, 0x20, 0x60, 0x28, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, + 0x02, 0x0e, 0x01, 0x12, 0x04, 0xad, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x0e, 0x02, 0x12, 0x04, 0xad, 0x03, 0x1a, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x27, 0x12, 0x06, + 0xb0, 0x03, 0x00, 0xbe, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x27, 0x01, 0x12, 0x04, 0xb0, + 0x03, 0x08, 0x10, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x27, 0x03, 0x00, 0x12, 0x06, 0xb1, 0x03, 0x02, + 0xb4, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x03, 0x00, 0x01, 0x12, 0x04, 0xb1, 0x03, + 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0xb2, 0x03, + 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb2, + 0x03, 0x04, 0x08, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xb2, 0x03, 0x09, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, + 0x04, 0xb2, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x27, 0x03, 0x00, 0x02, 0x01, 0x12, + 0x04, 0xb3, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x01, 0x06, + 0x12, 0x04, 0xb3, 0x03, 0x04, 0x0c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, 0x01, + 0x01, 0x12, 0x04, 0xb3, 0x03, 0x0d, 0x0f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x27, 0x03, 0x00, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xb3, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x00, + 0x12, 0x04, 0xb6, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, 0x06, 0x12, + 0x04, 0xb6, 0x03, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xb6, 0x03, 0x0c, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb6, + 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x27, 0x08, 0x00, 0x12, 0x06, 0xb7, 0x03, 0x02, + 0xbd, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x08, 0x00, 0x01, 0x12, 0x04, 0xb7, 0x03, + 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x01, 0x12, 0x04, 0xb8, 0x03, 0x04, 0x18, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb8, 0x03, 0x04, 0x0c, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb8, 0x03, 0x0d, 0x13, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x27, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb8, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x27, 0x02, 0x02, 0x12, 0x04, 0xb9, 0x03, 0x04, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x27, 0x02, 0x02, 0x06, 0x12, 0x04, 0xb9, 0x03, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, + 0x02, 0x02, 0x01, 0x12, 0x04, 0xb9, 0x03, 0x12, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, + 0x02, 0x03, 0x12, 0x04, 0xb9, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x03, + 0x12, 0x04, 0xba, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, 0x05, 0x12, + 0x04, 0xba, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, 0x01, 0x12, 0x04, + 0xba, 0x03, 0x0b, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x03, 0x03, 0x12, 0x04, 0xba, + 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x04, 0x12, 0x04, 0xbb, 0x03, 0x04, + 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x06, 0x12, 0x04, 0xbb, 0x03, 0x04, 0x11, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x01, 0x12, 0x04, 0xbb, 0x03, 0x12, 0x1b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, 0x04, 0x03, 0x12, 0x04, 0xbb, 0x03, 0x1e, 0x1f, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x27, 0x02, 0x05, 0x12, 0x04, 0xbc, 0x03, 0x04, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x27, 0x02, 0x05, 0x05, 0x12, 0x04, 0xbc, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x27, 0x02, 0x05, 0x01, 0x12, 0x04, 0xbc, 0x03, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, + 0x02, 0x05, 0x03, 0x12, 0x04, 0xbc, 0x03, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x05, 0x01, 0x12, + 0x06, 0xc0, 0x03, 0x00, 0xc6, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x01, 0x01, 0x12, 0x04, + 0xc0, 0x03, 0x05, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x00, 0x12, 0x04, 0xc1, 0x03, + 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc1, 0x03, 0x02, + 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc1, 0x03, 0x1d, 0x1e, + 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x01, 0x02, 0x01, 0x02, 0x12, 0x04, 0xc2, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, + 0x05, 0x01, 0x02, 0x02, 0x12, 0x04, 0xc3, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, + 0x02, 0x02, 0x01, 0x12, 0x04, 0xc3, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, + 0x02, 0x02, 0x12, 0x04, 0xc3, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x03, + 0x12, 0x04, 0xc4, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, 0x01, 0x12, + 0x04, 0xc4, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, 0x02, 0x12, 0x04, + 0xc4, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x04, 0x12, 0x04, 0xc5, 0x03, + 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x01, 0x12, 0x04, 0xc5, 0x03, 0x02, + 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x02, 0x12, 0x04, 0xc5, 0x03, 0x15, 0x16, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x28, 0x12, 0x06, 0xc8, 0x03, 0x00, 0xca, 0x03, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x28, 0x01, 0x12, 0x04, 0xc8, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x28, 0x02, 0x00, 0x12, 0x04, 0xc9, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, + 0x00, 0x06, 0x12, 0x04, 0xc9, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, + 0x01, 0x12, 0x04, 0xc9, 0x03, 0x0b, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x03, + 0x12, 0x04, 0xc9, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x29, 0x12, 0x06, 0xcc, 0x03, + 0x00, 0xcf, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x29, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x08, + 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x00, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x1a, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x06, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x0e, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcd, 0x03, 0x0f, 0x15, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x29, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcd, 0x03, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x29, 0x02, 0x01, 0x12, 0x04, 0xce, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, + 0x02, 0x01, 0x05, 0x12, 0x04, 0xce, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, + 0x01, 0x01, 0x12, 0x04, 0xce, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x01, + 0x03, 0x12, 0x04, 0xce, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2a, 0x12, 0x06, 0xd1, + 0x03, 0x00, 0xd4, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2a, 0x01, 0x12, 0x04, 0xd1, 0x03, + 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x03, 0x02, 0x15, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd2, 0x03, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x03, 0x09, 0x10, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd2, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x2a, 0x02, 0x01, 0x12, 0x04, 0xd3, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd3, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xd3, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xd3, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2b, 0x12, 0x06, + 0xd6, 0x03, 0x00, 0xdb, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2b, 0x01, 0x12, 0x04, 0xd6, + 0x03, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x00, 0x12, 0x04, 0xd7, 0x03, 0x02, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd7, 0x03, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x03, 0x09, 0x10, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd7, 0x03, 0x13, 0x14, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x01, 0x12, 0x04, 0xd8, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2b, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd8, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd8, 0x03, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xd8, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, + 0x02, 0x12, 0x04, 0xd9, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, 0x05, + 0x12, 0x04, 0xd9, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, 0x01, 0x12, + 0x04, 0xd9, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, 0x03, 0x12, 0x04, + 0xd9, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x03, 0x12, 0x04, 0xda, 0x03, + 0x02, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x04, 0x12, 0x04, 0xda, 0x03, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x06, 0x12, 0x04, 0xda, 0x03, 0x0b, 0x13, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x01, 0x12, 0x04, 0xda, 0x03, 0x14, 0x27, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x03, 0x12, 0x04, 0xda, 0x03, 0x2a, 0x2b, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x2c, 0x12, 0x06, 0xdd, 0x03, 0x00, 0xf1, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x2c, 0x01, 0x12, 0x04, 0xdd, 0x03, 0x08, 0x11, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x2c, 0x04, + 0x00, 0x12, 0x06, 0xde, 0x03, 0x02, 0xe6, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x04, + 0x00, 0x01, 0x12, 0x04, 0xde, 0x03, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, + 0x02, 0x00, 0x01, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, + 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdf, 0x03, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, + 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xe0, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, + 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe0, 0x03, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x2c, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xe0, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, + 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xe1, 0x03, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xe1, 0x03, 0x04, 0x16, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xe1, 0x03, 0x19, 0x1a, 0x0a, 0x0e, + 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xe2, 0x03, 0x04, 0x19, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe2, 0x03, 0x04, 0x14, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xe2, 0x03, 0x17, 0x18, + 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xe3, 0x03, 0x04, 0x17, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe3, 0x03, 0x04, + 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xe3, 0x03, + 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0xe4, 0x03, + 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe4, + 0x03, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, + 0xe4, 0x03, 0x19, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x12, 0x04, 0xe5, + 0x03, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, 0xe5, + 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, 0x04, + 0xe5, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2c, 0x04, 0x00, 0x04, 0x00, 0x02, 0x12, + 0x04, 0xe5, 0x03, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x00, 0x12, 0x04, 0xe8, + 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe8, 0x03, + 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x03, 0x07, + 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe8, 0x03, 0x0e, 0x0f, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x2c, 0x08, 0x00, 0x12, 0x06, 0xe9, 0x03, 0x02, 0xf0, 0x03, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x08, 0x11, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x01, 0x12, 0x04, 0xea, 0x03, 0x04, 0x21, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xea, 0x03, 0x04, 0x14, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xea, 0x03, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xea, 0x03, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, + 0x02, 0x02, 0x12, 0x04, 0xeb, 0x03, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x02, + 0x06, 0x12, 0x04, 0xeb, 0x03, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xeb, 0x03, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xeb, 0x03, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x03, 0x12, 0x04, 0xec, + 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x06, 0x12, 0x04, 0xec, 0x03, + 0x04, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x01, 0x12, 0x04, 0xec, 0x03, 0x18, + 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x03, 0x03, 0x12, 0x04, 0xec, 0x03, 0x26, 0x27, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x04, 0x12, 0x04, 0xed, 0x03, 0x04, 0x24, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xed, 0x03, 0x04, 0x15, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xed, 0x03, 0x16, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xed, 0x03, 0x22, 0x23, 0x0a, 0x1e, 0x0a, 0x04, 0x04, + 0x2c, 0x02, 0x05, 0x12, 0x04, 0xef, 0x03, 0x04, 0x23, 0x1a, 0x10, 0x20, 0x36, 0x20, 0x69, 0x73, + 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xef, 0x03, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, + 0x02, 0x05, 0x01, 0x12, 0x04, 0xef, 0x03, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, + 0x05, 0x03, 0x12, 0x04, 0xef, 0x03, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2d, 0x12, 0x06, + 0xf3, 0x03, 0x00, 0xf6, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2d, 0x01, 0x12, 0x04, 0xf3, + 0x03, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x00, 0x12, 0x04, 0xf4, 0x03, 0x02, + 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x07, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf4, 0x03, 0x08, 0x12, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf4, 0x03, 0x15, 0x16, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x01, 0x12, 0x04, 0xf5, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf5, 0x03, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf5, 0x03, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xf5, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2e, 0x12, + 0x06, 0xf8, 0x03, 0x00, 0xfd, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2e, 0x01, 0x12, 0x04, + 0xf8, 0x03, 0x08, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x03, + 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x04, 0x12, 0x04, 0xf9, 0x03, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x03, 0x0b, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x03, 0x11, 0x1c, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x03, 0x1f, 0x20, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x01, 0x12, 0x04, 0xfa, 0x03, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2e, 0x02, 0x01, 0x04, 0x12, 0x04, 0xfa, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2e, 0x02, 0x01, 0x05, 0x12, 0x04, 0xfa, 0x03, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xfa, 0x03, 0x11, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xfa, 0x03, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x02, + 0x12, 0x04, 0xfb, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x05, 0x12, + 0x04, 0xfb, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xfb, 0x03, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfb, + 0x03, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x03, 0x12, 0x04, 0xfc, 0x03, 0x02, + 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x04, 0x12, 0x04, 0xfc, 0x03, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfc, 0x03, 0x0b, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x03, 0x12, 0x24, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfc, 0x03, 0x27, 0x28, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x2f, 0x12, 0x06, 0xff, 0x03, 0x00, 0x83, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x2f, 0x01, 0x12, 0x04, 0xff, 0x03, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x00, + 0x12, 0x04, 0x80, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x06, 0x12, + 0x04, 0x80, 0x04, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x01, 0x12, 0x04, + 0x80, 0x04, 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x03, 0x12, 0x04, 0x80, + 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x01, 0x12, 0x04, 0x81, 0x04, 0x02, + 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x04, 0x12, 0x04, 0x81, 0x04, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x05, 0x12, 0x04, 0x81, 0x04, 0x0b, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x01, 0x12, 0x04, 0x81, 0x04, 0x12, 0x2c, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x03, 0x12, 0x04, 0x81, 0x04, 0x2f, 0x30, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x2f, 0x02, 0x02, 0x12, 0x04, 0x82, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2f, 0x02, 0x02, 0x04, 0x12, 0x04, 0x82, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, + 0x02, 0x02, 0x06, 0x12, 0x04, 0x82, 0x04, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, + 0x02, 0x01, 0x12, 0x04, 0x82, 0x04, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, + 0x03, 0x12, 0x04, 0x82, 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x30, 0x12, 0x06, 0x85, + 0x04, 0x00, 0x8b, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x30, 0x01, 0x12, 0x04, 0x85, 0x04, + 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x00, 0x12, 0x04, 0x86, 0x04, 0x02, 0x1e, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x06, 0x12, 0x04, 0x86, 0x04, 0x02, 0x12, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x01, 0x12, 0x04, 0x86, 0x04, 0x13, 0x19, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x03, 0x12, 0x04, 0x86, 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x30, 0x02, 0x01, 0x12, 0x04, 0x87, 0x04, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x30, 0x02, 0x01, 0x04, 0x12, 0x04, 0x87, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, + 0x02, 0x01, 0x05, 0x12, 0x04, 0x87, 0x04, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, + 0x01, 0x01, 0x12, 0x04, 0x87, 0x04, 0x12, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x01, + 0x03, 0x12, 0x04, 0x87, 0x04, 0x2f, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x02, 0x12, + 0x04, 0x88, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x04, 0x12, 0x04, + 0x88, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x06, 0x12, 0x04, 0x88, + 0x04, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x01, 0x12, 0x04, 0x88, 0x04, + 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x02, 0x03, 0x12, 0x04, 0x88, 0x04, 0x30, + 0x31, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x03, 0x12, 0x04, 0x89, 0x04, 0x02, 0x1f, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x03, 0x05, 0x12, 0x04, 0x89, 0x04, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x30, 0x02, 0x03, 0x01, 0x12, 0x04, 0x89, 0x04, 0x09, 0x1a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x30, 0x02, 0x03, 0x03, 0x12, 0x04, 0x89, 0x04, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x30, 0x02, 0x04, 0x12, 0x04, 0x8a, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, + 0x02, 0x04, 0x06, 0x12, 0x04, 0x8a, 0x04, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, + 0x04, 0x01, 0x12, 0x04, 0x8a, 0x04, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x04, + 0x03, 0x12, 0x04, 0x8a, 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x31, 0x12, 0x06, 0x8d, + 0x04, 0x00, 0x99, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x31, 0x01, 0x12, 0x04, 0x8d, 0x04, + 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x31, 0x04, 0x00, 0x12, 0x06, 0x8e, 0x04, 0x02, 0x95, + 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x04, 0x00, 0x01, 0x12, 0x04, 0x8e, 0x04, 0x07, + 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x8f, 0x04, 0x04, + 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8f, 0x04, + 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x8f, + 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x90, + 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x90, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x04, 0x90, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x04, 0x91, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x04, 0x91, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0x91, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, + 0x03, 0x12, 0x04, 0x92, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x04, 0x92, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, + 0x02, 0x03, 0x02, 0x12, 0x04, 0x92, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, + 0x00, 0x02, 0x04, 0x12, 0x04, 0x93, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, + 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x93, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, + 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x93, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x31, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0x94, 0x04, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x31, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x94, 0x04, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x31, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0x94, 0x04, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x31, 0x02, 0x00, 0x12, 0x04, 0x97, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x31, 0x02, 0x00, 0x06, 0x12, 0x04, 0x97, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x97, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x97, 0x04, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x01, + 0x12, 0x04, 0x98, 0x04, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x05, 0x12, + 0x04, 0x98, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x98, 0x04, 0x08, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x03, 0x12, 0x04, 0x98, + 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x32, 0x12, 0x06, 0x9b, 0x04, 0x00, 0xb1, 0x04, + 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x32, 0x01, 0x12, 0x04, 0x9b, 0x04, 0x08, 0x14, 0x0a, 0x0e, + 0x0a, 0x04, 0x04, 0x32, 0x04, 0x00, 0x12, 0x06, 0x9c, 0x04, 0x02, 0xa2, 0x04, 0x03, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x32, 0x04, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x9d, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9d, 0x04, 0x04, 0x14, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x9d, 0x04, 0x17, 0x18, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x9e, 0x04, 0x04, 0x15, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9e, 0x04, 0x04, 0x10, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0x9e, 0x04, 0x13, + 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0x9f, 0x04, 0x04, + 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0x9f, 0x04, + 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0x9f, + 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xa0, + 0x04, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, + 0xa0, 0x04, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, + 0x04, 0xa0, 0x04, 0x14, 0x15, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x04, 0x00, 0x02, 0x04, 0x12, + 0x04, 0xa1, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x04, 0x01, + 0x12, 0x04, 0xa1, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x32, 0x04, 0x00, 0x02, 0x04, + 0x02, 0x12, 0x04, 0xa1, 0x04, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x00, 0x12, + 0x04, 0xa4, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x06, 0x12, 0x04, + 0xa4, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa4, + 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa4, 0x04, + 0x0e, 0x0f, 0x0a, 0x64, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x01, 0x12, 0x04, 0xa8, 0x04, 0x02, 0x2a, + 0x1a, 0x56, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x3a, 0x20, 0x75, + 0x73, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0x0a, 0x20, 0x4e, + 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2c, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, 0x72, + 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, + 0x05, 0x12, 0x04, 0xa8, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xa8, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xa8, 0x04, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x01, 0x08, 0x12, 0x04, + 0xa8, 0x04, 0x16, 0x29, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x32, 0x02, 0x01, 0x08, 0x03, 0x12, 0x04, + 0xa8, 0x04, 0x17, 0x28, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x32, 0x08, 0x00, 0x12, 0x06, 0xab, 0x04, + 0x02, 0xb0, 0x04, 0x03, 0x1a, 0x13, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x20, + 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x08, + 0x00, 0x01, 0x12, 0x04, 0xab, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x02, + 0x12, 0x04, 0xac, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, 0x06, 0x12, + 0x04, 0xac, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xac, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x02, 0x03, 0x12, 0x04, 0xac, + 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x03, 0x12, 0x04, 0xad, 0x04, 0x04, + 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x06, 0x12, 0x04, 0xad, 0x04, 0x04, 0x12, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x01, 0x12, 0x04, 0xad, 0x04, 0x13, 0x22, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x03, 0x03, 0x12, 0x04, 0xad, 0x04, 0x25, 0x26, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x32, 0x02, 0x04, 0x12, 0x04, 0xae, 0x04, 0x04, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x32, 0x02, 0x04, 0x06, 0x12, 0x04, 0xae, 0x04, 0x04, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x32, 0x02, 0x04, 0x01, 0x12, 0x04, 0xae, 0x04, 0x0d, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, + 0x02, 0x04, 0x03, 0x12, 0x04, 0xae, 0x04, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, + 0x05, 0x12, 0x04, 0xaf, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x05, 0x06, + 0x12, 0x04, 0xaf, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x05, 0x01, 0x12, + 0x04, 0xaf, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x05, 0x03, 0x12, 0x04, + 0xaf, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x33, 0x12, 0x06, 0xb3, 0x04, 0x00, 0xb5, + 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x33, 0x01, 0x12, 0x04, 0xb3, 0x04, 0x08, 0x0f, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x33, 0x02, 0x00, 0x12, 0x04, 0xb4, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x33, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb4, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x33, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb4, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x33, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb4, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x34, + 0x12, 0x06, 0xb7, 0x04, 0x00, 0xb9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x34, 0x01, 0x12, + 0x04, 0xb7, 0x04, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x34, 0x02, 0x00, 0x12, 0x04, 0xb8, + 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb8, 0x04, + 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb8, 0x04, 0x08, + 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb8, 0x04, 0x14, 0x15, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x35, 0x12, 0x06, 0xbb, 0x04, 0x00, 0xbd, 0x04, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x35, 0x01, 0x12, 0x04, 0xbb, 0x04, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x35, 0x02, 0x00, 0x12, 0x04, 0xbc, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, + 0x00, 0x05, 0x12, 0x04, 0xbc, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, + 0x01, 0x12, 0x04, 0xbc, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x03, + 0x12, 0x04, 0xbc, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x36, 0x12, 0x06, 0xbf, 0x04, + 0x00, 0xc1, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x36, 0x01, 0x12, 0x04, 0xbf, 0x04, 0x08, + 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x36, 0x02, 0x00, 0x12, 0x04, 0xc0, 0x04, 0x02, 0x16, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc0, 0x04, 0x02, 0x07, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc0, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x36, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc0, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x37, 0x12, 0x06, 0xc3, 0x04, 0x00, 0xc6, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x37, + 0x01, 0x12, 0x04, 0xc3, 0x04, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, 0x00, 0x12, + 0x04, 0xc4, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x06, 0x12, 0x04, + 0xc4, 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc4, + 0x04, 0x0f, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc4, 0x04, + 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, 0x01, 0x12, 0x04, 0xc5, 0x04, 0x02, 0x1d, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc5, 0x04, 0x02, 0x0e, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc5, 0x04, 0x0f, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc5, 0x04, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x38, 0x12, 0x06, 0xc8, 0x04, 0x00, 0xcb, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x38, 0x01, 0x12, 0x04, 0xc8, 0x04, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x00, + 0x12, 0x04, 0xc9, 0x04, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x05, 0x12, + 0x04, 0xc9, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xc9, 0x04, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc9, + 0x04, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x01, 0x12, 0x04, 0xca, 0x04, 0x02, + 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x06, 0x12, 0x04, 0xca, 0x04, 0x02, 0x0e, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x01, 0x12, 0x04, 0xca, 0x04, 0x0f, 0x18, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x03, 0x12, 0x04, 0xca, 0x04, 0x1b, 0x1c, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x39, 0x12, 0x06, 0xcd, 0x04, 0x00, 0xd1, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x39, 0x01, 0x12, 0x04, 0xcd, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, + 0x00, 0x12, 0x04, 0xce, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x04, + 0x12, 0x04, 0xce, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x06, 0x12, + 0x04, 0xce, 0x04, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xce, 0x04, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x03, 0x12, 0x04, 0xce, + 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x01, 0x12, 0x04, 0xcf, 0x04, 0x02, + 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x04, 0x12, 0x04, 0xcf, 0x04, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x06, 0x12, 0x04, 0xcf, 0x04, 0x0b, 0x1b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcf, 0x04, 0x1c, 0x26, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x03, 0x12, 0x04, 0xcf, 0x04, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x39, 0x02, 0x02, 0x12, 0x04, 0xd0, 0x04, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x39, 0x02, 0x02, 0x05, 0x12, 0x04, 0xd0, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, + 0x02, 0x02, 0x01, 0x12, 0x04, 0xd0, 0x04, 0x09, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, + 0x02, 0x03, 0x12, 0x04, 0xd0, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3a, 0x12, 0x06, + 0xd3, 0x04, 0x00, 0xd6, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3a, 0x01, 0x12, 0x04, 0xd3, + 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x00, 0x12, 0x04, 0xd4, 0x04, 0x02, + 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd4, 0x04, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd4, 0x04, 0x09, 0x16, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd4, 0x04, 0x19, 0x1a, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x01, 0x12, 0x04, 0xd5, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xd5, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd5, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xd5, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3b, 0x12, + 0x06, 0xd8, 0x04, 0x00, 0xda, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3b, 0x01, 0x12, 0x04, + 0xd8, 0x04, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x00, 0x12, 0x04, 0xd9, 0x04, + 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd9, 0x04, 0x02, + 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd9, 0x04, 0x13, 0x19, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd9, 0x04, 0x1c, 0x1d, 0x0a, + 0x0c, 0x0a, 0x02, 0x04, 0x3c, 0x12, 0x06, 0xdc, 0x04, 0x00, 0xf1, 0x04, 0x01, 0x0a, 0x0b, 0x0a, + 0x03, 0x04, 0x3c, 0x01, 0x12, 0x04, 0xdc, 0x04, 0x08, 0x18, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x3c, + 0x04, 0x00, 0x12, 0x06, 0xdd, 0x04, 0x02, 0xe6, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, + 0x04, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, + 0x00, 0x02, 0x00, 0x12, 0x04, 0xde, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, + 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xde, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, + 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xde, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x3c, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x3c, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x3c, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xdf, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xe0, 0x04, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xe0, 0x04, 0x04, 0x16, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xe0, 0x04, 0x19, 0x1a, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xe1, 0x04, 0x04, 0x18, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe1, 0x04, 0x04, 0x13, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xe1, 0x04, 0x16, + 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xe2, 0x04, 0x04, + 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe2, 0x04, + 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xe2, + 0x04, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0xe3, + 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, + 0xe3, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, + 0x04, 0xe3, 0x04, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x12, 0x04, + 0xe5, 0x04, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, + 0xe5, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, + 0x04, 0xe5, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3c, 0x04, 0x00, 0x04, 0x00, 0x02, + 0x12, 0x04, 0xe5, 0x04, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x00, 0x12, 0x04, + 0xe8, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe8, + 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x04, + 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe8, 0x04, 0x0e, + 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x3c, 0x08, 0x00, 0x12, 0x06, 0xe9, 0x04, 0x02, 0xf0, 0x04, + 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x08, 0x00, 0x01, 0x12, 0x04, 0xe9, 0x04, 0x08, 0x11, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x01, 0x12, 0x04, 0xea, 0x04, 0x04, 0x21, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xea, 0x04, 0x04, 0x14, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x3c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xea, 0x04, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xea, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x3c, 0x02, 0x02, 0x12, 0x04, 0xeb, 0x04, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, + 0x02, 0x06, 0x12, 0x04, 0xeb, 0x04, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x02, + 0x01, 0x12, 0x04, 0xeb, 0x04, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x02, 0x03, + 0x12, 0x04, 0xeb, 0x04, 0x2a, 0x2b, 0x0a, 0x1e, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x03, 0x12, 0x04, + 0xed, 0x04, 0x04, 0x30, 0x1a, 0x10, 0x20, 0x34, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, 0x06, 0x12, + 0x04, 0xed, 0x04, 0x04, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, 0x01, 0x12, 0x04, + 0xed, 0x04, 0x17, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x03, 0x03, 0x12, 0x04, 0xed, + 0x04, 0x2e, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x04, 0x12, 0x04, 0xee, 0x04, 0x04, + 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xee, 0x04, 0x04, 0x15, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xee, 0x04, 0x16, 0x29, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xee, 0x04, 0x2c, 0x2d, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x05, 0x12, 0x04, 0xef, 0x04, 0x04, 0x26, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xef, 0x04, 0x04, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xef, 0x04, 0x16, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, + 0x02, 0x05, 0x03, 0x12, 0x04, 0xef, 0x04, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3d, 0x12, + 0x06, 0xf3, 0x04, 0x00, 0xf7, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3d, 0x01, 0x12, 0x04, + 0xf3, 0x04, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x00, 0x12, 0x04, 0xf4, 0x04, + 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf4, 0x04, 0x02, + 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf4, 0x04, 0x09, 0x1a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf4, 0x04, 0x1d, 0x1e, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x01, 0x12, 0x04, 0xf5, 0x04, 0x02, 0x2d, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x3d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xf5, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xf5, 0x04, 0x0b, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf5, 0x04, 0x19, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xf5, 0x04, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, + 0x02, 0x12, 0x04, 0xf6, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x04, + 0x12, 0x04, 0xf6, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x06, 0x12, + 0x04, 0xf6, 0x04, 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xf6, 0x04, 0x1b, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x02, 0x03, 0x12, 0x04, 0xf6, + 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3e, 0x12, 0x06, 0xf9, 0x04, 0x00, 0xfc, 0x04, + 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3e, 0x01, 0x12, 0x04, 0xf9, 0x04, 0x08, 0x15, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x3e, 0x02, 0x00, 0x12, 0x04, 0xfa, 0x04, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xfa, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfa, 0x04, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, + 0x02, 0x00, 0x03, 0x12, 0x04, 0xfa, 0x04, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3e, 0x02, + 0x01, 0x12, 0x04, 0xfb, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x01, 0x05, + 0x12, 0x04, 0xfb, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xfb, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x01, 0x03, 0x12, 0x04, + 0xfb, 0x04, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3f, 0x12, 0x06, 0xfe, 0x04, 0x00, 0x81, + 0x05, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3f, 0x01, 0x12, 0x04, 0xfe, 0x04, 0x08, 0x17, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x3f, 0x02, 0x00, 0x12, 0x04, 0xff, 0x04, 0x02, 0x17, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x3f, 0x02, 0x00, 0x05, 0x12, 0x04, 0xff, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xff, 0x04, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xff, 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3f, + 0x02, 0x01, 0x12, 0x04, 0x80, 0x05, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x01, + 0x05, 0x12, 0x04, 0x80, 0x05, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x01, 0x01, + 0x12, 0x04, 0x80, 0x05, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3f, 0x02, 0x01, 0x03, 0x12, + 0x04, 0x80, 0x05, 0x17, 0x18, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("aptos.transaction.v1.serde.rs"); // @@protoc_insertion_point(module) diff --git a/protos/rust/src/pb/aptos.transaction.v1.serde.rs b/protos/rust/src/pb/aptos.transaction.v1.serde.rs index cdf01be1e23..9bf2b487140 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.serde.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.serde.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // @generated -impl serde::Serialize for AbstractionSignature { +impl serde::Serialize for AbstractSignature { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -16,7 +16,7 @@ impl serde::Serialize for AbstractionSignature { if !self.signature.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.AbstractionSignature", len)?; + let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.AbstractSignature", len)?; if !self.function_info.is_empty() { struct_ser.serialize_field("functionInfo", &self.function_info)?; } @@ -26,7 +26,7 @@ impl serde::Serialize for AbstractionSignature { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for AbstractionSignature { +impl<'de> serde::Deserialize<'de> for AbstractSignature { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -74,13 +74,13 @@ impl<'de> serde::Deserialize<'de> for AbstractionSignature { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = AbstractionSignature; + type Value = AbstractSignature; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct aptos.transaction.v1.AbstractionSignature") + formatter.write_str("struct aptos.transaction.v1.AbstractSignature") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -104,13 +104,13 @@ impl<'de> serde::Deserialize<'de> for AbstractionSignature { } } } - Ok(AbstractionSignature { + Ok(AbstractSignature { function_info: function_info__.unwrap_or_default(), signature: signature__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("aptos.transaction.v1.AbstractionSignature", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("aptos.transaction.v1.AbstractSignature", FIELDS, GeneratedVisitor) } } impl serde::Serialize for AccountSignature { @@ -4407,6 +4407,9 @@ impl serde::Serialize for MoveStruct { if self.is_event { len += 1; } + if self.is_enum { + len += 1; + } if !self.abilities.is_empty() { len += 1; } @@ -4426,6 +4429,9 @@ impl serde::Serialize for MoveStruct { if self.is_event { struct_ser.serialize_field("isEvent", &self.is_event)?; } + if self.is_enum { + struct_ser.serialize_field("isEnum", &self.is_enum)?; + } if !self.abilities.is_empty() { let v = self.abilities.iter().cloned().map(|v| { MoveAbility::from_i32(v) @@ -4454,6 +4460,8 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { "isNative", "is_event", "isEvent", + "is_enum", + "isEnum", "abilities", "generic_type_params", "genericTypeParams", @@ -4465,6 +4473,7 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { Name, IsNative, IsEvent, + IsEnum, Abilities, GenericTypeParams, Fields, @@ -4492,6 +4501,7 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { "name" => Ok(GeneratedField::Name), "isNative" | "is_native" => Ok(GeneratedField::IsNative), "isEvent" | "is_event" => Ok(GeneratedField::IsEvent), + "isEnum" | "is_enum" => Ok(GeneratedField::IsEnum), "abilities" => Ok(GeneratedField::Abilities), "genericTypeParams" | "generic_type_params" => Ok(GeneratedField::GenericTypeParams), "fields" => Ok(GeneratedField::Fields), @@ -4517,6 +4527,7 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { let mut name__ = None; let mut is_native__ = None; let mut is_event__ = None; + let mut is_enum__ = None; let mut abilities__ = None; let mut generic_type_params__ = None; let mut fields__ = None; @@ -4540,6 +4551,12 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { } is_event__ = Some(map.next_value()?); } + GeneratedField::IsEnum => { + if is_enum__.is_some() { + return Err(serde::de::Error::duplicate_field("isEnum")); + } + is_enum__ = Some(map.next_value()?); + } GeneratedField::Abilities => { if abilities__.is_some() { return Err(serde::de::Error::duplicate_field("abilities")); @@ -4564,6 +4581,7 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { name: name__.unwrap_or_default(), is_native: is_native__.unwrap_or_default(), is_event: is_event__.unwrap_or_default(), + is_enum: is_enum__.unwrap_or_default(), abilities: abilities__.unwrap_or_default(), generic_type_params: generic_type_params__.unwrap_or_default(), fields: fields__.unwrap_or_default(), diff --git a/protos/typescript/src/aptos/transaction/v1/transaction.ts b/protos/typescript/src/aptos/transaction/v1/transaction.ts index 259ac50a8bf..dbfd81b6770 100644 --- a/protos/typescript/src/aptos/transaction/v1/transaction.ts +++ b/protos/typescript/src/aptos/transaction/v1/transaction.ts @@ -805,6 +805,7 @@ export interface MoveStruct { name?: string | undefined; isNative?: boolean | undefined; isEvent?: boolean | undefined; + isEnum?: boolean | undefined; abilities?: MoveAbility[] | undefined; genericTypeParams?: MoveStructGenericTypeParam[] | undefined; fields?: MoveStructField[] | undefined; @@ -1116,7 +1117,7 @@ export interface MultiKeySignature { signaturesRequired?: number | undefined; } -export interface AbstractionSignature { +export interface AbstractSignature { functionInfo?: string | undefined; signature?: Uint8Array | undefined; } @@ -1134,7 +1135,7 @@ export interface AccountSignature { /** 4 is reserved. */ singleKeySignature?: SingleKeySignature | undefined; multiKeySignature?: MultiKeySignature | undefined; - abstraction?: AbstractionSignature | undefined; + abstraction?: AbstractSignature | undefined; } export enum AccountSignature_Type { @@ -7397,7 +7398,7 @@ export const MoveFunction = { }; function createBaseMoveStruct(): MoveStruct { - return { name: "", isNative: false, isEvent: false, abilities: [], genericTypeParams: [], fields: [] }; + return { name: "", isNative: false, isEvent: false, isEnum: false, abilities: [], genericTypeParams: [], fields: [] }; } export const MoveStruct = { @@ -7411,6 +7412,9 @@ export const MoveStruct = { if (message.isEvent === true) { writer.uint32(48).bool(message.isEvent); } + if (message.isEnum === true) { + writer.uint32(56).bool(message.isEnum); + } if (message.abilities !== undefined && message.abilities.length !== 0) { writer.uint32(26).fork(); for (const v of message.abilities) { @@ -7459,6 +7463,13 @@ export const MoveStruct = { message.isEvent = reader.bool(); continue; + case 7: + if (tag !== 56) { + break; + } + + message.isEnum = reader.bool(); + continue; case 3: if (tag === 24) { message.abilities!.push(reader.int32() as any); @@ -7536,6 +7547,7 @@ export const MoveStruct = { name: isSet(object.name) ? globalThis.String(object.name) : "", isNative: isSet(object.isNative) ? globalThis.Boolean(object.isNative) : false, isEvent: isSet(object.isEvent) ? globalThis.Boolean(object.isEvent) : false, + isEnum: isSet(object.isEnum) ? globalThis.Boolean(object.isEnum) : false, abilities: globalThis.Array.isArray(object?.abilities) ? object.abilities.map((e: any) => moveAbilityFromJSON(e)) : [], @@ -7559,6 +7571,9 @@ export const MoveStruct = { if (message.isEvent === true) { obj.isEvent = message.isEvent; } + if (message.isEnum === true) { + obj.isEnum = message.isEnum; + } if (message.abilities?.length) { obj.abilities = message.abilities.map((e) => moveAbilityToJSON(e)); } @@ -7579,6 +7594,7 @@ export const MoveStruct = { message.name = object.name ?? ""; message.isNative = object.isNative ?? false; message.isEvent = object.isEvent ?? false; + message.isEnum = object.isEnum ?? false; message.abilities = object.abilities?.map((e) => e) || []; message.genericTypeParams = object.genericTypeParams?.map((e) => MoveStructGenericTypeParam.fromPartial(e)) || []; message.fields = object.fields?.map((e) => MoveStructField.fromPartial(e)) || []; @@ -10404,12 +10420,12 @@ export const MultiKeySignature = { }, }; -function createBaseAbstractionSignature(): AbstractionSignature { +function createBaseAbstractSignature(): AbstractSignature { return { functionInfo: "", signature: new Uint8Array(0) }; } -export const AbstractionSignature = { - encode(message: AbstractionSignature, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { +export const AbstractSignature = { + encode(message: AbstractSignature, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { if (message.functionInfo !== undefined && message.functionInfo !== "") { writer.uint32(10).string(message.functionInfo); } @@ -10419,10 +10435,10 @@ export const AbstractionSignature = { return writer; }, - decode(input: _m0.Reader | Uint8Array, length?: number): AbstractionSignature { + decode(input: _m0.Reader | Uint8Array, length?: number): AbstractSignature { const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseAbstractionSignature(); + const message = createBaseAbstractSignature(); while (reader.pos < end) { const tag = reader.uint32(); switch (tag >>> 3) { @@ -10450,47 +10466,45 @@ export const AbstractionSignature = { }, // encodeTransform encodes a source of message objects. - // Transform + // Transform async *encodeTransform( - source: - | AsyncIterable - | Iterable, + source: AsyncIterable | Iterable, ): AsyncIterable { for await (const pkt of source) { if (globalThis.Array.isArray(pkt)) { for (const p of (pkt as any)) { - yield* [AbstractionSignature.encode(p).finish()]; + yield* [AbstractSignature.encode(p).finish()]; } } else { - yield* [AbstractionSignature.encode(pkt as any).finish()]; + yield* [AbstractSignature.encode(pkt as any).finish()]; } } }, // decodeTransform decodes a source of encoded messages. - // Transform + // Transform async *decodeTransform( source: AsyncIterable | Iterable, - ): AsyncIterable { + ): AsyncIterable { for await (const pkt of source) { if (globalThis.Array.isArray(pkt)) { for (const p of (pkt as any)) { - yield* [AbstractionSignature.decode(p)]; + yield* [AbstractSignature.decode(p)]; } } else { - yield* [AbstractionSignature.decode(pkt as any)]; + yield* [AbstractSignature.decode(pkt as any)]; } } }, - fromJSON(object: any): AbstractionSignature { + fromJSON(object: any): AbstractSignature { return { functionInfo: isSet(object.functionInfo) ? globalThis.String(object.functionInfo) : "", signature: isSet(object.signature) ? bytesFromBase64(object.signature) : new Uint8Array(0), }; }, - toJSON(message: AbstractionSignature): unknown { + toJSON(message: AbstractSignature): unknown { const obj: any = {}; if (message.functionInfo !== undefined && message.functionInfo !== "") { obj.functionInfo = message.functionInfo; @@ -10501,11 +10515,11 @@ export const AbstractionSignature = { return obj; }, - create(base?: DeepPartial): AbstractionSignature { - return AbstractionSignature.fromPartial(base ?? {}); + create(base?: DeepPartial): AbstractSignature { + return AbstractSignature.fromPartial(base ?? {}); }, - fromPartial(object: DeepPartial): AbstractionSignature { - const message = createBaseAbstractionSignature(); + fromPartial(object: DeepPartial): AbstractSignature { + const message = createBaseAbstractSignature(); message.functionInfo = object.functionInfo ?? ""; message.signature = object.signature ?? new Uint8Array(0); return message; @@ -10632,7 +10646,7 @@ export const AccountSignature = { MultiKeySignature.encode(message.multiKeySignature, writer.uint32(50).fork()).ldelim(); } if (message.abstraction !== undefined) { - AbstractionSignature.encode(message.abstraction, writer.uint32(58).fork()).ldelim(); + AbstractSignature.encode(message.abstraction, writer.uint32(58).fork()).ldelim(); } return writer; }, @@ -10684,7 +10698,7 @@ export const AccountSignature = { break; } - message.abstraction = AbstractionSignature.decode(reader, reader.uint32()); + message.abstraction = AbstractSignature.decode(reader, reader.uint32()); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -10738,7 +10752,7 @@ export const AccountSignature = { multiKeySignature: isSet(object.multiKeySignature) ? MultiKeySignature.fromJSON(object.multiKeySignature) : undefined, - abstraction: isSet(object.abstraction) ? AbstractionSignature.fromJSON(object.abstraction) : undefined, + abstraction: isSet(object.abstraction) ? AbstractSignature.fromJSON(object.abstraction) : undefined, }; }, @@ -10760,7 +10774,7 @@ export const AccountSignature = { obj.multiKeySignature = MultiKeySignature.toJSON(message.multiKeySignature); } if (message.abstraction !== undefined) { - obj.abstraction = AbstractionSignature.toJSON(message.abstraction); + obj.abstraction = AbstractSignature.toJSON(message.abstraction); } return obj; }, @@ -10784,7 +10798,7 @@ export const AccountSignature = { ? MultiKeySignature.fromPartial(object.multiKeySignature) : undefined; message.abstraction = (object.abstraction !== undefined && object.abstraction !== null) - ? AbstractionSignature.fromPartial(object.abstraction) + ? AbstractSignature.fromPartial(object.abstraction) : undefined; return message; }, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b7051f1e849..1bc66d36178 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.86.0" +channel = "1.90.0" # Note: we don't specify cargofmt in our toolchain because we rely on # the nightly version of cargofmt and verify formatting in CI/CD. diff --git a/rustfmt.toml b/rustfmt.toml index f1c193bbcd5..8bf6aa236ad 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,5 +1,6 @@ combine_control_expr = false -edition = "2021" +edition = "2024" +style_edition = "2021" imports_granularity = "Crate" format_macro_matchers = true group_imports = "One" diff --git a/scripts/cli/build_cli_release.sh b/scripts/cli/build_cli_release.sh index e5d7dbe98e5..1df33df6df0 100755 --- a/scripts/cli/build_cli_release.sh +++ b/scripts/cli/build_cli_release.sh @@ -31,32 +31,32 @@ OS=$(uname -s) VERSION=$(sed -n '/^\w*version = /p' "$CARGO_PATH" | sed 's/^.*=[ ]*"//g' | sed 's/".*$//g') if [[ "$SKIP_CHECKS" != "true" ]]; then - # Check that the version is well-formed, note that it should already be correct, but this double checks it - if ! [[ "$EXPECTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "$EXPECTED_VERSION is malformed, must be of the form '^[0-9]+\.[0-9]+\.[0-9]+$'" - exit 1 - fi + # Check that the version is well-formed, note that it should already be correct, but this double checks it + if ! [[ "$EXPECTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "$EXPECTED_VERSION is malformed, must be of the form '^[0-9]+\.[0-9]+\.[0-9]+$'" + exit 1 + fi - # Check that the version matches the Cargo.toml - if [[ "$EXPECTED_VERSION" != "$VERSION" ]]; then - echo "Wanted to release for $EXPECTED_VERSION, but Cargo.toml says the version is $VERSION" - exit 2 - fi + # Check that the version matches the Cargo.toml + if [[ "$EXPECTED_VERSION" != "$VERSION" ]]; then + echo "Wanted to release for $EXPECTED_VERSION, but Cargo.toml says the version is $VERSION" + exit 2 + fi - # Check that the release doesn't already exist - if curl -s --stderr /dev/null --output /dev/null --head -f "https://github.com/movementlabsxyz/aptos-core/releases/download/movement-cli-v$EXPECTED_VERSION/movement-cli-$EXPECTED_VERSION-Linux-x86_64.zip"; then - echo "$EXPECTED_VERSION already released" - exit 3 - fi + # Check that the release doesn't already exist + if curl -s --stderr /dev/null --output /dev/null --head -f "https://github.com/movement-network/aptos-core/releases/download/movement-cli-v$EXPECTED_VERSION/movement-cli-$EXPECTED_VERSION-Linux-x86_64.zip"; then + echo "$EXPECTED_VERSION already released" + exit 3 + fi else - echo "WARNING: Skipping version checks!" + echo "WARNING: Skipping version checks!" fi echo "Building release $VERSION of $NAME for $OS-$PLATFORM_NAME on $ARCH" if [[ "$COMPATIBILITY_MODE" == "true" ]]; then - RUSTFLAGS="-C target-cpu=generic --cfg tokio_unstable -C target-feature=-sse4.2,-avx" cargo build -p "$CRATE_NAME" --profile cli + RUSTFLAGS="-C target-cpu=generic --cfg tokio_unstable -C target-feature=-sse4.2,-avx" cargo build -p "$CRATE_NAME" --profile cli else - cargo build -p "$CRATE_NAME" --profile cli + cargo build -p "$CRATE_NAME" --profile cli fi cd target/cli/ diff --git a/scripts/cli/minimal_cli_build.sh b/scripts/cli/minimal_cli_build.sh index 1bbdef2be40..26d4332e6ab 100755 --- a/scripts/cli/minimal_cli_build.sh +++ b/scripts/cli/minimal_cli_build.sh @@ -34,7 +34,17 @@ case "$OS" in sh install_pkg.sh build-essential pkgconf libssl-dev git libudev-dev lld libdw-dev clang llvm cmake elif has_command dnf; then # RHEL / CentOS based DNF - sh install_pkg.sh gcc gcc-c++ make pkgconf openssl-devel git rust-libudev-devel lld elfutils-devel clang llvm cmake + # This depends on the OS! + # Source the os-release file to parse it + . /etc/os-release + + # Check if it's Rocky + if [ "$ID" = "rocky" ]; then + echo "Rocky Linux detected" + sh install_pkg.sh gcc gcc-c++ make pkgconf openssl-devel git systemd-devel lld elfutils-devel clang llvm cmake + else + sh install_pkg.sh gcc gcc-c++ make pkgconf openssl-devel git rust-libudev-devel lld elfutils-devel clang llvm cmake + fi elif has_command yum; then # RHEL / CentOS based YUM sh install_pkg.sh gcc gcc-c++ make pkgconf openssl-devel git rust-libudev-devel lld elfutils-devel clang llvm cmake @@ -60,9 +70,11 @@ case "$OS" in fi ;; Darwin) + # macOS sh install_pkg.sh pkgconfig openssl git llvm cmake ;; FreeBSD) + # FreeBSD sh install_pkg.sh gcc gmake binutils pkgconf git openssl cmake llvm hidapi ;; *) diff --git a/scripts/dev_setup.sh b/scripts/dev_setup.sh index aa9f7ca0aac..659645fc930 100755 --- a/scripts/dev_setup.sh +++ b/scripts/dev_setup.sh @@ -1062,10 +1062,12 @@ install_libudev-dev install_python3 if [[ "$SKIP_PRE_COMMIT" == "false" ]]; then - if [[ "$PACKAGE_MANAGER" != "pacman" ]]; then - pip3 install pre-commit - else + if [[ "$PACKAGE_MANAGER" == "brew" ]]; then + install_pkg pre-commit "$PACKAGE_MANAGER" + elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then install_pkg python-pre-commit "$PACKAGE_MANAGER" + else + pip3 install pre-commit fi # For now best effort install, will need to improve later diff --git a/scripts/devnet_message.sh b/scripts/devnet_message.sh deleted file mode 100755 index 5da0185b410..00000000000 --- a/scripts/devnet_message.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -xe - -TEMP="$(mktemp)" - -curl https://fullnode.devnet.aptoslabs.com/v1 > "$TEMP" - -COMMIT="$(jq -r .git_hash "$TEMP")" -CHAIN_ID="$(jq -r .chain_id "$TEMP")" - -DIGEST="$(crane digest aptoslabs/validator:devnet_"$COMMIT")" -GENESIS_SHA="$(curl https://devnet.aptoslabs.com/genesis.blob | shasum -a 256 | awk '{print $1}')" -WAYPOINT="$(curl https://devnet.aptoslabs.com/waypoint.txt)" - -cat < + + $0 build [-- ] + + $0 run [-- ] +EOF + exit 1 +} + +# Get the first argument as subcommand +if [ $# -lt 1 ]; then + usage +fi +CMD="$1" +shift || true + +case "$CMD" in + profile) + PROFILE_DATA_PATH="$1" + [ -z "$PROFILE_DATA_PATH" ] && usage + shift + + # Create a temporary directory for storing raw profile data + TMPDIR=$(mktemp -d /tmp/pgo-data.XXXXXX) + + # Build the test binary with instrumentation + # Current workload is fixed -- 1000 p2p transactions in a single block + # Should switch to something more comprehensive once we have it. + env RUST_BACKTRACE=1 RUST_MIN_STACK=104857600 \ + RUSTFLAGS="$RUSTFLAGS -C profile-generate=$TMPDIR" \ + cargo build --profile release -p aptos-vm-profiling --bin run-aptos-p2p + + # Run the test binary + # + # Note: We first compile the binary, clear the profile directory, and then run the binary. + # This is a defensive measure to ensure the profile data is not tainted by + # build scripts. + rm -rf "$TMPDIR/*" + REPO_ROOT=$(dirname $(cargo locate-project --workspace --message-format plain)) + "$REPO_ROOT/target/release/run-aptos-p2p" + + # Merge the raw profile data + # Note: A relatively up-to-date version of llvm is required. + # (Rust 1.89 uses llvm-20) + # + # Follow the instructions here to install: + # - https://apt.llvm.org/ + llvm-profdata-20 merge -o "$PROFILE_DATA_PATH" "$TMPDIR" + + # Clean up the raw profile data + rm -rf "$TMPDIR" + ;; + build) + PROFILE_DATA_PATH="$1" + [ -z "$PROFILE_DATA_PATH" ] && usage + shift + PROFILE_DATA_PATH=$(realpath "$PROFILE_DATA_PATH") + + env RUST_BACKTRACE=1 RUST_MIN_STACK=104857600 \ + RUSTFLAGS="$RUSTFLAGS -C profile-use=$PROFILE_DATA_PATH" \ + cargo build --profile release "$@" + ;; + run) + PROFILE_DATA_PATH="$1" + [ -z "$PROFILE_DATA_PATH" ] && usage + shift + PROFILE_DATA_PATH=$(realpath "$PROFILE_DATA_PATH") + + env RUST_BACKTRACE=1 RUST_MIN_STACK=104857600 \ + RUSTFLAGS="$RUSTFLAGS -C profile-use=$PROFILE_DATA_PATH" \ + cargo run --profile release "$@" + ;; + *) + usage + ;; +esac diff --git a/sdk/src/transaction_builder.rs b/sdk/src/transaction_builder.rs index 08b3a4f8ff0..af0f5fb6d04 100644 --- a/sdk/src/transaction_builder.rs +++ b/sdk/src/transaction_builder.rs @@ -16,6 +16,7 @@ use aptos_types::{ function_info::FunctionInfo, transaction::{EntryFunction, Script}, }; +use rand::{thread_rng, Rng}; pub struct TransactionBuilder { sender: Option, @@ -79,15 +80,17 @@ impl TransactionBuilder { self.payload.replay_protection_nonce().is_some() } - // Primarily used for running the tests with both payload v1 and v2 formats. - pub fn upgrade_payload( + pub fn upgrade_payload_with_rng( mut self, + rng: &mut impl Rng, use_txn_payload_v2_format: bool, use_orderless_transactions: bool, ) -> Self { - self.payload = self - .payload - .upgrade_payload(use_txn_payload_v2_format, use_orderless_transactions); + self.payload = self.payload.upgrade_payload_with_rng( + rng, + use_txn_payload_v2_format, + use_orderless_transactions, + ); if use_orderless_transactions { self.sequence_number = self.sequence_number.map(|_| u64::MAX); } @@ -113,12 +116,21 @@ impl TransactionBuilder { } } +#[derive(Clone, Debug)] +enum TransactionExpiration { + Relative { expiration_duration: u64 }, + Absolute { expiration_timestamp: u64 }, +} + #[derive(Clone, Debug)] pub struct TransactionFactory { max_gas_amount: u64, gas_unit_price: u64, - transaction_expiration_time: u64, + transaction_expiration: TransactionExpiration, chain_id: ChainId, + + use_txn_payload_v2_format: bool, + use_replay_protection_nonce: bool, } impl TransactionFactory { @@ -127,8 +139,12 @@ impl TransactionFactory { // TODO(Gas): double check if this right max_gas_amount: MAX_GAS_AMOUNT, gas_unit_price: GAS_UNIT_PRICE, - transaction_expiration_time: 30, + transaction_expiration: TransactionExpiration::Relative { + expiration_duration: 30, + }, chain_id, + use_txn_payload_v2_format: false, + use_replay_protection_nonce: false, } } @@ -143,7 +159,21 @@ impl TransactionFactory { } pub fn with_transaction_expiration_time(mut self, transaction_expiration_time: u64) -> Self { - self.transaction_expiration_time = transaction_expiration_time; + self.transaction_expiration = TransactionExpiration::Relative { + expiration_duration: transaction_expiration_time, + }; + self + } + + /// Sets the transaction expiration timestamp to an absolute value. + /// Generally only useful for testing. + pub fn with_absolute_transaction_expiration_timestamp( + mut self, + transaction_expiration_timestamp: u64, + ) -> Self { + self.transaction_expiration = TransactionExpiration::Absolute { + expiration_timestamp: transaction_expiration_timestamp, + }; self } @@ -160,8 +190,16 @@ impl TransactionFactory { self.gas_unit_price } + /// Returns relative duration of transaction expiration. pub fn get_transaction_expiration_time(&self) -> u64 { - self.transaction_expiration_time + match self.transaction_expiration { + TransactionExpiration::Relative { + expiration_duration, + } => expiration_duration, + TransactionExpiration::Absolute { .. } => { + unimplemented!() + }, + } } pub fn get_chain_id(&self) -> ChainId { @@ -319,7 +357,15 @@ impl TransactionFactory { TransactionBuilder { sender: None, sequence_number: None, - payload, + payload: if self.use_txn_payload_v2_format || self.use_replay_protection_nonce { + payload.upgrade_payload_with_fn( + self.use_txn_payload_v2_format, + self.use_replay_protection_nonce + .then_some(|| thread_rng().r#gen()), + ) + } else { + payload + }, max_gas_amount: self.max_gas_amount, gas_unit_price: self.gas_unit_price, expiration_timestamp_secs: self.expiration_timestamp(), @@ -328,10 +374,19 @@ impl TransactionFactory { } fn expiration_timestamp(&self) -> u64 { - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs() - + self.transaction_expiration_time + match self.transaction_expiration { + TransactionExpiration::Relative { + expiration_duration, + } => { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() + + expiration_duration + }, + TransactionExpiration::Absolute { + expiration_timestamp, + } => expiration_timestamp, + } } } diff --git a/sdk/src/types.rs b/sdk/src/types.rs index 77df3a49642..16181ae7cea 100644 --- a/sdk/src/types.rs +++ b/sdk/src/types.rs @@ -272,9 +272,9 @@ impl LocalAccount { // Simulation of OIDC provider processing. let iss = keyless::test_utils::get_sample_iss(); let jwk = keyless::test_utils::get_sample_jwk(); - let aud = format!("aud_{}", hex::encode(rng.gen::<[u8; 4]>())); + let aud = format!("aud_{}", hex::encode(rng.r#gen::<[u8; 4]>())); let uid_key = "sub".to_string(); - let uid_val = format!("uid_{}", hex::encode(rng.gen::<[u8; 4]>())); + let uid_val = format!("uid_{}", hex::encode(rng.r#gen::<[u8; 4]>())); let jwt_header = keyless::test_utils::get_sample_jwt_header_json(); let jwt_header_b64 = keyless::base64url_encode_str(&jwt_header); let jwt_payload = keyless::circuit_testcases::render_jwt_payload_json( @@ -513,7 +513,7 @@ impl LocalAccount { } } - pub fn auth(&self) -> Auth { + pub fn auth(&self) -> Auth<'_> { match &self.auth { LocalAccountAuthenticator::PrivateKey(key) => Auth::Ed25519(key.private_key()), LocalAccountAuthenticator::Keyless(_) => todo!(), diff --git a/secure/net/src/network_controller/mod.rs b/secure/net/src/network_controller/mod.rs index 4bd9ee80446..f9266f8f406 100644 --- a/secure/net/src/network_controller/mod.rs +++ b/secure/net/src/network_controller/mod.rs @@ -13,6 +13,7 @@ use std::{ }; use tokio::{runtime::Runtime, sync::oneshot}; +#[allow(dead_code)] // TODO: remove. mod error; mod inbound_handler; pub(crate) mod metrics; diff --git a/secure/storage/src/crypto_kv_storage.rs b/secure/storage/src/crypto_kv_storage.rs index 7040e6f438a..ef5adf00129 100644 --- a/secure/storage/src/crypto_kv_storage.rs +++ b/secure/storage/src/crypto_kv_storage.rs @@ -113,7 +113,7 @@ impl CryptoStorage for T { /// Private helper method to generate a new ed25519 key pair using entropy from the OS. fn new_ed25519_key_pair() -> (Ed25519PrivateKey, Ed25519PublicKey) { let mut seed_rng = OsRng; - let mut rng = rand::rngs::StdRng::from_seed(seed_rng.gen()); + let mut rng = rand::rngs::StdRng::from_seed(seed_rng.r#gen()); let private_key = Ed25519PrivateKey::generate(&mut rng); let public_key = private_key.public_key(); (private_key, public_key) diff --git a/secure/storage/src/on_disk.rs b/secure/storage/src/on_disk.rs index dfbb921a6f0..d2db600e24b 100644 --- a/secure/storage/src/on_disk.rs +++ b/secure/storage/src/on_disk.rs @@ -88,7 +88,7 @@ impl KVStorage for OnDiskStorage { let mut data = self.read()?; data.insert( key.to_string(), - serde_json::to_value(&GetResponse::new(value, now))?, + serde_json::to_value(GetResponse::new(value, now))?, ); self.write(&data) } diff --git a/state-sync/aptos-data-client/src/client.rs b/state-sync/aptos-data-client/src/client.rs index b821c955815..8000ab20927 100644 --- a/state-sync/aptos-data-client/src/client.rs +++ b/state-sync/aptos-data-client/src/client.rs @@ -42,7 +42,7 @@ use aptos_storage_service_types::{ SubscriptionStreamMetadata, TransactionOutputsWithProofRequest, TransactionsOrOutputsWithProofRequest, TransactionsWithProofRequest, }, - responses::{StorageServerSummary, StorageServiceResponse, TransactionOrOutputListWithProof}, + responses::{StorageServerSummary, StorageServiceResponse, TransactionOrOutputListWithProofV2}, Epoch, StorageServiceMessage, }; use aptos_time_service::TimeService; @@ -50,7 +50,7 @@ use aptos_types::{ epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, }; use arc_swap::ArcSwap; use async_trait::async_trait; @@ -150,11 +150,22 @@ impl AptosDataClient { self.data_client_config.max_num_output_reductions } + /// Returns the maximum number of bytes that can be returned in a single response + fn get_max_response_bytes(&self) -> u64 { + self.data_client_config.max_response_bytes + } + /// Returns the peers and metadata struct pub fn get_peers_and_metadata(&self) -> Arc { self.storage_service_client.get_peers_and_metadata() } + /// Returns true iff transaction v2 is enabled, and + /// the client should use transaction v2 data requests. + fn is_transaction_v2_enabled(&self) -> bool { + self.data_client_config.enable_transaction_data_v2 + } + /// Updates the metrics and logs for peer states. This includes /// peer priorities and request distributions. pub fn update_peer_metrics_and_logs(&self) { @@ -454,6 +465,9 @@ impl AptosDataClient { DataRequest::SubscribeTransactionsOrOutputsWithProof(request) => { request.subscription_stream_metadata.subscription_stream_id }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request.subscription_stream_metadata.subscription_stream_id + }, data_request => { return Err(Error::UnexpectedErrorEncountered(format!( "Invalid subscription request type found: {:?}", @@ -939,13 +953,20 @@ impl AptosDataClientInterface for AptosDataClient { known_version: Version, known_epoch: Epoch, request_timeout_ms: u64, - ) -> crate::error::Result> + ) -> crate::error::Result> { - let data_request = + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_new_transaction_output_data_with_proof( + known_version, + known_epoch, + self.get_max_response_bytes(), + ) + } else { DataRequest::GetNewTransactionOutputsWithProof(NewTransactionOutputsWithProofRequest { known_version, known_epoch, - }); + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -956,13 +977,22 @@ impl AptosDataClientInterface for AptosDataClient { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> { - let data_request = + ) -> crate::error::Result> + { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_new_transaction_data_with_proof( + known_version, + known_epoch, + include_events, + self.get_max_response_bytes(), + ) + } else { DataRequest::GetNewTransactionsWithProof(NewTransactionsWithProofRequest { known_version, known_epoch, include_events, - }); + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -973,16 +1003,26 @@ impl AptosDataClientInterface for AptosDataClient { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> - { - let data_request = DataRequest::GetNewTransactionsOrOutputsWithProof( - NewTransactionsOrOutputsWithProofRequest { + ) -> crate::error::Result< + Response<(TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures)>, + > { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_new_transaction_or_output_data_with_proof( known_version, known_epoch, include_events, - max_num_output_reductions: self.get_max_num_output_reductions(), - }, - ); + self.get_max_response_bytes(), + ) + } else { + DataRequest::GetNewTransactionsOrOutputsWithProof( + NewTransactionsOrOutputsWithProofRequest { + known_version, + known_epoch, + include_events, + max_num_output_reductions: self.get_max_num_output_reductions(), + }, + ) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1019,13 +1059,21 @@ impl AptosDataClientInterface for AptosDataClient { start_version: Version, end_version: Version, request_timeout_ms: u64, - ) -> crate::error::Result> { - let data_request = + ) -> crate::error::Result> { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_transaction_output_data_with_proof( + proof_version, + start_version, + end_version, + self.get_max_response_bytes(), + ) + } else { DataRequest::GetTransactionOutputsWithProof(TransactionOutputsWithProofRequest { proof_version, start_version, end_version, - }); + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1037,13 +1085,23 @@ impl AptosDataClientInterface for AptosDataClient { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> { - let data_request = DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { - proof_version, - start_version, - end_version, - include_events, - }); + ) -> crate::error::Result> { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_transaction_data_with_proof( + proof_version, + start_version, + end_version, + include_events, + self.get_max_response_bytes(), + ) + } else { + DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { + proof_version, + start_version, + end_version, + include_events, + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1055,15 +1113,24 @@ impl AptosDataClientInterface for AptosDataClient { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> { - let data_request = + ) -> crate::error::Result> { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::get_transaction_or_output_data_with_proof( + proof_version, + start_version, + end_version, + include_events, + self.get_max_response_bytes(), + ) + } else { DataRequest::GetTransactionsOrOutputsWithProof(TransactionsOrOutputsWithProofRequest { proof_version, start_version, end_version, include_events, max_num_output_reductions: self.get_max_num_output_reductions(), - }); + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1072,19 +1139,27 @@ impl AptosDataClientInterface for AptosDataClient { &self, request_metadata: SubscriptionRequestMetadata, request_timeout_ms: u64, - ) -> crate::error::Result> + ) -> crate::error::Result> { let subscription_stream_metadata = SubscriptionStreamMetadata { known_version_at_stream_start: request_metadata.known_version_at_stream_start, known_epoch_at_stream_start: request_metadata.known_epoch_at_stream_start, subscription_stream_id: request_metadata.subscription_stream_id, }; - let data_request = DataRequest::SubscribeTransactionOutputsWithProof( - SubscribeTransactionOutputsWithProofRequest { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::subscribe_transaction_output_data_with_proof( subscription_stream_metadata, - subscription_stream_index: request_metadata.subscription_stream_index, - }, - ); + request_metadata.subscription_stream_index, + self.get_max_response_bytes(), + ) + } else { + DataRequest::SubscribeTransactionOutputsWithProof( + SubscribeTransactionOutputsWithProofRequest { + subscription_stream_metadata, + subscription_stream_index: request_metadata.subscription_stream_index, + }, + ) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1094,18 +1169,27 @@ impl AptosDataClientInterface for AptosDataClient { request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> { + ) -> crate::error::Result> + { let subscription_stream_metadata = SubscriptionStreamMetadata { known_version_at_stream_start: request_metadata.known_version_at_stream_start, known_epoch_at_stream_start: request_metadata.known_epoch_at_stream_start, subscription_stream_id: request_metadata.subscription_stream_id, }; - let data_request = + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::subscribe_transaction_data_with_proof( + subscription_stream_metadata, + request_metadata.subscription_stream_index, + include_events, + self.get_max_response_bytes(), + ) + } else { DataRequest::SubscribeTransactionsWithProof(SubscribeTransactionsWithProofRequest { subscription_stream_metadata, include_events, subscription_stream_index: request_metadata.subscription_stream_index, - }); + }) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } @@ -1115,21 +1199,31 @@ impl AptosDataClientInterface for AptosDataClient { request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> crate::error::Result> - { + ) -> crate::error::Result< + Response<(TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures)>, + > { let subscription_stream_metadata = SubscriptionStreamMetadata { known_version_at_stream_start: request_metadata.known_version_at_stream_start, known_epoch_at_stream_start: request_metadata.known_epoch_at_stream_start, subscription_stream_id: request_metadata.subscription_stream_id, }; - let data_request = DataRequest::SubscribeTransactionsOrOutputsWithProof( - SubscribeTransactionsOrOutputsWithProofRequest { + let data_request = if self.is_transaction_v2_enabled() { + DataRequest::subscribe_transaction_or_output_data_with_proof( subscription_stream_metadata, + request_metadata.subscription_stream_index, include_events, - max_num_output_reductions: self.get_max_num_output_reductions(), - subscription_stream_index: request_metadata.subscription_stream_index, - }, - ); + self.get_max_response_bytes(), + ) + } else { + DataRequest::SubscribeTransactionsOrOutputsWithProof( + SubscribeTransactionsOrOutputsWithProofRequest { + subscription_stream_metadata, + include_events, + max_num_output_reductions: self.get_max_num_output_reductions(), + subscription_stream_index: request_metadata.subscription_stream_index, + }, + ) + }; self.create_and_send_storage_request(request_timeout_ms, data_request) .await } diff --git a/state-sync/aptos-data-client/src/interface.rs b/state-sync/aptos-data-client/src/interface.rs index ef5fff04010..254e03bca41 100644 --- a/state-sync/aptos-data-client/src/interface.rs +++ b/state-sync/aptos-data-client/src/interface.rs @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{error, error::Error, global_summary::GlobalDataSummary}; -use aptos_storage_service_types::{responses::TransactionOrOutputListWithProof, Epoch}; +use aptos_storage_service_types::{responses::TransactionOrOutputListWithProofV2, Epoch}; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, }; use async_trait::async_trait; use serde::{Deserialize, Serialize}; @@ -41,7 +41,7 @@ pub trait AptosDataClientInterface { known_version: Version, known_epoch: Epoch, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Fetches a new transaction list with proof. Versions start at /// `known_version + 1` and `known_epoch` (inclusive). The end version @@ -53,7 +53,7 @@ pub trait AptosDataClientInterface { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Fetches a new transaction or output list with proof. Versions start at /// `known_version + 1` and `known_epoch` (inclusive). The end version @@ -65,7 +65,7 @@ pub trait AptosDataClientInterface { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Fetches the number of states at the specified version. async fn get_number_of_states( @@ -98,7 +98,7 @@ pub trait AptosDataClientInterface { start_version: Version, end_version: Version, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Fetches a transaction list with proof, with transactions from /// start to end versions (inclusive). The proof is relative to the @@ -113,7 +113,7 @@ pub trait AptosDataClientInterface { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Fetches a transaction or output list with proof, with data from /// start to end versions (inclusive). The proof is relative to the @@ -128,7 +128,7 @@ pub trait AptosDataClientInterface { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Subscribes to new transaction output lists with proofs. Subscriptions /// start at `known_version + 1` and `known_epoch` (inclusive), as @@ -139,7 +139,7 @@ pub trait AptosDataClientInterface { &self, subscription_request_metadata: SubscriptionRequestMetadata, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Subscribes to new transaction lists with proofs. Subscriptions start /// at `known_version + 1` and `known_epoch` (inclusive), as specified @@ -152,7 +152,7 @@ pub trait AptosDataClientInterface { subscription_request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; /// Subscribes to new transaction or output lists with proofs. Subscriptions /// start at `known_version + 1` and `known_epoch` (inclusive), as @@ -165,7 +165,7 @@ pub trait AptosDataClientInterface { subscription_request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> error::Result>; + ) -> error::Result>; } /// Subscription stream metadata associated with each subscription request @@ -264,12 +264,12 @@ impl Response { #[derive(Clone, Debug, Eq, PartialEq)] pub enum ResponsePayload { EpochEndingLedgerInfos(Vec), - NewTransactionOutputsWithProof((TransactionOutputListWithProof, LedgerInfoWithSignatures)), - NewTransactionsWithProof((TransactionListWithProof, LedgerInfoWithSignatures)), + NewTransactionOutputsWithProof((TransactionOutputListWithProofV2, LedgerInfoWithSignatures)), + NewTransactionsWithProof((TransactionListWithProofV2, LedgerInfoWithSignatures)), NumberOfStates(u64), StateValuesWithProof(StateValueChunkWithProof), - TransactionOutputsWithProof(TransactionOutputListWithProof), - TransactionsWithProof(TransactionListWithProof), + TransactionOutputsWithProof(TransactionOutputListWithProofV2), + TransactionsWithProof(TransactionListWithProofV2), } impl ResponsePayload { @@ -295,10 +295,10 @@ impl ResponsePayload { epoch_ending_ledger_infos.len() }, Self::NewTransactionOutputsWithProof((outputs_with_proof, _)) => { - outputs_with_proof.transactions_and_outputs.len() + outputs_with_proof.get_num_outputs() }, Self::NewTransactionsWithProof((transactions_with_proof, _)) => { - transactions_with_proof.transactions.len() + transactions_with_proof.get_num_transactions() }, Self::NumberOfStates(_) => { 1 // The number of states is a single u64 @@ -307,10 +307,10 @@ impl ResponsePayload { state_values_with_proof.raw_values.len() }, Self::TransactionOutputsWithProof(outputs_with_proof) => { - outputs_with_proof.transactions_and_outputs.len() + outputs_with_proof.get_num_outputs() }, Self::TransactionsWithProof(transactions_with_proof) => { - transactions_with_proof.transactions.len() + transactions_with_proof.get_num_transactions() }, } } @@ -328,23 +328,23 @@ impl From> for ResponsePayload { } } -impl From<(TransactionOutputListWithProof, LedgerInfoWithSignatures)> for ResponsePayload { - fn from(inner: (TransactionOutputListWithProof, LedgerInfoWithSignatures)) -> Self { +impl From<(TransactionOutputListWithProofV2, LedgerInfoWithSignatures)> for ResponsePayload { + fn from(inner: (TransactionOutputListWithProofV2, LedgerInfoWithSignatures)) -> Self { Self::NewTransactionOutputsWithProof(inner) } } -impl From<(TransactionListWithProof, LedgerInfoWithSignatures)> for ResponsePayload { - fn from(inner: (TransactionListWithProof, LedgerInfoWithSignatures)) -> Self { +impl From<(TransactionListWithProofV2, LedgerInfoWithSignatures)> for ResponsePayload { + fn from(inner: (TransactionListWithProofV2, LedgerInfoWithSignatures)) -> Self { Self::NewTransactionsWithProof(inner) } } -impl TryFrom<(TransactionOrOutputListWithProof, LedgerInfoWithSignatures)> for ResponsePayload { +impl TryFrom<(TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures)> for ResponsePayload { type Error = Error; fn try_from( - inner: (TransactionOrOutputListWithProof, LedgerInfoWithSignatures), + inner: (TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures), ) -> error::Result { let ((transaction_list, output_list), ledger_info) = inner; if let Some(transaction_list) = transaction_list { @@ -371,22 +371,22 @@ impl From for ResponsePayload { } } -impl From for ResponsePayload { - fn from(inner: TransactionOutputListWithProof) -> Self { +impl From for ResponsePayload { + fn from(inner: TransactionOutputListWithProofV2) -> Self { Self::TransactionOutputsWithProof(inner) } } -impl From for ResponsePayload { - fn from(inner: TransactionListWithProof) -> Self { +impl From for ResponsePayload { + fn from(inner: TransactionListWithProofV2) -> Self { Self::TransactionsWithProof(inner) } } -impl TryFrom for ResponsePayload { +impl TryFrom for ResponsePayload { type Error = Error; - fn try_from(inner: TransactionOrOutputListWithProof) -> error::Result { + fn try_from(inner: TransactionOrOutputListWithProofV2) -> error::Result { let (transaction_list, output_list) = inner; if let Some(transaction_list) = transaction_list { Ok(Self::TransactionsWithProof(transaction_list)) diff --git a/state-sync/aptos-data-client/src/latency_monitor.rs b/state-sync/aptos-data-client/src/latency_monitor.rs index 5a36dba4947..f9ec9f37035 100644 --- a/state-sync/aptos-data-client/src/latency_monitor.rs +++ b/state-sync/aptos-data-client/src/latency_monitor.rs @@ -29,8 +29,9 @@ pub struct LatencyMonitor { caught_up_to_latest: bool, // Whether the node has ever caught up to the latest blockchain version data_client: Arc, // The data client through which to see advertised data monitor_loop_interval: Duration, // The interval between latency monitor loop executions - storage: Arc, // The reader interface to storage - time_service: TimeService, // The service to monitor elapsed time + progress_check_max_stall_duration: Duration, // The duration after which to panic if no progress has been made + storage: Arc, // The reader interface to storage + time_service: TimeService, // The service to monitor elapsed time } impl LatencyMonitor { @@ -42,12 +43,15 @@ impl LatencyMonitor { ) -> Self { let monitor_loop_interval = Duration::from_millis(data_client_config.latency_monitor_loop_interval_ms); + let progress_check_max_stall_duration = + Duration::from_secs(data_client_config.progress_check_max_stall_time_secs); Self { advertised_versions: BTreeMap::new(), caught_up_to_latest: false, data_client, monitor_loop_interval, + progress_check_max_stall_duration, storage, time_service, } @@ -59,14 +63,23 @@ impl LatencyMonitor { (LogSchema::new(LogEntry::LatencyMonitor) .message("Starting the Aptos data client latency monitor!")) ); + + // Create a ticker for the monitor loop let loop_ticker = self.time_service.interval(self.monitor_loop_interval); futures::pin_mut!(loop_ticker); + // Create a progress checker to track syncing progress + let mut progress_checker = ProgressChecker::new( + self.time_service.clone(), + self.progress_check_max_stall_duration, + ); + // Start the monitor loop { // Wait for the next round loop_ticker.next().await; + // Get the highest synced version from storage let highest_synced_version = match self.storage.ensure_synced_version() { Ok(version) => version, Err(error) => { @@ -82,6 +95,9 @@ impl LatencyMonitor { }, }; + // Check if we've made sufficient progress since the last loop iteration + progress_checker.check_syncing_progress(highest_synced_version); + // Get the latest block timestamp from storage let latest_block_timestamp_usecs = match self .storage @@ -274,6 +290,49 @@ impl LatencyMonitor { } } +/// A simple struct that tracks the progress of node synchronization +/// and panics if no progress has been made for a long time. +struct ProgressChecker { + last_sync_progress_time: Instant, // The time when we last made syncing progress + highest_synced_version: u64, // The highest synced version we've seen + progress_check_max_stall_duration: Duration, // The duration after which to panic if no progress has been made + time_service: TimeService, // The time service to track elapsed time +} + +impl ProgressChecker { + fn new(time_service: TimeService, progress_check_max_stall_duration: Duration) -> Self { + Self { + last_sync_progress_time: time_service.now(), + highest_synced_version: 0, + progress_check_max_stall_duration, + time_service, + } + } + + /// Ensures we've made progress since the last check, and + /// panics if we haven't made any progress for too long. + fn check_syncing_progress(&mut self, highest_synced_version: u64) { + // Check if we've made progress since the last iteration + let time_now = self.time_service.now(); + if highest_synced_version > self.highest_synced_version { + // We've made progress, so reset the progress state + self.last_sync_progress_time = time_now; + self.highest_synced_version = highest_synced_version; + return; + } + + // Otherwise, check if we've stalled for too long + let elapsed_time = time_now.duration_since(self.last_sync_progress_time); + if elapsed_time >= self.progress_check_max_stall_duration { + panic!( + "No syncing progress has been made for {:?}! Highest synced version: {}. \ + We recommend restarting the node and checking if the issue persists.", + elapsed_time, highest_synced_version + ); + } + } +} + /// A simple struct that holds the metadata of an advertised version. /// /// Note: the struct stores both the seen time as an Instant, as well @@ -398,7 +457,7 @@ mod tests { ); // Elapse some time - elapse_time(time_service.clone(), 1000); + elapse_time_ms(time_service.clone(), 1000); // Verify the seen to synced duration is 0 let duration_from_seen_to_synced = calculate_duration_from_seen_to_synced( @@ -416,7 +475,7 @@ mod tests { // Elapse some time let elapsed_time_ms = 1000; - elapse_time(time_service.clone(), elapsed_time_ms); + elapse_time_ms(time_service.clone(), elapsed_time_ms); // Verify the seen to synced duration is correct let duration_from_seen_to_synced = @@ -470,7 +529,7 @@ mod tests { }); // Elapse the time - elapse_time(time_service.clone(), 1000); + elapse_time_ms(time_service.clone(), 1000); // Update the advertised version timestamps again highest_advertised_version += 100; @@ -519,7 +578,7 @@ mod tests { let start_time_usecs = time_service.now_unix_time().as_micros() as u64; for advertised_version in 0..num_advertised_versions { // Elapse some time (1 ms) - elapse_time(time_service.clone(), 1); + elapse_time_ms(time_service.clone(), 1); // Update the advertised version timestamps latency_monitor.update_advertised_version_timestamps(0, advertised_version); @@ -562,7 +621,7 @@ mod tests { }); // Elapse some time - elapse_time(time_service.clone(), 1000); + elapse_time_ms(time_service.clone(), 1000); // Update the advertised version timestamps again. But, this time // the highest synced version is equal to the highest advertised version. @@ -663,6 +722,72 @@ mod tests { verify_advertised_version_timestamps_length(&mut latency_monitor, 1); } + #[tokio::test] + async fn test_progress_check_healthy() { + // Create a progress checker + let time_service = TimeService::mock(); + let progress_check_max_stall_duration = Duration::from_secs(1); // 1 second + let mut progress_checker = latency_monitor::ProgressChecker::new( + time_service.clone(), + progress_check_max_stall_duration, + ); + + // Check progress with increasing versions + let max_synced_version = 10; + for highest_synced_version in 1..=max_synced_version { + // Elapse some time (2 seconds) + elapse_time_ms(time_service.clone(), 2000); + + // Check progress (this should be fine, as we've made progress) + progress_checker.check_syncing_progress(highest_synced_version); + } + + // Elapse some time (0.5 seconds), and verify that we don't panic (even with no progress) + elapse_time_ms(time_service.clone(), 500); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (0.4 seconds), and verify that we don't panic (even with no progress) + elapse_time_ms(time_service.clone(), 400); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (0.09 seconds), and verify that we don't panic (even with no progress) + elapse_time_ms(time_service.clone(), 90); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (1 seconds), and verify that we don't panic if we make progress + elapse_time_ms(time_service.clone(), 1000); + progress_checker.check_syncing_progress(max_synced_version + 1); + } + + #[tokio::test] + #[should_panic(expected = "No syncing progress has been made for 1.1s!")] + async fn test_progress_check_panic() { + // Create a progress checker + let time_service = TimeService::mock(); + let progress_check_max_stall_duration = Duration::from_secs(1); // 1 second + let mut progress_checker = latency_monitor::ProgressChecker::new( + time_service.clone(), + progress_check_max_stall_duration, + ); + + // Elapse some time (0.5 seconds), and verify that we don't panic (progress was made) + let max_synced_version = 10; + elapse_time_ms(time_service.clone(), 500); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (0.5 seconds), and verify that we don't panic (even with no progress) + elapse_time_ms(time_service.clone(), 500); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (0.4 seconds), and verify that we don't panic (even with no progress) + elapse_time_ms(time_service.clone(), 400); + progress_checker.check_syncing_progress(max_synced_version); + + // Elapse more time (0.2 seconds), and verify that we panic (we've stalled for too long) + elapse_time_ms(time_service.clone(), 200); + progress_checker.check_syncing_progress(max_synced_version); + } + /// Creates a latency monitor for testing fn create_latency_monitor() -> (TimeService, LatencyMonitor) { let data_client_config = Arc::new(AptosDataClientConfig::default()); @@ -680,7 +805,7 @@ mod tests { } /// Elapses the given time (in milliseconds) on the specified time service - fn elapse_time(time_service: TimeService, time_ms: u64) { + fn elapse_time_ms(time_service: TimeService, time_ms: u64) { time_service.into_mock().advance_ms(time_ms); } diff --git a/state-sync/aptos-data-client/src/tests/advertise.rs b/state-sync/aptos-data-client/src/tests/advertise.rs index 512f191b1e3..187b3a2441a 100644 --- a/state-sync/aptos-data-client/src/tests/advertise.rs +++ b/state-sync/aptos-data-client/src/tests/advertise.rs @@ -16,7 +16,7 @@ use aptos_storage_service_types::{ responses::{CompleteDataRange, DataResponse, StorageServerSummary, StorageServiceResponse}, }; use aptos_time_service::MockTimeService; -use aptos_types::transaction::{TransactionListWithProof, Version}; +use aptos_types::transaction::{TransactionListWithProofV2, Version}; use claims::assert_matches; use std::time::Duration; use tokio::time::timeout; @@ -28,8 +28,13 @@ async fn request_works_only_when_data_available() { // Create a base config for a validator let base_config = utils::create_validator_base_config(); + // Create the aptos data client config + let data_client_config = AptosDataClientConfig { + enable_transaction_data_v2: false, + ..Default::default() + }; + // Create the mock network, mock time, client and poller - let data_client_config = AptosDataClientConfig::default(); let (mut mock_network, mut mock_time, client, poller) = MockNetwork::new(Some(base_config), Some(data_client_config), None); @@ -90,7 +95,7 @@ async fn request_works_only_when_data_available() { .get_transactions_with_proof(100, 0, 100, false, request_timeout) .await .unwrap(); - assert_eq!(response.payload, TransactionListWithProof::new_empty()); + assert_eq!(response.payload, TransactionListWithProofV2::new_empty()); } } diff --git a/state-sync/aptos-data-client/src/tests/compression.rs b/state-sync/aptos-data-client/src/tests/compression.rs index b3280d09888..23083c04cf8 100644 --- a/state-sync/aptos-data-client/src/tests/compression.rs +++ b/state-sync/aptos-data-client/src/tests/compression.rs @@ -14,7 +14,7 @@ use aptos_storage_service_types::{ requests::{DataRequest, TransactionsWithProofRequest}, responses::{CompleteDataRange, DataResponse, StorageServiceResponse}, }; -use aptos_types::transaction::TransactionListWithProof; +use aptos_types::transaction::TransactionListWithProofV2; use claims::assert_matches; #[tokio::test] @@ -183,6 +183,7 @@ async fn disable_compression() { // Create a data client config that disables compression let data_client_config = AptosDataClientConfig { + enable_transaction_data_v2: false, use_compression: false, ..Default::default() }; @@ -265,6 +266,6 @@ async fn disable_compression() { .get_transactions_with_proof(100, 50, 100, false, request_timeout) .await .unwrap(); - assert_eq!(response.payload, TransactionListWithProof::new_empty()); + assert_eq!(response.payload, TransactionListWithProofV2::new_empty()); } } diff --git a/state-sync/aptos-data-client/src/tests/mock.rs b/state-sync/aptos-data-client/src/tests/mock.rs index b9fde73ad55..c15868cff35 100644 --- a/state-sync/aptos-data-client/src/tests/mock.rs +++ b/state-sync/aptos-data-client/src/tests/mock.rs @@ -31,13 +31,13 @@ use aptos_storage_interface::DbReader; use aptos_storage_service_client::StorageServiceClient; use aptos_storage_service_server::network::{NetworkRequest, ResponseSender}; use aptos_storage_service_types::{ - responses::TransactionOrOutputListWithProof, Epoch, StorageServiceMessage, + responses::TransactionOrOutputListWithProofV2, Epoch, StorageServiceMessage, }; use aptos_time_service::{MockTimeService, TimeService}; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, PeerId, }; use async_trait::async_trait; @@ -189,10 +189,10 @@ impl MockNetwork { // Insert peer monitoring metadata for the peer let network_info_response = NetworkInformationResponse { connected_peers: Default::default(), - distance_from_validators: OsRng.gen(), + distance_from_validators: OsRng.r#gen(), }; let peer_monitoring_metadata = PeerMonitoringMetadata::new( - Some(OsRng.gen()), + Some(OsRng.r#gen()), None, Some(network_info_response), None, @@ -283,7 +283,7 @@ mock! { known_version: Version, known_epoch: Epoch, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn get_new_transactions_with_proof( &self, @@ -291,7 +291,7 @@ mock! { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn get_new_transactions_or_outputs_with_proof( &self, @@ -299,7 +299,7 @@ mock! { known_epoch: Epoch, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn get_number_of_states( &self, @@ -321,7 +321,7 @@ mock! { start_version: Version, end_version: Version, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn get_transactions_with_proof( &self, @@ -330,7 +330,7 @@ mock! { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn get_transactions_or_outputs_with_proof( &self, @@ -339,27 +339,27 @@ mock! { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn subscribe_to_transaction_outputs_with_proof( &self, subscription_request_metadata: SubscriptionRequestMetadata, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn subscribe_to_transactions_with_proof( &self, subscription_request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; async fn subscribe_to_transactions_or_outputs_with_proof( &self, subscription_request_metadata: SubscriptionRequestMetadata, include_events: bool, request_timeout_ms: u64, - ) -> Result>; + ) -> Result>; } } diff --git a/state-sync/aptos-data-client/src/tests/mod.rs b/state-sync/aptos-data-client/src/tests/mod.rs index bcf444d836e..613a47f24fa 100644 --- a/state-sync/aptos-data-client/src/tests/mod.rs +++ b/state-sync/aptos-data-client/src/tests/mod.rs @@ -8,5 +8,6 @@ mod multi_fetch; mod peers; mod poller; mod priority; +mod request_v2; mod utils; mod weighted_selection; diff --git a/state-sync/aptos-data-client/src/tests/peers.rs b/state-sync/aptos-data-client/src/tests/peers.rs index 4931e37b438..45fb279480a 100644 --- a/state-sync/aptos-data-client/src/tests/peers.rs +++ b/state-sync/aptos-data-client/src/tests/peers.rs @@ -20,7 +20,7 @@ use aptos_storage_service_types::{ responses::{CompleteDataRange, DataResponse, StorageServerSummary, StorageServiceResponse}, StorageServiceError, }; -use aptos_types::transaction::TransactionListWithProof; +use aptos_types::transaction::{TransactionListWithProof, TransactionListWithProofV2}; use claims::{assert_err, assert_matches, assert_ok}; use maplit::hashset; use rand::{rngs::OsRng, Rng}; @@ -182,7 +182,7 @@ async fn bad_peer_is_eventually_banned_internal() { .get_transactions_with_proof(100, 50, 100, false, response_timeout_ms) .await .unwrap(); - assert_eq!(response.payload, TransactionListWithProof::new_empty()); + assert_eq!(response.payload, TransactionListWithProofV2::new_empty()); } } @@ -279,6 +279,7 @@ async fn bad_peer_is_eventually_added_back() { // Create a data client config with peer ignoring enabled let data_client_config = AptosDataClientConfig { + enable_transaction_data_v2: false, ignore_low_score_peers: true, ..Default::default() }; @@ -579,7 +580,7 @@ async fn single_good_peer() { send_transaction_response(network_request); } else { // Send an error or drop the request - if !OsRng.gen::() { + if !OsRng.r#gen::() { send_error_response(network_request); } } @@ -663,7 +664,7 @@ async fn single_good_peer_across_priorities() { send_transaction_response(network_request); } else { // Send an error or drop the request - if !OsRng.gen::() { + if !OsRng.r#gen::() { send_error_response(network_request); } } @@ -682,7 +683,7 @@ async fn single_good_peer_across_priorities() { /// If no duration is specified, the sleep duration is randomly chosen. async fn emulate_network_latencies(sleep_duration_ms: Option) { let sleep_duration_ms = sleep_duration_ms.unwrap_or_else(|| { - OsRng.gen::() % 500 // Up to 0.5 seconds + OsRng.r#gen::() % 500 // Up to 0.5 seconds }); tokio::time::sleep(Duration::from_millis(sleep_duration_ms)).await; } diff --git a/state-sync/aptos-data-client/src/tests/request_v2.rs b/state-sync/aptos-data-client/src/tests/request_v2.rs new file mode 100644 index 00000000000..985c8665884 --- /dev/null +++ b/state-sync/aptos-data-client/src/tests/request_v2.rs @@ -0,0 +1,1003 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + client::AptosDataClient, + interface::{AptosDataClientInterface, SubscriptionRequestMetadata}, + priority::PeerPriority, + tests::{mock::MockNetwork, utils}, +}; +use aptos_config::{config::AptosDataClientConfig, network_id::NetworkId}; +use aptos_crypto::{ed25519::Ed25519PrivateKey, HashValue, PrivateKey, SigningKey, Uniform}; +use aptos_storage_service_types::{ + requests::{DataRequest, TransactionData, TransactionDataRequestType, TransactionOrOutputData}, + responses::{ + DataResponse, NewTransactionDataWithProofResponse, StorageServiceResponse, + TransactionDataResponseType, TransactionDataWithProofResponse, + }, +}; +use aptos_types::{ + account_address::AccountAddress, + aggregate_signature::AggregateSignature, + block_info::BlockInfo, + chain_id::ChainId, + ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, + transaction::{ + ExecutionStatus, PersistedAuxiliaryInfo, RawTransaction, Script, SignedTransaction, + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionListWithAuxiliaryInfos, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithAuxiliaryInfos, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, TransactionPayload, TransactionStatus, + }, + write_set::WriteSet, +}; +use claims::assert_matches; + +#[tokio::test] +async fn test_get_transactions() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions = 10; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetTransactionsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionData(TransactionData { + include_events: true, + }) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_list_with_proof = + Some(create_transaction_list_with_proof_v2(num_transactions)); + DataResponse::TransactionDataWithProof(TransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof, + transaction_output_list_with_proof: None, + }) + } else { + let transaction_list_with_proof = + create_transaction_list_with_proof(num_transactions); + DataResponse::TransactionsWithProof(transaction_list_with_proof) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_transactions_with_proof(0, 0, 0, true, 0) + .await + .unwrap(); + + // Verify the response + let transaction_list_with_proof_v2 = response.payload; + verify_response_data( + Some(transaction_list_with_proof_v2), + None, + use_request_v2, + num_transactions, + ); + } +} + +#[tokio::test] +async fn test_get_transaction_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_outputs = 15; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetTransactionOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOutputData + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_output_list_with_proof = + Some(create_transaction_output_list_with_proof_v2(num_outputs)); + DataResponse::TransactionDataWithProof(TransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof, + }) + } else { + let output_list_with_proof = + create_transaction_output_list_with_proof(num_outputs); + DataResponse::TransactionOutputsWithProof(output_list_with_proof) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_transaction_outputs_with_proof(0, 0, 0, 0) + .await + .unwrap(); + + // Verify the response + let output_list_with_proof_v2 = response.payload; + verify_response_data( + None, + Some(output_list_with_proof_v2), + use_request_v2, + num_outputs, + ); + } +} + +#[tokio::test] +async fn test_get_transactions_or_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions_or_outputs = 20; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetTransactionsOrOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOrOutputData( + TransactionOrOutputData { + include_events: false, + } + ) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_list_with_proof = Some( + create_transaction_list_with_proof_v2(num_transactions_or_outputs), + ); + DataResponse::TransactionDataWithProof(TransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof, + transaction_output_list_with_proof: None, + }) + } else { + let transaction_list_with_proof = Some(create_transaction_list_with_proof( + num_transactions_or_outputs, + )); + DataResponse::TransactionsOrOutputsWithProof(( + transaction_list_with_proof, + None, + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_transactions_or_outputs_with_proof(0, 0, 0, false, 0) + .await + .unwrap(); + + // Verify the response + let (transaction_list_with_proof_v2, output_list_with_proof_v2) = response.payload; + verify_response_data( + transaction_list_with_proof_v2, + output_list_with_proof_v2, + use_request_v2, + num_transactions_or_outputs, + ); + } +} + +#[tokio::test] +async fn test_get_new_transactions() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions = 34; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetNewTransactionsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetNewTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionData(TransactionData { + include_events: true, + }) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_list_with_proof = + Some(create_transaction_list_with_proof_v2(num_transactions)); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof, + transaction_output_list_with_proof: None, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let transaction_list_with_proof = + create_transaction_list_with_proof(num_transactions); + DataResponse::NewTransactionsWithProof(( + transaction_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_new_transactions_with_proof(0, 0, true, 0) + .await + .unwrap(); + + // Verify the response + let (transaction_list_with_proof_v2, _) = response.payload; + verify_response_data( + Some(transaction_list_with_proof_v2), + None, + use_request_v2, + num_transactions, + ); + } +} + +#[tokio::test] +async fn test_get_new_transaction_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_outputs = 42; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetNewTransactionOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetNewTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOutputData + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_output_list_with_proof = + Some(create_transaction_output_list_with_proof_v2(num_outputs)); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let output_list_with_proof = + create_transaction_output_list_with_proof(num_outputs); + DataResponse::NewTransactionOutputsWithProof(( + output_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_new_transaction_outputs_with_proof(0, 0, 0) + .await + .unwrap(); + + // Verify the response + let (output_list_with_proof_v2, _) = response.payload; + verify_response_data( + None, + Some(output_list_with_proof_v2), + use_request_v2, + num_outputs, + ); + } +} + +#[tokio::test] +async fn test_get_new_transactions_or_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions_or_outputs = 50; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::GetNewTransactionsOrOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::GetNewTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOrOutputData( + TransactionOrOutputData { + include_events: false, + } + ) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_list_with_proof = Some( + create_transaction_list_with_proof_v2(num_transactions_or_outputs), + ); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof, + transaction_output_list_with_proof: None, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let transaction_list_with_proof = + create_transaction_list_with_proof(num_transactions_or_outputs); + let transaction_or_output_list_with_proof = + (Some(transaction_list_with_proof), None); + DataResponse::NewTransactionsOrOutputsWithProof(( + transaction_or_output_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let response = client + .get_new_transactions_or_outputs_with_proof(0, 0, false, 0) + .await + .unwrap(); + + // Verify the response + let ((transaction_list_with_proof, output_list_with_proof), _) = response.payload; + verify_response_data( + transaction_list_with_proof, + output_list_with_proof, + use_request_v2, + num_transactions_or_outputs, + ); + } +} + +#[tokio::test] +async fn test_subscribe_transactions() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions = 5; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::SubscribeTransactionsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionData(TransactionData { + include_events: true, + }) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_list_with_proof = + Some(create_transaction_list_with_proof_v2(num_transactions)); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof, + transaction_output_list_with_proof: None, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let transaction_list_with_proof = + create_transaction_list_with_proof(num_transactions); + DataResponse::NewTransactionsWithProof(( + transaction_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let subscription_request_metadata = create_subscription_request_metadata(); + let response = client + .subscribe_to_transactions_with_proof(subscription_request_metadata, true, 0) + .await + .unwrap(); + + // Verify the response + let (transaction_list_with_proof_v2, _) = response.payload; + verify_response_data( + Some(transaction_list_with_proof_v2), + None, + use_request_v2, + num_transactions, + ); + } +} + +#[tokio::test] +async fn test_subscribe_transaction_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_outputs = 7; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::SubscribeTransactionOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOutputData + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_output_list_with_proof = + Some(create_transaction_output_list_with_proof_v2(num_outputs)); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let output_list_with_proof = + create_transaction_output_list_with_proof(num_outputs); + DataResponse::NewTransactionOutputsWithProof(( + output_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let subscription_request_metadata = create_subscription_request_metadata(); + let response = client + .subscribe_to_transaction_outputs_with_proof(subscription_request_metadata, 0) + .await + .unwrap(); + + // Verify the response + let (output_list_with_proof_v2, _) = response.payload; + verify_response_data( + None, + Some(output_list_with_proof_v2), + use_request_v2, + num_outputs, + ); + } +} + +#[tokio::test] +async fn test_subscribe_transactions_or_outputs() { + // Test both v1 and v2 requests + for use_request_v2 in [false, true] { + // Create the data client with a connected peer + let (mut mock_network, client, network_id) = create_client_with_peer(use_request_v2); + + // Spawn a handler for the peer to respond to the request + let num_transactions_or_outputs = 12; + tokio::spawn(async move { + while let Some(network_request) = mock_network.next_request(network_id).await { + tokio::spawn(async move { + // Verify the network request + match network_request.storage_service_request.data_request { + DataRequest::SubscribeTransactionsOrOutputsWithProof(_) => { + assert!(!use_request_v2) + }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + assert!(use_request_v2); + assert_matches!( + request.transaction_data_request_type, + TransactionDataRequestType::TransactionOrOutputData( + TransactionOrOutputData { + include_events: true, + } + ) + ); + }, + _ => panic!( + "Unexpected data request type: {:?}", + network_request.storage_service_request.data_request + ), + } + + // Create the storage service response + let data_response = if use_request_v2 { + let transaction_output_list_with_proof = + Some(create_transaction_output_list_with_proof_v2( + num_transactions_or_outputs, + )); + DataResponse::NewTransactionDataWithProof( + NewTransactionDataWithProofResponse { + transaction_data_response_type: + TransactionDataResponseType::TransactionData, + transaction_list_with_proof: None, + transaction_output_list_with_proof, + ledger_info_with_signatures: create_ledger_info(), + }, + ) + } else { + let output_list_with_proof = + create_transaction_output_list_with_proof(num_transactions_or_outputs); + let transaction_or_output_list_with_proof = + (None, Some(output_list_with_proof)); + DataResponse::NewTransactionsOrOutputsWithProof(( + transaction_or_output_list_with_proof, + create_ledger_info(), + )) + }; + let storage_service_response = + StorageServiceResponse::new(data_response, true).unwrap(); + + // Send the response + network_request + .response_sender + .send(Ok(storage_service_response)); + }); + } + }); + + // Send the request and wait for the response + let subscription_request_metadata = create_subscription_request_metadata(); + let response = client + .subscribe_to_transactions_or_outputs_with_proof(subscription_request_metadata, true, 0) + .await + .unwrap(); + + // Verify the response + let ((transaction_list_with_proof, output_list_with_proof), _) = response.payload; + verify_response_data( + transaction_list_with_proof, + output_list_with_proof, + use_request_v2, + num_transactions_or_outputs, + ); + } +} + +/// Creates a data client config with the specified request v2 flag +fn create_aptos_data_client(use_request_v2: bool) -> AptosDataClientConfig { + AptosDataClientConfig { + enable_transaction_data_v2: use_request_v2, + ..Default::default() + } +} + +/// Creates a data client with a connected peer for testing +fn create_client_with_peer(use_request_v2: bool) -> (MockNetwork, AptosDataClient, NetworkId) { + // Create a base config for a fullnode + let base_config = utils::create_fullnode_base_config(); + + // Create a data client config with request v2 set appropriately + let data_client_config = create_aptos_data_client(use_request_v2); + + // Create the mock network and client + let (mut mock_network, _, client, _) = + MockNetwork::new(Some(base_config), Some(data_client_config), None); + + // Add a peer to the network + let (peer_network_id, network_id) = + utils::add_peer_to_network(PeerPriority::HighPriority, &mut mock_network); + + // Advertise transaction data for the peer + let storage_summary = utils::create_storage_summary(1000); + client.update_peer_storage_summary(peer_network_id, storage_summary.clone()); + client.update_global_summary_cache().unwrap(); + (mock_network, client, network_id) +} + +/// Creates a new ledger info +fn create_ledger_info() -> LedgerInfoWithSignatures { + LedgerInfoWithSignatures::new( + LedgerInfo::new(BlockInfo::random_with_epoch(10, 10), HashValue::random()), + AggregateSignature::empty(), + ) +} + +/// Creates a subscription request metadata with default values +fn create_subscription_request_metadata() -> SubscriptionRequestMetadata { + SubscriptionRequestMetadata { + known_version_at_stream_start: 0, + known_epoch_at_stream_start: 0, + subscription_stream_index: 0, + subscription_stream_id: 0, + } +} + +/// Creates a test transaction +fn create_transaction() -> Transaction { + let private_key = Ed25519PrivateKey::generate_for_testing(); + let public_key = private_key.public_key(); + + let transaction_payload = TransactionPayload::Script(Script::new(vec![], vec![], vec![])); + let raw_transaction = RawTransaction::new( + AccountAddress::random(), + 0, + transaction_payload, + 0, + 0, + 0, + ChainId::new(10), + ); + let signature = private_key.sign(&raw_transaction).unwrap(); + let signed_transaction = SignedTransaction::new(raw_transaction, public_key, signature); + + Transaction::UserTransaction(signed_transaction) +} + +/// Creates a test transaction info +fn create_transaction_info() -> TransactionInfo { + TransactionInfo::new( + HashValue::random(), + HashValue::random(), + HashValue::random(), + Some(HashValue::random()), + 0, + ExecutionStatus::Success, + Some(HashValue::random()), + ) +} + +/// Creates a transaction list with proof (with the specified number of transactions) +fn create_transaction_list_with_proof(num_transactions: usize) -> TransactionListWithProof { + // Create the requested transactions + let mut transactions = vec![]; + for _ in 0..num_transactions { + transactions.push(create_transaction()); + } + + // Create the transaction infos + let mut transaction_infos = vec![]; + for _ in 0..num_transactions { + transaction_infos.push(create_transaction_info()); + } + + // Create the transaction list with proof + let mut transaction_list_with_proof = TransactionListWithProof::new_empty(); + transaction_list_with_proof.transactions = transactions; + transaction_list_with_proof.proof.transaction_infos = transaction_infos; + + transaction_list_with_proof +} + +/// Creates a transaction list with proof v2 (with the specified number of transactions) +fn create_transaction_list_with_proof_v2(num_transactions: usize) -> TransactionListWithProofV2 { + // Create the transaction list with proof + let transaction_list_with_proof = create_transaction_list_with_proof(num_transactions); + + // Create the auxiliary infos + let mut persisted_auxiliary_infos = vec![]; + for index in 0..num_transactions { + persisted_auxiliary_infos.push(PersistedAuxiliaryInfo::V1 { + transaction_index: index as u32, + }); + } + + // Create the transaction list with proof v2 + let transaction_list_with_auxiliary_infos = TransactionListWithAuxiliaryInfos::new( + transaction_list_with_proof, + persisted_auxiliary_infos, + ); + TransactionListWithProofV2::new(transaction_list_with_auxiliary_infos) +} + +/// Creates a single test transaction output +fn create_transaction_output() -> TransactionOutput { + TransactionOutput::new( + WriteSet::default(), + vec![], + 0, + TransactionStatus::Keep(ExecutionStatus::Success), + TransactionAuxiliaryData::default(), + ) +} + +/// Creates a transaction output list with proof (with the specified number of outputs) +fn create_transaction_output_list_with_proof(num_outputs: usize) -> TransactionOutputListWithProof { + // Create the transactions and outputs + let transaction_list_with_proof = create_transaction_list_with_proof(num_outputs); + let transactions_and_outputs = transaction_list_with_proof + .transactions + .iter() + .map(|txn| (txn.clone(), create_transaction_output())) + .collect(); + + // Create the transaction infos + let mut transaction_infos = vec![]; + for _ in 0..num_outputs { + transaction_infos.push(create_transaction_info()); + } + + // Create the transaction output list with proof + let mut output_list_with_proof = TransactionOutputListWithProof::new_empty(); + output_list_with_proof.transactions_and_outputs = transactions_and_outputs; + output_list_with_proof.proof.transaction_infos = transaction_infos; + + output_list_with_proof +} + +/// Creates a transaction output list with proof v2 (with the specified number of outputs) +fn create_transaction_output_list_with_proof_v2( + num_outputs: usize, +) -> TransactionOutputListWithProofV2 { + // Create the transaction output list with proof + let transaction_output_list_with_proof = create_transaction_output_list_with_proof(num_outputs); + + // Create the auxiliary infos + let mut persisted_auxiliary_infos = vec![]; + for index in 0..num_outputs { + persisted_auxiliary_infos.push(PersistedAuxiliaryInfo::V1 { + transaction_index: index as u32, + }); + } + + // Create the transaction output list with proof v2 + let output_list_with_auxiliary_infos = TransactionOutputListWithAuxiliaryInfos::new( + transaction_output_list_with_proof, + persisted_auxiliary_infos, + ); + TransactionOutputListWithProofV2::new(output_list_with_auxiliary_infos) +} + +/// Verifies that the persisted auxiliary infos are populated correctly +fn verify_persisted_auxiliary_infos( + use_request_v2: bool, + persisted_auxiliary_infos: &[PersistedAuxiliaryInfo], + expected_length: usize, +) { + // Verify the length of the auxiliary infos + assert_eq!(persisted_auxiliary_infos.len(), expected_length); + + // Verify the contents of the auxiliary infos + for auxiliary_info in persisted_auxiliary_infos { + if use_request_v2 { + assert_matches!(auxiliary_info, PersistedAuxiliaryInfo::V1 { .. }); + } else { + assert_eq!(auxiliary_info, &PersistedAuxiliaryInfo::None); + } + } +} + +/// Verifies the response data for any given transaction or output list. +/// Also verifies the persisted auxiliary infos (if applicable). +fn verify_response_data( + transaction_list_with_proof_v2: Option, + output_list_with_proof_v2: Option, + use_request_v2: bool, + expected_count: usize, +) { + // Verify the transaction data + if let Some(transaction_list_with_proof_v2) = transaction_list_with_proof_v2 { + // Verify the number of transactions + let transaction_list_with_proof = + transaction_list_with_proof_v2.get_transaction_list_with_proof(); + let num_transactions = transaction_list_with_proof.get_num_transactions(); + assert_eq!(num_transactions, expected_count); + + // Verify the persisted auxiliary infos + verify_persisted_auxiliary_infos( + use_request_v2, + transaction_list_with_proof_v2.get_persisted_auxiliary_infos(), + expected_count, + ); + } + + // Verify the output data + if let Some(output_list_with_proof_v2) = output_list_with_proof_v2 { + // Verify the number of outputs + let output_list_with_proof = output_list_with_proof_v2.get_output_list_with_proof(); + let num_outputs = output_list_with_proof.get_num_outputs(); + assert_eq!(num_outputs, expected_count); + + // Verify the persisted auxiliary infos + verify_persisted_auxiliary_infos( + use_request_v2, + output_list_with_proof_v2.get_persisted_auxiliary_infos(), + expected_count, + ); + } +} diff --git a/state-sync/aptos-data-client/src/tests/utils.rs b/state-sync/aptos-data-client/src/tests/utils.rs index 7dc403f6d73..9d68187f634 100644 --- a/state-sync/aptos-data-client/src/tests/utils.rs +++ b/state-sync/aptos-data-client/src/tests/utils.rs @@ -307,7 +307,7 @@ pub fn get_peer_priority_for_polling(poll_priority_peers: bool) -> PeerPriority PeerPriority::HighPriority } else { // Generate a random u64 - let random_number: u64 = OsRng.gen(); + let random_number: u64 = OsRng.r#gen(); // If the random number is even, return medium priority. // Otherwise, return low priority. diff --git a/state-sync/data-streaming-service/src/data_notification.rs b/state-sync/data-streaming-service/src/data_notification.rs index f3ea476086d..229e3fb3e8a 100644 --- a/state-sync/data-streaming-service/src/data_notification.rs +++ b/state-sync/data-streaming-service/src/data_notification.rs @@ -7,7 +7,7 @@ use aptos_data_client::interface::{Response, ResponsePayload}; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, }; use std::{ fmt::{Debug, Formatter}, @@ -39,13 +39,16 @@ impl DataNotification { #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Eq, PartialEq)] pub enum DataPayload { - ContinuousTransactionOutputsWithProof(LedgerInfoWithSignatures, TransactionOutputListWithProof), - ContinuousTransactionsWithProof(LedgerInfoWithSignatures, TransactionListWithProof), + ContinuousTransactionOutputsWithProof( + LedgerInfoWithSignatures, + TransactionOutputListWithProofV2, + ), + ContinuousTransactionsWithProof(LedgerInfoWithSignatures, TransactionListWithProofV2), EpochEndingLedgerInfos(Vec), EndOfStream, StateValuesWithProof(StateValueChunkWithProof), - TransactionOutputsWithProof(TransactionOutputListWithProof), - TransactionsWithProof(TransactionListWithProof), + TransactionOutputsWithProof(TransactionOutputListWithProofV2), + TransactionsWithProof(TransactionListWithProofV2), } /// A request that has been sent to the Aptos data client. diff --git a/state-sync/data-streaming-service/src/data_stream.rs b/state-sync/data-streaming-service/src/data_stream.rs index 68e8fbe4aba..8c407701391 100644 --- a/state-sync/data-streaming-service/src/data_stream.rs +++ b/state-sync/data-streaming-service/src/data_stream.rs @@ -555,8 +555,9 @@ impl DataStream { // Get the highest version sent in the subscription response let highest_response_version = match response_payload { ResponsePayload::NewTransactionsWithProof((transactions_with_proof, _)) => { - if let Some(first_version) = transactions_with_proof.first_transaction_version { - let num_transactions = transactions_with_proof.transactions.len(); + if let Some(first_version) = transactions_with_proof.get_first_transaction_version() + { + let num_transactions = transactions_with_proof.get_num_transactions(); first_version .saturating_add(num_transactions as u64) .saturating_sub(1) // first_version + num_txns - 1 @@ -567,8 +568,8 @@ impl DataStream { } }, ResponsePayload::NewTransactionOutputsWithProof((outputs_with_proof, _)) => { - if let Some(first_version) = outputs_with_proof.first_transaction_output_version { - let num_outputs = outputs_with_proof.transactions_and_outputs.len(); + if let Some(first_version) = outputs_with_proof.get_first_output_version() { + let num_outputs = outputs_with_proof.get_num_outputs(); first_version .saturating_add(num_outputs as u64) .saturating_sub(1) // first_version + num_outputs - 1 @@ -1165,7 +1166,7 @@ fn create_missing_transactions_request( match response_payload { ResponsePayload::TransactionsWithProof(transactions_with_proof) => { // Check if the request was satisfied - let num_received_transactions = transactions_with_proof.transactions.len() as u64; + let num_received_transactions = transactions_with_proof.get_num_transactions() as u64; if num_received_transactions < num_requested_transactions { let start_version = request .start_version @@ -1210,9 +1211,7 @@ fn create_missing_transaction_outputs_request( match response_payload { ResponsePayload::TransactionOutputsWithProof(transaction_outputs_with_proof) => { // Check if the request was satisfied - let num_received_outputs = transaction_outputs_with_proof - .transactions_and_outputs - .len() as u64; + let num_received_outputs = transaction_outputs_with_proof.get_num_outputs() as u64; if num_received_outputs < num_requested_outputs { let start_version = request .start_version @@ -1257,12 +1256,10 @@ fn create_missing_transactions_or_outputs_request( // Calculate the number of received data items let num_received_data_items = match response_payload { ResponsePayload::TransactionsWithProof(transactions_with_proof) => { - transactions_with_proof.transactions.len() as u64 + transactions_with_proof.get_num_transactions() as u64 }, ResponsePayload::TransactionOutputsWithProof(transaction_outputs_with_proof) => { - transaction_outputs_with_proof - .transactions_and_outputs - .len() as u64 + transaction_outputs_with_proof.get_num_outputs() as u64 }, payload => { return Err(Error::AptosDataClientResponseIsInvalid(format!( diff --git a/state-sync/data-streaming-service/src/stream_engine.rs b/state-sync/data-streaming-service/src/stream_engine.rs index 88045007cfa..f304083901d 100644 --- a/state-sync/data-streaming-service/src/stream_engine.rs +++ b/state-sync/data-streaming-service/src/stream_engine.rs @@ -427,19 +427,46 @@ impl ContinuousTransactionStreamEngine { data_streaming_config: DataStreamingServiceConfig, stream_request: &StreamRequest, ) -> Result { - let (next_version, next_epoch) = match stream_request { + // Extract the target version, next version, and next epoch + let (target_version, next_version, next_epoch) = match stream_request { StreamRequest::ContinuouslyStreamTransactions(request) => { - Self::calculate_next_version_and_epoch(request.known_version, request.known_epoch)? + let target_version = Self::get_target_version(&request.target); + let (next_version, next_epoch) = Self::calculate_next_version_and_epoch( + request.known_version, + request.known_epoch, + )?; + (target_version, next_version, next_epoch) }, StreamRequest::ContinuouslyStreamTransactionOutputs(request) => { - Self::calculate_next_version_and_epoch(request.known_version, request.known_epoch)? + let target_version = Self::get_target_version(&request.target); + let (next_version, next_epoch) = Self::calculate_next_version_and_epoch( + request.known_version, + request.known_epoch, + )?; + (target_version, next_version, next_epoch) }, StreamRequest::ContinuouslyStreamTransactionsOrOutputs(request) => { - Self::calculate_next_version_and_epoch(request.known_version, request.known_epoch)? + let target_version = Self::get_target_version(&request.target); + let (next_version, next_epoch) = Self::calculate_next_version_and_epoch( + request.known_version, + request.known_epoch, + )?; + (target_version, next_version, next_epoch) }, request => invalid_stream_request!(request), }; + // Verify that the target version is >= the next version + if let Some(target_version) = target_version { + if target_version < next_version { + return Err(Error::UnexpectedErrorEncountered(format!( + "Invalid stream request found! Target version ({}) is < next version ({})! No data can be fetched!", + target_version, next_version + ))); + } + } + + // Create the continuous transaction stream engine Ok(ContinuousTransactionStreamEngine { data_streaming_config, request: stream_request.clone(), @@ -453,6 +480,12 @@ impl ContinuousTransactionStreamEngine { }) } + fn get_target_version(target: &Option) -> Option { + target + .as_ref() + .map(|ledger_info_with_signatures| ledger_info_with_signatures.ledger_info().version()) + } + fn calculate_next_version_and_epoch( known_version: Version, known_epoch: Epoch, @@ -518,10 +551,10 @@ impl ContinuousTransactionStreamEngine { // Check the number of received versions let num_received_versions = match &client_response_payload { ResponsePayload::TransactionsWithProof(transactions_with_proof) => { - transactions_with_proof.transactions.len() + transactions_with_proof.get_num_transactions() }, ResponsePayload::TransactionOutputsWithProof(outputs_with_proof) => { - outputs_with_proof.transactions_and_outputs.len() + outputs_with_proof.get_num_outputs() }, _ => invalid_response_type!(client_response_payload), }; @@ -1674,10 +1707,10 @@ impl TransactionStreamEngine { // Check the number of received versions let num_received_versions = match client_response_payload { ResponsePayload::TransactionsWithProof(transactions_with_proof) => { - transactions_with_proof.transactions.len() + transactions_with_proof.get_num_transactions() }, ResponsePayload::TransactionOutputsWithProof(outputs_with_proof) => { - outputs_with_proof.transactions_and_outputs.len() + outputs_with_proof.get_num_outputs() }, _ => invalid_response_type!(client_response_payload), }; @@ -2186,7 +2219,7 @@ fn create_data_notification( StreamEngine::ContinuousTransactionStreamEngine(_) => { DataPayload::ContinuousTransactionOutputsWithProof( target_ledger_info, - transactions_output_chunk, + transactions_output_chunk.clone(), ) }, _ => invalid_response_type!(client_response_type), @@ -2243,14 +2276,14 @@ fn extract_new_versions_and_target( transactions_with_proof, target_ledger_info, )) => ( - transactions_with_proof.transactions.len(), + transactions_with_proof.get_num_transactions(), target_ledger_info.clone(), ), ResponsePayload::NewTransactionOutputsWithProof(( outputs_with_proof, target_ledger_info, )) => ( - outputs_with_proof.transactions_and_outputs.len(), + outputs_with_proof.get_num_outputs(), target_ledger_info.clone(), ), response_payload => { diff --git a/state-sync/data-streaming-service/src/tests/data_stream.rs b/state-sync/data-streaming-service/src/tests/data_stream.rs index c62e854110d..fa97624ccfe 100644 --- a/state-sync/data-streaming-service/src/tests/data_stream.rs +++ b/state-sync/data-streaming-service/src/tests/data_stream.rs @@ -3952,8 +3952,7 @@ fn get_pending_client_request( ) -> DataClientRequest { let (sent_requests, _) = data_stream.get_sent_requests_and_notifications(); let pending_response = sent_requests.as_ref().unwrap().get(index).unwrap(); - let client_request = pending_response.lock().client_request.clone(); - client_request + pending_response.lock().client_request.clone() } /// Returns the subscription stream ID from the pending client request at the given index diff --git a/state-sync/data-streaming-service/src/tests/missing_data.rs b/state-sync/data-streaming-service/src/tests/missing_data.rs index df70d4af21f..939cde66ffb 100644 --- a/state-sync/data-streaming-service/src/tests/missing_data.rs +++ b/state-sync/data-streaming-service/src/tests/missing_data.rs @@ -17,7 +17,7 @@ use crate::{ ContinuouslyStreamTransactionOutputsRequest, GetAllEpochEndingLedgerInfosRequest, GetAllStatesRequest, GetAllTransactionsRequest, StreamRequest, }, - tests::utils::{create_ledger_info, create_transaction_list_with_proof}, + tests::{utils, utils::create_ledger_info}, }; use aptos_config::config::DataStreamingServiceConfig; use aptos_crypto::HashValue; @@ -31,8 +31,9 @@ use aptos_types::{ state_value::{StateValue, StateValueChunkWithProof}, }, transaction::{ - Transaction, TransactionAuxiliaryData, TransactionListWithProof, TransactionOutput, - TransactionOutputListWithProof, TransactionStatus, + Transaction, TransactionAuxiliaryData, TransactionListWithProof, + TransactionListWithProofV2, TransactionOutput, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, TransactionStatus, Version, }, write_set::WriteSet, }; @@ -233,12 +234,9 @@ fn create_missing_data_request_transactions() { let transactions = (start_version..last_response_version + 1) .map(|_| create_test_transaction()) .collect::>(); - let response_payload = ResponsePayload::TransactionsWithProof(TransactionListWithProof { - transactions, - events: None, - first_transaction_version: Some(start_version), - proof: TransactionInfoListWithProof::new_empty(), - }); + let transaction_list_with_proof = + create_transaction_list_with_proof(start_version, transactions); + let response_payload = ResponsePayload::TransactionsWithProof(transaction_list_with_proof); // Create the missing data request and verify that it's valid let missing_data_request = @@ -257,12 +255,9 @@ fn create_missing_data_request_transactions() { let transactions = (start_version..last_response_version + 1) .map(|_| create_test_transaction()) .collect::>(); - let response_payload = ResponsePayload::TransactionsWithProof(TransactionListWithProof { - transactions, - events: None, - first_transaction_version: Some(start_version), - proof: TransactionInfoListWithProof::new_empty(), - }); + let transaction_list_with_proof = + create_transaction_list_with_proof(start_version, transactions); + let response_payload = ResponsePayload::TransactionsWithProof(transaction_list_with_proof); // Create the missing data request and verify that it's empty let missing_data_request = @@ -287,12 +282,9 @@ fn create_missing_data_request_transaction_outputs() { let transactions_and_outputs = (start_version..last_response_version + 1) .map(|_| (create_test_transaction(), create_test_transaction_output())) .collect::>(); - let response_payload = - ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProof { - transactions_and_outputs, - proof: TransactionInfoListWithProof::new_empty(), - first_transaction_output_version: Some(start_version), - }); + let output_list_with_proof = + create_output_list_with_proof(start_version, transactions_and_outputs); + let response_payload = ResponsePayload::TransactionOutputsWithProof(output_list_with_proof); // Create the missing data request and verify that it's valid let missing_data_request = @@ -310,12 +302,9 @@ fn create_missing_data_request_transaction_outputs() { let transactions_and_outputs = (start_version..last_response_version + 1) .map(|_| (create_test_transaction(), create_test_transaction_output())) .collect::>(); - let response_payload = - ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProof { - transactions_and_outputs, - proof: TransactionInfoListWithProof::new_empty(), - first_transaction_output_version: Some(start_version), - }); + let output_list_with_proof = + create_output_list_with_proof(start_version, transactions_and_outputs); + let response_payload = ResponsePayload::TransactionOutputsWithProof(output_list_with_proof); // Create the missing data request and verify that it's empty let missing_data_request = @@ -341,24 +330,19 @@ fn create_missing_data_request_transactions_or_outputs() { let transactions = (start_version..last_response_version + 1) .map(|_| create_test_transaction()) .collect::>(); + let transaction_list_with_proof = + create_transaction_list_with_proof(start_version, transactions); let response_payload_with_transactions = - ResponsePayload::TransactionsWithProof(TransactionListWithProof { - transactions, - events: None, - first_transaction_version: Some(start_version), - proof: TransactionInfoListWithProof::new_empty(), - }); + ResponsePayload::TransactionsWithProof(transaction_list_with_proof); // Create a partial response payload with transaction outputs let transactions_and_outputs = (start_version..last_response_version + 1) .map(|_| (create_test_transaction(), create_test_transaction_output())) .collect::>(); + let output_list_with_proof = + create_output_list_with_proof(start_version, transactions_and_outputs); let response_payload_with_transaction_outputs = - ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProof { - transactions_and_outputs, - proof: TransactionInfoListWithProof::new_empty(), - first_transaction_output_version: Some(start_version), - }); + ResponsePayload::TransactionOutputsWithProof(output_list_with_proof); // Create the missing data requests and verify that they are valid for response_payload in [ @@ -383,24 +367,19 @@ fn create_missing_data_request_transactions_or_outputs() { let transactions = (start_version..last_response_version + 1) .map(|_| create_test_transaction()) .collect::>(); + let transaction_list_with_proof = + create_transaction_list_with_proof(start_version, transactions); let response_payload_with_transactions = - ResponsePayload::TransactionsWithProof(TransactionListWithProof { - transactions, - events: None, - first_transaction_version: Some(start_version), - proof: TransactionInfoListWithProof::new_empty(), - }); + ResponsePayload::TransactionsWithProof(transaction_list_with_proof); // Create a complete response payload with transaction outputs let transactions_and_outputs = (start_version..last_response_version + 1) .map(|_| (create_test_transaction(), create_test_transaction_output())) .collect::>(); + let output_list_with_proof = + create_output_list_with_proof(start_version, transactions_and_outputs); let response_payload_with_transaction_outputs = - ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProof { - transactions_and_outputs, - proof: TransactionInfoListWithProof::new_empty(), - first_transaction_output_version: Some(start_version), - }); + ResponsePayload::TransactionOutputsWithProof(output_list_with_proof); // Create the missing data requests and verify that they are empty for response_payload in [ @@ -699,7 +678,7 @@ fn transform_transactions_stream_notifications() { // Create an empty client response let client_response_payload = - ResponsePayload::TransactionsWithProof(TransactionListWithProof::new_empty()); + ResponsePayload::TransactionsWithProof(TransactionListWithProofV2::new_empty()); // Transform the client response into a notification and verify an error is returned let _ = stream_engine @@ -713,7 +692,7 @@ fn transform_transactions_stream_notifications() { // Create a partial client response let last_version = end_version - 50; let transactions_with_proof = - create_transaction_list_with_proof(start_version, last_version, true); + utils::create_transaction_list_with_proof(start_version, last_version, true); let client_response_payload = ResponsePayload::TransactionsWithProof(transactions_with_proof.clone()); @@ -806,7 +785,7 @@ fn transform_continuous_outputs_stream_notifications() { // Create an empty client response let client_response_payload = - ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProof::new_empty()); + ResponsePayload::TransactionOutputsWithProof(TransactionOutputListWithProofV2::new_empty()); // Transform the client response into a notification and verify an error is returned let _ = stream_engine @@ -822,13 +801,10 @@ fn transform_continuous_outputs_stream_notifications() { let transactions_and_outputs = (known_version..last_version + 1) .map(|_| (create_test_transaction(), create_test_transaction_output())) .collect::>(); - let transaction_outputs_with_proof = TransactionOutputListWithProof { - transactions_and_outputs, - proof: TransactionInfoListWithProof::new_empty(), - first_transaction_output_version: Some(known_version), - }; + let output_list_with_proof = + create_output_list_with_proof(known_version, transactions_and_outputs); let client_response_payload = - ResponsePayload::TransactionOutputsWithProof(transaction_outputs_with_proof.clone()); + ResponsePayload::TransactionOutputsWithProof(output_list_with_proof); // Transform the client response into a notification let data_client_request = @@ -861,6 +837,19 @@ fn create_notification_id_generator() -> Arc { Arc::new(U64IdGenerator::new()) } +/// Creates an output list with proof for testing purposes +fn create_output_list_with_proof( + start_version: Version, + transactions_and_outputs: Vec<(Transaction, TransactionOutput)>, +) -> TransactionOutputListWithProofV2 { + let output_list_with_proof = TransactionOutputListWithProof { + transactions_and_outputs, + proof: TransactionInfoListWithProof::new_empty(), + first_transaction_output_version: Some(start_version), + }; + TransactionOutputListWithProofV2::new_from_v1(output_list_with_proof) +} + /// Returns a state value chunk with proof for testing purposes fn create_state_value_chunk( first_index: u64, @@ -899,3 +888,17 @@ fn create_test_transaction_output() -> TransactionOutput { TransactionAuxiliaryData::default(), ) } + +/// Creates a transaction list with proof for testing purposes +fn create_transaction_list_with_proof( + start_version: Version, + transactions: Vec, +) -> TransactionListWithProofV2 { + let transaction_list_with_proof = TransactionListWithProof { + transactions, + events: None, + first_transaction_version: Some(start_version), + proof: TransactionInfoListWithProof::new_empty(), + }; + TransactionListWithProofV2::new_from_v1(transaction_list_with_proof) +} diff --git a/state-sync/data-streaming-service/src/tests/stream_engine.rs b/state-sync/data-streaming-service/src/tests/stream_engine.rs index edfe25ddf7d..89952735bc5 100644 --- a/state-sync/data-streaming-service/src/tests/stream_engine.rs +++ b/state-sync/data-streaming-service/src/tests/stream_engine.rs @@ -6,11 +6,12 @@ use crate::{ data_notification::{DataClientRequest, EpochEndingLedgerInfosRequest}, error::Error, stream_engine::{DataStreamEngine, EpochEndingStreamEngine, StreamEngine}, - streaming_client::{GetAllEpochEndingLedgerInfosRequest, StreamRequest}, - tests::{ - utils, - utils::{create_ledger_info, initialize_logger}, + streaming_client::{ + ContinuouslyStreamTransactionOutputsRequest, + ContinuouslyStreamTransactionsOrOutputsRequest, ContinuouslyStreamTransactionsRequest, + GetAllEpochEndingLedgerInfosRequest, StreamRequest, }, + tests::{utils, utils::initialize_logger}, }; use aptos_config::config::DataStreamingServiceConfig; use aptos_data_client::{ @@ -19,6 +20,7 @@ use aptos_data_client::{ }; use aptos_id_generator::U64IdGenerator; use aptos_storage_service_types::responses::CompleteDataRange; +use aptos_types::transaction::Version; use claims::{assert_matches, assert_ok}; use std::{cmp, sync::Arc}; @@ -246,6 +248,91 @@ fn test_epoch_ending_stream_engine() { } } +#[test] +fn test_invalid_continuous_transactions_stream_engine() { + // Create a continuous transaction stream request with an invalid target + let known_version = 100; + let known_epoch = 5; + let target = utils::create_ledger_info(known_version - 1, known_epoch, false); + let stream_request = + StreamRequest::ContinuouslyStreamTransactions(ContinuouslyStreamTransactionsRequest { + known_version, + known_epoch, + include_events: false, + target: Some(target), + }); + + // Create a global data summary with non-zero advertised data + let global_data_summary = create_global_data_summary_for_transactions(known_version); + + // Try to create a stream engine and verify an error is returned (the + // target version is already known, so there is no new data to fetch). + let data_streaming_config = DataStreamingServiceConfig::default(); + let result = StreamEngine::new( + data_streaming_config, + &stream_request, + &global_data_summary.advertised_data, + ); + assert_matches!(result, Err(Error::UnexpectedErrorEncountered(_))); +} + +#[test] +fn test_invalid_continuous_transactions_or_outputs_stream_engine() { + // Create a continuous transactions or outputs stream request with an invalid target + let known_version = 100; + let known_epoch = 5; + let target = utils::create_ledger_info(known_version - 2, known_epoch, false); + let stream_request = StreamRequest::ContinuouslyStreamTransactionsOrOutputs( + ContinuouslyStreamTransactionsOrOutputsRequest { + known_version, + known_epoch, + include_events: false, + target: Some(target), + }, + ); + + // Create a global data summary with non-zero advertised data + let global_data_summary = create_global_data_summary_for_transactions(known_version); + + // Try to create a stream engine and verify an error is returned (the + // target version is already known, so there is no new data to fetch). + let data_streaming_config = DataStreamingServiceConfig::default(); + let result = StreamEngine::new( + data_streaming_config, + &stream_request, + &global_data_summary.advertised_data, + ); + assert_matches!(result, Err(Error::UnexpectedErrorEncountered(_))); +} + +#[test] +fn test_invalid_continuous_outputs_stream_engine() { + // Create a continuous outputs stream request with an invalid target + let known_version = 100; + let known_epoch = 5; + let target = utils::create_ledger_info(known_version, known_epoch, false); + let stream_request = StreamRequest::ContinuouslyStreamTransactionOutputs( + ContinuouslyStreamTransactionOutputsRequest { + known_version, + known_epoch, + target: Some(target), + }, + ); + + // Create a global data summary with non-zero advertised data + let global_data_summary = create_global_data_summary_for_transactions(known_version); + + // Try to create a stream engine and verify an error is returned (the + // target version is already known, so there is no new data to fetch). + let data_streaming_config = DataStreamingServiceConfig::default(); + let result = StreamEngine::new( + data_streaming_config, + &stream_request, + &global_data_summary.advertised_data, + ); + assert_matches!(result, Err(Error::UnexpectedErrorEncountered(_))); +} + #[test] fn test_update_epoch_ending_stream_progress() { // Create a new data stream engine @@ -279,7 +366,7 @@ fn test_update_epoch_ending_stream_panic() { // Update the engine with a valid notification let client_response_payload = - ResponsePayload::EpochEndingLedgerInfos(vec![create_ledger_info(0, 0, true)]); + ResponsePayload::EpochEndingLedgerInfos(vec![utils::create_ledger_info(0, 0, true)]); let _ = stream_engine .transform_client_response_into_notification( &DataClientRequest::EpochEndingLedgerInfos(EpochEndingLedgerInfosRequest { @@ -363,3 +450,12 @@ fn create_epoch_ending_ledger_info_payload(start_epoch: u64, end_epoch: u64) -> .collect(); ResponsePayload::EpochEndingLedgerInfos(epoch_ending_ledger_infos) } + +/// Creates a global data summary with advertised transactions and transaction outputs +fn create_global_data_summary_for_transactions(known_version: Version) -> GlobalDataSummary { + let mut global_data_summary = GlobalDataSummary::empty(); + let complete_data_range = CompleteDataRange::new(0, known_version * 2).unwrap(); + global_data_summary.advertised_data.transactions = vec![complete_data_range]; + global_data_summary.advertised_data.transaction_outputs = vec![complete_data_range]; + global_data_summary +} diff --git a/state-sync/data-streaming-service/src/tests/streaming_service.rs b/state-sync/data-streaming-service/src/tests/streaming_service.rs index 73dbc63726e..c4978fc58bf 100644 --- a/state-sync/data-streaming-service/src/tests/streaming_service.rs +++ b/state-sync/data-streaming-service/src/tests/streaming_service.rs @@ -23,9 +23,9 @@ use aptos_config::config::{AptosDataClientConfig, DataStreamingServiceConfig}; use aptos_time_service::TimeService; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, - transaction::{TransactionListWithProof, TransactionOutputListWithProof}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2}, }; -use claims::{assert_le, assert_matches, assert_ok, assert_some}; +use claims::{assert_le, assert_matches, assert_ok}; macro_rules! unexpected_payload_type { ($received:expr) => { @@ -186,11 +186,11 @@ async fn test_notifications_continuous_outputs_target() { assert_eq!(ledger_info.epoch(), next_expected_epoch); // Verify the output start version matches the expected version - let first_output_version = outputs_with_proofs.first_transaction_output_version; + let first_output_version = outputs_with_proofs.get_first_output_version(); assert_eq!(Some(next_expected_version), first_output_version); // Update the next expected version - let num_outputs = outputs_with_proofs.transactions_and_outputs.len() as u64; + let num_outputs = outputs_with_proofs.get_num_outputs() as u64; next_expected_version += num_outputs; // Update epochs if we've hit the epoch end @@ -234,11 +234,11 @@ async fn test_notifications_continuous_outputs_multiple_streams() { outputs_with_proofs, ) => { // Verify the first output version - let first_output_version = outputs_with_proofs.first_transaction_output_version; + let first_output_version = outputs_with_proofs.get_first_output_version(); assert_eq!(Some(next_expected_version), first_output_version); // Update the next expected version - let num_outputs = outputs_with_proofs.transactions_and_outputs.len() as u64; + let num_outputs = outputs_with_proofs.get_num_outputs() as u64; next_expected_version += num_outputs; // Update the next expected epoch if we've hit the epoch end @@ -356,14 +356,18 @@ async fn test_notifications_continuous_transactions_target() { assert_eq!(ledger_info.epoch(), next_expected_epoch); // Verify the transaction start version matches the expected version - let first_transaction_version = transactions_with_proof.first_transaction_version; + let first_transaction_version = + transactions_with_proof.get_first_transaction_version(); assert_eq!(Some(next_expected_version), first_transaction_version); // Verify the payload contains events - assert_some!(transactions_with_proof.events); + assert!(transactions_with_proof + .get_transaction_list_with_proof() + .events + .is_some()); // Update the next expected version - let num_transactions = transactions_with_proof.transactions.len() as u64; + let num_transactions = transactions_with_proof.get_num_transactions() as u64; next_expected_version += num_transactions; // Update epochs if we've hit the epoch end @@ -409,11 +413,12 @@ async fn test_notifications_continuous_transactions_multiple_streams() { transactions_with_proofs, ) => { // Verify the first transaction version - let first_transaction_version = transactions_with_proofs.first_transaction_version; + let first_transaction_version = + transactions_with_proofs.get_first_transaction_version(); assert_eq!(Some(next_expected_version), first_transaction_version); // Update the next expected version - let num_transactions = transactions_with_proofs.transactions.len() as u64; + let num_transactions = transactions_with_proofs.get_num_transactions() as u64; next_expected_version += num_transactions; // Update the next expected epoch if we've hit the epoch end @@ -550,29 +555,30 @@ async fn test_notifications_continuous_transactions_or_outputs_target() { transactions_with_proof .clone() .unwrap() - .first_transaction_version + .get_first_transaction_version() } else { outputs_with_proof .clone() .unwrap() - .first_transaction_output_version + .get_first_output_version() }; assert_eq!(Some(next_expected_version), first_version); // Verify the payload contains events if transactions_with_proof.is_some() { - assert_some!(transactions_with_proof.clone().unwrap().events); + assert!(transactions_with_proof + .clone() + .unwrap() + .get_transaction_list_with_proof() + .events + .is_some()); } // Update the next expected version let num_transactions = if transactions_with_proof.is_some() { - transactions_with_proof.clone().unwrap().transactions.len() as u64 + transactions_with_proof.unwrap().get_num_transactions() as u64 } else { - outputs_with_proof - .clone() - .unwrap() - .transactions_and_outputs - .len() as u64 + outputs_with_proof.unwrap().get_num_outputs() as u64 }; next_expected_version += num_transactions; @@ -626,24 +632,20 @@ async fn test_notifications_continuous_transactions_or_outputs_multiple_streams( transactions_with_proof .clone() .unwrap() - .first_transaction_version + .get_first_transaction_version() } else { outputs_with_proof .clone() .unwrap() - .first_transaction_output_version + .get_first_output_version() }; assert_eq!(Some(next_expected_version), first_version); // Update the next expected version let num_transactions = if transactions_with_proof.is_some() { - transactions_with_proof.clone().unwrap().transactions.len() as u64 + transactions_with_proof.unwrap().get_num_transactions() as u64 } else { - outputs_with_proof - .clone() - .unwrap() - .transactions_and_outputs - .len() as u64 + outputs_with_proof.unwrap().get_num_outputs() as u64 }; next_expected_version += num_transactions; @@ -1083,11 +1085,11 @@ async fn test_notifications_transaction_outputs_multiple_streams() { match data_notification.data_payload { DataPayload::TransactionOutputsWithProof(outputs_with_proof) => { // Verify the first transaction output version - let first_output_version = outputs_with_proof.first_transaction_output_version; + let first_output_version = outputs_with_proof.get_first_output_version(); assert_eq!(Some(next_expected_version), first_output_version); // Update the next expected version - next_expected_version += outputs_with_proof.transactions_and_outputs.len() as u64; + next_expected_version += outputs_with_proof.get_num_outputs() as u64; // Terminate the stream if we haven't reached the end if next_expected_version < MAX_ADVERTISED_TRANSACTION_OUTPUT { @@ -1196,11 +1198,12 @@ async fn test_notifications_transactions_multiple_streams() { match data_notification.data_payload { DataPayload::TransactionsWithProof(transactions_with_proof) => { // Verify the first transaction version - let first_transaction_version = transactions_with_proof.first_transaction_version; + let first_transaction_version = + transactions_with_proof.get_first_transaction_version(); assert_eq!(Some(next_expected_version), first_transaction_version); // Update the next expected version - next_expected_version += transactions_with_proof.transactions.len() as u64; + next_expected_version += transactions_with_proof.get_num_transactions() as u64; // Terminate the stream if we haven't reached the end if next_expected_version < MAX_ADVERTISED_TRANSACTION { @@ -1904,18 +1907,20 @@ fn verify_continuous_outputs_with_proof( expected_epoch: u64, expected_version: u64, ledger_info_with_sigs: LedgerInfoWithSignatures, - outputs_with_proofs: TransactionOutputListWithProof, + outputs_with_proofs: TransactionOutputListWithProofV2, ) -> (u64, u64) { // Verify the ledger info epoch matches the expected epoch let ledger_info = ledger_info_with_sigs.ledger_info(); assert_eq!(ledger_info.epoch(), expected_epoch); // Verify the output start version matches the expected version - let first_output_version = outputs_with_proofs.first_transaction_output_version; + let first_output_version = outputs_with_proofs.get_first_output_version(); assert_eq!(Some(expected_version), first_output_version); // Calculate the next expected version - let num_outputs = outputs_with_proofs.transactions_and_outputs.len() as u64; + let num_outputs = outputs_with_proofs + .get_output_list_with_proof() + .get_num_outputs() as u64; let next_expected_version = expected_version + num_outputs; // Update epochs if we've hit the epoch end @@ -1937,18 +1942,18 @@ fn verify_continuous_transactions_with_proof( expected_epoch: u64, expected_version: u64, ledger_info_with_sigs: LedgerInfoWithSignatures, - transactions_with_proofs: TransactionListWithProof, + transactions_with_proofs: TransactionListWithProofV2, ) -> (u64, u64) { // Verify the ledger info epoch matches the expected epoch let ledger_info = ledger_info_with_sigs.ledger_info(); assert_eq!(ledger_info.epoch(), expected_epoch); // Verify the transaction start version matches the expected version - let first_transaction_version = transactions_with_proofs.first_transaction_version; + let first_transaction_version = transactions_with_proofs.get_first_transaction_version(); assert_eq!(Some(expected_version), first_transaction_version); // Calculate the next expected version - let num_transactions = transactions_with_proofs.transactions.len() as u64; + let num_transactions = transactions_with_proofs.get_num_transactions() as u64; let next_expected_version = expected_version + num_transactions; // Update epochs if we've hit the epoch end @@ -1979,11 +1984,11 @@ async fn verify_output_notifications( match data_notification.data_payload { DataPayload::TransactionOutputsWithProof(outputs_with_proof) => { // Verify the transaction output start version matches the expected version - let first_output_version = outputs_with_proof.first_transaction_output_version; + let first_output_version = outputs_with_proof.get_first_output_version(); assert_eq!(Some(next_expected_version), first_output_version); // Calculate the next expected version - let num_outputs = outputs_with_proof.transactions_and_outputs.len(); + let num_outputs = outputs_with_proof.get_num_outputs(); next_expected_version += num_outputs as u64; }, DataPayload::EndOfStream => { @@ -2009,11 +2014,12 @@ async fn verify_transaction_notifications( match data_notification.data_payload { DataPayload::TransactionsWithProof(transactions_with_proof) => { // Verify the transaction start version matches the expected version - let first_transaction_version = transactions_with_proof.first_transaction_version; + let first_transaction_version = + transactions_with_proof.get_first_transaction_version(); assert_eq!(Some(next_expected_version), first_transaction_version); // Calculate the next expected version - let num_transactions = transactions_with_proof.transactions.len(); + let num_transactions = transactions_with_proof.get_num_transactions(); next_expected_version += num_transactions as u64; }, DataPayload::EndOfStream => { diff --git a/state-sync/data-streaming-service/src/tests/utils.rs b/state-sync/data-streaming-service/src/tests/utils.rs index 23e8f7d1285..7adb7adc58c 100644 --- a/state-sync/data-streaming-service/src/tests/utils.rs +++ b/state-sync/data-streaming-service/src/tests/utils.rs @@ -23,7 +23,7 @@ use aptos_storage_service_types::{ SubscriptionStreamMetadata, TransactionOutputsWithProofRequest, TransactionsOrOutputsWithProofRequest, TransactionsWithProofRequest, }, - responses::{CompleteDataRange, TransactionOrOutputListWithProof}, + responses::{CompleteDataRange, TransactionOrOutputListWithProofV2}, Epoch, }; use aptos_types::{ @@ -40,8 +40,9 @@ use aptos_types::{ }, transaction::{ RawTransaction, Script, SignedTransaction, Transaction, TransactionAuxiliaryData, - TransactionListWithProof, TransactionOutput, TransactionOutputListWithProof, - TransactionPayload, TransactionStatus, Version, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithProof, TransactionOutputListWithProofV2, TransactionPayload, + TransactionStatus, Version, }, write_set::WriteSet, }; @@ -56,7 +57,6 @@ use std::{ time::Duration, }; use tokio::time::timeout; - // TODO(joshlind): provide a better way to mock the data client. // Especially around verifying timeouts! @@ -369,7 +369,7 @@ impl AptosDataClientInterface for MockAptosDataClient { known_epoch: Epoch, request_timeout_ms: u64, ) -> Result< - Response<(TransactionOutputListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionOutputListWithProofV2, LedgerInfoWithSignatures)>, aptos_data_client::error::Error, > { // Verify the request timeout @@ -423,7 +423,7 @@ impl AptosDataClientInterface for MockAptosDataClient { include_events: bool, request_timeout_ms: u64, ) -> Result< - Response<(TransactionListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionListWithProofV2, LedgerInfoWithSignatures)>, aptos_data_client::error::Error, > { // Verify the request timeout @@ -479,7 +479,7 @@ impl AptosDataClientInterface for MockAptosDataClient { include_events: bool, request_timeout_ms: u64, ) -> aptos_data_client::error::Result< - Response<(TransactionOrOutputListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures)>, > { // Verify the request timeout let data_request = DataRequest::GetNewTransactionsOrOutputsWithProof( @@ -548,7 +548,7 @@ impl AptosDataClientInterface for MockAptosDataClient { start_version: Version, end_version: Version, request_timeout_ms: u64, - ) -> Result, aptos_data_client::error::Error> { + ) -> Result, aptos_data_client::error::Error> { // Verify the request timeout let data_request = DataRequest::GetTransactionOutputsWithProof(TransactionOutputsWithProofRequest { @@ -578,7 +578,7 @@ impl AptosDataClientInterface for MockAptosDataClient { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> Result, aptos_data_client::error::Error> { + ) -> Result, aptos_data_client::error::Error> { // Verify the request timeout let data_request = DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { proof_version, @@ -609,7 +609,7 @@ impl AptosDataClientInterface for MockAptosDataClient { end_version: Version, include_events: bool, request_timeout_ms: u64, - ) -> aptos_data_client::error::Result> { + ) -> aptos_data_client::error::Result> { // Verify the request timeout let data_request = DataRequest::GetTransactionsOrOutputsWithProof(TransactionsOrOutputsWithProofRequest { @@ -660,7 +660,7 @@ impl AptosDataClientInterface for MockAptosDataClient { subscription_request_metadata: SubscriptionRequestMetadata, request_timeout_ms: u64, ) -> aptos_data_client::error::Result< - Response<(TransactionOutputListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionOutputListWithProofV2, LedgerInfoWithSignatures)>, > { // Extract the known version, known epoch and the subscription stream index let known_version_at_stream_start = @@ -727,7 +727,7 @@ impl AptosDataClientInterface for MockAptosDataClient { include_events: bool, request_timeout_ms: u64, ) -> aptos_data_client::error::Result< - Response<(TransactionListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionListWithProofV2, LedgerInfoWithSignatures)>, > { // Extract the known version, known epoch and the subscription stream index let known_version_at_stream_start = @@ -795,7 +795,7 @@ impl AptosDataClientInterface for MockAptosDataClient { include_events: bool, request_timeout_ms: u64, ) -> aptos_data_client::error::Result< - Response<(TransactionOrOutputListWithProof, LedgerInfoWithSignatures)>, + Response<(TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures)>, > { // Extract the known version, known epoch and the subscription stream index let known_version_at_stream_start = @@ -1069,7 +1069,7 @@ pub fn create_transaction_list_with_proof( start_version: u64, end_version: u64, include_events: bool, -) -> TransactionListWithProof { +) -> TransactionListWithProofV2 { // Include events if required let events = if include_events { Some(vec![]) } else { None }; @@ -1085,27 +1085,35 @@ pub fn create_transaction_list_with_proof( transaction_list_with_proof.events = events; transaction_list_with_proof.transactions = transactions; - transaction_list_with_proof + TransactionListWithProofV2::new_from_v1(transaction_list_with_proof) } /// Creates an output list with proof for testing pub fn create_output_list_with_proof( start_version: u64, end_version: u64, -) -> TransactionOutputListWithProof { +) -> TransactionOutputListWithProofV2 { + // Create a transaction list with proof let transaction_list_with_proof = create_transaction_list_with_proof(start_version, end_version, false); + + // Create a transaction output list with proof let transactions_and_outputs = transaction_list_with_proof + .get_transaction_list_with_proof() .transactions .iter() .map(|txn| (txn.clone(), create_transaction_output())) .collect(); - - TransactionOutputListWithProof::new( + let output_list_with_proof = TransactionOutputListWithProof::new( transactions_and_outputs, Some(start_version), - transaction_list_with_proof.proof, - ) + transaction_list_with_proof + .get_transaction_list_with_proof() + .proof + .clone(), + ); + + TransactionOutputListWithProofV2::new_from_v1(output_list_with_proof) } /// Returns true iff the server should return transactions diff --git a/state-sync/inter-component/event-notifications/src/tests.rs b/state-sync/inter-component/event-notifications/src/tests.rs index 65f5c98904b..95c260e390c 100644 --- a/state-sync/inter-component/event-notifications/src/tests.rs +++ b/state-sync/inter-component/event-notifications/src/tests.rs @@ -19,14 +19,12 @@ use aptos_types::{ event::EventKey, ledger_info::set_waypoint_version, on_chain_config, - on_chain_config::OnChainConfig, transaction::{Transaction, Version, WriteSetPayload}, }; use aptos_vm::aptos_vm::AptosVMBlockExecutor; use claims::{assert_lt, assert_matches, assert_ok}; use futures::{FutureExt, StreamExt}; use move_core_types::language_storage::TypeTag; -use serde::{Deserialize, Serialize}; use std::{convert::TryInto, str::FromStr, sync::Arc}; #[test] @@ -418,17 +416,6 @@ fn test_event_v2_subscription_by_tag() { verify_no_event_notifications(vec![&mut listener_2]); } -/// Defines a new on-chain config for test purposes. -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Serialize)] -pub struct TestOnChainConfig { - pub some_value: u64, -} - -impl OnChainConfig for TestOnChainConfig { - const MODULE_IDENTIFIER: &'static str = "test_on_chain_config"; - const TYPE_IDENTIFIER: &'static str = "TestOnChainConfig"; -} - // Counts the number of event notifications received by the listener. Also ensures that // the notifications have increasing versions. fn count_event_notifications_and_ensure_ordering(listener: &mut EventNotificationListener) -> u64 { diff --git a/state-sync/state-sync-driver/src/bootstrapper.rs b/state-sync/state-sync-driver/src/bootstrapper.rs index 07555d77adc..0249e029fde 100644 --- a/state-sync/state-sync-driver/src/bootstrapper.rs +++ b/state-sync/state-sync-driver/src/bootstrapper.rs @@ -27,7 +27,7 @@ use aptos_types::{ epoch_state::EpochState, ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, validator_verifier::ValidatorVerifier, waypoint::Waypoint, }; @@ -293,7 +293,7 @@ pub(crate) struct StateValueSyncer { next_state_index_to_process: u64, // The transaction output (inc. info and proof) for the version we're syncing - transaction_output_to_sync: Option, + transaction_output_to_sync: Option, } impl StateValueSyncer { @@ -314,7 +314,7 @@ impl StateValueSyncer { /// Sets the transaction output to sync pub fn set_transaction_output_to_sync( &mut self, - transaction_output_to_sync: TransactionOutputListWithProof, + transaction_output_to_sync: TransactionOutputListWithProofV2, ) { self.transaction_output_to_sync = Some(transaction_output_to_sync); } @@ -672,7 +672,8 @@ impl< .await?; }, DataPayload::TransactionsWithProof(transactions_with_proof) => { - let payload_start_version = transactions_with_proof.first_transaction_version; + let payload_start_version = + transactions_with_proof.get_first_transaction_version(); let notification_metadata = NotificationMetadata::new( data_notification.creation_time, data_notification.notification_id, @@ -687,7 +688,7 @@ impl< }, DataPayload::TransactionOutputsWithProof(transaction_outputs_with_proof) => { let payload_start_version = - transaction_outputs_with_proof.first_transaction_output_version; + transaction_outputs_with_proof.get_first_output_version(); let notification_metadata = NotificationMetadata::new( data_notification.creation_time, data_notification.notification_id, @@ -1072,6 +1073,7 @@ impl< // Verify the chunk root hash matches the expected root hash let first_transaction_info = transaction_output_to_sync + .get_output_list_with_proof() .proof .transaction_infos .first() @@ -1191,8 +1193,8 @@ impl< async fn process_transaction_or_output_payload( &mut self, notification_metadata: NotificationMetadata, - transaction_list_with_proof: Option, - transaction_outputs_with_proof: Option, + transaction_list_with_proof: Option, + transaction_outputs_with_proof: Option, payload_start_version: Option, ) -> Result<(), Error> { // Verify that we're expecting transaction or output payloads @@ -1343,7 +1345,7 @@ impl< async fn verify_transaction_info_to_sync( &mut self, notification_id: NotificationId, - transaction_outputs_with_proof: Option, + transaction_outputs_with_proof: Option, payload_start_version: Option, ) -> Result<(), Error> { // Verify the payload starting version @@ -1360,7 +1362,13 @@ impl< // Verify the payload proof (the ledger info has already been verified) // and save the transaction output with proof. if let Some(transaction_outputs_with_proof) = transaction_outputs_with_proof { - if transaction_outputs_with_proof.proof.transaction_infos.len() == 1 { + if transaction_outputs_with_proof + .get_output_list_with_proof() + .proof + .transaction_infos + .len() + == 1 + { match transaction_outputs_with_proof.verify( ledger_info_to_sync.ledger_info(), Some(expected_start_version), @@ -1445,16 +1453,14 @@ impl< &mut self, notification_id: NotificationId, payload_start_version: Version, - transaction_list_with_proof: Option<&TransactionListWithProof>, - transaction_outputs_with_proof: Option<&TransactionOutputListWithProof>, + transaction_list_with_proof: Option<&TransactionListWithProofV2>, + transaction_outputs_with_proof: Option<&TransactionOutputListWithProofV2>, ) -> Result, Error> { // Calculate the payload end version let num_versions = match self.get_bootstrapping_mode() { BootstrappingMode::ApplyTransactionOutputsFromGenesis => { if let Some(transaction_outputs_with_proof) = transaction_outputs_with_proof { - transaction_outputs_with_proof - .transactions_and_outputs - .len() + transaction_outputs_with_proof.get_num_outputs() } else { self.reset_active_stream(Some(NotificationAndFeedback::new( notification_id, @@ -1468,7 +1474,7 @@ impl< }, BootstrappingMode::ExecuteTransactionsFromGenesis => { if let Some(transaction_list_with_proof) = transaction_list_with_proof { - transaction_list_with_proof.transactions.len() + transaction_list_with_proof.get_num_transactions() } else { self.reset_active_stream(Some(NotificationAndFeedback::new( notification_id, @@ -1482,9 +1488,9 @@ impl< }, BootstrappingMode::ExecuteOrApplyFromGenesis => { if let Some(transaction_list_with_proof) = transaction_list_with_proof { - transaction_list_with_proof.transactions.len() + transaction_list_with_proof.get_num_transactions() } else if let Some(output_list_with_proof) = transaction_outputs_with_proof { - output_list_with_proof.transactions_and_outputs.len() + output_list_with_proof.get_num_outputs() } else { self.reset_active_stream(Some(NotificationAndFeedback::new( notification_id, @@ -1574,7 +1580,9 @@ impl< } /// Returns the transaction output to sync - fn get_transaction_output_to_sync(&mut self) -> Result { + fn get_transaction_output_to_sync( + &mut self, + ) -> Result { self.state_value_syncer .transaction_output_to_sync .clone() diff --git a/state-sync/state-sync-driver/src/continuous_syncer.rs b/state-sync/state-sync-driver/src/continuous_syncer.rs index 84727902d2a..491b20e457f 100644 --- a/state-sync/state-sync-driver/src/continuous_syncer.rs +++ b/state-sync/state-sync-driver/src/continuous_syncer.rs @@ -23,7 +23,7 @@ use aptos_logger::{prelude::*, sample, sample::SampleRate}; use aptos_storage_interface::DbReader; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, }; use std::{sync::Arc, time::Duration}; @@ -213,7 +213,7 @@ impl< transaction_outputs_with_proof, ) => { let payload_start_version = - transaction_outputs_with_proof.first_transaction_output_version; + transaction_outputs_with_proof.get_first_output_version(); let notification_metadata = NotificationMetadata::new( data_notification.creation_time, data_notification.notification_id, @@ -232,7 +232,8 @@ impl< ledger_info_with_sigs, transactions_with_proof, ) => { - let payload_start_version = transactions_with_proof.first_transaction_version; + let payload_start_version = + transactions_with_proof.get_first_transaction_version(); let notification_metadata = NotificationMetadata::new( data_notification.creation_time, data_notification.notification_id, @@ -277,8 +278,8 @@ impl< consensus_sync_request: Arc>>, notification_metadata: NotificationMetadata, ledger_info_with_signatures: LedgerInfoWithSignatures, - transaction_list_with_proof: Option, - transaction_outputs_with_proof: Option, + transaction_list_with_proof: Option, + transaction_outputs_with_proof: Option, payload_start_version: Option, ) -> Result<(), Error> { // Verify the payload starting version diff --git a/state-sync/state-sync-driver/src/driver.rs b/state-sync/state-sync-driver/src/driver.rs index fb7dcc56ad5..0f82c9decf1 100644 --- a/state-sync/state-sync-driver/src/driver.rs +++ b/state-sync/state-sync-driver/src/driver.rs @@ -409,12 +409,21 @@ impl< &mut self, sync_target_notification: ConsensusSyncTargetNotification, ) -> Result<(), Error> { - // Update the sync target notification metrics - let latest_synced_version = utils::fetch_pre_committed_version(self.storage.clone())?; + // Fetch the pre-committed and committed versions + let latest_pre_committed_version = + utils::fetch_pre_committed_version(self.storage.clone())?; + let latest_synced_ledger_info = + utils::fetch_latest_synced_ledger_info(self.storage.clone())?; + let latest_committed_version = latest_synced_ledger_info.ledger_info().version(); + + // Update the sync target notification logs and metrics info!( LogSchema::new(LogEntry::ConsensusNotification).message(&format!( - "Received a consensus sync target notification! Target version: {:?}. Latest synced version: {:?}", - sync_target_notification.get_target(), latest_synced_version, + "Received a consensus sync target notification! Target: {:?}. \ + Latest pre-committed version: {}. Latest committed version: {}.", + sync_target_notification.get_target(), + latest_pre_committed_version, + latest_committed_version, )) ); metrics::increment_counter( @@ -423,10 +432,12 @@ impl< ); // Initialize a new sync request - let latest_synced_ledger_info = - utils::fetch_latest_synced_ledger_info(self.storage.clone())?; self.consensus_notification_handler - .initialize_sync_target_request(sync_target_notification, latest_synced_ledger_info) + .initialize_sync_target_request( + sync_target_notification, + latest_pre_committed_version, + latest_synced_ledger_info, + ) .await } diff --git a/state-sync/state-sync-driver/src/driver_client.rs b/state-sync/state-sync-driver/src/driver_client.rs index 1b557addcda..8eb9644ee25 100644 --- a/state-sync/state-sync-driver/src/driver_client.rs +++ b/state-sync/state-sync-driver/src/driver_client.rs @@ -32,7 +32,7 @@ impl DriverClient { } /// Notifies the caller once the driver has successfully bootstrapped the node - pub fn notify_once_bootstrapped(&self) -> impl Future> { + pub fn notify_once_bootstrapped(&self) -> impl Future> + use<> { let mut notification_sender = self.notification_sender.clone(); let (callback_sender, callback_receiver) = oneshot::channel(); diff --git a/state-sync/state-sync-driver/src/error.rs b/state-sync/state-sync-driver/src/error.rs index 1fea61da8cb..c2e7c143f11 100644 --- a/state-sync/state-sync-driver/src/error.rs +++ b/state-sync/state-sync-driver/src/error.rs @@ -29,12 +29,16 @@ pub enum Error { IntegerOverflow(String), #[error("An invalid payload was received: {0}")] InvalidPayload(String), + #[error( + "Received an invalid sync request for version: {0}, but the pre-committed version is: {1}" + )] + InvalidSyncRequest(Version, Version), #[error("Failed to notify mempool of the new commit: {0}")] NotifyMempoolError(String), #[error("Failed to notify the storage service of the new commit: {0}")] NotifyStorageServiceError(String), - #[error("Received an old sync request for version {0}, but our committed version is: {1}")] - OldSyncRequest(Version, Version), + #[error("Received an old sync request for version {0}, but our pre-committed version is: {1} and committed version: {2}")] + OldSyncRequest(Version, Version, Version), #[error("Received oneshot::canceled. The sender of a channel was dropped: {0}")] SenderDroppedError(String), #[error("Unexpected storage error: {0}")] @@ -62,10 +66,11 @@ impl Error { Error::EventNotificationError(_) => "event_notification_error", Error::FullNodeConsensusNotification(_) => "full_node_consensus_notification", Error::IntegerOverflow(_) => "integer_overflow", + Error::InvalidSyncRequest(_, _) => "invalid_sync_request", Error::InvalidPayload(_) => "invalid_payload", Error::NotifyMempoolError(_) => "notify_mempool_error", Error::NotifyStorageServiceError(_) => "notify_storage_service_error", - Error::OldSyncRequest(_, _) => "old_sync_request", + Error::OldSyncRequest(_, _, _) => "old_sync_request", Error::SenderDroppedError(_) => "sender_dropped_error", Error::StorageError(_) => "storage_error", Error::SyncedBeyondTarget(_, _) => "synced_beyond_target", diff --git a/state-sync/state-sync-driver/src/notification_handlers.rs b/state-sync/state-sync-driver/src/notification_handlers.rs index ab80d673691..8b168474be1 100644 --- a/state-sync/state-sync-driver/src/notification_handlers.rs +++ b/state-sync/state-sync-driver/src/notification_handlers.rs @@ -263,9 +263,10 @@ impl ConsensusNotificationHandler { pub async fn initialize_sync_target_request( &mut self, sync_target_notification: ConsensusSyncTargetNotification, + latest_pre_committed_version: Version, latest_synced_ledger_info: LedgerInfoWithSignatures, ) -> Result<(), Error> { - // Get the latest committed version and the target sync version + // Get the target sync version and latest committed version let sync_target_version = sync_target_notification .get_target() .ledger_info() @@ -273,24 +274,42 @@ impl ConsensusNotificationHandler { let latest_committed_version = latest_synced_ledger_info.ledger_info().version(); // If the target version is old, return an error to consensus (something is wrong!) - if sync_target_version < latest_committed_version { + if sync_target_version < latest_committed_version + || sync_target_version < latest_pre_committed_version + { let error = Err(Error::OldSyncRequest( sync_target_version, + latest_pre_committed_version, latest_committed_version, )); self.respond_to_sync_target_notification(sync_target_notification, error.clone())?; return error; } - // If we're now at the target, return successfully + // If the committed version is at the target, return successfully if sync_target_version == latest_committed_version { - info!(LogSchema::new(LogEntry::NotificationHandler) - .message("We're already at the requested sync target version! Returning early")); + info!( + LogSchema::new(LogEntry::NotificationHandler).message(&format!( + "We're already at the requested sync target version: {} \ + (pre-committed version: {}, committed version: {})!", + sync_target_version, latest_pre_committed_version, latest_committed_version + )) + ); let result = Ok(()); self.respond_to_sync_target_notification(sync_target_notification, result.clone())?; return result; } + // If the pre-committed version is already at the target, something has else gone wrong + if sync_target_version == latest_pre_committed_version { + let error = Err(Error::InvalidSyncRequest( + sync_target_version, + latest_pre_committed_version, + )); + self.respond_to_sync_target_notification(sync_target_notification, error.clone())?; + return error; + } + // Save the request so we can notify consensus once we've hit the target let consensus_sync_request = ConsensusSyncRequest::new_with_target(sync_target_notification); diff --git a/state-sync/state-sync-driver/src/storage_synchronizer.rs b/state-sync/state-sync-driver/src/storage_synchronizer.rs index 820c8b8055f..b3977451ba2 100644 --- a/state-sync/state-sync-driver/src/storage_synchronizer.rs +++ b/state-sync/state-sync-driver/src/storage_synchronizer.rs @@ -30,8 +30,8 @@ use aptos_types::{ state_value::{StateValue, StateValueChunkWithProof}, }, transaction::{ - Transaction, TransactionListWithProof, TransactionOutput, TransactionOutputListWithProof, - Version, + Transaction, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithProofV2, Version, }, }; use async_trait::async_trait; @@ -59,7 +59,7 @@ pub trait StorageSynchronizerInterface { async fn apply_transaction_outputs( &mut self, notification_metadata: NotificationMetadata, - output_list_with_proof: TransactionOutputListWithProof, + output_list_with_proof: TransactionOutputListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> Result<(), Error>; @@ -70,7 +70,7 @@ pub trait StorageSynchronizerInterface { async fn execute_transactions( &mut self, notification_metadata: NotificationMetadata, - transaction_list_with_proof: TransactionListWithProof, + transaction_list_with_proof: TransactionListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> Result<(), Error>; @@ -85,7 +85,7 @@ pub trait StorageSynchronizerInterface { &mut self, epoch_change_proofs: Vec, target_ledger_info: LedgerInfoWithSignatures, - target_output_with_proof: TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, ) -> Result, Error>; /// Returns true iff there is storage data that is still waiting @@ -331,7 +331,7 @@ impl< async fn apply_transaction_outputs( &mut self, notification_metadata: NotificationMetadata, - output_list_with_proof: TransactionOutputListWithProof, + output_list_with_proof: TransactionOutputListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> Result<(), Error> { @@ -355,7 +355,7 @@ impl< async fn execute_transactions( &mut self, notification_metadata: NotificationMetadata, - transaction_list_with_proof: TransactionListWithProof, + transaction_list_with_proof: TransactionListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> Result<(), Error> { @@ -380,7 +380,7 @@ impl< &mut self, epoch_change_proofs: Vec, target_ledger_info: LedgerInfoWithSignatures, - target_output_with_proof: TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, ) -> Result, Error> { // Create a channel to notify the state snapshot receiver when data chunks are ready let max_pending_data_chunks = self.driver_config.max_pending_data_chunks as usize; @@ -471,13 +471,13 @@ enum StorageDataChunk { States(NotificationId, StateValueChunkWithProof), Transactions( NotificationMetadata, - TransactionListWithProof, + TransactionListWithProofV2, LedgerInfoWithSignatures, Option, ), TransactionOutputs( NotificationMetadata, - TransactionOutputListWithProof, + TransactionOutputListWithProofV2, LedgerInfoWithSignatures, Option, ), @@ -838,7 +838,7 @@ fn spawn_state_snapshot_receiver< storage: DbReaderWriter, epoch_change_proofs: Vec, target_ledger_info: LedgerInfoWithSignatures, - target_output_with_proof: TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, runtime: Option, ) -> JoinHandle<()> { // Create a state snapshot receiver @@ -846,6 +846,7 @@ fn spawn_state_snapshot_receiver< // Get the target version and expected root hash let version = target_ledger_info.ledger_info().version(); let expected_root_hash = target_output_with_proof + .get_output_list_with_proof() .proof .transaction_infos .first() @@ -985,12 +986,12 @@ fn spawn_state_snapshot_receiver< /// block the async thread. async fn apply_output_chunk( chunk_executor: Arc, - outputs_with_proof: TransactionOutputListWithProof, + outputs_with_proof: TransactionOutputListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> anyhow::Result<()> { // Apply the output chunk - let num_outputs = outputs_with_proof.transactions_and_outputs.len(); + let num_outputs = outputs_with_proof.get_num_outputs(); let result = tokio::task::spawn_blocking(move || { chunk_executor.enqueue_chunk_by_transaction_outputs( outputs_with_proof, @@ -1025,12 +1026,15 @@ async fn apply_output_chunk( /// doesn't block the async thread. async fn execute_transaction_chunk( chunk_executor: Arc, - transactions_with_proof: TransactionListWithProof, + transactions_with_proof: TransactionListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> anyhow::Result<()> { // Execute the transaction chunk - let num_transactions = transactions_with_proof.transactions.len(); + let num_transactions = transactions_with_proof + .get_transaction_list_with_proof() + .transactions + .len(); let result = tokio::task::spawn_blocking(move || { chunk_executor.enqueue_chunk_by_execution( transactions_with_proof, @@ -1111,7 +1115,7 @@ async fn finalize_storage_and_send_commit< >, storage: DbReaderWriter, epoch_change_proofs: &[LedgerInfoWithSignatures], - target_output_with_proof: TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, version: Version, target_ledger_info: &LedgerInfoWithSignatures, last_committed_state_index: u64, @@ -1153,7 +1157,7 @@ async fn finalize_storage_and_send_commit< // Create and send the commit notification let commit_notification = create_commit_notification( - &target_output_with_proof, + target_output_with_proof, last_committed_state_index, version, ); @@ -1180,14 +1184,14 @@ async fn finalize_storage_and_send_commit< /// Creates a commit notification for the new committed state snapshot fn create_commit_notification( - target_output_with_proof: &TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, last_committed_state_index: u64, version: u64, ) -> CommitNotification { let (transactions, outputs): (Vec, Vec) = target_output_with_proof + .consume_output_list_with_proof() .transactions_and_outputs - .clone() .into_iter() .unzip(); let events = outputs diff --git a/state-sync/state-sync-driver/src/tests/bootstrapper.rs b/state-sync/state-sync-driver/src/tests/bootstrapper.rs index d8c7c60fc12..192bdd26d0a 100644 --- a/state-sync/state-sync-driver/src/tests/bootstrapper.rs +++ b/state-sync/state-sync-driver/src/tests/bootstrapper.rs @@ -29,7 +29,7 @@ use aptos_data_streaming_service::{ }; use aptos_time_service::TimeService; use aptos_types::{ - transaction::{TransactionOutputListWithProof, Version}, + transaction::{TransactionOutputListWithProofV2, Version}, waypoint::Waypoint, }; use claims::{assert_matches, assert_none, assert_ok}; @@ -546,7 +546,7 @@ async fn test_data_stream_transaction_outputs() { // Send an invalid output along the stream let data_notification = DataNotification::new( notification_id, - DataPayload::TransactionOutputsWithProof(TransactionOutputListWithProof::new_empty()), + DataPayload::TransactionOutputsWithProof(TransactionOutputListWithProofV2::new_empty()), ); notification_sender_1.send(data_notification).await.unwrap(); diff --git a/state-sync/state-sync-driver/src/tests/continuous_syncer.rs b/state-sync/state-sync-driver/src/tests/continuous_syncer.rs index 5bd5a93cbf0..26f82fe3d71 100644 --- a/state-sync/state-sync-driver/src/tests/continuous_syncer.rs +++ b/state-sync/state-sync-driver/src/tests/continuous_syncer.rs @@ -29,7 +29,9 @@ use aptos_data_streaming_service::{ use aptos_infallible::Mutex; use aptos_storage_service_types::Epoch; use aptos_time_service::TimeService; -use aptos_types::transaction::{TransactionOutputListWithProof, Version}; +use aptos_types::transaction::{ + TransactionOutputListWithProof, TransactionOutputListWithProofV2, Version, +}; use claims::assert_matches; use futures::SinkExt; use mockall::{predicate::eq, Sequence}; @@ -181,7 +183,7 @@ async fn test_data_stream_transactions_with_sync_duration() { notification_id, DataPayload::ContinuousTransactionOutputsWithProof( create_epoch_ending_ledger_info(), - TransactionOutputListWithProof::new_empty(), + TransactionOutputListWithProofV2::new_empty(), ), ); notification_sender_1.send(data_notification).await.unwrap(); @@ -262,7 +264,7 @@ async fn test_data_stream_transactions_with_sync_target() { notification_id, DataPayload::ContinuousTransactionOutputsWithProof( create_epoch_ending_ledger_info(), - TransactionOutputListWithProof::new_empty(), + TransactionOutputListWithProofV2::new_empty(), ), ); notification_sender_1.send(data_notification).await.unwrap(); @@ -341,7 +343,7 @@ async fn test_data_stream_transaction_outputs() { notification_id, DataPayload::ContinuousTransactionOutputsWithProof( create_epoch_ending_ledger_info(), - transaction_output_with_proof, + TransactionOutputListWithProofV2::new_from_v1(transaction_output_with_proof), ), ); notification_sender_1.send(data_notification).await.unwrap(); @@ -423,7 +425,7 @@ async fn test_data_stream_transactions_or_outputs_with_sync_duration() { notification_id, DataPayload::ContinuousTransactionOutputsWithProof( create_epoch_ending_ledger_info(), - TransactionOutputListWithProof::new_empty(), + TransactionOutputListWithProofV2::new_empty(), ), ); notification_sender_1.send(data_notification).await.unwrap(); @@ -504,7 +506,7 @@ async fn test_data_stream_transactions_or_outputs_with_sync_target() { notification_id, DataPayload::ContinuousTransactionOutputsWithProof( create_epoch_ending_ledger_info(), - TransactionOutputListWithProof::new_empty(), + TransactionOutputListWithProofV2::new_empty(), ), ); notification_sender_1.send(data_notification).await.unwrap(); diff --git a/state-sync/state-sync-driver/src/tests/mocks.rs b/state-sync/state-sync-driver/src/tests/mocks.rs index c8ba342e129..b63d66db4d3 100644 --- a/state-sync/state-sync-driver/src/tests/mocks.rs +++ b/state-sync/state-sync-driver/src/tests/mocks.rs @@ -36,8 +36,8 @@ use aptos_types::{ state_value::{StateValue, StateValueChunkWithProof}, }, transaction::{ - AccountOrderedTransactionsWithProof, TransactionListWithProof, - TransactionOutputListWithProof, TransactionWithProof, Version, + AccountOrderedTransactionsWithProof, TransactionListWithProofV2, + TransactionOutputListWithProofV2, TransactionWithProof, Version, }, }; use async_trait::async_trait; @@ -139,28 +139,28 @@ mock! { impl ChunkExecutorTrait for ChunkExecutor { fn execute_chunk<'a>( &self, - txn_list_with_proof: TransactionListWithProof, + txn_list_with_proof: TransactionListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&'a LedgerInfoWithSignatures>, ) -> AnyhowResult<()>; fn apply_chunk<'a>( &self, - txn_output_list_with_proof: TransactionOutputListWithProof, + txn_output_list_with_proof: TransactionOutputListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&'a LedgerInfoWithSignatures>, ) -> AnyhowResult<()>; fn enqueue_chunk_by_execution<'a>( &self, - txn_list_with_proof: TransactionListWithProof, + txn_list_with_proof: TransactionListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&'a LedgerInfoWithSignatures>, ) -> AnyhowResult<()>; fn enqueue_chunk_by_transaction_outputs<'a>( &self, - txn_output_list_with_proof: TransactionOutputListWithProof, + txn_output_list_with_proof: TransactionOutputListWithProofV2, verified_target_li: &LedgerInfoWithSignatures, epoch_change_li: Option<&'a LedgerInfoWithSignatures>, ) -> AnyhowResult<()>; @@ -191,7 +191,7 @@ mock! { batch_size: u64, ledger_version: Version, fetch_events: bool, - ) -> Result; + ) -> Result; fn get_transaction_by_hash( &self, @@ -212,7 +212,7 @@ mock! { start_version: Version, limit: u64, ledger_version: Version, - ) -> Result; + ) -> Result; fn get_events( &self, @@ -319,7 +319,7 @@ mock! { fn finalize_state_snapshot( &self, version: Version, - output_with_proof: TransactionOutputListWithProof, + output_with_proof: TransactionOutputListWithProofV2, ledger_infos: &[LedgerInfoWithSignatures], ) -> Result<()>; @@ -454,7 +454,7 @@ mock! { async fn apply_transaction_outputs( &mut self, notification_metadata: NotificationMetadata, - output_list_with_proof: TransactionOutputListWithProof, + output_list_with_proof: TransactionOutputListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> AnyhowResult<(), crate::error::Error>; @@ -462,7 +462,7 @@ mock! { async fn execute_transactions( &mut self, notification_metadata: NotificationMetadata, - transaction_list_with_proof: TransactionListWithProof, + transaction_list_with_proof: TransactionListWithProofV2, target_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, ) -> AnyhowResult<(), crate::error::Error>; @@ -471,7 +471,7 @@ mock! { &mut self, epoch_change_proofs: Vec, target_ledger_info: LedgerInfoWithSignatures, - target_output_with_proof: TransactionOutputListWithProof, + target_output_with_proof: TransactionOutputListWithProofV2, ) -> AnyhowResult, crate::error::Error>; fn pending_storage_data(&self) -> bool; diff --git a/state-sync/state-sync-driver/src/tests/storage_synchronizer.rs b/state-sync/state-sync-driver/src/tests/storage_synchronizer.rs index c4b5ecfc82f..682ebb7eaef 100644 --- a/state-sync/state-sync-driver/src/tests/storage_synchronizer.rs +++ b/state-sync/state-sync-driver/src/tests/storage_synchronizer.rs @@ -35,7 +35,7 @@ use aptos_storage_interface::{AptosDbError, DbReaderWriter}; use aptos_storage_service_notifications::StorageServiceNotificationListener; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, - transaction::{TransactionOutputListWithProof, Version}, + transaction::{TransactionOutputListWithProofV2, Version}, }; use claims::assert_matches; use futures::StreamExt; @@ -626,8 +626,11 @@ async fn test_execute_transactions_commit_send_error() { #[should_panic] async fn test_initialize_state_synchronizer_missing_info() { // Create test data that is missing transaction infos - let mut output_list_with_proof = create_output_list_with_proof(); + let mut output_list_with_proof = + create_output_list_with_proof().consume_output_list_with_proof(); output_list_with_proof.proof.transaction_infos = vec![]; // This is invalid! + let output_list_with_proof = + TransactionOutputListWithProofV2::new_from_v1(output_list_with_proof); // Create the storage synchronizer let (_, _, _, _, _, mut storage_synchronizer, _) = create_storage_synchronizer( @@ -716,7 +719,7 @@ async fn test_save_states_completion() { .expect_finalize_state_snapshot() .withf( move |version: &Version, - output_with_proof: &TransactionOutputListWithProof, + output_with_proof: &TransactionOutputListWithProofV2, ledger_infos: &[LedgerInfoWithSignatures]| { version == &target_ledger_info_clone.ledger_info().version() && output_with_proof == &output_list_with_proof_clone @@ -733,7 +736,9 @@ async fn test_save_states_completion() { ); // Subscribe to the expected event - let expected_event = output_list_with_proof.transactions_and_outputs[0] + let expected_event = output_list_with_proof + .get_output_list_with_proof() + .transactions_and_outputs[0] .1 .events()[0] .clone(); @@ -758,7 +763,11 @@ async fn test_save_states_completion() { .unwrap(); // Verify we get a commit notification - let expected_transaction = output_list_with_proof.transactions_and_outputs[0].0.clone(); + let expected_transaction = output_list_with_proof + .get_output_list_with_proof() + .transactions_and_outputs[0] + .0 + .clone(); let expected_committed_transactions = CommittedTransactions { events: vec![expected_event.clone()], transactions: vec![expected_transaction.clone()], diff --git a/state-sync/state-sync-driver/src/tests/utils.rs b/state-sync/state-sync-driver/src/tests/utils.rs index 3566925b225..72e16afaf72 100644 --- a/state-sync/state-sync-driver/src/tests/utils.rs +++ b/state-sync/state-sync-driver/src/tests/utils.rs @@ -34,8 +34,9 @@ use aptos_types::{ transaction::{ use_case::UseCaseAwareTransaction, ExecutionStatus, RawTransaction, ReplayProtector, Script, SignedTransaction, Transaction, TransactionAuxiliaryData, TransactionInfo, - TransactionListWithProof, TransactionOutput, TransactionOutputListWithProof, - TransactionPayload, TransactionStatus, Version, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithProof, TransactionOutputListWithProofV2, TransactionPayload, + TransactionStatus, Version, }, validator_verifier::ValidatorVerifier, waypoint::Waypoint, @@ -145,14 +146,14 @@ pub fn create_ledger_info_at_version(version: Version) -> LedgerInfoWithSignatur } /// Creates a test transaction output list with proof -pub fn create_output_list_with_proof() -> TransactionOutputListWithProof { +pub fn create_output_list_with_proof() -> TransactionOutputListWithProofV2 { let transaction_info_list_with_proof = create_transaction_info_list_with_proof(); let transaction_and_output = (create_transaction(), create_transaction_output()); - TransactionOutputListWithProof::new( + TransactionOutputListWithProofV2::new_from_v1(TransactionOutputListWithProof::new( vec![transaction_and_output], Some(0), transaction_info_list_with_proof, - ) + )) } /// Creates a random epoch ending ledger info with the specified values @@ -189,7 +190,7 @@ pub fn create_epoch_state(epoch: u64) -> EpochState { /// Returns a random u64 pub fn create_random_u64() -> u64 { let mut rng = OsRng; - rng.gen() + rng.r#gen() } /// Creates a test state value chunk with proof @@ -243,6 +244,7 @@ pub fn create_transaction_info() -> TransactionInfo { Some(HashValue::random()), 0, ExecutionStatus::Success, + Some(HashValue::random()), ) } @@ -254,14 +256,14 @@ pub fn create_transaction_info_list_with_proof() -> TransactionInfoListWithProof } /// Creates a test transaction list with proof -pub fn create_transaction_list_with_proof() -> TransactionListWithProof { +pub fn create_transaction_list_with_proof() -> TransactionListWithProofV2 { let transaction_info_list_with_proof = create_transaction_info_list_with_proof(); - TransactionListWithProof::new( + TransactionListWithProofV2::new_from_v1(TransactionListWithProof::new( vec![create_transaction()], None, Some(0), transaction_info_list_with_proof, - ) + )) } /// Creates a single test transaction output diff --git a/state-sync/state-sync-driver/src/utils.rs b/state-sync/state-sync-driver/src/utils.rs index fa64ceccf38..18acdebea2c 100644 --- a/state-sync/state-sync-driver/src/utils.rs +++ b/state-sync/state-sync-driver/src/utils.rs @@ -29,7 +29,7 @@ use aptos_types::{ epoch_change::Verifier, epoch_state::EpochState, ledger_info::LedgerInfoWithSignatures, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2, Version}, }; use futures::StreamExt; use std::{ @@ -434,9 +434,9 @@ pub async fn execute_transactions( notification_metadata: NotificationMetadata, proof_ledger_info: LedgerInfoWithSignatures, end_of_epoch_ledger_info: Option, - transaction_list_with_proof: TransactionListWithProof, + transaction_list_with_proof: TransactionListWithProofV2, ) -> Result { - let num_transactions = transaction_list_with_proof.transactions.len(); + let num_transactions = transaction_list_with_proof.get_num_transactions(); storage_synchronizer .execute_transactions( notification_metadata, @@ -455,11 +455,9 @@ pub async fn apply_transaction_outputs, - transaction_outputs_with_proof: TransactionOutputListWithProof, + transaction_outputs_with_proof: TransactionOutputListWithProofV2, ) -> Result { - let num_transaction_outputs = transaction_outputs_with_proof - .transactions_and_outputs - .len(); + let num_transaction_outputs = transaction_outputs_with_proof.get_num_outputs(); storage_synchronizer .apply_transaction_outputs( notification_metadata, diff --git a/state-sync/storage-service/server/Cargo.toml b/state-sync/storage-service/server/Cargo.toml index a3f95458ddc..112fc663c4b 100644 --- a/state-sync/storage-service/server/Cargo.toml +++ b/state-sync/storage-service/server/Cargo.toml @@ -30,6 +30,7 @@ bcs = { workspace = true } bytes = { workspace = true } dashmap = { workspace = true } futures = { workspace = true } +itertools = { workspace = true } mini-moka = { workspace = true } once_cell = { workspace = true } serde = { workspace = true } @@ -44,7 +45,7 @@ aptos-crypto = { workspace = true } aptos-netcore = { workspace = true } aptos-storage-interface = { workspace = true } aptos-time-service = { workspace = true, features = ["async", "testing"] } -aptos-types = { workspace = true } +aptos-types = { workspace = true, features = ["testing"] } claims = { workspace = true } maplit = { workspace = true } mockall = { workspace = true } diff --git a/state-sync/storage-service/server/src/handler.rs b/state-sync/storage-service/server/src/handler.rs index fc642e212de..a6d8b3f9af1 100644 --- a/state-sync/storage-service/server/src/handler.rs +++ b/state-sync/storage-service/server/src/handler.rs @@ -21,8 +21,8 @@ use aptos_logger::{debug, sample, sample::SampleRate, trace, warn}; use aptos_network::protocols::wire::handshake::v1::ProtocolId; use aptos_storage_service_types::{ requests::{ - DataRequest, EpochEndingLedgerInfoRequest, StateValuesWithProofRequest, - StorageServiceRequest, TransactionOutputsWithProofRequest, + DataRequest, EpochEndingLedgerInfoRequest, GetTransactionDataWithProofRequest, + StateValuesWithProofRequest, StorageServiceRequest, TransactionOutputsWithProofRequest, TransactionsOrOutputsWithProofRequest, TransactionsWithProofRequest, }, responses::{ @@ -102,6 +102,20 @@ impl Handler { request.get_label(), ); + // If the request is for transaction v2 data, only process it + // if the server supports it. Otherwise, drop the request. + if request.data_request.is_transaction_data_v2_request() + && !storage_service_config.enable_transaction_data_v2 + { + warn!(LogSchema::new(LogEntry::StorageServiceError) + .error(&Error::InvalidRequest(format!( + "Received a v2 data request ({}), which is not supported!", + request.get_label() + ))) + .peer_network_id(&peer_network_id)); + return; + } + // Handle any optimistic fetch requests if request.data_request.is_optimistic_fetch() { self.handle_optimistic_fetch_request(peer_network_id, request, response_sender); @@ -409,6 +423,9 @@ impl Handler { DataRequest::GetTransactionsOrOutputsWithProof(request) => { self.get_transactions_or_outputs_with_proof(request) }, + DataRequest::GetTransactionDataWithProof(request) => { + self.get_transaction_data_with_proof(request) + }, _ => Err(Error::UnexpectedErrorEncountered(format!( "Received an unexpected request: {:?}", request @@ -494,14 +511,17 @@ impl Handler { &self, request: &TransactionOutputsWithProofRequest, ) -> aptos_storage_service_types::Result { - let transaction_output_list_with_proof = self.storage.get_transaction_outputs_with_proof( + let response = self.storage.get_transaction_outputs_with_proof( request.proof_version, request.start_version, request.end_version, )?; Ok(DataResponse::TransactionOutputsWithProof( - transaction_output_list_with_proof, + response + .transaction_output_list_with_proof + .unwrap() + .consume_output_list_with_proof(), )) } @@ -509,34 +529,52 @@ impl Handler { &self, request: &TransactionsWithProofRequest, ) -> aptos_storage_service_types::Result { - let transactions_with_proof = self.storage.get_transactions_with_proof( + let response = self.storage.get_transactions_with_proof( request.proof_version, request.start_version, request.end_version, request.include_events, )?; - Ok(DataResponse::TransactionsWithProof(transactions_with_proof)) + Ok(DataResponse::TransactionsWithProof( + response + .transaction_list_with_proof + .unwrap() + .consume_transaction_list_with_proof(), + )) } fn get_transactions_or_outputs_with_proof( &self, request: &TransactionsOrOutputsWithProofRequest, ) -> aptos_storage_service_types::Result { - let (transactions_with_proof, outputs_with_proof) = - self.storage.get_transactions_or_outputs_with_proof( - request.proof_version, - request.start_version, - request.end_version, - request.include_events, - request.max_num_output_reductions, - )?; + let response = self.storage.get_transactions_or_outputs_with_proof( + request.proof_version, + request.start_version, + request.end_version, + request.include_events, + request.max_num_output_reductions, + )?; Ok(DataResponse::TransactionsOrOutputsWithProof(( - transactions_with_proof, - outputs_with_proof, + response + .transaction_list_with_proof + .map(|t| t.consume_transaction_list_with_proof()), + response + .transaction_output_list_with_proof + .map(|t| t.consume_output_list_with_proof()), ))) } + + fn get_transaction_data_with_proof( + &self, + request: &GetTransactionDataWithProofRequest, + ) -> aptos_storage_service_types::Result { + let transaction_data_with_proof = self.storage.get_transaction_data_with_proof(request)?; + Ok(DataResponse::TransactionDataWithProof( + transaction_data_with_proof, + )) + } } /// Updates the subscription metrics with a created subscription stream event diff --git a/state-sync/storage-service/server/src/metrics.rs b/state-sync/storage-service/server/src/metrics.rs index af20e50c045..bbcff51549e 100644 --- a/state-sync/storage-service/server/src/metrics.rs +++ b/state-sync/storage-service/server/src/metrics.rs @@ -21,6 +21,8 @@ pub const SUBSCRIPTION_ADD: &str = "subscription_add"; pub const SUBSCRIPTION_EXPIRE: &str = "subscription_expire"; pub const SUBSCRIPTION_FAILURE: &str = "subscription_failure"; pub const SUBSCRIPTION_NEW_STREAM: &str = "subscription_new_stream"; +pub const TRUNCATION_FOR_SIZE: &str = "size_truncation"; +pub const TRUNCATION_FOR_TIME: &str = "time_truncation"; // Latency buckets for request processing latencies (seconds) const REQUEST_PROCESSING_LATENCY_BUCKETS_SECS: &[f64] = &[ @@ -48,13 +50,13 @@ pub static LRU_CACHE_EVENT: Lazy = Lazy::new(|| { .unwrap() }); -/// Counter for the number of times a storage response overflowed the network -/// frame limit size and had to be retried. +/// Counter for the number of times a storage response overflowed +/// the network frame limit size or storage read time. pub static NETWORK_FRAME_OVERFLOW: Lazy = Lazy::new(|| { register_int_counter_vec!( "aptos_storage_service_server_network_frame_overflow", "Counters for network frame overflows in the storage server", - &["response_type"] + &["truncation_reason", "response_type"] ) .unwrap() }); @@ -213,10 +215,10 @@ pub static SUBSCRIPTION_LATENCIES: Lazy = Lazy::new(|| { .unwrap() }); -/// Increments the network frame overflow counter for the given response -pub fn increment_network_frame_overflow(response_type: &str) { +/// Increments the chunk truncation counter for the given response +pub fn increment_chunk_truncation_counter(truncation_reason: &str, response_type: &str) { NETWORK_FRAME_OVERFLOW - .with_label_values(&[response_type]) + .with_label_values(&[truncation_reason, response_type]) .inc() } diff --git a/state-sync/storage-service/server/src/optimistic_fetch.rs b/state-sync/storage-service/server/src/optimistic_fetch.rs index 10a2fb4e64b..ae207166892 100644 --- a/state-sync/storage-service/server/src/optimistic_fetch.rs +++ b/state-sync/storage-service/server/src/optimistic_fetch.rs @@ -19,7 +19,8 @@ use aptos_infallible::Mutex; use aptos_logger::{error, warn}; use aptos_storage_service_types::{ requests::{ - DataRequest, StorageServiceRequest, TransactionOutputsWithProofRequest, + DataRequest, GetTransactionDataWithProofRequest, StorageServiceRequest, + TransactionDataRequestType, TransactionOutputsWithProofRequest, TransactionsOrOutputsWithProofRequest, TransactionsWithProofRequest, }, responses::{StorageServerSummary, StorageServiceResponse}, @@ -124,6 +125,15 @@ impl OptimisticFetchRequest { }, ) }, + DataRequest::GetNewTransactionDataWithProof(request) => { + DataRequest::GetTransactionDataWithProof(GetTransactionDataWithProofRequest { + transaction_data_request_type: request.transaction_data_request_type, + proof_version: target_version, + start_version, + end_version, + max_response_bytes: request.max_response_bytes, + }) + }, request => unreachable!("Unexpected optimistic fetch request: {:?}", request), }; let storage_request = @@ -137,6 +147,7 @@ impl OptimisticFetchRequest { DataRequest::GetNewTransactionOutputsWithProof(request) => request.known_version, DataRequest::GetNewTransactionsWithProof(request) => request.known_version, DataRequest::GetNewTransactionsOrOutputsWithProof(request) => request.known_version, + DataRequest::GetNewTransactionDataWithProof(request) => request.known_version, request => unreachable!("Unexpected optimistic fetch request: {:?}", request), } } @@ -147,6 +158,7 @@ impl OptimisticFetchRequest { DataRequest::GetNewTransactionOutputsWithProof(request) => request.known_epoch, DataRequest::GetNewTransactionsWithProof(request) => request.known_epoch, DataRequest::GetNewTransactionsOrOutputsWithProof(request) => request.known_epoch, + DataRequest::GetNewTransactionDataWithProof(request) => request.known_epoch, request => unreachable!("Unexpected optimistic fetch request: {:?}", request), } } @@ -162,6 +174,19 @@ impl OptimisticFetchRequest { DataRequest::GetNewTransactionsOrOutputsWithProof(_) => { config.max_transaction_output_chunk_size }, + DataRequest::GetNewTransactionDataWithProof(request) => { + match request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(_) => { + config.max_transaction_chunk_size + }, + TransactionDataRequestType::TransactionOutputData => { + config.max_transaction_output_chunk_size + }, + TransactionDataRequestType::TransactionOrOutputData(_) => { + config.max_transaction_output_chunk_size + }, + } + }, request => unreachable!("Unexpected optimistic fetch request: {:?}", request), } } diff --git a/state-sync/storage-service/server/src/storage.rs b/state-sync/storage-service/server/src/storage.rs index 6c950715b16..3ecde243bbe 100644 --- a/state-sync/storage-service/server/src/storage.rs +++ b/state-sync/storage-service/server/src/storage.rs @@ -1,21 +1,39 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{error::Error, metrics::increment_network_frame_overflow}; +use crate::{error::Error, metrics}; use aptos_config::config::StorageServiceConfig; -use aptos_logger::debug; +use aptos_logger::{debug, warn}; use aptos_storage_interface::{AptosDbError, DbReader, Result as StorageResult}; -use aptos_storage_service_types::responses::{ - CompleteDataRange, DataResponse, DataSummary, TransactionOrOutputListWithProof, +use aptos_storage_service_types::{ + requests::{GetTransactionDataWithProofRequest, TransactionDataRequestType}, + responses::{ + CompleteDataRange, DataResponse, DataSummary, TransactionDataResponseType, + TransactionDataWithProofResponse, + }, }; +use aptos_time_service::{TimeService, TimeServiceTrait}; use aptos_types::{ + contract_event::ContractEvent, epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures, - state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + proof::{ + AccumulatorRangeProof, TransactionAccumulatorRangeProof, TransactionInfoListWithProof, + }, + state_store::{ + state_key::StateKey, + state_value::{StateValue, StateValueChunkWithProof}, + }, + transaction::{ + PersistedAuxiliaryInfo, Transaction, TransactionAuxiliaryData, TransactionInfo, + TransactionListWithAuxiliaryInfos, TransactionListWithProof, TransactionListWithProofV2, + TransactionOutput, TransactionOutputListWithAuxiliaryInfos, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, Version, + }, + write_set::WriteSet, }; use serde::Serialize; -use std::{cmp::min, sync::Arc}; +use std::{cmp::min, sync::Arc, time::Instant}; /// The interface into local storage (e.g., the Aptos DB) used by the storage /// server to handle client requests and responses. @@ -34,7 +52,7 @@ pub trait StorageReaderInterface: Clone + Send + 'static { start_version: u64, end_version: u64, include_events: bool, - ) -> aptos_storage_service_types::Result; + ) -> aptos_storage_service_types::Result; /// Returns a list of epoch ending ledger infos, starting at `start_epoch` /// and ending at the `expected_end_epoch` (inclusive). For example, if @@ -58,7 +76,7 @@ pub trait StorageReaderInterface: Clone + Send + 'static { proof_version: u64, start_version: u64, end_version: u64, - ) -> aptos_storage_service_types::Result; + ) -> aptos_storage_service_types::Result; /// Returns a list of transaction or outputs with a proof relative to the /// `proof_version`. The data list is expected to start at `start_version` @@ -73,7 +91,13 @@ pub trait StorageReaderInterface: Clone + Send + 'static { end_version: u64, include_events: bool, max_num_output_reductions: u64, - ) -> aptos_storage_service_types::Result; + ) -> aptos_storage_service_types::Result; + + /// Returns transaction data with a proof for the given request + fn get_transaction_data_with_proof( + &self, + transaction_data_with_proof_request: &GetTransactionDataWithProofRequest, + ) -> aptos_storage_service_types::Result; /// Returns the number of states in the state tree at the specified version. fn get_number_of_states(&self, version: u64) @@ -97,14 +121,23 @@ pub trait StorageReaderInterface: Clone + Send + 'static { pub struct StorageReader { config: StorageServiceConfig, storage: Arc, + time_service: TimeService, } impl StorageReader { - pub fn new(config: StorageServiceConfig, storage: Arc) -> Self { + pub fn new( + config: StorageServiceConfig, + storage: Arc, + time_service: TimeService, + ) -> Self { // Create a timed storage reader let storage = Arc::new(TimedStorageReader::new(storage)); - Self { config, storage } + Self { + config, + storage, + time_service, + } } /// Returns the state values range held in the database (lowest to highest). @@ -115,17 +148,11 @@ impl StorageReader { latest_version: Version, transactions_range: &Option>, ) -> aptos_storage_service_types::Result>, Error> { - let pruner_enabled = self - .storage - .is_state_merkle_pruner_enabled() - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let pruner_enabled = self.storage.is_state_merkle_pruner_enabled()?; if !pruner_enabled { return Ok(*transactions_range); } - let pruning_window = self - .storage - .get_epoch_snapshot_prune_window() - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let pruning_window = self.storage.get_epoch_snapshot_prune_window()?; if latest_version > pruning_window as Version { // lowest_state_version = latest_version - pruning_window + 1; @@ -153,10 +180,7 @@ impl StorageReader { &self, latest_version: Version, ) -> aptos_storage_service_types::Result>, Error> { - let first_transaction_version = self - .storage - .get_first_txn_version() - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let first_transaction_version = self.storage.get_first_txn_version()?; if let Some(first_transaction_version) = first_transaction_version { let transaction_range = CompleteDataRange::new(first_transaction_version, latest_version) @@ -172,10 +196,7 @@ impl StorageReader { &self, latest_version: Version, ) -> aptos_storage_service_types::Result>, Error> { - let first_output_version = self - .storage - .get_first_write_set_version() - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let first_output_version = self.storage.get_first_write_set_version()?; if let Some(first_output_version) = first_output_version { let output_range = CompleteDataRange::new(first_output_version, latest_version) .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; @@ -184,115 +205,105 @@ impl StorageReader { Ok(None) } } -} -impl StorageReaderInterface for StorageReader { - fn get_data_summary(&self) -> aptos_storage_service_types::Result { - // Fetch the latest ledger info - let latest_ledger_info_with_sigs = self - .storage - .get_latest_ledger_info() - .map_err(|err| Error::StorageErrorEncountered(err.to_string()))?; + /// Returns an epoch ending ledger info response (bound by the max response size in bytes) + fn get_epoch_ending_ledger_infos_by_size( + &self, + start_epoch: u64, + expected_end_epoch: u64, + max_response_size: u64, + use_size_and_time_aware_chunking: bool, + ) -> Result { + // Calculate the number of ledger infos to fetch + let expected_num_ledger_infos = inclusive_range_len(start_epoch, expected_end_epoch)?; + let max_num_ledger_infos = self.config.max_epoch_chunk_size; + let num_ledger_infos_to_fetch = min(expected_num_ledger_infos, max_num_ledger_infos); - // Fetch the epoch ending ledger info range - let latest_ledger_info = latest_ledger_info_with_sigs.ledger_info(); - let epoch_ending_ledger_infos = if latest_ledger_info.ends_epoch() { - let highest_ending_epoch = latest_ledger_info.epoch(); - Some(CompleteDataRange::from_genesis(highest_ending_epoch)) - } else if latest_ledger_info.epoch() > 0 { - let highest_ending_epoch = - latest_ledger_info.epoch().checked_sub(1).ok_or_else(|| { - Error::UnexpectedErrorEncountered("Highest ending epoch overflowed!".into()) - })?; - Some(CompleteDataRange::from_genesis(highest_ending_epoch)) - } else { - None // We haven't seen an epoch change yet - }; + // If size and time-aware chunking are disabled, use the legacy implementation + if !use_size_and_time_aware_chunking { + return self.get_epoch_ending_ledger_infos_by_size_legacy( + start_epoch, + expected_end_epoch, + num_ledger_infos_to_fetch, + max_response_size, + ); + } - // Fetch the transaction and transaction output ranges - let latest_version = latest_ledger_info.version(); - let transactions = self.fetch_transaction_range(latest_version)?; - let transaction_outputs = self.fetch_transaction_output_range(latest_version)?; + // Calculate the end epoch for storage. This is required because the DbReader + // interface returns the epochs up to: `end_epoch - 1`. However, we wish to + // fetch epoch endings up to expected_end_epoch (inclusive). + let end_epoch = start_epoch + .checked_add(num_ledger_infos_to_fetch) + .ok_or_else(|| Error::UnexpectedErrorEncountered("End epoch has overflown!".into()))?; - // Fetch the state values range - let states = self.fetch_state_values_range(latest_version, &transactions)?; + // Get the epoch ending ledger info iterator + let mut epoch_ending_ledger_info_iterator = self + .storage + .get_epoch_ending_ledger_info_iterator(start_epoch, end_epoch)?; - // Return the relevant data summary - let data_summary = DataSummary { - synced_ledger_info: Some(latest_ledger_info_with_sigs), - epoch_ending_ledger_infos, - transactions, - transaction_outputs, - states, - }; + // Initialize the fetched epoch ending ledger infos + let mut epoch_ending_ledger_infos = vec![]; - Ok(data_summary) - } + // Create a response progress tracker + let mut response_progress_tracker = ResponseDataProgressTracker::new( + num_ledger_infos_to_fetch, + max_response_size, + self.config.max_storage_read_wait_time_ms, + self.time_service.clone(), + ); - fn get_transactions_with_proof( - &self, - proof_version: u64, - start_version: u64, - end_version: u64, - include_events: bool, - ) -> aptos_storage_service_types::Result { - // Calculate the number of transactions to fetch - let expected_num_transactions = inclusive_range_len(start_version, end_version)?; - let max_num_transactions = self.config.max_transaction_chunk_size; - let mut num_transactions_to_fetch = min(expected_num_transactions, max_num_transactions); + // Fetch as many epoch ending ledger infos as possible + while !response_progress_tracker.is_response_complete() { + match epoch_ending_ledger_info_iterator.next() { + Some(Ok(epoch_ending_ledger_info)) => { + // Calculate the number of serialized bytes for the epoch ending ledger info + let num_serialized_bytes = get_num_serialized_bytes(&epoch_ending_ledger_info) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; - // Attempt to serve the request - while num_transactions_to_fetch >= 1 { - let transaction_list_with_proof = self - .storage - .get_transactions( - start_version, - num_transactions_to_fetch, - proof_version, - include_events, - ) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; - if num_transactions_to_fetch == 1 { - return Ok(transaction_list_with_proof); // We cannot return less than a single item - } - - // Attempt to divide up the request if it overflows the message size - let (overflow_frame, num_bytes) = check_overflow_network_frame( - &transaction_list_with_proof, - self.config.max_network_chunk_bytes, - )?; - if !overflow_frame { - return Ok(transaction_list_with_proof); - } else { - increment_network_frame_overflow( - DataResponse::TransactionsWithProof(transaction_list_with_proof).get_label(), - ); - let new_num_transactions_to_fetch = num_transactions_to_fetch / 2; - debug!("The request for {:?} transactions was too large (num bytes: {:?}). Retrying with {:?}.", - num_transactions_to_fetch, num_bytes, new_num_transactions_to_fetch); - num_transactions_to_fetch = new_num_transactions_to_fetch; // Try again with half the amount of data + // Add the ledger info to the list + if response_progress_tracker + .data_items_fits_in_response(true, num_serialized_bytes) + { + epoch_ending_ledger_infos.push(epoch_ending_ledger_info); + response_progress_tracker.add_data_item(num_serialized_bytes); + } else { + break; // Cannot add any more data items + } + }, + Some(Err(error)) => { + return Err(Error::StorageErrorEncountered(error.to_string())); + }, + None => { + // Log a warning that the iterator did not contain all the expected data + warn!( + "The epoch ending ledger info iterator is missing data! \ + Start epoch: {:?}, expected end epoch: {:?}, num ledger infos to fetch: {:?}", + start_epoch, expected_end_epoch, num_ledger_infos_to_fetch + ); + break; + }, } } - Err(Error::UnexpectedErrorEncountered(format!( - "Unable to serve the get_transactions_with_proof request! Proof version: {:?}, \ - start version: {:?}, end version: {:?}, include events: {:?}. The data cannot fit into \ - a single network frame!", - proof_version, start_version, end_version, include_events, - ))) + // Create the epoch change proof + let epoch_change_proof = EpochChangeProof::new(epoch_ending_ledger_infos, false); + + // Update the data truncation metrics + response_progress_tracker + .update_data_truncation_metrics(DataResponse::get_epoch_ending_ledger_info_label()); + + Ok(epoch_change_proof) } - fn get_epoch_ending_ledger_infos( + /// Returns an epoch ending ledger info response (bound by the max response size in bytes). + /// This is the legacy implementation (that does not use size and time-aware chunking). + fn get_epoch_ending_ledger_infos_by_size_legacy( &self, start_epoch: u64, expected_end_epoch: u64, - ) -> aptos_storage_service_types::Result { - // Calculate the number of ledger infos to fetch - let expected_num_ledger_infos = inclusive_range_len(start_epoch, expected_end_epoch)?; - let max_num_ledger_infos = self.config.max_epoch_chunk_size; - let mut num_ledger_infos_to_fetch = min(expected_num_ledger_infos, max_num_ledger_infos); - - // Attempt to serve the request + mut num_ledger_infos_to_fetch: u64, + max_response_size: u64, + ) -> Result { while num_ledger_infos_to_fetch >= 1 { // The DbReader interface returns the epochs up to: `end_epoch - 1`. // However, we wish to fetch epoch endings up to end_epoch (inclusive). @@ -303,26 +314,24 @@ impl StorageReaderInterface for StorageReader { })?; let epoch_change_proof = self .storage - .get_epoch_ending_ledger_infos(start_epoch, end_epoch) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + .get_epoch_ending_ledger_infos(start_epoch, end_epoch)?; if num_ledger_infos_to_fetch == 1 { return Ok(epoch_change_proof); // We cannot return less than a single item } // Attempt to divide up the request if it overflows the message size - let (overflow_frame, num_bytes) = check_overflow_network_frame( - &epoch_change_proof, - self.config.max_network_chunk_bytes, - )?; + let (overflow_frame, num_bytes) = + check_overflow_network_frame(&epoch_change_proof, max_response_size)?; if !overflow_frame { return Ok(epoch_change_proof); } else { - increment_network_frame_overflow( + metrics::increment_chunk_truncation_counter( + metrics::TRUNCATION_FOR_SIZE, DataResponse::EpochEndingLedgerInfos(epoch_change_proof).get_label(), ); let new_num_ledger_infos_to_fetch = num_ledger_infos_to_fetch / 2; - debug!("The request for {:?} ledger infos was too large (num bytes: {:?}). Retrying with {:?}.", - num_ledger_infos_to_fetch, num_bytes, new_num_ledger_infos_to_fetch); + debug!("The request for {:?} ledger infos was too large (num bytes: {:?}, limit: {:?}). Retrying with {:?}.", + num_ledger_infos_to_fetch, num_bytes, max_response_size, new_num_ledger_infos_to_fetch); num_ledger_infos_to_fetch = new_num_ledger_infos_to_fetch; // Try again with half the amount of data } } @@ -334,41 +343,435 @@ impl StorageReaderInterface for StorageReader { ))) } - fn get_transaction_outputs_with_proof( + /// Returns a transaction with proof response (bound by the max response size in bytes) + fn get_transactions_with_proof_by_size( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + include_events: bool, + max_response_size: u64, + use_size_and_time_aware_chunking: bool, + ) -> Result { + // Calculate the number of transactions to fetch + let expected_num_transactions = inclusive_range_len(start_version, end_version)?; + let max_num_transactions = self.config.max_transaction_chunk_size; + let num_transactions_to_fetch = min(expected_num_transactions, max_num_transactions); + + // If size and time-aware chunking are disabled, use the legacy implementation + if !use_size_and_time_aware_chunking { + return self.get_transactions_with_proof_by_size_legacy( + proof_version, + start_version, + end_version, + num_transactions_to_fetch, + include_events, + max_response_size, + ); + } + + // Get the iterators for the transaction, info, events and persisted auxiliary infos + let transaction_iterator = self + .storage + .get_transaction_iterator(start_version, num_transactions_to_fetch)?; + let transaction_info_iterator = self + .storage + .get_transaction_info_iterator(start_version, num_transactions_to_fetch)?; + let transaction_events_iterator = if include_events { + self.storage + .get_events_iterator(start_version, num_transactions_to_fetch)? + } else { + // If events are not included, create a fake iterator (they will be dropped anyway) + Box::new(std::iter::repeat_n( + Ok(vec![]), + num_transactions_to_fetch as usize, + )) + }; + let persisted_auxiliary_info_iterator = + self.storage.get_persisted_auxiliary_info_iterator( + start_version, + num_transactions_to_fetch as usize, + )?; + + let mut multizip_iterator = itertools::multizip(( + transaction_iterator, + transaction_info_iterator, + transaction_events_iterator, + persisted_auxiliary_info_iterator, + )); + + // Initialize the fetched data items + let mut transactions = vec![]; + let mut transaction_infos = vec![]; + let mut transaction_events = vec![]; + let mut persisted_auxiliary_infos = vec![]; + + // Create a response progress tracker + let mut response_progress_tracker = ResponseDataProgressTracker::new( + num_transactions_to_fetch, + max_response_size, + self.config.max_storage_read_wait_time_ms, + self.time_service.clone(), + ); + + // Fetch as many transactions as possible + while !response_progress_tracker.is_response_complete() { + match multizip_iterator.next() { + Some((Ok(transaction), Ok(info), Ok(events), Ok(persisted_auxiliary_info))) => { + // Calculate the number of serialized bytes for the data items + let num_transaction_bytes = get_num_serialized_bytes(&transaction) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_info_bytes = get_num_serialized_bytes(&info) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_events_bytes = get_num_serialized_bytes(&events) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_auxiliary_info_bytes = + get_num_serialized_bytes(&persisted_auxiliary_info).map_err(|error| { + Error::UnexpectedErrorEncountered(error.to_string()) + })?; + + // Add the data items to the lists + let total_serialized_bytes = num_transaction_bytes + + num_info_bytes + + num_events_bytes + + num_auxiliary_info_bytes; + if response_progress_tracker + .data_items_fits_in_response(true, total_serialized_bytes) + { + transactions.push(transaction); + transaction_infos.push(info); + transaction_events.push(events); + persisted_auxiliary_infos.push(persisted_auxiliary_info); + + response_progress_tracker.add_data_item(total_serialized_bytes); + } else { + break; // Cannot add any more data items + } + }, + Some((Err(error), _, _, _)) + | Some((_, Err(error), _, _)) + | Some((_, _, Err(error), _)) + | Some((_, _, _, Err(error))) => { + return Err(Error::StorageErrorEncountered(error.to_string())); + }, + None => { + // Log a warning that the iterators did not contain all the expected data + warn!( + "The iterators for transactions, transaction infos, events and \ + persisted auxiliary infos are missing data! Start version: {:?}, \ + end version: {:?}, num transactions to fetch: {:?}, num fetched: {:?}.", + start_version, + end_version, + num_transactions_to_fetch, + transactions.len() + ); + break; + }, + } + } + + // Create the transaction info list with proof + let accumulator_range_proof = self.storage.get_transaction_accumulator_range_proof( + start_version, + transactions.len() as u64, + proof_version, + )?; + let info_list_with_proof = + TransactionInfoListWithProof::new(accumulator_range_proof, transaction_infos); + + // Create the transaction list with proof + let transaction_events = if include_events { + Some(transaction_events) + } else { + None + }; + let transaction_list_with_proof = TransactionListWithProof::new( + transactions, + transaction_events, + Some(start_version), + info_list_with_proof, + ); + + // Update the data truncation metrics + response_progress_tracker + .update_data_truncation_metrics(DataResponse::get_transactions_with_proof_v2_label()); + + // Create the transaction data with proof response + let transaction_list_with_proof_v2 = + TransactionListWithProofV2::new(TransactionListWithAuxiliaryInfos::new( + transaction_list_with_proof, + persisted_auxiliary_infos, + )); + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionData, + transaction_list_with_proof: Some(transaction_list_with_proof_v2), + transaction_output_list_with_proof: None, + }; + Ok(response) + } + + /// Returns a transaction with proof response (bound by the max response size in bytes). + /// This is the legacy implementation (that does not use size and time-aware chunking). + fn get_transactions_with_proof_by_size_legacy( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + mut num_transactions_to_fetch: u64, + include_events: bool, + max_response_size: u64, + ) -> Result { + while num_transactions_to_fetch >= 1 { + let transaction_list_with_proof = self.storage.get_transactions( + start_version, + num_transactions_to_fetch, + proof_version, + include_events, + )?; + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionData, + transaction_list_with_proof: Some(transaction_list_with_proof), + transaction_output_list_with_proof: None, + }; + if num_transactions_to_fetch == 1 { + return Ok(response); // We cannot return less than a single item + } + + // Attempt to divide up the request if it overflows the message size + let (overflow_frame, num_bytes) = + check_overflow_network_frame(&response, max_response_size)?; + if !overflow_frame { + return Ok(response); + } else { + metrics::increment_chunk_truncation_counter( + metrics::TRUNCATION_FOR_SIZE, + DataResponse::TransactionDataWithProof(response).get_label(), + ); + let new_num_transactions_to_fetch = num_transactions_to_fetch / 2; + debug!("The request for {:?} transactions was too large (num bytes: {:?}, limit: {:?}). Retrying with {:?}.", + num_transactions_to_fetch, num_bytes, max_response_size, new_num_transactions_to_fetch); + num_transactions_to_fetch = new_num_transactions_to_fetch; // Try again with half the amount of data + } + } + + Err(Error::UnexpectedErrorEncountered(format!( + "Unable to serve the get_transactions_with_proof request! Proof version: {:?}, \ + start version: {:?}, end version: {:?}, include events: {:?}. The data cannot fit into \ + a single network frame!", + proof_version, start_version, end_version, include_events, + ))) + } + + /// Returns a transaction output with proof response (bound by the max response size in bytes) + fn get_transaction_outputs_with_proof_by_size( &self, proof_version: u64, start_version: u64, end_version: u64, - ) -> aptos_storage_service_types::Result { + max_response_size: u64, + is_transaction_or_output_request: bool, + use_size_and_time_aware_chunking: bool, + ) -> Result { // Calculate the number of transaction outputs to fetch let expected_num_outputs = inclusive_range_len(start_version, end_version)?; let max_num_outputs = self.config.max_transaction_output_chunk_size; - let mut num_outputs_to_fetch = min(expected_num_outputs, max_num_outputs); + let num_outputs_to_fetch = min(expected_num_outputs, max_num_outputs); - // Attempt to serve the request + // If size and time-aware chunking are disabled, use the legacy implementation + if !use_size_and_time_aware_chunking { + return self.get_transaction_outputs_with_proof_by_size_legacy( + proof_version, + start_version, + end_version, + num_outputs_to_fetch, + max_response_size, + ); + } + + // Get the iterators for the transaction, info, write set, events, + // auxiliary data and persisted auxiliary infos. + let transaction_iterator = self + .storage + .get_transaction_iterator(start_version, num_outputs_to_fetch)?; + let transaction_info_iterator = self + .storage + .get_transaction_info_iterator(start_version, num_outputs_to_fetch)?; + let transaction_write_set_iterator = self + .storage + .get_write_set_iterator(start_version, num_outputs_to_fetch)?; + let transaction_events_iterator = self + .storage + .get_events_iterator(start_version, num_outputs_to_fetch)?; + let persisted_auxiliary_info_iterator = self + .storage + .get_persisted_auxiliary_info_iterator(start_version, num_outputs_to_fetch as usize)?; + let mut multizip_iterator = itertools::multizip(( + transaction_iterator, + transaction_info_iterator, + transaction_write_set_iterator, + transaction_events_iterator, + persisted_auxiliary_info_iterator, + )); + + // Initialize the fetched data items + let mut transactions_and_outputs = vec![]; + let mut transaction_infos = vec![]; + let mut persisted_auxiliary_infos = vec![]; + + // Create a response progress tracker + let mut response_progress_tracker = ResponseDataProgressTracker::new( + num_outputs_to_fetch, + max_response_size, + self.config.max_storage_read_wait_time_ms, + self.time_service.clone(), + ); + + // Fetch as many transaction outputs as possible + while !response_progress_tracker.is_response_complete() { + match multizip_iterator.next() { + Some(( + Ok(transaction), + Ok(info), + Ok(write_set), + Ok(events), + Ok(persisted_auxiliary_info), + )) => { + // Create the transaction output + let output = TransactionOutput::new( + write_set, + events, + info.gas_used(), + info.status().clone().into(), + TransactionAuxiliaryData::None, // Auxiliary data is no longer supported + ); + + // Calculate the number of serialized bytes for the data items + let num_transaction_bytes = get_num_serialized_bytes(&transaction) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_info_bytes = get_num_serialized_bytes(&info) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_output_bytes = get_num_serialized_bytes(&output) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + let num_auxiliary_info_bytes = + get_num_serialized_bytes(&persisted_auxiliary_info).map_err(|error| { + Error::UnexpectedErrorEncountered(error.to_string()) + })?; + + // Add the data items to the lists + let total_serialized_bytes = num_transaction_bytes + + num_info_bytes + + num_output_bytes + + num_auxiliary_info_bytes; + if response_progress_tracker.data_items_fits_in_response( + !is_transaction_or_output_request, + total_serialized_bytes, + ) { + transactions_and_outputs.push((transaction, output)); + transaction_infos.push(info); + persisted_auxiliary_infos.push(persisted_auxiliary_info); + + response_progress_tracker.add_data_item(total_serialized_bytes); + } else { + break; // Cannot add any more data items + } + }, + Some((Err(error), _, _, _, _)) + | Some((_, Err(error), _, _, _)) + | Some((_, _, Err(error), _, _)) + | Some((_, _, _, Err(error), _)) + | Some((_, _, _, _, Err(error))) => { + return Err(Error::StorageErrorEncountered(error.to_string())); + }, + None => { + // Log a warning that the iterators did not contain all the expected data + warn!( + "The iterators for transactions, transaction infos, write sets, events, \ + auxiliary data and persisted auxiliary infos are missing data! Start version: {:?}, \ + end version: {:?}, num outputs to fetch: {:?}, num fetched: {:?}.", + start_version, end_version, num_outputs_to_fetch, transactions_and_outputs.len() + ); + break; + }, + } + } + + // Create the transaction output list with proof + let num_fetched_outputs = transactions_and_outputs.len(); + let accumulator_range_proof = if num_fetched_outputs == 0 { + AccumulatorRangeProof::new_empty() // Return an empty proof if no outputs were fetched + } else { + self.storage.get_transaction_accumulator_range_proof( + start_version, + num_fetched_outputs as u64, + proof_version, + )? + }; + let transaction_info_list_with_proof = + TransactionInfoListWithProof::new(accumulator_range_proof, transaction_infos); + let transaction_output_list_with_proof = TransactionOutputListWithProof::new( + transactions_and_outputs, + Some(start_version), + transaction_info_list_with_proof, + ); + + // Update the data truncation metrics + response_progress_tracker.update_data_truncation_metrics( + DataResponse::get_transaction_outputs_with_proof_v2_label(), + ); + + // Create the transaction data with proof response + let output_list_with_proof_v2 = + TransactionOutputListWithProofV2::new(TransactionOutputListWithAuxiliaryInfos::new( + transaction_output_list_with_proof, + persisted_auxiliary_infos, + )); + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof: Some(output_list_with_proof_v2), + }; + + Ok(response) + } + + /// Returns a transaction output with proof response (bound by the max response size in bytes). + /// This is the legacy implementation (that does not use size and time-aware chunking). + fn get_transaction_outputs_with_proof_by_size_legacy( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + mut num_outputs_to_fetch: u64, + max_response_size: u64, + ) -> Result { while num_outputs_to_fetch >= 1 { - let output_list_with_proof = self - .storage - .get_transaction_outputs(start_version, num_outputs_to_fetch, proof_version) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let output_list_with_proof = self.storage.get_transaction_outputs( + start_version, + num_outputs_to_fetch, + proof_version, + )?; + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof: Some(output_list_with_proof), + }; if num_outputs_to_fetch == 1 { - return Ok(output_list_with_proof); // We cannot return less than a single item + return Ok(response); // We cannot return less than a single item } // Attempt to divide up the request if it overflows the message size - let (overflow_frame, num_bytes) = check_overflow_network_frame( - &output_list_with_proof, - self.config.max_network_chunk_bytes, - )?; + let (overflow_frame, num_bytes) = + check_overflow_network_frame(&response, max_response_size)?; if !overflow_frame { - return Ok(output_list_with_proof); + return Ok(response); } else { - increment_network_frame_overflow( - DataResponse::TransactionOutputsWithProof(output_list_with_proof).get_label(), + metrics::increment_chunk_truncation_counter( + metrics::TRUNCATION_FOR_SIZE, + DataResponse::TransactionDataWithProof(response).get_label(), ); let new_num_outputs_to_fetch = num_outputs_to_fetch / 2; - debug!("The request for {:?} outputs was too large (num bytes: {:?}). Retrying with {:?}.", - num_outputs_to_fetch, num_bytes, new_num_outputs_to_fetch); + debug!("The request for {:?} outputs was too large (num bytes: {:?}, limit: {:?}). Retrying with {:?}.", + num_outputs_to_fetch, num_bytes, max_response_size, new_num_outputs_to_fetch); num_outputs_to_fetch = new_num_outputs_to_fetch; // Try again with half the amount of data } } @@ -380,114 +783,243 @@ impl StorageReaderInterface for StorageReader { ))) } - fn get_transactions_or_outputs_with_proof( + /// Returns a transaction or output with proof response (bound by the max response size in bytes) + fn get_transactions_or_outputs_with_proof_by_size( &self, proof_version: u64, start_version: u64, end_version: u64, include_events: bool, max_num_output_reductions: u64, - ) -> aptos_storage_service_types::Result { + max_response_size: u64, + use_size_and_time_aware_chunking: bool, + ) -> Result { // Calculate the number of transaction outputs to fetch let expected_num_outputs = inclusive_range_len(start_version, end_version)?; let max_num_outputs = self.config.max_transaction_output_chunk_size; - let mut num_outputs_to_fetch = min(expected_num_outputs, max_num_outputs); + let num_outputs_to_fetch = min(expected_num_outputs, max_num_outputs); + + // If size and time-aware chunking are disabled, use the legacy implementation + if !use_size_and_time_aware_chunking { + return self.get_transactions_or_outputs_with_proof_by_size_legacy( + proof_version, + start_version, + end_version, + num_outputs_to_fetch, + include_events, + max_num_output_reductions, + max_response_size, + ); + } - // Attempt to serve the outputs. Halve the data only as many - // times as the fallback count allows. If the data still - // doesn't fit, return a transaction chunk instead. + // Fetch the transaction outputs with proof + let response = self.get_transaction_outputs_with_proof_by_size( + proof_version, + start_version, + end_version, + max_response_size, + true, // This is a transaction or output request + use_size_and_time_aware_chunking, + )?; + + // If the request was fully satisfied (all items were fetched), return the response + if let Some(output_list_with_proof) = response.transaction_output_list_with_proof.as_ref() { + if num_outputs_to_fetch == output_list_with_proof.get_num_outputs() as u64 { + return Ok(response); + } + } + + // Otherwise, return as many transactions as possible + self.get_transactions_with_proof_by_size( + proof_version, + start_version, + end_version, + include_events, + max_response_size, + use_size_and_time_aware_chunking, + ) + } + + /// Returns a transaction or output with proof response (bound by the max response size in bytes). + /// This is the legacy implementation (that does not use size and time-aware chunking). + fn get_transactions_or_outputs_with_proof_by_size_legacy( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + mut num_outputs_to_fetch: u64, + include_events: bool, + max_num_output_reductions: u64, + max_response_size: u64, + ) -> Result { let mut num_output_reductions = 0; while num_output_reductions <= max_num_output_reductions { - let output_list_with_proof = self - .storage - .get_transaction_outputs(start_version, num_outputs_to_fetch, proof_version) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; - let (overflow_frame, num_bytes) = check_overflow_network_frame( - &output_list_with_proof, - self.config.max_network_chunk_bytes, + let output_list_with_proof = self.storage.get_transaction_outputs( + start_version, + num_outputs_to_fetch, + proof_version, )?; + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof: Some(output_list_with_proof), + }; + + let (overflow_frame, num_bytes) = + check_overflow_network_frame(&response, max_response_size)?; if !overflow_frame { - return Ok((None, Some(output_list_with_proof))); + return Ok(response); } else if num_outputs_to_fetch == 1 { break; // We cannot return less than a single item. Fallback to transactions } else { - increment_network_frame_overflow( - DataResponse::TransactionsOrOutputsWithProof(( - None, - Some(output_list_with_proof), - )) - .get_label(), + metrics::increment_chunk_truncation_counter( + metrics::TRUNCATION_FOR_SIZE, + DataResponse::TransactionDataWithProof(response).get_label(), ); let new_num_outputs_to_fetch = num_outputs_to_fetch / 2; - debug!("The request for {:?} outputs was too large (num bytes: {:?}). Current number of data reductions: {:?}", - num_outputs_to_fetch, num_bytes, num_output_reductions); + debug!("The request for {:?} outputs was too large (num bytes: {:?}, limit: {:?}). Current number of data reductions: {:?}", + num_outputs_to_fetch, num_bytes, max_response_size, num_output_reductions); num_outputs_to_fetch = new_num_outputs_to_fetch; // Try again with half the amount of data num_output_reductions += 1; } } // Return transactions only - let transactions_with_proof = self.get_transactions_with_proof( + self.get_transactions_with_proof_by_size( proof_version, start_version, end_version, include_events, - )?; - Ok((Some(transactions_with_proof), None)) - } - - fn get_number_of_states( - &self, - version: u64, - ) -> aptos_storage_service_types::Result { - let number_of_states = self - .storage - .get_state_item_count(version) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; - Ok(number_of_states as u64) + max_response_size, + self.config.enable_size_and_time_aware_chunking, + ) } - fn get_state_value_chunk_with_proof( + /// Returns a state value chunk with proof response (bound by the max response size in bytes) + fn get_state_value_chunk_with_proof_by_size( &self, version: u64, start_index: u64, end_index: u64, - ) -> aptos_storage_service_types::Result { + max_response_size: u64, + use_size_and_time_aware_chunking: bool, + ) -> Result { // Calculate the number of state values to fetch let expected_num_state_values = inclusive_range_len(start_index, end_index)?; let max_num_state_values = self.config.max_state_chunk_size; - let mut num_state_values_to_fetch = min(expected_num_state_values, max_num_state_values); + let num_state_values_to_fetch = min(expected_num_state_values, max_num_state_values); + + // If size and time-aware chunking are disabled, use the legacy implementation + if !use_size_and_time_aware_chunking { + return self.get_state_value_chunk_with_proof_by_size_legacy( + version, + start_index, + end_index, + num_state_values_to_fetch, + max_response_size, + ); + } + + // Get the state value chunk iterator + let mut state_value_iterator = self.storage.get_state_value_chunk_iter( + version, + start_index as usize, + num_state_values_to_fetch as usize, + )?; + + // Initialize the fetched state values + let mut state_values = vec![]; + + // Create a response progress tracker + let mut response_progress_tracker = ResponseDataProgressTracker::new( + num_state_values_to_fetch, + max_response_size, + self.config.max_storage_read_wait_time_ms, + self.time_service.clone(), + ); + + // Fetch as many state values as possible + while !response_progress_tracker.is_response_complete() { + match state_value_iterator.next() { + Some(Ok(state_value)) => { + // Calculate the number of serialized bytes for the state value + let num_serialized_bytes = get_num_serialized_bytes(&state_value) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; - // Attempt to serve the request + // Add the state value to the list + if response_progress_tracker + .data_items_fits_in_response(true, num_serialized_bytes) + { + state_values.push(state_value); + response_progress_tracker.add_data_item(num_serialized_bytes); + } else { + break; // Cannot add any more data items + } + }, + Some(Err(error)) => { + return Err(Error::StorageErrorEncountered(error.to_string())); + }, + None => { + // Log a warning that the iterator did not contain all the expected data + warn!( + "The state value iterator is missing data! Version: {:?}, \ + start index: {:?}, end index: {:?}, num state values to fetch: {:?}", + version, start_index, end_index, num_state_values_to_fetch + ); + break; + }, + } + } + + // Create the state value chunk with proof + let state_value_chunk_with_proof = self.storage.get_state_value_chunk_proof( + version, + start_index as usize, + state_values, + )?; + + // Update the data truncation metrics + response_progress_tracker + .update_data_truncation_metrics(DataResponse::get_state_value_chunk_with_proof_label()); + + Ok(state_value_chunk_with_proof) + } + + /// Returns a state value chunk with proof response (bound by the max response size in bytes). + /// This is the legacy implementation (that does not use size and time-aware chunking). + fn get_state_value_chunk_with_proof_by_size_legacy( + &self, + version: u64, + start_index: u64, + end_index: u64, + mut num_state_values_to_fetch: u64, + max_response_size: u64, + ) -> Result { while num_state_values_to_fetch >= 1 { - let state_value_chunk_with_proof = self - .storage - .get_state_value_chunk_with_proof( - version, - start_index as usize, - num_state_values_to_fetch as usize, - ) - .map_err(|error| Error::StorageErrorEncountered(error.to_string()))?; + let state_value_chunk_with_proof = self.storage.get_state_value_chunk_with_proof( + version, + start_index as usize, + num_state_values_to_fetch as usize, + )?; if num_state_values_to_fetch == 1 { return Ok(state_value_chunk_with_proof); // We cannot return less than a single item } // Attempt to divide up the request if it overflows the message size - let (overflow_frame, num_bytes) = check_overflow_network_frame( - &state_value_chunk_with_proof, - self.config.max_network_chunk_bytes, - )?; + let (overflow_frame, num_bytes) = + check_overflow_network_frame(&state_value_chunk_with_proof, max_response_size)?; if !overflow_frame { return Ok(state_value_chunk_with_proof); } else { - increment_network_frame_overflow( + metrics::increment_chunk_truncation_counter( + metrics::TRUNCATION_FOR_SIZE, DataResponse::StateValueChunkWithProof(state_value_chunk_with_proof) .get_label(), ); let new_num_state_values_to_fetch = num_state_values_to_fetch / 2; - debug!("The request for {:?} state values was too large (num bytes: {:?}). Retrying with {:?}.", - num_state_values_to_fetch, num_bytes, new_num_state_values_to_fetch); + debug!("The request for {:?} state values was too large (num bytes: {:?}, limit: {:?}). Retrying with {:?}.", + num_state_values_to_fetch, num_bytes, max_response_size, new_num_state_values_to_fetch); num_state_values_to_fetch = new_num_state_values_to_fetch; // Try again with half the amount of data } } @@ -500,6 +1032,189 @@ impl StorageReaderInterface for StorageReader { } } +impl StorageReaderInterface for StorageReader { + fn get_data_summary(&self) -> aptos_storage_service_types::Result { + // Fetch the latest ledger info + let latest_ledger_info_with_sigs = self.storage.get_latest_ledger_info()?; + + // Fetch the epoch ending ledger info range + let latest_ledger_info = latest_ledger_info_with_sigs.ledger_info(); + let epoch_ending_ledger_infos = if latest_ledger_info.ends_epoch() { + let highest_ending_epoch = latest_ledger_info.epoch(); + Some(CompleteDataRange::from_genesis(highest_ending_epoch)) + } else if latest_ledger_info.epoch() > 0 { + let highest_ending_epoch = + latest_ledger_info.epoch().checked_sub(1).ok_or_else(|| { + Error::UnexpectedErrorEncountered("Highest ending epoch overflowed!".into()) + })?; + Some(CompleteDataRange::from_genesis(highest_ending_epoch)) + } else { + None // We haven't seen an epoch change yet + }; + + // Fetch the transaction and transaction output ranges + let latest_version = latest_ledger_info.version(); + let transactions = self.fetch_transaction_range(latest_version)?; + let transaction_outputs = self.fetch_transaction_output_range(latest_version)?; + + // Fetch the state values range + let states = self.fetch_state_values_range(latest_version, &transactions)?; + + // Return the relevant data summary + let data_summary = DataSummary { + synced_ledger_info: Some(latest_ledger_info_with_sigs), + epoch_ending_ledger_infos, + transactions, + transaction_outputs, + states, + }; + + Ok(data_summary) + } + + fn get_transactions_with_proof( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + include_events: bool, + ) -> aptos_storage_service_types::Result { + self.get_transactions_with_proof_by_size( + proof_version, + start_version, + end_version, + include_events, + self.config.max_network_chunk_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + } + + fn get_epoch_ending_ledger_infos( + &self, + start_epoch: u64, + expected_end_epoch: u64, + ) -> aptos_storage_service_types::Result { + self.get_epoch_ending_ledger_infos_by_size( + start_epoch, + expected_end_epoch, + self.config.max_network_chunk_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + } + + fn get_transaction_outputs_with_proof( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + ) -> aptos_storage_service_types::Result { + self.get_transaction_outputs_with_proof_by_size( + proof_version, + start_version, + end_version, + self.config.max_network_chunk_bytes, + false, + self.config.enable_size_and_time_aware_chunking, + ) + } + + fn get_transactions_or_outputs_with_proof( + &self, + proof_version: u64, + start_version: u64, + end_version: u64, + include_events: bool, + max_num_output_reductions: u64, + ) -> aptos_storage_service_types::Result { + self.get_transactions_or_outputs_with_proof_by_size( + proof_version, + start_version, + end_version, + include_events, + max_num_output_reductions, + self.config.max_network_chunk_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + } + + fn get_transaction_data_with_proof( + &self, + transaction_data_with_proof_request: &GetTransactionDataWithProofRequest, + ) -> aptos_storage_service_types::Result { + // Extract the data versions from the request + let proof_version = transaction_data_with_proof_request.proof_version; + let start_version = transaction_data_with_proof_request.start_version; + let end_version = transaction_data_with_proof_request.end_version; + + // Calculate the max response size to use + let max_response_bytes = min( + transaction_data_with_proof_request.max_response_bytes, + self.config.max_network_chunk_bytes_v2, + ); + + // Fetch the transaction data based on the request type + match transaction_data_with_proof_request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(request) => { + // Get the transaction list with proof + self.get_transactions_with_proof_by_size( + proof_version, + start_version, + end_version, + request.include_events, + max_response_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + }, + TransactionDataRequestType::TransactionOutputData => { + // Get the transaction output list with proof + self.get_transaction_outputs_with_proof_by_size( + proof_version, + start_version, + end_version, + max_response_bytes, + false, + self.config.enable_size_and_time_aware_chunking, + ) + }, + TransactionDataRequestType::TransactionOrOutputData(request) => { + // Get the transaction or output list with proof + self.get_transactions_or_outputs_with_proof_by_size( + proof_version, + start_version, + end_version, + request.include_events, + 0, // Fetch all outputs, or return transactions + max_response_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + }, + } + } + + fn get_number_of_states( + &self, + version: u64, + ) -> aptos_storage_service_types::Result { + let number_of_states = self.storage.get_state_item_count(version)?; + Ok(number_of_states as u64) + } + + fn get_state_value_chunk_with_proof( + &self, + version: u64, + start_index: u64, + end_index: u64, + ) -> aptos_storage_service_types::Result { + self.get_state_value_chunk_with_proof_by_size( + version, + start_index, + end_index, + self.config.max_network_chunk_bytes, + self.config.enable_size_and_time_aware_chunking, + ) + } +} + // A simple macro that wraps each storage read call with a timer macro_rules! timed_read { ($( @@ -555,7 +1270,7 @@ impl DbReader for TimedStorageReader { batch_size: u64, ledger_version: Version, fetch_events: bool, - ) -> StorageResult; + ) -> StorageResult; fn get_epoch_ending_ledger_infos( &self, @@ -568,7 +1283,7 @@ impl DbReader for TimedStorageReader { start_version: Version, limit: u64, ledger_version: Version, - ) -> StorageResult; + ) -> StorageResult; fn get_state_item_count(&self, version: Version) -> StorageResult; @@ -578,9 +1293,193 @@ impl DbReader for TimedStorageReader { start_idx: usize, chunk_size: usize, ) -> StorageResult; + + fn get_epoch_ending_ledger_info_iterator( + &self, + start_epoch: u64, + end_epoch: u64, + ) -> StorageResult> + '_>>; + + fn get_transaction_iterator( + &self, + start_version: Version, + limit: u64, + ) -> StorageResult> + '_>>; + + fn get_transaction_info_iterator( + &self, + start_version: Version, + limit: u64, + ) -> StorageResult> + '_>>; + + fn get_events_iterator( + &self, + start_version: Version, + limit: u64, + ) -> StorageResult>> + '_>>; + + fn get_write_set_iterator( + &self, + start_version: Version, + limit: u64, + ) -> StorageResult> + '_>>; + + fn get_transaction_accumulator_range_proof( + &self, + start_version: Version, + limit: u64, + ledger_version: Version, + ) -> StorageResult; + + fn get_state_value_chunk_iter( + &self, + version: Version, + first_index: usize, + chunk_size: usize, + ) -> StorageResult> + '_>>; + + fn get_state_value_chunk_proof( + &self, + version: Version, + first_index: usize, + state_key_values: Vec<(StateKey, StateValue)>, + ) -> StorageResult; + + fn get_persisted_auxiliary_info_iterator( + &self, + start_version: Version, + num_persisted_auxiliary_info: usize, + ) -> StorageResult> + '_>>; ); } +/// A simple struct to track the progress of data fetching operations for each response +pub struct ResponseDataProgressTracker { + num_items_to_fetch: u64, + max_response_size: u64, + max_storage_read_wait_time_ms: u64, + time_service: TimeService, + + num_items_fetched: u64, + serialized_data_size: u64, + storage_read_start_time: Instant, +} + +impl ResponseDataProgressTracker { + pub fn new( + num_items_to_fetch: u64, + max_response_size: u64, + max_storage_read_wait_time_ms: u64, + time_service: TimeService, + ) -> Self { + let storage_read_start_time = time_service.now(); + Self { + num_items_to_fetch, + max_response_size, + max_storage_read_wait_time_ms, + time_service, + num_items_fetched: 0, + serialized_data_size: 0, + storage_read_start_time, + } + } + + /// Adds a data item to the response, updating the number of items + /// fetched and the cumulative serialized data size. + pub fn add_data_item(&mut self, serialized_data_size: u64) { + self.num_items_fetched += 1; + self.serialized_data_size += serialized_data_size; + } + + /// Returns true iff the given data item fits in the response + /// (i.e., it does not overflow the maximum response size). + /// + /// Note: If `always_allow_first_item` is true, the first item is + /// always allowed (even if it overflows the maximum response size). + pub fn data_items_fits_in_response( + &self, + always_allow_first_item: bool, + serialized_data_size: u64, + ) -> bool { + if always_allow_first_item && self.num_items_fetched == 0 { + true // We always include at least one item + } else { + let new_serialized_data_size = self + .serialized_data_size + .saturating_add(serialized_data_size); + new_serialized_data_size < self.max_response_size + } + } + + /// Checks if the response is complete based on the number of items fetched, the + /// cumulative serialized data size, and the cumulative storage read duration. + pub fn is_response_complete(&self) -> bool { + // If we have fetched all the items, the response is complete + if self.num_items_fetched >= self.num_items_to_fetch { + return true; + } + + // If the serialized data size exceeds the maximum, the response is complete + if self.serialized_data_size >= self.max_response_size { + return true; + } + + // If the storage read duration exceeds the maximum, the response is complete + if self.overflowed_storage_read_duration() { + return true; + } + + // Otherwise, the response is not yet complete + false + } + + /// Checks if the storage read duration has overflowed the maximum wait time + fn overflowed_storage_read_duration(&self) -> bool { + let time_now = self.time_service.now(); + let time_elapsed_ms = time_now + .duration_since(self.storage_read_start_time) + .as_millis() as u64; + + time_elapsed_ms >= self.max_storage_read_wait_time_ms + } + + /// Updates the truncation logs and metrics if the data was truncated + fn update_data_truncation_metrics(&self, data_response_label: &str) { + // Only update the metrics if the data was truncated + if self.num_items_fetched >= self.num_items_to_fetch { + return; + } + + // Update the metrics based on the truncation reason + let truncation_reason = if self.overflowed_storage_read_duration() { + debug!( + "Truncated data response for {:?} by time, after fetching {:?} out of {:?} \ + items (time waited: {:?} ms, maximum wait time: {:?}).", + data_response_label, + self.num_items_fetched, + self.num_items_to_fetch, + self.storage_read_start_time.elapsed().as_millis(), + self.max_storage_read_wait_time_ms, + ); + + metrics::TRUNCATION_FOR_TIME + } else { + debug!( + "Truncated data response for {:?} by size, after fetching {:?} out of {:?} \ + items (response size: {:?} bytes, maximum size: {:?}).", + data_response_label, + self.num_items_fetched, + self.num_items_to_fetch, + self.serialized_data_size, + self.max_response_size, + ); + + metrics::TRUNCATION_FOR_SIZE + }; + metrics::increment_chunk_truncation_counter(truncation_reason, data_response_label); + } +} + /// Calculate `(start..=end).len()`. Returns an error if `end < start` or /// `end == u64::MAX`. fn inclusive_range_len(start: u64, end: u64) -> aptos_storage_service_types::Result { @@ -597,7 +1496,7 @@ fn inclusive_range_len(start: u64, end: u64) -> aptos_storage_service_types::Res /// Serializes the given data and returns true iff the data will overflow /// the maximum network frame size. Also returns the number of serialized /// bytes for logging purposes. -pub(crate) fn check_overflow_network_frame( +fn check_overflow_network_frame( data: &T, max_network_frame_bytes: u64, ) -> aptos_storage_service_types::Result<(bool, u64), Error> { @@ -607,3 +1506,12 @@ pub(crate) fn check_overflow_network_frame( let overflow_frame = num_serialized_bytes >= max_network_frame_bytes; Ok((overflow_frame, num_serialized_bytes)) } + +/// Serializes the given data and returns the number of serialized bytes +fn get_num_serialized_bytes( + data: &T, +) -> aptos_storage_service_types::Result { + let num_serialized_bytes = bcs::serialized_size(data) + .map_err(|error| Error::UnexpectedErrorEncountered(error.to_string()))?; + Ok(num_serialized_bytes as u64) +} diff --git a/state-sync/storage-service/server/src/subscription.rs b/state-sync/storage-service/server/src/subscription.rs index b7515ea1304..276a70da290 100644 --- a/state-sync/storage-service/server/src/subscription.rs +++ b/state-sync/storage-service/server/src/subscription.rs @@ -19,11 +19,13 @@ use aptos_infallible::Mutex; use aptos_logger::{error, warn}; use aptos_storage_service_types::{ requests::{ - DataRequest, StorageServiceRequest, SubscriptionStreamMetadata, - TransactionOutputsWithProofRequest, TransactionsOrOutputsWithProofRequest, - TransactionsWithProofRequest, + DataRequest, GetTransactionDataWithProofRequest, StorageServiceRequest, + SubscriptionStreamMetadata, TransactionDataRequestType, TransactionOutputsWithProofRequest, + TransactionsOrOutputsWithProofRequest, TransactionsWithProofRequest, + }, + responses::{ + DataResponse, StorageServerSummary, StorageServiceResponse, TransactionDataResponseType, }, - responses::{DataResponse, StorageServerSummary, StorageServiceResponse}, }; use aptos_time_service::{TimeService, TimeServiceTrait}; use aptos_types::{ledger_info::LedgerInfoWithSignatures, transaction::Version}; @@ -122,6 +124,15 @@ impl SubscriptionRequest { }, ) }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + DataRequest::GetTransactionDataWithProof(GetTransactionDataWithProofRequest { + transaction_data_request_type: request.transaction_data_request_type, + proof_version: target_version, + start_version, + end_version, + max_response_bytes: request.max_response_bytes, + }) + }, request => unreachable!("Unexpected subscription request: {:?}", request), }; let storage_request = @@ -147,6 +158,11 @@ impl SubscriptionRequest { .subscription_stream_metadata .known_version_at_stream_start }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request + .subscription_stream_metadata + .known_version_at_stream_start + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -169,6 +185,11 @@ impl SubscriptionRequest { .subscription_stream_metadata .known_epoch_at_stream_start }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request + .subscription_stream_metadata + .known_epoch_at_stream_start + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -184,6 +205,19 @@ impl SubscriptionRequest { DataRequest::SubscribeTransactionsOrOutputsWithProof(_) => { config.max_transaction_output_chunk_size }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + match request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(_) => { + config.max_transaction_chunk_size + }, + TransactionDataRequestType::TransactionOutputData => { + config.max_transaction_output_chunk_size + }, + TransactionDataRequestType::TransactionOrOutputData(_) => { + config.max_transaction_output_chunk_size + }, + } + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -200,6 +234,9 @@ impl SubscriptionRequest { DataRequest::SubscribeTransactionsOrOutputsWithProof(request) => { request.subscription_stream_metadata.subscription_stream_id }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request.subscription_stream_metadata.subscription_stream_id + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -216,6 +253,9 @@ impl SubscriptionRequest { DataRequest::SubscribeTransactionsOrOutputsWithProof(request) => { request.subscription_stream_index }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request.subscription_stream_index + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -232,6 +272,9 @@ impl SubscriptionRequest { DataRequest::SubscribeTransactionsOrOutputsWithProof(request) => { request.subscription_stream_metadata }, + DataRequest::SubscribeTransactionDataWithProof(request) => { + request.subscription_stream_metadata + }, request => unreachable!("Unexpected subscription request: {:?}", request), } } @@ -430,21 +473,21 @@ impl SubscriptionStreamRequests { transaction_output_list, target_ledger_info, )) => ( - transaction_output_list.transactions_and_outputs.len(), + transaction_output_list.get_num_outputs(), target_ledger_info, ), DataResponse::NewTransactionsWithProof((transaction_list, target_ledger_info)) => { - (transaction_list.transactions.len(), target_ledger_info) + (transaction_list.get_num_transactions(), target_ledger_info) }, DataResponse::NewTransactionsOrOutputsWithProof(( (transaction_list, transaction_output_list), target_ledger_info, )) => { if let Some(transaction_list) = transaction_list { - (transaction_list.transactions.len(), target_ledger_info) + (transaction_list.get_num_transactions(), target_ledger_info) } else if let Some(transaction_output_list) = transaction_output_list { ( - transaction_output_list.transactions_and_outputs.len(), + transaction_output_list.get_num_outputs(), target_ledger_info, ) } else { @@ -454,6 +497,41 @@ impl SubscriptionStreamRequests { ))); } }, + DataResponse::NewTransactionDataWithProof(response) => { + let num_data_items = match response.transaction_data_response_type { + TransactionDataResponseType::TransactionData => { + if let Some(transaction_list_with_proof_v2) = + &response.transaction_list_with_proof + { + transaction_list_with_proof_v2 + .get_transaction_list_with_proof() + .get_num_transactions() + } else { + return Err(Error::UnexpectedErrorEncountered(format!( + "Transaction data response is missing transaction list: {:?}", + data_response + ))); + } + }, + TransactionDataResponseType::TransactionOutputData => { + if let Some(output_list_with_proof_v2) = + &response.transaction_output_list_with_proof + { + output_list_with_proof_v2 + .get_output_list_with_proof() + .get_num_outputs() + } else { + return Err(Error::UnexpectedErrorEncountered(format!( + "Transaction output data response is missing output list: {:?}", + data_response + ))); + } + }, + }; + let target_ledger_info = &response.ledger_info_with_signatures; + + (num_data_items, target_ledger_info) + }, _ => { return Err(Error::UnexpectedErrorEncountered(format!( "Unexpected data response type: {:?}", diff --git a/state-sync/storage-service/server/src/tests/cache.rs b/state-sync/storage-service/server/src/tests/cache.rs index 587d0671a35..9d74b148c13 100644 --- a/state-sync/storage-service/server/src/tests/cache.rs +++ b/state-sync/storage-service/server/src/tests/cache.rs @@ -4,7 +4,6 @@ use crate::tests::{mock, mock::MockClient, utils}; use aptos_config::config::StorageServiceConfig; use aptos_crypto::hash::HashValue; -use aptos_storage_service_types::responses::{DataResponse, StorageServiceResponse}; use aptos_types::{ proof::definition::SparseMerkleRangeProof, state_store::state_value::StateValueChunkWithProof, }; @@ -15,142 +14,155 @@ use mockall::{ #[tokio::test] async fn test_cachable_requests_compression() { - // Create test data - let start_version = 0; - let end_version = 454; - let proof_version = end_version; - let include_events = false; - let compression_options = [true, false]; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut transaction_lists_with_proof = vec![]; - for _ in compression_options { - // Create and save test transaction lists - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - end_version, - proof_version, - include_events, - ); - transaction_lists_with_proof.push(transaction_list_with_proof.clone()); - - // Expect the data to be fetched from storage exactly once - db_reader - .expect_get_transactions() - .times(1) - .with( - eq(start_version), - eq(end_version - start_version + 1), - eq(proof_version), - eq(include_events), - ) - .return_once(move |_, _, _, _| Ok(transaction_list_with_proof)) - .in_sequence(&mut expectation_sequence); - } - - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, end_version, 10); - tokio::spawn(service.start()); - - // Repeatedly fetch the data and verify the responses - for (i, use_compression) in compression_options.iter().enumerate() { - for _ in 0..10 { - let response = utils::get_transactions_with_proof( - &mut mock_client, - start_version, - end_version, - proof_version, - include_events, - *use_compression, - ) - .await - .unwrap(); - - // Verify the response is correct - assert_eq!(response.is_compressed(), *use_compression); - match response.get_data_response().unwrap() { - DataResponse::TransactionsWithProof(response) => { - assert_eq!(response, transaction_lists_with_proof[i]); - }, - _ => panic!("Expected transactions with proof but got: {:?}", response), - }; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let start_version = 0; + let end_version = 454; + let proof_version = end_version; + let include_events = false; + let compression_options = [true, false]; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + let mut transaction_lists_with_proof = vec![]; + for _ in compression_options { + // Create and save test transaction lists + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + include_events, + use_request_v2, + ); + transaction_lists_with_proof.push(transaction_list_with_proof.clone()); + + // Expect the data to be fetched from storage exactly once + utils::expect_get_transactions( + &mut db_reader, + start_version, + end_version - start_version + 1, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, end_version, 10); + tokio::spawn(service.start()); + + // Repeatedly fetch the data and verify the responses + for (i, use_compression) in compression_options.iter().enumerate() { + for _ in 0..10 { + let response = utils::get_transactions_with_proof( + &mut mock_client, + start_version, + end_version, + proof_version, + include_events, + *use_compression, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + assert_eq!(response.is_compressed(), *use_compression); + utils::verify_transaction_with_proof_response( + use_request_v2, + transaction_lists_with_proof[i].clone(), + response, + ); + } + } } } } #[tokio::test] async fn test_cachable_requests_data_versions() { - // Create test data - let start_versions = [0, 76, 101, 230, 300, 454]; - let end_version = 454; - let proof_version = end_version; - let include_events = false; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut transaction_lists_with_proof = vec![]; - for start_version in start_versions { - // Create and save test transaction lists - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - end_version, - proof_version, - include_events, - ); - transaction_lists_with_proof.push(transaction_list_with_proof.clone()); - - // Expect the data to be fetched from storage once - db_reader - .expect_get_transactions() - .times(1) - .with( - eq(start_version), - eq(end_version - start_version + 1), - eq(proof_version), - eq(include_events), - ) - .return_once(move |_, _, _, _| Ok(transaction_list_with_proof)) - .in_sequence(&mut expectation_sequence); - } - - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, end_version, 10); - tokio::spawn(service.start()); - - // Repeatedly fetch the data and verify the responses - for (i, start_version) in start_versions.iter().enumerate() { - for _ in 0..10 { - let response = utils::get_transactions_with_proof( - &mut mock_client, - *start_version, - end_version, - proof_version, - include_events, - true, - ) - .await - .unwrap(); - - // Verify the response is correct - match response { - StorageServiceResponse::CompressedResponse(_, _) => { - match response.get_data_response().unwrap() { - DataResponse::TransactionsWithProof(transactions_with_proof) => { - assert_eq!(transactions_with_proof, transaction_lists_with_proof[i]) - }, - _ => panic!( - "Expected compressed transactions with proof but got: {:?}", - response - ), - } - }, - _ => panic!("Expected compressed response but got: {:?}", response), - }; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let start_versions = [0, 76, 101, 230, 300, 454]; + let end_version = 454; + let proof_version = end_version; + let include_events = false; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + let mut transaction_lists_with_proof = vec![]; + for start_version in start_versions { + // Create and save test transaction lists + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + include_events, + use_request_v2, + ); + transaction_lists_with_proof.push(transaction_list_with_proof.clone()); + + // Expect the data to be fetched from storage once + utils::expect_get_transactions( + &mut db_reader, + start_version, + end_version - start_version + 1, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, end_version, 10); + tokio::spawn(service.start()); + + // Repeatedly fetch the data and verify the responses + for (i, start_version) in start_versions.iter().enumerate() { + for _ in 0..10 { + let response = utils::get_transactions_with_proof( + &mut mock_client, + *start_version, + end_version, + proof_version, + include_events, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + assert!(response.is_compressed()); + utils::verify_transaction_with_proof_response( + use_request_v2, + transaction_lists_with_proof[i].clone(), + response, + ); + } + } } } } @@ -195,7 +207,9 @@ async fn test_cachable_requests_eviction() { } // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); + let storage_config = utils::create_storage_config(false, false); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); utils::update_storage_server_summary(&mut service, version + 10, 10); tokio::spawn(service.start()); diff --git a/state-sync/storage-service/server/src/tests/epoch_ending.rs b/state-sync/storage-service/server/src/tests/epoch_ending.rs index da3ec8f198c..066e5963d53 100644 --- a/state-sync/storage-service/server/src/tests/epoch_ending.rs +++ b/state-sync/storage-service/server/src/tests/epoch_ending.rs @@ -1,7 +1,11 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::tests::{mock, mock::MockClient, utils}; +use crate::tests::{ + mock, + mock::{MockClient, MockDatabaseReader}, + utils, +}; use aptos_bitvec::BitVec; use aptos_config::config::StorageServiceConfig; use aptos_crypto::HashValue; @@ -22,12 +26,71 @@ use rand::Rng; #[tokio::test] async fn test_get_epoch_ending_ledger_infos() { - // Test small and large chunk requests - let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; - for chunk_size in [1, 100, max_epoch_chunk_size] { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test small and large chunk requests + let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; + for chunk_size in [1, 100, max_epoch_chunk_size] { + // Create test data + let start_epoch = 11; + let expected_end_epoch = start_epoch + chunk_size - 1; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: create_epoch_ending_ledger_infos( + start_epoch, + expected_end_epoch, + ), + more: false, + }; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + start_epoch, + expected_end_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let storage_service_config = + utils::create_storage_config(false, use_size_and_time_aware_chunking); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); + tokio::spawn(service.start()); + + // Create a request to fetch epoch ending ledger infos + let data_request = + DataRequest::GetEpochEndingLedgerInfos(EpochEndingLedgerInfoRequest { + start_epoch, + expected_end_epoch, + }); + let storage_request = StorageServiceRequest::new(data_request, true); + + // Process the request + let response = mock_client.process_request(storage_request).await.unwrap(); + + // Verify the response is correct + match response.get_data_response().unwrap() { + DataResponse::EpochEndingLedgerInfos(response_epoch_change_proof) => { + assert_eq!(response_epoch_change_proof, epoch_change_proof) + }, + _ => panic!("Expected epoch ending ledger infos but got: {:?}", response), + }; + } + } +} + +#[tokio::test] +async fn test_get_epoch_ending_ledger_infos_chunk_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { // Create test data + let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; + let chunk_size = max_epoch_chunk_size * 10; // Set a chunk request larger than the max let start_epoch = 11; - let expected_end_epoch = start_epoch + chunk_size - 1; + let expected_end_epoch = start_epoch + max_epoch_chunk_size - 1; let epoch_change_proof = EpochChangeProof { ledger_info_with_sigs: create_epoch_ending_ledger_infos( start_epoch, @@ -43,20 +106,25 @@ async fn test_get_epoch_ending_ledger_infos() { start_epoch, expected_end_epoch + 1, epoch_change_proof.clone(), + use_size_and_time_aware_chunking, ); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); - tokio::spawn(service.start()); - // Create a request to fetch epoch ending ledger infos + let expected_end_epoch = start_epoch + chunk_size - 1; let data_request = DataRequest::GetEpochEndingLedgerInfos(EpochEndingLedgerInfoRequest { start_epoch, expected_end_epoch, }); let storage_request = StorageServiceRequest::new(data_request, true); + // Create the storage client and server + let storage_service_config = + utils::create_storage_config(false, use_size_and_time_aware_chunking); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); + tokio::spawn(service.start()); + // Process the request let response = mock_client.process_request(storage_request).await.unwrap(); @@ -70,52 +138,6 @@ async fn test_get_epoch_ending_ledger_infos() { } } -#[tokio::test] -async fn test_get_epoch_ending_ledger_infos_chunk_limit() { - // Create test data - let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; - let chunk_size = max_epoch_chunk_size * 10; // Set a chunk request larger than the max - let start_epoch = 11; - let expected_end_epoch = start_epoch + max_epoch_chunk_size - 1; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: create_epoch_ending_ledger_infos(start_epoch, expected_end_epoch), - more: false, - }; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - start_epoch, - expected_end_epoch + 1, - epoch_change_proof.clone(), - ); - - // Create a request to fetch epoch ending ledger infos - let expected_end_epoch = start_epoch + chunk_size - 1; - let data_request = DataRequest::GetEpochEndingLedgerInfos(EpochEndingLedgerInfoRequest { - start_epoch, - expected_end_epoch, - }); - let storage_request = StorageServiceRequest::new(data_request, true); - - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); - tokio::spawn(service.start()); - - // Process the request - let response = mock_client.process_request(storage_request).await.unwrap(); - - // Verify the response is correct - match response.get_data_response().unwrap() { - DataResponse::EpochEndingLedgerInfos(response_epoch_change_proof) => { - assert_eq!(response_epoch_change_proof, epoch_change_proof) - }, - _ => panic!("Expected epoch ending ledger infos but got: {:?}", response), - }; -} - #[tokio::test] async fn test_get_epoch_ending_ledger_infos_invalid() { // Create the storage client and server @@ -206,7 +228,7 @@ fn create_epoch_ending_ledger_infos_using_sizes( // Generate random bytes of the given size let mut rng = rand::thread_rng(); let random_bytes: Vec = (0..min_bytes_per_ledger_info) - .map(|_| rng.gen::()) + .map(|_| rng.r#gen::()) .collect(); // Create the ledger infos with signatures @@ -222,66 +244,112 @@ fn create_epoch_ending_ledger_infos_using_sizes( /// A helper method to request a states with proof chunk using the /// the specified network limit. async fn get_epoch_ending_ledger_infos_network_limit(network_limit_bytes: u64) { - for use_compression in [true, false] { - // Create test data - let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; - let min_bytes_per_ledger_info = 5000; - let start_epoch = 98754; - let expected_end_epoch = start_epoch + max_epoch_chunk_size - 1; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut chunk_size = max_epoch_chunk_size; - while chunk_size >= 1 { - let ledger_info_with_sigs = - create_epoch_ending_ledger_infos_using_sizes(chunk_size, min_bytes_per_ledger_info); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs, - more: false, + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + for use_compression in [true, false] { + // Create test data + let max_epoch_chunk_size = StorageServiceConfig::default().max_epoch_chunk_size; + let min_bytes_per_ledger_info = 5000; + let start_epoch = 98754; + let expected_end_epoch = start_epoch + max_epoch_chunk_size - 1; + + // Create the mock db reader + let db_reader = create_mock_db_with_epoch_ending_expectations( + max_epoch_chunk_size, + min_bytes_per_ledger_info, + start_epoch, + use_size_and_time_aware_chunking, + ); + + // Create a storage config with the specified max network byte limit + let storage_config = StorageServiceConfig { + max_network_chunk_bytes: network_limit_bytes, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() }; - db_reader - .expect_get_epoch_ending_ledger_infos() - .times(1) - .with(eq(start_epoch), eq(start_epoch + chunk_size)) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _| Ok(epoch_change_proof.clone())); - chunk_size /= 2; + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); + tokio::spawn(service.start()); + + // Process a request to fetch epoch ending ledger infos + let data_request = + DataRequest::GetEpochEndingLedgerInfos(EpochEndingLedgerInfoRequest { + start_epoch, + expected_end_epoch, + }); + let storage_request = StorageServiceRequest::new(data_request, use_compression); + let response = mock_client.process_request(storage_request).await.unwrap(); + + // Verify the response adheres to the network limits + match response.get_data_response().unwrap() { + DataResponse::EpochEndingLedgerInfos(epoch_change_proof) => { + let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; + let num_ledger_infos = epoch_change_proof.ledger_info_with_sigs.len() as u64; + if num_response_bytes > network_limit_bytes { + assert_eq!(num_ledger_infos, 1); // Data cannot be reduced more than a single item + } else { + let max_num_ledger_infos = network_limit_bytes / min_bytes_per_ledger_info; + assert!(num_ledger_infos <= max_num_ledger_infos); // Verify data fits correctly into the limit + } + }, + _ => panic!("Expected epoch ending ledger infos but got: {:?}", response), + } } + } +} - // Create a storage config with the specified max network byte limit - let storage_config = StorageServiceConfig { - max_network_chunk_bytes: network_limit_bytes, - ..Default::default() - }; +/// Creates a mock db reader with expectations for fetching epoch ending ledger infos +fn create_mock_db_with_epoch_ending_expectations( + mut chunk_size: u64, + min_bytes_per_ledger_info: u64, + start_epoch: u64, + use_size_and_time_aware_chunking: bool, +) -> MockDatabaseReader { + // Create the mock DB reader + let mut db_reader = mock::create_mock_db_reader(); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - utils::update_storage_server_summary(&mut service, 1000, expected_end_epoch); - tokio::spawn(service.start()); + // Create an epoch change proof with the initial chunk size + let ledger_info_with_sigs = + create_epoch_ending_ledger_infos_using_sizes(chunk_size, min_bytes_per_ledger_info); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs, + more: false, + }; - // Process a request to fetch epoch ending ledger infos - let data_request = DataRequest::GetEpochEndingLedgerInfos(EpochEndingLedgerInfoRequest { + // If size and time-aware chunking are enabled, expect iterator usage + if use_size_and_time_aware_chunking { + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, start_epoch, - expected_end_epoch, - }); - let storage_request = StorageServiceRequest::new(data_request, use_compression); - let response = mock_client.process_request(storage_request).await.unwrap(); + start_epoch + chunk_size, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + return db_reader; + } - // Verify the response adheres to the network limits - match response.get_data_response().unwrap() { - DataResponse::EpochEndingLedgerInfos(epoch_change_proof) => { - let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; - let num_ledger_infos = epoch_change_proof.ledger_info_with_sigs.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_ledger_infos, 1); // Data cannot be reduced more than a single item - } else { - let max_num_ledger_infos = network_limit_bytes / min_bytes_per_ledger_info; - assert!(num_ledger_infos <= max_num_ledger_infos); // Verify data fits correctly into the limit - } - }, - _ => panic!("Expected epoch ending ledger infos but got: {:?}", response), - } + // Otherwise, expect the legacy implementation that halves the chunk size until it fits + let mut expectation_sequence = Sequence::new(); + while chunk_size >= 1 { + let ledger_info_with_sigs = + create_epoch_ending_ledger_infos_using_sizes(chunk_size, min_bytes_per_ledger_info); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs, + more: false, + }; + + db_reader + .expect_get_epoch_ending_ledger_infos() + .times(1) + .with(eq(start_epoch), eq(start_epoch + chunk_size)) + .in_sequence(&mut expectation_sequence) + .returning(move |_, _| Ok(epoch_change_proof.clone())); + + chunk_size /= 2; } + + db_reader } diff --git a/state-sync/storage-service/server/src/tests/mock.rs b/state-sync/storage-service/server/src/tests/mock.rs index 2b3df621c1e..7c63c41b2ac 100644 --- a/state-sync/storage-service/server/src/tests/mock.rs +++ b/state-sync/storage-service/server/src/tests/mock.rs @@ -31,20 +31,25 @@ use aptos_storage_service_types::{ use aptos_time_service::{MockTimeService, TimeService}; use aptos_types::{ account_address::AccountAddress, - contract_event::EventWithVersion, + contract_event::{ContractEvent, EventWithVersion}, epoch_change::EpochChangeProof, event::EventKey, ledger_info::LedgerInfoWithSignatures, - proof::{AccumulatorConsistencyProof, SparseMerkleProof, TransactionAccumulatorSummary}, + proof::{ + AccumulatorConsistencyProof, SparseMerkleProof, TransactionAccumulatorRangeProof, + TransactionAccumulatorSummary, + }, state_proof::StateProof, state_store::{ state_key::StateKey, state_value::{StateValue, StateValueChunkWithProof}, }, transaction::{ - AccountOrderedTransactionsWithProof, TransactionListWithProof, - TransactionOutputListWithProof, TransactionWithProof, Version, + AccountOrderedTransactionsWithProof, PersistedAuxiliaryInfo, Transaction, TransactionInfo, + TransactionListWithProofV2, TransactionOutputListWithProofV2, TransactionWithProof, + Version, }, + write_set::WriteSet, PeerId, }; use futures::channel::{oneshot, oneshot::Receiver}; @@ -82,9 +87,11 @@ impl MockClient { state_sync_config.storage_service = storage_service_config; // Create the storage reader + let mock_time_service = TimeService::mock(); let storage_reader = StorageReader::new( storage_service_config, Arc::new(db_reader.unwrap_or_else(create_mock_db_reader)), + mock_time_service.clone(), ); // Setup the networks and the network events @@ -113,7 +120,6 @@ impl MockClient { // Create the storage service let peers_and_metadata = create_peers_and_metadata(network_ids); let executor = tokio::runtime::Handle::current(); - let mock_time_service = TimeService::mock(); let storage_server = StorageServiceServer::new( state_sync_config, executor, @@ -213,7 +219,7 @@ pub fn create_peers_and_metadata(network_ids: Vec) -> Arc NetworkId { let mut rng = OsRng; - let random_number: u8 = rng.gen(); + let random_number: u8 = rng.r#gen(); match random_number % 3 { 0 => NetworkId::Validator, 1 => NetworkId::Vfn, @@ -240,7 +246,7 @@ mock! { batch_size: u64, ledger_version: Version, fetch_events: bool, - ) -> aptos_storage_interface::Result; + ) -> aptos_storage_interface::Result; fn get_transaction_by_hash( &self, @@ -265,7 +271,7 @@ mock! { start_version: Version, limit: u64, ledger_version: Version, - ) -> aptos_storage_interface::Result; + ) -> aptos_storage_interface::Result; fn get_events( &self, @@ -354,6 +360,63 @@ mock! { fn get_epoch_snapshot_prune_window(&self) -> aptos_storage_interface::Result; fn is_state_merkle_pruner_enabled(&self) -> aptos_storage_interface::Result; + + fn get_persisted_auxiliary_info_iterator( + &self, + start_version: Version, + num_persisted_auxiliary_info: usize, + ) -> aptos_storage_interface::Result>>>; + + fn get_epoch_ending_ledger_info_iterator( + &self, + start_epoch: u64, + end_epoch: u64, + ) -> aptos_storage_interface::Result>>>; + + fn get_transaction_iterator( + &self, + start_version: Version, + limit: u64, + ) -> aptos_storage_interface::Result>>>; + + fn get_transaction_info_iterator( + &self, + start_version: Version, + limit: u64, + ) -> aptos_storage_interface::Result>>>; + + fn get_events_iterator( + &self, + start_version: Version, + limit: u64, + ) -> aptos_storage_interface::Result>>>>; + + fn get_write_set_iterator( + &self, + start_version: Version, + limit: u64, + ) -> aptos_storage_interface::Result>>>; + + fn get_transaction_accumulator_range_proof( + &self, + start_version: Version, + limit: u64, + ledger_version: Version, + ) -> aptos_storage_interface::Result; + + fn get_state_value_chunk_iter( + &self, + version: Version, + first_index: usize, + chunk_size: usize, + ) -> aptos_storage_interface::Result>>>; + + fn get_state_value_chunk_proof( + &self, + version: Version, + first_index: usize, + state_key_values: Vec<(StateKey, StateValue)>, + ) -> aptos_storage_interface::Result; } } diff --git a/state-sync/storage-service/server/src/tests/mod.rs b/state-sync/storage-service/server/src/tests/mod.rs index af71f856efd..da74a782d85 100644 --- a/state-sync/storage-service/server/src/tests/mod.rs +++ b/state-sync/storage-service/server/src/tests/mod.rs @@ -1,6 +1,8 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +// TODO(joshlind): once the latest features are stabilized, remove the legacy features and tests!! + mod cache; mod epoch_ending; mod mock; @@ -11,6 +13,7 @@ mod number_of_states; mod optimistic_fetch; mod protocol_version; mod request_moderator; +mod response_progress_tracker; mod state_values; mod storage_summary; mod subscribe_transaction_outputs; diff --git a/state-sync/storage-service/server/src/tests/new_transaction_outputs.rs b/state-sync/storage-service/server/src/tests/new_transaction_outputs.rs index d46c93c98d7..b01c8cdb985 100644 --- a/state-sync/storage-service/server/src/tests/new_transaction_outputs.rs +++ b/state-sync/storage-service/server/src/tests/new_transaction_outputs.rs @@ -15,305 +15,416 @@ use futures::channel::oneshot::Receiver; #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transaction_outputs() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [1, 100, max_output_chunk_size] { - // Create test data - let highest_version = 5060; - let highest_epoch = 30; - let lowest_version = 101; - let peer_version = highest_version - chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - highest_version, - highest_version, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - output_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transaction outputs - let mut response_receiver = - get_new_outputs_with_proof(&mut mock_client, peer_version, highest_epoch).await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_list_with_proof, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [1, 100, max_output_chunk_size] { + // Create test data + let highest_version = 5060; + let highest_epoch = 30; + let lowest_version = 101; + let peer_version = highest_version - chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + highest_version - peer_version, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transaction outputs + let mut response_receiver = get_new_outputs_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + output_list_with_proof, + highest_ledger_info, + ) + .await; + } + } } } #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transaction_outputs_different_networks() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [100, max_output_chunk_size] { - // Create test data - let highest_version = 5060; - let highest_epoch = 30; - let lowest_version = 101; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 50); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof_1 = utils::create_output_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - ); - let output_list_with_proof_2 = utils::create_output_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - output_list_with_proof_1.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - output_list_with_proof_2.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transaction outputs for peer 1 - let peer_id = PeerId::random(); - let peer_network_1 = PeerNetworkId::new(NetworkId::Validator, peer_id); - let mut response_receiver_1 = get_new_outputs_with_proof_for_peer( - &mut mock_client, - peer_version_1, - highest_epoch, - Some(peer_network_1), - ) - .await; - - // Send a request to optimistically fetch new transaction outputs for peer 2 - let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); - let mut response_receiver_2 = get_new_outputs_with_proof_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - Some(peer_network_2), - ) - .await; - - // Wait until the optimistic fetches are active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver_1, - output_list_with_proof_1, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver_2, - output_list_with_proof_2, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [100, max_output_chunk_size] { + // Create test data + let highest_version = 5060; + let highest_epoch = 30; + let lowest_version = 101; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - (chunk_size - 50); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof_1 = utils::create_output_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let output_list_with_proof_2 = utils::create_output_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + output_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + output_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transaction outputs for peer 1 + let peer_id = PeerId::random(); + let peer_network_1 = PeerNetworkId::new(NetworkId::Validator, peer_id); + let mut response_receiver_1 = get_new_outputs_with_proof_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to optimistically fetch new transaction outputs for peer 2 + let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); + let mut response_receiver_2 = get_new_outputs_with_proof_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetches are active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + output_list_with_proof_1, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + output_list_with_proof_2, + highest_ledger_info, + ) + .await; + } + } } } -#[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transaction_outputs_epoch_change() { - // Create test data - let highest_version = 10000; - let highest_epoch = 10000; - let lowest_version = 0; - let peer_version = highest_version - 1000; - let peer_epoch = highest_epoch - 1000; - let epoch_change_version = peer_version + 1; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - output_list_with_proof.clone(), - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_get_new_transaction_outputs_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); tokio::spawn(service.start()); - // Send a request to optimistically fetch new transaction outputs - let response_receiver = - get_new_outputs_with_proof(&mut mock_client, peer_version, peer_epoch).await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( + // Send a new transaction output v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + let response_receiver = get_new_outputs_with_proof( &mut mock_client, - &mock_time, - &storage_service_notifier, + 0, + 0, + true, // use_request_v2 + storage_config.max_network_chunk_bytes_v2, ) .await; - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_list_with_proof, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); } #[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transaction_outputs_max_chunk() { - // Create a storage service config with a configured max chunk size - let max_transaction_output_chunk_size = 400; - let storage_service_config = StorageServiceConfig { - max_transaction_output_chunk_size, - ..StorageServiceConfig::default() - }; - - // Create test data - let highest_version = 65660; - let highest_epoch = 30; - let lowest_version = 101; - let requested_chunk_size = max_transaction_output_chunk_size + 100; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - peer_version + max_transaction_output_chunk_size, - highest_version, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - max_transaction_output_chunk_size, - highest_version, - output_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transaction outputs - let response_receiver = - get_new_outputs_with_proof(&mut mock_client, peer_version, highest_epoch).await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; +async fn test_get_new_transaction_outputs_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let highest_version = 10000; + let highest_epoch = 10000; + let lowest_version = 0; + let peer_version = highest_version - 1000; + let peer_epoch = highest_epoch - 1000; + let epoch_change_version = peer_version + 1; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transaction outputs + let response_receiver = get_new_outputs_with_proof( + &mut mock_client, + peer_version, + peer_epoch, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + output_list_with_proof, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } + } +} - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_list_with_proof, - highest_ledger_info, - ) - .await; +#[tokio::test(flavor = "multi_thread")] +async fn test_get_new_transaction_outputs_max_chunk() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config with a configured max chunk size + let max_transaction_output_chunk_size = 400; + let storage_service_config = StorageServiceConfig { + max_transaction_output_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..StorageServiceConfig::default() + }; + + // Create test data + let highest_version = 65660; + let highest_epoch = 30; + let lowest_version = 101; + let requested_chunk_size = max_transaction_output_chunk_size + 100; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + highest_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + max_transaction_output_chunk_size, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transaction outputs + let response_receiver = get_new_outputs_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + output_list_with_proof, + highest_ledger_info, + ) + .await; + } + } } /// Creates and sends a request for new transaction outputs @@ -321,8 +432,18 @@ async fn get_new_outputs_with_proof( mock_client: &mut MockClient, known_version: u64, known_epoch: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { - get_new_outputs_with_proof_for_peer(mock_client, known_version, known_epoch, None).await + get_new_outputs_with_proof_for_peer( + mock_client, + known_version, + known_epoch, + None, + use_request_v2, + max_response_bytes_v2, + ) + .await } /// Creates and sends a request for new transaction outputs for the specified peer @@ -331,13 +452,22 @@ async fn get_new_outputs_with_proof_for_peer( known_version: u64, known_epoch: u64, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request - let data_request = + let data_request = if use_request_v2 { + DataRequest::get_new_transaction_output_data_with_proof( + known_version, + known_epoch, + max_response_bytes_v2, + ) + } else { DataRequest::GetNewTransactionOutputsWithProof(NewTransactionOutputsWithProofRequest { known_version, known_epoch, - }); + }) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request diff --git a/state-sync/storage-service/server/src/tests/new_transactions.rs b/state-sync/storage-service/server/src/tests/new_transactions.rs index 0eed390bce1..eb0392ab30d 100644 --- a/state-sync/storage-service/server/src/tests/new_transactions.rs +++ b/state-sync/storage-service/server/src/tests/new_transactions.rs @@ -15,347 +15,449 @@ use futures::channel::oneshot::Receiver; #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transactions() { - // Test small and large chunk sizes - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - for chunk_size in [1, 100, max_transaction_chunk_size] { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version = highest_version - chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - highest_version, - highest_version, - include_events, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - highest_ledger_info.clone(), - lowest_version, - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - include_events, - transaction_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions - let mut response_receiver = get_new_transactions_with_proof( - &mut mock_client, - peer_version, - highest_epoch, - include_events, - ) - .await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + for chunk_size in [1, 100, max_transaction_chunk_size] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version = highest_version - chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + highest_version - peer_version, + highest_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = utils::create_storage_config( + use_request_v2, + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions + let mut response_receiver = get_new_transactions_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + include_events, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + highest_ledger_info, + ) + .await; + } + } } } } #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transactions_different_networks() { - // Test small and large chunk sizes - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - for chunk_size in [100, max_transaction_chunk_size] { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 10); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - include_events, - ); - let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - include_events, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - highest_ledger_info.clone(), - lowest_version, - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - include_events, - transaction_list_with_proof_1.clone(), - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - include_events, - transaction_list_with_proof_2.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions for peer 1 - let peer_id = PeerId::random(); - let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); - let mut response_receiver_1 = get_new_transactions_with_proof_for_peer( - &mut mock_client, - peer_version_1, - highest_epoch, - include_events, - Some(peer_network_1), - ) - .await; - - // Send a request to optimistically fetch new transactions for peer 2 - let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); - let mut response_receiver_2 = get_new_transactions_with_proof_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - include_events, - Some(peer_network_2), - ) - .await; - - // Wait until the optimistic fetches are active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data for both peers - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver_1, - transaction_list_with_proof_1, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver_2, - transaction_list_with_proof_2, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + for chunk_size in [100, max_transaction_chunk_size] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - (chunk_size - 10); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + include_events, + use_request_v2, + ); + let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + include_events, + transaction_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + include_events, + transaction_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = utils::create_storage_config( + use_request_v2, + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions for peer 1 + let peer_id = PeerId::random(); + let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); + let mut response_receiver_1 = get_new_transactions_with_proof_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + include_events, + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to optimistically fetch new transactions for peer 2 + let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); + let mut response_receiver_2 = get_new_transactions_with_proof_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + include_events, + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetches are active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data for both peers + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + transaction_list_with_proof_1, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + transaction_list_with_proof_2, + highest_ledger_info, + ) + .await; + } + } } } } -#[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transactions_epoch_change() { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 45576; - let highest_epoch = 1032; - let lowest_version = 4566; - let peer_version = highest_version - 100; - let peer_epoch = highest_epoch - 20; - let epoch_change_version = peer_version + 45; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - include_events, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - include_events, - transaction_list_with_proof.clone(), - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions - let response_receiver = get_new_transactions_with_proof( - &mut mock_client, - peer_version, - peer_epoch, - include_events, - ) - .await; +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_get_new_transactions_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Send a new transaction v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + let response_receiver = get_new_transactions_with_proof( + &mut mock_client, + 0, + 0, + true, + true, // use_request_v2 + 0, + ) + .await; - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); +} - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; +#[tokio::test(flavor = "multi_thread")] +async fn test_get_new_transactions_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 45576; + let highest_epoch = 1032; + let lowest_version = 4566; + let peer_version = highest_version - 100; + let peer_epoch = highest_epoch - 20; + let epoch_change_version = peer_version + 45; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions + let response_receiver = get_new_transactions_with_proof( + &mut mock_client, + peer_version, + peer_epoch, + include_events, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } + } } } #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transactions_max_chunk() { - // Create a storage service config with a configured max chunk size - let max_transaction_chunk_size = 200; - let storage_service_config = StorageServiceConfig { - max_transaction_chunk_size, - ..StorageServiceConfig::default() - }; - - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 1034556; - let highest_epoch = 343; - let lowest_version = 3453; - let requested_chunk_size = max_transaction_chunk_size + 1; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + max_transaction_chunk_size, - peer_version + max_transaction_chunk_size, - include_events, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - max_transaction_chunk_size, - highest_version, - include_events, - transaction_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions - let response_receiver = get_new_transactions_with_proof( - &mut mock_client, - peer_version, - highest_epoch, - include_events, - ) - .await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config with a configured max chunk size + let max_transaction_chunk_size = 200; + let storage_service_config = StorageServiceConfig { + max_transaction_chunk_size, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + enable_transaction_data_v2: use_request_v2, + ..StorageServiceConfig::default() + }; + + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 1034556; + let highest_epoch = 343; + let lowest_version = 3453; + let requested_chunk_size = max_transaction_chunk_size + 1; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + peer_version + max_transaction_chunk_size, + peer_version + max_transaction_chunk_size, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + max_transaction_chunk_size, + highest_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions + let response_receiver = get_new_transactions_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + include_events, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + highest_ledger_info, + ) + .await; + } + } } } @@ -365,6 +467,8 @@ async fn get_new_transactions_with_proof( known_version: u64, known_epoch: u64, include_events: bool, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { get_new_transactions_with_proof_for_peer( mock_client, @@ -372,6 +476,8 @@ async fn get_new_transactions_with_proof( known_epoch, include_events, None, + use_request_v2, + max_response_bytes_v2, ) .await } @@ -383,13 +489,24 @@ async fn get_new_transactions_with_proof_for_peer( known_epoch: u64, include_events: bool, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request - let data_request = DataRequest::GetNewTransactionsWithProof(NewTransactionsWithProofRequest { - known_version, - known_epoch, - include_events, - }); + let data_request = if use_request_v2 { + DataRequest::get_new_transaction_data_with_proof( + known_version, + known_epoch, + include_events, + max_response_bytes_v2, + ) + } else { + DataRequest::GetNewTransactionsWithProof(NewTransactionsWithProofRequest { + known_version, + known_epoch, + include_events, + }) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request diff --git a/state-sync/storage-service/server/src/tests/new_transactions_or_outputs.rs b/state-sync/storage-service/server/src/tests/new_transactions_or_outputs.rs index 3a5682045c9..cb14c742fd9 100644 --- a/state-sync/storage-service/server/src/tests/new_transactions_or_outputs.rs +++ b/state-sync/storage-service/server/src/tests/new_transactions_or_outputs.rs @@ -15,491 +15,611 @@ use futures::channel::oneshot::Receiver; #[tokio::test(flavor = "multi_thread")] async fn test_get_new_transactions_or_outputs() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [1, 100, max_output_chunk_size] { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 5060; - let highest_epoch = 30; - let lowest_version = 101; - let peer_version = highest_version - chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - highest_version, - highest_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - highest_version, - highest_version, - highest_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - highest_ledger_info.clone(), - lowest_version, - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - output_list_with_proof.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - false, - transaction_list_with_proof.clone(), - ); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [1, 100, max_output_chunk_size] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 5060; + let highest_epoch = 30; + let lowest_version = 101; + let peer_version = highest_version - chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + highest_version - peer_version, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + highest_version - peer_version, + highest_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions or outputs + let mut response_receiver = get_new_transactions_or_outputs_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + false, + 0, // Outputs cannot be reduced and will fallback to transactions + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some(transaction_list_with_proof), + None, + highest_ledger_info, + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_list_with_proof), + highest_ledger_info, + ) + .await; + } + } } + } + } +} - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions or outputs - let mut response_receiver = get_new_transactions_or_outputs_with_proof( - &mut mock_client, - peer_version, - highest_epoch, - false, - 0, // Outputs cannot be reduced and will fallback to transactions - ) - .await; - - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - Some(transaction_list_with_proof), - None, - highest_ledger_info, - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - None, - Some(output_list_with_proof), - highest_ledger_info, - ) - .await; +#[tokio::test(flavor = "multi_thread")] +async fn test_get_new_transactions_or_outputs_different_network() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [100, max_output_chunk_size] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 5060; + let highest_epoch = 30; + let lowest_version = 101; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - chunk_size + 1; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof_1 = utils::create_output_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let output_list_with_proof_2 = utils::create_output_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); + let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + output_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + output_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + false, + transaction_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + false, + transaction_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof_1, + &transaction_list_with_proof_1, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); + + // Send a request to optimistically fetch new transactions or outputs for peer 1 + let peer_id = PeerId::random(); + let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); + let mut response_receiver_1 = + get_new_transactions_or_outputs_with_proof_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + false, + 0, // Outputs cannot be reduced and will fallback to transactions + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to optimistically fetch new transactions or outputs for peer 1 + let peer_network_2 = PeerNetworkId::new(NetworkId::Validator, peer_id); + let mut response_receiver_2 = + get_new_transactions_or_outputs_with_proof_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + false, + 0, // Outputs cannot be reduced and will fallback to transactions + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the optimistic fetches are active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2) + .await; + + // Verify no optimistic fetch response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + Some(transaction_list_with_proof_1.clone()), + None, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + Some(transaction_list_with_proof_2.clone()), + None, + highest_ledger_info, + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + None, + Some(output_list_with_proof_1.clone()), + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + None, + Some(output_list_with_proof_2.clone()), + highest_ledger_info, + ) + .await; + } + } } } } } +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_get_new_transactions_or_outputs_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Send a new transaction or output v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + let response_receiver = get_new_transactions_or_outputs_with_proof( + &mut mock_client, + 0, + 0, + true, + 0, + true, // use_request_v2 + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); +} + #[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transactions_or_outputs_different_network() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [100, max_output_chunk_size] { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 5060; - let highest_epoch = 30; - let lowest_version = 101; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 50); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof_1 = utils::create_output_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - ); - let output_list_with_proof_2 = utils::create_output_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - highest_version, - highest_version, - highest_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - highest_ledger_info.clone(), - lowest_version, - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - output_list_with_proof_1.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - output_list_with_proof_2.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, +async fn test_get_new_transactions_or_outputs_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 10000; + let highest_epoch = 10000; + let lowest_version = 0; + let peer_version = highest_version - 1000; + let peer_epoch = highest_epoch - 1000; + let epoch_change_version = peer_version + 1; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, false, - transaction_list_with_proof.clone(), + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, ); - utils::expect_get_transactions( + utils::expect_get_epoch_ending_ledger_infos( &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - false, - transaction_list_with_proof.clone(), + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, ); - } + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof_1, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transactions or outputs for peer 1 - let peer_id = PeerId::random(); - let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); - let mut response_receiver_1 = get_new_transactions_or_outputs_with_proof_for_peer( - &mut mock_client, - peer_version_1, - highest_epoch, - false, - 0, // Outputs cannot be reduced and will fallback to transactions - Some(peer_network_1), - ) - .await; - - // Send a request to optimistically fetch new transactions or outputs for peer 1 - let peer_network_2 = PeerNetworkId::new(NetworkId::Validator, peer_id); - let mut response_receiver_2 = get_new_transactions_or_outputs_with_proof_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - false, - 0, // Outputs cannot be reduced and will fallback to transactions - Some(peer_network_2), - ) - .await; - - // Wait until the optimistic fetches are active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 2).await; - - // Verify no optimistic fetch response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver_1, - Some(transaction_list_with_proof.clone()), - None, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver_2, - Some(transaction_list_with_proof), - None, - highest_ledger_info, - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( + // Send a request to optimistically fetch new transaction outputs + let response_receiver = get_new_transactions_or_outputs_with_proof( &mut mock_client, - response_receiver_1, - None, - Some(output_list_with_proof_1.clone()), - highest_ledger_info.clone(), + peer_version, + peer_epoch, + false, + 5, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, ) .await; - utils::verify_new_transactions_or_outputs_with_proof( + + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; + + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( &mut mock_client, - response_receiver_2, - None, - Some(output_list_with_proof_2.clone()), - highest_ledger_info, + &mock_time, + &storage_service_notifier, ) .await; + + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some(transaction_list_with_proof), + None, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_list_with_proof), + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } } } } } #[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transactions_or_outputs_epoch_change() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 10000; - let highest_epoch = 10000; - let lowest_version = 0; - let peer_version = highest_version - 1000; - let peer_epoch = highest_epoch - 1000; - let epoch_change_version = peer_version + 1; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + 1, - epoch_change_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - output_list_with_proof.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - false, - transaction_list_with_proof.clone(), - ); - } +async fn test_get_new_transactions_or_outputs_max_chunk() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 65660; + let highest_epoch = 30; + let lowest_version = 101; + let max_transaction_output_chunk_size = 600; + let requested_chunk_size = max_transaction_output_chunk_size + 1; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + peer_version + max_transaction_output_chunk_size, + false, + use_request_v2, + ); - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transaction outputs - let response_receiver = get_new_transactions_or_outputs_with_proof( - &mut mock_client, - peer_version, - peer_epoch, - false, - 5, - ) - .await; + // Create the mock db reader + let max_num_output_reductions = 5; + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + for i in 0..=max_num_output_reductions { + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + (max_transaction_output_chunk_size as u32 / (u32::pow(2, i as u32))) as u64, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + if use_size_and_time_aware_chunking { + break; // Size and time-aware chunking only makes one attempt + } + } + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + max_transaction_output_chunk_size, + highest_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage service config + let mut storage_service_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + storage_service_config.max_transaction_output_chunk_size = + max_transaction_output_chunk_size; - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_optimistic_fetches = service.get_optimistic_fetches(); + tokio::spawn(service.start()); - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - Some(transaction_list_with_proof), - None, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - None, - Some(output_list_with_proof), - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; - } - } -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_get_new_transactions_or_outputs_max_chunk() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 65660; - let highest_epoch = 30; - let lowest_version = 101; - let max_transaction_output_chunk_size = 600; - let requested_chunk_size = max_transaction_output_chunk_size + 1; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - peer_version + max_transaction_output_chunk_size, - highest_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + 1, - peer_version + max_transaction_output_chunk_size, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let max_num_output_reductions = 5; - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..=max_num_output_reductions { - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - (max_transaction_output_chunk_size as u32 / (u32::pow(2, i as u32))) as u64, - highest_version, - output_list_with_proof.clone(), - ); - } - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - max_transaction_output_chunk_size, - highest_version, - false, - transaction_list_with_proof.clone(), - ); - } + // Send a request to optimistically fetch new transaction outputs + let response_receiver = get_new_transactions_or_outputs_with_proof( + &mut mock_client, + peer_version, + highest_epoch, + false, + max_num_output_reductions, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Create the storage service config - let mut storage_service_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - storage_service_config.max_transaction_output_chunk_size = - max_transaction_output_chunk_size; - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_optimistic_fetches = service.get_optimistic_fetches(); - tokio::spawn(service.start()); - - // Send a request to optimistically fetch new transaction outputs - let response_receiver = get_new_transactions_or_outputs_with_proof( - &mut mock_client, - peer_version, - highest_epoch, - false, - max_num_output_reductions, - ) - .await; + // Wait until the optimistic fetch is active + utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1) + .await; - // Wait until the optimistic fetch is active - utils::wait_for_active_optimistic_fetches(active_optimistic_fetches.clone(), 1).await; + // Force the optimistic fetch handler to work + utils::force_optimistic_fetch_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Force the optimistic fetch handler to work - utils::force_optimistic_fetch_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - Some(transaction_list_with_proof), - None, - highest_ledger_info, - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - None, - Some(output_list_with_proof), - highest_ledger_info, - ) - .await; + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some(transaction_list_with_proof), + None, + highest_ledger_info, + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_list_with_proof), + highest_ledger_info, + ) + .await; + } + } } } } @@ -511,6 +631,8 @@ async fn get_new_transactions_or_outputs_with_proof( known_epoch: u64, include_events: bool, max_num_output_reductions: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { get_new_transactions_or_outputs_with_proof_for_peer( mock_client, @@ -519,6 +641,8 @@ async fn get_new_transactions_or_outputs_with_proof( include_events, max_num_output_reductions, None, + use_request_v2, + max_response_bytes_v2, ) .await } @@ -531,16 +655,27 @@ async fn get_new_transactions_or_outputs_with_proof_for_peer( include_events: bool, max_num_output_reductions: u64, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request - let data_request = DataRequest::GetNewTransactionsOrOutputsWithProof( - NewTransactionsOrOutputsWithProofRequest { + let data_request = if use_request_v2 { + DataRequest::get_new_transaction_or_output_data_with_proof( known_version, known_epoch, include_events, - max_num_output_reductions, - }, - ); + max_response_bytes_v2, + ) + } else { + DataRequest::GetNewTransactionsOrOutputsWithProof( + NewTransactionsOrOutputsWithProofRequest { + known_version, + known_epoch, + include_events, + max_num_output_reductions, + }, + ) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request diff --git a/state-sync/storage-service/server/src/tests/optimistic_fetch.rs b/state-sync/storage-service/server/src/tests/optimistic_fetch.rs index dd55311ca91..e69f54e1b2a 100644 --- a/state-sync/storage-service/server/src/tests/optimistic_fetch.rs +++ b/state-sync/storage-service/server/src/tests/optimistic_fetch.rs @@ -33,388 +33,465 @@ use tokio::runtime::Handle; #[tokio::test] async fn test_peers_with_ready_optimistic_fetches() { - // Create a mock time service - let time_service = TimeService::mock(); - - // Create two peers and optimistic fetch requests - let peer_network_1 = PeerNetworkId::random(); - let peer_network_2 = PeerNetworkId::random(); - let optimistic_fetch_1 = - create_optimistic_fetch_request(time_service.clone(), Some(1), Some(1)); - let optimistic_fetch_2 = - create_optimistic_fetch_request(time_service.clone(), Some(10), Some(1)); - - // Insert the optimistic fetches into the pending map - let optimistic_fetches = Arc::new(DashMap::new()); - optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); - optimistic_fetches.insert(peer_network_2, optimistic_fetch_2); - - // Create epoch ending test data - let epoch_ending_ledger_info = utils::create_epoch_ending_ledger_info(1, 5); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![epoch_ending_ledger_info], - more: false, - }; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_epoch_ending_ledger_infos(&mut db_reader, 1, 2, epoch_change_proof); - - // Create the storage reader - let storage_service_config = StorageServiceConfig::default(); - let storage_reader = StorageReader::new(storage_service_config, Arc::new(db_reader)); - - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - storage_service_config, - time_service.clone(), - )); - let subscriptions = Arc::new(DashMap::new()); - - // Verify that there are no peers with ready optimistic fetches - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a mock time service + let time_service = TimeService::mock(); + + // Create two peers and optimistic fetch requests + let peer_network_1 = PeerNetworkId::random(); + let peer_network_2 = PeerNetworkId::random(); + let optimistic_fetch_1 = + create_optimistic_fetch_request(time_service.clone(), Some(1), Some(1), use_request_v2); + let optimistic_fetch_2 = create_optimistic_fetch_request( time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_optimistic_fetches.is_empty()); - - // Update the storage server summary so that there is new data for optimistic fetch 1 - let synced_ledger_info = - utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 2, 1); - - // Verify that optimistic fetch 1 is ready - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), + Some(10), + Some(1), + use_request_v2, + ); + + // Insert the optimistic fetches into the pending map + let optimistic_fetches = Arc::new(DashMap::new()); + optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); + optimistic_fetches.insert(peer_network_2, optimistic_fetch_2); + + // Create epoch ending test data + let epoch_ending_ledger_info = utils::create_epoch_ending_ledger_info(1, 5); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![epoch_ending_ledger_info], + more: false, + }; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + 1, + 2, + epoch_change_proof, + false, + ); + + // Create the storage reader + let storage_service_config = utils::create_storage_config(use_request_v2, false); + let storage_reader = StorageReader::new( storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), + Arc::new(db_reader), time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_optimistic_fetches, vec![( - peer_network_1, - synced_ledger_info - )]); - - // Manually remove optimistic fetch 1 from the map - optimistic_fetches.remove(&peer_network_1); - - // Update the storage server summary so that there is new data for optimistic fetch 2, - // but the optimistic fetch is invalid because it doesn't respect an epoch boundary. - let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 100, 2); - - // Verify that optimistic fetch 2 is not returned because it was invalid - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), + ); + + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), + cached_storage_server_summary.clone(), + mock::create_peers_and_metadata(vec![]), storage_service_config, - cached_storage_server_summary, - optimistic_fetches, - lru_response_cache, - request_moderator, - storage_reader, - subscriptions, - time_service, - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_optimistic_fetches, vec![]); - - // Verify that optimistic fetches no longer contains peer 2 - assert!(peers_with_ready_optimistic_fetches.is_empty()); + time_service.clone(), + )); + let subscriptions = Arc::new(DashMap::new()); + + // Verify that there are no peers with ready optimistic fetches + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_optimistic_fetches.is_empty()); + + // Update the storage server summary so that there is new data for optimistic fetch 1 + let synced_ledger_info = + utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 2, 1); + + // Verify that optimistic fetch 1 is ready + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_optimistic_fetches, vec![( + peer_network_1, + synced_ledger_info + )]); + + // Manually remove optimistic fetch 1 from the map + optimistic_fetches.remove(&peer_network_1); + + // Update the storage server summary so that there is new data for optimistic fetch 2, + // but the optimistic fetch is invalid because it doesn't respect an epoch boundary. + let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 100, 2); + + // Verify that optimistic fetch 2 is not returned because it was invalid + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary, + optimistic_fetches, + lru_response_cache, + request_moderator, + storage_reader, + subscriptions, + time_service, + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_optimistic_fetches, vec![]); + + // Verify that optimistic fetches no longer contains peer 2 + assert!(peers_with_ready_optimistic_fetches.is_empty()); + } } #[tokio::test] async fn test_peers_with_ready_optimistic_fetches_update() { - // Create a mock time service - let time_service = TimeService::mock(); - - // Create two peers and optimistic fetch requests - let peer_network_1 = PeerNetworkId::random(); - let peer_network_2 = PeerNetworkId::random(); - let optimistic_fetch_1 = - create_optimistic_fetch_request(time_service.clone(), Some(1), Some(1)); - let optimistic_fetch_2 = - create_optimistic_fetch_request(time_service.clone(), Some(10), Some(1)); - - // Insert the optimistic fetches into the pending map - let optimistic_fetches = Arc::new(DashMap::new()); - optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); - optimistic_fetches.insert(peer_network_2, optimistic_fetch_2); - - // Create the storage reader - let db_reader = mock::create_mock_db_reader(); - let storage_service_config = StorageServiceConfig::default(); - let storage_reader = StorageReader::new(storage_service_config, Arc::new(db_reader)); - - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - storage_service_config, - time_service.clone(), - )); - let subscriptions = Arc::new(DashMap::new()); - - // Update the storage server summary so that there is new data for optimistic fetch 1 - let highest_synced_version = 5; - let synced_ledger_info = utils::update_storage_summary_cache( - cached_storage_server_summary.clone(), - highest_synced_version, - 1, - ); - - // Verify that optimistic fetch 1 is ready - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a mock time service + let time_service = TimeService::mock(); + + // Create two peers and optimistic fetch requests + let peer_network_1 = PeerNetworkId::random(); + let peer_network_2 = PeerNetworkId::random(); + let optimistic_fetch_1 = + create_optimistic_fetch_request(time_service.clone(), Some(1), Some(1), use_request_v2); + let optimistic_fetch_2 = create_optimistic_fetch_request( + time_service.clone(), + Some(10), + Some(1), + use_request_v2, + ); + + // Insert the optimistic fetches into the pending map + let optimistic_fetches = Arc::new(DashMap::new()); + optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); + optimistic_fetches.insert(peer_network_2, optimistic_fetch_2); + + // Create the storage reader + let db_reader = mock::create_mock_db_reader(); + let storage_service_config = StorageServiceConfig::default(); + let storage_reader = StorageReader::new( storage_service_config, + Arc::new(db_reader), + time_service.clone(), + ); + + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), + mock::create_peers_and_metadata(vec![]), + storage_service_config, time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_optimistic_fetches, vec![( - peer_network_1, - synced_ledger_info - )]); - - // Update optimistic fetch 1 to have a new higher known version - let optimistic_fetch_1 = create_optimistic_fetch_request( - time_service.clone(), - Some(highest_synced_version), - Some(1), - ); - optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); - - // Handle the ready optimistic fetches - optimistic_fetch::handle_ready_optimistic_fetches( - Handle::current(), - cached_storage_server_summary.clone(), - storage_service_config, - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - peers_with_ready_optimistic_fetches, - ) - .await; - - // Verify that there are still 2 optimistic fetches pending (the - // first one was not removed because it was updated!) - assert_eq!(optimistic_fetches.len(), 2); - - // Update the storage server summary so that there is new data for optimistic fetch 1 - let synced_ledger_info = utils::update_storage_summary_cache( - cached_storage_server_summary.clone(), - highest_synced_version + 1, - 1, - ); - - // Verify that optimistic fetch 1 is ready (again!) - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( + )); + let subscriptions = Arc::new(DashMap::new()); + + // Update the storage server summary so that there is new data for optimistic fetch 1 + let highest_synced_version = 5; + let synced_ledger_info = utils::update_storage_summary_cache( + cached_storage_server_summary.clone(), + highest_synced_version, + 1, + ); + + // Verify that optimistic fetch 1 is ready + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_optimistic_fetches, vec![( + peer_network_1, + synced_ledger_info + )]); + + // Update optimistic fetch 1 to have a new higher known version + let optimistic_fetch_1 = create_optimistic_fetch_request( + time_service.clone(), + Some(highest_synced_version), + Some(1), + use_request_v2, + ); + optimistic_fetches.insert(peer_network_1, optimistic_fetch_1); + + // Handle the ready optimistic fetches + optimistic_fetch::handle_ready_optimistic_fetches( Handle::current(), - storage_service_config, cached_storage_server_summary.clone(), + storage_service_config, optimistic_fetches.clone(), lru_response_cache.clone(), request_moderator.clone(), storage_reader.clone(), subscriptions.clone(), time_service.clone(), + peers_with_ready_optimistic_fetches, ) - .await - .unwrap(); - assert_eq!(peers_with_ready_optimistic_fetches, vec![( - peer_network_1, - synced_ledger_info - )]); -} - -#[tokio::test] -async fn test_remove_expired_optimistic_fetches() { - // Create a storage service config - let max_optimistic_fetch_period_ms = 100; - let storage_service_config = StorageServiceConfig { - max_optimistic_fetch_period_ms, - ..Default::default() - }; - - // Create the mock storage reader and time service - let db_reader = mock::create_mock_db_reader(); - let storage = StorageReader::new(storage_service_config, Arc::new(db_reader)); - let time_service = TimeService::mock(); - - // Create the test components - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - storage_service_config, - time_service.clone(), - )); - let subscriptions = Arc::new(DashMap::new()); - - // Create the first batch of test optimistic fetches - let num_optimistic_fetches_in_batch = 10; - let optimistic_fetches = Arc::new(DashMap::new()); - for _ in 0..num_optimistic_fetches_in_batch { - let optimistic_fetch = - create_optimistic_fetch_request(time_service.clone(), Some(9), Some(9)); - optimistic_fetches.insert(PeerNetworkId::random(), optimistic_fetch); - } - - // Verify the number of active optimistic fetches - assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); - - // Elapse a small amount of time (not enough to expire the optimistic fetches) - utils::elapse_time(max_optimistic_fetch_period_ms / 2, &time_service).await; + .await; - // Update the storage server summary so that there is new data - let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 1, 1); + // Verify that there are still 2 optimistic fetches pending (the + // first one was not removed because it was updated!) + assert_eq!(optimistic_fetches.len(), 2); - // Remove the expired optimistic fetches and verify none were removed - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), - storage_service_config, + // Update the storage server summary so that there is new data for optimistic fetch 1 + let synced_ledger_info = utils::update_storage_summary_cache( cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_optimistic_fetches.is_empty()); - assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); - - // Create another batch of optimistic fetches - for _ in 0..num_optimistic_fetches_in_batch { - let optimistic_fetch = - create_optimistic_fetch_request(time_service.clone(), Some(9), Some(9)); - optimistic_fetches.insert(PeerNetworkId::random(), optimistic_fetch); + highest_synced_version + 1, + 1, + ); + + // Verify that optimistic fetch 1 is ready (again!) + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_optimistic_fetches, vec![( + peer_network_1, + synced_ledger_info + )]); } +} - // Verify the new number of active optimistic fetches - assert_eq!( - optimistic_fetches.len(), - num_optimistic_fetches_in_batch * 2 - ); - - // Elapse enough time to expire the first batch of optimistic fetches - utils::elapse_time(max_optimistic_fetch_period_ms, &time_service).await; - - // Remove the expired optimistic fetches and verify the first batch was removed - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), +#[tokio::test] +async fn test_remove_expired_optimistic_fetches() { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_optimistic_fetch_period_ms = 100; + let storage_service_config = StorageServiceConfig { + max_optimistic_fetch_period_ms, + ..Default::default() + }; + + // Create the mock storage reader and time service + let db_reader = mock::create_mock_db_reader(); + let time_service = TimeService::mock(); + let storage = StorageReader::new( storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage.clone(), - subscriptions.clone(), + Arc::new(db_reader), time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_optimistic_fetches.is_empty()); - assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); - - // Elapse enough time to expire the second batch of optimistic fetches - utils::elapse_time(max_optimistic_fetch_period_ms + 1, &time_service).await; - - // Remove the expired optimistic fetches and verify the second batch was removed - let peers_with_ready_optimistic_fetches = - optimistic_fetch::get_peers_with_ready_optimistic_fetches( - Handle::current(), - storage_service_config, + ); + + // Create the test components + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache, - request_moderator, - storage.clone(), - subscriptions, + mock::create_peers_and_metadata(vec![]), + storage_service_config, time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_optimistic_fetches.is_empty()); - assert!(optimistic_fetches.is_empty()); + )); + let subscriptions = Arc::new(DashMap::new()); + + // Create the first batch of test optimistic fetches + let num_optimistic_fetches_in_batch = 10; + let optimistic_fetches = Arc::new(DashMap::new()); + for _ in 0..num_optimistic_fetches_in_batch { + let optimistic_fetch = create_optimistic_fetch_request( + time_service.clone(), + Some(9), + Some(9), + use_request_v2, + ); + optimistic_fetches.insert(PeerNetworkId::random(), optimistic_fetch); + } + + // Verify the number of active optimistic fetches + assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); + + // Elapse a small amount of time (not enough to expire the optimistic fetches) + utils::elapse_time(max_optimistic_fetch_period_ms / 2, &time_service).await; + + // Update the storage server summary so that there is new data + let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 1, 1); + + // Remove the expired optimistic fetches and verify none were removed + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_optimistic_fetches.is_empty()); + assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); + + // Create another batch of optimistic fetches + for _ in 0..num_optimistic_fetches_in_batch { + let optimistic_fetch = create_optimistic_fetch_request( + time_service.clone(), + Some(9), + Some(9), + use_request_v2, + ); + optimistic_fetches.insert(PeerNetworkId::random(), optimistic_fetch); + } + + // Verify the new number of active optimistic fetches + assert_eq!( + optimistic_fetches.len(), + num_optimistic_fetches_in_batch * 2 + ); + + // Elapse enough time to expire the first batch of optimistic fetches + utils::elapse_time(max_optimistic_fetch_period_ms, &time_service).await; + + // Remove the expired optimistic fetches and verify the first batch was removed + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_optimistic_fetches.is_empty()); + assert_eq!(optimistic_fetches.len(), num_optimistic_fetches_in_batch); + + // Elapse enough time to expire the second batch of optimistic fetches + utils::elapse_time(max_optimistic_fetch_period_ms + 1, &time_service).await; + + // Remove the expired optimistic fetches and verify the second batch was removed + let peers_with_ready_optimistic_fetches = + optimistic_fetch::get_peers_with_ready_optimistic_fetches( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache, + request_moderator, + storage.clone(), + subscriptions, + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_optimistic_fetches.is_empty()); + assert!(optimistic_fetches.is_empty()); + } } /// Creates a random request for optimistic fetch data fn create_optimistic_fetch_data_request( known_version: Option, known_epoch: Option, + use_request_v2: bool, ) -> DataRequest { let known_version = known_version.unwrap_or_default(); let known_epoch = known_epoch.unwrap_or_default(); // Generate the random data request let mut rng = OsRng; - let random_number: u8 = rng.gen(); + let random_number: u8 = rng.r#gen(); match random_number % 3 { - 0 => DataRequest::GetNewTransactionsWithProof(NewTransactionsWithProofRequest { - known_version, - known_epoch, - include_events: false, - }), + 0 => { + if use_request_v2 { + DataRequest::get_new_transaction_data_with_proof( + known_version, + known_epoch, + true, + 0, + ) + } else { + DataRequest::GetNewTransactionsWithProof(NewTransactionsWithProofRequest { + known_version, + known_epoch, + include_events: true, + }) + } + }, 1 => { - DataRequest::GetNewTransactionOutputsWithProof(NewTransactionOutputsWithProofRequest { - known_version, - known_epoch, - }) + if use_request_v2 { + DataRequest::get_new_transaction_output_data_with_proof( + known_version, + known_epoch, + 0, + ) + } else { + DataRequest::GetNewTransactionOutputsWithProof( + NewTransactionOutputsWithProofRequest { + known_version, + known_epoch, + }, + ) + } + }, + 2 => { + if use_request_v2 { + DataRequest::get_new_transaction_or_output_data_with_proof( + known_version, + known_epoch, + true, + 0, + ) + } else { + DataRequest::GetNewTransactionsOrOutputsWithProof( + NewTransactionsOrOutputsWithProofRequest { + known_version, + known_epoch, + include_events: true, + max_num_output_reductions: 1, + }, + ) + } }, - 2 => DataRequest::GetNewTransactionsOrOutputsWithProof( - NewTransactionsOrOutputsWithProofRequest { - known_version, - known_epoch, - include_events: true, - max_num_output_reductions: 1, - }, - ), num => panic!("This shouldn't be possible! Got num: {:?}", num), } } @@ -424,9 +501,11 @@ fn create_optimistic_fetch_request( time_service: TimeService, known_version: Option, known_epoch: Option, + use_request_v2: bool, ) -> OptimisticFetchRequest { // Create a storage service request - let data_request = create_optimistic_fetch_data_request(known_version, known_epoch); + let data_request = + create_optimistic_fetch_data_request(known_version, known_epoch, use_request_v2); let storage_service_request = StorageServiceRequest::new(data_request, true); // Create the response sender diff --git a/state-sync/storage-service/server/src/tests/response_progress_tracker.rs b/state-sync/storage-service/server/src/tests/response_progress_tracker.rs new file mode 100644 index 00000000000..d41abc3405a --- /dev/null +++ b/state-sync/storage-service/server/src/tests/response_progress_tracker.rs @@ -0,0 +1,151 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::storage::ResponseDataProgressTracker; +use aptos_time_service::TimeService; + +#[test] +fn data_items_fits_in_response() { + // Create a response progress tracker + let max_response_size = 2000; + let time_service = TimeService::mock(); + let mut response_progress_tracker = ResponseDataProgressTracker::new( + 100, // Number of items to fetch + max_response_size, + 5000, // Max storage read wait time + time_service.clone(), + ); + + // Verify that an item can only overflow the response size if "always_allow_first_item" is true + let large_data_item_size = max_response_size * 2; + assert!(!response_progress_tracker.data_items_fits_in_response(false, large_data_item_size)); + assert!(response_progress_tracker.data_items_fits_in_response(true, large_data_item_size)); + + // Add a small item to the response + let small_data_item_size = 1; + assert!(response_progress_tracker.data_items_fits_in_response(false, small_data_item_size)); + response_progress_tracker.add_data_item(small_data_item_size); + + // Verify that the response tracker will not overflow the response size (even if the flag is true) + assert!(!response_progress_tracker.data_items_fits_in_response(false, large_data_item_size)); + assert!(!response_progress_tracker.data_items_fits_in_response(true, large_data_item_size)); + + // Add several medium items that fit into the response (adds 1600 bytes in total, total will be 1601) + let medium_data_item_size = 400; + for _ in 0..4 { + assert!(response_progress_tracker.data_items_fits_in_response(false, medium_data_item_size)); + response_progress_tracker.add_data_item(medium_data_item_size); + } + + // Verify that the response tracker will not overflow the response size + assert!(!response_progress_tracker.data_items_fits_in_response(false, large_data_item_size)); + assert!(!response_progress_tracker.data_items_fits_in_response(false, medium_data_item_size)); + assert!(response_progress_tracker.data_items_fits_in_response(false, small_data_item_size)); + + // Verify that we can add another item that just fits into the response (i.e., the total size is < max_response_size) + let just_fits_data_item_size = 398; // 1601 + 398 = 1999 < 2000 + assert!(response_progress_tracker.data_items_fits_in_response(false, just_fits_data_item_size)); + response_progress_tracker.add_data_item(just_fits_data_item_size); + + // Verify that adding another small item (that would overflow the response size) is not allowed + assert!(!response_progress_tracker.data_items_fits_in_response(false, small_data_item_size)); +} + +#[test] +fn is_response_complete_all_items_fetched() { + // Create a response progress tracker + let num_items_to_fetch = 100; + let time_service = TimeService::mock(); + let mut response_progress_tracker = ResponseDataProgressTracker::new( + num_items_to_fetch, + 2000, // Max response size + 5000, // Max storage read wait time + time_service.clone(), + ); + + // Verify that the response is not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Add almost all items to the response tracker (but not enough to complete) + for _ in 0..num_items_to_fetch - 1 { + response_progress_tracker.add_data_item(10); + } + + // Verify that the response is not complete (still one item left to fetch) + assert!(!response_progress_tracker.is_response_complete()); + + // Add the last item to the response tracker + response_progress_tracker.add_data_item(10); + + // Verify that the response is complete (all items were fetched) + assert!(response_progress_tracker.is_response_complete()); + + // Continue to add items to the response tracker (this should not affect the completion status) + for _ in 0..10 { + response_progress_tracker.add_data_item(10); + assert!(response_progress_tracker.is_response_complete()); + } +} + +#[test] +fn is_response_complete_overflowed_data_size() { + // Create a response progress tracker + let max_response_size = 2000; + let time_service = TimeService::mock(); + let mut response_progress_tracker = ResponseDataProgressTracker::new( + 100, // Number of items to fetch + max_response_size, + 5000, // Max storage read wait time + time_service.clone(), + ); + + // Verify that the response is not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Add a small item to the response tracker (not enough to overflow the size) + response_progress_tracker.add_data_item(10); + + // Verify that the response is not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Add a large item to the response tracker (but not enough to overflow the size) + response_progress_tracker.add_data_item(max_response_size / 2); + + // Verify that the response is still not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Add another large item to exceed the max response size + response_progress_tracker.add_data_item(max_response_size / 2); + + // Verify that the response is complete (we overflowed the data size) + assert!(response_progress_tracker.is_response_complete()); +} + +#[test] +fn is_response_complete_overflowed_storage_read_duration() { + // Create a response progress tracker + let max_storage_read_wait_time_ms = 5000; + let time_service = TimeService::mock(); + let response_progress_tracker = ResponseDataProgressTracker::new( + 100, // Number of items to fetch + 2000, // Max response size + max_storage_read_wait_time_ms, + time_service.clone(), + ); + + // Verify that the response is not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Elapse some time (but not enough to overflow the storage read duration) + let mock_time_service = time_service.into_mock(); + mock_time_service.advance_ms(max_storage_read_wait_time_ms / 2); + + // Verify that the response is still not complete + assert!(!response_progress_tracker.is_response_complete()); + + // Elapse more time to exceed the max storage read wait time + mock_time_service.advance_ms(max_storage_read_wait_time_ms); + + // Verify that the response is complete (we overflowed the storage read duration) + assert!(response_progress_tracker.is_response_complete()); +} diff --git a/state-sync/storage-service/server/src/tests/state_values.rs b/state-sync/storage-service/server/src/tests/state_values.rs index b270de8bbe8..31f7e9617b2 100644 --- a/state-sync/storage-service/server/src/tests/state_values.rs +++ b/state-sync/storage-service/server/src/tests/state_values.rs @@ -19,24 +19,91 @@ use aptos_types::{ state_key::StateKey, state_value::{StateValue, StateValueChunkWithProof}, }, + transaction::Version, }; use bytes::Bytes; use claims::assert_matches; -use mockall::{predicate::eq, Sequence}; +use mockall::{ + predicate::{always, eq}, + Sequence, +}; use rand::Rng; #[tokio::test] async fn test_get_states_with_proof() { - // Test small and large chunk requests - let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; - for chunk_size in [1, 100, max_state_chunk_size] { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test small and large chunk requests + let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; + for chunk_size in [1, 100, max_state_chunk_size] { + // Create test data + let version = 101; + let start_index = 100; + let end_index = start_index + chunk_size - 1; + let state_value_chunk_with_proof = StateValueChunkWithProof { + first_index: start_index, + last_index: end_index, + first_key: HashValue::random(), + last_key: HashValue::random(), + raw_values: vec![], + proof: SparseMerkleRangeProof::new(vec![]), + root_hash: HashValue::random(), + }; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + expect_get_state_values_with_proof( + &mut db_reader, + version, + start_index, + chunk_size, + state_value_chunk_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(false, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, version, 10); + tokio::spawn(service.start()); + + // Process a request to fetch a states chunk with a proof + let response = get_state_values_with_proof( + &mut mock_client, + version, + start_index, + end_index, + false, + ) + .await + .unwrap(); + + // Verify the response is correct + assert_matches!(response, StorageServiceResponse::RawResponse(_)); + assert_eq!( + response.get_data_response().unwrap(), + DataResponse::StateValueChunkWithProof(state_value_chunk_with_proof) + ); + } + } +} + +#[tokio::test] +async fn test_get_states_with_proof_chunk_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { // Create test data + let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; + let chunk_size = max_state_chunk_size * 10; // Set a chunk request larger than the max let version = 101; let start_index = 100; - let end_index = start_index + chunk_size - 1; let state_value_chunk_with_proof = StateValueChunkWithProof { first_index: start_index, - last_index: end_index, + last_index: start_index + max_state_chunk_size - 1, first_key: HashValue::random(), last_key: HashValue::random(), raw_values: vec![], @@ -50,20 +117,30 @@ async fn test_get_states_with_proof() { &mut db_reader, version, start_index, - chunk_size, + max_state_chunk_size, state_value_chunk_with_proof.clone(), + use_size_and_time_aware_chunking, ); + // Create a storage service config + let storage_config = utils::create_storage_config(false, use_size_and_time_aware_chunking); + // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); utils::update_storage_server_summary(&mut service, version, 10); tokio::spawn(service.start()); // Process a request to fetch a states chunk with a proof - let response = - get_state_values_with_proof(&mut mock_client, version, start_index, end_index, false) - .await - .unwrap(); + let response = get_state_values_with_proof( + &mut mock_client, + version, + start_index, + start_index + chunk_size - 1, + false, + ) + .await + .unwrap(); // Verify the response is correct assert_matches!(response, StorageServiceResponse::RawResponse(_)); @@ -74,57 +151,6 @@ async fn test_get_states_with_proof() { } } -#[tokio::test] -async fn test_get_states_with_proof_chunk_limit() { - // Create test data - let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; - let chunk_size = max_state_chunk_size * 10; // Set a chunk request larger than the max - let version = 101; - let start_index = 100; - let state_value_chunk_with_proof = StateValueChunkWithProof { - first_index: start_index, - last_index: start_index + max_state_chunk_size - 1, - first_key: HashValue::random(), - last_key: HashValue::random(), - raw_values: vec![], - proof: SparseMerkleRangeProof::new(vec![]), - root_hash: HashValue::random(), - }; - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - expect_get_state_values_with_proof( - &mut db_reader, - version, - start_index, - max_state_chunk_size, - state_value_chunk_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, version, 10); - tokio::spawn(service.start()); - - // Process a request to fetch a states chunk with a proof - let response = get_state_values_with_proof( - &mut mock_client, - version, - start_index, - start_index + chunk_size - 1, - false, - ) - .await - .unwrap(); - - // Verify the response is correct - assert_matches!(response, StorageServiceResponse::RawResponse(_)); - assert_eq!( - response.get_data_response().unwrap(), - DataResponse::StateValueChunkWithProof(state_value_chunk_with_proof) - ); -} - #[tokio::test] async fn test_get_states_with_proof_invalid() { // Create the storage client and server @@ -145,7 +171,7 @@ async fn test_get_states_with_proof_invalid() { #[tokio::test] async fn test_get_states_with_proof_network_limit() { // Test different byte limits - for network_limit_bytes in [1, 512, 1024, 10 * 1024] { + for network_limit_bytes in [1, 500, 2500, 5500, 10 * 1024] { get_states_with_proof_network_limit(network_limit_bytes).await; } } @@ -184,7 +210,7 @@ fn create_state_keys_and_values( // Generate random bytes of the given size let mut rng = rand::thread_rng(); let random_bytes: Bytes = (0..min_bytes_per_key_value) - .map(|_| rng.gen::()) + .map(|_| rng.r#gen::()) .collect::>() .into(); @@ -197,23 +223,74 @@ fn create_state_keys_and_values( .collect() } +/// Creates a state value chunk with proof +fn create_state_value_chunk_with_proof( + start_index: u64, + chunk_size: u64, + min_bytes_per_state_value: u64, +) -> StateValueChunkWithProof { + StateValueChunkWithProof { + first_index: start_index, + last_index: start_index + chunk_size - 1, + first_key: HashValue::random(), + last_key: HashValue::random(), + raw_values: create_state_keys_and_values(chunk_size, min_bytes_per_state_value), + proof: SparseMerkleRangeProof::new(vec![]), + root_hash: HashValue::random(), + } +} + /// Sets an expectation on the given mock db for a call to fetch state values with proof fn expect_get_state_values_with_proof( mock_db: &mut MockDatabaseReader, version: u64, start_index: u64, chunk_size: u64, - state_value_chunk_with_proof: StateValueChunkWithProof, + mut state_value_chunk_with_proof: StateValueChunkWithProof, + use_size_and_time_aware_chunking: bool, ) { + // If size and time-aware chunking are disabled, expect the legacy implementation + if !use_size_and_time_aware_chunking { + mock_db + .expect_get_state_value_chunk_with_proof() + .times(1) + .with( + eq(version), + eq(start_index as usize), + eq(chunk_size as usize), + ) + .returning(move |_, _, _| Ok(state_value_chunk_with_proof.clone())); + return; + } + + // Expect a call to get a state value iterator + let mut expectation_sequence = Sequence::new(); + let state_value_iterator = state_value_chunk_with_proof + .clone() + .raw_values + .into_iter() + .map(Ok); mock_db - .expect_get_state_value_chunk_with_proof() + .expect_get_state_value_chunk_iter() .times(1) .with( eq(version), eq(start_index as usize), eq(chunk_size as usize), ) - .returning(move |_, _, _| Ok(state_value_chunk_with_proof.clone())); + .returning(move |_, _, _| Ok(Box::new(state_value_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get the state value chunk proof + mock_db + .expect_get_state_value_chunk_proof() + .times(1) + .with(eq(version), eq(start_index as usize), always()) + .return_once(move |_, _, given_state_values| { + state_value_chunk_with_proof.raw_values = given_state_values; + Ok(state_value_chunk_with_proof) + }) + .in_sequence(&mut expectation_sequence); } /// Sends a state values with proof request and processes the response @@ -235,76 +312,113 @@ async fn get_state_values_with_proof( /// A helper method to request a states with proof chunk using the /// the specified network limit. async fn get_states_with_proof_network_limit(network_limit_bytes: u64) { - for use_compression in [true, false] { - // Create test data - let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; - let min_bytes_per_state_value = 100; - let version = 101; - let start_index = 100; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + for use_compression in [true, false] { + // Create test data + let max_state_chunk_size = StorageServiceConfig::default().max_state_chunk_size; + let min_bytes_per_state_value = 1000; + let version = 101; + let start_index = 100; - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut chunk_size = max_state_chunk_size; - while chunk_size >= 1 { - let state_value_chunk_with_proof = StateValueChunkWithProof { - first_index: start_index, - last_index: start_index + chunk_size - 1, - first_key: HashValue::random(), - last_key: HashValue::random(), - raw_values: create_state_keys_and_values(chunk_size, min_bytes_per_state_value), - proof: SparseMerkleRangeProof::new(vec![]), - root_hash: HashValue::random(), + // Create the mock db reader + let db_reader = create_mock_db_with_state_value_expectations( + max_state_chunk_size, + min_bytes_per_state_value, + version, + start_index, + use_size_and_time_aware_chunking, + ); + + // Create a storage config with the specified max network byte limit + let storage_config = StorageServiceConfig { + max_network_chunk_bytes: network_limit_bytes, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() }; - db_reader - .expect_get_state_value_chunk_with_proof() - .times(1) - .with( - eq(version), - eq(start_index as usize), - eq(chunk_size as usize), - ) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _, _| Ok(state_value_chunk_with_proof.clone())); - chunk_size /= 2; + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, version, 10); + tokio::spawn(service.start()); + + // Process a request to fetch a states chunk with a proof + let response = get_state_values_with_proof( + &mut mock_client, + version, + start_index, + start_index + max_state_chunk_size + 1000, // Request more than the max chunk + use_compression, + ) + .await + .unwrap(); + + // Verify the response adheres to the network limits + match response.get_data_response().unwrap() { + DataResponse::StateValueChunkWithProof(state_value_chunk_with_proof) => { + let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; + let num_state_values = state_value_chunk_with_proof.raw_values.len() as u64; + if num_response_bytes > network_limit_bytes { + assert_eq!(num_state_values, 1); // Data cannot be reduced more than a single item + } else { + let max_num_state_values = network_limit_bytes / min_bytes_per_state_value; + assert!(num_state_values <= max_num_state_values); // Verify data fits correctly into the limit + } + }, + _ => panic!("Expected state values with proof but got: {:?}", response), + } } + } +} - // Create a storage config with the specified max network byte limit - let storage_config = StorageServiceConfig { - max_network_chunk_bytes: network_limit_bytes, - ..Default::default() - }; +/// Creates a mock db reader with expectations for fetching state values +fn create_mock_db_with_state_value_expectations( + mut chunk_size: u64, + min_bytes_per_state_value: u64, + version: Version, + start_index: u64, + use_size_and_time_aware_chunking: bool, +) -> MockDatabaseReader { + // Create the mock DB reader + let mut db_reader = mock::create_mock_db_reader(); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - utils::update_storage_server_summary(&mut service, version, 10); - tokio::spawn(service.start()); + // Create a state value chunk with proof using the initial chunk size + let state_value_chunk_with_proof = + create_state_value_chunk_with_proof(start_index, chunk_size, min_bytes_per_state_value); - // Process a request to fetch a states chunk with a proof - let response = get_state_values_with_proof( - &mut mock_client, + // If size and time-aware chunking are enabled, expect iterator usage + if use_size_and_time_aware_chunking { + expect_get_state_values_with_proof( + &mut db_reader, version, start_index, - start_index + max_state_chunk_size + 1000, // Request more than the max chunk - use_compression, - ) - .await - .unwrap(); + chunk_size, + state_value_chunk_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + return db_reader; + } - // Verify the response adheres to the network limits - match response.get_data_response().unwrap() { - DataResponse::StateValueChunkWithProof(state_value_chunk_with_proof) => { - let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; - let num_state_values = state_value_chunk_with_proof.raw_values.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_state_values, 1); // Data cannot be reduced more than a single item - } else { - let max_num_state_values = network_limit_bytes / min_bytes_per_state_value; - assert!(num_state_values <= max_num_state_values); // Verify data fits correctly into the limit - } - }, - _ => panic!("Expected state values with proof but got: {:?}", response), - } + // Otherwise, expect the legacy implementation that halves the chunk size until it fits + let mut expectation_sequence = Sequence::new(); + while chunk_size >= 1 { + let state_value_chunk_with_proof = + create_state_value_chunk_with_proof(start_index, chunk_size, min_bytes_per_state_value); + + db_reader + .expect_get_state_value_chunk_with_proof() + .times(1) + .with( + eq(version), + eq(start_index as usize), + eq(chunk_size as usize), + ) + .in_sequence(&mut expectation_sequence) + .returning(move |_, _, _| Ok(state_value_chunk_with_proof.clone())); + + chunk_size /= 2; } + + db_reader } diff --git a/state-sync/storage-service/server/src/tests/storage_summary.rs b/state-sync/storage-service/server/src/tests/storage_summary.rs index ad010302a80..450aa9e4ed2 100644 --- a/state-sync/storage-service/server/src/tests/storage_summary.rs +++ b/state-sync/storage-service/server/src/tests/storage_summary.rs @@ -21,6 +21,7 @@ use aptos_storage_service_types::{ }, StorageServiceError, }; +use aptos_time_service::TimeService; use aptos_types::{ledger_info::LedgerInfoWithSignatures, transaction::Version}; use arc_swap::ArcSwap; use futures::StreamExt; @@ -47,7 +48,11 @@ async fn test_refresh_cached_storage_summary() { state_prune_window, highest_ledger_info.clone(), ); - let storage_reader = StorageReader::new(storage_service_config, Arc::new(db_reader)); + let storage_reader = StorageReader::new( + storage_service_config, + Arc::new(db_reader), + TimeService::mock(), + ); // Create the storage summary cache let cached_storage_server_summary = diff --git a/state-sync/storage-service/server/src/tests/subscribe_transaction_outputs.rs b/state-sync/storage-service/server/src/tests/subscribe_transaction_outputs.rs index c7aafea832d..475b67979f3 100644 --- a/state-sync/storage-service/server/src/tests/subscribe_transaction_outputs.rs +++ b/state-sync/storage-service/server/src/tests/subscribe_transaction_outputs.rs @@ -11,355 +11,335 @@ use claims::assert_none; #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transaction_outputs_different_networks() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [100, max_output_chunk_size] { - // Create test data - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 10); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof_1 = utils::create_output_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - ); - let output_list_with_proof_2 = utils::create_output_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - output_list_with_proof_1.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - output_list_with_proof_2.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to transaction outputs for peer 1 - let peer_id = PeerId::random(); - let subscription_stream_id = 200; - let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); - let mut response_receiver_1 = utils::subscribe_to_transaction_outputs_for_peer( - &mut mock_client, - peer_version_1, - highest_epoch, - subscription_stream_id, - 0, - Some(peer_network_1), - ) - .await; - - // Send a request to subscribe to transaction outputs for peer 2 - let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); - let mut response_receiver_2 = utils::subscribe_to_transaction_outputs_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - subscription_stream_id, - 0, - Some(peer_network_2), - ) - .await; - - // Wait until the subscriptions are active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; - - // Verify no subscription response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data for both peers - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver_1, - output_list_with_proof_1, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver_2, - output_list_with_proof_2, - highest_ledger_info, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [100, max_output_chunk_size] { + // Create test data + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - (chunk_size - 10); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof_1 = utils::create_output_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let output_list_with_proof_2 = utils::create_output_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + output_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + output_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to transaction outputs for peer 1 + let peer_id = PeerId::random(); + let subscription_stream_id = 200; + let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); + let mut response_receiver_1 = utils::subscribe_to_transaction_outputs_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + subscription_stream_id, + 0, + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to subscribe to transaction outputs for peer 2 + let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); + let mut response_receiver_2 = utils::subscribe_to_transaction_outputs_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + subscription_stream_id, + 0, + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the subscriptions are active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; + + // Verify no subscription response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data for both peers + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + output_list_with_proof_1, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + output_list_with_proof_2, + highest_ledger_info, + ) + .await; + } + } } } -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transaction_outputs_epoch_change() { - // Create test data - let highest_version = 45576; - let highest_epoch = 1032; - let lowest_version = 4566; - let peer_version = highest_version - 100; - let peer_epoch = highest_epoch - 20; - let epoch_change_version = peer_version + 45; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - output_list_with_proof.clone(), - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_subscribe_transaction_outputs_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_subscriptions = service.get_subscriptions(); + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); tokio::spawn(service.start()); - // Send a request to subscribe to transaction outputs + // Send a transaction output v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). let response_receiver = utils::subscribe_to_transaction_outputs( &mut mock_client, - peer_version, - peer_epoch, - utils::get_random_u64(), + 0, + 0, + 0, + 0, + true, // Use transaction v2 0, ) .await; - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_list_with_proof, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); } #[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transaction_outputs_max_chunk() { - // Create a storage service config with a configured max chunk size - let max_transaction_output_chunk_size = 301; - let storage_service_config = StorageServiceConfig { - max_transaction_output_chunk_size, - ..StorageServiceConfig::default() - }; - - // Create test data - let highest_version = 1034556; - let highest_epoch = 343; - let lowest_version = 3453; - let requested_chunk_size = max_transaction_output_chunk_size + 100; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - peer_version + requested_chunk_size, - highest_version, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - max_transaction_output_chunk_size, - highest_version, - output_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to new transaction outputs - let response_receiver = utils::subscribe_to_transaction_outputs( - &mut mock_client, - peer_version, - highest_epoch, - utils::get_random_u64(), - 0, - ) - .await; +async fn test_subscribe_transaction_outputs_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let highest_version = 45576; + let highest_epoch = 1032; + let lowest_version = 4566; + let peer_version = highest_version - 100; + let peer_epoch = highest_epoch - 20; + let epoch_change_version = peer_version + 45; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to transaction outputs + let response_receiver = utils::subscribe_to_transaction_outputs( + &mut mock_client, + peer_version, + peer_epoch, + utils::get_random_u64(), + 0, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Verify a response is received and that it contains the correct data - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_list_with_proof, - highest_ledger_info, - ) - .await; + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + output_list_with_proof, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } + } } #[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transaction_outputs_streaming() { - // Create a storage service config - let max_transaction_output_chunk_size = 200; - let storage_service_config = StorageServiceConfig { - max_transaction_output_chunk_size, - ..Default::default() - }; - - // Create test data - let num_stream_requests = 30; - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version = highest_version - (num_stream_requests * max_transaction_output_chunk_size); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the output lists with proofs - let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; - let end_version = start_version + max_transaction_output_chunk_size - 1; - utils::create_output_list_with_proof(start_version, end_version, highest_version) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..num_stream_requests { - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + (i * max_transaction_output_chunk_size) + 1, - max_transaction_output_chunk_size, - highest_version, - output_lists_with_proofs[i as usize].clone(), - ); - } +async fn test_subscribe_transaction_outputs_max_chunk() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config with a configured max chunk size + let max_transaction_output_chunk_size = 301; + let storage_service_config = StorageServiceConfig { + max_transaction_output_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..StorageServiceConfig::default() + }; + + // Create test data + let highest_version = 1034556; + let highest_epoch = 343; + let lowest_version = 3453; + let requested_chunk_size = max_transaction_output_chunk_size + 100; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + peer_version + max_transaction_output_chunk_size, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + max_transaction_output_chunk_size, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to new transaction outputs + let response_receiver = utils::subscribe_to_transaction_outputs( + &mut mock_client, + peer_version, + highest_epoch, + utils::get_random_u64(), + 0, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send multiple batches of requests to the server and verify the responses - let num_batches_to_send = 6; - for batch_id in 0..num_batches_to_send { - // Send the request batch to subscribe to transaction outputs - let num_requests_per_batch = num_stream_requests / num_batches_to_send; - let first_request_index = batch_id * num_requests_per_batch; - let last_request_index = (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; - let mut response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - first_request_index, - last_request_index, - stream_id, - peer_version, - highest_epoch, - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_requests_per_batch as usize, - ) - .await; - - // Force the subscription handler to work - utils::force_cache_update_notification( - &mut mock_client, - &mock_time, - &storage_service_notifier, - true, - true, - ) - .await; - - // Continuously run the subscription service until the batch responses are received - for stream_request_index in first_request_index..=last_request_index { - // Verify that the correct response is received - utils::verify_output_subscription_response( - output_lists_with_proofs.clone(), - highest_ledger_info.clone(), + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transaction_outputs_with_proof( &mut mock_client, - &mut response_receivers, - stream_request_index, + response_receiver, + use_request_v2, + output_list_with_proof, + highest_ledger_info, ) .await; } @@ -367,231 +347,394 @@ async fn test_subscribe_transaction_outputs_streaming() { } #[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transaction_outputs_streaming_epoch_change() { - // Create a storage service config - let max_transaction_output_chunk_size = 5; - let max_num_active_subscriptions = 50; - let storage_service_config = StorageServiceConfig { - max_transaction_output_chunk_size, - max_num_active_subscriptions, - ..Default::default() - }; - - // Create test data - let highest_version = 1000; - let highest_epoch = 2; - let lowest_version = 0; - let peer_version = highest_version - 500; - let peer_epoch = highest_epoch - 1; - let epoch_change_version = peer_version + 97; - - // Create the highest ledger info and epoch change proof - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let epoch_change_ledger_info = - utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], - more: false, - }; - - // Create the output lists with proofs - let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( - max_transaction_output_chunk_size, - max_num_active_subscriptions, - peer_version, - epoch_change_version, - ); - let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_output_list_with_proof(*start_version, *end_version, highest_version) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - for (i, (start_version, end_version)) in chunk_start_and_end_versions.iter().enumerate() { - let proof_version = if *end_version <= epoch_change_version { - epoch_change_version - } else { - highest_version - }; - utils::expect_get_transaction_outputs( - &mut db_reader, - *start_version, - end_version - start_version + 1, - proof_version, - output_lists_with_proofs[i].clone(), - ); +async fn test_subscribe_transaction_outputs_streaming() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_output_chunk_size = 200; + let storage_service_config = StorageServiceConfig { + max_transaction_output_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; + + // Create test data + let num_stream_requests = 30; + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version = + highest_version - (num_stream_requests * max_transaction_output_chunk_size); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + + // Create the output lists with proofs + let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) + .map(|i| { + let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; + let end_version = start_version + max_transaction_output_chunk_size - 1; + utils::create_output_list_with_proof( + start_version, + end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + for i in 0..num_stream_requests { + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + (i * max_transaction_output_chunk_size) + 1, + max_transaction_output_chunk_size, + highest_version, + output_lists_with_proofs[i as usize].clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send multiple batches of requests to the server and verify the responses + let num_batches_to_send = 6; + for batch_id in 0..num_batches_to_send { + // Send the request batch to subscribe to transaction outputs + let num_requests_per_batch = num_stream_requests / num_batches_to_send; + let first_request_index = batch_id * num_requests_per_batch; + let last_request_index = + (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; + let mut response_receivers = utils::send_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + first_request_index, + last_request_index, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_requests_per_batch as usize, + ) + .await; + + // Force the subscription handler to work + utils::force_cache_update_notification( + &mut mock_client, + &mock_time, + &storage_service_notifier, + true, + true, + ) + .await; + + // Continuously run the subscription service until the batch responses are received + for stream_request_index in first_request_index..=last_request_index { + // Verify that the correct response is received + utils::verify_output_subscription_response( + output_lists_with_proofs.clone(), + highest_ledger_info.clone(), + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + } + } } +} - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the request batch to subscribe to transaction outputs - let mut response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - max_num_active_subscriptions - 1, - stream_id, - peer_version, - peer_epoch, - ) - .await; +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transaction_outputs_streaming_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_output_chunk_size = 5; + let max_num_active_subscriptions = 50; + let storage_service_config = StorageServiceConfig { + max_transaction_output_chunk_size, + max_num_active_subscriptions, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; + + // Create test data + let highest_version = 1000; + let highest_epoch = 2; + let lowest_version = 0; + let peer_version = highest_version - 500; + let peer_epoch = highest_epoch - 1; + let epoch_change_version = peer_version + 97; + + // Create the highest ledger info and epoch change proof + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let epoch_change_ledger_info = + utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], + more: false, + }; + + // Create the output lists with proofs + let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( + max_transaction_output_chunk_size, + max_num_active_subscriptions, + peer_version, + epoch_change_version, + ); + let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_output_list_with_proof( + *start_version, + *end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + for (i, (start_version, end_version)) in chunk_start_and_end_versions.iter().enumerate() + { + let proof_version = if *end_version <= epoch_change_version { + epoch_change_version + } else { + highest_version + }; + utils::expect_get_transaction_outputs( + &mut db_reader, + *start_version, + end_version - start_version + 1, + proof_version, + output_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send the request batch to subscribe to transaction outputs + let mut response_receivers = utils::send_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + 0, + max_num_active_subscriptions - 1, + stream_id, + peer_version, + peer_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - max_num_active_subscriptions as usize, - ) - .await; + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + max_num_active_subscriptions as usize, + ) + .await; - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Continuously run the subscription service until all the responses are received - for stream_request_index in 0..max_num_active_subscriptions { - // Determine the target ledger info for the response - let first_output_version = output_lists_with_proofs[stream_request_index as usize] - .first_transaction_output_version - .unwrap(); - let target_ledger_info = if first_output_version > epoch_change_version { - highest_ledger_info.clone() - } else { - epoch_change_ledger_info.clone() - }; - - // Verify that the correct response is received - utils::verify_output_subscription_response( - output_lists_with_proofs.clone(), - target_ledger_info.clone(), - &mut mock_client, - &mut response_receivers, - stream_request_index, - ) - .await; + // Continuously run the subscription service until all the responses are received + for stream_request_index in 0..max_num_active_subscriptions { + // Determine the target ledger info for the response + let first_output_version = output_lists_with_proofs[stream_request_index as usize] + .get_first_output_version() + .unwrap(); + let target_ledger_info = if first_output_version > epoch_change_version { + highest_ledger_info.clone() + } else { + epoch_change_ledger_info.clone() + }; + + // Verify that the correct response is received + utils::verify_output_subscription_response( + output_lists_with_proofs.clone(), + target_ledger_info.clone(), + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + } } } #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transaction_outputs_streaming_loop() { - // Create a storage service config - let max_transaction_output_chunk_size = 100; - let storage_service_config = StorageServiceConfig { - max_transaction_output_chunk_size, - ..Default::default() - }; - - // Create test data - let num_stream_requests = 30; - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version = highest_version - (num_stream_requests * max_transaction_output_chunk_size); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the output lists with proofs - let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; - let end_version = start_version + max_transaction_output_chunk_size - 1; - utils::create_output_list_with_proof(start_version, end_version, highest_version) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..num_stream_requests { - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + (i * max_transaction_output_chunk_size) + 1, - max_transaction_output_chunk_size, - highest_version, - output_lists_with_proofs[i as usize].clone(), - ); - } - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the requests to the server and verify the responses - let mut response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - num_stream_requests - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_output_chunk_size = 100; + let storage_service_config = StorageServiceConfig { + max_transaction_output_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; + + // Create test data + let num_stream_requests = 30; + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version = + highest_version - (num_stream_requests * max_transaction_output_chunk_size); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + + // Create the output lists with proofs + let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) + .map(|i| { + let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; + let end_version = start_version + max_transaction_output_chunk_size - 1; + utils::create_output_list_with_proof( + start_version, + end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + for i in 0..num_stream_requests { + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + (i * max_transaction_output_chunk_size) + 1, + max_transaction_output_chunk_size, + highest_version, + output_lists_with_proofs[i as usize].clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send the requests to the server and verify the responses + let mut response_receivers = utils::send_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + 0, + num_stream_requests - 1, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests as usize, - ) - .await; + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests as usize, + ) + .await; - // Verify the state of the subscription stream - utils::verify_subscription_stream_entry( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests, - peer_version, - highest_epoch, - max_transaction_output_chunk_size, - ); - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Verify the state of the subscription stream + utils::verify_subscription_stream_entry( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests, + peer_version, + highest_epoch, + max_transaction_output_chunk_size, + ); + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Verify all responses are received - for stream_request_index in 0..num_stream_requests { - let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); - utils::verify_new_transaction_outputs_with_proof( - &mut mock_client, - response_receiver, - output_lists_with_proofs[stream_request_index as usize].clone(), - highest_ledger_info.clone(), - ) - .await; + // Verify all responses are received + for stream_request_index in 0..num_stream_requests { + let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); + utils::verify_new_transaction_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + output_lists_with_proofs[stream_request_index as usize].clone(), + highest_ledger_info.clone(), + ) + .await; + } + } } } diff --git a/state-sync/storage-service/server/src/tests/subscribe_transactions.rs b/state-sync/storage-service/server/src/tests/subscribe_transactions.rs index fa5523cdb59..cd52ebb79b0 100644 --- a/state-sync/storage-service/server/src/tests/subscribe_transactions.rs +++ b/state-sync/storage-service/server/src/tests/subscribe_transactions.rs @@ -9,7 +9,7 @@ use aptos_config::{ use aptos_network::protocols::network::RpcError; use aptos_types::{ epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures, - transaction::TransactionListWithProof, PeerId, + transaction::TransactionListWithProofV2, PeerId, }; use bytes::Bytes; use claims::assert_none; @@ -18,95 +18,605 @@ use std::collections::HashMap; #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transactions_different_networks() { - // Test small and large chunk sizes - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - for chunk_size in [100, max_transaction_chunk_size] { - // Test event inclusion - for include_events in [true, false] { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + for chunk_size in [100, max_transaction_chunk_size] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 4566; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - (chunk_size - 10); + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + include_events, + use_request_v2, + ); + let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + include_events, + transaction_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + include_events, + transaction_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = utils::create_storage_config( + use_request_v2, + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to transactions for peer 1 + let peer_id = PeerId::random(); + let subscription_stream_id = 200; + let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); + let mut response_receiver_1 = utils::subscribe_to_transactions_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + include_events, + subscription_stream_id, + 0, + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to subscribe to transactions for peer 2 + let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); + let mut response_receiver_2 = utils::subscribe_to_transactions_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + include_events, + subscription_stream_id, + 0, + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the subscriptions are active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; + + // Verify no subscription response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data for both peers + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + transaction_list_with_proof_1, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + transaction_list_with_proof_2, + highest_ledger_info, + ) + .await; + } + } + } + } +} + +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_subscribe_transactions_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Send a transaction v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + let response_receiver = utils::subscribe_to_transactions( + &mut mock_client, + 0, + 0, + true, + 0, + 0, + true, // Use transaction v2 + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transactions_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 45576; + let highest_epoch = 1032; + let lowest_version = 4566; + let peer_version = highest_version - 100; + let peer_epoch = highest_epoch - 20; + let epoch_change_version = peer_version + 45; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to transactions + let response_receiver = utils::subscribe_to_transactions( + &mut mock_client, + peer_version, + peer_epoch, + include_events, + utils::get_random_u64(), + 0, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transactions_max_chunk() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config with a configured max chunk size + let max_transaction_chunk_size = 400; + let storage_service_config = StorageServiceConfig { + max_transaction_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..StorageServiceConfig::default() + }; + + // Test event inclusion + for include_events in [true, false] { + // Create test data + let highest_version = 1034556; + let highest_epoch = 343; + let lowest_version = 3453; + let requested_chunk_size = max_transaction_chunk_size + 1; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + peer_version + max_transaction_chunk_size, + peer_version + max_transaction_chunk_size, + include_events, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + max_transaction_chunk_size, + highest_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to new transactions + let response_receiver = utils::subscribe_to_transactions( + &mut mock_client, + peer_version, + highest_epoch, + include_events, + utils::get_random_u64(), + 0, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + highest_ledger_info, + ) + .await; + } + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transactions_streaming() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_chunk_size = 100; + let storage_service_config = StorageServiceConfig { + max_transaction_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; + // Create test data - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 4566; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 10); + let num_stream_requests = 20; + let highest_version = 100_000; + let highest_epoch = 10; + let lowest_version = 10_000; + let peer_version = 50_000; let highest_ledger_info = utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - include_events, + + // Create the transaction lists with proofs + let transaction_lists_with_proofs: Vec<_> = (0..num_stream_requests) + .map(|i| { + let start_version = peer_version + (i * max_transaction_chunk_size) + 1; + let end_version = start_version + max_transaction_chunk_size - 1; + utils::create_transaction_list_with_proof( + start_version, + end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, ); - let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - include_events, + for i in 0..num_stream_requests { + utils::expect_get_transactions( + &mut db_reader, + peer_version + (i * max_transaction_chunk_size) + 1, + max_transaction_chunk_size, + highest_version, + false, + transaction_lists_with_proofs[i as usize].clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send multiple batches of requests to the server and verify the responses + let num_batches_to_send = 10; + for batch_id in 0..num_batches_to_send { + // Send the request batch to subscribe to transaction outputs + let num_requests_per_batch = num_stream_requests / num_batches_to_send; + let first_request_index = batch_id * num_requests_per_batch; + let last_request_index = + (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; + let mut response_receivers = send_transaction_subscription_request_batch( + &mut mock_client, + peer_network_id, + first_request_index, + last_request_index, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_requests_per_batch as usize, + ) + .await; + + // Force the subscription handler to work + utils::force_cache_update_notification( + &mut mock_client, + &mock_time, + &storage_service_notifier, + true, + true, + ) + .await; + + // Continuously run the subscription service until the batch responses are received + for stream_request_index in first_request_index..=last_request_index { + // Verify that the correct response is received + verify_transaction_subscription_response( + transaction_lists_with_proofs.clone(), + highest_ledger_info.clone(), + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + } + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transactions_streaming_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_chunk_size = 50; + let max_num_active_subscriptions = 25; + let storage_service_config = StorageServiceConfig { + max_transaction_chunk_size, + max_num_active_subscriptions, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; + + // Create test data + let highest_version = 10_000; + let highest_epoch = 2; + let lowest_version = 0; + let peer_version = highest_version - 5000; + let peer_epoch = highest_epoch - 1; + let epoch_change_version = peer_version + 97; + + // Create the highest ledger info and epoch change proof + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let epoch_change_ledger_info = + utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], + more: false, + }; + + // Create the transaction lists with proofs + let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( + max_transaction_chunk_size, + max_num_active_subscriptions, + peer_version, + epoch_change_version, ); + let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_transaction_list_with_proof( + *start_version, + *end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); // Create the mock db reader let mut db_reader = mock::create_mock_db_with_summary_updates( highest_ledger_info.clone(), lowest_version, ); - utils::expect_get_transactions( + utils::expect_get_epoch_ending_ledger_infos( &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - include_events, - transaction_list_with_proof_1.clone(), - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - include_events, - transaction_list_with_proof_2.clone(), + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, ); + for (i, (start_version, end_version)) in chunk_start_and_end_versions.iter().enumerate() + { + let proof_version = if *end_version <= epoch_change_version { + epoch_change_version + } else { + highest_version + }; + utils::expect_get_transactions( + &mut db_reader, + *start_version, + end_version - start_version + 1, + proof_version, + false, + transaction_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + } // Create the storage client and server let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); + MockClient::new(Some(db_reader), Some(storage_service_config)); let active_subscriptions = service.get_subscriptions(); tokio::spawn(service.start()); - // Send a request to subscribe to transactions for peer 1 - let peer_id = PeerId::random(); - let subscription_stream_id = 200; - let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); - let mut response_receiver_1 = utils::subscribe_to_transactions_for_peer( + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send the request batch to subscribe to transaction outputs + let mut response_receivers = send_transaction_subscription_request_batch( &mut mock_client, - peer_version_1, - highest_epoch, - include_events, - subscription_stream_id, + peer_network_id, 0, - Some(peer_network_1), + max_num_active_subscriptions - 1, + stream_id, + peer_version, + peer_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, ) .await; - // Send a request to subscribe to transactions for peer 2 - let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); - let mut response_receiver_2 = utils::subscribe_to_transactions_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - include_events, - subscription_stream_id, - 0, - Some(peer_network_2), + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + max_num_active_subscriptions as usize, ) .await; - // Wait until the subscriptions are active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; - - // Verify no subscription response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - // Force the subscription handler to work utils::force_subscription_handler_to_run( &mut mock_client, @@ -115,532 +625,153 @@ async fn test_subscribe_transactions_different_networks() { ) .await; - // Verify a response is received and that it contains the correct data for both peers - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver_1, - transaction_list_with_proof_1, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver_2, - transaction_list_with_proof_2, - highest_ledger_info, - ) - .await; + // Continuously run the subscription service until all the responses are received + for stream_request_index in 0..max_num_active_subscriptions { + // Determine the target ledger info for the response + let first_output_version = transaction_lists_with_proofs + [stream_request_index as usize] + .get_first_transaction_version() + .unwrap(); + let target_ledger_info = if first_output_version > epoch_change_version { + highest_ledger_info.clone() + } else { + epoch_change_ledger_info.clone() + }; + + // Verify that the correct response is received + verify_transaction_subscription_response( + transaction_lists_with_proofs.clone(), + target_ledger_info.clone(), + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } } } } #[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_epoch_change() { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 45576; - let highest_epoch = 1032; - let lowest_version = 4566; - let peer_version = highest_version - 100; - let peer_epoch = highest_epoch - 20; - let epoch_change_version = peer_version + 45; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - include_events, - ); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - include_events, - transaction_list_with_proof.clone(), - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to transactions - let response_receiver = utils::subscribe_to_transactions( - &mut mock_client, - peer_version, - peer_epoch, - include_events, - utils::get_random_u64(), - 0, - ) - .await; - - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; - } -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_max_chunk() { - // Create a storage service config with a configured max chunk size - let max_transaction_chunk_size = 400; - let storage_service_config = StorageServiceConfig { - max_transaction_chunk_size, - ..StorageServiceConfig::default() - }; - - // Test event inclusion - for include_events in [true, false] { - // Create test data - let highest_version = 1034556; - let highest_epoch = 343; - let lowest_version = 3453; - let requested_chunk_size = max_transaction_chunk_size + 1; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + requested_chunk_size, - peer_version + requested_chunk_size, - include_events, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - max_transaction_chunk_size, - highest_version, - include_events, - transaction_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to new transactions - let response_receiver = utils::subscribe_to_transactions( - &mut mock_client, - peer_version, - highest_epoch, - include_events, - utils::get_random_u64(), - 0, - ) - .await; - - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - highest_ledger_info, - ) - .await; - } -} +async fn test_subscribe_transactions_streaming_loop() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_chunk_size = 100; + let storage_service_config = StorageServiceConfig { + max_transaction_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, + ..Default::default() + }; -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_streaming() { - // Create a storage service config - let max_transaction_chunk_size = 100; - let storage_service_config = StorageServiceConfig { - max_transaction_chunk_size, - ..Default::default() - }; - - // Create test data - let num_stream_requests = 20; - let highest_version = 100_000; - let highest_epoch = 10; - let lowest_version = 10_000; - let peer_version = 50_000; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the transaction lists with proofs - let transaction_lists_with_proofs: Vec<_> = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_chunk_size) + 1; - let end_version = start_version + max_transaction_chunk_size - 1; - utils::create_transaction_list_with_proof( - start_version, - end_version, - highest_version, - false, - ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..num_stream_requests { - utils::expect_get_transactions( - &mut db_reader, - peer_version + (i * max_transaction_chunk_size) + 1, - max_transaction_chunk_size, - highest_version, - false, - transaction_lists_with_proofs[i as usize].clone(), - ); - } + // Create test data + let num_stream_requests = 20; + let highest_version = 100_000; + let highest_epoch = 10; + let lowest_version = 10_000; + let peer_version = 50_000; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); + // Create the transaction lists with proofs + let transaction_lists_with_proofs: Vec<_> = (0..num_stream_requests) + .map(|i| { + let start_version = peer_version + (i * max_transaction_chunk_size) + 1; + let end_version = start_version + max_transaction_chunk_size - 1; + utils::create_transaction_list_with_proof( + start_version, + end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send multiple batches of requests to the server and verify the responses - let num_batches_to_send = 10; - for batch_id in 0..num_batches_to_send { - // Send the request batch to subscribe to transaction outputs - let num_requests_per_batch = num_stream_requests / num_batches_to_send; - let first_request_index = batch_id * num_requests_per_batch; - let last_request_index = (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; - let mut response_receivers = send_transaction_subscription_request_batch( - &mut mock_client, - peer_network_id, - first_request_index, - last_request_index, - stream_id, - peer_version, - highest_epoch, - ) - .await; + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + for i in 0..num_stream_requests { + utils::expect_get_transactions( + &mut db_reader, + peer_version + (i * max_transaction_chunk_size) + 1, + max_transaction_chunk_size, + highest_version, + false, + transaction_lists_with_proofs[i as usize].clone(), + use_size_and_time_aware_chunking, + ); + } - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_requests_per_batch as usize, - ) - .await; + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); - // Force the subscription handler to work - utils::force_cache_update_notification( - &mut mock_client, - &mock_time, - &storage_service_notifier, - true, - true, - ) - .await; + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); - // Continuously run the subscription service until the batch responses are received - for stream_request_index in first_request_index..=last_request_index { - // Verify that the correct response is received - verify_transaction_subscription_response( - transaction_lists_with_proofs.clone(), - highest_ledger_info.clone(), + // Send the requests to the server and verify the responses + let mut response_receivers = send_transaction_subscription_request_batch( &mut mock_client, - &mut response_receivers, - stream_request_index, + peer_network_id, + 0, + num_stream_requests - 1, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, ) .await; - } - } -} -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_streaming_epoch_change() { - // Create a storage service config - let max_transaction_chunk_size = 50; - let max_num_active_subscriptions = 25; - let storage_service_config = StorageServiceConfig { - max_transaction_chunk_size, - max_num_active_subscriptions, - ..Default::default() - }; - - // Create test data - let highest_version = 10_000; - let highest_epoch = 2; - let lowest_version = 0; - let peer_version = highest_version - 5000; - let peer_epoch = highest_epoch - 1; - let epoch_change_version = peer_version + 97; - - // Create the highest ledger info and epoch change proof - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let epoch_change_ledger_info = - utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], - more: false, - }; - - // Create the transaction lists with proofs - let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( - max_transaction_chunk_size, - max_num_active_subscriptions, - peer_version, - epoch_change_version, - ); - let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_transaction_list_with_proof( - *start_version, - *end_version, - highest_version, - false, + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests as usize, ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - for (i, (start_version, end_version)) in chunk_start_and_end_versions.iter().enumerate() { - let proof_version = if *end_version <= epoch_change_version { - epoch_change_version - } else { - highest_version - }; - utils::expect_get_transactions( - &mut db_reader, - *start_version, - end_version - start_version + 1, - proof_version, - false, - transaction_lists_with_proofs[i].clone(), - ); - } - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the request batch to subscribe to transaction outputs - let mut response_receivers = send_transaction_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - max_num_active_subscriptions - 1, - stream_id, - peer_version, - peer_epoch, - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - max_num_active_subscriptions as usize, - ) - .await; - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + .await; - // Continuously run the subscription service until all the responses are received - for stream_request_index in 0..max_num_active_subscriptions { - // Determine the target ledger info for the response - let first_output_version = transaction_lists_with_proofs[stream_request_index as usize] - .first_transaction_version - .unwrap(); - let target_ledger_info = if first_output_version > epoch_change_version { - highest_ledger_info.clone() - } else { - epoch_change_ledger_info.clone() - }; - - // Verify that the correct response is received - verify_transaction_subscription_response( - transaction_lists_with_proofs.clone(), - target_ledger_info.clone(), - &mut mock_client, - &mut response_receivers, - stream_request_index, - ) - .await; - } -} + // Verify the state of the subscription stream + utils::verify_subscription_stream_entry( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests, + peer_version, + highest_epoch, + max_transaction_chunk_size, + ); -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_streaming_loop() { - // Create a storage service config - let max_transaction_chunk_size = 100; - let storage_service_config = StorageServiceConfig { - max_transaction_chunk_size, - ..Default::default() - }; - - // Create test data - let num_stream_requests = 20; - let highest_version = 100_000; - let highest_epoch = 10; - let lowest_version = 10_000; - let peer_version = 50_000; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the transaction lists with proofs - let transaction_lists_with_proofs: Vec<_> = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_chunk_size) + 1; - let end_version = start_version + max_transaction_chunk_size - 1; - utils::create_transaction_list_with_proof( - start_version, - end_version, - highest_version, - false, + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..num_stream_requests { - utils::expect_get_transactions( - &mut db_reader, - peer_version + (i * max_transaction_chunk_size) + 1, - max_transaction_chunk_size, - highest_version, - false, - transaction_lists_with_proofs[i as usize].clone(), - ); - } - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the requests to the server and verify the responses - let mut response_receivers = send_transaction_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - num_stream_requests - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests as usize, - ) - .await; - - // Verify the state of the subscription stream - utils::verify_subscription_stream_entry( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests, - peer_version, - highest_epoch, - max_transaction_chunk_size, - ); - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + .await; - // Verify all responses are received - for stream_request_index in 0..num_stream_requests { - let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_lists_with_proofs[stream_request_index as usize].clone(), - highest_ledger_info.clone(), - ) - .await; + // Verify all responses are received + for stream_request_index in 0..num_stream_requests { + let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_lists_with_proofs[stream_request_index as usize].clone(), + highest_ledger_info.clone(), + ) + .await; + } + } } } @@ -654,6 +785,8 @@ async fn send_transaction_subscription_request_batch( stream_id: u64, peer_version: u64, peer_epoch: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> HashMap>> { // Shuffle the stream request indices to emulate out of order requests let stream_request_indices = @@ -671,6 +804,8 @@ async fn send_transaction_subscription_request_batch( stream_id, stream_request_index, Some(peer_network_id), + use_request_v2, + max_response_bytes_v2, ) .await; @@ -684,16 +819,18 @@ async fn send_transaction_subscription_request_batch( /// Verifies that a response is received for a given stream request index /// and that the response contains the correct data. async fn verify_transaction_subscription_response( - expected_transaction_lists_with_proofs: Vec, + expected_transaction_lists_with_proofs: Vec, expected_target_ledger_info: LedgerInfoWithSignatures, mock_client: &mut MockClient, response_receivers: &mut HashMap>>, stream_request_index: u64, + use_request_v2: bool, ) { let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); utils::verify_new_transactions_with_proof( mock_client, response_receiver, + use_request_v2, expected_transaction_lists_with_proofs[stream_request_index as usize].clone(), expected_target_ledger_info, ) diff --git a/state-sync/storage-service/server/src/tests/subscribe_transactions_or_outputs.rs b/state-sync/storage-service/server/src/tests/subscribe_transactions_or_outputs.rs index 45d17de5b98..b6129e76dae 100644 --- a/state-sync/storage-service/server/src/tests/subscribe_transactions_or_outputs.rs +++ b/state-sync/storage-service/server/src/tests/subscribe_transactions_or_outputs.rs @@ -10,7 +10,7 @@ use aptos_network::protocols::network::RpcError; use aptos_types::{ epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures, - transaction::{TransactionListWithProof, TransactionOutputListWithProof}, + transaction::{TransactionListWithProofV2, TransactionOutputListWithProofV2}, PeerId, }; use bytes::Bytes; @@ -20,528 +20,652 @@ use std::collections::HashMap; #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transactions_or_outputs_different_network() { - // Test small and large chunk sizes - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [100, max_output_chunk_size] { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 5060; - let highest_epoch = 30; - let lowest_version = 101; - let peer_version_1 = highest_version - chunk_size; - let peer_version_2 = highest_version - (chunk_size - 50); - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof_1 = utils::create_output_list_with_proof( - peer_version_1 + 1, - highest_version, - highest_version, - ); - let output_list_with_proof_2 = utils::create_output_list_with_proof( - peer_version_2 + 1, - highest_version, - highest_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - highest_version, - highest_version, - highest_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - highest_ledger_info.clone(), - lowest_version, - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, - output_list_with_proof_1.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - output_list_with_proof_2.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version_1 + 1, - highest_version - peer_version_1, - highest_version, + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk sizes + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [100, max_output_chunk_size] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 5060; + let highest_epoch = 30; + let lowest_version = 101; + let peer_version_1 = highest_version - chunk_size; + let peer_version_2 = highest_version - chunk_size + 1; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof_1 = utils::create_output_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let output_list_with_proof_2 = utils::create_output_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof_1 = utils::create_transaction_list_with_proof( + peer_version_1 + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); + let transaction_list_with_proof_2 = utils::create_transaction_list_with_proof( + peer_version_2 + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + output_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + output_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version_1 + 1, + highest_version - peer_version_1, + highest_version, + false, + transaction_list_with_proof_1.clone(), + use_size_and_time_aware_chunking, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version_2 + 1, + highest_version - peer_version_2, + highest_version, + false, + transaction_list_with_proof_2.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof_1, + &transaction_list_with_proof_1, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to transactions or outputs for peer 1 + let peer_id = PeerId::random(); + let subscription_stream_id = 56756; + let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); + let mut response_receiver_1 = + utils::subscribe_to_transactions_or_outputs_for_peer( + &mut mock_client, + peer_version_1, + highest_epoch, + false, + 0, // Outputs cannot be reduced and will fallback to transactions + subscription_stream_id, + 0, + Some(peer_network_1), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Send a request to subscribe to transactions or outputs for peer 2 + let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); + let mut response_receiver_2 = + utils::subscribe_to_transactions_or_outputs_for_peer( + &mut mock_client, + peer_version_2, + highest_epoch, + false, + 0, // Outputs cannot be reduced and will fallback to transactions + subscription_stream_id, + 0, + Some(peer_network_2), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the subscriptions are active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; + + // Verify no response has been received yet + assert_none!(response_receiver_1.try_recv().unwrap()); + assert_none!(response_receiver_2.try_recv().unwrap()); + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; + + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + Some(transaction_list_with_proof_1.clone()), + None, + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + Some(transaction_list_with_proof_2.clone()), + None, + highest_ledger_info, + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_1, + use_request_v2, + None, + Some(output_list_with_proof_1.clone()), + highest_ledger_info.clone(), + ) + .await; + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver_2, + use_request_v2, + None, + Some(output_list_with_proof_2.clone()), + highest_ledger_info, + ) + .await; + } + } + } + } + } +} + +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_subscribe_transactions_or_outputs_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Send a transaction or output v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + let response_receiver = utils::subscribe_to_transactions_or_outputs( + &mut mock_client, + 0, + 0, + false, + 0, + 0, + 0, + true, // Use transaction v2 + 0, + ) + .await; + + // Wait for the response, which should never come + response_receiver.await.unwrap().unwrap(); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_subscribe_transactions_or_outputs_epoch_change() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 10000; + let highest_epoch = 10000; + let lowest_version = 0; + let peer_version = highest_version - 1000; + let peer_epoch = highest_epoch - 1000; + let epoch_change_version = peer_version + 1; + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( + peer_epoch, + epoch_change_version, + )], + more: false, + }; + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + epoch_change_version, + epoch_change_version, false, - transaction_list_with_proof.clone(), + use_request_v2, ); - utils::expect_get_transactions( + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), + lowest_version, + ); + utils::expect_get_epoch_ending_ledger_infos( &mut db_reader, - peer_version_2 + 1, - highest_version - peer_version_2, - highest_version, - false, - transaction_list_with_proof.clone(), + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, ); - } + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + epoch_change_version - peer_version, + epoch_change_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof_1, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to transactions or outputs for peer 1 - let peer_id = PeerId::random(); - let subscription_stream_id = 56756; - let peer_network_1 = PeerNetworkId::new(NetworkId::Public, peer_id); - let mut response_receiver_1 = utils::subscribe_to_transactions_or_outputs_for_peer( - &mut mock_client, - peer_version_1, - highest_epoch, - false, - 0, // Outputs cannot be reduced and will fallback to transactions - subscription_stream_id, - 0, - Some(peer_network_1), - ) - .await; - - // Send a request to subscribe to transactions or outputs for peer 2 - let peer_network_2 = PeerNetworkId::new(NetworkId::Vfn, peer_id); - let mut response_receiver_2 = utils::subscribe_to_transactions_or_outputs_for_peer( - &mut mock_client, - peer_version_2, - highest_epoch, - false, - 0, // Outputs cannot be reduced and will fallback to transactions - subscription_stream_id, - 0, - Some(peer_network_2), - ) - .await; - - // Wait until the subscriptions are active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 2).await; - - // Verify no response has been received yet - assert_none!(response_receiver_1.try_recv().unwrap()); - assert_none!(response_receiver_2.try_recv().unwrap()); - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver_1, - Some(transaction_list_with_proof.clone()), - None, - highest_ledger_info.clone(), - ) - .await; - utils::verify_new_transactions_or_outputs_with_proof( + // Send a request to subscribe to new transactions or outputs + let response_receiver = utils::subscribe_to_transactions_or_outputs( &mut mock_client, - response_receiver_2, - Some(transaction_list_with_proof), - None, - highest_ledger_info, - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver_1, - None, - Some(output_list_with_proof_1.clone()), - highest_ledger_info.clone(), + peer_version, + peer_epoch, + false, + 5, + utils::get_random_u64(), + 0, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, ) .await; - utils::verify_new_transactions_or_outputs_with_proof( + + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( &mut mock_client, - response_receiver_2, - None, - Some(output_list_with_proof_2.clone()), - highest_ledger_info, + &mock_time, + &storage_service_notifier, ) .await; - } - } - } -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_subscribe_transactions_or_outputs_epoch_change() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 10000; - let highest_epoch = 10000; - let lowest_version = 0; - let peer_version = highest_version - 1000; - let peer_epoch = highest_epoch - 1000; - let epoch_change_version = peer_version + 1; - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![utils::create_test_ledger_info_with_sigs( - peer_epoch, - epoch_change_version, - )], - more: false, - }; - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - epoch_change_version, - epoch_change_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + 1, - epoch_change_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_with_summary_updates( - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version), - lowest_version, - ); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - output_list_with_proof.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - epoch_change_version - peer_version, - epoch_change_version, - false, - transaction_list_with_proof.clone(), - ); - } - - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to new transactions or outputs - let response_receiver = utils::subscribe_to_transactions_or_outputs( - &mut mock_client, - peer_version, - peer_epoch, - false, - 5, - utils::get_random_u64(), - 0, - ) - .await; - - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - Some(transaction_list_with_proof), - None, - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - None, - Some(output_list_with_proof), - epoch_change_proof.ledger_info_with_sigs[0].clone(), - ) - .await; + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some(transaction_list_with_proof), + None, + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_list_with_proof), + epoch_change_proof.ledger_info_with_sigs[0].clone(), + ) + .await; + } + } } } } #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transactions_or_outputs_max_chunk() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let highest_version = 65660; - let highest_epoch = 30; - let lowest_version = 101; - let max_transaction_output_chunk_size = - StorageServiceConfig::default().max_transaction_output_chunk_size; - let requested_chunk_size = max_transaction_output_chunk_size + 100; - let peer_version = highest_version - requested_chunk_size; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = utils::create_output_list_with_proof( - peer_version + 1, - peer_version + requested_chunk_size, - highest_version, - ); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - peer_version + 1, - peer_version + requested_chunk_size, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let max_num_output_reductions = 5; - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for i in 0..=max_num_output_reductions { - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - (max_transaction_output_chunk_size as u32 / (u32::pow(2, i as u32))) as u64, - highest_version, - output_list_with_proof.clone(), - ); - } - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - max_transaction_output_chunk_size, - highest_version, - false, - transaction_list_with_proof.clone(), - ); - } + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let highest_version = 65660; + let highest_epoch = 30; + let lowest_version = 101; + let max_transaction_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + let requested_chunk_size = max_transaction_output_chunk_size + 100; + let peer_version = highest_version - requested_chunk_size; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + peer_version + max_transaction_output_chunk_size, + peer_version + max_transaction_output_chunk_size, + false, + use_request_v2, + ); - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send a request to subscribe to new transactions or outputs - let response_receiver = utils::subscribe_to_transactions_or_outputs( - &mut mock_client, - peer_version, - highest_epoch, - false, - max_num_output_reductions, - utils::get_random_u64(), - 0, - ) - .await; + // Create the mock db reader + let max_num_output_reductions = 5; + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + for i in 0..=max_num_output_reductions { + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + 1, + (max_transaction_output_chunk_size as u32 / (u32::pow(2, i as u32))) as u64, + highest_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + if use_size_and_time_aware_chunking { + break; // Size and time-aware chunking only makes one attempt + } + } + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + max_transaction_output_chunk_size, + highest_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send a request to subscribe to new transactions or outputs + let response_receiver = utils::subscribe_to_transactions_or_outputs( + &mut mock_client, + peer_version, + highest_epoch, + false, + max_num_output_reductions, + utils::get_random_u64(), + 0, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await; - // Wait until the subscription is active - utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; + // Wait until the subscription is active + utils::wait_for_active_subscriptions(active_subscriptions.clone(), 1).await; - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Verify a response is received and that it contains the correct data - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - Some(transaction_list_with_proof), - None, - highest_ledger_info, - ) - .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( - &mut mock_client, - response_receiver, - None, - Some(output_list_with_proof), - highest_ledger_info, - ) - .await; + // Verify a response is received and that it contains the correct data + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some(transaction_list_with_proof), + None, + highest_ledger_info, + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_list_with_proof), + highest_ledger_info, + ) + .await; + } + } } } } #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transaction_or_outputs_streaming() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let max_transaction_output_chunk_size = 90; - let num_stream_requests = 30; - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 2; - let peer_version = 1; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the transaction and output lists with proofs - let chunk_start_and_end_versions = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; - let end_version = start_version + max_transaction_output_chunk_size - 1; - (start_version, end_version) - }) - .collect::>(); - let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_output_list_with_proof(*start_version, *end_version, highest_version) - }) - .collect(); - let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_transaction_list_with_proof( - *start_version, - *end_version, - highest_version, - false, - ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for (i, (start_version, _)) in chunk_start_and_end_versions.iter().enumerate() { - // Set expectations for transaction output reads - utils::expect_get_transaction_outputs( - &mut db_reader, - *start_version, - max_transaction_output_chunk_size, - highest_version, - output_lists_with_proofs[i].clone(), - ); - - // Set expectations for transaction reads - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - *start_version, - max_transaction_output_chunk_size, - highest_version, - false, - transaction_lists_with_proofs[i].clone(), - ); - } - } - - // Create the storage service config - let mut storage_service_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_lists_with_proofs[0], - &transaction_lists_with_proofs[0], - ); - storage_service_config.max_transaction_output_chunk_size = - max_transaction_output_chunk_size; - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send multiple batches of requests to the server and verify the responses - let num_batches_to_send = 5; - for batch_id in 0..num_batches_to_send { - // Send the request batch to subscribe to transaction outputs - let num_requests_per_batch = num_stream_requests / num_batches_to_send; - let first_request_index = batch_id * num_requests_per_batch; - let last_request_index = - (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; - let mut response_receivers = send_transaction_or_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - first_request_index, - last_request_index, - stream_id, - peer_version, - highest_epoch, - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_requests_per_batch as usize, - ) - .await; - - // Force the subscription handler to work - utils::force_cache_update_notification( - &mut mock_client, - &mock_time, - &storage_service_notifier, - true, - true, - ) - .await; - - // Continuously run the subscription service until the batch responses are received - for stream_request_index in first_request_index..=last_request_index { - // Verify that the correct response is received - verify_transaction_or_output_subscription_response( - transaction_lists_with_proofs.clone(), - output_lists_with_proofs.clone(), + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let max_transaction_output_chunk_size = 90; + let num_stream_requests = 30; + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 2; + let peer_version = 1; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + + // Create the transaction and output lists with proofs + let chunk_start_and_end_versions = (0..num_stream_requests) + .map(|i| { + let start_version = + peer_version + (i * max_transaction_output_chunk_size) + 1; + let end_version = start_version + max_transaction_output_chunk_size - 1; + (start_version, end_version) + }) + .collect::>(); + let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_output_list_with_proof( + *start_version, + *end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_transaction_list_with_proof( + *start_version, + *end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( highest_ledger_info.clone(), + lowest_version, + ); + for (i, (start_version, _)) in chunk_start_and_end_versions.iter().enumerate() { + // Set expectations for transaction output reads + utils::expect_get_transaction_outputs( + &mut db_reader, + *start_version, + max_transaction_output_chunk_size, + highest_version, + output_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + + // Set expectations for transaction reads + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + *start_version, + max_transaction_output_chunk_size, + highest_version, + false, + transaction_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + } + } + + // Create the storage service config + let mut storage_service_config = utils::configure_network_chunk_limit( fallback_to_transactions, - &mut mock_client, - &mut response_receivers, - stream_request_index, - ) - .await; + &output_lists_with_proofs[0], + &transaction_lists_with_proofs[0], + use_request_v2, + use_size_and_time_aware_chunking, + ); + storage_service_config.max_transaction_output_chunk_size = + max_transaction_output_chunk_size; + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send multiple batches of requests to the server and verify the responses + let num_batches_to_send = 5; + for batch_id in 0..num_batches_to_send { + // Send the request batch to subscribe to transaction outputs + let num_requests_per_batch = num_stream_requests / num_batches_to_send; + let first_request_index = batch_id * num_requests_per_batch; + let last_request_index = + (batch_id * num_requests_per_batch) + num_requests_per_batch - 1; + let mut response_receivers = + send_transaction_or_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + first_request_index, + last_request_index, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_requests_per_batch as usize, + ) + .await; + + // Force the subscription handler to work + utils::force_cache_update_notification( + &mut mock_client, + &mock_time, + &storage_service_notifier, + true, + true, + ) + .await; + + // Continuously run the subscription service until the batch responses are received + for stream_request_index in first_request_index..=last_request_index { + // Verify that the correct response is received + verify_transaction_or_output_subscription_response( + transaction_lists_with_proofs.clone(), + output_lists_with_proofs.clone(), + highest_ledger_info.clone(), + fallback_to_transactions, + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + } } } } @@ -549,321 +673,360 @@ async fn test_subscribe_transaction_or_outputs_streaming() { #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transactions_or_outputs_streaming_epoch_change() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let max_transaction_output_chunk_size = 10; - let max_num_active_subscriptions = 50; - let highest_version = 1000; - let highest_epoch = 2; - let lowest_version = 0; - let peer_version = highest_version - 900; - let peer_epoch = highest_epoch - 1; - let epoch_change_version = peer_version + 97; - - // Create the highest ledger info and epoch change proof - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let epoch_change_ledger_info = - utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], - more: false, - }; - - // Create the transaction and output lists with proofs - let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( - max_transaction_output_chunk_size, - max_num_active_subscriptions, - peer_version, - epoch_change_version, - ); - let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_output_list_with_proof(*start_version, *end_version, highest_version) - }) - .collect(); - let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_transaction_list_with_proof( - *start_version, - *end_version, - highest_version, - false, - ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_epoch_ending_ledger_infos( - &mut db_reader, - peer_epoch, - peer_epoch + 1, - epoch_change_proof.clone(), - ); - for (i, (start_version, end_version)) in chunk_start_and_end_versions.iter().enumerate() { - // Set expectations for transaction output reads - let proof_version = if *end_version <= epoch_change_version { - epoch_change_version - } else { - highest_version - }; - utils::expect_get_transaction_outputs( - &mut db_reader, - *start_version, - end_version - start_version + 1, - proof_version, - output_lists_with_proofs[i].clone(), - ); - - // Set expectations for transaction reads - if fallback_to_transactions { - utils::expect_get_transactions( + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let max_transaction_output_chunk_size = 10; + let max_num_active_subscriptions = 50; + let highest_version = 1000; + let highest_epoch = 2; + let lowest_version = 0; + let peer_version = highest_version - 900; + let peer_epoch = highest_epoch - 1; + let epoch_change_version = peer_version + 97; + + // Create the highest ledger info and epoch change proof + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let epoch_change_ledger_info = + utils::create_epoch_ending_ledger_info(peer_epoch, epoch_change_version); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![epoch_change_ledger_info.clone()], + more: false, + }; + + // Create the transaction and output lists with proofs + let chunk_start_and_end_versions = utils::create_data_chunks_with_epoch_boundary( + max_transaction_output_chunk_size, + max_num_active_subscriptions, + peer_version, + epoch_change_version, + ); + let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_output_list_with_proof( + *start_version, + *end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_transaction_list_with_proof( + *start_version, + *end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, + ); + utils::expect_get_epoch_ending_ledger_infos( &mut db_reader, - *start_version, - end_version - start_version + 1, - proof_version, - false, - transaction_lists_with_proofs[i].clone(), + peer_epoch, + peer_epoch + 1, + epoch_change_proof.clone(), + use_size_and_time_aware_chunking, ); - } - } - - // Create the storage service config - let mut storage_service_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_lists_with_proofs[0], - &transaction_lists_with_proofs[0], - ); - storage_service_config.max_transaction_output_chunk_size = - max_transaction_output_chunk_size; - storage_service_config.max_num_active_subscriptions = max_num_active_subscriptions; - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the request batch to subscribe to transactions or outputs - let mut response_receivers = send_transaction_or_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - max_num_active_subscriptions - 1, - stream_id, - peer_version, - peer_epoch, - ) - .await; + for (i, (start_version, end_version)) in + chunk_start_and_end_versions.iter().enumerate() + { + // Set expectations for transaction output reads + let proof_version = if *end_version <= epoch_change_version { + epoch_change_version + } else { + highest_version + }; + utils::expect_get_transaction_outputs( + &mut db_reader, + *start_version, + end_version - start_version + 1, + proof_version, + output_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + + // Set expectations for transaction reads + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + *start_version, + end_version - start_version + 1, + proof_version, + false, + transaction_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + } + } + + // Create the storage service config + let mut storage_service_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_lists_with_proofs[0], + &transaction_lists_with_proofs[0], + use_request_v2, + use_size_and_time_aware_chunking, + ); + storage_service_config.max_transaction_output_chunk_size = + max_transaction_output_chunk_size; + storage_service_config.max_num_active_subscriptions = max_num_active_subscriptions; + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); + + // Send the request batch to subscribe to transactions or outputs + let mut response_receivers = send_transaction_or_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + 0, + max_num_active_subscriptions - 1, + stream_id, + peer_version, + peer_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - max_num_active_subscriptions as usize, - ) - .await; + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + max_num_active_subscriptions as usize, + ) + .await; - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Continuously run the subscription service until all the responses are received - for stream_request_index in 0..max_num_active_subscriptions { - // Determine the target ledger info for the response - let first_version = output_lists_with_proofs[stream_request_index as usize] - .first_transaction_output_version - .unwrap(); - let target_ledger_info = if first_version > epoch_change_version { - highest_ledger_info.clone() - } else { - epoch_change_ledger_info.clone() - }; - - // If we're syncing to the epoch change, then we don't need - // to fallback as the configured network limit won't be reached. - let epoch_change_version = epoch_change_ledger_info.ledger_info().version(); - let fallback_to_transactions = if fallback_to_transactions - && (first_version < epoch_change_version) - && (first_version + max_transaction_output_chunk_size) >= epoch_change_version - { - false - } else { - fallback_to_transactions - }; - - // Verify that the correct response is received - verify_transaction_or_output_subscription_response( - transaction_lists_with_proofs.clone(), - output_lists_with_proofs.clone(), - target_ledger_info.clone(), - fallback_to_transactions, - &mut mock_client, - &mut response_receivers, - stream_request_index, - ) - .await; + // Continuously run the subscription service until all the responses are received + for stream_request_index in 0..max_num_active_subscriptions { + // Determine the target ledger info for the response + let first_version = output_lists_with_proofs[stream_request_index as usize] + .get_first_output_version() + .unwrap(); + let target_ledger_info = if first_version > epoch_change_version { + highest_ledger_info.clone() + } else { + epoch_change_ledger_info.clone() + }; + + // Verify that the correct response is received + verify_transaction_or_output_subscription_response( + transaction_lists_with_proofs.clone(), + output_lists_with_proofs.clone(), + target_ledger_info.clone(), + fallback_to_transactions, + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + } } } } #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_transaction_or_outputs_streaming_loop() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let max_transaction_output_chunk_size = 90; - let num_stream_requests = 30; - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 2; - let peer_version = 1; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the transaction and output lists with proofs - let chunk_start_and_end_versions = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; - let end_version = start_version + max_transaction_output_chunk_size - 1; - (start_version, end_version) - }) - .collect::>(); - let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_output_list_with_proof(*start_version, *end_version, highest_version) - }) - .collect(); - let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions - .iter() - .map(|(start_version, end_version)| { - utils::create_transaction_list_with_proof( - *start_version, - *end_version, - highest_version, - false, - ) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for (i, (start_version, _)) in chunk_start_and_end_versions.iter().enumerate() { - // Set expectations for transaction output reads - utils::expect_get_transaction_outputs( - &mut db_reader, - *start_version, - max_transaction_output_chunk_size, - highest_version, - output_lists_with_proofs[i].clone(), - ); - - // Set expectations for transaction reads - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - *start_version, - max_transaction_output_chunk_size, - highest_version, - false, - transaction_lists_with_proofs[i].clone(), + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let max_transaction_output_chunk_size = 90; + let num_stream_requests = 30; + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 2; + let peer_version = 1; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + + // Create the transaction and output lists with proofs + let chunk_start_and_end_versions = (0..num_stream_requests) + .map(|i| { + let start_version = + peer_version + (i * max_transaction_output_chunk_size) + 1; + let end_version = start_version + max_transaction_output_chunk_size - 1; + (start_version, end_version) + }) + .collect::>(); + let output_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_output_list_with_proof( + *start_version, + *end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + let transaction_lists_with_proofs: Vec<_> = chunk_start_and_end_versions + .iter() + .map(|(start_version, end_version)| { + utils::create_transaction_list_with_proof( + *start_version, + *end_version, + highest_version, + false, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_with_summary_updates( + highest_ledger_info.clone(), + lowest_version, ); - } - } - - // Create the storage service config - let mut storage_service_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_lists_with_proofs[0], - &transaction_lists_with_proofs[0], - ); - storage_service_config.max_transaction_output_chunk_size = - max_transaction_output_chunk_size; - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a new peer and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send the requests to the server and verify the responses - let mut response_receivers = send_transaction_or_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - num_stream_requests - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; + for (i, (start_version, _)) in chunk_start_and_end_versions.iter().enumerate() { + // Set expectations for transaction output reads + utils::expect_get_transaction_outputs( + &mut db_reader, + *start_version, + max_transaction_output_chunk_size, + highest_version, + output_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + + // Set expectations for transaction reads + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + *start_version, + max_transaction_output_chunk_size, + highest_version, + false, + transaction_lists_with_proofs[i].clone(), + use_size_and_time_aware_chunking, + ); + } + } + + // Create the storage service config + let mut storage_service_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_lists_with_proofs[0], + &transaction_lists_with_proofs[0], + use_request_v2, + use_size_and_time_aware_chunking, + ); + storage_service_config.max_transaction_output_chunk_size = + max_transaction_output_chunk_size; - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests as usize, - ) - .await; + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); - // Verify the state of the subscription stream - utils::verify_subscription_stream_entry( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests, - peer_version, - highest_epoch, - max_transaction_output_chunk_size, - ); - - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Create a new peer and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); - // Verify all responses are received - for stream_request_index in 0..num_stream_requests { - let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); - if fallback_to_transactions { - utils::verify_new_transactions_or_outputs_with_proof( + // Send the requests to the server and verify the responses + let mut response_receivers = send_transaction_or_output_subscription_request_batch( &mut mock_client, - response_receiver, - Some(transaction_lists_with_proofs[stream_request_index as usize].clone()), - None, - highest_ledger_info.clone(), + peer_network_id, + 0, + num_stream_requests - 1, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, ) .await; - } else { - utils::verify_new_transactions_or_outputs_with_proof( + + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests as usize, + ) + .await; + + // Verify the state of the subscription stream + utils::verify_subscription_stream_entry( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests, + peer_version, + highest_epoch, + max_transaction_output_chunk_size, + ); + + // Force the subscription handler to work + utils::force_subscription_handler_to_run( &mut mock_client, - response_receiver, - None, - Some(output_lists_with_proofs[stream_request_index as usize].clone()), - highest_ledger_info.clone(), + &mock_time, + &storage_service_notifier, ) .await; + + // Verify all responses are received + for stream_request_index in 0..num_stream_requests { + let response_receiver = + response_receivers.remove(&stream_request_index).unwrap(); + if fallback_to_transactions { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + Some( + transaction_lists_with_proofs[stream_request_index as usize] + .clone(), + ), + None, + highest_ledger_info.clone(), + ) + .await; + } else { + utils::verify_new_transactions_or_outputs_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + None, + Some(output_lists_with_proofs[stream_request_index as usize].clone()), + highest_ledger_info.clone(), + ) + .await; + } + } } } } @@ -879,6 +1042,8 @@ async fn send_transaction_or_output_subscription_request_batch( stream_id: u64, peer_version: u64, peer_epoch: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> HashMap>> { // Shuffle the stream request indices to emulate out of order requests let stream_request_indices = @@ -897,6 +1062,8 @@ async fn send_transaction_or_output_subscription_request_batch( stream_id, stream_request_index, Some(peer_network_id), + use_request_v2, + max_response_bytes_v2, ) .await; @@ -910,19 +1077,21 @@ async fn send_transaction_or_output_subscription_request_batch( /// Verifies that a response is received for a given stream request index /// and that the response contains the correct data. async fn verify_transaction_or_output_subscription_response( - expected_transaction_lists_with_proofs: Vec, - expected_output_lists_with_proofs: Vec, + expected_transaction_lists_with_proofs: Vec, + expected_output_lists_with_proofs: Vec, expected_target_ledger_info: LedgerInfoWithSignatures, fallback_to_transactions: bool, mock_client: &mut MockClient, response_receivers: &mut HashMap>>, stream_request_index: u64, + use_request_v2: bool, ) { let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); if fallback_to_transactions { utils::verify_new_transactions_or_outputs_with_proof( mock_client, response_receiver, + use_request_v2, Some(expected_transaction_lists_with_proofs[stream_request_index as usize].clone()), None, expected_target_ledger_info.clone(), @@ -932,6 +1101,7 @@ async fn verify_transaction_or_output_subscription_response( utils::verify_new_transactions_or_outputs_with_proof( mock_client, response_receiver, + use_request_v2, None, Some(expected_output_lists_with_proofs[stream_request_index as usize].clone()), expected_target_ledger_info.clone(), diff --git a/state-sync/storage-service/server/src/tests/subscription.rs b/state-sync/storage-service/server/src/tests/subscription.rs index 2a3cae53376..3f3ecf16efc 100644 --- a/state-sync/storage-service/server/src/tests/subscription.rs +++ b/state-sync/storage-service/server/src/tests/subscription.rs @@ -35,937 +35,1042 @@ use tokio::runtime::Handle; #[tokio::test] async fn test_peers_with_ready_subscriptions() { - // Create a mock time service and subscriptions map - let time_service = TimeService::mock(); - let subscriptions = Arc::new(DashMap::new()); - - // Create three peers with ready subscriptions - let mut peer_network_ids = vec![]; - for known_version in &[1, 5, 10] { - // Create a random peer network id - let peer_network_id = PeerNetworkId::random(); - peer_network_ids.push(peer_network_id); + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a mock time service and subscriptions map + let time_service = TimeService::mock(); + let subscriptions = Arc::new(DashMap::new()); + + // Create three peers with ready subscriptions + let mut peer_network_ids = vec![]; + for known_version in &[1, 5, 10] { + // Create a random peer network id + let peer_network_id = PeerNetworkId::random(); + peer_network_ids.push(peer_network_id); + + // Create a subscription stream and insert it into the pending map + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(*known_version), + Some(1), + Some(0), + Some(0), + use_request_v2, + ); + subscriptions.insert(peer_network_id, subscription_stream_requests); + } + + // Create epoch ending test data at version 9 + let epoch_ending_ledger_info = utils::create_epoch_ending_ledger_info(1, 9); + let epoch_change_proof = EpochChangeProof { + ledger_info_with_sigs: vec![epoch_ending_ledger_info], + more: false, + }; + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_epoch_ending_ledger_infos( + &mut db_reader, + 1, + 2, + epoch_change_proof, + false, + ); - // Create a subscription stream and insert it into the pending map - let subscription_stream_requests = create_subscription_stream_requests( + // Create the storage reader + let storage_service_config = utils::create_storage_config(use_request_v2, false); + let storage_reader = StorageReader::new( + storage_service_config, + Arc::new(db_reader), time_service.clone(), - Some(*known_version), - Some(1), - Some(0), - Some(0), ); - subscriptions.insert(peer_network_id, subscription_stream_requests); - } - - // Create epoch ending test data at version 9 - let epoch_ending_ledger_info = utils::create_epoch_ending_ledger_info(1, 9); - let epoch_change_proof = EpochChangeProof { - ledger_info_with_sigs: vec![epoch_ending_ledger_info], - more: false, - }; - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_epoch_ending_ledger_infos(&mut db_reader, 1, 2, epoch_change_proof); - - // Create the storage reader - let storage_service_config = StorageServiceConfig::default(); - let storage_reader = StorageReader::new(storage_service_config, Arc::new(db_reader)); - - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let optimistic_fetches = Arc::new(DashMap::new()); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - StorageServiceConfig::default(), - time_service.clone(), - )); - - // Verify that there are no peers with ready subscriptions - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - - // Update the storage server summary so that there is new data (at version 2) - let highest_synced_ledger_info = - utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 2, 1); - - // Verify that peer 1 has a ready subscription - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_subscriptions, vec![( - peer_network_ids[0], - highest_synced_ledger_info - )]); - - // Manually remove subscription 1 from the map - subscriptions.remove(&peer_network_ids[0]); - - // Update the storage server summary so that there is new data (at version 8) - let highest_synced_ledger_info = - utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 8, 1); - - // Verify that peer 2 has a ready subscription - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_subscriptions, vec![( - peer_network_ids[1], - highest_synced_ledger_info - )]); - - // Manually remove subscription 2 from the map - subscriptions.remove(&peer_network_ids[1]); - - // Update the storage server summary so that there is new data (at version 100) - let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 100, 2); - - // Verify that subscription 3 is not returned because it was invalid - // (i.e., the epoch ended at version 9, but the peer didn't respect it). - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_subscriptions, vec![]); + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let optimistic_fetches = Arc::new(DashMap::new()); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), + cached_storage_server_summary.clone(), + mock::create_peers_and_metadata(vec![]), + StorageServiceConfig::default(), + time_service.clone(), + )); + + // Verify that there are no peers with ready subscriptions + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + + // Update the storage server summary so that there is new data (at version 2) + let highest_synced_ledger_info = + utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 2, 1); + + // Verify that peer 1 has a ready subscription + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_subscriptions, vec![( + peer_network_ids[0], + highest_synced_ledger_info + )]); + + // Manually remove subscription 1 from the map + subscriptions.remove(&peer_network_ids[0]); + + // Update the storage server summary so that there is new data (at version 8) + let highest_synced_ledger_info = + utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 8, 1); + + // Verify that peer 2 has a ready subscription + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_subscriptions, vec![( + peer_network_ids[1], + highest_synced_ledger_info + )]); + + // Manually remove subscription 2 from the map + subscriptions.remove(&peer_network_ids[1]); + + // Update the storage server summary so that there is new data (at version 100) + let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 100, 2); + + // Verify that subscription 3 is not returned because it was invalid + // (i.e., the epoch ended at version 9, but the peer didn't respect it). + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_subscriptions, vec![]); - // Verify that the subscriptions are now empty - assert!(subscriptions.is_empty()); + // Verify that the subscriptions are now empty + assert!(subscriptions.is_empty()); + } } #[tokio::test] async fn test_remove_expired_subscriptions_no_new_data() { - // Create a storage service config - let max_subscription_period_ms = 100; - let storage_service_config = StorageServiceConfig { - max_subscription_period_ms, - ..Default::default() - }; - - // Create the mock storage reader and time service - let db_reader = mock::create_mock_db_reader(); - let storage_reader = StorageReader::new(storage_service_config, Arc::new(db_reader)); - let time_service = TimeService::mock(); - - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let optimistic_fetches = Arc::new(DashMap::new()); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - StorageServiceConfig::default(), - time_service.clone(), - )); - - // Create the first batch of test subscriptions - let num_subscriptions_in_batch = 10; - let subscriptions = Arc::new(DashMap::new()); - for _ in 0..num_subscriptions_in_batch { - let subscription_stream_requests = - create_subscription_stream_requests(time_service.clone(), Some(9), Some(9), None, None); - subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); - } + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_subscription_period_ms = 100; + let storage_service_config = StorageServiceConfig { + max_subscription_period_ms, + ..Default::default() + }; + + // Create the mock storage reader and time service + let db_reader = mock::create_mock_db_reader(); + let time_service = TimeService::mock(); + let storage_reader = StorageReader::new( + storage_service_config, + Arc::new(db_reader), + time_service.clone(), + ); - // Verify the number of active subscriptions - assert_eq!(subscriptions.len(), num_subscriptions_in_batch); - - // Elapse a small amount of time (not enough to expire the subscriptions) - utils::elapse_time(max_subscription_period_ms / 2, &time_service).await; - - // Update the storage server summary so that there is new data - let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 1, 1); - - // Remove the expired subscriptions and verify none were removed - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - assert_eq!(subscriptions.len(), num_subscriptions_in_batch); - - // Create another batch of test subscriptions - for _ in 0..num_subscriptions_in_batch { - let subscription_stream_requests = - create_subscription_stream_requests(time_service.clone(), Some(9), Some(9), None, None); - subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let optimistic_fetches = Arc::new(DashMap::new()); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), + cached_storage_server_summary.clone(), + mock::create_peers_and_metadata(vec![]), + StorageServiceConfig::default(), + time_service.clone(), + )); + + // Create the first batch of test subscriptions + let num_subscriptions_in_batch = 10; + let subscriptions = Arc::new(DashMap::new()); + for _ in 0..num_subscriptions_in_batch { + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(9), + Some(9), + None, + None, + use_request_v2, + ); + subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); + } + + // Verify the number of active subscriptions + assert_eq!(subscriptions.len(), num_subscriptions_in_batch); + + // Elapse a small amount of time (not enough to expire the subscriptions) + utils::elapse_time(max_subscription_period_ms / 2, &time_service).await; + + // Update the storage server summary so that there is new data + let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 1, 1); + + // Remove the expired subscriptions and verify none were removed + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + assert_eq!(subscriptions.len(), num_subscriptions_in_batch); + + // Create another batch of test subscriptions + for _ in 0..num_subscriptions_in_batch { + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(9), + Some(9), + None, + None, + use_request_v2, + ); + subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); + } + + // Verify the new number of active subscriptions + assert_eq!(subscriptions.len(), num_subscriptions_in_batch * 2); + + // Elapse enough time to expire the first batch of subscriptions + utils::elapse_time(max_subscription_period_ms, &time_service).await; + + // Remove the expired subscriptions and verify the first batch was removed + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + assert_eq!(subscriptions.len(), num_subscriptions_in_batch); + + // Elapse enough time to expire the second batch of subscriptions + utils::elapse_time(max_subscription_period_ms, &time_service).await; + + // Remove the expired subscriptions and verify the second batch was removed + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + assert!(subscriptions.is_empty()); } - - // Verify the new number of active subscriptions - assert_eq!(subscriptions.len(), num_subscriptions_in_batch * 2); - - // Elapse enough time to expire the first batch of subscriptions - utils::elapse_time(max_subscription_period_ms, &time_service).await; - - // Remove the expired subscriptions and verify the first batch was removed - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - assert_eq!(subscriptions.len(), num_subscriptions_in_batch); - - // Elapse enough time to expire the second batch of subscriptions - utils::elapse_time(max_subscription_period_ms, &time_service).await; - - // Remove the expired subscriptions and verify the second batch was removed - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - assert!(subscriptions.is_empty()); } #[tokio::test] async fn test_remove_expired_subscriptions_blocked_stream() { - // Create a storage service config - let max_subscription_period_ms = 100; - let storage_service_config = StorageServiceConfig { - max_subscription_period_ms, - ..Default::default() - }; - - // Create a mock time service - let time_service = TimeService::mock(); - - // Create a batch of test subscriptions - let num_subscriptions_in_batch = 10; - let subscriptions = Arc::new(DashMap::new()); - let mut peer_network_ids = vec![]; - for i in 0..num_subscriptions_in_batch { - // Create a new peer - let peer_network_id = PeerNetworkId::random(); - peer_network_ids.push(peer_network_id); + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_subscription_period_ms = 100; + let storage_service_config = StorageServiceConfig { + max_subscription_period_ms, + ..Default::default() + }; + + // Create a mock time service + let time_service = TimeService::mock(); + + // Create a batch of test subscriptions + let num_subscriptions_in_batch = 10; + let subscriptions = Arc::new(DashMap::new()); + let mut peer_network_ids = vec![]; + for i in 0..num_subscriptions_in_batch { + // Create a new peer + let peer_network_id = PeerNetworkId::random(); + peer_network_ids.push(peer_network_id); + + // Create a subscription stream request for the peer + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(1), + Some(1), + Some(i as u64), + Some(0), + use_request_v2, + ); + subscriptions.insert(peer_network_id, subscription_stream_requests); + } + + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let optimistic_fetches = Arc::new(DashMap::new()); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), + cached_storage_server_summary.clone(), + mock::create_peers_and_metadata(vec![]), + StorageServiceConfig::default(), + time_service.clone(), + )); + let storage_reader = StorageReader::new( + storage_service_config, + Arc::new(mock::create_mock_db_reader()), + time_service.clone(), + ); - // Create a subscription stream request for the peer - let subscription_stream_requests = create_subscription_stream_requests( + // Update the storage server summary so that there is new data (at version 5) + let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 5, 1); + + // Handle the active subscriptions + subscription::handle_active_subscriptions( + Handle::current(), + cached_storage_server_summary.clone(), + storage_service_config, + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), time_service.clone(), + ) + .await + .unwrap(); + + // Verify that all subscription streams are now empty because + // the pending requests were sent. + assert_eq!(subscriptions.len(), num_subscriptions_in_batch); + for subscription in subscriptions.iter() { + assert!(subscription.value().first_pending_request().is_none()); + } + + // Elapse enough time to expire the blocked streams + utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; + + // Add a new subscription request to the first subscription stream + let subscription_request = create_subscription_request( + &time_service, Some(1), Some(1), - Some(i as u64), Some(0), + Some(1), + use_request_v2, ); - subscriptions.insert(peer_network_id, subscription_stream_requests); - } - - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let optimistic_fetches = Arc::new(DashMap::new()); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - StorageServiceConfig::default(), - time_service.clone(), - )); - let storage_reader = StorageReader::new( - storage_service_config, - Arc::new(mock::create_mock_db_reader()), - ); - - // Update the storage server summary so that there is new data (at version 5) - let _ = utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 5, 1); - - // Handle the active subscriptions - subscription::handle_active_subscriptions( - Handle::current(), - cached_storage_server_summary.clone(), - storage_service_config, - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - - // Verify that all subscription streams are now empty because - // the pending requests were sent. - assert_eq!(subscriptions.len(), num_subscriptions_in_batch); - for subscription in subscriptions.iter() { - assert!(subscription.value().first_pending_request().is_none()); + add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_ids[0], + ) + .unwrap(); + + // Remove the expired subscriptions and verify the second batch was removed + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + assert_eq!(subscriptions.len(), 1); + assert!(subscriptions.contains_key(&peer_network_ids[0])); } - - // Elapse enough time to expire the blocked streams - utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; - - // Add a new subscription request to the first subscription stream - let subscription_request = - create_subscription_request(&time_service, Some(1), Some(1), Some(0), Some(1)); - add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_ids[0], - ) - .unwrap(); - - // Remove the expired subscriptions and verify the second batch was removed - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - assert_eq!(subscriptions.len(), 1); - assert!(subscriptions.contains_key(&peer_network_ids[0])); } #[tokio::test] async fn test_remove_expired_subscriptions_blocked_stream_index() { - // Create a storage service config - let max_subscription_period_ms = 100; - let storage_service_config = StorageServiceConfig { - max_subscription_period_ms, - ..Default::default() - }; + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_subscription_period_ms = 100; + let storage_service_config = StorageServiceConfig { + max_subscription_period_ms, + ..Default::default() + }; + + // Create a mock time service + let time_service = TimeService::mock(); + + // Create the first batch of test subscriptions + let num_subscriptions_in_batch = 10; + let subscriptions = Arc::new(DashMap::new()); + for _ in 0..num_subscriptions_in_batch { + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(1), + Some(1), + None, + Some(0), + use_request_v2, + ); + subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); + } + + // Create test data with an empty storage server summary + let cached_storage_server_summary = + Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); + let optimistic_fetches = Arc::new(DashMap::new()); + let lru_response_cache = Cache::new(0); + let request_moderator = Arc::new(RequestModerator::new( + AptosDataClientConfig::default(), + cached_storage_server_summary.clone(), + mock::create_peers_and_metadata(vec![]), + StorageServiceConfig::default(), + time_service.clone(), + )); + let storage_reader = StorageReader::new( + storage_service_config, + Arc::new(mock::create_mock_db_reader()), + time_service.clone(), + ); - // Create a mock time service - let time_service = TimeService::mock(); + // Update the storage server summary so that there is new data (at version 5) + let highest_synced_ledger_info = + utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 5, 1); + + // Verify that all peers have ready subscriptions (but don't serve them!) + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!( + peers_with_ready_subscriptions.len(), + num_subscriptions_in_batch + ); - // Create the first batch of test subscriptions - let num_subscriptions_in_batch = 10; - let subscriptions = Arc::new(DashMap::new()); - for _ in 0..num_subscriptions_in_batch { - let subscription_stream_requests = create_subscription_stream_requests( + // Elapse enough time to expire the subscriptions + utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; + + // Remove the expired subscriptions and verify they were all removed + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + assert!(subscriptions.is_empty()); + + // Create another batch of test subscriptions (where the stream is + // blocked on the next index to serve). + let mut peer_network_ids = vec![]; + for i in 0..num_subscriptions_in_batch { + // Create a new peer + let peer_network_id = PeerNetworkId::random(); + peer_network_ids.push(peer_network_id); + + // Create a subscription stream request for the peer + let subscription_stream_requests = create_subscription_stream_requests( + time_service.clone(), + Some(1), + Some(1), + None, + Some(i as u64 + 1), + use_request_v2, + ); + subscriptions.insert(peer_network_id, subscription_stream_requests); + } + + // Verify the number of active subscriptions + assert_eq!(subscriptions.len(), num_subscriptions_in_batch); + + // Verify that none of the subscriptions are ready to be served (they are blocked) + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert!(peers_with_ready_subscriptions.is_empty()); + + // Elapse enough time to expire the batch of subscriptions + utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; + + // Add a new subscription request to the first subscription stream (to unblock it) + let subscription_request = create_subscription_request( + &time_service, Some(1), Some(1), None, Some(0), + use_request_v2, ); - subscriptions.insert(PeerNetworkId::random(), subscription_stream_requests); + add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_ids[0], + ) + .unwrap(); + + // Verify that the first peer subscription stream is unblocked + let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(peers_with_ready_subscriptions.len(), 1); + assert!(peers_with_ready_subscriptions + .contains(&(peer_network_ids[0], highest_synced_ledger_info))); + + // Remove the expired subscriptions and verify all but one were removed + let _ = subscription::get_peers_with_ready_subscriptions( + Handle::current(), + storage_service_config, + cached_storage_server_summary.clone(), + optimistic_fetches.clone(), + lru_response_cache.clone(), + request_moderator.clone(), + storage_reader.clone(), + subscriptions.clone(), + time_service.clone(), + ) + .await + .unwrap(); + assert_eq!(subscriptions.len(), 1); + assert!(subscriptions.contains_key(&peer_network_ids[0])); } +} - // Create test data with an empty storage server summary - let cached_storage_server_summary = - Arc::new(ArcSwap::from(Arc::new(StorageServerSummary::default()))); - let optimistic_fetches = Arc::new(DashMap::new()); - let lru_response_cache = Cache::new(0); - let request_moderator = Arc::new(RequestModerator::new( - AptosDataClientConfig::default(), - cached_storage_server_summary.clone(), - mock::create_peers_and_metadata(vec![]), - StorageServiceConfig::default(), - time_service.clone(), - )); - let storage_reader = StorageReader::new( - storage_service_config, - Arc::new(mock::create_mock_db_reader()), - ); - - // Update the storage server summary so that there is new data (at version 5) - let highest_synced_ledger_info = - utils::update_storage_summary_cache(cached_storage_server_summary.clone(), 5, 1); - - // Verify that all peers have ready subscriptions (but don't serve them!) - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!( - peers_with_ready_subscriptions.len(), - num_subscriptions_in_batch - ); +#[tokio::test(flavor = "multi_thread")] +async fn test_subscription_invalid_requests() { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a mock time service + let time_service = TimeService::mock(); - // Elapse enough time to expire the subscriptions - utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; - - // Remove the expired subscriptions and verify they were all removed - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - assert!(subscriptions.is_empty()); - - // Create another batch of test subscriptions (where the stream is - // blocked on the next index to serve). - let mut peer_network_ids = vec![]; - for i in 0..num_subscriptions_in_batch { - // Create a new peer + // Create a new batch of subscriptions that includes a single stream and request + let subscriptions = Arc::new(DashMap::new()); let peer_network_id = PeerNetworkId::random(); - peer_network_ids.push(peer_network_id); - - // Create a subscription stream request for the peer + let peer_known_version = 10; + let peer_known_epoch = 1; + let subscription_stream_id = utils::get_random_u64(); let subscription_stream_requests = create_subscription_stream_requests( time_service.clone(), + Some(peer_known_version), + Some(peer_known_epoch), + Some(subscription_stream_id), + Some(0), + use_request_v2, + ); + subscriptions.insert(peer_network_id, subscription_stream_requests); + + // Add a request to the stream that is invalid (the stream id is incorrect) + let subscription_request = create_subscription_request( + &time_service, + Some(peer_known_version), + Some(peer_known_epoch), + Some(subscription_stream_id + 1), Some(1), + use_request_v2, + ); + let (error, _) = add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_id, + ) + .unwrap_err(); + assert_matches!(error, Error::InvalidRequest(_)); + + // Add a request to the stream that is invalid (the known version is incorrect) + let subscription_request = create_subscription_request( + &time_service, + Some(peer_known_version + 1), + Some(peer_known_epoch), + Some(subscription_stream_id), Some(1), - None, - Some(i as u64 + 1), + use_request_v2, ); - subscriptions.insert(peer_network_id, subscription_stream_requests); + let (error, _) = add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_id, + ) + .unwrap_err(); + assert_matches!(error, Error::InvalidRequest(_)); + + // Add a request to the stream that is invalid (the known epoch is incorrect) + let subscription_request = create_subscription_request( + &time_service, + Some(peer_known_version), + Some(peer_known_epoch + 1), + Some(subscription_stream_id), + Some(1), + use_request_v2, + ); + let (error, _) = add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_id, + ) + .unwrap_err(); + assert_matches!(error, Error::InvalidRequest(_)); + + // Update the next index to serve for the stream + let next_index_to_serve = 10; + let mut subscription = subscriptions.get_mut(&peer_network_id).unwrap(); + let subscription_stream_requests = subscription.value_mut(); + subscription_stream_requests.set_next_index_to_serve(next_index_to_serve); + drop(subscription); + + // Add a request to the stream that is invalid (the stream index is less than the next index to serve) + let subscription_request = create_subscription_request( + &time_service, + Some(peer_known_version), + Some(peer_known_epoch), + Some(subscription_stream_id), + Some(next_index_to_serve - 1), + use_request_v2, + ); + let (error, _) = add_subscription_request_to_stream( + subscription_request, + subscriptions.clone(), + &peer_network_id, + ) + .unwrap_err(); + assert_matches!(error, Error::InvalidRequest(_)); } - - // Verify the number of active subscriptions - assert_eq!(subscriptions.len(), num_subscriptions_in_batch); - - // Verify that none of the subscriptions are ready to be served (they are blocked) - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert!(peers_with_ready_subscriptions.is_empty()); - - // Elapse enough time to expire the batch of subscriptions - utils::elapse_time(max_subscription_period_ms + 1, &time_service).await; - - // Add a new subscription request to the first subscription stream (to unblock it) - let subscription_request = - create_subscription_request(&time_service, Some(1), Some(1), None, Some(0)); - add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_ids[0], - ) - .unwrap(); - - // Verify that the first peer subscription stream is unblocked - let peers_with_ready_subscriptions = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(peers_with_ready_subscriptions.len(), 1); - assert!( - peers_with_ready_subscriptions.contains(&(peer_network_ids[0], highest_synced_ledger_info)) - ); - - // Remove the expired subscriptions and verify all but one were removed - let _ = subscription::get_peers_with_ready_subscriptions( - Handle::current(), - storage_service_config, - cached_storage_server_summary.clone(), - optimistic_fetches.clone(), - lru_response_cache.clone(), - request_moderator.clone(), - storage_reader.clone(), - subscriptions.clone(), - time_service.clone(), - ) - .await - .unwrap(); - assert_eq!(subscriptions.len(), 1); - assert!(subscriptions.contains_key(&peer_network_ids[0])); } #[tokio::test(flavor = "multi_thread")] -async fn test_subscription_invalid_requests() { - // Create a mock time service - let time_service = TimeService::mock(); - - // Create a new batch of subscriptions that includes a single stream and request - let subscriptions = Arc::new(DashMap::new()); - let peer_network_id = PeerNetworkId::random(); - let peer_known_version = 10; - let peer_known_epoch = 1; - let subscription_stream_id = utils::get_random_u64(); - let subscription_stream_requests = create_subscription_stream_requests( - time_service.clone(), - Some(peer_known_version), - Some(peer_known_epoch), - Some(subscription_stream_id), - Some(0), - ); - subscriptions.insert(peer_network_id, subscription_stream_requests); +async fn test_subscription_max_pending_requests() { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let max_transaction_output_chunk_size = 5; + let max_num_active_subscriptions = 10; + let storage_service_config = StorageServiceConfig { + max_num_active_subscriptions, + max_transaction_output_chunk_size, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: false, + ..Default::default() + }; + + // Create test data + let num_stream_requests = max_num_active_subscriptions * 10; // Send more requests than allowed + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 0; + let peer_version = 50; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + + // Create the output lists with proofs + let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) + .map(|i| { + let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; + let end_version = start_version + max_transaction_output_chunk_size - 1; + utils::create_output_list_with_proof( + start_version, + end_version, + highest_version, + use_request_v2, + ) + }) + .collect(); + + // Create the mock db reader + let mut db_reader = + mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); + for stream_request_index in 0..num_stream_requests { + utils::expect_get_transaction_outputs( + &mut db_reader, + peer_version + (stream_request_index * max_transaction_output_chunk_size) + 1, + max_transaction_output_chunk_size, + highest_version, + output_lists_with_proofs[stream_request_index as usize].clone(), + false, + ); + } + + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_service_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Send the maximum number of stream requests + let peer_network_id = PeerNetworkId::random(); + let stream_id = 101; + let mut response_receivers = utils::send_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + 0, + max_num_active_subscriptions - 1, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Add a request to the stream that is invalid (the stream id is incorrect) - let subscription_request = create_subscription_request( - &time_service, - Some(peer_known_version), - Some(peer_known_epoch), - Some(subscription_stream_id + 1), - Some(1), - ); - let (error, _) = add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_id, - ) - .unwrap_err(); - assert_matches!(error, Error::InvalidRequest(_)); + // Wait until the maximum number of stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + max_num_active_subscriptions as usize, + ) + .await; - // Add a request to the stream that is invalid (the known version is incorrect) - let subscription_request = create_subscription_request( - &time_service, - Some(peer_known_version + 1), - Some(peer_known_epoch), - Some(subscription_stream_id), - Some(1), - ); - let (error, _) = add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_id, - ) - .unwrap_err(); - assert_matches!(error, Error::InvalidRequest(_)); + // Send another batch of stream requests (to exceed the maximum number of + // subscriptions), and verify that the client receives a failure for each request. + for stream_request_index in max_num_active_subscriptions..max_num_active_subscriptions * 2 { + // Send the transaction output subscription request + let response_receiver = utils::subscribe_to_transaction_outputs_for_peer( + &mut mock_client, + peer_version, + highest_epoch, + stream_id, + stream_request_index, + Some(peer_network_id), + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Verify that the client receives an invalid request error + let response = mock_client + .wait_for_response(response_receiver) + .await + .unwrap_err(); + assert!(matches!(response, StorageServiceError::InvalidRequest(_))); + } + + // Verify the request indices that are pending + verify_pending_subscription_request_indices( + active_subscriptions.clone(), + peer_network_id, + 0, + max_num_active_subscriptions, + num_stream_requests, + ); - // Add a request to the stream that is invalid (the known epoch is incorrect) - let subscription_request = create_subscription_request( - &time_service, - Some(peer_known_version), - Some(peer_known_epoch + 1), - Some(subscription_stream_id), - Some(1), - ); - let (error, _) = add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_id, - ) - .unwrap_err(); - assert_matches!(error, Error::InvalidRequest(_)); + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Update the next index to serve for the stream - let next_index_to_serve = 10; - let mut subscription = subscriptions.get_mut(&peer_network_id).unwrap(); - let subscription_stream_requests = subscription.value_mut(); - subscription_stream_requests.set_next_index_to_serve(next_index_to_serve); - drop(subscription); + // Continuously run the subscription service until all of the responses are sent + for stream_request_index in 0..max_num_active_subscriptions { + // Verify that the correct response is received + utils::verify_output_subscription_response( + output_lists_with_proofs.clone(), + highest_ledger_info.clone(), + &mut mock_client, + &mut response_receivers, + stream_request_index, + use_request_v2, + ) + .await; + } + + // Send another batch of requests for transaction outputs + let _response_receivers = utils::send_output_subscription_request_batch( + &mut mock_client, + peer_network_id, + max_num_active_subscriptions, + (max_num_active_subscriptions * 2) - 1, + stream_id, + peer_version, + highest_epoch, + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; - // Add a request to the stream that is invalid (the stream index is less than the next index to serve) - let subscription_request = create_subscription_request( - &time_service, - Some(peer_known_version), - Some(peer_known_epoch), - Some(subscription_stream_id), - Some(next_index_to_serve - 1), - ); - let (error, _) = add_subscription_request_to_stream( - subscription_request, - subscriptions.clone(), - &peer_network_id, - ) - .unwrap_err(); - assert_matches!(error, Error::InvalidRequest(_)); + // Wait until the maximum number of stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + max_num_active_subscriptions as usize, + ) + .await; + + // Send another batch of stream requests (to exceed the maximum number of + // subscriptions), and verify that the client receives a failure for each request. + for stream_request_index in + max_num_active_subscriptions * 2..max_num_active_subscriptions * 3 + { + // Send the transaction output subscription request + let response_receiver = utils::subscribe_to_transaction_outputs_for_peer( + &mut mock_client, + peer_version, + highest_epoch, + stream_id, + stream_request_index, + Some(peer_network_id), + use_request_v2, + storage_service_config.max_network_chunk_bytes_v2, + ) + .await; + + // Verify that the client receives an invalid request error + let response = mock_client + .wait_for_response(response_receiver) + .await + .unwrap_err(); + assert!(matches!(response, StorageServiceError::InvalidRequest(_))); + } + + // Verify the request indices that are pending + verify_pending_subscription_request_indices( + active_subscriptions, + peer_network_id, + max_num_active_subscriptions, + max_num_active_subscriptions * 2, + num_stream_requests, + ); + } } #[tokio::test(flavor = "multi_thread")] -async fn test_subscription_max_pending_requests() { - // Create a storage service config - let max_transaction_output_chunk_size = 5; - let max_num_active_subscriptions = 10; - let storage_service_config = StorageServiceConfig { - max_num_active_subscriptions, - max_transaction_output_chunk_size, - ..Default::default() - }; +async fn test_subscription_overwrite_streams() { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let highest_version = 45576; + let highest_epoch = 43; + let lowest_version = 0; + let peer_version = highest_version - 100; + let highest_ledger_info = + utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); + let output_list_with_proof = utils::create_output_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + peer_version + 1, + highest_version, + highest_version, + false, + use_request_v2, + ); - // Create test data - let num_stream_requests = max_num_active_subscriptions * 10; // Send more requests than allowed - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 0; - let peer_version = 50; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - - // Create the output lists with proofs - let output_lists_with_proofs: Vec<_> = (0..num_stream_requests) - .map(|i| { - let start_version = peer_version + (i * max_transaction_output_chunk_size) + 1; - let end_version = start_version + max_transaction_output_chunk_size - 1; - utils::create_output_list_with_proof(start_version, end_version, highest_version) - }) - .collect(); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - for stream_request_index in 0..num_stream_requests { + // Create the mock db reader + let mut db_reader = + mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); utils::expect_get_transaction_outputs( &mut db_reader, - peer_version + (stream_request_index * max_transaction_output_chunk_size) + 1, - max_transaction_output_chunk_size, + peer_version + 1, + highest_version - peer_version, highest_version, - output_lists_with_proofs[stream_request_index as usize].clone(), + output_list_with_proof.clone(), + false, + ); + utils::expect_get_transactions( + &mut db_reader, + peer_version + 1, + highest_version - peer_version, + highest_version, + false, + transaction_list_with_proof.clone(), + false, ); - } - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), Some(storage_service_config)); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Send the maximum number of stream requests - let peer_network_id = PeerNetworkId::random(); - let stream_id = 101; - let mut response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - max_num_active_subscriptions - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; + // Create a storage service config + let storage_config = utils::create_storage_config(use_request_v2, false); - // Wait until the maximum number of stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - max_num_active_subscriptions as usize, - ) - .await; + // Create the storage client and server + let (mut mock_client, service, storage_service_notifier, mock_time, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + let active_subscriptions = service.get_subscriptions(); + tokio::spawn(service.start()); + + // Create a peer network ID and stream ID + let peer_network_id = PeerNetworkId::random(); + let stream_id = utils::get_random_u64(); - // Send another batch of stream requests (to exceed the maximum number of - // subscriptions), and verify that the client receives a failure for each request. - for stream_request_index in max_num_active_subscriptions..max_num_active_subscriptions * 2 { - // Send the transaction output subscription request - let response_receiver = utils::subscribe_to_transaction_outputs_for_peer( + // Send multiple requests to subscribe to transaction outputs with the stream ID + let num_stream_requests = 10; + let mut response_receivers = utils::send_output_subscription_request_batch( &mut mock_client, + peer_network_id, + 0, + num_stream_requests - 1, + stream_id, peer_version, highest_epoch, - stream_id, - stream_request_index, - Some(peer_network_id), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, ) .await; - // Verify that the client receives an invalid request error - let response = mock_client - .wait_for_response(response_receiver) - .await - .unwrap_err(); - assert!(matches!(response, StorageServiceError::InvalidRequest(_))); - } + // Wait until the stream requests are active + utils::wait_for_active_stream_requests( + active_subscriptions.clone(), + peer_network_id, + num_stream_requests as usize, + ) + .await; - // Verify the request indices that are pending - verify_pending_subscription_request_indices( - active_subscriptions.clone(), - peer_network_id, - 0, - max_num_active_subscriptions, - num_stream_requests, - ); + // Verify no subscription response has been received yet + utils::verify_no_subscription_responses(&mut response_receivers); - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; + // Force the subscription handler to work + utils::force_subscription_handler_to_run( + &mut mock_client, + &mock_time, + &storage_service_notifier, + ) + .await; - // Continuously run the subscription service until all of the responses are sent - for stream_request_index in 0..max_num_active_subscriptions { - // Verify that the correct response is received + // Verify that the correct response is received (when it comes through) utils::verify_output_subscription_response( - output_lists_with_proofs.clone(), + vec![output_list_with_proof.clone()], highest_ledger_info.clone(), &mut mock_client, &mut response_receivers, - stream_request_index, + 0, + use_request_v2, ) .await; - } - - // Send another batch of requests for transaction outputs - let _response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - max_num_active_subscriptions, - (max_num_active_subscriptions * 2) - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; - // Wait until the maximum number of stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - max_num_active_subscriptions as usize, - ) - .await; - - // Send another batch of stream requests (to exceed the maximum number of - // subscriptions), and verify that the client receives a failure for each request. - for stream_request_index in max_num_active_subscriptions * 2..max_num_active_subscriptions * 3 { - // Send the transaction output subscription request - let response_receiver = utils::subscribe_to_transaction_outputs_for_peer( + // Send a request to subscribe to transactions with a new stream ID + let new_stream_id = utils::get_random_u64(); + let response_receiver = utils::subscribe_to_transactions_for_peer( &mut mock_client, peer_version, highest_epoch, - stream_id, - stream_request_index, + false, + new_stream_id, + 0, Some(peer_network_id), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, ) .await; - // Verify that the client receives an invalid request error - let response = mock_client - .wait_for_response(response_receiver) - .await - .unwrap_err(); - assert!(matches!(response, StorageServiceError::InvalidRequest(_))); - } - - // Verify the request indices that are pending - verify_pending_subscription_request_indices( - active_subscriptions, - peer_network_id, - max_num_active_subscriptions, - max_num_active_subscriptions * 2, - num_stream_requests, - ); -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_subscription_overwrite_streams() { - // Create test data - let highest_version = 45576; - let highest_epoch = 43; - let lowest_version = 0; - let peer_version = highest_version - 100; - let highest_ledger_info = - utils::create_test_ledger_info_with_sigs(highest_epoch, highest_version); - let output_list_with_proof = - utils::create_output_list_with_proof(peer_version + 1, highest_version, highest_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - peer_version + 1, - highest_version, - highest_version, - false, - ); - - // Create the mock db reader - let mut db_reader = - mock::create_mock_db_with_summary_updates(highest_ledger_info.clone(), lowest_version); - utils::expect_get_transaction_outputs( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - output_list_with_proof.clone(), - ); - utils::expect_get_transactions( - &mut db_reader, - peer_version + 1, - highest_version - peer_version, - highest_version, - false, - transaction_list_with_proof.clone(), - ); - - // Create the storage client and server - let (mut mock_client, service, storage_service_notifier, mock_time, _) = - MockClient::new(Some(db_reader), None); - let active_subscriptions = service.get_subscriptions(); - tokio::spawn(service.start()); - - // Create a peer network ID and stream ID - let peer_network_id = PeerNetworkId::random(); - let stream_id = utils::get_random_u64(); - - // Send multiple requests to subscribe to transaction outputs with the stream ID - let num_stream_requests = 10; - let mut response_receivers = utils::send_output_subscription_request_batch( - &mut mock_client, - peer_network_id, - 0, - num_stream_requests - 1, - stream_id, - peer_version, - highest_epoch, - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests( - active_subscriptions.clone(), - peer_network_id, - num_stream_requests as usize, - ) - .await; - - // Verify no subscription response has been received yet - utils::verify_no_subscription_responses(&mut response_receivers); + // Wait until the stream requests are active + utils::wait_for_active_stream_requests(active_subscriptions.clone(), peer_network_id, 1) + .await; - // Force the subscription handler to work - utils::force_subscription_handler_to_run( - &mut mock_client, - &mock_time, - &storage_service_notifier, - ) - .await; - - // Verify that the correct response is received (when it comes through) - utils::verify_output_subscription_response( - vec![output_list_with_proof.clone()], - highest_ledger_info.clone(), - &mut mock_client, - &mut response_receivers, - 0, - ) - .await; - - // Send a request to subscribe to transactions with a new stream ID - let new_stream_id = utils::get_random_u64(); - let response_receiver = utils::subscribe_to_transactions_for_peer( - &mut mock_client, - peer_version, - highest_epoch, - false, - new_stream_id, - 0, - Some(peer_network_id), - ) - .await; - - // Wait until the stream requests are active - utils::wait_for_active_stream_requests(active_subscriptions.clone(), peer_network_id, 1).await; + // Verify the new stream ID has been used + utils::verify_active_stream_id_for_peer( + active_subscriptions.clone(), + peer_network_id, + new_stream_id, + ); - // Verify the new stream ID has been used - utils::verify_active_stream_id_for_peer( - active_subscriptions.clone(), - peer_network_id, - new_stream_id, - ); + // Force the subscription handler to work + utils::force_cache_update_notification( + &mut mock_client, + &mock_time, + &storage_service_notifier, + true, + true, + ) + .await; - // Force the subscription handler to work - utils::force_cache_update_notification( - &mut mock_client, - &mock_time, - &storage_service_notifier, - true, - true, - ) - .await; - - // Verify a response is received and that it contains the correct data - utils::verify_new_transactions_with_proof( - &mut mock_client, - response_receiver, - transaction_list_with_proof, - highest_ledger_info, - ) - .await; + // Verify a response is received and that it contains the correct data + utils::verify_new_transactions_with_proof( + &mut mock_client, + response_receiver, + use_request_v2, + transaction_list_with_proof, + highest_ledger_info, + ) + .await; + } } /// Adds a subscription request to the subscription stream for the given peer @@ -986,6 +1091,7 @@ fn create_subscription_data_request( known_epoch_at_stream_start: Option, subscription_stream_id: Option, subscription_stream_index: Option, + use_request_v2: bool, ) -> DataRequest { // Get the request data let known_version_at_stream_start = known_version_at_stream_start.unwrap_or_default(); @@ -1003,25 +1109,57 @@ fn create_subscription_data_request( // Generate the random data request let random_number = utils::get_random_u64(); match random_number % 3 { - 0 => DataRequest::SubscribeTransactionOutputsWithProof( - SubscribeTransactionOutputsWithProofRequest { - subscription_stream_metadata, - subscription_stream_index, - }, - ), - 1 => DataRequest::SubscribeTransactionsWithProof(SubscribeTransactionsWithProofRequest { - subscription_stream_metadata, - include_events: false, - subscription_stream_index, - }), - 2 => DataRequest::SubscribeTransactionsOrOutputsWithProof( - SubscribeTransactionsOrOutputsWithProofRequest { - subscription_stream_metadata, - include_events: false, - max_num_output_reductions: 0, - subscription_stream_index, - }, - ), + 0 => { + if use_request_v2 { + DataRequest::subscribe_transaction_data_with_proof( + subscription_stream_metadata, + subscription_stream_index, + true, + 0, + ) + } else { + DataRequest::SubscribeTransactionsWithProof(SubscribeTransactionsWithProofRequest { + subscription_stream_metadata, + subscription_stream_index, + include_events: true, + }) + } + }, + 1 => { + if use_request_v2 { + DataRequest::subscribe_transaction_output_data_with_proof( + subscription_stream_metadata, + subscription_stream_index, + 0, + ) + } else { + DataRequest::SubscribeTransactionOutputsWithProof( + SubscribeTransactionOutputsWithProofRequest { + subscription_stream_metadata, + subscription_stream_index, + }, + ) + } + }, + 2 => { + if use_request_v2 { + DataRequest::subscribe_transaction_or_output_data_with_proof( + subscription_stream_metadata, + subscription_stream_index, + true, + 0, + ) + } else { + DataRequest::SubscribeTransactionsOrOutputsWithProof( + SubscribeTransactionsOrOutputsWithProofRequest { + subscription_stream_metadata, + include_events: false, + max_num_output_reductions: 0, + subscription_stream_index, + }, + ) + } + }, number => panic!("This shouldn't be possible! Got: {:?}", number), } } @@ -1033,6 +1171,7 @@ fn create_subscription_request( known_epoch: Option, subscription_stream_id: Option, subscription_stream_index: Option, + use_request_v2: bool, ) -> SubscriptionRequest { // Create a storage service request let data_request = create_subscription_data_request( @@ -1040,6 +1179,7 @@ fn create_subscription_request( known_epoch, subscription_stream_id, subscription_stream_index, + use_request_v2, ); let storage_service_request = StorageServiceRequest::new(data_request, true); @@ -1062,6 +1202,7 @@ fn create_subscription_stream_requests( known_epoch: Option, subscription_stream_id: Option, subscription_stream_index: Option, + use_request_v2: bool, ) -> SubscriptionStreamRequests { // Create a new subscription request let subscription_request = create_subscription_request( @@ -1070,6 +1211,7 @@ fn create_subscription_stream_requests( known_epoch, subscription_stream_id, subscription_stream_index, + use_request_v2, ); // Create and return the subscription stream containing the request diff --git a/state-sync/storage-service/server/src/tests/transaction_outputs.rs b/state-sync/storage-service/server/src/tests/transaction_outputs.rs index 20fc99654f9..78d266339b8 100644 --- a/state-sync/storage-service/server/src/tests/transaction_outputs.rs +++ b/state-sync/storage-service/server/src/tests/transaction_outputs.rs @@ -1,174 +1,306 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::tests::{mock, mock::MockClient, utils}; +use crate::tests::{ + mock, + mock::{MockClient, MockDatabaseReader}, + utils, +}; use aptos_config::config::StorageServiceConfig; use aptos_storage_service_types::{ requests::{DataRequest, TransactionOutputsWithProofRequest}, - responses::{DataResponse, StorageServiceResponse}, + responses::{DataResponse, StorageServiceResponse, TransactionDataResponseType}, StorageServiceError, }; +use aptos_types::transaction::TransactionOutputListWithProofV2; use claims::assert_matches; -use mockall::{predicate::eq, Sequence}; +use std::cmp::min; #[tokio::test] async fn test_get_transaction_outputs_with_proof() { - // Test small and large chunk requests - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [1, 100, max_output_chunk_size] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; - let output_list_with_proof = - utils::create_output_list_with_proof(start_version, end_version, proof_version); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [1, 100, max_output_chunk_size] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; + let output_list_with_proof = utils::create_output_list_with_proof( + start_version, + end_version, + proof_version, + use_request_v2, + ); - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_transaction_outputs( - &mut db_reader, - start_version, - chunk_size, - proof_version, - output_list_with_proof.clone(), - ); + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + chunk_size, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, proof_version + 100, 10); - tokio::spawn(service.start()); + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); - // Create a request to fetch transactions outputs with a proof - let response = get_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - true, - ) - .await - .unwrap(); + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version + 100, 10); + tokio::spawn(service.start()); - // Verify the response is correct - match response.get_data_response().unwrap() { - DataResponse::TransactionOutputsWithProof(outputs_with_proof) => { - assert_eq!(outputs_with_proof, output_list_with_proof) - }, - _ => panic!( - "Expected transaction outputs with proof but got: {:?}", - response - ), - }; + // Create a request to fetch transactions outputs with a proof + let response = get_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + verify_output_with_proof_response(use_request_v2, output_list_with_proof, response); + } + } } } #[tokio::test] async fn test_get_transaction_outputs_with_proof_chunk_limit() { - // Create test data - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - let chunk_size = max_output_chunk_size * 10; // Set a chunk request larger than the max - let start_version = 0; - let end_version = start_version + max_output_chunk_size - 1; - let proof_version = end_version; - let output_list_with_proof = - utils::create_output_list_with_proof(start_version, end_version, proof_version); - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_transaction_outputs( - &mut db_reader, - start_version, - max_output_chunk_size, - proof_version, - output_list_with_proof.clone(), - ); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create test data + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + let chunk_size = max_output_chunk_size * 10; // Set a chunk request larger than the max + let start_version = 0; + let end_version = start_version + max_output_chunk_size - 1; + let proof_version = end_version; + let output_list_with_proof = utils::create_output_list_with_proof( + start_version, + end_version, + proof_version, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + max_output_chunk_size, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); + + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transaction outputs with a proof + let response = get_outputs_with_proof( + &mut mock_client, + start_version, + start_version + chunk_size - 1, + end_version, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + verify_output_with_proof_response(use_request_v2, output_list_with_proof, response); + } + } +} + +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_get_transaction_outputs_with_proof_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); tokio::spawn(service.start()); - // Create a request to fetch transactions outputs with a proof - let response = get_outputs_with_proof( + // Send a transaction v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + get_outputs_with_proof( &mut mock_client, - start_version, - start_version + chunk_size - 1, - end_version, + 0, + 10, + 10, true, + true, // Use transaction v2 + storage_config.max_network_chunk_bytes_v2, ) .await .unwrap(); - - // Verify the response is correct - match response.get_data_response().unwrap() { - DataResponse::TransactionOutputsWithProof(outputs_with_proof) => { - assert_eq!(outputs_with_proof, output_list_with_proof) - }, - _ => panic!( - "Expected transaction outputs with proof but got: {:?}", - response - ), - }; } #[tokio::test] async fn test_get_transaction_outputs_with_proof_invalid() { - // Create the storage client and server - let (mut mock_client, service, _, _, _) = MockClient::new(None, None); - tokio::spawn(service.start()); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); - // Test invalid ranges - let start_version = 1000; - for end_version in [0, 999] { - let response = get_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - true, - ) - .await - .unwrap_err(); - assert_matches!(response, StorageServiceError::InvalidRequest(_)); + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Test invalid ranges + let start_version = 1000; + for end_version in [0, 999] { + let response = get_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap_err(); + assert_matches!(response, StorageServiceError::InvalidRequest(_)); + } + } } } #[tokio::test] async fn test_get_transaction_outputs_with_proof_network_limit() { - // Test different byte limits - for network_limit_bytes in [1, 5 * 1024, 50 * 1024, 100 * 1024] { - get_outputs_with_proof_network_limit(network_limit_bytes).await; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits (the client and server limits match) + for max_specified_bytes in [1, 5 * 1024, 50 * 1024] { + get_outputs_with_proof_network_limit( + max_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } + } +} + +#[tokio::test] +async fn test_get_transaction_outputs_with_proof_network_limit_client_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 5 * 1024, 50 * 1024] { + let max_server_specified_bytes = max_specified_bytes * 10; // The server limit is 10x the client limit + get_outputs_with_proof_network_limit( + max_specified_bytes, + max_server_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } + } +} + +#[tokio::test] +async fn test_get_transaction_outputs_with_proof_network_limit_server_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 5 * 1024, 50 * 1024] { + let max_client_specified_bytes = max_specified_bytes * 10; // The client limit is 10x the server limit + get_outputs_with_proof_network_limit( + max_client_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } } } #[tokio::test] async fn test_get_transaction_outputs_with_proof_not_serviceable() { - // Test small and large chunk requests - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [2, 100, max_output_chunk_size] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [2, 100, max_output_chunk_size] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; - // Create the storage client and server (that cannot service the request) - let (mut mock_client, mut service, _, _, _) = MockClient::new(None, None); - utils::update_storage_server_summary(&mut service, proof_version - 1, 10); - tokio::spawn(service.start()); + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); - // Create a request to fetch transactions outputs with a proof - let response = get_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - true, - ) - .await - .unwrap_err(); + // Create the storage client and server (that cannot service the request) + let (mut mock_client, mut service, _, _, _) = + MockClient::new(None, Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version - 1, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions outputs with a proof + let response = get_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap_err(); - // Verify the request is not serviceable - assert_matches!(response, StorageServiceError::InvalidRequest(_)); + // Verify the request is not serviceable + assert_matches!(response, StorageServiceError::InvalidRequest(_)); + } + } } } @@ -179,19 +311,34 @@ async fn get_outputs_with_proof( end_version: u64, proof_version: u64, use_compression: bool, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Result { - let data_request = + let data_request = if use_request_v2 { + DataRequest::get_transaction_output_data_with_proof( + proof_version, + start_version, + end_version, + max_response_bytes_v2, + ) + } else { DataRequest::GetTransactionOutputsWithProof(TransactionOutputsWithProofRequest { proof_version, start_version, end_version, - }); + }) + }; utils::send_storage_request(mock_client, use_compression, data_request).await } -/// A helper method to request a transaction outputs with proof chunk using the -/// the specified network limit. -async fn get_outputs_with_proof_network_limit(network_limit_bytes: u64) { +/// A helper method to request a transaction outputs with proof chunk using +/// the specified network limits (client and server). +async fn get_outputs_with_proof_network_limit( + max_client_specified_bytes: u64, + max_server_specified_bytes: u64, + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, +) { for use_compression in [true, false] { // Create test data let max_output_chunk_size = @@ -201,27 +348,21 @@ async fn get_outputs_with_proof_network_limit(network_limit_bytes: u64) { let proof_version = 1000000; // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut chunk_size = max_output_chunk_size; - while chunk_size >= 1 { - let output_list_with_proof = utils::create_output_list_using_sizes( - start_version, - chunk_size, - min_bytes_per_output, - ); - db_reader - .expect_get_transaction_outputs() - .times(1) - .with(eq(start_version), eq(chunk_size), eq(proof_version)) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _, _| Ok(output_list_with_proof.clone())); - chunk_size /= 2; - } + let db_reader = create_mock_db_with_output_expectations( + use_request_v2, + use_size_and_time_aware_chunking, + max_output_chunk_size, + min_bytes_per_output, + start_version, + proof_version, + ); // Create a storage config with the specified max network byte limit let storage_config = StorageServiceConfig { - max_network_chunk_bytes: network_limit_bytes, + max_network_chunk_bytes: max_server_specified_bytes, + max_network_chunk_bytes_v2: max_server_specified_bytes, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, ..Default::default() }; @@ -238,23 +379,151 @@ async fn get_outputs_with_proof_network_limit(network_limit_bytes: u64) { start_version + (max_output_chunk_size * 10), // Request more than the max chunk proof_version, use_compression, + use_request_v2, + max_client_specified_bytes, ) .await .unwrap(); // Verify the response is correct - match response.get_data_response().unwrap() { + let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; + let num_outputs = match response.get_data_response().unwrap() { DataResponse::TransactionOutputsWithProof(outputs_with_proof) => { - let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; - let num_outputs = outputs_with_proof.transactions_and_outputs.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_outputs, 1); // Data cannot be reduced more than a single item - } else { - let max_outputs = network_limit_bytes / min_bytes_per_output; - assert!(num_outputs <= max_outputs); // Verify data fits correctly into the limit - } + outputs_with_proof.get_num_outputs() as u64 + }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof) => { + let output_list_with_proof_v2 = transaction_data_with_proof + .transaction_output_list_with_proof + .unwrap(); + output_list_with_proof_v2.get_num_outputs() as u64 }, _ => panic!("Expected outputs with proof but got: {:?}", response), }; + if num_response_bytes > max_server_specified_bytes { + assert_eq!(num_outputs, 1); // Data cannot be reduced more than a single item + } else { + // Determine the max specified bytes + let max_specified_bytes = if use_request_v2 { + min(max_client_specified_bytes, max_server_specified_bytes) + } else { + max_server_specified_bytes + }; + + // Verify the number of outputs fits within the specified byte limit + let max_outputs = max_specified_bytes / min_bytes_per_output; + assert!(num_outputs <= max_outputs); + } + } +} + +/// Creates a mock db reader with expectations for fetching outputs +fn create_mock_db_with_output_expectations( + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, + mut chunk_size: u64, + min_bytes_per_output: u64, + start_version: u64, + proof_version: u64, +) -> MockDatabaseReader { + // Create the mock DB reader + let mut db_reader = mock::create_mock_db_reader(); + + // Create an output list using the initial chunk size + let output_list_with_proof = utils::create_output_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_output, + use_request_v2, + ); + + // If size and time-aware chunking are enabled, expect iterator usage + if use_size_and_time_aware_chunking { + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + chunk_size, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + return db_reader; + } + + // Otherwise, expect the legacy implementation that halves the chunk size until it fits + while chunk_size >= 1 { + let output_list_with_proof = utils::create_output_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_output, + use_request_v2, + ); + + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + chunk_size, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + chunk_size /= 2; + } + + db_reader +} + +/// Verifies the response for a transaction output with proof request +fn verify_output_with_proof_response( + use_request_v2: bool, + output_list_with_proof: TransactionOutputListWithProofV2, + response: StorageServiceResponse, +) { + // Get the data response + let data_response = response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::TransactionOutputsWithProof(_) => assert!(!use_request_v2), + DataResponse::TransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected transaction outputs with proof but got: {:?}", + data_response + ), + } + + // Verify the response data + match data_response { + DataResponse::TransactionOutputsWithProof(outputs_with_proof) => { + assert_eq!( + outputs_with_proof, + output_list_with_proof.get_output_list_with_proof().clone() + ) + }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof) => { + // Verify the data type + assert_eq!( + transaction_data_with_proof.transaction_data_response_type, + TransactionDataResponseType::TransactionOutputData + ); + + // Verify the transactions + assert!(transaction_data_with_proof + .transaction_list_with_proof + .is_none()); + + assert_eq!( + transaction_data_with_proof + .transaction_output_list_with_proof + .unwrap(), + output_list_with_proof + ); + }, + _ => panic!( + "Expected transaction outputs with proof but got: {:?}", + data_response + ), } } diff --git a/state-sync/storage-service/server/src/tests/transactions.rs b/state-sync/storage-service/server/src/tests/transactions.rs index b88f5e71dfe..18cd4e5686c 100644 --- a/state-sync/storage-service/server/src/tests/transactions.rs +++ b/state-sync/storage-service/server/src/tests/transactions.rs @@ -1,193 +1,338 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::tests::{mock, mock::MockClient, utils}; +use crate::tests::{ + mock, + mock::{MockClient, MockDatabaseReader}, + utils, +}; use aptos_config::config::StorageServiceConfig; use aptos_storage_service_types::{responses::DataResponse, StorageServiceError}; use claims::assert_matches; -use mockall::{predicate::eq, Sequence}; +use std::cmp::min; #[tokio::test] async fn test_get_transactions_with_proof() { - // Test small and large chunk requests - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - for chunk_size in [1, 100, max_transaction_chunk_size] { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - end_version, - proof_version, - include_events, - ); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + for chunk_size in [1, 100, max_transaction_chunk_size] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + include_events, + use_request_v2, + ); - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_transactions( - &mut db_reader, - start_version, - chunk_size, - proof_version, - include_events, - transaction_list_with_proof.clone(), - ); + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_transactions( + &mut db_reader, + start_version, + chunk_size, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, proof_version, 10); - tokio::spawn(service.start()); + // Create a storage service config + let storage_config = utils::create_storage_config( + use_request_v2, + use_size_and_time_aware_chunking, + ); - // Create a request to fetch transactions with a proof - let response = utils::get_transactions_with_proof( - &mut mock_client, - start_version, - end_version, - proof_version, - include_events, - true, - ) - .await - .unwrap(); + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version, 10); + tokio::spawn(service.start()); - // Verify the response is correct - match response.get_data_response().unwrap() { - DataResponse::TransactionsWithProof(transactions_with_proof) => { - assert_eq!(transactions_with_proof, transaction_list_with_proof) - }, - _ => panic!("Expected transactions with proof but got: {:?}", response), - }; + // Create a request to fetch transactions with a proof + let response = utils::get_transactions_with_proof( + &mut mock_client, + start_version, + end_version, + proof_version, + include_events, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + utils::verify_transaction_with_proof_response( + use_request_v2, + transaction_list_with_proof, + response, + ); + } + } } } } #[tokio::test] -async fn test_get_transactions_with_chunk_limit() { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - let chunk_size = max_transaction_chunk_size * 10; // Set a chunk request larger than the max - let start_version = 0; - let end_version = start_version + max_transaction_chunk_size - 1; - let proof_version = end_version; - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - end_version, - proof_version, - include_events, - ); +async fn test_get_transactions_with_chunk_proof_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + let chunk_size = max_transaction_chunk_size * 10; // Set a chunk request larger than the max + let start_version = 0; + let end_version = start_version + max_transaction_chunk_size - 1; + let proof_version = end_version; + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + include_events, + use_request_v2, + ); - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_transactions( - &mut db_reader, - start_version, - max_transaction_chunk_size, - proof_version, - include_events, - transaction_list_with_proof.clone(), - ); + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); + utils::expect_get_transactions( + &mut db_reader, + start_version, + max_transaction_chunk_size, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); - // Create the storage client and server - let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), None); - utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); - tokio::spawn(service.start()); + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); - // Create a request to fetch transactions with a proof - let response = utils::get_transactions_with_proof( - &mut mock_client, - start_version, - start_version + chunk_size - 1, - proof_version, - include_events, - true, - ) - .await - .unwrap(); - - // Verify the response is correct - match response.get_data_response().unwrap() { - DataResponse::TransactionsWithProof(transactions_with_proof) => { - assert_eq!(transactions_with_proof, transaction_list_with_proof) - }, - _ => panic!("Expected transactions with proof but got: {:?}", response), - }; + // Create the storage client and server + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions with a proof + let response = utils::get_transactions_with_proof( + &mut mock_client, + start_version, + start_version + chunk_size - 1, + proof_version, + include_events, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + utils::verify_transaction_with_proof_response( + use_request_v2, + transaction_list_with_proof, + response, + ); + } + } } } #[tokio::test] -async fn test_get_transactions_with_proof_invalid() { +#[should_panic(expected = "Canceled")] +async fn test_get_transactions_with_proof_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + // Create the storage client and server - let (mut mock_client, service, _, _, _) = MockClient::new(None, None); + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); tokio::spawn(service.start()); - // Test invalid ranges - let start_version = 1000; - for end_version in [0, 999] { - let response = utils::get_transactions_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - true, - true, - ) - .await - .unwrap_err(); - assert_matches!(response, StorageServiceError::InvalidRequest(_)); - } + // Send a transaction v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + utils::get_transactions_with_proof( + &mut mock_client, + 0, + 10, + 10, + true, + true, + true, // Use transaction v2 + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); } #[tokio::test] -async fn test_get_transactions_with_proof_network_limit() { - // Test different byte limits - for network_limit_bytes in [1, 1024, 10 * 1024, 100 * 1024] { - get_transactions_with_proof_network_limit(network_limit_bytes).await; - } -} - -#[tokio::test] -async fn test_get_transactions_with_proof_not_serviceable() { - // Test small and large chunk requests - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - for chunk_size in [2, 100, max_transaction_chunk_size] { - // Test event inclusion - for include_events in [true, false] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; +async fn test_get_transactions_with_proof_invalid() { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let storage_config = utils::create_storage_config(use_request_v2, false); - // Create the storage client and server (that cannot service the request) - let (mut mock_client, mut service, _, _, _) = MockClient::new(None, None); - utils::update_storage_server_summary(&mut service, proof_version - 1, 10); - tokio::spawn(service.start()); + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); - // Create a request to fetch transactions with a proof + // Test invalid ranges + let start_version = 1000; + for end_version in [0, 999] { let response = utils::get_transactions_with_proof( &mut mock_client, start_version, end_version, - proof_version, - include_events, + end_version, + true, true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, ) .await .unwrap_err(); - - // Verify the request is not serviceable assert_matches!(response, StorageServiceError::InvalidRequest(_)); } } } -/// A helper method to request a transactions with proof chunk using the -/// the specified network limit. -async fn get_transactions_with_proof_network_limit(network_limit_bytes: u64) { +#[tokio::test] +async fn test_get_transactions_with_proof_network_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits (the client and server limits match) + for max_specified_bytes in [1, 1024, 10 * 1024] { + get_transactions_with_proof_network_limit( + max_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } + } +} + +#[tokio::test] +async fn test_get_transactions_with_proof_network_limit_client_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 1024, 10 * 1024] { + let max_server_specified_bytes = max_specified_bytes * 10; // The server limit is 10x the client limit + get_transactions_with_proof_network_limit( + max_specified_bytes, + max_server_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } + } +} + +#[tokio::test] +async fn test_get_transactions_with_proof_network_limit_server_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 1024, 10 * 1024] { + let max_client_specified_bytes = max_specified_bytes * 10; // The client limit is 10x the server limit + get_transactions_with_proof_network_limit( + max_client_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } + } +} + +#[tokio::test] +async fn test_get_transactions_with_proof_not_serviceable() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + for chunk_size in [2, 100, max_transaction_chunk_size] { + // Test event inclusion + for include_events in [true, false] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; + + // Create a storage service config + let storage_config = utils::create_storage_config( + use_request_v2, + use_size_and_time_aware_chunking, + ); + + // Create the storage client and server (that cannot service the request) + let (mut mock_client, mut service, _, _, _) = + MockClient::new(None, Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version - 1, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions with a proof + let response = utils::get_transactions_with_proof( + &mut mock_client, + start_version, + end_version, + proof_version, + include_events, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap_err(); + + // Verify the request is not serviceable + assert_matches!(response, StorageServiceError::InvalidRequest(_)); + } + } + } + } +} + +/// A helper method to request a transactions with proof chunk using +/// the specified network limits (client and server). +async fn get_transactions_with_proof_network_limit( + max_client_specified_bytes: u64, + max_server_specified_bytes: u64, + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, +) { for use_compression in [true, false] { for include_events in [true, false] { // Create test data @@ -198,33 +343,22 @@ async fn get_transactions_with_proof_network_limit(network_limit_bytes: u64) { let proof_version = 202020; // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut chunk_size = max_transaction_chunk_size; - while chunk_size >= 1 { - let transaction_list_with_proof = utils::create_transaction_list_using_sizes( - start_version, - chunk_size, - min_bytes_per_transaction, - include_events, - ); - db_reader - .expect_get_transactions() - .times(1) - .with( - eq(start_version), - eq(chunk_size), - eq(proof_version), - eq(include_events), - ) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _, _, _| Ok(transaction_list_with_proof.clone())); - chunk_size /= 2; - } + let db_reader = create_mock_db_with_transaction_expectations( + use_request_v2, + use_size_and_time_aware_chunking, + include_events, + max_transaction_chunk_size, + min_bytes_per_transaction, + start_version, + proof_version, + ); // Create a storage config with the specified max network byte limit let storage_config = StorageServiceConfig { - max_network_chunk_bytes: network_limit_bytes, + max_network_chunk_bytes: max_server_specified_bytes, + max_network_chunk_bytes_v2: max_server_specified_bytes, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, ..Default::default() }; @@ -242,24 +376,101 @@ async fn get_transactions_with_proof_network_limit(network_limit_bytes: u64) { proof_version, include_events, use_compression, + use_request_v2, + max_client_specified_bytes, ) .await .unwrap(); // Verify the response is correct - match response.get_data_response().unwrap() { + let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; + let num_transactions = match response.get_data_response().unwrap() { DataResponse::TransactionsWithProof(transactions_with_proof) => { - let num_response_bytes = bcs::serialized_size(&response).unwrap() as u64; - let num_transactions = transactions_with_proof.transactions.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_transactions, 1); // Data cannot be reduced more than a single item - } else { - let max_transactions = network_limit_bytes / min_bytes_per_transaction; - assert!(num_transactions <= max_transactions); // Verify data fits correctly into the limit - } + transactions_with_proof.get_num_transactions() as u64 + }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof) => { + let transaction_list_with_proof_v2 = transaction_data_with_proof + .transaction_list_with_proof + .unwrap(); + transaction_list_with_proof_v2.get_num_transactions() as u64 }, _ => panic!("Expected transactions with proof but got: {:?}", response), }; + if num_response_bytes > max_server_specified_bytes { + assert_eq!(num_transactions, 1); // Data cannot be reduced more than a single item + } else { + // Determine the max specified bytes + let max_specified_bytes = if use_request_v2 { + min(max_client_specified_bytes, max_server_specified_bytes) + } else { + max_server_specified_bytes + }; + + // Verify the number of transactions fits within the specified byte limit + let max_transactions = max_specified_bytes / min_bytes_per_transaction; + assert!(num_transactions <= max_transactions); + } } } } + +/// Creates a mock db reader with expectations for fetching transactions +fn create_mock_db_with_transaction_expectations( + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, + include_events: bool, + mut chunk_size: u64, + min_bytes_per_transaction: u64, + start_version: u64, + proof_version: u64, +) -> MockDatabaseReader { + // Create the mock DB reader + let mut db_reader = mock::create_mock_db_reader(); + + // Create a transaction list using the initial chunk size + let transaction_list_with_proof = utils::create_transaction_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_transaction, + include_events, + use_request_v2, + ); + + // If size and time-aware chunking are enabled, expect iterator usage + if use_size_and_time_aware_chunking { + utils::expect_get_transactions( + &mut db_reader, + start_version, + chunk_size, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Otherwise, expect the legacy implementation that halves the chunk size until it fits + while chunk_size >= 1 { + let transaction_list_with_proof = utils::create_transaction_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_transaction, + include_events, + use_request_v2, + ); + + utils::expect_get_transactions( + &mut db_reader, + start_version, + chunk_size, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + chunk_size /= 2; + } + + db_reader +} diff --git a/state-sync/storage-service/server/src/tests/transactions_or_outputs.rs b/state-sync/storage-service/server/src/tests/transactions_or_outputs.rs index f857aa29d21..836cb947a3c 100644 --- a/state-sync/storage-service/server/src/tests/transactions_or_outputs.rs +++ b/state-sync/storage-service/server/src/tests/transactions_or_outputs.rs @@ -1,232 +1,388 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::tests::{mock, mock::MockClient, utils}; +use crate::tests::{ + mock, + mock::{MockClient, MockDatabaseReader}, + utils, +}; use aptos_config::config::StorageServiceConfig; use aptos_storage_service_types::{ requests::{DataRequest, TransactionsOrOutputsWithProofRequest}, - responses::{DataResponse, StorageServiceResponse}, + responses::{DataResponse, StorageServiceResponse, TransactionDataResponseType}, StorageServiceError, }; -use aptos_types::transaction::{TransactionListWithProof, TransactionOutputListWithProof}; +use aptos_types::transaction::{ + TransactionListWithProof, TransactionListWithProofV2, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, +}; use claims::assert_matches; -use mockall::{predicate::eq, Sequence}; +use std::cmp::min; #[tokio::test] async fn test_get_transactions_or_outputs_with_proof() { - // Test small and large chunk requests - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [1, 100, max_output_chunk_size] { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; - let output_list_with_proof = - utils::create_output_list_with_proof(start_version, end_version, proof_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - start_version, - proof_version, - false, - ); // Creates a small transaction list + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [1, 100, max_output_chunk_size] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; + let output_list_with_proof = utils::create_output_list_with_proof( + start_version, + end_version, + proof_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + false, + use_request_v2, + ); - // Create the mock db reader - let max_num_output_reductions = 5; - let mut db_reader = mock::create_mock_db_reader(); - for i in 0..=max_num_output_reductions { + // Create the mock db reader + let max_num_output_reductions = 5; + let mut db_reader = mock::create_mock_db_reader(); + for i in 0..=max_num_output_reductions { + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + (chunk_size as u32 / (u32::pow(2, i as u32))) as u64, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + if use_size_and_time_aware_chunking { + break; // Size and time-aware chunking only makes one attempt + } + } + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + start_version, + chunk_size, + proof_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version + 100, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions or outputs with a proof + let response = get_transactions_or_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + false, + max_num_output_reductions, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + verify_transactions_or_output_response( + use_request_v2, + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + &response, + ); + } + } + } + } +} + +#[tokio::test] +async fn test_get_transactions_or_outputs_with_proof_chunk_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test fallback to transaction syncing + for fallback_to_transactions in [false, true] { + // Create test data + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + let max_transaction_chunk_size = + StorageServiceConfig::default().max_transaction_chunk_size; + let chunk_size = max_output_chunk_size * 10; // Set a chunk request larger than the max + let start_version = 0; + let end_version = start_version + max_output_chunk_size - 1; + let proof_version = end_version; + let output_list_with_proof = utils::create_output_list_with_proof( + start_version, + end_version, + proof_version, + use_request_v2, + ); + let transaction_list_with_proof = utils::create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + false, + use_request_v2, + ); + + // Create the mock db reader + let mut db_reader = mock::create_mock_db_reader(); utils::expect_get_transaction_outputs( &mut db_reader, start_version, - (chunk_size as u32 / (u32::pow(2, i as u32))) as u64, + max_output_chunk_size, proof_version, output_list_with_proof.clone(), + use_size_and_time_aware_chunking, ); - } - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, + if fallback_to_transactions { + utils::expect_get_transactions( + &mut db_reader, + start_version, + max_transaction_chunk_size, + proof_version, + false, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + } + + // Create the storage client and server + let storage_config = utils::configure_network_chunk_limit( + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + use_request_v2, + use_size_and_time_aware_chunking, + ); + let (mut mock_client, mut service, _, _, _) = + MockClient::new(Some(db_reader), Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions or outputs with a proof + let response = get_transactions_or_outputs_with_proof( + &mut mock_client, start_version, - chunk_size, - proof_version, + start_version + chunk_size - 1, + end_version, + false, + 0, false, - transaction_list_with_proof.clone(), + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); + + // Verify the response is correct + verify_transactions_or_output_response( + use_request_v2, + fallback_to_transactions, + &output_list_with_proof, + &transaction_list_with_proof, + &response, ); } + } + } +} + +#[tokio::test] +#[should_panic(expected = "Canceled")] +async fn test_get_transactions_or_outputs_with_proof_disable_v2() { + // Create a storage service config with transaction v2 disabled + let storage_config = utils::create_storage_config(false, false); + + // Create the storage client and server + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); + tokio::spawn(service.start()); + + // Send a transaction v2 request. This will cause a test panic + // as no response will be received (the receiver is dropped). + get_transactions_or_outputs_with_proof( + &mut mock_client, + 0, + 10, + 10, + false, + 3, + true, + true, // Use transaction v2 + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap(); +} + +#[tokio::test] +async fn test_get_transactions_or_outputs_with_proof_invalid() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, mut service, _, _, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - utils::update_storage_server_summary(&mut service, proof_version + 100, 10); + let (mut mock_client, service, _, _, _) = MockClient::new(None, Some(storage_config)); tokio::spawn(service.start()); - // Create a request to fetch transactions or outputs with a proof - let response = get_transactions_or_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - false, - max_num_output_reductions, - true, - ) - .await - .unwrap(); - - // Verify the response is correct - verify_transactions_or_output_response( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - &response, - ); + // Test invalid ranges + let start_version = 1000; + for end_version in [0, 999] { + let response = get_transactions_or_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + false, + 3, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap_err(); + assert_matches!(response, StorageServiceError::InvalidRequest(_)); + } } } } #[tokio::test] -async fn test_get_transactions_or_outputs_with_proof_chunk_limit() { - // Test fallback to transaction syncing - for fallback_to_transactions in [false, true] { - // Create test data - let max_output_chunk_size = - StorageServiceConfig::default().max_transaction_output_chunk_size; - let max_transaction_chunk_size = StorageServiceConfig::default().max_transaction_chunk_size; - let chunk_size = max_output_chunk_size * 10; // Set a chunk request larger than the max - let start_version = 0; - let end_version = start_version + max_output_chunk_size - 1; - let proof_version = end_version; - let output_list_with_proof = - utils::create_output_list_with_proof(start_version, end_version, proof_version); - let transaction_list_with_proof = utils::create_transaction_list_with_proof( - start_version, - start_version, - proof_version, - false, - ); // Creates a small transaction list - - // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - utils::expect_get_transaction_outputs( - &mut db_reader, - start_version, - max_output_chunk_size, - proof_version, - output_list_with_proof.clone(), - ); - if fallback_to_transactions { - utils::expect_get_transactions( - &mut db_reader, - start_version, - max_transaction_chunk_size, - proof_version, - false, - transaction_list_with_proof.clone(), - ); +async fn test_get_transactions_or_outputs_with_proof_network_limit() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits (the client and server limits match) + for max_specified_bytes in [1, 2 * 1024, 4 * 1024] { + get_transactions_or_outputs_with_proof_network_limit( + max_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } } - - // Create the storage client and server - let storage_config = utils::configure_network_chunk_limit( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - ); - let (mut mock_client, mut service, _, _, _) = - MockClient::new(Some(db_reader), Some(storage_config)); - utils::update_storage_server_summary(&mut service, proof_version + chunk_size, 10); - tokio::spawn(service.start()); - - // Create a request to fetch transactions outputs with a proof - let response = get_transactions_or_outputs_with_proof( - &mut mock_client, - start_version, - start_version + chunk_size - 1, - end_version, - false, - 0, - false, - ) - .await - .unwrap(); - - // Verify the response is correct - verify_transactions_or_output_response( - fallback_to_transactions, - &output_list_with_proof, - &transaction_list_with_proof, - &response, - ); } } #[tokio::test] -async fn test_get_transactions_or_outputs_with_proof_invalid() { - // Create the storage client and server - let (mut mock_client, service, _, _, _) = MockClient::new(None, None); - tokio::spawn(service.start()); - - // Test invalid ranges - let start_version = 1000; - for end_version in [0, 999] { - let response = get_transactions_or_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - false, - 3, - true, - ) - .await - .unwrap_err(); - assert_matches!(response, StorageServiceError::InvalidRequest(_)); +async fn test_get_transactions_or_outputs_with_proof_network_limit_client_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 2 * 1024, 4 * 1024] { + let max_server_specified_bytes = max_specified_bytes * 10; // The server limit is 10x the client limit + get_transactions_or_outputs_with_proof_network_limit( + max_specified_bytes, + max_server_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } } } #[tokio::test] -async fn test_get_transactions_or_outputs_with_proof_network_limit() { - // Test different byte limits - for network_limit_bytes in [1, 2 * 1024, 10 * 1024, 30 * 1024] { - get_transactions_or_outputs_with_proof_network_limit(network_limit_bytes).await; +async fn test_get_transactions_or_outputs_with_proof_network_limit_server_bounded() { + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test different byte limits + for max_specified_bytes in [1, 2 * 1024, 4 * 1024] { + let max_client_specified_bytes = max_specified_bytes * 10; // The client limit is 10x the server limit + get_transactions_or_outputs_with_proof_network_limit( + max_client_specified_bytes, + max_specified_bytes, + use_request_v2, + use_size_and_time_aware_chunking, + ) + .await; + } + } } } #[tokio::test] async fn test_get_transactions_or_outputs_with_proof_not_serviceable() { - // Test small and large chunk requests - let max_output_chunk_size = StorageServiceConfig::default().max_transaction_output_chunk_size; - for chunk_size in [2, 100, max_output_chunk_size] { - // Create test data - let start_version = 0; - let end_version = start_version + chunk_size - 1; - let proof_version = end_version; - - // Create the storage client and server (that cannot service the request) - let (mut mock_client, mut service, _, _, _) = MockClient::new(None, None); - utils::update_storage_server_summary(&mut service, proof_version - 1, 10); - tokio::spawn(service.start()); - - // Create a request to fetch transactions or outputs with a proof - let response = get_transactions_or_outputs_with_proof( - &mut mock_client, - start_version, - end_version, - end_version, - false, - 5, - true, - ) - .await - .unwrap_err(); + // Test size and time-aware chunking + for use_size_and_time_aware_chunking in [false, true] { + // Test both v1 and v2 data requests + for use_request_v2 in [false, true] { + // Test small and large chunk requests + let max_output_chunk_size = + StorageServiceConfig::default().max_transaction_output_chunk_size; + for chunk_size in [2, 100, max_output_chunk_size] { + // Create test data + let start_version = 0; + let end_version = start_version + chunk_size - 1; + let proof_version = end_version; + + // Create a storage service config + let storage_config = + utils::create_storage_config(use_request_v2, use_size_and_time_aware_chunking); - // Verify the request is not serviceable - assert_matches!(response, StorageServiceError::InvalidRequest(_)); + // Create the storage client and server (that cannot service the request) + let (mut mock_client, mut service, _, _, _) = + MockClient::new(None, Some(storage_config)); + utils::update_storage_server_summary(&mut service, proof_version - 1, 10); + tokio::spawn(service.start()); + + // Create a request to fetch transactions or outputs with a proof + let response = get_transactions_or_outputs_with_proof( + &mut mock_client, + start_version, + end_version, + end_version, + false, + 5, + true, + use_request_v2, + storage_config.max_network_chunk_bytes_v2, + ) + .await + .unwrap_err(); + + // Verify the request is not serviceable + assert_matches!(response, StorageServiceError::InvalidRequest(_)); + } + } } } @@ -239,21 +395,37 @@ async fn get_transactions_or_outputs_with_proof( include_events: bool, max_num_output_reductions: u64, use_compression: bool, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Result { - let data_request = + let data_request = if use_request_v2 { + DataRequest::get_transaction_or_output_data_with_proof( + proof_version, + start_version, + end_version, + include_events, + max_response_bytes_v2, + ) + } else { DataRequest::GetTransactionsOrOutputsWithProof(TransactionsOrOutputsWithProofRequest { proof_version, start_version, end_version, include_events, max_num_output_reductions, - }); + }) + }; utils::send_storage_request(mock_client, use_compression, data_request).await } -/// A helper method to request transactions or outputs with proof using the -/// the specified network limit. -async fn get_transactions_or_outputs_with_proof_network_limit(network_limit_bytes: u64) { +/// A helper method to request transactions or outputs with proof using +/// the specified network limits (client and server). +async fn get_transactions_or_outputs_with_proof_network_limit( + max_client_specified_bytes: u64, + max_server_specified_bytes: u64, + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, +) { for use_compression in [true, false] { for include_events in [true, false] { // Create test data @@ -265,52 +437,29 @@ async fn get_transactions_or_outputs_with_proof_network_limit(network_limit_byte let max_transaction_size = StorageServiceConfig::default().max_transaction_chunk_size; // Create the mock db reader - let mut db_reader = mock::create_mock_db_reader(); - let mut expectation_sequence = Sequence::new(); - let mut chunk_size = max_output_size; - let mut max_num_output_reductions = 0; - while chunk_size >= 1 { - let output_list_with_proof = utils::create_output_list_using_sizes( - start_version, - chunk_size, + let (db_reader, max_num_output_reductions) = + create_mock_db_with_transactions_or_outputs_expectations( + use_request_v2, + use_size_and_time_aware_chunking, + include_events, min_bytes_per_output, - ); - db_reader - .expect_get_transaction_outputs() - .times(1) - .with(eq(start_version), eq(chunk_size), eq(proof_version)) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _, _| Ok(output_list_with_proof.clone())); - chunk_size /= 2; - max_num_output_reductions += 1; - } - let mut chunk_size = max_transaction_size; - while chunk_size >= 1 { - let transaction_list_with_proof = utils::create_transaction_list_using_sizes( - start_version, - chunk_size, min_bytes_per_transaction, - include_events, + start_version, + proof_version, + max_output_size, + max_transaction_size, ); - db_reader - .expect_get_transactions() - .times(1) - .with( - eq(start_version), - eq(chunk_size), - eq(proof_version), - eq(include_events), - ) - .in_sequence(&mut expectation_sequence) - .returning(move |_, _, _, _| Ok(transaction_list_with_proof.clone())); - chunk_size /= 2; - } - // Create the storage client and server + // Create a storage config with the specified max network byte limit let storage_config = StorageServiceConfig { - max_network_chunk_bytes: network_limit_bytes, + max_network_chunk_bytes: max_server_specified_bytes, + max_network_chunk_bytes_v2: max_server_specified_bytes, + enable_transaction_data_v2: use_request_v2, + enable_size_and_time_aware_chunking: use_size_and_time_aware_chunking, ..Default::default() }; + + // Create the storage client and server let (mut mock_client, mut service, _, _, _) = MockClient::new(Some(db_reader), Some(storage_config)); utils::update_storage_server_summary(&mut service, proof_version + 100, 10); @@ -325,42 +474,67 @@ async fn get_transactions_or_outputs_with_proof_network_limit(network_limit_byte include_events, max_num_output_reductions, use_compression, + use_request_v2, + max_client_specified_bytes, ) .await .unwrap(); // Verify the response is correct match response.get_data_response().unwrap() { - DataResponse::TransactionsOrOutputsWithProof( - transactions_or_outputs_with_proof, - ) => { - let (transactions_with_proof, outputs_with_proof) = - transactions_or_outputs_with_proof; - + DataResponse::TransactionsOrOutputsWithProof(( + transactions_with_proof, + outputs_with_proof, + )) => { if let Some(transactions_with_proof) = transactions_with_proof { - let num_response_bytes = - bcs::serialized_size(&transactions_with_proof).unwrap() as u64; - let num_transactions = transactions_with_proof.transactions.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_transactions, 1); // Data cannot be reduced more than a single item - } else { - let max_transactions = network_limit_bytes / min_bytes_per_transaction; - assert!(num_transactions <= max_transactions); - } + check_transaction_response_bytes( + max_client_specified_bytes, + max_server_specified_bytes, + min_bytes_per_transaction, + &transactions_with_proof, + use_request_v2, + ); } else if let Some(outputs_with_proof) = outputs_with_proof { - let num_response_bytes = - bcs::serialized_size(&outputs_with_proof).unwrap() as u64; - let num_outputs = outputs_with_proof.transactions_and_outputs.len() as u64; - if num_response_bytes > network_limit_bytes { - assert_eq!(num_outputs, 1); // Data cannot be reduced more than a single item - } else { - let max_outputs = network_limit_bytes / min_bytes_per_output; - assert!(num_outputs <= max_outputs); - } + check_output_response_bytes( + max_client_specified_bytes, + max_server_specified_bytes, + min_bytes_per_output, + &outputs_with_proof, + use_request_v2, + ); } else { panic!("No transactions or outputs were returned!"); } }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof_response) => { + match transaction_data_with_proof_response.transaction_data_response_type { + TransactionDataResponseType::TransactionData => { + let transaction_list_with_proof_v2 = + transaction_data_with_proof_response + .transaction_list_with_proof + .unwrap(); + check_transaction_response_bytes( + max_client_specified_bytes, + max_server_specified_bytes, + min_bytes_per_transaction, + transaction_list_with_proof_v2.get_transaction_list_with_proof(), + use_request_v2, + ); + }, + TransactionDataResponseType::TransactionOutputData => { + let output_list_with_proof_v2 = transaction_data_with_proof_response + .transaction_output_list_with_proof + .unwrap(); + check_output_response_bytes( + max_client_specified_bytes, + max_server_specified_bytes, + min_bytes_per_output, + output_list_with_proof_v2.get_output_list_with_proof(), + use_request_v2, + ); + }, + } + }, _ => panic!( "Expected transactions or outputs with proof but got: {:?}", response @@ -370,29 +544,208 @@ async fn get_transactions_or_outputs_with_proof_network_limit(network_limit_byte } } +/// Creates a mock db reader with expectations for fetching transactions or outputs +fn create_mock_db_with_transactions_or_outputs_expectations( + use_request_v2: bool, + use_size_and_time_aware_chunking: bool, + include_events: bool, + min_bytes_per_output: u64, + min_bytes_per_transaction: u64, + start_version: u64, + proof_version: u64, + max_output_size: u64, + max_transaction_size: u64, +) -> (MockDatabaseReader, u64) { + // Create the mock DB reader + let mut db_reader = mock::create_mock_db_reader(); + + // Expect calls to get outputs with the specified chunk sizes + let mut max_num_output_reductions = 0; + let mut chunk_size = max_output_size; + while chunk_size >= 1 { + let output_list_with_proof = utils::create_output_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_output, + use_request_v2, + ); + utils::expect_get_transaction_outputs( + &mut db_reader, + start_version, + chunk_size, + proof_version, + output_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + chunk_size /= 2; + max_num_output_reductions += 1; + + if use_size_and_time_aware_chunking || (use_request_v2 && max_num_output_reductions > 0) { + break; // No need to reduce outputs more than once + } + } + + // Expect calls to get transactions with the specified chunk sizes + let mut chunk_size = max_transaction_size; + while chunk_size >= 1 { + let transaction_list_with_proof = utils::create_transaction_list_using_sizes( + start_version, + chunk_size, + min_bytes_per_transaction, + include_events, + use_request_v2, + ); + utils::expect_get_transactions( + &mut db_reader, + start_version, + chunk_size, + proof_version, + include_events, + transaction_list_with_proof.clone(), + use_size_and_time_aware_chunking, + ); + + chunk_size /= 2; + + if use_size_and_time_aware_chunking { + break; // Size and time-aware chunking only makes one attempt + } + } + + (db_reader, max_num_output_reductions) +} + +/// Checks that the number of bytes in the output response is valid +fn check_output_response_bytes( + max_client_specified_bytes: u64, + max_server_specified_bytes: u64, + min_bytes_per_output: u64, + outputs_with_proof: &TransactionOutputListWithProof, + use_request_v2: bool, +) { + let num_response_bytes = bcs::serialized_size(&outputs_with_proof).unwrap() as u64; + let num_outputs = outputs_with_proof.get_num_outputs() as u64; + + if num_response_bytes > max_server_specified_bytes { + assert_eq!(num_outputs, 1); // Data cannot be reduced more than a single item + } else { + // Determine the max specified bytes + let max_specified_bytes = if use_request_v2 { + min(max_client_specified_bytes, max_server_specified_bytes) + } else { + max_server_specified_bytes + }; + + // Verify the number of outputs fits within the specified byte limit + let max_outputs = max_specified_bytes / min_bytes_per_output; + assert!(num_outputs <= max_outputs); + } +} + +/// Checks that the number of bytes in the transaction response is valid +fn check_transaction_response_bytes( + max_client_specified_bytes: u64, + max_server_specified_bytes: u64, + min_bytes_per_transaction: u64, + transactions_with_proof: &TransactionListWithProof, + use_request_v2: bool, +) { + let num_response_bytes = bcs::serialized_size(&transactions_with_proof).unwrap() as u64; + let num_transactions = transactions_with_proof.get_num_transactions() as u64; + + if num_response_bytes > max_server_specified_bytes { + assert_eq!(num_transactions, 1); // Data cannot be reduced more than a single item + } else { + // Determine the max specified bytes + let max_specified_bytes = if use_request_v2 { + min(max_client_specified_bytes, max_server_specified_bytes) + } else { + max_server_specified_bytes + }; + + // Verify the number of transactions fits within the specified byte limit + let max_transactions = max_specified_bytes / min_bytes_per_transaction; + assert!(num_transactions <= max_transactions); + } +} + /// Verifies that a transactions or outputs with proof response is received /// and that the response contains the correct data. fn verify_transactions_or_output_response( + use_request_v2: bool, fallback_to_transactions: bool, - output_list_with_proof: &TransactionOutputListWithProof, - transaction_list_with_proof: &TransactionListWithProof, + output_list_with_proof: &TransactionOutputListWithProofV2, + transaction_list_with_proof: &TransactionListWithProofV2, response: &StorageServiceResponse, ) { - match response.get_data_response().unwrap() { - DataResponse::TransactionsOrOutputsWithProof(transactions_or_outputs_with_proof) => { - let (transactions_with_proof, outputs_with_proof) = transactions_or_outputs_with_proof; + // Get the data response + let data_response = response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::TransactionsOrOutputsWithProof(_) => assert!(!use_request_v2), + DataResponse::TransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected transactions or outputs with proof but got: {:?}", + response + ), + } + + // Verify the response data + match data_response { + DataResponse::TransactionsOrOutputsWithProof(( + transactions_with_proof, + outputs_with_proof, + )) => { if fallback_to_transactions { assert_eq!( transactions_with_proof.unwrap(), + transaction_list_with_proof + .get_transaction_list_with_proof() + .clone() + ); + } else { + assert_eq!( + outputs_with_proof.unwrap(), + output_list_with_proof.get_output_list_with_proof().clone(), + ); + } + }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof) => { + if fallback_to_transactions { + // Verify the data type + assert_eq!( + transaction_data_with_proof.transaction_data_response_type, + TransactionDataResponseType::TransactionData + ); + + assert_eq!( + transaction_data_with_proof + .transaction_list_with_proof + .unwrap(), transaction_list_with_proof.clone() ); } else { - assert_eq!(outputs_with_proof.unwrap(), output_list_with_proof.clone()); + // Verify the data type + assert_eq!( + transaction_data_with_proof.transaction_data_response_type, + TransactionDataResponseType::TransactionOutputData + ); + + assert_eq!( + transaction_data_with_proof + .transaction_output_list_with_proof + .unwrap(), + output_list_with_proof.clone() + ); } }, _ => panic!( "Expected transactions or outputs with proof but got: {:?}", response ), - }; + } } diff --git a/state-sync/storage-service/server/src/tests/utils.rs b/state-sync/storage-service/server/src/tests/utils.rs index 83ee7276f7c..42eea05e7f6 100644 --- a/state-sync/storage-service/server/src/tests/utils.rs +++ b/state-sync/storage-service/server/src/tests/utils.rs @@ -25,7 +25,10 @@ use aptos_storage_service_types::{ SubscribeTransactionsOrOutputsWithProofRequest, SubscribeTransactionsWithProofRequest, SubscriptionStreamMetadata, TransactionsWithProofRequest, }, - responses::{CompleteDataRange, DataResponse, StorageServerSummary, StorageServiceResponse}, + responses::{ + CompleteDataRange, DataResponse, StorageServerSummary, StorageServiceResponse, + TransactionDataResponseType, TransactionDataWithProofResponse, + }, Epoch, StorageServiceError, }; use aptos_time_service::{MockTimeService, TimeService}; @@ -34,14 +37,18 @@ use aptos_types::{ aggregate_signature::AggregateSignature, block_info::BlockInfo, chain_id::ChainId, + contract_event::ContractEvent, epoch_change::EpochChangeProof, epoch_state::EpochState, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, on_chain_config::ValidatorSet, + proof::{TransactionAccumulatorRangeProof, TransactionInfoListWithProof}, transaction::{ - ExecutionStatus, RawTransaction, Script, SignedTransaction, Transaction, - TransactionAuxiliaryData, TransactionListWithProof, TransactionOutput, - TransactionOutputListWithProof, TransactionPayload, TransactionStatus, + ExecutionStatus, PersistedAuxiliaryInfo, RawTransaction, Script, SignedTransaction, + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionListWithAuxiliaryInfos, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithAuxiliaryInfos, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, TransactionPayload, TransactionStatus, }, validator_verifier::ValidatorVerifier, write_set::WriteSet, @@ -51,8 +58,12 @@ use bytes::Bytes; use claims::assert_none; use dashmap::DashMap; use futures::channel::oneshot::Receiver; -use mockall::predicate::eq; +use mockall::{ + predicate::{always, eq}, + Sequence, +}; use rand::{prelude::SliceRandom, rngs::OsRng, Rng}; +use serde::Serialize; use std::{collections::HashMap, future::Future, sync::Arc, time::Duration}; use tokio::time::timeout; @@ -128,27 +139,34 @@ pub fn create_output_list_using_sizes( start_version: u64, num_outputs: u64, min_bytes_per_output: u64, -) -> TransactionOutputListWithProof { + use_request_v2: bool, +) -> TransactionOutputListWithProofV2 { // Create a test transaction list that enforces the given size requirements - let transaction_list_with_proof = create_transaction_list_using_sizes( - start_version, - num_outputs, - min_bytes_per_output, - false, - ); + let (transaction_list_with_proof, persisted_auxiliary_info) = + create_transaction_list_using_sizes( + start_version, + num_outputs, + min_bytes_per_output, + false, + use_request_v2, + ) + .into_parts(); // Create a test transaction and output list let transactions_and_outputs = transaction_list_with_proof .transactions - .iter() - .map(|txn| (txn.clone(), create_test_transaction_output())) + .into_iter() + .map(|txn| (txn, create_test_transaction_output())) .collect(); - TransactionOutputListWithProof::new( - transactions_and_outputs, - Some(start_version), - transaction_list_with_proof.proof, - ) + TransactionOutputListWithProofV2::new(TransactionOutputListWithAuxiliaryInfos::new( + TransactionOutputListWithProof::new( + transactions_and_outputs, + Some(start_version), + transaction_list_with_proof.proof, + ), + persisted_auxiliary_info, + )) } /// Creates a test transaction output list with proof @@ -156,20 +174,53 @@ pub fn create_output_list_with_proof( start_version: u64, end_version: u64, proof_version: u64, -) -> TransactionOutputListWithProof { - let transaction_list_with_proof = - create_transaction_list_with_proof(start_version, end_version, proof_version, false); + use_request_v2: bool, +) -> TransactionOutputListWithProofV2 { + let (transaction_list_with_proof, persisted_auxiliary_info) = + create_transaction_list_with_proof( + start_version, + end_version, + proof_version, + false, + use_request_v2, + ) + .into_parts(); let transactions_and_outputs = transaction_list_with_proof .transactions .iter() .map(|txn| (txn.clone(), create_test_transaction_output())) .collect(); - TransactionOutputListWithProof::new( - transactions_and_outputs, - Some(start_version), - transaction_list_with_proof.proof, - ) + TransactionOutputListWithProofV2::new(TransactionOutputListWithAuxiliaryInfos::new( + TransactionOutputListWithProof::new( + transactions_and_outputs, + Some(start_version), + transaction_list_with_proof.proof, + ), + persisted_auxiliary_info, + )) +} + +/// Creates and returns a list of persisted auxiliary infos (if request v2 is enabled) +pub fn create_persisted_auxiliary_infos( + start_version: u64, + end_version: u64, + use_request_v2: bool, +) -> Vec { + let mut persisted_auxiliary_infos = vec![]; + for i in start_version..=end_version { + let persisted_auxiliary_info = if use_request_v2 { + PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + } + } else { + PersistedAuxiliaryInfo::None + }; + persisted_auxiliary_infos.push(persisted_auxiliary_info); + } + + // Return the list of auxiliary infos + persisted_auxiliary_infos } /// Creates a vector of entries from first_index to last_index (inclusive) @@ -180,6 +231,18 @@ pub fn create_shuffled_vector(first_index: u64, last_index: u64) -> Vec { vector } +/// Creates and returns a storage service config +pub fn create_storage_config( + enable_transaction_data_v2: bool, + enable_size_and_time_aware_chunking: bool, +) -> StorageServiceConfig { + StorageServiceConfig { + enable_transaction_data_v2, + enable_size_and_time_aware_chunking, + ..Default::default() + } +} + /// Creates a test ledger info with signatures pub fn create_test_ledger_info_with_sigs(epoch: u64, version: u64) -> LedgerInfoWithSignatures { // Create a mock ledger info with signatures @@ -228,32 +291,61 @@ pub fn create_transaction_list_using_sizes( num_transactions: u64, min_bytes_per_transaction: u64, include_events: bool, -) -> TransactionListWithProof { + use_request_v2: bool, +) -> TransactionListWithProofV2 { // Generate random bytes of the given size let mut rng = rand::thread_rng(); let random_bytes: Vec = (0..min_bytes_per_transaction) - .map(|_| rng.gen::()) + .map(|_| rng.r#gen::()) .collect(); - // Include events if required - let events = if include_events { Some(vec![]) } else { None }; - - // Create the requested transactions + // Create the transaction data let mut transactions = vec![]; - for sequence_number in start_version..=start_version + num_transactions - 1 { + let mut transaction_infos = vec![]; + let mut events = vec![]; + let end_version = start_version + num_transactions - 1; + for sequence_number in start_version..=end_version { + // Create a transaction info + let transaction_info = TransactionInfo::new( + HashValue::zero(), + HashValue::zero(), + HashValue::zero(), + None, + 0, + ExecutionStatus::Success, + None, + ); + + // Save the transaction data transactions.push(create_test_transaction( sequence_number, random_bytes.clone(), )); + transaction_infos.push(transaction_info); + events.push(vec![]); } - // Create a transaction list with an empty proof - let mut transaction_list_with_proof = TransactionListWithProof::new_empty(); - transaction_list_with_proof.first_transaction_version = Some(start_version); - transaction_list_with_proof.events = events; - transaction_list_with_proof.transactions = transactions; + // Create a transaction list with proof + let events = if include_events { Some(events) } else { None }; + let transaction_info_list_with_proof = TransactionInfoListWithProof::new( + TransactionAccumulatorRangeProof::new_empty(), + transaction_infos, + ); + let transaction_list_with_proof = TransactionListWithProof::new( + transactions, + events, + Some(start_version), + transaction_info_list_with_proof, + ); + + // Create the auxiliary infos + let auxiliary_infos = + create_persisted_auxiliary_infos(start_version, end_version, use_request_v2); - transaction_list_with_proof + TransactionListWithProofV2::new(TransactionListWithAuxiliaryInfos::new( + transaction_list_with_proof, + auxiliary_infos, + )) } /// Creates a test transaction output list with proof @@ -262,32 +354,69 @@ pub fn create_transaction_list_with_proof( end_version: u64, _proof_version: u64, include_events: bool, -) -> TransactionListWithProof { - // Include events if required - let events = if include_events { Some(vec![]) } else { None }; - - // Create the requested transactions + use_request_v2: bool, +) -> TransactionListWithProofV2 { + // Create the transaction data let mut transactions = vec![]; + let mut transaction_infos = vec![]; + let mut events = vec![]; for sequence_number in start_version..=end_version { + // Create a transaction info + let transaction_info = TransactionInfo::new( + HashValue::zero(), + HashValue::zero(), + HashValue::zero(), + None, + 0, + ExecutionStatus::Success, + None, + ); + + // Save the transaction data transactions.push(create_test_transaction(sequence_number, vec![])); + transaction_infos.push(transaction_info); + events.push(vec![]); } - // Create a transaction list with an empty proof - let mut transaction_list_with_proof = TransactionListWithProof::new_empty(); - transaction_list_with_proof.first_transaction_version = Some(start_version); - transaction_list_with_proof.events = events; - transaction_list_with_proof.transactions = transactions; + // Create a transaction list with proof + let events = if include_events { Some(events) } else { None }; + let transaction_info_list_with_proof = TransactionInfoListWithProof::new( + TransactionAccumulatorRangeProof::new_empty(), + transaction_infos, + ); + let transaction_list_with_proof = TransactionListWithProof::new( + transactions, + events, + Some(start_version), + transaction_info_list_with_proof, + ); + + // Create the auxiliary infos + let auxiliary_infos = + create_persisted_auxiliary_infos(start_version, end_version, use_request_v2); - transaction_list_with_proof + TransactionListWithProofV2::new(TransactionListWithAuxiliaryInfos::new( + transaction_list_with_proof, + auxiliary_infos, + )) } /// Creates a test transaction output fn create_test_transaction_output() -> TransactionOutput { + // Create the event list + let mut events = vec![]; + for _ in 0..10 { + let event = + ContractEvent::new_v2_with_type_tag_str("0x1::dkg::DKGStartEvent", b"dkg_2".to_vec()); + events.push(event); + } + + // Create the transaction output TransactionOutput::new( WriteSet::default(), - vec![], + events, 0, - TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(None)), + TransactionStatus::Keep(ExecutionStatus::Success), TransactionAuxiliaryData::default(), ) } @@ -297,22 +426,82 @@ fn create_test_transaction_output() -> TransactionOutput { /// list (depending on if `fallback_to_transactions` is set). pub fn configure_network_chunk_limit( fallback_to_transactions: bool, - output_list_with_proof: &TransactionOutputListWithProof, - transaction_list_with_proof: &TransactionListWithProof, + output_list_with_proof: &TransactionOutputListWithProofV2, + transaction_list_with_proof: &TransactionListWithProofV2, + enable_transaction_data_v2: bool, + enable_size_and_time_aware_chunking: bool, ) -> StorageServiceConfig { + // Determine the max network chunk bytes let max_network_chunk_bytes = if fallback_to_transactions { - // Network limit is only big enough for the transaction list - bcs::serialized_size(&transaction_list_with_proof).unwrap() as u64 + 1 + if enable_size_and_time_aware_chunking { + let (transaction_list, persisted_auxiliary_infos) = + transaction_list_with_proof.clone().into_parts(); + + // Calculate the serialized size of each component + let mut serialized_size = 0; + for transaction in transaction_list.transactions { + serialized_size += get_num_serialized_bytes(&transaction) + 1; + } + for transaction_info in transaction_list.proof.transaction_infos { + serialized_size += get_num_serialized_bytes(&transaction_info) + 1; + } + if let Some(events) = transaction_list.events { + for events in events { + serialized_size += get_num_serialized_bytes(&events) + 1; + } + } + for auxiliary_info in persisted_auxiliary_infos { + serialized_size += get_num_serialized_bytes(&auxiliary_info) + 1; + } + serialized_size + 1 + } else { + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionData, + transaction_list_with_proof: Some(transaction_list_with_proof.clone()), + transaction_output_list_with_proof: None, + }; + bcs::serialized_size(&response).unwrap() as u64 + 1 + } + } else if enable_size_and_time_aware_chunking { + let (output_list, persisted_auxiliary_infos) = output_list_with_proof.clone().into_parts(); + + // Calculate the serialized size of each component + let mut serialized_size = 0; + for (transaction, output) in output_list.transactions_and_outputs { + serialized_size += get_num_serialized_bytes(&transaction) + 1; + serialized_size += get_num_serialized_bytes(&output) + 1; + } + for transaction_info in output_list.proof.transaction_infos { + serialized_size += get_num_serialized_bytes(&transaction_info) + 1; + } + for auxiliary_info in persisted_auxiliary_infos { + serialized_size += get_num_serialized_bytes(&auxiliary_info) + 1; + } + serialized_size + 1 } else { - // Network limit is big enough for the output list - bcs::serialized_size(&output_list_with_proof).unwrap() as u64 + 1 + let response = TransactionDataWithProofResponse { + transaction_data_response_type: TransactionDataResponseType::TransactionOutputData, + transaction_list_with_proof: None, + transaction_output_list_with_proof: Some(output_list_with_proof.clone()), + }; + bcs::serialized_size(&response).unwrap() as u64 + 1 }; + + // Create the storage service config StorageServiceConfig { max_network_chunk_bytes, + enable_transaction_data_v2, + enable_size_and_time_aware_chunking, + max_network_chunk_bytes_v2: max_network_chunk_bytes, // Use the same limit for v2 ..Default::default() } } +/// Serializes the given data and returns the number of serialized bytes +fn get_num_serialized_bytes(data: &T) -> u64 { + bcs::serialized_size(data).unwrap() as u64 +} + /// Advances the mock time service by the specified number of milliseconds pub async fn elapse_time(time_ms: u64, time_service: &TimeService) { time_service @@ -328,12 +517,25 @@ pub fn expect_get_epoch_ending_ledger_infos( start_epoch: u64, expected_end_epoch: u64, epoch_change_proof: EpochChangeProof, + use_size_and_time_aware_chunking: bool, ) { + // If size and time-aware chunking are disabled, expect the legacy implementation + if !use_size_and_time_aware_chunking { + mock_db + .expect_get_epoch_ending_ledger_infos() + .times(1) + .with(eq(start_epoch), eq(expected_end_epoch)) + .returning(move |_, _| Ok(epoch_change_proof.clone())); + return; + } + + // Expect a call to get an epoch ending iterator + let epoch_ending_iterator = epoch_change_proof.ledger_info_with_sigs.into_iter().map(Ok); mock_db - .expect_get_epoch_ending_ledger_infos() + .expect_get_epoch_ending_ledger_info_iterator() .times(1) .with(eq(start_epoch), eq(expected_end_epoch)) - .returning(move |_, _| Ok(epoch_change_proof.clone())); + .returning(move |_, _| Ok(Box::new(epoch_ending_iterator.clone()))); } /// Sets an expectation on the given mock db for a call to fetch transaction outputs @@ -342,13 +544,93 @@ pub fn expect_get_transaction_outputs( start_version: u64, num_items: u64, proof_version: u64, - output_list: TransactionOutputListWithProof, + output_list: TransactionOutputListWithProofV2, + use_size_and_time_aware_chunking: bool, ) { + // If size and time-aware chunking are disabled, expect the legacy implementation + if !use_size_and_time_aware_chunking { + mock_db + .expect_get_transaction_outputs() + .times(1) + .with(eq(start_version), eq(num_items), eq(proof_version)) + .returning(move |_, _, _| Ok(output_list.clone())); + return; + } + + // Expect a call to get a transaction iterator + let (output_list_with_proof, persisted_auxiliary_infos) = output_list.into_parts(); + let mut expectation_sequence = Sequence::new(); + let transaction_iterator = output_list_with_proof + .clone() + .transactions_and_outputs + .into_iter() + .map(|(transaction, _)| Ok(transaction)); + mock_db + .expect_get_transaction_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(transaction_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get a transaction info iterator + let transaction_info_iterator = output_list_with_proof + .clone() + .proof + .transaction_infos + .into_iter() + .map(Ok); + mock_db + .expect_get_transaction_info_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(transaction_info_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get a write set iterator + let write_set_iterator = output_list_with_proof + .clone() + .transactions_and_outputs + .into_iter() + .map(|(_, output)| Ok(output.write_set().clone())); + mock_db + .expect_get_write_set_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(write_set_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get an event iterator + let events_iterator = output_list_with_proof + .clone() + .transactions_and_outputs + .into_iter() + .map(|(_, output)| Ok(output.events().to_vec())); + mock_db + .expect_get_events_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(events_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get a persisted auxiliary info iterator + let persisted_auxiliary_info_iterator = persisted_auxiliary_infos.clone().into_iter().map(Ok); mock_db - .expect_get_transaction_outputs() + .expect_get_persisted_auxiliary_info_iterator() .times(1) - .with(eq(start_version), eq(num_items), eq(proof_version)) - .returning(move |_, _, _| Ok(output_list.clone())); + .with(eq(start_version), eq(num_items as usize)) + .returning(move |_, _| Ok(Box::new(persisted_auxiliary_info_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get the transaction accumulator range proof + let accumulator_range_proof = output_list_with_proof + .proof + .ledger_info_to_transaction_infos_proof; + mock_db + .expect_get_transaction_accumulator_range_proof() + .times(1) + .with(eq(start_version), always(), eq(proof_version)) + .returning(move |_, _, _| Ok(accumulator_range_proof.clone())) + .in_sequence(&mut expectation_sequence); } /// Sets an expectation on the given mock db for a call to fetch transactions @@ -358,18 +640,88 @@ pub fn expect_get_transactions( num_items: u64, proof_version: u64, include_events: bool, - transaction_list: TransactionListWithProof, + transaction_list: TransactionListWithProofV2, + use_size_and_time_aware_chunking: bool, ) { + // If size and time-aware chunking are disabled, expect the legacy implementation + if !use_size_and_time_aware_chunking { + mock_db + .expect_get_transactions() + .times(1) + .with( + eq(start_version), + eq(num_items), + eq(proof_version), + eq(include_events), + ) + .returning(move |_, _, _, _| Ok(transaction_list.clone())); + return; + } + + // Expect a call to get a transaction iterator + let (transaction_list_with_proof, persisted_auxiliary_infos) = transaction_list.into_parts(); + let mut expectation_sequence = Sequence::new(); + let transaction_iterator = transaction_list_with_proof + .clone() + .transactions + .into_iter() + .map(Ok); mock_db - .expect_get_transactions() + .expect_get_transaction_iterator() .times(1) - .with( - eq(start_version), - eq(num_items), - eq(proof_version), - eq(include_events), - ) - .returning(move |_, _, _, _| Ok(transaction_list.clone())); + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(transaction_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get a transaction info iterator + let transaction_info_iterator = transaction_list_with_proof + .clone() + .proof + .transaction_infos + .into_iter() + .map(Ok); + mock_db + .expect_get_transaction_info_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(transaction_info_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get an event iterator (only if events are requested) + if include_events { + let events_iterator = transaction_list_with_proof + .clone() + .events + .unwrap() + .into_iter() + .map(Ok); + mock_db + .expect_get_events_iterator() + .times(1) + .with(eq(start_version), eq(num_items)) + .returning(move |_, _| Ok(Box::new(events_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + } + + // Expect a call to get a persisted auxiliary info iterator + let persisted_auxiliary_info_iterator = persisted_auxiliary_infos.clone().into_iter().map(Ok); + mock_db + .expect_get_persisted_auxiliary_info_iterator() + .times(1) + .with(eq(start_version), eq(num_items as usize)) + .returning(move |_, _| Ok(Box::new(persisted_auxiliary_info_iterator.clone()))) + .in_sequence(&mut expectation_sequence); + + // Expect a call to get the transaction accumulator range proof + let accumulator_range_proof = transaction_list_with_proof + .proof + .ledger_info_to_transaction_infos_proof; + mock_db + .expect_get_transaction_accumulator_range_proof() + .times(1) + .with(eq(start_version), always(), eq(proof_version)) + .returning(move |_, _, _| Ok(accumulator_range_proof.clone())) + .in_sequence(&mut expectation_sequence); } /// Extracts the peer and network ids from an optional peer network id @@ -402,7 +754,7 @@ pub async fn force_cache_update_notification( // Generate a random number and if the number is even, send // a state sync notification. Otherwise, advance enough time // to refresh the storage cache manually. - let random_number: u8 = OsRng.gen(); + let random_number: u8 = OsRng.r#gen(); if always_advance_time || random_number % 2 != 0 { // Advance the storage refresh time manually advance_storage_refresh_time(mock_time).await; @@ -470,7 +822,7 @@ pub async fn get_number_of_states( /// Generates and returns a random number (u64) pub fn get_random_u64() -> u64 { - OsRng.gen() + OsRng.r#gen() } /// Sends a state values with proof request and processes the response @@ -497,13 +849,25 @@ pub async fn get_transactions_with_proof( proof_version: u64, include_events: bool, use_compression: bool, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Result { - let data_request = DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { - proof_version, - start_version, - end_version, - include_events, - }); + let data_request = if use_request_v2 { + DataRequest::get_transaction_data_with_proof( + proof_version, + start_version, + end_version, + include_events, + max_response_bytes_v2, + ) + } else { + DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { + proof_version, + start_version, + end_version, + include_events, + }) + }; send_storage_request(mock_client, use_compression, data_request).await } @@ -525,6 +889,8 @@ pub async fn send_output_subscription_request_batch( stream_id: u64, peer_version: u64, peer_epoch: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> HashMap>> { // Shuffle the stream request indices to emulate out of order requests let stream_request_indices = @@ -541,6 +907,8 @@ pub async fn send_output_subscription_request_batch( stream_id, stream_request_index, Some(peer_network_id), + use_request_v2, + max_response_bytes_v2, ) .await; @@ -570,6 +938,8 @@ pub async fn subscribe_to_transactions_or_outputs( max_num_output_reductions: u64, stream_id: u64, stream_index: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { subscribe_to_transactions_or_outputs_for_peer( mock_client, @@ -580,6 +950,8 @@ pub async fn subscribe_to_transactions_or_outputs( stream_id, stream_index, None, + use_request_v2, + max_response_bytes_v2, ) .await } @@ -594,6 +966,8 @@ pub async fn subscribe_to_transactions_or_outputs_for_peer( subscription_stream_id: u64, subscription_stream_index: u64, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request let subscription_stream_metadata = SubscriptionStreamMetadata { @@ -601,14 +975,23 @@ pub async fn subscribe_to_transactions_or_outputs_for_peer( known_epoch_at_stream_start, subscription_stream_id, }; - let data_request = DataRequest::SubscribeTransactionsOrOutputsWithProof( - SubscribeTransactionsOrOutputsWithProofRequest { + let data_request = if use_request_v2 { + DataRequest::subscribe_transaction_or_output_data_with_proof( subscription_stream_metadata, - include_events, - max_num_output_reductions, subscription_stream_index, - }, - ); + include_events, + max_response_bytes_v2, + ) + } else { + DataRequest::SubscribeTransactionsOrOutputsWithProof( + SubscribeTransactionsOrOutputsWithProofRequest { + subscription_stream_metadata, + include_events, + max_num_output_reductions, + subscription_stream_index, + }, + ) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request @@ -625,6 +1008,8 @@ pub async fn subscribe_to_transaction_outputs( known_epoch: u64, stream_id: u64, stream_index: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { subscribe_to_transaction_outputs_for_peer( mock_client, @@ -633,6 +1018,8 @@ pub async fn subscribe_to_transaction_outputs( stream_id, stream_index, None, + use_request_v2, + max_response_bytes_v2, ) .await } @@ -645,6 +1032,8 @@ pub async fn subscribe_to_transaction_outputs_for_peer( subscription_stream_id: u64, subscription_stream_index: u64, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request let subscription_stream_metadata = SubscriptionStreamMetadata { @@ -652,12 +1041,20 @@ pub async fn subscribe_to_transaction_outputs_for_peer( known_epoch_at_stream_start, subscription_stream_id, }; - let data_request = DataRequest::SubscribeTransactionOutputsWithProof( - SubscribeTransactionOutputsWithProofRequest { + let data_request = if use_request_v2 { + DataRequest::subscribe_transaction_output_data_with_proof( subscription_stream_metadata, subscription_stream_index, - }, - ); + max_response_bytes_v2, + ) + } else { + DataRequest::SubscribeTransactionOutputsWithProof( + SubscribeTransactionOutputsWithProofRequest { + subscription_stream_metadata, + subscription_stream_index, + }, + ) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request @@ -675,6 +1072,8 @@ pub async fn subscribe_to_transactions( include_events: bool, stream_id: u64, stream_index: u64, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { subscribe_to_transactions_for_peer( mock_client, @@ -684,6 +1083,8 @@ pub async fn subscribe_to_transactions( stream_id, stream_index, None, + use_request_v2, + max_response_bytes_v2, ) .await } @@ -697,6 +1098,8 @@ pub async fn subscribe_to_transactions_for_peer( subscription_stream_id: u64, subscription_stream_index: u64, peer_network_id: Option, + use_request_v2: bool, + max_response_bytes_v2: u64, ) -> Receiver> { // Create the data request let subscription_stream_metadata = SubscriptionStreamMetadata { @@ -704,12 +1107,20 @@ pub async fn subscribe_to_transactions_for_peer( known_epoch_at_stream_start, subscription_stream_id, }; - let data_request = + let data_request = if use_request_v2 { + DataRequest::subscribe_transaction_data_with_proof( + subscription_stream_metadata, + subscription_stream_index, + include_events, + max_response_bytes_v2, + ) + } else { DataRequest::SubscribeTransactionsWithProof(SubscribeTransactionsWithProofRequest { subscription_stream_metadata, include_events, subscription_stream_index, - }); + }) + }; let storage_request = StorageServiceRequest::new(data_request, true); // Send the request @@ -798,26 +1209,68 @@ pub fn verify_active_stream_id_for_peer( /// and that the response contains the correct data. pub async fn verify_new_transaction_outputs_with_proof( mock_client: &mut MockClient, - receiver: Receiver>, - output_list_with_proof: TransactionOutputListWithProof, + receiver: Receiver>, + use_request_v2: bool, + expected_output_list_with_proof: TransactionOutputListWithProofV2, expected_ledger_info: LedgerInfoWithSignatures, ) { - match mock_client - .wait_for_response(receiver) - .await - .unwrap() - .get_data_response() - .unwrap() - { + // Get the data response + let storage_service_response = mock_client.wait_for_response(receiver).await.unwrap(); + let data_response = storage_service_response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::NewTransactionOutputsWithProof(_) => assert!(!use_request_v2), + DataResponse::NewTransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected new transaction outputs with proof but got: {:?}", + data_response + ), + } + + // Verify the response data + match data_response { DataResponse::NewTransactionOutputsWithProof((outputs_with_proof, ledger_info)) => { - assert_eq!(outputs_with_proof, output_list_with_proof); + assert_eq!( + outputs_with_proof, + expected_output_list_with_proof + .get_output_list_with_proof() + .clone() + ); assert_eq!(ledger_info, expected_ledger_info); }, - response => panic!( + DataResponse::NewTransactionDataWithProof(new_transaction_data_with_proof_response) => { + // Verify the data type + assert_eq!( + new_transaction_data_with_proof_response.transaction_data_response_type, + TransactionDataResponseType::TransactionOutputData + ); + + // Verify the ledger info + assert_eq!( + new_transaction_data_with_proof_response.ledger_info_with_signatures, + expected_ledger_info + ); + + // Verify the transactions + assert!(new_transaction_data_with_proof_response + .transaction_list_with_proof + .is_none()); + + assert_eq!( + new_transaction_data_with_proof_response + .transaction_output_list_with_proof + .unwrap(), + expected_output_list_with_proof + ); + }, + _ => panic!( "Expected new transaction outputs with proof but got: {:?}", - response + data_response ), - }; + } } /// Verifies that a new transactions with proof response is received @@ -825,25 +1278,67 @@ pub async fn verify_new_transaction_outputs_with_proof( pub async fn verify_new_transactions_with_proof( mock_client: &mut MockClient, receiver: Receiver>, - expected_transactions_with_proof: TransactionListWithProof, + use_request_v2: bool, + expected_transactions_with_proof: TransactionListWithProofV2, expected_ledger_info: LedgerInfoWithSignatures, ) { - match mock_client - .wait_for_response(receiver) - .await - .unwrap() - .get_data_response() - .unwrap() - { + // Get the data response + let storage_service_response = mock_client.wait_for_response(receiver).await.unwrap(); + let data_response = storage_service_response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::NewTransactionsWithProof(_) => assert!(!use_request_v2), + DataResponse::NewTransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected new transaction with proof but got: {:?}", + data_response + ), + } + + // Verify the response data + match data_response { DataResponse::NewTransactionsWithProof((transactions_with_proof, ledger_info)) => { - assert_eq!(transactions_with_proof, expected_transactions_with_proof); + assert_eq!( + transactions_with_proof, + expected_transactions_with_proof + .get_transaction_list_with_proof() + .clone() + ); assert_eq!(ledger_info, expected_ledger_info); }, - response => panic!( + DataResponse::NewTransactionDataWithProof(new_transaction_data_with_proof_response) => { + // Verify the data type + assert_eq!( + new_transaction_data_with_proof_response.transaction_data_response_type, + TransactionDataResponseType::TransactionData + ); + + // Verify the ledger info + assert_eq!( + new_transaction_data_with_proof_response.ledger_info_with_signatures, + expected_ledger_info + ); + + // Verify the outputs + assert!(new_transaction_data_with_proof_response + .transaction_output_list_with_proof + .is_none()); + + assert_eq!( + new_transaction_data_with_proof_response + .transaction_list_with_proof + .unwrap(), + expected_transactions_with_proof + ); + }, + _ => panic!( "Expected new transaction with proof but got: {:?}", - response + data_response ), - }; + } } /// Verifies that a new transactions or outputs with proof response is received @@ -851,34 +1346,145 @@ pub async fn verify_new_transactions_with_proof( pub async fn verify_new_transactions_or_outputs_with_proof( mock_client: &mut MockClient, receiver: Receiver>, - expected_transaction_list_with_proof: Option, - expected_output_list_with_proof: Option, + use_request_v2: bool, + expected_transaction_list_with_proof: Option, + expected_output_list_with_proof: Option, expected_ledger_info: LedgerInfoWithSignatures, ) { - let response = mock_client.wait_for_response(receiver).await.unwrap(); - match response.get_data_response().unwrap() { + // Get the data response + let storage_service_response = mock_client.wait_for_response(receiver).await.unwrap(); + let data_response = storage_service_response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::NewTransactionsOrOutputsWithProof(_) => assert!(!use_request_v2), + DataResponse::NewTransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected new transactions or outputs with proof but got: {:?}", + data_response + ), + } + + // Verify the response data + match data_response { DataResponse::NewTransactionsOrOutputsWithProof(( - transactions_or_outputs_with_proof, + (transactions_with_proof, outputs_with_proof), ledger_info, )) => { - let (transactions_with_proof, outputs_with_proof) = transactions_or_outputs_with_proof; - if let Some(transactions_with_proof) = transactions_with_proof { + // Verify the ledger info + assert_eq!(ledger_info, expected_ledger_info); + + // Verify the transactions or outputs + assert_eq!( + transactions_with_proof, + expected_transaction_list_with_proof + .map(|t| t.get_transaction_list_with_proof().clone()) + ); + assert_eq!( + outputs_with_proof, + expected_output_list_with_proof.map(|t| t.get_output_list_with_proof().clone()) + ); + }, + DataResponse::NewTransactionDataWithProof(new_transaction_data_with_proof_response) => { + // Verify the ledger info + assert_eq!( + new_transaction_data_with_proof_response.ledger_info_with_signatures, + expected_ledger_info + ); + + // Verify the transactions or outputs + if let Some(transactions_with_proof_v2) = + new_transaction_data_with_proof_response.transaction_list_with_proof + { + assert_eq!( + new_transaction_data_with_proof_response.transaction_data_response_type, + TransactionDataResponseType::TransactionData, + ); + assert!(new_transaction_data_with_proof_response + .transaction_output_list_with_proof + .is_none()); assert_eq!( - transactions_with_proof, + transactions_with_proof_v2, expected_transaction_list_with_proof.unwrap() ); - } else { + } else if let Some(outputs_with_proof_v2) = + new_transaction_data_with_proof_response.transaction_output_list_with_proof + { assert_eq!( - outputs_with_proof.unwrap(), + new_transaction_data_with_proof_response.transaction_data_response_type, + TransactionDataResponseType::TransactionOutputData, + ); + assert!(new_transaction_data_with_proof_response + .transaction_list_with_proof + .is_none()); + assert_eq!( + outputs_with_proof_v2, expected_output_list_with_proof.unwrap() ); + } else { + panic!("Expected either transactions or outputs with proof, but got neither!"); } - assert_eq!(ledger_info, expected_ledger_info); }, - response => panic!( - "Expected new transaction outputs with proof but got: {:?}", - response + _ => panic!( + "Expected new transactions or outputs with proof but got: {:?}", + data_response ), + } +} + +/// Verifies the response for a transaction with proof request +pub fn verify_transaction_with_proof_response( + use_request_v2: bool, + transaction_list_with_proof: TransactionListWithProofV2, + response: StorageServiceResponse, +) { + // Get the data response + let data_response = response.get_data_response().unwrap(); + + // Verify the response type (v1 or v2) + match &data_response { + DataResponse::TransactionsWithProof(_) => assert!(!use_request_v2), + DataResponse::TransactionDataWithProof(_) => { + assert!(use_request_v2) + }, + _ => panic!( + "Expected transactions with proof but got: {:?}", + data_response + ), + } + + // Verify the response data + match data_response { + DataResponse::TransactionsWithProof(transactions_with_proof) => { + assert_eq!( + transactions_with_proof, + transaction_list_with_proof + .get_transaction_list_with_proof() + .clone() + ) + }, + DataResponse::TransactionDataWithProof(transaction_data_with_proof) => { + // Verify the data type + assert_eq!( + transaction_data_with_proof.transaction_data_response_type, + TransactionDataResponseType::TransactionData + ); + + // Verify the outputs + assert!(transaction_data_with_proof + .transaction_output_list_with_proof + .is_none()); + + assert_eq!( + transaction_data_with_proof + .transaction_list_with_proof + .unwrap(), + transaction_list_with_proof + ); + }, + _ => panic!("Expected transactions with proof but got: {:?}", response), }; } @@ -894,16 +1500,18 @@ pub fn verify_no_subscription_responses( /// Verifies that a response is received for a given stream request index /// and that the response contains the correct data. pub async fn verify_output_subscription_response( - expected_output_lists_with_proofs: Vec, + expected_output_lists_with_proofs: Vec, expected_target_ledger_info: LedgerInfoWithSignatures, mock_client: &mut MockClient, response_receivers: &mut HashMap>>, stream_request_index: u64, + use_request_v2: bool, ) { let response_receiver = response_receivers.remove(&stream_request_index).unwrap(); verify_new_transaction_outputs_with_proof( mock_client, response_receiver, + use_request_v2, expected_output_lists_with_proofs[stream_request_index as usize].clone(), expected_target_ledger_info, ) diff --git a/state-sync/storage-service/server/src/utils.rs b/state-sync/storage-service/server/src/utils.rs index e771c549b5f..102ff5aa46b 100644 --- a/state-sync/storage-service/server/src/utils.rs +++ b/state-sync/storage-service/server/src/utils.rs @@ -10,7 +10,10 @@ use aptos_config::network_id::PeerNetworkId; use aptos_metrics_core::HistogramVec; use aptos_storage_service_types::{ requests::{DataRequest, EpochEndingLedgerInfoRequest, StorageServiceRequest}, - responses::{DataResponse, StorageServerSummary, StorageServiceResponse}, + responses::{ + DataResponse, NewTransactionDataWithProofResponse, StorageServerSummary, + StorageServiceResponse, + }, }; use aptos_time_service::TimeService; use aptos_types::ledger_info::LedgerInfoWithSignatures; @@ -145,6 +148,17 @@ pub fn notify_peer_of_new_data( )); } }, + Ok(DataResponse::TransactionDataWithProof(transaction_data_with_proof)) => { + DataResponse::NewTransactionDataWithProof(NewTransactionDataWithProofResponse { + transaction_data_response_type: transaction_data_with_proof + .transaction_data_response_type, + transaction_list_with_proof: transaction_data_with_proof + .transaction_list_with_proof, + transaction_output_list_with_proof: transaction_data_with_proof + .transaction_output_list_with_proof, + ledger_info_with_signatures: target_ledger_info, + }) + }, data_response => { return Err(Error::UnexpectedErrorEncountered(format!( "Failed to get appropriate data response for peer! Got: {:?}", diff --git a/state-sync/storage-service/types/src/requests.rs b/state-sync/storage-service/types/src/requests.rs index e7e03503cc6..67d5cbeacc4 100644 --- a/state-sync/storage-service/types/src/requests.rs +++ b/state-sync/storage-service/types/src/requests.rs @@ -47,6 +47,12 @@ pub enum DataRequest { SubscribeTransactionOutputsWithProof(SubscribeTransactionOutputsWithProofRequest), // Subscribes to transaction outputs with a proof SubscribeTransactionsOrOutputsWithProof(SubscribeTransactionsOrOutputsWithProofRequest), // Subscribes to transactions or outputs with a proof SubscribeTransactionsWithProof(SubscribeTransactionsWithProofRequest), // Subscribes to transactions with a proof + + // All the requests listed below are for transaction data v2 (i.e., transactions with auxiliary information). + // TODO: eventually we should deprecate all the old request types. + GetTransactionDataWithProof(GetTransactionDataWithProofRequest), // Fetches transaction data with a proof + GetNewTransactionDataWithProof(GetNewTransactionDataWithProofRequest), // Optimistically fetches new transaction data with a proof + SubscribeTransactionDataWithProof(SubscribeTransactionDataWithProofRequest), // Subscribes to transaction data with a proof } impl DataRequest { @@ -73,27 +79,238 @@ impl DataRequest { "subscribe_transactions_or_outputs_with_proof" }, Self::SubscribeTransactionsWithProof(_) => "subscribe_transactions_with_proof", + + // Transaction data v2 requests (transactions with auxiliary data) + Self::GetTransactionDataWithProof(request) => match request + .transaction_data_request_type + { + TransactionDataRequestType::TransactionData(_) => "get_transactions_with_proof_v2", + TransactionDataRequestType::TransactionOutputData => { + "get_transaction_outputs_with_proof_v2" + }, + TransactionDataRequestType::TransactionOrOutputData(_) => { + "get_transactions_or_outputs_with_proof_v2" + }, + }, + Self::GetNewTransactionDataWithProof(request) => { + match request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(_) => { + "get_new_transactions_with_proof_v2" + }, + TransactionDataRequestType::TransactionOutputData => { + "get_new_transaction_outputs_with_proof_v2" + }, + TransactionDataRequestType::TransactionOrOutputData(_) => { + "get_new_transactions_or_outputs_with_proof_v2" + }, + } + }, + Self::SubscribeTransactionDataWithProof(request) => { + match request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(_) => { + "subscribe_transactions_with_proof_v2" + }, + TransactionDataRequestType::TransactionOutputData => { + "subscribe_transaction_outputs_with_proof_v2" + }, + TransactionDataRequestType::TransactionOrOutputData(_) => { + "subscribe_transactions_or_outputs_with_proof_v2" + }, + } + }, } } + /// Returns true iff the request is an optimistic fetch request pub fn is_optimistic_fetch(&self) -> bool { matches!(self, &Self::GetNewTransactionOutputsWithProof(_)) || matches!(self, &Self::GetNewTransactionsWithProof(_)) || matches!(self, Self::GetNewTransactionsOrOutputsWithProof(_)) + || matches!(self, &Self::GetNewTransactionDataWithProof(_)) } + /// Returns true iff the request is a protocol version request pub fn is_protocol_version_request(&self) -> bool { matches!(self, &Self::GetServerProtocolVersion) } + /// Returns true iff the request is a storage summary request pub fn is_storage_summary_request(&self) -> bool { matches!(self, &Self::GetStorageServerSummary) } + /// Returns true iff the request is a subscription request pub fn is_subscription_request(&self) -> bool { matches!(self, &Self::SubscribeTransactionOutputsWithProof(_)) || matches!(self, &Self::SubscribeTransactionsWithProof(_)) || matches!(self, Self::SubscribeTransactionsOrOutputsWithProof(_)) + || matches!(self, Self::SubscribeTransactionDataWithProof(_)) + } + + /// Returns true iff the request is a transaction data v2 request + pub fn is_transaction_data_v2_request(&self) -> bool { + matches!(self, &Self::GetTransactionDataWithProof(_)) + || matches!(self, &Self::GetNewTransactionDataWithProof(_)) + || matches!(self, &Self::SubscribeTransactionDataWithProof(_)) + } + + /// Creates and returns a request to get transaction data with a proof + pub fn get_transaction_data_with_proof( + proof_version: u64, + start_version: u64, + end_version: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionData(TransactionData { include_events }); + Self::GetTransactionDataWithProof(GetTransactionDataWithProofRequest { + transaction_data_request_type, + proof_version, + start_version, + end_version, + max_response_bytes, + }) + } + + /// Creates and returns a request to get new transaction output data with a proof + pub fn get_transaction_output_data_with_proof( + proof_version: u64, + start_version: u64, + end_version: u64, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = TransactionDataRequestType::TransactionOutputData; + Self::GetTransactionDataWithProof(GetTransactionDataWithProofRequest { + transaction_data_request_type, + proof_version, + start_version, + end_version, + max_response_bytes, + }) + } + + /// Creates and returns a request to get new transaction or output data with a proof + pub fn get_transaction_or_output_data_with_proof( + proof_version: u64, + start_version: u64, + end_version: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionOrOutputData(TransactionOrOutputData { + include_events, + }); + Self::GetTransactionDataWithProof(GetTransactionDataWithProofRequest { + transaction_data_request_type, + proof_version, + start_version, + end_version, + max_response_bytes, + }) + } + + /// Creates and returns a request to get new transaction data with a proof + pub fn get_new_transaction_data_with_proof( + known_version: u64, + known_epoch: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionData(TransactionData { include_events }); + Self::GetNewTransactionDataWithProof(GetNewTransactionDataWithProofRequest { + transaction_data_request_type, + known_version, + known_epoch, + max_response_bytes, + }) + } + + /// Creates and returns a request to get new transaction output data with a proof + pub fn get_new_transaction_output_data_with_proof( + known_version: u64, + known_epoch: u64, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = TransactionDataRequestType::TransactionOutputData; + Self::GetNewTransactionDataWithProof(GetNewTransactionDataWithProofRequest { + transaction_data_request_type, + known_version, + known_epoch, + max_response_bytes, + }) + } + + /// Creates and returns a request to get new transaction or output data with a proof + pub fn get_new_transaction_or_output_data_with_proof( + known_version: u64, + known_epoch: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionOrOutputData(TransactionOrOutputData { + include_events, + }); + Self::GetNewTransactionDataWithProof(GetNewTransactionDataWithProofRequest { + transaction_data_request_type, + known_version, + known_epoch, + max_response_bytes, + }) + } + + /// Creates and returns a request to subscribe to transaction with a proof + pub fn subscribe_transaction_data_with_proof( + subscription_stream_metadata: SubscriptionStreamMetadata, + subscription_stream_index: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionData(TransactionData { include_events }); + Self::SubscribeTransactionDataWithProof(SubscribeTransactionDataWithProofRequest { + transaction_data_request_type, + subscription_stream_metadata, + subscription_stream_index, + max_response_bytes, + }) + } + + /// Creates and returns a request to subscribe to transaction output with a proof + pub fn subscribe_transaction_output_data_with_proof( + subscription_stream_metadata: SubscriptionStreamMetadata, + subscription_stream_index: u64, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = TransactionDataRequestType::TransactionOutputData; + Self::SubscribeTransactionDataWithProof(SubscribeTransactionDataWithProofRequest { + transaction_data_request_type, + subscription_stream_metadata, + subscription_stream_index, + max_response_bytes, + }) + } + + /// Creates and returns a request to subscribe to transaction or output with a proof + pub fn subscribe_transaction_or_output_data_with_proof( + subscription_stream_metadata: SubscriptionStreamMetadata, + subscription_stream_index: u64, + include_events: bool, + max_response_bytes: u64, + ) -> Self { + let transaction_data_request_type = + TransactionDataRequestType::TransactionOrOutputData(TransactionOrOutputData { + include_events, + }); + Self::SubscribeTransactionDataWithProof(SubscribeTransactionDataWithProofRequest { + transaction_data_request_type, + subscription_stream_metadata, + subscription_stream_index, + max_response_bytes, + }) } } @@ -203,3 +420,45 @@ pub struct SubscriptionStreamMetadata { pub known_epoch_at_stream_start: u64, // The highest known epoch at stream start pub subscription_stream_id: u64, // The unique id of the subscription stream } + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct GetTransactionDataWithProofRequest { + pub transaction_data_request_type: TransactionDataRequestType, // The type of transaction data to request + pub proof_version: u64, // The version the proof should be relative to + pub start_version: u64, // The starting version of the data + pub end_version: u64, // The ending version of the data (inclusive) + pub max_response_bytes: u64, // The max number of bytes to return in the response +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct GetNewTransactionDataWithProofRequest { + pub transaction_data_request_type: TransactionDataRequestType, // The type of transaction data to request + pub known_version: u64, // The highest known version + pub known_epoch: u64, // The highest known epoch + pub max_response_bytes: u64, // The max number of bytes to return in the response +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct SubscribeTransactionDataWithProofRequest { + pub transaction_data_request_type: TransactionDataRequestType, // The type of transaction data to request + pub subscription_stream_metadata: SubscriptionStreamMetadata, // The metadata for the subscription stream request + pub subscription_stream_index: u64, // The request index of the subscription stream + pub max_response_bytes: u64, // The max number of bytes to return in the response +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub enum TransactionDataRequestType { + TransactionData(TransactionData), + TransactionOutputData, + TransactionOrOutputData(TransactionOrOutputData), +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct TransactionData { + pub include_events: bool, // Whether to include events with the transactions +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct TransactionOrOutputData { + pub include_events: bool, // Whether to include events with the transactions +} diff --git a/state-sync/storage-service/types/src/responses.rs b/state-sync/storage-service/types/src/responses.rs index 4ad44ab41b5..cd8f2285c0d 100644 --- a/state-sync/storage-service/types/src/responses.rs +++ b/state-sync/storage-service/types/src/responses.rs @@ -2,13 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - requests::DataRequest::{ - GetEpochEndingLedgerInfos, GetNewTransactionOutputsWithProof, - GetNewTransactionsOrOutputsWithProof, GetNewTransactionsWithProof, - GetNumberOfStatesAtVersion, GetServerProtocolVersion, GetStateValuesWithProof, - GetStorageServerSummary, GetTransactionOutputsWithProof, GetTransactionsOrOutputsWithProof, - GetTransactionsWithProof, SubscribeTransactionOutputsWithProof, - SubscribeTransactionsOrOutputsWithProof, SubscribeTransactionsWithProof, + requests::{ + DataRequest::{ + GetEpochEndingLedgerInfos, GetNewTransactionDataWithProof, + GetNewTransactionOutputsWithProof, GetNewTransactionsOrOutputsWithProof, + GetNewTransactionsWithProof, GetNumberOfStatesAtVersion, GetServerProtocolVersion, + GetStateValuesWithProof, GetStorageServerSummary, GetTransactionDataWithProof, + GetTransactionOutputsWithProof, GetTransactionsOrOutputsWithProof, + GetTransactionsWithProof, SubscribeTransactionDataWithProof, + SubscribeTransactionOutputsWithProof, SubscribeTransactionsOrOutputsWithProof, + SubscribeTransactionsWithProof, + }, + TransactionDataRequestType, }, responses::Error::DegenerateRangeError, Epoch, StorageServiceRequest, COMPRESSION_SUFFIX_LABEL, @@ -22,7 +27,10 @@ use aptos_types::{ epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures, state_store::state_value::StateValueChunkWithProof, - transaction::{TransactionListWithProof, TransactionOutputListWithProof, Version}, + transaction::{ + TransactionListWithProof, TransactionListWithProofV2, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, Version, + }, }; use num_traits::{PrimInt, Zero}; #[cfg(test)] @@ -124,6 +132,12 @@ pub type TransactionOrOutputListWithProof = ( Option, ); +/// A useful type to hold optional transaction data v2 +pub type TransactionOrOutputListWithProofV2 = ( + Option, + Option, +); + /// A single data response. #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[allow(clippy::large_enum_variant)] @@ -139,25 +153,156 @@ pub enum DataResponse { TransactionsWithProof(TransactionListWithProof), NewTransactionsOrOutputsWithProof((TransactionOrOutputListWithProof, LedgerInfoWithSignatures)), TransactionsOrOutputsWithProof(TransactionOrOutputListWithProof), + + // All the responses listed below are for transaction data v2 (i.e., transactions with auxiliary information). + // TODO: eventually we should deprecate all the old response types. + TransactionDataWithProof(TransactionDataWithProofResponse), + NewTransactionDataWithProof(NewTransactionDataWithProofResponse), +} + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct TransactionDataWithProofResponse { + pub transaction_data_response_type: TransactionDataResponseType, + pub transaction_list_with_proof: Option, + pub transaction_output_list_with_proof: Option, +} + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct NewTransactionDataWithProofResponse { + pub transaction_data_response_type: TransactionDataResponseType, + pub transaction_list_with_proof: Option, + pub transaction_output_list_with_proof: Option, + pub ledger_info_with_signatures: LedgerInfoWithSignatures, +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub enum TransactionDataResponseType { + TransactionData, + TransactionOutputData, } impl DataResponse { /// Returns a summary label for the response pub fn get_label(&self) -> &'static str { match self { - Self::EpochEndingLedgerInfos(_) => "epoch_ending_ledger_infos", - Self::NewTransactionOutputsWithProof(_) => "new_transaction_outputs_with_proof", - Self::NewTransactionsWithProof(_) => "new_transactions_with_proof", - Self::NumberOfStatesAtVersion(_) => "number_of_states_at_version", - Self::ServerProtocolVersion(_) => "server_protocol_version", - Self::StateValueChunkWithProof(_) => "state_value_chunk_with_proof", - Self::StorageServerSummary(_) => "storage_server_summary", - Self::TransactionOutputsWithProof(_) => "transaction_outputs_with_proof", - Self::TransactionsWithProof(_) => "transactions_with_proof", - Self::NewTransactionsOrOutputsWithProof(_) => "new_transactions_or_outputs_with_proof", - Self::TransactionsOrOutputsWithProof(_) => "transactions_or_outputs_with_proof", + Self::EpochEndingLedgerInfos(_) => Self::get_epoch_ending_ledger_info_label(), + Self::NewTransactionOutputsWithProof(_) => { + Self::get_new_transaction_outputs_with_proof_label() + }, + Self::NewTransactionsWithProof(_) => Self::get_new_transactions_with_proof_label(), + Self::NumberOfStatesAtVersion(_) => Self::get_number_of_states_at_version_label(), + Self::ServerProtocolVersion(_) => Self::get_server_protocol_version_label(), + Self::StateValueChunkWithProof(_) => Self::get_state_value_chunk_with_proof_label(), + Self::StorageServerSummary(_) => Self::get_storage_server_summary_label(), + Self::TransactionOutputsWithProof(_) => { + Self::get_transaction_outputs_with_proof_label() + }, + Self::TransactionsWithProof(_) => Self::get_transactions_with_proof_label(), + Self::NewTransactionsOrOutputsWithProof(_) => { + Self::get_new_transactions_or_outputs_with_proof_label() + }, + Self::TransactionsOrOutputsWithProof(_) => { + Self::get_transactions_or_outputs_with_proof_label() + }, + + // Transaction data v2 responses (transactions with auxiliary data) + Self::TransactionDataWithProof(response) => { + match response.transaction_data_response_type { + TransactionDataResponseType::TransactionData => { + Self::get_transactions_with_proof_v2_label() + }, + TransactionDataResponseType::TransactionOutputData => { + Self::get_transaction_outputs_with_proof_v2_label() + }, + } + }, + Self::NewTransactionDataWithProof(response) => { + match response.transaction_data_response_type { + TransactionDataResponseType::TransactionData => { + Self::new_transactions_with_proof_v2_label() + }, + TransactionDataResponseType::TransactionOutputData => { + Self::get_transaction_outputs_with_proof_v2_label() + }, + } + }, } } + + /// Returns a label for the epoch ending ledger info response + pub fn get_epoch_ending_ledger_info_label() -> &'static str { + "epoch_ending_ledger_infos" + } + + /// Returns a label for the new transaction outputs with proof response + pub fn get_new_transaction_outputs_with_proof_label() -> &'static str { + "new_transaction_outputs_with_proof" + } + + /// Returns a label for the new transactions with proof response + pub fn get_new_transactions_with_proof_label() -> &'static str { + "new_transactions_with_proof" + } + + /// Returns a label for the number of states at version response + pub fn get_number_of_states_at_version_label() -> &'static str { + "number_of_states_at_version" + } + + /// Returns a label for the server protocol version response + pub fn get_server_protocol_version_label() -> &'static str { + "server_protocol_version" + } + + /// Returns a label for the state value chunk with proof response + pub fn get_state_value_chunk_with_proof_label() -> &'static str { + "state_value_chunk_with_proof" + } + + /// Returns a label for the storage server summary response + pub fn get_storage_server_summary_label() -> &'static str { + "storage_server_summary" + } + + /// Returns a label for the transaction outputs with proof response + pub fn get_transaction_outputs_with_proof_label() -> &'static str { + "transaction_outputs_with_proof" + } + + /// Returns a label for the transactions with proof response + pub fn get_transactions_with_proof_label() -> &'static str { + "transactions_with_proof" + } + + /// Returns a label for the new transactions or outputs with proof response + pub fn get_new_transactions_or_outputs_with_proof_label() -> &'static str { + "new_transactions_or_outputs_with_proof" + } + + /// Returns a label for the transactions or outputs with proof response + pub fn get_transactions_or_outputs_with_proof_label() -> &'static str { + "transactions_or_outputs_with_proof" + } + + /// Returns a label for the transactions with proof v2 response + pub fn get_transactions_with_proof_v2_label() -> &'static str { + "transactions_with_proof_v2" + } + + /// Returns a label for the transaction outputs with proof v2 response + pub fn get_transaction_outputs_with_proof_v2_label() -> &'static str { + "transaction_outputs_with_proof_v2" + } + + /// Returns a label for the new transactions with proof v2 response + pub fn new_transactions_with_proof_v2_label() -> &'static str { + "new_transactions_with_proof_v2" + } + + /// Returns a label for the new transaction outputs with proof v2 response + pub fn new_transaction_outputs_with_proof_v2_label() -> &'static str { + "new_transaction_outputs_with_proof_v2" + } } impl Display for DataResponse { @@ -209,14 +354,37 @@ impl TryFrom for EpochChangeProof { } impl TryFrom - for (TransactionOutputListWithProof, LedgerInfoWithSignatures) + for (TransactionOutputListWithProofV2, LedgerInfoWithSignatures) { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::NewTransactionOutputsWithProof(inner) => Ok(inner), + DataResponse::NewTransactionOutputsWithProof(( + output_list_with_proof, + ledger_info_with_signatures, + )) => Ok(( + TransactionOutputListWithProofV2::new_from_v1(output_list_with_proof), + ledger_info_with_signatures, + )), + DataResponse::NewTransactionDataWithProof(response) => { + if let TransactionDataResponseType::TransactionOutputData = + response.transaction_data_response_type + { + if let Some(output_list_with_proof_v2) = + response.transaction_output_list_with_proof + { + return Ok(( + output_list_with_proof_v2, + response.ledger_info_with_signatures, + )); + } + } + Err(Error::UnexpectedResponseError( + "new_transaction_output_list_with_proof is empty".into(), + )) + }, _ => Err(Error::UnexpectedResponseError(format!( "expected new_transaction_outputs_with_proof, found {}", data_response.get_label() @@ -225,13 +393,36 @@ impl TryFrom } } -impl TryFrom for (TransactionListWithProof, LedgerInfoWithSignatures) { +impl TryFrom for (TransactionListWithProofV2, LedgerInfoWithSignatures) { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::NewTransactionsWithProof(inner) => Ok(inner), + DataResponse::NewTransactionsWithProof(( + transaction_list_with_proof, + ledger_info_with_signatures, + )) => Ok(( + TransactionListWithProofV2::new_from_v1(transaction_list_with_proof), + ledger_info_with_signatures, + )), + DataResponse::NewTransactionDataWithProof(response) => { + if let TransactionDataResponseType::TransactionData = + response.transaction_data_response_type + { + if let Some(transaction_list_with_proof_v2) = + response.transaction_list_with_proof + { + return Ok(( + transaction_list_with_proof_v2, + response.ledger_info_with_signatures, + )); + } + } + Err(Error::UnexpectedResponseError( + "new_transaction_list_with_proof is empty".into(), + )) + }, _ => Err(Error::UnexpectedResponseError(format!( "expected new_transactions_with_proof, found {}", data_response.get_label() @@ -285,13 +476,29 @@ impl TryFrom for StorageServerSummary { } } -impl TryFrom for TransactionOutputListWithProof { +impl TryFrom for TransactionOutputListWithProofV2 { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::TransactionOutputsWithProof(inner) => Ok(inner), + DataResponse::TransactionOutputsWithProof(output_list_with_proof) => Ok( + TransactionOutputListWithProofV2::new_from_v1(output_list_with_proof), + ), + DataResponse::TransactionDataWithProof(response) => { + if let TransactionDataResponseType::TransactionOutputData = + response.transaction_data_response_type + { + if let Some(output_list_with_proof_v2) = + response.transaction_output_list_with_proof + { + return Ok(output_list_with_proof_v2); + } + } + Err(Error::UnexpectedResponseError( + "transaction_output_list_with_proof is empty".into(), + )) + }, _ => Err(Error::UnexpectedResponseError(format!( "expected transaction_outputs_with_proof, found {}", data_response.get_label() @@ -300,13 +507,29 @@ impl TryFrom for TransactionOutputListWithProof { } } -impl TryFrom for TransactionListWithProof { +impl TryFrom for TransactionListWithProofV2 { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::TransactionsWithProof(inner) => Ok(inner), + DataResponse::TransactionsWithProof(transaction_list_with_proof) => Ok( + TransactionListWithProofV2::new_from_v1(transaction_list_with_proof), + ), + DataResponse::TransactionDataWithProof(response) => { + if let TransactionDataResponseType::TransactionData = + response.transaction_data_response_type + { + if let Some(transaction_list_with_proof_v2) = + response.transaction_list_with_proof + { + return Ok(transaction_list_with_proof_v2); + } + } + Err(Error::UnexpectedResponseError( + "transaction_list_with_proof is empty".into(), + )) + }, _ => Err(Error::UnexpectedResponseError(format!( "expected transactions_with_proof, found {}", data_response.get_label() @@ -316,14 +539,33 @@ impl TryFrom for TransactionListWithProof { } impl TryFrom - for (TransactionOrOutputListWithProof, LedgerInfoWithSignatures) + for (TransactionOrOutputListWithProofV2, LedgerInfoWithSignatures) { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::NewTransactionsOrOutputsWithProof(inner) => Ok(inner), + DataResponse::NewTransactionsOrOutputsWithProof(( + (transaction_list_with_proof, output_list_with_proof), + ledger_info_with_signatures, + )) => Ok(( + ( + transaction_list_with_proof.map(TransactionListWithProofV2::new_from_v1), + output_list_with_proof.map(TransactionOutputListWithProofV2::new_from_v1), + ), + ledger_info_with_signatures, + )), + DataResponse::NewTransactionDataWithProof(response) => { + let transaction_or_output_list_with_proof = ( + response.transaction_list_with_proof, + response.transaction_output_list_with_proof, + ); + Ok(( + transaction_or_output_list_with_proof, + response.ledger_info_with_signatures, + )) + }, _ => Err(Error::UnexpectedResponseError(format!( "expected new_transactions_or_outputs_with_proof, found {}", data_response.get_label() @@ -332,13 +574,23 @@ impl TryFrom } } -impl TryFrom for TransactionOrOutputListWithProof { +impl TryFrom for TransactionOrOutputListWithProofV2 { type Error = crate::responses::Error; fn try_from(response: StorageServiceResponse) -> crate::Result { let data_response = response.get_data_response()?; match data_response { - DataResponse::TransactionsOrOutputsWithProof(inner) => Ok(inner), + DataResponse::TransactionsOrOutputsWithProof(( + transaction_list_with_proof, + output_list_with_proof, + )) => Ok(( + transaction_list_with_proof.map(TransactionListWithProofV2::new_from_v1), + output_list_with_proof.map(TransactionOutputListWithProofV2::new_from_v1), + )), + DataResponse::TransactionDataWithProof(response) => Ok(( + response.transaction_list_with_proof, + response.transaction_output_list_with_proof, + )), _ => Err(Error::UnexpectedResponseError(format!( "expected transactions_or_outputs_with_proof, found {}", data_response.get_label() @@ -488,71 +740,23 @@ impl DataSummary { can_serve_states && can_create_proof }, - GetTransactionOutputsWithProof(request) => { - let desired_range = - match CompleteDataRange::new(request.start_version, request.end_version) { - Ok(desired_range) => desired_range, - Err(_) => return false, - }; - - let can_serve_outputs = self - .transaction_outputs - .map(|range| range.superset_of(&desired_range)) - .unwrap_or(false); - - let can_create_proof = self - .synced_ledger_info - .as_ref() - .map(|li| li.ledger_info().version() >= request.proof_version) - .unwrap_or(false); - - can_serve_outputs && can_create_proof - }, - GetTransactionsWithProof(request) => { - let desired_range = - match CompleteDataRange::new(request.start_version, request.end_version) { - Ok(desired_range) => desired_range, - Err(_) => return false, - }; - - let can_serve_txns = self - .transactions - .map(|range| range.superset_of(&desired_range)) - .unwrap_or(false); - - let can_create_proof = self - .synced_ledger_info - .as_ref() - .map(|li| li.ledger_info().version() >= request.proof_version) - .unwrap_or(false); - - can_serve_txns && can_create_proof - }, - GetTransactionsOrOutputsWithProof(request) => { - let desired_range = - match CompleteDataRange::new(request.start_version, request.end_version) { - Ok(desired_range) => desired_range, - Err(_) => return false, - }; - - let can_serve_txns = self - .transactions - .map(|range| range.superset_of(&desired_range)) - .unwrap_or(false); - - let can_serve_outputs = self - .transaction_outputs - .map(|range| range.superset_of(&desired_range)) - .unwrap_or(false); - - let can_create_proof = self - .synced_ledger_info - .as_ref() - .map(|li| li.ledger_info().version() >= request.proof_version) - .unwrap_or(false); - - can_serve_txns && can_serve_outputs && can_create_proof - }, + GetTransactionOutputsWithProof(request) => self + .can_service_transaction_outputs_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), + GetTransactionsWithProof(request) => self.can_service_transactions_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), + GetTransactionsOrOutputsWithProof(request) => self + .can_service_transactions_or_outputs_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), SubscribeTransactionOutputsWithProof(_) => can_service_subscription_request( aptos_data_client_config, time_service, @@ -568,9 +772,115 @@ impl DataSummary { time_service, self.synced_ledger_info.as_ref(), ), + + // Transaction data v2 requests (transactions with auxiliary data) + GetTransactionDataWithProof(request) => match request.transaction_data_request_type { + TransactionDataRequestType::TransactionData(_) => self + .can_service_transactions_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), + TransactionDataRequestType::TransactionOutputData => self + .can_service_transaction_outputs_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), + TransactionDataRequestType::TransactionOrOutputData(_) => self + .can_service_transactions_or_outputs_with_proof( + request.start_version, + request.end_version, + request.proof_version, + ), + }, + GetNewTransactionDataWithProof(_) => can_service_optimistic_request( + aptos_data_client_config, + time_service, + self.synced_ledger_info.as_ref(), + ), + SubscribeTransactionDataWithProof(_) => can_service_subscription_request( + aptos_data_client_config, + time_service, + self.synced_ledger_info.as_ref(), + ), } } + /// Returns true iff the peer can create a proof for the given version + fn can_create_proof(&self, proof_version: u64) -> bool { + self.synced_ledger_info + .as_ref() + .map(|li| li.ledger_info().version() >= proof_version) + .unwrap_or(false) + } + + /// Returns true iff the peer can service the transaction outputs in the given range + fn can_service_transaction_outputs(&self, desired_range: &CompleteDataRange) -> bool { + self.transaction_outputs + .map(|range| range.superset_of(desired_range)) + .unwrap_or(false) + } + + /// Returns true iff the peer can service the transactions in the given range + fn can_service_transactions(&self, desired_range: &CompleteDataRange) -> bool { + self.transactions + .map(|range| range.superset_of(desired_range)) + .unwrap_or(false) + } + + /// Returns true iff the peer can service the transaction outputs and proof + fn can_service_transaction_outputs_with_proof( + &self, + start_version: u64, + end_version: u64, + proof_version: u64, + ) -> bool { + let desired_range = match CompleteDataRange::new(start_version, end_version) { + Ok(desired_range) => desired_range, + Err(_) => return false, + }; + + let can_service_outputs = self.can_service_transaction_outputs(&desired_range); + let can_create_proof = self.can_create_proof(proof_version); + can_service_outputs && can_create_proof + } + + /// Returns true iff the peer can service the transactions or outputs and proof + fn can_service_transactions_or_outputs_with_proof( + &self, + start_version: u64, + end_version: u64, + proof_version: u64, + ) -> bool { + let desired_range = match CompleteDataRange::new(start_version, end_version) { + Ok(desired_range) => desired_range, + Err(_) => return false, + }; + + let can_service_transactions = self.can_service_transactions(&desired_range); + let can_service_outputs = self.can_service_transaction_outputs(&desired_range); + let can_create_proof = self.can_create_proof(proof_version); + can_service_transactions && can_service_outputs && can_create_proof + } + + /// Returns true iff the peer can service the transactions and proof + fn can_service_transactions_with_proof( + &self, + start_version: u64, + end_version: u64, + proof_version: u64, + ) -> bool { + let desired_range = match CompleteDataRange::new(start_version, end_version) { + Ok(desired_range) => desired_range, + Err(_) => return false, + }; + + let can_service_transactions = self.can_service_transactions(&desired_range); + let can_create_proof = self.can_create_proof(proof_version); + can_service_transactions && can_create_proof + } + /// Returns the version of the synced ledger info (if one exists) pub fn get_synced_ledger_info_version(&self) -> Option { self.synced_ledger_info diff --git a/state-sync/storage-service/types/src/tests.rs b/state-sync/storage-service/types/src/tests.rs index 7c9090faabc..95be3b4a98e 100644 --- a/state-sync/storage-service/types/src/tests.rs +++ b/state-sync/storage-service/types/src/tests.rs @@ -91,349 +91,381 @@ fn test_data_summary_service_epoch_ending_ledger_infos() { #[test] fn test_data_summary_service_optimistic_fetch() { - // Create a data client config with the specified max optimistic fetch lag - let max_optimistic_fetch_lag_secs = 50; - let data_client_config = AptosDataClientConfig { - max_optimistic_fetch_lag_secs, - ..Default::default() - }; - - // Create a mock time service and get the current timestamp - let time_service = TimeService::mock(); - let timestamp_usecs = time_service.now_unix_time().as_micros() as u64; - - // Create a data summary with the specified synced ledger info - let highest_synced_version = 10_000; - let data_summary = DataSummary { - synced_ledger_info: Some(create_ledger_info_at_version_and_timestamp( - highest_synced_version, - timestamp_usecs, - )), - ..Default::default() - }; - - // Elapse the time service by half the max optimistic fetch lag - time_service - .clone() - .into_mock() - .advance_secs(max_optimistic_fetch_lag_secs / 2); - - // Verify that optimistic fetch requests can be serviced - for compression in [true, false] { - let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; - verify_can_service_optimistic_fetch_requests( - &data_client_config, - &data_summary, - time_service.clone(), - compression, - known_versions, - true, - ); - } - - // Elapse the time service by the max optimistic fetch lag - time_service - .clone() - .into_mock() - .advance_secs(max_optimistic_fetch_lag_secs); - - // Verify that optimistic fetch requests can no longer be serviced - // (as the max lag has been exceeded for the given data summary). - for compression in [true, false] { - let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; - verify_can_service_optimistic_fetch_requests( - &data_client_config, - &data_summary, - time_service.clone(), - compression, - known_versions, - false, - ); + // Test both v1 and v2 transaction requests + for use_request_v2 in [false, true] { + // Create a data client config with the specified max optimistic fetch lag + let max_optimistic_fetch_lag_secs = 50; + let data_client_config = AptosDataClientConfig { + max_optimistic_fetch_lag_secs, + ..Default::default() + }; + + // Create a mock time service and get the current timestamp + let time_service = TimeService::mock(); + let timestamp_usecs = time_service.now_unix_time().as_micros() as u64; + + // Create a data summary with the specified synced ledger info + let highest_synced_version = 10_000; + let data_summary = DataSummary { + synced_ledger_info: Some(create_ledger_info_at_version_and_timestamp( + highest_synced_version, + timestamp_usecs, + )), + ..Default::default() + }; + + // Elapse the time service by half the max optimistic fetch lag + time_service + .clone() + .into_mock() + .advance_secs(max_optimistic_fetch_lag_secs / 2); + + // Verify that optimistic fetch requests can be serviced + for compression in [true, false] { + let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; + verify_can_service_optimistic_fetch_requests( + use_request_v2, + &data_client_config, + &data_summary, + time_service.clone(), + compression, + known_versions, + true, + ); + } + + // Elapse the time service by the max optimistic fetch lag + time_service + .clone() + .into_mock() + .advance_secs(max_optimistic_fetch_lag_secs); + + // Verify that optimistic fetch requests can no longer be serviced + // (as the max lag has been exceeded for the given data summary). + for compression in [true, false] { + let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; + verify_can_service_optimistic_fetch_requests( + use_request_v2, + &data_client_config, + &data_summary, + time_service.clone(), + compression, + known_versions, + false, + ); + } } } #[test] fn test_data_summary_service_subscription() { - // Create a data client config with the specified max subscription lag - let max_subscription_lag_secs = 100; - let data_client_config = AptosDataClientConfig { - max_subscription_lag_secs, - ..Default::default() - }; - - // Create a mock time service and get the current timestamp - let time_service = TimeService::mock(); - let timestamp_usecs = time_service.now_unix_time().as_micros() as u64; - - // Create a data summary with the specified synced ledger info - let highest_synced_version = 50_000; - let data_summary = DataSummary { - synced_ledger_info: Some(create_ledger_info_at_version_and_timestamp( - highest_synced_version, - timestamp_usecs, - )), - ..Default::default() - }; - - // Elapse the time service by half the max subscription lag - time_service - .clone() - .into_mock() - .advance_secs(max_subscription_lag_secs / 2); - - // Verify that subscription requests can be serviced - for compression in [true, false] { - let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; - verify_can_service_subscription_requests( - &data_client_config, - &data_summary, - time_service.clone(), - compression, - known_versions, - true, - ); - } - - // Elapse the time service by the max subscription lag - time_service - .clone() - .into_mock() - .advance_secs(max_subscription_lag_secs); - - // Verify that subscription requests can no longer be serviced - // (as the max lag has been exceeded for the given data summary). - for compression in [true, false] { - let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; - verify_can_service_subscription_requests( - &data_client_config, - &data_summary, - time_service.clone(), - compression, - known_versions, - false, - ); + // Test both v1 and v2 transaction requests + for use_request_v2 in [false, true] { + // Create a data client config with the specified max subscription lag + let max_subscription_lag_secs = 100; + let data_client_config = AptosDataClientConfig { + max_subscription_lag_secs, + ..Default::default() + }; + + // Create a mock time service and get the current timestamp + let time_service = TimeService::mock(); + let timestamp_usecs = time_service.now_unix_time().as_micros() as u64; + + // Create a data summary with the specified synced ledger info + let highest_synced_version = 50_000; + let data_summary = DataSummary { + synced_ledger_info: Some(create_ledger_info_at_version_and_timestamp( + highest_synced_version, + timestamp_usecs, + )), + ..Default::default() + }; + + // Elapse the time service by half the max subscription lag + time_service + .clone() + .into_mock() + .advance_secs(max_subscription_lag_secs / 2); + + // Verify that subscription requests can be serviced + for compression in [true, false] { + let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; + verify_can_service_subscription_requests( + use_request_v2, + &data_client_config, + &data_summary, + time_service.clone(), + compression, + known_versions, + true, + ); + } + + // Elapse the time service by the max subscription lag + time_service + .clone() + .into_mock() + .advance_secs(max_subscription_lag_secs); + + // Verify that subscription requests can no longer be serviced + // (as the max lag has been exceeded for the given data summary). + for compression in [true, false] { + let known_versions = vec![0, 1, highest_synced_version, highest_synced_version * 2]; + verify_can_service_subscription_requests( + use_request_v2, + &data_client_config, + &data_summary, + time_service.clone(), + compression, + known_versions, + false, + ); + } } } #[test] fn test_data_summary_service_transactions() { - // Create a data client config and data summary - let data_client_config = AptosDataClientConfig::default(); - let data_summary = DataSummary { - synced_ledger_info: Some(create_ledger_info_at_version(250)), - transactions: Some(create_data_range(100, 200)), - ..Default::default() - }; - - // Verify the different requests that can be serviced - for compression in [true, false] { - // Test the valid data ranges and proofs - let valid_ranges_and_proofs = vec![ - (100, 200, 225), - (125, 175, 225), - (100, 100, 225), - (150, 150, 225), - (200, 200, 225), - (200, 200, 250), - ]; - verify_can_service_transaction_requests( - &data_client_config, - &data_summary, - compression, - valid_ranges_and_proofs, - true, - ); - - // Test the missing data ranges and proofs - let missing_data_ranges = vec![ - (99, 200, 225), - (100, 201, 225), - (50, 250, 225), - (50, 150, 225), - (150, 250, 225), - ]; - verify_can_service_transaction_requests( - &data_client_config, - &data_summary, - compression, - missing_data_ranges, - false, - ); - - // Test the invalid data ranges and proofs - let invalid_proof_versions = vec![ - (100, 200, 300), - (125, 175, 300), - (100, 100, 300), - (150, 150, 300), - (200, 200, 300), - (200, 200, 251), - ]; - verify_can_service_transaction_requests( - &data_client_config, - &data_summary, - compression, - invalid_proof_versions, - false, - ); + // Test both v1 and v2 transaction requests + for use_request_v2 in [false, true] { + // Create a data client config and data summary + let data_client_config = AptosDataClientConfig::default(); + let data_summary = DataSummary { + synced_ledger_info: Some(create_ledger_info_at_version(250)), + transactions: Some(create_data_range(100, 200)), + ..Default::default() + }; + + // Verify the different requests that can be serviced + for compression in [true, false] { + // Test the valid data ranges and proofs + let valid_ranges_and_proofs = vec![ + (100, 200, 225), + (125, 175, 225), + (100, 100, 225), + (150, 150, 225), + (200, 200, 225), + (200, 200, 250), + ]; + verify_can_service_transaction_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + valid_ranges_and_proofs, + true, + ); + + // Test the missing data ranges and proofs + let missing_data_ranges = vec![ + (99, 200, 225), + (100, 201, 225), + (50, 250, 225), + (50, 150, 225), + (150, 250, 225), + ]; + verify_can_service_transaction_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + missing_data_ranges, + false, + ); + + // Test the invalid data ranges and proofs + let invalid_proof_versions = vec![ + (100, 200, 300), + (125, 175, 300), + (100, 100, 300), + (150, 150, 300), + (200, 200, 300), + (200, 200, 251), + ]; + verify_can_service_transaction_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + invalid_proof_versions, + false, + ); + } } } #[test] fn test_data_summary_service_transaction_outputs() { - // Create a data client config and data summary - let data_client_config = AptosDataClientConfig::default(); - let data_summary = DataSummary { - synced_ledger_info: Some(create_ledger_info_at_version(250)), - transaction_outputs: Some(create_data_range(100, 200)), - ..Default::default() - }; - - // Verify the different requests that can be serviced - for compression in [true, false] { - // Test the valid data ranges and proofs - let valid_ranges_and_proofs = vec![ - (100, 200, 225), - (125, 175, 225), - (100, 100, 225), - (150, 150, 225), - (200, 200, 225), - (200, 200, 250), - ]; - verify_can_service_output_requests( - &data_client_config, - &data_summary, - compression, - valid_ranges_and_proofs, - true, - ); - - // Test the missing data ranges and proofs - let missing_data_ranges = vec![ - (99, 200, 225), - (100, 201, 225), - (50, 250, 225), - (50, 150, 225), - (150, 250, 225), - ]; - verify_can_service_output_requests( - &data_client_config, - &data_summary, - compression, - missing_data_ranges, - false, - ); - - // Test the valid data ranges and invalid proofs - let invalid_proof_versions = vec![ - (100, 200, 300), - (125, 175, 300), - (100, 100, 300), - (150, 150, 300), - (200, 200, 300), - (200, 200, 251), - ]; - verify_can_service_output_requests( - &data_client_config, - &data_summary, - compression, - invalid_proof_versions, - false, - ); - - // Test the invalid data ranges and proofs - let invalid_ranges = vec![(175, 125, 225), (201, 200, 201), (202, 200, 200)]; - verify_can_service_output_requests( - &data_client_config, - &data_summary, - compression, - invalid_ranges, - false, - ); + // Test both v1 and v2 transaction requests + for use_request_v2 in [false, true] { + // Create a data client config and data summary + let data_client_config = AptosDataClientConfig::default(); + let data_summary = DataSummary { + synced_ledger_info: Some(create_ledger_info_at_version(250)), + transaction_outputs: Some(create_data_range(100, 200)), + ..Default::default() + }; + + // Verify the different requests that can be serviced + for compression in [true, false] { + // Test the valid data ranges and proofs + let valid_ranges_and_proofs = vec![ + (100, 200, 225), + (125, 175, 225), + (100, 100, 225), + (150, 150, 225), + (200, 200, 225), + (200, 200, 250), + ]; + verify_can_service_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + valid_ranges_and_proofs, + true, + ); + + // Test the missing data ranges and proofs + let missing_data_ranges = vec![ + (99, 200, 225), + (100, 201, 225), + (50, 250, 225), + (50, 150, 225), + (150, 250, 225), + ]; + verify_can_service_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + missing_data_ranges, + false, + ); + + // Test the valid data ranges and invalid proofs + let invalid_proof_versions = vec![ + (100, 200, 300), + (125, 175, 300), + (100, 100, 300), + (150, 150, 300), + (200, 200, 300), + (200, 200, 251), + ]; + verify_can_service_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + invalid_proof_versions, + false, + ); + + // Test the invalid data ranges and proofs + let invalid_ranges = vec![(175, 125, 225), (201, 200, 201), (202, 200, 200)]; + verify_can_service_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + invalid_ranges, + false, + ); + } } } #[test] fn test_data_summary_service_transactions_or_outputs() { - // Create a data client config and data summary - let data_client_config = AptosDataClientConfig::default(); - let data_summary = DataSummary { - synced_ledger_info: Some(create_ledger_info_at_version(250)), - transactions: Some(create_data_range(50, 200)), - transaction_outputs: Some(create_data_range(100, 250)), - ..Default::default() - }; - - // Verify the different requests that can be serviced - for compression in [true, false] { - // Test the valid data ranges and proofs - let valid_ranges_and_proofs = vec![ - (100, 200, 225), - (125, 175, 225), - (100, 100, 225), - (150, 150, 225), - (200, 200, 225), - (200, 200, 250), - ]; - verify_can_service_transaction_or_output_requests( - &data_client_config, - &data_summary, - compression, - valid_ranges_and_proofs, - true, - ); - - // Test the missing output ranges and proofs - let missing_output_ranges = vec![(51, 200, 225), (99, 100, 225), (51, 71, 225)]; - verify_can_service_transaction_or_output_requests( - &data_client_config, - &data_summary, - compression, - missing_output_ranges, - false, - ); - - // Test the missing transaction ranges and proofs - let missing_transaction_ranges = vec![(200, 202, 225), (150, 201, 225), (201, 225, 225)]; - verify_can_service_transaction_or_output_requests( - &data_client_config, - &data_summary, - compression, - missing_transaction_ranges, - false, - ); - - // Test the valid data ranges and invalid proofs - let invalid_proof_versions = vec![ - (100, 200, 300), - (125, 175, 300), - (100, 100, 300), - (150, 150, 300), - (200, 200, 300), - (200, 200, 251), - ]; - verify_can_service_transaction_or_output_requests( - &data_client_config, - &data_summary, - compression, - invalid_proof_versions, - false, - ); - - // Test the invalid data ranges and proofs - let invalid_ranges = vec![(175, 125, 225), (201, 200, 201), (202, 200, 200)]; - verify_can_service_transaction_or_output_requests( - &data_client_config, - &data_summary, - compression, - invalid_ranges, - false, - ); + // Test both v1 and v2 transaction requests + for use_request_v2 in [false, true] { + // Create a data client config and data summary + let data_client_config = AptosDataClientConfig::default(); + let data_summary = DataSummary { + synced_ledger_info: Some(create_ledger_info_at_version(250)), + transactions: Some(create_data_range(50, 200)), + transaction_outputs: Some(create_data_range(100, 250)), + ..Default::default() + }; + + // Verify the different requests that can be serviced + for compression in [true, false] { + // Test the valid data ranges and proofs + let valid_ranges_and_proofs = vec![ + (100, 200, 225), + (125, 175, 225), + (100, 100, 225), + (150, 150, 225), + (200, 200, 225), + (200, 200, 250), + ]; + verify_can_service_transaction_or_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + valid_ranges_and_proofs, + true, + ); + + // Test the missing output ranges and proofs + let missing_output_ranges = vec![(51, 200, 225), (99, 100, 225), (51, 71, 225)]; + verify_can_service_transaction_or_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + missing_output_ranges, + false, + ); + + // Test the missing transaction ranges and proofs + let missing_transaction_ranges = + vec![(200, 202, 225), (150, 201, 225), (201, 225, 225)]; + verify_can_service_transaction_or_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + missing_transaction_ranges, + false, + ); + + // Test the valid data ranges and invalid proofs + let invalid_proof_versions = vec![ + (100, 200, 300), + (125, 175, 300), + (100, 100, 300), + (150, 150, 300), + (200, 200, 300), + (200, 200, 251), + ]; + verify_can_service_transaction_or_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + invalid_proof_versions, + false, + ); + + // Test the invalid data ranges and proofs + let invalid_ranges = vec![(175, 125, 225), (201, 200, 201), (202, 200, 200)]; + verify_can_service_transaction_or_output_requests( + use_request_v2, + &data_client_config, + &data_summary, + compression, + invalid_ranges, + false, + ); + } } } #[test] -fn test_data_summary_can_service_state_chunk_request() { +fn test_data_summary_service_state_chunk_request() { // Create a data client config and data summary let data_client_config = AptosDataClientConfig::default(); let data_summary = DataSummary { @@ -492,6 +524,39 @@ fn test_protocol_metadata_service() { } } +#[test] +fn test_is_transaction_data_v2_request() { + // Create transaction data v1 requests + let transactions_request = create_transactions_request(200, 100, 101, false); + let outputs_request = create_outputs_request(200, 100, 101, false); + let transactions_or_outputs_request = + create_transactions_or_outputs_request(200, 100, 101, false); + + // Verify that none of them are v2 requests + for request in [ + transactions_request, + outputs_request, + transactions_or_outputs_request, + ] { + assert!(!request.data_request.is_transaction_data_v2_request()); + } + + // Create transaction data v2 requests + let transactions_request_v2 = create_transactions_request_v2(200, 100, 101, false); + let outputs_request_v2 = create_outputs_request_v2(200, 100, 101, false); + let transactions_or_outputs_request_v2 = + create_transactions_or_outputs_request_v2(200, 100, 101, false); + + // Verify that all of them are v2 requests + for request in [ + transactions_request_v2, + outputs_request_v2, + transactions_or_outputs_request_v2, + ] { + assert!(request.data_request.is_transaction_data_v2_request()); + } +} + proptest! { #![proptest_config(ProptestConfig::with_cases(1000))] @@ -579,6 +644,39 @@ fn create_optimistic_fetch_request( StorageServiceRequest::new(data_request, use_compression) } +/// Creates a new optimistic request (v2) +fn create_optimistic_fetch_request_v2( + known_version: u64, + use_compression: bool, +) -> StorageServiceRequest { + // Generate a random number + let random_number = get_random_u64(); + + // Determine the data request type based on the random number + let data_request = if random_number % 3 == 0 { + DataRequest::get_new_transaction_data_with_proof( + known_version, + get_random_u64(), + false, + get_random_u64(), + ) + } else if random_number % 3 == 1 { + DataRequest::get_new_transaction_output_data_with_proof( + known_version, + get_random_u64(), + get_random_u64(), + ) + } else { + DataRequest::get_new_transaction_or_output_data_with_proof( + known_version, + get_random_u64(), + false, + get_random_u64(), + ) + }; + StorageServiceRequest::new(data_request, use_compression) +} + /// Creates a request for transaction outputs fn create_outputs_request( proof_version: Version, @@ -595,6 +693,22 @@ fn create_outputs_request( StorageServiceRequest::new(data_request, use_compression) } +/// Creates a request for transaction outputs (v2) +fn create_outputs_request_v2( + proof_version: Version, + start_version: Version, + end_version: Version, + use_compression: bool, +) -> StorageServiceRequest { + let data_request = DataRequest::get_transaction_output_data_with_proof( + proof_version, + start_version, + end_version, + get_random_u64(), + ); + StorageServiceRequest::new(data_request, use_compression) +} + /// Creates a new subscription request fn create_subscription_request(known_version: u64, use_compression: bool) -> StorageServiceRequest { // Create a new subscription stream metadata @@ -634,40 +748,114 @@ fn create_subscription_request(known_version: u64, use_compression: bool) -> Sto StorageServiceRequest::new(data_request, use_compression) } +/// Creates a new subscription request (v2) +fn create_subscription_request_v2( + known_version: u64, + use_compression: bool, +) -> StorageServiceRequest { + // Create a new subscription stream metadata + let subscription_stream_metadata = SubscriptionStreamMetadata { + known_version_at_stream_start: known_version, + known_epoch_at_stream_start: get_random_u64(), + subscription_stream_id: get_random_u64(), + }; + + // Generate a random number + let random_number = get_random_u64(); + + // Determine the data request type based on the random number + let data_request = if random_number % 3 == 0 { + DataRequest::subscribe_transaction_data_with_proof( + subscription_stream_metadata, + get_random_u64(), + false, + get_random_u64(), + ) + } else if random_number % 3 == 1 { + DataRequest::subscribe_transaction_output_data_with_proof( + subscription_stream_metadata, + get_random_u64(), + get_random_u64(), + ) + } else { + DataRequest::subscribe_transaction_or_output_data_with_proof( + subscription_stream_metadata, + get_random_u64(), + false, + get_random_u64(), + ) + }; + StorageServiceRequest::new(data_request, use_compression) +} + /// Creates a request for transactions fn create_transactions_request( - proof: Version, - start: Version, - end: Version, + proof_version: Version, + start_version: Version, + end_version: Version, use_compression: bool, ) -> StorageServiceRequest { let data_request = DataRequest::GetTransactionsWithProof(TransactionsWithProofRequest { - proof_version: proof, - start_version: start, - end_version: end, + proof_version, + start_version, + end_version, include_events: true, }); StorageServiceRequest::new(data_request, use_compression) } +/// Creates a request for transactions (v2) +fn create_transactions_request_v2( + proof_version: Version, + start_version: Version, + end_version: Version, + use_compression: bool, +) -> StorageServiceRequest { + let data_request = DataRequest::get_transaction_data_with_proof( + proof_version, + start_version, + end_version, + true, + get_random_u64(), + ); + StorageServiceRequest::new(data_request, use_compression) +} + /// Creates a request for transactions or outputs fn create_transactions_or_outputs_request( - proof: Version, - start: Version, - end: Version, + proof_version: Version, + start_version: Version, + end_version: Version, use_compression: bool, ) -> StorageServiceRequest { let data_request = DataRequest::GetTransactionsOrOutputsWithProof(TransactionsOrOutputsWithProofRequest { - proof_version: proof, - start_version: start, - end_version: end, + proof_version, + start_version, + end_version, include_events: true, max_num_output_reductions: 3, }); StorageServiceRequest::new(data_request, use_compression) } +/// Creates a request for transactions or outputs (v2) +fn create_transactions_or_outputs_request_v2( + proof_version: Version, + start_version: Version, + end_version: Version, + use_compression: bool, +) -> StorageServiceRequest { + let data_request = DataRequest::get_transaction_or_output_data_with_proof( + proof_version, + start_version, + end_version, + false, + get_random_u64(), + ); + StorageServiceRequest::new(data_request, use_compression) +} + /// Creates a request for state values fn create_state_values_request( version: Version, @@ -693,7 +881,7 @@ fn create_state_values_request_at_version( /// Generates a random u64 fn get_random_u64() -> u64 { - thread_rng().gen() + thread_rng().r#gen() } /// Verifies the serviceability of the epoch ending request ranges against @@ -725,6 +913,7 @@ fn verify_can_service_epoch_ending_requests( /// the specified data summary. If `expect_service` is true, then the /// request should be serviceable. fn verify_can_service_optimistic_fetch_requests( + use_request_v2: bool, data_client_config: &AptosDataClientConfig, data_summary: &DataSummary, time_service: TimeService, @@ -734,7 +923,11 @@ fn verify_can_service_optimistic_fetch_requests( ) { for known_version in known_versions { // Create the optimistic fetch request - let request = create_optimistic_fetch_request(known_version, compression); + let request = if use_request_v2 { + create_optimistic_fetch_request_v2(known_version, compression) + } else { + create_optimistic_fetch_request(known_version, compression) + }; // Verify the serviceability of the request verify_serviceability( @@ -776,6 +969,7 @@ fn verify_can_service_state_chunk_requests( /// the specified data summary. If `expect_service` is true, then the /// request should be serviceable. fn verify_can_service_subscription_requests( + use_request_v2: bool, data_client_config: &AptosDataClientConfig, data_summary: &DataSummary, time_service: TimeService, @@ -785,7 +979,11 @@ fn verify_can_service_subscription_requests( ) { for known_version in known_versions { // Create the subscription request - let request = create_subscription_request(known_version, compression); + let request = if use_request_v2 { + create_subscription_request_v2(known_version, compression) + } else { + create_subscription_request(known_version, compression) + }; // Verify the serviceability of the request verify_serviceability( @@ -802,6 +1000,7 @@ fn verify_can_service_subscription_requests( /// the specified data summary. If `expect_service` is true, then the /// request should be serviceable. fn verify_can_service_transaction_requests( + use_request_v2: bool, data_client_config: &AptosDataClientConfig, data_summary: &DataSummary, use_compression: bool, @@ -810,8 +1009,16 @@ fn verify_can_service_transaction_requests( ) { for (start_version, end_version, proof_version) in transaction_ranges { // Create the transaction request - let request = - create_transactions_request(proof_version, start_version, end_version, use_compression); + let request = if use_request_v2 { + create_transactions_request_v2( + proof_version, + start_version, + end_version, + use_compression, + ) + } else { + create_transactions_request(proof_version, start_version, end_version, use_compression) + }; // Verify the serviceability of the request verify_serviceability( @@ -828,6 +1035,7 @@ fn verify_can_service_transaction_requests( /// ranges against the specified data summary. If `expect_service` is /// true, then the request should be serviceable. fn verify_can_service_transaction_or_output_requests( + use_request_v2: bool, data_client_config: &AptosDataClientConfig, data_summary: &DataSummary, use_compression: bool, @@ -836,12 +1044,21 @@ fn verify_can_service_transaction_or_output_requests( ) { for (start_version, end_version, proof_version) in transaction_ranges { // Create the transaction or output request - let request = create_transactions_or_outputs_request( - proof_version, - start_version, - end_version, - use_compression, - ); + let request = if use_request_v2 { + create_transactions_or_outputs_request_v2( + proof_version, + start_version, + end_version, + use_compression, + ) + } else { + create_transactions_or_outputs_request( + proof_version, + start_version, + end_version, + use_compression, + ) + }; // Verify the serviceability of the request verify_serviceability( @@ -858,6 +1075,7 @@ fn verify_can_service_transaction_or_output_requests( /// the specified data summary. If `expect_service` is true, then the /// request should be serviceable. fn verify_can_service_output_requests( + use_request_v2: bool, data_client_config: &AptosDataClientConfig, data_summary: &DataSummary, use_compression: bool, @@ -866,8 +1084,11 @@ fn verify_can_service_output_requests( ) { for (start_version, end_version, proof_version) in output_ranges { // Create the output request - let request = - create_outputs_request(proof_version, start_version, end_version, use_compression); + let request = if use_request_v2 { + create_outputs_request_v2(proof_version, start_version, end_version, use_compression) + } else { + create_outputs_request(proof_version, start_version, end_version, use_compression) + }; // Verify the serviceability of the request verify_serviceability( diff --git a/storage/README.md b/storage/README.md index 4f4227c852e..162ce6d61af 100644 --- a/storage/README.md +++ b/storage/README.md @@ -188,7 +188,7 @@ https://github.com/aptos-labs/aptos-core/blob/main/state-sync/README.md ### Continuously backing up to a cloud storage -The backup coordinator runs continously, talks to the backup service embedded +The backup coordinator runs continuously, talks to the backup service embedded inside a Aptos Node and writes backup data automatically to a configured cloud storage. diff --git a/storage/aptosdb/proptest-regressions/db/aptosdb_test.txt b/storage/aptosdb/proptest-regressions/db/aptosdb_test.txt new file mode 100644 index 00000000000..533c7eda94e --- /dev/null +++ b/storage/aptosdb/proptest-regressions/db/aptosdb_test.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 4af782d32b6a58f397dda7bc59fc7c3e533173e8d36623dc4cfd8f46d00a35aa # shrinks to input = [([TransactionToCommit { transaction: UserTransaction(SignedTransaction { { raw_txn: RawTransaction { sender: 2f92fe53934cb8ecfb4f4c4acabb2723f34d5ab94df9c9b7c39eb0dbec7e21b9, sequence_number: 0, payload: Payload( V1 { executable: EntryFunction( EntryFunction { module: ModuleId { address: 1d3f1fe124d32c33cd4d4f77da09d8d6b4594c5ab559c5d84bf486e038e750ed, name: Identifier( "module", ), }, function: Identifier( "function", ), ty_args: [ Bool, Struct( StructTag { address: f16e445621cfbe3f72a82504284b10dd8c11a7b965fd0baa047142c683f6a5f3, module: Identifier( "abLc_rpySCGBJprO_1H6t_Z_8_A_", ), name: Identifier( "_K44VcI__0sr52_uPz_3pZa2xz", ), type_args: [], }, ), ], args: [ [ 184, 195, 136, 154, 138, 217, 125, 5, 48, 127, 152, 184, ], [ 68, 169, 133, 73, 234, 120, 1, 176, 11, 7, 111, 219, 236, 94, 227, 0, 242, 38, 245, 153, 194, 34, 103, 193, 87, 15, 243, 10, 249, 1, 56, 183, 218, 54, 66, 61, 37, 52, 247, 218, 1, 243, 86, 51, 207, 198, 4, 240, 34, 8, 98, 154, 10, 143, 116, 255, 97, 157, 12, 167, 214, 192, 98, 217, 2, 40, 25, 231, 15, 45, 197, 230, 233, ], ], }, ), extra_config: V1 { multisig_address: Some( cf3ba1bb21ec2f7ae9cb83f8672cffd0d4d84b551d27d9be0433eeb869bd7c8f, ), replay_protection_nonce: None, }, }, ), max_gas_amount: 3529336661713764497, gas_unit_price: 2705230699640603746, expiration_timestamp_secs: 7366863827941788601, chain_id: testing, }, authenticator: Ed25519 { public_key: Ed25519PublicKey(873a034664cf4853c3420d8450a790dd0df52264f52f48ea79969f1cec34f1e4), signature: Ed25519Signature(28beb55209b40ceae1b22193f18fe962130ec5b7ebeae18cf4fe4ba7a9e5da9234210651a413f390760d5868e3ed154111614c5852c0e97a41d010241641910f), }, } }), transaction_info: V0(TransactionInfoV0 { gas_used: 17022163878903957628, status: Success, transaction_hash: HashValue(3538189984d0ea2b858f7c9e71ce7f863bf9d1d7ee83d408cab9af6a95203649), event_root_hash: HashValue(4e811f419ba883fe0e9eb408952969307881494ff5f4f702289d80c3c080dc0c), state_change_hash: HashValue(eca2e3b1d552ab4c5cb6b958db9105d104e703075916a918d5a0e4333990371a), state_checkpoint_hash: None, auxiliary_info_hash: Some(HashValue(2110f2ab9257012d59345cf91a8446e970bc91b93444aefc643f55f3867552f9)) }), write_set: WriteSet { value: V0(WriteSetV0(WriteSetMut { write_set: {StateKey::AccessPath { address: 0x2f92fe53934cb8ecfb4f4c4acabb2723f34d5ab94df9c9b7c39eb0dbec7e21b9, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }: Modification(25d563b5c3026351000000000000000000a1e72d4e82a80868cde18fe1a5a4113abd0b695a98ac60783d48df4a29402b0fc1e6601174f6020600000000000000009b06e6f40987a62083deb366cd508c26e46a1997c03165bb088b4f5c777e7496e71d299d7bfba5d4, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0x2f92fe53934cb8ecfb4f4c4acabb2723f34d5ab94df9c9b7c39eb0dbec7e21b9, path: "Resource(0x1::account::Account)" }: Modification(20873a034664cf4853c3420d8450a790dd0df52264f52f48ea79969f1cec34f1e4010000000000000000000000000000000000000000000000fa4d59fb21535da5dbc2e181ee80ee6cfcaa0b964f044c46c0520b0a67c810c8db18d79fbf9e4fb90100000000000000f15765ee8622294b02d972c82895d237fa0c9abe7fb1de55bbb5a93ca4537d0a7743312325528b290000, metadata:StateValueMetadata { inner: None })} })), hotness: {} }, events: [ModuleEvent { type: U128, event_data: "ee0f8dad31" }], is_reconfig: false, transaction_auxiliary_data: None }, TransactionToCommit { transaction: UserTransaction(SignedTransaction { { raw_txn: RawTransaction { sender: 7e2e9b4cf58f69941af9058f1973b1fbce9307f8652c720f06f1f2298ea51218, sequence_number: 0, payload: EntryFunction( EntryFunction { module: ModuleId { address: 3cc76d76b9c15d4abaa5a6e05484448bfe088b238fead119df17d00d86809346, name: Identifier( "module", ), }, function: Identifier( "function", ), ty_args: [ Struct( StructTag { address: 9c3161c77a4eda07fadead7ab706690409c8d1be3c09e305b7eb395b209f88ef, module: Identifier( "_A_iJEhaa6Im4KDt_JT_l", ), name: Identifier( "w", ), type_args: [ Struct( StructTag { address: ab0d6bfc7e5a0d7c3f08301dbd8124e4bef34e9c665a0b897199c9ece5f82cca, module: Identifier( "_e7p6_Bg", ), name: Identifier( "xJK_bj_k_TwswOQFG", ), type_args: [], }, ), U16, Bool, ], }, ), Struct( StructTag { address: 5ea31cda6e84c6abee686ee600d1010a0a5da03adf211675a06260db7fe83c49, module: Identifier( "W8of7JLSz__c0g4F_aL3", ), name: Identifier( "_7_r_6js4_VEp8GB2CoWB_tc_n8", ), type_args: [], }, ), Struct( StructTag { address: 27be60a44c37148bcbfed91a7dac734a0ac41d0a28b9d02e5eefb8d206509089, module: Identifier( "Xc2vFOz3M0Xm_CO_9OiC___x", ), name: Identifier( "T", ), type_args: [ Struct( StructTag { address: bcf26c1ee0fb3f46f8b4c971bf2b105476813562e69932dee47db2602c4352c7, module: Identifier( "_ECw_BojS9p_q_KPzQp", ), name: Identifier( "__F_rmiBw0g_", ), type_args: [ Address, ], }, ), Address, Struct( StructTag { address: f921374139d347727c232059f3d0ec7159cf631f699542c8dc17d7ef374bff5c, module: Identifier( "__4ZpKQja_vQb18hkX9d_5", ), name: Identifier( "_D__3MwIyIJ_5kLXF", ), type_args: [ Address, ], }, ), ], }, ), ], args: [ [ 189, 242, 21, 158, 62, 88, 73, 161, 95, 100, 211, 147, 128, 163, 225, 164, 110, 75, 129, 243, 8, 58, 214, 55, 129, 81, 169, 185, 180, 203, 191, 173, 17, 2, 215, 231, 128, 14, 23, 21, 146, 70, 178, 89, 107, 37, 120, 52, 111, 137, 101, 190, 235, 150, ], ], }, ), max_gas_amount: 16468724479510503138, gas_unit_price: 15535327671788253985, expiration_timestamp_secs: 9178933541833259155, chain_id: testing, }, authenticator: Ed25519 { public_key: Ed25519PublicKey(c429ae9435cc01e3352c5e305b6b2cd3d3babbbcc179280bfe9752752ec56834), signature: Ed25519Signature(8a026eb0a0f86853e0934fd207c5cd1c9fac04498d16b87ae7e13c867bd495592b03d14c70cd4942a7648df9cf3ddcc95ac6389c21c5690648be5a8dbd24630f), }, } }), transaction_info: V0(TransactionInfoV0 { gas_used: 10837505644634402020, status: ExecutionFailure { location: c7741a762abb7647bf70b04e91a21e3d2f5f4a54048a568ede01a977039b8ec9::__egoD_n1SHt_1ad_N8BBSF, function: 44169, code_offset: 58563 }, transaction_hash: HashValue(b4a85541e81abb08717e0173982153b51f29e9c5438ce4446832dab8aa21c5db), event_root_hash: HashValue(e801f393c862c01f2ffcf8d862d95f0621489d344f6586b996188ba2ea194c36), state_change_hash: HashValue(f334888145453a364d66fee54e63c79f2ae4e86394dc1489ae870f80627e504e), state_checkpoint_hash: None, auxiliary_info_hash: Some(HashValue(7c041697a0e96e1e242c8d02c544cf4249a84735a8e068241562598e9150f305)) }), write_set: WriteSet { value: V0(WriteSetV0(WriteSetMut { write_set: {StateKey::AccessPath { address: 0x7e2e9b4cf58f69941af9058f1973b1fbce9307f8652c720f06f1f2298ea51218, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }: Modification(1fcb48f550d9c55700000000000000000080e258a3eb58aaeb859b246cdf22aaebf4c41476314fd1a7cd16d38ee49bab0e5a3db06e0722f33e00000000000000004f7dbd34c5c16a8674485d8cb0f31e1181d86b08d2dd9c8226ab95e3629ae6e6705c74e5e5470bcb, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0x7e2e9b4cf58f69941af9058f1973b1fbce9307f8652c720f06f1f2298ea51218, path: "Resource(0x1::account::Account)" }: Modification(20c429ae9435cc01e3352c5e305b6b2cd3d3babbbcc179280bfe9752752ec568340100000000000000000000000000000000000000000000003cfd4e34e53a926f36a82c287eda21bf9cf4a384f412f5c320fc0558912250694f2a1926c4e529e401000000000000005af492800d007dafabbc0ff9f89d86d0503dd60b3aa210874527cdec7b8647b61fdd67f402c3a7f10000, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0xb8d6ccfd7604b725ce7a65127942c13d86de7aa2f6cf653e3642742bb2e81d5b, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }: Modification(b79d46ce5b7dcb2500000000000000000086d6df5072fdab01bb87bfa156d4b2bb89d51277a16d977faff4ded59c169fa3742c3e8d2288d5ac0000000000000000ad4cb30e2e24405304dd32d1d26dd954c7da396fba7c685ad3532f66bc348cb9df304c0d67f5d59e, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0xb8d6ccfd7604b725ce7a65127942c13d86de7aa2f6cf653e3642742bb2e81d5b, path: "Resource(0x1::account::Account)" }: Modification(20ca7eb9502fa61e27221b8a9e214cfaa733afd73691ae365e3000a8089bbdffb8000000000000000000000000000000000000000000000000747d4e4ee2972a8b48aa4316b420e53beba7102de1c1e5a4dc7ea178534e6b9f56620b5e69f2f59c0100000000000000afc0724f2c94485c2a12f9a546902838b8c58bc294bdb4492e8861fed1150a27cd516e1364bb51170000, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0xbcfccd10ccc325f22f34d0eb36f2973738eda35d1a16f40b28250dabf96452c4, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }: Modification(1e87027e689dfa2c000000000000000000607471d9fe2e0091257cae78d75e78fb8665bd3c8af38f097122d0cd375c45f4a3cb92eee1ed012d00000000000000007c4c763f2382e1972a57c72c24c7c9e7ef6a82630497fa35598b69739a5bd00641083e040d2aaba1, metadata:StateValueMetadata { inner: None }), StateKey::AccessPath { address: 0xbcfccd10ccc325f22f34d0eb36f2973738eda35d1a16f40b28250dabf96452c4, path: "Resource(0x1::account::Account)" }: Modification(2054b0922d881d48bacea587010bbafb960bf93b83331a13805641fdb5176d3b7b000000000000000000000000000000000000000000000000513acb1555fe55bc399886ccaab9e8bb5ed30e7ac5ab12c36e2a2b61a6751b5751a7657ab2666242010000000000000067109082191ac136725a87cbe9e9f1986e2b202f2393c4f62459e69d0ee6878371e5228023a887170000, metadata:StateValueMetadata { inner: None })} })), hotness: {} }, events: [ModuleEvent { type: Struct(StructTag { address: 67a8158877295e53f85cdb8f3c8ae9b2ef84605a7573402d87a0045f7a294f34, module: Identifier("cGc_O2S8__7a1x_tqb4f"), name: Identifier("_R_E_RdLD__lf9S4RR9K0_v__bh_9VVS"), type_args: [U256, Address, Struct(StructTag { address: a5a6a87ccc72d9d1a09055273054b7065d51c03ba45ec4420a6ab166e4b503e8, module: Identifier("dG9u79tc5b_L9iq_L_8HBlq3_X_RYesy"), name: Identifier("C5aEoqICKu"), type_args: [U64, U256, U32] })] }), event_data: "4cc03333a9e017e66c4964f5f8caa8480b52c146f9a6837fc4f347f93e4c4b6058f2a991bf4eabf8e128561504fc8749d08e151f069919fcc4e0563d0c924e44e518c9e81247699c1524ff84" }, ModuleEvent { type: Struct(StructTag { address: caf0dc808c605cdbcda8bf2e3a6ffed30e3a34e6b2c2b8db4c28fac8bb99c20b, module: Identifier("_lW_nOJ_mEbHW0Dnxdwu_QQ9___MEVVSW"), name: Identifier("_MSoDw5Evya6x_8LU_SriI1_RfI_"), type_args: [Struct(StructTag { address: 717bfafc7b522f41e4a62f77423342aa5afdc4213a13c017265718edfa29a987, module: Identifier("O_9418v_"), name: Identifier("WiY_b_p"), type_args: [] })] }), event_data: "" }], is_reconfig: false, transaction_auxiliary_data: None }, TransactionToCommit { transaction: StateCheckpoint(HashValue(5e79d94a9fc9118e35d982137244889e2d1d30715dd9b1b2f709de94bcae9722)), transaction_info: V0(TransactionInfoV0 { gas_used: 0, status: Success, transaction_hash: HashValue(eff5ad4b0051706aa883a91e1a7d22aea04a5e5661a8775c0f200b077d6b6188), event_root_hash: HashValue(9f8137f006f3f8f58e2f01e14bab3993e0083b08db15a27a79e871bbf344e7d5), state_change_hash: HashValue(afb6e14fe47d850fd0a7395bcfb997ffacf4715e0f895cc162c218e4a7564bc6), state_checkpoint_hash: Some(HashValue(7db257ec92b2aae6fe3799e36307db51d9f2b6f9b418f170689eff206cc4e3c9)), auxiliary_info_hash: Some(HashValue(6118666a97cf40e70dca33a5fe8b37ff5e23fab46bd52b67e0a36791a151e836)) }), write_set: WriteSet { value: V0(WriteSetV0(WriteSetMut { write_set: {} })), hotness: {} }, events: [ModuleEvent { type: Struct(StructTag { address: 0000000000000000000000000000000000000000000000000000000000000001, module: Identifier("reconfiguration"), name: Identifier("NewEpoch"), type_args: [] }), event_data: "0000000000000000" }], is_reconfig: true, transaction_auxiliary_data: None }], V0(LedgerInfoWithV0 { ledger_info: LedgerInfo { commit_info: BlockInfo { epoch: 0, round: 0, id: HashValue(045d6138fc24f737ede555861733396a8af4a7c263969ce53f43dd8ea78b180a), executed_state_id: HashValue(0e8de262432f7b6645816bfc4bcc3ae1fac6a89ab066740efd9635008e0f74db), version: 2, timestamp_usecs: 2453639917954629045, next_epoch_state: Some(EpochState [epoch: 1, validator: ValidatorSet: [b8d6ccfd7604b725ce7a65127942c13d86de7aa2f6cf653e3642742bb2e81d5b: 1, f2417be9ec94b108af46d5579716ce0c8288476ada0e21f73364b72bb9341633: 1, ]]) }, consensus_data_hash: HashValue(a564daa8f63e08cb5ed5566f940107d7ae52fe59b9c0b5aec538b75aa3bc731a) }, signatures: AggregateSignature { validator_bitmask: BitVec { inner: [128] }, sig: Some(937a0a1e763b02b0c000aa3913fd049c2f06d17fe635bf3246bd11a77e1632d385d92f44839c6191a76501f0a9c289f30cd552bb5aadc821d399ce32b42ecf50822495d4493bde788236b1b5fffb9d32270b441895906799d5f68756a6cc804d) } }))], threshold = 14 diff --git a/storage/aptosdb/src/backup/backup_handler.rs b/storage/aptosdb/src/backup/backup_handler.rs index 8a14eea4468..09defe04f6b 100644 --- a/storage/aptosdb/src/backup/backup_handler.rs +++ b/storage/aptosdb/src/backup/backup_handler.rs @@ -17,7 +17,7 @@ use aptos_types::{ ledger_info::LedgerInfoWithSignatures, proof::{SparseMerkleRangeProof, TransactionAccumulatorRangeProof, TransactionInfoWithProof}, state_store::{state_key::StateKey, state_value::StateValue}, - transaction::{Transaction, TransactionInfo, Version}, + transaction::{PersistedAuxiliaryInfo, Transaction, TransactionInfo, Version}, write_set::WriteSet, }; use serde::{Deserialize, Serialize}; @@ -44,7 +44,15 @@ impl BackupHandler { start_version: Version, num_transactions: usize, ) -> Result< - impl Iterator, WriteSet)>> + '_, + impl Iterator< + Item = Result<( + Transaction, + PersistedAuxiliaryInfo, + TransactionInfo, + Vec, + WriteSet, + )>, + > + '_, > { let txn_iter = self .ledger_db @@ -62,6 +70,10 @@ impl BackupHandler { .ledger_db .write_set_db() .get_write_set_iter(start_version, num_transactions)?; + let mut persisted_aux_info_iter = self + .ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info_iter(start_version, num_transactions)?; let zipped = txn_iter.enumerate().map(move |(idx, txn_res)| { let version = start_version + idx as u64; // overflow is impossible since it's check upon txn_iter construction. @@ -85,8 +97,14 @@ impl BackupHandler { version )) })??; + let persisted_aux_info = persisted_aux_info_iter.next().ok_or_else(|| { + AptosDbError::NotFound(format!( + "PersistedAuxiliaryInfo not found when Transaction exists, version {}", + version + )) + })??; BACKUP_TXN_VERSION.set(version as i64); - Ok((txn, txn_info, event_vec, write_set)) + Ok((txn, persisted_aux_info, txn_info, event_vec, write_set)) }); Ok(zipped) } @@ -130,7 +148,7 @@ impl BackupHandler { version: Version, start_idx: usize, limit: usize, - ) -> Result> + Send> { + ) -> Result> + Send + use<>> { let iterator = self .state_store .get_state_key_and_value_iter(version, start_idx)? diff --git a/storage/aptosdb/src/backup/restore_handler.rs b/storage/aptosdb/src/backup/restore_handler.rs index 83768e867b8..34e8cd4beba 100644 --- a/storage/aptosdb/src/backup/restore_handler.rs +++ b/storage/aptosdb/src/backup/restore_handler.rs @@ -17,7 +17,7 @@ use aptos_types::{ ledger_info::LedgerInfoWithSignatures, proof::definition::LeafCount, state_store::{state_key::StateKey, state_value::StateValue}, - transaction::{Transaction, TransactionInfo, Version}, + transaction::{PersistedAuxiliaryInfo, Transaction, TransactionInfo, Version}, write_set::WriteSet, }; use std::sync::Arc; @@ -84,6 +84,7 @@ impl RestoreHandler { &self, first_version: Version, txns: &[Transaction], + persisted_aux_info: &[PersistedAuxiliaryInfo], txn_infos: &[TransactionInfo], events: &[Vec], write_sets: Vec, @@ -93,6 +94,7 @@ impl RestoreHandler { self.ledger_db.clone(), first_version, txns, + persisted_aux_info, txn_infos, events, write_sets, @@ -109,6 +111,7 @@ impl RestoreHandler { &self, first_version: Version, txns: &[Transaction], + persisted_aux_info: &[PersistedAuxiliaryInfo], txn_infos: &[TransactionInfo], events: &[Vec], write_sets: Vec, @@ -118,6 +121,7 @@ impl RestoreHandler { self.ledger_db.clone(), first_version, txns, + persisted_aux_info, txn_infos, events, write_sets, diff --git a/storage/aptosdb/src/backup/restore_utils.rs b/storage/aptosdb/src/backup/restore_utils.rs index a6873bcb521..259e6fd3e15 100644 --- a/storage/aptosdb/src/backup/restore_utils.rs +++ b/storage/aptosdb/src/backup/restore_utils.rs @@ -6,8 +6,10 @@ //! state sync v2. use crate::{ ledger_db::{ - ledger_metadata_db::LedgerMetadataDb, transaction_info_db::TransactionInfoDb, - write_set_db::WriteSetDb, LedgerDb, LedgerDbSchemaBatches, + ledger_metadata_db::LedgerMetadataDb, + persisted_auxiliary_info_db::PersistedAuxiliaryInfoDb, + transaction_info_db::TransactionInfoDb, write_set_db::WriteSetDb, LedgerDb, + LedgerDbSchemaBatches, }, schema::{ db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, @@ -29,7 +31,7 @@ use aptos_types::{ definition::LeafCount, position::{FrozenSubTreeIterator, Position}, }, - transaction::{Transaction, TransactionInfo, Version}, + transaction::{PersistedAuxiliaryInfo, Transaction, TransactionInfo, Version}, write_set::WriteSet, }; use std::sync::Arc; @@ -115,6 +117,7 @@ pub(crate) fn save_transactions( ledger_db: Arc, first_version: Version, txns: &[Transaction], + persisted_aux_info: &[PersistedAuxiliaryInfo], txn_infos: &[TransactionInfo], events: &[Vec], write_sets: Vec, @@ -131,6 +134,7 @@ pub(crate) fn save_transactions( ledger_db, first_version, txns, + persisted_aux_info, txn_infos, events, write_sets.as_ref(), @@ -149,6 +153,7 @@ pub(crate) fn save_transactions( Arc::clone(&ledger_db), first_version, txns, + persisted_aux_info, txn_infos, events, write_sets.as_ref(), @@ -190,6 +195,7 @@ pub(crate) fn save_transactions_impl( ledger_db: Arc, first_version: Version, txns: &[Transaction], + persisted_aux_info: &[PersistedAuxiliaryInfo], txn_infos: &[TransactionInfo], events: &[Vec], write_sets: &[WriteSet], @@ -206,6 +212,14 @@ pub(crate) fn save_transactions_impl( )?; } + for (idx, aux_info) in persisted_aux_info.iter().enumerate() { + PersistedAuxiliaryInfoDb::put_persisted_auxiliary_info( + first_version + idx as Version, + aux_info, + &mut ledger_db_batch.persisted_auxiliary_info_db_batches, + )?; + } + for (idx, txn_info) in txn_infos.iter().enumerate() { TransactionInfoDb::put_transaction_info( first_version + idx as Version, @@ -254,7 +268,7 @@ pub(crate) fn save_transactions_impl( if kv_replay && first_version > 0 && state_store.get_usage(Some(first_version - 1)).is_ok() { let ledger_state = state_store.calculate_state_and_put_updates( - &StateUpdateRefs::index_write_sets(first_version, write_sets, write_sets.len(), None), + &StateUpdateRefs::index_write_sets(first_version, write_sets, write_sets.len(), vec![]), &mut ledger_db_batch.ledger_metadata_db_batches, // used for storing the storage usage state_kv_batches, )?; diff --git a/storage/aptosdb/src/db/include/aptosdb_internal.rs b/storage/aptosdb/src/db/aptosdb_internal.rs similarity index 80% rename from storage/aptosdb/src/db/include/aptosdb_internal.rs rename to storage/aptosdb/src/db/aptosdb_internal.rs index 1ea266d0dec..76f448d59d7 100644 --- a/storage/aptosdb/src/db/include/aptosdb_internal.rs +++ b/storage/aptosdb/src/db/aptosdb_internal.rs @@ -1,9 +1,42 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::metrics::CONCURRENCY_GAUGE; -use aptos_metrics_core::IntGaugeHelper; -use aptos_storage_interface::block_info::BlockInfo; +use crate::{ + db::AptosDB, + event_store::EventStore, + ledger_db::LedgerDb, + metrics::{API_LATENCY_SECONDS, CONCURRENCY_GAUGE}, + pruner::{LedgerPrunerManager, PrunerManager, StateKvPrunerManager, StateMerklePrunerManager}, + rocksdb_property_reporter::RocksdbPropertyReporter, + state_kv_db::StateKvDb, + state_merkle_db::StateMerkleDb, + state_store::StateStore, + transaction_store::TransactionStore, +}; +use aptos_config::config::{ + PrunerConfig, RocksdbConfig, RocksdbConfigs, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG, +}; +use aptos_db_indexer::{db_indexer::InternalIndexerDB, Indexer}; +use aptos_logger::prelude::*; +use aptos_metrics_core::{IntGaugeVecHelper, TimerHelper}; +use aptos_resource_viewer::AptosValueAnnotator; +use aptos_schemadb::{Cache, Env}; +use aptos_storage_interface::{ + block_info::BlockInfo, db_ensure as ensure, db_other_bail as bail, AptosDbError, DbReader, + Order, Result, +}; +use aptos_types::{ + account_config::{new_block_event_key, NewBlockEvent}, + transaction::Version, +}; +use std::{ + cell::Cell, + fmt::{Debug, Formatter}, + iter::Iterator, + path::Path, + sync::Arc, + time::Instant, +}; impl AptosDB { fn new_with_dbs( @@ -70,7 +103,7 @@ impl AptosDB { } } - fn open_internal( + pub(super) fn open_internal( db_paths: &StorageDirPaths, readonly: bool, pruner_config: PrunerConfig, @@ -86,9 +119,20 @@ impl AptosDB { "Do not set prune_window when opening readonly.", ); + let mut env = + Env::new().map_err(|err| AptosDbError::OtherRocksDbError(err.into_string()))?; + env.set_high_priority_background_threads(rocksdb_configs.high_priority_background_threads); + env.set_low_priority_background_threads(rocksdb_configs.low_priority_background_threads); + let block_cache = Cache::new_hyper_clock_cache( + rocksdb_configs.shared_block_cache_size, + /* estimated_entry_charge = */ 0, + ); + let (ledger_db, state_merkle_db, state_kv_db) = Self::open_dbs( db_paths, rocksdb_configs, + Some(&env), + Some(&block_cache), readonly, max_num_nodes_per_lru_cache_shard, )?; @@ -107,15 +151,23 @@ impl AptosDB { if !readonly { if let Some(version) = myself.get_synced_version()? { - myself.ledger_pruner + myself + .ledger_pruner .maybe_set_pruner_target_db_version(version); - myself.state_store + myself + .state_store .state_kv_pruner .maybe_set_pruner_target_db_version(version); } if let Some(version) = myself.get_latest_state_checkpoint_version()? { - myself.state_store.state_merkle_pruner.maybe_set_pruner_target_db_version(version); - myself.state_store.epoch_snapshot_pruner.maybe_set_pruner_target_db_version(version); + myself + .state_store + .state_merkle_pruner + .maybe_set_pruner_target_db_version(version); + myself + .state_store + .epoch_snapshot_pruner + .maybe_set_pruner_target_db_version(version); } } @@ -171,7 +223,7 @@ impl AptosDB { } #[cfg(any(test, feature = "fuzzing", feature = "consensus-only-perf-test"))] - fn new_without_pruner + Clone>( + pub(super) fn new_without_pruner + Clone>( db_root_path: P, readonly: bool, buffered_state_target_items: usize, @@ -195,7 +247,7 @@ impl AptosDB { .expect("Unable to open AptosDB") } - fn error_if_ledger_pruned(&self, data_type: &str, version: Version) -> Result<()> { + pub(super) fn error_if_ledger_pruned(&self, data_type: &str, version: Version) -> Result<()> { let min_readable_version = self.ledger_pruner.get_min_readable_version(); ensure!( version >= min_readable_version, @@ -207,7 +259,11 @@ impl AptosDB { Ok(()) } - fn error_if_state_merkle_pruned(&self, data_type: &str, version: Version) -> Result<()> { + pub(super) fn error_if_state_merkle_pruned( + &self, + data_type: &str, + version: Version, + ) -> Result<()> { let min_readable_version = self .state_store .state_db @@ -235,7 +291,7 @@ impl AptosDB { } } - fn error_if_state_kv_pruned(&self, data_type: &str, version: Version) -> Result<()> { + pub(super) fn error_if_state_kv_pruned(&self, data_type: &str, version: Version) -> Result<()> { let min_readable_version = self.state_store.state_kv_pruner.get_min_readable_version(); ensure!( version >= min_readable_version, @@ -247,7 +303,7 @@ impl AptosDB { Ok(()) } - fn get_raw_block_info_by_height(&self, block_height: u64) -> Result { + pub(super) fn get_raw_block_info_by_height(&self, block_height: u64) -> Result { if !self.skip_index_and_usage { let (first_version, new_block_event) = self.event_store.get_event_by_key( &new_block_event_key(), @@ -270,7 +326,7 @@ impl AptosDB { } } - fn get_raw_block_info_by_version( + pub(super) fn get_raw_block_info_by_version( &self, version: Version, ) -> Result<(u64 /* block_height */, BlockInfo)> { @@ -304,7 +360,7 @@ impl AptosDB { } } - fn to_api_block_info( + pub(super) fn to_api_block_info( &self, block_height: u64, block_info: BlockInfo, @@ -344,7 +400,7 @@ impl Debug for AptosDB { } } -fn error_if_too_many_requested(num_requested: u64, max_allowed: u64) -> Result<()> { +pub(super) fn error_if_too_many_requested(num_requested: u64, max_allowed: u64) -> Result<()> { if num_requested > max_allowed { Err(AptosDbError::TooManyRequested(num_requested, max_allowed)) } else { @@ -356,7 +412,7 @@ thread_local! { static ENTERED_GAUGED_API: Cell = const { Cell::new(false) }; } -fn gauged_api(api_name: &'static str, api_impl: F) -> Result +pub(super) fn gauged_api(api_name: &'static str, api_impl: F) -> Result where F: FnOnce() -> Result, { @@ -389,9 +445,7 @@ where "Err" }, }; - API_LATENCY_SECONDS - .with_label_values(&[api_name, res_type]) - .observe(timer.elapsed().as_secs_f64()); + API_LATENCY_SECONDS.observe_with(&[api_name, res_type], timer.elapsed().as_secs_f64()); ENTERED_GAUGED_API.with(|entered| entered.set(false)); res @@ -399,7 +453,11 @@ where } // Convert requested range and order to a range in ascending order. -fn get_first_seq_num_and_limit(order: Order, cursor: u64, limit: u64) -> Result<(u64, u64)> { +pub(super) fn get_first_seq_num_and_limit( + order: Order, + cursor: u64, + limit: u64, +) -> Result<(u64, u64)> { ensure!(limit > 0, "limit should > 0, got {}", limit); Ok(if order == Order::Ascending { diff --git a/storage/aptosdb/src/db/include/aptosdb_reader.rs b/storage/aptosdb/src/db/aptosdb_reader.rs similarity index 80% rename from storage/aptosdb/src/db/include/aptosdb_reader.rs rename to storage/aptosdb/src/db/aptosdb_reader.rs index f48b10daa8b..ea47102c1f7 100644 --- a/storage/aptosdb/src/db/include/aptosdb_reader.rs +++ b/storage/aptosdb/src/db/aptosdb_reader.rs @@ -1,10 +1,54 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_storage_interface::state_store::state::State; -use aptos_storage_interface::state_store::state_summary::StateSummary; -use aptos_storage_interface::state_store::state_view::hot_state_view::HotStateView; -use aptos_types::{block_info::BlockHeight, transaction::IndexedTransactionSummary}; +use crate::{ + common::MAX_NUM_EPOCH_ENDING_LEDGER_INFO, + db::{ + aptosdb_internal::{error_if_too_many_requested, gauged_api, get_first_seq_num_and_limit}, + AptosDB, + }, + pruner::PrunerManager, + schema::block_info::BlockInfoSchema, +}; +use aptos_crypto::HashValue; +use aptos_storage_interface::{ + db_ensure as ensure, db_other_bail as bail, + state_store::{ + state::State, state_summary::StateSummary, state_view::hot_state_view::HotStateView, + }, + AptosDbError, BlockHeight, DbReader, LedgerSummary, Order, Result, MAX_REQUEST_LIMIT, +}; +use aptos_types::{ + account_address::AccountAddress, + account_config::{new_block_event_key, NewBlockEvent}, + contract_event::{ContractEvent, EventWithVersion}, + epoch_change::EpochChangeProof, + epoch_state::EpochState, + event::EventKey, + ledger_info::LedgerInfoWithSignatures, + proof::{ + accumulator::InMemoryAccumulator, AccumulatorConsistencyProof, SparseMerkleProofExt, + TransactionAccumulatorRangeProof, TransactionAccumulatorSummary, + TransactionInfoListWithProof, + }, + state_proof::StateProof, + state_store::{ + state_key::{prefix::StateKeyPrefix, StateKey}, + state_storage_usage::StateStorageUsage, + state_value::{StateValue, StateValueChunkWithProof}, + table::{TableHandle, TableInfo}, + }, + transaction::{ + AccountOrderedTransactionsWithProof, IndexedTransactionSummary, PersistedAuxiliaryInfo, + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionListWithAuxiliaryInfos, + TransactionListWithProof, TransactionListWithProofV2, TransactionOutput, + TransactionOutputListWithAuxiliaryInfos, TransactionOutputListWithProof, + TransactionOutputListWithProofV2, TransactionWithProof, Version, + }, + write_set::WriteSet, +}; +use itertools::Itertools; +use std::{iter::Iterator, sync::Arc}; impl DbReader for AptosDB { fn get_persisted_state(&self) -> Result<(Arc, State)> { @@ -64,6 +108,20 @@ impl DbReader for AptosDB { }) } + fn get_persisted_auxiliary_info_by_version( + &self, + version: Version, + ) -> Result { + gauged_api("get_persisted_auxiliary_info_by_version", || { + self.error_if_ledger_pruned("PersistedAuxiliaryInfo", version)?; + Ok(self + .ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info(version)? + .unwrap_or(PersistedAuxiliaryInfo::None)) + }) + } + fn get_latest_ledger_info_option(&self) -> Result> { gauged_api("get_latest_ledger_info_option", || { Ok(self.ledger_db.metadata_db().get_latest_ledger_info_option()) @@ -149,24 +207,23 @@ impl DbReader for AptosDB { let txn_summaries_iter = self .transaction_store - .get_account_transaction_summaries_iter(address, start_version, end_version, limit, ledger_version)? + .get_account_transaction_summaries_iter( + address, + start_version, + end_version, + limit, + ledger_version, + )? .map(|result| { let (_version, txn_summary) = result?; Ok(txn_summary) }); if start_version.is_some() { - txn_summaries_iter - .collect::>>() + txn_summaries_iter.collect::>>() } else { - let txn_summaries = txn_summaries_iter - .collect::>>()?; - Ok( - txn_summaries - .into_iter() - .rev() - .collect::>() - ) + let txn_summaries = txn_summaries_iter.collect::>>()?; + Ok(txn_summaries.into_iter().rev().collect::>()) } }) } @@ -213,12 +270,12 @@ impl DbReader for AptosDB { limit: u64, ledger_version: Version, fetch_events: bool, - ) -> Result { + ) -> Result { gauged_api("get_transactions", || { error_if_too_many_requested(limit, MAX_REQUEST_LIMIT)?; if start_version > ledger_version || limit == 0 { - return Ok(TransactionListWithProof::new_empty()); + return Ok(TransactionListWithProofV2::new_empty()); } self.error_if_ledger_pruned("Transaction", start_version)?; @@ -243,6 +300,15 @@ impl DbReader for AptosDB { } else { None }; + let persisted_aux_info = (start_version..start_version + limit) + .map(|version| { + Ok(self + .ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info(version)? + .unwrap_or(PersistedAuxiliaryInfo::None)) + }) + .collect::>>()?; let proof = TransactionInfoListWithProof::new( self.ledger_db .transaction_accumulator_db() @@ -250,11 +316,11 @@ impl DbReader for AptosDB { txn_infos, ); - Ok(TransactionListWithProof::new( - txns, - events, - Some(start_version), - proof, + Ok(TransactionListWithProofV2::new( + TransactionListWithAuxiliaryInfos::new( + TransactionListWithProof::new(txns, events, Some(start_version), proof), + persisted_aux_info, + ), )) }) } @@ -310,19 +376,20 @@ impl DbReader for AptosDB { start_version: Version, limit: u64, ledger_version: Version, - ) -> Result { - gauged_api("get_transactions_outputs", || { + ) -> Result { + gauged_api("get_transaction_outputs", || { error_if_too_many_requested(limit, MAX_REQUEST_LIMIT)?; if start_version > ledger_version || limit == 0 { - return Ok(TransactionOutputListWithProof::new_empty()); + return Ok(TransactionOutputListWithProofV2::new_empty()); } self.error_if_ledger_pruned("Transaction", start_version)?; let limit = std::cmp::min(limit, ledger_version - start_version + 1); - let (txn_infos, txns_and_outputs) = (start_version..start_version + limit) + let (txn_infos, txns_and_outputs, persisted_aux_info) = (start_version + ..start_version + limit) .map(|version| { let txn_info = self .ledger_db @@ -343,11 +410,16 @@ impl DbReader for AptosDB { txn_info.status().clone().into(), auxiliary_data, ); - Ok((txn_info, (txn, txn_output))) + let persisted_aux_info = self + .ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info(version)? + .unwrap_or(PersistedAuxiliaryInfo::None); + Ok((txn_info, (txn, txn_output), persisted_aux_info)) }) .collect::>>()? .into_iter() - .unzip(); + .multiunzip(); let proof = TransactionInfoListWithProof::new( self.ledger_db .transaction_accumulator_db() @@ -355,14 +427,39 @@ impl DbReader for AptosDB { txn_infos, ); - Ok(TransactionOutputListWithProof::new( - txns_and_outputs, - Some(start_version), - proof, + Ok(TransactionOutputListWithProofV2::new( + TransactionOutputListWithAuxiliaryInfos::new( + TransactionOutputListWithProof::new( + txns_and_outputs, + Some(start_version), + proof, + ), + persisted_aux_info, + ), )) }) } + /// Returns an iterator that yields the requested number of persisted auxiliary + /// info's starting from the specified version. Note: the caller should ensure + /// that the iterator does not query data beyond the latest version. + fn get_persisted_auxiliary_info_iterator( + &self, + start_version: Version, + num_persisted_auxiliary_info: usize, + ) -> Result> + '_>> { + gauged_api("get_persisted_auxiliary_info_iterator", || { + let iter = self + .ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info_iter(start_version, num_persisted_auxiliary_info)?; + Ok(Box::new(iter) + as Box< + dyn Iterator> + '_, + >) + }) + } + /// TODO(bowu): Deprecate after internal index migration fn get_events( &self, @@ -472,6 +569,31 @@ impl DbReader for AptosDB { }) } + fn get_epoch_ending_ledger_info_iterator( + &self, + start_epoch: u64, + end_epoch: u64, + ) -> Result> + '_>> { + gauged_api("get_epoch_ending_ledger_info_iterator", || { + self.check_epoch_ending_ledger_infos_request(start_epoch, end_epoch)?; + let limit = std::cmp::min( + end_epoch.saturating_sub(start_epoch), + MAX_NUM_EPOCH_ENDING_LEDGER_INFO as u64, + ); + let end_epoch = start_epoch.saturating_add(limit); + + let iter = self + .ledger_db + .metadata_db() + .get_epoch_ending_ledger_info_iter(start_epoch, end_epoch)?; + + Ok(Box::new(iter) + as Box< + dyn Iterator> + '_, + >) + }) + } + fn get_state_proof_with_ledger_info( &self, known_version: u64, @@ -556,11 +678,8 @@ impl DbReader for AptosDB { gauged_api("get_state_value_with_proof_by_version_ext", || { self.error_if_state_merkle_pruned("State merkle", version)?; - self.state_store.get_state_value_with_proof_by_version_ext( - key_hash, - version, - root_depth, - ) + self.state_store + .get_state_value_with_proof_by_version_ext(key_hash, version, root_depth) }) } @@ -579,7 +698,10 @@ impl DbReader for AptosDB { fn get_pre_committed_ledger_summary(&self) -> Result { gauged_api("get_pre_committed_ledger_summary", || { - let (state, state_summary) = self.state_store.current_state_locked().to_state_and_summary(); + let (state, state_summary) = self + .state_store + .current_state_locked() + .to_state_and_summary(); let num_txns = state.next_version(); let frozen_subtrees = self @@ -628,9 +750,7 @@ impl DbReader for AptosDB { for item in iter { let (_block_height, block_info) = item?; let first_version = block_info.first_version(); - if latest_version - .as_ref().is_some_and(|v| first_version <= *v) - { + if latest_version.as_ref().is_some_and(|v| first_version <= *v) { let event = self .ledger_db .event_db() @@ -681,7 +801,11 @@ impl DbReader for AptosDB { fn get_latest_state_checkpoint_version(&self) -> Result> { gauged_api("get_latest_state_checkpoint_version", || { - Ok(self.state_store.current_state_locked().last_checkpoint().version()) + Ok(self + .state_store + .current_state_locked() + .last_checkpoint() + .version()) }) } @@ -756,6 +880,37 @@ impl DbReader for AptosDB { }) } + fn get_state_value_chunk_iter( + &self, + version: Version, + first_index: usize, + chunk_size: usize, + ) -> Result> + '_>> { + gauged_api("get_state_value_chunk_iter", || { + self.error_if_state_merkle_pruned("State merkle", version)?; + let state_value_chunk_iter = + self.state_store + .get_value_chunk_iter(version, first_index, chunk_size)?; + Ok(Box::new(state_value_chunk_iter) + as Box< + dyn Iterator> + '_, + >) + }) + } + + fn get_state_value_chunk_proof( + &self, + version: Version, + first_index: usize, + state_key_values: Vec<(StateKey, StateValue)>, + ) -> Result { + gauged_api("get_state_value_chunk_proof", || { + self.error_if_state_merkle_pruned("State merkle", version)?; + self.state_store + .get_value_chunk_proof(version, first_index, state_key_values) + }) + } + fn is_state_merkle_pruner_enabled(&self) -> Result { gauged_api("is_state_merkle_pruner_enabled", || { Ok(self @@ -839,12 +994,11 @@ impl AptosDB { ) } - fn get_epoch_ending_ledger_infos_impl( + fn check_epoch_ending_ledger_infos_request( &self, start_epoch: u64, end_epoch: u64, - limit: usize, - ) -> Result<(Vec, bool)> { + ) -> Result<()> { ensure!( start_epoch <= end_epoch, "Bad epoch range [{}, {})", @@ -866,6 +1020,16 @@ impl AptosDB { end_epoch, latest_epoch - 1, // okay to -1 because genesis LedgerInfo has .next_block_epoch() == 1 ); + Ok(()) + } + + pub(super) fn get_epoch_ending_ledger_infos_impl( + &self, + start_epoch: u64, + end_epoch: u64, + limit: usize, + ) -> Result<(Vec, bool)> { + self.check_epoch_ending_ledger_infos_request(start_epoch, end_epoch)?; let (paging_epoch, more) = if end_epoch - start_epoch > limit as u64 { (start_epoch + limit as u64, true) @@ -891,7 +1055,7 @@ impl AptosDB { /// Returns the transaction with proof for a given version, or error if the transaction is not /// found. - fn get_transaction_with_proof( + pub(super) fn get_transaction_with_proof( &self, version: Version, ledger_version: Version, @@ -926,7 +1090,7 @@ impl AptosDB { } /// TODO(bowu): Deprecate after internal index migration - fn get_events_by_event_key( + pub(super) fn get_events_by_event_key( &self, event_key: &EventKey, start_seq_num: u64, diff --git a/storage/aptosdb/src/db/aptosdb_test.rs b/storage/aptosdb/src/db/aptosdb_test.rs index f1ff5353c5a..abc4851c8bf 100644 --- a/storage/aptosdb/src/db/aptosdb_test.rs +++ b/storage/aptosdb/src/db/aptosdb_test.rs @@ -3,8 +3,11 @@ use crate::{ db::{ - get_first_seq_num_and_limit, test_helper, - test_helper::{arb_blocks_to_commit, put_transaction_auxiliary_data}, + aptosdb_internal::get_first_seq_num_and_limit, + test_helper::{ + arb_blocks_to_commit, put_transaction_auxiliary_data, test_save_blocks_impl, + test_sync_transactions_impl, + }, AptosDB, }, pruner::{LedgerPrunerManager, PrunerManager, StateMerklePrunerManager}, @@ -23,15 +26,14 @@ use aptos_types::{ proof::SparseMerkleLeafNode, state_store::{state_key::StateKey, state_value::StateValue}, transaction::{ - ExecutionStatus, TransactionAuxiliaryData, TransactionAuxiliaryDataV1, TransactionInfo, - TransactionToCommit, VMErrorDetail, Version, + ExecutionStatus, PersistedAuxiliaryInfo, TransactionAuxiliaryData, + TransactionAuxiliaryDataV1, TransactionInfo, TransactionToCommit, VMErrorDetail, Version, }, vm_status::StatusCode, write_set::WriteSet, }; use proptest::prelude::*; use std::{collections::HashSet, sync::Arc}; -use test_helper::{test_save_blocks_impl, test_sync_transactions_impl}; proptest! { #![proptest_config(ProptestConfig::with_cases(10))] @@ -192,6 +194,9 @@ fn test_get_latest_ledger_summary() { let key = StateKey::raw(b"test_key"); let value = StateValue::from(b"test_val".to_vec()); let state_hash = SparseMerkleLeafNode::new(key.hash(), value.hash()).hash(); + let auxiliary_info = PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }; let txn_info = TransactionInfo::new( HashValue::random(), HashValue::random(), @@ -199,6 +204,7 @@ fn test_get_latest_ledger_summary() { Some(state_hash), 0, ExecutionStatus::MiscellaneousError(None), + Some(auxiliary_info.hash()), ); let root_hash = txn_info.hash(); let mut txn_to_commit = TransactionToCommit::dummy(); @@ -321,6 +327,8 @@ proptest! { #![proptest_config(ProptestConfig::with_cases(10))] #[test] + #[ignore] + // TODO(grao): Fix this. fn test_state_merkle_pruning(input in arb_blocks_to_commit()) { aptos_logger::Logger::new().init(); test_state_merkle_pruning_impl(input); diff --git a/storage/aptosdb/src/db/aptosdb_testonly.rs b/storage/aptosdb/src/db/aptosdb_testonly.rs new file mode 100644 index 00000000000..b1cac1d4526 --- /dev/null +++ b/storage/aptosdb/src/db/aptosdb_testonly.rs @@ -0,0 +1,231 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::db::AptosDB; +#[cfg(test)] +use crate::state_merkle_db::StateMerkleDb; +use aptos_config::config::{ + RocksdbConfigs, StorageDirPaths, BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, NO_OP_STORAGE_PRUNER_CONFIG, +}; +use aptos_crypto::hash::CryptoHash; +use aptos_executor_types::transactions_with_output::TransactionsToKeep; +use aptos_storage_interface::{ + chunk_to_commit::ChunkToCommit, state_store::state_summary::ProvableStateSummary, DbReader, + DbWriter, Result, +}; +use aptos_types::{ + ledger_info::LedgerInfoWithSignatures, + transaction::{ + PersistedAuxiliaryInfo, Transaction, TransactionInfo, TransactionOutput, TransactionStatus, + TransactionToCommit, Version, + }, +}; +use itertools::Itertools; +use std::path::Path; +#[cfg(test)] +use std::sync::Arc; + +impl AptosDB { + /// This opens db in non-readonly mode, without the pruner. + pub fn new_for_test + Clone>(db_root_path: P) -> Self { + Self::new_without_pruner( + db_root_path, + false, + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, + false, /* indexer */ + false, + ) + } + + /// This opens db with sharding enabled. + pub fn new_for_test_with_sharding + Clone>( + db_root_path: P, + max_node_cache: usize, + ) -> Self { + let db_config = RocksdbConfigs { + enable_storage_sharding: true, + ..Default::default() + }; + Self::open( + StorageDirPaths::from_path(db_root_path), + false, + NO_OP_STORAGE_PRUNER_CONFIG, /* pruner */ + db_config, + false, /* indexer */ + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + max_node_cache, + None, + ) + .expect("Unable to open AptosDB") + } + + /// This opens db in non-readonly mode, without the pruner and cache. + pub fn new_for_test_no_cache + Clone>(db_root_path: P) -> Self { + Self::new_without_pruner( + db_root_path, + false, + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + 0, + false, + false, + ) + } + + /// This opens db in non-readonly mode, without the pruner, and with the indexer + pub fn new_for_test_with_indexer + Clone>( + db_root_path: P, + enable_sharding: bool, + ) -> Self { + Self::new_without_pruner( + db_root_path, + false, + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, + true, /* indexer */ + enable_sharding, + ) + } + + /// This opens db in non-readonly mode, without the pruner. + pub fn new_for_test_with_buffered_state_target_items + Clone>( + db_root_path: P, + buffered_state_target_items: usize, + ) -> Self { + Self::new_without_pruner( + db_root_path, + false, + buffered_state_target_items, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, + false, /* indexer */ + false, + ) + } + + /// This opens db in non-readonly mode, without the pruner. + pub fn new_readonly_for_test + Clone>(db_root_path: P) -> Self { + Self::new_without_pruner( + db_root_path, + true, + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, + false, /* indexer */ + false, + ) + } + + #[cfg(test)] + pub(crate) fn state_merkle_db(&self) -> Arc { + self.state_store.state_db.state_merkle_db.clone() + } +} + +/// Test only methods for the DB +impl AptosDB { + pub fn save_transactions_for_test( + &self, + txns_to_commit: &[TransactionToCommit], + first_version: Version, + ledger_info_with_sigs: Option<&LedgerInfoWithSignatures>, + sync_commit: bool, + ) -> Result<()> { + let (transactions, transaction_outputs, transaction_infos) = + Self::disassemble_txns_to_commit(txns_to_commit); + // Keep auxiliary info consistent with what was used to create TransactionInfo + // Use block-relative indices to match what was used during TransactionInfo creation + let persisted_auxiliary_infos = txns_to_commit + .iter() + .map( + |txn_to_commit| match txn_to_commit.transaction_info.auxiliary_info_hash() { + Some(hash) => { + for i in 0..100 { + if hash + == CryptoHash::hash(&PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }) + { + return PersistedAuxiliaryInfo::V1 { + transaction_index: i as u32, + }; + } + } + panic!("Hash not found"); + }, + None => PersistedAuxiliaryInfo::None, + }, + ) + .collect(); + let transactions_to_keep = TransactionsToKeep::make( + first_version, + transactions, + transaction_outputs, + persisted_auxiliary_infos, + ); + + let current = self.state_store.current_state_locked().clone(); + let (hot_state, persisted_state) = self.state_store.get_persisted_state()?; + let (new_state, reads) = current.ledger_state().update_with_db_reader( + &persisted_state, + hot_state, + transactions_to_keep.state_update_refs(), + self.state_store.clone(), + )?; + let persisted_summary = self.state_store.get_persisted_state_summary()?; + let new_state_summary = current.ledger_state_summary().update( + &ProvableStateSummary::new(persisted_summary, self), + transactions_to_keep.state_update_refs(), + )?; + + let chunk = ChunkToCommit { + first_version, + transactions: &transactions_to_keep.transactions, + persisted_auxiliary_infos: &transactions_to_keep.persisted_auxiliary_infos, + transaction_outputs: &transactions_to_keep.transaction_outputs, + transaction_infos: &transaction_infos, + state: &new_state, + state_summary: &new_state_summary, + state_update_refs: transactions_to_keep.state_update_refs(), + state_reads: &reads, + is_reconfig: transactions_to_keep.is_reconfig(), + }; + + self.save_transactions(chunk, ledger_info_with_sigs, sync_commit) + } + + fn disassemble_txns_to_commit( + txns_to_commit: &[TransactionToCommit], + ) -> ( + Vec, + Vec, + Vec, + ) { + txns_to_commit + .iter() + .map(|txn_to_commit| { + let TransactionToCommit { + transaction, + transaction_info, + write_set, + events, + is_reconfig: _, + transaction_auxiliary_data, + } = txn_to_commit; + + let transaction_output = TransactionOutput::new( + write_set.clone(), + events.clone(), + transaction_info.gas_used(), + TransactionStatus::Keep(transaction_info.status().clone()), + transaction_auxiliary_data.clone(), + ); + + ( + transaction.clone(), + transaction_output, + transaction_info.clone(), + ) + }) + .multiunzip() + } +} diff --git a/storage/aptosdb/src/db/include/aptosdb_writer.rs b/storage/aptosdb/src/db/aptosdb_writer.rs similarity index 81% rename from storage/aptosdb/src/db/include/aptosdb_writer.rs rename to storage/aptosdb/src/db/aptosdb_writer.rs index ef02303e12a..2b13e398097 100644 --- a/storage/aptosdb/src/db/include/aptosdb_writer.rs +++ b/storage/aptosdb/src/db/aptosdb_writer.rs @@ -1,15 +1,47 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use crate::{ + backup::restore_utils, + db::{aptosdb_internal::gauged_api, AptosDB}, + ledger_db::{ + ledger_metadata_db::LedgerMetadataDb, + transaction_auxiliary_data_db::TransactionAuxiliaryDataDb, + transaction_info_db::TransactionInfoDb, LedgerDbSchemaBatches, + }, + metrics::{ + COMMITTED_TXNS, LATEST_TXN_VERSION, LEDGER_VERSION, NEXT_BLOCK_EPOCH, OTHER_TIMERS_SECONDS, + }, + pruner::PrunerManager, + schema::{ + db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, + transaction_accumulator_root_hash::TransactionAccumulatorRootHashSchema, + }, +}; +use aptos_crypto::HashValue; +use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; +use aptos_metrics_core::TimerHelper; +use aptos_schemadb::batch::SchemaBatch; +use aptos_storage_interface::{ + chunk_to_commit::ChunkToCommit, db_ensure as ensure, AptosDbError, DbReader, DbWriter, Result, + StateSnapshotReceiver, +}; +use aptos_types::{ + account_config::new_block_event_key, + ledger_info::LedgerInfoWithSignatures, + state_store::{state_key::StateKey, state_value::StateValue}, + transaction::{ + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionOutput, + TransactionOutputListWithProofV2, Version, + }, + write_set::WriteSet, +}; use itertools::Itertools; -use aptos_storage_interface::chunk_to_commit::ChunkToCommit; +use rayon::prelude::*; +use std::{iter::Iterator, time::Instant}; impl DbWriter for AptosDB { - fn pre_commit_ledger( - &self, - chunk: ChunkToCommit, - sync_commit: bool, - ) -> Result<()> { + fn pre_commit_ledger(&self, chunk: ChunkToCommit, sync_commit: bool) -> Result<()> { gauged_api("pre_commit_ledger", || { // Pre-committing and committing in concurrency is allowed but not pre-committing at the // same time from multiple threads, the same for committing. @@ -21,13 +53,15 @@ impl DbWriter for AptosDB { .expect("Concurrent committing detected."); let _timer = OTHER_TIMERS_SECONDS.timer_with(&["pre_commit_ledger"]); - chunk.state_summary.latest().global_state_summary.log_generation("db_save"); + chunk + .state_summary + .latest() + .global_state_summary + .log_generation("db_save"); self.pre_commit_validation(&chunk)?; - let _new_root_hash = self.calculate_and_commit_ledger_and_state_kv( - &chunk, - self.skip_index_and_usage, - )?; + let _new_root_hash = + self.calculate_and_commit_ledger_and_state_kv(&chunk, self.skip_index_and_usage)?; let _timer = OTHER_TIMERS_SECONDS.timer_with(&["save_transactions__others"]); @@ -73,16 +107,10 @@ impl DbWriter for AptosDB { self.ledger_db.metadata_db().write_schemas(ledger_batch)?; // Notify the pruners, invoke the indexer, and update in-memory ledger info. - self.post_commit( - old_committed_ver, - version, - ledger_info_with_sigs, - chunk_opt, - ) + self.post_commit(old_committed_ver, version, ledger_info_with_sigs, chunk_opt) }) } - fn get_state_snapshot_receiver( &self, version: Version, @@ -97,12 +125,13 @@ impl DbWriter for AptosDB { fn finalize_state_snapshot( &self, version: Version, - output_with_proof: TransactionOutputListWithProof, + output_with_proof: TransactionOutputListWithProofV2, ledger_infos: &[LedgerInfoWithSignatures], ) -> Result<()> { + let (output_with_proof, persisted_aux_info) = output_with_proof.into_parts(); gauged_api("finalize_state_snapshot", || { // Ensure the output with proof only contains a single transaction output and info - let num_transaction_outputs = output_with_proof.transactions_and_outputs.len(); + let num_transaction_outputs = output_with_proof.get_num_outputs(); let num_transaction_infos = output_with_proof.proof.transaction_infos.len(); ensure!( num_transaction_outputs == 1, @@ -156,6 +185,7 @@ impl DbWriter for AptosDB { self.ledger_db.clone(), version, &transactions, + &persisted_aux_info, &transaction_infos, &events, wsets, @@ -212,10 +242,7 @@ impl DbWriter for AptosDB { } impl AptosDB { - fn pre_commit_validation( - &self, - chunk: &ChunkToCommit, - ) -> Result<()> { + fn pre_commit_validation(&self, chunk: &ChunkToCommit) -> Result<()> { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["save_transactions_validation"]); ensure!(!chunk.is_empty(), "chunk is empty, nothing to save."); @@ -247,30 +274,38 @@ impl AptosDB { // // TODO(grao): Consider propagating the error instead of panic, if necessary. s.spawn(|_| { - self.commit_events(chunk.first_version, chunk.transaction_outputs, skip_index_and_usage) - .unwrap() + self.commit_events( + chunk.first_version, + chunk.transaction_outputs, + skip_index_and_usage, + ) + .unwrap() }); s.spawn(|_| { self.ledger_db .write_set_db() - .commit_write_sets( + .commit_write_sets(chunk.first_version, chunk.transaction_outputs) + .unwrap() + }); + s.spawn(|_| { + self.ledger_db + .transaction_db() + .commit_transactions( chunk.first_version, - chunk.transaction_outputs, + chunk.transactions, + skip_index_and_usage, ) .unwrap() }); s.spawn(|_| { self.ledger_db - .transaction_db() - .commit_transactions(chunk.first_version, chunk.transactions, skip_index_and_usage) + .persisted_auxiliary_info_db() + .commit_auxiliary_info(chunk.first_version, chunk.persisted_auxiliary_infos) .unwrap() }); s.spawn(|_| { - self.commit_state_kv_and_ledger_metadata( - chunk, - skip_index_and_usage, - ) - .unwrap() + self.commit_state_kv_and_ledger_metadata(chunk, skip_index_and_usage) + .unwrap() }); s.spawn(|_| { self.commit_transaction_infos(chunk.first_version, chunk.transaction_infos) @@ -329,7 +364,8 @@ impl AptosDB { ) .unwrap(); - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_state_kv_and_ledger_metadata___commit"]); + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["commit_state_kv_and_ledger_metadata___commit"]); rayon::scope(|s| { s.spawn(|_| { self.ledger_db @@ -339,11 +375,7 @@ impl AptosDB { }); s.spawn(|_| { self.state_kv_db - .commit( - chunk.expect_last_version(), - None, - sharded_state_kv_batches, - ) + .commit(chunk.expect_last_version(), None, sharded_state_kv_batches) .unwrap(); }); }); @@ -379,9 +411,7 @@ impl AptosDB { .collect::>>()?; { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_events___commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_events___commit"]); for batch in batches { self.ledger_db.event_db().db().write_schemas(batch)? } @@ -389,7 +419,7 @@ impl AptosDB { } } - fn commit_transaction_accumulator( + pub(super) fn commit_transaction_accumulator( &self, first_version: Version, transaction_infos: &[TransactionInfo], @@ -402,11 +432,7 @@ impl AptosDB { let root_hash = self .ledger_db .transaction_accumulator_db() - .put_transaction_accumulator( - first_version, - transaction_infos, - &mut batch, - )?; + .put_transaction_accumulator(first_version, transaction_infos, &mut batch)?; let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_accumulator___commit"]); self.ledger_db @@ -414,8 +440,7 @@ impl AptosDB { .write_schemas(batch)?; let mut batch = SchemaBatch::new(); - let all_versions: Vec<_> = - (first_version..first_version + num_txns).collect(); + let all_versions: Vec<_> = (first_version..first_version + num_txns).collect(); THREAD_MANAGER .get_non_exe_cpu_pool() .install(|| -> Result<()> { @@ -444,7 +469,7 @@ impl AptosDB { } #[allow(dead_code)] - fn commit_transaction_auxiliary_data<'a>( + pub(super) fn commit_transaction_auxiliary_data<'a>( &self, first_version: Version, auxiliary_data: impl IntoIterator, @@ -465,13 +490,14 @@ impl AptosDB { Ok(()) })?; - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_auxiliary_data___commit"]); + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_auxiliary_data___commit"]); self.ledger_db .transaction_auxiliary_data_db() .write_schemas(batch) } - fn commit_transaction_infos( + pub(super) fn commit_transaction_infos( &self, first_version: Version, txn_infos: &[TransactionInfo], @@ -484,11 +510,7 @@ impl AptosDB { .enumerate() .try_for_each(|(i, txn_info)| -> Result<()> { let version = first_version + i as u64; - TransactionInfoDb::put_transaction_info( - version, - txn_info, - &mut batch, - )?; + TransactionInfoDb::put_transaction_info(version, txn_info, &mut batch)?; Ok(()) })?; @@ -497,10 +519,7 @@ impl AptosDB { self.ledger_db.transaction_info_db().write_schemas(batch) } - fn get_and_check_commit_range( - &self, - version_to_commit: Version, - ) -> Result> { + fn get_and_check_commit_range(&self, version_to_commit: Version) -> Result> { let old_committed_ver = self.ledger_db.metadata_db().get_synced_version()?; let pre_committed_ver = self.state_store.current_state_locked().version(); ensure!( @@ -522,7 +541,7 @@ impl AptosDB { &self, version: Version, ledger_info_with_sig: &LedgerInfoWithSignatures, - ledger_batch: &mut SchemaBatch + ledger_batch: &mut SchemaBatch, ) -> Result<(), AptosDbError> { let ledger_info = ledger_info_with_sig.ledger_info(); @@ -535,8 +554,13 @@ impl AptosDB { ); // Verify the root hash. - let db_root_hash = self.ledger_db.transaction_accumulator_db().get_root_hash(version)?; - let li_root_hash = ledger_info_with_sig.ledger_info().transaction_accumulator_hash(); + let db_root_hash = self + .ledger_db + .transaction_accumulator_db() + .get_root_hash(version)?; + let li_root_hash = ledger_info_with_sig + .ledger_info() + .transaction_accumulator_hash(); ensure!( db_root_hash == li_root_hash, "Root hash pre-committed doesn't match LedgerInfo. pre-commited: {:?} vs in LedgerInfo: {:?}", @@ -592,9 +616,9 @@ impl AptosDB { COMMITTED_TXNS.inc_by(num_txns); LATEST_TXN_VERSION.set(version as i64); if let Some(update_sender) = &self.update_subscriber { - update_sender.send( - (Instant::now(), version) - ).map_err(| err | { + update_sender + .send((Instant::now(), version)) + .map_err(|err| { AptosDbError::Other(format!("Failed to send update to subscriber: {}", err)) })?; } @@ -613,11 +637,21 @@ impl AptosDB { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["indexer_index"]); // n.b. txns_to_commit can be partial, when the control was handed over from consensus to state sync // where state sync won't send the pre-committed part to the DB again. - if chunk_opt.is_some() && chunk_opt.as_ref().unwrap().len() == num_txns as usize { - let write_sets = chunk_opt.as_ref().unwrap().transaction_outputs.iter().map(|t| t.write_set()).collect_vec(); + if let Some(chunk) = chunk_opt + && chunk.len() == num_txns as usize + { + let write_sets = chunk + .transaction_outputs + .iter() + .map(|t| t.write_set()) + .collect_vec(); indexer.index(self.state_store.clone(), first_version, &write_sets)?; } else { - let write_sets: Vec<_> = self.ledger_db.write_set_db().get_write_set_iter(first_version, num_txns as usize)?.try_collect()?; + let write_sets: Vec<_> = self + .ledger_db + .write_set_db() + .get_write_set_iter(first_version, num_txns as usize)? + .try_collect()?; let write_set_refs = write_sets.iter().collect_vec(); indexer.index(self.state_store.clone(), first_version, &write_set_refs)?; }; diff --git a/storage/aptosdb/src/db/fake_aptosdb.rs b/storage/aptosdb/src/db/fake_aptosdb.rs index c62d23c449e..8631a2c7847 100644 --- a/storage/aptosdb/src/db/fake_aptosdb.rs +++ b/storage/aptosdb/src/db/fake_aptosdb.rs @@ -1184,21 +1184,20 @@ mod tests { ) -> Result<()> { // Verify the first transaction/output versions match ensure!( - txn_outputs_with_proof.first_transaction_output_version - == first_transaction_output_version, + txn_outputs_with_proof.get_first_output_version() == first_transaction_output_version, "First transaction and output version ({:?}) doesn't match given version ({:?}).", - txn_outputs_with_proof.first_transaction_output_version, + txn_outputs_with_proof.get_first_output_version(), first_transaction_output_version, ); // Verify the lengths of the transaction(output)s and transaction infos match ensure!( txn_outputs_with_proof.proof.transaction_infos.len() - == txn_outputs_with_proof.transactions_and_outputs.len(), + == txn_outputs_with_proof.get_num_outputs(), "The number of TransactionInfo objects ({}) does not match the number of \ transactions and outputs ({}).", txn_outputs_with_proof.proof.transaction_infos.len(), - txn_outputs_with_proof.transactions_and_outputs.len(), + txn_outputs_with_proof.get_num_outputs(), ); // Verify the events, status, gas used and transaction hashes. @@ -1247,19 +1246,19 @@ mod tests { ) -> Result<()> { // Verify the first transaction versions match ensure!( - txn_list.first_transaction_version == first_transaction_version, + txn_list.get_first_transaction_version() == first_transaction_version, "First transaction version ({:?}) doesn't match given version ({:?}).", - txn_list.first_transaction_version, + txn_list.get_first_transaction_version(), first_transaction_version, ); // Verify the lengths of the transactions and transaction infos match ensure!( - txn_list.proof.transaction_infos.len() == txn_list.transactions.len(), + txn_list.proof.transaction_infos.len() == txn_list.get_num_transactions(), "The number of TransactionInfo objects ({}) does not match the number of \ transactions ({}).", txn_list.proof.transaction_infos.len(), - txn_list.transactions.len(), + txn_list.get_num_transactions(), ); // Verify the transaction hashes match those of the transaction infos diff --git a/storage/aptosdb/src/db/include/aptosdb_testonly.rs b/storage/aptosdb/src/db/include/aptosdb_testonly.rs deleted file mode 100644 index 67fc0c027d4..00000000000 --- a/storage/aptosdb/src/db/include/aptosdb_testonly.rs +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_config::config::{BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD}; -use std::default::Default; -use aptos_types::transaction::{TransactionStatus, TransactionToCommit}; -use aptos_executor_types::transactions_with_output::TransactionsToKeep; -use aptos_storage_interface::state_store::state_summary::ProvableStateSummary; - -impl AptosDB { - /// This opens db in non-readonly mode, without the pruner. - pub fn new_for_test + Clone>(db_root_path: P) -> Self { - Self::new_without_pruner( - db_root_path, - false, - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, - false, /* indexer */ - false, - ) - } - - /// This opens db with sharding enabled. - pub fn new_for_test_with_sharding + Clone>( - db_root_path: P, - max_node_cache: usize, - ) -> Self { - let db_config = RocksdbConfigs { - enable_storage_sharding: true, - ..Default::default() - }; - Self::open( - StorageDirPaths::from_path(db_root_path), - false, - NO_OP_STORAGE_PRUNER_CONFIG, /* pruner */ - db_config, - false, /* indexer */ - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - max_node_cache, - None, - ) - .expect("Unable to open AptosDB") - } - - /// This opens db in non-readonly mode, without the pruner and cache. - pub fn new_for_test_no_cache + Clone>(db_root_path: P) -> Self { - Self::new_without_pruner(db_root_path, false, - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - 0, false, false) - } - - /// This opens db in non-readonly mode, without the pruner, and with the indexer - pub fn new_for_test_with_indexer + Clone>(db_root_path: P, enable_sharding: bool) -> Self { - Self::new_without_pruner( - db_root_path, - false, - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, - true, /* indexer */ - enable_sharding, - ) - } - - /// This opens db in non-readonly mode, without the pruner. - pub fn new_for_test_with_buffered_state_target_items + Clone>( - db_root_path: P, - buffered_state_target_items: usize, - ) -> Self { - Self::new_without_pruner( - db_root_path, - false, - buffered_state_target_items, - DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, - false, /* indexer */ - false, - ) - } - - /// This opens db in non-readonly mode, without the pruner. - pub fn new_readonly_for_test + Clone>(db_root_path: P) -> Self { - Self::new_without_pruner( - db_root_path, - true, - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, - false, /* indexer */ - false, - ) - } - - #[cfg(test)] - pub(crate) fn state_merkle_db(&self) -> Arc { - self.state_store.state_db.state_merkle_db.clone() - } -} - -/// Test only methods for the DB -impl AptosDB { - pub fn save_transactions_for_test( - &self, - txns_to_commit: &[TransactionToCommit], - first_version: Version, - ledger_info_with_sigs: Option<&LedgerInfoWithSignatures>, - sync_commit: bool, - ) -> Result<()> { - let (transactions, transaction_outputs, transaction_infos) = Self::disassemble_txns_to_commit(txns_to_commit); - let is_reconfig = transaction_outputs - .iter() - .rev() - .flat_map(TransactionOutput::events) - .any(ContractEvent::is_new_epoch_event); - let transactions_to_keep = TransactionsToKeep::make(first_version, transactions, transaction_outputs, is_reconfig); - - let current = self.state_store.current_state_locked().clone(); - let (hot_state, persisted_state) = self.state_store.get_persisted_state()?; - let (new_state, reads) = current.ledger_state().update_with_db_reader( - &persisted_state, - hot_state, - transactions_to_keep.state_update_refs(), - self.state_store.clone(), - )?; - let persisted_summary = self.state_store.get_persisted_state_summary()?; - let new_state_summary = current.ledger_state_summary().update( - &ProvableStateSummary::new(persisted_summary, self), - transactions_to_keep.state_update_refs(), - )?; - - let chunk = ChunkToCommit { - first_version, - transactions: &transactions_to_keep.transactions, - transaction_outputs: &transactions_to_keep.transaction_outputs, - transaction_infos: &transaction_infos, - state: &new_state, - state_summary: &new_state_summary, - state_update_refs: transactions_to_keep.state_update_refs(), - state_reads: &reads, - is_reconfig, - }; - - self.save_transactions( chunk, ledger_info_with_sigs, sync_commit) - } - - fn disassemble_txns_to_commit(txns_to_commit: &[TransactionToCommit]) -> ( - Vec, Vec, Vec - ) { - txns_to_commit.iter().map(|txn_to_commit| { - let TransactionToCommit { - transaction, transaction_info, write_set, events, is_reconfig: _, transaction_auxiliary_data - } = txn_to_commit; - - let transaction_output = TransactionOutput::new( - write_set.clone(), - events.clone(), - transaction_info.gas_used(), - TransactionStatus::Keep(transaction_info.status().clone()), - transaction_auxiliary_data.clone(), - ); - - (transaction.clone(), transaction_output, transaction_info.clone()) - }).multiunzip() - } -} diff --git a/storage/aptosdb/src/db/mod.rs b/storage/aptosdb/src/db/mod.rs index 7927313b634..83bbb0aa479 100644 --- a/storage/aptosdb/src/db/mod.rs +++ b/storage/aptosdb/src/db/mod.rs @@ -3,80 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - backup::{backup_handler::BackupHandler, restore_utils}, - common::MAX_NUM_EPOCH_ENDING_LEDGER_INFO, - event_store::EventStore, - ledger_db::{ - ledger_metadata_db::LedgerMetadataDb, - transaction_auxiliary_data_db::TransactionAuxiliaryDataDb, - transaction_info_db::TransactionInfoDb, LedgerDb, LedgerDbSchemaBatches, - }, - metrics::{ - API_LATENCY_SECONDS, COMMITTED_TXNS, LATEST_TXN_VERSION, LEDGER_VERSION, NEXT_BLOCK_EPOCH, - OTHER_TIMERS_SECONDS, - }, - pruner::{LedgerPrunerManager, PrunerManager, StateKvPrunerManager, StateMerklePrunerManager}, - rocksdb_property_reporter::RocksdbPropertyReporter, - schema::{ - block_info::BlockInfoSchema, - db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, - transaction_accumulator_root_hash::TransactionAccumulatorRootHashSchema, - }, - state_kv_db::StateKvDb, - state_merkle_db::StateMerkleDb, - state_store::StateStore, + backup::backup_handler::BackupHandler, event_store::EventStore, ledger_db::LedgerDb, + pruner::LedgerPrunerManager, rocksdb_property_reporter::RocksdbPropertyReporter, + state_kv_db::StateKvDb, state_merkle_db::StateMerkleDb, state_store::StateStore, transaction_store::TransactionStore, }; -use aptos_config::config::{ - PrunerConfig, RocksdbConfig, RocksdbConfigs, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG, -}; -use aptos_crypto::HashValue; +use aptos_config::config::{PrunerConfig, RocksdbConfigs, StorageDirPaths}; use aptos_db_indexer::{db_indexer::InternalIndexerDB, Indexer}; -use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::*; -use aptos_metrics_core::TimerHelper; -use aptos_resource_viewer::AptosValueAnnotator; -use aptos_schemadb::batch::SchemaBatch; -use aptos_storage_interface::{ - db_ensure as ensure, db_other_bail as bail, AptosDbError, DbReader, DbWriter, LedgerSummary, - Order, Result, StateSnapshotReceiver, MAX_REQUEST_LIMIT, -}; -use aptos_types::{ - account_address::AccountAddress, - account_config::{new_block_event_key, NewBlockEvent}, - contract_event::{ContractEvent, EventWithVersion}, - epoch_change::EpochChangeProof, - epoch_state::EpochState, - event::EventKey, - ledger_info::LedgerInfoWithSignatures, - proof::{ - accumulator::InMemoryAccumulator, AccumulatorConsistencyProof, SparseMerkleProofExt, - TransactionAccumulatorRangeProof, TransactionAccumulatorSummary, - TransactionInfoListWithProof, - }, - state_proof::StateProof, - state_store::{ - state_key::{prefix::StateKeyPrefix, StateKey}, - state_storage_usage::StateStorageUsage, - state_value::{StateValue, StateValueChunkWithProof}, - table::{TableHandle, TableInfo}, - }, - transaction::{ - AccountOrderedTransactionsWithProof, Transaction, TransactionAuxiliaryData, - TransactionInfo, TransactionListWithProof, TransactionOutput, - TransactionOutputListWithProof, TransactionWithProof, Version, - }, - write_set::WriteSet, -}; -use rayon::prelude::*; -use std::{ - cell::Cell, - fmt::{Debug, Formatter}, - iter::Iterator, - path::Path, - sync::Arc, - time::Instant, -}; +use aptos_schemadb::{batch::SchemaBatch, Cache, Env}; +use aptos_storage_interface::{db_ensure as ensure, AptosDbError, Result}; +use aptos_types::{ledger_info::LedgerInfoWithSignatures, transaction::Version}; +use std::{path::Path, sync::Arc, time::Instant}; use tokio::sync::watch::Sender; #[cfg(test)] @@ -104,14 +42,14 @@ pub struct AptosDB { } // DbReader implementations and private functions used by them. -include!("include/aptosdb_reader.rs"); +mod aptosdb_reader; // DbWriter implementations and private functions used by them. -include!("include/aptosdb_writer.rs"); +mod aptosdb_writer; // Other private methods. -include!("include/aptosdb_internal.rs"); +mod aptosdb_internal; // Testonly methods. #[cfg(any(test, feature = "fuzzing", feature = "consensus-only-perf-test"))] -include!("include/aptosdb_testonly.rs"); +mod aptosdb_testonly; #[cfg(feature = "consensus-only-perf-test")] pub mod fake_aptosdb; @@ -166,19 +104,31 @@ impl AptosDB { pub fn open_dbs( db_paths: &StorageDirPaths, rocksdb_configs: RocksdbConfigs, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, max_num_nodes_per_lru_cache_shard: usize, ) -> Result<(LedgerDb, StateMerkleDb, StateKvDb)> { - let ledger_db = LedgerDb::new(db_paths.ledger_db_root_path(), rocksdb_configs, readonly)?; + let ledger_db = LedgerDb::new( + db_paths.ledger_db_root_path(), + rocksdb_configs, + env, + block_cache, + readonly, + )?; let state_kv_db = StateKvDb::new( db_paths, rocksdb_configs, + env, + block_cache, readonly, ledger_db.metadata_db_arc(), )?; let state_merkle_db = StateMerkleDb::new( db_paths, rocksdb_configs, + env, + block_cache, readonly, max_num_nodes_per_lru_cache_shard, )?; diff --git a/storage/aptosdb/src/db/test_helper.rs b/storage/aptosdb/src/db/test_helper.rs index b3e55268440..c6d455aa44f 100644 --- a/storage/aptosdb/src/db/test_helper.rs +++ b/storage/aptosdb/src/db/test_helper.rs @@ -21,8 +21,8 @@ use aptos_types::{ proptest_types::{AccountInfoUniverse, BlockGen}, state_store::{state_key::StateKey, state_value::StateValue}, transaction::{ - ReplayProtector, Transaction, TransactionAuxiliaryData, TransactionInfo, - TransactionToCommit, Version, + AuxiliaryInfo, PersistedAuxiliaryInfo, ReplayProtector, Transaction, + TransactionAuxiliaryData, TransactionInfo, TransactionToCommit, Version, }, write_set::TransactionWrite, }; @@ -160,7 +160,7 @@ prop_compose! { let state_checkpoint_root_hash = smt.root_hash(); // make real txn_info's - for txn in txns_to_commit.iter_mut() { + for (idx, txn) in txns_to_commit.iter_mut().enumerate() { let placeholder_txn_info = txn.transaction_info(); // calculate event root hash @@ -174,6 +174,8 @@ prop_compose! { None }; + let auxiliary_info = AuxiliaryInfo::new(PersistedAuxiliaryInfo::V1 { transaction_index: idx as u32 }, None); + let txn_info = TransactionInfo::new( txn.transaction().hash(), txn.write_set().hash(), @@ -181,6 +183,7 @@ prop_compose! { state_checkpoint_hash, placeholder_txn_info.gas_used(), placeholder_txn_info.status().clone(), + auxiliary_info.persisted_info_hash(), ); txn_accumulator = txn_accumulator.append(&[txn_info.hash()]); txn.set_transaction_info(txn_info); @@ -895,7 +898,7 @@ pub fn verify_committed_transactions( txn_list_with_proof .verify(ledger_info, Some(cur_ver)) .unwrap(); - assert_eq!(txn_list_with_proof.transactions.len(), 1); + assert_eq!(txn_list_with_proof.get_num_transactions(), 1); let txn_output_list_with_proof = db .get_transaction_outputs(cur_ver, 1, ledger_version) @@ -903,7 +906,7 @@ pub fn verify_committed_transactions( txn_output_list_with_proof .verify(ledger_info, Some(cur_ver)) .unwrap(); - assert_eq!(txn_output_list_with_proof.transactions_and_outputs.len(), 1); + assert_eq!(txn_output_list_with_proof.get_num_outputs(), 1); } cur_ver += 1; } @@ -930,6 +933,17 @@ pub fn verify_committed_transactions( ); } +pub fn put_persisted_auxiliary_info( + db: &AptosDB, + version: Version, + persisted_info: &[PersistedAuxiliaryInfo], +) { + db.ledger_db + .persisted_auxiliary_info_db() + .commit_auxiliary_info(version, persisted_info) + .unwrap() +} + pub fn put_transaction_infos( db: &AptosDB, version: Version, diff --git a/storage/aptosdb/src/db_debugger/common/mod.rs b/storage/aptosdb/src/db_debugger/common/mod.rs index dc9a19e390e..b4d1556a5b6 100644 --- a/storage/aptosdb/src/db_debugger/common/mod.rs +++ b/storage/aptosdb/src/db_debugger/common/mod.rs @@ -26,12 +26,16 @@ pub struct DbDir { impl DbDir { pub fn open_state_merkle_db(&self) -> Result { + let env = None; + let block_cache = None; StateMerkleDb::new( &StorageDirPaths::from_path(&self.db_dir), RocksdbConfigs { enable_storage_sharding: self.sharding_config.enable_storage_sharding, ..Default::default() }, + env, + block_cache, false, 0, ) @@ -39,24 +43,32 @@ impl DbDir { pub fn open_state_kv_db(&self) -> Result { let leger_db = self.open_ledger_db()?; + let env = None; + let block_cache = None; StateKvDb::new( &StorageDirPaths::from_path(&self.db_dir), RocksdbConfigs { enable_storage_sharding: self.sharding_config.enable_storage_sharding, ..Default::default() }, + env, + block_cache, true, leger_db.metadata_db_arc(), ) } pub fn open_ledger_db(&self) -> Result { + let env = None; + let block_cache = None; LedgerDb::new( self.db_dir.as_path(), RocksdbConfigs { enable_storage_sharding: self.sharding_config.enable_storage_sharding, ..Default::default() }, + env, + block_cache, true, ) } diff --git a/storage/aptosdb/src/db_debugger/examine/mod.rs b/storage/aptosdb/src/db_debugger/examine/mod.rs index 42d95e253b6..dcb82623e02 100644 --- a/storage/aptosdb/src/db_debugger/examine/mod.rs +++ b/storage/aptosdb/src/db_debugger/examine/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 mod print_db_versions; +mod print_raw_data_by_version; use aptos_storage_interface::Result; @@ -9,12 +10,14 @@ use aptos_storage_interface::Result; #[clap(about = "Examine databases.")] pub enum Cmd { PrintDbVersions(print_db_versions::Cmd), + PrintRawDataByVersion(print_raw_data_by_version::Cmd), } impl Cmd { pub fn run(self) -> Result<()> { match self { Self::PrintDbVersions(cmd) => cmd.run(), + Self::PrintRawDataByVersion(cmd) => cmd.run(), } } } diff --git a/storage/aptosdb/src/db_debugger/examine/print_db_versions.rs b/storage/aptosdb/src/db_debugger/examine/print_db_versions.rs index dccc954ea97..921ed47025a 100644 --- a/storage/aptosdb/src/db_debugger/examine/print_db_versions.rs +++ b/storage/aptosdb/src/db_debugger/examine/print_db_versions.rs @@ -21,7 +21,7 @@ use crate::{ use aptos_config::config::{RocksdbConfigs, StorageDirPaths}; use aptos_schemadb::{schema::Schema, DB}; use aptos_storage_interface::Result; -use aptos_types::transaction::Version; +use aptos_types::{state_store::NUM_STATE_SHARDS, transaction::Version}; use clap::Parser; use std::path::PathBuf; @@ -41,9 +41,13 @@ impl Cmd { enable_storage_sharding: self.sharding_config.enable_storage_sharding, ..Default::default() }; + let env = None; + let block_cache = None; let (ledger_db, state_merkle_db, state_kv_db) = AptosDB::open_dbs( &StorageDirPaths::from_path(&self.db_dir), rocksdb_config, + env, + block_cache, /*readonly=*/ true, /*max_num_nodes_per_lru_cache_shard=*/ 0, )?; @@ -73,6 +77,54 @@ impl Cmd { ledger_db.metadata_db().get_pruner_progress(), ); + println!( + "-- Event: {:?}", + ledger_db + .event_db_raw() + .get::(&DbMetadataKey::EventPrunerProgress)? + .map(|v| v.expect_version()) + ); + + println!( + "-- PersistedAuxiliaryInfo: {:?}", + ledger_db + .persisted_auxiliary_info_db_raw() + .get::(&DbMetadataKey::PersistedAuxiliaryInfoPrunerProgress)? + .map(|v| v.expect_version()) + ); + + println!( + "-- Transaction: {:?}", + ledger_db + .transaction_db_raw() + .get::(&DbMetadataKey::TransactionPrunerProgress)? + .map(|v| v.expect_version()) + ); + + println!( + "-- TransactionAccumulator: {:?}", + ledger_db + .transaction_accumulator_db_raw() + .get::(&DbMetadataKey::TransactionAccumulatorPrunerProgress)? + .map(|v| v.expect_version()) + ); + + println!( + "-- TransactionInfo: {:?}", + ledger_db + .transaction_info_db_raw() + .get::(&DbMetadataKey::TransactionInfoPrunerProgress)? + .map(|v| v.expect_version()) + ); + + println!( + "-- WriteSet: {:?}", + ledger_db + .write_set_db_raw() + .get::(&DbMetadataKey::WriteSetPrunerProgress)? + .map(|v| v.expect_version()) + ); + println!( "StateKvPruner Progress: {:?}", state_kv_db @@ -81,6 +133,16 @@ impl Cmd { .map_or(0, |v| v.expect_version()) ); + for shard_id in 0..NUM_STATE_SHARDS { + println!( + "-- Shard {shard_id}: {:?}", + state_kv_db + .db_shard(shard_id) + .get::(&DbMetadataKey::StateKvShardPrunerProgress(shard_id))? + .map(|v| v.expect_version()) + ); + } + println!( "StateMerklePruner Progress: {:?}", state_merkle_db @@ -89,6 +151,18 @@ impl Cmd { .map_or(0, |v| v.expect_version()) ); + for shard_id in 0..NUM_STATE_SHARDS { + println!( + "-- Shard {shard_id}: {:?}", + state_merkle_db + .db_shard(shard_id) + .get::(&DbMetadataKey::StateMerkleShardPrunerProgress( + shard_id + ))? + .map(|v| v.expect_version()) + ); + } + println!( "EpochEndingStateMerkle Pruner Progress: {:?}", state_merkle_db @@ -97,6 +171,18 @@ impl Cmd { .map_or(0, |v| v.expect_version()) ); + for shard_id in 0..NUM_STATE_SHARDS { + println!( + "-- Shard {shard_id}: {:?}", + state_merkle_db + .db_shard(shard_id) + .get::( + &DbMetadataKey::EpochEndingStateMerkleShardPrunerProgress(shard_id) + )? + .map(|v| v.expect_version()) + ); + } + println!( "Current ledger info: {:?}", ledger_db.metadata_db().get_latest_ledger_info_option() diff --git a/storage/aptosdb/src/db_debugger/examine/print_raw_data_by_version.rs b/storage/aptosdb/src/db_debugger/examine/print_raw_data_by_version.rs new file mode 100644 index 00000000000..689b5b13236 --- /dev/null +++ b/storage/aptosdb/src/db_debugger/examine/print_raw_data_by_version.rs @@ -0,0 +1,79 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{db_debugger::ShardingConfig, AptosDB}; +use aptos_config::config::{RocksdbConfigs, StorageDirPaths}; +use aptos_storage_interface::Result; +use clap::Parser; +use std::path::PathBuf; + +#[derive(Parser)] +#[clap(about = "Print the version of each types of data.")] +pub struct Cmd { + #[clap(long, value_parser)] + db_dir: PathBuf, + + #[clap(flatten)] + sharding_config: ShardingConfig, + + #[clap(long)] + version: u64, +} + +impl Cmd { + pub fn run(self) -> Result<()> { + let rocksdb_config = RocksdbConfigs { + enable_storage_sharding: self.sharding_config.enable_storage_sharding, + ..Default::default() + }; + let env = None; + let block_cache = None; + + let (ledger_db, _, _) = AptosDB::open_dbs( + &StorageDirPaths::from_path(&self.db_dir), + rocksdb_config, + env, + block_cache, + /*readonly=*/ true, + /*max_num_nodes_per_lru_cache_shard=*/ 0, + )?; + + println!( + "Transaction: {:?}", + ledger_db.transaction_db().get_transaction(self.version)? + ); + + println!( + "PersistedAuxiliaryInfo: {:?}", + ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info(self.version)? + ); + + println!( + "WriteSet: {:?}", + ledger_db.write_set_db().get_write_set(self.version)? + ); + + println!( + "Events: {:?}", + ledger_db.event_db().get_events_by_version(self.version)? + ); + + println!( + "TransactionInfo: {:?}", + ledger_db + .transaction_info_db() + .get_transaction_info(self.version)? + ); + + println!( + "TransactionAccumulatorHash: {:?}", + ledger_db + .transaction_accumulator_db() + .get_root_hash(self.version)? + ); + + Ok(()) + } +} diff --git a/storage/aptosdb/src/db_debugger/state_kv/get_value.rs b/storage/aptosdb/src/db_debugger/state_kv/get_value.rs index 78490fd88f7..2d98784d924 100644 --- a/storage/aptosdb/src/db_debugger/state_kv/get_value.rs +++ b/storage/aptosdb/src/db_debugger/state_kv/get_value.rs @@ -3,9 +3,14 @@ use crate::db_debugger::common::DbDir; use aptos_storage_interface::Result; -use aptos_types::{state_store::state_key::StateKey, transaction::Version}; +use aptos_types::{ + state_store::{state_key::StateKey, state_value::StateValue}, + transaction::Version, +}; use clap::Parser; +use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; use owo_colors::OwoColorize; +use std::str::FromStr; #[derive(Parser)] #[clap(about = "Print state value by given key and version.")] @@ -14,7 +19,13 @@ pub struct Cmd { db_dir: DbDir, #[clap(long)] - key_hex: String, + key_hex: Option, + + #[clap(long)] + address: String, + + #[clap(long)] + struct_tag: String, #[clap(long)] version: Version, @@ -22,6 +33,7 @@ pub struct Cmd { impl Cmd { pub fn run(self) -> Result<()> { + /* let key_vec = hex::decode(&self.key_hex).unwrap(); let key: StateKey = bcs::from_bytes(&key_vec)?; println!( @@ -31,7 +43,11 @@ impl Cmd { key, self.version, ) .yellow() - ); + );*/ + + let address = AccountAddress::from_hex_literal(&self.address).unwrap(); + let struct_tag = StructTag::from_str(&self.struct_tag)?; + let key = StateKey::resource(&address, &struct_tag)?; let ledger_db = self.db_dir.open_ledger_db()?; let db = self.db_dir.open_state_kv_db()?; @@ -51,22 +67,38 @@ impl Cmd { ); } - match db.get_state_value_with_version_by_version(&key, self.version)? { - None => { - println!("{}", "Value not found.".to_string().yellow()); - }, - Some((version, value)) => { - println!("{}", "Value found:".to_string().yellow()); - println!(" version: {version}"); - if value.bytes().len() > 1024 { - println!(" value: {} bytes", value.bytes().len()) - } else { - println!(" value: {:?}", value.bytes()) - } - println!(" metadata: {:?}", value.into_metadata()); - }, + let mut start_version = self.version; + let mut count = 0; + while count < 10 { + match db.get_state_value_with_version_by_version(&key, start_version)? { + None => { + if count == 0 { + println!("{}", "Value not found.".to_string().yellow()); + } + break; + }, + Some((version, value)) => { + Self::print_value(version, value); + count += 1; + if version == 0 { + break; + } + start_version = version - 1; + }, + } } Ok(()) } + + pub fn print_value(version: u64, value: StateValue) { + println!("{}", "Value found:".to_string().yellow()); + println!(" version: {version}"); + if value.bytes().len() > 1024 { + println!(" value: {} bytes", value.bytes().len()) + } else { + println!(" value: {:?}", value.bytes()) + } + println!(" metadata: {:?}", value.into_metadata()); + } } diff --git a/storage/aptosdb/src/db_debugger/truncate/mod.rs b/storage/aptosdb/src/db_debugger/truncate/mod.rs index c7c8c23498f..8c873f9b389 100644 --- a/storage/aptosdb/src/db_debugger/truncate/mod.rs +++ b/storage/aptosdb/src/db_debugger/truncate/mod.rs @@ -68,9 +68,13 @@ impl Cmd { enable_storage_sharding: self.sharding_config.enable_storage_sharding, ..Default::default() }; + let env = None; + let block_cache = None; let (ledger_db, state_merkle_db, state_kv_db) = AptosDB::open_dbs( &StorageDirPaths::from_path(&self.db_dir), rocksdb_config, + env, + block_cache, /*readonly=*/ false, /*max_num_nodes_per_lru_cache_shard=*/ 0, )?; @@ -174,8 +178,9 @@ mod test { }, utils::truncation_helper::num_frozen_nodes_in_accumulator, }; - use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, DbReader}; + use aptos_storage_interface::DbReader; use aptos_temppath::TempPath; + use aptos_types::state_store::NUM_STATE_SHARDS; use proptest::prelude::*; proptest! { @@ -226,10 +231,10 @@ mod test { prop_assert!(db_version <= target_version); target_version = db_version; - let txn_list_with_proof = db.get_transactions(0, db_version + 1, db_version, true).unwrap(); + let txn_list_with_proof = db.get_transactions(0, db_version + 1, db_version, true).unwrap().into_parts().0; prop_assert_eq!(txn_list_with_proof.transactions.len() as u64, db_version + 1); - prop_assert_eq!(txn_list_with_proof.events.unwrap().len() as u64, db_version + 1); - prop_assert_eq!(txn_list_with_proof.first_transaction_version, Some(0)); + prop_assert_eq!(txn_list_with_proof.clone().events.unwrap().len() as u64, db_version + 1); + prop_assert_eq!(txn_list_with_proof.get_first_transaction_version(), Some(0)); let state_checkpoint_version = db.get_latest_state_checkpoint_version().unwrap().unwrap(); let state_leaf_count = db.get_state_item_count(state_checkpoint_version).unwrap(); @@ -241,12 +246,16 @@ mod test { drop(db); + let env = None; + let block_cache = None; let (ledger_db, state_merkle_db, state_kv_db) = AptosDB::open_dbs( &StorageDirPaths::from_path(tmp_dir.path()), RocksdbConfigs { enable_storage_sharding: input.1, ..Default::default() }, + env, + block_cache, /*readonly=*/ false, /*max_num_nodes_per_lru_cache_shard=*/ 0, ).unwrap(); @@ -338,7 +347,7 @@ mod test { if sharding_config.enable_storage_sharding { let state_merkle_db = Arc::new(state_merkle_db); - for i in 0..NUM_STATE_SHARDS as u8 { + for i in 0..NUM_STATE_SHARDS { let mut kv_shard_iter = state_kv_db.db_shard(i).iter::().unwrap(); kv_shard_iter.seek_to_first(); for item in kv_shard_iter { diff --git a/storage/aptosdb/src/db_debugger/validation.rs b/storage/aptosdb/src/db_debugger/validation.rs index 127ddba23f2..072e46086f1 100644 --- a/storage/aptosdb/src/db_debugger/validation.rs +++ b/storage/aptosdb/src/db_debugger/validation.rs @@ -16,7 +16,7 @@ use aptos_storage_interface::{DbReader, Result}; use aptos_types::{ contract_event::ContractEvent, event::EventKey, - transaction::{Transaction::UserTransaction, TransactionListWithProof}, + transaction::{Transaction::UserTransaction, TransactionListWithProofV2}, }; use rayon::{ iter::{IntoParallelIterator, ParallelIterator}, @@ -105,7 +105,7 @@ pub fn validate_db_data( .unwrap(); verify_batch_txn_events(&txns, &internal_db, start) .unwrap_or_else(|_| panic!("{}, {} failed to verify", start, end)); - assert_eq!(txns.transactions.len() as u64, num_of_txns); + assert_eq!(txns.get_num_transactions() as u64, num_of_txns); }); Ok(()) @@ -118,7 +118,8 @@ pub fn verify_state_kvs( ) -> Result<()> { println!("Validating db statekeys"); let storage_dir = StorageDirPaths::from_path(db_root_path); - let state_kv_db = StateKvDb::open_sharded(&storage_dir, RocksdbConfig::default(), false)?; + let state_kv_db = + StateKvDb::open_sharded(&storage_dir, RocksdbConfig::default(), None, None, false)?; //read all statekeys from internal db and store them in mem let mut all_internal_keys = HashSet::new(); @@ -145,7 +146,7 @@ pub fn verify_state_kvs( } pub fn verify_batch_txn_events( - txns: &TransactionListWithProof, + txns: &TransactionListWithProofV2, internal_db: &DB, start_version: u64, ) -> Result<()> { @@ -190,11 +191,16 @@ fn verify_state_kv( } fn verify_transactions( - transaction_list: &TransactionListWithProof, + transaction_list: &TransactionListWithProofV2, internal_indexer_db: &DB, start_version: u64, ) -> Result<()> { - for (idx, txn) in transaction_list.transactions.iter().enumerate() { + for (idx, txn) in transaction_list + .get_transaction_list_with_proof() + .transactions + .iter() + .enumerate() + { match txn { UserTransaction(signed_transaction) => { let key = ( @@ -268,12 +274,12 @@ fn verify_event_by_version( } fn verify_events( - transaction_list: &TransactionListWithProof, + transaction_list: &TransactionListWithProofV2, internal_indexer_db: &DB, start_version: u64, ) -> Result<()> { let mut version = start_version; - match &transaction_list.events { + match &transaction_list.get_transaction_list_with_proof().events { None => { return Ok(()); }, diff --git a/storage/aptosdb/src/db_options.rs b/storage/aptosdb/src/db_options.rs index 0d59eaad0ca..af11eff9e88 100644 --- a/storage/aptosdb/src/db_options.rs +++ b/storage/aptosdb/src/db_options.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::schema::*; -use aptos_config::config::RocksdbConfig; +use aptos_config::config::{IndexType, RocksdbConfig}; use aptos_schemadb::{ - BlockBasedOptions, Cache, ColumnFamilyDescriptor, ColumnFamilyName, DBCompressionType, Options, - SliceTransform, DEFAULT_COLUMN_FAMILY_NAME, + BlockBasedIndexType, BlockBasedOptions, Cache, ColumnFamilyDescriptor, ColumnFamilyName, + DBCompressionType, Options, SliceTransform, DEFAULT_COLUMN_FAMILY_NAME, }; use aptos_types::transaction::Version; @@ -22,6 +22,7 @@ pub(super) fn ledger_db_column_families() -> Vec { EVENT_BY_VERSION_CF_NAME, EVENT_CF_NAME, LEDGER_INFO_CF_NAME, + PERSISTED_AUXILIARY_INFO_CF_NAME, STALE_STATE_VALUE_INDEX_CF_NAME, STATE_VALUE_CF_NAME, TRANSACTION_CF_NAME, @@ -49,6 +50,14 @@ pub(super) fn event_db_column_families() -> Vec { ] } +pub(super) fn persisted_auxiliary_info_db_column_families() -> Vec { + vec![ + /* empty cf */ DEFAULT_COLUMN_FAMILY_NAME, + DB_METADATA_CF_NAME, + PERSISTED_AUXILIARY_INFO_CF_NAME, + ] +} + pub(super) fn transaction_accumulator_db_column_families() -> Vec { vec![ /* empty cf */ DEFAULT_COLUMN_FAMILY_NAME, @@ -148,19 +157,17 @@ pub(super) fn hot_state_kv_db_column_families() -> Vec { fn gen_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, cfs: Vec, cf_opts_post_processor: F, ) -> Vec where F: Fn(ColumnFamilyName, &mut Options), { - let mut table_options = BlockBasedOptions::default(); - table_options.set_cache_index_and_filter_blocks(rocksdb_config.cache_index_and_filter_blocks); - table_options.set_block_size(rocksdb_config.block_size as usize); - let cache = Cache::new_lru_cache(rocksdb_config.block_cache_size as usize); - table_options.set_block_cache(&cache); let mut cfds = Vec::with_capacity(cfs.len()); for cf_name in cfs { + let table_options = gen_table_options(rocksdb_config, block_cache, cf_name); + let mut cf_opts = Options::default(); cf_opts.set_compression_type(DBCompressionType::Lz4); cf_opts.set_block_based_table_factory(&table_options); @@ -171,6 +178,50 @@ where cfds } +fn gen_table_options( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, + cf_name: ColumnFamilyName, +) -> BlockBasedOptions { + let mut table_options = BlockBasedOptions::default(); + + table_options.set_block_size(rocksdb_config.block_size as usize); + + table_options.set_index_type(convert_index_type(rocksdb_config.index_type)); + table_options.set_partition_filters(rocksdb_config.partition_filters); + table_options.set_cache_index_and_filter_blocks(rocksdb_config.cache_index_and_filter_blocks); + table_options.set_pin_l0_filter_and_index_blocks_in_cache( + rocksdb_config.pin_l0_filter_and_index_blocks_in_cache, + ); + + if let Some(cache) = block_cache { + table_options.set_block_cache(cache); + } + + if let Some(bits) = rocksdb_config.bloom_filter_bits { + match rocksdb_config.bloom_before_level { + Some(level) => table_options.set_hybrid_ribbon_filter(bits, level), + None => table_options.set_bloom_filter(bits, /* block_based = */ false), + } + } + + if cf_name == STATE_VALUE_BY_KEY_HASH_CF_NAME || cf_name == HOT_STATE_VALUE_BY_KEY_HASH_CF_NAME + { + // We do not generally perform point queries on these tables. + table_options.set_whole_key_filtering(false); + } + + table_options +} + +fn convert_index_type(index_type: IndexType) -> BlockBasedIndexType { + match index_type { + IndexType::BinarySearch => BlockBasedIndexType::BinarySearch, + IndexType::HashSearch => BlockBasedIndexType::HashSearch, + IndexType::TwoLevelIndexSearch => BlockBasedIndexType::TwoLevelIndexSearch, + } +} + fn with_state_key_extractor_processor(cf_name: ColumnFamilyName, cf_opts: &mut Options) { if cf_name == STATE_VALUE_CF_NAME || cf_name == STATE_VALUE_BY_KEY_HASH_CF_NAME @@ -186,68 +237,112 @@ fn state_key_extractor(state_value_raw_key: &[u8]) -> &[u8] { &state_value_raw_key[..(state_value_raw_key.len() - VERSION_SIZE)] } -pub(super) fn gen_event_cfds(rocksdb_config: &RocksdbConfig) -> Vec { +pub(super) fn gen_event_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { let cfs = event_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) +} + +pub(super) fn gen_persisted_auxiliary_info_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { + let cfs = persisted_auxiliary_info_db_column_families(); + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } pub(super) fn gen_transaction_accumulator_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = transaction_accumulator_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } pub(super) fn gen_transaction_auxiliary_data_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = transaction_auxiliary_data_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } -pub(super) fn gen_transaction_cfds(rocksdb_config: &RocksdbConfig) -> Vec { +pub(super) fn gen_transaction_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { let cfs = transaction_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } pub(super) fn gen_transaction_info_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = transaction_info_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } -pub(super) fn gen_write_set_cfds(rocksdb_config: &RocksdbConfig) -> Vec { +pub(super) fn gen_write_set_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { let cfs = write_set_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } pub(super) fn gen_ledger_metadata_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = ledger_metadata_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } -pub(super) fn gen_ledger_cfds(rocksdb_config: &RocksdbConfig) -> Vec { +pub(super) fn gen_ledger_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { let cfs = ledger_db_column_families(); - gen_cfds(rocksdb_config, cfs, with_state_key_extractor_processor) + gen_cfds( + rocksdb_config, + block_cache, + cfs, + with_state_key_extractor_processor, + ) } -pub(super) fn gen_state_merkle_cfds(rocksdb_config: &RocksdbConfig) -> Vec { +pub(super) fn gen_state_merkle_cfds( + rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, +) -> Vec { let cfs = state_merkle_db_column_families(); - gen_cfds(rocksdb_config, cfs, |_, _| {}) + gen_cfds(rocksdb_config, block_cache, cfs, |_, _| {}) } pub(super) fn gen_state_kv_shard_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = state_kv_db_new_key_column_families(); - gen_cfds(rocksdb_config, cfs, with_state_key_extractor_processor) + gen_cfds( + rocksdb_config, + block_cache, + cfs, + with_state_key_extractor_processor, + ) } pub(super) fn gen_hot_state_kv_shard_cfds( rocksdb_config: &RocksdbConfig, + block_cache: Option<&Cache>, ) -> Vec { let cfs = hot_state_kv_db_column_families(); - gen_cfds(rocksdb_config, cfs, with_state_key_extractor_processor) + gen_cfds( + rocksdb_config, + block_cache, + cfs, + with_state_key_extractor_processor, + ) } diff --git a/storage/aptosdb/src/event_store/test.rs b/storage/aptosdb/src/event_store/test.rs index 167648bd7d5..e3fcbd60d26 100644 --- a/storage/aptosdb/src/event_store/test.rs +++ b/storage/aptosdb/src/event_store/test.rs @@ -84,7 +84,7 @@ proptest! { .into_iter() .map(|gens| { gens.into_iter() - .map(|(index, gen)| gen.materialize(*index, &mut universe)) + .map(|(index, r#gen)| r#gen.materialize(*index, &mut universe)) .collect() }) .collect(); @@ -238,7 +238,7 @@ fn test_get_last_version_before_timestamp_impl(new_block_events: Vec<(Version, C event_db .put_events( *ver, - &[event.clone()], + std::slice::from_ref(event), /*skip_index=*/ false, &mut batch, ) @@ -270,7 +270,7 @@ fn test_get_last_version_before_timestamp_impl(new_block_events: Vec<(Version, C } assert_eq!( store - .get_last_version_before_timestamp((last_block_ts + ts + 1) / 2, ledger_version) + .get_last_version_before_timestamp((last_block_ts + ts).div_ceil(2), ledger_version) .unwrap(), version - 1, ); diff --git a/storage/aptosdb/src/fast_sync_storage_wrapper.rs b/storage/aptosdb/src/fast_sync_storage_wrapper.rs index d1a42ebf14e..6d8a3f7ee36 100644 --- a/storage/aptosdb/src/fast_sync_storage_wrapper.rs +++ b/storage/aptosdb/src/fast_sync_storage_wrapper.rs @@ -13,7 +13,7 @@ use aptos_storage_interface::{ use aptos_types::{ ledger_info::LedgerInfoWithSignatures, state_store::{state_key::StateKey, state_value::StateValue}, - transaction::{TransactionOutputListWithProof, Version}, + transaction::{TransactionOutputListWithProofV2, Version}, }; use either::Either; use std::{sync::Arc, time::Instant}; @@ -152,7 +152,7 @@ impl DbWriter for FastSyncStorageWrapper { fn finalize_state_snapshot( &self, version: Version, - output_with_proof: TransactionOutputListWithProof, + output_with_proof: TransactionOutputListWithProofV2, ledger_infos: &[LedgerInfoWithSignatures], ) -> Result<()> { let status = self.get_fast_sync_status(); diff --git a/storage/aptosdb/src/ledger_db/event_db.rs b/storage/aptosdb/src/ledger_db/event_db.rs index 52b4e3d078c..913b89d8ff2 100644 --- a/storage/aptosdb/src/ledger_db/event_db.rs +++ b/storage/aptosdb/src/ledger_db/event_db.rs @@ -101,7 +101,7 @@ impl EventDb { &self, start_version: Version, num_versions: usize, - ) -> Result { + ) -> Result> { let mut iter = self.db.iter::()?; iter.seek(&start_version)?; diff --git a/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs b/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs index 9cbe3651b3b..df564634cab 100644 --- a/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs +++ b/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs @@ -125,7 +125,7 @@ impl LedgerMetadataDb { &self, start_epoch: u64, end_epoch: u64, - ) -> Result { + ) -> Result> { let mut iter = self.db.iter::()?; iter.seek(&start_epoch)?; Ok(EpochEndingLedgerInfoIter::new(iter, start_epoch, end_epoch)) diff --git a/storage/aptosdb/src/ledger_db/mod.rs b/storage/aptosdb/src/ledger_db/mod.rs index afc68ad8858..1bc3a2db8ca 100644 --- a/storage/aptosdb/src/ledger_db/mod.rs +++ b/storage/aptosdb/src/ledger_db/mod.rs @@ -7,16 +7,17 @@ use crate::{ db_options::{ event_db_column_families, gen_event_cfds, gen_ledger_cfds, gen_ledger_metadata_cfds, - gen_transaction_accumulator_cfds, gen_transaction_auxiliary_data_cfds, - gen_transaction_cfds, gen_transaction_info_cfds, gen_write_set_cfds, - ledger_db_column_families, ledger_metadata_db_column_families, - transaction_accumulator_db_column_families, transaction_auxiliary_data_db_column_families, - transaction_db_column_families, transaction_info_db_column_families, - write_set_db_column_families, + gen_persisted_auxiliary_info_cfds, gen_transaction_accumulator_cfds, + gen_transaction_auxiliary_data_cfds, gen_transaction_cfds, gen_transaction_info_cfds, + gen_write_set_cfds, ledger_db_column_families, ledger_metadata_db_column_families, + persisted_auxiliary_info_db_column_families, transaction_accumulator_db_column_families, + transaction_auxiliary_data_db_column_families, transaction_db_column_families, + transaction_info_db_column_families, write_set_db_column_families, }, event_store::EventStore, ledger_db::{ event_db::EventDb, ledger_metadata_db::LedgerMetadataDb, + persisted_auxiliary_info_db::PersistedAuxiliaryInfoDb, transaction_accumulator_db::TransactionAccumulatorDb, transaction_auxiliary_data_db::TransactionAuxiliaryDataDb, transaction_db::TransactionDb, transaction_info_db::TransactionInfoDb, write_set_db::WriteSetDb, @@ -27,7 +28,9 @@ use aptos_config::config::{RocksdbConfig, RocksdbConfigs}; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::info; use aptos_rocksdb_options::gen_rocksdb_options; -use aptos_schemadb::{batch::SchemaBatch, ColumnFamilyDescriptor, ColumnFamilyName, DB}; +use aptos_schemadb::{ + batch::SchemaBatch, Cache, ColumnFamilyDescriptor, ColumnFamilyName, Env, DB, +}; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::{ @@ -41,6 +44,9 @@ mod event_db_test; pub(crate) mod ledger_metadata_db; #[cfg(test)] mod ledger_metadata_db_test; +pub(crate) mod persisted_auxiliary_info_db; +#[cfg(test)] +mod persisted_auxiliary_info_db_test; pub(crate) mod transaction_accumulator_db; pub(crate) mod transaction_auxiliary_data_db; #[cfg(test)] @@ -59,6 +65,7 @@ pub const LEDGER_DB_FOLDER_NAME: &str = "ledger_db"; pub const LEDGER_DB_NAME: &str = "ledger_db"; pub const LEDGER_METADATA_DB_NAME: &str = "ledger_metadata_db"; pub const EVENT_DB_NAME: &str = "event_db"; +pub const PERSISTED_AUXILIARY_INFO_DB_NAME: &str = "persisted_auxiliary_info_db"; pub const TRANSACTION_ACCUMULATOR_DB_NAME: &str = "transaction_accumulator_db"; pub const TRANSACTION_AUXILIARY_DATA_DB_NAME: &str = "transaction_auxiliary_data_db"; pub const TRANSACTION_DB_NAME: &str = "transaction_db"; @@ -69,6 +76,7 @@ pub const WRITE_SET_DB_NAME: &str = "write_set_db"; pub struct LedgerDbSchemaBatches { pub ledger_metadata_db_batches: SchemaBatch, pub event_db_batches: SchemaBatch, + pub persisted_auxiliary_info_db_batches: SchemaBatch, pub transaction_accumulator_db_batches: SchemaBatch, pub transaction_auxiliary_data_db_batches: SchemaBatch, pub transaction_db_batches: SchemaBatch, @@ -81,6 +89,7 @@ impl Default for LedgerDbSchemaBatches { Self { ledger_metadata_db_batches: SchemaBatch::new(), event_db_batches: SchemaBatch::new(), + persisted_auxiliary_info_db_batches: SchemaBatch::new(), transaction_accumulator_db_batches: SchemaBatch::new(), transaction_auxiliary_data_db_batches: SchemaBatch::new(), transaction_db_batches: SchemaBatch::new(), @@ -100,6 +109,7 @@ impl LedgerDbSchemaBatches { pub struct LedgerDb { ledger_metadata_db: LedgerMetadataDb, event_db: EventDb, + persisted_auxiliary_info_db: PersistedAuxiliaryInfoDb, transaction_accumulator_db: TransactionAccumulatorDb, transaction_auxiliary_data_db: TransactionAuxiliaryDataDb, transaction_db: TransactionDb, @@ -112,6 +122,8 @@ impl LedgerDb { pub(crate) fn new>( db_root_path: P, rocksdb_configs: RocksdbConfigs, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ) -> Result { let sharding = rocksdb_configs.enable_storage_sharding; @@ -124,6 +136,8 @@ impl LedgerDb { LEDGER_DB_NAME }, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, )?); @@ -141,6 +155,9 @@ impl LedgerDb { Arc::clone(&ledger_metadata_db), EventStore::new(Arc::clone(&ledger_metadata_db)), ), + persisted_auxiliary_info_db: PersistedAuxiliaryInfoDb::new(Arc::clone( + &ledger_metadata_db, + )), transaction_accumulator_db: TransactionAccumulatorDb::new(Arc::clone( &ledger_metadata_db, )), @@ -157,6 +174,7 @@ impl LedgerDb { let ledger_db_folder = db_root_path.as_ref().join(LEDGER_DB_FOLDER_NAME); let mut event_db = None; + let mut persisted_auxiliary_info_db = None; let mut transaction_accumulator_db = None; let mut transaction_auxiliary_data_db = None; let mut transaction_db = None; @@ -169,6 +187,8 @@ impl LedgerDb { ledger_db_folder.join(EVENT_DB_NAME), EVENT_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -178,12 +198,27 @@ impl LedgerDb { EventStore::new(event_db_raw), )); }); + s.spawn(|_| { + persisted_auxiliary_info_db = Some(PersistedAuxiliaryInfoDb::new(Arc::new( + Self::open_rocksdb( + ledger_db_folder.join(PERSISTED_AUXILIARY_INFO_DB_NAME), + PERSISTED_AUXILIARY_INFO_DB_NAME, + &rocksdb_configs.ledger_db_config, + env, + block_cache, + readonly, + ) + .unwrap(), + ))); + }); s.spawn(|_| { transaction_accumulator_db = Some(TransactionAccumulatorDb::new(Arc::new( Self::open_rocksdb( ledger_db_folder.join(TRANSACTION_ACCUMULATOR_DB_NAME), TRANSACTION_ACCUMULATOR_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -195,6 +230,8 @@ impl LedgerDb { ledger_db_folder.join(TRANSACTION_AUXILIARY_DATA_DB_NAME), TRANSACTION_AUXILIARY_DATA_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -206,6 +243,8 @@ impl LedgerDb { ledger_db_folder.join(TRANSACTION_DB_NAME), TRANSACTION_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -217,6 +256,8 @@ impl LedgerDb { ledger_db_folder.join(TRANSACTION_INFO_DB_NAME), TRANSACTION_INFO_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -228,6 +269,8 @@ impl LedgerDb { ledger_db_folder.join(WRITE_SET_DB_NAME), WRITE_SET_DB_NAME, &rocksdb_configs.ledger_db_config, + env, + block_cache, readonly, ) .unwrap(), @@ -240,6 +283,7 @@ impl LedgerDb { Ok(Self { ledger_metadata_db: LedgerMetadataDb::new(ledger_metadata_db), event_db: event_db.unwrap(), + persisted_auxiliary_info_db: persisted_auxiliary_info_db.unwrap(), transaction_accumulator_db: transaction_accumulator_db.unwrap(), transaction_auxiliary_data_db: transaction_auxiliary_data_db.unwrap(), transaction_db: transaction_db.unwrap(), @@ -273,7 +317,15 @@ impl LedgerDb { enable_storage_sharding: sharding, ..Default::default() }; - let ledger_db = Self::new(db_root_path, rocksdb_configs, /*readonly=*/ false)?; + let env = None; + let block_cache = None; + let ledger_db = Self::new( + db_root_path, + rocksdb_configs, + env, + block_cache, + /*readonly=*/ false, + )?; let cp_ledger_db_folder = cp_root_path.as_ref().join(LEDGER_DB_FOLDER_NAME); info!( @@ -294,6 +346,9 @@ impl LedgerDb { ledger_db .event_db() .create_checkpoint(cp_ledger_db_folder.join(EVENT_DB_NAME))?; + ledger_db + .persisted_auxiliary_info_db() + .create_checkpoint(cp_ledger_db_folder.join(PERSISTED_AUXILIARY_INFO_DB_NAME))?; ledger_db .transaction_accumulator_db() .create_checkpoint(cp_ledger_db_folder.join(TRANSACTION_ACCUMULATOR_DB_NAME))?; @@ -318,6 +373,8 @@ impl LedgerDb { pub(crate) fn write_pruner_progress(&self, version: Version) -> Result<()> { info!("Fast sync is done, writing pruner progress {version} for all ledger sub pruners."); self.event_db.write_pruner_progress(version)?; + self.persisted_auxiliary_info_db + .write_pruner_progress(version)?; self.transaction_accumulator_db .write_pruner_progress(version)?; self.transaction_auxiliary_data_db @@ -348,6 +405,14 @@ impl LedgerDb { self.event_db.db() } + pub(crate) fn persisted_auxiliary_info_db(&self) -> &PersistedAuxiliaryInfoDb { + &self.persisted_auxiliary_info_db + } + + pub(crate) fn persisted_auxiliary_info_db_raw(&self) -> &DB { + self.persisted_auxiliary_info_db.db() + } + pub(crate) fn transaction_accumulator_db(&self) -> &TransactionAccumulatorDb { &self.transaction_accumulator_db } @@ -393,21 +458,23 @@ impl LedgerDb { path: PathBuf, name: &str, db_config: &RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ) -> Result { let db = if readonly { DB::open_cf_readonly( - &gen_rocksdb_options(db_config, true), + &gen_rocksdb_options(db_config, env, true), path.clone(), name, - Self::gen_cfds_by_name(db_config, name), + Self::gen_cfds_by_name(db_config, block_cache, name), )? } else { DB::open_cf( - &gen_rocksdb_options(db_config, false), + &gen_rocksdb_options(db_config, env, false), path.clone(), name, - Self::gen_cfds_by_name(db_config, name), + Self::gen_cfds_by_name(db_config, block_cache, name), )? }; @@ -421,6 +488,7 @@ impl LedgerDb { LEDGER_DB_NAME => ledger_db_column_families(), LEDGER_METADATA_DB_NAME => ledger_metadata_db_column_families(), EVENT_DB_NAME => event_db_column_families(), + PERSISTED_AUXILIARY_INFO_DB_NAME => persisted_auxiliary_info_db_column_families(), TRANSACTION_ACCUMULATOR_DB_NAME => transaction_accumulator_db_column_families(), TRANSACTION_AUXILIARY_DATA_DB_NAME => transaction_auxiliary_data_db_column_families(), TRANSACTION_DB_NAME => transaction_db_column_families(), @@ -430,16 +498,23 @@ impl LedgerDb { } } - fn gen_cfds_by_name(db_config: &RocksdbConfig, name: &str) -> Vec { + fn gen_cfds_by_name( + db_config: &RocksdbConfig, + cache: Option<&Cache>, + name: &str, + ) -> Vec { match name { - LEDGER_DB_NAME => gen_ledger_cfds(db_config), - LEDGER_METADATA_DB_NAME => gen_ledger_metadata_cfds(db_config), - EVENT_DB_NAME => gen_event_cfds(db_config), - TRANSACTION_ACCUMULATOR_DB_NAME => gen_transaction_accumulator_cfds(db_config), - TRANSACTION_AUXILIARY_DATA_DB_NAME => gen_transaction_auxiliary_data_cfds(db_config), - TRANSACTION_DB_NAME => gen_transaction_cfds(db_config), - TRANSACTION_INFO_DB_NAME => gen_transaction_info_cfds(db_config), - WRITE_SET_DB_NAME => gen_write_set_cfds(db_config), + LEDGER_DB_NAME => gen_ledger_cfds(db_config, cache), + LEDGER_METADATA_DB_NAME => gen_ledger_metadata_cfds(db_config, cache), + EVENT_DB_NAME => gen_event_cfds(db_config, cache), + PERSISTED_AUXILIARY_INFO_DB_NAME => gen_persisted_auxiliary_info_cfds(db_config, cache), + TRANSACTION_ACCUMULATOR_DB_NAME => gen_transaction_accumulator_cfds(db_config, cache), + TRANSACTION_AUXILIARY_DATA_DB_NAME => { + gen_transaction_auxiliary_data_cfds(db_config, cache) + }, + TRANSACTION_DB_NAME => gen_transaction_cfds(db_config, cache), + TRANSACTION_INFO_DB_NAME => gen_transaction_info_cfds(db_config, cache), + WRITE_SET_DB_NAME => gen_write_set_cfds(db_config, cache), _ => unreachable!(), } } @@ -460,6 +535,8 @@ impl LedgerDb { .write_schemas(schemas.transaction_info_db_batches)?; self.transaction_db .write_schemas(schemas.transaction_db_batches)?; + self.persisted_auxiliary_info_db + .write_schemas(schemas.persisted_auxiliary_info_db_batches)?; self.event_db.write_schemas(schemas.event_db_batches)?; self.transaction_accumulator_db .write_schemas(schemas.transaction_accumulator_db_batches)?; diff --git a/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db.rs b/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db.rs new file mode 100644 index 00000000000..8ada4875cd4 --- /dev/null +++ b/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db.rs @@ -0,0 +1,127 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + metrics::OTHER_TIMERS_SECONDS, + schema::{ + db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, + persisted_auxiliary_info::PersistedAuxiliaryInfoSchema, + }, + utils::iterators::ExpectContinuousVersions, +}; +use aptos_metrics_core::TimerHelper; +use aptos_schemadb::{batch::SchemaBatch, DB}; +use aptos_storage_interface::Result; +use aptos_types::transaction::{PersistedAuxiliaryInfo, Version}; +use std::{path::Path, sync::Arc}; + +#[derive(Debug)] +pub(crate) struct PersistedAuxiliaryInfoDb { + db: Arc, +} + +impl PersistedAuxiliaryInfoDb { + pub(super) fn new(db: Arc) -> Self { + Self { db } + } + + pub(super) fn create_checkpoint(&self, path: impl AsRef) -> Result<()> { + self.db.create_checkpoint(path) + } + + pub(super) fn write_pruner_progress(&self, version: Version) -> Result<()> { + self.db.put::( + &DbMetadataKey::PersistedAuxiliaryInfoPrunerProgress, + &DbMetadataValue::Version(version), + ) + } + + pub(super) fn db(&self) -> &DB { + &self.db + } + + pub(crate) fn write_schemas(&self, batch: SchemaBatch) -> Result<()> { + self.db.write_schemas(batch) + } + + pub(crate) fn get_persisted_auxiliary_info( + &self, + version: Version, + ) -> Result> { + self.db.get::(&version) + } + + /// Returns an iterator that yields `num_persisted_auxiliary_info` persisted_auxiliary_info + /// starting from `start_version`. + /// + /// Requires the caller to not query the data beyond the latest version. + pub(crate) fn get_persisted_auxiliary_info_iter( + &self, + start_version: Version, + num_persisted_auxiliary_info: usize, + ) -> Result> + '_>> { + let mut iter = self.db.iter::()?; + iter.seek(&start_version)?; + let mut iter = iter.peekable(); + let item = iter.peek(); + let version = if item.is_some() { + item.unwrap().as_ref().map_err(|e| e.clone())?.0 + } else { + let mut iter = self.db.iter::()?; + iter.seek_to_last(); + if iter.next().transpose()?.is_some() { + return Ok(Box::new(std::iter::empty())); + } + // Note in this case we return all Nones. We rely on the caller to not query future + // data when the DB is empty. + // TODO(grao): This will be unreachable in the future, consider make it an error later. + start_version + num_persisted_auxiliary_info as u64 + }; + let num_none = std::cmp::min( + num_persisted_auxiliary_info, + version.saturating_sub(start_version) as usize, + ); + let none_iter = itertools::repeat_n(Ok(PersistedAuxiliaryInfo::None), num_none); + Ok(Box::new(none_iter.chain(iter.expect_continuous_versions( + start_version + num_none as u64, + num_persisted_auxiliary_info - num_none, + )?))) + } + + pub(crate) fn commit_auxiliary_info( + &self, + first_version: Version, + persisted_auxiliary_info: &[PersistedAuxiliaryInfo], + ) -> Result<()> { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_auxiliary_info"]); + + let mut batch = SchemaBatch::new(); + persisted_auxiliary_info.iter().enumerate().try_for_each( + |(i, aux_info)| -> Result<()> { + let version = first_version + i as u64; + Self::put_persisted_auxiliary_info(version, aux_info, &mut batch) + }, + )?; + + { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_auxiliary_info___commit"]); + self.write_schemas(batch) + } + } + + pub(crate) fn put_persisted_auxiliary_info( + version: Version, + persisted_info: &PersistedAuxiliaryInfo, + batch: &mut SchemaBatch, + ) -> Result<()> { + batch.put::(&version, persisted_info) + } + + /// Deletes the persisted auxiliary info between a range of version in [begin, end) + pub(crate) fn prune(begin: Version, end: Version, batch: &mut SchemaBatch) -> Result<()> { + for version in begin..end { + batch.delete::(&version)?; + } + Ok(()) + } +} diff --git a/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db_test.rs b/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db_test.rs new file mode 100644 index 00000000000..b97a9480a65 --- /dev/null +++ b/storage/aptosdb/src/ledger_db/persisted_auxiliary_info_db_test.rs @@ -0,0 +1,102 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{db::test_helper::put_persisted_auxiliary_info, AptosDB}; +use aptos_temppath::TempPath; +use aptos_types::transaction::PersistedAuxiliaryInfo; +use proptest::{collection::vec, prelude::*}; + +fn get_persisted_auxiliary_info( + db: &AptosDB, + start_version: u64, + count: usize, +) -> Vec { + db.ledger_db + .persisted_auxiliary_info_db() + .get_persisted_auxiliary_info_iter(start_version, count) + .unwrap() + .collect::, _>>() + .unwrap() +} + +#[test] +pub fn test_iterator() { + let tmp_dir = TempPath::new(); + let db = AptosDB::new_for_test(&tmp_dir); + let v1_info = PersistedAuxiliaryInfo::V1 { + transaction_index: 0, + }; + + { + assert_eq!( + get_persisted_auxiliary_info(&db, 90, 20), + vec![PersistedAuxiliaryInfo::None; 20] + ); + } + + let persisted_info = vec![v1_info; 100]; + put_persisted_auxiliary_info(&db, 100, &persisted_info); + + { + let mut expected = vec![]; + for _ in 0..10 { + expected.push(PersistedAuxiliaryInfo::None); + } + for _ in 0..10 { + expected.push(v1_info); + } + assert_eq!(get_persisted_auxiliary_info(&db, 90, 20), expected); + } + + assert_eq!( + get_persisted_auxiliary_info(&db, 0, 20), + vec![PersistedAuxiliaryInfo::None; 20] + ); + + assert_eq!(get_persisted_auxiliary_info(&db, 100, 20), vec![ + v1_info; + 20 + ]); + + assert_eq!(get_persisted_auxiliary_info(&db, 190, 20), vec![ + v1_info; + 10 + ]); + + assert_eq!(get_persisted_auxiliary_info(&db, 200, 20), vec![]); +} + +proptest! { + #![proptest_config(ProptestConfig::with_cases(10))] + + #[test] + fn test_persisted_auxiliary_info_get_iterator( + (persisted_info, start_version, num_transactions) in + vec(any::(), 1..100) + .prop_flat_map(|info| { + let num_txns = info.len() as u64; + (Just(info), 0..num_txns) + }) + .prop_flat_map(|(info, start_version)| { + let num_txns = info.len() as u64; + (Just(info), Just(start_version), 0..num_txns as usize * 2) + }) + ) { + let tmp_dir = TempPath::new(); + let db = AptosDB::new_for_test(&tmp_dir); + put_persisted_auxiliary_info(&db, 0, &persisted_info); + + let iter = db.ledger_db.persisted_auxiliary_info_db() + .get_persisted_auxiliary_info_iter(start_version, num_transactions) + .unwrap(); + prop_assert_eq!( + persisted_info + .into_iter() + .skip(start_version as usize) + .take(num_transactions) + .collect::>(), + iter.collect::, _>>().unwrap() + ); + } +} diff --git a/storage/aptosdb/src/ledger_db/transaction_db_test.rs b/storage/aptosdb/src/ledger_db/transaction_db_test.rs index 8595b0c6c9d..98cf796c2ef 100644 --- a/storage/aptosdb/src/ledger_db/transaction_db_test.rs +++ b/storage/aptosdb/src/ledger_db/transaction_db_test.rs @@ -137,8 +137,8 @@ pub(crate) fn init_db( ) -> Vec { let txns = gens .into_iter() - .map(|(index, gen)| { - Transaction::UserTransaction(gen.materialize(*index, &mut universe).into_inner()) + .map(|(index, r#gen)| { + Transaction::UserTransaction(r#gen.materialize(*index, &mut universe).into_inner()) }) .collect::>(); diff --git a/storage/aptosdb/src/lru_node_cache.rs b/storage/aptosdb/src/lru_node_cache.rs index 7ec7e4f4ac9..3ae37b2ef87 100644 --- a/storage/aptosdb/src/lru_node_cache.rs +++ b/storage/aptosdb/src/lru_node_cache.rs @@ -6,7 +6,7 @@ use aptos_infallible::Mutex; use aptos_jellyfish_merkle::node_type::NodeKey; use aptos_types::{nibble::nibble_path::NibblePath, transaction::Version}; use lru::LruCache; -use std::fmt; +use std::{fmt, num::NonZeroUsize}; const NUM_SHARDS: usize = 256; @@ -21,7 +21,7 @@ impl fmt::Debug for LruNodeCache { } impl LruNodeCache { - pub fn new(max_nodes_per_shard: usize) -> Self { + pub fn new(max_nodes_per_shard: NonZeroUsize) -> Self { Self { // `arr!()` doesn't allow a const in place of the integer literal shards: arr_macro::arr![Mutex::new(LruCache::new(max_nodes_per_shard)); 256], @@ -39,14 +39,13 @@ impl LruNodeCache { pub fn get(&self, node_key: &NodeKey) -> Option { let mut r = self.shards[Self::shard(node_key.nibble_path()) as usize].lock(); - let ret = r.get(node_key.nibble_path()).and_then(|(version, node)| { + r.get(node_key.nibble_path()).and_then(|(version, node)| { if *version == node_key.version() { Some(node.clone()) } else { None } - }); - ret + }) } pub fn put(&self, node_key: NodeKey, node: Node) { diff --git a/storage/aptosdb/src/metrics.rs b/storage/aptosdb/src/metrics.rs index 875fd5d4ee0..e6da8b9ff61 100644 --- a/storage/aptosdb/src/metrics.rs +++ b/storage/aptosdb/src/metrics.rs @@ -3,9 +3,9 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_metrics_core::{ - exponential_buckets, register_histogram_vec, register_int_counter, register_int_counter_vec, - register_int_gauge, register_int_gauge_vec, HistogramVec, IntCounter, IntCounterVec, IntGauge, - IntGaugeVec, + exponential_buckets, make_thread_local_histogram_vec, make_thread_local_int_counter_vec, + register_histogram_vec, register_int_counter, register_int_gauge, register_int_gauge_vec, + HistogramVec, IntCounter, IntGauge, IntGaugeVec, }; use once_cell::sync::Lazy; @@ -130,18 +130,17 @@ pub static OTHER_TIMERS_SECONDS: Lazy = Lazy::new(|| { .unwrap() }); -pub static NODE_CACHE_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_storage_node_cache_seconds", - // metric description - "Latency of node cache.", - // metric labels (dimensions) - &["tag", "name"], - exponential_buckets(/*start=*/ 1e-9, /*factor=*/ 2.0, /*count=*/ 30).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + NODE_CACHE_SECONDS, + // metric name + "aptos_storage_node_cache_seconds", + // metric description + "Latency of node cache.", + // metric labels (dimensions) + &["tag", "name"], + exponential_buckets(/*start=*/ 1e-9, /*factor=*/ 2.0, /*count=*/ 30).unwrap(), +); /// Rocksdb metrics pub static ROCKSDB_PROPERTIES: Lazy = Lazy::new(|| { @@ -243,14 +242,13 @@ pub static GAUGE: Lazy = Lazy::new(|| { register_int_gauge_vec!("aptos_storage_gauge", "Various gauges", &["name"]).unwrap() }); -pub static COUNTER: Lazy = Lazy::new(|| { - register_int_counter_vec!( - // metric name - "aptos_storage_counter", - // metric description - "Various counters for Aptos DB / storage.", - // metric labels (dimensions) - &["name"], - ) - .unwrap() -}); +make_thread_local_int_counter_vec!( + pub, + COUNTER, + // metric name + "aptos_storage_counter", + // metric description + "Various counters for Aptos DB / storage.", + // metric labels (dimensions) + &["name"], +); diff --git a/storage/aptosdb/src/pruner/ledger_pruner/mod.rs b/storage/aptosdb/src/pruner/ledger_pruner/mod.rs index 1bd766c93ef..09e522e1596 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/mod.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/mod.rs @@ -4,6 +4,7 @@ mod event_store_pruner; mod ledger_metadata_pruner; pub(crate) mod ledger_pruner_manager; +mod persisted_auxiliary_info_pruner; mod transaction_accumulator_pruner; mod transaction_auxiliary_data_pruner; mod transaction_info_pruner; @@ -18,6 +19,7 @@ use crate::{ db_sub_pruner::DBSubPruner, ledger_pruner::{ event_store_pruner::EventStorePruner, ledger_metadata_pruner::LedgerMetadataPruner, + persisted_auxiliary_info_pruner::PersistedAuxiliaryInfoPruner, transaction_accumulator_pruner::TransactionAccumulatorPruner, transaction_auxiliary_data_pruner::TransactionAuxiliaryDataPruner, transaction_info_pruner::TransactionInfoPruner, transaction_pruner::TransactionPruner, @@ -138,6 +140,10 @@ impl LedgerPruner { metadata_progress, internal_indexer_db.clone(), )?); + let persisted_auxiliary_info_pruner = Box::new(PersistedAuxiliaryInfoPruner::new( + Arc::clone(&ledger_db), + metadata_progress, + )?); let transaction_accumulator_pruner = Box::new(TransactionAccumulatorPruner::new( Arc::clone(&ledger_db), metadata_progress, @@ -169,6 +175,7 @@ impl LedgerPruner { ledger_metadata_pruner, sub_pruners: vec![ event_store_pruner, + persisted_auxiliary_info_pruner, transaction_accumulator_pruner, transaction_auxiliary_data_pruner, transaction_info_pruner, diff --git a/storage/aptosdb/src/pruner/ledger_pruner/persisted_auxiliary_info_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/persisted_auxiliary_info_pruner.rs new file mode 100644 index 00000000000..f422b00ce59 --- /dev/null +++ b/storage/aptosdb/src/pruner/ledger_pruner/persisted_auxiliary_info_pruner.rs @@ -0,0 +1,60 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + ledger_db::{persisted_auxiliary_info_db::PersistedAuxiliaryInfoDb, LedgerDb}, + pruner::{db_sub_pruner::DBSubPruner, pruner_utils::get_or_initialize_subpruner_progress}, + schema::db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, +}; +use aptos_logger::info; +use aptos_schemadb::batch::SchemaBatch; +use aptos_storage_interface::Result; +use aptos_types::transaction::Version; +use std::sync::Arc; + +#[derive(Debug)] +pub struct PersistedAuxiliaryInfoPruner { + ledger_db: Arc, +} + +impl DBSubPruner for PersistedAuxiliaryInfoPruner { + fn name(&self) -> &str { + "PersistedAuxiliaryInfoPruner" + } + + fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { + let mut batch = SchemaBatch::new(); + PersistedAuxiliaryInfoDb::prune(current_progress, target_version, &mut batch)?; + batch.put::( + &DbMetadataKey::PersistedAuxiliaryInfoPrunerProgress, + &DbMetadataValue::Version(target_version), + )?; + self.ledger_db + .persisted_auxiliary_info_db() + .write_schemas(batch) + } +} + +impl PersistedAuxiliaryInfoPruner { + pub(in crate::pruner) fn new( + ledger_db: Arc, + metadata_progress: Version, + ) -> Result { + let progress = get_or_initialize_subpruner_progress( + ledger_db.persisted_auxiliary_info_db_raw(), + &DbMetadataKey::PersistedAuxiliaryInfoPrunerProgress, + metadata_progress, + )?; + + let myself = PersistedAuxiliaryInfoPruner { ledger_db }; + + info!( + progress = progress, + metadata_progress = metadata_progress, + "Catching up PersistedAuxiliaryInfoPruner." + ); + myself.prune(progress, metadata_progress)?; + + Ok(myself) + } +} diff --git a/storage/aptosdb/src/pruner/pruner_worker.rs b/storage/aptosdb/src/pruner/pruner_worker.rs index 954758b87e3..29cfc468f45 100644 --- a/storage/aptosdb/src/pruner/pruner_worker.rs +++ b/storage/aptosdb/src/pruner/pruner_worker.rs @@ -96,6 +96,7 @@ impl PrunerWorker { } } + #[allow(dead_code)] pub fn is_pruning_pending(&self) -> bool { self.inner.pruner.is_pruning_pending() } diff --git a/storage/aptosdb/src/pruner/state_kv_pruner/mod.rs b/storage/aptosdb/src/pruner/state_kv_pruner/mod.rs index f94760a75e8..96a56348586 100644 --- a/storage/aptosdb/src/pruner/state_kv_pruner/mod.rs +++ b/storage/aptosdb/src/pruner/state_kv_pruner/mod.rs @@ -19,6 +19,7 @@ use crate::{ use anyhow::anyhow; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::info; +use aptos_metrics_core::TimerHelper; use aptos_storage_interface::Result; use aptos_types::transaction::{AtomicVersion, Version}; use rayon::prelude::*; @@ -46,9 +47,7 @@ impl DBPruner for StateKvPruner { } fn prune(&self, max_versions: usize) -> Result { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_kv_pruner__prune"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_kv_pruner__prune"]); let mut progress = self.progress(); let target_version = self.target_version(); @@ -124,7 +123,7 @@ impl StateKvPruner { let shard_pruners = if state_kv_db.enabled_sharding() { let num_shards = state_kv_db.num_shards(); - let mut shard_pruners = Vec::with_capacity(num_shards as usize); + let mut shard_pruners = Vec::with_capacity(num_shards); for shard_id in 0..num_shards { shard_pruners.push(StateKvShardPruner::new( shard_id, diff --git a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs index cf11242544a..8df97146736 100644 --- a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs +++ b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs @@ -17,19 +17,19 @@ use std::sync::Arc; // This pruner is only used when enable_sharding flag is true pub(in crate::pruner) struct StateKvShardPruner { - shard_id: u8, + shard_id: usize, db_shard: Arc, } impl StateKvShardPruner { pub(in crate::pruner) fn new( - shard_id: u8, + shard_id: usize, db_shard: Arc, metadata_progress: Version, ) -> Result { let progress = get_or_initialize_subpruner_progress( &db_shard, - &DbMetadataKey::StateKvShardPrunerProgress(shard_id as usize), + &DbMetadataKey::StateKvShardPrunerProgress(shard_id), metadata_progress, )?; let myself = Self { shard_id, db_shard }; @@ -64,14 +64,14 @@ impl StateKvShardPruner { batch.delete::(&(index.state_key_hash, index.version))?; } batch.put::( - &DbMetadataKey::StateKvShardPrunerProgress(self.shard_id as usize), + &DbMetadataKey::StateKvShardPrunerProgress(self.shard_id), &DbMetadataValue::Version(target_version), )?; self.db_shard.write_schemas(batch) } - pub(in crate::pruner) fn shard_id(&self) -> u8 { + pub(in crate::pruner) fn shard_id(&self) -> usize { self.shard_id } } diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/generics.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/generics.rs index 8c3f62e3fc6..90ce17eb9be 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/generics.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/generics.rs @@ -12,14 +12,14 @@ pub trait StaleNodeIndexSchemaTrait: Schema where StaleNodeIndex: KeyCodec, { - fn progress_metadata_key(shard_id: Option) -> DbMetadataKey; + fn progress_metadata_key(shard_id: Option) -> DbMetadataKey; fn name() -> &'static str; } impl StaleNodeIndexSchemaTrait for StaleNodeIndexSchema { - fn progress_metadata_key(shard_id: Option) -> DbMetadataKey { + fn progress_metadata_key(shard_id: Option) -> DbMetadataKey { if let Some(shard_id) = shard_id { - DbMetadataKey::StateMerkleShardPrunerProgress(shard_id as usize) + DbMetadataKey::StateMerkleShardPrunerProgress(shard_id) } else { DbMetadataKey::StateMerklePrunerProgress } @@ -31,9 +31,9 @@ impl StaleNodeIndexSchemaTrait for StaleNodeIndexSchema { } impl StaleNodeIndexSchemaTrait for StaleNodeIndexCrossEpochSchema { - fn progress_metadata_key(shard_id: Option) -> DbMetadataKey { + fn progress_metadata_key(shard_id: Option) -> DbMetadataKey { if let Some(shard_id) = shard_id { - DbMetadataKey::EpochEndingStateMerkleShardPrunerProgress(shard_id as usize) + DbMetadataKey::EpochEndingStateMerkleShardPrunerProgress(shard_id) } else { DbMetadataKey::EpochEndingStateMerklePrunerProgress } diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/mod.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/mod.rs index d4dc3550408..16dac2754dd 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/mod.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/mod.rs @@ -24,6 +24,7 @@ use anyhow::anyhow; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_jellyfish_merkle::{node_type::NodeKey, StaleNodeIndex}; use aptos_logger::info; +use aptos_metrics_core::TimerHelper; use aptos_schemadb::{schema::KeyCodec, DB}; use aptos_storage_interface::Result; use aptos_types::transaction::{AtomicVersion, Version}; @@ -57,9 +58,7 @@ where fn prune(&self, batch_size: usize) -> Result { // TODO(grao): Consider separate pruner metrics, and have a label for pruner name. - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_merkle_pruner__prune"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_merkle_pruner__prune"]); let mut progress = self.progress(); let target_version = self.target_version(); @@ -136,7 +135,7 @@ where let shard_pruners = if state_merkle_db.sharding_enabled() { let num_shards = state_merkle_db.num_shards(); - let mut shard_pruners = Vec::with_capacity(num_shards as usize); + let mut shard_pruners = Vec::with_capacity(num_shards); for shard_id in 0..num_shards { shard_pruners.push(StateMerkleShardPruner::new( shard_id, diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs index 5e83ae6f1fd..ab0e2bcae68 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs @@ -19,7 +19,7 @@ use aptos_types::transaction::Version; use std::{marker::PhantomData, sync::Arc}; pub(in crate::pruner) struct StateMerkleShardPruner { - shard_id: u8, + shard_id: usize, db_shard: Arc, _phantom: PhantomData, } @@ -29,7 +29,7 @@ where StaleNodeIndex: KeyCodec, { pub(in crate::pruner) fn new( - shard_id: u8, + shard_id: usize, db_shard: Arc, metadata_progress: Version, ) -> Result { @@ -99,7 +99,7 @@ where Ok(()) } - pub(in crate::pruner) fn shard_id(&self) -> u8 { + pub(in crate::pruner) fn shard_id(&self) -> usize { self.shard_id } } diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs index 491aab1e967..2f5debe02c0 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs @@ -17,12 +17,13 @@ use crate::{ }; use aptos_config::config::{LedgerPrunerConfig, StateMerklePrunerConfig}; use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, DbReader}; +use aptos_storage_interface::DbReader; use aptos_temppath::TempPath; use aptos_types::{ state_store::{ state_key::StateKey, state_value::{StaleStateValueByKeyHashIndex, StaleStateValueIndex, StateValue}, + NUM_STATE_SHARDS, }, transaction::Version, }; @@ -234,7 +235,7 @@ fn test_state_store_pruner_partial_version() { ); if aptos_db.state_merkle_db().sharding_enabled() { - for i in 0..NUM_STATE_SHARDS as u8 { + for i in 0..NUM_STATE_SHARDS { assert_eq!( aptos_db .state_merkle_db() diff --git a/storage/aptosdb/src/rocksdb_property_reporter.rs b/storage/aptosdb/src/rocksdb_property_reporter.rs index d992f9692b1..553526e789d 100644 --- a/storage/aptosdb/src/rocksdb_property_reporter.rs +++ b/storage/aptosdb/src/rocksdb_property_reporter.rs @@ -18,8 +18,9 @@ use crate::{ use anyhow::Result; use aptos_infallible::Mutex; use aptos_logger::prelude::*; +use aptos_metrics_core::TimerHelper; use aptos_schemadb::{ColumnFamilyName, DB}; -use aptos_storage_interface::state_store::NUM_STATE_SHARDS; +use aptos_types::state_store::NUM_STATE_SHARDS; use once_cell::sync::Lazy; use std::{ collections::HashMap, @@ -104,9 +105,7 @@ fn update_rocksdb_properties( state_merkle_db: &StateMerkleDb, state_kv_db: &StateKvDb, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["update_rocksdb_properties"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["update_rocksdb_properties"]); let enable_storage_sharding = state_kv_db.enabled_sharding(); @@ -143,7 +142,7 @@ fn update_rocksdb_properties( for cf in state_kv_db_new_key_column_families() { set_property(cf, state_kv_db.metadata_db())?; for shard in 0..NUM_STATE_SHARDS { - set_shard_property(cf, state_kv_db.db_shard(shard as u8), shard)?; + set_shard_property(cf, state_kv_db.db_shard(shard), shard)?; } } } @@ -157,7 +156,7 @@ fn update_rocksdb_properties( set_property(cf_name, state_merkle_db.metadata_db())?; if state_merkle_db.sharding_enabled() { for shard in 0..NUM_STATE_SHARDS { - set_shard_property(cf_name, state_merkle_db.db_shard(shard as u8), shard)?; + set_shard_property(cf_name, state_merkle_db.db_shard(shard), shard)?; } } } diff --git a/storage/aptosdb/src/schema/db_metadata/mod.rs b/storage/aptosdb/src/schema/db_metadata/mod.rs index b76a423ba0e..682f9d18c94 100644 --- a/storage/aptosdb/src/schema/db_metadata/mod.rs +++ b/storage/aptosdb/src/schema/db_metadata/mod.rs @@ -68,6 +68,7 @@ pub enum DbMetadataKey { StateKvShardPrunerProgress(ShardId), StateMerkleShardRestoreProgress(ShardId, Version), TransactionAuxiliaryDataPrunerProgress, + PersistedAuxiliaryInfoPrunerProgress, } define_schema!( diff --git a/storage/aptosdb/src/schema/mod.rs b/storage/aptosdb/src/schema/mod.rs index e4a6f62eed3..ee5c681cd8d 100644 --- a/storage/aptosdb/src/schema/mod.rs +++ b/storage/aptosdb/src/schema/mod.rs @@ -15,6 +15,7 @@ pub(crate) mod event_accumulator; pub(crate) mod hot_state_value_by_key_hash; pub(crate) mod jellyfish_merkle_node; pub(crate) mod ledger_info; +pub(crate) mod persisted_auxiliary_info; pub(crate) mod stale_node_index; pub(crate) mod stale_node_index_cross_epoch; pub(crate) mod stale_state_value_index; @@ -45,6 +46,7 @@ pub const EVENT_CF_NAME: ColumnFamilyName = "event"; pub const HOT_STATE_VALUE_BY_KEY_HASH_CF_NAME: ColumnFamilyName = "hot_state_value_by_key_hash"; pub const JELLYFISH_MERKLE_NODE_CF_NAME: ColumnFamilyName = "jellyfish_merkle_node"; pub const LEDGER_INFO_CF_NAME: ColumnFamilyName = "ledger_info"; +pub const PERSISTED_AUXILIARY_INFO_CF_NAME: ColumnFamilyName = "persisted_auxiliary_info"; pub const STALE_NODE_INDEX_CF_NAME: ColumnFamilyName = "stale_node_index"; pub const STALE_NODE_INDEX_CROSS_EPOCH_CF_NAME: ColumnFamilyName = "stale_node_index_cross_epoch"; pub const STALE_STATE_VALUE_INDEX_CF_NAME: ColumnFamilyName = "stale_state_value_index"; @@ -103,6 +105,9 @@ pub mod fuzzing { ); assert_no_panic_decoding::(data); assert_no_panic_decoding::(data); + assert_no_panic_decoding::( + data, + ); assert_no_panic_decoding::(data); assert_no_panic_decoding::< super::stale_node_index_cross_epoch::StaleNodeIndexCrossEpochSchema, diff --git a/storage/aptosdb/src/schema/persisted_auxiliary_info/mod.rs b/storage/aptosdb/src/schema/persisted_auxiliary_info/mod.rs new file mode 100644 index 00000000000..abc632663eb --- /dev/null +++ b/storage/aptosdb/src/schema/persisted_auxiliary_info/mod.rs @@ -0,0 +1,54 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines physical storage schema for PersistedAuxiliaryInfo structure. +//! +//! Serialized PersistedAuxiliaryInfo bytes keyed by transaction version. +//! ```text +//! |<--key-->|<------------value------------->| +//! | version | persisted_auxiliary_info bytes | +//! ``` +//! +//! `Version` is serialized in big endian so that records in RocksDB will be in order of it's +//! numeric value. + +use crate::schema::{ensure_slice_len_eq, PERSISTED_AUXILIARY_INFO_CF_NAME}; +use anyhow::Result; +use aptos_schemadb::{ + define_schema, + schema::{KeyCodec, ValueCodec}, +}; +use aptos_types::transaction::{PersistedAuxiliaryInfo, Version}; +use byteorder::{BigEndian, ReadBytesExt}; +use std::mem::size_of; + +define_schema!( + PersistedAuxiliaryInfoSchema, + Version, + PersistedAuxiliaryInfo, + PERSISTED_AUXILIARY_INFO_CF_NAME +); + +impl KeyCodec for Version { + fn encode_key(&self) -> Result> { + Ok(self.to_be_bytes().to_vec()) + } + + fn decode_key(mut data: &[u8]) -> Result { + ensure_slice_len_eq(data, size_of::())?; + Ok(data.read_u64::()?) + } +} + +impl ValueCodec for PersistedAuxiliaryInfo { + fn encode_value(&self) -> Result> { + bcs::to_bytes(self).map_err(Into::into) + } + + fn decode_value(data: &[u8]) -> Result { + bcs::from_bytes(data).map_err(Into::into) + } +} + +#[cfg(test)] +mod test; diff --git a/storage/aptosdb/src/schema/persisted_auxiliary_info/test.rs b/storage/aptosdb/src/schema/persisted_auxiliary_info/test.rs new file mode 100644 index 00000000000..05ef4b1cd8d --- /dev/null +++ b/storage/aptosdb/src/schema/persisted_auxiliary_info/test.rs @@ -0,0 +1,16 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use super::*; +use aptos_schemadb::{schema::fuzzing::assert_encode_decode, test_no_panic_decoding}; +use aptos_types::transaction::{PersistedAuxiliaryInfo, Version}; +use proptest::prelude::*; + +proptest! { + #[test] + fn test_encode_decode(version in any::(), info in any::()) { + assert_encode_decode::(&version, &info); + } +} + +test_no_panic_decoding!(PersistedAuxiliaryInfoSchema); diff --git a/storage/aptosdb/src/state_kv_db.rs b/storage/aptosdb/src/state_kv_db.rs index 44e0647459c..1a89d6f7f40 100644 --- a/storage/aptosdb/src/state_kv_db.rs +++ b/storage/aptosdb/src/state_kv_db.rs @@ -24,15 +24,14 @@ use aptos_metrics_core::TimerHelper; use aptos_rocksdb_options::gen_rocksdb_options; use aptos_schemadb::{ batch::{SchemaBatch, WriteBatch}, - ReadOptions, DB, + Cache, Env, ReadOptions, DB, }; -use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, Result}; +use aptos_storage_interface::Result; use aptos_types::{ - state_store::{state_key::StateKey, state_value::StateValue}, + state_store::{state_key::StateKey, state_value::StateValue, NUM_STATE_SHARDS}, transaction::Version, }; use arr_macro::arr; -use itertools::Itertools; use rayon::prelude::*; use std::{ path::{Path, PathBuf}, @@ -55,6 +54,8 @@ impl StateKvDb { pub(crate) fn new( db_paths: &StorageDirPaths, rocksdb_configs: RocksdbConfigs, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ledger_db: Arc, ) -> Result { @@ -69,12 +70,20 @@ impl StateKvDb { }); } - Self::open_sharded(db_paths, rocksdb_configs.state_kv_db_config, readonly) + Self::open_sharded( + db_paths, + rocksdb_configs.state_kv_db_config, + env, + block_cache, + readonly, + ) } pub(crate) fn open_sharded( db_paths: &StorageDirPaths, state_kv_db_config: RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ) -> Result { let state_kv_metadata_db_path = @@ -84,6 +93,8 @@ impl StateKvDb { state_kv_metadata_db_path.clone(), STATE_KV_METADATA_DB_NAME, &state_kv_db_config, + env, + block_cache, readonly, /* is_hot = */ false, )?); @@ -96,11 +107,13 @@ impl StateKvDb { let state_kv_db_shards = (0..NUM_STATE_SHARDS) .into_par_iter() .map(|shard_id| { - let shard_root_path = db_paths.state_kv_db_shard_root_path(shard_id as u8); + let shard_root_path = db_paths.state_kv_db_shard_root_path(shard_id); let db = Self::open_shard( shard_root_path, - shard_id as u8, + shard_id, &state_kv_db_config, + env, + block_cache, readonly, /* is_hot = */ false, ) @@ -120,12 +133,13 @@ impl StateKvDb { (0..NUM_STATE_SHARDS) .into_par_iter() .map(|shard_id| { - let shard_root_path = - db_paths.hot_state_kv_db_shard_root_path(shard_id as u8); + let shard_root_path = db_paths.hot_state_kv_db_shard_root_path(shard_id); let db = Self::open_shard( shard_root_path, - shard_id as u8, + shard_id, &state_kv_db_config, + env, + block_cache, readonly, /* is_hot = */ true, ) @@ -156,12 +170,8 @@ impl StateKvDb { Ok(state_kv_db) } - pub(crate) fn new_sharded_native_batches(&self) -> ShardedStateKvSchemaBatch { - (0..NUM_STATE_SHARDS) - .map(|shard_id| self.db_shard(shard_id as u8).new_native_batch()) - .collect_vec() - .try_into() - .expect("known to be 16 shards") + pub(crate) fn new_sharded_native_batches(&self) -> ShardedStateKvSchemaBatch<'_> { + std::array::from_fn(|shard_id| self.db_shard(shard_id).new_native_batch()) } pub(crate) fn commit( @@ -170,13 +180,9 @@ impl StateKvDb { state_kv_metadata_batch: Option, sharded_state_kv_batches: ShardedStateKvSchemaBatch, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_kv_db__commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_kv_db__commit"]); { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_kv_db__commit_shards"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_kv_db__commit_shards"]); THREAD_MANAGER.get_io_pool().scope(|s| { let mut batches = sharded_state_kv_batches.into_iter(); for shard_id in 0..NUM_STATE_SHARDS { @@ -185,7 +191,7 @@ impl StateKvDb { .expect("Not sufficient number of sharded state kv batches"); s.spawn(move |_| { // TODO(grao): Consider propagating the error instead of panic, if necessary. - self.commit_single_shard(version, shard_id as u8, state_kv_batch) + self.commit_single_shard(version, shard_id, state_kv_batch) .unwrap_or_else(|err| { panic!("Failed to commit shard {shard_id}: {err}.") }); @@ -223,6 +229,8 @@ impl StateKvDb { let state_kv_db = Self::open_sharded( &StorageDirPaths::from_path(db_root_path), RocksdbConfig::default(), + None, + None, false, )?; let cp_state_kv_db_path = cp_root_path.as_ref().join(STATE_KV_DB_FOLDER_NAME); @@ -239,10 +247,10 @@ impl StateKvDb { // TODO(HotState): should handle hot state as well. for shard_id in 0..NUM_STATE_SHARDS { state_kv_db - .db_shard(shard_id as u8) + .db_shard(shard_id) .create_checkpoint(Self::db_shard_path( cp_root_path.as_ref(), - shard_id as u8, + shard_id, /* is_hot = */ false, ))?; } @@ -258,20 +266,20 @@ impl StateKvDb { Arc::clone(&self.state_kv_metadata_db) } - pub(crate) fn db_shard(&self, shard_id: u8) -> &DB { - &self.state_kv_db_shards[shard_id as usize] + pub(crate) fn db_shard(&self, shard_id: usize) -> &DB { + &self.state_kv_db_shards[shard_id] } - pub(crate) fn db_shard_arc(&self, shard_id: u8) -> Arc { - Arc::clone(&self.state_kv_db_shards[shard_id as usize]) + pub(crate) fn db_shard_arc(&self, shard_id: usize) -> Arc { + Arc::clone(&self.state_kv_db_shards[shard_id]) } pub(crate) fn enabled_sharding(&self) -> bool { self.enabled_sharding } - pub(crate) fn num_shards(&self) -> u8 { - NUM_STATE_SHARDS as u8 + pub(crate) fn num_shards(&self) -> usize { + NUM_STATE_SHARDS } pub(crate) fn hack_num_real_shards(&self) -> usize { @@ -285,20 +293,22 @@ impl StateKvDb { pub(crate) fn commit_single_shard( &self, version: Version, - shard_id: u8, + shard_id: usize, mut batch: impl WriteBatch, ) -> Result<()> { batch.put::( - &DbMetadataKey::StateKvShardCommitProgress(shard_id as usize), + &DbMetadataKey::StateKvShardCommitProgress(shard_id), &DbMetadataValue::Version(version), )?; - self.state_kv_db_shards[shard_id as usize].write_schemas(batch) + self.state_kv_db_shards[shard_id].write_schemas(batch) } fn open_shard>( db_root_path: P, - shard_id: u8, + shard_id: usize, state_kv_db_config: &RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, is_hot: bool, ) -> Result { @@ -311,6 +321,8 @@ impl StateKvDb { Self::db_shard_path(db_root_path, shard_id, is_hot), &db_name, state_kv_db_config, + env, + block_cache, readonly, is_hot, ) @@ -320,6 +332,8 @@ impl StateKvDb { path: PathBuf, name: &str, state_kv_db_config: &RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, is_hot: bool, ) -> Result { @@ -328,17 +342,17 @@ impl StateKvDb { } else { DB::open_cf }; - let rocksdb_opts = gen_rocksdb_options(state_kv_db_config, readonly); + let rocksdb_opts = gen_rocksdb_options(state_kv_db_config, env, readonly); let cfds = if is_hot { gen_hot_state_kv_shard_cfds } else { gen_state_kv_shard_cfds - }(state_kv_db_config); + }(state_kv_db_config, block_cache); open_func(&rocksdb_opts, path, name, cfds) } - fn db_shard_path>(db_root_path: P, shard_id: u8, is_hot: bool) -> PathBuf { + fn db_shard_path>(db_root_path: P, shard_id: usize, is_hot: bool) -> PathBuf { let shard_sub_path = format!( "{}_{}", if is_hot { "hot_shard" } else { "shard" }, diff --git a/storage/aptosdb/src/state_merkle_db.rs b/storage/aptosdb/src/state_merkle_db.rs index bf6b9a17d28..ae04d9aae0f 100644 --- a/storage/aptosdb/src/state_merkle_db.rs +++ b/storage/aptosdb/src/state_merkle_db.rs @@ -25,23 +25,22 @@ use aptos_metrics_core::TimerHelper; use aptos_rocksdb_options::gen_rocksdb_options; use aptos_schemadb::{ batch::{IntoRawBatch, RawBatch, SchemaBatch, WriteBatch}, - DB, + Cache, Env, DB, }; #[cfg(test)] use aptos_scratchpad::get_state_shard_id; -use aptos_storage_interface::{ - db_ensure as ensure, state_store::NUM_STATE_SHARDS, AptosDbError, Result, -}; +use aptos_storage_interface::{db_ensure as ensure, AptosDbError, Result}; use aptos_types::{ nibble::{nibble_path::NibblePath, ROOT_NIBBLE_HEIGHT}, proof::{SparseMerkleProofExt, SparseMerkleRangeProof}, - state_store::state_key::StateKey, + state_store::{state_key::StateKey, NUM_STATE_SHARDS}, transaction::Version, }; use arr_macro::arr; use rayon::prelude::*; use std::{ collections::HashMap, + num::NonZeroUsize, path::{Path, PathBuf}, sync::Arc, time::Instant, @@ -62,30 +61,33 @@ pub struct StateMerkleDb { // Stores sharded part of tree nodes. state_merkle_db_shards: [Arc; NUM_STATE_SHARDS], enable_sharding: bool, - enable_cache: bool, // shard_id -> cache. - version_caches: HashMap, VersionedNodeCache>, - lru_cache: LruNodeCache, + version_caches: HashMap, VersionedNodeCache>, + // `None` means the cache is not enabled. + lru_cache: Option, } impl StateMerkleDb { pub(crate) fn new( db_paths: &StorageDirPaths, rocksdb_configs: RocksdbConfigs, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, + // TODO(grao): Currently when this value is set to 0 we disable both caches. This is + // hacky, need to revisit. max_nodes_per_lru_cache_shard: usize, ) -> Result { let sharding = rocksdb_configs.enable_storage_sharding; let state_merkle_db_config = rocksdb_configs.state_merkle_db_config; - // TODO(grao): Currently when this value is set to 0 we disable both caches. This is - // hacky, need to revisit. - let enable_cache = max_nodes_per_lru_cache_shard > 0; + let mut version_caches = HashMap::with_capacity(NUM_STATE_SHARDS + 1); version_caches.insert(None, VersionedNodeCache::new()); for i in 0..NUM_STATE_SHARDS { - version_caches.insert(Some(i as u8), VersionedNodeCache::new()); + version_caches.insert(Some(i), VersionedNodeCache::new()); } - let lru_cache = LruNodeCache::new(max_nodes_per_lru_cache_shard); + let lru_cache = NonZeroUsize::new(max_nodes_per_lru_cache_shard).map(LruNodeCache::new); + if !sharding { info!("Sharded state merkle DB is not enabled!"); let state_merkle_db_path = db_paths.default_root_path().join(STATE_MERKLE_DB_NAME); @@ -93,13 +95,14 @@ impl StateMerkleDb { state_merkle_db_path, STATE_MERKLE_DB_NAME, &state_merkle_db_config, + env, + block_cache, readonly, )?); return Ok(Self { state_merkle_metadata_db: Arc::clone(&db), state_merkle_db_shards: arr![Arc::clone(&db); 16], enable_sharding: false, - enable_cache, version_caches, lru_cache, }); @@ -108,8 +111,9 @@ impl StateMerkleDb { Self::open( db_paths, state_merkle_db_config, + env, + block_cache, readonly, - enable_cache, version_caches, lru_cache, ) @@ -130,7 +134,7 @@ impl StateMerkleDb { .into_par_iter() .enumerate() .for_each(|(shard_id, batch)| { - self.db_shard(shard_id as u8) + self.db_shard(shard_id) .write_schemas(batch) .unwrap_or_else(|err| { panic!("Failed to commit state merkle shard {shard_id}: {err}") @@ -173,6 +177,8 @@ impl StateMerkleDb { let state_merkle_db = Self::new( &StorageDirPaths::from_path(db_root_path), rocksdb_configs, + /*env=*/ None, + /*block_cache=*/ None, /*readonly=*/ false, /*max_nodes_per_lru_cache_shard=*/ 0, )?; @@ -192,11 +198,8 @@ impl StateMerkleDb { if sharding { for shard_id in 0..NUM_STATE_SHARDS { state_merkle_db - .db_shard(shard_id as u8) - .create_checkpoint(Self::db_shard_path( - cp_root_path.as_ref(), - shard_id as u8, - ))?; + .db_shard(shard_id) + .create_checkpoint(Self::db_shard_path(cp_root_path.as_ref(), shard_id))?; } } @@ -211,15 +214,15 @@ impl StateMerkleDb { Arc::clone(&self.state_merkle_metadata_db) } - pub(crate) fn db_shard(&self, shard_id: u8) -> &DB { - &self.state_merkle_db_shards[shard_id as usize] + pub(crate) fn db_shard(&self, shard_id: usize) -> &DB { + &self.state_merkle_db_shards[shard_id] } - pub(crate) fn db_shard_arc(&self, shard_id: u8) -> Arc { - Arc::clone(&self.state_merkle_db_shards[shard_id as usize]) + pub(crate) fn db_shard_arc(&self, shard_id: usize) -> Arc { + Arc::clone(&self.state_merkle_db_shards[shard_id]) } - pub(crate) fn db(&self, shard_id: Option) -> &DB { + pub(crate) fn db(&self, shard_id: Option) -> &DB { if let Some(shard_id) = shard_id { self.db_shard(shard_id) } else { @@ -266,14 +269,14 @@ impl StateMerkleDb { pub fn batch_put_value_set_for_shard( &self, - shard_id: u8, + shard_id: usize, value_set: Vec<(HashValue, Option<&(HashValue, StateKey)>)>, node_hashes: Option<&HashMap>, persisted_version: Option, version: Version, ) -> Result<(Node, TreeUpdateBatch)> { JellyfishMerkleTree::new(self).batch_put_value_set_for_shard( - shard_id, + shard_id as u8, value_set, node_hashes, persisted_version, @@ -311,7 +314,7 @@ impl StateMerkleDb { fn create_jmt_commit_batch_for_shard( &self, version: Version, - shard_id: Option, + shard_id: Option, tree_update_batch: &TreeUpdateBatch, previous_epoch_ending_version: Option, ) -> Result { @@ -353,11 +356,11 @@ impl StateMerkleDb { pub(crate) fn put_progress( version: Option, - shard_id: Option, + shard_id: Option, batch: &mut impl WriteBatch, ) -> Result<()> { let key = if let Some(shard_id) = shard_id { - DbMetadataKey::StateMerkleShardCommitProgress(shard_id as usize) + DbMetadataKey::StateMerkleShardCommitProgress(shard_id) } else { DbMetadataKey::StateMerkleCommitProgress }; @@ -389,7 +392,7 @@ impl StateMerkleDb { .map(|shard_id| { self.merklize_value_set_for_shard( shard_id, - sharded_value_set[shard_id as usize].clone(), + sharded_value_set[shard_id].clone(), /*node_hashes=*/ None, version, base_version, @@ -417,7 +420,7 @@ impl StateMerkleDb { /// Assumes 16 shards in total for now. pub fn merklize_value_set_for_shard( &self, - shard_id: u8, + shard_id: usize, value_set: Vec<(HashValue, Option<&(HashValue, StateKey)>)>, node_hashes: Option<&HashMap>, version: Version, @@ -430,9 +433,7 @@ impl StateMerkleDb { } let (shard_root_node, tree_update_batch) = { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["jmt_update"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["jmt_update"]); self.batch_put_value_set_for_shard( shard_id, @@ -517,15 +518,15 @@ impl StateMerkleDb { } pub(crate) fn cache_enabled(&self) -> bool { - self.enable_cache + self.lru_cache.is_some() } - pub(crate) fn version_caches(&self) -> &HashMap, VersionedNodeCache> { + pub(crate) fn version_caches(&self) -> &HashMap, VersionedNodeCache> { &self.version_caches } - pub(crate) fn lru_cache(&self) -> &LruNodeCache { - &self.lru_cache + pub(crate) fn lru_cache(&self) -> Option<&LruNodeCache> { + self.lru_cache.as_ref() } pub(crate) fn write_pruner_progress( @@ -537,8 +538,8 @@ impl StateMerkleDb { .put::(progress_key, &DbMetadataValue::Version(version)) } - pub(crate) fn num_shards(&self) -> u8 { - NUM_STATE_SHARDS as u8 + pub(crate) fn num_shards(&self) -> usize { + NUM_STATE_SHARDS } pub(crate) fn hack_num_real_shards(&self) -> usize { @@ -560,10 +561,11 @@ impl StateMerkleDb { fn open( db_paths: &StorageDirPaths, state_merkle_db_config: RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, - enable_cache: bool, - version_caches: HashMap, VersionedNodeCache>, - lru_cache: LruNodeCache, + version_caches: HashMap, VersionedNodeCache>, + lru_cache: Option, ) -> Result { let state_merkle_metadata_db_path = Self::metadata_db_path( db_paths.state_merkle_db_metadata_root_path(), @@ -574,6 +576,8 @@ impl StateMerkleDb { state_merkle_metadata_db_path.clone(), STATE_MERKLE_METADATA_DB_NAME, &state_merkle_db_config, + env, + block_cache, readonly, )?); @@ -585,11 +589,13 @@ impl StateMerkleDb { let state_merkle_db_shards = (0..NUM_STATE_SHARDS) .into_par_iter() .map(|shard_id| { - let shard_root_path = db_paths.state_merkle_db_shard_root_path(shard_id as u8); + let shard_root_path = db_paths.state_merkle_db_shard_root_path(shard_id); let db = Self::open_shard( shard_root_path, - shard_id as u8, + shard_id, &state_merkle_db_config, + env, + block_cache, readonly, ) .unwrap_or_else(|e| { @@ -605,7 +611,6 @@ impl StateMerkleDb { state_merkle_metadata_db, state_merkle_db_shards, enable_sharding: true, - enable_cache, version_caches, lru_cache, }; @@ -626,8 +631,10 @@ impl StateMerkleDb { fn open_shard>( db_root_path: P, - shard_id: u8, + shard_id: usize, state_merkle_db_config: &RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ) -> Result { let db_name = format!("state_merkle_db_shard_{}", shard_id); @@ -635,6 +642,8 @@ impl StateMerkleDb { Self::db_shard_path(db_root_path, shard_id), &db_name, state_merkle_db_config, + env, + block_cache, readonly, ) } @@ -643,26 +652,28 @@ impl StateMerkleDb { path: PathBuf, name: &str, state_merkle_db_config: &RocksdbConfig, + env: Option<&Env>, + block_cache: Option<&Cache>, readonly: bool, ) -> Result { Ok(if readonly { DB::open_cf_readonly( - &gen_rocksdb_options(state_merkle_db_config, true), + &gen_rocksdb_options(state_merkle_db_config, env, true), path, name, - gen_state_merkle_cfds(state_merkle_db_config), + gen_state_merkle_cfds(state_merkle_db_config, block_cache), )? } else { DB::open_cf( - &gen_rocksdb_options(state_merkle_db_config, false), + &gen_rocksdb_options(state_merkle_db_config, env, false), path, name, - gen_state_merkle_cfds(state_merkle_db_config), + gen_state_merkle_cfds(state_merkle_db_config, block_cache), )? }) } - fn db_shard_path>(db_root_path: P, shard_id: u8) -> PathBuf { + fn db_shard_path>(db_root_path: P, shard_id: usize) -> PathBuf { let shard_sub_path = format!("shard_{}", shard_id); db_root_path .as_ref() @@ -721,14 +732,14 @@ impl StateMerkleDb { fn get_rightmost_leaf_in_single_shard( &self, version: Version, - shard_id: u8, + shard_id: usize, ) -> Result> { assert!( - shard_id < NUM_STATE_SHARDS as u8, + shard_id < NUM_STATE_SHARDS, "Invalid shard_id: {}", shard_id ); - let shard_db = self.state_merkle_db_shards[shard_id as usize].clone(); + let shard_db = self.state_merkle_db_shards[shard_id].clone(); // The encoding of key and value in DB looks like: // // | <-------------- key --------------> | <- value -> | @@ -784,38 +795,40 @@ impl TreeReader for StateMerkleDb { .db_by_key(node_key) .get::(node_key)?; NODE_CACHE_SECONDS - .with_label_values(&[tag, "cache_disabled"]) - .observe(start_time.elapsed().as_secs_f64()); + .observe_with(&[tag, "cache_disabled"], start_time.elapsed().as_secs_f64()); return Ok(node_opt); } - let node_opt = if let Some(node_cache) = self + if let Some(node_cache) = self .version_caches .get(&node_key.get_shard_id()) .unwrap() .get_version(node_key.version()) { let node = node_cache.get(node_key).cloned(); - NODE_CACHE_SECONDS - .with_label_values(&[tag, "versioned_cache_hit"]) - .observe(start_time.elapsed().as_secs_f64()); - node - } else if let Some(node) = self.lru_cache.get(node_key) { - NODE_CACHE_SECONDS - .with_label_values(&[tag, "lru_cache_hit"]) - .observe(start_time.elapsed().as_secs_f64()); - Some(node) - } else { - let node_opt = self - .db_by_key(node_key) - .get::(node_key)?; + NODE_CACHE_SECONDS.observe_with( + &[tag, "versioned_cache_hit"], + start_time.elapsed().as_secs_f64(), + ); + return Ok(node); + } + + if let Some(lru_cache) = &self.lru_cache { + if let Some(node) = lru_cache.get(node_key) { + NODE_CACHE_SECONDS + .observe_with(&[tag, "lru_cache_hit"], start_time.elapsed().as_secs_f64()); + return Ok(Some(node)); + } + } + + let node_opt = self + .db_by_key(node_key) + .get::(node_key)?; + if let Some(lru_cache) = &self.lru_cache { if let Some(node) = &node_opt { - self.lru_cache.put(node_key.clone(), node.clone()); + lru_cache.put(node_key.clone(), node.clone()); } - NODE_CACHE_SECONDS - .with_label_values(&[tag, "cache_miss"]) - .observe(start_time.elapsed().as_secs_f64()); - node_opt - }; + } + NODE_CACHE_SECONDS.observe_with(&[tag, "cache_miss"], start_time.elapsed().as_secs_f64()); Ok(node_opt) } @@ -826,7 +839,7 @@ impl TreeReader for StateMerkleDb { // Search from right to left to find the first leaf node. for shard_id in shards.rev() { if let Some((node_key, leaf_node)) = - self.get_rightmost_leaf_in_single_shard(version, shard_id as u8)? + self.get_rightmost_leaf_in_single_shard(version, shard_id)? { return Ok(Some((node_key, leaf_node))); } @@ -838,17 +851,14 @@ impl TreeReader for StateMerkleDb { impl TreeWriter for StateMerkleDb { fn write_node_batch(&self, node_batch: &NodeBatch) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["tree_writer_write_batch"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["tree_writer_write_batch"]); // Get the top level batch and sharded batch from raw NodeBatch let mut top_level_batch = SchemaBatch::new(); let mut jmt_shard_batches: Vec = Vec::with_capacity(NUM_STATE_SHARDS); jmt_shard_batches.resize_with(NUM_STATE_SHARDS, SchemaBatch::new); node_batch.iter().try_for_each(|(node_key, node)| { if let Some(shard_id) = node_key.get_shard_id() { - jmt_shard_batches[shard_id as usize] - .put::(node_key, node) + jmt_shard_batches[shard_id].put::(node_key, node) } else { top_level_batch.put::(node_key, node) } diff --git a/storage/aptosdb/src/state_restore/mod.rs b/storage/aptosdb/src/state_restore/mod.rs index 15deb6e53e2..439c8110416 100644 --- a/storage/aptosdb/src/state_restore/mod.rs +++ b/storage/aptosdb/src/state_restore/mod.rs @@ -7,6 +7,7 @@ use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_db_indexer_schemas::metadata::StateSnapshotProgress; use aptos_infallible::Mutex; use aptos_jellyfish_merkle::{restore::JellyfishMerkleRestore, Key, TreeReader, TreeWriter, Value}; +use aptos_metrics_core::TimerHelper; use aptos_storage_interface::{Result, StateSnapshotReceiver}; use aptos_types::{ proof::SparseMerkleRangeProof, state_store::state_storage_usage::StateStorageUsage, @@ -226,9 +227,7 @@ impl StateSnapshotReceiver { fn add_chunk(&mut self, chunk: Vec<(K, V)>, proof: SparseMerkleRangeProof) -> Result<()> { let kv_fn = || { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_value_add_chunk"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_value_add_chunk"]); self.kv_restore .lock() .as_mut() @@ -237,9 +236,7 @@ impl StateSnapshotReceiver }; let tree_fn = || { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["jmt_add_chunk"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["jmt_add_chunk"]); self.tree_restore .lock() .as_mut() diff --git a/storage/aptosdb/src/state_store/buffered_state.rs b/storage/aptosdb/src/state_store/buffered_state.rs index 7e8b81300ed..398d9ad8832 100644 --- a/storage/aptosdb/src/state_store/buffered_state.rs +++ b/storage/aptosdb/src/state_store/buffered_state.rs @@ -112,7 +112,7 @@ impl BufferedState { } } - fn current_state_locked(&self) -> MutexGuard { + fn current_state_locked(&self) -> MutexGuard<'_, LedgerStateWithSummary> { self.current_state.lock() } diff --git a/storage/aptosdb/src/state_store/hot_state.rs b/storage/aptosdb/src/state_store/hot_state.rs index bb100445662..b04684b3bf4 100644 --- a/storage/aptosdb/src/state_store/hot_state.rs +++ b/storage/aptosdb/src/state_store/hot_state.rs @@ -3,58 +3,107 @@ // SPDX-License-Identifier: Apache-2.0 use crate::metrics::{COUNTER, GAUGE, OTHER_TIMERS_SECONDS}; +use anyhow::{ensure, Result}; use aptos_infallible::Mutex; use aptos_logger::prelude::*; -use aptos_metrics_core::{IntCounterHelper, IntGaugeHelper, TimerHelper}; +use aptos_metrics_core::{IntCounterVecHelper, IntGaugeVecHelper, TimerHelper}; use aptos_storage_interface::state_store::{ state::State, state_view::hot_state_view::HotStateView, }; -use aptos_types::{ - state_store::{state_key::StateKey, state_slot::StateSlot, StateViewResult}, - transaction::Version, +use aptos_types::state_store::{ + hot_state::{HotStateConfig, THotStateSlot}, + state_key::StateKey, + state_slot::StateSlot, + NUM_STATE_SHARDS, }; -use dashmap::DashMap; -use std::{ - collections::BTreeSet, - sync::{ - mpsc::{Receiver, SyncSender, TryRecvError}, - Arc, - }, +#[cfg(test)] +use aptos_types::transaction::Version; +use arr_macro::arr; +use dashmap::{mapref::one::Ref, DashMap}; +#[cfg(test)] +use std::collections::BTreeMap; +use std::sync::{ + mpsc::{Receiver, SyncSender, TryRecvError}, + Arc, }; const MAX_HOT_STATE_COMMIT_BACKLOG: usize = 10; #[derive(Debug)] -pub struct HotStateBase { - /// After committing a new batch to `inner`, items are evicted so that - /// 1. total number of items doesn't exceed this number - max_items: usize, - /// 2. total number of bytes, incl. both keys and values doesn't exceed this number - max_bytes: usize, - /// No item is accepted to `inner` if the size of the value exceeds this number - max_single_value_bytes: usize, - - inner: DashMap, +struct Shard +where + K: Eq + std::hash::Hash, +{ + inner: DashMap, } -impl HotStateBase { - fn new_empty(max_items: usize, max_bytes: usize, max_single_value_bytes: usize) -> Self { +impl Shard +where + K: Clone + Eq + std::hash::Hash, + V: Clone, +{ + fn new(max_items: usize) -> Self { Self { - max_items, - max_bytes, - max_single_value_bytes, inner: DashMap::with_capacity(max_items), } } - fn get(&self, key: &StateKey) -> Option { - self.inner.get(key).map(|val| val.clone()) + fn get(&self, key: &K) -> Option> { + self.inner.get(key) } + + fn insert(&self, key: K, value: V) -> Option { + self.inner.insert(key, value) + } + + fn remove(&self, key: &K) -> Option<(K, V)> { + self.inner.remove(key) + } + + fn len(&self) -> usize { + self.inner.len() + } + + #[cfg(test)] + fn iter(&self) -> impl Iterator + use<'_, K, V> { + self.inner + .iter() + .map(|entry| (entry.key().clone(), entry.value().clone())) + } +} + +#[derive(Debug)] +pub struct HotStateBase +where + K: Eq + std::hash::Hash, +{ + shards: [Shard; NUM_STATE_SHARDS], } -impl HotStateView for HotStateBase { - fn get_state_slot(&self, state_key: &StateKey) -> StateViewResult> { - Ok(self.get(state_key)) +impl HotStateBase +where + K: Clone + Eq + std::hash::Hash, + V: Clone, +{ + fn new_empty(max_items_per_shard: usize) -> Self { + Self { + shards: arr![Shard::new(max_items_per_shard); 16], + } + } + + fn get_from_shard(&self, shard_id: usize, key: &K) -> Option> { + self.shards[shard_id].get(key) + } + + fn len(&self) -> usize { + self.shards.iter().map(|s| s.len()).sum() + } +} + +impl HotStateView for HotStateBase { + fn get_state_slot(&self, state_key: &StateKey) -> Option { + let shard_id = state_key.get_shard_id(); + self.get_from_shard(shard_id, state_key).map(|v| v.clone()) } } @@ -66,17 +115,8 @@ pub struct HotState { } impl HotState { - pub fn new( - state: State, - max_items: usize, - max_bytes: usize, - max_single_value_bytes: usize, - ) -> Self { - let base = Arc::new(HotStateBase::new_empty( - max_items, - max_bytes, - max_single_value_bytes, - )); + pub fn new(state: State, config: HotStateConfig) -> Self { + let base = Arc::new(HotStateBase::new_empty(config.max_items_per_shard)); let committed = Arc::new(Mutex::new(state)); let commit_tx = Committer::spawn(base.clone(), committed.clone()); @@ -105,19 +145,35 @@ impl HotState { .send(to_commit) .expect("Failed to queue for hot state commit.") } + + /// Wait until the asynchronous commit finishes and the state reaches certain version. + #[cfg(test)] + pub fn wait_for_commit(&self, next_version: Version) { + while self.committed.lock().next_version() < next_version { + std::thread::sleep(std::time::Duration::from_millis(1)); + } + } + + #[cfg(test)] + pub fn get_all_entries(&self, shard_id: usize) -> BTreeMap { + self.base.shards[shard_id].iter().collect() + } } pub struct Committer { base: Arc, committed: Arc>, rx: Receiver, - key_by_hot_since_version: BTreeSet<(Version, StateKey)>, total_key_bytes: usize, total_value_bytes: usize, + /// Points to the newest entry. `None` if empty. + heads: [Option; NUM_STATE_SHARDS], + /// Points to the oldest entry. `None` if empty. + tails: [Option; NUM_STATE_SHARDS], } impl Committer { - pub fn spawn(base: Arc, committed: Arc>) -> SyncSender { + fn spawn(base: Arc, committed: Arc>) -> SyncSender { let (tx, rx) = std::sync::mpsc::sync_channel(MAX_HOT_STATE_COMMIT_BACKLOG); std::thread::spawn(move || Self::new(base, committed, rx).run()); @@ -129,9 +185,10 @@ impl Committer { base, committed, rx, - key_by_hot_since_version: BTreeSet::new(), total_key_bytes: 0, total_value_bytes: 0, + heads: arr![None; 16], + tails: arr![None; 16], } } @@ -140,12 +197,9 @@ impl Committer { while let Some(to_commit) = self.next_to_commit() { self.commit(&to_commit); - self.evict(); *self.committed.lock() = to_commit; - assert_eq!(self.key_by_hot_since_version.len(), self.base.inner.len()); - - GAUGE.set_with(&["hot_state_items"], self.base.inner.len() as i64); + GAUGE.set_with(&["hot_state_items"], self.base.len() as i64); GAUGE.set_with(&["hot_state_key_bytes"], self.total_key_bytes as i64); GAUGE.set_with(&["hot_state_value_bytes"], self.total_value_bytes as i64); } @@ -184,96 +238,78 @@ impl Committer { fn commit(&mut self, to_commit: &State) { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["hot_state_commit"]); - let mut n_delete = 0; - let mut n_too_large = 0; - let mut n_update = 0; let mut n_insert = 0; + let mut n_update = 0; + let mut n_evict = 0; let delta = to_commit.make_delta(&self.committed.lock()); - for (key, slot) in delta.shards.iter().flat_map(|shard| shard.iter()) { - let has_old_entry = if let Some(old_slot) = self.base.get(&key) { - self.total_key_bytes -= key.size(); - self.total_value_bytes -= old_slot.size(); - - self.key_by_hot_since_version - .remove(&(old_slot.expect_hot_since_version(), key.clone())); - true - } else { - false - }; - - if slot.is_cold() { - // deletion - if has_old_entry { - n_delete += 1; + for shard_id in 0..NUM_STATE_SHARDS { + for (key, slot) in delta.shards[shard_id].iter() { + if slot.is_hot() { + let key_size = key.size(); + self.total_key_bytes += key_size; + self.total_value_bytes += slot.size(); + if let Some(old_slot) = self.base.shards[shard_id].insert(key, slot) { + self.total_key_bytes -= key_size; + self.total_value_bytes -= old_slot.size(); + n_update += 1; + } else { + n_insert += 1; + } + } else if let Some((key, old_slot)) = self.base.shards[shard_id].remove(&key) { + self.total_key_bytes -= key.size(); + self.total_value_bytes -= old_slot.size(); + n_evict += 1; } - - self.base.inner.remove(&key); - } else if slot.size() > self.base.max_single_value_bytes { - // item too large to hold in memory - n_too_large += 1; - - self.base.inner.remove(&key); - } else { - if has_old_entry { - n_update += 1; - } else { - n_insert += 1; - }; - - self.total_key_bytes += key.size(); - self.total_value_bytes += slot.size(); - - self.key_by_hot_since_version - .insert((slot.expect_hot_since_version(), key.clone())); - self.base.inner.insert(key, slot); } - } - - COUNTER.inc_with_by(&["hot_state_delete"], n_delete); - COUNTER.inc_with_by(&["hot_state_too_large"], n_too_large); - COUNTER.inc_with_by(&["hot_state_update"], n_update); - COUNTER.inc_with_by(&["hot_state_insert"], n_insert); - } - - fn evict(&mut self) { - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["hot_state_evict"]); - - let latest_version = match self.key_by_hot_since_version.last() { - None => { - // hot state is empty - return; - }, - Some((hot_since_version, _key)) => *hot_since_version, - }; - let mut max_evicted_version = 0; - let mut num_evicted = 0; + self.heads[shard_id] = to_commit.latest_hot_key(shard_id); + self.tails[shard_id] = to_commit.oldest_hot_key(shard_id); + assert_eq!( + self.base.shards[shard_id].len(), + to_commit.num_hot_items(shard_id) + ); - while self.should_evict() { - let (ver, key) = self - .key_by_hot_since_version - .pop_first() - .expect("Known Non-empty."); - let (key, slot) = self.base.inner.remove(&key).expect("Known to exist."); + debug_assert!(self.validate_lru(shard_id).is_ok()); - self.total_key_bytes -= key.size(); - self.total_value_bytes -= slot.size(); + COUNTER.inc_with_by(&["hot_state_insert"], n_insert); + COUNTER.inc_with_by(&["hot_state_update"], n_update); + COUNTER.inc_with_by(&["hot_state_evict"], n_evict); + } + } - num_evicted += 1; - max_evicted_version = ver; + /// Traverses the entire map and checks if all the pointers are correctly linked. + fn validate_lru(&self, shard_id: usize) -> Result<()> { + let head = &self.heads[shard_id]; + let tail = &self.tails[shard_id]; + ensure!(head.is_some() == tail.is_some()); + let shard = &self.base.shards[shard_id]; + + { + let mut num_visited = 0; + let mut current = head.clone(); + while let Some(key) = current { + let entry = shard.get(&key).expect("Must exist."); + num_visited += 1; + ensure!(num_visited <= shard.len()); + ensure!(entry.is_hot()); + current = entry.next().cloned(); + } + ensure!(num_visited == shard.len()); } - if num_evicted > 0 { - GAUGE.set_with( - &["hot_state_item_evict_age_versions"], - (latest_version - max_evicted_version) as i64, - ); - COUNTER.inc_with_by(&["hot_state_evict"], num_evicted as u64); + { + let mut num_visited = 0; + let mut current = tail.clone(); + while let Some(key) = current { + let entry = shard.get(&key).expect("Must exist."); + num_visited += 1; + ensure!(num_visited <= shard.len()); + ensure!(entry.is_hot()); + current = entry.prev().cloned(); + } + ensure!(num_visited == shard.len()); } - } - fn should_evict(&self) -> bool { - self.base.inner.len() > self.base.max_items - || self.total_key_bytes + self.total_value_bytes > self.base.max_bytes + Ok(()) } } diff --git a/storage/aptosdb/src/state_store/mod.rs b/storage/aptosdb/src/state_store/mod.rs index 19d2bc0657e..3caaf2f0368 100644 --- a/storage/aptosdb/src/state_store/mod.rs +++ b/storage/aptosdb/src/state_store/mod.rs @@ -58,13 +58,13 @@ use aptos_storage_interface::{ }, state_with_summary::{LedgerStateWithSummary, StateWithSummary}, versioned_state_value::StateUpdateRef, - NUM_STATE_SHARDS, }, AptosDbError, DbReader, Result, StateSnapshotReceiver, }; use aptos_types::{ proof::{definition::LeafCount, SparseMerkleProofExt, SparseMerkleRangeProof}, state_store::{ + hot_state::HotStateConfig, state_key::{prefix::StateKeyPrefix, StateKey}, state_slot::StateSlot, state_storage_usage::StateStorageUsage, @@ -72,6 +72,7 @@ use aptos_types::{ StaleStateValueByKeyHashIndex, StaleStateValueIndex, StateValue, StateValueChunkWithProof, }, + NUM_STATE_SHARDS, }, transaction::Version, }; @@ -330,12 +331,16 @@ impl StateStore { state_kv_pruner, skip_usage, }); - let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_empty())); + // TODO(HotState): probably fetch onchain config from storage. + let hot_state_config = HotStateConfig::default(); + let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_empty( + hot_state_config, + ))); let persisted_state = PersistedState::new_empty(); let buffered_state = if empty_buffered_state_for_restore { BufferedState::new_at_snapshot( &state_db, - StateWithSummary::new_empty(), + StateWithSummary::new_empty(hot_state_config), buffered_state_target_items, current_state.clone(), persisted_state.clone(), @@ -487,7 +492,9 @@ impl StateStore { state_kv_pruner, skip_usage: false, }); - let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_empty())); + let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_empty( + HotStateConfig::default(), + ))); let persisted_state = PersistedState::new_empty(); let _ = Self::create_buffered_state_from_latest_snapshot( &state_db, @@ -539,6 +546,7 @@ impl StateStore { *SPARSE_MERKLE_PLACEHOLDER_HASH, // TODO(HotState): for now hot state always starts from empty upon restart. latest_snapshot_root_hash, usage, + HotStateConfig::default(), ); let mut buffered_state = BufferedState::new_at_snapshot( state_db, @@ -583,20 +591,18 @@ impl StateStore { .ledger_db .transaction_info_db() .get_transaction_info_iter(snapshot_next_version, write_sets.len())?; - let last_checkpoint_index = txn_info_iter + let all_checkpoint_indices = txn_info_iter .into_iter() .collect::>>()? .into_iter() - .enumerate() - .filter(|(_idx, txn_info)| txn_info.has_state_checkpoint_hash()) - .next_back() - .map(|(idx, _)| idx); + .positions(|txn_info| txn_info.has_state_checkpoint_hash()) + .collect(); let state_update_refs = StateUpdateRefs::index_write_sets( state.next_version(), &write_sets, write_sets.len(), - last_checkpoint_index, + all_checkpoint_indices, ); let current_state = out_current_state.lock().clone(); let (hot_state, state) = out_persisted_state.get_state(); @@ -649,7 +655,7 @@ impl StateStore { &self.buffered_state } - pub fn current_state_locked(&self) -> MutexGuard { + pub fn current_state_locked(&self) -> MutexGuard<'_, LedgerStateWithSummary> { self.current_state.lock() } @@ -661,7 +667,7 @@ impl StateStore { key_prefix: &StateKeyPrefix, first_key_opt: Option<&StateKey>, desired_version: Version, - ) -> Result { + ) -> Result> { // this can only handle non-sharded db scenario. // For sharded db, should look at API side using internal indexer to handle this request PrefixedStateValueIterator::new( @@ -770,9 +776,7 @@ impl StateStore { } pub fn get_usage(&self, version: Option) -> Result { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["get_usage"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["get_usage"]); self.state_db.get_state_storage_usage(version) } @@ -882,7 +886,12 @@ impl StateStore { // TODO(aldenhu): cache changes here, should consume it. let old_entry = cache // TODO(HotState): Revisit: assuming every write op results in a hot slot - .insert((*key).clone(), update_to_cold.to_result_slot()) + .insert( + (*key).clone(), + update_to_cold + .to_result_slot() + .expect("hot state ops should have been filtered out above"), + ) .unwrap_or_else(|| { // n.b. all updated state items must be read and recorded in the state cache, // otherwise we can't calculate the correct usage. The is_untracked() hack @@ -958,7 +967,7 @@ impl StateStore { enable_sharding: bool, ) -> Result<()> { values.iter().for_each(|((key, version), value)| { - let shard_id = key.get_shard_id() as usize; + let shard_id = key.get_shard_id(); assert!( shard_id < NUM_STATE_SHARDS, "Invalid shard id: {}", @@ -989,14 +998,13 @@ impl StateStore { self: &Arc, version: Version, start_idx: usize, - ) -> Result> + Send + Sync> { + ) -> Result> + Send + Sync + use<>> { let store = Arc::clone(self); Ok(JellyfishMerkleIterator::new_by_index( Arc::clone(&self.state_merkle_db), version, start_idx, )? - .map(|it| it) .map(move |res| match res { Ok((_hashed_key, (key, version))) => { Ok((key.clone(), store.expect_value_by_version(&key, version)?)) @@ -1011,21 +1019,40 @@ impl StateStore { first_index: usize, chunk_size: usize, ) -> Result { - let result_iter = JellyfishMerkleIterator::new_by_index( + let state_key_values: Vec<(StateKey, StateValue)> = self + .get_value_chunk_iter(version, first_index, chunk_size)? + .collect::>>()?; + self.get_value_chunk_proof(version, first_index, state_key_values) + } + + pub fn get_value_chunk_iter( + self: &Arc, + version: Version, + first_index: usize, + chunk_size: usize, + ) -> Result> + Send + Sync + use<>> { + let store = Arc::clone(self); + let value_chunk_iter = JellyfishMerkleIterator::new_by_index( Arc::clone(&self.state_merkle_db), version, first_index, )? .take(chunk_size) - .map(|it| it); - let state_key_values: Vec<(StateKey, StateValue)> = result_iter - .into_iter() - .map(|res| { - res.and_then(|(_, (key, version))| { - Ok((key.clone(), self.expect_value_by_version(&key, version)?)) - }) + .map(move |res| { + res.and_then(|(_, (key, version))| { + Ok((key.clone(), store.expect_value_by_version(&key, version)?)) }) - .collect::>>()?; + }); + + Ok(value_chunk_iter) + } + + pub fn get_value_chunk_proof( + self: &Arc, + version: Version, + first_index: usize, + state_key_values: Vec<(StateKey, StateValue)>, + ) -> Result { ensure!( !state_key_values.is_empty(), "State chunk starting at {}", @@ -1088,7 +1115,7 @@ impl StateStore { let mut keys: Vec = all_rows.into_iter().map(|(k, _v)| k).collect(); if self.state_merkle_db.sharding_enabled() { - for i in 0..NUM_STATE_SHARDS as u8 { + for i in 0..NUM_STATE_SHARDS { let mut iter = self.state_merkle_db .db_shard(i) @@ -1104,7 +1131,7 @@ impl StateStore { pub fn init_state_ignoring_summary(&self, version: Option) -> Result<()> { let usage = self.get_usage(version)?; - let state = State::new_at_version(version, usage); + let state = State::new_at_version(version, usage, HotStateConfig::default()); let ledger_state = LedgerState::new(state.clone(), state); self.set_state_ignoring_summary(ledger_state); @@ -1147,9 +1174,7 @@ impl StateValueWriter for StateStore { node_batch: &StateValueBatch, progress: StateSnapshotProgress, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_value_writer_write_chunk"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_value_writer_write_chunk"]); let mut batch = SchemaBatch::new(); let mut sharded_schema_batch = self.state_kv_db.new_sharded_native_batches(); @@ -1165,7 +1190,7 @@ impl StateValueWriter for StateStore { .unwrap() .statekeys_enabled() { - let keys = node_batch.iter().map(|(key, _)| key.0.clone()).collect(); + let keys = node_batch.keys().map(|key| key.0.clone()).collect(); self.internal_indexer_db .as_ref() .unwrap() @@ -1331,7 +1356,7 @@ mod test_only { .iter() .map(|updates| updates.iter().map(|(k, op)| (k, op))), num_versions, - Some(num_versions - 1), + vec![num_versions - 1], ); let mut ledger_batch = SchemaBatch::new(); diff --git a/storage/aptosdb/src/state_store/persisted_state.rs b/storage/aptosdb/src/state_store/persisted_state.rs index fa21ae6db4e..9164d0b0f92 100644 --- a/storage/aptosdb/src/state_store/persisted_state.rs +++ b/storage/aptosdb/src/state_store/persisted_state.rs @@ -9,6 +9,7 @@ use aptos_storage_interface::state_store::{ state::State, state_summary::StateSummary, state_view::hot_state_view::HotStateView, state_with_summary::StateWithSummary, }; +use aptos_types::state_store::hot_state::HotStateConfig; use std::sync::Arc; #[derive(Clone)] @@ -18,34 +19,15 @@ pub struct PersistedState { } impl PersistedState { - // 4 GiB - const HOT_STATE_MAX_BYTES: usize = 4 * 1024 * 1024 * 1024; - // 4 million items - const HOT_STATE_MAX_ITEMS: usize = 4_000_000; - // 10KB, worst case the hot state still caches 400K items - const HOT_STATE_MAX_SINGLE_VALUE_BYTES: usize = 10 * 1024; const MAX_PENDING_DROPS: usize = 8; pub fn new_empty() -> Self { - Self::new_empty_with_config( - Self::HOT_STATE_MAX_ITEMS, - Self::HOT_STATE_MAX_BYTES, - Self::HOT_STATE_MAX_SINGLE_VALUE_BYTES, - ) + Self::new_empty_with_config(HotStateConfig::default()) } - pub fn new_empty_with_config( - hot_state_max_items: usize, - hot_state_max_bytes: usize, - hot_state_max_single_value_bytes: usize, - ) -> Self { - let state = State::new_empty(); - let hot_state = Arc::new(HotState::new( - state, - hot_state_max_items, - hot_state_max_bytes, - hot_state_max_single_value_bytes, - )); + pub fn new_empty_with_config(config: HotStateConfig) -> Self { + let state = State::new_empty(config); + let hot_state = Arc::new(HotState::new(state, config)); let summary = Arc::new(Mutex::new(StateSummary::new_empty())); Self { hot_state, summary } } @@ -60,6 +42,11 @@ impl PersistedState { self.summary.lock().clone() } + #[cfg(test)] + pub fn get_hot_state(&self) -> Arc { + Arc::clone(&self.hot_state) + } + pub fn get_state(&self) -> (Arc, State) { self.hot_state.get_committed() } diff --git a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs index 6050253f51d..99b9781a061 100644 --- a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs +++ b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs @@ -65,14 +65,12 @@ impl StateMerkleBatchCommitter { .state_merkle_db .commit(current_version, top_levels_batch, batches_for_shards) .expect("State merkle nodes commit failed."); - if self.state_db.state_merkle_db.cache_enabled() { + if let Some(lru_cache) = self.state_db.state_merkle_db.lru_cache() { self.state_db .state_merkle_db .version_caches() .iter() - .for_each(|(_, cache)| { - cache.maybe_evict_version(self.state_db.state_merkle_db.lru_cache()) - }); + .for_each(|(_, cache)| cache.maybe_evict_version(lru_cache)); } info!( diff --git a/storage/aptosdb/src/state_store/state_snapshot_committer.rs b/storage/aptosdb/src/state_store/state_snapshot_committer.rs index 5605e8f253c..1d10d057c34 100644 --- a/storage/aptosdb/src/state_store/state_snapshot_committer.rs +++ b/storage/aptosdb/src/state_store/state_snapshot_committer.rs @@ -131,7 +131,7 @@ impl StateSnapshotCommitter { }; self.state_db.state_merkle_db.merklize_value_set_for_shard( - shard_id as u8, + shard_id, jmt_update_refs(&updates), Some(&node_hashes), version, diff --git a/storage/aptosdb/src/state_store/tests/speculative_state_workflow.rs b/storage/aptosdb/src/state_store/tests/speculative_state_workflow.rs index b17c81c4d32..021f9ec5782 100644 --- a/storage/aptosdb/src/state_store/tests/speculative_state_workflow.rs +++ b/storage/aptosdb/src/state_store/tests/speculative_state_workflow.rs @@ -1,7 +1,7 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{db::test_helper::arb_key_universe, state_store::persisted_state::PersistedState}; +use crate::state_store::persisted_state::PersistedState; use aptos_block_executor::hot_state_op_accumulator::BlockHotStateOpAccumulator; use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_infallible::Mutex; @@ -19,20 +19,26 @@ use aptos_storage_interface::{ use aptos_types::{ proof::SparseMerkleProofExt, state_store::{ + hot_state::{HotStateConfig, LRUEntry}, state_key::StateKey, state_slot::StateSlot, state_storage_usage::StateStorageUsage, - state_value::{StateValue, ARB_STATE_VALUE_MAX_SIZE}, - StateViewId, StateViewResult, TStateView, + state_value::StateValue, + StateViewId, StateViewResult, TStateView, NUM_STATE_SHARDS, }, transaction::Version, write_set::{BaseStateOp, HotStateOp, WriteOp}, }; use itertools::Itertools; -use proptest::{collection::vec, prelude::*, sample::Index}; +use lru::LruCache; +use proptest::{ + collection::{hash_set, vec}, + prelude::*, + sample::Index, +}; use rayon::prelude::*; use std::{ - collections::{HashMap, HashSet}, + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, fmt::{Debug, Formatter}, ops::Deref, sync::{ @@ -42,21 +48,27 @@ use std::{ thread::spawn, }; -const NUM_KEYS: usize = 10; -const HOT_STATE_MAX_ITEMS: usize = NUM_KEYS / 2; -const HOT_STATE_MAX_BYTES: usize = NUM_KEYS / 2 * ARB_STATE_VALUE_MAX_SIZE / 3; -const HOT_STATE_MAX_SINGLE_VALUE_BYTES: usize = ARB_STATE_VALUE_MAX_SIZE / 2; +const NUM_KEYS: usize = NUM_STATE_SHARDS * 6; +const HOT_STATE_MAX_ITEMS_PER_SHARD: usize = NUM_KEYS / NUM_STATE_SHARDS / 2; + +// TODO(HotState): these are not used much at the moment. +const MAX_PROMOTIONS_PER_BLOCK: usize = NUM_KEYS; +const REFRESH_INTERVAL_VERSIONS: usize = 50; + +const TEST_CONFIG: HotStateConfig = HotStateConfig { + max_items_per_shard: HOT_STATE_MAX_ITEMS_PER_SHARD, +}; #[derive(Debug)] struct UserTxn { - reads: Vec, - writes: Vec<(StateKey, Option)>, + reads: BTreeSet, + writes: BTreeMap>, } #[derive(Debug)] struct Txn { - reads: Vec, - write_set: Vec<(StateKey, BaseStateOp)>, + reads: BTreeSet, + write_set: BTreeMap, is_checkpoint: bool, } @@ -75,11 +87,9 @@ impl Chunk { update_refs_builder: |txn_outs| { StateUpdateRefs::index( first_version, - txn_outs - .iter() - .map(|t| t.write_set.iter().map(|(key, op)| (key, op))), + txn_outs.iter().map(|t| t.write_set.iter()), txn_outs.len(), - txn_outs.iter().rposition(|t| t.is_checkpoint), + txn_outs.iter().positions(|t| t.is_checkpoint).collect(), ) }, } @@ -90,7 +100,7 @@ impl Chunk { self.borrow_txns().iter().flat_map(|t| &t.reads) } - fn update_refs(&self) -> &StateUpdateRefs { + fn update_refs(&self) -> &StateUpdateRefs<'_> { self.borrow_update_refs() } } @@ -102,7 +112,15 @@ impl Debug for Chunk { } prop_compose! { - pub fn arb_user_block( + fn arb_keys(num_keys: usize)( + raw_keys in hash_set("[a-z0-9]{5}", num_keys), + ) -> Vec { + raw_keys.iter().map(|raw| StateKey::raw(raw.as_bytes())).collect_vec() + } +} + +prop_compose! { + fn arb_user_block( keys: Vec, max_read_only_set_size: usize, max_write_set_size: usize, @@ -125,20 +143,21 @@ prop_compose! { input .into_iter() .map(|(reads, writes)| { - let write_set: HashMap<_, _> = writes + let write_set: BTreeMap<_, _> = writes .into_iter() .map(|(idx, value)| (idx.get(&keys).clone(), value)) .collect(); // The read set is a super set of the write set. - let read_set: HashSet<_> = write_set + let read_set: BTreeSet<_> = write_set .keys() - .chain(reads.iter().map(|idx| idx.get(&keys))) + .cloned() + .chain(reads.iter().map(|idx| idx.get(&keys)).cloned()) .collect(); UserTxn { - reads: read_set.into_iter().cloned().collect(), - writes: write_set.into_iter().collect(), + reads: read_set, + writes: write_set, } }) .collect_vec() @@ -148,6 +167,7 @@ prop_compose! { #[derive(Clone)] struct VersionState { usage: StateStorageUsage, + hot_state: [LruCache; NUM_STATE_SHARDS], state: HashMap, summary: NaiveSmt, next_version: Version, @@ -157,6 +177,7 @@ impl VersionState { fn new_empty() -> Self { Self { usage: StateStorageUsage::zero(), + hot_state: [(); NUM_STATE_SHARDS].map(|_| LruCache::unbounded()), state: HashMap::new(), summary: NaiveSmt::default(), next_version: 0, @@ -166,26 +187,72 @@ impl VersionState { fn update<'a>( &self, version: Version, - kvs: impl IntoIterator)>, + writes: impl IntoIterator)>, + promotions: impl IntoIterator, + is_checkpoint: bool, ) -> Self { assert_eq!(version, self.next_version); + let mut hot_state = self.hot_state.clone(); let mut state = self.state.clone(); let mut smt_updates = vec![]; - for (k, v_opt) in kvs.into_iter() { + for (k, v_opt) in writes { + let shard_id = k.get_shard_id(); match v_opt { None => { + let slot = StateSlot::HotVacant { + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }; + hot_state[shard_id].put(k.clone(), slot); state.remove(k); smt_updates.push((k.hash(), None)); }, Some(v) => { + let slot = StateSlot::HotOccupied { + value_version: version, + value: v.clone(), + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }; + hot_state[shard_id].put(k.clone(), slot); state.insert(k.clone(), (version, v.clone())); smt_updates.push((k.hash(), Some(v.hash()))); }, } } + for k in promotions { + assert!(is_checkpoint, "No promotions unless in checkpoints"); + let shard_id = k.get_shard_id(); + if let Some(slot) = hot_state[shard_id].get_mut(k) { + slot.refresh(version); + continue; + } + let slot = match state.get(k) { + Some((value_version, value)) => StateSlot::HotOccupied { + value_version: *value_version, + value: value.clone(), + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }, + None => StateSlot::HotVacant { + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }, + }; + hot_state[shard_id].put(k.clone(), slot); + } + + if is_checkpoint { + for shard in hot_state.iter_mut() { + while shard.len() > HOT_STATE_MAX_ITEMS_PER_SHARD { + shard.pop_lru(); + } + } + } + let summary = self.summary.clone().update(&smt_updates); let items = state.len(); @@ -193,9 +260,10 @@ impl VersionState { let usage = StateStorageUsage::new(items, bytes); Self { + usage, + hot_state, state, summary, - usage, next_version: version + 1, } } @@ -205,7 +273,16 @@ impl TStateView for VersionState { type Key = StateKey; fn get_state_slot(&self, key: &Self::Key) -> StateViewResult { - Ok(StateSlot::from_db_get(self.state.get(key).cloned())) + let from_cold = StateSlot::from_db_get(self.state.get(key).cloned()); + let shard_id = key.get_shard_id(); + let slot = match self.hot_state[shard_id].peek(key) { + Some(slot) => { + assert_eq!(slot.as_state_value_opt(), from_cold.as_state_value_opt()); + slot.clone() + }, + None => from_cold, + }; + Ok(slot) } fn get_usage(&self) -> StateViewResult { @@ -222,7 +299,7 @@ struct StateByVersion { } impl StateByVersion { - pub fn get_state(&self, version: Option) -> &Arc { + fn get_state(&self, version: Option) -> &VersionState { let next_version = version.map_or(0, |ver| ver + 1); &self.state_by_next_version[next_version as usize] } @@ -235,14 +312,17 @@ impl StateByVersion { fn append_version<'a>( &mut self, - kvs: impl IntoIterator)>, + writes: impl IntoIterator)>, + promotions: impl IntoIterator, + is_checkpoint: bool, ) { - let kvs = kvs.into_iter().collect_vec(); self.state_by_next_version.push(Arc::new( - self.state_by_next_version - .last() - .unwrap() - .update(self.next_version(), kvs.clone()), + self.state_by_next_version.last().unwrap().update( + self.next_version(), + writes, + promotions, + is_checkpoint, + ), )); } @@ -250,11 +330,45 @@ impl StateByVersion { self.state_by_next_version.len() as Version - 1 } + fn assert_state_slot(slot1: &StateSlot, slot2: &StateSlot) { + match (slot1, slot2) { + ( + StateSlot::HotVacant { + hot_since_version: v1, + .. + }, + StateSlot::HotVacant { + hot_since_version: v2, + .. + }, + ) => assert_eq!(v1, v2), + ( + StateSlot::HotOccupied { + value_version: vv1, + value: v1, + hot_since_version: h1, + .. + }, + StateSlot::HotOccupied { + value_version: vv2, + value: v2, + hot_since_version: h2, + .. + }, + ) => { + assert_eq!(vv1, vv2); + assert_eq!(v1, v2); + assert_eq!(h1, h2); + }, + (s1, s2) => assert_eq!(s1, s2), + } + } + fn assert_state(&self, state: &State) { assert_eq!(state.usage(), self.get_state(state.version()).usage); } - pub fn assert_ledger_state(&self, ledger_state: &LedgerState) { + fn assert_ledger_state(&self, ledger_state: &LedgerState) { self.assert_state(ledger_state.last_checkpoint()); self.assert_state(ledger_state.latest()); } @@ -268,16 +382,12 @@ impl StateByVersion { ); } - pub fn assert_ledger_state_summary(&self, ledger_state_summary: &LedgerStateSummary) { + fn assert_ledger_state_summary(&self, ledger_state_summary: &LedgerStateSummary) { self.assert_state_summary(ledger_state_summary.last_checkpoint()); self.assert_state_summary(ledger_state_summary.latest()); } - pub fn assert_jmt_updates( - &self, - last_snapshot: &StateWithSummary, - snapshot: &StateWithSummary, - ) { + fn assert_jmt_updates(&self, last_snapshot: &StateWithSummary, snapshot: &StateWithSummary) { let base_state = self.get_state(last_snapshot.version()).clone(); let result_state = self.get_state(snapshot.version()).clone(); assert_eq!( @@ -415,6 +525,7 @@ fn update_state( let memorized_reads = state_view.into_memorized_reads(); let next_state = parent_state.update_with_memorized_reads( + hot_state.clone(), &persisted_state, block.update_refs(), &memorized_reads, @@ -487,32 +598,65 @@ fn send_to_state_buffer( } } + // Make sure the final checkpoint is committed. + let final_state_with_summary: LedgerStateWithSummary = current_state.lock().clone(); + assert!(final_state_with_summary.is_at_checkpoint()); + let final_version = final_state_with_summary.version().unwrap(); + if last_snapshot.version() != Some(final_version) { + let snapshot = final_state_with_summary.last_checkpoint(); + state_by_version.assert_jmt_updates(&last_snapshot, snapshot); + to_buffered_state_commit.send(snapshot.clone()).unwrap(); + } + // inform downstream to quit drop(to_buffered_state_commit); } fn commit_state_buffer( + state_by_version: Arc, from_buffered_state_commit: Receiver, persisted_state: PersistedState, ) { while let Ok(snapshot) = from_buffered_state_commit.recv() { + let next_version = snapshot.next_version(); persisted_state.set(snapshot); + + let hot_state = persisted_state.get_hot_state(); + hot_state.wait_for_commit(next_version); + + (0..NUM_STATE_SHARDS).into_par_iter().for_each(|shard_id| { + let all_entries = hot_state.get_all_entries(shard_id); + let naive_hot_state = + &state_by_version.get_state(Some(next_version - 1)).hot_state[shard_id]; + assert_eq!(all_entries.len(), naive_hot_state.len()); + + for (key, slot) in &all_entries { + let slot2 = naive_hot_state.peek(key).unwrap(); + StateByVersion::assert_state_slot(slot, slot2); + } + }); } } fn naive_run_blocks(blocks: Vec<(Vec, bool)>) -> (Vec, StateByVersion) { let mut all_txns = vec![]; let mut state_by_version = StateByVersion::new_empty(); - let mut next_version: Version = 0; for (block_txns, append_epilogue) in blocks { - let base_view = state_by_version - .get_state(next_version.checked_sub(1)) - .clone(); - let mut op_accu = - BlockHotStateOpAccumulator::::new_with_config(&base_view, 10, 50); - for txn in block_txns { - state_by_version.append_version(txn.writes.iter().map(|(k, v)| (k, v.as_ref()))); - op_accu.add_transaction(txn.writes.iter().map(|(k, _v)| k), txn.reads.iter()); + let mut op_accu = BlockHotStateOpAccumulator::::new_with_config( + MAX_PROMOTIONS_PER_BLOCK, + REFRESH_INTERVAL_VERSIONS, + ); + let num_txns = block_txns.len(); + for (idx, txn) in block_txns.into_iter().enumerate() { + // No promotions except for block epilogue. Also note that in case of reconfig, there's + // no epilogue, but we still have a checkpoint and will run eviction on hot state. + let is_checkpoint = !append_epilogue && idx + 1 == num_txns; + state_by_version.append_version( + txn.writes.iter().map(|(k, v)| (k, v.as_ref())), + vec![], + is_checkpoint, + ); + op_accu.add_transaction(txn.writes.keys(), txn.reads.iter()); all_txns.push(Txn { reads: txn.reads, write_set: txn @@ -525,25 +669,22 @@ fn naive_run_blocks(blocks: Vec<(Vec, bool)>) -> (Vec, StateByVers .collect(), is_checkpoint: false, }); - next_version += 1; } if append_epilogue { - // TODO(HotState): revisit - // all ops are hotness only, no effect on the global state - state_by_version.append_version(vec![]); + let to_make_hot = op_accu.get_keys_to_make_hot(); + let is_checkpoint = true; + state_by_version.append_version(vec![], to_make_hot.iter(), is_checkpoint); - let write_set = op_accu - .get_slots_to_make_hot() + let reads = to_make_hot.clone(); + let write_set = to_make_hot .into_iter() - .map(|(k, slot)| (k, HotStateOp::make_hot(slot).into_base_op())) - .collect_vec(); - let reads = write_set.iter().map(|(k, _op)| k.clone()).collect_vec(); + .map(|k| (k, HotStateOp::make_hot().into_base_op())) + .collect(); all_txns.push(Txn { reads, write_set, is_checkpoint: true, }); - next_version += 1; } } @@ -551,14 +692,10 @@ fn naive_run_blocks(blocks: Vec<(Vec, bool)>) -> (Vec, StateByVers } fn replay_chunks_pipelined(chunks: Vec, state_by_version: Arc) { - let empty = LedgerStateWithSummary::new_empty(); + let empty = LedgerStateWithSummary::new_empty(TEST_CONFIG); let current_state = Arc::new(Mutex::new(empty.clone())); - let persisted_state = PersistedState::new_empty_with_config( - HOT_STATE_MAX_ITEMS, - HOT_STATE_MAX_BYTES, - HOT_STATE_MAX_SINGLE_VALUE_BYTES, - ); + let persisted_state = PersistedState::new_empty_with_config(TEST_CONFIG); persisted_state.hack_reset(empty.deref().clone()); let (to_summary_update, from_state_update) = channel(); @@ -613,9 +750,14 @@ fn replay_chunks_pipelined(chunks: Vec, state_by_version: Arc, state_by_version: ArcJust(false), 9=>Just(true)] - ), 1..100) + ( + vec( + ( + arb_user_block(keys.clone(), NUM_KEYS, NUM_KEYS, NUM_KEYS), + prop_oneof![1=>Just(false), 9=>Just(true)] + ), + 1..100 + ), + arb_user_block(keys, NUM_KEYS, NUM_KEYS, NUM_KEYS) + ) }) ) { + blocks.push((last_block, /* is_checkpoint */ true)); let (all_txns, state_by_version) = naive_run_blocks(blocks); diff --git a/storage/aptosdb/src/transaction_store/mod.rs b/storage/aptosdb/src/transaction_store/mod.rs index 5eed6fc5aaa..9b5a8da3ee1 100644 --- a/storage/aptosdb/src/transaction_store/mod.rs +++ b/storage/aptosdb/src/transaction_store/mod.rs @@ -64,7 +64,7 @@ impl TransactionStore { min_seq_num: u64, num_versions: u64, ledger_version: Version, - ) -> Result { + ) -> Result> { let mut iter = self .ledger_db .transaction_db_raw() @@ -88,7 +88,7 @@ impl TransactionStore { end_version: Option, limit: u64, ledger_version: Version, - ) -> Result { + ) -> Result> { // Question[Orderless]: When start version is specified, we are current scanning forward from start version. // When start version is not specified we are scanning backward, so as to return the most recent transactions. // This doesn't seem to be a good design. Should we instead let the API take scan direction as input? diff --git a/storage/aptosdb/src/utils/mod.rs b/storage/aptosdb/src/utils/mod.rs index 7bdfb3b53fb..fea102209b2 100644 --- a/storage/aptosdb/src/utils/mod.rs +++ b/storage/aptosdb/src/utils/mod.rs @@ -6,8 +6,8 @@ pub(crate) mod truncation_helper; use crate::schema::db_metadata::{DbMetadataKey, DbMetadataSchema}; use aptos_schemadb::{batch::NativeBatch, DB}; -use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, Result}; -use aptos_types::transaction::Version; +use aptos_storage_interface::Result; +use aptos_types::{state_store::NUM_STATE_SHARDS, transaction::Version}; pub(crate) type ShardedStateKvSchemaBatch<'db> = [NativeBatch<'db>; NUM_STATE_SHARDS]; diff --git a/storage/aptosdb/src/utils/truncation_helper.rs b/storage/aptosdb/src/utils/truncation_helper.rs index 057f76ef7a0..128e80fc7c4 100644 --- a/storage/aptosdb/src/utils/truncation_helper.rs +++ b/storage/aptosdb/src/utils/truncation_helper.rs @@ -122,13 +122,13 @@ pub(crate) fn truncate_state_kv_db_shards( (0..state_kv_db.hack_num_real_shards()) .into_par_iter() .try_for_each(|shard_id| { - truncate_state_kv_db_single_shard(state_kv_db, shard_id as u8, target_version) + truncate_state_kv_db_single_shard(state_kv_db, shard_id, target_version) }) } pub(crate) fn truncate_state_kv_db_single_shard( state_kv_db: &StateKvDb, - shard_id: u8, + shard_id: usize, target_version: Version, ) -> Result<()> { let mut batch = SchemaBatch::new(); @@ -186,13 +186,13 @@ pub(crate) fn truncate_state_merkle_db_shards( (0..state_merkle_db.hack_num_real_shards()) .into_par_iter() .try_for_each(|shard_id| { - truncate_state_merkle_db_single_shard(state_merkle_db, shard_id as u8, target_version) + truncate_state_merkle_db_single_shard(state_merkle_db, shard_id, target_version) }) } pub(crate) fn truncate_state_merkle_db_single_shard( state_merkle_db: &StateMerkleDb, - shard_id: u8, + shard_id: usize, target_version: Version, ) -> Result<()> { let mut batch = SchemaBatch::new(); @@ -264,7 +264,7 @@ pub(crate) fn get_max_version_in_state_merkle_db( state_merkle_db: &StateMerkleDb, ) -> Result> { let mut version = get_current_version_in_state_merkle_db(state_merkle_db)?; - let num_real_shards = state_merkle_db.hack_num_real_shards() as u8; + let num_real_shards = state_merkle_db.hack_num_real_shards(); if num_real_shards > 1 { for shard_id in 0..num_real_shards { let shard_version = find_closest_node_version_at_or_before( @@ -603,7 +603,7 @@ where fn delete_nodes_and_stale_indices_at_or_after_version( db: &DB, version: Version, - shard_id: Option, + shard_id: Option, batch: &mut SchemaBatch, ) -> Result<()> { delete_stale_node_index_at_or_after_version::(db, version, batch)?; diff --git a/storage/aptosdb/src/versioned_node_cache.rs b/storage/aptosdb/src/versioned_node_cache.rs index 688614493ec..a177e493608 100644 --- a/storage/aptosdb/src/versioned_node_cache.rs +++ b/storage/aptosdb/src/versioned_node_cache.rs @@ -5,6 +5,7 @@ use crate::{lru_node_cache::LruNodeCache, metrics::OTHER_TIMERS_SECONDS, state_m use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_infallible::RwLock; use aptos_jellyfish_merkle::node_type::NodeKey; +use aptos_metrics_core::TimerHelper; use aptos_types::transaction::Version; use rayon::prelude::*; use std::{ @@ -40,9 +41,7 @@ impl VersionedNodeCache { } pub fn add_version(&self, version: Version, nodes: NodeCache) { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["version_cache_add"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["version_cache_add"]); let mut locked = self.inner.write(); if !locked.is_empty() { @@ -58,9 +57,7 @@ impl VersionedNodeCache { } pub fn maybe_evict_version(&self, lru_cache: &LruNodeCache) { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["version_cache_evict"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["version_cache_evict"]); let to_evict = { let locked = self.inner.read(); diff --git a/storage/backup/backup-cli/src/backup_types/epoch_ending/tests.rs b/storage/backup/backup-cli/src/backup_types/epoch_ending/tests.rs index 63f12e11acd..923a36a572b 100644 --- a/storage/backup/backup-cli/src/backup_types/epoch_ending/tests.rs +++ b/storage/backup/backup-cli/src/backup_types/epoch_ending/tests.rs @@ -141,8 +141,8 @@ prop_compose! { let mut should_fail_without_waypoints = false; let mut res_lis = Vec::new(); let mut res_waypoints = Vec::new(); - for (block_size, gen, overwrite, trusted) in blocks { - let mut li = gen.materialize(&mut universe, block_size); + for (block_size, r#gen, overwrite, trusted) in blocks { + let mut li = r#gen.materialize(&mut universe, block_size); if li.ledger_info().ends_epoch() { if overwrite && li.ledger_info().epoch() != 0 { li = LedgerInfoWithSignatures::new( diff --git a/storage/backup/backup-cli/src/backup_types/state_snapshot/backup.rs b/storage/backup/backup-cli/src/backup_types/state_snapshot/backup.rs index 155858011d8..0a62d136bf2 100644 --- a/storage/backup/backup-cli/src/backup_types/state_snapshot/backup.rs +++ b/storage/backup/backup-cli/src/backup_types/state_snapshot/backup.rs @@ -272,7 +272,8 @@ impl StateSnapshotBackupController { async fn record_stream( &self, concurrency: usize, - ) -> Result>> { + ) -> Result> + use<>> + { const CHUNK_SIZE: usize = if cfg!(test) { 2 } else { 100_000 }; let count = self.client.get_state_item_count(self.version()).await?; diff --git a/storage/backup/backup-cli/src/backup_types/state_snapshot/restore.rs b/storage/backup/backup-cli/src/backup_types/state_snapshot/restore.rs index 0a32a2f2747..9f34a056f1a 100644 --- a/storage/backup/backup-cli/src/backup_types/state_snapshot/restore.rs +++ b/storage/backup/backup-cli/src/backup_types/state_snapshot/restore.rs @@ -26,6 +26,7 @@ use anyhow::{anyhow, ensure, Result}; use aptos_db::state_restore::StateSnapshotRestoreMode; use aptos_infallible::Mutex; use aptos_logger::prelude::*; +use aptos_metrics_core::TimerHelper; use aptos_storage_interface::StateSnapshotReceiver; use aptos_types::{ access_path::Path, @@ -38,7 +39,7 @@ use aptos_types::{ }, transaction::Version, }; -use aptos_vm_environment::prod_configs::aptos_prod_verifier_config; +use aptos_vm_environment::prod_configs::{aptos_prod_verifier_config, LATEST_GAS_FEATURE_VERSION}; use clap::Parser; use futures::{stream, TryStreamExt}; use move_binary_format::CompiledModule; @@ -200,9 +201,7 @@ impl StateSnapshotRestoreController { let mut start = None; while let Some((chunk_idx, chunk, mut blobs, proof)) = futs_stream.try_next().await? { start = start.or_else(|| Some(Instant::now())); - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["add_state_chunk"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["add_state_chunk"]); let receiver = receiver.clone(); if self.validate_modules { blobs = tokio::task::spawn_blocking(move || { @@ -233,10 +232,10 @@ impl StateSnapshotRestoreController { } fn validate_modules(blob: &[(StateKey, StateValue)]) { - // TODO: Instead of using default features, fetch them from the the state. + // TODO: Instead of using default features, fetch them from the state. let features = Features::default(); - let config = aptos_prod_verifier_config(&features); + let config = aptos_prod_verifier_config(LATEST_GAS_FEATURE_VERSION, &features); for (key, value) in blob { if let StateKeyInner::AccessPath(p) = key.inner() { if let Path::Code(module_id) = p.get_path() { diff --git a/storage/backup/backup-cli/src/backup_types/state_snapshot/tests.rs b/storage/backup/backup-cli/src/backup_types/state_snapshot/tests.rs index 9f9160c4da6..c02a98d3ae1 100644 --- a/storage/backup/backup-cli/src/backup_types/state_snapshot/tests.rs +++ b/storage/backup/backup-cli/src/backup_types/state_snapshot/tests.rs @@ -46,6 +46,7 @@ fn end_to_end() { let state_root_hash = src_db .get_transactions(version, 1, version, false) .unwrap() + .consume_transaction_list_with_proof() .proof .transaction_infos .pop() diff --git a/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs b/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs index 95177512f36..764634e3542 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs @@ -5,7 +5,7 @@ use anyhow::Result; use aptos_types::{ contract_event::ContractEvent, - transaction::{Transaction, TransactionInfo, Version}, + transaction::{PersistedAuxiliaryInfo, Transaction, TransactionInfo, Version}, write_set::{TransactionWrite, WriteSet}, }; use serde::Serialize; @@ -69,6 +69,7 @@ impl TransactionAnalysis { &mut self, version: Version, txn: &Transaction, + _persisted_aux_info: &PersistedAuxiliaryInfo, _txn_info: &TransactionInfo, events: &[ContractEvent], write_set: &WriteSet, diff --git a/storage/backup/backup-cli/src/backup_types/transaction/backup.rs b/storage/backup/backup-cli/src/backup_types/transaction/backup.rs index 86ce1b8c553..833aceb3d36 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/backup.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/backup.rs @@ -3,7 +3,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - backup_types::transaction::manifest::{TransactionBackup, TransactionChunk}, + backup_types::transaction::manifest::{ + TransactionBackup, TransactionChunk, TransactionChunkFormat, + }, metadata::Metadata, storage::{BackupHandleRef, BackupStorage, FileHandle, ShellSafeName}, utils::{ @@ -181,6 +183,7 @@ impl TransactionBackupController { last_version, transactions: chunk_handle, proof: proof_handle, + format: TransactionChunkFormat::V1, }) } diff --git a/storage/backup/backup-cli/src/backup_types/transaction/manifest.rs b/storage/backup/backup-cli/src/backup_types/transaction/manifest.rs index 96aa2facd91..69386f863e4 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/manifest.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/manifest.rs @@ -7,6 +7,14 @@ use anyhow::{ensure, Result}; use aptos_types::transaction::Version; use serde::{Deserialize, Serialize}; +#[derive(Clone, Deserialize, Serialize, Debug)] +pub enum TransactionChunkFormat { + // (Transaction, TransactionInfo, Vec, WriteSet) + V0, + // (Transaction, PersistedAuxiliaryInfo, TransactionInfo, Vec, WriteSet) + V1, +} + /// A chunk of a transaction backup manifest to represent the /// [`first_version`, `last_version`] range (right side inclusive). #[derive(Clone, Deserialize, Serialize, Debug)] @@ -22,6 +30,12 @@ pub struct TransactionChunk { /// signatures it carries, against the validator set in the epoch. (Hence proper /// `EpochEndingBackup` is needed for verification.) pub proof: FileHandle, + #[serde(default = "default_to_v0")] + pub format: TransactionChunkFormat, +} + +fn default_to_v0() -> TransactionChunkFormat { + TransactionChunkFormat::V0 } /// Transaction backup manifest, representing transactions in the diff --git a/storage/backup/backup-cli/src/backup_types/transaction/restore.rs b/storage/backup/backup-cli/src/backup_types/transaction/restore.rs index cfb0481c877..c881964b7f7 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/restore.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/restore.rs @@ -7,7 +7,7 @@ use crate::{ epoch_ending::restore::EpochHistory, transaction::{ analysis::TransactionAnalysis, - manifest::{TransactionBackup, TransactionChunk}, + manifest::{TransactionBackup, TransactionChunk, TransactionChunkFormat}, }, }, metrics::{ @@ -35,7 +35,10 @@ use aptos_types::{ contract_event::ContractEvent, ledger_info::LedgerInfoWithSignatures, proof::{TransactionAccumulatorRangeProof, TransactionInfoListWithProof}, - transaction::{Transaction, TransactionInfo, TransactionListWithProof, Version}, + transaction::{ + PersistedAuxiliaryInfo, Transaction, TransactionInfo, TransactionListWithAuxiliaryInfos, + TransactionListWithProof, TransactionListWithProofV2, Version, + }, write_set::WriteSet, }; use aptos_vm::{aptos_vm::AptosVMBlockExecutor, AptosVM}; @@ -84,15 +87,14 @@ pub struct TransactionRestoreController { inner: TransactionRestoreBatchController, } -#[allow(dead_code)] struct LoadedChunk { pub manifest: TransactionChunk, pub txns: Vec, + pub persisted_aux_info: Vec, pub txn_infos: Vec, pub event_vecs: Vec>, pub write_sets: Vec, pub range_proof: TransactionAccumulatorRangeProof, - pub ledger_info: LedgerInfoWithSignatures, } impl LoadedChunk { @@ -103,14 +105,33 @@ impl LoadedChunk { ) -> Result { let mut file = BufReader::new(storage.open_for_read(&manifest.transactions).await?); let mut txns = Vec::new(); + let mut persisted_aux_info = Vec::new(); let mut txn_infos = Vec::new(); let mut event_vecs = Vec::new(); let mut write_sets = Vec::new(); while let Some(record_bytes) = file.read_record_bytes().await? { - let (txn, txn_info, events, write_set): (_, _, _, WriteSet) = - bcs::from_bytes(&record_bytes)?; + let (txn, aux_info, txn_info, events, write_set): ( + _, + PersistedAuxiliaryInfo, + _, + _, + WriteSet, + ) = match manifest.format { + TransactionChunkFormat::V0 => { + let (txn, txn_info, events, write_set) = bcs::from_bytes(&record_bytes)?; + ( + txn, + PersistedAuxiliaryInfo::None, + txn_info, + events, + write_set, + ) + }, + TransactionChunkFormat::V1 => bcs::from_bytes(&record_bytes)?, + }; txns.push(txn); + persisted_aux_info.push(aux_info); txn_infos.push(txn_info); event_vecs.push(events); write_sets.push(write_set); @@ -134,14 +155,19 @@ impl LoadedChunk { } // make a `TransactionListWithProof` to reuse its verification code. - let txn_list_with_proof = TransactionListWithProof::new( - txns, - Some(event_vecs), - Some(manifest.first_version), - TransactionInfoListWithProof::new(range_proof, txn_infos), - ); + let txn_list_with_proof = + TransactionListWithProofV2::new(TransactionListWithAuxiliaryInfos::new( + TransactionListWithProof::new( + txns, + Some(event_vecs), + Some(manifest.first_version), + TransactionInfoListWithProof::new(range_proof, txn_infos), + ), + persisted_aux_info, + )); txn_list_with_proof.verify(ledger_info.ledger_info(), Some(manifest.first_version))?; // and disassemble it to get things back. + let (txn_list_with_proof, persisted_aux_info) = txn_list_with_proof.into_parts(); let txns = txn_list_with_proof.transactions; let range_proof = txn_list_with_proof .proof @@ -152,10 +178,10 @@ impl LoadedChunk { Ok(Self { manifest, txns, + persisted_aux_info, txn_infos, event_vecs, range_proof, - ledger_info, write_sets, }) } @@ -164,6 +190,7 @@ impl LoadedChunk { self, ) -> ( Vec, + Vec, Vec, Vec>, Vec, @@ -171,14 +198,14 @@ impl LoadedChunk { let Self { manifest: _, txns, + persisted_aux_info, txn_infos, event_vecs, write_sets, range_proof: _, - ledger_info: _, } = self; - (txns, txn_infos, event_vecs, write_sets) + (txns, persisted_aux_info, txn_infos, event_vecs, write_sets) } } @@ -312,7 +339,7 @@ impl TransactionRestoreBatchController { Ok(()) } - fn loaded_chunk_stream(&self) -> Peekable>> { + fn loaded_chunk_stream(&self) -> Peekable> + use<>> { let con = self.global_opt.concurrent_downloads; let manifest_handle_stream = stream::iter(self.manifest_handles.clone()); @@ -402,7 +429,15 @@ impl TransactionRestoreBatchController { restore_handler: &RestoreHandler, ) -> Result< Option< - impl Stream)>>, + impl Stream< + Item = Result<( + Transaction, + PersistedAuxiliaryInfo, + TransactionInfo, + WriteSet, + Vec, + )>, + >, >, > { // get the next expected transaction version of the current aptos db from txn_info CF @@ -429,12 +464,19 @@ impl TransactionRestoreBatchController { future::ok(async move { let mut first_version = chunk.manifest.first_version; let mut last_version = chunk.manifest.last_version; - let (mut txns, mut txn_infos, mut event_vecs, mut write_sets) = chunk.unpack(); + let ( + mut txns, + mut persisted_aux_info, + mut txn_infos, + mut event_vecs, + mut write_sets, + ) = chunk.unpack(); // remove the txns that exceeds the target_version to be restored if target_version < last_version { let num_to_keep = (target_version - first_version + 1) as usize; txns.drain(num_to_keep..); + persisted_aux_info.drain(num_to_keep..); txn_infos.drain(num_to_keep..); event_vecs.drain(num_to_keep..); write_sets.drain(num_to_keep..); @@ -446,6 +488,7 @@ impl TransactionRestoreBatchController { let num_to_remove = (global_first_version - first_version) as usize; txns.drain(..num_to_remove); + persisted_aux_info.drain(..num_to_remove); txn_infos.drain(..num_to_remove); event_vecs.drain(..num_to_remove); write_sets.drain(..num_to_remove); @@ -457,6 +500,8 @@ impl TransactionRestoreBatchController { let num_to_save = (min(first_to_replay, last_version + 1) - first_version) as usize; let txns_to_save: Vec<_> = txns.drain(..num_to_save).collect(); + let persisted_aux_info_to_save: Vec<_> = + persisted_aux_info.drain(..num_to_save).collect(); let txn_infos_to_save: Vec<_> = txn_infos.drain(..num_to_save).collect(); let event_vecs_to_save: Vec<_> = event_vecs.drain(..num_to_save).collect(); let write_sets_to_save = write_sets.drain(..num_to_save).collect(); @@ -464,6 +509,7 @@ impl TransactionRestoreBatchController { restore_handler.save_transactions( first_version, &txns_to_save, + &persisted_aux_info_to_save, &txn_infos_to_save, &event_vecs_to_save, write_sets_to_save, @@ -483,7 +529,8 @@ impl TransactionRestoreBatchController { // create iterator of txn and its outputs to be replayed after the snapshot. Ok(stream::iter( - izip!(txns, txn_infos, write_sets, event_vecs).map(Result::<_>::Ok), + izip!(txns, persisted_aux_info, txn_infos, write_sets, event_vecs) + .map(Result::<_>::Ok), )) }) }) @@ -509,7 +556,13 @@ impl TransactionRestoreBatchController { &self, restore_handler: &RestoreHandler, txns_to_execute_stream: impl Stream< - Item = Result<(Transaction, TransactionInfo, WriteSet, Vec)>, + Item = Result<( + Transaction, + PersistedAuxiliaryInfo, + TransactionInfo, + WriteSet, + Vec, + )>, >, ) -> Result<()> { let (first_version, _) = self.replay_from_version.unwrap(); @@ -524,20 +577,24 @@ impl TransactionRestoreBatchController { .try_chunks(BATCH_SIZE) .err_into::() .map_ok(|chunk| { - let (txns, txn_infos, write_sets, events): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = - chunk.into_iter().multiunzip(); + let (txns, persisted_aux_info, txn_infos, write_sets, events): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = chunk.into_iter().multiunzip(); let handler = arc_restore_handler.clone(); base_version += offset; offset = txns.len() as u64; async move { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["replay_txn_chunk_kv_only"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["replay_txn_chunk_kv_only"]); tokio::task::spawn_blocking(move || { // we directly save transaction and kvs to DB without involving chunk executor handler.save_transactions_and_replay_kv( base_version, &txns, + &persisted_aux_info, &txn_infos, &events, write_sets, @@ -554,9 +611,7 @@ impl TransactionRestoreBatchController { let total_replayed = db_commit_stream .and_then(|version| async move { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_txn_chunk_kv_only"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_txn_chunk_kv_only"]); tokio::task::spawn_blocking(move || { // version is the latest version finishing the KV replaying let total_replayed = version - first_version; @@ -587,7 +642,13 @@ impl TransactionRestoreBatchController { &self, restore_handler: &RestoreHandler, txns_to_execute_stream: impl Stream< - Item = Result<(Transaction, TransactionInfo, WriteSet, Vec)>, + Item = Result<( + Transaction, + PersistedAuxiliaryInfo, + TransactionInfo, + WriteSet, + Vec, + )>, >, ) -> Result<()> { let (first_version, _) = self.replay_from_version.unwrap(); @@ -599,8 +660,13 @@ impl TransactionRestoreBatchController { .try_chunks(BATCH_SIZE) .err_into::() .map_ok(|chunk| { - let (txns, txn_infos, write_sets, events): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = - chunk.into_iter().multiunzip(); + let (txns, persisted_aux_info, txn_infos, write_sets, events): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = chunk.into_iter().multiunzip(); let chunk_replayer = chunk_replayer.clone(); let verify_execution_mode = self.verify_execution_mode.clone(); @@ -610,6 +676,7 @@ impl TransactionRestoreBatchController { tokio::task::spawn_blocking(move || { chunk_replayer.enqueue_chunks( txns, + persisted_aux_info, txn_infos, write_sets, events, @@ -693,9 +760,18 @@ impl TransactionRestoreBatchController { let mut version = chunk.manifest.first_version; let last_version = chunk.manifest.last_version; - for (txn, txn_info, events, write_set) in itertools::multizip(chunk.unpack()) { + for (txn, persisted_aux_info, txn_info, events, write_set) in + itertools::multizip(chunk.unpack()) + { if let Some(analysis) = &mut analysis { - analysis.add_transaction(version, &txn, &txn_info, &events, &write_set)?; + analysis.add_transaction( + version, + &txn, + &persisted_aux_info, + &txn_info, + &events, + &write_set, + )?; } version += 1; } diff --git a/storage/backup/backup-cli/src/backup_types/transaction/tests.rs b/storage/backup/backup-cli/src/backup_types/transaction/tests.rs index f53e7e3f963..3a34c4c0614 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/tests.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/tests.rs @@ -128,7 +128,8 @@ fn end_to_end() { let tgt_db = AptosDB::new_readonly_for_test(&tgt_db_dir); let ouptputlist = tgt_db .get_transaction_outputs(0, target_version, target_version) - .unwrap(); + .unwrap() + .consume_output_list_with_proof(); for (restore_ws, org_ws) in zip_eq( ouptputlist @@ -145,6 +146,7 @@ fn end_to_end() { } assert_eq!(tgt_db.expect_synced_version(), target_version); + // TODO(grao): Test PersistedAuxiliaryInfo here. let recovered_transactions = tgt_db .get_transactions( 0, @@ -152,7 +154,8 @@ fn end_to_end() { target_version, true, /* fetch_events */ ) - .unwrap(); + .unwrap() + .consume_transaction_list_with_proof(); assert_eq!( recovered_transactions.transactions, diff --git a/storage/backup/backup-cli/src/storage/command_adapter/command.rs b/storage/backup/backup-cli/src/storage/command_adapter/command.rs index 12ef74e230c..b0d4e9ba60b 100644 --- a/storage/backup/backup-cli/src/storage/command_adapter/command.rs +++ b/storage/backup/backup-cli/src/storage/command_adapter/command.rs @@ -161,7 +161,7 @@ impl AsyncRead for ChildStdoutAsDataSource<'_> { Pin::new(self.join_fut.as_mut().unwrap()) .poll(cx) - .map_err(|e| ::std::io::Error::new(::std::io::ErrorKind::Other, e)) + .map_err(::std::io::Error::other) } } @@ -219,6 +219,6 @@ impl AsyncWrite for ChildStdinAsDataSink<'_> { Pin::new(self.join_fut.as_mut().unwrap()) .poll(cx) - .map_err(|e| tokio::io::Error::new(tokio::io::ErrorKind::Other, e)) + .map_err(tokio::io::Error::other) } } diff --git a/storage/backup/backup-cli/src/storage/command_adapter/tests.rs b/storage/backup/backup-cli/src/storage/command_adapter/tests.rs index 03f7fb6de68..2b52bde145a 100644 --- a/storage/backup/backup-cli/src/storage/command_adapter/tests.rs +++ b/storage/backup/backup-cli/src/storage/command_adapter/tests.rs @@ -168,13 +168,15 @@ fn test_unprocessed_error() { #[test] fn test_unset_env_var() { - std::env::remove_var("MYVAR2343u2"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var("MYVAR2343u2") }; block_on(assert_commands_error( "echo $MYVAR2343u2 > /dev/null; echo okay; exec 1>&-; cat > /dev/null", )); // variable set - std::env::set_var("MYVAR2343u2", "hehe"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var("MYVAR2343u2", "hehe") }; block_on(assert_commands_okay( "echo $MYVAR2343u2 > /dev/null; echo okay; exec 1>&-; cat > /dev/null", )); diff --git a/storage/backup/backup-cli/src/storage/mod.rs b/storage/backup/backup-cli/src/storage/mod.rs index 25373025326..c90e000496a 100644 --- a/storage/backup/backup-cli/src/storage/mod.rs +++ b/storage/backup/backup-cli/src/storage/mod.rs @@ -167,7 +167,8 @@ pub trait BackupStorage: Send + Sync { name: &ShellSafeName, content: &TextLine, ) -> Result { - self.save_metadata_lines(name, &[content.clone()]).await + self.save_metadata_lines(name, std::slice::from_ref(content)) + .await } /// The backup system always asks for all metadata files and cache and build index on top of /// the content of them. This means: diff --git a/storage/backup/backup-cli/src/utils/backup_service_client.rs b/storage/backup/backup-cli/src/utils/backup_service_client.rs index 530dc604b8c..4515b49204f 100644 --- a/storage/backup/backup-cli/src/utils/backup_service_client.rs +++ b/storage/backup/backup-cli/src/utils/backup_service_client.rs @@ -9,7 +9,7 @@ use crate::{ use anyhow::Result; use aptos_crypto::HashValue; use aptos_db::backup::backup_handler::DbState; -use aptos_metrics_core::{IntCounterHelper, TimerHelper}; +use aptos_metrics_core::{IntCounterVecHelper, TimerHelper}; use aptos_types::transaction::Version; use clap::Parser; use futures::TryStreamExt; @@ -53,7 +53,7 @@ impl BackupServiceClient { } } - async fn get(&self, endpoint: &'static str, params: &str) -> Result { + async fn get(&self, endpoint: &'static str, params: &str) -> Result> { let _timer = BACKUP_TIMER.timer_with(&[&format!("backup_service_client_get_{endpoint}")]); let url = if params.is_empty() { @@ -72,7 +72,7 @@ impl BackupServiceClient { THROUGHPUT_COUNTER.inc_with_by(&[endpoint], bytes.len() as u64); bytes }) - .map_err(|e| futures::io::Error::new(futures::io::ErrorKind::Other, e)) + .map_err(futures::io::Error::other) .into_async_read() .compat(); @@ -97,7 +97,7 @@ impl BackupServiceClient { &self, key: HashValue, version: Version, - ) -> Result { + ) -> Result> { self.get("state_range_proof", &format!("{}/{:x}", version, key)) .await } @@ -116,7 +116,7 @@ impl BackupServiceClient { version: Version, start_idx: usize, limit: usize, - ) -> Result { + ) -> Result> { self.get( "state_snapshot_chunk", &format!("{}/{}/{}", version, start_idx, limit), @@ -137,7 +137,7 @@ impl BackupServiceClient { &self, start_epoch: u64, end_epoch: u64, - ) -> Result { + ) -> Result> { self.get( "epoch_ending_ledger_infos", &format!("{}/{}", start_epoch, end_epoch), @@ -149,10 +149,10 @@ impl BackupServiceClient { &self, start_version: Version, num_transactions: usize, - ) -> Result { + ) -> Result> { self.get( "transactions", - &format!("{}/{}", start_version, num_transactions,), + &format!("{}/{}", start_version, num_transactions), ) .await } @@ -161,7 +161,7 @@ impl BackupServiceClient { &self, first_version: Version, last_version: Version, - ) -> Result { + ) -> Result> { self.get( "transaction_range_proof", &format!("{}/{}", first_version, last_version,), diff --git a/storage/backup/backup-cli/src/utils/mod.rs b/storage/backup/backup-cli/src/utils/mod.rs index 7c7342d7561..5f0dbefc430 100644 --- a/storage/backup/backup-cli/src/utils/mod.rs +++ b/storage/backup/backup-cli/src/utils/mod.rs @@ -87,8 +87,8 @@ pub struct RocksdbOpt { index_db_max_total_wal_size: u64, #[clap(long, hide(true), default_value_t = 16)] max_background_jobs: i32, - #[clap(long, hide(true), default_value_t = 1024)] - block_cache_size: u64, + #[clap(long, hide(true), default_value_t = RocksdbConfigs::DEFAULT_BLOCK_CACHE_SIZE)] + block_cache_size: usize, } impl From for RocksdbConfigs { @@ -98,14 +98,12 @@ impl From for RocksdbConfigs { max_open_files: opt.ledger_db_max_open_files, max_total_wal_size: opt.ledger_db_max_total_wal_size, max_background_jobs: opt.max_background_jobs, - block_cache_size: opt.block_cache_size, ..Default::default() }, state_merkle_db_config: RocksdbConfig { max_open_files: opt.state_merkle_db_max_open_files, max_total_wal_size: opt.state_merkle_db_max_total_wal_size, max_background_jobs: opt.max_background_jobs, - block_cache_size: opt.block_cache_size, ..Default::default() }, enable_storage_sharding: opt.enable_storage_sharding, @@ -113,16 +111,16 @@ impl From for RocksdbConfigs { max_open_files: opt.state_kv_db_max_open_files, max_total_wal_size: opt.state_kv_db_max_total_wal_size, max_background_jobs: opt.max_background_jobs, - block_cache_size: opt.block_cache_size, ..Default::default() }, index_db_config: RocksdbConfig { max_open_files: opt.index_db_max_open_files, max_total_wal_size: opt.index_db_max_total_wal_size, max_background_jobs: opt.max_background_jobs, - block_cache_size: opt.block_cache_size, ..Default::default() }, + shared_block_cache_size: opt.block_cache_size, + ..Default::default() } } } diff --git a/storage/backup/backup-cli/src/utils/stream/try_buffered_x.rs b/storage/backup/backup-cli/src/utils/stream/try_buffered_x.rs index 8496f04239b..0f6267a4654 100644 --- a/storage/backup/backup-cli/src/utils/stream/try_buffered_x.rs +++ b/storage/backup/backup-cli/src/utils/stream/try_buffered_x.rs @@ -58,7 +58,9 @@ where // our queue of futures. Propagate errors from the stream immediately. while this.in_progress_queue.len() < *this.max { match this.stream.as_mut().poll_next(cx)? { - Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut.into_future()), + Poll::Ready(Some(fut)) => { + this.in_progress_queue.push(TryFutureExt::into_future(fut)) + }, Poll::Ready(None) | Poll::Pending => break, } } diff --git a/storage/backup/backup-service/src/handlers/bytes_sender.rs b/storage/backup/backup-service/src/handlers/bytes_sender.rs index 250ea4f57ef..5d018a2d509 100644 --- a/storage/backup/backup-service/src/handlers/bytes_sender.rs +++ b/storage/backup/backup-service/src/handlers/bytes_sender.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::handlers::utils::THROUGHPUT_COUNTER; -use aptos_metrics_core::IntCounterHelper; +use aptos_metrics_core::IntCounterVecHelper; use aptos_storage_interface::{AptosDbError, Result as DbResult}; use bytes::{BufMut, Bytes, BytesMut}; use serde::Serialize; diff --git a/storage/backup/backup-service/src/handlers/mod.rs b/storage/backup/backup-service/src/handlers/mod.rs index 8ed06b2764c..8b6fe1672de 100644 --- a/storage/backup/backup-service/src/handlers/mod.rs +++ b/storage/backup/backup-service/src/handlers/mod.rs @@ -11,6 +11,7 @@ use crate::handlers::utils::{ }; use aptos_crypto::hash::HashValue; use aptos_db::backup::backup_handler::BackupHandler; +use aptos_metrics_core::TimerHelper; use aptos_types::transaction::Version; use warp::{filters::BoxedFilter, reply::Reply, Filter}; @@ -138,9 +139,10 @@ pub(crate) fn get_routes(backup_handler: BackupHandler) -> BoxedFilter<(impl Rep .and(routes) .with(warp::log::custom(|info| { let endpoint = info.path().split('/').nth(1).unwrap_or("-"); - LATENCY_HISTOGRAM - .with_label_values(&[endpoint, info.status().as_str()]) - .observe(info.elapsed().as_secs_f64()) + LATENCY_HISTOGRAM.observe_with( + &[endpoint, info.status().as_str()], + info.elapsed().as_secs_f64(), + ) })) .boxed() } diff --git a/storage/db-tool/Cargo.toml b/storage/db-tool/Cargo.toml index a7ebbe0f6b7..d6a1549c1aa 100644 --- a/storage/db-tool/Cargo.toml +++ b/storage/db-tool/Cargo.toml @@ -25,6 +25,7 @@ aptos-storage-interface = { workspace = true } aptos-temppath = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } +aptos-vm-environment = { workspace = true } bcs = { workspace = true } clap = { workspace = true } itertools = { workspace = true } diff --git a/storage/db-tool/src/backup_maintenance.rs b/storage/db-tool/src/backup_maintenance.rs index 7db4fc10261..febd91b8a30 100644 --- a/storage/db-tool/src/backup_maintenance.rs +++ b/storage/db-tool/src/backup_maintenance.rs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use anyhow::Result; use aptos_backup_cli::{ - coordinators::backup::BackupCompactor, metadata::cache::MetadataCacheOpt, - storage::DBToolStorageOpt, utils::ConcurrentDownloadsOpt, + coordinators::backup::BackupCompactor, + metadata::cache::MetadataCacheOpt, + storage::DBToolStorageOpt, + utils::{storage_ext::BackupStorageExt, ConcurrentDownloadsOpt}, }; use clap::{Parser, Subcommand}; @@ -14,6 +16,8 @@ pub enum Command { Compact(CompactionOpt), #[clap(about = "Cleanup the backup metadata files")] Cleanup(CleanupOpt), + #[clap(about = "Display the backup meatdata in human-readable JSON format.")] + ReadMetadata(ReadMetadataOpt), } #[derive(Parser)] @@ -48,6 +52,13 @@ pub struct CleanupOpt { pub storage: DBToolStorageOpt, } +#[derive(Parser)] +pub struct ReadMetadataOpt { + #[clap(flatten)] + pub storage: DBToolStorageOpt, + pub path: String, +} + impl Command { pub async fn run(self) -> Result<()> { match self { @@ -66,6 +77,14 @@ impl Command { Command::Cleanup(_) => { // TODO: add cleanup logic for removing obsolete metadata files }, + Command::ReadMetadata(opt) => { + println!("Reading metadata file at: {}...", opt.path); + let storage = opt.storage.init_storage().await?; + let json_value = storage + .load_json_file::(&opt.path) + .await?; + println!("{}", serde_json::to_string_pretty(&json_value).unwrap()); + }, } Ok(()) } diff --git a/storage/db-tool/src/replay_on_archive.rs b/storage/db-tool/src/replay_on_archive.rs index c0e4731ea6a..58a4b7877d7 100644 --- a/storage/db-tool/src/replay_on_archive.rs +++ b/storage/db-tool/src/replay_on_archive.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use anyhow::{Error, Ok, Result}; +use anyhow::{bail, Error, Ok, Result}; use aptos_backup_cli::utils::{ReplayConcurrencyLevelOpt, RocksdbOpt}; use aptos_block_executor::txn_provider::default::DefaultTxnProvider; use aptos_config::config::{ @@ -15,17 +15,25 @@ use aptos_storage_interface::{ state_store::state_view::db_state_view::DbStateViewAtVersion, AptosDbError, DbReader, }; use aptos_types::{ + block_executor::{ + config::BlockExecutorConfigFromOnchain, + transaction_slice_metadata::TransactionSliceMetadata, + }, contract_event::ContractEvent, transaction::{ - signature_verified_transaction::SignatureVerifiedTransaction, Transaction, TransactionInfo, - Version, + signature_verified_transaction::SignatureVerifiedTransaction, AuxiliaryInfo, BlockOutput, + PersistedAuxiliaryInfo, Transaction, TransactionInfo, Version, }, write_set::WriteSet, }; use aptos_vm::{aptos_vm::AptosVMBlockExecutor, AptosVM, VMBlockExecutor}; +use aptos_vm_environment::prod_configs::{ + set_async_runtime_checks, set_layout_caches, set_paranoid_type_checks, +}; use clap::Parser; -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use rayon::{iter::ParallelIterator, prelude::IntoParallelIterator}; use std::{ + panic, path::PathBuf, process, sync::{atomic::AtomicU64, Arc}, @@ -71,6 +79,13 @@ pub struct Opt { help = "The maximum time in seconds to wait for each transaction replay" )] pub timeout_secs: Option, + + #[clap( + long, + default_value_t = false, + help = "Enable paranoid type checks in the Move VM" + )] + pub paranoid_type_checks: bool, } impl Opt { @@ -134,6 +149,24 @@ struct Verifier { impl Verifier { pub fn new(config: &Opt) -> Result { + // Open in write mode to create any new DBs necessary. + { + if let Err(e) = panic::catch_unwind(|| { + AptosDB::open( + StorageDirPaths::from_path(config.db_dir.as_path()), + false, + NO_OP_STORAGE_PRUNER_CONFIG, + config.rocksdb_opt.clone().into(), + false, + BUFFERED_STATE_TARGET_ITEMS, + DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, + None, + ) + }) { + warn!("Unable to open AptosDB in write mode: {:?}", e); + }; + } + let aptos_db = AptosDB::open( StorageDirPaths::from_path(config.db_dir.as_path()), true, @@ -151,6 +184,10 @@ impl Verifier { // calculate a valid start and limit let (start, limit) = Self::get_start_and_limit(&arc_db, config.start_version, config.end_version)?; + set_layout_caches(true); + set_paranoid_type_checks(config.paranoid_type_checks); + // Paranoid checks are done async if enabled. + set_async_runtime_checks(config.paranoid_type_checks); info!( start_version = start, limit = limit, @@ -177,24 +214,22 @@ impl Verifier { } AptosVM::set_concurrency_level_once(self.replay_concurrency_level); - let task_size = self.limit / self.concurrent_replay as u64; - let ranges: Vec<(u64, u64)> = (0..self.concurrent_replay) - .map(|i| { - let chunk_start = self.start + (i as u64) * task_size; - let chunk_limit = if i == self.concurrent_replay - 1 { - self.start + self.limit - chunk_start - } else { - task_size - }; - (chunk_start, chunk_limit) - }) - .collect(); - - // Process each range in parallel using `par_iter` - let res = ranges - .par_iter() - .map(|(start, limit)| self.verify(*start, *limit)) - .collect::>>>(); + let thread_pool = rayon::ThreadPoolBuilder::new() + .num_threads(self.concurrent_replay) + .thread_name(|i| format!("replay-verify-{}", i)) + .build()?; + let chunk_size = self.chunk_size as u64; + let total_chunks = self.limit.div_ceil(chunk_size); + let res: Vec<_> = thread_pool.install(|| { + (0..total_chunks) + .into_par_iter() + .map(|i| { + let start = self.start + i * chunk_size; + let end = std::cmp::min(start + chunk_size - 1, self.start + self.limit - 1); + self.verify(start, end - start + 1) + }) + .collect() + }); let mut all_failed_txns = Vec::new(); for iter in res.into_iter() { all_failed_txns.extend(iter?); @@ -202,33 +237,42 @@ impl Verifier { Ok(all_failed_txns) } - // Execute the verify one valide range + // Execute the verify one valid range pub fn verify(&self, start: Version, limit: u64) -> Result> { - let mut total_failed_txns = Vec::new(); + let mut total_failed_txns = Vec::with_capacity(limit as usize); let txn_iter = self .backup_handler .get_transaction_iter(start, limit as usize)?; - let mut cur_txns = Vec::new(); - let mut expected_events = Vec::new(); - let mut expected_writesets = Vec::new(); - let mut expected_txn_infos = Vec::new(); + let mut cur_txns = Vec::with_capacity(limit as usize); + let mut cur_persisted_aux_info = Vec::with_capacity(limit as usize); + let mut expected_events = Vec::with_capacity(limit as usize); + let mut expected_writesets = Vec::with_capacity(limit as usize); + let mut expected_txn_infos = Vec::with_capacity(limit as usize); let mut chunk_start_version = start; + let executor = AptosVMBlockExecutor::new(); for item in txn_iter { // timeout check if let Some(duration) = self.timeout_secs { if self.replay_stat.get_elapsed_secs() >= duration { - error!( - "Verify timeout: {}s elapsed. Deadline: {}s", + bail!( + "Verify timeout: {}s elapsed. Deadline: {}s. Failed txns count: {}", self.replay_stat.get_elapsed_secs(), - duration + duration, + total_failed_txns.len(), ); - return Ok(total_failed_txns); } } - let (input_txn, expected_txn_info, expected_event, expected_writeset) = item?; + let ( + input_txn, + persisted_aux_info, + expected_txn_info, + expected_event, + expected_writeset, + ) = item?; let is_epoch_ending = expected_event.iter().any(ContractEvent::is_new_epoch_event); cur_txns.push(input_txn); + cur_persisted_aux_info.push(persisted_aux_info); expected_txn_infos.push(expected_txn_info); expected_events.push(expected_event); expected_writesets.push(expected_writeset); @@ -237,8 +281,10 @@ impl Verifier { while !cur_txns.is_empty() { // verify results let failed_txn_opt = self.execute_and_verify( + &executor, &mut chunk_start_version, &mut cur_txns, + &mut cur_persisted_aux_info, &mut expected_txn_infos, &mut expected_events, &mut expected_writesets, @@ -252,8 +298,10 @@ impl Verifier { } // verify results let fail_txns = self.execute_and_verify( + &executor, &mut chunk_start_version, &mut cur_txns, + &mut cur_persisted_aux_info, &mut expected_txn_infos, &mut expected_events, &mut expected_writesets, @@ -298,8 +346,10 @@ impl Verifier { fn execute_and_verify( &self, + executor: &AptosVMBlockExecutor, current_version: &mut Version, cur_txns: &mut Vec, + cur_persisted_aux_info: &mut Vec, expected_txn_infos: &mut Vec, expected_events: &mut Vec>, expected_writesets: &mut Vec, @@ -311,13 +361,26 @@ impl Verifier { .iter() .map(|txn| SignatureVerifiedTransaction::from(txn.clone())) .collect::>(); - let txns_provider = DefaultTxnProvider::new(txns); - let executed_outputs = AptosVMBlockExecutor::new().execute_block_no_limit( - &txns_provider, - &self - .arc_db - .state_view_at_version(current_version.checked_sub(1))?, - )?; + let txns_provider = DefaultTxnProvider::new( + txns, + cur_persisted_aux_info + .iter() + .map(|info| AuxiliaryInfo::new(*info, None)) + .collect(), + ); + let executed_outputs = executor + .execute_block( + &txns_provider, + &self + .arc_db + .state_view_at_version(current_version.checked_sub(1))?, + BlockExecutorConfigFromOnchain::new_no_block_limit(), + TransactionSliceMetadata::Chunk { + begin: *current_version, + end: *current_version + cur_txns.len() as u64, + }, + ) + .map(BlockOutput::into_transaction_outputs_forced)?; assert_eq!(executed_outputs.len(), cur_txns.len()); for idx in 0..cur_txns.len() { @@ -331,6 +394,7 @@ impl Verifier { Some(&expected_events[idx]), ) { cur_txns.drain(0..idx + 1); + cur_persisted_aux_info.drain(0..idx + 1); expected_txn_infos.drain(0..idx + 1); expected_events.drain(0..idx + 1); expected_writesets.drain(0..idx + 1); @@ -340,6 +404,7 @@ impl Verifier { } cur_txns.clear(); + cur_persisted_aux_info.clear(); expected_txn_infos.clear(); expected_events.clear(); expected_writesets.clear(); diff --git a/storage/db-tool/src/tests.rs b/storage/db-tool/src/tests.rs index eeeaae5c67f..7affed0607c 100644 --- a/storage/db-tool/src/tests.rs +++ b/storage/db-tool/src/tests.rs @@ -366,16 +366,13 @@ mod dbtool_tests { backup_dir: PathBuf, old_db_dir: PathBuf, new_db_dir: PathBuf, - force_sharding: bool, ) -> (Runtime, String) { use aptos_config::config::{ RocksdbConfigs, StorageDirPaths, BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, NO_OP_STORAGE_PRUNER_CONFIG, }; - use aptos_db::utils::iterators::PrefixedStateValueIterator; use aptos_db_indexer::utils::PrefixedStateValueIterator as IndexerPrefixedStateValueIterator; use aptos_indexer_grpc_table_info::internal_indexer_db_service::InternalIndexerDBService; - use itertools::zip_eq; let db = test_execution_with_storage_impl_inner(false, old_db_dir.as_path()); let (rt, port) = start_local_backup_service(Arc::clone(&db)); let server_addr = format!(" http://localhost:{}", port); @@ -527,132 +524,77 @@ mod dbtool_tests { "--local-fs-dir".to_string(), backup_dir.as_path().to_str().unwrap().to_string(), ]; - if force_sharding { - let additional_args = vec!["--enable-storage-sharding", "--enable-state-indices"] - .into_iter() - .map(|s| s.to_string()) - .collect::>(); - restore_args.extend(additional_args); - } + let additional_args = vec!["--enable-storage-sharding", "--enable-state-indices"] + .into_iter() + .map(|s| s.to_string()) + .collect::>(); + restore_args.extend(additional_args); rt.block_on(DBTool::try_parse_from(restore_args).unwrap().run()) .unwrap(); - // verify the new DB has the same data as the original DB - let db_config = if !force_sharding { - RocksdbConfigs::default() - } else { - RocksdbConfigs { - enable_storage_sharding: true, - ..Default::default() - } - }; - // assert the kv are the same in db and new_db // current all the kv are still stored in the ledger db // - if !force_sharding { - let (_ledger_db, tree_db, state_kv_db) = - AptosDB::open_dbs(&StorageDirPaths::from_path(new_db_dir), db_config, false, 0) - .unwrap(); - for ver in start..=end { - let new_iter = PrefixedStateValueIterator::new( - &state_kv_db, - StateKeyPrefix::new(AccessPath, b"".to_vec()), - None, - ver, - ) - .unwrap(); + let internal_indexer_db = + InternalIndexerDBService::get_indexer_db_for_restore(new_db_dir.as_path()).unwrap(); + + let aptos_db: Arc = Arc::new( + AptosDB::open( + StorageDirPaths::from_path(new_db_dir), + false, + NO_OP_STORAGE_PRUNER_CONFIG, + RocksdbConfigs::default(), + false, + BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, + 1000, + Some(internal_indexer_db.clone()), + ) + .unwrap(), + ); - let old_iter = db - .deref() - .get_prefixed_state_value_iterator( - &StateKeyPrefix::new(AccessPath, b"".to_vec()), - None, - ver, - ) - .unwrap(); - - zip_eq(new_iter, old_iter).for_each(|(new, old)| { - let (new_key, new_value) = new.unwrap(); - let (old_key, old_value) = old.unwrap(); - assert_eq!(new_key, old_key); - assert_eq!(new_value, old_value); - }); - // first snapshot tree not recovered - assert!( - tree_db.get_root_hash(0).is_err() || tree_db.get_leaf_count(0).unwrap() == 0, - "tree at version 0 should not be restored" - ); - // second snapshot tree recovered - let second_snapshot_version: Version = 13; - assert!( - tree_db.get_root_hash(second_snapshot_version).is_ok(), - "root hash at version {} doesn't exist", - second_snapshot_version, - ); - } + // Only state key at and by the snapshot version are restored in internal indexer + let snapshot_version = if start == 0 { + 0 + } else if start > 0 && start < 15 { + 1 } else { - let internal_indexer_db = - InternalIndexerDBService::get_indexer_db_for_restore(new_db_dir.as_path()).unwrap(); - - let aptos_db: Arc = Arc::new( - AptosDB::open( - StorageDirPaths::from_path(new_db_dir), - false, - NO_OP_STORAGE_PRUNER_CONFIG, - db_config, - false, - BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, - 1000, - Some(internal_indexer_db.clone()), - ) - .unwrap(), - ); - - // Only state key at and by the snapshot version are restored in internal indexer - let snapshot_version = if start == 0 { - 0 - } else if start > 0 && start < 15 { - 1 - } else { - 15 - }; + 15 + }; - let new_iter = IndexerPrefixedStateValueIterator::new( - aptos_db.clone(), - internal_indexer_db.get_inner_db_ref(), - StateKeyPrefix::new(AccessPath, b"".to_vec()), + let new_iter = IndexerPrefixedStateValueIterator::new( + aptos_db.clone(), + internal_indexer_db.get_inner_db_ref(), + StateKeyPrefix::new(AccessPath, b"".to_vec()), + None, + snapshot_version, + ) + .unwrap(); + + let old_iter = db + .deref() + .get_prefixed_state_value_iterator( + &StateKeyPrefix::new(AccessPath, b"".to_vec()), None, snapshot_version, ) .unwrap(); - let old_iter = db - .deref() - .get_prefixed_state_value_iterator( - &StateKeyPrefix::new(AccessPath, b"".to_vec()), - None, - snapshot_version, - ) - .unwrap(); - - // collect all the keys in the new_iter - let mut new_keys = new_iter.map(|e| e.unwrap().0).collect::>(); - new_keys.sort(); - let mut old_keys = old_iter.map(|e| e.unwrap().0).collect::>(); - old_keys.sort(); - assert_eq!(new_keys, old_keys); - - let ledger_version = aptos_db.get_latest_ledger_info_version().unwrap(); - for ver in start..=ledger_version { - let old_block_res = db.get_block_info_by_version(ver); - let new_block_res = aptos_db.get_block_info_by_version(ver); - let (old_block_version, old_block_height, _) = old_block_res.unwrap(); - let (new_block_version, new_block_height, _) = new_block_res.unwrap(); - assert_eq!(old_block_version, new_block_version); - assert_eq!(old_block_height, new_block_height); - } + // collect all the keys in the new_iter + let mut new_keys = new_iter.map(|e| e.unwrap().0).collect::>(); + new_keys.sort(); + let mut old_keys = old_iter.map(|e| e.unwrap().0).collect::>(); + old_keys.sort(); + assert_eq!(new_keys, old_keys); + + let ledger_version = aptos_db.get_latest_ledger_info_version().unwrap(); + for ver in start..=ledger_version { + let old_block_res = db.get_block_info_by_version(ver); + let new_block_res = aptos_db.get_block_info_by_version(ver); + let (old_block_version, old_block_height, _) = old_block_res.unwrap(); + let (new_block_version, new_block_height, _) = new_block_res.unwrap(); + assert_eq!(old_block_version, new_block_version); + assert_eq!(old_block_height, new_block_height); } (rt, server_addr) @@ -812,7 +754,6 @@ mod dbtool_tests { PathBuf::from(backup_dir.path()), PathBuf::from(old_db_dir.path()), PathBuf::from(new_db_dir.path()), - false, ); let backup_size = dir_size(backup_dir.path()); let db_size = dir_size(new_db_dir.path()); @@ -838,7 +779,6 @@ mod dbtool_tests { PathBuf::from(backup_dir.path()), PathBuf::from(old_db_dir.path()), PathBuf::from(new_db_dir.path()), - false, ); rt.shutdown_timeout(Duration::from_secs(1)); } @@ -858,7 +798,6 @@ mod dbtool_tests { PathBuf::from(backup_dir.path()), PathBuf::from(old_db_dir.path()), PathBuf::from(new_db_dir.path()), - false, ); // boostrap a historical DB starting from version 1 to version 18 // This only replays the txn from txn 17 to 18 @@ -897,7 +836,6 @@ mod dbtool_tests { PathBuf::from(backup_dir.path()), PathBuf::from(old_db_dir.path()), PathBuf::from(new_db_dir.path()), - true, ); let backup_size = dir_size(backup_dir.path()); let db_size = dir_size(new_db_dir.path()); diff --git a/storage/indexer/src/db_indexer.rs b/storage/indexer/src/db_indexer.rs index 64d40b4eb64..32bfef3cdb6 100644 --- a/storage/indexer/src/db_indexer.rs +++ b/storage/indexer/src/db_indexer.rs @@ -21,6 +21,7 @@ use aptos_db_indexer_schemas::{ }, }; use aptos_logger::warn; +use aptos_metrics_core::TimerHelper; use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ db_ensure as ensure, db_other_bail as bail, AptosDbError, DbReader, Result, @@ -176,7 +177,7 @@ impl InternalIndexerDB { min_seq_num: u64, num_versions: u64, ledger_version: Version, - ) -> Result { + ) -> Result> { let mut iter = self.db.iter::()?; iter.seek(&(address, min_seq_num))?; Ok(AccountOrderedTransactionsIter::new( @@ -407,8 +408,7 @@ impl DBIndexer { /// Process a batch of transactions that is within the range of `start_version` to `end_version`. Left inclusive, right exclusive. pub fn process_a_batch(&self, start_version: Version, end_version: Version) -> Result { - let _timer: aptos_metrics_core::HistogramTimer = - TIMER.with_label_values(&["process_a_batch"]).start_timer(); + let _timer: aptos_metrics_core::HistogramTimer = TIMER.timer_with(&["process_a_batch"]); let mut version = start_version; let num_transactions = self.get_num_of_transactions(version, end_version)?; // This promises num_transactions should be readable from main db @@ -553,9 +553,7 @@ impl DBIndexer { &self, v2: &ContractEventV2, ) -> Result> { - let _timer = TIMER - .with_label_values(&["translate_event_v2_to_v1"]) - .start_timer(); + let _timer = TIMER.timer_with(&["translate_event_v2_to_v1"]); if let Some(translator) = self .event_v2_translation_engine .translators @@ -618,7 +616,7 @@ impl DBIndexer { key_prefix: &StateKeyPrefix, cursor: Option<&StateKey>, ledger_version: Version, - ) -> Result> + '_> { + ) -> Result> + '_ + use<'_>> { self.indexer_db .ensure_cover_ledger_version(ledger_version)?; PrefixedStateValueIterator::new( diff --git a/storage/indexer/src/db_ops.rs b/storage/indexer/src/db_ops.rs index e8a9a1fbf20..cf211afc3c8 100644 --- a/storage/indexer/src/db_ops.rs +++ b/storage/indexer/src/db_ops.rs @@ -11,24 +11,39 @@ use std::{mem, path::Path}; const INTERNAL_INDEXER_DB_NAME: &str = "internal_indexer_db"; const TABLE_INFO_DB_NAME: &str = "index_async_v2_db"; -pub fn open_db>(db_path: P, rocksdb_config: &RocksdbConfig) -> Result { - Ok(DB::open( - db_path, - TABLE_INFO_DB_NAME, - column_families(), - &gen_rocksdb_options(rocksdb_config, false), - )?) +pub fn open_db>( + db_path: P, + rocksdb_config: &RocksdbConfig, + readonly: bool, +) -> Result { + let env = None; + if readonly { + Ok(DB::open_readonly( + db_path, + TABLE_INFO_DB_NAME, + column_families(), + &gen_rocksdb_options(rocksdb_config, env, readonly), + )?) + } else { + Ok(DB::open( + db_path, + TABLE_INFO_DB_NAME, + column_families(), + &gen_rocksdb_options(rocksdb_config, env, readonly), + )?) + } } pub fn open_internal_indexer_db>( db_path: P, rocksdb_config: &RocksdbConfig, ) -> Result { + let env = None; Ok(DB::open( db_path, INTERNAL_INDEXER_DB_NAME, internal_indexer_column_families(), - &gen_rocksdb_options(rocksdb_config, false), + &gen_rocksdb_options(rocksdb_config, env, false), )?) } diff --git a/storage/indexer/src/db_v2.rs b/storage/indexer/src/db_v2.rs index 016dc86c3d7..28c2603fd90 100644 --- a/storage/indexer/src/db_v2.rs +++ b/storage/indexer/src/db_v2.rs @@ -9,8 +9,8 @@ use aptos_db_indexer_schemas::{ metadata::{MetadataKey, MetadataValue}, schema::{indexer_metadata::IndexerMetadataSchema, table_info::TableInfoSchema}, }; -use aptos_logger::info; -use aptos_resource_viewer::{AnnotatedMoveValue, AptosValueAnnotator}; +use aptos_logger::{info, sample, sample::SampleRate}; +use aptos_resource_viewer::{AptosValueAnnotator, MoveTableInfo}; use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ db_other_bail as bail, state_store::state_view::db_state_view::DbStateViewAtVersion, @@ -18,7 +18,6 @@ use aptos_storage_interface::{ }; use aptos_types::{ access_path::Path, - account_address::AccountAddress, state_store::{ state_key::{inner::StateKeyInner, StateKey}, table::{TableHandle, TableInfo}, @@ -29,10 +28,7 @@ use aptos_types::{ }; use bytes::Bytes; use dashmap::{DashMap, DashSet}; -use move_core_types::{ - ident_str, - language_storage::{StructTag, TypeTag}, -}; +use move_core_types::language_storage::{StructTag, TypeTag}; use std::{ collections::{BTreeMap, HashMap}, fs, @@ -98,7 +94,7 @@ impl IndexerAsyncV2 { let mut table_info_parser = TableInfoParser::new(self, annotator, &self.pending_on); for write_set in write_sets { for (state_key, write_op) in write_set.write_op_iter() { - table_info_parser.parse_write_op(state_key, write_op)?; + table_info_parser.collect_table_info_from_write_op(state_key, write_op)?; } } let mut batch = SchemaBatch::new(); @@ -160,12 +156,18 @@ impl IndexerAsyncV2 { if let Ok(Some(table_info)) = self.get_table_info(handle) { return Ok(Some(table_info)); } + + // Log the first failure, and then sample subsequent failures to avoid log spam + if retried == 0 { + log_table_info_failure(handle, retried); + } else { + sample!( + SampleRate::Duration(Duration::from_secs(1)), + log_table_info_failure(handle, retried) + ); + } + retried += 1; - info!( - retry_count = retried, - table_handle = handle.0.to_canonical_string(), - "[DB] Failed to get table info", - ); std::thread::sleep(Duration::from_millis(TABLE_INFO_RETRY_TIME_MILLIS)); } } @@ -194,6 +196,15 @@ impl IndexerAsyncV2 { } } +/// Logs a failure to retrieve table information +fn log_table_info_failure(handle: TableHandle, retried: u64) { + info!( + retry_count = retried, + table_handle = handle.0.to_canonical_string(), + "[DB] Failed to get table info", + ) +} + struct TableInfoParser<'a, R> { indexer_async_v2: &'a IndexerAsyncV2, annotator: &'a AptosValueAnnotator<'a, R>, @@ -216,45 +227,66 @@ impl<'a, R: StateView> TableInfoParser<'a, R> { } /// Parses a write operation and extracts table information from it. - pub fn parse_write_op(&mut self, state_key: &'a StateKey, write_op: &'a WriteOp) -> Result<()> { + pub fn collect_table_info_from_write_op( + &mut self, + state_key: &'a StateKey, + write_op: &'a WriteOp, + ) -> Result<()> { if let Some(bytes) = write_op.bytes() { match state_key.inner() { StateKeyInner::AccessPath(access_path) => { let path: Path = (&access_path.path).try_into()?; match path { Path::Code(_) => (), - Path::Resource(struct_tag) => self.parse_struct(struct_tag, bytes)?, - Path::ResourceGroup(_struct_tag) => self.parse_resource_group(bytes)?, + Path::Resource(struct_tag) => { + self.collect_table_info_from_struct(struct_tag, bytes)? + }, + Path::ResourceGroup(_struct_tag) => { + self.collect_table_info_from_resource_group(bytes)? + }, } }, - StateKeyInner::TableItem { handle, .. } => self.parse_table_item(*handle, bytes)?, + StateKeyInner::TableItem { handle, .. } => { + self.collect_table_info_from_table_item(*handle, bytes)? + }, StateKeyInner::Raw(_) => (), } } Ok(()) } - fn parse_struct(&mut self, struct_tag: StructTag, bytes: &Bytes) -> Result<()> { - self.parse_move_value( - &self - .annotator - .view_value(&TypeTag::Struct(Box::new(struct_tag)), bytes)?, - ) + fn collect_table_info_from_struct( + &mut self, + struct_tag: StructTag, + bytes: &Bytes, + ) -> Result<()> { + let ty_tag = TypeTag::Struct(Box::new(struct_tag)); + let mut infos = vec![]; + self.annotator + .collect_table_info(&ty_tag, bytes, &mut infos)?; + self.process_table_infos(infos) } - fn parse_resource_group(&mut self, bytes: &Bytes) -> Result<()> { + fn collect_table_info_from_resource_group(&mut self, bytes: &Bytes) -> Result<()> { type ResourceGroup = BTreeMap; for (struct_tag, bytes) in bcs::from_bytes::(bytes)? { - self.parse_struct(struct_tag, &bytes)?; + self.collect_table_info_from_struct(struct_tag, &bytes)?; } Ok(()) } - fn parse_table_item(&mut self, handle: TableHandle, bytes: &Bytes) -> Result<()> { + fn collect_table_info_from_table_item( + &mut self, + handle: TableHandle, + bytes: &Bytes, + ) -> Result<()> { match self.get_table_info(handle)? { Some(table_info) => { - self.parse_move_value(&self.annotator.view_value(&table_info.value_type, bytes)?)?; + let mut infos = vec![]; + self.annotator + .collect_table_info(&table_info.value_type, bytes, &mut infos)?; + self.process_table_infos(infos)? }, None => { self.pending_on @@ -266,64 +298,17 @@ impl<'a, R: StateView> TableInfoParser<'a, R> { Ok(()) } - /// Parses a write operation and extracts table information from it. - /// - /// The `parse_move_value` function is a recursive method that traverses - /// through the `AnnotatedMoveValue` structure. Depending on the type of - /// `AnnotatedMoveValue` (e.g., Vector, Struct, or primitive types), it - /// performs different parsing actions. For Vector and Struct, it recursively - /// calls itself to parse each element or field. This recursive approach allows - /// the function to handle nested data structures in Move values. - fn parse_move_value(&mut self, move_value: &AnnotatedMoveValue) -> Result<()> { - match move_value { - AnnotatedMoveValue::Vector(_type_tag, items) => { - for item in items { - self.parse_move_value(item)?; - } - }, - AnnotatedMoveValue::Struct(struct_value) => { - let struct_tag = &struct_value.ty_tag; - if Self::is_table(struct_tag) { - assert_eq!(struct_tag.type_args.len(), 2); - let table_info = TableInfo { - key_type: struct_tag.type_args[0].clone(), - value_type: struct_tag.type_args[1].clone(), - }; - let table_handle = match &struct_value.value[0] { - (name, AnnotatedMoveValue::Address(handle)) => { - assert_eq!(name.as_ref(), ident_str!("handle")); - TableHandle(*handle) - }, - _ => bail!("Table struct malformed. {:?}", struct_value), - }; - self.save_table_info(table_handle, table_info)?; - } else { - for (_identifier, field) in &struct_value.value { - self.parse_move_value(field)?; - } - } - }, - AnnotatedMoveValue::RawStruct(struct_value) => { - for val in &struct_value.field_values { - self.parse_move_value(val)? - } - }, - AnnotatedMoveValue::Closure(closure_value) => { - for capture in &closure_value.captured { - self.parse_move_value(capture)? - } - }, - - // there won't be tables in primitives - AnnotatedMoveValue::U8(_) => {}, - AnnotatedMoveValue::U16(_) => {}, - AnnotatedMoveValue::U32(_) => {}, - AnnotatedMoveValue::U64(_) => {}, - AnnotatedMoveValue::U128(_) => {}, - AnnotatedMoveValue::U256(_) => {}, - AnnotatedMoveValue::Bool(_) => {}, - AnnotatedMoveValue::Address(_) => {}, - AnnotatedMoveValue::Bytes(_) => {}, + fn process_table_infos(&mut self, infos: Vec) -> Result<()> { + for MoveTableInfo { + key_type, + value_type, + handle, + } in infos + { + self.save_table_info(TableHandle(handle), TableInfo { + key_type, + value_type, + })? } Ok(()) } @@ -333,19 +318,13 @@ impl<'a, R: StateView> TableInfoParser<'a, R> { self.result.insert(handle, info); if let Some(pending_items) = self.pending_on.remove(&handle) { for bytes in pending_items.1 { - self.parse_table_item(handle, &bytes)?; + self.collect_table_info_from_table_item(handle, &bytes)?; } } } Ok(()) } - fn is_table(struct_tag: &StructTag) -> bool { - struct_tag.address == AccountAddress::ONE - && struct_tag.module.as_ident_str() == ident_str!("table") - && struct_tag.name.as_ident_str() == ident_str!("Table") - } - /// Retrieves table information either from the in-memory results or from the database. /// /// This method first checks if the table information for the given handle exists in the diff --git a/storage/indexer/src/lib.rs b/storage/indexer/src/lib.rs index 7e254fcdcc1..11c7718a6c9 100644 --- a/storage/indexer/src/lib.rs +++ b/storage/indexer/src/lib.rs @@ -61,12 +61,13 @@ impl Indexer { rocksdb_config: RocksdbConfig, ) -> Result { let db_path = db_root_path.as_ref().join(INDEX_DB_NAME); + let env = None; let db = DB::open( db_path, "index_db", column_families(), - &gen_rocksdb_options(&rocksdb_config, false), + &gen_rocksdb_options(&rocksdb_config, env, false), )?; let next_version = db @@ -269,6 +270,12 @@ impl<'a, R: StateView> TableInfoParser<'a, R> { AnnotatedMoveValue::U64(_) => {}, AnnotatedMoveValue::U128(_) => {}, AnnotatedMoveValue::U256(_) => {}, + AnnotatedMoveValue::I8(_) => {}, + AnnotatedMoveValue::I16(_) => {}, + AnnotatedMoveValue::I32(_) => {}, + AnnotatedMoveValue::I64(_) => {}, + AnnotatedMoveValue::I128(_) => {}, + AnnotatedMoveValue::I256(_) => {}, AnnotatedMoveValue::Bool(_) => {}, AnnotatedMoveValue::Address(_) => {}, AnnotatedMoveValue::Bytes(_) => {}, diff --git a/storage/jellyfish-merkle/src/lib.rs b/storage/jellyfish-merkle/src/lib.rs index fd55164f26e..40ac2c42c54 100644 --- a/storage/jellyfish-merkle/src/lib.rs +++ b/storage/jellyfish-merkle/src/lib.rs @@ -86,7 +86,7 @@ pub mod test_helper; use crate::metrics::{APTOS_JELLYFISH_LEAF_COUNT, APTOS_JELLYFISH_LEAF_DELETION_COUNT, COUNTER}; use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; -use aptos_metrics_core::IntCounterHelper; +use aptos_metrics_core::{IntCounterHelper, IntCounterVecHelper}; use aptos_storage_interface::{db_ensure as ensure, db_other_bail, AptosDbError, Result}; use aptos_types::{ nibble::{nibble_path::NibblePath, Nibble, ROOT_NIBBLE_HEIGHT}, diff --git a/storage/jellyfish-merkle/src/metrics.rs b/storage/jellyfish-merkle/src/metrics.rs index 647f60febe9..3f5f60a1a91 100644 --- a/storage/jellyfish-merkle/src/metrics.rs +++ b/storage/jellyfish-merkle/src/metrics.rs @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_metrics_core::{ - register_int_counter, register_int_counter_vec, register_int_gauge, IntCounter, IntCounterVec, - IntGauge, + make_thread_local_int_counter, make_thread_local_int_counter_vec, register_int_counter, + register_int_gauge, IntCounter, IntGauge, }; use once_cell::sync::Lazy; @@ -32,22 +32,20 @@ pub static APTOS_JELLYFISH_LEAF_COUNT: Lazy = Lazy::new(|| { .unwrap() }); -pub static APTOS_JELLYFISH_LEAF_DELETION_COUNT: Lazy = Lazy::new(|| { - register_int_counter!( - "aptos_jellyfish_leaf_deletion_count", - "The number of deletions happened in JMT." - ) - .unwrap() -}); +make_thread_local_int_counter!( + pub, + APTOS_JELLYFISH_LEAF_DELETION_COUNT, + "aptos_jellyfish_leaf_deletion_count", + "The number of deletions happened in JMT." +); -pub static COUNTER: Lazy = Lazy::new(|| { - register_int_counter_vec!( - // metric name - "aptos_jellyfish_counter", - // metric description - "Various counters for the JellyfishMerkleTree", - // metric labels (dimensions) - &["name"], - ) - .unwrap() -}); +make_thread_local_int_counter_vec!( + pub, + COUNTER, + // metric name + "aptos_jellyfish_counter", + // metric description + "Various counters for the JellyfishMerkleTree", + // metric labels (dimensions) + &["name"], +); diff --git a/storage/jellyfish-merkle/src/node_type/mod.rs b/storage/jellyfish-merkle/src/node_type/mod.rs index 31f375ccdad..89c8d3d7f97 100644 --- a/storage/jellyfish-merkle/src/node_type/mod.rs +++ b/storage/jellyfish-merkle/src/node_type/mod.rs @@ -119,10 +119,10 @@ impl NodeKey { "Invalid number of nibbles: {}", num_nibbles, ); - let mut nibble_bytes = Vec::with_capacity((num_nibbles + 1) / 2); + let mut nibble_bytes = Vec::with_capacity(num_nibbles.div_ceil(2)); reader.read_to_end(&mut nibble_bytes)?; ensure!( - (num_nibbles + 1) / 2 == nibble_bytes.len(), + num_nibbles.div_ceil(2) == nibble_bytes.len(), "encoded num_nibbles {} mismatches nibble path bytes {:?}", num_nibbles, nibble_bytes @@ -146,7 +146,7 @@ impl NodeKey { } // Returns the shard_id of the NodeKey, or None if it is root. - pub fn get_shard_id(&self) -> Option { + pub fn get_shard_id(&self) -> Option { self.nibble_path().get_shard_id() } } diff --git a/storage/rocksdb-options/src/lib.rs b/storage/rocksdb-options/src/lib.rs index 79c55e05ced..f066fac5bc6 100644 --- a/storage/rocksdb-options/src/lib.rs +++ b/storage/rocksdb-options/src/lib.rs @@ -1,18 +1,40 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_config::config::RocksdbConfig; -use rocksdb::Options; +use aptos_config::config::{RocksDBStatsLevel, RocksdbConfig}; +use rocksdb::{statistics::StatsLevel, Env, Options}; // TODO: Clean this up. It is currently separated into its own crate // to avoid circular dependencies, because it depends on aptos-config (which // is widely used). -pub fn gen_rocksdb_options(config: &RocksdbConfig, readonly: bool) -> Options { +fn convert_stats_level(level: RocksDBStatsLevel) -> StatsLevel { + use RocksDBStatsLevel::*; + match level { + ExceptHistogramOrTimers => StatsLevel::ExceptHistogramOrTimers, + ExceptTimers => StatsLevel::ExceptTimers, + ExceptDetailedTimers => StatsLevel::ExceptDetailedTimers, + ExceptTimeForMutex => StatsLevel::ExceptTimeForMutex, + All => StatsLevel::All, + } +} + +pub fn gen_rocksdb_options(config: &RocksdbConfig, env: Option<&Env>, readonly: bool) -> Options { let mut db_opts = Options::default(); + if let Some(env) = env { + db_opts.set_env(env); + } db_opts.set_max_open_files(config.max_open_files); db_opts.set_max_total_wal_size(config.max_total_wal_size); - db_opts.set_max_background_jobs(config.max_background_jobs); + + if let Some(level) = config.stats_level { + db_opts.enable_statistics(); + db_opts.set_statistics_level(convert_stats_level(level)); + } + if let Some(stats_dump_period_sec) = config.stats_dump_period_sec { + db_opts.set_stats_dump_period_sec(stats_dump_period_sec); + } + if !readonly { db_opts.create_if_missing(true); db_opts.create_missing_column_families(true); diff --git a/storage/schemadb/Cargo.toml b/storage/schemadb/Cargo.toml index bf676d3880a..b3775614c5e 100644 --- a/storage/schemadb/Cargo.toml +++ b/storage/schemadb/Cargo.toml @@ -19,7 +19,6 @@ aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-storage-interface = { workspace = true } dunce = { workspace = true } -once_cell = { workspace = true } proptest = { workspace = true, optional = true } rand = { workspace = true } rocksdb = { workspace = true } diff --git a/storage/schemadb/src/batch.rs b/storage/schemadb/src/batch.rs index 4f817bb9561..d86fc25469b 100644 --- a/storage/schemadb/src/batch.rs +++ b/storage/schemadb/src/batch.rs @@ -7,7 +7,7 @@ use crate::{ ColumnFamilyName, DB, }; use aptos_drop_helper::DropHelper; -use aptos_metrics_core::TimerHelper; +use aptos_metrics_core::{IntCounterVecHelper, TimerHelper}; use aptos_storage_interface::Result as DbResult; use std::{ collections::HashMap, @@ -32,15 +32,11 @@ impl BatchStats { fn commit(&self) { for (cf_name, put_sizes) in &self.put_sizes { for put_size in put_sizes { - APTOS_SCHEMADB_PUT_BYTES_SAMPLED - .with_label_values(&[cf_name]) - .observe(*put_size as f64); + APTOS_SCHEMADB_PUT_BYTES_SAMPLED.observe_with(&[cf_name], *put_size as f64); } } for (cf_name, num_deletes) in &self.num_deletes { - APTOS_SCHEMADB_DELETES_SAMPLED - .with_label_values(&[cf_name]) - .inc_by(*num_deletes as u64); + APTOS_SCHEMADB_DELETES_SAMPLED.inc_with_by(&[cf_name], *num_deletes as u64); } } } @@ -178,7 +174,8 @@ impl WriteBatch for SchemaBatch { impl IntoRawBatch for SchemaBatch { fn into_raw_batch(self, db: &DB) -> DbResult { - let _timer = TIMER.timer_with(&["schema_batch_to_raw_batch", &db.name]); + let labels = ["schema_batch_to_raw_batch", &db.name]; + let _timer = TIMER.timer_with(&labels); let Self { rows, stats } = self; diff --git a/storage/schemadb/src/iterator.rs b/storage/schemadb/src/iterator.rs index b239489e618..29166fba8cf 100644 --- a/storage/schemadb/src/iterator.rs +++ b/storage/schemadb/src/iterator.rs @@ -5,6 +5,7 @@ use crate::{ IntoDbResult, KeyCodec, Schema, SeekKeyCodec, ValueCodec, APTOS_SCHEMADB_ITER_BYTES, APTOS_SCHEMADB_ITER_LATENCY_SECONDS, APTOS_SCHEMADB_SEEK_LATENCY_SECONDS, }; +use aptos_metrics_core::TimerHelper; use std::marker::PhantomData; #[derive(PartialEq)] @@ -45,8 +46,7 @@ where /// Seeks to the first key. pub fn seek_to_first(&mut self) { let _timer = APTOS_SCHEMADB_SEEK_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME, "seek_to_first"]) - .start_timer(); + .timer_with(&[S::COLUMN_FAMILY_NAME, "seek_to_first"]); self.db_iter.seek_to_first(); self.status = Status::DoneSeek; } @@ -54,8 +54,7 @@ where /// Seeks to the last key. pub fn seek_to_last(&mut self) { let _timer = APTOS_SCHEMADB_SEEK_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME, "seek_to_last"]) - .start_timer(); + .timer_with(&[S::COLUMN_FAMILY_NAME, "seek_to_last"]); self.db_iter.seek_to_last(); self.status = Status::DoneSeek; } @@ -66,9 +65,8 @@ where where SK: SeekKeyCodec, { - let _timer = APTOS_SCHEMADB_SEEK_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME, "seek"]) - .start_timer(); + let _timer = + APTOS_SCHEMADB_SEEK_LATENCY_SECONDS.timer_with(&[S::COLUMN_FAMILY_NAME, "seek"]); let key = >::encode_seek_key(seek_key)?; self.db_iter.seek(&key); self.status = Status::DoneSeek; @@ -84,8 +82,7 @@ where SK: SeekKeyCodec, { let _timer = APTOS_SCHEMADB_SEEK_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME, "seek_for_prev"]) - .start_timer(); + .timer_with(&[S::COLUMN_FAMILY_NAME, "seek_for_prev"]); let key = >::encode_seek_key(seek_key)?; self.db_iter.seek_for_prev(&key); self.status = Status::DoneSeek; @@ -93,9 +90,7 @@ where } fn next_impl(&mut self) -> aptos_storage_interface::Result> { - let _timer = APTOS_SCHEMADB_ITER_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .start_timer(); + let _timer = APTOS_SCHEMADB_ITER_LATENCY_SECONDS.timer_with(&[S::COLUMN_FAMILY_NAME]); if let Status::Advancing = self.status { match self.direction { @@ -115,9 +110,10 @@ where let raw_key = self.db_iter.key().expect("db_iter.key() failed."); let raw_value = self.db_iter.value().expect("db_iter.value(0 failed."); - APTOS_SCHEMADB_ITER_BYTES - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .observe((raw_key.len() + raw_value.len()) as f64); + APTOS_SCHEMADB_ITER_BYTES.observe_with( + &[S::COLUMN_FAMILY_NAME], + (raw_key.len() + raw_value.len()) as f64, + ); let key = >::decode_key(raw_key); let value = >::decode_value(raw_value); diff --git a/storage/schemadb/src/lib.rs b/storage/schemadb/src/lib.rs index 7b55878d9d0..c30c0e03e3a 100644 --- a/storage/schemadb/src/lib.rs +++ b/storage/schemadb/src/lib.rs @@ -34,12 +34,12 @@ use aptos_metrics_core::TimerHelper; use aptos_storage_interface::{AptosDbError, Result as DbResult}; use batch::{IntoRawBatch, NativeBatch, WriteBatch}; use iterator::{ScanDirection, SchemaIterator}; -use rocksdb::ErrorKind; /// Type alias to `rocksdb::ReadOptions`. See [`rocksdb doc`](https://github.com/pingcap/rust-rocksdb/blob/master/src/rocksdb_options.rs) pub use rocksdb::{ - BlockBasedOptions, Cache, ColumnFamilyDescriptor, DBCompressionType, Options, ReadOptions, - SliceTransform, DEFAULT_COLUMN_FAMILY_NAME, + BlockBasedIndexType, BlockBasedOptions, Cache, ColumnFamilyDescriptor, DBCompressionType, Env, + Options, ReadOptions, SliceTransform, DEFAULT_COLUMN_FAMILY_NAME, }; +use rocksdb::{ErrorKind, WriteOptions}; use std::{collections::HashSet, fmt::Debug, iter::Iterator, path::Path}; pub type ColumnFamilyName = &'static str; @@ -66,20 +66,16 @@ impl DB { column_families: Vec, db_opts: &Options, ) -> DbResult { - let db = DB::open_cf( - db_opts, - path, - name, - column_families - .iter() - .map(|cf_name| { - let mut cf_opts = Options::default(); - cf_opts.set_compression_type(DBCompressionType::Lz4); - ColumnFamilyDescriptor::new((*cf_name).to_string(), cf_opts) - }) - .collect(), - )?; - Ok(db) + Self::open_impl(path, name, column_families, db_opts, OpenMode::ReadWrite) + } + + pub fn open_readonly( + path: impl AsRef, + name: &str, + column_families: Vec, + db_opts: &Options, + ) -> DbResult { + Self::open_impl(path, name, column_families, db_opts, OpenMode::ReadOnly) } pub fn open_cf( @@ -119,6 +115,30 @@ impl DB { ) } + fn open_impl( + path: impl AsRef, + name: &str, + column_families: Vec, + db_opts: &Options, + open_mode: OpenMode, + ) -> DbResult { + let db = DB::open_cf_impl( + db_opts, + path, + name, + column_families + .iter() + .map(|cf_name| { + let mut cf_opts = Options::default(); + cf_opts.set_compression_type(DBCompressionType::Lz4); + ColumnFamilyDescriptor::new((*cf_name).to_string(), cf_opts) + }) + .collect(), + open_mode, + )?; + Ok(db) + } + fn open_cf_impl( db_opts: &Options, path: impl AsRef, @@ -195,17 +215,16 @@ impl DB { /// Reads single record by key. pub fn get(&self, schema_key: &S::Key) -> DbResult> { - let _timer = APTOS_SCHEMADB_GET_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .start_timer(); + let _timer = APTOS_SCHEMADB_GET_LATENCY_SECONDS.timer_with(&[S::COLUMN_FAMILY_NAME]); let k = >::encode_key(schema_key)?; let cf_handle = self.get_cf_handle(S::COLUMN_FAMILY_NAME)?; let result = self.inner.get_cf(cf_handle, k).into_db_res()?; - APTOS_SCHEMADB_GET_BYTES - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .observe(result.as_ref().map_or(0.0, |v| v.len() as f64)); + APTOS_SCHEMADB_GET_BYTES.observe_with( + &[S::COLUMN_FAMILY_NAME], + result.as_ref().map_or(0.0, |v| v.len() as f64), + ); result .map(|raw_value| >::decode_value(&raw_value)) @@ -213,7 +232,7 @@ impl DB { .map_err(Into::into) } - pub fn new_native_batch(&self) -> NativeBatch { + pub fn new_native_batch(&self) -> NativeBatch<'_> { NativeBatch::new(self) } @@ -237,7 +256,7 @@ impl DB { &self, opts: ReadOptions, direction: ScanDirection, - ) -> DbResult> { + ) -> DbResult> { let cf_handle = self.get_cf_handle(S::COLUMN_FAMILY_NAME)?; Ok(SchemaIterator::new( self.inner.raw_iterator_cf_opt(cf_handle, opts), @@ -246,44 +265,59 @@ impl DB { } /// Returns a forward [`SchemaIterator`] on a certain schema. - pub fn iter(&self) -> DbResult> { + pub fn iter(&self) -> DbResult> { self.iter_with_opts(ReadOptions::default()) } /// Returns a forward [`SchemaIterator`] on a certain schema, with non-default ReadOptions - pub fn iter_with_opts(&self, opts: ReadOptions) -> DbResult> { + pub fn iter_with_opts(&self, opts: ReadOptions) -> DbResult> { self.iter_with_direction::(opts, ScanDirection::Forward) } /// Returns a backward [`SchemaIterator`] on a certain schema. - pub fn rev_iter(&self) -> DbResult> { + pub fn rev_iter(&self) -> DbResult> { self.rev_iter_with_opts(ReadOptions::default()) } /// Returns a backward [`SchemaIterator`] on a certain schema, with non-default ReadOptions - pub fn rev_iter_with_opts(&self, opts: ReadOptions) -> DbResult> { + pub fn rev_iter_with_opts( + &self, + opts: ReadOptions, + ) -> DbResult> { self.iter_with_direction::(opts, ScanDirection::Backward) } - /// Writes a group of records wrapped in a [`SchemaBatch`]. - pub fn write_schemas(&self, batch: impl IntoRawBatch) -> DbResult<()> { - let _timer = APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS.timer_with(&[&self.name]); + fn write_schemas_inner(&self, batch: impl IntoRawBatch, option: &WriteOptions) -> DbResult<()> { + let labels = [self.name.as_str()]; + let _timer = APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS.timer_with(&labels); let raw_batch = batch.into_raw_batch(self)?; let serialized_size = raw_batch.inner.size_in_bytes(); self.inner - .write_opt(raw_batch.inner, &default_write_options()) + .write_opt(raw_batch.inner, option) .into_db_res()?; raw_batch.stats.commit(); - APTOS_SCHEMADB_BATCH_COMMIT_BYTES - .with_label_values(&[&self.name]) - .observe(serialized_size as f64); + APTOS_SCHEMADB_BATCH_COMMIT_BYTES.observe_with(&[&self.name], serialized_size as f64); Ok(()) } + /// Writes a group of records wrapped in a [`SchemaBatch`]. + pub fn write_schemas(&self, batch: impl IntoRawBatch) -> DbResult<()> { + self.write_schemas_inner(batch, &sync_write_option()) + } + + /// Writes without sync flag in write option. + /// If this flag is false, and the machine crashes, some recent + /// writes may be lost. Note that if it is just the process that + /// crashes (i.e., the machine does not reboot), no writes will be + /// lost even if sync==false. + pub fn write_schemas_relaxed(&self, batch: impl IntoRawBatch) -> DbResult<()> { + self.write_schemas_inner(batch, &WriteOptions::default()) + } + fn get_cf_handle(&self, cf_name: &str) -> DbResult<&rocksdb::ColumnFamily> { self.inner .cf_handle(cf_name) @@ -338,7 +372,7 @@ impl Drop for DB { /// For now we always use synchronous writes. This makes sure that once the operation returns /// `Ok(())` the data is persisted even if the machine crashes. In the future we might consider /// selectively turning this off for some non-critical writes to improve performance. -fn default_write_options() -> rocksdb::WriteOptions { +fn sync_write_option() -> rocksdb::WriteOptions { let mut opts = rocksdb::WriteOptions::default(); opts.set_sync(true); opts diff --git a/storage/schemadb/src/metrics.rs b/storage/schemadb/src/metrics.rs index cbaf4f703ca..e763e7e4d4a 100644 --- a/storage/schemadb/src/metrics.rs +++ b/storage/schemadb/src/metrics.rs @@ -3,126 +3,114 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_metrics_core::{ - exponential_buckets, register_histogram_vec, register_int_counter_vec, HistogramVec, - IntCounterVec, + exponential_buckets, make_thread_local_histogram_vec, make_thread_local_int_counter_vec, }; -use once_cell::sync::Lazy; -pub static APTOS_SCHEMADB_SEEK_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_seek_latency_seconds", - // metric description - "Aptos schemadb seek latency in seconds", - // metric labels (dimensions) - &["cf_name", "tag"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_SEEK_LATENCY_SECONDS, + // metric name + "aptos_schemadb_seek_latency_seconds", + // metric description + "Aptos schemadb seek latency in seconds", + // metric labels (dimensions) + &["cf_name", "tag"], + exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), +); -pub static APTOS_SCHEMADB_ITER_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_iter_latency_seconds", - // metric description - "Aptos schemadb iter latency in seconds", - // metric labels (dimensions) - &["cf_name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_ITER_LATENCY_SECONDS, + // metric name + "aptos_schemadb_iter_latency_seconds", + // metric description + "Aptos schemadb iter latency in seconds", + // metric labels (dimensions) + &["cf_name"], + exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), +); -pub static APTOS_SCHEMADB_ITER_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_iter_bytes", - // metric description - "Aptos schemadb iter size in bytes", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_ITER_BYTES, + // metric name + "aptos_schemadb_iter_bytes", + // metric description + "Aptos schemadb iter size in bytes", + // metric labels (dimensions) + &["cf_name"] +); -pub static APTOS_SCHEMADB_GET_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_get_latency_seconds", - // metric description - "Aptos schemadb get latency in seconds", - // metric labels (dimensions) - &["cf_name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_GET_LATENCY_SECONDS, + // metric name + "aptos_schemadb_get_latency_seconds", + // metric description + "Aptos schemadb get latency in seconds", + // metric labels (dimensions) + &["cf_name"], + exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), +); -pub static APTOS_SCHEMADB_GET_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_get_bytes", - // metric description - "Aptos schemadb get call returned data size in bytes", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_GET_BYTES, + // metric name + "aptos_schemadb_get_bytes", + // metric description + "Aptos schemadb get call returned data size in bytes", + // metric labels (dimensions) + &["cf_name"] +); -pub static APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_batch_commit_latency_seconds", - // metric description - "Aptos schemadb schema batch commit latency in seconds", - // metric labels (dimensions) - &["db_name"], - exponential_buckets(/*start=*/ 1e-3, /*factor=*/ 2.0, /*count=*/ 20).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS, + // metric name + "aptos_schemadb_batch_commit_latency_seconds", + // metric description + "Aptos schemadb schema batch commit latency in seconds", + // metric labels (dimensions) + &["db_name"], + exponential_buckets(/*start=*/ 1e-3, /*factor=*/ 2.0, /*count=*/ 20).unwrap(), +); -pub static APTOS_SCHEMADB_BATCH_COMMIT_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_batch_commit_bytes", - // metric description - "Aptos schemadb schema batch commit size in bytes", - // metric labels (dimensions) - &["db_name"] - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_BATCH_COMMIT_BYTES, + // metric name + "aptos_schemadb_batch_commit_bytes", + // metric description + "Aptos schemadb schema batch commit size in bytes", + // metric labels (dimensions) + &["db_name"] +); -pub static APTOS_SCHEMADB_PUT_BYTES_SAMPLED: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "aptos_schemadb_put_bytes_sampled", - // metric description - "Aptos schemadb put call puts data size in bytes (sampled)", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + APTOS_SCHEMADB_PUT_BYTES_SAMPLED, + // metric name + "aptos_schemadb_put_bytes_sampled", + // metric description + "Aptos schemadb put call puts data size in bytes (sampled)", + // metric labels (dimensions) + &["cf_name"] +); -pub static APTOS_SCHEMADB_DELETES_SAMPLED: Lazy = Lazy::new(|| { - register_int_counter_vec!( - "aptos_storage_deletes_sampled", - "Aptos storage delete calls (sampled)", - &["cf_name"] - ) - .unwrap() -}); +make_thread_local_int_counter_vec!( + pub, + APTOS_SCHEMADB_DELETES_SAMPLED, + "aptos_storage_deletes_sampled", + "Aptos storage delete calls (sampled)", + &["cf_name"] +); -pub static TIMER: Lazy = Lazy::new(|| { - register_histogram_vec!( - "aptos_schema_db_timer_seconds", - "Various timers for performance analysis.", - &["name", "sub_name"], - exponential_buckets(/*start=*/ 1e-9, /*factor=*/ 2.0, /*count=*/ 32).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + TIMER, + "aptos_schema_db_timer_seconds", + "Various timers for performance analysis.", + &["name", "sub_name"], + exponential_buckets(/*start=*/ 1e-9, /*factor=*/ 2.0, /*count=*/ 32).unwrap(), +); diff --git a/storage/schemadb/tests/iterator.rs b/storage/schemadb/tests/iterator.rs index c1ba4b188a1..db8002c2f6b 100644 --- a/storage/schemadb/tests/iterator.rs +++ b/storage/schemadb/tests/iterator.rs @@ -138,11 +138,11 @@ impl TestDB { } impl TestDB { - fn iter(&self) -> SchemaIterator { + fn iter(&self) -> SchemaIterator<'_, TestSchema> { self.db.iter().expect("Failed to create iterator.") } - fn rev_iter(&self) -> SchemaIterator { + fn rev_iter(&self) -> SchemaIterator<'_, TestSchema> { self.db.rev_iter().expect("Failed to create iterator.") } } @@ -374,11 +374,11 @@ impl TestDBWithPrefixExtractor { } } - fn iter(&self) -> SchemaIterator { + fn iter(&self) -> SchemaIterator<'_, TestSchema> { self.db.iter().expect("Failed to create iterator.") } - fn iter_with_same_prefix(&self) -> SchemaIterator { + fn iter_with_same_prefix(&self) -> SchemaIterator<'_, TestSchema> { let mut opts = rocksdb::ReadOptions::default(); opts.set_prefix_same_as_start(true); self.db @@ -386,7 +386,7 @@ impl TestDBWithPrefixExtractor { .expect("Failed to create iterator.") } - fn iter_with_max_skipped_deletions(&self, num_skips: u64) -> SchemaIterator { + fn iter_with_max_skipped_deletions(&self, num_skips: u64) -> SchemaIterator<'_, TestSchema> { let mut opts = rocksdb::ReadOptions::default(); opts.set_max_skippable_internal_keys(num_skips); self.db @@ -394,7 +394,7 @@ impl TestDBWithPrefixExtractor { .expect("Failed to create iterator.") } - fn iter_with_upper_bound(&self, upper_bound: Vec) -> SchemaIterator { + fn iter_with_upper_bound(&self, upper_bound: Vec) -> SchemaIterator<'_, TestSchema> { let mut opts = rocksdb::ReadOptions::default(); opts.set_iterate_upper_bound(upper_bound); self.db diff --git a/storage/scratchpad/Cargo.toml b/storage/scratchpad/Cargo.toml index c488f91a648..588931e49bc 100644 --- a/storage/scratchpad/Cargo.toml +++ b/storage/scratchpad/Cargo.toml @@ -36,10 +36,7 @@ proptest = { workspace = true } rand = { workspace = true } [target.'cfg(unix)'.dev-dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [features] fuzzing = ["aptos-types/fuzzing", "proptest"] diff --git a/storage/scratchpad/benches/sparse_merkle.rs b/storage/scratchpad/benches/sparse_merkle.rs index baef11c0441..b7ea0c8ceb5 100644 --- a/storage/scratchpad/benches/sparse_merkle.rs +++ b/storage/scratchpad/benches/sparse_merkle.rs @@ -68,7 +68,7 @@ struct Benches { } impl Benches { - fn gen(block_sizes: &[usize]) -> Self { + fn r#gen(block_sizes: &[usize]) -> Self { let mut rng = Self::rng(); // 1 million possible keys @@ -205,7 +205,7 @@ fn sparse_merkle_benches(c: &mut Criterion) { .build_global() .expect("Failed to build rayon global thread pool."); - Benches::gen(&[2, 4, 8, 16, 32, 100, 1000, 10000]).run(c); + Benches::r#gen(&[2, 4, 8, 16, 32, 100, 1000, 10000]).run(c); } criterion_group!(benches, sparse_merkle_benches); diff --git a/storage/scratchpad/src/sparse_merkle/metrics.rs b/storage/scratchpad/src/sparse_merkle/metrics.rs index 4bb41d66e92..2754a84ef27 100644 --- a/storage/scratchpad/src/sparse_merkle/metrics.rs +++ b/storage/scratchpad/src/sparse_merkle/metrics.rs @@ -5,19 +5,18 @@ #![forbid(unsafe_code)] use aptos_metrics_core::{ - exponential_buckets, register_histogram_vec, register_int_gauge_vec, HistogramVec, IntGaugeVec, + exponential_buckets, make_thread_local_histogram_vec, register_int_gauge_vec, IntGaugeVec, }; use once_cell::sync::Lazy; -pub static TIMER: Lazy = Lazy::new(|| { - register_histogram_vec!( - "aptos_scratchpad_smt_timer_seconds", - "Various timers for performance analysis.", - &["name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub, + TIMER, + "aptos_scratchpad_smt_timer_seconds", + "Various timers for performance analysis.", + &["name"], + exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), +); pub static GENERATION: Lazy = Lazy::new(|| { register_int_gauge_vec!( diff --git a/storage/scratchpad/src/sparse_merkle/mod.rs b/storage/scratchpad/src/sparse_merkle/mod.rs index 5a44727446e..ea1d5245424 100644 --- a/storage/scratchpad/src/sparse_merkle/mod.rs +++ b/storage/scratchpad/src/sparse_merkle/mod.rs @@ -89,7 +89,7 @@ use crate::sparse_merkle::{ }; use aptos_crypto::{hash::SPARSE_MERKLE_PLACEHOLDER_HASH, HashValue}; use aptos_infallible::Mutex; -use aptos_metrics_core::IntGaugeHelper; +use aptos_metrics_core::{IntGaugeVecHelper, TimerHelper}; use aptos_types::{ nibble::{nibble_path::NibblePath, Nibble}, proof::SparseMerkleProofExt, @@ -268,9 +268,7 @@ impl SparseMerkleTree { since_smt: &Self, shard_id: u8, ) -> HashMap { - let _timer = TIMER - .with_label_values(&["new_node_hashes_since"]) - .start_timer(); + let _timer = TIMER.timer_with(&["new_node_hashes_since"]); assert!(since_smt.is_family(self)); diff --git a/storage/scratchpad/src/sparse_merkle/sparse_merkle_test.rs b/storage/scratchpad/src/sparse_merkle/sparse_merkle_test.rs index 04d70166bf5..5dc1d5f9da0 100644 --- a/storage/scratchpad/src/sparse_merkle/sparse_merkle_test.rs +++ b/storage/scratchpad/src/sparse_merkle/sparse_merkle_test.rs @@ -209,9 +209,7 @@ fn test_update_256_siblings_in_proof() { let leaf2 = SparseMerkleLeafNode::new(key2, value2_hash); let mut siblings: Vec<_> = - std::iter::repeat(NodeInProof::Other(*SPARSE_MERKLE_PLACEHOLDER_HASH)) - .take(255) - .collect(); + std::iter::repeat_n(NodeInProof::Other(*SPARSE_MERKLE_PLACEHOLDER_HASH), 255).collect(); siblings.push(leaf2.into()); let proof_of_key1 = SparseMerkleProofExt::new(Some(leaf1), siblings.clone()); diff --git a/storage/storage-interface/Cargo.toml b/storage/storage-interface/Cargo.toml index 24475a51b31..39ac9857465 100644 --- a/storage/storage-interface/Cargo.toml +++ b/storage/storage-interface/Cargo.toml @@ -16,6 +16,7 @@ rust-version = { workspace = true } anyhow = { workspace = true } aptos-crypto = { workspace = true } aptos-experimental-layered-map = { workspace = true } +aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-scratchpad = { workspace = true } aptos-secure-net = { workspace = true } @@ -36,6 +37,8 @@ thiserror = { workspace = true } [dev-dependencies] aptos-types = { workspace = true, features = ["fuzzing"] } +bytes = { workspace = true } +lru = { workspace = true } [features] default = [] diff --git a/storage/storage-interface/src/chunk_to_commit.rs b/storage/storage-interface/src/chunk_to_commit.rs index d8d51094776..21356d74cc6 100644 --- a/storage/storage-interface/src/chunk_to_commit.rs +++ b/storage/storage-interface/src/chunk_to_commit.rs @@ -8,12 +8,15 @@ use crate::state_store::{ state_view::cached_state_view::ShardedStateCache, state_with_summary::{LedgerStateWithSummary, StateWithSummary}, }; -use aptos_types::transaction::{Transaction, TransactionInfo, TransactionOutput, Version}; +use aptos_types::transaction::{ + PersistedAuxiliaryInfo, Transaction, TransactionInfo, TransactionOutput, Version, +}; #[derive(Clone)] pub struct ChunkToCommit<'a> { pub first_version: Version, pub transactions: &'a [Transaction], + pub persisted_auxiliary_infos: &'a [PersistedAuxiliaryInfo], pub transaction_outputs: &'a [TransactionOutput], pub transaction_infos: &'a [TransactionInfo], pub state: &'a LedgerState, @@ -55,13 +58,11 @@ impl ChunkToCommit<'_> { pub fn estimated_total_state_updates(&self) -> usize { let for_last_checkpoint = self .state_update_refs - .for_last_checkpoint - .as_ref() + .for_last_checkpoint_batched() .map_or(0, |x| x.len()); let for_latest = self .state_update_refs - .for_latest - .as_ref() + .for_latest_batched() .map_or(0, |x| x.len()); for_latest + for_last_checkpoint diff --git a/storage/storage-interface/src/errors.rs b/storage/storage-interface/src/errors.rs index 7acb9e20202..d472d025e51 100644 --- a/storage/storage-interface/src/errors.rs +++ b/storage/storage-interface/src/errors.rs @@ -8,7 +8,7 @@ use std::sync::mpsc::RecvError; use thiserror::Error; /// This enum defines errors commonly used among `AptosDB` APIs. -#[derive(Debug, Error)] +#[derive(Clone, Debug, Error)] pub enum AptosDbError { /// A requested item is not found. #[error("{0} not found.")] diff --git a/storage/storage-interface/src/ledger_summary.rs b/storage/storage-interface/src/ledger_summary.rs index 0a223b98551..a9464a6c8fd 100644 --- a/storage/storage-interface/src/ledger_summary.rs +++ b/storage/storage-interface/src/ledger_summary.rs @@ -4,6 +4,7 @@ use crate::state_store::{state::LedgerState, state_summary::LedgerStateSummary}; use aptos_types::{ proof::accumulator::{InMemoryAccumulator, InMemoryTransactionAccumulator}, + state_store::hot_state::HotStateConfig, transaction::Version, }; use std::sync::Arc; @@ -38,8 +39,8 @@ impl LedgerSummary { self.next_version().checked_sub(1) } - pub fn new_empty() -> Self { - let state = LedgerState::new_empty(); + pub fn new_empty(hot_state_config: HotStateConfig) -> Self { + let state = LedgerState::new_empty(hot_state_config); let state_summary = LedgerStateSummary::new_empty(); Self::new( state, @@ -48,9 +49,3 @@ impl LedgerSummary { ) } } - -impl Default for LedgerSummary { - fn default() -> Self { - Self::new_empty() - } -} diff --git a/storage/storage-interface/src/lib.rs b/storage/storage-interface/src/lib.rs index d40e3252427..76e9faf095c 100644 --- a/storage/storage-interface/src/lib.rs +++ b/storage/storage-interface/src/lib.rs @@ -25,9 +25,9 @@ use aptos_types::{ table::{TableHandle, TableInfo}, }, transaction::{ - AccountOrderedTransactionsWithProof, IndexedTransactionSummary, Transaction, - TransactionAuxiliaryData, TransactionInfo, TransactionListWithProof, - TransactionOutputListWithProof, TransactionToCommit, TransactionWithProof, Version, + AccountOrderedTransactionsWithProof, IndexedTransactionSummary, PersistedAuxiliaryInfo, + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionListWithProofV2, + TransactionOutputListWithProofV2, TransactionToCommit, TransactionWithProof, Version, }, write_set::WriteSet, }; @@ -100,7 +100,7 @@ impl From for Error { macro_rules! delegate_read { ($( $(#[$($attr:meta)*])* - fn $name:ident(&self $(, $arg: ident : $ty: ty $(,)?)*) -> $return_type:ty; + fn $name:ident(&self $(, $arg: ident : $ty: ty)* $(,)?) -> $return_type:ty; )+) => { $( $(#[$($attr)*])* @@ -139,7 +139,7 @@ pub trait DbReader: Send + Sync { batch_size: u64, ledger_version: Version, fetch_events: bool, - ) -> Result; + ) -> Result; /// See [AptosDB::get_transaction_by_hash]. /// @@ -166,6 +166,20 @@ pub trait DbReader: Send + Sync { version: Version, ) -> Result>; + fn get_persisted_auxiliary_info_by_version( + &self, + version: Version, + ) -> Result; + + /// See [AptosDB::get_persisted_auxiliary_info_iterator]. + /// + /// [AptosDB::get_persisted_auxiliary_info_iterator]: ../aptosdb/struct.AptosDB.html#method.get_persisted_auxiliary_info_iterator + fn get_persisted_auxiliary_info_iterator( + &self, + start_version: Version, + num_persisted_auxiliary_info: usize, + ) -> Result> + '_>>; + /// See [AptosDB::get_first_txn_version]. /// /// [AptosDB::get_first_txn_version]: ../aptosdb/struct.AptosDB.html#method.get_first_txn_version @@ -189,7 +203,7 @@ pub trait DbReader: Send + Sync { start_version: Version, limit: u64, ledger_version: Version, - ) -> Result; + ) -> Result; /// Returns events by given event key fn get_events( @@ -408,6 +422,17 @@ pub trait DbReader: Send + Sync { known_version: u64, ) -> Result; + /// Returns an epoch ending ledger info iterator for the given range. + /// + /// Note: the end epoch is exclusive (an epoch ending ledger info for the + /// end epoch is not returned), e.g., if the start epoch is 1 and the end + /// epoch is 5, epoch ending ledger infos for epochs 1 -> 4 are returned. + fn get_epoch_ending_ledger_info_iterator( + &self, + start_epoch: u64, + end_epoch: u64, + ) -> Result> + '_>>; + /// Gets the transaction accumulator root hash at specified version. /// Caller must guarantee the version is not greater than the latest version. fn get_accumulator_root_hash(&self, _version: Version) -> Result; @@ -452,6 +477,22 @@ pub trait DbReader: Send + Sync { chunk_size: usize, ) -> Result; + /// Returns an iterator of state key value pairs starting from the index. + fn get_state_value_chunk_iter( + &self, + version: Version, + first_index: usize, + chunk_size: usize, + ) -> Result> + '_>>; + + /// Returns a state value chunk proof for the given state key values. + fn get_state_value_chunk_proof( + &self, + version: Version, + first_index: usize, + state_key_values: Vec<(StateKey, StateValue)>, + ) -> Result; + /// Returns if the state store pruner is enabled. fn is_state_merkle_pruner_enabled(&self) -> Result; @@ -550,7 +591,7 @@ pub trait DbWriter: Send + Sync { fn finalize_state_snapshot( &self, version: Version, - output_with_proof: TransactionOutputListWithProof, + output_with_proof: TransactionOutputListWithProofV2, ledger_infos: &[LedgerInfoWithSignatures], ) -> Result<()> { unimplemented!() diff --git a/storage/storage-interface/src/metrics.rs b/storage/storage-interface/src/metrics.rs index 7d18850ebaa..a569946cf25 100644 --- a/storage/storage-interface/src/metrics.rs +++ b/storage/storage-interface/src/metrics.rs @@ -4,29 +4,22 @@ #![forbid(unsafe_code)] use aptos_metrics_core::{ - exponential_buckets, register_histogram_vec, register_int_counter_vec, HistogramVec, - IntCounterVec, + exponential_buckets, make_thread_local_histogram_vec, make_thread_local_int_counter_vec, }; -use once_cell::sync::Lazy; -pub(crate) static TIMER: Lazy = Lazy::new(|| { - register_histogram_vec!( - "aptos_storage_interface_timer_seconds", - "Various timers for performance analysis.", - &["name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); +make_thread_local_histogram_vec!( + pub(crate), + TIMER, + "aptos_storage_interface_timer_seconds", + "Various timers for performance analysis.", + &["name"], + exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), +); -pub static COUNTER: Lazy = Lazy::new(|| { - register_int_counter_vec!( - // metric name - "aptos_storage_interface_counter", - // metric description - "Various counters for storage-interface.", - // metric labels (dimensions) - &["name"], - ) - .unwrap() -}); +make_thread_local_int_counter_vec!( + pub(crate), + COUNTER, + "aptos_storage_interface_counter", + "Various counters for storage-interface.", + &["name"], +); diff --git a/storage/storage-interface/src/state_store/hot_state.rs b/storage/storage-interface/src/state_store/hot_state.rs new file mode 100644 index 00000000000..a1704a3fd3a --- /dev/null +++ b/storage/storage-interface/src/state_store/hot_state.rs @@ -0,0 +1,410 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::state_store::state_view::hot_state_view::HotStateView; +use aptos_experimental_layered_map::LayeredMap; +use aptos_types::state_store::{ + hot_state::THotStateSlot, state_key::StateKey, state_slot::StateSlot, +}; +use std::{collections::HashMap, num::NonZeroUsize, sync::Arc}; + +pub(crate) struct HotStateLRU<'a> { + /// Max total number of items in the cache. + capacity: NonZeroUsize, + /// The entire committed hot state. While this contains all the shards, this struct is supposed + /// to handle a single shard. + committed: Arc, + /// Additional entries resulted from previous speculative execution. + overlay: &'a LayeredMap, + /// The new entries from current execution. + pending: HashMap, + /// Points to the latest entry. `None` if empty. + head: Option, + /// Points to the oldest entry. `None` if empty. + tail: Option, + /// Total number of items. + num_items: usize, +} + +impl<'a> HotStateLRU<'a> { + pub fn new( + capacity: NonZeroUsize, + committed: Arc, + overlay: &'a LayeredMap, + head: Option, + tail: Option, + num_items: usize, + ) -> Self { + Self { + capacity, + committed, + overlay, + pending: HashMap::new(), + head, + tail, + num_items, + } + } + + pub fn insert(&mut self, key: StateKey, slot: StateSlot) { + assert!( + slot.is_hot(), + "Should not insert cold slots into hot state." + ); + if self.delete(&key).is_none() { + self.num_items += 1; + } + self.insert_as_head(key, slot); + } + + fn insert_as_head(&mut self, key: StateKey, mut slot: StateSlot) { + match self.head.take() { + Some(head) => { + let mut old_head_slot = self.expect_hot_slot(&head); + old_head_slot.set_prev(Some(key.clone())); + slot.set_prev(None); + slot.set_next(Some(head.clone())); + self.pending.insert(head, old_head_slot); + self.pending.insert(key.clone(), slot); + self.head = Some(key); + }, + None => { + slot.set_prev(None); + slot.set_next(None); + self.pending.insert(key.clone(), slot); + self.head = Some(key.clone()); + self.tail = Some(key); + }, + } + } + + /// Returns the list of entries evicted, beginning from the LRU. + pub fn maybe_evict(&mut self) -> Vec<(StateKey, StateSlot)> { + let mut current = match &self.tail { + Some(tail) => tail.clone(), + None => { + assert_eq!(self.num_items, 0); + return Vec::new(); + }, + }; + + let mut evicted = Vec::new(); + while self.num_items > self.capacity.get() { + let slot = self + .delete(¤t) + .expect("There must be entries to evict when current size is above capacity."); + let prev_key = slot + .prev() + .cloned() + .expect("There must be at least one newer entry (num_items > capacity >= 1)."); + evicted.push((current.clone(), slot.clone())); + self.pending.insert(current, slot.to_cold()); + current = prev_key; + self.num_items -= 1; + } + evicted + } + + /// Returns the deleted slot, or `None` if the key doesn't exist or is not hot. + fn delete(&mut self, key: &StateKey) -> Option { + // Fetch the slot corresponding to the given key. Note that `self.pending` and + // `self.overlay` may contain cold slots, like the ones recently evicted, and we need to + // ignore them. + let old_slot = match self.get_slot(key) { + Some(slot) if slot.is_hot() => slot, + _ => return None, + }; + + match old_slot.prev() { + Some(prev_key) => { + let mut prev_slot = self.expect_hot_slot(prev_key); + prev_slot.set_next(old_slot.next().cloned()); + self.pending.insert(prev_key.clone(), prev_slot); + }, + None => { + // There is no newer entry. The current key was the head. + self.head = old_slot.next().cloned(); + }, + } + + match old_slot.next() { + Some(next_key) => { + let mut next_slot = self.expect_hot_slot(next_key); + next_slot.set_prev(old_slot.prev().cloned()); + self.pending.insert(next_key.clone(), next_slot); + }, + None => { + // There is no older entry. The current key was the tail. + self.tail = old_slot.prev().cloned(); + }, + } + + Some(old_slot) + } + + pub(crate) fn get_slot(&self, key: &StateKey) -> Option { + if let Some(slot) = self.pending.get(key) { + return Some(slot.clone()); + } + + if let Some(slot) = self.overlay.get(key) { + return Some(slot); + } + + self.committed.get_state_slot(key) + } + + fn expect_hot_slot(&self, key: &StateKey) -> StateSlot { + let slot = self.get_slot(key).expect("Given key is expected to exist."); + assert!(slot.is_hot(), "Given key is expected to be hot."); + slot + } + + pub fn into_updates( + self, + ) -> ( + HashMap, + Option, + Option, + usize, + ) { + (self.pending, self.head, self.tail, self.num_items) + } + + #[cfg(test)] + fn iter(&self) -> Iter<'_, '_> { + Iter { + current_key: self.head.clone(), + lru: self, + } + } + + #[cfg(test)] + fn validate(&self) { + self.validate_impl(self.head.clone(), |slot| slot.next()); + self.validate_impl(self.tail.clone(), |slot| slot.prev()); + } + + #[cfg(test)] + fn validate_impl( + &self, + start: Option, + func: impl Fn(&StateSlot) -> Option<&StateKey>, + ) { + let mut current = start; + let mut num_visited = 0; + while let Some(key) = current { + let slot = self.expect_hot_slot(&key); + num_visited += 1; + current = func(&slot).cloned(); + } + assert_eq!(num_visited, self.num_items); + } +} + +#[cfg(test)] +struct Iter<'a, 'b> { + current_key: Option, + lru: &'a HotStateLRU<'b>, +} + +#[cfg(test)] +impl<'a, 'b> Iterator for Iter<'a, 'b> { + type Item = (StateKey, StateSlot); + + fn next(&mut self) -> Option<(StateKey, StateSlot)> { + let key = self.current_key.take()?; + let slot = self.lru.expect_hot_slot(&key); + self.current_key = slot.next().cloned(); + Some((key, slot)) + } +} + +#[cfg(test)] +mod tests { + use super::HotStateLRU; + use crate::state_store::state_view::hot_state_view::HotStateView; + use aptos_experimental_layered_map::{LayeredMap, MapLayer}; + use aptos_types::{ + state_store::{ + hot_state::LRUEntry, state_key::StateKey, state_slot::StateSlot, + state_value::StateValue, + }, + transaction::Version, + }; + use lru::LruCache; + use proptest::{ + collection::{hash_set, vec}, + prelude::*, + sample, + strategy::Strategy, + }; + use std::{ + collections::HashMap, + num::NonZeroUsize, + sync::{Arc, Mutex}, + }; + + #[derive(Debug)] + struct HotState { + inner: HashMap, + head: Option, + tail: Option, + } + + impl HotStateView for Mutex { + fn get_state_slot(&self, state_key: &StateKey) -> Option { + self.lock().unwrap().inner.get(state_key).cloned() + } + } + + struct LRUTest { + hot_state: Arc>, + _base_layer: MapLayer, + _top_layer: MapLayer, + overlay: LayeredMap, + } + + impl LRUTest { + fn new_empty() -> Self { + let hot_state = Arc::new(Mutex::new(HotState { + inner: HashMap::new(), + head: None, + tail: None, + })); + let base_layer = MapLayer::new_family("test"); + let top_layer = base_layer.clone(); + let overlay = base_layer.view_layers_after(&top_layer); + + Self { + hot_state, + _base_layer: base_layer, + _top_layer: top_layer, + overlay, + } + } + + fn commit_updates( + &self, + updates: HashMap, + head: Option, + tail: Option, + num_items: usize, + ) { + // For most of the logic we don't really care whether the data is in committed state or + // in the overlay, so we just merge everything directly to committed state, and keep + // the overlay empty. + let mut locked = self.hot_state.lock().unwrap(); + for (key, slot) in updates { + if slot.is_hot() { + locked.inner.insert(key, slot); + } else { + locked.inner.remove(&key); + } + } + locked.head = head; + locked.tail = tail; + assert_eq!(locked.inner.len(), num_items); + } + } + + fn arb_hot_slot() -> impl Strategy { + (any::(), any::()).prop_flat_map(|(version, value)| { + prop_oneof![ + 4 => Just(StateSlot::HotOccupied { + value_version: version, + value, + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }), + 1 => Just(StateSlot::HotVacant { + hot_since_version: version, + lru_info: LRUEntry::uninitialized(), + }), + ] + }) + } + + fn assert_lru_equal(actual: &HotStateLRU, expected: &LruCache) { + assert_eq!( + actual + .iter() + .map(|(key, slot)| { + assert!(slot.is_hot()); + (key, slot.into_state_value_opt()) + }) + .collect::>(), + expected + .iter() + .map(|(key, slot)| { + assert!(slot.is_hot()); + (key.clone(), slot.clone().into_state_value_opt()) + }) + .collect::>(), + ); + } + + proptest! { + #![proptest_config(ProptestConfig::with_cases(20))] + + #[test] + fn test_empty_overlay( + blocks in (hash_set(any::(), 1..50), 1..10usize) + .prop_flat_map(|(keys, num_blocks)| { + let pool: Vec<_> = keys.into_iter().collect(); + let mut blocks = Vec::new(); + for _i in 0..num_blocks { + let block = vec((sample::select(pool.clone()), arb_hot_slot()), 1..100); + blocks.push(block); + } + blocks + }), + capacity in (1..10usize).prop_map(|n| NonZeroUsize::new(n).unwrap()), + ) { + let test_obj = LRUTest::new_empty(); + let mut head = None; + let mut tail = None; + let mut num_items = 0; + // Use an unbounded cache because it can temporarily exceed the capacity in the middle + // of the block. + let mut naive_lru = LruCache::unbounded(); + + for updates in blocks { + let mut lru = HotStateLRU::new( + capacity, + Arc::clone(&test_obj.hot_state) as Arc, + &test_obj.overlay, + head, + tail, + num_items, + ); + lru.validate(); + + for (key, slot) in updates { + lru.insert(key.clone(), slot.clone()); + naive_lru.put(key, slot); + lru.validate(); + assert_lru_equal(&lru, &naive_lru); + } + + let actual_evicted = lru.maybe_evict(); + let mut expected_evicted = Vec::new(); + while naive_lru.len() > capacity.get() { + expected_evicted.push(naive_lru.pop_lru().unwrap()); + } + itertools::zip_eq(actual_evicted, expected_evicted).for_each(|(actual, expected)| { + assert_eq!(actual.0, expected.0); + assert_eq!(actual.1.into_state_value_opt(), expected.1.into_state_value_opt()); + }); + lru.validate(); + assert_lru_equal(&lru, &naive_lru); + + let (updates, new_head, new_tail, new_num_items) = lru.into_updates(); + test_obj.commit_updates(updates, new_head.clone(), new_tail.clone(), new_num_items); + head = new_head; + tail = new_tail; + num_items = new_num_items; + } + } + } +} diff --git a/storage/storage-interface/src/state_store/mod.rs b/storage/storage-interface/src/state_store/mod.rs index 05accea0ad8..00c44162862 100644 --- a/storage/storage-interface/src/state_store/mod.rs +++ b/storage/storage-interface/src/state_store/mod.rs @@ -1,6 +1,9 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +// TODO(HotState): remove. +#[allow(dead_code)] +mod hot_state; pub mod state; pub mod state_delta; pub mod state_summary; @@ -8,5 +11,3 @@ pub mod state_update_refs; pub mod state_view; pub mod state_with_summary; pub mod versioned_state_value; - -pub const NUM_STATE_SHARDS: usize = 16; diff --git a/storage/storage-interface/src/state_store/state.rs b/storage/storage-interface/src/state_store/state.rs index eaa9bee467b..fa0d8638d72 100644 --- a/storage/storage-interface/src/state_store/state.rs +++ b/storage/storage-interface/src/state_store/state.rs @@ -4,14 +4,16 @@ use crate::{ metrics::TIMER, state_store::{ + hot_state::HotStateLRU, state_delta::StateDelta, - state_update_refs::{BatchedStateUpdateRefs, StateUpdateRefs}, + state_update_refs::{BatchedStateUpdateRefs, PerVersionStateUpdateRefs, StateUpdateRefs}, state_view::{ - cached_state_view::{CachedStateView, ShardedStateCache, StateCacheShard}, + cached_state_view::{ + CachedStateView, PrimingPolicy, ShardedStateCache, StateCacheShard, + }, hot_state_view::HotStateView, }, versioned_state_value::StateUpdateRef, - NUM_STATE_SHARDS, }, DbReader, }; @@ -20,8 +22,8 @@ use aptos_experimental_layered_map::{LayeredMap, MapLayer}; use aptos_metrics_core::TimerHelper; use aptos_types::{ state_store::{ - state_key::StateKey, state_slot::StateSlot, state_storage_usage::StateStorageUsage, - StateViewId, + hot_state::HotStateConfig, state_key::StateKey, state_slot::StateSlot, + state_storage_usage::StateStorageUsage, StateViewId, NUM_STATE_SHARDS, }, transaction::Version, }; @@ -29,7 +31,24 @@ use arr_macro::arr; use derive_more::Deref; use itertools::Itertools; use rayon::prelude::*; -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, num::NonZeroUsize, sync::Arc}; + +#[derive(Clone, Debug)] +pub struct HotStateMetadata { + latest: Option, + oldest: Option, + num_items: usize, +} + +impl HotStateMetadata { + fn new() -> Self { + Self { + latest: None, + oldest: None, + num_items: 0, + } + } +} /// Represents the blockchain state at a given version. /// n.b. the state can be either persisted or speculative. @@ -42,33 +61,45 @@ pub struct State { /// between this and a `base_version` to list the updates or create a /// new `State` at a descendant version. shards: Arc<[MapLayer; NUM_STATE_SHARDS]>, + hot_state_metadata: [HotStateMetadata; NUM_STATE_SHARDS], /// The total usage of the state at the current version. usage: StateStorageUsage, + hot_state_config: HotStateConfig, } impl State { pub fn new_with_updates( version: Option, shards: Arc<[MapLayer; NUM_STATE_SHARDS]>, + hot_state_metadata: [HotStateMetadata; NUM_STATE_SHARDS], usage: StateStorageUsage, + hot_state_config: HotStateConfig, ) -> Self { Self { next_version: version.map_or(0, |v| v + 1), shards, + hot_state_metadata, usage, + hot_state_config, } } - pub fn new_at_version(version: Option, usage: StateStorageUsage) -> Self { + pub fn new_at_version( + version: Option, + usage: StateStorageUsage, + hot_state_config: HotStateConfig, + ) -> Self { Self::new_with_updates( version, Arc::new(arr![MapLayer::new_family("state"); 16]), + arr![HotStateMetadata::new(); 16], usage, + hot_state_config, ) } - pub fn new_empty() -> Self { - Self::new_at_version(None, StateStorageUsage::zero()) + pub fn new_empty(hot_state_config: HotStateConfig) -> Self { + Self::new_at_version(None, StateStorageUsage::zero(), hot_state_config) } pub fn next_version(&self) -> Version { @@ -104,16 +135,32 @@ impl State { self.shards[0].is_descendant_of(&rhs.shards[0]) } - pub fn update( + pub fn latest_hot_key(&self, shard_id: usize) -> Option { + self.hot_state_metadata[shard_id].latest.clone() + } + + pub fn oldest_hot_key(&self, shard_id: usize) -> Option { + self.hot_state_metadata[shard_id].oldest.clone() + } + + pub fn num_hot_items(&self, shard_id: usize) -> usize { + self.hot_state_metadata[shard_id].num_items + } + + fn update( &self, + persisted_hot_state: Arc, persisted: &State, - updates: &BatchedStateUpdateRefs, + batched_updates: &BatchedStateUpdateRefs, + per_version_updates: &PerVersionStateUpdateRefs, + all_checkpoint_versions: &[Version], state_cache: &ShardedStateCache, ) -> Result { let _timer = TIMER.timer_with(&["state__update"]); // 1. The update batch must begin at self.next_version(). - assert_eq!(self.next_version(), updates.first_version); + assert_eq!(self.next_version(), batched_updates.first_version); + assert_eq!(self.next_version(), per_version_updates.first_version); // 2. The cache must be at a version equal or newer than `persisted`, otherwise // updates between the cached version and the persisted version are potentially // missed during the usage calculation. @@ -131,29 +178,94 @@ impl State { assert!(self.next_version() >= state_cache.next_version()); let overlay = self.make_delta(persisted); - let (shards, usage_delta_per_shard): (Vec<_>, Vec<_>) = ( + let ((shards, new_metadata), usage_delta_per_shard): ((Vec<_>, Vec<_>), Vec<_>) = ( state_cache.shards.as_slice(), overlay.shards.as_slice(), - updates.shards.as_slice(), + self.hot_state_metadata.as_slice(), + batched_updates.shards.as_slice(), + per_version_updates.shards.as_slice(), ) .into_par_iter() - .map(|(cache, overlay, updates)| { - let new_items = updates - .iter() - .map(|(k, u)| ((*k).clone(), u.to_result_slot())) - .collect_vec(); + .map( + |(cache, overlay, hot_metadata, batched_updates, per_version)| { + let mut lru = HotStateLRU::new( + NonZeroUsize::new(self.hot_state_config.max_items_per_shard).unwrap(), + Arc::clone(&persisted_hot_state), + overlay, + hot_metadata.latest.clone(), + hot_metadata.oldest.clone(), + hot_metadata.num_items, + ); + let mut all_updates = per_version.iter(); + for ckpt_version in all_checkpoint_versions { + for (key, update) in + all_updates.take_while_ref(|(_k, u)| u.version <= *ckpt_version) + { + Self::apply_one_update(&mut lru, overlay, cache, key, update); + } + // Only evict at the checkpoints. + lru.maybe_evict(); + } + for (key, update) in all_updates { + Self::apply_one_update(&mut lru, overlay, cache, key, update); + } + + let (new_items, new_head, new_tail, new_num_items) = lru.into_updates(); + let new_items = new_items.into_iter().collect_vec(); - ( // TODO(aldenhu): change interface to take iter of ref - overlay.new_layer(&new_items), - Self::usage_delta_for_shard(cache, overlay, updates), - ) - }) + let new_layer = overlay.new_layer(&new_items); + let new_metadata = HotStateMetadata { + latest: new_head, + oldest: new_tail, + num_items: new_num_items, + }; + let new_usage = Self::usage_delta_for_shard(cache, overlay, batched_updates); + ((new_layer, new_metadata), new_usage) + }, + ) .unzip(); let shards = Arc::new(shards.try_into().expect("Known to be 16 shards.")); + let new_metadata = new_metadata.try_into().expect("Known to be 16 shards."); let usage = self.update_usage(usage_delta_per_shard); - Ok(State::new_with_updates(updates.last_version(), shards, usage)) + // TODO(HotState): extract and pass new hot state onchain config if needed. + Ok(State::new_with_updates( + batched_updates.last_version(), + shards, + new_metadata, + usage, + self.hot_state_config, + )) + } + + fn apply_one_update( + lru: &mut HotStateLRU, + overlay: &LayeredMap, + read_cache: &StateCacheShard, + key: &StateKey, + update: &StateUpdateRef, + ) { + if update.state_op.is_value_write_op() { + lru.insert((*key).clone(), update.to_result_slot().unwrap()); + return; + } + + if let Some(mut slot) = lru.get_slot(key) { + lru.insert( + (*key).clone(), + if slot.is_hot() { + slot.refresh(update.version); + slot + } else { + slot.to_hot(update.version) + }, + ); + } else { + let slot = Self::expect_old_slot(overlay, read_cache, key); + assert!(slot.is_cold()); + lru.insert((*key).clone(), slot.to_hot(update.version)); + } } fn update_usage(&self, usage_delta_per_shard: Vec<(i64, i64)>) -> StateStorageUsage { @@ -176,19 +288,20 @@ impl State { let mut items_delta: i64 = 0; let mut bytes_delta: i64 = 0; for (k, v) in updates { + let state_value_opt = match v.state_op.as_state_value_opt() { + Some(value_opt) => value_opt, + None => continue, + }; + let key_size = k.size(); - if let Some(value) = v.state_op.as_state_value_opt() { + if let Some(value) = state_value_opt { items_delta += 1; bytes_delta += (key_size + value.size()) as i64; } - // TODO(aldenhu): avoid cloning the state value (by not using DashMap) // n.b. all updated state items must be read and recorded in the state cache, // otherwise we can't calculate the correct usage. - let old_slot = overlay - .get(k) - .or_else(|| cache.get(k).map(|entry| entry.value().clone())) - .expect("Must cache read"); + let old_slot = Self::expect_old_slot(overlay, cache, k); if old_slot.is_occupied() { items_delta -= 1; bytes_delta -= (key_size + old_slot.size()) as i64; @@ -196,6 +309,23 @@ impl State { } (items_delta, bytes_delta) } + + fn expect_old_slot( + overlay: &LayeredMap, + cache: &StateCacheShard, + key: &StateKey, + ) -> StateSlot { + if let Some(slot) = overlay.get(key) { + return slot; + } + + // TODO(aldenhu): avoid cloning the state value (by not using DashMap) + cache + .get(key) + .unwrap_or_else(|| panic!("Key {:?} must exist in the cache.", key)) + .value() + .clone() + } } /// At a given version, the state and the last checkpoint state at or before the version. @@ -216,8 +346,8 @@ impl LedgerState { } } - pub fn new_empty() -> Self { - let state = State::new_empty(); + pub fn new_empty(hot_state_config: HotStateConfig) -> Self { + let state = State::new_empty(hot_state_config); Self::new(state.clone(), state) } @@ -237,25 +367,46 @@ impl LedgerState { /// have already been recorded. pub fn update_with_memorized_reads( &self, + persisted_hot_view: Arc, persisted_snapshot: &State, updates: &StateUpdateRefs, reads: &ShardedStateCache, ) -> Result { let _timer = TIMER.timer_with(&["ledger_state__update"]); - let last_checkpoint = if let Some(updates) = &updates.for_last_checkpoint { - self.latest().update(persisted_snapshot, updates, reads)? + let last_checkpoint = if let Some(batched) = updates.for_last_checkpoint_batched() { + let per_version = updates + .for_last_checkpoint_per_version() + .expect("Both per-version and batched updates should exist."); + self.latest().update( + Arc::clone(&persisted_hot_view), + persisted_snapshot, + batched, + per_version, + updates.all_checkpoint_versions(), + reads, + )? } else { self.last_checkpoint.clone() }; - let base_of_latest = if updates.for_last_checkpoint.is_none() { + let base_of_latest = if updates.for_last_checkpoint_batched().is_none() { self.latest() } else { &last_checkpoint }; - let latest = if let Some(updates) = &updates.for_latest { - base_of_latest.update(persisted_snapshot, updates, reads)? + let latest = if let Some(batched) = updates.for_latest_batched() { + let per_version = updates + .for_latest_per_version() + .expect("Both per-version and batched updates should exist."); + base_of_latest.update( + persisted_hot_view, + persisted_snapshot, + batched, + per_version, + &[], + reads, + )? } else { base_of_latest.clone() }; @@ -275,13 +426,14 @@ impl LedgerState { let state_view = CachedStateView::new_impl( StateViewId::Miscellaneous, reader, - hot_state, + Arc::clone(&hot_state), persisted_snapshot.clone(), self.latest().clone(), ); - state_view.prime_cache(updates)?; + state_view.prime_cache(updates, PrimingPolicy::All)?; let updated = self.update_with_memorized_reads( + hot_state, persisted_snapshot, updates, state_view.memorized_reads(), @@ -299,7 +451,9 @@ impl LedgerState { #[cfg(test)] mod tests { use super::*; - use crate::state_store::state_view::cached_state_view::ShardedStateCache; + use crate::state_store::state_view::{ + cached_state_view::ShardedStateCache, hot_state_view::EmptyHotState, + }; use aptos_types::state_store::state_storage_usage::StateStorageUsage; /// When the persisted version advances past the cache version (fork race), @@ -307,15 +461,25 @@ mod tests { #[test] fn state_update_returns_error_when_persisted_exceeds_cache() { // "self" state at version 5 (next_version = 6) - let current = State::new_at_version(Some(5), StateStorageUsage::new(0, 0)); + let current = + State::new_at_version(Some(5), StateStorageUsage::new(0, 0), HotStateConfig::default()); // Persisted state has advanced to version 8 (next_version = 9) — fork race - let persisted = State::new_at_version(Some(8), StateStorageUsage::new(0, 0)); + let persisted = + State::new_at_version(Some(8), StateStorageUsage::new(0, 0), HotStateConfig::default()); // Cache is still at version 5 (next_version = 6) — behind persisted let cache = ShardedStateCache::new_empty(Some(5)); // Updates starting at version 6 (matching current.next_version) let updates = BatchedStateUpdateRefs::new_empty(6, 1); - - let result = current.update(&persisted, &updates, &cache); + let per_version_updates = PerVersionStateUpdateRefs::new_empty(6); + + let result = current.update( + Arc::new(EmptyHotState), + &persisted, + &updates, + &per_version_updates, + &[], + &cache, + ); assert!(result.is_err(), "expected error when persisted > cache version"); let msg = result.unwrap_err().to_string(); assert!(msg.contains("fork race"), "error should mention fork race, got: {msg}"); @@ -324,17 +488,27 @@ mod tests { /// Boundary: persisted.next_version == cache.next_version should pass the check. #[test] fn state_update_does_not_error_when_persisted_equals_cache() { - let current = State::new_at_version(Some(5), StateStorageUsage::new(0, 0)); - let persisted = State::new_at_version(Some(5), StateStorageUsage::new(0, 0)); + let current = + State::new_at_version(Some(5), StateStorageUsage::new(0, 0), HotStateConfig::default()); + let persisted = + State::new_at_version(Some(5), StateStorageUsage::new(0, 0), HotStateConfig::default()); let cache = ShardedStateCache::new_empty(Some(5)); let updates = BatchedStateUpdateRefs::new_empty(6, 1); + let per_version_updates = PerVersionStateUpdateRefs::new_empty(6); // We only care that the ensure! check passes (persisted <= cache). // The call will panic later on the descendant-of check (states aren't // from the same family in this unit harness), but that's a different // invariant — catch it and verify the panic isn't from the fork-race guard. let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - let _ = current.update(&persisted, &updates, &cache); + let _ = current.update( + Arc::new(EmptyHotState), + &persisted, + &updates, + &per_version_updates, + &[], + &cache, + ); })); if let Err(panic) = result { let msg = panic diff --git a/storage/storage-interface/src/state_store/state_delta.rs b/storage/storage-interface/src/state_store/state_delta.rs index aefcaa63cd0..39e3f72f617 100644 --- a/storage/storage-interface/src/state_store/state_delta.rs +++ b/storage/storage-interface/src/state_store/state_delta.rs @@ -1,13 +1,15 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::state_store::{state::State, NUM_STATE_SHARDS}; +use crate::state_store::state::State; use aptos_experimental_layered_map::LayeredMap; use aptos_types::{ - state_store::{state_key::StateKey, state_slot::StateSlot}, + state_store::{ + hot_state::HOT_STATE_MAX_ITEMS_PER_SHARD, state_key::StateKey, state_slot::StateSlot, + NUM_STATE_SHARDS, + }, transaction::Version, }; -use itertools::Itertools; use std::sync::Arc; /// This represents two state sparse merkle trees at their versions in memory with the updates @@ -28,16 +30,9 @@ impl StateDelta { pub fn new(base: State, current: State) -> Self { assert!(current.is_descendant_of(&base)); - let shards = Arc::new( - current - .shards() - .iter() - .zip_eq(base.shards().iter()) - .map(|(current, base)| current.view_layers_after(base)) - .collect_vec() - .try_into() - .expect("Known to be 16 shards."), - ); + let shards = Arc::new(std::array::from_fn(|shard_id| { + current.shards()[shard_id].view_layers_after(&base.shards()[shard_id]) + })); Self { base, @@ -57,6 +52,28 @@ impl StateDelta { /// Get the state update for a given state key. /// `None` indicates the key is not updated in the delta. pub fn get_state_slot(&self, state_key: &StateKey) -> Option { - self.shards[state_key.get_shard_id() as usize].get(state_key) + self.shards[state_key.get_shard_id()].get(state_key) + } + + pub(crate) fn num_free_hot_slots(&self) -> [usize; NUM_STATE_SHARDS] { + std::array::from_fn(|shard_id| { + let num_items = self.current.num_hot_items(shard_id); + assert!( + num_items <= HOT_STATE_MAX_ITEMS_PER_SHARD, + "Number of hot state items {} exceeded max size {} in shard {}.", + num_items, + HOT_STATE_MAX_ITEMS_PER_SHARD, + shard_id, + ); + HOT_STATE_MAX_ITEMS_PER_SHARD - num_items + }) + } + + pub fn latest_hot_key(&self, shard_id: usize) -> Option { + self.current.latest_hot_key(shard_id) + } + + pub fn oldest_hot_key(&self, shard_id: usize) -> Option { + self.current.oldest_hot_key(shard_id) } } diff --git a/storage/storage-interface/src/state_store/state_summary.rs b/storage/storage-interface/src/state_store/state_summary.rs index f2f03fcbd47..03b5e470c6c 100644 --- a/storage/storage-interface/src/state_store/state_summary.rs +++ b/storage/storage-interface/src/state_store/state_summary.rs @@ -10,7 +10,10 @@ use crate::{ DbReader, }; use anyhow::{ensure, Result}; -use aptos_crypto::{hash::CORRUPTION_SENTINEL, HashValue}; +use aptos_crypto::{ + hash::{CryptoHash, CORRUPTION_SENTINEL}, + HashValue, +}; use aptos_metrics_core::TimerHelper; use aptos_scratchpad::{ProofRead, SparseMerkleTree}; use aptos_types::{proof::SparseMerkleProofExt, transaction::Version}; @@ -95,7 +98,13 @@ impl StateSummary { .flat_map(|shard| { shard .iter() - .map(|(k, u)| (*k, u.value_hash_opt())) + .filter_map(|(k, u)| { + // Filter out `MakeHot` ops. + u.state_op + .as_state_value_opt() + .map(|value_opt| (k, value_opt)) + }) + .map(|(k, value_opt)| (*k, value_opt.map(|v| v.hash()))) // The keys in the shard are already unique, and shards are ordered by the // first nibble of the key hash. `batch_update_sorted_uniq` can be // called if within each shard items are sorted by key hash. @@ -170,18 +179,18 @@ impl LedgerStateSummary { ) -> Result { let _timer = TIMER.timer_with(&["ledger_state_summary__update"]); - let last_checkpoint = if let Some(updates) = &updates.for_last_checkpoint { + let last_checkpoint = if let Some(updates) = updates.for_last_checkpoint_batched() { self.latest.update(persisted, updates)? } else { self.last_checkpoint.clone() }; - let base_of_latest = if updates.for_last_checkpoint.is_none() { + let base_of_latest = if updates.for_last_checkpoint_batched().is_none() { self.latest() } else { &last_checkpoint }; - let latest = if let Some(updates) = &updates.for_latest { + let latest = if let Some(updates) = updates.for_latest_batched() { base_of_latest.update(persisted, updates)? } else { base_of_latest.clone() diff --git a/storage/storage-interface/src/state_store/state_update_refs.rs b/storage/storage-interface/src/state_store/state_update_refs.rs index 29748a445e5..fe33cea8e33 100644 --- a/storage/storage-interface/src/state_store/state_update_refs.rs +++ b/storage/storage-interface/src/state_store/state_update_refs.rs @@ -1,31 +1,40 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - metrics::TIMER, - state_store::{versioned_state_value::StateUpdateRef, NUM_STATE_SHARDS}, -}; +use crate::{metrics::TIMER, state_store::versioned_state_value::StateUpdateRef}; +use aptos_logger::{sample, sample::SampleRate, warn}; use aptos_metrics_core::TimerHelper; use aptos_types::{ - state_store::state_key::StateKey, + state_store::{state_key::StateKey, NUM_STATE_SHARDS}, transaction::Version, write_set::{BaseStateOp, WriteSet}, }; use arr_macro::arr; use itertools::Itertools; -use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator}; -use std::collections::HashMap; +use rayon::prelude::*; +use std::{ + collections::{hash_map::Entry, HashMap}, + time::Duration, +}; +#[derive(Clone, Debug)] pub struct PerVersionStateUpdateRefs<'kv> { pub first_version: Version, pub num_versions: usize, - /// Converting to Vec to Box<[]> to release over-allocated memory during construction /// TODO(HotState): let WriteOp always carry StateSlot, so we can use &'kv StateSlot here - pub shards: [Box<[(&'kv StateKey, StateUpdateRef<'kv>)]>; NUM_STATE_SHARDS], + pub shards: [Vec<(&'kv StateKey, StateUpdateRef<'kv>)>; NUM_STATE_SHARDS], } impl<'kv> PerVersionStateUpdateRefs<'kv> { - pub fn index< + pub(crate) fn new_empty(first_version: Version) -> Self { + Self { + first_version, + num_versions: 0, + shards: arr![Vec::new(); 16], + } + } + + fn index< UpdateIter: IntoIterator, VersionIter: IntoIterator, >( @@ -44,7 +53,7 @@ impl<'kv> PerVersionStateUpdateRefs<'kv> { versions_seen += 1; for (key, write_op) in update_iter.into_iter() { - shards[key.get_shard_id() as usize].push((key, StateUpdateRef { + shards[key.get_shard_id()].push((key, StateUpdateRef { version, state_op: write_op, })); @@ -54,7 +63,11 @@ impl<'kv> PerVersionStateUpdateRefs<'kv> { Self { first_version, - shards: shards.map(|shard| shard.into_boxed_slice()), + shards: shards.map(|mut shard| { + // Release over-allocated memory during construction. + shard.shrink_to_fit(); + shard + }), num_versions, } } @@ -68,7 +81,7 @@ pub struct BatchedStateUpdateRefs<'kv> { } impl BatchedStateUpdateRefs<'_> { - pub fn new_empty(first_version: Version, num_versions: usize) -> Self { + pub(crate) fn new_empty(first_version: Version, num_versions: usize) -> Self { Self { first_version, num_versions, @@ -95,24 +108,52 @@ impl BatchedStateUpdateRefs<'_> { pub fn is_empty(&self) -> bool { self.len() == 0 } + + #[cfg(test)] + fn get(&self, key: &str) -> Option<&StateUpdateRef<'_>> { + let state_key = StateKey::raw(key.as_bytes()); + let shard_id = state_key.get_shard_id(); + self.shards[shard_id].get(&state_key) + } } +#[derive(Debug)] pub struct StateUpdateRefs<'kv> { pub per_version: PerVersionStateUpdateRefs<'kv>, - /// Batched updates (updates for the same keys are merged) from the - /// beginning of the block/chunk to the last checkpoint (if it exists). - pub for_last_checkpoint: Option>, - /// Batched updates from the version after last check point to last version - /// (`None` if the last version is a checkpoint, e.g. in a regular block). - pub for_latest: Option>, + all_checkpoint_versions: Vec, + /// Updates from the beginning of the block/chunk to the last checkpoint (if it exists). + for_last_checkpoint: Option<(PerVersionStateUpdateRefs<'kv>, BatchedStateUpdateRefs<'kv>)>, + /// Updates from the version after last checkpoint to last version (`None` if the last version + /// is a checkpoint, e.g. in a regular block). + for_latest: Option<(PerVersionStateUpdateRefs<'kv>, BatchedStateUpdateRefs<'kv>)>, } impl<'kv> StateUpdateRefs<'kv> { + pub(crate) fn all_checkpoint_versions(&self) -> &[Version] { + &self.all_checkpoint_versions + } + + pub(crate) fn for_last_checkpoint_per_version(&self) -> Option<&PerVersionStateUpdateRefs<'_>> { + self.for_last_checkpoint.as_ref().map(|x| &x.0) + } + + pub(crate) fn for_last_checkpoint_batched(&self) -> Option<&BatchedStateUpdateRefs<'_>> { + self.for_last_checkpoint.as_ref().map(|x| &x.1) + } + + pub(crate) fn for_latest_per_version(&self) -> Option<&PerVersionStateUpdateRefs<'_>> { + self.for_latest.as_ref().map(|x| &x.0) + } + + pub(crate) fn for_latest_batched(&self) -> Option<&BatchedStateUpdateRefs<'_>> { + self.for_latest.as_ref().map(|x| &x.1) + } + pub fn index_write_sets( first_version: Version, write_sets: impl IntoIterator, num_write_sets: usize, - last_checkpoint_index: Option, + all_checkpoint_indices: Vec, ) -> Self { Self::index( first_version, @@ -120,7 +161,7 @@ impl<'kv> StateUpdateRefs<'kv> { .into_iter() .map(|write_set| write_set.base_op_iter()), num_write_sets, - last_checkpoint_index, + all_checkpoint_indices, ) } @@ -131,88 +172,245 @@ impl<'kv> StateUpdateRefs<'kv> { first_version: Version, updates_by_version: VersionIter, num_versions: usize, - last_checkpoint_index: Option, + all_checkpoint_indices: Vec, ) -> Self { - let per_version = - PerVersionStateUpdateRefs::index(first_version, updates_by_version, num_versions); + if num_versions == 0 { + return Self { + per_version: PerVersionStateUpdateRefs::new_empty(first_version), + all_checkpoint_versions: vec![], + for_last_checkpoint: None, + for_latest: None, + }; + } + + let mut updates_by_version = updates_by_version.into_iter(); + let mut num_versions_for_last_checkpoint = 0; + let last_checkpoint_index = all_checkpoint_indices.last().copied(); + + let for_last_checkpoint = last_checkpoint_index.map(|index| { + num_versions_for_last_checkpoint = index + 1; + let per_version = PerVersionStateUpdateRefs::index( + first_version, + updates_by_version + .by_ref() + .take(num_versions_for_last_checkpoint), + num_versions_for_last_checkpoint, + ); + let batched = Self::batch_updates(&per_version); + (per_version, batched) + }); + + let for_latest = match last_checkpoint_index { + Some(index) if index + 1 == num_versions => None, + _ => { + assert!(num_versions_for_last_checkpoint < num_versions); + let per_version = PerVersionStateUpdateRefs::index( + first_version + num_versions_for_last_checkpoint as Version, + updates_by_version, + num_versions - num_versions_for_last_checkpoint, + ); + let batched = Self::batch_updates(&per_version); + Some((per_version, batched)) + }, + }; - let (for_last_checkpoint, for_latest) = - Self::collect_updates(&per_version, last_checkpoint_index); Self { - per_version, + per_version: Self::concat_per_version_updates( + for_last_checkpoint.as_ref().map(|x| &x.0), + for_latest.as_ref().map(|x| &x.0), + ), + all_checkpoint_versions: all_checkpoint_indices + .into_iter() + .map(|index| first_version + index as Version) + .collect(), for_last_checkpoint, for_latest, } } + fn concat_per_version_updates( + for_last_checkpoint: Option<&PerVersionStateUpdateRefs<'kv>>, + for_latest: Option<&PerVersionStateUpdateRefs<'kv>>, + ) -> PerVersionStateUpdateRefs<'kv> { + match for_last_checkpoint { + Some(for_last_checkpoint) => { + let mut all = for_last_checkpoint.clone(); + if let Some(for_latest) = for_latest { + all.num_versions += for_latest.num_versions; + for (dest, src) in all.shards.iter_mut().zip_eq(for_latest.shards.iter()) { + dest.extend_from_slice(src); + } + } + all + }, + None => for_latest.cloned().expect("At least one should be Some."), + } + } + pub fn last_inner_checkpoint_index(&self) -> Option { - self.for_last_checkpoint - .as_ref() - .map(|updates| updates.num_versions - 1) + self.for_last_checkpoint.as_ref().map(|updates| { + assert_eq!(updates.0.num_versions, updates.1.num_versions); + updates.0.num_versions - 1 + }) } - fn collect_updates( + fn batch_updates( per_version_updates: &PerVersionStateUpdateRefs<'kv>, - last_checkpoint_index: Option, - ) -> ( - Option>, - Option>, - ) { + ) -> BatchedStateUpdateRefs<'kv> { let _timer = TIMER.timer_with(&["index_state_updates__collect_batch"]); - let mut shard_iters = per_version_updates + let mut ret = BatchedStateUpdateRefs::new_empty( + per_version_updates.first_version, + per_version_updates.num_versions, + ); + per_version_updates .shards - .iter() + .par_iter() .map(|shard| shard.iter().cloned()) - .collect::>(); - - let mut first_version_to_collect = per_version_updates.first_version; - let mut remaining_versions = per_version_updates.num_versions; - let updates_for_last_checkpoint = last_checkpoint_index.map(|idx| { - let num_versions = idx + 1; - let ret = Self::collect_some_updates( - first_version_to_collect, - num_versions, - &mut shard_iters, - ); - first_version_to_collect += num_versions as Version; - remaining_versions -= num_versions; - ret - }); - let updates_for_latest = if remaining_versions == 0 { - None - } else { - Some(Self::collect_some_updates( - first_version_to_collect, - remaining_versions, - &mut shard_iters, - )) - }; - - // Assert that all updates are consumed. - assert!(shard_iters.iter_mut().all(|iter| iter.next().is_none())); - - (updates_for_last_checkpoint, updates_for_latest) - } - - fn collect_some_updates( - first_version: Version, - num_versions: usize, - shard_iters: &mut [impl Iterator)> + Clone + Send], - ) -> BatchedStateUpdateRefs<'kv> { - let mut ret = BatchedStateUpdateRefs::new_empty(first_version, num_versions); - // exclusive - let end_version = first_version + num_versions as Version; - shard_iters - .par_iter_mut() .zip_eq(ret.shards.par_iter_mut()) .for_each(|(shard_iter, dedupped)| { - dedupped.extend( - shard_iter - // n.b. take_while_ref so that in the next step we can process the rest of the entries from the iters. - .take_while_ref(|(_k, u)| u.version < end_version), - ) + for (k, u) in shard_iter { + // If it's a value write op (Creation/Modification/Deletion), just insert and + // overwrite the previous op. + if u.state_op.is_value_write_op() { + dedupped.insert(k, u); + continue; + } + + // If we see a hotness op, we check if there is a value write op with the same + // key before. This is unlikely, but if it does happen (e.g. if the write + // summary used to compute MakeHot is missing keys), we must discard the + // hotness op to avoid overwriting the value write op. + // TODO(HotState): also double check this logic for state sync later. For now + // we do not output hotness ops for state sync. + match dedupped.entry(k) { + Entry::Occupied(mut entry) => { + let prev_op = &entry.get().state_op; + sample!( + SampleRate::Duration(Duration::from_secs(10)), + warn!( + "Key: {:?}. Previous write op: {}. Current write op: {}", + k, + prev_op.as_ref(), + u.state_op.as_ref() + ) + ); + if !prev_op.is_value_write_op() { + entry.insert(u); + } + }, + Entry::Vacant(entry) => { + entry.insert(u); + }, + } + } }); ret } } + +#[cfg(test)] +mod tests { + use super::{BatchedStateUpdateRefs, StateUpdateRefs}; + use aptos_types::{ + state_store::{state_key::StateKey, state_value::StateValueMetadata}, + transaction::Version, + write_set::{WriteOp, WriteSet, WriteSetMut}, + }; + use bytes::Bytes; + + fn write_set(kvs: &[(&str, &str)]) -> WriteSet { + WriteSetMut::from_iter(kvs.iter().map(|(key, value)| { + let key = StateKey::raw(key.as_bytes()); + let value = Bytes::copy_from_slice(value.as_bytes()); + let op = WriteOp::modification(value, StateValueMetadata::none()); + (key, op) + })) + .freeze() + .unwrap() + } + + fn verify_batching( + res: &BatchedStateUpdateRefs, + key: &str, + expected_version: Version, + expected_value: &str, + ) { + let u = res.get(key).unwrap(); + assert_eq!(u.version, expected_version); + assert_eq!( + u.state_op.as_state_value_opt().unwrap().unwrap().bytes(), + expected_value + ); + } + + #[test] + fn test_regular_block() { + // A regular block, or a chunk that ends exactly at a block boundary. + let v0 = write_set(&[("A", "A0")]); + let v1 = write_set(&[("A", "A1"), ("B", "B1")]); + let v2 = write_set(&[("C", "C2")]); + let all_checkpoint_indices = vec![2]; + let ret = + StateUpdateRefs::index_write_sets(0, vec![&v0, &v1, &v2], 3, all_checkpoint_indices); + + let for_last_checkpoint = ret.for_last_checkpoint_batched().unwrap(); + assert_eq!(for_last_checkpoint.first_version, 0); + assert_eq!(for_last_checkpoint.num_versions, 3); + verify_batching(for_last_checkpoint, "A", 1, "A1"); + verify_batching(for_last_checkpoint, "B", 1, "B1"); + verify_batching(for_last_checkpoint, "C", 2, "C2"); + + assert!(ret.for_latest_batched().is_none()); + } + + #[test] + fn test_chunk_with_checkpoint() { + // For example, the second half of a previous block and the first half of the current + // block. + let v0 = write_set(&[("A", "A0")]); + let v1 = write_set(&[("A", "A1"), ("B", "B1")]); + let v2 = write_set(&[("A", "A2"), ("B", "B2")]); + let v3 = write_set(&[("B", "B3"), ("C", "C3")]); + let all_checkpoint_indices = vec![1]; + let ret = StateUpdateRefs::index_write_sets( + 0, + vec![&v0, &v1, &v2, &v3], + 4, + all_checkpoint_indices, + ); + + let for_last_checkpoint = ret.for_last_checkpoint_batched().unwrap(); + assert_eq!(for_last_checkpoint.first_version, 0); + assert_eq!(for_last_checkpoint.num_versions, 2); + verify_batching(for_last_checkpoint, "A", 1, "A1"); + verify_batching(for_last_checkpoint, "B", 1, "B1"); + + let for_latest = ret.for_latest_batched().unwrap(); + assert_eq!(for_latest.first_version, 2); + assert_eq!(for_latest.num_versions, 2); + verify_batching(for_latest, "A", 2, "A2"); + verify_batching(for_latest, "B", 3, "B3"); + verify_batching(for_latest, "C", 3, "C3"); + } + + #[test] + fn test_chunk_with_no_checkpoint() { + // A chunk that is the middle of a large block. + let v0 = write_set(&[("A", "A0"), ("B", "B0")]); + let v1 = write_set(&[("A", "A1")]); + let v2 = write_set(&[("C", "C2")]); + let all_checkpoint_indices = vec![]; + let ret = + StateUpdateRefs::index_write_sets(10, vec![&v0, &v1, &v2], 3, all_checkpoint_indices); + + assert!(ret.for_last_checkpoint_batched().is_none()); + + let for_latest = ret.for_latest_batched().unwrap(); + assert_eq!(for_latest.first_version, 10); + assert_eq!(for_latest.num_versions, 3); + verify_batching(for_latest, "A", 11, "A1"); + verify_batching(for_latest, "B", 10, "B0"); + verify_batching(for_latest, "C", 12, "C2"); + } +} diff --git a/storage/storage-interface/src/state_store/state_view/cached_state_view.rs b/storage/storage-interface/src/state_store/state_view/cached_state_view.rs index a3a9689eb61..9cecb6e13d7 100644 --- a/storage/storage-interface/src/state_store/state_view/cached_state_view.rs +++ b/storage/storage-interface/src/state_store/state_view/cached_state_view.rs @@ -11,16 +11,16 @@ use crate::{ db_state_view::DbStateView, hot_state_view::{EmptyHotState, HotStateView}, }, - NUM_STATE_SHARDS, }, DbReader, }; use anyhow::Result; -use aptos_metrics_core::{IntCounterHelper, TimerHelper}; +use aptos_metrics_core::{IntCounterVecHelper, TimerHelper}; use aptos_types::{ state_store::{ - state_key::StateKey, state_slot::StateSlot, state_storage_usage::StateStorageUsage, - state_value::StateValue, StateViewId, StateViewResult, TStateView, + hot_state::THotStateSlot, state_key::StateKey, state_slot::StateSlot, + state_storage_usage::StateStorageUsage, StateViewId, StateViewResult, TStateView, + NUM_STATE_SHARDS, }, transaction::Version, }; @@ -59,8 +59,8 @@ impl ShardedStateCache { } } - fn shard(&self, shard_id: u8) -> &StateCacheShard { - &self.shards[shard_id as usize] + fn shard(&self, shard_id: usize) -> &StateCacheShard { + &self.shards[shard_id] } pub fn get_cloned(&self, state_key: &StateKey) -> Option { @@ -85,6 +85,14 @@ impl ShardedStateCache { } } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PrimingPolicy { + /// Prime cache for all keys in the write sets. + All, + /// Only prime cache for the keys that are prepared for hot state promotion. + MakeHotOnly, +} + /// `CachedStateView` is like a snapshot of the global state comprised of state view at two /// levels, persistent storage and memory. /// TODO(aldenhu): This is actually MemorizingStateUpdateView? @@ -168,25 +176,36 @@ impl CachedStateView { ) } - pub fn prime_cache(&self, updates: &StateUpdateRefs) -> Result<()> { + pub fn prime_cache(&self, updates: &StateUpdateRefs, policy: PrimingPolicy) -> Result<()> { let _timer = TIMER.timer_with(&["prime_state_cache"]); IO_POOL.install(|| { - if let Some(updates) = &updates.for_last_checkpoint { - self.prime_cache_for_batched_updates(updates)?; + if let Some(updates) = updates.for_last_checkpoint_batched() { + self.prime_cache_for_batched_updates(updates, policy)?; } - if let Some(updates) = &updates.for_latest { - self.prime_cache_for_batched_updates(updates)?; + if let Some(updates) = updates.for_latest_batched() { + self.prime_cache_for_batched_updates(updates, policy)?; } Ok(()) }) } - fn prime_cache_for_batched_updates(&self, updates: &BatchedStateUpdateRefs) -> Result<()> { - updates - .shards - .par_iter() - .try_for_each(|shard| self.prime_cache_for_keys(shard.keys().cloned())) + fn prime_cache_for_batched_updates( + &self, + updates: &BatchedStateUpdateRefs, + policy: PrimingPolicy, + ) -> Result<()> { + updates.shards.par_iter().try_for_each(|shard| { + self.prime_cache_for_keys( + shard + .iter() + .filter_map(|(k, u)| match policy { + PrimingPolicy::MakeHotOnly if u.state_op.is_value_write_op() => None, + _ => Some(k), + }) + .cloned(), + ) + }) } fn prime_cache_for_keys<'a, T: IntoIterator + Send>( @@ -218,7 +237,7 @@ impl CachedStateView { let ret = if let Some(slot) = self.speculative.get_state_slot(state_key) { COUNTER.inc_with(&["sv_hit_speculative"]); slot - } else if let Some(slot) = self.hot.get_state_slot(state_key)? { + } else if let Some(slot) = self.hot.get_state_slot(state_key) { COUNTER.inc_with(&["sv_hit_hot"]); slot } else if let Some(base_version) = self.base_version() { @@ -246,6 +265,10 @@ impl CachedStateView { &self.speculative.base } + pub fn persisted_hot_state(&self) -> Arc { + Arc::clone(&self.hot) + } + pub fn memorized_reads(&self) -> &ShardedStateCache { &self.memorized } @@ -259,7 +282,7 @@ impl TStateView for CachedStateView { } fn get_state_slot(&self, state_key: &StateKey) -> StateViewResult { - let _timer = TIMER.with_label_values(&["get_state_value"]).start_timer(); + let _timer = TIMER.timer_with(&["get_state_value"]); COUNTER.inc_with(&["sv_total_get"]); // First check if requested key is already memorized. @@ -281,11 +304,56 @@ impl TStateView for CachedStateView { fn next_version(&self) -> Version { self.speculative.next_version() } + + fn contains_hot_state_value(&self, state_key: &StateKey) -> bool { + if let Some(slot) = self.speculative.get_state_slot(state_key) { + // Most likely the slot we get from `self.speculative` is hot, because it is recently + // written to. However, this is not guaranteed because there could be rules, for + // example, one that prevents large state values from going into the hot state. So we + // need to check whether it's hot explicitly. + // + // Same for `get_next_old_key` below. + return slot.is_hot(); + } + + self.hot.get_state_slot(state_key).is_some() + } + + fn num_free_hot_slots(&self) -> [usize; NUM_STATE_SHARDS] { + self.speculative.num_free_hot_slots() + } + + fn get_shard_id(&self, state_key: &StateKey) -> usize { + state_key.get_shard_id() + } + + fn get_next_old_key( + &self, + shard_id: usize, + state_key: Option<&StateKey>, + ) -> Option> { + let key = match state_key { + Some(k) => { + assert_eq!(k.get_shard_id(), shard_id); + k + }, + None => return Some(self.speculative.oldest_hot_key(shard_id)), + }; + + if let Some(slot) = self.speculative.get_state_slot(key) { + slot.is_hot().then(|| slot.next().cloned()) + } else if let Some(slot) = self.hot.get_state_slot(key) { + assert!(slot.is_hot()); + Some(slot.next().cloned()) + } else { + None + } + } } pub struct CachedDbStateView { db_state_view: DbStateView, - state_cache: RwLock>>, + state_cache: RwLock>, } impl From for CachedDbStateView { @@ -304,18 +372,16 @@ impl TStateView for CachedDbStateView { self.db_state_view.id() } - fn get_state_value(&self, state_key: &StateKey) -> StateViewResult> { + fn get_state_slot(&self, state_key: &Self::Key) -> StateViewResult { // First check if the cache has the state value. if let Some(val_opt) = self.state_cache.read().get(state_key) { // This can return None, which means the value has been deleted from the DB. return Ok(val_opt.clone()); } - let state_value_option = self.db_state_view.get_state_value(state_key)?; + let state_slot = self.db_state_view.get_state_slot(state_key)?; // Update the cache if still empty let mut cache = self.state_cache.write(); - let new_value = cache - .entry(state_key.clone()) - .or_insert_with(|| state_value_option); + let new_value = cache.entry(state_key.clone()).or_insert_with(|| state_slot); Ok(new_value.clone()) } diff --git a/storage/storage-interface/src/state_store/state_view/db_state_view.rs b/storage/storage-interface/src/state_store/state_view/db_state_view.rs index 145f0011869..870ba75bd02 100644 --- a/storage/storage-interface/src/state_store/state_view/db_state_view.rs +++ b/storage/storage-interface/src/state_store/state_view/db_state_view.rs @@ -6,8 +6,9 @@ use aptos_crypto::HashValue; use aptos_types::{ ledger_info::LedgerInfo, state_store::{ - errors::StateViewError, state_key::StateKey, state_storage_usage::StateStorageUsage, - state_value::StateValue, StateViewResult, TStateView, + errors::StateViewError, state_key::StateKey, state_slot::StateSlot, + state_storage_usage::StateStorageUsage, state_value::StateValue, StateViewId, + StateViewResult, TStateView, }, transaction::Version, }; @@ -23,7 +24,7 @@ pub struct DbStateView { } impl DbStateView { - fn get(&self, key: &StateKey) -> StateViewResult> { + fn get(&self, key: &StateKey) -> StateViewResult> { if let Some(version) = self.version { if let Some(root_hash) = self.maybe_verify_against_state_root_hash { // TODO(aldenhu): sample-verify proof inside DB @@ -34,10 +35,11 @@ impl DbStateView { self.db.get_state_value_with_proof_by_version(key, version) { proof.verify(root_hash, *key.crypto_hash_ref(), value.as_ref())?; - return Ok(value); } } - Ok(self.db.get_state_value_by_version(key, version)?) + Ok(self + .db + .get_state_value_with_version_by_version(key, version)?) } else { Ok(None) } @@ -47,8 +49,18 @@ impl DbStateView { impl TStateView for DbStateView { type Key = StateKey; - fn get_state_value(&self, state_key: &StateKey) -> StateViewResult> { - self.get(state_key) + fn id(&self) -> StateViewId { + if let Some(version) = self.version { + StateViewId::TransactionValidation { + base_version: version, + } + } else { + StateViewId::Miscellaneous + } + } + + fn get_state_slot(&self, state_key: &StateKey) -> StateViewResult { + Ok(StateSlot::from_db_get(self.get(state_key)?)) } fn get_usage(&self) -> StateViewResult { diff --git a/storage/storage-interface/src/state_store/state_view/hot_state_view.rs b/storage/storage-interface/src/state_store/state_view/hot_state_view.rs index a511b5a62b7..8af3cbad2b0 100644 --- a/storage/storage-interface/src/state_store/state_view/hot_state_view.rs +++ b/storage/storage-interface/src/state_store/state_view/hot_state_view.rs @@ -2,17 +2,17 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use aptos_types::state_store::{state_key::StateKey, state_slot::StateSlot, StateViewResult}; +use aptos_types::state_store::{state_key::StateKey, state_slot::StateSlot}; /// A view into the hot state store, whose content overlays on top of the cold state store content. pub trait HotStateView: Send + Sync { - fn get_state_slot(&self, state_key: &StateKey) -> StateViewResult>; + fn get_state_slot(&self, state_key: &StateKey) -> Option; } pub struct EmptyHotState; impl HotStateView for EmptyHotState { - fn get_state_slot(&self, _state_key: &StateKey) -> StateViewResult> { - Ok(None) + fn get_state_slot(&self, _state_key: &StateKey) -> Option { + None } } diff --git a/storage/storage-interface/src/state_store/state_with_summary.rs b/storage/storage-interface/src/state_store/state_with_summary.rs index 27c9086e0fe..c74c7365c2f 100644 --- a/storage/storage-interface/src/state_store/state_with_summary.rs +++ b/storage/storage-interface/src/state_store/state_with_summary.rs @@ -7,7 +7,10 @@ use crate::state_store::{ }; use aptos_crypto::HashValue; use aptos_scratchpad::SparseMerkleTree; -use aptos_types::{state_store::state_storage_usage::StateStorageUsage, transaction::Version}; +use aptos_types::{ + state_store::{hot_state::HotStateConfig, state_storage_usage::StateStorageUsage}, + transaction::Version, +}; use derive_more::{Deref, DerefMut}; #[derive(Clone, Debug, Deref)] @@ -23,8 +26,11 @@ impl StateWithSummary { Self { state, summary } } - pub fn new_empty() -> Self { - Self::new(State::new_empty(), StateSummary::new_empty()) + pub fn new_empty(hot_state_config: HotStateConfig) -> Self { + Self::new( + State::new_empty(hot_state_config), + StateSummary::new_empty(), + ) } pub fn new_at_version( @@ -32,9 +38,10 @@ impl StateWithSummary { hot_state_root_hash: HashValue, global_state_root_hash: HashValue, usage: StateStorageUsage, + hot_state_config: HotStateConfig, ) -> Self { Self::new( - State::new_at_version(version, usage), + State::new_at_version(version, usage, hot_state_config), StateSummary::new_at_version( version, SparseMerkleTree::new(hot_state_root_hash), @@ -86,8 +93,8 @@ impl LedgerStateWithSummary { Self::from_latest_and_last_checkpoint(checkpoint.clone(), checkpoint) } - pub fn new_empty() -> Self { - let empty = StateWithSummary::new_empty(); + pub fn new_empty(hot_state_config: HotStateConfig) -> Self { + let empty = StateWithSummary::new_empty(hot_state_config); Self::from_latest_and_last_checkpoint(empty.clone(), empty) } @@ -101,6 +108,10 @@ impl LedgerStateWithSummary { ) } + pub fn is_at_checkpoint(&self) -> bool { + self.latest.next_version() == self.last_checkpoint.next_version() + } + pub fn last_checkpoint(&self) -> &StateWithSummary { &self.last_checkpoint } diff --git a/storage/storage-interface/src/state_store/versioned_state_value.rs b/storage/storage-interface/src/state_store/versioned_state_value.rs index a890c3427fe..55f2e0a00f4 100644 --- a/storage/storage-interface/src/state_store/versioned_state_value.rs +++ b/storage/storage-interface/src/state_store/versioned_state_value.rs @@ -1,9 +1,10 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_types::{ - state_store::state_slot::StateSlot, transaction::Version, write_set::BaseStateOp, + state_store::{hot_state::LRUEntry, state_slot::StateSlot}, + transaction::Version, + write_set::BaseStateOp, }; #[derive(Clone, Debug)] @@ -14,45 +15,22 @@ pub struct StateUpdateRef<'kv> { } impl StateUpdateRef<'_> { - pub fn to_result_slot(&self) -> StateSlot { + /// NOTE: the lru_info in the result is not initialized yet. + pub fn to_result_slot(&self) -> Option { match self.state_op.clone() { BaseStateOp::Creation(value) | BaseStateOp::Modification(value) => { - StateSlot::HotOccupied { + Some(StateSlot::HotOccupied { value_version: self.version, value, hot_since_version: self.version, - } + lru_info: LRUEntry::uninitialized(), + }) }, - BaseStateOp::Deletion(_) => StateSlot::HotVacant { + BaseStateOp::Deletion(_) => Some(StateSlot::HotVacant { hot_since_version: self.version, - }, - BaseStateOp::MakeHot { prev_slot } => match prev_slot { - StateSlot::ColdVacant => StateSlot::HotVacant { - hot_since_version: self.version, - }, - StateSlot::HotVacant { - hot_since_version: _, - } => StateSlot::HotVacant { - hot_since_version: self.version, - }, - StateSlot::ColdOccupied { - value_version, - value, - } - | StateSlot::HotOccupied { - value_version, - value, - hot_since_version: _, - } => StateSlot::HotOccupied { - value_version, - value, - hot_since_version: self.version, - }, - }, + lru_info: LRUEntry::uninitialized(), + }), + BaseStateOp::MakeHot => None, } } - - pub fn value_hash_opt(&self) -> Option { - self.state_op.as_state_value_opt().map(|val| val.hash()) - } } diff --git a/terraform/helm/fullnode/README.md b/terraform/helm/fullnode/README.md index 7fd1cfa8451..9ec53e157ef 100644 --- a/terraform/helm/fullnode/README.md +++ b/terraform/helm/fullnode/README.md @@ -134,6 +134,6 @@ Deployment $ helm install fullnode --set storage.class=gp2 . -[REST API]: https://github.com/aptos-labs/aptos-core/blob/main/api/doc/v0/openapi.yaml +[REST API]: https://github.com/aptos-labs/aptos-core/blob/main/api/doc/spec.yaml [values.yaml]: values.yaml [Aptos dockerhub]: https://hub.docker.com/r/aptoslabs/validator/tags?page=1&ordering=last_updated diff --git a/testsuite/benchmark-workloads/README.md b/testsuite/benchmark-workloads/README.md new file mode 100644 index 00000000000..c3f84aa5804 --- /dev/null +++ b/testsuite/benchmark-workloads/README.md @@ -0,0 +1,18 @@ +# Adding benchmarking workloads + +In order to add a benchmark to the testsuite, follow the following steps: + +1. Add your Move package to `packages` if you want to use a stable language version. + Alternatively, for latest language version (which may be unstable) use `packages-experimental`. +2. Generate prebuilt packages. + These packages are saved as binaries. + Transaction generator library will load these binaries and generate transactions that publish packages. + + ```bash + cd testsuite/benchmark-workloads + ./generate.py + ``` + Make sure to always run generation script in order to persist your new workloads. +3. In transaction generator, add CLI arguments to call entry functions from your packages or scripts. + For that, just follow what is done for existing arguments [here](../../crates/transaction-workloads-lib/src/args.rs) + and [here](../../crates/transaction-workloads-lib/src/move_workloads.rs). diff --git a/testsuite/benchmark-workloads/generate.py b/testsuite/benchmark-workloads/generate.py new file mode 100755 index 00000000000..b0ae27bde1e --- /dev/null +++ b/testsuite/benchmark-workloads/generate.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +# Copyright © Aptos Foundation +# SPDX-License-Identifier: Apache-2.0 + +import subprocess +import pathlib + +ROOT = pathlib.Path(__file__).absolute().parents[2] + +# Specifies directories for regular packages. +# Paths are relative to the root of the aptos-core repository. +PACKAGES = [ + "testsuite/benchmark-workloads/packages", + "aptos-move/move-examples/token_objects/ambassador", + "aptos-move/move-examples/aggregator_examples", + "aptos-move/move-examples/bcs-stream" +] +# Specifies directories for experimental packages (will be compiled with latest, possibly unstable) language version. +# Paths are relative to the root of the aptos-core repository. +EXPERIMENTAL_PACKAGES = [ + "testsuite/benchmark-workloads/packages-experimental/experimental_usecases", +] + +# Directory where the prebuilt binary is saved. +PREBUILT_PACKAGES_DIR = "crates/transaction-workloads-lib" + + +def run_command(command): + with subprocess.Popen( + command, + shell=True, + text=True, + stdout=subprocess.PIPE, + bufsize=1, + universal_newlines=True, + ) as p: + if p.stdout is not None: + for line in p.stdout: + print(line, end="") + + if p.returncode != 0: + print("Failed to generate the workloads!") + exit(p.returncode) + + +if __name__ == "__main__": + package_paths = " ".join(f"--packages-path {ROOT / package}" for package in PACKAGES) + experimental_package_paths = " ".join( + f"--experimental-packages-path {ROOT / package}" for package in EXPERIMENTAL_PACKAGES) + + # By default, we built in with local framework. + command = (f"cargo run --package package-generator -- " + f"--use-local-std " + f"{package_paths} " + f"{experimental_package_paths} " + f"--prebuilt-packages-file-dir {ROOT / PREBUILT_PACKAGES_DIR} " + f"--prebuilt-packages-rust-dir {ROOT / PREBUILT_PACKAGES_DIR}/src") + print(command) + run_command(command) diff --git a/testsuite/benchmark-workloads/package-generator/Cargo.toml b/testsuite/benchmark-workloads/package-generator/Cargo.toml new file mode 100644 index 00000000000..e20a14185d3 --- /dev/null +++ b/testsuite/benchmark-workloads/package-generator/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "package-generator" +description = "Move package generator for benchmarking" +version = "0.1.0" + +# Workspace inherited keys +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +anyhow = { workspace = true } +aptos-transaction-generator-lib = { workspace = true } +clap = { workspace = true } diff --git a/testsuite/benchmark-workloads/package-generator/src/main.rs b/testsuite/benchmark-workloads/package-generator/src/main.rs new file mode 100644 index 00000000000..9a6fe3b7702 --- /dev/null +++ b/testsuite/benchmark-workloads/package-generator/src/main.rs @@ -0,0 +1,87 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::bail; +use aptos_transaction_generator_lib::{create_prebuilt_packages_bundle, PrebuiltPackageConfig}; +use clap::Parser; +use std::{ + fs, io, + path::{Path, PathBuf}, +}; + +#[derive(Parser)] +#[command(author, version, about)] +struct Args { + /// Root directory where packages are stored. + #[clap(long)] + packages_path: Vec, + /// Root directory where packages are stored. + #[clap(long)] + experimental_packages_path: Vec, + /// Root directory where prebuilt packages binary will be saved. + #[clap(long)] + prebuilt_packages_file_dir: PathBuf, + /// Root directory where the Rust file to access prebuilt packages will be saved. + #[clap(long)] + prebuilt_packages_rust_dir: PathBuf, + /// If true, uses local aptos-framework from aptos-core. + #[clap(long)] + use_local_std: bool, + /// Experiments for compiler optimization. + #[clap(long, num_args = 1.., value_delimiter = ',')] + experiments: Vec, +} + +/// Recursively traverses a directory to extract paths of all Move packages inside it. +fn visit( + dir: &Path, + config: &PrebuiltPackageConfig, + package_paths: &mut Vec<(PathBuf, PrebuiltPackageConfig)>, +) -> io::Result<()> { + // Package found, do not recurse further. + if dir.join("Move.toml").is_file() { + package_paths.push((dir.to_path_buf(), config.clone())); + return Ok(()); + } + + for entry in fs::read_dir(dir)? { + let entry = entry?; + if entry.file_type()?.is_dir() { + visit(&entry.path(), config, package_paths)?; + } + } + Ok(()) +} + +fn main() -> anyhow::Result<()> { + let args = Args::parse(); + let use_local_std = args.use_local_std; + + if args.packages_path.is_empty() && args.experimental_packages_path.is_empty() { + bail!("At least one path pointing to packages directory should be provided"); + } + let mut all_package_paths = vec![]; + for (package_path, latest_language) in args.packages_path.into_iter().map(|p| (p, false)).chain( + args.experimental_packages_path + .into_iter() + .map(|p| (p, true)), + ) { + let config = + PrebuiltPackageConfig::new(latest_language, use_local_std, args.experiments.clone()); + visit(&package_path, &config, &mut all_package_paths)?; + } + + let output_file = args.prebuilt_packages_rust_dir.join("prebuilt_packages.rs"); + create_prebuilt_packages_bundle( + args.prebuilt_packages_file_dir, + all_package_paths, + output_file, + )?; + Ok(()) +} + +#[test] +fn verify_tool() { + use clap::CommandFactory; + Args::command().debug_assert() +} diff --git a/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/Move.toml b/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/Move.toml new file mode 100644 index 00000000000..b7e04190236 --- /dev/null +++ b/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "experimental_usecases" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../aptos-move/framework/aptos-framework" } +AptosExperimental = { local = "../../../../aptos-move/framework/aptos-experimental" } +AptosToken = { local = "../../../../aptos-move/framework/aptos-token" } +AptosTokenObjects = { local = "../../../../aptos-move/framework/aptos-token-objects" } + +# testing exchanging of constant address works as well. +[addresses] +publisher_address = "0xABCD" diff --git a/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/sources/order_book_example.move b/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/sources/order_book_example.move new file mode 100644 index 00000000000..637e2923c9b --- /dev/null +++ b/testsuite/benchmark-workloads/packages-experimental/experimental_usecases/sources/order_book_example.move @@ -0,0 +1,111 @@ +module 0xABCD::order_book_example { + use std::signer; + use std::error; + use std::option; + use std::vector; + use std::table::{Self, Table}; + use aptos_experimental::order_book_types::{OrderIdType, good_till_cancelled, OrderMatch}; + use aptos_experimental::order_book; + use aptos_experimental::order_book::OrderBook; + + const ENOT_AUTHORIZED: u64 = 1; + // Resource being modified doesn't exist + const EDEX_RESOURCE_NOT_PRESENT: u64 = 2; + + struct Empty has store, copy, drop {} + + struct Dex has key { + order_books: Table>, + } + + // Create the global `Dex`. + // Stored under the module publisher address. + fun init_module(publisher: &signer) { + assert!( + signer::address_of(publisher) == @publisher_address, + ENOT_AUTHORIZED, + ); + + let order_books = table::new(); + for (i in 0..10) { + order_books.add(i, order_book::new_order_book()); + }; + + move_to( + publisher, + Dex { order_books } + ); + } + + + inline fun borrow_order_book_mut(market_id: u32): &mut OrderBook { + assert!(exists(@publisher_address), error::invalid_argument(EDEX_RESOURCE_NOT_PRESENT)); + let dex = borrow_global_mut(@publisher_address); + + if (!dex.order_books.contains(market_id)) { + let order_book = order_book::new_order_book(); + dex.order_books.add(market_id, order_book); + }; + + dex.order_books.borrow_mut(market_id) + } + + public entry fun place_order(market_id: u32, sender: address, order_id: u64, bid_price: u64, volume: u64, is_bid: bool) acquires Dex { + let order_book = borrow_order_book_mut(market_id); + place_order_and_get_matches( + order_book, + sender, // account + aptos_experimental::order_book_types::new_order_id_type(order_id as u128), + bid_price, + volume, + volume, + is_bid, + ); + } + + public entry fun cancel_order(market_id: u32, order_id: u64) acquires Dex { + let order_book = borrow_order_book_mut(market_id); + order_book.cancel_order(@publisher_address, aptos_experimental::order_book_types::new_order_id_type(order_id as u128)); + } + + // Copied from order_book, as it's test_only and not part of public API there. + fun place_order_and_get_matches( + order_book: &mut OrderBook, + account: address, + order_id: OrderIdType, + price: u64, + orig_size: u64, + remaining_size: u64, + is_bid: bool, + ): vector> { + let trigger_condition = option::none(); + let match_results = vector::empty(); + while (remaining_size > 0) { + if (!order_book.is_taker_order(price, is_bid, trigger_condition)) { + order_book.place_maker_order( + order_book::new_single_order_request( + account, + order_id, + option::none(), + price, + orig_size, + remaining_size, + is_bid, + trigger_condition, // trigger_condition + good_till_cancelled(), + Empty {}, // metadata + ) + ); + return match_results; + }; + let match_result = + order_book.get_single_match_for_taker( + price, remaining_size, is_bid + ); + let matched_size = match_result.get_matched_size(); + match_results.push_back(match_result); + remaining_size -= matched_size; + }; + return match_results + } +} diff --git a/testsuite/benchmark-workloads/packages/complex/Move.toml b/testsuite/benchmark-workloads/packages/complex/Move.toml new file mode 100644 index 00000000000..e6c163ae8bf --- /dev/null +++ b/testsuite/benchmark-workloads/packages/complex/Move.toml @@ -0,0 +1,9 @@ +[package] +name = 'complex' +version = '1.0.0' + +[dependencies] +AptosFramework = { local = "../../../../aptos-move/framework/aptos-framework" } + +[addresses] +publisher_address = "0xABCD" diff --git a/testsuite/module-publish/src/packages/complex/sources/liquid_pool/liquidity_pool.move b/testsuite/benchmark-workloads/packages/complex/sources/liquid_pool/liquidity_pool.move similarity index 100% rename from testsuite/module-publish/src/packages/complex/sources/liquid_pool/liquidity_pool.move rename to testsuite/benchmark-workloads/packages/complex/sources/liquid_pool/liquidity_pool.move diff --git a/testsuite/module-publish/src/packages/complex/sources/liquid_pool/liquidity_pool_wrapper.move b/testsuite/benchmark-workloads/packages/complex/sources/liquid_pool/liquidity_pool_wrapper.move similarity index 100% rename from testsuite/module-publish/src/packages/complex/sources/liquid_pool/liquidity_pool_wrapper.move rename to testsuite/benchmark-workloads/packages/complex/sources/liquid_pool/liquidity_pool_wrapper.move diff --git a/testsuite/module-publish/src/packages/complex/sources/smart_table_picture.move b/testsuite/benchmark-workloads/packages/complex/sources/smart_table_picture.move similarity index 100% rename from testsuite/module-publish/src/packages/complex/sources/smart_table_picture.move rename to testsuite/benchmark-workloads/packages/complex/sources/smart_table_picture.move diff --git a/testsuite/module-publish/src/packages/complex/sources/vector_picture.move b/testsuite/benchmark-workloads/packages/complex/sources/vector_picture.move similarity index 100% rename from testsuite/module-publish/src/packages/complex/sources/vector_picture.move rename to testsuite/benchmark-workloads/packages/complex/sources/vector_picture.move diff --git a/testsuite/benchmark-workloads/packages/framework_usecases/Move.toml b/testsuite/benchmark-workloads/packages/framework_usecases/Move.toml new file mode 100644 index 00000000000..f02b2d85278 --- /dev/null +++ b/testsuite/benchmark-workloads/packages/framework_usecases/Move.toml @@ -0,0 +1,12 @@ +[package] +name = "framework_usecases" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../aptos-move/framework/aptos-framework" } +AptosToken = { local = "../../../../aptos-move/framework/aptos-token" } +AptosTokenObjects = { local = "../../../../aptos-move/framework/aptos-token-objects" } + +# testing exchanging of constant address works as well. +[addresses] +publisher_address = "0xABCD" diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/aggregator_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/aggregator_example.move similarity index 99% rename from testsuite/module-publish/src/packages/framework_usecases/sources/aggregator_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/aggregator_example.move index 4876b63a3c6..b0cbfa70b74 100644 --- a/testsuite/module-publish/src/packages/framework_usecases/sources/aggregator_example.move +++ b/testsuite/benchmark-workloads/packages/framework_usecases/sources/aggregator_example.move @@ -1,5 +1,3 @@ - - module 0xABCD::aggregator_example { use std::error; use std::signer; diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/coin_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/coin_example.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/coin_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/coin_example.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/fungible_asset_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/fungible_asset_example.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/fungible_asset_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/fungible_asset_example.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/maps_example.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/maps_example.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/objects.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/objects.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/objects.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/objects.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/permissioned_transfer.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/permissioned_transfer.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/permissioned_transfer.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/permissioned_transfer.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/resource_groups_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/resource_groups_example.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/resource_groups_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/resource_groups_example.move diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/token_v1.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/token_v1.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/token_v1.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/token_v1.move diff --git a/testsuite/benchmark-workloads/packages/framework_usecases/sources/transaction_context_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/transaction_context_example.move new file mode 100644 index 00000000000..8684e18b851 --- /dev/null +++ b/testsuite/benchmark-workloads/packages/framework_usecases/sources/transaction_context_example.move @@ -0,0 +1,19 @@ +/// Module for testing monotonically increasing counter native function throughput +module 0xABCD::transaction_context_example { + use aptos_framework::transaction_context; + + /// Test single call to monotonic counter per transaction + public entry fun test_monotonic_counter_single() { + // Call the monotonic counter once + let _counter = transaction_context::monotonically_increasing_counter(); + } + + /// Test multiple calls to monotonic counter per transaction + public entry fun test_monotonic_counter_multiple(count: u64) { + let i = 0; + while (i < count) { + let _counter = transaction_context::monotonically_increasing_counter(); + i = i + 1; + } + } +} diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/vector_example.move b/testsuite/benchmark-workloads/packages/framework_usecases/sources/vector_example.move similarity index 100% rename from testsuite/module-publish/src/packages/framework_usecases/sources/vector_example.move rename to testsuite/benchmark-workloads/packages/framework_usecases/sources/vector_example.move diff --git a/testsuite/benchmark-workloads/packages/locals/Move.toml b/testsuite/benchmark-workloads/packages/locals/Move.toml new file mode 100644 index 00000000000..1ea7359944c --- /dev/null +++ b/testsuite/benchmark-workloads/packages/locals/Move.toml @@ -0,0 +1,9 @@ +[package] +name = 'locals' +version = '1.0.0' + +[dependencies] +MoveStdlib = { local = "../../../../aptos-move/framework/move-stdlib" } + +[addresses] +publisher_address = "0xABCD" diff --git a/testsuite/benchmark-workloads/packages/locals/sources/locals.move b/testsuite/benchmark-workloads/packages/locals/sources/locals.move new file mode 100644 index 00000000000..def530b2501 --- /dev/null +++ b/testsuite/benchmark-workloads/packages/locals/sources/locals.move @@ -0,0 +1,168 @@ +// Copyright Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +module 0xABCD::locals { + struct Data has copy, drop { + a: vector, + b: vector>, + c: C, + d: u128, + } + + struct NestedData< + A: copy + drop, + B: copy + drop, + C: copy + drop, + D: copy + drop, + E: copy + drop, + F: copy + drop, + > has copy, drop { + abc: Data, + def: Data, + } + + fun work_with_many_locals() { + let a = vector[0_u128]; + let b = vector[vector[0_u64]]; + let c = vector[0_u8]; + let d = 120; + let data1 = Data { + a, + b, + c, + d, + }; + let a = vector[0_u8]; + let b = vector[vector[120_u32]]; + let c = false; + let d = 30; + let data2 = Data { + a, + b, + c, + d, + }; + let data3 = data1; + let data4 = data2; + let data5 = NestedData { + abc: data3, + def: data4, + }; + let data6 = NestedData { + abc: data4, + def: data3, + }; + let data7 = NestedData { + abc: data4, + def: data4, + }; + let data8 = NestedData { + abc: data3, + def: data3, + }; + assert!(data7.abc.d == data5.def.d, 777); + assert!(data8.abc.d == data6.def.d, 888); + } + + fun generic_work_with_many_locals< + A: copy + drop, + B: copy + drop, + C: copy + drop, + D: copy + drop, + E: copy + drop, + F: copy + drop, + >() { + let a = vector[]; + let b = vector[vector[]]; + let c = vector[false]; + let d = 40; + let data1 = Data> { + a, + b, + c, + d, + }; + let a = vector[]; + let b = vector[vector[]]; + let c = data1; + let d = 23; + let data2 = Data>> { + a, + b, + c, + d, + }; + let data3 = data1; + let data4 = data2; + let data5 = NestedData { + abc: data3, + def: data4, + }; + let data6 = NestedData { + abc: data4, + def: data3, + }; + let data7 = NestedData { + abc: data4, + def: data4, + }; + let data8 = NestedData { + abc: data3, + def: data3, + }; + assert!(data7.abc.d == data5.def.d, 777); + assert!(data8.abc.d == data6.def.d, 888); + } + + public entry fun benchmark_generic() { + let i = 0; + while (i < 100) { + generic_work_with_many_locals, Data>, bool>(); + generic_work_with_many_locals>, bool, vector, Data>, bool>(); + generic_work_with_many_locals, Data>, bool>(); + generic_work_with_many_locals, Data>, bool, u32, bool>(); + + generic_work_with_many_locals, Data>, bool>(); + generic_work_with_many_locals, bool, Data>>(); + generic_work_with_many_locals>, u32, u32, bool, vector, Data>>(); + generic_work_with_many_locals>, bool, vector, Data>, bool>(); + + generic_work_with_many_locals>, u8, vector>, vector, Data>, bool>(); + generic_work_with_many_locals>, Data>, vector>, bool, vector, Data>, bool>(); + generic_work_with_many_locals, Data>, bool>(); + generic_work_with_many_locals, vector, Data>, bool>(); + + generic_work_with_many_locals, bool, bool>, bool, bool>, bool, vector, Data>, bool>(); + generic_work_with_many_locals, Data>>, bool>(); + generic_work_with_many_locals, bool>, u32>>, Data>, bool>(); + generic_work_with_many_locals>>>, bool, vector, Data>>, Data>(); + i = i + 1; + } + } + + public entry fun benchmark() { + let i = 0; + while (i < 100) { + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + work_with_many_locals(); + i = i + 1; + } + } +} diff --git a/testsuite/benchmark-workloads/packages/simple/Move.toml b/testsuite/benchmark-workloads/packages/simple/Move.toml new file mode 100644 index 00000000000..6fdd820c5c8 --- /dev/null +++ b/testsuite/benchmark-workloads/packages/simple/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "simple" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../aptos-move/framework/aptos-framework" } diff --git a/testsuite/module-publish/src/packages/simple/scripts/main.move b/testsuite/benchmark-workloads/packages/simple/scripts/main.move similarity index 100% rename from testsuite/module-publish/src/packages/simple/scripts/main.move rename to testsuite/benchmark-workloads/packages/simple/scripts/main.move diff --git a/testsuite/module-publish/src/packages/simple/sources/Simple.move b/testsuite/benchmark-workloads/packages/simple/sources/Simple.move similarity index 94% rename from testsuite/module-publish/src/packages/simple/sources/Simple.move rename to testsuite/benchmark-workloads/packages/simple/sources/Simple.move index 359962f78d1..12b62e31bc5 100644 --- a/testsuite/module-publish/src/packages/simple/sources/Simple.move +++ b/testsuite/benchmark-workloads/packages/simple/sources/Simple.move @@ -1,12 +1,5 @@ // This is a generic module used by the transaction generator to produce -// multiple module to publish and use. -// The idea is that by running `cargo run --package module-publish` -// in `testsuite/module-publish` -// a rust file (`generic_module.rs`) gets generated in -// `crates/transaction-emitter-lib/src/transaction_generator/publishing` which -// contains a `CompiledModule` for the module below. -// A helper file is provided to manipulate that file to generate -// multiple, publishable module. +// multiple modules to publish and use. module 0xABCD::simple { use std::error; use std::bcs; @@ -108,6 +101,56 @@ module 0xABCD::simple { } } + public entry fun fibonacci_recursive(_s: &signer, n: u64) { + fib_rec(n); + } + + public entry fun fibonacci_tail_recursive(_s: &signer, n: u64) { + fib_tail_rec(n, 0, 1); + } + + public entry fun fibonacci_iterative(_s: &signer, n: u64) { + fib_iter(n); + } + + /// Computes the n-th fibonacci number using a simple recursive algorithm. + fun fib_rec(n: u64): u64 { + if (n <= 1) { + n + } else { + fib_rec(n - 1) + fib_rec(n - 2) + } + } + + /// Computes the n-th fibonacci number using a tail-recursive algorithm. + fun fib_tail_rec(n: u64, a: u64, b: u64): u64 { + if (n == 0) { + a + } else { + fib_tail_rec(n - 1, b, a + b) + } + } + + /// Computes the n-th fibonacci number using an iterative algorithm. + fun fib_iter(n: u64): u64 { + if (n <= 1) { + return n; + }; + + let a = 0; + let b = 1; + + let i = 2; + while (i <= n) { + let temp = a + b; + a = b; + b = temp; + i += 1; + }; + + b + } + // Counter // This is a constant to change to check versioning of the module published. // In a simple way this can be used as a verion info, and incremented by 1 diff --git a/testsuite/forge-cli/Cargo.toml b/testsuite/forge-cli/Cargo.toml index f948aaba0f0..1450d8ffdad 100644 --- a/testsuite/forge-cli/Cargo.toml +++ b/testsuite/forge-cli/Cargo.toml @@ -38,10 +38,7 @@ tokio = { workspace = true } url = { workspace = true } [target.'cfg(unix)'.dependencies] -jemallocator = { version = "0.5.0", features = [ - "profiling", - "unprefixed_malloc_on_supported_platforms", -] } +jemallocator = { workspace = true } [[bin]] name = "forge" diff --git a/testsuite/forge-cli/src/main.rs b/testsuite/forge-cli/src/main.rs index 9f5b02e5355..80564cb28fc 100644 --- a/testsuite/forge-cli/src/main.rs +++ b/testsuite/forge-cli/src/main.rs @@ -11,7 +11,7 @@ use clap::{Parser, Subcommand}; use futures::{future, FutureExt}; use rand::{rngs::ThreadRng, seq::SliceRandom, Rng}; use serde_json::{json, Value}; -use std::{self, env, num::NonZeroUsize, process, time::Duration}; +use std::{self, num::NonZeroUsize, process, time::Duration}; use sugars::{boxed, hmap}; use suites::{ dag::get_dag_test, @@ -28,7 +28,6 @@ use suites::{ }, }; use tokio::runtime::Runtime; -use url::Url; mod suites; @@ -56,8 +55,6 @@ struct Args { default_value = "land_blocking" )] suite: String, - #[clap(long, num_args = 0..)] - changelog: Option>, // subcommand groups #[clap(subcommand)] @@ -288,7 +285,7 @@ fn main() -> Result<()> { duration, LocalFactory::from_workspace(swarm_dir)?, ); - run_forge_with_changelog(forge, &args.options, args.changelog.clone()) + run_forge(forge, &args.options) }, TestCommand::K8sSwarm(k8s) => { if let Some(move_modules_dir) = &k8s.move_modules_dir { @@ -330,7 +327,7 @@ fn main() -> Result<()> { k8s.deployer_profile.clone(), )?, ); - run_forge_with_changelog(forge, &args.options, args.changelog) + run_forge(forge, &args.options) }, } }, @@ -416,11 +413,7 @@ fn main() -> Result<()> { } } -pub fn run_forge_with_changelog( - forge: Forge, - options: &Options, - optional_changelog: Option>, -) -> Result<()> { +pub fn run_forge(forge: Forge, options: &Options) -> Result<()> { if options.list { forge.list()?; @@ -428,68 +421,17 @@ pub fn run_forge_with_changelog( } let forge_result = forge.run(); - let report = forge_result.map_err(|e| { + let summary = forge_result.map_err(|e| { eprintln!("Failed to run tests:\n{}", e); anyhow::anyhow!(e) })?; - if let Some(changelog) = optional_changelog { - if changelog.len() != 2 { - println!("Use: changelog "); - process::exit(1); - } - let to_commit = changelog[1].clone(); - let from_commit = Some(changelog[0].clone()); - send_changelog_message(&report.to_string(), &from_commit, &to_commit); - } - Ok(()) -} - -pub fn send_changelog_message(perf_msg: &str, from_commit: &Option, to_commit: &str) { - println!( - "Generating changelog from {:?} to {}", - from_commit, to_commit - ); - let changelog = get_changelog(from_commit.as_ref(), to_commit); - let msg = format!("{}\n\n{}", changelog, perf_msg); - let slack_url: Option = env::var("SLACK_URL") - .map(|u| u.parse().expect("Failed to parse SLACK_URL")) - .ok(); - if let Some(ref slack_url) = slack_url { - let slack_client = SlackClient::new(); - if let Err(e) = slack_client.send_message(slack_url, &msg) { - println!("Failed to send slack message: {}", e); - } - } -} - -fn get_changelog(prev_commit: Option<&String>, upstream_commit: &str) -> String { - let github_client = GitHub::new(); - let commits = github_client.get_commits("aptos-labs/aptos-core", upstream_commit); - match commits { - Err(e) => { - println!("Failed to get github commits: {:?}", e); - format!("*Revision upstream_{}*", upstream_commit) - }, - Ok(commits) => { - let mut msg = format!("*Revision {}*", upstream_commit); - for commit in commits { - if let Some(prev_commit) = prev_commit { - if commit.sha.starts_with(prev_commit) { - break; - } - } - let commit_lines: Vec<_> = commit.commit.message.split('\n').collect(); - let commit_head = commit_lines[0]; - let commit_head = commit_head.replace("[breaking]", "*[breaking]*"); - let short_sha = &commit.sha[..6]; - let email_parts: Vec<_> = commit.commit.author.email.split('@').collect(); - let author = email_parts[0]; - let line = format!("\n>\u{2022} {} _{}_ {}", short_sha, author, commit_head); - msg.push_str(&line); - } - msg - }, + if summary.success() { + Ok(()) + } else if summary.is_soft_failure() { + process::exit(51); + } else { + process::exit(1); } } @@ -526,7 +468,7 @@ fn get_test_suite( boxed!(|| get_state_sync_test(test_name)), boxed!(|| get_dag_test(test_name, duration, test_cmd)), boxed!(|| get_indexer_test(test_name)), - boxed!(|| get_ungrouped_test(test_name)), + boxed!(|| get_ungrouped_test(test_name, duration)), ]; for named_suite in named_test_suites.iter() { diff --git a/testsuite/forge-cli/src/suites/dag.rs b/testsuite/forge-cli/src/suites/dag.rs index b9554a8eaeb..7f1fddedec8 100644 --- a/testsuite/forge-cli/src/suites/dag.rs +++ b/testsuite/forge-cli/src/suites/dag.rs @@ -119,6 +119,14 @@ fn dag_realistic_env_max_load_test( config_v5.block_gas_limit_type = BlockGasLimitType::NoLimit; config_v5.transaction_shuffler_type = TransactionShufflerType::default_for_genesis(); } + OnChainExecutionConfig::V6(config_v6) => { + config_v6.block_gas_limit_type = BlockGasLimitType::NoLimit; + config_v6.transaction_shuffler_type = TransactionShufflerType::default_for_genesis(); + } + OnChainExecutionConfig::V7(config_v7) => { + config_v7.block_gas_limit_type = BlockGasLimitType::NoLimit; + config_v7.transaction_shuffler_type = TransactionShufflerType::default_for_genesis(); + } } helm_values["chain"]["on_chain_execution_config"] = serde_yaml::to_value(on_chain_execution_config).expect("must serialize"); @@ -223,6 +231,12 @@ fn dag_reconfig_enable_test() -> ForgeConfig { OnChainExecutionConfig::V5(config_v5) => { config_v5.block_gas_limit_type = BlockGasLimitType::NoLimit; } + OnChainExecutionConfig::V6(config_v6) => { + config_v6.block_gas_limit_type = BlockGasLimitType::NoLimit; + } + OnChainExecutionConfig::V7(config_v7) => { + config_v7.block_gas_limit_type = BlockGasLimitType::NoLimit; + } } helm_values["chain"]["on_chain_execution_config"] = serde_yaml::to_value(on_chain_execution_config).expect("must serialize"); diff --git a/testsuite/forge-cli/src/suites/pfn.rs b/testsuite/forge-cli/src/suites/pfn.rs index 81f72169806..eb792b7c7f7 100644 --- a/testsuite/forge-cli/src/suites/pfn.rs +++ b/testsuite/forge-cli/src/suites/pfn.rs @@ -56,7 +56,9 @@ fn pfn_const_tps( 7, add_cpu_chaos, add_network_emulation, - None, + Some(Arc::new(|config: &mut NodeConfig, _| { + config.indexer_db_config.enable_event = true; + })), )) .with_genesis_helm_config_fn(Arc::new(move |helm_values| { helm_values["chain"]["epoch_duration_secs"] = epoch_duration_secs.into(); diff --git a/testsuite/forge-cli/src/suites/realistic_environment.rs b/testsuite/forge-cli/src/suites/realistic_environment.rs index babfc18ee22..376cfca2115 100644 --- a/testsuite/forge-cli/src/suites/realistic_environment.rs +++ b/testsuite/forge-cli/src/suites/realistic_environment.rs @@ -41,6 +41,7 @@ pub(crate) fn get_realistic_env_test( "realistic_env_max_load_large" => realistic_env_max_load_test(duration, test_cmd, 20, 10), "realistic_env_load_sweep" => realistic_env_load_sweep_test(), "realistic_env_workload_sweep" => realistic_env_workload_sweep_test(), + "realistic_env_orderbook_workload_sweep" => realistic_env_orderbook_workload_sweep_bench(), "realistic_env_fairness_workload_sweep" => realistic_env_fairness_workload_sweep(), "realistic_env_graceful_workload_sweep" => realistic_env_graceful_workload_sweep(), "realistic_env_graceful_overload" => realistic_env_graceful_overload(duration), @@ -142,6 +143,82 @@ pub(crate) fn realistic_env_workload_sweep_test() -> ForgeConfig { SuccessCriteria::new(min_tps) .add_max_expired_tps(max_expired as f64) .add_max_failed_submission_tps(200.0) + .add_no_restarts() + .add_latency_breakdown_threshold(LatencyBreakdownThreshold::new_strict(vec![ + ( + LatencyBreakdownSlice::MempoolToBlockCreation, + mempool_to_block_creation, + ), + ( + LatencyBreakdownSlice::ConsensusProposalToOrdered, + proposal_to_ordered, + ), + ( + LatencyBreakdownSlice::ConsensusOrderedToCommit, + ordered_to_commit, + ), + ])) + }, + ) + .collect(), + background_traffic: background_traffic_for_sweep(5), + }) +} + +pub(crate) fn realistic_env_orderbook_workload_sweep_bench() -> ForgeConfig { + realistic_env_sweep_wrap(7, 3, LoadVsPerfBenchmark { + test: Box::new(PerformanceBenchmark), + workloads: Workloads::TRANSACTIONS(vec![ + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedMatches25Pct1Market, + 1000, + ), + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedMatches25Pct50Markets, + 5000, + ), + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedMatches80Pct1Market, + 1000, + ), + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedMatches80Pct50Markets, + 5000, + ), + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct1Market, + 1000, + ), + TransactionWorkload::new( + TransactionTypeArg::OrderBookBalancedSizeSkewed80Pct50Markets, + 5000, + ), + TransactionWorkload::new(TransactionTypeArg::OrderBookNoMatches1Market, 1000), + TransactionWorkload::new(TransactionTypeArg::OrderBookNoMatches50Markets, 5000), + ]), + criteria: [ + (350, 100, 0.3 + 1.0, 0.4, 0.2), + (1700, 100, 0.3 + 1.0, 0.4, 0.5), + (350, 300, 0.3 + 1.0, 0.4, 0.2), + (2000, 500, 0.3 + 1.0, 0.4, 0.5), + (320, 5, 0.3 + 1.0, 0.4, 0.25), + (1500, 5, 0.3 + 1.5, 0.4, 0.5), + (320, 100, 0.3 + 1.0, 0.4, 0.2), + (1700, 100, 0.3 + 1.0, 0.4, 0.7), + ] + .into_iter() + .map( + |( + min_tps, + max_expired, + mempool_to_block_creation, + proposal_to_ordered, + ordered_to_commit, + )| { + SuccessCriteria::new(min_tps) + .add_max_expired_tps(max_expired as f64) + .add_max_failed_submission_tps(200.0) + .add_no_restarts() .add_latency_breakdown_threshold(LatencyBreakdownThreshold::new_strict(vec![ ( LatencyBreakdownSlice::MempoolToBlockCreation, @@ -253,6 +330,9 @@ pub(crate) fn realistic_env_graceful_overload(duration: Duration) -> ForgeConfig ) .with_validator_override_node_config_fn(Arc::new(|config, _| { config.execution.processed_transactions_detailed_counters = true; + // TODO(georgemitenkov): remove once features are added to default config. + config.execution.layout_caches_enabled = true; + config.execution.async_runtime_checks = true; })) .with_genesis_helm_config_fn(Arc::new(|helm_values| { helm_values["chain"]["epoch_duration_secs"] = 300.into(); @@ -268,7 +348,7 @@ pub(crate) fn realistic_env_graceful_overload(duration: Duration) -> ForgeConfig // TODO(ibalajiarun): Investigate the high utilization and adjust accordingly. // Memory starts around 8GB, and grows around 8GB/hr in this test. // Check that we don't use more than final expected memory for more than 20% of the time. - MetricsThreshold::new_gb(8.5 + 8.0 * (duration.as_secs_f64() / 3600.0), 20), + MetricsThreshold::new_gb(16.0 + 8.0 * (duration.as_secs_f64() / 3600.0), 20), )) .add_latency_threshold(10.0, LatencyType::P50) .add_latency_threshold(30.0, LatencyType::P90) @@ -309,15 +389,15 @@ pub(crate) fn realistic_env_max_load_test( MetricsThreshold::new(25.0, 15), // Memory starts around 8GB, and grows around 1.4GB/hr in this test. // Check that we don't use more than final expected memory for more than 20% of the time. - MetricsThreshold::new_gb(8.0 + 1.4 * (duration_secs as f64 / 3600.0), 20), + MetricsThreshold::new_gb(16.0 + 8.0 * (duration_secs as f64 / 3600.0), 20), )) .add_no_restarts() .add_wait_for_catchup_s( // Give at least 60s for catchup, give 10% of the run for longer durations. (duration.as_secs() / 10).max(60), ) - .add_latency_threshold(3.4, LatencyType::P50) - .add_latency_threshold(4.5, LatencyType::P70) + .add_latency_threshold(3.6, LatencyType::P50) + .add_latency_threshold(4.8, LatencyType::P70) .add_chain_progress(StateProgressThreshold { max_non_epoch_no_progress_secs: 15.0, max_epoch_no_progress_secs: 16.0, @@ -335,7 +415,7 @@ pub(crate) fn realistic_env_max_load_test( LatencyBreakdownThreshold::new_with_breach_pct( vec![ // quorum store backpressure is relaxed, so queueing happens here - (LatencyBreakdownSlice::MempoolToBlockCreation, 0.35 + 2.5), + (LatencyBreakdownSlice::MempoolToBlockCreation, 0.35 + 3.25), // can be adjusted down if less backpressure (LatencyBreakdownSlice::ConsensusProposalToOrdered, 0.85), // can be adjusted down if less backpressure @@ -347,7 +427,7 @@ pub(crate) fn realistic_env_max_load_test( } // Create the test - let mempool_backlog = if ha_proxy { 30000 } else { 40000 }; + let mempool_backlog = if ha_proxy { 28000 } else { 38000 }; ForgeConfig::default() .with_initial_validator_count(NonZeroUsize::new(num_validators).unwrap()) .with_initial_fullnode_count(num_fullnodes) @@ -382,10 +462,13 @@ pub(crate) fn realistic_env_max_load_test( // Increase the consensus observer fallback thresholds config .consensus_observer - .observer_fallback_progress_threshold_ms = 20_000; // 20 seconds + .observer_fallback_progress_threshold_ms = 30_000; // 30 seconds config .consensus_observer - .observer_fallback_sync_lag_threshold_ms = 30_000; // 30 seconds + .observer_fallback_sync_lag_threshold_ms = 45_000; // 45 seconds + // TODO(georgemitenkov): remove once features are added to default config. + config.execution.layout_caches_enabled = true; + config.execution.async_runtime_checks = true; })) // First start higher gas-fee traffic, to not cause issues with TxnEmitter setup - account creation .with_emit_job( @@ -441,6 +524,10 @@ pub(crate) fn realistic_network_tuned_for_throughput_test() -> ForgeConfig { if USE_CRAZY_MACHINES { config.execution.concurrency_level = 48; } + + // TODO(georgemitenkov): remove once features are added to default config. + config.execution.layout_caches_enabled = true; + config.execution.async_runtime_checks = true; })) .with_genesis_helm_config_fn(Arc::new(move |helm_values| { let mut on_chain_execution_config = OnChainExecutionConfig::default_for_genesis(); @@ -468,6 +555,22 @@ pub(crate) fn realistic_network_tuned_for_throughput_test() -> ForgeConfig { user_use_case_spread_factor: 0, }; } + OnChainExecutionConfig::V6(config_v6) => { + config_v6.block_gas_limit_type = BlockGasLimitType::NoLimit; + config_v6.transaction_shuffler_type = TransactionShufflerType::UseCaseAware { + sender_spread_factor: 256, + platform_use_case_spread_factor: 0, + user_use_case_spread_factor: 0, + }; + }, + OnChainExecutionConfig::V7(config_v7) => { + config_v7.block_gas_limit_type = BlockGasLimitType::NoLimit; + config_v7.transaction_shuffler_type = TransactionShufflerType::UseCaseAware { + sender_spread_factor: 256, + platform_use_case_spread_factor: 0, + user_use_case_spread_factor: 0, + }; + } } helm_values["chain"]["on_chain_execution_config"] = serde_yaml::to_value(on_chain_execution_config).expect("must serialize"); diff --git a/testsuite/forge-cli/src/suites/ungrouped.rs b/testsuite/forge-cli/src/suites/ungrouped.rs index 8dcc2528bdd..d9ca5614d92 100644 --- a/testsuite/forge-cli/src/suites/ungrouped.rs +++ b/testsuite/forge-cli/src/suites/ungrouped.rs @@ -23,11 +23,15 @@ use aptos_forge::{ SystemMetricsThreshold, }, AdminContext, AdminTest, AptosContext, AptosTest, EmitJobMode, EmitJobRequest, ForgeConfig, - NetworkContext, NetworkContextSynchronizer, NetworkTest, Test, WorkflowProgress, + NetworkContext, NetworkContextSynchronizer, NetworkTest, NodeResourceOverride, Test, + WorkflowProgress, }; use aptos_logger::info; use aptos_rest_client::Client as RestClient; -use aptos_sdk::move_types::account_address::AccountAddress; +use aptos_sdk::{ + move_types::account_address::AccountAddress, + types::on_chain_config::{OnChainConsensusConfig, OnChainExecutionConfig}, +}; use aptos_testcases::{ self, consensus_reliability_tests::ChangingWorkingQuorumTest, @@ -46,6 +50,7 @@ use aptos_testcases::{ reconfiguration_test::ReconfigurationTest, three_region_simulation_test::ThreeRegionSameCloudSimulationTest, twin_validator_test::TwinValidatorTest, + two_traffics_test::TwoTrafficsTest, validator_join_leave_test::ValidatorJoinLeaveTest, validator_reboot_stress_test::ValidatorRebootStressTest, CompositeNetworkTest, @@ -68,7 +73,7 @@ use std::{ use tokio::{runtime::Runtime, select}; use url::Url; -pub fn get_ungrouped_test(test_name: &str) -> Option { +pub fn get_ungrouped_test(test_name: &str, duration: Duration) -> Option { // Otherwise, check the test name against the ungrouped test suites match test_name { // Consensus @@ -88,6 +93,8 @@ pub fn get_ungrouped_test(test_name: &str) -> Option { "consensus_stress_test" => Some(consensus_stress_test()), // not scheduled on continuous "large_test_only_few_nodes_down" => Some(large_test_only_few_nodes_down()), + // single cluster test + "single_cluster_test" => Some(single_cluster_test(duration, 7, 5)), // System tests "gather_metrics" => Some(gather_metrics()), @@ -416,8 +423,7 @@ fn background_emit_request(high_gas_price: bool) -> EmitJobRequest { pub fn background_traffic_for_sweep(num_cases: usize) -> Option { Some(BackgroundTraffic { traffic: background_emit_request(true), - criteria: std::iter::repeat(9.5) - .take(num_cases) + criteria: std::iter::repeat_n(9.5, num_cases) .map(|min_tps| { SuccessCriteria::new_float(min_tps) .add_max_expired_tps(0.1) @@ -470,6 +476,91 @@ fn load_vs_perf_benchmark() -> ForgeConfig { ) } +pub(crate) fn single_cluster_test( + duration: Duration, + num_validators: usize, + num_fullnodes: usize, +) -> ForgeConfig { + // Determine if this is a long running test + let duration_secs = duration.as_secs(); + let long_running = duration_secs >= 2400; + + // resource override for long_running tests + let resource_override = if long_running { + NodeResourceOverride { + storage_gib: Some(1000), // long running tests need more storage + ..NodeResourceOverride::default() + } + } else { + NodeResourceOverride::default() // no overrides + }; + + let mut success_criteria = SuccessCriteria::new(85) + .add_system_metrics_threshold(SystemMetricsThreshold::new( + // Check that we don't use more than 18 CPU cores for 15% of the time. + MetricsThreshold::new(25.0, 15), + // Memory starts around 8GB, and grows around 1.4GB/hr in this test. + // Check that we don't use more than final expected memory for more than 20% of the time. + MetricsThreshold::new_gb(8.0 + 1.4 * (duration_secs as f64 / 3600.0), 20), + )) + .add_no_restarts() + .add_wait_for_catchup_s( + // Give at least 60s for catchup, give 10% of the run for longer durations. + (duration.as_secs() / 10).max(60), + ) + .add_chain_progress(StateProgressThreshold { + max_non_epoch_no_progress_secs: 15.0, + max_epoch_no_progress_secs: 16.0, + max_non_epoch_round_gap: 4, + max_epoch_round_gap: 4, + }); + + // If the test is short lived, we should verify that there are no fullnode failures + if !long_running { + success_criteria = success_criteria.add_no_fullnode_failures(); + } + + // Create the test + let mempool_backlog = 300; + ForgeConfig::default() + .with_initial_validator_count(NonZeroUsize::new(num_validators).unwrap()) + .with_initial_fullnode_count(num_fullnodes) + .add_network_test(TwoTrafficsTest { + inner_traffic: EmitJobRequest::default() + .mode(EmitJobMode::MaxLoad { mempool_backlog }) + .init_gas_price_multiplier(20), + inner_success_criteria: SuccessCriteria::new(10), + }) + .with_genesis_helm_config_fn(Arc::new(move |helm_values| { + // Have single epoch change in land blocking, and a few on long-running + helm_values["chain"]["epoch_duration_secs"] = + (if long_running { 600 } else { 300 }).into(); + helm_values["chain"]["on_chain_consensus_config"] = + serde_yaml::to_value(OnChainConsensusConfig::default_for_genesis()) + .expect("must serialize"); + helm_values["chain"]["on_chain_execution_config"] = + serde_yaml::to_value(OnChainExecutionConfig::default_for_genesis()) + .expect("must serialize"); + })) + .with_fullnode_override_node_config_fn(Arc::new(|config, _| { + // Increase the consensus observer fallback thresholds + config + .consensus_observer + .observer_fallback_progress_threshold_ms = 30_000; // 30 seconds + config + .consensus_observer + .observer_fallback_sync_lag_threshold_ms = 45_000; // 45 seconds + })) + .with_emit_job( + EmitJobRequest::default() + .mode(EmitJobMode::ConstTps { tps: 10 }) + .gas_price(5 * aptos_global_constants::GAS_UNIT_PRICE), + ) + .with_success_criteria(success_criteria) + .with_validator_resource_override(resource_override) + .with_fullnode_resource_override(resource_override) +} + pub fn mixed_emit_job() -> EmitJobRequest { EmitJobRequest::default() .mode(EmitJobMode::MaxLoad { diff --git a/testsuite/forge-test-runner-template.yaml b/testsuite/forge-test-runner-template.yaml index 15a59774c4f..37c4b84150b 100644 --- a/testsuite/forge-test-runner-template.yaml +++ b/testsuite/forge-test-runner-template.yaml @@ -25,12 +25,9 @@ spec: ulimit -n 1048576 {FORGE_ARGS} resources: - limits: - cpu: 15.5 - memory: 26Gi requests: - cpu: 15 - memory: 26Gi + cpu: 8 + memory: 20G env: - name: FORGE_TRIGGERED_BY value: {FORGE_TRIGGERED_BY} diff --git a/testsuite/forge.py b/testsuite/forge.py index dcf15e3e323..08c7137aa82 100644 --- a/testsuite/forge.py +++ b/testsuite/forge.py @@ -61,6 +61,7 @@ MULTIREGION_KUBECONFIG_DIR = "/etc/multiregion-kubeconfig" MULTIREGION_KUBECONFIG_PATH = f"{MULTIREGION_KUBECONFIG_DIR}/kubeconfig" GAR_REPO_NAME = "us-docker.pkg.dev/aptos-registry/docker" +DEFAULT_FORGE_IMAGE_NAME = "forge" @dataclass @@ -134,6 +135,7 @@ def envoption(name: str, default: Optional[Any] = None) -> Any: class ForgeState(Enum): RUNNING = "RUNNING" PASS = "PASS" + SOFT_FAIL = "SOFT_FAIL" FAIL = "FAIL" SKIP = "SKIP" EMPTY = "EMPTY" @@ -202,12 +204,18 @@ def with_context( ) ) result._end_time = context.time.now() - if result.state not in (ForgeState.PASS, ForgeState.FAIL, ForgeState.SKIP): + if result.state not in ( + ForgeState.PASS, + ForgeState.SOFT_FAIL, + ForgeState.FAIL, + ForgeState.SKIP, + ): raise Exception("Forge result never entered terminal state") if result.output is None: raise Exception("Forge result didnt record output") def set_state(self, state: ForgeState) -> None: + log.info(f"Setting state to {state.value}") self.state = state def set_output(self, output: str) -> None: @@ -238,6 +246,9 @@ def format(self, context: ForgeContext) -> str: def succeeded(self) -> bool: return self.state == ForgeState.PASS + def is_hard_failure(self) -> bool: + return self.state == ForgeState.FAIL + @dataclass class SystemContext: @@ -258,6 +269,7 @@ class ForgeContext: forge_namespace: str forge_args: Sequence[str] + forge_image_name: str forge_image_tag: str image_tag: str upgrade_image_tag: str @@ -343,7 +355,7 @@ def format_report(context: ForgeContext, result: ForgeResult) -> str: debugging_appendix ) else: - if result.state == ForgeState.FAIL: + if result.state in (ForgeState.FAIL, ForgeState.SOFT_FAIL): return "{}\n{}".format(report_text, debugging_appendix) return report_text @@ -532,7 +544,7 @@ def get_axiom_link_for_test_runner_logs( ['k8s.labels.app.kubernetes.io/name'] = "forge" and ['k8s.namespace'] == "{forge_namespace}" """ - logs_url = f"https://app.axiom.co/aptoslabs-hghf/explorer?initForm={urlquote( json.dumps({ 'apl': apl_query, 'queryOptions': apply_axiom_time_filter(time_filter), }) )}" + logs_url = f"https://app.axiom.co/aptoslabs-hghf/explorer?initForm={urlquote(json.dumps({'apl': apl_query, 'queryOptions': apply_axiom_time_filter(time_filter), }))}" return logs_url @@ -553,7 +565,7 @@ def get_axiom_link_for_node_logs( ) """ - logs_url = f"https://app.axiom.co/aptoslabs-hghf/explorer?initForm={urlquote( json.dumps({ 'apl': apl_query, 'queryOptions': apply_axiom_time_filter(time_filter), }) )}" + logs_url = f"https://app.axiom.co/aptoslabs-hghf/explorer?initForm={urlquote(json.dumps({'apl': apl_query, 'queryOptions': apply_axiom_time_filter(time_filter), }))}" return logs_url @@ -663,8 +675,10 @@ def format_comment(context: ForgeContext, result: ForgeResult) -> str: if result.state == ForgeState.PASS: forge_comment_header = f"### :white_check_mark: Forge suite `{context.forge_test_suite}` success on {get_testsuite_images(context)}" + elif result.state == ForgeState.SOFT_FAIL: + forge_comment_header = f"### :heavy_exclamation_mark: Forge suite `{context.forge_test_suite}` soft failure on {get_testsuite_images(context)}" elif result.state == ForgeState.FAIL: - forge_comment_header = f"### :x: Forge suite `{context.forge_test_suite}` failure on {get_testsuite_images(context)}" + forge_comment_header = f"### :x: Forge suite `{context.forge_test_suite}` hard failure on {get_testsuite_images(context)}" elif result.state == ForgeState.SKIP: forge_comment_header = f"### :thought_balloon: Forge suite `{context.forge_test_suite}` preempted on {get_testsuite_images(context)}" else: @@ -849,10 +863,11 @@ def run(self, context: ForgeContext) -> ForgeResult: if context.cloud == Cloud.AWS: forge_image_full = f"{context.aws_account_num}.dkr.ecr.{context.aws_region}.amazonaws.com/{ECR_REPO_PREFIX}/forge:{context.forge_image_tag}" validator_node_selector = "eks.amazonaws.com/nodegroup: validators" - elif ( - context.cloud == Cloud.GCP - ): # the GCP project for images is separate than the cluster - forge_image_full = f"{GAR_REPO_NAME}/forge:{context.forge_image_tag}" + elif context.cloud == Cloud.GCP: + # the GCP project for images is separate from the cluster + forge_image_full = ( + f"{GAR_REPO_NAME}/{context.forge_image_name}:{context.forge_image_tag}" + ) validator_node_selector = "" # no selector # TODO: also no NAP node selector yet # TODO: also registries need to be set up such that the default compute service account can access it: $PROJECT_ID-compute@developer.gserviceaccount.com @@ -966,7 +981,25 @@ def run(self, context: ForgeContext) -> ForgeResult: ) ) else: - state = ForgeState.FAIL + exit_code = context.shell.run( + [ + "kubectl", + "--kubeconfig", + context.forge_cluster.kubeconf, + "get", + "pod", + "-n", + "default", + forge_pod_name, + "-o", + "jsonpath={.status.containerStatuses[*].state.terminated.exitCode}", + ] + ).output.decode() + log.info(f"Forge runner exit code: {exit_code}") + if exit_code == "51": + state = ForgeState.SOFT_FAIL + else: + state = ForgeState.FAIL attempts -= 1 if attempts <= 0: @@ -1373,6 +1406,7 @@ def seeded_random_choice(namespace: str, cluster_names: Sequence[str]) -> str: @envoption("FORGE_ENABLE_FAILPOINTS") @envoption("FORGE_ENABLE_PERFORMANCE") @envoption("FORGE_RUNNER_DURATION_SECS", "300") +@envoption("FORGE_IMAGE_NAME") @envoption("FORGE_IMAGE_TAG") @envoption("FORGE_RETAIN_DEBUG_LOGS", "false") @envoption("FORGE_JUNIT_XML_PATH") @@ -1384,6 +1418,7 @@ def seeded_random_choice(namespace: str, cluster_names: Sequence[str]) -> str: @envoption("GITHUB_ACTIONS", "false") @click.option("--balance-clusters", is_flag=True) @envoption("FORGE_BLOCKING", "true") +@envoption("FORGE_CONTINUOUS_TEST_MODE", "false") @envoption("GITHUB_SERVER_URL") @envoption("GITHUB_REPOSITORY") @envoption("GITHUB_RUN_ID") @@ -1420,6 +1455,7 @@ def test( forge_deployer_profile: Optional[str], forge_test_suite: str, forge_runner_duration_secs: str, + forge_image_name: Optional[str], forge_image_tag: Optional[str], forge_retain_debug_logs: str, forge_junit_xml_path: Optional[str], @@ -1430,6 +1466,7 @@ def test( github_actions: str, balance_clusters: bool, forge_blocking: Optional[str], + forge_continuous_test_mode: str, github_server_url: Optional[str], github_repository: Optional[str], github_run_id: Optional[str], @@ -1589,6 +1626,7 @@ def test( image_tag = image_tag or second_latest_image forge_image_tag = forge_image_tag or default_latest_image upgrade_image_tag = upgrade_image_tag or default_latest_image + forge_image_name = DEFAULT_FORGE_IMAGE_NAME else: # All other tests use just one image tag # Only try finding exactly 1 image @@ -1601,8 +1639,16 @@ def test( cloud=cloud_enum, )[0] + forge_image_name = forge_image_name or DEFAULT_FORGE_IMAGE_NAME + if forge_image_name == DEFAULT_FORGE_IMAGE_NAME: + forge_image_tag = forge_image_tag or default_latest_image + else: + latest_image_tag_for_forge_image_with_name = "main" + forge_image_tag = ( + forge_image_tag or latest_image_tag_for_forge_image_with_name + ) + image_tag = image_tag or default_latest_image - forge_image_tag = forge_image_tag or default_latest_image upgrade_image_tag = upgrade_image_tag or default_latest_image image_tag, upgrade_image_tag = ensure_provided_image_tags_has_profile_or_features( @@ -1615,7 +1661,11 @@ def test( assert image_tag is not None, "Image tag is required" assert forge_image_tag is not None, "Forge image tag is required" assert upgrade_image_tag is not None, "Upgrade image tag is required" + assert forge_image_name is not None, "Forge image name is required" + log.info( + f"Using image name {forge_image_name} and tag {forge_image_tag} for forge runner" + ) log.info("Using the following image tags:") log.info(f"\tforge: {forge_image_tag}") log.info(f"\tswarm: {image_tag}") @@ -1665,6 +1715,7 @@ def test( aws_account_num=aws_account_num, aws_region=aws_region, gcp_zone=gcp_zone, + forge_image_name=forge_image_name, forge_image_tag=forge_image_tag, image_tag=image_tag, upgrade_image_tag=upgrade_image_tag, @@ -1703,6 +1754,11 @@ def test( try: forge_runner = forge_runner_mapping[forge_runner_mode]() + + # For debug! if forge_runner_duration_secs is 0, then just quit + if forge_runner_duration_secs == "0": + raise SystemExit(0) + result = forge_runner.run(forge_context) outputs = [] @@ -1725,7 +1781,14 @@ def test( log.info(result.format(forge_context)) - if not result.succeeded() and forge_blocking == "true": + # Exit with error if required based on test result and mode + if ( + forge_blocking == "true" + and forge_continuous_test_mode == "false" + and not result.succeeded() + ): + raise SystemExit(1) + if forge_continuous_test_mode == "true" and result.is_hard_failure(): raise SystemExit(1) except Exception as e: diff --git a/testsuite/forge/src/backend/k8s/cluster_helper.rs b/testsuite/forge/src/backend/k8s/cluster_helper.rs index feb368c5728..8999196a0cb 100644 --- a/testsuite/forge/src/backend/k8s/cluster_helper.rs +++ b/testsuite/forge/src/backend/k8s/cluster_helper.rs @@ -405,7 +405,7 @@ pub async fn uninstall_testnet_resources(kube_namespace: String) -> Result<()> { pub fn generate_new_era() -> String { let mut rng = rand::thread_rng(); - let r: u32 = rng.gen(); + let r: u32 = rng.r#gen(); format!("forge{:08x}", r) } diff --git a/testsuite/forge/src/backend/k8s/prometheus.rs b/testsuite/forge/src/backend/k8s/prometheus.rs index 7aed5be1c07..5f073f1cf50 100644 --- a/testsuite/forge/src/backend/k8s/prometheus.rs +++ b/testsuite/forge/src/backend/k8s/prometheus.rs @@ -263,14 +263,16 @@ mod tests { async fn test_create_client_env() { let secret_api = Arc::new(MockK8sResourceApi::new()); - env::set_var("PROMETHEUS_URL", "http://prometheus.site"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::set_var("PROMETHEUS_URL", "http://prometheus.site") }; // this is the worst case and will default to local (and not panic) create_prometheus_client_from_environment(secret_api.clone()) .await .unwrap(); - env::set_var("PROMETHEUS_TOKEN", "token"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::set_var("PROMETHEUS_TOKEN", "token") }; // this should use the envs create_prometheus_client_from_environment(secret_api) @@ -278,8 +280,10 @@ mod tests { .unwrap(); // cleanup - env::remove_var("PROMETHEUS_URL"); - env::remove_var("PROMETHEUS_TOKEN"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::remove_var("PROMETHEUS_URL") }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { env::remove_var("PROMETHEUS_TOKEN") }; } #[tokio::test] diff --git a/testsuite/forge/src/backend/k8s/swarm.rs b/testsuite/forge/src/backend/k8s/swarm.rs index 5550462d945..96ccb71f815 100644 --- a/testsuite/forge/src/backend/k8s/swarm.rs +++ b/testsuite/forge/src/backend/k8s/swarm.rs @@ -733,7 +733,7 @@ trait ChaosExperimentOps { async fn list_stress_chaos(&self) -> Result>; async fn ensure_chaos_experiments_active(&self) -> Result<()> { - let timeout_duration = Duration::from_secs(600); // 10 minutes + let timeout_duration = Duration::from_secs(1800); // 30 minutes let polling_interval = Duration::from_secs(10); tokio::time::timeout(timeout_duration, async { diff --git a/testsuite/forge/src/backend/k8s_deployer/constants.rs b/testsuite/forge/src/backend/k8s_deployer/constants.rs index 0347e132e51..71219603a10 100644 --- a/testsuite/forge/src/backend/k8s_deployer/constants.rs +++ b/testsuite/forge/src/backend/k8s_deployer/constants.rs @@ -10,7 +10,7 @@ pub const INDEXER_GRPC_DOCKER_IMAGE_REPO: &str = "us-docker.pkg.dev/aptos-registry/docker/indexer-grpc"; /// The version of the forge deployer image to use. -pub const DEFAULT_FORGE_DEPLOYER_IMAGE_TAG: &str = "f5937ed393eb5214997d1cae0da75d2392cdbc70"; // default to the latest stable build from the main branch +pub const DEFAULT_FORGE_DEPLOYER_IMAGE_TAG: &str = "a5a8bb0bc90998a874c6c2e0f8b9ae4feffe4675"; // default to the latest stable build from the main branch (2025-11-04) /// This is the service account name that the deployer will use to deploy the forge components. It may require extra permissions and additonal setup pub const FORGE_DEPLOYER_SERVICE_ACCOUNT_NAME: &str = "forge"; diff --git a/testsuite/forge/src/config.rs b/testsuite/forge/src/config.rs index 82135446878..deae999da40 100644 --- a/testsuite/forge/src/config.rs +++ b/testsuite/forge/src/config.rs @@ -6,7 +6,10 @@ use crate::{ success_criteria::{MetricsThreshold, SuccessCriteria, SystemMetricsThreshold}, *, }; -use aptos_config::config::{NodeConfig, OverrideNodeConfig}; +use aptos_config::config::{ + ExecutionBackpressureGasLimitConfig, ExecutionBackpressureTxnLimitConfig, NodeConfig, + OverrideNodeConfig, +}; use aptos_framework::ReleaseBundle; use std::{num::NonZeroUsize, sync::Arc}; @@ -239,13 +242,22 @@ impl ForgeConfig { helm_values["validator"]["config"]["indexer_db_config"]["enable_event"] = true.into(); helm_values["fullnode"]["config"]["indexer_db_config"]["enable_event"] = true.into(); - // enable optqs - helm_values["validator"]["config"]["consensus"]["quorum_store"] - ["enable_opt_quorum_store"] = true.into(); - // override consensus observer refresh latency helm_values["fullnode"]["config"]["consensus_observer"] ["subscription_peer_change_interval_ms"] = 5_000.into(); + + // enable opt proposal + helm_values["validator"]["config"]["consensus"]["enable_optimistic_proposal_tx"] = + true.into(); + + let mut txn_limit_backpressure = ExecutionBackpressureTxnLimitConfig::default(); + txn_limit_backpressure.lookback_config.target_block_time_ms = 63; + let mut gas_limit_backpressure = ExecutionBackpressureGasLimitConfig::default(); + gas_limit_backpressure.lookback_config.target_block_time_ms = 63; + helm_values["validator"]["config"]["consensus"]["execution_backpressure"] + ["txn_limit"] = serde_yaml::to_value(&txn_limit_backpressure).unwrap(); + helm_values["validator"]["config"]["consensus"]["execution_backpressure"] + ["gas_limit"] = serde_yaml::to_value(&gas_limit_backpressure).unwrap(); })) } diff --git a/testsuite/forge/src/interface/aptos.rs b/testsuite/forge/src/interface/aptos.rs index abd87690e47..2001644f250 100644 --- a/testsuite/forge/src/interface/aptos.rs +++ b/testsuite/forge/src/interface/aptos.rs @@ -137,7 +137,7 @@ impl AptosPublicInfo { rest_api_url, chain_id, root_account, - rng: ::rand::rngs::StdRng::from_seed(OsRng.gen()), + rng: ::rand::rngs::StdRng::from_seed(OsRng.r#gen()), } } diff --git a/testsuite/forge/src/interface/prometheus_metrics.rs b/testsuite/forge/src/interface/prometheus_metrics.rs index 5abe73ef0ae..6b0c5b9db18 100644 --- a/testsuite/forge/src/interface/prometheus_metrics.rs +++ b/testsuite/forge/src/interface/prometheus_metrics.rs @@ -161,7 +161,7 @@ impl LatencyBreakdown { } pub async fn fetch_latency_breakdown( - swarm: Arc>>, + swarm: Arc>>, start_time: u64, end_time: u64, ) -> anyhow::Result { diff --git a/testsuite/forge/src/observer/junit.rs b/testsuite/forge/src/observer/junit.rs index 30ddce90db6..1d0a07dd977 100644 --- a/testsuite/forge/src/observer/junit.rs +++ b/testsuite/forge/src/observer/junit.rs @@ -48,8 +48,10 @@ impl TestObserver for JunitTestObserver { let mut suite = TestSuite::new(self.name.clone()); for (test_name, result) in self.results.lock().unwrap().iter() { let status = match result { - TestResult::Ok => quick_junit::TestCaseStatus::success(), - TestResult::FailedWithMsg(msg) => { + TestResult::Successful => quick_junit::TestCaseStatus::success(), + TestResult::HardFailure(msg) + | TestResult::InfraFailure(msg) + | TestResult::SoftFailure(msg) => { // Not 100% sure what the difference between failure and error is. let mut status = quick_junit::TestCaseStatus::non_success(NonSuccessKind::Failure); diff --git a/testsuite/forge/src/result.rs b/testsuite/forge/src/result.rs index 0c96d2d1f1d..dabd1df847e 100644 --- a/testsuite/forge/src/result.rs +++ b/testsuite/forge/src/result.rs @@ -12,15 +12,19 @@ use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; #[derive(Debug, Clone)] pub enum TestResult { - Ok, - FailedWithMsg(String), + Successful, + SoftFailure(String), + HardFailure(String), + InfraFailure(String), } impl Display for TestResult { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { - TestResult::Ok => write!(f, "Test Ok"), - TestResult::FailedWithMsg(msg) => write!(f, "Test Failed: {}", msg), + TestResult::Successful => write!(f, "Test Ok"), + TestResult::SoftFailure(msg) => write!(f, "Test Metrics Violation: {}", msg), + TestResult::HardFailure(msg) => write!(f, "Test Failed: {}", msg), + TestResult::InfraFailure(msg) => write!(f, "Failed due to infrastructure: {}", msg), } } } @@ -36,6 +40,7 @@ pub struct TestSummary { total: usize, filtered_out: usize, passed: usize, + soft_failure: Vec, failed: Vec, observers: Vec>, } @@ -47,6 +52,7 @@ impl TestSummary { total, filtered_out, passed: 0, + soft_failure: Vec::new(), failed: Vec::new(), observers: Vec::new(), } @@ -58,12 +64,21 @@ impl TestSummary { pub fn handle_result(&mut self, details: TestDetails, result: TestResult) -> Result<()> { write!(self.stdout, "test {} ... ", details.name())?; - match result.clone() { - TestResult::Ok => { + match &result { + TestResult::Successful => { self.passed += 1; self.write_ok()?; }, - TestResult::FailedWithMsg(msg) => { + TestResult::SoftFailure(msg) => { + self.soft_failure.push(details.name()); + + writeln!(self.stdout)?; + write!(self.stdout, "Error: {}", msg)?; + writeln!(self.stdout)?; + + self.write_ok()?; + }, + TestResult::HardFailure(msg) | TestResult::InfraFailure(msg) => { self.failed.push(details.name()); self.write_failed()?; writeln!(self.stdout)?; @@ -144,8 +159,9 @@ impl TestSummary { } writeln!( self.stdout, - ". {} passed; {} failed; {} filtered out", + ". {} passed; {} soft failed; {} hard failed; {} filtered out", self.passed, + self.soft_failure.len(), self.failed.len(), self.filtered_out )?; @@ -154,6 +170,10 @@ impl TestSummary { } pub fn success(&self) -> bool { - self.failed.is_empty() + self.failed.is_empty() && self.soft_failure.is_empty() + } + + pub fn is_soft_failure(&self) -> bool { + !self.soft_failure.is_empty() && self.failed.is_empty() } } diff --git a/testsuite/forge/src/runner.rs b/testsuite/forge/src/runner.rs index 5d1ca9e5366..aa85e1e83c7 100644 --- a/testsuite/forge/src/runner.rs +++ b/testsuite/forge/src/runner.rs @@ -7,11 +7,12 @@ use crate::{ config::ForgeConfig, observer::junit::JunitTestObserver, result::{TestResult, TestSummary}, + success_criteria::SuccessCriteriaErrors, AdminContext, AdminTest, AptosContext, AptosTest, CoreContext, Factory, NetworkContext, NetworkContextSynchronizer, NetworkTest, ShouldFail, Test, TestReport, Version, NAMESPACE_CLEANUP_DURATION_BUFFER_SECS, }; -use anyhow::{bail, format_err, Error, Result}; +use anyhow::{format_err, Error, Result}; use aptos_config::config::NodeConfig; use clap::{Parser, ValueEnum}; use rand::{rngs::OsRng, Rng, SeedableRng}; @@ -247,7 +248,7 @@ impl<'cfg, F: Factory> Forge<'cfg, F> { .expect("There has to be at least 1 version") } - pub fn run(&self) -> Result { + pub fn run(&self) -> Result { let test_count = self.filter_tests(&self.tests.all_tests()).count(); let filtered_out = test_count.saturating_sub(self.tests.all_tests().len()); let retain_debug_logs = self.options.retain_debug_logs || self.tests.retain_debug_logs; @@ -277,7 +278,7 @@ impl<'cfg, F: Factory> Forge<'cfg, F> { // The genesis version should always match the initial node version let genesis_version = initial_version.clone(); let runtime = Runtime::new().unwrap(); // TODO: new multithreaded? - let mut rng = ::rand::rngs::StdRng::from_seed(OsRng.gen()); + let mut rng = ::rand::rngs::StdRng::from_seed(OsRng.r#gen()); let mut swarm = runtime.block_on(self.factory.launch_swarm( &mut rng, self.tests.initial_validator_count, @@ -352,11 +353,7 @@ impl<'cfg, F: Factory> Forge<'cfg, F> { summary.write_summary()?; - if summary.success() { - Ok(report) - } else { - bail!("Tests Failed") - } + Ok(summary) } fn filter_tests<'a, T: Test + ?Sized>( @@ -390,15 +387,19 @@ impl<'cfg, F: Factory> Forge<'cfg, F> { fn process_test_result(result: Result<()>) -> TestResult { match result { - Ok(()) => TestResult::Ok, + Ok(()) => TestResult::Successful, Err(e) => { + let test_result = e + .downcast() + .map(|e: SuccessCriteriaErrors| e.into()) + .unwrap_or_else(|e| TestResult::InfraFailure(format!("Error: {:?}", e))); let is_triggerd_by_github_actions = std::env::var("FORGE_TRIGGERED_BY").unwrap_or_default() == "github-actions"; if is_triggerd_by_github_actions { // ::error:: is github specific syntax to set an error on the job that is highlighted as described here https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message - println!("::error::{:?}", e); + println!("::error::{:?}", test_result); } - TestResult::FailedWithMsg(format!("{:?}", e)) + test_result }, } } @@ -416,34 +417,48 @@ mod test { let original_kubernetes_service_host = std::env::var(KUBERNETES_SERVICE_HOST); // Test the default locally - std::env::remove_var(FORGE_RUNNER_MODE); - std::env::remove_var(KUBERNETES_SERVICE_HOST); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var(FORGE_RUNNER_MODE) }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var(KUBERNETES_SERVICE_HOST) }; let default_local_runner_mode = ForgeRunnerMode::try_from_env(); - std::env::remove_var(FORGE_RUNNER_MODE); - std::env::set_var(KUBERNETES_SERVICE_HOST, "1.1.1.1"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var(FORGE_RUNNER_MODE) }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var(KUBERNETES_SERVICE_HOST, "1.1.1.1") }; let default_kubernetes_runner_mode = ForgeRunnerMode::try_from_env(); - std::env::set_var(FORGE_RUNNER_MODE, "local"); - std::env::set_var(KUBERNETES_SERVICE_HOST, "1.1.1.1"); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var(FORGE_RUNNER_MODE, "local") }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var(KUBERNETES_SERVICE_HOST, "1.1.1.1") }; let local_runner_mode = ForgeRunnerMode::try_from_env(); - std::env::set_var(FORGE_RUNNER_MODE, "k8s"); - std::env::remove_var(KUBERNETES_SERVICE_HOST); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var(FORGE_RUNNER_MODE, "k8s") }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var(KUBERNETES_SERVICE_HOST) }; let k8s_runner_mode = ForgeRunnerMode::try_from_env(); - std::env::set_var(FORGE_RUNNER_MODE, "durian"); - std::env::remove_var(KUBERNETES_SERVICE_HOST); + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::set_var(FORGE_RUNNER_MODE, "durian") }; + // TODO: Audit that the environment access only happens in single-threaded code. + unsafe { std::env::remove_var(KUBERNETES_SERVICE_HOST) }; let invalid_runner_mode = ForgeRunnerMode::try_from_env(); // Reset the env variables after running match original_forge_runner_mode { - Ok(mode) => std::env::set_var(FORGE_RUNNER_MODE, mode), - Err(_) => std::env::remove_var(FORGE_RUNNER_MODE), + // TODO: Audit that the environment access only happens in single-threaded code. + Ok(mode) => unsafe { std::env::set_var(FORGE_RUNNER_MODE, mode) }, + // TODO: Audit that the environment access only happens in single-threaded code. + Err(_) => unsafe { std::env::remove_var(FORGE_RUNNER_MODE) }, } match original_kubernetes_service_host { - Ok(service_host) => std::env::set_var(KUBERNETES_SERVICE_HOST, service_host), - Err(_) => std::env::remove_var(KUBERNETES_SERVICE_HOST), + // TODO: Audit that the environment access only happens in single-threaded code. + Ok(service_host) => unsafe { std::env::set_var(KUBERNETES_SERVICE_HOST, service_host) }, + // TODO: Audit that the environment access only happens in single-threaded code. + Err(_) => unsafe { std::env::remove_var(KUBERNETES_SERVICE_HOST) }, } assert_eq!(default_local_runner_mode.unwrap(), ForgeRunnerMode::Local); diff --git a/testsuite/forge/src/success_criteria.rs b/testsuite/forge/src/success_criteria.rs index 8568ee350da..83e380a4f05 100644 --- a/testsuite/forge/src/success_criteria.rs +++ b/testsuite/forge/src/success_criteria.rs @@ -6,6 +6,7 @@ use crate::{ fetch_fullnode_failures, fetch_system_metrics, fetch_validator_error_metrics, LatencyBreakdown, LatencyBreakdownSlice, SystemMetrics, }, + result::TestResult, Swarm, SwarmExt, TestReport, }; use anyhow::{bail, Context}; @@ -16,7 +17,13 @@ use movement::node::analyze::{ analyze_validators::AnalyzeValidators, fetch_metadata::FetchMetadata, }; use prometheus_http_query::response::Sample; -use std::{collections::BTreeMap, sync::Arc, time::Duration}; +use serde_json::json; +use std::{ + collections::BTreeMap, + fmt::{Debug, Formatter}, + sync::Arc, + time::Duration, +}; #[derive(Clone, Debug)] pub struct StateProgressThreshold { @@ -254,82 +261,119 @@ impl SuccessCriteria { } } -enum CombinedError { - Single(anyhow::Error), - Multiple(CriteriaCheckerErrors), +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum CheckType { + Hard, + Soft, } -impl From for CombinedError { - fn from(error: anyhow::Error) -> Self { - CombinedError::Single(error) - } +#[derive(Debug)] +struct CheckError { + name: String, + check_type: CheckType, + error: anyhow::Error, } -impl From for CombinedError { - fn from(errors: CriteriaCheckerErrors) -> Self { - CombinedError::Multiple(errors) +impl CheckError { + pub fn new(name: String, check_type: CheckType, error: anyhow::Error) -> Self { + Self { + name, + check_type, + error, + } } } -#[derive(Debug)] -struct CriteriaCheckerErrors { - errors: Vec, -} +impl std::ops::Deref for CheckError { + type Target = anyhow::Error; -impl CriteriaCheckerErrors { - pub fn new() -> Self { - Self { errors: Vec::new() } + fn deref(&self) -> &Self::Target { + &self.error } +} + +#[derive(Debug, Default)] +pub struct SuccessCriteriaErrors { + errors: Vec, +} - pub fn push(&mut self, error: anyhow::Error) { - self.errors.push(error); +impl SuccessCriteriaErrors { + fn push(&mut self, check_error: CheckError) { + self.errors.push(check_error); } - pub fn extend(&mut self, errors: CriteriaCheckerErrors) { + fn extend(&mut self, errors: SuccessCriteriaErrors) { self.errors.extend(errors.errors); } - pub fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.errors.is_empty() } } -impl std::fmt::Display for CriteriaCheckerErrors { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "The following errors occurred:")?; - writeln!(f, "--------------------------------")?; - for (i, error) in self.errors.iter().enumerate() { - writeln!(f, "Error {}: {}", i + 1, error)?; - writeln!(f, "Caused by:")?; - for (j, cause) in error.chain().skip(1).enumerate() { - writeln!(f, " {}. {}", j + 1, cause)?; - } - writeln!(f)?; +impl std::fmt::Display for SuccessCriteriaErrors { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut errors_json = Vec::new(); + + for error in self.errors.iter() { + let causes: Vec = error.chain().map(|c| c.to_string()).collect(); + errors_json.push(json!({ + "name": error.name, + "error": error.to_string(), + "causes": causes + })); } + write!(f, "{}", json!({ "errors": errors_json }))?; Ok(()) } } -impl std::error::Error for CriteriaCheckerErrors {} - -macro_rules! collect_errors { - ($($expr:expr),+ $(,)?) => {{ - let mut errors = CriteriaCheckerErrors::new(); - $( - match $expr { - Err(e) => match e.into() { - CombinedError::Single(err) => errors.push(err), - CombinedError::Multiple(errs) => errors.extend(errs), - }, - Ok(_) => {} - } - )+ +impl std::error::Error for SuccessCriteriaErrors {} + +impl From for TestResult { + fn from(errors: SuccessCriteriaErrors) -> Self { if errors.is_empty() { + Self::Successful + } else { + let is_hard_failure = errors + .errors + .iter() + .any(|e| e.check_type == CheckType::Hard); + if is_hard_failure { + Self::HardFailure(errors.to_string()) + } else { + Self::SoftFailure(errors.to_string()) + } + } + } +} + +#[derive(Default)] +pub struct SuccessCriteriaResults { + check_errors: SuccessCriteriaErrors, +} + +impl SuccessCriteriaResults { + fn add_result(&mut self, name: &str, check_type: CheckType, result: anyhow::Result<()>) { + if let Err(e) = result { + self.check_errors + .push(CheckError::new(name.to_string(), check_type, e)) + } + } + + pub fn extend(&mut self, result: anyhow::Result<(), SuccessCriteriaErrors>) { + if let Err(e) = result { + self.check_errors.extend(e) + } + } + + pub fn evaluate(self) -> Result<(), SuccessCriteriaErrors> { + if self.check_errors.is_empty() { Ok(()) } else { - Err(errors) + Err(self.check_errors) } - }}; + } } pub struct SuccessCriteriaChecker {} @@ -346,19 +390,23 @@ impl SuccessCriteriaChecker { .map(|n| format!(" for {}", n)) .unwrap_or_default(); - collect_errors!( - Self::check_throughput( - success_criteria.min_avg_tps, - success_criteria.max_expired_tps, - success_criteria.max_failed_submission_tps, - stats_rate, - &traffic_name_addition, - ), + let mut results = SuccessCriteriaResults::default(); + + results.extend(Self::check_throughput( + success_criteria.min_avg_tps, + success_criteria.max_expired_tps, + success_criteria.max_failed_submission_tps, + stats_rate, + &traffic_name_addition, + )); + results.add_result("Check Latency", CheckType::Soft, { Self::check_latency( &success_criteria.latency_thresholds, stats_rate, &traffic_name_addition, - ), + ) + }); + results.add_result("Check Latency Breakdown", CheckType::Soft, { if let Some(latency_breakdown_thresholds) = &success_criteria.latency_breakdown_thresholds { @@ -367,7 +415,9 @@ impl SuccessCriteriaChecker { } else { Ok(()) } - )?; + }); + + results.evaluate()?; Ok(()) } @@ -392,65 +442,72 @@ impl SuccessCriteriaChecker { let no_traffic_name_addition = "".to_string(); - collect_errors!( - Self::check_throughput( - success_criteria.min_avg_tps, - success_criteria.max_expired_tps, - success_criteria.max_failed_submission_tps, - &stats_rate, - &no_traffic_name_addition, - ), + let mut results = SuccessCriteriaResults::default(); + + results.extend(Self::check_throughput( + success_criteria.min_avg_tps, + success_criteria.max_expired_tps, + success_criteria.max_failed_submission_tps, + &stats_rate, + &no_traffic_name_addition, + )); + results.add_result( + "Check Latency", + CheckType::Soft, Self::check_latency( &success_criteria.latency_thresholds, &stats_rate, &no_traffic_name_addition, ), - if let Some(latency_breakdown_thresholds) = - &success_criteria.latency_breakdown_thresholds - { + ); + if let Some(latency_breakdown_thresholds) = &success_criteria.latency_breakdown_thresholds { + results.add_result( + "Check Latency Breakdown", + CheckType::Soft, latency_breakdown_thresholds - .ensure_threshold(latency_breakdown, &no_traffic_name_addition) - } else { - Ok(()) - }, - if let Some(timeout) = success_criteria.wait_for_all_nodes_to_catchup { + .ensure_threshold(latency_breakdown, &no_traffic_name_addition), + ); + } + if let Some(timeout) = success_criteria.wait_for_all_nodes_to_catchup { + results.add_result("Check nodes catchup", CheckType::Hard, { swarm .read() .await .wait_for_all_nodes_to_catchup_to_next(timeout) .await .context("Failed waiting for all nodes to catchup to next version") - } else { - Ok(()) - }, - if success_criteria.check_no_restarts { + }); + } + if success_criteria.check_no_restarts { + results.add_result("Check no validator restart", CheckType::Hard, { let swarm_read = swarm.read().await; - collect_errors!( - swarm_read - .ensure_no_validator_restart() - .await - .context("Failed ensuring no validator restarted"), - swarm_read - .ensure_no_fullnode_restart() - .await - .context("Failed ensuring no fullnode restarted"), - ) - } else { - Ok(()) - }, - if success_criteria.check_no_errors { + swarm_read + .ensure_no_validator_restart() + .await + .context("Failed ensuring no validator restarted") + }); + + results.add_result("Check no fullnode restart", CheckType::Hard, { + let swarm_read = swarm.read().await; + swarm_read + .ensure_no_fullnode_restart() + .await + .context("Failed ensuring no fullnode restarted") + }); + } + + if success_criteria.check_no_errors { + results.add_result("Check no error", CheckType::Hard, { Self::check_no_errors(swarm.clone()).await - } else { - Ok(()) - }, - if success_criteria.check_no_fullnode_failures { + }); + } + if success_criteria.check_no_fullnode_failures { + results.add_result("Check no fullnode failures", CheckType::Hard, { Self::check_no_fullnode_failures(swarm.clone()).await - } else { - Ok(()) - }, - if let Some(system_metrics_threshold) = - success_criteria.system_metrics_threshold.clone() - { + }); + } + if let Some(system_metrics_threshold) = success_criteria.system_metrics_threshold.clone() { + results.add_result("Check system metrics", CheckType::Hard, { Self::check_system_metrics( swarm.clone(), start_time, @@ -458,10 +515,11 @@ impl SuccessCriteriaChecker { system_metrics_threshold, ) .await - } else { - Ok(()) - }, - if let Some(chain_progress_threshold) = &success_criteria.chain_progress_check { + }); + } + + if let Some(chain_progress_threshold) = &success_criteria.chain_progress_check { + results.add_result("Check chain progress", CheckType::Hard, { Self::check_chain_progress( swarm.clone(), report, @@ -471,10 +529,10 @@ impl SuccessCriteriaChecker { ) .await .context("Failed check chain progress") - } else { - Ok(()) - } - )?; + }); + } + + results.evaluate()?; Ok(()) } @@ -618,9 +676,17 @@ impl SuccessCriteriaChecker { max_failed_submission_config: Option, stats_rate: &TxnStatsRate, traffic_name_addition: &String, - ) -> anyhow::Result<()> { - collect_errors!( + ) -> anyhow::Result<(), SuccessCriteriaErrors> { + let mut runner = SuccessCriteriaResults::default(); + + runner.add_result( + "Min avg tps", + CheckType::Soft, Self::check_tps(min_avg_tps, stats_rate, traffic_name_addition), + ); + runner.add_result( + "Max expired tps", + CheckType::Hard, Self::check_max_value( max_expired_config, stats_rate, @@ -628,6 +694,10 @@ impl SuccessCriteriaChecker { "expired", traffic_name_addition, ), + ); + runner.add_result( + "Max failed submission", + CheckType::Soft, Self::check_max_value( max_failed_submission_config, stats_rate, @@ -635,8 +705,8 @@ impl SuccessCriteriaChecker { "submission", traffic_name_addition, ), - )?; - Ok(()) + ); + runner.evaluate() } pub fn check_latency( diff --git a/testsuite/fuzzer/.cargo/config.toml b/testsuite/fuzzer/.cargo/config.toml index b9891568c79..29804a20603 100644 --- a/testsuite/fuzzer/.cargo/config.toml +++ b/testsuite/fuzzer/.cargo/config.toml @@ -4,5 +4,5 @@ target-applies-to-host = false rustflags = ["--cfg", "tokio_unstable", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes"] [host.x86_64-unknown-linux-gnu] -linker = "clang" -rustflags = ["--cfg", "tokio_unstable", "-C", "link-args=-fuse-ld=gold -Wl,--no-keep-files-mapped -Wl,--no-keep-memory -Wl,--no-threads", "-C", "codegen-units=1", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] +#linker = "rust-lld" +rustflags = ["--cfg", "tokio_unstable", "-Z", "unstable-options", "-C", "linker-features=+lld", "-C", "link-self-contained=+linker", "-C", "codegen-units=1", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] diff --git a/testsuite/fuzzer/.gitignore b/testsuite/fuzzer/.gitignore index b7cc4f77a77..d4258a3eb5a 100644 --- a/testsuite/fuzzer/.gitignore +++ b/testsuite/fuzzer/.gitignore @@ -2,3 +2,4 @@ *.crash perf.data perf.data.old +test-casr-report/ \ No newline at end of file diff --git a/testsuite/fuzzer/Cargo.toml b/testsuite/fuzzer/Cargo.toml index d0cf589dcdb..869614c88cd 100644 --- a/testsuite/fuzzer/Cargo.toml +++ b/testsuite/fuzzer/Cargo.toml @@ -1,21 +1,24 @@ [package] name = "fuzzer" version = "0.1.0" -edition = "2021" +edition = { workspace = true } license = { workspace = true } [dependencies] aptos-framework = { workspace = true } +aptos-language-e2e-tests = { workspace = true } aptos-types = { workspace = true } -arbitrary = { workspace = true } +arbitrary = { workspace = true, features = ["derive"] } base64 = "0.21.7" bcs = { workspace = true } -clap = { workspace = true } +clap = { workspace = true, features = ["derive"] } csv = { workspace = true } dearbitrary = { workspace = true } hex = { workspace = true } move-binary-format = { workspace = true, features = ["fuzzing"] } -move-core-types = { workspace = true, features = ["fuzzing"] } +move-core-types = { workspace = true } +move-model = { workspace = true } +move-transactional-test-runner = { workspace = true, features = ["fuzzing"] } rayon = { workspace = true } sha2 = { workspace = true } walkdir = { workspace = true } diff --git a/testsuite/fuzzer/data/0x1/function_values/any/Move.toml b/testsuite/fuzzer/data/0x1/function_values/any/Move.toml new file mode 100644 index 00000000000..fd233e31941 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/any/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "fv_any" +version = "1.0.0" +authors = [] + +[addresses] +poc = "0xcaffe" + +[dependencies] +MoveStdlib = { local = "../../../../../../aptos-move/framework/move-stdlib" } +AptosFramework = { local = "../../../../../../aptos-move/framework/aptos-framework" } +AptosStdlib = { local = "../../../../../../aptos-move/framework/aptos-stdlib" } + \ No newline at end of file diff --git a/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move b/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move new file mode 100644 index 00000000000..6c7d99db2a6 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move @@ -0,0 +1,26 @@ +module poc::fv_any { + use std::any; + struct A {} + + public fun make_potato(): A { + A {} + } + + public fun destroy_potato(x: A) { + A {} = x; + } + + public fun zzz(): || { + let potato = make_potato(); + || destroy_potato(potato) + } + + public entry fun win() { + let x: || (||) has drop + store = zzz; + + let a = 0x1::any::pack(x); + + let b = 0x1::any::unpack<|| (|| has drop + store)>(a); + b(); + } +} diff --git a/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml b/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml new file mode 100644 index 00000000000..07f1b8c6d7f --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "fv_ref" +version = "1.0.0" +authors = [] + +[addresses] +poc = "0xcaffe" + +[dependencies] +MoveStdlib = { local = "../../../../../../aptos-move/framework/move-stdlib" } +AptosFramework = { local = "../../../../../../aptos-move/framework/aptos-framework" } +AptosStdlib = { local = "../../../../../../aptos-move/framework/aptos-stdlib" } + \ No newline at end of file diff --git a/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move b/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move new file mode 100644 index 00000000000..783eb18d739 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move @@ -0,0 +1,31 @@ +module poc::fv_ref { + use std::debug; + struct DropCopy has drop, copy; + + + public fun assn(ref: &mut T, x: T){ + *ref = x; + } + + public entry fun foo() { + let x = DropCopy; + + // closure capturing x: DropCopy + let a: ||u64 has drop = ||{ + let DropCopy = x; + 1 + }; + + // harmless copy+drop function + let pwn: ||u64 has drop + copy = ||1; + + // swap them + // 0x1::mem::replace<||u64 has drop + copy>(&mut pwn, a); + assn<||u64 has drop + copy>(&mut pwn, a); + + // copy the closure with captured DropCopy + let pwncopy = copy pwn; + pwn(); + pwncopy(); + } +} diff --git a/testsuite/fuzzer/data/transactional/script_ext_dep.move b/testsuite/fuzzer/data/transactional/script_ext_dep.move new file mode 100644 index 00000000000..b2f6a80c8dc --- /dev/null +++ b/testsuite/fuzzer/data/transactional/script_ext_dep.move @@ -0,0 +1,59 @@ +//# init --addresses poc=0xcafe + +//# publish +module poc::a1 { + + public entry fun noop_generic() { + + // Do nothing. + + } +} + +//# publish +module poc::a2 { + + struct A2 has key, store, copy, drop {} +} + +//# publish +module poc::a3 { + use std::signer; + + struct Counter has key { value: u64 } + + fun init_module(account: &signer) { + move_to(account, Counter { value: 0 }); + } + + public entry fun increment_counter() acquires Counter { + let cnt = &mut borrow_global_mut(@poc).value; + *cnt = *cnt + 1; + } +} + +//# run --signers poc --exec-group 1 -- poc::a3::increment_counter + +//# run --signers 0x1111 --exec-group 1 +script { + fun main() { + poc::a1::noop_generic(); + poc::a3::increment_counter(); + } +} + +//# run --signers 0x2222 --exec-group 1 +script { + fun main() { + poc::a1::noop_generic(); + poc::a3::increment_counter(); + } +} + +//# run --signers 0x3333 --exec-group 1 +script { + fun main() { + poc::a1::noop_generic(); + poc::a3::increment_counter(); + } +} diff --git a/testsuite/fuzzer/fuzz.sh b/testsuite/fuzzer/fuzz.sh index a31cfb0d165..f416f25a1c0 100755 --- a/testsuite/fuzzer/fuzz.sh +++ b/testsuite/fuzzer/fuzz.sh @@ -1,14 +1,16 @@ #!/bin/bash -export RUSTFLAGS="${RUSTFLAGS} --cfg tokio_unstable" +export RUSTFLAGS="${RUSTFLAGS} --cfg tokio_unstable -C target-cpu=native" export EXTRAFLAGS="-Ztarget-applies-to-host -Zhost-config" # Nightly version control -# Pin nightly-2024-02-12 because of https://github.com/google/oss-fuzz/issues/11626 -NIGHTLY_VERSION="nightly-2024-09-05" +NIGHTLY_VERSION="nightly-2025-08-07" # GDRIVE format https://docs.google.com/uc?export=download&id=DOCID # "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_seed_corpus.zip" -CORPUS_ZIPS=("https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip") +CORPUS_ZIPS=( + "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip" + "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_transactional_seed_corpus.zip" +) # This save time excluding some features needed only for specific targets # Downside: fuzzers which require specific features need to recompile all dependencies @@ -263,12 +265,32 @@ function coverage() { install-coverage-tools fi - clean-coverage $fuzz_target - local corpus_dir="fuzz/corpus/$fuzz_target" + local profdata_file="fuzz/coverage/$fuzz_target/coverage.profdata" local coverage_dir="./fuzz/coverage/$fuzz_target/report" mkdir -p $coverage_dir - - if [ ! -d "fuzz/coverage/$fuzz_target/raw" ]; then + + if [ -f "$profdata_file" ]; then + local profdata_time + profdata_time=$(stat -f "%Sm" "$profdata_file") + echo "Found existing profdata file created at: $profdata_time" + read -p "Do you want to (c)lean and regenerate or (g)enerate report with existing file? [c/g]: " choice + case "$choice" in + c|C ) + clean-coverage $fuzz_target + local corpus_dir="fuzz/corpus/$fuzz_target" + cargo_fuzz coverage $fuzz_target $corpus_dir + ;; + g|G ) + echo "Using existing profdata file..." + ;; + * ) + echo "Invalid choice. Exiting." + exit 1 + ;; + esac + else + clean-coverage $fuzz_target + local corpus_dir="fuzz/corpus/$fuzz_target" cargo_fuzz coverage $fuzz_target $corpus_dir fi @@ -279,12 +301,12 @@ function coverage() { PERM="+111" fi - fuzz_target_bin=$(find ./target/*/coverage -name $fuzz_target -type f -perm $PERM) + fuzz_target_bin=$(find ./target/*/coverage -name $fuzz_target -type f -perm $PERM | head -n 1) echo "Found fuzz target binary: $fuzz_target_bin" # Generate the coverage report cargo +$NIGHTLY_VERSION cov -- show $fuzz_target_bin \ --format=html \ - --instr-profile=fuzz/coverage/$fuzz_target/coverage.profdata \ + --instr-profile=$profdata_file \ --show-directory-coverage \ --output-dir=$coverage_dir \ -Xdemangler=rustfilt \ @@ -318,7 +340,7 @@ function debug() { fi info "Debugging $fuzz_target with $testcase" # find the binary - binary=$(find ./target/*/release/ -name $fuzz_target -type f -perm /111) + binary=$(find_release_binary "$fuzz_target") if [ -z "$binary" ]; then error "Could not find binary for $fuzz_target. Run `./fuzz.sh build $fuzz_target` first" fi @@ -349,6 +371,10 @@ function run() { usage run fi fuzz_target=$1 + # TODO: switch to name args + # INFO: forkin with more then 8 cores degradate performances + fork_count=${3:-4} + ignore_crashes=${4:-0} testcase=$2 if [ ! -z "$testcase" ]; then if [ -f "$testcase" ]; then @@ -360,9 +386,9 @@ function run() { info "Running $fuzz_target" features=$(get_features_for_target $fuzz_target) if [[ "$OSTYPE" == "darwin"* ]]; then - cargo_fuzz run $features --sanitizer address -O $fuzz_target $testcase -- -fork=4 #-ignore_crashes=1 + cargo_fuzz run $features --sanitizer address -O $fuzz_target $testcase -- -fork=4 -ignore_crashes=$ignore_crashes else - cargo_fuzz run $features --sanitizer address -O $fuzz_target $testcase -- -rss_limit_mb=4096 -fork=10 #-ignore_crashes=1 + cargo_fuzz run $features --sanitizer none -O $fuzz_target $testcase -- -rss_limit_mb=4096 -fork=$fork_count -ignore_crashes=$ignore_crashes fi } @@ -386,14 +412,14 @@ function add() { fuzz_target=$1 fuzz_target_path="$fuzz_target.rs" - mkdir -p fuzz/fuzz_targets/$(dirname $fuzz_target_path) && touch fuzz/fuzz_targets/$fuzz_target_path + mkdir -p fuzz/fuzz_targets/"$(dirname "$fuzz_target_path")" && touch fuzz/fuzz_targets/"$fuzz_target_path" if [ $? -eq 0 ]; then { echo "" echo "[[bin]]" echo "name = \"$fuzz_target\"" - echo "path = \"$fuzz_target_path\"" + echo "path = \"fuzz_targets/$fuzz_target_path\"" echo "test = false" echo "doc = false" } >> fuzz/Cargo.toml @@ -415,6 +441,23 @@ function get_latest_mtime() { find "$dir" -type f -exec stat -f %m {} \; | sort -n | tail -n 1 | awk '{print $1+0}' || echo 0 } +# Helper to get the correct -perm pattern across platforms +function get_exec_perm_pattern() { + if [[ $OSTYPE == 'darwin'* ]]; then + echo "+111" + else + echo "/111" + fi +} + +# Helper to find the built release binary for a fuzz target +function find_release_binary() { + local fuzz_target="$1" + local perm_pattern + perm_pattern=$(get_exec_perm_pattern) + find ./target/*/release/ -name "$fuzz_target" -type f -perm $perm_pattern | head -n 1 +} + function monitor-coverage() { if [ -z "$1" ]; then usage monitor-coverage @@ -490,10 +533,17 @@ function samply() { error "$testcase does not exist" fi # find the binary - binary=$(find ./target/*/release/ -name $fuzz_target -type f -perm /111) + binary=$(find_release_binary "$fuzz_target") + + # Rebuild if missing or older than one day (1440 minutes) if [ -z "$binary" ]; then info "Building $fuzz_target" build "$fuzz_target" + binary=$(find_release_binary "$fuzz_target") + elif [ -n "$(find "$binary" -mmin +1440 -print -quit 2>/dev/null)" ]; then + info "Existing binary is older than one day. Rebuilding $fuzz_target" + build "$fuzz_target" + # No need to re-discover path; file is rebuilt in place fi info "Sampling $fuzz_target with $testcase" command samply record "$binary" "$testcase" diff --git a/testsuite/fuzzer/fuzz/Cargo.toml b/testsuite/fuzzer/fuzz/Cargo.toml index 905bbfa200b..8620ce70c5f 100644 --- a/testsuite/fuzzer/fuzz/Cargo.toml +++ b/testsuite/fuzzer/fuzz/Cargo.toml @@ -2,39 +2,12 @@ name = "fuzzer-fuzz" version = "0.0.0" publish = false -edition = "2021" +edition = { workspace = true } build = "build.rs" [package.metadata] cargo-fuzz = true -[dependencies] -aptos-cached-packages = { workspace = true } -aptos-consensus = { workspace = true, features = ["fuzzing"], optional = true } -aptos-crypto = { workspace = true } -aptos-framework = { workspace = true } -aptos-language-e2e-tests = { workspace = true, features = ["fuzzing"] } -aptos-transaction-simulation = { workspace = true } -aptos-types = { workspace = true, features = ["fuzzing"] } -aptos-vm = { workspace = true } -aptos-vm-environment = { workspace = true } -arbitrary = { workspace = true, features = ["derive"] } -base64 = { workspace = true } -bcs = { workspace = true } -libfuzzer-sys = "0.4.9" -move-binary-format = { workspace = true, features = ["fuzzing"] } -move-bytecode-verifier = { workspace = true } -move-core-types = { workspace = true, features = ["fuzzing"] } -move-vm-types = { workspace = true, features = ["fuzzing"] } -once_cell = { workspace = true } -rayon = { workspace = true } -ring = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } - -[features] -consensus = ["dep:aptos-consensus"] - [[bin]] name = "move_value_deserialize" path = "fuzz_targets/move/value_deserialize.rs" @@ -101,3 +74,40 @@ name = "type_tag_to_string" path = "fuzz_targets/move/type_tag_to_string.rs" test = false doc = false + +[[bin]] +name = "move_aptosvm_publish_and_run_transactional" +path = "fuzz_targets/move/aptosvm_publish_and_run_transactional.rs" +test = false +doc = false + +[features] +consensus = ["dep:aptos-consensus"] + +[dependencies] +aptos-block-executor = { workspace = true } +aptos-cached-packages = { workspace = true } +aptos-consensus = { workspace = true, features = ["fuzzing"], optional = true } +aptos-crypto = { workspace = true } +aptos-framework = { workspace = true } +aptos-language-e2e-tests = { workspace = true, features = ["fuzzing"] } +aptos-transaction-simulation = { workspace = true } +aptos-types = { workspace = true, features = ["fuzzing"] } +aptos-vm = { workspace = true } +aptos-vm-environment = { workspace = true } +arbitrary = { workspace = true, features = ["derive"] } +base64 = { workspace = true } +bcs = { workspace = true } +fuzzer = { path = "../" } +libfuzzer-sys = "0.4.9" +move-binary-format = { workspace = true, features = ["fuzzing"] } +move-bytecode-verifier = { workspace = true } +move-core-types = { workspace = true, features = ["fuzzing"] } +move-transactional-test-runner = { workspace = true, features = ["fuzzing"] } +move-vm-runtime = { workspace = true } +move-vm-types = { workspace = true, features = ["fuzzing"] } +once_cell = { workspace = true } +rayon = { workspace = true } +ring = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_authenticators.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_authenticators.rs index 3e5e880e4b8..b32fefbbbc6 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_authenticators.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_authenticators.rs @@ -69,6 +69,7 @@ fn run_case(input: TransactionState) -> Result<(), Corpus> { &VM, ChainId::mainnet(), Arc::clone(&TP), + None, ) .set_not_parallel(); diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs index d0de51f1bea..cd37385d623 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs @@ -8,6 +8,7 @@ use aptos_language_e2e_tests::executor::FakeExecutor; use aptos_transaction_simulation::GENESIS_CHANGE_SET_HEAD; use aptos_types::{chain_id::ChainId, write_set::WriteSet}; use aptos_vm::AptosVM; +use fuzzer::{ExecVariant, RunnableState}; use libfuzzer_sys::{fuzz_target, Corpus}; use move_binary_format::{ access::ModuleAccess, @@ -15,11 +16,8 @@ use move_binary_format::{ file_format::{CompiledModule, CompiledScript}, }; use once_cell::sync::Lazy; -use std::{ - collections::{BTreeMap, HashSet}, - sync::Arc, -}; -use utils::vm::{publish_group, sort_by_deps, ExecVariant, RunnableState}; +use std::{collections::HashSet, sync::Arc}; +use utils::vm::{group_modules_by_address_topo, publish_group}; // genesis write set generated once for each fuzzing session static VM: Lazy = Lazy::new(|| GENESIS_CHANGE_SET_HEAD.write_set().clone()); @@ -52,9 +50,9 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { } if let ExecVariant::Script { - script: s, - type_args: _, - args: _, + _script: s, + _type_args: _, + _args: _, } = &input.exec_variant { // reject bad scripts fast lite @@ -70,43 +68,15 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { return Err(Corpus::Keep); } - // topologically order modules { - let all_modules = input.dep_modules.clone(); - let mut map = all_modules - .into_iter() - .map(|m| (m.self_id(), m)) - .collect::>(); - let mut order = vec![]; - for id in map.keys() { - let mut visited = HashSet::new(); - sort_by_deps(&map, &mut order, id.clone(), &mut visited)?; - } - // } - - // group same address modules in packages. keep local ordering. - let mut packages = vec![]; - for cur_package_id in order.iter() { - let mut cur = vec![]; - if !map.contains_key(cur_package_id) { - continue; - } - // this makes sure we keep the order in packages - for id in order.iter() { - // check if part of current package - if id.address() == cur_package_id.address() { - if let Some(module) = map.remove(cur_package_id) { - cur.push(module); - } - } - } - packages.push(cur) - } + // group packages using shared topo helper + let packages = group_modules_by_address_topo(input.dep_modules.clone())?; AptosVM::set_concurrency_level_once(FUZZER_CONCURRENCY_LEVEL); let mut vm = FakeExecutor::from_genesis_with_existing_thread_pool( &VM, ChainId::mainnet(), Arc::clone(&TP), + None, ) .set_not_parallel(); diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs index e92824cc168..a1dea2a53d0 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs @@ -9,31 +9,26 @@ use aptos_types::{ chain_id::ChainId, on_chain_config::Features, transaction::{ - EntryFunction, ExecutionStatus, Script, TransactionArgument, TransactionPayload, - TransactionStatus, + EntryFunction, ExecutionStatus, Script, TransactionArgument, TransactionOutput, + TransactionPayload, TransactionStatus, }, write_set::WriteSet, }; use aptos_vm::AptosVM; -use aptos_vm_environment::prod_configs; +use aptos_vm_environment::{prod_configs, prod_configs::LATEST_GAS_FEATURE_VERSION}; use libfuzzer_sys::{fuzz_target, Corpus}; use move_binary_format::{ - access::ModuleAccess, - deserializer::DeserializerConfig, - errors::VMError, - file_format::{CompiledModule, CompiledScript, SignatureToken}, + access::ModuleAccess, deserializer::DeserializerConfig, file_format::SignatureToken, }; use move_core_types::vm_status::{StatusCode, StatusType}; use once_cell::sync::Lazy; -use std::{ - collections::{BTreeMap, HashSet}, - sync::Arc, - time::Instant, -}; +use std::{collections::HashSet, sync::Arc, time::Instant}; mod utils; +use fuzzer::{Authenticator, ExecVariant, RunnableState}; +use move_vm_runtime::RuntimeEnvironment; use utils::vm::{ - check_for_invariant_violation, publish_group, sort_by_deps, ExecVariant, - FuzzerRunnableAuthenticator, RunnableState, + group_modules_by_address_topo, publish_group, resolve_function_name, verify_module_fast, + verify_script_fast, BYTECODE_VERSION, }; // genesis write set generated once for each fuzzing session @@ -53,40 +48,19 @@ const MAX_TYPE_PARAMETER_VALUE: u16 = 64 / 4 * 16; // third_party/move/move-byte const EXECUTION_TIME_GAS_RATIO: u8 = 100; -// List of known false positive messages for invariant violations -// If some invariant violation do not come with a message, we need to attach a message to it at throwing site. -const KNOWN_FALSE_POSITIVES: &[&str] = &["too many type parameters/arguments in the program"]; - #[inline(always)] fn is_coverage_enabled() -> bool { cfg!(coverage_enabled) || std::env::var("LLVM_PROFILE_FILE").is_ok() } -fn check_for_invariant_violation_vmerror(e: VMError) { - if e.status_type() == StatusType::InvariantViolation { - let is_known_false_positive = e.message().map_or(false, |msg| { - KNOWN_FALSE_POSITIVES - .iter() - .any(|known| msg.starts_with(known)) - }); - - if !is_known_false_positive && e.status_type() == StatusType::InvariantViolation { - panic!( - "invariant violation {:?}\n{}{:?} {}", - e, - "RUST_BACKTRACE=1 DEBUG_VM_STATUS=", - e.major_status(), - "./fuzz.sh run move_aptosvm_publish_and_run " - ); - } - } -} +// moved to utils::vm::check_for_invariant_violation_vmerror // filter modules +#[inline(always)] fn filter_modules(input: &RunnableState) -> Result<(), Corpus> { // reject any TypeParameter exceeds the maximum allowed value (Avoid known Ivariant Violation) - if let ExecVariant::Script { script, .. } = input.exec_variant.clone() { - for signature in script.signatures { + if let ExecVariant::Script { _script, .. } = input.exec_variant.clone() { + for signature in _script.signatures { for sign_token in signature.0.iter() { if let SignatureToken::TypeParameter(idx) = sign_token { if *idx > MAX_TYPE_PARAMETER_VALUE { @@ -112,39 +86,16 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { // filter modules filter_modules(&input)?; - let verifier_config = prod_configs::aptos_prod_verifier_config(&Features::default()); - let deserializer_config = DeserializerConfig::new(8, 255); + let verifier_config = + prod_configs::aptos_prod_verifier_config(LATEST_GAS_FEATURE_VERSION, &Features::default()); + let deserializer_config = DeserializerConfig::new(BYTECODE_VERSION, 255); for m in input.dep_modules.iter_mut() { - // m.metadata = vec![]; // we could optimize metadata to only contain aptos metadata - // m.version = VERSION_MAX; - - // reject bad modules fast - let mut module_code: Vec = vec![]; - m.serialize(&mut module_code).map_err(|_| Corpus::Keep)?; - let m_de = CompiledModule::deserialize_with_config(&module_code, &deserializer_config) - .map_err(|_| Corpus::Reject)?; - move_bytecode_verifier::verify_module_with_config(&verifier_config, &m_de).map_err(|e| { - check_for_invariant_violation_vmerror(e); - Corpus::Reject - })? + verify_module_fast(m, &verifier_config, &deserializer_config)?; } - if let ExecVariant::Script { - script: s, - type_args: _, - args: _, - } = &input.exec_variant - { - // reject bad scripts fast - let mut script_code: Vec = vec![]; - s.serialize(&mut script_code).map_err(|_| Corpus::Keep)?; - let s_de = CompiledScript::deserialize_with_config(&script_code, &deserializer_config) - .map_err(|_| Corpus::Reject)?; - move_bytecode_verifier::verify_script_with_config(&verifier_config, &s_de).map_err(|e| { - check_for_invariant_violation_vmerror(e); - Corpus::Reject - })? + if let ExecVariant::Script { _script: s, .. } = &input.exec_variant { + verify_script_fast(s, &verifier_config, &deserializer_config)? } // check no duplicates @@ -153,43 +104,16 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { return Err(Corpus::Reject); } - // topologically order modules { - let all_modules = input.dep_modules.clone(); - let mut map = all_modules - .into_iter() - .map(|m| (m.self_id(), m)) - .collect::>(); - let mut order = vec![]; - for id in map.keys() { - let mut visited = HashSet::new(); - sort_by_deps(&map, &mut order, id.clone(), &mut visited)?; - } - // } - - // group same address modules in packages. keep local ordering. - let mut packages = vec![]; - for cur_package_id in order.iter() { - let mut cur = vec![]; - if !map.contains_key(cur_package_id) { - continue; - } - // this makes sure we keep the order in packages - for id in order.iter() { - // check if part of current package - if id.address() == cur_package_id.address() { - if let Some(module) = map.remove(cur_package_id) { - cur.push(module); - } - } - } - packages.push(cur) - } + let packages = group_modules_by_address_topo(input.dep_modules.clone())?; AptosVM::set_concurrency_level_once(FUZZER_CONCURRENCY_LEVEL); + // Enable runtime reference-safety checks for the Move VM + // prod_configs::set_paranoid_ref_checks(true); let mut vm = FakeExecutor::from_genesis_with_existing_thread_pool( &VM_WRITE_SET, ChainId::mainnet(), Arc::clone(&TP), + None, ) .set_not_parallel(); @@ -212,13 +136,13 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { // build tx let tx = match input.exec_variant.clone() { ExecVariant::Script { - script, - type_args, - args, + _script: script, + _type_args: type_args, + _args: args, } => { let mut script_bytes = vec![]; script - .serialize(&mut script_bytes) + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_bytes) .map_err(|_| Corpus::Reject)?; sender_acc .transaction() @@ -235,33 +159,18 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { ))) }, ExecVariant::CallFunction { - module, - function, - type_args, - args, + _module: module, + _function: function, + _type_args: type_args, + _args: args, } => { - // convert FunctionDefinitionIndex to function name... { + // convert FunctionDefinitionIndex to function name let cm = input .dep_modules .iter() .find(|m| m.self_id() == module) .ok_or(Corpus::Reject)?; - let fhi = cm - .function_defs - .get(function.0 as usize) - .ok_or(Corpus::Reject)? - .function; - let function_identifier_index = cm - .function_handles - .get(fhi.0 as usize) - .ok_or(Corpus::Reject)? - .name; - let function_name = cm - .identifiers - .get(function_identifier_index.0 as usize) - .ok_or(Corpus::Reject)? - .clone(); - // } + let function_name = resolve_function_name(cm, function)?; sender_acc .transaction() .gas_unit_price(100) @@ -277,13 +186,13 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { }; let raw_tx = tx.raw(); let tx = match input.tx_auth_type { - FuzzerRunnableAuthenticator::Ed25519 { sender: _ } => raw_tx + Authenticator::Ed25519 { _sender: _ } => raw_tx .sign(&sender_acc.privkey, sender_acc.pubkey.as_ed25519().unwrap()) .map_err(|_| Corpus::Reject)? .into_inner(), - FuzzerRunnableAuthenticator::MultiAgent { - sender: _, - secondary_signers, + Authenticator::MultiAgent { + _sender: _, + _secondary_signers: secondary_signers, } => { // higher number here slows down fuzzer significatly due to slow signing process. if secondary_signers.len() > 10 { @@ -304,10 +213,10 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { .map_err(|_| Corpus::Reject)? .into_inner() }, - FuzzerRunnableAuthenticator::FeePayer { - sender: _, - secondary_signers, - fee_payer, + Authenticator::FeePayer { + _sender: _, + _secondary_signers: secondary_signers, + _fee_payer: fee_payer, } => { // higher number here slows down fuzzer significatly due to slow signing process. if secondary_signers.len() > 10 { @@ -336,39 +245,36 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { // exec tx tdbg!("exec start"); - let mut old_res = None; + let mut old_outputs: Option> = None; const N_EXTRA_RERUNS: usize = 0; #[allow(clippy::reversed_empty_ranges)] for _ in 0..N_EXTRA_RERUNS { - let res = vm.execute_block(vec![tx.clone()]); - if let Some(old_res) = old_res { - assert!(old_res == res); + let outputs = utils::vm::execute_block_or_keep(&vm, vec![tx.clone()])?; + if let Some(old) = &old_outputs { + assert_eq!(old, &outputs); } - old_res = Some(res); + old_outputs = Some(outputs); } let now = Instant::now(); - let res = vm.execute_block(vec![tx.clone()]); + let mut outputs = utils::vm::execute_block_or_keep(&vm, vec![tx.clone()])?; let elapsed = now.elapsed(); // check main execution as well - if let Some(old_res) = old_res { - assert!(old_res == res); + if let Some(old) = &old_outputs { + assert_eq!(old, &outputs); } - let res = res - .map_err(|e| { - check_for_invariant_violation(e); - Corpus::Keep - })? - .pop() - .expect("expect 1 output"); + assert_eq!(outputs.len(), 1, "expect 1 output"); + let res = outputs.pop().expect("expect 1 output"); tdbg!("exec end"); // if error exit gracefully let status = match tdbg!(res.status()) { TransactionStatus::Keep(status) => status, TransactionStatus::Discard(e) => { - if e.status_type() == StatusType::InvariantViolation { + if e.status_type() == StatusType::InvariantViolation + || e.status_type() == StatusType::Unknown + { panic!("invariant violation {:?}", e); } return Err(Corpus::Keep); @@ -379,7 +285,8 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { ExecutionStatus::Success => (), ExecutionStatus::MiscellaneousError(e) => { if let Some(e) = e { - if e.status_type() == StatusType::InvariantViolation + if (e.status_type() == StatusType::InvariantViolation + || e.status_type() == StatusType::Unknown) && *e != StatusCode::TYPE_RESOLUTION_FAILURE && *e != StatusCode::STORAGE_ERROR { @@ -415,7 +322,8 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { ); } } - + drop(vm); + RuntimeEnvironment::flush_verified_module_cache(); Ok(()) } diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs new file mode 100644 index 00000000000..db62a0ea671 --- /dev/null +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs @@ -0,0 +1,383 @@ +#![no_main] + +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_block_executor::code_cache_global_manager::AptosModuleCacheManager; +use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; +use aptos_transaction_simulation::GENESIS_CHANGE_SET_HEAD; +use aptos_types::{ + chain_id::ChainId, + on_chain_config::Features, + transaction::{ + EntryFunction, ExecutionStatus, Script, SignedTransaction, TransactionArgument, + TransactionPayload, TransactionStatus, + }, + write_set::WriteSet, +}; +use aptos_vm::AptosVM; +use aptos_vm_environment::{prod_configs, prod_configs::LATEST_GAS_FEATURE_VERSION}; +use libfuzzer_sys::{fuzz_target, Corpus}; +use move_binary_format::{ + access::ModuleAccess, + deserializer::DeserializerConfig, + file_format::{CompiledModule, SignatureToken}, +}; +use move_core_types::{ + account_address::AccountAddress, + vm_status::{StatusCode, StatusType}, +}; +use move_transactional_test_runner::transactional_ops::TransactionalOperation; +use once_cell::sync::Lazy; +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; +mod utils; +use fuzzer::RunnableStateWithOperations; +use utils::vm::{ + execute_block_or_keep, group_modules_by_address_topo, publish_group, + select_or_create_block_index, verify_module_fast, verify_script_fast, BYTECODE_VERSION, +}; + +// genesis write set generated once for each fuzzing session +static VM_WRITE_SET: Lazy = Lazy::new(|| GENESIS_CHANGE_SET_HEAD.write_set().clone()); + +const FUZZER_CONCURRENCY_LEVEL: usize = 4; +static TP: Lazy> = Lazy::new(|| { + Arc::new( + rayon::ThreadPoolBuilder::new() + .num_threads(FUZZER_CONCURRENCY_LEVEL) + .build() + .unwrap(), + ) +}); + +const MAX_TYPE_PARAMETER_VALUE: u16 = 64 / 4 * 16; // third_party/move/move-bytecode-verifier/src/signature_v2.rs#L1306-L1312 + +// filter modules +#[inline(always)] +fn filter_modules(input: &RunnableStateWithOperations) -> Result<(), Corpus> { + // reject any TypeParameter exceeds the maximum allowed value (Avoid known Ivariant Violation) + for operation in input.operations.iter() { + match operation { + TransactionalOperation::PublishModule { _module } => { + for signature in _module.signatures.iter() { + for sign_token in signature.0.iter() { + if let SignatureToken::TypeParameter(idx) = sign_token { + if *idx > MAX_TYPE_PARAMETER_VALUE { + return Err(Corpus::Reject); + } + } + } + } + }, + TransactionalOperation::RunScript { _script, .. } => { + for signature in _script.signatures.iter() { + for sign_token in signature.0.iter() { + if let SignatureToken::TypeParameter(idx) = sign_token { + if *idx > MAX_TYPE_PARAMETER_VALUE { + return Err(Corpus::Reject); + } + } + } + } + }, + _ => (), + } + } + Ok(()) +} + +#[allow(clippy::literal_string_with_formatting_args)] +fn run_case(input: RunnableStateWithOperations) -> Result<(), Corpus> { + tdbg!(&input); + + // filter modules + tdbg!("filtering modules"); + filter_modules(&input)?; + + let verifier_config = + prod_configs::aptos_prod_verifier_config(LATEST_GAS_FEATURE_VERSION, &Features::default()); + let deserializer_config = DeserializerConfig::new(BYTECODE_VERSION, 255); + + let mut dep_modules: Vec = vec![]; + // Collect dependency modules and later we will verify runs individually + for operation in input.operations.iter() { + if let TransactionalOperation::PublishModule { _module } = operation { + dep_modules.push(_module.clone()); + } + } + + tdbg!("verifying scripts"); + for operation in input.operations.iter() { + if let TransactionalOperation::RunScript { _script, .. } = operation { + verify_script_fast(_script, &verifier_config, &deserializer_config)?; + } + } + + tdbg!("verifying modules"); + for m in dep_modules.iter_mut() { + verify_module_fast(m, &verifier_config, &deserializer_config)?; + } + + tdbg!("checking no duplicates"); + // check no duplicates + let mset: HashSet<_> = dep_modules.iter().map(|m| m.self_id()).collect(); + if mset.len() != dep_modules.len() { + return Err(Corpus::Reject); + } + + tdbg!("topologically ordering and grouping modules"); + let packages = group_modules_by_address_topo(dep_modules.clone())?; + + // Enable runtime reference-safety checks for the Move VM + // prod_configs::set_paranoid_ref_checks(true); + + let module_cache_manager = AptosModuleCacheManager::new(); + AptosVM::set_concurrency_level_once(FUZZER_CONCURRENCY_LEVEL); + let mut vm = FakeExecutor::from_genesis_with_existing_thread_pool( + &VM_WRITE_SET, + ChainId::mainnet(), + Arc::clone(&TP), + Some(module_cache_manager), + ) + .set_parallel(); + + // publish all packages + for group in packages { + let sender = *group[0].address(); + let acc = vm.new_account_at(sender); + publish_group(&mut vm, &acc, &group, 0)?; + } + + // Build blocks grouped by exec_group and sign with provided signers + tdbg!("building grouped tx blocks"); + // Helper maps to reuse accounts and sequence numbers per sender + let mut accounts_by_addr: HashMap = HashMap::new(); + let mut next_seq_by_addr: HashMap = HashMap::new(); + let mut blocks: Vec> = Vec::new(); + let mut group_to_block_index: HashMap = HashMap::new(); + + // Fallback sender if no signers provided (rare) + let mut fallback_sender: Option = None; + + // Convert operations into blocks + for operation in input.operations.iter() { + match operation { + TransactionalOperation::PublishModule { .. } => (), + TransactionalOperation::RunScript { + _script, + _type_args, + _args, + _signers, + _exec_group, + } => { + // Determine block index for this operation + let block_index = select_or_create_block_index( + *_exec_group, + &mut blocks, + &mut group_to_block_index, + ); + + // Build raw transaction + let mut script_bytes = vec![]; + _script + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_bytes) + .map_err(|_| Corpus::Reject)?; + + // Prepare sender and secondary signers + let (sender_addr, secondary_addrs) = if !_signers.is_empty() { + (_signers[0], _signers[1..].to_vec()) + } else { + // Create fallback sender lazily + let f = fallback_sender.get_or_insert_with(|| { + vm.create_accounts(1, input.tx_auth_type.sender().fund_amount(), 0) + .remove(0) + }); + (*f.address(), vec![]) + }; + + // Ensure accounts exist for sender and secondary signers + accounts_by_addr + .entry(sender_addr) + .or_insert_with(|| vm.new_account_at(sender_addr)); + for sec in secondary_addrs.iter() { + if !accounts_by_addr.contains_key(sec) { + let acc = vm.new_account_at(*sec); + accounts_by_addr.insert(*sec, acc); + } + } + + let sender_acc = accounts_by_addr.get(&sender_addr).unwrap(); + let sequence_number = *next_seq_by_addr.get(&sender_addr).unwrap_or(&0u64); + + let tx_builder = sender_acc + .transaction() + .gas_unit_price(100) + .max_gas_amount(1000) + .sequence_number(sequence_number) + .payload(TransactionPayload::Script(Script::new( + script_bytes, + _type_args.clone(), + _args + .iter() + .map(|x| x.clone().try_into()) + .collect::, _>>() + .map_err(|_| Corpus::Reject)?, + ))); + + let raw_tx = tx_builder.raw(); + + // Sign transaction: single or multi-agent + let signed_tx = utils::vm::sign_single_or_multi( + raw_tx, + sender_acc, + &secondary_addrs, + &accounts_by_addr, + )?; + + // Increment sender sequence + next_seq_by_addr.insert(sender_addr, sequence_number + 1); + + blocks[block_index].push(signed_tx); + }, + TransactionalOperation::CallFunction { + _module, + _function, + _type_args, + _args, + _signers, + _exec_group, + } => { + // Determine block index for this operation + let block_index = select_or_create_block_index( + *_exec_group, + &mut blocks, + &mut group_to_block_index, + ); + + // Resolve function name from index + let cm = dep_modules + .iter() + .find(|m| m.self_id() == *_module) + .ok_or(Corpus::Reject)?; + let fhi = cm + .function_defs + .get(_function.0 as usize) + .ok_or(Corpus::Reject)? + .function; + let function_identifier_index = cm + .function_handles + .get(fhi.0 as usize) + .ok_or(Corpus::Reject)? + .name; + let function_name = cm + .identifiers + .get(function_identifier_index.0 as usize) + .ok_or(Corpus::Reject)? + .clone(); + + // Prepare sender and secondary signers + let (sender_addr, secondary_addrs) = if !_signers.is_empty() { + (_signers[0], _signers[1..].to_vec()) + } else { + // Create fallback sender lazily + let f = fallback_sender.get_or_insert_with(|| { + vm.create_accounts(1, input.tx_auth_type.sender().fund_amount(), 0) + .remove(0) + }); + (*f.address(), vec![]) + }; + + // Ensure accounts exist for sender and secondary signers + accounts_by_addr + .entry(sender_addr) + .or_insert_with(|| vm.new_account_at(sender_addr)); + for sec in secondary_addrs.iter() { + if !accounts_by_addr.contains_key(sec) { + let acc = vm.new_account_at(*sec); + accounts_by_addr.insert(*sec, acc); + } + } + + let sender_acc = accounts_by_addr.get(&sender_addr).unwrap(); + let sequence_number = *next_seq_by_addr.get(&sender_addr).unwrap_or(&0u64); + + let tx_builder = sender_acc + .transaction() + .gas_unit_price(100) + .max_gas_amount(1000) + .sequence_number(sequence_number) + .payload(TransactionPayload::EntryFunction(EntryFunction::new( + _module.clone(), + function_name, + _type_args.clone(), + _args.clone(), + ))); + + let raw_tx = tx_builder.raw(); + + // Sign transaction: single or multi-agent + let signed_tx = utils::vm::sign_single_or_multi( + raw_tx, + sender_acc, + &secondary_addrs, + &accounts_by_addr, + )?; + + // Increment sender sequence + next_seq_by_addr.insert(sender_addr, sequence_number + 1); + + blocks[block_index].push(signed_tx); + }, + } + } + + // Execute blocks + tdbg!("exec start"); + for block in blocks.into_iter() { + if block.is_empty() { + continue; + } + let outputs = execute_block_or_keep(&vm, block)?; + + // Check all transaction outputs and apply write sets on success + for res in outputs.into_iter() { + let status = match tdbg!(res.status()) { + TransactionStatus::Keep(status) => status, + TransactionStatus::Discard(e) => { + if e.status_type() == StatusType::InvariantViolation { + panic!("invariant violation {:?}", e); + } + return Err(Corpus::Keep); + }, + _ => return Err(Corpus::Keep), + }; + match tdbg!(status) { + ExecutionStatus::Success | ExecutionStatus::OutOfGas => { + vm.apply_write_set(res.write_set()) + }, + ExecutionStatus::MiscellaneousError(e) => { + if let Some(e) = e { + if e.status_type() == StatusType::InvariantViolation + && *e != StatusCode::TYPE_RESOLUTION_FAILURE + && *e != StatusCode::STORAGE_ERROR + { + panic!("invariant violation {:?}, {:?}", e, res.auxiliary_data()); + } + } + return Err(Corpus::Keep); + }, + _ => return Err(Corpus::Keep), + }; + } + } + tdbg!("exec end"); + + Ok(()) +} + +fuzz_target!(|fuzz_data: RunnableStateWithOperations| -> Corpus { + run_case(fuzz_data).err().unwrap_or(Corpus::Keep) +}); diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs index fced79cd3be..8e735198ab4 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs @@ -4,12 +4,12 @@ #![no_main] use aptos_types::on_chain_config::Features; -use aptos_vm_environment::prod_configs; +use aptos_vm_environment::{prod_configs, prod_configs::LATEST_GAS_FEATURE_VERSION}; use libfuzzer_sys::{fuzz_target, Corpus}; use move_binary_format::errors::VMError; use move_core_types::vm_status::StatusType; mod utils; -use utils::vm::RunnableState; +use fuzzer::RunnableState; fn check_for_invariant_violation_vmerror(e: VMError) { if e.status_type() == StatusType::InvariantViolation @@ -23,7 +23,8 @@ fn check_for_invariant_violation_vmerror(e: VMError) { } fuzz_target!(|fuzz_data: RunnableState| -> Corpus { - let verifier_config = prod_configs::aptos_prod_verifier_config(&Features::default()); + let verifier_config = + prod_configs::aptos_prod_verifier_config(LATEST_GAS_FEATURE_VERSION, &Features::default()); for m in fuzz_data.dep_modules.iter() { if let Err(e) = move_bytecode_verifier::verify_module_with_config(&verifier_config, m) { diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs index bbd6d5a0639..17ad74ccd89 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs @@ -6,8 +6,11 @@ use arbitrary::Arbitrary; use libfuzzer_sys::{fuzz_target, Corpus}; // mod utils; use move_binary_format::{ - deserializer::DeserializerConfig, file_format::CompiledScript, CompiledModule, + deserializer::DeserializerConfig, + file_format::{CompiledModule, CompiledScript}, + file_format_common::VERSION_MAX, }; +use move_vm_types::natives::function::StatusCode; #[derive(Arbitrary, Debug)] enum ExecVariant { @@ -28,31 +31,49 @@ fn run_case(data: &ExecVariant) -> Corpus { fn run_case_module(module: &CompiledModule) -> Corpus { let mut module_code = vec![]; - if module.serialize(&mut module_code).is_err() { + if module + .serialize_for_version(Some(VERSION_MAX), &mut module_code) + .is_err() + { return Corpus::Reject; } - match CompiledModule::deserialize_with_config(&module_code, &DeserializerConfig::default()) { + + match CompiledModule::deserialize_no_check_bounds(&module_code) { Ok(mut m) => { m.version = module.version; assert_eq!(*module, m); Corpus::Keep }, - Err(_) => Corpus::Reject, + Err(e) => { + if e.major_status() != StatusCode::MALFORMED { + panic!("Failed to deserialize module after serialization\nCompiledModule:\n{:?}\nSerialized:{:?}", module, module_code); + } + Corpus::Reject + }, } } fn run_case_script(script: &CompiledScript) -> Corpus { let mut script_code = vec![]; - if script.serialize(&mut script_code).is_err() { + if script + .serialize_for_version(Some(VERSION_MAX), &mut script_code) + .is_err() + { return Corpus::Reject; } - match CompiledScript::deserialize_with_config(&script_code, &DeserializerConfig::default()) { + + match CompiledScript::deserialize_no_check_bounds(&script_code) { Ok(mut s) => { s.version = script.version; assert_eq!(*script, s); Corpus::Keep }, - Err(_) => Corpus::Reject, + Err(e) => { + if e.major_status() != StatusCode::MALFORMED { + panic!("Failed to deserialize script after serialization\nCompiledScript:\n{:?}\nSerialized:{:?}", script, script_code); + } + Corpus::Reject + }, } } @@ -60,7 +81,8 @@ fn run_case_raw(raw_data: &Vec) -> Corpus { if let Ok(m) = CompiledModule::deserialize_with_config(raw_data, &DeserializerConfig::default()) { let mut module_code = vec![]; - m.serialize(&mut module_code).unwrap(); + m.serialize_for_version(Some(VERSION_MAX), &mut module_code) + .unwrap(); assert_eq!(*raw_data, module_code); return Corpus::Keep; } @@ -68,7 +90,8 @@ fn run_case_raw(raw_data: &Vec) -> Corpus { if let Ok(s) = CompiledScript::deserialize_with_config(raw_data, &DeserializerConfig::default()) { let mut script_code = vec![]; - s.serialize(&mut script_code).unwrap(); + s.serialize_for_version(Some(VERSION_MAX), &mut script_code) + .unwrap(); assert_eq!(*raw_data, script_code); return Corpus::Keep; } diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs index bb873b59db7..2f18bcbaf4e 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs @@ -5,6 +5,7 @@ use arbitrary::Arbitrary; use libfuzzer_sys::{fuzz_target, Corpus}; use move_core_types::{ability::AbilitySet, identifier::Identifier, language_storage::TypeTag}; + mod utils; #[derive(Arbitrary, Debug)] @@ -17,15 +18,21 @@ struct FuzzData { fn is_valid_type_tag(type_tag: &TypeTag) -> bool { match type_tag { TypeTag::Struct(struct_tag) => { - Identifier::is_valid(&struct_tag.module.to_string()) - && Identifier::is_valid(&struct_tag.name.to_string()) + Identifier::is_valid(struct_tag.module.to_string()) + && Identifier::is_valid(struct_tag.name.to_string()) && struct_tag.type_args.iter().all(is_valid_type_tag) }, TypeTag::Vector(inner_type_tag) => is_valid_type_tag(inner_type_tag), TypeTag::Function(function_tag) => { function_tag.abilities.into_u8() <= AbilitySet::ALL.into_u8() - && function_tag.args.iter().all(is_valid_type_tag) - && function_tag.results.iter().all(is_valid_type_tag) + && function_tag + .args + .iter() + .all(|t| is_valid_type_tag(t.inner_tag())) + && function_tag + .results + .iter() + .all(|t| is_valid_type_tag(t.inner_tag())) }, _ => true, // Primitive types are always valid } diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs index 1dc04685b92..04d24d252f7 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs @@ -3,9 +3,9 @@ #![allow(dead_code)] -use super::helpers::UserAccount; use aptos_types::keyless::{AnyKeylessPublicKey, EphemeralCertificate}; use arbitrary::Arbitrary; +use fuzzer::UserAccount; use serde::{Deserialize, Serialize}; use serde_json; diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs index bb0a4b5f31f..091be0e3967 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs @@ -3,8 +3,6 @@ #![allow(dead_code)] -use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; -use arbitrary::Arbitrary; use move_binary_format::file_format::CompiledModule; use move_core_types::value::{MoveStructLayout, MoveTypeLayout}; @@ -33,37 +31,6 @@ macro_rules! tdbg { }; } -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone, Copy)] -pub enum FundAmount { - Zero, - Poor, - Rich, -} - -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone, Copy)] -pub struct UserAccount { - is_inited_and_funded: bool, - fund: FundAmount, -} - -impl UserAccount { - pub fn fund_amount(&self) -> u64 { - match self.fund { - FundAmount::Zero => 0, - FundAmount::Poor => 1_000, - FundAmount::Rich => 1_000_000_000_000_000, - } - } - - pub fn convert_account(&self, vm: &mut FakeExecutor) -> Account { - if self.is_inited_and_funded { - vm.create_accounts(1, self.fund_amount(), 0).remove(0) - } else { - Account::new() - } - } -} - pub(crate) fn is_valid_layout(layout: &MoveTypeLayout) -> bool { use MoveTypeLayout as L; @@ -75,6 +42,12 @@ pub(crate) fn is_valid_layout(layout: &MoveTypeLayout) -> bool { | L::U64 | L::U128 | L::U256 + | L::I8 + | L::I16 + | L::I32 + | L::I64 + | L::I128 + | L::I256 | L::Address | L::Signer | L::Function => true, diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs index 1e3fc543138..cf415388d77 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs @@ -3,26 +3,38 @@ #![allow(dead_code)] -use super::helpers::UserAccount; use crate::tdbg; use aptos_cached_packages::aptos_stdlib::code_publish_package_txn; -use aptos_framework::natives::code::{ - ModuleMetadata, MoveOption, PackageDep, PackageMetadata, UpgradePolicy, -}; +use aptos_crypto::HashValue; +use aptos_framework::natives::code::{ModuleMetadata, PackageDep, PackageMetadata, UpgradePolicy}; use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; -use aptos_types::transaction::{ExecutionStatus, TransactionPayload, TransactionStatus}; +use aptos_types::{ + block_executor::transaction_slice_metadata::TransactionSliceMetadata, + transaction::{ + ExecutionStatus, RawTransaction, SignedTransaction, TransactionOutput, TransactionPayload, + TransactionStatus, + }, +}; use arbitrary::Arbitrary; +use fuzzer::UserAccount; use libfuzzer_sys::Corpus; use move_binary_format::{ access::ModuleAccess, + deserializer::DeserializerConfig, + errors::VMError, file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex}, }; use move_core_types::{ - language_storage::{ModuleId, TypeTag}, - value::MoveValue, + identifier::Identifier, + language_storage::ModuleId, vm_status::{StatusCode, StatusType, VMStatus}, }; -use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::{ + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, + sync::atomic::{AtomicU64, Ordering}, +}; + +pub const BYTECODE_VERSION: u32 = 8; // Used to fuzz the MoveVM #[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] @@ -58,28 +70,6 @@ impl FuzzerRunnableAuthenticator { } } -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] -pub enum ExecVariant { - Script { - script: CompiledScript, - type_args: Vec, - args: Vec, - }, - CallFunction { - module: ModuleId, - function: FunctionDefinitionIndex, - type_args: Vec, - args: Vec>, - }, -} - -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] -pub struct RunnableState { - pub dep_modules: Vec, - pub exec_variant: ExecVariant, - pub tx_auth_type: FuzzerRunnableAuthenticator, -} - // used for ordering modules topologically pub(crate) fn sort_by_deps( map: &BTreeMap, @@ -107,6 +97,144 @@ pub(crate) fn sort_by_deps( Ok(()) } +// Small, hot helpers — eligible for inlining +#[inline] +pub(crate) fn select_or_create_block_index( + exec_group: u64, + blocks: &mut Vec>, + group_to_block_index: &mut HashMap, +) -> usize { + if exec_group == 0 { + blocks.push(Vec::new()); + blocks.len() - 1 + } else if let Some(&idx) = group_to_block_index.get(&exec_group) { + idx + } else { + let idx = blocks.len(); + blocks.push(Vec::new()); + group_to_block_index.insert(exec_group, idx); + idx + } +} + +#[inline] +pub(crate) fn ensure_account_present( + vm: &mut FakeExecutor, + accounts_by_addr: &mut HashMap, + addr: move_core_types::account_address::AccountAddress, +) { + accounts_by_addr + .entry(addr) + .or_insert_with(|| vm.new_account_at(addr)); +} + +#[inline] +pub(crate) fn ensure_accounts_present( + vm: &mut FakeExecutor, + accounts_by_addr: &mut HashMap, + addrs: &[move_core_types::account_address::AccountAddress], +) { + for addr in addrs.iter().copied() { + accounts_by_addr + .entry(addr) + .or_insert_with(|| vm.new_account_at(addr)); + } +} + +#[inline] +pub(crate) fn resolve_function_name( + module: &CompiledModule, + def_idx: FunctionDefinitionIndex, +) -> Result { + let f_handle_idx = module + .function_defs + .get(def_idx.0 as usize) + .ok_or(Corpus::Reject)? + .function; + let ident_idx = module + .function_handles + .get(f_handle_idx.0 as usize) + .ok_or(Corpus::Reject)? + .name; + Ok(module + .identifiers + .get(ident_idx.0 as usize) + .ok_or(Corpus::Reject)? + .clone()) +} + +// Verification wrappers (avoid duplicating serialize/deserialize boilerplate) +pub(crate) fn verify_module_fast( + module: &CompiledModule, + verifier_config: &move_bytecode_verifier::VerifierConfig, + deserializer_config: &DeserializerConfig, +) -> Result<(), Corpus> { + let mut module_code = vec![]; + module + .serialize_for_version(Some(BYTECODE_VERSION), &mut module_code) + .map_err(|_| Corpus::Reject)?; + let m_de = CompiledModule::deserialize_with_config(&module_code, deserializer_config) + .map_err(|_| Corpus::Reject)?; + move_bytecode_verifier::verify_module_with_config(verifier_config, &m_de).map_err(|e| { + check_for_invariant_violation_vmerror(e); + Corpus::Reject + }) +} + +pub(crate) fn verify_script_fast( + script: &CompiledScript, + verifier_config: &move_bytecode_verifier::VerifierConfig, + deserializer_config: &DeserializerConfig, +) -> Result<(), Corpus> { + let mut script_code = vec![]; + script + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_code) + .map_err(|_| Corpus::Reject)?; + let s_de = CompiledScript::deserialize_with_config(&script_code, deserializer_config) + .map_err(|_| Corpus::Reject)?; + move_bytecode_verifier::verify_script_with_config(verifier_config, &s_de).map_err(|e| { + check_for_invariant_violation_vmerror(e); + Corpus::Reject + }) +} + +pub(crate) fn group_modules_by_address_topo( + dep_modules: Vec, +) -> Result>, Corpus> { + let all_modules = dep_modules; + let map = all_modules + .into_iter() + .map(|m| (m.self_id(), m)) + .collect::>(); + let mut order = vec![]; + for id in map.keys() { + let mut visited = HashSet::new(); + sort_by_deps(&map, &mut order, id.clone(), &mut visited)?; + } + + // group same address modules in packages. keep local ordering. + let mut packages: Vec> = Vec::new(); + let mut remaining_modules_map = map.clone(); + for module_id_to_start_package in &order { + if !remaining_modules_map.contains_key(module_id_to_start_package) { + continue; + } + let package_address = module_id_to_start_package.address(); + let mut current_package_for_address: Vec = Vec::new(); + for module_id_in_global_order in &order { + if module_id_in_global_order.address() == package_address { + if let Some(module) = remaining_modules_map.remove(module_id_in_global_order) { + current_package_for_address.push(module); + } + } + } + if !current_package_for_address.is_empty() { + packages.push(current_package_for_address); + } + } + Ok(packages) +} + fn publish_transaction_payload(modules: &[CompiledModule]) -> TransactionPayload { let modules_metadatas: Vec<_> = modules .iter() @@ -114,7 +242,7 @@ fn publish_transaction_payload(modules: &[CompiledModule]) -> TransactionPayload name: cm.name().to_string(), source: vec![], source_map: vec![], - extension: MoveOption::default(), + extension: None, }) .collect(); @@ -138,14 +266,14 @@ fn publish_transaction_payload(modules: &[CompiledModule]) -> TransactionPayload manifest: vec![], modules: modules_metadatas, deps: all_immediate_deps, - extension: MoveOption::default(), + extension: None, }; let pkg_metadata = bcs::to_bytes(&metadata).expect("PackageMetadata must serialize"); let mut pkg_code: Vec> = vec![]; for module in modules { let mut module_code: Vec = vec![]; module - .serialize(&mut module_code) + .serialize_for_version(Some(BYTECODE_VERSION), &mut module_code) .expect("Module must serialize"); pkg_code.push(module_code); } @@ -158,7 +286,7 @@ const KNOWN_FALSE_POSITIVES_VMSTATUS: &[&str] = &["moving container with danglin // panic to catch invariant violations pub(crate) fn check_for_invariant_violation(e: VMStatus) { - let is_known_false_positive = e.message().map_or(false, |msg| { + let is_known_false_positive = e.message().is_some_and(|msg| { KNOWN_FALSE_POSITIVES_VMSTATUS .iter() .any(|known| msg.starts_with(known)) @@ -175,12 +303,100 @@ pub(crate) fn check_for_invariant_violation(e: VMStatus) { } } +// For VMError (verifier) invariants. +const KNOWN_FALSE_POSITIVES_VMERROR: &[&str] = + &["too many type parameters/arguments in the program"]; + +pub(crate) fn check_for_invariant_violation_vmerror(e: VMError) { + if e.status_type() == StatusType::InvariantViolation { + let is_known_false_positive = e.message().is_some_and(|msg| { + KNOWN_FALSE_POSITIVES_VMERROR + .iter() + .any(|known| msg.starts_with(known)) + }); + + if !is_known_false_positive { + panic!( + "invariant violation {:?}\n{}{:?} {}", + e, + "RUST_BACKTRACE=1 DEBUG_VM_STATUS=", + e.major_status(), + "./fuzz.sh run move_aptosvm_publish_and_run " + ); + } + } +} + +// Optional block execution wrapper — useful for consistent error mapping +#[inline] +pub(crate) fn execute_block_or_keep( + vm: &FakeExecutor, + block: Vec, +) -> Result, Corpus> { + let requested = block.len(); + vm.execute_block(block) + .map(|mut outputs| { + // Trim any appended BlockEpilogue to preserve outputs.len() == requested. + if outputs.len() > requested { + outputs.truncate(requested); + } + outputs + }) + .map_err(|e| { + check_for_invariant_violation(e); + Corpus::Keep + }) +} + +#[inline] +pub(crate) fn sign_single_or_multi( + raw_tx: RawTransaction, + sender_acc: &Account, + secondary_addrs: &[move_core_types::account_address::AccountAddress], + accounts_by_addr: &HashMap, +) -> Result { + if secondary_addrs.is_empty() { + return raw_tx + .sign( + &sender_acc.privkey, + sender_acc.pubkey.as_ed25519().expect("ed25519 public key"), + ) + .map_err(|_| Corpus::Reject) + .map(|c| c.into_inner()); + } + + let secondary_accounts: Vec<_> = secondary_addrs + .iter() + .map(|a| accounts_by_addr.get(a).expect("secondary account exists")) + .collect(); + let secondary_privs = secondary_accounts.iter().map(|a| &a.privkey).collect(); + raw_tx + .sign_multi_agent( + &sender_acc.privkey, + secondary_addrs.to_vec(), + secondary_privs, + ) + .map_err(|_| Corpus::Reject) + .map(|c| c.into_inner()) +} + +// Shared sequential block metadata across all cached publishes and executions in this fuzzer. +// Ensures AptosModuleCacheManager sees consecutive (parent, child) pairs and preserves caches. +static NEXT_BLOCK_ID: AtomicU64 = AtomicU64::new(1); + +#[inline] +pub(crate) fn next_block_metadata() -> TransactionSliceMetadata { + let child = NEXT_BLOCK_ID.fetch_add(1, Ordering::Relaxed); + TransactionSliceMetadata::block(HashValue::from_u64(child - 1), HashValue::from_u64(child)) +} + pub(crate) fn publish_group( vm: &mut FakeExecutor, acc: &Account, group: &[CompiledModule], sequence_number: u64, ) -> Result<(), Corpus> { + tdbg!("publishing"); let tx = acc .transaction() .gas_unit_price(100) @@ -188,15 +404,8 @@ pub(crate) fn publish_group( .payload(publish_transaction_payload(group)) .sign(); - tdbg!("publishing"); - let res = vm - .execute_block(vec![tx]) - .map_err(|e| { - check_for_invariant_violation(e); - Corpus::Keep - })? - .pop() - .expect("expected 1 output"); + let outputs = execute_block_or_keep(vm, vec![tx])?; + let res = outputs.into_iter().next().expect("expected 1 output"); // if error exit gracefully tdbg!(&res); let status = match tdbg!(res.status()) { @@ -213,7 +422,6 @@ pub(crate) fn publish_group( }, _ => return Err(Corpus::Keep), }; - tdbg!(&status); // apply write set to commit published packages vm.apply_write_set(res.write_set()); match tdbg!(status) { diff --git a/testsuite/fuzzer/src/lib.rs b/testsuite/fuzzer/src/lib.rs new file mode 100644 index 00000000000..64b479b1829 --- /dev/null +++ b/testsuite/fuzzer/src/lib.rs @@ -0,0 +1,9 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod types; +pub mod utils; + +pub use types::{ + Authenticator, ExecVariant, FundAmount, RunnableState, RunnableStateWithOperations, UserAccount, +}; diff --git a/testsuite/fuzzer/src/main.rs b/testsuite/fuzzer/src/main.rs index d6400724b91..00fa6b1e9fc 100644 --- a/testsuite/fuzzer/src/main.rs +++ b/testsuite/fuzzer/src/main.rs @@ -1,7 +1,6 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -mod utils; use clap::{Arg, Command}; fn main() { @@ -67,6 +66,32 @@ fn main() { .index(2), ) ) + .subcommand( + Command::new("generate_transactional_runnable_states_recursive") + .about("Recursively generates transactional runnable states from all .move files under a directory.") + .arg( + Arg::new("base_dir") + .help("Base directory to search for .move files under") + .required(true) + .index(1), + ) + .arg( + Arg::new("destination_path") + .help("Path to write the transactional runnable states to") + .required(true) + .index(2), + ) + ) + .subcommand( + Command::new("generate_runnable_states_from_all_tests") + .about("Generates runnable states from all test sources (e2e, transactional, and compiler v2 tests).") + .arg( + Arg::new("destination_path") + .help("Path to write the runnable states to") + .required(true) + .index(1), + ) + ) .get_matches(); match matches.subcommand() { @@ -74,7 +99,7 @@ fn main() { let module_path = sub_m.get_one::("module_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = utils::cli::compile_federated_jwk(module_path) { + if let Err(e) = fuzzer::utils::cli::compile_federated_jwk(module_path) { eprintln!("Error compiling module: {}", e); std::process::exit(1); } else { @@ -86,7 +111,8 @@ fn main() { let destination_path = sub_m.get_one::("destination_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = utils::cli::generate_runnable_state(csv_path, destination_path) { + if let Err(e) = fuzzer::utils::cli::generate_runnable_state(csv_path, destination_path) + { eprintln!("Error generating runnable state: {}", e); std::process::exit(1); } else { @@ -98,9 +124,10 @@ fn main() { let destination_path = sub_m.get_one::("destination_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = - utils::cli::generate_runnable_state_from_project(project_path, destination_path) - { + if let Err(e) = fuzzer::utils::cli::generate_runnable_state_from_project( + project_path, + destination_path, + ) { eprintln!("Error generating runnable state: {}", e); std::process::exit(1); } else { @@ -113,7 +140,7 @@ fn main() { // Call the function with the provided arguments if let Err(e) = - utils::cli::generate_runnable_states_recursive(base_dir, destination_path) + fuzzer::utils::cli::generate_runnable_states_recursive(base_dir, destination_path) { eprintln!("Error generating runnable states recursively: {}", e); std::process::exit(1); @@ -121,6 +148,37 @@ fn main() { println!("Runnable states generated successfully."); } }, + Some(("generate_transactional_runnable_states_recursive", sub_m)) => { + let base_dir = sub_m.get_one::("base_dir").unwrap(); + let destination_path = sub_m.get_one::("destination_path").unwrap(); + + // Call the function with the provided arguments + if let Err(e) = fuzzer::utils::cli::generate_transactional_runnable_states_recursive( + base_dir, + destination_path, + ) { + eprintln!( + "Error generating transactional runnable states recursively: {}", + e + ); + std::process::exit(1); + } else { + println!("Transactional runnable states generated successfully."); + } + }, + Some(("generate_runnable_states_from_all_tests", sub_m)) => { + let destination_path = sub_m.get_one::("destination_path").unwrap(); + + // Call the function with the provided arguments + if let Err(e) = + fuzzer::utils::cli::generate_runnable_states_from_all_tests(destination_path) + { + eprintln!("Error: {}", e); + std::process::exit(1); + } else { + println!("Runnable states generated successfully from all test sources."); + } + }, // Handle other subcommands or default behavior _ => { println!("No valid subcommand was used. Use --help for more information."); diff --git a/testsuite/fuzzer/src/types.rs b/testsuite/fuzzer/src/types.rs new file mode 100644 index 00000000000..45e860e542d --- /dev/null +++ b/testsuite/fuzzer/src/types.rs @@ -0,0 +1,105 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; +use arbitrary::Arbitrary; +use dearbitrary::Dearbitrary; +use move_binary_format::file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex}; +use move_core_types::{ + language_storage::{ModuleId, TypeTag}, + value::MoveValue, +}; +use move_transactional_test_runner::transactional_ops::TransactionalOperation; + +// Originally from testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +// (with Dearbitrary added and fields made public) +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone, Copy)] +pub enum FundAmount { + Zero, + Poor, + Rich, +} + +// Originally from testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +// (with Dearbitrary added and fields made public) +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone, Copy)] +pub struct UserAccount { + pub is_inited_and_funded: bool, + pub fund: FundAmount, +} + +impl UserAccount { + pub fn fund_amount(&self) -> u64 { + match self.fund { + FundAmount::Zero => 0, + FundAmount::Poor => 1_000, + FundAmount::Rich => 1_000_000_000_000_000, + } + } + + pub fn convert_account(&self, vm: &mut FakeExecutor) -> Account { + if self.is_inited_and_funded { + vm.create_accounts(1, self.fund_amount(), 0).remove(0) + } else { + Account::new() + } + } +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub enum ExecVariant { + Script { + _script: CompiledScript, + _type_args: Vec, + _args: Vec, + }, + CallFunction { + _module: ModuleId, + _function: FunctionDefinitionIndex, + _type_args: Vec, + _args: Vec>, + }, +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] +pub enum Authenticator { + Ed25519 { + _sender: UserAccount, + }, + MultiAgent { + _sender: UserAccount, + _secondary_signers: Vec, + }, + FeePayer { + _sender: UserAccount, + _secondary_signers: Vec, + _fee_payer: UserAccount, + }, +} + +impl Authenticator { + pub fn sender(&self) -> UserAccount { + match self { + Authenticator::Ed25519 { _sender } => *_sender, + Authenticator::MultiAgent { _sender, .. } => *_sender, + Authenticator::FeePayer { _sender, .. } => *_sender, + } + } +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub struct RunnableState { + pub dep_modules: Vec, + pub exec_variant: ExecVariant, + pub tx_auth_type: Authenticator, +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub struct RunnableStateWithOperations { + pub operations: Vec, + pub tx_auth_type: Authenticator, +} diff --git a/testsuite/fuzzer/src/utils.rs b/testsuite/fuzzer/src/utils.rs index c9f4b2a1353..4813993725d 100644 --- a/testsuite/fuzzer/src/utils.rs +++ b/testsuite/fuzzer/src/utils.rs @@ -3,12 +3,18 @@ #[allow(dead_code)] #[allow(unused_variables)] -pub(crate) mod cli { +pub mod cli { + // Import from crate root (lib.rs) + use crate::{ + Authenticator, ExecVariant, FundAmount, RunnableState, RunnableStateWithOperations, + UserAccount, + }; use aptos_framework::{BuildOptions, BuiltPackage}; use aptos_types::{ account_address::AccountAddress, transaction::{EntryFunction, Script, TransactionPayload}, }; + // Import traits for their methods use arbitrary::Arbitrary; use base64::{engine::general_purpose::STANDARD, Engine as _}; use dearbitrary::Dearbitrary; @@ -16,22 +22,49 @@ pub(crate) mod cli { access::ModuleAccess, file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex, SignatureToken}, }; - use move_core_types::{ - ident_str, - identifier::Identifier, - language_storage::{ModuleId, TypeTag}, - value::MoveValue, + use move_core_types::{ident_str, identifier::Identifier, language_storage::ModuleId}; + use move_model::metadata::{CompilerVersion, LanguageVersion}; + // Import official transactional test runner functions + use move_transactional_test_runner::{ + tasks::{taskify, EmptyCommand, TaskCommand, TaskInput}, + vm_test_harness::{ + precompiled_v2_stdlib_fuzzer, AdapterExecuteArgs, AdapterPublishArgs, + PrecompiledFilesModules, + }, }; use rayon::prelude::*; use sha2::{Digest, Sha256}; - use std::{collections::HashMap, fs::File, io::Write, path::PathBuf}; + use std::{ + collections::{HashMap, VecDeque}, + fs::File, + io::Write, + path::PathBuf, + }; use walkdir::WalkDir; + macro_rules! debug_println_error { + ($($arg:tt)*) => { + if std::env::var("DEBUG").unwrap_or_default() == "1" { + println!($($arg)*); + } + }; + } + + /// Standard build options for consistent compilation across the fuzzer + pub(crate) fn standard_build_options() -> BuildOptions { + BuildOptions { + language_version: Some(LanguageVersion::default()), // This is V2_1 (latest stable) + compiler_version: Some(CompilerVersion::latest_stable()), // This is V2_0 + bytecode_version: Some(8), // Use VERSION_MAX to match official transactional test runner + ..BuildOptions::default() + } + } + /// Compiles a Move module from source code. /// The compiled module and its metadata are returned serialized. /// Those can be used to publish the module on-chain via code_publish_package_txn(). - pub(crate) fn compile_federated_jwk(module_path: &str) -> Result<(), String> { - let package = BuiltPackage::build(PathBuf::from(module_path), BuildOptions::default()) + pub fn compile_federated_jwk(module_path: &str) -> Result<(), String> { + let package = BuiltPackage::build(PathBuf::from(module_path), standard_build_options()) .map_err(|e| e.to_string())?; let transaction_payload = generate_script_payload_jwk(&package); @@ -107,63 +140,93 @@ pub(crate) mod cli { )) } - /// Data types for generate VM fuzzer corpora - #[derive(Debug, Eq, PartialEq, arbitrary::Arbitrary, dearbitrary::Dearbitrary)] - pub enum ExecVariant { - Script { - script: CompiledScript, - type_args: Vec, - args: Vec, - }, - CallFunction { - module: ModuleId, - function: FunctionDefinitionIndex, - type_args: Vec, - args: Vec>, - }, + /// Parse a transactional test file + /// + /// This uses the framework taskify function to parse transactional test files + pub fn parse_transactional_test( + file_path: &std::path::Path, + ) -> Result< + VecDeque< + TaskInput< + TaskCommand, + >, + >, + String, + > { + taskify(file_path) + .map(|vec| vec.into_iter().collect()) + .map_err(|e| e.to_string()) } - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub enum FundAmount { - Zero, - Poor, - Rich, - } + /// Convert transactional test to runnable state using the framework's compilation logic + pub fn transactional_test_to_runnable_state( + file_path: &std::path::Path, + pre_compiled_deps: &PrecompiledFilesModules, + ) -> Result { + use move_model::metadata::LanguageVersion; + use move_transactional_test_runner::{ + framework::MoveTestAdapter, + tasks::SyntaxChoice, + transactional_ops::{tasks_to_transactional_operations, MinimalAdapter}, + vm_test_harness::TestRunConfig, + }; - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub struct UserAccount { - pub is_inited_and_funded: bool, - pub fund: FundAmount, - } + // Parse the transactional test file + let mut tasks = parse_transactional_test(file_path)?; + + // Create a minimal test configuration + let run_config = TestRunConfig::new(LanguageVersion::latest(), vec![]); + + let first_task = tasks.pop_front().unwrap(); + let init_opt = match &first_task.command { + TaskCommand::Init(_, _) => Some(first_task.map(|known| match known { + TaskCommand::Init(command, extra_args) => (command, extra_args), + _ => unreachable!(), + })), + _ => { + tasks.push_front(first_task); + None + }, + }; - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub enum Authenticator { - Ed25519 { - sender: UserAccount, - }, - MultiAgent { - sender: UserAccount, - secondary_signers: Vec, - }, - FeePayer { - sender: UserAccount, - secondary_signers: Vec, - fee_payer: UserAccount, - }, - } - #[derive(Debug, Eq, arbitrary::Arbitrary, dearbitrary::Dearbitrary, PartialEq)] - pub struct RunnableState { - pub dep_modules: Vec, - pub exec_variant: ExecVariant, - pub tx_auth_type: Authenticator, + // Create our minimal adapter + let (mut adapter, _init_output) = MinimalAdapter::init( + SyntaxChoice::Source, + run_config, + pre_compiled_deps, + init_opt, + ); + + // Use the framework's helper function to convert tasks to operations + let operations = tasks_to_transactional_operations(&mut adapter, tasks) + .map_err(|e| format!("Failed to convert tasks to operations: {}", e))?; + + if operations.is_empty() { + return Err("No valid operations found in transactional test".to_string()); + } + + // Limit the number of operations to prevent performance issues + const MAX_OPERATIONS: usize = 10; + let operations = if operations.len() > MAX_OPERATIONS { + operations.into_iter().take(MAX_OPERATIONS).collect() + } else { + operations + }; + + Ok(RunnableStateWithOperations { + operations, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }) } /// Convert module to RunnableState data structure /// This is used to run the module in the VM - pub(crate) fn generate_runnable_state( - csv_path: &str, - destination_path: &str, - ) -> Result<(), String> { + pub fn generate_runnable_state(csv_path: &str, destination_path: &str) -> Result<(), String> { std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; let runnable_states = to_runnablestate_from_csv(&read_csv(csv_path)); let mut cnt: usize = 0; @@ -176,11 +239,11 @@ pub(crate) mod cli { let runnable_state_generated = RunnableState::arbitrary_take_rest(u).map_err(|e| e.to_string())?; if runnable_state.0 != runnable_state_generated { - println!( + debug_println_error!( "Failed : {:#?}", runnable_state.0.dep_modules[0] ); - println!("Failed : {:#?} \n", runnable_state.1); + debug_println_error!("Failed : {:#?} \n", runnable_state.1); cnt += 1; } let mut hasher = Sha256::new(); @@ -215,25 +278,19 @@ pub(crate) mod cli { record.get(2).unwrap() ), }; - /* - let bytecode: Vec = match hex::decode(decoded_bytecode.clone()) { - Ok(bytecode) => bytecode, - Err(err) => panic!("Error decoding {:?}, Decoded Error: {:?}, bytecode: {:?}", address, err, decoded_bytecode), - }; - */ let serialized = record.get(2).unwrap(); let account_address = match AccountAddress::from_hex_literal(address) { Ok(addr) => addr, Err(err) => { - eprintln!("Invalid address {}: {:?}", address, err); + debug_println_error!("Invalid address {}: {:?}", address, err); continue; }, }; let identifier = match Identifier::new(module_name) { Ok(id) => id, Err(err) => { - eprintln!("Invalid module name {}: {:?}", module_name, err); + debug_println_error!("Invalid module name {}: {:?}", module_name, err); continue; }, }; @@ -241,7 +298,7 @@ pub(crate) mod cli { let compiled_module = match CompiledModule::deserialize(&bytecode) { Ok(module) => module, Err(err) => { - eprintln!("Error deserializing module: {:?}", err); + debug_println_error!("Error deserializing module: {:?}", err); continue; // Skip to the next iteration of the loop }, }; @@ -258,13 +315,13 @@ pub(crate) mod cli { let runnable_state = RunnableState { dep_modules: vec![tuple.0.to_owned()], exec_variant: ExecVariant::CallFunction { - module: module_id.to_owned(), - function: FunctionDefinitionIndex::new(0), - type_args: vec![], - args: vec![], + _module: module_id.to_owned(), + _function: FunctionDefinitionIndex::new(0), + _type_args: vec![], + _args: vec![], }, tx_auth_type: Authenticator::Ed25519 { - sender: UserAccount { + _sender: UserAccount { is_inited_and_funded: true, fund: FundAmount::Rich, }, @@ -284,151 +341,248 @@ pub(crate) mod cli { } } - fn to_runnablestate_from_package(package: &BuiltPackage) -> Result { + fn to_runnablestate_from_script( + script: Vec, + all_modules: &[CompiledModule], + ) -> Result { + let compiled_script = CompiledScript::deserialize(&script) + .map_err(|e| format!("Failed to deserialize script: {}", e))?; + + Ok(RunnableState { + dep_modules: all_modules.to_vec(), // TODO: Check which module in all_modules is actually a dependency + exec_variant: ExecVariant::Script { + _script: compiled_script, + _type_args: vec![], // Default to no type args + _args: vec![], // Default to no args + }, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }) + } + + // TODO: Refactor to build arguments for the function + // TODO2: Check which module in all_modules is actually a dependency + fn to_runnablestate_from_module( + module: CompiledModule, + all_modules: &[CompiledModule], + ) -> Result, String> { + let mut runnable_states = Vec::new(); + + // Find all entry functions in the module + for (func_idx, func_def) in module.function_defs.iter().enumerate() { + if func_def.is_entry { + let module_id = module.self_id(); + let function_handle = &module.function_handles[func_def.function.0 as usize]; + + // Skip generic functions + if !function_handle.type_parameters.is_empty() { + debug_println_error!( + "Skipping generic entry function {}::{}", + module_id, + module.identifier_at(function_handle.name) + ); + continue; + } + + let function_signature = &module.signatures[function_handle.parameters.0 as usize]; + + // Skip functions with non-signer parameters after signer parameters + if !function_signature.0.is_empty() + && !is_signer_or_reference(&function_signature.0[0]) + { + debug_println_error!( + "Skipping function {}::{} with non-signer parameters after signer", + module_id, + module.identifier_at(function_handle.name) + ); + continue; + } + + let runnable_state = RunnableState { + dep_modules: all_modules.to_vec(), + exec_variant: ExecVariant::CallFunction { + _module: module_id, + _function: FunctionDefinitionIndex::new(func_idx as u16), + _type_args: vec![], + _args: vec![], + }, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }; + + runnable_states.push(runnable_state); + } + } + + Ok(runnable_states) + } + + fn to_runnablestate_from_package(package: &BuiltPackage) -> Result, String> { + let mut runnable_states = Vec::new(); let modules = package.extract_code(); + let scripts = package.extract_script_code(); - // Create a vector to hold all compiled modules + // Process all modules let mut compiled_modules = Vec::new(); - for module_bytes in modules { if let Ok(module) = CompiledModule::deserialize(&module_bytes) { compiled_modules.push(module); } } - if compiled_modules.is_empty() { - return Err("No valid modules found in package".to_string()); - } - - // Find the first module with an entry function - let mut primary_module = None; - let mut function_def_idx = None; - + // Process each module for module in &compiled_modules { - for (idx, func_def) in module.function_defs.iter().enumerate() { - if func_def.is_entry { - primary_module = Some(module); - function_def_idx = Some(idx); - break; - } - } - if primary_module.is_some() { - break; + match to_runnablestate_from_module(module.clone(), &compiled_modules) { + Ok(states) => runnable_states.extend(states), + Err(e) => { + debug_println_error!("Failed to process module {}: {}", module.self_id(), e) + }, } } - // If no entry function found, use the first function of the first module - let (primary_module, function_def_idx) = if let (Some(module), Some(idx)) = - (primary_module, function_def_idx) - { - (module, idx) - } else if !compiled_modules.is_empty() && !compiled_modules[0].function_defs.is_empty() { - (&compiled_modules[0], 0) - } else { - return Err("No functions found in any module".to_string()); - }; - - let module_id = primary_module.self_id(); - let function_def = &primary_module.function_defs[function_def_idx]; - let function_handle = &primary_module.function_handles[function_def.function.0 as usize]; - - // Check if the function has type parameters (is generic) - let has_type_params = !function_handle.type_parameters.is_empty(); - - // Return error if the function is generic - if has_type_params { - return Err(format!( - "Entry function {}::{} has {} type parameters. Generic entry functions are not supported.", - module_id, - primary_module.identifier_at(function_handle.name), - function_handle.type_parameters.len() - )); + // Process all scripts + for script in scripts { + match to_runnablestate_from_script(script, &compiled_modules) { + Ok(state) => runnable_states.push(state), + Err(e) => debug_println_error!("Failed to process script: {}", e), + } } - let type_args = vec![]; - - let function_signature = &primary_module.signatures[function_handle.parameters.0 as usize]; - - // Check if there are any non-signer parameters after the signer parameters - let has_non_signer_params = if !function_signature.0.is_empty() { - !is_signer_or_reference(&function_signature.0[0]) - } else { - false - }; - - let args = if has_non_signer_params { - return Err( - "Entry function has non-signer parameters after signer parameters".to_string(), - ); - } else { - vec![] - }; - - println!( - "Using module: {}, function idx: {}", - module_id, function_def_idx - ); - - // Create a single runnable state with all modules as dependencies - let runnable_state = RunnableState { - dep_modules: compiled_modules, - exec_variant: ExecVariant::CallFunction { - module: module_id, - function: FunctionDefinitionIndex::new(function_def_idx as u16), - type_args, - args, - }, - tx_auth_type: Authenticator::Ed25519 { - sender: UserAccount { - is_inited_and_funded: true, - fund: FundAmount::Rich, - }, - }, - }; + if runnable_states.is_empty() { + return Err("No valid runnable states found in package".to_string()); + } - Ok(runnable_state) + Ok(runnable_states) } fn compile_source_code_from_project(project_path: &str) -> Result { - let package = BuiltPackage::build(PathBuf::from(project_path), BuildOptions::default()) - .map_err(|e| e.to_string())?; - - Ok(package) + // Wrap the build in catch_unwind to handle panics + match std::panic::catch_unwind(|| { + BuiltPackage::build( + PathBuf::from(project_path), + BuildOptions::move_2().set_latest_language(), + ) + }) { + Ok(result) => result.map_err(|e| e.to_string()), + Err(e) => { + let error_msg = if let Some(s) = e.downcast_ref::() { + s.clone() + } else if let Some(s) = e.downcast_ref::<&str>() { + s.to_string() + } else { + "Unknown panic during build".to_string() + }; + Err(format!("Build panicked: {}", error_msg)) + }, + } } - //Generate Runnable State from Project folder - //It can be used to create custom Move packages to extend coverage as needed - //Inside data folder, at the left level of the project, you can find some examples - pub(crate) fn generate_runnable_state_from_project( + /// Given a path to a project directory and a destination path, + /// this function compiles the project, converts it into RunnableState(s), + /// and writes these states to individual files in the destination directory. + pub fn generate_runnable_state_from_project( project_path: &str, destination_path: &str, ) -> Result<(), String> { std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; - let package = compile_source_code_from_project(project_path)?; - let runnable_state = to_runnablestate_from_package(&package)?; + // Transactional tests come as a single .move file + let path = std::path::Path::new(project_path); + if path.is_file() + && path + .extension() + .and_then(|ext| ext.to_str()) + .is_some_and(|ext| ext == "move") + { + let pre_compiled_deps = precompiled_v2_stdlib_fuzzer(); + match transactional_test_to_runnable_state(path, pre_compiled_deps) { + Ok(runnable_state) => { + if runnable_state.operations.is_empty() { + return Err("No valid operations found in transactional test".to_string()); + } + + let bytes = runnable_state.dearbitrary_first().finish(); + let mut hasher = Sha256::new(); + hasher.update(&bytes); + let hash = hasher.finalize(); + + let filename = format!( + "{}/transactional_test_{}.bytes", + destination_path, + hex::encode(hash) + ); + + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { + debug_println_error!( + "Failed to write transactional test {}: {}", + project_path, + e + ); + } else { + println!("Transactional test saved to {}", filename); + } + + return Ok(()); + }, + Err(e) => { + return Err(e); + }, + } + } - println!("Generated runnable state from package"); + let package = compile_source_code_from_project(project_path)?; + let runnable_states = to_runnablestate_from_package(&package)?; - // Serialize the runnable state - let bytes = runnable_state.dearbitrary_first().finish(); + for (idx, runnable_state) in runnable_states.into_iter().enumerate() { + // Serialize the runnable state + let bytes = runnable_state.dearbitrary_first().finish(); + let mut hasher = Sha256::new(); + hasher.update(&bytes); + let hash = hasher.finalize(); - // Generate a filename based on hash - let mut hasher = Sha256::new(); - hasher.update(&bytes); - let hash = hasher.finalize(); - let filename = format!("{}/{}.bytes", destination_path, hex::encode(hash)); + // Generate filename based on the type of runnable state + let filename = match &runnable_state.exec_variant { + ExecVariant::Script { .. } => { + format!("{}/script_{}.bytes", destination_path, hex::encode(hash)) + }, + ExecVariant::CallFunction { + _module: module, .. + } => { + let mut hasher = Sha256::new(); + hasher.update(&bytes); + format!( + "{}/module_{}_{}.bytes", + destination_path, + module, + hex::encode(hasher.finalize()) + ) + }, + }; - // Write to file - let mut file = File::create(&filename).map_err(|e| e.to_string())?; - file.write_all(&bytes).map_err(|e| e.to_string())?; - println!("Runnable state saved to {}", filename); + // Write to file + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { + debug_println_error!("Failed to write runnable state {}: {}", idx, e); + } else { + println!("Runnable state saved to {}", filename); + } + } Ok(()) } - //Generate Runnable States recursively from all Move.toml projects under base directory - pub(crate) fn generate_runnable_states_recursive( + /// Recursively finds all Move.toml files within a given base directory, + /// compiles each corresponding project, converts them into RunnableState(s), + /// and writes these states to individual files in a specified destination directory. + /// Skips any projects that fail to compile or convert. + pub fn generate_runnable_states_recursive( base_dir: &str, destination_path: &str, ) -> Result<(), String> { @@ -452,41 +606,224 @@ pub(crate) mod cli { match compile_source_code_from_project(project_dir) { Ok(package) => { match to_runnablestate_from_package(&package) { + Ok(runnable_states) => { + println!("Generated runnable states from package at {}", project_dir); + + // Serialize the runnable states + for (idx, runnable_state) in runnable_states.into_iter().enumerate() { + let bytes = runnable_state.dearbitrary_first().finish(); + + // Generate filename based on the type of runnable state + let filename = match &runnable_state.exec_variant { + ExecVariant::Script { .. } => { + format!("{}/script_{}.bytes", destination_path, idx) + }, + ExecVariant::CallFunction { + _module: module, .. + } => { + let mut hasher = Sha256::new(); + hasher.update(&bytes); + format!( + "{}/module_{}_{}.bytes", + destination_path, + module, + hex::encode(hasher.finalize()) + ) + }, + }; + + // Write to file + if let Err(e) = + File::create(&filename).and_then(|mut f| f.write_all(&bytes)) + { + debug_println_error!( + "Failed to write runnable state {}: {}", + idx, + e + ); + } else { + println!("Runnable state saved to {}", filename); + } + } + }, + Err(e) => { + debug_println_error!( + "Failed to generate runnable states for {}: {}", + project_dir, + e + ); + }, + } + }, + Err(e) => { + debug_println_error!("Failed to compile project at {}: {}", project_dir, e); + }, + } + }); + + Ok(()) + } + + /// Generates runnable states from all known test sources, including + /// e2e tests, transactional tests, and compiler v2 tests. + /// The generated states are written to individual files in the specified destination directory. + /// This function leverages precompiled standard library modules for efficiency. + pub fn generate_runnable_states_from_all_tests(destination_path: &str) -> Result<(), String> { + std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; + + // Build once the framework + let pre_compiled_deps = precompiled_v2_stdlib_fuzzer(); + + // Process transactional tests from move-compiler-v2 + let transactional_test_dirs = vec![ + "", + "../../third_party/move/move-compiler-v2/transactional-tests/tests", + ]; + + for test_dir in transactional_test_dirs { + if std::path::Path::new(test_dir).exists() { + println!("Processing transactional tests from: {}", test_dir); + + for entry in WalkDir::new(test_dir) + .follow_links(false) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|entry| entry.path().extension().is_some_and(|ext| ext == "move")) + { + match transactional_test_to_runnable_state(entry.path(), pre_compiled_deps) { Ok(runnable_state) => { - println!("Generated runnable state from package at {}", project_dir); + if runnable_state.operations.is_empty() { + debug_println_error!("Skipping empty transactional test (no operations produced): {}", entry.path().display()); + continue; + } - // Serialize the runnable state let bytes = runnable_state.dearbitrary_first().finish(); - - // Generate a filename based on hash let mut hasher = Sha256::new(); hasher.update(&bytes); let hash = hasher.finalize(); - let filename = - format!("{}/{}.bytes", destination_path, hex::encode(hash)); - // Write to file + let filename = format!( + "{}/transactional_test_{}.bytes", + destination_path, + hex::encode(hash) + ); + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { - println!( - "Failed to write runnable state for {}: {}", - project_dir, e + debug_println_error!( + "Failed to write transactional test {}: {}", + entry.path().display(), + e ); } else { - println!("Runnable state saved to {}", filename); + println!("Transactional test saved to {}", filename); } }, Err(e) => { - println!( - "Failed to generate runnable state for {}: {}", - project_dir, e - ); + // More detailed error logging + if e.contains("No valid operations found") + || e.contains("Skipping unsupported task command") + || e.contains("must be the first command") + { + // These might be benign (e.g. test file with only //# init or specific ordering issues) + debug_println_error!( + "Skipping transactional test {}: {}", + entry.path().display(), + e + ); + } else { + // eprintln is better for user-facing errors if this becomes a CLI tool part + // For fuzzer internal logic, debug_println_error or a dedicated logger is fine. + debug_println_error!( + "Error processing transactional test {}: {}", + entry.path().display(), + e + ); + } }, } + } + } + } + + // Process Move projects recursively from common test directories + let move_test_dirs = vec![ + //"../../aptos-move/move-examples", + //"../../aptos-move/e2e-move-tests", + ]; + + for test_dir in move_test_dirs { + if std::path::Path::new(test_dir).exists() { + println!("Processing Move projects from: {}", test_dir); + if let Err(e) = generate_runnable_states_recursive(test_dir, destination_path) { + debug_println_error!("Failed to process {}: {}", test_dir, e); + } + } + } + Ok(()) + } + + /// Recursively finds all transactional `.move` test files under `base_dir`, + /// converts each into a `RunnableStateWithOperations` using the transactional + /// test runner, and writes the serialized bytes to `destination_path`. + /// Files that fail to convert or produce no operations are skipped. + pub fn generate_transactional_runnable_states_recursive( + base_dir: &str, + destination_path: &str, + ) -> Result<(), String> { + std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; + + let pre_compiled_deps = precompiled_v2_stdlib_fuzzer(); + + let test_files: Vec<_> = WalkDir::new(base_dir) + .follow_links(false) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|entry| entry.path().extension().is_some_and(|ext| ext == "move")) + .map(|entry| entry.path().to_path_buf()) + .collect(); + + println!("Found {} transactional test files", test_files.len()); + + test_files.par_iter().for_each(|path| { + match transactional_test_to_runnable_state(path, pre_compiled_deps) { + Ok(runnable_state) => { + if runnable_state.operations.is_empty() { + debug_println_error!( + "Skipping empty transactional test (no operations produced): {}", + path.display() + ); + return; + } + + let bytes = runnable_state.dearbitrary_first().finish(); + let mut hasher = Sha256::new(); + hasher.update(&bytes); + let hash = hasher.finalize(); + + let filename = format!( + "{}/transactional_test_{}.bytes", + destination_path, + hex::encode(hash) + ); + + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { + debug_println_error!( + "Failed to write transactional test {}: {}", + path.display(), + e + ); + } else { + println!("Transactional test saved to {}", filename); + } }, Err(e) => { - println!("Failed to compile project at {}: {}", project_dir, e); + debug_println_error!( + "Error processing transactional test {}: {}", + path.display(), + e + ); }, } }); diff --git a/testsuite/generate-format/src/api.rs b/testsuite/generate-format/src/api.rs index d519dfda1f1..9ab0edafc1e 100644 --- a/testsuite/generate-format/src/api.rs +++ b/testsuite/generate-format/src/api.rs @@ -97,6 +97,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. // stdlib types tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; @@ -105,6 +106,7 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; @@ -120,7 +122,8 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; // events tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/aptos.rs b/testsuite/generate-format/src/aptos.rs index 9760854c559..9169a1d39eb 100644 --- a/testsuite/generate-format/src/aptos.rs +++ b/testsuite/generate-format/src/aptos.rs @@ -91,6 +91,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; @@ -99,6 +100,7 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; @@ -107,7 +109,8 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/consensus.rs b/testsuite/generate-format/src/consensus.rs index f79142cca93..8bbbf05c530 100644 --- a/testsuite/generate-format/src/consensus.rs +++ b/testsuite/generate-format/src/consensus.rs @@ -90,6 +90,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; @@ -98,12 +99,14 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/move_abi.rs b/testsuite/generate-format/src/move_abi.rs index f07d8b27fb4..26dffb6ea0a 100644 --- a/testsuite/generate-format/src/move_abi.rs +++ b/testsuite/generate-format/src/move_abi.rs @@ -19,6 +19,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; // aliases within StructTag diff --git a/testsuite/generate-format/tests/staged/api.yaml b/testsuite/generate-format/tests/staged/api.yaml index bfcaceda30d..3e5dde383be 100644 --- a/testsuite/generate-format/tests/staged/api.yaml +++ b/testsuite/generate-format/tests/staged/api.yaml @@ -13,19 +13,25 @@ AbortLocation: TYPENAME: ModuleId 1: Script: UNIT -AbstractionAuthData: +AbstractAuthenticationData: ENUM: 0: V1: STRUCT: - signing_message_digest: BYTES - - authenticator: BYTES + - abstract_signature: BYTES 1: DerivableV1: STRUCT: - signing_message_digest: BYTES - abstract_signature: BYTES - abstract_public_key: BYTES +AbstractAuthenticator: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractAuthenticationData AccessPath: STRUCT: - address: @@ -65,12 +71,10 @@ AccountAuthenticator: 4: NoAccountAuthenticator: UNIT 5: - Abstraction: + Abstract: STRUCT: - - function_info: - TYPENAME: FunctionInfo - - auth_data: - TYPENAME: AbstractionAuthData + - authenticator: + TYPENAME: AbstractAuthenticator AggregateSignature: STRUCT: - validator_bitmask: @@ -159,6 +163,15 @@ BlockEpiloguePayload: TYPENAME: HashValue - block_end_info: TYPENAME: BlockEndInfo + 1: + V1: + STRUCT: + - block_id: + TYPENAME: HashValue + - block_end_info: + TYPENAME: BlockEndInfo + - fee_distribution: + TYPENAME: FeeDistribution BlockMetadata: STRUCT: - id: @@ -256,6 +269,37 @@ Ed25519PublicKey: NEWTYPESTRUCT: BYTES Ed25519Signature: NEWTYPESTRUCT: BYTES +EncryptedPayload: + ENUM: + 0: + Encrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + 1: + FailedDecryption: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + 2: + Decrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + - executable: + TYPENAME: TransactionExecutable + - decryption_nonce: U64 EntryFunction: STRUCT: - module: @@ -343,20 +387,43 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 FunctionInfo: STRUCT: - module_address: TYPENAME: AccountAddress - module_name: STR - function_name: STR +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: @@ -660,6 +727,27 @@ TransactionArgument: 9: Serialized: NEWTYPE: BYTES + 10: + I8: + NEWTYPE: I8 + 11: + I16: + NEWTYPE: I16 + 12: + I32: + NEWTYPE: I32 + 13: + I64: + NEWTYPE: I64 + 14: + I128: + NEWTYPE: I128 + 15: + I256: + NEWTYPE: + TUPLEARRAY: + CONTENT: U8 + SIZE: 32 TransactionAuthenticator: ENUM: 0: @@ -759,7 +847,7 @@ TransactionInfoV0: - state_checkpoint_hash: OPTION: TYPENAME: HashValue - - state_cemetery_hash: + - auxiliary_info_hash: OPTION: TYPENAME: HashValue TransactionOnChainData: @@ -798,6 +886,10 @@ TransactionPayload: Payload: NEWTYPE: TYPENAME: TransactionPayloadInner + 5: + EncryptedPayload: + NEWTYPE: + TYPENAME: EncryptedPayload TransactionPayloadInner: ENUM: 0: @@ -839,6 +931,18 @@ TypeTag: Function: NEWTYPE: TYPENAME: FunctionTag + 12: + i8: UNIT + 13: + i16: UNIT + 14: + i32: UNIT + 15: + i64: UNIT + 16: + i128: UNIT + 17: + i256: UNIT ValidatorTransaction: ENUM: 0: diff --git a/testsuite/generate-format/tests/staged/aptos.yaml b/testsuite/generate-format/tests/staged/aptos.yaml index 731db6591d8..abc413092b0 100644 --- a/testsuite/generate-format/tests/staged/aptos.yaml +++ b/testsuite/generate-format/tests/staged/aptos.yaml @@ -1,19 +1,25 @@ --- AbilitySet: NEWTYPESTRUCT: U8 -AbstractionAuthData: +AbstractAuthenticationData: ENUM: 0: V1: STRUCT: - signing_message_digest: BYTES - - authenticator: BYTES + - abstract_signature: BYTES 1: DerivableV1: STRUCT: - signing_message_digest: BYTES - abstract_signature: BYTES - abstract_public_key: BYTES +AbstractAuthenticator: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractAuthenticationData AccessPath: STRUCT: - address: @@ -53,12 +59,10 @@ AccountAuthenticator: 4: NoAccountAuthenticator: UNIT 5: - Abstraction: + Abstract: STRUCT: - - function_info: - TYPENAME: FunctionInfo - - auth_data: - TYPENAME: AbstractionAuthData + - authenticator: + TYPENAME: AbstractAuthenticator AggregateSignature: STRUCT: - validator_bitmask: @@ -147,6 +151,15 @@ BlockEpiloguePayload: TYPENAME: HashValue - block_end_info: TYPENAME: BlockEndInfo + 1: + V1: + STRUCT: + - block_id: + TYPENAME: HashValue + - block_end_info: + TYPENAME: BlockEndInfo + - fee_distribution: + TYPENAME: FeeDistribution BlockMetadata: STRUCT: - id: @@ -233,6 +246,37 @@ Ed25519PublicKey: NEWTYPESTRUCT: BYTES Ed25519Signature: NEWTYPESTRUCT: BYTES +EncryptedPayload: + ENUM: + 0: + Encrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + 1: + FailedDecryption: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + 2: + Decrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + - executable: + TYPENAME: TransactionExecutable + - decryption_nonce: U64 EntryFunction: STRUCT: - module: @@ -289,20 +333,43 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 FunctionInfo: STRUCT: - module_address: TYPENAME: AccountAddress - module_name: STR - function_name: STR +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: @@ -592,6 +659,27 @@ TransactionArgument: 9: Serialized: NEWTYPE: BYTES + 10: + I8: + NEWTYPE: I8 + 11: + I16: + NEWTYPE: I16 + 12: + I32: + NEWTYPE: I32 + 13: + I64: + NEWTYPE: I64 + 14: + I128: + NEWTYPE: I128 + 15: + I256: + NEWTYPE: + TUPLEARRAY: + CONTENT: U8 + SIZE: 32 TransactionAuthenticator: ENUM: 0: @@ -683,6 +771,10 @@ TransactionPayload: Payload: NEWTYPE: TYPENAME: TransactionPayloadInner + 5: + EncryptedPayload: + NEWTYPE: + TYPENAME: EncryptedPayload TransactionPayloadInner: ENUM: 0: @@ -724,6 +816,18 @@ TypeTag: Function: NEWTYPE: TYPENAME: FunctionTag + 12: + i8: UNIT + 13: + i16: UNIT + 14: + i32: UNIT + 15: + i64: UNIT + 16: + i128: UNIT + 17: + i256: UNIT ValidatorTransaction: ENUM: 0: diff --git a/testsuite/generate-format/tests/staged/consensus.yaml b/testsuite/generate-format/tests/staged/consensus.yaml index 69ddf732872..d6117e0fe3d 100644 --- a/testsuite/generate-format/tests/staged/consensus.yaml +++ b/testsuite/generate-format/tests/staged/consensus.yaml @@ -1,19 +1,25 @@ --- AbilitySet: NEWTYPESTRUCT: U8 -AbstractionAuthData: +AbstractAuthenticationData: ENUM: 0: V1: STRUCT: - signing_message_digest: BYTES - - authenticator: BYTES + - abstract_signature: BYTES 1: DerivableV1: STRUCT: - signing_message_digest: BYTES - abstract_signature: BYTES - abstract_public_key: BYTES +AbstractAuthenticator: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractAuthenticationData AccessPath: STRUCT: - address: @@ -53,12 +59,10 @@ AccountAuthenticator: 4: NoAccountAuthenticator: UNIT 5: - Abstraction: + Abstract: STRUCT: - - function_info: - TYPENAME: FunctionInfo - - auth_data: - TYPENAME: AbstractionAuthData + - authenticator: + TYPENAME: AbstractAuthenticator AggregateSignature: STRUCT: - validator_bitmask: @@ -226,6 +230,15 @@ BlockEpiloguePayload: TYPENAME: HashValue - block_end_info: TYPENAME: BlockEndInfo + 1: + V1: + STRUCT: + - block_id: + TYPENAME: HashValue + - block_end_info: + TYPENAME: BlockEndInfo + - fee_distribution: + TYPENAME: FeeDistribution BlockInfo: STRUCT: - epoch: U64 @@ -345,6 +358,10 @@ BlockType: ProposalExt: NEWTYPE: TYPENAME: ProposalExt + 4: + OptimisticProposal: + NEWTYPE: + TYPENAME: OptBlockBody ChainId: NEWTYPESTRUCT: U8 ChangeSet: @@ -467,6 +484,10 @@ ConsensusMsg: BlockRetrievalRequest: NEWTYPE: TYPENAME: BlockRetrievalRequest + 21: + OptProposalMsg: + NEWTYPE: + TYPENAME: OptProposalMsg ContractEvent: ENUM: 0: @@ -511,6 +532,37 @@ Ed25519PublicKey: NEWTYPESTRUCT: BYTES Ed25519Signature: NEWTYPESTRUCT: BYTES +EncryptedPayload: + ENUM: + 0: + Encrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + 1: + FailedDecryption: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + 2: + Decrypted: + STRUCT: + - ciphertext: BYTES + - extra_config: + TYPENAME: TransactionExtraConfig + - payload_hash: + TYPENAME: HashValue + - eval_proof: BYTES + - executable: + TYPENAME: TransactionExecutable + - decryption_nonce: U64 EntryFunction: STRUCT: - module: @@ -582,20 +634,43 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 FunctionInfo: STRUCT: - module_address: TYPENAME: AccountAddress - module_name: STR - function_name: STR +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: @@ -722,6 +797,35 @@ OpenIdSig: TYPENAME: Pepper - idc_aud_val: OPTION: STR +OptBlockBody: + ENUM: + 0: + V0: + STRUCT: + - validator_txns: + SEQ: + TYPENAME: ValidatorTransaction + - payload: + TYPENAME: Payload + - author: + TYPENAME: AccountAddress + - grandparent_qc: + TYPENAME: QuorumCert +OptBlockData: + STRUCT: + - epoch: U64 + - round: U64 + - timestamp_usecs: U64 + - parent: + TYPENAME: BlockInfo + - block_body: + TYPENAME: OptBlockBody +OptProposalMsg: + STRUCT: + - block_data: + TYPENAME: OptBlockData + - sync_info: + TYPENAME: SyncInfo OptQuorumStorePayload: ENUM: 0: @@ -1101,6 +1205,27 @@ TransactionArgument: 9: Serialized: NEWTYPE: BYTES + 10: + I8: + NEWTYPE: I8 + 11: + I16: + NEWTYPE: I16 + 12: + I32: + NEWTYPE: I32 + 13: + I64: + NEWTYPE: I64 + 14: + I128: + NEWTYPE: I128 + 15: + I256: + NEWTYPE: + TUPLEARRAY: + CONTENT: U8 + SIZE: 32 TransactionAuthenticator: ENUM: 0: @@ -1192,6 +1317,10 @@ TransactionPayload: Payload: NEWTYPE: TYPENAME: TransactionPayloadInner + 5: + EncryptedPayload: + NEWTYPE: + TYPENAME: EncryptedPayload TransactionPayloadInner: ENUM: 0: @@ -1251,6 +1380,18 @@ TypeTag: Function: NEWTYPE: TYPENAME: FunctionTag + 12: + i8: UNIT + 13: + i16: UNIT + 14: + i32: UNIT + 15: + i64: UNIT + 16: + i128: UNIT + 17: + i256: UNIT ValidatorConsensusInfo: STRUCT: - address: diff --git a/testsuite/generate-format/tests/staged/move_abi.yaml b/testsuite/generate-format/tests/staged/move_abi.yaml index 9919ebb6a1f..cc4cfa875fb 100644 --- a/testsuite/generate-format/tests/staged/move_abi.yaml +++ b/testsuite/generate-format/tests/staged/move_abi.yaml @@ -21,14 +21,28 @@ EntryABI: EntryFunction: NEWTYPE: TYPENAME: ScriptFunctionABI +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet Identifier: @@ -108,3 +122,15 @@ TypeTag: Function: NEWTYPE: TYPENAME: FunctionTag + 12: + i8: UNIT + 13: + i16: UNIT + 14: + i32: UNIT + 15: + i64: UNIT + 16: + i128: UNIT + 17: + i256: UNIT diff --git a/testsuite/module-publish/Cargo.toml b/testsuite/module-publish/Cargo.toml deleted file mode 100644 index 5c6305c5bc9..00000000000 --- a/testsuite/module-publish/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "module-publish" -description = "Aptos package binary file generator for Rust" -version = "0.1.0" - -# Workspace inherited keys -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -publish = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[dependencies] -anyhow = { workspace = true } -aptos-transaction-generator-lib = { workspace = true } -clap = { workspace = true } diff --git a/testsuite/module-publish/src/main.rs b/testsuite/module-publish/src/main.rs deleted file mode 100644 index 64ce282fcba..00000000000 --- a/testsuite/module-publish/src/main.rs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::Result; -use aptos_transaction_generator_lib::publishing::prebuild_packages::create_prebuilt_packages_rs_file; -use clap::Parser; - -#[derive(Parser, Debug)] -#[clap( - name = "module-publish", - about = "Write Move packages binaries in a Rust file (raw_module_data.rs). Defaults to \n\ - aptos-core/crates/transaction-workloads-lib/src/raw_module_data.rs" -)] -struct Args { - #[clap(long, help = "Optional output directory for raw_module_data.rs")] - out_dir: Option, -} - -// List of additional packages (beyond those in testsuite/module-publish/src/packages) to include -fn additional_packages() -> Vec<(&'static str, &'static str, bool)> { - // Pairs of (package_name, package_path) - vec![ - ("simple", "src/packages/simple", false), - ( - "framework_usecases", - "src/packages/framework_usecases", - false, - ), - ( - "experimental_usecases", - "src/packages/experimental_usecases", - true, - ), - ("complex", "src/packages/complex", false), - ( - "ambassador_token", - "../../aptos-move/move-examples/token_objects/ambassador", - false, - ), - ( - "aggregator_examples", - "../../aptos-move/move-examples/aggregator_examples", - false, - ), - ( - "bcs_stream", - "../../aptos-move/move-examples/bcs-stream", - false, - ), - ] -} - -// Run "cargo run -p module-publish" to generate the file `raw_module_data.rs`. - -// This file updates `raw_module_data.rs` in -// `crates/transaction-emitter-lib/src/transaction_generator/publishing/` by default, -// or in a provided directory. -// That file contains `Lazy` static variables for the binary of all the packages in -// `testsuite/simple/src/packages` as `Lazy`. -// In `crates/transaction-emitter-lib/src/transaction_generator/publishing` you should -// also find the files that can load, manipulate and use the modules. -// Typically those modules will be altered (publishing at different addresses requires a module -// address rewriting, versioning may benefit from real changes), published and used in transaction. -// Code to conveniently do that should be in that crate. -// -// All of that considered, please be careful when changing this file or the modules in -// `testsuite/simple/src/packages` given that it will likely require -// changes in `crates/transaction-emitter-lib/src/transaction_generator/publishing`. -fn main() -> Result<()> { - let args = Args::parse(); - - let packages_to_build = additional_packages(); - - // build GenericModule - let provided_dir = match &args.out_dir { - None => env!("CARGO_MANIFEST_DIR"), - Some(str) => str, - }; - println!("Building GenericModule in {}", provided_dir); - let base_dir = std::path::Path::new(provided_dir); - // this is gotta be the most brittle solution ever! - // If directory structure changes this breaks. - // However it is a test that is ignored and runs only with the intent of creating files - // for the modules compiled, so people can change it as they wish and need to. - let base_path = base_dir.join("../../crates/transaction-workloads-lib/src/"); - let output_file = base_path.join("raw_module_data.rs"); - - create_prebuilt_packages_rs_file(base_dir, packages_to_build, output_file, true) -} - -#[test] -fn verify_tool() { - use clap::CommandFactory; - Args::command().debug_assert() -} diff --git a/testsuite/module-publish/src/packages/complex/Move.toml b/testsuite/module-publish/src/packages/complex/Move.toml deleted file mode 100644 index 470371e2ae1..00000000000 --- a/testsuite/module-publish/src/packages/complex/Move.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = 'complex' -version = '1.0.0' - -[dependencies] -AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } - -[addresses] -publisher_address = "0xABCD" diff --git a/testsuite/module-publish/src/packages/experimental_usecases/Move.toml b/testsuite/module-publish/src/packages/experimental_usecases/Move.toml deleted file mode 100644 index 6bcfeea82c8..00000000000 --- a/testsuite/module-publish/src/packages/experimental_usecases/Move.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "ExperimentalUsecases" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } -AptosExperimental = { local = "../../../../../aptos-move/framework/aptos-experimental" } -AptosToken = { local = "../../../../../aptos-move/framework/aptos-token" } -AptosTokenObjects = { local = "../../../../../aptos-move/framework/aptos-token-objects" } - -# testing exchanging of constant address works as well. -[addresses] -publisher_address = "0xABCD" diff --git a/testsuite/module-publish/src/packages/experimental_usecases/sources/order_book_example.move b/testsuite/module-publish/src/packages/experimental_usecases/sources/order_book_example.move deleted file mode 100644 index ec9ce4c966b..00000000000 --- a/testsuite/module-publish/src/packages/experimental_usecases/sources/order_book_example.move +++ /dev/null @@ -1,83 +0,0 @@ -module 0xABCD::order_book_example { - use std::signer; - use std::error; - use std::option; - - use aptos_experimental::active_order_book::{Self, ActiveOrderBook}; - use aptos_experimental::order_book::{Self, OrderBook}; - use aptos_experimental::order_book_types; - - const ENOT_AUTHORIZED: u64 = 1; - // Resource being modified doesn't exist - const EDEX_RESOURCE_NOT_PRESENT: u64 = 2; - - struct Empty has store, copy, drop {} - - struct ActiveOnly has key { - active_only: ActiveOrderBook, - } - - struct Dex has key { - order_book: OrderBook, - } - - // Create the global `Dex`. - // Stored under the module publisher address. - fun init_module(publisher: &signer) { - assert!( - signer::address_of(publisher) == @publisher_address, - ENOT_AUTHORIZED, - ); - - move_to( - publisher, - ActiveOnly { active_only: active_order_book::new_active_order_book() } - ); - - move_to( - publisher, - Dex { order_book: order_book::new_order_book() } - ); - } - - public entry fun place_active_post_only_order(sender: address, account_order_id: u64, bid_price: u64, volume: u64, is_buy: bool) acquires ActiveOnly { - assert!(exists(@publisher_address), error::invalid_argument(EDEX_RESOURCE_NOT_PRESENT)); - let active_only = borrow_global_mut(@publisher_address); - - let order_id = order_book_types::new_order_id_type(sender, account_order_id); - // TODO change from random to monothonically increasing value - let unique_priority_idx = order_book_types::generate_unique_idx_fifo_tiebraker(); - - active_only.active_only.place_maker_order( - order_id, - bid_price, - unique_priority_idx, - volume, - is_buy - ); - } - - public entry fun place_order(sender: address, account_order_id: u64, bid_price: u64, volume: u64, is_buy: bool) acquires Dex { - assert!(exists(@publisher_address), error::invalid_argument(EDEX_RESOURCE_NOT_PRESENT)); - let dex = borrow_global_mut(@publisher_address); - dex.order_book.place_order_and_get_matches( - order_book::new_order_request( - sender, // account - account_order_id, - option::none(), // unique_priority_idx, - bid_price, - volume, - volume, - is_buy, - option::none(), // trigger_condition - Empty {}, //metadata - ) - ); - } - - public entry fun cancel_order(account_order_id: u64) acquires Dex { - assert!(exists(@publisher_address), error::invalid_argument(EDEX_RESOURCE_NOT_PRESENT)); - let order_book = borrow_global_mut(@publisher_address); - order_book.order_book.cancel_order(@publisher_address, account_order_id); - } -} diff --git a/testsuite/module-publish/src/packages/framework_usecases/Move.toml b/testsuite/module-publish/src/packages/framework_usecases/Move.toml deleted file mode 100644 index 274cfdd70db..00000000000 --- a/testsuite/module-publish/src/packages/framework_usecases/Move.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "FrameworkUsecases" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } -AptosToken = { local = "../../../../../aptos-move/framework/aptos-token" } -AptosTokenObjects = { local = "../../../../../aptos-move/framework/aptos-token-objects" } - -# testing exchanging of constant address works as well. -[addresses] -publisher_address = "0xABCD" diff --git a/testsuite/module-publish/src/packages/simple/Move.toml b/testsuite/module-publish/src/packages/simple/Move.toml deleted file mode 100644 index 80106222a4c..00000000000 --- a/testsuite/module-publish/src/packages/simple/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "GenericModule" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } diff --git a/testsuite/pangu_lib/tests/add_pfn_test.py b/testsuite/pangu_lib/tests/add_pfn_test.py index b2f4d3e7890..72c48979fda 100644 --- a/testsuite/pangu_lib/tests/add_pfn_test.py +++ b/testsuite/pangu_lib/tests/add_pfn_test.py @@ -75,6 +75,6 @@ def test_add_pfn_live(self) -> None: add_pfn_main(args, system_args) except: self.fail("add_pfn_main() raised exception unexpectedly!") - self.assertEquals(4, len(kubernetes.namespaced_resource_dictionary["default"])) + self.assertEqual(4, len(kubernetes.namespaced_resource_dictionary["default"])) filesystem.assert_reads(self) filesystem.assert_writes(self) diff --git a/testsuite/pyproject.toml b/testsuite/pyproject.toml index 3eb002623c0..234c3177282 100644 --- a/testsuite/pyproject.toml +++ b/testsuite/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Aptos E2E tests and utilities in python, including Forge" authors = [] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = ">=3.8,<4.0" diff --git a/testsuite/replay-verify/archive-pvc-template.yaml b/testsuite/replay-verify/archive-pvc-template.yaml index b70c06b0ead..eeb7c6f83d6 100644 --- a/testsuite/replay-verify/archive-pvc-template.yaml +++ b/testsuite/replay-verify/archive-pvc-template.yaml @@ -8,11 +8,11 @@ metadata: run: some-label spec: accessModes: - - ReadOnlyMany + - ReadWriteOnce resources: requests: - storage: 10Ti - storageClassName: ssd-data-xfs-immediate + storage: 12Ti + storageClassName: pd-balanced-xfs-immediate volumeMode: Filesystem dataSourceRef: name: testnet-archive diff --git a/testsuite/replay-verify/archive_disk_utils.py b/testsuite/replay-verify/archive_disk_utils.py index 9709328355d..878aaaab16a 100644 --- a/testsuite/replay-verify/archive_disk_utils.py +++ b/testsuite/replay-verify/archive_disk_utils.py @@ -14,10 +14,9 @@ ) from typing import Tuple, List, Optional, Any - # Constants DISK_COPIES = 1 -STORAGE_CLASS = "ssd-data-xfs-immediate" +STORAGE_CLASS = "pd-balanced-xfs-immediate" # Logging configuration logging.basicConfig(level=logging.INFO) @@ -34,6 +33,17 @@ NAMESPACE = "replay-verify" ZONE = "us-central1-a" +DEFAULT_PVC_ACCESS_MODE = "ReadOnlyMany" # Default access mode for PVCs +TESTNET_SNAPSHOT_DISK_SIZE = "12Ti" # Default disk size for testnet snapshots +MAINNET_SNAPSHOT_DISK_SIZE = "15Ti" # Default disk size for mainnet snapshots + +def get_disk_size_for_snapshot(snapshot_name: str) -> str: + if TESTNET_SNAPSHOT_NAME in snapshot_name: + return TESTNET_SNAPSHOT_DISK_SIZE + elif MAINNET_SNAPSHOT_NAME in snapshot_name: + return MAINNET_SNAPSHOT_DISK_SIZE + else: + raise ValueError(f"Unknown snapshot name: {snapshot_name}") def get_region_from_zone(zone: str) -> str: return zone.rsplit("-", 1)[0] @@ -508,7 +518,7 @@ def create_one_pvc_from_snapshot( config.load_kube_config() api_instance = client.CoreV1Api() # testnet and mainnet disk size could be different - storage_size = "10Ti" if TESTNET_SNAPSHOT_NAME in snapshot_name else "10Ti" + storage_size = get_disk_size_for_snapshot(snapshot_name) # Define the PVC manifest pvc_manifest = { "apiVersion": "v1", @@ -522,7 +532,7 @@ def create_one_pvc_from_snapshot( "labels": {"run": f"{label}"}, }, "spec": { - "accessModes": ["ReadOnlyMany"], + "accessModes": [DEFAULT_PVC_ACCESS_MODE], "resources": {"requests": {"storage": storage_size}}, "storageClassName": STORAGE_CLASS, "volumeMode": "Filesystem", @@ -626,6 +636,80 @@ def create_replay_verify_pvcs_from_snapshot( return res +def create_one_pvc_from_existing( + pvc_name: str, existing_pvc_name: str, namespace: str, label: str, ttl_secs: int +) -> str: + config.load_kube_config() + api_instance = client.CoreV1Api() + # testnet and mainnet disk size could be different + storage_size = get_disk_size_for_snapshot(existing_pvc_name) + # Define the PVC manifest + pvc_manifest = { + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": { + "name": f"{pvc_name}", + "annotations": { + "volume.kubernetes.io/storage-provisioner": "pd.csi.storage.gke.io", + "k8s-ttl-controller.twin.sh/ttl": f"{ttl_secs}s", + }, + "labels": {"run": f"{label}"}, + }, + "spec": { + "accessModes": [DEFAULT_PVC_ACCESS_MODE], + "resources": {"requests": {"storage": storage_size}}, + "storageClassName": STORAGE_CLASS, + "volumeMode": "Filesystem", + "dataSource": { + "name": f"{existing_pvc_name}", + "kind": "PersistentVolumeClaim", + }, + }, + } + + api_instance.create_namespaced_persistent_volume_claim( + namespace=namespace, body=pvc_manifest + ) + return pvc_name + + +def create_replay_verify_pvcs_from_existing( + run_id: str, + original_snapshot_name: str, + existing_pvc: str, + pvc_num: int, + namespace: str, + label: str, + ttl_secs: int, +) -> List[str]: + config.load_kube_config() + api_instance = client.CoreV1Api() + + tasks = [ + ( + generate_disk_name(run_id, f"{original_snapshot_name}-clone", pvc_id), + existing_pvc, + namespace, + label, + ttl_secs, + ) + for pvc_id in range(pvc_num) + ] + res = [] + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(create_one_pvc_from_existing, *task) for task in tasks + ] + for future in concurrent.futures.as_completed(futures): + try: + result = future.result() + logger.info(f"Task result: {result}") + res.append(result) + except Exception as e: + logger.error(f"Task generated an exception: {e}") + return res + + if __name__ == "__main__": # check input arg network args = parse_args() diff --git a/testsuite/replay-verify/main.py b/testsuite/replay-verify/main.py index efd86aefa63..8929188fb83 100644 --- a/testsuite/replay-verify/main.py +++ b/testsuite/replay-verify/main.py @@ -20,6 +20,7 @@ from archive_disk_utils import ( TESTNET_SNAPSHOT_NAME, MAINNET_SNAPSHOT_NAME, + create_replay_verify_pvcs_from_existing, create_replay_verify_pvcs_from_snapshot, get_kubectl_credentials, ) @@ -93,17 +94,17 @@ def get_env_var(name: str, default_value: str = "") -> str: class ReplayConfig: def __init__(self, network: Network) -> None: if network == Network.TESTNET: - self.concurrent_replayer = 20 - self.pvc_number = 5 + self.concurrent_replayer = 35 + self.pvc_number = 35 self.min_range_size = 10_000 self.range_size = 5_000_000 - self.timeout_secs = 2000 + self.timeout_secs = 9000 else: - self.concurrent_replayer = 18 - self.pvc_number = 8 + self.concurrent_replayer = 35 + self.pvc_number = 10 self.min_range_size = 10_000 self.range_size = 2_000_000 - self.timeout_secs = 1000 + self.timeout_secs = 9000 class WorkerPod: @@ -232,8 +233,17 @@ def start(self) -> None: "--timeout-secs", f"{self.config.timeout_secs}", "--block-cache-size", - "10737418240", + f"{36 * 1024 * 1024 * 1024}", ] + # TODO(ibalajiarun): bump memory limit to 180GiB for heavy ranges + if ( + self.network == Network.TESTNET + and self.start_version >= 6700000000 + and self.end_version < 6800000000 + ): + pod_manifest["spec"]["containers"][0]["resources"]["requests"][ + "memory" + ] = "180Gi" if SHARDING_ENABLED: pod_manifest["spec"]["containers"][0]["command"].append( @@ -313,8 +323,9 @@ def __init__(self, name: str) -> None: self.succeeded: bool = False def set_end_time(self) -> None: - self.end_time = time.time() - self.durations.append(self.end_time - self.start_time) + if self.end_time is None: + self.end_time = time.time() + self.durations.append(self.end_time - self.start_time) def increment_retry_count(self) -> None: self.retry_count += 1 @@ -398,6 +409,9 @@ def sorted_ranges_to_skip(self): list(r) for r in sorted(self.ranges_to_skip) if r[1] >= self.start_version ] + if len(sorted_skips) == 0: + return [] + # merge skip ranges ret = [] current_skip = sorted_skips.pop(0) @@ -409,7 +423,7 @@ def sorted_ranges_to_skip(self): current_skip[1] = max(current_skip[1], next_skip[1]) ret.append(current_skip) - return sorted_skips + return ret def create_tasks(self) -> None: current = self.start_version @@ -423,10 +437,6 @@ def create_tasks(self) -> None: (skip_start, skip_end) = ( (INT64_MAX, INT64_MAX) if len(skips) == 0 else skips[0] ) - if skip_start <= current: - skips.pop(0) - current = skip_end + 1 - continue # TODO(ibalajiarun): temporary hack to handle heavy ranges if ( @@ -442,6 +452,18 @@ def create_tasks(self) -> None: current + range_size, self.end_version + 1, skip_start ) + # Only skip if current is within the skip range + if skip_start <= current <= skip_end: + skips.pop(0) + current = skip_end + 1 + continue + elif skip_start <= next_current - 1 <= skip_end: + # If the next current is within the skip range, we need to adjust it + next_current = skip_start + elif next_current > skip_start: + # If the next current is beyond the skip range, we need to adjust it + next_current = skip_start + # avoid having too many small tasks, simply skip the task range = (current, next_current - 1) if next_current - current >= self.config.min_range_size: @@ -459,15 +481,62 @@ def create_pvc_from_snapshot(self): if self.network == Network.TESTNET else MAINNET_SNAPSHOT_NAME ) + # Because PVCs can be shared among multiple replay-verify runs, a more correct TTL + # would be computed from the number of shards and the expected run time of the replay-verify + # run. However, for simplicity, we set the TTL to 9 hours. + pvc_ttl = 9 * 60 * 60 # 9 hours + pvcs = create_replay_verify_pvcs_from_snapshot( + self.id, + snapshot_name, + self.namespace, + self.config.pvc_number, + self.get_label(), + pvc_ttl, + ) + assert len(pvcs) == self.config.pvc_number, "failed to create all pvcs" + self.pvcs = pvcs + + def create_all_required_pvcs(self) -> None: + snapshot_name = ( + TESTNET_SNAPSHOT_NAME + if self.network == Network.TESTNET + else MAINNET_SNAPSHOT_NAME + ) + pvc = self.create_one_pvc_from_snapshot(snapshot_name) + self.pvcs = [pvc] + # Wait for the PVC to be bound before creating other PVCs + logger.info(f"Waiting for the PVC {pvc} to be bound...") + bound_status = self.get_pvc_bound_status() + while not self.get_pvc_bound_status()[0]: + time.sleep(QUERY_DELAY) + logger.info(f"PVC {pvc} has been bound...") + self.create_pvc_from_existing(snapshot_name, pvc) + + def create_one_pvc_from_snapshot(self, snapshot_name: str) -> str: # Because PVCs can be shared among multiple replay-verify runs, a more correct TTL # would be computed from the number of shards and the expected run time of the replay-verify # run. However, for simplicity, we set the TTL to 3 hours. - pvc_ttl = 5 * 60 * 60 # 3 hours + pvc_ttl = 8 * 60 * 60 # 8 hours pvcs = create_replay_verify_pvcs_from_snapshot( self.id, snapshot_name, self.namespace, + 1, # only create one PVC + self.get_label(), + pvc_ttl, + ) + assert len(pvcs) == 1, "failed to create the PVC" + return pvcs[0] + + # Creates a pvc by cloning an existing pvc + def create_pvc_from_existing(self, original_snapshot_name: str, existing_pvc: str): + pvc_ttl = 8 * 60 * 60 + pvcs = create_replay_verify_pvcs_from_existing( + self.id, + original_snapshot_name, + existing_pvc, self.config.pvc_number, + self.namespace, self.get_label(), pvc_ttl, ) @@ -535,9 +604,9 @@ def schedule(self, from_scratch: bool = False) -> None: if self.current_workers[i] is not None: try: phase = self.current_workers[i].get_phase() - logger.info( - f"Checking worker {i}: {self.current_workers[i].name}: {phase}" - ) + # logger.info( + # f"Checking worker {i}: {self.current_workers[i].name}: {phase}" + # ) except Exception as e: logger.error(f"Failed to get pod status: {e}") self.reschedule_pod(self.current_workers[i], i) @@ -649,12 +718,13 @@ def parse_args() -> argparse.Namespace: "--namespace", required=False, type=str, default="replay-verify" ) parser.add_argument("--image_tag", required=False, type=str) + parser.add_argument("--image_profile", required=False, type=str, default="performance") parser.add_argument("--cleanup", required=False, action="store_true", default=False) args = parser.parse_args() return args -def get_image(image_tag: str | None = None) -> str: +def get_image(profile: str, image_tag: str | None = None) -> str: shell = forge.LocalShell() git = forge.Git(shell) image_name = "tools" @@ -668,7 +738,8 @@ def get_image(image_tag: str | None = None) -> str: if image_tag is None else image_tag ) - full_image = f"{forge.GAR_REPO_NAME}/{image_name}:{default_latest_image}" + tag_prefix = "" if profile == "release" else f"{profile}_" + full_image = f"{forge.GAR_REPO_NAME}/{image_name}:{tag_prefix}{default_latest_image}" return full_image @@ -689,11 +760,11 @@ def print_logs(failed_workpod_logs: list[str], txn_mismatch_logs: list[str]) -> args = parse_args() get_kubectl_credentials("aptos-devinfra-0", "us-central1", "devinfra-usce1-0") (start, end, skip_ranges) = read_skip_ranges(args.network) - image = get_image(args.image_tag) if args.image_tag is not None else get_image() + image = get_image(profile=args.image_profile, image_tag=args.image_tag) run_id = f"{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}-{image[-5:]}" network = Network.from_string(args.network) config = ReplayConfig(network) - worker_cnt = args.worker_cnt if args.worker_cnt else config.pvc_number * 7 + worker_cnt = args.worker_cnt if args.worker_cnt else config.pvc_number * 10 range_size = args.range_size if args.range_size else config.range_size if args.start is not None: @@ -723,7 +794,7 @@ def print_logs(failed_workpod_logs: list[str], txn_mismatch_logs: list[str]) -> scheduler.cleanup() exit(0) else: - scheduler.create_pvc_from_snapshot() + scheduler.create_all_required_pvcs() try: start_time = time.time() scheduler.schedule(from_scratch=True) diff --git a/testsuite/replay-verify/pyproject.toml b/testsuite/replay-verify/pyproject.toml index e893e923c0b..68c7819535d 100644 --- a/testsuite/replay-verify/pyproject.toml +++ b/testsuite/replay-verify/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "replay verify on archive" authors = ["Aptos Labs "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.10" diff --git a/testsuite/replay-verify/replay-verify-worker-template.yaml b/testsuite/replay-verify/replay-verify-worker-template.yaml index becc2aef7e6..39bb2689e5b 100644 --- a/testsuite/replay-verify/replay-verify-worker-template.yaml +++ b/testsuite/replay-verify/replay-verify-worker-template.yaml @@ -4,7 +4,7 @@ metadata: name: worker-pod-9 labels: run: some-label - annotations: {} + annotations: { } spec: serviceAccountName: default restartPolicy: Never # Pod restarts only if it fails @@ -15,29 +15,37 @@ spec: - mountPath: /mnt/archive name: archive readOnly: true # Mount the volume as read-only - command: ["/bin/sh", "-c", "ls -al /mnt/archive && sleep 3600"] + command: [ "/bin/sh", "-c", "ls -al /mnt/archive && sleep 3600" ] env: #- name: PUSH_METRICS_ENDPOINT # value: "http://localhost:9091" - name: RUST_LOG value: "info" + - name: RUST_BACKTRACE + value: "full" resources: requests: - memory: "180Gi" - cpu: "30" - limits: - memory: "180Gi" - cpu: "30" + memory: "100Gi" + cpu: "28" volumes: - name: archive persistentVolumeClaim: claimName: testnet-archive-9 + tolerations: + - key: aptos-workload + operator: Equal + value: "replay-verify" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - - key: cloud.google.com/machine-family - operator: In - values: - - t2d + - key: cloud.google.com/machine-family + operator: In + values: + - "t2d" + - "c3d" + - key: node-restriction.kubernetes.io/aptos-workload + operator: In + values: + - "replay-verify" diff --git a/testsuite/single_node_performance.py b/testsuite/single_node_performance.py index 82a361c5749..e7e7f195385 100755 --- a/testsuite/single_node_performance.py +++ b/testsuite/single_node_performance.py @@ -3,6 +3,7 @@ # Copyright © Aptos Foundation # SPDX-License-Identifier: Apache-2.0 +import math import re import os import tempfile @@ -84,12 +85,14 @@ class Flow(Flag): CODE_PERF_VERSION = "v10" # default to using production number of execution threads for assertions -NUMBER_OF_EXECUTION_THREADS = int( - os.environ.get("NUMBER_OF_EXECUTION_THREADS", default=32) -) +# but cap it at available CPU count to avoid concurrency validation errors +import multiprocessing +MAX_EXECUTION_THREADS = int(os.environ.get("NUMBER_OF_EXECUTION_THREADS", default=32)) +NUMBER_OF_EXECUTION_THREADS = min(MAX_EXECUTION_THREADS, multiprocessing.cpu_count()) if os.environ.get("DETAILED"): - EXECUTION_ONLY_NUMBER_OF_THREADS = [1, 2, 4, 8, 16, 32, 48, 60] + # Cap execution threads at available CPU count + EXECUTION_ONLY_NUMBER_OF_THREADS = [t for t in [1, 2, 4, 8, 16, 32, 48, 60] if t <= multiprocessing.cpu_count()] else: EXECUTION_ONLY_NUMBER_OF_THREADS = [] @@ -261,10 +264,20 @@ class RunGroupConfig: RunGroupConfig(key=RunGroupKey("vector-trim-append-len3000-size1"), included_in=Flow.CONTINUOUS), RunGroupConfig(key=RunGroupKey("vector-remove-insert-len3000-size1"), included_in=Flow.CONTINUOUS), - RunGroupConfig(key=RunGroupKey("order-book-no-matches"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS), - RunGroupConfig(key=RunGroupKey("order-book-balanced-matches25-pct"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS), - RunGroupConfig(key=RunGroupKey("order-book-balanced-matches80-pct"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS), - RunGroupConfig(key=RunGroupKey("order-book-balanced-size-skewed80-pct"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS), + # waived because of missing monotonic counter native. + RunGroupConfig(key=RunGroupKey("order-book-no-matches1-market"), included_in=Flow.ORDER_BOOK, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-matches25-pct1-market"), included_in=Flow.ORDER_BOOK, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-matches80-pct1-market"), included_in=Flow.ORDER_BOOK, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-size-skewed80-pct1-market"), included_in=Flow.ORDER_BOOK, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-no-matches50-markets"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-matches25-pct50-markets"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-matches80-pct50-markets"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("order-book-balanced-size-skewed80-pct50-markets"), included_in=Flow.ORDER_BOOK | Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("monotonic-counter-single"), included_in=Flow.CONTINUOUS, waived=True), + + RunGroupConfig(key=RunGroupKey("fibonacci-recursive20"), included_in=Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("fibonacci-tail-recursive20"), included_in=Flow.CONTINUOUS, waived=True), + RunGroupConfig(key=RunGroupKey("fibonacci-iterative20"), included_in=Flow.CONTINUOUS, waived=True), RunGroupConfig(expected_tps=50000, key=RunGroupKey("coin_transfer_connected_components", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--connected-tx-grps 5000", transaction_type_override=""), included_in=Flow.REPRESENTATIVE, waived=True), RunGroupConfig(expected_tps=50000, key=RunGroupKey("coin_transfer_hotspot", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--hotspot-probability 0.8", transaction_type_override=""), included_in=Flow.REPRESENTATIVE, waived=True), @@ -274,9 +287,9 @@ class RunGroupConfig: RunGroupConfig(expected_tps=15000, key=RunGroupKey("account-generation"), included_in=Flow.MAINNET_LARGE_DB), RunGroupConfig(expected_tps=60, key=RunGroupKey("publish-package"), included_in=Flow.MAINNET_LARGE_DB), RunGroupConfig(expected_tps=6800, key=RunGroupKey("token-v2-ambassador-mint"), included_in=Flow.MAINNET_LARGE_DB), - # RunGroupConfig(expected_tps=17000 if NUM_ACCOUNTS < 5000000 else 28000, key=RunGroupKey("coin_transfer_connected_components", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--connected-tx-grps 5000", transaction_type_override=""), included_in=Flow.MAINNET | Flow.MAINNET_LARGE_DB, waived=True), - # RunGroupConfig(expected_tps=27000 if NUM_ACCOUNTS < 5000000 else 23000, key=RunGroupKey("coin_transfer_hotspot", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--hotspot-probability 0.8", transaction_type_override=""), included_in=Flow.MAINNET | Flow.MAINNET_LARGE_DB, waived=True), -] + [ + RunGroupConfig(expected_tps=17000 if NUM_ACCOUNTS < 5000000 else 28000, key=RunGroupKey("coin_transfer_connected_components", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--connected-tx-grps 5000", transaction_type_override=""), included_in=Flow.MAINNET | Flow.MAINNET_LARGE_DB, waived=True), + RunGroupConfig(expected_tps=27000 if NUM_ACCOUNTS < 5000000 else 23000, key=RunGroupKey("coin_transfer_hotspot", executor_type="sharded"), key_extra=RunGroupKeyExtra(sharding_traffic_flags="--hotspot-probability 0.8", transaction_type_override=""), included_in=Flow.MAINNET | Flow.MAINNET_LARGE_DB, waived=True), +] + [ # no-commit throughput of different executor, used on continuous flow RunGroupConfig( key=RunGroupKey( @@ -663,7 +676,7 @@ def print_table( part for part in line.strip().split(CALIBRATION_SEPARATOR) if part ] ) - >= 1 + >= 3 } print(calibrated_expected_tps) @@ -887,6 +900,14 @@ def print_table( ) if not HIDE_OUTPUT: + def get_tps_delta(r: RunGroupInstance) -> str: + tps = r.single_node_result.tps + if not math.isclose(r.expected_tps, 0): + delta = (tps - r.expected_tps) / r.expected_tps * 100 + return f"{delta:+.2f}%" + else: + return "N/A" + print_table( results, by_levels=True, @@ -894,6 +915,7 @@ def print_table( ("block_size", lambda r: r.block_size), ("expected t/s", lambda r: r.expected_tps), ("t/s", lambda r: int(round(r.single_node_result.tps))), + ("delta", get_tps_delta), ], ) print_table( diff --git a/testsuite/single_node_performance_values.tsv b/testsuite/single_node_performance_values.tsv index c17be81ffe1..1a15f025fd0 100644 --- a/testsuite/single_node_performance_values.tsv +++ b/testsuite/single_node_performance_values.tsv @@ -1,54 +1,58 @@ -no-op 1 VM 56 0.887 1.040 32094.5 -no-op 1000 VM 56 0.887 1.035 30762.7 -apt-fa-transfer 1 VM 56 0.908 1.053 22232.7 -apt-fa-transfer 1 NativeVM 56 0.844 1.148 38636.6 -account-generation 1 VM 57 0.922 1.038 18049.1 -account-generation 1 NativeVM 57 0.856 1.132 39215.5 -account-resource32-b 1 VM 57 0.897 1.036 29851.6 -modify-global-resource 1 VM 57 0.893 1.019 1941.0 -modify-global-resource 100 VM 57 0.906 1.027 27100.2 -publish-package 1 VM 56 0.915 1.025 1051.9 -mix_publish_transfer 1 VM 57 0.903 1.035 17332.1 -batch100-transfer 1 VM 57 0.864 1.051 876.4 -batch100-transfer 1 NativeVM 57 0.794 1.278 1585.4 -vector-picture30k 1 VM 57 0.946 1.027 123.7 -vector-picture30k 100 VM 57 0.630 1.077 2103.7 -smart-table-picture30-k-with200-change 1 VM 57 0.955 1.059 18.1 -smart-table-picture30-k-with200-change 100 VM 57 0.941 1.068 251.2 -modify-global-resource-agg-v2 1 VM 57 0.903 1.040 30704.4 -modify-global-flag-agg-v2 1 VM 57 0.938 1.025 3315.4 -modify-global-bounded-agg-v2 1 VM 56 0.901 1.108 6120.2 -modify-global-milestone-agg-v2 1 VM 57 0.922 1.050 21954.9 -resource-groups-global-write-tag1-kb 1 VM 57 0.913 1.044 7764.2 -resource-groups-global-write-and-read-tag1-kb 1 VM 57 0.919 1.041 4651.7 -resource-groups-sender-write-tag1-kb 1 VM 57 0.821 1.192 20606.2 -resource-groups-sender-multi-change1-kb 1 VM 57 0.770 1.233 17264.6 -token-v1ft-mint-and-transfer 1 VM 57 0.884 1.016 824.4 -token-v1ft-mint-and-transfer 100 VM 57 0.938 1.035 10530.6 -token-v1nft-mint-and-transfer-sequential 1 VM 57 0.855 1.019 574.9 -token-v1nft-mint-and-transfer-sequential 100 VM 57 0.918 1.033 8119.0 -coin-init-and-mint 1 VM 57 0.913 1.046 14953.6 -coin-init-and-mint 100 VM 57 0.914 1.048 12459.9 -fungible-asset-mint 1 VM 57 0.916 1.047 18466.4 -fungible-asset-mint 100 VM 57 0.914 1.044 15768.8 -no-op5-signers 1 VM 57 0.914 1.040 32094.5 -token-v2-ambassador-mint 1 VM 57 0.922 1.036 11645.3 -token-v2-ambassador-mint 100 VM 57 0.925 1.041 11562.6 -liquidity-pool-swap 1 VM 57 0.870 1.022 627.6 -liquidity-pool-swap 100 VM 57 0.923 1.052 7976.7 -liquidity-pool-swap-stable 1 VM 57 0.872 1.027 602.6 -liquidity-pool-swap-stable 100 VM 57 0.917 1.049 7764.2 -deserialize-u256 1 VM 57 0.909 1.036 30530.7 -no-op-fee-payer 1 VM 57 0.908 1.018 1634.2 -no-op-fee-payer 100 VM 57 0.903 1.031 24743.2 -simple-script 1 VM 57 0.836 1.050 32094.5 -vector-trim-append-len3000-size1 1 VM 57 0.824 1.032 740.9 -vector-remove-insert-len3000-size1 1 VM 57 0.897 1.026 807.0 -order-book-no-matches 1 VM 56 0.8 1.2 1450.0 -order-book-balanced-matches25-pct 1 VM 56 0.8 1.2 920.0 -order-book-balanced-matches80-pct 1 VM 56 0.8 1.2 487.0 -order-book-balanced-size-skewed80-pct 1 VM 56 0.8 1.2 1091.0 -no_commit_apt-fa-transfer 1 VM 57 0.952 1.037 23751.6 -no_commit_apt-fa-transfer 1 NativeVM 57 0.878 1.023 49486.4 -no_commit_apt-fa-transfer 1 AptosVMSpeculative 57 0.914 1.012 1014.9 -no_commit_apt-fa-transfer 1 NativeSpeculative 57 0.876 1.018 99502.2 +no-op 1 VM 4 0.991 1.008 47418.6 +no-op 1000 VM 4 0.991 1.005 45675.8 +apt-fa-transfer 1 VM 4 0.993 1.029 33129.7 +apt-fa-transfer 1 NativeVM 4 0.970 1.049 39873.5 +account-generation 1 VM 4 0.989 1.015 29141.8 +account-generation 1 NativeVM 4 0.986 1.087 41589.9 +account-resource32-b 1 VM 4 0.964 1.014 42506.2 +modify-global-resource 1 VM 4 0.987 1.004 3357.3 +modify-global-resource 100 VM 4 0.981 1.011 41062.1 +publish-package 1 VM 4 0.991 1.017 2087.1 +mix_publish_transfer 1 VM 4 0.997 1.024 28981.5 +batch100-transfer 1 VM 4 0.935 1.076 1424.8 +batch100-transfer 1 NativeVM 4 0.993 1.126 1778.5 +vector-picture30k 1 VM 4 0.998 1.010 141.5 +vector-picture30k 100 VM 4 0.947 1.006 2256.1 +smart-table-picture30-k-with200-change 1 VM 4 0.999 1.008 47.6 +smart-table-picture30-k-with200-change 100 VM 4 0.962 1.008 707.3 +modify-global-resource-agg-v2 1 VM 4 0.999 1.011 44705.3 +modify-global-flag-agg-v2 1 VM 4 0.984 1.007 5568.2 +modify-global-bounded-agg-v2 1 VM 4 0.998 1.035 9659.1 +modify-global-milestone-agg-v2 1 VM 4 0.997 1.021 33725.8 +resource-groups-global-write-tag1-kb 1 VM 4 0.945 1.040 8398.2 +resource-groups-global-write-and-read-tag1-kb 1 VM 4 0.986 1.023 6998.6 +resource-groups-sender-write-tag1-kb 1 VM 4 0.941 1.028 20531.0 +resource-groups-sender-multi-change1-kb 1 VM 4 0.981 1.059 16238.0 +token-v1ft-mint-and-transfer 1 VM 4 0.988 1.008 1657.7 +token-v1ft-mint-and-transfer 100 VM 4 0.992 1.013 20984.9 +token-v1nft-mint-and-transfer-sequential 1 VM 4 0.995 1.006 1128.1 +token-v1nft-mint-and-transfer-sequential 100 VM 4 0.999 1.018 15323.2 +coin-init-and-mint 1 VM 4 0.988 1.025 22392.7 +coin-init-and-mint 100 VM 4 0.991 1.007 18853.9 +fungible-asset-mint 1 VM 4 0.989 1.011 27842.9 +fungible-asset-mint 100 VM 4 0.998 1.007 23290.7 +no-op5-signers 1 VM 4 0.991 1.005 47503.1 +token-v2-ambassador-mint 1 VM 4 0.998 1.019 18501.4 +token-v2-ambassador-mint 100 VM 4 0.992 1.005 18501.4 +liquidity-pool-swap 1 VM 4 0.993 1.008 1096.0 +liquidity-pool-swap 100 VM 4 0.996 1.012 13623.4 +liquidity-pool-swap-stable 1 VM 4 0.981 1.003 1060.2 +liquidity-pool-swap-stable 100 VM 4 0.989 1.015 13261.8 +deserialize-u256 1 VM 4 0.996 1.011 43988.8 +no-op-fee-payer 1 VM 4 0.998 1.016 3103.9 +no-op-fee-payer 100 VM 4 0.998 1.019 30588.4 +simple-script 1 VM 4 0.969 1.012 47082.1 +vector-trim-append-len3000-size1 1 VM 4 0.998 1.024 1154.1 +vector-remove-insert-len3000-size1 1 VM 4 0.990 1.008 1404.6 +order-book-no-matches50-markets 1 VM 4 0.978 1.026 3622.7 +order-book-balanced-matches25-pct50-markets 1 VM 4 0.972 1.033 3759.4 +order-book-balanced-matches80-pct50-markets 1 VM 4 0.997 1.006 3996.1 +order-book-balanced-size-skewed80-pct50-markets 1 VM 4 0.997 1.039 3838.0 +monotonic-counter-single 1 VM 4 0.987 1.009 45350.3 +fibonacci-recursive20 1 VM 4 0.987 1.009 45350.3 +fibonacci-tail-recursive20 1 VM 4 0.987 1.009 45350.3 +fibonacci-iterative20 1 VM 4 0.987 1.009 45350.3 +no_commit_apt-fa-transfer 1 VM 4 0.995 1.011 35616.6 +no_commit_apt-fa-transfer 1 NativeVM 4 0.994 1.030 60946.4 +no_commit_apt-fa-transfer 1 AptosVMSpeculative 4 0.998 1.021 10321.9 +no_commit_apt-fa-transfer 1 NativeSpeculative 4 0.988 1.005 103660.1 \ No newline at end of file diff --git a/testsuite/smoke-test/Cargo.toml b/testsuite/smoke-test/Cargo.toml index ebea8169df8..141132be2fa 100644 --- a/testsuite/smoke-test/Cargo.toml +++ b/testsuite/smoke-test/Cargo.toml @@ -15,6 +15,7 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } movement = { workspace = true, features = ["fuzzing"] } +aptos-api-types = { workspace = true } aptos-bitvec = { path = "../../crates/aptos-bitvec" } aptos-cached-packages = { workspace = true } aptos-config = { workspace = true, features = ["smoke-test"] } @@ -40,9 +41,11 @@ aptos-schemadb = { workspace = true } aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-temppath = { workspace = true } +aptos-transaction-filters = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } bcs = { workspace = true } +blake2-rfc = { workspace = true } diesel = { workspace = true, features = [ "chrono", "postgres", diff --git a/testsuite/smoke-test/src/aptos/mint_transfer.rs b/testsuite/smoke-test/src/aptos/mint_transfer.rs index cb8b02b9186..3be1eee701e 100644 --- a/testsuite/smoke-test/src/aptos/mint_transfer.rs +++ b/testsuite/smoke-test/src/aptos/mint_transfer.rs @@ -1,15 +1,23 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::smoke_test_environment::new_local_swarm_with_aptos; +use crate::smoke_test_environment::SwarmBuilder; use aptos_cached_packages::aptos_stdlib; use aptos_forge::Swarm; use aptos_move_debugger::aptos_debugger::AptosDebugger; use aptos_types::transaction::{ExecutionStatus, TransactionStatus}; +use std::sync::Arc; #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn test_mint_transfer() { - let swarm = new_local_swarm_with_aptos(1).await; + let swarm = SwarmBuilder::new_local(1) + .with_aptos() + .with_init_config(Arc::new(|_, conf, _| { + conf.indexer_db_config.enable_event = true; + conf.indexer_db_config.enable_transaction = true; + })) + .build() + .await; let mut info = swarm.aptos_public_info(); let account1 = info.random_account(); diff --git a/testsuite/smoke-test/src/aptos_cli/validator.rs b/testsuite/smoke-test/src/aptos_cli/validator.rs index 852c0badcd5..ff490601dcf 100644 --- a/testsuite/smoke-test/src/aptos_cli/validator.rs +++ b/testsuite/smoke-test/src/aptos_cli/validator.rs @@ -45,6 +45,9 @@ use std::{ async fn test_analyze_validators() { let (swarm, cli, _faucet) = SwarmBuilder::new_local(1) .with_aptos() + .with_init_config(Arc::new(|_, conf, _| { + conf.indexer_db_config.enable_event = true; + })) .with_init_genesis_stake(Arc::new(|_i, genesis_stake_amount| { *genesis_stake_amount = 100000; })) @@ -624,6 +627,7 @@ async fn test_nodes_rewards() { conf.consensus.round_initial_timeout_ms = 200; conf.consensus.quorum_store_poll_time_ms = 100; conf.api.failpoints_enabled = true; + conf.indexer_db_config.enable_event = true; })) .with_init_genesis_stake(Arc::new(|i, genesis_stake_amount| { // make sure we have quorum @@ -694,6 +698,13 @@ async fn test_nodes_rewards() { ) .await .unwrap(); + rest_clients[2] + .set_failpoint( + "consensus::send::broadcast_opt_proposal".to_string(), + "100%return".to_string(), + ) + .await + .unwrap(); reconfig( &rest_clients[0], @@ -760,6 +771,13 @@ async fn test_nodes_rewards() { ) .await .unwrap(); + rest_clients[2] + .set_failpoint( + "consensus::send::broadcast_opt_proposal".to_string(), + "20%return".to_string(), + ) + .await + .unwrap(); tokio::time::sleep(Duration::from_secs(5)).await; reconfig( diff --git a/testsuite/smoke-test/src/client.rs b/testsuite/smoke-test/src/client.rs index 7aa44679baa..53cc626fb56 100644 --- a/testsuite/smoke-test/src/client.rs +++ b/testsuite/smoke-test/src/client.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - smoke_test_environment::new_local_swarm_with_aptos, + smoke_test_environment::{new_local_swarm_with_aptos, SwarmBuilder}, utils::{ assert_balance, check_create_mint_transfer, create_and_fund_account, transfer_coins, MAX_HEALTHY_WAIT_SECS, @@ -11,7 +11,10 @@ use crate::{ }; use aptos_cached_packages::aptos_stdlib; use aptos_forge::{NodeExt, Swarm}; -use std::time::{Duration, Instant}; +use std::{ + sync::Arc, + time::{Duration, Instant}, +}; #[tokio::test] async fn test_create_mint_transfer_block_metadata() { @@ -110,7 +113,13 @@ async fn test_concurrent_transfers_single_node() { #[tokio::test] async fn test_latest_events_and_transactions() { - let mut swarm = new_local_swarm_with_aptos(1).await; + let mut swarm = SwarmBuilder::new_local(1) + .with_aptos() + .with_init_config(Arc::new(|_, conf, _| { + conf.indexer_db_config.enable_event = true; + })) + .build() + .await; let client = swarm.validators().next().unwrap().rest_client(); let start_events = client .get_new_block_events_bcs(None, Some(2)) diff --git a/testsuite/smoke-test/src/consensus/consensus_fault_tolerance.rs b/testsuite/smoke-test/src/consensus/consensus_fault_tolerance.rs index dc640d98146..84f4d495ed9 100644 --- a/testsuite/smoke-test/src/consensus/consensus_fault_tolerance.rs +++ b/testsuite/smoke-test/src/consensus/consensus_fault_tolerance.rs @@ -49,6 +49,7 @@ pub async fn create_swarm(num_nodes: usize, max_block_txns: u64) -> LocalSwarm { .state_sync .state_sync_driver .max_connection_deadline_secs = 3; + config.indexer_db_config.enable_event = true; })) .build() .await; diff --git a/testsuite/smoke-test/src/consensus/dag/dag_fault_tolerance.rs b/testsuite/smoke-test/src/consensus/dag/dag_fault_tolerance.rs index dff5abd9862..cf6d586e47b 100644 --- a/testsuite/smoke-test/src/consensus/dag/dag_fault_tolerance.rs +++ b/testsuite/smoke-test/src/consensus/dag/dag_fault_tolerance.rs @@ -139,6 +139,7 @@ async fn run_dag_fail_point_test( } #[tokio::test] +#[ignore] async fn test_fault_tolerance_of_network_send() { // Randomly increase network failure rate, until network halts, and check that it comes back afterwards. let mut small_rng = SmallRng::from_entropy(); @@ -172,6 +173,7 @@ async fn test_fault_tolerance_of_network_send() { } #[tokio::test] +#[ignore] async fn test_fault_tolerance_of_network_receive() { // Randomly increase network failure rate, until network halts, and check that it comes back afterwards. let mut small_rng = SmallRng::from_entropy(); @@ -205,6 +207,7 @@ async fn test_fault_tolerance_of_network_receive() { } #[tokio::test] +#[ignore] async fn test_changing_working_consensus() { // with 7 nodes, consensus needs 5 to operate. // we rotate in each cycle, which 2 nodes are down. diff --git a/testsuite/smoke-test/src/consensus/helpers.rs b/testsuite/smoke-test/src/consensus/helpers.rs index 51d5bb9e86b..04e6c3f081f 100644 --- a/testsuite/smoke-test/src/consensus/helpers.rs +++ b/testsuite/smoke-test/src/consensus/helpers.rs @@ -27,6 +27,8 @@ pub async fn generate_traffic_and_assert_committed( sender_use_account_pool: false, non_conflicting: false, use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, 70, ), diff --git a/testsuite/smoke-test/src/consensus_key_rotation.rs b/testsuite/smoke-test/src/consensus_key_rotation.rs index 1fed57dbd6f..2d0053696ce 100644 --- a/testsuite/smoke-test/src/consensus_key_rotation.rs +++ b/testsuite/smoke-test/src/consensus_key_rotation.rs @@ -67,7 +67,7 @@ async fn consensus_key_rotation() { let new_identity_path = PathBuf::from( format!( "/tmp/{}-new-validator-identity.yaml", - thread_rng().gen::() + thread_rng().r#gen::() ) .as_str(), ); diff --git a/testsuite/smoke-test/src/execution_pool.rs b/testsuite/smoke-test/src/execution_pool.rs index d0c82a6fb13..a5f36e1dd74 100644 --- a/testsuite/smoke-test/src/execution_pool.rs +++ b/testsuite/smoke-test/src/execution_pool.rs @@ -40,7 +40,10 @@ pub async fn assert_on_chain_consensus_config_window_size( panic!("Expected OnChainConsensusConfig::V4, but received a different version") }, OnChainConsensusConfig::V4 { window_size, .. } => { - assert_eq!(window_size.map(|v| v), expected_window_size) + assert_eq!(window_size, expected_window_size) + }, + OnChainConsensusConfig::V5 { window_size, .. } => { + assert_eq!(window_size, expected_window_size) }, } } diff --git a/testsuite/smoke-test/src/genesis.rs b/testsuite/smoke-test/src/genesis.rs index 0a2b8fbd836..dae073e1d85 100644 --- a/testsuite/smoke-test/src/genesis.rs +++ b/testsuite/smoke-test/src/genesis.rs @@ -99,7 +99,7 @@ async fn test_fullnode_genesis_transaction_flow() { let first_validator_storage_dir = first_validator_config.storage.dir(); let output = Command::new(aptos_debugger.as_path()) .current_dir(workspace_root()) - .args(&vec![ + .args(vec![ "aptos-db", "bootstrap", first_validator_storage_dir.to_str().unwrap(), @@ -236,7 +236,7 @@ async fn test_validator_genesis_transaction_and_db_restore_flow() { let first_validator_storage_dir = first_validator_config.storage.dir(); let output = Command::new(aptos_debugger.as_path()) .current_dir(workspace_root()) - .args(&vec![ + .args(vec![ "aptos-db", "bootstrap", first_validator_storage_dir.to_str().unwrap(), @@ -373,18 +373,7 @@ async fn delete_db_and_execute_restore( fs::remove_dir_all(&db_dir).unwrap(); // Perform a DB restore on the specified validator - let enable_storage_sharding = validator - .config() - .storage - .rocksdb_configs - .enable_storage_sharding; - db_restore( - backup_path.path(), - db_dir.as_path(), - &[waypoint], - enable_storage_sharding, - None, - ); + db_restore(backup_path.path(), db_dir.as_path(), &[waypoint], None); // Restart the validator and wait for it to become healthy validator.start().unwrap(); @@ -484,7 +473,7 @@ fn generate_genesis_transaction( // Generate the genesis write-set transaction Command::new(aptos_cli.as_path()) .current_dir(workspace_root()) - .args(&vec![ + .args(vec![ "genesis", "generate-admin-write-set", "--output-file", diff --git a/testsuite/smoke-test/src/jwks/jwk_consensus_basic.rs b/testsuite/smoke-test/src/jwks/jwk_consensus_basic.rs index 3d9e903faf9..c799e445073 100644 --- a/testsuite/smoke-test/src/jwks/jwk_consensus_basic.rs +++ b/testsuite/smoke-test/src/jwks/jwk_consensus_basic.rs @@ -35,6 +35,9 @@ async fn jwk_consensus_basic() { .with_init_genesis_config(Arc::new(move |conf| { conf.epoch_duration_secs = epoch_duration_secs; })) + .with_init_genesis_stake(Arc::new(|_i, genesis_stake_amount| { + *genesis_stake_amount = 100_000_000_000_000; + })) .build_with_cli(0) .await; let client = swarm.validators().next().unwrap().rest_client(); diff --git a/testsuite/smoke-test/src/jwks/jwk_consensus_per_issuer.rs b/testsuite/smoke-test/src/jwks/jwk_consensus_per_issuer.rs index 76a07be724a..ad4158bc258 100644 --- a/testsuite/smoke-test/src/jwks/jwk_consensus_per_issuer.rs +++ b/testsuite/smoke-test/src/jwks/jwk_consensus_per_issuer.rs @@ -32,6 +32,9 @@ async fn jwk_consensus_per_issuer() { let (swarm, mut cli, _faucet) = SwarmBuilder::new_local(4) .with_num_fullnodes(1) .with_aptos() + .with_init_genesis_stake(Arc::new(|_i, genesis_stake_amount| { + *genesis_stake_amount = 100_000_000_000_000; + })) .with_init_genesis_config(Arc::new(move |conf| { conf.epoch_duration_secs = epoch_duration_secs; })) diff --git a/testsuite/smoke-test/src/jwks/jwk_consensus_per_key.rs b/testsuite/smoke-test/src/jwks/jwk_consensus_per_key.rs index b374e5b1407..b74fd9e90fa 100644 --- a/testsuite/smoke-test/src/jwks/jwk_consensus_per_key.rs +++ b/testsuite/smoke-test/src/jwks/jwk_consensus_per_key.rs @@ -32,6 +32,9 @@ async fn jwk_consensus_per_key() { let (swarm, mut cli, _faucet) = SwarmBuilder::new_local(4) .with_num_fullnodes(1) .with_aptos() + .with_init_genesis_stake(Arc::new(|_i, genesis_stake_amount| { + *genesis_stake_amount = 100_000_000_000_000; + })) .with_init_genesis_config(Arc::new(move |conf| { conf.epoch_duration_secs = epoch_duration_secs; let mut features = Features::default(); diff --git a/testsuite/smoke-test/src/jwks/jwk_consensus_provider_change_mind.rs b/testsuite/smoke-test/src/jwks/jwk_consensus_provider_change_mind.rs index f26e1d4bf74..9f5a99e7aa9 100644 --- a/testsuite/smoke-test/src/jwks/jwk_consensus_provider_change_mind.rs +++ b/testsuite/smoke-test/src/jwks/jwk_consensus_provider_change_mind.rs @@ -34,6 +34,9 @@ async fn jwk_consensus_provider_change_mind() { let (swarm, mut cli, _faucet) = SwarmBuilder::new_local(4) .with_num_fullnodes(1) .with_aptos() + .with_init_genesis_stake(Arc::new(|_i, genesis_stake_amount| { + *genesis_stake_amount = 100_000_000_000_000; + })) .with_init_genesis_config(Arc::new(move |conf| { conf.epoch_duration_secs = epoch_duration_secs; })) diff --git a/testsuite/smoke-test/src/keyless.rs b/testsuite/smoke-test/src/keyless.rs index 88c5ba11ebb..8a940e9e868 100644 --- a/testsuite/smoke-test/src/keyless.rs +++ b/testsuite/smoke-test/src/keyless.rs @@ -650,12 +650,6 @@ async fn sign_transaction_any_keyless_pk( addr.to_hex_literal(), info.get_balance(addr).await ); - // TODO: No idea why, but these calls do not actually reflect the updated sequence number after a successful TXN. - info!( - "{} sequence number before TXN: {}", - addr.to_hex_literal(), - info.get_account_sequence_number(addr).await.unwrap() - ); info.sync_root_account_sequence_number().await; let recipient = info .create_and_fund_user_account(20_000_000_000) diff --git a/testsuite/smoke-test/src/lib.rs b/testsuite/smoke-test/src/lib.rs index 6db6c5bb6e9..e8c1902b9e3 100644 --- a/testsuite/smoke-test/src/lib.rs +++ b/testsuite/smoke-test/src/lib.rs @@ -39,6 +39,8 @@ mod network; #[cfg(test)] mod permissioned_delegation; #[cfg(test)] +mod priority_fee; +#[cfg(test)] mod randomness; #[cfg(test)] mod rest_api; @@ -49,10 +51,14 @@ mod state_sync_utils; #[cfg(test)] mod storage; #[cfg(test)] +mod sui_derivable_account; +#[cfg(test)] mod test_smoke_tests; #[cfg(test)] mod transaction; #[cfg(test)] +mod transaction_filter; +#[cfg(test)] mod txn_broadcast; #[cfg(test)] mod txn_emitter; diff --git a/testsuite/smoke-test/src/priority_fee.rs b/testsuite/smoke-test/src/priority_fee.rs new file mode 100644 index 00000000000..dbbbedcbb85 --- /dev/null +++ b/testsuite/smoke-test/src/priority_fee.rs @@ -0,0 +1,97 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{smoke_test_environment::SwarmBuilder, txn_emitter::generate_traffic}; +use aptos_api_types::ViewFunction; +use aptos_forge::{args::TransactionTypeArg, NodeExt}; +use aptos_types::on_chain_config::{ + BlockGasLimitType, ExecutionConfigV4, OnChainExecutionConfig, TransactionDeduperType, + TransactionShufflerType, +}; +use move_core_types::{identifier::Identifier, language_storage::ModuleId}; +use std::{str::FromStr, sync::Arc, time::Duration}; + +#[tokio::test] +async fn test_high_gas_limit_sequential() { + test_impl(100000000, 1).await; +} + +#[tokio::test] +async fn test_high_gas_limit_parallel() { + test_impl(100000000, 4).await; +} + +#[tokio::test] +async fn test_low_gas_limit_sequential() { + test_impl(30, 1).await; +} + +#[tokio::test] +async fn test_low_gas_limit_parallel() { + test_impl(30, 4).await; +} + +async fn test_impl(block_gas_limit: u64, concurrency_level: u16) { + let mut swarm = SwarmBuilder::new_local(2) + .with_aptos() + .with_init_config(Arc::new(move |_, config, _| { + config.execution.concurrency_level = concurrency_level; + })) + // Start with V1 + .with_init_genesis_config(Arc::new(move |genesis_config| { + let mut block_gas_limit_type = BlockGasLimitType::default_for_genesis(); + match &mut block_gas_limit_type { + BlockGasLimitType::ComplexLimitV1 { + effective_block_gas_limit, + .. + } => *effective_block_gas_limit = block_gas_limit, + _ => unreachable!(), + }; + genesis_config.execution_config = OnChainExecutionConfig::V4(ExecutionConfigV4 { + transaction_shuffler_type: TransactionShufflerType::NoShuffling, + block_gas_limit_type, + transaction_deduper_type: TransactionDeduperType::TxnHashAndAuthenticatorV1, + }); + })) + .build() + .await; + + let rest_client = swarm.validators().next().unwrap().rest_client(); + let view_function = ViewFunction { + module: ModuleId::from_str("0x1::stake").unwrap(), + function: Identifier::from_str("get_pending_transaction_fee").unwrap(), + ty_args: vec![], + args: vec![], + }; + let result_before: Vec> = rest_client + .view_bcs(&view_function, None) + .await + .unwrap() + .into_inner(); + + let all_validators = swarm.validators().map(|v| v.peer_id()).collect::>(); + let _ = generate_traffic( + &mut swarm, + &all_validators, + Duration::from_secs(20), + 100, + vec![vec![ + (TransactionTypeArg::CoinTransfer.materialize_default(), 70), + ( + TransactionTypeArg::AccountGeneration.materialize_default(), + 20, + ), + ]], + ) + .await + .unwrap(); + + let result_after: Vec> = rest_client + .view_bcs(&view_function, None) + .await + .unwrap() + .into_inner(); + assert_ne!(result_before, result_after); +} + +// TODO(grao): Add more tests to check the math. diff --git a/testsuite/smoke-test/src/randomness/e2e_correctness.rs b/testsuite/smoke-test/src/randomness/e2e_correctness.rs index 3a329d273c5..c63b74e2f22 100644 --- a/testsuite/smoke-test/src/randomness/e2e_correctness.rs +++ b/testsuite/smoke-test/src/randomness/e2e_correctness.rs @@ -24,6 +24,7 @@ async fn randomness_correctness() { // Ensure randomness is enabled. conf.consensus_config.enable_validator_txns(); + conf.consensus_config.disable_rand_check(); conf.randomness_config_override = Some(OnChainRandomnessConfig::default_enabled()); })) .build_with_cli(0) diff --git a/testsuite/smoke-test/src/randomness/randomness_stall_recovery.rs b/testsuite/smoke-test/src/randomness/randomness_stall_recovery.rs index 7fc02eb0489..2bce61fad26 100644 --- a/testsuite/smoke-test/src/randomness/randomness_stall_recovery.rs +++ b/testsuite/smoke-test/src/randomness/randomness_stall_recovery.rs @@ -157,9 +157,9 @@ script { let PerBlockRandomness { epoch: actual_epoch, - seed, .. } = get_on_chain_resource::(&rest_client).await; - assert!(seed.is_some()); + // seed is not necessarily generated because of the rand check optimization. + // but epoch and round should be updated. assert_eq!(epoch + 1, actual_epoch); } diff --git a/testsuite/smoke-test/src/rest_api.rs b/testsuite/smoke-test/src/rest_api.rs index ac7ac0a6446..1f3a143935c 100644 --- a/testsuite/smoke-test/src/rest_api.rs +++ b/testsuite/smoke-test/src/rest_api.rs @@ -39,7 +39,13 @@ async fn test_get_index() { #[tokio::test] async fn test_basic_client() { - let swarm = new_local_swarm_with_aptos(1).await; + let swarm = SwarmBuilder::new_local(1) + .with_aptos() + .with_init_config(Arc::new(|_, conf, _| { + conf.indexer_db_config.enable_statekeys = true; + })) + .build() + .await; let mut info = swarm.aptos_public_info(); info.client().get_ledger_information().await.unwrap(); @@ -125,6 +131,8 @@ async fn test_gas_estimation_inner(swarm: &mut LocalSwarm) { sender_use_account_pool: false, non_conflicting: false, use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, 100, )]], @@ -246,7 +254,15 @@ async fn test_gas_estimation_gas_used_limit() { #[tokio::test] async fn test_bcs() { - let swarm = new_local_swarm_with_aptos(1).await; + let swarm = SwarmBuilder::new_local(1) + .with_aptos() + .with_init_config(Arc::new(|_, conf, _| { + conf.indexer_db_config.enable_statekeys = true; + conf.indexer_db_config.enable_transaction = true; + conf.indexer_db_config.enable_event = true; + })) + .build() + .await; let mut info = swarm.aptos_public_info(); // Create accounts diff --git a/testsuite/smoke-test/src/state_sync.rs b/testsuite/smoke-test/src/state_sync.rs index c0534258d9e..915d0240f03 100644 --- a/testsuite/smoke-test/src/state_sync.rs +++ b/testsuite/smoke-test/src/state_sync.rs @@ -660,6 +660,7 @@ async fn test_validator_sync_and_participate(fast_sync: bool, epoch_changes: boo OnChainConsensusConfig::V2(consensus_config) => consensus_config, OnChainConsensusConfig::V3 { alg, .. } => alg.unwrap_jolteon_config_v1().clone(), OnChainConsensusConfig::V4 { alg, .. } => alg.unwrap_jolteon_config_v1().clone(), + OnChainConsensusConfig::V5 { alg, .. } => alg.unwrap_jolteon_config_v1().clone(), }; let leader_reputation_type = match &consensus_config.proposer_election_type { ProposerElectionType::LeaderReputation(leader_reputation_type) => { diff --git a/testsuite/smoke-test/src/state_sync_utils.rs b/testsuite/smoke-test/src/state_sync_utils.rs index b321fb22519..742d3d9b8cc 100644 --- a/testsuite/smoke-test/src/state_sync_utils.rs +++ b/testsuite/smoke-test/src/state_sync_utils.rs @@ -199,7 +199,7 @@ fn verify_first_ledger_info(node: &mut LocalNode) { node.stop(); // Verify that the ledger info exists at version 0 - let aptos_db = AptosDB::new_for_test(db_path_buf.as_path()); + let aptos_db = AptosDB::new_for_test_with_sharding(db_path_buf.as_path(), 1 << 13); aptos_db.get_epoch_ending_ledger_info(0).unwrap(); // Restart the node diff --git a/testsuite/smoke-test/src/storage.rs b/testsuite/smoke-test/src/storage.rs index 6211e50c7bd..f57f88c7e3b 100644 --- a/testsuite/smoke-test/src/storage.rs +++ b/testsuite/smoke-test/src/storage.rs @@ -134,13 +134,7 @@ async fn test_db_restore() { info!("---------- 3. stopped node 0, gonna restore DB."); // restore db from backup - db_restore( - backup_path.path(), - db_dir.as_path(), - &[], - node0_config.storage.rocksdb_configs.enable_storage_sharding, - None, - ); + db_restore(backup_path.path(), db_dir.as_path(), &[], None); expected_balance_0 -= 3; expected_balance_1 += 3; @@ -197,7 +191,7 @@ fn db_backup_verify(backup_path: &Path, trusted_waypoints: &[Waypoint]) { cmd.args(["aptos-db", "backup", "verify"]); trusted_waypoints.iter().for_each(|w| { cmd.arg("--trust-waypoint"); - cmd.arg(&w.to_string()); + cmd.arg(w.to_string()); }); let status = cmd @@ -229,7 +223,7 @@ fn replay_verify(backup_path: &Path, trusted_waypoints: &[Waypoint]) { cmd.args(["aptos-db", "replay-verify"]); trusted_waypoints.iter().for_each(|w| { cmd.arg("--trust-waypoint"); - cmd.arg(&w.to_string()); + cmd.arg(w.to_string()); }); let replay = cmd @@ -420,7 +414,6 @@ pub(crate) fn db_restore( backup_path: &Path, db_path: &Path, trusted_waypoints: &[Waypoint], - enable_storage_sharding: bool, target_verion: Option, /* target version should be same as epoch ending version to start a node */ ) { let now = Instant::now(); @@ -433,16 +426,14 @@ pub(crate) fn db_restore( cmd.args(["aptos-db", "restore", "bootstrap-db"]); trusted_waypoints.iter().for_each(|w| { cmd.arg("--trust-waypoint"); - cmd.arg(&w.to_string()); + cmd.arg(w.to_string()); }); - if enable_storage_sharding { - cmd.arg("--enable_storage_sharding"); - cmd.arg("--enable-state-indices"); - } + cmd.arg("--enable-storage-sharding"); + cmd.arg("--enable-state-indices"); if let Some(version) = target_verion { cmd.arg("--target-version"); - cmd.arg(&version.to_string()); + cmd.arg(version.to_string()); } let status = cmd diff --git a/testsuite/smoke-test/src/sui_derivable_account.rs b/testsuite/smoke-test/src/sui_derivable_account.rs new file mode 100644 index 00000000000..e421049c7e0 --- /dev/null +++ b/testsuite/smoke-test/src/sui_derivable_account.rs @@ -0,0 +1,169 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::smoke_test_environment::SwarmBuilder; +use aptos_cached_packages::aptos_stdlib; +use aptos_crypto::SigningKey; +use aptos_forge::Swarm; +use aptos_sdk::types::{AccountKey, LocalAccount}; +use aptos_types::function_info::FunctionInfo; +use blake2_rfc::blake2b::blake2b; +use move_core_types::account_address::AccountAddress; +use rand::thread_rng; +use serde::Serialize; +use std::sync::Arc; + +#[derive(Serialize)] +struct SuiAbstractPublicKey { + // The Sui account address, in hex string format with "0x" prefix + sui_account_address: Vec, + // The domain, in utf8 bytes + domain: Vec, +} + +#[derive(Serialize)] +enum SuiAbstractSignature { + MessageV1 { + /// The signature of the message in raw bytes + signature: Vec, + }, +} + +#[derive(Serialize)] +enum Scope { + PersonalMessage = 3, +} + +#[derive(Serialize)] +enum Version { + V0 = 0, +} + +#[derive(Serialize)] +enum AppId { + Sui = 0, +} + +#[derive(Serialize)] +struct Intent { + scope: u8, + version: u8, + app_id: u8, +} + +#[derive(Serialize)] +struct IntentMessage<'a> { + intent: &'a Intent, + value: &'a [u8], +} + +fn derive_account_address_from_public_key(public_key_bytes: Vec, scheme_flag: u8) -> Vec { + // Create auth key by prepending scheme flag + let mut auth_key = vec![scheme_flag]; + auth_key.extend(&public_key_bytes); + + // Compute blake2b hash + let hash = blake2b(32, &[], &auth_key).as_bytes().to_vec(); + + // Take all 32 bytes + let sui_address: Vec = hash.to_vec(); + + // Convert the address bytes to a hex string with "0x" prefix + let mut sui_account_address = b"0x".to_vec(); + sui_account_address.extend_from_slice(hex::encode(sui_address).as_bytes()); + + sui_account_address +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sui_derivable_account() { + let swarm = SwarmBuilder::new_local(1).with_aptos().build().await; + let mut info = swarm.aptos_public_info(); + + let function_info = FunctionInfo::new( + AccountAddress::ONE, + "sui_derivable_account".to_string(), + "authenticate".to_string(), + ); + + let account_key = AccountKey::generate(&mut thread_rng()); + let account_public_key = account_key.public_key().to_bytes(); + + let sui_account_address = derive_account_address_from_public_key( + account_public_key.to_vec(), + 0x00, // 0x00 for ED25519 + ); + + let domain = "localhost:3001"; + let account_identity: Vec = bcs::to_bytes(&SuiAbstractPublicKey { + sui_account_address: sui_account_address.clone(), + domain: domain.as_bytes().to_vec(), + }) + .unwrap(); + + let account = LocalAccount::new_domain_aa( + function_info, + account_identity, + Arc::new({ + move |x: &[u8]| { + let function_name = "0x1::aptos_account::create_account"; + let digest = format!("0x{}", hex::encode(x)); + + let message = format!( + "{} wants you to sign in with your Sui account:\n{}\n\nPlease confirm you explicitly initiated this request from {}. You are approving to execute transaction {} on Aptos blockchain (local).\n\nNonce: {}", + domain, + String::from_utf8(sui_account_address.clone()).unwrap(), + domain, + function_name, + digest + ); + + // Create Intent message + let intent = Intent { + scope: Scope::PersonalMessage as u8, + version: Version::V0 as u8, + app_id: AppId::Sui as u8, + }; + let intent_message = IntentMessage { + intent: &intent, + value: message.as_bytes(), + }; + + // Serialize and hash the message + let bcs_bytes = bcs::to_bytes(&intent_message).unwrap(); + let hash = blake2b(32, &[], &bcs_bytes).as_bytes().to_vec(); + + let signature = account_key + .private_key() + .sign_arbitrary_message(&hash) + .to_bytes() + .to_vec(); + + // Create the full signature bytes: [scheme_flag (1 byte) || signature (64 bytes) || public_key (32 bytes)] + let mut sui_signature = vec![0x00]; // ED25519 scheme + sui_signature.extend(signature); + sui_signature.extend(account_public_key.to_vec()); // Skip "0x00" prefix to get raw public key + + let signature = SuiAbstractSignature::MessageV1 { + signature: sui_signature, + }; + bcs::to_bytes(&signature).unwrap() + } + }), + 0, + ); + + // test some transaction + let create_txn = account.sign_aa_transaction_with_transaction_builder( + vec![], + Some(&info.root_account()), + info.transaction_factory() + .payload(aptos_stdlib::aptos_account_create_account( + AccountAddress::random(), + )), + ); + info.client() + .submit_and_wait(&create_txn) + .await + .unwrap_or_else(|_| panic!("aa: {:?}", create_txn)); +} diff --git a/testsuite/smoke-test/src/transaction_filter.rs b/testsuite/smoke-test/src/transaction_filter.rs new file mode 100644 index 00000000000..d2aec3eabad --- /dev/null +++ b/testsuite/smoke-test/src/transaction_filter.rs @@ -0,0 +1,284 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + smoke_test_environment::SwarmBuilder, + utils::{create_test_accounts, execute_transactions}, +}; +use aptos_cached_packages::aptos_stdlib; +use aptos_config::config::{ + BatchTransactionFilterConfig, BlockTransactionFilterConfig, NodeConfig, TransactionFilterConfig, +}; +use aptos_crypto::ed25519::{Ed25519PrivateKey, Ed25519PublicKey}; +use aptos_forge::{LocalSwarm, NodeExt, Swarm}; +use aptos_keygen::KeyGen; +use aptos_sdk::{ + crypto::{PrivateKey, SigningKey}, + types::{ + transaction::{authenticator::AuthenticationKey, SignedTransaction}, + LocalAccount, + }, +}; +use aptos_transaction_filters::{ + batch_transaction_filter::{BatchTransactionFilter, BatchTransactionMatcher}, + block_transaction_filter::{BlockTransactionFilter, BlockTransactionMatcher}, + transaction_filter::{TransactionFilter, TransactionMatcher}, +}; +use aptos_types::on_chain_config::{ + ConsensusAlgorithmConfig, OnChainConsensusConfig, ValidatorTxnConfig, DEFAULT_WINDOW_SIZE, +}; +use move_core_types::account_address::AccountAddress; +use std::sync::Arc; + +#[tokio::test] +async fn test_consensus_block_filter() { + // Generate a new key pair and sender address + let (private_key, sender_address) = create_sender_account(); + + // Create a new swarm with an inline consensus filter that denies transactions + // from the sender, and disable quorum store (to ensure the filter is applied). + let mut swarm = SwarmBuilder::new_local(3) + .with_aptos() + .with_init_config(Arc::new(move |_, config, _| { + filter_inline_transactions(config, sender_address); + })) + .with_init_genesis_config(Arc::new(|genesis_config| { + genesis_config.consensus_config = OnChainConsensusConfig::V4 { + alg: ConsensusAlgorithmConfig::default_with_quorum_store_disabled(), + vtxn: ValidatorTxnConfig::default_for_genesis(), + window_size: DEFAULT_WINDOW_SIZE, + }; + })) + .build() + .await; + + // Execute a few regular transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; + + // Prepare a transaction from the sender address + let transaction = create_transaction_from_sender(private_key, sender_address, &mut swarm).await; + + // Submit the transaction and wait for it to be processed + let aptos_public_info = swarm.aptos_public_info(); + let response = aptos_public_info + .client() + .submit_and_wait(&transaction) + .await; + + // Verify the transaction was dropped by the consensus filter + let error = response.unwrap_err(); + assert!(error + .to_string() + .contains("Used to be pending and now not found. Transaction expired.")); + + // Execute a few more transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; +} + +#[tokio::test] +async fn test_mempool_transaction_filter() { + // Generate a new key pair and sender address + let (private_key, sender_address) = create_sender_account(); + + // Create a new swarm with a mempool filter that denies transactions from the sender + let mut swarm = SwarmBuilder::new_local(3) + .with_aptos() + .with_init_config(Arc::new(move |_, config, _| { + filter_mempool_transactions(config, sender_address); + })) + .build() + .await; + + // Execute a few regular transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; + + // Prepare a transaction from the sender address + let transaction = create_transaction_from_sender(private_key, sender_address, &mut swarm).await; + + // Submit the transaction and wait for it to be processed + let aptos_public_info = swarm.aptos_public_info(); + let response = aptos_public_info + .client() + .submit_and_wait(&transaction) + .await; + + // Verify the transaction was rejected by the mempool filter + let error = response.unwrap_err(); + assert!(error + .to_string() + .contains("API error Error(RejectedByFilter)")); + + // Execute a few more transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; +} + +#[tokio::test] +async fn test_quorum_store_batch_filter() { + // Generate a new key pair and sender address + let (private_key, sender_address) = create_sender_account(); + + // Create a new swarm with a quorum store filter that denies transactions from the sender + let mut swarm = SwarmBuilder::new_local(3) + .with_aptos() + .with_init_config(Arc::new(move |_, config, _| { + filter_quorum_store_transactions(config, sender_address); + })) + .build() + .await; + + // Execute a few regular transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; + + // Prepare a transaction from the sender address + let transaction = create_transaction_from_sender(private_key, sender_address, &mut swarm).await; + + // Submit the transaction and wait for it to be processed + let aptos_public_info = swarm.aptos_public_info(); + let response = aptos_public_info + .client() + .submit_and_wait(&transaction) + .await; + + // Verify the transaction was dropped by the quorum store filter + let error = response.unwrap_err(); + assert!(error + .to_string() + .contains("Used to be pending and now not found. Transaction expired.")); + + // Execute a few more transactions and verify that they are processed correctly + execute_test_transactions(&mut swarm).await; +} + +/// Creates a new on-chain account for the given address and sends some funds to it +async fn create_account_with_funds( + public_key: &Ed25519PublicKey, + sender_address: AccountAddress, + swarm: &mut LocalSwarm, +) { + let mut aptos_public_info = swarm.aptos_public_info(); + aptos_public_info + .create_user_account(public_key) + .await + .unwrap(); + aptos_public_info + .mint(sender_address, 10_000_000) + .await + .unwrap(); +} + +/// Creates a new sender account and returns the private key and address +fn create_sender_account() -> (Ed25519PrivateKey, AccountAddress) { + let private_key = KeyGen::from_os_rng().generate_ed25519_private_key(); + let public_key = private_key.public_key(); + let sender_auth_key = AuthenticationKey::ed25519(&public_key); + let sender_address = sender_auth_key.account_address(); + + (private_key, sender_address) +} + +/// Creates a signed transaction from the sender address to the receiver address +async fn create_signed_transaction_from_sender( + private_key: Ed25519PrivateKey, + sender_address: AccountAddress, + receiver: LocalAccount, + swarm: &mut LocalSwarm, +) -> SignedTransaction { + // Fetch the sequence number for the sender address + let aptos_public_info = swarm.aptos_public_info(); + let sequence_number = aptos_public_info + .client() + .get_account(sender_address) + .await + .unwrap() + .into_inner() + .sequence_number; + + // Create the unsigned transaction + let unsigned_txn = aptos_public_info + .transaction_factory() + .payload(aptos_stdlib::aptos_coin_transfer(receiver.address(), 100)) + .sender(sender_address) + .sequence_number(sequence_number) + .max_gas_amount(1_000_000) + .gas_unit_price(1) + .build(); + assert_eq!(unsigned_txn.sender(), sender_address); + + // Sign the transaction + let signature = private_key.sign(&unsigned_txn).unwrap(); + SignedTransaction::new(unsigned_txn.clone(), private_key.public_key(), signature) +} + +/// Creates a transaction from the sender address to a random receiver address +async fn create_transaction_from_sender( + private_key: Ed25519PrivateKey, + sender_address: AccountAddress, + swarm: &mut LocalSwarm, +) -> SignedTransaction { + // Create the sender account and mint some coins to it + create_account_with_funds(&private_key.public_key(), sender_address, swarm).await; + + // Create a receiver account and mint some coins to it + let mut aptos_public_info = swarm.aptos_public_info(); + let receiver = aptos_public_info.random_account(); + create_account_with_funds(receiver.public_key(), receiver.address(), swarm).await; + + // Create a signed transaction + create_signed_transaction_from_sender(private_key, sender_address, receiver, swarm).await +} + +/// Executes a few test transactions and verifies that they are processed correctly +async fn execute_test_transactions(swarm: &mut LocalSwarm) { + let validator_peer_id_1 = swarm.validators().next().unwrap().peer_id(); + let validator_client_1 = swarm.validator(validator_peer_id_1).unwrap().rest_client(); + let (mut account_0, account_1) = create_test_accounts(swarm).await; + + execute_transactions( + swarm, + &validator_client_1, + &mut account_0, + &account_1, + false, + ) + .await; +} + +/// Adds a filter to the consensus config to ignore transactions from the given sender +fn filter_inline_transactions(node_config: &mut NodeConfig, sender_address: AccountAddress) { + // Create the block transaction filter + let block_transaction_filter = BlockTransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![BlockTransactionMatcher::Transaction( + TransactionMatcher::Sender(sender_address), + )]) + .add_all_filter(true); + + // Update the node config with the new filter + node_config.transaction_filters.consensus_filter = + BlockTransactionFilterConfig::new(true, block_transaction_filter); +} + +/// Adds a filter to the mempool config to ignore transactions from the given sender +fn filter_mempool_transactions(node_config: &mut NodeConfig, sender_address: AccountAddress) { + // Create the transaction filter + let transaction_filter = TransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![TransactionMatcher::Sender(sender_address)]) + .add_all_filter(true); + + // Update the node config with the new filter + node_config.transaction_filters.mempool_filter = + TransactionFilterConfig::new(true, transaction_filter); +} + +/// Adds a filter to the quorum store config to ignore transactions from the given sender +fn filter_quorum_store_transactions(node_config: &mut NodeConfig, sender_address: AccountAddress) { + // Create the batch transaction filter + let batch_transaction_filter = BatchTransactionFilter::empty() + .add_multiple_matchers_filter(false, vec![BatchTransactionMatcher::Transaction( + TransactionMatcher::Sender(sender_address), + )]) + .add_all_filter(true); + + // Update the node config with the new filter + node_config.transaction_filters.quorum_store_filter = + BatchTransactionFilterConfig::new(true, batch_transaction_filter); +} diff --git a/testsuite/smoke-test/src/upgrade.rs b/testsuite/smoke-test/src/upgrade.rs index b50260bf734..98660ef37b5 100644 --- a/testsuite/smoke-test/src/upgrade.rs +++ b/testsuite/smoke-test/src/upgrade.rs @@ -79,7 +79,7 @@ async fn test_upgrade_flow() { assert!(Command::new(aptos_cli.as_path()) .current_dir(workspace_root()) - .args(&vec![ + .args(vec![ "move", "run-script", "--script-path", @@ -176,7 +176,7 @@ async fn test_upgrade_flow() { for path in scripts.iter() { assert!(Command::new(aptos_cli.as_path()) .current_dir(workspace_root()) - .args(&vec![ + .args(vec![ "move", "run-script", "--script-path", diff --git a/testsuite/test_framework/cluster.py b/testsuite/test_framework/cluster.py index e7e8ac7bc7d..24e4052d080 100644 --- a/testsuite/test_framework/cluster.py +++ b/testsuite/test_framework/cluster.py @@ -6,9 +6,11 @@ from enum import Enum import json import os +import time from typing import Dict, List, Optional, TypedDict from .shell import Shell +from .logging import log class Cloud(Enum): @@ -213,11 +215,25 @@ def list_eks_clusters(shell: Shell) -> Dict[str, ForgeCluster]: def list_gke_clusters(shell: Shell) -> Dict[str, ForgeCluster]: - cluster_json = shell.run( - ["gcloud", "container", "clusters", "list", "--format=json"] - ).unwrap() + # hack: Retry GKE cluster listing few times in case of transient failures + max_retries = 10 + cluster_json_str = "[]" + for attempt in range(max_retries): + try: + cluster_json = shell.run( + ["gcloud", "container", "clusters", "list", "--format=json(name, location)"] + ).unwrap() + cluster_json_str = cluster_json.decode() + log.info(f"GKE clusters list (attempt {attempt + 1}): {cluster_json_str}") + break # Success, exit retry loop + except Exception as e: + if attempt == max_retries - 1: + # Last attempt failed, re-raise the exception + raise e + log.warning(f"GKE cluster listing attempt {attempt + 1} failed: {e}. Retrying...") + time.sleep(10) try: - cluster_result = json.loads(cluster_json.decode()) + cluster_result = json.loads(cluster_json_str) clusters: Dict[str, ForgeCluster] = {} for cluster_config in cluster_result: cluster_name = cluster_config["name"] diff --git a/testsuite/testcases/src/forge_setup_test.rs b/testsuite/testcases/src/forge_setup_test.rs index 6322c09a0f9..91d09d9361c 100644 --- a/testsuite/testcases/src/forge_setup_test.rs +++ b/testsuite/testcases/src/forge_setup_test.rs @@ -27,7 +27,7 @@ impl Test for ForgeSetupTest { #[async_trait] impl NetworkTest for ForgeSetupTest { async fn run<'a>(&self, ctx: NetworkContextSynchronizer<'a>) -> Result<()> { - let mut rng = StdRng::from_seed(OsRng.gen()); + let mut rng = StdRng::from_seed(OsRng.r#gen()); let mut ctx_locker = ctx.ctx.lock().await; let ctx = ctx_locker.deref_mut(); diff --git a/testsuite/testcases/src/lib.rs b/testsuite/testcases/src/lib.rs index c77f71567f6..0fa5718cd76 100644 --- a/testsuite/testcases/src/lib.rs +++ b/testsuite/testcases/src/lib.rs @@ -32,6 +32,7 @@ use aptos_forge::{ EmitJob, EmitJobRequest, NetworkContext, NetworkContextSynchronizer, NetworkTest, NodeExt, Result, Swarm, SwarmExt, Test, TestReport, TxnEmitter, TxnStats, Version, }; +use aptos_logger::warn; use aptos_rest_client::Client as RestClient; use aptos_sdk::{transaction_builder::TransactionFactory, types::PeerId}; use async_trait::async_trait; @@ -370,6 +371,7 @@ pub async fn create_buffered_load( } info!("Starting emitting txns for {}s", duration.as_secs()); + let job_init_timer = Instant::now(); let mut job = emitter .start_job( swarm.read().await.chain_info().root_account, @@ -378,6 +380,23 @@ pub async fn create_buffered_load( ) .await .context("start emitter job")?; + let job_setup_duration = job_init_timer.elapsed(); + + info!( + "Emitter setup took {}s. Reducing from total duration of {}s", + job_setup_duration.as_secs(), + duration.as_secs(), + ); + let duration = if duration > job_setup_duration { + duration.saturating_sub(job_setup_duration) + } else { + warn!( + "Setup took too long: {}s. Not enough test time left from total duration {}s", + job_setup_duration.as_secs(), + duration.as_secs() + ); + Duration::from_secs(60) + }; let total_start = PhaseTimingStart::now(); diff --git a/testsuite/testcases/src/load_vs_perf_benchmark.rs b/testsuite/testcases/src/load_vs_perf_benchmark.rs index a5ffc4c141c..6fb5be11b64 100644 --- a/testsuite/testcases/src/load_vs_perf_benchmark.rs +++ b/testsuite/testcases/src/load_vs_perf_benchmark.rs @@ -7,9 +7,9 @@ use aptos_forge::{ args::TransactionTypeArg, emitter::NumAccountsMode, prometheus_metrics::{LatencyBreakdown, LatencyBreakdownSlice, MetricSamples}, - success_criteria::{SuccessCriteria, SuccessCriteriaChecker}, + success_criteria::{SuccessCriteria, SuccessCriteriaChecker, SuccessCriteriaResults}, EmitJob, EmitJobMode, EmitJobRequest, NetworkContext, NetworkContextSynchronizer, NetworkTest, - Result, Test, TxnStats, WorkflowProgress, + Result, Test, TransactionType, TxnStats, WorkflowProgress, }; use async_trait::async_trait; use log::{error, info}; @@ -33,6 +33,7 @@ pub struct SingleRunStats { pub enum Workloads { TPS(Vec), TRANSACTIONS(Vec), + RawTransactions(Vec), } impl Workloads { @@ -40,6 +41,7 @@ impl Workloads { match self { Self::TPS(tpss) => tpss.len(), Self::TRANSACTIONS(workloads) => workloads.len(), + Self::RawTransactions(workloads) => workloads.len(), } } @@ -47,6 +49,7 @@ impl Workloads { match self { Self::TPS(_) => "Load (TPS)".to_string(), Self::TRANSACTIONS(_) => "Workload".to_string(), + Self::RawTransactions(_) => "RawWorkload".to_string(), } } @@ -60,6 +63,7 @@ impl Workloads { 1 } }, + Self::RawTransactions(_) => 1, } } @@ -69,6 +73,9 @@ impl Workloads { format!("TPS({})", tpss[index]) }, Self::TRANSACTIONS(workloads) => format!("TRANSACTIONS({:?})", workloads[index]), + Self::RawTransactions(workloads) => { + format!("RAW TRANSACTIONS({:?})", workloads[index].name) + }, } } @@ -88,6 +95,7 @@ impl Workloads { }, workloads[index].phase_name(phase) ), + Self::RawTransactions(workloads) => format!("{}: {}", index, workloads[index].name), } } @@ -95,6 +103,12 @@ impl Workloads { match self { Self::TPS(tpss) => request.mode(EmitJobMode::ConstTps { tps: tpss[index] }), Self::TRANSACTIONS(workloads) => workloads[index].configure(request), + Self::RawTransactions(workloads) => { + let workload = &workloads[index]; + request + .mode(workload.emit_job_mode.clone()) + .transaction_type(workload.workload.clone()) + }, } } @@ -237,6 +251,23 @@ impl TransactionWorkload { } } +#[derive(Debug, Clone)] +pub struct RawTransactionWorkload { + name: String, + workload: TransactionType, + emit_job_mode: EmitJobMode, +} + +impl RawTransactionWorkload { + pub fn new(name: String, workload: TransactionType, emit_job_mode: EmitJobMode) -> Self { + Self { + name, + workload, + emit_job_mode, + } + } +} + pub struct BackgroundTraffic { pub traffic: EmitJobRequest, pub criteria: Vec, @@ -255,6 +286,7 @@ impl Test for LoadVsPerfBenchmark { match self.workloads { Workloads::TPS(_) => "load vs perf test", Workloads::TRANSACTIONS(_) => "workload vs perf test", + Workloads::RawTransactions(_) => "raw workload vs perf test", } } } @@ -406,18 +438,21 @@ impl NetworkTest for LoadVsPerfBenchmark { None => None, }; + let mut criteria_results = SuccessCriteriaResults::default(); for (index, result) in results.iter().enumerate() { // always take last phase for success criteria let target_result = &result[result.len() - 1]; let rate = target_result.stats.rate(); if let Some(criteria) = self.criteria.get(index) { - SuccessCriteriaChecker::check_core_for_success( + let outcome = SuccessCriteriaChecker::check_core_for_success( criteria, ctx.report, &rate, Some(&target_result.latency_breakdown), Some(target_result.name.clone()), - )?; + ); + let outcome = outcome.map_err(|e| e.downcast().unwrap()); + criteria_results.extend(outcome); } } @@ -431,17 +466,21 @@ impl NetworkTest for LoadVsPerfBenchmark { .criteria .get(index) { - SuccessCriteriaChecker::check_core_for_success( + let outcome = SuccessCriteriaChecker::check_core_for_success( criteria, ctx.report, &rate, None, Some(name), - )?; + ); + let outcome = outcome.map_err(|e| e.downcast().unwrap()); + criteria_results.extend(outcome); } } } + criteria_results.evaluate()?; + Ok(()) } } diff --git a/testsuite/testcases/src/modifiers.rs b/testsuite/testcases/src/modifiers.rs index 91f3dddd17a..40132a064c0 100644 --- a/testsuite/testcases/src/modifiers.rs +++ b/testsuite/testcases/src/modifiers.rs @@ -13,7 +13,7 @@ use rand::Rng; use std::sync::Arc; async fn add_execution_delay( - swarm: Arc>>, + swarm: Arc>>, config: &ExecutionDelayConfig, ) -> anyhow::Result<()> { let validators = { swarm.read().await.get_validator_clients_with_names() }; @@ -52,7 +52,7 @@ async fn add_execution_delay( } async fn remove_execution_delay( - swarm: Arc>>, + swarm: Arc>>, ) -> anyhow::Result<()> { let validators = { swarm.read().await.get_validator_clients_with_names() }; @@ -229,7 +229,7 @@ impl CpuChaosTest { /// not the fullnodes). async fn create_cpu_chaos( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> SwarmCpuStress { let all_validators = swarm .read() diff --git a/testsuite/testcases/src/multi_region_network_test.rs b/testsuite/testcases/src/multi_region_network_test.rs index ab95b9962f7..15ea01dae2d 100644 --- a/testsuite/testcases/src/multi_region_network_test.rs +++ b/testsuite/testcases/src/multi_region_network_test.rs @@ -86,13 +86,11 @@ fn create_link_stats_table_with_peer_groups( // Create the link stats table with peer groups let peer_chunks = chunk_peers(peers, number_of_regions); - let peer_groups = peer_chunks + peer_chunks .into_iter() .zip(link_stats_table.iter()) .map(|(chunk, (from_region, stats))| (from_region.clone(), chunk, stats.clone())) - .collect(); - - peer_groups + .collect() } // A map of "source" regions to a map of "destination" region to (bandwidth, latency) @@ -283,7 +281,7 @@ impl MultiRegionNetworkEmulationTest { /// the fullnodes). async fn create_netem_chaos( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> SwarmNetEm { let (all_validators, all_vfns) = { let swarm = swarm.read().await; diff --git a/testsuite/testcases/src/public_fullnode_performance.rs b/testsuite/testcases/src/public_fullnode_performance.rs index c32d058b858..147de0d240b 100644 --- a/testsuite/testcases/src/public_fullnode_performance.rs +++ b/testsuite/testcases/src/public_fullnode_performance.rs @@ -44,7 +44,7 @@ impl PFNPerformance { config_override_fn: Option, ) -> Self { // Create a random seed for the shuffle RNG - let shuffle_rng_seed: [u8; 32] = OsRng.gen(); + let shuffle_rng_seed: [u8; 32] = OsRng.r#gen(); Self { num_pfns, @@ -59,7 +59,7 @@ impl PFNPerformance { /// to all validators, VFNs and PFNs in the swarm. async fn create_cpu_chaos( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> SwarmCpuStress { // Gather and shuffle all peers IDs (so that we get random CPU chaos) let shuffled_peer_ids = self.gather_and_shuffle_peer_ids(swarm).await; @@ -72,7 +72,7 @@ impl PFNPerformance { /// is added to all validators, VFNs and PFNs in the swarm. async fn create_network_emulation_chaos( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> SwarmNetEm { // Gather and shuffle all peers IDs (so that we get random network emulation) let shuffled_peer_ids = self @@ -86,7 +86,7 @@ impl PFNPerformance { /// Gathers and shuffles all peer IDs in the swarm async fn gather_and_shuffle_peer_ids( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> Vec { // Identify the validators and fullnodes in the swarm let (validator_peer_ids, fullnode_peer_ids) = { @@ -110,7 +110,7 @@ impl PFNPerformance { /// Gathers and shuffles all peer IDs in the swarm, colocating VFNs with their validator async fn gather_and_shuffle_peer_ids_with_colocation( &self, - swarm: Arc>>, + swarm: Arc>>, ) -> Vec> { // Identify the validators and fullnodes in the swarm let (validator_peer_ids, fullnode_peer_ids) = { diff --git a/third_party/move/extensions/move-table-extension/Cargo.toml b/third_party/move/extensions/move-table-extension/Cargo.toml index 07a9759b45b..d34a3df181f 100644 --- a/third_party/move/extensions/move-table-extension/Cargo.toml +++ b/third_party/move/extensions/move-table-extension/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Diem Association "] description = "Wrapper for the Move VM which coordinates multiple extensions" repository = "https://github.com/diem/move" license = "Apache-2.0" -edition = "2021" +edition = { workspace = true } publish = false [dependencies] @@ -17,6 +17,7 @@ move-vm-runtime = { workspace = true } move-vm-types = { workspace = true } sha3 = { workspace = true } smallvec = { workspace = true } +triomphe = { workspace = true } [dev-dependencies] move-cli = { workspace = true } diff --git a/third_party/move/extensions/move-table-extension/src/lib.rs b/third_party/move/extensions/move-table-extension/src/lib.rs index e8af643f87d..917bf6f422e 100644 --- a/third_party/move/extensions/move-table-extension/src/lib.rs +++ b/third_party/move/extensions/move-table-extension/src/lib.rs @@ -19,8 +19,9 @@ use move_core_types::{ vm_status::StatusCode, }; use move_vm_runtime::{ + native_extensions::UnreachableSessionListener, native_functions, - native_functions::{NativeContext, NativeFunction, NativeFunctionTable}, + native_functions::{LoaderContext, NativeContext, NativeFunction, NativeFunctionTable}, }; use move_vm_types::{ loaded_data::runtime_types::Type, @@ -37,6 +38,7 @@ use std::{ fmt::{Debug, Display}, sync::Arc, }; +use triomphe::Arc as TriompheArc; // =========================================================================================== // Public Data Structures and Constants @@ -137,8 +139,8 @@ struct TableData { /// A structure representing a single table. struct Table { handle: TableHandle, - key_layout: MoveTypeLayout, - value_layout: MoveTypeLayout, + key_layout: TriompheArc, + value_layout: TriompheArc, content: BTreeMap, GlobalValue>, } @@ -148,6 +150,8 @@ const HANDLE_FIELD_INDEX: usize = 0; // ========================================================================================= // Implementation of Native Table Context +impl<'a> UnreachableSessionListener for NativeTableContext<'a> {} + impl<'a> NativeTableContext<'a> { /// Create a new instance of a native table context. This must be passed in via an /// extension into VM session functions. @@ -215,15 +219,21 @@ impl TableData { /// the table, like the type layout for keys and values. fn get_or_create_table( &mut self, - context: &NativeContext, + loader_context: &mut LoaderContext, handle: TableHandle, key_ty: &Type, value_ty: &Type, ) -> PartialVMResult<&mut Table> { Ok(match self.tables.entry(handle) { Entry::Vacant(e) => { - let key_layout = context.type_to_type_layout(key_ty)?; - let value_layout = context.type_to_type_layout(value_ty)?; + let key_layout = loader_context + .type_to_type_layout_with_delayed_fields(key_ty)? + .into_layout_when_has_no_delayed_fields() + .expect("Move extension has no delayed fields"); + let value_layout = loader_context + .type_to_type_layout_with_delayed_fields(value_ty)? + .into_layout_when_has_no_delayed_fields() + .expect("Move extension has no delayed fields"); let table = Table { handle, key_layout, @@ -345,7 +355,7 @@ pub struct NewTableHandleGasParameters { fn native_new_table_handle( gas_params: &NewTableHandleGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 2); @@ -394,14 +404,14 @@ fn native_add_box( common_gas_params: &CommonGasParameters, gas_params: &AddBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); assert_eq!(args.len(), 3); - let function_value_extension = context.function_value_extension(); - let table_context = context.extensions().get::(); + let (extensions, mut loader_context) = context.extensions_with_loader_context(); + let table_context = extensions.get::(); let mut table_data = table_context.table_data.borrow_mut(); let val = args.pop_back().unwrap(); @@ -410,8 +420,10 @@ fn native_add_box( let mut cost = gas_params.base; - let table = table_data.get_or_create_table(context, handle, &ty_args[0], &ty_args[2])?; + let table = + table_data.get_or_create_table(&mut loader_context, handle, &ty_args[0], &ty_args[2])?; + let function_value_extension = loader_context.function_value_extension(); let key_bytes = serialize(&function_value_extension, &table.key_layout, &key)?; cost += gas_params.per_byte_serialized * NumBytes::new(key_bytes.len() as u64); @@ -446,23 +458,25 @@ fn native_borrow_box( common_gas_params: &CommonGasParameters, gas_params: &BorrowBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); assert_eq!(args.len(), 2); - let function_value_extension = context.function_value_extension(); - let table_context = context.extensions().get::(); + let (extensions, mut loader_context) = context.extensions_with_loader_context(); + let table_context = extensions.get::(); let mut table_data = table_context.table_data.borrow_mut(); let key = args.pop_back().unwrap(); let handle = get_table_handle(&pop_arg!(args, StructRef))?; - let table = table_data.get_or_create_table(context, handle, &ty_args[0], &ty_args[2])?; + let table = + table_data.get_or_create_table(&mut loader_context, handle, &ty_args[0], &ty_args[2])?; let mut cost = gas_params.base; + let function_value_extension = loader_context.function_value_extension(); let key_bytes = serialize(&function_value_extension, &table.key_layout, &key)?; cost += gas_params.per_byte_serialized * NumBytes::new(key_bytes.len() as u64); @@ -497,23 +511,25 @@ fn native_contains_box( common_gas_params: &CommonGasParameters, gas_params: &ContainsBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); assert_eq!(args.len(), 2); - let function_value_extension = context.function_value_extension(); - let table_context = context.extensions().get::(); + let (extensions, mut loader_context) = context.extensions_with_loader_context(); + let table_context = extensions.get::(); let mut table_data = table_context.table_data.borrow_mut(); let key = args.pop_back().unwrap(); let handle = get_table_handle(&pop_arg!(args, StructRef))?; - let table = table_data.get_or_create_table(context, handle, &ty_args[0], &ty_args[2])?; + let table = + table_data.get_or_create_table(&mut loader_context, handle, &ty_args[0], &ty_args[2])?; let mut cost = gas_params.base; + let function_value_extension = loader_context.function_value_extension(); let key_bytes = serialize(&function_value_extension, &table.key_layout, &key)?; cost += gas_params.per_byte_serialized * NumBytes::new(key_bytes.len() as u64); @@ -521,7 +537,7 @@ fn native_contains_box( table.get_or_create_global_value(&function_value_extension, table_context, key_bytes)?; cost += common_gas_params.calculate_load_cost(loaded); - let exists = Value::bool(gv.exists()?); + let exists = Value::bool(gv.exists()); Ok(NativeResult::ok(cost, smallvec![exists])) } @@ -547,23 +563,25 @@ fn native_remove_box( common_gas_params: &CommonGasParameters, gas_params: &RemoveGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); assert_eq!(args.len(), 2); - let function_value_extension = context.function_value_extension(); - let table_context = context.extensions().get::(); + let (extensions, mut loader_context) = context.extensions_with_loader_context(); + let table_context = extensions.get::(); let mut table_data = table_context.table_data.borrow_mut(); let key = args.pop_back().unwrap(); let handle = get_table_handle(&pop_arg!(args, StructRef))?; - let table = table_data.get_or_create_table(context, handle, &ty_args[0], &ty_args[2])?; + let table = + table_data.get_or_create_table(&mut loader_context, handle, &ty_args[0], &ty_args[2])?; let mut cost = gas_params.base; + let function_value_extension = loader_context.function_value_extension(); let key_bytes = serialize(&function_value_extension, &table.key_layout, &key)?; cost += gas_params.per_byte_serialized * NumBytes::new(key_bytes.len() as u64); @@ -596,18 +614,19 @@ pub struct DestroyEmptyBoxGasParameters { fn native_destroy_empty_box( gas_params: &DestroyEmptyBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); assert_eq!(args.len(), 1); - let table_context = context.extensions().get::(); + let (extensions, mut loader_context) = context.extensions_with_loader_context(); + let table_context = extensions.get::(); let mut table_data = table_context.table_data.borrow_mut(); let handle = get_table_handle(&pop_arg!(args, StructRef))?; // TODO: Can the following line be removed? - table_data.get_or_create_table(context, handle, &ty_args[0], &ty_args[2])?; + table_data.get_or_create_table(&mut loader_context, handle, &ty_args[0], &ty_args[2])?; assert!(table_data.removed_tables.insert(handle)); @@ -630,7 +649,7 @@ pub struct DropUncheckedBoxGasParameters { fn native_drop_unchecked_box( gas_params: &DropUncheckedBoxGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); diff --git a/third_party/move/extensions/move-table-extension/tests/move_unit_tests.rs b/third_party/move/extensions/move-table-extension/tests/move_unit_tests.rs index f12fee63e20..812b894c8f1 100644 --- a/third_party/move/extensions/move-table-extension/tests/move_unit_tests.rs +++ b/third_party/move/extensions/move-table-extension/tests/move_unit_tests.rs @@ -33,6 +33,7 @@ fn run_tests_for_pkg(path_to_pkg: impl Into) { /* cost_table */ None, /* compute_coverage */ false, &mut std::io::stdout(), + false, ); if res.is_err() || res.is_ok_and(|r| r == UnitTestResult::Failure) { panic!("move unit tests failed") diff --git a/third_party/move/move-binary-format/Cargo.toml b/third_party/move/move-binary-format/Cargo.toml index a701e9992c1..01aaa01391d 100644 --- a/third_party/move/move-binary-format/Cargo.toml +++ b/third_party/move/move-binary-format/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = ["crates-io"] -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } @@ -17,6 +17,7 @@ dearbitrary = { workspace = true, optional = true, features = ["derive"] } indexmap = { workspace = true } move-bytecode-spec = { workspace = true } move-core-types = { workspace = true } +once_cell = { workspace = true } proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } ref-cast = { workspace = true } diff --git a/third_party/move/move-binary-format/serializer-tests/Cargo.toml b/third_party/move/move-binary-format/serializer-tests/Cargo.toml index 8dd29651dec..cc6cd11ddd9 100644 --- a/third_party/move/move-binary-format/serializer-tests/Cargo.toml +++ b/third_party/move/move-binary-format/serializer-tests/Cargo.toml @@ -7,13 +7,14 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dev-dependencies] move-binary-format = { workspace = true, features = ["fuzzing"] } move-core-types = { workspace = true } proptest = { workspace = true } proptest-derive = { workspace = true } +similar-asserts = "1.7.0" [features] fuzzing = ["move-binary-format/fuzzing"] diff --git a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.proptest-regressions b/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.proptest-regressions deleted file mode 100644 index c6765cae798..00000000000 --- a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.proptest-regressions +++ /dev/null @@ -1,10 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 3d00be1cbcb9f344e7bce080015d7a755f6e69acd37dbde62e449732af226fe4 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, flags: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } -cc 7b1bb969b87bfcdbb0f635eb46212f8437d21bcd1ba754de84d66bb552e6aec2 # shrinks to module = CompiledModule { module_handles: [], struct_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000], struct_defs: [], field_defs: [], function_defs: [] } -cc 4118fc247fb7d48382876de931d47a8999a6e42658bbecc93afff9245ade141b # shrinks to module = CompiledModule { module_handles: [], struct_handles: [], function_handles: [], type_signatures: [], function_signatures: [], locals_signatures: [], string_pool: [], byte_array_pool: [], address_pool: [], struct_defs: [], field_defs: [FieldDefinition { struct_: StructHandleIndex(0), name: IdentifierIndex(0), signature: TypeSignatureIndex(0) }], function_defs: [] } -cc 42cd5d033842c708fc3a704a573a77455676f33b4cb987516cee12efeaa33655 # shrinks to module = CompiledModule { version: 7, self_module_handle_idx: ModuleHandleIndex(0), module_handles: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }], struct_handles: [StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(7), abilities: [Copy, Store, ], type_parameters: [StructTypeParameter { constraints: [Copy, ], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(16), abilities: [Copy, Drop, Store, ], type_parameters: [StructTypeParameter { constraints: [Drop, ], is_phantom: false }, StructTypeParameter { constraints: [], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(10), abilities: [Copy, ], type_parameters: [] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(15), abilities: [], type_parameters: [StructTypeParameter { constraints: [], is_phantom: true }, StructTypeParameter { constraints: [Copy, Store, ], is_phantom: false }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(12), abilities: [Copy, ], type_parameters: [] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), abilities: [Drop, ], type_parameters: [StructTypeParameter { constraints: [Copy, Drop, Store, ], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(5), abilities: [Copy, ], type_parameters: [StructTypeParameter { constraints: [Copy, Store, ], is_phantom: false }, StructTypeParameter { constraints: [], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(13), abilities: [Drop, ], type_parameters: [StructTypeParameter { constraints: [Copy, Drop, ], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(3), abilities: [Drop, ], type_parameters: [StructTypeParameter { constraints: [Drop, Store, ], is_phantom: false }, StructTypeParameter { constraints: [Copy, Drop, Store, ], is_phantom: false }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), abilities: [Drop, ], type_parameters: [StructTypeParameter { constraints: [Copy, Drop, Store, ], is_phantom: true }] }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(6), abilities: [Copy, ], type_parameters: [StructTypeParameter { constraints: [], is_phantom: false }, StructTypeParameter { constraints: [Drop, Store, ], is_phantom: true }] }], function_handles: [FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(9), parameters: SignatureIndex(2), return_: SignatureIndex(3), type_parameters: [], access_specifiers: None }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(16), parameters: SignatureIndex(5), return_: SignatureIndex(6), type_parameters: [], access_specifiers: None }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(4), parameters: SignatureIndex(9), return_: SignatureIndex(10), type_parameters: [], access_specifiers: None }], field_handles: [], friend_decls: [ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(0) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(2) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(4) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(5) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(10) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(12) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(13) }, ModuleHandle { address: AddressIdentifierIndex(0), name: IdentifierIndex(14) }], struct_def_instantiations: [StructDefInstantiation { def: StructDefinitionIndex(10), type_parameters: SignatureIndex(4) }, StructDefInstantiation { def: StructDefinitionIndex(5), type_parameters: SignatureIndex(7) }, StructDefInstantiation { def: StructDefinitionIndex(8), type_parameters: SignatureIndex(4) }], function_instantiations: [], field_instantiations: [], signatures: [Signature([U32, Bool]), Signature([U16, Address, U32]), Signature([]), Signature([Reference(Bool)]), Signature([U64, U64]), Signature([StructInstantiation(StructHandleIndex(7), [U64]), Reference(U32)]), Signature([U16, Reference(U256)]), Signature([U64]), Signature([StructInstantiation(StructHandleIndex(3), [U64, U64])]), Signature([StructInstantiation(StructHandleIndex(8), [U64, U64]), Vector(Signer), U8]), Signature([U128, MutableReference(Address)]), Signature([Bool])], identifiers: [Identifier("A"), Identifier("A0"), Identifier("AA"), Identifier("AB"), Identifier("AC"), Identifier("AD"), Identifier("AE"), Identifier("A_"), Identifier("Aa"), Identifier("a"), Identifier("a0"), Identifier("a1"), Identifier("a2"), Identifier("a3"), Identifier("aA"), Identifier("a_"), Identifier("aa")], address_identifiers: [0000000000000000000000000000000000000000000000000000000000000000], constant_pool: [], metadata: [], struct_defs: [StructDefinition { struct_handle: StructHandleIndex(0), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(1), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(2), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(3), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(4), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(5), field_information: Declared([FieldDefinition { name: IdentifierIndex(16), signature: TypeSignature(U64) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(12), signature: TypeSignature(U64) }]) }, StructDefinition { struct_handle: StructHandleIndex(6), field_information: DeclaredVariants([VariantDefinition { name: IdentifierIndex(2), fields: [FieldDefinition { name: IdentifierIndex(5), signature: TypeSignature(U256) }] }]) }, StructDefinition { struct_handle: StructHandleIndex(7), field_information: Native }, StructDefinition { struct_handle: StructHandleIndex(8), field_information: DeclaredVariants([VariantDefinition { name: IdentifierIndex(14), fields: [FieldDefinition { name: IdentifierIndex(11), signature: TypeSignature(StructInstantiation(StructHandleIndex(1), [Signer, U64])) }] }, VariantDefinition { name: IdentifierIndex(10), fields: [] }]) }, StructDefinition { struct_handle: StructHandleIndex(9), field_information: DeclaredVariants([VariantDefinition { name: IdentifierIndex(14), fields: [FieldDefinition { name: IdentifierIndex(13), signature: TypeSignature(Bool) }, FieldDefinition { name: IdentifierIndex(9), signature: TypeSignature(U16) }, FieldDefinition { name: IdentifierIndex(14), signature: TypeSignature(Address) }, FieldDefinition { name: IdentifierIndex(7), signature: TypeSignature(Signer) }] }]) }, StructDefinition { struct_handle: StructHandleIndex(10), field_information: Native }], function_defs: [FunctionDefinition { function: FunctionHandleIndex(0), visibility: Private, is_entry: true, acquires_global_resources: [StructDefinitionIndex(5)], code: Some(CodeUnit { locals: SignatureIndex(2), code: [MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), Branch(0)] }) }, FunctionDefinition { function: FunctionHandleIndex(1), visibility: Private, is_entry: false, acquires_global_resources: [StructDefinitionIndex(10)], code: Some(CodeUnit { locals: SignatureIndex(8), code: [Call(0), Xor, ImmBorrowVariantFieldGeneric(VariantFieldInstantiationIndex(0)), ExistsGeneric(StructDefInstantiationIndex(1)), ImmBorrowGlobal(StructDefinitionIndex(4)), MoveFromGeneric(StructDefInstantiationIndex(2)), BrFalse(1), ImmBorrowLoc(0), MutBorrowGlobalGeneric(StructDefInstantiationIndex(1)), ImmBorrowLoc(0), ExistsGeneric(StructDefInstantiationIndex(0)), ImmBorrowLoc(0), Exists(StructDefinitionIndex(2)), MutBorrowLoc(0), MoveToGeneric(StructDefInstantiationIndex(1))] }) }, FunctionDefinition { function: FunctionHandleIndex(2), visibility: Friend, is_entry: true, acquires_global_resources: [], code: Some(CodeUnit { locals: SignatureIndex(11), code: [StLoc(0), ImmBorrowVariantFieldGeneric(VariantFieldInstantiationIndex(1))] }) }], struct_variant_handles: [], struct_variant_instantiations: [], variant_field_handles: [VariantFieldHandle { owner: StructDefinitionIndex(9), variants: [0], field: 3 }, VariantFieldHandle { owner: StructDefinitionIndex(6), variants: [0], field: 0 }], variant_field_instantiations: [VariantFieldInstantiation { handle: VariantFieldHandleIndex(0), type_parameters: SignatureIndex(7) }, VariantFieldInstantiation { handle: VariantFieldHandleIndex(1), type_parameters: SignatureIndex(4) }] } diff --git a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs b/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs index 87c8ec664e9..87fefbd8f59 100644 --- a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs +++ b/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs @@ -16,6 +16,7 @@ use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, }; use proptest::prelude::*; +use similar_asserts::SimpleDiff; proptest! { #[test] @@ -46,7 +47,12 @@ proptest! { let deserialized_module = CompiledModule::deserialize_no_check_bounds(&serialized) .expect("deserialization should work"); - prop_assert_eq!(module, deserialized_module); + if module != deserialized_module { + let expected = format!("{:?}", module); + let actual = format!("{:?}", deserialized_module); + let diff = SimpleDiff::from_str(&expected, &actual, "expected", "actual"); + prop_assert!(false, "roundtrip failed: {}\n", diff) + } } } diff --git a/third_party/move/move-binary-format/src/binary_views.rs b/third_party/move/move-binary-format/src/binary_views.rs index aa244c086d4..29039024324 100644 --- a/third_party/move/move-binary-format/src/binary_views.rs +++ b/third_party/move/move-binary-format/src/binary_views.rs @@ -336,7 +336,8 @@ impl BinaryIndexedView<'_> { use SignatureToken::*; match ty { - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address => Ok(AbilitySet::PRIMITIVES), + Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | I8 | I16 | I32 | I64 | I128 + | I256 => Ok(AbilitySet::PRIMITIVES), Reference(_) | MutableReference(_) => Ok(AbilitySet::REFERENCES), Signer => Ok(AbilitySet::SIGNER), diff --git a/third_party/move/move-binary-format/src/builders.rs b/third_party/move/move-binary-format/src/builders.rs index e42812213a1..674f62f946f 100644 --- a/third_party/move/move-binary-format/src/builders.rs +++ b/third_party/move/move-binary-format/src/builders.rs @@ -226,6 +226,12 @@ impl CompiledScriptBuilder { U64 => U64, U128 => U128, U256 => U256, + I8 => I8, + I16 => I16, + I32 => I32, + I64 => I64, + I128 => I128, + I256 => I256, Bool => Bool, Address => Address, Signer => Signer, @@ -312,9 +318,9 @@ impl CompiledScriptBuilder { name: &IdentStr, module: &CompiledModule, ) -> PartialVMResult { - for (idx, handle) in module.function_handles().iter().enumerate() { - if module.identifier_at(handle.name) == name { - return self.import_function_by_handle(module, FunctionHandleIndex(idx as u16)); + for def in module.function_defs().iter() { + if module.identifier_at(module.function_handle_at(def.function).name) == name { + return self.import_function_by_handle(module, def.function); } } Err(PartialVMError::new(StatusCode::LOOKUP_FAILED)) diff --git a/third_party/move/move-binary-format/src/check_bounds.rs b/third_party/move/move-binary-format/src/check_bounds.rs index 6f259d57b72..a31d107399c 100644 --- a/third_party/move/move-binary-format/src/check_bounds.rs +++ b/third_party/move/move-binary-format/src/check_bounds.rs @@ -144,8 +144,8 @@ impl<'a> BoundsChecker<'a> { } fn check_module_handles(&self) -> PartialVMResult<()> { - for script_handle in self.view.module_handles() { - self.check_module_handle(script_handle)? + for module_handle in self.view.module_handles() { + self.check_module_handle(module_handle)? } Ok(()) } @@ -240,7 +240,7 @@ impl<'a> BoundsChecker<'a> { check_bounds_impl(self.view.identifiers(), function_handle.name)?; check_bounds_impl(self.view.signatures(), function_handle.parameters)?; check_bounds_impl(self.view.signatures(), function_handle.return_)?; - // function signature type paramters must be in bounds to the function type parameters + // function signature type parameters must be in bounds to the function type parameters let type_param_count = function_handle.type_parameters.len(); self.check_type_parameters_in_signature(function_handle.parameters, type_param_count)?; self.check_type_parameters_in_signature(function_handle.return_, type_param_count)?; @@ -670,21 +670,27 @@ impl<'a> BoundsChecker<'a> { // bytecode gets added. FreezeRef | Pop | Ret | LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU256(_) | LdU128(_) | CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 - | LdTrue | LdFalse | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div | BitOr - | BitAnd | Xor | Shl | Shr | Or | And | Not | Eq | Neq | Lt | Gt | Le | Ge - | Abort | Nop => (), + | LdI8(_) | LdI16(_) | LdI32(_) | LdI64(_) | LdI256(_) | LdI128(_) | CastI8 + | CastI16 | CastI32 | CastI64 | CastI128 | CastI256 | LdTrue | LdFalse + | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div | Negate | BitOr | BitAnd + | Xor | Shl | Shr | Or | And | Not | Eq | Neq | Lt | Gt | Le | Ge | Abort | Nop => { + }, } } Ok(()) } + /// Check `ty` for: + /// - struct handle bounds + /// - struct instantiations have the correct number of type parameters fn check_type(&self, ty: &SignatureToken) -> PartialVMResult<()> { use self::SignatureToken::*; for ty in ty.preorder_traversal() { match ty { Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer | TypeParameter(_) - | Reference(_) | MutableReference(_) | Vector(_) | Function(..) => (), + | Reference(_) | MutableReference(_) | Vector(_) | Function(..) | I8 | I16 + | I32 | I64 | I128 | I256 => (), Struct(idx) => { check_bounds_impl(self.view.struct_handles(), *idx)?; if let Some(sh) = self.view.struct_handles().get(idx.into_index()) { diff --git a/third_party/move/move-binary-format/src/check_complexity.rs b/third_party/move/move-binary-format/src/check_complexity.rs index c081334eda7..4e9a4ce4922 100644 --- a/third_party/move/move-binary-format/src/check_complexity.rs +++ b/third_party/move/move-binary-format/src/check_complexity.rs @@ -67,8 +67,9 @@ impl BinaryComplexityMeter<'_> { cost = cost.saturating_add(struct_name.len() as u64 * COST_PER_IDENT_BYTE); cost = cost.saturating_add(moduel_name.len() as u64 * COST_PER_IDENT_BYTE); }, - U8 | U16 | U32 | U64 | U128 | U256 | Signer | Address | Bool | Vector(_) - | Function(..) | TypeParameter(_) | Reference(_) | MutableReference(_) => (), + U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Signer | Address | Bool | Vector(_) | Function(..) | TypeParameter(_) + | Reference(_) | MutableReference(_) => (), } } @@ -309,6 +310,12 @@ impl BinaryComplexityMeter<'_> { | LdU64(_) | LdU128(_) | LdU256(_) + | LdI8(_) + | LdI16(_) + | LdI32(_) + | LdI64(_) + | LdI128(_) + | LdI256(_) | LdConst(_) | CastU8 | CastU16 @@ -316,6 +323,12 @@ impl BinaryComplexityMeter<'_> { | CastU64 | CastU128 | CastU256 + | CastI8 + | CastI16 + | CastI32 + | CastI64 + | CastI128 + | CastI256 | LdTrue | LdFalse | Call(_) @@ -333,6 +346,7 @@ impl BinaryComplexityMeter<'_> { | Mul | Mod | Div + | Negate | BitOr | BitAnd | Xor diff --git a/third_party/move/move-binary-format/src/compatibility.rs b/third_party/move/move-binary-format/src/compatibility.rs index 680c091d3c8..b7344afef9d 100644 --- a/third_party/move/move-binary-format/src/compatibility.rs +++ b/third_party/move/move-binary-format/src/compatibility.rs @@ -35,6 +35,9 @@ pub struct Compatibility { pub(crate) check_friend_linking: bool, /// if false, entry function will be treated as regular function. pub(crate) treat_entry_as_public: bool, + /// A temporary flag to preserve compatibility. + /// TODO(#17171): remove this once 1.34 rolled out + function_type_compat_bug: bool, } impl Default for Compatibility { @@ -44,6 +47,7 @@ impl Default for Compatibility { check_struct_layout: true, check_friend_linking: true, treat_entry_as_public: true, + function_type_compat_bug: false, } } } @@ -59,6 +63,7 @@ impl Compatibility { check_struct_layout: false, check_friend_linking: false, treat_entry_as_public: false, + function_type_compat_bug: false, } } @@ -66,12 +71,15 @@ impl Compatibility { check_struct_layout: bool, check_friend_linking: bool, treat_entry_as_public: bool, + // TODO: remove this once 1.34 is released + function_type_compat_bug: bool, ) -> Self { Self { check_struct_and_pub_function_linking: true, check_struct_layout, check_friend_linking, treat_entry_as_public, + function_type_compat_bug, } } @@ -117,14 +125,14 @@ impl Compatibility { }, }; - if !struct_abilities_compatible(old_struct.abilities(), new_struct.abilities()) { + if !self.struct_abilities_compatible(old_struct.abilities(), new_struct.abilities()) { errors.push(format!( "removed abilities `{}` from struct `{}`", old_struct.abilities().setminus(new_struct.abilities()), old_struct.name() )); } - if !struct_type_parameters_compatible( + if !self.struct_type_parameters_compatible( old_struct.type_parameters(), new_struct.type_parameters(), ) { @@ -134,7 +142,7 @@ impl Compatibility { )); } // Layout of old and new struct need to be compatible - if self.check_struct_layout && !struct_layout_compatible(&old_struct, new_struct) { + if self.check_struct_layout && !self.struct_layout_compatible(&old_struct, new_struct) { errors.push(format!("changed layout of struct `{}`", old_struct.name())); } } @@ -227,21 +235,21 @@ impl Compatibility { Some("removed `entry` modifier") } else if !is_attribute_compatible { Some("removed required attributes") - } else if !signature_compatible( + } else if !self.signature_compatible( old_module, old_func.parameters(), new_module, new_func.parameters(), ) { Some("changed parameter types") - } else if !signature_compatible( + } else if !self.signature_compatible( old_module, old_func.return_type(), new_module, new_func.return_type(), ) { Some("changed return type") - } else if !fun_type_parameters_compatible( + } else if !self.fun_type_parameters_compatible( old_func.type_parameters(), new_func.type_parameters(), ) { @@ -291,186 +299,252 @@ impl Compatibility { Ok(()) } } -} -// When upgrading, the new abilities must be a superset of the old abilities. -// Adding an ability is fine, but removing an ability could cause existing usages to fail. -fn struct_abilities_compatible(old_abilities: AbilitySet, new_abilities: AbilitySet) -> bool { - old_abilities.is_subset(new_abilities) -} + // When upgrading, the new abilities must be a superset of the old abilities. + // Adding an ability is fine, but removing an ability could cause existing usages to fail. + fn struct_abilities_compatible( + &self, + old_abilities: AbilitySet, + new_abilities: AbilitySet, + ) -> bool { + old_abilities.is_subset(new_abilities) + } -// When upgrading, the new type parameters must be the same length, and the new type parameter -// constraints must be compatible -fn fun_type_parameters_compatible( - old_type_parameters: &[AbilitySet], - new_type_parameters: &[AbilitySet], -) -> bool { - old_type_parameters.len() == new_type_parameters.len() - && old_type_parameters.iter().zip(new_type_parameters).all( - |(old_type_parameter_constraint, new_type_parameter_constraint)| { - type_parameter_constraints_compatible( - *old_type_parameter_constraint, - *new_type_parameter_constraint, - ) - }, - ) -} + // When upgrading, the new type parameters must be the same length, and the new type parameter + // constraints must be compatible + fn fun_type_parameters_compatible( + &self, + old_type_parameters: &[AbilitySet], + new_type_parameters: &[AbilitySet], + ) -> bool { + old_type_parameters.len() == new_type_parameters.len() + && old_type_parameters.iter().zip(new_type_parameters).all( + |(old_type_parameter_constraint, new_type_parameter_constraint)| { + self.type_parameter_constraints_compatible( + *old_type_parameter_constraint, + *new_type_parameter_constraint, + ) + }, + ) + } -fn struct_type_parameters_compatible( - old_type_parameters: &[StructTypeParameter], - new_type_parameters: &[StructTypeParameter], -) -> bool { - old_type_parameters.len() == new_type_parameters.len() - && old_type_parameters.iter().zip(new_type_parameters).all( - |(old_type_parameter, new_type_parameter)| { - type_parameter_phantom_decl_compatible(old_type_parameter, new_type_parameter) - && type_parameter_constraints_compatible( + fn struct_type_parameters_compatible( + &self, + old_type_parameters: &[StructTypeParameter], + new_type_parameters: &[StructTypeParameter], + ) -> bool { + old_type_parameters.len() == new_type_parameters.len() + && old_type_parameters.iter().zip(new_type_parameters).all( + |(old_type_parameter, new_type_parameter)| { + self.type_parameter_phantom_decl_compatible( + old_type_parameter, + new_type_parameter, + ) && self.type_parameter_constraints_compatible( old_type_parameter.constraints, new_type_parameter.constraints, ) - }, - ) -} - -fn struct_layout_compatible( - old_struct: &StructDefinitionView, - new_struct: &StructDefinitionView, -) -> bool { - if old_struct.variant_count() == 0 { - // Old is regular struct, new needs to be as well (i.e. have zero variants) and compatible - // fields. - new_struct.variant_count() == 0 - && fields_compatible( - old_struct.fields_optional_variant(None), - new_struct.fields_optional_variant(None), + }, ) - } else { - // Enum: the prefix of variants in the old definition must be the same as in the new one. - // (a) the variant names need to match - // (b) the variant fields need to be compatible - old_struct.variant_count() <= new_struct.variant_count() - && (0..old_struct.variant_count()).all(|i| { - let v_idx = i as VariantIndex; - old_struct.variant_name(v_idx) == new_struct.variant_name(v_idx) - && fields_compatible( - old_struct.fields_optional_variant(Some(v_idx)), - new_struct.fields_optional_variant(Some(v_idx)), - ) - }) } -} -fn fields_compatible<'a, 'b>( - mut old_fields: impl Iterator>, - mut new_fields: impl Iterator>, -) -> bool { - loop { - match (old_fields.next(), new_fields.next()) { - (Some(old_field), Some(new_field)) => { - // Require names and types to be equal. Notice this is a stricter definition - // than required. We could in principle choose that changing the name - // (but not position or type) of a field is compatible. The VM does not care about - // the name of a field but clients presumably do. - if old_field.name() != new_field.name() - || !signature_token_compatible( - old_field.module(), - old_field.signature_token(), - new_field.module(), - new_field.signature_token(), - ) - { - return false; - } - }, - (None, None) => return true, - _ => return false, + fn struct_layout_compatible( + &self, + old_struct: &StructDefinitionView, + new_struct: &StructDefinitionView, + ) -> bool { + if old_struct.variant_count() == 0 { + // Old is regular struct, new needs to be as well (i.e. have zero variants) and compatible + // fields. + new_struct.variant_count() == 0 + && self.fields_compatible( + old_struct.fields_optional_variant(None), + new_struct.fields_optional_variant(None), + ) + } else { + // Enum: the prefix of variants in the old definition must be the same as in the new one. + // (a) the variant names need to match + // (b) the variant fields need to be compatible + old_struct.variant_count() <= new_struct.variant_count() + && (0..old_struct.variant_count()).all(|i| { + let v_idx = i as VariantIndex; + old_struct.variant_name(v_idx) == new_struct.variant_name(v_idx) + && self.fields_compatible( + old_struct.fields_optional_variant(Some(v_idx)), + new_struct.fields_optional_variant(Some(v_idx)), + ) + }) } } -} -fn signature_compatible( - old_module: &CompiledModule, - old_sig: &Signature, - new_module: &CompiledModule, - new_sig: &Signature, -) -> bool { - old_sig.0.len() == new_sig.0.len() - && old_sig - .0 - .iter() - .zip(new_sig.0.iter()) - .all(|(old_tok, new_tok)| { - signature_token_compatible(old_module, old_tok, new_module, new_tok) - }) -} + fn fields_compatible<'a, 'b>( + &self, + mut old_fields: impl Iterator>, + mut new_fields: impl Iterator>, + ) -> bool { + loop { + match (old_fields.next(), new_fields.next()) { + (Some(old_field), Some(new_field)) => { + // Require names and types to be equal. Notice this is a stricter definition + // than required. We could in principle choose that changing the name + // (but not position or type) of a field is compatible. The VM does not care about + // the name of a field but clients presumably do. + if old_field.name() != new_field.name() + || !self.signature_token_compatible( + old_field.module(), + old_field.signature_token(), + new_field.module(), + new_field.signature_token(), + ) + { + return false; + } + }, + (None, None) => return true, + _ => return false, + } + } + } -fn signature_token_compatible( - old_module: &CompiledModule, - old_tok: &SignatureToken, - new_module: &CompiledModule, - new_tok: &SignatureToken, -) -> bool { - match (old_tok, new_tok) { - (SignatureToken::Reference(old_elem), SignatureToken::Reference(new_elem)) => { - signature_token_compatible(old_module, old_elem, new_module, new_elem) - }, - ( - SignatureToken::MutableReference(old_elem), - SignatureToken::MutableReference(new_elem), - ) => signature_token_compatible(old_module, old_elem, new_module, new_elem), - (SignatureToken::Vector(old_elem), SignatureToken::Vector(new_elem)) => { - signature_token_compatible(old_module, old_elem, new_module, new_elem) - }, - (SignatureToken::Struct(old_handle), SignatureToken::Struct(new_handle)) => { - struct_equal(old_module, *old_handle, new_module, *new_handle) - }, - ( - SignatureToken::StructInstantiation(old_handle, old_args), - SignatureToken::StructInstantiation(new_handle, new_args), - ) => { - struct_equal(old_module, *old_handle, new_module, *new_handle) - && old_args.len() == new_args.len() - && (0..old_args.len()).all(|i| { - signature_token_compatible(old_module, &old_args[i], new_module, &new_args[i]) + fn signature_compatible( + &self, + old_module: &CompiledModule, + old_sig: &Signature, + new_module: &CompiledModule, + new_sig: &Signature, + ) -> bool { + old_sig.0.len() == new_sig.0.len() + && old_sig + .0 + .iter() + .zip(new_sig.0.iter()) + .all(|(old_tok, new_tok)| { + self.signature_token_compatible(old_module, old_tok, new_module, new_tok) }) - }, - _ => { - // Map to representation equality. Notice that after handling of the cases above, - // two signature tokens which have equal representation are also logically equal. - // This is _not_ the case if handles are involved: for instance, Struct(h1) and - // Struct(h2) can be different even if h1 == h2, but stem from different modules. - old_tok == new_tok - }, } -} -fn struct_equal( - old_module: &CompiledModule, - old_handle: StructHandleIndex, - new_module: &CompiledModule, - new_handle: StructHandleIndex, -) -> bool { - let old_struct = StructHandleView::new(old_module, old_module.struct_handle_at(old_handle)); - let new_struct = StructHandleView::new(new_module, new_module.struct_handle_at(new_handle)); - old_struct.name() == new_struct.name() && old_struct.module_id() == new_struct.module_id() -} + fn signature_token_compatible( + &self, + old_module: &CompiledModule, + old_tok: &SignatureToken, + new_module: &CompiledModule, + new_tok: &SignatureToken, + ) -> bool { + let vec_ok = |old_tys: &[SignatureToken], new_tys: &[SignatureToken]| -> bool { + old_tys.len() == new_tys.len() + && old_tys.iter().zip(new_tys).all(|(old, new)| { + self.signature_token_compatible(old_module, old, new_module, new) + }) + }; + match (old_tok, new_tok) { + (SignatureToken::Bool, SignatureToken::Bool) + | (SignatureToken::U8, SignatureToken::U8) + | (SignatureToken::U16, SignatureToken::U16) + | (SignatureToken::U32, SignatureToken::U32) + | (SignatureToken::U64, SignatureToken::U64) + | (SignatureToken::U128, SignatureToken::U128) + | (SignatureToken::U256, SignatureToken::U256) + | (SignatureToken::Address, SignatureToken::Address) + | (SignatureToken::Signer, SignatureToken::Signer) + | (SignatureToken::I8, SignatureToken::I8) + | (SignatureToken::I16, SignatureToken::I16) + | (SignatureToken::I32, SignatureToken::I32) + | (SignatureToken::I64, SignatureToken::I64) + | (SignatureToken::I128, SignatureToken::I128) + | (SignatureToken::I256, SignatureToken::I256) => true, + (SignatureToken::TypeParameter(old_idx), SignatureToken::TypeParameter(new_idx)) => { + old_idx == new_idx + }, + (SignatureToken::Reference(old_elem), SignatureToken::Reference(new_elem)) => { + self.signature_token_compatible(old_module, old_elem, new_module, new_elem) + }, + ( + SignatureToken::MutableReference(old_elem), + SignatureToken::MutableReference(new_elem), + ) => self.signature_token_compatible(old_module, old_elem, new_module, new_elem), + (SignatureToken::Vector(old_elem), SignatureToken::Vector(new_elem)) => { + self.signature_token_compatible(old_module, old_elem, new_module, new_elem) + }, + (SignatureToken::Struct(old_handle), SignatureToken::Struct(new_handle)) => { + self.struct_equal(old_module, *old_handle, new_module, *new_handle) + }, + ( + SignatureToken::StructInstantiation(old_handle, old_args), + SignatureToken::StructInstantiation(new_handle, new_args), + ) => { + self.struct_equal(old_module, *old_handle, new_module, *new_handle) + && vec_ok(old_args, new_args) + }, + ( + SignatureToken::Function(old_args, old_results, old_abilities), + SignatureToken::Function(new_args, new_results, new_abilities), + ) => { + // Before bug #17171 was fixed, function types where compared with representation + // equality. Simulate this behavior if requested. + // TODO(#17171): remove this once fix rolled out + if self.function_type_compat_bug { + old_tok == new_tok + } else { + vec_ok(old_args, new_args) + && vec_ok(old_results, new_results) + && old_abilities == new_abilities + } + }, + (SignatureToken::Bool, _) + | (SignatureToken::U8, _) + | (SignatureToken::U64, _) + | (SignatureToken::U128, _) + | (SignatureToken::Address, _) + | (SignatureToken::Signer, _) + | (SignatureToken::Vector(_), _) + | (SignatureToken::Function(..), _) + | (SignatureToken::Struct(_), _) + | (SignatureToken::StructInstantiation(_, _), _) + | (SignatureToken::Reference(_), _) + | (SignatureToken::MutableReference(_), _) + | (SignatureToken::TypeParameter(_), _) + | (SignatureToken::U16, _) + | (SignatureToken::U32, _) + | (SignatureToken::U256, _) + | (SignatureToken::I8, _) + | (SignatureToken::I16, _) + | (SignatureToken::I32, _) + | (SignatureToken::I64, _) + | (SignatureToken::I128, _) + | (SignatureToken::I256, _) => false, + } + } -// When upgrading, the new constraints must be a subset of (or equal to) the old constraints. -// Removing an ability is fine, but adding an ability could cause existing callsites to fail -fn type_parameter_constraints_compatible( - old_type_constraints: AbilitySet, - new_type_constraints: AbilitySet, -) -> bool { - new_type_constraints.is_subset(old_type_constraints) -} + fn struct_equal( + &self, + old_module: &CompiledModule, + old_handle: StructHandleIndex, + new_module: &CompiledModule, + new_handle: StructHandleIndex, + ) -> bool { + let old_struct = StructHandleView::new(old_module, old_module.struct_handle_at(old_handle)); + let new_struct = StructHandleView::new(new_module, new_module.struct_handle_at(new_handle)); + old_struct.name() == new_struct.name() && old_struct.module_id() == new_struct.module_id() + } + + // When upgrading, the new constraints must be a subset of (or equal to) the old constraints. + // Removing an ability is fine, but adding an ability could cause existing callsites to fail + fn type_parameter_constraints_compatible( + &self, + old_type_constraints: AbilitySet, + new_type_constraints: AbilitySet, + ) -> bool { + new_type_constraints.is_subset(old_type_constraints) + } -// Adding a phantom annotation to a parameter won't break clients because that can only increase the -// the set of abilities in struct instantiations. Put it differently, adding phantom declarations -// relaxes the requirements for clients. -fn type_parameter_phantom_decl_compatible( - old_type_parameter: &StructTypeParameter, - new_type_parameter: &StructTypeParameter, -) -> bool { - // old_type_paramter.is_phantom => new_type_parameter.is_phantom - !old_type_parameter.is_phantom || new_type_parameter.is_phantom + // Adding a phantom annotation to a parameter won't break clients because that can only increase the + // the set of abilities in struct instantiations. Put it differently, adding phantom declarations + // relaxes the requirements for clients. + fn type_parameter_phantom_decl_compatible( + &self, + old_type_parameter: &StructTypeParameter, + new_type_parameter: &StructTypeParameter, + ) -> bool { + // old_type_paramter.is_phantom => new_type_parameter.is_phantom + !old_type_parameter.is_phantom || new_type_parameter.is_phantom + } } diff --git a/third_party/move/move-binary-format/src/compatibility_legacy.rs b/third_party/move/move-binary-format/src/compatibility_legacy.rs deleted file mode 100644 index 1187d5e5eca..00000000000 --- a/third_party/move/move-binary-format/src/compatibility_legacy.rs +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -#![allow(deprecated)] - -use crate::{ - compatibility, - errors::{PartialVMError, PartialVMResult}, - file_format::{StructTypeParameter, Visibility}, - file_format_common::VERSION_5, - normalized::Module, -}; -use compatibility::Compatibility; -use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; -use std::collections::BTreeSet; - -impl Compatibility { - /// Check compatibility for `new_module` relative to old module `old_module`. - pub fn legacy_check(&self, old_module: &Module, new_module: &Module) -> PartialVMResult<()> { - let mut struct_and_pub_function_linking = true; - let mut struct_layout = true; - let mut friend_linking = true; - - // module's name and address are unchanged - if old_module.address != new_module.address || old_module.name != new_module.name { - struct_and_pub_function_linking = false; - } - - // old module's structs are a subset of the new module's structs - for (name, old_struct) in &old_module.structs { - let new_struct = match new_module.structs.get(name) { - Some(new_struct) => new_struct, - None => { - // Struct not present in new . Existing modules that depend on this struct will fail to link with the new version of the module. - // Also, struct layout cannot be guaranteed transitively, because after - // removing the struct, it could be re-added later with a different layout. - struct_and_pub_function_linking = false; - struct_layout = false; - break; - }, - }; - - if !struct_abilities_compatibile(old_struct.abilities, new_struct.abilities) - || !struct_type_parameters_compatibile( - &old_struct.type_parameters, - &new_struct.type_parameters, - ) - { - struct_and_pub_function_linking = false; - } - if new_struct.fields != old_struct.fields { - // TODO(#13806): implement struct variants - // Fields changed. Code in this module will fail at runtime if it tries to - // read a previously published struct value - // TODO: this is a stricter definition than required. We could in principle - // choose that changing the name (but not position or type) of a field is - // compatible. The VM does not care about the name of a field - // (it's purely informational), but clients presumably do. - struct_layout = false - } - } - - // The modules are considered as compatible function-wise when all the conditions are met: - // - // - old module's public functions are a subset of the new module's public functions - // (i.e. we cannot remove or change public functions) - // - old module's script functions are a subset of the new module's script functions - // (i.e. we cannot remove or change script functions) - // - for any friend function that is removed or changed in the old module - // - if the function visibility is upgraded to public, it is OK - // - otherwise, it is considered as incompatible. - // - for (name, old_func) in &old_module.exposed_functions { - let new_func = match new_module.exposed_functions.get(name) { - Some(new_func) => new_func, - None => { - if matches!(old_func.visibility, Visibility::Friend) - && !(old_func.is_entry && self.treat_entry_as_public) - // self.treat_entry_as_public is false: trying to remove friend - // self.treat_entry_as_public is true: trying to remove Friend non-entry - { - // Report as friend linking error, which would be dismissed when - // self.check_friend_linking is set to false - friend_linking = false; - } else { - // Otherwise report as function linking error. - struct_and_pub_function_linking = false; - } - continue; - }, - }; - let is_vis_compatible = match (old_func.visibility, new_func.visibility) { - // public must remain public - (Visibility::Public, Visibility::Public) => true, - (Visibility::Public, _) => false, - // friend can become public or remain friend - (Visibility::Friend, Visibility::Public) - | (Visibility::Friend, Visibility::Friend) => true, - (Visibility::Friend, _) => false, - // private can become public or friend, or stay private - (Visibility::Private, _) => true, - }; - let is_entry_compatible = if old_module.file_format_version < VERSION_5 - && new_module.file_format_version < VERSION_5 - { - // if it was public(script), it must remain pubic(script) - // if it was not public(script), it _cannot_ become public(script) - old_func.is_entry == new_func.is_entry - } else { - // If it was an entry function, it must remain one. - // If it was not an entry function, it is allowed to become one. - !old_func.is_entry || new_func.is_entry - }; - if !is_vis_compatible - || !is_entry_compatible - || old_func.parameters != new_func.parameters - || old_func.return_ != new_func.return_ - || !fun_type_parameters_compatibile( - &old_func.type_parameters, - &new_func.type_parameters, - ) - { - if matches!(old_func.visibility, Visibility::Friend) - && (!old_func.is_entry || !self.treat_entry_as_public) - // self.treat_entry_as_public is false: trying to change signature of a friend function - // self.treat_entry_as_public is true: trying to change signature of a friend non-entry function. - { - // Report as friend linking error, which would be dismissed when - // self.check_friend_linking is set to false - friend_linking = false; - } else { - // Otherwise report as function linking error. - struct_and_pub_function_linking = false; - } - } - } - - // check friend declarations compatibility - // - // - additions to the list are allowed - // - removals are not allowed - // - let old_friend_module_ids: BTreeSet<_> = old_module.friends.iter().cloned().collect(); - let new_friend_module_ids: BTreeSet<_> = new_module.friends.iter().cloned().collect(); - if !old_friend_module_ids.is_subset(&new_friend_module_ids) { - friend_linking = false; - } - - if self.check_struct_and_pub_function_linking && !struct_and_pub_function_linking { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - ).with_message(format!("Module Update Failure: Public function/struct signature of new module differs from existing module in {:?}::{}", old_module.address, old_module.name))); - } - if self.check_struct_layout && !struct_layout { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - ).with_message(format!("Module Update Failure: Struct layout of new module differs from existing modul in {:?}::{}", old_module.address, old_module.name))); - } - if self.check_friend_linking && !friend_linking { - return Err(PartialVMError::new( - StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE, - ).with_message(format!("Module Update Failure: Friend signature of new module differs from existing module in {:?}::{}", old_module.address, old_module.name))); - } - - Ok(()) - } -} - -// When upgrading, the new abilities must be a superset of the old abilities. -// Adding an ability is fine, but removing an ability could cause existing usages to fail. -fn struct_abilities_compatibile(old_abilities: AbilitySet, new_abilities: AbilitySet) -> bool { - old_abilities.is_subset(new_abilities) -} - -// When upgrading, the new type parameters must be the same length, and the new type parameter -// constraints must be compatible -fn fun_type_parameters_compatibile( - old_type_parameters: &[AbilitySet], - new_type_parameters: &[AbilitySet], -) -> bool { - old_type_parameters.len() == new_type_parameters.len() - && old_type_parameters.iter().zip(new_type_parameters).all( - |(old_type_parameter_constraint, new_type_parameter_constraint)| { - type_parameter_constraints_compatibile( - *old_type_parameter_constraint, - *new_type_parameter_constraint, - ) - }, - ) -} - -fn struct_type_parameters_compatibile( - old_type_parameters: &[StructTypeParameter], - new_type_parameters: &[StructTypeParameter], -) -> bool { - old_type_parameters.len() == new_type_parameters.len() - && old_type_parameters.iter().zip(new_type_parameters).all( - |(old_type_parameter, new_type_parameter)| { - type_parameter_phantom_decl_compatibile(old_type_parameter, new_type_parameter) - && type_parameter_constraints_compatibile( - old_type_parameter.constraints, - new_type_parameter.constraints, - ) - }, - ) -} - -// When upgrading, the new constraints must be a subset of (or equal to) the old constraints. -// Removing an ability is fine, but adding an ability could cause existing callsites to fail -fn type_parameter_constraints_compatibile( - old_type_constraints: AbilitySet, - new_type_constraints: AbilitySet, -) -> bool { - new_type_constraints.is_subset(old_type_constraints) -} - -// Adding a phantom annotation to a parameter won't break clients because that can only increase the -// the set of abilities in struct instantiations. Put it differently, adding phantom declarations -// relaxes the requirements for clients. -fn type_parameter_phantom_decl_compatibile( - old_type_parameter: &StructTypeParameter, - new_type_parameter: &StructTypeParameter, -) -> bool { - // old_type_paramter.is_phantom => new_type_parameter.is_phantom - !old_type_parameter.is_phantom || new_type_parameter.is_phantom -} diff --git a/third_party/move/move-binary-format/src/constant.rs b/third_party/move/move-binary-format/src/constant.rs index 0c56bc1ce3f..ddee069f702 100644 --- a/third_party/move/move-binary-format/src/constant.rs +++ b/third_party/move/move-binary-format/src/constant.rs @@ -16,6 +16,12 @@ fn sig_to_ty(sig: &SignatureToken) -> Option { SignatureToken::U64 => Some(MoveTypeLayout::U64), SignatureToken::U128 => Some(MoveTypeLayout::U128), SignatureToken::U256 => Some(MoveTypeLayout::U256), + SignatureToken::I8 => Some(MoveTypeLayout::I8), + SignatureToken::I16 => Some(MoveTypeLayout::I16), + SignatureToken::I32 => Some(MoveTypeLayout::I32), + SignatureToken::I64 => Some(MoveTypeLayout::I64), + SignatureToken::I128 => Some(MoveTypeLayout::I128), + SignatureToken::I256 => Some(MoveTypeLayout::I256), SignatureToken::Vector(v) => Some(MoveTypeLayout::Vector(Box::new(sig_to_ty(v.as_ref())?))), SignatureToken::Reference(_) | SignatureToken::MutableReference(_) @@ -36,6 +42,12 @@ fn construct_ty_for_constant(layout: &MoveTypeLayout) -> Option MoveTypeLayout::U64 => Some(SignatureToken::U64), MoveTypeLayout::U128 => Some(SignatureToken::U128), MoveTypeLayout::U256 => Some(SignatureToken::U256), + MoveTypeLayout::I8 => Some(SignatureToken::I8), + MoveTypeLayout::I16 => Some(SignatureToken::I16), + MoveTypeLayout::I32 => Some(SignatureToken::I32), + MoveTypeLayout::I64 => Some(SignatureToken::I64), + MoveTypeLayout::I128 => Some(SignatureToken::I128), + MoveTypeLayout::I256 => Some(SignatureToken::I256), MoveTypeLayout::Vector(l) => Some(SignatureToken::Vector(Box::new( construct_ty_for_constant(l.as_ref())?, ))), diff --git a/third_party/move/move-binary-format/src/deserializer.rs b/third_party/move/move-binary-format/src/deserializer.rs index deb66c854d3..a2059c0024e 100644 --- a/third_party/move/move-binary-format/src/deserializer.rs +++ b/third_party/move/move-binary-format/src/deserializer.rs @@ -8,6 +8,7 @@ use move_core_types::{ account_address::AccountAddress, function::ClosureMask, identifier::Identifier, + int256::{I256, U256}, metadata::Metadata, state::VMState, vm_status::StatusCode, @@ -151,14 +152,23 @@ fn read_u128_internal(cursor: &mut VersionedCursor) -> BinaryLoaderResult Ok(u128::from_le_bytes(u128_bytes)) } -fn read_u256_internal( - cursor: &mut VersionedCursor, -) -> BinaryLoaderResult { - let mut u256_bytes = [0; 32]; +fn read_u256_internal(cursor: &mut VersionedCursor) -> BinaryLoaderResult { + let mut bytes = [0; 32]; cursor - .read_exact(&mut u256_bytes) + .read_exact(&mut bytes) .map_err(|_| PartialVMError::new(StatusCode::BAD_U256))?; - Ok(move_core_types::u256::U256::from_le_bytes(&u256_bytes)) + Ok(U256::from_le_bytes(bytes)) +} + +macro_rules! read_signed_int_internal { + ($cursor:ident, $ty:ty, $bytes:literal) => {{ + let mut bytes = [0; $bytes]; + $cursor + .read_exact(&mut bytes) + .map_err(|_| PartialVMError::new(StatusCode::MALFORMED).with_message("bad integer"))?; + let result: $ty = <$ty>::from_le_bytes(bytes); + Ok(result) + }}; } // @@ -971,11 +981,21 @@ fn load_identifier(cursor: &mut VersionedCursor) -> BinaryLoaderResult = vec![0u8; size]; if !cursor.read(&mut buffer).map(|count| count == size).unwrap() { Err(PartialVMError::new(StatusCode::MALFORMED) - .with_message("Bad Identifier pool size".to_string()))? + .with_message("Bad Identifier pool size".to_string()))?; } - Identifier::from_utf8(buffer).map_err(|_| { + let ident = Identifier::from_utf8(buffer).map_err(|_| { PartialVMError::new(StatusCode::MALFORMED).with_message("Invalid Identifier".to_string()) - }) + })?; + if cursor.version() < VERSION_9 && ident.as_str().contains('$') { + Err( + PartialVMError::new(StatusCode::MALFORMED).with_message(format!( + "`$` in identifiers not supported in bytecode version {}", + cursor.version() + )), + ) + } else { + Ok(ident) + } } fn load_address_identifier(cursor: &mut VersionedCursor) -> BinaryLoaderResult { @@ -1269,6 +1289,16 @@ fn load_signature_token(cursor: &mut VersionedCursor) -> BinaryLoaderResult + { + return Err( + PartialVMError::new(StatusCode::MALFORMED).with_message(format!( + "signer integer types not supported in bytecode version {}", + cursor.version() + )), + ); + }, _ => (), }; Ok(match ser_type { @@ -1279,6 +1309,12 @@ fn load_signature_token(cursor: &mut VersionedCursor) -> BinaryLoaderResult T::Saturated(SignatureToken::U64), S::U128 => T::Saturated(SignatureToken::U128), S::U256 => T::Saturated(SignatureToken::U256), + S::I8 => T::Saturated(SignatureToken::I8), + S::I16 => T::Saturated(SignatureToken::I16), + S::I32 => T::Saturated(SignatureToken::I32), + S::I64 => T::Saturated(SignatureToken::I64), + S::I128 => T::Saturated(SignatureToken::I128), + S::I256 => T::Saturated(SignatureToken::I256), S::ADDRESS => T::Saturated(SignatureToken::Address), S::SIGNER => T::Saturated(SignatureToken::Signer), S::VECTOR => T::Vector, @@ -1748,20 +1784,6 @@ fn load_code(cursor: &mut VersionedCursor, code: &mut Vec) -> BinaryLo )), ); }, - Opcodes::PACK_CLOSURE | Opcodes::PACK_CLOSURE_GENERIC | Opcodes::CALL_CLOSURE - if cursor.version() < VERSION_8 => - { - return Err( - PartialVMError::new(StatusCode::MALFORMED).with_message(format!( - "Closure operations not available before bytecode version {}", - VERSION_8 - )), - ); - }, - _ => {}, - }; - - match opcode { Opcodes::LD_U16 | Opcodes::LD_U32 | Opcodes::LD_U256 @@ -1777,7 +1799,39 @@ fn load_code(cursor: &mut VersionedCursor, code: &mut Vec) -> BinaryLo )), ); }, - _ => (), + Opcodes::PACK_CLOSURE | Opcodes::PACK_CLOSURE_GENERIC | Opcodes::CALL_CLOSURE + if cursor.version() < VERSION_8 => + { + return Err( + PartialVMError::new(StatusCode::MALFORMED).with_message(format!( + "Closure operations not available before bytecode version {}", + VERSION_8 + )), + ); + }, + Opcodes::LD_I8 + | Opcodes::LD_I16 + | Opcodes::LD_I32 + | Opcodes::LD_I64 + | Opcodes::LD_I128 + | Opcodes::LD_I256 + | Opcodes::CAST_I8 + | Opcodes::CAST_I16 + | Opcodes::CAST_I32 + | Opcodes::CAST_I64 + | Opcodes::CAST_I128 + | Opcodes::CAST_I256 + | Opcodes::NEGATE + if cursor.version() < VERSION_9 => + { + return Err( + PartialVMError::new(StatusCode::MALFORMED).with_message(format!( + "signed integer operations not available before bytecode version {}", + VERSION_9 + )), + ); + }, + _ => {}, }; // conversion @@ -1873,6 +1927,7 @@ fn load_code(cursor: &mut VersionedCursor, code: &mut Vec) -> BinaryLo Opcodes::MUL => Bytecode::Mul, Opcodes::MOD => Bytecode::Mod, Opcodes::DIV => Bytecode::Div, + Opcodes::NEGATE => Bytecode::Negate, Opcodes::BIT_OR => Bytecode::BitOr, Opcodes::BIT_AND => Bytecode::BitAnd, Opcodes::XOR => Bytecode::Xor, @@ -1935,6 +1990,20 @@ fn load_code(cursor: &mut VersionedCursor, code: &mut Vec) -> BinaryLo Opcodes::CAST_U16 => Bytecode::CastU16, Opcodes::CAST_U32 => Bytecode::CastU32, Opcodes::CAST_U256 => Bytecode::CastU256, + + Opcodes::LD_I8 => Bytecode::LdI8(read_signed_int_internal!(cursor, i8, 1)?), + Opcodes::LD_I16 => Bytecode::LdI16(read_signed_int_internal!(cursor, i16, 2)?), + Opcodes::LD_I32 => Bytecode::LdI32(read_signed_int_internal!(cursor, i32, 4)?), + Opcodes::LD_I64 => Bytecode::LdI64(read_signed_int_internal!(cursor, i64, 8)?), + Opcodes::LD_I128 => Bytecode::LdI128(read_signed_int_internal!(cursor, i128, 16)?), + Opcodes::LD_I256 => Bytecode::LdI256(read_signed_int_internal!(cursor, I256, 32)?), + + Opcodes::CAST_I8 => Bytecode::CastI8, + Opcodes::CAST_I16 => Bytecode::CastI16, + Opcodes::CAST_I32 => Bytecode::CastI32, + Opcodes::CAST_I64 => Bytecode::CastI64, + Opcodes::CAST_I128 => Bytecode::CastI128, + Opcodes::CAST_I256 => Bytecode::CastI256, }; code.push(bytecode); } @@ -1987,6 +2056,12 @@ impl SerializedType { 0xE => Ok(SerializedType::U32), 0xF => Ok(SerializedType::U256), 0x10 => Ok(SerializedType::FUNCTION), + 0x11 => Ok(SerializedType::I8), + 0x12 => Ok(SerializedType::I16), + 0x13 => Ok(SerializedType::I32), + 0x14 => Ok(SerializedType::I64), + 0x15 => Ok(SerializedType::I128), + 0x16 => Ok(SerializedType::I256), _ => Err(PartialVMError::new(StatusCode::UNKNOWN_SERIALIZED_TYPE)), } } @@ -2137,6 +2212,20 @@ impl Opcodes { 0x58 => Ok(Opcodes::PACK_CLOSURE), 0x59 => Ok(Opcodes::PACK_CLOSURE_GENERIC), 0x5A => Ok(Opcodes::CALL_CLOSURE), + // Since bytecode version 9 + 0x5B => Ok(Opcodes::LD_I8), + 0x5C => Ok(Opcodes::LD_I16), + 0x5D => Ok(Opcodes::LD_I32), + 0x5E => Ok(Opcodes::LD_I64), + 0x5F => Ok(Opcodes::LD_I128), + 0x60 => Ok(Opcodes::LD_I256), + 0x61 => Ok(Opcodes::CAST_I8), + 0x62 => Ok(Opcodes::CAST_I16), + 0x63 => Ok(Opcodes::CAST_I32), + 0x64 => Ok(Opcodes::CAST_I64), + 0x65 => Ok(Opcodes::CAST_I128), + 0x66 => Ok(Opcodes::CAST_I256), + 0x67 => Ok(Opcodes::NEGATE), _ => Err(PartialVMError::new(StatusCode::UNKNOWN_OPCODE) .with_message(format!("code {:X}", value))), } diff --git a/third_party/move/move-binary-format/src/errors.rs b/third_party/move/move-binary-format/src/errors.rs index abe6e81c3cc..9c85ff2bef0 100644 --- a/third_party/move/move-binary-format/src/errors.rs +++ b/third_party/move/move-binary-format/src/errors.rs @@ -10,12 +10,28 @@ use move_core_types::{ language_storage::ModuleId, vm_status::{self, StatusCode, StatusType, VMStatus}, }; +use once_cell::sync::{Lazy, OnceCell}; use std::fmt; pub type VMResult = ::std::result::Result; pub type BinaryLoaderResult = ::std::result::Result; pub type PartialVMResult = ::std::result::Result; +static STABLE_TEST_DISPLAY: OnceCell = OnceCell::new(); + +/// Call this function if display of errors should be stable for baseline tests. +/// Specifically, no stack traces should be generated, as they contain transitive +/// file locations. +pub fn set_stable_test_display() { + STABLE_TEST_DISPLAY.set(true).unwrap_or(()) +} + +/// Check whether stable test display is enabled. This can be used by other components +/// to adjust their output. +pub fn is_stable_test_display() -> bool { + STABLE_TEST_DISPLAY.get().copied().unwrap_or(false) +} + /// This macro is used to panic while debugging fuzzing crashes obtaining the right stack trace. /// e.g. DEBUG_VM_STATUS=ABORTED,UNKNOWN_INVARIANT_VIOLATION_ERROR ./fuzz.sh run move_aptosvm_publish_and_run /// third_party/move/move-core/types/src/vm_status.rs:506 for the list of status codes. @@ -73,6 +89,7 @@ struct VMError_ { } impl VMError { + #[cold] pub fn into_vm_status(self) -> VMStatus { let VMError_ { major_status, @@ -225,6 +242,7 @@ impl VMError { ) } + #[cold] pub fn to_partial(self) -> PartialVMError { let VMError_ { major_status, @@ -345,6 +363,7 @@ struct PartialVMError_ { } impl PartialVMError { + #[cold] pub fn all_data( self, ) -> ( @@ -373,6 +392,7 @@ impl PartialVMError { ) } + #[cold] pub fn finish(self, location: Location) -> VMError { let PartialVMError_ { major_status, @@ -382,12 +402,21 @@ impl PartialVMError { indices, offsets, } = *self.0; - let bt = std::backtrace::Backtrace::capture(); - let message = if std::backtrace::BacktraceStatus::Captured == bt.status() { - if let Some(message) = message { - Some(format!("{}\nBacktrace: {:#?}", message, bt).to_string()) + static MOVE_TEST_DEBUG: Lazy = Lazy::new(|| { + std::env::var("MOVE_TEST_DEBUG").is_ok_and(|v| matches!(v.as_str(), "true" | "1")) + }); + let message = if *MOVE_TEST_DEBUG { + // Do this only if env var is set. Otherwise, we cannot use the output in baseline files + // since it is not deterministic. + let bt = std::backtrace::Backtrace::capture(); + if std::backtrace::BacktraceStatus::Captured == bt.status() { + if let Some(message) = message { + Some(format!("{}\nBacktrace: {:#?}", message, bt).to_string()) + } else { + Some(format!("Backtrace: {:#?}", bt).to_string()) + } } else { - Some(format!("Backtrace: {:#?}", bt).to_string()) + message } } else { message @@ -404,9 +433,12 @@ impl PartialVMError { })) } + #[cold] pub fn new(major_status: StatusCode) -> Self { debug_assert!(major_status != StatusCode::EXECUTED); - let message = if major_status == StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR { + let message = if major_status == StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR + && !is_stable_test_display() + { let mut len = 5; let mut trace: String = "Unknown invariant violation generated:\n".to_string(); backtrace::trace(|frame| { @@ -448,6 +480,7 @@ impl PartialVMError { })) } + #[cold] pub fn new_invariant_violation(msg: impl ToString) -> PartialVMError { Self::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message(msg.to_string()) } @@ -460,14 +493,19 @@ impl PartialVMError { self.0.sub_status } + #[cold] pub fn with_sub_status(mut self, sub_status: u64) -> Self { debug_assert!(self.0.sub_status.is_none()); self.0.sub_status = Some(sub_status); self } - pub fn with_message(mut self, mut message: String) -> Self { + #[cold] + pub fn with_message(mut self, message: impl ToString) -> Self { + let mut message = message.to_string(); if self.0.major_status == StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR { + // If there is already something in the message, interpret as stack trace + // and append at the end if let Some(stacktrace) = self.0.message.take() { message = format!("{} @{}", message, stacktrace); } @@ -477,6 +515,7 @@ impl PartialVMError { self } + #[cold] pub fn with_exec_state(mut self, exec_state: ExecutionState) -> Self { debug_assert!(self.0.exec_state.is_none()); self.0.exec_state = Some(exec_state); @@ -487,21 +526,25 @@ impl PartialVMError { self.0.message.as_deref() } + #[cold] pub fn at_index(mut self, kind: IndexKind, index: TableIndex) -> Self { self.0.indices.push((kind, index)); self } + #[cold] pub fn at_indices(mut self, additional_indices: Vec<(IndexKind, TableIndex)>) -> Self { self.0.indices.extend(additional_indices); self } + #[cold] pub fn at_code_offset(mut self, function: FunctionDefinitionIndex, offset: CodeOffset) -> Self { self.0.offsets.push((function, offset)); self } + #[cold] pub fn at_code_offsets( mut self, additional_offsets: Vec<(FunctionDefinitionIndex, CodeOffset)>, @@ -512,6 +555,7 @@ impl PartialVMError { /// Append the message `message` to the message field of the VM status, and insert a separator /// if the original message is non-empty. + #[cold] pub fn append_message_with_separator( mut self, separator: char, @@ -610,6 +654,7 @@ pub fn vm_status_of_result(result: VMResult) -> VMStatus { } } +#[cold] pub fn offset_out_of_bounds( status: StatusCode, kind: IndexKind, @@ -627,6 +672,7 @@ pub fn offset_out_of_bounds( .at_code_offset(cur_function, cur_bytecode_offset) } +#[cold] pub fn bounds_error( status: StatusCode, kind: IndexKind, @@ -642,6 +688,7 @@ pub fn bounds_error( .with_message(msg) } +#[cold] pub fn verification_error(status: StatusCode, kind: IndexKind, idx: TableIndex) -> PartialVMError { PartialVMError::new(status).at_index(kind, idx) } diff --git a/third_party/move/move-binary-format/src/file_format.rs b/third_party/move/move-binary-format/src/file_format.rs index 7a049f724ad..23652d80ecd 100644 --- a/third_party/move/move-binary-format/src/file_format.rs +++ b/third_party/move/move-binary-format/src/file_format.rs @@ -49,7 +49,7 @@ use move_core_types::{ use proptest::{collection::vec, prelude::*, strategy::BoxedStrategy}; use ref_cast::RefCast; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{fmt, fmt::Formatter}; use variant_count::VariantCount; /// Generic index into one of the tables in the binary format. @@ -384,6 +384,15 @@ impl FunctionAttribute { } } +impl fmt::Display for FunctionAttribute { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + FunctionAttribute::Persistent => write!(f, "persistent"), + FunctionAttribute::ModuleLock => write!(f, "module_lock"), + } + } +} + /// A field access info (owner type and offset) #[derive(Clone, Debug, Eq, Hash, PartialEq)] #[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] @@ -658,6 +667,13 @@ impl Visibility { Self::Private | Self::Friend => false, } } + + pub fn is_public_or_friend(&self) -> bool { + match self { + Self::Public | Self::Friend => true, + Self::Private => false, + } + } } impl std::convert::TryFrom for Visibility { @@ -945,6 +961,13 @@ pub enum SignatureToken { U32, /// Unsigned integers, 256 bits length. U256, + /// Signed integers + I8, + I16, + I32, + I64, + I128, + I256, } /// An iterator to help traverse the `SignatureToken` in a non-recursive fashion to avoid @@ -977,8 +1000,8 @@ impl<'a> Iterator for SignatureTokenPreorderTraversalIter<'a> { self.stack.extend(args.iter().rev()); }, - Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | Struct(_) - | TypeParameter(_) => (), + Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 + | I32 | I64 | I128 | I256 | Struct(_) | TypeParameter(_) => (), } Some(tok) }, @@ -1017,8 +1040,8 @@ impl<'a> Iterator for SignatureTokenPreorderTraversalIterWithDepth<'a> { .extend(args.iter().map(|tok| (tok, depth + 1)).rev()); }, - Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | Struct(_) - | TypeParameter(_) => (), + Signer | Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 + | I32 | I64 | I128 | I256 | Struct(_) | TypeParameter(_) => (), } Some((tok, depth)) }, @@ -1074,6 +1097,12 @@ impl std::fmt::Debug for SignatureToken { SignatureToken::U64 => write!(f, "U64"), SignatureToken::U128 => write!(f, "U128"), SignatureToken::U256 => write!(f, "U256"), + SignatureToken::I8 => write!(f, "I8"), + SignatureToken::I16 => write!(f, "I16"), + SignatureToken::I32 => write!(f, "I32"), + SignatureToken::I64 => write!(f, "I64"), + SignatureToken::I128 => write!(f, "I128"), + SignatureToken::I256 => write!(f, "I256"), SignatureToken::Address => write!(f, "Address"), SignatureToken::Signer => write!(f, "Signer"), SignatureToken::Vector(boxed) => write!(f, "Vector({:?})", boxed), @@ -1094,10 +1123,58 @@ impl std::fmt::Debug for SignatureToken { impl SignatureToken { /// Returns true if the token is an integer type. pub fn is_integer(&self) -> bool { + use SignatureToken::*; + match self { + U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 => true, + Bool + | Address + | Signer + | Vector(_) + | Function(..) + | Struct(_) + | StructInstantiation(_, _) + | Reference(_) + | MutableReference(_) + | TypeParameter(_) => false, + } + } + + /// Returns true if the token is a signed integer type. + pub fn is_signed_integer(&self) -> bool { + use SignatureToken::*; + match self { + I8 | I16 | I32 | I64 | I128 | I256 => true, + Bool + | U8 + | U16 + | U32 + | U64 + | U128 + | U256 + | Address + | Signer + | Vector(_) + | Function(..) + | Struct(_) + | StructInstantiation(_, _) + | Reference(_) + | MutableReference(_) + | TypeParameter(_) => false, + } + } + + /// Returns true if the token is a signed integer type. + pub fn is_unsigned_integer(&self) -> bool { use SignatureToken::*; match self { U8 | U16 | U32 | U64 | U128 | U256 => true, Bool + | I8 + | I16 + | I32 + | I64 + | I128 + | I256 | Address | Signer | Vector(_) @@ -1137,7 +1214,8 @@ impl SignatureToken { use SignatureToken::*; match self { - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address => true, + Bool | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Address => true, Vector(inner) => inner.is_valid_for_constant(), Signer | Function(..) @@ -1172,10 +1250,11 @@ impl SignatureToken { /// Panics if this token doesn't contain a struct handle. pub fn debug_set_sh_idx(&mut self, sh_idx: StructHandleIndex) { match self { - SignatureToken::Struct(ref mut wrapped) => *wrapped = sh_idx, - SignatureToken::StructInstantiation(ref mut wrapped, _) => *wrapped = sh_idx, - SignatureToken::Reference(ref mut token) - | SignatureToken::MutableReference(ref mut token) => token.debug_set_sh_idx(sh_idx), + SignatureToken::Struct(wrapped) => *wrapped = sh_idx, + SignatureToken::StructInstantiation(wrapped, _) => *wrapped = sh_idx, + SignatureToken::Reference(token) | SignatureToken::MutableReference(token) => { + token.debug_set_sh_idx(sh_idx) + }, other => panic!( "debug_set_sh_idx (to {}) called for non-struct token {:?}", sh_idx, other @@ -1212,6 +1291,12 @@ impl SignatureToken { U64 => U64, U128 => U128, U256 => U256, + I8 => I8, + I16 => I16, + I32 => I32, + I64 => I64, + I128 => I128, + I256 => I256, Address => Address, Signer => Signer, Vector(ty) => Vector(Box::new(ty.instantiate(subst_mapping))), @@ -1378,7 +1463,7 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - if int_val > u8::MAX: + if int_val < 0 || int_val > u8::MAX: arithmetic error else: stack << int_val as u8 @@ -1396,7 +1481,7 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - if int_val > u64::MAX: + if int_val < 0 || int_val > u64::MAX: arithmetic error else: stack << int_val as u64 @@ -1414,7 +1499,7 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - if int_val > u128::MAX: + if int_val < 0 || int_val > u128::MAX: arithmetic error else: stack << int_val as u128 @@ -1679,7 +1764,7 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &struct_ty + assert ty == &struct_ty or ty == &mut struct_ty ty_stack << bool "#] TestVariant(StructVariantHandleIndex), @@ -1812,7 +1897,7 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &struct_ty + assert ty == &mut struct_ty ty_stack << &mut field_ty "#] #[gas_type_creation_tier_0 = "struct_ty"] @@ -1854,7 +1939,7 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &struct_ty + assert ty == &struct_ty or ty == &mut struct_ty ty_stack << &field_ty "#] ImmBorrowField(FieldHandleIndex), @@ -1877,8 +1962,8 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &mut struct_ty - ty_stack << &mut field_ty + assert ty == &struct_ty or ty == &mut struct_ty + ty_stack << &field_ty "#] ImmBorrowVariantField(VariantFieldHandleIndex), @@ -1895,7 +1980,7 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &struct_ty + assert ty == &struct_ty or ty == &mut struct_ty ty_stack << &field_ty "#] #[gas_type_creation_tier_0 = "struct_ty"] @@ -1920,8 +2005,8 @@ pub enum Bytecode { "#] #[runtime_check_epilogue = r#" ty_stack >> ty - assert ty == &mut struct_ty - ty_stack << &mut field_ty + assert ty == &struct_ty or ty == &mut struct_ty + ty_stack << &field_ty "#] ImmBorrowVariantFieldGeneric(VariantFieldInstantiationIndex), @@ -2077,12 +2162,12 @@ pub enum Bytecode { #[description = r#" Divide the two integer values at the top of the stack and push the result on the stack. - This operation aborts the transaction in case the right hand side is zero. + This operation aborts the transaction in case the right hand side is zero or overflow happens. "#] #[semantics = r#" stack >> rhs stack >> lhs - if rhs == 0 + if rhs == 0 || (lhs == i::MIN && rhs == -1) arithmetic error else stack << (lhs / rhs) @@ -2426,7 +2511,7 @@ pub enum Bytecode { #[runtime_check_epilogue = r#" ty_stack >> ty1 ty_stack >> ty2 - assert ty2 == signer + assert ty2 == &signer assert ty1 == struct_ty assert struct_ty has key "#] @@ -2523,7 +2608,7 @@ pub enum Bytecode { #[runtime_check_epilogue = r#" elem_ty = instantiate elem_ty ty_stack >> ty - assert ty == &elem_ty + assert ty == &vector or ty == &mut vector ty_stack << u64 "#] #[gas_type_creation_tier_0 = "elem_ty"] @@ -2544,7 +2629,7 @@ pub enum Bytecode { ty_stack >> idx_ty assert idx_ty == u64 ty_stack >> ref_ty - assert ref_ty == &vector + assert ref_ty == &vector or ref_ty == &mut vector ty_stack << &elem_ty "#] #[gas_type_creation_tier_0 = "elem_ty"] @@ -2642,7 +2727,7 @@ pub enum Bytecode { ty_stack >> ty3 assert ty1 == u64 assert ty2 == u64 - assert ty3 == &vector + assert ty3 == &mut vector "#] VecSwap(SignatureIndex), @@ -2698,7 +2783,7 @@ pub enum Bytecode { #[group = "closure"] #[description = r#" - `CallClosure(|t1..tn|r has a)` evalutes a closure of the given function type, + `CallClosure(|t1..tn|r has a)` evaluates a closure of the given function type, taking the captured arguments and mixing in the provided ones on the stack. On top of the stack is the closure being evaluated, underneath the arguments: @@ -2743,7 +2828,7 @@ pub enum Bytecode { #[static_operands = "[u256_value]"] #[semantics = "stack << u256_value"] #[runtime_check_epilogue = "ty_stack << u256"] - LdU256(move_core_types::u256::U256), + LdU256(move_core_types::int256::U256), #[group = "casting"] #[description = r#" @@ -2752,7 +2837,7 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - if int_val > u16::MAX: + if int_val < 0 || int_val > u16::MAX: arithmetic error else: stack << int_val as u16 @@ -2770,7 +2855,7 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - if int_val > u32::MAX: + if int_val < 0 || int_val > u32::MAX: arithmetic error else: stack << int_val as u32 @@ -2787,13 +2872,184 @@ pub enum Bytecode { "#] #[semantics = r#" stack >> int_val - stack << int_val as u256 + if int_val < 0: + arithmetic error + else: + stack << int_val as u256 "#] #[runtime_check_epilogue = r#" ty_stack >> _ ty_stack << u256 "#] CastU256, + + #[group = "stack_and_local"] + #[description = "Push a i8 constant onto the stack."] + #[static_operands = "[i8_value]"] + #[semantics = "stack << i8_value"] + #[runtime_check_epilogue = "ty_stack << i8"] + LdI8(i8), + + #[group = "stack_and_local"] + #[description = "Push a i16 constant onto the stack."] + #[static_operands = "[i16_value]"] + #[semantics = "stack << i16_value"] + #[runtime_check_epilogue = "ty_stack << i16"] + LdI16(i16), + + #[group = "stack_and_local"] + #[description = "Push a i32 constant onto the stack."] + #[static_operands = "[i32_value]"] + #[semantics = "stack << i32_value"] + #[runtime_check_epilogue = "ty_stack << i32"] + LdI32(i32), + + #[group = "stack_and_local"] + #[description = "Push a i64 constant onto the stack."] + #[static_operands = "[i64_value]"] + #[semantics = "stack << i64_value"] + #[runtime_check_epilogue = "ty_stack << i64"] + LdI64(i64), + + #[group = "stack_and_local"] + #[description = "Push a i128 constant onto the stack."] + #[static_operands = "[i128_value]"] + #[semantics = "stack << i128_value"] + #[runtime_check_epilogue = "ty_stack << i128"] + LdI128(i128), + + #[group = "stack_and_local"] + #[description = "Push a i256 constant onto the stack."] + #[static_operands = "[i256_value]"] + #[semantics = "stack << i256_value"] + #[runtime_check_epilogue = "ty_stack << i256"] + LdI256(move_core_types::int256::I256), + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i8. + An arithmetic error will be raised if the value cannot be represented as a i8. + "#] + #[semantics = r#" + stack >> int_val + if int_val < i8::MIN || int_val > i8::MAX: + arithmetic error + else: + stack << int_val as i8 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i8 + "#] + CastI8, + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i16. + An arithmetic error will be raised if the value cannot be represented as a i16. + "#] + #[semantics = r#" + stack >> int_val + if int_val < i16::MIN || int_val > i16::MAX: + arithmetic error + else: + stack << int_val as i16 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i16 + "#] + CastI16, + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i32. + An arithmetic error will be raised if the value cannot be represented as a i32. + "#] + #[semantics = r#" + stack >> int_val + if int_val < i32::MIN || int_val > i32::MAX: + arithmetic error + else: + stack << int_val as i32 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i32 + "#] + CastI32, + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i64. + An arithmetic error will be raised if the value cannot be represented as a i64. + "#] + #[semantics = r#" + stack >> int_val + if int_val < i64::MIN || int_val > i64::MAX: + arithmetic error + else: + stack << int_val as i64 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i64 + "#] + CastI64, + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i128. + An arithmetic error will be raised if the value cannot be represented as a i128. + "#] + #[semantics = r#" + stack >> int_val + if int_val < i128::MIN || int_val > i128::MAX: + arithmetic error + else: + stack << int_val as i128 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i128 + "#] + CastI128, + + #[group = "casting"] + #[description = r#" + Convert the integer value at the top of the stack into a i256. + "#] + #[semantics = r#" + stack >> int_val + if int_val > i256::MAX: + arithmetic error + else: + stack << int_val as i256 + "#] + #[runtime_check_epilogue = r#" + ty_stack >> _ + ty_stack << i256 + "#] + CastI256, + + #[group = "arithmetic"] + #[description = r#" + Negate the signed integer on top of the stack. + An arithmetic error will be raised if the value cannot be negated, as is the + case for the minimum of a given signed integer type + "#] + #[semantics = r#" + stack >> num + if num == i::MIN + arithmetic error + else + stack << -num + "#] + #[runtime_check_epilogue = r#" + ty_stack >> ty + ty_stack << ty + "#] + Negate, } impl ::std::fmt::Debug for Bytecode { @@ -2816,6 +3072,18 @@ impl ::std::fmt::Debug for Bytecode { Bytecode::CastU64 => write!(f, "CastU64"), Bytecode::CastU128 => write!(f, "CastU128"), Bytecode::CastU256 => write!(f, "CastU256"), + Bytecode::LdI8(a) => write!(f, "LdI8({})", a), + Bytecode::LdI16(a) => write!(f, "LdI16({})", a), + Bytecode::LdI32(a) => write!(f, "LdI32({})", a), + Bytecode::LdI64(a) => write!(f, "LdI64({})", a), + Bytecode::LdI128(a) => write!(f, "LdI128({})", a), + Bytecode::LdI256(a) => write!(f, "LdI256({})", a), + Bytecode::CastI8 => write!(f, "CastI8"), + Bytecode::CastI16 => write!(f, "CastI16"), + Bytecode::CastI32 => write!(f, "CastI32"), + Bytecode::CastI64 => write!(f, "CastI64"), + Bytecode::CastI128 => write!(f, "CastI128"), + Bytecode::CastI256 => write!(f, "CastI256"), Bytecode::LdConst(a) => write!(f, "LdConst({})", a), Bytecode::LdTrue => write!(f, "LdTrue"), Bytecode::LdFalse => write!(f, "LdFalse"), @@ -2865,6 +3133,7 @@ impl ::std::fmt::Debug for Bytecode { Bytecode::Mul => write!(f, "Mul"), Bytecode::Mod => write!(f, "Mod"), Bytecode::Div => write!(f, "Div"), + Bytecode::Negate => write!(f, "Negate"), Bytecode::BitOr => write!(f, "BitOr"), Bytecode::BitAnd => write!(f, "BitAnd"), Bytecode::Xor => write!(f, "Xor"), @@ -2995,6 +3264,18 @@ impl Bytecode { | CastU64 | CastU128 | CastU256 + | LdI8(_) + | LdI16(_) + | LdI32(_) + | LdI64(_) + | LdI128(_) + | LdI256(_) + | CastI8 + | CastI16 + | CastI32 + | CastI64 + | CastI128 + | CastI256 | LdConst(_) | LdTrue | LdFalse @@ -3031,6 +3312,7 @@ impl Bytecode { | Mul | Mod | Div + | Negate | BitOr | BitAnd | Xor @@ -3465,14 +3747,29 @@ pub fn empty_module_with_dependencies_and_friends<'a>( dependencies: impl IntoIterator, friends: impl IntoIterator, ) -> CompiledModule { - // Rename this empty module. + empty_module_with_dependencies_and_friends_at_addr( + AccountAddress::ZERO, + module_name, + dependencies, + friends, + ) +} + +/// Creates an empty compiled module with specified dependencies and friends. All +/// modules (including itself) are stored at the specified address. +pub fn empty_module_with_dependencies_and_friends_at_addr<'a>( + address: AccountAddress, + module_name: &'a str, + dependencies: impl IntoIterator, + friends: impl IntoIterator, +) -> CompiledModule { let mut module = empty_module(); + module.address_identifiers[0] = address; module.identifiers[0] = Identifier::new(module_name).unwrap(); for name in dependencies { module.identifiers.push(Identifier::new(name).unwrap()); module.module_handles.push(ModuleHandle { - // Empty module sets up this index to 0x0. address: AddressIdentifierIndex(0), name: IdentifierIndex((module.identifiers.len() - 1) as TableIndex), }); @@ -3480,7 +3777,6 @@ pub fn empty_module_with_dependencies_and_friends<'a>( for name in friends { module.identifiers.push(Identifier::new(name).unwrap()); module.friend_decls.push(ModuleHandle { - // Empty module sets up this index to 0x0. address: AddressIdentifierIndex(0), name: IdentifierIndex((module.identifiers.len() - 1) as TableIndex), }); diff --git a/third_party/move/move-binary-format/src/file_format_common.rs b/third_party/move/move-binary-format/src/file_format_common.rs index 1b7b0cad9d5..53da7b56303 100644 --- a/third_party/move/move-binary-format/src/file_format_common.rs +++ b/third_party/move/move-binary-format/src/file_format_common.rs @@ -13,7 +13,7 @@ //! It's used to compress mostly indexes into the main binary tables. use crate::file_format::Bytecode; use anyhow::{bail, Result}; -use move_core_types::value; +use move_core_types::{int256, value}; use std::{ io::{Cursor, Read}, mem::size_of, @@ -142,7 +142,13 @@ pub enum SerializedType { U16 = 0xD, U32 = 0xE, U256 = 0xF, - FUNCTION = 0x10 + FUNCTION = 0x10, + I8 = 0x11, + I16 = 0x12, + I32 = 0x13, + I64 = 0x14, + I128 = 0x15, + I256 = 0x16, } /// A marker for an option in the serialized output. @@ -222,7 +228,7 @@ pub enum SerializedFunctionAttribute { #[rustfmt::skip] #[allow(non_camel_case_types)] #[repr(u8)] -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Opcodes { POP = 0x01, RET = 0x02, @@ -316,6 +322,20 @@ pub enum Opcodes { PACK_CLOSURE = 0x58, PACK_CLOSURE_GENERIC = 0x59, CALL_CLOSURE = 0x5A, + // Since bytecode version 9 + LD_I8 = 0x5B, + LD_I16 = 0x5C, + LD_I32 = 0x5D, + LD_I64 = 0x5E, + LD_I128 = 0x5F, + LD_I256 = 0x60, + CAST_I8 = 0x61, + CAST_I16 = 0x62, + CAST_I32 = 0x63, + CAST_I64 = 0x64, + CAST_I128 = 0x65, + CAST_I256 = 0x66, + NEGATE = 0x67 } /// Upper limit on the binary size @@ -441,10 +461,7 @@ pub(crate) fn write_u128(binary: &mut BinaryData, value: u128) -> Result<()> { } /// Write a `u256` in Little Endian format. -pub(crate) fn write_u256( - binary: &mut BinaryData, - value: move_core_types::u256::U256, -) -> Result<()> { +pub(crate) fn write_u256(binary: &mut BinaryData, value: int256::U256) -> Result<()> { binary.extend(&value.to_le_bytes()) } @@ -530,16 +547,24 @@ pub const VERSION_7: u32 = 7; /// + closure instructions pub const VERSION_8: u32 = 8; +/// Version 9: changes compared to version 8 +/// + signed integers +/// + allow `$` in identifiers +pub const VERSION_9: u32 = 9; + /// Mark which version is the latest version. -pub const VERSION_MAX: u32 = VERSION_8; +pub const VERSION_MAX: u32 = VERSION_9; /// Mark which version is the default version. This is the version used by default by tools like /// the compiler. Notice that this version might be different from the one supported on nodes. /// The node's max version is determined by the on-chain config for that node. -pub const VERSION_DEFAULT: u32 = VERSION_7; +pub const VERSION_DEFAULT: u32 = VERSION_8; /// Mark which version is the default version if compiling Move 2. -pub const VERSION_DEFAULT_LANG_V2: u32 = VERSION_7; +pub const VERSION_DEFAULT_LANG_V2: u32 = VERSION_8; + +/// Mark which version is the default version if compiling with language version 2.3 +pub const VERSION_DEFAULT_LANG_V2_3: u32 = VERSION_9; // Mark which oldest version is supported. pub const VERSION_MIN: u32 = VERSION_5; @@ -809,6 +834,20 @@ pub fn instruction_key(instruction: &Bytecode) -> u8 { PackClosure(..) => Opcodes::PACK_CLOSURE, PackClosureGeneric(..) => Opcodes::PACK_CLOSURE_GENERIC, CallClosure(_) => Opcodes::CALL_CLOSURE, + // Since bytecode version 9 + LdI8(_) => Opcodes::LD_I8, + LdI16(_) => Opcodes::LD_I16, + LdI32(_) => Opcodes::LD_I32, + LdI64(_) => Opcodes::LD_I64, + LdI128(_) => Opcodes::LD_I128, + LdI256(_) => Opcodes::LD_I256, + CastI8 => Opcodes::CAST_I8, + CastI16 => Opcodes::CAST_I16, + CastI32 => Opcodes::CAST_I32, + CastI64 => Opcodes::CAST_I64, + CastI128 => Opcodes::CAST_I128, + CastI256 => Opcodes::CAST_I256, + Negate => Opcodes::NEGATE, }; opcode as u8 } diff --git a/third_party/move/move-binary-format/src/lib.rs b/third_party/move/move-binary-format/src/lib.rs index 9ffa05af1f8..5f8f61c3074 100644 --- a/third_party/move/move-binary-format/src/lib.rs +++ b/third_party/move/move-binary-format/src/lib.rs @@ -11,7 +11,6 @@ pub mod access; pub mod binary_views; pub mod check_bounds; pub mod compatibility; -pub mod compatibility_legacy; #[macro_use] pub mod errors; pub mod builders; @@ -22,7 +21,7 @@ pub mod deserializer; pub mod file_format; pub mod file_format_common; pub mod internals; -pub mod normalized; +pub mod module_script_conversion; #[cfg(any(test, feature = "fuzzing"))] pub mod proptest_types; pub mod serializer; diff --git a/third_party/move/move-binary-format/src/module_script_conversion.rs b/third_party/move/move-binary-format/src/module_script_conversion.rs new file mode 100644 index 00000000000..e2d1400264b --- /dev/null +++ b/third_party/move/move-binary-format/src/module_script_conversion.rs @@ -0,0 +1,210 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + check_bounds::BoundsChecker, + file_format::{ + AddressIdentifierIndex, CompiledScript, FunctionDefinition, FunctionHandle, + FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, + SignatureIndex, Visibility, + }, + CompiledModule, +}; +use anyhow::bail; +use move_core_types::{identifier::Identifier, language_storage::pseudo_script_module_id}; + +/// Converts a compiled module into a script. The module must define exactly one function +/// and no types. The `main_handle` is the handle info of the one function in the module +/// which must not be contained in function_handles table. +pub fn module_into_script( + module: CompiledModule, + main_handle: FunctionHandle, +) -> anyhow::Result { + let CompiledModule { + version, + self_module_handle_idx: _, + module_handles, + struct_handles, + function_handles, + field_handles: _, + friend_decls: _, + struct_def_instantiations: _, + field_instantiations: _, + struct_defs, + mut function_defs, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + struct_variant_handles: _, + struct_variant_instantiations: _, + variant_field_handles: _, + variant_field_instantiations: _, + } = module; + if function_defs.len() != 1 { + bail!("scripts can only contain one function") + } + if !struct_defs.is_empty() { + bail!("scripts cannot have struct or enum declarations") + } + let FunctionDefinition { + function: _, + visibility: _, + is_entry: _, + acquires_global_resources: _, + code, + } = function_defs.pop().unwrap(); + let Some(code) = code else { + bail!("script functions must have a body") + }; + let FunctionHandle { + module: _, + name: _, + parameters, + return_, + type_parameters, + access_specifiers, + attributes: _, + } = main_handle; + if signatures + .get(return_.0 as usize) + .is_none_or(|s| !s.is_empty()) + { + bail!("main function must not return values") + } + Ok(CompiledScript { + version, + module_handles, + struct_handles, + function_handles, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + code, + type_parameters, + parameters, + access_specifiers, + }) +} + +/// Converts a compiled script into a module. The function in the script gets +/// `name` assigned in the produced module. +pub fn script_into_module(compiled_script: CompiledScript, name: &str) -> CompiledModule { + let mut script = compiled_script; + + // Add the "" identifier if it isn't present. + let self_ident_idx = match script + .identifiers + .iter() + .position(|ident| ident.as_ident_str().as_str() == name) + { + Some(idx) => IdentifierIndex::new(idx as u16), + None => { + let idx = IdentifierIndex::new(script.identifiers.len() as u16); + script + .identifiers + .push(Identifier::new(name.to_string()).unwrap()); + idx + }, + }; + + // Add a dummy address if none exists. + let dummy_addr = pseudo_script_module_id().address; + let dummy_addr_idx = match script + .address_identifiers + .iter() + .position(|addr| addr == &dummy_addr) + { + Some(idx) => AddressIdentifierIndex::new(idx as u16), + None => { + let idx = AddressIdentifierIndex::new(script.address_identifiers.len() as u16); + script.address_identifiers.push(dummy_addr); + idx + }, + }; + + // Add a self module handle. + let self_module_handle_idx = match script + .module_handles + .iter() + .position(|handle| handle.address == dummy_addr_idx && handle.name == self_ident_idx) + { + Some(idx) => ModuleHandleIndex::new(idx as u16), + None => { + let idx = ModuleHandleIndex::new(script.module_handles.len() as u16); + script.module_handles.push(ModuleHandle { + address: dummy_addr_idx, + name: self_ident_idx, + }); + idx + }, + }; + + // Find the index to the empty signature []. + // Create one if it doesn't exist. + let return_sig_idx = match script.signatures.iter().position(|sig| sig.0.is_empty()) { + Some(idx) => SignatureIndex::new(idx as u16), + None => { + let idx = SignatureIndex::new(script.signatures.len() as u16); + script.signatures.push(Signature(vec![])); + idx + }, + }; + + // Create a function handle for the main function. + let main_handle_idx = FunctionHandleIndex::new(script.function_handles.len() as u16); + script.function_handles.push(FunctionHandle { + module: self_module_handle_idx, + name: self_ident_idx, + parameters: script.parameters, + return_: return_sig_idx, + type_parameters: script.type_parameters, + access_specifiers: None, // TODO: access specifiers for script functions + attributes: vec![], + }); + + // Create a function definition for the main function. + let main_def = FunctionDefinition { + function: main_handle_idx, + visibility: Visibility::Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(script.code), + }; + + let module = CompiledModule { + version: script.version, + module_handles: script.module_handles, + self_module_handle_idx, + struct_handles: script.struct_handles, + function_handles: script.function_handles, + field_handles: vec![], + friend_decls: vec![], + + struct_def_instantiations: vec![], + function_instantiations: script.function_instantiations, + field_instantiations: vec![], + + signatures: script.signatures, + + identifiers: script.identifiers, + address_identifiers: script.address_identifiers, + constant_pool: script.constant_pool, + metadata: script.metadata, + + struct_defs: vec![], + function_defs: vec![main_def], + + struct_variant_handles: vec![], + struct_variant_instantiations: vec![], + variant_field_handles: vec![], + variant_field_instantiations: vec![], + }; + BoundsChecker::verify_module(&module).expect("invalid bounds in module"); + module +} diff --git a/third_party/move/move-binary-format/src/normalized.rs b/third_party/move/move-binary-format/src/normalized.rs deleted file mode 100644 index 9978beb12c7..00000000000 --- a/third_party/move/move-binary-format/src/normalized.rs +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -#![allow(deprecated)] -//! Defines normalized representations of Move types, fields, kinds, structs, functions, and -//! modules. These representations are useful in situations that require require comparing -//! functions, resources, and types across modules. This arises in linking, compatibility checks -//! (e.g., "is it safe to deploy this new module without updating its dependents and/or restarting -//! genesis?"), defining schemas for resources stored on-chain, and (possibly in the future) -//! allowing module updates transactions. - -use crate::{ - access::ModuleAccess, - errors::{PartialVMError, PartialVMResult}, - file_format::{ - CompiledModule, FieldDefinition, FunctionDefinition, SignatureToken, StructDefinition, - StructFieldInformation, StructTypeParameter, TypeParameterIndex, Visibility, - }, -}; -use move_core_types::{ - ability::AbilitySet, - account_address::AccountAddress, - identifier::{IdentStr, Identifier}, - language_storage::{ModuleId, StructTag, TypeTag}, - vm_status::StatusCode, -}; -use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; - -/// A normalized version of `SignatureToken`, a type expression appearing in struct or function -/// declarations. Unlike `SignatureToken`s, `normalized::Type`s from different modules can safely be -/// compared. -#[deprecated = "Normalized types are known to have serious performance issues and should be avoided for new use cases."] -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] -pub enum Type { - #[serde(rename = "bool")] - Bool, - #[serde(rename = "u8")] - U8, - #[serde(rename = "u64")] - U64, - #[serde(rename = "u128")] - U128, - #[serde(rename = "address")] - Address, - #[serde(rename = "signer")] - Signer, - Struct { - address: AccountAddress, - module: Identifier, - name: Identifier, - type_arguments: Vec, - }, - #[serde(rename = "vector")] - Vector(Box), - TypeParameter(TypeParameterIndex), - Reference(Box), - MutableReference(Box), - // NOTE: Added in bytecode version v6, do not reorder! - #[serde(rename = "u16")] - U16, - #[serde(rename = "u32")] - U32, - #[serde(rename = "u256")] - U256, -} - -/// Normalized version of a `FieldDefinition`. The `name` is included even though it is -/// metadata that it is ignored by the VM. The reason: names are important to clients. We would -/// want a change from `Account { bal: u64, seq: u64 }` to `Account { seq: u64, bal: u64 }` to be -/// marked as incompatible. Not safe to compare without an enclosing `Struct`. -#[deprecated = "Normalized types are known to have serious performance issues and should be avoided for new use cases."] -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct Field { - pub name: Identifier, - pub type_: Type, -} - -/// Normalized version of a `StructDefinition`. Not safe to compare without an associated -/// `ModuleId` or `Module`. -#[deprecated = "Normalized types are known to have serious performance issues and should be avoided for new use cases."] -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct Struct { - pub abilities: AbilitySet, - pub type_parameters: Vec, - pub fields: Vec, -} - -/// Normalized version of a `FunctionDefinition`. Not safe to compare without an associated -/// `ModuleId` or `Module`. -#[deprecated = "Normalized types are known to have serious performance issues and should be avoided for new use cases."] -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] -pub struct Function { - pub visibility: Visibility, - pub is_entry: bool, - pub type_parameters: Vec, - pub parameters: Vec, - pub return_: Vec, -} - -/// Normalized version of a `CompiledModule`: its address, name, struct declarations, and public -/// function declarations. -#[deprecated = "Normalized types are known to have serious performance issues and should be avoided for new use cases."] -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct Module { - pub file_format_version: u32, - pub address: AccountAddress, - pub name: Identifier, - pub friends: Vec, - pub structs: BTreeMap, - pub exposed_functions: BTreeMap, -} - -impl Module { - /// Extract a normalized module from a `CompiledModule`. The module `m` should be verified. - /// Nothing will break here if that is not the case, but there is little point in computing a - /// normalized representation of a module that won't verify (since it can't be published). - pub fn new(m: &CompiledModule) -> PartialVMResult { - let friends = m.immediate_friends(); - let structs = m - .struct_defs() - .iter() - .map(|d| Struct::new(m, d)) - .collect::>>()?; - let exposed_functions = m - .function_defs() - .iter() - .filter(|func_def| { - let is_vis_exposed = match func_def.visibility { - Visibility::Public | Visibility::Friend => true, - Visibility::Private => false, - }; - let is_entry_exposed = func_def.is_entry; - is_vis_exposed || is_entry_exposed - }) - .map(|func_def| Function::new(m, func_def)) - .collect(); - - Ok(Self { - file_format_version: m.version(), - address: *m.address(), - name: m.name().to_owned(), - friends, - structs, - exposed_functions, - }) - } - - pub fn module_id(&self) -> ModuleId { - ModuleId::new(self.address, self.name.clone()) - } -} - -impl Type { - /// Create a normalized `Type` for `SignatureToken` `s` in module `m`. - pub fn new(m: &CompiledModule, s: &SignatureToken) -> Self { - use SignatureToken::*; - match s { - Struct(shi) => { - let s_handle = m.struct_handle_at(*shi); - assert!(s_handle.type_parameters.is_empty(), "A struct with N type parameters should be encoded as StructModuleInstantiation with type_arguments = [TypeParameter(1), ..., TypeParameter(N)]"); - let m_handle = m.module_handle_at(s_handle.module); - Type::Struct { - address: *m.address_identifier_at(m_handle.address), - module: m.identifier_at(m_handle.name).to_owned(), - name: m.identifier_at(s_handle.name).to_owned(), - type_arguments: Vec::new(), - } - }, - StructInstantiation(shi, type_actuals) => { - let s_handle = m.struct_handle_at(*shi); - let m_handle = m.module_handle_at(s_handle.module); - Type::Struct { - address: *m.address_identifier_at(m_handle.address), - module: m.identifier_at(m_handle.name).to_owned(), - name: m.identifier_at(s_handle.name).to_owned(), - type_arguments: type_actuals.iter().map(|t| Type::new(m, t)).collect(), - } - }, - Bool => Type::Bool, - U8 => Type::U8, - U16 => Type::U16, - U32 => Type::U32, - U64 => Type::U64, - U128 => Type::U128, - U256 => Type::U256, - Address => Type::Address, - Signer => Type::Signer, - Vector(t) => Type::Vector(Box::new(Type::new(m, t))), - TypeParameter(i) => Type::TypeParameter(*i), - Reference(t) => Type::Reference(Box::new(Type::new(m, t))), - MutableReference(t) => Type::MutableReference(Box::new(Type::new(m, t))), - - Function(..) => panic!("normalized representation does not support function types"), - } - } - - /// Return true if `self` is a closed type with no free type variables - pub fn is_closed(&self) -> bool { - use Type::*; - match self { - TypeParameter(_) => false, - Bool => true, - U8 => true, - U16 => true, - U32 => true, - U64 => true, - U128 => true, - U256 => true, - Address => true, - Signer => true, - Struct { type_arguments, .. } => type_arguments.iter().all(|t| t.is_closed()), - Vector(t) | Reference(t) | MutableReference(t) => t.is_closed(), - } - } - - pub fn into_type_tag(self) -> Option { - use Type::*; - Some( - if self.is_closed() { - match self { - Reference(_) | MutableReference(_) => return None, - Bool => TypeTag::Bool, - U8 => TypeTag::U8, - U16 => TypeTag::U16, - U32 => TypeTag::U32, - U64 => TypeTag::U64, - U128 => TypeTag::U128, - U256 => TypeTag::U256, - Address => TypeTag::Address, - Signer => TypeTag::Signer, - Vector(t) => TypeTag::Vector(Box::new( - t.into_type_tag() - .expect("Invariant violation: vector type argument contains reference"), - )), - Struct { - address, - module, - name, - type_arguments, - } => TypeTag::Struct(Box::new(StructTag { - address, - module, - name, - type_args: type_arguments - .into_iter() - .map(|t| { - t.into_type_tag().expect( - "Invariant violation: struct type argument contains reference", - ) - }) - .collect(), - })), - TypeParameter(_) => unreachable!(), - } - } else { - return None; - }, - ) - } - - pub fn into_struct_tag(self) -> Option { - match self.into_type_tag()? { - TypeTag::Struct(s) => Some(*s), - _ => None, - } - } - - pub fn subst(&self, type_args: &[Type]) -> Self { - use Type::*; - match self { - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer => self.clone(), - Reference(ty) => Reference(Box::new(ty.subst(type_args))), - MutableReference(ty) => MutableReference(Box::new(ty.subst(type_args))), - Vector(t) => Vector(Box::new(t.subst(type_args))), - Struct { - address, - module, - name, - type_arguments, - } => Struct { - address: *address, - module: module.clone(), - name: name.clone(), - type_arguments: type_arguments - .iter() - .map(|t| t.subst(type_args)) - .collect::>(), - }, - TypeParameter(i) => type_args - .get(*i as usize) - .expect("Type parameter index out of bound") - .clone(), - } - } -} - -impl Field { - /// Create a `Field` for `FieldDefinition` `f` in module `m`. - pub fn new(m: &CompiledModule, f: &FieldDefinition) -> Self { - Field { - name: m.identifier_at(f.name).to_owned(), - type_: Type::new(m, &f.signature.0), - } - } -} - -impl Struct { - /// Create a `Struct` for `StructDefinition` `def` in module `m`. Panics if `def` is a - /// a native struct definition. - pub fn new(m: &CompiledModule, def: &StructDefinition) -> PartialVMResult<(Identifier, Self)> { - let handle = m.struct_handle_at(def.struct_handle); - let fields = match &def.field_information { - StructFieldInformation::Native => { - // Pretend for compatibility checking no fields - vec![] - }, - StructFieldInformation::Declared(fields) => { - fields.iter().map(|f| Field::new(m, f)).collect() - }, - StructFieldInformation::DeclaredVariants(..) => { - // If we run into this it means that the legacy compatibility checker is run - // which is based on deprecated normalized representation since the new one - // is feature gated. - return Err(PartialVMError::new(StatusCode::FEATURE_NOT_ENABLED) - .with_message("enum types".to_string())); - }, - }; - let name = m.identifier_at(handle.name).to_owned(); - let s = Struct { - abilities: handle.abilities, - type_parameters: handle.type_parameters.clone(), - fields, - }; - Ok((name, s)) - } - - pub fn type_param_constraints(&self) -> impl ExactSizeIterator { - self.type_parameters.iter().map(|param| ¶m.constraints) - } -} - -impl Function { - /// Create a `FunctionSignature` for `FunctionHandle` `f` in module `m`. - pub fn new(m: &CompiledModule, def: &FunctionDefinition) -> (Identifier, Self) { - let fhandle = m.function_handle_at(def.function); - let name = m.identifier_at(fhandle.name).to_owned(); - let f = Function { - visibility: def.visibility, - is_entry: def.is_entry, - type_parameters: fhandle.type_parameters.clone(), - parameters: m - .signature_at(fhandle.parameters) - .0 - .iter() - .map(|s| Type::new(m, s)) - .collect(), - return_: m - .signature_at(fhandle.return_) - .0 - .iter() - .map(|s| Type::new(m, s)) - .collect(), - }; - (name, f) - } - - /// Create a `Function` for function named `func_name` in module `m`. - pub fn new_from_name(m: &CompiledModule, func_name: &IdentStr) -> Option { - for func_defs in &m.function_defs { - if m.identifier_at(m.function_handle_at(func_defs.function).name) == func_name { - return Some(Self::new(m, func_defs).1); - } - } - None - } -} - -impl From for Type { - fn from(ty: TypeTag) -> Type { - use Type::*; - match ty { - TypeTag::Bool => Bool, - TypeTag::U8 => U8, - TypeTag::U16 => U16, - TypeTag::U32 => U32, - TypeTag::U64 => U64, - TypeTag::U128 => U128, - TypeTag::U256 => U256, - TypeTag::Address => Address, - TypeTag::Signer => Signer, - TypeTag::Vector(ty) => Vector(Box::new(Type::from(*ty))), - TypeTag::Struct(s) => Struct { - address: s.address, - module: s.module, - name: s.name, - type_arguments: s.type_args.into_iter().map(|ty| ty.into()).collect(), - }, - TypeTag::Function(_) => panic!("function types not supported in normalized types"), - } - } -} - -impl std::fmt::Display for Type { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Type::Struct { - address, - module, - name, - type_arguments, - } => { - write!( - f, - "0x{}::{}::{}", - address.short_str_lossless(), - module, - name - )?; - if let Some(first_ty) = type_arguments.first() { - write!(f, "<")?; - write!(f, "{}", first_ty)?; - for ty in type_arguments.iter().skip(1) { - write!(f, ", {}", ty)?; - } - write!(f, ">")?; - } - Ok(()) - }, - Type::Vector(ty) => write!(f, "vector<{}>", ty), - Type::U8 => write!(f, "u8"), - Type::U16 => write!(f, "u16"), - Type::U32 => write!(f, "u32"), - Type::U64 => write!(f, "u64"), - Type::U128 => write!(f, "u128"), - Type::U256 => write!(f, "u256"), - Type::Address => write!(f, "address"), - Type::Signer => write!(f, "signer"), - Type::Bool => write!(f, "bool"), - Type::Reference(r) => write!(f, "&{}", r), - Type::MutableReference(r) => write!(f, "&mut {}", r), - Type::TypeParameter(i) => write!(f, "T{:?}", i), - } - } -} diff --git a/third_party/move/move-binary-format/src/proptest_types.rs b/third_party/move/move-binary-format/src/proptest_types.rs index 9625fc5457f..13bb5d968b3 100644 --- a/third_party/move/move-binary-format/src/proptest_types.rs +++ b/third_party/move/move-binary-format/src/proptest_types.rs @@ -405,10 +405,10 @@ impl CompiledModuleStrategyGen { /// A utility function that produces a prop_index but also avoiding the given index. If the random /// index at the first choice collides with the avoidance, then try +/- 1 from the chosen value and /// pick the one that does not over/under-flow. -pub(crate) fn prop_index_avoid(gen: PropIndex, avoid: usize, pool_size: usize) -> usize { +pub(crate) fn prop_index_avoid(r#gen: PropIndex, avoid: usize, pool_size: usize) -> usize { assert!(pool_size > 1); assert!(pool_size > avoid); - let rand = gen.index(pool_size); + let rand = r#gen.index(pool_size); if rand != avoid { return rand; } diff --git a/third_party/move/move-binary-format/src/proptest_types/functions.rs b/third_party/move/move-binary-format/src/proptest_types/functions.rs index 55465b56bf8..bd41e1b1fce 100644 --- a/third_party/move/move-binary-format/src/proptest_types/functions.rs +++ b/third_party/move/move-binary-format/src/proptest_types/functions.rs @@ -21,7 +21,7 @@ use crate::{ TableSize, }, }; -use move_core_types::{ability::AbilitySet, u256::U256}; +use move_core_types::{ability::AbilitySet, int256::U256}; use proptest::{ collection::{vec, SizeRange}, option::of, @@ -1063,8 +1063,8 @@ impl BytecodeGen { fn check_signature_token(token: &SignatureToken) -> bool { use SignatureToken::*; match token { - U8 | U16 | U32 | U64 | U128 | U256 | Bool | Address | Signer | Struct(_) - | TypeParameter(_) => true, + U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 | Bool + | Address | Signer | Struct(_) | TypeParameter(_) => true, Vector(element_token) => BytecodeGen::check_signature_token(element_token), StructInstantiation(_, type_arguments) => type_arguments .iter() diff --git a/third_party/move/move-binary-format/src/proptest_types/types.rs b/third_party/move/move-binary-format/src/proptest_types/types.rs index e54b0bdb972..fd8f6a00d8a 100644 --- a/third_party/move/move-binary-format/src/proptest_types/types.rs +++ b/third_party/move/move-binary-format/src/proptest_types/types.rs @@ -63,7 +63,8 @@ impl StDefnMaterializeState { use SignatureToken::*; match ty { - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address => AbilitySet::PRIMITIVES, + Bool | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Address => AbilitySet::PRIMITIVES, Reference(_) | MutableReference(_) => AbilitySet::REFERENCES, Signer => AbilitySet::SIGNER, diff --git a/third_party/move/move-binary-format/src/serializer.rs b/third_party/move/move-binary-format/src/serializer.rs index 8920313627a..dc4c309264f 100644 --- a/third_party/move/move-binary-format/src/serializer.rs +++ b/third_party/move/move-binary-format/src/serializer.rs @@ -782,6 +782,12 @@ fn serialize_signature_token_single_node_impl( SignatureToken::U64 => binary.push(SerializedType::U64 as u8)?, SignatureToken::U128 => binary.push(SerializedType::U128 as u8)?, SignatureToken::U256 => binary.push(SerializedType::U256 as u8)?, + SignatureToken::I8 => binary.push(SerializedType::I8 as u8)?, + SignatureToken::I16 => binary.push(SerializedType::I16 as u8)?, + SignatureToken::I32 => binary.push(SerializedType::I32 as u8)?, + SignatureToken::I64 => binary.push(SerializedType::I64 as u8)?, + SignatureToken::I128 => binary.push(SerializedType::I128 as u8)?, + SignatureToken::I256 => binary.push(SerializedType::I256 as u8)?, SignatureToken::Address => binary.push(SerializedType::ADDRESS as u8)?, SignatureToken::Signer => binary.push(SerializedType::SIGNER as u8)?, SignatureToken::Vector(_) => { @@ -1146,6 +1152,7 @@ fn serialize_instruction_inner( Bytecode::Mul => binary.push(Opcodes::MUL as u8), Bytecode::Mod => binary.push(Opcodes::MOD as u8), Bytecode::Div => binary.push(Opcodes::DIV as u8), + Bytecode::Negate => binary.push(Opcodes::NEGATE as u8), Bytecode::BitOr => binary.push(Opcodes::BIT_OR as u8), Bytecode::BitAnd => binary.push(Opcodes::BIT_AND as u8), Bytecode::Xor => binary.push(Opcodes::XOR as u8), @@ -1251,6 +1258,37 @@ fn serialize_instruction_inner( Bytecode::CastU16 => binary.push(Opcodes::CAST_U16 as u8), Bytecode::CastU32 => binary.push(Opcodes::CAST_U32 as u8), Bytecode::CastU256 => binary.push(Opcodes::CAST_U256 as u8), + + Bytecode::LdI8(value) => { + binary.push(Opcodes::LD_I8 as u8)?; + binary.push(*value as u8) + }, + Bytecode::LdI16(value) => { + binary.push(Opcodes::LD_I16 as u8)?; + binary.extend(&value.to_le_bytes()) + }, + Bytecode::LdI32(value) => { + binary.push(Opcodes::LD_I32 as u8)?; + binary.extend(&value.to_le_bytes()) + }, + Bytecode::LdI64(value) => { + binary.push(Opcodes::LD_I64 as u8)?; + binary.extend(&value.to_le_bytes()) + }, + Bytecode::LdI128(value) => { + binary.push(Opcodes::LD_I128 as u8)?; + binary.extend(&value.to_le_bytes()) + }, + Bytecode::LdI256(value) => { + binary.push(Opcodes::LD_I256 as u8)?; + binary.extend(&(*value).to_le_bytes()) + }, + Bytecode::CastI8 => binary.push(Opcodes::CAST_I8 as u8), + Bytecode::CastI16 => binary.push(Opcodes::CAST_I16 as u8), + Bytecode::CastI32 => binary.push(Opcodes::CAST_I32 as u8), + Bytecode::CastI64 => binary.push(Opcodes::CAST_I64 as u8), + Bytecode::CastI128 => binary.push(Opcodes::CAST_I128 as u8), + Bytecode::CastI256 => binary.push(Opcodes::CAST_I256 as u8), }; res?; Ok(()) diff --git a/third_party/move/move-binary-format/src/views.rs b/third_party/move/move-binary-format/src/views.rs index ed3c041e9a2..02c23ae2dfa 100644 --- a/third_party/move/move-binary-format/src/views.rs +++ b/third_party/move/move-binary-format/src/views.rs @@ -53,7 +53,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn module_handles( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .module_handles() @@ -63,7 +63,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn struct_handles( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .struct_handles() @@ -73,7 +73,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn function_handles( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .function_handles() @@ -81,7 +81,9 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { .map(move |function_handle| FunctionHandleView::new(module, function_handle)) } - pub fn field_handles(&self) -> impl DoubleEndedIterator> + Send { + pub fn field_handles( + &self, + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .field_handles() @@ -91,7 +93,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn struct_instantiations( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .struct_instantiations() @@ -101,7 +103,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn function_instantiations( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .function_instantiations() @@ -111,7 +113,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn field_instantiations( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .field_instantiations() @@ -119,7 +121,9 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { .map(move |field_inst| FieldInstantiationView::new(module, field_inst)) } - pub fn signatures(&self) -> impl DoubleEndedIterator> + Send { + pub fn signatures( + &self, + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .signatures() @@ -127,7 +131,9 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { .map(move |signature| SignatureView::new(module, signature)) } - pub fn structs(&self) -> impl DoubleEndedIterator> + Send { + pub fn structs( + &self, + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .struct_defs() @@ -137,7 +143,7 @@ impl<'a, T: ModuleAccess> ModuleView<'a, T> { pub fn functions( &self, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; module .function_defs() @@ -285,7 +291,9 @@ impl<'a, T: ModuleAccess> FunctionHandleView<'a, T> { } #[inline] - pub fn return_tokens(&self) -> impl DoubleEndedIterator> + 'a { + pub fn return_tokens( + &self, + ) -> impl DoubleEndedIterator> + 'a + use<'a, T> { let module = self.module; let return_ = self.module.signature_at(self.function_handle.return_); return_ @@ -295,7 +303,9 @@ impl<'a, T: ModuleAccess> FunctionHandleView<'a, T> { } #[inline] - pub fn arg_tokens(&self) -> impl DoubleEndedIterator> + 'a { + pub fn arg_tokens( + &self, + ) -> impl DoubleEndedIterator> + 'a + use<'a, T> { let module = self.module; let parameters = self.module.signature_at(self.function_handle.parameters); parameters @@ -330,6 +340,10 @@ impl<'a, T: ModuleAccess> FunctionHandleView<'a, T> { pub fn attributes(&self) -> &[FunctionAttribute] { &self.function_handle.attributes } + + pub fn access_specifiers(&self) -> Option<&Vec> { + self.function_handle.access_specifiers.as_ref() + } } pub struct StructDefinitionView<'a, T> { @@ -372,14 +386,15 @@ impl<'a, T: ModuleAccess> StructDefinitionView<'a, T> { pub fn fields( &self, - ) -> Option> + Send> { + ) -> Option> + Send + use<'a, T>> + { Some(self.fields_optional_variant(None)) } pub fn fields_optional_variant( &self, variant: Option, - ) -> impl DoubleEndedIterator> + Send { + ) -> impl DoubleEndedIterator> + Send + use<'a, T> { let module = self.module; self.struct_def .field_information @@ -511,6 +526,10 @@ impl<'a, T: ModuleAccess> FunctionDefinitionView<'a, T> { self.function_handle_view.attributes() } + pub fn acquired_resources(&self) -> &[StructDefinitionIndex] { + &self.function_def.acquires_global_resources + } + pub fn is_entry(&self) -> bool { self.function_def.is_entry } @@ -539,11 +558,15 @@ impl<'a, T: ModuleAccess> FunctionDefinitionView<'a, T> { self.function_handle_view.type_parameters() } - pub fn return_tokens(&self) -> impl DoubleEndedIterator> + 'a { + pub fn return_tokens( + &self, + ) -> impl DoubleEndedIterator> + 'a + use<'a, T> { self.function_handle_view.return_tokens() } - pub fn arg_tokens(&self) -> impl DoubleEndedIterator> + 'a { + pub fn arg_tokens( + &self, + ) -> impl DoubleEndedIterator> + 'a + use<'a, T> { self.function_handle_view.arg_tokens() } @@ -664,7 +687,9 @@ impl<'a, T: ModuleAccess> SignatureView<'a, T> { } #[inline] - pub fn tokens(&self) -> impl DoubleEndedIterator> + 'a { + pub fn tokens( + &self, + ) -> impl DoubleEndedIterator> + 'a + use<'a, T> { let module = self.module; self.signature .0 diff --git a/third_party/move/move-borrow-graph/Cargo.toml b/third_party/move/move-borrow-graph/Cargo.toml index 891b9be448c..d8dbd70991a 100644 --- a/third_party/move/move-borrow-graph/Cargo.toml +++ b/third_party/move/move-borrow-graph/Cargo.toml @@ -3,5 +3,5 @@ name = "move-borrow-graph" version = "0.0.1" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" diff --git a/third_party/move/move-borrow-graph/src/references.rs b/third_party/move/move-borrow-graph/src/references.rs index 9f9798b1e47..83f623642bb 100644 --- a/third_party/move/move-borrow-graph/src/references.rs +++ b/third_party/move/move-borrow-graph/src/references.rs @@ -130,7 +130,7 @@ impl BorrowEdgeSet { self.edges.is_empty() } - pub(crate) fn iter(&self) -> std::collections::btree_set::Iter> { + pub(crate) fn iter(&self) -> std::collections::btree_set::Iter<'_, BorrowEdge> { debug_assert!(self.overflown || !self.is_empty()); self.edges.iter() } diff --git a/third_party/move/move-bytecode-spec/Cargo.toml b/third_party/move/move-bytecode-spec/Cargo.toml index 56d48533bfe..ad84987530b 100644 --- a/third_party/move/move-bytecode-spec/Cargo.toml +++ b/third_party/move/move-bytecode-spec/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/aptos-labs/aptos-core" homepage = "https://aptosfoundation.org/" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] once_cell = { workspace = true } diff --git a/third_party/move/move-bytecode-verifier/Cargo.toml b/third_party/move/move-bytecode-verifier/Cargo.toml index 2f506216981..71715923f82 100644 --- a/third_party/move/move-bytecode-verifier/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] fail = { workspace = true } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml index 30c43d5d75f..b8524843088 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dev-dependencies] fail = { workspace = true, features = ['failpoints'] } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs deleted file mode 100644 index 08bbdca20c0..00000000000 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::CompiledModule; -use move_bytecode_verifier::ability_field_requirements; -use proptest::prelude::*; - -proptest! { - #[test] - fn valid_ability_transitivity(module in CompiledModule::valid_strategy(20)) { - prop_assert!(ability_field_requirements::verify_module(&module).is_ok()); - } -} diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs index 081ed67a5f4..2df4e49233c 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs @@ -104,7 +104,7 @@ fn invalid_type_param_in_field() { let mut m = basic_test_module(); match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { + StructFieldInformation::Declared(fields) => { fields[0].signature.0 = TypeParameter(0); assert_eq!( BoundsChecker::verify_module(&m).unwrap_err().major_status(), @@ -121,7 +121,7 @@ fn invalid_struct_in_field() { let mut m = basic_test_module(); match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { + StructFieldInformation::Declared(fields) => { fields[0].signature.0 = Struct(StructHandleIndex::new(3)); assert_eq!( BoundsChecker::verify_module(&m).unwrap_err().major_status(), @@ -138,7 +138,7 @@ fn invalid_struct_with_actuals_in_field() { let mut m = basic_test_module(); match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { + StructFieldInformation::Declared(fields) => { fields[0].signature.0 = StructInstantiation(StructHandleIndex::new(0), vec![TypeParameter(0)]); assert_eq!( @@ -395,9 +395,9 @@ proptest! { /// There are some potentially tricky edge cases around ranges that are captured here. #[test] fn valid_bounds_no_members() { - let mut gen = CompiledModuleStrategyGen::new(20); - gen.zeros_all(); - proptest!(|(_module in gen.generate())| { + let mut r#gen = CompiledModuleStrategyGen::new(20); + r#gen.zeros_all(); + proptest!(|(_module in r#gen.generate())| { // gen.generate() will panic if there are any bounds check issues. }); } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs index 30acf6b0013..ed4df8b9127 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::file_format::*; -use move_bytecode_verifier::dependencies; +use move_bytecode_verifier::{dependencies, VerifierConfig}; use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, @@ -276,20 +276,23 @@ fn deprecated_script_visibility_checks_valid() { // module uses script functions from script context let is_valid = true; let non_generic_call_mod = mk_invoking_module(false, is_valid); - let result = dependencies::verify_module(&non_generic_call_mod, deps); + let result = + dependencies::verify_module(&VerifierConfig::default(), &non_generic_call_mod, deps); assert!(result.is_ok()); let generic_call_mod = mk_invoking_module(true, is_valid); - let result = dependencies::verify_module(&generic_call_mod, deps); + let result = dependencies::verify_module(&VerifierConfig::default(), &generic_call_mod, deps); assert!(result.is_ok()); // script uses script functions let non_generic_call_script = mk_invoking_script(false); - let result = dependencies::verify_script(&non_generic_call_script, deps); + let result = + dependencies::verify_script(&VerifierConfig::default(), &non_generic_call_script, deps); assert!(result.is_ok()); let generic_call_script = mk_invoking_script(true); - let result = dependencies::verify_script(&generic_call_script, deps); + let result = + dependencies::verify_script(&VerifierConfig::default(), &generic_call_script, deps); assert!(result.is_ok()); } @@ -303,14 +306,15 @@ fn deprecated_script_visibility_checks_invalid() { // module uses script functions from script context let not_valid = false; let non_generic_call_mod = mk_invoking_module(false, not_valid); - let result = dependencies::verify_module(&non_generic_call_mod, deps); + let result = + dependencies::verify_module(&VerifierConfig::default(), &non_generic_call_mod, deps); assert_eq!( result.unwrap_err().major_status(), StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, ); let generic_call_mod = mk_invoking_module(true, not_valid); - let result = dependencies::verify_module(&generic_call_mod, deps); + let result = dependencies::verify_module(&VerifierConfig::default(), &generic_call_mod, deps); assert_eq!( result.unwrap_err().major_status(), StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs index 1bb45fd6b9c..e5679dcbb03 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs @@ -27,9 +27,11 @@ fn test_large_types() { let mut m = empty_module(); m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(get_nested_vec_type(64)))) - .take(NUM_LOCALS as usize) - .collect(), + std::iter::repeat_n( + SignatureToken::Reference(Box::new(get_nested_vec_type(64))), + NUM_LOCALS as usize, + ) + .collect(), )); m.function_handles.push(FunctionHandle { @@ -160,6 +162,6 @@ fn test_large_types() { ); assert_eq!( result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED, + StatusCode::TOO_MANY_TYPE_NODES, ); } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs index dc09fd919b3..5f2c6236cbf 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs @@ -18,7 +18,7 @@ fn test_function_handle_type_instantiation() { name: IdentifierIndex::new(0), parameters: SignatureIndex(0), return_: SignatureIndex(0), - type_parameters: std::iter::repeat(AbilitySet::ALL).take(10).collect(), + type_parameters: std::iter::repeat_n(AbilitySet::ALL, 10).collect(), access_specifiers: None, attributes: vec![], }); @@ -42,7 +42,7 @@ fn test_function_handle_type_instantiation() { name: IdentifierIndex::new(0), parameters: SignatureIndex(0), return_: SignatureIndex(0), - type_parameters: std::iter::repeat(AbilitySet::ALL).take(10).collect(), + type_parameters: std::iter::repeat_n(AbilitySet::ALL, 10).collect(), access_specifiers: None, attributes: vec![], }); @@ -68,11 +68,13 @@ fn test_struct_handle_type_instantiation() { module: ModuleHandleIndex::new(0), name: IdentifierIndex::new(0), abilities: AbilitySet::ALL, - type_parameters: std::iter::repeat(StructTypeParameter { - constraints: AbilitySet::ALL, - is_phantom: false, - }) - .take(10) + type_parameters: std::iter::repeat_n( + StructTypeParameter { + constraints: AbilitySet::ALL, + is_phantom: false, + }, + 10, + ) .collect(), }); @@ -94,11 +96,13 @@ fn test_struct_handle_type_instantiation() { module: ModuleHandleIndex::new(0), name: IdentifierIndex::new(0), abilities: AbilitySet::ALL, - type_parameters: std::iter::repeat(StructTypeParameter { - constraints: AbilitySet::ALL, - is_phantom: false, - }) - .take(10) + type_parameters: std::iter::repeat_n( + StructTypeParameter { + constraints: AbilitySet::ALL, + is_phantom: false, + }, + 10, + ) .collect(), }); @@ -120,7 +124,7 @@ fn test_struct_handle_type_instantiation() { fn test_function_handle_parameters() { let mut m = basic_test_module(); m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Bool).take(10).collect(), + std::iter::repeat_n(SignatureToken::Bool, 10).collect(), )); m.function_handles.push(FunctionHandle { module: ModuleHandleIndex::new(0), @@ -147,7 +151,7 @@ fn test_function_handle_parameters() { let mut s = basic_test_script(); s.signatures.push(Signature( - std::iter::repeat(SignatureToken::Bool).take(10).collect(), + std::iter::repeat_n(SignatureToken::Bool, 10).collect(), )); s.function_handles.push(FunctionHandle { module: ModuleHandleIndex::new(0), diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/locals.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/locals.rs index 4e59638d22e..320ef1d233b 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/locals.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/locals.rs @@ -41,9 +41,7 @@ fn test_locals() { // signature of locals in f1..f m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8) - .take(MAX_LOCALS as usize) - .collect(), + std::iter::repeat_n(SignatureToken::U8, MAX_LOCALS as usize).collect(), )); m.identifiers.push(Identifier::new("pwn").unwrap()); diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs index 85c2ad5b41a..435ccf8edfe 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs @@ -20,9 +20,7 @@ fn many_backedges() { // signature of locals in f1..f m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8) - .take(MAX_LOCALS as usize) - .collect(), + std::iter::repeat_n(SignatureToken::U8, MAX_LOCALS as usize).collect(), )); // create returns_bool_and_u64 diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs index 7b6037e7335..5eed1537473 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/mod.rs @@ -2,7 +2,6 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -pub mod ability_field_requirements_tests; pub mod binary_samples; pub mod bounds_tests; pub mod catch_unwind; diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs index d244f6dd37e..d81f81015b8 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs @@ -4,8 +4,8 @@ use move_binary_format::CompiledModule; use move_bytecode_verifier::{ - ability_field_requirements, constants, instantiation_loops::InstantiationLoopChecker, - DuplicationChecker, InstructionConsistency, RecursiveStructDefChecker, SignatureChecker, + constants, instantiation_loops::InstantiationLoopChecker, DuplicationChecker, + InstructionConsistency, RecursiveStructDefChecker, }; use proptest::prelude::*; @@ -13,10 +13,8 @@ proptest! { #[test] fn check_verifier_passes(module in CompiledModule::valid_strategy(20)) { DuplicationChecker::verify_module(&module).expect("DuplicationChecker failure"); - SignatureChecker::verify_module(&module).expect("SignatureChecker failure"); InstructionConsistency::verify_module(&module).expect("InstructionConsistency failure"); constants::verify_module(&module).expect("constants failure"); - ability_field_requirements::verify_module(&module).expect("ability_field_requirements failure"); RecursiveStructDefChecker::verify_module(&module).expect("RecursiveStructDefChecker failure"); InstantiationLoopChecker::verify_module(&module).expect("InstantiationLoopChecker failure"); } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs index e4888cf4204..392ef54a8a8 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs @@ -41,9 +41,11 @@ fn test_bicliques() { // create take_and_return_references m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U64))) - .take(NUM_LOCALS as usize) - .collect(), + std::iter::repeat_n( + SignatureToken::Reference(Box::new(SignatureToken::U64)), + NUM_LOCALS as usize, + ) + .collect(), )); m.identifiers .push(Identifier::new("take_and_return_references").unwrap()); @@ -170,9 +172,11 @@ fn test_merge_state_large_graph() { }); m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) - .take(N as usize) - .collect(), + std::iter::repeat_n( + SignatureToken::Reference(Box::new(SignatureToken::U8)), + N as usize, + ) + .collect(), )); m.identifiers.push(Identifier::new("return_refs").unwrap()); @@ -301,9 +305,11 @@ fn test_merge_state() { SignatureToken::U8, ))])); m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) - .take(NUM_LOCALS as usize - 1) - .collect(), + std::iter::repeat_n( + SignatureToken::Reference(Box::new(SignatureToken::U8)), + NUM_LOCALS as usize - 1, + ) + .collect(), )); for i in 0..NUM_FUNCTIONS { @@ -382,7 +388,7 @@ fn test_copyloc_pop() { ])); // for VecImmBorrow m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8).take(1).collect(), + std::iter::repeat_n(SignatureToken::U8, 1).collect(), )); m.signatures .push(Signature(vec![SignatureToken::TypeParameter(0)])); diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs index 39befed6019..4103114a9b5 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs @@ -5,58 +5,11 @@ use move_binary_format::file_format::{ Bytecode::*, CompiledModule, SignatureToken::*, Visibility::Public, *, }; -use move_bytecode_verifier::{ - verify_module, verify_module_with_config_for_test, SignatureChecker, VerifierConfig, -}; -use move_bytecode_verifier_invalid_mutations::signature::{FieldRefMutation, SignatureRefMutation}; +use move_bytecode_verifier::{verify_module, verify_module_with_config_for_test, VerifierConfig}; use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, }; -use proptest::{collection::vec, prelude::*, sample::Index as PropIndex}; - -#[test] -fn test_reference_of_reference() { - let mut m = basic_test_module(); - m.signatures[0] = Signature(vec![Reference(Box::new(Reference(Box::new( - SignatureToken::Bool, - ))))]); - let errors = SignatureChecker::verify_module(&m); - assert!(errors.is_err()); -} - -proptest! { - #[test] - fn valid_signatures(module in CompiledModule::valid_strategy(20)) { - prop_assert!(SignatureChecker::verify_module(&module).is_ok()) - } - - #[test] - fn double_refs( - mut module in CompiledModule::valid_strategy(20), - mutations in vec((any::(), any::()), 0..20), - ) { - let context = SignatureRefMutation::new(&mut module, mutations); - let expected_violations = context.apply(); - - let result = SignatureChecker::verify_module(&module); - - prop_assert_eq!(expected_violations, result.is_err()); - } - - #[test] - fn field_def_references( - mut module in CompiledModule::valid_strategy(20), - mutations in vec((any::(), any::()), 0..40), - ) { - let context = FieldRefMutation::new(&mut module, mutations); - let expected_violations = context.apply(); - - let result = SignatureChecker::verify_module(&module); - - prop_assert_eq!(expected_violations, result.is_err()); - } -} #[test] fn no_verify_locals_good() { diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs index 4a119ab4b50..b2399273677 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs @@ -50,12 +50,10 @@ fn test_vec_pack() { m.function_defs[0].code.as_mut().unwrap().code = std::iter::once(&[Bytecode::VecPack(sig, 0)][..]) - .chain( - std::iter::repeat( - &[Bytecode::VecUnpack(sig, 1024), Bytecode::VecPack(sig, 1024)][..], - ) - .take(COUNT), - ) + .chain(std::iter::repeat_n( + &[Bytecode::VecUnpack(sig, 1024), Bytecode::VecPack(sig, 1024)][..], + COUNT, + )) .chain(std::iter::once(&[Bytecode::Pop, Bytecode::Ret][..])) .flatten() .cloned() @@ -67,5 +65,5 @@ fn test_vec_pack() { &m, ) .unwrap_err(); - assert_eq!(res.major_status(), StatusCode::VALUE_STACK_PUSH_OVERFLOW); + assert_eq!(res.major_status(), StatusCode::TOO_MANY_TYPE_NODES); } diff --git a/third_party/move/move-bytecode-verifier/invalid-mutations/Cargo.toml b/third_party/move/move-bytecode-verifier/invalid-mutations/Cargo.toml index db099869774..4f7e63f75ff 100644 --- a/third_party/move/move-bytecode-verifier/invalid-mutations/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/invalid-mutations/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "move-bytecode-verifier-invalid-mutations" version = "0.1.0" -edition = "2021" +edition = { workspace = true } authors = ["Diem Association "] description = "Diem invalid mutations" repository = "https://github.com/diem/diem" diff --git a/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds.rs b/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds.rs index cb47be2e8e2..bca6a65e776 100644 --- a/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds.rs +++ b/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds.rs @@ -358,7 +358,7 @@ fn struct_handle(token: &SignatureToken) -> Option { Struct(sh_idx) => Some(*sh_idx), StructInstantiation(sh_idx, _) => Some(*sh_idx), Reference(token) | MutableReference(token) => struct_handle(token), - Bool | U8 | U16 | U32 | U64 | U128 | U256 | Address | Signer | Vector(_) - | TypeParameter(_) | Function(..) => None, + Bool | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 + | Address | Signer | Vector(_) | TypeParameter(_) | Function(..) => None, } } diff --git a/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds/code_unit.rs b/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds/code_unit.rs index 92a32f57b84..4d161f49f72 100644 --- a/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds/code_unit.rs +++ b/third_party/move/move-bytecode-verifier/invalid-mutations/src/bounds/code_unit.rs @@ -480,9 +480,11 @@ impl<'a> ApplyCodeUnitBoundsContext<'a> { // bytecode gets added. FreezeRef | Pop | Ret | LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU128(_) | LdU256(_) | CastU8 | CastU16 | CastU32 | CastU64 | CastU128 - | CastU256 | LdTrue | LdFalse | ReadRef | WriteRef | Add | Sub | Mul | Mod - | Div | BitOr | BitAnd | Xor | Shl | Shr | Or | And | Not | Eq | Neq | Lt - | Gt | Le | Ge | Abort | Nop => { + | CastU256 | LdI8(_) | LdI16(_) | LdI32(_) | LdI64(_) | LdI128(_) + | LdI256(_) | CastI8 | CastI16 | CastI32 | CastI64 | CastI128 | CastI256 + | LdTrue | LdFalse | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div + | Negate | BitOr | BitAnd | Xor | Shl | Shr | Or | And | Not | Eq | Neq + | Lt | Gt | Le | Ge | Abort | Nop => { panic!("Bytecode has no internal index: {:?}", code[bytecode_idx]) }, PackVariant(_) @@ -557,9 +559,11 @@ fn is_interesting(bytecode: &Bytecode) -> bool { // List out the other options explicitly so there's a compile error if a new // bytecode gets added. FreezeRef | Pop | Ret | LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU128(_) - | LdU256(_) | CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 | LdTrue - | LdFalse | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div | BitOr | BitAnd | Xor - | Shl | Shr | Or | And | Not | Eq | Neq | Lt | Gt | Le | Ge | Abort | Nop => false, + | LdU256(_) | CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 | LdI8(_) + | LdI16(_) | LdI32(_) | LdI64(_) | LdI128(_) | LdI256(_) | CastI8 | CastI16 | CastI32 + | CastI64 | CastI128 | CastI256 | LdTrue | LdFalse | ReadRef | WriteRef | Add | Sub + | Mul | Mod | Div | Negate | BitOr | BitAnd | Xor | Shl | Shr | Or | And | Not | Eq + | Neq | Lt | Gt | Le | Ge | Abort | Nop => false, PackClosure(..) | PackClosureGeneric(..) diff --git a/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs b/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs deleted file mode 100644 index 4a5e5cb2fad..00000000000 --- a/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker for verifying that all of the struct's fields satisfy the -//! abilities required by the struct's abilities -use move_binary_format::{ - access::ModuleAccess, - binary_views::BinaryIndexedView, - errors::{verification_error, Location, PartialVMResult, VMResult}, - file_format::{CompiledModule, FieldDefinition, StructFieldInformation, TableIndex}, - IndexKind, -}; -use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; - -pub fn verify_module(module: &CompiledModule) -> VMResult<()> { - verify_module_impl(module).map_err(|e| e.finish(Location::Module(module.self_id()))) -} - -fn verify_module_impl(module: &CompiledModule) -> PartialVMResult<()> { - let view = BinaryIndexedView::Module(module); - for (idx, struct_def) in module.struct_defs().iter().enumerate() { - let sh = module.struct_handle_at(struct_def.struct_handle); - let required_abilities = sh - .abilities - .into_iter() - .map(|a| a.requires()) - .fold(AbilitySet::EMPTY, |acc, required| acc | required); - // Assume type parameters have all abilities, as the struct's abilities will be dependent on - // them - let type_parameter_abilities = sh - .type_parameters - .iter() - .map(|_| AbilitySet::ALL) - .collect::>(); - match &struct_def.field_information { - StructFieldInformation::Native => continue, - StructFieldInformation::Declared(fields) => check_field_abilities( - view, - idx, - required_abilities, - &type_parameter_abilities, - fields.iter(), - )?, - StructFieldInformation::DeclaredVariants(variants) => check_field_abilities( - view, - idx, - required_abilities, - &type_parameter_abilities, - variants.iter().flat_map(|v| v.fields.iter()), - )?, - } - } - Ok(()) -} - -fn check_field_abilities<'a>( - view: BinaryIndexedView, - idx: usize, - required_abilities: AbilitySet, - type_parameter_abilities: &[AbilitySet], - fields: impl Iterator, -) -> PartialVMResult<()> { - for field in fields { - let field_abilities = view.abilities(&field.signature.0, type_parameter_abilities)?; - if !required_abilities.is_subset(field_abilities) { - return Err(verification_error( - StatusCode::FIELD_MISSING_TYPE_ABILITY, - IndexKind::StructDefinition, - idx as TableIndex, - )); - } - } - Ok(()) -} diff --git a/third_party/move/move-bytecode-verifier/src/acquires_list_verifier.rs b/third_party/move/move-bytecode-verifier/src/acquires_list_verifier.rs index 0c9f7daf119..b87b2a5cc33 100644 --- a/third_party/move/move-bytecode-verifier/src/acquires_list_verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/acquires_list_verifier.rs @@ -135,6 +135,12 @@ impl<'a> AcquiresVerifier<'a> { | Bytecode::LdU64(_) | Bytecode::LdU128(_) | Bytecode::LdU256(_) + | Bytecode::LdI8(_) + | Bytecode::LdI16(_) + | Bytecode::LdI32(_) + | Bytecode::LdI64(_) + | Bytecode::LdI128(_) + | Bytecode::LdI256(_) | Bytecode::LdConst(_) | Bytecode::LdTrue | Bytecode::LdFalse @@ -156,11 +162,18 @@ impl<'a> AcquiresVerifier<'a> { | Bytecode::CastU64 | Bytecode::CastU128 | Bytecode::CastU256 + | Bytecode::CastI8 + | Bytecode::CastI16 + | Bytecode::CastI32 + | Bytecode::CastI64 + | Bytecode::CastI128 + | Bytecode::CastI256 | Bytecode::Add | Bytecode::Sub | Bytecode::Mul | Bytecode::Mod | Bytecode::Div + | Bytecode::Negate | Bytecode::BitOr | Bytecode::BitAnd | Bytecode::Xor diff --git a/third_party/move/move-bytecode-verifier/src/check_duplication.rs b/third_party/move/move-bytecode-verifier/src/check_duplication.rs index a42008a92ca..4e13e887695 100644 --- a/third_party/move/move-bytecode-verifier/src/check_duplication.rs +++ b/third_party/move/move-bytecode-verifier/src/check_duplication.rs @@ -271,6 +271,7 @@ impl<'a> DuplicationChecker<'a> { }, StructFieldInformation::DeclaredVariants(variants) => { Self::check_duplicate_variants(variants.iter())?; + // Note: unlike structs, number of fields within a variant can be zero. for variant in variants { Self::check_duplicate_fields(variant.fields.iter())? } diff --git a/third_party/move/move-bytecode-verifier/src/control_flow_v5.rs b/third_party/move/move-bytecode-verifier/src/control_flow_v5.rs index bd2d39c0732..c20e9182732 100644 --- a/third_party/move/move-bytecode-verifier/src/control_flow_v5.rs +++ b/third_party/move/move-bytecode-verifier/src/control_flow_v5.rs @@ -62,7 +62,7 @@ struct ControlFlowVerifier<'a> { } impl<'a> ControlFlowVerifier<'a> { - fn code(&self) -> impl Iterator { + fn code(&self) -> impl Iterator + use<'a> { self.code .iter() .enumerate() @@ -72,7 +72,7 @@ impl<'a> ControlFlowVerifier<'a> { fn labeled_code<'b: 'a>( &self, labels: &'b [Label], - ) -> impl Iterator { + ) -> impl Iterator + use<'a, 'b> { self.code() .zip(labels) .map(|((i, instr), lbl)| (i, instr, lbl)) diff --git a/third_party/move/move-bytecode-verifier/src/dependencies.rs b/third_party/move/move-bytecode-verifier/src/dependencies.rs index 3dd868b5e8e..d99047cc43b 100644 --- a/third_party/move/move-bytecode-verifier/src/dependencies.rs +++ b/third_party/move/move-bytecode-verifier/src/dependencies.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 //! This module contains verification of usage of dependencies for modules and scripts. +use crate::VerifierConfig; use move_binary_format::{ access::{ModuleAccess, ScriptAccess}, binary_views::BinaryIndexedView, @@ -170,10 +171,13 @@ impl<'a, 'b> Context<'a, 'b> { } pub fn verify_module<'a>( + config: &VerifierConfig, module: &CompiledModule, dependencies: impl IntoIterator, ) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); + if config.verify_nothing() { + return Ok(()); + } verify_module_impl(module, dependencies) .map_err(|e| e.finish(Location::Module(module.self_id()))) } @@ -191,10 +195,13 @@ fn verify_module_impl<'a>( } pub fn verify_script<'a>( + config: &VerifierConfig, script: &CompiledScript, dependencies: impl IntoIterator, ) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); + if config.verify_nothing() { + return Ok(()); + } verify_script_impl(script, dependencies).map_err(|e| e.finish(Location::Script)) } @@ -255,7 +262,8 @@ fn verify_imported_structs(context: &Context) -> PartialVMResult<()> { StatusCode::TYPE_MISMATCH, IndexKind::StructHandle, idx as TableIndex, - )); + ) + .with_message("imported struct mismatches expectation")); } }, None => { @@ -296,7 +304,8 @@ fn verify_imported_functions(context: &Context) -> PartialVMResult<()> { StatusCode::TYPE_MISMATCH, IndexKind::FunctionHandle, idx as TableIndex, - )); + ) + .with_message("imported function mismatches expectation")); } // same parameters let handle_params = context.resolver.signature_at(function_handle.parameters); @@ -477,7 +486,7 @@ fn compare_types( def_type: &SignatureToken, def_module: &CompiledModule, ) -> PartialVMResult<()> { - match (handle_type, def_type) { + let result = match (handle_type, def_type) { (SignatureToken::Bool, SignatureToken::Bool) | (SignatureToken::U8, SignatureToken::U8) | (SignatureToken::U16, SignatureToken::U16) @@ -485,6 +494,12 @@ fn compare_types( | (SignatureToken::U64, SignatureToken::U64) | (SignatureToken::U128, SignatureToken::U128) | (SignatureToken::U256, SignatureToken::U256) + | (SignatureToken::I8, SignatureToken::I8) + | (SignatureToken::I16, SignatureToken::I16) + | (SignatureToken::I32, SignatureToken::I32) + | (SignatureToken::I64, SignatureToken::I64) + | (SignatureToken::I128, SignatureToken::I128) + | (SignatureToken::I256, SignatureToken::I256) | (SignatureToken::Address, SignatureToken::Address) | (SignatureToken::Signer, SignatureToken::Signer) => Ok(()), (SignatureToken::Vector(handle_ty), SignatureToken::Vector(def_ty)) => { @@ -496,8 +511,6 @@ fn compare_types( ) => { compare_cross_module_signatures(context, handle_args, def_args, def_module)?; compare_cross_module_signatures(context, handle_result, def_result, def_module)?; - // TODO(#15664): should we allow the definition to change to a weaker ability - // requirement? Currently we do not allow `&mut` to be changed to `&` either. if handle_ab == def_ab { Ok(()) } else { @@ -540,8 +553,21 @@ fn compare_types( | (SignatureToken::TypeParameter(_), _) | (SignatureToken::U16, _) | (SignatureToken::U32, _) - | (SignatureToken::U256, _) => Err(PartialVMError::new(StatusCode::TYPE_MISMATCH)), - } + | (SignatureToken::U256, _) + | (SignatureToken::I8, _) + | (SignatureToken::I16, _) + | (SignatureToken::I32, _) + | (SignatureToken::I64, _) + | (SignatureToken::I128, _) + | (SignatureToken::I256, _) => Err(PartialVMError::new(StatusCode::TYPE_MISMATCH)), + }; + result.map_err(|err| { + if err.message().is_none() { + err.with_message("imported type mismatches expectation") + } else { + err + } + }) } fn compare_structs( diff --git a/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs b/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs index 53896c212ee..eec171a1226 100644 --- a/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs +++ b/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs @@ -143,7 +143,8 @@ impl<'a> InstantiationLoopChecker<'a> { fn rec(type_params: &mut HashSet, ty: &SignatureToken) { match ty { - Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | Signer | Struct(_) => (), + Bool | Address | U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 + | I128 | I256 | Signer | Struct(_) => (), TypeParameter(idx) => { type_params.insert(*idx); }, @@ -217,15 +218,119 @@ impl<'a> InstantiationLoopChecker<'a> { ) { if let Some(code) = &caller_def.code { for instr in &code.code { - if let Bytecode::CallGeneric(callee_inst_idx) = instr { - // Get the id of the definition of the function being called. - // Skip if the function is not defined in the current module, as we do not - // have mutual recursions across module boundaries. - let callee_si = self.module.function_instantiation_at(*callee_inst_idx); - if let Some(callee_idx) = self.func_handle_def_map.get(&callee_si.handle) { - let callee_idx = *callee_idx; - self.build_graph_call(caller_idx, callee_idx, callee_si.type_parameters) - } + match instr { + Bytecode::CallGeneric(callee_inst_idx) + | Bytecode::PackClosureGeneric(callee_inst_idx, _) => { + // Get the id of the definition of the function being called/packed into a closure. + // Skip if the function is not defined in the current module, as we do not + // have mutual recursions across module boundaries. + let callee_si = self.module.function_instantiation_at(*callee_inst_idx); + if let Some(callee_idx) = self.func_handle_def_map.get(&callee_si.handle) { + let callee_idx = *callee_idx; + self.build_graph_call(caller_idx, callee_idx, callee_si.type_parameters) + } + }, + Bytecode::Pop + | Bytecode::Ret + | Bytecode::BrTrue(_) + | Bytecode::BrFalse(_) + | Bytecode::Branch(_) + | Bytecode::LdU8(_) + | Bytecode::LdU16(_) + | Bytecode::LdU32(_) + | Bytecode::LdU64(_) + | Bytecode::LdU128(_) + | Bytecode::LdU256(_) + | Bytecode::LdI8(_) + | Bytecode::LdI16(_) + | Bytecode::LdI32(_) + | Bytecode::LdI64(_) + | Bytecode::LdI128(_) + | Bytecode::LdI256(_) + | Bytecode::LdConst(_) + | Bytecode::LdTrue + | Bytecode::LdFalse + | Bytecode::CopyLoc(_) + | Bytecode::MoveLoc(_) + | Bytecode::StLoc(_) + | Bytecode::FreezeRef + | Bytecode::MutBorrowLoc(_) + | Bytecode::ImmBorrowLoc(_) + | Bytecode::MutBorrowField(_) + | Bytecode::ImmBorrowField(_) + | Bytecode::MutBorrowFieldGeneric(_) + | Bytecode::ImmBorrowFieldGeneric(_) + | Bytecode::Call(_) + | Bytecode::Pack(_) + | Bytecode::Unpack(_) + | Bytecode::ReadRef + | Bytecode::WriteRef + | Bytecode::CastU8 + | Bytecode::CastU16 + | Bytecode::CastU32 + | Bytecode::CastU64 + | Bytecode::CastU128 + | Bytecode::CastU256 + | Bytecode::CastI8 + | Bytecode::CastI16 + | Bytecode::CastI32 + | Bytecode::CastI64 + | Bytecode::CastI128 + | Bytecode::CastI256 + | Bytecode::Add + | Bytecode::Sub + | Bytecode::Mul + | Bytecode::Mod + | Bytecode::Div + | Bytecode::Negate + | Bytecode::BitOr + | Bytecode::BitAnd + | Bytecode::Xor + | Bytecode::Shl + | Bytecode::Shr + | Bytecode::Or + | Bytecode::And + | Bytecode::Not + | Bytecode::Eq + | Bytecode::Neq + | Bytecode::Lt + | Bytecode::Gt + | Bytecode::Le + | Bytecode::Ge + | Bytecode::Abort + | Bytecode::Nop + | Bytecode::Exists(_) + | Bytecode::ExistsGeneric(_) + | Bytecode::MoveFrom(_) + | Bytecode::MoveFromGeneric(_) + | Bytecode::MoveTo(_) + | Bytecode::MoveToGeneric(_) + | Bytecode::VecPack(_, _) + | Bytecode::VecLen(_) + | Bytecode::VecImmBorrow(_) + | Bytecode::VecMutBorrow(_) + | Bytecode::VecPushBack(_) + | Bytecode::VecPopBack(_) + | Bytecode::VecUnpack(_, _) + | Bytecode::VecSwap(_) + | Bytecode::UnpackGeneric(_) + | Bytecode::PackGeneric(_) + | Bytecode::PackVariant(_) + | Bytecode::UnpackVariant(_) + | Bytecode::PackVariantGeneric(_) + | Bytecode::UnpackVariantGeneric(_) + | Bytecode::TestVariant(_) + | Bytecode::TestVariantGeneric(_) + | Bytecode::MutBorrowVariantField(_) + | Bytecode::MutBorrowVariantFieldGeneric(_) + | Bytecode::ImmBorrowVariantField(_) + | Bytecode::ImmBorrowVariantFieldGeneric(_) + | Bytecode::MutBorrowGlobal(_) + | Bytecode::ImmBorrowGlobal(_) + | Bytecode::MutBorrowGlobalGeneric(_) + | Bytecode::ImmBorrowGlobalGeneric(_) + | Bytecode::PackClosure(_, _) + | Bytecode::CallClosure(_) => {}, } } } diff --git a/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs b/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs index ffde7c1a0f5..04cae527f8d 100644 --- a/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs +++ b/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs @@ -147,10 +147,13 @@ impl<'a> InstructionConsistency<'a> { CallClosure(_) | FreezeRef | Pop | Ret | Branch(_) | BrTrue(_) | BrFalse(_) | LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU128(_) | LdU256(_) | LdConst(_) | CastU8 | CastU16 | CastU32 | CastU64 | CastU128 | CastU256 | LdTrue | LdFalse - | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div | BitOr | BitAnd | Xor | Shl - | Shr | Or | And | Not | Eq | Neq | Lt | Gt | Le | Ge | CopyLoc(_) | MoveLoc(_) - | StLoc(_) | MutBorrowLoc(_) | ImmBorrowLoc(_) | VecLen(_) | VecImmBorrow(_) - | VecMutBorrow(_) | VecPushBack(_) | VecPopBack(_) | VecSwap(_) | Abort | Nop => (), + | ReadRef | WriteRef | Add | Sub | Mul | Mod | Div | Negate | BitOr | BitAnd + | Xor | Shl | Shr | Or | And | Not | Eq | Neq | Lt | Gt | Le | Ge | CopyLoc(_) + | MoveLoc(_) | StLoc(_) | MutBorrowLoc(_) | ImmBorrowLoc(_) | VecLen(_) + | VecImmBorrow(_) | VecMutBorrow(_) | VecPushBack(_) | VecPopBack(_) + | VecSwap(_) | Abort | Nop | LdI8(_) | LdI16(_) | LdI32(_) | LdI64(_) + | LdI128(_) | LdI256(_) | CastI8 | CastI16 | CastI32 | CastI64 | CastI128 + | CastI256 => (), } } Ok(()) diff --git a/third_party/move/move-bytecode-verifier/src/lib.rs b/third_party/move/move-bytecode-verifier/src/lib.rs index 19e53f730c7..c7b5c0f0bbf 100644 --- a/third_party/move/move-bytecode-verifier/src/lib.rs +++ b/third_party/move/move-bytecode-verifier/src/lib.rs @@ -7,7 +7,6 @@ //! Verifies bytecode sanity. // Bounds checks are implemented in the `vm` crate. -pub mod ability_field_requirements; pub mod absint; pub mod check_duplication; pub mod code_unit_verifier; @@ -22,7 +21,6 @@ pub mod instruction_consistency; pub mod limits; pub mod loop_summary; pub mod script_signature; -pub mod signature; pub mod signature_v2; pub mod struct_defs; pub mod verifier; @@ -33,7 +31,6 @@ pub use instruction_consistency::InstructionConsistency; pub use script_signature::{ legacy_script_signature_checks, no_additional_script_signature_checks, FnCheckScriptSignature, }; -pub use signature::SignatureChecker; pub use struct_defs::RecursiveStructDefChecker; pub use verifier::{ verify_module, verify_module_with_config, verify_module_with_config_for_test, verify_script, diff --git a/third_party/move/move-bytecode-verifier/src/limits.rs b/third_party/move/move-bytecode-verifier/src/limits.rs index 1fcb2436be6..e02d5921fe0 100644 --- a/third_party/move/move-bytecode-verifier/src/limits.rs +++ b/third_party/move/move-bytecode-verifier/src/limits.rs @@ -81,7 +81,14 @@ impl<'a> LimitsVerifier<'a> { return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS) .at_index(IndexKind::FunctionHandle, idx as u16)); } + } + if let Some(limit) = config.max_function_return_values { + if self.resolver.signature_at(function_handle.return_).0.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS) + .at_index(IndexKind::FunctionHandle, idx as u16)); + } }; + // Note: the size of `attributes` is limited by the deserializer. } Ok(()) } @@ -122,24 +129,65 @@ impl<'a> LimitsVerifier<'a> { config: &VerifierConfig, ty: &SignatureToken, ) -> PartialVMResult<()> { - if let Some(max) = &config.max_type_nodes { - // Structs and Parameters can expand to an unknown number of nodes, therefore - // we give them a higher size weight here. - const STRUCT_SIZE_WEIGHT: usize = 4; - const PARAM_SIZE_WEIGHT: usize = 4; - let mut size = 0; - for t in ty.preorder_traversal() { - // Notice that the preorder traversal will iterate all type instantiations, so we - // why we can ignore them below. - match t { - SignatureToken::Struct(..) | SignatureToken::StructInstantiation(..) => { - size += STRUCT_SIZE_WEIGHT - }, - SignatureToken::TypeParameter(..) => size += PARAM_SIZE_WEIGHT, - _ => size += 1, + if config.max_type_nodes.is_none() + && config.max_function_parameters.is_none() + && config.max_function_return_values.is_none() + && config.max_type_depth.is_none() + { + // If no type-related limits are set, we do not need to verify the type nodes. + return Ok(()); + } + // Structs and Parameters can expand to an unknown number of nodes, therefore + // we give them a higher size weight here. + const STRUCT_SIZE_WEIGHT: usize = 4; + const PARAM_SIZE_WEIGHT: usize = 4; + let mut type_size = 0; + for (token, depth) in ty.preorder_traversal_with_depth() { + if let Some(limit) = config.max_type_depth { + if depth > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } } - if size > *max { + match token { + SignatureToken::Struct(..) | SignatureToken::StructInstantiation(..) => { + type_size += STRUCT_SIZE_WEIGHT + }, + SignatureToken::TypeParameter(..) => type_size += PARAM_SIZE_WEIGHT, + SignatureToken::Function(params, ret, _) => { + if let Some(limit) = config.max_function_parameters { + if params.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS)); + } + } + if let Some(limit) = config.max_function_return_values { + if ret.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS)); + } + } + type_size += 1; + }, + SignatureToken::Bool + | SignatureToken::U8 + | SignatureToken::U16 + | SignatureToken::U32 + | SignatureToken::U64 + | SignatureToken::U128 + | SignatureToken::U256 + | SignatureToken::I8 + | SignatureToken::I16 + | SignatureToken::I32 + | SignatureToken::I64 + | SignatureToken::I128 + | SignatureToken::I256 + | SignatureToken::Address + | SignatureToken::Signer + | SignatureToken::Vector(_) + | SignatureToken::Reference(_) + | SignatureToken::MutableReference(_) => type_size += 1, + } + } + if let Some(limit) = config.max_type_nodes { + if type_size > limit { return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } } diff --git a/third_party/move/move-bytecode-verifier/src/locals_safety/mod.rs b/third_party/move/move-bytecode-verifier/src/locals_safety/mod.rs index 13220a1e2ee..fe51f453ba0 100644 --- a/third_party/move/move-bytecode-verifier/src/locals_safety/mod.rs +++ b/third_party/move/move-bytecode-verifier/src/locals_safety/mod.rs @@ -110,6 +110,12 @@ fn execute_inner( | Bytecode::LdU64(_) | Bytecode::LdU128(_) | Bytecode::LdU256(_) + | Bytecode::LdI8(_) + | Bytecode::LdI16(_) + | Bytecode::LdI32(_) + | Bytecode::LdI64(_) + | Bytecode::LdI128(_) + | Bytecode::LdI256(_) | Bytecode::LdConst(_) | Bytecode::LdTrue | Bytecode::LdFalse @@ -136,11 +142,18 @@ fn execute_inner( | Bytecode::CastU64 | Bytecode::CastU128 | Bytecode::CastU256 + | Bytecode::CastI8 + | Bytecode::CastI16 + | Bytecode::CastI32 + | Bytecode::CastI64 + | Bytecode::CastI128 + | Bytecode::CastI256 | Bytecode::Add | Bytecode::Sub | Bytecode::Mul | Bytecode::Mod | Bytecode::Div + | Bytecode::Negate | Bytecode::BitOr | Bytecode::BitAnd | Bytecode::Xor diff --git a/third_party/move/move-bytecode-verifier/src/loop_summary.rs b/third_party/move/move-bytecode-verifier/src/loop_summary.rs index 813f5997060..ce31624bad3 100644 --- a/third_party/move/move-bytecode-verifier/src/loop_summary.rs +++ b/third_party/move/move-bytecode-verifier/src/loop_summary.rs @@ -164,7 +164,7 @@ impl LoopSummary { /// Returns an iterator over `NodeId`s in this `LoopSummary` in pre-order according to its /// depth-first spanning tree. - pub fn preorder(&self) -> impl DoubleEndedIterator { + pub fn preorder(&self) -> impl DoubleEndedIterator + use<> { // `LoopSummary::new` assigns `NodeId`s to blocks in preorder, so just return the natural // order. (0..self.blocks.len()).map(|id| NodeId(id as u16)) diff --git a/third_party/move/move-bytecode-verifier/src/reference_safety/abstract_state.rs b/third_party/move/move-bytecode-verifier/src/reference_safety/abstract_state.rs index c950affab79..8d5b6dec48f 100644 --- a/third_party/move/move-bytecode-verifier/src/reference_safety/abstract_state.rs +++ b/third_party/move/move-bytecode-verifier/src/reference_safety/abstract_state.rs @@ -607,7 +607,7 @@ impl AbstractState { )); } - // Check mutable references can be transfered + // Check mutable references can be transferred for id in values.into_iter().filter_map(|v| v.ref_id()) { if self.borrow_graph.is_mutable(id) && !self.is_writable(id) { return Err(self.error(StatusCode::RET_BORROWED_MUTABLE_REFERENCE_ERROR, offset)); diff --git a/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs b/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs index b22f17c8097..4ce6141f368 100644 --- a/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs +++ b/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs @@ -469,6 +469,13 @@ fn execute_inner( | Bytecode::CastU64 | Bytecode::CastU128 | Bytecode::CastU256 + | Bytecode::CastI8 + | Bytecode::CastI16 + | Bytecode::CastI32 + | Bytecode::CastI64 + | Bytecode::CastI128 + | Bytecode::CastI256 + | Bytecode::Negate | Bytecode::Not | Bytecode::Exists(_) | Bytecode::ExistsGeneric(_) => (), @@ -492,6 +499,12 @@ fn execute_inner( Bytecode::LdU64(_) => verifier.stack.push(state.value_for(&SignatureToken::U64)), Bytecode::LdU128(_) => verifier.stack.push(state.value_for(&SignatureToken::U128)), Bytecode::LdU256(_) => verifier.stack.push(state.value_for(&SignatureToken::U256)), + Bytecode::LdI8(_) => verifier.stack.push(state.value_for(&SignatureToken::I8)), + Bytecode::LdI16(_) => verifier.stack.push(state.value_for(&SignatureToken::I16)), + Bytecode::LdI32(_) => verifier.stack.push(state.value_for(&SignatureToken::I32)), + Bytecode::LdI64(_) => verifier.stack.push(state.value_for(&SignatureToken::I64)), + Bytecode::LdI128(_) => verifier.stack.push(state.value_for(&SignatureToken::I128)), + Bytecode::LdI256(_) => verifier.stack.push(state.value_for(&SignatureToken::I256)), Bytecode::LdConst(idx) => { let signature = &verifier.resolver.constant_at(*idx).type_; verifier.stack.push(state.value_for(signature)) diff --git a/third_party/move/move-bytecode-verifier/src/signature.rs b/third_party/move/move-bytecode-verifier/src/signature.rs deleted file mode 100644 index f8f5ce0c84a..00000000000 --- a/third_party/move/move-bytecode-verifier/src/signature.rs +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker for verifying signature tokens used in types of function -//! parameters, locals, and fields of structs are well-formed. References can only occur at the -//! top-level in all tokens. Additionally, references cannot occur at all in field types. -use move_binary_format::{ - access::{ModuleAccess, ScriptAccess}, - binary_views::BinaryIndexedView, - errors::{Location, PartialVMError, PartialVMResult, VMResult}, - file_format::{ - Bytecode, CodeUnit, CompiledModule, CompiledScript, FieldDefinition, FunctionDefinition, - FunctionHandle, Signature, SignatureIndex, SignatureToken, StructDefinition, - StructFieldInformation, StructTypeParameter, TableIndex, - }, - file_format_common::VERSION_6, - IndexKind, -}; -use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; - -pub struct SignatureChecker<'a> { - resolver: BinaryIndexedView<'a>, -} - -impl<'a> SignatureChecker<'a> { - pub fn verify_module(module: &'a CompiledModule) -> VMResult<()> { - Self::verify_module_impl(module).map_err(|e| e.finish(Location::Module(module.self_id()))) - } - - fn verify_module_impl(module: &'a CompiledModule) -> PartialVMResult<()> { - let sig_check = Self { - resolver: BinaryIndexedView::Module(module), - }; - sig_check.verify_signature_pool(module.signatures())?; - sig_check.verify_function_signatures(module.function_handles())?; - sig_check.verify_fields(module.struct_defs())?; - sig_check.verify_code_units(module.function_defs()) - } - - pub fn verify_script(module: &'a CompiledScript) -> VMResult<()> { - Self::verify_script_impl(module).map_err(|e| e.finish(Location::Script)) - } - - fn verify_script_impl(script: &'a CompiledScript) -> PartialVMResult<()> { - let sig_check = Self { - resolver: BinaryIndexedView::Script(script), - }; - sig_check.verify_signature_pool(script.signatures())?; - sig_check.verify_function_signatures(script.function_handles())?; - sig_check.check_instantiation(script.parameters, &script.type_parameters)?; - sig_check.verify_code(script.code(), &script.type_parameters) - } - - fn verify_signature_pool(&self, signatures: &[Signature]) -> PartialVMResult<()> { - for i in 0..signatures.len() { - self.check_signature(SignatureIndex::new(i as TableIndex))? - } - Ok(()) - } - - fn verify_function_signatures( - &self, - function_handles: &[FunctionHandle], - ) -> PartialVMResult<()> { - let err_handler = |err: PartialVMError, idx| { - err.at_index(IndexKind::Signature, idx as TableIndex) - .at_index(IndexKind::FunctionHandle, idx as TableIndex) - }; - - for (idx, fh) in function_handles.iter().enumerate() { - self.check_signature(fh.return_) - .map_err(|err| err_handler(err, idx))?; - self.check_instantiation(fh.return_, &fh.type_parameters) - .map_err(|err| err_handler(err, idx))?; - self.check_signature(fh.parameters) - .map_err(|err| err_handler(err, idx))?; - self.check_instantiation(fh.parameters, &fh.type_parameters) - .map_err(|err| err_handler(err, idx))?; - if !fh.type_parameters.is_empty() {} - } - Ok(()) - } - - fn verify_fields(&self, struct_defs: &[StructDefinition]) -> PartialVMResult<()> { - for (struct_def_idx, struct_def) in struct_defs.iter().enumerate() { - match &struct_def.field_information { - StructFieldInformation::Native => {}, - StructFieldInformation::Declared(fields) => { - self.verify_fields_of_struct(struct_def_idx, struct_def, None, fields.iter())? - }, - StructFieldInformation::DeclaredVariants(variants) => { - variants - .iter() - .enumerate() - .try_for_each(|(variant_offset, variant)| { - self.verify_fields_of_struct( - struct_def_idx, - struct_def, - Some(variant_offset), - variant.fields.iter(), - ) - })? - }, - }; - } - Ok(()) - } - - fn verify_fields_of_struct<'l>( - &self, - struct_def_idx: usize, - struct_def: &StructDefinition, - variant: Option, - fields: impl Iterator, - ) -> Result<(), PartialVMError> { - let struct_handle = self.resolver.struct_handle_at(struct_def.struct_handle); - let err_handler = |err: PartialVMError, offset| { - let err = err - .at_index(IndexKind::FieldDefinition, offset as TableIndex) - .at_index(IndexKind::StructDefinition, struct_def_idx as TableIndex); - if let Some(variant) = variant { - err.at_index(IndexKind::VariantDefinition, variant as TableIndex) - } else { - err - } - }; - for (field_offset, field_def) in fields.enumerate() { - self.check_signature_token(&field_def.signature.0) - .map_err(|err| err_handler(err, field_offset))?; - let type_param_constraints: Vec<_> = struct_handle.type_param_constraints().collect(); - self.check_type_instantiation(&field_def.signature.0, &type_param_constraints) - .map_err(|err| err_handler(err, field_offset))?; - - self.check_phantom_params( - &field_def.signature.0, - false, - &struct_handle.type_parameters, - ) - .map_err(|err| err_handler(err, field_offset))?; - } - Ok(()) - } - - fn verify_code_units(&self, function_defs: &[FunctionDefinition]) -> PartialVMResult<()> { - for (func_def_idx, func_def) in function_defs.iter().enumerate() { - // skip native functions - let code = match &func_def.code { - Some(code) => code, - None => continue, - }; - let func_handle = self.resolver.function_handle_at(func_def.function); - self.verify_code(code, &func_handle.type_parameters) - .map_err(|err| { - err.at_index(IndexKind::Signature, code.locals.0) - .at_index(IndexKind::FunctionDefinition, func_def_idx as TableIndex) - })? - } - Ok(()) - } - - fn verify_code(&self, code: &CodeUnit, type_parameters: &[AbilitySet]) -> PartialVMResult<()> { - self.check_signature(code.locals)?; - self.check_instantiation(code.locals, type_parameters)?; - - // Check if the type actuals in certain bytecode instructions are well defined. - use Bytecode::*; - for (offset, instr) in code.code.iter().enumerate() { - let result = match instr { - CallGeneric(idx) => { - let func_inst = self.resolver.function_instantiation_at(*idx); - let func_handle = self.resolver.function_handle_at(func_inst.handle); - let type_arguments = &self.resolver.signature_at(func_inst.type_parameters).0; - self.check_signature_tokens(type_arguments)?; - self.check_generic_instance( - type_arguments, - func_handle.type_parameters.iter().copied(), - type_parameters, - ) - }, - PackGeneric(idx) - | UnpackGeneric(idx) - | ExistsGeneric(idx) - | MoveFromGeneric(idx) - | MoveToGeneric(idx) - | ImmBorrowGlobalGeneric(idx) - | MutBorrowGlobalGeneric(idx) => { - let struct_inst = self.resolver.struct_instantiation_at(*idx)?; - let struct_def = self.resolver.struct_def_at(struct_inst.def)?; - let struct_handle = self.resolver.struct_handle_at(struct_def.struct_handle); - let type_arguments = &self.resolver.signature_at(struct_inst.type_parameters).0; - self.check_signature_tokens(type_arguments)?; - self.check_generic_instance( - type_arguments, - struct_handle.type_param_constraints(), - type_parameters, - ) - }, - PackVariantGeneric(idx) | UnpackVariantGeneric(idx) | TestVariantGeneric(idx) => { - let variant_inst = self.resolver.struct_variant_instantiation_at(*idx)?; - let variant_handle = self - .resolver - .struct_variant_handle_at(variant_inst.handle)?; - let struct_def = self.resolver.struct_def_at(variant_handle.struct_index)?; - let struct_handle = self.resolver.struct_handle_at(struct_def.struct_handle); - let type_arguments = - &self.resolver.signature_at(variant_inst.type_parameters).0; - self.check_signature_tokens(type_arguments)?; - self.check_generic_instance( - type_arguments, - struct_handle.type_param_constraints(), - type_parameters, - ) - }, - ImmBorrowFieldGeneric(idx) | MutBorrowFieldGeneric(idx) => { - let field_inst = self.resolver.field_instantiation_at(*idx)?; - let field_handle = self.resolver.field_handle_at(field_inst.handle)?; - let struct_def = self.resolver.struct_def_at(field_handle.owner)?; - let struct_handle = self.resolver.struct_handle_at(struct_def.struct_handle); - let type_arguments = &self.resolver.signature_at(field_inst.type_parameters).0; - self.check_signature_tokens(type_arguments)?; - self.check_generic_instance( - type_arguments, - struct_handle.type_param_constraints(), - type_parameters, - ) - }, - ImmBorrowVariantFieldGeneric(idx) | MutBorrowVariantFieldGeneric(idx) => { - let field_inst = self.resolver.variant_field_instantiation_at(*idx)?; - let field_handle = self.resolver.variant_field_handle_at(field_inst.handle)?; - let struct_def = self.resolver.struct_def_at(field_handle.struct_index)?; - let struct_handle = self.resolver.struct_handle_at(struct_def.struct_handle); - let type_arguments = &self.resolver.signature_at(field_inst.type_parameters).0; - self.check_signature_tokens(type_arguments)?; - self.check_generic_instance( - type_arguments, - struct_handle.type_param_constraints(), - type_parameters, - ) - }, - VecPack(idx, _) - | VecLen(idx) - | VecImmBorrow(idx) - | VecMutBorrow(idx) - | VecPushBack(idx) - | VecPopBack(idx) - | VecUnpack(idx, _) - | VecSwap(idx) => { - let type_arguments = &self.resolver.signature_at(*idx).0; - if type_arguments.len() != 1 { - return Err(PartialVMError::new( - StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - ) - .with_message(format!( - "expected 1 type token for vector operations, got {}", - type_arguments.len() - ))); - } - self.check_signature_tokens(type_arguments) - }, - - // Closure operations not supported by legacy signature checker - PackClosure(..) | PackClosureGeneric(..) | CallClosure(_) => { - return Err(PartialVMError::new(StatusCode::UNEXPECTED_VERIFIER_ERROR) - .with_message("closure operations not supported".to_owned())) - }, - - // List out the other options explicitly so there's a compile error if a new - // bytecode gets added. - Pop - | Ret - | Branch(_) - | BrTrue(_) - | BrFalse(_) - | LdU8(_) - | LdU16(_) - | LdU32(_) - | LdU64(_) - | LdU128(_) - | LdU256(_) - | LdConst(_) - | CastU8 - | CastU16 - | CastU32 - | CastU64 - | CastU128 - | CastU256 - | LdTrue - | LdFalse - | Call(_) - | Pack(_) - | Unpack(_) - | PackVariant(_) - | UnpackVariant(_) - | TestVariant(_) - | ReadRef - | WriteRef - | FreezeRef - | Add - | Sub - | Mul - | Mod - | Div - | BitOr - | BitAnd - | Xor - | Shl - | Shr - | Or - | And - | Not - | Eq - | Neq - | Lt - | Gt - | Le - | Ge - | CopyLoc(_) - | MoveLoc(_) - | StLoc(_) - | MutBorrowLoc(_) - | ImmBorrowLoc(_) - | MutBorrowField(_) - | ImmBorrowField(_) - | MutBorrowVariantField(_) - | ImmBorrowVariantField(_) - | MutBorrowGlobal(_) - | ImmBorrowGlobal(_) - | Exists(_) - | MoveTo(_) - | MoveFrom(_) - | Abort - | Nop => Ok(()), - }; - result.map_err(|err| { - err.append_message_with_separator(' ', format!("at offset {} ", offset)) - })? - } - Ok(()) - } - - /// Checks that phantom type parameters are only used in phantom position. - fn check_phantom_params( - &self, - ty: &SignatureToken, - is_phantom_pos: bool, - type_parameters: &[StructTypeParameter], - ) -> PartialVMResult<()> { - match ty { - SignatureToken::Vector(ty) => self.check_phantom_params(ty, false, type_parameters)?, - SignatureToken::StructInstantiation(idx, type_arguments) => { - let sh = self.resolver.struct_handle_at(*idx); - for (i, ty) in type_arguments.iter().enumerate() { - self.check_phantom_params( - ty, - sh.type_parameters[i].is_phantom, - type_parameters, - )?; - } - }, - SignatureToken::TypeParameter(idx) => { - if type_parameters[*idx as usize].is_phantom && !is_phantom_pos { - return Err(PartialVMError::new( - StatusCode::INVALID_PHANTOM_TYPE_PARAM_POSITION, - ) - .with_message( - "phantom type parameter cannot be used in non-phantom position".to_string(), - )); - } - }, - - SignatureToken::Function(..) => { - return Err(PartialVMError::new(StatusCode::UNEXPECTED_VERIFIER_ERROR) - .with_message("function types not supported".to_string())); - }, - - SignatureToken::Struct(_) - | SignatureToken::Reference(_) - | SignatureToken::MutableReference(_) - | SignatureToken::Bool - | SignatureToken::U8 - | SignatureToken::U16 - | SignatureToken::U32 - | SignatureToken::U64 - | SignatureToken::U128 - | SignatureToken::U256 - | SignatureToken::Address - | SignatureToken::Signer => {}, - } - Ok(()) - } - - /// Checks if the given type is well defined in the given context. - /// References are only permitted at the top level. - fn check_signature(&self, idx: SignatureIndex) -> PartialVMResult<()> { - for token in &self.resolver.signature_at(idx).0 { - match token { - SignatureToken::Reference(inner) | SignatureToken::MutableReference(inner) => { - self.check_signature_token(inner)? - }, - _ => self.check_signature_token(token)?, - } - } - Ok(()) - } - - /// Checks if the given types are well defined in the given context. - /// No references are permitted. - fn check_signature_tokens(&self, tys: &[SignatureToken]) -> PartialVMResult<()> { - for ty in tys { - self.check_signature_token(ty)? - } - Ok(()) - } - - /// Checks if the given type is well defined in the given context. - /// No references are permitted. - fn check_signature_token(&self, ty: &SignatureToken) -> PartialVMResult<()> { - use SignatureToken::*; - match ty { - U8 | U16 | U32 | U64 | U128 | U256 | Bool | Address | Signer | Struct(_) - | TypeParameter(_) => Ok(()), - Reference(_) | MutableReference(_) => { - // TODO: Prop tests expect us to NOT check the inner types. - // Revisit this once we rework prop tests. - Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) - .with_message("reference not allowed".to_string())) - }, - Function(..) => Err(PartialVMError::new(StatusCode::UNEXPECTED_VERIFIER_ERROR) - .with_message("function types not supported".to_string())), - Vector(ty) => self.check_signature_token(ty), - StructInstantiation(_, type_arguments) => self.check_signature_tokens(type_arguments), - } - } - - fn check_instantiation( - &self, - idx: SignatureIndex, - type_parameters: &[AbilitySet], - ) -> PartialVMResult<()> { - for ty in &self.resolver.signature_at(idx).0 { - self.check_type_instantiation(ty, type_parameters)? - } - Ok(()) - } - - fn check_type_instantiation( - &self, - s: &SignatureToken, - type_parameters: &[AbilitySet], - ) -> PartialVMResult<()> { - if self.resolver.version() >= VERSION_6 { - for ty in s.preorder_traversal() { - self.check_type_instantiation_(ty, type_parameters)? - } - Ok(()) - } else { - // preserve buggy, but harmless old behavior for backward compatibility - self.check_type_instantiation_(s, type_parameters) - } - } - - fn check_type_instantiation_( - &self, - s: &SignatureToken, - type_parameters: &[AbilitySet], - ) -> PartialVMResult<()> { - match s { - SignatureToken::StructInstantiation(idx, type_arguments) => { - // Check that the instantiation satisfies the `idx` struct's constraints - // Cannot be checked completely if we do not know the constraints of type parameters - // i.e. it cannot be checked unless we are inside some module member. The only case - // where that happens is when checking the signature pool itself - let sh = self.resolver.struct_handle_at(*idx); - self.check_generic_instance( - type_arguments, - sh.type_param_constraints(), - type_parameters, - ) - }, - SignatureToken::Function(..) => { - Err(PartialVMError::new(StatusCode::UNEXPECTED_VERIFIER_ERROR) - .with_message("function types not supported".to_string())) - }, - SignatureToken::Reference(_) - | SignatureToken::MutableReference(_) - | SignatureToken::Vector(_) - | SignatureToken::TypeParameter(_) - | SignatureToken::Struct(_) - | SignatureToken::Bool - | SignatureToken::U8 - | SignatureToken::U16 - | SignatureToken::U32 - | SignatureToken::U64 - | SignatureToken::U128 - | SignatureToken::U256 - | SignatureToken::Address - | SignatureToken::Signer => Ok(()), - } - } - - // Checks if the given types are well defined and satisfy the constraints in the given context. - fn check_generic_instance( - &self, - type_arguments: &[SignatureToken], - constraints: impl ExactSizeIterator, - global_abilities: &[AbilitySet], - ) -> PartialVMResult<()> { - if type_arguments.len() != constraints.len() { - return Err( - PartialVMError::new(StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH).with_message( - format!( - "expected {} type argument(s), got {}", - constraints.len(), - type_arguments.len() - ), - ), - ); - } - - for (constraint, ty) in constraints.into_iter().zip(type_arguments) { - let given = self.resolver.abilities(ty, global_abilities)?; - if !constraint.is_subset(given) { - return Err(PartialVMError::new(StatusCode::CONSTRAINT_NOT_SATISFIED) - .with_message(format!( - "expected type with abilities {:?} got type actual {:?} with incompatible \ - abilities {:?}", - constraint, ty, given - ))); - } - } - Ok(()) - } -} diff --git a/third_party/move/move-bytecode-verifier/src/signature_v2.rs b/third_party/move/move-bytecode-verifier/src/signature_v2.rs index 56e24b07007..f5f1700549c 100644 --- a/third_party/move/move-bytecode-verifier/src/signature_v2.rs +++ b/third_party/move/move-bytecode-verifier/src/signature_v2.rs @@ -110,148 +110,143 @@ impl BitsetTypeParameterConstraints { } } -/// Checks if the given type is well formed and has the required abilities. -/// -/// This function does NOT require the context (type parameter abilities) to be specified. -/// Instead, it will construct a minimal set of ability constraints each type parameter needs to satisfy, -/// which the caller can then verify in individual contexts. -/// This allows us to cache the results in the extreme case where a signature is being -/// referenced many many times. -/// -/// Time Complexity: `O(size_of_type * num_of_abilities * log(num_of_ty_params))`. -/// Can be treated as `O(size_of_type)` if there are only a handful of abilities and type params. -fn check_ty( - struct_handles: &[StructHandle], - ty: &SignatureToken, - allow_ref: bool, - required_abilities: AbilitySet, - param_constraints: &mut BitsetTypeParameterConstraints, -) -> PartialVMResult<()> { - use SignatureToken::*; - - let assert_abilities = |abilities: AbilitySet, required: AbilitySet| -> PartialVMResult<()> { - if !required.is_subset(abilities) { - Err( - PartialVMError::new(StatusCode::CONSTRAINT_NOT_SATISFIED).with_message(format!( +impl<'a, const N: usize> SignatureChecker<'a, N> { + /// Checks if the given type is well formed and has the required abilities. + /// + /// This function does NOT require the context (type parameter abilities) to be specified. + /// Instead, it will construct a minimal set of ability constraints each type parameter needs to satisfy, + /// which the caller can then verify in individual contexts. + /// This allows us to cache the results in the extreme case where a signature is being + /// referenced many many times. + /// + /// Time Complexity: `O(size_of_type * num_of_abilities * log(num_of_ty_params))`. + /// Can be treated as `O(size_of_type)` if there are only a handful of abilities and type params. + fn check_ty( + &self, + ty: &SignatureToken, + allow_ref: bool, + required_abilities: AbilitySet, + param_constraints: &mut BitsetTypeParameterConstraints, + ) -> PartialVMResult<()> { + use SignatureToken::*; + + let assert_abilities = + |abilities: AbilitySet, required: AbilitySet| -> PartialVMResult<()> { + if !required.is_subset(abilities) { + Err( + PartialVMError::new(StatusCode::CONSTRAINT_NOT_SATISFIED).with_message( + format!( "expected type with abilities {:?} got type actual {:?} with incompatible \ abilities {:?}", required, ty, abilities - )), - ) - } else { - Ok(()) - } - }; - - match ty { - TypeParameter(param_idx) => param_constraints.insert(*param_idx, required_abilities), - U8 | U16 | U32 | U64 | U128 | U256 | Bool | Address => { - assert_abilities(AbilitySet::PRIMITIVES, required_abilities)?; - }, - Signer => { - assert_abilities(AbilitySet::SIGNER, required_abilities)?; - }, - Reference(ty) | MutableReference(ty) => { - if allow_ref { - assert_abilities(AbilitySet::REFERENCES, required_abilities)?; - check_ty( - struct_handles, - ty, - false, - AbilitySet::EMPTY, - param_constraints, - )?; - } else { - return Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) - .with_message("reference not allowed".to_string())); - } - }, - Vector(ty) => { - assert_abilities(AbilitySet::VECTOR, required_abilities)?; - check_ty( - struct_handles, - ty, - false, - required_abilities.requires(), - param_constraints, - )?; - }, - Function(_, _, abilities) => { - assert_abilities(*abilities, required_abilities)?; - // Note we do not need to check abilities of argument or result types, - // they do not matter for the `required_abilities`. - }, - Struct(sh_idx) => { - let handle = &struct_handles[sh_idx.0 as usize]; - assert_abilities(handle.abilities, required_abilities)?; - }, - StructInstantiation(sh_idx, ty_args) => { - let handle = &struct_handles[sh_idx.0 as usize]; - - assert_abilities(handle.abilities, required_abilities)?; + ), + ), + ) + } else { + Ok(()) + } + }; - // TODO: is this needed? - if handle.type_parameters.len() != ty_args.len() { - return Err( - PartialVMError::new(StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH) - .with_message(format!( - "expected {} type argument(s), got {}", - handle.type_parameters.len(), - ty_args.len() - )), - ); - } - for (ty_param, ty_arg) in handle.type_parameters.iter().zip(ty_args.iter()) { - let required_abilities = if ty_param.is_phantom { - ty_param.constraints + match ty { + TypeParameter(param_idx) => param_constraints.insert(*param_idx, required_abilities), + U8 | U16 | U32 | U64 | U128 | U256 | I8 | I16 | I32 | I64 | I128 | I256 | Bool + | Address => { + assert_abilities(AbilitySet::PRIMITIVES, required_abilities)?; + }, + Signer => { + assert_abilities(AbilitySet::SIGNER, required_abilities)?; + }, + Reference(ty) | MutableReference(ty) => { + if allow_ref { + assert_abilities(AbilitySet::REFERENCES, required_abilities)?; + self.check_ty(ty, false, AbilitySet::EMPTY, param_constraints)?; } else { - ty_param.constraints.union(required_abilities.requires()) - }; + return Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) + .with_message("reference not allowed".to_string())); + } + }, + Vector(ty) => { + assert_abilities(AbilitySet::VECTOR, required_abilities)?; + self.check_ty(ty, false, required_abilities.requires(), param_constraints)?; + }, + Function(params, results, abilities) => { + assert_abilities(*abilities, required_abilities)?; + if self.sig_checker_v2_fix_function_signatures { + for ty in params.iter().chain(results) { + self.check_ty( + ty, + // Immediate params and returns can be references. + true, + // Note we do not need to check abilities of argument or result types, + // they do not matter for the `required_abilities`. + AbilitySet::EMPTY, + param_constraints, + )? + } + } + }, + Struct(sh_idx) => { + let struct_handles = self.resolver.struct_handles(); + let handle = &struct_handles[sh_idx.0 as usize]; + assert_abilities(handle.abilities, required_abilities)?; + }, + StructInstantiation(sh_idx, ty_args) => { + let struct_handles = self.resolver.struct_handles(); + let handle = &struct_handles[sh_idx.0 as usize]; - check_ty( - struct_handles, - ty_arg, - false, - required_abilities, - param_constraints, - )?; - } - }, - } + assert_abilities(handle.abilities, required_abilities)?; - Ok(()) -} + // TODO: is this needed? + if handle.type_parameters.len() != ty_args.len() { + return Err( + PartialVMError::new(StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH) + .with_message(format!( + "expected {} type argument(s), got {}", + handle.type_parameters.len(), + ty_args.len() + )), + ); + } + for (ty_param, ty_arg) in handle.type_parameters.iter().zip(ty_args.iter()) { + let required_abilities = if ty_param.is_phantom { + ty_param.constraints + } else { + ty_param.constraints.union(required_abilities.requires()) + }; + + self.check_ty(ty_arg, false, required_abilities, param_constraints)?; + } + }, + } -/// Checks if the given type is well formed and has the required abilities within a context. -/// -/// Calls `check_ty` internally. -/// -/// Time complexity: same as `check_ty`. -fn check_ty_in_context( - struct_handles: &[StructHandle], - ability_context: &BitsetTypeParameterConstraints, - ty: &SignatureToken, - allow_ref: bool, - required_abilities: AbilitySet, -) -> PartialVMResult<()> { - let mut param_constraints = BitsetTypeParameterConstraints::new(); - - check_ty( - struct_handles, - ty, - allow_ref, - required_abilities, - &mut param_constraints, - )?; + Ok(()) + } - param_constraints - .check_in_context(ability_context) - .map_err(|err| { - err.with_message(format!( - "expected type with abilities {:?} got type {:?} within context {:?}", - required_abilities, ty, ability_context, - )) - }) + /// Checks if the given type is well formed and has the required abilities within a context. + /// + /// Calls `check_ty` internally. + /// + /// Time complexity: same as `check_ty`. + fn check_ty_in_context( + &self, + ability_context: &BitsetTypeParameterConstraints, + ty: &SignatureToken, + allow_ref: bool, + required_abilities: AbilitySet, + ) -> PartialVMResult<()> { + let mut param_constraints = BitsetTypeParameterConstraints::new(); + + self.check_ty(ty, allow_ref, required_abilities, &mut param_constraints)?; + + param_constraints + .check_in_context(ability_context) + .map_err(|err| { + err.with_message(format!( + "expected type with abilities {:?} got type {:?} within context {:?}", + required_abilities, ty, ability_context, + )) + }) + } } /// Helper function to check if a type contains phantom type parameters in non-phantom positions. @@ -296,7 +291,7 @@ fn check_phantom_params( }, Struct(_) | Reference(_) | MutableReference(_) | Bool | U8 | U16 | U32 | U64 | U128 - | U256 | Address | Signer => {}, + | U256 | I8 | I16 | I32 | I64 | I128 | I256 | Address | Signer => {}, } Ok(()) @@ -304,6 +299,8 @@ fn check_phantom_params( struct SignatureChecker<'a, const N: usize> { resolver: BinaryIndexedView<'a>, + // If enabled, recurses into function signature to check type signatures. + sig_checker_v2_fix_function_signatures: bool, // Here the arena is used as a scoped interner, allowing us to store references in the // caches below. @@ -346,10 +343,12 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { fn new( constraints: &'a Arena>, resolver: BinaryIndexedView<'a>, + sig_checker_v2_fix_function_signatures: bool, ) -> Self { Self { resolver, constraints, + sig_checker_v2_fix_function_signatures, ty_results: RefCell::new(BTreeMap::new()), sig_results: RefCell::new(BTreeMap::new()), @@ -373,6 +372,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { sig_idx: SignatureIndex, ty_idx: usize, required_abilities: AbilitySet, + allow_ref: bool, ) -> PartialVMResult<&'a BitsetTypeParameterConstraints> { let r = match self .ty_results @@ -384,17 +384,11 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let mut param_constraints = BitsetTypeParameterConstraints::new(); let sig = self.resolver.signature_at(sig_idx); let ty = &sig.0[ty_idx]; - check_ty( - self.resolver.struct_handles(), - ty, - true, - required_abilities, - &mut param_constraints, - ) - .map_err(|err| { - err.append_message_with_separator(' ', format!("at type {}", ty_idx)) - .at_index(IndexKind::Signature, sig_idx.0) - })?; + self.check_ty(ty, allow_ref, required_abilities, &mut param_constraints) + .map_err(|err| { + err.append_message_with_separator(' ', format!("at type {}", ty_idx)) + .at_index(IndexKind::Signature, sig_idx.0) + })?; let r = self.constraints.alloc(param_constraints); @@ -415,6 +409,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { fn verify_signature_contextless( &self, sig_idx: SignatureIndex, + allow_ref: bool, ) -> PartialVMResult<&'a BitsetTypeParameterConstraints> { let r = match self.sig_results.borrow_mut().entry(sig_idx) { btree_map::Entry::Occupied(entry) => *entry.into_mut(), @@ -426,6 +421,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { sig_idx, ty_idx, AbilitySet::EMPTY, + allow_ref, )?) } @@ -439,7 +435,11 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { /// Verifies that all signatures in the signature pool are well-formed, in a context-less fashion. fn verify_signature_pool_contextless(&self) -> PartialVMResult<()> { for sig_idx in 0..self.resolver.signatures().len() { - self.verify_signature_contextless(SignatureIndex(sig_idx as u16))?; + // Here we check signatures, which can be locals for instance, so references should be + // allowed. Note that this function will cache results, which means that the signature + // which is not supposed reference is cached with references allowed. One must make + // sure any later checks do not go through cache, but explicitly reject references. + self.verify_signature_contextless(SignatureIndex(sig_idx as u16), true)?; } Ok(()) } @@ -451,8 +451,9 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { &self, ability_context: &BitsetTypeParameterConstraints, sig_idx: SignatureIndex, + allow_ref: bool, ) -> PartialVMResult<()> { - let constraints = self.verify_signature_contextless(sig_idx)?; + let constraints = self.verify_signature_contextless(sig_idx, allow_ref)?; constraints.check_in_context(ability_context)?; Ok(()) } @@ -499,6 +500,10 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let mut constraints = BitsetTypeParameterConstraints::new(); for (ty_idx, ty) in ty_args.iter().enumerate() { + // IMPORTANT: + // This check should be kept here at all times, because it is possible + // that the signature is already cached when allowing references, so the + // below traversal will not complain about references... if ty.is_reference() { return Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) .with_message("reference not allowed".to_string()) @@ -509,6 +514,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { ty_args_idx, ty_idx, func_handle.type_parameters[ty_idx], + false, )?) } @@ -643,11 +649,6 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let mut constraints = BitsetTypeParameterConstraints::new(); for (ty_idx, ty) in ty_args.iter().enumerate() { - if ty.is_reference() { - return Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) - .with_message("reference not allowed".to_string())); - } - let arg_abilities = if struct_handle.type_parameters[ty_idx].is_phantom { struct_handle.type_parameters[ty_idx].constraints } else { @@ -656,10 +657,20 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { .union(required_abilities.requires()) }; + // IMPORTANT: + // This check should be kept here at all times, because it is possible + // that the signature is already cached when allowing references, so the + // below traversal will not complain about references... + if ty.is_reference() { + return Err(PartialVMError::new(StatusCode::INVALID_SIGNATURE_TOKEN) + .with_message("reference not allowed".to_string())); + } + constraints.merge(self.verify_type_in_signature_contextless( ty_args_idx, ty_idx, arg_abilities, + false, )?); } Ok(constraints) @@ -780,8 +791,9 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { /// Time complexity: `O(total_size_of_all_types)` if not cached. fn verify_function_handle(&self, fh: &FunctionHandle) -> PartialVMResult<()> { let ability_context = BitsetTypeParameterConstraints::from(fh.type_parameters.as_slice()); - self.verify_signature_in_context(&ability_context, fh.parameters)?; - self.verify_signature_in_context(&ability_context, fh.return_)?; + // Reference are allowed to be in parameter and return signatures. + self.verify_signature_in_context(&ability_context, fh.parameters, true)?; + self.verify_signature_in_context(&ability_context, fh.return_, true)?; Ok(()) } @@ -808,7 +820,8 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let ability_context = BitsetTypeParameterConstraints::from(ability_context); - self.verify_signature_in_context(&ability_context, code.locals) + // Locals can be references, so we pass `true` here. + self.verify_signature_in_context(&ability_context, code.locals, true) .map_err(|err| err.at_index(IndexKind::Signature, code.locals.0))?; // Local caches to avoid re-verifying identical instantiations within the same context. @@ -923,13 +936,18 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { )))); } + // IMPORTANT: + // This check should be kept here at all times, because it is possible + // that the signature is already cached when allowing references, so the + // below traversal will not complain about references... if ty_args[0].is_reference() { return map_err(Err(PartialVMError::new( StatusCode::INVALID_SIGNATURE_TOKEN, ) .with_message("reference not allowed".to_string()))); } - map_err(self.verify_signature_in_context(&ability_context, *idx))?; + + map_err(self.verify_signature_in_context(&ability_context, *idx, false))?; entry.insert(()); } @@ -955,6 +973,18 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { | CastU64 | CastU128 | CastU256 + | LdI8(_) + | LdI16(_) + | LdI32(_) + | LdI64(_) + | LdI128(_) + | LdI256(_) + | CastI8 + | CastI16 + | CastI32 + | CastI64 + | CastI128 + | CastI256 | LdTrue | LdFalse | Call(_) @@ -972,6 +1002,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { | Mul | Mod | Div + | Negate | BitOr | BitAnd | Xor @@ -1052,14 +1083,14 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { match &struct_def.field_information { StructFieldInformation::Native => Ok(()), StructFieldInformation::Declared(fields) => self.verify_fields_of_struct( - &struct_handle, + struct_handle, &context, required_abilities_conditional, &context_all_abilities, fields.iter(), ), StructFieldInformation::DeclaredVariants(variants) => self.verify_fields_of_struct( - &struct_handle, + struct_handle, &context, required_abilities_conditional, &context_all_abilities, @@ -1070,7 +1101,7 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { fn verify_fields_of_struct<'l>( &self, - struct_handle: &&StructHandle, + struct_handle: &StructHandle, context: &BitsetTypeParameterConstraints<{ N }>, required_abilities_conditional: AbilitySet, context_all_abilities: &BitsetTypeParameterConstraints<{ N }>, @@ -1080,17 +1111,10 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { let field_ty = &field_def.signature.0; // Check if the field type itself is well-formed. - check_ty_in_context( - self.resolver.struct_handles(), - context, - field_ty, - false, - AbilitySet::EMPTY, - )?; + self.check_ty_in_context(context, field_ty, false, AbilitySet::EMPTY)?; // Check if the field type satisfies the conditional ability requirements. - check_ty_in_context( - self.resolver.struct_handles(), + self.check_ty_in_context( context_all_abilities, field_ty, false, @@ -1118,9 +1142,16 @@ impl<'a, const N: usize> SignatureChecker<'a, N> { } } -fn verify_module_impl(module: &CompiledModule) -> PartialVMResult<()> { +fn verify_module_impl( + config: &VerifierConfig, + module: &CompiledModule, +) -> PartialVMResult<()> { let arena = Arena::>::new(); - let checker = SignatureChecker::new(&arena, BinaryIndexedView::Module(module)); + let checker = SignatureChecker::new( + &arena, + BinaryIndexedView::Module(module), + config.sig_checker_v2_fix_function_signatures, + ); // Check if all signatures & instantiations are well-formed without any specific contexts. // This is only needed if we want to keep the binary format super clean. @@ -1138,9 +1169,16 @@ fn verify_module_impl(module: &CompiledModule) -> PartialVMResul Ok(()) } -fn verify_script_impl(script: &CompiledScript) -> PartialVMResult<()> { +fn verify_script_impl( + config: &VerifierConfig, + script: &CompiledScript, +) -> PartialVMResult<()> { let arena = Arena::>::new(); - let checker = SignatureChecker::new(&arena, BinaryIndexedView::Script(script)); + let checker = SignatureChecker::new( + &arena, + BinaryIndexedView::Script(script), + config.sig_checker_v2_fix_function_signatures, + ); // Check if all signatures & instantiations are well-formed without any specific contexts. // This is only needed if we want to keep the binary format super clean. @@ -1151,6 +1189,8 @@ fn verify_script_impl(script: &CompiledScript) -> PartialVMResul checker.verify_signature_in_context( &BitsetTypeParameterConstraints::from(script.type_parameters.as_slice()), script.parameters, + // Script parameters can be signer references. + true, )?; checker.verify_code(&script.type_parameters, &script.code)?; @@ -1209,15 +1249,15 @@ fn max_num_of_ty_params_or_args(resolver: BinaryIndexedView) -> usize { n } -pub fn verify_module(module: &CompiledModule) -> VMResult<()> { +pub fn verify_module(config: &VerifierConfig, module: &CompiledModule) -> VMResult<()> { let max_num = max_num_of_ty_params_or_args(BinaryIndexedView::Module(module)); let res = if max_num <= NUM_PARAMS_PER_WORD { - verify_module_impl::<1>(module) + verify_module_impl::<1>(config, module) } else if max_num <= NUM_PARAMS_PER_WORD * 2 { - verify_module_impl::<2>(module) + verify_module_impl::<2>(config, module) } else if max_num <= NUM_PARAMS_PER_WORD * 16 { - verify_module_impl::<16>(module) + verify_module_impl::<16>(config, module) } else { return Err( PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) @@ -1236,11 +1276,11 @@ pub fn verify_script(config: &VerifierConfig, script: &CompiledScript) -> VMResu } let res = if max_num <= NUM_PARAMS_PER_WORD { - verify_script_impl::<1>(script) + verify_script_impl::<1>(config, script) } else if max_num <= NUM_PARAMS_PER_WORD * 2 { - verify_script_impl::<2>(script) + verify_script_impl::<2>(config, script) } else if max_num <= NUM_PARAMS_PER_WORD * 16 { - verify_script_impl::<16>(script) + verify_script_impl::<16>(config, script) } else { return Err( PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) diff --git a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs index 4a40ecb3e52..19af4c9120d 100644 --- a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs @@ -59,6 +59,9 @@ impl<'a> StackUsageVerifier<'a> { let (num_pops, num_pushes) = self.instruction_effect(&code[i as usize])?; if let Some(new_pushes) = u64::checked_add(overall_push, num_pushes) { overall_push = new_pushes + } else { + return Err(PartialVMError::new(StatusCode::VALUE_STACK_PUSH_OVERFLOW) + .at_code_offset(self.current_function(), block_start)); }; // Check that the accumulated pushes does not exceed a pre-defined max size @@ -129,6 +132,12 @@ impl<'a> StackUsageVerifier<'a> { | Bytecode::LdU64(_) | Bytecode::LdU128(_) | Bytecode::LdU256(_) + | Bytecode::LdI8(_) + | Bytecode::LdI16(_) + | Bytecode::LdI32(_) + | Bytecode::LdI64(_) + | Bytecode::LdI128(_) + | Bytecode::LdI256(_) | Bytecode::LdTrue | Bytecode::LdFalse | Bytecode::LdConst(_) @@ -139,6 +148,7 @@ impl<'a> StackUsageVerifier<'a> { // Instructions that pop and push once Bytecode::Not + | Bytecode::Negate | Bytecode::FreezeRef | Bytecode::ReadRef | Bytecode::Exists(_) @@ -165,6 +175,12 @@ impl<'a> StackUsageVerifier<'a> { | Bytecode::CastU64 | Bytecode::CastU128 | Bytecode::CastU256 + | Bytecode::CastI8 + | Bytecode::CastI16 + | Bytecode::CastI32 + | Bytecode::CastI64 + | Bytecode::CastI128 + | Bytecode::CastI256 | Bytecode::VecLen(_) | Bytecode::VecPopBack(_) => (1, 1), @@ -228,42 +244,27 @@ impl<'a> StackUsageVerifier<'a> { (arg_count, return_count) }, - // ClosEval pops the number of arguments and pushes the results of the given function - // type + // `CallClosure` pops the closure and then the number of arguments and + // pushes the results of the given function type Bytecode::CallClosure(idx) => { if let Some(SignatureToken::Function(args, result, _)) = self.resolver.signature_at(*idx).0.first() { ((1 + args.len()) as u64, result.len() as u64) } else { - // We don't know what it will pop/push, but the signature checker + // We don't know what it will pop/push, but the signature checker v2 // ensures we never reach this (0, 0) } }, - // ClosPack pops the captured arguments and returns 1 value - Bytecode::PackClosure(idx, mask) => { - let function_handle = self.resolver.function_handle_at(*idx); - // TODO(#15664): use `captured_count` for efficiency - let arg_count = mask - .extract( - &self.resolver.signature_at(function_handle.parameters).0, - true, - ) - .len() as u64; + // `PackClosure` pops the captured arguments and returns 1 value + Bytecode::PackClosure(_, mask) => { + let arg_count = mask.captured_count() as u64; (arg_count, 1) }, - Bytecode::PackClosureGeneric(idx, mask) => { - let func_inst = self.resolver.function_instantiation_at(*idx); - let function_handle = self.resolver.function_handle_at(func_inst.handle); - // TODO(#15664): use `captured_count` for efficiency - let arg_count = mask - .extract( - &self.resolver.signature_at(function_handle.parameters).0, - true, - ) - .len() as u64; + Bytecode::PackClosureGeneric(_, mask) => { + let arg_count = mask.captured_count() as u64; (arg_count, 1) }, diff --git a/third_party/move/move-bytecode-verifier/src/struct_defs.rs b/third_party/move/move-bytecode-verifier/src/struct_defs.rs index 3dcc81051ad..f57fa970327 100644 --- a/third_party/move/move-bytecode-verifier/src/struct_defs.rs +++ b/third_party/move/move-bytecode-verifier/src/struct_defs.rs @@ -122,6 +122,12 @@ impl<'a> StructDefGraphBuilder<'a> { | T::U64 | T::U128 | T::U256 + | T::I8 + | T::I16 + | T::I32 + | T::I64 + | T::I128 + | T::I256 | T::Address | T::Signer | T::TypeParameter(_) => (), diff --git a/third_party/move/move-bytecode-verifier/src/type_safety.rs b/third_party/move/move-bytecode-verifier/src/type_safety.rs index 60beb13850d..5aafc0d42b0 100644 --- a/third_party/move/move-bytecode-verifier/src/type_safety.rs +++ b/third_party/move/move-bytecode-verifier/src/type_safety.rs @@ -361,6 +361,8 @@ fn clos_pack( }; // Check the captured arguments on the stack let param_sgn = verifier.resolver.signature_at(func_handle.parameters); + // Instruction consistency check has verified that the number of captured arguments + // is less than or equal to the number of parameters of the function. let captured_param_tys = mask.extract(¶m_sgn.0, true); for ty in captured_param_tys.into_iter().rev() { let arg = safe_unwrap!(verifier.stack.pop()); @@ -784,6 +786,30 @@ fn verify_instr( verifier.push(meter, ST::U256)?; }, + Bytecode::LdI8(_) => { + verifier.push(meter, ST::I8)?; + }, + + Bytecode::LdI16(_) => { + verifier.push(meter, ST::I16)?; + }, + + Bytecode::LdI32(_) => { + verifier.push(meter, ST::I32)?; + }, + + Bytecode::LdI64(_) => { + verifier.push(meter, ST::I64)?; + }, + + Bytecode::LdI128(_) => { + verifier.push(meter, ST::I128)?; + }, + + Bytecode::LdI256(_) => { + verifier.push(meter, ST::I256)?; + }, + Bytecode::LdConst(idx) => { let signature = verifier.resolver.constant_at(*idx).type_.clone(); verifier.push(meter, signature)?; @@ -1005,14 +1031,7 @@ fn verify_instr( verifier.push(meter, ST::U128)?; }, - Bytecode::Add - | Bytecode::Sub - | Bytecode::Mul - | Bytecode::Mod - | Bytecode::Div - | Bytecode::BitOr - | Bytecode::BitAnd - | Bytecode::Xor => { + Bytecode::Add | Bytecode::Sub | Bytecode::Mul | Bytecode::Mod | Bytecode::Div => { let operand1 = safe_unwrap!(verifier.stack.pop()); let operand2 = safe_unwrap!(verifier.stack.pop()); if operand1.is_integer() && operand1 == operand2 { @@ -1022,10 +1041,29 @@ fn verify_instr( } }, + Bytecode::BitOr | Bytecode::BitAnd | Bytecode::Xor => { + let operand1 = safe_unwrap!(verifier.stack.pop()); + let operand2 = safe_unwrap!(verifier.stack.pop()); + if operand1.is_unsigned_integer() && operand1 == operand2 { + verifier.push(meter, operand1)?; + } else { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + }, + + Bytecode::Negate => { + let operand = safe_unwrap!(verifier.stack.pop()); + if operand.is_signed_integer() { + verifier.push(meter, operand)?; + } else { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + }, + Bytecode::Shl | Bytecode::Shr => { let operand1 = safe_unwrap!(verifier.stack.pop()); let operand2 = safe_unwrap!(verifier.stack.pop()); - if operand2.is_integer() && operand1 == ST::U8 { + if operand2.is_unsigned_integer() && operand1 == ST::U8 { verifier.push(meter, operand2)?; } else { return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); @@ -1240,6 +1278,49 @@ fn verify_instr( } verifier.push(meter, ST::U256)?; }, + + Bytecode::CastI8 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I8)?; + }, + Bytecode::CastI16 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I16)?; + }, + Bytecode::CastI32 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I32)?; + }, + Bytecode::CastI64 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I64)?; + }, + Bytecode::CastI128 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I128)?; + }, + Bytecode::CastI256 => { + let operand = safe_unwrap!(verifier.stack.pop()); + if !operand.is_integer() { + return Err(verifier.error(StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR, offset)); + } + verifier.push(meter, ST::I256)?; + }, }; Ok(()) } @@ -1274,6 +1355,12 @@ fn instantiate(token: &SignatureToken, subst: &Signature) -> SignatureToken { U64 => U64, U128 => U128, U256 => U256, + I8 => I8, + I16 => I16, + I32 => I32, + I64 => I64, + I128 => I128, + I256 => I256, Address => Address, Signer => Signer, Vector(ty) => Vector(Box::new(instantiate(ty, subst))), diff --git a/third_party/move/move-bytecode-verifier/src/verifier.rs b/third_party/move/move-bytecode-verifier/src/verifier.rs index d358a73537a..cb1efd45341 100644 --- a/third_party/move/move-bytecode-verifier/src/verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/verifier.rs @@ -4,12 +4,19 @@ //! This module contains the public APIs supported by the bytecode verifier. use crate::{ - ability_field_requirements, check_duplication::DuplicationChecker, - code_unit_verifier::CodeUnitVerifier, constants, features::FeatureVerifier, friends, - instantiation_loops::InstantiationLoopChecker, instruction_consistency::InstructionConsistency, - limits::LimitsVerifier, script_signature, - script_signature::no_additional_script_signature_checks, signature::SignatureChecker, - signature_v2, struct_defs::RecursiveStructDefChecker, + //ability_field_requirements, + check_duplication::DuplicationChecker, + code_unit_verifier::CodeUnitVerifier, + constants, + features::FeatureVerifier, + friends, + instantiation_loops::InstantiationLoopChecker, + instruction_consistency::InstructionConsistency, + limits::LimitsVerifier, + script_signature, + script_signature::no_additional_script_signature_checks, + signature_v2, + struct_defs::RecursiveStructDefChecker, }; use move_binary_format::{ check_bounds::BoundsChecker, @@ -20,8 +27,14 @@ use move_core_types::{state::VMState, vm_status::StatusCode}; use serde::Serialize; use std::time::Instant; +/// Configuration for the bytecode verifier. +/// +/// Always add new fields to the end, as we rely on the hash or serialized bytes of config to +/// detect if it has changed (e.g., new feature flag was enabled). Also, do not delete existing +/// fields, or change the type of existing field. #[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct VerifierConfig { + pub scope: VerificationScope, pub max_loop_depth: Option, pub max_function_parameters: Option, pub max_generic_instantiation_length: Option, @@ -38,11 +51,28 @@ pub struct VerifierConfig { pub max_basic_blocks_in_script: Option, pub max_per_fun_meter_units: Option, pub max_per_mod_meter_units: Option, - pub use_signature_checker_v2: bool, + // signature checker v2 is enabled on mainnet and cannot be disabled + pub _use_signature_checker_v2: bool, pub sig_checker_v2_fix_script_ty_param_count: bool, pub enable_enum_types: bool, pub enable_resource_access_control: bool, pub enable_function_values: bool, + /// Maximum number of function return values. + pub max_function_return_values: Option, + /// Maximum depth of a type node. + pub max_type_depth: Option, + /// If enabled, signature checker V2 also checks parameter and return types in function + /// signatures. + pub sig_checker_v2_fix_function_signatures: bool, +} + +/// Scope of verification. +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum VerificationScope { + /// Do all verification + Everything, + /// The remaining variants are for testing and should never be used in production + Nothing, } /// Helper for a "canonical" verification of a module. @@ -102,8 +132,9 @@ pub fn verify_module_with_config_for_test_with_version( } pub fn verify_module_with_config(config: &VerifierConfig, module: &CompiledModule) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); - + if config.verify_nothing() { + return Ok(()); + } let prev_state = move_core_types::state::set_state(VMState::VERIFIER); let result = std::panic::catch_unwind(|| { // Always needs to run bound checker first as subsequent passes depend on it @@ -116,19 +147,12 @@ pub fn verify_module_with_config(config: &VerifierConfig, module: &CompiledModul LimitsVerifier::verify_module(config, module)?; DuplicationChecker::verify_module(module)?; - if config.use_signature_checker_v2 { - signature_v2::verify_module(module)?; - } else { - SignatureChecker::verify_module(module)?; - } + signature_v2::verify_module(config, module)?; InstructionConsistency::verify_module(module)?; constants::verify_module(module)?; friends::verify_module(module)?; - if !config.use_signature_checker_v2 { - // This has been merged into the new signature checker so no need to run it if that one is enabled. - ability_field_requirements::verify_module(module)?; - } + RecursiveStructDefChecker::verify_module(module)?; InstantiationLoopChecker::verify_module(module)?; CodeUnitVerifier::verify_module(config, module)?; @@ -163,8 +187,9 @@ pub fn verify_script(script: &CompiledScript) -> VMResult<()> { } pub fn verify_script_with_config(config: &VerifierConfig, script: &CompiledScript) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); - + if config.verify_nothing() { + return Ok(()); + } let prev_state = move_core_types::state::set_state(VMState::VERIFIER); let result = std::panic::catch_unwind(|| { // Always needs to run bound checker first as subsequent passes depend on it @@ -177,11 +202,7 @@ pub fn verify_script_with_config(config: &VerifierConfig, script: &CompiledScrip LimitsVerifier::verify_script(config, script)?; DuplicationChecker::verify_script(script)?; - if config.use_signature_checker_v2 { - signature_v2::verify_script(config, script)?; - } else { - SignatureChecker::verify_script(script)?; - } + signature_v2::verify_script(config, script)?; InstructionConsistency::verify_script(script)?; constants::verify_script(script)?; @@ -203,6 +224,7 @@ pub fn verify_script_with_config(config: &VerifierConfig, script: &CompiledScrip impl Default for VerifierConfig { fn default() -> Self { Self { + scope: VerificationScope::Everything, max_loop_depth: None, max_function_parameters: None, max_generic_instantiation_length: None, @@ -235,13 +257,17 @@ impl Default for VerifierConfig { max_per_fun_meter_units: None, max_per_mod_meter_units: None, - use_signature_checker_v2: true, + _use_signature_checker_v2: true, sig_checker_v2_fix_script_ty_param_count: true, + sig_checker_v2_fix_function_signatures: true, enable_enum_types: true, enable_resource_access_control: true, enable_function_values: true, + + max_function_return_values: None, + max_type_depth: None, } } } @@ -259,13 +285,14 @@ impl VerifierConfig { /// An approximation of what config is used in production. pub fn production() -> Self { Self { + scope: VerificationScope::Everything, max_loop_depth: Some(5), max_generic_instantiation_length: Some(32), max_function_parameters: Some(128), max_basic_blocks: Some(1024), max_basic_blocks_in_script: Some(1024), max_value_stack_size: 1024, - max_type_nodes: Some(256), + max_type_nodes: Some(128), max_push_size: Some(10000), max_struct_definitions: Some(200), max_fields_in_struct: Some(30), @@ -280,13 +307,26 @@ impl VerifierConfig { max_per_fun_meter_units: Some(1000 * 8000), max_per_mod_meter_units: Some(1000 * 8000), - use_signature_checker_v2: true, - + _use_signature_checker_v2: true, sig_checker_v2_fix_script_ty_param_count: true, + sig_checker_v2_fix_function_signatures: true, enable_enum_types: true, enable_resource_access_control: true, enable_function_values: true, + + max_function_return_values: Some(128), + max_type_depth: Some(20), } } + + /// Set verification scope + pub fn set_scope(self, scope: VerificationScope) -> Self { + Self { scope, ..self } + } + + /// Returns true if verification is disabled. + pub fn verify_nothing(&self) -> bool { + matches!(self.scope, VerificationScope::Nothing) + } } diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/Cargo.toml b/third_party/move/move-bytecode-verifier/transactional-tests/Cargo.toml index c65d4f675b6..4085fd74890 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/transactional-tests/Cargo.toml @@ -3,12 +3,15 @@ name = "bytecode-verifier-transactional-tests" version = "0.1.0" authors = ["Diem Association "] publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dev-dependencies] datatest-stable = { workspace = true } +libtest-mimic = { workspace = true } move-transactional-test-runner = { workspace = true } +once_cell = { workspace = true } +walkdir = { workspace = true } [[test]] name = "tests" diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.exp index 2e1d987e606..c7565994945 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.exp @@ -1,6 +1,6 @@ processed 8 tasks - -task 1 'publish'. lines 11-19: +task 0 lines 1-9: publish [module 0x1.m1_good {] +task 1 lines 11-19: publish [module 0x1.m1_bad {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1_bad'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -8,8 +8,9 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 4 'publish'. lines 41-53: +task 2 lines 21-27: publish [module 0x1.m2 {] +task 3 lines 29-39: publish [module 0x1.m3 {] +task 4 lines 41-53: publish [module 0x1.m4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -17,8 +18,8 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 2)], offsets: [], } - -task 6 'publish'. lines 67-77: +task 5 lines 55-65: publish [module 0x1.m5_good {] +task 6 lines 67-77: publish [module 0x1.m5_bad {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5_bad'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -26,8 +27,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 7 'publish'. lines 79-92: +task 7 lines 79-92: publish [module 0x1.m6 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m6'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.v2_exp deleted file mode 100644 index 2e1d987e606..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/fields_conditional_abilities.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 8 tasks - -task 1 'publish'. lines 11-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1_bad'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::m1_bad, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 4 'publish'. lines 41-53: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::m4, - indices: [(StructDefinition, 2)], - offsets: [], -} - -task 6 'publish'. lines 67-77: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5_bad'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::m5_bad, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 7 'publish'. lines 79-92: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m6'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::m6, - indices: [(StructDefinition, 2)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.exp index ecf403fb87a..bec38b09ccd 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 9-17: +task 0 lines 1-7: publish [module 0x42.Test {] +task 1 lines 9-17: run [import 0x42.Test;] Error: Script execution failed with VMError: { major_status: CALL_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.v2_exp deleted file mode 100644 index ecf403fb87a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/procedure_args.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 9-17: -Error: Script execution failed with VMError: { - major_status: CALL_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp index 6cd67db3f64..05228191685 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-5: publish [module 0x42.Test {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/resource_has_resource_field.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp index 8fc6a9cda1f..d4ce0f4df3a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.v2_exp deleted file mode 100644 index 8fc6a9cda1f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x42::Test, - indices: [(StructDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.exp index 0d1108cb066..bf65309168b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-265: +task 0 lines 1-265: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: TOO_MANY_LOCALS, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.v2_exp deleted file mode 100644 index 0d1108cb066..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/128_params_and_128_locals.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-265: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: TOO_MANY_LOCALS, - sub_status: None, - location: undefined, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.exp index f5cf0a77943..2833be31da4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-264: +task 0 lines 1-264: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: TOO_MANY_LOCALS, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.v2_exp deleted file mode 100644 index f5cf0a77943..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/1_param_and_255_locals.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-264: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: TOO_MANY_LOCALS, - sub_status: None, - location: undefined, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.exp index cb05a36a19c..d353145f0ac 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'publish'. lines 1-263: +task 0 lines 1-263: publish [module 0x1.M {] Error: value (256) cannot exceed (255) diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.v2_exp deleted file mode 100644 index cb05a36a19c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_locals.v2_exp +++ /dev/null @@ -1,4 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-263: -Error: value (256) cannot exceed (255) diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.exp index b62ab7bb96f..bb35f5686bf 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.exp @@ -1,4 +1,3 @@ processed 1 task - -task 0 'publish'. lines 1-264: +task 0 lines 1-264: publish [module 0x1.M {] Error: value (256) cannot exceed (255) diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.v2_exp deleted file mode 100644 index b62ab7bb96f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/256_params.v2_exp +++ /dev/null @@ -1,4 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-264: -Error: value (256) cannot exceed (255) diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.exp index 6f873d8ae35..30bcef55db2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.v2_exp deleted file mode 100644 index 6f873d8ae35..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_few_type_actuals.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - sub_status: None, - location: undefined, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.exp index 6f873d8ae35..30bcef55db2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.v2_exp deleted file mode 100644 index 6f873d8ae35..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_bounds/too_many_type_actuals.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - sub_status: None, - location: undefined, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.exp index 5495d3b884e..29fe2d8b289 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-7: +task 0 lines 1-7: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: DUPLICATE_ELEMENT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.v2_exp deleted file mode 100644 index 5495d3b884e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_field_name.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-7: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: DUPLICATE_ELEMENT, - sub_status: None, - location: 0x1::M, - indices: [(FieldDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.exp index 86db5c83171..4117c04b370 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: DUPLICATE_ELEMENT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.v2_exp deleted file mode 100644 index 86db5c83171..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_function_name.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-6: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: DUPLICATE_ELEMENT, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.exp index cedea2736a3..7bc2d5ac250 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: DUPLICATE_ELEMENT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.v2_exp deleted file mode 100644 index cedea2736a3..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/duplicate_struct_name.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-6: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: DUPLICATE_ELEMENT, - sub_status: None, - location: 0x42::M, - indices: [(StructDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.exp index 1f49c06d237..478c3642b7e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0x1.EmptyStruct {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::EmptyStruct'. Got VMError: { major_status: ZERO_SIZED_STRUCT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.v2_exp deleted file mode 100644 index 1f49c06d237..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/empty_structs.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-6: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::EmptyStruct'. Got VMError: { - major_status: ZERO_SIZED_STRUCT, - sub_status: None, - location: 0x1::EmptyStruct, - indices: [(StructDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.exp index a0c4d8fa72c..ecd0f53fe00 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 5-10: +task 0 lines 1-3: publish [module 0x42.A {] +task 1 lines 5-10: publish [module 0x42.B {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::B'. Got VMError: { major_status: DUPLICATE_ELEMENT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.v2_exp deleted file mode 100644 index a0c4d8fa72c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/check_duplication/friend_decl_duplicated.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 5-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::B'. Got VMError: { - major_status: DUPLICATE_ELEMENT, - sub_status: None, - location: 0x42::B, - indices: [(ModuleHandle, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.exp index 8337459bd9a..3079f0b4b93 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-51: +task 0 lines 1-51: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.v2_exp deleted file mode 100644 index 8337459bd9a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_alias.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-51: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 16)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.exp index bfb97e05350..56840c096ad 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-39: +task 0 lines 1-39: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.v2_exp deleted file mode 100644 index bfb97e05350..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/block_traversal_order_hot_potato.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-39: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.exp index 6cd67db3f64..45269d92f44 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-21: run [// check valid breaks in control flow check] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_nested.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.exp index 6cd67db3f64..d7a3d177163 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: run [// simple breaks for control flow check] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_simple.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.exp index 6cd67db3f64..b462f74b397 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: run [// simple breaks for control flow check] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/break_unreachable.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.exp index 5d92c423f3f..98827a49ca0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [// TODO: we might need to modify this test if we enable unreachable code] +task 1 lines 14-22: run [import 0x1.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.exp index 6cd67db3f64..351f5233cf1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: run [// TODO: should the verifier allow dead code?] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/dead_return_local.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.exp index 7f57ebf8ce3..5608aa2884e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run [main() {] Error: Script execution failed with VMError: { major_status: CODE_DESERIALIZATION_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.v2_exp deleted file mode 100644 index 7f57ebf8ce3..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_5.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-14: -Error: Script execution failed with VMError: { - major_status: CODE_DESERIALIZATION_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.exp index 599e4aef117..a02f1b7913e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-17: +task 0 lines 1-17: run [main() {] Error: Script execution failed with VMError: { major_status: CODE_DESERIALIZATION_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.v2_exp deleted file mode 100644 index 599e4aef117..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_6.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-17: -Error: Script execution failed with VMError: { - major_status: CODE_DESERIALIZATION_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.exp index 1e5c6da6ef8..70d63cfabda 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-20: +task 0 lines 1-20: run [main() {] Error: Script execution failed with VMError: { major_status: CODE_DESERIALIZATION_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.v2_exp deleted file mode 100644 index 1e5c6da6ef8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/if_branch_diverges_8.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-20: -Error: Script execution failed with VMError: { - major_status: CODE_DESERIALIZATION_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.exp index de05f2fa7ee..b30c1270c7d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-4: +task 0 lines 1-4: run [main() {] Error: Script execution failed with VMError: { major_status: EMPTY_CODE_UNIT, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.v2_exp deleted file mode 100644 index de05f2fa7ee..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-4: -Error: Script execution failed with VMError: { - major_status: EMPTY_CODE_UNIT, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.exp index 889d8a263c8..3028c59d4ca 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-8: +task 0 lines 1-8: run [main() {] Error: Script execution failed with VMError: { major_status: INVALID_FALL_THROUGH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.v2_exp deleted file mode 100644 index 889d8a263c8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-8: -Error: Script execution failed with VMError: { - major_status: INVALID_FALL_THROUGH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.exp index dd092ca7a31..b691f19b86e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-13: +task 0 lines 1-13: run [main() {] Error: Script execution failed with VMError: { major_status: INVALID_FALL_THROUGH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.v2_exp deleted file mode 100644 index dd092ca7a31..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/invalid_fallthrough3.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-13: -Error: Script execution failed with VMError: { - major_status: INVALID_FALL_THROUGH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.exp index 6cd67db3f64..72f9f3c1db7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-18: publish [module 0x42::test_case {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_496.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.exp index 6cd67db3f64..56d49a85ed8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-22: publish [module 0x42::test_case {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/control_flow/regression_test_678.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.exp index c08c13cd903..51fc50978c6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 9-18: +task 0 lines 1-7: publish [module 0x42.M {] +task 1 lines 9-18: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: LOOKUP_FAILED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.v2_exp deleted file mode 100644 index c08c13cd903..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 9-18: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: LOOKUP_FAILED, - sub_status: None, - location: 0x42::N, - indices: [(FunctionHandle, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.exp index fc5a4436b29..795f23f322c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-11: publish [// NOTE: given that we don't have multi-module publishing yet, we have to go through the] +task 1 lines 13-20: publish [module 0x42.M {] +task 2 lines 22-31: publish [module 0x42.N {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_friend_function_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.exp index 29da56131b7..cc8a8c5f450 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 9-20: +task 0 lines 1-7: publish [module 0x42.M {] +task 1 lines 9-20: run [import 0x42.M;] Error: Script execution failed with VMError: { major_status: LOOKUP_FAILED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.v2_exp deleted file mode 100644 index 29da56131b7..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_private_function.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 9-20: -Error: Script execution failed with VMError: { - major_status: LOOKUP_FAILED, - sub_status: None, - location: script, - indices: [(FunctionHandle, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.exp index 5d92c423f3f..5a2ad5322e5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-7: publish [module 0x42.M {] +task 1 lines 9-18: run [import 0x42.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/access_public_function.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.exp index 5d92c423f3f..7fe498869bb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-46: publish [module 0x42.M {] +task 1 lines 48-74: run [import 0x42.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/all_fields_accessible.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.exp index 5d92c423f3f..2000b37d0f8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-9: publish [module 0x42::m {] +task 1 lines 12-22: publish [module 0x42::m_test {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/call_integers_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.exp index fcab61c77e2..499113a548d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 41-54: +task 0 lines 1-39: publish [module 0x42.Test {] +task 1 lines 41-54: run [import 0x42.Test;] Error: Script execution failed with VMError: { major_status: CALL_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.v2_exp deleted file mode 100644 index fcab61c77e2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/internal_function_invalid_call.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 41-54: -Error: Script execution failed with VMError: { - major_status: CALL_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.exp index 5d92c423f3f..7439614849b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-39: publish [module 0x42.Test {] +task 1 lines 41-54: run [import 0x42.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/non_internal_function_valid_call.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.exp index 3f44c1d8cdb..cd1682ac3c3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-8: +task 0 lines 1-8: run [// missing dep] Error: Script execution failed with VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.v2_exp deleted file mode 100644 index 3f44c1d8cdb..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/dependencies/use_unpublished_module.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-8: -Error: Script execution failed with VMError: { - major_status: LINKER_ERROR, - sub_status: None, - location: undefined, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.exp index 233693e52c5..a27036429ee 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 5-9: +task 0 lines 1-3: publish [module 0x43.M {] +task 1 lines 5-9: publish [module 0x44.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::N'. Got VMError: { major_status: INVALID_FRIEND_DECL_WITH_MODULES_OUTSIDE_ACCOUNT_ADDRESS, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.v2_exp deleted file mode 100644 index 233693e52c5..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_different_address.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 5-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::N'. Got VMError: { - major_status: INVALID_FRIEND_DECL_WITH_MODULES_OUTSIDE_ACCOUNT_ADDRESS, - sub_status: None, - location: 0x44::N, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.exp index bccb4f0e917..7aaff409e38 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-5: +task 0 lines 1-5: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: LINKER_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.v2_exp deleted file mode 100644 index bccb4f0e917..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_non_existing.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-5: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: LINKER_ERROR, - sub_status: None, - location: undefined, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.exp index 1cf0800e87b..18135c63efd 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-5: +task 0 lines 1-5: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INVALID_FRIEND_DECL_WITH_SELF, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.v2_exp deleted file mode 100644 index 1cf0800e87b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/friends/friend_decl_self.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-5: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INVALID_FRIEND_DECL_WITH_SELF, - sub_status: None, - location: 0x42::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.exp index 88822b96288..517b04eddaa 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-51: +task 0 lines 1-51: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [], offsets: [], } - -task 1 'publish'. lines 53-70: +task 1 lines 53-70: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [], offsets: [], } - -task 2 'publish'. lines 72-122: +task 2 lines 72-122: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.v2_exp deleted file mode 100644 index 88822b96288..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/complex_1.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'publish'. lines 1-51: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} - -task 1 'publish'. lines 53-70: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M2, - indices: [], - offsets: [], -} - -task 2 'publish'. lines 72-122: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M3, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp index 6cd67db3f64..3760663f9e2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp index 6cd67db3f64..f43c6536c42 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-16: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp index 6cd67db3f64..dae24c30c7f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-20: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp index 6cd67db3f64..ed9625ec60d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp index 3b9f372dec8..57baf5c68bf 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-23: +task 0 lines 1-23: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.v2_exp deleted file mode 100644 index 3b9f372dec8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp index 6cd67db3f64..3760663f9e2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp index 6cd67db3f64..3760663f9e2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp index 6457e989da4..b928c67ee37 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.v2_exp deleted file mode 100644 index 6457e989da4..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp index e68aa0a009b..8642cfb1f5a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-20: +task 0 lines 1-20: publish [// Not good: infinitely many types/instances.] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.v2_exp deleted file mode 100644 index e68aa0a009b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-20: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.exp index 011ac8091e0..3c79a37a2fe 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.v2_exp deleted file mode 100644 index 011ac8091e0..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.exp index e7a1ab8d9a1..72a764ad8ea 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.v2_exp deleted file mode 100644 index e7a1ab8d9a1..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/nested_types_2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp index f4a66de93b6..06032b707b3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-45: +task 0 lines 1-45: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.v2_exp deleted file mode 100644 index f4a66de93b6..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-45: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp index 6cd67db3f64..02a82dd6311 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [// This is good as there is only one instance foo for any T.] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp index 6cd67db3f64..bfcf3cbe84d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [// Good: two instances foo & foo (if T != u64) for any T.] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp index e7a1ab8d9a1..9c4d6907b68 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [// Bad! Can have infinitely many instances: f, f>, f>>, ...] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.v2_exp deleted file mode 100644 index e7a1ab8d9a1..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp index 2d87672574b..12a83513b16 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [// Similar to the case with one argument, but swaps the two type parameters.] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.v2_exp deleted file mode 100644 index 2d87672574b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.exp index e68aa0a009b..01436eeee82 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-20: +task 0 lines 1-20: publish [// Two loops in the resulting graph.] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: LOOP_IN_INSTANTIATION_GRAPH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.v2_exp deleted file mode 100644 index e68aa0a009b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/instantiation_loops/two_loops.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-20: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: LOOP_IN_INSTANTIATION_GRAPH, - sub_status: None, - location: 0x1::M, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.exp index 48eadf4974c..761baa24df2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.v2_exp deleted file mode 100644 index 48eadf4974c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unreleased_reference.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.exp index 1dc80549752..35eb440f3f8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 10-18: +task 0 lines 1-8: publish [module 0x1.M {] +task 1 lines 10-18: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: LOOKUP_FAILED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.v2_exp deleted file mode 100644 index 1dc80549752..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/abort_unused_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 10-18: -Error: Script execution failed with VMError: { - major_status: LOOKUP_FAILED, - sub_status: None, - location: script, - indices: [(FunctionHandle, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.exp index 6cd67db3f64..20eed0325ee 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_copy.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp index 37ce98a2831..61ee48b781c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-19: +task 0 lines 1-19: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.v2_exp deleted file mode 100644 index 37ce98a2831..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_in_one_if_branch.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-19: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 14)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.exp index 6cd67db3f64..20eed0325ee 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_move.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.exp index 3e48acb9662..ee43e2d8e08 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 10-20: +task 0 lines 1-8: publish [module 0x1.M {] +task 1 lines 10-20: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.v2_exp deleted file mode 100644 index 3e48acb9662..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 10-20: -Error: Script execution failed with VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp index b1807704caf..2ed64a05c4f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-15: +task 0 lines 1-15: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.v2_exp deleted file mode 100644 index b1807704caf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-15: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 10)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp index 932cb9fbf73..b16c56bdfc3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.v2_exp deleted file mode 100644 index 932cb9fbf73..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-11: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp index 5ea7f07864d..99342b13701 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-17: +task 0 lines 1-17: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.v2_exp deleted file mode 100644 index 5ea7f07864d..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-17: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp index 6cd67db3f64..67c4fbb461a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-18: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp index 6cd67db3f64..7383e07cfa3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-19: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp index 21e91f82ad7..bf539a1e201 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-16: +task 0 lines 1-16: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.v2_exp deleted file mode 100644 index 21e91f82ad7..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_assigns_if_doesnt.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-16: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp index 5ea7f07864d..99342b13701 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-17: +task 0 lines 1-17: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.v2_exp deleted file mode 100644 index 5ea7f07864d..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/else_moves_if_doesnt.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-17: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp index 21e91f82ad7..bf539a1e201 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-16: +task 0 lines 1-16: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.v2_exp deleted file mode 100644 index 21e91f82ad7..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_else_doesnt.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-16: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.exp index 79031505c47..f5f57f4b742 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-12: +task 0 lines 1-12: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.v2_exp deleted file mode 100644 index 79031505c47..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_assigns_no_else.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-12: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp index 5ea7f07864d..99342b13701 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-17: +task 0 lines 1-17: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.v2_exp deleted file mode 100644 index 5ea7f07864d..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_else_doesnt.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-17: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.exp index 5bf2215c142..af97ab09afe 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.v2_exp deleted file mode 100644 index 5bf2215c142..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/if_moves_no_else.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-14: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.exp index 8fb0fb20b27..165389b7ecb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.exp @@ -1,6 +1,5 @@ processed 5 tasks - -task 0 'publish'. lines 1-20: +task 0 lines 1-20: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: MOVELOC_UNAVAILABLE_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 15)], } - -task 1 'publish'. lines 22-40: +task 1 lines 22-40: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 15)], } - -task 2 'publish'. lines 42-61: +task 2 lines 42-61: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 17)], } - -task 3 'publish'. lines 63-82: +task 3 lines 63-82: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 15)], } - -task 4 'publish'. lines 84-104: +task 4 lines 84-104: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: BORROWLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.v2_exp deleted file mode 100644 index 8fb0fb20b27..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/join_failure.v2_exp +++ /dev/null @@ -1,46 +0,0 @@ -processed 5 tasks - -task 0 'publish'. lines 1-20: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: MOVELOC_UNAVAILABLE_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} - -task 1 'publish'. lines 22-40: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} - -task 2 'publish'. lines 42-61: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 17)], -} - -task 3 'publish'. lines 63-82: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} - -task 4 'publish'. lines 84-104: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: BORROWLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.exp index 4b2d0cbf4f1..a9af2ffe271 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.v2_exp deleted file mode 100644 index 4b2d0cbf4f1..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/move_before_assign.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-11: -Error: Script execution failed with VMError: { - major_status: MOVELOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp index 6cd67db3f64..76d74b23566 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_doesnt_assign.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.exp index 6cd67db3f64..fefd2d6eaba 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/return_branch_moves.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.exp index 6cd67db3f64..9532d851d1a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-22: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_st_loc_partial.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.exp index 6cd67db3f64..733d76eb5a6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.exp index 6cd67db3f64..c8c6adb11f6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-20: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/signer_unused_partial.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.exp index 88792dc3555..e392fcf8d90 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: COPYLOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.v2_exp deleted file mode 100644 index 88792dc3555..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/use_before_assign.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: COPYLOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp index 7a8a07c5bfa..a03748e3d34 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.v2_exp deleted file mode 100644 index 7a8a07c5bfa..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.exp index 8f8c8555066..a32c34959b4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-19: +task 0 lines 1-19: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.v2_exp deleted file mode 100644 index 8f8c8555066..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-19: -Error: Script execution failed with VMError: { - major_status: MOVELOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.exp index b59c1c88f3e..ef447a70d9d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-23: +task 0 lines 1-23: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.v2_exp deleted file mode 100644 index b59c1c88f3e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/locals_safety/while_move_local_2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-23: -Error: Script execution failed with VMError: { - major_status: MOVELOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.exp index 56a1524b0ac..004b1b3b57c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-22: +task 0 lines 1-22: publish [module 0x42.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.v2_exp deleted file mode 100644 index 56a1524b0ac..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_field_after_local.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x42::Tester, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.exp index e1edd1b9620..f53ff0a35f5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-13: +task 0 lines 1-13: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.v2_exp deleted file mode 100644 index e1edd1b9620..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_after_move.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-13: -Error: Script execution failed with VMError: { - major_status: MOVELOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 12)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.exp index 5d92c423f3f..c5469924ca7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-32: publish [module 0x42.Tester {] +task 1 lines 34-54: run [import 0x42.Tester;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp index 7bd47c8c4ad..8a4df558083 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 36-61: +task 0 lines 1-34: publish [module 0x42.Tester {] +task 1 lines 36-61: run [import 0x42.Tester;] Error: Script execution failed with VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.v2_exp deleted file mode 100644 index 7bd47c8c4ad..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_struct_invalidated.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 36-61: -Error: Script execution failed with VMError: { - major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.exp index 6cd67db3f64..50903c202f6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-13: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/assign_local_value.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.exp index 5d92c423f3f..95b757b48eb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-21: publish [module 0x1.B {] +task 1 lines 23-34: run [import 0x1.B;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_copy_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.exp index 5d92c423f3f..b7df272da5f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-23: publish [module 0x1.A {] +task 1 lines 25-38: run [import 0x1.A;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_field_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.exp index 6cd67db3f64..fc7ae62a9f1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-24: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_1.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.exp index 6cd67db3f64..59438fdf176 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-53: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_2.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.exp index 6cd67db3f64..2b94136028c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-64: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_3.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.exp index b7e3960f80b..b7a97925adc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: DUPLICATE_ACQUIRES_ANNOTATION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.v2_exp deleted file mode 100644 index b7e3960f80b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_duplicate_annotation.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: DUPLICATE_ACQUIRES_ANNOTATION, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.exp index 27feec460e0..9b9aec94e0e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: EXTRANEOUS_ACQUIRES_ANNOTATION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.v2_exp deleted file mode 100644 index 27feec460e0..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_extraneous_annotation.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: EXTRANEOUS_ACQUIRES_ANNOTATION, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.exp index e16c4e5f846..85becbd1bc1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-23: +task 0 lines 1-23: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.v2_exp deleted file mode 100644 index e16c4e5f846..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.exp index 6b5b4c4ac26..eec4fb0643d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-29: +task 0 lines 1-29: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 2)], offsets: [(FunctionDefinitionIndex(2), 7)], } - -task 1 'publish'. lines 31-59: +task 1 lines 31-59: publish [module 0x1.A2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 2)], offsets: [(FunctionDefinitionIndex(2), 7)], } - -task 2 'publish'. lines 61-89: +task 2 lines 61-89: publish [module 0x1.A2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.v2_exp deleted file mode 100644 index 6b5b4c4ac26..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_2.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'publish'. lines 1-29: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 7)], -} - -task 1 'publish'. lines 31-59: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A2, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 7)], -} - -task 2 'publish'. lines 61-89: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A2, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.exp index 88b629cac51..b32db7aadd2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-33: +task 0 lines 1-33: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 3)], offsets: [(FunctionDefinitionIndex(3), 8)], } - -task 1 'publish'. lines 35-68: +task 1 lines 35-68: publish [module 0x1.A2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 3)], offsets: [(FunctionDefinitionIndex(3), 10)], } - -task 2 'publish'. lines 70-102: +task 2 lines 70-102: publish [module 0x1.A3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A3'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.v2_exp deleted file mode 100644 index 88b629cac51..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_3.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'publish'. lines 1-33: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 3)], - offsets: [(FunctionDefinitionIndex(3), 8)], -} - -task 1 'publish'. lines 35-68: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A2'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A2, - indices: [(FunctionDefinition, 3)], - offsets: [(FunctionDefinitionIndex(3), 10)], -} - -task 2 'publish'. lines 70-102: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A3'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A3, - indices: [(FunctionDefinition, 3)], - offsets: [(FunctionDefinitionIndex(3), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.exp index 56a34f0dd15..40839bed95e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: INVALID_ACQUIRES_ANNOTATION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.v2_exp deleted file mode 100644 index 56a34f0dd15..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_invalid_annotation.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: INVALID_ACQUIRES_ANNOTATION, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.exp index 451f76b7e28..471e96170c4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: MISSING_ACQUIRES_ANNOTATION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.v2_exp deleted file mode 100644 index 451f76b7e28..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_missing_annotation.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: MISSING_ACQUIRES_ANNOTATION, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.exp index 6cd67db3f64..adceebbd298 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-30: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_1.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.exp index e9f84e17e5e..ff932ae09e7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.v2_exp deleted file mode 100644 index e9f84e17e5e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_acquires_return_reference_invalid_1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.exp index ec909b80a0f..09f05c3216b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.v2_exp deleted file mode 100644 index ec909b80a0f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad0.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.exp index b36375914c4..92605249ab0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-18: +task 0 lines 1-18: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.v2_exp deleted file mode 100644 index b36375914c4..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-18: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.exp index 8aec91d43fb..f96a1b3bd69 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-19: +task 0 lines 1-19: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.v2_exp deleted file mode 100644 index 8aec91d43fb..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.exp index 8f741b7df7b..26c8586f6c7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-28: +task 0 lines 1-28: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.v2_exp deleted file mode 100644 index 8f741b7df7b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_bad5.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.exp index 6cd67db3f64..4f9699ee87a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-86: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_global_good.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.exp index 4f66e9a976b..ba8a3eeac73 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-14: +task 0 lines 1-14: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_UNAVAILABLE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.v2_exp deleted file mode 100644 index 4f66e9a976b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_if.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-14: -Error: Script execution failed with VMError: { - major_status: MOVELOC_UNAVAILABLE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.exp index 6cd67db3f64..1371996f8fb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 2-12: publish [module 0x42.m {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_in_loop.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp index cefe0fe3aa0..f142b65d97f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-16: +task 0 lines 1-16: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: RET_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.v2_exp deleted file mode 100644 index cefe0fe3aa0..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-16: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: RET_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp index 6cd67db3f64..7383e07cfa3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-19: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.exp index f8d6784e6d2..b453a6a42ba 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 2-416: +task 0 lines 2-416: publish [module 0x42::pwn {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::pwn'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.v2_exp deleted file mode 100644 index f8d6784e6d2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/call_function_with_many_acquires.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 2-416: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::pwn'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::pwn, - indices: [(FunctionDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.exp index 6cd67db3f64..0c9d81bf54d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-15: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp index 6cd67db3f64..b9c6c47210a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-21: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp index 58c50b9f5be..3303c0c4596 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: COPYLOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.v2_exp deleted file mode 100644 index 58c50b9f5be..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: COPYLOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp index 6cd67db3f64..7f70129ef32 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp index a666808cede..5c27dcdb8fb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-20: +task 0 lines 1-20: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: COPYLOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.v2_exp deleted file mode 100644 index a666808cede..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-20: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: COPYLOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp index e10bfcc9373..a7520fe9bb0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: COPYLOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.v2_exp deleted file mode 100644 index e10bfcc9373..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: COPYLOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp index 5d92c423f3f..1a27e5b4da7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-17: publish [module 0x1.M {] +task 1 lines 19-30: run [import 0x1.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_borrow_field_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.exp index e1edd1b9620..f53ff0a35f5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-13: +task 0 lines 1-13: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.v2_exp deleted file mode 100644 index e1edd1b9620..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_copy_bad.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-13: -Error: Script execution failed with VMError: { - major_status: MOVELOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 12)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.exp index de038a27cb2..e467fbc8075 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-18: +task 0 lines 1-18: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.v2_exp deleted file mode 100644 index de038a27cb2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_bad.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-18: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.exp index 6cd67db3f64..d6371b3fea6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-25: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/deref_eq_good.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.exp index 7c78f043bf4..b6e9e0e1aa1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 6)], } - -task 1 'publish'. lines 15-27: +task 1 lines 15-27: publish [module 0x1.Tester2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 6)], } - -task 2 'publish'. lines 29-41: +task 2 lines 29-41: publish [module 0x1.Tester3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester3'. Got VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 6)], } - -task 3 'publish'. lines 43-55: +task 3 lines 43-55: publish [module 0x1.Tester4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester4'. Got VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.v2_exp deleted file mode 100644 index 7c78f043bf4..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_bad.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} - -task 1 'publish'. lines 15-27: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} - -task 2 'publish'. lines 29-41: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester3'. Got VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester3, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} - -task 3 'publish'. lines 43-55: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester4'. Got VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester4, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.exp index 6cd67db3f64..74a06ef2bd0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-44: publish [// testing valid usages of == and != over references] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/eq_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.exp index 782b6965557..d4f817308cb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-28: +task 0 lines 1-28: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 15)], } - -task 1 'publish'. lines 30-57: +task 1 lines 30-57: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.v2_exp deleted file mode 100644 index 782b6965557..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_1.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} - -task 1 'publish'. lines 30-57: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 15)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.exp index 92041c10d46..6710a84ac1f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-31: +task 0 lines 1-31: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.v2_exp deleted file mode 100644 index 92041c10d46..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_invalid_2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-31: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 13)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.exp index 6cd67db3f64..15ae2647a4b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-35: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_1.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.exp index 6cd67db3f64..71f60ae3dbb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-74: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/factor_valid_2.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.exp index fc5a4436b29..a5594f94bd6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-29: publish [module 0x1.A {] +task 1 lines 31-58: publish [module 0x1.Tester {] +task 2 lines 60-67: run --signers 0x1 [import 0x1.Tester;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.exp index 1debe98a838..4db2a4ed135 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.exp @@ -1,6 +1,6 @@ processed 4 tasks - -task 1 'publish'. lines 31-46: +task 0 lines 1-29: publish [module 0x1.A {] +task 1 lines 31-46: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -8,8 +8,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 2 'publish'. lines 48-62: +task 2 lines 48-62: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, @@ -17,8 +16,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } - -task 3 'publish'. lines 64-82: +task 3 lines 64-82: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.v2_exp deleted file mode 100644 index 1debe98a838..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_invalid.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 4 tasks - -task 1 'publish'. lines 31-46: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 2 'publish'. lines 48-62: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} - -task 3 'publish'. lines 64-82: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 7)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.exp index 6aca78fb364..3c417cc7ac0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 32-58: +task 0 lines 1-30: publish [module 0x1.A {] +task 1 lines 32-58: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: GLOBAL_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.v2_exp deleted file mode 100644 index 6aca78fb364..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_lossy_acquire_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 32-58: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: GLOBAL_REFERENCE_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.exp index 23a48a16da4..ece3641d867 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: MISSING_ACQUIRES_ANNOTATION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.v2_exp deleted file mode 100644 index 23a48a16da4..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_global_requires_acquire.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: MISSING_ACQUIRES_ANNOTATION, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.exp index 6cd67db3f64..ff58c357013 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-56: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp index 6cd67db3f64..7f38ca9a3d9 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-27: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp index 6cd67db3f64..a76e3b078df 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-26: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp index 6cd67db3f64..b4e33519a9c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-54: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_loc_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp index 6cd67db3f64..0702bcdf610 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-50: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp index 893405511c8..26f2b14c4b7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-51: +task 0 lines 1-51: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 2)], offsets: [(FunctionDefinitionIndex(2), 23)], } - -task 1 'publish'. lines 53-103: +task 1 lines 53-103: publish [module 0x1.Tester2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { major_status: FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.v2_exp deleted file mode 100644 index 893405511c8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-51: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 23)], -} - -task 1 'publish'. lines 53-103: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { - major_status: FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester2, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 23)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp index 6cd67db3f64..3a9269f74f0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-20: publish [module 0x1.Tester {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp index fd136e2a4d2..a496a89c142 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-29: +task 0 lines 1-29: publish [module 0x1.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.v2_exp deleted file mode 100644 index fd136e2a4d2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-29: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { - major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: 0x1::Tester, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp index 6cd67db3f64..ed9625ec60d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.exp index 6cd67db3f64..6b0a7524ab4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-37: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/move_one_branch.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp index 80a12b0918a..916c16b21c6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-19: +task 0 lines 1-19: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 12)], } - -task 1 'publish'. lines 21-44: +task 1 lines 21-44: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.v2_exp deleted file mode 100644 index 80a12b0918a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_invalid.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 12)], -} - -task 1 'publish'. lines 21-44: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 12)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp index 6cd67db3f64..c51fb37114c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-17: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp index 8b2edcf8860..f49629465f7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.v2_exp deleted file mode 100644 index 8b2edcf8860..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp index 5d92c423f3f..de845f28bbf 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-22: publish [module 0x42.Test {] +task 1 lines 24-36: run [import 0x42.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_borrow_field_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.exp index 509d5fddf0c..db45c1269b5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.v2_exp deleted file mode 100644 index 509d5fddf0c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp index 5d92c423f3f..c38ae18a2eb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-35: publish [module 0x42.A {] +task 1 lines 37-49: run [import 0x42.A;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_resource_holder_2.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp index 6cd67db3f64..726ebd897a0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp index f7f6be1fd56..d47093267e5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.v2_exp deleted file mode 100644 index f7f6be1fd56..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp index 06d18baed1e..ace471615b4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 7)], } - -task 1 'publish'. lines 19-35: +task 1 lines 19-35: publish [module 0x1.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::N'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.v2_exp deleted file mode 100644 index 06d18baed1e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 7)], -} - -task 1 'publish'. lines 19-35: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::N'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 10)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.exp index fc5a4436b29..235c959b9e1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-19: publish [module 0x42.B {] +task 1 lines 21-40: publish [module 0x42.A {] +task 2 lines 42-56: run [import 0x42.A;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/nested_mutate.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.exp index f55db293660..f3e7ef8c23a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-10: +task 0 lines 1-10: run [main() {] Error: Script execution failed with VMError: { major_status: BORROWLOC_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.v2_exp deleted file mode 100644 index f55db293660..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/no_borrow_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-10: -Error: Script execution failed with VMError: { - major_status: BORROWLOC_REFERENCE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.exp index bac0e5bb932..2550b0b89bf 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-21: +task 0 lines 1-21: publish [module 0x42.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.v2_exp deleted file mode 100644 index bac0e5bb932..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_field_after_assign_local.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-21: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x42::Tester, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp index f9ea14c07e3..6b4052f9f7e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-16: +task 0 lines 1-16: run [main() {] Error: Script execution failed with VMError: { major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.v2_exp deleted file mode 100644 index f9ea14c07e3..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_assign.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-16: -Error: Script execution failed with VMError: { - major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 18)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.exp index 068b8819b9b..14d190b40b8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.v2_exp deleted file mode 100644 index 068b8819b9b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/read_local_ref_after_move.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-11: -Error: Script execution failed with VMError: { - major_status: MOVELOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.exp index 6cd67db3f64..0398852dfd5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-21: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/ref_moved_one_branch.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.exp index 6cd67db3f64..d6371b3fea6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-25: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/release_cycle.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.exp index e9f47104d90..06412508721 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.Tester {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.v2_exp deleted file mode 100644 index e9f47104d90..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_local_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x42::Tester, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp index 6cd67db3f64..88e28b3a606 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-27: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp index d1360176893..1e147a5a29b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-15: +task 0 lines 1-15: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } - -task 1 'publish'. lines 17-30: +task 1 lines 17-30: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } - -task 2 'publish'. lines 32-49: +task 2 lines 32-49: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 13)], } - -task 3 'publish'. lines 51-68: +task 3 lines 51-68: publish [module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.v2_exp deleted file mode 100644 index d1360176893..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-15: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} - -task 1 'publish'. lines 17-30: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} - -task 2 'publish'. lines 32-49: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::M3, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 13)], -} - -task 3 'publish'. lines 51-68: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::M4, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 13)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp index 28a4b4f71ea..790b7b07f92 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.v2_exp deleted file mode 100644 index 28a4b4f71ea..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.exp index 5d92c423f3f..91aaa29116e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-20: publish [module 0x42.A {] +task 1 lines 22-33: run [import 0x42.A;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/simple_mutate.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.exp index 6cd67db3f64..c8c6adb11f6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-20: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/two_mutable_ref.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.exp index e9762e99ad7..be2d25bac3b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 12-37: +task 0 lines 1-9: publish [module 0x42.B {] +task 1 lines 12-37: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.v2_exp deleted file mode 100644 index e9762e99ad7..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_after_move.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 12-37: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 10)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.exp index fc5a4436b29..c285314afd4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-17: publish [module 0x42.B {] +task 1 lines 19-38: publish [module 0x42.A {] +task 2 lines 40-54: run [import 0x42.A;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_prefix_after_move.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.exp index 4a14be9c9a5..7887f13029d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'publish'. lines 19-41: +task 0 lines 1-16: publish [module 0x42.B {] +task 1 lines 19-41: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.v2_exp deleted file mode 100644 index 4a14be9c9a5..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/use_suffix_after_move.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'publish'. lines 19-41: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 12)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp index fe00bc7961c..b92ff9e3d82 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'run'. lines 1-15: +task 0 lines 1-15: run [main() {] Error: Script execution failed with VMError: { major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 14)], } - -task 1 'run'. lines 17-31: +task 1 lines 17-31: run [main() {] Error: Script execution failed with VMError: { major_status: BORROWLOC_EXISTS_BORROW_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 12)], } - -task 2 'run'. lines 33-47: +task 2 lines 33-47: run [main() {] Error: Script execution failed with VMError: { major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.v2_exp deleted file mode 100644 index fe00bc7961c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_double_borrow.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'run'. lines 1-15: -Error: Script execution failed with VMError: { - major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 14)], -} - -task 1 'run'. lines 17-31: -Error: Script execution failed with VMError: { - major_status: BORROWLOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 12)], -} - -task 2 'run'. lines 33-47: -Error: Script execution failed with VMError: { - major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 14)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp index 0c783f82df6..fb512f1da98 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'run'. lines 1-12: +task 0 lines 1-12: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_EXISTS_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 9)], } - -task 1 'run'. lines 14-25: +task 1 lines 14-25: run [main() {] Error: Script execution failed with VMError: { major_status: MOVELOC_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.v2_exp deleted file mode 100644 index 0c783f82df6..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'run'. lines 1-12: -Error: Script execution failed with VMError: { - major_status: MOVELOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} - -task 1 'run'. lines 14-25: -Error: Script execution failed with VMError: { - major_status: MOVELOC_EXISTS_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp index cf012f0cc74..438339b5f43 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'run'. lines 1-12: +task 0 lines 1-12: run [main() {] Error: Script execution failed with VMError: { major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 10)], } - -task 1 'run'. lines 14-25: +task 1 lines 14-25: run [main() {] Error: Script execution failed with VMError: { major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.v2_exp deleted file mode 100644 index cf012f0cc74..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'run'. lines 1-12: -Error: Script execution failed with VMError: { - major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 10)], -} - -task 1 'run'. lines 14-25: -Error: Script execution failed with VMError: { - major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 10)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp index 7eb26651023..68937dbce12 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-17: +task 0 lines 1-17: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: WRITEREF_EXISTS_BORROW_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.v2_exp deleted file mode 100644 index 7eb26651023..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_invalid.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-17: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: WRITEREF_EXISTS_BORROW_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 10)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp index 6cd67db3f64..a253a4b9848 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-22: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid1.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp index 6cd67db3f64..6b0a7524ab4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-37: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/reference_safety/writeref_borrow_valid2.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.exp index b134af1aea2..a02b2a54f7a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.exp @@ -1 +1,6 @@ processed 5 tasks +task 0 lines 1-6: run --type-args u64 --args 0 [// all invalid signatures] +task 1 lines 9-13: run --type-args u8 --args 1u8 [main(x: &T) {] +task 2 lines 16-20: run --type-args u8 --args b"hello" [main(v: vector) {] +task 3 lines 23-26: publish [module 0x42.M {] +task 4 lines 29-36: run --type-args u8 --args 0u8 [// bit of a hack but works because structs have no overhead] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.v2_exp deleted file mode 100644 index b134af1aea2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_type_parameters_in_args.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 5 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.exp index 5d92c423f3f..45dc5fd8f15 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-4: publish [module 0x1.M {] +task 1 lines 6-10: run --type-args 0x1::M::Cup<0x1::M::Cup> [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_generic_type_arg.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.exp index 1dddbff45c6..5afdd965b16 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 20-24: +task 0 lines 1-18: publish [module 0x1.Coin {] +task 1 lines 20-24: run --type-args u64 u8 0x1::Coin::Coin [main() {] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.v2_exp deleted file mode 100644 index 1dddbff45c6..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/script_with_type_parameters.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 20-24: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/signer_misplaced_signer_arg.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/signer_misplaced_signer_arg.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/signer_misplaced_signer_arg.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.exp index 8f8129931bf..08b312d470c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 15-20: +task 0 lines 1-13: publish [// struct and struct ref arguments are now allowed] +task 1 lines 15-20: run --args 0 0 0 [import 0x42.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 22-22: +task 2 lines 22-22: run 0x42::M::foo --args 0 0 0 Error: Function execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.v2_exp deleted file mode 100644 index 8f8129931bf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/script_signature/struct_arguments.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 3 tasks - -task 1 'run'. lines 15-20: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 2 'run'. lines 22-22: -Error: Function execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: 0x42::M, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.exp index 6cd67db3f64..f47767bcb56 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_all_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.exp index b15334ba4bf..3e0f61dca9a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.v2_exp deleted file mode 100644 index b15334ba4bf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.exp index b15334ba4bf..3e0f61dca9a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.v2_exp deleted file mode 100644 index b15334ba4bf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/all_as_unrestricted.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.exp index fb9b9ccf9a2..788be4f810c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.exp @@ -1,6 +1,5 @@ processed 7 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.m1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 1), (FunctionDefinition, 0)], offsets: [], } - -task 1 'publish'. lines 13-22: +task 1 lines 13-22: publish [module 0x1.m2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 2 'publish'. lines 24-30: +task 2 lines 24-30: publish [module 0x1.m3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 3 'publish'. lines 32-38: +task 3 lines 32-38: publish [module 0x1.m4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 4 'publish'. lines 40-50: +task 4 lines 40-50: publish [module 0x1.m5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -44,8 +39,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [], } - -task 5 'publish'. lines 52-65: +task 5 lines 52-65: publish [module 0x1.m6 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m6'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -53,8 +47,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [], } - -task 6 'publish'. lines 67-77: +task 6 lines 67-77: publish [module 0x1.m7 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m7'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.v2_exp deleted file mode 100644 index fb9b9ccf9a2..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_in_context.v2_exp +++ /dev/null @@ -1,64 +0,0 @@ -processed 7 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m1, - indices: [(Signature, 1), (FunctionDefinition, 0)], - offsets: [], -} - -task 1 'publish'. lines 13-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m2, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 2 'publish'. lines 24-30: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m3, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 3 'publish'. lines 32-38: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m4, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 4 'publish'. lines 40-50: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m5, - indices: [(FunctionDefinition, 0)], - offsets: [], -} - -task 5 'publish'. lines 52-65: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m6'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m6, - indices: [(FunctionDefinition, 1)], - offsets: [], -} - -task 6 'publish'. lines 67-77: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m7'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m7, - indices: [(FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.exp index 5396e86e007..6e6e18d2fd3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.m {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.v2_exp deleted file mode 100644 index 5396e86e007..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/bad_type_move_to_after_pack.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.exp index 88cabce7565..1e67e417b70 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.exp @@ -1,6 +1,6 @@ processed 9 tasks - -task 1 'run'. lines 19-24: +task 0 lines 1-17: publish [module 0x1.M {] +task 1 lines 19-24: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 26-31: +task 2 lines 26-31: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'run'. lines 33-38: +task 3 lines 33-38: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 4 'run'. lines 40-45: +task 4 lines 40-45: run --type-args 0x1::M::K --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 5 'run'. lines 47-52: +task 5 lines 47-52: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -44,8 +40,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 6 'run'. lines 54-59: +task 6 lines 54-59: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -53,8 +48,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 7 'run'. lines 61-66: +task 7 lines 61-66: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -62,8 +56,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 8 'run'. lines 68-73: +task 8 lines 68-73: run --type-args u64 --args false [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.v2_exp deleted file mode 100644 index 88cabce7565..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script.v2_exp +++ /dev/null @@ -1,73 +0,0 @@ -processed 9 tasks - -task 1 'run'. lines 19-24: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 2 'run'. lines 26-31: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 3 'run'. lines 33-38: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 4 'run'. lines 40-45: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 5 'run'. lines 47-52: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 6 'run'. lines 54-59: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 7 'run'. lines 61-66: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 8 'run'. lines 68-73: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.exp index 6958d8d8d9f..a696a54c828 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.exp @@ -1,6 +1,6 @@ processed 9 tasks - -task 1 'run'. lines 17-22: +task 0 lines 1-15: publish [module 0x1.M {] +task 1 lines 17-22: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 24-29: +task 2 lines 24-29: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +16,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 3 'run'. lines 31-36: +task 3 lines 31-36: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +24,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 4 'run'. lines 38-43: +task 4 lines 38-43: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -35,8 +32,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 5 'run'. lines 45-50: +task 5 lines 45-50: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -44,8 +40,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 6 'run'. lines 52-57: +task 6 lines 52-57: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -53,8 +48,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 7 'run'. lines 59-64: +task 7 lines 59-64: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -62,8 +56,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 8 'run'. lines 66-71: +task 8 lines 66-71: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.v2_exp deleted file mode 100644 index 6958d8d8d9f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/check_constraints_script_invalid.v2_exp +++ /dev/null @@ -1,73 +0,0 @@ -processed 9 tasks - -task 1 'run'. lines 17-22: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 2 'run'. lines 24-29: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 3 'run'. lines 31-36: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 4 'run'. lines 38-43: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 5 'run'. lines 45-50: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 6 'run'. lines 52-57: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 7 'run'. lines 59-64: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 8 'run'. lines 66-71: -Error: Script execution failed with VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.exp index 1ea1314362a..5f3f095089c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.exp @@ -1,6 +1,5 @@ processed 5 tasks - -task 0 'publish'. lines 1-15: +task 0 lines 1-15: publish [module 0x1.m1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2)], offsets: [], } - -task 1 'publish'. lines 17-31: +task 1 lines 17-31: publish [module 0x1.m2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2)], offsets: [], } - -task 2 'publish'. lines 33-47: +task 2 lines 33-47: publish [module 0x1.m3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2)], offsets: [], } - -task 3 'publish'. lines 49-63: +task 3 lines 49-63: publish [module 0x1.m4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2)], offsets: [], } - -task 4 'publish'. lines 65-79: +task 4 lines 65-79: publish [module 0x1.m5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.v2_exp deleted file mode 100644 index 1ea1314362a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/global_ops_bad_inner_type.v2_exp +++ /dev/null @@ -1,46 +0,0 @@ -processed 5 tasks - -task 0 'publish'. lines 1-15: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m1, - indices: [(Signature, 2)], - offsets: [], -} - -task 1 'publish'. lines 17-31: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m2, - indices: [(Signature, 2)], - offsets: [], -} - -task 2 'publish'. lines 33-47: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m3, - indices: [(Signature, 2)], - offsets: [], -} - -task 3 'publish'. lines 49-63: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m4, - indices: [(Signature, 2)], - offsets: [], -} - -task 4 'publish'. lines 65-79: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::m5'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::m5, - indices: [(Signature, 2)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp index 6193148848b..4d629b5bcec 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.v2_exp deleted file mode 100644 index 6193148848b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(FunctionInstantiation, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp index 5c410b7de26..ed2a5acc86f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.v2_exp deleted file mode 100644 index 5c410b7de26..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_for_struct.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp index 308112724e6..c127d0b205c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp @@ -1,6 +1,5 @@ processed 9 tasks - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 1 'publish'. lines 15-28: +task 1 lines 15-28: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 2 'publish'. lines 30-42: +task 2 lines 30-42: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 3 'publish'. lines 44-57: +task 3 lines 44-57: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 4 'publish'. lines 59-70: +task 4 lines 59-70: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -44,8 +39,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 5 'publish'. lines 72-86: +task 5 lines 72-86: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -53,8 +47,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 6 'publish'. lines 88-100: +task 6 lines 88-100: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -62,8 +55,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefInstantiation, 0)], offsets: [], } - -task 7 'publish'. lines 102-111: +task 7 lines 102-111: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -71,8 +63,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 0)], offsets: [], } - -task 8 'publish'. lines 113-122: +task 8 lines 113-122: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.v2_exp deleted file mode 100644 index 308112724e6..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.v2_exp +++ /dev/null @@ -1,82 +0,0 @@ -processed 9 tasks - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 1 'publish'. lines 15-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 2 'publish'. lines 30-42: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 3 'publish'. lines 44-57: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 4 'publish'. lines 59-70: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 5 'publish'. lines 72-86: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 6 'publish'. lines 88-100: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0)], - offsets: [], -} - -task 7 'publish'. lines 102-111: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 0)], - offsets: [], -} - -task 8 'publish'. lines 113-122: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.exp index f606abadc3c..6e5007a34a0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-5: +task 0 lines 1-5: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.v2_exp deleted file mode 100644 index f606abadc3c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_fields.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-5: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x42::M, - indices: [(StructDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.exp new file mode 100644 index 00000000000..811d83423e9 --- /dev/null +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.exp @@ -0,0 +1,34 @@ +processed 5 tasks +task 0 lines 4-23: publish [module 0x42::a] +task 1 lines 26-30: publish [module 0x42::b] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::b'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::b, + indices: [(Signature, 0)], + offsets: [], +} +task 2 lines 33-37: publish [module 0x42::b] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::b'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::b, + indices: [(Signature, 0)], + offsets: [], +} +task 3 lines 40-47: publish [module 0x42::c] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::c'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::c, + indices: [(Signature, 0)], + offsets: [], +} +task 4 lines 50-54: publish [module 0x42::d] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::d'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::d, + indices: [(StructDefinition, 0)], + offsets: [], +} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.masm b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.masm new file mode 100644 index 00000000000..c73dd294180 --- /dev/null +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_function_signatures.masm @@ -0,0 +1,54 @@ +// Having references as immediate parameters or return types is allowed. All other use cases are +// not allowed. + +//# publish +module 0x42::a + +struct A + x: T + +struct B + x: |&u64, &mut u64|(&u64, &mut u64) + +struct C has copy + x: |B|B has copy + +struct D has drop + x: |B|B has drop + +public fun foo(f: |&u64, &mut u64|(&u64, &mut u64) has drop) + ret + +public fun bar(f: |&u64, &mut u64|u32 has drop) + ret + + +//# publish +module 0x42::b + +public fun foo(f: |&&u64|u32 has drop) + ret + + +//# publish +module 0x42::b + +public fun foo(f: |vector<&u64>|u32 has drop) + ret + + +//# publish +module 0x42::c + +struct A + x: T + +public fun foo(f: |A<&u64>|u32 has drop) + ret + + +//# publish +module 0x42::d + +struct A + x: |vector<&u64>| diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.exp index 6cd67db3f64..9f4b10326c8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-8: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/reference_in_locals_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.exp index 6cd67db3f64..726ebd897a0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_all_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.exp index 07c9297f091..5bfc1965db5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.v2_exp deleted file mode 100644 index 07c9297f091..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/resource_as_unrestricted.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.exp index 6cd67db3f64..726ebd897a0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-12: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.exp index a6a2d382aaf..41cb4dab8f7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 1)], offsets: [], } - -task 1 'publish'. lines 13-24: +task 1 lines 13-24: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.v2_exp deleted file mode 100644 index a6a2d382aaf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/two_type_actuals_reverse_order.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1)], - offsets: [], -} - -task 1 'publish'. lines 13-24: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M2, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.exp index 6cd67db3f64..0b5768b09bc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_all_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.exp index 9ce36d43527..dec8514efbc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.v2_exp deleted file mode 100644 index 9ce36d43527..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/unrestricted_as_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.exp index ead8050a5fd..f91780936dc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'run'. lines 1-6: +task 0 lines 1-6: run [main() {] Error: Script execution failed with VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 1 'run'. lines 8-13: +task 1 lines 8-13: run [main() {] Error: Script execution failed with VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [], } - -task 2 'run'. lines 15-20: +task 2 lines 15-20: run [main() {] Error: Script execution failed with VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.v2_exp deleted file mode 100644 index ead8050a5fd..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/signature/vector_ops_invalid_type_args.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'run'. lines 1-6: -Error: Script execution failed with VMError: { - major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 1 'run'. lines 8-13: -Error: Script execution failed with VMError: { - major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [], -} - -task 2 'run'. lines 15-20: -Error: Script execution failed with VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp index 7ee696b46ee..7657fc5eeae 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-6: +task 0 lines 1-6: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.v2_exp deleted file mode 100644 index 7ee696b46ee..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-6: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.exp index cbe3f217dbc..fa26343ecdc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-6: +task 0 lines 1-6: run [main() {] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.v2_exp deleted file mode 100644 index cbe3f217dbc..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_no_return.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-6: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp index b5ff75d93db..298d9d47086 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 11-19: +task 0 lines 1-9: publish [module 0x1.M {] +task 1 lines 11-19: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.v2_exp deleted file mode 100644 index b5ff75d93db..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 11-19: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp index fb39cf47b32..5d9df2cb533 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'run'. lines 1-6: +task 0 lines 1-6: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'run'. lines 8-13: +task 1 lines 8-13: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 2 'run'. lines 15-20: +task 2 lines 15-20: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 3 'run'. lines 22-27: +task 3 lines 22-27: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 4 'run'. lines 29-34: +task 4 lines 29-34: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 5 'run'. lines 36-41: +task 5 lines 36-41: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.v2_exp deleted file mode 100644 index fb39cf47b32..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_negative_stack.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'run'. lines 1-6: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'run'. lines 8-13: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 2 'run'. lines 15-20: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 3 'run'. lines 22-27: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 4 'run'. lines 29-34: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 5 'run'. lines 36-41: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp index 7537209e317..c5f2148ffd3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'run'. lines 9-15: +task 1 lines 9-15: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 2 'run'. lines 17-23: +task 2 lines 17-23: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 3 'run'. lines 25-31: +task 3 lines 25-31: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 4 'run'. lines 33-39: +task 4 lines 33-39: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 5 'run'. lines 41-47: +task 5 lines 41-47: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.v2_exp deleted file mode 100644 index 7537209e317..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/cast_positive_stack.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'run'. lines 1-7: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'run'. lines 9-15: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 2 'run'. lines 17-23: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 3 'run'. lines 25-31: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 4 'run'. lines 33-39: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 5 'run'. lines 41-47: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.exp index 6cd67db3f64..b4d81765b0c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-26: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/consume_stack.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp index e2e5d56821f..899e7210fa8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-15: +task 0 lines 1-15: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.v2_exp deleted file mode 100644 index e2e5d56821f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-15: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp index 57599443792..9e92be414f5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 11-19: +task 0 lines 1-9: publish [module 0x1.Test {] +task 1 lines 11-19: run [import 0x1.Test;] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.v2_exp deleted file mode 100644 index 57599443792..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 11-19: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp index f3216bb069d..9747ad56c6d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 24-35: +task 0 lines 1-22: publish [module 0x1.A {] +task 1 lines 24-35: run [import 0x1.A;] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.v2_exp deleted file mode 100644 index f3216bb069d..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 24-35: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp index 69e4fd879d8..da125e7d012 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 23-38: +task 0 lines 1-21: publish [module 0x1.A {] +task 1 lines 23-38: run [import 0x1.A;] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.v2_exp deleted file mode 100644 index 69e4fd879d8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 23-38: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp index 70daa8491fb..6c2368bf99a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 18-31: +task 0 lines 1-16: publish [module 0x1.Test {] +task 1 lines 18-31: run [import 0x1.Test;] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.v2_exp deleted file mode 100644 index 70daa8491fb..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 18-31: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp index f0a3934dd7a..16dc79459b9 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 18-30: +task 0 lines 1-16: publish [module 0x1.A {] +task 1 lines 18-30: run [import 0x1.A;] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.v2_exp deleted file mode 100644 index f0a3934dd7a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 18-30: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp index 2301000e50a..164bdf00c2a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp @@ -1 +1,7 @@ processed 6 tasks +task 0 lines 1-14: publish [module 0x1.A {] +task 1 lines 17-30: publish [module 0x1.A {] +task 2 lines 32-45: publish [module 0x1.A {] +task 3 lines 47-60: publish [module 0x1.A {] +task 4 lines 62-75: publish [module 0x1.A {] +task 5 lines 77-90: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.v2_exp deleted file mode 100644 index 2301000e50a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 6 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp index 14f3442e133..36994fe20d8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 1 'publish'. lines 17-30: +task 1 lines 17-30: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 2 'publish'. lines 32-45: +task 2 lines 32-45: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 3 'publish'. lines 47-60: +task 3 lines 47-60: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 4 'publish'. lines 62-75: +task 4 lines 62-75: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -44,8 +39,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 5 'publish'. lines 77-90: +task 5 lines 77-90: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.v2_exp deleted file mode 100644 index 14f3442e133..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_negative.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 1 'publish'. lines 17-30: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 2 'publish'. lines 32-45: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 3 'publish'. lines 47-60: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 4 'publish'. lines 62-75: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 5 'publish'. lines 77-90: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp index e3e8ca2c39a..c607c726d56 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 1 'publish'. lines 17-30: +task 1 lines 17-30: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 2 'publish'. lines 32-45: +task 2 lines 32-45: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 3 'publish'. lines 47-60: +task 3 lines 47-60: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 4 'publish'. lines 62-75: +task 4 lines 62-75: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -44,8 +39,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 1)], offsets: [(FunctionDefinitionIndex(1), 0)], } - -task 5 'publish'. lines 77-90: +task 5 lines 77-90: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.v2_exp deleted file mode 100644 index e3e8ca2c39a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/integer_stack_positive.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 1 'publish'. lines 17-30: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 2 'publish'. lines 32-45: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 3 'publish'. lines 47-60: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 4 'publish'. lines 62-75: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} - -task 5 'publish'. lines 77-90: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp index 01c291322c9..3ed3512b86b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'run'. lines 1-6: +task 0 lines 1-6: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'run'. lines 8-13: +task 1 lines 8-13: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 2 'run'. lines 15-20: +task 2 lines 15-20: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 3 'run'. lines 22-27: +task 3 lines 22-27: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 4 'run'. lines 29-34: +task 4 lines 29-34: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 5 'run'. lines 36-41: +task 5 lines 36-41: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.v2_exp deleted file mode 100644 index 01c291322c9..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/load_positive_stack.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'run'. lines 1-6: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'run'. lines 8-13: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 2 'run'. lines 15-20: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 3 'run'. lines 22-27: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 4 'run'. lines 29-34: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 5 'run'. lines 36-41: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp index 91529eed122..15779983a19 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-10: +task 0 lines 1-10: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.v2_exp deleted file mode 100644 index 91529eed122..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-10: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp index 39f276bf0c9..5e60d730019 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.v2_exp deleted file mode 100644 index 39f276bf0c9..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp index 5d92c423f3f..fe9491d23b9 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-21: publish [module 0x1.Test {] +task 1 lines 23-41: run [import 0x1.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp index a9b16505dbd..af6253d496e 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 23-43: +task 0 lines 1-21: publish [module 0x1.Test {] +task 1 lines 23-43: run [import 0x1.Test;] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.v2_exp deleted file mode 100644 index a9b16505dbd..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 23-43: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp index 892b8117ea3..2e06304e751 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-22: +task 0 lines 1-22: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.v2_exp deleted file mode 100644 index 892b8117ea3..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp index 69e4fd879d8..fa1c9c931ec 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 23-38: +task 0 lines 1-21: publish [module 0x1.Test {] +task 1 lines 23-38: run [import 0x1.Test;] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.v2_exp deleted file mode 100644 index 69e4fd879d8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 23-38: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp index e7dbcda0a66..649045f617d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-22: +task 0 lines 1-22: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.v2_exp deleted file mode 100644 index e7dbcda0a66..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.exp index 6cd67db3f64..473cf0e866c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: publish [module 0x1.A {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_exact.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.exp index 559dd06120b..8c0c49799e1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.v2_exp deleted file mode 100644 index 559dd06120b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_negative.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.exp index 269d1dd064a..127b556d000 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x1.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.v2_exp deleted file mode 100644 index 269d1dd064a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/pop_positive.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::A, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.exp index d385bf5798e..2440ea2be9f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'publish'. lines 15-24: +task 1 lines 15-24: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.v2_exp deleted file mode 100644 index d385bf5798e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_extra_arg.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'publish'. lines 15-24: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.exp index 5cf0785cbdc..1797b9bd165 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'publish'. lines 13-22: +task 1 lines 13-22: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.v2_exp deleted file mode 100644 index 5cf0785cbdc..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_resource.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'publish'. lines 13-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::N, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.exp index 5cf0785cbdc..1797b9bd165 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'publish'. lines 13-22: +task 1 lines 13-22: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.v2_exp deleted file mode 100644 index 5cf0785cbdc..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_missing_signer.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'publish'. lines 13-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::N, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.exp index 773ae7b550b..52d9c87bd42 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'publish'. lines 12-21: +task 1 lines 12-21: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.v2_exp deleted file mode 100644 index 773ae7b550b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/signer_move_to_no_args.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'publish'. lines 12-21: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::N, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp index 99f3813d692..9daf041e429 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-23: +task 0 lines 1-23: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.v2_exp deleted file mode 100644 index 99f3813d692..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp index 49c6e9980cc..7ced75553bc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-23: +task 0 lines 1-23: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.v2_exp deleted file mode 100644 index 49c6e9980cc..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp index 364055d4b5c..7826aa856d5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'run'. lines 9-15: +task 1 lines 9-15: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 2 'run'. lines 17-25: +task 2 lines 17-25: run [main() {] Error: Script execution failed with VMError: { major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 3 'run'. lines 27-35: +task 3 lines 27-35: run [main() {] Error: Script execution failed with VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.v2_exp deleted file mode 100644 index 364055d4b5c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'run'. lines 1-7: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'run'. lines 9-15: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 2 'run'. lines 17-25: -Error: Script execution failed with VMError: { - major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 3 'run'. lines 27-35: -Error: Script execution failed with VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.exp index 5d92c423f3f..dddea8af70a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-8: publish [module 0x42.M {] +task 1 lines 10-19: run [import 0x42.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/module_struct_shared_name.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.exp index e6cc45c48b1..fbb94135af3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-6: +task 0 lines 1-6: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.v2_exp deleted file mode 100644 index e6cc45c48b1..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/mutual_recursive_struct.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-6: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x42::M, - indices: [(StructDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.exp index 67e995bfc2f..a1cc5405f35 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.exp @@ -1,6 +1,6 @@ processed 6 tasks - -task 1 'publish'. lines 10-14: +task 0 lines 1-8: publish [module 0x1.Cup {] +task 1 lines 10-14: publish [module 0x1.M0 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M0'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, @@ -8,8 +8,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 2 'publish'. lines 16-28: +task 2 lines 16-28: publish [module 0x1.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, @@ -17,8 +16,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 3 'publish'. lines 30-49: +task 3 lines 30-49: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, @@ -26,8 +24,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 4 'publish'. lines 51-58: +task 4 lines 51-58: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, @@ -35,8 +32,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 5 'publish'. lines 60-70: +task 5 lines 60-70: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: RECURSIVE_STRUCT_DEFINITION, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.v2_exp deleted file mode 100644 index 67e995bfc2f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/recursive_struct.v2_exp +++ /dev/null @@ -1,46 +0,0 @@ -processed 6 tasks - -task 1 'publish'. lines 10-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M0'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x1::M0, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 2 'publish'. lines 16-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x1::M1, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 3 'publish'. lines 30-49: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x1::M2, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 4 'publish'. lines 51-58: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x1::M3, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 5 'publish'. lines 60-70: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: RECURSIVE_STRUCT_DEFINITION, - sub_status: None, - location: 0x1::M3, - indices: [(StructDefinition, 3)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.exp index 1457d52cadf..a936650db2a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-4: +task 0 lines 1-4: publish [module 0x42.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 1 'publish'. lines 6-9: +task 1 lines 6-9: publish [module 0x42.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 2 'publish'. lines 11-14: +task 2 lines 11-14: publish [module 0x42.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 3 'publish'. lines 16-19: +task 3 lines 16-19: publish [module 0x42.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { major_status: INVALID_SIGNATURE_TOKEN, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.v2_exp deleted file mode 100644 index 1457d52cadf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/struct_defs/ref_in_struct.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-4: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x42::M1, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 1 'publish'. lines 6-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x42::M2, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 2 'publish'. lines 11-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x42::M3, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 3 'publish'. lines 16-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { - major_status: INVALID_SIGNATURE_TOKEN, - sub_status: None, - location: 0x42::M4, - indices: [(StructDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/tests.rs b/third_party/move/move-bytecode-verifier/transactional-tests/tests/tests.rs index 68a9a2fb9aa..7e626cf2896 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/tests.rs +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/tests.rs @@ -2,7 +2,102 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -pub const TEST_DIR: &str = "tests"; -use move_transactional_test_runner::vm_test_harness::run_test; +use libtest_mimic::{Arguments, Trial}; +use move_transactional_test_runner::{vm_test_harness, vm_test_harness::TestRunConfig}; +use once_cell::sync::Lazy; +use std::{ + default::Default, + path::{Path, PathBuf}, +}; +use walkdir::WalkDir; -datatest_stable::harness!(run_test, TEST_DIR, r".*\.(mvir|move)$"); +#[derive(Clone)] +struct TestConfig { + name: &'static str, + /// Path substrings for tests to include. If empty, all tests are included. + include: &'static [&'static str], + /// Path substrings for tests to exclude (applied after the include filter). + /// If empty, no additional tests are excluded. + exclude: &'static [&'static str], +} + +/// Note that any config which has different output for a test directory *must* be added to the +/// [SEPARATE_BASELINE] array below, so that a special output file `test.foo.exp` will be used for +/// outputs comparison when running `test.move` or `test.mvir` for config "foo". +static TEST_CONFIGS: Lazy> = Lazy::new(|| { + vec![TestConfig { + name: "baseline", + include: &[], + exclude: &[], + }] +}); + +/// Test files which must use separate baselines because their result is different. +/// +/// Note that each config named "foo" above will compare the output of running `test.move` (or +/// `test.masm`) to the same baseline file `test.exp` *unless* there is an entry in this array +/// matching the path of `test.move` or `test.masm`. If there is such an entry, then each config +/// "foo" will have a separate baseline output file `test.foo.exp`. +const SEPARATE_BASELINE: &[&str] = &[]; + +fn get_config_by_name(name: &str) -> TestConfig { + TEST_CONFIGS + .iter() + .find(|c| c.name == name) + .cloned() + .unwrap_or_else(|| panic!("undeclared test config `{}`", name)) +} + +fn run(path: &Path, config: TestConfig) -> datatest_stable::Result<()> { + let p = path.to_str().unwrap_or_default(); + let exp_suffix = if SEPARATE_BASELINE.iter().any(|s| p.contains(s)) { + Some(format!("{}.exp", config.name)) + } else { + None + }; + let config = TestRunConfig::default(); + vm_test_harness::run_test_with_config_and_exp_suffix(config, path, &exp_suffix) +} + +fn main() { + let files = WalkDir::new("tests") + .follow_links(false) + .min_depth(1) + .into_iter() + .flatten() + .filter_map(|e| { + let p = e.path().display().to_string(); + if p.ends_with(".move") || p.ends_with(".mvir") || p.ends_with(".masm") { + Some(p) + } else { + None + } + }) + .collect::>(); + let mut tests = TEST_CONFIGS + .iter() + .flat_map(|config| { + files + .iter() + .filter(|file| { + (config.include.is_empty() + || config.include.iter().any(|include| file.contains(include))) + && (!config.exclude.iter().any(|exclude| file.contains(exclude))) + }) + .map(move |file| { + let prompt = format!( + "move-bytecode-verifier-txn[config={}]::{}", + config.name, file + ); + let path = PathBuf::from(file); + Trial::test(prompt, move || { + run(&path, get_config_by_name(config.name)) + .map_err(|err| format!("{:?}", err).into()) + }) + }) + }) + .collect::>(); + tests.sort_unstable_by(|a, b| a.name().cmp(b.name())); + let args = Arguments::from_args(); + libtest_mimic::run(&args, tests).exit() +} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.exp index 509d5fddf0c..db45c1269b5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.v2_exp deleted file mode 100644 index 509d5fddf0c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.exp index 04ab2b89db9..2779efccaac 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.v2_exp deleted file mode 100644 index 04ab2b89db9..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_local_resource_twice.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.exp index a830d1e9baf..68b97960342 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x42.A {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.v2_exp deleted file mode 100644 index a830d1e9baf..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_resource_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x42::A, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.exp index 8020e634d57..dec8dd8d806 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.v2_exp deleted file mode 100644 index 8020e634d57..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/assign_wrong_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-7: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.exp index 887cbe5c1f8..1050987b2a2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.v2_exp deleted file mode 100644 index 887cbe5c1f8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/boolean_not_non_boolean.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.exp index 6cd67db3f64..e1bbd0c7a6f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-28: publish [module 0x1337::reproduce {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_notworking.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.exp index 6cd67db3f64..4ca57438823 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-22: publish [module 0x1337::reproduce {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/bug_9459_working.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.exp index 21025e25e7a..1085258bfa8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-48: +task 0 lines 1-48: publish [module 0x1.Token {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { major_status: READREF_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.v2_exp deleted file mode 100644 index 21025e25e7a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/cant_deref_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-48: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { - major_status: READREF_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::Token, - indices: [(FunctionDefinition, 4)], - offsets: [(FunctionDefinitionIndex(4), 13)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp index 8804a80a8b9..c6779564cd4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp @@ -1,6 +1,5 @@ processed 18 tasks - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run [// tests bad casts/integer conversions] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 1 'run'. lines 9-14: +task 1 lines 9-14: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 16-21: +task 2 lines 16-21: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'run'. lines 23-28: +task 3 lines 23-28: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 4 'run'. lines 30-35: +task 4 lines 30-35: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 5 'run'. lines 37-42: +task 5 lines 37-42: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -53,8 +47,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 6 'run'. lines 45-50: +task 6 lines 45-50: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -62,8 +55,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 7 'run'. lines 52-57: +task 7 lines 52-57: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -71,8 +63,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 8 'run'. lines 59-64: +task 8 lines 59-64: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -80,8 +71,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 9 'run'. lines 66-71: +task 9 lines 66-71: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -89,8 +79,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 10 'run'. lines 73-78: +task 10 lines 73-78: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -98,8 +87,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 11 'run'. lines 80-85: +task 11 lines 80-85: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -107,8 +95,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 12 'publish'. lines 88-96: +task 12 lines 88-96: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -116,8 +103,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 13 'publish'. lines 98-106: +task 13 lines 98-106: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -125,8 +111,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 14 'publish'. lines 108-116: +task 14 lines 108-116: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -134,8 +119,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 15 'publish'. lines 118-126: +task 15 lines 118-126: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -143,8 +127,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'publish'. lines 128-136: +task 16 lines 128-136: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -152,8 +135,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 17 'publish'. lines 138-146: +task 17 lines 138-146: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.v2_exp deleted file mode 100644 index 8804a80a8b9..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/casting_operators_types_mismatch.v2_exp +++ /dev/null @@ -1,163 +0,0 @@ -processed 18 tasks - -task 0 'run'. lines 1-7: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 1 'run'. lines 9-14: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 2 'run'. lines 16-21: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 3 'run'. lines 23-28: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 4 'run'. lines 30-35: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 5 'run'. lines 37-42: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 6 'run'. lines 45-50: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 7 'run'. lines 52-57: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 8 'run'. lines 59-64: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 9 'run'. lines 66-71: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 10 'run'. lines 73-78: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 11 'run'. lines 80-85: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 12 'publish'. lines 88-96: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 13 'publish'. lines 98-106: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 14 'publish'. lines 108-116: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 15 'publish'. lines 118-126: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 16 'publish'. lines 128-136: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 17 'publish'. lines 138-146: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.exp index 48938fbb132..27d042a997b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: READREF_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.v2_exp deleted file mode 100644 index 48938fbb132..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_non_reference.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: READREF_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.exp index 52031e1a9ce..fa1ea89809c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-9: +task 0 lines 1-9: run [main() {] Error: Script execution failed with VMError: { major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.v2_exp deleted file mode 100644 index 52031e1a9ce..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/deref_not_reference_bad.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-9: -Error: Script execution failed with VMError: { - major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.exp index 9029cccd468..ad45e89cf10 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.exp @@ -1,4 +1,4 @@ processed 2 tasks - -task 1 'run'. lines 22-33: +task 0 lines 1-20: publish [module 0x42.A {] +task 1 lines 22-33: run [import 0x42.A;] Error: Unbound module alias Diem diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.v2_exp deleted file mode 100644 index 9029cccd468..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/destroy_resource_holder.v2_exp +++ /dev/null @@ -1,4 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 22-33: -Error: Unbound module alias Diem diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.exp index 96059e4c886..c8efe0112c9 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.v2_exp deleted file mode 100644 index 96059e4c886..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_one_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-11: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.exp index 5d92c423f3f..7661de790cc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-16: publish [module 0x1.Token {] +task 1 lines 18-25: run [import 0x1.Token;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_refs.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.exp index 9f367810cba..76a999909a3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.Token {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.v2_exp deleted file mode 100644 index 9f367810cba..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/equality_resource_values.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x1::Token, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.exp index 6afb8900a4f..57759946429 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-13: +task 0 lines 1-13: run [main() {] Error: Script execution failed with VMError: { major_status: WRITEREF_NO_MUTABLE_REFERENCE_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.v2_exp deleted file mode 100644 index 6afb8900a4f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_makes_imm.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-13: -Error: Script execution failed with VMError: { - major_status: WRITEREF_NO_MUTABLE_REFERENCE_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 9)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.exp index ab1dba46f71..7342ce51f3f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-12: +task 0 lines 1-12: run [main() {] Error: Script execution failed with VMError: { major_status: FREEZEREF_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.v2_exp deleted file mode 100644 index ab1dba46f71..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_on_imm.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-12: -Error: Script execution failed with VMError: { - major_status: FREEZEREF_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.exp index 6cd67db3f64..76d74b23566 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: run [main() {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.exp index 60ba13b716a..9eaa8cfac62 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-13: +task 0 lines 1-13: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.v2_exp deleted file mode 100644 index 60ba13b716a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/freeze_wrong_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-13: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp index 6cd67db3f64..17de1329064 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-19: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_field.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.exp index bf502bcfc4a..625599bd4a5 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.v2_exp deleted file mode 100644 index bf502bcfc4a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.exp index 849d979b310..40cfc867087 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.v2_exp deleted file mode 100644 index 849d979b310..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_borrow_global_mut.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.exp index 69762fde129..40823caf4ed 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-15: +task 0 lines 1-15: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.v2_exp deleted file mode 100644 index 69762fde129..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_call.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-15: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.exp index 3f42db671be..fcf1dd67e61 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.v2_exp deleted file mode 100644 index 3f42db671be..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_exists.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp index 6cd67db3f64..a253a4b9848 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-22: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.exp index 6cd67db3f64..0b5768b09bc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_pack.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp index 6e22edc070f..acc8ff7abfd 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.v2_exp deleted file mode 100644 index 6e22edc070f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp index 1a4232f2815..736f685a6ad 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.v2_exp deleted file mode 100644 index 1a4232f2815..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_all.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp index 1a4232f2815..736f685a6ad 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.v2_exp deleted file mode 100644 index 1a4232f2815..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_type_param_resource.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.exp index 59701471c16..209d05565ef 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.v2_exp deleted file mode 100644 index 59701471c16..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_abilities_unpack.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.exp index 6cd67db3f64..93428bca909 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-56: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_builtins.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.exp index 6cd67db3f64..ed9625ec60d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-23: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_call.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.exp index 6cd67db3f64..27b637a261f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-9: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp index 6cd67db3f64..3760663f9e2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-14: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_field_borrow_after_call.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.exp index 6cd67db3f64..0785bd20925 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-19: publish [// This test checks that for each function definition] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_function_def.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.exp index 5d92c423f3f..53eaee84f20 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-7: publish [module 0x1.M {] +task 1 lines 11-21: run [import 0x1.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_id_function.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.exp index 7c332969013..d5d85426190 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.exp @@ -1,6 +1,6 @@ processed 3 tasks - -task 1 'run'. lines 21-28: +task 0 lines 1-19: publish [module 0x1.M {] +task 1 lines 21-28: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), @@ -8,8 +8,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'run'. lines 30-37: +task 2 lines 30-37: run [import 0x1.M;] Error: Script execution failed with VMError: { major_status: ABORTED, sub_status: Some(0), diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.v2_exp deleted file mode 100644 index 7c332969013..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_function.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 3 tasks - -task 1 'run'. lines 21-28: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: 0x1::M, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 2 'run'. lines 30-37: -Error: Script execution failed with VMError: { - major_status: ABORTED, - sub_status: Some(0), - location: 0x1::M, - indices: [], - offsets: [(FunctionDefinitionIndex(1), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.exp index fc5a4436b29..ae0c5e003fb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-6: publish [module 0x1.M {] +task 1 lines 8-15: run [import 0x1.M;] +task 2 lines 17-24: run [import 0x1.M;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_import_struct.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.exp index 6cd67db3f64..ba4cd37d4d3 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-39: publish [// example using generics in a few common/interesting/non-trivial ways] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_option.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.exp index 5d92c423f3f..666b16f5fdb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x1.M {] +task 1 lines 13-24: publish [module 0x1.N {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_pack.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.exp index 6cd67db3f64..5df83ac0e02 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-10: publish [// This test checks that for each struct definition] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_struct_def.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.exp index 5d92c423f3f..128f36ff785 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-11: publish [module 0x1.M {] +task 1 lines 13-25: publish [module 0x1.N {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/generic_unpack.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.exp index 367e3b6d0b8..e69de29bb2d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.exp @@ -1,11 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-93: -Error: compilation errors: - error: Only inline functions may have function-typed parameters, but non-inline function `test_case::for_each_ref` has a function parameter: - ┌─ TEMPFILE:9:16 - │ -9 │ public fun for_each_ref(v: &vector, f: |&Element|) { - │ ^^^^^^^^^^^^ - Parameter `f` has function-valued type `|&Element|`. - - diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.move b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.move deleted file mode 100644 index a0a1d27cdb5..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.move +++ /dev/null @@ -1,93 +0,0 @@ -//# publish -// Try to pass a lambda to a non-inline function by mistake. -// Should generate an error. -module 0x42::test_case { - use std::vector; - - /// The index into the vector is out of bounds - const EINVALID_RANGE: u64 = 0x20001; - - /// Apply the function to a reference of each element in the vector. - public fun for_each_ref(v: &vector, f: |&Element|) { - let i = 0; - while (i < vector::length(v)) { - f(vector::borrow(v, i)); - i = i + 1 - } - } - - /// Map the function over the references of the elements of the vector, producing a new vector without modifying the - /// original map. - public inline fun map_ref( - v: &vector, - f: |&Element|NewElement - ): vector { - let result = vector[]; - for_each_ref(v, |elem| vector::push_back(&mut result, f(elem))); - result - } - - /// Reverses the order of the elements [left, right) in the vector `v` in place. - public fun reverse_slice(v: &mut vector, left: u64, right: u64) { - assert!(left <= right, EINVALID_RANGE); - if (left == right) return; - right = right - 1; - while (left < right) { - vector::swap(v, left, right); - left = left + 1; - right = right - 1; - } - } - /// Same as above but on a sub-slice of an array [left, right) with left <= rot <= right - /// returns the - public fun rotate_slice( - v: &mut vector, - left: u64, - rot: u64, - right: u64 - ): u64 { - reverse_slice(v, left, rot); - reverse_slice(v, rot, right); - reverse_slice(v, left, right); - left + (right - rot) - } - - /// For in-place stable partition we need recursion so we cannot use inline functions - /// and thus we cannot use lambdas. Luckily it so happens that we can precompute the predicate - /// in a secondary array. Note how the algorithm belows only start shuffling items after the - /// predicate is checked. - public fun stable_partition_internal( - v: &mut vector, - pred: &vector, - left: u64, - right: u64 - ): u64 { - if (left == right) { - left - } else if (left + 1 == right) { - if (*vector::borrow(pred, left)) right else left - } else { - let mid = left + ((right - left) >> 1); - let p1 = stable_partition_internal(v, pred, left, mid); - let p2 = stable_partition_internal(v, pred, mid, right); - rotate_slice(v, p1, mid, p2) - } - } - - /// Partition the array based on a predicate p, this routine is stable and thus - /// preserves the relative order of the elements in the two partitions. - public inline fun stable_partition( - v: &mut vector, - p: |&Element|bool - ): u64 { - let pred = map_ref(v, |e| p(e)); - let len = vector::length(v); - stable_partition_internal(v, &pred,0, len) - } - - fun test_stable_partition() { - let v = vector[1, 2, 3, 4, 5]; - assert!(stable_partition(&mut v, |n| *n % 2 == 0) == 2, 0); - assert!(&v == &vector[2, 4, 1, 3, 5], 1); - } -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.v2_exp deleted file mode 100644 index 367e3b6d0b8..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test.v2_exp +++ /dev/null @@ -1,11 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-93: -Error: compilation errors: - error: Only inline functions may have function-typed parameters, but non-inline function `test_case::for_each_ref` has a function parameter: - ┌─ TEMPFILE:9:16 - │ -9 │ public fun for_each_ref(v: &vector, f: |&Element|) { - │ ^^^^^^^^^^^^ - Parameter `f` has function-valued type `|&Element|`. - - diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.exp index 6cd67db3f64..e69de29bb2d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.exp @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.move b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.move deleted file mode 100644 index 0027b0e024c..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.move +++ /dev/null @@ -1,93 +0,0 @@ -//# publish -// Should succeed. -module 0x42::test_case { - use std::vector; - - /// The index into the vector is out of bounds - const EINVALID_RANGE: u64 = 0x20001; - - /// Apply the function to a reference of each element in the vector. - public inline fun for_each_ref(v: &vector, f: |&Element|) { - let i = 0; - while (i < vector::length(v)) { - f(vector::borrow(v, i)); - i = i + 1 - } - } - - /// Map the function over the references of the elements of the vector, producing a new vector without modifying the - /// original map. - public inline fun map_ref( - v: &vector, - f: |&Element|NewElement - ): vector { - let result = vector[]; - for_each_ref(v, |elem| vector::push_back(&mut result, f(elem))); - result - } - - /// Reverses the order of the elements [left, right) in the vector `v` in place. - public fun reverse_slice(v: &mut vector, left: u64, right: u64) { - assert!(left <= right, EINVALID_RANGE); - if (left == right) return; - right = right - 1; - while (left < right) { - vector::swap(v, left, right); - left = left + 1; - right = right - 1; - } - } - /// Same as above but on a sub-slice of an array [left, right) with left <= rot <= right - /// returns the - public fun rotate_slice( - v: &mut vector, - left: u64, - rot: u64, - right: u64 - ): u64 { - reverse_slice(v, left, rot); - reverse_slice(v, rot, right); - reverse_slice(v, left, right); - left + (right - rot) - } - - /// For in-place stable partition we need recursion so we cannot use inline functions - /// and thus we cannot use lambdas. Luckily it so happens that we can precompute the predicate - /// in a secondary array. Note how the algorithm belows only start shuffling items after the - /// predicate is checked. - public fun stable_partition_internal( - v: &mut vector, - pred: &vector, - left: u64, - right: u64 - ): u64 { - if (left == right) { - left - } else if (left + 1 == right) { - if (*vector::borrow(pred, left)) right else left - } else { - let mid = left + ((right - left) >> 1); - let p1 = stable_partition_internal(v, pred, left, mid); - let p2 = stable_partition_internal(v, pred, mid, right); - rotate_slice(v, p1, mid, p2) - } - } - - /// Partition the array based on a predicate p, this routine is stable and thus - /// preserves the relative order of the elements in the two partitions. - public inline fun stable_partition( - v: &mut vector, - p: |&Element|bool - ): u64 { - let pred = map_ref(v, |e| p(e)); - let len = vector::length(v); - stable_partition_internal(v, &pred,0, len) - } - - fun test_stable_partition() { - let v = vector[1, 2, 3, 4, 5]; - let t = stable_partition(&mut v, |n| *n % 2 == 0); - assert!(t == 2, 0); - assert!(&v == &vector[2, 4, 1, 3, 5], 1); - } -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/gerbens_test1.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp index 13167fe2e24..556afe8c581 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp @@ -1,6 +1,5 @@ processed 191 tasks - -task 0 'run'. lines 1-11: +task 0 lines 1-11: run [// tests multiple type mismatches for int operations] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 1 'run'. lines 14-19: +task 1 lines 14-19: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 2 'run'. lines 22-27: +task 2 lines 22-27: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 3 'run'. lines 30-35: +task 3 lines 30-35: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'run'. lines 38-43: +task 4 lines 38-43: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 5 'run'. lines 46-51: +task 5 lines 46-51: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -53,8 +47,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 6 'run'. lines 54-59: +task 6 lines 54-59: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -62,8 +55,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 7 'run'. lines 62-67: +task 7 lines 62-67: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -71,8 +63,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 8 'run'. lines 70-75: +task 8 lines 70-75: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -80,8 +71,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 9 'run'. lines 78-83: +task 9 lines 78-83: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -89,8 +79,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 10 'run'. lines 86-91: +task 10 lines 86-91: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -98,8 +87,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 11 'run'. lines 94-99: +task 11 lines 94-99: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -107,8 +95,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 12 'publish'. lines 102-110: +task 12 lines 102-110: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -116,8 +103,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 13 'publish'. lines 112-120: +task 13 lines 112-120: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -125,8 +111,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 14 'publish'. lines 122-134: +task 14 lines 122-134: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -134,8 +119,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 15 'run'. lines 135-140: +task 15 lines 135-140: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -143,8 +127,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 16 'run'. lines 143-148: +task 16 lines 143-148: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -152,8 +135,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 17 'run'. lines 151-156: +task 17 lines 151-156: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -161,8 +143,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 18 'run'. lines 159-164: +task 18 lines 159-164: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -170,8 +151,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 19 'run'. lines 167-172: +task 19 lines 167-172: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -179,8 +159,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 20 'run'. lines 175-180: +task 20 lines 175-180: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -188,8 +167,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 21 'run'. lines 183-188: +task 21 lines 183-188: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -197,8 +175,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 22 'run'. lines 191-196: +task 22 lines 191-196: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -206,8 +183,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 23 'run'. lines 199-204: +task 23 lines 199-204: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -215,8 +191,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 24 'run'. lines 207-212: +task 24 lines 207-212: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -224,8 +199,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 25 'run'. lines 215-220: +task 25 lines 215-220: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -233,8 +207,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 26 'run'. lines 223-228: +task 26 lines 223-228: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -242,8 +215,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 27 'publish'. lines 231-239: +task 27 lines 231-239: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -251,8 +223,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 28 'publish'. lines 241-249: +task 28 lines 241-249: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -260,8 +231,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 29 'publish'. lines 251-263: +task 29 lines 251-263: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -269,8 +239,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 30 'run'. lines 264-269: +task 30 lines 264-269: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -278,8 +247,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 31 'run'. lines 272-277: +task 31 lines 272-277: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -287,8 +255,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 32 'run'. lines 280-285: +task 32 lines 280-285: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -296,8 +263,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 33 'run'. lines 288-293: +task 33 lines 288-293: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -305,8 +271,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 34 'run'. lines 296-301: +task 34 lines 296-301: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -314,8 +279,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 35 'run'. lines 304-309: +task 35 lines 304-309: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -323,8 +287,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 36 'run'. lines 312-317: +task 36 lines 312-317: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -332,8 +295,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 37 'run'. lines 320-325: +task 37 lines 320-325: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -341,8 +303,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 38 'run'. lines 328-333: +task 38 lines 328-333: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -350,8 +311,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 39 'run'. lines 336-341: +task 39 lines 336-341: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -359,8 +319,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 40 'run'. lines 344-349: +task 40 lines 344-349: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -368,8 +327,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 41 'run'. lines 352-357: +task 41 lines 352-357: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -377,8 +335,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 42 'publish'. lines 360-368: +task 42 lines 360-368: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -386,8 +343,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 43 'publish'. lines 370-378: +task 43 lines 370-378: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -395,8 +351,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 44 'publish'. lines 380-392: +task 44 lines 380-392: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -404,8 +359,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 45 'run'. lines 393-398: +task 45 lines 393-398: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -413,8 +367,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 46 'run'. lines 401-406: +task 46 lines 401-406: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -422,8 +375,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 47 'run'. lines 409-414: +task 47 lines 409-414: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -431,8 +383,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 48 'run'. lines 417-422: +task 48 lines 417-422: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -440,8 +391,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 49 'run'. lines 425-430: +task 49 lines 425-430: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -449,8 +399,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 50 'run'. lines 433-438: +task 50 lines 433-438: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -458,8 +407,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 51 'run'. lines 441-446: +task 51 lines 441-446: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -467,8 +415,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 52 'run'. lines 449-454: +task 52 lines 449-454: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -476,8 +423,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 53 'run'. lines 457-462: +task 53 lines 457-462: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -485,8 +431,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 54 'run'. lines 465-470: +task 54 lines 465-470: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -494,8 +439,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 55 'run'. lines 473-478: +task 55 lines 473-478: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -503,8 +447,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 56 'run'. lines 481-486: +task 56 lines 481-486: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -512,8 +455,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 57 'publish'. lines 489-497: +task 57 lines 489-497: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -521,8 +463,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 58 'publish'. lines 499-507: +task 58 lines 499-507: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -530,8 +471,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 59 'publish'. lines 509-521: +task 59 lines 509-521: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -539,8 +479,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 60 'run'. lines 522-527: +task 60 lines 522-527: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -548,8 +487,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 61 'run'. lines 530-535: +task 61 lines 530-535: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -557,8 +495,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 62 'run'. lines 538-543: +task 62 lines 538-543: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -566,8 +503,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 63 'run'. lines 546-551: +task 63 lines 546-551: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -575,8 +511,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 64 'run'. lines 554-559: +task 64 lines 554-559: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -584,8 +519,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 65 'run'. lines 562-567: +task 65 lines 562-567: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -593,8 +527,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 66 'run'. lines 570-575: +task 66 lines 570-575: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -602,8 +535,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 67 'run'. lines 578-583: +task 67 lines 578-583: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -611,8 +543,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 68 'run'. lines 586-591: +task 68 lines 586-591: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -620,8 +551,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 69 'run'. lines 594-599: +task 69 lines 594-599: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -629,8 +559,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 70 'run'. lines 602-607: +task 70 lines 602-607: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -638,8 +567,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 71 'run'. lines 610-615: +task 71 lines 610-615: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -647,8 +575,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 72 'publish'. lines 618-626: +task 72 lines 618-626: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -656,8 +583,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 73 'publish'. lines 628-636: +task 73 lines 628-636: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -665,8 +591,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 74 'publish'. lines 638-650: +task 74 lines 638-650: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -674,8 +599,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 75 'run'. lines 651-656: +task 75 lines 651-656: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -683,8 +607,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 76 'run'. lines 659-664: +task 76 lines 659-664: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -692,8 +615,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 77 'run'. lines 667-672: +task 77 lines 667-672: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -701,8 +623,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 78 'run'. lines 675-680: +task 78 lines 675-680: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -710,8 +631,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 79 'run'. lines 683-688: +task 79 lines 683-688: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -719,8 +639,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 80 'run'. lines 691-696: +task 80 lines 691-696: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -728,8 +647,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 81 'run'. lines 699-704: +task 81 lines 699-704: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -737,8 +655,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 82 'run'. lines 707-712: +task 82 lines 707-712: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -746,8 +663,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 83 'run'. lines 715-720: +task 83 lines 715-720: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -755,8 +671,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 84 'run'. lines 723-728: +task 84 lines 723-728: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -764,8 +679,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 85 'run'. lines 731-736: +task 85 lines 731-736: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -773,8 +687,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 86 'run'. lines 739-744: +task 86 lines 739-744: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -782,8 +695,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 87 'publish'. lines 747-755: +task 87 lines 747-755: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -791,8 +703,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 88 'publish'. lines 757-765: +task 88 lines 757-765: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -800,8 +711,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 89 'publish'. lines 767-779: +task 89 lines 767-779: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -809,8 +719,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 90 'run'. lines 780-785: +task 90 lines 780-785: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -818,8 +727,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 91 'run'. lines 788-793: +task 91 lines 788-793: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -827,8 +735,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 92 'run'. lines 796-801: +task 92 lines 796-801: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -836,8 +743,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 93 'run'. lines 804-809: +task 93 lines 804-809: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -845,8 +751,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 94 'run'. lines 812-817: +task 94 lines 812-817: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -854,8 +759,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 95 'run'. lines 820-825: +task 95 lines 820-825: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -863,8 +767,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 96 'run'. lines 828-833: +task 96 lines 828-833: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -872,8 +775,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 97 'run'. lines 836-841: +task 97 lines 836-841: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -881,8 +783,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 98 'run'. lines 844-849: +task 98 lines 844-849: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -890,8 +791,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 99 'run'. lines 852-857: +task 99 lines 852-857: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -899,8 +799,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 100 'run'. lines 860-865: +task 100 lines 860-865: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -908,8 +807,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 101 'run'. lines 868-873: +task 101 lines 868-873: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -917,8 +815,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 102 'publish'. lines 876-884: +task 102 lines 876-884: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -926,8 +823,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 103 'publish'. lines 886-894: +task 103 lines 886-894: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -935,8 +831,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 104 'publish'. lines 896-908: +task 104 lines 896-908: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -944,8 +839,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 105 'run'. lines 909-914: +task 105 lines 909-914: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -953,8 +847,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 106 'run'. lines 917-922: +task 106 lines 917-922: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -962,8 +855,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 107 'run'. lines 925-930: +task 107 lines 925-930: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -971,8 +863,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 108 'run'. lines 933-938: +task 108 lines 933-938: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -980,8 +871,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 109 'run'. lines 941-946: +task 109 lines 941-946: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -989,8 +879,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 110 'run'. lines 949-954: +task 110 lines 949-954: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -998,8 +887,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 111 'run'. lines 957-962: +task 111 lines 957-962: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1007,8 +895,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 112 'run'. lines 965-970: +task 112 lines 965-970: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1016,8 +903,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 113 'run'. lines 973-978: +task 113 lines 973-978: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1025,8 +911,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 114 'run'. lines 981-986: +task 114 lines 981-986: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1034,8 +919,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 115 'publish'. lines 989-997: +task 115 lines 989-997: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1043,8 +927,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 116 'publish'. lines 999-1010: +task 116 lines 999-1010: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1052,8 +935,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 117 'run'. lines 1011-1016: +task 117 lines 1011-1016: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1061,8 +943,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 118 'run'. lines 1019-1024: +task 118 lines 1019-1024: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1070,8 +951,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 119 'run'. lines 1027-1032: +task 119 lines 1027-1032: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1079,8 +959,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 120 'run'. lines 1035-1040: +task 120 lines 1035-1040: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1088,8 +967,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 121 'run'. lines 1043-1048: +task 121 lines 1043-1048: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1097,8 +975,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 122 'run'. lines 1051-1056: +task 122 lines 1051-1056: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1106,8 +983,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 123 'run'. lines 1059-1064: +task 123 lines 1059-1064: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1115,8 +991,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 124 'run'. lines 1067-1072: +task 124 lines 1067-1072: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1124,8 +999,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 125 'run'. lines 1075-1080: +task 125 lines 1075-1080: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1133,8 +1007,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 126 'run'. lines 1083-1088: +task 126 lines 1083-1088: run [main() {] Error: Script execution failed with VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1142,8 +1015,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 127 'publish'. lines 1091-1099: +task 127 lines 1091-1099: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1151,8 +1023,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 128 'publish'. lines 1101-1113: +task 128 lines 1101-1113: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1160,8 +1031,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 129 'run'. lines 1114-1119: +task 129 lines 1114-1119: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1169,8 +1039,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 130 'run'. lines 1122-1127: +task 130 lines 1122-1127: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1178,8 +1047,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 131 'run'. lines 1130-1135: +task 131 lines 1130-1135: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1187,8 +1055,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 132 'run'. lines 1138-1143: +task 132 lines 1138-1143: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1196,8 +1063,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 133 'run'. lines 1146-1151: +task 133 lines 1146-1151: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1205,8 +1071,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 134 'run'. lines 1154-1159: +task 134 lines 1154-1159: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1214,8 +1079,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 135 'run'. lines 1162-1167: +task 135 lines 1162-1167: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1223,8 +1087,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 136 'run'. lines 1170-1175: +task 136 lines 1170-1175: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1232,8 +1095,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 137 'run'. lines 1178-1183: +task 137 lines 1178-1183: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1241,8 +1103,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 138 'run'. lines 1186-1194: +task 138 lines 1186-1194: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1250,8 +1111,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 139 'run'. lines 1195-1200: +task 139 lines 1195-1200: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1259,8 +1119,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 140 'run'. lines 1203-1208: +task 140 lines 1203-1208: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1268,8 +1127,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 141 'run'. lines 1211-1216: +task 141 lines 1211-1216: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1277,8 +1135,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 142 'run'. lines 1219-1224: +task 142 lines 1219-1224: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1286,8 +1143,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 143 'run'. lines 1227-1232: +task 143 lines 1227-1232: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1295,8 +1151,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 144 'run'. lines 1235-1240: +task 144 lines 1235-1240: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1304,8 +1159,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 145 'run'. lines 1243-1248: +task 145 lines 1243-1248: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1313,8 +1167,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 146 'run'. lines 1251-1256: +task 146 lines 1251-1256: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1322,8 +1175,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 147 'run'. lines 1259-1264: +task 147 lines 1259-1264: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1331,8 +1183,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 148 'run'. lines 1267-1275: +task 148 lines 1267-1275: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1340,8 +1191,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 149 'run'. lines 1276-1281: +task 149 lines 1276-1281: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1349,8 +1199,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 150 'run'. lines 1284-1289: +task 150 lines 1284-1289: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1358,8 +1207,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 151 'run'. lines 1292-1297: +task 151 lines 1292-1297: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1367,8 +1215,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 152 'run'. lines 1300-1305: +task 152 lines 1300-1305: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1376,8 +1223,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 153 'run'. lines 1308-1313: +task 153 lines 1308-1313: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1385,8 +1231,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 154 'run'. lines 1316-1321: +task 154 lines 1316-1321: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1394,8 +1239,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 155 'run'. lines 1324-1329: +task 155 lines 1324-1329: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1403,8 +1247,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 156 'run'. lines 1332-1337: +task 156 lines 1332-1337: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1412,8 +1255,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 157 'run'. lines 1340-1345: +task 157 lines 1340-1345: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1421,8 +1263,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 158 'run'. lines 1348-1356: +task 158 lines 1348-1356: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1430,8 +1271,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 159 'run'. lines 1357-1362: +task 159 lines 1357-1362: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1439,8 +1279,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 160 'run'. lines 1365-1370: +task 160 lines 1365-1370: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1448,8 +1287,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 161 'run'. lines 1373-1378: +task 161 lines 1373-1378: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1457,8 +1295,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 162 'run'. lines 1381-1386: +task 162 lines 1381-1386: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1466,8 +1303,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 163 'run'. lines 1389-1394: +task 163 lines 1389-1394: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1475,8 +1311,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 164 'run'. lines 1397-1402: +task 164 lines 1397-1402: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1484,8 +1319,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 165 'run'. lines 1405-1410: +task 165 lines 1405-1410: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1493,8 +1327,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 166 'run'. lines 1413-1418: +task 166 lines 1413-1418: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1502,8 +1335,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 167 'run'. lines 1421-1426: +task 167 lines 1421-1426: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1511,8 +1343,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 168 'run'. lines 1429-1437: +task 168 lines 1429-1437: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1520,8 +1351,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 169 'run'. lines 1438-1443: +task 169 lines 1438-1443: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1529,8 +1359,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 170 'run'. lines 1446-1451: +task 170 lines 1446-1451: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1538,8 +1367,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 171 'run'. lines 1454-1459: +task 171 lines 1454-1459: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1547,8 +1375,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 172 'run'. lines 1462-1467: +task 172 lines 1462-1467: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1556,8 +1383,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 173 'run'. lines 1470-1475: +task 173 lines 1470-1475: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1565,8 +1391,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 174 'run'. lines 1478-1483: +task 174 lines 1478-1483: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1574,8 +1399,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 175 'run'. lines 1486-1491: +task 175 lines 1486-1491: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1583,8 +1407,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 176 'run'. lines 1494-1499: +task 176 lines 1494-1499: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1592,8 +1415,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 177 'publish'. lines 1502-1510: +task 177 lines 1502-1510: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1601,8 +1423,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 178 'publish'. lines 1512-1520: +task 178 lines 1512-1520: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1610,8 +1431,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 179 'publish'. lines 1522-1534: +task 179 lines 1522-1534: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1619,8 +1439,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 180 'run'. lines 1535-1540: +task 180 lines 1535-1540: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1628,8 +1447,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 181 'run'. lines 1543-1548: +task 181 lines 1543-1548: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1637,8 +1455,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 182 'run'. lines 1551-1556: +task 182 lines 1551-1556: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1646,8 +1463,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 183 'run'. lines 1559-1564: +task 183 lines 1559-1564: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1655,8 +1471,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 184 'run'. lines 1567-1572: +task 184 lines 1567-1572: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1664,8 +1479,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 185 'run'. lines 1575-1580: +task 185 lines 1575-1580: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1673,8 +1487,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 186 'run'. lines 1583-1588: +task 186 lines 1583-1588: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1682,8 +1495,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 187 'run'. lines 1591-1596: +task 187 lines 1591-1596: run [main() {] Error: Script execution failed with VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1691,8 +1503,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 188 'publish'. lines 1599-1607: +task 188 lines 1599-1607: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1700,8 +1511,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 189 'publish'. lines 1609-1617: +task 189 lines 1609-1617: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, @@ -1709,8 +1519,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 190 'publish'. lines 1619-1627: +task 190 lines 1619-1627: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.v2_exp deleted file mode 100644 index 13167fe2e24..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.v2_exp +++ /dev/null @@ -1,1720 +0,0 @@ -processed 191 tasks - -task 0 'run'. lines 1-11: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 1 'run'. lines 14-19: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 2 'run'. lines 22-27: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 3 'run'. lines 30-35: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 4 'run'. lines 38-43: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 5 'run'. lines 46-51: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 6 'run'. lines 54-59: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 7 'run'. lines 62-67: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 8 'run'. lines 70-75: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 9 'run'. lines 78-83: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 10 'run'. lines 86-91: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 11 'run'. lines 94-99: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 12 'publish'. lines 102-110: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 13 'publish'. lines 112-120: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 14 'publish'. lines 122-134: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 15 'run'. lines 135-140: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 16 'run'. lines 143-148: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 17 'run'. lines 151-156: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 18 'run'. lines 159-164: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 19 'run'. lines 167-172: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 20 'run'. lines 175-180: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 21 'run'. lines 183-188: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 22 'run'. lines 191-196: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 23 'run'. lines 199-204: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 24 'run'. lines 207-212: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 25 'run'. lines 215-220: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 26 'run'. lines 223-228: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 27 'publish'. lines 231-239: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 28 'publish'. lines 241-249: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 29 'publish'. lines 251-263: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 30 'run'. lines 264-269: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 31 'run'. lines 272-277: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 32 'run'. lines 280-285: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 33 'run'. lines 288-293: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 34 'run'. lines 296-301: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 35 'run'. lines 304-309: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 36 'run'. lines 312-317: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 37 'run'. lines 320-325: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 38 'run'. lines 328-333: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 39 'run'. lines 336-341: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 40 'run'. lines 344-349: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 41 'run'. lines 352-357: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 42 'publish'. lines 360-368: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 43 'publish'. lines 370-378: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 44 'publish'. lines 380-392: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 45 'run'. lines 393-398: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 46 'run'. lines 401-406: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 47 'run'. lines 409-414: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 48 'run'. lines 417-422: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 49 'run'. lines 425-430: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 50 'run'. lines 433-438: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 51 'run'. lines 441-446: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 52 'run'. lines 449-454: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 53 'run'. lines 457-462: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 54 'run'. lines 465-470: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 55 'run'. lines 473-478: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 56 'run'. lines 481-486: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 57 'publish'. lines 489-497: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 58 'publish'. lines 499-507: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 59 'publish'. lines 509-521: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 60 'run'. lines 522-527: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 61 'run'. lines 530-535: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 62 'run'. lines 538-543: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 63 'run'. lines 546-551: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 64 'run'. lines 554-559: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 65 'run'. lines 562-567: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 66 'run'. lines 570-575: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 67 'run'. lines 578-583: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 68 'run'. lines 586-591: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 69 'run'. lines 594-599: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 70 'run'. lines 602-607: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 71 'run'. lines 610-615: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 72 'publish'. lines 618-626: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 73 'publish'. lines 628-636: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 74 'publish'. lines 638-650: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 75 'run'. lines 651-656: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 76 'run'. lines 659-664: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 77 'run'. lines 667-672: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 78 'run'. lines 675-680: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 79 'run'. lines 683-688: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 80 'run'. lines 691-696: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 81 'run'. lines 699-704: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 82 'run'. lines 707-712: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 83 'run'. lines 715-720: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 84 'run'. lines 723-728: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 85 'run'. lines 731-736: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 86 'run'. lines 739-744: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 87 'publish'. lines 747-755: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 88 'publish'. lines 757-765: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 89 'publish'. lines 767-779: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 90 'run'. lines 780-785: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 91 'run'. lines 788-793: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 92 'run'. lines 796-801: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 93 'run'. lines 804-809: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 94 'run'. lines 812-817: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 95 'run'. lines 820-825: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 96 'run'. lines 828-833: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 97 'run'. lines 836-841: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 98 'run'. lines 844-849: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 99 'run'. lines 852-857: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 100 'run'. lines 860-865: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 101 'run'. lines 868-873: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 102 'publish'. lines 876-884: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 103 'publish'. lines 886-894: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 104 'publish'. lines 896-908: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 105 'run'. lines 909-914: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 106 'run'. lines 917-922: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 107 'run'. lines 925-930: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 108 'run'. lines 933-938: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 109 'run'. lines 941-946: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 110 'run'. lines 949-954: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 111 'run'. lines 957-962: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 112 'run'. lines 965-970: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 113 'run'. lines 973-978: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 114 'run'. lines 981-986: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 115 'publish'. lines 989-997: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 116 'publish'. lines 999-1010: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 117 'run'. lines 1011-1016: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 118 'run'. lines 1019-1024: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 119 'run'. lines 1027-1032: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 120 'run'. lines 1035-1040: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 121 'run'. lines 1043-1048: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 122 'run'. lines 1051-1056: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 123 'run'. lines 1059-1064: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 124 'run'. lines 1067-1072: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 125 'run'. lines 1075-1080: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 126 'run'. lines 1083-1088: -Error: Script execution failed with VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 127 'publish'. lines 1091-1099: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 128 'publish'. lines 1101-1113: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 129 'run'. lines 1114-1119: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 130 'run'. lines 1122-1127: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 131 'run'. lines 1130-1135: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 132 'run'. lines 1138-1143: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 133 'run'. lines 1146-1151: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 134 'run'. lines 1154-1159: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 135 'run'. lines 1162-1167: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 136 'run'. lines 1170-1175: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 137 'run'. lines 1178-1183: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 138 'run'. lines 1186-1194: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 139 'run'. lines 1195-1200: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 140 'run'. lines 1203-1208: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 141 'run'. lines 1211-1216: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 142 'run'. lines 1219-1224: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 143 'run'. lines 1227-1232: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 144 'run'. lines 1235-1240: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 145 'run'. lines 1243-1248: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 146 'run'. lines 1251-1256: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 147 'run'. lines 1259-1264: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 148 'run'. lines 1267-1275: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 149 'run'. lines 1276-1281: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 150 'run'. lines 1284-1289: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 151 'run'. lines 1292-1297: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 152 'run'. lines 1300-1305: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 153 'run'. lines 1308-1313: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 154 'run'. lines 1316-1321: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 155 'run'. lines 1324-1329: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 156 'run'. lines 1332-1337: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 157 'run'. lines 1340-1345: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 158 'run'. lines 1348-1356: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 159 'run'. lines 1357-1362: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 160 'run'. lines 1365-1370: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 161 'run'. lines 1373-1378: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 162 'run'. lines 1381-1386: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 163 'run'. lines 1389-1394: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 164 'run'. lines 1397-1402: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 165 'run'. lines 1405-1410: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 166 'run'. lines 1413-1418: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 167 'run'. lines 1421-1426: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 168 'run'. lines 1429-1437: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 169 'run'. lines 1438-1443: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 170 'run'. lines 1446-1451: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 171 'run'. lines 1454-1459: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 172 'run'. lines 1462-1467: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 173 'run'. lines 1470-1475: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 174 'run'. lines 1478-1483: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 175 'run'. lines 1486-1491: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 176 'run'. lines 1494-1499: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 177 'publish'. lines 1502-1510: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 178 'publish'. lines 1512-1520: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 179 'publish'. lines 1522-1534: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 180 'run'. lines 1535-1540: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 181 'run'. lines 1543-1548: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 182 'run'. lines 1551-1556: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 183 'run'. lines 1559-1564: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 184 'run'. lines 1567-1572: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 185 'run'. lines 1575-1580: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 186 'run'. lines 1583-1588: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 187 'run'. lines 1591-1596: -Error: Script execution failed with VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 188 'publish'. lines 1599-1607: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 189 'publish'. lines 1609-1617: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 190 'publish'. lines 1619-1627: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.exp index 2301000e50a..8a4f38b6121 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.exp @@ -1 +1,7 @@ processed 6 tasks +task 0 lines 1-20: publish [module 0x42.tu8 {] +task 1 lines 22-41: publish [module 0x42.tu16 {] +task 2 lines 43-62: publish [module 0x42.tu32 {] +task 3 lines 64-83: publish [module 0x42.tu64 {] +task 4 lines 85-104: publish [module 0x42.tu128 {] +task 5 lines 106-125: publish [module 0x42.tu256 {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.v2_exp deleted file mode 100644 index 2301000e50a..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/integers_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 6 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.exp index 9927b5107da..464520d7127 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-18: +task 0 lines 1-18: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: WRITEREF_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.v2_exp deleted file mode 100644 index 9927b5107da..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_field_write.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-18: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: WRITEREF_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.exp index b1ff6981506..f94164f07ff 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x42.RTest {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::RTest'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.v2_exp deleted file mode 100644 index b1ff6981506..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/invalid_resource_write.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::RTest'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x42::RTest, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp index 5e1d9de7a69..e1f695d4803 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-25: +task 0 lines 1-25: publish [module 0x42.Token {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { major_status: BORROWFIELD_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.v2_exp deleted file mode 100644 index 5e1d9de7a69..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-25: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { - major_status: BORROWFIELD_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Token, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.exp index 5d92c423f3f..8e6bd9e152d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-64: publish [module 0x42.Token {] +task 1 lines 66-73: run --signers 0x43 [import 0x42.Token;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_from_get_resource.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp index db9153197af..2c3cdf4e58c 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-33: +task 0 lines 1-33: publish [module 0x42.Token {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { major_status: CALL_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.v2_exp deleted file mode 100644 index db9153197af..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/mut_call_with_imm_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-33: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { - major_status: CALL_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Token, - indices: [(FunctionDefinition, 2)], - offsets: [(FunctionDefinitionIndex(2), 4)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp index d3090ae8637..be46e5f4f01 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp @@ -1,6 +1,6 @@ processed 9 tasks - -task 1 'publish'. lines 10-22: +task 0 lines 1-8: publish [// This file contains tests checking that type arguments used in phantom position] +task 1 lines 10-22: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, @@ -8,8 +8,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 2 'publish'. lines 24-36: +task 2 lines 24-36: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: POP_WITHOUT_DROP_ABILITY, sub_status: None, @@ -17,8 +16,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 3 'publish'. lines 38-49: +task 3 lines 38-49: publish [ module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, @@ -26,8 +24,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 4 'publish'. lines 51-61: +task 4 lines 51-61: publish [ module 0x1.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, @@ -35,8 +32,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 5 'publish'. lines 63-76: +task 5 lines 63-76: publish [ module 0x1.M6 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M6'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -44,8 +40,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], offsets: [], } - -task 6 'publish'. lines 78-89: +task 6 lines 78-89: publish [ module 0x1.M7 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M7'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -53,8 +48,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], offsets: [], } - -task 7 'publish'. lines 91-102: +task 7 lines 91-102: publish [ module 0x1.M8 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M8'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -62,8 +56,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], offsets: [], } - -task 8 'publish'. lines 104-115: +task 8 lines 104-115: publish [module 0x1.M9 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M9'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.v2_exp deleted file mode 100644 index d3090ae8637..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.v2_exp +++ /dev/null @@ -1,73 +0,0 @@ -processed 9 tasks - -task 1 'publish'. lines 10-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 2 'publish'. lines 24-36: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: POP_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x1::M3, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 3 'publish'. lines 38-49: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M4, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 4 'publish'. lines 51-61: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M5, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 5 'publish'. lines 63-76: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M6'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M6, - indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} - -task 6 'publish'. lines 78-89: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M7'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M7, - indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} - -task 7 'publish'. lines 91-102: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M8'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M8, - indices: [(Signature, 2), (StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} - -task 8 'publish'. lines 104-115: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M9'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M9, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp index 6cd67db3f64..af76f288651 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-64: publish [// Test checking that type arguments used in phantom position (phantom arguments)] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp index 38045918145..a0a7d88adbb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp @@ -1,6 +1,6 @@ processed 6 tasks - -task 1 'publish'. lines 7-15: +task 0 lines 1-5: publish [module 0x1.M1 {] +task 1 lines 7-15: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +8,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 2 'publish'. lines 17-34: +task 2 lines 17-34: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +16,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 5)], offsets: [], } - -task 3 'publish'. lines 36-46: +task 3 lines 36-46: publish [module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +24,8 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(Signature, 1)], offsets: [], } - -task 5 'publish'. lines 60-75: +task 4 lines 49-58: publish [module 0x1.M3Valid {] +task 5 lines 60-75: publish [module 0x1.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.v2_exp deleted file mode 100644 index 38045918145..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 6 tasks - -task 1 'publish'. lines 7-15: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M2, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 2 'publish'. lines 17-34: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M3, - indices: [(StructDefinition, 5)], - offsets: [], -} - -task 3 'publish'. lines 36-46: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M4, - indices: [(Signature, 1)], - offsets: [], -} - -task 5 'publish'. lines 60-75: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M5, - indices: [(Signature, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp index 6cd67db3f64..0ab4824c09d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-41: publish [module 0x1.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp index 43e65b41761..ea2396712e4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp @@ -1,6 +1,6 @@ processed 5 tasks - -task 1 'publish'. lines 16-21: +task 0 lines 1-14: publish [// Negative version of tests in fields_abilities_ok instantiating the non-phantom] +task 1 lines 16-21: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -8,8 +8,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 2 'publish'. lines 23-28: +task 2 lines 23-28: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -17,8 +16,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 3 'publish'. lines 30-35: +task 3 lines 30-35: publish [module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, @@ -26,8 +24,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 4 'publish'. lines 37-42: +task 4 lines 37-42: publish [module 0x1.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { major_status: FIELD_MISSING_TYPE_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.v2_exp deleted file mode 100644 index 43e65b41761..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 5 tasks - -task 1 'publish'. lines 16-21: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::M2, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 2 'publish'. lines 23-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::M3, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 3 'publish'. lines 30-35: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::M4, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 4 'publish'. lines 37-42: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { - major_status: FIELD_MISSING_TYPE_ABILITY, - sub_status: None, - location: 0x1::M5, - indices: [(StructDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp index 6cd67db3f64..215e153c6e2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-18: publish [// This module checks that phantom arguments are not considered by checking against] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp index 600468a8b35..7b8503d8a65 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp @@ -1,6 +1,5 @@ processed 6 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [// Tests checking incorrect struct declarations using phantom parameters] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 1 'publish'. lines 13-19: +task 1 lines 13-19: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 2 'publish'. lines 21-28: +task 2 lines 21-28: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 1)], offsets: [], } - -task 3 'publish'. lines 30-39: +task 3 lines 30-39: publish [module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 2)], offsets: [], } - -task 4 'publish'. lines 41-47: +task 4 lines 41-47: publish [module 0x1.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, sub_status: None, @@ -44,8 +39,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(StructDefinition, 0)], offsets: [], } - -task 5 'publish'. lines 49-56: +task 5 lines 49-56: publish [module 0x1.M6 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M6'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.v2_exp deleted file mode 100644 index 600468a8b35..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.v2_exp +++ /dev/null @@ -1,55 +0,0 @@ -processed 6 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { - major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, - sub_status: None, - location: 0x1::M1, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 1 'publish'. lines 13-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, - sub_status: None, - location: 0x1::M2, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 2 'publish'. lines 21-28: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, - sub_status: None, - location: 0x1::M3, - indices: [(StructDefinition, 1)], - offsets: [], -} - -task 3 'publish'. lines 30-39: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, - sub_status: None, - location: 0x1::M4, - indices: [(StructDefinition, 2)], - offsets: [], -} - -task 4 'publish'. lines 41-47: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { - major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, - sub_status: None, - location: 0x1::M5, - indices: [(StructDefinition, 0)], - offsets: [], -} - -task 5 'publish'. lines 49-56: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M6'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x1::M6, - indices: [(StructDefinition, 1)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp index fc5a4436b29..4001ad879fc 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp @@ -1 +1,4 @@ processed 3 tasks +task 0 lines 1-24: publish [module 0x1.M1 {] +task 1 lines 26-34: publish [module 0x1.M2 {] +task 2 lines 36-47: publish [module 0x1.M3 {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.v2_exp deleted file mode 100644 index fc5a4436b29..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 3 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.exp index 47e3c11d774..888cc10eb27 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 11-22: +task 0 lines 1-9: publish [module 0x42.Test {] +task 1 lines 11-22: run [import 0x42.Test;] Error: Script execution failed with VMError: { major_status: CALL_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.v2_exp deleted file mode 100644 index 47e3c11d774..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_args_subtype.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 11-22: -Error: Script execution failed with VMError: { - major_status: CALL_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp index b1a59d8fc5f..9f62cd591b4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: RET_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.v2_exp deleted file mode 100644 index b1a59d8fc5f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_subtype.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: RET_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Test, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.exp index b1a59d8fc5f..9f62cd591b4 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-9: +task 0 lines 1-9: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: RET_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.v2_exp deleted file mode 100644 index b1a59d8fc5f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/procedure_return_invalid_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-9: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: RET_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Test, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.exp index 3cd6db23021..d5c3e508273 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 1 'publish'. lines 12-21: +task 1 lines 12-21: publish [module 0x42.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 2 'publish'. lines 23-32: +task 2 lines 23-32: publish [module 0x42.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [], offsets: [], } - -task 3 'publish'. lines 34-44: +task 3 lines 34-44: publish [module 0x42.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.v2_exp deleted file mode 100644 index 3cd6db23021..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M1, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 1 'publish'. lines 12-21: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M2, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 2 'publish'. lines 23-32: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { - major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, - sub_status: None, - location: undefined, - indices: [], - offsets: [], -} - -task 3 'publish'. lines 34-44: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M4, - indices: [(FunctionHandle, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.exp index daecd5cf37f..d84422478b0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.exp @@ -1,6 +1,5 @@ processed 5 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 1 'publish'. lines 13-23: +task 1 lines 13-23: publish [module 0x42.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 2 'publish'. lines 25-36: +task 2 lines 25-36: publish [module 0x42.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 3 'publish'. lines 38-54: +task 3 lines 38-54: publish [module 0x42.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 4 'publish'. lines 56-72: +task 4 lines 56-72: publish [module 0x42.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M5'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.v2_exp deleted file mode 100644 index daecd5cf37f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/ref_type_param_exploits.v2_exp +++ /dev/null @@ -1,46 +0,0 @@ -processed 5 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M1, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 1 'publish'. lines 13-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M2, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 2 'publish'. lines 25-36: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M3, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 3 'publish'. lines 38-54: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M4, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 4 'publish'. lines 56-72: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M5'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M5, - indices: [(Signature, 3)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.exp index f3a7de94e64..a040c4c513f 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.v2_exp deleted file mode 100644 index f3a7de94e64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/release.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp index f8cfe0681b7..a9c561bd1b0 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-14: +task 0 lines 1-14: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: PACK_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.v2_exp deleted file mode 100644 index f8cfe0681b7..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/resource_instantiate_bad_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-14: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: PACK_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Test, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp index 63337530dac..2eca5ed0054 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: RET_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 1 'publish'. lines 15-27: +task 1 lines 15-27: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: RET_TYPE_MISMATCH_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 5)], } - -task 2 'publish'. lines 29-40: +task 2 lines 29-40: publish [module 0x1.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 3 'publish'. lines 42-53: +task 3 lines 42-53: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.v2_exp deleted file mode 100644 index 63337530dac..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: RET_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 1 'publish'. lines 15-27: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: RET_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} - -task 2 'publish'. lines 29-40: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 3 'publish'. lines 42-53: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.exp index c1dde036e20..5f608aecf90 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.v2_exp deleted file mode 100644 index c1dde036e20..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-8: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp index 0325d662d1b..1ad490fa371 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.v2_exp deleted file mode 100644 index 0325d662d1b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_copy_loc_transitive.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.exp index 43d37571936..5bc19631fe7 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.v2_exp deleted file mode 100644 index 43d37571936..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_does_not_have_store.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.exp index 6cd67db3f64..fd8e08be443 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-7: run --signers 0x1 [main(s: signer) {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_equality.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.exp index 75588e9f172..40daf7665b8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 1 'publish'. lines 14-23: +task 1 lines 14-23: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.v2_exp deleted file mode 100644 index 75588e9f172..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_mutable_signer.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 1 'publish'. lines 14-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.exp index 3018ac82175..472084971fa 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_WITHOUT_KEY_ABILITY, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 1 'publish'. lines 14-23: +task 1 lines 14-23: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.v2_exp deleted file mode 100644 index 3018ac82175..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_resource.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_WITHOUT_KEY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 1 'publish'. lines 14-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::N, - indices: [(StructDefInstantiation, 0), (FunctionDefinition, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.exp index 75588e9f172..40daf7665b8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 1 'publish'. lines 14-23: +task 1 lines 14-23: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.v2_exp deleted file mode 100644 index 75588e9f172..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_signer.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 1 'publish'. lines 14-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.exp index bb82c8d342b..bf8e6e7dc25 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.v2_exp deleted file mode 100644 index bb82c8d342b..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_non_struct.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.exp index 75588e9f172..40daf7665b8 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 1 'publish'. lines 14-23: +task 1 lines 14-23: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.v2_exp deleted file mode 100644 index 75588e9f172..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_args_flipped.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 1 'publish'. lines 14-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.exp index 53af9e0e2e3..eb644a123ed 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 1 'publish'. lines 14-23: +task 1 lines 14-23: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.v2_exp deleted file mode 100644 index 53af9e0e2e3..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_resource.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 1 'publish'. lines 14-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.exp index 42149f180d9..f4d07d962a2 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-13: +task 0 lines 1-13: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 1 'publish'. lines 15-25: +task 1 lines 15-25: publish [module 0x42.N {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { major_status: MOVETO_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.v2_exp deleted file mode 100644 index 42149f180d9..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_reference_to_wrong_resource.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-13: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 1 'publish'. lines 15-25: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { - major_status: MOVETO_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::N, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 3)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.exp index 5d92c423f3f..a895d362893 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-12: publish [module 0x42.M {] +task 1 lines 14-25: publish [module 0x42.N {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_move_to_valid.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.exp index 8bad387623f..cdbe4bf6d51 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-8: +task 0 lines 1-8: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: READREF_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.v2_exp deleted file mode 100644 index 8bad387623f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-8: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: READREF_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.exp index 91e9dd2f2bb..025b6502830 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.exp @@ -1,6 +1,5 @@ processed 2 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: READREF_WITHOUT_COPY_ABILITY, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 4)], } - -task 1 'publish'. lines 13-23: +task 1 lines 13-23: publish [module 0x42.M {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { major_status: READREF_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.v2_exp deleted file mode 100644 index 91e9dd2f2bb..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_read_ref_transitive.v2_exp +++ /dev/null @@ -1,19 +0,0 @@ -processed 2 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: READREF_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 4)], -} - -task 1 'publish'. lines 13-23: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { - major_status: READREF_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x42::M, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.exp index 6cd67db3f64..25ddef458ca 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_st_loc.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.exp index 6cd67db3f64..a2c9cc7519a 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-16: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_transitive.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.exp index 6cd67db3f64..25ddef458ca 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.exp @@ -1 +1,2 @@ processed 1 task +task 0 lines 1-11: publish [module 0x42.M {] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.v2_exp deleted file mode 100644 index 6cd67db3f64..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/signer_write_ref.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 1 task diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.exp index 65b2121aeca..a4150d1d334 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.exp @@ -1,6 +1,5 @@ processed 5 tasks - -task 0 'publish'. lines 1-12: +task 0 lines 1-12: publish [// ensure that generic structs instantiated with struct types behave like resources] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 0)], } - -task 1 'publish'. lines 14-25: +task 1 lines 14-25: publish [module 0x1.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 2 'publish'. lines 27-37: +task 2 lines 27-37: publish [module 0x1.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { major_status: READREF_WITHOUT_COPY_ABILITY, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 3 'publish'. lines 39-50: +task 3 lines 39-50: publish [module 0x1.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { major_status: WRITEREF_WITHOUT_DROP_ABILITY, sub_status: None, @@ -35,8 +31,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionDefinition, 0)], offsets: [(FunctionDefinitionIndex(0), 2)], } - -task 4 'publish'. lines 52-62: +task 4 lines 52-62: publish [module 0x1.M5 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { major_status: COPYLOC_WITHOUT_COPY_ABILITY, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.v2_exp deleted file mode 100644 index 65b2121aeca..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/struct_kind_inference.v2_exp +++ /dev/null @@ -1,46 +0,0 @@ -processed 5 tasks - -task 0 'publish'. lines 1-12: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: 0x1::M1, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} - -task 1 'publish'. lines 14-25: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { - major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, - sub_status: None, - location: 0x1::M2, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 2 'publish'. lines 27-37: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { - major_status: READREF_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M3, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 3 'publish'. lines 39-50: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { - major_status: WRITEREF_WITHOUT_DROP_ABILITY, - sub_status: None, - location: 0x1::M4, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 2)], -} - -task 4 'publish'. lines 52-62: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { - major_status: COPYLOC_WITHOUT_COPY_ABILITY, - sub_status: None, - location: 0x1::M5, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 0)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.exp index e46998e2583..d451d8115c9 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'run'. lines 1-15: +task 0 lines 1-15: run [main(b: bool) {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.v2_exp deleted file mode 100644 index e46998e2583..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/type_error_after_branch.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'run'. lines 1-15: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 8)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.exp index 5d92c423f3f..6eff0a9851d 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-33: publish [module 0x1.Test {] +task 1 lines 35-49: run [import 0x1.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_resource.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.exp index 776bf60546e..18c8e1c8634 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-19: +task 0 lines 1-19: publish [module 0x1.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { major_status: UNPACK_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.v2_exp deleted file mode 100644 index 776bf60546e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unpack_wrong_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-19: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { - major_status: UNPACK_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x1::Test, - indices: [(FunctionDefinition, 1)], - offsets: [(FunctionDefinitionIndex(1), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.exp index 5d92c423f3f..6d33a2e49a1 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.exp @@ -1 +1,3 @@ processed 2 tasks +task 0 lines 1-14: publish [module 0x42.Test {] +task 1 lines 16-27: run [import 0x42.Test;] diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.v2_exp deleted file mode 100644 index 5d92c423f3f..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate.v2_exp +++ /dev/null @@ -1 +0,0 @@ -processed 2 tasks diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp index 6603cc32602..6bb3a3dfee6 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp @@ -1,6 +1,5 @@ processed 1 task - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.Test {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { major_status: PACK_TYPE_MISMATCH_ERROR, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.v2_exp deleted file mode 100644 index 6603cc32602..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 1 task - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { - major_status: PACK_TYPE_MISMATCH_ERROR, - sub_status: None, - location: 0x42::Test, - indices: [(FunctionDefinition, 0)], - offsets: [(FunctionDefinitionIndex(0), 1)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.exp index 4ea140c610e..3ba6290cd6b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.exp @@ -1,6 +1,6 @@ processed 2 tasks - -task 1 'run'. lines 18-31: +task 0 lines 1-16: publish [module 0x42.A {] +task 1 lines 18-31: run [import 0x42.A;] Error: Script execution failed with VMError: { major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.v2_exp deleted file mode 100644 index 4ea140c610e..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/unused_resource_holder.v2_exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 18-31: -Error: Script execution failed with VMError: { - major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp index 375939935ea..2e1c784523b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp @@ -1,6 +1,5 @@ processed 8 tasks - -task 0 'run'. lines 1-7: +task 0 lines 1-7: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, @@ -8,8 +7,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 1 'run'. lines 9-18: +task 1 lines 9-18: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, @@ -17,8 +15,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 3)], } - -task 2 'run'. lines 20-31: +task 2 lines 20-31: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, @@ -26,8 +23,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 6)], } - -task 3 'run'. lines 33-45: +task 3 lines 33-45: run [main() {] Error: Script execution failed with VMError: { major_status: TYPE_MISMATCH, sub_status: None, @@ -35,8 +31,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 8)], } - -task 4 'run'. lines 47-59: +task 4 lines 47-59: run [main() {] Error: Script execution failed with VMError: { major_status: TYPE_MISMATCH, sub_status: None, @@ -44,8 +39,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 6)], } - -task 5 'run'. lines 61-77: +task 5 lines 61-77: run [main() {] Error: Script execution failed with VMError: { major_status: STLOC_TYPE_MISMATCH_ERROR, sub_status: None, @@ -53,8 +47,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 6 'run'. lines 78-86: +task 6 lines 78-86: run [main() {] Error: Script execution failed with VMError: { major_status: TYPE_MISMATCH, sub_status: None, @@ -62,8 +55,7 @@ Error: Script execution failed with VMError: { indices: [], offsets: [(FunctionDefinitionIndex(0), 1)], } - -task 7 'run'. lines 87-96: +task 7 lines 87-96: run [main() {] Error: Script execution failed with VMError: { major_status: TYPE_MISMATCH, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.v2_exp deleted file mode 100644 index 375939935ea..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_ops_type_mismatch.v2_exp +++ /dev/null @@ -1,73 +0,0 @@ -processed 8 tasks - -task 0 'run'. lines 1-7: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 1 'run'. lines 9-18: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 3)], -} - -task 2 'run'. lines 20-31: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} - -task 3 'run'. lines 33-45: -Error: Script execution failed with VMError: { - major_status: TYPE_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 8)], -} - -task 4 'run'. lines 47-59: -Error: Script execution failed with VMError: { - major_status: TYPE_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 6)], -} - -task 5 'run'. lines 61-77: -Error: Script execution failed with VMError: { - major_status: STLOC_TYPE_MISMATCH_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 6 'run'. lines 78-86: -Error: Script execution failed with VMError: { - major_status: TYPE_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 1)], -} - -task 7 'run'. lines 87-96: -Error: Script execution failed with VMError: { - major_status: TYPE_MISMATCH, - sub_status: None, - location: script, - indices: [], - offsets: [(FunctionDefinitionIndex(0), 5)], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.exp index 31b017ab448..8614969a48b 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.exp @@ -1,6 +1,5 @@ processed 3 tasks - -task 0 'publish'. lines 1-10: +task 0 lines 1-10: publish [module 0x42.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 1 'publish'. lines 12-21: +task 1 lines 12-21: publish [module 0x42.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 2 'publish'. lines 23-32: +task 2 lines 23-32: publish [module 0x42.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.v2_exp deleted file mode 100644 index 31b017ab448..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param.v2_exp +++ /dev/null @@ -1,28 +0,0 @@ -processed 3 tasks - -task 0 'publish'. lines 1-10: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M1, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 1 'publish'. lines 12-21: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M2, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 2 'publish'. lines 23-32: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M3, - indices: [(FunctionHandle, 0)], - offsets: [], -} diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.exp index 14cdd9a3eb6..780325badbb 100644 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.exp +++ b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.exp @@ -1,6 +1,5 @@ processed 4 tasks - -task 0 'publish'. lines 1-11: +task 0 lines 1-11: publish [module 0x42.M1 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -8,8 +7,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 1 'publish'. lines 13-22: +task 1 lines 13-22: publish [module 0x42.M2 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -17,8 +15,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 2 'publish'. lines 24-40: +task 2 lines 24-40: publish [module 0x42.M3 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, @@ -26,8 +23,7 @@ Error: Unable to publish module '00000000000000000000000000000000000000000000000 indices: [(FunctionHandle, 0)], offsets: [], } - -task 3 'publish'. lines 42-58: +task 3 lines 42-58: publish [module 0x42.M4 {] Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { major_status: CONSTRAINT_NOT_SATISFIED, sub_status: None, diff --git a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.v2_exp b/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.v2_exp deleted file mode 100644 index 14cdd9a3eb6..00000000000 --- a/third_party/move/move-bytecode-verifier/transactional-tests/tests/type_safety/vector_type_param_exploits.v2_exp +++ /dev/null @@ -1,37 +0,0 @@ -processed 4 tasks - -task 0 'publish'. lines 1-11: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M1, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 1 'publish'. lines 13-22: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M2, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 2 'publish'. lines 24-40: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M3, - indices: [(FunctionHandle, 0)], - offsets: [], -} - -task 3 'publish'. lines 42-58: -Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { - major_status: CONSTRAINT_NOT_SATISFIED, - sub_status: None, - location: 0x42::M4, - indices: [(Signature, 2)], - offsets: [], -} diff --git a/third_party/move/move-command-line-common/Cargo.toml b/third_party/move/move-command-line-common/Cargo.toml index 7fc21855f50..693dda46b65 100644 --- a/third_party/move/move-command-line-common/Cargo.toml +++ b/third_party/move/move-command-line-common/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/diem/diem" homepage = "https://diem.com" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/third_party/move/move-command-line-common/src/address.rs b/third_party/move/move-command-line-common/src/address.rs index 4e546285ef4..2475efd0402 100644 --- a/third_party/move/move-command-line-common/src/address.rs +++ b/third_party/move/move-command-line-common/src/address.rs @@ -44,11 +44,6 @@ impl NumericalAddress { bytes: AccountAddress::ONE, format: NumberFormat::Hex, }; - // bytes used for scripts, which don't have an address - pub const MAX_ADDRESS: Self = NumericalAddress { - bytes: AccountAddress::MAX_ADDRESS, - format: NumberFormat::Hex, - }; pub fn from_account_address(addr: AccountAddress) -> Self { Self { diff --git a/third_party/move/move-command-line-common/src/files.rs b/third_party/move/move-command-line-common/src/files.rs index 79b4e0e5c34..76c00cb4815 100644 --- a/third_party/move/move-command-line-common/src/files.rs +++ b/third_party/move/move-command-line-common/src/files.rs @@ -41,6 +41,12 @@ impl std::fmt::Debug for FileHash { pub const MOVE_EXTENSION: &str = "move"; /// Extension for Move IR files pub const MOVE_IR_EXTENSION: &str = "mvir"; +/// Extension for Move ASM files +pub const MOVE_ASM_EXTENSION: &str = "masm"; +/// Extension for decompiled move +pub const DECOMPILED_EXTENSION: &str = "decompiled"; +/// Extension for disassembled masm +pub const DISASSEMBLED_EXTENSION: &str = "disassembled"; /// Extension for Move bytecode files pub const MOVE_COMPILED_EXTENSION: &str = "mv"; /// Extension for Move source map files (mappings from source to bytecode) diff --git a/third_party/move/move-command-line-common/src/parser.rs b/third_party/move/move-command-line-common/src/parser.rs index d1951b60088..199b9a0e275 100644 --- a/third_party/move/move-command-line-common/src/parser.rs +++ b/third_party/move/move-command-line-common/src/parser.rs @@ -9,7 +9,7 @@ use crate::{ use anyhow::{anyhow, bail, Result}; use move_core_types::{ account_address::AccountAddress, - u256::{U256FromStrError, U256}, + int256::{I256, U256}, }; use num_bigint::BigUint; use std::{collections::BTreeMap, fmt::Display, iter::Peekable, num::ParseIntError}; @@ -140,6 +140,12 @@ impl<'a, I: Iterator> Parser<'a, TypeToken, I> { (TypeToken::Ident, "u64") => ParsedType::U64, (TypeToken::Ident, "u128") => ParsedType::U128, (TypeToken::Ident, "u256") => ParsedType::U256, + (TypeToken::Ident, "i8") => ParsedType::I8, + (TypeToken::Ident, "i16") => ParsedType::I16, + (TypeToken::Ident, "i32") => ParsedType::I32, + (TypeToken::Ident, "i64") => ParsedType::I64, + (TypeToken::Ident, "i128") => ParsedType::I128, + (TypeToken::Ident, "i256") => ParsedType::I256, (TypeToken::Ident, "bool") => ParsedType::Bool, (TypeToken::Ident, "address") => ParsedType::Address, (TypeToken::Ident, "signer") => ParsedType::Signer, @@ -194,8 +200,13 @@ impl<'a, I: Iterator> Parser<'a, ValueToken, I> { let (tok, contents) = self.advance_any()?; Ok(match tok { ValueToken::Number if !matches!(self.peek_tok(), Some(ValueToken::ColonColon)) => { - let (u, _) = parse_u256(contents)?; - ParsedValue::InferredNum(u) + if contents.starts_with('-') { + let i = parse_i256(contents)?; + ParsedValue::InferredNegNum(i) + } else { + let u = parse_u256(contents)?; + ParsedValue::InferredNum(u) + } }, ValueToken::NumberTyped => { if let Some(s) = contents.strip_suffix("u8") { @@ -213,9 +224,27 @@ impl<'a, I: Iterator> Parser<'a, ValueToken, I> { } else if let Some(s) = contents.strip_suffix("u128") { let (u, _) = parse_u128(s)?; ParsedValue::U128(u) - } else { - let (u, _) = parse_u256(contents.strip_suffix("u256").unwrap())?; + } else if let Some(s) = contents.strip_suffix("u256") { + let u = parse_u256(s)?; ParsedValue::U256(u) + } else if let Some(s) = contents.strip_suffix("i8") { + let (i, _) = parse_i8(s)?; + ParsedValue::I8(i) + } else if let Some(s) = contents.strip_suffix("i16") { + let (i, _) = parse_i16(s)?; + ParsedValue::I16(i) + } else if let Some(s) = contents.strip_suffix("i32") { + let (i, _) = parse_i32(s)?; + ParsedValue::I32(i) + } else if let Some(s) = contents.strip_suffix("i64") { + let (i, _) = parse_i64(s)?; + ParsedValue::I64(i) + } else if let Some(s) = contents.strip_suffix("i128") { + let (i, _) = parse_i128(s)?; + ParsedValue::I128(i) + } else { + let i = parse_i256(contents.strip_suffix("i256").unwrap())?; + ParsedValue::I256(i) } }, ValueToken::True => ParsedValue::Bool(true), @@ -345,10 +374,14 @@ pub enum NumberFormat { } // Determines the base of the number literal, depending on the prefix -pub(crate) fn determine_num_text_and_base(s: &str) -> (&str, NumberFormat) { - match s.strip_prefix("0x") { - Some(s_hex) => (s_hex, NumberFormat::Hex), - None => (s, NumberFormat::Decimal), +pub(crate) fn determine_num_text_and_base(s: &str) -> (String, NumberFormat) { + if let Some(s_hex) = s.strip_prefix("0x") { + (s_hex.to_string(), NumberFormat::Hex) + } else if let Some(s_hex) = s.strip_prefix("-0x") { + // if negative hex, need to add the '-' back + (format!("-{}", s_hex), NumberFormat::Hex) + } else { + (s.to_string(), NumberFormat::Decimal) } } @@ -398,15 +431,63 @@ pub fn parse_u128(s: &str) -> Result<(u128, NumberFormat), ParseIntError> { } // Parse a u256 from a decimal or hex encoding -pub fn parse_u256(s: &str) -> Result<(U256, NumberFormat), U256FromStrError> { +pub fn parse_u256(s: &str) -> anyhow::Result { + let (txt, base) = determine_num_text_and_base(s); + U256::from_str_radix(&txt.replace('_', ""), base as u32) +} + +/// Parse an i8 from a decimal or hex encoding and return its value in i8 +pub fn parse_i8(s: &str) -> Result<(i8, NumberFormat), ParseIntError> { + let (txt, base) = determine_num_text_and_base(s); + Ok(( + i8::from_str_radix(&txt.replace('_', ""), base as u32)?, + base, + )) +} + +/// Parse an i16 from a decimal or hex encoding and return its value in i16 +pub fn parse_i16(s: &str) -> Result<(i16, NumberFormat), ParseIntError> { + let (txt, base) = determine_num_text_and_base(s); + Ok(( + i16::from_str_radix(&txt.replace('_', ""), base as u32)?, + base, + )) +} + +/// Parse an i32 from a decimal or hex encoding and return its value in i32 +pub fn parse_i32(s: &str) -> Result<(i32, NumberFormat), ParseIntError> { let (txt, base) = determine_num_text_and_base(s); Ok(( - U256::from_str_radix(&txt.replace('_', ""), base as u32)?, + i32::from_str_radix(&txt.replace('_', ""), base as u32)?, base, )) } -// Parse an address from a decimal or hex encoding +/// Parse an i64 from a decimal or hex encoding and return its value in i64 +pub fn parse_i64(s: &str) -> Result<(i64, NumberFormat), ParseIntError> { + let (txt, base) = determine_num_text_and_base(s); + Ok(( + i64::from_str_radix(&txt.replace('_', ""), base as u32)?, + base, + )) +} + +/// Parse an i128 from a decimal or hex encoding and return its value in i128 +pub fn parse_i128(s: &str) -> Result<(i128, NumberFormat), ParseIntError> { + let (txt, base) = determine_num_text_and_base(s); + Ok(( + i128::from_str_radix(&txt.replace('_', ""), base as u32)?, + base, + )) +} + +/// Parse an i256 from a decimal or hex encoding and return its value in I256 +pub fn parse_i256(s: &str) -> anyhow::Result { + let (txt, base) = determine_num_text_and_base(s); + I256::from_str_radix(&txt.replace('_', ""), base as u32) +} + +/// Parse an address from a decimal or hex encoding pub fn parse_address_number(s: &str) -> Option<([u8; AccountAddress::LENGTH], NumberFormat)> { let (txt, base) = determine_num_text_and_base(s); let parsed = BigUint::parse_bytes(txt.as_bytes(), match base { @@ -429,7 +510,7 @@ mod tests { types::{ParsedStructType, ParsedType}, values::ParsedValue, }; - use move_core_types::{account_address::AccountAddress, u256::U256}; + use move_core_types::{account_address::AccountAddress, int256::U256}; #[allow(clippy::unreadable_literal)] #[test] diff --git a/third_party/move/move-command-line-common/src/types.rs b/third_party/move/move-command-line-common/src/types.rs index d38b9c231c1..489dd30ff6d 100644 --- a/third_party/move/move-command-line-common/src/types.rs +++ b/third_party/move/move-command-line-common/src/types.rs @@ -37,6 +37,12 @@ pub enum ParsedType { U64, U128, U256, + I8, + I16, + I32, + I64, + I128, + I256, Bool, Address, Signer, @@ -149,6 +155,12 @@ impl ParsedType { ParsedType::U64 => TypeTag::U64, ParsedType::U128 => TypeTag::U128, ParsedType::U256 => TypeTag::U256, + ParsedType::I8 => TypeTag::I8, + ParsedType::I16 => TypeTag::I16, + ParsedType::I32 => TypeTag::I32, + ParsedType::I64 => TypeTag::I64, + ParsedType::I128 => TypeTag::I128, + ParsedType::I256 => TypeTag::I256, ParsedType::Bool => TypeTag::Bool, ParsedType::Address => TypeTag::Address, ParsedType::Signer => TypeTag::Signer, diff --git a/third_party/move/move-command-line-common/src/values.rs b/third_party/move/move-command-line-common/src/values.rs index 04aa8858534..fd8a4a36a2b 100644 --- a/third_party/move/move-command-line-common/src/values.rs +++ b/third_party/move/move-command-line-common/src/values.rs @@ -42,13 +42,20 @@ pub enum ValueToken { #[derive(Eq, PartialEq, Debug, Clone)] pub enum ParsedValue { Address(ParsedAddress), - InferredNum(move_core_types::u256::U256), + InferredNum(move_core_types::int256::U256), + InferredNegNum(move_core_types::int256::I256), U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), - U256(move_core_types::u256::U256), + U256(move_core_types::int256::U256), + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + I256(move_core_types::int256::I256), Bool(bool), Vector(Vec>), Struct( @@ -314,13 +321,21 @@ impl ParsedValue { ParsedValue::U16(u) => Extra::move_value_into_concrete(MoveValue::U16(u)), ParsedValue::U32(u) => Extra::move_value_into_concrete(MoveValue::U32(u)), ParsedValue::U64(u) => Extra::move_value_into_concrete(MoveValue::U64(u)), - ParsedValue::InferredNum(u) if u <= (u64::MAX.into()) => { + ParsedValue::InferredNum(u) if u <= u64::MAX.into() => { Extra::move_value_into_concrete(MoveValue::U64(u.try_into()?)) }, ParsedValue::U128(u) => Extra::move_value_into_concrete(MoveValue::U128(u)), ParsedValue::InferredNum(u) | ParsedValue::U256(u) => { Extra::move_value_into_concrete(MoveValue::U256(u)) }, + ParsedValue::I8(i) => Extra::move_value_into_concrete(MoveValue::I8(i)), + ParsedValue::I16(i) => Extra::move_value_into_concrete(MoveValue::I16(i)), + ParsedValue::I32(i) => Extra::move_value_into_concrete(MoveValue::I32(i)), + ParsedValue::I64(i) => Extra::move_value_into_concrete(MoveValue::I64(i)), + ParsedValue::I128(i) => Extra::move_value_into_concrete(MoveValue::I128(i)), + ParsedValue::InferredNegNum(i) | ParsedValue::I256(i) => { + Extra::move_value_into_concrete(MoveValue::I256(i)) + }, ParsedValue::Bool(b) => Extra::move_value_into_concrete(MoveValue::Bool(b)), ParsedValue::Vector(values) => Extra::concrete_vector( values diff --git a/third_party/move/move-compiler-v2/Cargo.toml b/third_party/move/move-compiler-v2/Cargo.toml index b8c3a787afd..c6b5a9e1b08 100644 --- a/third_party/move/move-compiler-v2/Cargo.toml +++ b/third_party/move/move-compiler-v2/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/aptos-labs/aptos-core" homepage = "https://aptosfoundation.org/" license = "Apache-2.0" publish = false -edition = "2021" +edition = { workspace = true } [dependencies] abstract-domain-derive = { path = "../move-model/bytecode/abstract_domain_derive" } @@ -16,19 +16,20 @@ bcs = { workspace = true } clap = { workspace = true, features = ["derive", "env"] } codespan = { workspace = true } codespan-reporting = { workspace = true, features = ["serde", "serialization"] } +colored = { workspace = true } ethnum = { workspace = true } flexi_logger = { workspace = true } im = { workspace = true } itertools = { workspace = true } legacy-move-compiler = { workspace = true } log = { workspace = true, features = ["serde"] } +move-asm = { workspace = true } move-binary-format = { workspace = true } move-borrow-graph = { workspace = true } move-bytecode-source-map = { workspace = true } move-bytecode-verifier = { workspace = true } move-command-line-common = { workspace = true } move-core-types = { workspace = true } -move-disassembler = { workspace = true } move-ir-types = { workspace = true } move-model = { workspace = true } move-stackless-bytecode = { workspace = true } diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/Cargo.toml b/third_party/move/move-compiler-v2/legacy-move-compiler/Cargo.toml index 88d9c55cc4f..ac206dbc23c 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/Cargo.toml +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.1" authors = ["Diem Association "] description = "Legacy Move Compiler Passes" publish = false -edition = "2021" +edition = { workspace = true } license = "Apache-2.0" [dependencies] diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/diagnostics/codes.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/diagnostics/codes.rs index 3b4b7bdee64..eddfcc2fc9c 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/diagnostics/codes.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/diagnostics/codes.rs @@ -347,7 +347,7 @@ impl DeprecatedItem { } } - pub fn get_code(&self) -> impl DiagnosticCode { + pub fn get_code(&self) -> impl DiagnosticCode + use<> { match self { DeprecatedItem::Module => NameResolution::DeprecatedModule, DeprecatedItem::Member => NameResolution::DeprecatedMember, diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs index 34e84c50ce1..19b16bf754e 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/ast.rs @@ -166,6 +166,7 @@ pub struct StructDefinition { pub abilities: AbilitySet, pub type_parameters: Vec, pub layout: StructLayout, + pub visibility: Visibility, } #[derive(Debug, Clone, PartialEq)] @@ -475,7 +476,9 @@ pub enum Value_ { // 0x Address(Address), // - InferredNum(move_core_types::u256::U256), + InferredNum(move_core_types::int256::U256), + // + InferredNegNum(move_core_types::int256::I256), // u8 U8(u8), // u16 @@ -487,7 +490,19 @@ pub enum Value_ { // u128 U128(u128), // u256 - U256(move_core_types::u256::U256), + U256(move_core_types::int256::U256), + // i8 + I8(i8), + // i16 + I16(i16), + // i32 + I32(i32), + // i64 + I64(i64), + // i128 + I128(i128), + // i256 + I256(move_core_types::int256::I256), // true // false Bool(bool), @@ -744,7 +759,7 @@ impl AbilitySet { self.0.is_subset(&other.0) } - pub fn iter(&self) -> AbilitySetIter { + pub fn iter(&self) -> AbilitySetIter<'_> { self.into_iter() } @@ -971,13 +986,13 @@ impl AstDebug for Program { fn ast_debug(&self, w: &mut AstWriter) { let Program { modules, scripts } = self; for (m, mdef) in modules.key_cloned_iter() { - w.write(&format!("module {}", m)); + w.write(format!("module {}", m)); w.block(|w| mdef.ast_debug(w)); w.new_line(); } for (n, s) in scripts { - w.write(&format!("script {}", n)); + w.write(format!("script {}", n)); w.block(|w| s.ast_debug(w)); w.new_line() } @@ -988,7 +1003,7 @@ impl AstDebug for AttributeValue_ { fn ast_debug(&self, w: &mut AstWriter) { match self { AttributeValue_::Value(v) => v.ast_debug(w), - AttributeValue_::Module(m) => w.write(&format!("{}", m)), + AttributeValue_::Module(m) => w.write(format!("{}", m)), AttributeValue_::ModuleAccess(n) => n.ast_debug(w), } } @@ -997,14 +1012,14 @@ impl AstDebug for AttributeValue_ { impl AstDebug for Attribute_ { fn ast_debug(&self, w: &mut AstWriter) { match self { - Attribute_::Name(n) => w.write(&format!("{}", n)), + Attribute_::Name(n) => w.write(format!("{}", n)), Attribute_::Assigned(n, v) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write(" = "); v.ast_debug(w); }, Attribute_::Parameterized(n, inners) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write("("); w.list(inners, ", ", |w, (_, _, inner)| { inner.ast_debug(w); @@ -1042,15 +1057,15 @@ impl AstDebug for Script { use_decls: _, } = self; if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); for (mident, neighbor) in immediate_neighbors.key_cloned_iter() { - w.write(&format!("{} {};", neighbor, mident)); + w.write(format!("{} {};", neighbor, mident)); w.new_line(); } for addr in used_addresses { - w.write(&format!("uses address {};", addr)); + w.write(format!("uses address {};", addr)); w.new_line() } for cdef in constants.key_cloned_iter() { @@ -1083,7 +1098,7 @@ impl AstDebug for ModuleDefinition { use_decls: _, } = self; if let Some(n) = package_name { - w.writeln(&format!("{}", n)) + w.writeln(format!("{}", n)) } attributes.ast_debug(w); w.writeln( @@ -1093,17 +1108,17 @@ impl AstDebug for ModuleDefinition { "library module" }, ); - w.writeln(&format!("dependency order #{}", dependency_order)); + w.writeln(format!("dependency order #{}", dependency_order)); for (mident, neighbor) in immediate_neighbors.key_cloned_iter() { - w.write(&format!("{} {};", neighbor, mident)); + w.write(format!("{} {};", neighbor, mident)); w.new_line(); } for addr in used_addresses { - w.write(&format!("uses address {};", addr)); + w.write(format!("uses address {};", addr)); w.new_line() } for (mident, _loc) in friends.key_cloned_iter() { - w.write(&format!("friend {};", mident)); + w.write(format!("friend {};", mident)); w.new_line(); } for sdef in structs.key_cloned_iter() { @@ -1145,6 +1160,7 @@ impl AstDebug for (StructName, &StructDefinition) { abilities, type_parameters, layout: fields, + visibility, }, ) = self; @@ -1154,14 +1170,14 @@ impl AstDebug for (StructName, &StructDefinition) { w.write("native "); } - w.write(&format!("struct {}", name)); + w.write(format!("{} struct {}", visibility, name)); type_parameters.ast_debug(w); ability_modifiers_ast_debug(w, abilities); if let StructLayout::Singleton(fields, _) = fields { w.block(|w| { w.list(fields, ",", |w, (_, f, idx_st)| { let (idx, st) = idx_st; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); st.ast_debug(w); true }); @@ -1192,7 +1208,7 @@ impl AstDebug for SpecBlockTarget_ { } }, SpecBlockTarget_::Schema(n, tys) => { - w.write(&format!("schema {}", n.value)); + w.write(format!("schema {}", n.value)); if !tys.is_empty() { w.write("<"); w.list(tys, ", ", |w, ty| { @@ -1266,7 +1282,7 @@ impl AstDebug for SpecBlockMember_ { } else if let FunctionBody_::Native = &body.value { w.write("native "); } - w.write(&format!("define {}", name)); + w.write(format!("define {}", name)); signature.ast_debug(w); match &body.value { FunctionBody_::Defined(body) => w.block(|w| body.ast_debug(w)), @@ -1285,7 +1301,7 @@ impl AstDebug for SpecBlockMember_ { } else { w.write("local"); } - w.write(&format!("{}", name)); + w.write(format!("{}", name)); type_parameters.ast_debug(w); w.write(": "); type_.ast_debug(w); @@ -1301,7 +1317,7 @@ impl AstDebug for SpecBlockMember_ { post_state, def, } => { - w.write(&format!( + w.write(format!( "let {}{} = ", if *post_state { "post " } else { "" }, name @@ -1376,15 +1392,15 @@ impl AstDebug for (FunctionName, &Function) { attributes.ast_debug(w); visibility.ast_debug(w); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if let FunctionBody_::Native = &body.value { w.write("native "); } if *inline { - w.write(&format!("inline fun {}", name)); + w.write(format!("inline fun {}", name)); } else { - w.write(&format!("fun {}", name)); + w.write(format!("fun {}", name)); } signature.ast_debug(w); if !acquires.is_empty() { @@ -1401,7 +1417,7 @@ impl AstDebug for (FunctionName, &Function) { impl AstDebug for Visibility { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{} ", self)) + w.write(format!("{} ", self)) } } @@ -1415,7 +1431,7 @@ impl AstDebug for FunctionSignature { type_parameters.ast_debug(w); w.write("("); w.comma(parameters, |w, (v, st)| { - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); }); w.write("): "); @@ -1435,7 +1451,7 @@ impl AstDebug for (ConstantName, &Constant) { }, ) = self; attributes.ast_debug(w); - w.write(&format!("const {}:", name)); + w.write(format!("const {}:", name)); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -1588,16 +1604,23 @@ impl AstDebug for Value_ { fn ast_debug(&self, w: &mut AstWriter) { use Value_ as V; match self { - V::Address(addr) => w.write(&format!("@{}", addr)), - V::InferredNum(u) => w.write(&format!("{}", u)), - V::U8(u) => w.write(&format!("{}u8", u)), - V::U16(u) => w.write(&format!("{}u16", u)), - V::U32(u) => w.write(&format!("{}u32", u)), - V::U64(u) => w.write(&format!("{}u64", u)), - V::U128(u) => w.write(&format!("{}u128", u)), - V::U256(u) => w.write(&format!("{}u256", u)), - V::Bool(b) => w.write(&format!("{}", b)), - V::Bytearray(v) => w.write(&format!("{:?}", v)), + V::Address(addr) => w.write(format!("@{}", addr)), + V::InferredNum(u) => w.write(format!("{}", u)), + V::U8(u) => w.write(format!("{}u8", u)), + V::U16(u) => w.write(format!("{}u16", u)), + V::U32(u) => w.write(format!("{}u32", u)), + V::U64(u) => w.write(format!("{}u64", u)), + V::U128(u) => w.write(format!("{}u128", u)), + V::U256(u) => w.write(format!("{}u256", u)), + V::InferredNegNum(i) => w.write(format!("{}", i)), + V::I8(i) => w.write(format!("{}i8", i)), + V::I16(i) => w.write(format!("{}i16", i)), + V::I32(i) => w.write(format!("{}i32", i)), + V::I64(i) => w.write(format!("{}i64", i)), + V::I128(i) => w.write(format!("{}i128", i)), + V::I256(i) => w.write(format!("{}i256", i)), + V::Bool(b) => w.write(format!("{}", b)), + V::Bytearray(v) => w.write(format!("{:?}", v)), } } } @@ -1611,8 +1634,8 @@ impl AstDebug for Exp_ { trailing: _trailing, } => w.write("/*()*/"), E::Value(v) => v.ast_debug(w), - E::Move(v) => w.write(&format!("move {}", v)), - E::Copy(v) => w.write(&format!("copy {}", v)), + E::Move(v) => w.write(format!("move {}", v)), + E::Copy(v) => w.write(format!("copy {}", v)), E::Name(ma, tys_opt) => { ma.ast_debug(w); if let Some(ss) = tys_opt { @@ -1649,7 +1672,7 @@ impl AstDebug for Exp_ { w.write("{"); w.comma(fields, |w, (_, f, idx_e)| { let (idx, e) = idx_e; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); e.ast_debug(w); }); w.write("}"); @@ -1675,7 +1698,7 @@ impl AstDebug for Exp_ { }, E::While(l, b, e) => { if let Some(l) = l { - w.write(&format!("{}: ", l.value().as_str())) + w.write(format!("{}: ", l.value().as_str())) } w.write("while ("); b.ast_debug(w); @@ -1684,7 +1707,7 @@ impl AstDebug for Exp_ { }, E::Loop(l, e) => { if let Some(l) = l { - w.write(&format!("{}: ", l.value().as_str())) + w.write(format!("{}: ", l.value().as_str())) } w.write("loop "); e.ast_debug(w); @@ -1828,15 +1851,15 @@ impl AstDebug for Exp_ { w.write(")"); }, E::Spec(u, unbound_vars, unbound_func_ptrs) => { - w.write(&format!("spec #{}", u)); + w.write(format!("spec #{}", u)); if !unbound_vars.is_empty() { w.write(" uses ["); - w.comma(unbound_vars, |w, n| w.write(&format!("{}", n))); + w.comma(unbound_vars, |w, n| w.write(format!("{}", n))); w.write("]"); } if !unbound_func_ptrs.is_empty() { w.write(" applies ["); - w.comma(unbound_func_ptrs, |w, n| w.write(&format!("{}", n))); + w.comma(unbound_func_ptrs, |w, n| w.write(format!("{}", n))); w.write("]"); } }, @@ -1852,7 +1875,7 @@ impl AstDebug for ExpDotted_ { D::Exp(e) => e.ast_debug(w), D::Dot(e, n) => { e.ast_debug(w); - w.write(&format!(".{}", n)) + w.write(format!(".{}", n)) }, } } @@ -1893,7 +1916,7 @@ impl AstDebug for LValue_ { use LValue_ as L; match self { L::Var(v, tys_opt) => { - w.write(&format!("{}", v)); + w.write(format!("{}", v)); if let Some(ss) = tys_opt { w.write("<"); ss.ast_debug(w); @@ -1910,7 +1933,7 @@ impl AstDebug for LValue_ { w.write("{"); w.comma(fields, |w, (_, f, idx_b)| { let (idx, b) = idx_b; - w.write(&format!("{}#{}: ", idx, f)); + w.write(format!("{}#{}: ", idx, f)); b.ast_debug(w); }); if !fields.is_empty() { diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs index 2b65661467e..5b0f9d72cc8 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs @@ -37,7 +37,8 @@ pub fn verify( .map(|(mident, _)| mident) .collect::>(); let graph = dependency_graph(&module_neighbors, &imm_module_idents); - let graph = add_implicit_vector_dependencies(graph); + let graph = add_implicit_module_dependencies(graph, AccountAddress::ONE, "vector"); + let graph = add_implicit_module_dependencies(graph, AccountAddress::ONE, "cmp"); match petgraph_toposort(&graph, None) { Err(cycle_node) => { let cycle_ident = *cycle_node.node_id(); @@ -180,29 +181,31 @@ impl<'a> Context<'a> { } } -/// If the `vector` module is present in `graph`, then add dependency edges -/// from every module (not in the `vector` module's dependency closure) to the -/// `vector` module. This is because modules can have implicit dependencies -/// on the `vector` module. -fn add_implicit_vector_dependencies( - mut graph: DiGraphMap<&ModuleIdent, ()>, -) -> DiGraphMap<&ModuleIdent, ()> { - let vector_module = graph.nodes().find(|m| { - m.value.address.into_addr_bytes().into_inner() == AccountAddress::ONE - && m.value.module.0.value.as_str() == "vector" +/// If the target module (`module_address::module_name`) is present in `graph`, +/// then add dependency edges from every module (not in the target module's dependency closure) +/// to the target module. This is used to maintain implicit dependencies introduced +/// by the compiler between user modules and modules like `vector` or `cmp`. +fn add_implicit_module_dependencies<'a>( + mut graph: DiGraphMap<&'a ModuleIdent, ()>, + module_address: AccountAddress, + module_name: &str, +) -> DiGraphMap<&'a ModuleIdent, ()> { + let target_module = graph.nodes().find(|m| { + m.value.address.into_addr_bytes().into_inner() == module_address + && m.value.module.0.value.as_str() == module_name }); - if let Some(vector_module) = vector_module { - let mut dfs = Dfs::new(&graph, vector_module); + if let Some(target_module) = target_module { + let mut dfs = Dfs::new(&graph, target_module); // Get the transitive closure of the `vector` module and its dependencies. - let mut vector_dep_closure = BTreeSet::new(); + let mut target_dep_closure = BTreeSet::new(); while let Some(node) = dfs.next(&graph) { - vector_dep_closure.insert(node); + target_dep_closure.insert(node); } // For every module that is not in `vector_dep_closure`, add an edge to `vector_module`. let all_modules = graph.nodes().collect::>(); for module in all_modules { - if !vector_dep_closure.contains(module) { - graph.add_edge(module, vector_module, ()); + if !target_dep_closure.contains(module) { + graph.add_edge(module, target_module, ()); } } } diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs index 0f785292bd3..2cb48f12e88 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/translate.rs @@ -23,13 +23,15 @@ use crate::{ shared::{ builtins, known_attributes::{AttributeKind, AttributePosition, KnownAttribute}, - parse_u128, parse_u64, parse_u8, unique_map::UniqueMap, CompilationEnv, Identifier, Name, NamedAddressMap, NamedAddressMaps, NumericalAddress, }, FullyCompiledProgram, }; -use move_command_line_common::parser::{parse_u16, parse_u256, parse_u32}; +use move_command_line_common::parser::{ + parse_i128, parse_i16, parse_i256, parse_i32, parse_i64, parse_i8, parse_u128, parse_u16, + parse_u256, parse_u32, parse_u64, parse_u8, +}; use move_ir_types::location::*; use move_symbol_pool::Symbol; use once_cell::sync::Lazy; @@ -1431,6 +1433,7 @@ fn struct_def_( abilities: abilities_vec, type_parameters: pty_params, layout: pfields, + visibility: pvisibility, } = pstruct; let was_in_deprecated_code = context.enter_possibly_deprecated_member(&name.0); let attributes = flatten_attributes(context, AttributePosition::Struct, attributes); @@ -1440,12 +1443,14 @@ fn struct_def_( .shadow_for_type_parameters(type_parameters.iter().map(|tp| &tp.name)); let abilities = ability_set(context, "modifier", abilities_vec); let fields = struct_layout(context, &name, pfields); + let visibility = visibility(pvisibility); let sdef = E::StructDefinition { attributes, loc, abilities, type_parameters, layout: fields, + visibility, }; context.set_to_outer_scope(old_aliases); context.set_in_deprecated_code(was_in_deprecated_code); @@ -2673,6 +2678,7 @@ fn exp_(context: &mut Context, sp!(loc, pe_): P::Exp) -> E::Exp { // { let t2 = e2; let t1 = e1; *t1 = *t1 + t2 } Some(op) => { // t2, let t2 = e2; + let lhs_loc = el.loc; let (tmp2, bind2) = let_symbol_eq_exp(er.loc, Symbol::from("$t2"), *er); // t1, let t1 = e1; let (tmp1, bind1) = @@ -2681,7 +2687,7 @@ fn exp_(context: &mut Context, sp!(loc, pe_): P::Exp) -> E::Exp { _ => *el, }); // *t1 - let deref_tmp1 = sp(loc, EE::Dereference(Box::new(tmp1.clone()))); + let deref_tmp1 = sp(lhs_loc, EE::Dereference(Box::new(tmp1.clone()))); // *t1 + t2 let rhs_expanded = sp(loc, EE::BinopExp(Box::new(deref_tmp1), op, Box::new(tmp2))); @@ -2711,7 +2717,7 @@ fn exp_(context: &mut Context, sp!(loc, pe_): P::Exp) -> E::Exp { // t1, let t1 = &mut e1.f; let (tmp1, bind1) = let_symbol_eq_exp(lhs_loc, Symbol::from("$t1"), e_mut); // *t1 - let deref_tmp1 = sp(loc, EE::Dereference(Box::new(tmp1.clone()))); + let deref_tmp1 = sp(lhs_loc, EE::Dereference(Box::new(tmp1.clone()))); // *t1 + t2 let rhs_expanded = sp(loc, EE::BinopExp(Box::new(deref_tmp1), op, Box::new(tmp2))); @@ -2829,50 +2835,100 @@ fn value(context: &mut Context, sp!(loc, pvalue_): P::Value) -> Option PV::Num(s) if s.ends_with("u8") => match parse_u8(&s[..s.len() - 2]) { Ok((u, _format)) => EV::U8(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u8'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u8'")); return None; }, }, PV::Num(s) if s.ends_with("u16") => match parse_u16(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U16(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u16'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u16'")); return None; }, }, PV::Num(s) if s.ends_with("u32") => match parse_u32(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U32(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u32'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u32'")); return None; }, }, PV::Num(s) if s.ends_with("u64") => match parse_u64(&s[..s.len() - 3]) { Ok((u, _format)) => EV::U64(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u64'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u64'")); return None; }, }, PV::Num(s) if s.ends_with("u128") => match parse_u128(&s[..s.len() - 4]) { Ok((u, _format)) => EV::U128(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u128'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u128'")); return None; }, }, PV::Num(s) if s.ends_with("u256") => match parse_u256(&s[..s.len() - 4]) { - Ok((u, _format)) => EV::U256(u), + Ok(u) => EV::U256(u), Err(_) => { - context.env.add_diag(num_too_big_error(loc, "'u256'")); + context.env.add_diag(num_cannot_fit_error(loc, "'u256'")); return None; }, }, - + PV::Num(s) if s.ends_with("i8") => match parse_i8(&s[..s.len() - 2]) { + Ok((i, _format)) => EV::I8(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i8'")); + return None; + }, + }, + PV::Num(s) if s.ends_with("i16") => match parse_i16(&s[..s.len() - 3]) { + Ok((i, _format)) => EV::I16(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i16'")); + return None; + }, + }, + PV::Num(s) if s.ends_with("i32") => match parse_i32(&s[..s.len() - 3]) { + Ok((i, _format)) => EV::I32(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i32'")); + return None; + }, + }, + PV::Num(s) if s.ends_with("i64") => match parse_i64(&s[..s.len() - 3]) { + Ok((i, _format)) => EV::I64(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i64'")); + return None; + }, + }, + PV::Num(s) if s.ends_with("i128") => match parse_i128(&s[..s.len() - 4]) { + Ok((i, _format)) => EV::I128(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i128'")); + return None; + }, + }, + PV::Num(s) if s.ends_with("i256") => match parse_i256(&s[..s.len() - 4]) { + Ok(i) => EV::I256(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i256'")); + return None; + }, + }, + // non-typed negative number literal + PV::Num(s) if s.starts_with("-") => match parse_i256(&s) { + Ok(i) => EV::InferredNegNum(i), + Err(_) => { + context.env.add_diag(num_cannot_fit_error(loc, "'i256'")); + return None; + }, + }, + // non-typed number literal PV::Num(s) => match parse_u256(&s) { - Ok((u, _format)) => EV::InferredNum(u), + Ok(u) => EV::InferredNum(u), Err(_) => { - context.env.add_diag(num_too_big_error( + context.env.add_diag(num_cannot_fit_error( loc, "the largest possible integer type, 'u256'", )); @@ -2898,15 +2954,15 @@ fn value(context: &mut Context, sp!(loc, pvalue_): P::Value) -> Option Some(sp(loc, value_)) } -// Create an error for an integer literal that is too big to fit in its type. +// Create an error for an integer literal that cannot fit in its type. // This assumes that the literal is the current token. -fn num_too_big_error(loc: Loc, type_description: &'static str) -> Diagnostic { +fn num_cannot_fit_error(loc: Loc, type_description: &'static str) -> Diagnostic { diag!( Syntax::InvalidNumber, ( loc, format!( - "Invalid number literal. The given literal is too large to fit into {}", + "Invalid number literal. The given literal cannot fit into {}", type_description ) ), diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/interface_generator.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/interface_generator.rs index 83b0017fbb7..3679120448e 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/interface_generator.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/interface_generator.rs @@ -365,6 +365,12 @@ fn write_signature_token(ctx: &mut Context, t: &SignatureToken) -> String { SignatureToken::U64 => "u64".to_string(), SignatureToken::U128 => "u128".to_string(), SignatureToken::U256 => "u256".to_string(), + SignatureToken::I8 => "i8".to_string(), + SignatureToken::I16 => "i16".to_string(), + SignatureToken::I32 => "i32".to_string(), + SignatureToken::I64 => "i64".to_string(), + SignatureToken::I128 => "i128".to_string(), + SignatureToken::I256 => "i256".to_string(), SignatureToken::Address => "address".to_string(), SignatureToken::Signer => "signer".to_string(), SignatureToken::Vector(inner) => format!("vector<{}>", write_signature_token(ctx, inner)), diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs index 3013b72d5a0..0fb02075971 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/ast.rs @@ -218,6 +218,7 @@ pub struct StructDefinition { pub name: StructName, pub type_parameters: Vec, pub layout: StructLayout, + pub visibility: Visibility, } #[derive(Debug, PartialEq, Clone)] @@ -245,6 +246,7 @@ new_name!(FunctionName); pub const NATIVE_MODIFIER: &str = "native"; pub const ENTRY_MODIFIER: &str = "entry"; +pub const ENUM_MODIFIER: &str = "enum"; /// An access specifier describes the resources being accessed by a function. /// In contrast to regular `NameAccessChain`, the identifiers inside of the @@ -571,6 +573,8 @@ pub type Value = Spanned; pub enum UnaryOp_ { // ! Not, + // - (negate) + Negate, } pub type UnaryOp = Spanned; @@ -924,12 +928,14 @@ impl Type_ { } impl UnaryOp_ { + pub const NEGATE: &'static str = "-"; pub const NOT: &'static str = "!"; pub fn symbol(&self) -> &'static str { use UnaryOp_ as U; match self { U::Not => U::NOT, + U::Negate => U::NEGATE, } } @@ -937,6 +943,7 @@ impl UnaryOp_ { use UnaryOp_ as U; match self { U::Not => true, + U::Negate => false, // negating the minimal value will overflow } } } @@ -1146,7 +1153,7 @@ fn ast_debug_package_definition( def, } = pkg; match package { - Some(n) => w.writeln(&format!("package: {}", n)), + Some(n) => w.writeln(format!("package: {}", n)), None => w.writeln("no package"), } named_address_maps.get(*named_address_map).ast_debug(w); @@ -1156,7 +1163,7 @@ fn ast_debug_package_definition( impl AstDebug for NamedAddressMap { fn ast_debug(&self, w: &mut AstWriter) { for (sym, addr) in self { - w.write(&format!("{} => {}", sym, addr)); + w.write(format!("{} => {}", sym, addr)); w.new_line() } } @@ -1181,7 +1188,7 @@ impl AstDebug for AddressDefinition { modules, } = self; attributes.ast_debug(w); - w.write(&format!("address {}", addr)); + w.write(format!("address {}", addr)); w.writeln(" {{"); for m in modules { m.ast_debug(w) @@ -1202,14 +1209,14 @@ impl AstDebug for AttributeValue_ { impl AstDebug for Attribute_ { fn ast_debug(&self, w: &mut AstWriter) { match self { - Attribute_::Name(n) => w.write(&format!("{}", n)), + Attribute_::Name(n) => w.write(format!("{}", n)), Attribute_::Assigned(n, v) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write(" = "); v.ast_debug(w); }, Attribute_::Parameterized(n, inners) => { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); w.write("("); w.list(&inners.value, ", ", |w, inner| { inner.ast_debug(w); @@ -1282,12 +1289,12 @@ impl AstDebug for ModuleDefinition { } = self; attributes.ast_debug(w); match address { - None => w.write(&format!( + None => w.write(format!( "module {}{}", if *is_spec_module { "spec " } else { "" }, name )), - Some(addr) => w.write(&format!("module {}::{}", addr, name)), + Some(addr) => w.write(format!("module {}::{}", addr, name)), }; w.block(|w| { for mem in members { @@ -1322,18 +1329,18 @@ impl AstDebug for Use { fn ast_debug(&self, w: &mut AstWriter) { match self { Use::Module(m, alias_opt) => { - w.write(&format!("use {}", m)); + w.write(format!("use {}", m)); if let Some(alias) = alias_opt { - w.write(&format!(" as {}", alias)) + w.write(format!(" as {}", alias)) } }, Use::Members(m, sub_uses) => { - w.write(&format!("use {}::", m)); + w.write(format!("use {}::", m)); w.block(|w| { w.comma(sub_uses, |w, (n, alias_opt)| { - w.write(&format!("{}", n)); + w.write(format!("{}", n)); if let Some(alias) = alias_opt { - w.write(&format!(" as {}", alias)) + w.write(format!(" as {}", alias)) } }) }) @@ -1351,7 +1358,7 @@ impl AstDebug for FriendDecl { friend, } = self; attributes.ast_debug(w); - w.write(&format!("friend {}", friend)); + w.write(format!("friend {}", friend)); } } @@ -1364,6 +1371,7 @@ impl AstDebug for StructDefinition { name, type_parameters, layout, + visibility, } = self; attributes.ast_debug(w); @@ -1376,12 +1384,12 @@ impl AstDebug for StructDefinition { w.write("native "); } - w.write(&format!("struct {}", name)); + w.write(format!("{} struct {}", visibility, name)); type_parameters.ast_debug(w); match layout { StructLayout::Singleton(fields, _) => w.block(|w| { w.semicolon(fields, |w, (f, st)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); st.ast_debug(w); }); }), @@ -1413,7 +1421,7 @@ impl AstDebug for SpecBlockTarget_ { } }, SpecBlockTarget_::Schema(n, tys) => { - w.write(&format!("schema {}", n.value)); + w.write(format!("schema {}", n.value)); if !tys.is_empty() { w.write("<"); w.list(tys, ", ", |w, ty| { @@ -1488,7 +1496,7 @@ impl AstDebug for SpecBlockMember_ { w.write("native "); } w.write("fun "); - w.write(&format!("{}", name)); + w.write(format!("{}", name)); signature.ast_debug(w); match &body.value { FunctionBody_::Defined(body) => w.block(|w| body.ast_debug(w)), @@ -1507,7 +1515,7 @@ impl AstDebug for SpecBlockMember_ { } else { w.write("local"); } - w.write(&format!("{}", name)); + w.write(format!("{}", name)); type_parameters.ast_debug(w); w.write(": "); type_.ast_debug(w); @@ -1523,7 +1531,7 @@ impl AstDebug for SpecBlockMember_ { post_state, def, } => { - w.write(&format!( + w.write(format!( "let {}{} = ", if *post_state { "post " } else { "" }, name @@ -1617,15 +1625,15 @@ impl AstDebug for Function { attributes.ast_debug(w); visibility.ast_debug(w); if entry.is_some() { - w.write(&format!("{} ", ENTRY_MODIFIER)); + w.write(format!("{} ", ENTRY_MODIFIER)); } if let FunctionBody_::Native = &body.value { w.write("native "); } if *inline { - w.write(&format!("inline fun {}", name)); + w.write(format!("inline fun {}", name)); } else { - w.write(&format!("fun {}", name)); + w.write(format!("fun {}", name)); } signature.ast_debug(w); match &body.value { @@ -1637,7 +1645,7 @@ impl AstDebug for Function { impl AstDebug for Visibility { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{} ", self)) + w.write(format!("{} ", self)) } } @@ -1651,7 +1659,7 @@ impl AstDebug for FunctionSignature { type_parameters.ast_debug(w); w.write("("); w.comma(parameters, |w, (v, st)| { - w.write(&format!("{}: ", v)); + w.write(format!("{}: ", v)); st.ast_debug(w); }); w.write(")"); @@ -1670,7 +1678,7 @@ impl AstDebug for Constant { value, } = self; attributes.ast_debug(w); - w.write(&format!("const {}:", name)); + w.write(format!("const {}:", name)); signature.ast_debug(w); w.write(" = "); value.ast_debug(w); @@ -1733,7 +1741,7 @@ fn ability_constraints_ast_debug(w: &mut AstWriter, abilities: &[Ability]) { impl AstDebug for Ability_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)) + w.write(format!("{}", self)) } } @@ -1780,7 +1788,7 @@ impl AstDebug for Vec { impl AstDebug for NameAccessChain_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)) + w.write(format!("{}", self)) } } @@ -1841,8 +1849,8 @@ impl AstDebug for Exp_ { match self { E::Unit => w.write("()"), E::Value(v) => v.ast_debug(w), - E::Move(v) => w.write(&format!("move {}", v)), - E::Copy(v) => w.write(&format!("copy {}", v)), + E::Move(v) => w.write(format!("move {}", v)), + E::Copy(v) => w.write(format!("copy {}", v)), E::Name(ma, tys_opt) => { ma.ast_debug(w); if let Some(ss) = tys_opt { @@ -1878,7 +1886,7 @@ impl AstDebug for Exp_ { } w.write("{"); w.comma(fields, |w, (f, e)| { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); e.ast_debug(w); }); w.write("}"); @@ -1920,7 +1928,7 @@ impl AstDebug for Exp_ { }, E::While(l, b, e) => { if let Some(l) = l { - w.write(&format!("{}: ", l.value().as_str())) + w.write(format!("{}: ", l.value().as_str())) } w.write("while ("); b.ast_debug(w); @@ -1929,7 +1937,7 @@ impl AstDebug for Exp_ { }, E::Loop(l, e) => { if let Some(l) = l { - w.write(&format!("{}: ", l.value().as_str())) + w.write(format!("{}: ", l.value().as_str())) } w.write("loop "); e.ast_debug(w); @@ -2023,7 +2031,7 @@ impl AstDebug for Exp_ { }, E::Dot(e, n) => { e.ast_debug(w); - w.write(&format!(".{}", n)); + w.write(format!(".{}", n)); }, E::Cast(e, ty) => { w.write("("); @@ -2067,13 +2075,13 @@ impl AstDebug for Exp_ { impl AstDebug for BinOp_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)); + w.write(format!("{}", self)); } } impl AstDebug for UnaryOp_ { fn ast_debug(&self, w: &mut AstWriter) { - w.write(&format!("{}", self)); + w.write(format!("{}", self)); } } @@ -2150,7 +2158,7 @@ impl AstDebug for BindFieldOrDotDot_ { use BindFieldOrDotDot_ as B; match self { B::FieldBind(f, b) => { - w.write(&format!("{}: ", f)); + w.write(format!("{}: ", f)); b.ast_debug(w); }, B::DotDot => w.write(".."), @@ -2172,7 +2180,7 @@ impl AstDebug for Bind_ { fn ast_debug(&self, w: &mut AstWriter) { use Bind_ as B; match self { - B::Var(v) => w.write(&format!("{}", v)), + B::Var(v) => w.write(format!("{}", v)), B::Unpack(ma, tys_opt, fields) => { ma.ast_debug(w); if let Some(ss) = tys_opt { diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/lexer.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/lexer.rs index 4bbbc164e26..a7769a896ae 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/lexer.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/lexer.rs @@ -734,11 +734,21 @@ fn get_hex_number(text: &str) -> (Tok, usize) { // portion, checks for a typed suffix. fn get_number_maybe_with_suffix(text: &str, num_text_len: usize) -> (Tok, usize) { let rest = &text[num_text_len..]; - if rest.starts_with("u8") { + if rest.starts_with("u8") || rest.starts_with("i8") { (Tok::NumTypedValue, num_text_len + 2) - } else if rest.starts_with("u64") || rest.starts_with("u16") || rest.starts_with("u32") { + } else if rest.starts_with("u16") + || rest.starts_with("u32") + || rest.starts_with("u64") + || rest.starts_with("i16") + || rest.starts_with("i32") + || rest.starts_with("i64") + { (Tok::NumTypedValue, num_text_len + 3) - } else if rest.starts_with("u128") || rest.starts_with("u256") { + } else if rest.starts_with("u128") + || rest.starts_with("u256") + || rest.starts_with("i128") + || rest.starts_with("i256") + { (Tok::NumTypedValue, num_text_len + 4) } else { // No typed suffix diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs index 5cffb4308f9..0ec285f7f28 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/parser/syntax.rs @@ -2219,6 +2219,37 @@ fn parse_unary_exp(context: &mut Context) -> Result> { let e = parse_unary_exp(context)?; Exp_::UnaryExp(op, Box::new(e)) }, + // Parse `Minus` as the `Negate` unary operator + Tok::Minus => { + context.tokens.advance()?; + let op_end_loc = context.tokens.previous_end_loc(); + let e = parse_unary_exp(context)?; + // if the operand is a numeric literal, we fold the negation into the literal + if let Exp_::Value(Spanned { + loc, + value: Value_::Num(s), + }) = e.value + { + let neg_num = format!("-{}", s.as_str()); + // the new literal now spans from the `-` to the end of the original literal + let op_end_loc = loc.end(); + Exp_::Value(spanned( + context.tokens.file_hash(), + start_loc, + op_end_loc as usize, + Value_::Num(Symbol::from(neg_num)), + )) + } else { + // otherwise, we create a new unary negation operator + let op = spanned( + context.tokens.file_hash(), + start_loc, + op_end_loc, + UnaryOp_::Negate, + ); + Exp_::UnaryExp(op, Box::new(e)) + } + }, Tok::AmpMut => { context.tokens.advance()?; let e = parse_unary_exp(context)?; @@ -3046,9 +3077,9 @@ fn parse_address_specifier(context: &mut Context) -> Result ? ";" -// | "struct" ? "{" Comma "}" ( ";")? -// | "struct" ( "(" Comma ")" )? ?";" -// | "enum" ? "{" Comma "}" ( ";")? +// | "struct" ? "{" Comma "}" ( ";")? +// | "struct" ( "(" Comma ")" )? ?";" +// | "enum" ? "{" Comma "}" ( ";")? // StructDefName = // // EnumVariant = @@ -3065,11 +3096,12 @@ fn parse_struct_decl( context: &mut Context, ) -> Result> { let Modifiers { - visibility, + visibility: visibility_opt, entry, native, } = modifiers; - match visibility { + let mut visibility = Visibility::Internal; + match visibility_opt { Some(vis) if !context.env.flags().lang_v2() => { let msg = format!( "Invalid struct declaration. Structs cannot have visibility modifiers as they are \ @@ -3080,6 +3112,9 @@ fn parse_struct_decl( .env .add_diag(diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg))); }, + Some(vis) => { + visibility = vis; + }, _ => {}, } if let Some(loc) = entry { @@ -3168,6 +3203,7 @@ fn parse_struct_decl( name, type_parameters, layout, + visibility, }) } @@ -3510,7 +3546,10 @@ fn parse_use_alias(context: &mut Context) -> Result, Box bool { if context.tokens.peek() == Tok::Friend { if let Ok((tok, content)) = context.tokens.lookahead_content() { - if ![Tok::Fun, Tok::Inline, Tok::Native].contains(&tok) && content != ENTRY_MODIFIER { + if ![Tok::Fun, Tok::Inline, Tok::Native, Tok::Struct].contains(&tok) + && content != ENTRY_MODIFIER + && content != ENUM_MODIFIER + { return true; } } @@ -3619,7 +3658,7 @@ fn parse_module( Tok::Struct => ModuleMember::Struct(parse_struct_decl( false, attributes, start_loc, modifiers, context, )?), - Tok::Identifier if context.tokens.content() == "enum" => { + Tok::Identifier if context.tokens.content() == ENUM_MODIFIER => { ModuleMember::Struct(parse_struct_decl( true, attributes, start_loc, modifiers, context, )?) diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/mod.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/mod.rs index e34c7b92185..b1f00a07ce1 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/mod.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/mod.rs @@ -566,6 +566,10 @@ pub enum LanguageVersion { V2_2, #[value(name = "2.3")] V2_3, + #[value(name = "2.4")] + V2_4, + #[value(name = "2.5")] + V2_5, } impl LanguageVersion { @@ -577,6 +581,8 @@ impl LanguageVersion { V2 | V2_1 => 2, V2_2 => 3, V2_3 => 4, + V2_4 => 5, + V2_5 => 6, } } } @@ -591,7 +597,7 @@ impl Eq for LanguageVersion {} impl PartialOrd for LanguageVersion { fn partial_cmp(&self, other: &LanguageVersion) -> Option { - Some(self.to_ordinal().cmp(&other.to_ordinal())) + Some(self.cmp(other)) } } @@ -610,6 +616,8 @@ impl std::fmt::Display for LanguageVersion { LanguageVersion::V2_1 => "2.1", LanguageVersion::V2_2 => "2.2", LanguageVersion::V2_3 => "2.3", + LanguageVersion::V2_4 => "2.4", + LanguageVersion::V2_5 => "2.5", }) } } diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/remembering_unique_map.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/remembering_unique_map.rs index 8c971da5a09..ecdd031f1be 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/remembering_unique_map.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/remembering_unique_map.rs @@ -104,11 +104,11 @@ impl RememberingUniqueMap { } } - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, K, V> { self.into_iter() } - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { self.into_iter() } diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_map.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_map.rs index 75b79896692..24e1f405d71 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_map.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_map.rs @@ -151,7 +151,7 @@ impl UniqueMap { joined } - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, K, V> { self.into_iter() } @@ -160,7 +160,7 @@ impl UniqueMap { .map(|(loc, k_, v)| (K::add_loc(loc, k_.clone()), v)) } - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { self.into_iter() } diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_set.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_set.rs index 3337be0f66c..f1e1961bbac 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_set.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/shared/unique_set.rs @@ -82,11 +82,11 @@ impl UniqueSet { self.iter().all(|(_, x_)| other.contains_(x_)) } - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { self.into_iter() } - pub fn cloned_iter(&self) -> impl Iterator { + pub fn cloned_iter(&self) -> impl Iterator + use { self.into_iter() .map(|(loc, k_)| T::add_loc(loc, k_.clone())) .collect::>() diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/unit_test/mod.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/unit_test/mod.rs index e082ca973cd..73fa5e9010c 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/unit_test/mod.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/unit_test/mod.rs @@ -130,7 +130,7 @@ impl TestPlan { } impl ExpectedMoveError { - pub fn verbiage(&self, is_past_tense: bool) -> ExpectedMoveErrorDisplay { + pub fn verbiage(&self, is_past_tense: bool) -> ExpectedMoveErrorDisplay<'_> { ExpectedMoveErrorDisplay { error: self, is_past_tense, diff --git a/third_party/move/move-compiler-v2/src/bytecode_generator.rs b/third_party/move/move-compiler-v2/src/bytecode_generator.rs index 3e3982fdfbd..39e9a88f9b6 100644 --- a/third_party/move/move-compiler-v2/src/bytecode_generator.rs +++ b/third_party/move/move-compiler-v2/src/bytecode_generator.rs @@ -2,17 +2,18 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::Options; +use crate::{Options, COMPILER_BUG_REPORT_MSG}; use codespan_reporting::diagnostic::Severity; -use ethnum::U256; +use ethnum::{I256, U256}; use itertools::Itertools; +use move_binary_format::file_format::Visibility; use move_core_types::ability::Ability; use move_model::{ ast::{Exp, ExpData, MatchArm, Operation, Pattern, SpecBlockTarget, TempIndex, Value}, exp_rewriter::{ExpRewriter, ExpRewriterFunctions, RewriteTarget}, metadata::LanguageVersion, model::{ - FieldId, FunId, FunctionEnv, GlobalEnv, Loc, NodeId, Parameter, QualifiedId, + FieldId, FunId, FunctionEnv, GlobalEnv, Loc, ModuleId, NodeId, Parameter, QualifiedId, QualifiedInstId, StructId, }, symbol::Symbol, @@ -26,7 +27,7 @@ use move_stackless_bytecode::{ }, stackless_bytecode_generator::BytecodeGeneratorContext, }; -use num::ToPrimitive; +use num::{BigInt, ToPrimitive, Zero}; use std::{ collections::{BTreeMap, BTreeSet}, fmt, @@ -38,7 +39,7 @@ use std::{ /// This returns `FunctionData` suitable for the bytecode processing pipeline. pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionData { let func_env = env.get_function(fid); - let mut gen = Generator { + let mut gnr = Generator { func_env, context: Default::default(), temps: Default::default(), @@ -52,32 +53,32 @@ pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionDa local_names: BTreeMap::new(), }; let mut scope = BTreeMap::new(); - for Parameter(name, ty, _) in gen.func_env.get_parameters() { - let temp = gen.new_temp(ty); + for Parameter(name, ty, _) in gnr.func_env.get_parameters() { + let temp = gnr.new_temp(ty); scope.insert(name, temp); - gen.local_names.insert(temp, name); + gnr.local_names.insert(temp, name); } - let tys = gen.func_env.get_result_type().flatten(); + let tys = gnr.func_env.get_result_type().flatten(); let multiple = tys.len() > 1; for (p, ty) in tys.into_iter().enumerate() { - let temp = gen.new_temp(ty); - gen.results.push(temp); - let pool = gen.func_env.module_env.symbol_pool(); + let temp = gnr.new_temp(ty); + gnr.results.push(temp); + let pool = gnr.func_env.module_env.symbol_pool(); let name = if multiple { pool.make(&format!("return[{}]", p)) } else { pool.make("return") }; - gen.local_names.insert(temp, name); + gnr.local_names.insert(temp, name); } - gen.scopes.push(scope); - let optional_def = gen.func_env.get_def().cloned(); + gnr.scopes.push(scope); + let optional_def = gnr.func_env.get_def().cloned(); if let Some(def) = optional_def { - let results = gen.results.clone(); + let results = gnr.results.clone(); // Need to clone expression if present because of sharing issues with `gen`. However, because // of interning, clone is cheap. - gen.gen(results.clone(), &def); - gen.emit_with(def.result_node_id(), |attr| Bytecode::Ret(attr, results)) + gnr.generate(results.clone(), &def); + gnr.emit_with(def.result_node_id(), |attr| Bytecode::Ret(attr, results)) } let Generator { func_env, @@ -91,7 +92,7 @@ pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionDa results: _, code, local_names, - } = gen; + } = gnr; let BytecodeGeneratorContext { loop_unrolling, loop_invariants, @@ -317,7 +318,21 @@ impl<'env> Generator<'env> { /// Report an (internal) error at the location associated with the node. fn internal_error(&self, id: NodeId, msg: impl AsRef) { - self.diag(id, Severity::Bug, msg) + let env = self.env(); + let loc = env.get_node_loc(id); + env.diag_with_notes( + Severity::Bug, + loc.as_ref(), + &format!("compiler internal error: {}", msg.as_ref()), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ); + } + + /// Check if the current module is at least version 2.4. + fn check_version_for_cross_module_access(&self) -> bool { + self.env() + .language_version() + .language_version_for_public_struct() } fn diag(&self, id: NodeId, severity: Severity, msg: impl AsRef) { @@ -351,7 +366,7 @@ impl<'env> Generator<'env> { // Dispatcher impl Generator<'_> { - fn gen(&mut self, targets: Vec, exp: &Exp) { + fn generate(&mut self, targets: Vec, exp: &Exp) { match exp.as_ref() { ExpData::Invalid(id) => self.internal_error(*id, "invalid expression"), ExpData::Temporary(id, temp) => self.gen_temporary(targets, *id, *temp), @@ -382,11 +397,11 @@ impl Generator<'_> { .into_iter() .map(|ty| self.new_temp(ty)) .collect::>(); - self.gen(step_targets.clone(), step); + self.generate(step_targets.clone(), step); self.release_temps(step_targets) } if let Some(final_step) = exps.last() { - self.gen(targets, final_step) + self.generate(targets, final_step) } else { self.release_temps(targets) } @@ -407,14 +422,14 @@ impl Generator<'_> { // temporary for `binding` and directly pass the temp for `x` into // translation. let local = self.find_local_for_pattern(*var_id, *sym, Some(&scope)); - self.without_reference_mode(|s| s.gen(vec![local], binding)) + self.without_reference_mode(|s| s.generate(vec![local], binding)) } else { self.gen_assign(pat.node_id(), pat, binding, Some(&scope)); } } // Compile the body self.scopes.push(scope); - self.gen(targets, body); + self.generate(targets, body); self.scopes.pop(); }, ExpData::Mutate(id, lhs, rhs) => { @@ -445,7 +460,7 @@ impl Generator<'_> { ExpData::Assign(id, lhs, rhs) => self.gen_assign(*id, lhs, rhs, None), ExpData::Return(id, exp) => { let results = self.results.clone(); - self.gen(results.clone(), exp); + self.generate(results.clone(), exp); self.emit_with(*id, |attr| Bytecode::Ret(attr, results)) }, ExpData::IfElse(id, cond, then_exp, else_exp) => { @@ -458,11 +473,11 @@ impl Generator<'_> { }); let then_id = then_exp.node_id(); self.emit_with(then_id, |attr| Bytecode::Label(attr, then_label)); - self.gen(targets.clone(), then_exp); + self.generate(targets.clone(), then_exp); self.emit_with(then_id, |attr| Bytecode::Jump(attr, end_label)); let else_id = else_exp.node_id(); self.emit_with(else_id, |attr| Bytecode::Label(attr, else_label)); - self.gen(targets, else_exp); + self.generate(targets, else_exp); self.emit_with(else_id, |attr| Bytecode::Label(attr, end_label)); }, ExpData::Match(id, exp, arms) => self.gen_match(targets, *id, exp, arms), @@ -474,7 +489,7 @@ impl Generator<'_> { break_label, }); self.emit_with(*id, |attr| Bytecode::Label(attr, continue_label)); - self.gen(vec![], body); + self.generate(vec![], body); self.loops.pop(); self.emit_with(*id, |attr| Bytecode::Jump(attr, continue_label)); self.emit_with(*id, |attr| Bytecode::Label(attr, break_label)); @@ -548,8 +563,38 @@ impl Generator<'_> { }, Type::Primitive(PrimitiveType::U256) => { // No direct way to go from BigInt to ethnum::U256... - let x = U256::from_str_radix(&x.to_str_radix(16), 16).unwrap(); - Constant::U256(x) + // Detour: convert BitInt to little-endian bytes, then interpret as U256. + let x = x.to_bytes_le(); + // Must fit into 32 bytes. This `assert!` should not be triggered as previous value translator has checked the value range of the BigInt. + assert!(x.0 != num::bigint::Sign::Minus && x.1.len() <= 32); + let mut bytes = [0u8; 32]; + bytes[..x.1.len()].copy_from_slice(&x.1); + Constant::U256(U256::from_le_bytes(bytes)) + }, + Type::Primitive(PrimitiveType::I8) => Constant::I8(x.to_i8().unwrap_or_default()), + Type::Primitive(PrimitiveType::I16) => { + Constant::I16(x.to_i16().unwrap_or_default()) + }, + Type::Primitive(PrimitiveType::I32) => { + Constant::I32(x.to_i32().unwrap_or_default()) + }, + Type::Primitive(PrimitiveType::I64) => { + Constant::I64(x.to_i64().unwrap_or_default()) + }, + Type::Primitive(PrimitiveType::I128) => { + Constant::I128(x.to_i128().unwrap_or_default()) + }, + Type::Primitive(PrimitiveType::I256) => { + // No direct way to go from BigInt to ethnum::I256... + // Detour: convert BitInt to signed little-endian bytes (i.e., 2's complement), then interpret as I256. + let pad = if *x < BigInt::zero() { 0xFFu8 } else { 0x00u8 }; + let x = x.to_signed_bytes_le(); + // Must fit into 32 bytes. This `assert!` should not be triggered as previous value translator has checked the value range of the BigInt. + assert!(x.len() <= 32); + // `BigInt::to_signed_bytes_le` returns the shortest representation, so we need to sign-extend to 32 bytes. + let mut bytes = [pad; 32]; + bytes[..x.len()].copy_from_slice(&x); + Constant::I256(I256::from_le_bytes(bytes)) }, ty => { self.internal_error(id, format!("inconsistent numeric constant: {:?}", ty)); @@ -648,18 +693,17 @@ impl Generator<'_> { let raw_fun_temp = self.new_temp(raw_fun_ty); // This here should be well-defined because only structs can be wrappers. let (wrapper_struct, inst) = fun_ty.get_struct(self.env()).unwrap(); + let inst: Vec = inst.to_vec(); let struct_id = wrapper_struct.get_qualified_id(); - if struct_id.module_id != self.func_env.module_env.get_id() { - self.error( - id, - format!( - "cannot unpack a wrapper struct `{}` (defined in a different module `{}`) and invoke the wrapped function value ", - wrapper_struct.get_full_name_str(), - self.func_env.env().get_module(struct_id.module_id).get_full_name_str(), - ), - ) - } - let inst = inst.to_vec(); + self.check_pack_unpack_wrapper( + id, + self.func_env.module_env.get_id(), + fun_ty, + struct_id.module_id, + struct_id.id, + "unpack", + " and invoke the wrapped function value", + ); self.emit_with(id, |attr| { Bytecode::Call( attr, @@ -696,7 +740,7 @@ impl Generator<'_> { ) } else { for (target, arg) in targets.into_iter().zip(args.iter()) { - self.gen(vec![target], arg) + self.generate(vec![target], arg) } } }, @@ -857,16 +901,15 @@ impl Generator<'_> { ); let target_ty = self.temp_type(targets[0]).clone(); if let Type::Struct(wrapper_mid, wrapper_sid, wrapper_inst) = target_ty.clone() { - if wrapper_mid != *mid { - self.error( - id, - format!( - "cannot implicitly pack a wrapper struct `{}` defined in a different module `{}`", - target_ty.display(&self.func_env.get_type_display_ctx()), - self.func_env.env().get_module(wrapper_mid).get_full_name_str(), - ), - ); - } + self.check_pack_unpack_wrapper( + id, + *mid, + target_ty, + wrapper_mid, + wrapper_sid, + "pack", + "", + ); // Implicitly convert to a function wrapper. let fun_ty = self .env() @@ -923,6 +966,7 @@ impl Generator<'_> { Operation::Le => self.gen_op_call_auto_freeze(targets, id, BytecodeOperation::Le, args), Operation::Ge => self.gen_op_call_auto_freeze(targets, id, BytecodeOperation::Ge, args), Operation::Not => self.gen_op_call(targets, id, BytecodeOperation::Not, args), + Operation::Negate => self.gen_op_call(targets, id, BytecodeOperation::Negate, args), Operation::NoOp => {}, // do nothing @@ -977,6 +1021,61 @@ impl Generator<'_> { } } + /// Check whether we can pack/unpack a wrapper struct + /// if public struct is not supported, pack/unpack can only happen in the module that defines the wrapper struct + /// otherwise, error is raised when either the struct is private or the struct is package/friend + /// and pack/unpack happens in modules that are not a friend of the module that defines the wrapper struct + fn check_pack_unpack_wrapper( + &mut self, + id: NodeId, + mid: ModuleId, + target_ty: Type, + wrapper_mid: ModuleId, + wrapper_sid: StructId, + oper: &str, + extra_msg: &str, + ) { + let wrapper_struct = self.env().get_struct(wrapper_mid.qualified(wrapper_sid)); + let different_module = wrapper_mid != mid; + let lang_pub_api = self.check_version_for_cross_module_access(); + if different_module { + let wrapper_name = wrapper_struct.get_full_name_str(); + let module_name = self + .func_env + .env() + .get_module(wrapper_mid) + .get_full_name_str(); + + let err_msg = if !lang_pub_api || wrapper_struct.get_visibility() == Visibility::Private + { + Some(format!( + "cannot implicitly {} a wrapper struct `{}` defined in a different module `{}`{}", + oper, + target_ty.display(&self.func_env.get_type_display_ctx()), + module_name, + extra_msg, + )) + } else if wrapper_struct.get_visibility() == Visibility::Friend + && !wrapper_struct.module_env.has_friend(&mid) + { + let visibility_str = if wrapper_struct.has_package_visibility() { + "package" + } else { + "friend" + }; + Some(format!( + "cannot implicitly {} a wrapper struct `{}` defined in a different module `{}`{} because it has {} visibility", + oper, wrapper_name, module_name, extra_msg, visibility_str, + )) + } else { + None + }; + if let Some(msg) = err_msg { + self.error(id, msg); + } + } + } + fn gen_test_variants( &mut self, targets: Vec, @@ -988,18 +1087,37 @@ impl Generator<'_> { let target = self.require_unary_target(id, targets); let temp = self.gen_auto_ref_arg(&self.require_unary_arg(id, args), ReferenceKind::Immutable); - let mut bool_temp = Some(target); - let success_label = self.new_label(id); let inst = self.env().get_node_instantiation(id); - self.gen_test_variants_operation( - id, - &mut bool_temp, - success_label, - &struct_id.instantiate(inst), - variants.to_vec(), - temp, - ); - self.emit_with(id, |attr| Bytecode::Label(attr, success_label)) + if variants.len() == 1 { + // Test single variant: directly translate + self.emit_with(id, |attr| { + Bytecode::Call( + attr, + vec![target], + BytecodeOperation::TestVariant( + struct_id.module_id, + struct_id.id, + variants[0], + inst, + ), + vec![temp], + None, + ) + }) + } else { + // Test more than one variant: create branches + let mut bool_temp = Some(target); + let success_label = self.new_label(id); + self.gen_test_variants_operation( + id, + &mut bool_temp, + success_label, + &struct_id.instantiate(inst), + variants.to_vec(), + temp, + ); + self.emit_with(id, |attr| Bytecode::Label(attr, success_label)) + } } fn gen_cast_call(&mut self, targets: Vec, id: NodeId, args: &[Exp]) { @@ -1011,6 +1129,12 @@ impl Generator<'_> { Type::Primitive(PrimitiveType::U64) => BytecodeOperation::CastU64, Type::Primitive(PrimitiveType::U128) => BytecodeOperation::CastU128, Type::Primitive(PrimitiveType::U256) => BytecodeOperation::CastU256, + Type::Primitive(PrimitiveType::I8) => BytecodeOperation::CastI8, + Type::Primitive(PrimitiveType::I16) => BytecodeOperation::CastI16, + Type::Primitive(PrimitiveType::I32) => BytecodeOperation::CastI32, + Type::Primitive(PrimitiveType::I64) => BytecodeOperation::CastI64, + Type::Primitive(PrimitiveType::I128) => BytecodeOperation::CastI128, + Type::Primitive(PrimitiveType::I256) => BytecodeOperation::CastI256, _ => { self.internal_error(id, "inconsistent type"); return; @@ -1060,7 +1184,7 @@ impl Generator<'_> { // in such expressions. match args[0].as_ref() { ExpData::Call(_, Operation::Borrow(_), borrow_args) => { - self.gen(targets, &borrow_args[0]) + self.generate(targets, &borrow_args[0]) }, _ => self.gen_op_call(targets, id, BytecodeOperation::ReadRef, args), } @@ -1083,7 +1207,7 @@ impl Generator<'_> { }); self.emit_with(id, |attr| Bytecode::Label(attr, true_label)); if is_and { - self.gen(vec![target], &args[1]); + self.generate(vec![target], &args[1]); } else { self.emit_with(id, |attr| { Bytecode::Load(attr, target, Constant::Bool(true)) @@ -1096,7 +1220,7 @@ impl Generator<'_> { Bytecode::Load(attr, target, Constant::Bool(false)) }) } else { - self.gen(vec![target], &args[1]); + self.generate(vec![target], &args[1]); } self.emit_with(id, |attr| Bytecode::Label(attr, done_label)); } @@ -1215,7 +1339,7 @@ impl Generator<'_> { let ty = Type::Reference(self.reference_mode_kind, Box::new(self.get_node_type(*id))); let temp = self.new_temp(ty); - self.gen(vec![temp], exp); + self.generate(vec![temp], exp); temp }, _ => { @@ -1228,7 +1352,7 @@ impl Generator<'_> { self.get_node_type(id) }; let temp = self.new_temp(ty); - self.gen(vec![temp], exp); + self.generate(vec![temp], exp); temp }, } @@ -1253,7 +1377,7 @@ impl Generator<'_> { .into_iter() .map(|ty| self.new_temp(ty)) .collect::>(); - self.gen(temps.clone(), exp); + self.generate(temps.clone(), exp); temps } else { vec![self.gen_escape_auto_ref_arg(exp, with_forced_temp)] @@ -1330,7 +1454,7 @@ impl Generator<'_> { let arg_type = self.env().get_node_type(args[0].node_id()); if let Type::Reference(ref_kind, _) = arg_type { if ref_kind == kind { - return self.gen(vec![target], &args[0]); + return self.generate(vec![target], &args[0]); } } }, @@ -1721,7 +1845,7 @@ impl Generator<'_> { // assign the call results. let match_mode = &MatchMode::Irrefutable; let sub_matches = self.collect_sub_matches(true, pats, match_mode, next_scope); - self.gen(sub_matches.values().map(|(temp, _)| *temp).collect(), exp); + self.generate(sub_matches.values().map(|(temp, _)| *temp).collect(), exp); for (_, (temp, cont_opt)) in sub_matches.into_iter() { if let Some(cont_pat) = cont_opt { self.gen_match_from_temp( @@ -1795,11 +1919,11 @@ impl Generator<'_> { // If we have not yet executed the condition during probing, execute it now. self.scopes.push(scope); if let Some(cond) = arm.condition.as_ref().filter(|_| !needs_probing) { - self.gen(vec![bool_temp], cond); + self.generate(vec![bool_temp], cond); self.branch_to_exit_if_false(cond.node_id(), bool_temp, exit_path) } // Translate the body - self.gen(targets.clone(), &arm.body); + self.generate(targets.clone(), &arm.body); self.scopes.pop().expect("scope stack balanced"); // Exit match with success self.emit_with(id, |attr| Bytecode::Jump(attr, success_path)); @@ -1894,7 +2018,7 @@ impl Generator<'_> { }) .rewrite_exp(exp.clone()); self.scopes.push(probe_scope); - self.gen(vec![bool_temp], &rewritten_exp); + self.generate(vec![bool_temp], &rewritten_exp); self.branch_to_exit_if_false(id, bool_temp, exit_path); self.scopes.pop(); } @@ -2041,18 +2165,18 @@ impl Generator<'_> { .collect_vec(); for (pos, (temp, _)) in sub_matches { let field_offset = fields[*pos]; - self.with_reference_mode(|gen, entering| { + self.with_reference_mode(|r#gen, entering| { if entering { - gen.reference_mode_kind = ref_kind + r#gen.reference_mode_kind = ref_kind } - if !gen.temp_type(*temp).is_reference() { - gen.env().diag( + if !r#gen.temp_type(*temp).is_reference() { + r#gen.env().diag( Severity::Bug, - &gen.env().get_node_loc(*id), + &r#gen.env().get_node_loc(*id), "Unpacking a reference to a struct must return the references of fields", ); } - gen.emit_call( + r#gen.emit_call( *id, vec![*temp], if let Some(var) = variant { @@ -2389,7 +2513,7 @@ impl ValueShape { fn possible_values_product( env: &GlobalEnv, shapes: &[ValueShape], - ) -> impl Iterator> { + ) -> impl Iterator> + use<> { shapes .iter() .map(|shape| shape.possible_values(env)) diff --git a/third_party/move/move-compiler-v2/src/diagnostics/mod.rs b/third_party/move/move-compiler-v2/src/diagnostics/mod.rs index fc2cb767a3a..87b018adaa2 100644 --- a/third_party/move/move-compiler-v2/src/diagnostics/mod.rs +++ b/third_party/move/move-compiler-v2/src/diagnostics/mod.rs @@ -9,7 +9,7 @@ use anyhow::bail; use codespan::{FileId, Files}; use codespan_reporting::{ diagnostic::{Diagnostic, Severity}, - term::termcolor::WriteColor, + term::termcolor::{ColorChoice, StandardStream, WriteColor}, }; use move_model::model::GlobalEnv; @@ -17,6 +17,14 @@ pub mod human; pub mod json; impl options::Options { + pub fn error_writer(&self) -> Box { + if self.print_errors { + Box::new(StandardStream::stderr(ColorChoice::Auto)) + } else { + Box::new(std::io::sink()) + } + } + pub fn error_emitter<'w, W>(&self, dest: &'w mut W) -> Box where W: WriteColor, diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs b/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs index 316fba8dd5e..3f06f49c15d 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs @@ -52,7 +52,7 @@ use itertools::Itertools; use log::{debug, log_enabled, trace, Level}; use move_core_types::ability::Ability; use move_model::{ - ast::{Exp, ExpData, Operation, Pattern, Value, VisitorPosition}, + ast::{Exp, ExpData, MatchArm, Operation, Pattern, Value, VisitorPosition}, constant_folder::ConstantFolder, exp_rewriter::ExpRewriterFunctions, model::{FunctionEnv, GlobalEnv, NodeId, Parameter}, @@ -70,13 +70,23 @@ const DEBUG: bool = false; /// Run the AST simplification pass on all target functions in the `env`. /// Optionally do some aggressive simplifications that may eliminate code. -pub fn run_simplifier(env: &mut GlobalEnv, eliminate_code: bool) { +/// Also, let the simplifier know if it is being run after inlining optimization +/// (we do not want to emit warnings for eliminated code in such a case). +pub fn run_simplifier( + env: &mut GlobalEnv, + eliminate_code: bool, + after_inlining_optimization: bool, +) { let mut new_definitions = Vec::new(); // Avoid borrowing issues for env. for module in env.get_modules() { if module.is_target() { for func_env in module.get_functions() { if let Some(def) = func_env.get_def() { - let mut rewriter = SimplifierRewriter::new(&func_env, eliminate_code); + let mut rewriter = SimplifierRewriter::new( + &func_env, + eliminate_code, + after_inlining_optimization, + ); let rewritten = rewriter.rewrite_function_body(def.clone()); trace!( "After rewrite_function_body, function body is `{}`", @@ -505,26 +515,29 @@ struct SimplifierRewriter<'env> { pub constant_folder: ConstantFolder<'env>, - // Guard whether entire subexpressions are eliminated (possibly hiding some warnings). + /// Guard whether entire subexpressions are eliminated (possibly hiding some warnings). pub eliminate_code: bool, - // Tracks which definition (`Let` or `Lambda` statement `NodeId`) is visible during visit to - // find modified local vars. A use of a symbol which is missing must be a `Parameter`. This is - // used only to determine if a symbol is in `possibly_modified_variables`. + /// Tracks which definition (`Let` or `Lambda` statement `NodeId`) is visible during visit to + /// find modified local vars. A use of a symbol which is missing must be a `Parameter`. This is + /// used only to determine if a symbol is in `possibly_modified_variables`. visiting_binding: ScopedMap, - // Possibly modified variables are identified by `Symbol` and `Let` or `Lambda` statement `NodeId`, - // except enclosing function parameters, which have no `NodeId` so get `None`. + /// Possibly modified variables are identified by `Symbol` and `Let` or `Lambda` statement `NodeId`, + /// except enclosing function parameters, which have no `NodeId` so get `None`. possibly_modified_variables: BTreeSet<(Symbol, Option)>, - // Tracks constant values from scope. + /// Tracks constant values from scope. values: ScopedMap, - // During expression rewriting, tracks whether we are evaluating a mutable borrow argument. + /// During expression rewriting, tracks whether we are evaluating a mutable borrow argument. in_mut_borrow: bool, - // Records values from outer scope of a borrow. + /// Records values from outer scope of a borrow. in_mut_borrow_stack: Vec, + + /// Are we doing the simplification after the inlining optimization? + after_inlining_optimization: bool, } // Representation to record a known value of a variable to @@ -537,7 +550,11 @@ enum SimpleValue { } impl<'env> SimplifierRewriter<'env> { - fn new(func_env: &'env FunctionEnv, eliminate_code: bool) -> Self { + fn new( + func_env: &'env FunctionEnv, + eliminate_code: bool, + after_inlining_optimization: bool, + ) -> Self { let constant_folder = ConstantFolder::new(func_env.module_env.env, false); Self { func_env, @@ -548,6 +565,7 @@ impl<'env> SimplifierRewriter<'env> { values: ScopedMap::new(), in_mut_borrow: false, in_mut_borrow_stack: Vec::new(), + after_inlining_optimization, } } @@ -852,6 +870,41 @@ impl ExpRewriterFunctions for SimplifierRewriter<'_> { }) } + fn rewrite_match(&mut self, id: NodeId, disc: &Exp, arms: &[MatchArm]) -> Option { + // match (e) { V(_) => true, _ => false } ==> e is V + let is_bool = |e: &Exp, test: bool| -> bool { + matches!(e.as_ref(), ExpData::Value(_, Value::Bool(v)) if test == *v) + }; + if arms.len() == 2 + && let MatchArm { + loc: _, + pattern: Pattern::Struct(_, qid, Some(variant), args), + condition: None, + body, + } = &arms[0] + && args.iter().all(|p| matches!(p, Pattern::Wildcard(_))) + && is_bool(body, true) + && let MatchArm { + loc: _, + pattern: Pattern::Wildcard(_), + condition: None, + body, + } = &arms[1] + && is_bool(body, false) + { + Some( + ExpData::Call( + id, + Operation::TestVariants(qid.module_id, qid.id, vec![*variant]), + vec![disc.clone()], + ) + .into_exp(), + ) + } else { + None + } + } + fn rewrite_enter_block_scope( &mut self, id: NodeId, @@ -1060,26 +1113,28 @@ impl ExpRewriterFunctions for SimplifierRewriter<'_> { }, _ => None, } { - let loc = self.env().get_node_loc(eliminated_id); - let cond_loc = self.env().get_node_loc(cond.node_id()); - self.env().diag_with_labels( - Severity::Warning, - &cond_loc, - &format!( - "If condition is always {}, so {} branch code eliminated as dead code", - truth_value, branch_name, - ), - vec![ - ( - cond_loc.clone(), - format!("condition is always {}", truth_value).to_string(), - ), - ( - loc, - format!("{} branch eliminated", branch_name).to_string(), + if !self.after_inlining_optimization { + let loc = self.env().get_node_loc(eliminated_id); + let cond_loc = self.env().get_node_loc(cond.node_id()); + self.env().diag_with_labels( + Severity::Warning, + &cond_loc, + &format!( + "If condition is always {}, so {} branch code eliminated as dead code", + truth_value, branch_name, ), - ], - ); + vec![ + ( + cond_loc.clone(), + format!("condition is always {}", truth_value).to_string(), + ), + ( + loc, + format!("{} branch eliminated", branch_name).to_string(), + ), + ], + ); + } Some(result) } else { None @@ -1097,12 +1152,14 @@ impl ExpRewriterFunctions for SimplifierRewriter<'_> { let side_effecting_elts_refs = siter .filter(|exp| if exp.as_ref().is_ok_to_remove_from_code() { - let loc = self.env().get_node_loc(exp.node_id()); - self.env().diag( - Severity::Warning, - &loc, - "Expression value unused and side-effect free, so eliminated as dead code" - ); + if !self.after_inlining_optimization { + let loc = self.env().get_node_loc(exp.node_id()); + self.env().diag( + Severity::Warning, + &loc, + "Expression value unused and side-effect free, so eliminated as dead code" + ); + } false } else { true diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/closure_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/closure_checker.rs index 1538625ee99..02fb9194a87 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/closure_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/closure_checker.rs @@ -17,6 +17,7 @@ use move_core_types::ability::Ability; use move_model::{ ast::{ExpData, Operation}, model::GlobalEnv, + ty::Type, well_known, }; @@ -90,6 +91,12 @@ pub fn check_closures(env: &GlobalEnv) { }; for captured in args { let captured_ty = env.get_node_type(captured.node_id()); + // when capturing a value that contains option, we need to generate a warning + // After refactoring option type to use enum, we can lift this limitation + // TODO: remove it after option type is refactored to use enum + if contains_option_type(env, &captured_ty) { + env.warning(&env.get_node_loc(captured.node_id()), "capturing option values is currently not supported"); + } if captured_ty.is_reference() { env.error( &env.get_node_loc(captured.node_id()), @@ -135,3 +142,49 @@ pub fn check_closures(env: &GlobalEnv) { } } } + +/// Check if the type contains an option type +/// Note that this function does not find contained options within reference types/function types +/// because it is used for checking captured values only +fn contains_option_type(env: &GlobalEnv, ty: &Type) -> bool { + match ty { + Type::Vector(ty) => contains_option_type(env, ty), + Type::Struct(mid, sid, tys) => { + let struct_env = env.get_module(*mid).into_struct(*sid); + if struct_env.is_option_type() { + return true; + } + if struct_env.has_variants() { + for variant in struct_env.get_variants() { + for field in struct_env.get_fields_of_variant(variant) { + if contains_option_type(env, &field.get_type()) { + return true; + } + } + } + } else { + for field in struct_env.get_fields() { + if contains_option_type(env, &field.get_type()) { + return true; + } + } + } + tys.iter() + .zip(struct_env.get_type_parameters().iter()) + .filter(|(_, param)| !param.1.is_phantom) + .any(|(t, _)| contains_option_type(env, t)) + }, + // since fun params and result does not appear in layout, we can safely return false, + Type::Fun(..) => false, + Type::Primitive(..) => false, + // compiler error will be generated separately + // we are looking at option values that are captured, and because references cannot be captured, + // we do not have to recurse here. + Type::Reference(..) => false, + Type::TypeParameter(..) => false, + _ => unreachable!( + "ICE: argument with type `{}` should not appear in this context", + ty.display(&env.get_type_display_ctx()) + ), + } +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs new file mode 100644 index 00000000000..9a56b1fe411 --- /dev/null +++ b/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs @@ -0,0 +1,373 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Comparison operation rewriter +//! - The in-house Lt/Le/Gt/Ge operations only allow integer operands. +//! - We visit Lt/Le/Gt/Ge operations +//! - If their operands are not integer primitive types, +//! - we rewrite the operation to use the `std::cmp::compare` function, +//! - and then interpret the result using `std::cmp::is_lt`, `std::cmp::is_le`, etc. +//! +//! Example: +//! x <= y +//! =======> +//! std::cmp::compare(&x, &y).std::cmp::is_le() +//! +//! Key impls +//! - `fn rewrite_cmp_operation`: +//! - Given an ast exp representing a comparison operation, e.g., `Call(Operation::Lt, [arg1, arg2])`, +//! - the function takes five steps: +//! 1. check if `arg1` and `arg2` can be transformed based on their types +//! 2. transform `arg1` and `arg2`, if not already references, into `&arg1` and `&arg2` +//! 3. create a call to `std::cmp::compare`: `exp1 = Call(MoveFunction(std::cmp::compare), [&arg1, &arg2])` +//! 4. create an immutable reference to the result of `std::cmp::compare`: `exp2 = Call(Borrow(Immutable), [exp1])` +//! 5. generate a final call of `is_lt / is_le / is_gt / is_ge` to interpret the result of `std::cmp::compare`: `exp3 = Call(MoveFunction(std::cmp::is_le), [exp2])` +//! - [TODO] An optimization to consider +//! - Once we have public enum, we can direly apply `==` to the result of `std::cmp::compare` (of the `Enum Ordering` type), +//! - which can avoid creating a reference to the result of `std::cmp::compare` and calling `is_lt / is_le / is_gt / is_ge`. +//! +//! +//! Important notes about linking `std::cmp` module: +//! - To ensure the `std::cmp` module is preserved in GlobalEnv during compilation, +//! - code is added in `third_party/move/move-model/src/lib.rs` to keep `std::cmp` and its dependencies during the ast expansion phase +//! - To ensure implicit dependencies introduced by comparison rewriting are maintained +//! - code is added in `third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs` to add dependency between every user module and `std::cmp`. +//! - If the user does not include `move-stdlib` for compilation, +//! - a compilation error "cannot find `std::cmp` module" will be raised. +//! +//! Important notes about specs +//! - No extensions are made to comparison operations in specs. +//! - Only primitive integer types are supported as before +//! + +use crate::env_pipeline::rewrite_target::{ + RewriteState, RewriteTarget, RewriteTargets, RewritingScope, +}; +use move_core_types::account_address::AccountAddress; +use move_model::{ + ast::{Address, Exp, ExpData, ModuleName, Operation}, + exp_rewriter::ExpRewriterFunctions, + model::{FunId, FunctionEnv, GlobalEnv, ModuleEnv, NodeId, QualifiedId}, + ty::*, + well_known, +}; +use std::{ + collections::{BTreeMap, BTreeSet}, + iter::Iterator, +}; + +/// Main interface for the comparison operation rewriter +pub fn rewrite(env: &mut GlobalEnv) { + // Create a shared CmpRewriter instance for processing all target functions + let mut rewriter = CmpRewriter::new(env); + let mut targets = RewriteTargets::create(env, RewritingScope::CompilationTarget); + let todo: BTreeSet<_> = targets.keys().collect(); + for target in todo { + if let RewriteTarget::MoveFun(func_id) = target { + let new_def = rewrite_target(&mut rewriter, func_id); + if let Some(def) = new_def { + *targets.state_mut(&target) = RewriteState::Def(def); + } + } + } + targets.write_to_env(env); +} + +/// Rewrite each target function +/// - The rewriting will go through the ExpRewriterFunctions trait +/// - On a `Call` operation, the transformation will be redirected to `rewrite_call` defined later +fn rewrite_target(rewriter: &mut CmpRewriter, func_id: QualifiedId) -> Option { + let func_env = rewriter.env.get_function(func_id); + let def_opt = func_env.get_def(); + if let Some(def) = def_opt { + let rewritten_def = rewriter.rewrite_exp(def.clone()); + if !ExpData::ptr_eq(&rewritten_def, def) { + return Some(rewritten_def); + } + } + None +} + +struct CmpRewriter<'env> { + env: &'env GlobalEnv, + cmp_module: Option>, + cmp_functions: BTreeMap<&'static str, FunctionEnv<'env>>, +} + +/// Override `rewrite_call` from `ExpRewriterFunctions` trait +impl ExpRewriterFunctions for CmpRewriter<'_> { + fn rewrite_call(&mut self, call_id: NodeId, oper: &Operation, args: &[Exp]) -> Option { + if matches!( + oper, + Operation::Lt | Operation::Le | Operation::Gt | Operation::Ge + ) { + self.rewrite_cmp_operation(call_id, oper, args) + } else { + None + } + } +} + +impl<'env> CmpRewriter<'env> { + /// Constants for the `std::cmp` module and its functions + const COMPARE: &'static str = "compare"; + const IS_GE: &'static str = "is_ge"; + const IS_GT: &'static str = "is_gt"; + const IS_LE: &'static str = "is_le"; + const IS_LT: &'static str = "is_lt"; + + fn new(env: &'env GlobalEnv) -> Self { + let cmp_module = Self::find_cmp_module(env); + let mut cmp_functions = BTreeMap::new(); + + if let Some(module) = &cmp_module { + for name in [ + Self::COMPARE, + Self::IS_LT, + Self::IS_LE, + Self::IS_GT, + Self::IS_GE, + ] { + if let Some(func) = Self::find_cmp_function(module, name) { + cmp_functions.insert(name, func); + } + } + } + + Self { + env, + cmp_module, + cmp_functions, + } + } + + /// Rewrite comparison operations + /// - Designs detailed in the beginning of this file + fn rewrite_cmp_operation( + &mut self, + call_id: NodeId, + cmp_op: &Operation, + args: &[Exp], + ) -> Option { + // Step 1: Check argument types + if args.iter().any(|arg| self.arg_cannot_transform(arg)) { + return None; + } + // Get the expected type-parameter type for the `std::cmp::compare` function + let arg_ty = self.env.get_node_type(args[0].node_id()); + let expected_arg_ty = arg_ty.drop_reference(); + + // Step 2: Transform `arg1` and `arg2` into `&arg1` and `&arg2` (do nothing if already references) + let transformed_args: Vec = args.iter().map(|arg| self.rewrite_cmp_arg(arg)).collect(); + + // Step 3: Create an inner call to `std::cmp::compare(&arg1, &arg2)` + let call_cmp = self.generate_call_to_compare(call_id, transformed_args, expected_arg_ty)?; + + // Step 4: Create a immutable reference to the result of `std::cmp::compare(&arg1, &arg2)` + let immref_cmp_res = self.immborrow_compare_res(call_cmp); + + //Step 5: Generate a final call of `is_lt / is_le / is_gt / is_ge` to interpret the result of `std::cmp::compare` + self.generate_call_to_final_res(call_id, cmp_op, vec![immref_cmp_res]) + } + + /// Generate a call to `std::cmp::compare(&arg1, &arg2)` + fn generate_call_to_compare( + &self, + cmp_op_id: NodeId, + args: Vec, + expected_arg_ty: Type, + ) -> Option { + // Reuse the loc info of the original comparison operation + let cmp_loc = self.env.get_node_loc(cmp_op_id); + + // Check the `std::cmp` module + let cmp_module = match self.cmp_module.as_ref() { + Some(module) => module, + None => { + self.env.error( + &cmp_loc, + "cannot find `std::cmp` module. Include `move-stdlib` for compilation.", + ); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + let cmp_module_id = cmp_module.get_id(); + + // Check the `std::cmp::compare` function + let compare_function = match self.cmp_functions.get(Self::COMPARE) { + Some(func) => func, + None => { + self.env.error(&cmp_loc, "cannot find `std::cmp::compare` function. Include `move-stdlib` for compilation."); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + + // Create a new node sharing return type with `std::cmp::compare` + let cmp_ty = compare_function.get_result_type(); + let new_cmp_node = self.env.new_node(cmp_loc, cmp_ty.clone()); + + // `std::cmp::compare` takes a type parameter, + // which should be instantiated with the type of the actual arguments + self.env + .set_node_instantiation(new_cmp_node, vec![expected_arg_ty]); + + Some( + ExpData::Call( + new_cmp_node, + Operation::MoveFunction(cmp_module_id, compare_function.get_id()), + args, + ) + .into_exp(), + ) + } + + /// Create a new immutable reference for the result of `std::cmp::compare` + fn immborrow_compare_res(&self, call_cmp: Exp) -> Exp { + let call_cmp_id = call_cmp.node_id(); + let cmp_loc = self.env.get_node_loc(call_cmp_id); + let cmp_ty = self.env.get_node_type(call_cmp_id); + let new_ref_type = Type::Reference(ReferenceKind::Immutable, Box::new(cmp_ty)); + let new_ref_id = self.env.new_node(cmp_loc, new_ref_type); + + ExpData::Call( + new_ref_id, + Operation::Borrow(ReferenceKind::Immutable), + vec![call_cmp], + ) + .into_exp() + } + + /// Generate a final call to interpret the result of `std::cmp::compare` + fn generate_call_to_final_res( + &self, + ori_op_id: NodeId, + cmp_op: &Operation, + args: Vec, + ) -> Option { + // Reuse the loc info of the original comparison operation + let final_res_loc = self.env.get_node_loc(ori_op_id); + + // Check the `std::cmp` module + let cmp_module = match self.cmp_module.as_ref() { + Some(module) => module, + None => { + self.env + .error(&final_res_loc, "cannot find `std::cmp` module"); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + let cmp_module_id = cmp_module.get_id(); + + let sym = match cmp_op { + Operation::Lt => Self::IS_LT, + Operation::Le => Self::IS_LE, + Operation::Gt => Self::IS_GT, + Operation::Ge => Self::IS_GE, + _ => return None, + }; + + // Check the `std::cmp::is_lt/is_le/is_gt/is_ge` function + let final_res_function = match self.cmp_functions.get(sym) { + Some(func) => func, + None => { + self.env.error( + &final_res_loc, + format!("cannot find `std::cmp::{}` function", sym).as_str(), + ); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + + let final_res_ty = Type::Primitive(PrimitiveType::Bool); + let final_res_id = self.env.new_node(final_res_loc, final_res_ty.clone()); + Some( + ExpData::Call( + final_res_id, + Operation::MoveFunction(cmp_module_id, final_res_function.get_id()), + args, + ) + .into_exp(), + ) + } + + /// We cannot rewrite integer primitive types and "Num" + /// - Integer primitive types are supported by the VM natively + /// - "Num" is for spec only + fn arg_cannot_transform(&mut self, arg: &Exp) -> bool { + let arg_ty = self.env.get_node_type(arg.as_ref().node_id()); + arg_ty.is_number() + } + + /// Obtain a reference to the argument + fn rewrite_cmp_arg(&mut self, arg: &Exp) -> Exp { + // Deref a reference, return the inner reference + if let Some(arg_ref) = self.remove_deref_from_arg(arg) { + return arg_ref; + } + let node_id = arg.as_ref().node_id(); + let arg_loc = self.env.get_node_loc(node_id); + let arg_ty = self.env.get_node_type(node_id); + + match arg_ty { + // Already a immutable reference, return it directly + Type::Reference(ReferenceKind::Immutable, _) => arg.clone(), + // Already a mutable reference, freeze and return it + Type::Reference(ReferenceKind::Mutable, inner_ty) => { + let new_ref_type = Type::Reference(ReferenceKind::Immutable, Box::new(*inner_ty)); + let new_ref_id = self.env.new_node(arg_loc, new_ref_type); + ExpData::Call(new_ref_id, Operation::Freeze(false), vec![arg.clone()]).into_exp() + }, + _ => { + // Not a reference, create a new immutable reference + let new_ref_type = + Type::Reference(ReferenceKind::Immutable, Box::new(arg_ty.clone())); + let new_ref_id = self.env.new_node(arg_loc, new_ref_type); + ExpData::Call( + new_ref_id, + Operation::Borrow(ReferenceKind::Immutable), + vec![arg.clone()], + ) + .into_exp() + }, + } + } + + /// Optimization: if the argument is a dereference operation, we get the inner reference directly + fn remove_deref_from_arg(&mut self, arg: &Exp) -> Option { + if let ExpData::Call(_, Operation::Deref, deref_args) = arg.as_ref() { + debug_assert!( + deref_args.len() == 1, + "there should be exactly one argument for dereference" + ); + let deref_arg_ty = self.env.get_node_type(deref_args[0].as_ref().node_id()); + if let Type::Reference(ReferenceKind::Immutable, _) = deref_arg_ty { + // If the deref argument is an immutable reference, we can return it directly + return Some(deref_args[0].clone()); + } + } + None + } + + /// Find the `std::cmp` module + fn find_cmp_module(env: &'env GlobalEnv) -> Option> { + // Find the `std::cmp` module + let cmp_module_name = ModuleName::new( + Address::Numerical(AccountAddress::ONE), + env.symbol_pool().make(well_known::CMP_MODULE), + ); + env.find_module(&cmp_module_name) + } + + /// Find function from the `std::cmp` module + fn find_cmp_function( + cmp_module: &ModuleEnv<'env>, + func_name: &str, + ) -> Option> { + let compare_sym = cmp_module.symbol_pool().make(func_name); + cmp_module.find_function(compare_sym) + } +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs index 1293ee754b3..b35bed77f5e 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs @@ -88,7 +88,8 @@ impl<'a> CyclicInstantiationChecker<'a> { insts: &[Type], callers_chain: &mut Vec<(Loc, QualifiedInstId)>, ) -> bool { - if let Operation::MoveFunction(mod_id, fun_id) = op { + if let Operation::MoveFunction(mod_id, fun_id) | Operation::Closure(mod_id, fun_id, _) = op + { let callee_uninst = mod_id.qualified_inst(*fun_id, self.get_inst(*nid)); let callee = callee_uninst.instantiate(insts); if *mod_id != self.mod_env.get_id() || self.def_not_recursive(callee.to_qualified_id()) @@ -97,8 +98,8 @@ impl<'a> CyclicInstantiationChecker<'a> { // or if the callee is not recursive true } else { - for (_, ancester_caller) in callers_chain.iter() { - if ancester_caller.to_qualified_id() == callee.to_qualified_id() { + for (_, ancestor_caller) in callers_chain.iter() { + if ancestor_caller.to_qualified_id() == callee.to_qualified_id() { // we are checking for the root caller let (_, checking_for) = &callers_chain[0]; if checking_for.to_qualified_id() != callee.to_qualified_id() { @@ -164,7 +165,7 @@ impl<'a> CyclicInstantiationChecker<'a> { .mod_env .env .get_function(id) - .get_transitive_closure_of_called_functions() + .get_transitive_closure_of_used_functions() .contains(&id) } @@ -184,7 +185,7 @@ impl<'a> CyclicInstantiationChecker<'a> { // callee of `caller` let (callee_loc, callee) = &callers_chain[i + 1]; format!( - "`{}` calls `{}` {}", + "`{}` uses `{}` {}", self.display_call(caller, root), self.display_call(callee, root), callee_loc.display_file_name_and_line(self.mod_env.env) @@ -194,7 +195,7 @@ impl<'a> CyclicInstantiationChecker<'a> { let (_caller_loc, caller) = &callers_chain.last().expect("parent"); let callee_loc = self.mod_env.env.get_node_loc(nid); labels.push(format!( - "`{}` calls `{}` {}", + "`{}` uses `{}` {}", self.display_call(caller, root), self.display_call(&callee, root), callee_loc.display_file_name_and_line(self.mod_env.env) @@ -207,7 +208,7 @@ impl<'a> CyclicInstantiationChecker<'a> { .env .error_with_notes( &root_loc, - "cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound", + "cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound", labels ) } @@ -236,7 +237,14 @@ fn ty_contains_ty_parameter(ty: &Type) -> Option { Type::Vector(ty) => ty_contains_ty_parameter(ty), Type::Struct(_, _, insts) => insts.iter().filter_map(ty_contains_ty_parameter).next(), Type::Primitive(_) => None, - _ => panic!("ICE: {:?} used as a type parameter", ty), + Type::Fun(args, result, _) => { + ty_contains_ty_parameter(args).or_else(|| ty_contains_ty_parameter(result)) + }, + Type::Reference(_, ty) => ty_contains_ty_parameter(ty), + Type::Tuple(ty) => ty.iter().filter_map(ty_contains_ty_parameter).next(), + Type::TypeDomain(_) | Type::ResourceDomain(..) | Type::Error | Type::Var(_) => { + panic!("ICE: {:?} used as a type parameter", ty) + }, } } @@ -246,6 +254,13 @@ fn ty_properly_contains_ty_parameter(ty: &Type) -> Option { Type::Vector(ty) => ty_contains_ty_parameter(ty), Type::Struct(_, _, insts) => insts.iter().filter_map(ty_contains_ty_parameter).next(), Type::Primitive(_) | Type::TypeParameter(_) => None, - _ => panic!("ICE: {:?} used as a type parameter", ty), + Type::Fun(args, result, _) => { + ty_contains_ty_parameter(args).or_else(|| ty_contains_ty_parameter(result)) + }, + Type::Reference(_, ty) => ty_contains_ty_parameter(ty), + Type::Tuple(ty) => ty.iter().filter_map(ty_contains_ty_parameter).next(), + Type::TypeDomain(_) | Type::ResourceDomain(..) | Type::Error | Type::Var(_) => { + panic!("ICE: {:?} used as a type parameter", ty) + }, } } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs index 66655238318..9201ca8138e 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs @@ -3,13 +3,16 @@ //! Do a few checks of functions and function calls. -use crate::Options; +use crate::{experiments::Experiment, Options}; use codespan_reporting::diagnostic::Severity; use move_binary_format::file_format::Visibility; use move_model::{ ast::{ExpData, Operation, Pattern}, metadata::LanguageVersion, - model::{FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, NodeId, Parameter, QualifiedId}, + model::{ + FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, NodeId, Parameter, QualifiedId, + StructEnv, + }, ty::Type, }; use std::{collections::BTreeSet, iter::Iterator, vec::Vec}; @@ -189,6 +192,7 @@ fn access_error( id: &NodeId, oper: &str, msg: String, + extra_msg: Option, module_env: &ModuleEnv, ) { let call_details: Vec<_> = [*id] @@ -196,9 +200,10 @@ fn access_error( .map(|node_id| (env.get_node_loc(*node_id), format!("{} here", oper))) .collect(); let msg = format!( - "Invalid operation: {} can only be done within the defining module `{}`", + "Invalid operation: {} can only be done within the defining module `{}` {}", msg, - module_env.get_full_name_str() + module_env.get_full_name_str(), + extra_msg.unwrap_or_default() ); env.diag_with_labels(Severity::Error, &fun_env.get_id_loc(), &msg, call_details); } @@ -224,9 +229,14 @@ fn access_warning( env.diag_with_labels(Severity::Warning, &fun_env.get_id_loc(), &msg, call_details); } +/// Check for access error or warning for a struct operation. +/// storage operations include `exists`, `move_to`, `move_from`, `borrow_global`, `borrow_global_mut` fn check_for_access_error_or_warning( env: &GlobalEnv, fun_env: &FunctionEnv, + struct_env: &StructEnv, + caller_module_id: &ModuleId, + storage_operation: bool, id: &NodeId, oper: &str, msg_maker: F, @@ -237,8 +247,35 @@ fn check_for_access_error_or_warning( F: Fn() -> String, { if cross_module { - access_error(env, fun_env, id, oper, msg_maker(), module_env); + let mut err_msg = None; + // storage operations cannot be cross-module, even for public structs + if !storage_operation && env.language_version().language_version_for_public_struct() { + match struct_env.get_visibility() { + Visibility::Public => { + return; + }, + Visibility::Friend => { + if struct_env.module_env.has_friend(caller_module_id) { + return; + } + let friend_str = if struct_env.has_package_visibility() { + "modules in the same package".to_string() + } else { + "friend modules".to_string() + }; + err_msg = Some(format!("or {}", friend_str)); + }, + Visibility::Private => {}, + } + } + access_error(env, fun_env, id, oper, msg_maker(), err_msg, module_env); } else if caller_is_inline_non_private { + if !storage_operation + && env.language_version().language_version_for_public_struct() + && struct_env.get_visibility() == Visibility::Public + { + return; + } access_warning(env, fun_env, id, oper, msg_maker(), module_env); } } @@ -250,182 +287,221 @@ fn check_privileged_operations_on_structs(env: &GlobalEnv, fun_env: &FunctionEnv let caller_module_id = fun_env.module_env.get_id(); let caller_is_inline_non_private = fun_env.is_inline() && fun_env.visibility() != Visibility::Private; - fun_body.visit_pre_order(&mut |exp: &ExpData| { - match exp { - ExpData::Call(id, oper, _) => match oper { - Operation::Exists(_) - | Operation::BorrowGlobal(_) - | Operation::MoveFrom - | Operation::MoveTo => { - let inst = env.get_node_instantiation(*id); - debug_assert!(!inst.is_empty()); - if let Some((struct_env, _)) = inst[0].get_struct(env) { - let mid = struct_env.module_env.get_id(); - let sid = struct_env.get_id(); - let qualified_struct_id = mid.qualified(sid); + // Ancestor spec blocks seen during AST traversal. + let mut spec_blocks_seen = 0; + fun_body.visit_pre_post(&mut |post, exp: &ExpData| { + if !post { + if matches!(exp, ExpData::SpecBlock(..)) { + spec_blocks_seen += 1; + } + if spec_blocks_seen > 0 { + // we are inside a spec block, no privileged operation check needed + return true; + } + match exp { + ExpData::Call(id, oper, _) => match oper { + Operation::Exists(_) + | Operation::BorrowGlobal(_) + | Operation::MoveFrom + | Operation::MoveTo => { + let inst = env.get_node_instantiation(*id); + debug_assert!(!inst.is_empty()); + if let Some((struct_env, _)) = inst[0].get_struct(env) { + let mid = struct_env.module_env.get_id(); + let sid = struct_env.get_id(); + let qualified_struct_id = mid.qualified(sid); + let struct_env = env.get_struct(qualified_struct_id); + let msg_maker = || { + format!( + "storage operation on type `{}`", + struct_env.get_full_name_str(), + ) + }; + check_for_access_error_or_warning( + env, + fun_env, + &struct_env, + &caller_module_id, + true, + id, + "called", + msg_maker, + &struct_env.module_env, + mid != caller_module_id, + caller_is_inline_non_private, + ); + } + }, + Operation::Select(mid, sid, fid) => { + let qualified_struct_id = mid.qualified(*sid); let struct_env = env.get_struct(qualified_struct_id); let msg_maker = || { format!( - "storage operation on type `{}`", + "access of the field `{}` on type `{}`", + fid.symbol().display(struct_env.symbol_pool()), struct_env.get_full_name_str(), ) }; check_for_access_error_or_warning( env, fun_env, + &struct_env, + &caller_module_id, + false, id, - "called", + "accessed", msg_maker, &struct_env.module_env, - mid != caller_module_id, + *mid != caller_module_id, caller_is_inline_non_private, ); - } - }, - Operation::Select(mid, sid, fid) => { - let qualified_struct_id = mid.qualified(*sid); - let struct_env = env.get_struct(qualified_struct_id); - let msg_maker = || { - format!( - "access of the field `{}` on type `{}`", - fid.symbol().display(struct_env.symbol_pool()), - struct_env.get_full_name_str(), - ) - }; - check_for_access_error_or_warning( - env, - fun_env, - id, - "accessed", - msg_maker, - &struct_env.module_env, - *mid != caller_module_id, - caller_is_inline_non_private, - ); - }, - Operation::SelectVariants(mid, sid, fids) => { - let qualified_struct_id = mid.qualified(*sid); - let struct_env = env.get_struct(qualified_struct_id); - // All field names are the same, so take one representative field id to report. - let field_env = struct_env.get_field(fids[0]); - let msg_maker = || { - format!( - "access of the field `{}` on enum type `{}`", - field_env.get_name().display(struct_env.symbol_pool()), - struct_env.get_full_name_str(), - ) - }; - check_for_access_error_or_warning( - env, - fun_env, - id, - "accessed", - msg_maker, - &struct_env.module_env, - *mid != caller_module_id, - caller_is_inline_non_private, - ); - }, - Operation::TestVariants(mid, sid, _) => { - let qualified_struct_id = mid.qualified(*sid); - let struct_env = env.get_struct(qualified_struct_id); - let msg_maker = || { - format!( - "variant test on enum type `{}`", - struct_env.get_full_name_str(), - ) - }; - check_for_access_error_or_warning( - env, - fun_env, - id, - "tested", - msg_maker, - &struct_env.module_env, - *mid != caller_module_id, - caller_is_inline_non_private, - ); - }, - Operation::Pack(mid, sid, _) => { - let qualified_struct_id = mid.qualified(*sid); - let struct_env = env.get_struct(qualified_struct_id); - let msg_maker = || format!("pack of `{}`", struct_env.get_full_name_str()); - check_for_access_error_or_warning( - env, - fun_env, - id, - "packed", - msg_maker, - &struct_env.module_env, - *mid != caller_module_id, - caller_is_inline_non_private, - ); - }, - _ => { - // all the other operations are either: - // - not related to structs - // - spec-only - }, - }, - ExpData::Assign(_, pat, _) - | ExpData::Block(_, pat, _, _) - | ExpData::Lambda(_, pat, _, _, _) => { - pat.visit_pre_post(&mut |_, pat| { - if let Pattern::Struct(id, str, _, _) = pat { - let module_id = str.module_id; - let struct_env = env.get_struct(str.to_qualified_id()); + }, + Operation::SelectVariants(mid, sid, fids) => { + let qualified_struct_id = mid.qualified(*sid); + let struct_env = env.get_struct(qualified_struct_id); + // All field names are the same, so take one representative field id to report. + let field_env = struct_env.get_field(fids[0]); + let msg_maker = || { + format!( + "access of the field `{}` on enum type `{}`", + field_env.get_name().display(struct_env.symbol_pool()), + struct_env.get_full_name_str(), + ) + }; + check_for_access_error_or_warning( + env, + fun_env, + &struct_env, + &caller_module_id, + false, + id, + "accessed", + msg_maker, + &struct_env.module_env, + *mid != caller_module_id, + caller_is_inline_non_private, + ); + }, + Operation::TestVariants(mid, sid, _) => { + let qualified_struct_id = mid.qualified(*sid); + let struct_env = env.get_struct(qualified_struct_id); + let msg_maker = || { + format!( + "variant test on enum type `{}`", + struct_env.get_full_name_str(), + ) + }; + check_for_access_error_or_warning( + env, + fun_env, + &struct_env, + &caller_module_id, + false, + id, + "tested", + msg_maker, + &struct_env.module_env, + *mid != caller_module_id, + caller_is_inline_non_private, + ); + }, + Operation::Pack(mid, sid, _) => { + let qualified_struct_id = mid.qualified(*sid); + let struct_env = env.get_struct(qualified_struct_id); let msg_maker = - || format!("unpack of `{}`", struct_env.get_full_name_str(),); + || format!("pack of `{}`", struct_env.get_full_name_str()); check_for_access_error_or_warning( env, fun_env, + &struct_env, + &caller_module_id, + false, id, - "unpacked", + "packed", + msg_maker, + &struct_env.module_env, + *mid != caller_module_id, + caller_is_inline_non_private, + ); + }, + _ => { + // all the other operations are either: + // - not related to structs + // - spec-only + }, + }, + ExpData::Assign(_, pat, _) + | ExpData::Block(_, pat, _, _) + | ExpData::Lambda(_, pat, _, _, _) => { + pat.visit_pre_post(&mut |_, pat| { + if let Pattern::Struct(id, str, _, _) = pat { + let module_id = str.module_id; + let struct_env = env.get_struct(str.to_qualified_id()); + let msg_maker = + || format!("unpack of `{}`", struct_env.get_full_name_str(),); + check_for_access_error_or_warning( + env, + fun_env, + &struct_env, + &caller_module_id, + false, + id, + "unpacked", + msg_maker, + &struct_env.module_env, + module_id != caller_module_id, + caller_is_inline_non_private, + ); + } + }); + }, + ExpData::Match(_, discriminator, _) => { + let discriminator_node_id = discriminator.node_id(); + if let Type::Struct(mid, sid, _) = + env.get_node_type(discriminator_node_id).drop_reference() + { + let qualified_struct_id = mid.qualified(sid); + let struct_env = env.get_struct(qualified_struct_id); + let msg_maker = || { + format!("match on enum type `{}`", struct_env.get_full_name_str(),) + }; + check_for_access_error_or_warning( + env, + fun_env, + &struct_env, + &caller_module_id, + false, + &discriminator_node_id, + "matched", msg_maker, &struct_env.module_env, - module_id != caller_module_id, + mid != caller_module_id, caller_is_inline_non_private, ); } - }); - }, - ExpData::Match(_, discriminator, _) => { - let discriminator_node_id = discriminator.node_id(); - if let Type::Struct(mid, sid, _) = - env.get_node_type(discriminator_node_id).drop_reference() - { - let qualified_struct_id = mid.qualified(sid); - let struct_env = env.get_struct(qualified_struct_id); - let msg_maker = - || format!("match on enum type `{}`", struct_env.get_full_name_str(),); - check_for_access_error_or_warning( - env, - fun_env, - &discriminator_node_id, - "matched", - msg_maker, - &struct_env.module_env, - mid != caller_module_id, - caller_is_inline_non_private, - ); - } - }, - ExpData::Invalid(_) - | ExpData::Value(..) - | ExpData::LocalVar(..) - | ExpData::Temporary(..) - | ExpData::Invoke(..) - | ExpData::Quant(..) - | ExpData::IfElse(..) - | ExpData::Return(..) - | ExpData::Sequence(..) - | ExpData::Loop(..) - | ExpData::LoopCont(..) - | ExpData::Mutate(..) => {}, - // access in specs is not restricted - ExpData::SpecBlock(_, _) => { - return false; - }, + }, + ExpData::Invalid(_) + | ExpData::Value(..) + | ExpData::LocalVar(..) + | ExpData::Temporary(..) + | ExpData::Invoke(..) + | ExpData::Quant(..) + | ExpData::IfElse(..) + | ExpData::Return(..) + | ExpData::Sequence(..) + | ExpData::Loop(..) + | ExpData::LoopCont(..) + | ExpData::Mutate(..) => {}, + ExpData::SpecBlock(_, _) => { + unreachable!("we have already checked for spec blocks"); + }, + } + } else { + // post visit + if matches!(exp, ExpData::SpecBlock(..)) { + debug_assert!(spec_blocks_seen > 0, "should match in pre and post"); + spec_blocks_seen -= 1; + } } true }); @@ -482,6 +558,12 @@ pub fn check_access_and_use(env: &mut GlobalEnv, before_inlining: bool) { let callees_with_sites = def.used_funs_with_uses(); for (callee, sites) in &callees_with_sites { let callee_func = env.get_function(*callee); + + // Script functions cannot be called. + if callee_func.module_env.is_script_module() { + calling_script_function_error(env, sites, &callee_func); + } + // Check visibility. // Same module is always visible @@ -527,13 +609,25 @@ pub fn check_access_and_use(env: &mut GlobalEnv, before_inlining: bool) { caller_func.module_env.get_full_name_str() ); } else { - call_package_fun_from_diff_package_error( - env, - sites, - &caller_func, - &callee_func, - ); - false + // With "unsafe package visibility" experiment on, all package functions are made + // visible in all modules with the same address. The prover uses this in filter mode + // to get around the lack of package-based target filtering functionality. + let options = env + .get_extension::() + .expect("Options is available"); + if options.experiment_on( + Experiment::UNSAFE_PACKAGE_VISIBILITY, + ) { + true + } else { + call_package_fun_from_diff_package_error( + env, + sites, + &caller_func, + &callee_func, + ); + false + } } } else { call_package_fun_from_diff_addr_error( @@ -837,3 +931,16 @@ fn call_package_fun_from_diff_addr_error( let why = "they are from different addresses"; cannot_call_error(env, why, sites, caller, callee); } + +fn calling_script_function_error(env: &GlobalEnv, sites: &BTreeSet, callee: &FunctionEnv) { + let call_details: Vec<_> = sites + .iter() + .map(|node_id| (env.get_node_loc(*node_id), "used here".to_owned())) + .collect(); + let callee_name = callee.get_name_str(); + let msg = format!( + "script function `{}` cannot be used in Move code", + callee_name + ); + env.diag_with_labels(Severity::Error, &callee.get_id_loc(), &msg, call_details); +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs b/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs index 9dd6108ef39..6d735b95d07 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/inliner.rs @@ -56,6 +56,7 @@ use move_model::{ model::{FunId, GlobalEnv, Loc, NodeId, Parameter, QualifiedId, SpecFunId}, symbol::Symbol, ty::{ReferenceKind, Type}, + well_known, }; use std::{ collections::{BTreeMap, BTreeSet}, @@ -155,7 +156,8 @@ pub fn run_inlining( } } -/// Check that inline functions are (1) not native, (2) have a body (3) are not in a script. +/// Check that inline functions are (1) not native, (2) have a body, (3) are not in a script, +/// (4) do not have certain attributes, and (5) do not have access specifiers. /// Filter out inline functions from the targets if `Experiment::SKIP_INLINING_INLINE_FUNS` is on. fn check_and_maybe_filter_targets(env: &GlobalEnv, targets: &mut RewriteTargets) { let keep_inline_functions = !env @@ -180,12 +182,32 @@ fn check_and_maybe_filter_targets(env: &GlobalEnv, targets: &mut RewriteTargets) env.diag(Severity::Bug, &func_loc, &msg); } } + if func.module_env.is_script_module() { env.error( &func.get_id_loc(), "inline function cannot be defined in a script", ); } + + if func.has_attribute(|attr| { + let name = env.symbol_pool().string(attr.name()); + name.as_str() == well_known::PERSISTENT_ATTRIBUTE + || name.as_str() == well_known::MODULE_LOCK_ATTRIBUTE + }) { + env.error( + &func.get_id_loc(), + "inline functions cannot have the following attributes: `#[persistent]`, `#[module_lock]`", + ); + } + + if func.get_access_specifiers().is_some() { + env.warning( + &func.get_id_loc(), + "acquires and access specifiers are not applicable to inline functions and should be removed", + ); + } + keep_inline_functions } else { // not an inline function @@ -347,7 +369,7 @@ fn check_for_cycles( let mut cycles: BTreeSet> = BTreeSet::new(); let mut reachable_from_map: BTreeMap>> = call_graph .iter() - .map(|(node, set)| (*node, iter::repeat(vec![*node]).take(set.len()).collect())) + .map(|(node, set)| (*node, std::iter::repeat_n(vec![*node], set.len()).collect())) .collect(); let mut changed = true; @@ -735,13 +757,13 @@ impl<'env, 'rewriter> InlinedRewriter<'env, 'rewriter> { let mut sym_param_map: BTreeMap = BTreeMap::new(); let mut function_value_spec_map = BTreeMap::new(); - if lift_inline_funs && target_qualified_fun_id_opt.is_some() { + if lift_inline_funs && let Some(target_qualified_fun_id) = target_qualified_fun_id_opt { let mut lifted_lambda_funs: BTreeMap = BTreeMap::new(); let options = LambdaLiftingOptions { include_inline_functions: true, }; - let fun_env = env.get_function(target_qualified_fun_id_opt.unwrap()); + let fun_env = env.get_function(target_qualified_fun_id); for (para, lambda) in lambda_args_matched.iter().copied() { let mut lifter = LambdaLifter::new( &options, @@ -762,7 +784,7 @@ impl<'env, 'rewriter> InlinedRewriter<'env, 'rewriter> { } function_value_spec_map = run_spec_rewriter_inline( env, - target_qualified_fun_id_opt.unwrap().module_id, + target_qualified_fun_id.module_id, lifted_lambda_funs, ); } @@ -854,13 +876,29 @@ impl<'env, 'rewriter> InlinedRewriter<'env, 'rewriter> { .map(|(_, para)| para) .collect_vec(); - // Find free variables in lambda expr. Perhaps we could minimize changes if we tracked each - // lambda arg individually in the inlined method and only rewrite the context of each - // inlined lambda, but that seems quite difficult. Instead, just group all the free vars - // together and shadow them all. + // If a caller is provided, collect its parameter symbols. + let caller_param_symbols = target_qualified_fun_id_opt.map(|caller| { + env.get_function(caller) + .get_parameters() + .iter() + .map(|p| p.0) + .collect_vec() + }); + // Find free variables across all lambda expr arguments. + // Perhaps we could minimize changes if we tracked each lambda arg individually in the inlined + // method and only rewrite the context of each inlined lambda, but that seems quite difficult. + // Instead, just group all the free vars together and shadow them all. let all_lambda_free_vars: BTreeSet<_> = lambda_args_matched .iter() - .flat_map(|(_, exp)| exp.free_vars().into_iter()) + .flat_map(|(_, exp)| { + // If a caller is provided, compute free vars and used params. + if let Some(caller_param_symbols) = &caller_param_symbols { + exp.free_vars_and_used_params(caller_param_symbols) + .into_iter() + } else { + exp.free_vars().into_iter() + } + }) .collect(); // While we're looking at the lambdas, check for Return in their bodies. @@ -1433,7 +1471,7 @@ impl ExpRewriterFunctions for InlinedRewriter<'_, '_> { pattern_vec.clone(), )) }, - Pattern::Wildcard(_) => None, + Pattern::Wildcard(_) => Some(Pattern::Wildcard(new_id)), Pattern::Error(_) => None, } } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs b/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs new file mode 100644 index 00000000000..1ea58681a25 --- /dev/null +++ b/third_party/move/move-compiler-v2/src/env_pipeline/inlining_optimization.rs @@ -0,0 +1,769 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module implements the inlining optimization, whose aim is to reduce the number +//! of function calls (which comes at the cost of increasing code size). +//! +//! See the documentation for the `optimize` function for more details on what inlining is. + +use crate::{ + env_pipeline::rewrite_target::{RewriteState, RewriteTarget, RewriteTargets, RewritingScope}, + file_format_generator::MAX_LOCAL_COUNT, +}; +use codespan_reporting::diagnostic::Severity; +use move_binary_format::file_format::Visibility; +use move_model::{ + ast::{AccessSpecifierKind, Exp, ExpData, Operation, Pattern, TempIndex}, + exp_rewriter::ExpRewriterFunctions, + metadata::LanguageVersion, + model::{ + FunId, FunctionEnv, FunctionSize, GlobalEnv, Loc, ModuleEnv, ModuleId, NodeId, Parameter, + QualifiedId, + }, + ty::Type, + well_known, +}; +use once_cell::sync::Lazy; +use petgraph::{algo::kosaraju_scc, prelude::DiGraphMap}; +use std::{collections::BTreeSet, env}; + +/// [TODO]: tune the heuristic limits below +/// A conservative heuristic limit posed by the inlining optimization on how +/// large a caller function can grow to due to inlining. +pub static MAX_CALLER_CODE_SIZE: Lazy = Lazy::new(|| { + env::var("MAX_CALLER_CODE_SIZE") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(1024) +}); +/// A conservative heuristic limit posed by the inlining optimization on how +/// large a callee function can be for it to be considered for inlining. +pub static MAX_CALLEE_CODE_SIZE: Lazy = Lazy::new(|| { + env::var("MAX_CALLEE_CODE_SIZE") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(128) +}); +/// Number of times we want to apply "unrolling" of functions with inlining. +pub static UNROLL_DEPTH: Lazy = Lazy::new(|| { + env::var("UNROLL_DEPTH") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(10) +}); + +/// Optimize functions in target modules by applying inlining transformations. +/// With inlining, a call site of the form: +/// ```move +/// foo(a, b, c, ...) +/// ``` +/// with +/// ```move +/// fun foo(x, y, z, ...) { body } +/// ``` +/// becomes: +/// ```move +/// let (x, y, z, ...) = (a, b, c, ...); body +/// ``` +/// +/// The `across_package` value controls if inlining is performed across package boundaries. +/// With across-package inlining, calls to functions in other packages may be inlined, +/// which means that if the other package is upgraded, one would get the behavior +/// at the inline-time rather than the latest upgrade. +/// With `allow_non_primary_targets`, inlining optimization is performed to functions +/// that do not belong to the primary target. +pub fn optimize(env: &mut GlobalEnv, across_package: bool, allow_non_primary_targets: bool) { + let mut targets = RewriteTargets::create(env, RewritingScope::CompilationTarget); + let skip_functions = find_cycles_in_call_graph(env, &targets); + targets.filter(|target, _| { + if let RewriteTarget::MoveFun(function_id) = target { + let function = env.get_function(*function_id); + // We will consider inlining the callees in a function only if it satisfies all of: + // - is not a part of a cycle in the call graph + // - is in a primary target module (if `allow_non_primary_targets` is false) + // - is not in a script module + // - is not a test only function + // - is not a verify only function + // - is not a native function + // - is not an inline function + // - does not have the `#[module_lock]` attribute + !skip_functions.contains(function_id) + && (allow_non_primary_targets || function.module_env.is_primary_target()) + && !function.module_env.is_script_module() + && !function.is_test_only() + && !function.is_verify_only() + && !function.is_native() + && !function.is_inline() + && !has_module_lock_attribute(&function) + } else { + // only move functions are considered for inlining optimization + false + } + }); + let mut todo: Vec<_> = targets.keys().collect(); + // Each time you unroll, a call site may be substituted with the original body of the callee. + for _ in 0..*UNROLL_DEPTH { + if todo.is_empty() { + break; + } + todo = inline_call_sites(env, &mut targets, todo, across_package); + } + // Update the changed function definitions due to inlining. + targets.write_to_env(env); + // Inlining can cause direct calls to `package` functions that were previously + // indirect. Thus, it may require additional caller modules to become friends + // of the callee modules. + env.update_friend_decls_in_targets(); +} + +/// Inline call sites in the given `todo` list of functions. +/// When inlining, the original definition of the callee is used, resulting in +/// one-level of "unrolling". +/// The function size estimates are also updated based on the inlining decisions. +/// Return the list of functions that were changed due to inlining. +fn inline_call_sites( + env: &GlobalEnv, + targets: &mut RewriteTargets, + todo: Vec, + across_package: bool, +) -> Vec { + let mut changed_targets = Vec::new(); + for target in todo { + let RewriteTarget::MoveFun(function_id) = target else { + continue; + }; + let function_env = env.get_function(function_id); + if let Some(def) = get_latest_function_definition(targets, &target, &function_env) { + let caller_module = &function_env.module_env; + let current_caller_size = env + .function_size_estimate + .borrow() + .get(&function_id) + .copied(); + let Some(caller_size) = current_caller_size else { + continue; + }; + let (call_sites, new_size) = compute_call_sites_to_inline_and_new_function_size( + env, + caller_module, + def, + caller_size, + across_package, + &function_env, + ); + let mut rewriter = CallerRewriter { env, call_sites }; + // Rewrite the caller's body with inlined call sites. + let rewritten_def = rewriter.rewrite_exp(def.clone()); + // If nothing has changed, no need to update. + if !ExpData::ptr_eq(&rewritten_def, def) { + *targets.state_mut(&target) = RewriteState::Def(rewritten_def); + env.function_size_estimate + .borrow_mut() + .insert(function_id, new_size); + changed_targets.push(target); + } + } + } + changed_targets +} + +/// Get the "latest" definition of a `function`. If a function has some callsites +/// already inlined (unrolled up to some depth), then that definition is used. +fn get_latest_function_definition<'a>( + targets: &'a RewriteTargets, + target: &'a RewriteTarget, + function: &'a FunctionEnv, +) -> Option<&'a Exp> { + if let RewriteState::Def(def) = targets.state(target) { + // If the code has changed due to inlining, use updated definition. + Some(def) + } else if let Some(def) = function.get_def() { + // If code is unchanged, use original definition. + Some(def) + } else { + None + } +} + +/// Construct a call graph starting from the `targets`, and find all functions +/// that are part of cycles (including self-recursion). +fn find_cycles_in_call_graph( + env: &GlobalEnv, + targets: &RewriteTargets, +) -> BTreeSet> { + let mut graph = DiGraphMap::, ()>::new(); + let mut cycle_nodes = BTreeSet::new(); + for target in targets.keys() { + if let RewriteTarget::MoveFun(function) = target { + graph.add_node(function); + } + } + for caller in graph.nodes().collect::>() { + let caller_env = env.get_function(caller); + for callee in caller_env + .get_used_functions() + .expect("used functions must be computed") + { + if callee == &caller { + // self-recursion is added to the solution directly + cycle_nodes.insert(caller); + } else { + // non-self-recursion edges + graph.add_edge(caller, *callee, ()); + } + } + } + for scc in kosaraju_scc(&graph) { + if scc.len() > 1 { + // cycle involving non-self-recursion + cycle_nodes.extend(scc.into_iter()); + } + } + cycle_nodes +} + +/// For a given caller function `def`, find all the call sites that are eligible for inlining, +/// compute their costs, and pick as many as can fit within the heuristic limits. +/// Return the set of call sites to inline, and the new estimated size of the caller function +/// after inlining those call sites. +fn compute_call_sites_to_inline_and_new_function_size( + env: &GlobalEnv, + caller_module: &ModuleEnv, + def: &Exp, + caller_function_size: FunctionSize, + across_package: bool, + caller_func_env: &FunctionEnv, +) -> (BTreeSet, FunctionSize) { + let caller_mid = caller_module.get_id(); + let callees = def.called_funs_with_callsites_and_loop_depth(); + // Find all the callees that are eligible for inlining. + let inline_eligible_functions = callees + .into_iter() + .filter_map(|(callee, sites_and_loop_depth)| { + let callee_env = env.get_function(callee); + let callee_size = get_function_size_estimate(env, &callee); + if callee_env.is_inline() + || callee_env.is_native() + || callee_size.code_size > *MAX_CALLEE_CODE_SIZE + || has_explicit_return(&callee_env) + || has_abort(&callee_env, caller_func_env) + || has_privileged_operations(caller_mid, &callee_env) + || has_invisible_calls(caller_module, &callee_env, across_package) + || has_module_lock_attribute(&callee_env) + || has_access_controls(&callee_env) + { + // won't inline if: + // - callee is inline (should have been inlined already) + // - callee is native (no body to inline) + // - callee is too large (heuristic limit) + // - callee has an explicit return (cannot inline safely without additional + // transformations) + // - callee has privileged operations on structs/enums that the caller cannot + // perform directly + // - callee has calls to functions that are not visible from the caller module + // - callee has the `#[module_lock]` attribute + // - callee has runtime access control checks + // - callee has an abort expression + None + } else { + let function_size = get_function_size_estimate(env, &callee); + let callee_frequency = sites_and_loop_depth.len(); + assert!(callee_frequency > 0); + // Note that the number of locals introduced by inlining a callee can be amortized + // by the number of times the callee is called, because these variables have + // non-overlapping lifetimes and will likely be coalesced. + // We also currently either inline all the callsites of a callee or none (for simplicity). + let locals_per_site = function_size.num_locals; + let amortized_locals_per_site = locals_per_site.div_ceil(callee_frequency); + let max_loop_depth = sites_and_loop_depth + .iter() + .map(|(_, depth)| depth) + .max() + .copied() + .unwrap_or_default(); + let sites = sites_and_loop_depth + .iter() + .map(|(s, _)| s) + .copied() + .collect::>(); + let code_size = callee_size.code_size; + Some((sites, CalleeInfo { + max_loop_depth, + amortized_locals_per_site, + code_size, + locals_per_site, + })) + } + }) + .collect::>(); + pick_from_eligible_and_compute_cost(inline_eligible_functions, caller_function_size) +} + +/// Various information about a callee function that is eligible for inlining. +struct CalleeInfo { + /// Maximum loop depth of any of the call sites of this callee. + max_loop_depth: usize, + /// Amortized number of locals per call site after inlining. + amortized_locals_per_site: usize, + /// Estimated code size of the callee function. + code_size: usize, + /// Estimate number of locals in the callee function. + locals_per_site: usize, +} + +/// Given a list of eligible callsites to inline, pick as many as possible within the +/// heuristic limits, and compute the new estimated size of the caller function. +/// Each element of `inline_eligible_callees` is a pair of: +/// - set of call sites of a callee +/// - information about the callee that can help in making inlining decisions +fn pick_from_eligible_and_compute_cost( + mut inline_eligible_callees: Vec<(BTreeSet, CalleeInfo)>, + caller_function_size: FunctionSize, +) -> (BTreeSet, FunctionSize) { + inline_eligible_callees.sort_by(|a, b| { + // Sort callees based on the following (tie-break leads to next criteria): + // 1. Highest loop depth of any of the call sites + // 2. Lower amortized locals per call site + // 3. Lower code size of callee + // 4. Lower frequency of callee + // 5. Lower locals per call site + b.1.max_loop_depth + .cmp(&a.1.max_loop_depth) + .then_with(|| { + a.1.amortized_locals_per_site + .cmp(&b.1.amortized_locals_per_site) + }) + .then_with(|| a.1.code_size.cmp(&b.1.code_size)) + .then_with(|| a.0.len().cmp(&b.0.len())) + .then_with(|| a.1.locals_per_site.cmp(&b.1.locals_per_site)) + }); + let FunctionSize { + code_size, + num_locals, + } = caller_function_size; + let locals_budget = MAX_LOCAL_COUNT.saturating_sub(num_locals); + let code_size_budget = MAX_CALLER_CODE_SIZE.saturating_sub(code_size); + let mut locals_budget_remaining = locals_budget; + let mut code_size_budget_remaining = code_size_budget; + let mut call_sites_to_inline = BTreeSet::new(); + // Go over the sorted callees and greedily pick as many as fit within the budget. + for (sites, callee_info) in inline_eligible_callees { + if locals_budget_remaining == 0 || code_size_budget_remaining == 0 { + // no more budget left + break; + } + if let (Some(locals_reduced), Some(code_size_reduced)) = ( + locals_budget_remaining.checked_sub(callee_info.locals_per_site), + code_size_budget_remaining.checked_sub(callee_info.code_size * sites.len()), + ) { + call_sites_to_inline.extend(sites.into_iter()); + // Note that we reduce the remaining budget for number of locals once for + // all the callsites of a callee, because we expect to coalesce the locals at + // different callsites. + // The remaining budget for code size is reduced for each callsite. + locals_budget_remaining = locals_reduced; + code_size_budget_remaining = code_size_reduced; + } else { + // cannot inline this callee due to budget limits + // maybe try the next candidate + continue; + } + } + ( + call_sites_to_inline, + FunctionSize::new( + code_size + (code_size_budget - code_size_budget_remaining), + num_locals + (locals_budget - locals_budget_remaining), + ), + ) +} + +fn get_function_size_estimate(env: &GlobalEnv, function: &QualifiedId) -> FunctionSize { + env.function_size_estimate + .borrow() + .get(function) + .copied() + .unwrap_or_default() +} + +/// Does `callee` have any privileged operations on structs/enums that cannot be performed +/// directly in a caller with module id `caller_mid`? +fn has_privileged_operations(caller_mid: ModuleId, callee: &FunctionEnv) -> bool { + let env = callee.env(); + // keep track if we have found any privileged operations + let mut found = false; + // used to track if we are within a spec block, privileged operations within + // spec blocks are allowed + let mut spec_blocks_seen = 0; + if let Some(body) = callee.get_def() { + body.visit_pre_post(&mut |post, exp: &ExpData| { + if !post { + if matches!(exp, ExpData::SpecBlock(..)) { + spec_blocks_seen += 1; + } + if spec_blocks_seen > 0 { + // within a spec block, we can have privileged operations + return true; + } + // not inside a spec block, see if there are any privileged operations + match exp { + ExpData::Call(id, op, _) => match op { + Operation::Exists(_) + | Operation::BorrowGlobal(_) + | Operation::MoveFrom + | Operation::MoveTo => { + let inst = env.get_node_instantiation(*id); + if let Some((struct_env, _)) = inst[0].get_struct(env) { + let struct_mid = struct_env.module_env.get_id(); + if struct_mid != caller_mid { + found = true; + } + } + }, + Operation::Select(mid, ..) + | Operation::SelectVariants(mid, ..) + | Operation::TestVariants(mid, ..) + | Operation::Pack(mid, ..) => { + if *mid != caller_mid { + found = true; + } + }, + _ => {}, + }, + // various ways to unpack + ExpData::Assign(_, pat, _) + | ExpData::Block(_, pat, ..) + | ExpData::Lambda(_, pat, ..) => pat.visit_pre_post(&mut |post, pat| { + if !post { + if let Pattern::Struct(_, sid, ..) = pat { + let struct_mid = sid.module_id; + if struct_mid != caller_mid { + found = true; + } + } + } + }), + ExpData::Match(_, discriminator, _) => { + let did = discriminator.node_id(); + if let Type::Struct(mid, ..) = env.get_node_type(did).drop_reference() { + if mid != caller_mid { + found = true; + } + } + }, + _ => {}, + } + } else { + // post visit + if matches!(exp, ExpData::SpecBlock(..)) { + spec_blocks_seen -= 1; + } + } + // skip scanning for privileged operations if we already found one + !found + }); + } + found +} + +/// Does `callee` have any calls to functions that are not visible from `caller_module`? +fn has_invisible_calls( + caller_module: &ModuleEnv, + callee: &FunctionEnv, + across_package: bool, +) -> bool { + let env = callee.env(); + let caller_mid = caller_module.get_id(); + if let Some(body) = callee.get_def() { + for called_fun_id in body.used_funs() { + let called_function = env.get_function(called_fun_id); + let called_mid = called_function.module_env.get_id(); + if called_mid == caller_mid { + // same module, so visible + continue; + } + // TODO(#13745): hack for checking if two modules are in the same package + let same_package = caller_module.self_address() + == called_function.module_env.self_address() + && caller_module.is_primary_target() + && called_function.module_env.is_primary_target(); + + match called_function.visibility() { + Visibility::Public => { + if !same_package && !across_package { + // public function in a different package cannot be inlined due to change + // in semantics on package upgrade, but we allow it when across-package + // inlining is enabled + return true; + } + }, + Visibility::Private => { + return true; + }, + Visibility::Friend => { + // Note: `is_friend` implies `same_package` + let is_friend = called_function.module_env.has_friend(&caller_mid); + if is_friend || (called_function.has_package_visibility() && same_package) { + // 1. a call to a friend function whose module has the caller module as a friend + // is visible and belongs to the same package + // 2. a call to a package function belonging to the same package is also visible + continue; + } + return true; + }, + } + } + } + false +} + +/// Does `function` have an explicit return statement in its body? +fn has_explicit_return(function: &FunctionEnv) -> bool { + let Some(exp) = function.get_def() else { + return false; + }; + let mut found = false; + exp.visit_pre_order(&mut |e: &ExpData| { + if let ExpData::Return(..) = e { + found = true; + } + // Keep going if not yet found + !found + }); + found +} + +/// Does `function` have an abort expression in its body? +fn has_abort(function: &FunctionEnv, caller: &FunctionEnv) -> bool { + let Some(exp) = function.get_def() else { + return false; + }; + if function.module_env.get_id() == caller.module_env.get_id() { + return false; + } + let mut found = false; + exp.visit_pre_order(&mut |e: &ExpData| { + if let ExpData::Call(_, Operation::Abort, _) = e { + found = true; + } + // Keep going if not yet found + !found + }); + found +} + +/// Does `function` have any runtime access control checks? +/// If so, by inlining, such checks would not be performed. +fn has_access_controls(function: &FunctionEnv) -> bool { + if let Some(access_specifiers) = function.get_access_specifiers() { + if access_specifiers.is_empty() { + // empty access specifiers means no access is allowed, the strictest form + // of access control + return true; + } + // any reads or writes specification is considered an access control + access_specifiers + .iter() + .any(|spec| spec.kind != AccessSpecifierKind::LegacyAcquires) + } else { + false + } +} + +/// Does `function` have the `#[module_lock]` attribute? +fn has_module_lock_attribute(function: &FunctionEnv) -> bool { + let env = function.env(); + function.has_attribute(|attr| { + env.symbol_pool().string(attr.name()).as_str() == well_known::MODULE_LOCK_ATTRIBUTE + }) +} + +/// Rewriter for a caller function to inline the call sites in it. +struct CallerRewriter<'env> { + env: &'env GlobalEnv, + // The call sites that have been picked to inline + call_sites: BTreeSet, +} + +impl ExpRewriterFunctions for CallerRewriter<'_> { + fn rewrite_call(&mut self, call_id: NodeId, op: &Operation, args: &[Exp]) -> Option { + if self.call_sites.contains(&call_id) { + if let Operation::MoveFunction(mid, fid) = op { + let callee = self.env.get_function(mid.qualified(*fid)); + let type_args = self.env.get_node_instantiation(call_id); + let call_site_loc = self.env.get_node_loc(call_id); + let mut callee_rewriter = CalleeRewriter { + function_env: &callee, + type_args: &type_args, + call_site_loc: &call_site_loc, + }; + let body = callee.get_def()?; + // Rewrite the body of the callee to adjust node ids, types, and locations. + let rewritten_body = callee_rewriter.rewrite_exp(body.clone()); + // Construct a pattern for the parameters of the callee to create a `let` binding. + let params_pattern = callee_rewriter.params_to_pattern(&callee); + // Perform inlining transformation at the call site. + Some(self.construct_inlined_call_expression( + &call_site_loc, + rewritten_body, + params_pattern, + args.to_vec(), + )) + } else { + unreachable!("callsites should be calls to MoveFunction") + } + } else { + None + } + } +} + +impl CallerRewriter<'_> { + /// Given a transformed `body` of the callee, a tuple pattern `(x, y, ..)` + /// corresponding to the parameters of the callee, and the arguments + /// `a, b, ..` at the call site, construct the inlined expression: + /// ```move + /// let (x, y, ..) = (a, b, ..); body + /// ``` + fn construct_inlined_call_expression( + &self, + call_site_loc: &Loc, + body: Exp, + params_pattern: Pattern, + args: Vec, + ) -> Exp { + let body_node_id = body.as_ref().node_id(); + let body_type = self.env.get_node_type(body_node_id); + let body_loc = self + .env + .get_node_loc(body_node_id) + .inlined_from(call_site_loc); + + let new_block_id = self.env.new_node(body_loc, body_type); + + let optional_binding_exp = if args.is_empty() { + None + } else { + let args_node_ids = args + .iter() + .map(|e| e.as_ref().node_id()) + .collect::>(); + let args_types = args_node_ids + .iter() + .map(|id| self.env.get_node_type(*id)) + .collect::>(); + let args_loc = Loc::enclosing( + args_node_ids + .iter() + .map(|id| self.env.get_node_loc(*id)) + .collect::>() + .as_slice(), + ); + let new_binding_id = self.env.new_node(args_loc, Type::Tuple(args_types)); + Some(ExpData::Call(new_binding_id, Operation::Tuple, args).into_exp()) + }; + + ExpData::Block(new_block_id, params_pattern, optional_binding_exp, body).into_exp() + } +} + +/// Rewriter for the callee function at a given call site. +struct CalleeRewriter<'a> { + /// The function environment of the callee. + function_env: &'a FunctionEnv<'a>, + /// The type arguments at the call site. + type_args: &'a Vec, + /// The location of the call site. + call_site_loc: &'a Loc, +} + +impl ExpRewriterFunctions for CalleeRewriter<'_> { + /// Update node ids to new ones, and update their locations to reflect inlining. + fn rewrite_node_id(&mut self, id: NodeId) -> Option { + let loc = self.function_env.env().get_node_loc(id); + let new_loc = loc.inlined_from(self.call_site_loc); + ExpData::instantiate_node_new_loc(self.function_env.env(), id, self.type_args, &new_loc) + } + + /// Update patterns to use new node ids. + fn rewrite_pattern(&mut self, pat: &Pattern, _entering_scope: bool) -> Option { + let old_id = pat.node_id(); + let new_id = ExpData::instantiate_node(self.function_env.env(), old_id, self.type_args) + .unwrap_or(old_id); + match pat { + Pattern::Struct(_, struct_id, variant, pattern_vec) => { + let new_struct_id = struct_id.clone().instantiate(self.type_args); + Some(Pattern::Struct( + new_id, + new_struct_id, + *variant, + pattern_vec.clone(), + )) + }, + Pattern::Tuple(_, pattern_vec) => Some(Pattern::Tuple(new_id, pattern_vec.clone())), + Pattern::Var(_, symbol) => Some(Pattern::Var(new_id, *symbol)), + Pattern::Wildcard(_) => Some(Pattern::Wildcard(new_id)), + Pattern::Error(_) => None, + } + } + + /// Replaces the temporary referring to the parameter with the corresponding symbol. + fn rewrite_temporary(&mut self, id: NodeId, idx: TempIndex) -> Option { + if let Some(Parameter(sym, ty, loc)) = self.function_env.get_parameters_ref().get(idx) { + let inst_ty = ty.instantiate(self.type_args); + let new_node_id = self.function_env.env().new_node(loc.clone(), inst_ty); + Some(ExpData::LocalVar(new_node_id, *sym).into()) + } else { + let loc = self.function_env.env().get_node_loc(id); + self.function_env.env().diag( + Severity::Bug, + &loc, + &format!( + "temporary with invalid index `{}` when applying inlining optimization", + idx + ), + ); + None + } + } +} + +impl CalleeRewriter<'_> { + /// Construct a tuple pattern for the parameters of the callee function. + /// E.g., for a function with parameters `x: T, y: bool`, this returns + /// the pattern `(x, y)`, with `x` and `y` instantiated with respective + /// types known at this call site. + fn params_to_pattern(&self, function: &FunctionEnv) -> Pattern { + let params = function.get_parameters(); + let function_loc = function.get_id_loc(); + let tuple_args = params + .iter() + .map(|Parameter(sym, ty, loc)| { + let id = self + .function_env + .env() + .new_node(loc.clone(), ty.instantiate(self.type_args)); + if self + .function_env + .env() + .language_version() + .is_at_least(LanguageVersion::V2_1) + && self.function_env.symbol_pool().string(*sym).as_ref() == "_" + { + Pattern::Wildcard(id) + } else { + Pattern::Var(id, *sym) + } + }) + .collect::>(); + let tuple_types = params + .iter() + .map(|p| p.1.instantiate(self.type_args)) + .collect::>(); + let id = self.function_env.env().new_node( + function_loc.inlined_from(self.call_site_loc), + Type::Tuple(tuple_types), + ); + Pattern::Tuple(id, tuple_args) + } +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs index 58333b037ac..5515daa5889 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs @@ -40,6 +40,8 @@ //! like `|x| f(c, x)` can be represented as `Closure(f, mask(0b01), c)`, whereas //! `|x| f(x, c)` can be represented as `Closure(f, mask(0b10), c)`. +use crate::COMPILER_BUG_REPORT_MSG; +use codespan_reporting::diagnostic::Severity; use itertools::Itertools; use move_binary_format::file_format::Visibility; use move_core_types::function::ClosureMask; @@ -174,7 +176,7 @@ pub struct LambdaLifter<'a> { } struct VarInfo { - /// The node were this variable was found. + /// The node where this variable was found. node_id: NodeId, /// Whether the variable is modified modified: bool, @@ -387,12 +389,10 @@ impl<'a> LambdaLifter<'a> { { // We can capture an argument if it can be eagerly evaluated and if // it does not depend on lambda arguments. - if pos >= ClosureMask::MAX_ARGS { - // Exceeded maximal number of arguments which can be captured + if mask.set_captured(pos).is_err() { return None; } captured.push(arg.clone()); - mask.set_captured(pos); } else if lambda_param_pos < lambda_params.len() && matches!(arg.as_ref(), LocalVar(_, name) if name == &lambda_params[lambda_param_pos].0) { @@ -462,6 +462,53 @@ impl<'a> LambdaLifter<'a> { | Loop(..) | LoopCont(..) | Assign(..) | Mutate(..) | SpecBlock(..) => false, } } + + fn is_symbol_in_scope(&self, sym: &Symbol) -> bool { + self.scopes.iter().any(|scope| scope.contains(sym)) + } + + /// Insert `sym` as a free local variable, if it is not already in scope. + fn try_insert_free_local(&mut self, sym: Symbol, var_info: VarInfo) { + if !self.is_symbol_in_scope(&sym) { + if var_info.modified { + // Make sure we mark the variable as modified. + self.free_locals.insert(sym, var_info); + } else { + self.free_locals.entry(sym).or_insert(var_info); + } + } + } + + /// Perform a rewrite action in an isolated context. + /// To do so, we save the current context (free parameters, free locals, and scopes), + /// perform the rewrite action, and then restore the context. + fn rewrite_with_isolated_context(&mut self, rewrite: F, exp: Exp) -> Exp + where + F: FnOnce(&mut Self, Exp) -> Exp, + { + // Save the current context. + let mut curr_free_params = mem::take(&mut self.free_params); + let mut curr_free_locals = mem::take(&mut self.free_locals); + let curr_scopes = mem::take(&mut self.scopes); + // Perform the rewrite action. + let result = rewrite(self, exp); + // Restore the context. + self.scopes = curr_scopes; + // Remove free vars present in the re-instated scope. + let to_remove = self + .free_locals + .keys() + .filter(|sym| self.is_symbol_in_scope(sym)) + .copied() + .collect::>(); + for sym in to_remove { + self.free_locals.remove(&sym); + } + self.free_locals.append(&mut curr_free_locals); + self.free_params.append(&mut curr_free_params); + // Return the result of the rewrite. + result + } } impl ExpRewriterFunctions for LambdaLifter<'_> { @@ -483,12 +530,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { // Also if this is a lambda, before descent, clear any usages from siblings in the // context, so we get the isolated usage information for the lambda's body. if matches!(exp.as_ref(), ExpData::Lambda(..)) { - let mut curr_free_params = mem::take(&mut self.free_params); - let mut curr_free_locals = mem::take(&mut self.free_locals); - let result = self.rewrite_exp_descent(exp); - self.free_params.append(&mut curr_free_params); - self.free_locals.append(&mut curr_free_locals); - result + self.rewrite_with_isolated_context(ExpRewriterFunctions::rewrite_exp_descent, exp) } else { self.rewrite_exp_descent(exp) } @@ -504,14 +546,12 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { } fn rewrite_exit_scope(&mut self, _id: NodeId) { - let exiting = self.scopes.pop().expect("stack balanced"); - // Remove all locals which are bound in the scope we are exiting. - self.free_locals.retain(|name, _| !exiting.contains(name)); + self.scopes.pop().expect("stack balanced"); } fn rewrite_local_var(&mut self, node_id: NodeId, sym: Symbol) -> Option { // duplicates are OK -- they are all the same local at different locations - self.free_locals.entry(sym).or_insert(VarInfo { + self.try_insert_free_local(sym, VarInfo { node_id, modified: false, }); @@ -529,7 +569,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { fn rewrite_assign(&mut self, _node_id: NodeId, lhs: &Pattern, _rhs: &Exp) -> Option { for (node_id, name) in lhs.vars() { - self.free_locals.insert(name, VarInfo { + self.try_insert_free_local(name, VarInfo { node_id, modified: true, }); @@ -541,7 +581,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { if matches!(oper, Operation::Borrow(ReferenceKind::Mutable)) { match args[0].as_ref() { ExpData::LocalVar(node_id, name) => { - self.free_locals.insert(*name, VarInfo { + self.try_insert_free_local(*name, VarInfo { node_id: *node_id, modified: true, }); @@ -724,7 +764,15 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { Operation::Closure( module_id, fun_id, - ClosureMask::new_for_leading(closure_args.len()), + ClosureMask::new_for_leading(closure_args.len()).unwrap_or_else(|err| { + env.diag_with_notes( + Severity::Bug, + &env.get_node_loc(id), + &format!("compiler internal error: {}", err), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ); + ClosureMask::empty() + }), ), closure_args, ) diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs index fb2161ae5ee..a8fdec924dd 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs @@ -11,10 +11,12 @@ use std::io::Write; pub mod acquires_checker; pub mod ast_simplifier; pub mod closure_checker; +pub mod cmp_rewriter; pub mod cyclic_instantiation_checker; pub mod flow_insensitive_checkers; pub mod function_checker; pub mod inliner; +pub mod inlining_optimization; pub mod lambda_lifter; pub mod model_ast_lints; pub mod recursive_struct_checker; diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs index e400eac2c6c..72d032f069b 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs @@ -11,7 +11,7 @@ use crate::env_pipeline::rewrite_target::{ RewriteState, RewriteTarget, RewriteTargets, RewritingScope, }; use codespan_reporting::diagnostic::Severity; -use log::info; +use log::debug; use move_model::{ ast::{Exp, Spec}, model::{FunId, GlobalEnv, NodeId, QualifiedId}, @@ -19,7 +19,7 @@ use move_model::{ }; pub fn run_spec_checker(env: &GlobalEnv) { - info!("checking specifications"); + debug!("checking specifications"); // Targets are all spec functions and spec blocks, as well as functions to // process inline specs. diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs index a0ce2157dba..e56f7c4b729 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs @@ -24,7 +24,7 @@ use crate::env_pipeline::rewrite_target::{ RewriteState, RewriteTarget, RewriteTargets, RewritingScope, }; use itertools::Itertools; -use log::info; +use log::debug; use move_model::{ ast::{ConditionKind, Exp, ExpData, GlobalInvariant, Operation, SpecBlockTarget, SpecFunDecl}, exp_rewriter::ExpRewriterFunctions, @@ -43,7 +43,7 @@ use std::{ }; pub fn run_spec_rewriter(env: &mut GlobalEnv) { - info!("rewriting specifications"); + debug!("rewriting specifications"); // Collect all spec blocks and spec functions in the whole program, plus // functions in compilation scope. For the later we need to process @@ -233,7 +233,7 @@ pub fn run_spec_rewriter_inline( module_id: ModuleId, lambda_fun_map: BTreeMap, ) -> BTreeMap, QualifiedId)> { - info!("rewriting specifications in inline functions"); + debug!("rewriting specifications in inline functions"); let mut targets = RewriteTargets::create_fun_targets(env, vec![]); diff --git a/third_party/move/move-compiler-v2/src/experiments.rs b/third_party/move/move-compiler-v2/src/experiments.rs index 1a94e655181..9d1e5890fb8 100644 --- a/third_party/move/move-compiler-v2/src/experiments.rs +++ b/third_party/move/move-compiler-v2/src/experiments.rs @@ -96,11 +96,31 @@ pub static EXPERIMENTS: Lazy> = Lazy::new(|| { .to_string(), default: Inherited(Experiment::CHECKS.to_string()), }, + Experiment { + name: Experiment::CMP_REWRITE.to_string(), + description: "Rewrite comparison operations".to_string(), + default: Given(true), + }, Experiment { name: Experiment::INLINING.to_string(), description: "Turns on or off inlining".to_string(), default: Given(true), }, + Experiment { + name: Experiment::INLINING_OPTIMIZATION.to_string(), + description: "Turns on or off inlining optimizations".to_string(), + default: Given(false), + }, + Experiment { + name: Experiment::ACROSS_PACKAGE_INLINING.to_string(), + description: "Turns on or off inlining across package boundaries".to_string(), + default: Given(false), + }, + Experiment { + name: Experiment::INLINING_OPTIMIZATION_TO_NON_PRIMARY_TARGETS.to_string(), + description: "Turns on or off restricting inlining optimization to primary target modules".to_string(), + default: Given(false), + }, Experiment { name: Experiment::SPEC_CHECK.to_string(), description: "Turns on or off specification checks".to_string(), @@ -265,6 +285,19 @@ pub static EXPERIMENTS: Lazy> = Lazy::new(|| { .to_string(), default: Given(false), }, + Experiment { + name: Experiment::UNSAFE_PACKAGE_VISIBILITY.to_string(), + description: "Treat all package functions with same address as visible (currently necessary for prover in filter mode)" + .to_string(), + default: Given(false), + }, + Experiment { + name: Experiment::COMPILE_FOR_TESTING.to_string(), + description: "Compile for testing. If set, constant \ + `__COMPILE_FOR_TESTING__` will be true, otherwise false." + .to_string(), + default: Given(false), + }, ]; experiments .into_iter() @@ -277,16 +310,22 @@ impl Experiment { pub const ABILITY_CHECK: &'static str = "ability-check"; pub const ACCESS_CHECK: &'static str = "access-use-function-check"; pub const ACQUIRES_CHECK: &'static str = "acquires-check"; + pub const ACROSS_PACKAGE_INLINING: &'static str = "across-package-inlining"; pub const AST_SIMPLIFY: &'static str = "ast-simplify"; pub const AST_SIMPLIFY_FULL: &'static str = "ast-simplify-full"; pub const ATTACH_COMPILED_MODULE: &'static str = "attach-compiled-module"; pub const CFG_SIMPLIFICATION: &'static str = "cfg-simplification"; pub const CHECKS: &'static str = "checks"; + pub const CMP_REWRITE: &'static str = "cmp-rewrite"; + pub const COMPILE_FOR_TESTING: &'static str = "compile-for-testing"; pub const DEAD_CODE_ELIMINATION: &'static str = "dead-code-elimination"; pub const DUPLICATE_STRUCT_PARAMS_CHECK: &'static str = "duplicate-struct-params-check"; pub const FAIL_ON_WARNING: &'static str = "fail-on-warning"; pub const FLUSH_WRITES_OPTIMIZATION: &'static str = "flush-writes-optimization"; pub const INLINING: &'static str = "inlining"; + pub const INLINING_OPTIMIZATION: &'static str = "inlining-optimization"; + pub const INLINING_OPTIMIZATION_TO_NON_PRIMARY_TARGETS: &'static str = + "inlining-optimization-to-non-primary-targets"; pub const KEEP_INLINE_FUNS: &'static str = "keep-inline-funs"; pub const KEEP_UNINIT_ANNOTATIONS: &'static str = "keep-uninit-annotations"; pub const LAMBDA_LIFTING_INLINE: &'static str = "lambda-lifting-inline"; @@ -312,6 +351,7 @@ impl Experiment { pub const STOP_BEFORE_FILE_FORMAT: &'static str = "stop-before-file-format"; pub const STOP_BEFORE_STACKLESS_BYTECODE: &'static str = "stop-before-stackless-bytecode"; pub const UNINITIALIZED_CHECK: &'static str = "uninitialized-check"; + pub const UNSAFE_PACKAGE_VISIBILITY: &'static str = "unsafe-package-visibility"; pub const UNUSED_ASSIGNMENT_CHECK: &'static str = "unused-assignment-check"; pub const UNUSED_STRUCT_PARAMS_CHECK: &'static str = "unused-struct-params-check"; pub const USAGE_CHECK: &'static str = "usage-check"; diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs index 91321f32bc9..9bc8b9bdda1 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs @@ -33,7 +33,7 @@ use std::collections::{BTreeMap, BTreeSet}; pub struct FunctionGenerator<'a> { /// The underlying module generator. - gen: &'a mut ModuleGenerator, + r#gen: &'a mut ModuleGenerator, /// The set of temporaries which need to be pinned to locals because references are taken for /// them, or they are used in specs. pinned: BTreeSet, @@ -104,37 +104,40 @@ struct LabelInfo { impl<'a> FunctionGenerator<'a> { /// Runs the function generator for the given function. pub fn run<'b>( - gen: &'a mut ModuleGenerator, + r#gen: &'a mut ModuleGenerator, ctx: &'b ModuleContext, fun_env: FunctionEnv<'b>, acquires_list: &BTreeSet, ) { let loc = fun_env.get_id_loc(); - let function = gen.function_index(ctx, &loc, &fun_env); + let function = r#gen.function_index(ctx, &loc, &fun_env); let visibility = fun_env.visibility(); - let fun_count = gen.module.function_defs.len(); + let fun_count = r#gen.module.function_defs.len(); let def_idx = FunctionDefinitionIndex::new(ctx.checked_bound( &loc, fun_count, MAX_FUNCTION_DEF_COUNT, "defined function", )); - gen.source_map + r#gen + .source_map .add_top_level_function_mapping(def_idx, ctx.env.to_ir_loc(&loc), fun_env.is_native()) .expect(SOURCE_MAP_OK); for TypeParameter(name, _, loc) in fun_env.get_type_parameters() { - gen.source_map + r#gen + .source_map .add_function_type_parameter_mapping(def_idx, ctx.source_name(name, loc)) .expect(SOURCE_MAP_OK) } for Parameter(name, _, loc) in fun_env.get_parameters() { - gen.source_map + r#gen + .source_map .add_parameter_mapping(def_idx, ctx.source_name(name, loc)) .expect(SOURCE_MAP_OK) } - let (gen, code) = if !fun_env.is_native() { + let (r#gen, code) = if !fun_env.is_native() { let mut fun_gen = Self { - gen, + r#gen, pinned: Default::default(), temps: Default::default(), stack: vec![], @@ -159,7 +162,7 @@ impl<'a> FunctionGenerator<'a> { let transformed_code_chunk = peephole_optimizer::optimize(&code.code); // Fix the source map for the optimized code. fun_gen - .gen + .r#gen .source_map .remap_code_map(def_idx, &transformed_code_chunk.original_offsets) .expect(SOURCE_MAP_OK); @@ -171,15 +174,15 @@ impl<'a> FunctionGenerator<'a> { if !fun_gen.spec_blocks.is_empty() { fun_env.get_mut_spec().on_impl = fun_gen.spec_blocks; } - (fun_gen.gen, Some(code)) + (fun_gen.r#gen, Some(code)) } else { - (gen, None) + (r#gen, None) }; let acquires_global_resources = acquires_list .iter() .map(|id| { let struct_env = fun_env.module_env.get_struct(*id); - gen.struct_def_index(ctx, &struct_env.get_loc(), &struct_env) + r#gen.struct_def_index(ctx, &struct_env.get_loc(), &struct_env) }) .collect(); let def = FF::FunctionDefinition { @@ -190,7 +193,7 @@ impl<'a> FunctionGenerator<'a> { code, }; - gen.module.function_defs.push(def) + r#gen.module.function_defs.push(def) } /// Generates code for a function. @@ -250,7 +253,7 @@ impl<'a> FunctionGenerator<'a> { } // Deliver result - let locals = self.gen.signature( + let locals = self.r#gen.signature( &ctx.module, &ctx.loc, self.locals[ctx.fun.get_parameter_count()..].to_vec(), @@ -264,7 +267,7 @@ impl<'a> FunctionGenerator<'a> { /// Generate file-format bytecode from a stackless bytecode and an optional next bytecode /// for peephole optimizations. fn gen_bytecode(&mut self, ctx: &BytecodeContext, bc: &Bytecode, next_bc: Option<&Bytecode>) { - self.gen + self.r#gen .source_map .add_code_mapping( ctx.fun_ctx.def_idx, @@ -333,7 +336,7 @@ impl<'a> FunctionGenerator<'a> { self.emit(FF::Bytecode::Branch(0)); }, Bytecode::Abort(_, temp) => { - self.balance_stack_end_of_block(ctx, &vec![*temp]); + self.balance_stack_end_of_block(ctx, vec![*temp]); self.emit(FF::Bytecode::Abort); self.abstract_pop(ctx) }, @@ -566,7 +569,7 @@ impl<'a> FunctionGenerator<'a> { Type::new_prim(PrimitiveType::Bool) }; let sign = self - .gen + .r#gen .signature(&fun_ctx.module, &fun_ctx.loc, vec![elem_type]); self.gen_builtin( ctx, @@ -599,6 +602,12 @@ impl<'a> FunctionGenerator<'a> { Operation::CastU64 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU64, source), Operation::CastU128 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU128, source), Operation::CastU256 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU256, source), + Operation::CastI8 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI8, source), + Operation::CastI16 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI16, source), + Operation::CastI32 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI32, source), + Operation::CastI64 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI64, source), + Operation::CastI128 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI128, source), + Operation::CastI256 => self.gen_builtin(ctx, dest, FF::Bytecode::CastI256, source), Operation::Not => self.gen_builtin(ctx, dest, FF::Bytecode::Not, source), Operation::Add => self.gen_builtin(ctx, dest, FF::Bytecode::Add, source), Operation::Sub => self.gen_builtin(ctx, dest, FF::Bytecode::Sub, source), @@ -618,6 +627,7 @@ impl<'a> FunctionGenerator<'a> { Operation::And => self.gen_builtin(ctx, dest, FF::Bytecode::And, source), Operation::Eq => self.gen_builtin(ctx, dest, FF::Bytecode::Eq, source), Operation::Neq => self.gen_builtin(ctx, dest, FF::Bytecode::Neq, source), + Operation::Negate => self.gen_builtin(ctx, dest, FF::Bytecode::Negate, source), Operation::TraceLocal(_) | Operation::TraceReturn(_) @@ -658,20 +668,20 @@ impl<'a> FunctionGenerator<'a> { &ctx.fun_ctx.loc, id, Some( - self.gen + self.r#gen .signature(&ctx.fun_ctx.module, &ctx.fun_ctx.loc, inst.to_vec()), ), ) { self.emit(opcode) } else if inst.is_empty() { - let idx = self.gen.function_index( + let idx = self.r#gen.function_index( &fun_ctx.module, &fun_ctx.loc, &fun_ctx.module.env.get_function(id), ); self.emit(FF::Bytecode::Call(idx)) } else { - let idx = self.gen.function_instantiation_index( + let idx = self.r#gen.function_instantiation_index( &fun_ctx.module, &fun_ctx.loc, &fun_ctx.module.env.get_function(id), @@ -696,14 +706,14 @@ impl<'a> FunctionGenerator<'a> { let fun_ctx = ctx.fun_ctx; self.abstract_push_args(ctx, source, None); if inst.is_empty() { - let idx = self.gen.function_index( + let idx = self.r#gen.function_index( &fun_ctx.module, &fun_ctx.loc, &fun_ctx.module.env.get_function(id), ); self.emit(FF::Bytecode::PackClosure(idx, mask)) } else { - let idx = self.gen.function_instantiation_index( + let idx = self.r#gen.function_instantiation_index( &fun_ctx.module, &fun_ctx.loc, &fun_ctx.module.env.get_function(id), @@ -722,7 +732,7 @@ impl<'a> FunctionGenerator<'a> { .fun .get_local_type(*source.last().expect("invoke has function argument last")); let sign_idx = self - .gen + .r#gen .signature(&ctx.fun_ctx.module, &ctx.fun_ctx.loc, vec![ clos_type.clone() ]); @@ -750,11 +760,11 @@ impl<'a> FunctionGenerator<'a> { let struct_env = &fun_ctx.module.env.get_struct(id); if inst.is_empty() { let idx = self - .gen + .r#gen .struct_def_index(&fun_ctx.module, &fun_ctx.loc, struct_env); self.emit(mk_simple(idx)) } else { - let idx = self.gen.struct_def_instantiation_index( + let idx = self.r#gen.struct_def_instantiation_index( &fun_ctx.module, &fun_ctx.loc, struct_env, @@ -782,11 +792,11 @@ impl<'a> FunctionGenerator<'a> { let struct_env = &fun_ctx.module.env.get_struct(id); if inst.is_empty() { let idx = - self.gen + self.r#gen .struct_variant_index(&fun_ctx.module, &fun_ctx.loc, struct_env, variant); self.emit(mk_simple(idx)) } else { - let idx = self.gen.struct_variant_inst_index( + let idx = self.r#gen.struct_variant_inst_index( &fun_ctx.module, &fun_ctx.loc, struct_env, @@ -820,7 +830,7 @@ impl<'a> FunctionGenerator<'a> { let field_env = &struct_env.get_field_by_offset_optional_variant(Some(variants[0]), offset); if inst.is_empty() { - let idx = self.gen.variant_field_index( + let idx = self.r#gen.variant_field_index( &fun_ctx.module, &fun_ctx.loc, variants, @@ -832,7 +842,7 @@ impl<'a> FunctionGenerator<'a> { self.emit(FF::Bytecode::ImmBorrowVariantField(idx)) } } else { - let idx = self.gen.variant_field_inst_index( + let idx = self.r#gen.variant_field_inst_index( &fun_ctx.module, &fun_ctx.loc, variants, @@ -849,7 +859,7 @@ impl<'a> FunctionGenerator<'a> { let field_env = &struct_env.get_field_by_offset_optional_variant(None, offset); if inst.is_empty() { let idx = self - .gen + .r#gen .field_index(&fun_ctx.module, &fun_ctx.loc, field_env); if is_mut { self.emit(FF::Bytecode::MutBorrowField(idx)) @@ -857,9 +867,9 @@ impl<'a> FunctionGenerator<'a> { self.emit(FF::Bytecode::ImmBorrowField(idx)) } } else { - let idx = self - .gen - .field_inst_index(&fun_ctx.module, &fun_ctx.loc, field_env, inst); + let idx = + self.r#gen + .field_inst_index(&fun_ctx.module, &fun_ctx.loc, field_env, inst); if is_mut { self.emit(FF::Bytecode::MutBorrowFieldGeneric(idx)) } else { @@ -908,15 +918,26 @@ impl<'a> FunctionGenerator<'a> { U64(n) => self.emit(FF::Bytecode::LdU64(*n)), U128(n) => self.emit(FF::Bytecode::LdU128(*n)), U256(n) => self.emit(FF::Bytecode::LdU256( - move_core_types::u256::U256::from_le_bytes(&n.to_le_bytes()), + move_core_types::int256::U256::from_le_bytes(n.to_le_bytes()), + )), + I8(n) => self.emit(FF::Bytecode::LdI8(*n)), + I16(n) => self.emit(FF::Bytecode::LdI16(*n)), + I32(n) => self.emit(FF::Bytecode::LdI32(*n)), + I64(n) => self.emit(FF::Bytecode::LdI64(*n)), + I128(n) => self.emit(FF::Bytecode::LdI128(*n)), + I256(n) => self.emit(FF::Bytecode::LdI256( + move_core_types::int256::I256::from_le_bytes(n.to_le_bytes()), )), Vector(vec) if vec.is_empty() => { self.gen_vector_load_push(ctx, vec, dest_type); }, _ => { - let cons = - self.gen - .constant_index(&ctx.fun_ctx.module, &ctx.fun_ctx.loc, cons, dest_type); + let cons = self.r#gen.constant_index( + &ctx.fun_ctx.module, + &ctx.fun_ctx.loc, + cons, + dest_type, + ); self.emit(FF::Bytecode::LdConst(cons)); }, } @@ -934,7 +955,7 @@ impl<'a> FunctionGenerator<'a> { self.gen_load_push(ctx, cons, &elem_type); } let sign = self - .gen + .r#gen .signature(&fun_ctx.module, &fun_ctx.loc, vec![elem_type]); self.emit(FF::Bytecode::VecPack(sign, vec.len() as u64)); } @@ -1054,7 +1075,7 @@ impl<'a> FunctionGenerator<'a> { if ctx.is_alive_after(*temp, &temps_to_push[pos + 1..], true) { if !fun_ctx.is_copyable(*temp) { fun_ctx.module.internal_error( - &ctx.fun_ctx.fun.get_bytecode_loc(ctx.attr_id), + ctx.fun_ctx.fun.get_bytecode_loc(ctx.attr_id), format!("value in `$t{}` expected to be copyable", temp), ) } @@ -1250,7 +1271,7 @@ impl<'a> FunctionGenerator<'a> { }; // Only add to the source map if it wasn't a parameter. let name = ctx.fun.get_local_name(temp); - self.gen + self.r#gen .source_map .add_local_mapping(ctx.def_idx, ctx.module.source_name(name, loc)) .expect(SOURCE_MAP_OK); diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs index 9a87434a141..e8938ea361c 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 mod function_generator; -mod module_generator; +pub mod module_generator; mod peephole_optimizer; use crate::{file_format_generator::module_generator::ModuleContext, options::Options, Experiment}; use legacy_move_compiler::compiled_unit as CU; use module_generator::ModuleGenerator; -use move_binary_format::{file_format as FF, internals::ModuleIndex}; +use move_binary_format::{file_format as FF, internals::ModuleIndex, module_script_conversion}; use move_command_line_common::{address::NumericalAddress, parser::NumberFormat}; use move_model::{ast::ModuleName, model::GlobalEnv}; use move_stackless_bytecode::function_target_pipeline::FunctionTargetsHolder; @@ -81,7 +81,7 @@ pub fn generate_file_format( let module_name = ModuleName::pseudo_script_name(env.symbol_pool(), script_index); script_index += 1; - let module = move_model::script_into_module( + let module = module_script_conversion::script_into_module( script.clone(), &module_name.name().display(env.symbol_pool()).to_string(), ); @@ -138,4 +138,4 @@ const MAX_FIELD_INST_COUNT: usize = FF::TableIndex::MAX as usize; const MAX_FUNCTION_COUNT: usize = FF::TableIndex::MAX as usize; const MAX_FUNCTION_INST_COUNT: usize = FF::TableIndex::MAX as usize; const MAX_FUNCTION_DEF_COUNT: usize = FF::TableIndex::MAX as usize; -const MAX_LOCAL_COUNT: usize = FF::LocalIndex::MAX as usize; +pub const MAX_LOCAL_COUNT: usize = FF::LocalIndex::MAX as usize; diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs index ab2b8fb6733..84def3632b4 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs @@ -8,7 +8,7 @@ use crate::{ MAX_MODULE_COUNT, MAX_SIGNATURE_COUNT, MAX_STRUCT_COUNT, MAX_STRUCT_DEF_COUNT, MAX_STRUCT_DEF_INST_COUNT, MAX_STRUCT_VARIANT_COUNT, MAX_STRUCT_VARIANT_INST_COUNT, }, - Options, + Options, COMPILER_BUG_REPORT_MSG, }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; @@ -20,7 +20,10 @@ use move_core_types::{ use move_ir_types::ast as IR_AST; use move_model::{ ast::{AccessSpecifier, AccessSpecifierKind, AddressSpecifier, Attribute, ResourceSpecifier}, - metadata::{CompilationMetadata, CompilerVersion, LanguageVersion, COMPILATION_METADATA_KEY}, + metadata::{ + lang_feature_versions::LANGUAGE_VERSION_FOR_RAC, CompilationMetadata, CompilerVersion, + LanguageVersion, COMPILATION_METADATA_KEY, + }, model::{ FieldEnv, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, Parameter, QualifiedId, StructEnv, StructId, TypeParameter, TypeParameterKind, @@ -124,7 +127,7 @@ impl ModuleGenerator { let compiler_version = options .compiler_version .unwrap_or(CompilerVersion::latest_stable()); - let gen_access_specifiers = language_version.is_at_least(LanguageVersion::V2_3); + let gen_access_specifiers = language_version.is_at_least(LANGUAGE_VERSION_FOR_RAC); let gen_function_attributes = language_version.is_at_least(LanguageVersion::V2_2); let compilation_metadata = CompilationMetadata::new(compiler_version, language_version); let metadata = Metadata { @@ -152,7 +155,7 @@ impl ModuleGenerator { }; SourceMap::new(ctx.env.to_ir_loc(&module_env.get_loc()), module_name_opt) }; - let mut gen = Self { + let mut r#gen = Self { gen_access_specifiers, gen_function_attributes, module_idx: FF::ModuleHandleIndex(0), @@ -176,8 +179,8 @@ impl ModuleGenerator { module, source_map, }; - gen.gen_module(ctx, module_env); - (gen.module, gen.source_map, gen.main_handle) + r#gen.gen_module(ctx, module_env); + (r#gen.module, r#gen.source_map, r#gen.main_handle) } /// Generates a module, visiting all of its members. @@ -334,6 +337,12 @@ impl ModuleGenerator { U64 => FF::SignatureToken::U64, U128 => FF::SignatureToken::U128, U256 => FF::SignatureToken::U256, + I8 => FF::SignatureToken::I8, + I16 => FF::SignatureToken::I16, + I32 => FF::SignatureToken::I32, + I64 => FF::SignatureToken::I64, + I128 => FF::SignatureToken::I128, + I256 => FF::SignatureToken::I256, Address => FF::SignatureToken::Address, Signer => FF::SignatureToken::Signer, Num | Range | EventStore => { @@ -368,9 +377,9 @@ impl ModuleGenerator { } }, Fun(param_ty, result_ty, abilities) => { - let list = |gen: &mut ModuleGenerator, ts: Vec| { + let list = |r#gen: &mut ModuleGenerator, ts: Vec| { ts.into_iter() - .map(|t| gen.signature_token(ctx, loc, &t)) + .map(|t| r#gen.signature_token(ctx, loc, &t)) .collect_vec() }; FF::SignatureToken::Function( @@ -995,8 +1004,13 @@ impl ModuleContext<'_> { } /// Emits an internal error at the location. - pub fn internal_error(&self, loc: impl AsRef, msg: impl AsRef) { - self.env.diag(Severity::Bug, loc.as_ref(), msg.as_ref()) + pub fn internal_error(&self, loc: impl AsRef, msg: impl AsRef + ToString) { + self.env.diag_with_notes( + Severity::Bug, + loc.as_ref(), + format!("compiler internal error: {}", msg.to_string()).as_str(), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ) } /// Check for a bound table index and report an error if its out of bound. All bounds @@ -1069,6 +1083,33 @@ impl ModuleContext<'_> { } impl ModuleContext<'_> { + /// Get the called functions from the same module by traversing the stackless bytecode. + fn get_same_module_called_functions( + &self, + module: &ModuleEnv, + ) -> BTreeMap> { + let mut called_functions_map = BTreeMap::new(); + for fun in module.get_functions() { + if fun.is_inline() { + continue; + } + let mut called_functions = BTreeSet::new(); + let target = self.targets.get_target(&fun, &FunctionVariant::Baseline); + for bc in target.get_bytecode() { + use Bytecode::*; + use Operation::*; + if let Call(_, _, Function(mid, fid, _), ..) = bc { + // only add functions from the same module and not the function itself + if *mid == module.get_id() && *fid != fun.get_id() { + called_functions.insert(*fid); + } + } + } + called_functions_map.insert(fun.get_id(), called_functions); + } + called_functions_map + } + /// Acquires analysis. This is temporary until we have the full reference analysis. fn generate_acquires_map(&self, module: &ModuleEnv) -> BTreeMap> { // Compute map with direct usage of resources @@ -1077,6 +1118,7 @@ impl ModuleContext<'_> { .filter(|f| !f.is_inline()) .map(|f| (f.get_id(), self.get_direct_function_acquires(&f))) .collect::>(); + let called_functions_map = self.get_same_module_called_functions(module); // Now run a fixed-point loop: add resources used by called functions until there are no // changes. loop { @@ -1085,20 +1127,16 @@ impl ModuleContext<'_> { if fun.is_inline() { continue; } - if let Some(callees) = fun.get_called_functions() { - let mut usage = usage_map[&fun.get_id()].clone(); - let count = usage.len(); + let mut usage = usage_map[&fun.get_id()].clone(); + let count = usage.len(); + for called_fun in called_functions_map[&fun.get_id()].iter() { // Extend usage by that of callees from the same module. Acquires is only // local to a module. - for callee in callees { - if callee.module_id == module.get_id() { - usage.extend(usage_map[&callee.id].iter().cloned()); - } - } - if usage.len() > count { - *usage_map.get_mut(&fun.get_id()).unwrap() = usage; - changes = true; - } + usage.extend(usage_map[called_fun].iter().cloned()); + } + if usage.len() > count { + *usage_map.get_mut(&fun.get_id()).unwrap() = usage; + changes = true; } } if !changes { diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer.rs b/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer.rs index 812e662f70b..4f2b6b29267 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer.rs @@ -49,7 +49,7 @@ impl BasicBlockOptimizerPipeline { let mut code_chunk = TransformedCodeChunk::make_from(code); let mut cfg = VMControlFlowGraph::new(&code_chunk.code); loop { - let optimized_blocks = self.get_optimized_blocks(&code_chunk.code, &cfg); + let optimized_blocks = self.get_optimized_blocks(&code_chunk, &cfg); let optimized_code_chunk = Self::flatten_blocks(optimized_blocks); let optimized_cfg = VMControlFlowGraph::new(&optimized_code_chunk.code); if optimized_cfg.num_blocks() == cfg.num_blocks() { @@ -62,7 +62,7 @@ impl BasicBlockOptimizerPipeline { // Number of basic blocks changed, re-run the basic-block // optimization pipeline again on the new basic blocks. cfg = optimized_cfg; - code_chunk = optimized_code_chunk.remap(code_chunk.original_offsets); + code_chunk = optimized_code_chunk; } } } @@ -71,14 +71,14 @@ impl BasicBlockOptimizerPipeline { /// basic blocks. fn get_optimized_blocks( &self, - code: &[Bytecode], + original_block: &TransformedCodeChunk, cfg: &VMControlFlowGraph, ) -> BTreeMap { let mut optimized_blocks = BTreeMap::new(); for block_id in cfg.blocks() { let start = cfg.block_start(block_id); let end = cfg.block_end(block_id); // `end` is inclusive - let mut block = TransformedCodeChunk::make_from(&code[start as usize..=end as usize]); + let mut block = original_block.extract(start, end); for bb_optimizer in self.optimizers.iter() { block = bb_optimizer .optimize(&block.code) @@ -97,7 +97,7 @@ impl BasicBlockOptimizerPipeline { let mut block_mapping = BTreeMap::new(); for (offset, block) in optimized_blocks { block_mapping.insert(offset, optimized_code.code.len() as CodeOffset); - optimized_code.extend(block, offset); + optimized_code.extend(block, 0); } Self::remap_branch_targets(&mut optimized_code.code, &block_mapping); optimized_code @@ -115,3 +115,58 @@ impl BasicBlockOptimizerPipeline { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_basic_block_optimizer_pipeline() { + let pipeline = BasicBlockOptimizerPipeline::default(); + use Bytecode::*; + // Below, we handcraft a scenario where multiple peephole optimizations can be applied, + // in multiple passes, including merging basic blocks multiple times. + // We test both the optimization as well as the offset transformation. + let code = vec![ + CopyLoc(0), // 0 + CopyLoc(0), // 1 + Add, // 2 + StLoc(0), // 3 + CopyLoc(0), // 4 + StLoc(1), // 5 + MoveLoc(1), // 6 + StLoc(0), // 7 + LdTrue, // 8 + StLoc(2), // 9 + LdTrue, // 10 + StLoc(3), // 11 + MoveLoc(3), // 12 + BrFalse(22), // 13 + MoveLoc(2), // 14 + BrFalse(22), // 15 + CopyLoc(0), // 16 + CopyLoc(0), // 17 + Add, // 18 + StLoc(0), // 19 + CopyLoc(0), // 20 + Pop, // 21 + Ret, // 22 + ]; + let optimized_code_chunk = pipeline.optimize(&code); + let expected_code_chunk = TransformedCodeChunk::new( + vec![ + CopyLoc(0), // 0 + CopyLoc(0), // 1 + Add, // 2 + StLoc(0), // 3 + CopyLoc(0), // 16 + CopyLoc(0), // 17 + Add, // 18 + StLoc(0), // 19 + Ret, // 22 + ], + vec![0, 1, 2, 3, 16, 17, 18, 19, 22], + ); + assert!(optimized_code_chunk == expected_code_chunk); + } +} diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer/optimizers.rs b/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer/optimizers.rs index d29335b56b3..5d5474230a4 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer/optimizers.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/peephole_optimizer/optimizers.rs @@ -7,6 +7,7 @@ use move_binary_format::file_format::{Bytecode, CodeOffset}; /// A contiguous chunk of bytecode that may have been transformed from some /// other "original" contiguous chunk of bytecode. +#[derive(PartialEq, Eq)] pub struct TransformedCodeChunk { /// The transformed bytecode. pub code: Vec, @@ -32,6 +33,13 @@ impl TransformedCodeChunk { Self::new(vec![], vec![]) } + /// Extract a contiguous sub-chunk from this chunk, + pub fn extract(&self, start: CodeOffset, end: CodeOffset) -> TransformedCodeChunk { + let new_code = self.code[start as usize..=end as usize].to_vec(); + let new_offsets = self.original_offsets[start as usize..=end as usize].to_vec(); + TransformedCodeChunk::new(new_code, new_offsets) + } + /// Extend this chunk with another `other` chunk. /// The `original_offsets` for the `other` chunk are incremented by `adjust`. pub fn extend(&mut self, other: TransformedCodeChunk, adjust: CodeOffset) { diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs index 223287b9a2f..3573a1e57e3 100644 --- a/third_party/move/move-compiler-v2/src/lib.rs +++ b/third_party/move/move-compiler-v2/src/lib.rs @@ -7,7 +7,7 @@ pub mod diagnostics; pub mod env_pipeline; mod experiments; pub mod external_checks; -mod file_format_generator; +pub mod file_format_generator; pub mod lint_common; pub mod logging; pub mod options; @@ -17,11 +17,11 @@ pub mod plan_builder; use crate::{ diagnostics::Emitter, env_pipeline::{ - acquires_checker, ast_simplifier, closure_checker, cyclic_instantiation_checker, - flow_insensitive_checkers, function_checker, inliner, lambda_lifter, - lambda_lifter::LambdaLiftingOptions, model_ast_lints, recursive_struct_checker, - rewrite_target::RewritingScope, seqs_in_binop_checker, spec_checker, spec_rewriter, - unused_params_checker, EnvProcessorPipeline, + acquires_checker, ast_simplifier, closure_checker, cmp_rewriter, + cyclic_instantiation_checker, flow_insensitive_checkers, function_checker, inliner, + inlining_optimization, lambda_lifter, lambda_lifter::LambdaLiftingOptions, model_ast_lints, + recursive_struct_checker, rewrite_target::RewritingScope, seqs_in_binop_checker, + spec_checker, spec_rewriter, unused_params_checker, EnvProcessorPipeline, }, pipeline::{ ability_processor::AbilityProcessor, @@ -58,7 +58,6 @@ use log::{debug, info, log_enabled, Level}; use move_binary_format::errors::VMError; use move_bytecode_source_map::source_map::SourceMap; use move_core_types::vm_status::StatusType; -use move_disassembler::disassembler::Disassembler; use move_model::{ metadata::LanguageVersion, model::{GlobalEnv, Loc, MoveIrLoc}, @@ -72,6 +71,8 @@ pub use options::Options; use std::{collections::BTreeSet, path::Path}; const DEBUG: bool = false; +const COMPILER_BUG_REPORT_MSG: &str = + "please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue)"; /// Run Move compiler and print errors to stderr. pub fn run_move_compiler_to_stderr( @@ -90,7 +91,7 @@ pub fn run_move_compiler( where E: Emitter + ?Sized, { - logging::setup_logging(); + logging::setup_logging(None); info!("Move Compiler v2"); // Run context check. @@ -187,7 +188,7 @@ pub fn run_move_compiler_for_analysis( /// Run the type checker and return the global env (with errors if encountered). The result /// fails not on context checking errors, but possibly on i/o errors. pub fn run_checker(options: Options) -> anyhow::Result { - info!("Type Checking"); + info!("type checking"); // Run the model builder, which performs context checking. let addrs = move_model::parse_addresses_from_options(options.named_address_mapping.clone())?; let mut env = move_model::run_model_builder_in_compiler_mode( @@ -280,7 +281,7 @@ pub fn run_stackless_bytecode_pipeline( /// compilation, create an entry in the functions target holder which encapsulate info /// like the generated bytecode. pub fn run_stackless_bytecode_gen(env: &GlobalEnv) -> FunctionTargetsHolder { - info!("Stackless bytecode Generation"); + debug!("Stackless bytecode Generation"); let mut targets = FunctionTargetsHolder::default(); let mut todo = BTreeSet::new(); let mut done = BTreeSet::new(); @@ -309,6 +310,8 @@ pub fn run_stackless_bytecode_gen(env: &GlobalEnv) -> FunctionTargetsHolder { } } } + env.set_function_size_estimates(targets.compute_function_size_estimates()); + targets } @@ -317,7 +320,7 @@ pub fn run_file_format_gen( env: &mut GlobalEnv, targets: &FunctionTargetsHolder, ) -> Vec { - info!("File Format Generation"); + debug!("File Format Generation"); file_format_generator::generate_file_format(env, targets) } @@ -377,6 +380,20 @@ pub fn env_check_and_transform_pipeline<'a, 'b>(options: &'a Options) -> EnvProc env_pipeline.add("model AST lints", model_ast_lints::checker); } + // The comparison rewriter is a new features in Aptos Move 2.2 and onwards + let rewrite_cmp = options + .language_version + .unwrap_or_default() + .is_at_least(LanguageVersion::V2_2) + && options.experiment_on(Experiment::CMP_REWRITE); + + if rewrite_cmp { + env_pipeline.add("rewrite comparison operations", |env| { + // This rewrite is suggested to run before inlining to avoid repeated rewriting + cmp_rewriter::rewrite(env); + }); + } + if options.experiment_on(Experiment::INLINING) { let rewriting_scope = if options.whole_program { RewritingScope::Everything @@ -450,13 +467,32 @@ pub fn env_check_and_transform_pipeline<'a, 'b>(options: &'a Options) -> EnvProc pub fn env_optimization_pipeline<'a, 'b>(options: &'a Options) -> EnvProcessorPipeline<'b> { let mut env_pipeline = EnvProcessorPipeline::<'b>::default(); + // Note: we should run inlining optimization before other AST simplifications, so that + // those simplifications can take advantage of the inlining. + let do_inlining_optimization = options.experiment_on(Experiment::INLINING_OPTIMIZATION); + if do_inlining_optimization { + // This allows inlining a call that comes from a different package + let across_package = options.experiment_on(Experiment::ACROSS_PACKAGE_INLINING); + // This allows performing an inlining optimization to a function that does not belong to the primary target package + let allow_non_primary_targets = + options.experiment_on(Experiment::INLINING_OPTIMIZATION_TO_NON_PRIMARY_TARGETS); + env_pipeline.add("inlining optimization", { + move |env: &mut GlobalEnv| { + inlining_optimization::optimize(env, across_package, allow_non_primary_targets) + } + }); + } if options.experiment_on(Experiment::AST_SIMPLIFY_FULL) { env_pipeline.add("simplifier with code elimination", { - |env: &mut GlobalEnv| ast_simplifier::run_simplifier(env, true) + move |env: &mut GlobalEnv| { + ast_simplifier::run_simplifier(env, true, do_inlining_optimization) + } }); } else if options.experiment_on(Experiment::AST_SIMPLIFY) { env_pipeline.add("simplifier", { - |env: &mut GlobalEnv| ast_simplifier::run_simplifier(env, false) + move |env: &mut GlobalEnv| { + ast_simplifier::run_simplifier(env, false, do_inlining_optimization) + } }); } @@ -588,7 +624,14 @@ pub fn stackless_bytecode_optimization_pipeline(options: &Options) -> FunctionTa pub fn disassemble_compiled_units(units: &[CompiledUnit]) -> anyhow::Result { let disassembled_units: anyhow::Result> = units .iter() - .map(|unit| Disassembler::from_unit(unit).disassemble()) + .map(|unit| match unit { + CompiledUnit::Module(module) => { + move_asm::disassembler::disassemble_module(String::new(), &module.module, false) + }, + CompiledUnit::Script(script) => { + move_asm::disassembler::disassemble_script(String::new(), &script.script) + }, + }) .collect(); Ok(disassembled_units?.concat()) } @@ -641,13 +684,14 @@ fn report_bytecode_verification_error( env.to_loc(module_ir_loc) }); if e.status_type() != StatusType::Verification { - env.diag( + env.diag_with_notes( Severity::Bug, loc, &format!( - "unexpected error returned from bytecode verification. This is a compiler bug, consider reporting it.\n{:#?}", + "unexpected error returned from bytecode verification:\n{:#?}", e ), + vec![COMPILER_BUG_REPORT_MSG.to_string()], ) } else { let debug_info = if command_line::get_move_compiler_backtrace_from_env() { @@ -658,15 +702,15 @@ fn report_bytecode_verification_error( e.message().cloned().unwrap_or_else(|| "none".to_string()) ) }; - env.diag( + env.diag_with_notes( Severity::Bug, loc, &format!( - "bytecode verification failed with \ - unexpected status code `{:?}`. This is a compiler bug, consider reporting it.{}", + "bytecode verification failed with unexpected status code `{:?}`:{}", e.major_status(), debug_info ), + vec![COMPILER_BUG_REPORT_MSG.to_string()], ) } } diff --git a/third_party/move/move-compiler-v2/src/logging.rs b/third_party/move/move-compiler-v2/src/logging.rs index 03fae153193..56ed228d344 100644 --- a/third_party/move/move-compiler-v2/src/logging.rs +++ b/third_party/move/move-compiler-v2/src/logging.rs @@ -44,51 +44,76 @@ //! if DEBUG { debug!(..) } //! ``` +use colored::Colorize; use flexi_logger::{DeferredNow, FileSpec, LogSpecification, Logger}; -use log::Record; +use log::{Level, LevelFilter, Record}; use std::env; const MVC_LOG_VAR: &str = "MVC_LOG"; /// Configures logging for applications. -pub fn setup_logging() { +pub fn setup_logging(level: Option) { // Currently no different to testing - setup_logging_for_testing() + setup_logging_for_testing(level) } /// Configures logging for testing. Can be called multiple times. -pub fn setup_logging_for_testing() { - if let Some(logger) = configure_logger() { +pub fn setup_logging_for_testing(level: Option) { + if let Some(logger) = configure_logger(level) { // Will produce error if a logger is already installed, which we ignore. Its either this same logger // already installed, or some outer code overriding the logger. let _ = logger.start(); } } -fn configure_logger() -> Option { - let var = env::var(MVC_LOG_VAR).ok()?; - let mut parts = var.rsplitn(2, '@').collect::>(); - parts.reverse(); - let spec = if parts[0].trim().is_empty() { - // Show everything - LogSpecification::trace() +#[allow(clippy::unnecessary_unwrap)] +fn configure_logger(level: Option) -> Option { + let var = env::var(MVC_LOG_VAR); + let (spec, fname) = if var.is_err() && level.is_some() { + ( + match level.unwrap() { + LevelFilter::Error => LogSpecification::error(), + LevelFilter::Warn => LogSpecification::warn(), + LevelFilter::Info => LogSpecification::info(), + LevelFilter::Debug => LogSpecification::debug(), + LevelFilter::Trace => LogSpecification::trace(), + LevelFilter::Off => LogSpecification::off(), + }, + None, + ) } else { - LogSpecification::parse(parts[0]).expect("log spec") - }; - let mut logger = Logger::with(spec).format(format_record); - if parts.len() > 1 { - let fname = if !parts[1].contains('/') { - // Flex logger somehow does not like relative file names, help them. - format!("./{}", parts[1]) + let var = var.ok()?; + let mut parts = var.rsplitn(2, '@').collect::>(); + parts.reverse(); + let spec = if parts[0].trim().is_empty() { + // Show everything + LogSpecification::trace() } else { - parts[1].to_string() + LogSpecification::parse(parts[0]).expect("log spec") }; - logger = logger.log_to_file(FileSpec::try_from(fname).expect("file name")) - } - Some(logger) + if parts.len() > 1 { + if !parts[1].contains('/') { + // Flex logger somehow does not like relative file names, help them. + (spec, Some(format!("./{}", parts[1]))) + } else { + (spec, Some(parts[1].to_string())) + } + } else { + (spec, None) + } + }; + Some( + if let Some(fname) = fname { + Logger::with(spec) + .format(format_record_file) + .log_to_file(FileSpec::try_from(fname).expect("file name")) + } else { + Logger::with(spec).format(format_record_colored) + }, + ) } -fn format_record( +fn format_record_file( w: &mut dyn std::io::Write, _now: &mut DeferredNow, record: &Record, @@ -101,3 +126,18 @@ fn format_record( &record.args() ) } + +fn format_record_colored( + w: &mut dyn std::io::Write, + _now: &mut DeferredNow, + record: &Record, +) -> Result<(), std::io::Error> { + let level_color = match record.level() { + Level::Error => "ERROR".red().bold(), + Level::Warn => "WARN".yellow().bold(), + Level::Info => "INFO".green().bold(), + Level::Debug => "DEBUG".cyan().bold(), + Level::Trace => "TRACE".normal(), + }; + write!(w, "[{}] {}", level_color, &record.args()) +} diff --git a/third_party/move/move-compiler-v2/src/options.rs b/third_party/move/move-compiler-v2/src/options.rs index ede3469c100..7c1c07f1066 100644 --- a/third_party/move/move-compiler-v2/src/options.rs +++ b/third_party/move/move-compiler-v2/src/options.rs @@ -129,6 +129,10 @@ pub struct Options { /// External checks to be performed. #[clap(skip)] pub external_checks: Vec>, + + /// Whether to print errors to stderr as they are reported. + #[clap(long, default_value = "true")] + pub print_errors: bool, } impl Default for Options { diff --git a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs index bd446bbe1e3..a3bab1bef24 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs @@ -162,9 +162,8 @@ impl TransferFunctions for CopyDropAnalysis<'_> { let lifetime = self.lifetime.get_info_at(offset); let exit_state = self.exit_state.get_state_at(offset); // Only temps which are used after or borrowed need a copy - let temp_needs_copy = |temp, instr| { - live_var.is_temp_used_after(temp, instr) || lifetime.borrow_kind_before(*temp).is_some() - }; + let temp_needs_copy = + |temp, instr| live_var.is_temp_used_after(temp, instr) || lifetime.is_borrowed(*temp); // References always need to be dropped to satisfy bytecode verifier borrow analysis, other values // only if this execution path can return. let temp_needs_drop = |temp: &TempIndex| { @@ -366,12 +365,7 @@ impl Transformer<'_> { // Only need to perform the actual copy if src is borrowed, as this // information cannot be determined from live-var analysis in later // phases. - if self - .lifetime - .get_info_at(code_offset) - .borrow_kind_after(*src) - .is_some() - { + if self.lifetime.get_info_at(code_offset).is_borrowed(*src) { let ty = self.builder.get_local_type(*src); let temp = self.builder.new_temp(ty); self.builder.emit(Assign(id, temp, *src, AssignKind::Copy)); @@ -445,11 +439,7 @@ impl Transformer<'_> { } for temp in copy_drop_at.needs_drop.iter() { // Give a better error message if we know its borrowed - let is_borrowed = self - .lifetime - .get_info_at(code_offset) - .borrow_kind_after(*temp) - .is_some(); + let is_borrowed = self.lifetime.get_info_at(code_offset).is_borrowed(*temp); self.check_drop(bytecode.get_attr_id(), *temp, || { ( if is_borrowed { diff --git a/third_party/move/move-compiler-v2/src/pipeline/control_flow_graph_simplifier.rs b/third_party/move/move-compiler-v2/src/pipeline/control_flow_graph_simplifier.rs index 578dd7b010a..940efcbcb1f 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/control_flow_graph_simplifier.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/control_flow_graph_simplifier.rs @@ -80,6 +80,20 @@ //! //! goto L //! +//! 5. Hoists jumps to blocks which simply exit the function into the source block. This +//! simplification may result in dead code which is removed in later stages: +//! +//! L1: ...; goto L2; +//! L2: return|abort +//! +//! ==> +//! +//! L1: ...; return/abort; +//! L2: return|abort // might be dead code now +//! +//! While this transformation may lead to more complex stackless bytecode, it the +//! final stack machine of the VM, this avoids unnecessary temporaries and branches. +//! //! We also remove unused labels. //! //! Side effects: removes all annotations. @@ -493,17 +507,17 @@ impl ControlFlowGraphCodeGenerator { // check invariant 2 assert!(self.successors.keys().eq(pred_map_reversed.keys())); for block in self.successors.keys() { - assert!( + assert_eq!( self.successors .get(block) .expect("successors") .iter() + .collect::>(), + pred_map_reversed + .get(block) + .expect("pred_map_reversed") + .iter() .collect::>() - == pred_map_reversed - .get(block) - .expect("pred_map_reversed") - .iter() - .collect::>() ); } // check invariant 3 @@ -556,25 +570,23 @@ impl ControlFlowGraphCodeGenerator { .iter() .map(|block| self.get_block_label(*block).expect("label")) .collect(); - assert!( - succs_labels.len() == { - if l0 == l1 { - 1 - } else { - 2 - } + assert_eq!(succs_labels.len(), { + if l0 == l1 { + 1 + } else { + 2 } - ); + }); assert!(succs_labels.contains(l0)); assert!(succs_labels.contains(l1)); }, Bytecode::Jump(_, l) => { let suc_block = self.get_the_non_trivial_successor(*block); let suc_label = self.get_block_label(suc_block).expect("label"); - assert!(l == &suc_label); + assert_eq!(l, &suc_label); }, _ => { - assert!(self.successors.get(block).expect("successors").len() == 1); + assert_eq!(self.successors.get(block).expect("successors").len(), 1); }, } } @@ -710,20 +722,26 @@ impl RedundantJumpRemover { /// Requires: `block` still in the cfg, `block` is not entry/exit fn remove_redundant_edges_from(&mut self, block: BlockId) { for suc in self.0.successors.get(&block).expect("successors").clone() { - if !self.0.is_trivial_block(suc) && self.remove_jump_if_possible(block, suc) { - // we may have removed block - if !self.0.successors.contains_key(&block) { + if !self.0.is_trivial_block(suc) { + if self.hoist_exit_jump_if_possible(block, suc) { + // No further processing needed break; } - // successors of `block` changes - // consider - // L0: goto L1; L1: goto L2; L2: goto L3; - // the successor of L0 is L1 - // after merging block L1 into block L0 we get - // L0: goto L2; L2: goto L3; - // now the successor of L0 becomes L2 - // we continue to merge block L3 into block L0 ... - self.remove_redundant_edges_from(block); + if self.remove_jump_if_possible(block, suc) { + // we may have removed block + if !self.0.successors.contains_key(&block) { + break; + } + // successors of `block` changes + // consider + // L0: goto L1; L1: goto L2; L2: goto L3; + // the successor of L0 is L1 + // after merging block L1 into block L0 we get + // L0: goto L2; L2: goto L3; + // now the successor of L0 becomes L2 + // we continue to merge block L3 into block L0 ... + self.remove_redundant_edges_from(block); + } } } } @@ -788,6 +806,40 @@ impl RedundantJumpRemover { true } } + + /// If the edge `(from , to)` is unconditional jump to an exit (return or abort) + /// instruction, pull that instruction into the `from` block, eliminating the jump. + /// The `to` block may eventually become dead code and removed by the deadcode + /// eliminator. + fn hoist_exit_jump_if_possible(&mut self, from: BlockId, to: BlockId) -> bool { + if from != to + && let Some(exit_bc) = self.get_exit_target(from, to).cloned() + { + let from_code = self.0.code_block_mut(from); + remove_tail_jump(from_code); + from_code.push(exit_bc); + true + } else { + false + } + } + + /// Determine whether we jump `from` -> `to` and simply exit. + fn get_exit_target(&self, from: BlockId, to: BlockId) -> Option<&Bytecode> { + // Last instruction of from must be `Jump` + let from_instrs = self.0.block_instrs(from); + from_instrs + .last() + .filter(|bc| matches!(bc, Bytecode::Jump(..)))?; + let mut to_instrs = self.0.block_instrs(to); + // If the block may start with a label marker, skip it. + while matches!(to_instrs.first(), Some(Bytecode::Label(..))) { + to_instrs = &to_instrs[1..]; + } + to_instrs + .first() + .filter(|bc| matches!(bc, Bytecode::Ret(..) | Bytecode::Abort(..))) + } } /// Computes the map from each block to its predecessors diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs index 361bc44c17b..efada5b51d0 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs @@ -56,6 +56,11 @@ impl LifetimeInfoAtCodeOffset { pub fn borrow_kind_after(&self, temp: TempIndex) -> Option { self.after.borrow_kind(temp) } + + /// Returns true if the given temporary is borrowed before or after the program point. + pub fn is_borrowed(&self, temp: TempIndex) -> bool { + self.borrow_kind_before(temp).is_some() || self.borrow_kind_after(temp).is_some() + } } /// A trait to be implemented by reference safety processors diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs index 04f5b3f925f..9145e4a03b5 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v2.rs @@ -527,7 +527,7 @@ impl LifetimeState { } /// Returns an iteration of child edges of given node. - fn children(&self, label: &LifetimeLabel) -> impl Iterator { + fn children(&self, label: &LifetimeLabel) -> impl Iterator + use<'_> { self.node(label).children.iter() } @@ -1410,7 +1410,7 @@ impl LifetimeAnalysisStep<'_, '_> { } #[inline] - fn target(&self) -> &FunctionTarget { + fn target(&self) -> &FunctionTarget<'_> { self.parent.target } diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs index 0358e2d0110..4cca02e891a 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/reference_safety_processor_v3.rs @@ -334,7 +334,9 @@ impl LifetimeState { } /// Returns all currently active global borrow edges. - fn global_borrow_edges(&self) -> impl Iterator, RefID)> { + fn global_borrow_edges( + &self, + ) -> impl Iterator, RefID)> + use<> { self.borrow_graph .out_edges(self.frame_root()) .into_iter() @@ -580,7 +582,7 @@ impl LifetimeAnalysisStep<'_, '_> { } #[inline] - fn target(&self) -> &FunctionTarget { + fn target(&self) -> &FunctionTarget<'_> { self.parent.target } diff --git a/third_party/move/move-compiler-v2/src/pipeline/uninitialized_use_checker.rs b/third_party/move/move-compiler-v2/src/pipeline/uninitialized_use_checker.rs index 1e09db80141..ed170af566f 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/uninitialized_use_checker.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/uninitialized_use_checker.rs @@ -78,9 +78,10 @@ impl InitializedState { panic!("ICE: num_locals must be >= num_params"); } Self(Vector::from_iter( - std::iter::repeat(Initialized::Yes) - .take(num_params) - .chain(std::iter::repeat(Initialized::No).take(num_locals - num_params)), + std::iter::repeat_n(Initialized::Yes, num_params).chain(std::iter::repeat_n( + Initialized::No, + num_locals - num_params, + )), )) } diff --git a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp index 449755574b0..bb5deed1f94 100644 --- a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp +++ b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp @@ -1,18 +1,18 @@ Diagnostics: -error: local `x` of type `Impotent` does not have the `copy` ability +error: value of type `Impotent` does not have the `drop` ability ┌─ tests/ability-check/ability_violation.move:7:10 │ 7 │ (x, x); - │ ^ - used here - │ │ - │ copy needed here because value is still in use + │ ^ implicitly dropped here since it is no longer used -error: value of type `Impotent` does not have the `drop` ability +error: local `x` of type `Impotent` does not have the `copy` ability ┌─ tests/ability-check/ability_violation.move:7:10 │ 7 │ (x, x); - │ ^ implicitly dropped here since it is no longer used + │ ^ - used here + │ │ + │ copy needed here because value is still in use error: value of type `Impotent` does not have the `drop` ability ┌─ tests/ability-check/ability_violation.move:7:13 diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp new file mode 100644 index 00000000000..90b32906711 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp @@ -0,0 +1,2 @@ + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move new file mode 100644 index 00000000000..f2821c6d729 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move @@ -0,0 +1,24 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + if (f == f) + 1 + else + 2 + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // ok case + let f: | &||u64 |u64 has copy+store+drop = test; + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp new file mode 100644 index 00000000000..90b32906711 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp @@ -0,0 +1,2 @@ + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move new file mode 100644 index 00000000000..4509789116a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move @@ -0,0 +1,15 @@ +module 0x99::basic_enum { + #[persistent] + fun increment_by_one(x: &mut u64): u64 { *x = *x + 1; *x } + + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // ok case + let f1: |&mut u64|u64 has copy+store = increment_by_one; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp new file mode 100644 index 00000000000..6877d4385cf --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp @@ -0,0 +1,7 @@ + +Diagnostics: +error: type `|&||u64|u64 has copy + drop` is missing required ability `store` + ┌─ tests/ability-check/fv_as_keys/missing_store.move:19:35 + │ +19 │ add_resource_with_struct(acc, f); + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move new file mode 100644 index 00000000000..affa0fc0a35 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move @@ -0,0 +1,21 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + 1 + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // not ok case: cannot store functions without `store` + let f: | &||u64 |u64 has copy+drop = test; + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp new file mode 100644 index 00000000000..7e6ffea6dc3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp @@ -0,0 +1,7 @@ + +Diagnostics: +error: type `|&mut u64|u64 has copy` is missing required ability `store` + ┌─ tests/ability-check/fv_as_keys/missing_store_enum.move:12:29 + │ +12 │ let v1 = FV::V1{v1: f1}; + │ ^^ diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move new file mode 100644 index 00000000000..dfee4998879 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move @@ -0,0 +1,15 @@ +module 0x99::basic_enum { + #[persistent] + fun increment_by_one(x: &mut u64): u64 { *x = *x + 1; *x } + + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // not ok case: cannot store functions without `store` + let f1: |&mut u64|u64 has copy = increment_by_one; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp new file mode 100644 index 00000000000..fec0864f595 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp @@ -0,0 +1,19 @@ + +Diagnostics: +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:12:45 + │ +12 │ fun add_resource_with_fv(acc: &signer, f: | &||u64 |u64 has store+drop+key) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:13:13 + │ +13 │ move_to<| &||u64 |u64 has store+drop+key>(acc, f); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:18:12 + │ +18 │ let f: | &||u64 |u64 has store+drop+key = test; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move new file mode 100644 index 00000000000..994c93d8420 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move @@ -0,0 +1,21 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + 1 + } + + // not ok: storage mandates struct type + fun add_resource_with_fv(acc: &signer, f: | &||u64 |u64 has store+drop+key) { + move_to<| &||u64 |u64 has store+drop+key>(acc, f); + } + + public fun test_driver(acc: &signer){ + // not ok case: cannot put function values in storage directly + let f: | &||u64 |u64 has store+drop+key = test; + add_resource_with_fv(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp new file mode 100644 index 00000000000..b3241dfc2bc --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: function resulting from lambda lifting is missing the `store` ability + ┌─ tests/ability-check/fv_as_keys/store_lambda.move:13:48 + │ +13 │ let f: | &||u64 |u64 has copy+store+drop = |x| (*x)(); + │ ^^^^^^^^^^ + │ + = lambda cannot be reduced to partial application of existing function + = expected function type: `|&||u64|u64 has copy + drop + store` diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move new file mode 100644 index 00000000000..801f58c6515 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move @@ -0,0 +1,16 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // not ok case: lambda functions have no `store` + let f: | &||u64 |u64 has copy+store+drop = |x| (*x)(); + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp new file mode 100644 index 00000000000..011ebe00360 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: function resulting from lambda lifting is missing the `store` ability + ┌─ tests/ability-check/fv_as_keys/store_lambda_enum.move:8:48 + │ +8 │ let f1: |&mut u64|u64 has copy+store = |x| *x+1; + │ ^^^^^^^^ + │ + = lambda cannot be reduced to partial application of existing function + = expected function type: `|&mut u64|u64 has copy + store` diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move new file mode 100644 index 00000000000..26483bf05dd --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move @@ -0,0 +1,12 @@ +module 0x99::basic_enum { + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // not ok case: cannot put function values in storage directly + let f1: |&mut u64|u64 has copy+store = |x| *x+1; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp new file mode 100644 index 00000000000..b4db6366a2a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp @@ -0,0 +1,13 @@ + +Diagnostics: +error: value of type `|&mut u64|u64 has copy + store` does not have the `drop` ability + ┌─ tests/ability-check/fv_enum_err.move:21:17 + │ +21 │ vector::pop_back(&mut v1); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used + +error: value of type `|&mut u64|u64 has copy + store` does not have the `drop` ability + ┌─ tests/ability-check/fv_enum_err.move:22:17 + │ +22 │ vector::pop_back(&mut v1); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move new file mode 100644 index 00000000000..5c030935934 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move @@ -0,0 +1,32 @@ +module 0x66::fv_enum_basic { + use std::signer; + + #[persistent] + fun add_k_persistent_ref(x: &mut u64, k: u64): u64 { *x = *x + 1; *x + k } + + enum FunVec has key { + V1 { v1: vector<|&mut T|T has copy + store> }, + V2 { v0: u64, v1: vector<|&mut T|T has copy + store> }, + } + + fun test_fun_vec(s: &signer) { + use std::vector; + let k = 3; + let add_k: |&mut u64|u64 has copy + store + drop = |x: &mut u64| add_k_persistent_ref(x, k); + let v1 = FunVec::V1 { v1: vector[add_k, add_k] }; + move_to(s, v1); + let m = move_from>(signer::address_of(s)); + match (m) { + FunVec::V1 { v1 } => { + vector::pop_back(&mut v1); + vector::pop_back(&mut v1); + vector::destroy_empty(v1); + } + FunVec::V2 { v0: _, v1 } => { + vector::destroy_empty(v1); + assert!(false, 99); + } + }; + } + +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/typing/pack.v2_exp b/third_party/move/move-compiler-v2/tests/ability-check/typing/pack.v2_exp deleted file mode 100644 index 572e482b9d8..00000000000 --- a/third_party/move/move-compiler-v2/tests/ability-check/typing/pack.v2_exp +++ /dev/null @@ -1,36 +0,0 @@ -============ initial translation from Move ================ - -[variant baseline] -public fun Test::test_pack(): Test::R { - var $t0: u64 - var $t1: u64 - var $t2: Test::S - var $t3: Test::R - 0: $t0 := 3 - 1: $t1 := 1 - 2: $t2 := pack Test::S($t1) - 3: $t3 := pack Test::R($t0, $t2) - 4: return $t3 -} - -============ after pipeline `data_invariant_instrumentation` ================ - -[variant verification] -public fun Test::test_pack(): Test::R { - var $t0: u64 - var $t1: u64 - var $t2: Test::S - var $t3: Test::R - 0: $t0 := 3 - 1: $t1 := 1 - 2: $t2 := pack Test::S($t1) - # data invariant at tests/data_invariant_instrumentation/pack.move:16:9+16 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/pack.move:16:9+16 - 3: assert Gt(select Test::S.y($t2), 0) - 4: $t3 := pack Test::R($t0, $t2) - # data invariant at tests/data_invariant_instrumentation/pack.move:12:9+18 - # VC: data invariant does not hold at tests/data_invariant_instrumentation/pack.move:12:9+18 - 5: assert Gt(select Test::R.x($t3), select Test::S.y(select Test::R.s($t3))) - 6: label L1 - 7: return $t3 -} diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/borrowed_from_one_path.exp b/third_party/move/move-compiler-v2/tests/ability-transform/borrowed_from_one_path.exp index ed6144d84f3..4819afcfae2 100644 --- a/third_party/move/move-compiler-v2/tests/ability-transform/borrowed_from_one_path.exp +++ b/third_party/move/move-compiler-v2/tests/ability-transform/borrowed_from_one_path.exp @@ -1086,36 +1086,35 @@ fun m::f($t0: u8, $t1: &vector): u64 { ============ disassembled file-format ================== -// Move bytecode v8 -module 42.m { -struct R has key { - data: vector -} +// Bytecode version v9 +module 0x42::m +struct R has key + data: vector + +// Function definition at index 0 +fun f(l0: u8, l1: &vector): u64 acquires R + local l2: &vector + move_loc l0 + ld_u8 0 + eq + br_false l0 + move_loc l1 + // @5 + pop + ld_const